Coverage Report

Created: 2022-08-24 06:40

/src/duckdb/third_party/thrift/thrift/protocol/TProtocol.h
Line
Count
Source (jump to first uncovered line)
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
#ifndef _DUCKDB_THRIFT_PROTOCOL_TPROTOCOL_H_
21
#define _DUCKDB_THRIFT_PROTOCOL_TPROTOCOL_H_ 1
22
23
#ifdef _WIN32
24
// Need to come before any Windows.h includes
25
#include <winsock2.h>
26
#endif
27
28
#include "thrift/transport/TTransport.h"
29
#include "thrift/protocol/TProtocolException.h"
30
31
#include <memory>
32
33
#ifdef HAVE_NETINET_IN_H
34
#include <netinet/in.h>
35
#endif
36
#include <sys/types.h>
37
#include <string>
38
#include <map>
39
#include <vector>
40
#include <climits>
41
42
// Use this to get around strict aliasing rules.
43
// For example, uint64_t i = bitwise_cast<uint64_t>(returns_double());
44
// The most obvious implementation is to just cast a pointer,
45
// but that doesn't work.
46
// For a pretty in-depth explanation of the problem, see
47
// http://cellperformance.beyond3d.com/articles/2006/06/understanding-strict-aliasing.html
48
namespace duckdb_apache { namespace thrift {
49
template <typename To, typename From>
50
0
static inline To bitwise_cast(From from) {
51
0
  static_assert(sizeof(From) == sizeof(To), "sizeof(From) == sizeof(To)");
52
53
  // BAD!!!  These are all broken with -O2.
54
  // return *reinterpret_cast<To*>(&from);  // BAD!!!
55
  // return *static_cast<To*>(static_cast<void*>(&from));  // BAD!!!
56
  // return *(To*)(void*)&from;  // BAD!!!
57
58
  // Super clean and paritally blessed by section 3.9 of the standard.
59
  // unsigned char c[sizeof(from)];
60
  // memcpy(c, &from, sizeof(from));
61
  // To to;
62
  // memcpy(&to, c, sizeof(c));
63
  // return to;
64
65
  // Slightly more questionable.
66
  // Same code emitted by GCC.
67
  // To to;
68
  // memcpy(&to, &from, sizeof(from));
69
  // return to;
70
71
  // Technically undefined, but almost universally supported,
72
  // and the most efficient implementation.
73
0
  union {
74
0
    From f;
75
0
    To t;
76
0
  } u;
77
0
  u.f = from;
78
0
  return u.t;
79
0
}
Unexecuted instantiation: parquet_reader.cpp:unsigned long duckdb_apache::thrift::bitwise_cast<unsigned long, double>(double)
Unexecuted instantiation: parquet_reader.cpp:double duckdb_apache::thrift::bitwise_cast<double, unsigned long>(unsigned long)
Unexecuted instantiation: parquet_writer.cpp:unsigned long duckdb_apache::thrift::bitwise_cast<unsigned long, double>(double)
Unexecuted instantiation: parquet_writer.cpp:double duckdb_apache::thrift::bitwise_cast<double, unsigned long>(unsigned long)
80
}} // namespace duckdb_apache::thrift
81
82
83
#ifdef HAVE_SYS_PARAM_H
84
#include <sys/param.h>
85
#endif
86
87
#ifndef __THRIFT_BYTE_ORDER
88
# if defined(BYTE_ORDER) && defined(LITTLE_ENDIAN) && defined(BIG_ENDIAN)
89
#  define __THRIFT_BYTE_ORDER BYTE_ORDER
90
#  define __THRIFT_LITTLE_ENDIAN LITTLE_ENDIAN
91
#  define __THRIFT_BIG_ENDIAN BIG_ENDIAN
92
# else
93
//#  include <boost/predef/other/endian.h>
94
#  if BOOST_ENDIAN_BIG_BYTE
95
#    define __THRIFT_BYTE_ORDER 4321
96
#    define __THRIFT_LITTLE_ENDIAN 0
97
#    define __THRIFT_BIG_ENDIAN __THRIFT_BYTE_ORDER
98
#  elif BOOST_ENDIAN_LITTLE_BYTE
99
#    define __THRIFT_BYTE_ORDER 1234
100
#    define __THRIFT_LITTLE_ENDIAN __THRIFT_BYTE_ORDER
101
#    define __THRIFT_BIG_ENDIAN 0
102
#  endif
103
#  ifdef BOOST_LITTLE_ENDIAN
104
#  else
105
#  endif
106
# endif
107
#endif
108
109
#if __THRIFT_BYTE_ORDER == __THRIFT_BIG_ENDIAN
110
# if !defined(THRIFT_ntohll)
111
#  define THRIFT_ntohll(n) (n)
112
#  define THRIFT_htonll(n) (n)
113
# endif
114
# if defined(__GNUC__) && defined(__GLIBC__)
115
#  include <byteswap.h>
116
#  define THRIFT_htolell(n) bswap_64(n)
117
#  define THRIFT_letohll(n) bswap_64(n)
118
#  define THRIFT_htolel(n) bswap_32(n)
119
#  define THRIFT_letohl(n) bswap_32(n)
120
#  define THRIFT_htoles(n) bswap_16(n)
121
#  define THRIFT_letohs(n) bswap_16(n)
122
# else /* GNUC & GLIBC */
123
#  define bswap_64(n) \
124
      ( (((n) & 0xff00000000000000ull) >> 56) \
125
      | (((n) & 0x00ff000000000000ull) >> 40) \
126
      | (((n) & 0x0000ff0000000000ull) >> 24) \
127
      | (((n) & 0x000000ff00000000ull) >> 8)  \
128
      | (((n) & 0x00000000ff000000ull) << 8)  \
129
      | (((n) & 0x0000000000ff0000ull) << 24) \
130
      | (((n) & 0x000000000000ff00ull) << 40) \
131
      | (((n) & 0x00000000000000ffull) << 56) )
132
#  define bswap_32(n) \
133
      ( (((n) & 0xff000000ul) >> 24) \
134
      | (((n) & 0x00ff0000ul) >> 8)  \
135
      | (((n) & 0x0000ff00ul) << 8)  \
136
      | (((n) & 0x000000fful) << 24) )
137
#  define bswap_16(n) \
138
      ( (((n) & ((unsigned short)0xff00ul)) >> 8)  \
139
      | (((n) & ((unsigned short)0x00fful)) << 8)  )
140
#  define THRIFT_htolell(n) bswap_64(n)
141
#  define THRIFT_letohll(n) bswap_64(n)
142
#  define THRIFT_htolel(n) bswap_32(n)
143
#  define THRIFT_letohl(n) bswap_32(n)
144
#  define THRIFT_htoles(n) bswap_16(n)
145
#  define THRIFT_letohs(n) bswap_16(n)
146
# endif /* GNUC & GLIBC */
147
#elif __THRIFT_BYTE_ORDER == __THRIFT_LITTLE_ENDIAN
148
0
#  define THRIFT_htolell(n) (n)
149
0
#  define THRIFT_letohll(n) (n)
150
#  define THRIFT_htolel(n) (n)
151
#  define THRIFT_letohl(n) (n)
152
#  define THRIFT_htoles(n) (n)
153
#  define THRIFT_letohs(n) (n)
154
# if defined(__GNUC__) && defined(__GLIBC__)
155
#  include <byteswap.h>
156
#  define THRIFT_ntohll(n) bswap_64(n)
157
#  define THRIFT_htonll(n) bswap_64(n)
158
# elif defined(_MSC_VER) /* Microsoft Visual C++ */
159
#  define THRIFT_ntohll(n) ( _byteswap_uint64((uint64_t)n) )
160
#  define THRIFT_htonll(n) ( _byteswap_uint64((uint64_t)n) )
161
# elif !defined(THRIFT_ntohll) /* Not GNUC/GLIBC or MSVC */
162
#  define THRIFT_ntohll(n) ( (((uint64_t)ntohl((uint32_t)n)) << 32) + ntohl((uint32_t)(n >> 32)) )
163
#  define THRIFT_htonll(n) ( (((uint64_t)htonl((uint32_t)n)) << 32) + htonl((uint32_t)(n >> 32)) )
164
# endif /* GNUC/GLIBC or MSVC or something else */
165
#else /* __THRIFT_BYTE_ORDER */
166
# error "Can't define THRIFT_htonll or THRIFT_ntohll!"
167
#endif
168
169
namespace duckdb_apache {
170
namespace thrift {
171
namespace protocol {
172
173
using duckdb_apache::thrift::transport::TTransport;
174
175
/**
176
 * Enumerated definition of the types that the Thrift protocol supports.
177
 * Take special note of the T_END type which is used specifically to mark
178
 * the end of a sequence of fields.
179
 */
180
enum TType {
181
  T_STOP       = 0,
182
  T_VOID       = 1,
183
  T_BOOL       = 2,
184
  T_BYTE       = 3,
185
  T_I08        = 3,
186
  T_I16        = 6,
187
  T_I32        = 8,
188
  T_U64        = 9,
189
  T_I64        = 10,
190
  T_DOUBLE     = 4,
191
  T_STRING     = 11,
192
  T_UTF7       = 11,
193
  T_STRUCT     = 12,
194
  T_MAP        = 13,
195
  T_SET        = 14,
196
  T_LIST       = 15,
197
  T_UTF8       = 16,
198
  T_UTF16      = 17
199
};
200
201
/**
202
 * Enumerated definition of the message types that the Thrift protocol
203
 * supports.
204
 */
205
enum TMessageType {
206
  T_CALL       = 1,
207
  T_REPLY      = 2,
208
  T_EXCEPTION  = 3,
209
  T_ONEWAY     = 4
210
};
211
212
static const uint32_t DEFAULT_RECURSION_LIMIT = 64;
213
214
/**
215
 * Abstract class for a thrift protocol driver. These are all the methods that
216
 * a protocol must implement. Essentially, there must be some way of reading
217
 * and writing all the base types, plus a mechanism for writing out structs
218
 * with indexed fields.
219
 *
220
 * TProtocol objects should not be shared across multiple encoding contexts,
221
 * as they may need to maintain internal state in some protocols (i.e. XML).
222
 * Note that is is acceptable for the TProtocol module to do its own internal
223
 * buffered reads/writes to the underlying TTransport where appropriate (i.e.
224
 * when parsing an input XML stream, reading should be batched rather than
225
 * looking ahead character by character for a close tag).
226
 *
227
 */
228
class TProtocol {
229
public:
230
  virtual ~TProtocol();
231
232
  /**
233
   * Writing functions.
234
   */
235
236
  virtual uint32_t writeMessageBegin_virt(const std::string& name,
237
                                          const TMessageType messageType,
238
                                          const int32_t seqid) = 0;
239
240
  virtual uint32_t writeMessageEnd_virt() = 0;
241
242
  virtual uint32_t writeStructBegin_virt(const char* name) = 0;
243
244
  virtual uint32_t writeStructEnd_virt() = 0;
245
246
  virtual uint32_t writeFieldBegin_virt(const char* name,
247
                                        const TType fieldType,
248
                                        const int16_t fieldId) = 0;
249
250
  virtual uint32_t writeFieldEnd_virt() = 0;
251
252
  virtual uint32_t writeFieldStop_virt() = 0;
253
254
  virtual uint32_t writeMapBegin_virt(const TType keyType, const TType valType, const uint32_t size)
255
      = 0;
256
257
  virtual uint32_t writeMapEnd_virt() = 0;
258
259
  virtual uint32_t writeListBegin_virt(const TType elemType, const uint32_t size) = 0;
260
261
  virtual uint32_t writeListEnd_virt() = 0;
262
263
  virtual uint32_t writeSetBegin_virt(const TType elemType, const uint32_t size) = 0;
264
265
  virtual uint32_t writeSetEnd_virt() = 0;
266
267
  virtual uint32_t writeBool_virt(const bool value) = 0;
268
269
  virtual uint32_t writeByte_virt(const int8_t byte) = 0;
270
271
  virtual uint32_t writeI16_virt(const int16_t i16) = 0;
272
273
  virtual uint32_t writeI32_virt(const int32_t i32) = 0;
274
275
  virtual uint32_t writeI64_virt(const int64_t i64) = 0;
276
277
  virtual uint32_t writeDouble_virt(const double dub) = 0;
278
279
  virtual uint32_t writeString_virt(const std::string& str) = 0;
280
281
  virtual uint32_t writeBinary_virt(const std::string& str) = 0;
282
283
  uint32_t writeMessageBegin(const std::string& name,
284
                             const TMessageType messageType,
285
0
                             const int32_t seqid) {
286
0
    T_VIRTUAL_CALL();
287
0
    return writeMessageBegin_virt(name, messageType, seqid);
288
0
  }
289
290
0
  uint32_t writeMessageEnd() {
291
0
    T_VIRTUAL_CALL();
292
0
    return writeMessageEnd_virt();
293
0
  }
294
295
0
  uint32_t writeStructBegin(const char* name) {
296
0
    T_VIRTUAL_CALL();
297
0
    return writeStructBegin_virt(name);
298
0
  }
299
300
0
  uint32_t writeStructEnd() {
301
0
    T_VIRTUAL_CALL();
302
0
    return writeStructEnd_virt();
303
0
  }
304
305
0
  uint32_t writeFieldBegin(const char* name, const TType fieldType, const int16_t fieldId) {
306
0
    T_VIRTUAL_CALL();
307
0
    return writeFieldBegin_virt(name, fieldType, fieldId);
308
0
  }
309
310
0
  uint32_t writeFieldEnd() {
311
0
    T_VIRTUAL_CALL();
312
0
    return writeFieldEnd_virt();
313
0
  }
314
315
0
  uint32_t writeFieldStop() {
316
0
    T_VIRTUAL_CALL();
317
0
    return writeFieldStop_virt();
318
0
  }
319
320
0
  uint32_t writeMapBegin(const TType keyType, const TType valType, const uint32_t size) {
321
0
    T_VIRTUAL_CALL();
322
0
    return writeMapBegin_virt(keyType, valType, size);
323
0
  }
324
325
0
  uint32_t writeMapEnd() {
326
0
    T_VIRTUAL_CALL();
327
0
    return writeMapEnd_virt();
328
0
  }
329
330
0
  uint32_t writeListBegin(const TType elemType, const uint32_t size) {
331
0
    T_VIRTUAL_CALL();
332
0
    return writeListBegin_virt(elemType, size);
333
0
  }
334
335
0
  uint32_t writeListEnd() {
336
0
    T_VIRTUAL_CALL();
337
0
    return writeListEnd_virt();
338
0
  }
339
340
0
  uint32_t writeSetBegin(const TType elemType, const uint32_t size) {
341
0
    T_VIRTUAL_CALL();
342
0
    return writeSetBegin_virt(elemType, size);
343
0
  }
344
345
0
  uint32_t writeSetEnd() {
346
0
    T_VIRTUAL_CALL();
347
0
    return writeSetEnd_virt();
348
0
  }
349
350
0
  uint32_t writeBool(const bool value) {
351
0
    T_VIRTUAL_CALL();
352
0
    return writeBool_virt(value);
353
0
  }
354
355
0
  uint32_t writeByte(const int8_t byte) {
356
0
    T_VIRTUAL_CALL();
357
0
    return writeByte_virt(byte);
358
0
  }
359
360
0
  uint32_t writeI16(const int16_t i16) {
361
0
    T_VIRTUAL_CALL();
362
0
    return writeI16_virt(i16);
363
0
  }
364
365
0
  uint32_t writeI32(const int32_t i32) {
366
0
    T_VIRTUAL_CALL();
367
0
    return writeI32_virt(i32);
368
0
  }
369
370
0
  uint32_t writeI64(const int64_t i64) {
371
0
    T_VIRTUAL_CALL();
372
0
    return writeI64_virt(i64);
373
0
  }
374
375
0
  uint32_t writeDouble(const double dub) {
376
0
    T_VIRTUAL_CALL();
377
0
    return writeDouble_virt(dub);
378
0
  }
379
380
0
  uint32_t writeString(const std::string& str) {
381
0
    T_VIRTUAL_CALL();
382
0
    return writeString_virt(str);
383
0
  }
384
385
0
  uint32_t writeBinary(const std::string& str) {
386
0
    T_VIRTUAL_CALL();
387
0
    return writeBinary_virt(str);
388
0
  }
389
390
  /**
391
   * Reading functions
392
   */
393
394
  virtual uint32_t readMessageBegin_virt(std::string& name,
395
                                         TMessageType& messageType,
396
                                         int32_t& seqid) = 0;
397
398
  virtual uint32_t readMessageEnd_virt() = 0;
399
400
  virtual uint32_t readStructBegin_virt(std::string& name) = 0;
401
402
  virtual uint32_t readStructEnd_virt() = 0;
403
404
  virtual uint32_t readFieldBegin_virt(std::string& name, TType& fieldType, int16_t& fieldId) = 0;
405
406
  virtual uint32_t readFieldEnd_virt() = 0;
407
408
  virtual uint32_t readMapBegin_virt(TType& keyType, TType& valType, uint32_t& size) = 0;
409
410
  virtual uint32_t readMapEnd_virt() = 0;
411
412
  virtual uint32_t readListBegin_virt(TType& elemType, uint32_t& size) = 0;
413
414
  virtual uint32_t readListEnd_virt() = 0;
415
416
  virtual uint32_t readSetBegin_virt(TType& elemType, uint32_t& size) = 0;
417
418
  virtual uint32_t readSetEnd_virt() = 0;
419
420
  virtual uint32_t readBool_virt(bool& value) = 0;
421
422
  virtual uint32_t readBool_virt(std::vector<bool>::reference value) = 0;
423
424
  virtual uint32_t readByte_virt(int8_t& byte) = 0;
425
426
  virtual uint32_t readI16_virt(int16_t& i16) = 0;
427
428
  virtual uint32_t readI32_virt(int32_t& i32) = 0;
429
430
  virtual uint32_t readI64_virt(int64_t& i64) = 0;
431
432
  virtual uint32_t readDouble_virt(double& dub) = 0;
433
434
  virtual uint32_t readString_virt(std::string& str) = 0;
435
436
  virtual uint32_t readBinary_virt(std::string& str) = 0;
437
438
0
  uint32_t readMessageBegin(std::string& name, TMessageType& messageType, int32_t& seqid) {
439
0
    T_VIRTUAL_CALL();
440
0
    return readMessageBegin_virt(name, messageType, seqid);
441
0
  }
442
443
0
  uint32_t readMessageEnd() {
444
0
    T_VIRTUAL_CALL();
445
0
    return readMessageEnd_virt();
446
0
  }
447
448
0
  uint32_t readStructBegin(std::string& name) {
449
0
    T_VIRTUAL_CALL();
450
0
    return readStructBegin_virt(name);
451
0
  }
452
453
0
  uint32_t readStructEnd() {
454
0
    T_VIRTUAL_CALL();
455
0
    return readStructEnd_virt();
456
0
  }
457
458
0
  uint32_t readFieldBegin(std::string& name, TType& fieldType, int16_t& fieldId) {
459
0
    T_VIRTUAL_CALL();
460
0
    return readFieldBegin_virt(name, fieldType, fieldId);
461
0
  }
462
463
0
  uint32_t readFieldEnd() {
464
0
    T_VIRTUAL_CALL();
465
0
    return readFieldEnd_virt();
466
0
  }
467
468
0
  uint32_t readMapBegin(TType& keyType, TType& valType, uint32_t& size) {
469
0
    T_VIRTUAL_CALL();
470
0
    return readMapBegin_virt(keyType, valType, size);
471
0
  }
472
473
0
  uint32_t readMapEnd() {
474
0
    T_VIRTUAL_CALL();
475
0
    return readMapEnd_virt();
476
0
  }
477
478
0
  uint32_t readListBegin(TType& elemType, uint32_t& size) {
479
0
    T_VIRTUAL_CALL();
480
0
    return readListBegin_virt(elemType, size);
481
0
  }
482
483
0
  uint32_t readListEnd() {
484
0
    T_VIRTUAL_CALL();
485
0
    return readListEnd_virt();
486
0
  }
487
488
0
  uint32_t readSetBegin(TType& elemType, uint32_t& size) {
489
0
    T_VIRTUAL_CALL();
490
0
    return readSetBegin_virt(elemType, size);
491
0
  }
492
493
0
  uint32_t readSetEnd() {
494
0
    T_VIRTUAL_CALL();
495
0
    return readSetEnd_virt();
496
0
  }
497
498
0
  uint32_t readBool(bool& value) {
499
0
    T_VIRTUAL_CALL();
500
0
    return readBool_virt(value);
501
0
  }
502
503
0
  uint32_t readByte(int8_t& byte) {
504
0
    T_VIRTUAL_CALL();
505
0
    return readByte_virt(byte);
506
0
  }
507
508
0
  uint32_t readI16(int16_t& i16) {
509
0
    T_VIRTUAL_CALL();
510
0
    return readI16_virt(i16);
511
0
  }
512
513
0
  uint32_t readI32(int32_t& i32) {
514
0
    T_VIRTUAL_CALL();
515
0
    return readI32_virt(i32);
516
0
  }
517
518
0
  uint32_t readI64(int64_t& i64) {
519
0
    T_VIRTUAL_CALL();
520
0
    return readI64_virt(i64);
521
0
  }
522
523
0
  uint32_t readDouble(double& dub) {
524
0
    T_VIRTUAL_CALL();
525
0
    return readDouble_virt(dub);
526
0
  }
527
528
0
  uint32_t readString(std::string& str) {
529
0
    T_VIRTUAL_CALL();
530
0
    return readString_virt(str);
531
0
  }
532
533
0
  uint32_t readBinary(std::string& str) {
534
0
    T_VIRTUAL_CALL();
535
0
    return readBinary_virt(str);
536
0
  }
537
538
  /*
539
   * std::vector is specialized for bool, and its elements are individual bits
540
   * rather than bools.   We need to define a different version of readBool()
541
   * to work with std::vector<bool>.
542
   */
543
0
  uint32_t readBool(std::vector<bool>::reference value) {
544
0
    T_VIRTUAL_CALL();
545
0
    return readBool_virt(value);
546
0
  }
547
548
  /**
549
   * Method to arbitrarily skip over data.
550
   */
551
0
  uint32_t skip(TType type) {
552
0
    T_VIRTUAL_CALL();
553
0
    return skip_virt(type);
554
0
  }
555
  virtual uint32_t skip_virt(TType type);
556
557
0
  inline std::shared_ptr<TTransport> getTransport() { return ptrans_; }
558
559
  // TODO: remove these two calls, they are for backwards
560
  // compatibility
561
0
  inline std::shared_ptr<TTransport> getInputTransport() { return ptrans_; }
562
0
  inline std::shared_ptr<TTransport> getOutputTransport() { return ptrans_; }
563
564
  // input and output recursion depth are kept separate so that one protocol
565
  // can be used concurrently for both input and output.
566
0
  void incrementInputRecursionDepth() {
567
0
    if (recursion_limit_ < ++input_recursion_depth_) {
568
0
      throw TProtocolException(TProtocolException::DEPTH_LIMIT);
569
0
    }
570
0
  }
571
0
  void decrementInputRecursionDepth() { --input_recursion_depth_; }
572
573
0
  void incrementOutputRecursionDepth() {
574
0
    if (recursion_limit_ < ++output_recursion_depth_) {
575
0
      throw TProtocolException(TProtocolException::DEPTH_LIMIT);
576
0
    }
577
0
  }
578
0
  void decrementOutputRecursionDepth() { --output_recursion_depth_; }
579
580
0
  uint32_t getRecursionLimit() const {return recursion_limit_;}
581
0
  void setRecurisionLimit(uint32_t depth) {recursion_limit_ = depth;}
582
583
protected:
584
  TProtocol(std::shared_ptr<TTransport> ptrans)
585
    : ptrans_(ptrans), input_recursion_depth_(0), output_recursion_depth_(0), recursion_limit_(DEFAULT_RECURSION_LIMIT)
586
0
  {}
587
588
  std::shared_ptr<TTransport> ptrans_;
589
590
private:
591
  TProtocol() = default;
592
  uint32_t input_recursion_depth_;
593
  uint32_t output_recursion_depth_;
594
  uint32_t recursion_limit_;
595
};
596
597
/**
598
 * Constructs input and output protocol objects given transports.
599
 */
600
class TProtocolFactory {
601
public:
602
0
  TProtocolFactory() = default;
603
604
  virtual ~TProtocolFactory();
605
606
  virtual std::shared_ptr<TProtocol> getProtocol(std::shared_ptr<TTransport> trans) = 0;
607
  virtual std::shared_ptr<TProtocol> getProtocol(std::shared_ptr<TTransport> inTrans,
608
0
               std::shared_ptr<TTransport> outTrans) {
609
0
    (void)outTrans;
610
0
    return getProtocol(inTrans);
611
0
  }
612
};
613
614
/**
615
 * Dummy protocol class.
616
 *
617
 * This class does nothing, and should never be instantiated.
618
 * It is used only by the generator code.
619
 */
620
class TDummyProtocol : public TProtocol {};
621
622
623
// HM: this is sub-optimal since it creates a depencency even for memory-only struct
624
//// This is the default / legacy choice
625
//struct TNetworkBigEndian
626
//{
627
//  static uint16_t toWire16(uint16_t x)   {return htons(x);}
628
//  static uint32_t toWire32(uint32_t x)   {return htonl(x);}
629
//  static uint64_t toWire64(uint64_t x)   {return THRIFT_htonll(x);}
630
//  static uint16_t fromWire16(uint16_t x) {return ntohs(x);}
631
//  static uint32_t fromWire32(uint32_t x) {return ntohl(x);}
632
//  static uint64_t fromWire64(uint64_t x) {return THRIFT_ntohll(x);}
633
//};
634
//
635
//// On most systems, this will be a bit faster than TNetworkBigEndian
636
//struct TNetworkLittleEndian
637
//{
638
//  static uint16_t toWire16(uint16_t x)   {return THRIFT_htoles(x);}
639
//  static uint32_t toWire32(uint32_t x)   {return THRIFT_htolel(x);}
640
//  static uint64_t toWire64(uint64_t x)   {return THRIFT_htolell(x);}
641
//  static uint16_t fromWire16(uint16_t x) {return THRIFT_letohs(x);}
642
//  static uint32_t fromWire32(uint32_t x) {return THRIFT_letohl(x);}
643
//  static uint64_t fromWire64(uint64_t x) {return THRIFT_letohll(x);}
644
//};
645
646
struct TOutputRecursionTracker {
647
  TProtocol &prot_;
648
0
  TOutputRecursionTracker(TProtocol &prot) : prot_(prot) {
649
0
    prot_.incrementOutputRecursionDepth();
650
0
  }
651
0
  ~TOutputRecursionTracker() {
652
0
    prot_.decrementOutputRecursionDepth();
653
0
  }
654
};
655
656
struct TInputRecursionTracker {
657
  TProtocol &prot_;
658
0
  TInputRecursionTracker(TProtocol &prot) : prot_(prot) {
659
0
    prot_.incrementInputRecursionDepth();
660
0
  }
661
0
  ~TInputRecursionTracker() {
662
0
    prot_.decrementInputRecursionDepth();
663
0
  }
664
};
665
666
/**
667
 * Helper template for implementing TProtocol::skip().
668
 *
669
 * Templatized to avoid having to make virtual function calls.
670
 */
671
template <class Protocol_>
672
0
uint32_t skip(Protocol_& prot, TType type) {
673
0
  TInputRecursionTracker tracker(prot);
674
675
0
  switch (type) {
676
0
  case T_BOOL: {
677
0
    bool boolv;
678
0
    return prot.readBool(boolv);
679
0
  }
680
0
  case T_BYTE: {
681
0
    int8_t bytev = 0;
682
0
    return prot.readByte(bytev);
683
0
  }
684
0
  case T_I16: {
685
0
    int16_t i16;
686
0
    return prot.readI16(i16);
687
0
  }
688
0
  case T_I32: {
689
0
    int32_t i32;
690
0
    return prot.readI32(i32);
691
0
  }
692
0
  case T_I64: {
693
0
    int64_t i64;
694
0
    return prot.readI64(i64);
695
0
  }
696
0
  case T_DOUBLE: {
697
0
    double dub;
698
0
    return prot.readDouble(dub);
699
0
  }
700
0
  case T_STRING: {
701
0
    std::string str;
702
0
    return prot.readBinary(str);
703
0
  }
704
0
  case T_STRUCT: {
705
0
    uint32_t result = 0;
706
0
    std::string name;
707
0
    int16_t fid;
708
0
    TType ftype;
709
0
    result += prot.readStructBegin(name);
710
0
    while (true) {
711
0
      result += prot.readFieldBegin(name, ftype, fid);
712
0
      if (ftype == T_STOP) {
713
0
        break;
714
0
      }
715
0
      result += skip(prot, ftype);
716
0
      result += prot.readFieldEnd();
717
0
    }
718
0
    result += prot.readStructEnd();
719
0
    return result;
720
0
  }
721
0
  case T_MAP: {
722
0
    uint32_t result = 0;
723
0
    TType keyType;
724
0
    TType valType;
725
0
    uint32_t i, size;
726
0
    result += prot.readMapBegin(keyType, valType, size);
727
0
    for (i = 0; i < size; i++) {
728
0
      result += skip(prot, keyType);
729
0
      result += skip(prot, valType);
730
0
    }
731
0
    result += prot.readMapEnd();
732
0
    return result;
733
0
  }
734
0
  case T_SET: {
735
0
    uint32_t result = 0;
736
0
    TType elemType;
737
0
    uint32_t i, size;
738
0
    result += prot.readSetBegin(elemType, size);
739
0
    for (i = 0; i < size; i++) {
740
0
      result += skip(prot, elemType);
741
0
    }
742
0
    result += prot.readSetEnd();
743
0
    return result;
744
0
  }
745
0
  case T_LIST: {
746
0
    uint32_t result = 0;
747
0
    TType elemType;
748
0
    uint32_t i, size;
749
0
    result += prot.readListBegin(elemType, size);
750
0
    for (i = 0; i < size; i++) {
751
0
      result += skip(prot, elemType);
752
0
    }
753
0
    result += prot.readListEnd();
754
0
    return result;
755
0
  }
756
0
  default:
757
0
    break;
758
0
  }
759
760
0
  throw TProtocolException(TProtocolException::INVALID_DATA,
761
0
                           "invalid TType");
762
0
}
Unexecuted instantiation: unsigned int duckdb_apache::thrift::protocol::skip<duckdb_apache::thrift::protocol::TProtocolDefaults>(duckdb_apache::thrift::protocol::TProtocolDefaults&, duckdb_apache::thrift::protocol::TType)
Unexecuted instantiation: unsigned int duckdb_apache::thrift::protocol::skip<duckdb_apache::thrift::protocol::TCompactProtocolT<duckdb::ThriftFileTransport> >(duckdb_apache::thrift::protocol::TCompactProtocolT<duckdb::ThriftFileTransport>&, duckdb_apache::thrift::protocol::TType)
Unexecuted instantiation: unsigned int duckdb_apache::thrift::protocol::skip<duckdb_apache::thrift::protocol::TCompactProtocolT<duckdb::MyTransport> >(duckdb_apache::thrift::protocol::TCompactProtocolT<duckdb::MyTransport>&, duckdb_apache::thrift::protocol::TType)
Unexecuted instantiation: unsigned int duckdb_apache::thrift::protocol::skip<duckdb_apache::thrift::protocol::TCompactProtocolT<duckdb_apache::thrift::transport::TTransport> >(duckdb_apache::thrift::protocol::TCompactProtocolT<duckdb_apache::thrift::transport::TTransport>&, duckdb_apache::thrift::protocol::TType)
Unexecuted instantiation: unsigned int duckdb_apache::thrift::protocol::skip<duckdb_apache::thrift::protocol::TProtocol>(duckdb_apache::thrift::protocol::TProtocol&, duckdb_apache::thrift::protocol::TType)
763
764
}}} // duckdb_apache::thrift::protocol
765
766
#endif // #define _DUCKDB_THRIFT_PROTOCOL_TPROTOCOL_H_ 1