Contributor: GREG ESTABROOKS {$A+,B-,D-,E-,F-,I+,N-,O-,R-,S-,V+} program TestStringComp; uses TpTimer; (* TurboPower's public domain TpTimer unit. *) (* Run-Length-Encoded string compression. *) function fustRLEcomp(stIn : string) : string; var byCount, byStInSize, byStTempPos : byte; woStInPos : word; stTemp : string; begin fillchar(stTemp, sizeof(stTemp), 0); byCount := 1; byStTempPos := 1; woStInPos := 1; byStInSize := ord(stIn[0]); repeat if (woStInPos < byStInSize) and (stIn[woStInPos] = stIn[succ(woStInPos)]) and (byCount < $7F) then inc(byCount) else if (byCount > 3) then begin stTemp[byStTempPos] := #0; stTemp[(byStTempPos + 1)] := chr(byCount); stTemp[(byStTempPos + 2)] := stIn[woStInPos]; inc(stTemp[0], 3); inc(byStTempPos, 3); byCount := 1 end else begin move(stIn[succ(woStInPos - byCount)], stTemp[byStTempPos], byCount); inc(stTemp[0], byCount); inc(byStTempPos, byCount); byCount := 1 end; inc(woStInPos, 1) until (woStInPos > byStInSize); fustRLEcomp := stTemp end; (* Run-Length-Encoded string expansion. *) function fustRLEexp(stIn : string) : string; var byStInSize, byStTempPos : byte; woStInPos : word; stTemp : string; begin fillchar(stTemp, sizeof(stTemp), 0); byStInSize := ord(stIn[0]); byStTempPos := 1; woStInPos := 1; repeat if (stIn[woStInPos] <> #0) then begin stTemp[byStTempPos] := stIn[woStInPos]; inc(woStInPos, 1); inc(byStTempPos, 1); inc(stTemp[0], 1) end else begin fillchar(stTemp[byStTempPos], ord(stIn[succ(woStInPos)]), stIn[(woStInPos + 2)]); inc(byStTempPos, ord(stIn[succ(woStInPos)])); inc(stTemp[0], ord(stIn[succ(woStInPos)])); inc(woStInPos, 3) end until (woStInPos > byStInSize); fustRLEexp := stTemp end; (* 8 bit into 7 bit string compression. *) function fustComp87(stIn : string) : string; var stTemp : string; byLoop, byTempSize, byOffset : byte; begin if (stIn[0] < #255) then stIn[succ(ord(stIn[0]))] := #0; fillchar(stTemp, sizeof(stTemp), 0); byTempSize := ord(stIn[0]) shr 3; if ((ord(stIn[0]) mod 8) <> 0) then inc(byTempsize, 1); byOffset := 0; for byLoop := 1 to byTempSize do begin stTemp[(byOffset * 7) + 1] := chr( ( (ord(stIn[(byOffset * 8) + 1]) and $7F) shl 1) + ( (ord(stIn[(byOffset * 8) + 2]) and $40) shr 6) ); stTemp[(byOffset * 7) + 2] := chr( ( (ord(stIn[(byOffset * 8) + 2]) and $3F) shl 2) + ( (ord(stIn[(byOffset * 8) + 3]) and $60) shr 5) ); stTemp[(byOffset * 7) + 3] := chr( ( (ord(stIn[(byOffset * 8) + 3]) and $1F) shl 3) + ( (ord(stIn[(byOffset * 8) + 4]) and $70) shr 4) ); stTemp[(byOffset * 7) + 4] := chr( ( (ord(stIn[(byOffset * 8) + 4]) and $0F) shl 4) + ( (ord(stIn[(byOffset * 8) + 5]) and $78) shr 3) ); stTemp[(byOffset * 7) + 5] := chr( ( (ord(stIn[(byOffset * 8) + 5]) and $07) shl 5) + ( (ord(stIn[(byOffset * 8) + 6]) and $7C) shr 2) ); stTemp[(byOffset * 7) + 6] := chr( ( (ord(stIn[(byOffset * 8) + 6]) and $03) shl 6) + ( (ord(stIn[(byOffset * 8) + 7]) and $7E) shr 1) ); if (byOffset < 31) then stTemp[(byOffset * 7) + 7] := chr( ( ( ord(stIn[(byOffset * 8) + 7]) and $01) shl 7) + ( ord(stIn[(byOffset * 8) + 8]) and $7F) ) else stTemp[(byOffset * 7) + 7] := chr( ( ord(stIn[(byOffset * 8) + 7]) and $01) shl 7); inc(byOffset, 1) end; stTemp[0] := chr(((ord(stIn[0]) div 8) * 7) + (ord(stIn[0]) mod 8) ); fustComp87 := stTemp end; (* 7 bit into 8 bit string expansion. *) function fustExp78(stIn : string) : string; var stTemp : string; byOffset, byTempSize, byLoop : byte; begin fillchar(stTemp, sizeof(stTemp), 0); byTempSize := ord(stIn[0]) div 7; if ((ord(stIn[0]) mod 7) <> 0)then inc(byTempSize, 1); byOffset := 0; for byLoop := 1 to byTempSize do begin stTemp[(byOffset * 8) + 1] := chr( ord(stIn[(byOffset * 7) + 1]) shr 1); stTemp[(byOffset * 8) + 2] := chr( ( ( ord(stIn[(byOffset * 7) + 1]) and $01) shl 6) + ( ( ord(stIn[(byOffset * 7) + 2]) and $FC) shr 2) ); stTemp[(byOffset * 8) + 3] := chr( ( ( ord(stIn[(byOffset * 7) + 2]) and $03) shl 5) + ( ord(stIn[(byOffset * 7) + 3]) shr 3) ); stTemp[(byOffset * 8) + 4] := chr( ( ( ord(stIn[(byOffset * 7) + 3]) and $07) shl 4) + ( ord(stIn[(byOffset * 7) + 4]) shr 4) ); stTemp[(byOffset * 8) + 5] := chr( ( ( ord(stIn[(byOffset * 7) + 4]) and $0F) shl 3) + ( ord(stIn[(byOffset * 7) + 5]) shr 5) ); stTemp[(byOffset * 8) + 6] := chr( ( ( ord(stIn[(byOffset * 7) + 5]) and $1F) shl 2) + ( ord(stIn[(byOffset * 7) + 6]) shr 6) ); stTemp[(byOffset * 8) + 7] := chr( ( ( ord(stIn[(byOffset * 7) + 6]) and $3F) shl 1) + ( ord(stIn[(byOffset * 7) + 7]) shr 7) ); if (byOffset < 31) then stTemp[(byOffset * 8) + 8] := chr( (ord(stIn[(byOffset * 7) + 7]) and $7F) ); inc(byOffset, 1) end; stTemp[0] := chr( ( (ord(stIn[0]) div 7) * 8) + (ord(stIn[0]) mod 7) ); if (stTemp[ord(stTemp[0])] = #0) then dec(stTemp[0], 1); fustExp78 := stTemp end; var loStart, loStop : longint; stMy1, stMy2, stMy3 : string; (* Main program execution block. *) BEGIN (* Test string 1. *) stMy1 := '12345678901111111111123456789022222222221234567890' + '33333333331234567890444444444412345678905555555555' + '12345678906666666666123456789077777777771234567890' + '88888888881234567890999999999912345678900000000000' + '1234567890AAAAAAAAAA1234567890BBBBBBBBBB1234567890' + 'CCCCC'; (* Test string 2. *) { stMy1 := '12345678901234567890123456789012345678901234567890' + '12345678901234567890123456789012345678901234567890' + '12345678901234567890123456789012345678901234567890' + '12345678901234567890123456789012345678901234567890' + '12345678901234567890123456789012345678901234567890' + '12345'; } (* Test string 3. *) { stMy1 := '11111111111111111111111111111111111111111111111111' + '11111111111111111111111111111111111111111111111111' + '11111111111111111111111111111111111111111111111111' + '11111111111111111111111111111111111111111111111111' + '11111111111111111111111111111111111111111111111111' + '11111'; } loStart := ReadTimer; stMy2 := fustComp87(fustRLEcomp(stMy1)); loStop := ReadTimer; writeln(' Time to compress = ', ElapsedTimeString(loStart, loStop), ' ms'); loStart := ReadTimer; stMy3 := fustRLEexp(fustExp78(stMy2)); loStop := ReadTimer; writeln(' Time to expand = ', ElapsedTimeString(loStart, loStop), ' ms'); writeln; writeln(stMy1); writeln; writeln(stMy2); writeln; writeln(stMy3); writeln; if (stMy1 <> stMy3) then writeln(' Conversion Error') else writeln(' Conversion Match') END.