Skip to content

Instantly share code, notes, and snippets.

@jangko
Created October 2, 2015 04:26
Show Gist options
  • Save jangko/df130311ebce7e51d8d4 to your computer and use it in GitHub Desktop.
Save jangko/df130311ebce7e51d8d4 to your computer and use it in GitHub Desktop.
import msgpack, streams
type
anyType = enum
msgMap, msgArray, msgString, msgBool,
msgBin, msgExt, msgFloat32, msgFloat64,
msgInt, msgUint, msgNull
msgPair = tuple[key, val: msgAny]
msgAny = ref object of RootObj
case msgType: anyType
of msgMap: mapVal: seq[msgPair]
of msgArray: arrayVal: seq[msgAny]
of msgString: stringVal: string
of msgBool: boolVal: bool
of msgBin:
binLen: int
binData: string
of msgExt:
extLen, extType: int
extData: string
of msgFloat32: float32Val: float32
of msgFloat64: float64Val: float64
of msgInt: intVal: int64
of msgUint: uintVal: uint64
of msgNull: nullVal: int #should be void?
proc newMsgAny(msgType: anyType): msgAny =
new(result)
result.msgType = msgType
proc toAny(s: Stream): msgAny =
let pos = s.getPosition()
let c = ord(s.readChar)
var len = 0
case c
of 0x00..0x7f:
result = newMsgAny(msgInt)
result.intVal = c
of 0x80..0x8f, 0xde..0xdf:
s.setPosition(pos)
len = s.unpack_map()
result = newMsgAny(msgMap)
result.mapVal = @[]
for i in 0..len-1:
let v = (key: toAny(s), val: toAny(s))
result.mapVal.add v
of 0x90..0x9f, 0xdc..0xdd:
s.setPosition(pos)
len = s.unpack_array()
result = newMsgAny(msgArray)
result.arrayVal = @[]
for i in 0..len-1:
result.arrayVal.add toAny(s)
of 0xa0..0xbf, 0xd9..0xdb:
s.setPosition(pos)
len = s.unpack_string()
result = newMsgAny(msgString)
result.stringVal = s.readStr(len)
of 0xc0:
result = newMsgAny(msgNull)
of 0xc1:
var err: ref ObjectConversionError
new(err)
err.msg = "toAny unused"
raise err
of 0xc2:
result = newMsgAny(msgBool)
result.boolVal = false
of 0xc3:
result = newMsgAny(msgBool)
result.boolVal = true
of 0xc4..0xc6:
s.setPosition(pos)
result = newMsgAny(msgBin)
result.binLen = s.unpack_bin()
result.binData = s.readStr(result.binLen)
of 0xc7..0xc9, 0xd4..0xd8:
s.setPosition(pos)
let (exttype, extlen) = s.unpack_ext()
result = newMsgAny(msgExt)
result.extLen = extlen
result.extType = exttype.int
result.binData = s.readStr(extlen)
of 0xca:
s.setPosition(pos)
result = newMsgAny(msgFloat32)
result.float32Val = s.unpack_imp_float32()
of 0xcb:
s.setPosition(pos)
result = newMsgAny(msgFloat64)
result.float64Val = s.unpack_imp_float64()
of 0xcc..0xcf:
s.setPosition(pos)
result = newMsgAny(msgUint)
result.uintVal = s.unpack_imp_uint64()
of 0xd0..0xd3:
s.setPosition(pos)
result = newMsgAny(msgInt)
result.intVal = s.unpack_imp_int64()
of 0xe0..0xff:
result = newMsgAny(msgInt)
result.intVal = cast[int8](c).int64
proc toAny*(data: string): msgAny =
var s = newStringStream(data)
result = s.toAny()
when isMainModule:
import strtabs
# [1, "hello", {"a": "b"}]
var s = newStringStream()
s.pack_array(3)
s.pack(1)
s.pack("hello")
var tmpMap = newStringTable(modeCaseSensitive)
tmpMap["a"] = "b"
s.pack(tmpMap)
s.setPosition(0)
var a = s.toAny()
assert a.msgType == msgArray
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment