omads/omadsextensions/adapters/bookmark/src/vbookmarkconverter.cpp
changeset 40 b63e67867dcd
equal deleted inserted replaced
39:9905f7d46607 40:b63e67867dcd
       
     1 /*
       
     2 * Copyright (c) 2005-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:  Bookmark object conversion routines
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDES
       
    20 #include <utf.h>
       
    21 #include <favouritesitem.h>
       
    22 #include <feedsserverfolderitem.h>
       
    23 #include "vbookmarkconverter.h"
       
    24 #include "logger.h"
       
    25 
       
    26 // CONSTANTS
       
    27 _LIT8(KVBMKBegin, "BEGIN");
       
    28 _LIT8(KVBMKEnd, "END");
       
    29 _LIT8(KVBMKVbkm, "VBKM");
       
    30 _LIT8(KVBMKEnv, "ENV");
       
    31 _LIT8(KVBMKVersion, "VERSION");         
       
    32 _LIT8(KVBMKVer, "1.0");             
       
    33 _LIT8(KVBMKUrl, "URL");                 
       
    34 _LIT8(KVBMKTitle, "TITLE");     
       
    35 _LIT8(KVBMKXIrmcUrl, "X-IRMC-URL");
       
    36 _LIT8(KVBMKInternetShortcut, "[InternetShortcut]"); 
       
    37 _LIT8(KVBMKPrintable, "QUOTED-PRINTABLE");  
       
    38 _LIT8(KVBMKLinefeed, "\r\n");
       
    39 _LIT8(KVBMKColon, ":");
       
    40 _LIT8(KVBMKAssignment, "=");
       
    41 _LIT8(KVBMKSemicolon, ";");
       
    42 _LIT8(KVBMKNone, "");
       
    43 _LIT(KEmptyString, "");
       
    44 _LIT8(KVBMKCharset, "CHARSET");
       
    45 _LIT8(KVBMKUtf8, "UTF-8");
       
    46 
       
    47 // -----------------------------------------------------------------------------
       
    48 // CVBookmarkConverter::NewL
       
    49 // Two-phased constructor.
       
    50 // -----------------------------------------------------------------------------
       
    51 CVBookmarkConverter* CVBookmarkConverter::NewL()
       
    52     {
       
    53     CVBookmarkConverter* self = CVBookmarkConverter::NewLC();
       
    54     CleanupStack::Pop( self );
       
    55     return self;
       
    56     }
       
    57 
       
    58 // -----------------------------------------------------------------------------
       
    59 // CVBookmarkConverter::NewLC
       
    60 // Two-phased constructor.
       
    61 // -----------------------------------------------------------------------------
       
    62 CVBookmarkConverter* CVBookmarkConverter::NewLC()
       
    63     {
       
    64     CVBookmarkConverter* self = new (ELeave) CVBookmarkConverter();
       
    65     CleanupStack::PushL( self );
       
    66     self->ConstructL();
       
    67     return self;
       
    68     }
       
    69 
       
    70 // -----------------------------------------------------------------------------
       
    71 // CVBookmarkConverter::ConstructL
       
    72 // Symbian 2nd phase constructor can leave.
       
    73 // -----------------------------------------------------------------------------
       
    74 void CVBookmarkConverter::ConstructL()
       
    75     {
       
    76     iVersion = HBufC::NewL(1);
       
    77     iTitle = HBufC::NewL(1);
       
    78     iUrl = HBufC::NewL(1);
       
    79     iInternetShortcut = HBufC::NewL(1);
       
    80     }
       
    81 
       
    82 // -----------------------------------------------------------------------------
       
    83 // CVBookmarkConverter::CVBookmarkConverter
       
    84 // C++ default constructor can NOT contain any code, that might leave
       
    85 // -----------------------------------------------------------------------------
       
    86 CVBookmarkConverter::CVBookmarkConverter()
       
    87     {
       
    88     }
       
    89 
       
    90 // -----------------------------------------------------------------------------
       
    91 // CVBookmarkConverter::~CVBookmarkConverter
       
    92 // Destructor.
       
    93 // -----------------------------------------------------------------------------
       
    94 CVBookmarkConverter::~CVBookmarkConverter()
       
    95     {
       
    96     delete iVersion;
       
    97     delete iUrl;
       
    98     delete iTitle;
       
    99     delete iInternetShortcut;
       
   100     }
       
   101 
       
   102 const TDesC& CVBookmarkConverter::GetVersion() const
       
   103     {
       
   104     return *iVersion;
       
   105     }
       
   106 
       
   107 const TDesC& CVBookmarkConverter::GetUrl() const
       
   108     {
       
   109     return *iUrl;
       
   110     }
       
   111 
       
   112 const TDesC& CVBookmarkConverter::GetTitle() const
       
   113     {
       
   114     return *iTitle;
       
   115     }
       
   116 
       
   117 const TDesC& CVBookmarkConverter::GetInternetShortcut() const
       
   118     {
       
   119     return *iInternetShortcut;
       
   120     }
       
   121 
       
   122 void CVBookmarkConverter::SetVersionL( const TDesC& aVersion )
       
   123     {
       
   124     delete iVersion;
       
   125     iVersion = NULL;
       
   126     iVersion = aVersion.AllocL();
       
   127     }
       
   128     
       
   129 void CVBookmarkConverter::SetVersionL( const TDesC8& aVersion )
       
   130     {
       
   131     delete iVersion;
       
   132     iVersion = NULL;
       
   133     iVersion = CnvUtfConverter::ConvertToUnicodeFromUtf8L( aVersion );  
       
   134     }   
       
   135     
       
   136 void CVBookmarkConverter::SetUrlL( const TDesC& aUrl )
       
   137     {
       
   138     delete iUrl;
       
   139     iUrl = NULL;
       
   140     iUrl = aUrl.AllocL();
       
   141     }
       
   142     
       
   143 void CVBookmarkConverter::SetUrlL( const TDesC8& aUrl )
       
   144     {
       
   145     delete iUrl;
       
   146     iUrl = NULL;
       
   147     iUrl = CnvUtfConverter::ConvertToUnicodeFromUtf8L( aUrl );      
       
   148     }   
       
   149     
       
   150 void CVBookmarkConverter::SetTitleL( const TDesC& aTitle )
       
   151     {
       
   152     delete iTitle;
       
   153     iTitle = NULL;
       
   154     iTitle = aTitle.AllocL();
       
   155     }
       
   156         
       
   157 void CVBookmarkConverter::SetTitleL( const TDesC8& aTitle, TBookmarkEncoding aEncoding )
       
   158     {
       
   159     delete iTitle;
       
   160     iTitle = NULL;
       
   161     
       
   162     if ( aEncoding == EQuotedPrintable )
       
   163         {
       
   164         HBufC8* decodedData = DecodeQuotedPrintableLC( aTitle );
       
   165         iTitle = CnvUtfConverter::ConvertToUnicodeFromUtf8L( *decodedData );
       
   166         CleanupStack::PopAndDestroy( decodedData );
       
   167         }
       
   168     else
       
   169         {
       
   170         iTitle = CnvUtfConverter::ConvertToUnicodeFromUtf8L( aTitle );
       
   171         }        
       
   172     }
       
   173     
       
   174 HBufC8* CVBookmarkConverter::DecodeQuotedPrintableLC( const TDesC8& aEncodedData )
       
   175     {
       
   176     TInt encodedLength = aEncodedData.Length();
       
   177     
       
   178     HBufC8* decodeBuffer = HBufC8::NewLC( encodedLength );
       
   179     TPtr8 ptrDecodeBuffer = decodeBuffer->Des();
       
   180     
       
   181     TInt i(0);
       
   182     while ( i < encodedLength )
       
   183         {
       
   184         TChar nextChar = aEncodedData[i++];
       
   185         
       
   186         if ( nextChar == '=' )
       
   187             {
       
   188             if ( i + 2 > encodedLength )
       
   189                 {
       
   190                 ptrDecodeBuffer.Append( '=' );
       
   191                 if ( i + 1 == encodedLength )
       
   192                     {
       
   193                     ptrDecodeBuffer.Append( aEncodedData[i++] );
       
   194                     }     
       
   195                 }
       
   196             else
       
   197                 {
       
   198                 TPtrC8 data = aEncodedData.Mid( i, 2 );
       
   199                 i += 2;    
       
   200                 
       
   201                 if ( data.Compare(KVBMKLinefeed) == 0 )
       
   202                     {
       
   203                     // Do nothing
       
   204                     // '=' at the end of line is soft line break, not to be decoded
       
   205                     }
       
   206                 else
       
   207                     {
       
   208                     TLex8 hexChar( data );
       
   209                     TUint8 value( 0 );
       
   210                     
       
   211                     if ( hexChar.Val( value, EHex ) == KErrNone )
       
   212                         {
       
   213                         ptrDecodeBuffer.Append( TChar( value ) );
       
   214                         }
       
   215                     else
       
   216                         {
       
   217                         // Decoding failed, put the data at itself
       
   218                         ptrDecodeBuffer.Append( '=' );
       
   219                         ptrDecodeBuffer.Append( data );
       
   220                         }    
       
   221                     }
       
   222                 }
       
   223             }
       
   224         else
       
   225             {
       
   226             ptrDecodeBuffer.Append( nextChar );
       
   227             }    
       
   228         }
       
   229         
       
   230     return decodeBuffer;    
       
   231     }
       
   232 
       
   233 void CVBookmarkConverter::SetInternetShortcutL( const TDesC& aInternetShortcut )
       
   234     {
       
   235     delete iInternetShortcut;
       
   236     iInternetShortcut = NULL;
       
   237     iInternetShortcut = aInternetShortcut.AllocL();
       
   238     }
       
   239     
       
   240 void CVBookmarkConverter::SetInternetShortcutL( const TDesC8& aInternetShortcut )
       
   241     {
       
   242     delete iInternetShortcut;
       
   243     iInternetShortcut = NULL;
       
   244     iInternetShortcut = CnvUtfConverter::ConvertToUnicodeFromUtf8L( aInternetShortcut );        
       
   245     }   
       
   246 
       
   247 void CVBookmarkConverter::ExportDbItemL( CFavouritesItem& aItem )
       
   248     {
       
   249     if ( iTitle->Des().Length() > KFavouritesMaxName )
       
   250         {
       
   251         TPtrC title = iTitle->Des().Left( KFavouritesMaxName );
       
   252         aItem.SetNameL( title );
       
   253         }
       
   254     else
       
   255         {
       
   256         aItem.SetNameL( *iTitle );
       
   257         }
       
   258         
       
   259     if ( iUrl->Des().Length() > KFavouritesMaxUrl )
       
   260         {
       
   261         TPtrC url = iUrl->Des().Left( KFavouritesMaxUrl );
       
   262         aItem.SetUrlL( url );
       
   263         }
       
   264     else
       
   265         {
       
   266         aItem.SetUrlL( *iUrl );
       
   267         }   
       
   268     }
       
   269 
       
   270 void CVBookmarkConverter::ImportDbItemL( const CFavouritesItem& aItem )
       
   271     {
       
   272     ResetL();
       
   273     
       
   274     if( aItem.Type() != CFavouritesItem::EItem )
       
   275         {
       
   276         User::Leave( KErrNotSupported );
       
   277         }
       
   278     
       
   279     SetVersionL( KVBMKVer );
       
   280     SetUrlL( aItem.Url() );
       
   281     SetInternetShortcutL( aItem.Url() );
       
   282     SetTitleL( aItem.Name() );
       
   283     }
       
   284 
       
   285 void CVBookmarkConverter::ImportDbItemL( const CFolderItem& aItem )
       
   286     {
       
   287     ResetL();
       
   288     
       
   289     if( aItem.IsFolder() )
       
   290         {
       
   291         User::Leave( KErrNotSupported );
       
   292         }
       
   293     
       
   294     SetVersionL( KVBMKVer );
       
   295     SetUrlL( aItem.SourceUrl() );
       
   296     SetInternetShortcutL( aItem.SourceUrl() );
       
   297     SetTitleL( aItem.Name() );
       
   298     }
       
   299 
       
   300 void CVBookmarkConverter::ExportVBookmarkL( CBufBase& aBuffer )
       
   301     {
       
   302     LOGGER_ENTERFN( "CVBookmarkConverter::ExportVBookmarkL" );
       
   303     
       
   304     iDesc = NULL;
       
   305     iBuffer = &aBuffer;
       
   306     iWriteBufPosition = 0;
       
   307     iWriteBufSize = aBuffer.Size();     
       
   308     
       
   309     ExportL();  
       
   310     iBuffer->ResizeL( iWriteBufPosition );    
       
   311     
       
   312     LOGGER_LEAVEFN( "CVBookmarkConverter::ExportVBookmarkL" );
       
   313     }
       
   314 
       
   315 void CVBookmarkConverter::ExportVBookmarkL( TDes8& aBuffer )
       
   316     {
       
   317     iDesc = &aBuffer;
       
   318     iBuffer = NULL;
       
   319     
       
   320     ExportL();
       
   321     }
       
   322 
       
   323 void CVBookmarkConverter::ResetL()
       
   324     {
       
   325     SetVersionL( KEmptyString );
       
   326     SetUrlL( KEmptyString );
       
   327     SetTitleL( KEmptyString );    
       
   328     SetInternetShortcutL( KEmptyString );    
       
   329     }
       
   330     
       
   331 void CVBookmarkConverter::ExportL()
       
   332     {
       
   333     LOGGER_ENTERFN( "CVBookmarkConverter::ExportL" );
       
   334     
       
   335     WriteMessageLineL( KVBMKBegin, KVBMKVbkm, KVBMKColon ); // Begin tag
       
   336     
       
   337     HBufC8* version = CnvUtfConverter::ConvertFromUnicodeToUtf8L( *iVersion );
       
   338     CleanupStack::PushL( version );
       
   339     WriteMessageLineL( KVBMKVersion, *version, KVBMKColon ); // Version
       
   340     CleanupStack::PopAndDestroy( version );
       
   341     
       
   342     HBufC8* url = CnvUtfConverter::ConvertFromUnicodeToUtf8L( *iUrl );
       
   343     CleanupStack::PushL( url );
       
   344     // Url
       
   345     WriteL( KVBMKUrl );
       
   346     WriteL( KVBMKSemicolon );
       
   347     WriteL( KVBMKCharset );
       
   348     WriteL( KVBMKAssignment );
       
   349     WriteL( KVBMKUtf8 );
       
   350     WriteL( KVBMKColon );
       
   351     WriteL( *url );
       
   352     WriteL( KVBMKLinefeed );
       
   353     CleanupStack::PopAndDestroy( url );
       
   354     
       
   355     HBufC8* title = CnvUtfConverter::ConvertFromUnicodeToUtf8L( *iTitle );
       
   356     CleanupStack::PushL( title );
       
   357     // Title
       
   358     WriteL( KVBMKTitle );
       
   359     WriteL( KVBMKSemicolon );
       
   360     WriteL( KVBMKCharset );
       
   361     WriteL( KVBMKAssignment );
       
   362     WriteL( KVBMKUtf8 );
       
   363     WriteL( KVBMKColon );
       
   364     WriteL( *title );
       
   365     WriteL( KVBMKLinefeed );
       
   366     CleanupStack::PopAndDestroy( title );          
       
   367 
       
   368     if( iInternetShortcut->Length() > 0 )
       
   369         {
       
   370         WriteEnvelopeL();
       
   371         }
       
   372         
       
   373     WriteMessageLineL( KVBMKEnd, KVBMKVbkm, KVBMKColon ); // End tag
       
   374     
       
   375     LOGGER_LEAVEFN( "CVBookmarkConverter::ExportL" );       
       
   376     }
       
   377     
       
   378 TInt CVBookmarkConverter::ImportVBookmarkL( const TDesC8& aBuffer )
       
   379     {
       
   380     LOGGER_ENTERFN( "CVBookmarkConverter::ImportVBookmarkL" );
       
   381     
       
   382     ResetL();
       
   383         
       
   384     TInt error = KErrNone;
       
   385     TInt position = 0;
       
   386     TPtrC8 tag;
       
   387     TPtrC8 value;
       
   388     TPtrC8 properties;
       
   389     error = ReadTagAndValue( aBuffer, position, tag, value, properties );
       
   390     if( error != KErrNone )
       
   391         {
       
   392         LOGGER_WRITE_1( "ReadTagAndValue err: %d", error );
       
   393         return error;
       
   394         }
       
   395         
       
   396     if ( ( tag != KVBMKBegin ) || ( value != KVBMKVbkm ) )
       
   397         {
       
   398         LOGGER_WRITE( "Invalid tag" );
       
   399         return KErrNotFound;
       
   400         }
       
   401     
       
   402     while ( ( error = ReadTagAndValue( aBuffer, position, tag, value, properties ) ) == KErrNone )
       
   403         {
       
   404         // Version
       
   405         if ( tag == KVBMKVersion )
       
   406             {
       
   407             SetVersionL( value );
       
   408             }
       
   409         
       
   410         // Url
       
   411         else if ( tag == KVBMKUrl )
       
   412             {
       
   413             SetUrlL( value );
       
   414             }
       
   415         
       
   416         // Title
       
   417         else if ( tag == KVBMKTitle )
       
   418             {
       
   419             TBookmarkEncoding encoding = Encoding( properties );
       
   420             SetTitleL( value, encoding );
       
   421             }
       
   422             
       
   423         // Beginning of envelope    
       
   424         else if ( ( tag == KVBMKBegin ) && ( value == KVBMKEnv ) )
       
   425             {
       
   426             // Read the envelope, quit if error
       
   427             error = ReadEnvelopeL( aBuffer, position );
       
   428             if( error != KErrNone )
       
   429                 {
       
   430                 return error;
       
   431                 }
       
   432             }       
       
   433                 
       
   434         // End of Bookmark
       
   435         else if ( ( tag == KVBMKEnd ) && ( value == KVBMKVbkm ) )
       
   436             {
       
   437             return error;
       
   438             }
       
   439         
       
   440         else
       
   441             {
       
   442             // Unknown data, skip
       
   443             }
       
   444         }
       
   445 
       
   446     LOGGER_LEAVEFN( "CVBookmarkConverter::ImportVBookmarkL" );      
       
   447     return error;
       
   448     }
       
   449 
       
   450 void CVBookmarkConverter::WriteMessageLineL( const TDesC8& aMsgLineTag,
       
   451     const TDesC8& aMsgLineData, const TDesC8& aSeparator )
       
   452     {
       
   453     WriteL( aMsgLineTag );
       
   454     WriteL( aSeparator );
       
   455     WriteL( aMsgLineData );
       
   456     WriteL( KVBMKLinefeed );
       
   457     }
       
   458 
       
   459 TInt CVBookmarkConverter::ReadTagAndValue( const TDesC8& aBuffer, TInt& aPosition, 
       
   460     TPtrC8& aTag, TPtrC8& aValue, TPtrC8& aProperties )
       
   461     {
       
   462     LOGGER_ENTERFN( "CVBookmarkConverter::ReadTagAndValue" );   
       
   463     
       
   464     TPtrC8 start = aBuffer.Mid( aPosition );
       
   465     TInt delimeter = start.Find( KVBMKColon );
       
   466     TInt linefeed = start.Find( KVBMKLinefeed );
       
   467     TInt semicolon = start.Find( KVBMKSemicolon );
       
   468     
       
   469     
       
   470     // Did we find a linefeed?
       
   471     if ( linefeed == KErrNotFound )
       
   472         {
       
   473         // Check whether file ends without newline
       
   474         if( aBuffer.Length() <= ( aPosition + start.Length() ) )
       
   475             {
       
   476             // Set linefeed at the end of the file
       
   477             linefeed = start.Length();
       
   478             }
       
   479         else
       
   480             { 
       
   481             return KErrNotFound;
       
   482             }
       
   483         }
       
   484 
       
   485     // Did we find a semicolon?
       
   486     if ( semicolon != KErrNotFound )
       
   487         {
       
   488         // It must be before the delimeter (property identifiers reside in this block)
       
   489         if ( semicolon >= delimeter || semicolon < 0 )
       
   490             {
       
   491             semicolon = KErrNotFound;
       
   492             }
       
   493         }
       
   494     
       
   495     // Did we find the delimeter
       
   496     if( delimeter == KErrNotFound )
       
   497         {
       
   498         return KErrNotFound;
       
   499         }
       
   500 
       
   501     // Linefeed must reside behind the delimeter
       
   502     if ( linefeed <= delimeter )
       
   503         {
       
   504         return KErrNotFound;
       
   505         }
       
   506     
       
   507     aTag.Set( start.Left( semicolon != KErrNotFound ? semicolon : delimeter ) );
       
   508     IgnoreSpaces( aTag );
       
   509 
       
   510     // Extract value
       
   511     aValue.Set( start.Mid( delimeter + 1, (linefeed - 1) - delimeter ) );
       
   512     IgnoreSpaces( aValue );
       
   513     
       
   514     // Extract properties if found
       
   515     if ( semicolon != KErrNotFound )
       
   516         {
       
   517         aProperties.Set( start.Mid( semicolon, delimeter - semicolon ) );
       
   518         IgnoreSpaces( aProperties );
       
   519         }
       
   520     else
       
   521         {
       
   522         aProperties.Set( KVBMKNone() );
       
   523         }     
       
   524     
       
   525     // update position
       
   526     aPosition += ( linefeed + KVBMKLinefeed().Length() );
       
   527     
       
   528     LOGGER_LEAVEFN( "CVBookmarkConverter::ReadTagAndValue" );       
       
   529     return KErrNone;
       
   530     }
       
   531     
       
   532 TInt CVBookmarkConverter::ReadEnvelopeL( const TDesC8& aBuffer, TInt& aPosition )
       
   533     {
       
   534     LOGGER_ENTERFN( "CVBookmarkConverter::ReadEnvelopeL" ); 
       
   535         
       
   536     TInt error = KErrNone;
       
   537     TPtrC8 tag;
       
   538     TPtrC8 value;
       
   539     TPtrC8 properties;
       
   540 
       
   541     while ( ( error = ReadTagAndValue( aBuffer, aPosition, tag, value, properties ) ) == KErrNone )
       
   542         {
       
   543         // End of Bookmark
       
   544         if ( tag == KVBMKXIrmcUrl )
       
   545             {
       
   546             error = ReadAssignment( aBuffer, aPosition, tag, value );
       
   547             if ( error != KErrNone )
       
   548                 {
       
   549                 return error;
       
   550                 }
       
   551                 
       
   552             if ( tag == KVBMKInternetShortcut )
       
   553                 {
       
   554                 error = ReadAssignment( aBuffer, aPosition, tag, value );
       
   555                 if( error != KErrNone )
       
   556                     {
       
   557                     return error;
       
   558                     }
       
   559                 
       
   560                 if ( tag == KVBMKUrl )
       
   561                     {
       
   562                     SetInternetShortcutL( value );
       
   563                     }
       
   564                 else
       
   565                     {
       
   566                     return KErrNotFound;
       
   567                     }               
       
   568                 }
       
   569             else
       
   570                 {
       
   571                 return KErrNotFound;
       
   572                 }
       
   573             }
       
   574         
       
   575         else if ( ( tag == KVBMKEnd ) && ( value == KVBMKEnv ) )
       
   576             {
       
   577             return error;
       
   578             }
       
   579         else
       
   580             {
       
   581             // Unknown data, skip
       
   582             }
       
   583         }
       
   584 
       
   585     LOGGER_LEAVEFN( "CVBookmarkConverter::ReadEnvelopeL" );         
       
   586     return error;
       
   587     }
       
   588 
       
   589 TInt CVBookmarkConverter::ReadAssignment( const TDesC8& aBuffer,
       
   590     TInt& aPosition, TPtrC8& aTag, TPtrC8& aValue )
       
   591     {
       
   592     LOGGER_ENTERFN( "CVBookmarkConverter::ReadAssignment" );    
       
   593         
       
   594     TPtrC8 start = aBuffer.Mid( aPosition );
       
   595     TInt assignment = start.Find( KVBMKAssignment );
       
   596     TInt linefeed = start.Find( KVBMKLinefeed );
       
   597     
       
   598     // Did we find the delimeter and the linefeed
       
   599     if ( ( assignment == KErrNotFound) || ( linefeed == KErrNotFound ) )
       
   600         {
       
   601         return KErrNotFound;
       
   602         }
       
   603     // Linefeed must reside behind the delimeter
       
   604     if ( linefeed <= assignment )
       
   605         {
       
   606         return KErrNotFound;
       
   607         }
       
   608     // Extract tag
       
   609     aTag.Set( start.Left( assignment ) );
       
   610     IgnoreSpaces( aTag );
       
   611 
       
   612     // Extract value
       
   613     aValue.Set( start.Mid( assignment + 1, ( linefeed - 1 ) - assignment ) );
       
   614     IgnoreSpaces( aValue );
       
   615     
       
   616     // update position
       
   617     aPosition += ( linefeed + KVBMKLinefeed().Length() );
       
   618 
       
   619     LOGGER_LEAVEFN( "CVBookmarkConverter::ReadAssignment" );        
       
   620     return KErrNone;
       
   621     }
       
   622 
       
   623 void CVBookmarkConverter::WriteEnvelopeL()
       
   624     {
       
   625     WriteMessageLineL( KVBMKBegin, KVBMKEnv, KVBMKColon ); // Begin tag
       
   626 
       
   627     // "X-IRMC-URL;QUOTED-PRINTABLE:="
       
   628     WriteL( KVBMKXIrmcUrl );
       
   629     WriteL( KVBMKSemicolon );
       
   630     WriteL( KVBMKPrintable );
       
   631     WriteL( KVBMKColon );
       
   632     WriteL( KVBMKAssignment );
       
   633     WriteL( KVBMKLinefeed );
       
   634     
       
   635     WriteMessageLineL( KVBMKInternetShortcut, KVBMKNone, KVBMKAssignment );
       
   636     
       
   637     HBufC8* internetShortcut = CnvUtfConverter::ConvertFromUnicodeToUtf8L( *iInternetShortcut );
       
   638     CleanupStack::PushL( internetShortcut );
       
   639     WriteMessageLineL( KVBMKUrl, *internetShortcut, KVBMKAssignment );
       
   640     CleanupStack::PopAndDestroy( internetShortcut );
       
   641     
       
   642     WriteMessageLineL( KVBMKEnd, KVBMKEnv, KVBMKColon ); // End tag
       
   643     }
       
   644     
       
   645 void CVBookmarkConverter::WriteL( const TDesC8 &aData )
       
   646     {
       
   647     if ( iBuffer )
       
   648         {
       
   649         TInt newPosition = iWriteBufPosition + aData.Length();
       
   650 
       
   651         if ( newPosition > iWriteBufSize )
       
   652             {
       
   653             TInt expandStep = newPosition - iWriteBufSize + 100;
       
   654             iBuffer->ExpandL( iWriteBufSize, expandStep );
       
   655             iWriteBufSize += expandStep;
       
   656             }
       
   657 
       
   658         iBuffer->Write( iWriteBufPosition, aData );
       
   659         iWriteBufPosition = newPosition;
       
   660         }
       
   661     else if( iDesc )
       
   662         {
       
   663         iDesc->Append( aData );       
       
   664         }
       
   665     }
       
   666     
       
   667 void CVBookmarkConverter::IgnoreSpaces( TPtrC8& aData )
       
   668     {
       
   669     TInt last = aData.Length() - 1;
       
   670     
       
   671     TInt begin;
       
   672     for ( begin = 0; begin <= last; begin++ )
       
   673         {
       
   674         if ( !TChar( aData[begin] ).IsSpace() )
       
   675             {
       
   676             break;
       
   677             }
       
   678         }
       
   679         
       
   680     TInt end;   
       
   681     for ( end = last; end >= 0; end-- )
       
   682         {
       
   683         if ( !TChar( aData[end] ).IsSpace() )
       
   684             {
       
   685             break;
       
   686             }
       
   687         }
       
   688         
       
   689     TInt length = end - begin + 1;  
       
   690                 
       
   691     if ( ( begin != 0 || end != last ) && length > 0 )
       
   692         {
       
   693         TPtrC8 newData = aData.Mid( begin, length );
       
   694         aData.Set( newData );
       
   695         }
       
   696     }
       
   697     
       
   698 TBookmarkEncoding CVBookmarkConverter::Encoding( TPtrC8& aProperties )
       
   699     {
       
   700     TBookmarkEncoding encoding = ENoEncoding;
       
   701     
       
   702     TInt length = aProperties.Length();
       
   703     
       
   704     if ( aProperties.Length() > 0 )
       
   705         {
       
   706         if ( aProperties.Find( KVBMKPrintable ) > 0 )
       
   707             {
       
   708             encoding = EQuotedPrintable;
       
   709             }    
       
   710         }
       
   711     
       
   712     return encoding;
       
   713     }