blob: 196cff2094ab7afa1079ab67b88628715186d2b4 [file] [log] [blame]
David Reiss00dcccf2007-07-21 01:18:10 +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_PROTOCOL_TDEBUGPROTOCOL_H_
8#define _THRIFT_PROTOCOL_TDEBUGPROTOCOL_H_ 1
9
10#include "TProtocol.h"
11#include "TOneWayProtocol.h"
12
13#include <boost/shared_ptr.hpp>
14
15#include <transport/TTransportUtils.h>
16
David Reiss0c90f6f2008-02-06 22:18:40 +000017namespace facebook { namespace thrift { namespace protocol {
David Reiss00dcccf2007-07-21 01:18:10 +000018
19/*
20
21!!! EXPERIMENTAL CODE !!!
22
23This protocol is very much a work in progress.
24It doesn't handle many cases properly.
25It throws exceptions in many cases.
26It probably segfaults in many cases.
27Bug reports and feature requests are welcome.
28Complaints are not. :R
29
30*/
31
32
33/**
34 * Protocol that prints the payload in a nice human-readable format.
35 * Reading from this protocol is not supported.
36 *
37 * @author David Reiss <dreiss@facebook.com>
38 */
39class TDebugProtocol : public TWriteOnlyProtocol {
40 private:
41 enum write_state_t {
42 UNINIT,
43 STRUCT,
44 LIST,
45 SET,
46 MAP_KEY,
47 MAP_VALUE,
48 };
49
50 public:
51 TDebugProtocol(boost::shared_ptr<TTransport> trans)
52 : TWriteOnlyProtocol(trans, "TDebugProtocol")
53 {
54 write_state_.push_back(UNINIT);
55 }
56
57
58 virtual uint32_t writeMessageBegin(const std::string& name,
59 const TMessageType messageType,
60 const int32_t seqid);
61
62 virtual uint32_t writeMessageEnd();
63
64
65 uint32_t writeStructBegin(const std::string& name);
66
67 uint32_t writeStructEnd();
68
69 uint32_t writeFieldBegin(const std::string& name,
70 const TType fieldType,
71 const int16_t fieldId);
72
73 uint32_t writeFieldEnd();
74
75 uint32_t writeFieldStop();
David Reiss0c90f6f2008-02-06 22:18:40 +000076
David Reiss00dcccf2007-07-21 01:18:10 +000077 uint32_t writeMapBegin(const TType keyType,
78 const TType valType,
79 const uint32_t size);
80
81 uint32_t writeMapEnd();
82
83 uint32_t writeListBegin(const TType elemType,
84 const uint32_t size);
85
86 uint32_t writeListEnd();
87
88 uint32_t writeSetBegin(const TType elemType,
89 const uint32_t size);
90
91 uint32_t writeSetEnd();
92
93 uint32_t writeBool(const bool value);
94
95 uint32_t writeByte(const int8_t byte);
96
97 uint32_t writeI16(const int16_t i16);
98
99 uint32_t writeI32(const int32_t i32);
100
101 uint32_t writeI64(const int64_t i64);
102
103 uint32_t writeDouble(const double dub);
104
105 uint32_t writeString(const std::string& str);
106
David Reissc005b1b2008-02-15 01:38:18 +0000107 uint32_t writeBinary(const std::string& str);
108
David Reiss00dcccf2007-07-21 01:18:10 +0000109
110 private:
111 void indentUp();
112 void indentDown();
113 uint32_t writePlain(const std::string& str);
114 uint32_t writeIndented(const std::string& str);
115 uint32_t startItem();
116 uint32_t endItem();
117 uint32_t writeItem(const std::string& str);
118
119 static std::string fieldTypeName(TType type);
120
121 std::string indent_str_;
122 static const int indent_inc = 2;
123
124 std::vector<write_state_t> write_state_;
125 std::vector<int> list_idx_;
126};
127
128/**
129 * Constructs debug protocol handlers
130 */
131class TDebugProtocolFactory : public TProtocolFactory {
132 public:
133 TDebugProtocolFactory() {}
134 virtual ~TDebugProtocolFactory() {}
135
136 boost::shared_ptr<TProtocol> getProtocol(boost::shared_ptr<TTransport> trans) {
137 return boost::shared_ptr<TProtocol>(new TDebugProtocol(trans));
138 }
139
140};
141
142}}} // facebook::thrift::protocol
143
144
David Reiss0c90f6f2008-02-06 22:18:40 +0000145namespace facebook { namespace thrift {
David Reiss00dcccf2007-07-21 01:18:10 +0000146
147template<typename ThriftStruct>
148std::string ThriftDebugString(const ThriftStruct& ts) {
149 using namespace facebook::thrift::transport;
150 using namespace facebook::thrift::protocol;
151 TMemoryBuffer* buffer = new TMemoryBuffer;
152 boost::shared_ptr<TTransport> trans(buffer);
153 TDebugProtocol protocol(trans);
154
155 ts.write(&protocol);
156
157 uint8_t* buf;
158 uint32_t size;
159 buffer->getBuffer(&buf, &size);
160 return std::string((char*)buf, (unsigned int)size);
161}
162
163// TODO(dreiss): This is badly broken. Don't use it unless you are me.
164#if 0
165template<typename Object>
166std::string DebugString(const std::vector<Object>& vec) {
167 using namespace facebook::thrift::transport;
168 using namespace facebook::thrift::protocol;
169 TMemoryBuffer* buffer = new TMemoryBuffer;
170 boost::shared_ptr<TTransport> trans(buffer);
171 TDebugProtocol protocol(trans);
172
173 // I am gross!
174 protocol.writeStructBegin("SomeRandomVector");
175
176 // TODO: Fix this with a trait.
177 protocol.writeListBegin((TType)99, vec.size());
178 typename std::vector<Object>::const_iterator it;
179 for (it = vec.begin(); it != vec.end(); ++it) {
180 it->write(&protocol);
181 }
182 protocol.writeListEnd();
183
184 uint8_t* buf;
185 uint32_t size;
186 buffer->getBuffer(&buf, &size);
187 return std::string((char*)buf, (unsigned int)size);
188}
189#endif // 0
190
191}} // facebook::thrift
192
193
194#endif // #ifndef _THRIFT_PROTOCOL_TDEBUGPROTOCOL_H_
195
196