webservices/wsutils/src/senchunk.cpp
changeset 0 62f9d29f7211
equal deleted inserted replaced
-1:000000000000 0:62f9d29f7211
       
     1 /*
       
     2 * Copyright (c) 2002-2007 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:          
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 
       
    21 
       
    22 
       
    23 
       
    24 
       
    25 
       
    26 
       
    27 
       
    28 
       
    29 #include "senchunk.h"
       
    30 #include "sendebug.h" // internal Utils\inc - filelogging MACROs
       
    31 #include "senlogger.h"
       
    32 
       
    33 const TInt KSenChunkFourByteAlignment = 4;
       
    34 
       
    35 EXPORT_C CSenChunk* CSenChunk::NewL(const TDesC& aChunkName)
       
    36     {
       
    37     CSenChunk* pOperation = NewLC(aChunkName);
       
    38     CleanupStack::Pop();
       
    39     return pOperation;
       
    40     }
       
    41 
       
    42 EXPORT_C CSenChunk* CSenChunk::NewLC(const TDesC& aChunkName)
       
    43     {
       
    44     CSenChunk* pOperation = new (ELeave) CSenChunk;
       
    45     CleanupStack::PushL(pOperation);
       
    46     pOperation->ConstructL(aChunkName);
       
    47     return pOperation;
       
    48     }
       
    49 
       
    50 void CSenChunk::ConstructL(const TDesC& aChunkName)
       
    51     {
       
    52     if (aChunkName.Length() > 0)
       
    53         {
       
    54         ipChunkName = aChunkName.AllocL();
       
    55         }
       
    56     else
       
    57         {
       
    58         ipChunkName = NULL;
       
    59         }
       
    60     }
       
    61 
       
    62 EXPORT_C CSenChunk::CSenChunk() :
       
    63     ipChunkName(NULL)
       
    64     {
       
    65     }
       
    66 
       
    67 EXPORT_C CSenChunk::~CSenChunk()
       
    68     {
       
    69     CloseChunk();
       
    70     delete ipChunkName;
       
    71     }
       
    72 
       
    73 EXPORT_C RChunk& CSenChunk::Chunk()
       
    74     {
       
    75     return iChunk;
       
    76     }
       
    77 
       
    78 EXPORT_C TPtrC CSenChunk::ChunkName() const
       
    79     {
       
    80     if(ipChunkName)
       
    81         {
       
    82         return *ipChunkName;
       
    83         }
       
    84     else
       
    85         {
       
    86         return KNullDesC();
       
    87         }
       
    88     }
       
    89 
       
    90 EXPORT_C TBool CSenChunk::operator==(const CSenChunk& a)
       
    91     {
       
    92     return (this==&a);
       
    93     }
       
    94 
       
    95 EXPORT_C TInt CSenChunk::CreateChunk()
       
    96     {
       
    97     TInt retVal(KErrNone);
       
    98 #ifdef EKA2
       
    99     // Create protected global chunk in EKA2
       
   100     // (Global chunk will be protected chunk when chunk name length is zero)
       
   101     retVal = iChunk.CreateGlobal(KNullDesC, KSenMinRChunkSize, KSenMaxRChunkSize);
       
   102 #else // EKA1
       
   103     // Create named global chunk in EKA1
       
   104     retVal = iChunk.CreateGlobal(*ipChunkName, KSenMinRChunkSize, KSenMaxRChunkSize);
       
   105 #ifdef _SENDEBUG
       
   106         TLSLOG_FORMAT((KSenUtilsLogChannel, KNormalLogLevel, _L8("- RChunk.CreateGlobal('%S', %d, %d) returned: %d"),
       
   107                 ipChunkName,
       
   108                 KSenMinRChunkSize,
       
   109                 KSenMinRChunkSize,
       
   110                 retVal));
       
   111 #endif // _SENDEBUG
       
   112 #endif // EKA2/EKA1
       
   113     if (retVal == KErrNone)
       
   114         {
       
   115         TUint8* heapPtr = iChunk.Base();
       
   116         // Create header in the beginning of the chunk
       
   117         TLSLOG_FORMAT((KSenUtilsLogChannel, KNormalLogLevel, _L8("CSenChunk::CreateChunk KHeaderOffset size: (%d)"), KHeaderOffset));        
       
   118         new (heapPtr+KHeaderOffset) TChunkHeader;
       
   119         TChunkHeader& header = ChunkHeader();
       
   120         header.SetDescriptorCount(0);
       
   121         header.SetMessageType(MSenMessage::EMessageBase);
       
   122         header.SetMessageDirection(MSenMessage::EOutbound);
       
   123         header.SetPropertiesType(MSenProperties::ENotInUse);
       
   124         header.SetDoInitBeforeSending(EFalse);
       
   125         header.SetTransactionId(0);
       
   126         header.SetPendingTransactionId(0);
       
   127         }
       
   128     return retVal;
       
   129     }
       
   130     
       
   131 EXPORT_C TInt CSenChunk::OpenChunk()
       
   132     {
       
   133     TInt retVal(KErrNone);
       
   134 #ifdef EKA2
       
   135     retVal = KErrNotSupported;
       
   136 #else // EKA1
       
   137     // Open named global chunk in EKA1
       
   138     retVal = iChunk.OpenGlobal(*ipChunkName, EFalse); 
       
   139 #ifdef _SENDEBUG
       
   140         TLSLOG_FORMAT((KSenUtilsLogChannel, KNormalLogLevel, _L8("- RChunk.OpenGlobal() returned %d"), retVal));
       
   141 #endif // _SENDEBUG
       
   142 #endif // EKA2/EKA1
       
   143     return retVal;
       
   144     }
       
   145     
       
   146 EXPORT_C TInt CSenChunk::OpenChunkFromRMsgL(const RMessage2& aMessage, TInt aIndex)
       
   147     {
       
   148     TInt retVal(KErrNone);
       
   149 #ifdef EKA2 // // EKA2
       
   150     retVal = iChunk.Open(aMessage, aIndex, EOwnerProcess);
       
   151 #else // EKA1
       
   152     HBufC* pChunkName = HBufC::NewLC(KMaxName);
       
   153     TPtr chunkname = pChunkName->Des();
       
   154     TInt leaveCode(KErrNone);
       
   155     TRAP(leaveCode, retVal = aMessage.Read(aIndex, chunkname); )
       
   156 
       
   157     if(retVal==KErrNone && leaveCode != KErrNone)
       
   158         {
       
   159 #ifdef _SENDEBUG
       
   160             TLSLOG_FORMAT((KSenUtilsLogChannel, KMinLogLevel, _L8("- aMessage.Read(aIndex, chunkname) leaved: %d"), leaveCode ));
       
   161 #endif // _SENDEBUG
       
   162         retVal = leaveCode;
       
   163         }
       
   164         
       
   165     ipChunkName = chunkname.AllocL();
       
   166     CleanupStack::PopAndDestroy(pChunkName);
       
   167 
       
   168 #ifdef _SENDEBUG
       
   169     if (ipChunkName->Length() > 0 )
       
   170         {
       
   171         TLSLOG_FORMAT((KSenUtilsLogChannel, KNormalLogLevel, _L8("- RChunk name from RMessage2: '%S'"), ipChunkName ));
       
   172         }
       
   173 #endif // _SENDEBUG
       
   174 
       
   175     if(retVal==KErrNone)
       
   176         {
       
   177         retVal = iChunk.OpenGlobal(*ipChunkName, EFalse); 
       
   178 #ifdef _SENDEBUG
       
   179              TLSLOG_FORMAT((KSenUtilsLogChannel, KNormalLogLevel, _L8("- RChunk.OpenGlobal() returned %d"), retVal));
       
   180 #endif // _SENDEBUG
       
   181         }    
       
   182 #endif // EKA2/EKA1
       
   183     return retVal;
       
   184     }
       
   185 
       
   186 EXPORT_C TInt CSenChunk::OpenChunkFromHandleNumberL(TInt aHandleOrError)
       
   187     {
       
   188     TInt retVal(KErrNone);
       
   189 #ifdef EKA2 // // EKA2
       
   190     retVal = iChunk.SetReturnedHandle(aHandleOrError);
       
   191 #else // EKA1
       
   192     iChunk.SetHandle(aHandleOrError);
       
   193 #endif // EKA2/EKA1
       
   194     return retVal;
       
   195     }
       
   196     
       
   197 EXPORT_C void CSenChunk::CloseChunk()
       
   198     {
       
   199 #ifdef _SENDEBUG
       
   200         TLSLOG_FORMAT((KSenUtilsLogChannel, KNormalLogLevel, _L8("CSenChunk::CloseChunk - handle: %d"), iChunk.Handle()));
       
   201 #endif // _SENDEBUG
       
   202 
       
   203     THandleInfo chunkInfo;
       
   204     iChunk.HandleInfo(&chunkInfo);
       
   205 #ifdef _SENDEBUG
       
   206         TLSLOG_FORMAT((KSenUtilsLogChannel, KNormalLogLevel, _L8("- Before Close(): TChunkInfo: numOpenInThread: %d, numOpenInProcess: %d, numProcesses: %d"),
       
   207             chunkInfo.iNumOpenInThread,
       
   208             chunkInfo.iNumOpenInProcess,
       
   209             chunkInfo.iNumProcesses));
       
   210 #endif // _SENDEBUG
       
   211 
       
   212     iChunk.Close();
       
   213     }
       
   214     
       
   215 EXPORT_C TInt CSenChunk::AdjustChunk(TInt aNewSize)
       
   216     {
       
   217     // Ensure that at least 10064 bytes are allocated:
       
   218     if(aNewSize<KSenMinRChunkSize)
       
   219         {
       
   220         aNewSize = KSenMinRChunkSize;
       
   221         }
       
   222     TInt retVal = iChunk.Adjust(aNewSize);
       
   223     TLSLOG_FORMAT((KSenUtilsLogChannel, KNormalLogLevel, _L8("CSenChunk::AdjustChunk returns: (%d)"), retVal));
       
   224     return retVal;
       
   225     }
       
   226 
       
   227 EXPORT_C TChunkHeader& CSenChunk::ChunkHeader()
       
   228     {
       
   229     return *reinterpret_cast<TChunkHeader*>(iChunk.Base()+KHeaderOffset);
       
   230     }
       
   231 
       
   232 EXPORT_C TInt CSenChunk::DescToChunk(const TDesC8& aDescriptor)
       
   233     {
       
   234     TInt retVal(KErrNone);
       
   235 
       
   236     TInt size(aDescriptor.Length()+sizeof(TPtr8)+KSenChunkFourByteAlignment+KDataOffset);
       
   237 
       
   238     retVal = AdjustChunk(size);
       
   239 
       
   240     if(retVal == KErrNone)
       
   241         {
       
   242         TUint8* heapPtr = iChunk.Base();
       
   243         TChunkHeader& header = ChunkHeader();
       
   244         header.SetDescriptorCount(1);
       
   245         heapPtr += KDataOffset;
       
   246         heapPtr = RoundToNextDividableByFourAddress(heapPtr);
       
   247         // Place a new descriptor in the chunk to initialize it
       
   248         new (heapPtr) TPtr8(heapPtr + sizeof(TPtr8), 0, aDescriptor.Length());
       
   249         // Set the descriptor
       
   250         TPtr8* pDes = reinterpret_cast<TPtr8*>(heapPtr);
       
   251         pDes->Zero();
       
   252         pDes->Append(aDescriptor);
       
   253         }
       
   254     return retVal;
       
   255     }
       
   256 EXPORT_C TInt CSenChunk::DescToChunk(const TDesC8& aDescriptor, TInt aIndex)
       
   257     {
       
   258 #ifdef _SENDEBUG
       
   259         TLSLOG_L(KSenUtilsLogChannel,KMinLogLevel ,"CSenChunk::DescFromChunk");
       
   260 #endif // _SENDEBUG
       
   261     TInt retVal(KErrNone);
       
   262     
       
   263     if ( iChunk.Handle() > KErrNone )
       
   264         {
       
   265         TInt maxPtr = iChunk.Size();
       
   266 
       
   267         TInt size(aDescriptor.Length()+sizeof(TPtr8)+(aIndex+1)*KSenChunkFourByteAlignment);
       
   268         retVal = AdjustChunk(maxPtr+size);
       
   269         
       
   270         TChunkHeader& header = *reinterpret_cast<TChunkHeader*>(iChunk.Base() + KHeaderOffset);
       
   271         
       
   272         if ( aIndex <= header.DescriptorCount() )
       
   273             {
       
   274             header.SetDescriptorCount(aIndex+1);
       
   275             
       
   276             TUint8* heapPtr = iChunk.Base();
       
   277             heapPtr += KDataOffset;
       
   278             heapPtr = RoundToNextDividableByFourAddress(heapPtr);
       
   279             TPtr8* pDesc;
       
   280             pDesc = reinterpret_cast<TPtr8*>(heapPtr);
       
   281             for (TInt i=1; i < aIndex; i++)
       
   282                 {
       
   283                 heapPtr += (sizeof(TPtr8) + pDesc->MaxLength());
       
   284                 heapPtr = RoundToNextDividableByFourAddress(heapPtr);
       
   285                 pDesc = reinterpret_cast<TPtr8*>(heapPtr);
       
   286                 }
       
   287             heapPtr += (sizeof(TPtr8) + pDesc->MaxLength());
       
   288             heapPtr = RoundToNextDividableByFourAddress(heapPtr);
       
   289             
       
   290             // Place a new descriptor in the chunk to initialize it
       
   291             new (heapPtr) TPtr8(heapPtr + sizeof(TPtr8), 0, aDescriptor.Length());
       
   292             // Set the descriptor
       
   293             pDesc = reinterpret_cast<TPtr8*>(heapPtr);
       
   294             pDesc->Zero();
       
   295             pDesc->Append(aDescriptor);
       
   296             }
       
   297         else
       
   298             {
       
   299             retVal = KErrNotFound;
       
   300             }
       
   301         }
       
   302     else
       
   303         {
       
   304         retVal = KErrBadHandle;
       
   305 #ifdef _SENDEBUG
       
   306             TLSLOG_FORMAT((KSenUtilsLogChannel, KMinLogLevel, _L8("CSenChunk::DescFromChunk(chunk), RChunk.Handle(): %d is an error!"),
       
   307                 iChunk.Handle()));
       
   308 #endif // _SENDEBUG
       
   309         }
       
   310         
       
   311     return retVal;
       
   312     }
       
   313     
       
   314 EXPORT_C TInt CSenChunk::AllocDescToChunk(TInt size, TPtr8*& apAllocated)
       
   315     {
       
   316     TInt retVal(KErrNone);
       
   317     
       
   318     retVal = AdjustChunk(size+KSenChunkFourByteAlignment);
       
   319     
       
   320     if(retVal == KErrNone)
       
   321         {
       
   322         TUint8* heapPtr = iChunk.Base();
       
   323         TChunkHeader& header = ChunkHeader();
       
   324         header.SetDescriptorCount(1);
       
   325         heapPtr += KDataOffset;
       
   326         heapPtr = RoundToNextDividableByFourAddress(heapPtr);
       
   327         // Place a new descriptor in the chunk to initialize it
       
   328         new (heapPtr) TPtr8(heapPtr + sizeof(TPtr8), 0, size);
       
   329         // Set the descriptor
       
   330         apAllocated = reinterpret_cast<TPtr8*>(heapPtr);
       
   331         apAllocated->Zero();
       
   332         }
       
   333     return retVal;    
       
   334     }
       
   335 
       
   336 EXPORT_C TInt CSenChunk::DescsToChunk(const TDesC8& aDescriptor1,
       
   337                                    const TDesC8& aDescriptor2)
       
   338     {
       
   339 TInt retVal(KErrNone);
       
   340 
       
   341     TInt size(KDataOffset+aDescriptor1.Length()+aDescriptor2.Length()+\
       
   342               2*sizeof(TPtr8)+2*KSenChunkFourByteAlignment); 
       
   343 
       
   344     retVal = AdjustChunk(size);
       
   345 
       
   346     if(retVal == KErrNone)
       
   347         {
       
   348         TUint8* heapPtr = iChunk.Base();
       
   349         TChunkHeader& header = ChunkHeader();
       
   350         header.SetDescriptorCount(2);
       
   351         heapPtr += KDataOffset;
       
   352         heapPtr = RoundToNextDividableByFourAddress(heapPtr);
       
   353         // Place a new descriptor in the chunk to initialize it
       
   354         new (heapPtr) TPtr8(heapPtr + sizeof(TPtr8), 0, aDescriptor1.Length());
       
   355         // Set the descriptor
       
   356         TPtr8* pDes = reinterpret_cast<TPtr8*>(heapPtr);
       
   357         pDes->Zero();
       
   358         pDes->Append(aDescriptor1);
       
   359 
       
   360         heapPtr = heapPtr + sizeof(TPtr8) + aDescriptor1.Length();
       
   361         heapPtr = RoundToNextDividableByFourAddress(heapPtr);
       
   362         // Place a new descriptor in the chunk to initialize it
       
   363         new (heapPtr) TPtr8(heapPtr + sizeof(TPtr8), 0, aDescriptor2.Length());
       
   364         // Set the descriptor
       
   365         pDes = reinterpret_cast<TPtr8*>(heapPtr);
       
   366         pDes->Zero();
       
   367         pDes->Append(aDescriptor2);
       
   368         }
       
   369     return retVal;
       
   370 
       
   371     }
       
   372 
       
   373 EXPORT_C TInt CSenChunk::DescFromChunk(TPtrC8& aDesc, TInt aIndex)
       
   374     {
       
   375 #ifdef _SENDEBUG
       
   376         TLSLOG_L(KSenUtilsLogChannel,KMinLogLevel ,"CSenChunk::DescFromChunk");
       
   377 #endif // _SENDEBUG
       
   378     TInt retVal(KErrNone);
       
   379     
       
   380     if(iChunk.Handle()>KErrNone)
       
   381         {
       
   382         TChunkHeader& header = *reinterpret_cast<TChunkHeader*>(iChunk.Base() + KHeaderOffset);
       
   383         
       
   384         if (aIndex < header.DescriptorCount() && aIndex >= 0)
       
   385             {
       
   386             TUint8* heapPtr = iChunk.Base();
       
   387             heapPtr += KDataOffset;
       
   388             heapPtr = RoundToNextDividableByFourAddress(heapPtr);
       
   389             TPtr8* pDesc;
       
   390             pDesc = reinterpret_cast<TPtr8*>(heapPtr);
       
   391             for (TInt i=1; i <= aIndex; i++)
       
   392                 {
       
   393                 heapPtr += (sizeof(TPtr8) + pDesc->MaxLength());
       
   394                 heapPtr = RoundToNextDividableByFourAddress(heapPtr);
       
   395                 pDesc = reinterpret_cast<TPtr8*>(heapPtr);
       
   396                 }
       
   397             const TInt length = pDesc->Length();
       
   398             const TInt maxLength = pDesc->MaxLength();
       
   399             pDesc->Set(heapPtr + sizeof(TPtr8), length, maxLength);
       
   400             aDesc.Set(*pDesc);
       
   401             }
       
   402         else
       
   403             {
       
   404             retVal = KErrNotFound;
       
   405             }
       
   406         }
       
   407     else
       
   408         {
       
   409         retVal = KErrBadHandle;
       
   410 #ifdef _SENDEBUG
       
   411             TLSLOG_FORMAT((KSenUtilsLogChannel, KMinLogLevel, _L8("CSenChunk::DescFromChunk(chunk), RChunk.Handle(): %d is an error!"),
       
   412                 iChunk.Handle()));
       
   413 #endif // _SENDEBUG
       
   414         }
       
   415 
       
   416     return retVal;
       
   417     }
       
   418     
       
   419 EXPORT_C TInt CSenChunk::DescsFromChunk(TPtrC8& aDesc1, TPtrC8& aDesc2)
       
   420     {
       
   421     TInt retVal;
       
   422     retVal = DescFromChunk(aDesc1,0);
       
   423     if (retVal == KErrNone)
       
   424         {
       
   425         retVal = DescFromChunk(aDesc2,1);
       
   426         }
       
   427     return retVal;
       
   428     }
       
   429 
       
   430 EXPORT_C void CSenChunk::ChunkToArgs(TIpcArgs& aArgs, TInt aIndex)
       
   431     {
       
   432 #ifdef EKA2
       
   433     aArgs.Set(aIndex, iChunk); // EKA2
       
   434 #else
       
   435     aArgs.Set(aIndex, ipChunkName); // EKA1
       
   436 #endif
       
   437     }
       
   438 
       
   439 EXPORT_C void CSenChunk::SetLogger(RFileLogger* aLog)
       
   440     {
       
   441     iLog = aLog;
       
   442     }
       
   443 
       
   444 EXPORT_C RFileLogger* CSenChunk::Log() const
       
   445     {
       
   446     return iLog;
       
   447     }
       
   448     
       
   449 TUint8* CSenChunk::RoundToNextDividableByFourAddress(TUint8* aValue)
       
   450     {
       
   451     TInt modulo = ((TUint)aValue)%KSenChunkFourByteAlignment;
       
   452     if ( modulo == 0 ) 
       
   453         {
       
   454         return aValue;
       
   455         }
       
   456     else
       
   457         {
       
   458         return aValue+(KSenChunkFourByteAlignment-modulo);        
       
   459         }
       
   460     }
       
   461     
       
   462 EXPORT_C RFile& CSenChunk::RequestFileHandle()
       
   463 	{
       
   464 	return iFile;
       
   465 	}
       
   466 	
       
   467 EXPORT_C void CSenChunk::RequestFileHandle(RFile& aFile)
       
   468 	{
       
   469 	iFile = aFile;
       
   470 	}
       
   471     
       
   472 
       
   473     
       
   474 // End of File