|
1 /* |
|
2 * Copyright (c) 2005-2009 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 the License "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 |
|
20 #include "streamreader.h" |
|
21 #include "options.h" |
|
22 #include "ucmp.h" |
|
23 #include "utf8.h" |
|
24 |
|
25 StreamReader::StreamReader(istream& aFile) |
|
26 :iFileStream(&aFile), |
|
27 iBuf(NULL), |
|
28 iCurrentPos(NULL), |
|
29 iLength(0), |
|
30 iStreamOwnership(false) |
|
31 { |
|
32 } |
|
33 |
|
34 |
|
35 StreamReader::StreamReader(const char* aRegFile) |
|
36 :iBuf (0) , |
|
37 iCurrentPos (0), |
|
38 iStreamOwnership(true) |
|
39 { |
|
40 iFileStream = new ifstream(aRegFile, ios::binary ); |
|
41 } |
|
42 |
|
43 bool StreamReader::Initialise() |
|
44 { |
|
45 // get length of file: |
|
46 iFileStream->seekg (0, ios::end); |
|
47 iLength = iFileStream->tellg(); |
|
48 |
|
49 //checks if file is empty |
|
50 if(!iLength) |
|
51 { |
|
52 return true; |
|
53 } |
|
54 |
|
55 iFileStream->seekg (0, ios::beg); |
|
56 // allocate memory: |
|
57 iBuf = new char [iLength]; |
|
58 iCurrentPos = iBuf; |
|
59 // read data as a block: |
|
60 iFileStream->read (iCurrentPos,iLength); |
|
61 |
|
62 return false; |
|
63 } |
|
64 |
|
65 |
|
66 unsigned int StreamReader::ReadInt32() |
|
67 { |
|
68 int i = 0; |
|
69 if ((iLength - (iCurrentPos - iBuf)) < 4) |
|
70 { |
|
71 throw EInvalidFile; |
|
72 } |
|
73 unsigned int result = (iCurrentPos[i] & 0x000000FF) + ((iCurrentPos[i+1] << 8) & 0x0000FF00) + |
|
74 ((iCurrentPos[i+2] << 16) & 0x00FF0000) + ((iCurrentPos[i+3] << 24) & 0xFF000000) ; |
|
75 |
|
76 iCurrentPos += 4; |
|
77 return result; |
|
78 } |
|
79 |
|
80 unsigned short int StreamReader::ReadInt16() |
|
81 { |
|
82 int i = 0; |
|
83 if ((iLength - (iCurrentPos - iBuf)) < 2) |
|
84 { |
|
85 throw EInvalidFile; |
|
86 } |
|
87 unsigned short int result = (iCurrentPos[i] & 0x00FF) |
|
88 + ((iCurrentPos[i+1] << 8) & 0xFF00); |
|
89 |
|
90 iCurrentPos += 2; |
|
91 |
|
92 return result; |
|
93 } |
|
94 |
|
95 unsigned char StreamReader::ReadInt8() |
|
96 { |
|
97 int i = 0; |
|
98 if ((iLength - (iCurrentPos - iBuf)) < 1) |
|
99 { |
|
100 throw EInvalidFile; |
|
101 } |
|
102 unsigned char result = iCurrentPos[i]; |
|
103 iCurrentPos += 1; |
|
104 |
|
105 return result; |
|
106 } |
|
107 |
|
108 |
|
109 unsigned char StreamReader::Peek() |
|
110 { |
|
111 unsigned char result = ReadInt8(); |
|
112 iCurrentPos -= 1; |
|
113 return result; |
|
114 } |
|
115 |
|
116 |
|
117 char* StreamReader::ReadDescriptor() |
|
118 { |
|
119 bool isWide = false; |
|
120 int len = GetDescriptorInfo(isWide); |
|
121 |
|
122 // allocate a buffer big enough to hold this stuff and |
|
123 // a null at the end |
|
124 char *result = NULL; |
|
125 |
|
126 TInt32 bytesRead = 0; |
|
127 |
|
128 if(isWide) |
|
129 { |
|
130 wchar_t* buffer = new wchar_t[len + 1]; |
|
131 TMemoryUnicodeSink unicodeTarget(buffer); |
|
132 |
|
133 TUnicodeExpander converter; |
|
134 |
|
135 converter.Expand(unicodeTarget, (const TUint8*)iCurrentPos, len, KMaxTInt, NULL, &bytesRead); |
|
136 |
|
137 buffer[len] = 0; |
|
138 |
|
139 // UTF16toUTF8Conversion allocates memory |
|
140 // This memory will be freed by the caller of this function |
|
141 result = UTF16toUTF8Convert(buffer, len); |
|
142 |
|
143 delete []buffer; |
|
144 } |
|
145 else |
|
146 { |
|
147 // This memory will be freed by the caller of this function |
|
148 result = new char[len + 2]; |
|
149 memcpy(result, iCurrentPos, len); |
|
150 |
|
151 bytesRead = len; |
|
152 result[len] = 0; |
|
153 } |
|
154 |
|
155 iCurrentPos += bytesRead; |
|
156 return result; |
|
157 } |
|
158 |
|
159 |
|
160 int StreamReader::GetDescriptorInfo(bool& aIsWide, const bool &aConstReadPtr) |
|
161 { |
|
162 int len; |
|
163 unsigned char cardinality = Peek(); |
|
164 if ((cardinality & 0x01) == 0) |
|
165 { |
|
166 // 8 bit cardinality |
|
167 len = ReadInt8() & 0xFF; |
|
168 // shift of the cardinality bit |
|
169 len >>= 1; |
|
170 |
|
171 if(aConstReadPtr) |
|
172 { |
|
173 iCurrentPos -= 1; |
|
174 } |
|
175 } |
|
176 else if ((cardinality & 0x02) == 0) |
|
177 { |
|
178 // 16 bit cardinality |
|
179 len = ReadInt16() & 0xFFFF; |
|
180 // shift off the cardinality bits |
|
181 len >>= 2; |
|
182 |
|
183 if(aConstReadPtr) |
|
184 { |
|
185 iCurrentPos -= 2; |
|
186 } |
|
187 } |
|
188 else if ((cardinality & 0x04) == 0) |
|
189 { |
|
190 // 32 bit cardinality |
|
191 len = ReadInt32(); |
|
192 // shift off the cardinality bits |
|
193 len >>= 3; |
|
194 |
|
195 if(aConstReadPtr) |
|
196 { |
|
197 iCurrentPos -= 4; |
|
198 } |
|
199 } |
|
200 else |
|
201 { |
|
202 // WTF. Unknown cardinality |
|
203 throw EInvalidFile; |
|
204 } |
|
205 |
|
206 // read the wideness of the characters |
|
207 aIsWide = ((len & 0x01) == 0); |
|
208 // shift off the wideness bit |
|
209 len >>= 1; |
|
210 |
|
211 // check if we have enough length left in the buffer |
|
212 if ((iLength - (iCurrentPos - iBuf)) < len) |
|
213 { |
|
214 throw EInvalidFile; |
|
215 } |
|
216 |
|
217 return len; |
|
218 } |
|
219 |
|
220 |
|
221 char* StreamReader::UTF16toUTF8Convert(wchar_t* aSource, int aSrcLength) |
|
222 { |
|
223 int targetLength = 2 * aSrcLength; |
|
224 int totalSize = targetLength + 1; |
|
225 // This memory will be freed by the caller of this function |
|
226 char *ptrUtf8 = new char[targetLength + 1]; |
|
227 |
|
228 UTF16* sourceStart = static_cast<UTF16*>(aSource); |
|
229 UTF16* sourceEnd = sourceStart + aSrcLength; |
|
230 UTF8* targetStart = reinterpret_cast<UTF8*>(ptrUtf8); |
|
231 UTF8* targetEnd; |
|
232 |
|
233 ConversionResult result = ok; |
|
234 do |
|
235 { |
|
236 targetEnd = targetStart + targetLength; |
|
237 result = ConvertUTF16toUTF8(&sourceStart, sourceEnd, &targetStart, targetEnd); |
|
238 |
|
239 if(targetExhausted != result) |
|
240 { |
|
241 break; |
|
242 } |
|
243 |
|
244 // Memory reallocation |
|
245 |
|
246 int endOffset = (char *)targetStart - ptrUtf8; |
|
247 |
|
248 char *temp = new char[totalSize + targetLength]; |
|
249 |
|
250 memcpy(temp, ptrUtf8, totalSize); |
|
251 delete[] ptrUtf8; |
|
252 |
|
253 ptrUtf8 = temp; |
|
254 |
|
255 // New source pointer |
|
256 targetStart = reinterpret_cast<UTF8*>(ptrUtf8) + endOffset; |
|
257 totalSize += targetLength; |
|
258 }while(true); |
|
259 |
|
260 // NULL terminating the UTF8 string |
|
261 *targetStart = 0; |
|
262 |
|
263 return ptrUtf8; |
|
264 } |
|
265 |
|
266 |
|
267 StreamReader::~StreamReader() |
|
268 { |
|
269 if(iStreamOwnership) |
|
270 { |
|
271 ifstream* str = static_cast<ifstream *>(iFileStream); |
|
272 str->close(); |
|
273 delete iFileStream; |
|
274 } |
|
275 |
|
276 delete [] iBuf; |
|
277 } |
|
278 |