'=========================================================================== ' Subject: PACK/UNPACK STRING TO/FROM QUAD Date: 01-14-00 (03:11) ' Author: Don Schullian Code: PBCC ' Origin: d83@DASoftVSS.com Packet: PBCC.ABC '=========================================================================== $IF 0 ---------------------------- PowerBASIC/cc v2.0 ---| DASoft |------------------------------------------ ---------------------------- Code DATE: 2000-01-14 | FILE NAME STR2QUAD.bas | by | DIRECTORY | Don Schullian, Jr. ---------------------------- This code is placed into the Public Domain ------------------------------------------------------------------------- PURPOSE: pack and unpack strings into/from a QUAD integer PARMAS: TheString - A STRING of no more than 12 characters TheQuad - A QUAD integer that carries a packed string NOTE: The incoming string will be UCASEd and all characters other than the 26 letters of the alphabet and the SPACE will be discarded ------------------------------------------------------------------------- Similar routines to these were developed while I was building an anagram game. The speed difference in locating a word in list of 80,000 strings was prohibitive hence the use of QUAD integers. QUADs proved to be about 10 times faster than STRINGS. These QUADs are packed to hold up to 12 characters with 4 bits left over and sort alphabetically. One COULD use 3 of the left over bits as a flag and still maintain alphabetical order by shifting the QUAD left 3 bits and ORing the flag(s) onto the end then, when unpacking, remove the flag(s) first. These routines could come in handy to create index keys. PB/DOS users should make the following changes to the code: Change: LONGs to INTEGERs in all cases STRPTR to STRPTR32 in fString2Quad VARPTR to VARPTR32 in fQuad2String Remove: the following lines FUNCTION PBmain () FORMAT$ WAITKEY$ END FUNCTION N'joy, ____ _ ____ ____ _____ | _ \ / \ / ___) __ | ___)(_ _) Don Schullian | |_) / _ \ \____\/ \| _) | | d83@DASoftVSS.com |____//_/ \_\(____/\__/|_| |_| www.DASoftVSS.com ___________________________________ www.basicguru.com Vertical Software Solutions $ENDIF ' '------------------------------------------------------------------------------- ' FUNCTION fString2Quad(BYVAL TheString AS STRING) AS QUAD DIM C AS LOCAL LONG DIM Offset AS LOCAL LONG DIM S_ptr AS LOCAL BYTE PTR DIM Slen AS LOCAL LONG DIM TheQuad AS LOCAL QUAD Slen = MIN(12,LEN(TheString)) -1 ' length of string -1 IF Slen < 0 THEN EXIT FUNCTION ' nothing to do here S_ptr = STRPTR(TheString) ' set string pointer ' FOR Offset = 0 TO Slen ' once for each character C = @S_ptr[Offset] ' glean ASCii value from string SELECT CASE C ' convert ASCii value CASE 65 TO 90 : C = C - 64 ' already UPPER CASE CASE 97 TO 122 : C = C - 96 ' UCASE the value CASE = 32 : GOTO NoORing ' this is a space CASE ELSE : ITERATE ' not a valid character END SELECT ' TheQuad = (TheQuad OR C) ' OR the new value to the buffer NoORing: ' IF Offset = Slen THEN EXIT FOR ' SHIFT LEFT TheQuad, 5 ' NEXT ' ' IF Slen < 11 THEN ' C = 5 * ( 11 - Slen ) ' SHIFT LEFT TheQuad, C ' END IF ' ' FUNCTION = TheQuad ' RETURN PACKED STRING END FUNCTION ' '------------------------------------------------------------------------------- ' FUNCTION fQuad2String(BYVAL TheQuad AS QUAD) AS STRING DIM C AS LOCAL LONG DIM Offset AS LOCAL LONG DIM S_ptr AS LOCAL BYTE PTR DIM TheString AS LOCAL STRING * 12 IF TheQuad = 0 THEN EXIT FUNCTION ' nothing to do here S_ptr = VARPTR(TheString) ' set string pointer ' FOR Offset = 11 TO 0 STEP -1 ' unpack 12 characters C = (TheQuad AND 31) ' read value from 5 bits SHIFT RIGHT TheQuad, 5 ' move next 5 bits into line IF C > 0 THEN ' convert value into ASCii value @S_ptr[Offset] = C + 64 ' END IF ' NEXT ' ' FUNCTION = RTRIM$(TheString) ' RETURN THE UNPACKED STRING END FUNCTION ' '------------------------------------------------------------------------------- ' FUNCTION PBmain () ' remove this line for PB/DOS DIM L AS LOCAL LONG DIM Q(20) AS LOCAL QUAD DIM S(20) AS LOCAL STRING DIM X AS LOCAL LONG RANDOMIZE TIMER S(0) = "hello world" Q(0) = fString2Quad(S(0)) FOR X = 1 TO 20 L = RND(1,12) WHILE L > 0 S(X) = S(X) & CHR$(RND(65,90)) DECR L WEND Q(X) = fString2Quad(S(X)) NEXT ARRAY SORT S(0), COLLATE UCASE ARRAY SORT Q(0) FOR X = 0 TO 20 PRINT S(X); TAB(14); PRINT fQuad2String(Q(X)); TAB(28); PRINT FORMAT$(Q(X),"###,###,###,###,###,###,###") ' remove this line NEXT WAITKEY$ ' remove this line END FUNCTION ' remove this line