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 { // check for leading whitespace 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]; snprintf(buf, 256, "Hexadecimal string incomplete: hexadecimal pair starting with the character \"%c\" in position %zd is missing the second hexadecimal digit\0", hexData[i-1], len); 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 hexadecimal string (last hex 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 position 28 in hexadecimal string. 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 position 28 in hexadecimal string. rc = 93.931 ............................... rexxtry.rex on WindowsNT The above version reports "/SYNTAX 93.900 Hexadecimal string incomplete: hexadecimal pair starting with the character "1" in position 29 is missing the second hexadecimal digit./" to 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