Permalink
Cannot retrieve contributors at this time
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
ufo/lib/msgpack.lua
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
executable file
198 lines (183 sloc)
4.31 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| local ffi = require( "ffi" ) | |
| ffi.cdef [[ | |
| typedef union msgpack_lua_union_helper { | |
| float f[2]; | |
| double d; | |
| uint64_t u64; | |
| int64_t s64; | |
| uint8_t u8[8]; | |
| uint16_t u16[4]; | |
| uint32_t u132[4]; | |
| } msgpack_lua_union_helper; | |
| ]] | |
| -- The next variable, union, would serve as a "register" to a lot of functions below | |
| local union = ffi.new( "msgpack_lua_union_helper[1]" ) | |
| -- Based on msgpack_pack_real_int64. Can write up to 9 bytes | |
| local function pack_integer( buf, pos ) | |
| local d = union.s64 | |
| if d < -32 then | |
| if d < -32768 then | |
| if d < -2147483648 then | |
| buf[pos+0] = 0xD3 | |
| buf[pos+1] = union.u8[0] | |
| buf[pos+2] = union.u8[1] | |
| buf[pos+3] = union.u8[2] | |
| buf[pos+4] = union.u8[3] | |
| buf[pos+5] = union.u8[4] | |
| buf[pos+6] = union.u8[5] | |
| buf[pos+7] = union.u8[6] | |
| buf[pos+8] = union.u8[7] | |
| return 9 | |
| else | |
| buf[pos+0] = 0xD2 | |
| buf[pos+1] = union.u8[0] | |
| buf[pos+1] = union.u8[1] | |
| buf[pos+2] = union.u8[2] | |
| buf[pos+3] = union.u8[3] | |
| return 5 | |
| end | |
| else | |
| if d < -128 then | |
| buf[pos+0] = 0xD1 | |
| buf[pos+1] = union.u8[0] | |
| buf[pos+2] = union.u8[1] | |
| return 3 | |
| else | |
| buf[pos+0] = 0xD0 | |
| buf[pos+1] = union.u8[0] | |
| return 2 | |
| end | |
| end | |
| elseif d < 128 then | |
| buf[pos] = union.u8[0] | |
| return 1 | |
| else | |
| if d < 65536 then | |
| if d < 256 then | |
| buf[pos+0] = 0xCC | |
| buf[pos+1] = union.u8[0] | |
| return 2 | |
| else | |
| buf[pos+0] = 0xCD | |
| buf[pos+1] = union.u8[0] | |
| buf[pos+2] = union.u8[1] | |
| return 3 | |
| end | |
| else | |
| if d < 4294967296 then | |
| buf[pos+0] = 0xCE | |
| buf[pos+1] = union.u8[0] | |
| buf[pos+1] = union.u8[1] | |
| buf[pos+2] = union.u8[2] | |
| buf[pos+3] = union.u8[3] | |
| return 5 | |
| else | |
| buf[pos+0] = 0xCF | |
| buf[pos+1] = union.u8[0] | |
| buf[pos+2] = union.u8[1] | |
| buf[pos+3] = union.u8[2] | |
| buf[pos+4] = union.u8[3] | |
| buf[pos+5] = union.u8[4] | |
| buf[pos+6] = union.u8[5] | |
| buf[pos+7] = union.u8[6] | |
| buf[pos+8] = union.u8[7] | |
| return 9 | |
| end | |
| end | |
| end | |
| end | |
| local function pack_nil( buf, pos ) | |
| buf[pos] = 0xC0 | |
| return 1 | |
| end | |
| local function pack_false( buf, pos ) | |
| buf[pos] = 0xC2 | |
| return 1 | |
| end | |
| local function pack_true( buf, pos ) | |
| buf[pos] = 0xC3 | |
| return 1 | |
| end | |
| local function pack_float( buf, pos ) | |
| buf[pos+0] = 0xCA | |
| buf[pos+1] = union.u8[0] | |
| buf[pos+2] = union.u8[1] | |
| buf[pos+3] = union.u8[2] | |
| buf[pos+4] = union.u8[3] | |
| return 5 | |
| end | |
| local function pack_double( buf, pos ) | |
| buf[pos+0] = 0xCB | |
| buf[pos+1] = union.u8[0] | |
| buf[pos+2] = union.u8[1] | |
| buf[pos+3] = union.u8[2] | |
| buf[pos+4] = union.u8[3] | |
| buf[pos+5] = union.u8[4] | |
| buf[pos+6] = union.u8[5] | |
| buf[pos+7] = union.u8[6] | |
| buf[pos+8] = union.u8[7] | |
| return 9 | |
| end | |
| local function pack_array_length( buf, pos ) | |
| if len < 16 then | |
| buf[pos] = 0x90 + len | |
| return 1 | |
| elseif len < 65536 then | |
| buf[pos] = 0xDC | |
| else | |
| buf[pos] = 0xDD | |
| end | |
| return 1 + pack_integer( buf, pos + 1 ) | |
| end | |
| local function pack_map_length( buf, pos ) | |
| if len < 16 then | |
| buf[pos] = 0x80 + len | |
| return 1 | |
| elseif len < 65536 then | |
| buf[pos] = 0xDE | |
| else | |
| buf[pos] = 0xDF | |
| end | |
| return 1 + pack_integer( buf, pos + 1, len ) | |
| end | |
| local function pack_string( buf, pos, string, start, len ) | |
| start = start or 1 | |
| len = len or #string | |
| if len < 32 then | |
| buf[pos] = 0xA0 + len | |
| else | |
| if len < 65536 then | |
| buf[pos] = 0xDA | |
| else | |
| buf[pos] = 0xDB | |
| end | |
| pos = pos + pack_integer( buf, pos, len ) | |
| end | |
| for i=0, len-1 do | |
| buf[pos+i] = string:byte(i+start) | |
| end | |
| return len | |
| end | |
| local function pack_table( buf, pos, table ) | |
| local len = #table | |
| for k,v in pairs( table ) do | |
| local t = type(k) | |
| end | |
| end | |
| local function iter_table( table ) | |
| local inext, it, is = ipairs(table) | |
| local next, t, s = pairs(table) | |
| local max = 10 | |
| print( "I", inext, it, is ) | |
| print( ">", next, t, s ) | |
| local ik, iv = 0, 0 | |
| local k, v = 0, 0 | |
| while true do | |
| -- ik,kv = inext(table, ik) | |
| k,v = next(table, k) | |
| max = max - 1 | |
| if max < 0 then break end | |
| end | |
| end | |
| local st = { 10, 20, 30, 40, fifty="Petdeset", sixty="Shestdest" } | |
| iter_table(st) |