vox-etf 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +11 -0
- data/.rspec +3 -0
- data/.rubocop.yml +22 -0
- data/.travis.yml +6 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +21 -0
- data/README.md +44 -0
- data/Rakefile +14 -0
- data/bin/console +15 -0
- data/bin/rake +31 -0
- data/bin/setup +8 -0
- data/ext/vox/decoder.hpp +356 -0
- data/ext/vox/encoder.hpp +162 -0
- data/ext/vox/erlpack/constants.h +51 -0
- data/ext/vox/erlpack/encoder.h +296 -0
- data/ext/vox/erlpack/sysdep.h +170 -0
- data/ext/vox/etf.cpp +35 -0
- data/ext/vox/etf.hpp +58 -0
- data/ext/vox/extconf.rb +13 -0
- data/lib/vox/etf/version.rb +7 -0
- data/vox-etf.gemspec +40 -0
- metadata +167 -0
data/ext/vox/encoder.hpp
ADDED
@@ -0,0 +1,162 @@
|
|
1
|
+
#include "erlpack/encoder.h"
|
2
|
+
#include "etf.hpp"
|
3
|
+
|
4
|
+
namespace etf
|
5
|
+
{
|
6
|
+
class encoder
|
7
|
+
{
|
8
|
+
public:
|
9
|
+
encoder()
|
10
|
+
{
|
11
|
+
erl_buff = (erlpack_buffer *)malloc(sizeof(erl_buff));
|
12
|
+
erl_buff->buf = (char *)malloc(sizeof(char) * 128);
|
13
|
+
erl_buff->length = 0;
|
14
|
+
erl_buff->allocated_size = 128;
|
15
|
+
erlpack_append_version(erl_buff);
|
16
|
+
}
|
17
|
+
|
18
|
+
~encoder()
|
19
|
+
{
|
20
|
+
free(erl_buff->buf);
|
21
|
+
free(erl_buff);
|
22
|
+
}
|
23
|
+
|
24
|
+
void encode_object(VALUE input)
|
25
|
+
{
|
26
|
+
switch (TYPE(input))
|
27
|
+
{
|
28
|
+
case T_TRUE:
|
29
|
+
encode_true();
|
30
|
+
break;
|
31
|
+
case T_FALSE:
|
32
|
+
encode_false();
|
33
|
+
break;
|
34
|
+
case T_NIL:
|
35
|
+
encode_nil();
|
36
|
+
break;
|
37
|
+
case T_FLOAT:
|
38
|
+
encode_float(input);
|
39
|
+
break;
|
40
|
+
case T_BIGNUM:
|
41
|
+
encode_bignum(input);
|
42
|
+
break;
|
43
|
+
case T_FIXNUM:
|
44
|
+
encode_fixnum(input);
|
45
|
+
break;
|
46
|
+
case T_SYMBOL:
|
47
|
+
encode_symbol(input);
|
48
|
+
break;
|
49
|
+
case T_STRING:
|
50
|
+
encode_string(input);
|
51
|
+
break;
|
52
|
+
case T_ARRAY:
|
53
|
+
encode_array(input);
|
54
|
+
break;
|
55
|
+
case T_HASH:
|
56
|
+
encode_hash(input);
|
57
|
+
break;
|
58
|
+
default:
|
59
|
+
rb_raise(rb_eArgError, "Unsupported serialization type");
|
60
|
+
break;
|
61
|
+
}
|
62
|
+
}
|
63
|
+
|
64
|
+
VALUE
|
65
|
+
r_string(void)
|
66
|
+
{
|
67
|
+
return rb_str_new(erl_buff->buf, erl_buff->length);
|
68
|
+
}
|
69
|
+
|
70
|
+
private:
|
71
|
+
erlpack_buffer *erl_buff;
|
72
|
+
|
73
|
+
void encode_true()
|
74
|
+
{
|
75
|
+
erlpack_append_true(erl_buff);
|
76
|
+
}
|
77
|
+
|
78
|
+
void encode_false()
|
79
|
+
{
|
80
|
+
erlpack_append_false(erl_buff);
|
81
|
+
}
|
82
|
+
|
83
|
+
void encode_nil()
|
84
|
+
{
|
85
|
+
erlpack_append_nil(erl_buff);
|
86
|
+
}
|
87
|
+
|
88
|
+
void encode_fixnum(VALUE fixnum)
|
89
|
+
{
|
90
|
+
long l = FIX2LONG(fixnum);
|
91
|
+
if (l > 0 && l <= 0xFF)
|
92
|
+
erlpack_append_small_integer(erl_buff, (unsigned char)l);
|
93
|
+
else
|
94
|
+
erlpack_append_integer(erl_buff, l);
|
95
|
+
}
|
96
|
+
|
97
|
+
void encode_bignum(VALUE bignum)
|
98
|
+
{
|
99
|
+
size_t byte_count = rb_absint_size(bignum, NULL);
|
100
|
+
if (byte_count <= 0xFF)
|
101
|
+
{
|
102
|
+
// id byte | n byte | sign byte | data
|
103
|
+
uint8_t buff[3 + byte_count];
|
104
|
+
buff[0] = term::small_big;
|
105
|
+
buff[1] = byte_count;
|
106
|
+
buff[2] = FIX2LONG(bignum) >= 0 ? 0 : 1;
|
107
|
+
rb_integer_pack(bignum, buff + 3, byte_count, sizeof(uint8_t), 0, INTEGER_PACK_LITTLE_ENDIAN);
|
108
|
+
erlpack_buffer_write(erl_buff, (const char *)buff, 3 + byte_count);
|
109
|
+
}
|
110
|
+
else
|
111
|
+
{
|
112
|
+
// id byte | 4 byte n | sign byte | data
|
113
|
+
uint8_t buff[6 + byte_count];
|
114
|
+
buff[0] = term::large_big;
|
115
|
+
_erlpack_store32(buff + 1, byte_count);
|
116
|
+
buff[5] = RBIGNUM_SIGN(bignum) ? 0 : 1;
|
117
|
+
rb_integer_pack(bignum, buff + 6, byte_count, sizeof(uint8_t), 0, INTEGER_PACK_LITTLE_ENDIAN);
|
118
|
+
erlpack_buffer_write(erl_buff, (const char *)buff, 6 + byte_count);
|
119
|
+
}
|
120
|
+
}
|
121
|
+
|
122
|
+
void encode_float(VALUE rfloat)
|
123
|
+
{
|
124
|
+
erlpack_append_double(erl_buff, NUM2DBL(rfloat));
|
125
|
+
}
|
126
|
+
|
127
|
+
void encode_array(VALUE array)
|
128
|
+
{
|
129
|
+
erlpack_append_list_header(erl_buff, RARRAY_LEN(array));
|
130
|
+
uint32_t size = RARRAY_LEN(array);
|
131
|
+
for (uint32_t index = 0; index < size; index++)
|
132
|
+
{
|
133
|
+
encode_object(RARRAY_AREF(array, index));
|
134
|
+
}
|
135
|
+
}
|
136
|
+
|
137
|
+
void encode_symbol(VALUE symbol)
|
138
|
+
{
|
139
|
+
VALUE str = rb_sym2str(symbol);
|
140
|
+
erlpack_append_atom_utf8(erl_buff, RSTRING_PTR(str), RSTRING_LEN(str));
|
141
|
+
}
|
142
|
+
|
143
|
+
void encode_string(VALUE string)
|
144
|
+
{
|
145
|
+
erlpack_append_binary(erl_buff, RSTRING_PTR(string), RSTRING_LEN(string));
|
146
|
+
}
|
147
|
+
|
148
|
+
void encode_hash(VALUE hash)
|
149
|
+
{
|
150
|
+
uint32_t size = RHASH_SIZE(hash);
|
151
|
+
erlpack_append_map_header(erl_buff, size);
|
152
|
+
VALUE keys = rb_funcall(hash, rb_intern("keys"), 0);
|
153
|
+
|
154
|
+
for (uint32_t index = 0; index < size * 2; index += 2)
|
155
|
+
{
|
156
|
+
VALUE key = RARRAY_AREF(keys, index / 2);
|
157
|
+
encode_object(key);
|
158
|
+
encode_object(rb_hash_aref(hash, key));
|
159
|
+
}
|
160
|
+
}
|
161
|
+
};
|
162
|
+
} // namespace etf
|
@@ -0,0 +1,51 @@
|
|
1
|
+
/************************************************
|
2
|
+
* MIT License
|
3
|
+
*
|
4
|
+
* Copyright (c) 2017 Discord
|
5
|
+
*
|
6
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
7
|
+
* of this software and associated documentation files (the "Software"), to deal
|
8
|
+
* in the Software without restriction, including without limitation the rights
|
9
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
10
|
+
* copies of the Software, and to permit persons to whom the Software is
|
11
|
+
* furnished to do so, subject to the following conditions:
|
12
|
+
*
|
13
|
+
* The above copyright notice and this permission notice shall be included in all
|
14
|
+
* copies or substantial portions of the Software.
|
15
|
+
*
|
16
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
17
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
18
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
19
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
20
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
21
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
22
|
+
* SOFTWARE.
|
23
|
+
************************************************/
|
24
|
+
|
25
|
+
#define FORMAT_VERSION 131
|
26
|
+
#define NEW_FLOAT_EXT 'F' // 70 [Float64:IEEE float]
|
27
|
+
#define BIT_BINARY_EXT 'M' // 77 [UInt32:Len, UInt8:Bits, Len:Data]
|
28
|
+
#define COMPRESSED 'P' // 80 [UInt4:UncompressedSize, N:ZlibCompressedData]
|
29
|
+
#define SMALL_INTEGER_EXT 'a' // 97 [UInt8:Int]
|
30
|
+
#define INTEGER_EXT 'b' // 98 [Int32:Int]
|
31
|
+
#define FLOAT_EXT 'c' // 99 [31:Float String] Float in string format (formatted "%.20e", sscanf "%lf"). Superseded by NEW_FLOAT_EXT
|
32
|
+
#define ATOM_EXT 'd' // 100 [UInt16:Len, Len:AtomName] max Len is 255
|
33
|
+
#define REFERENCE_EXT 'e' // 101 [atom:Node, UInt32:ID, UInt8:Creation]
|
34
|
+
#define PORT_EXT 'f' // 102 [atom:Node, UInt32:ID, UInt8:Creation]
|
35
|
+
#define PID_EXT 'g' // 103 [atom:Node, UInt32:ID, UInt32:Serial, UInt8:Creation]
|
36
|
+
#define SMALL_TUPLE_EXT 'h' // 104 [UInt8:Arity, N:Elements]
|
37
|
+
#define LARGE_TUPLE_EXT 'i' // 105 [UInt32:Arity, N:Elements]
|
38
|
+
#define NIL_EXT 'j' // 106 empty list
|
39
|
+
#define STRING_EXT 'k' // 107 [UInt16:Len, Len:Characters]
|
40
|
+
#define LIST_EXT 'l' // 108 [UInt32:Len, Elements, Tail]
|
41
|
+
#define BINARY_EXT 'm' // 109 [UInt32:Len, Len:Data]
|
42
|
+
#define SMALL_BIG_EXT 'n' // 110 [UInt8:n, UInt8:Sign, n:nums]
|
43
|
+
#define LARGE_BIG_EXT 'o' // 111 [UInt32:n, UInt8:Sign, n:nums]
|
44
|
+
#define NEW_FUN_EXT 'p' // 112 [UInt32:Size, UInt8:Arity, 16*Uint6-MD5:Uniq, UInt32:Index, UInt32:NumFree, atom:Module, int:OldIndex, int:OldUniq, pid:Pid, NunFree*ext:FreeVars]
|
45
|
+
#define EXPORT_EXT 'q' // 113 [atom:Module, atom:Function, smallint:Arity]
|
46
|
+
#define NEW_REFERENCE_EXT 'r' // 114 [UInt16:Len, atom:Node, UInt8:Creation, Len*UInt32:ID]
|
47
|
+
#define SMALL_ATOM_EXT 's' // 115 [UInt8:Len, Len:AtomName]
|
48
|
+
#define MAP_EXT 't' // 116 [UInt32:Airty, N:Pairs]
|
49
|
+
#define FUN_EXT 'u' // 117 [UInt4:NumFree, pid:Pid, atom:Module, int:Index, int:Uniq, NumFree*ext:FreeVars]
|
50
|
+
#define ATOM_UTF8_EXT 'v' // 118 [UInt16:Len, Len:AtomName] max Len is 255 characters (up to 4 bytes per)
|
51
|
+
#define SMALL_ATOM_UTF8_EXT 'w' // 119 [UInt8:Len, Len:AtomName]
|
@@ -0,0 +1,296 @@
|
|
1
|
+
/************************************************
|
2
|
+
* MIT License
|
3
|
+
*
|
4
|
+
* Copyright (c) 2017 Discord
|
5
|
+
*
|
6
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
7
|
+
* of this software and associated documentation files (the "Software"), to deal
|
8
|
+
* in the Software without restriction, including without limitation the rights
|
9
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
10
|
+
* copies of the Software, and to permit persons to whom the Software is
|
11
|
+
* furnished to do so, subject to the following conditions:
|
12
|
+
*
|
13
|
+
* The above copyright notice and this permission notice shall be included in all
|
14
|
+
* copies or substantial portions of the Software.
|
15
|
+
*
|
16
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
17
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
18
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
19
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
20
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
21
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
22
|
+
* SOFTWARE.
|
23
|
+
************************************************/
|
24
|
+
|
25
|
+
#include <stddef.h>
|
26
|
+
#include <stdlib.h>
|
27
|
+
#include "sysdep.h"
|
28
|
+
#include "constants.h"
|
29
|
+
#include <limits.h>
|
30
|
+
#include <string.h>
|
31
|
+
|
32
|
+
#ifdef __cplusplus
|
33
|
+
extern "C"
|
34
|
+
{
|
35
|
+
#endif
|
36
|
+
|
37
|
+
typedef struct erlpack_buffer
|
38
|
+
{
|
39
|
+
char *buf;
|
40
|
+
size_t length;
|
41
|
+
size_t allocated_size;
|
42
|
+
} erlpack_buffer;
|
43
|
+
|
44
|
+
static inline int erlpack_buffer_write(erlpack_buffer *pk, const char *bytes,
|
45
|
+
size_t l)
|
46
|
+
{
|
47
|
+
char *buf = pk->buf;
|
48
|
+
size_t allocated_size = pk->allocated_size;
|
49
|
+
size_t length = pk->length;
|
50
|
+
|
51
|
+
if (length + l > allocated_size)
|
52
|
+
{
|
53
|
+
// Grow buffer 2x to avoid excessive re-allocations.
|
54
|
+
allocated_size = (length + l) * 2;
|
55
|
+
buf = (char *)realloc(buf, allocated_size);
|
56
|
+
|
57
|
+
if (!buf)
|
58
|
+
return -1;
|
59
|
+
}
|
60
|
+
|
61
|
+
memcpy(buf + length, bytes, l);
|
62
|
+
length += l;
|
63
|
+
|
64
|
+
pk->buf = buf;
|
65
|
+
pk->allocated_size = allocated_size;
|
66
|
+
pk->length = length;
|
67
|
+
return 0;
|
68
|
+
}
|
69
|
+
|
70
|
+
#define erlpack_append(pk, buf, len) \
|
71
|
+
return erlpack_buffer_write(pk, (const char *)buf, len)
|
72
|
+
|
73
|
+
static inline int erlpack_append_version(erlpack_buffer *b)
|
74
|
+
{
|
75
|
+
static unsigned char buf[1] = {FORMAT_VERSION};
|
76
|
+
erlpack_append(b, buf, 1);
|
77
|
+
}
|
78
|
+
|
79
|
+
static inline int erlpack_append_nil(erlpack_buffer *b)
|
80
|
+
{
|
81
|
+
static unsigned char buf[5] = {SMALL_ATOM_EXT, 3, 'n', 'i', 'l'};
|
82
|
+
erlpack_append(b, buf, 5);
|
83
|
+
}
|
84
|
+
static inline int erlpack_append_false(erlpack_buffer *b)
|
85
|
+
{
|
86
|
+
static unsigned char buf[7] = {SMALL_ATOM_EXT, 5, 'f', 'a', 'l', 's', 'e'};
|
87
|
+
erlpack_append(b, buf, 7);
|
88
|
+
}
|
89
|
+
|
90
|
+
static inline int erlpack_append_true(erlpack_buffer *b)
|
91
|
+
{
|
92
|
+
static unsigned char buf[6] = {SMALL_ATOM_EXT, 4, 't', 'r', 'u', 'e'};
|
93
|
+
erlpack_append(b, buf, 6);
|
94
|
+
}
|
95
|
+
|
96
|
+
static inline int erlpack_append_small_integer(erlpack_buffer *b,
|
97
|
+
unsigned char d)
|
98
|
+
{
|
99
|
+
unsigned char buf[2] = {SMALL_INTEGER_EXT, d};
|
100
|
+
erlpack_append(b, buf, 2);
|
101
|
+
}
|
102
|
+
|
103
|
+
static inline int erlpack_append_integer(erlpack_buffer *b, int32_t d)
|
104
|
+
{
|
105
|
+
unsigned char buf[5];
|
106
|
+
buf[0] = INTEGER_EXT;
|
107
|
+
_erlpack_store32(buf + 1, d);
|
108
|
+
erlpack_append(b, buf, 5);
|
109
|
+
}
|
110
|
+
|
111
|
+
static inline int erlpack_append_unsigned_long_long(erlpack_buffer *b,
|
112
|
+
unsigned long long d)
|
113
|
+
{
|
114
|
+
unsigned char buf[1 + 2 + sizeof(unsigned long long)];
|
115
|
+
buf[0] = SMALL_BIG_EXT;
|
116
|
+
|
117
|
+
unsigned char bytes_enc = 0;
|
118
|
+
while (d > 0)
|
119
|
+
{
|
120
|
+
buf[3 + bytes_enc] = d & 0xFF;
|
121
|
+
d >>= 8;
|
122
|
+
bytes_enc++;
|
123
|
+
}
|
124
|
+
buf[1] = bytes_enc;
|
125
|
+
buf[2] = 0;
|
126
|
+
|
127
|
+
erlpack_append(b, buf, 1 + 2 + bytes_enc);
|
128
|
+
}
|
129
|
+
|
130
|
+
static inline int erlpack_append_long_long(erlpack_buffer *b, long long d)
|
131
|
+
{
|
132
|
+
unsigned char buf[1 + 2 + sizeof(unsigned long long)];
|
133
|
+
buf[0] = SMALL_BIG_EXT;
|
134
|
+
buf[2] = d < 0 ? 1 : 0;
|
135
|
+
unsigned long long ull = d < 0 ? -d : d;
|
136
|
+
unsigned char bytes_enc = 0;
|
137
|
+
while (ull > 0)
|
138
|
+
{
|
139
|
+
buf[3 + bytes_enc] = ull & 0xFF;
|
140
|
+
ull >>= 8;
|
141
|
+
bytes_enc++;
|
142
|
+
}
|
143
|
+
buf[1] = bytes_enc;
|
144
|
+
erlpack_append(b, buf, 1 + 2 + bytes_enc);
|
145
|
+
}
|
146
|
+
|
147
|
+
typedef union
|
148
|
+
{
|
149
|
+
uint64_t ui64;
|
150
|
+
double df;
|
151
|
+
} typePunner;
|
152
|
+
|
153
|
+
static inline int erlpack_append_double(erlpack_buffer *b, double f)
|
154
|
+
{
|
155
|
+
unsigned char buf[1 + 8] = {0};
|
156
|
+
buf[0] = NEW_FLOAT_EXT;
|
157
|
+
typePunner p;
|
158
|
+
p.df = f;
|
159
|
+
_erlpack_store64(buf + 1, p.ui64);
|
160
|
+
erlpack_append(b, buf, 1 + 8);
|
161
|
+
}
|
162
|
+
|
163
|
+
static inline int erlpack_append_atom(erlpack_buffer *b, const char *bytes, size_t size)
|
164
|
+
{
|
165
|
+
if (size < 255)
|
166
|
+
{
|
167
|
+
unsigned char buf[2] = {SMALL_ATOM_EXT, (unsigned char)size};
|
168
|
+
int ret = erlpack_buffer_write(b, (const char *)buf, 2);
|
169
|
+
if (ret < 0)
|
170
|
+
return ret;
|
171
|
+
|
172
|
+
erlpack_append(b, bytes, size);
|
173
|
+
}
|
174
|
+
else
|
175
|
+
{
|
176
|
+
unsigned char buf[3];
|
177
|
+
buf[0] = ATOM_EXT;
|
178
|
+
|
179
|
+
if (size > 0xFFFF)
|
180
|
+
{
|
181
|
+
return 1;
|
182
|
+
}
|
183
|
+
|
184
|
+
_erlpack_store16(buf + 1, size);
|
185
|
+
|
186
|
+
int ret = erlpack_buffer_write(b, (const char *)buf, 3);
|
187
|
+
if (ret < 0)
|
188
|
+
return ret;
|
189
|
+
|
190
|
+
erlpack_append(b, bytes, size);
|
191
|
+
}
|
192
|
+
}
|
193
|
+
|
194
|
+
static inline int erlpack_append_atom_utf8(erlpack_buffer *b, const char *bytes, size_t size)
|
195
|
+
{
|
196
|
+
if (size < 255)
|
197
|
+
{
|
198
|
+
unsigned char buf[2] = {SMALL_ATOM_UTF8_EXT, (unsigned char)size};
|
199
|
+
int ret = erlpack_buffer_write(b, (const char *)buf, 2);
|
200
|
+
if (ret < 0)
|
201
|
+
return ret;
|
202
|
+
|
203
|
+
erlpack_append(b, bytes, size);
|
204
|
+
}
|
205
|
+
else
|
206
|
+
{
|
207
|
+
unsigned char buf[3];
|
208
|
+
buf[0] = ATOM_UTF8_EXT;
|
209
|
+
|
210
|
+
if (size > 0xFFFF)
|
211
|
+
{
|
212
|
+
return 1;
|
213
|
+
}
|
214
|
+
|
215
|
+
_erlpack_store16(buf + 1, size);
|
216
|
+
|
217
|
+
int ret = erlpack_buffer_write(b, (const char *)buf, 3);
|
218
|
+
if (ret < 0)
|
219
|
+
return ret;
|
220
|
+
|
221
|
+
erlpack_append(b, bytes, size);
|
222
|
+
}
|
223
|
+
}
|
224
|
+
|
225
|
+
static inline int erlpack_append_binary(erlpack_buffer *b, const char *bytes, size_t size)
|
226
|
+
{
|
227
|
+
unsigned char buf[5];
|
228
|
+
buf[0] = BINARY_EXT;
|
229
|
+
|
230
|
+
_erlpack_store32(buf + 1, size);
|
231
|
+
|
232
|
+
int ret = erlpack_buffer_write(b, (const char *)buf, 5);
|
233
|
+
if (ret < 0)
|
234
|
+
return ret;
|
235
|
+
|
236
|
+
erlpack_append(b, bytes, size);
|
237
|
+
}
|
238
|
+
|
239
|
+
static inline int erlpack_append_string(erlpack_buffer *b, const char *bytes, size_t size)
|
240
|
+
{
|
241
|
+
unsigned char buf[3];
|
242
|
+
buf[0] = STRING_EXT;
|
243
|
+
|
244
|
+
_erlpack_store16(buf + 1, size);
|
245
|
+
|
246
|
+
int ret = erlpack_buffer_write(b, (const char *)buf, 3);
|
247
|
+
if (ret < 0)
|
248
|
+
return ret;
|
249
|
+
|
250
|
+
erlpack_append(b, bytes, size);
|
251
|
+
}
|
252
|
+
|
253
|
+
static inline int erlpack_append_tuple_header(erlpack_buffer *b, size_t size)
|
254
|
+
{
|
255
|
+
if (size < 256)
|
256
|
+
{
|
257
|
+
unsigned char buf[2];
|
258
|
+
buf[0] = SMALL_TUPLE_EXT;
|
259
|
+
buf[1] = (unsigned char)size;
|
260
|
+
erlpack_append(b, buf, 2);
|
261
|
+
}
|
262
|
+
else
|
263
|
+
{
|
264
|
+
unsigned char buf[5];
|
265
|
+
buf[0] = LARGE_TUPLE_EXT;
|
266
|
+
_erlpack_store32(buf + 1, size);
|
267
|
+
erlpack_append(b, buf, 5);
|
268
|
+
}
|
269
|
+
}
|
270
|
+
|
271
|
+
static inline int erlpack_append_nil_ext(erlpack_buffer *b)
|
272
|
+
{
|
273
|
+
static unsigned char buf[1] = {NIL_EXT};
|
274
|
+
erlpack_append(b, buf, 1);
|
275
|
+
}
|
276
|
+
|
277
|
+
static inline int erlpack_append_list_header(erlpack_buffer *b, size_t size)
|
278
|
+
{
|
279
|
+
unsigned char buf[5];
|
280
|
+
buf[0] = LIST_EXT;
|
281
|
+
_erlpack_store32(buf + 1, size);
|
282
|
+
erlpack_append(b, buf, 5);
|
283
|
+
}
|
284
|
+
|
285
|
+
static inline int erlpack_append_map_header(erlpack_buffer *b, size_t size)
|
286
|
+
{
|
287
|
+
unsigned char buf[5];
|
288
|
+
buf[0] = MAP_EXT;
|
289
|
+
_erlpack_store32(buf + 1, size);
|
290
|
+
erlpack_append(b, buf, 5);
|
291
|
+
}
|
292
|
+
|
293
|
+
#ifdef __cplusplus
|
294
|
+
}
|
295
|
+
|
296
|
+
#endif
|