[STOCK] Url encode stock

For scripting examples for learning how to use AMXX.
User avatar
Archive-Poster
Posts: 1267
Gender:
United States of America

[STOCK] Url encode stock

Post by Archive-Poster »

Sometimes you need to encode parameters before send it to an http server.

For example you might want to do this:

Code: Select all

GET /some/script.php?parameter=Hello world!!!~
But server will get only this:

Code: Select all

GET /some/script.php?parameter=Hello
How to fix that? Encode parameters values following some rules (spaces, non-printable characters, etc).

Here's a stock that makes this work for you

Code: Select all

new const sHexTable[] = "0123456789abcdef"

stock urlencode(const sString[], sResult[], len)
{
    new from, c
    new to

    while(from < len)
    {
        c = sString[from++]
        if(c == 0)
        {
            sResult[to++] = c
            break
        }
        else if(c == ' ')
        {
            sResult[to++] = '+'
        }
        else if((c < '0' && c != '-' && c != '.') ||
                (c < 'A' && c > '9') ||
                (c > 'Z' && c < 'a' && c != '_') ||
                (c > 'z'))
        {
            if((to + 3) > len)
            {
                sResult[to] = 0
                break
            }
            sResult[to++] = '%'
            sResult[to++] = sHexTable[c >> 4]
            sResult[to++] = sHexTable[c & 15]
        }
        else
        {
            sResult[to++] = c
        }
    }
} 
How to use?

Code: Select all

public somefunc()
{
    new source[64] = "Hello ~ world!"
    new output[128]

    urlencode(source, output, charsmax(output)
    server_print("original= %s", output)
    server_print("encoded= %s", source)
} 
And you will get

Code: Select all

original= Hello ~ world!
encoded= Hello+%7e+world!
Then you can use encoded value to add to your GET/POST request.
Nice, yesterday I was having problem with System.Web.Server.URLEncode and I create my func.

But your func work better than my. I will update :P
I copied the function from php source code.
You have urlencode function in php.
I have Http Solution also in .NET.

Yep, I see that function in a PHP Forum.
User avatar
Archive-Poster
Posts: 1267
Gender:
United States of America

Re: [STOCK] Url encode stock

Post by Archive-Poster »

I wrote one awhile ago but never thought anyone would need it.
Yours actually has an error where you can exceed the "len" parameter in the output string.

Code: Select all

stock StringURLEncode( const szInput[ ], szOutput[ ], const iLen )
{
    static const HEXCHARS[ 16 ] = {
        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
        0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66
    };
    
    new iPos, cChar, iFLen;
    while( ( cChar = szInput[ iPos ] ) && iFLen < iLen )
    {
        if( cChar == 0x20 )
        {
            szOutput[ iFLen++ ] = 0x2B;
        }
        else if( !( 0x41 <= cChar <= 0x5A )
        && !( 0x61 <= cChar <= 0x7A )
        && !( 0x30 <= cChar <= 0x39 )
        && cChar != 0x2D
        && cChar != 0x2E
        && cChar != 0x5F )
        {
            if( ( iFLen + 3 ) > iLen )
            {
                break;
            }
            else if( cChar > 0xFF
            || cChar < 0x00 )
            {
                cChar = 0x2A;
            }
            
            szOutput[ iFLen++ ] = 0x25;
            szOutput[ iFLen++ ] = HEXCHARS[ cChar >> 4 ];
            szOutput[ iFLen++ ] = HEXCHARS[ cChar & 15 ];
        }
        else
        {
            szOutput[ iFLen++ ] = cChar;
        }
        
        iPos++;
    }
    
    szOutput[ iFLen ] = 0;
    return iFLen;
}
User avatar
Archive-Poster
Posts: 1267
Gender:
United States of America

Re: [STOCK] Url encode stock

Post by Archive-Poster »

I'm particularly interested in these two lines:

Code: Select all

            sResult[to+1] = sHexTable[c >> 4]
            sResult[to+2] = sHexTable[c & 15] 
I understand that >> is an arithmetic shift to the right of c by 4 bits, as described in the Pawn Language Guide Pg. 106.
I understand that & is a bitwise logical "and" as described in the Pawn Language Guide Pg. 107.

Code: Select all

1,000s  |                     1           
Hundreds|                     0521        
Tens    |                     2152621     
Units   |                     42684368421 
________|_______________________________________
         00000000000000000000000001111110 ( 126)| ASCII Charater '~'.
     SAR 00000000000000000000000000000100 (   4)| Signed Arithmetic Left (By 4).
       = 00000000000000000000000000000111 (   7)|
         --------------------------------=======+ 
         00000000000000000000000001111110 ( 126)| ASCII Charater '~'.
     AND 00000000000000000000000000001111 (  15)| Bitwise logical AND: 126 & 15.
       = 00000000000000000000000000001110 (  14)| sHexTable[14] = e.
That's pretty cool!
User avatar
Archive-Poster
Posts: 1267
Gender:
United States of America

Re: [STOCK] Url encode stock

Post by Archive-Poster »

Yeah, it's a pretty way to get:

Code: Select all

sResult[to+1] = sHexTable[c >> 4]
4 most significant bits (left nibble)

Code: Select all

sResult[to+2] = sHexTable[c & 15]
4 least significant bits (right nibble)
User avatar
Archive-Poster
Posts: 1267
Gender:
United States of America

Re: [STOCK] Url encode stock

Post by Archive-Poster »

shouldn't you terminate the string if you don't have the extra 3 spots for the encoding?

Code: Select all

            if( ( iFLen + 3 ) > iLen )
            {
                break;
            }
-->

Code: Select all

            if( ( iFLen + 3 ) > iLen )
            {
                szOutput[ iFLen ] = 0;
                break;
            }
User avatar
Archive-Poster
Posts: 1267
Gender:
United States of America

Re: [STOCK] Url encode stock

Post by Archive-Poster »

I have a little question...

I don't understand this simple thing in the code:

condition(c < 'a') for example... how a character can be MORE than other character? i need to reference by the alphabet? B > A? or what?
When you reference 'a' with single quotes that means you are referencing the ASCII decimal value of that letter.
User avatar
Archive-Poster
Posts: 1267
Gender:
United States of America

Re: [STOCK] Url encode stock

Post by Archive-Poster »

You should take a look on an ascii table to understand char to number conversion

ASCII_Table

A = 65
..
Z = 90

a = 97
..
z = 122
Yes i know, i didnt think that when using a simple character 'a' is refering to the ASCII decimal character...

Thanks
Note that "a" is not the same as 'a'
So... "a" is a string and 'a' is a character refering a decimal character in the ASCII table = 97, right?
"a" is an array (string)

"a" = { 'a', 0 } = { 97, 0 }

'a' is an integer

'a' = 97
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest