Move the Security package to EPL, and add the implementations of the cryptographic algorithms
#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 <s32strm.h>
#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<TUint32> fieldCost("cost");
Typically this template will not require specialisations to handle
additional types.
*/
template <class T> 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)
template<typename T>class 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<EncDecContainerItem *> 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 <class T> 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 <class T> 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 <class T>
inline REncodeWriteStream& operator<<(REncodeWriteStream& aStream,const T& anObject);
REncodeWriteStream& operator<<(REncodeWriteStream& aStream, const EncDecContainer &aContainer);
template <typename T>
REncodeWriteStream& operator<<(REncodeWriteStream& aStream, const EncDecEnum<T> &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 <class T>
inline RDecodeReadStream& operator>>(RDecodeReadStream& aStream,T& anObject);
RDecodeReadStream& operator>>(RDecodeReadStream& aStream,EncDecContainer &aContainer);
template <typename T>
RDecodeReadStream& operator>>(RDecodeReadStream& aStream, EncDecEnum<T> &aEncDecEnum);
#include "encdec.inl"
#endif