blob: 1efcbd0a374731efdebe4dc5bccf2c02fc3e52a0 [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 Reissa80f0fb2008-04-08 05:06:15 +000062 , string_limit_(DEFAULT_STRING_LIMIT)
63 , string_prefix_size_(DEFAULT_STRING_PREFIX_SIZE)
David Reiss00dcccf2007-07-21 01:18:10 +000064 {
65 write_state_.push_back(UNINIT);
66 }
67
David Reissa80f0fb2008-04-08 05:06:15 +000068 static const int32_t DEFAULT_STRING_LIMIT = 256;
69 static const int32_t DEFAULT_STRING_PREFIX_SIZE = 16;
70
71 void setStringSizeLimit(int32_t string_limit) {
72 string_limit_ = string_limit;
73 }
74
75 void setStringPrefixSize(int32_t string_prefix_size) {
76 string_prefix_size_ = string_prefix_size;
77 }
78
David Reiss00dcccf2007-07-21 01:18:10 +000079
David Reiss6806fb82010-10-06 17:09:52 +000080 uint32_t writeMessageBegin(const std::string& name,
81 const TMessageType messageType,
82 const int32_t seqid);
David Reiss00dcccf2007-07-21 01:18:10 +000083
David Reiss6806fb82010-10-06 17:09:52 +000084 uint32_t writeMessageEnd();
David Reiss00dcccf2007-07-21 01:18:10 +000085
86
David Reiss64120002008-04-29 23:12:24 +000087 uint32_t writeStructBegin(const char* name);
David Reiss00dcccf2007-07-21 01:18:10 +000088
89 uint32_t writeStructEnd();
90
David Reiss64120002008-04-29 23:12:24 +000091 uint32_t writeFieldBegin(const char* name,
David Reiss00dcccf2007-07-21 01:18:10 +000092 const TType fieldType,
93 const int16_t fieldId);
94
95 uint32_t writeFieldEnd();
96
97 uint32_t writeFieldStop();
David Reiss0c90f6f2008-02-06 22:18:40 +000098
David Reiss00dcccf2007-07-21 01:18:10 +000099 uint32_t writeMapBegin(const TType keyType,
100 const TType valType,
101 const uint32_t size);
102
103 uint32_t writeMapEnd();
104
105 uint32_t writeListBegin(const TType elemType,
106 const uint32_t size);
107
108 uint32_t writeListEnd();
109
110 uint32_t writeSetBegin(const TType elemType,
111 const uint32_t size);
112
113 uint32_t writeSetEnd();
114
115 uint32_t writeBool(const bool value);
116
117 uint32_t writeByte(const int8_t byte);
118
119 uint32_t writeI16(const int16_t i16);
120
121 uint32_t writeI32(const int32_t i32);
122
123 uint32_t writeI64(const int64_t i64);
124
125 uint32_t writeDouble(const double dub);
126
127 uint32_t writeString(const std::string& str);
128
David Reissc005b1b2008-02-15 01:38:18 +0000129 uint32_t writeBinary(const std::string& str);
130
David Reiss00dcccf2007-07-21 01:18:10 +0000131
132 private:
133 void indentUp();
134 void indentDown();
135 uint32_t writePlain(const std::string& str);
136 uint32_t writeIndented(const std::string& str);
137 uint32_t startItem();
138 uint32_t endItem();
139 uint32_t writeItem(const std::string& str);
140
141 static std::string fieldTypeName(TType type);
142
David Reissa80f0fb2008-04-08 05:06:15 +0000143 int32_t string_limit_;
144 int32_t string_prefix_size_;
145
David Reiss00dcccf2007-07-21 01:18:10 +0000146 std::string indent_str_;
147 static const int indent_inc = 2;
148
149 std::vector<write_state_t> write_state_;
150 std::vector<int> list_idx_;
151};
152
153/**
154 * Constructs debug protocol handlers
155 */
156class TDebugProtocolFactory : public TProtocolFactory {
157 public:
158 TDebugProtocolFactory() {}
159 virtual ~TDebugProtocolFactory() {}
160
161 boost::shared_ptr<TProtocol> getProtocol(boost::shared_ptr<TTransport> trans) {
162 return boost::shared_ptr<TProtocol>(new TDebugProtocol(trans));
163 }
164
165};
166
T Jake Lucianib5e62212009-01-31 22:36:20 +0000167}}} // apache::thrift::protocol
David Reiss00dcccf2007-07-21 01:18:10 +0000168
169
David Reiss28f298d2008-05-01 06:17:36 +0000170// TODO(dreiss): Move (part of) ThriftDebugString into a .cpp file and remove this.
171#include <transport/TBufferTransports.h>
172
T Jake Lucianib5e62212009-01-31 22:36:20 +0000173namespace apache { namespace thrift {
David Reiss00dcccf2007-07-21 01:18:10 +0000174
175template<typename ThriftStruct>
176std::string ThriftDebugString(const ThriftStruct& ts) {
T Jake Lucianib5e62212009-01-31 22:36:20 +0000177 using namespace apache::thrift::transport;
178 using namespace apache::thrift::protocol;
David Reiss00dcccf2007-07-21 01:18:10 +0000179 TMemoryBuffer* buffer = new TMemoryBuffer;
180 boost::shared_ptr<TTransport> trans(buffer);
181 TDebugProtocol protocol(trans);
182
183 ts.write(&protocol);
184
185 uint8_t* buf;
186 uint32_t size;
187 buffer->getBuffer(&buf, &size);
188 return std::string((char*)buf, (unsigned int)size);
189}
190
191// TODO(dreiss): This is badly broken. Don't use it unless you are me.
192#if 0
193template<typename Object>
194std::string DebugString(const std::vector<Object>& vec) {
T Jake Lucianib5e62212009-01-31 22:36:20 +0000195 using namespace apache::thrift::transport;
196 using namespace apache::thrift::protocol;
David Reiss00dcccf2007-07-21 01:18:10 +0000197 TMemoryBuffer* buffer = new TMemoryBuffer;
198 boost::shared_ptr<TTransport> trans(buffer);
199 TDebugProtocol protocol(trans);
200
201 // I am gross!
202 protocol.writeStructBegin("SomeRandomVector");
203
204 // TODO: Fix this with a trait.
205 protocol.writeListBegin((TType)99, vec.size());
206 typename std::vector<Object>::const_iterator it;
207 for (it = vec.begin(); it != vec.end(); ++it) {
208 it->write(&protocol);
209 }
210 protocol.writeListEnd();
211
212 uint8_t* buf;
213 uint32_t size;
214 buffer->getBuffer(&buf, &size);
215 return std::string((char*)buf, (unsigned int)size);
216}
217#endif // 0
218
T Jake Lucianib5e62212009-01-31 22:36:20 +0000219}} // apache::thrift
David Reiss00dcccf2007-07-21 01:18:10 +0000220
221
222#endif // #ifndef _THRIFT_PROTOCOL_TDEBUGPROTOCOL_H_
223
224