realtimenetprots/sipfw/SDP/src/SdpKeyField.cpp
changeset 0 307788aac0a8
equal deleted inserted replaced
-1:000000000000 0:307788aac0a8
       
     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 // Name          : SdpKeyField.h
       
    15 // Part of       : SDP Codec
       
    16 // Version       : 1.0
       
    17 //
       
    18 
       
    19 
       
    20 
       
    21 #include <uri8.h>
       
    22 #include <s32strm.h>
       
    23 #include "SdpKeyField.h"
       
    24 #include "SdpUtil.h"
       
    25 #include "SDPCodec.pan"
       
    26 #include "_sdpdefs.h"
       
    27 #include "sdpcodecstringconstants.h"
       
    28 #include "SdpCodecConstants.h"
       
    29 #include "SdpCodecErr.h"
       
    30 #include "SdpCodecStringPool.h"
       
    31 
       
    32 // LOCAL CONSTANTS
       
    33 const TText8 KPlusChar = '+';
       
    34 
       
    35 // -----------------------------------------------------------------------------
       
    36 // CSdpKeyField::DecodeL
       
    37 // Decodes key field from TDesC
       
    38 // -----------------------------------------------------------------------------
       
    39 //
       
    40 EXPORT_C CSdpKeyField* CSdpKeyField::DecodeL(const TDesC8& aFieldValue)
       
    41 	{
       
    42 	CSdpKeyField* obj = DecodeLC(aFieldValue);
       
    43 	CleanupStack::Pop();
       
    44 	return obj;
       
    45 	}
       
    46 
       
    47 // -----------------------------------------------------------------------------
       
    48 // CSdpKeyField::DecodeL
       
    49 // Decodes key field from TDesC
       
    50 // -----------------------------------------------------------------------------
       
    51 //
       
    52 EXPORT_C CSdpKeyField* CSdpKeyField::DecodeLC(const TDesC8& aFieldValue)
       
    53 	{
       
    54 	CSdpKeyField* obj = new (ELeave) CSdpKeyField();
       
    55 	CleanupStack::PushL(obj);
       
    56 	obj->ConstructL(aFieldValue);
       
    57 	return obj;
       
    58 	}
       
    59 
       
    60 // -----------------------------------------------------------------------------
       
    61 // CSdpKeyField::NewL
       
    62 // Two-phased constructor
       
    63 // -----------------------------------------------------------------------------
       
    64 //
       
    65 EXPORT_C CSdpKeyField* CSdpKeyField::NewL(RStringF aMethod,
       
    66                                           const TDesC8& aEncryptionKey)
       
    67 	{
       
    68 	CSdpKeyField* obj = NewLC(aMethod, aEncryptionKey);
       
    69 	CleanupStack::Pop();
       
    70 	return obj;
       
    71 	}
       
    72 
       
    73 // -----------------------------------------------------------------------------
       
    74 // CSdpKeyField::NewLC
       
    75 // Two-phased constructor
       
    76 // -----------------------------------------------------------------------------
       
    77 //
       
    78 EXPORT_C CSdpKeyField* CSdpKeyField::NewLC(RStringF aMethod,
       
    79                                            const TDesC8& aEncryptionKey)
       
    80 	{
       
    81 	CSdpKeyField* obj = new (ELeave) CSdpKeyField();
       
    82 	CleanupStack::PushL(obj);
       
    83 	obj->ConstructL(aMethod, aEncryptionKey);
       
    84 	return obj;
       
    85 	}
       
    86 
       
    87 // -----------------------------------------------------------------------------
       
    88 // CSdpKeyField::~CSdpKeyField
       
    89 // Destructor
       
    90 // -----------------------------------------------------------------------------
       
    91 //
       
    92 EXPORT_C CSdpKeyField::~CSdpKeyField()
       
    93 	{
       
    94     iMethod.Close();
       
    95 	delete iEncryptionKey;
       
    96 	}
       
    97 
       
    98 // -----------------------------------------------------------------------------
       
    99 // CSdpKeyField::EncodeL
       
   100 // Writes attributes in proper format to the stream
       
   101 // -----------------------------------------------------------------------------
       
   102 //
       
   103 EXPORT_C void CSdpKeyField::EncodeL(RWriteStream& aStream) const
       
   104 	{
       
   105 	__TEST_INVARIANT;
       
   106     RStringF header = iStringPool.StringF(SdpCodecStringConstants::EKey,
       
   107                                         SdpCodecStringConstants::Table);
       
   108     aStream.WriteL( header.DesC() );
       
   109 
       
   110     aStream.WriteL( iMethod.DesC() );
       
   111     if (iMethod != iStringPool.StringF(SdpCodecStringConstants::EMethodPrompt,
       
   112                                     SdpCodecStringConstants::Table))
       
   113         {
       
   114         aStream.WriteL( KColonStr );
       
   115         if (iEncryptionKey->Length() > 0)
       
   116             {
       
   117             aStream.WriteL( *iEncryptionKey );
       
   118             }
       
   119         }
       
   120 
       
   121     aStream.WriteL( KCRLFStr );
       
   122 	}
       
   123 
       
   124 // -----------------------------------------------------------------------------
       
   125 // CSdpKeyField::CloneL
       
   126 // Creates an exact copy of the key field
       
   127 // -----------------------------------------------------------------------------
       
   128 //
       
   129 EXPORT_C CSdpKeyField * CSdpKeyField::CloneL() const
       
   130 	{
       
   131 	__TEST_INVARIANT;
       
   132 	CSdpKeyField* obj = CSdpKeyField::NewL(iMethod, *iEncryptionKey);
       
   133 	__ASSERT_DEBUG(*this == *obj, User::Panic(  KSdpCodecPanicCat,
       
   134                                                 KSdpCodecPanicInternal));
       
   135 	return obj;
       
   136 	}
       
   137 
       
   138 // -----------------------------------------------------------------------------
       
   139 // CSdpKeyField::operator ==
       
   140 // Checks if two key fields are equal
       
   141 // -----------------------------------------------------------------------------
       
   142 //
       
   143 EXPORT_C TBool CSdpKeyField::operator == (const CSdpKeyField& aObj) const
       
   144 	{
       
   145 	__TEST_INVARIANT;
       
   146 	return iMethod == aObj.iMethod
       
   147 			&& ((iEncryptionKey == 0 && aObj.iEncryptionKey == 0)
       
   148 				|| (iEncryptionKey != 0 && aObj.iEncryptionKey != 0
       
   149                 && aObj.iEncryptionKey->Compare(*iEncryptionKey) == 0));
       
   150 	}
       
   151 
       
   152 // -----------------------------------------------------------------------------
       
   153 // CSdpKeyField::Method
       
   154 // Returns method
       
   155 // -----------------------------------------------------------------------------
       
   156 //
       
   157 EXPORT_C RStringF CSdpKeyField::Method() const
       
   158 	{
       
   159 	__TEST_INVARIANT;
       
   160 	return iMethod;
       
   161 	}
       
   162 
       
   163 // -----------------------------------------------------------------------------
       
   164 // CSdpKeyField::EncryptionKey
       
   165 // Returns encryption key
       
   166 // -----------------------------------------------------------------------------
       
   167 //
       
   168 EXPORT_C const TDesC8& CSdpKeyField::EncryptionKey() const
       
   169 	{
       
   170 	__TEST_INVARIANT;
       
   171 	return *iEncryptionKey;
       
   172 	}
       
   173 
       
   174 // -----------------------------------------------------------------------------
       
   175 // CSdpKeyField::SetL
       
   176 // Sets new values to key method and encryption key
       
   177 // -----------------------------------------------------------------------------
       
   178 //
       
   179 EXPORT_C void CSdpKeyField::SetL(RStringF aMethod,
       
   180                                  const TDesC8& aEncryptionKey)
       
   181 	{
       
   182     RStringF methodClear = iStringPool.StringF(
       
   183                                         SdpCodecStringConstants::EMethodClear,
       
   184                                         SdpCodecStringConstants::Table );
       
   185     RStringF methodBase64 = iStringPool.StringF(
       
   186                                         SdpCodecStringConstants::EMethodBase64,
       
   187                                         SdpCodecStringConstants::Table );
       
   188     RStringF methodUri = iStringPool.StringF(
       
   189                                         SdpCodecStringConstants::EMethodUri,
       
   190                                         SdpCodecStringConstants::Table );
       
   191     RStringF methodPrompt = iStringPool.StringF(
       
   192                                         SdpCodecStringConstants::EMethodPrompt,
       
   193                                         SdpCodecStringConstants::Table );
       
   194 
       
   195     if (aMethod == methodClear)
       
   196         {
       
   197         SetMethodClearAndKeyL(methodClear, aEncryptionKey);
       
   198         }
       
   199     else if (aMethod == methodBase64)
       
   200         {
       
   201         SetMethodBase64AndKeyL(methodBase64, aEncryptionKey);
       
   202         }
       
   203     else if (aMethod == methodUri)
       
   204         {
       
   205         SetMethodUriAndKeyL(methodUri, aEncryptionKey);
       
   206         }
       
   207     else if (aMethod == methodPrompt)
       
   208         {
       
   209         SetMethodPromptL(methodPrompt, aEncryptionKey);
       
   210         }
       
   211     else
       
   212         {
       
   213         User::Leave(KErrSdpCodecKeyField);
       
   214         }
       
   215 
       
   216     __TEST_INVARIANT;
       
   217 	}
       
   218 
       
   219 // -----------------------------------------------------------------------------
       
   220 // CSdpKeyField::ExternalizeL
       
   221 // Externalizes the object to stream
       
   222 // -----------------------------------------------------------------------------
       
   223 //
       
   224 void CSdpKeyField::ExternalizeL(RWriteStream& aStream) const
       
   225     {
       
   226     aStream.WriteUint32L( iMethod.DesC().Length() );
       
   227     aStream.WriteL( iMethod.DesC() );
       
   228 
       
   229     aStream.WriteUint32L( iEncryptionKey->Des().Length() );
       
   230 	if (iEncryptionKey->Des().Length() > 0)
       
   231         {
       
   232         aStream.WriteL(iEncryptionKey->Des(), iEncryptionKey->Des().Length());
       
   233         }
       
   234     }
       
   235 
       
   236 // -----------------------------------------------------------------------------
       
   237 // CSdpKeyField::InternalizeL
       
   238 // Internalizes the object from stream
       
   239 // -----------------------------------------------------------------------------
       
   240 //
       
   241 CSdpKeyField* CSdpKeyField::InternalizeL(RReadStream& aStream)
       
   242     {
       
   243     CSdpKeyField* self = new (ELeave) CSdpKeyField();
       
   244     CleanupStack::PushL(self);
       
   245     self->iStringPool = SdpCodecStringPool::StringPoolL();
       
   246 
       
   247     self->DoInternalizeL(aStream);
       
   248 
       
   249     CleanupStack::Pop(); // self
       
   250     return self;
       
   251     }
       
   252 
       
   253 // -----------------------------------------------------------------------------
       
   254 // CSdpKeyField::CSdpKeyField
       
   255 // Constructor
       
   256 // -----------------------------------------------------------------------------
       
   257 //
       
   258 CSdpKeyField::CSdpKeyField()
       
   259 	{
       
   260 	}
       
   261 
       
   262 // -----------------------------------------------------------------------------
       
   263 // CSdpKeyField::ConstructL
       
   264 // Symbian 2nd phase constructor can leave.
       
   265 // -----------------------------------------------------------------------------
       
   266 //
       
   267 void CSdpKeyField::ConstructL(const TDesC8& aText)
       
   268 	{
       
   269     iStringPool = SdpCodecStringPool::StringPoolL();
       
   270     RArray <TPtrC8> lines;
       
   271     lines = SdpUtil::DivideToLinesL(aText, KErrSdpCodecKeyField);
       
   272     CleanupClosePushL(lines);
       
   273 
       
   274     TLex8 lexer(lines[0]);
       
   275     RArray<TPtrC8> keyArray = GetElementsFromLineL(lexer);
       
   276     CleanupClosePushL(keyArray);
       
   277     const TDesC8& keyName = iStringPool.StringF(SdpCodecStringConstants::EKey,
       
   278         SdpCodecStringConstants::Table).DesC();
       
   279 
       
   280     __ASSERT_ALWAYS(lines.Count() == 1
       
   281                     && keyArray.Count() >= 2 && keyArray.Count() <= 3
       
   282                     && keyArray[0].Find(keyName) != KErrNotFound,
       
   283                     User::Leave(KErrSdpCodecKeyField));
       
   284 
       
   285     RStringF method = iStringPool.OpenFStringL(keyArray[1]);
       
   286     CleanupClosePushL(method);
       
   287 
       
   288     if (keyArray.Count() == 3)
       
   289         {
       
   290         SetL(method, keyArray[2]);
       
   291         }
       
   292     else
       
   293         {
       
   294         SetL(method, KNullDesC8);
       
   295         }
       
   296     CleanupStack::PopAndDestroy(3);  // method, lines, keyArray
       
   297 	__TEST_INVARIANT;
       
   298 	}
       
   299 
       
   300 // -----------------------------------------------------------------------------
       
   301 // CSdpKeyField::ConstructL
       
   302 // Symbian 2nd phase constructor can leave.
       
   303 // -----------------------------------------------------------------------------
       
   304 //
       
   305 void CSdpKeyField::ConstructL(RStringF aMethod, const TDesC8& aEncryptionKey)
       
   306 	{
       
   307     iStringPool = SdpCodecStringPool::StringPoolL();
       
   308     SetL(aMethod, aEncryptionKey);
       
   309 
       
   310 	__TEST_INVARIANT;
       
   311 	}
       
   312 
       
   313 // -----------------------------------------------------------------------------
       
   314 // CSdpKeyField::DoInternalizeL
       
   315 // Internalizes the object members from stream
       
   316 // -----------------------------------------------------------------------------
       
   317 //
       
   318 void CSdpKeyField::DoInternalizeL(RReadStream& aStream)
       
   319     {
       
   320      // <method>
       
   321     TUint32 length = aStream.ReadUint32L();
       
   322     HBufC8* method = HBufC8::NewLC(length);
       
   323     TPtr8 ptr(method->Des());
       
   324     aStream.ReadL(ptr, length);
       
   325 
       
   326     RStringF methodStr = iStringPool.OpenFStringL(*method);
       
   327     CleanupStack::PopAndDestroy(); // method
       
   328     CleanupClosePushL(methodStr);
       
   329 
       
   330     length = aStream.ReadUint32L();
       
   331     if (length > 0)
       
   332         {
       
   333         HBufC8* key = HBufC8::NewLC(length);
       
   334         ptr.Set(key->Des());
       
   335         aStream.ReadL(ptr, length);
       
   336 
       
   337         SetL(methodStr, *key);
       
   338         CleanupStack::PopAndDestroy(); //key
       
   339         }
       
   340     else
       
   341         {
       
   342         SetL(methodStr, KNullDesC8);
       
   343         }
       
   344     CleanupStack::PopAndDestroy(); // methodStr
       
   345     }
       
   346 
       
   347 // -----------------------------------------------------------------------------
       
   348 // CSdpKeyField::SetMethodAndKeyL
       
   349 // Sets new values to key method and encryption key
       
   350 // -----------------------------------------------------------------------------
       
   351 //
       
   352 void CSdpKeyField::SetMethodAndKeyL(RStringF aMethod,
       
   353                                     const TDesC8& aEncryptionKey,
       
   354                                     TBool aAllowEmptyKeyValue)
       
   355     {
       
   356     HBufC8* tempKey = aEncryptionKey.AllocL();
       
   357     tempKey->Des().Trim();
       
   358     if (tempKey->Length() == 0 && !aAllowEmptyKeyValue)
       
   359         {
       
   360         delete tempKey;
       
   361         User::Leave(KErrSdpCodecKeyField);
       
   362         }
       
   363     iMethod.Close();
       
   364     iMethod = aMethod.Copy();
       
   365     delete iEncryptionKey;
       
   366     iEncryptionKey = tempKey;
       
   367     }
       
   368 
       
   369 // -----------------------------------------------------------------------------
       
   370 // CSdpKeyField::SetMethodClearAndKeyL
       
   371 // Sets key method to clear and new encryption key
       
   372 // -----------------------------------------------------------------------------
       
   373 //
       
   374 void CSdpKeyField::SetMethodClearAndKeyL(RStringF aMethod,
       
   375                                          const TDesC8& aEncryptionKey)
       
   376     {
       
   377     __ASSERT_ALWAYS(SdpUtil::IsByteString(aEncryptionKey),
       
   378                     User::Leave(KErrSdpCodecKeyField));
       
   379     SetMethodAndKeyL(aMethod, aEncryptionKey, EFalse);
       
   380 	}
       
   381 
       
   382 // -----------------------------------------------------------------------------
       
   383 // CSdpKeyField::SetMethodBase64AndKeyL
       
   384 // Sets key method to Base64 and new encryption key
       
   385 // -----------------------------------------------------------------------------
       
   386 //
       
   387 void CSdpKeyField::SetMethodBase64AndKeyL(RStringF aMethod,
       
   388                                           const TDesC8& aText)
       
   389     {
       
   390     __ASSERT_ALWAYS(aText.Length() > 0, User::Leave(KErrSdpCodecKeyField));
       
   391 
       
   392     for (TInt i = 0; i < aText.Length(); i++)
       
   393         {
       
   394         if ( !( ( aText[i] >= 'a' && aText[i] <= 'z' ) ||
       
   395                 ( aText[i] >= 'A' && aText[i] <= 'Z' ) ||
       
   396                 ( aText[i] >= '0' && aText[i] <= '9' ) ||
       
   397                 ( aText[i] == KPlusChar ) ||
       
   398                 ( aText[i] == KSlashChar ) ||
       
   399                 ( aText[i] == KEqualChar ) ) )
       
   400             {
       
   401             User::Leave(KErrSdpCodecKeyField);
       
   402             }
       
   403         }
       
   404     SetMethodAndKeyL(aMethod, aText, EFalse);
       
   405     }
       
   406 
       
   407 // -----------------------------------------------------------------------------
       
   408 // CSdpKeyField::SetMethodUriAndKeyL
       
   409 // Sets key method to uri and new encryption key
       
   410 // -----------------------------------------------------------------------------
       
   411 //
       
   412 void CSdpKeyField::SetMethodUriAndKeyL(RStringF aMethod, const TDesC8& aText)
       
   413     {
       
   414     TUriParser8 parser;
       
   415     User::LeaveIfError(parser.Parse(aText));
       
   416     SetMethodAndKeyL(aMethod, aText, EFalse);
       
   417     }
       
   418 
       
   419 // -----------------------------------------------------------------------------
       
   420 // CSdpKeyField::SetMethodPromptL
       
   421 // Sets key method to Prompt and new encryption key
       
   422 // -----------------------------------------------------------------------------
       
   423 //
       
   424 void CSdpKeyField::SetMethodPromptL(RStringF aMethod, const TDesC8& aText)
       
   425     {
       
   426     __ASSERT_ALWAYS(aText.Length() == 0, User::Leave(KErrSdpCodecKeyField));
       
   427     SetMethodAndKeyL(aMethod, aText, ETrue);
       
   428     }
       
   429 
       
   430 // -----------------------------------------------------------------------------
       
   431 // CSdpKeyField::GetElementsFromLineL
       
   432 // Gets all the elements from a single line
       
   433 // -----------------------------------------------------------------------------
       
   434 //
       
   435 RArray<TPtrC8> CSdpKeyField::GetElementsFromLineL( TLex8& aLexer)
       
   436     {
       
   437     RArray<TPtrC8> lineArray;
       
   438     CleanupClosePushL(lineArray);
       
   439 
       
   440     aLexer.Mark();
       
   441     for (TChar curChar(KColonChar); curChar != KEqualChar;)
       
   442         {
       
   443         curChar = aLexer.Peek();
       
   444         if (curChar == KEofChar || curChar == KLFChar ||
       
   445              curChar == KCRChar)
       
   446             {
       
   447             User::Leave(KErrSdpCodecKeyField);
       
   448             }
       
   449         aLexer.Inc();
       
   450         }
       
   451     User::LeaveIfError(lineArray.Append(aLexer.MarkedToken()));
       
   452 
       
   453     TBool colonFound = EFalse;
       
   454     TBool eofcFound = EFalse;
       
   455     while (!eofcFound)
       
   456         {
       
   457         aLexer.Mark();
       
   458         while ((aLexer.Peek() != KColonChar || colonFound) &&
       
   459                 aLexer.Peek() != KCRChar &&
       
   460                 aLexer.Peek() != KLFChar &&
       
   461                 aLexer.Peek() != KEofChar)
       
   462             {
       
   463             aLexer.Inc();
       
   464             }
       
   465 
       
   466         if (aLexer.MarkedToken().Length() > 0)
       
   467             {
       
   468             User::LeaveIfError(lineArray.Append(aLexer.MarkedToken()));
       
   469             }
       
   470         else
       
   471             {
       
   472             User::Leave(KErrSdpCodecKeyField);
       
   473             }
       
   474 
       
   475         if (aLexer.Peek() == KColonChar)
       
   476             {
       
   477             colonFound = ETrue;
       
   478             }
       
   479 
       
   480         if (aLexer.Peek() == KCRChar)
       
   481             {
       
   482             aLexer.Inc();
       
   483             }
       
   484         if (aLexer.Peek() == KLFChar)
       
   485             {
       
   486             aLexer.Inc();
       
   487             if (aLexer.Peek() == KEofChar)
       
   488                 {
       
   489                 eofcFound = ETrue;
       
   490                 }
       
   491             }
       
   492         else
       
   493             {
       
   494             aLexer.Inc();
       
   495             }
       
   496         }
       
   497 
       
   498     CleanupStack::Pop();
       
   499     return lineArray;
       
   500     }
       
   501 
       
   502 void CSdpKeyField::__DbgTestInvariant() const
       
   503 	{
       
   504     RStringF methodClear = iStringPool.StringF(
       
   505                                         SdpCodecStringConstants::EMethodClear,
       
   506                                         SdpCodecStringConstants::Table );
       
   507     RStringF methodBase64 = iStringPool.StringF(
       
   508                                         SdpCodecStringConstants::EMethodBase64,
       
   509                                         SdpCodecStringConstants::Table );
       
   510     RStringF methodUri = iStringPool.StringF(
       
   511                                         SdpCodecStringConstants::EMethodUri,
       
   512                                         SdpCodecStringConstants::Table );
       
   513     RStringF methodPrompt = iStringPool.StringF(
       
   514                                         SdpCodecStringConstants::EMethodPrompt,
       
   515                                         SdpCodecStringConstants::Table );
       
   516 
       
   517     TBool invariant =   (iMethod == methodPrompt
       
   518 	                        && (iEncryptionKey != 0 && (iEncryptionKey->Length() == 0)) )
       
   519 						||  ((iMethod == methodClear || iMethod == methodBase64
       
   520 	                            || iMethod == methodUri)
       
   521                         && (iEncryptionKey != 0 && (iEncryptionKey->Length() != 0)) );
       
   522 
       
   523 	if (!invariant)
       
   524 		User::Invariant();
       
   525 	}