104 lines
2.8 KiB
Plaintext
104 lines
2.8 KiB
Plaintext
enum FN, V, BITS -- fields of a bitwiseioreader/writer
|
|
|
|
function new_bitwiseio(string filename, mode)
|
|
integer fn = open(filename,mode)
|
|
return {fn,0,0} -- ie {FN,V=0,BITS=0}
|
|
end function
|
|
|
|
function new_bitwiseiowriter(string filename)
|
|
return new_bitwiseio(filename,"wb")
|
|
end function
|
|
|
|
function new_bitwiseioreader(string filename)
|
|
return new_bitwiseio(filename,"rb")
|
|
end function
|
|
|
|
function write_bits(sequence writer, integer v, bits)
|
|
integer {fn,wv,wb} = writer,
|
|
p2 = power(2,bits), ch
|
|
if v!=and_bits(v,p2*2-1) then ?9/0 end if
|
|
wv = wv*p2+v
|
|
wb += bits
|
|
while wb>=8 do
|
|
wb -= 8
|
|
p2 = power(2,wb)
|
|
ch = floor(wv/p2)
|
|
puts(fn,ch)
|
|
wv -= ch*p2
|
|
end while
|
|
if wv>=#100 then ?9/0 end if
|
|
if wb>=8 then ?9/0 end if
|
|
writer[V]= wv
|
|
writer[BITS]= wb
|
|
return writer
|
|
end function
|
|
|
|
function close_bitwiseiowriter(sequence writer)
|
|
integer {fn,wv,wb} = writer
|
|
if wb then
|
|
if wb>=8 then ?9/0 end if -- sanity check
|
|
writer = write_bits(writer,0,8-wb)
|
|
end if
|
|
if writer[V]!=0 then ?9/0 end if
|
|
if writer[BITS]!=0 then ?9/0 end if
|
|
close(fn)
|
|
writer[FN]=-1
|
|
return writer
|
|
end function
|
|
|
|
function read_bits(sequence reader, integer bits)
|
|
integer {fn,rv,rb} = reader, ch, p2
|
|
while bits>rb do
|
|
ch = getc(fn)
|
|
if ch=-1 then return {-1,reader} end if
|
|
rv = rv*#100+ch
|
|
rb += 8
|
|
end while
|
|
rb -= bits
|
|
p2 = power(2,rb)
|
|
ch = floor(rv/p2)
|
|
rv -= ch*p2
|
|
reader[V]= rv
|
|
reader[BITS]= rb
|
|
return {ch,reader}
|
|
end function
|
|
|
|
function as_hexb(string s, fmt="%02x ")
|
|
-- helper funtion, returns hex string, or binary if fmt="%08b "
|
|
string res = ""
|
|
for i=1 to length(s) do
|
|
res &= sprintf(fmt,s[i])
|
|
end for
|
|
return trim(res)
|
|
end function
|
|
|
|
constant test = "This is a test."
|
|
--constant test = "This is a test"
|
|
--constant test = "abcdefghijk"
|
|
--constant test = "STRING"
|
|
--constant test = "This is an ascii string that will be crunched, written, read and expanded."
|
|
printf(1,"\"%s\" as bytes: %s (length %d)\n",{test,as_hexb(test),length(test)})
|
|
printf(1," original bits: %s\n",{as_hexb(test,"%08b ")})
|
|
|
|
sequence writer = new_bitwiseiowriter("test.bin")
|
|
for i=1 to length(test) do
|
|
writer = write_bits(writer,test[i],7)
|
|
end for
|
|
writer = close_bitwiseiowriter(writer)
|
|
|
|
integer fn = open("test.bin","rb")
|
|
string bytes = get_text(fn,GT_WHOLE_FILE)
|
|
printf(1,"Written bitstream: %s\n",{as_hexb(bytes,"%08b ")})
|
|
printf(1,"Written bytes: %s (length %d)\n",{as_hexb(bytes),length(bytes)})
|
|
close(fn)
|
|
|
|
sequence reader = new_bitwiseioreader("test.bin")
|
|
bytes = ""
|
|
integer ch
|
|
while true do
|
|
{ch,reader} = read_bits(reader,7)
|
|
if ch=-1 then exit end if
|
|
bytes &= ch
|
|
end while
|
|
printf(1,"\"%s\" as bytes: %s (length %d)\n",{bytes,as_hexb(bytes),length(bytes)})
|