diff -r 4ce476e64c59 -r 8592a65ad3fb emailuis/emailui/src/FreestyleEmailUiHtmlViewerContainer.cpp --- a/emailuis/emailui/src/FreestyleEmailUiHtmlViewerContainer.cpp Wed Mar 31 21:08:33 2010 +0300 +++ b/emailuis/emailui/src/FreestyleEmailUiHtmlViewerContainer.cpp Wed Apr 14 15:42:15 2010 +0300 @@ -1373,7 +1373,6 @@ TInt maxlength = bodyBuf.MaxSize(); TInt position( 0 ); - TText previous = 0; TBool EndOfString( EFalse ); while ( !EndOfString ) @@ -1442,7 +1441,6 @@ i++; break; } - previous = ch; } position += segment.Length(); if ( ( bodyBuf.Length() - position ) <= 0 ) @@ -1504,252 +1502,69 @@ void CFsEmailUiHtmlViewerContainer::CreateHyperlinksFromUrlsL( RBuf& aSource ) { FUNC_LOG; - const TInt urlMaxLength = 2048; - _LIT( KHttp, "http://" ); - _LIT( KHttps, "https://"); - _LIT( KWww, "www."); - - TBool eos( aSource.Size() <= 0 ); - TInt position( 0 ); - TInt carryOverInc( 0 ); - TInt maxlength = aSource.Length(); - while ( !eos ) + const TInt searhCases( CFindItemEngine::EFindItemSearchURLBin ); + CFindItemEngine* itemEngine = CFindItemEngine::NewL( aSource, CFindItemEngine::TFindItemSearchCase( searhCases ) ); + CleanupStack::PushL ( itemEngine ); + if ( itemEngine->ItemCount() > 0 ) { - while ( carryOverInc >= aSource.MidTPtr( position ).Length() && aSource.Size() != 0 ) - { // Skip segments of overlapping url string - carryOverInc -= aSource.MidTPtr( position ).Length(); - position += aSource.MidTPtr( position ).Length(); - } + _LIT( KHttp, "http://" ); + _LIT( KUrlFormat, "%S" ); + _LIT( KUrlFormatWithHttp, "%S" ); - TPtr16 segment( aSource.MidTPtr( position ) ); - TLex16 lexSegment( segment ); - lexSegment.Inc( carryOverInc ); - carryOverInc = 0; + const TInt sourceLength( aSource.Length() ); + // Allocate enough space for the final result + aSource.ReAllocL( sourceLength + TotalLengthOfItems( *itemEngine ) + KUrlFormatWithHttp().Length() * itemEngine->ItemCount() ); + aSource.SetMax(); + // Organize buffer so that original data is in the back of the aSource + aSource.RightTPtr( sourceLength ).Copy( aSource.Left( sourceLength ) ); + // Set source to new original data's position + const TPtrC source( aSource.RightTPtr( sourceLength ) ); + // Set target to aSource's beginning + TPtr target( aSource.MidTPtr( 0 ) ); + // Reset length, we now have an empty buffer to fill + target.SetLength( 0 ); - while (!lexSegment.Eos()) + TInt currentSourcePosition( 0 ); + CFindItemEngine::SFoundItem item; + for ( TBool available( itemEngine->Item( item ) ); available; available = itemEngine->NextItem( item ) ) { - TPtrC nextToken( lexSegment.NextToken() ); - TInt foundAt( KErrNotFound ); - - // Find HTTP, HTTPS, or WWW link in CBufSeg segment of size 1024 bytes. - if ( ( ( foundAt = nextToken.FindC( KHttp ) ) != KErrNotFound ) || - ( ( foundAt = nextToken.FindC( KHttps ) ) != KErrNotFound ) || - ( ( foundAt = nextToken.FindC( KWww ) ) != KErrNotFound ) ) + target.Append( source.Mid( currentSourcePosition, item.iStartPos - currentSourcePosition ) ); + const TPtrC url( source.Mid( item.iStartPos, item.iLength ) ); + TPtrC format( KUrlFormat() ); + if ( url.FindF( KHttp() ) == KErrNotFound ) { - if ( !lexSegment.Eos() ) - { - if ( !foundAt ) - { // Token starts with http/https/www.x - TPtrC url; - TInt lineBreakPos( KErrNotFound ); - if ( ( lineBreakPos = nextToken.FindC( KHtmlLineBreak ) ) != KErrNotFound ) - { // Token contains html line break -> remove - url.Set( nextToken.Left( lineBreakPos ) ); - } - else - { - url.Set( nextToken ); - } - - if ( url.CompareC( KWww ) != KErrNone ) // if token=www., validate format - { // www.x - RBuf urlBuf; - TBool wwwLink( EFalse ); - if ( url.Left( KWww().Length() ).CompareF( KWww ) == 0 ) - { - wwwLink = ETrue; - //Hyperlinks beginning with www. needs http:// prefix - urlBuf.CreateL( KHtmlLinkTagWWW().Length() + url.Length() * 2 - + KHtmlLinkEndTag().Length() + KHtmlLineBreak().Length() + KHttp().Length() ); - } - else - { - urlBuf.CreateL( KHtmlLinkTag().Length() + url.Length() * 2 - + KHtmlLinkEndTag().Length() + KHtmlLineBreak().Length() ); - } - urlBuf.CleanupClosePushL(); - // Format html link - if ( wwwLink ) - { - urlBuf.AppendFormat( KHtmlLinkTagWWW, &KHttp, &url ); - } - else - { - urlBuf.AppendFormat( KHtmlLinkTag, &url ); - } - urlBuf.Append( url ); - urlBuf.Append( KHtmlLinkEndTag ); - if ( lineBreakPos != KErrNotFound ) - { // Add line break if removed earlier - urlBuf.Append( KHtmlLineBreak ); - } - //Test - TInt nextTokenLength = nextToken.Length(); - TInt segOffset = lexSegment.Offset(); - TInt urlLength = urlBuf.Length(); - - //Test - TInt offset = lexSegment.Offset() - nextToken.Length(); - TLexMark tokenMark; - // Move next character last token back - lexSegment.Inc( - nextToken.Length() ); - lexSegment.Mark( tokenMark ); - aSource.Delete( offset + position, nextToken.Length() ); - aSource.ReAlloc( maxlength + urlBuf.Length() ); - aSource.Insert( offset + position, urlBuf ); - segment.Set( aSource.MidTPtr( position ) ); - lexSegment.Assign( segment ); - // Set next character to the position of inserted hyperlink - lexSegment.UnGetToMark( tokenMark ); - - // If Max segment length is reached, set carry over value to - // properly set next character in following CBufSeg segment - if ( ( offset + urlBuf.Length() ) >= segment.Length() ) - { - carryOverInc = offset + urlBuf.Length() - segment.Length(); - while ( !lexSegment.Eos() ) - { // Set to segment's end - lexSegment.NextToken(); - } - } - else - { - lexSegment.Inc( urlBuf.Length() ); - } - - CleanupStack::PopAndDestroy( &urlBuf ); - } - } - } - else - // Next token is end of string, here we handle the last token of a segment - { - _LIT( KUrlEnd, "<" ); - - TInt endOfUrlPos( KErrNotFound ); - TText ch = segment[ segment.Length() - 1]; - RBuf url; - url.CreateL( urlMaxLength ); - url.CleanupClosePushL(); - - // Find if hyperlink ends within this segment boundaries - if ( ch == KSOH || ch == KCR || ch == KLF || ch == KHT || ch == KCharacterSpace ) - { - endOfUrlPos = nextToken.Length() - 1; - } - else if ( ( endOfUrlPos = nextToken.Right( KHtmlLineBreak().Length() ).Find( KUrlEnd ) ) != KErrNotFound ) - { - endOfUrlPos = nextToken.Length() - KHtmlLineBreak().Length() + endOfUrlPos; - } - else - { // Handle hyperlink spread in multiple segments - TInt nextPos = position; - TPtrC nextSegment( aSource.MidTPtr( nextPos ) ); - TLex lexNextSegment( nextSegment ); - TPtrC nextNextToken( nextToken ); - TBool firstPass( ETrue ); - - while ( endOfUrlPos == KErrNotFound || nextPos >= aSource.Length() ) - { - if ( ( url.Length() + nextNextToken.Length() ) > urlMaxLength ) - { // URL exceeds limit of 2K, do nothing - break; - } - - url.Append( nextNextToken ); - if ( ( nextSegment.Length() == nextNextToken.Length() ) || firstPass ) - { // Token takes up the whole segment, or first pass( first segment - // with last token where hyperlink does not end within segment's - // boundaries, move to next segment - nextPos += nextSegment.Length(); - nextSegment.Set( aSource.MidTPtr( nextPos ) ); - if( nextSegment.Length() == 0 ) - { - break; - } - lexNextSegment.Assign( nextSegment ); - nextNextToken.Set( lexNextSegment.NextToken() ); - if ( firstPass ) - { - firstPass = EFalse; - } - } - else - { // Last segment's token with hyperlink's end - if ( ( endOfUrlPos = url.Find( KHtmlLineBreak ) ) != KErrNotFound ) - { // Remove line break - url.Delete( endOfUrlPos, KHtmlLineBreak().Length() ); - endOfUrlPos = nextNextToken.Length() - KHtmlLineBreak().Length(); - } - else - { - endOfUrlPos = nextNextToken.Length(); - } - } - } - - if ( endOfUrlPos != KErrNotFound ) - { // Handle hyperlink that is within 2K limit - RBuf urlBuf; - TBool wwwLink( EFalse ); - - if ( url.Left( KWww().Length() ).CompareF( KWww ) == 0 ) - { - wwwLink = ETrue; - urlBuf.CreateL( KHtmlLinkTagWWW().Length() + url.Length() * 2 - + KHtmlLinkEndTag().Length() + KHtmlLineBreak().Length() + KHttp().Length() ); - } - else - { - urlBuf.CreateL( KHtmlLinkTag().Length() + url.Length() * 2 - + KHtmlLinkEndTag().Length() + KHtmlLineBreak().Length() ); - } - - urlBuf.CleanupClosePushL(); - // Format html link - if ( wwwLink ) - { - urlBuf.AppendFormat( KHtmlLinkTagWWW, &KHttp, &url ); - } - else - { - urlBuf.AppendFormat( KHtmlLinkTag, &url ); - } - - urlBuf.Append( url ); - urlBuf.Append( KHtmlLinkEndTag ); - urlBuf.Append( KHtmlLineBreak ); - - TInt offset = lexSegment.Offset() - nextToken.Length(); - // Remove hyperlink from the original message body - aSource.Delete( offset + position, url.Length() ); - // Insert html formated hyperlink - aSource.ReAlloc( maxlength + urlBuf.Length() ); - aSource.Insert( offset + position, urlBuf ); - segment.Set( aSource.MidTPtr( position ) ); - - // Set carry on value to mark where new token should start in following segment - carryOverInc = endOfUrlPos; - position = nextPos; - - CleanupStack::PopAndDestroy( &urlBuf ); - } - } - CleanupStack::PopAndDestroy( &url ); - } + format.Set( KUrlFormatWithHttp() ); } - } - position += segment.Length(); - if ( ( aSource.Length() - position ) <= 0 ) + HBufC* formatBuffer = HBufC::NewLC( format.Length() + url.Length() * 2 ); + formatBuffer->Des().Format( format, &url, &url ); + target.Append( *formatBuffer ); + CleanupStack::PopAndDestroy(); // formatBuffer + currentSourcePosition = item.iStartPos + item.iLength; + } + // Append characters that are left in buffer + if ( currentSourcePosition < sourceLength ) { - eos = ETrue; + target.Append( source.Mid( currentSourcePosition, sourceLength - currentSourcePosition ) ); } + aSource.SetLength( target.Length() ); } - - + CleanupStack::PopAndDestroy(); // itemEngine } +TInt CFsEmailUiHtmlViewerContainer::TotalLengthOfItems( CFindItemEngine& aItemEngine ) const + { + TInt totalLength( 0 ); + CFindItemEngine::SFoundItem item; + aItemEngine.ResetPosition(); + for ( TBool available( aItemEngine.Item( item ) ); available; available = aItemEngine.NextItem( item ) ) + { + totalLength += item.iLength; + } + aItemEngine.ResetPosition(); + return totalLength; + } + // --------------------------------------------------------------------------- // Get Character set from CFSMailMessagePart // ---------------------------------------------------------------------------