greatly simplified
(former project name: packed bits)
Code: Select all
/' -- bit-aligned read / write (up to 57 bits) - 2024 Feb 29
Why 57 ?
internal var b_offs can maximally represent an offset of 7:
00000001
that bit plus up to 7 more bytes = 57 bits
- dafhi
--------
updates documented at their locality
'/
''
'' -- bits printout .. MSB left
''
function sbin(p as any ptr, cBits as longint = 1) as string
static as string ret: ret = "" '' 2024 Feb 25
dim as long cbytes = (cbits + 7) \ 8
dim as ubyte ptr b = p + cbytes - 1
for j as long = 1 to cBytes
var s = ""
for i as long = 7 to 0 step -1
s += str((*b shr i) and 1)
next
ret += s + " "
b -= 1
next
return ret
end function
#define min( a, b) iif( (a)<(b), (a), (b) )
#define max( a, b) iif( (a)>(b), (a), (b) )
'' reduced text
#define dbl as double
function clamp( in dbl, hi dbl = 1, lo dbl = 0) dbl
return min( max(in, lo), hi ) '' 2023 June 12
End Function
' -- support
'
union uptrs '' i forget who suggested (avoids sus ptr)
as any ptr a
as ubyte ptr b
as ushort ptr sho
as ulong ptr l
as ulongint ptr li
As Single Ptr s
as double ptr d
End Union
namespace ba57 ' bit aligned read / write - 2024 Feb 29 - by dafhi
/' -- usage
dim as byte a(5)
ba57.pdata = @a(0)
ba57.wri valu, offs, cbits_0_to_57
var result = _
ba57.rea( offs, cbits_0_to_57 )
'/
'' support
dim as any ptr pdata
dim as ulongint b_offs, mask
dim as uptrs gp
sub _rw_common( bpos as ulongint, byref c as byte )
gp.a = pdata + bpos \ 8 '' integer divide
b_offs = bpos - (bpos \ 8) * 8
c = clamp( c, 57 )
mask = ( (1 shl c)-1 ) shl b_offs
'mask = ((culngint(1) shl c)-1) shl b_offs ' Feb 29
end sub
'' main functions
''
function rea( bitpos as ulongint, cbits as byte = 1 ) as ulongint
_rw_common bitpos, cbits
return (*gp.li and mask)shr b_offs
end function
sub wri( valu as ulongint, bitpos as ulongint, cbits as byte = 1 )
_rw_common bitpos, cbits
*gp.li xor= *gp.li and mask
*gp.li or= (valu shl b_offs)and mask
end sub
end namespace
''
'' Main
''
dim as ulongint a
ba57.pdata = @a
print " bit-aligned read / write"
print
print " wri"
var valu = -1
var offs = 7
var size = 2
ba57.wri valu, offs, size
'var data_size_in_bits = 5 * 8 ' Feb 29
var print_size_in_bits = 5 * 8
print sbin( @a, print_size_in_bits )
print " rea"
var result = ba57.rea( offs, print_size_in_bits - offs )
print sbin( @result, print_size_in_bits );
print " (from bit"; offs; ")"