blob: c1c8b59f38ef5749e6627e97ff662dd04a7bae37 [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
T Jake Lucianib5e62212009-01-31 22:36:20 +000015namespace apache { 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 *
David Reiss00dcccf2007-07-21 01:18:10 +000035 */
36class TDebugProtocol : public TWriteOnlyProtocol {
37 private:
David Reiss322e5952008-12-05 02:54:09 +000038 enum write_state_t
39 { UNINIT
40 , STRUCT
41 , LIST
42 , SET
43 , MAP_KEY
44 , MAP_VALUE
David Reiss00dcccf2007-07-21 01:18:10 +000045 };
46
47 public:
48 TDebugProtocol(boost::shared_ptr<TTransport> trans)
49 : TWriteOnlyProtocol(trans, "TDebugProtocol")
David Reissa80f0fb2008-04-08 05:06:15 +000050 , string_limit_(DEFAULT_STRING_LIMIT)
51 , string_prefix_size_(DEFAULT_STRING_PREFIX_SIZE)
David Reiss00dcccf2007-07-21 01:18:10 +000052 {
53 write_state_.push_back(UNINIT);
54 }
55
David Reissa80f0fb2008-04-08 05:06:15 +000056 static const int32_t DEFAULT_STRING_LIMIT = 256;
57 static const int32_t DEFAULT_STRING_PREFIX_SIZE = 16;
58
59 void setStringSizeLimit(int32_t string_limit) {
60 string_limit_ = string_limit;
61 }
62
63 void setStringPrefixSize(int32_t string_prefix_size) {
64 string_prefix_size_ = string_prefix_size;
65 }
66
David Reiss00dcccf2007-07-21 01:18:10 +000067
68 virtual uint32_t writeMessageBegin(const std::string& name,
69 const TMessageType messageType,
70 const int32_t seqid);
71
72 virtual uint32_t writeMessageEnd();
73
74
David Reiss64120002008-04-29 23:12:24 +000075 uint32_t writeStructBegin(const char* name);
David Reiss00dcccf2007-07-21 01:18:10 +000076
77 uint32_t writeStructEnd();
78
David Reiss64120002008-04-29 23:12:24 +000079 uint32_t writeFieldBegin(const char* name,
David Reiss00dcccf2007-07-21 01:18:10 +000080 const TType fieldType,
81 const int16_t fieldId);
82
83 uint32_t writeFieldEnd();
84
85 uint32_t writeFieldStop();
David Reiss0c90f6f2008-02-06 22:18:40 +000086
David Reiss00dcccf2007-07-21 01:18:10 +000087 uint32_t writeMapBegin(const TType keyType,
88 const TType valType,
89 const uint32_t size);
90
91 uint32_t writeMapEnd();
92
93 uint32_t writeListBegin(const TType elemType,
94 const uint32_t size);
95
96 uint32_t writeListEnd();
97
98 uint32_t writeSetBegin(const TType elemType,
99 const uint32_t size);
100
101 uint32_t writeSetEnd();
102
103 uint32_t writeBool(const bool value);
104
105 uint32_t writeByte(const int8_t byte);
106
107 uint32_t writeI16(const int16_t i16);
108
109 uint32_t writeI32(const int32_t i32);
110
111 uint32_t writeI64(const int64_t i64);
112
113 uint32_t writeDouble(const double dub);
114
115 uint32_t writeString(const std::string& str);
116
David Reissc005b1b2008-02-15 01:38:18 +0000117 uint32_t writeBinary(const std::string& str);
118
David Reiss00dcccf2007-07-21 01:18:10 +0000119
120 private:
121 void indentUp();
122 void indentDown();
123 uint32_t writePlain(const std::string& str);
124 uint32_t writeIndented(const std::string& str);
125 uint32_t startItem();
126 uint32_t endItem();
127 uint32_t writeItem(const std::string& str);
128
129 static std::string fieldTypeName(TType type);
130
David Reissa80f0fb2008-04-08 05:06:15 +0000131 int32_t string_limit_;
132 int32_t string_prefix_size_;
133
David Reiss00dcccf2007-07-21 01:18:10 +0000134 std::string indent_str_;
135 static const int indent_inc = 2;
136
137 std::vector<write_state_t> write_state_;
138 std::vector<int> list_idx_;
139};
140
141/**
142 * Constructs debug protocol handlers
143 */
144class TDebugProtocolFactory : public TProtocolFactory {
145 public:
146 TDebugProtocolFactory() {}
147 virtual ~TDebugProtocolFactory() {}
148
149 boost::shared_ptr<TProtocol> getProtocol(boost::shared_ptr<TTransport> trans) {
150 return boost::shared_ptr<TProtocol>(new TDebugProtocol(trans));
151 }
152
153};
154
T Jake Lucianib5e62212009-01-31 22:36:20 +0000155}}} // apache::thrift::protocol
David Reiss00dcccf2007-07-21 01:18:10 +0000156
157
David Reiss28f298d2008-05-01 06:17:36 +0000158// TODO(dreiss): Move (part of) ThriftDebugString into a .cpp file and remove this.
159#include <transport/TBufferTransports.h>
160
T Jake Lucianib5e62212009-01-31 22:36:20 +0000161namespace apache { namespace thrift {
David Reiss00dcccf2007-07-21 01:18:10 +0000162
163template<typename ThriftStruct>
164std::string ThriftDebugString(const ThriftStruct& ts) {
T Jake Lucianib5e62212009-01-31 22:36:20 +0000165 using namespace apache::thrift::transport;
166 using namespace apache::thrift::protocol;
David Reiss00dcccf2007-07-21 01:18:10 +0000167 TMemoryBuffer* buffer = new TMemoryBuffer;
168 boost::shared_ptr<TTransport> trans(buffer);
169 TDebugProtocol protocol(trans);
170
171 ts.write(&protocol);
172
173 uint8_t* buf;
174 uint32_t size;
175 buffer->getBuffer(&buf, &size);
176 return std::string((char*)buf, (unsigned int)size);
177}
178
179// TODO(dreiss): This is badly broken. Don't use it unless you are me.
180#if 0
181template<typename Object>
182std::string DebugString(const std::vector<Object>& vec) {
T Jake Lucianib5e62212009-01-31 22:36:20 +0000183 using namespace apache::thrift::transport;
184 using namespace apache::thrift::protocol;
David Reiss00dcccf2007-07-21 01:18:10 +0000185 TMemoryBuffer* buffer = new TMemoryBuffer;
186 boost::shared_ptr<TTransport> trans(buffer);
187 TDebugProtocol protocol(trans);
188
189 // I am gross!
190 protocol.writeStructBegin("SomeRandomVector");
191
192 // TODO: Fix this with a trait.
193 protocol.writeListBegin((TType)99, vec.size());
194 typename std::vector<Object>::const_iterator it;
195 for (it = vec.begin(); it != vec.end(); ++it) {
196 it->write(&protocol);
197 }
198 protocol.writeListEnd();
199
200 uint8_t* buf;
201 uint32_t size;
202 buffer->getBuffer(&buf, &size);
203 return std::string((char*)buf, (unsigned int)size);
204}
205#endif // 0
206
T Jake Lucianib5e62212009-01-31 22:36:20 +0000207}} // apache::thrift
David Reiss00dcccf2007-07-21 01:18:10 +0000208
209
210#endif // #ifndef _THRIFT_PROTOCOL_TDEBUGPROTOCOL_H_
211
212