/** Copyright (c) 1997-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: **/#ifndef __RCOFSTRM_H__#define __RCOFSTRM_H__#if defined(__VC32__) && !defined(__MSVCDOTNET__)#pragma warning( disable : 4710 ) // function not inlined#endif#if defined(__MSVCDOTNET__) || defined(__TOOLS2__)#include <fstream>using std::ofstream;#else //!__MSVCDOTNET__#include <fstream.h>#endif //__MSVCDOTNET__#include "ASTRING.H"#include "NUMVAL.H"#include "ARRAY.H" class RCBinaryStream {public: RCBinaryStream(); ~RCBinaryStream(); void OpenForAppend(const String& aFileName); int IsOpen(); RCBinaryStream& operator<<(char aChar); RCBinaryStream& operator<<(char* aCharPtr); static int SizeOfCompressedInteger(unsigned int aInteger); void WriteCompressedInteger(unsigned int aInteger); void Write(const unsigned char* aCharPtr, unsigned long aCount); unsigned long GetPosition(); void SetPosition(unsigned long NewPosition);private: ofstream iOs; };class ResourceDataStream // this class knows about resources that contain compressed Unicode - i.e. that each run of alternating compressed-Unicode and other-stuff needs to be preceded by a 1-2 byte run-length {public: ResourceDataStream(); ~ResourceDataStream(); void StartOfBlockWithSizePrefix(DataType aDataTypeOfSizePrefix); // StartOfBlockWithSizePrefix/EndOfBlockWithSizePrefix blocks can be nested void EndOfBlockWithSizePrefix(); void StartOfCompressedUnicodeRun(int aUncompressedUnicodeSizeInBytes, const unsigned char* aUncompressedUnicodeBuffer); // StartOfCompressedUnicodeRun/EndOfCompressedUnicodeRun runs *cannot* be nested void EndOfCompressedUnicodeRun(); void TwoByteAlignmentPoint(); void EnquireStreamPositionWhenKnown(unsigned long& aStreamPosition); void StreamIn(const unsigned char* aBuffer, int aNumberOfBytes); void MakePlaceHolder(int aNumberOfBytes); bool StreamOutReturningWhetherContainsCompressedUnicode(RCBinaryStream& aStream, int& aSizeWhenUncompressed); void Dump(const char* aDumpFile) const;private: enum MarkType { EMarkType_StartOfBlockWithSizePrefix, // uses iOtherData to store the address of the NumericValue of the size-prefix EMarkType_EndOfBlockWithSizePrefix, EMarkType_StartOfCompressedUnicodeRun, // uses iOtherData to store a BinaryBuffer which contains the uncompressed Unicode - a EMarkType_StartOfCompressedUnicodeRun mark is always followed in ResourceDataStream's iArrayOfMarks by a EMarkType_EndOfCompressedUnicodeRun EMarkType_EndOfCompressedUnicodeRun, // uses iOtherData to store the combined size of the run taking into account any extra bytes caused by other marks, e.g. a padding byte caused by a EMarkType_TwoByteAlignmentPoint EMarkType_TwoByteAlignmentPoint, // uses iOtherData to store whether a padding byte is required or not (iOtherData is set to non-zero if it is and zero if it isn't) EMarkType_EnquireStreamPositionWhenKnown // uses iOtherData to store the address of the unsigned long to write the stream-position to }; class BinaryBuffer { public: static BinaryBuffer* New(int aNumberOfBytes, const unsigned char* aBuffer); void Destroy(); inline int NumberOfBytes() const {return iNumberOfBytes;} inline const unsigned char* Buffer() const {return iBuffer;} private: BinaryBuffer(); // defined (as private) but not declared to prevent anyone instantiating this class apart from the static New function private: int iNumberOfBytes; unsigned char iBuffer[1]; }; class Mark : public ArrayItem { public: inline Mark(int aBufferPosition, MarkType aMarkType, unsigned int aOtherData) :iBufferPosition(aBufferPosition), iMarkType(aMarkType), iOtherData(aOtherData) {} public: int iBufferPosition; MarkType iMarkType; unsigned int iOtherData; }; class ArrayOfMarks : public Array { public: inline ArrayOfMarks() {} inline void AppendMark(int aBufferPosition, MarkType aMarkType, unsigned int aOtherData=0xbebebebe) {Add(new Mark(aBufferPosition, aMarkType, aOtherData));} inline void InsertMark(int aIndex, int aBufferPosition, MarkType aMarkType, unsigned int aOtherData=0xbebebebe) {Add(aIndex, new Mark(aBufferPosition, aMarkType, aOtherData));} inline void RemoveMark(int aIndex) {Discard(aIndex);} inline Mark& MarkAt(int aIndex) const {return *(Mark*)(*this)[aIndex];} };private: void EnsureEnoughSpareBytes(int aNumberOfBytes); int NumberOfBytesToNextMark(int aMarkIndex) const; void ConvertCompressedRunToUncompressed(int aIndexOfStartOfCompressedUnicodeRun); // aIndexOfStartOfCompressedUnicodeRun is an index into iArrayOfMarksprivate: unsigned char* iBuffer; int iNumberOfBytesAllocated; int iNumberOfBytesUsed; ArrayOfMarks iArrayOfMarks; bool iContainsCompressedUnicode; };#endif