|
1 /* |
|
2 * Copyright (c) 2007-2008 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include <f32file.h> |
|
20 #include "hnmdlocalizationelement.h" |
|
21 #include "hnglobals.h" |
|
22 #include "hnconvutils.h" |
|
23 #include "hnutils.h" |
|
24 |
|
25 const TText8 KSPChar = ' '; |
|
26 const TText8 KNLChar = '\n'; |
|
27 const TInt KWholeFileReadLimit = 1024; |
|
28 |
|
29 // ======== MEMBER FUNCTIONS ======== |
|
30 |
|
31 // --------------------------------------------------------------------------- |
|
32 // |
|
33 // --------------------------------------------------------------------------- |
|
34 // |
|
35 TUint32 HBufC8Hash( HBufC8* const & aBuf ) |
|
36 { |
|
37 return DefaultHash::Des8(*aBuf); |
|
38 } |
|
39 // --------------------------------------------------------------------------- |
|
40 // |
|
41 // --------------------------------------------------------------------------- |
|
42 // |
|
43 TBool HBufC8Ident( HBufC8* const & aL, HBufC8* const & aR ) |
|
44 { |
|
45 return DefaultIdentity::Des8(*aL, *aR); |
|
46 } |
|
47 |
|
48 // --------------------------------------------------------------------------- |
|
49 // |
|
50 // --------------------------------------------------------------------------- |
|
51 // |
|
52 void CHnMdLocalizationElement::ConstructL( const TDesC& aNamespace, |
|
53 const TDesC& aSource ) |
|
54 { |
|
55 iNamespace.CreateL( aNamespace ); |
|
56 iSource.CreateL( aSource ); |
|
57 iSource.LowerCase(); |
|
58 LocateLanguageFileL(); |
|
59 } |
|
60 |
|
61 // --------------------------------------------------------------------------- |
|
62 // |
|
63 // --------------------------------------------------------------------------- |
|
64 // |
|
65 void CHnMdLocalizationElement::ConstructL( TXmlEngElement aElement ) |
|
66 { |
|
67 ASSERT( aElement.HasAttributeL( KNameSpaceAttrName8 ) ); |
|
68 |
|
69 SetNamespaceL( aElement.AttributeNodeL( KNameSpaceAttrName8 ) ); |
|
70 SetSourceL( aElement.AttributeNodeL( KSourceAttrName8 ) ); |
|
71 } |
|
72 |
|
73 // --------------------------------------------------------------------------- |
|
74 // |
|
75 // --------------------------------------------------------------------------- |
|
76 // |
|
77 void CHnMdLocalizationElement::SetNamespaceL( TXmlEngAttr aNamespace ) |
|
78 { |
|
79 HBufC* namespac = HnConvUtils::Str8ToStrLC( aNamespace.Value() ); |
|
80 |
|
81 iNamespace.Close(); |
|
82 iNamespace.CreateL( *namespac ); |
|
83 |
|
84 CleanupStack::PopAndDestroy( namespac ); |
|
85 } |
|
86 |
|
87 // --------------------------------------------------------------------------- |
|
88 // |
|
89 // --------------------------------------------------------------------------- |
|
90 // |
|
91 void CHnMdLocalizationElement::SetSourceL( TXmlEngAttr aSource ) |
|
92 { |
|
93 HBufC* source = HnConvUtils::Str8ToStrLC( aSource.Value() ); |
|
94 iSource.Close(); |
|
95 iSource.CreateL( *source ); |
|
96 iSource.LowerCase(); |
|
97 LocateLanguageFileL(); |
|
98 CleanupStack::PopAndDestroy( source ); |
|
99 } |
|
100 |
|
101 // --------------------------------------------------------------------------- |
|
102 // |
|
103 // --------------------------------------------------------------------------- |
|
104 // |
|
105 CHnMdLocalizationElement* CHnMdLocalizationElement::NewL( |
|
106 TXmlEngElement aElement ) |
|
107 { |
|
108 CHnMdLocalizationElement* self = new( ELeave ) CHnMdLocalizationElement; |
|
109 CleanupStack::PushL( self ); |
|
110 self->ConstructL( aElement ); |
|
111 CleanupStack::Pop( self ); |
|
112 return self; |
|
113 } |
|
114 |
|
115 // --------------------------------------------------------------------------- |
|
116 // |
|
117 // --------------------------------------------------------------------------- |
|
118 // |
|
119 CHnMdLocalizationElement* CHnMdLocalizationElement::NewL(const TDesC& aNamespace, |
|
120 const TDesC& aSource) |
|
121 { |
|
122 CHnMdLocalizationElement* self = new( ELeave ) CHnMdLocalizationElement; |
|
123 CleanupStack::PushL( self ); |
|
124 self->ConstructL( aNamespace, aSource ); |
|
125 CleanupStack::Pop( self ); |
|
126 return self; |
|
127 } |
|
128 |
|
129 // --------------------------------------------------------------------------- |
|
130 // |
|
131 // --------------------------------------------------------------------------- |
|
132 // |
|
133 CHnMdLocalizationElement::CHnMdLocalizationElement(): |
|
134 iResourceIDs( &HBufC8Hash, &HBufC8Ident ) |
|
135 { |
|
136 } |
|
137 |
|
138 // --------------------------------------------------------------------------- |
|
139 // |
|
140 // --------------------------------------------------------------------------- |
|
141 // |
|
142 CHnMdLocalizationElement::~CHnMdLocalizationElement() |
|
143 { |
|
144 iNamespace.Close(); |
|
145 iSource.Close(); |
|
146 delete iSourcePath; |
|
147 THashMapIter<HBufC8*, TInt> iter( iResourceIDs ); |
|
148 while ( HBufC8* const * ptr = iter.NextKey() ) |
|
149 { |
|
150 delete *ptr; |
|
151 } |
|
152 iResourceIDs.Close(); |
|
153 } |
|
154 |
|
155 // --------------------------------------------------------------------------- |
|
156 // |
|
157 // --------------------------------------------------------------------------- |
|
158 // |
|
159 const TDesC& CHnMdLocalizationElement::Namespace() const |
|
160 { |
|
161 return iNamespace; |
|
162 } |
|
163 |
|
164 // --------------------------------------------------------------------------- |
|
165 // |
|
166 // --------------------------------------------------------------------------- |
|
167 // |
|
168 const TDesC& CHnMdLocalizationElement::Source() const |
|
169 { |
|
170 return iSource; |
|
171 } |
|
172 |
|
173 // --------------------------------------------------------------------------- |
|
174 // |
|
175 // --------------------------------------------------------------------------- |
|
176 // |
|
177 HBufC* CHnMdLocalizationElement::SourcePath() const |
|
178 { |
|
179 return iSourcePath; |
|
180 } |
|
181 // --------------------------------------------------------------------------- |
|
182 // |
|
183 // --------------------------------------------------------------------------- |
|
184 // |
|
185 TBool CHnMdLocalizationElement::SourceExists() const |
|
186 { |
|
187 if ( iSourcePath ) |
|
188 { |
|
189 return iSourcePath->Compare(KNullDesC) != 0; |
|
190 } |
|
191 else |
|
192 { |
|
193 return EFalse; |
|
194 } |
|
195 } |
|
196 |
|
197 // --------------------------------------------------------------------------- |
|
198 // |
|
199 // --------------------------------------------------------------------------- |
|
200 // |
|
201 void CHnMdLocalizationElement::LocateLanguageFileL() |
|
202 { |
|
203 delete iSourcePath; |
|
204 iSourcePath = NULL; |
|
205 iSourcePath = HnUtils::LocateNearestLanguageFileLC( iSource ); |
|
206 CleanupStack::Pop( iSourcePath ); |
|
207 } |
|
208 |
|
209 // --------------------------------------------------------------------------- |
|
210 // |
|
211 // --------------------------------------------------------------------------- |
|
212 // |
|
213 const TInt& CHnMdLocalizationElement::FindResourceIdL( HBufC8* aResourceName ) |
|
214 { |
|
215 if ( iState&EInitialized ) |
|
216 { |
|
217 // check if we have it in cache |
|
218 TInt* result = iResourceIDs.Find(aResourceName); |
|
219 if (result) |
|
220 { |
|
221 return *result; |
|
222 } |
|
223 else if (iState&EWholeFileCached) // all should be in cache |
|
224 { |
|
225 User::Leave(KErrNotFound); |
|
226 } |
|
227 } |
|
228 |
|
229 if (!(iState&EInitialized) || iState&EUsedItemsCached ) |
|
230 { |
|
231 // set initialized here, as we could have problem with file read |
|
232 // i.e. file is missing, but we dont want to go here next time |
|
233 iState |= EInitialized; |
|
234 HBufC8* rsgContent = ReadRsgContentLC( ); |
|
235 if (rsgContent->Length() < KWholeFileReadLimit) |
|
236 { |
|
237 iState |= EWholeFileCached; |
|
238 ParseRsgContentL(*rsgContent); |
|
239 } |
|
240 else |
|
241 { |
|
242 iState |= EUsedItemsCached; |
|
243 ParseRsgContentL(*rsgContent, *aResourceName); |
|
244 } |
|
245 //cleanup |
|
246 CleanupStack::PopAndDestroy(rsgContent); |
|
247 } |
|
248 |
|
249 return iResourceIDs.FindL(aResourceName); |
|
250 } |
|
251 |
|
252 // --------------------------------------------------------------------------- |
|
253 // |
|
254 // --------------------------------------------------------------------------- |
|
255 // |
|
256 HBufC8* CHnMdLocalizationElement::ReadRsgContentLC( ) |
|
257 { |
|
258 HBufC8* result(NULL); |
|
259 if ( iSourcePath->Compare( KNullDesC ) ) |
|
260 { |
|
261 HBufC* fPath = iSourcePath->AllocLC(); |
|
262 // change extension to rsg |
|
263 TInt extPos = fPath->LocateReverse(KExtDelimiter); |
|
264 fPath->Des().Replace(extPos, fPath->Length() - extPos, KRsg); |
|
265 result = HnUtils::ReadFileLC(*fPath); |
|
266 CleanupStack::Pop(result); |
|
267 CleanupStack::PopAndDestroy(fPath); |
|
268 CleanupStack::PushL(result); |
|
269 } |
|
270 else |
|
271 { |
|
272 result = KNullDesC8().AllocLC(); |
|
273 } |
|
274 return result; |
|
275 } |
|
276 |
|
277 // --------------------------------------------------------------------------- |
|
278 // |
|
279 // --------------------------------------------------------------------------- |
|
280 // |
|
281 void CHnMdLocalizationElement::ParseRsgContentL( const TDesC8& aContent ) |
|
282 { |
|
283 TPtrC8 content(aContent); |
|
284 TInt posEoL(-1); |
|
285 // iterate over each line |
|
286 while ((posEoL = content.Locate(KNLChar)) > 0) |
|
287 { |
|
288 TPtrC8 line = content.Left( posEoL - 1 ); |
|
289 TInt firstSpace = line.Locate(KSPChar); |
|
290 TInt lastSpace = line.LocateReverse(KSPChar); |
|
291 // resource name |
|
292 TPtrC8 rname = line.Mid(firstSpace, lastSpace - firstSpace); |
|
293 // resource id |
|
294 TPtrC8 rid = line.Right( line.Length() - lastSpace - 1 ); |
|
295 // trim resource name |
|
296 HBufC8* rnameTrimmed = rname.AllocLC(); |
|
297 rnameTrimmed->Des().Trim(); |
|
298 // parse numer and insert to map |
|
299 TInt id(0); |
|
300 User::LeaveIfError( HnConvUtils::Str8ToInt(rid, id) ); |
|
301 User::LeaveIfError( iResourceIDs.Insert(rnameTrimmed->AllocL(), id) ); |
|
302 CleanupStack::PopAndDestroy(rnameTrimmed); |
|
303 // start search from next line |
|
304 content.Set(content.Mid( posEoL + 1 )); |
|
305 } |
|
306 } |
|
307 |
|
308 // --------------------------------------------------------------------------- |
|
309 // |
|
310 // --------------------------------------------------------------------------- |
|
311 // |
|
312 void CHnMdLocalizationElement::ParseRsgContentL( const TDesC8& aContent, |
|
313 const TDesC8& aResourceName ) |
|
314 { |
|
315 TPtrC8 content(aContent); |
|
316 |
|
317 HBufC8* resourceName = HBufC8::NewLC( aResourceName.Length() |
|
318 + 2 /* extra spaces */ ); |
|
319 // add extra space to make sure that we find the right one |
|
320 resourceName->Des().Append(KSPChar); |
|
321 resourceName->Des().Append(aResourceName); |
|
322 resourceName->Des().Append(KSPChar); |
|
323 |
|
324 TInt position = content.Find(*resourceName); |
|
325 User::LeaveIfError(position); // we can not find resource |
|
326 TPtrC8 contentAfterMid = content.Mid( position + |
|
327 resourceName->Length()); |
|
328 |
|
329 TInt posResId = contentAfterMid.Locate(KNLChar); |
|
330 User::LeaveIfError(posResId); // we can not find resource |
|
331 TPtrC8 rid = contentAfterMid.Left(posResId - 1); |
|
332 |
|
333 HBufC8* ridTrimmed = rid.AllocLC(); |
|
334 ridTrimmed->Des().Trim(); |
|
335 // trim also resource name |
|
336 resourceName->Des().Trim(); |
|
337 |
|
338 TInt id(0); |
|
339 User::LeaveIfError( HnConvUtils::Str8ToInt( *ridTrimmed, id) ); |
|
340 User::LeaveIfError( iResourceIDs.Insert( resourceName->AllocL(), id) ); |
|
341 // clean up |
|
342 CleanupStack::PopAndDestroy(ridTrimmed); |
|
343 CleanupStack::PopAndDestroy(resourceName); |
|
344 } |