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