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