pax_global_header00006660000000000000000000000064125323433000014505gustar00rootroot0000000000000052 comment=099ef9e0a81b632ecf96a07373810bd4fcdcbddf lua-MessagePack-0.3.3/000077500000000000000000000000001253234330000144525ustar00rootroot00000000000000lua-MessagePack-0.3.3/.gitignore000066400000000000000000000000771253234330000164460ustar00rootroot00000000000000 /MANIFEST /README.html /*.tar /*.bak /*.tar.gz /*.rock *.out lua-MessagePack-0.3.3/.test.luacheckrc000066400000000000000000000015201253234330000175330ustar00rootroot00000000000000read_globals = { -- Test.More 'plan', 'done_testing', 'skip_all', 'BAIL_OUT', 'ok', 'nok', 'is', 'isnt', 'like', 'unlike', 'cmp_ok', 'type_ok', 'subtest', 'pass', 'fail', 'require_ok', 'eq_array', 'is_deeply', 'error_is', 'error_like', 'lives_ok', 'diag', 'note', 'skip', 'todo_skip', 'skip_rest', 'todo', -- testsuite 'Point', } globals = { -- Coat 'argerror', 'checktype', 'can', 'isa', 'does', 'dump', 'new', 'instance', '_INIT', 'has', 'method', 'overload', 'override', 'mock', 'unmock', 'before', 'around', 'after', 'memoize', 'bind', 'extends', 'with', 'module', 'class', 'singleton', 'abstract', 'augment', } lua-MessagePack-0.3.3/.travis.yml000066400000000000000000000016271253234330000165710ustar00rootroot00000000000000language: c env: - LUASUFFIX=5.1 LUAVER=5.1 - LUASUFFIX=5.2 LUAVER=5.2 - LUASUFFIX=jit LUAVER=5.1 # Tool setup. install: - sudo apt-get install -qq lua5.1 liblua5.1-0-dev - sudo apt-get install -qq lua5.2 liblua5.2-dev - sudo apt-get install -qq luajit - sudo ln -s /usr/bin/luajit-2.0.0-beta9 /usr/bin/luajit - sudo rm /usr/bin/lua - sudo ln -s /usr/bin/lua$LUASUFFIX /usr/bin/lua - lua -v - git clone git://github.com/keplerproject/luarocks.git - cd luarocks - ./configure --lua-version=$LUAVER --lua-suffix=$LUASUFFIX - make - sudo make install - cd .. - sudo luarocks install lua-testmore - sudo luarocks install lua-coat - sudo luarocks install lbc - sudo luarocks install luacov-coveralls - sudo luarocks install luacheck # Build and test. script: - make luacheck - make LUA=lua$LUASUFFIX test - make LUA=lua$LUASUFFIX coveralls branches: only: - master lua-MessagePack-0.3.3/CHANGES000066400000000000000000000013441253234330000154470ustar00rootroot00000000000000Revision history for lua-MessagePack 0.3.3 Sat May 30 16:30:00 2015 shadow _ENV (see PR #12) unsigned packer becomes the default for integer (see issue #13) set_integer marked as deprecated handle nil as table index (see issue #14) 0.3.2 Wed Jan 14 20:30:00 2015 add variant for Lua 5.3 compat Lua 5.3 0.3.1 Sun May 4 18:30:00 2014 add option set_array'always_as_map' fix issue #6 0.3.0 Sun Sep 1 15:30:00 2013 compliant with specifications v5 0.2.2 Sun Aug 25 09:30:00 2013 fix packer when downcast double->float 0.2.1 Thu Nov 29 19:30:00 2012 add set_array 0.2.0 Sat Nov 17 15:30:00 2012 INCOMPATIBILITY : now, unpacker accepts a ltn12.source instead of a file 0.1.0 Sun Nov 11 09:30:00 2012 First release lua-MessagePack-0.3.3/COPYRIGHT000066400000000000000000000025521253234330000157510ustar00rootroot00000000000000lua-MessagePack License -------------------------- lua-MessagePack is licensed under the terms of the MIT/X11 license reproduced below. =============================================================================== Copyright (C) 2012-2015 Francois Perrad. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. =============================================================================== (end of COPYRIGHT) lua-MessagePack-0.3.3/Makefile000066400000000000000000000055241253234330000161200ustar00rootroot00000000000000 LUA := lua VERSION := $(shell cd src && $(LUA) -e "m = require [[MessagePack]]; print(m._VERSION)") TARBALL := lua-messagepack-$(VERSION).tar.gz REV := 1 LUAVER := 5.1 PREFIX := /usr/local DPREFIX := $(DESTDIR)$(PREFIX) LIBDIR := $(DPREFIX)/share/lua/$(LUAVER) INSTALL := install ifeq ($(LUAVER),5.3) SRC := src5.3 else SRC := src endif all: @echo "Nothing to build here, you can just make install" install: $(INSTALL) -m 644 -D $(SRC)/MessagePack.lua $(LIBDIR)/MessagePack.lua uninstall: rm -f $(LIBDIR)/MessagePack.lua manifest_pl := \ use strict; \ use warnings; \ my @files = qw{MANIFEST}; \ while (<>) { \ chomp; \ next if m{^\.}; \ next if m{^doc/\.}; \ next if m{^doc/google}; \ next if m{^rockspec/}; \ push @files, $$_; \ } \ print join qq{\n}, sort @files; rockspec_pl := \ use strict; \ use warnings; \ use Digest::MD5; \ open my $$FH, q{<}, q{$(TARBALL)} \ or die qq{Cannot open $(TARBALL) ($$!)}; \ binmode $$FH; \ my %config = ( \ version => q{$(VERSION)}, \ rev => q{$(REV)}, \ md5 => Digest::MD5->new->addfile($$FH)->hexdigest(), \ ); \ close $$FH; \ while (<>) { \ s{@(\w+)@}{$$config{$$1}}g; \ print; \ } version: @echo $(VERSION) CHANGES: perl -i.bak -pe "s{^$(VERSION).*}{q{$(VERSION) }.localtime()}e" CHANGES tag: git tag -a -m 'tag release $(VERSION)' $(VERSION) doc: git read-tree --prefix=doc/ -u remotes/origin/gh-pages MANIFEST: doc git ls-files | perl -e '$(manifest_pl)' > MANIFEST $(TARBALL): MANIFEST [ -d lua-MessagePack-$(VERSION) ] || ln -s . lua-MessagePack-$(VERSION) perl -ne 'print qq{lua-MessagePack-$(VERSION)/$$_};' MANIFEST | \ tar -zc -T - -f $(TARBALL) rm lua-MessagePack-$(VERSION) rm -rf doc git rm doc/* dist: $(TARBALL) rockspec: $(TARBALL) perl -e '$(rockspec_pl)' rockspec.in > rockspec/lua-messagepack-$(VERSION)-$(REV).rockspec perl -e '$(rockspec_pl)' rockspec.lua53.in > rockspec/lua-messagepack-lua53-$(VERSION)-$(REV).rockspec rock: luarocks pack rockspec/lua-messagepack-$(VERSION)-$(REV).rockspec luarocks pack rockspec/lua-messagepack-lua53-$(VERSION)-$(REV).rockspec check: test test: cd $(SRC) && prove --exec=$(LUA) ../test/*.t luacheck: luacheck --std=max --codes src --ignore 211/_ENV 212 213 311/j luacheck --std=max --codes src5.3 --ignore 211/_ENV 212 213 311/j luacheck --std=max --config .test.luacheckrc test/*.t coverage: rm -f src/luacov.stats.out src/luacov.report.out cd $(SRC) && prove --exec="$(LUA) -lluacov" ../test/*.t cd $(SRC) && luacov coveralls: rm -f src/luacov.stats.out src/luacov.report.out cd $(SRC) && prove --exec="$(LUA) -lluacov" ../test/*.t cd $(SRC) && luacov-coveralls -e ^/usr -e %.t$ README.html: README.md Markdown.pl README.md > README.html clean: rm -rf doc rm -f MANIFEST *.bak src/luacov.*.out README.html realclean: clean .PHONY: test rockspec CHANGES lua-MessagePack-0.3.3/README.md000066400000000000000000000022561253234330000157360ustar00rootroot00000000000000lua-MessagePack : a pure Lua implementation (spec v5) ===================================================== [![Build Status](https://travis-ci.org/fperrad/lua-MessagePack.png?branch=master)](https://travis-ci.org/fperrad/lua-MessagePack) [![Coverage Status](https://coveralls.io/repos/fperrad/lua-MessagePack/badge.png?branch=master)](https://coveralls.io/r/fperrad/lua-MessagePack?branch=master) [![Licence](http://img.shields.io/badge/Licence-MIT-brightgreen.svg)](COPYRIGHT) Introduction ------------ [MessagePack](http://msgpack.org/) is an efficient binary serialization format. It lets you exchange data among multiple languages like JSON but it's faster and smaller. It's a pure Lua implementation, without dependency. And it's really fast with [LuaJIT](http://luajit.org). Links ----- The homepage is at [http://fperrad.github.io/lua-MessagePack/](http://fperrad.github.io/lua-MessagePack/), and the sources are hosted at [http://github.com/fperrad/lua-MessagePack/](http://github.com/fperrad/lua-MessagePack/). Copyright and License --------------------- Copyright (c) 2012-2015 Francois Perrad This library is licensed under the terms of the MIT/X11 license, like Lua itself. lua-MessagePack-0.3.3/msgpack.org.md000066400000000000000000000023511253234330000172100ustar00rootroot00000000000000MessagePack for Lua (spec v5) ============================= [![Build Status](https://travis-ci.org/fperrad/lua-MessagePack.png?branch=master)](https://travis-ci.org/fperrad/lua-MessagePack) [![Coverage Status](https://coveralls.io/repos/fperrad/lua-MessagePack/badge.png?branch=master)](https://coveralls.io/r/fperrad/lua-MessagePack?branch=master) [![Licence](http://img.shields.io/badge/Licence-MIT-brightgreen.svg)](COPYRIGHT) [![Dependencies](http://img.shields.io/badge/Dependencies-none-brightgreen.svg)](COPYRIGHT) ``` lua local mp = require 'MessagePack' mpac = mp.pack(data) data = mp.unpack(mpac) ``` Install ------- You can use LuaRocks to install lua-MessagePack: ``` $ luarocks install lua-messagepack ``` or from the source, with: ``` $ make install ``` It is a pure Lua implementation, without any dependency. Links ----- * [Github](http://github.com/fperrad/lua-MessagePack/) * [API reference](http://fperrad.github.io/lua-MessagePack/msgpack.html) Copyright and License --------------------- Copyright (c) 2012-2015 Francois Perrad [![rank](https://www.openhub.net/accounts/4780/widgets/account_rank.gif)](https://www.openhub.net/accounts/4780) This library is licensed under the terms of the MIT/X11 license, like Lua itself. lua-MessagePack-0.3.3/rockspec.in000066400000000000000000000014521253234330000166150ustar00rootroot00000000000000package = 'lua-MessagePack' version = '@version@-@rev@' source = { url = 'http://sites.google.com/site/fperrad/lua-messagepack-@version@.tar.gz', md5 = '@md5@', dir = 'lua-MessagePack-@version@', } description = { summary = "a pure Lua implementation of the MessagePack serialization format", detailed = [[ MessagePack is an efficient binary serialization format. It lets you exchange data among multiple languages like JSON but it's faster and smaller. ]], homepage = 'http://fperrad.github.io/lua-MessagePack/', maintainer = 'Francois Perrad', license = 'MIT/X11' } dependencies = { 'lua >= 5.1', } build = { type = 'builtin', modules = { ['MessagePack'] = 'src/MessagePack.lua', }, copy_directories = { 'doc', 'test' }, } lua-MessagePack-0.3.3/rockspec.lua53.in000066400000000000000000000014631253234330000175470ustar00rootroot00000000000000package = 'lua-MessagePack-lua53' version = '@version@-@rev@' source = { url = 'http://sites.google.com/site/fperrad/lua-messagepack-@version@.tar.gz', md5 = '@md5@', dir = 'lua-MessagePack-@version@', } description = { summary = "a pure Lua implementation of the MessagePack serialization format", detailed = [[ MessagePack is an efficient binary serialization format. It lets you exchange data among multiple languages like JSON but it's faster and smaller. ]], homepage = 'http://fperrad.github.io/lua-MessagePack/', maintainer = 'Francois Perrad', license = 'MIT/X11' } dependencies = { 'lua >= 5.3', } build = { type = 'builtin', modules = { ['MessagePack'] = 'src5.3/MessagePack.lua', }, copy_directories = { 'doc', 'test' }, } lua-MessagePack-0.3.3/rockspec/000077500000000000000000000000001253234330000162635ustar00rootroot00000000000000lua-MessagePack-0.3.3/rockspec/lua-messagepack-0.1.0-1.rockspec000066400000000000000000000014431253234330000236520ustar00rootroot00000000000000package = 'lua-MessagePack' version = '0.1.0-1' source = { url = 'http://cloud.github.com/downloads/fperrad/lua-MessagePack/lua-messagepack-0.1.0.tar.gz', md5 = '3fb1625aa2b277d7913ee090fd770d87', dir = 'lua-MessagePack-0.1.0', } description = { summary = "a pure Lua implementation", detailed = [[ MessagePack is an efficient binary serialization format. It lets you exchange data among multiple languages like JSON but it's faster and smaller. ]], homepage = 'http://fperrad.github.com/lua-MessagePack/', maintainer = 'Francois Perrad', license = 'MIT/X11' } dependencies = { 'lua >= 5.1', } build = { type = 'builtin', modules = { ['MessagePack'] = 'src/MessagePack.lua', }, copy_directories = { 'doc', 'test' }, } lua-MessagePack-0.3.3/rockspec/lua-messagepack-0.2.0-1.rockspec000066400000000000000000000014431253234330000236530ustar00rootroot00000000000000package = 'lua-MessagePack' version = '0.2.0-1' source = { url = 'http://cloud.github.com/downloads/fperrad/lua-MessagePack/lua-messagepack-0.2.0.tar.gz', md5 = 'bf08ae0e81c83fa512be9041a45de44e', dir = 'lua-MessagePack-0.2.0', } description = { summary = "a pure Lua implementation", detailed = [[ MessagePack is an efficient binary serialization format. It lets you exchange data among multiple languages like JSON but it's faster and smaller. ]], homepage = 'http://fperrad.github.com/lua-MessagePack/', maintainer = 'Francois Perrad', license = 'MIT/X11' } dependencies = { 'lua >= 5.1', } build = { type = 'builtin', modules = { ['MessagePack'] = 'src/MessagePack.lua', }, copy_directories = { 'doc', 'test' }, } lua-MessagePack-0.3.3/rockspec/lua-messagepack-0.2.1-1.rockspec000066400000000000000000000014431253234330000236540ustar00rootroot00000000000000package = 'lua-MessagePack' version = '0.2.1-1' source = { url = 'http://cloud.github.com/downloads/fperrad/lua-MessagePack/lua-messagepack-0.2.1.tar.gz', md5 = '867da634cbe61e83e6d052435afa8eaa', dir = 'lua-MessagePack-0.2.1', } description = { summary = "a pure Lua implementation", detailed = [[ MessagePack is an efficient binary serialization format. It lets you exchange data among multiple languages like JSON but it's faster and smaller. ]], homepage = 'http://fperrad.github.com/lua-MessagePack/', maintainer = 'Francois Perrad', license = 'MIT/X11' } dependencies = { 'lua >= 5.1', } build = { type = 'builtin', modules = { ['MessagePack'] = 'src/MessagePack.lua', }, copy_directories = { 'doc', 'test' }, } lua-MessagePack-0.3.3/rockspec/lua-messagepack-0.2.2-1.rockspec000066400000000000000000000014651253234330000236610ustar00rootroot00000000000000package = 'lua-MessagePack' version = '0.2.2-1' source = { url = 'http://sites.google.com/site/fperrad/lua-messagepack-0.2.2.tar.gz', md5 = '6b0e08e6b877d2bb9ada27fd6b20fd95', dir = 'lua-MessagePack-0.2.2', } description = { summary = "a pure Lua implementation of the MessagePack serialization format", detailed = [[ MessagePack is an efficient binary serialization format. It lets you exchange data among multiple languages like JSON but it's faster and smaller. ]], homepage = 'http://fperrad.github.io/lua-MessagePack/', maintainer = 'Francois Perrad', license = 'MIT/X11' } dependencies = { 'lua >= 5.1', } build = { type = 'builtin', modules = { ['MessagePack'] = 'src/MessagePack.lua', }, copy_directories = { 'doc', 'test' }, } lua-MessagePack-0.3.3/rockspec/lua-messagepack-0.3.0-1.rockspec000066400000000000000000000014651253234330000236600ustar00rootroot00000000000000package = 'lua-MessagePack' version = '0.3.0-1' source = { url = 'http://sites.google.com/site/fperrad/lua-messagepack-0.3.0.tar.gz', md5 = 'ef645a32b779d1a80f2b4f1477111fd7', dir = 'lua-MessagePack-0.3.0', } description = { summary = "a pure Lua implementation of the MessagePack serialization format", detailed = [[ MessagePack is an efficient binary serialization format. It lets you exchange data among multiple languages like JSON but it's faster and smaller. ]], homepage = 'http://fperrad.github.io/lua-MessagePack/', maintainer = 'Francois Perrad', license = 'MIT/X11' } dependencies = { 'lua >= 5.1', } build = { type = 'builtin', modules = { ['MessagePack'] = 'src/MessagePack.lua', }, copy_directories = { 'doc', 'test' }, } lua-MessagePack-0.3.3/rockspec/lua-messagepack-0.3.1-1.rockspec000066400000000000000000000014651253234330000236610ustar00rootroot00000000000000package = 'lua-MessagePack' version = '0.3.1-1' source = { url = 'http://sites.google.com/site/fperrad/lua-messagepack-0.3.1.tar.gz', md5 = '3b11cbd32c9dfe3bbc493eae33ab8cab', dir = 'lua-MessagePack-0.3.1', } description = { summary = "a pure Lua implementation of the MessagePack serialization format", detailed = [[ MessagePack is an efficient binary serialization format. It lets you exchange data among multiple languages like JSON but it's faster and smaller. ]], homepage = 'http://fperrad.github.io/lua-MessagePack/', maintainer = 'Francois Perrad', license = 'MIT/X11' } dependencies = { 'lua >= 5.1', } build = { type = 'builtin', modules = { ['MessagePack'] = 'src/MessagePack.lua', }, copy_directories = { 'doc', 'test' }, } lua-MessagePack-0.3.3/rockspec/lua-messagepack-0.3.2-1.rockspec000066400000000000000000000014651253234330000236620ustar00rootroot00000000000000package = 'lua-MessagePack' version = '0.3.2-1' source = { url = 'http://sites.google.com/site/fperrad/lua-messagepack-0.3.2.tar.gz', md5 = '1576021d86773520ed46936f993e7832', dir = 'lua-MessagePack-0.3.2', } description = { summary = "a pure Lua implementation of the MessagePack serialization format", detailed = [[ MessagePack is an efficient binary serialization format. It lets you exchange data among multiple languages like JSON but it's faster and smaller. ]], homepage = 'http://fperrad.github.io/lua-MessagePack/', maintainer = 'Francois Perrad', license = 'MIT/X11' } dependencies = { 'lua >= 5.1', } build = { type = 'builtin', modules = { ['MessagePack'] = 'src/MessagePack.lua', }, copy_directories = { 'doc', 'test' }, } lua-MessagePack-0.3.3/rockspec/lua-messagepack-0.3.3-1.rockspec000066400000000000000000000014651253234330000236630ustar00rootroot00000000000000package = 'lua-MessagePack' version = '0.3.3-1' source = { url = 'http://sites.google.com/site/fperrad/lua-messagepack-0.3.3.tar.gz', md5 = '906324e7e2311ded347f7e68de467adf', dir = 'lua-MessagePack-0.3.3', } description = { summary = "a pure Lua implementation of the MessagePack serialization format", detailed = [[ MessagePack is an efficient binary serialization format. It lets you exchange data among multiple languages like JSON but it's faster and smaller. ]], homepage = 'http://fperrad.github.io/lua-MessagePack/', maintainer = 'Francois Perrad', license = 'MIT/X11' } dependencies = { 'lua >= 5.1', } build = { type = 'builtin', modules = { ['MessagePack'] = 'src/MessagePack.lua', }, copy_directories = { 'doc', 'test' }, } lua-MessagePack-0.3.3/rockspec/lua-messagepack-lua53-0.3.2-1.rockspec000066400000000000000000000014761253234330000246130ustar00rootroot00000000000000package = 'lua-MessagePack-lua53' version = '0.3.2-1' source = { url = 'http://sites.google.com/site/fperrad/lua-messagepack-0.3.2.tar.gz', md5 = '1576021d86773520ed46936f993e7832', dir = 'lua-MessagePack-0.3.2', } description = { summary = "a pure Lua implementation of the MessagePack serialization format", detailed = [[ MessagePack is an efficient binary serialization format. It lets you exchange data among multiple languages like JSON but it's faster and smaller. ]], homepage = 'http://fperrad.github.io/lua-MessagePack/', maintainer = 'Francois Perrad', license = 'MIT/X11' } dependencies = { 'lua >= 5.3', } build = { type = 'builtin', modules = { ['MessagePack'] = 'src5.3/MessagePack.lua', }, copy_directories = { 'doc', 'test' }, } lua-MessagePack-0.3.3/rockspec/lua-messagepack-lua53-0.3.3-1.rockspec000066400000000000000000000014761253234330000246140ustar00rootroot00000000000000package = 'lua-MessagePack-lua53' version = '0.3.3-1' source = { url = 'http://sites.google.com/site/fperrad/lua-messagepack-0.3.3.tar.gz', md5 = '906324e7e2311ded347f7e68de467adf', dir = 'lua-MessagePack-0.3.3', } description = { summary = "a pure Lua implementation of the MessagePack serialization format", detailed = [[ MessagePack is an efficient binary serialization format. It lets you exchange data among multiple languages like JSON but it's faster and smaller. ]], homepage = 'http://fperrad.github.io/lua-MessagePack/', maintainer = 'Francois Perrad', license = 'MIT/X11' } dependencies = { 'lua >= 5.3', } build = { type = 'builtin', modules = { ['MessagePack'] = 'src5.3/MessagePack.lua', }, copy_directories = { 'doc', 'test' }, } lua-MessagePack-0.3.3/src/000077500000000000000000000000001253234330000152415ustar00rootroot00000000000000lua-MessagePack-0.3.3/src/MessagePack.lua000066400000000000000000001013201253234330000201240ustar00rootroot00000000000000-- -- lua-MessagePack : -- local r, jit = pcall(require, 'jit') if not r then jit = nil end local SIZEOF_NUMBER = string.pack and #string.pack('n', 0.0) or 8 local NUMBER_INTEGRAL = math.type and (math.type(0.0) == math.type(0)) or false if not jit and _VERSION < 'Lua 5.3' then -- Lua 5.1 & 5.2 local loadstring = loadstring or load local luac = string.dump(loadstring "a = 1") local header = { luac:sub(1, 12):byte(1, 12) } SIZEOF_NUMBER = header[11] NUMBER_INTEGRAL = 1 == header[12] end local assert = assert local error = error local pairs = pairs local pcall = pcall local setmetatable = setmetatable local tostring = tostring local type = type local char = require'string'.char local floor = require'math'.floor local tointeger = require'math'.tointeger or floor local frexp = require'math'.frexp or require'mathx'.frexp local ldexp = require'math'.ldexp or require'mathx'.ldexp local huge = require'math'.huge local tconcat = require'table'.concat --[[ debug only local format = require'string'.format local function hexadump (s) return (s:gsub('.', function (c) return format('%02X ', c:byte()) end)) end --]] local _ENV = nil local m = {} --[[ debug only m.hexadump = hexadump --]] local function argerror (caller, narg, extramsg) error("bad argument #" .. tostring(narg) .. " to " .. caller .. " (" .. extramsg .. ")") end local function typeerror (caller, narg, arg, tname) argerror(caller, narg, tname .. " expected, got " .. type(arg)) end local function checktype (caller, narg, arg, tname) if type(arg) ~= tname then typeerror(caller, narg, arg, tname) end end local packers = setmetatable({}, { __index = function (t, k) error("pack '" .. k .. "' is unimplemented") end }) m.packers = packers packers['nil'] = function (buffer) buffer[#buffer+1] = char(0xC0) -- nil end packers['boolean'] = function (buffer, bool) if bool then buffer[#buffer+1] = char(0xC3) -- true else buffer[#buffer+1] = char(0xC2) -- false end end packers['string_compat'] = function (buffer, str) local n = #str if n <= 0x1F then buffer[#buffer+1] = char(0xA0 + n) -- fixstr elseif n <= 0xFFFF then buffer[#buffer+1] = char(0xDA, -- str16 floor(n / 0x100), n % 0x100) elseif n <= 4294967295.0 then buffer[#buffer+1] = char(0xDB, -- str32 floor(n / 0x1000000), floor(n / 0x10000) % 0x100, floor(n / 0x100) % 0x100, n % 0x100) else error"overflow in pack 'string_compat'" end buffer[#buffer+1] = str end packers['_string'] = function (buffer, str) local n = #str if n <= 0x1F then buffer[#buffer+1] = char(0xA0 + n) -- fixstr elseif n <= 0xFF then buffer[#buffer+1] = char(0xD9, -- str8 n) elseif n <= 0xFFFF then buffer[#buffer+1] = char(0xDA, -- str16 floor(n / 0x100), n % 0x100) elseif n <= 4294967295.0 then buffer[#buffer+1] = char(0xDB, -- str32 floor(n / 0x1000000), floor(n / 0x10000) % 0x100, floor(n / 0x100) % 0x100, n % 0x100) else error"overflow in pack 'string'" end buffer[#buffer+1] = str end packers['binary'] = function (buffer, str) local n = #str if n <= 0xFF then buffer[#buffer+1] = char(0xC4, -- bin8 n) elseif n <= 0xFFFF then buffer[#buffer+1] = char(0xC5, -- bin16 floor(n / 0x100), n % 0x100) elseif n <= 4294967295.0 then buffer[#buffer+1] = char(0xC6, -- bin32 floor(n / 0x1000000), floor(n / 0x10000) % 0x100, floor(n / 0x100) % 0x100, n % 0x100) else error"overflow in pack 'binary'" end buffer[#buffer+1] = str end local set_string = function (str) if str == 'string_compat' then packers['string'] = packers['string_compat'] elseif str == 'string' then packers['string'] = packers['_string'] elseif str == 'binary' then packers['string'] = packers['binary'] else argerror('set_string', 1, "invalid option '" .. str .."'") end end m.set_string = set_string packers['map'] = function (buffer, tbl, n) if n <= 0x0F then buffer[#buffer+1] = char(0x80 + n) -- fixmap elseif n <= 0xFFFF then buffer[#buffer+1] = char(0xDE, -- map16 floor(n / 0x100), n % 0x100) elseif n <= 4294967295.0 then buffer[#buffer+1] = char(0xDF, -- map32 floor(n / 0x1000000), floor(n / 0x10000) % 0x100, floor(n / 0x100) % 0x100, n % 0x100) else error"overflow in pack 'map'" end for k, v in pairs(tbl) do packers[type(k)](buffer, k) packers[type(v)](buffer, v) end end packers['array'] = function (buffer, tbl, n) if n <= 0x0F then buffer[#buffer+1] = char(0x90 + n) -- fixarray elseif n <= 0xFFFF then buffer[#buffer+1] = char(0xDC, -- array16 floor(n / 0x100), n % 0x100) elseif n <= 4294967295.0 then buffer[#buffer+1] = char(0xDD, -- array32 floor(n / 0x1000000), floor(n / 0x10000) % 0x100, floor(n / 0x100) % 0x100, n % 0x100) else error"overflow in pack 'array'" end for i = 1, n do local v = tbl[i] packers[type(v)](buffer, v) end end local set_array = function (array) if array == 'without_hole' then packers['_table'] = function (buffer, tbl) local is_map, n, max = false, 0, 0 for k in pairs(tbl) do if type(k) == 'number' and k > 0 then if k > max then max = k end else is_map = true end n = n + 1 end if max ~= n then -- there are holes is_map = true end if is_map then return packers['map'](buffer, tbl, n) else return packers['array'](buffer, tbl, n) end end elseif array == 'with_hole' then packers['_table'] = function (buffer, tbl) local is_map, n, max = false, 0, 0 for k in pairs(tbl) do if type(k) == 'number' and k > 0 then if k > max then max = k end else is_map = true end n = n + 1 end if is_map then return packers['map'](buffer, tbl, n) else return packers['array'](buffer, tbl, max) end end elseif array == 'always_as_map' then packers['_table'] = function(buffer, tbl) local n = 0 for k in pairs(tbl) do n = n + 1 end return packers['map'](buffer, tbl, n) end else argerror('set_array', 1, "invalid option '" .. array .."'") end end m.set_array = set_array packers['table'] = function (buffer, tbl) return packers['_table'](buffer, tbl) end packers['unsigned'] = function (buffer, n) if n >= 0 then if n <= 0x7F then buffer[#buffer+1] = char(n) -- fixnum_pos elseif n <= 0xFF then buffer[#buffer+1] = char(0xCC, -- uint8 n) elseif n <= 0xFFFF then buffer[#buffer+1] = char(0xCD, -- uint16 floor(n / 0x100), n % 0x100) elseif n <= 4294967295.0 then buffer[#buffer+1] = char(0xCE, -- uint32 floor(n / 0x1000000), floor(n / 0x10000) % 0x100, floor(n / 0x100) % 0x100, n % 0x100) else buffer[#buffer+1] = char(0xCF, -- uint64 0, -- only 53 bits from double floor(n / 0x1000000000000) % 0x100, floor(n / 0x10000000000) % 0x100, floor(n / 0x100000000) % 0x100, floor(n / 0x1000000) % 0x100, floor(n / 0x10000) % 0x100, floor(n / 0x100) % 0x100, n % 0x100) end else if n >= -0x20 then buffer[#buffer+1] = char(0x100 + n) -- fixnum_neg elseif n >= -0x80 then buffer[#buffer+1] = char(0xD0, -- int8 0x100 + n) elseif n >= -0x8000 then n = 0x10000 + n buffer[#buffer+1] = char(0xD1, -- int16 floor(n / 0x100), n % 0x100) elseif n >= -0x80000000 then n = 4294967296.0 + n buffer[#buffer+1] = char(0xD2, -- int32 floor(n / 0x1000000), floor(n / 0x10000) % 0x100, floor(n / 0x100) % 0x100, n % 0x100) else buffer[#buffer+1] = char(0xD3, -- int64 0xFF, -- only 53 bits from double floor(n / 0x1000000000000) % 0x100, floor(n / 0x10000000000) % 0x100, floor(n / 0x100000000) % 0x100, floor(n / 0x1000000) % 0x100, floor(n / 0x10000) % 0x100, floor(n / 0x100) % 0x100, n % 0x100) end end end packers['signed'] = function (buffer, n) if n >= 0 then if n <= 0x7F then buffer[#buffer+1] = char(n) -- fixnum_pos elseif n <= 0x7FFF then buffer[#buffer+1] = char(0xD1, -- int16 floor(n / 0x100), n % 0x100) elseif n <= 0x7FFFFFFF then buffer[#buffer+1] = char(0xD2, -- int32 floor(n / 0x1000000), floor(n / 0x10000) % 0x100, floor(n / 0x100) % 0x100, n % 0x100) else buffer[#buffer+1] = char(0xD3, -- int64 0, -- only 53 bits from double floor(n / 0x1000000000000) % 0x100, floor(n / 0x10000000000) % 0x100, floor(n / 0x100000000) % 0x100, floor(n / 0x1000000) % 0x100, floor(n / 0x10000) % 0x100, floor(n / 0x100) % 0x100, n % 0x100) end else if n >= -0x20 then buffer[#buffer+1] = char(0xE0 + 0x20 + n) -- fixnum_neg elseif n >= -0x80 then buffer[#buffer+1] = char(0xD0, -- int8 0x100 + n) elseif n >= -0x8000 then n = 0x10000 + n buffer[#buffer+1] = char(0xD1, -- int16 floor(n / 0x100), n % 0x100) elseif n >= -0x80000000 then n = 4294967296.0 + n buffer[#buffer+1] = char(0xD2, -- int32 floor(n / 0x1000000), floor(n / 0x10000) % 0x100, floor(n / 0x100) % 0x100, n % 0x100) else buffer[#buffer+1] = char(0xD3, -- int64 0xFF, -- only 53 bits from double floor(n / 0x1000000000000) % 0x100, floor(n / 0x10000000000) % 0x100, floor(n / 0x100000000) % 0x100, floor(n / 0x1000000) % 0x100, floor(n / 0x10000) % 0x100, floor(n / 0x100) % 0x100, n % 0x100) end end end local set_integer = function (integer) if integer == 'unsigned' then packers['integer'] = packers['unsigned'] elseif integer == 'signed' then packers['integer'] = packers['signed'] else argerror('set_integer', 1, "invalid option '" .. integer .."'") end end m.set_integer = set_integer packers['float'] = function (buffer, n) local sign = 0 if n < 0.0 then sign = 0x80 n = -n end local mant, expo = frexp(n) if mant ~= mant then buffer[#buffer+1] = char(0xCA, -- nan 0xFF, 0x88, 0x00, 0x00) elseif mant == huge or expo > 0x80 then if sign == 0 then buffer[#buffer+1] = char(0xCA, -- inf 0x7F, 0x80, 0x00, 0x00) else buffer[#buffer+1] = char(0xCA, -- -inf 0xFF, 0x80, 0x00, 0x00) end elseif (mant == 0.0 and expo == 0) or expo < -0x7E then buffer[#buffer+1] = char(0xCA, -- zero sign, 0x00, 0x00, 0x00) else expo = expo + 0x7E mant = (mant * 2.0 - 1.0) * ldexp(0.5, 24) buffer[#buffer+1] = char(0xCA, sign + floor(expo / 0x2), (expo % 0x2) * 0x80 + floor(mant / 0x10000), floor(mant / 0x100) % 0x100, mant % 0x100) end end packers['double'] = function (buffer, n) local sign = 0 if n < 0.0 then sign = 0x80 n = -n end local mant, expo = frexp(n) if mant ~= mant then buffer[#buffer+1] = char(0xCB, -- nan 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00) elseif mant == huge then if sign == 0 then buffer[#buffer+1] = char(0xCB, -- inf 0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00) else buffer[#buffer+1] = char(0xCB, -- -inf 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00) end elseif mant == 0.0 and expo == 0 then buffer[#buffer+1] = char(0xCB, -- zero sign, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00) else expo = expo + 0x3FE mant = (mant * 2.0 - 1.0) * ldexp(0.5, 53) buffer[#buffer+1] = char(0xCB, sign + floor(expo / 0x10), (expo % 0x10) * 0x10 + floor(mant / 0x1000000000000), floor(mant / 0x10000000000) % 0x100, floor(mant / 0x100000000) % 0x100, floor(mant / 0x1000000) % 0x100, floor(mant / 0x10000) % 0x100, floor(mant / 0x100) % 0x100, mant % 0x100) end end local set_number = function (number) if number == 'integer' then packers['number'] = packers['signed'] elseif number == 'float' then packers['number'] = function (buffer, n) if floor(n) ~= n or n ~= n or n > 3.40282347e+38 or n < -3.40282347e+38 then return packers['float'](buffer, n) else return packers['integer'](buffer, n) end end elseif number == 'double' then packers['number'] = function (buffer, n) if floor(n) ~= n or n ~= n or n == huge or n == -huge then return packers['double'](buffer, n) else return packers['integer'](buffer, n) end end else argerror('set_number', 1, "invalid option '" .. number .."'") end end m.set_number = set_number for k = 0, 4 do local n = tointeger(2^k) local fixext = 0xD4 + k packers['fixext' .. tostring(n)] = function (buffer, tag, data) assert(#data == n, "bad length for fixext" .. tostring(n)) buffer[#buffer+1] = char(fixext, tag < 0 and tag + 0x100 or tag) buffer[#buffer+1] = data end end packers['ext'] = function (buffer, tag, data) local n = #data if n <= 0xFF then buffer[#buffer+1] = char(0xC7, -- ext8 n, tag < 0 and tag + 0x100 or tag) elseif n <= 0xFFFF then buffer[#buffer+1] = char(0xC8, -- ext16 floor(n / 0x100), n % 0x100, tag < 0 and tag + 0x100 or tag) elseif n <= 4294967295.0 then buffer[#buffer+1] = char(0xC9, -- ext&32 floor(n / 0x1000000), floor(n / 0x10000) % 0x100, floor(n / 0x100) % 0x100, n % 0x100, tag < 0 and tag + 0x100 or tag) else error"overflow in pack 'ext'" end buffer[#buffer+1] = data end function m.pack (data) local buffer = {} packers[type(data)](buffer, data) return tconcat(buffer) end local types_map = setmetatable({ [0xC0] = 'nil', [0xC2] = 'false', [0xC3] = 'true', [0xC4] = 'bin8', [0xC5] = 'bin16', [0xC6] = 'bin32', [0xC7] = 'ext8', [0xC8] = 'ext16', [0xC9] = 'ext32', [0xCA] = 'float', [0xCB] = 'double', [0xCC] = 'uint8', [0xCD] = 'uint16', [0xCE] = 'uint32', [0xCF] = 'uint64', [0xD0] = 'int8', [0xD1] = 'int16', [0xD2] = 'int32', [0xD3] = 'int64', [0xD4] = 'fixext1', [0xD5] = 'fixext2', [0xD6] = 'fixext4', [0xD7] = 'fixext8', [0xD8] = 'fixext16', [0xD9] = 'str8', [0xDA] = 'str16', [0xDB] = 'str32', [0xDC] = 'array16', [0xDD] = 'array32', [0xDE] = 'map16', [0xDF] = 'map32', }, { __index = function (t, k) if k < 0xC0 then if k < 0x80 then return 'fixnum_pos' elseif k < 0x90 then return 'fixmap' elseif k < 0xA0 then return 'fixarray' else return 'fixstr' end elseif k > 0xDF then return 'fixnum_neg' else return 'reserved' .. tostring(k) end end }) m.types_map = types_map local unpackers = setmetatable({}, { __index = function (t, k) error("unpack '" .. k .. "' is unimplemented") end }) m.unpackers = unpackers local function unpack_array (c, n) local t = {} local decode = unpackers['any'] for i = 1, n do t[i] = decode(c) end return t end local function unpack_map (c, n) local t = {} local decode = unpackers['any'] for i = 1, n do local k = decode(c) local val = decode(c) if k == nil then k = m.sentinel end if k ~= nil then t[k] = val end end return t end unpackers['any'] = function (c) local s, i, j = c.s, c.i, c.j if i > j then c:underflow(i) s, i, j = c.s, c.i, c.j end local val = s:sub(i, i):byte() c.i = i+1 return unpackers[types_map[val]](c, val) end unpackers['nil'] = function () return nil end unpackers['false'] = function () return false end unpackers['true'] = function () return true end unpackers['float'] = function (c) local s, i, j = c.s, c.i, c.j if i+3 > j then c:underflow(i+3) s, i, j = c.s, c.i, c.j end local b1, b2, b3, b4 = s:sub(i, i+3):byte(1, 4) local sign = b1 > 0x7F local expo = (b1 % 0x80) * 0x2 + floor(b2 / 0x80) local mant = ((b2 % 0x80) * 0x100 + b3) * 0x100 + b4 if sign then sign = -1 else sign = 1 end local n if mant == 0 and expo == 0 then n = sign * 0.0 elseif expo == 0xFF then if mant == 0 then n = sign * huge else n = 0.0/0.0 end else n = sign * ldexp(1.0 + mant / 0x800000, expo - 0x7F) end c.i = i+4 return n end unpackers['double'] = function (c) local s, i, j = c.s, c.i, c.j if i+7 > j then c:underflow(i+7) s, i, j = c.s, c.i, c.j end local b1, b2, b3, b4, b5, b6, b7, b8 = s:sub(i, i+7):byte(1, 8) local sign = b1 > 0x7F local expo = (b1 % 0x80) * 0x10 + floor(b2 / 0x10) local mant = ((((((b2 % 0x10) * 0x100 + b3) * 0x100 + b4) * 0x100 + b5) * 0x100 + b6) * 0x100 + b7) * 0x100 + b8 if sign then sign = -1 else sign = 1 end local n if mant == 0 and expo == 0 then n = sign * 0.0 elseif expo == 0x7FF then if mant == 0 then n = sign * huge else n = 0.0/0.0 end else n = sign * ldexp(1.0 + mant / 4503599627370496.0, expo - 0x3FF) end c.i = i+8 return n end unpackers['fixnum_pos'] = function (c, val) return val end unpackers['uint8'] = function (c) local s, i, j = c.s, c.i, c.j if i > j then c:underflow(i) s, i, j = c.s, c.i, c.j end local b1 = s:sub(i, i):byte() c.i = i+1 return b1 end unpackers['uint16'] = function (c) local s, i, j = c.s, c.i, c.j if i+1 > j then c:underflow(i+1) s, i, j = c.s, c.i, c.j end local b1, b2 = s:sub(i, i+1):byte(1, 2) c.i = i+2 return b1 * 0x100 + b2 end unpackers['uint32'] = function (c) local s, i, j = c.s, c.i, c.j if i+3 > j then c:underflow(i+3) s, i, j = c.s, c.i, c.j end local b1, b2, b3, b4 = s:sub(i, i+3):byte(1, 4) c.i = i+4 return ((b1 * 0x100 + b2) * 0x100 + b3) * 0x100 + b4 end unpackers['uint64'] = function (c) local s, i, j = c.s, c.i, c.j if i+7 > j then c:underflow(i+7) s, i, j = c.s, c.i, c.j end local b1, b2, b3, b4, b5, b6, b7, b8 = s:sub(i, i+7):byte(1, 8) c.i = i+8 return ((((((b1 * 0x100 + b2) * 0x100 + b3) * 0x100 + b4) * 0x100 + b5) * 0x100 + b6) * 0x100 + b7) * 0x100 + b8 end unpackers['fixnum_neg'] = function (c, val) return val - 0x100 end unpackers['int8'] = function (c) local s, i, j = c.s, c.i, c.j if i > j then c:underflow(i) s, i, j = c.s, c.i, c.j end local b1 = s:sub(i, i):byte() c.i = i+1 if b1 < 0x80 then return b1 else return b1 - 0x100 end end unpackers['int16'] = function (c) local s, i, j = c.s, c.i, c.j if i+1 > j then c:underflow(i+1) s, i, j = c.s, c.i, c.j end local b1, b2 = s:sub(i, i+1):byte(1, 2) c.i = i+2 if b1 < 0x80 then return b1 * 0x100 + b2 else return ((b1 - 0xFF) * 0x100 + (b2 - 0xFF)) - 1 end end unpackers['int32'] = function (c) local s, i, j = c.s, c.i, c.j if i+3 > j then c:underflow(i+3) s, i, j = c.s, c.i, c.j end local b1, b2, b3, b4 = s:sub(i, i+3):byte(1, 4) c.i = i+4 if b1 < 0x80 then return ((b1 * 0x100 + b2) * 0x100 + b3) * 0x100 + b4 else return ((((b1 - 0xFF) * 0x100 + (b2 - 0xFF)) * 0x100 + (b3 - 0xFF)) * 0x100 + (b4 - 0xFF)) - 1 end end unpackers['int64'] = function (c) local s, i, j = c.s, c.i, c.j if i+7 > j then c:underflow(i+7) s, i, j = c.s, c.i, c.j end local b1, b2, b3, b4, b5, b6, b7, b8 = s:sub(i, i+7):byte(1, 8) c.i = i+8 if b1 < 0x80 then return ((((((b1 * 0x100 + b2) * 0x100 + b3) * 0x100 + b4) * 0x100 + b5) * 0x100 + b6) * 0x100 + b7) * 0x100 + b8 else return ((((((((b1 - 0xFF) * 0x100 + (b2 - 0xFF)) * 0x100 + (b3 - 0xFF)) * 0x100 + (b4 - 0xFF)) * 0x100 + (b5 - 0xFF)) * 0x100 + (b6 - 0xFF)) * 0x100 + (b7 - 0xFF)) * 0x100 + (b8 - 0xFF)) - 1 end end unpackers['fixstr'] = function (c, val) local s, i, j = c.s, c.i, c.j local n = val % 0x20 local e = i+n-1 if e > j then c:underflow(e) s, i, j = c.s, c.i, c.j e = i+n-1 end c.i = i+n return s:sub(i, e) end unpackers['str8'] = function (c) local s, i, j = c.s, c.i, c.j if i > j then c:underflow(i) s, i, j = c.s, c.i, c.j end local n = s:sub(i, i):byte() i = i+1 c.i = i local e = i+n-1 if e > j then c:underflow(e) s, i, j = c.s, c.i, c.j e = i+n-1 end c.i = i+n return s:sub(i, e) end unpackers['str16'] = function (c) local s, i, j = c.s, c.i, c.j if i+1 > j then c:underflow(i+1) s, i, j = c.s, c.i, c.j end local b1, b2 = s:sub(i, i+1):byte(1, 2) i = i+2 c.i = i local n = b1 * 0x100 + b2 local e = i+n-1 if e > j then c:underflow(e) s, i, j = c.s, c.i, c.j e = i+n-1 end c.i = i+n return s:sub(i, e) end unpackers['str32'] = function (c) local s, i, j = c.s, c.i, c.j if i+3 > j then c:underflow(i+3) s, i, j = c.s, c.i, c.j end local b1, b2, b3, b4 = s:sub(i, i+3):byte(1, 4) i = i+4 c.i = i local n = ((b1 * 0x100 + b2) * 0x100 + b3) * 0x100 + b4 local e = i+n-1 if e > j then c:underflow(e) s, i, j = c.s, c.i, c.j e = i+n-1 end c.i = i+n return s:sub(i, e) end unpackers['bin8'] = unpackers['str8'] unpackers['bin16'] = unpackers['str16'] unpackers['bin32'] = unpackers['str32'] unpackers['fixarray'] = function (c, val) return unpack_array(c, val % 0x10) end unpackers['array16'] = function (c) local s, i, j = c.s, c.i, c.j if i+1 > j then c:underflow(i+1) s, i, j = c.s, c.i, c.j end local b1, b2 = s:sub(i, i+1):byte(1, 2) c.i = i+2 return unpack_array(c, b1 * 0x100 + b2) end unpackers['array32'] = function (c) local s, i, j = c.s, c.i, c.j if i+3 > j then c:underflow(i+3) s, i, j = c.s, c.i, c.j end local b1, b2, b3, b4 = s:sub(i, i+3):byte(1, 4) c.i = i+4 return unpack_array(c, ((b1 * 0x100 + b2) * 0x100 + b3) * 0x100 + b4) end unpackers['fixmap'] = function (c, val) return unpack_map(c, val % 0x10) end unpackers['map16'] = function (c) local s, i, j = c.s, c.i, c.j if i+1 > j then c:underflow(i+1) s, i, j = c.s, c.i, c.j end local b1, b2 = s:sub(i, i+1):byte(1, 2) c.i = i+2 return unpack_map(c, b1 * 0x100 + b2) end unpackers['map32'] = function (c) local s, i, j = c.s, c.i, c.j if i+3 > j then c:underflow(i+3) s, i, j = c.s, c.i, c.j end local b1, b2, b3, b4 = s:sub(i, i+3):byte(1, 4) c.i = i+4 return unpack_map(c, ((b1 * 0x100 + b2) * 0x100 + b3) * 0x100 + b4) end function m.build_ext (tag, data) return nil end for k = 0, 4 do local n = tointeger(2^k) unpackers['fixext' .. tostring(n)] = function (c) local s, i, j = c.s, c.i, c.j if i > j then c:underflow(i) s, i, j = c.s, c.i, c.j end local tag = s:sub(i, i):byte() i = i+1 c.i = i local e = i+n-1 if e > j then c:underflow(e) s, i, j = c.s, c.i, c.j e = i+n-1 end c.i = i+n return m.build_ext(tag < 0x80 and tag or tag - 0x100, s:sub(i, e)) end end unpackers['ext8'] = function (c) local s, i, j = c.s, c.i, c.j if i > j then c:underflow(i) s, i, j = c.s, c.i, c.j end local n = s:sub(i, i):byte() i = i+1 c.i = i if i > j then c:underflow(i) s, i, j = c.s, c.i, c.j end local tag = s:sub(i, i):byte() i = i+1 c.i = i local e = i+n-1 if e > j then c:underflow(e) s, i, j = c.s, c.i, c.j e = i+n-1 end c.i = i+n return m.build_ext(tag < 0x80 and tag or tag - 0x100, s:sub(i, e)) end unpackers['ext16'] = function (c) local s, i, j = c.s, c.i, c.j if i+1 > j then c:underflow(i+1) s, i, j = c.s, c.i, c.j end local b1, b2 = s:sub(i, i+1):byte(1, 2) i = i+2 c.i = i local n = b1 * 0x100 + b2 if i > j then c:underflow(i) s, i, j = c.s, c.i, c.j end local tag = s:sub(i, i):byte() i = i+1 c.i = i local e = i+n-1 if e > j then c:underflow(e) s, i, j = c.s, c.i, c.j e = i+n-1 end c.i = i+n return m.build_ext(tag < 0x80 and tag or tag - 0x100, s:sub(i, e)) end unpackers['ext32'] = function (c) local s, i, j = c.s, c.i, c.j if i+3 > j then c:underflow(i+3) s, i, j = c.s, c.i, c.j end local b1, b2, b3, b4 = s:sub(i, i+3):byte(1, 4) i = i+4 c.i = i local n = ((b1 * 0x100 + b2) * 0x100 + b3) * 0x100 + b4 if i > j then c:underflow(i) s, i, j = c.s, c.i, c.j end local tag = s:sub(i, i):byte() i = i+1 c.i = i local e = i+n-1 if e > j then c:underflow(e) s, i, j = c.s, c.i, c.j e = i+n-1 end c.i = i+n return m.build_ext(tag < 0x80 and tag or tag - 0x100, s:sub(i, e)) end local function cursor_string (str) return { s = str, i = 1, j = #str, underflow = function (self) error "missing bytes" end, } end local function cursor_loader (ld) return { s = '', i = 1, j = 0, underflow = function (self, e) self.s = self.s:sub(self.i) e = e - self.i + 1 self.i = 1 self.j = 0 while e > self.j do local chunk = ld() if not chunk then error "missing bytes" end self.s = self.s .. chunk self.j = #self.s end end, } end function m.unpack (s) checktype('unpack', 1, s, 'string') local cursor = cursor_string(s) local data = unpackers['any'](cursor) if cursor.i < cursor.j then error "extra bytes" end return data end function m.unpacker (src) if type(src) == 'string' then local cursor = cursor_string(src) return function () if cursor.i <= cursor.j then return cursor.i, unpackers['any'](cursor) end end elseif type(src) == 'function' then local cursor = cursor_loader(src) return function () if cursor.i > cursor.j then pcall(cursor.underflow, cursor, cursor.i) end if cursor.i <= cursor.j then return true, unpackers['any'](cursor) end end else argerror('unpacker', 1, "string or function expected, got " .. type(src)) end end set_string'string_compat' set_integer'unsigned' if NUMBER_INTEGRAL then packers['double'] = packers['integer'] packers['float'] = packers['integer'] set_number'integer' elseif SIZEOF_NUMBER == 4 then packers['double'] = packers['float'] m.small_lua = true set_number'float' else set_number'double' end set_array'without_hole' m._VERSION = '0.3.3' m._DESCRIPTION = "lua-MessagePack : a pure Lua implementation" m._COPYRIGHT = "Copyright (c) 2012-2015 Francois Perrad" return m -- -- This library is licensed under the terms of the MIT/X11 license, -- like Lua itself. -- lua-MessagePack-0.3.3/src5.3/000077500000000000000000000000001253234330000154675ustar00rootroot00000000000000lua-MessagePack-0.3.3/src5.3/MessagePack.lua000066400000000000000000000550061253234330000203630ustar00rootroot00000000000000-- -- lua-MessagePack : -- local assert = assert local error = error local pairs = pairs local pcall = pcall local setmetatable = setmetatable local tostring = tostring local type = type local char = require'string'.char local math_type = require'math'.type local tointeger = require'math'.tointeger local tconcat = require'table'.concat local pack = require'string'.pack local unpack = require'string'.unpack --[[ debug only local format = require'string'.format local function hexadump (s) return (s:gsub('.', function (c) return format('%02X ', c:byte()) end)) end --]] local _ENV = nil local m = {} --[[ debug only m.hexadump = hexadump --]] local function argerror (caller, narg, extramsg) error("bad argument #" .. tostring(narg) .. " to " .. caller .. " (" .. extramsg .. ")") end local function typeerror (caller, narg, arg, tname) argerror(caller, narg, tname .. " expected, got " .. type(arg)) end local function checktype (caller, narg, arg, tname) if type(arg) ~= tname then typeerror(caller, narg, arg, tname) end end local packers = setmetatable({}, { __index = function (t, k) error("pack '" .. k .. "' is unimplemented") end }) m.packers = packers packers['nil'] = function (buffer) buffer[#buffer+1] = char(0xC0) -- nil end packers['boolean'] = function (buffer, bool) if bool then buffer[#buffer+1] = char(0xC3) -- true else buffer[#buffer+1] = char(0xC2) -- false end end packers['string_compat'] = function (buffer, str) local n = #str if n <= 0x1F then buffer[#buffer+1] = char(0xA0 + n) -- fixstr elseif n <= 0xFFFF then buffer[#buffer+1] = char(0xDA) -- str16 buffer[#buffer+1] = pack('>I2', n) elseif n <= 0xFFFFFFFF.0 then buffer[#buffer+1] = char(0xDB) -- str32 buffer[#buffer+1] = pack('>I4', n) else error"overflow in pack 'string_compat'" end buffer[#buffer+1] = str end packers['_string'] = function (buffer, str) local n = #str if n <= 0x1F then buffer[#buffer+1] = char(0xA0 + n) -- fixstr elseif n <= 0xFF then buffer[#buffer+1] = char(0xD9, -- str8 n) elseif n <= 0xFFFF then buffer[#buffer+1] = char(0xDA) -- str16 buffer[#buffer+1] = pack('>I2', n) elseif n <= 0xFFFFFFFF.0 then buffer[#buffer+1] = char(0xDB) -- str32 buffer[#buffer+1] = pack('>I4', n) else error"overflow in pack 'string'" end buffer[#buffer+1] = str end packers['binary'] = function (buffer, str) local n = #str if n <= 0xFF then buffer[#buffer+1] = char(0xC4, -- bin8 n) elseif n <= 0xFFFF then buffer[#buffer+1] = char(0xC5) -- bin16 buffer[#buffer+1] = pack('>I2', n) elseif n <= 0xFFFFFFFF.0 then buffer[#buffer+1] = char(0xC6) -- bin32 buffer[#buffer+1] = pack('>I4', n) else error"overflow in pack 'binary'" end buffer[#buffer+1] = str end local set_string = function (str) if str == 'string_compat' then packers['string'] = packers['string_compat'] elseif str == 'string' then packers['string'] = packers['_string'] elseif str == 'binary' then packers['string'] = packers['binary'] else argerror('set_string', 1, "invalid option '" .. str .."'") end end m.set_string = set_string packers['map'] = function (buffer, tbl, n) if n <= 0x0F then buffer[#buffer+1] = char(0x80 + n) -- fixmap elseif n <= 0xFFFF then buffer[#buffer+1] = char(0xDE) -- map16 buffer[#buffer+1] = pack('>I2', n) elseif n <= 0xFFFFFFFF.0 then buffer[#buffer+1] = char(0xDF) -- map32 buffer[#buffer+1] = pack('>I4', n) else error"overflow in pack 'map'" end for k, v in pairs(tbl) do packers[type(k)](buffer, k) packers[type(v)](buffer, v) end end packers['array'] = function (buffer, tbl, n) if n <= 0x0F then buffer[#buffer+1] = char(0x90 + n) -- fixarray elseif n <= 0xFFFF then buffer[#buffer+1] = char(0xDC) -- array16 buffer[#buffer+1] = pack('>I2', n) elseif n <= 0xFFFFFFFF.0 then buffer[#buffer+1] = char(0xDD) -- array32 buffer[#buffer+1] = pack('>I4', n) else error"overflow in pack 'array'" end for i = 1, n do local v = tbl[i] packers[type(v)](buffer, v) end end local set_array = function (array) if array == 'without_hole' then packers['_table'] = function (buffer, tbl) local is_map, n, max = false, 0, 0 for k in pairs(tbl) do if type(k) == 'number' and k > 0 then if k > max then max = k end else is_map = true end n = n + 1 end if max ~= n then -- there are holes is_map = true end if is_map then return packers['map'](buffer, tbl, n) else return packers['array'](buffer, tbl, n) end end elseif array == 'with_hole' then packers['_table'] = function (buffer, tbl) local is_map, n, max = false, 0, 0 for k in pairs(tbl) do if type(k) == 'number' and k > 0 then if k > max then max = k end else is_map = true end n = n + 1 end if is_map then return packers['map'](buffer, tbl, n) else return packers['array'](buffer, tbl, max) end end elseif array == 'always_as_map' then packers['_table'] = function(buffer, tbl) local n = 0 for k in pairs(tbl) do n = n + 1 end return packers['map'](buffer, tbl, n) end else argerror('set_array', 1, "invalid option '" .. array .."'") end end m.set_array = set_array packers['table'] = function (buffer, tbl) return packers['_table'](buffer, tbl) end packers['unsigned'] = function (buffer, n) if n >= 0 then if n <= 0x7F then buffer[#buffer+1] = char(n) -- fixnum_pos elseif n <= 0xFF then buffer[#buffer+1] = char(0xCC, -- uint8 n) elseif n <= 0xFFFF then buffer[#buffer+1] = char(0xCD) -- uint16 buffer[#buffer+1] = pack('>I2', n) elseif n <= 0xFFFFFFFF.0 then buffer[#buffer+1] = char(0xCE) -- uint32 buffer[#buffer+1] = pack('>I4', n) else buffer[#buffer+1] = char(0xCF) -- uint64 buffer[#buffer+1] = pack('>I8', n) end else if n >= -0x20 then buffer[#buffer+1] = char(0x100 + n) -- fixnum_neg elseif n >= -0x80 then buffer[#buffer+1] = char(0xD0) -- int8 buffer[#buffer+1] = pack('>i1', n) elseif n >= -0x8000 then buffer[#buffer+1] = char(0xD1) -- int16 buffer[#buffer+1] = pack('>i2', n) elseif n >= -0x80000000 then buffer[#buffer+1] = char(0xD2) -- int32 buffer[#buffer+1] = pack('>i4', n) else buffer[#buffer+1] = char(0xD3) -- int64 buffer[#buffer+1] = pack('>i8', n) end end end packers['signed'] = function (buffer, n) if n >= 0 then if n <= 0x7F then buffer[#buffer+1] = char(n) -- fixnum_pos elseif n <= 0x7FFF then buffer[#buffer+1] = char(0xD1) -- int16 buffer[#buffer+1] = pack('>i2', n) elseif n <= 0x7FFFFFFF then buffer[#buffer+1] = char(0xD2) -- int32 buffer[#buffer+1] = pack('>i4', n) else buffer[#buffer+1] = char(0xD3) -- int64 buffer[#buffer+1] = pack('>i8', n) end else if n >= -0x20 then buffer[#buffer+1] = char(0xE0 + 0x20 + n) -- fixnum_neg elseif n >= -0x80 then buffer[#buffer+1] = char(0xD0) -- int8 buffer[#buffer+1] = pack('>i1', n) elseif n >= -0x8000 then buffer[#buffer+1] = char(0xD1) -- int16 buffer[#buffer+1] = pack('>i2', n) elseif n >= -0x80000000 then buffer[#buffer+1] = char(0xD2) -- int32 buffer[#buffer+1] = pack('>i4', n) else buffer[#buffer+1] = char(0xD3) -- int64 buffer[#buffer+1] = pack('>i8', n) end end end local set_integer = function (integer) if integer == 'unsigned' then packers['integer'] = packers['unsigned'] elseif integer == 'signed' then packers['integer'] = packers['signed'] else argerror('set_integer', 1, "invalid option '" .. integer .."'") end end m.set_integer = set_integer packers['float'] = function (buffer, n) buffer[#buffer+1] = char(0xCA) buffer[#buffer+1] = pack('>f', n) end packers['double'] = function (buffer, n) buffer[#buffer+1] = char(0xCB) buffer[#buffer+1] = pack('>d', n) end local set_number = function (number) if number == 'integer' then packers['number'] = packers['signed'] elseif number == 'float' then packers['number'] = function (buffer, n) if math_type(n) == 'float' then return packers['float'](buffer, n) else return packers['integer'](buffer, n) end end elseif number == 'double' then packers['number'] = function (buffer, n) if math_type(n) == 'float' then return packers['double'](buffer, n) else return packers['integer'](buffer, n) end end else argerror('set_number', 1, "invalid option '" .. number .."'") end end m.set_number = set_number for k = 0, 4 do local n = tointeger(2^k) local fixext = 0xD4 + k packers['fixext' .. tostring(n)] = function (buffer, tag, data) assert(#data == n, "bad length for fixext" .. tostring(n)) buffer[#buffer+1] = char(fixext) buffer[#buffer+1] = pack('>i1', tag) buffer[#buffer+1] = data end end packers['ext'] = function (buffer, tag, data) local n = #data if n <= 0xFF then buffer[#buffer+1] = char(0xC7, -- ext8 n) buffer[#buffer+1] = pack('>i1', tag) elseif n <= 0xFFFF then buffer[#buffer+1] = char(0xC8) -- ext16 buffer[#buffer+1] = pack('>I2', n) buffer[#buffer+1] = pack('>i1', tag) elseif n <= 0xFFFFFFFF.0 then buffer[#buffer+1] = char(0xC9) -- ext32 buffer[#buffer+1] = pack('>I4', n) buffer[#buffer+1] = pack('>i1', tag) else error"overflow in pack 'ext'" end buffer[#buffer+1] = data end function m.pack (data) local buffer = {} packers[type(data)](buffer, data) return tconcat(buffer) end local types_map = setmetatable({ [0xC0] = 'nil', [0xC2] = 'false', [0xC3] = 'true', [0xC4] = 'bin8', [0xC5] = 'bin16', [0xC6] = 'bin32', [0xC7] = 'ext8', [0xC8] = 'ext16', [0xC9] = 'ext32', [0xCA] = 'float', [0xCB] = 'double', [0xCC] = 'uint8', [0xCD] = 'uint16', [0xCE] = 'uint32', [0xCF] = 'uint64', [0xD0] = 'int8', [0xD1] = 'int16', [0xD2] = 'int32', [0xD3] = 'int64', [0xD4] = 'fixext1', [0xD5] = 'fixext2', [0xD6] = 'fixext4', [0xD7] = 'fixext8', [0xD8] = 'fixext16', [0xD9] = 'str8', [0xDA] = 'str16', [0xDB] = 'str32', [0xDC] = 'array16', [0xDD] = 'array32', [0xDE] = 'map16', [0xDF] = 'map32', }, { __index = function (t, k) if k < 0xC0 then if k < 0x80 then return 'fixnum_pos' elseif k < 0x90 then return 'fixmap' elseif k < 0xA0 then return 'fixarray' else return 'fixstr' end elseif k > 0xDF then return 'fixnum_neg' else return 'reserved' .. tostring(k) end end }) m.types_map = types_map local unpackers = setmetatable({}, { __index = function (t, k) error("unpack '" .. k .. "' is unimplemented") end }) m.unpackers = unpackers local function unpack_array (c, n) local t = {} local decode = unpackers['any'] for i = 1, n do t[i] = decode(c) end return t end local function unpack_map (c, n) local t = {} local decode = unpackers['any'] for i = 1, n do local k = decode(c) local val = decode(c) if k == nil then k = m.sentinel end if k ~= nil then t[k] = val end end return t end unpackers['any'] = function (c) local s, i, j = c.s, c.i, c.j if i > j then c:underflow(i) s, i, j = c.s, c.i, c.j end local val = s:sub(i, i):byte() c.i = i+1 return unpackers[types_map[val]](c, val) end unpackers['nil'] = function () return nil end unpackers['false'] = function () return false end unpackers['true'] = function () return true end unpackers['float'] = function (c) local s, i, j = c.s, c.i, c.j if i+3 > j then c:underflow(i+3) s, i, j = c.s, c.i, c.j end c.i = i+4 return unpack('>f', s, i) end unpackers['double'] = function (c) local s, i, j = c.s, c.i, c.j if i+7 > j then c:underflow(i+7) s, i, j = c.s, c.i, c.j end c.i = i+8 return unpack('>d', s, i) end unpackers['fixnum_pos'] = function (c, val) return val end unpackers['uint8'] = function (c) local s, i, j = c.s, c.i, c.j if i > j then c:underflow(i) s, i, j = c.s, c.i, c.j end c.i = i+1 return unpack('>I1', s, i) end unpackers['uint16'] = function (c) local s, i, j = c.s, c.i, c.j if i+1 > j then c:underflow(i+1) s, i, j = c.s, c.i, c.j end c.i = i+2 return unpack('>I2', s, i) end unpackers['uint32'] = function (c) local s, i, j = c.s, c.i, c.j if i+3 > j then c:underflow(i+3) s, i, j = c.s, c.i, c.j end c.i = i+4 return unpack('>I4', s, i) end unpackers['uint64'] = function (c) local s, i, j = c.s, c.i, c.j if i+7 > j then c:underflow(i+7) s, i, j = c.s, c.i, c.j end c.i = i+8 return unpack('>I8', s, i) end unpackers['fixnum_neg'] = function (c, val) return val - 0x100 end unpackers['int8'] = function (c) local s, i, j = c.s, c.i, c.j if i > j then c:underflow(i) s, i, j = c.s, c.i, c.j end c.i = i+1 return unpack('>i1', s, i) end unpackers['int16'] = function (c) local s, i, j = c.s, c.i, c.j if i+1 > j then c:underflow(i+1) s, i, j = c.s, c.i, c.j end c.i = i+2 return unpack('>i2', s, i) end unpackers['int32'] = function (c) local s, i, j = c.s, c.i, c.j if i+3 > j then c:underflow(i+3) s, i, j = c.s, c.i, c.j end c.i = i+4 return unpack('>i4', s, i) end unpackers['int64'] = function (c) local s, i, j = c.s, c.i, c.j if i+7 > j then c:underflow(i+7) s, i, j = c.s, c.i, c.j end c.i = i+8 return unpack('>i8', s, i) end unpackers['fixstr'] = function (c, val) local s, i, j = c.s, c.i, c.j local n = val & 0x1F local e = i+n-1 if e > j then c:underflow(e) s, i, j = c.s, c.i, c.j e = i+n-1 end c.i = i+n return s:sub(i, e) end unpackers['str8'] = function (c) local s, i, j = c.s, c.i, c.j if i > j then c:underflow(i) s, i, j = c.s, c.i, c.j end local n = unpack('>I1', s, i) i = i+1 c.i = i local e = i+n-1 if e > j then c:underflow(e) s, i, j = c.s, c.i, c.j e = i+n-1 end c.i = i+n return s:sub(i, e) end unpackers['str16'] = function (c) local s, i, j = c.s, c.i, c.j if i+1 > j then c:underflow(i+1) s, i, j = c.s, c.i, c.j end local n = unpack('>I2', s, i) i = i+2 c.i = i local e = i+n-1 if e > j then c:underflow(e) s, i, j = c.s, c.i, c.j e = i+n-1 end c.i = i+n return s:sub(i, e) end unpackers['str32'] = function (c) local s, i, j = c.s, c.i, c.j if i+3 > j then c:underflow(i+3) s, i, j = c.s, c.i, c.j end local n = unpack('>I4', s, i) i = i+4 c.i = i local e = i+n-1 if e > j then c:underflow(e) s, i, j = c.s, c.i, c.j e = i+n-1 end c.i = i+n return s:sub(i, e) end unpackers['bin8'] = unpackers['str8'] unpackers['bin16'] = unpackers['str16'] unpackers['bin32'] = unpackers['str32'] unpackers['fixarray'] = function (c, val) return unpack_array(c, val & 0xF) end unpackers['array16'] = function (c) local s, i, j = c.s, c.i, c.j if i+1 > j then c:underflow(i+1) s, i, j = c.s, c.i, c.j end local n = unpack('>I2', s, i) c.i = i+2 return unpack_array(c, n) end unpackers['array32'] = function (c) local s, i, j = c.s, c.i, c.j if i+3 > j then c:underflow(i+3) s, i, j = c.s, c.i, c.j end local n = unpack('>I4', s, i) c.i = i+4 return unpack_array(c, n) end unpackers['fixmap'] = function (c, val) return unpack_map(c, val & 0xF) end unpackers['map16'] = function (c) local s, i, j = c.s, c.i, c.j if i+1 > j then c:underflow(i+1) s, i, j = c.s, c.i, c.j end local n = unpack('>I2', s, i) c.i = i+2 return unpack_map(c, n) end unpackers['map32'] = function (c) local s, i, j = c.s, c.i, c.j if i+3 > j then c:underflow(i+3) s, i, j = c.s, c.i, c.j end local n = unpack('>I4', s, i) c.i = i+4 return unpack_map(c, n) end function m.build_ext (tag, data) return nil end for k = 0, 4 do local n = tointeger(2^k) unpackers['fixext' .. tostring(n)] = function (c) local s, i, j = c.s, c.i, c.j if i > j then c:underflow(i) s, i, j = c.s, c.i, c.j end local tag = unpack('>i1', s, i) i = i+1 c.i = i local e = i+n-1 if e > j then c:underflow(e) s, i, j = c.s, c.i, c.j e = i+n-1 end c.i = i+n return m.build_ext(tag, s:sub(i, e)) end end unpackers['ext8'] = function (c) local s, i, j = c.s, c.i, c.j if i > j then c:underflow(i) s, i, j = c.s, c.i, c.j end local n = unpack('>I1', s, i) i = i+1 c.i = i if i > j then c:underflow(i) s, i, j = c.s, c.i, c.j end local tag = unpack('>i1', s, i) i = i+1 c.i = i local e = i+n-1 if e > j then c:underflow(e) s, i, j = c.s, c.i, c.j e = i+n-1 end c.i = i+n return m.build_ext(tag, s:sub(i, e)) end unpackers['ext16'] = function (c) local s, i, j = c.s, c.i, c.j if i+1 > j then c:underflow(i+1) s, i, j = c.s, c.i, c.j end local n = unpack('>I2', s, i) i = i+2 c.i = i if i > j then c:underflow(i) s, i, j = c.s, c.i, c.j end local tag = unpack('>i1', s, i) i = i+1 c.i = i local e = i+n-1 if e > j then c:underflow(e) s, i, j = c.s, c.i, c.j e = i+n-1 end c.i = i+n return m.build_ext(tag, s:sub(i, e)) end unpackers['ext32'] = function (c) local s, i, j = c.s, c.i, c.j if i+3 > j then c:underflow(i+3) s, i, j = c.s, c.i, c.j end local n = unpack('>I4', s, i) i = i+4 c.i = i if i > j then c:underflow(i) s, i, j = c.s, c.i, c.j end local tag = unpack('>i1', s, i) i = i+1 c.i = i local e = i+n-1 if e > j then c:underflow(e) s, i, j = c.s, c.i, c.j e = i+n-1 end c.i = i+n return m.build_ext(tag, s:sub(i, e)) end local function cursor_string (str) return { s = str, i = 1, j = #str, underflow = function (self) error "missing bytes" end, } end local function cursor_loader (ld) return { s = '', i = 1, j = 0, underflow = function (self, e) self.s = self.s:sub(self.i) e = e - self.i + 1 self.i = 1 self.j = 0 while e > self.j do local chunk = ld() if not chunk then error "missing bytes" end self.s = self.s .. chunk self.j = #self.s end end, } end function m.unpack (s) checktype('unpack', 1, s, 'string') local cursor = cursor_string(s) local data = unpackers['any'](cursor) if cursor.i < cursor.j then error "extra bytes" end return data end function m.unpacker (src) if type(src) == 'string' then local cursor = cursor_string(src) return function () if cursor.i <= cursor.j then return cursor.i, unpackers['any'](cursor) end end elseif type(src) == 'function' then local cursor = cursor_loader(src) return function () if cursor.i > cursor.j then pcall(cursor.underflow, cursor, cursor.i) end if cursor.i <= cursor.j then return true, unpackers['any'](cursor) end end else argerror('unpacker', 1, "string or function expected, got " .. type(src)) end end set_string'string_compat' set_integer'unsigned' if math_type(0.0) == math_type(0) then set_number'integer' elseif #pack('n', 0.0) == 4 then m.small_lua = true set_number'float' else m.full64bits = true set_number'double' end set_array'without_hole' m._VERSION = '0.3.3' m._DESCRIPTION = "lua-MessagePack : a pure Lua implementation" m._COPYRIGHT = "Copyright (c) 2012-2015 Francois Perrad" return m -- -- This library is licensed under the terms of the MIT/X11 license, -- like Lua itself. -- lua-MessagePack-0.3.3/test/000077500000000000000000000000001253234330000154315ustar00rootroot00000000000000lua-MessagePack-0.3.3/test/00-require.t000077500000000000000000000011041253234330000175060ustar00rootroot00000000000000#! /usr/bin/lua require 'Test.More' plan(9) if not require_ok 'MessagePack' then BAIL_OUT "no lib" end local m = require 'MessagePack' type_ok( m, 'table' ) like( m._COPYRIGHT, 'Perrad', "_COPYRIGHT" ) like( m._DESCRIPTION, 'MessagePack', "_DESCRIPTION" ) like( m._VERSION, '^%d%.%d%.%d$', "_VERSION" ) type_ok( m.packers, 'table', "table packers" ) type_ok( m.unpackers, 'table', "table unpackers" ) type_ok( m.types_map, 'table', "table types_map" ) type_ok( m.build_ext, 'function', "function build_ext" ) if m.full64bits then diag "full 64bits with Lua 5.3" end lua-MessagePack-0.3.3/test/01-spectest.t000077500000000000000000000231621253234330000176750ustar00rootroot00000000000000#! /usr/bin/lua local unpack = table.unpack or unpack require 'Test.More' local mp = require 'MessagePack' local data = { false, "false", true, "true", nil, "nil", 0, "0 Positive FixNum", 0, "0 uint8", 0, "0 uint16", 0, "0 uint32", 0, "0 uint64", 0, "0 int8", 0, "0 int16", 0, "0 int32", 0, "0 int64", -1, "-1 Negative FixNum", -1, "-1 int8", -1, "-1 int16", -1, "-1 int32", -1, "-1 int64", 127, "127 Positive FixNum", 127, "127 uint8", 255, "255 uint16", 65535, "65535 uint32", 4294967295, "4294967295 uint64", -32, "-32 Negative FixNum", -32, "-32 int8", -128, "-128 int16", -32768, "-32768 int32", -2147483648, "-2147483648 int64", 0.0, "0.0 float", 0.0, "0.0 double", -0.0, "-0.0 float", -0.0, "-0.0 double", 1.0, "1.0 double", -1.0, "-1.0 double", "a", "\"a\" FixStr", "a", "\"a\" str 8", "a", "\"a\" str 16", "a", "\"a\" str 32", "", "\"\" FixStr", "", "\"\" str 8", "", "\"\" str 16", "", "\"\" str 32", "a", "\"a\" bin 8", "a", "\"a\" bin 16", "a", "\"a\" bin 32", "", "\"\" bin 8", "", "\"\" bin 16", "", "\"\" bin 32", { 0 }, "[0] FixArray", { 0 }, "[0] array 16", { 0 }, "[0] array 32", {}, "[] FixArray", {}, "[] array 16", {}, "[] array 32", {}, "{} FixMap", {}, "{} map 16", {}, "{} map 32", { a=97 }, "{\"a\"=>97} FixMap", { a=97}, "{\"a\"=>97} map 16", { a=97 }, "{\"a\"=>97} map 32", { {} }, "[[]]", { {"a"} }, "[[\"a\"]]", nil, "fixext 1", nil, "fixext 2", nil, "fixext 4", nil, "fixext 8", nil, "fixext 16", nil, "ext 8", nil, "ext 16", nil, "ext 32", } plan(10 * 69) -- see http://github.com/msgpack/msgpack/blob/master/test/cases_gen.rb local source = [===[ c2 # false c3 # true c0 # nil 00 # 0 Positive FixNum cc 00 # 0 uint8 cd 00 00 # 0 uint16 ce 00 00 00 00 # 0 uint32 cf 00 00 00 00 00 00 00 00 # 0 uint64 d0 00 # 0 int8 d1 00 00 # 0 int16 d2 00 00 00 00 # 0 int32 d3 00 00 00 00 00 00 00 00 # 0 int64 ff # -1 Negative FixNum d0 ff # -1 int8 d1 ff ff # -1 int16 d2 ff ff ff ff # -1 int32 d3 ff ff ff ff ff ff ff ff # -1 int64 7f # 127 Positive FixNum cc 7f # 127 uint8 cd 00 ff # 255 uint16 ce 00 00 ff ff # 65535 uint32 cf 00 00 00 00 ff ff ff ff # 4294967295 uint64 e0 # -32 Negative FixNum d0 e0 # -32 int8 d1 ff 80 # -128 int16 d2 ff ff 80 00 # -32768 int32 d3 ff ff ff ff 80 00 00 00 # -2147483648 int64 ca 00 00 00 00 # 0.0 float cb 00 00 00 00 00 00 00 00 # 0.0 double ca 80 00 00 00 # -0.0 float cb 80 00 00 00 00 00 00 00 # -0.0 double cb 3f f0 00 00 00 00 00 00 # 1.0 double cb bf f0 00 00 00 00 00 00 # -1.0 double a1 61 # "a" FixStr d9 01 61 # "a" str 8 da 00 01 61 # "a" str 16 db 00 00 00 01 61 # "a" str 32 a0 # "" FixStr d9 00 # "" str 8 da 00 00 # "" str 16 db 00 00 00 00 # "" str 32 c4 01 61 # "a" bin 8 c5 00 01 61 # "a" bin 16 c6 00 00 00 01 61 # "a" bin 32 c4 00 # "" bin 8 c5 00 00 # "" bin 16 c6 00 00 00 00 # "" bin 32 91 00 # [0] FixArray dc 00 01 00 # [0] array 16 dd 00 00 00 01 00 # [0] array 32 90 # [] FixArray dc 00 00 # [] array 16 dd 00 00 00 00 # [] array 32 80 # {} FixMap de 00 00 # {} map 16 df 00 00 00 00 # {} map 32 81 a1 61 61 # {"a"=>97} FixMap de 00 01 a1 61 61 # {"a"=>97} map 16 df 00 00 00 01 a1 61 61 # {"a"=>97} map 32 91 90 # [[]] 91 91 a1 61 # [["a"]] d4 01 01 # fixext 1 d5 02 02 01 # fixext 2 d6 04 04 03 02 01 # fixext 4 d7 08 08 07 06 05 04 03 02 01 # fixext 8 d8 16 10 0f 0e 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 # fixext 16 c7 01 08 61 # ext 8 c8 00 01 16 61 # ext 16 c9 00 00 00 01 32 61 # ext 32 ]===] source = source:gsub('#[^\n]+', '') local t = {} for v in source:gmatch'%x%x' do t[#t+1] = tonumber(v, 16) end local mpac = string.char(unpack(t)) local i = 1 for _, val in mp.unpacker(mpac) do if type(val) == 'table' then is_deeply(val, data[i], "reference " .. data[i+1]) is_deeply(mp.unpack(mp.pack(data[i])), data[i], "unpack/pack " .. data[i+1]) else is(val, data[i], "reference " .. data[i+1]) is(mp.unpack(mp.pack(data[i])), data[i], "unpack/pack " .. data[i+1]) end i = i + 2 end local f = io.open('cases.mpac', 'w') f:write(mpac) f:close() local r, ltn12 = pcall(require, 'ltn12') -- from LuaSocket if not r then diag "ltn12.source.file emulated" ltn12 = { source = {} } function ltn12.source.file (handle) if handle then return function () local chunk = handle:read(1) if not chunk then handle:close() end return chunk end else return function () return nil, "unable to open file" end end end end i = 1 f = io.open('cases.mpac', 'r') local s = ltn12.source.file(f) for _, val in mp.unpacker(s) do if type(val) == 'table' then is_deeply(val, data[i], "reference " .. data[i+1]) else is(val, data[i], "reference " .. data[i+1]) end i = i + 2 end os.remove 'cases.mpac' -- clean up diag("set_string'string'") mp.set_string'string' i = 1 for _, val in mp.unpacker(mpac) do if type(val) == 'table' then is_deeply(mp.unpack(mp.pack(data[i])), data[i], "unpack/pack " .. data[i+1]) else is(mp.unpack(mp.pack(data[i])), data[i], "unpack/pack " .. data[i+1]) end i = i + 2 end diag("set_string'binary'") mp.set_string'binary' i = 1 for _, val in mp.unpacker(mpac) do if type(val) == 'table' then is_deeply(mp.unpack(mp.pack(data[i])), data[i], "unpack/pack " .. data[i+1]) else is(mp.unpack(mp.pack(data[i])), data[i], "unpack/pack " .. data[i+1]) end i = i + 2 end mp.set_string'string_compat' diag("set_integer'unsigned'") mp.set_integer'unsigned' i = 1 for _, val in mp.unpacker(mpac) do if type(val) == 'table' then is_deeply(mp.unpack(mp.pack(data[i])), data[i], "unpack/pack " .. data[i+1]) else is(mp.unpack(mp.pack(data[i])), data[i], "unpack/pack " .. data[i+1]) end i = i + 2 end mp.set_integer'signed' diag("set_number'float'") mp.set_number'float' i = 1 for _, val in mp.unpacker(mpac) do if type(val) == 'table' then is_deeply(mp.unpack(mp.pack(data[i])), data[i], "unpack/pack " .. data[i+1]) else is(mp.unpack(mp.pack(data[i])), data[i], "unpack/pack " .. data[i+1]) end i = i + 2 end diag("set_number'integer'") mp.set_number'integer' i = 1 for _, val in mp.unpacker(mpac) do if type(val) == 'table' then is_deeply(mp.unpack(mp.pack(data[i])), data[i], "unpack/pack " .. data[i+1]) else is(mp.unpack(mp.pack(data[i])), data[i], "unpack/pack " .. data[i+1]) end i = i + 2 end mp.set_number'double' diag("set_array'with_hole'") mp.set_array'with_hole' i = 1 for _, val in mp.unpacker(mpac) do if type(val) == 'table' then is_deeply(mp.unpack(mp.pack(data[i])), data[i], "unpack/pack " .. data[i+1]) else is(mp.unpack(mp.pack(data[i])), data[i], "unpack/pack " .. data[i+1]) end i = i + 2 end diag("set_array'always_as_map'") mp.set_array'always_as_map' i = 1 for _, val in mp.unpacker(mpac) do if type(val) == 'table' then is_deeply(mp.unpack(mp.pack(data[i])), data[i], "unpack/pack " .. data[i+1]) else is(mp.unpack(mp.pack(data[i])), data[i], "unpack/pack " .. data[i+1]) end i = i + 2 end mp.set_array'without_hole' lua-MessagePack-0.3.3/test/02-except.t000077500000000000000000000057111253234330000173340ustar00rootroot00000000000000#! /usr/bin/lua require 'Test.More' plan(22) local mp = require 'MessagePack' error_like( function () mp.pack( print ) end, "pack 'function' is unimplemented" ) error_like( function () mp.pack( coroutine.create(plan) ) end, "pack 'thread' is unimplemented" ) error_like( function () mp.pack( io.stdin ) end, "pack 'userdata' is unimplemented" ) error_like( function () local a = {} a.foo = a mp.pack( a ) end, "stack overflow", -- from Lua interpreter "direct cycle" ) error_like( function () local a = {} local b = {} a.foo = b b.foo = a mp.pack( a ) end, "stack overflow", -- from Lua interpreter "indirect cycle" ) error_like( function () mp.unpack(string.char(193)) -- 0xC1 end, "unpack 'reserved193' is unimplemented" ) is( mp.unpack(mp.pack("text")), "text" ) error_like( function () mp.unpack(mp.pack("text"):sub(1, -2)) end, "missing bytes" ) error_like( function () mp.unpack(mp.pack("text") .. "more") end, "extra bytes" ) error_like( function () mp.unpack( {} ) end, "bad argument #1 to unpack %(string expected, got table%)" ) error_like( function () mp.unpacker( false ) end, "bad argument #1 to unpacker %(string or function expected, got boolean%)" ) error_like( function () mp.unpacker( {} ) end, "bad argument #1 to unpacker %(string or function expected, got table%)" ) for _, val in mp.unpacker(string.rep(mp.pack("text"), 2)) do is( val, "text" ) end error_like( function () for _, val in mp.unpacker(string.rep(mp.pack("text"), 2):sub(1, -2)) do is( val, "text" ) end end, "missing bytes" ) error_like( function () mp.set_string'bad' end, "bad argument #1 to set_string %(invalid option 'bad'%)" ) error_like( function () mp.set_number'bad' end, "bad argument #1 to set_number %(invalid option 'bad'%)" ) error_like( function () mp.set_integer'bad' end, "bad argument #1 to set_integer %(invalid option 'bad'%)" ) error_like( function () mp.set_array'bad' end, "bad argument #1 to set_array %(invalid option 'bad'%)" ) error_like( function () mp.packers['fixext4'](nil, 1, '123') end, "bad length for fixext4" ) lives_ok( function () mp.packers['fixext4']({}, 1, '1234') end, "fixext4" ) lua-MessagePack-0.3.3/test/03-edge.t000077500000000000000000000046031253234330000167500ustar00rootroot00000000000000#! /usr/bin/lua require 'Test.More' plan(35) local mp = require 'MessagePack' is( mp.unpack(mp.pack(1/0)), 1/0, "inf" ) is( mp.unpack(mp.pack(-1/0)), -1/0, "-inf" ) local nan = mp.unpack(mp.pack(0/0)) type_ok( nan, 'number', "nan" ) ok( nan ~= nan ) is( mp.pack{}:byte(), 0x90, "empty table as array" ) local t = setmetatable( { 'a', 'b', 'c' }, { __index = { [4] = 'd' } } ) is( t[4], 'd' ) t = mp.unpack(mp.pack(t)) is( t[2], 'b' ) is( t[4], nil, "don't follow metatable" ) t = setmetatable( { a = 1, b = 2, c = 3 }, { __index = { d = 4 } } ) is( t.d, 4 ) t = mp.unpack(mp.pack(t)) is( t.b, 2 ) is( t.d, nil, "don't follow metatable" ) t = { 10, 20, nil, 40 } mp.set_array'without_hole' is( mp.pack(t):byte(), 0x80 + 3, "array with hole as map" ) is_deeply( mp.unpack(mp.pack(t)), t ) mp.set_array'with_hole' is( mp.pack(t):byte(), 0x90 + 4, "array with hole as array" ) is_deeply( mp.unpack(mp.pack(t)), t ) mp.set_array'always_as_map' is( mp.pack(t):byte(), 0x80 + 3, "always_as_map" ) is_deeply( mp.unpack(mp.pack(t)), t ) t = {} mp.set_array'without_hole' is( mp.pack(t):byte(), 0x90, "empty table as array" ) mp.set_array'with_hole' is( mp.pack(t):byte(), 0x90, "empty table as array" ) mp.set_array'always_as_map' is( mp.pack(t):byte(), 0x80, "empty table as map" ) mp.set_number'float' is( mp.pack(3.402824e+38), mp.pack(1/0), "float 3.402824e+38") is( mp.pack(7e42), mp.pack(1/0), "inf (downcast double -> float)") is( mp.pack(-7e42), mp.pack(-1/0), "-inf (downcast double -> float)") is( mp.unpack(mp.pack(7e42)), 1/0, "inf (downcast double -> float)") is( mp.unpack(mp.pack(-7e42)), -1/0, "-inf (downcast double -> float)") is( mp.unpack(mp.pack(7e-46)), 0, "epsilon (downcast double -> float)") is( mp.unpack(mp.pack(-7e-46)), -0, "-epsilon (downcast double -> float)") mp.set_integer'unsigned' is( mp.unpack(mp.pack(0xF0)), 0xF0, "packint 0xF0") is( mp.unpack(mp.pack(0xF000)), 0xF000, "packint 0xF000") is( mp.unpack(mp.pack(0xF0000000)), 0xF0000000, "packint 0xF0000000") local buffer = {} mp.packers.float(buffer, 0) is( mp.unpack(table.concat(buffer)), 0) buffer = {} mp.packers.double(buffer, 0) is( mp.unpack(table.concat(buffer)), 0) local mpac = string.char(0x82, 0xC0, 0x01, 0xA2, 0x69, 0x64, 0x02) t = mp.unpack(mpac) is( t.id, 2, "unpack map with nil as table index" ) mp.sentinel = {} t = mp.unpack(mpac) is( t[mp.sentinel], 1, "unpack using a sentinel for nil as table index" ) is( t.id, 2 ) lua-MessagePack-0.3.3/test/04-cover.t000077500000000000000000000057231253234330000171670ustar00rootroot00000000000000#! /usr/bin/lua require 'Test.More' plan(40) local mp = require 'MessagePack' mp.set_number'float' local nan = mp.unpack(mp.pack(0/0)) type_ok( nan, 'number', "nan" ) ok( nan ~= nan ) is( mp.unpack(mp.pack(3.140625)), 3.140625, "3.140625" ) mp.set_number'double' is( mp.unpack(mp.pack(math.pi)), math.pi, "pi" ) mp.set_integer'signed' is( mp.unpack(mp.pack(2^5)), 2^5, "2^5" ) is( mp.unpack(mp.pack(-2^5)), -2^5, "-2^5" ) is( mp.unpack(mp.pack(2^11)), 2^11, "2^11" ) is( mp.unpack(mp.pack(-2^11)), -2^11, "-2^11" ) is( mp.unpack(mp.pack(2^21)), 2^21, "2^21" ) is( mp.unpack(mp.pack(-2^21)), -2^21, "-2^21" ) if mp.small_lua then skip("Small Lua (32 bits)", 2) else is( mp.unpack(mp.pack(2^51)), 2^51, "2^51" ) is( mp.unpack(mp.pack(-2^51)), -2^51, "-2^51" ) end if mp.full64bits then is( mp.unpack(mp.pack(2^61)), 2^61, "2^61" ) is( mp.unpack(mp.pack(-2^61)), -2^61, "-2^61" ) else skip("only 53 bits", 2) end mp.set_integer'unsigned' is( mp.unpack(mp.pack(2^5)), 2^5, "2^5" ) is( mp.unpack(mp.pack(-2^5)), -2^5, "-2^5" ) is( mp.unpack(mp.pack(2^11)), 2^11, "2^11" ) is( mp.unpack(mp.pack(-2^11)), -2^11, "-2^11" ) is( mp.unpack(mp.pack(2^21)), 2^21, "2^21" ) is( mp.unpack(mp.pack(-2^21)), -2^21, "-2^21" ) if mp.small_lua then skip("Small Lua (32 bits)", 2) else is( mp.unpack(mp.pack(2^51)), 2^51, "2^51" ) is( mp.unpack(mp.pack(-2^51)), -2^51, "-2^51" ) end if mp.full64bits then is( mp.unpack(mp.pack(2^61)), 2^61, "2^61" ) is( mp.unpack(mp.pack(-2^61)), -2^61, "-2^61" ) else skip("only 53 bits", 2) end mp.set_string'string' local s = string.rep('x', 2^3) is( mp.unpack(mp.pack(s)), s, "#s 2^3" ) -- fixstr s = string.rep('x', 2^7) is( mp.unpack(mp.pack(s)), s, "#s 2^7" ) -- str 8 s = string.rep('x', 2^11) is( mp.unpack(mp.pack(s)), s, "#s 2^11" ) -- str 16 s = string.rep('x', 2^19) is( mp.unpack(mp.pack(s)), s, "#s 2^19" ) -- str 32 mp.set_string'string_compat' s = string.rep('x', 2^3) is( mp.unpack(mp.pack(s)), s, "#s 2^3" ) -- fixstr s = string.rep('x', 2^11) is( mp.unpack(mp.pack(s)), s, "#s 2^11" ) -- str 16 s = string.rep('x', 2^19) is( mp.unpack(mp.pack(s)), s, "#s 2^19" ) -- str 32 mp.set_string'binary' s = string.rep('x', 2^5) is( mp.unpack(mp.pack(s)), s, "#s 2^5" ) -- bin 8 s = string.rep('x', 2^11) is( mp.unpack(mp.pack(s)), s, "#s 2^11" ) -- bin 16 s = string.rep('x', 2^19) is( mp.unpack(mp.pack(s)), s, "#s 2^19" ) -- bin 32 local t = { string.rep('x', 2^3):byte(1, -1) } is_deeply( mp.unpack(mp.pack(t)), t, "#t 2^3" ) t = { string.rep('x', 2^9):byte(1, -1) } is_deeply( mp.unpack(mp.pack(t)), t, "#t 2^9" ) while #t < 2^17 do t[#t+1] = 'x' end is_deeply( mp.unpack(mp.pack(t)), t, "#t 2^17" ) local h = {} for i = 1, 2^3 do h[10*i] = 'x' end is_deeply( mp.unpack(mp.pack(h)), h, "#h 2^3" ) h = {} for i = 1, 2^9 do h[10*i] = 'x' end is_deeply( mp.unpack(mp.pack(h)), h, "#h 2^9" ) for i = 1, 2^17 do h[10*i] = 'x' end is_deeply( mp.unpack(mp.pack(h)), h, "#h 2^17" ) lua-MessagePack-0.3.3/test/11-userdata-bc.t000077500000000000000000000013561253234330000202370ustar00rootroot00000000000000#! /usr/bin/lua require 'Test.More' if not pcall(require, 'bc') then skip_all 'no bc' end plan(3) local mp = require 'MessagePack' local bc = require 'bc' local EXT_BC = 42 bc.digits(65) mp.packers['userdata'] = function (buffer, u) if getmetatable(u) == bc then mp.packers['ext'](buffer, EXT_BC, tostring(u)) else error("pack 'userdata' is unimplemented") end end mp.build_ext = function (tag, data) if tag == EXT_BC then return bc.number(data) end end local orig = bc.sqrt(2) local dest = mp.unpack(mp.pack(orig)) is( dest, orig, "bc" ) nok( rawequal(orig, dest) ) error_like( function () mp.pack( io.stdin ) end, "pack 'userdata' is unimplemented" ) lua-MessagePack-0.3.3/test/12-metatable.t000077500000000000000000000016671253234330000200110ustar00rootroot00000000000000#! /usr/bin/lua require 'Test.More' plan(6) local mp = require 'MessagePack' local EXT_METATABLE = 42 mp.packers['table'] = function (buffer, t) local mt = getmetatable(t) if mt then local buf = {} mp.packers['_table'](buf, t) mp.packers['table'](buf, mt) mp.packers['ext'](buffer, EXT_METATABLE, table.concat(buf)) else mp.packers['_table'](buffer, t) end end mp.build_ext = function (tag, data) if tag == EXT_METATABLE then local f = mp.unpacker(data) local _, t = f() local _, mt = f() return setmetatable(t, mt) end end local t = setmetatable( { 'a', 'b', 'c' }, { __index = { [4] = 'd' } } ) is( t[4], 'd' ) t = mp.unpack(mp.pack(t)) is( t[2], 'b' ) is( t[4], 'd', "follow metatable" ) t = setmetatable( { a = 1, b = 2, c = 3 }, { __index = { d = 4 } } ) is( t.d, 4 ) t = mp.unpack(mp.pack(t)) is( t.b, 2 ) is( t.d, 4, "follow metatable" ) lua-MessagePack-0.3.3/test/13-coat.t000077500000000000000000000030031253234330000167640ustar00rootroot00000000000000#! /usr/bin/lua require 'Test.More' if not pcall(require, 'Coat') then skip_all 'no Coat' end plan(8) local Meta = require 'Coat.Meta.Class' local mp = require 'MessagePack' local EXT_COAT = 4 mp.packers['table'] = function (buffer, obj) local classname = obj._CLASS if classname then local buf = {} mp.packers['string'](buf, classname) mp.packers['table'](buf, obj._VALUES) mp.packers['ext'](buffer, EXT_COAT, table.concat(buf)) else mp.packers['_table'](buffer, obj) end end mp.build_ext = function (tag, data) if tag == EXT_COAT then local f = mp.unpacker(data) local _, classname = f() local _, values = f() local class = assert(Meta.class(classname)) return class.new(values) end end class 'Point' has.x = { is = 'ro', isa = 'number', default = 0 } has.y = { is = 'ro', isa = 'number', default = 0 } has.desc = { is = 'rw', isa = 'string' } function overload:__tostring () return '(' .. tostring(self.x) .. ', ' .. tostring(self.y) .. ')' end function method:draw () return "drawing " .. self._CLASS .. tostring(self) end local a = Point{x = 1, y = 2} ok( a:isa 'Point' ) is( a:draw(), "drawing Point(1, 2)" ) local b = mp.unpack(mp.pack(a)) ok( b:isa 'Point' ) is( b:draw(), "drawing Point(1, 2)" ) a.desc = string.rep('x', 2^9) local c = mp.unpack(mp.pack(a)) ok( c:isa 'Point' ) is( #c.desc, 2^9 ) a.desc = string.rep('x', 2^17) local d = mp.unpack(mp.pack(a)) ok( d:isa 'Point' ) is( #d.desc, 2^17 ) lua-MessagePack-0.3.3/test/14-function.t000077500000000000000000000010741253234330000176720ustar00rootroot00000000000000#! /usr/bin/lua require 'Test.More' plan(4) local loadstring = loadstring or load local mp = require 'MessagePack' local EXT_FUNCTION = 7 mp.packers['function'] = function (buffer, fct) mp.packers['ext'](buffer, EXT_FUNCTION, assert(string.dump(fct))) end mp.build_ext = function (tag, data) if tag == EXT_FUNCTION then return assert(loadstring(data)) end end local function square (n) return n * n end is( square(2), 4 ) local result = mp.unpack(mp.pack(square)) type_ok( result, 'function' ) nok( rawequal(square, result) ) is( result(3), 9 ) lua-MessagePack-0.3.3/test/15-ffi-cdata.t000077500000000000000000000050501253234330000176620ustar00rootroot00000000000000#! /usr/bin/lua require 'Test.More' if not pcall(require, 'ffi') then skip_all 'no ffi' end plan(20) local mp = require 'MessagePack' local ffi = require 'ffi' local EXT_UINT = 0x40 local uint8_t = ffi.typeof'uint8_t' local uint16_t = ffi.typeof'uint16_t' local uint32_t = ffi.typeof'uint32_t' local uint64_t = ffi.typeof'uint64_t' local uint8_a1 = ffi.typeof'uint8_t[1]' local uint16_a1 = ffi.typeof'uint16_t[1]' local uint32_a1 = ffi.typeof'uint32_t[1]' local uint64_a1 = ffi.typeof'uint64_t[1]' local uint8_p = ffi.typeof'uint8_t *' local uint16_p = ffi.typeof'uint16_t *' local uint32_p = ffi.typeof'uint32_t *' local uint64_p = ffi.typeof'uint64_t *' mp.packers['cdata'] = function (buffer, cdata) if ffi.istype(uint8_t, cdata) then mp.packers['fixext1'](buffer, EXT_UINT, ffi.string(uint8_a1(cdata), 1)) elseif ffi.istype(uint16_t, cdata) then mp.packers['fixext2'](buffer, EXT_UINT+1, ffi.string(uint16_a1(cdata), 2)) elseif ffi.istype(uint32_t, cdata) then mp.packers['fixext4'](buffer, EXT_UINT+2, ffi.string(uint32_a1(cdata), 4)) elseif ffi.istype(uint64_t, cdata) then mp.packers['fixext8'](buffer, EXT_UINT+3, ffi.string(uint64_a1(cdata), 8)) else error("pack 'cdata' is unimplemented") end end mp.build_ext = function (tag, data) if tag == EXT_UINT then return uint8_t(ffi.cast(uint8_p, data)[0]) elseif tag == EXT_UINT+1 then return uint16_t(ffi.cast(uint16_p, data)[0]) elseif tag == EXT_UINT+2 then return uint32_t(ffi.cast(uint32_p, data)[0]) elseif tag == EXT_UINT+3 then return uint64_t(ffi.cast(uint64_p, data)[0]) end end local a = ffi.new('uint8_t', 100) ok( ffi.istype(uint8_t, a) ) -- diag(mp.hexadump(mp.pack(a))) local b = mp.unpack(mp.pack(a)) type_ok( b, 'cdata' ) is( tonumber(b), 100 ) nok( rawequal(a, b) ) ok( ffi.istype(uint8_t, b) ) a = ffi.new('uint16_t', 10000) ok( ffi.istype(uint16_t, a) ) -- diag(mp.hexadump(mp.pack(a))) b = mp.unpack(mp.pack(a)) type_ok( b, 'cdata' ) is( tonumber(b), 10000 ) nok( rawequal(a, b) ) ok( ffi.istype(uint16_t, b) ) a = ffi.new('uint32_t', 100000000) ok( ffi.istype(uint32_t, a) ) -- diag(mp.hexadump(mp.pack(a))) b = mp.unpack(mp.pack(a)) type_ok( b, 'cdata' ) is( tonumber(b), 100000000 ) nok( rawequal(a, b) ) ok( ffi.istype(uint32_t, b) ) a = ffi.new('uint64_t', 1000000000000) ok( ffi.istype(uint64_t, a) ) -- diag(mp.hexadump(mp.pack(a))) b = mp.unpack(mp.pack(a)) type_ok( b, 'cdata' ) is( tonumber(b), 1000000000000 ) nok( rawequal(a, b) ) ok( ffi.istype(uint64_t, b) ) lua-MessagePack-0.3.3/test/issue6.t000077500000000000000000000017351253234330000170450ustar00rootroot00000000000000#! /usr/bin/lua require 'Test.More' local mp = require 'MessagePack' local data = { '1', '12', '123', '1234', '12345', '123456', '1234567', '12345678', '123456789', '12345678', '1234567', '123456', '12345', '1234', '123', '12', '1', } plan(#data) local f = io.open('data.mpac', 'w') for i = 1, #data do local mpac = mp.pack(data[i]) f:write(mpac) end f:close() local ltn12 = { source = {} } function ltn12.source.file (handle) if handle then return function () local chunk = handle:read(16) if not chunk then handle:close() end return chunk end else return function () return nil, "unable to open file" end end end f = io.open('data.mpac', 'r') local s = ltn12.source.file(f) local i = 1 for _, val in mp.unpacker(s) do is(val, data[i]) i = i + 1 end os.remove 'data.mpac' -- clean up