|
1 // Copyright (c) 2009 - 2010 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // Resource reader |
|
15 // |
|
16 // |
|
17 /** |
|
18 * @file BaRsReadImpl.cpp |
|
19 * |
|
20 * @internalComponent |
|
21 * @released |
|
22 */ |
|
23 #include <iostream> |
|
24 #include <cassert> |
|
25 #include <string> |
|
26 #include "barsreadimpl.h" |
|
27 #include "barsc2.h" |
|
28 |
|
29 #define REINTERPRET_CAST(type,exp) (reinterpret_cast<type>(exp)) |
|
30 |
|
31 /** @internalComponent |
|
32 An error will be issued at compile time if the class size is not KRsReaderImplSize. */ |
|
33 TResourceReaderImpl::TResourceReaderImpl() : |
|
34 iBuffer(NULL), |
|
35 iCurrentPtr(NULL) |
|
36 { |
|
37 //TResourceReaderImpl size. It should be 8 because of the BC reasons. |
|
38 //8 is the size of TResourceReader class. |
|
39 enum |
|
40 { |
|
41 KRsReaderImplSize = 8 |
|
42 }; |
|
43 assert(sizeof(TResourceReaderImpl) == KRsReaderImplSize); |
|
44 } |
|
45 |
|
46 /** Sets the buffer containing the resource data. |
|
47 |
|
48 The current position within the buffer is set to the start of the buffer so |
|
49 that subsequent calls to the interpreting functions, for example ReadInt8(), |
|
50 start at the beginning of this buffer. |
|
51 |
|
52 @internalComponent |
|
53 @param aBuffer Pointer to an 8 bit non-modifiable buffer containing |
|
54 or representing resource data. |
|
55 @param aResourceId The numeric id of the resource to be read. |
|
56 @post Buffer pointer is initialized. |
|
57 @post Buffer current position pointer is initialized. */ |
|
58 void TResourceReaderImpl::SetBuffer(const Ptr8* aBuffer) |
|
59 { |
|
60 iBuffer=aBuffer; |
|
61 iCurrentPtr= (TUint8*)iBuffer->GetPtr(); |
|
62 } |
|
63 |
|
64 /** Sets the buffer and current position to NULL. |
|
65 @internalComponent |
|
66 @post Buffer pointer is set to NULL. |
|
67 @post Buffer current position pointer is set to NULL. */ |
|
68 void TResourceReaderImpl::ResetBuffer() |
|
69 { |
|
70 iBuffer=NULL; |
|
71 iCurrentPtr=NULL; |
|
72 } |
|
73 |
|
74 /** Returns the current position within the resource buffer. |
|
75 |
|
76 The function makes no assumption about the type of data in the buffer at the |
|
77 current position. |
|
78 |
|
79 @internalComponent |
|
80 @return A pointer to the current position within the resource buffer. */ |
|
81 const TAny* TResourceReaderImpl::Ptr() |
|
82 { |
|
83 return(iCurrentPtr); |
|
84 } |
|
85 |
|
86 /** Updates iCurrentPtr with a new value. |
|
87 |
|
88 @internalComponent |
|
89 @pre iBuffer is not NULL. |
|
90 @pre aPtr is not NULL. |
|
91 @param aPtr The new value of iCurrentPtr. |
|
92 @post iCurrentPtr is updated. |
|
93 @leave KErrOff The new iCurrentPtr points beyond the buffer end. */ |
|
94 void TResourceReaderImpl::MovePtrL(const TUint8* aPtr) |
|
95 { |
|
96 assert(iBuffer != NULL); |
|
97 assert(aPtr != NULL); |
|
98 if(aPtr > ((TUint8*)( iBuffer->GetPtr() + iBuffer->GetLength() ))) |
|
99 { |
|
100 std::string errMsg= "Failed : Trying to access pointer beyond valid range for registrationFile"; |
|
101 throw CResourceFileException(errMsg); |
|
102 } |
|
103 |
|
104 iCurrentPtr=aPtr; |
|
105 } |
|
106 |
|
107 /** Interprets the data at the current buffer position as leading byte count data |
|
108 and constructs a 16 bit heap buffer containing a copy of this data. |
|
109 |
|
110 The data is interpreted as: |
|
111 |
|
112 a byte value defining the number of 16 bit text characters |
|
113 (the resource string/binary data length is limited to 255 characters max) |
|
114 |
|
115 followed by: |
|
116 |
|
117 the 16 bit text characters. |
|
118 |
|
119 If the value of the leading byte is zero, the function assumes that no data |
|
120 follows the leading byte and returns a NULL pointer. |
|
121 |
|
122 The current position within the resource buffer is updated. |
|
123 |
|
124 Do not use this explicit 16 bit variant when the resource contains binary |
|
125 data; use the explicit 8 bit variant instead. If the resource contains text, |
|
126 use the build independent variant ReadHBufCL(). |
|
127 |
|
128 @internalComponent |
|
129 @pre The same as for ReadTPtrC16L(). |
|
130 @return Pointer to the 16bit heap buffer containing a |
|
131 copy of the data following the leading byte count at |
|
132 the current position within the resource buffer. The |
|
133 pointer can be NULL. |
|
134 @post iCurrentPtr is updated. |
|
135 @leave The same as ReadTPtrC16L(). |
|
136 @see ReadTPtrC16L() */ |
|
137 |
|
138 Ptr16* TResourceReaderImpl::ReadHBufCL() |
|
139 { |
|
140 |
|
141 PtrC16* ucode = ReadTPtrC16L(); |
|
142 if(NULL==ucode) |
|
143 return NULL; |
|
144 Ptr16* unicode = new Ptr16(ucode->iMaxLength); |
|
145 memcpy(unicode->GetPtr(),ucode->iPtr,ucode->iMaxLength*2); |
|
146 unicode->UpdateLength(ucode->iMaxLength); |
|
147 return unicode; |
|
148 } |
|
149 |
|
150 |
|
151 /** Interprets the data at the current buffer position as leading byte count data |
|
152 and constructs an 8 bit non modifiable pointer to represent this data. |
|
153 |
|
154 The data is interpreted as: |
|
155 |
|
156 a byte value defining the number of text characters or the length of binary |
|
157 data (the resource string/binary data length is limited to 255 characters max) |
|
158 |
|
159 followed by: |
|
160 |
|
161 the 8 bit text characters or binary data. |
|
162 |
|
163 If the value of the leading byte is zero, calling Length() on the returned |
|
164 TPtrC8 returns zero. |
|
165 |
|
166 The current position within the resource buffer is updated. |
|
167 |
|
168 Use this explicit 8 bit variant when the resource contains binary data. If |
|
169 the resource contains text, then use the build independent variant ReadTPtrC(). |
|
170 |
|
171 In general, this type of resource data corresponds to one of the following: |
|
172 |
|
173 a LTEXT type in a resource STRUCT declaration. |
|
174 |
|
175 a variable length array within a STRUCT declaration which includes the LEN |
|
176 BYTE keywords. |
|
177 |
|
178 @internalComponent |
|
179 @pre iCurrentPtr != NULL. |
|
180 @pre The same as MovePtrL(const TUint8* aPtr). |
|
181 @return 8bit non modifiable pointer representing |
|
182 the data following the leading byte count at the |
|
183 current position within the resource buffer. |
|
184 @post iCurrentPtr is updated. |
|
185 @leave The same as MovePtrL(const TUint8* aPtr). |
|
186 @see MovePtrL(const TUint8* aPtr) */ |
|
187 PtrC8* TResourceReaderImpl::ReadTPtrC8L() |
|
188 { |
|
189 assert(iCurrentPtr != NULL); |
|
190 const TUint8* currentPtr=iCurrentPtr;//TUint8 pointer is used, which means that the |
|
191 //resource string length is limited to 255 characters max. |
|
192 const TInt strLen=*currentPtr; |
|
193 ++currentPtr; |
|
194 |
|
195 PtrC8* unicode = new PtrC8; |
|
196 |
|
197 if(!strLen) |
|
198 unicode = NULL; |
|
199 else |
|
200 { |
|
201 unicode ->iMaxLength = strLen; |
|
202 unicode ->iPtr = currentPtr; |
|
203 } |
|
204 MovePtrL(currentPtr+strLen); |
|
205 return unicode; |
|
206 } |
|
207 |
|
208 /** Interprets the data at the current buffer position as leading byte count data |
|
209 and constructs a 16 bit non modifiable pointer to represent this data. |
|
210 |
|
211 The data is interpreted as: |
|
212 |
|
213 a byte value defining the number of 16 bit text characters |
|
214 (the resource string/binary data length is limited to 255 characters max) |
|
215 |
|
216 followed by: |
|
217 |
|
218 the 16 bit text characters. |
|
219 |
|
220 If the value of the leading byte is zero, calling Length() on the returned |
|
221 TPtrC16 returns zero. |
|
222 |
|
223 The current position within the resource buffer is updated. |
|
224 |
|
225 Do not use this explicit 16 bit variant when the resource contains binary |
|
226 data; use the explicit 8 bit variant instead. If the resource contains text, |
|
227 use the build independent variant ReadTPtrC(). |
|
228 |
|
229 @internalComponent |
|
230 @pre iCurrentPtr != NULL. |
|
231 @pre The same as MovePtrL(const TUint8* aPtr). |
|
232 @return Pointer to an 8bit variant flat array. |
|
233 @post iCurrentPtr is updated. |
|
234 @leave KErrCorrupt The resource is a unicode string and it is not properly aligned. |
|
235 @leave The same as MovePtrL(const TUint8* aPtr). |
|
236 @see MovePtrL(const TUint8* aPtr) */ |
|
237 |
|
238 PtrC16* TResourceReaderImpl::ReadTPtrC16L() |
|
239 { |
|
240 assert(iCurrentPtr != NULL); |
|
241 const TUint8* currentPtr=iCurrentPtr;//TUint8 pointer is used, which means that the |
|
242 |
|
243 //resource string length is limited to 255 characters max. |
|
244 const TInt unicodeLength=*currentPtr; |
|
245 ++currentPtr; |
|
246 if (unicodeLength!=0) |
|
247 { |
|
248 if (REINTERPRET_CAST(TUint,currentPtr)&0x1) |
|
249 { |
|
250 // The resource compiler puts out a padding byte (arbitrarily 0xab) |
|
251 // to ensure the alignment of Unicode strings within each resource. |
|
252 if(*currentPtr!=0xab) |
|
253 { |
|
254 std::string errMsg= "Failed : Improper alignment of Unicode strings (0xab) within each resource."; |
|
255 throw CResourceFileException(errMsg); |
|
256 } |
|
257 ++currentPtr; |
|
258 } |
|
259 } |
|
260 |
|
261 if (unicodeLength ==0) |
|
262 { |
|
263 MovePtrL(currentPtr); |
|
264 return NULL; |
|
265 } |
|
266 else |
|
267 { |
|
268 PtrC16* unicode = new PtrC16; |
|
269 unicode ->iMaxLength = unicodeLength; |
|
270 unicode ->iPtr = (TUint16*) currentPtr; |
|
271 |
|
272 currentPtr+=unicodeLength*sizeof(TText16); |
|
273 MovePtrL(currentPtr); |
|
274 return unicode; |
|
275 } |
|
276 } |
|
277 |
|
278 |
|
279 /** Interprets the data at the current buffer position as a TInt8 type and returns |
|
280 the value as a TInt. |
|
281 |
|
282 The current position within the resource buffer is updated. |
|
283 |
|
284 In general, a TInt8 corresponds to a BYTE type in a resource STRUCT declaration. |
|
285 |
|
286 Note that in Symbian OS, a TInt is at least as big as a TInt8. |
|
287 |
|
288 @internalComponent |
|
289 @pre iCurrentPtr != NULL. |
|
290 @pre The same as MovePtrL(const TUint8* aPtr). |
|
291 @return The TInt8 value taken from the resource buffer. |
|
292 @post The same as MovePtrL(const TUint8* aPtr). |
|
293 @leave The same as MovePtrL(const TUint8* aPtr). |
|
294 @see MovePtrL(const TUint8* aPtr) */ |
|
295 TInt TResourceReaderImpl::ReadInt8L() |
|
296 { |
|
297 assert(iCurrentPtr != NULL); |
|
298 const TUint8* currentPtr=iCurrentPtr; |
|
299 MovePtrL(currentPtr+sizeof(TInt8)); |
|
300 return(*(TInt8*)currentPtr); |
|
301 } |
|
302 |
|
303 /** Interprets the data at the current buffer position as a TUint8 type and returns |
|
304 the value as a TUint. |
|
305 |
|
306 The current position within the resource buffer is updated. |
|
307 |
|
308 In general, a TUint8 corresponds to a BYTE type in a resource STRUCT declaration. |
|
309 |
|
310 Note that in Symbian OS, a TUint is at least as big as a TUint8. |
|
311 |
|
312 @internalComponent |
|
313 @pre iCurrentPtr != NULL. |
|
314 @pre The same as MovePtrL(const TUint8* aPtr). |
|
315 @return The TUint8 value taken from the resource buffer. |
|
316 @post The same as MovePtrL(const TUint8* aPtr). |
|
317 @leave The same as MovePtrL(const TUint8* aPtr). |
|
318 @see MovePtrL(const TUint8* aPtr) */ |
|
319 TUint32 TResourceReaderImpl::ReadUint8L() |
|
320 { |
|
321 assert(iCurrentPtr != NULL); |
|
322 const TUint8* currentPtr=iCurrentPtr; |
|
323 MovePtrL(currentPtr+sizeof(TUint8)); |
|
324 return(*(TUint8*)currentPtr); |
|
325 } |
|
326 |
|
327 /** Interprets the data at the current buffer position as a TInt16 type and returns |
|
328 the value as a TInt. |
|
329 |
|
330 The current position within the resource buffer is updated. |
|
331 |
|
332 In general, a TInt16 corresponds to a WORD type in a resource STRUCT declaration. |
|
333 |
|
334 Note that in Symbian OS, a TInt is at least as big as a TInt16. |
|
335 |
|
336 @internalComponent |
|
337 @pre iCurrentPtr != NULL. |
|
338 @pre The same as MovePtrL(const TUint8* aPtr). |
|
339 @return The TInt16 value taken from the resource buffer. |
|
340 @post The same as MovePtrL(const TUint8* aPtr). |
|
341 @leave The same as MovePtrL(const TUint8* aPtr). |
|
342 @see MovePtrL(const TUint8* aPtr) */ |
|
343 TInt TResourceReaderImpl::ReadInt16L() |
|
344 { |
|
345 assert(iCurrentPtr != NULL); |
|
346 if (((TUint32)iCurrentPtr)%2) |
|
347 { |
|
348 TInt16 ret; |
|
349 ReadL(&ret,sizeof(ret)); |
|
350 return(ret); |
|
351 } |
|
352 const TUint8* currentPtr=iCurrentPtr; |
|
353 MovePtrL(currentPtr+sizeof(TInt16)); |
|
354 return(*(TInt16*)currentPtr); |
|
355 } |
|
356 |
|
357 /** Interprets the data at the current buffer position as a TInt32 type and returns |
|
358 the value as a TInt. |
|
359 |
|
360 The current position within the resource buffer is updated. |
|
361 |
|
362 In general, a TInt32 corresponds to a LONG type in a resource STRUCT declaration. |
|
363 |
|
364 Note that in Symbian OS, TInt and TInt32 are the same size. |
|
365 |
|
366 @internalComponent |
|
367 @pre iCurrentPtr != NULL. |
|
368 @pre The same as MovePtrL(const TUint8* aPtr). |
|
369 @return The TInt32 value taken from the resource buffer. |
|
370 @post The same as MovePtrL(const TUint8* aPtr). |
|
371 @leave The same as MovePtrL(const TUint8* aPtr). |
|
372 @see MovePtrL(const TUint8* aPtr) */ |
|
373 TInt TResourceReaderImpl::ReadInt32L() |
|
374 { |
|
375 assert(iCurrentPtr != NULL); |
|
376 if (((TUint)iCurrentPtr)%4) |
|
377 { |
|
378 TInt32 ret; |
|
379 ReadL(&ret,sizeof(ret)); |
|
380 return(ret); |
|
381 } |
|
382 const TUint8* currentPtr=iCurrentPtr; |
|
383 MovePtrL(currentPtr+sizeof(TInt32)); |
|
384 return(*(TInt32*)currentPtr); |
|
385 } |
|
386 |
|
387 |
|
388 /** Interprets the data at the current buffer position as a TUint32 type and returns |
|
389 the value as a TUint. |
|
390 |
|
391 The current position within the resource buffer is updated. |
|
392 |
|
393 In general, a TUint32 corresponds to a LONG type in a resource STRUCT declaration. |
|
394 |
|
395 Note that in Symbian OS a TUint is the same size as a TUint32. |
|
396 |
|
397 @internalComponent |
|
398 @pre iCurrentPtr != NULL. |
|
399 @pre The same as MovePtrL(const TUint8* aPtr). |
|
400 @return The TUint32 value taken from the resource buffer. |
|
401 @post The same as MovePtrL(const TUint8* aPtr). |
|
402 @leave The same as MovePtrL(const TUint8* aPtr). |
|
403 @see MovePtrL(const TUint8* aPtr) */ |
|
404 TUint32 TResourceReaderImpl::ReadUint32L() |
|
405 { |
|
406 assert(iCurrentPtr != NULL); |
|
407 if (((TUint32)iCurrentPtr)%4) |
|
408 { |
|
409 TUint32 ret; |
|
410 ReadL(&ret,sizeof(ret)); |
|
411 return(ret); |
|
412 } |
|
413 const TUint8* currentPtr=iCurrentPtr; |
|
414 MovePtrL(currentPtr+sizeof(TUint32)); |
|
415 return(*(TUint32*)currentPtr); |
|
416 } |
|
417 |
|
418 /** Copies a specified length of data from the resource buffer, starting at the |
|
419 current position within the buffer, into the location pointed to by a specified |
|
420 pointer. No assumption is made about the type of data at being read. |
|
421 |
|
422 The current position within the resource buffer is updated. |
|
423 |
|
424 @internalComponent |
|
425 @pre iCurrentPtr != NULL. |
|
426 @pre The same as MovePtrL(const TUint8* aPtr). |
|
427 @param aPtr Pointer to the target location for data copied from the resource buffer. |
|
428 @param aLength The length of data to be copied from the resource buffer. |
|
429 @post The same as MovePtrL(const TUint8* aPtr). |
|
430 @leave The same as MovePtrL(const TUint8* aPtr). |
|
431 @see MovePtrL(const TUint8* aPtr) */ |
|
432 void TResourceReaderImpl::ReadL(TAny* aPtr,TInt aLength) |
|
433 { |
|
434 assert(iCurrentPtr != NULL); |
|
435 const TUint8* currentPtr=iCurrentPtr; |
|
436 MovePtrL(currentPtr+aLength); |
|
437 memcpy(aPtr,currentPtr,aLength); |
|
438 } |