commsfwsupport/commselements/MsgParser/include/RecordItem.h
changeset 0 dfb7c4ff071f
child 43 d65d023db13c
equal deleted inserted replaced
-1:000000000000 0:dfb7c4ff071f
       
     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 // THIS API IS INTERNAL TO NETWORKING AND IS SUBJECT TO CHANGE AND NOT FOR EXTERNAL USE
       
    15 // Offers a tool to declare message structure as a class and parse/compose the message
       
    16 // from/into a descriptor. The design assumes byte addressing (byte == octet)
       
    17 // Overall idea
       
    18 // Data buffer => maps to a structure of items each linked to the next one.
       
    19 // The first item is pointed to by the class TRecord
       
    20 // |                        Data Buffer                                                 |
       
    21 // |     an Item<THEADER> 1       |  2 |             3         |          N             |
       
    22 // |Header|       Body            |
       
    23 // | +-> Constant of length 0 bytes             => constant length payload (class TConstant)
       
    24 // +---> Value of length 1 - sizeof(TInt) bytes => variable length payload (class TValue)
       
    25 // <LAYOUT>
       
    26 // V          V
       
    27 // Big Endian          Little Endian
       
    28 // (class TBigEndian)   (class TLittleEndian)
       
    29 // class TRecord uses its member iFirst(pointing to the first CBaseItem in the structure)
       
    30 // to process all items in the structure
       
    31 // The solution is not thread safe
       
    32 // 
       
    33 //
       
    34 
       
    35 /**
       
    36  @file
       
    37  @internalTechnology
       
    38  @code
       
    39  @endcode
       
    40 */
       
    41 
       
    42 #include <e32base.h>
       
    43 #include <comms-infras/commsdebugutility.h>
       
    44 
       
    45 #ifndef _RECORDITEM_H_
       
    46 #define _RECORDITEM_H_
       
    47 
       
    48 #ifdef _DEBUG
       
    49 // Panic category for "absolutely impossible!" vanilla ASSERT()-type panics from this module
       
    50 // (if it could happen through user error then you should give it an explicit, documented, category + code)
       
    51 _LIT(KSpecAssert_ElemMsgParserRcr, "ElemMsgParserRcr");
       
    52 #endif
       
    53 
       
    54 /**
       
    55  A template parameter for TValue<>; it sets/gets a
       
    56  value into/from a buffer as a big endian of length 0 - sizeof(TInt)
       
    57  @see TValue<>
       
    58  @internalTechnology
       
    59 **/
       
    60 class TBigEndian
       
    61 {
       
    62 public:
       
    63    TBigEndian() {};
       
    64 
       
    65    IMPORT_C static TInt GetValue( const TUint8 *aPtr, TInt aValueLength );
       
    66    IMPORT_C static void SetValue( TUint8 *aPtr, TInt aValueLength, TInt aValue );
       
    67 };
       
    68 
       
    69 /**
       
    70  A template parameter for TValue<>; it sets/gets a
       
    71  value into/from a buffer as a little endian of length 0 - sizeof(TInt)
       
    72  @see TValue<>
       
    73  @internalTechnology
       
    74  **/
       
    75 class TLittleEndian
       
    76 {
       
    77 public:
       
    78    TLittleEndian() {};
       
    79 
       
    80    IMPORT_C static TInt GetValue( const TUint8* aPtr, TInt aValueLength );
       
    81    IMPORT_C static void SetValue( TUint8 *aPtr, TInt aValueLength, TInt aValue );
       
    82 };
       
    83 
       
    84 /**
       
    85  A template parameter to CItem<>; it sets/gets a
       
    86  value into/from a buffer as a little/big endian depending on the template parameter.
       
    87 
       
    88  Also, it keeps the value length and the initial value.
       
    89  @see CItem<>
       
    90  @see TLittleEndian
       
    91  @see TBigEndian
       
    92  @internalTechnology
       
    93 **/
       
    94 template < class LAYOUT >
       
    95 class TValue
       
    96 {
       
    97 public:
       
    98    TValue( TInt aValueLength ) :
       
    99       iValueLength( aValueLength )
       
   100    {
       
   101    }
       
   102 
       
   103    /**
       
   104     * Gets the length of the value in bytes(octets)
       
   105     *
       
   106     * @return The value length
       
   107     */
       
   108    TInt GetValueLength() const
       
   109    {
       
   110       return iValueLength;
       
   111    }
       
   112 
       
   113    /**
       
   114     * Sets the value length in bytes(octets)
       
   115     *
       
   116     * @param aValueLength initial value
       
   117     */
       
   118    void SetValueLength( TInt aValueLength )
       
   119    {
       
   120       iValueLength = aValueLength;
       
   121    }
       
   122 
       
   123    /**
       
   124     * Gets the initial value
       
   125     *
       
   126     * @return The initial value
       
   127     */
       
   128    TInt GetInitialValue() const
       
   129    {
       
   130       return iInitialValue;
       
   131    }
       
   132 
       
   133    /**
       
   134     * Sets the initial value
       
   135     *
       
   136     * @param aInitialValue The initial value
       
   137     */
       
   138    void SetInitialValue( TInt aInitialValue )
       
   139    {
       
   140       iInitialValue = aInitialValue;
       
   141    }
       
   142 
       
   143 protected:
       
   144    TInt GetValue( const TUint8* aPtr ) const;
       
   145    void SetValue( TUint8* aPtr8, TInt aValue ) const;
       
   146 
       
   147 protected:
       
   148    TInt iValueLength;
       
   149    TInt iInitialValue;
       
   150 };
       
   151 
       
   152 /**
       
   153  A template parameter to CItem<> to create an item with
       
   154  a header of length 1 - sizeof(TInt) and with a big endian layout.
       
   155  @see CItem<>
       
   156  @see TBigEndian
       
   157  @internalTechnology
       
   158 **/
       
   159 class TValueBigEndian : public TValue<TBigEndian>
       
   160 {
       
   161 public:
       
   162    TValueBigEndian( TInt aValueLength ) :
       
   163       TValue<TBigEndian>( aValueLength )
       
   164       {
       
   165       }
       
   166 
       
   167    IMPORT_C TInt GetValue( const TUint8* aPtr ) const;
       
   168    IMPORT_C void SetValue( TUint8* aPtr8, TInt aValue ) const;
       
   169 };
       
   170 
       
   171 /**
       
   172  A template parameter to CItem<> to create an item with
       
   173  a header of length 1 - sizeof(TInt) and with a little endian layout.
       
   174  @see CItem<>
       
   175  @see TLittleEndian
       
   176  @internalTechnology
       
   177 **/
       
   178 class TValueLittleEndian : public TValue<TLittleEndian>
       
   179 {
       
   180 public:
       
   181    TValueLittleEndian( TInt aValueLength ) :
       
   182       TValue<TLittleEndian>( aValueLength )
       
   183       {
       
   184       }
       
   185 
       
   186    IMPORT_C TInt GetValue( const TUint8* aPtr ) const;
       
   187    IMPORT_C void SetValue( TUint8* aPtr8, TInt aValue ) const;
       
   188 };
       
   189 
       
   190 /**
       
   191  A template parameter to CItem<>
       
   192  in the case that the item has constant length (no header).
       
   193 
       
   194  It keeps the length of the item
       
   195  @see CItem<>
       
   196  @internalTechnology
       
   197 **/
       
   198 class TConstant
       
   199 {
       
   200 public:
       
   201    TConstant( TInt aValue ) :
       
   202       iValue( aValue )
       
   203    {
       
   204    }
       
   205 
       
   206    /**
       
   207     * Gets the value from the data buffer.
       
   208 
       
   209     * For constant length items, there is no
       
   210     * data buffer and the value is given by iValue.
       
   211     *
       
   212     * @see TValue::GetValue()
       
   213     * param not used
       
   214     * @return iValue
       
   215     */
       
   216    TInt GetValue( const TUint8* ) const
       
   217    {
       
   218       return iValue;
       
   219    }
       
   220 
       
   221    /**
       
   222     * Gets the length of the value in bytes(octets)
       
   223     *
       
   224     * @return 0
       
   225     */
       
   226    TInt GetValueLength() const
       
   227    {
       
   228       return 0;
       
   229    }
       
   230 
       
   231    /**
       
   232     * Sets the value length in bytes(octets)
       
   233     *
       
   234     * param not used - constant value has length 0
       
   235     */
       
   236    void SetValueLength( TInt /*aValueLength*/ )
       
   237    {
       
   238    }
       
   239 
       
   240    /**
       
   241     * Sets the value into the data buffer.
       
   242 
       
   243     * For constant length items, there is no
       
   244     * data buffer and the value is given by iValue => function does nothing.
       
   245     *
       
   246     * @see TValue::SetValue()
       
   247     * param not used
       
   248     */
       
   249    void SetValue( TUint8*, TInt ) const
       
   250    {
       
   251    }
       
   252 
       
   253    /**
       
   254     * Gets the initial value
       
   255     *
       
   256     * @return The initial value == iValue
       
   257     */
       
   258    TInt GetInitialValue() const
       
   259    {
       
   260       return iValue;
       
   261    }
       
   262 
       
   263 protected:
       
   264    const TInt iValue;
       
   265 };
       
   266 
       
   267 /**
       
   268  A base class for a buffer item represented by CItem<>, which derives from it.
       
   269 
       
   270  It keeps a pointer to the beginning of the data belonging to the item and points to
       
   271  the next CItemBase object. It provides basic functions for the item.
       
   272  @see CItem<>
       
   273  @internalTechnology
       
   274   @version 0.01
       
   275  @date	12/11/2003
       
   276 **/
       
   277 class CItemBase : public CBase
       
   278 {
       
   279 public:
       
   280    CItemBase( CItemBase* aNext ) :
       
   281       iNext( aNext )
       
   282    {
       
   283    }
       
   284 
       
   285    virtual void Dump( const TDesC& aTag, const TDesC& aFile ) = 0;
       
   286    virtual void ParseL( TPtr8& aDes8 ) = 0;
       
   287    virtual void InitialiseL( TPtr8& aBuf8 ) = 0;  //buffer must be initialised beforehand
       
   288    virtual TInt CalcTotalInitialiseLength() const = 0;
       
   289 
       
   290    /**
       
   291     * Sets the iPtr8 to point to the beginning of the descriptor
       
   292     *
       
   293     * @param aDes8 An 8 bit non-modifiable descriptor representing the item's data
       
   294     */
       
   295    void SetPtr( TDesC8& aDes8 )
       
   296    {
       
   297       iPtr8 = (TUint8*)aDes8.Ptr();
       
   298    }
       
   299 
       
   300    /**
       
   301     * Returns a pointer to the beginning of the item data
       
   302     *
       
   303     * @return iPtr8 a pointer to an 8-bit unsigned integer representing the item data
       
   304     */
       
   305    TUint8* Ptr() const
       
   306    {
       
   307       return iPtr8;
       
   308    }
       
   309 
       
   310 public:
       
   311    CItemBase* iNext;
       
   312 
       
   313 protected:
       
   314    IMPORT_C void SetBody( const TDesC8& aDes8, TInt aHeaderLength );
       
   315    IMPORT_C void InitialiseL( TPtr8& aBuf8, TInt aInitialLength, TInt aHeaderLength );
       
   316    IMPORT_C void ParseL( TPtr8& aDes8, TInt aLength, TInt aHeaderLength );
       
   317    IMPORT_C void CopyBodyToL( HBufC8*& aBuf8, TInt aLength, TInt aHeaderLength );
       
   318 
       
   319 protected:
       
   320    TUint8* iPtr8; //ptr to part of record belonging to the item
       
   321 };
       
   322 
       
   323 /**
       
   324  Represents an item having header and payload.
       
   325 
       
   326  It offers functions to manipulate the item data.
       
   327  @see TValue
       
   328  @see TConstant
       
   329  @internalTechnology
       
   330 **/
       
   331 template <class THEADER>
       
   332 class CItem : public CItemBase
       
   333 {
       
   334 public:
       
   335    CItem( CItemBase* aNext, TInt aValue ) :
       
   336       CItemBase( aNext ),
       
   337       iHeader( aValue )
       
   338    {
       
   339    }
       
   340    virtual void InitialiseL( TPtr8& aBuf8 ); //buffer must be initialised beforehand
       
   341    virtual void ParseL( TPtr8& aDes8 );
       
   342    virtual TInt CalcTotalInitialiseLength() const;
       
   343 
       
   344    void SetLength(); //assumes there is enough space for the header
       
   345    TInt GetLength() const; //from the item header (must be initialised || parsed)
       
   346    TInt GetItemLength() const; //from the item header (must be initialised || parsed) + header length
       
   347    TInt GetHeaderLength() const;
       
   348    TUint8* GetBodyPtr() const;
       
   349    TPtr8 GetBodyDes() const;
       
   350    TPtr8 GetItemDes() const;
       
   351    void SetBody( const TDesC8& aDes8 );
       
   352    void CopyBodyToL( HBufC8*& aBuf8 );
       
   353 
       
   354    //the number is considered to have as many bytes as GetLengthL() value
       
   355    void SetBigEndian( TUint32 aUint );
       
   356    TUint32 GetBigEndian() const;
       
   357    void SetLittleEndian( TUint32 aUint );
       
   358    TUint32 GetLittleEndian() const;
       
   359 
       
   360    THEADER& Header();
       
   361 
       
   362    virtual void Dump( const TDesC& aTag, const TDesC& aFile );
       
   363 public:
       
   364    TBuf<16> iName;
       
   365 
       
   366 
       
   367 private:
       
   368    THEADER iHeader;
       
   369 };
       
   370 
       
   371 /**
       
   372  * Returns a reference to a header class
       
   373  *
       
   374  * @return iHeader (type is template parameter dependent)
       
   375  */
       
   376 template <class THEADER>
       
   377 inline THEADER& CItem<THEADER>::Header()
       
   378 {
       
   379    return iHeader;
       
   380 }
       
   381 
       
   382 template <class THEADER>
       
   383 inline void CItem<THEADER>::SetLength()
       
   384 /**
       
   385  * Sets the initial item length into the item data buffer.
       
   386 
       
   387  * The function assumes there is enough space for the header which
       
   388  * implies that the item must be parsed or initialised
       
   389  *
       
   390  */
       
   391 {
       
   392    iHeader.SetValue( iPtr8, iHeader.GetInitialValue() );
       
   393 }
       
   394 
       
   395 template <class THEADER>
       
   396 inline TInt CItem<THEADER>::GetLength() const
       
   397 /**
       
   398  * Gets the item length from the item data buffer.
       
   399 
       
   400  * The function assumes there is enough space for the header which
       
   401  * implies that the item must be parsed or initialised
       
   402  *
       
   403  * @return the length of the item body
       
   404  */
       
   405 {
       
   406    return iHeader.GetValue( iPtr8 );
       
   407 }
       
   408 
       
   409 template <class THEADER>
       
   410 inline TInt CItem<THEADER>::GetHeaderLength() const
       
   411 /**
       
   412  * Gets the length of the header in bytes(octets)
       
   413  *
       
   414  * @return the length of the item's header
       
   415  */
       
   416 {
       
   417    return iHeader.GetValueLength();
       
   418 }
       
   419 
       
   420 template <class THEADER>
       
   421 TUint32 CItem<THEADER>::GetBigEndian() const
       
   422 /**
       
   423  * Gets the big endian value from the item body.
       
   424 
       
   425  * It panics if the body length > sizeof(TInt). The item must be parsed or initialised
       
   426  *
       
   427  * @see TValue::GetValue()
       
   428  * @return  A 32-bit unsigned integer type representing the extracted value
       
   429  */
       
   430 {
       
   431    TBigEndian val;
       
   432    return val.GetValue( GetBodyPtr(), GetLength() );
       
   433 }
       
   434 
       
   435 template <class THEADER>
       
   436 TUint32 CItem<THEADER>::GetLittleEndian() const
       
   437 /**
       
   438  * Gets the little endian value from the item body.
       
   439 
       
   440  * It panics if the body length > sizeof(TInt). The item must be parsed or initialised
       
   441  *
       
   442  * @see TValue::GetValue()
       
   443  * @return  A 32-bit unsigned integer type representing the extracted value
       
   444  */
       
   445 {
       
   446    TLittleEndian val;
       
   447    return val.GetValue( GetBodyPtr(), GetLength() );
       
   448 }
       
   449 
       
   450 template <class THEADER>
       
   451 inline TUint8* CItem<THEADER>::GetBodyPtr() const
       
   452 /**
       
   453  * Gets the pointer to the item body.
       
   454 
       
   455  * The item must be parsed or initialised
       
   456  *
       
   457  * @return A pointer to the item body
       
   458  */
       
   459 {
       
   460    return iPtr8 + GetHeaderLength();
       
   461 }
       
   462 
       
   463 template <class THEADER>
       
   464 inline void CItem<THEADER>::SetBody( const TDesC8& aDes8 )
       
   465 /**
       
   466  * Copies the aDes into the item body.
       
   467 
       
   468  * The item must be parsed or initialised
       
   469  *
       
   470  * @param aDes8 An 8 bit non-modifiable descriptor representing the source data
       
   471  */
       
   472 {
       
   473    __ASSERT_DEBUG(iHeader.GetInitialValue() >= aDes8.Length(), User::Panic(KSpecAssert_ElemMsgParserRcr, 1));
       
   474    CItemBase::SetBody( aDes8, GetHeaderLength() );
       
   475 }
       
   476 
       
   477 template <class THEADER>
       
   478 inline TInt CItem<THEADER>::GetItemLength() const
       
   479 /**
       
   480  * Gets the item length (body+header).
       
   481 
       
   482  * The item must be parsed or initialised
       
   483  *
       
   484  * @return the item length
       
   485  */
       
   486 {
       
   487    return GetLength() + GetHeaderLength();
       
   488 }
       
   489 
       
   490 template <class THEADER>
       
   491 inline TPtr8 CItem<THEADER>::GetBodyDes() const
       
   492 /**
       
   493  * Creates the item body descriptor.
       
   494 
       
   495  * The item must be parsed or initialised
       
   496  *
       
   497  * @return An 8 bit modifiable pointer descriptor representing the item bod
       
   498  */
       
   499 {
       
   500    TInt n = GetLength();
       
   501    return TPtr8( GetBodyPtr(), n, n );
       
   502 }
       
   503 
       
   504 template <class THEADER>
       
   505 inline TPtr8 CItem<THEADER>::GetItemDes() const
       
   506 /**
       
   507  * Creates the item modifiable descriptor.
       
   508 
       
   509  * The item must be parsed or initialised
       
   510  *
       
   511  * @return the item
       
   512  */
       
   513 {
       
   514    TInt n = GetItemLength();
       
   515    return TPtr8( Ptr(), n, n );
       
   516 }
       
   517 
       
   518 template <class THEADER>
       
   519 void CItem<THEADER>::SetBigEndian( TUint32 aUint )
       
   520 /**
       
   521  * Sets the big endian value into the item body.
       
   522 
       
   523  * It panics if the body length > sizeof(TInt). The item must be parsed or initialised
       
   524  *
       
   525  * @see TValue::SetValue()
       
   526  * @param aUint value to set
       
   527  */
       
   528 {
       
   529    TBigEndian val;
       
   530    val.SetValue( iPtr8 + GetHeaderLength(), GetLength(), aUint );
       
   531 }
       
   532 
       
   533 template <class THEADER>
       
   534 void CItem<THEADER>::SetLittleEndian( TUint32 aUint )
       
   535 /**
       
   536  * Sets the little endian value into the item body.
       
   537 
       
   538  * It panics if the body length > sizeof(TInt). The item must be parsed or initialised
       
   539  *
       
   540  * @see TValue::SetValue()
       
   541  * @param aUint value to set
       
   542  */
       
   543 {
       
   544    TLittleEndian val;
       
   545    val.SetValue( GetBodyPtr(), GetLength(), aUint );
       
   546 }
       
   547 
       
   548 template <class THEADER>
       
   549 inline TInt CItem<THEADER>::CalcTotalInitialiseLength() const
       
   550 /**
       
   551  * Calculates the length of the data buffer to hold the item's data.
       
   552 
       
   553  * An initial value must be assigned to the item's header.
       
   554  *
       
   555  * @return the buffer length
       
   556  */
       
   557 {
       
   558    return iHeader.GetInitialValue() + GetHeaderLength();
       
   559 }
       
   560 
       
   561 template <class THEADER>
       
   562 void CItem<THEADER>::CopyBodyToL( HBufC8*& aBuf8 )
       
   563 /**
       
   564  * Copies the message body into the HBufC8.
       
   565 
       
   566  * Allocates/reallocates the specified aBuf8
       
   567  * if necessary. The item must be parsed or initialised
       
   568  *
       
   569  * @param aBuf8 descriptor to set
       
   570  */
       
   571 {
       
   572    CItemBase::CopyBodyToL( aBuf8, GetLength(), GetHeaderLength() );
       
   573 }
       
   574 
       
   575 template <class THEADER>
       
   576 void CItem<THEADER>::InitialiseL( TPtr8& aBuf8 )
       
   577 /**
       
   578  * Initialises the item pointer to point to the beginning of the buffer
       
   579  *
       
   580  * @param aBuf8  An 8 bit modifiable pointer descriptor to hold the item's data
       
   581  */
       
   582 {
       
   583    CItemBase::InitialiseL( aBuf8, iHeader.GetInitialValue(), GetHeaderLength() );
       
   584    //set expected length to the item header
       
   585    SetLength();
       
   586 }
       
   587 
       
   588 template <class THEADER>
       
   589 void CItem<THEADER>::ParseL( TPtr8& aDes8 )
       
   590 /**
       
   591  * Checks the input and initialises the item pointer to point to the beginning
       
   592  * of the input buffer
       
   593  *
       
   594  * @param aDes8 An 8 bit modifiable pointer descriptor representing the descriptor to be checked
       
   595  */
       
   596 {
       
   597    CItemBase::ParseL( aDes8, iHeader.GetValue( aDes8.Ptr() ), GetHeaderLength() );
       
   598 }
       
   599 
       
   600 #ifdef _DEBUG
       
   601 template <class THEADER>
       
   602 inline void CItem<THEADER>::Dump( const TDesC& aTag, const TDesC& aFile )
       
   603 /**
       
   604  * Dumps the item.
       
   605 
       
   606  * The item must be parsed or initialised
       
   607  *
       
   608  * @param aTag A log file tag
       
   609  * @param aFile A log file
       
   610  */
       
   611    {
       
   612 #ifdef __FLOG_ACTIVE
       
   613    RFileLogger f;
       
   614    if ( f.Connect() == KErrNone )
       
   615       {
       
   616       f.CreateLog( aTag, aFile, EFileLoggingModeAppend );
       
   617 	   f.WriteFormat( _L("Item[%S]"), &iName );
       
   618 	   f.WriteFormat( _L("header length: %d, length from header: %d, initial length: %d"),
       
   619          GetHeaderLength(), GetLength(), iHeader.GetInitialValue() );
       
   620       if ( GetHeaderLength() )
       
   621          {
       
   622 	      f.Write( _L("Header & Body:"));
       
   623 	      f.HexDump( NULL, NULL, iPtr8, GetItemLength() );
       
   624          }
       
   625       else if ( GetLength() )
       
   626          {
       
   627 	      f.Write( _L("Body:"));
       
   628 	      f.HexDump( NULL, NULL, iPtr8, GetItemLength() );
       
   629          }
       
   630       f.CloseLog();
       
   631       f.Close();
       
   632       }
       
   633 #else
       
   634 (void)aTag;
       
   635 (void)aFile;
       
   636 #endif
       
   637    }
       
   638 #else  // #ifdef _DEBUG
       
   639 template <class THEADER>
       
   640 inline void CItem<THEADER>::Dump( const TDesC& /*aTag*/, const TDesC& /*aFile*/ )
       
   641    {
       
   642    }
       
   643 #endif
       
   644 
       
   645 /**
       
   646  Keeps a pointer to the first item and processes all items in the message structure.
       
   647 
       
   648  There is one instance of this class in each message structure.
       
   649  @internalTechnology
       
   650  **/
       
   651 class TRecord
       
   652 {
       
   653 public:
       
   654    TRecord( CItemBase* aFirst ) :
       
   655       iFirst( aFirst )
       
   656    {
       
   657    }
       
   658 
       
   659    void Dump( const TDesC& aTag, const TDesC& aFile );
       
   660    IMPORT_C void ParseL( TPtr8& aDes8 );
       
   661    IMPORT_C void InitialiseL( TPtr8& aBuf8 );  //buffer must be initialised beforehand
       
   662    IMPORT_C TInt CalcTotalInitialiseLength() const;
       
   663 
       
   664    CItemBase* First() const
       
   665    {
       
   666       return iFirst;
       
   667    }
       
   668 
       
   669 protected:
       
   670    IMPORT_C CItemBase& Get( TInt nIndex );
       
   671 
       
   672 public:
       
   673    CItemBase* iFirst;
       
   674 };
       
   675 
       
   676 //Dump methods must be present in UREL builds also to avoid vtable BC breaks
       
   677 //when SSL component is debug but this one isn't. Still not exposing it
       
   678 //as an export to avoid changing the DEF files now.
       
   679 #ifdef _DEBUG
       
   680 inline void TRecord::Dump( const TDesC& aTag, const TDesC& aFile )
       
   681 /**
       
   682  * Dumps the item list starting with iFirst.
       
   683 
       
   684  * The items must be parsed or initialised
       
   685  *
       
   686  * @param aTag A log file tag
       
   687  * @param aFile A log file
       
   688  */
       
   689 {
       
   690    CItemBase* pItem = iFirst;
       
   691    while ( pItem != 0 )
       
   692    {
       
   693       pItem->Dump( aTag, aFile );
       
   694       pItem = pItem->iNext;
       
   695    }
       
   696 }
       
   697 #else
       
   698 inline void TRecord::Dump( const TDesC& /*aTag*/, const TDesC& /*aFile*/ )
       
   699 {
       
   700 }
       
   701 #endif
       
   702 
       
   703 /**
       
   704  Represents an item of constant length
       
   705  @internalTechnology
       
   706  **/
       
   707 class CConstItem : public CItem< TConstant >
       
   708 {
       
   709 public:
       
   710    CConstItem( CItemBase* aNext, TInt aLength ) :
       
   711       CItem< TConstant >( aNext, aLength )
       
   712    {
       
   713    }
       
   714 
       
   715   // Empty destructor necessary to compile for x86gcc target.
       
   716   ~CConstItem()
       
   717 	  {
       
   718 	  }
       
   719 };
       
   720 
       
   721 /**
       
   722  Represents an item of variable length having a big endian layout
       
   723  @internalTechnology
       
   724  **/
       
   725 class CVariableItem : public CItem< TValueBigEndian >
       
   726 {
       
   727 public:
       
   728    CVariableItem( TInt aHeaderLength, CItemBase* aNext, TInt aInitLength = 0 ) :
       
   729       CItem< TValueBigEndian >( aNext, aHeaderLength )
       
   730    {
       
   731       Header().SetInitialValue( aInitLength );
       
   732    }
       
   733 };
       
   734 
       
   735 /**
       
   736  The class represents a header of an item list.
       
   737 
       
   738  An item list is a variable part of a message. It's created as the data is being parsed
       
   739  @see CListItem
       
   740  @internalTechnology
       
   741  **/
       
   742 class CListItemHeader : public CConstItem
       
   743 {
       
   744 public:
       
   745    CListItemHeader( CItemBase* aNext, TInt aHeaderLength ) :
       
   746       CConstItem( aNext, aHeaderLength  )
       
   747    {
       
   748    }
       
   749 };
       
   750 
       
   751 /**
       
   752  Represents one item of the item list.
       
   753 
       
   754  The item has variable length with a big endian header layout
       
   755  @see CListItem
       
   756  @internalTechnology
       
   757  **/
       
   758 class CListNode : public CItem< TValueBigEndian >
       
   759 {
       
   760    friend class CListItem;
       
   761 
       
   762 public:
       
   763 	 CListNode* Next() const;
       
   764 
       
   765 protected:
       
   766    CListNode( TInt aHeaderLength );
       
   767    IMPORT_C ~CListNode();
       
   768 };
       
   769 
       
   770 inline CListNode::CListNode( TInt aHeaderLength ) :
       
   771    CItem< TValueBigEndian >( NULL, aHeaderLength )
       
   772 {
       
   773 }
       
   774 
       
   775 inline CListNode* CListNode::Next() const
       
   776    {
       
   777       return static_cast<CListNode*>(iNext);
       
   778    }
       
   779 
       
   780 /**
       
   781  Represents an item list consisting of CListNode items and
       
   782  having a CListItemHeader header.
       
   783  @see CListNode
       
   784  @see CListItemHeader
       
   785  @internalTechnology
       
   786  **/
       
   787 class CListItem : public CListItemHeader
       
   788 {
       
   789 public:
       
   790    CListItem( CItemBase* aNext, TInt aHeaderLength );
       
   791    IMPORT_C virtual ~CListItem();
       
   792 
       
   793    virtual void Dump( const TDesC& aTag, const TDesC& aFile );
       
   794    IMPORT_C void AddNode( CItemBase* aItemBase );
       
   795    IMPORT_C void AddNodeL( TInt aInitialLength );
       
   796    IMPORT_C virtual void InitialiseL( TPtr8& aBuf8 );  //buffer must be initialised beforehand
       
   797    IMPORT_C virtual TInt CalcTotalInitialiseLength() const;
       
   798 
       
   799    IMPORT_C virtual void ParseL( TPtr8& aDes8 );
       
   800 
       
   801    void RemoveAllNodes();
       
   802 
       
   803    CListNode* First() const;
       
   804 
       
   805 protected:
       
   806    TRecord iRecord;
       
   807 
       
   808 };
       
   809 
       
   810 inline CListItem::CListItem( CItemBase* aNext, TInt aHeaderLength ) :
       
   811    CListItemHeader( aNext, aHeaderLength ),
       
   812    iRecord( NULL )
       
   813 {
       
   814 }
       
   815 
       
   816 inline CListNode* CListItem::First() const
       
   817    {
       
   818       return static_cast<CListNode*>( iRecord.First() );
       
   819    }
       
   820 
       
   821 #ifdef _DEBUG
       
   822 inline void CListItem::Dump( const TDesC& aTag, const TDesC& aFile )
       
   823 /**
       
   824  * Dumps the variable item list's header and item list.
       
   825 
       
   826  * The items must be parsed or initialised
       
   827  *
       
   828  * @param aTag A log file tag
       
   829  * @param aFile A log file
       
   830  */
       
   831 {
       
   832    CListItemHeader::Dump( aTag, aFile );
       
   833    iRecord.Dump( aTag, aFile );
       
   834 }
       
   835 #else
       
   836 inline void CListItem::Dump( const TDesC& /*aTag*/, const TDesC& /*aFile*/ )
       
   837 {
       
   838 }
       
   839 #endif
       
   840 
       
   841 inline void CListItem::RemoveAllNodes()
       
   842 /**
       
   843  * Deletes all items from the list.
       
   844  *
       
   845  */
       
   846 {
       
   847    delete iRecord.iFirst;
       
   848    iRecord.iFirst = NULL;
       
   849 }
       
   850 
       
   851 #endif
       
   852