public static String decodeString(String encoded,int offset,int length,String charset)
    {
        if (charset==null)
            charset=StringUtil.__ISO_8859_1;
        byte[] bytes=null;
        int n=0;
        
        for (int i=0;i<length;i++)
        {
            char c = encoded.charAt(offset+i);
            if (c<0||c>0xff)
                throw new IllegalArgumentException("Not encoded");
            
            if (c=='+')
            {
                if (bytes==null)
                {
                    bytes=new byte[length*2];
                    encoded.getBytes(offset, offset+i, bytes, 0);
                    n=i;
                }
                bytes[n++] = (byte) ' ';
            }
            else if (c=='%' && (i+2)<length)
            {
                byte b;
                char cn = encoded.charAt(offset+i+1);
                if (cn>='a' && cn<='z')
                    b=(byte)(10+cn-'a');
                else if (cn>='A' && cn<='Z')
                    b=(byte)(10+cn-'A');
                else
                    b=(byte)(cn-'0');
                cn = encoded.charAt(offset+i+2);
                if (cn>='a' && cn<='z')
                    b=(byte)(b*16+10+cn-'a');
                else if (cn>='A' && cn<='Z')
                    b=(byte)(b*16+10+cn-'A');
                else
                    b=(byte)(b*16+cn-'0');

                if (bytes==null)
                {
                    bytes=new byte[length*2];
                    encoded.getBytes(offset, offset+i, bytes, 0);
                    n=i;
                }
                i+=2;
                bytes[n++]=b;
            }
            else if (n>0)
                bytes[n++] = (byte) c;
        }

        if (bytes==null)
        {
            if (offset==0 && encoded.length()==length)
                return encoded;
            return encoded.substring(offset,offset+length);
        }
        
        try
        {
            return new String(bytes,0,n,charset);
        }
        catch (UnsupportedEncodingException e)
        {
            return new String(bytes,0,n);
        }
        
    }
public static String decodeString ( String encoded , int offset , int length , String charset ) { if ( charset == null ) charset = StringUtil . __ISO_8859_1 ; byte [ ] bytes = null ; int n = 0 ; for ( int i = 0 ; i < length ; i ++ ) { char c = encoded . charAt ( offset + i ) ; if ( c < 0 || c > 0xff ) throw new IllegalArgumentException ( "Not encoded" ) ; if ( c == '+' ) { if ( bytes == null ) { bytes = new byte [ length * 2 ] ; encoded . getBytes ( offset , offset + i , bytes , 0 ) ; n = i ; } bytes [ n ++ ] = ( byte ) ' ' ; } else if ( c == '%' && ( i + 2 ) < length ) { byte b ; char cn = encoded . charAt ( offset + i + 1 ) ; if ( cn >= 'a' && cn <= 'z' ) b = ( byte ) ( 10 + cn - 'a' ) ; else if ( cn >= 'A' && cn <= 'Z' ) b = ( byte ) ( 10 + cn - 'A' ) ; else b = ( byte ) ( cn - '0' ) ; cn = encoded . charAt ( offset + i + 2 ) ; if ( cn >= 'a' && cn <= 'z' ) b = ( byte ) ( b * 16 + 10 + cn - 'a' ) ; else if ( cn >= 'A' && cn <= 'Z' ) b = ( byte ) ( b * 16 + 10 + cn - 'A' ) ; else b = ( byte ) ( b * 16 + cn - '0' ) ; if ( bytes == null ) { bytes = new byte [ length * 2 ] ; encoded . getBytes ( offset , offset + i , bytes , 0 ) ; n = i ; } i += 2 ; bytes [ n ++ ] = b ; } else if ( n > 0 ) bytes [ n ++ ] = ( byte ) c ; } if ( bytes == null ) { if ( offset == 0 && encoded . length ( ) == length ) return encoded ; return encoded . substring ( offset , offset + length ) ; } try { return new String ( bytes , 0 , n , charset ) ; } catch ( UnsupportedEncodingException e ) { return new String ( bytes , 0 , n ) ; } }
Decode String with % encoding.
This method makes the assumption that the majority of calls
will need no decoding.