While experimenting a little bit with C code to decode hex strings I came up 
with the following code:

    boolean hex2char(CSTRING hexData, size_t len, char *data)
    {
        if (len % 2 == 1)   // not an even number of hex characters
        {
            data[0]='\0';
            return false;
        }

        size_t dIdx=0;

        for (size_t i=0; i<len; )
        {
            char tmp='\0';
            switch (hexData[i++])
            {
            case '0':         break;
            case '1': tmp= 1; break;
            case '2': tmp= 2; break;
            case '3': tmp= 3; break;
            case '4': tmp= 4; break;
            case '5': tmp= 5; break;
            case '6': tmp= 6; break;
            case '7': tmp= 7; break;
            case '8': tmp= 8; break;
            case '9': tmp= 9; break;
            case 'A': tmp=10; break;
            case 'B': tmp=11; break;
            case 'C': tmp=12; break;
            case 'D': tmp=13; break;
            case 'E': tmp=14; break;
            case 'F': tmp=15; break;
            default:        // illegal character
                data[0]='\0';
                return false;
            }
            tmp<<=4;        // shift to high order nibble

            switch (hexData[i++])
            {
            case '0':           break;
            case '1': tmp |=  1; break;
            case '2': tmp |=  2; break;
            case '3': tmp |=  3; break;
            case '4': tmp |=  4; break;
            case '5': tmp |=  5; break;
            case '6': tmp |=  6; break;
            case '7': tmp |=  7; break;
            case '8': tmp |=  8; break;
            case '9': tmp |=  9; break;
            case 'A': tmp |= 10; break;
            case 'B': tmp |= 11; break;
            case 'C': tmp |= 12; break;
            case 'D': tmp |= 13; break;
            case 'E': tmp |= 14; break;
            case 'F': tmp |= 15; break;
            default:        // illegal character
                data[0]='\0';
                return false;
            }
            data[dIdx++]=tmp;
        }
        data[dIdx]='\0';
        return true;        // success
    }

    RexxRoutine1( RexxStringObject, cppX2C, CSTRING, hexData  )
    {
        size_t len=strlen(hexData);

        char *data=(char *) malloc (len+1);
        boolean res=hex2char(hexData,len,data);  // true, if translated; false, 
else

        if (res==false)
        {
            free(data);
            return NULLOBJECT;      // for now: do not return a result, evoking 
a runtime error 
        }

        RexxStringObject rso=context->String(data, len/2);
        free(data);

        return rso;
    }

Comparing the duration of x2c() with the above cppX2C() 1,000 times on a 512KB 
string (
xrange("00"x,"FF"x)~copies(1000)~c2x ) the implementation of hex2char() seems 
to be about 3,8 faster
than x2c(). (This was tested on Windows, 32-bit ooRexx.) Left the RexxRoutine1 
cppX2C() in the above
pasted code, such that you could double-check it by merely copying and pasting 
the above code and
test it for yourself.

---rony




_______________________________________________
Oorexx-devel mailing list
Oorexx-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/oorexx-devel

Reply via email to