diff -r 000000000000 -r 307788aac0a8 realtimenetprots/sipfw/SDP/src/SdpUtil.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/realtimenetprots/sipfw/SDP/src/SdpUtil.cpp Tue Feb 02 01:03:15 2010 +0200 @@ -0,0 +1,635 @@ +// Copyright (c) 2003-2009 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 : SDP Codec +// Version : 1.0 +// + + + +#include +#include +#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 SdpUtil::DivideToLinesL( + const TDesC8& aLines, + TInt aErrCode ) + { + RArray 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 SdpUtil::GetElementsFromLineL( + const TDesC8& aLine, + TInt aErrCode ) + { + TLex8 lexer( aLine ); + RArray lineArray = + SdpUtil::GetElementsFromLineL( lexer, KSPChar, aErrCode ); + return lineArray; + } + +// ----------------------------------------------------------------------------- +// SdpUtil::GetElementsFromLineL +// Gets all the elements from a single line +// ----------------------------------------------------------------------------- +// +RArray SdpUtil::GetElementsFromLineL( + const TDesC8& aLine, + TChar aDelimiter, + TInt aErrCode ) + { + TLex8 lexer( aLine ); + RArray lineArray = + SdpUtil::GetElementsFromLineL( lexer, aDelimiter, aErrCode ); + return lineArray; + } + +// ----------------------------------------------------------------------------- +// SdpUtil::GetElementsFromLineL +// Gets all the elements from a single line +// ----------------------------------------------------------------------------- +// +RArray SdpUtil::GetElementsFromLineL( + TLex8& aLexer, + TChar aDelimiter, + TInt aErrCode ) + { + RArray 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 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& 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(); + } + } + }