|
1 #ifndef __ENCDEC_H__ |
|
2 #define __ENCDEC_H__ |
|
3 /* |
|
4 * Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
5 * All rights reserved. |
|
6 * This component and the accompanying materials are made available |
|
7 * under the terms of the License "Eclipse Public License v1.0" |
|
8 * which accompanies this distribution, and is available |
|
9 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
10 * |
|
11 * Initial Contributors: |
|
12 * Nokia Corporation - initial contribution. |
|
13 * |
|
14 * Contributors: |
|
15 * |
|
16 * Description: |
|
17 * |
|
18 */ |
|
19 |
|
20 |
|
21 #include <s32strm.h> |
|
22 #include "filestream.h" |
|
23 #include "logger.h" |
|
24 |
|
25 /** |
|
26 * @file |
|
27 * @internalComponent |
|
28 */ |
|
29 |
|
30 typedef uint64_t TUint64; |
|
31 typedef int64_t TInt64; |
|
32 |
|
33 typedef int TInt32; |
|
34 typedef unsigned int TUint32; |
|
35 |
|
36 typedef short TInt16; |
|
37 typedef unsigned short TUint16; |
|
38 |
|
39 typedef signed char TInt8; |
|
40 typedef unsigned char TUint8; |
|
41 |
|
42 typedef TUint32 TChar; |
|
43 |
|
44 typedef int TBool; |
|
45 |
|
46 typedef void TAny; |
|
47 |
|
48 TUint8 fromHex(TUint8 ch); |
|
49 TUint32 ReadUnsignedNumber(std::string &aStr, size_t aSize); |
|
50 class RDecodeReadStream |
|
51 { |
|
52 public: |
|
53 // Create store based stream in binary mode |
|
54 RDecodeReadStream(CFileStore *aStore, RReadStream &aReadStream); |
|
55 // Create a file based stream in human mode |
|
56 RDecodeReadStream(const std::string &aCertBaseName, RReadStream &aReadStream); |
|
57 |
|
58 void RawRead(void *aPtr, TUint32 aLength); |
|
59 |
|
60 void CheckName(const std::string &aExpected); |
|
61 TUint32 ReadUnsignedNumber(size_t aSize); |
|
62 |
|
63 // Return current token |
|
64 const std::string &Token() const; |
|
65 // Discard current token and read the next |
|
66 void ReadNextToken(); |
|
67 |
|
68 // Return the token after the current token. |
|
69 // The current token is not updated. |
|
70 // This will only look ahead a single token. |
|
71 const std::string &PeakToken(); |
|
72 |
|
73 bool HumanReadable() const; |
|
74 void Close(); |
|
75 |
|
76 CFileStore *iStore; // Only used for STORE based streams ie. not human readable |
|
77 std::string iCertBaseName; // Only used for file based streams ie. human readable |
|
78 |
|
79 RReadStream &iReadStream; |
|
80 private: |
|
81 bool iHumanReadable; |
|
82 std::string iToken; |
|
83 bool iPrefetchedTokenIsValid; |
|
84 std::string iPrefetchedToken; |
|
85 |
|
86 void GetToken(std::string &aToken); |
|
87 }; |
|
88 |
|
89 |
|
90 class REncodeWriteStream |
|
91 { |
|
92 public: |
|
93 // Construct stream based on a store in binary mode |
|
94 REncodeWriteStream(CFileStore *aStore, RWriteStream &aWriteStream); // store stream |
|
95 // Construct stream based on a file in human mode |
|
96 REncodeWriteStream(const std::string &aCertBaseName, RWriteStream &aWriteStream); // file stream |
|
97 // Create a human readable log |
|
98 REncodeWriteStream(Log &aLog); |
|
99 |
|
100 /** |
|
101 Write binary data to the output stream without escaping |
|
102 it. This data is allowed to contain the NUL (0) character and |
|
103 may be binary data for the store file or UTF-8 text for the |
|
104 human readable config file output. |
|
105 */ |
|
106 void WriteBin(const void *aPtr, TUint32 aLength); |
|
107 /** |
|
108 Write a C style string to the output stream without escaping |
|
109 it. It is NOT safe to write a generic UTF-8 string via this |
|
110 this function, because such a string may contain embedded 0 |
|
111 characters. A 7-bit ASCII string will work reliably. This |
|
112 function is intended for writing 7-but ASCII strings to the |
|
113 human readable config file, and should not be used for writing |
|
114 data to a store file. |
|
115 */ |
|
116 void WriteQuotedUtf8(const void *aStr, TUint32 aLength); |
|
117 /** |
|
118 Write a single byte. |
|
119 */ |
|
120 void WriteByte(TUint8 aByte); |
|
121 /** |
|
122 Write a UTF-8 string quoting backslash and double quote characters. |
|
123 |
|
124 A backslash will be written as \\ |
|
125 A quote character will be written as \" |
|
126 |
|
127 Note that all bytes in UTF-8 escape sequences have the top bit |
|
128 set therefore the quoting technique used by this function will |
|
129 not effect them. |
|
130 */ |
|
131 void WriteCStr(const void *aCstr); |
|
132 |
|
133 void WriteHexNumber(TUint32 aNumber); |
|
134 |
|
135 void WriteSpace(); |
|
136 void WriteLineEnd(); |
|
137 |
|
138 void WriteIndent(); |
|
139 void IncIndent(); |
|
140 void DecIndent(); |
|
141 |
|
142 bool HumanReadable() const; |
|
143 bool &PemOut(); |
|
144 bool &Verbose(); |
|
145 void Close(); |
|
146 |
|
147 bool Quiet() const; |
|
148 |
|
149 CFileStore *StoreObject(); |
|
150 RWriteStream &StoreWriteStream(); |
|
151 |
|
152 std::string CertFileName(TUint32 aFormat, TUint32 aCertNumber); |
|
153 |
|
154 private: |
|
155 CFileStore *iStore; // Only used for STORE based streams ie. not human readable |
|
156 std::string iCertBaseName; // Only used for file based streams ie. human readable |
|
157 |
|
158 RWriteStream *iWriteStream; // STORE or file based stream, valid if iLogStream==0 |
|
159 |
|
160 std::ostream *iLogStream; |
|
161 private: |
|
162 bool iHumanReadable; |
|
163 bool iPemOut; |
|
164 bool iVerbose; |
|
165 int iIndentLevel; |
|
166 }; |
|
167 |
|
168 /** |
|
169 A template which generates a class which can be |
|
170 internalised/externalised via the REncodeWriteStream and |
|
171 RDecodeReadStream templates. |
|
172 |
|
173 The constructor takes a C string constant which specifies the field |
|
174 name. |
|
175 |
|
176 The optional aCommentOnlyInHumanMode parameter changes operation in human |
|
177 mode only - The field will be written as a comment, and will not be |
|
178 accepted whilst reading. |
|
179 |
|
180 Typical use is something like this:- |
|
181 EncDecObject<TUint32> fieldCost("cost"); |
|
182 |
|
183 Typically this template will not require specialisations to handle |
|
184 additional types. |
|
185 */ |
|
186 template <class T> class EncDecObject |
|
187 { |
|
188 public: |
|
189 EncDecObject(const char *aName, bool aCommentOnlyInHumanMode = false) |
|
190 : iName(aName), iCommentOnlyInHumanMode(aCommentOnlyInHumanMode), iValue() |
|
191 { |
|
192 } |
|
193 |
|
194 const std::string &Name() const { return iName; } |
|
195 |
|
196 const T &Value() const { return iValue; } |
|
197 T &Value() { return iValue; } |
|
198 |
|
199 bool CommentOnlyInHumanMode() const { return iCommentOnlyInHumanMode; } |
|
200 private: |
|
201 std::string iName; |
|
202 bool iCommentOnlyInHumanMode; |
|
203 T iValue; |
|
204 }; |
|
205 |
|
206 /** |
|
207 Class for handling Enum values |
|
208 */ |
|
209 struct EnumEntry |
|
210 { |
|
211 const char *iName; |
|
212 TUint32 iValue; |
|
213 }; |
|
214 |
|
215 // This class should be template by a type which standard store can |
|
216 // internalise/externalise ie TUint8/TUin16/TUint32 (probably not an enum) |
|
217 template<typename T>class EncDecEnum |
|
218 { |
|
219 public: |
|
220 /** |
|
221 Construct an object for handling an enum type. |
|
222 aEnumEntries must be a pointer to a static array of EnumEntry |
|
223 structs terminated by one with iName==0. |
|
224 */ |
|
225 EncDecEnum(const char *aName, const EnumEntry *aEnumEntries, bool aCommentOnlyInHumanMode = false); |
|
226 |
|
227 const std::string &Name() const { return iName; } |
|
228 |
|
229 const T &Value() const { return iValue; } |
|
230 T &Value() { return iValue; } |
|
231 |
|
232 const char *ValueName() const { return ValueToName(iValue); } |
|
233 |
|
234 bool CommentOnlyInHumanMode() const { return iCommentOnlyInHumanMode; } |
|
235 |
|
236 void SetValue(const T &aValue); |
|
237 void SetValue(const char *aName); |
|
238 private: |
|
239 const char *ValueToName(const T &aValue) const; |
|
240 std::string iName; |
|
241 TUint8 iWidth; |
|
242 const EnumEntry *iEnumEntries; // Array terminated by entry with iName==0 |
|
243 bool iCommentOnlyInHumanMode; |
|
244 T iValue; |
|
245 }; |
|
246 |
|
247 /* |
|
248 The EncDecContainer class manages a set of objects which inherit |
|
249 from the EncDecContainerItem base class. It can be |
|
250 internalised/externalised via the REncodeWriteStream and |
|
251 RDecodeReadStream templates. |
|
252 |
|
253 The constructor takes a C string constant which specifies the |
|
254 container name. |
|
255 |
|
256 The binary form is a 32 bit count followed by a sequence of |
|
257 EncDecContainerItem objects. |
|
258 |
|
259 In human readable form is a sequence of zero or more human readable |
|
260 representations of T bracketed by StartX and EndX. Where X is the |
|
261 container name. |
|
262 */ |
|
263 class EncDecContainerItem |
|
264 { |
|
265 public: |
|
266 virtual ~EncDecContainerItem(); |
|
267 |
|
268 // Get the type name for the container. If 0 then do not bracket item with StartType/EndType |
|
269 virtual const char *ItemType() const = 0; |
|
270 // If ItemType()!=0 then ItemName will be included after StartType |
|
271 virtual std::string ItemName() const; |
|
272 virtual void SetItemName(const std::string &aName); |
|
273 virtual void Encode(REncodeWriteStream &aWriteStream) = 0; |
|
274 virtual void Decode(RDecodeReadStream &aReadStream) = 0; |
|
275 }; |
|
276 |
|
277 typedef EncDecContainerItem *EncDecContainerItemFactoryFunc(); |
|
278 |
|
279 class EncDecContainer |
|
280 { |
|
281 public: |
|
282 EncDecContainer(const char *aContainerName, EncDecContainerItemFactoryFunc *aFactory); |
|
283 ~EncDecContainer(); |
|
284 |
|
285 void push_back(EncDecContainerItem *aItem); |
|
286 const EncDecContainerItem &operator[](TUint32 aIndex) const; |
|
287 EncDecContainerItem &operator[](TUint32 aIndex); |
|
288 TUint32 size() const; |
|
289 void reset(); |
|
290 |
|
291 void Encode(REncodeWriteStream &aWriteStream) const; |
|
292 void Decode(RDecodeReadStream &aReadStream); |
|
293 |
|
294 private: |
|
295 std::string iName; |
|
296 EncDecContainerItemFactoryFunc *iFactory; |
|
297 std::vector<EncDecContainerItem *> iArray; |
|
298 }; |
|
299 |
|
300 void readContainer(const std::string &aFileName, bool aHuman, EncDecContainer &container); |
|
301 void writeContainer(const char *aFileName, bool aHuman, bool aPemOut, bool aVerbose, const EncDecContainer &container); |
|
302 |
|
303 /* |
|
304 The EncodeHuman template functions are used to convert a type to |
|
305 human readable form. |
|
306 |
|
307 Do NOT try and write specialisations of these templates, it probably |
|
308 will not work, instead just write a conventional function which is |
|
309 selected via the norml overloading rules. See GOTW articles on the |
|
310 web. |
|
311 */ |
|
312 |
|
313 // The basic EncodeHuman template assumes that T is an unsigned |
|
314 // integer and encodes it in hex. |
|
315 template <class T> void EncodeHuman(REncodeWriteStream& aStream,const T &aUnsignedIntType) |
|
316 { |
|
317 aStream.WriteHexNumber(aUnsignedIntType); |
|
318 } |
|
319 |
|
320 void EncodeHuman(REncodeWriteStream& aStream,const TUid &aUid); |
|
321 void EncodeHuman(REncodeWriteStream& aStream,const TName &aName); |
|
322 |
|
323 /* |
|
324 The DecodeHuman template functions are used to read in the human |
|
325 readable form. |
|
326 |
|
327 Do NOT try and write specialisations of these templates, it probably |
|
328 will not work, instead just write a conventional function which is |
|
329 selected via the norml overloading rules. See GOTW articles on the |
|
330 web. |
|
331 */ |
|
332 |
|
333 // The basic DecodeHuman template assumes that T is an unsigned integer |
|
334 // and decodes it from either decimal or hex (starting with 0x). The |
|
335 // code calls RDecodeReadStream::ReadUnsignedNumber which will decode |
|
336 // the number (max 32bits) and check it fits into specified type. |
|
337 template <class T> void DecodeHuman(RDecodeReadStream& aStream,T &aUnsignedIntType) |
|
338 { |
|
339 aUnsignedIntType = (T) aStream.ReadUnsignedNumber(sizeof(aUnsignedIntType)); |
|
340 } |
|
341 |
|
342 void DecodeHuman(RDecodeReadStream& aStream,TUid &aUid); |
|
343 void DecodeHuman(RDecodeReadStream& aStream,TName &aName); |
|
344 |
|
345 /* |
|
346 The following two template operators require the object which is |
|
347 being internalised or externalised to provide a const Name function |
|
348 (which returns the field name) and two Value functions (one const |
|
349 and one not) which return a reference to an instance of the type |
|
350 being handled. A function called CommentOnlyInHumanMode should |
|
351 return true if the human output should be prefixed with # and should |
|
352 be reject when reading. |
|
353 |
|
354 Typicaly types will be wrapped by the EncDecObject template to |
|
355 provide the Name() and Value() functions required by these |
|
356 templates. |
|
357 |
|
358 Do NOT try and write specialisations of these templates, it probably |
|
359 will not work, instead just write a conventional function which is |
|
360 selected via the norml overloading rules. See GOTW articles on the |
|
361 web. |
|
362 |
|
363 Note: You probably only need to enhance the EncodeHuman/DecodeHuman |
|
364 functions unless you are adding a new variable length container type. |
|
365 */ |
|
366 |
|
367 /* |
|
368 The externalise operator << first checks if the destination stream |
|
369 is HumanReadable. If it is, it writes the Name(), followed by a |
|
370 space, calls EncodeHuman, then WriteLineEnd. If the stream is not |
|
371 HumanReadable it simply applies the << operator to the Value(). |
|
372 */ |
|
373 template <class T> |
|
374 inline REncodeWriteStream& operator<<(REncodeWriteStream& aStream,const T& anObject); |
|
375 |
|
376 REncodeWriteStream& operator<<(REncodeWriteStream& aStream, const EncDecContainer &aContainer); |
|
377 |
|
378 template <typename T> |
|
379 REncodeWriteStream& operator<<(REncodeWriteStream& aStream, const EncDecEnum<T> &aEncDecEnum); |
|
380 |
|
381 /* |
|
382 The internalise operator >> first checks if the source stream is |
|
383 HumanReadable. If it is, it reads/checks the field name then calls |
|
384 DecodeHuman. If the stream is not HumanReadable |
|
385 it simply applies the >> operator to the Value(). |
|
386 */ |
|
387 template <class T> |
|
388 inline RDecodeReadStream& operator>>(RDecodeReadStream& aStream,T& anObject); |
|
389 |
|
390 RDecodeReadStream& operator>>(RDecodeReadStream& aStream,EncDecContainer &aContainer); |
|
391 |
|
392 template <typename T> |
|
393 RDecodeReadStream& operator>>(RDecodeReadStream& aStream, EncDecEnum<T> &aEncDecEnum); |
|
394 |
|
395 #include "encdec.inl" |
|
396 |
|
397 |
|
398 |
|
399 #endif |