Skip to content
Snippets Groups Projects
Commit 3f7d20f2 authored by Roman Tsisyk's avatar Roman Tsisyk
Browse files

Fix yaml.encode on cdata objects and add tests cases

parent b197ba40
No related branches found
No related tags found
No related merge requests found
......@@ -477,3 +477,105 @@ space:delete{1}
space:drop()
---
...
----------------
-- # yaml encode/decode on cdata
----------------
ffi = require('ffi')
---
...
ffi.new('uint8_t', 128)
---
- 128
...
ffi.new('int8_t', -128)
---
- -128
...
ffi.new('uint16_t', 128)
---
- 128
...
ffi.new('int16_t', -128)
---
- -128
...
ffi.new('uint32_t', 128)
---
- 128
...
ffi.new('int32_t', -128)
---
- -128
...
ffi.new('uint64_t', 128)
---
- 128
...
ffi.new('int64_t', -128)
---
- -128
...
ffi.new('char', 128)
---
- -128
...
ffi.new('char', -128)
---
- -128
...
ffi.new('bool', true)
---
- true
...
ffi.new('bool', false)
---
- false
...
ffi.new('float', 1.23456)
---
- 1.2345600128174
...
ffi.new('float', 1e10)
---
- 10000000000
...
ffi.new('double', 1.23456)
---
- 1.23456
...
ffi.new('double', 1e10)
---
- 10000000000
...
ffi.cast('void *', 0)
---
- null
...
ffi.cast('void *', 0xabcdef)
---
- 'cdata<void *>: 0x00abcdef'
...
ffi.cdef([[struct test { int a; }; ]])
---
...
ffi.cast('struct test *', 0)
---
- 'cdata<struct test *>: NULL'
...
--# setopt delimiter ';'
type(ffi.metatype('struct test', {
__index = {
totable = function(test)
return { 'yaml totable test = ' .. test.a }
end
}
}));
---
- cdata
...
--# setopt delimiter ''
-- custom totable function will be called by yaml.encode
ffi.new('struct test', { a = 15 })
---
- - yaml totable test = 15
...
......@@ -147,3 +147,47 @@ fifo_top(space, 1)
space:delete{1}
space:drop()
----------------
-- # yaml encode/decode on cdata
----------------
ffi = require('ffi')
ffi.new('uint8_t', 128)
ffi.new('int8_t', -128)
ffi.new('uint16_t', 128)
ffi.new('int16_t', -128)
ffi.new('uint32_t', 128)
ffi.new('int32_t', -128)
ffi.new('uint64_t', 128)
ffi.new('int64_t', -128)
ffi.new('char', 128)
ffi.new('char', -128)
ffi.new('bool', true)
ffi.new('bool', false)
ffi.new('float', 1.23456)
ffi.new('float', 1e10)
ffi.new('double', 1.23456)
ffi.new('double', 1e10)
ffi.cast('void *', 0)
ffi.cast('void *', 0xabcdef)
ffi.cdef([[struct test { int a; }; ]])
ffi.cast('struct test *', 0)
--# setopt delimiter ';'
type(ffi.metatype('struct test', {
__index = {
totable = function(test)
return { 'yaml totable test = ' .. test.a }
end
}
}));
--# setopt delimiter ''
-- custom totable function will be called by yaml.encode
ffi.new('struct test', { a = 15 })
......@@ -560,20 +560,29 @@ dump_node(struct lua_yaml_dumper *dumper)
int type = lua_type(dumper->L, top);
if (field.type == MP_EXT &&
(type == LUA_TUSERDATA || type == LUA_TCDATA)) {
/* has metatable, try to call 'totable' and use return value */
lua_getfield(dumper->L, top, "totable");
if (lua_isfunction(dumper->L, -1)) {
lua_pushvalue(dumper->L, top); /* copy object itself */
lua_call(dumper->L, 1, 1);
lua_replace(dumper->L, top);
luaL_tofield(dumper->L, -1, &field);
} else {
lua_pop(dumper->L, 1); /* pop result */
/* try to call 'totable' method on udata/cdata */
try {
/*
* LuaJIT specific: lua_getfield raises exception on
* cdata objects if field doesn't exist.
*/
lua_getfield(dumper->L, top, "totable");
if (lua_isfunction(dumper->L, -1)) {
/* copy object itself */
lua_pushvalue(dumper->L, top);
lua_call(dumper->L, 1, 1);
if (lua_istable(dumper->L, -1)) {
/* replace obj with the unpacked table*/
lua_replace(dumper->L, top);
luaL_tofield(dumper->L, -1, &field);
}
}
} catch (...) {
/* ignore lua_getfield exceptions */
}
lua_settop(dumper->L, top); /* remove temporary objects */
}
luaL_tofield(dumper->L, top, &field);
/* Still have unknown type on the stack,
* try to call 'tostring' */
if (field.type == MP_EXT) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment