os/security/securityanddataprivacytools/securitytools/certapp/encdec/encdec.h
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/security/securityanddataprivacytools/securitytools/certapp/encdec/encdec.h	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,398 @@
     1.4 +#ifndef __ENCDEC_H__
     1.5 +#define __ENCDEC_H__/*
     1.6 +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
     1.7 +* All rights reserved.
     1.8 +* This component and the accompanying materials are made available
     1.9 +* under the terms of the License "Eclipse Public License v1.0"
    1.10 +* which accompanies this distribution, and is available
    1.11 +* at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.12 +*
    1.13 +* Initial Contributors:
    1.14 +* Nokia Corporation - initial contribution.
    1.15 +*
    1.16 +* Contributors:
    1.17 +*
    1.18 +* Description: 
    1.19 +*
    1.20 +*/
    1.21 +
    1.22 +
    1.23 +#include <s32strm.h>
    1.24 +#include "filestream.h"
    1.25 +#include "logger.h"
    1.26 +
    1.27 +/**
    1.28 + * @file
    1.29 + * @internalComponent
    1.30 + */
    1.31 +
    1.32 +typedef uint64_t TUint64;
    1.33 +typedef int64_t TInt64;
    1.34 +
    1.35 +typedef	int	TInt32;
    1.36 +typedef	unsigned int TUint32;
    1.37 +
    1.38 +typedef	short TInt16;
    1.39 +typedef	unsigned short TUint16;
    1.40 +
    1.41 +typedef	signed char	TInt8;
    1.42 +typedef	unsigned char TUint8;
    1.43 +
    1.44 +typedef	TUint32 TChar;
    1.45 +
    1.46 +typedef	int TBool;
    1.47 +
    1.48 +typedef void TAny;
    1.49 +
    1.50 +TUint8 fromHex(TUint8 ch);
    1.51 +TUint32 ReadUnsignedNumber(std::string &aStr, size_t aSize);
    1.52 +class RDecodeReadStream
    1.53 +	{
    1.54 +public:
    1.55 +	// Create store based stream in binary mode
    1.56 +	RDecodeReadStream(CFileStore *aStore, RReadStream &aReadStream);
    1.57 +	// Create a file based stream  in human mode
    1.58 +	RDecodeReadStream(const std::string &aCertBaseName, RReadStream &aReadStream);
    1.59 +
    1.60 +	void RawRead(void *aPtr, TUint32 aLength);
    1.61 +
    1.62 +	void CheckName(const std::string &aExpected);
    1.63 +	TUint32 ReadUnsignedNumber(size_t aSize);
    1.64 +
    1.65 +	// Return current token
    1.66 +	const std::string &Token() const;
    1.67 +	// Discard current token and read the next
    1.68 +	void ReadNextToken();
    1.69 +	
    1.70 +	// Return the token after the current token.
    1.71 +	// The current token is not updated.
    1.72 +	// This will only look ahead a single token.
    1.73 +	const std::string &PeakToken();
    1.74 +
    1.75 +	bool HumanReadable() const;
    1.76 +	void Close();
    1.77 +
    1.78 +	CFileStore *iStore;  // Only used for STORE based streams ie. not human readable
    1.79 +	std::string iCertBaseName; // Only used for file based streams ie. human readable
    1.80 +
    1.81 +	RReadStream &iReadStream;
    1.82 +private:
    1.83 +	bool iHumanReadable; 
    1.84 +	std::string iToken;
    1.85 +	bool iPrefetchedTokenIsValid;
    1.86 +	std::string iPrefetchedToken;
    1.87 +
    1.88 +	void GetToken(std::string &aToken);
    1.89 +	};
    1.90 +
    1.91 +
    1.92 +class REncodeWriteStream
    1.93 +	{
    1.94 +public:
    1.95 +	// Construct stream based on a store in binary mode
    1.96 +	REncodeWriteStream(CFileStore *aStore, RWriteStream &aWriteStream); // store stream
    1.97 +	// Construct stream based on a file in human mode
    1.98 +	REncodeWriteStream(const std::string &aCertBaseName, RWriteStream &aWriteStream); // file stream
    1.99 +	// Create a human readable log
   1.100 +	REncodeWriteStream(Log &aLog);
   1.101 +
   1.102 +	/**
   1.103 +	   Write binary data to the output stream without escaping
   1.104 +	   it. This data is allowed to contain the NUL (0) character and
   1.105 +	   may be binary data for the store file or UTF-8 text for the
   1.106 +	   human readable config file output.
   1.107 +	*/
   1.108 +	void WriteBin(const void *aPtr, TUint32 aLength);
   1.109 +	/**
   1.110 +	   Write a C style string to the output stream without escaping
   1.111 +	   it. It is NOT safe to write a generic UTF-8 string via this
   1.112 +	   this function, because such a string may contain embedded 0
   1.113 +	   characters. A 7-bit ASCII string will work reliably.  This
   1.114 +	   function is intended for writing 7-but ASCII strings to the
   1.115 +	   human readable config file, and should not be used for writing
   1.116 +	   data to a store file.
   1.117 +	 */
   1.118 +	void WriteQuotedUtf8(const void *aStr, TUint32 aLength);
   1.119 +	/**
   1.120 +	   Write a single byte.
   1.121 +	 */
   1.122 +	void WriteByte(TUint8 aByte);
   1.123 +	/**
   1.124 +	   Write a UTF-8 string quoting backslash and double quote characters.
   1.125 +
   1.126 +	   A backslash will be written as \\
   1.127 +	   A quote character will be written as \"
   1.128 +
   1.129 +	   Note that all bytes in UTF-8 escape sequences have the top bit
   1.130 +	   set therefore the quoting technique used by this function will
   1.131 +	   not effect them.
   1.132 +	 */
   1.133 +	void WriteCStr(const void *aCstr);
   1.134 +
   1.135 +	void WriteHexNumber(TUint32 aNumber);
   1.136 +
   1.137 +	void WriteSpace();
   1.138 +	void WriteLineEnd();
   1.139 +
   1.140 +	void WriteIndent();
   1.141 +	void IncIndent();
   1.142 +	void DecIndent();
   1.143 +
   1.144 +	bool HumanReadable() const;
   1.145 +	bool &PemOut();
   1.146 +	bool &Verbose();
   1.147 +	void Close();
   1.148 +
   1.149 +	bool Quiet() const;
   1.150 +
   1.151 +	CFileStore *StoreObject();
   1.152 +	RWriteStream &StoreWriteStream();
   1.153 +
   1.154 +	std::string CertFileName(TUint32 aFormat, TUint32 aCertNumber);
   1.155 +	
   1.156 +private:
   1.157 +	CFileStore *iStore; // Only used for STORE based streams ie. not human readable
   1.158 +	std::string iCertBaseName; // Only used for file based streams ie. human readable
   1.159 +
   1.160 +	RWriteStream *iWriteStream; // STORE or file based stream, valid if iLogStream==0
   1.161 +	
   1.162 +	std::ostream *iLogStream;
   1.163 +private:
   1.164 +	bool iHumanReadable; 
   1.165 +	bool iPemOut; 
   1.166 +	bool iVerbose; 
   1.167 +	int iIndentLevel;
   1.168 +	};
   1.169 +
   1.170 +/**
   1.171 +  A template which generates a class which can be
   1.172 +  internalised/externalised via the REncodeWriteStream and
   1.173 +  RDecodeReadStream templates.
   1.174 +
   1.175 +  The constructor takes a C string constant which specifies the field
   1.176 +  name.
   1.177 +  
   1.178 +  The optional aCommentOnlyInHumanMode parameter changes operation in human
   1.179 +  mode only - The field will be written as a comment, and will not be
   1.180 +  accepted whilst reading.
   1.181 +
   1.182 +  Typical use is something like this:-
   1.183 +  EncDecObject<TUint32> fieldCost("cost");
   1.184 +
   1.185 +  Typically this template will not require specialisations to handle
   1.186 +  additional types.
   1.187 +*/
   1.188 +template <class T> class EncDecObject
   1.189 +	{
   1.190 +public:
   1.191 +	EncDecObject(const char *aName, bool aCommentOnlyInHumanMode = false)
   1.192 +		: iName(aName), iCommentOnlyInHumanMode(aCommentOnlyInHumanMode), iValue()
   1.193 +		{
   1.194 +		}
   1.195 +
   1.196 +	const std::string &Name() const { return iName; }
   1.197 +
   1.198 +	const T &Value() const { return iValue; }
   1.199 +	T &Value() { return iValue; }
   1.200 +
   1.201 +	bool CommentOnlyInHumanMode() const { return iCommentOnlyInHumanMode; }
   1.202 +private:
   1.203 +	std::string iName;
   1.204 +	bool iCommentOnlyInHumanMode;
   1.205 +	T iValue;
   1.206 +	};
   1.207 +
   1.208 +/**
   1.209 +   Class for handling Enum values
   1.210 + */
   1.211 +struct EnumEntry
   1.212 +	{
   1.213 +	const char *iName;
   1.214 +	TUint32 iValue;
   1.215 +	};
   1.216 +
   1.217 +// This class should be template by a type which standard store can
   1.218 +// internalise/externalise ie TUint8/TUin16/TUint32 (probably not an enum)
   1.219 +template<typename T>class EncDecEnum
   1.220 +	{
   1.221 +public:
   1.222 +	/**
   1.223 +	   Construct an object for handling an enum type.
   1.224 +	   aEnumEntries must be a pointer to a static array of EnumEntry
   1.225 +	   structs terminated by one with iName==0.
   1.226 +	 */
   1.227 +	EncDecEnum(const char *aName, const EnumEntry *aEnumEntries, bool aCommentOnlyInHumanMode = false);
   1.228 +
   1.229 +	const std::string &Name() const { return iName; }
   1.230 +
   1.231 +	const T &Value() const { return iValue; }
   1.232 +	T &Value() { return iValue; }
   1.233 +
   1.234 +	const char *ValueName() const { return ValueToName(iValue); }
   1.235 +
   1.236 +	bool CommentOnlyInHumanMode() const { return iCommentOnlyInHumanMode; }
   1.237 +
   1.238 +	void SetValue(const T &aValue);
   1.239 +	void SetValue(const char *aName);
   1.240 +private:
   1.241 +	const char *ValueToName(const T &aValue) const;
   1.242 +	std::string iName;
   1.243 +	TUint8 iWidth;
   1.244 +	const EnumEntry *iEnumEntries; // Array terminated by entry with iName==0
   1.245 +	bool iCommentOnlyInHumanMode;
   1.246 +	T iValue;
   1.247 +	};
   1.248 +
   1.249 +/*
   1.250 +  The EncDecContainer class manages a set of objects which inherit
   1.251 +  from the EncDecContainerItem base class. It can be
   1.252 +  internalised/externalised via the REncodeWriteStream and
   1.253 +  RDecodeReadStream templates.
   1.254 +
   1.255 +  The constructor takes a C string constant which specifies the
   1.256 +  container name.
   1.257 +
   1.258 +  The binary form is a 32 bit count followed by a sequence of
   1.259 +  EncDecContainerItem objects.
   1.260 +
   1.261 +  In human readable form is a sequence of zero or more human readable
   1.262 +  representations of T bracketed by StartX and EndX. Where X is the
   1.263 +  container name.
   1.264 +*/
   1.265 +class EncDecContainerItem
   1.266 +	{
   1.267 +public:
   1.268 +	virtual ~EncDecContainerItem();
   1.269 +
   1.270 +	// Get the type name for the container. If 0 then do not bracket item with StartType/EndType
   1.271 +	virtual const char *ItemType() const = 0;
   1.272 +	// If ItemType()!=0 then ItemName will be included after StartType
   1.273 +	virtual std::string ItemName() const;
   1.274 +	virtual void SetItemName(const std::string &aName);
   1.275 +	virtual void Encode(REncodeWriteStream &aWriteStream) = 0;
   1.276 +	virtual void Decode(RDecodeReadStream &aReadStream) = 0;
   1.277 +	};
   1.278 +
   1.279 +typedef EncDecContainerItem *EncDecContainerItemFactoryFunc();
   1.280 +
   1.281 +class EncDecContainer
   1.282 +	{
   1.283 +public:
   1.284 +	EncDecContainer(const char *aContainerName, EncDecContainerItemFactoryFunc *aFactory);
   1.285 +	~EncDecContainer();
   1.286 +
   1.287 +	void push_back(EncDecContainerItem *aItem);
   1.288 +	const EncDecContainerItem &operator[](TUint32 aIndex) const;
   1.289 +	EncDecContainerItem &operator[](TUint32 aIndex);
   1.290 +	TUint32 size() const;
   1.291 +	void reset();
   1.292 +
   1.293 +	void Encode(REncodeWriteStream &aWriteStream) const;
   1.294 +	void Decode(RDecodeReadStream &aReadStream);
   1.295 +
   1.296 +private:
   1.297 +	std::string iName;
   1.298 +	EncDecContainerItemFactoryFunc *iFactory;
   1.299 +	std::vector<EncDecContainerItem *> iArray;
   1.300 +	};
   1.301 +
   1.302 +void readContainer(const std::string &aFileName, bool aHuman, EncDecContainer &container);
   1.303 +void writeContainer(const char *aFileName, bool aHuman, bool aPemOut, bool aVerbose, const EncDecContainer &container);
   1.304 +
   1.305 +/*
   1.306 +  The EncodeHuman template functions are used to convert a type to
   1.307 +  human readable form.
   1.308 +
   1.309 +  Do NOT try and write specialisations of these templates, it probably
   1.310 +  will not work, instead just write a conventional function which is
   1.311 +  selected via the norml overloading rules. See GOTW articles on the
   1.312 +  web.
   1.313 + */
   1.314 +
   1.315 +// The basic EncodeHuman template assumes that T is an unsigned
   1.316 +// integer and encodes it in hex.
   1.317 +template <class T> void EncodeHuman(REncodeWriteStream& aStream,const T &aUnsignedIntType)
   1.318 +{
   1.319 +	aStream.WriteHexNumber(aUnsignedIntType);
   1.320 +}
   1.321 +
   1.322 +void EncodeHuman(REncodeWriteStream& aStream,const TUid &aUid);
   1.323 +void EncodeHuman(REncodeWriteStream& aStream,const TName &aName);
   1.324 +
   1.325 +/*
   1.326 +  The DecodeHuman template functions are used to read in the human
   1.327 +  readable form.
   1.328 +
   1.329 +  Do NOT try and write specialisations of these templates, it probably
   1.330 +  will not work, instead just write a conventional function which is
   1.331 +  selected via the norml overloading rules. See GOTW articles on the
   1.332 +  web.
   1.333 + */
   1.334 +
   1.335 +// The basic DecodeHuman template assumes that T is an unsigned integer
   1.336 +// and decodes it from either decimal or hex (starting with 0x).  The
   1.337 +// code calls RDecodeReadStream::ReadUnsignedNumber which will decode
   1.338 +// the number (max 32bits) and check it fits into specified type.
   1.339 +template <class T> void DecodeHuman(RDecodeReadStream& aStream,T &aUnsignedIntType)
   1.340 +{
   1.341 +	aUnsignedIntType = (T) aStream.ReadUnsignedNumber(sizeof(aUnsignedIntType));
   1.342 +}
   1.343 +
   1.344 +void DecodeHuman(RDecodeReadStream& aStream,TUid &aUid);
   1.345 +void DecodeHuman(RDecodeReadStream& aStream,TName &aName);
   1.346 +
   1.347 +/*
   1.348 +  The following two template operators require the object which is
   1.349 +  being internalised or externalised to provide a const Name function
   1.350 +  (which returns the field name) and two Value functions (one const
   1.351 +  and one not) which return a reference to an instance of the type
   1.352 +  being handled. A function called CommentOnlyInHumanMode should
   1.353 +  return true if the human output should be prefixed with # and should
   1.354 +  be reject when reading.
   1.355 +
   1.356 +  Typicaly types will be wrapped by the EncDecObject template to
   1.357 +  provide the Name() and Value() functions required by these
   1.358 +  templates.
   1.359 +
   1.360 +  Do NOT try and write specialisations of these templates, it probably
   1.361 +  will not work, instead just write a conventional function which is
   1.362 +  selected via the norml overloading rules. See GOTW articles on the
   1.363 +  web.
   1.364 +
   1.365 +  Note: You probably only need to enhance the EncodeHuman/DecodeHuman
   1.366 +  functions unless you are adding a new variable length container type.
   1.367 + */
   1.368 +
   1.369 +/*
   1.370 +  The externalise operator << first checks if the destination stream
   1.371 +  is HumanReadable. If it is, it writes the Name(), followed by a
   1.372 +  space, calls EncodeHuman, then WriteLineEnd. If the stream is not
   1.373 +  HumanReadable it simply applies the << operator to the Value().
   1.374 +*/
   1.375 +template <class T>
   1.376 +inline REncodeWriteStream& operator<<(REncodeWriteStream& aStream,const T& anObject);
   1.377 +
   1.378 +REncodeWriteStream& operator<<(REncodeWriteStream& aStream, const EncDecContainer &aContainer);
   1.379 +
   1.380 +template <typename T>
   1.381 +REncodeWriteStream& operator<<(REncodeWriteStream& aStream, const EncDecEnum<T> &aEncDecEnum);
   1.382 +
   1.383 +/*
   1.384 +  The internalise operator >> first checks if the source stream is
   1.385 +  HumanReadable. If it is, it reads/checks the field name then calls
   1.386 +  DecodeHuman. If the stream is not HumanReadable
   1.387 +  it simply applies the >> operator to the Value().
   1.388 +*/
   1.389 +template <class T>
   1.390 +inline RDecodeReadStream& operator>>(RDecodeReadStream& aStream,T& anObject);
   1.391 +
   1.392 +RDecodeReadStream& operator>>(RDecodeReadStream& aStream,EncDecContainer &aContainer);
   1.393 +
   1.394 +template <typename T>
   1.395 +RDecodeReadStream& operator>>(RDecodeReadStream& aStream, EncDecEnum<T> &aEncDecEnum);
   1.396 +
   1.397 +#include "encdec.inl"
   1.398 +
   1.399 +
   1.400 +
   1.401 +#endif