Not sure if it would be any faster, but maybe neater to simplify some of the
below along the lines of:
 
  case '0':
  case '1':
  case '2':
  case '3':
  case '4':
  case '5':
  case '6':
  case '7':
  case '8':
  case '9': tmp=hexData[i-1]-'0'; break;
 
(I'd also make the increments of i separate rather than a side-effect within
the switch .. but that's just a style issue.)
 
Mike
 
 


  _____  

From: Rony G. Flatscher [mailto:rony.flatsc...@wu.ac.at] 
Sent: 18 April 2019 17:04
To: Open Object Rexx Developer Mailing List
Subject: [Oorexx-devel] An alternative algorithm for x2c()



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