I had to write a simple string compressor/decompressor for a database project that allows variable length records.
This is for user-input TEXT strings only, as the ASCII code 0 is being used arbitrarily as a "marker" for blocks
of duplicate characters that are compressed. Can anyone see where it could be made faster? (Please respond in the
Programming forum) Thanks.
[This message has been edited by Timm Motl (edited March 01, 2001).]
This is for user-input TEXT strings only, as the ASCII code 0 is being used arbitrarily as a "marker" for blocks
of duplicate characters that are compressed. Can anyone see where it could be made faster? (Please respond in the
Programming forum) Thanks.
Code:
#COMPILE EXE #REGISTER NONE #INCLUDE "Win32Api.Inc" GLOBAL BlockChar AS STRING FUNCTION Compress(Source AS STRING) AS STRING LOCAL LoopVar AS LONG LOCAL Compressed AS STRING LOCAL CurrChar AS STRING LOCAL CharCount AS LONG IF INSTR(Source, BlockChar) THEN EXIT FUNCTION ELSE CurrChar = MID$(Source, 1, 1) CharCount = 1 FOR LoopVar = 2 TO LEN(Source) + 1 IF MID$(Source, LoopVar, 1) <> CurrChar OR CharCount = 255 OR LoopVar = LEN(Source) + 1 THEN IF CharCount > 1 THEN IF CharCount > 3 THEN Compressed = Compressed + BlockChar + CHR$(CharCount) + CurrChar ELSE Compressed = Compressed + STRING$(CharCount, CurrChar) END IF CharCount = 1 ELSE Compressed = Compressed + CurrChar END IF CurrChar = MID$(Source, LoopVar, 1) ELSE INCR CharCount END IF NEXT END IF FUNCTION = Compressed END FUNCTION FUNCTION Decompress(Source AS STRING) AS STRING LOCAL Decompressed AS STRING LOCAL PrevSeekPos AS LONG LOCAL SeekPos AS LONG PrevSeekPos = 1 DO SeekPos = INSTR(SeekPos + 1, Source, BlockChar) IF SeekPos THEN Decompressed = Decompressed + MID$(Source, PrevSeekPos, SeekPos - PrevSeekPos) Decompressed = Decompressed + STRING$(ASC(MID$(Source, SeekPos + 1)), MID$(Source, SeekPos + 2)) PrevSeekPos = SeekPos + 3 ELSE Decompressed = Decompressed + MID$(Source, PrevSeekPos, LEN(Source) - (PrevSeekPos - 1)) EXIT DO END IF LOOP FUNCTION = Decompressed END FUNCTION FUNCTION PBMAIN LOCAL A AS STRING LOCAL B AS STRING LOCAL C AS STRING LOCAL Start AS DWORD LOCAL Finish AS DWORD BlockChar = CHR$(0) ' <--- Can be any ASCII code not likely to be in a text string (eg: 255) ' 64K test string A = "Sample " + STRING$(21835, "X") + " Text " + STRING$(21835, "Z") + " Compressor " + SPACE$(21835) + " ABCDE" Start = GetTickCount B = Compress(A) IF LEN(B) THEN C = Decompress(B) Finish = GetTickCount IF C = A THEN MSGBOX "Return string (" + TRIM$(STR$(LEN(C))) + " bytes) matches the source string!" + $CRLF + $CRLF +_ "Compressed AND Decompressed in " + FORMAT$((Finish - Start) / 1000, "#.###") + " seconds." ELSE MSGBOX "Oops! Return string did NOT match source string!" END IF ELSE MSGBOX "Source string was binary (contained a NULL ASCII character)" + $CRLF + $CRLF +_ "This routine is for text strings!" END IF END FUNCTION
Comment