File: 15-ffi-cdata.lua

package info (click to toggle)
lua-messagepack 0.5.2-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 364 kB
  • sloc: makefile: 108
file content (90 lines) | stat: -rwxr-xr-x 2,600 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#! /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) )