tech-userlevel archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[patch] Lua data library
Hi Folks,
I've implemented the core features of the Lua data library; the patch
is attached. Luadata provides C and Lua APIs to handle binary data
using Lua scripts. Here is a briefly description of those:
1. Lua API:
1.1 creation
- data.new(table)
Returns a new data object initialized with the given byte array. For example:
d1 = data.new{0xFF, 0xFE, 0x00} --> returns a data object with 3 bytes.
1.2 layout
- data.layout(table)
Returns a new layout table based on table argument, which should have
the following formats for its fields:
(i) field = {<offset>, <length> [, <endian>]} or
(ii) field = {offset = <offset>, length = <length> [endian = <endian>]}
Where, field is the name of the field, <offset> is the offset in bits
(MSB 0), <length> is the length in bits, endian is a string that
indicates the field endianness ('host', 'net', 'little', 'big'). The
default value for endian is 'big'.
Here are a couple examples:
(i) l1 = data.layout{msb = {0, 1}, uint32 = {0, 32}, uint64le = {0,
64, 'little'}}
(ii) l2 = data.layout{msb = {offset = 0, length = 1},
net_unaligned_uint16 = {offset = 1, length = 16, endian = 'net'}}
- d:layout(layout | table)
Applies a layout table on a given data object. If a regular table is
passed, it calls data.layout(table) first. For example:
d1:layout(l1) -- applies l1 layout into d1 data object
d2:layout{byte = {0, 8}} -- creates and applies a new layout into d2 data object
2. API C
2.1 creation
- int ldata_newref(lua_State *L, void *ptr, size_t size);
Creates a new data object pointing to ptr (without copying it), leaves
the data object on the top of the Lua stack and returns a reference
for it. The data object will not be garbage-collected until it is
unreferred.
2.2 deletion
- void ldata_unref(lua_State *L, int ref);
Removes the ptr from the data object and releases the data-object
reference, allowing it to be garbage-collected. After that, it is safe
to free the ptr pointer.
Regards,
--
Lourival Vieira Neto
Index: lib/lua/data/Makefile
===================================================================
RCS file: lib/lua/data/Makefile
diff -N lib/lua/data/Makefile
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ lib/lua/data/Makefile 17 Jan 2014 11:47:53 -0000
@@ -0,0 +1,9 @@
+LUA_MODULES= data
+
+LUA_SRCS.data= luadata.c
+LUA_SRCS.data+= data.c
+LUA_SRCS.data+= layout.c
+LUA_SRCS.data+= luautil.c
+LUA_SRCS.data+= binary.c
+
+.include <bsd.lua.mk>
Index: lib/lua/data/binary.c
===================================================================
RCS file: lib/lua/data/binary.c
diff -N lib/lua/data/binary.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ lib/lua/data/binary.c 17 Jan 2014 11:47:53 -0000
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 2013, 2014, Lourival Vieira Neto <lneto%NetBSD.org@localhost>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the Author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <limits.h>
+
+#include <sys/param.h>
+
+#include "binary.h"
+
+#define BYTE_MAX UCHAR_MAX
+#define UINT64_BIT (64)
+
+inline static void
+set_bits(uint64_t *value, uint64_t clear_mask, uint64_t set_mask)
+{
+ *value &= clear_mask;
+ *value |= set_mask;
+}
+
+#define CONTIGUOUS_BITS(widt, truncated) (width - truncated)
+
+static void
+expand(uint64_t *value, size_t width, size_t msb_offset, byte_t truncated)
+{
+ size_t contiguous = CONTIGUOUS_BITS(width, truncated);
+
+ size_t trunc_msb_offset = BYTE_BIT - truncated;
+ size_t trunc_lsb_offset = contiguous + trunc_msb_offset;
+
+ size_t clear_offset = msb_offset + truncated;
+
+ uint64_t clear_mask = UINT64_MAX >> clear_offset;
+ uint64_t trunc_mask = *value >> trunc_lsb_offset << contiguous;
+
+ set_bits(value, clear_mask, trunc_mask);
+}
+
+static void
+contract(uint64_t *value, size_t width, size_t msb_offset, byte_t truncated)
+{
+ size_t contiguous = CONTIGUOUS_BITS(width, truncated);
+
+ size_t trunc_lsb_offset = BYTE_BIT - truncated;
+ size_t trunc_msb_offset = contiguous + trunc_lsb_offset;
+
+ size_t clear_offset = msb_offset + truncated;
+
+ uint64_t clear_mask = UINT64_MAX << clear_offset;
+ uint64_t trunc_mask = *value << trunc_msb_offset >> contiguous;
+
+ set_bits(value, clear_mask, trunc_mask);
+}
+
+#define TRUNCATED_BITS(width) (width % BYTE_BIT)
+
+#define VALUE_MSB_OFFSET(width) (UINT64_BIT - width)
+
+static void
+swap_bytes_in(uint64_t *value, size_t width)
+{
+ size_t msb_offset = VALUE_MSB_OFFSET(width);
+
+ *value <<= msb_offset;
+
+ *value = bswap64(*value);
+
+ byte_t truncated = TRUNCATED_BITS(width);
+ if (truncated > 0)
+ expand(value, width, msb_offset, truncated);
+}
+
+static void
+swap_bytes_out(uint64_t *value, size_t width)
+{
+ size_t msb_offset = VALUE_MSB_OFFSET(width);
+
+ *value = bswap64(*value);
+
+ byte_t truncated = TRUNCATED_BITS(width);
+ if (truncated > 0)
+ contract(value, width, msb_offset, truncated);
+
+ *value >>= msb_offset;
+}
+
+#define MSB_OFFSET(offset) (offset % BYTE_BIT)
+
+#define LSB_OFFSET(width, msb_offset) \
+ MAX((ssize_t) (BYTE_BIT - msb_offset - width), 0)
+
+#define BYTE_POSITION(offset) (offset / BYTE_BIT)
+
+#define OVERFLOW_BITS(width, msb_offset, lsb_offset) \
+ (width - (BYTE_BIT - msb_offset - lsb_offset))
+
+#define MASK(msb_offset, lsb_offset) \
+ ((byte_t) BYTE_MAX >> (msb_offset + lsb_offset) << lsb_offset)
+
+#define OVERFLOW_LSB_OFFSET(overflow) (BYTE_BIT - overflow)
+
+#define NEED_SWAP(width, endian) \
+ (width > BYTE_BIT && endian == LITTLE_ENDIAN)
+
+uint64_t
+binary_get_uint64(byte_t *bytes, size_t offset, size_t width, int endian)
+{
+ size_t msb_offset = MSB_OFFSET(offset);
+ size_t lsb_offset = LSB_OFFSET(width, msb_offset);
+ size_t pos = BYTE_POSITION(offset);
+ size_t overflow = OVERFLOW_BITS(width, msb_offset, lsb_offset);
+ byte_t mask = MASK(msb_offset, lsb_offset);
+
+ uint64_t value = (byte_t) (bytes[ pos ] & mask) >> lsb_offset;
+
+ for (; overflow >= BYTE_BIT; overflow -= BYTE_BIT)
+ value = (value << BYTE_BIT) | bytes[ ++pos ];
+
+ if (overflow > 0) {
+ /* assertion: overflow < BYTE_BIT */
+ size_t overflow_lsb_offset = OVERFLOW_LSB_OFFSET(overflow);
+
+ value <<= overflow;
+ value |= (byte_t) bytes[ ++pos ] >> overflow_lsb_offset;
+ }
+
+ if (NEED_SWAP(width, endian))
+ swap_bytes_in(&value, width);
+
+ return value;
+}
+
+void
+binary_set_uint64(byte_t *bytes, size_t offset, size_t width, int endian,
uint64_t value)
+{
+ size_t msb_offset = MSB_OFFSET(offset);
+ size_t lsb_offset = LSB_OFFSET(width, msb_offset);
+ size_t pos = BYTE_POSITION(offset);
+ size_t overflow = OVERFLOW_BITS(width, msb_offset, lsb_offset);
+ byte_t clear_mask = ~MASK(msb_offset, lsb_offset);
+
+ if (NEED_SWAP(width, endian))
+ swap_bytes_out(&value, width);
+
+ bytes[ pos ] &= clear_mask;
+ bytes[ pos ] |= (uint64_t) value << lsb_offset >> overflow;
+
+ for (; overflow >= BYTE_BIT; overflow -= BYTE_BIT)
+ bytes[ ++pos ] = (uint64_t) value >> (overflow - BYTE_BIT);
+
+ if (overflow > 0) {
+ /* assertion: overflow < BYTE_BIT */
+ size_t overflow_lsb_offset = OVERFLOW_LSB_OFFSET(overflow);
+ byte_t overflow_clear_mask = ~(BYTE_MAX << overflow_lsb_offset);
+
+ bytes[ ++pos ] &= overflow_clear_mask;
+ bytes[ pos ] |= value << overflow_lsb_offset;
+ }
+}
Index: lib/lua/data/binary.h
===================================================================
RCS file: lib/lua/data/binary.h
diff -N lib/lua/data/binary.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ lib/lua/data/binary.h 17 Jan 2014 11:47:53 -0000
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2013, 2014, Lourival Vieira Neto <lneto%NetBSD.org@localhost>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the Author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#ifndef _BINARY_H_
+#define _BINARY_H_
+
+#include <sys/endian.h>
+
+#ifdef _KERNEL
+#include <sys/types.h>
+#else
+#include <stddef.h>
+#include <stdint.h>
+#endif
+
+#define BYTE_BIT CHAR_BIT
+
+typedef unsigned char byte_t;
+
+uint64_t binary_get_uint64(byte_t *, size_t, size_t, int);
+
+void binary_set_uint64(byte_t *, size_t, size_t, int, uint64_t);
+
+#endif /* _BINARY_H_ */
Index: lib/lua/data/data.c
===================================================================
RCS file: lib/lua/data/data.c
diff -N lib/lua/data/data.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ lib/lua/data/data.c 17 Jan 2014 11:47:53 -0000
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2013, 2014, Lourival Vieira Neto <lneto%NetBSD.org@localhost>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the Author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <lauxlib.h>
+
+#include "luautil.h"
+
+#include "data.h"
+
+#include "binary.h"
+#include "layout.h"
+
+#define LUA_INTEGER_BYTE (sizeof(lua_Integer))
+#define LUA_INTEGER_BIT (LUA_INTEGER_BYTE * BYTE_BIT)
+
+inline static bool
+check_limits(data_t *data, layout_entry_t *entry)
+{
+ return entry->length <= LUA_INTEGER_BIT &&
+ entry->offset + entry->length <= data->length;
+}
+
+inline static bool
+check_entry(data_t *data, layout_entry_t *entry)
+{
+ return entry != NULL && check_limits(data, entry);
+}
+
+inline static layout_entry_t *
+get_entry(lua_State *L, data_t *data, int key_ix)
+{
+ if (!luau_isvalidref(data->layout))
+ return NULL;
+
+ return layout_get_entry(L, data->layout, key_ix);
+}
+
+data_t *
+data_new(lua_State *L, void *ptr, size_t size, bool free)
+{
+ data_t *data = lua_newuserdata(L, sizeof(data_t));
+
+ data->ptr = ptr;
+ data->size = size;
+ data->length = size * BYTE_BIT;
+ data->layout = LUA_REFNIL;
+ data->free = free;
+
+ luaL_getmetatable(L, DATA_USERDATA);
+ lua_setmetatable(L, -2);
+ return data;
+}
+
+inline data_t *
+data_check(lua_State *L, int index)
+{
+ return (data_t *) luaL_checkudata(L, index, DATA_USERDATA);
+}
+
+inline void
+data_apply_layout(lua_State *L, data_t *data, int layout_ix)
+{
+ luau_unref(L, data->layout);
+ lua_pushvalue(L, layout_ix);
+ data->layout = luau_ref(L);
+}
+
+#define BINARY_PARMS(data, entry) \
+ data->ptr, entry->offset, entry->length, entry->endian
+
+int
+data_get_field(lua_State *L, data_t *data, int key_ix)
+{
+ if (data->ptr == NULL)
+ return 0;
+
+ layout_entry_t *entry = get_entry(L, data, key_ix);
+ if (!check_entry(data, entry))
+ return 0;
+
+ /* assertion: LUA_INTEGER_BIT <= 64 */
+ lua_Integer value = binary_get_uint64(BINARY_PARMS(data, entry));
+ lua_pushinteger(L, value);
+ return 1;
+}
+
+void
+data_set_field(lua_State *L, data_t *data, int key_ix, lua_Integer value)
+{
+ if (data->ptr == NULL)
+ return;
+
+ layout_entry_t *entry = get_entry(L, data, key_ix);
+ if (!check_entry(data, entry))
+ return;
+
+ binary_set_uint64(BINARY_PARMS(data, entry), value);
+}
Index: lib/lua/data/data.h
===================================================================
RCS file: lib/lua/data/data.h
diff -N lib/lua/data/data.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ lib/lua/data/data.h 17 Jan 2014 11:47:53 -0000
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2013, 2014, Lourival Vieira Neto <lneto%NetBSD.org@localhost>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the Author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#ifndef _DATA_H_
+#define _DATA_H_
+
+#ifndef _KERNEL
+#include <stddef.h>
+#include <stdbool.h>
+#else
+#include <sys/types.h>
+#endif
+
+#include <lua.h>
+
+#include "layout.h"
+
+#define DATA_LIB "data"
+#define DATA_USERDATA "data.data"
+
+typedef struct {
+ void *ptr;
+ size_t size;
+ size_t length;
+ int layout;
+ bool free;
+} data_t;
+
+data_t * data_new(lua_State *, void *, size_t, bool);
+
+data_t * data_check(lua_State *, int);
+
+void data_apply_layout(lua_State *, data_t *, int);
+
+int data_get_field(lua_State *, data_t *, int);
+
+void data_set_field(lua_State *, data_t *, int, lua_Integer);
+
+#endif /* _DATA_H_ */
Index: lib/lua/data/filter.lua
===================================================================
RCS file: lib/lua/data/filter.lua
diff -N lib/lua/data/filter.lua
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ lib/lua/data/filter.lua 17 Jan 2014 11:47:53 -0000
@@ -0,0 +1,20 @@
+function filter(d)
+ -- store d in a global
+ gd = d
+ d:layout{
+ -- most significant 4-bytes
+ uint4_msb = {0,4},
+ -- inner 16-bytes
+ uint16 = {4, 16},
+ -- least significant 4-bytes
+ uint4_lsb = {20, 4}
+ }
+ return d.uint4_msb == 0xa and
+ d.uint16 == 0xbcde and
+ d.uint4_lsb == 0xf
+end
+
+function access_global_data()
+ -- should return nil if ldata_unref(d) has been called from C
+ return gd.uint16
+end
Index: lib/lua/data/layout.c
===================================================================
RCS file: lib/lua/data/layout.c
diff -N lib/lua/data/layout.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ lib/lua/data/layout.c 17 Jan 2014 11:47:54 -0000
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2013, 2014, Lourival Vieira Neto <lneto%NetBSD.org@localhost>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the Author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <lauxlib.h>
+
+#include "luautil.h"
+
+#include "layout.h"
+
+inline static layout_entry_t *
+check_entry(lua_State *L, int index)
+{
+ return (layout_entry_t *) luaL_checkudata(L, index,
LAYOUT_ENTRY_USERDATA);
+}
+
+inline static void
+init_layout(layout_entry_t *entry)
+{
+ entry->offset = 0;
+ entry->length = 0;
+ entry->endian = LAYOUT_ENDIAN_DEFAULT;
+}
+
+static void
+load_endian(lua_State *L, layout_entry_t *entry)
+{
+ const char *endian = lua_tostring(L, -1);
+
+ if (endian[0] == 'n' || endian[0] == 'b')
+ entry->endian = BIG_ENDIAN;
+ else if (endian[0] == 'l')
+ entry->endian = LITTLE_ENDIAN;
+ else if (endian[0] == 'h')
+ entry->endian = BYTE_ORDER;
+}
+
+/* format: {<offset>, <length>, <endian>, <step>} */
+static void
+load_entry_numbered(lua_State *L, layout_entry_t *entry)
+{
+ size_t array_len = lua_objlen(L, -1);
+
+ if (array_len >= 1)
+ entry->offset = luau_getarray_integer(L, -1, 1);
+ if (array_len >= 2)
+ entry->length = luau_getarray_integer(L, -1, 2);
+ if (array_len >= 3) {
+ luau_getarray(L, -1, 3);
+ load_endian(L, entry);
+ lua_pop(L, 1);
+ }
+}
+
+/* format: {offset = <offset>, length = <length>, endian = <endian>, step =
<step>} */
+static void
+load_entry_named(lua_State *L, layout_entry_t *entry)
+{
+ lua_getfield(L, -1, "offset");
+ if (lua_isnumber(L, -1))
+ entry->offset = lua_tointeger(L, -1);
+ lua_pop(L, 1);
+
+ lua_getfield(L, -1, "length");
+ if (lua_isnumber(L, -1))
+ entry->length = lua_tointeger(L, -1);
+ lua_pop(L, 1);
+
+ lua_getfield(L, -1, "endian");
+ if (lua_isstring(L, -1))
+ load_endian(L, entry);
+ lua_pop(L, 1);
+}
+
+static void
+load_entry(lua_State *L, layout_entry_t *entry)
+{
+ init_layout(entry);
+ load_entry_numbered(L, entry);
+ load_entry_named(L, entry);
+}
+
+static int
+new_entry(lua_State *L, layout_entry_t *entry)
+{
+ layout_entry_t *nentry =
+ (layout_entry_t *) lua_newuserdata(L, sizeof(layout_entry_t));
+
+ luaL_getmetatable(L, LAYOUT_ENTRY_USERDATA);
+ lua_setmetatable(L, -2);
+
+ layout_copy_entry(nentry, entry);
+ return 1;
+}
+
+void
+layout_load(lua_State *L, int index)
+{
+ layout_entry_t entry;
+
+ lua_pushnil(L); /* first key */
+ while (lua_next(L, index) != 0) {
+ /* uses 'key' (at index -2) and 'value' (at index -1) */
+ load_entry(L, &entry);
+ if (entry.length == 0)
+ lua_pushnil(L);
+ else
+ new_entry(L, &entry);
+
+ /* layout[ key ] = entry */
+ luau_settable(L, index, -3, -1);
+
+ /* removes 'value' and 'entry'; keeps 'key' for next iteration
*/
+ lua_pop(L, 2);
+ }
+
+ lua_pushboolean(L, true);
+ lua_setfield(L, index, LAYOUT_STAMP);
+}
+
+layout_entry_t *
+layout_get_entry(lua_State *L, int layout_ix, int key_ix)
+{
+ void *entry = NULL;
+
+ luau_getref(L, layout_ix);
+ luau_gettable(L, -1, key_ix);
+ if (lua_isnil(L, -1))
+ goto end;
+
+ entry = check_entry(L, -1);
+
+end:
+ lua_pop(L, 2);
+ return entry;
+}
+
+void
+layout_copy_entry(layout_entry_t *dst, layout_entry_t *src)
+{
+ dst->offset = src->offset;
+ dst->length = src->length;
+ dst->endian = src->endian;
+}
Index: lib/lua/data/layout.h
===================================================================
RCS file: lib/lua/data/layout.h
diff -N lib/lua/data/layout.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ lib/lua/data/layout.h 17 Jan 2014 11:47:54 -0000
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2013, 2014, Lourival Vieira Neto <lneto%NetBSD.org@localhost>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the Author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#ifndef _LAYOUT_H_
+#define _LAYOUT_H_
+
+#ifndef _KERNEL
+#include <stdint.h>
+#include <stdbool.h>
+#else
+#include <sys/types.h>
+#endif
+
+#include <sys/endian.h>
+
+#include <lua.h>
+
+#define LAYOUT_ENTRY_USERDATA "data.layout.entry"
+
+#define LAYOUT_STAMP "__layout_stamp"
+
+#define LAYOUT_ENDIAN_DEFAULT BIG_ENDIAN
+
+typedef struct {
+ size_t offset;
+ size_t length;
+ int endian;
+} layout_entry_t;
+
+void layout_load(lua_State *, int);
+
+layout_entry_t * layout_get_entry(lua_State *, int, int);
+
+void layout_copy_entry(layout_entry_t *, layout_entry_t *);
+
+#endif /* _LAYOUT_H_ */
Index: lib/lua/data/luadata.c
===================================================================
RCS file: lib/lua/data/luadata.c
diff -N lib/lua/data/luadata.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ lib/lua/data/luadata.c 17 Jan 2014 11:47:54 -0000
@@ -0,0 +1,222 @@
+/*
+ * Copyright (c) 2013, 2014 Lourival Vieira Neto <lneto%NetBSD.org@localhost>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the Author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <lua.h>
+#include <lauxlib.h>
+
+#include "luadata.h"
+
+#include "luautil.h"
+
+#include "data.h"
+#include "layout.h"
+
+static int
+new_data(lua_State *L)
+{
+ if(!lua_istable(L, 1))
+ return 0;
+
+ size_t len = lua_objlen(L, 1);
+ char *data = (char *) luau_malloc(L, len);
+
+ size_t i = 0;
+ lua_pushnil(L); /* first key */
+ while (lua_next(L, 1) != 0 && i < len) {
+ /* uses 'key' (at index -2) and 'value' (at index -1) */
+ data[ i++ ] = (char) lua_tointeger(L, -1);
+ /* removes 'value'; keeps 'key' for next iteration */
+ lua_pop(L, 1);
+ }
+ data_new(L, (void *) data, len, true);
+
+ return 1;
+}
+
+static int
+new_layout(lua_State *L)
+{
+ if (!lua_istable(L, 1))
+ return 0;
+
+ layout_load(L, 1);
+ return 1;
+}
+
+static int
+apply_layout(lua_State *L)
+{
+ data_t *data = data_check(L, 1);
+
+ if (!lua_istable(L, 2))
+ return 0;
+
+ lua_getfield(L, 2, LAYOUT_STAMP);
+ bool is_layout = (bool) lua_toboolean(L, -1);
+ lua_pop(L, 1);
+
+ if (!is_layout)
+ layout_load(L, 2);
+
+ data_apply_layout(L, data, 2);
+
+ /* return data object */
+ lua_pushvalue(L, 1);
+ return 1;
+}
+
+static int
+gc(lua_State *L)
+{
+ data_t *data = data_check(L, 1);
+
+ if (data->free)
+ luau_free(L, data->ptr, data->size);
+ return 0;
+}
+
+static int
+get_field(lua_State *L)
+{
+ data_t *data = data_check(L, 1);
+
+ lua_getmetatable(L, 1);
+ if (lua_isstring(L, 2)) {
+ /* try object-oriented access first */
+ luau_gettable(L, -1, 2);
+ if (lua_iscfunction(L, -1))
+ /* return this method */
+ return 1;
+ lua_pop(L, 1);
+ }
+
+ return data_get_field(L, data, 2);
+}
+
+static int
+set_field(lua_State *L)
+{
+ data_t *data = data_check(L, 1);
+
+ lua_getmetatable(L, 1);
+ if (lua_isstring(L, 2)) {
+ /* try object-oriented access first */
+ luau_gettable(L, -1, 2);
+ if (lua_iscfunction(L, -1)) {
+ /* shouldn't overwrite a method */
+ lua_pop(L, 1);
+ return 0;
+ }
+ }
+
+ lua_Integer value = lua_tointeger(L, 3);
+
+ data_set_field(L, data, 2, value);
+ return 0;
+}
+
+static const luaL_Reg data_lib[ ] = {
+ {"new" , new_data},
+ {"layout", new_layout},
+ {NULL , NULL}
+};
+
+static const luaL_Reg data_m[ ] = {
+ {"layout" , apply_layout},
+ {"__index" , get_field},
+ {"__newindex", set_field},
+ {"__gc" , gc},
+ {NULL , NULL}
+};
+
+static const luaL_Reg layout_entry_m[ ] = {
+ {NULL, NULL}
+};
+
+int
+luaopen_data(lua_State *L);
+
+int
+luaopen_data(lua_State *L)
+{
+ luaL_newmetatable(L, DATA_USERDATA);
+ luaL_register(L, NULL, data_m);
+ luaL_register(L, DATA_LIB, data_lib);
+
+ luaL_newmetatable(L, LAYOUT_ENTRY_USERDATA);
+ luaL_register(L, NULL, layout_entry_m);
+
+ return 1;
+}
+
+int
+ldata_newref(lua_State *L, void *ptr, size_t size)
+{
+ data_new(L, ptr, size, false);
+ /* keep the new data object on the stack */
+ lua_pushvalue(L, -1);
+ return luau_ref(L);
+}
+
+void
+ldata_unref(lua_State *L, int r)
+{
+ luau_getref(L, r);
+ data_t *data = data_check(L, -1);
+
+ data->ptr = NULL;
+
+ lua_pop(L, 1);
+ luau_unref(L, r);
+}
+
+#ifdef _MODULE
+#include <sys/lua.h>
+#include <sys/module.h>
+
+MODULE(MODULE_CLASS_MISC, luadata, "lua");
+
+typedef int (*kluaopen_t)(void *) ;
+
+static int
+luadata_modcmd(modcmd_t cmd, void *opaque)
+{
+ int error;
+
+ switch (cmd) {
+ case MODULE_CMD_INIT:
+ error = lua_mod_register(DATA_LIB, (kluaopen_t) luaopen_data);
+ break;
+ case MODULE_CMD_FINI:
+ error = lua_mod_unregister(DATA_LIB);
+ break;
+ default:
+ error = ENOTTY;
+ }
+ return error;
+}
+#endif
Index: lib/lua/data/luadata.h
===================================================================
RCS file: lib/lua/data/luadata.h
diff -N lib/lua/data/luadata.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ lib/lua/data/luadata.h 17 Jan 2014 11:47:54 -0000
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2013, 2014, Lourival Vieira Neto <lneto%NetBSD.org@localhost>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the Author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#ifndef _LUA_DATA_H_
+#define _LUA_DATA_H_
+
+#ifndef _KERNEL
+#include <stddef.h>
+#include <stdbool.h>
+#endif
+
+#include <lua.h>
+
+extern int ldata_newref(lua_State *, void *, size_t);
+
+extern void ldata_unref(lua_State *, int);
+
+extern int luaopen_data(lua_State *L);
+
+#endif /* _LUA_DATA_H_ */
Index: lib/lua/data/luautil.c
===================================================================
RCS file: lib/lua/data/luautil.c
diff -N lib/lua/data/luautil.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ lib/lua/data/luautil.c 17 Jan 2014 11:47:54 -0000
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2013, 2014, Lourival Vieira Neto <lneto%NetBSD.org@localhost>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the Author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include "luautil.h"
+
+inline static void
+adjust_index(int *index, int factor)
+{
+ if (*index < 0)
+ (*index) -= factor;
+}
+
+void
+luau_getarray(lua_State *L, int index, lua_Integer n)
+{
+ lua_pushinteger(L, n);
+ adjust_index(&index, 1);
+ lua_gettable(L, index);
+}
+
+lua_Integer
+luau_getarray_integer(lua_State *L, int index, lua_Integer n)
+{
+ luau_getarray(L, index, n);
+ lua_Integer result = lua_tointeger(L, -1);
+ lua_pop(L, 1);
+ return result;
+}
+
+void
+luau_gettable(lua_State *L, int index, int field_index)
+{
+ lua_pushvalue(L, field_index);
+ adjust_index(&index, 1);
+ lua_gettable(L, index);
+}
+
+void
+luau_settable(lua_State *L, int index, int field_index, int value_index)
+{
+ lua_pushvalue(L, field_index);
+ adjust_index(&value_index, 1);
+ lua_pushvalue(L, value_index);
+ adjust_index(&index, 2);
+ lua_settable(L, index);
+}
+
+void *
+luau_malloc(lua_State *L, size_t size)
+{
+ void * ud = NULL;
+ lua_Alloc alloc = lua_getallocf(L, &ud);
+ return alloc(ud, NULL, 0, size);
+}
+
+void
+luau_free(lua_State *L, void * ptr, size_t size)
+{
+ void * ud = NULL;
+ lua_Alloc alloc = lua_getallocf(L, &ud);
+ alloc(ud, ptr, size, 0);
+}
Index: lib/lua/data/luautil.h
===================================================================
RCS file: lib/lua/data/luautil.h
diff -N lib/lua/data/luautil.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ lib/lua/data/luautil.h 17 Jan 2014 11:47:54 -0000
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2013, 2014 Lourival Vieira Neto <lneto%NetBSD.org@localhost>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the Author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#ifndef _LUA_UTIL_H_
+#define _LUA_UTIL_H_
+
+#ifndef _KERNEL
+#include <stddef.h>
+#endif
+
+#include <lua.h>
+#include <lauxlib.h>
+
+#define luau_isvalidref(ref) (ref != LUA_REFNIL && ref != LUA_NOREF)
+
+#define luau_ref(L) luaL_ref(L, LUA_REGISTRYINDEX)
+#define luau_unref(L, r) luaL_unref(L, LUA_REGISTRYINDEX, r)
+#define luau_getref(L, r) lua_rawgeti(L, LUA_REGISTRYINDEX, r)
+
+void luau_getarray(lua_State *, int, lua_Integer);
+
+lua_Integer luau_getarray_integer(lua_State *, int, lua_Integer);
+
+void luau_gettable(lua_State *, int, int);
+
+void luau_settable(lua_State *, int, int, int);
+
+void * luau_malloc(lua_State *, size_t);
+
+void luau_free(lua_State *, void *, size_t);
+
+#endif /* _LUA_UTIL_H_ */
Index: lib/lua/data/test.c
===================================================================
RCS file: lib/lua/data/test.c
diff -N lib/lua/data/test.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ lib/lua/data/test.c 17 Jan 2014 11:47:54 -0000
@@ -0,0 +1,64 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <lua.h>
+#include <lauxlib.h>
+
+#include "luadata.h"
+
+typedef unsigned char byte_t;
+
+int main(void)
+{
+ /* create a new Lua state */
+ lua_State *L = luaL_newstate();
+
+ /* open luadata library */
+ luaopen_data(L);
+
+ /* load a script */
+ if (luaL_dofile(L, "filter.lua") != 0)
+ goto err;
+
+ /* get the filter function */
+ lua_getglobal(L, "filter");
+
+ /* create a new data ptr */
+ size_t data_size = 3;
+ byte_t *data_ptr = (byte_t *) malloc(data_size);
+ data_ptr[0] = 0xAB;
+ data_ptr[1] = 0xCD;
+ data_ptr[2] = 0xEF;
+
+ /* create a new data object */
+ int rd = ldata_newref(L, data_ptr, data_size);
+
+ /* call filter(d)*/
+ if (lua_pcall(L, 1, 1, 0) != 0)
+ goto err;
+
+ /* get filter result */
+ bool passed = (bool) lua_toboolean(L, -1);
+
+ /* unregister the Lua data object */
+ ldata_unref(L, rd);
+
+ /* now we can safely free the data pointer */
+ free(data_ptr);
+
+ /* get the access_global_data function */
+ lua_getglobal(L, "access_global_data");
+
+ /* call access_global_data() */
+ if (lua_pcall(L, 0, 1, 0) != 0)
+ goto err;
+
+ /* if global access returned nil and filter has passed; then test
passed */
+ if (lua_isnil(L, -1) && passed)
+ printf("test passed ;-)\n");
+
+ return 0;
+err:
+ return 1;
+}
+
Index: lib/lua/data/test.lua
===================================================================
RCS file: lib/lua/data/test.lua
diff -N lib/lua/data/test.lua
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ lib/lua/data/test.lua 17 Jan 2014 11:47:54 -0000
@@ -0,0 +1,45 @@
+require "data"
+
+-- create a new data object
+d1 = data.new{0x0f}
+
+-- create and apply a data layout
+d1:layout{byte = {0, 8}, lsb = {7, 1}}
+
+-- access the whole byte
+assert(d1.byte == 0x0f)
+
+-- set 0 to the least significant bit
+d1.lsb = 0
+
+-- access the whole byte again
+assert(d1.byte == 0x0e)
+
+-- create a new layout
+l = data.layout{
+ uint16be = {0, 16},
+ uint16le = {0, 16, 'l'},
+ uint4 = {16, 4},
+ uint9 = {20, 9},
+ overflow = {32, 1},
+}
+
+-- create a new data object
+d2 = data.new{0xaa, 0xbb, 0xcc, 0xdd}
+
+-- apply the layout 'l' to data 'd2'
+d2:layout(l)
+
+-- access 2 bytes using big-endian ordering
+assert(d2.uint16be == 0xaabb)
+
+-- access 2 bytes using little-endian ordering
+assert(d2.uint16le == 0xbbaa)
+
+-- access 4 bits
+assert(d2.uint4 == 0xc)
+
+-- access out of bounds
+assert(d2.overflow == nil)
+
+print("test passed ;-)")
Index: sys/modules/luadata/Makefile
===================================================================
RCS file: sys/modules/luadata/Makefile
diff -N sys/modules/luadata/Makefile
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ sys/modules/luadata/Makefile 17 Jan 2014 11:47:54 -0000
@@ -0,0 +1,18 @@
+.include "../Makefile.inc"
+
+.PATH: ${S}/../lib/lua/data
+
+KMOD= luadata
+
+SRCS= luadata.c
+SRCS+= data.c
+SRCS+= layout.c
+SRCS+= luautil.c
+SRCS+= binary.c
+
+CPPFLAGS+= -I${S}/../external/mit/lua/dist/src
+CPPFLAGS+= -I${S}/modules/lua
+CPPFLAGS+= -I${S}/sys
+
+.include <bsd.kmodule.mk>
+
Home |
Main Index |
Thread Index |
Old Index