Update contrib.
3 * Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
5 * This component and the accompanying materials are made available
6 * under the terms of the License "Eclipse Public License v1.0"
7 * which accompanies this distribution, and is available
8 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
10 * Initial Contributors:
11 * Nokia Corporation - initial contribution.
21 #include "filestream.h"
29 typedef uint64_t TUint64;
30 typedef int64_t TInt64;
33 typedef unsigned int TUint32;
36 typedef unsigned short TUint16;
38 typedef signed char TInt8;
39 typedef unsigned char TUint8;
41 typedef TUint32 TChar;
47 TUint8 fromHex(TUint8 ch);
48 TUint32 ReadUnsignedNumber(std::string &aStr, size_t aSize);
49 class RDecodeReadStream
52 // Create store based stream in binary mode
53 RDecodeReadStream(CFileStore *aStore, RReadStream &aReadStream);
54 // Create a file based stream in human mode
55 RDecodeReadStream(const std::string &aCertBaseName, RReadStream &aReadStream);
57 void RawRead(void *aPtr, TUint32 aLength);
59 void CheckName(const std::string &aExpected);
60 TUint32 ReadUnsignedNumber(size_t aSize);
62 // Return current token
63 const std::string &Token() const;
64 // Discard current token and read the next
67 // Return the token after the current token.
68 // The current token is not updated.
69 // This will only look ahead a single token.
70 const std::string &PeakToken();
72 bool HumanReadable() const;
75 CFileStore *iStore; // Only used for STORE based streams ie. not human readable
76 std::string iCertBaseName; // Only used for file based streams ie. human readable
78 RReadStream &iReadStream;
82 bool iPrefetchedTokenIsValid;
83 std::string iPrefetchedToken;
85 void GetToken(std::string &aToken);
89 class REncodeWriteStream
92 // Construct stream based on a store in binary mode
93 REncodeWriteStream(CFileStore *aStore, RWriteStream &aWriteStream); // store stream
94 // Construct stream based on a file in human mode
95 REncodeWriteStream(const std::string &aCertBaseName, RWriteStream &aWriteStream); // file stream
96 // Create a human readable log
97 REncodeWriteStream(Log &aLog);
100 Write binary data to the output stream without escaping
101 it. This data is allowed to contain the NUL (0) character and
102 may be binary data for the store file or UTF-8 text for the
103 human readable config file output.
105 void WriteBin(const void *aPtr, TUint32 aLength);
107 Write a C style string to the output stream without escaping
108 it. It is NOT safe to write a generic UTF-8 string via this
109 this function, because such a string may contain embedded 0
110 characters. A 7-bit ASCII string will work reliably. This
111 function is intended for writing 7-but ASCII strings to the
112 human readable config file, and should not be used for writing
113 data to a store file.
115 void WriteQuotedUtf8(const void *aStr, TUint32 aLength);
119 void WriteByte(TUint8 aByte);
121 Write a UTF-8 string quoting backslash and double quote characters.
123 A backslash will be written as \\
124 A quote character will be written as \"
126 Note that all bytes in UTF-8 escape sequences have the top bit
127 set therefore the quoting technique used by this function will
130 void WriteCStr(const void *aCstr);
132 void WriteHexNumber(TUint32 aNumber);
141 bool HumanReadable() const;
148 CFileStore *StoreObject();
149 RWriteStream &StoreWriteStream();
151 std::string CertFileName(TUint32 aFormat, TUint32 aCertNumber);
154 CFileStore *iStore; // Only used for STORE based streams ie. not human readable
155 std::string iCertBaseName; // Only used for file based streams ie. human readable
157 RWriteStream *iWriteStream; // STORE or file based stream, valid if iLogStream==0
159 std::ostream *iLogStream;
168 A template which generates a class which can be
169 internalised/externalised via the REncodeWriteStream and
170 RDecodeReadStream templates.
172 The constructor takes a C string constant which specifies the field
175 The optional aCommentOnlyInHumanMode parameter changes operation in human
176 mode only - The field will be written as a comment, and will not be
177 accepted whilst reading.
179 Typical use is something like this:-
180 EncDecObject<TUint32> fieldCost("cost");
182 Typically this template will not require specialisations to handle
185 template <class T> class EncDecObject
188 EncDecObject(const char *aName, bool aCommentOnlyInHumanMode = false)
189 : iName(aName), iCommentOnlyInHumanMode(aCommentOnlyInHumanMode), iValue()
193 const std::string &Name() const { return iName; }
195 const T &Value() const { return iValue; }
196 T &Value() { return iValue; }
198 bool CommentOnlyInHumanMode() const { return iCommentOnlyInHumanMode; }
201 bool iCommentOnlyInHumanMode;
206 Class for handling Enum values
214 // This class should be template by a type which standard store can
215 // internalise/externalise ie TUint8/TUin16/TUint32 (probably not an enum)
216 template<typename T>class EncDecEnum
220 Construct an object for handling an enum type.
221 aEnumEntries must be a pointer to a static array of EnumEntry
222 structs terminated by one with iName==0.
224 EncDecEnum(const char *aName, const EnumEntry *aEnumEntries, bool aCommentOnlyInHumanMode = false);
226 const std::string &Name() const { return iName; }
228 const T &Value() const { return iValue; }
229 T &Value() { return iValue; }
231 const char *ValueName() const { return ValueToName(iValue); }
233 bool CommentOnlyInHumanMode() const { return iCommentOnlyInHumanMode; }
235 void SetValue(const T &aValue);
236 void SetValue(const char *aName);
238 const char *ValueToName(const T &aValue) const;
241 const EnumEntry *iEnumEntries; // Array terminated by entry with iName==0
242 bool iCommentOnlyInHumanMode;
247 The EncDecContainer class manages a set of objects which inherit
248 from the EncDecContainerItem base class. It can be
249 internalised/externalised via the REncodeWriteStream and
250 RDecodeReadStream templates.
252 The constructor takes a C string constant which specifies the
255 The binary form is a 32 bit count followed by a sequence of
256 EncDecContainerItem objects.
258 In human readable form is a sequence of zero or more human readable
259 representations of T bracketed by StartX and EndX. Where X is the
262 class EncDecContainerItem
265 virtual ~EncDecContainerItem();
267 // Get the type name for the container. If 0 then do not bracket item with StartType/EndType
268 virtual const char *ItemType() const = 0;
269 // If ItemType()!=0 then ItemName will be included after StartType
270 virtual std::string ItemName() const;
271 virtual void SetItemName(const std::string &aName);
272 virtual void Encode(REncodeWriteStream &aWriteStream) = 0;
273 virtual void Decode(RDecodeReadStream &aReadStream) = 0;
276 typedef EncDecContainerItem *EncDecContainerItemFactoryFunc();
278 class EncDecContainer
281 EncDecContainer(const char *aContainerName, EncDecContainerItemFactoryFunc *aFactory);
284 void push_back(EncDecContainerItem *aItem);
285 const EncDecContainerItem &operator[](TUint32 aIndex) const;
286 EncDecContainerItem &operator[](TUint32 aIndex);
287 TUint32 size() const;
290 void Encode(REncodeWriteStream &aWriteStream) const;
291 void Decode(RDecodeReadStream &aReadStream);
295 EncDecContainerItemFactoryFunc *iFactory;
296 std::vector<EncDecContainerItem *> iArray;
299 void readContainer(const std::string &aFileName, bool aHuman, EncDecContainer &container);
300 void writeContainer(const char *aFileName, bool aHuman, bool aPemOut, bool aVerbose, const EncDecContainer &container);
303 The EncodeHuman template functions are used to convert a type to
306 Do NOT try and write specialisations of these templates, it probably
307 will not work, instead just write a conventional function which is
308 selected via the norml overloading rules. See GOTW articles on the
312 // The basic EncodeHuman template assumes that T is an unsigned
313 // integer and encodes it in hex.
314 template <class T> void EncodeHuman(REncodeWriteStream& aStream,const T &aUnsignedIntType)
316 aStream.WriteHexNumber(aUnsignedIntType);
319 void EncodeHuman(REncodeWriteStream& aStream,const TUid &aUid);
320 void EncodeHuman(REncodeWriteStream& aStream,const TName &aName);
323 The DecodeHuman template functions are used to read in the human
326 Do NOT try and write specialisations of these templates, it probably
327 will not work, instead just write a conventional function which is
328 selected via the norml overloading rules. See GOTW articles on the
332 // The basic DecodeHuman template assumes that T is an unsigned integer
333 // and decodes it from either decimal or hex (starting with 0x). The
334 // code calls RDecodeReadStream::ReadUnsignedNumber which will decode
335 // the number (max 32bits) and check it fits into specified type.
336 template <class T> void DecodeHuman(RDecodeReadStream& aStream,T &aUnsignedIntType)
338 aUnsignedIntType = (T) aStream.ReadUnsignedNumber(sizeof(aUnsignedIntType));
341 void DecodeHuman(RDecodeReadStream& aStream,TUid &aUid);
342 void DecodeHuman(RDecodeReadStream& aStream,TName &aName);
345 The following two template operators require the object which is
346 being internalised or externalised to provide a const Name function
347 (which returns the field name) and two Value functions (one const
348 and one not) which return a reference to an instance of the type
349 being handled. A function called CommentOnlyInHumanMode should
350 return true if the human output should be prefixed with # and should
351 be reject when reading.
353 Typicaly types will be wrapped by the EncDecObject template to
354 provide the Name() and Value() functions required by these
357 Do NOT try and write specialisations of these templates, it probably
358 will not work, instead just write a conventional function which is
359 selected via the norml overloading rules. See GOTW articles on the
362 Note: You probably only need to enhance the EncodeHuman/DecodeHuman
363 functions unless you are adding a new variable length container type.
367 The externalise operator << first checks if the destination stream
368 is HumanReadable. If it is, it writes the Name(), followed by a
369 space, calls EncodeHuman, then WriteLineEnd. If the stream is not
370 HumanReadable it simply applies the << operator to the Value().
373 inline REncodeWriteStream& operator<<(REncodeWriteStream& aStream,const T& anObject);
375 REncodeWriteStream& operator<<(REncodeWriteStream& aStream, const EncDecContainer &aContainer);
377 template <typename T>
378 REncodeWriteStream& operator<<(REncodeWriteStream& aStream, const EncDecEnum<T> &aEncDecEnum);
381 The internalise operator >> first checks if the source stream is
382 HumanReadable. If it is, it reads/checks the field name then calls
383 DecodeHuman. If the stream is not HumanReadable
384 it simply applies the >> operator to the Value().
387 inline RDecodeReadStream& operator>>(RDecodeReadStream& aStream,T& anObject);
389 RDecodeReadStream& operator>>(RDecodeReadStream& aStream,EncDecContainer &aContainer);
391 template <typename T>
392 RDecodeReadStream& operator>>(RDecodeReadStream& aStream, EncDecEnum<T> &aEncDecEnum);
394 #include "encdec.inl"