messagingfw/wappushfw/MiscPushMsgUtils/src/CMultipartBinIterator.cpp
changeset 0 8e480a14352b
equal deleted inserted replaced
-1:000000000000 0:8e480a14352b
       
     1 // Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15     
       
    16 #include "cmultipartbiniterator.h"
       
    17 
       
    18 
       
    19 EXPORT_C  CMultipartBinIterator* CMultipartBinIterator::NewL(CPushMessage& aPushMessage)
       
    20 /** Allocates and creates a new binary multipart message iterator.
       
    21 
       
    22 @param aPushMessage Binary multipart message to process
       
    23 @return New binary multipart message iterator */
       
    24 	{
       
    25 	CMultipartBinIterator* self =  new (ELeave) CMultipartBinIterator(aPushMessage);
       
    26 	CleanupStack::PushL(self);
       
    27 	self->ConstructL(); 
       
    28 	CleanupStack::Pop();
       
    29 	return self;
       
    30 	}
       
    31 
       
    32 
       
    33 /**
       
    34  * CMultipartPushMessage is a base utility class to crack out parts of a 
       
    35  * multipart message.
       
    36  * @param aPushMessage: A message determined to be multipart. 
       
    37  */
       
    38 CMultipartBinIterator::CMultipartBinIterator(CPushMessage& aPushMessage) : 
       
    39 	CMultipartIteratorBase(aPushMessage)
       
    40 	{
       
    41 	}
       
    42 
       
    43 
       
    44 /**
       
    45  * Validates & completes the construction of this class.
       
    46  */
       
    47 void CMultipartBinIterator::ConstructL() 
       
    48 	{
       
    49 #ifdef _DEBUG
       
    50 	_LIT(KMultipartBin, "application/vnd.wap.multipart.");
       
    51 	TPtrC contentType;
       
    52 	iPushMessage.GetContentType(contentType);
       
    53 	__ASSERT_DEBUG( contentType.Find(KMultipartBin) == 0 , User::Panic(KPushInvalidContentType,0));
       
    54 #endif
       
    55 	
       
    56 	TPtrC8 msgBody;
       
    57 	if (!iPushMessage.GetMessageBody(msgBody))
       
    58 		User::Leave(KErrNotFound);
       
    59 	
       
    60 	// get the nEntries field from the start of the binary multipart
       
    61 	TWapBinCodex::ExtractUIntvarL(msgBody, 0, iMultiNumEntries);
       
    62 		
       
    63 	if (iMultiNumEntries.iValue == 0) // No multiparts
       
    64 		User::Leave(KErrCorrupt);
       
    65 
       
    66 		
       
    67 	// move the iterator to start off after the multipart header
       
    68 	iCurrentPartStart = iMultiNumEntries.iOctetSize;		
       
    69 	}
       
    70 
       
    71 
       
    72 EXPORT_C TBool CMultipartBinIterator::NextL()
       
    73 /** Moves the iterator to the next message part.
       
    74 
       
    75 @return ETrue if there is a next part, EFalse otherwise */
       
    76 	{
       
    77 	if (++iCurrentPart >= iMultiNumEntries.iValue)
       
    78 		return EFalse;
       
    79 
       
    80 	TWapBinCodex::TUintvar hdrSize, bodySize;
       
    81 		
       
    82 	TPtrC8 msgBody;
       
    83 	if (!iPushMessage.GetMessageBody(msgBody))
       
    84 		return EFalse;
       
    85 
       
    86 	// Get the header size
       
    87 	TWapBinCodex::ExtractUIntvarL(msgBody, iCurrentPartStart,  hdrSize);
       
    88 
       
    89 	// move index over the header size data
       
    90 	iCurrentPartStart += hdrSize.iOctetSize;
       
    91 
       
    92 	// Get the body size
       
    93 	TWapBinCodex::ExtractUIntvarL(msgBody, iCurrentPartStart, bodySize);
       
    94 
       
    95 	// move index over the body size data
       
    96 	iCurrentPartStart += bodySize.iOctetSize;
       
    97 
       
    98 	// move index over the part data
       
    99 	iCurrentPartStart += (hdrSize.iValue + bodySize.iValue);
       
   100 
       
   101 	return ETrue;
       
   102 	}
       
   103 
       
   104 EXPORT_C void CMultipartBinIterator::FirstL()
       
   105 /** Resets the iterator the beginning of the first part of the message. */
       
   106 	{
       
   107 	iCurrentPartStart = iMultiNumEntries.iOctetSize;	
       
   108 	iCurrentPart = 0;
       
   109 	}
       
   110 
       
   111 EXPORT_C CPushMessage* CMultipartBinIterator::PartL()
       
   112 /** Gets the message part currently referenced by the iterator.
       
   113 
       
   114 @return Message part 
       
   115 @leave KErrCorrupt The message is too short
       
   116 @leave KErrNotFound Will leave if message body is empty
       
   117 @leave TDesC8::AllocLC
       
   118 @leave CPushMessage::NewL
       
   119 */
       
   120 	{
       
   121 	__ASSERT_DEBUG( iCurrentPart < iMultiNumEntries.iValue, User::Panic(KPushPartIndexOutOfRange,0));
       
   122 
       
   123 	TPtrC8 msgBody;
       
   124 	if (!iPushMessage.GetMessageBody(msgBody))
       
   125 		User::Leave(KErrNotFound);
       
   126 
       
   127 	// iCurrentPartStart is pointing to beginning of the message 
       
   128 	// index will be used to get past the message headers
       
   129 	TUint index = iCurrentPartStart;
       
   130 
       
   131 	// Move over the headers
       
   132 	TWapBinCodex::TUintvar hdrSize, bodySize;
       
   133 	TWapBinCodex::ExtractUIntvarL(msgBody, index,  hdrSize);
       
   134 	index += hdrSize.iOctetSize;
       
   135 	TWapBinCodex::ExtractUIntvarL(msgBody, index, bodySize);
       
   136 	index += bodySize.iOctetSize;
       
   137 
       
   138 	// Now get the data
       
   139 	TUint len = msgBody.Length();
       
   140 
       
   141 	// validate that we have as much data as HEADER indicates
       
   142 	if ( hdrSize.iValue < 0 || // No negative indices
       
   143 		(len < (index + hdrSize.iValue)))	
       
   144 		User::Leave(KErrCorrupt);
       
   145 
       
   146 	// Get the Header
       
   147 	HBufC8* header = msgBody.Mid(index, hdrSize.iValue).AllocLC();
       
   148 	index += hdrSize.iValue;
       
   149 		
       
   150 	// validate that we have as much data as BODY indicates 
       
   151 	if ( bodySize.iValue < 0 || // No negative indices
       
   152 		(len < (index + bodySize.iValue)))	
       
   153 		User::Leave(KErrCorrupt);
       
   154 
       
   155 	// Get the Body
       
   156 	HBufC8* body = msgBody.Mid(index, bodySize.iValue).AllocLC();
       
   157 		
       
   158 	CPushMessage* pm = CPushMessage::NewL( header,  body);
       
   159 	CleanupStack::Pop(2, header);  // body, header
       
   160 	return pm;
       
   161 	}
       
   162