httpfilters/cookie/ManagerSrc/CookieIPC.cpp
changeset 0 b16258d2340f
child 19 c0c2f28ace9c
equal deleted inserted replaced
-1:000000000000 0:b16258d2340f
       
     1 /*
       
     2 * Copyright (c) 2002 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:  Implementation of class TCookiePacker
       
    15 *
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 // INCLUDE FILES
       
    21 	// User includes
       
    22 #include "cookie.h"
       
    23 #include "cookieipc.h"
       
    24 #include "CookieLogger.h"
       
    25 
       
    26 #ifdef __TEST_COOKIE_LOG__
       
    27 const TInt KCookiePackerLogLevel = 4;
       
    28 #endif
       
    29 
       
    30 // Maximum cookie size (defined in RFC2965)
       
    31 const TInt KMaxCookieBufferSize = 0x1000;   // 4 kilobytes
       
    32 
       
    33 
       
    34 // ---------------------------------------------------------
       
    35 // TCookiePacker::TCookiePacker
       
    36 // ---------------------------------------------------------
       
    37 //
       
    38 TCookiePacker::TCookiePacker( RStringPool aStringPool )
       
    39 : iStringPool( aStringPool )
       
    40 	{
       
    41 	}
       
    42 
       
    43 
       
    44 // ---------------------------------------------------------
       
    45 // TCookiePacker::AddDateL
       
    46 // ---------------------------------------------------------
       
    47 //
       
    48 TInt TCookiePacker::AddDateL( const CCookie& aCookie,
       
    49                             TDes8& aBuffer,
       
    50                             TBool aNoDefaulted ) const
       
    51     {
       
    52     CLOG( ( EClient, KCookiePackerLogLevel, _L("-> TCookiePacker::AddDate") ) );
       
    53 
       
    54     THTTPHdrVal attributeVal;
       
    55     TInt error = KErrNone;
       
    56 
       
    57     TBool defaulted( EFalse );
       
    58     TInt found = aCookie.Attribute( CCookie::EDate, attributeVal, defaulted );
       
    59     // Date attribute must present in the RFC cookie
       
    60     if ( found == KErrNone )
       
    61         {
       
    62         if (aNoDefaulted && defaulted )
       
    63             {// pass a null text, that is, a length of 0
       
    64 		    AppendAttributeLength( 0, aBuffer );
       
    65             }
       
    66         else
       
    67             {
       
    68             TDateTime attrTime = attributeVal.DateTime();
       
    69             TTime cookieDate( attrTime );
       
    70 
       
    71             // This FormatString must be shorter than sizeof(TDateTime)!
       
    72             // As the cookie's date attribute always costs sizeof(TDateTime) byte
       
    73             // in the memory (when we calculate its size in GetCookieSize),
       
    74             // we have to allocate sizeof(TDateTime) byte in the client-server
       
    75             // communication buffer too.
       
    76             _LIT(KDateFormatString, "%F%Y%M%D:%H%T%S");
       
    77             // convert DateTime to string (16 bit)
       
    78             TInt size =  sizeof( TDateTime );
       
    79             HBufC *buf = HBufC::NewLC( size );
       
    80             TPtr bufDes( buf->Des() );
       
    81             bufDes.Fill( ' ', size );
       
    82             cookieDate.FormatL( bufDes, KDateFormatString );
       
    83             bufDes.SetLength( size );
       
    84             // convert to 8 bit
       
    85             HBufC8 *buf8 = HBufC8::NewLC( size );
       
    86             TPtr8 buf8Des( buf8->Des() );
       
    87             buf8Des.Copy( bufDes );
       
    88 
       
    89             AppendAttributeLength( buf8Des.Length(), aBuffer );
       
    90             aBuffer.Append( buf8Des );
       
    91 
       
    92             CleanupStack::PopAndDestroy();  // buf8
       
    93             CleanupStack::PopAndDestroy();  // buf
       
    94             }
       
    95         }
       
    96     else  // Netscape cookie?
       
    97         { // pass a null text, that is, a length of 0
       
    98 		AppendAttributeLength( 0, aBuffer );
       
    99         }
       
   100 
       
   101     // always append 'found' to the end...
       
   102     // if found == 0 -> HAS IT, 1
       
   103     // otherwise, 0    
       
   104     AppendAttributeLength( found ? 0 : 1, aBuffer);
       
   105 
       
   106     // always append 'defaulted' to the end...
       
   107     AppendAttributeLength( defaulted, aBuffer);
       
   108 
       
   109     CLOG( ( EClient, KCookiePackerLogLevel, 
       
   110         _L("<- TCookiePacker::AddDate, errcode %d"), error ) );
       
   111     return error;
       
   112     }
       
   113 
       
   114 // ---------------------------------------------------------
       
   115 // TCookiePacker::AddStringF
       
   116 // ---------------------------------------------------------
       
   117 //
       
   118 TInt TCookiePacker::AddStringF( const CCookie::TCookieAttributeName aAttrib,
       
   119 							   const CCookie& aCookie,
       
   120 							   TDes8& aBuffer,
       
   121                                TBool aNoDefaulted ) const
       
   122     {
       
   123 	CLOG( ( EClient, KCookiePackerLogLevel, _L( "-> TCookiePacker::AddStringF" ) ) );
       
   124 
       
   125     THTTPHdrVal attributeVal;
       
   126     TInt error = KErrNone;
       
   127 
       
   128     TBool defaulted( EFalse );
       
   129     TInt found = aCookie.Attribute( aAttrib, attributeVal, defaulted );
       
   130     if ( found == KErrNone )
       
   131         {
       
   132         if ( aNoDefaulted && defaulted )
       
   133             {// pass a null text, that is, a length of 0
       
   134 		    AppendAttributeLength( 0, aBuffer );
       
   135             }
       
   136         else
       
   137             {
       
   138             HBufC8* txt( NULL );
       
   139             if( attributeVal.Type() == THTTPHdrVal::KStrFVal )
       
   140                 txt = attributeVal.StrF().DesC().Alloc();
       
   141             else if ( attributeVal.Type() == THTTPHdrVal::KStrVal )
       
   142                 txt = attributeVal.Str().DesC().Alloc();
       
   143                 
       
   144             if ( txt )
       
   145                 {
       
   146                 AppendAttributeLength( txt->Length(), aBuffer );
       
   147 			    aBuffer.Append( *txt );
       
   148                 delete txt;
       
   149                 }
       
   150             else
       
   151                 {
       
   152                 error = KErrNoMemory;
       
   153                 }
       
   154             }
       
   155         }
       
   156     else
       
   157         { // pass a null text, that is, a length of 0
       
   158 		AppendAttributeLength( 0, aBuffer );
       
   159         }
       
   160 
       
   161     // always append 'found' to the end...
       
   162     // if found == 0 -> HAS IT, 1
       
   163     // otherwise, 0    
       
   164     AppendAttributeLength( found ? 0 : 1, aBuffer);
       
   165 
       
   166     // always append 'defaulted' to the end...
       
   167     AppendAttributeLength( defaulted, aBuffer);
       
   168 
       
   169 	CLOG( ( EClient, KCookiePackerLogLevel,
       
   170 		_L( "<- TCookiePacker::AddStringF, errcode%d" ), error ) );
       
   171 
       
   172     return error;
       
   173     }
       
   174 
       
   175 
       
   176 // ---------------------------------------------------------
       
   177 // TCookiePacker::AppendAttributeLength
       
   178 // ---------------------------------------------------------
       
   179 //
       
   180 void TCookiePacker::AppendAttributeLength( TInt aLength, TDes8& aBuffer ) const
       
   181     {
       
   182 	CLOG( ( EClient, KCookiePackerLogLevel, _L( "-> TCookiePacker::AppendAttributeLength" ) ) );
       
   183 
       
   184 	TInt attrLength = aLength;
       
   185 	TPtrC8 attrDes( (const TUint8*)&attrLength, sizeof( TInt ) );
       
   186 	aBuffer.Append( attrDes );
       
   187 
       
   188 	CLOG( ( EClient, KCookiePackerLogLevel, _L( "<- TCookiePacker::AppendAttributeLength" ) ) );
       
   189     }
       
   190 
       
   191 
       
   192 
       
   193 // ---------------------------------------------------------
       
   194 // TCookiePacker::CliPackCookie
       
   195 // ---------------------------------------------------------
       
   196 //
       
   197 TInt TCookiePacker::CliPackCookie( TDes8& aBuffer, 
       
   198                                    const CCookie& aCookie ) const
       
   199 	{
       
   200     return DoPackCookie( aBuffer, aCookie, EFalse );
       
   201     }
       
   202 
       
   203 
       
   204 
       
   205 // ---------------------------------------------------------
       
   206 // TCookiePacker::SrvPackCookie
       
   207 // ---------------------------------------------------------
       
   208 //
       
   209 TInt TCookiePacker::SrvPackCookie( TDes8& aBuffer, 
       
   210                                    const CCookie& aCookie ) const
       
   211 	{
       
   212     return DoPackCookie( aBuffer, aCookie, ETrue );
       
   213     }
       
   214 
       
   215 
       
   216 
       
   217 // ---------------------------------------------------------
       
   218 // TCookiePacker::GetPackedAttribute
       
   219 // ---------------------------------------------------------
       
   220 //
       
   221 void TCookiePacker::GetPackedAttributeL
       
   222 						( const CCookie::TCookieAttributeName aAttrib,
       
   223 						CCookie& aCookie, 
       
   224 						const TUint8*& aPtrStart ) const
       
   225     {
       
   226 	// the first 4 bytes (i.e. sizeof(TInt)) contains the size
       
   227 	TInt size;
       
   228 	TPtr8 sizeDes( (TUint8*)&size, sizeof( TInt ) );
       
   229 	sizeDes.Copy( aPtrStart, sizeof( TInt ) );
       
   230 	
       
   231 	User::LeaveIfError(size);
       
   232 	// now we have the size, jump to the value
       
   233     aPtrStart += sizeof( TInt );
       
   234     
       
   235     if ( size )
       
   236         {
       
   237         HBufC8* buf = HBufC8::NewLC( size );
       
   238 		TPtr8 bufDes( buf->Des() );	// buffer descriptor
       
   239 	    Mem::Copy( (void*)buf->Ptr(), (void*)aPtrStart, size );
       
   240         bufDes.SetLength( size );
       
   241 
       
   242 		aPtrStart += size;
       
   243 
       
   244         // now get the 'found' value 
       
   245 	    TInt found;
       
   246 	    TPtr8 foundDes( (TUint8*)&found, sizeof( TInt ) );
       
   247 	    foundDes.Copy( aPtrStart, sizeof( TInt ) );
       
   248         aPtrStart += sizeof( TInt );
       
   249 
       
   250         // now get the 'defaulted' value 
       
   251 	    TInt defaulted;
       
   252 	    TPtr8 defaultedDes( (TUint8*)&defaulted, sizeof( TInt ) );
       
   253 	    defaultedDes.Copy( aPtrStart, sizeof( TInt ) );
       
   254         aPtrStart += sizeof( TInt );
       
   255         
       
   256         THTTPHdrVal attributeVal;
       
   257         // Name and Value are case-sensitive
       
   258         if( ( CCookie::EName == aAttrib ) || ( CCookie::EValue == aAttrib ) )
       
   259             {
       
   260             RString str = iStringPool.OpenStringL( bufDes );
       
   261             attributeVal.SetStr( str );
       
   262             aCookie.SetAttribute( aAttrib, 
       
   263                 attributeVal, 
       
   264                 defaulted ); // ignore the result
       
   265             str.Close();
       
   266             }
       
   267         else
       
   268             {
       
   269             RStringF strf = iStringPool.OpenFStringL( bufDes );
       
   270             attributeVal.SetStrF( strf );
       
   271             aCookie.SetAttribute( aAttrib, 
       
   272                 attributeVal, 
       
   273                 defaulted ); // ignore the result
       
   274             strf.Close();
       
   275             }
       
   276 
       
   277 		CleanupStack::PopAndDestroy();	// buf
       
   278         }
       
   279     else
       
   280         {
       
   281         // now get the 'found' value 
       
   282 	    TInt found;
       
   283 	    TPtr8 foundDes( (TUint8*)&found, sizeof( TInt ) );
       
   284 	    foundDes.Copy( aPtrStart, sizeof( TInt ) );
       
   285         aPtrStart += sizeof( TInt );
       
   286 
       
   287         // now get the 'defaulted' value 
       
   288 	    TInt defaulted;
       
   289 	    TPtr8 defaultedDes( (TUint8*)&defaulted, sizeof( TInt ) );
       
   290 	    defaultedDes.Copy( aPtrStart, sizeof( TInt ) );
       
   291         aPtrStart += sizeof( TInt );
       
   292 
       
   293         if ( found )
       
   294             { // still add empty str...
       
   295             HBufC8* buf = HBufC8::NewLC( 0 );
       
   296 		    TPtr8 bufDes( buf->Des() );	// buffer descriptor
       
   297             bufDes.SetLength( 0 );
       
   298             
       
   299             THTTPHdrVal attributeVal;
       
   300             // Name and Value are case-sensitive
       
   301             // It is a serious error if Name or Value is empty!
       
   302             if( ( CCookie::EName == aAttrib ) || ( CCookie::EValue == aAttrib ) )
       
   303                 {
       
   304                 RString str = iStringPool.OpenStringL( bufDes );
       
   305                 attributeVal.SetStr( str );
       
   306                 aCookie.SetAttribute( aAttrib, 
       
   307                     attributeVal, 
       
   308                     defaulted ); // ignore the result
       
   309                 str.Close();
       
   310                 }
       
   311             else
       
   312                 {
       
   313                 RStringF strf = iStringPool.OpenFStringL( bufDes );
       
   314                 attributeVal.SetStrF( strf );
       
   315                 aCookie.SetAttribute( aAttrib, 
       
   316                     attributeVal, 
       
   317                     defaulted ); // ignore the result
       
   318                 strf.Close();
       
   319                 }
       
   320 
       
   321     		CleanupStack::PopAndDestroy();	// buf
       
   322             }
       
   323         }
       
   324     }
       
   325 
       
   326 
       
   327 // ---------------------------------------------------------
       
   328 // TCookiePacker::GetPackedDateAttributeL
       
   329 // ---------------------------------------------------------
       
   330 //
       
   331 void TCookiePacker::GetPackedDateAttributeL( CCookie& aCookie,
       
   332                                             const TUint8*& aPtrStart ) const
       
   333     {
       
   334 	// the first 4 bytes (i.e. sizeof(TInt)) contains the size
       
   335 	TInt size;
       
   336 	TPtr8 sizeDes( (TUint8*)&size, sizeof( TInt ) );
       
   337 	sizeDes.Copy( aPtrStart, sizeof( TInt ) );
       
   338 	User::LeaveIfError(size);
       
   339 	// now we have the size, jump to the value
       
   340     aPtrStart += sizeof( TInt );
       
   341     if ( size )
       
   342         {
       
   343         HBufC8* buf8 = HBufC8::NewLC( size );
       
   344 		TPtr8 buf8Des( buf8->Des() );	// buffer descriptor
       
   345 	    Mem::Copy( (void*)buf8->Ptr(), (void*)aPtrStart, size );
       
   346         buf8Des.SetLength( size );
       
   347         aPtrStart += size;
       
   348 
       
   349         // now get the 'found' value 
       
   350 	    TInt found;
       
   351 	    TPtr8 foundDes( (TUint8*)&found, sizeof( TInt ) );
       
   352 	    foundDes.Copy( aPtrStart, sizeof( TInt ) );
       
   353         aPtrStart += sizeof( TInt );
       
   354 
       
   355         // now get the 'defaulted' value 
       
   356 	    TInt defaulted;
       
   357 	    TPtr8 defaultedDes( (TUint8*)&defaulted, sizeof( TInt ) );
       
   358 	    defaultedDes.Copy( aPtrStart, sizeof( TInt ) );
       
   359         aPtrStart += sizeof( TInt );
       
   360 
       
   361         // convert string to 16 bit
       
   362         HBufC *buf = HBufC::NewLC( size );
       
   363         TPtr bufDes( buf->Des() );
       
   364         bufDes.Copy( buf8Des );
       
   365 
       
   366         // convert to DateTime
       
   367         TTime cookieDate;
       
   368         // TTime::Set() uses 0 value as offset for Month and Day,
       
   369         // we convert those values.
       
   370         DecreaseNumericValueL( bufDes, 5 );  // Month
       
   371         DecreaseNumericValueL( bufDes, 7 );  // Day
       
   372         bufDes.Trim();  // spaces must be removed before TTime::Set()
       
   373         // TInt parseError = 
       
   374         cookieDate.Set( bufDes );
       
   375         TDateTime temp = cookieDate.DateTime();
       
   376         THTTPHdrVal attributeVal( temp );
       
   377         aCookie.SetAttribute( CCookie::EDate, attributeVal, defaulted );
       
   378 
       
   379 		CleanupStack::PopAndDestroy();	// buf
       
   380 		CleanupStack::PopAndDestroy();	// buf8
       
   381         }
       
   382     else
       
   383         {
       
   384         // now get the 'found' value 
       
   385 	    TInt found;
       
   386 	    TPtr8 foundDes( (TUint8*)&found, sizeof( TInt ) );
       
   387 	    foundDes.Copy( aPtrStart, sizeof( TInt ) );
       
   388         aPtrStart += sizeof( TInt );
       
   389 
       
   390         // now get the 'defaulted' value 
       
   391 	    TInt defaulted;
       
   392 	    TPtr8 defaultedDes( (TUint8*)&defaulted, sizeof( TInt ) );
       
   393 	    defaultedDes.Copy( aPtrStart, sizeof( TInt ) );
       
   394         aPtrStart += sizeof( TInt );
       
   395 
       
   396         if ( found )
       
   397             {
       
   398             TTime nowTime;
       
   399             nowTime.UniversalTime();
       
   400             TDateTime attrTime = nowTime.DateTime();
       
   401 		    THTTPHdrVal attributeVal( attrTime );
       
   402             aCookie.SetAttribute( CCookie::EDate, attributeVal, defaulted );
       
   403             }
       
   404 
       
   405         }
       
   406     }
       
   407 
       
   408 // ---------------------------------------------------------
       
   409 // TCookiePacker::UnpackCookieL
       
   410 // get the cookie entries, one after the other
       
   411 // an entry with a length of 0 and no txtbuf means empty value
       
   412 // ---------------------------------------------------------
       
   413 //
       
   414 void TCookiePacker::UnpackCookieL( const TUint8*& aPtr,
       
   415 								  CCookie& aCookie ) const
       
   416     {
       
   417 	CLOG( ( EClient, KCookiePackerLogLevel, 
       
   418 	    _L( "-> TCookiePacker::UnpackCookieL" ) ) );
       
   419     GetPackedAttributeL( CCookie::EName, aCookie, aPtr );
       
   420 	GetPackedAttributeL( CCookie::EValue, aCookie, aPtr );
       
   421 	GetPackedAttributeL( CCookie::EComment, aCookie, aPtr );
       
   422 	GetPackedAttributeL( CCookie::ECommentURI, aCookie, aPtr );
       
   423 	GetPackedAttributeL( CCookie::EDiscard, aCookie, aPtr );
       
   424 	GetPackedAttributeL( CCookie::EDomain, aCookie, aPtr );
       
   425 	GetPackedAttributeL( CCookie::EMaxAge, aCookie, aPtr );
       
   426 	GetPackedAttributeL( CCookie::EPath, aCookie, aPtr );
       
   427 	GetPackedAttributeL( CCookie::EPort, aCookie, aPtr );
       
   428 	GetPackedAttributeL( CCookie::ESecure, aCookie, aPtr );
       
   429 	GetPackedAttributeL( CCookie::EVersion, aCookie, aPtr );
       
   430 	GetPackedAttributeL( CCookie::EExpires, aCookie, aPtr );
       
   431     GetPackedDateAttributeL( aCookie, aPtr );
       
   432 	// now get the FromCookie2 TBool, which comes a TInt...
       
   433     TInt fromcookie2( 0 );
       
   434 	TPtr8 sizeDes( (TUint8*)&fromcookie2, sizeof( TInt ) );
       
   435 	sizeDes.Copy( aPtr, sizeof( TInt ) );
       
   436     aPtr += sizeof( TInt );
       
   437 	// now we have the size, jump to the value
       
   438     aCookie.SetCookie2( fromcookie2 );
       
   439 
       
   440     THTTPHdrVal hVal;
       
   441 	// We're checking the Version attribute - this
       
   442 	// attribute is present in RFC but not in Netscape cookies
       
   443 	if ( aCookie.Attribute( CCookie::EVersion, hVal ) == KErrNone )
       
   444         {
       
   445         aCookie.SetFromNetscape( EFalse );
       
   446         }
       
   447     else
       
   448         {
       
   449         aCookie.SetFromNetscape( ETrue );
       
   450         }
       
   451     TrimNameAndValueL( aCookie );
       
   452 	CLOG( ( EClient, KCookiePackerLogLevel, 
       
   453 	    _L( "<- TCookiePacker::UnpackCookieL" ) ) );
       
   454     }
       
   455 
       
   456 // ---------------------------------------------------------
       
   457 // TCookiePacker::TrimNameAndValueL
       
   458 // ---------------------------------------------------------
       
   459 //
       
   460 void TCookiePacker::TrimNameAndValueL( CCookie& aCookie ) const
       
   461     {
       
   462 	CLOG( ( EClient, KCookiePackerLogLevel, 
       
   463 	    _L( "-> TCookiePacker::TrimNameAndValueL" ) ) );
       
   464     THTTPHdrVal hValName;
       
   465     if( aCookie.Attribute( CCookie::EName, hValName ) == KErrNone )
       
   466         {
       
   467         THTTPHdrVal hValValue;
       
   468         if( aCookie.Attribute( CCookie::EValue, hValValue ) == KErrNone )
       
   469             {
       
   470             TInt lenName( hValName.Str().DesC().Length() );
       
   471             TInt lenValue( hValValue.Str().DesC().Length() );
       
   472             CLOG( ( EClient, KCookiePackerLogLevel, 
       
   473                 _L( "NameLen: %d, ValueLen: %d" ), lenName, lenValue ) );
       
   474             if( lenName + lenValue < KMaxCookieBufferSize )
       
   475                 {
       
   476                 // everything is OK.
       
   477                 return;
       
   478                 }
       
   479             if( lenName >= KMaxCookieBufferSize )
       
   480                 {
       
   481                 // Cookie should be discarded
       
   482                 User::Leave( KErrTooBig );
       
   483                 }
       
   484             else
       
   485                 {
       
   486                 // trim value
       
   487                 TInt size( KMaxCookieBufferSize - lenName );
       
   488                 HBufC8* buf = HBufC8::NewLC( size + 1 );
       
   489                 TPtr8 bufDes( buf->Des() );	// buffer descriptor
       
   490                 bufDes.Copy( hValValue.Str().DesC().Left( size ) );
       
   491                 bufDes.ZeroTerminate();
       
   492                 // modify aCookie
       
   493                 RString str = iStringPool.OpenStringL( bufDes );
       
   494                 THTTPHdrVal attributeVal( str );
       
   495                 aCookie.RemoveAttribute( CCookie::EValue );
       
   496                 aCookie.SetAttribute( CCookie::EValue, attributeVal );
       
   497                 str.Close();
       
   498                 CleanupStack::PopAndDestroy( buf );
       
   499                 }
       
   500             }
       
   501         }
       
   502 	CLOG( ( EClient, KCookiePackerLogLevel, 
       
   503 	    _L( "<- TCookiePacker::TrimNameAndValueL" ) ) );
       
   504     }
       
   505 
       
   506 // ---------------------------------------------------------
       
   507 // TCookiePacker::UnpackCookieL
       
   508 // ---------------------------------------------------------
       
   509 //
       
   510 void TCookiePacker::UnpackCookieL( const TDesC8& aBuffer,
       
   511 								  CCookie& aCookie ) const
       
   512     {
       
   513 	const TUint8* ptr = aBuffer.Ptr();
       
   514 	UnpackCookieL( ptr, aCookie );
       
   515 	}
       
   516 
       
   517 // ---------------------------------------------------------
       
   518 // TCookiePacker::UnpackCookiesFromBufferL
       
   519 // ---------------------------------------------------------
       
   520 //
       
   521 void TCookiePacker::UnpackCookiesFromBufferL( const TDesC8& aBuffer,
       
   522 									RPointerArray<CCookie>& aCookies ) const
       
   523     {
       
   524 	const TUint8* bufferPtr = aBuffer.Ptr();
       
   525 	const TUint8* bufferEndPtr = bufferPtr + aBuffer.Size();
       
   526 
       
   527 	while ( bufferPtr < bufferEndPtr )
       
   528 		{
       
   529 		CCookie* cookie = CCookie::NewL( iStringPool );
       
   530 		CleanupStack::PushL( cookie );
       
   531 
       
   532 		UnpackCookieL( bufferPtr, *cookie );
       
   533 
       
   534 		if ( bufferEndPtr < bufferPtr )	// we read in too many bytes
       
   535 			{
       
   536 			CleanupStack::PopAndDestroy();	// destroy the last bad cookie
       
   537 			}
       
   538 		else	// everything is okay
       
   539 			{
       
   540 			// The cookie pointer array (i.e. iCookies) takes over the
       
   541 			// ownership
       
   542 			User::LeaveIfError( aCookies.Append( cookie ) );
       
   543 
       
   544 			CleanupStack::Pop();	// cookie
       
   545 			}
       
   546 		}
       
   547     }
       
   548 
       
   549 
       
   550 
       
   551 // ---------------------------------------------------------
       
   552 // TCookiePacker::DoPackCookie
       
   553 // ---------------------------------------------------------
       
   554 //
       
   555 TInt TCookiePacker::DoPackCookie( TDes8& aBuffer, 
       
   556                                   const CCookie& aCookie,
       
   557                                   TBool aServer ) const
       
   558 	{
       
   559 	CLOG( ( EClient, KCookiePackerLogLevel, _L( "-> TCookiePacker::DoPackCookie" ) ) );
       
   560     TInt error = AddStringF( CCookie::EName, aCookie, aBuffer );
       
   561     if ( error == KErrNone )
       
   562         {
       
   563         error = AddStringF( CCookie::EValue, aCookie, aBuffer );
       
   564         if ( error == KErrNone )
       
   565             {
       
   566             error = AddStringF( CCookie::EComment, aCookie, aBuffer );
       
   567             if ( error == KErrNone )
       
   568                 {
       
   569                 error = AddStringF( CCookie::ECommentURI, aCookie, aBuffer );
       
   570                 if ( error == KErrNone )
       
   571                     {
       
   572                     error = AddStringF( CCookie::EDiscard,
       
   573 										aCookie,
       
   574 										aBuffer );
       
   575                     if ( error == KErrNone )
       
   576                         {
       
   577                         // If the server is packing, need to take extra care 
       
   578                         // for the Domain attribute...
       
   579                         // If the Domain is defaulted, defaulted domain 
       
   580                         // should not be sent back...
       
   581                         // for this, set aNoDefaulted to aServer:
       
   582                         // if server is packing, attribute will be suppressed
       
   583                         // if the client is packing, attribute
       
   584                         // will be transferred normally...
       
   585                         error = AddStringF( CCookie::EDomain,
       
   586 							    			aCookie,
       
   587 								    		aBuffer,
       
   588                                             aServer );
       
   589                         if ( error == KErrNone )
       
   590                             {
       
   591                             error = AddStringF( CCookie::EMaxAge,
       
   592 												aCookie,
       
   593 												aBuffer );
       
   594                             if ( error == KErrNone )
       
   595                                 {
       
   596                                 // If the server is packing, need to take extra care 
       
   597                                 // If the Path is defaulted, defaulted path
       
   598                                 // should not be sent back...
       
   599                                 // for this, set aNoDefaulted to aServer:
       
   600                                 // if server is packing, attribute will be 
       
   601                                 // suppressed
       
   602                                 // if the client is packing, attribute
       
   603                                 // will be transferred normally...
       
   604                                 error = AddStringF( CCookie::EPath,
       
   605 													aCookie,
       
   606 													aBuffer,
       
   607                                                     aServer );
       
   608                                 if ( error == KErrNone )
       
   609                                     {
       
   610                                     // If the server is packing, 
       
   611                                     // need to take extra care 
       
   612                                     // If the Port is defaulted, 
       
   613                                     // defaulted Port
       
   614                                     // should not be sent back...
       
   615                                     // for this, set aNoDefaulted to aServer:
       
   616                                     // if server is packing, attribute will be 
       
   617                                     // suppressed
       
   618                                     // if the client is packing, attribute
       
   619                                     // will be transferred normally...
       
   620                                     error = AddStringF( CCookie::EPort,
       
   621 														aCookie,
       
   622 														aBuffer,
       
   623                                                         aServer );
       
   624                                     if ( error == KErrNone )
       
   625                                         {
       
   626                                         error = AddStringF( CCookie::ESecure,
       
   627 															aCookie,
       
   628 															aBuffer );
       
   629                                         if ( error == KErrNone )
       
   630                                             {
       
   631                                             error =
       
   632 												AddStringF( CCookie::EVersion,
       
   633 															aCookie,
       
   634 															aBuffer );
       
   635                                             if ( error == KErrNone )
       
   636                                                 {
       
   637                                                 error = AddStringF
       
   638 													( CCookie::EExpires,
       
   639 													aCookie,
       
   640 													aBuffer );
       
   641                                                 if ( error == KErrNone )
       
   642                                                     {
       
   643                                                     TRAPD( err, error = AddDateL
       
   644 													    ( aCookie,
       
   645 													    aBuffer ) );
       
   646                                                     if ( err != KErrNone )
       
   647                                                         {
       
   648                                                         error = err;
       
   649                                                         }
       
   650                                                     if ( error == KErrNone )
       
   651                                                         { 
       
   652                                                         // handle 
       
   653                                                         // CCookie::FromCookie2()
       
   654                                                         AppendAttributeLength( 
       
   655                                                             aCookie.FromCookie2(), 
       
   656                                                             aBuffer );
       
   657                                                         }
       
   658                                                     }
       
   659                                                 }
       
   660                                             }
       
   661                                         }
       
   662                                     }
       
   663                                 }
       
   664                             }
       
   665                         }
       
   666                     }
       
   667                 }
       
   668             }
       
   669         }
       
   670 
       
   671 	CLOG( ( EClient, KCookiePackerLogLevel, _L( "<- TCookiePacker::DoPackCookie" ) ) );
       
   672     return error;
       
   673 	}
       
   674 
       
   675 // ---------------------------------------------------------
       
   676 // TCookiePacker::DecreaseNumericValueL
       
   677 // ---------------------------------------------------------
       
   678 //
       
   679 TInt TCookiePacker::DecreaseNumericValueL( TDes& aBuffer, const TInt aIndex ) const
       
   680 {
       
   681     HBufC *nums = HBufC::NewLC( 12 );
       
   682     TPtr numDes( nums->Des() );
       
   683     numDes.Copy( _L("98765432109") );
       
   684     HBufC *midChar = HBufC::NewLC( 2 );
       
   685     TPtr charDes( midChar->Des() );
       
   686     charDes.FillZ( 2 );
       
   687 
       
   688     TInt found = numDes.Length() - 1;
       
   689     TInt i = aIndex + 1;
       
   690     while( (i > 0 ) && ( found == numDes.Length() - 1 ) )
       
   691     {
       
   692         i--;
       
   693         found = numDes.Locate( aBuffer[i] ) + 1;
       
   694         charDes = numDes.Mid( found, 1 );
       
   695         charDes.ZeroTerminate();
       
   696         aBuffer.Replace( i, 1, charDes );
       
   697     }
       
   698 
       
   699     CleanupStack::PopAndDestroy(); // midChar
       
   700     CleanupStack::PopAndDestroy(); // nums
       
   701     return ( (i == 0 ) && ( found == numDes.Length() - 1 ) ) ? 
       
   702         KErrGeneral : KErrNone;
       
   703 }
       
   704