<GeeXLab Rootard Guide/>
Buffers
Last update: 2018.12.09 by JeGX
>> Back <<
From GeeXLab 0.26+ and zip file support, it is possible to map the contents of a file located in the zip archive to memory.
This file is represented by a simple buffer in memory and it is possible to access this buffer for reading and writing.
The principle was quickly extended to classic files (located on the file system). And finally the possibility to create
empty buffers has also been added (why not).
But why these new features? It is possible to do more or less the same thing in Lua and Python.
Indeed it is possible to create buffers in Lua and Python, to write and read them and save them in a file.
The fundamental reason for all these functions is the need to be able to access the content of any file located in a
zip archive. It all started from there. Python supports zip files but not Lua. The other reason is that these buffers
are directly accessible to the GeeXLab engine in C/C++. The principle can be extended to other data sources such as
vertex buffers for example.
All functions to manipulate memory buffers are available in the
gh_utils library (in Lua and Python).
Let's take a quick look at how to create a buffer from a file contained in a zip archive. The following example
shows how to create a memory buffer representing the
params.txt file stored in the
params.zip archive:
demo_dir = gh_utils.get_demo_dir()
zip_filename = demo_dir .. "params.zip"
filename = "params.txt"
ptr, size = gh_utils.zip_get_buffer(zip_filename, filename)
ptr is the access point to the memory buffer and
size is the size of the buffer in bytes.
Now that we have our memory buffer, we can read or write bytes in it using the following two functions:
buffer_read_byte
and
buffer_write_byte.
This is how to read the first two bytes:
offset = 0
x0 = gh_utils.buffer_read_byte(ptr, offset)
offset = 1
x1 = gh_utils.buffer_read_byte(ptr, offset)
This is how to write the first two bytes:
offset = 0
gh_utils.buffer_write_byte(ptr, offset, x0)
offset = 1
gh_utils.buffer_write_byte(ptr, offset, x1)
There is also a function that allows you to read a complete line. Useful for processing text files for example (init file...).
This is how to read the first line of the buffer:
offset = 0
line, line_len = gh_utils.buffer_read_line(ptr, size, offset)
line contains the first line of the buffer and
line_len is the size of the line including the line break character ('\n').
After using the buffer, you have to kill it:
gh_utils.zip_buffer_kill(ptr)
A buffer can also be created from a classic file:
filename = demo_dir .. "params.txt"
ptr, size = gh_utils.file_buffer_create
...
gh_utils.file_buffer_kill(ptr)
Finally, you can create an empty buffer by specifying its size:
ptr = gh_utils.buffer_create(1024)
...
gh_utils.buffer_kill(ptr)
Before destroying a buffer, it can be saved in a file:
demo_dir = gh_utils.get_demo_dir()
filename = demo_dir .. "buffer.txt"
if (gh_utils.buffer_to_file(ptr, size, filename) == 1)
-- OK
end
To finish the code of the demo download, which reads creates a buffer from a zip file and then reads
the buffer line by line:
local zip_filename = demo_dir .. "params.zip"
local filename = "params.txt"
ptr, size = gh_utils.zip_buffer_create(zip_filename, filename)
offset = 0
line, line_len = gh_utils.buffer_read_line(ptr, size, offset)
while (line_len > 0) do
gh_utils.trace(line)
offset = offset + line_len -- next line please!
line, line_len = gh_utils.buffer_read_line(ptr, size, offset)
end
gh_utils.zip_buffer_kill(ptr)