os/security/securityanddataprivacytools/securitytools/certapp/encdec/encdec.h
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 #ifndef __ENCDEC_H__
     2 #define __ENCDEC_H__/*
     3 * Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
     4 * All rights reserved.
     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".
     9 *
    10 * Initial Contributors:
    11 * Nokia Corporation - initial contribution.
    12 *
    13 * Contributors:
    14 *
    15 * Description: 
    16 *
    17 */
    18 
    19 
    20 #include <s32strm.h>
    21 #include "filestream.h"
    22 #include "logger.h"
    23 
    24 /**
    25  * @file
    26  * @internalComponent
    27  */
    28 
    29 typedef uint64_t TUint64;
    30 typedef int64_t TInt64;
    31 
    32 typedef	int	TInt32;
    33 typedef	unsigned int TUint32;
    34 
    35 typedef	short TInt16;
    36 typedef	unsigned short TUint16;
    37 
    38 typedef	signed char	TInt8;
    39 typedef	unsigned char TUint8;
    40 
    41 typedef	TUint32 TChar;
    42 
    43 typedef	int TBool;
    44 
    45 typedef void TAny;
    46 
    47 TUint8 fromHex(TUint8 ch);
    48 TUint32 ReadUnsignedNumber(std::string &aStr, size_t aSize);
    49 class RDecodeReadStream
    50 	{
    51 public:
    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);
    56 
    57 	void RawRead(void *aPtr, TUint32 aLength);
    58 
    59 	void CheckName(const std::string &aExpected);
    60 	TUint32 ReadUnsignedNumber(size_t aSize);
    61 
    62 	// Return current token
    63 	const std::string &Token() const;
    64 	// Discard current token and read the next
    65 	void ReadNextToken();
    66 	
    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();
    71 
    72 	bool HumanReadable() const;
    73 	void Close();
    74 
    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
    77 
    78 	RReadStream &iReadStream;
    79 private:
    80 	bool iHumanReadable; 
    81 	std::string iToken;
    82 	bool iPrefetchedTokenIsValid;
    83 	std::string iPrefetchedToken;
    84 
    85 	void GetToken(std::string &aToken);
    86 	};
    87 
    88 
    89 class REncodeWriteStream
    90 	{
    91 public:
    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);
    98 
    99 	/**
   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.
   104 	*/
   105 	void WriteBin(const void *aPtr, TUint32 aLength);
   106 	/**
   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.
   114 	 */
   115 	void WriteQuotedUtf8(const void *aStr, TUint32 aLength);
   116 	/**
   117 	   Write a single byte.
   118 	 */
   119 	void WriteByte(TUint8 aByte);
   120 	/**
   121 	   Write a UTF-8 string quoting backslash and double quote characters.
   122 
   123 	   A backslash will be written as \\
   124 	   A quote character will be written as \"
   125 
   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
   128 	   not effect them.
   129 	 */
   130 	void WriteCStr(const void *aCstr);
   131 
   132 	void WriteHexNumber(TUint32 aNumber);
   133 
   134 	void WriteSpace();
   135 	void WriteLineEnd();
   136 
   137 	void WriteIndent();
   138 	void IncIndent();
   139 	void DecIndent();
   140 
   141 	bool HumanReadable() const;
   142 	bool &PemOut();
   143 	bool &Verbose();
   144 	void Close();
   145 
   146 	bool Quiet() const;
   147 
   148 	CFileStore *StoreObject();
   149 	RWriteStream &StoreWriteStream();
   150 
   151 	std::string CertFileName(TUint32 aFormat, TUint32 aCertNumber);
   152 	
   153 private:
   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
   156 
   157 	RWriteStream *iWriteStream; // STORE or file based stream, valid if iLogStream==0
   158 	
   159 	std::ostream *iLogStream;
   160 private:
   161 	bool iHumanReadable; 
   162 	bool iPemOut; 
   163 	bool iVerbose; 
   164 	int iIndentLevel;
   165 	};
   166 
   167 /**
   168   A template which generates a class which can be
   169   internalised/externalised via the REncodeWriteStream and
   170   RDecodeReadStream templates.
   171 
   172   The constructor takes a C string constant which specifies the field
   173   name.
   174   
   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.
   178 
   179   Typical use is something like this:-
   180   EncDecObject<TUint32> fieldCost("cost");
   181 
   182   Typically this template will not require specialisations to handle
   183   additional types.
   184 */
   185 template <class T> class EncDecObject
   186 	{
   187 public:
   188 	EncDecObject(const char *aName, bool aCommentOnlyInHumanMode = false)
   189 		: iName(aName), iCommentOnlyInHumanMode(aCommentOnlyInHumanMode), iValue()
   190 		{
   191 		}
   192 
   193 	const std::string &Name() const { return iName; }
   194 
   195 	const T &Value() const { return iValue; }
   196 	T &Value() { return iValue; }
   197 
   198 	bool CommentOnlyInHumanMode() const { return iCommentOnlyInHumanMode; }
   199 private:
   200 	std::string iName;
   201 	bool iCommentOnlyInHumanMode;
   202 	T iValue;
   203 	};
   204 
   205 /**
   206    Class for handling Enum values
   207  */
   208 struct EnumEntry
   209 	{
   210 	const char *iName;
   211 	TUint32 iValue;
   212 	};
   213 
   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
   217 	{
   218 public:
   219 	/**
   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.
   223 	 */
   224 	EncDecEnum(const char *aName, const EnumEntry *aEnumEntries, bool aCommentOnlyInHumanMode = false);
   225 
   226 	const std::string &Name() const { return iName; }
   227 
   228 	const T &Value() const { return iValue; }
   229 	T &Value() { return iValue; }
   230 
   231 	const char *ValueName() const { return ValueToName(iValue); }
   232 
   233 	bool CommentOnlyInHumanMode() const { return iCommentOnlyInHumanMode; }
   234 
   235 	void SetValue(const T &aValue);
   236 	void SetValue(const char *aName);
   237 private:
   238 	const char *ValueToName(const T &aValue) const;
   239 	std::string iName;
   240 	TUint8 iWidth;
   241 	const EnumEntry *iEnumEntries; // Array terminated by entry with iName==0
   242 	bool iCommentOnlyInHumanMode;
   243 	T iValue;
   244 	};
   245 
   246 /*
   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.
   251 
   252   The constructor takes a C string constant which specifies the
   253   container name.
   254 
   255   The binary form is a 32 bit count followed by a sequence of
   256   EncDecContainerItem objects.
   257 
   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
   260   container name.
   261 */
   262 class EncDecContainerItem
   263 	{
   264 public:
   265 	virtual ~EncDecContainerItem();
   266 
   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;
   274 	};
   275 
   276 typedef EncDecContainerItem *EncDecContainerItemFactoryFunc();
   277 
   278 class EncDecContainer
   279 	{
   280 public:
   281 	EncDecContainer(const char *aContainerName, EncDecContainerItemFactoryFunc *aFactory);
   282 	~EncDecContainer();
   283 
   284 	void push_back(EncDecContainerItem *aItem);
   285 	const EncDecContainerItem &operator[](TUint32 aIndex) const;
   286 	EncDecContainerItem &operator[](TUint32 aIndex);
   287 	TUint32 size() const;
   288 	void reset();
   289 
   290 	void Encode(REncodeWriteStream &aWriteStream) const;
   291 	void Decode(RDecodeReadStream &aReadStream);
   292 
   293 private:
   294 	std::string iName;
   295 	EncDecContainerItemFactoryFunc *iFactory;
   296 	std::vector<EncDecContainerItem *> iArray;
   297 	};
   298 
   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);
   301 
   302 /*
   303   The EncodeHuman template functions are used to convert a type to
   304   human readable form.
   305 
   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
   309   web.
   310  */
   311 
   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)
   315 {
   316 	aStream.WriteHexNumber(aUnsignedIntType);
   317 }
   318 
   319 void EncodeHuman(REncodeWriteStream& aStream,const TUid &aUid);
   320 void EncodeHuman(REncodeWriteStream& aStream,const TName &aName);
   321 
   322 /*
   323   The DecodeHuman template functions are used to read in the human
   324   readable form.
   325 
   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
   329   web.
   330  */
   331 
   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)
   337 {
   338 	aUnsignedIntType = (T) aStream.ReadUnsignedNumber(sizeof(aUnsignedIntType));
   339 }
   340 
   341 void DecodeHuman(RDecodeReadStream& aStream,TUid &aUid);
   342 void DecodeHuman(RDecodeReadStream& aStream,TName &aName);
   343 
   344 /*
   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.
   352 
   353   Typicaly types will be wrapped by the EncDecObject template to
   354   provide the Name() and Value() functions required by these
   355   templates.
   356 
   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
   360   web.
   361 
   362   Note: You probably only need to enhance the EncodeHuman/DecodeHuman
   363   functions unless you are adding a new variable length container type.
   364  */
   365 
   366 /*
   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().
   371 */
   372 template <class T>
   373 inline REncodeWriteStream& operator<<(REncodeWriteStream& aStream,const T& anObject);
   374 
   375 REncodeWriteStream& operator<<(REncodeWriteStream& aStream, const EncDecContainer &aContainer);
   376 
   377 template <typename T>
   378 REncodeWriteStream& operator<<(REncodeWriteStream& aStream, const EncDecEnum<T> &aEncDecEnum);
   379 
   380 /*
   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().
   385 */
   386 template <class T>
   387 inline RDecodeReadStream& operator>>(RDecodeReadStream& aStream,T& anObject);
   388 
   389 RDecodeReadStream& operator>>(RDecodeReadStream& aStream,EncDecContainer &aContainer);
   390 
   391 template <typename T>
   392 RDecodeReadStream& operator>>(RDecodeReadStream& aStream, EncDecEnum<T> &aEncDecEnum);
   393 
   394 #include "encdec.inl"
   395 
   396 
   397 
   398 #endif