Re: boolean sequence
- Posted by "Juergen Luethje" <j.lue at gmx.de> Sep 08, 2004
- 460 views
Tone Skoda wrote: > oh i forgot to this, i would more like 1 as base index. Here is the code concerning bytes:
include misc.e -- for pretty_print() include bit.e -- Eu 2.4 or later required ------------------------------------------------------------------------ -- utility functions function ceil (object x) -- the opposite of floor() -- x may be an atom or a sequence return -floor(-x) end function ------------------------------------------------------------------------ -- types type sequence_of_long (object x) -- sequence consisting of 32-bit integers (signed or unsigned) object t if atom(x) then return 0 end if for i = 1 to length(x) do t = x[i] if (not atom(t)) or (t != floor(t)) or (t < -#80000000) or (#FFFFFFFF < t) then return 0 end if end for return 1 end type global type positive_int (object x) if integer(x) then return x > 0 end if return 0 end type type byte (object x) -- signed or unsigned byte if integer(x) then if -128 <= x then return x <= 255 end if end if return 0 end type ------------------------------------------------------------------------ -- * The following functions let us treat sequences consisting of an -- arbitrary number of 32-bit integers as huge "byte arrays". * -- Note: The lowest order byte is always indexed by 1. global function put_byte (sequence_of_long s, positive_int number, byte val) -- Store 'val' in the byte in 's', that is indexed by 'number'. -- It doesn't matter, whether 'val' is signed or unsigned -- (like with the built-in procedure poke4()). integer n n = ceil(number/4) if n > length(s) then return -1 -- error end if s[n] = or_bits(s[n], c_func( SHIFT_LEFT, {and_bits(val, #FF), remainder(number+3,4)*8} )) return s end function global function get_byte_u (sequence_of_long s, positive_int number) -- Return the byte in 's', that is indexed by 'number', as an -- *unsigned* value. integer n n = ceil(number/4) if n > length(s) then return {} -- error end if return and_bits(c_func( SHIFT_RIGHT, {s[n], remainder(number+3,4)*8} ), #FF) end function global function get_byte_s (sequence_of_long s, positive_int number) -- Return the byte in 's', that is indexed by 'number', as a -- *signed* value. integer n, val n = ceil(number/4) if n > length(s) then return {} -- error end if val = and_bits(c_func( SHIFT_RIGHT, {s[n], remainder(number+3,4)*8} ), #FF) if val > 127 then val -= 256 -- convert to signed end if return val end function global function find_byte_forward (sequence_of_long s, byte val) -- Return the number of the lowest order byte in 's', that is equal -- to 'val' (or return -1, if 'val' is not found). -- It doesn't matter, whether 'val' is signed or unsigned. atom t if val < 0 then val += 256 -- convert to unsigned end if for i = 1 to length(s) do t = s[i] for k = 1 to 4 do if and_bits(t, #FF) = val then return (i-1)*4 + k end if t = c_func( SHIFT_RIGHT, {t, 8} ) end for end for return -1 -- val not found end function global function find_byte_reverse (sequence_of_long s, byte val) -- Return the number of the highest order byte in 's', that is equal -- to 'val' (or return -1, if 'val' is not found). -- It doesn't matter, whether 'val' is signed or unsigned. atom t if val < 0 then val += 256 -- convert to unsigned end if for i = length(s) to 1 by -1 do t = s[i] for k = 4 to 1 by -1 do t = c_func( ROTATE_LEFT, {t, 8} ) if and_bits(t, #FF) = val then return (i-1)*4 + k end if end for end for return -1 -- val not found end function ------------------------------------------------------------------------ -- * Demo * -- object s sequence_of_long pattern sequence p positive_int numEls integer fn byte val fn = open("byte.txt", "w") numEls = 3 pattern = repeat(0, numEls) p = "0" for i = 1 to numEls-1 do p &= ",0" end for without warning -- no short-circuite warning, please for byteNo = 1 to numEls*4 + 1 do val = rand(256+128)-129 -- signed or unsigned byte [-128,255] s = put_byte(pattern, byteNo, val) printf(fn, "s = put_byte({%s}, %d, #%02x)", {p, byteNo, and_bits(val, #FF)}) puts(fn, "\n-> s = ") if sequence(s) then pretty_print(fn, s, {0,3,1,78,"#%08x","#%08x"}) if (val < 0 and val != get_byte_s(s, byteNo)) or (val >= 0 and val != get_byte_u(s, byteNo)) then puts(fn, "* Error *\n") end if printf(fn, "-> find_byte_forward(s, #%02x) = %d\n", {and_bits(val, #FF), find_byte_forward(s, val)}) printf(fn, "-> find_byte_reverse(s, #%02x) = %d\n", {and_bits(val, #FF), find_byte_reverse(s, val)}) else printf(fn, "%d\n", {s}) end if puts(fn, "\n") end for close(fn) puts(1, "finished")
Regards, Juergen