Re: boolean sequence

new topic     » goto parent     » topic index » view thread      » older message » newer message

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

new topic     » goto parent     » topic index » view thread      » older message » newer message

Search



Quick Links

User menu

Not signed in.

Misc Menu