diff -r 000000000000 -r ba25891c3a9e secureswitools/swisistools/source/sisxlibrary/structure.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/secureswitools/swisistools/source/sisxlibrary/structure.h Thu Dec 17 08:51:10 2009 +0200 @@ -0,0 +1,289 @@ +/* +* Copyright (c) 2007-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: +* Note: This file may contain code to generate corrupt files for test purposes. +* Such code is excluded from production builds by use of compiler defines; +* it is recommended that such code should be removed if this code is ever published publicly. +* generic SIS structure container, provides common functionality on members, see fieldroot.h for purpose of functions +* +*/ + + +/** + @file + @internalComponent + @released +*/ + +#ifndef __STRUCTURE_H__ +#define __STRUCTURE_H__ + +#include "container.h" +#include "fieldroot.h" + +template class CStructure : public CContainer + + { +public: + CStructure (); + CStructure (const bool aRequired); + CStructure (const CStructure& s); + + virtual void Read (TSISStream& aFile, const CSISFieldRoot::TFieldSize& aContainerSize, const CSISFieldRoot::TFieldType aArrayType = CSISFieldRoot::ESISUndefined); + + virtual void Write (TSISStream& aFile, const bool aIsArrayElement) const; + virtual CSISFieldRoot::TFieldSize ByteCount (const bool aIsArray) const; + virtual void CalculateCrc (TCRC& aCRC, const bool aIsArrayElement) const; + + TUint64 SkipRead (TSISStream& aFile, const CSISFieldRoot::TFieldSize& aContainerSize, const CSISFieldRoot::TFieldType aArrayType, const TUint32 aSkipCount, const bool aCompleteWithNormalRead); + void RawSkipWrite (TSISStream& aFile, const bool aIsArrayElement, TUint8* aRawBuffer, const TUint64 aBufferSize, const TUint32 aSkipCount) const; + +protected: + void InsertMember (CSISFieldRoot& aMember); + // intended to be used by inheriting constructors *ONLY* + + }; + + + +template inline + CStructure ::CStructure () + { + } + +template inline + CStructure ::CStructure (const bool aRequired) : + CContainer (aRequired) + { + } + +template inline + CStructure ::CStructure (const CStructure& s) : + CContainer (s, 0) + { + } + + + +template + void CStructure ::Read (TSISStream& aFile, const CSISFieldRoot::TFieldSize& aContainerSize, const CSISFieldRoot::TFieldType aArrayType) + { + SetPreHeaderPos (aFile.tell ()); + + CSISHeader header (aArrayType); + if (IsDataThere (aFile, header, aArrayType)) + { + SetByteCount (header.DataSize ()); + TSISStream::pos_type pos = aFile.tell (); + + SetPostHeaderPos (pos); +#ifdef _DEBUG + TSISStream::pos_type expected = pos + static_cast (AlignedSize (header.DataSize ())); +#endif + TUint64 available = aContainerSize; + for (ContainerIter(CSISFieldRoot) iterMemb = ContainerMem(CSISFieldRoot, FieldType).begin(); + iterMemb != ContainerMem(CSISFieldRoot, FieldType).end(); + ++iterMemb) + { + (*iterMemb) -> Read (aFile, available); + available = aContainerSize - (aFile.tell () - pos); + } + ReadFiller (aFile); +#ifdef _DEBUG + TSISStream::pos_type got = aFile.tell (); + assert (expected == got); +#endif + } + } + + +template + TUint64 CStructure ::SkipRead (TSISStream& aFile, const CSISFieldRoot::TFieldSize& aContainerSize, const CSISFieldRoot::TFieldType aArrayType, const TUint32 aSkipCount, const bool aCompleteWithNormalRead) + { + CSISHeader header (CSISFieldRoot::ESISUndefined); + TUint32 skipped = 0; + TUint64 offset = 0; + if (IsDataThere (aFile, header, aArrayType)) + { + SetByteCount (header.DataSize ()); + TSISStream::pos_type pos = aFile.tell (); +#ifdef _DEBUG + TSISStream::pos_type expected = pos + static_cast (AlignedSize (header.DataSize ())); +#endif + TUint64 available = aContainerSize; + for (ContainerIter(CSISFieldRoot) iterMemb = ContainerMem(CSISFieldRoot,FieldType).begin (); iterMemb != ContainerMem(CSISFieldRoot, FieldType).end (); iterMemb++) + { + if (! aCompleteWithNormalRead || (skipped < aSkipCount)) + { + (*iterMemb) -> Skip (aFile, available); + if (++skipped == aSkipCount) + { + offset = static_cast (aFile.tell ()) - pos; + assert (AlignedSize (offset) == offset); + } + } + else + { + (*iterMemb) -> Read (aFile, available); + } + available = aContainerSize - (aFile.tell () - pos); + } + ReadFiller (aFile); +#ifdef _DEBUG + TSISStream::pos_type got = aFile.tell (); + assert (expected == got); +#endif + } + return offset; + } + +template + void CStructure ::Write (TSISStream& aFile, const bool aIsArrayElement) const + { +#ifdef GENERATE_ERRORS + unsigned int unknownLen = rand()%1000; +#endif // GENERATE_ERRORS + + bool writeData = ! WasteOfSpace (); + if (writeData) + { +#ifdef GENERATE_ERRORS + bool unknownField = CSISFieldRoot::IsBugToBeCreated (CSISFieldRoot::EBugUnknownField); +#endif // GENERATE_ERRORS +#ifdef _DEBUG + TSISStream::pos_type before = aFile.tell (); +#endif + CSISHeader ( +#ifdef GENERATE_ERRORS + static_cast (unknownField ? + static_cast (rand () % 0x0FFF + CSISFieldRoot::EBugUnknownField) : + FieldType), +#else // GENERATE_ERRORS + FieldType, +#endif // GENERATE_ERRORS + ByteCount (false)).Write (aFile, aIsArrayElement); +#ifdef _DEBUG + TSISStream::pos_type pos = aFile.tell (); + TSISStream::pos_type expected = aFile.tell () + static_cast (AlignedSize (ByteCount (false))); +#endif + for (ContainerIter(CSISFieldRoot) iterMemb = ContainerMem(CSISFieldRoot,FieldType).begin(); iterMemb != ContainerMem(CSISFieldRoot,FieldType).end(); iterMemb++) + { +#ifdef GENERATE_ERRORS + if (! CSISFieldRoot::IsBugToBeCreated (CSISFieldRoot::EBugMissingField)) + { + if (CSISFieldRoot::IsBugToBeCreated (CSISFieldRoot::EBugUnexpectedField)) + { + (*iterMemb) -> Write (aFile, false); + } + (*iterMemb) -> Write (aFile, false); + } + if (CSISFieldRoot::IsBugToBeCreated(CSISFieldRoot::EBugUnknownData)) + { + CSISFieldRoot::AddRawDataValue(aFile,unknownLen); + } +#else // GENERATE_ERRORS + (*iterMemb) -> Write (aFile, false); + +#endif // GENERATE_ERRORS +#ifdef _DEBUG + TSISStream::pos_type ici = aFile.tell (); +#endif + } + TSISStream::pos_type beforeFiller = aFile.tell (); + WriteFiller (aFile); +#ifdef _DEBUG + TSISStream::pos_type actual = aFile.tell (); +#ifdef GENERATE_ERRORS + if (! IsAnyBugSet ()) + { + assert (expected == actual); + } + else + { + if (expected != actual) + { + aFile.seek (before); + CSISHeader (FieldType, beforeFiller - pos).Write (aFile, aIsArrayElement); + aFile.seek (actual); + } + } +#else + assert (expected == actual); +#endif // GENERATE_ERRORS +#endif // DEBUG + } + } + +template + void CStructure ::RawSkipWrite (TSISStream& aFile, const bool aIsArrayElement, TUint8* aRawBuffer, const TUint64 aBufferSize, const TUint32 aSkipCount) const + { + assert (! WasteOfSpace ()); // not tested + assert ((! aBufferSize) ^ (aRawBuffer != NULL)); + TUint32 skipped = 0; + TUint64 before = static_cast (aFile.tell ()); + CSISHeader (FieldType, 0).Write (aFile, aIsArrayElement); + TUint64 after = static_cast (aFile.tell ()); + if (aRawBuffer) + { + aFile.write (aRawBuffer, aBufferSize); + WriteFiller (aFile); + } + for (ContainerIter(CSISFieldRoot) iterMemb = ContainerMem(CSISFieldRoot,FieldType).begin (); iterMemb != ContainerMem(CSISFieldRoot,FieldType).end (); iterMemb++) + { + if (skipped++ >= aSkipCount) + { + (*iterMemb) -> Write (aFile, false); + } + else + if (skipped == aSkipCount) + { + (*iterMemb) -> SkipOldWriteNew (aFile); + } + } + WriteFiller (aFile); + TUint64 actual = static_cast (aFile.tell ()); + CSISException::ThrowIf (CSISHeader::IsBigHeader (actual - after), + CSISException::EFileFormat, + "inconsistent structure size"); // why is SISController so huge; + aFile.seek (before); + CSISHeader (FieldType, actual - after).Write (aFile, aIsArrayElement); + aFile.seek (actual); + } + +template inline + void CStructure ::CalculateCrc (TCRC& aCRC, const bool aIsArrayElement) const + { + if(!WasteOfSpace()) + { + CSISHeader (FieldType, ByteCount (false)).CalculateCrc (aCRC, aIsArrayElement); + CContainer::CalculateCrc (aCRC, false); + } + } + +template inline + void CStructure ::InsertMember (CSISFieldRoot& aMember) + { + ContainerMem(CSISFieldRoot,FieldType).push_back (&aMember); + } + +template inline + CSISFieldRoot::TFieldSize CStructure ::ByteCount (const bool aIsArray) const + { + assert (! aIsArray); + return CContainer::ByteCount (false); + } + + +#endif // __STRUCTURE_H__ +