Line data Source code
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 : * Copyright 2006-2017 The Apache Software Foundation.
20 : * https://github.com/apache/thrift
21 : */
22 :
23 : #ifndef _SANDESH_PROTOCOL_TBINARYPROTOCOL_TCC_
24 : #define _SANDESH_PROTOCOL_TBINARYPROTOCOL_TCC_ 1
25 :
26 : #include "TBinaryProtocol.h"
27 :
28 : #include <limits>
29 :
30 :
31 : namespace contrail { namespace sandesh { namespace protocol {
32 :
33 : template <class Transport_>
34 0 : int32_t TBinaryProtocolT<Transport_>::writeMessageBegin(const std::string& name,
35 : const TMessageType messageType,
36 : const int32_t seqid) {
37 0 : if (this->strict_write_) {
38 0 : int32_t version = (VERSION_1) | ((int32_t)messageType);
39 0 : int32_t wsize = 0;
40 : int32_t ret;
41 0 : if ((ret = writeI32(version)) < 0) {
42 0 : return ret;
43 : }
44 0 : wsize += ret;
45 0 : if ((ret = writeString(name)) < 0) {
46 0 : return ret;
47 : }
48 0 : wsize += ret;
49 0 : if ((ret = writeI32(seqid)) < 0) {
50 0 : return ret;
51 : }
52 0 : wsize += ret;
53 0 : return wsize;
54 : } else {
55 0 : int32_t wsize = 0;
56 : int32_t ret;
57 0 : if ((ret = writeString(name)) < 0) {
58 0 : return ret;
59 : }
60 0 : wsize += ret;
61 0 : if ((ret = writeByte((int8_t)messageType)) < 0) {
62 0 : return ret;
63 : }
64 0 : wsize += ret;
65 0 : if ((ret = writeI32(seqid)) < 0) {
66 0 : return ret;
67 : }
68 0 : wsize += ret;
69 0 : return wsize;
70 : }
71 : }
72 :
73 : template <class Transport_>
74 0 : int32_t TBinaryProtocolT<Transport_>::writeMessageEnd() {
75 0 : return 0;
76 : }
77 :
78 : template <class Transport_>
79 0 : int32_t TBinaryProtocolT<Transport_>::writeStructBegin(const char* name) {
80 : (void) name;
81 0 : return 0;
82 : }
83 :
84 : template <class Transport_>
85 0 : int32_t TBinaryProtocolT<Transport_>::writeStructEnd() {
86 0 : return 0;
87 : }
88 :
89 : template <class Transport_>
90 2332 : int32_t TBinaryProtocolT<Transport_>::writeSandeshBegin(const char* name) {
91 2332 : return writeString(name);
92 : }
93 :
94 : template <class Transport_>
95 2331 : int32_t TBinaryProtocolT<Transport_>::writeSandeshEnd() {
96 2331 : return 0;
97 : }
98 :
99 : template <class Transport_>
100 4294 : int32_t TBinaryProtocolT<Transport_>::writeContainerElementBegin() {
101 4294 : return 0;
102 : }
103 :
104 : template <class Transport_>
105 4294 : int32_t TBinaryProtocolT<Transport_>::writeContainerElementEnd() {
106 4294 : return 0;
107 : }
108 :
109 : template <class Transport_>
110 30508 : int32_t TBinaryProtocolT<Transport_>::writeFieldBegin(const char* name,
111 : const TType fieldType,
112 : const int16_t fieldId,
113 : const std::map<std::string, std::string> *const amap) {
114 : (void) name;
115 : (void) amap;
116 30508 : int32_t wsize = 0;
117 : int32_t ret;
118 30508 : if ((ret = writeByte((int8_t)fieldType)) < 0) {
119 0 : return ret;
120 : }
121 30511 : wsize += ret;
122 30511 : if ((ret = writeI16(fieldId)) < 0) {
123 0 : return ret;
124 : }
125 30512 : wsize += ret;
126 30512 : return wsize;
127 : }
128 :
129 : template <class Transport_>
130 30505 : int32_t TBinaryProtocolT<Transport_>::writeFieldEnd() {
131 30505 : return 0;
132 : }
133 :
134 : template <class Transport_>
135 2331 : int32_t TBinaryProtocolT<Transport_>::writeFieldStop() {
136 : return
137 2331 : writeByte((int8_t)T_STOP);
138 : }
139 :
140 : template <class Transport_>
141 0 : int32_t TBinaryProtocolT<Transport_>::writeMapBegin(const TType keyType,
142 : const TType valType,
143 : const uint32_t size) {
144 0 : int32_t wsize = 0;
145 : int32_t ret;
146 0 : if ((ret = writeByte((int8_t)keyType)) < 0) {
147 0 : return ret;
148 : }
149 0 : wsize += ret;
150 0 : if ((ret = writeByte((int8_t)valType)) < 0) {
151 0 : return ret;
152 : }
153 0 : wsize += ret;
154 0 : if ((ret = writeI32((int32_t)size)) < 0) {
155 0 : return ret;
156 : }
157 0 : wsize += ret;
158 0 : return wsize;
159 : }
160 :
161 : template <class Transport_>
162 0 : int32_t TBinaryProtocolT<Transport_>::writeMapEnd() {
163 0 : return 0;
164 : }
165 :
166 : template <class Transport_>
167 5984 : int32_t TBinaryProtocolT<Transport_>::writeListBegin(const TType elemType,
168 : const uint32_t size) {
169 5984 : int32_t wsize = 0;
170 : int32_t ret;
171 5984 : if ((ret = writeByte((int8_t) elemType)) < 0) {
172 0 : return ret;
173 : }
174 5984 : wsize += ret;
175 5984 : if ((ret = writeI32((int32_t)size)) < 0) {
176 0 : return ret;
177 : }
178 5984 : wsize += ret;
179 5984 : return wsize;
180 : }
181 :
182 : template <class Transport_>
183 5985 : int32_t TBinaryProtocolT<Transport_>::writeListEnd() {
184 5985 : return 0;
185 : }
186 :
187 : template <class Transport_>
188 0 : int32_t TBinaryProtocolT<Transport_>::writeSetBegin(const TType elemType,
189 : const uint32_t size) {
190 0 : uint32_t wsize = 0;
191 : int32_t ret;
192 0 : if ((ret = writeByte((int8_t)elemType)) < 0) {
193 0 : return ret;
194 : }
195 0 : wsize += ret;
196 0 : if ((ret = writeI32((int32_t)size)) < 0) {
197 0 : return ret;
198 : }
199 0 : wsize += ret;
200 0 : return wsize;
201 : }
202 :
203 : template <class Transport_>
204 0 : int32_t TBinaryProtocolT<Transport_>::writeSetEnd() {
205 0 : return 0;
206 : }
207 :
208 : template <class Transport_>
209 0 : int32_t TBinaryProtocolT<Transport_>::writeBool(const bool value) {
210 0 : uint8_t tmp = value ? 1 : 0;
211 0 : this->trans_->write(&tmp, 1);
212 0 : return 1;
213 : }
214 :
215 : template <class Transport_>
216 44772 : int32_t TBinaryProtocolT<Transport_>::writeByte(const int8_t byte) {
217 44772 : this->trans_->write((uint8_t*)&byte, 1);
218 44776 : return 1;
219 : }
220 :
221 : template <class Transport_>
222 33365 : int32_t TBinaryProtocolT<Transport_>::writeI16(const int16_t i16) {
223 33365 : int16_t net = (int16_t)htons(i16);
224 33365 : this->trans_->write((uint8_t*)&net, 2);
225 33366 : return 2;
226 : }
227 :
228 : template <class Transport_>
229 20282 : int32_t TBinaryProtocolT<Transport_>::writeI32(const int32_t i32) {
230 20282 : int32_t net = (int32_t)htonl(i32);
231 20282 : this->trans_->write((uint8_t*)&net, 4);
232 20278 : return 4;
233 : }
234 :
235 : template <class Transport_>
236 1656 : int32_t TBinaryProtocolT<Transport_>::writeI64(const int64_t i64) {
237 1656 : int64_t net = (int64_t)htonll(i64);
238 1656 : this->trans_->write((uint8_t*)&net, 8);
239 1656 : return 8;
240 : }
241 :
242 : template <class Transport_>
243 2020 : int32_t TBinaryProtocolT<Transport_>::writeU16(const uint16_t u16) {
244 2020 : uint16_t net = (uint16_t)htons(u16);
245 2020 : this->trans_->write((uint8_t*)&net, 2);
246 2020 : return 2;
247 : }
248 :
249 : template <class Transport_>
250 2957 : int32_t TBinaryProtocolT<Transport_>::writeU32(const uint32_t u32) {
251 2957 : uint32_t net = (uint32_t)htonl(u32);
252 2957 : this->trans_->write((uint8_t*)&net, 4);
253 2957 : return 4;
254 : }
255 :
256 : template <class Transport_>
257 1403 : int32_t TBinaryProtocolT<Transport_>::writeU64(const uint64_t u64) {
258 1403 : uint64_t net = (uint64_t)htonll(u64);
259 1403 : this->trans_->write((uint8_t*)&net, 8);
260 1403 : return 8;
261 : }
262 :
263 : template <class Transport_>
264 0 : int32_t TBinaryProtocolT<Transport_>::writeIPV4(const uint32_t ip4) {
265 0 : uint32_t net = (uint32_t)htonl(ip4);
266 0 : this->trans_->write((uint8_t*)&net, 4);
267 0 : return 4;
268 : }
269 :
270 : template <class Transport_>
271 0 : int32_t TBinaryProtocolT<Transport_>::writeIPADDR(
272 : const boost::asio::ip::address& ipaddress) {
273 : int32_t ret;
274 0 : if (ipaddress.is_v4()) {
275 : // encode the ip version
276 0 : if ((ret = writeByte(AF_INET)) < 0) {
277 0 : return ret;
278 : }
279 0 : this->trans_->write(ipaddress.to_v4().to_bytes().data(), 4);
280 0 : return ret+4;
281 0 : } else if (ipaddress.is_v6()) {
282 : // encode the ip version
283 0 : if ((ret = writeByte(AF_INET6)) < 0) {
284 0 : return ret;
285 : }
286 0 : this->trans_->write(ipaddress.to_v6().to_bytes().data(), 16);
287 0 : return ret+16;
288 : }
289 0 : return -1;
290 : }
291 :
292 : template <class Transport_>
293 0 : int32_t TBinaryProtocolT<Transport_>::writeDouble(const double dub) {
294 : BOOST_STATIC_ASSERT(sizeof(double) == sizeof(uint64_t));
295 : BOOST_STATIC_ASSERT(std::numeric_limits<double>::is_iec559);
296 :
297 0 : uint64_t bits = bitwise_cast<uint64_t>(dub);
298 0 : bits = htonll(bits);
299 0 : this->trans_->write((uint8_t*)&bits, 8);
300 0 : return 8;
301 : }
302 :
303 :
304 : template <class Transport_>
305 2407 : int32_t TBinaryProtocolT<Transport_>::writeString(const std::string& str) {
306 2407 : uint32_t size = str.size();
307 : int32_t result;
308 2407 : if ((result = writeI32((int32_t)size)) < 0) {
309 0 : return result;
310 : }
311 2407 : if (size > 0) {
312 2375 : this->trans_->write((uint8_t*)str.data(), size);
313 : }
314 2407 : return result + size;
315 : }
316 :
317 : template <class Transport_>
318 0 : int32_t TBinaryProtocolT<Transport_>::writeBinary(const std::string& str) {
319 0 : return TBinaryProtocolT<Transport_>::writeString(str);
320 : }
321 :
322 : template <class Transport_>
323 0 : int32_t TBinaryProtocolT<Transport_>::writeXML(const std::string& str) {
324 0 : return TBinaryProtocolT<Transport_>::writeString(str);
325 : }
326 :
327 : template <class Transport_>
328 0 : int32_t TBinaryProtocolT<Transport_>::writeUUID(const boost::uuids::uuid& uuid) {
329 0 : this->trans_->write((uint8_t*)&uuid, 16);
330 0 : return 16;
331 : }
332 :
333 : /**
334 : * Reading functions
335 : */
336 :
337 : template <class Transport_>
338 0 : int32_t TBinaryProtocolT<Transport_>::readMessageBegin(std::string& name,
339 : TMessageType& messageType,
340 : int32_t& seqid) {
341 0 : int32_t result = 0;
342 : int32_t sz;
343 : int ret;
344 0 : if ((ret = readI32(sz)) < 0) {
345 0 : return ret;
346 : }
347 0 : result += ret;
348 :
349 0 : if (sz < 0) {
350 : // Check for correct version number
351 0 : int32_t version = sz & VERSION_MASK;
352 0 : if (version != VERSION_1) {
353 0 : LOG(ERROR, __func__ << ": Bad version identifier");
354 0 : return -1;
355 : }
356 0 : messageType = (TMessageType)(sz & 0x000000ff);
357 0 : if ((ret = readString(name)) < 0) {
358 0 : return ret;
359 : }
360 0 : result += ret;
361 0 : if ((ret = readI32(seqid)) < 0) {
362 0 : return ret;
363 : }
364 0 : result += ret;
365 : } else {
366 0 : if (this->strict_read_) {
367 0 : LOG(ERROR, __func__ << ": No version identifier... old protocol client in strict mode?");
368 0 : return -1;
369 : } else {
370 : // Handle pre-versioned input
371 : int8_t type;
372 0 : if ((ret = readStringBody(name, sz)) < 0) {
373 0 : return ret;
374 : }
375 0 : result += ret;
376 0 : if ((ret = readByte(type)) < 0) {
377 0 : return ret;
378 : }
379 0 : result += ret;
380 0 : messageType = (TMessageType)type;
381 0 : if ((ret = readI32(seqid)) < 0) {
382 0 : return ret;
383 : }
384 0 : result += ret;
385 : }
386 : }
387 0 : return result;
388 : }
389 :
390 : template <class Transport_>
391 0 : int32_t TBinaryProtocolT<Transport_>::readMessageEnd() {
392 0 : return 0;
393 : }
394 :
395 : template <class Transport_>
396 4663 : int32_t TBinaryProtocolT<Transport_>::readSandeshBegin(std::string& name) {
397 4663 : return readString(name);
398 : }
399 :
400 : template <class Transport_>
401 2333 : int32_t TBinaryProtocolT<Transport_>::readSandeshEnd() {
402 2333 : return 0;
403 : }
404 :
405 : template <class Transport_>
406 4294 : int32_t TBinaryProtocolT<Transport_>::readContainerElementBegin() {
407 4294 : return 0;
408 : }
409 :
410 : template <class Transport_>
411 4294 : int32_t TBinaryProtocolT<Transport_>::readContainerElementEnd() {
412 4294 : return 0;
413 : }
414 :
415 : template <class Transport_>
416 0 : int32_t TBinaryProtocolT<Transport_>::readStructBegin(std::string& name) {
417 0 : name = "";
418 0 : return 0;
419 : }
420 :
421 : template <class Transport_>
422 0 : int32_t TBinaryProtocolT<Transport_>::readStructEnd() {
423 0 : return 0;
424 : }
425 :
426 : template <class Transport_>
427 32895 : int32_t TBinaryProtocolT<Transport_>::readFieldBegin(std::string& name,
428 : TType& fieldType,
429 : int16_t& fieldId) {
430 : (void) name;
431 32895 : int32_t result = 0;
432 : int8_t type;
433 : int32_t ret;
434 32895 : if ((ret = readByte(type)) < 0) {
435 0 : return ret;
436 : }
437 32894 : result += ret;
438 32894 : fieldType = (TType)type;
439 32894 : if (fieldType == T_STOP) {
440 2333 : fieldId = 0;
441 2333 : return result;
442 : }
443 30561 : if ((ret = readI16(fieldId)) < 0) {
444 0 : return ret;
445 : }
446 30575 : result += ret;
447 30575 : return result;
448 : }
449 :
450 : template <class Transport_>
451 30567 : int32_t TBinaryProtocolT<Transport_>::readFieldEnd() {
452 30567 : return 0;
453 : }
454 :
455 : template <class Transport_>
456 0 : int32_t TBinaryProtocolT<Transport_>::readMapBegin(TType& keyType,
457 : TType& valType,
458 : uint32_t& size) {
459 : int8_t k, v;
460 0 : int32_t result = 0;
461 : int32_t sizei;
462 : int32_t ret;
463 0 : if ((ret = readByte(k)) < 0) {
464 0 : return ret;
465 : }
466 0 : result += ret;
467 0 : keyType = (TType)k;
468 0 : if ((ret = readByte(v)) < 0) {
469 0 : return ret;
470 : }
471 0 : result += ret;
472 0 : valType = (TType)v;
473 0 : if ((ret = readI32(sizei)) < 0) {
474 0 : return ret;
475 : }
476 0 : result += ret;
477 0 : if (sizei < 0) {
478 0 : LOG(ERROR, __func__ << ": Negative size " << sizei);
479 0 : return -1;
480 0 : } else if (this->container_limit_ && sizei > this->container_limit_) {
481 0 : LOG(ERROR, __func__ << ": Size " << sizei << " greater than limit "
482 : << this->container_limit_);
483 0 : return -1;
484 : }
485 0 : size = (uint32_t)sizei;
486 0 : return result;
487 : }
488 :
489 : template <class Transport_>
490 0 : int32_t TBinaryProtocolT<Transport_>::readMapEnd() {
491 0 : return 0;
492 : }
493 :
494 : template <class Transport_>
495 5985 : int32_t TBinaryProtocolT<Transport_>::readListBegin(TType& elemType,
496 : uint32_t& size) {
497 : int8_t e;
498 5985 : int32_t result = 0;
499 : int32_t sizei;
500 : int32_t ret;
501 5985 : if ((ret = readByte(e)) < 0) {
502 0 : return ret;
503 : }
504 5985 : result += ret;
505 5985 : elemType = (TType)e;
506 5985 : if ((ret = readI32(sizei)) < 0) {
507 0 : return ret;
508 : }
509 5985 : result += ret;
510 5985 : if (sizei < 0) {
511 0 : LOG(ERROR, __func__ << ": Negative size " << sizei);
512 0 : return -1;
513 5985 : } else if (this->container_limit_ && sizei > this->container_limit_) {
514 0 : LOG(ERROR, __func__ << ": Size " << sizei << " greater than limit "
515 : << this->container_limit_);
516 0 : return -1;
517 : }
518 5985 : size = (uint32_t)sizei;
519 5985 : return result;
520 : }
521 :
522 : template <class Transport_>
523 5985 : int32_t TBinaryProtocolT<Transport_>::readListEnd() {
524 5985 : return 0;
525 : }
526 :
527 : template <class Transport_>
528 0 : int32_t TBinaryProtocolT<Transport_>::readSetBegin(TType& elemType,
529 : uint32_t& size) {
530 : int8_t e;
531 0 : int32_t result = 0;
532 : int32_t sizei;
533 : int32_t ret;
534 0 : if ((ret = readByte(e)) < 0) {
535 0 : return ret;
536 : }
537 0 : result += ret;
538 0 : elemType = (TType)e;
539 0 : if ((ret = readI32(sizei)) < 0) {
540 0 : return ret;
541 : }
542 0 : result += ret;
543 0 : if (sizei < 0) {
544 0 : LOG(ERROR, __func__ << ": Negative size " << sizei);
545 0 : } else if (this->container_limit_ && sizei > this->container_limit_) {
546 0 : LOG(ERROR, __func__ << ": Size " << sizei << " greater than limit "
547 : << this->container_limit_);
548 0 : return -1;
549 : }
550 0 : size = (uint32_t)sizei;
551 0 : return result;
552 : }
553 :
554 : template <class Transport_>
555 0 : int32_t TBinaryProtocolT<Transport_>::readSetEnd() {
556 0 : return 0;
557 : }
558 :
559 : template <class Transport_>
560 0 : int32_t TBinaryProtocolT<Transport_>::readBool(bool& value) {
561 : uint8_t b[1];
562 0 : this->trans_->readAll(b, 1);
563 0 : value = *(int8_t*)b != 0;
564 0 : return 1;
565 : }
566 :
567 : template <class Transport_>
568 44872 : int32_t TBinaryProtocolT<Transport_>::readByte(int8_t& byte) {
569 : uint8_t b[1];
570 44872 : this->trans_->readAll(b, 1);
571 44870 : byte = *(int8_t*)b;
572 44870 : return 1;
573 : }
574 :
575 : template <class Transport_>
576 33425 : int32_t TBinaryProtocolT<Transport_>::readI16(int16_t& i16) {
577 : union bytes {
578 : uint8_t b[2];
579 : int16_t all;
580 : } theBytes;
581 33425 : this->trans_->readAll(theBytes.b, 2);
582 33423 : i16 = (int16_t)ntohs(theBytes.all);
583 33423 : return 2;
584 : }
585 :
586 : template <class Transport_>
587 22644 : int32_t TBinaryProtocolT<Transport_>::readI32(int32_t& i32) {
588 : union bytes {
589 : uint8_t b[4];
590 : int32_t all;
591 : } theBytes;
592 22644 : this->trans_->readAll(theBytes.b, 4);
593 22641 : i32 = (int32_t)ntohl(theBytes.all);
594 22641 : return 4;
595 : }
596 :
597 : template <class Transport_>
598 1656 : int32_t TBinaryProtocolT<Transport_>::readI64(int64_t& i64) {
599 : union bytes {
600 : uint8_t b[8];
601 : int64_t all;
602 : } theBytes;
603 1656 : this->trans_->readAll(theBytes.b, 8);
604 1656 : i64 = (int64_t)ntohll(theBytes.all);
605 1656 : return 8;
606 : }
607 :
608 : template <class Transport_>
609 2020 : int32_t TBinaryProtocolT<Transport_>::readU16(uint16_t& u16) {
610 : union bytes {
611 : uint8_t b[2];
612 : uint16_t all;
613 : } theBytes;
614 2020 : this->trans_->readAll(theBytes.b, 2);
615 2020 : u16 = (uint16_t)ntohs(theBytes.all);
616 2020 : return 2;
617 : }
618 :
619 : template <class Transport_>
620 2957 : int32_t TBinaryProtocolT<Transport_>::readU32(uint32_t& u32) {
621 : union bytes {
622 : uint8_t b[4];
623 : uint32_t all;
624 : } theBytes;
625 2957 : this->trans_->readAll(theBytes.b, 4);
626 2957 : u32 = (uint32_t)ntohl(theBytes.all);
627 2957 : return 4;
628 : }
629 :
630 : template <class Transport_>
631 1403 : int32_t TBinaryProtocolT<Transport_>::readU64(uint64_t& u64) {
632 : union bytes {
633 : uint8_t b[8];
634 : int64_t all;
635 : } theBytes;
636 1403 : this->trans_->readAll(theBytes.b, 8);
637 1403 : u64 = (uint64_t)ntohll(theBytes.all);
638 1403 : return 8;
639 : }
640 :
641 : template <class Transport_>
642 0 : int32_t TBinaryProtocolT<Transport_>::readIPV4(uint32_t& ip4) {
643 : union bytes {
644 : uint8_t b[4];
645 : uint32_t all;
646 : } theBytes;
647 0 : this->trans_->readAll(theBytes.b, 4);
648 0 : ip4 = (uint32_t)ntohl(theBytes.all);
649 0 : return 4;
650 : }
651 :
652 : template <class Transport_>
653 0 : int32_t TBinaryProtocolT<Transport_>::readIPADDR(
654 : boost::asio::ip::address& ipaddress) {
655 : int32_t ret;
656 : int8_t version;
657 : // decode the ip version
658 0 : if ((ret = readByte(version)) < 0) {
659 0 : return ret;
660 : }
661 0 : if (version == AF_INET) {
662 : boost::asio::ip::address_v4::bytes_type ipv4;
663 : #ifdef BOOST_ASIO_HAS_STD_ARRAY
664 0 : this->trans_->readAll(ipv4.data(), 4);
665 : #else
666 : this->trans_->readAll(ipv4.c_array(), 4);
667 : #endif
668 0 : ipaddress = boost::asio::ip::address_v4(ipv4);
669 0 : return ret+4;
670 0 : } else if (version == AF_INET6) {
671 : boost::asio::ip::address_v6::bytes_type ipv6;
672 : #ifdef BOOST_ASIO_HAS_STD_ARRAY
673 0 : this->trans_->readAll(ipv6.data(), 16);
674 : #else
675 : this->trans_->readAll(ipv6.c_array(), 16);
676 : #endif
677 0 : ipaddress = boost::asio::ip::address_v6(ipv6);
678 0 : return ret+16;
679 : }
680 0 : return -1;
681 : }
682 :
683 : template <class Transport_>
684 0 : int32_t TBinaryProtocolT<Transport_>::readDouble(double& dub) {
685 : BOOST_STATIC_ASSERT(sizeof(double) == sizeof(uint64_t));
686 : BOOST_STATIC_ASSERT(std::numeric_limits<double>::is_iec559);
687 :
688 : union bytes {
689 : uint8_t b[8];
690 : uint64_t all;
691 : } theBytes;
692 0 : this->trans_->readAll(theBytes.b, 8);
693 0 : theBytes.all = ntohll(theBytes.all);
694 0 : dub = bitwise_cast<double>(theBytes.all);
695 0 : return 8;
696 : }
697 :
698 : template <class Transport_>
699 4738 : int32_t TBinaryProtocolT<Transport_>::readString(std::string& str) {
700 4738 : int32_t result = 0;
701 : int32_t size;
702 : int32_t ret;
703 4738 : if ((ret = readI32(size)) < 0) {
704 0 : return ret;
705 : }
706 4738 : result += ret;
707 4738 : if ((ret = readStringBody(str, size)) < 0) {
708 0 : return ret;
709 : }
710 4738 : result += ret;
711 4738 : return result;
712 : }
713 :
714 : template <class Transport_>
715 0 : int32_t TBinaryProtocolT<Transport_>::readBinary(std::string& str) {
716 0 : return TBinaryProtocolT<Transport_>::readString(str);
717 : }
718 :
719 : template <class Transport_>
720 0 : int32_t TBinaryProtocolT<Transport_>::readXML(std::string& str) {
721 0 : return TBinaryProtocolT<Transport_>::readString(str);
722 : }
723 :
724 : template <class Transport_>
725 0 : int32_t TBinaryProtocolT<Transport_>::readUUID(boost::uuids::uuid& uuid) {
726 0 : this->trans_->readAll(uuid.data, 16);
727 0 : return 16;
728 : }
729 :
730 : template <class Transport_>
731 4738 : int32_t TBinaryProtocolT<Transport_>::readStringBody(std::string& str,
732 : int32_t size) {
733 4738 : int32_t result = 0;
734 :
735 : // Catch error cases
736 4738 : if (size < 0) {
737 0 : LOG(ERROR, __func__ << ": Negative size " << size);
738 0 : return -1;
739 : }
740 4738 : if (this->string_limit_ > 0 && size > this->string_limit_) {
741 0 : LOG(ERROR, __func__ << ": Size " << size << " greater than limit "
742 : << this->string_limit_);
743 0 : return -1;
744 : }
745 :
746 : // Catch empty string case
747 4738 : if (size == 0) {
748 32 : str = "";
749 32 : return result;
750 : }
751 :
752 : // Try to borrow first
753 : const uint8_t* borrow_buf;
754 4706 : uint32_t got = size;
755 4706 : if ((borrow_buf = this->trans_->borrow(NULL, &got))) {
756 4706 : str.assign((const char*)borrow_buf, size);
757 4706 : this->trans_->consume(size);
758 4706 : return size;
759 : }
760 :
761 : // Use the heap here to prevent stack overflow for v. large strings
762 0 : if (size > this->string_buf_size_ || this->string_buf_ == NULL) {
763 0 : void* new_string_buf = std::realloc(this->string_buf_, (uint32_t)size);
764 0 : if (new_string_buf == NULL) {
765 0 : LOG(ERROR, __func__ << ": Realloc size " << (uint32_t)size << " FAILED");
766 0 : return -1;
767 : }
768 0 : this->string_buf_ = (uint8_t*)new_string_buf;
769 0 : this->string_buf_size_ = size;
770 : }
771 0 : this->trans_->readAll(this->string_buf_, size);
772 0 : str = std::string((char*)this->string_buf_, size);
773 0 : return size;
774 : }
775 :
776 : }}} // contrail::sandesh::protocol
777 :
778 : #endif // #ifndef _SANDESH_PROTOCOL_TBINARYPROTOCOL_TCC_
|