--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/webservices/wsutils/src/senchunk.cpp Thu Jan 07 16:19:19 2010 +0200
@@ -0,0 +1,474 @@
+/*
+* Copyright (c) 2002-2007 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "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 "senchunk.h"
+#include "sendebug.h" // internal Utils\inc - filelogging MACROs
+#include "senlogger.h"
+
+const TInt KSenChunkFourByteAlignment = 4;
+
+EXPORT_C CSenChunk* CSenChunk::NewL(const TDesC& aChunkName)
+ {
+ CSenChunk* pOperation = NewLC(aChunkName);
+ CleanupStack::Pop();
+ return pOperation;
+ }
+
+EXPORT_C CSenChunk* CSenChunk::NewLC(const TDesC& aChunkName)
+ {
+ CSenChunk* pOperation = new (ELeave) CSenChunk;
+ CleanupStack::PushL(pOperation);
+ pOperation->ConstructL(aChunkName);
+ return pOperation;
+ }
+
+void CSenChunk::ConstructL(const TDesC& aChunkName)
+ {
+ if (aChunkName.Length() > 0)
+ {
+ ipChunkName = aChunkName.AllocL();
+ }
+ else
+ {
+ ipChunkName = NULL;
+ }
+ }
+
+EXPORT_C CSenChunk::CSenChunk() :
+ ipChunkName(NULL)
+ {
+ }
+
+EXPORT_C CSenChunk::~CSenChunk()
+ {
+ CloseChunk();
+ delete ipChunkName;
+ }
+
+EXPORT_C RChunk& CSenChunk::Chunk()
+ {
+ return iChunk;
+ }
+
+EXPORT_C TPtrC CSenChunk::ChunkName() const
+ {
+ if(ipChunkName)
+ {
+ return *ipChunkName;
+ }
+ else
+ {
+ return KNullDesC();
+ }
+ }
+
+EXPORT_C TBool CSenChunk::operator==(const CSenChunk& a)
+ {
+ return (this==&a);
+ }
+
+EXPORT_C TInt CSenChunk::CreateChunk()
+ {
+ TInt retVal(KErrNone);
+#ifdef EKA2
+ // Create protected global chunk in EKA2
+ // (Global chunk will be protected chunk when chunk name length is zero)
+ retVal = iChunk.CreateGlobal(KNullDesC, KSenMinRChunkSize, KSenMaxRChunkSize);
+#else // EKA1
+ // Create named global chunk in EKA1
+ retVal = iChunk.CreateGlobal(*ipChunkName, KSenMinRChunkSize, KSenMaxRChunkSize);
+#ifdef _SENDEBUG
+ TLSLOG_FORMAT((KSenUtilsLogChannel, KNormalLogLevel, _L8("- RChunk.CreateGlobal('%S', %d, %d) returned: %d"),
+ ipChunkName,
+ KSenMinRChunkSize,
+ KSenMinRChunkSize,
+ retVal));
+#endif // _SENDEBUG
+#endif // EKA2/EKA1
+ if (retVal == KErrNone)
+ {
+ TUint8* heapPtr = iChunk.Base();
+ // Create header in the beginning of the chunk
+ TLSLOG_FORMAT((KSenUtilsLogChannel, KNormalLogLevel, _L8("CSenChunk::CreateChunk KHeaderOffset size: (%d)"), KHeaderOffset));
+ new (heapPtr+KHeaderOffset) TChunkHeader;
+ TChunkHeader& header = ChunkHeader();
+ header.SetDescriptorCount(0);
+ header.SetMessageType(MSenMessage::EMessageBase);
+ header.SetMessageDirection(MSenMessage::EOutbound);
+ header.SetPropertiesType(MSenProperties::ENotInUse);
+ header.SetDoInitBeforeSending(EFalse);
+ header.SetTransactionId(0);
+ header.SetPendingTransactionId(0);
+ }
+ return retVal;
+ }
+
+EXPORT_C TInt CSenChunk::OpenChunk()
+ {
+ TInt retVal(KErrNone);
+#ifdef EKA2
+ retVal = KErrNotSupported;
+#else // EKA1
+ // Open named global chunk in EKA1
+ retVal = iChunk.OpenGlobal(*ipChunkName, EFalse);
+#ifdef _SENDEBUG
+ TLSLOG_FORMAT((KSenUtilsLogChannel, KNormalLogLevel, _L8("- RChunk.OpenGlobal() returned %d"), retVal));
+#endif // _SENDEBUG
+#endif // EKA2/EKA1
+ return retVal;
+ }
+
+EXPORT_C TInt CSenChunk::OpenChunkFromRMsgL(const RMessage2& aMessage, TInt aIndex)
+ {
+ TInt retVal(KErrNone);
+#ifdef EKA2 // // EKA2
+ retVal = iChunk.Open(aMessage, aIndex, EOwnerProcess);
+#else // EKA1
+ HBufC* pChunkName = HBufC::NewLC(KMaxName);
+ TPtr chunkname = pChunkName->Des();
+ TInt leaveCode(KErrNone);
+ TRAP(leaveCode, retVal = aMessage.Read(aIndex, chunkname); )
+
+ if(retVal==KErrNone && leaveCode != KErrNone)
+ {
+#ifdef _SENDEBUG
+ TLSLOG_FORMAT((KSenUtilsLogChannel, KMinLogLevel, _L8("- aMessage.Read(aIndex, chunkname) leaved: %d"), leaveCode ));
+#endif // _SENDEBUG
+ retVal = leaveCode;
+ }
+
+ ipChunkName = chunkname.AllocL();
+ CleanupStack::PopAndDestroy(pChunkName);
+
+#ifdef _SENDEBUG
+ if (ipChunkName->Length() > 0 )
+ {
+ TLSLOG_FORMAT((KSenUtilsLogChannel, KNormalLogLevel, _L8("- RChunk name from RMessage2: '%S'"), ipChunkName ));
+ }
+#endif // _SENDEBUG
+
+ if(retVal==KErrNone)
+ {
+ retVal = iChunk.OpenGlobal(*ipChunkName, EFalse);
+#ifdef _SENDEBUG
+ TLSLOG_FORMAT((KSenUtilsLogChannel, KNormalLogLevel, _L8("- RChunk.OpenGlobal() returned %d"), retVal));
+#endif // _SENDEBUG
+ }
+#endif // EKA2/EKA1
+ return retVal;
+ }
+
+EXPORT_C TInt CSenChunk::OpenChunkFromHandleNumberL(TInt aHandleOrError)
+ {
+ TInt retVal(KErrNone);
+#ifdef EKA2 // // EKA2
+ retVal = iChunk.SetReturnedHandle(aHandleOrError);
+#else // EKA1
+ iChunk.SetHandle(aHandleOrError);
+#endif // EKA2/EKA1
+ return retVal;
+ }
+
+EXPORT_C void CSenChunk::CloseChunk()
+ {
+#ifdef _SENDEBUG
+ TLSLOG_FORMAT((KSenUtilsLogChannel, KNormalLogLevel, _L8("CSenChunk::CloseChunk - handle: %d"), iChunk.Handle()));
+#endif // _SENDEBUG
+
+ THandleInfo chunkInfo;
+ iChunk.HandleInfo(&chunkInfo);
+#ifdef _SENDEBUG
+ TLSLOG_FORMAT((KSenUtilsLogChannel, KNormalLogLevel, _L8("- Before Close(): TChunkInfo: numOpenInThread: %d, numOpenInProcess: %d, numProcesses: %d"),
+ chunkInfo.iNumOpenInThread,
+ chunkInfo.iNumOpenInProcess,
+ chunkInfo.iNumProcesses));
+#endif // _SENDEBUG
+
+ iChunk.Close();
+ }
+
+EXPORT_C TInt CSenChunk::AdjustChunk(TInt aNewSize)
+ {
+ // Ensure that at least 10064 bytes are allocated:
+ if(aNewSize<KSenMinRChunkSize)
+ {
+ aNewSize = KSenMinRChunkSize;
+ }
+ TInt retVal = iChunk.Adjust(aNewSize);
+ TLSLOG_FORMAT((KSenUtilsLogChannel, KNormalLogLevel, _L8("CSenChunk::AdjustChunk returns: (%d)"), retVal));
+ return retVal;
+ }
+
+EXPORT_C TChunkHeader& CSenChunk::ChunkHeader()
+ {
+ return *reinterpret_cast<TChunkHeader*>(iChunk.Base()+KHeaderOffset);
+ }
+
+EXPORT_C TInt CSenChunk::DescToChunk(const TDesC8& aDescriptor)
+ {
+ TInt retVal(KErrNone);
+
+ TInt size(aDescriptor.Length()+sizeof(TPtr8)+KSenChunkFourByteAlignment+KDataOffset);
+
+ retVal = AdjustChunk(size);
+
+ if(retVal == KErrNone)
+ {
+ TUint8* heapPtr = iChunk.Base();
+ TChunkHeader& header = ChunkHeader();
+ header.SetDescriptorCount(1);
+ heapPtr += KDataOffset;
+ heapPtr = RoundToNextDividableByFourAddress(heapPtr);
+ // Place a new descriptor in the chunk to initialize it
+ new (heapPtr) TPtr8(heapPtr + sizeof(TPtr8), 0, aDescriptor.Length());
+ // Set the descriptor
+ TPtr8* pDes = reinterpret_cast<TPtr8*>(heapPtr);
+ pDes->Zero();
+ pDes->Append(aDescriptor);
+ }
+ return retVal;
+ }
+EXPORT_C TInt CSenChunk::DescToChunk(const TDesC8& aDescriptor, TInt aIndex)
+ {
+#ifdef _SENDEBUG
+ TLSLOG_L(KSenUtilsLogChannel,KMinLogLevel ,"CSenChunk::DescFromChunk");
+#endif // _SENDEBUG
+ TInt retVal(KErrNone);
+
+ if ( iChunk.Handle() > KErrNone )
+ {
+ TInt maxPtr = iChunk.Size();
+
+ TInt size(aDescriptor.Length()+sizeof(TPtr8)+(aIndex+1)*KSenChunkFourByteAlignment);
+ retVal = AdjustChunk(maxPtr+size);
+
+ TChunkHeader& header = *reinterpret_cast<TChunkHeader*>(iChunk.Base() + KHeaderOffset);
+
+ if ( aIndex <= header.DescriptorCount() )
+ {
+ header.SetDescriptorCount(aIndex+1);
+
+ TUint8* heapPtr = iChunk.Base();
+ heapPtr += KDataOffset;
+ heapPtr = RoundToNextDividableByFourAddress(heapPtr);
+ TPtr8* pDesc;
+ pDesc = reinterpret_cast<TPtr8*>(heapPtr);
+ for (TInt i=1; i < aIndex; i++)
+ {
+ heapPtr += (sizeof(TPtr8) + pDesc->MaxLength());
+ heapPtr = RoundToNextDividableByFourAddress(heapPtr);
+ pDesc = reinterpret_cast<TPtr8*>(heapPtr);
+ }
+ heapPtr += (sizeof(TPtr8) + pDesc->MaxLength());
+ heapPtr = RoundToNextDividableByFourAddress(heapPtr);
+
+ // Place a new descriptor in the chunk to initialize it
+ new (heapPtr) TPtr8(heapPtr + sizeof(TPtr8), 0, aDescriptor.Length());
+ // Set the descriptor
+ pDesc = reinterpret_cast<TPtr8*>(heapPtr);
+ pDesc->Zero();
+ pDesc->Append(aDescriptor);
+ }
+ else
+ {
+ retVal = KErrNotFound;
+ }
+ }
+ else
+ {
+ retVal = KErrBadHandle;
+#ifdef _SENDEBUG
+ TLSLOG_FORMAT((KSenUtilsLogChannel, KMinLogLevel, _L8("CSenChunk::DescFromChunk(chunk), RChunk.Handle(): %d is an error!"),
+ iChunk.Handle()));
+#endif // _SENDEBUG
+ }
+
+ return retVal;
+ }
+
+EXPORT_C TInt CSenChunk::AllocDescToChunk(TInt size, TPtr8*& apAllocated)
+ {
+ TInt retVal(KErrNone);
+
+ retVal = AdjustChunk(size+KSenChunkFourByteAlignment);
+
+ if(retVal == KErrNone)
+ {
+ TUint8* heapPtr = iChunk.Base();
+ TChunkHeader& header = ChunkHeader();
+ header.SetDescriptorCount(1);
+ heapPtr += KDataOffset;
+ heapPtr = RoundToNextDividableByFourAddress(heapPtr);
+ // Place a new descriptor in the chunk to initialize it
+ new (heapPtr) TPtr8(heapPtr + sizeof(TPtr8), 0, size);
+ // Set the descriptor
+ apAllocated = reinterpret_cast<TPtr8*>(heapPtr);
+ apAllocated->Zero();
+ }
+ return retVal;
+ }
+
+EXPORT_C TInt CSenChunk::DescsToChunk(const TDesC8& aDescriptor1,
+ const TDesC8& aDescriptor2)
+ {
+TInt retVal(KErrNone);
+
+ TInt size(KDataOffset+aDescriptor1.Length()+aDescriptor2.Length()+\
+ 2*sizeof(TPtr8)+2*KSenChunkFourByteAlignment);
+
+ retVal = AdjustChunk(size);
+
+ if(retVal == KErrNone)
+ {
+ TUint8* heapPtr = iChunk.Base();
+ TChunkHeader& header = ChunkHeader();
+ header.SetDescriptorCount(2);
+ heapPtr += KDataOffset;
+ heapPtr = RoundToNextDividableByFourAddress(heapPtr);
+ // Place a new descriptor in the chunk to initialize it
+ new (heapPtr) TPtr8(heapPtr + sizeof(TPtr8), 0, aDescriptor1.Length());
+ // Set the descriptor
+ TPtr8* pDes = reinterpret_cast<TPtr8*>(heapPtr);
+ pDes->Zero();
+ pDes->Append(aDescriptor1);
+
+ heapPtr = heapPtr + sizeof(TPtr8) + aDescriptor1.Length();
+ heapPtr = RoundToNextDividableByFourAddress(heapPtr);
+ // Place a new descriptor in the chunk to initialize it
+ new (heapPtr) TPtr8(heapPtr + sizeof(TPtr8), 0, aDescriptor2.Length());
+ // Set the descriptor
+ pDes = reinterpret_cast<TPtr8*>(heapPtr);
+ pDes->Zero();
+ pDes->Append(aDescriptor2);
+ }
+ return retVal;
+
+ }
+
+EXPORT_C TInt CSenChunk::DescFromChunk(TPtrC8& aDesc, TInt aIndex)
+ {
+#ifdef _SENDEBUG
+ TLSLOG_L(KSenUtilsLogChannel,KMinLogLevel ,"CSenChunk::DescFromChunk");
+#endif // _SENDEBUG
+ TInt retVal(KErrNone);
+
+ if(iChunk.Handle()>KErrNone)
+ {
+ TChunkHeader& header = *reinterpret_cast<TChunkHeader*>(iChunk.Base() + KHeaderOffset);
+
+ if (aIndex < header.DescriptorCount() && aIndex >= 0)
+ {
+ TUint8* heapPtr = iChunk.Base();
+ heapPtr += KDataOffset;
+ heapPtr = RoundToNextDividableByFourAddress(heapPtr);
+ TPtr8* pDesc;
+ pDesc = reinterpret_cast<TPtr8*>(heapPtr);
+ for (TInt i=1; i <= aIndex; i++)
+ {
+ heapPtr += (sizeof(TPtr8) + pDesc->MaxLength());
+ heapPtr = RoundToNextDividableByFourAddress(heapPtr);
+ pDesc = reinterpret_cast<TPtr8*>(heapPtr);
+ }
+ const TInt length = pDesc->Length();
+ const TInt maxLength = pDesc->MaxLength();
+ pDesc->Set(heapPtr + sizeof(TPtr8), length, maxLength);
+ aDesc.Set(*pDesc);
+ }
+ else
+ {
+ retVal = KErrNotFound;
+ }
+ }
+ else
+ {
+ retVal = KErrBadHandle;
+#ifdef _SENDEBUG
+ TLSLOG_FORMAT((KSenUtilsLogChannel, KMinLogLevel, _L8("CSenChunk::DescFromChunk(chunk), RChunk.Handle(): %d is an error!"),
+ iChunk.Handle()));
+#endif // _SENDEBUG
+ }
+
+ return retVal;
+ }
+
+EXPORT_C TInt CSenChunk::DescsFromChunk(TPtrC8& aDesc1, TPtrC8& aDesc2)
+ {
+ TInt retVal;
+ retVal = DescFromChunk(aDesc1,0);
+ if (retVal == KErrNone)
+ {
+ retVal = DescFromChunk(aDesc2,1);
+ }
+ return retVal;
+ }
+
+EXPORT_C void CSenChunk::ChunkToArgs(TIpcArgs& aArgs, TInt aIndex)
+ {
+#ifdef EKA2
+ aArgs.Set(aIndex, iChunk); // EKA2
+#else
+ aArgs.Set(aIndex, ipChunkName); // EKA1
+#endif
+ }
+
+EXPORT_C void CSenChunk::SetLogger(RFileLogger* aLog)
+ {
+ iLog = aLog;
+ }
+
+EXPORT_C RFileLogger* CSenChunk::Log() const
+ {
+ return iLog;
+ }
+
+TUint8* CSenChunk::RoundToNextDividableByFourAddress(TUint8* aValue)
+ {
+ TInt modulo = ((TUint)aValue)%KSenChunkFourByteAlignment;
+ if ( modulo == 0 )
+ {
+ return aValue;
+ }
+ else
+ {
+ return aValue+(KSenChunkFourByteAlignment-modulo);
+ }
+ }
+
+EXPORT_C RFile& CSenChunk::RequestFileHandle()
+ {
+ return iFile;
+ }
+
+EXPORT_C void CSenChunk::RequestFileHandle(RFile& aFile)
+ {
+ iFile = aFile;
+ }
+
+
+
+// End of File