blob: 0dd60d8109fd4fede027971aaf9797dfe91d6f63 [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
17namespace facebook { namespace thrift { namespace protocol {
18
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();
76
77 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
107
108 private:
109 void indentUp();
110 void indentDown();
111 uint32_t writePlain(const std::string& str);
112 uint32_t writeIndented(const std::string& str);
113 uint32_t startItem();
114 uint32_t endItem();
115 uint32_t writeItem(const std::string& str);
116
117 static std::string fieldTypeName(TType type);
118
119 std::string indent_str_;
120 static const int indent_inc = 2;
121
122 std::vector<write_state_t> write_state_;
123 std::vector<int> list_idx_;
124};
125
126/**
127 * Constructs debug protocol handlers
128 */
129class TDebugProtocolFactory : public TProtocolFactory {
130 public:
131 TDebugProtocolFactory() {}
132 virtual ~TDebugProtocolFactory() {}
133
134 boost::shared_ptr<TProtocol> getProtocol(boost::shared_ptr<TTransport> trans) {
135 return boost::shared_ptr<TProtocol>(new TDebugProtocol(trans));
136 }
137
138};
139
140}}} // facebook::thrift::protocol
141
142
143namespace facebook { namespace thrift {
144
145template<typename ThriftStruct>
146std::string ThriftDebugString(const ThriftStruct& ts) {
147 using namespace facebook::thrift::transport;
148 using namespace facebook::thrift::protocol;
149 TMemoryBuffer* buffer = new TMemoryBuffer;
150 boost::shared_ptr<TTransport> trans(buffer);
151 TDebugProtocol protocol(trans);
152
153 ts.write(&protocol);
154
155 uint8_t* buf;
156 uint32_t size;
157 buffer->getBuffer(&buf, &size);
158 return std::string((char*)buf, (unsigned int)size);
159}
160
161// TODO(dreiss): This is badly broken. Don't use it unless you are me.
162#if 0
163template<typename Object>
164std::string DebugString(const std::vector<Object>& vec) {
165 using namespace facebook::thrift::transport;
166 using namespace facebook::thrift::protocol;
167 TMemoryBuffer* buffer = new TMemoryBuffer;
168 boost::shared_ptr<TTransport> trans(buffer);
169 TDebugProtocol protocol(trans);
170
171 // I am gross!
172 protocol.writeStructBegin("SomeRandomVector");
173
174 // TODO: Fix this with a trait.
175 protocol.writeListBegin((TType)99, vec.size());
176 typename std::vector<Object>::const_iterator it;
177 for (it = vec.begin(); it != vec.end(); ++it) {
178 it->write(&protocol);
179 }
180 protocol.writeListEnd();
181
182 uint8_t* buf;
183 uint32_t size;
184 buffer->getBuffer(&buf, &size);
185 return std::string((char*)buf, (unsigned int)size);
186}
187#endif // 0
188
189}} // facebook::thrift
190
191
192#endif // #ifndef _THRIFT_PROTOCOL_TDEBUGPROTOCOL_H_
193
194