-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmsgpack-out.lisp
74 lines (67 loc) · 2.54 KB
/
msgpack-out.lisp
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
(in-package :cn)
;;==============================================================================
;;
;; MSGPACK encoder
;; https://github.com/msgpack/msgpack/blob/master/spec.md
;;
;;------------------------------------------------------------------------------
;;
;; wb - write an 8-bit octet of integer, optionally starting from startbit.
;;
(defun wb (s int &optional (startbit 0) )
(write-byte (ldb (byte 8 startbit) int) s))
;;------------------------------------------------------------------------------
;; Encode an integer
(defun !int (s int)
(if (minusp int)
(cond;; NEGATIVE numbers!
((> int -33) (wb s int 0))
((> int -257) (wb s #xD0) (wb s int))
((> int -65537)
(wb s #xD1) (wb s int 8) (wb s int 0))
((> int #x-100000001)
(wb s #xD2) (wb s int 24) (wb s int 16)(wb s int 8) (wb s int 0))
(t (wb s #xD3) (wb s int 56) (wb s int 48)(wb s int 40) (wb s int 32)
(wb s int 24) (wb s int 16)(wb s int 8) (wb s int 0)))
(cond;; POSITIVE numbers and 0
((zerop int) (wb s 0))
((< int #x80) (wb s int))
((< int #x100) (wb s #xCC) (wb s int))
((< int #x10000) (wb s #xCD) (wb s int 8) (wb s int))
((< int #x100000000)
(wb s #xCE) (wb s int 24) (wb s int 16) (wb s int 8) (wb s int))
(t (wb s #xCE) (wb s int 56) (wb s int 48) (wb s int 40) (wb s int 32)
(wb s #xCE) (wb s int 24) (wb s int 16) (wb s int 8) (wb s int))))
int)
(defun !ints (s &rest ints)
(loop for int in ints do
(!int s int)))
;;------------------------------------------------------------------------------
;; string
;;
(defun !string-header (s len)
(cond
((< len #x20) (wb s (+ #xA0 len)))
((< len #x100) (wb s #xD9) (wb s len))
((< len #x10000) (wb s #xDA) (wb s len 8) (wb s len 0))
((< len #x100000000) (wb s #xDB) (wb s len 24) (wb s len 16)(wb s len 8) (wb s len))
(t (error "String too long")))
len)
;; TODO: UTF8
(defun !string (s string)
(!string-header s (length string))
(loop for c across string do
(write-byte (char-code c) s)))
;;------------------------------------------------------------------------------
;; just the header - you write the data later!
(defun !array-header (s len)
(cond
((< len #x10) (wb s (+ #x90 len)))
((< len #x10000) (wb s #xDC) (wb s len))
(t (wb s #xDD) (wb s len 24) (wb s len 16)(wb s len 8) (wb s len))))
;;------------------------------------------------------------------------------
(defun !map-header (s len)
(cond
((< len #x10) (wb s (+ #x80 len)))
((< len #x10000) (wb s #xDE) (wb s len))
(t (wb s #xDF) (wb s len 24) (wb s len 16)(wb s len 8) (wb s len))))