diff -r 000000000000 -r 8e480a14352b messagingfw/msgcommonutils/src/msgtextutils.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/messagingfw/msgcommonutils/src/msgtextutils.cpp Mon Jan 18 20:36:02 2010 +0200 @@ -0,0 +1,950 @@ +/* +* Copyright (c) 2006-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: +* Miscellaneous text related utility methods. +* +*/ + + + +// ========== INCLUDE FILES ================================ + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include "msgtextutils.h" + +// ========== LOCAL CONSTANTS AND MACROS =================== + +/* Reddy - Moved ot header +// Default charsets +const TUint KDefaultCharConvCharset = KCharacterSetIdentifierAscii; +const TUint KDefaultMIBCharset = KCharacterSetMIBEnumUsAscii; +*/ + +const TInt KMaxSampleLengthForAutoDetection = 512; +const TInt KCharsetPluginArrayGranularity = 10; + +const TUint KCharParagraphSeparator = 0x2029; +const TUint KCharLineFeed = 0x0a; +const TUint KCharCarriageReturn = 0x0d; +const TUint KCharAsciiDot = 0x2e; +const TUint KCharAsciiMax = 0x7f; + +const TInt KMaxFileNameLength = 8; // must be at least 4! +const TInt KMaxFileExtensionLenght = 5; // includes dot +const TInt KMaxFileTotalLength = 12; + +_LIT8( KReplaceChar8, "_" ); +_LIT16( KReplaceChar16, "_" ); + +// ========== MEMBER FUNCTIONS ============================= + + +// --------------------------------------------------------- +// CMsgTextUtils::NewL +// --------------------------------------------------------- +// +EXPORT_C CMsgTextUtils* CMsgTextUtils::NewL( RFs& aFs ) + { + CMsgTextUtils* data = new ( ELeave ) CMsgTextUtils( aFs ); + CleanupStack::PushL( data ); + data->ConstructL(); + CleanupStack::Pop(); + return data; + } + + +// --------------------------------------------------------- +// CMsgTextUtils::CMsgTextUtils +// +// Constructor +// --------------------------------------------------------- +// +CMsgTextUtils::CMsgTextUtils( RFs& aFs ) + : iFs( aFs ) + { + } + + +// --------------------------------------------------------- +// CMsgTextUtils::ConstructL +// --------------------------------------------------------- +// +void CMsgTextUtils::ConstructL() + { + // Nothing to do. Reserved for future use. + } + +// --------------------------------------------------------- +// CMsgTextUtils::~CMsgTextUtils +// +// Destructor. +// --------------------------------------------------------- +// +CMsgTextUtils::~CMsgTextUtils() + { + delete iCharConv; + } + +// --------------------------------------------------------- +// CMsgTextUtils::ConvertToBuffer8LC +// +// --------------------------------------------------------- +// +EXPORT_C HBufC8* CMsgTextUtils::ConvertToBuffer8LC( + const TDesC& aText, + TUint aCharacterSetIdentifier ) + { + TInt origLength = aText.Length(); + TInt maxLength = origLength; + HBufC8* resultBuffer = HBufC8::NewLC( maxLength ); + if ( !iCharConv ) + { + iCharConv = CCnvCharacterSetConverter::NewL(); + } + + if ( iCharConv->PrepareToConvertToOrFromL( aCharacterSetIdentifier, iFs ) != + CCnvCharacterSetConverter::EAvailable ) + { + User::Leave( KErrNotSupported ); + } + + iCharConv->SetReplacementForUnconvertibleUnicodeCharactersL( KReplaceChar8 ); + + TBuf8<40> outputBuffer; + TPtrC16 remainderOfUnicode( aText ); + + FOREVER + { + const TInt doneAll = iCharConv->ConvertFromUnicode( outputBuffer, remainderOfUnicode ); + + if ( doneAll == CCnvCharacterSetConverter::EErrorIllFormedInput ) + { + User::Leave( KErrCorrupt ); + } + else if ( doneAll < 0 ) + { + // For future expansion of errors + User::Leave( KErrGeneral ); + } + else + { // lint + } + + // Make sure outputBuffer fits into resultBuffer + while ( resultBuffer->Length() + outputBuffer.Length() > maxLength ) + { + // Increase resultBuffer length by origLength + maxLength += origLength; + resultBuffer = resultBuffer->ReAllocL( maxLength ); + CleanupStack::Pop(); // resultBuffer + CleanupStack::PushL(resultBuffer); + } + // Append to result + resultBuffer->Des().Append( outputBuffer ); + + if ( doneAll == 0 ) + { + return resultBuffer; // All converted + } + + remainderOfUnicode.Set( remainderOfUnicode.Right( doneAll )); + } + } + +// --------------------------------------------------------- +// CMsgTextUtils::ConvertToBuffer16LC +// +// --------------------------------------------------------- +// +EXPORT_C HBufC* CMsgTextUtils::ConvertToBuffer16LC( + const TDesC& aText, + TUint aCharacterSetIdentifier ) + { + HBufC8* resultBuffer = ConvertToBuffer8LC( aText, aCharacterSetIdentifier ); + + HBufC* finalresult = HBufC::NewL( resultBuffer->Length() ); + finalresult->Des().Copy( *resultBuffer ); + CleanupStack::PopAndDestroy(); // resultbuffer + CleanupStack::PushL( finalresult ); + + return finalresult; + } + +// --------------------------------------------------------- +// CMsgTextUtils::ConvertToFileL +// +// --------------------------------------------------------- +// +EXPORT_C void CMsgTextUtils::ConvertToFileL( + const TDesC& aText, + RFile& aFile, + TUint aCharacterSetIdentifier ) + { + // Takes ownership of "aFile". + RFileWriteStream writer( aFile ); + writer.PushL(); + + if ( !iCharConv ) + { + iCharConv = CCnvCharacterSetConverter::NewL(); + } + + if ( iCharConv->PrepareToConvertToOrFromL( aCharacterSetIdentifier, iFs ) + != CCnvCharacterSetConverter::EAvailable ) + { + User::Leave( KErrNotSupported ); + } + + iCharConv->SetReplacementForUnconvertibleUnicodeCharactersL( KReplaceChar8 ); + + TBuf8<128> outputBuffer; + TPtrC16 remainderOfUnicodeText( aText ); + FOREVER + { + TInt doneAll = iCharConv->ConvertFromUnicode( + outputBuffer, remainderOfUnicodeText ); + if ( doneAll == CCnvCharacterSetConverter::EErrorIllFormedInput ) + { + User::Leave( KErrCorrupt ); + } + else if ( doneAll < 0 ) // future-proof against "TError" expanding + { + User::Leave( KErrGeneral ); + } + else + { // lint + } + + writer.WriteL( outputBuffer ); + + if ( doneAll == 0 ) + { + // All of aText has been converted and handled + writer.CommitL(); + writer.Pop(); + writer.Close(); + return; + } + remainderOfUnicodeText.Set( remainderOfUnicodeText.Right( doneAll ) ); + } + } + +// --------------------------------------------------------- +// CMsgTextUtils::CharconvIdToMibIdL +// +// --------------------------------------------------------- +// +EXPORT_C TUint CMsgTextUtils::CharconvIdToMibIdL( TUint aCharconvCharsetId ) + { + // Switch-case is here for performance optimization + TUint charset = 0; + switch ( aCharconvCharsetId ) + { + case 0: + // Symbian OS native charset + charset = KCharacterSetMIBEnumIso10646Ucs2; + break; + case KCharacterSetIdentifierAscii: + charset = KCharacterSetMIBEnumUsAscii; + break; + case KCharacterSetIdentifierUtf8: + charset = KCharacterSetMIBEnumUtf8; + break; + case KCharacterSetIdentifierIso88591: + charset = KCharacterSetMIBEnumISO_8859_1; + break; + case KCharacterSetIdentifierIso88592: + charset = KCharacterSetMIBEnumISO_8859_2; + break; + case KCharacterSetIdentifierIso88593: + charset = KCharacterSetMIBEnumISO_8859_3; + break; + case KCharacterSetIdentifierIso88594: + charset = KCharacterSetMIBEnumISO_8859_4; + break; + case KCharacterSetIdentifierIso88595: + charset = KCharacterSetMIBEnumISO_8859_5; + break; + case KCharacterSetIdentifierIso88596: + charset = KCharacterSetMIBEnumISO_8859_6; + break; + case KCharacterSetIdentifierIso88597: + charset = KCharacterSetMIBEnumISO_8859_7; + break; + case KCharacterSetIdentifierIso88598: + charset = KCharacterSetMIBEnumISO_8859_8; + break; + case KCharacterSetIdentifierIso88599: + charset = KCharacterSetMIBEnumISO_8859_9; + break; + case KCharacterSetIdentifierIso885910: + charset = KCharacterSetMIBEnumISO_8859_10; + break; + case KCharacterSetIdentifierIso885913: + charset = KCharacterSetMIBEnumISO_8859_13; + break; + case KCharacterSetIdentifierIso885914: + charset = KCharacterSetMIBEnumISO_8859_14; + break; + case KCharacterSetIdentifierIso885915: + charset = KCharacterSetMIBEnumISO_8859_15; + break; + case KCharacterSetIdentifierUtf7: + charset = KCharacterSetMIBEnumUtf7; + break; + case KCharacterSetIdentifierCodePage1252: + charset = KCharacterSetMIBEnumCodePage1252; + break; + // Chinese charsets + case KCharacterSetIdentifierGb2312: + charset = KCharacterSetMIBEnumGb2312; + break; + case KCharacterSetIdentifierHz: + charset = KCharacterSetMIBEnumHz; + break; + case KCharacterSetIdentifierGbk: + charset = KCharacterSetMIBEnumGbk; + break; + case KCharacterSetIdentifierBig5: + charset = KCharacterSetMIBEnumBig5; + break; + // Japanese charsets + case KCharacterSetIdentifierShiftJis: + charset = KCharacterSetMIBEnumShiftJis; + break; + case KCharacterSetIdentifierIso2022Jp: + charset = KCharacterSetMIBEnumIso2022Jp; + break; + case KCharacterSetIdentifierJis: + charset = KCharacterSetMIBEnumJis; + break; + case KCharacterSetIdentifierEucJpPacked: + charset = KCharacterSetMIBEnumEucJpPacked; + break; + default: + { + if ( !iCharConv ) + { + iCharConv = CCnvCharacterSetConverter::NewL(); + } + charset = iCharConv->ConvertCharacterSetIdentifierToMibEnumL( + aCharconvCharsetId, iFs ); + if ( charset == 0 ) + { + charset = KDefaultMIBCharset; + } + break; + } + } + return charset; + } + +// --------------------------------------------------------- +// CMsgTextUtils::MibIdToCharconvIdL +// +// --------------------------------------------------------- +// +EXPORT_C TUint CMsgTextUtils::MibIdToCharconvIdL( TUint aMibId ) + { + // Switch-case is here for performance optimization + TUint charset = 0; + switch ( aMibId ) + { + case KCharacterSetMIBEnumIso10646Ucs2: + case KCharacterSetMIBEnumUTF16: + //no conversion for Unicode + charset = 0; + break; + case KCharacterSetMIBEnumUTF16BE: + charset = KCharacterSetIdentifierUnicodeBig; + break; + case KCharacterSetMIBEnumUTF16LE: + charset = KCharacterSetIdentifierUnicodeLittle; + break; + case KCharacterSetMIBEnumUsAscii: + charset = KCharacterSetIdentifierAscii; + break; + case KCharacterSetMIBEnumUtf8: + charset = KCharacterSetIdentifierUtf8; + break; + case KCharacterSetMIBEnumISO_8859_1: + charset = KCharacterSetIdentifierIso88591; + break; + case KCharacterSetMIBEnumISO_8859_2: + charset = KCharacterSetIdentifierIso88592; + break; + case KCharacterSetMIBEnumISO_8859_3: + charset = KCharacterSetIdentifierIso88593; + break; + case KCharacterSetMIBEnumISO_8859_4: + charset = KCharacterSetIdentifierIso88594; + break; + case KCharacterSetMIBEnumISO_8859_5: + charset = KCharacterSetIdentifierIso88595; + break; + case KCharacterSetMIBEnumISO_8859_6: + charset = KCharacterSetIdentifierIso88596; + break; + case KCharacterSetMIBEnumISO_8859_7: + charset = KCharacterSetIdentifierIso88597; + break; + case KCharacterSetMIBEnumISO_8859_8: + charset = KCharacterSetIdentifierIso88598; + break; + case KCharacterSetMIBEnumISO_8859_9: + charset = KCharacterSetIdentifierIso88599; + break; + case KCharacterSetMIBEnumISO_8859_10: + charset = KCharacterSetIdentifierIso885910; + break; + case KCharacterSetMIBEnumISO_8859_13: + charset = KCharacterSetIdentifierIso885913; + break; + case KCharacterSetMIBEnumISO_8859_14: + charset = KCharacterSetIdentifierIso885914; + break; + case KCharacterSetMIBEnumISO_8859_15: + charset = KCharacterSetIdentifierIso885915; + break; + case KCharacterSetMIBEnumUtf7: + charset = KCharacterSetIdentifierUtf7; + break; + case KCharacterSetMIBEnumCodePage1252: + charset = KCharacterSetIdentifierCodePage1252; + break; + // Chinese charsets + case KCharacterSetMIBEnumGb2312: + charset = KCharacterSetIdentifierGb2312; + break; + case KCharacterSetMIBEnumHz: + charset = KCharacterSetIdentifierHz; + break; + case KCharacterSetMIBEnumGbk: + charset = KCharacterSetIdentifierGbk; + break; + case KCharacterSetMIBEnumBig5: + charset = KCharacterSetIdentifierBig5; + break; + // Japanese charsets + case KCharacterSetMIBEnumShiftJis: + charset = KCharacterSetIdentifierShiftJis; + break; + case KCharacterSetMIBEnumIso2022Jp: + charset = KCharacterSetIdentifierIso2022Jp; + break; + case KCharacterSetMIBEnumJis: + charset = KCharacterSetIdentifierJis; + break; + case KCharacterSetMIBEnumEucJpPacked: + charset = KCharacterSetIdentifierEucJpPacked; + break; + default: + { + if ( !iCharConv ) + { + iCharConv = CCnvCharacterSetConverter::NewL(); + } + charset = iCharConv->ConvertMibEnumOfCharacterSetToIdentifierL( aMibId, iFs ); + if ( charset == 0 ) + { + charset = KDefaultCharConvCharset; + } + break; + } + } + return charset; + } + +// --------------------------------------------------------- +// ConvertParagraphSeparatorsLC +// --------------------------------------------------------- +// +EXPORT_C HBufC* CMsgTextUtils::ConvertParagraphSeparatorsLC( const TDesC& aText ) + { + TInt position; + TPtrC ptr; + + TInt numberOfSeparators = 0; + + position = 0; + ptr.Set( aText.Mid( 0 ) ); + while ( position != KErrNotFound && position < aText.Length() ) + { + ptr.Set( ptr.Mid( position ) ); + position = ptr.Locate( TChar( KCharParagraphSeparator ) ); + if ( position != KErrNotFound ) + { + numberOfSeparators++; + position++; // point past separator just found + } + } + + HBufC* convertedText = HBufC::NewLC( aText.Length() + numberOfSeparators ); + ptr.Set( aText.Mid( 0 ) ); + TInt start = 0; + position = aText.Locate( TChar( KCharParagraphSeparator ) ); + while ( position != KErrNotFound && start < aText.Length() ) + { + ptr.Set( aText.Mid( start ) ); + position = ptr.Locate( TChar( KCharParagraphSeparator ) ); + if ( position != KErrNotFound ) + { + convertedText->Des().Append( ptr.Left( position ) ); + convertedText->Des().Append( TChar( KCharCarriageReturn ) ); + convertedText->Des().Append( TChar( KCharLineFeed ) ); + start = start + position + 1; // point past separator + } + } + // append what is left after last separator has been found + if ( start < aText.Length() ) + { + convertedText->Des().Append( aText.Mid( start ) ); + } + + return convertedText; + } + +// --------------------------------------------------------- +// CMsgTextUtils::TrimAndRemoveNonAlphaDigit +// +// NOTE: This is intended for small strings. With long +// strings if could be more efficient to to seek replacable +// chars than to loop thru every char. +// --------------------------------------------------------- +// +EXPORT_C void CMsgTextUtils::TrimAndRemoveNonAlphaDigit( TDes& aString ) + { + aString.Trim(); + for (TInt i = aString.Length(); --i >= 0 ;) + { + TChar c = (TChar) aString[i]; + // Allow dots i.e. "." because they are allowed in URI and + // because filename are created from content-location + // so this will result to "filename.txt" instead of "filename_txt" + if ( aString[i] > KCharAsciiMax || + ( aString[i] != KCharAsciiDot && !c.IsAlphaDigit() ) ) + { + aString.Replace( i, 1, KReplaceChar16 ); + } + } + } + +// --------------------------------------------------------- +// UTF8Size +// --------------------------------------------------------- +// +EXPORT_C TInt CMsgTextUtils::UTF8Size( TPtrC aText ) + { + TInt count = 0; + TInt sizeInBytes = 0; + TUint16 charValue; + while ( count < aText.Length() ) + { + charValue = aText[count]; + if ( charValue < 0x80 ) + { + sizeInBytes += 1; + } + else if ( charValue < 0x800 ) + { + sizeInBytes += 2; + } + else //if ( charValue < 0x10000 ) + { + sizeInBytes += 3; + } + count++; + } + return sizeInBytes; + } + +// --------------------------------------------------------- +// ConvertLineBreaksL +// --------------------------------------------------------- +// +EXPORT_C void CMsgTextUtils::ConvertLineBreaksL( CRichText& aText, TInt aMode ) + { + if ( aMode & ECRLFtoLF ) + { + DoConvertCRLFL( aText ); + } + } + +// --------------------------------------------------------- +// DoConvertCRLFL +// --------------------------------------------------------- +// +void CMsgTextUtils::DoConvertCRLFL( CRichText& aText ) + { + TInt i( 0 ); + TInt documentLength( aText.DocumentLength() ); + + while ( i < documentLength ) + { + if ( aText.Read( i, 1 ).Locate( KCharCarriageReturn ) != KErrNotFound ) + { + if ( i < documentLength - 1 && + aText.Read( i + 1, 1 ).Locate( KCharLineFeed ) != KErrNotFound ) + { + // "CR+LF" -> "LF" + aText.DeleteL( i, 1 ); + documentLength--; + } + } + i++; + } + } + +// ----------------------------------------------------------------------------- +// RecognizeCharSetL +// ----------------------------------------------------------------------------- +// +EXPORT_C TUint CMsgTextUtils::RecognizeCharSetL( RFs& aFs, RFile& aFile ) + { + TUint charSet( 0 ); + + HBufC8* sample = HBufC8::NewLC( KMaxSampleLengthForAutoDetection ); + TPtr8 sampleDes = sample->Des(); + + TInt fileSize( 0 ); + User::LeaveIfError( aFile.Size( fileSize ) ); + User::LeaveIfError( aFile.Read( 0, sampleDes, fileSize > sampleDes.MaxLength() + ? sampleDes.MaxLength() + : fileSize ) ); + + + // Check for Byte Order Mark (BOM) + // U+FEFF ZERO WIDTH NON-BREAKING SPACE + // + // (from www.unicode.org FAQ) + // - FE FF -> UTF-16, big-endian + // - FF FE -> UTF-16, little-endian + // + if ( !sampleDes.Length() || + ( sampleDes.Size() >= 2 && + ( ( sampleDes[0] == 0xfe && sampleDes[1] == 0xff ) || + ( sampleDes[0] == 0xff && sampleDes[1] == 0xfe ) ) ) ) + { + // Zero means no conversion + charSet = 0; + } + else + { + const CArrayFix* availableSets = + CCnvCharacterSetConverter::CreateArrayOfCharacterSetsAvailableLC( aFs ); + + CArrayFix* toDetectSets = + new ( ELeave ) CArrayFixFlat( KCharsetPluginArrayGranularity ); + CleanupStack::PushL( toDetectSets ); + + const TInt count( availableSets->Count() ); + for ( TInt i( 0 ); i < count; i++ ) + { + switch ( availableSets->At( i ).Identifier() ) + { + case KCharacterSetIdentifierSms7Bit: + // remove Sms7Bit from charset list + break; + default: + toDetectSets->AppendL( availableSets->At( i ) ); + break; + } + } + + TUint resultCharset( 0 ); + TInt confidence( 0 ); + CCnvCharacterSetConverter::AutoDetectCharacterSetL( + confidence, resultCharset, *toDetectSets, sampleDes ); + charSet = resultCharset; + + CleanupStack::PopAndDestroy( 2 ); // availableSets, toDetectSets + } + CleanupStack::PopAndDestroy( sample ); + TInt seekPos(0); + aFile.Seek( ESeekStart, seekPos ); + return charSet; + } + +// --------------------------------------------------------- +// GetSafeAttachmentNameLC +// --------------------------------------------------------- +// +EXPORT_C HBufC* CMsgTextUtils::GetSafeAttachmentNameLC( + MMsvAttachmentManager& aManager, + const TDesC& aFileName, + TMsvAttachmentId aAttachmentId, + TBool aContentLocation ) + { + TBuf name; + TBuf ext; + TBuf candidate; + TParsePtrC parse( aFileName ); + + ext.Copy( parse.Ext().Left( KMaxFileExtensionLenght ) ); + CMsgTextUtils::TrimAndRemoveNonAlphaDigit( ext ); + + TInt nameLen = Min( KMaxFileNameLength, + ( KMaxFileTotalLength - ext.Length() ) ); + name.Copy( parse.Name().Left( nameLen ) ); + CMsgTextUtils::TrimAndRemoveNonAlphaDigit( name ); + + candidate.Copy( name ); + candidate.Append( ext ); + + TBool safeFound = EFalse; + TInt count = aManager.AttachmentCount(); + TInt i = 0; + while ( !safeFound && i < count ) + { + safeFound = ETrue; + for ( TInt ii = 0; ii < count && safeFound; ii++ ) + { + CMsvAttachment* attachment = aManager.GetAttachmentInfoL( ii ); + CleanupStack::PushL( attachment ); + if ( aContentLocation ) + { + CMsvMimeHeaders* msvMime = CMsvMimeHeaders::NewLC(); + msvMime->RestoreL( *attachment ); + if ( attachment->Id() != aAttachmentId && + !candidate.CompareF( msvMime->ContentLocation() ) ) + { + safeFound = EFalse; + } + CleanupStack::PopAndDestroy( msvMime ); + } + else + { + if ( attachment->Id() != aAttachmentId && + !candidate.CompareF( attachment->AttachmentName() ) ) + { + safeFound = EFalse; + } + } + CleanupStack::PopAndDestroy( attachment ); + } + i++; + if ( !safeFound ) + { + name.Zero(); + name.Copy( parse.Name().Left( nameLen - 3 ) ); + CMsgTextUtils::TrimAndRemoveNonAlphaDigit( name ); + TBuf<3> num; + num.NumFixedWidth( i, EDecimal, 3 ); + name.Append( num ); + candidate.Zero(); + candidate.Copy( name ); + candidate.Append( ext ); + } + } + + // It is guaranteed that we always find a safe candidate: + // - either safeFound == ETrue, or + // - we've got "count + 1st" candidate while there are + // "count" existing attachments. + HBufC* safeFileName = candidate.AllocLC(); + return safeFileName; + } + +// --------------------------------------------------------- +// from: TBool CImRecvConvert::IsIllegalChar(const TUint aChar) +// --------------------------------------------------------- +// +LOCAL_C TBool IsIllegalChar(const TUint aChar) + { + return ( + aChar == '*' || + aChar == '\\' || + aChar == '<' || + aChar == '>' || + aChar == ':' || + aChar == '.' || + aChar == '"' || + aChar == '/' || + aChar == '|' || + aChar == '?' || + aChar == CEditableText::EParagraphDelimiter || + aChar == CEditableText::ELineBreak || + aChar < ' ' ); + } + +// --------------------------------------------------------- +// GetFileNameFromBuffer +// --------------------------------------------------------- +// +EXPORT_C void CMsgTextUtils::GetFileNameFromBuffer( + TFileName& aFileName, + const TDesC& aBuffer, + TInt aMaxLength, + const TDesC* aExt /*= NULL*/ ) + { + if ( aExt != NULL ) + { + aMaxLength -= aExt->Length(); + } + + TInt len = aBuffer.Length(); + TInt max = Min( len, aMaxLength ); + + //__ASSERT_DEBUG( max > 0, Panic( EMsgZeroLength ) ); + + aFileName.Zero(); + + TInt cc = 0; + TUint ch; + TUint ch1 = 0; + TBool spaces = EFalse; + for ( TInt i = 0; i < len && cc < max; i++ ) + { + ch = aBuffer[i]; + + // ignore spaces from beginning of the buffer until first + // non-space is encountered. + if ( !spaces && ch != ' ' ) + { + spaces = ETrue; + } + + if ( i > 0 ) + { + ch1 = aBuffer[i - 1]; + } + + // strip illegal chars away. + // checks also if previous and current chars are '.' + if ( spaces && ! IsIllegalChar( ch ) ) + { + if ( !( i > 0 && ch == '.' && ch1 == '.' ) ) + { + aFileName.Append( ch ); + cc++; + } + } + } + + aFileName.Trim(); + + // If filename is empty at this point, do not append extension either. + // Instead, empty filename is returned so that caller can use whatever + // default s/he has for it. + if ( aFileName.Length() > 0 && aExt != NULL ) + { + aFileName.Append( *aExt ); + } + } + +// --------------------------------------------------------- +// CMsgTextUtils::ConvertToUnicodeL +// Converts input 8-bit data buffer (in given foreign charset type) to unicode buffer. +// --------------------------------------------------------- +EXPORT_C HBufC16* CMsgTextUtils::ConvertToUnicodeL( const TDesC8& aText, TUint aCharacterSetIdentifier ) + { + TInt origLength = aText.Length(); + TInt maxLength = origLength; + + if ( !iCharConv ) + { + iCharConv = CCnvCharacterSetConverter::NewL(); + } + + //buffer to hold target data and return to caller + HBufC* resultBuffer = HBufC::NewL( maxLength ); + _LIT8( KReplaceChar8, "_" ); + + if ( iCharConv->PrepareToConvertToOrFromL( aCharacterSetIdentifier, iFs ) != + CCnvCharacterSetConverter::EAvailable ) + { + User::Leave( KErrNotSupported ); + } + + //TODO:: need to set endianess if required. + //TODO:: below line is not necessary i guess??? + //The missing character is simply replaced by the Unicode character which represents unknown characters (0xFFFD) + //iCharConv->SetReplacementForUnconvertibleUnicodeCharactersL( KReplaceChar8 ); + + TBuf16<40> outputBuffer; + TPtrC8 remainderOfinputBuf ( aText ); + //TODO: KStateDefault header include + TInt aState = 0; // KStateDefault; + + FOREVER + { + const TInt doneAll = iCharConv->ConvertToUnicode( outputBuffer, remainderOfinputBuf, aState ); + + if ( doneAll == CCnvCharacterSetConverter::EErrorIllFormedInput ) + { + User::Leave( KErrCorrupt ); + } + else if ( doneAll < 0 ) + { + // For future expansion of errors + User::Leave( KErrGeneral ); + } + else + { // lint + } + + // Make sure outputBuffer fits into resultBuffer + while ( resultBuffer->Length() + outputBuffer.Length() > maxLength ) + { + // Increase resultBuffer length by origLength + maxLength += origLength; + resultBuffer = resultBuffer->ReAllocL( maxLength ); + } + // Append to result + resultBuffer->Des().Append( outputBuffer ); + + if ( doneAll == 0 ) + { + /* Testing */ + /* start --- + resultBuffer = resultBuffer->ReAllocL( maxLength + 20); + resultBuffer->Des().Append(_L("Korean Enc:415-5434")); + ---- End */ + return resultBuffer; // All converted + } + //TODO:: set the buffer correctly w.r.t length, Remember this is HBUFC16 + remainderOfinputBuf.Set( remainderOfinputBuf.Right( doneAll )); + } + } + +// --------------------------------------------------------- +// CMsgTextUtils::ConvertPtrToDesC16 +// Converts input 8-bit data buffer to 16-bit data buffer. +// --------------------------------------------------------- +EXPORT_C void CMsgTextUtils::ConvertPtrToDesC16( const TDes8& aFromBuff8, TDes16& aToBuff16 ) + { + TInt i = 0; + TInt j = 0; + + aToBuff16.FillZ( aToBuff16.MaxSize()/2 ); //MaxSize returns in bytes, hence devide by 2 + while( j < (aFromBuff8.Length() - 1) ) + { + aToBuff16[i] = aFromBuff8[j++] & 0xff; // low byte + aToBuff16[i++] |= (aFromBuff8[j++] << 8); // high byte + } + aToBuff16.SetLength(i); + } + +// End of File