secureswitools/swisistools/source/sisxlibrary/structure.h
changeset 0 ba25891c3a9e
--- /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 <CSISFieldRoot::TFieldType FieldType> class CStructure : public CContainer <CSISFieldRoot, FieldType>
+
+	{
+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 <CSISFieldRoot::TFieldType FieldType> inline
+	CStructure <FieldType>::CStructure ()
+	{
+	}
+
+template <CSISFieldRoot::TFieldType FieldType> inline
+		CStructure <FieldType>::CStructure (const bool aRequired) :
+			CContainer<CSISFieldRoot, FieldType> (aRequired)
+	{
+	}
+
+template <CSISFieldRoot::TFieldType FieldType> inline
+		CStructure <FieldType>::CStructure (const CStructure& s) :
+			CContainer<CSISFieldRoot, FieldType> (s, 0)
+	{ 
+	}
+
+
+
+template <CSISFieldRoot::TFieldType FieldType>
+		void CStructure <FieldType>::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 <TSISStream::pos_type> (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 <CSISFieldRoot::TFieldType FieldType>
+		TUint64 CStructure <FieldType>::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 <TSISStream::pos_type> (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 <TUint64> (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 <CSISFieldRoot::TFieldType FieldType>
+		void CStructure <FieldType>::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 <const CSISFieldRoot::TFieldType> (unknownField ? 
+							static_cast <TUint32> (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 <TSISStream::pos_type> (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 <CSISFieldRoot::TFieldType FieldType>
+		void  CStructure <FieldType>::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 <TUint64> (aFile.tell ());
+	CSISHeader (FieldType, 0).Write (aFile, aIsArrayElement);
+	TUint64 after = static_cast <TUint64> (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 <TUint64> (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 <CSISFieldRoot::TFieldType FieldType> inline
+		void CStructure <FieldType>::CalculateCrc (TCRC& aCRC, const bool aIsArrayElement) const
+	{
+	if(!WasteOfSpace())
+		{
+		CSISHeader (FieldType, ByteCount (false)).CalculateCrc (aCRC, aIsArrayElement); 
+		CContainer<CSISFieldRoot, FieldType>::CalculateCrc (aCRC, false);
+		}
+	}
+
+template <CSISFieldRoot::TFieldType FieldType> inline
+		void CStructure <FieldType>::InsertMember (CSISFieldRoot& aMember)
+	{
+	ContainerMem(CSISFieldRoot,FieldType).push_back (&aMember);
+	}
+
+template <CSISFieldRoot::TFieldType FieldType> inline
+		CSISFieldRoot::TFieldSize CStructure <FieldType>::ByteCount (const bool aIsArray) const
+	{
+	assert (! aIsArray);
+	return CContainer<CSISFieldRoot, FieldType>::ByteCount (false);
+	}
+
+
+#endif // __STRUCTURE_H__
+