[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: simplify word handling (was: enhance fh:read?)
- From: Markus Huber <pulse@...>
- Date: Sat, 18 Jan 2003 14:44:51 +0100 (GMT)
> > "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