[Back to MISC SWAG index] [Back to Main SWAG index] [Original]
{$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.
[Back to MISC SWAG index] [Back to Main SWAG index] [Original]