contentmgmt/referencedrmagent/RefTestAgent/localsdp/src/sdputil.cpp
changeset 72 de46a57f75fb
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/contentmgmt/referencedrmagent/RefTestAgent/localsdp/src/sdputil.cpp	Thu Jun 24 15:39:07 2010 +0530
@@ -0,0 +1,635 @@
+// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// Name          : SdpUtil.cpp
+// Part of       : Local SDP Codec
+// Version       : 1.0
+//
+
+
+
+#include <s32strm.h>
+#include <in_sock.h>
+#include "sdputil.h"
+#include "sdpcodecstringconstants.h"
+#include "sdpcodecstringpool.h"
+#include "sdpcodecconstants.h"
+#include "_sdpdefs.h"
+
+// LOCAL CONSTANTS
+const TInt KMaxAddressLength = 256;
+_LIT8(KInvalidTokenCharacters, "\0\r\n\t ()<>@,;:");
+_LIT8(KInvalidByteStringCharacters, "\0\r\n");
+_LIT8(KWhitespaceCharacters, "\0\r\n \t");
+_LIT16(KWildAddr, "0.0.0.0");
+    
+// -----------------------------------------------------------------------------
+// SdpUtil::IsValidCharSet
+// Generic checker to validate that string has only valid characters
+// -----------------------------------------------------------------------------
+//
+TBool SdpUtil::IsValidCharSet(
+    const TDesC8& aIllegalChars,
+    const TDesC8& aValue,
+    TInt aStart,
+    TInt aEnd)
+	{
+	TBool result = EFalse;
+	
+	if ( aIllegalChars.Length() > 0 && aStart >= 0 && 
+         aEnd <= aValue.Length() && aStart < aEnd )
+		{
+		TInt comp = KErrNotFound;
+		while (comp == KErrNotFound && aStart < aEnd)
+			{
+			comp = aIllegalChars.Locate( aValue[aStart] );
+			++aStart;
+			}
+		result = ( comp == KErrNotFound );
+		}
+	else 
+		{
+		result = ( ( aStart < aEnd ) && 
+                   ( aIllegalChars.Length() == 0 || aValue.Length() == 0 ) );
+		}
+
+	return result;
+	}
+
+// -----------------------------------------------------------------------------
+// SdpUtil::IsTokenList
+// Checks that token list is valid
+// -----------------------------------------------------------------------------
+//
+TBool SdpUtil::IsTokenList(
+    const TDesC8& aValue )
+	{	
+	TBool atError = ( aValue.Length() == 0 );
+    
+    // Check that we are starting with valid character, not e.g. with space
+    if ( !atError && 
+         KInvalidTokenCharacters().Locate( aValue[0] ) != KErrNotFound )
+        {
+        atError = ETrue;
+        }
+    
+    TLex8 lexer( aValue );
+    // Go through the tokens to see that they are valid
+    while ( !atError && !lexer.Eos() )
+        {
+        if ( !IsToken( lexer.NextToken() ) )
+            {
+            atError = ETrue;
+            }   
+        }
+
+	return !atError;
+	}
+
+// -----------------------------------------------------------------------------
+// SdpUtil::IsToken
+// Checks if aValue is valid token
+// -----------------------------------------------------------------------------
+//
+TBool SdpUtil::IsToken( 
+    const TDesC8& aValue, 
+    TInt aStart, 
+    TInt aEnd)
+	{
+	return IsValidCharSet( KInvalidTokenCharacters, aValue, aStart, aEnd );
+	}
+
+// -----------------------------------------------------------------------------
+// SdpUtil::IsToken
+// Checks if aValue is valid token
+// -----------------------------------------------------------------------------
+//
+TBool SdpUtil::IsToken(
+    const TDesC8& aValue )
+	{
+	return IsValidCharSet( KInvalidTokenCharacters, aValue, 0, aValue.Length() );
+	}
+
+// -----------------------------------------------------------------------------
+// SdpUtil::IsByteString
+// Checks if aValue is valid byte string
+// -----------------------------------------------------------------------------
+//
+TBool SdpUtil::IsByteString(
+    const TDesC8& aValue, 
+    TInt aStart, 
+    TInt aEnd )
+	{
+	return IsValidCharSet( KInvalidByteStringCharacters, aValue, aStart, aEnd );
+	}
+
+// -----------------------------------------------------------------------------
+// SdpUtil::IsByteString
+// Checks if aValue is valid byte string
+// -----------------------------------------------------------------------------
+//
+TBool SdpUtil::IsByteString(
+    const TDesC8& aValue )
+	{
+	return IsValidCharSet( KInvalidByteStringCharacters, aValue, 0, 
+                           aValue.Length() );
+	}
+
+// -----------------------------------------------------------------------------
+// SdpUtil::IsTokenTextPair
+// Checks if aValue is valid pair ("valid token":"valid byte-string")
+// -----------------------------------------------------------------------------
+//
+TBool SdpUtil::IsTokenTextPair(
+    const TDesC8& aValue, 
+    TInt aStart,
+    TInt aEnd )
+	{
+	// token ":" text
+	TBool result = EFalse;
+	if ( aStart >= 0 && aEnd <= aValue.Length() && aStart < aEnd )
+		{
+		TPtrC8 subVal = aValue.Mid( aStart, aEnd - aStart );
+		TInt colonPos = subVal.Locate( KColonChar );
+		result = colonPos != KErrNone &&
+                 IsToken( subVal, 0, colonPos ) &&
+                 IsByteString( subVal, colonPos + 1, subVal.Length() );
+		}
+	return result;
+	}
+
+// -----------------------------------------------------------------------------
+// SdpUtil::IsTokenTextPair
+// Checks if aValue is valid pair ("valid token":"valid byte-string")
+// -----------------------------------------------------------------------------
+//
+TBool SdpUtil::IsTokenTextPair(
+    const TDesC8& aValue )
+	{
+	return IsTokenTextPair( aValue, 0, aValue.Length() );
+	}
+
+// -----------------------------------------------------------------------------
+// SdpUtil::IsNonWhitepce
+// Checks if aValue contains only non-whitespace characters
+// -----------------------------------------------------------------------------
+//
+TBool SdpUtil::IsNonWhitespace(
+    const TDesC8& aValue )
+	{
+	return IsValidCharSet( KWhitespaceCharacters, aValue, 0, aValue.Length() );
+	}
+
+// -----------------------------------------------------------------------------
+// SdpUtil::IsValidNtpTime
+// Checks if aValue contains only non-whitespace characters
+// -----------------------------------------------------------------------------
+//
+TBool SdpUtil::IsValidNtpTime(
+    const TDesC8& aValue )
+	{
+	// POS-DIGIT 9*DIGIT
+	TUint len = aValue.Length();
+	TBool result = len >= 10 && TChar( aValue[0] ) != TChar('0');
+	if ( result )
+		{
+		for ( TUint i( 0 ); result && i < len; i++)
+			{
+			TInt tmp = aValue[i] - '0';
+			result = ( tmp >= 0 && tmp <= 9 );
+			}
+		}
+	return result;
+	}
+
+// -----------------------------------------------------------------------------
+// SdpUtil::DivideToLinesL
+// Divides descriptor into a number of lines that are separated by
+// CRLF or LF marks
+// -----------------------------------------------------------------------------
+//
+RArray<TPtrC8> SdpUtil::DivideToLinesL( 
+    const TDesC8& aLines,
+    TInt aErrCode )
+    {
+    RArray<TPtrC8> lineArray;
+    CleanupClosePushL( lineArray );
+    
+    TInt lineStartPos( 0 );
+    TInt lineEndPos( aLines.Length() );
+    TInt pos( 0 );
+    
+    TPtrC8 parsedPart( aLines.Right( lineEndPos - lineStartPos ) );
+    // Splits aLines to number of TPtrC8s, each ending to CRLF/LF
+    while ( lineStartPos < lineEndPos && 
+           ( pos = parsedPart.Find( KLFStr ) ) != KErrNotFound )
+        {  
+        if ( ! ( pos == 0 || 
+                ( pos == ( KCRLFStr().Length() - 1 ) && 
+                  parsedPart.Find( KCRLFStr ) == 0 ) ) )
+            {
+            // Lines that contain only CRLF or LF are ignored
+            // Put the valid lines to the array
+            User::LeaveIfError( 
+                lineArray.Append( 
+                    TPtrC8( parsedPart.Left( pos + KLFStr().Length() ) ) ) );
+            }
+        // Advance the start of the line after LF mark
+        lineStartPos += pos + KLFStr().Length();
+        parsedPart.Set( aLines.Right( lineEndPos - lineStartPos ) );
+        }    
+    
+    // This method expects that last line of aLines ends _always_ 
+    // to LF not to '\0'
+    if ( aLines.Length() == 0 ||
+        ( aLines.Length() > 0 && aLines[aLines.Length() - 1] != '\n' ) )
+        {
+        User::Leave( aErrCode );
+        }
+
+    CleanupStack::Pop();    // lineArray
+    return lineArray;    
+    }
+
+// -----------------------------------------------------------------------------
+// SdpUtil::GetElementsFromLineL
+// Gets all the elements from a single line
+// -----------------------------------------------------------------------------
+//
+RArray<TPtrC8> SdpUtil::GetElementsFromLineL(
+    const TDesC8& aLine, 
+    TInt aErrCode )
+    {
+    TLex8 lexer( aLine );
+    RArray<TPtrC8> lineArray = 
+        SdpUtil::GetElementsFromLineL( lexer, KSPChar, aErrCode );    
+    return lineArray;
+    }
+
+// -----------------------------------------------------------------------------
+// SdpUtil::GetElementsFromLineL
+// Gets all the elements from a single line
+// -----------------------------------------------------------------------------
+//
+RArray<TPtrC8> SdpUtil::GetElementsFromLineL( 
+    const TDesC8& aLine, 
+    TChar aDelimiter,
+    TInt aErrCode )
+    {
+    TLex8 lexer( aLine );
+    RArray<TPtrC8> lineArray = 
+        SdpUtil::GetElementsFromLineL( lexer, aDelimiter, aErrCode );
+    return lineArray;
+    }
+
+// -----------------------------------------------------------------------------
+// SdpUtil::GetElementsFromLineL
+// Gets all the elements from a single line
+// -----------------------------------------------------------------------------
+//
+RArray<TPtrC8> SdpUtil::GetElementsFromLineL( 
+    TLex8& aLexer, 
+    TChar aDelimiter,
+    TInt aErrCode )
+    {
+    RArray<TPtrC8> lineArray;    
+    CleanupClosePushL( lineArray );
+   
+    // Header is special case, because it is joined _without_
+    // space character with the first attribute, so it must be
+    // parsed separately        
+            
+    aLexer.Mark();
+    // curChar must be != KEqualChar at first comparison
+    for ( TChar curChar( KSPChar ); curChar != KEqualChar; )
+        {
+        curChar = aLexer.Peek();
+        // Syntax check      
+        if ( curChar == KEofChar || curChar == KLFChar ||
+             curChar == KCRChar )
+            {
+            User::Leave( aErrCode );
+            }        
+        aLexer.Inc();       
+        }
+    // Append header to array
+    User::LeaveIfError( lineArray.Append( aLexer.MarkedToken() ) );
+    
+    // Whitespace MUST NOT be used after the "=" sign
+    if (aLexer.Peek() == KSPChar) 
+	    {
+		User::Leave( aErrCode );	    	 
+	    }
+
+    // Get the other elements from the string to the array
+    ChopElementsFromLineL( lineArray, aLexer, aDelimiter, aErrCode );
+
+    CleanupStack::Pop();    // lineArray
+    return lineArray;
+    }
+
+// -----------------------------------------------------------------------------
+// SdpUtil::IsPosDigit
+// Checks if all the charcaters on the descriptor are POS-DIGITs
+// -----------------------------------------------------------------------------
+//
+TBool SdpUtil::IsPosDigit( 
+    const TDesC8& aDes )
+    {
+    // POS-DIGIT = %x31-39 ; 1 - 9
+    _LIT8( KValidPosDigits, "123456789" );
+    return SdpUtil::IsValidChars( KValidPosDigits, aDes );
+    }
+
+// -----------------------------------------------------------------------------
+// SdpUtil::IsDigit
+// Checks if all the charcaters on the descriptor are DIGITs
+// -----------------------------------------------------------------------------
+//
+TBool SdpUtil::IsDigit( 
+    const TDesC8& aDes )
+    {
+    // DIGIT = "0" / "1" / "2" / "3" / "4" / "5" / "6" /
+    //         "7" / "8" / "9"
+    _LIT8( KValidDigits, "0123456789" );
+
+    return SdpUtil::IsValidChars( KValidDigits, aDes );
+    }
+
+// -----------------------------------------------------------------------------
+// SdpUtil::IsValidChars
+// Checks if all the charcaters on the descriptor are from valid charset
+// -----------------------------------------------------------------------------
+//
+TBool SdpUtil::IsValidChars( 
+    const TDesC8& aValidChars, 
+    const TDesC8& aDes )
+    {
+    TBool valid( aDes.Length() > 0 );
+    for ( TInt i( 0 ); i < aDes.Length() && valid; i++ )
+        {
+        if ( aValidChars.Locate( aDes[i] ) == KErrNotFound )
+            {
+            valid = EFalse;
+            }
+        }
+
+    return valid;
+    }
+        
+// -----------------------------------------------------------------------------
+// SdpUtil::IsTokenCharWithSpacesL
+// Checks if all the elements on the string are valid tokens
+// -----------------------------------------------------------------------------
+//
+TBool SdpUtil::IsTokenCharWithSpacesL(
+    const TDesC8& aValue )
+	{
+	TLex8 lex( aValue );
+	lex.SkipSpace();
+
+	if( lex.Remainder().Length() == 0 )
+		{
+		User::Leave( KErrArgument );
+		}
+
+	while ( !lex.Eos() )
+		{
+		if ( !IsTokenChar( lex.NextToken() ) )
+			{
+			return EFalse;
+			}
+		lex.SkipSpace();
+		}
+	return ETrue;
+	}
+
+// -----------------------------------------------------------------------------
+// SdpUtil::IsTokenCharWithOptionalSlash
+// Checks if all the possible two elements divided by slash are valid tokens
+// -----------------------------------------------------------------------------
+//
+TBool SdpUtil::IsTokenCharWithOptionalSlash(const TDesC8& aValue)
+	{
+	TInt lineEndPosition = aValue.Locate('/');
+
+	if ( lineEndPosition != KErrNotFound )
+		{
+		TPtrC8 firstToken( aValue.Left( lineEndPosition ) );
+		if( !IsTokenChar( firstToken ) ||
+		    !IsTokenChar( aValue.Mid( lineEndPosition + 1 ) ) )
+			{
+			return EFalse;
+			}
+		}
+	else
+		{
+		return IsTokenChar( aValue );
+		}
+	return ETrue;
+	}
+
+// -----------------------------------------------------------------------------
+// SdpUtil::IsTokenChar
+// Checks if all the elements on the string are valid tokens
+// -----------------------------------------------------------------------------
+//
+TBool SdpUtil::IsTokenChar(
+    const TDesC8& aValue )
+	{	
+    TLex8 lex( aValue );
+	while( !lex.Eos() )
+		{
+		TChar ch = lex.Get();
+		lex.Inc();
+
+		if( ch == '\r' ||ch == '\n' || ch == '\0' || !IsTokenChar( ch ) )
+			{
+			return EFalse;
+			}
+		}
+	return ETrue;
+	}
+
+// -----------------------------------------------------------------------------
+// SdpUtil::IsTokenChar
+// Checks if the character is a valid token character
+// -----------------------------------------------------------------------------
+//
+TBool SdpUtil::IsTokenChar( 
+    TChar aChar )
+	{
+    return ( ( aChar == '!')||
+	         ( aChar >= '#' && aChar <= '\'' ) ||
+	         ( aChar == '*' || aChar == '+' ) ||
+	         ( aChar == '-' || aChar == '.' ) ||
+	         ( aChar.IsDigit() ) ||
+	         ( aChar >= 'a' && aChar <= 'z' ) ||
+	         ( aChar >= 'A' && aChar <= 'Z' ) ||
+	         ( aChar >= '^' && aChar <= '~' ) );	
+	}
+
+// ---------------------------------------------------------------------------
+// SdpUtil::EncodeBufferL
+// Encodes headername and a value to the stream
+// ---------------------------------------------------------------------------
+//
+void SdpUtil::EncodeBufferL(
+    const TDesC8& aValue, 
+    TInt aIndex,
+    RWriteStream& aStream )
+	{
+	if( aValue.Length() != 0 )
+		{
+        RStringPool pool = SdpCodecStringPool::StringPoolL();
+		RStringF headername = pool.StringF( aIndex, 
+                                        SdpCodecStringPool::StringTableL() );
+		aStream.WriteL( headername.DesC() );
+		aStream.WriteL( aValue );
+		aStream.WriteL( KCRLFStr );
+		}
+	}
+
+// ---------------------------------------------------------------------------
+// SdpUtil::SetDefaultNetTypeAndAddrType
+// Sets network type and address type to their "default" values
+// ---------------------------------------------------------------------------
+//
+void SdpUtil::SetDefaultNetTypeAndAddrType( 
+    RStringPool aPool, 
+    const TInetAddr& aAddress,
+    RStringF& aNetType, 
+    RStringF& aAddressType )
+    {
+     // Sets network type to IN
+    aNetType.Close();
+    aNetType = aPool.StringF( SdpCodecStringConstants::ENetType,
+                              SdpCodecStringConstants::Table ).Copy();
+    // Address type       
+    aAddressType.Close();
+
+    TBuf16 <KMaxAddressLength> output;
+    aAddress.Output(output);
+
+
+    //addresstype for IPv4    
+	if((aAddress.Address() &&  !aAddress.IsV4Mapped()) ||
+       (!aAddress.Address() && aAddress.IsWildAddr() && 
+        output.Match(KWildAddr) == 0))
+        {
+        aAddressType = aPool.StringF( SdpCodecStringConstants::EAddressTypeIP4,
+                                      SdpCodecStringConstants::Table ).Copy();
+        }
+    else
+        {
+		//addresstype for IPv4-Mapped IPv6 && IPv6
+        aAddressType = aPool.StringF( SdpCodecStringConstants::EAddressType,
+                                      SdpCodecStringConstants::Table ).Copy();
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// SdpUtil::SkipSpacesUntilNextLineBreak
+// Skips spaces until next line break, if the line break can be found.
+// Examples: "   \r\n" -> "\r\n", "abc def\r\n" -> "abc def\r\n"
+// ---------------------------------------------------------------------------
+//       
+TBool SdpUtil::SkipSpacesUntilNextLineBreak( TLex8& aLexer )
+    {
+    TBool found = EFalse;
+    if ( aLexer.Peek() == KSPChar )
+        {
+        TInt spaceCount = 0;
+        while ( aLexer.Peek() == KSPChar )
+            {
+            spaceCount++;
+            aLexer.Get();
+            }
+        if ( aLexer.Peek() != KCRChar && aLexer.Peek() != KLFChar )
+            {
+            for ( TInt i=0; i < spaceCount; i++ )
+                {
+                aLexer.UnGet();
+                }
+            }
+        else
+            {
+            found = ETrue;
+            }
+        }
+    return found;
+    }
+
+// ---------------------------------------------------------------------------
+// SdpUtil::ChopElementsFromLineL
+// Chops all the elements that are divided by delimiter from the string
+// ---------------------------------------------------------------------------
+//
+void SdpUtil::ChopElementsFromLineL( 
+    RArray<TPtrC8>& aArray, 
+    TLex8& aLexer,
+    TChar aDelimiter,
+    TInt aErrCode )
+    {
+    // Chop the elements to the array from lexer
+    TBool eofcFound = EFalse;
+    while (!eofcFound)
+        {
+        aLexer.Mark();        
+        // Parse single token, leave other special characters
+        // to token except aDelimiter | '\r' | '\n' | '\0'
+        while ( aLexer.Peek() != aDelimiter && 
+                aLexer.Peek() != KCRChar &&
+                aLexer.Peek() != KLFChar && 
+                aLexer.Peek() != KEofChar )
+            {
+            aLexer.Inc();
+            }
+		
+        if ( aLexer.MarkedToken().Length() > 0 )
+            {            
+            aArray.AppendL( aLexer.MarkedToken() );
+            }
+
+        if ( aDelimiter == KSPChar &&
+             aLexer.Peek() == aDelimiter )
+            {
+            SkipSpacesUntilNextLineBreak( aLexer );
+            }
+
+        // Check if its end-of-line
+        if ( aLexer.Peek() == KCRChar )
+            {
+            aLexer.Inc();
+            }
+
+        if ( aLexer.Peek() == KLFChar )
+            {
+            aLexer.Inc();
+            if ( aLexer.Peek() != KEofChar )
+                {
+                User::Leave( aErrCode );
+                }
+            eofcFound = ETrue;
+            }
+        else if ( aLexer.Peek() == KEofChar )
+            {
+            // EoF character not tolerated at the middle of the string
+            User::Leave( aErrCode );
+            }
+        else
+            {
+            aLexer.Inc();
+            }
+        }
+    }