diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ad2fef1de7d2500bf969d92caf76b905b4958b1e..ffd08aa786b01d173daf8575f45e8606efe2e65c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -94,6 +94,7 @@ set (common_sources lua/utils.c lua/errno.c lua/bsdsocket.cc + lua/pickle.cc ${lua_sources} ) diff --git a/src/box/lua/call.cc b/src/box/lua/call.cc index 0428242fd3f294d1f9af81ebc824da7bedd63cf3..f0f6b38e9593d0b8814a30d740dbd516ce3e816f 100644 --- a/src/box/lua/call.cc +++ b/src/box/lua/call.cc @@ -29,8 +29,6 @@ #include "box/lua/call.h" #include "pickle.h" -#include <arpa/inet.h> - #include "box/lua/tuple.h" #include "box/lua/index.h" #include "box/lua/space.h" @@ -47,7 +45,6 @@ #include "box/port.h" #include "box/request.h" #include "box/txn.h" -#include "bit/bit.h" #include "box/access.h" #include "box/schema.h" @@ -539,395 +536,6 @@ box_lua_call(struct request *request, struct txn *txn, struct port *port) port_add_lua_multret(port, L); } -/** - * Convert box.pack() format specifier to Tarantool - * binary protocol UPDATE opcode - */ -static char format_to_opcode(char format) -{ - switch (format) { - case '=': return 0; - case '+': return 1; - case '&': return 2; - case '^': return 3; - case '|': return 4; - case ':': return 5; - case '#': return 6; - case '!': return 7; - case '-': return 8; - default: return format; - } -} - -/** - * Counterpart to @a format_to_opcode - */ -static char opcode_to_format(char opcode) -{ - switch (opcode) { - case 0: return '='; - case 1: return '+'; - case 2: return '&'; - case 3: return '^'; - case 4: return '|'; - case 5: return ':'; - case 6: return '#'; - case 7: return '!'; - case 8: return '-'; - default: return opcode; - } -} - -/** - * To use Tarantool/Box binary protocol primitives from Lua, we - * need a way to pack Lua variables into a binary representation. - * We do it by exporting a helper function - * - * box.pack(format, args...) - * - * which takes the format, which is very similar to Perl 'pack' - * format, and a list of arguments, and returns a binary string - * which has the arguments packed according to the format. - * - * For example, a typical SELECT packet packs in Lua like this: - * - * pkt = box.pack("iiiiiip", -- pack format - * 0, -- space id - * 0, -- index id - * 0, -- offset - * 2^32, -- limit - * 1, -- number of SELECT arguments - * 1, -- tuple cardinality - * key); -- the key to use for SELECT - * - * @sa doc/box-protocol.txt, binary protocol description - * @todo: implement box.unpack(format, str), for testing purposes - */ -static int -lbox_pack(struct lua_State *L) -{ - const char *format = luaL_checkstring(L, 1); - /* first arg comes second */ - int i = 2; - int nargs = lua_gettop(L); - size_t size; - const char *str; - - RegionGuard region_guard(&fiber()->gc); - struct tbuf *b = tbuf_new(&fiber()->gc); - - struct luaL_field field; - double dbl; - float flt; - char *data; - while (*format) { - if (i > nargs) - luaL_error(L, "box.pack: argument count does not match " - "the format"); - luaL_tofield(L, i, &field); - switch (*format) { - case 'B': - case 'b': - /* signed and unsigned 8-bit integers */ - if (field.type != MP_UINT && field.type != MP_INT) - luaL_error(L, "box.pack: expected 8-bit int"); - - tbuf_append(b, (char *) &field.ival, sizeof(uint8_t)); - break; - case 'S': - case 's': - /* signed and unsigned 16-bit integers */ - if (field.type != MP_UINT && field.type != MP_INT) - luaL_error(L, "box.pack: expected 16-bit int"); - - tbuf_append(b, (char *) &field.ival, sizeof(uint16_t)); - break; - case 'n': - /* signed and unsigned 16-bit big endian integers */ - if (field.type != MP_UINT && field.type != MP_INT) - luaL_error(L, "box.pack: expected 16-bit int"); - - field.ival = (uint16_t) htons((uint16_t) field.ival); - tbuf_append(b, (char *) &field.ival, sizeof(uint16_t)); - break; - case 'I': - case 'i': - /* signed and unsigned 32-bit integers */ - if (field.type != MP_UINT && field.ival != MP_INT) - luaL_error(L, "box.pack: expected 32-bit int"); - - tbuf_append(b, (char *) &field.ival, sizeof(uint32_t)); - break; - case 'N': - /* signed and unsigned 32-bit big endian integers */ - if (field.type != MP_UINT && field.ival != MP_INT) - luaL_error(L, "box.pack: expected 32-bit int"); - - field.ival = htonl(field.ival); - tbuf_append(b, (char *) &field.ival, sizeof(uint32_t)); - break; - case 'L': - case 'l': - /* signed and unsigned 64-bit integers */ - if (field.type != MP_UINT && field.type != MP_INT) - luaL_error(L, "box.pack: expected 64-bit int"); - - tbuf_append(b, (char *) &field.ival, sizeof(uint64_t)); - break; - case 'Q': - case 'q': - /* signed and unsigned 64-bit integers */ - if (field.type != MP_UINT && field.type != MP_INT) - luaL_error(L, "box.pack: expected 64-bit int"); - - field.ival = bswap_u64(field.ival); - tbuf_append(b, (char *) &field.ival, sizeof(uint64_t)); - break; - case 'd': - dbl = (double) lua_tonumber(L, i); - tbuf_append(b, (char *) &dbl, sizeof(double)); - break; - case 'f': - flt = (float) lua_tonumber(L, i); - tbuf_append(b, (char *) &flt, sizeof(float)); - break; - case 'A': - case 'a': - /* A sequence of bytes */ - str = luaL_checklstring(L, i, &size); - tbuf_append(b, str, size); - break; - case 'P': - case 'p': - luamp_encode(L, b, i); - break; - case 'V': - { - int arg_count = luaL_checkint(L, i); - if (i + arg_count > nargs) - luaL_error(L, "box.pack: argument count does not match " - "the format"); - int first = i + 1; - int last = i + arg_count; - i += luamp_encodestack(L, b, first, last); - break; - } - case '=': - /* update tuple set foo = bar */ - case '+': - /* set field += val */ - case '-': - /* set field -= val */ - case '&': - /* set field & =val */ - case '|': - /* set field |= val */ - case '^': - /* set field ^= val */ - case ':': - /* splice */ - case '#': - /* delete field */ - case '!': - /* insert field */ - /* field no */ - tbuf_ensure(b, sizeof(uint32_t) + 1); - data = b->data + b->size; - - data = pack_u32(data, lua_tointeger(L, i)); - *data++ = format_to_opcode(*format); - - assert(data <= b->data + b->capacity); - b->size = data - b->data; - break; - default: - luaL_error(L, "box.pack: unsupported pack " - "format specifier '%c'", *format); - } - i++; - format++; - } - - lua_pushlstring(L, tbuf_str(b), b->size); - - return 1; -} - -const char * -box_unpack_response(struct lua_State *L, const char *s, const char *end) -{ - uint32_t tuple_count = pick_u32(&s, end); - - /* Unpack and push tuples. */ - while (tuple_count--) { - const char *t = s; - if (unlikely(mp_check(&s, end))) - tnt_raise(ClientError, ER_INVALID_MSGPACK); - if (unlikely(mp_typeof(*t) != MP_ARRAY)) - tnt_raise(ClientError, ER_TUPLE_NOT_ARRAY); - struct tuple *tuple = tuple_new(tuple_format_ber, t, s); - lbox_pushtuple(L, tuple); - } - return s; -} - -static int -lbox_unpack(struct lua_State *L) -{ - size_t format_size = 0; - const char *format = luaL_checklstring(L, 1, &format_size); - const char *f = format; - - size_t str_size = 0; - const char *str = luaL_checklstring(L, 2, &str_size); - const char *end = str + str_size; - const char *s = str; - - int save_stacksize = lua_gettop(L); - - char charbuf; - uint8_t u8buf; - uint16_t u16buf; - uint32_t u32buf; - double dbl; - float flt; - -#define CHECK_SIZE(cur) if (unlikely((cur) >= end)) { \ - luaL_error(L, "box.unpack('%c'): got %d bytes (expected: %d+)", \ - *f, (int) (end - str), (int) 1 + ((cur) - str)); \ -} - while (*f) { - switch (*f) { - case 'b': - CHECK_SIZE(s); - u8buf = *(uint8_t *) s; - lua_pushnumber(L, u8buf); - s++; - break; - case 's': - CHECK_SIZE(s + 1); - u16buf = *(uint16_t *) s; - lua_pushnumber(L, u16buf); - s += 2; - break; - case 'n': - CHECK_SIZE(s + 1); - u16buf = ntohs(*(uint16_t *) s); - lua_pushnumber(L, u16buf); - s += 2; - break; - case 'i': - CHECK_SIZE(s + 3); - u32buf = *(uint32_t *) s; - lua_pushnumber(L, u32buf); - s += 4; - break; - case 'N': - CHECK_SIZE(s + 3); - u32buf = ntohl(*(uint32_t *) s); - lua_pushnumber(L, u32buf); - s += 4; - break; - case 'l': - CHECK_SIZE(s + 7); - luaL_pushnumber64(L, *(uint64_t*) s); - s += 8; - break; - case 'q': - CHECK_SIZE(s + 7); - luaL_pushnumber64(L, bswap_u64(*(uint64_t*) s)); - s += 8; - break; - case 'd': - CHECK_SIZE(s + 7); - dbl = *(double *) s; - lua_pushnumber(L, dbl); - s += 8; - break; - case 'f': - CHECK_SIZE(s + 3); - flt = *(float *) s; - lua_pushnumber(L, flt); - s += 4; - break; - case 'a': - case 'A': /* The rest of the data is a Lua string. */ - lua_pushlstring(L, s, end - s); - s = end; - break; - case 'P': - case 'p': - { - const char *data = s; - if (unlikely(mp_check(&s, end))) - tnt_raise(ClientError, ER_INVALID_MSGPACK); - luamp_decode(L, &data); - assert(data == s); - break; - } - case '=': - /* update tuple set foo = bar */ - case '+': - /* set field += val */ - case '-': - /* set field -= val */ - case '&': - /* set field & =val */ - case '|': - /* set field |= val */ - case '^': - /* set field ^= val */ - case ':': - /* splice */ - case '#': - /* delete field */ - case '!': - /* insert field */ - CHECK_SIZE(s + 4); - - /* field no */ - u32buf = *(uint32_t *) s; - - /* opcode */ - charbuf = *(s + 4); - charbuf = opcode_to_format(charbuf); - if (charbuf != *f) { - luaL_error(L, "box.unpack('%s'): " - "unexpected opcode: " - "offset %d, expected '%c'," - "found '%c'", - format, s - str, *f, charbuf); - } - - lua_pushnumber(L, u32buf); - s += 5; - break; - - case 'R': /* Unpack server response, IPROTO format. */ - { - s = box_unpack_response(L, s, end); - break; - } - default: - luaL_error(L, "box.unpack: unsupported " - "format specifier '%c'", *f); - } - f++; - } - - assert(s <= end); - - if (s != end) { - luaL_error(L, "box.unpack('%s'): too many bytes: " - "unpacked %d, total %d", - format, s - str, str_size); - } - - return lua_gettop(L) - save_stacksize; - -#undef CHECK_SIZE -} - static int lbox_snapshot(struct lua_State *L) { @@ -943,8 +551,6 @@ lbox_snapshot(struct lua_State *L) static const struct luaL_reg boxlib[] = { {"raise", lbox_raise}, - {"pack", lbox_pack}, - {"unpack", lbox_unpack}, {"snapshot", lbox_snapshot}, {NULL, NULL} }; diff --git a/src/lua/init.cc b/src/lua/init.cc index 60e1fe30ae71103d0a85c9b90d41e7882d635eca..fbc084083065a976f7dd6e01ca59bf6c01bb7d15 100644 --- a/src/lua/init.cc +++ b/src/lua/init.cc @@ -56,6 +56,7 @@ extern "C" { #include "lua/cjson.h" #include "lua/yaml.h" #include "lua/msgpack.h" +#include "lua/pickle.h" #include <ctype.h> #include "small/region.h" @@ -236,6 +237,7 @@ tarantool_lua_init(const char *tarantool_bin, int argc, char **argv) tarantool_lua_bsdsocket_init(L); tarantool_lua_session_init(L); tarantool_lua_error_init(L); + tarantool_lua_pickle_init(L); luaopen_msgpack(L); lua_pop(L, 1); diff --git a/src/lua/pickle.cc b/src/lua/pickle.cc new file mode 100644 index 0000000000000000000000000000000000000000..09fafad3cd323be1a85c991fc25ad5c362503728 --- /dev/null +++ b/src/lua/pickle.cc @@ -0,0 +1,266 @@ +/* + * 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. + * + * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``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 + * <COPYRIGHT HOLDER> 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/pickle.h" + +#include <arpa/inet.h> + +extern "C" { +#include <lua.h> +#include <lauxlib.h> +#include <lualib.h> +} /* extern "C" */ + +#include "lua/utils.h" +#include <tbuf.h> +#include <fiber.h> +#include "bit/bit.h" + +static int +lbox_pack(struct lua_State *L) +{ + const char *format = luaL_checkstring(L, 1); + /* first arg comes second */ + int i = 2; + int nargs = lua_gettop(L); + size_t size; + const char *str; + + RegionGuard region_guard(&fiber()->gc); + struct tbuf *b = tbuf_new(&fiber()->gc); + + struct luaL_field field; + double dbl; + float flt; + while (*format) { + if (i > nargs) + luaL_error(L, "pickle.pack: argument count does not match " + "the format"); + luaL_tofield(L, i, &field); + switch (*format) { + case 'B': + case 'b': + /* signed and unsigned 8-bit integers */ + if (field.type != MP_UINT && field.type != MP_INT) + luaL_error(L, "pickle.pack: expected 8-bit int"); + + tbuf_append(b, (char *) &field.ival, sizeof(uint8_t)); + break; + case 'S': + case 's': + /* signed and unsigned 16-bit integers */ + if (field.type != MP_UINT && field.type != MP_INT) + luaL_error(L, "pickle.pack: expected 16-bit int"); + + tbuf_append(b, (char *) &field.ival, sizeof(uint16_t)); + break; + case 'n': + /* signed and unsigned 16-bit big endian integers */ + if (field.type != MP_UINT && field.type != MP_INT) + luaL_error(L, "pickle.pack: expected 16-bit int"); + + field.ival = (uint16_t) htons((uint16_t) field.ival); + tbuf_append(b, (char *) &field.ival, sizeof(uint16_t)); + break; + case 'I': + case 'i': + /* signed and unsigned 32-bit integers */ + if (field.type != MP_UINT && field.ival != MP_INT) + luaL_error(L, "pickle.pack: expected 32-bit int"); + + tbuf_append(b, (char *) &field.ival, sizeof(uint32_t)); + break; + case 'N': + /* signed and unsigned 32-bit big endian integers */ + if (field.type != MP_UINT && field.ival != MP_INT) + luaL_error(L, "pickle.pack: expected 32-bit int"); + + field.ival = htonl(field.ival); + tbuf_append(b, (char *) &field.ival, sizeof(uint32_t)); + break; + case 'L': + case 'l': + /* signed and unsigned 64-bit integers */ + if (field.type != MP_UINT && field.type != MP_INT) + luaL_error(L, "pickle.pack: expected 64-bit int"); + + tbuf_append(b, (char *) &field.ival, sizeof(uint64_t)); + break; + case 'Q': + case 'q': + /* signed and unsigned 64-bit integers */ + if (field.type != MP_UINT && field.type != MP_INT) + luaL_error(L, "pickle.pack: expected 64-bit int"); + + field.ival = bswap_u64(field.ival); + tbuf_append(b, (char *) &field.ival, sizeof(uint64_t)); + break; + case 'd': + dbl = (double) lua_tonumber(L, i); + tbuf_append(b, (char *) &dbl, sizeof(double)); + break; + case 'f': + flt = (float) lua_tonumber(L, i); + tbuf_append(b, (char *) &flt, sizeof(float)); + break; + case 'A': + case 'a': + /* A sequence of bytes */ + str = luaL_checklstring(L, i, &size); + tbuf_append(b, str, size); + break; + default: + luaL_error(L, "pickle.pack: unsupported pack " + "format specifier '%c'", *format); + } + i++; + format++; + } + + lua_pushlstring(L, tbuf_str(b), b->size); + + return 1; +} + + +static int +lbox_unpack(struct lua_State *L) +{ + size_t format_size = 0; + const char *format = luaL_checklstring(L, 1, &format_size); + const char *f = format; + + size_t str_size = 0; + const char *str = luaL_checklstring(L, 2, &str_size); + const char *end = str + str_size; + const char *s = str; + + int save_stacksize = lua_gettop(L); + + uint8_t u8buf; + uint16_t u16buf; + uint32_t u32buf; + double dbl; + float flt; + +#define CHECK_SIZE(cur) if (unlikely((cur) >= end)) { \ + luaL_error(L, "pickle.unpack('%c'): got %d bytes (expected: %d+)", \ + *f, (int) (end - str), (int) 1 + ((cur) - str)); \ +} + while (*f) { + switch (*f) { + case 'b': + CHECK_SIZE(s); + u8buf = *(uint8_t *) s; + lua_pushnumber(L, u8buf); + s++; + break; + case 's': + CHECK_SIZE(s + 1); + u16buf = *(uint16_t *) s; + lua_pushnumber(L, u16buf); + s += 2; + break; + case 'n': + CHECK_SIZE(s + 1); + u16buf = ntohs(*(uint16_t *) s); + lua_pushnumber(L, u16buf); + s += 2; + break; + case 'i': + CHECK_SIZE(s + 3); + u32buf = *(uint32_t *) s; + lua_pushnumber(L, u32buf); + s += 4; + break; + case 'N': + CHECK_SIZE(s + 3); + u32buf = ntohl(*(uint32_t *) s); + lua_pushnumber(L, u32buf); + s += 4; + break; + case 'l': + CHECK_SIZE(s + 7); + luaL_pushnumber64(L, *(uint64_t*) s); + s += 8; + break; + case 'q': + CHECK_SIZE(s + 7); + luaL_pushnumber64(L, bswap_u64(*(uint64_t*) s)); + s += 8; + break; + case 'd': + CHECK_SIZE(s + 7); + dbl = *(double *) s; + lua_pushnumber(L, dbl); + s += 8; + break; + case 'f': + CHECK_SIZE(s + 3); + flt = *(float *) s; + lua_pushnumber(L, flt); + s += 4; + break; + case 'a': + case 'A': /* The rest of the data is a Lua string. */ + lua_pushlstring(L, s, end - s); + s = end; + break; + default: + luaL_error(L, "pickle.unpack: unsupported " + "format specifier '%c'", *f); + } + f++; + } + + assert(s <= end); + + if (s != end) { + luaL_error(L, "pickle.unpack('%s'): too many bytes: " + "unpacked %d, total %d", + format, s - str, str_size); + } + + return lua_gettop(L) - save_stacksize; + +#undef CHECK_SIZE +} + +void +tarantool_lua_pickle_init(struct lua_State *L) +{ + const luaL_reg picklelib[] = { + {"pack", lbox_pack}, + {"unpack", lbox_unpack}, + { NULL, NULL} + }; + + luaL_register_module(L, "pickle", picklelib); + lua_pop(L, 1); +} diff --git a/src/lua/pickle.h b/src/lua/pickle.h new file mode 100644 index 0000000000000000000000000000000000000000..ead5695a790a77e5153c29ef8906f41aee4105ce --- /dev/null +++ b/src/lua/pickle.h @@ -0,0 +1,35 @@ +#ifndef TARANTOOL_LUA_PICKLE_H_INCLUDED +#define TARANTOOL_LUA_PICKLE_H_INCLUDED +/* + * 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. + * + * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``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 + * <COPYRIGHT HOLDER> 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. + */ + +void +tarantool_lua_pickle_init(struct lua_State *L); + +#endif /* TARANTOOL_LUA_PICKLE_H_INCLUDED */ diff --git a/test/box/bsdsocket.result b/test/box/bsdsocket.result index 111e22bc3692a980f357031ae20ae4e5fb201978..164901710624c75492ed52fef92c04610beca78a 100644 --- a/test/box/bsdsocket.result +++ b/test/box/bsdsocket.result @@ -1,6 +1,9 @@ json = require('json') --- ... +pickle = require('pickle') +--- +... socket = require('socket') --- ... @@ -91,7 +94,7 @@ s:wait(.01) --- - RW ... -s:syswrite(box.pack('iii', 65280, 0, 12334)) +s:syswrite(pickle.pack('iii', 65280, 0, 12334)) --- - 12 ... @@ -103,11 +106,11 @@ s:wait(.01) --- - RW ... -box.unpack('iii', s:sysread(4096)) +pickle.unpack('iii', s:sysread(4096)) --- -- error: 'box.unpack(''iii''): too many bytes: unpacked 12, total 128' +- error: 'pickle.unpack(''iii''): too many bytes: unpacked 12, total 128' ... -s:syswrite(box.pack('iii', 65280, 0, 12335)) +s:syswrite(pickle.pack('iii', 65280, 0, 12335)) --- - 12 ... diff --git a/test/box/bsdsocket.test.lua b/test/box/bsdsocket.test.lua index 95af2305217585fadc2f54d7fb5083404b5f2753..25eab88e90b74ee8de5229c4fd976760f477be07 100644 --- a/test/box/bsdsocket.test.lua +++ b/test/box/bsdsocket.test.lua @@ -1,4 +1,5 @@ json = require('json') +pickle = require('pickle') socket = require('socket') type(socket) @@ -27,12 +28,12 @@ s:writable(.00000000000001) s:writable(0) s:wait(.01) -s:syswrite(box.pack('iii', 65280, 0, 12334)) +s:syswrite(pickle.pack('iii', 65280, 0, 12334)) s:readable(1) s:wait(.01) -box.unpack('iii', s:sysread(4096)) +pickle.unpack('iii', s:sysread(4096)) -s:syswrite(box.pack('iii', 65280, 0, 12335)) +s:syswrite(pickle.pack('iii', 65280, 0, 12335)) s:readable(1) string.len(s:sysread(4096)) s:close() diff --git a/test/box/misc.result b/test/box/misc.result index b6e031a74281772f9dace5fa5c7324534b7d6a3c..d0cc405924b2dc41527dc09c6e8d15144635c22f 100644 --- a/test/box/misc.result +++ b/test/box/misc.result @@ -21,7 +21,6 @@ t - index - info - net - - pack - raise - schema - slab @@ -29,7 +28,6 @@ t - space - stat - tuple - - unpack ... t = nil --- @@ -318,7 +316,7 @@ tonumber64('184467440737095516155') --- - error: 'lua_tointeger64: bad argument' ... -string.byte(box.pack('p', tonumber64(123))) +string.byte(require('msgpack').encode(tonumber64(123))) --- - 123 ... diff --git a/test/box/misc.test.lua b/test/box/misc.test.lua index 8b7ff88588fa88d2edda430ab482c8fb1c7cb77e..024806cf08558490ba063068bcd3bf2b709dd7f8 100644 --- a/test/box/misc.test.lua +++ b/test/box/misc.test.lua @@ -103,7 +103,7 @@ tonumber64('18446744073709551615') == tonumber64('18446744073709551615') tonumber64('18446744073709551615') + 1 tonumber64(-1) tonumber64('184467440737095516155') -string.byte(box.pack('p', tonumber64(123))) +string.byte(require('msgpack').encode(tonumber64(123))) -- A test case for Bug#1061747 'tonumber64 is not transitive' tonumber64(tonumber64(2)) tostring(tonumber64(tonumber64(3))) diff --git a/test/box/pack.result b/test/box/pack.result index b83e831380c840c7e1fcd0b378d7916ce317d1fe..8c1333abbbcebb8bb30ddfb4d78572faa18bd343 100644 --- a/test/box/pack.result +++ b/test/box/pack.result @@ -1,111 +1,78 @@ --- Test box.pack() -box.pack() +-- Test pickle.pack() +pickle = require('pickle') +--- +... +pickle.pack() --- - error: 'bad argument #1 to ''?'' (string expected, got no value)' ... -box.pack(1) +pickle.pack(1) --- -- error: 'box.pack: argument count does not match the format' +- error: 'pickle.pack: argument count does not match the format' ... -box.pack('abc') +pickle.pack('abc') --- -- error: 'box.pack: argument count does not match the format' +- error: 'pickle.pack: argument count does not match the format' ... -box.pack('a', ' - hello') +pickle.pack('a', ' - hello') --- - ' - hello' ... -box.pack('Aa', ' - hello', ' world') +pickle.pack('Aa', ' - hello', ' world') --- - ' - hello world' ... -string.sub(box.pack('p', 1684234849), 2) ---- -- dcba -... -box.pack('p', 'this string is 45 characters long 1234567890 ') ---- -- !!binary 2S10aGlzIHN0cmluZyBpcyA0NSBjaGFyYWN0ZXJzIGxvbmcgMTIzNDU2Nzg5MCA= -... -box.pack('s', 0x4d) +pickle.pack('s', 0x4d) --- - "M\0" ... -box.pack('ssss', 25940, 29811, 28448, 11883) +pickle.pack('ssss', 25940, 29811, 28448, 11883) --- - Test ok. ... -box.pack('SSSS', 25940, 29811, 28448, 11883) +pickle.pack('SSSS', 25940, 29811, 28448, 11883) --- - Test ok. ... -box.pack('SSSSSSSS', 28493, 29550, 27680, 27497, 29541, 20512, 29285, 8556) +pickle.pack('SSSSSSSS', 28493, 29550, 27680, 27497, 29541, 20512, 29285, 8556) --- - Mons likes Perl! ... -box.pack('bsil', 84, 29541, 1802444916, 2338318684567380014ULL) +pickle.pack('bsil', 84, 29541, 1802444916, 2338318684567380014ULL) --- - 'Test ok. Let`s ' ... -box.unpack('b', 'T') +pickle.unpack('b', 'T') --- - 84 ... -box.unpack('s', 'Te') +pickle.unpack('s', 'Te') --- - 25940 ... -box.unpack('i', 'Test') +pickle.unpack('i', 'Test') --- - 1953719636 ... -box.unpack('l', 'Test ok.') +pickle.unpack('l', 'Test ok.') --- - 3344889333436081492 ... -box.unpack('bsil', box.pack('bsil', 255, 65535, 4294967295, tonumber64('18446744073709551615'))) +pickle.unpack('bsil', pickle.pack('bsil', 255, 65535, 4294967295, tonumber64('18446744073709551615'))) --- - 255 - 65535 - 4294967295 - 18446744073709551615 ... -box.unpack('ppp', box.pack('ppp', 'one', 'two', 'three')) ---- -- one -- two -- three -... -num, str, num64 = box.unpack('ppp', box.pack('ppp', 666, 'string', tonumber64('666666666666666'))) ---- -... -num, str, num64 ---- -- 666 -- string -- 666666666666666 -... -box.unpack('=p', box.pack('=p', 1, '666')) ---- -- 1 -- '666' -... -box.unpack('','') ---- -... -box.unpack('ii', box.pack('i', 1)) ---- -- error: 'box.unpack(''i''): got 4 bytes (expected: 8+)' -... -box.unpack('i', box.pack('ii', 1, 1)) +pickle.unpack('','') --- -- error: 'box.unpack(''i''): too many bytes: unpacked 4, total 8' ... -box.unpack('+p', box.pack('=p', 1, '666')) +pickle.unpack('ii', pickle.pack('i', 1)) --- -- error: 'box.unpack(''+p''): unexpected opcode: offset 0, expected ''+'',found ''=''' +- error: 'pickle.unpack(''i''): got 4 bytes (expected: 8+)' ... -box.unpack('p', box.pack('p', 'this this this this')) +pickle.unpack('i', pickle.pack('ii', 1, 1)) --- -- this this this this +- error: 'pickle.unpack(''i''): too many bytes: unpacked 4, total 8' ... diff --git a/test/box/pack.test.lua b/test/box/pack.test.lua index 2dff411eede6ca5e94a0476d84e180cf144a7e75..8f7a6a0f45cf89c5e556a95a1306e28eb859ee7d 100644 --- a/test/box/pack.test.lua +++ b/test/box/pack.test.lua @@ -1,27 +1,21 @@ --- Test box.pack() -box.pack() -box.pack(1) -box.pack('abc') -box.pack('a', ' - hello') -box.pack('Aa', ' - hello', ' world') -string.sub(box.pack('p', 1684234849), 2) -box.pack('p', 'this string is 45 characters long 1234567890 ') -box.pack('s', 0x4d) -box.pack('ssss', 25940, 29811, 28448, 11883) -box.pack('SSSS', 25940, 29811, 28448, 11883) -box.pack('SSSSSSSS', 28493, 29550, 27680, 27497, 29541, 20512, 29285, 8556) -box.pack('bsil', 84, 29541, 1802444916, 2338318684567380014ULL) -box.unpack('b', 'T') -box.unpack('s', 'Te') -box.unpack('i', 'Test') -box.unpack('l', 'Test ok.') -box.unpack('bsil', box.pack('bsil', 255, 65535, 4294967295, tonumber64('18446744073709551615'))) -box.unpack('ppp', box.pack('ppp', 'one', 'two', 'three')) -num, str, num64 = box.unpack('ppp', box.pack('ppp', 666, 'string', tonumber64('666666666666666'))) -num, str, num64 -box.unpack('=p', box.pack('=p', 1, '666')) -box.unpack('','') -box.unpack('ii', box.pack('i', 1)) -box.unpack('i', box.pack('ii', 1, 1)) -box.unpack('+p', box.pack('=p', 1, '666')) -box.unpack('p', box.pack('p', 'this this this this')) +-- Test pickle.pack() +pickle = require('pickle') + +pickle.pack() +pickle.pack(1) +pickle.pack('abc') +pickle.pack('a', ' - hello') +pickle.pack('Aa', ' - hello', ' world') +pickle.pack('s', 0x4d) +pickle.pack('ssss', 25940, 29811, 28448, 11883) +pickle.pack('SSSS', 25940, 29811, 28448, 11883) +pickle.pack('SSSSSSSS', 28493, 29550, 27680, 27497, 29541, 20512, 29285, 8556) +pickle.pack('bsil', 84, 29541, 1802444916, 2338318684567380014ULL) +pickle.unpack('b', 'T') +pickle.unpack('s', 'Te') +pickle.unpack('i', 'Test') +pickle.unpack('l', 'Test ok.') +pickle.unpack('bsil', pickle.pack('bsil', 255, 65535, 4294967295, tonumber64('18446744073709551615'))) +pickle.unpack('','') +pickle.unpack('ii', pickle.pack('i', 1)) +pickle.unpack('i', pickle.pack('ii', 1, 1))