diff -r 000000000000 -r f5a58ecadc66 upnp/upnpstack/upnputils/src/upnpstring.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/upnp/upnpstack/upnputils/src/upnpstring.cpp Tue Feb 02 01:12:20 2010 +0200 @@ -0,0 +1,844 @@ +/** @file +* Copyright (c) 2005-2006 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: String handling +* +*/ + + +// INCLUDES +#include +#include +#include +#include +#include +#include "upnpcons.h" +#include "upnpstring.h" +#include "upnpcommonupnplits.h" + +// ================= MEMBER FUNCTIONS ======================= + + +namespace UpnpString + { + + // PR: following for optimized encode/decodexml functions + _LIT8( KGtEntity, "gt;"); + _LIT8( KLtEntity, "lt;"); + _LIT8( KQuotEntity, "quot;"); + _LIT8( KAposEntity, "apos;"); + _LIT8( KAmpEntity, "amp;"); + + // for formatting a date string (in UT) + _LIT8( KDay1,"Mon"); + _LIT8( KDay2,"Tue"); + _LIT8( KDay3,"Wed"); + _LIT8( KDay4,"Thu"); + _LIT8( KDay5,"Fri"); + _LIT8( KDay6,"Sat"); + _LIT8( KDay7,"Sun"); + + // for formatting a date string (in UT) + _LIT8( KMonth1,"Jan"); + _LIT8( KMonth2,"Feb"); + _LIT8( KMonth3,"Mar"); + _LIT8( KMonth4,"Apr"); + _LIT8( KMonth5,"May"); + _LIT8( KMonth6,"Jun"); + _LIT8( KMonth7,"Jul"); + _LIT8( KMonth8,"Aug"); + _LIT8( KMonth9,"Sep"); + _LIT8( KMonth10,"Oct"); + _LIT8( KMonth11,"Nov"); + _LIT8( KMonth12,"Dec"); + + //for formatting UT + _LIT8( KTimeGMT,"GMT"); + + //for formatting UT + const static TInt KWidthFour = 4; + const static TInt KWidthTwo = 2; + + const static TInt KMaxEntityLength = 6; // e.g. " + const static TInt KEntitiesCount = 5; + const static TReal KReallocRatio = 1.3; + + +// ----------------------------------------------------------------------------- +// UpnpString::DeleteArray +// +// ----------------------------------------------------------------------------- +// +void DeleteArray(TAny* param); + +// ----------------------------------------------------------------------------- +// UpnpString::IsColon +// Is char colon. +// ----------------------------------------------------------------------------- +// +EXPORT_C TBool IsColon(const TUint8& aChar) + { + return aChar == ':'; + } +// ----------------------------------------------------------------------------- +// UpnpString::FromUnicodeL +// Convert from unicode. +// ----------------------------------------------------------------------------- +// +EXPORT_C HBufC8* FromUnicodeL(const TDesC& aBuffer) + { + return EscapeUtils::ConvertFromUnicodeToUtf8L(aBuffer); + } + +// ----------------------------------------------------------------------------- +// UpnpString::ToUnicodeL +// Convert to unicode. +// ----------------------------------------------------------------------------- +// +EXPORT_C HBufC16* ToUnicodeL(const TDesC8& aBuffer) + { + return EscapeUtils::ConvertToUnicodeFromUtf8L(aBuffer); + } + +// ----------------------------------------------------------------------------- +// UpnpString::CurrentDateLC +// Return current date. +// ----------------------------------------------------------------------------- +// +EXPORT_C HBufC8* CurrentDateLC() + { + HBufC8* timeBuf = NULL; + + TTime time; + time.UniversalTime(); + + timeBuf = GetDateLC(time); + + return timeBuf; + } + +// ----------------------------------------------------------------------------- +// UpnpString::GetDateLC +// Return current date. +// ----------------------------------------------------------------------------- +// +HBufC8* GetDateLC(const TTime& aTime) + { + TDateTime datetime = aTime.DateTime(); + + HBufC8* timeBuf = HBufC8::NewLC(KDateTimeStringLen); + //weekday + timeBuf->Des().Copy(GetWeekday(aTime)); + timeBuf->Des().Append(KComma); + timeBuf->Des().Append(KSpace); + + //date + //days numerated from 0 to 30, so +1 + timeBuf->Des().AppendNumFixedWidth((datetime.Day()+1),EDecimal, KWidthTwo); + timeBuf->Des().Append(KSpace); + timeBuf->Des().Append(GetMonth(datetime)); + timeBuf->Des().Append(KSpace); + timeBuf->Des().AppendNumFixedWidth(datetime.Year(),EDecimal, KWidthFour); + timeBuf->Des().Append(KSpace); + + //time + timeBuf->Des().AppendNumFixedWidth((datetime.Hour()),EDecimal, KWidthTwo); + timeBuf->Des().Append(KColon); + timeBuf->Des().AppendNumFixedWidth((datetime.Minute()),EDecimal, KWidthTwo); + timeBuf->Des().Append(KColon); + timeBuf->Des().AppendNumFixedWidth((datetime.Second()),EDecimal, KWidthTwo); + timeBuf->Des().Append(KSpace); + + //GMT + timeBuf->Des().Append(KTimeGMT); + + return timeBuf; + } + +// ----------------------------------------------------------------------------- +// UpnpString::GetWeekday +// +// ----------------------------------------------------------------------------- +// +const TDesC8& GetWeekday(const TTime& aDate) + { + switch (aDate.DayNoInWeek()) + { + case EMonday: + return KDay1(); + case ETuesday: + return KDay2(); + case EWednesday: + return KDay3(); + case EThursday: + return KDay4(); + case EFriday: + return KDay5(); + case ESaturday: + return KDay6(); + case ESunday: + return KDay7(); + default: + return KNullDesC8; + + } + } + +// ----------------------------------------------------------------------------- +// UpnpString::GetMonth +// +// ----------------------------------------------------------------------------- +// +const TDesC8& GetMonth(const TDateTime& aDate) + { + switch (aDate.Month()) + { + case EJanuary: + return KMonth1(); + case EFebruary: + return KMonth2(); + case EMarch: + return KMonth3(); + case EApril: + return KMonth4(); + case EMay: + return KMonth5(); + case EJune: + return KMonth6(); + case EJuly: + return KMonth7(); + case EAugust: + return KMonth8(); + case ESeptember: + return KMonth9(); + case EOctober: + return KMonth10(); + case ENovember: + return KMonth11(); + case EDecember: + return KMonth12(); + default: + return KNullDesC8; + } + } + +// ----------------------------------------------------------------------------- +// UpnpString::CutToPiecesL +// +// ----------------------------------------------------------------------------- +// +EXPORT_C void CutToPiecesL( TPtrC8 aPtr, + TChar aDelim, + RPointerArray& aArray ) + { + TInt i = 0; + CleanupStack::PushL(TCleanupItem(&DeleteArray,&aArray)); + + while(KErrNotFound != aPtr.Locate(aDelim)) + { + TPtrC8* tmp = new (ELeave)TPtrC8(); + CleanupStack::PushL(tmp); + User::LeaveIfError( aArray.Append( tmp ) ); + CleanupStack::Pop(tmp); + + aArray[i]->Set(aPtr.Left((aPtr.Locate(aDelim)))); + aPtr.Set(aPtr.Right(aPtr.Length() - (aPtr.Locate(aDelim) + 1)) ); + aArray[i]->Set(Trim(*aArray[i], EFalse)); + i++; + } + TPtrC8* tmp = new (ELeave)TPtrC8(); + CleanupStack::PushL(tmp); + User::LeaveIfError( aArray.Append( tmp ) ); + CleanupStack::Pop(tmp); + + aArray[i]->Set(aPtr); + aArray[i]->Set(Trim(*aArray[i], EFalse)); + + CleanupStack::Pop(&aArray); + } + +// ----------------------------------------------------------------------------- +// UpnpString::Trim +// +// ----------------------------------------------------------------------------- +// +EXPORT_C TPtrC8 Trim(TPtrC8 aPtr, TBool aQuotations) + { + if( aPtr.Length() == 0 ) + { + return aPtr; + } + while( ( ('"' == aPtr[0]) && aQuotations ) || + (' ' == aPtr[0]) ) + { + aPtr.Set(aPtr.Right(aPtr.Length() - 1)); + if( aPtr.Length() == 0) + { + return aPtr; + } + } + + while( ( ('"' == aPtr[aPtr.Length() - 1] ) && aQuotations ) || + (' ' == aPtr[aPtr.Length() - 1] ) ) + { + aPtr.Set(aPtr.Left(aPtr.Length() - 1 )); + if( aPtr.Length() == 0 ) + { + return aPtr; + } + } + return aPtr; + } + +// ----------------------------------------------------------------------------- +// CutToPiecesL +// +// ----------------------------------------------------------------------------- +// +void CutToPiecesL( TPtrC8 aPtr,TChar aDelim, RArray& aArray ) + { + TInt i = 0; + TInt loc = aPtr.Locate(aDelim); + while(KErrNotFound != loc) + { + TPtrC8 r(aPtr.Left(loc)); + User::LeaveIfError(aArray.Append(r)); + aPtr.Set(aPtr.Right(aPtr.Length() - (loc + 1)) ); + i++; + loc = aPtr.Locate(aDelim); + } + TInt parenthesis; + parenthesis = aPtr.Locate(')'); + if( KErrNotFound != parenthesis ) + { + User::LeaveIfError(aArray.Append(aPtr.Left( parenthesis ))); + } + else + { + User::LeaveIfError(aArray.Append(aPtr)); + } + } + +// ----------------------------------------------------------------------------- +// UpnpString::ValueFromCsvL +// +// ----------------------------------------------------------------------------- +// +EXPORT_C HBufC8* ValueFromCsvL(const TDesC8& aCSV, TInt aPlace) + { + RArray array; + CleanupClosePushL(array); + CutToPiecesL(aCSV, ',', array); + + HBufC8* value = HBufC8::NewL(array[aPlace].Length()); + value->Des().Copy(array[aPlace]); + CleanupStack::PopAndDestroy(); + return value; + } + +// ----------------------------------------------------------------------------- +// UpnpString::AddValueToCsvL +// +// ----------------------------------------------------------------------------- +// +EXPORT_C HBufC8* AddValueToCsvL(const TDesC8& aCSV, const TDesC8& aValue) + { + HBufC8* buf=NULL; + if( 0 == KEmptyString().Compare(aCSV) ) + { + buf = aValue.AllocL(); + } + else + { + buf = HBufC8::NewL(aCSV.Length() + KComma().Length() + aValue.Length()); + buf->Des().Append(aCSV); + buf->Des().Append(KComma()); + buf->Des().Append(aValue); + } + return buf; + } + +// ----------------------------------------------------------------------------- +// UpnpString::RemoveFromCsvLC +// +// ----------------------------------------------------------------------------- +// +EXPORT_C HBufC8* RemoveFromCsvLC(const TDesC8& aCSV, const TDesC8& aValue) + { + RPointerArray array; + CsvToRPointerArrayL(aCSV, array); + TPtrC8 val(Trim(aValue, EFalse)); + for( TInt i = 0; i < array.Count(); i++ ) + { + if( 0 == array[i]->CompareF(val) ) + { + delete array[i]; + array.Remove(i); + } + } + CleanupStack::PushL(TCleanupItem(&DeleteArray, &array)); + HBufC8* buf = RPointerArrayToCsvLC( array ); + CleanupStack::Pop( buf ); + CleanupStack::PopAndDestroy( &array ); + CleanupStack::PushL( buf ); + array.Close(); + return buf; + } + +// ----------------------------------------------------------------------------- +// UpnpString::CsvToRPointerArrayL +// +// ----------------------------------------------------------------------------- +// +EXPORT_C void CsvToRPointerArrayL( const TDesC8& aCSV, + RPointerArray& aArray ) + { + aArray.ResetAndDestroy(); + CutToPiecesL(aCSV, ',', aArray); + } + +// ----------------------------------------------------------------------------- +// UpnpString::RPointerArrayToCsvLC +// +// ----------------------------------------------------------------------------- +// +EXPORT_C HBufC8* RPointerArrayToCsvLC( RPointerArray& aArray ) + { + TInt length (0); + TInt i(0); + for( ; i< aArray.Count(); ++i) + { + length += aArray[i]->Length() + KComma().Length(); + } + + HBufC8* buf = HBufC8::NewLC(length); + TPtr8 des = buf->Des(); + + for( i = 0; i < aArray.Count(); i++ ) + { + des.Append(*aArray[i]); + if( i != aArray.Count() - 1 ) + { + des.Append(KComma()); + } + } + return buf; + } + +// ----------------------------------------------------------------------------- +// UpnpString::AppendStringL +// Append to string. +// ----------------------------------------------------------------------------- +// +EXPORT_C void AppendStringL( CBufFlat& aBuffer, const TDesC8& aString ) + { + RBufWriteStream bufWs(aBuffer, aBuffer.Size()); + CleanupClosePushL(bufWs); + bufWs.WriteL(aString); + bufWs.CommitL(); + CleanupStack::PopAndDestroy(); + } + +// ----------------------------------------------------------------------------- +// UpnpString::AppendStringL +// Append to string. +// ----------------------------------------------------------------------------- +// +EXPORT_C void AppendStringL( HBufC8*& aString, const TDesC8& aString2 ) + { + if(aString==NULL) + { + if(aString2.Length()==0) + { + return; + } + aString = HBufC8::NewLC(aString2.Length()); + aString->Des().Append(aString2); + CleanupStack::Pop(); + } + else if(aString2.Length()==0) + { + return; + } + else + { + HBufC8* nString = HBufC8::NewLC(aString->Length() + aString2.Length()); + nString->Des().Append(aString->Des()); + nString->Des().Append(aString2); + + delete aString; + aString = nString; + CleanupStack::Pop(); + } + } + +// ----------------------------------------------------------------------------- +// UpnpString::StringToInt +// String to integer. +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt StringToInt(const TDesC8& aStr, TInt* aInt) + { + if( 0 == aStr.Length() || aInt == NULL) + { + return KErrArgument; + } + TLex8 lex( aStr ); + return lex.Val( *aInt ); + } + +// ----------------------------------------------------------------------------- +// UpnpString::StringReplaceL +// +// ----------------------------------------------------------------------------- +// +EXPORT_C void StringReplaceL( const TDesC8& aOrginal, + HBufC8*& aResult, + const TDesC8& aTrg, + const TDesC8& aReplacement ) + { + TInt place = aOrginal.Find( aTrg ); + if( KErrNotFound != place ) + { + aResult = StringReplaceL(aOrginal, aTrg, aReplacement); + } + else + { + delete aResult; + aResult = NULL; + aResult = aOrginal.AllocL(); + } + } + +// ----------------------------------------------------------------------------- +// UpnpString::StringReplaceL +// +// ----------------------------------------------------------------------------- +// +EXPORT_C HBufC8* StringReplaceL( const TDesC8& aStr, + const TDesC8& aTrg, + const TDesC8& aReplacement ) + { + __ASSERT_DEBUG(aTrg.Length() && aStr.Length(), User::Panic(_L("String"), 0)); + TInt length = aStr.Length(); + if(aReplacement.Length() > aTrg.Length()) + { + TInt position(0); + TPtrC8 loc; + TInt numOccurrences(0); + loc.Set(aStr); + for(;;) + { + position = loc.Find(aTrg); + if(position == KErrNotFound) + { + break; + } + numOccurrences++; + position +=aTrg.Length(); + if(position >= loc.Length()) + { + break; + } + loc.Set(loc.Mid(position)); + } + length += (aReplacement.Length() - aTrg.Length())*numOccurrences; + } + HBufC8* result = HBufC8::NewLC(length); + TPtr8 ptr = result->Des(); + ptr.Copy(aStr); + StringReplaceInPlaceL(ptr, aTrg, aReplacement); + if(ptr.MaxLength() > ptr.Length()) + { + result = result->ReAllocL(result->Length()); + } + CleanupStack::Pop(); + return result; + } + +// ----------------------------------------------------------------------------- +// UpnpString::StringReplaceInPlaceL +// expected: aTrg.Length() >= aReplacement.Length() +// ----------------------------------------------------------------------------- +// +EXPORT_C void StringReplaceInPlaceL( + TDes8& aString, + const TDesC8& aTrg, + const TDesC8& aReplacement ) + { + __ASSERT_DEBUG(aTrg != aReplacement, User::Panic(_L("String"), 1)); + + TPtrC8 ptr(aString); + TInt position(0); + FOREVER + { + TInt found = ptr.Find( aTrg ); + if(found < 0) + { + return; + } + aString.Replace( position + found, aTrg.Length(), aReplacement ); + if(position + found + aReplacement.Length() < aString.Length()) + { + position += found + aReplacement.Length(); + ptr.Set(aString.Mid(position)); + } + else + return; + } + } + +// ----------------------------------------------------------------------------- +// String::EncodeXmlStringL +// Encode XML string. +// ----------------------------------------------------------------------------- +// + +EXPORT_C HBufC8* EncodeXmlStringL( HBufC8*& aBuf ) + { + return EncodeXmlStringL( *aBuf ); + } + +// ----------------------------------------------------------------------------- +// String::DecodeXmlStringL +// Decode XML string. +// ----------------------------------------------------------------------------- +// +EXPORT_C HBufC8* DecodeXmlStringL( HBufC8*& aBuf ) + { + return DecodeXmlStringL( *aBuf ); + } + +EXPORT_C HBufC8* EncodeXmlStringL( const TDesC8& aXmlString ) + { + const TPtrC8 KEntities[5] = + { + KGtEntity(), KLtEntity(), KQuotEntity(), KAposEntity(), KAmpEntity() + }; + const TChar KChars[5] = + { + '>', '<', '"', '\'', '&' + }; + + HBufC8* result = HBufC8::NewLC( aXmlString.Length() * KReallocRatio ); + TPtr8 ptr = result->Des(); + + TLex8 lexer( aXmlString ); + TChar ch; + while ( ch = lexer.Get() ) + { + if ( result->Length() >= ( ptr.MaxLength() - KMaxEntityLength ) ) + { + TInt newLength( ptr.MaxLength() * KReallocRatio ) ; + + result = result->ReAllocL( newLength ); + CleanupStack::Pop(); // "old" result descriptor + CleanupStack::PushL( result ); + ptr.Set( result->Des() ); + + } + TBool found = EFalse; + for ( TInt i = 0; i < KEntitiesCount; i++ ) + { + if ( ch == KChars[i] ) + { + ptr.Append( '&' ); + ptr.Append( KEntities[i] ); + found = ETrue; + break; + } + } + if ( !found ) + { + ptr.Append( ch ); + } + } + CleanupStack::Pop( result ); + return result; + } + +EXPORT_C HBufC8* DecodeXmlStringL( const TDesC8& aXmlString ) + { + const TPtrC8 KEntities[5] = + { + KGtEntity(), KLtEntity(), KQuotEntity(), KAposEntity(), KAmpEntity() + }; + const TChar KChars[5] = + { + '>', '<', '"', '\'', '&' + }; + + HBufC8* result = HBufC8::NewLC( aXmlString.Length() ); + TPtr8 ptr = result->Des(); + + TLex8 lexer( aXmlString ); + TChar ch; + TBool insideEntity = EFalse; + + while ( ch = lexer.Get() ) + { + if ( insideEntity ) + { + if ( ch == ';' ) // entity ends + { + insideEntity = EFalse; + TPtrC8 entity = lexer.MarkedToken(); + TBool found = EFalse; + + for ( TInt i = 0; i < KEntitiesCount; i++ ) + { + if ( !entity.Compare( KEntities[i] )) // match + { + ptr.Append( KChars[i] ); + found = ETrue; + break; + } + } + if ( !found ) + { + // no match, appending as it is + ptr.Append( '&' ); + ptr.Append( entity ); + } + } + } + else + { + if ( ch == '&' ) // entity starts + { + insideEntity = ETrue; + lexer.Mark(); + } + else + { + ptr.Append( ch ); + } + } + } + CleanupStack::Pop( result ); + return result; + } + + +// ----------------------------------------------------------------------------- +// UpnpString::InetToStringL +// Intet address to string. +// ----------------------------------------------------------------------------- +// +EXPORT_C HBufC8* InetToStringL(const TInetAddr& aAddress) + { + TBuf<20> address; + aAddress.Output(address); + HBufC8* host8 = UpnpString::FromUnicodeL(address); + CleanupStack::PushL(host8); + TBuf8<10> port; + port.Num(aAddress.Port()); + + HBufC8* host = HBufC8::NewL(host8->Length() + port.Length() + 1); + host->Des().Zero(); + host->Des().Append(*host8); + host->Des().Append(UpnpString::KColon()); + host->Des().Append(port); + + CleanupStack::PopAndDestroy(host8); + + return host; + } + +// ----------------------------------------------------------------------------- +// UpnpString::TrimLC +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +EXPORT_C HBufC8* TrimLC(const TDesC8& aBuf, TBool aQuotations) + { + if( aBuf.Length() == 0 ) + { + return aBuf.AllocLC(); + } + TPtrC8 ptr(aBuf); + + while( ( ('"' == ptr[0]) && aQuotations ) || + (' ' == ptr[0]) ) + { + if(ptr.Length() == 1) + { + return HBufC8::NewLC(0); + } + ptr.Set(ptr.Mid(1)); + } + while( ( ('"' == ptr[ptr.Length() - 1] ) && aQuotations ) || + (' ' == ptr[ptr.Length() - 1] ) ) + { + ptr.Set(ptr.Left(ptr.Length() -1)); + } + + return ptr.AllocLC(); + } + +// ----------------------------------------------------------------------------- +// UpnpString::DeleteArray +// Empties the array and deletes the referenced objects. +// ----------------------------------------------------------------------------- +// +void DeleteArray(TAny* param) + { + RPointerArray* array; + + array = reinterpret_cast*>(param); + array->ResetAndDestroy(); + } + + // ----------------------------------------------------------------------------- + // UpnpString::ReplaceHttpCharacters + // ----------------------------------------------------------------------------- + // +EXPORT_C void ReplaceHttpCharacters(TDes8& aString) + { + TInt i=-1; + while(++i < aString.Length()) + { //check if it is "%" and that the length from this position is at least + //3 = length of "%" HEX HEX + if( (aString[i] == '%') && (aString.Length() >= i+3) ) + { + TLex8 lexer(aString.Mid(i+1, KUrlCharNoLen-1)); // two characters next to '%' + TUint8 charNo; + if(lexer.Val(charNo, EHex) == KErrNone ) + { + TText8 c(charNo); + TPtrC8 charDes(&c, KOneCharLen); + aString.Replace(i, KUrlCharNoLen, charDes); + } + } + } + } + +// ----------------------------------------------------------------------------- +// UpnpString::ReplaceHttpCharactersL +// ----------------------------------------------------------------------------- +// +EXPORT_C void ReplaceHttpCharactersL(TDes& aString) + { + HBufC8* temp8 = FromUnicodeL(aString); + CleanupStack::PushL(temp8); + TPtr8 tempPtr(temp8->Des()); + ReplaceHttpCharacters(tempPtr); + + HBufC* temp16 = ToUnicodeL(tempPtr); + aString.Copy(*temp16); + delete temp16; + CleanupStack::PopAndDestroy(temp8); + } + +} +// End of file