# Re: [Oorexx-devel] An alternative algorithm for x2c()

```On 19.04.2019 13:09, Rick McGuire wrote:
> Well, you're missing all of the logic that allows for blanks at the
> boundaries and you're also
> assuming that you have an even number of digits to convert. If you remove all
> of the things that
> x2c() has to account for, then yes, you can do a faster conversion.```
```
OK, this version caters for illegal leading and trailing whitespace making sure
an even number of
digits gets processed; it is still appr. 4,8 faster than the current x2c:

/* A Rexx hex string may include any number of whitespace after even hex
characters, e.g.
"00 01   02"x
but no leading or trailing blanks like " 00 01   02 "x
*/
int64_t hex2char(RexxCallContext *rcc, CSTRING hexData, size_t len, char
*data)
{
// check for trailing whitespace
char tmp=(hexData[len-1]);      // get last character (must not be
whitespace)
if (tmp==' ' || tmp=='\t')
rcc->ThrowException1(93931, rcc->UnsignedInt64ToObject(len));

size_t dIdx=0;

for (size_t i=0; i<len; i++)
{

if      (hexData[i]>='0' && hexData[i]<='9') tmp=hexData[i]-'0';
else if (hexData[i]>='A' && hexData[i]<='F') tmp=hexData[i]-'A'+10;
else if (hexData[i]>='a' && hexData[i]<='f') tmp=hexData[i]-'a'+10;
else
{
if (dIdx==0 && (hexData[i]==' ' || hexData[i]=='\t') )
rcc->ThrowException1(93931, rcc->Int32ToObject(1));

if (hexData[i]==' ' || hexData[i]=='\t') continue; // skip on
whitespace

// illegal hex digit
char buf[64];
snprintf(buf, 64, "%c\0", hexData[i]);
rcc->ThrowException1(93933, rcc->NewStringFromAsciiz(buf));
}
tmp<<=4;    // shift to high order nibble
i++;        // position on next hex digit

if (i==len) // we are beyond the hex string and missing the second
hex digit
{
char buf[256];
pair starting with the character \"%c\" in position %zd is missing the second
rcc->ThrowException1(93900,rcc->NewStringFromAsciiz(buf));
}

if      (hexData[i]>='0' && hexData[i]<='9') tmp|=hexData[i]-'0';
else if (hexData[i]>='A' && hexData[i]<='F') tmp|=hexData[i]-'A'+10;
else if (hexData[i]>='a' && hexData[i]<='f') tmp|=hexData[i]-'a'+10;
else if (hexData[i]==' ' || hexData[i]=='\t')  // also whitespace
not allowed in between of a hex pair
rcc->ThrowException1(93931, rcc->UnsignedInt64ToObject(i));
else // illegal hex digit
{
char buf[64];
snprintf(buf, 64, "%c\0", hexData[i]);
rcc->ThrowException1(93933, rcc->NewStringFromAsciiz(buf));
}
data[dIdx++]=tmp;
}
data[dIdx]='\0';
return (int64_t)dIdx;            // return number or characters in data
}

RexxRoutine1( RexxStringObject, cppX2C, CSTRING, hexData  )
{
size_t len=strlen(hexData);
char *data=(char *) malloc (len+1);
int64_t res=(int64_t) hex2char(context, hexData,len,data);  // true, if
translated; false, else
RexxStringObject rso=context->String(data, (size_t) res);
free(data);
return rso;
}

Here the hexadecimal test strings checked against the x2c()-BIF and the above
hex2char():

.context~package~local~lineal="1234+6789|"~copies(7)

hexStrings=("Ab00ff00ff00ff12"                  , -
"Ab 00 ff 00 ff 00 ff 12"           , -
"AB  00  ff  00  ff  00  ff  12"    , -
"AB  00  ff  00  ff  00  ff  1"    , -    -- not ok: hex-digit
missing
"AB  00  ff  00  f   00  ff  12"    , -   -- not ok: whitespace
in wrong position (actually hex-digit missing)
"Ab  0 0  ff  00  ff  00  ff  12"   , -   -- not ok: pairs may
not contain whitespace
"Ab != 00  ff  00  ff  00  ff  12"  , -   -- not ok: illegal
characters "!="
"aB 0X 00  ff  00  ff  00  ff  12"  , -   -- not ok: illegal
characters "!="
"  aB  00  ff  00  ff  00  ff  12"  , -   -- not ok: leading
whitespace
"aB  00  ff  00  ff  00  ff  12  "  )     -- not ok: trailing
whitespace
do h over hexStrings
call testHexStringWithX2c    h
say
call testHexStringWithCppX2C h
say
say "="~copies(79)
end

The x2c()-BIF has two wrong error messages:

* the hexadecimal string "Ab  0 0  ff  00  ff  00  ff  12" has an illegal
whitespace in position
5, x2c() reports wrongly position 6 instead,

* the hexadecimal string "AB 00 ff 00 ff 00 ff 1" is an incomplete
digit missing), x2c() reprots wrongly: "/SYNTAX 93.931 Incorrect location
of whitespace
character in position 28 in hexadecimal string./"

Here a rexxtry.rex-script with two different error messages (both wrong):

G:\oorexx.tmp\enrico2\win32>rexxtry
REXX-ooRexx_5.0.0(MT)_32-bit 6.05 16 Apr 2019
rexxtry.rex lets you interactively try REXX statements.
Each string is executed when you hit Enter.
Enter 'call tell' for a description of the features.
Go on - try a few...            Enter 'exit' to end.

say "AB  00  ff  00  ff  00  ff  1"*x*
Oooops ! ... try again.     Invalid hexadecimal or binary string.
Only 0-9, a-f, A-F, and whitespace characters
are valid in a hexadecimal string; found " ".
rc = 15.3 ................................. rexxtry.rex on WindowsNT

say "AB  00  ff  00  ff  00  ff  1"~x2c
Oooops ! ... try again.     Incorrect call to method.
Incorrect location of whitespace character in
rc = 93.931 ............................... rexxtry.rex on WindowsNT

say x2c("AB  00  ff  00  ff  00  ff  1")
Oooops ! ... try again.     Incorrect call to method.
Incorrect location of whitespace character in
rc = 93.931 ............................... rexxtry.rex on WindowsNT

The above version reports "/SYNTAX 93.900 Hexadecimal string incomplete:
starting with the character "1" in position 29 is missing the second
make the problem clear to the user.

---

The new ThrowException*()-APIs are really *very* handy!

---rony

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