trilogy_w_prepared_statements 2.2.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/LICENSE +22 -0
- data/README.md +80 -0
- data/Rakefile +22 -0
- data/ext/trilogy-ruby/cast.c +277 -0
- data/ext/trilogy-ruby/cext.c +1048 -0
- data/ext/trilogy-ruby/extconf.rb +17 -0
- data/ext/trilogy-ruby/inc/trilogy/blocking.h +281 -0
- data/ext/trilogy-ruby/inc/trilogy/buffer.h +64 -0
- data/ext/trilogy-ruby/inc/trilogy/builder.h +165 -0
- data/ext/trilogy-ruby/inc/trilogy/charset.h +277 -0
- data/ext/trilogy-ruby/inc/trilogy/client.h +760 -0
- data/ext/trilogy-ruby/inc/trilogy/error.h +44 -0
- data/ext/trilogy-ruby/inc/trilogy/packet_parser.h +34 -0
- data/ext/trilogy-ruby/inc/trilogy/protocol.h +1014 -0
- data/ext/trilogy-ruby/inc/trilogy/reader.h +216 -0
- data/ext/trilogy-ruby/inc/trilogy/socket.h +111 -0
- data/ext/trilogy-ruby/inc/trilogy/vendor/curl_hostcheck.h +29 -0
- data/ext/trilogy-ruby/inc/trilogy/vendor/openssl_hostname_validation.h +51 -0
- data/ext/trilogy-ruby/inc/trilogy.h +8 -0
- data/ext/trilogy-ruby/src/blocking.c +358 -0
- data/ext/trilogy-ruby/src/buffer.c +60 -0
- data/ext/trilogy-ruby/src/builder.c +236 -0
- data/ext/trilogy-ruby/src/charset.c +212 -0
- data/ext/trilogy-ruby/src/client.c +903 -0
- data/ext/trilogy-ruby/src/error.c +17 -0
- data/ext/trilogy-ruby/src/packet_parser.c +140 -0
- data/ext/trilogy-ruby/src/protocol.c +1175 -0
- data/ext/trilogy-ruby/src/reader.c +282 -0
- data/ext/trilogy-ruby/src/socket.c +623 -0
- data/ext/trilogy-ruby/src/vendor/curl_hostcheck.c +206 -0
- data/ext/trilogy-ruby/src/vendor/openssl_hostname_validation.c +175 -0
- data/ext/trilogy-ruby/trilogy-ruby.h +37 -0
- data/lib/trilogy/version.rb +3 -0
- data/lib/trilogy.rb +61 -0
- data/trilogy.gemspec +27 -0
- metadata +107 -0
@@ -0,0 +1,358 @@
|
|
1
|
+
#include <errno.h>
|
2
|
+
#include <poll.h>
|
3
|
+
|
4
|
+
#include "trilogy/blocking.h"
|
5
|
+
#include "trilogy/client.h"
|
6
|
+
#include "trilogy/error.h"
|
7
|
+
|
8
|
+
#define CHECKED(expr) \
|
9
|
+
if ((rc = (expr)) < 0) { \
|
10
|
+
return rc; \
|
11
|
+
}
|
12
|
+
|
13
|
+
static int flush_full(trilogy_conn_t *conn)
|
14
|
+
{
|
15
|
+
int rc;
|
16
|
+
|
17
|
+
while (1) {
|
18
|
+
CHECKED(trilogy_sock_wait_write(conn->socket));
|
19
|
+
|
20
|
+
rc = trilogy_flush_writes(conn);
|
21
|
+
|
22
|
+
if (rc != TRILOGY_AGAIN) {
|
23
|
+
return rc;
|
24
|
+
}
|
25
|
+
}
|
26
|
+
}
|
27
|
+
|
28
|
+
static int trilogy_connect_auth_switch(trilogy_conn_t *conn, trilogy_handshake_t *handshake)
|
29
|
+
{
|
30
|
+
int rc = trilogy_auth_switch_send(conn, handshake);
|
31
|
+
|
32
|
+
if (rc == TRILOGY_AGAIN) {
|
33
|
+
rc = flush_full(conn);
|
34
|
+
}
|
35
|
+
|
36
|
+
if (rc < 0) {
|
37
|
+
return rc;
|
38
|
+
}
|
39
|
+
|
40
|
+
while (1) {
|
41
|
+
rc = trilogy_auth_recv(conn, handshake);
|
42
|
+
|
43
|
+
if (rc != TRILOGY_AGAIN) {
|
44
|
+
break;
|
45
|
+
}
|
46
|
+
|
47
|
+
CHECKED(trilogy_sock_wait_read(conn->socket));
|
48
|
+
}
|
49
|
+
return rc;
|
50
|
+
}
|
51
|
+
|
52
|
+
static int trilogy_connect_handshake(trilogy_conn_t *conn)
|
53
|
+
{
|
54
|
+
trilogy_handshake_t handshake;
|
55
|
+
int rc;
|
56
|
+
|
57
|
+
while (1) {
|
58
|
+
rc = trilogy_connect_recv(conn, &handshake);
|
59
|
+
|
60
|
+
if (rc == TRILOGY_OK) {
|
61
|
+
break;
|
62
|
+
}
|
63
|
+
|
64
|
+
if (rc != TRILOGY_AGAIN) {
|
65
|
+
return rc;
|
66
|
+
}
|
67
|
+
|
68
|
+
CHECKED(trilogy_sock_wait_read(conn->socket));
|
69
|
+
}
|
70
|
+
|
71
|
+
rc = trilogy_auth_send(conn, &handshake);
|
72
|
+
|
73
|
+
if (rc == TRILOGY_AGAIN) {
|
74
|
+
rc = flush_full(conn);
|
75
|
+
}
|
76
|
+
|
77
|
+
if (rc < 0) {
|
78
|
+
return rc;
|
79
|
+
}
|
80
|
+
|
81
|
+
while (1) {
|
82
|
+
rc = trilogy_auth_recv(conn, &handshake);
|
83
|
+
|
84
|
+
if (rc != TRILOGY_AGAIN) {
|
85
|
+
break;
|
86
|
+
}
|
87
|
+
|
88
|
+
CHECKED(trilogy_sock_wait_read(conn->socket));
|
89
|
+
}
|
90
|
+
|
91
|
+
if (rc == TRILOGY_AUTH_SWITCH) {
|
92
|
+
return trilogy_connect_auth_switch(conn, &handshake);
|
93
|
+
}
|
94
|
+
return rc;
|
95
|
+
}
|
96
|
+
|
97
|
+
int trilogy_connect(trilogy_conn_t *conn, const trilogy_sockopt_t *opts)
|
98
|
+
{
|
99
|
+
int rc = trilogy_connect_send(conn, opts);
|
100
|
+
|
101
|
+
if (rc < 0) {
|
102
|
+
return rc;
|
103
|
+
}
|
104
|
+
|
105
|
+
return trilogy_connect_handshake(conn);
|
106
|
+
}
|
107
|
+
|
108
|
+
int trilogy_connect_sock(trilogy_conn_t *conn, trilogy_sock_t *sock)
|
109
|
+
{
|
110
|
+
int rc = trilogy_connect_send_socket(conn, sock);
|
111
|
+
|
112
|
+
if (rc < 0) {
|
113
|
+
return rc;
|
114
|
+
}
|
115
|
+
|
116
|
+
return trilogy_connect_handshake(conn);
|
117
|
+
}
|
118
|
+
|
119
|
+
int trilogy_change_db(trilogy_conn_t *conn, const char *name, size_t name_len)
|
120
|
+
{
|
121
|
+
int rc = trilogy_change_db_send(conn, name, name_len);
|
122
|
+
|
123
|
+
if (rc == TRILOGY_AGAIN) {
|
124
|
+
rc = flush_full(conn);
|
125
|
+
}
|
126
|
+
|
127
|
+
if (rc < 0) {
|
128
|
+
return rc;
|
129
|
+
}
|
130
|
+
|
131
|
+
while (1) {
|
132
|
+
rc = trilogy_change_db_recv(conn);
|
133
|
+
|
134
|
+
if (rc != TRILOGY_AGAIN) {
|
135
|
+
return rc;
|
136
|
+
}
|
137
|
+
|
138
|
+
CHECKED(trilogy_sock_wait_read(conn->socket));
|
139
|
+
}
|
140
|
+
}
|
141
|
+
|
142
|
+
int trilogy_ping(trilogy_conn_t *conn)
|
143
|
+
{
|
144
|
+
int rc = trilogy_ping_send(conn);
|
145
|
+
|
146
|
+
if (rc == TRILOGY_AGAIN) {
|
147
|
+
rc = flush_full(conn);
|
148
|
+
}
|
149
|
+
|
150
|
+
if (rc < 0) {
|
151
|
+
return rc;
|
152
|
+
}
|
153
|
+
|
154
|
+
while (1) {
|
155
|
+
rc = trilogy_ping_recv(conn);
|
156
|
+
|
157
|
+
if (rc != TRILOGY_AGAIN) {
|
158
|
+
return rc;
|
159
|
+
}
|
160
|
+
|
161
|
+
CHECKED(trilogy_sock_wait_read(conn->socket));
|
162
|
+
}
|
163
|
+
}
|
164
|
+
|
165
|
+
int trilogy_query(trilogy_conn_t *conn, const char *query, size_t query_len, uint64_t *column_count_out)
|
166
|
+
{
|
167
|
+
int rc = trilogy_query_send(conn, query, query_len);
|
168
|
+
|
169
|
+
if (rc == TRILOGY_AGAIN) {
|
170
|
+
rc = flush_full(conn);
|
171
|
+
}
|
172
|
+
|
173
|
+
if (rc < 0) {
|
174
|
+
return rc;
|
175
|
+
}
|
176
|
+
|
177
|
+
while (1) {
|
178
|
+
rc = trilogy_query_recv(conn, column_count_out);
|
179
|
+
|
180
|
+
if (rc != TRILOGY_AGAIN) {
|
181
|
+
return rc;
|
182
|
+
}
|
183
|
+
|
184
|
+
CHECKED(trilogy_sock_wait_read(conn->socket));
|
185
|
+
}
|
186
|
+
}
|
187
|
+
|
188
|
+
int trilogy_read_full_column(trilogy_conn_t *conn, trilogy_column_t *column_out)
|
189
|
+
{
|
190
|
+
int rc;
|
191
|
+
|
192
|
+
while (1) {
|
193
|
+
rc = trilogy_read_column(conn, column_out);
|
194
|
+
|
195
|
+
if (rc != TRILOGY_AGAIN) {
|
196
|
+
return rc;
|
197
|
+
}
|
198
|
+
|
199
|
+
CHECKED(trilogy_sock_wait_read(conn->socket));
|
200
|
+
}
|
201
|
+
}
|
202
|
+
|
203
|
+
int trilogy_read_full_row(trilogy_conn_t *conn, trilogy_value_t *values_out)
|
204
|
+
{
|
205
|
+
int rc;
|
206
|
+
|
207
|
+
while (1) {
|
208
|
+
rc = trilogy_read_row(conn, values_out);
|
209
|
+
|
210
|
+
if (rc != TRILOGY_AGAIN) {
|
211
|
+
return rc;
|
212
|
+
}
|
213
|
+
|
214
|
+
CHECKED(trilogy_sock_wait_read(conn->socket));
|
215
|
+
}
|
216
|
+
}
|
217
|
+
|
218
|
+
int trilogy_close(trilogy_conn_t *conn)
|
219
|
+
{
|
220
|
+
int rc = trilogy_close_send(conn);
|
221
|
+
|
222
|
+
if (rc == TRILOGY_AGAIN) {
|
223
|
+
rc = flush_full(conn);
|
224
|
+
}
|
225
|
+
|
226
|
+
if (rc < 0) {
|
227
|
+
return rc;
|
228
|
+
}
|
229
|
+
|
230
|
+
while (1) {
|
231
|
+
rc = trilogy_close_recv(conn);
|
232
|
+
|
233
|
+
if (rc != TRILOGY_AGAIN) {
|
234
|
+
return rc;
|
235
|
+
}
|
236
|
+
|
237
|
+
CHECKED(trilogy_sock_wait_read(conn->socket));
|
238
|
+
}
|
239
|
+
}
|
240
|
+
|
241
|
+
int trilogy_stmt_prepare(trilogy_conn_t *conn, const char *stmt, size_t stmt_len, trilogy_stmt_t *stmt_out)
|
242
|
+
{
|
243
|
+
int rc = trilogy_stmt_prepare_send(conn, stmt, stmt_len);
|
244
|
+
|
245
|
+
if (rc == TRILOGY_AGAIN) {
|
246
|
+
rc = flush_full(conn);
|
247
|
+
}
|
248
|
+
|
249
|
+
if (rc < 0) {
|
250
|
+
return rc;
|
251
|
+
}
|
252
|
+
|
253
|
+
while (1) {
|
254
|
+
rc = trilogy_stmt_prepare_recv(conn, stmt_out);
|
255
|
+
|
256
|
+
if (rc != TRILOGY_AGAIN) {
|
257
|
+
return rc;
|
258
|
+
}
|
259
|
+
|
260
|
+
CHECKED(trilogy_sock_wait_read(conn->socket));
|
261
|
+
}
|
262
|
+
}
|
263
|
+
|
264
|
+
int trilogy_stmt_execute(trilogy_conn_t *conn, trilogy_stmt_t *stmt, uint8_t flags, trilogy_binary_value_t *binds,
|
265
|
+
uint64_t *column_count_out)
|
266
|
+
{
|
267
|
+
int rc = trilogy_stmt_execute_send(conn, stmt, flags, binds);
|
268
|
+
|
269
|
+
if (rc == TRILOGY_AGAIN) {
|
270
|
+
rc = flush_full(conn);
|
271
|
+
}
|
272
|
+
|
273
|
+
if (rc < 0) {
|
274
|
+
return rc;
|
275
|
+
}
|
276
|
+
|
277
|
+
while (1) {
|
278
|
+
rc = trilogy_stmt_execute_recv(conn, column_count_out);
|
279
|
+
|
280
|
+
if (rc != TRILOGY_AGAIN) {
|
281
|
+
return rc;
|
282
|
+
}
|
283
|
+
|
284
|
+
CHECKED(trilogy_sock_wait_read(conn->socket));
|
285
|
+
}
|
286
|
+
}
|
287
|
+
|
288
|
+
int trilogy_stmt_bind_data(trilogy_conn_t *conn, trilogy_stmt_t *stmt, uint16_t param_num, uint8_t *data,
|
289
|
+
size_t data_len)
|
290
|
+
{
|
291
|
+
int rc = trilogy_stmt_bind_data_send(conn, stmt, param_num, data, data_len);
|
292
|
+
|
293
|
+
if (rc == TRILOGY_AGAIN) {
|
294
|
+
rc = flush_full(conn);
|
295
|
+
}
|
296
|
+
|
297
|
+
if (rc < 0) {
|
298
|
+
return rc;
|
299
|
+
}
|
300
|
+
|
301
|
+
return TRILOGY_OK;
|
302
|
+
}
|
303
|
+
|
304
|
+
int trilogy_stmt_read_full_row(trilogy_conn_t *conn, trilogy_stmt_t *stmt, trilogy_column_packet_t *columns,
|
305
|
+
trilogy_binary_value_t *values_out)
|
306
|
+
{
|
307
|
+
int rc;
|
308
|
+
|
309
|
+
while (1) {
|
310
|
+
rc = trilogy_stmt_read_row(conn, stmt, columns, values_out);
|
311
|
+
|
312
|
+
if (rc != TRILOGY_AGAIN) {
|
313
|
+
return rc;
|
314
|
+
}
|
315
|
+
|
316
|
+
CHECKED(trilogy_sock_wait_read(conn->socket));
|
317
|
+
}
|
318
|
+
}
|
319
|
+
|
320
|
+
int trilogy_stmt_reset(trilogy_conn_t *conn, trilogy_stmt_t *stmt)
|
321
|
+
{
|
322
|
+
int rc = trilogy_stmt_reset_send(conn, stmt);
|
323
|
+
|
324
|
+
if (rc == TRILOGY_AGAIN) {
|
325
|
+
rc = flush_full(conn);
|
326
|
+
}
|
327
|
+
|
328
|
+
if (rc < 0) {
|
329
|
+
return rc;
|
330
|
+
}
|
331
|
+
|
332
|
+
while (1) {
|
333
|
+
rc = trilogy_stmt_reset_recv(conn);
|
334
|
+
|
335
|
+
if (rc != TRILOGY_AGAIN) {
|
336
|
+
return rc;
|
337
|
+
}
|
338
|
+
|
339
|
+
CHECKED(trilogy_sock_wait_read(conn->socket));
|
340
|
+
}
|
341
|
+
}
|
342
|
+
|
343
|
+
int trilogy_stmt_close(trilogy_conn_t *conn, trilogy_stmt_t *stmt)
|
344
|
+
{
|
345
|
+
int rc = trilogy_stmt_close_send(conn, stmt);
|
346
|
+
|
347
|
+
if (rc == TRILOGY_AGAIN) {
|
348
|
+
rc = flush_full(conn);
|
349
|
+
}
|
350
|
+
|
351
|
+
if (rc < 0) {
|
352
|
+
return rc;
|
353
|
+
}
|
354
|
+
|
355
|
+
return TRILOGY_OK;
|
356
|
+
}
|
357
|
+
|
358
|
+
#undef CHECKED
|
@@ -0,0 +1,60 @@
|
|
1
|
+
#include <stdint.h>
|
2
|
+
#include <stdlib.h>
|
3
|
+
|
4
|
+
#include "trilogy/buffer.h"
|
5
|
+
#include "trilogy/error.h"
|
6
|
+
|
7
|
+
int trilogy_buffer_init(trilogy_buffer_t *buffer, size_t initial_capacity)
|
8
|
+
{
|
9
|
+
buffer->len = 0;
|
10
|
+
buffer->cap = initial_capacity;
|
11
|
+
buffer->buff = malloc(initial_capacity);
|
12
|
+
|
13
|
+
if (buffer->buff == NULL) {
|
14
|
+
return TRILOGY_SYSERR;
|
15
|
+
}
|
16
|
+
|
17
|
+
return TRILOGY_OK;
|
18
|
+
}
|
19
|
+
|
20
|
+
#define EXPAND_MULTIPLIER 2
|
21
|
+
|
22
|
+
int trilogy_buffer_expand(trilogy_buffer_t *buffer, size_t needed)
|
23
|
+
{
|
24
|
+
// expand buffer if necessary
|
25
|
+
if (buffer->len + needed > buffer->cap) {
|
26
|
+
size_t new_cap = buffer->cap;
|
27
|
+
|
28
|
+
while (buffer->len + needed > new_cap) {
|
29
|
+
// would this next step cause an overflow?
|
30
|
+
if (new_cap > SIZE_MAX / EXPAND_MULTIPLIER)
|
31
|
+
return TRILOGY_TYPE_OVERFLOW;
|
32
|
+
|
33
|
+
new_cap *= EXPAND_MULTIPLIER;
|
34
|
+
}
|
35
|
+
|
36
|
+
uint8_t *new_buff = realloc(buffer->buff, new_cap);
|
37
|
+
if (new_buff == NULL)
|
38
|
+
return TRILOGY_SYSERR;
|
39
|
+
|
40
|
+
buffer->buff = new_buff;
|
41
|
+
buffer->cap = new_cap;
|
42
|
+
}
|
43
|
+
|
44
|
+
return TRILOGY_OK;
|
45
|
+
}
|
46
|
+
|
47
|
+
int trilogy_buffer_putc(trilogy_buffer_t *buffer, uint8_t c)
|
48
|
+
{
|
49
|
+
int rc = trilogy_buffer_expand(buffer, 1);
|
50
|
+
|
51
|
+
if (rc) {
|
52
|
+
return rc;
|
53
|
+
}
|
54
|
+
|
55
|
+
buffer->buff[buffer->len++] = c;
|
56
|
+
|
57
|
+
return TRILOGY_OK;
|
58
|
+
}
|
59
|
+
|
60
|
+
void trilogy_buffer_free(trilogy_buffer_t *buffer) { free(buffer->buff); }
|
@@ -0,0 +1,236 @@
|
|
1
|
+
#include "trilogy/builder.h"
|
2
|
+
#include "trilogy/error.h"
|
3
|
+
#include "trilogy/packet_parser.h"
|
4
|
+
|
5
|
+
#include <stdlib.h>
|
6
|
+
#include <string.h>
|
7
|
+
|
8
|
+
static int write_header(trilogy_builder_t *builder)
|
9
|
+
{
|
10
|
+
int rc = trilogy_buffer_expand(builder->buffer, 4);
|
11
|
+
|
12
|
+
if (rc < 0) {
|
13
|
+
return rc;
|
14
|
+
}
|
15
|
+
|
16
|
+
builder->header_offset = builder->buffer->len;
|
17
|
+
builder->fragment_length = 0;
|
18
|
+
|
19
|
+
builder->buffer->buff[builder->buffer->len++] = 0;
|
20
|
+
builder->buffer->buff[builder->buffer->len++] = 0;
|
21
|
+
builder->buffer->buff[builder->buffer->len++] = 0;
|
22
|
+
builder->buffer->buff[builder->buffer->len++] = builder->seq++;
|
23
|
+
|
24
|
+
return TRILOGY_OK;
|
25
|
+
}
|
26
|
+
|
27
|
+
static int write_continuation_header(trilogy_builder_t *builder)
|
28
|
+
{
|
29
|
+
builder->buffer->buff[builder->header_offset] = 0xff;
|
30
|
+
builder->buffer->buff[builder->header_offset + 1] = 0xff;
|
31
|
+
builder->buffer->buff[builder->header_offset + 2] = 0xff;
|
32
|
+
|
33
|
+
return write_header(builder);
|
34
|
+
}
|
35
|
+
|
36
|
+
int trilogy_builder_init(trilogy_builder_t *builder, trilogy_buffer_t *buff, uint8_t seq)
|
37
|
+
{
|
38
|
+
builder->buffer = buff;
|
39
|
+
builder->buffer->len = 0;
|
40
|
+
|
41
|
+
builder->seq = seq;
|
42
|
+
|
43
|
+
return write_header(builder);
|
44
|
+
}
|
45
|
+
|
46
|
+
void trilogy_builder_finalize(trilogy_builder_t *builder)
|
47
|
+
{
|
48
|
+
builder->buffer->buff[builder->header_offset + 0] = (builder->fragment_length >> 0) & 0xff;
|
49
|
+
builder->buffer->buff[builder->header_offset + 1] = (builder->fragment_length >> 8) & 0xff;
|
50
|
+
builder->buffer->buff[builder->header_offset + 2] = (builder->fragment_length >> 16) & 0xff;
|
51
|
+
}
|
52
|
+
|
53
|
+
#define CHECKED(expr) \
|
54
|
+
{ \
|
55
|
+
int rc = (expr); \
|
56
|
+
if (rc) { \
|
57
|
+
return rc; \
|
58
|
+
} \
|
59
|
+
}
|
60
|
+
|
61
|
+
int trilogy_builder_write_uint8(trilogy_builder_t *builder, uint8_t val)
|
62
|
+
{
|
63
|
+
CHECKED(trilogy_buffer_expand(builder->buffer, 1));
|
64
|
+
|
65
|
+
builder->buffer->buff[builder->buffer->len++] = val;
|
66
|
+
builder->fragment_length++;
|
67
|
+
|
68
|
+
if (builder->fragment_length == TRILOGY_MAX_PACKET_LEN) {
|
69
|
+
CHECKED(write_continuation_header(builder));
|
70
|
+
}
|
71
|
+
|
72
|
+
return TRILOGY_OK;
|
73
|
+
}
|
74
|
+
|
75
|
+
int trilogy_builder_write_uint16(trilogy_builder_t *builder, uint16_t val)
|
76
|
+
{
|
77
|
+
CHECKED(trilogy_builder_write_uint8(builder, val & 0xff));
|
78
|
+
CHECKED(trilogy_builder_write_uint8(builder, (val >> 8) & 0xff));
|
79
|
+
|
80
|
+
return TRILOGY_OK;
|
81
|
+
}
|
82
|
+
|
83
|
+
int trilogy_builder_write_uint24(trilogy_builder_t *builder, uint32_t val)
|
84
|
+
{
|
85
|
+
CHECKED(trilogy_builder_write_uint8(builder, val & 0xff));
|
86
|
+
CHECKED(trilogy_builder_write_uint8(builder, (val >> 8) & 0xff));
|
87
|
+
CHECKED(trilogy_builder_write_uint8(builder, (val >> 16) & 0xff));
|
88
|
+
|
89
|
+
return TRILOGY_OK;
|
90
|
+
}
|
91
|
+
|
92
|
+
int trilogy_builder_write_uint32(trilogy_builder_t *builder, uint32_t val)
|
93
|
+
{
|
94
|
+
CHECKED(trilogy_builder_write_uint8(builder, val & 0xff));
|
95
|
+
CHECKED(trilogy_builder_write_uint8(builder, (val >> 8) & 0xff));
|
96
|
+
CHECKED(trilogy_builder_write_uint8(builder, (val >> 16) & 0xff));
|
97
|
+
CHECKED(trilogy_builder_write_uint8(builder, (val >> 24) & 0xff));
|
98
|
+
|
99
|
+
return TRILOGY_OK;
|
100
|
+
}
|
101
|
+
|
102
|
+
int trilogy_builder_write_uint64(trilogy_builder_t *builder, uint64_t val)
|
103
|
+
{
|
104
|
+
CHECKED(trilogy_builder_write_uint8(builder, val & 0xff));
|
105
|
+
CHECKED(trilogy_builder_write_uint8(builder, (val >> 8) & 0xff));
|
106
|
+
CHECKED(trilogy_builder_write_uint8(builder, (val >> 16) & 0xff));
|
107
|
+
CHECKED(trilogy_builder_write_uint8(builder, (val >> 24) & 0xff));
|
108
|
+
CHECKED(trilogy_builder_write_uint8(builder, (val >> 32) & 0xff));
|
109
|
+
CHECKED(trilogy_builder_write_uint8(builder, (val >> 40) & 0xff));
|
110
|
+
CHECKED(trilogy_builder_write_uint8(builder, (val >> 48) & 0xff));
|
111
|
+
CHECKED(trilogy_builder_write_uint8(builder, (val >> 56) & 0xff));
|
112
|
+
|
113
|
+
return TRILOGY_OK;
|
114
|
+
}
|
115
|
+
|
116
|
+
int trilogy_builder_write_float(trilogy_builder_t *builder, float val)
|
117
|
+
{
|
118
|
+
union {
|
119
|
+
float f;
|
120
|
+
uint32_t u;
|
121
|
+
} float_val;
|
122
|
+
|
123
|
+
float_val.f = val;
|
124
|
+
|
125
|
+
CHECKED(trilogy_builder_write_uint8(builder, float_val.u & 0xff));
|
126
|
+
CHECKED(trilogy_builder_write_uint8(builder, (float_val.u >> 8) & 0xff));
|
127
|
+
CHECKED(trilogy_builder_write_uint8(builder, (float_val.u >> 16) & 0xff));
|
128
|
+
CHECKED(trilogy_builder_write_uint8(builder, (float_val.u >> 24) & 0xff));
|
129
|
+
|
130
|
+
return TRILOGY_OK;
|
131
|
+
}
|
132
|
+
|
133
|
+
int trilogy_builder_write_double(trilogy_builder_t *builder, double val)
|
134
|
+
{
|
135
|
+
union {
|
136
|
+
double d;
|
137
|
+
uint64_t u;
|
138
|
+
} double_val;
|
139
|
+
|
140
|
+
double_val.d = val;
|
141
|
+
|
142
|
+
CHECKED(trilogy_builder_write_uint8(builder, double_val.u & 0xff));
|
143
|
+
CHECKED(trilogy_builder_write_uint8(builder, (double_val.u >> 8) & 0xff));
|
144
|
+
CHECKED(trilogy_builder_write_uint8(builder, (double_val.u >> 16) & 0xff));
|
145
|
+
CHECKED(trilogy_builder_write_uint8(builder, (double_val.u >> 24) & 0xff));
|
146
|
+
CHECKED(trilogy_builder_write_uint8(builder, (double_val.u >> 32) & 0xff));
|
147
|
+
CHECKED(trilogy_builder_write_uint8(builder, (double_val.u >> 40) & 0xff));
|
148
|
+
CHECKED(trilogy_builder_write_uint8(builder, (double_val.u >> 48) & 0xff));
|
149
|
+
CHECKED(trilogy_builder_write_uint8(builder, (double_val.u >> 56) & 0xff));
|
150
|
+
|
151
|
+
return TRILOGY_OK;
|
152
|
+
}
|
153
|
+
|
154
|
+
int trilogy_builder_write_lenenc(trilogy_builder_t *builder, uint64_t val)
|
155
|
+
{
|
156
|
+
if (val < 251) {
|
157
|
+
CHECKED(trilogy_builder_write_uint8(builder, (uint8_t)val));
|
158
|
+
} else if (val <= 0xffff) {
|
159
|
+
CHECKED(trilogy_builder_write_uint8(builder, 0xfc));
|
160
|
+
CHECKED(trilogy_builder_write_uint16(builder, (uint16_t)val));
|
161
|
+
} else if (val <= 0xffffff) {
|
162
|
+
CHECKED(trilogy_builder_write_uint8(builder, 0xfd));
|
163
|
+
CHECKED(trilogy_builder_write_uint24(builder, (uint32_t)val));
|
164
|
+
} else { // val <= 0xffffffffffffffff
|
165
|
+
CHECKED(trilogy_builder_write_uint8(builder, 0xfe));
|
166
|
+
CHECKED(trilogy_builder_write_uint64(builder, val));
|
167
|
+
}
|
168
|
+
|
169
|
+
return TRILOGY_OK;
|
170
|
+
}
|
171
|
+
|
172
|
+
int trilogy_builder_write_buffer(trilogy_builder_t *builder, const void *data, size_t len)
|
173
|
+
{
|
174
|
+
const char *ptr = data;
|
175
|
+
|
176
|
+
size_t fragment_remaining = TRILOGY_MAX_PACKET_LEN - builder->fragment_length;
|
177
|
+
|
178
|
+
// if this buffer write is not going to straddle a fragment boundary:
|
179
|
+
if (len < fragment_remaining) {
|
180
|
+
CHECKED(trilogy_buffer_expand(builder->buffer, len));
|
181
|
+
|
182
|
+
memcpy(builder->buffer->buff + builder->buffer->len, ptr, len);
|
183
|
+
|
184
|
+
builder->buffer->len += len;
|
185
|
+
builder->fragment_length += len;
|
186
|
+
|
187
|
+
return TRILOGY_OK;
|
188
|
+
}
|
189
|
+
|
190
|
+
// otherwise we're going to need to do this in multiple
|
191
|
+
while (len >= fragment_remaining) {
|
192
|
+
CHECKED(trilogy_buffer_expand(builder->buffer, fragment_remaining));
|
193
|
+
|
194
|
+
memcpy(builder->buffer->buff + builder->buffer->len, ptr, fragment_remaining);
|
195
|
+
|
196
|
+
builder->buffer->len += fragment_remaining;
|
197
|
+
builder->fragment_length += fragment_remaining;
|
198
|
+
|
199
|
+
ptr += fragment_remaining;
|
200
|
+
len -= fragment_remaining;
|
201
|
+
|
202
|
+
CHECKED(write_continuation_header(builder));
|
203
|
+
fragment_remaining = TRILOGY_MAX_PACKET_LEN;
|
204
|
+
}
|
205
|
+
|
206
|
+
if (len) {
|
207
|
+
CHECKED(trilogy_buffer_expand(builder->buffer, len));
|
208
|
+
|
209
|
+
memcpy(builder->buffer->buff + builder->buffer->len, ptr, len);
|
210
|
+
|
211
|
+
builder->buffer->len += len;
|
212
|
+
builder->fragment_length += len;
|
213
|
+
}
|
214
|
+
|
215
|
+
return TRILOGY_OK;
|
216
|
+
}
|
217
|
+
|
218
|
+
int trilogy_builder_write_lenenc_buffer(trilogy_builder_t *builder, const void *data, size_t len)
|
219
|
+
{
|
220
|
+
CHECKED(trilogy_builder_write_lenenc(builder, len));
|
221
|
+
|
222
|
+
CHECKED(trilogy_builder_write_buffer(builder, data, len));
|
223
|
+
|
224
|
+
return TRILOGY_OK;
|
225
|
+
}
|
226
|
+
|
227
|
+
int trilogy_builder_write_string(trilogy_builder_t *builder, const char *data)
|
228
|
+
{
|
229
|
+
CHECKED(trilogy_builder_write_buffer(builder, (void *)data, strlen(data)));
|
230
|
+
|
231
|
+
CHECKED(trilogy_builder_write_uint8(builder, 0));
|
232
|
+
|
233
|
+
return TRILOGY_OK;
|
234
|
+
}
|
235
|
+
|
236
|
+
#undef CHECKED
|