]> git.proxmox.com Git - ceph.git/blame - ceph/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/protocol/thrift_compact_protocol.c
buildsys: switch source download to quincy
[ceph.git] / ceph / src / jaegertracing / thrift / lib / c_glib / src / thrift / c_glib / protocol / thrift_compact_protocol.c
CommitLineData
f67539c2
TL
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 <string.h>
21#include <stdio.h>
22
23#include <thrift/c_glib/thrift.h>
24#include <thrift/c_glib/protocol/thrift_protocol.h>
25#include <thrift/c_glib/protocol/thrift_compact_protocol.h>
26
27#include <thrift/config.h>
28
29/*
30 * *_to_zigzag depend on the fact that the right shift
31 * operator on a signed integer is an arithmetic (sign-extending) shift.
32 * If this is not the case, the current implementation will not work.
33 */
34#if !defined(SIGNED_RIGHT_SHIFT_IS) || !defined(ARITHMETIC_RIGHT_SHIFT)
35# error "Unable to determine the behavior of a signed right shift"
36#endif
37#if SIGNED_RIGHT_SHIFT_IS != ARITHMETIC_RIGHT_SHIFT
38# error "thrift_compact_protocol only works if signed right shift is arithmetic"
39#endif
40
41/* object properties */
42enum _ThriftCompactProtocolProperties
43{
44 PROP_0,
45 PROP_THRIFT_COMPACT_PROTOCOL_STRING_LIMIT,
46 PROP_THRIFT_COMPACT_PROTOCOL_CONTAINER_LIMIT
47};
48
49G_DEFINE_TYPE (ThriftCompactProtocol, thrift_compact_protocol,
50 THRIFT_TYPE_PROTOCOL)
51
52static const gint8 PROTOCOL_ID = (gint8)0x82u;
53static const gint8 VERSION_N = 1;
54static const gint8 VERSION_MASK = 0x1f; /* 0001 1111 */
55static const gint8 TYPE_MASK = (gint8)0xe0u; /* 1110 0000 */
56static const gint8 TYPE_BITS = 0x07; /* 0000 0111 */
57static const gint32 TYPE_SHIFT_AMOUNT = 5;
58
59enum Types {
60 CT_STOP = 0x00,
61 CT_BOOLEAN_TRUE = 0x01,
62 CT_BOOLEAN_FALSE = 0x02,
63 CT_BYTE = 0x03,
64 CT_I16 = 0x04,
65 CT_I32 = 0x05,
66 CT_I64 = 0x06,
67 CT_DOUBLE = 0x07,
68 CT_BINARY = 0x08,
69 CT_LIST = 0x09,
70 CT_SET = 0x0A,
71 CT_MAP = 0x0B,
72 CT_STRUCT = 0x0C
73};
74
75static const gint8 TTypeToCType[16] = {
76 CT_STOP, /* T_STOP */
77 0, /* unused */
78 CT_BOOLEAN_TRUE, /* T_BOOL */
79 CT_BYTE, /* T_BYTE */
80 CT_DOUBLE, /* T_DOUBLE */
81 0, /* unused */
82 CT_I16, /* T_I16 */
83 0, /* unused */
84 CT_I32, /* T_I32 */
85 0, /* unused */
86 CT_I64, /* T_I64 */
87 CT_BINARY, /* T_STRING */
88 CT_STRUCT, /* T_STRUCT */
89 CT_MAP, /* T_MAP */
90 CT_SET, /* T_SET */
91 CT_LIST, /* T_LIST */
92};
93
94static guint64
95thrift_bitwise_cast_guint64 (const gdouble v)
96{
97 union {
98 gdouble from;
99 guint64 to;
100 } u;
101 u.from = v;
102 return u.to;
103}
104
105static gdouble
106thrift_bitwise_cast_gdouble (const guint64 v)
107{
108 union {
109 guint64 from;
110 gdouble to;
111 } u;
112 u.from = v;
113 return u.to;
114}
115
116/**
117 * Convert l into a zigzag long. This allows negative numbers to be
118 * represented compactly as a varint.
119 */
120static guint64
121i64_to_zigzag (const gint64 l)
122{
123 return (((guint64)l) << 1) ^ (l >> 63);
124}
125
126/**
127 * Convert n into a zigzag int. This allows negative numbers to be
128 * represented compactly as a varint.
129 */
130static guint32
131i32_to_zigzag (const gint32 n)
132{
133 return (((guint32)n) << 1) ^ (n >> 31);
134}
135
136/**
137 * Convert from zigzag int to int.
138 */
139static gint32
140zigzag_to_i32 (guint32 n)
141{
142 return (n >> 1) ^ (guint32) (-(gint32) (n & 1));
143}
144
145/**
146 * Convert from zigzag long to long.
147 */
148static gint64
149zigzag_to_i64 (guint64 n)
150{
151 return (n >> 1) ^ (guint64) (-(gint64) (n & 1));
152}
153
154ThriftType thrift_compact_protocol_get_ttype (ThriftCompactProtocol *protocol,
155 const gint8 type, GError **error)
156{
157 THRIFT_UNUSED_VAR (protocol);
158
159 switch (type) {
160 case T_STOP:
161 return T_STOP;
162 case CT_BOOLEAN_FALSE:
163 case CT_BOOLEAN_TRUE:
164 return T_BOOL;
165 case CT_BYTE:
166 return T_BYTE;
167 case CT_I16:
168 return T_I16;
169 case CT_I32:
170 return T_I32;
171 case CT_I64:
172 return T_I64;
173 case CT_DOUBLE:
174 return T_DOUBLE;
175 case CT_BINARY:
176 return T_STRING;
177 case CT_LIST:
178 return T_LIST;
179 case CT_SET:
180 return T_SET;
181 case CT_MAP:
182 return T_MAP;
183 case CT_STRUCT:
184 return T_STRUCT;
185 default:
186 g_set_error (error, THRIFT_PROTOCOL_ERROR,
187 THRIFT_PROTOCOL_ERROR_INVALID_DATA,
188 "unrecognized type");
189 return -1;
190 }
191}
192
193/**
194 * Write an i32 as a varint. Results in 1-5 bytes on the wire.
195 */
196gint32
197thrift_compact_protocol_write_varint32 (ThriftCompactProtocol *protocol,
198 const guint32 n,
199 GError **error)
200{
201 guint8 buf[5];
202 gint32 xfer;
203 guint32 m;
204
205 THRIFT_UNUSED_VAR (error);
206
207 xfer = 0;
208 m = n;
209
210 while (TRUE) {
211 if ((m & ~0x7F) == 0) {
212 buf[xfer++] = (gint8)m;
213 break;
214 } else {
215 buf[xfer++] = (gint8)((m & 0x7F) | 0x80);
216 m >>= 7;
217 }
218 }
219
220 if (thrift_transport_write (THRIFT_PROTOCOL (protocol)->transport,
221 (const gpointer) buf, xfer, error)) {
222 return xfer;
223 } else {
224 return -1;
225 }
226}
227
228/**
229 * Write an i64 as a varint. Results in 1-10 bytes on the wire.
230 */
231gint32
232thrift_compact_protocol_write_varint64 (ThriftCompactProtocol *protocol,
233 const guint64 n,
234 GError **error)
235{
236 guint8 buf[10];
237 gint32 xfer;
238 guint64 m;
239
240 THRIFT_UNUSED_VAR (error);
241
242 xfer = 0;
243 m = n;
244
245 while (TRUE) {
246 if ((m & ~0x7FL) == 0) {
247 buf[xfer++] = (gint8)m;
248 break;
249 } else {
250 buf[xfer++] = (gint8)((m & 0x7F) | 0x80);
251 m >>= 7;
252 }
253 }
254
255 if (thrift_transport_write (THRIFT_PROTOCOL (protocol)->transport,
256 (const gpointer) buf, xfer, error)) {
257 return xfer;
258 } else {
259 return -1;
260 }
261}
262
263/**
264 * Read an i64 from the wire as a proper varint. The MSB of each byte is set
265 * if there is another byte to follow. This can read up to 10 bytes.
266 */
267gint32
268thrift_compact_protocol_read_varint64 (ThriftCompactProtocol *protocol,
269 gint64 *i64,
270 GError **error)
271{
272 ThriftProtocol *tp;
273 gint32 ret;
274 gint32 xfer;
275 guint64 val;
276 gint shift;
277 guint8 byte;
278
279 tp = THRIFT_PROTOCOL (protocol);
280 xfer = 0;
281 val = 0;
282 shift = 0;
283 byte = 0;
284
285 while (TRUE) {
286 if ((ret = thrift_transport_read_all (tp->transport,
287 (gpointer) &byte, 1, error)) < 0) {
288 return -1;
289 }
290 ++xfer;
291 val |= (guint64)(byte & 0x7f) << shift;
292 shift += 7;
293 if (!(byte & 0x80)) {
294 *i64 = (gint64) val;
295 return xfer;
296 }
297 if (G_UNLIKELY (xfer == 10)) { /* 7 * 9 < 64 < 7 * 10 */
298 g_set_error (error, THRIFT_PROTOCOL_ERROR,
299 THRIFT_PROTOCOL_ERROR_INVALID_DATA,
300 "variable-length int over 10 bytes");
301 return -1;
302 }
303 }
304}
305
306/**
307 * Read an i32 from the wire as a varint. The MSB of each byte is set
308 * if there is another byte to follow. This can read up to 5 bytes.
309 */
310gint32
311thrift_compact_protocol_read_varint32 (ThriftCompactProtocol *protocol,
312 gint32 *i32,
313 GError **error)
314{
315 gint64 val;
316 gint32 ret;
317 gint32 xfer;
318
319 xfer = 0;
320
321 if ((ret = thrift_compact_protocol_read_varint64 (protocol, &val,
322 error)) < 0) {
323 return -1;
324 }
325 xfer += ret;
326
327 *i32 = (gint32)val;
328
329 return xfer;
330}
331
332gint32
333thrift_compact_protocol_write_field_begin_internal (ThriftCompactProtocol
334 *protocol,
335 const gchar *name,
336 const ThriftType field_type,
337 const gint16 field_id,
338 const gint8 type_override,
339 GError **error)
340{
341 gint32 ret;
342 gint32 xfer;
343 gint8 type_to_write;
344
345 THRIFT_UNUSED_VAR (name);
346
347 xfer = 0;
348
349 /* if there's a type override, use that. */
350 type_to_write
351 = (type_override == -1 ? TTypeToCType[field_type] : type_override);
352
353 /* check if we can use delta encoding for the field id */
354 if (field_id > protocol->_last_field_id
355 && field_id - protocol->_last_field_id <= 15) {
356 /* write them together */
357 if ((ret = thrift_protocol_write_byte (THRIFT_PROTOCOL (protocol),
358 (gint8) ((field_id
359 - protocol->_last_field_id)
360 << 4 | type_to_write),
361 error)) < 0) {
362 return -1;
363 }
364 xfer += ret;
365 } else {
366 /* write them separate */
367 if ((ret = thrift_protocol_write_byte (THRIFT_PROTOCOL (protocol),
368 type_to_write, error)) < 0) {
369 return -1;
370 }
371 xfer += ret;
372
373 if ((ret = thrift_protocol_write_i16 (THRIFT_PROTOCOL (protocol), field_id,
374 error)) < 0) {
375 return -1;
376 }
377 xfer += ret;
378 }
379
380 protocol->_last_field_id = field_id;
381 return xfer;
382}
383
384/**
385 * Method for writing the start of lists and sets. List and sets on
386 * the wire differ only by the type indicator.
387 */
388gint32
389thrift_compact_protocol_write_collection_begin (ThriftCompactProtocol *protocol,
390 const ThriftType elem_type,
391 guint32 size, GError **error)
392{
393 gint32 ret;
394 gint32 xfer;
395
396 xfer = 0;
397
398 if (size <= 14) {
399 if ((ret = thrift_protocol_write_byte (THRIFT_PROTOCOL (protocol),
400 (gint8) (size << 4
401 | TTypeToCType[elem_type]),
402 error)) < 0) {
403 return -1;
404 }
405 xfer += ret;
406 } else {
407 if ((ret = thrift_protocol_write_byte (THRIFT_PROTOCOL (protocol),
408 (gint8) (0xf0
409 | TTypeToCType[elem_type]),
410 error)) < 0) {
411 return -1;
412 }
413 xfer += ret;
414
415 if ((ret = thrift_compact_protocol_write_varint32 (protocol,
416 (guint32) size,
417 error)) < 0) {
418 return -1;
419 }
420 xfer += ret;
421 }
422
423 return xfer;
424}
425
426/*
427 * public methods
428 */
429
430gint32
431thrift_compact_protocol_write_message_begin (ThriftProtocol *protocol,
432 const gchar *name,
433 const ThriftMessageType
434 message_type,
435 const gint32 seqid, GError **error)
436{
437 gint8 version;
438 gint32 ret;
439 gint32 xfer;
440
441 ThriftCompactProtocol *cp;
442
443 g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
444
445 cp = THRIFT_COMPACT_PROTOCOL (protocol);
446
447 version = (VERSION_N & VERSION_MASK)
448 | (((gint32) message_type << TYPE_SHIFT_AMOUNT) & TYPE_MASK);
449 xfer = 0;
450
451 if ((ret = thrift_protocol_write_byte (protocol, PROTOCOL_ID, error)) < 0) {
452 return -1;
453 }
454 xfer += ret;
455
456 if ((ret = thrift_protocol_write_byte (protocol, version, error)) < 0) {
457 return -1;
458 }
459 xfer += ret;
460
461 if ((ret = thrift_compact_protocol_write_varint32 (cp,
462 (guint32) seqid,
463 error)) < 0) {
464 return -1;
465 }
466 xfer += ret;
467
468 if ((ret = thrift_protocol_write_string (protocol, name, error)) < 0) {
469 return -1;
470 }
471 xfer += ret;
472
473 return xfer;
474}
475
476gint32
477thrift_compact_protocol_write_message_end (ThriftProtocol *protocol,
478 GError **error)
479{
480 /* satisfy -Wall */
481 THRIFT_UNUSED_VAR (protocol);
482 THRIFT_UNUSED_VAR (error);
483 return 0;
484}
485
486gint32
487thrift_compact_protocol_write_struct_begin (ThriftProtocol *protocol,
488 const gchar *name,
489 GError **error)
490{
491 ThriftCompactProtocol *cp;
492 GQueue *q;
493
494 /* satisfy -Wall */
495 THRIFT_UNUSED_VAR (name);
496 THRIFT_UNUSED_VAR (error);
497
498 g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
499
500 cp = THRIFT_COMPACT_PROTOCOL (protocol);
501 q = &(cp->_last_field);
502
503 g_queue_push_tail (q, GINT_TO_POINTER ((gint) cp->_last_field_id));
504 cp->_last_field_id = 0;
505 return 0;
506}
507
508gint32
509thrift_compact_protocol_write_struct_end (ThriftProtocol *protocol,
510 GError **error)
511{
512 ThriftCompactProtocol *cp;
513 GQueue *q;
514
515 /* satisfy -Wall */
516 THRIFT_UNUSED_VAR (error);
517
518 cp = THRIFT_COMPACT_PROTOCOL (protocol);
519 q = &(cp->_last_field);
520
521 g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
522
523 cp->_last_field_id = (gint16) GPOINTER_TO_INT (g_queue_pop_tail (q));
524 return 0;
525}
526
527gint32
528thrift_compact_protocol_write_field_begin (ThriftProtocol *protocol,
529 const gchar *name,
530 const ThriftType field_type,
531 const gint16 field_id,
532 GError **error)
533{
534 ThriftCompactProtocol *cp;
535
536 g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
537
538 cp = THRIFT_COMPACT_PROTOCOL (protocol);
539
540 if (field_type == T_BOOL) {
541 cp->_bool_field_name = name;
542 cp->_bool_field_type = field_type;
543 cp->_bool_field_id = field_id;
544 return 0;
545 } else {
546 return thrift_compact_protocol_write_field_begin_internal (cp, name,
547 field_type,
548 field_id, -1,
549 error);
550 }
551}
552
553gint32
554thrift_compact_protocol_write_field_end (ThriftProtocol *protocol,
555 GError **error)
556{
557 /* satisfy -Wall */
558 THRIFT_UNUSED_VAR (protocol);
559 THRIFT_UNUSED_VAR (error);
560 return 0;
561}
562
563gint32
564thrift_compact_protocol_write_field_stop (ThriftProtocol *protocol,
565 GError **error)
566{
567 g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
568 return thrift_protocol_write_byte (protocol, (gint8) T_STOP, error);
569}
570
571gint32
572thrift_compact_protocol_write_map_begin (ThriftProtocol *protocol,
573 const ThriftType key_type,
574 const ThriftType value_type,
575 const guint32 size,
576 GError **error)
577{
578 gint32 ret;
579 gint32 xfer;
580
581 ThriftCompactProtocol *cp;
582
583 g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
584
585 cp = THRIFT_COMPACT_PROTOCOL (protocol);
586
587 xfer = 0;
588
589 if ((ret = thrift_compact_protocol_write_varint32 (cp, (guint32) size,
590 error)) < 0) {
591 return -1;
592 }
593 xfer += ret;
594
595 if (size > 0) {
596 if ((ret = thrift_protocol_write_byte (protocol,
597 (gint8) (TTypeToCType[key_type] << 4
598 | TTypeToCType[value_type]),
599 error)) < 0) {
600 return -1;
601 }
602 xfer += ret;
603 }
604
605 return xfer;
606}
607
608gint32
609thrift_compact_protocol_write_map_end (ThriftProtocol *protocol,
610 GError **error)
611{
612 THRIFT_UNUSED_VAR (protocol);
613 THRIFT_UNUSED_VAR (error);
614 return 0;
615}
616
617gint32
618thrift_compact_protocol_write_list_begin (ThriftProtocol *protocol,
619 const ThriftType element_type,
620 const guint32 size,
621 GError **error)
622{
623 ThriftCompactProtocol *cp;
624
625 g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
626
627 cp = THRIFT_COMPACT_PROTOCOL (protocol);
628
629 return thrift_compact_protocol_write_collection_begin (cp, element_type,
630 size, error);
631}
632
633gint32
634thrift_compact_protocol_write_list_end (ThriftProtocol *protocol,
635 GError **error)
636{
637 THRIFT_UNUSED_VAR (protocol);
638 THRIFT_UNUSED_VAR (error);
639 return 0;
640}
641
642gint32
643thrift_compact_protocol_write_set_begin (ThriftProtocol *protocol,
644 const ThriftType element_type,
645 const guint32 size,
646 GError **error)
647{
648 ThriftCompactProtocol *cp;
649
650 g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
651
652 cp = THRIFT_COMPACT_PROTOCOL (protocol);
653
654 return thrift_compact_protocol_write_collection_begin (cp, element_type,
655 size, error);
656}
657
658gint32
659thrift_compact_protocol_write_set_end (ThriftProtocol *protocol, GError **error)
660{
661 THRIFT_UNUSED_VAR (protocol);
662 THRIFT_UNUSED_VAR (error);
663 return 0;
664}
665
666gint32
667thrift_compact_protocol_write_bool (ThriftProtocol *protocol,
668 const gboolean value, GError **error)
669{
670 ThriftCompactProtocol *cp;
671
672 gint32 ret;
673 gint32 xfer;
674
675 g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
676
677 cp = THRIFT_COMPACT_PROTOCOL (protocol);
678
679 xfer = 0;
680
681 if (cp->_bool_field_name != NULL) {
682 /* we haven't written the field header yet */
683 if ((ret = thrift_compact_protocol_write_field_begin_internal (cp,
684 cp->_bool_field_name,
685 cp->_bool_field_type,
686 cp->_bool_field_id,
687 (gint8) (value
688 ? CT_BOOLEAN_TRUE : CT_BOOLEAN_FALSE),
689 error)) < 0) {
690 return -1;
691 }
692 xfer += ret;
693
694 cp->_bool_field_name = NULL;
695 } else {
696 /* we're not part of a field, so just write the value */
697 if ((ret = thrift_protocol_write_byte (protocol,
698 (gint8) (value ? CT_BOOLEAN_TRUE
699 : CT_BOOLEAN_FALSE),
700 error)) < 0) {
701 return -1;
702 }
703 xfer += ret;
704 }
705 return xfer;
706}
707
708gint32
709thrift_compact_protocol_write_byte (ThriftProtocol *protocol, const gint8 value,
710 GError **error)
711{
712 g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
713
714 if (thrift_transport_write (protocol->transport,
715 (const gpointer) &value, 1, error)) {
716 return 1;
717 } else {
718 return -1;
719 }
720}
721
722gint32
723thrift_compact_protocol_write_i16 (ThriftProtocol *protocol, const gint16 value,
724 GError **error)
725{
726 ThriftCompactProtocol *cp;
727
728 g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
729
730 cp = THRIFT_COMPACT_PROTOCOL (protocol);
731
732 return thrift_compact_protocol_write_varint32 (cp,
733 i32_to_zigzag ((gint32) value),
734 error);
735}
736
737gint32
738thrift_compact_protocol_write_i32 (ThriftProtocol *protocol, const gint32 value,
739 GError **error)
740{
741 ThriftCompactProtocol *cp;
742
743 g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
744
745 cp = THRIFT_COMPACT_PROTOCOL (protocol);
746
747 return thrift_compact_protocol_write_varint32 (cp,
748 i32_to_zigzag (value),
749 error);
750}
751
752gint32
753thrift_compact_protocol_write_i64 (ThriftProtocol *protocol, const gint64 value,
754 GError **error)
755{
756 ThriftCompactProtocol *cp;
757
758 g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
759
760 cp = THRIFT_COMPACT_PROTOCOL (protocol);
761
762 return thrift_compact_protocol_write_varint64 (cp,
763 i64_to_zigzag (value),
764 error);
765}
766
767gint32
768thrift_compact_protocol_write_double (ThriftProtocol *protocol,
769 const gdouble value, GError **error)
770{
771 guint64 bits;
772
773 g_assert (sizeof (gdouble) == sizeof (guint64));
774
775 g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
776
777 bits = GUINT64_TO_LE (thrift_bitwise_cast_guint64 (value));
778 if (thrift_transport_write (protocol->transport,
779 (const gpointer) &bits, 8, error)) {
780 return 8;
781 } else {
782 return -1;
783 }
784}
785
786gint32
787thrift_compact_protocol_write_string (ThriftProtocol *protocol,
788 const gchar *str, GError **error)
789{
790 size_t len;
791
792 g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
793
794 len = str != NULL ? strlen (str) : 0;
795 if (len > G_MAXINT32) {
796 g_set_error (error, THRIFT_PROTOCOL_ERROR,
797 THRIFT_PROTOCOL_ERROR_SIZE_LIMIT,
798 "string size (guess: %lu) is too large", (unsigned long) len);
799 return -1;
800 }
801
802 /* write the string length + 1 which includes the null terminator */
803 return thrift_protocol_write_binary (protocol, (const gpointer) str,
804 (const guint32) len, error);
805}
806
807gint32
808thrift_compact_protocol_write_binary (ThriftProtocol *protocol,
809 const gpointer buf,
810 const guint32 len, GError **error)
811{
812 ThriftCompactProtocol *cp;
813
814 gint32 ret;
815 gint32 xfer;
816
817 g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
818
819 cp = THRIFT_COMPACT_PROTOCOL (protocol);
820
821 xfer = 0;
822
823 if ((ret = thrift_compact_protocol_write_varint32 (cp, len, error)) < 0) {
824 return -1;
825 }
826 xfer += ret;
827
828 if (len > 0) {
829 /* checking len + xfer > uint_max, but we don't want to overflow while
830 * checking for overflows. transforming to len > uint_max - xfer.
831 */
832 if (len > (guint32) (G_MAXINT32 - xfer)) {
833 g_set_error (error, THRIFT_PROTOCOL_ERROR,
834 THRIFT_PROTOCOL_ERROR_SIZE_LIMIT,
835 "size %d + %d is too large", len, xfer);
836 return -1;
837 }
838
839 if (thrift_transport_write (protocol->transport,
840 (const gpointer) buf, len, error) == FALSE) {
841 return -1;
842 }
843 xfer += len;
844 }
845
846 return xfer;
847}
848
849gint32
850thrift_compact_protocol_read_message_begin (ThriftProtocol *protocol,
851 gchar **name,
852 ThriftMessageType *message_type,
853 gint32 *seqid, GError **error)
854{
855 ThriftCompactProtocol *cp;
856
857 gint32 ret;
858 gint32 xfer;
859
860 gint8 protocol_id, version_and_type, version;
861
862 xfer = 0;
863
864 g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
865
866 cp = THRIFT_COMPACT_PROTOCOL (protocol);
867
868 if ((ret = thrift_protocol_read_byte (protocol, &protocol_id, error)) < 0) {
869 return -1;
870 }
871 xfer += ret;
872
873 if (protocol_id != PROTOCOL_ID) {
874 g_set_error (error, THRIFT_PROTOCOL_ERROR,
875 THRIFT_PROTOCOL_ERROR_BAD_VERSION,
876 "bad protocol id");
877 return -1;
878 }
879
880 if ((ret = thrift_protocol_read_byte (protocol, &version_and_type,
881 error)) < 0) {
882 return -1;
883 }
884 xfer += ret;
885
886 version = (gint8)(version_and_type & VERSION_MASK);
887 if (version != VERSION_N) {
888 g_set_error (error, THRIFT_PROTOCOL_ERROR,
889 THRIFT_PROTOCOL_ERROR_BAD_VERSION,
890 "bad version and/or type");
891 return -1;
892 }
893
894 *message_type
895 = (ThriftMessageType)((version_and_type >> TYPE_SHIFT_AMOUNT) & TYPE_BITS);
896
897 if ((ret = thrift_compact_protocol_read_varint32 (cp, seqid, error)) < 0) {
898 return -1;
899 }
900 xfer += ret;
901
902 if ((ret = thrift_protocol_read_string (protocol, name, error)) < 0) {
903 return -1;
904 }
905 xfer += ret;
906
907 return xfer;
908}
909
910gint32
911thrift_compact_protocol_read_message_end (ThriftProtocol *protocol,
912 GError **error)
913{
914 THRIFT_UNUSED_VAR (protocol);
915 THRIFT_UNUSED_VAR (error);
916 return 0;
917}
918
919gint32
920thrift_compact_protocol_read_struct_begin (ThriftProtocol *protocol,
921 gchar **name,
922 GError **error)
923{
924 ThriftCompactProtocol *cp;
925 GQueue *q;
926
927 THRIFT_UNUSED_VAR (error);
928
929 g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
930
931 cp = THRIFT_COMPACT_PROTOCOL (protocol);
932 q = &(cp->_last_field);
933
934 *name = NULL;
935
936 g_queue_push_tail (q, GINT_TO_POINTER ((gint) cp->_last_field_id));
937 cp->_last_field_id = 0;
938
939 return 0;
940}
941
942gint32
943thrift_compact_protocol_read_struct_end (ThriftProtocol *protocol,
944 GError **error)
945{
946 ThriftCompactProtocol *cp;
947 GQueue *q;
948
949 THRIFT_UNUSED_VAR (error);
950
951 g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
952
953 cp = THRIFT_COMPACT_PROTOCOL (protocol);
954 q = &(cp->_last_field);
955
956 cp->_last_field_id = (gint16) GPOINTER_TO_INT (g_queue_pop_tail (q));
957
958 return 0;
959}
960
961gint32
962thrift_compact_protocol_read_field_begin (ThriftProtocol *protocol,
963 gchar **name,
964 ThriftType *field_type,
965 gint16 *field_id,
966 GError **error)
967{
968 ThriftCompactProtocol *cp;
969
970 gint32 ret;
971 gint32 xfer;
972
973 gint16 modifier;
974 gint8 byte;
975 gint8 type;
976
977 g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
978
979 cp = THRIFT_COMPACT_PROTOCOL (protocol);
980
981 THRIFT_UNUSED_VAR (name);
982
983 xfer = 0;
984
985 if ((ret = thrift_protocol_read_byte (protocol, &byte, error)) < 0) {
986 return -1;
987 }
988 xfer += ret;
989
990 type = (byte & 0x0f);
991
992 /* if it's a stop, then we can return immediately, as the struct is over. */
993 if (type == T_STOP) {
994 *field_type = T_STOP;
995 *field_id = 0;
996 return xfer;
997 }
998
999 /* mask off the 4 MSB of the type header.
1000 * it could contain a field id delta.
1001 */
1002 modifier = (gint16)(((guint8)byte & 0xf0) >> 4);
1003 if (modifier == 0) {
1004 /* not a delta, look ahead for the zigzag varint field id. */
1005 if ((ret = thrift_protocol_read_i16 (protocol, field_id, error)) < 0) {
1006 return -1;
1007 }
1008 xfer += ret;
1009 } else {
1010 *field_id = (gint16)(cp->_last_field_id + modifier);
1011 }
1012 if ((ret = thrift_compact_protocol_get_ttype (cp, type, error)) < 0) {
1013 return -1;
1014 }
1015 *field_type = ret;
1016
1017 /* if this happens to be a boolean field, the value is encoded in the type */
1018 if (type == CT_BOOLEAN_TRUE || type == CT_BOOLEAN_FALSE) {
1019 /* save the boolean value in a special instance variable. */
1020 cp->_has_bool_value = TRUE;
1021 cp->_bool_value =
1022 (type == CT_BOOLEAN_TRUE ? TRUE : FALSE);
1023 }
1024
1025 /* push the new field onto the field stack so we can keep the deltas going. */
1026 cp->_last_field_id = *field_id;
1027
1028 return xfer;
1029}
1030
1031gint32
1032thrift_compact_protocol_read_field_end (ThriftProtocol *protocol,
1033 GError **error)
1034{
1035 THRIFT_UNUSED_VAR (protocol);
1036 THRIFT_UNUSED_VAR (error);
1037 return 0;
1038}
1039
1040gint32
1041thrift_compact_protocol_read_map_begin (ThriftProtocol *protocol,
1042 ThriftType *key_type,
1043 ThriftType *value_type,
1044 guint32 *size,
1045 GError **error)
1046{
1047 gint32 ret;
1048 gint32 xfer;
1049
1050 gint8 kv_type;
1051 gint32 msize;
1052
1053 ThriftCompactProtocol *cp;
1054
1055 g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
1056
1057 kv_type = 0;
1058 msize = 0;
1059
1060 cp = THRIFT_COMPACT_PROTOCOL (protocol);
1061
1062 xfer = 0;
1063
1064 if ((ret = thrift_compact_protocol_read_varint32 (cp, &msize, error)) <0) {
1065 return -1;
1066 }
1067 xfer += ret;
1068
1069 /* still read the kv byte if negative size */
1070 if (msize != 0) {
1071 if ((ret = thrift_protocol_read_byte (protocol, &kv_type, error)) < 0) {
1072 return -1;
1073 }
1074 xfer += ret;
1075 }
1076
1077 if (cp->container_limit > 0 && msize > cp->container_limit) {
1078 g_set_error (error, THRIFT_PROTOCOL_ERROR,
1079 THRIFT_PROTOCOL_ERROR_SIZE_LIMIT,
1080 "got size over limit (%d > %d)", msize, cp->container_limit);
1081 return -1;
1082 } else if (msize > 0) {
1083 if ((ret = thrift_compact_protocol_get_ttype (cp,
1084 (gint8)((guint8)kv_type
1085 >> 4),
1086 error)) < 0) {
1087 return -1;
1088 }
1089 *key_type = ret;
1090 if ((ret = thrift_compact_protocol_get_ttype (cp,
1091 (gint8)((guint8)kv_type
1092 & 0xf),
1093 error)) < 0) {
1094 return -1;
1095 }
1096 *value_type = ret;
1097 *size = (guint32) msize;
1098 } else if (msize == 0) {
1099 *key_type = 0;
1100 *value_type = 0;
1101 *size = 0;
1102 } else {
1103 g_set_error (error, THRIFT_PROTOCOL_ERROR,
1104 THRIFT_PROTOCOL_ERROR_NEGATIVE_SIZE,
1105 "got negative size of %d", msize);
1106 return -1;
1107 }
1108
1109 return xfer;
1110}
1111
1112gint32
1113thrift_compact_protocol_read_map_end (ThriftProtocol *protocol,
1114 GError **error)
1115{
1116 THRIFT_UNUSED_VAR (protocol);
1117 THRIFT_UNUSED_VAR (error);
1118 return 0;
1119}
1120
1121gint32
1122thrift_compact_protocol_read_list_begin (ThriftProtocol *protocol,
1123 ThriftType *element_type,
1124 guint32 *size, GError **error)
1125{
1126 ThriftCompactProtocol *cp;
1127
1128 gint32 ret;
1129 gint32 xfer;
1130
1131 gint8 size_and_type;
1132 gint32 lsize;
1133
1134 g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
1135
1136 cp = THRIFT_COMPACT_PROTOCOL (protocol);
1137
1138 size_and_type = 0;
1139
1140 xfer = 0;
1141
1142 if ((ret = thrift_protocol_read_byte (protocol, &size_and_type, error)) < 0) {
1143 return -1;
1144 }
1145 xfer += ret;
1146
1147 lsize = ((guint8)size_and_type >> 4) & 0x0f;
1148 if (lsize == 15) {
1149 if ((ret = thrift_compact_protocol_read_varint32 (cp, &lsize, error)) < 0) {
1150 return -1;
1151 }
1152 xfer += ret;
1153 }
1154
1155 if (lsize < 0) {
1156 g_set_error (error, THRIFT_PROTOCOL_ERROR,
1157 THRIFT_PROTOCOL_ERROR_NEGATIVE_SIZE,
1158 "got negative size of %d", lsize);
1159 return -1;
1160 } else if (cp->container_limit > 0 && lsize > cp->container_limit) {
1161 g_set_error (error, THRIFT_PROTOCOL_ERROR,
1162 THRIFT_PROTOCOL_ERROR_SIZE_LIMIT,
1163 "got size over limit (%d > %d)", lsize, cp->container_limit);
1164 return -1;
1165 }
1166
1167 if ((ret = thrift_compact_protocol_get_ttype (cp,
1168 (gint8)(size_and_type & 0x0f),
1169 error)) < 0) {
1170 return -1;
1171 }
1172 *element_type = ret;
1173 *size = (guint32) lsize;
1174
1175 return xfer;
1176}
1177
1178gint32
1179thrift_compact_protocol_read_list_end (ThriftProtocol *protocol,
1180 GError **error)
1181{
1182 THRIFT_UNUSED_VAR (protocol);
1183 THRIFT_UNUSED_VAR (error);
1184 return 0;
1185}
1186
1187gint32
1188thrift_compact_protocol_read_set_begin (ThriftProtocol *protocol,
1189 ThriftType *element_type,
1190 guint32 *size, GError **error)
1191{
1192 g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
1193
1194 return thrift_protocol_read_list_begin (protocol, element_type, size, error);
1195}
1196
1197gint32
1198thrift_compact_protocol_read_set_end (ThriftProtocol *protocol,
1199 GError **error)
1200{
1201 THRIFT_UNUSED_VAR (protocol);
1202 THRIFT_UNUSED_VAR (error);
1203 return 0;
1204}
1205
1206gint32
1207thrift_compact_protocol_read_bool (ThriftProtocol *protocol, gboolean *value,
1208 GError **error)
1209{
1210 ThriftCompactProtocol *cp;
1211
1212 gint32 ret;
1213 gint32 xfer;
1214
1215 gint8 val;
1216
1217 g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
1218
1219 cp = THRIFT_COMPACT_PROTOCOL (protocol);
1220
1221 xfer = 0;
1222
1223 if (cp->_has_bool_value == TRUE) {
1224 *value = cp->_bool_value;
1225 cp->_has_bool_value = FALSE;
1226 return 0;
1227 } else {
1228 if ((ret = thrift_protocol_read_byte (protocol, &val, error)) < 0) {
1229 return -1;
1230 }
1231 xfer += ret;
1232
1233 *value = (val == CT_BOOLEAN_TRUE);
1234 return xfer;
1235 }
1236}
1237
1238gint32
1239thrift_compact_protocol_read_byte (ThriftProtocol *protocol, gint8 *value,
1240 GError **error)
1241{
1242 gint32 ret;
1243 gpointer b[1];
1244
1245 g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
1246
1247 if ((ret =
1248 thrift_transport_read_all (protocol->transport,
1249 b, 1, error)) < 0) {
1250 return -1;
1251 }
1252 *value = *(gint8 *) b;
1253 return ret;
1254}
1255
1256gint32
1257thrift_compact_protocol_read_i16 (ThriftProtocol *protocol, gint16 *value,
1258 GError **error)
1259{
1260 ThriftCompactProtocol *cp;
1261
1262 gint32 ret;
1263 gint32 val;
1264 gint32 xfer;
1265
1266 g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
1267
1268 cp = THRIFT_COMPACT_PROTOCOL (protocol);
1269
1270 xfer = 0;
1271
1272 if ((ret = thrift_compact_protocol_read_varint32 (cp, &val, error)) < 0) {
1273 return -1;
1274 }
1275 xfer += ret;
1276
1277 *value = (gint16) zigzag_to_i32 ((guint32) val);
1278
1279 return xfer;
1280}
1281
1282gint32
1283thrift_compact_protocol_read_i32 (ThriftProtocol *protocol, gint32 *value,
1284 GError **error)
1285{
1286 ThriftCompactProtocol *cp;
1287
1288 gint32 ret;
1289 gint32 val;
1290 gint32 xfer;
1291
1292 g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
1293
1294 cp = THRIFT_COMPACT_PROTOCOL (protocol);
1295
1296 xfer = 0;
1297
1298 if ((ret = thrift_compact_protocol_read_varint32 (cp, &val, error)) < 0) {
1299 return -1;
1300 }
1301 xfer += ret;
1302
1303 *value = zigzag_to_i32 ((guint32) val);
1304
1305 return xfer;
1306}
1307
1308gint32
1309thrift_compact_protocol_read_i64 (ThriftProtocol *protocol, gint64 *value,
1310 GError **error)
1311{
1312 ThriftCompactProtocol *cp;
1313
1314 gint32 ret;
1315 gint64 val;
1316 gint32 xfer;
1317
1318 g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
1319
1320 cp = THRIFT_COMPACT_PROTOCOL (protocol);
1321
1322 xfer = 0;
1323
1324 if ((ret = thrift_compact_protocol_read_varint64 (cp, &val, error)) < 0) {
1325 return -1;
1326 }
1327 xfer += ret;
1328
1329 *value = zigzag_to_i64 ((guint64) val);
1330
1331 return xfer;
1332}
1333
1334gint32
1335thrift_compact_protocol_read_double (ThriftProtocol *protocol,
1336 gdouble *value, GError **error)
1337{
1338 gint32 ret;
1339 union {
1340 guint64 bits;
1341 guint8 b[8];
1342 } u;
1343
1344 g_assert (sizeof (gdouble) == sizeof (guint64));
1345
1346 g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
1347
1348 if ((ret =
1349 thrift_transport_read_all (protocol->transport,
1350 u.b, 8, error)) < 0) {
1351 return -1;
1352 }
1353 u.bits = GUINT64_FROM_LE (u.bits);
1354 *value = thrift_bitwise_cast_gdouble (u.bits);
1355 return ret;
1356}
1357
1358gint32
1359thrift_compact_protocol_read_string (ThriftProtocol *protocol,
1360 gchar **str, GError **error)
1361{
1362 ThriftCompactProtocol *cp;
1363
1364 gint32 ret;
1365 gint32 xfer;
1366
1367 gint32 read_len;
1368
1369 g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
1370
1371 cp = THRIFT_COMPACT_PROTOCOL (protocol);
1372
1373 xfer = 0;
1374 read_len = 0;
1375
1376 /* read the length into read_len */
1377 if ((ret =
1378 thrift_compact_protocol_read_varint32 (cp, &read_len, error)) < 0) {
1379 return -1;
1380 }
1381 xfer += ret;
1382
1383 if (cp->string_limit > 0 && read_len > cp->string_limit) {
1384 g_set_error (error, THRIFT_PROTOCOL_ERROR,
1385 THRIFT_PROTOCOL_ERROR_SIZE_LIMIT,
1386 "got size over limit (%d > %d)", read_len, cp->string_limit);
1387 *str = NULL;
1388 return -1;
1389 }
1390
1391 if (read_len < 0) {
1392 g_set_error (error, THRIFT_PROTOCOL_ERROR,
1393 THRIFT_PROTOCOL_ERROR_NEGATIVE_SIZE,
1394 "got negative size of %d", read_len);
1395 *str = NULL;
1396 return -1;
1397 }
1398
1399 /* allocate the memory as an array of unsigned char for binary data */
1400 *str = g_new0 (gchar, read_len + 1);
1401 if (read_len > 0) {
1402 if ((ret =
1403 thrift_transport_read_all (protocol->transport,
1404 *str, read_len, error)) < 0) {
1405 g_free (*str);
1406 *str = NULL;
1407 return -1;
1408 }
1409 xfer += ret;
1410 } else {
1411 **str = 0;
1412 }
1413
1414 return xfer;
1415}
1416
1417gint32
1418thrift_compact_protocol_read_binary (ThriftProtocol *protocol,
1419 gpointer *buf, guint32 *len,
1420 GError **error)
1421{
1422 ThriftCompactProtocol *cp;
1423
1424 gint32 ret;
1425 gint32 xfer;
1426
1427 gint32 read_len;
1428
1429 g_return_val_if_fail (THRIFT_IS_COMPACT_PROTOCOL (protocol), -1);
1430
1431 cp = THRIFT_COMPACT_PROTOCOL (protocol);
1432
1433 xfer = 0;
1434 read_len = 0;
1435
1436 /* read the length into read_len */
1437 if ((ret =
1438 thrift_compact_protocol_read_varint32 (cp, &read_len, error)) < 0) {
1439 return -1;
1440 }
1441 xfer += ret;
1442
1443 if (cp->string_limit > 0 && read_len > cp->string_limit) {
1444 g_set_error (error, THRIFT_PROTOCOL_ERROR,
1445 THRIFT_PROTOCOL_ERROR_SIZE_LIMIT,
1446 "got size over limit (%d > %d)", read_len, cp->string_limit);
1447 *buf = NULL;
1448 *len = 0;
1449 return -1;
1450 }
1451
1452 if (read_len > 0) {
1453 /* allocate the memory as an array of unsigned char for binary data */
1454 *len = (guint32) read_len;
1455 *buf = g_new (guchar, *len);
1456 if ((ret =
1457 thrift_transport_read_all (protocol->transport,
1458 *buf, *len, error)) < 0) {
1459 g_free (*buf);
1460 *buf = NULL;
1461 *len = 0;
1462 return -1;
1463 }
1464 xfer += ret;
1465
1466 } else if (read_len == 0) {
1467 *len = (guint32) read_len;
1468 *buf = NULL;
1469
1470 } else {
1471 g_set_error (error, THRIFT_PROTOCOL_ERROR,
1472 THRIFT_PROTOCOL_ERROR_NEGATIVE_SIZE,
1473 "got negative size of %d", read_len);
1474 *buf = NULL;
1475 *len = 0;
1476 return -1;
1477 }
1478
1479 return xfer;
1480}
1481
1482/* property accessor */
1483void
1484thrift_compact_protocol_get_property (GObject *object, guint property_id,
1485 GValue *value, GParamSpec *pspec)
1486{
1487 ThriftCompactProtocol *tc;
1488
1489 THRIFT_UNUSED_VAR (pspec);
1490
1491 tc = THRIFT_COMPACT_PROTOCOL (object);
1492
1493 switch (property_id) {
1494 case PROP_THRIFT_COMPACT_PROTOCOL_STRING_LIMIT:
1495 g_value_set_int (value, tc->string_limit);
1496 break;
1497 case PROP_THRIFT_COMPACT_PROTOCOL_CONTAINER_LIMIT:
1498 g_value_set_int (value, tc->container_limit);
1499 break;
1500 }
1501}
1502
1503/* property mutator */
1504void
1505thrift_compact_protocol_set_property (GObject *object, guint property_id,
1506 const GValue *value, GParamSpec *pspec)
1507{
1508 ThriftCompactProtocol *tc;
1509
1510 THRIFT_UNUSED_VAR (pspec);
1511
1512 tc = THRIFT_COMPACT_PROTOCOL (object);
1513
1514 switch (property_id) {
1515 case PROP_THRIFT_COMPACT_PROTOCOL_STRING_LIMIT:
1516 tc->string_limit = g_value_get_int (value);
1517 break;
1518 case PROP_THRIFT_COMPACT_PROTOCOL_CONTAINER_LIMIT:
1519 tc->container_limit = g_value_get_int (value);
1520 break;
1521 }
1522}
1523
1524/* initialize the class */
1525static void
1526thrift_compact_protocol_class_init (ThriftCompactProtocolClass *klass)
1527{
1528 ThriftProtocolClass *cls;
1529 GObjectClass *gobject_class;
1530 GParamSpec *param_spec;
1531
1532 cls = THRIFT_PROTOCOL_CLASS (klass);
1533 gobject_class = G_OBJECT_CLASS (klass);
1534 param_spec = NULL;
1535
1536 /* setup accessors and mutators */
1537 gobject_class->get_property = thrift_compact_protocol_get_property;
1538 gobject_class->set_property = thrift_compact_protocol_set_property;
1539
1540 param_spec = g_param_spec_int ("string_limit",
1541 "Max allowed string size",
1542 "Set the max string limit",
1543 0, /* min */
1544 G_MAXINT32, /* max */
1545 0, /* default value */
1546 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
1547 g_object_class_install_property (gobject_class,
1548 PROP_THRIFT_COMPACT_PROTOCOL_STRING_LIMIT,
1549 param_spec);
1550
1551 param_spec = g_param_spec_int ("container_limit",
1552 "Max allowed container size",
1553 "Set the max container limit",
1554 0, /* min */
1555 G_MAXINT32, /* max */
1556 0, /* default value */
1557 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
1558 g_object_class_install_property (gobject_class,
1559 PROP_THRIFT_COMPACT_PROTOCOL_CONTAINER_LIMIT,
1560 param_spec);
1561
1562 cls->write_message_begin = thrift_compact_protocol_write_message_begin;
1563 cls->write_message_end = thrift_compact_protocol_write_message_end;
1564 cls->write_struct_begin = thrift_compact_protocol_write_struct_begin;
1565 cls->write_struct_end = thrift_compact_protocol_write_struct_end;
1566 cls->write_field_begin = thrift_compact_protocol_write_field_begin;
1567 cls->write_field_end = thrift_compact_protocol_write_field_end;
1568 cls->write_field_stop = thrift_compact_protocol_write_field_stop;
1569 cls->write_map_begin = thrift_compact_protocol_write_map_begin;
1570 cls->write_map_end = thrift_compact_protocol_write_map_end;
1571 cls->write_list_begin = thrift_compact_protocol_write_list_begin;
1572 cls->write_list_end = thrift_compact_protocol_write_list_end;
1573 cls->write_set_begin = thrift_compact_protocol_write_set_begin;
1574 cls->write_set_end = thrift_compact_protocol_write_set_end;
1575 cls->write_bool = thrift_compact_protocol_write_bool;
1576 cls->write_byte = thrift_compact_protocol_write_byte;
1577 cls->write_i16 = thrift_compact_protocol_write_i16;
1578 cls->write_i32 = thrift_compact_protocol_write_i32;
1579 cls->write_i64 = thrift_compact_protocol_write_i64;
1580 cls->write_double = thrift_compact_protocol_write_double;
1581 cls->write_string = thrift_compact_protocol_write_string;
1582 cls->write_binary = thrift_compact_protocol_write_binary;
1583 cls->read_message_begin = thrift_compact_protocol_read_message_begin;
1584 cls->read_message_end = thrift_compact_protocol_read_message_end;
1585 cls->read_struct_begin = thrift_compact_protocol_read_struct_begin;
1586 cls->read_struct_end = thrift_compact_protocol_read_struct_end;
1587 cls->read_field_begin = thrift_compact_protocol_read_field_begin;
1588 cls->read_field_end = thrift_compact_protocol_read_field_end;
1589 cls->read_map_begin = thrift_compact_protocol_read_map_begin;
1590 cls->read_map_end = thrift_compact_protocol_read_map_end;
1591 cls->read_list_begin = thrift_compact_protocol_read_list_begin;
1592 cls->read_list_end = thrift_compact_protocol_read_list_end;
1593 cls->read_set_begin = thrift_compact_protocol_read_set_begin;
1594 cls->read_set_end = thrift_compact_protocol_read_set_end;
1595 cls->read_bool = thrift_compact_protocol_read_bool;
1596 cls->read_byte = thrift_compact_protocol_read_byte;
1597 cls->read_i16 = thrift_compact_protocol_read_i16;
1598 cls->read_i32 = thrift_compact_protocol_read_i32;
1599 cls->read_i64 = thrift_compact_protocol_read_i64;
1600 cls->read_double = thrift_compact_protocol_read_double;
1601 cls->read_string = thrift_compact_protocol_read_string;
1602 cls->read_binary = thrift_compact_protocol_read_binary;
1603}
1604
1605static void
1606thrift_compact_protocol_init (ThriftCompactProtocol *self)
1607{
1608 g_queue_init (&(self->_last_field));
1609}