lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


> > "Markus Huber" <pulse@evolution.org>

> > Word= string.byte(Filehandle:read(1))*256
> >      +string.byte(Filehandle:read(1))

> > e.g. Word=Filehandle:read('w')

> "Björn De Meyer" <bjorn.demeyer@pandora.be>

> I guess that that would be unportable. On a big endian architecture,
> or reading from a file that is big-endian, ... Lua uses only ANSI C,
> so it cannot know anything about endianness.

But its possible to arrange a programmer useable distinguish between
little- and big-endian. If you read data from a file you should know
which type is used.

> "Peter Prade" <Peter.Prade@gmx.de>

> Well i'd say write a string.word() function, so you can then write:
> Word = string.word(Filehandle:read(2))

I think you are right. After sending my question I programmed a function
string.rbyte() to read individual bytes from a string and returning as
a integer number. But after many hours of spending grips to archive a
flexible, powerfull and Lua conform way we (a friend and I) came to this
result:

   function string.int(Bytes,String,Position,Endian)

-- Lua uses double-precision floating-point values defined with a
-- mantissa of 52 bits, this limits the useable range to 6 bytes

-- Bytes (number, optional); default is _INTSIZE
-- String (string)
-- Position (number, optional); default is 1; may be negative
-- Endian (string, optional); = 'little' or 'l'; default is _ENDIAN
--                            = 'big'    or 'b'
--                            = 'native' or 'n'


Defaults are:

   _INTSIZE=4
   _ENDIAN='n'


So this test generates this --> output

   print(string.int())                              --> nil
   print(string.int(''))                            --> nil
   print(string.int(        '\65'))                 --> nil
   print(string.int(2,    '\0\65'))                 --> 65

   _ENDIAN='b'

   print(string.int(2,    '\0\65'))                 --> 16640
   print(string.int(2,    '\0\65',       'little')) --> 65
   print(string.int(2,'----\0\65'    , 5         )) --> 16640
   print(string.int(2,    '\0\65----',-6         )) --> 16640
   print(string.int(2,    '\0\65----',-6,'little')) --> 65
   print(string.int(  '\129\0\0\129',    'l'     )) --> 2164260993
   print(string.int(  '\129\0\0\129',    'b'     )) --> 2164260993
   print(string.int(1,'\129\0\0\129',  4         )) --> 129
   print(string.int(2,'\129\0\0\129',  4,'l'     )) --> nil
   print(string.int(2,'\129\0\0\129',  4,'b'     )) --> nil
   print(string.int(0,'\129\0\0\129',  4,'b'     )) --> nil


The returned nil is very usefull in conjuction with filehandle:read() to
check the end of the file. This is an example to read the x and y image
size of an jpeg file:

   if string.sub(Filehandle:read(3),1,3)=='\255\216\255' then

      _INTSIZE,Memorize = 2,_INTSIZE

      Filehandle:seek('set',2)
      Data=string.int(Filehandle:read(2),'l')
      while Data~=65472 and Data~=nil do
         Data=string.int(Filehandle:read(2),'l')
         Filehandle:seek('cur',Data-2)
         Data=string.int(Filehandle:read(2),'l')
      end

      if Data~=nil then
         Type   = 'jpeg'
         Height = string.int(Filehandle:read(5),4,'l')
         Width  = string.int(Filehandle:read(2),'l')
      end

      _INTSIZE=Memorize

   end



Markus