diff -r 000000000000 -r bde4ae8d615e os/security/securityanddataprivacytools/securitytools/certapp/encdec/encdec.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/os/security/securityanddataprivacytools/securitytools/certapp/encdec/encdec.h Fri Jun 15 03:10:57 2012 +0200 @@ -0,0 +1,398 @@ +#ifndef __ENCDEC_H__ +#define __ENCDEC_H__/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#include +#include "filestream.h" +#include "logger.h" + +/** + * @file + * @internalComponent + */ + +typedef uint64_t TUint64; +typedef int64_t TInt64; + +typedef int TInt32; +typedef unsigned int TUint32; + +typedef short TInt16; +typedef unsigned short TUint16; + +typedef signed char TInt8; +typedef unsigned char TUint8; + +typedef TUint32 TChar; + +typedef int TBool; + +typedef void TAny; + +TUint8 fromHex(TUint8 ch); +TUint32 ReadUnsignedNumber(std::string &aStr, size_t aSize); +class RDecodeReadStream + { +public: + // Create store based stream in binary mode + RDecodeReadStream(CFileStore *aStore, RReadStream &aReadStream); + // Create a file based stream in human mode + RDecodeReadStream(const std::string &aCertBaseName, RReadStream &aReadStream); + + void RawRead(void *aPtr, TUint32 aLength); + + void CheckName(const std::string &aExpected); + TUint32 ReadUnsignedNumber(size_t aSize); + + // Return current token + const std::string &Token() const; + // Discard current token and read the next + void ReadNextToken(); + + // Return the token after the current token. + // The current token is not updated. + // This will only look ahead a single token. + const std::string &PeakToken(); + + bool HumanReadable() const; + void Close(); + + CFileStore *iStore; // Only used for STORE based streams ie. not human readable + std::string iCertBaseName; // Only used for file based streams ie. human readable + + RReadStream &iReadStream; +private: + bool iHumanReadable; + std::string iToken; + bool iPrefetchedTokenIsValid; + std::string iPrefetchedToken; + + void GetToken(std::string &aToken); + }; + + +class REncodeWriteStream + { +public: + // Construct stream based on a store in binary mode + REncodeWriteStream(CFileStore *aStore, RWriteStream &aWriteStream); // store stream + // Construct stream based on a file in human mode + REncodeWriteStream(const std::string &aCertBaseName, RWriteStream &aWriteStream); // file stream + // Create a human readable log + REncodeWriteStream(Log &aLog); + + /** + Write binary data to the output stream without escaping + it. This data is allowed to contain the NUL (0) character and + may be binary data for the store file or UTF-8 text for the + human readable config file output. + */ + void WriteBin(const void *aPtr, TUint32 aLength); + /** + Write a C style string to the output stream without escaping + it. It is NOT safe to write a generic UTF-8 string via this + this function, because such a string may contain embedded 0 + characters. A 7-bit ASCII string will work reliably. This + function is intended for writing 7-but ASCII strings to the + human readable config file, and should not be used for writing + data to a store file. + */ + void WriteQuotedUtf8(const void *aStr, TUint32 aLength); + /** + Write a single byte. + */ + void WriteByte(TUint8 aByte); + /** + Write a UTF-8 string quoting backslash and double quote characters. + + A backslash will be written as \\ + A quote character will be written as \" + + Note that all bytes in UTF-8 escape sequences have the top bit + set therefore the quoting technique used by this function will + not effect them. + */ + void WriteCStr(const void *aCstr); + + void WriteHexNumber(TUint32 aNumber); + + void WriteSpace(); + void WriteLineEnd(); + + void WriteIndent(); + void IncIndent(); + void DecIndent(); + + bool HumanReadable() const; + bool &PemOut(); + bool &Verbose(); + void Close(); + + bool Quiet() const; + + CFileStore *StoreObject(); + RWriteStream &StoreWriteStream(); + + std::string CertFileName(TUint32 aFormat, TUint32 aCertNumber); + +private: + CFileStore *iStore; // Only used for STORE based streams ie. not human readable + std::string iCertBaseName; // Only used for file based streams ie. human readable + + RWriteStream *iWriteStream; // STORE or file based stream, valid if iLogStream==0 + + std::ostream *iLogStream; +private: + bool iHumanReadable; + bool iPemOut; + bool iVerbose; + int iIndentLevel; + }; + +/** + A template which generates a class which can be + internalised/externalised via the REncodeWriteStream and + RDecodeReadStream templates. + + The constructor takes a C string constant which specifies the field + name. + + The optional aCommentOnlyInHumanMode parameter changes operation in human + mode only - The field will be written as a comment, and will not be + accepted whilst reading. + + Typical use is something like this:- + EncDecObject fieldCost("cost"); + + Typically this template will not require specialisations to handle + additional types. +*/ +template class EncDecObject + { +public: + EncDecObject(const char *aName, bool aCommentOnlyInHumanMode = false) + : iName(aName), iCommentOnlyInHumanMode(aCommentOnlyInHumanMode), iValue() + { + } + + const std::string &Name() const { return iName; } + + const T &Value() const { return iValue; } + T &Value() { return iValue; } + + bool CommentOnlyInHumanMode() const { return iCommentOnlyInHumanMode; } +private: + std::string iName; + bool iCommentOnlyInHumanMode; + T iValue; + }; + +/** + Class for handling Enum values + */ +struct EnumEntry + { + const char *iName; + TUint32 iValue; + }; + +// This class should be template by a type which standard store can +// internalise/externalise ie TUint8/TUin16/TUint32 (probably not an enum) +templateclass EncDecEnum + { +public: + /** + Construct an object for handling an enum type. + aEnumEntries must be a pointer to a static array of EnumEntry + structs terminated by one with iName==0. + */ + EncDecEnum(const char *aName, const EnumEntry *aEnumEntries, bool aCommentOnlyInHumanMode = false); + + const std::string &Name() const { return iName; } + + const T &Value() const { return iValue; } + T &Value() { return iValue; } + + const char *ValueName() const { return ValueToName(iValue); } + + bool CommentOnlyInHumanMode() const { return iCommentOnlyInHumanMode; } + + void SetValue(const T &aValue); + void SetValue(const char *aName); +private: + const char *ValueToName(const T &aValue) const; + std::string iName; + TUint8 iWidth; + const EnumEntry *iEnumEntries; // Array terminated by entry with iName==0 + bool iCommentOnlyInHumanMode; + T iValue; + }; + +/* + The EncDecContainer class manages a set of objects which inherit + from the EncDecContainerItem base class. It can be + internalised/externalised via the REncodeWriteStream and + RDecodeReadStream templates. + + The constructor takes a C string constant which specifies the + container name. + + The binary form is a 32 bit count followed by a sequence of + EncDecContainerItem objects. + + In human readable form is a sequence of zero or more human readable + representations of T bracketed by StartX and EndX. Where X is the + container name. +*/ +class EncDecContainerItem + { +public: + virtual ~EncDecContainerItem(); + + // Get the type name for the container. If 0 then do not bracket item with StartType/EndType + virtual const char *ItemType() const = 0; + // If ItemType()!=0 then ItemName will be included after StartType + virtual std::string ItemName() const; + virtual void SetItemName(const std::string &aName); + virtual void Encode(REncodeWriteStream &aWriteStream) = 0; + virtual void Decode(RDecodeReadStream &aReadStream) = 0; + }; + +typedef EncDecContainerItem *EncDecContainerItemFactoryFunc(); + +class EncDecContainer + { +public: + EncDecContainer(const char *aContainerName, EncDecContainerItemFactoryFunc *aFactory); + ~EncDecContainer(); + + void push_back(EncDecContainerItem *aItem); + const EncDecContainerItem &operator[](TUint32 aIndex) const; + EncDecContainerItem &operator[](TUint32 aIndex); + TUint32 size() const; + void reset(); + + void Encode(REncodeWriteStream &aWriteStream) const; + void Decode(RDecodeReadStream &aReadStream); + +private: + std::string iName; + EncDecContainerItemFactoryFunc *iFactory; + std::vector iArray; + }; + +void readContainer(const std::string &aFileName, bool aHuman, EncDecContainer &container); +void writeContainer(const char *aFileName, bool aHuman, bool aPemOut, bool aVerbose, const EncDecContainer &container); + +/* + The EncodeHuman template functions are used to convert a type to + human readable form. + + Do NOT try and write specialisations of these templates, it probably + will not work, instead just write a conventional function which is + selected via the norml overloading rules. See GOTW articles on the + web. + */ + +// The basic EncodeHuman template assumes that T is an unsigned +// integer and encodes it in hex. +template void EncodeHuman(REncodeWriteStream& aStream,const T &aUnsignedIntType) +{ + aStream.WriteHexNumber(aUnsignedIntType); +} + +void EncodeHuman(REncodeWriteStream& aStream,const TUid &aUid); +void EncodeHuman(REncodeWriteStream& aStream,const TName &aName); + +/* + The DecodeHuman template functions are used to read in the human + readable form. + + Do NOT try and write specialisations of these templates, it probably + will not work, instead just write a conventional function which is + selected via the norml overloading rules. See GOTW articles on the + web. + */ + +// The basic DecodeHuman template assumes that T is an unsigned integer +// and decodes it from either decimal or hex (starting with 0x). The +// code calls RDecodeReadStream::ReadUnsignedNumber which will decode +// the number (max 32bits) and check it fits into specified type. +template void DecodeHuman(RDecodeReadStream& aStream,T &aUnsignedIntType) +{ + aUnsignedIntType = (T) aStream.ReadUnsignedNumber(sizeof(aUnsignedIntType)); +} + +void DecodeHuman(RDecodeReadStream& aStream,TUid &aUid); +void DecodeHuman(RDecodeReadStream& aStream,TName &aName); + +/* + The following two template operators require the object which is + being internalised or externalised to provide a const Name function + (which returns the field name) and two Value functions (one const + and one not) which return a reference to an instance of the type + being handled. A function called CommentOnlyInHumanMode should + return true if the human output should be prefixed with # and should + be reject when reading. + + Typicaly types will be wrapped by the EncDecObject template to + provide the Name() and Value() functions required by these + templates. + + Do NOT try and write specialisations of these templates, it probably + will not work, instead just write a conventional function which is + selected via the norml overloading rules. See GOTW articles on the + web. + + Note: You probably only need to enhance the EncodeHuman/DecodeHuman + functions unless you are adding a new variable length container type. + */ + +/* + The externalise operator << first checks if the destination stream + is HumanReadable. If it is, it writes the Name(), followed by a + space, calls EncodeHuman, then WriteLineEnd. If the stream is not + HumanReadable it simply applies the << operator to the Value(). +*/ +template +inline REncodeWriteStream& operator<<(REncodeWriteStream& aStream,const T& anObject); + +REncodeWriteStream& operator<<(REncodeWriteStream& aStream, const EncDecContainer &aContainer); + +template +REncodeWriteStream& operator<<(REncodeWriteStream& aStream, const EncDecEnum &aEncDecEnum); + +/* + The internalise operator >> first checks if the source stream is + HumanReadable. If it is, it reads/checks the field name then calls + DecodeHuman. If the stream is not HumanReadable + it simply applies the >> operator to the Value(). +*/ +template +inline RDecodeReadStream& operator>>(RDecodeReadStream& aStream,T& anObject); + +RDecodeReadStream& operator>>(RDecodeReadStream& aStream,EncDecContainer &aContainer); + +template +RDecodeReadStream& operator>>(RDecodeReadStream& aStream, EncDecEnum &aEncDecEnum); + +#include "encdec.inl" + + + +#endif