150 lines
3 KiB
Text
150 lines
3 KiB
Text
*process source xref attributes or(!);
|
|
lzwt: Proc Options(main);
|
|
|
|
Dcl (LEFT,LENGTH,SUBSTR,TRANSLATE,TRIM,UNSPEC) Builtin;
|
|
Dcl SYSPRINT Print;
|
|
|
|
Dcl str Char(50) Var Init('TOBEORNOTTOBEORTOBEORNOT');
|
|
Dcl compressed Char(80) Var;
|
|
Dcl decompressed Char(80) Var;
|
|
|
|
Dcl 1 dict(0:300),
|
|
2 key Char(5) Var,
|
|
2 inx Bin Fixed(16) Unsigned;
|
|
Dcl dict_size Bin Fixed(31) Init(256);
|
|
Dcl hi Bin Fixed(16) Unsigned Init(65535);
|
|
|
|
Put Edit('str=',str)(Skip,a,a);
|
|
compressed = compress(str);
|
|
Put Edit(compressed)(Skip,a);
|
|
decompressed = decompress(compressed);
|
|
Put Edit('dec=',decompressed)(Skip,a,a);
|
|
If decompressed=str Then
|
|
Put Edit('decompression ok')(Skip,a);
|
|
Else
|
|
Put Edit('decompression not ok')(Skip,a);
|
|
|
|
compress: Proc(s) Returns(Char(80) Var);
|
|
Dcl s Char(*) Var;
|
|
Dcl res Char(80) Var;
|
|
Dcl i Bin Fixed(31);
|
|
Dcl c Char(1);
|
|
Dcl w Char(5) Var;
|
|
Dcl wc Char(5) Var;
|
|
dict.key='';
|
|
Dcl ii Bin Fixed(8) Unsigned;
|
|
Do i=0 To 255;
|
|
ii=i;
|
|
Unspec(c)=unspec(ii);
|
|
dict.key(i)=c;
|
|
dict.inx(i)=i;
|
|
End;
|
|
res='[';
|
|
w='';
|
|
Do i=1 To length(s);
|
|
c=substr(s,i,1);
|
|
wc=w!!c;
|
|
If dicti(wc)^=hi Then Do;
|
|
w=wc;
|
|
End;
|
|
Else Do;
|
|
res=res!!trim(dicti(w))!!', ';
|
|
Call dict_add(wc,dict_size);
|
|
w=c;
|
|
End;
|
|
End;
|
|
If w^='' Then
|
|
res=res!!trim(dicti(w))!!', ';
|
|
substr(res,length(res)-1,1)=']';
|
|
Return(res);
|
|
|
|
dicti: Proc(needle) Returns(Bin Fixed(31));
|
|
Dcl needle Char(*) Var;
|
|
Dcl i Bin Fixed(31);
|
|
Do i=1 To dict_size;
|
|
If dict.key(i)=needle Then
|
|
Return(i);
|
|
End;
|
|
Return(hi);
|
|
End;
|
|
|
|
dict_add: Proc(needle,dict_size);
|
|
Dcl needle Char(*) Var;
|
|
Dcl dict_size Bin Fixed(31);
|
|
dict.key(dict_size)=needle;
|
|
dict.inx(dict_size)=dict_size;
|
|
dict_size+=1;
|
|
End;
|
|
|
|
End;
|
|
|
|
decompress: Proc(s) Returns(Char(80) Var);
|
|
Dcl s Char(80) Var;
|
|
Dcl ss Char(80) Var;
|
|
Dcl words(50) Char(5) Var;
|
|
Dcl wn Bin Fixed(31);
|
|
Dcl ww Bin Fixed(31);
|
|
Dcl c Char(1);
|
|
Dcl entry Char(5) Var;
|
|
Dcl w Char(5) Var;
|
|
Dcl res Char(80) Var;
|
|
ss=translate(s,' ','[],');
|
|
Call mk_words(ss,words,wn);
|
|
dict.key='';
|
|
dict.inx=hi;
|
|
Dcl i Bin Fixed(31);
|
|
Dcl ii Bin Fixed(8) Unsigned;
|
|
Dcl dict(0:300) Char(5) Var;
|
|
Dcl dict_size Bin Fixed(31);
|
|
Do i=0 To 255;
|
|
ii=i;
|
|
Unspec(c)=unspec(ii);
|
|
dict(i)=c;
|
|
End;
|
|
dict_size=256;
|
|
ww=words(1);
|
|
w=dict(ww);
|
|
res=w;
|
|
Do i=2 To wn;
|
|
ww=words(i);
|
|
Select;
|
|
When(dict(ww)^='')
|
|
entry=dict(ww);
|
|
When(ww=dict_size)
|
|
entry=w!!substr(w,1,1);
|
|
Otherwise
|
|
Put Edit('Bad compressed k: ',ww)(Skip,a,a);
|
|
End;
|
|
res=res!!entry;
|
|
dict(dict_size)=w!!substr(entry,1,1);
|
|
dict_size+=1;
|
|
w=entry;
|
|
End;
|
|
Return(res);
|
|
End;
|
|
|
|
mk_words: Proc(st,arr,arrn);
|
|
Dcl st Char(*) Var;
|
|
Dcl sv Char(80) Var;
|
|
Dcl arr(*) Char(5) Var;
|
|
Dcl arrn Bin fixed(31);
|
|
Dcl elem Char(5) Var;
|
|
arrn=0;
|
|
sv=st!!' ';
|
|
elem='';
|
|
Do While(length(sv)>0);
|
|
If left(sv,1)=' ' Then Do;
|
|
If elem>'' Then Do;
|
|
arrn+=1;
|
|
arr(arrn)=elem;
|
|
elem='';
|
|
End;
|
|
End;
|
|
Else
|
|
elem=elem!!left(sv,1);
|
|
sv=substr(sv,2);
|
|
End;
|
|
End;
|
|
Return;
|
|
|
|
End;
|