blob: 3f7877c0051c619623c825ac6e6a58313afb7525 [file] [log] [blame]
David Reissea2cba82009-03-30 21:35:00 +00001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
David Reiss00dcccf2007-07-21 01:18:10 +000019
20#ifndef _THRIFT_PROTOCOL_TDEBUGPROTOCOL_H_
21#define _THRIFT_PROTOCOL_TDEBUGPROTOCOL_H_ 1
22
David Reiss6806fb82010-10-06 17:09:52 +000023#include "TVirtualProtocol.h"
David Reiss00dcccf2007-07-21 01:18:10 +000024
25#include <boost/shared_ptr.hpp>
26
T Jake Lucianib5e62212009-01-31 22:36:20 +000027namespace apache { namespace thrift { namespace protocol {
David Reiss00dcccf2007-07-21 01:18:10 +000028
29/*
30
31!!! EXPERIMENTAL CODE !!!
32
33This protocol is very much a work in progress.
34It doesn't handle many cases properly.
35It throws exceptions in many cases.
36It probably segfaults in many cases.
37Bug reports and feature requests are welcome.
38Complaints are not. :R
39
40*/
41
42
43/**
44 * Protocol that prints the payload in a nice human-readable format.
45 * Reading from this protocol is not supported.
46 *
David Reiss00dcccf2007-07-21 01:18:10 +000047 */
David Reiss6806fb82010-10-06 17:09:52 +000048class TDebugProtocol : public TVirtualProtocol<TDebugProtocol> {
David Reiss00dcccf2007-07-21 01:18:10 +000049 private:
David Reiss322e5952008-12-05 02:54:09 +000050 enum write_state_t
51 { UNINIT
52 , STRUCT
53 , LIST
54 , SET
55 , MAP_KEY
56 , MAP_VALUE
David Reiss00dcccf2007-07-21 01:18:10 +000057 };
58
59 public:
60 TDebugProtocol(boost::shared_ptr<TTransport> trans)
David Reiss6806fb82010-10-06 17:09:52 +000061 : TVirtualProtocol<TDebugProtocol>(trans)
David Reisse71115b2010-10-06 17:09:56 +000062 , trans_(trans.get())
David Reissa80f0fb2008-04-08 05:06:15 +000063 , string_limit_(DEFAULT_STRING_LIMIT)
64 , string_prefix_size_(DEFAULT_STRING_PREFIX_SIZE)
David Reiss00dcccf2007-07-21 01:18:10 +000065 {
66 write_state_.push_back(UNINIT);
67 }
68
David Reissa80f0fb2008-04-08 05:06:15 +000069 static const int32_t DEFAULT_STRING_LIMIT = 256;
70 static const int32_t DEFAULT_STRING_PREFIX_SIZE = 16;
71
72 void setStringSizeLimit(int32_t string_limit) {
73 string_limit_ = string_limit;
74 }
75
76 void setStringPrefixSize(int32_t string_prefix_size) {
77 string_prefix_size_ = string_prefix_size;
78 }
79
David Reiss00dcccf2007-07-21 01:18:10 +000080
David Reiss6806fb82010-10-06 17:09:52 +000081 uint32_t writeMessageBegin(const std::string& name,
82 const TMessageType messageType,
83 const int32_t seqid);
David Reiss00dcccf2007-07-21 01:18:10 +000084
David Reiss6806fb82010-10-06 17:09:52 +000085 uint32_t writeMessageEnd();
David Reiss00dcccf2007-07-21 01:18:10 +000086
87
David Reiss64120002008-04-29 23:12:24 +000088 uint32_t writeStructBegin(const char* name);
David Reiss00dcccf2007-07-21 01:18:10 +000089
90 uint32_t writeStructEnd();
91
David Reiss64120002008-04-29 23:12:24 +000092 uint32_t writeFieldBegin(const char* name,
David Reiss00dcccf2007-07-21 01:18:10 +000093 const TType fieldType,
94 const int16_t fieldId);
95
96 uint32_t writeFieldEnd();
97
98 uint32_t writeFieldStop();
David Reiss0c90f6f2008-02-06 22:18:40 +000099
David Reiss00dcccf2007-07-21 01:18:10 +0000100 uint32_t writeMapBegin(const TType keyType,
101 const TType valType,
102 const uint32_t size);
103
104 uint32_t writeMapEnd();
105
106 uint32_t writeListBegin(const TType elemType,
107 const uint32_t size);
108
109 uint32_t writeListEnd();
110
111 uint32_t writeSetBegin(const TType elemType,
112 const uint32_t size);
113
114 uint32_t writeSetEnd();
115
116 uint32_t writeBool(const bool value);
117
118 uint32_t writeByte(const int8_t byte);
119
120 uint32_t writeI16(const int16_t i16);
121
122 uint32_t writeI32(const int32_t i32);
123
124 uint32_t writeI64(const int64_t i64);
125
126 uint32_t writeDouble(const double dub);
127
128 uint32_t writeString(const std::string& str);
129
David Reissc005b1b2008-02-15 01:38:18 +0000130 uint32_t writeBinary(const std::string& str);
131
David Reiss00dcccf2007-07-21 01:18:10 +0000132
133 private:
134 void indentUp();
135 void indentDown();
136 uint32_t writePlain(const std::string& str);
137 uint32_t writeIndented(const std::string& str);
138 uint32_t startItem();
139 uint32_t endItem();
140 uint32_t writeItem(const std::string& str);
141
142 static std::string fieldTypeName(TType type);
143
David Reisse71115b2010-10-06 17:09:56 +0000144 TTransport* trans_;
145
David Reissa80f0fb2008-04-08 05:06:15 +0000146 int32_t string_limit_;
147 int32_t string_prefix_size_;
148
David Reiss00dcccf2007-07-21 01:18:10 +0000149 std::string indent_str_;
150 static const int indent_inc = 2;
151
152 std::vector<write_state_t> write_state_;
153 std::vector<int> list_idx_;
154};
155
156/**
157 * Constructs debug protocol handlers
158 */
159class TDebugProtocolFactory : public TProtocolFactory {
160 public:
161 TDebugProtocolFactory() {}
162 virtual ~TDebugProtocolFactory() {}
163
164 boost::shared_ptr<TProtocol> getProtocol(boost::shared_ptr<TTransport> trans) {
165 return boost::shared_ptr<TProtocol>(new TDebugProtocol(trans));
166 }
167
168};
169
T Jake Lucianib5e62212009-01-31 22:36:20 +0000170}}} // apache::thrift::protocol
David Reiss00dcccf2007-07-21 01:18:10 +0000171
172
David Reiss28f298d2008-05-01 06:17:36 +0000173// TODO(dreiss): Move (part of) ThriftDebugString into a .cpp file and remove this.
174#include <transport/TBufferTransports.h>
175
T Jake Lucianib5e62212009-01-31 22:36:20 +0000176namespace apache { namespace thrift {
David Reiss00dcccf2007-07-21 01:18:10 +0000177
178template<typename ThriftStruct>
179std::string ThriftDebugString(const ThriftStruct& ts) {
T Jake Lucianib5e62212009-01-31 22:36:20 +0000180 using namespace apache::thrift::transport;
181 using namespace apache::thrift::protocol;
David Reiss00dcccf2007-07-21 01:18:10 +0000182 TMemoryBuffer* buffer = new TMemoryBuffer;
183 boost::shared_ptr<TTransport> trans(buffer);
184 TDebugProtocol protocol(trans);
185
186 ts.write(&protocol);
187
188 uint8_t* buf;
189 uint32_t size;
190 buffer->getBuffer(&buf, &size);
191 return std::string((char*)buf, (unsigned int)size);
192}
193
194// TODO(dreiss): This is badly broken. Don't use it unless you are me.
195#if 0
196template<typename Object>
197std::string DebugString(const std::vector<Object>& vec) {
T Jake Lucianib5e62212009-01-31 22:36:20 +0000198 using namespace apache::thrift::transport;
199 using namespace apache::thrift::protocol;
David Reiss00dcccf2007-07-21 01:18:10 +0000200 TMemoryBuffer* buffer = new TMemoryBuffer;
201 boost::shared_ptr<TTransport> trans(buffer);
202 TDebugProtocol protocol(trans);
203
204 // I am gross!
205 protocol.writeStructBegin("SomeRandomVector");
206
207 // TODO: Fix this with a trait.
208 protocol.writeListBegin((TType)99, vec.size());
209 typename std::vector<Object>::const_iterator it;
210 for (it = vec.begin(); it != vec.end(); ++it) {
211 it->write(&protocol);
212 }
213 protocol.writeListEnd();
214
215 uint8_t* buf;
216 uint32_t size;
217 buffer->getBuffer(&buf, &size);
218 return std::string((char*)buf, (unsigned int)size);
219}
220#endif // 0
221
T Jake Lucianib5e62212009-01-31 22:36:20 +0000222}} // apache::thrift
David Reiss00dcccf2007-07-21 01:18:10 +0000223
224
225#endif // #ifndef _THRIFT_PROTOCOL_TDEBUGPROTOCOL_H_
226
227