1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20 #include <errno.h>
21 #include <string.h>
22 #include <stdio.h>
23
24 #include <thrift/c_glib/thrift.h>
25 #include <thrift/c_glib/protocol/thrift_protocol.h>
26 #include <thrift/c_glib/protocol/thrift_binary_protocol.h>
27
G_DEFINE_TYPE(ThriftBinaryProtocol,thrift_binary_protocol,THRIFT_TYPE_PROTOCOL)28 G_DEFINE_TYPE(ThriftBinaryProtocol, thrift_binary_protocol, THRIFT_TYPE_PROTOCOL)
29
30 static guint64
31 thrift_bitwise_cast_guint64 (gdouble v)
32 {
33 union {
34 gdouble from;
35 guint64 to;
36 } u;
37 u.from = v;
38 return u.to;
39 }
40
41 static gdouble
thrift_bitwise_cast_gdouble(guint64 v)42 thrift_bitwise_cast_gdouble (guint64 v)
43 {
44 union {
45 guint64 from;
46 gdouble to;
47 } u;
48 u.from = v;
49 return u.to;
50 }
51
52 gint32
thrift_binary_protocol_write_message_begin(ThriftProtocol * protocol,const gchar * name,const ThriftMessageType message_type,const gint32 seqid,GError ** error)53 thrift_binary_protocol_write_message_begin (ThriftProtocol *protocol,
54 const gchar *name, const ThriftMessageType message_type,
55 const gint32 seqid, GError **error)
56 {
57 gint32 version = (THRIFT_BINARY_PROTOCOL_VERSION_1)
58 | ((gint32) message_type);
59 gint32 ret;
60 gint32 xfer = 0;
61
62 g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
63
64 if ((ret = thrift_protocol_write_i32 (protocol, version, error)) < 0)
65 {
66 return -1;
67 }
68 xfer += ret;
69 if ((ret = thrift_protocol_write_string (protocol, name, error)) < 0)
70 {
71 return -1;
72 }
73 xfer += ret;
74 if ((ret = thrift_protocol_write_i32 (protocol, seqid, error)) < 0)
75 {
76 return -1;
77 }
78 xfer += ret;
79 return xfer;
80 }
81
82 gint32
thrift_binary_protocol_write_message_end(ThriftProtocol * protocol,GError ** error)83 thrift_binary_protocol_write_message_end (ThriftProtocol *protocol,
84 GError **error)
85 {
86 /* satisfy -Wall */
87 THRIFT_UNUSED_VAR (protocol);
88 THRIFT_UNUSED_VAR (error);
89 return 0;
90 }
91
92 gint32
thrift_binary_protocol_write_struct_begin(ThriftProtocol * protocol,const gchar * name,GError ** error)93 thrift_binary_protocol_write_struct_begin (ThriftProtocol *protocol,
94 const gchar *name,
95 GError **error)
96 {
97 /* satisfy -Wall */
98 THRIFT_UNUSED_VAR (protocol);
99 THRIFT_UNUSED_VAR (name);
100 THRIFT_UNUSED_VAR (error);
101 return 0;
102 }
103
104 gint32
thrift_binary_protocol_write_struct_end(ThriftProtocol * protocol,GError ** error)105 thrift_binary_protocol_write_struct_end (ThriftProtocol *protocol,
106 GError **error)
107 {
108 /* satisfy -Wall */
109 THRIFT_UNUSED_VAR (protocol);
110 THRIFT_UNUSED_VAR (error);
111 return 0;
112 }
113
114 gint32
thrift_binary_protocol_write_field_begin(ThriftProtocol * protocol,const gchar * name,const ThriftType field_type,const gint16 field_id,GError ** error)115 thrift_binary_protocol_write_field_begin (ThriftProtocol *protocol,
116 const gchar *name,
117 const ThriftType field_type,
118 const gint16 field_id,
119 GError **error)
120 {
121 gint32 ret;
122 gint32 xfer = 0;
123
124 g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
125
126 THRIFT_UNUSED_VAR (name);
127
128 if ((ret = thrift_protocol_write_byte (protocol, (gint8) field_type,
129 error)) < 0)
130 {
131 return -1;
132 }
133 xfer += ret;
134 if ((ret = thrift_protocol_write_i16 (protocol, field_id, error)) < 0)
135 {
136 return -1;
137 }
138 xfer += ret;
139 return xfer;
140 }
141
142 gint32
thrift_binary_protocol_write_field_end(ThriftProtocol * protocol,GError ** error)143 thrift_binary_protocol_write_field_end (ThriftProtocol *protocol,
144 GError **error)
145 {
146 /* satisfy -Wall */
147 THRIFT_UNUSED_VAR (protocol);
148 THRIFT_UNUSED_VAR (error);
149 return 0;
150 }
151
152 gint32
thrift_binary_protocol_write_field_stop(ThriftProtocol * protocol,GError ** error)153 thrift_binary_protocol_write_field_stop (ThriftProtocol *protocol,
154 GError **error)
155 {
156 g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
157 return thrift_protocol_write_byte (protocol, (gint8) T_STOP, error);
158 }
159
160 gint32
thrift_binary_protocol_write_map_begin(ThriftProtocol * protocol,const ThriftType key_type,const ThriftType value_type,const guint32 size,GError ** error)161 thrift_binary_protocol_write_map_begin (ThriftProtocol *protocol,
162 const ThriftType key_type,
163 const ThriftType value_type,
164 const guint32 size,
165 GError **error)
166 {
167 gint32 ret;
168 gint32 xfer = 0;
169
170 g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
171
172 if ((ret = thrift_protocol_write_byte (protocol, (gint8) key_type,
173 error)) < 0)
174 {
175 return -1;
176 }
177 xfer += ret;
178 if ((ret = thrift_protocol_write_byte (protocol, (gint8) value_type,
179 error)) < 0)
180 {
181 return -1;
182 }
183 xfer += ret;
184 if ((ret = thrift_protocol_write_i32 (protocol, (gint32) size, error)) < 0)
185 {
186 return -1;
187 }
188 xfer += ret;
189 return xfer;
190 }
191
192 gint32
thrift_binary_protocol_write_map_end(ThriftProtocol * protocol,GError ** error)193 thrift_binary_protocol_write_map_end (ThriftProtocol *protocol,
194 GError **error)
195 {
196 THRIFT_UNUSED_VAR (protocol);
197 THRIFT_UNUSED_VAR (error);
198 return 0;
199 }
200
201 gint32
thrift_binary_protocol_write_list_begin(ThriftProtocol * protocol,const ThriftType element_type,const guint32 size,GError ** error)202 thrift_binary_protocol_write_list_begin (ThriftProtocol *protocol,
203 const ThriftType element_type,
204 const guint32 size,
205 GError **error)
206 {
207 gint32 ret;
208 gint32 xfer = 0;
209
210 g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
211
212 if ((ret = thrift_protocol_write_byte (protocol, (gint8) element_type,
213 error)) < 0)
214 {
215 return -1;
216 }
217 xfer += ret;
218
219 if ((ret = thrift_protocol_write_i32 (protocol, (gint32) size, error)) < 0)
220 {
221 return -1;
222 }
223 xfer += ret;
224
225 return xfer;
226 }
227
228 gint32
thrift_binary_protocol_write_list_end(ThriftProtocol * protocol,GError ** error)229 thrift_binary_protocol_write_list_end (ThriftProtocol *protocol,
230 GError **error)
231 {
232 THRIFT_UNUSED_VAR (protocol);
233 THRIFT_UNUSED_VAR (error);
234 return 0;
235 }
236
237 gint32
thrift_binary_protocol_write_set_begin(ThriftProtocol * protocol,const ThriftType element_type,const guint32 size,GError ** error)238 thrift_binary_protocol_write_set_begin (ThriftProtocol *protocol,
239 const ThriftType element_type,
240 const guint32 size,
241 GError **error)
242 {
243 g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
244
245 return thrift_protocol_write_list_begin (protocol, element_type,
246 size, error);
247 }
248
249 gint32
thrift_binary_protocol_write_set_end(ThriftProtocol * protocol,GError ** error)250 thrift_binary_protocol_write_set_end (ThriftProtocol *protocol, GError **error)
251 {
252 THRIFT_UNUSED_VAR (protocol);
253 THRIFT_UNUSED_VAR (error);
254 return 0;
255 }
256
257 gint32
thrift_binary_protocol_write_bool(ThriftProtocol * protocol,const gboolean value,GError ** error)258 thrift_binary_protocol_write_bool (ThriftProtocol *protocol,
259 const gboolean value, GError **error)
260 {
261 guint8 tmp;
262
263 g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
264
265 tmp = value ? 1 : 0;
266 return thrift_protocol_write_byte (protocol, tmp, error);
267 }
268
269 gint32
thrift_binary_protocol_write_byte(ThriftProtocol * protocol,const gint8 value,GError ** error)270 thrift_binary_protocol_write_byte (ThriftProtocol *protocol, const gint8 value,
271 GError **error)
272 {
273 g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
274
275 if (thrift_transport_write (protocol->transport,
276 (const gpointer) &value, 1, error))
277 {
278 return 1;
279 } else {
280 return -1;
281 }
282 }
283
284 gint32
thrift_binary_protocol_write_i16(ThriftProtocol * protocol,const gint16 value,GError ** error)285 thrift_binary_protocol_write_i16 (ThriftProtocol *protocol, const gint16 value,
286 GError **error)
287 {
288 gint16 net;
289
290 g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
291
292 net = g_htons (value);
293 if (thrift_transport_write (protocol->transport,
294 (const gpointer) &net, 2, error))
295 {
296 return 2;
297 } else {
298 return -1;
299 }
300 }
301
302 gint32
thrift_binary_protocol_write_i32(ThriftProtocol * protocol,const gint32 value,GError ** error)303 thrift_binary_protocol_write_i32 (ThriftProtocol *protocol, const gint32 value,
304 GError **error)
305 {
306 gint32 net;
307
308 g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
309
310 net = g_htonl (value);
311 if (thrift_transport_write (protocol->transport,
312 (const gpointer) &net, 4, error))
313 {
314 return 4;
315 } else {
316 return -1;
317 }
318 }
319
320 gint32
thrift_binary_protocol_write_i64(ThriftProtocol * protocol,const gint64 value,GError ** error)321 thrift_binary_protocol_write_i64 (ThriftProtocol *protocol, const gint64 value,
322 GError **error)
323 {
324 gint64 net;
325
326 g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
327
328 net = GUINT64_TO_BE (value);
329 if (thrift_transport_write (protocol->transport,
330 (const gpointer) &net, 8, error))
331 {
332 return 8;
333 } else {
334 return -1;
335 }
336 }
337
338 gint32
thrift_binary_protocol_write_double(ThriftProtocol * protocol,const gdouble value,GError ** error)339 thrift_binary_protocol_write_double (ThriftProtocol *protocol,
340 const gdouble value, GError **error)
341 {
342 guint64 bits;
343
344 g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
345
346 bits = GUINT64_FROM_BE (thrift_bitwise_cast_guint64 (value));
347 if (thrift_transport_write (protocol->transport,
348 (const gpointer) &bits, 8, error))
349 {
350 return 8;
351 } else {
352 return -1;
353 }
354 }
355
356 gint32
thrift_binary_protocol_write_string(ThriftProtocol * protocol,const gchar * str,GError ** error)357 thrift_binary_protocol_write_string (ThriftProtocol *protocol,
358 const gchar *str, GError **error)
359 {
360 guint32 len;
361
362 g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
363
364 len = str != NULL ? strlen (str) : 0;
365 /* write the string length + 1 which includes the null terminator */
366 return thrift_protocol_write_binary (protocol, (const gpointer) str,
367 len, error);
368 }
369
370 gint32
thrift_binary_protocol_write_binary(ThriftProtocol * protocol,const gpointer buf,const guint32 len,GError ** error)371 thrift_binary_protocol_write_binary (ThriftProtocol *protocol,
372 const gpointer buf,
373 const guint32 len, GError **error)
374 {
375 gint32 ret;
376 gint32 xfer = 0;
377
378 g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
379
380 if ((ret = thrift_protocol_write_i32 (protocol, len, error)) < 0)
381 {
382 return -1;
383 }
384 xfer += ret;
385
386 if (len > 0)
387 {
388 if (thrift_transport_write (protocol->transport,
389 (const gpointer) buf, len, error) == FALSE)
390 {
391 return -1;
392 }
393 xfer += len;
394 }
395
396 return xfer;
397 }
398
399 gint32
thrift_binary_protocol_read_message_begin(ThriftProtocol * protocol,gchar ** name,ThriftMessageType * message_type,gint32 * seqid,GError ** error)400 thrift_binary_protocol_read_message_begin (ThriftProtocol *protocol,
401 gchar **name,
402 ThriftMessageType *message_type,
403 gint32 *seqid, GError **error)
404 {
405 gint32 ret;
406 gint32 xfer = 0;
407 gint32 sz;
408
409 g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
410
411 if ((ret = thrift_protocol_read_i32 (protocol, &sz, error)) < 0)
412 {
413 return -1;
414 }
415 xfer += ret;
416
417 if (sz < 0)
418 {
419 /* check for version */
420 guint32 version = sz & THRIFT_BINARY_PROTOCOL_VERSION_MASK;
421 if (version != THRIFT_BINARY_PROTOCOL_VERSION_1)
422 {
423 g_set_error (error, THRIFT_PROTOCOL_ERROR,
424 THRIFT_PROTOCOL_ERROR_BAD_VERSION,
425 "expected version %d, got %d",
426 THRIFT_BINARY_PROTOCOL_VERSION_1, version);
427 return -1;
428 }
429
430 *message_type = (ThriftMessageType) (sz & 0x000000ff);
431
432 if ((ret = thrift_protocol_read_string (protocol, name, error)) < 0)
433 {
434 return -1;
435 }
436 xfer += ret;
437
438 if ((ret = thrift_protocol_read_i32 (protocol, seqid, error)) < 0)
439 {
440 return -1;
441 }
442 xfer += ret;
443 }
444 return xfer;
445 }
446
447 gint32
thrift_binary_protocol_read_message_end(ThriftProtocol * protocol,GError ** error)448 thrift_binary_protocol_read_message_end (ThriftProtocol *protocol,
449 GError **error)
450 {
451 THRIFT_UNUSED_VAR (protocol);
452 THRIFT_UNUSED_VAR (error);
453 return 0;
454 }
455
456 gint32
thrift_binary_protocol_read_struct_begin(ThriftProtocol * protocol,gchar ** name,GError ** error)457 thrift_binary_protocol_read_struct_begin (ThriftProtocol *protocol,
458 gchar **name,
459 GError **error)
460 {
461 THRIFT_UNUSED_VAR (protocol);
462 THRIFT_UNUSED_VAR (error);
463 *name = NULL;
464 return 0;
465 }
466
467 gint32
thrift_binary_protocol_read_struct_end(ThriftProtocol * protocol,GError ** error)468 thrift_binary_protocol_read_struct_end (ThriftProtocol *protocol,
469 GError **error)
470 {
471 THRIFT_UNUSED_VAR (protocol);
472 THRIFT_UNUSED_VAR (error);
473 return 0;
474 }
475
476 gint32
thrift_binary_protocol_read_field_begin(ThriftProtocol * protocol,gchar ** name,ThriftType * field_type,gint16 * field_id,GError ** error)477 thrift_binary_protocol_read_field_begin (ThriftProtocol *protocol,
478 gchar **name,
479 ThriftType *field_type,
480 gint16 *field_id,
481 GError **error)
482 {
483 gint32 ret;
484 gint32 xfer = 0;
485 gint8 type;
486
487 g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
488
489 THRIFT_UNUSED_VAR (name);
490
491 if ((ret = thrift_protocol_read_byte (protocol, &type, error)) < 0)
492 {
493 return -1;
494 }
495 xfer += ret;
496 *field_type = (ThriftType) type;
497 if (*field_type == T_STOP)
498 {
499 *field_id = 0;
500 return xfer;
501 }
502 if ((ret = thrift_protocol_read_i16 (protocol, field_id, error)) < 0)
503 {
504 return -1;
505 }
506 xfer += ret;
507 return xfer;
508 }
509
510 gint32
thrift_binary_protocol_read_field_end(ThriftProtocol * protocol,GError ** error)511 thrift_binary_protocol_read_field_end (ThriftProtocol *protocol,
512 GError **error)
513 {
514 THRIFT_UNUSED_VAR (protocol);
515 THRIFT_UNUSED_VAR (error);
516 return 0;
517 }
518
519 gint32
thrift_binary_protocol_read_map_begin(ThriftProtocol * protocol,ThriftType * key_type,ThriftType * value_type,guint32 * size,GError ** error)520 thrift_binary_protocol_read_map_begin (ThriftProtocol *protocol,
521 ThriftType *key_type,
522 ThriftType *value_type,
523 guint32 *size,
524 GError **error)
525 {
526 gint32 ret;
527 gint32 xfer = 0;
528 gint8 k, v;
529 gint32 sizei;
530
531 g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
532
533 ThriftProtocol *tp = THRIFT_PROTOCOL (protocol);
534 ThriftTransportClass *ttc = THRIFT_TRANSPORT_GET_CLASS (tp->transport);
535
536 if ((ret = thrift_protocol_read_byte (protocol, &k, error)) < 0)
537 {
538 return -1;
539 }
540 xfer += ret;
541 *key_type = (ThriftType) k;
542
543 if ((ret = thrift_protocol_read_byte (protocol, &v, error)) < 0)
544 {
545 return -1;
546 }
547 xfer += ret;
548 *value_type = (ThriftType) v;
549
550 if ((ret = thrift_protocol_read_i32 (protocol, &sizei, error)) <0)
551 {
552 return -1;
553 }
554 xfer += ret;
555
556 if (sizei < 0)
557 {
558 g_set_error (error, THRIFT_PROTOCOL_ERROR,
559 THRIFT_PROTOCOL_ERROR_NEGATIVE_SIZE,
560 "got negative size of %d", sizei);
561 return -1;
562 }
563
564 if(!ttc->checkReadBytesAvailable (THRIFT_TRANSPORT(tp->transport),
565 sizei * thrift_binary_protocol_get_min_serialized_size(protocol, k, error) +
566 sizei * thrift_binary_protocol_get_min_serialized_size(protocol, v, error),
567 error))
568 {
569 return -1;
570 }
571
572 *size = (guint32) sizei;
573 return xfer;
574 }
575
576 gint32
thrift_binary_protocol_read_map_end(ThriftProtocol * protocol,GError ** error)577 thrift_binary_protocol_read_map_end (ThriftProtocol *protocol,
578 GError **error)
579 {
580 THRIFT_UNUSED_VAR (protocol);
581 THRIFT_UNUSED_VAR (error);
582 return 0;
583 }
584
585 gint32
thrift_binary_protocol_read_list_begin(ThriftProtocol * protocol,ThriftType * element_type,guint32 * size,GError ** error)586 thrift_binary_protocol_read_list_begin (ThriftProtocol *protocol,
587 ThriftType *element_type,
588 guint32 *size, GError **error)
589 {
590 gint32 ret;
591 gint32 xfer = 0;
592 gint8 e;
593 gint32 sizei;
594
595 g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
596
597 ThriftProtocol *tp = THRIFT_PROTOCOL (protocol);
598 ThriftTransportClass *ttc = THRIFT_TRANSPORT_GET_CLASS (tp->transport);
599
600 if ((ret = thrift_protocol_read_byte (protocol, &e, error)) < 0)
601 {
602 return -1;
603 }
604 xfer += ret;
605 *element_type = (ThriftType) e;
606
607 if ((ret = thrift_protocol_read_i32 (protocol, &sizei, error)) < 0)
608 {
609 return -1;
610 }
611 xfer += ret;
612
613 if (sizei < 0)
614 {
615 g_set_error (error, THRIFT_PROTOCOL_ERROR,
616 THRIFT_PROTOCOL_ERROR_NEGATIVE_SIZE,
617 "got negative size of %d", sizei);
618 return -1;
619 }
620
621 if(!ttc->checkReadBytesAvailable (THRIFT_TRANSPORT(tp->transport),
622 (sizei * thrift_binary_protocol_get_min_serialized_size(protocol, e, error)),
623 error))
624 {
625 return -1;
626 }
627
628 *size = (guint32) sizei;
629 return xfer;
630 }
631
632 gint32
thrift_binary_protocol_read_list_end(ThriftProtocol * protocol,GError ** error)633 thrift_binary_protocol_read_list_end (ThriftProtocol *protocol,
634 GError **error)
635 {
636 THRIFT_UNUSED_VAR (protocol);
637 THRIFT_UNUSED_VAR (error);
638 return 0;
639 }
640
641 gint32
thrift_binary_protocol_read_set_begin(ThriftProtocol * protocol,ThriftType * element_type,guint32 * size,GError ** error)642 thrift_binary_protocol_read_set_begin (ThriftProtocol *protocol,
643 ThriftType *element_type,
644 guint32 *size, GError **error)
645 {
646 g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
647
648 return thrift_protocol_read_list_begin (protocol, element_type, size, error);
649 }
650
651 gint32
thrift_binary_protocol_read_set_end(ThriftProtocol * protocol,GError ** error)652 thrift_binary_protocol_read_set_end (ThriftProtocol *protocol,
653 GError **error)
654 {
655 THRIFT_UNUSED_VAR (protocol);
656 THRIFT_UNUSED_VAR (error);
657 return 0;
658 }
659
660 gint32
thrift_binary_protocol_read_bool(ThriftProtocol * protocol,gboolean * value,GError ** error)661 thrift_binary_protocol_read_bool (ThriftProtocol *protocol, gboolean *value,
662 GError **error)
663 {
664 gint32 ret;
665 gpointer b[1];
666
667 g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
668
669 if ((ret =
670 thrift_transport_read_all (protocol->transport,
671 b, 1, error)) < 0)
672 {
673 return -1;
674 }
675 *value = *(gint8 *) b != 0;
676 return ret;
677 }
678
679 gint32
thrift_binary_protocol_read_byte(ThriftProtocol * protocol,gint8 * value,GError ** error)680 thrift_binary_protocol_read_byte (ThriftProtocol *protocol, gint8 *value,
681 GError **error)
682 {
683 gint32 ret;
684 gpointer b[1];
685
686 g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
687
688 if ((ret =
689 thrift_transport_read_all (protocol->transport,
690 b, 1, error)) < 0)
691 {
692 return -1;
693 }
694 *value = *(gint8 *) b;
695 return ret;
696 }
697
698 gint32
thrift_binary_protocol_read_i16(ThriftProtocol * protocol,gint16 * value,GError ** error)699 thrift_binary_protocol_read_i16 (ThriftProtocol *protocol, gint16 *value,
700 GError **error)
701 {
702 gint32 ret;
703 union
704 {
705 gint8 byte_array[2];
706 gint16 int16;
707 } b;
708
709 g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
710
711 if ((ret =
712 thrift_transport_read_all (protocol->transport,
713 b.byte_array, 2, error)) < 0)
714 {
715 return -1;
716 }
717 *value = g_ntohs (b.int16);
718 return ret;
719 }
720
721 gint32
thrift_binary_protocol_read_i32(ThriftProtocol * protocol,gint32 * value,GError ** error)722 thrift_binary_protocol_read_i32 (ThriftProtocol *protocol, gint32 *value,
723 GError **error)
724 {
725 gint32 ret;
726 union
727 {
728 gint8 byte_array[4];
729 gint32 int32;
730 } b;
731
732 g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
733
734 if ((ret =
735 thrift_transport_read_all (protocol->transport,
736 b.byte_array, 4, error)) < 0)
737 {
738 return -1;
739 }
740 *value = g_ntohl (b.int32);
741 return ret;
742 }
743
744 gint32
thrift_binary_protocol_read_i64(ThriftProtocol * protocol,gint64 * value,GError ** error)745 thrift_binary_protocol_read_i64 (ThriftProtocol *protocol, gint64 *value,
746 GError **error)
747 {
748 gint32 ret;
749 union
750 {
751 gint8 byte_array[8];
752 gint64 int64;
753 } b;
754
755 g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
756
757 if ((ret =
758 thrift_transport_read_all (protocol->transport,
759 b.byte_array, 8, error)) < 0)
760 {
761 return -1;
762 }
763 *value = GUINT64_FROM_BE (b.int64);
764 return ret;
765 }
766
767 gint32
thrift_binary_protocol_read_double(ThriftProtocol * protocol,gdouble * value,GError ** error)768 thrift_binary_protocol_read_double (ThriftProtocol *protocol,
769 gdouble *value, GError **error)
770 {
771 gint32 ret;
772 union
773 {
774 gint8 byte_array[8];
775 guint64 uint64;
776 } b;
777
778 g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
779
780 if ((ret =
781 thrift_transport_read_all (protocol->transport,
782 b.byte_array, 8, error)) < 0)
783 {
784 return -1;
785 }
786 *value = thrift_bitwise_cast_gdouble (GUINT64_FROM_BE (b.uint64));
787 return ret;
788 }
789
790 gint32
thrift_binary_protocol_read_string(ThriftProtocol * protocol,gchar ** str,GError ** error)791 thrift_binary_protocol_read_string (ThriftProtocol *protocol,
792 gchar **str, GError **error)
793 {
794 guint32 len;
795 gint32 ret;
796 gint32 xfer = 0;
797 gint32 read_len = 0;
798
799 g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
800
801 /* read the length into read_len */
802 if ((ret =
803 thrift_protocol_read_i32 (protocol, &read_len, error)) < 0)
804 {
805 return -1;
806 }
807 xfer += ret;
808
809 if (read_len < 0) {
810 g_set_error (error, THRIFT_PROTOCOL_ERROR,
811 THRIFT_PROTOCOL_ERROR_NEGATIVE_SIZE,
812 "got negative size of %d", read_len);
813 *str = NULL;
814 return -1;
815 }
816
817 /* allocate the memory for the string */
818 len = (guint32) read_len + 1; /* space for null terminator */
819 *str = g_new0 (gchar, len);
820 if (read_len > 0) {
821 if ((ret =
822 thrift_transport_read_all (protocol->transport,
823 *str, read_len, error)) < 0)
824 {
825 g_free (*str);
826 *str = NULL;
827 len = 0;
828 return -1;
829 }
830 xfer += ret;
831 } else {
832 **str = 0;
833 }
834
835 return xfer;
836 }
837
838 gint32
thrift_binary_protocol_read_binary(ThriftProtocol * protocol,gpointer * buf,guint32 * len,GError ** error)839 thrift_binary_protocol_read_binary (ThriftProtocol *protocol,
840 gpointer *buf, guint32 *len,
841 GError **error)
842 {
843 gint32 ret;
844 gint32 xfer = 0;
845 gint32 read_len = 0;
846
847 g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
848
849 /* read the length into read_len */
850 if ((ret =
851 thrift_protocol_read_i32 (protocol, &read_len, error)) < 0)
852 {
853 return -1;
854 }
855 xfer += ret;
856
857 if (read_len > 0)
858 {
859 /* allocate the memory as an array of unsigned char for binary data */
860 *len = (guint32) read_len;
861 *buf = g_new (guchar, *len);
862 if ((ret =
863 thrift_transport_read_all (protocol->transport,
864 *buf, *len, error)) < 0)
865 {
866 g_free (*buf);
867 *buf = NULL;
868 *len = 0;
869 return -1;
870 }
871 xfer += ret;
872 } else {
873 *len = (guint32) read_len;
874 *buf = NULL;
875 }
876
877 return xfer;
878 }
879
880 gint
thrift_binary_protocol_get_min_serialized_size(ThriftProtocol * protocol,ThriftType type,GError ** error)881 thrift_binary_protocol_get_min_serialized_size(ThriftProtocol *protocol, ThriftType type, GError **error)
882 {
883 THRIFT_UNUSED_VAR (protocol);
884
885 switch (type)
886 {
887 case T_STOP:
888 return 0;
889 case T_VOID:
890 return 0;
891 case T_BOOL:
892 return sizeof(gint8);
893 case T_BYTE:
894 return sizeof(gint8);
895 case T_DOUBLE:
896 return sizeof(double);
897 case T_I16:
898 return sizeof(short);
899 case T_I32:
900 return sizeof(int);
901 case T_I64:
902 return sizeof(long);
903 case T_STRING:
904 return sizeof(int);
905 case T_STRUCT:
906 return 0;
907 case T_MAP:
908 return sizeof(int);
909 case T_SET:
910 return sizeof(int);
911 case T_LIST:
912 return sizeof(int);
913 default:
914 g_set_error(error,
915 THRIFT_PROTOCOL_ERROR,
916 THRIFT_PROTOCOL_ERROR_INVALID_DATA,
917 "unrecognized type");
918 return -1;
919 }
920 }
921
922 static void
thrift_binary_protocol_init(ThriftBinaryProtocol * protocol)923 thrift_binary_protocol_init (ThriftBinaryProtocol *protocol)
924 {
925 THRIFT_UNUSED_VAR (protocol);
926 }
927
928 /* initialize the class */
929 static void
thrift_binary_protocol_class_init(ThriftBinaryProtocolClass * klass)930 thrift_binary_protocol_class_init (ThriftBinaryProtocolClass *klass)
931 {
932 ThriftProtocolClass *cls = THRIFT_PROTOCOL_CLASS (klass);
933
934 cls->write_message_begin = thrift_binary_protocol_write_message_begin;
935 cls->write_message_end = thrift_binary_protocol_write_message_end;
936 cls->write_struct_begin = thrift_binary_protocol_write_struct_begin;
937 cls->write_struct_end = thrift_binary_protocol_write_struct_end;
938 cls->write_field_begin = thrift_binary_protocol_write_field_begin;
939 cls->write_field_end = thrift_binary_protocol_write_field_end;
940 cls->write_field_stop = thrift_binary_protocol_write_field_stop;
941 cls->write_map_begin = thrift_binary_protocol_write_map_begin;
942 cls->write_map_end = thrift_binary_protocol_write_map_end;
943 cls->write_list_begin = thrift_binary_protocol_write_list_begin;
944 cls->write_list_end = thrift_binary_protocol_write_list_end;
945 cls->write_set_begin = thrift_binary_protocol_write_set_begin;
946 cls->write_set_end = thrift_binary_protocol_write_set_end;
947 cls->write_bool = thrift_binary_protocol_write_bool;
948 cls->write_byte = thrift_binary_protocol_write_byte;
949 cls->write_i16 = thrift_binary_protocol_write_i16;
950 cls->write_i32 = thrift_binary_protocol_write_i32;
951 cls->write_i64 = thrift_binary_protocol_write_i64;
952 cls->write_double = thrift_binary_protocol_write_double;
953 cls->write_string = thrift_binary_protocol_write_string;
954 cls->write_binary = thrift_binary_protocol_write_binary;
955 cls->read_message_begin = thrift_binary_protocol_read_message_begin;
956 cls->read_message_end = thrift_binary_protocol_read_message_end;
957 cls->read_struct_begin = thrift_binary_protocol_read_struct_begin;
958 cls->read_struct_end = thrift_binary_protocol_read_struct_end;
959 cls->read_field_begin = thrift_binary_protocol_read_field_begin;
960 cls->read_field_end = thrift_binary_protocol_read_field_end;
961 cls->read_map_begin = thrift_binary_protocol_read_map_begin;
962 cls->read_map_end = thrift_binary_protocol_read_map_end;
963 cls->read_list_begin = thrift_binary_protocol_read_list_begin;
964 cls->read_list_end = thrift_binary_protocol_read_list_end;
965 cls->read_set_begin = thrift_binary_protocol_read_set_begin;
966 cls->read_set_end = thrift_binary_protocol_read_set_end;
967 cls->read_bool = thrift_binary_protocol_read_bool;
968 cls->read_byte = thrift_binary_protocol_read_byte;
969 cls->read_i16 = thrift_binary_protocol_read_i16;
970 cls->read_i32 = thrift_binary_protocol_read_i32;
971 cls->read_i64 = thrift_binary_protocol_read_i64;
972 cls->read_double = thrift_binary_protocol_read_double;
973 cls->read_string = thrift_binary_protocol_read_string;
974 cls->read_binary = thrift_binary_protocol_read_binary;
975 cls->get_min_serialized_size = thrift_binary_protocol_get_min_serialized_size;
976 }
977