blob: 8e39117060c2b1dd8d3588fa82c9bc8928af966f [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 *
19 * @author David Reiss <dreiss@facebook.com>
20 */
21
David Reissd779cbe2007-08-31 01:42:55 +000022namespace facebook { namespace thrift { namespace reflection { namespace local {
23
24using facebook::thrift::protocol::TType;
25
David Reissce161a92007-09-11 22:09:42 +000026// We include this many bytes of the structure's fingerprint when serializing
27// a top-level structure. Long enough to make collisions unlikely, short
28// enough to not significantly affect the amount of memory used.
29const int FP_PREFIX_LEN = 4;
David Reissd779cbe2007-08-31 01:42:55 +000030
David Reiss47557bc2007-09-04 21:31:04 +000031struct FieldMeta {
David Reiss4e7530d2007-09-04 21:49:53 +000032 int16_t tag;
David Reiss47557bc2007-09-04 21:31:04 +000033 bool is_optional;
34};
35
David Reissd779cbe2007-08-31 01:42:55 +000036struct TypeSpec {
David Reissce161a92007-09-11 22:09:42 +000037 TType ttype;
38 uint8_t fp_prefix[FP_PREFIX_LEN];
39
David Reissd779cbe2007-08-31 01:42:55 +000040 // Use an anonymous union here so we can fit two TypeSpecs in one cache line.
41 union {
42 struct {
43 // Use parallel arrays here for denser packing (of the arrays).
David Reiss47557bc2007-09-04 21:31:04 +000044 FieldMeta* metas;
David Reissd779cbe2007-08-31 01:42:55 +000045 TypeSpec** specs;
David Reissd779cbe2007-08-31 01:42:55 +000046 } tstruct;
47 struct {
48 TypeSpec *subtype1;
49 TypeSpec *subtype2;
50 } tcontainer;
51 };
52
David Reissd779cbe2007-08-31 01:42:55 +000053 // Static initialization of unions isn't really possible,
54 // so take the plunge and use constructors.
55 // Hopefully they'll be evaluated at compile time.
56
David Reissce161a92007-09-11 22:09:42 +000057 TypeSpec(TType ttype) : ttype(ttype) {
58 std::memset(fp_prefix, 0, FP_PREFIX_LEN);
59 }
David Reissd779cbe2007-08-31 01:42:55 +000060
David Reissce161a92007-09-11 22:09:42 +000061 TypeSpec(TType ttype,
David Reiss2b9ddab2007-10-17 03:39:55 +000062 const uint8_t* fingerprint,
David Reissce161a92007-09-11 22:09:42 +000063 FieldMeta* metas,
64 TypeSpec** specs) :
David Reissd779cbe2007-08-31 01:42:55 +000065 ttype(ttype)
66 {
David Reissce161a92007-09-11 22:09:42 +000067 std::memcpy(fp_prefix, fingerprint, FP_PREFIX_LEN);
David Reiss47557bc2007-09-04 21:31:04 +000068 tstruct.metas = metas;
David Reissd779cbe2007-08-31 01:42:55 +000069 tstruct.specs = specs;
70 }
71
72 TypeSpec(TType ttype, TypeSpec* subtype1, TypeSpec* subtype2) :
73 ttype(ttype)
74 {
David Reissce161a92007-09-11 22:09:42 +000075 std::memset(fp_prefix, 0, FP_PREFIX_LEN);
David Reissd779cbe2007-08-31 01:42:55 +000076 tcontainer.subtype1 = subtype1;
77 tcontainer.subtype2 = subtype2;
78 }
79
80};
81
82}}}} // facebook::thrift::reflection::local
83
84#endif // #ifndef _THRIFT_TREFLECTIONLOCAL_H_