securityanddataprivacytools/securitytools/certapp/encdec/encdec.h
changeset 0 2c201484c85f
child 8 35751d3474b7
equal deleted inserted replaced
-1:000000000000 0:2c201484c85f
       
     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