trilogy_w_prepared_statements 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +22 -0
  3. data/README.md +80 -0
  4. data/Rakefile +22 -0
  5. data/ext/trilogy-ruby/cast.c +277 -0
  6. data/ext/trilogy-ruby/cext.c +1048 -0
  7. data/ext/trilogy-ruby/extconf.rb +17 -0
  8. data/ext/trilogy-ruby/inc/trilogy/blocking.h +281 -0
  9. data/ext/trilogy-ruby/inc/trilogy/buffer.h +64 -0
  10. data/ext/trilogy-ruby/inc/trilogy/builder.h +165 -0
  11. data/ext/trilogy-ruby/inc/trilogy/charset.h +277 -0
  12. data/ext/trilogy-ruby/inc/trilogy/client.h +760 -0
  13. data/ext/trilogy-ruby/inc/trilogy/error.h +44 -0
  14. data/ext/trilogy-ruby/inc/trilogy/packet_parser.h +34 -0
  15. data/ext/trilogy-ruby/inc/trilogy/protocol.h +1014 -0
  16. data/ext/trilogy-ruby/inc/trilogy/reader.h +216 -0
  17. data/ext/trilogy-ruby/inc/trilogy/socket.h +111 -0
  18. data/ext/trilogy-ruby/inc/trilogy/vendor/curl_hostcheck.h +29 -0
  19. data/ext/trilogy-ruby/inc/trilogy/vendor/openssl_hostname_validation.h +51 -0
  20. data/ext/trilogy-ruby/inc/trilogy.h +8 -0
  21. data/ext/trilogy-ruby/src/blocking.c +358 -0
  22. data/ext/trilogy-ruby/src/buffer.c +60 -0
  23. data/ext/trilogy-ruby/src/builder.c +236 -0
  24. data/ext/trilogy-ruby/src/charset.c +212 -0
  25. data/ext/trilogy-ruby/src/client.c +903 -0
  26. data/ext/trilogy-ruby/src/error.c +17 -0
  27. data/ext/trilogy-ruby/src/packet_parser.c +140 -0
  28. data/ext/trilogy-ruby/src/protocol.c +1175 -0
  29. data/ext/trilogy-ruby/src/reader.c +282 -0
  30. data/ext/trilogy-ruby/src/socket.c +623 -0
  31. data/ext/trilogy-ruby/src/vendor/curl_hostcheck.c +206 -0
  32. data/ext/trilogy-ruby/src/vendor/openssl_hostname_validation.c +175 -0
  33. data/ext/trilogy-ruby/trilogy-ruby.h +37 -0
  34. data/lib/trilogy/version.rb +3 -0
  35. data/lib/trilogy.rb +61 -0
  36. data/trilogy.gemspec +27 -0
  37. 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