blob: e9e76ac9da13634791115e8c9caf7daf9138364e [file] [log] [blame]
David Reissd779cbe2007-08-31 01:42:55 +00001// Copyright (c) 2006- Facebook
2// Distributed under the Thrift Software License
3//
4// See accompanying file LICENSE or visit the Thrift site at:
5// http://developers.facebook.com/thrift/
6
7#ifndef _THRIFT_TREFLECTIONLOCAL_H_
8#define _THRIFT_TREFLECTIONLOCAL_H_ 1
9
10#include <stdint.h>
David Reissce161a92007-09-11 22:09:42 +000011#include <cstring>
David Reissd779cbe2007-08-31 01:42:55 +000012#include <protocol/TProtocol.h>
13
David Reissce161a92007-09-11 22:09:42 +000014/**
15 * Local Reflection is a blanket term referring to the the structure
16 * and generation of this particular representation of Thrift types.
17 * (It is called local because it cannot be serialized by Thrift).
18 *
David Reissce161a92007-09-11 22:09:42 +000019 */
20
T Jake Lucianib5e62212009-01-31 22:36:20 +000021namespace apache { namespace thrift { namespace reflection { namespace local {
David Reissd779cbe2007-08-31 01:42:55 +000022
T Jake Lucianib5e62212009-01-31 22:36:20 +000023using apache::thrift::protocol::TType;
David Reissd779cbe2007-08-31 01:42:55 +000024
David Reissce161a92007-09-11 22:09:42 +000025// We include this many bytes of the structure's fingerprint when serializing
26// a top-level structure. Long enough to make collisions unlikely, short
27// enough to not significantly affect the amount of memory used.
28const int FP_PREFIX_LEN = 4;
David Reissd779cbe2007-08-31 01:42:55 +000029
David Reiss47557bc2007-09-04 21:31:04 +000030struct FieldMeta {
David Reiss4e7530d2007-09-04 21:49:53 +000031 int16_t tag;
David Reiss47557bc2007-09-04 21:31:04 +000032 bool is_optional;
33};
34
David Reissd779cbe2007-08-31 01:42:55 +000035struct TypeSpec {
David Reissce161a92007-09-11 22:09:42 +000036 TType ttype;
37 uint8_t fp_prefix[FP_PREFIX_LEN];
38
David Reissd779cbe2007-08-31 01:42:55 +000039 // Use an anonymous union here so we can fit two TypeSpecs in one cache line.
40 union {
41 struct {
42 // Use parallel arrays here for denser packing (of the arrays).
David Reiss47557bc2007-09-04 21:31:04 +000043 FieldMeta* metas;
David Reissd779cbe2007-08-31 01:42:55 +000044 TypeSpec** specs;
David Reissd779cbe2007-08-31 01:42:55 +000045 } tstruct;
46 struct {
47 TypeSpec *subtype1;
48 TypeSpec *subtype2;
49 } tcontainer;
50 };
51
David Reissd779cbe2007-08-31 01:42:55 +000052 // Static initialization of unions isn't really possible,
53 // so take the plunge and use constructors.
54 // Hopefully they'll be evaluated at compile time.
55
David Reissce161a92007-09-11 22:09:42 +000056 TypeSpec(TType ttype) : ttype(ttype) {
57 std::memset(fp_prefix, 0, FP_PREFIX_LEN);
58 }
David Reissd779cbe2007-08-31 01:42:55 +000059
David Reissce161a92007-09-11 22:09:42 +000060 TypeSpec(TType ttype,
David Reiss2b9ddab2007-10-17 03:39:55 +000061 const uint8_t* fingerprint,
David Reissce161a92007-09-11 22:09:42 +000062 FieldMeta* metas,
63 TypeSpec** specs) :
David Reissd779cbe2007-08-31 01:42:55 +000064 ttype(ttype)
65 {
David Reissce161a92007-09-11 22:09:42 +000066 std::memcpy(fp_prefix, fingerprint, FP_PREFIX_LEN);
David Reiss47557bc2007-09-04 21:31:04 +000067 tstruct.metas = metas;
David Reissd779cbe2007-08-31 01:42:55 +000068 tstruct.specs = specs;
69 }
70
71 TypeSpec(TType ttype, TypeSpec* subtype1, TypeSpec* subtype2) :
72 ttype(ttype)
73 {
David Reissce161a92007-09-11 22:09:42 +000074 std::memset(fp_prefix, 0, FP_PREFIX_LEN);
David Reissd779cbe2007-08-31 01:42:55 +000075 tcontainer.subtype1 = subtype1;
76 tcontainer.subtype2 = subtype2;
77 }
78
79};
80
T Jake Lucianib5e62212009-01-31 22:36:20 +000081}}}} // apache::thrift::reflection::local
David Reissd779cbe2007-08-31 01:42:55 +000082
83#endif // #ifndef _THRIFT_TREFLECTIONLOCAL_H_