×

Discussion Board

Results 1 to 5 of 5
  1. #1
    Registered User
    Join Date
    Apr 2008
    Posts
    13

    Question String search and replace

    I have been making a method for finding a string in HBufC8 and replacing it with a new one.

    Code:
    void StringReplaceL(HBufC8& aText, 
    const TDesC8& aSearchString, 
    const TDesC8& aReplaceWith)
        {
        TInt searchLength = aSearchString.Length();
        TInt replaceLength = aReplaceWith.Length();
       
        TPtr8 textPtr = aText.Des();
    
        TInt pos = 0;
       
        pos = 0;
       
        while(pos != KErrNotFound)
            {
            pos = textPtr.Find( aSearchString );
            if(pos != KErrNotFound)
                {           
                //Expand the buffer to hold the new data    
                aText.ReAlloc(aText.Length() - searchLength  +  replaceLength);
                          
                textPtr = aText.Des();
                textPtr.Replace(pos, searchLength, aReplaceWith);
                }
            }
        }
    I'd like to get some feedback on possible problems with this code.

    a) It seems that the textPtr.Replace() sometimes causes buffer overflow.

    b) Calling ReAlloc() on all search results doesn't seem like a proper way to do it. I wasn't able to make a loop that would just count the results, as calling
    aText.Mid(pos).Find(aSearchString )
    Always returned me KErrNotFound, even with pos = 0;

    c) Is
    textPtr = aText.Des();
    Necessary after ReAlloc()?

    d) Is there ready example on how to do this efficiently?
    Last edited by Zilppuri; 2009-05-08 at 17:15.

  2. #2
    Nokia Developer Moderator
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    28,737

    Re: String search and replace

    a) it is documented in TDes16::Replace: you will get USER 11 if the result does not fit into the descriptor
    b,c) ReAlloc/L/C re-allocates the descriptor, thus its proper usage is aText=aText->ReAllocL(...).
    and after that change textPtr has to be re-initialized as well.
    because you have to modify address of aText itself, it should be HBufC &* (reference to a pointer)

  3. #3
    Registered User
    Join Date
    Apr 2008
    Posts
    13

    Re: String search and replace

    Thanks for your answer.

    The code is now as follows:

    Code:
    StringReplaceL(HBufC8*& aText, const TDesC8& aSearchString, const TDesC8& aReplaceWith ) 
    	{
    	TInt searchLength = aSearchString.Length();
    	TInt replaceLength = aReplaceWith.Length();
    	
            TPtr8 textPtr( aText->Des() );
    
            TInt pos = 0;
    	
    	while( pos != KErrNotFound )
    		{
    		pos = textPtr.Find( aSearchString );
    		if( pos != KErrNotFound )
    			{
    			//Expand the buffer to hold the new data     
    			aText = aText->ReAllocL(aText->Length() - searchLength +  replaceLength);		
    			textPtr = aText->Des();		
    		        textPtr.Replace(pos, searchLength, aReplaceWith);
    			}
    		}
    	}
    Unfortunately I still get USER 23 (Buffer overflow) in my test case.

    I have the following setup:

    Code:
    _LIT8(KSearchTest1, "#");
    _LIT8(KSearchTest2, "<img src=\"moo\">");
    		
    HBufC8* test = HBufC8::NewL(55);	
    TPtr8 ptr(test->Des());
    ptr.Append(_L("tests ##tests # tests"));
    
    StringReplaceL(test, KSearchTest1, KSearchTest2);
    It panics at the third "#" in HBufC8* test.

    Any idea why it happens?

  4. #4
    Nokia Developer Moderator
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    28,737

    Re: String search and replace

    = is a nasty thing
    Quote Originally Posted by SDK Help, TPtr8
    Copies data into this 8-bit modifiable pointer descriptor replacing any existing data.
    so textPtr is not updated. What you need is TPtr8::Set.

    However you can also rely on variable scope, and use the fact that Find works on read-only descriptors (like aText) too:
    Code:
    void StringReplaceL(HBufC8*& aText, const TDesC8& aSearchString, const TDesC8& aReplaceWith ) 
        {
        TInt searchLength = aSearchString.Length();
        TInt replaceLength = aReplaceWith.Length();
    
        TInt pos = 0;
    	
        while( pos != KErrNotFound )
            {
            pos = aText->Find( aSearchString );
            if( pos != KErrNotFound )
                {
                //Expand the buffer to hold the new data     
                aText = aText->ReAllocL(aText->Length() - searchLength +  replaceLength);		
                TPtr8 textPtr( aText->Des() );
                textPtr.Replace(pos, searchLength, aReplaceWith);
                }
            }
        }
    In fact textPtr is used in a single statement, thus it does not have to be a separate variable any more
    Code:
    void StringReplaceL(HBufC8*& aText, const TDesC8& aSearchString, const TDesC8& aReplaceWith ) 
    {
        TInt searchLength = aSearchString.Length();
        TInt replaceLength = aReplaceWith.Length();
    
        for(TInt pos = aText->Find(aSearchString); pos != KErrNotFound; pos = aText->Find(aSearchString))
        {
            aText = aText->ReAllocL(aText->Length() - searchLength +  replaceLength);		
            aText->Des().Replace(pos, searchLength, aReplaceWith);
        }
    }

  5. #5
    Registered User
    Join Date
    Apr 2008
    Posts
    13

    Re: String search and replace

    Thank you!

    Works like a charm
    Code:
    void StringReplaceL(HBufC8*& aText, const TDesC8& aSearchString, const TDesC8& aReplaceWith ) 
    {
        TInt searchLength = aSearchString.Length();
        TInt replaceLength = aReplaceWith.Length();
    
        for(TInt pos = aText->Find(aSearchString); pos != KErrNotFound; pos = aText->Find(aSearchString))
        {
            aText = aText->ReAllocL(aText->Length() - searchLength +  replaceLength);		
            aText->Des().Replace(pos, searchLength, aReplaceWith);
        }
    }

Similar Threads

  1. Find and replace in descriptor.
    By giedi1 in forum Symbian
    Replies: 2
    Last Post: 2009-02-20, 09:50
  2. REPLACE on Carbide
    By PACALA_BA in forum Carbide.c++ IDE and plug-ins (Closed)
    Replies: 5
    Last Post: 2008-07-19, 10:40
  3. Calling cards: Replace "+" with "00" in case of dialling contacts via DTMF
    By cgalli in forum General Development Questions
    Replies: 1
    Last Post: 2007-08-30, 22:01
  4. Personal
    By JSmith77 in forum PersonalJava
    Replies: 4
    Last Post: 2003-07-30, 12:52

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
×