--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/secureswitools/swisistools/source/sisxlibrary/sisstring.cpp Thu Dec 17 08:51:10 2009 +0200
@@ -0,0 +1,179 @@
+/*
+* 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.
+*
+*/
+
+
+/**
+ @file
+ @internalComponent
+ @released
+*/
+
+#include "sisstring.h"
+#include "utility.h"
+#include "exception.h"
+#include "utils.h"
+#include "utf8.h"
+
+// we cannot write or read a string directly from a file, because we don't know what format the
+// MS implementation of STL will use for the std::string. So we need to go via an intemediate buffer.
+// But strings can be variable size, including very big indeed, so that buffer will have to be
+// allocated as need be. Buffer allocation and deletion is expensive. It is sensible to allocate
+// a common buffer, and only change its size when necessary. To reduce the frequency of file size
+// changes, the actual allocation oversteps the mark, so the next time something requests a slightly
+// bigger string, no allocation is required (usually). These variables could be private static members of our
+// string class, but that would mean some minor change to this code would require the entire
+// product to be recompiled.
+
+static TUint8* gBuffer = NULL;
+static unsigned long gBufferLength = 0;
+static const unsigned long gChunk = 512;
+
+
+
+void VerifyBufferSize (const unsigned long aSize)
+ {
+ if (aSize == 0)
+ {
+ return;
+ }
+ if (aSize > gBufferLength)
+ {
+ delete [] gBuffer;
+ gBufferLength = aSize + gChunk;
+ gBuffer = new TUint8 [gBufferLength];
+ }
+ }
+
+
+void CSISString::ExitInstance ()
+ {
+ delete [] gBuffer;
+ gBuffer = NULL;
+ gBufferLength = 0;
+ }
+
+
+void CSISString::Read (TSISStream& aFile, const TFieldSize& aContainerSize, const CSISFieldRoot::TFieldType aArrayType)
+ {
+ CSISHeader header (CSISFieldRoot::ESISString);
+ if (IsDataThere (aFile, header, aArrayType))
+ {
+ if (header.DataSize () == 0)
+ {
+ iData.erase ();
+ }
+ else
+ {
+ unsigned int dataSize = header.DataSize();
+ VerifyBufferSize (dataSize);
+ dataSize = AlignedSize(dataSize);
+ aFile.read (gBuffer, dataSize);
+
+ if(sizeof(WCHAR) != 2)
+ {
+ int targetLength = dataSize*sizeof(wchar_t);
+ wchar_t *ptrUCS4 = new wchar_t [dataSize];
+ UTF16* sourceStart = reinterpret_cast<UTF16*>(gBuffer);
+ UTF16* sourceEnd = sourceStart + dataSize;
+ UCS4* targetStart = reinterpret_cast<UCS4*>(ptrUCS4);
+ UCS4* targetEnd = targetStart + dataSize*2;
+ ConvertUTF16toUCS4(&sourceStart, sourceEnd, &targetStart, targetEnd);
+ iData.assign ((ptrUCS4), static_cast <std::wstring::size_type> (dataSize / 2));
+ }
+ else
+ {
+ iData.assign ( reinterpret_cast <wchar_t*> (gBuffer),
+ static_cast <std::wstring::size_type> (header.DataSize () / sizeof (wchar_t)));
+ }
+ }
+
+ }
+ }
+
+
+void CSISString::Write (TSISStream& aFile, const bool aIsArrayElement) const
+ {
+ if (! WasteOfSpace ())
+ {
+#ifdef GENERATE_ERRORS
+ if (CSISFieldRoot::IsBugToBeCreated (CSISFieldRoot::EBugInsaneString))
+ {
+ CSISHeader (CSISFieldRoot::ESISString, rand ()).Write (aFile, aIsArrayElement);
+ }
+ else
+#endif // GENERATE_ERRORS
+ {
+ CSISHeader (CSISFieldRoot::ESISString, ByteCount (aIsArrayElement)).Write (aFile, aIsArrayElement);
+ }
+
+ // SIS file format only supports UCS-2 format , so need conversion here if wchar is 4 bytes (Linux OS)
+ if(sizeof(WCHAR) != 2)
+ {
+ int targetLength = iData.size()*2;
+ UTF16 *ptrUtf16 = new UTF16[targetLength + 1];
+ UCS4* sourceStart = reinterpret_cast<UCS4*>(const_cast<wchar_t*>(iData.c_str()));
+ UCS4* sourceEnd = sourceStart + (iData.size()*sizeof(WCHAR));
+ UTF16* targetStart = reinterpret_cast<UTF16*>(ptrUtf16);
+ UTF16* targetEnd = targetStart + targetLength;
+ ConvertUCS4toUTF16(&sourceStart, sourceEnd, &targetStart, targetEnd);
+ int endOffset = (UTF16*)targetStart - ptrUtf16;
+ targetStart = reinterpret_cast<UTF16*>(ptrUtf16) + endOffset;
+ *targetStart = 0;
+ aFile.write (reinterpret_cast <const TUint8*> (ptrUtf16),targetLength);
+ }
+ else
+ {
+ aFile.write (reinterpret_cast <const TUint8*> (iData.c_str ()), ByteCount (aIsArrayElement));
+ }
+ WriteFiller (aFile);
+ }
+ }
+
+
+void CSISString::Dump (std::ostream& aStream, const int aLevel) const
+ {
+ aStream << "\"" << wstring2string (iData) << "\"";
+ }
+
+
+void CSISString::CalculateCrc (TCRC& aCRC, const bool aIsArrayElement) const
+ {
+ if(!WasteOfSpace())
+ {
+ CSISHeader (CSISFieldRoot::ESISString, ByteCount (false)).CalculateCrc (aCRC, aIsArrayElement);
+ CSISFieldRoot::DoPaddedCrc(aCRC, reinterpret_cast <const TUint8*> (iData.c_str ()), ByteCount (aIsArrayElement));
+ }
+ }
+
+
+CSISFieldRoot::TFieldSize CSISString::ByteCount (const bool aInsideArray) const
+ {
+ if(sizeof(wchar_t) != 2)
+ return static_cast <CSISFieldRoot::TFieldSize> (iData.size () * sizeof (wchar_t)/2);
+ else
+ return static_cast <CSISFieldRoot::TFieldSize> (iData.size () * sizeof (wchar_t));
+ }
+
+
+bool CSISString::WasteOfSpace () const
+ {
+ return ! Required () && iData.empty ();
+ }
+