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