lua-users home
lua-l archive

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


Ignacio Castaño writes:

>I just noticed there aren't any functions for reading/writting binary files
>in the lua standard library, I would like to suggest the addition of them.
>Something like:

>fh:readb( "pattern", [num] )
>fh:writeb( "pattern", ... )

[snip]

It's not what you're asking for, but here's some functions that I've been
using (I prefer to use pure Lua).  They assume little-endian data, as that's
what we use.  You can easily change that if you like (or even add a flag).

It was originally written for Yindo, which has an ancient version of Lua.
I've changed the reading functions, but haven't tested the new version.  But
it used to work, and the changes were trivial.

byte and ubyte are signed and unsigned 8 bit.  shorts are 16 bit.  ints are
32 bit.  floats are single precision (32 bit).

function readubyte( file )
	local str = read( file, "1" )
	return strbyte( str, 1 )
end

function readbyte( file )
	local val = readubyte( file )
	if val >= 128 then
		val = val - 256
	end
	return val
end

function readushort( file )
	local str = read( file, "2" )
	return strbyte( str, 1 ) + 256*strbyte( str, 2 )
end

function readshort( file )
	local val = readushort( file )
	if val >= 128*256 then
		val = val - 256*256
	end
	return val
end

function readuint( file )
	local str = read( file, "4" )
	return strbyte( str, 1 ) + 256*strbyte( str, 2 ) + 
		256*256*strbyte( str, 3 ) + 256*256*256*strbyte( str, 4 )
end

function readint( file )
	local val = readuint( file )
	if val >= 128*256*256*256 then
		val = val - 256*256*256*256
	end
	return val
end

function readfloat( file )
	local int = readuint( file )
	local f = 1 + mod( int, 128*256*256 )/(128*256*256)
	local e = floor( int/(128*256*256) )
	local s
	if e > 256 then
		e = e - 256
		s = -1
	else
		s = 1
	end
	e = e - 127
	return s * f * 2^e
end

function writeubyte( file, value )
	local str = strchar( mod( value, 256 ) )
	write( file, str )
end

function writebyte( file, value )
	if value < 0 then
		value = value + 256
	end
	writeubyte( file, value )
end

function writeushort( file, value )
	writeubyte( file, mod( value, 256 ) )
	writeubyte( file, mod( floor( value / 256 ), 256 ) )
end

function writebyte( file, value )
	if value < 0 then
		value = value + 256*256
	end
	writeubyte( file, value )
end

function writeuint( file, value )
	writeushort( file, mod( value, 256*256 ) )
	writeushort( file, mod( floor( value / (256*256) ), 256*256 ) )
end

function writeint( file, value )
	if value < 0 then
		value = value + 256*256*256*256
	end
	writeubyte( file, value )
end

function writefloat( file, value )
	local s
	local e
	local f
	if value < 0 then
		s = 1
		value = -value
	else
		s = 0
	end
	e = floor( log( value ) / log( 2 ) )
	f = floor( ((value / 2^e) - 1) * 128*256*256 )
	e = e + 127
	local int = s*128*256*256*256 + e*128*256*256 + f
	writeuint( file, int )
end
-Virus scanned and cleared ok