blob: ab69e0ca5b9f7f194c9ea56660a39574db41742a [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
23#include "TProtocol.h"
24#include "TOneWayProtocol.h"
25
26#include <boost/shared_ptr.hpp>
27
T Jake Lucianib5e62212009-01-31 22:36:20 +000028namespace apache { namespace thrift { namespace protocol {
David Reiss00dcccf2007-07-21 01:18:10 +000029
30/*
31
32!!! EXPERIMENTAL CODE !!!
33
34This protocol is very much a work in progress.
35It doesn't handle many cases properly.
36It throws exceptions in many cases.
37It probably segfaults in many cases.
38Bug reports and feature requests are welcome.
39Complaints are not. :R
40
41*/
42
43
44/**
45 * Protocol that prints the payload in a nice human-readable format.
46 * Reading from this protocol is not supported.
47 *
David Reiss00dcccf2007-07-21 01:18:10 +000048 */
49class TDebugProtocol : public TWriteOnlyProtocol {
50 private:
David Reiss322e5952008-12-05 02:54:09 +000051 enum write_state_t
52 { UNINIT
53 , STRUCT
54 , LIST
55 , SET
56 , MAP_KEY
57 , MAP_VALUE
David Reiss00dcccf2007-07-21 01:18:10 +000058 };
59
60 public:
61 TDebugProtocol(boost::shared_ptr<TTransport> trans)
62 : TWriteOnlyProtocol(trans, "TDebugProtocol")
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
81 virtual uint32_t writeMessageBegin(const std::string& name,
82 const TMessageType messageType,
83 const int32_t seqid);
84
85 virtual uint32_t writeMessageEnd();
86
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 Reissa80f0fb2008-04-08 05:06:15 +0000144 int32_t string_limit_;
145 int32_t string_prefix_size_;
146
David Reiss00dcccf2007-07-21 01:18:10 +0000147 std::string indent_str_;
148 static const int indent_inc = 2;
149
150 std::vector<write_state_t> write_state_;
151 std::vector<int> list_idx_;
152};
153
154/**
155 * Constructs debug protocol handlers
156 */
157class TDebugProtocolFactory : public TProtocolFactory {
158 public:
159 TDebugProtocolFactory() {}
160 virtual ~TDebugProtocolFactory() {}
161
162 boost::shared_ptr<TProtocol> getProtocol(boost::shared_ptr<TTransport> trans) {
163 return boost::shared_ptr<TProtocol>(new TDebugProtocol(trans));
164 }
165
166};
167
T Jake Lucianib5e62212009-01-31 22:36:20 +0000168}}} // apache::thrift::protocol
David Reiss00dcccf2007-07-21 01:18:10 +0000169
170
David Reiss28f298d2008-05-01 06:17:36 +0000171// TODO(dreiss): Move (part of) ThriftDebugString into a .cpp file and remove this.
172#include <transport/TBufferTransports.h>
173
T Jake Lucianib5e62212009-01-31 22:36:20 +0000174namespace apache { namespace thrift {
David Reiss00dcccf2007-07-21 01:18:10 +0000175
176template<typename ThriftStruct>
177std::string ThriftDebugString(const ThriftStruct& ts) {
T Jake Lucianib5e62212009-01-31 22:36:20 +0000178 using namespace apache::thrift::transport;
179 using namespace apache::thrift::protocol;
David Reiss00dcccf2007-07-21 01:18:10 +0000180 TMemoryBuffer* buffer = new TMemoryBuffer;
181 boost::shared_ptr<TTransport> trans(buffer);
182 TDebugProtocol protocol(trans);
183
184 ts.write(&protocol);
185
186 uint8_t* buf;
187 uint32_t size;
188 buffer->getBuffer(&buf, &size);
189 return std::string((char*)buf, (unsigned int)size);
190}
191
192// TODO(dreiss): This is badly broken. Don't use it unless you are me.
193#if 0
194template<typename Object>
195std::string DebugString(const std::vector<Object>& vec) {
T Jake Lucianib5e62212009-01-31 22:36:20 +0000196 using namespace apache::thrift::transport;
197 using namespace apache::thrift::protocol;
David Reiss00dcccf2007-07-21 01:18:10 +0000198 TMemoryBuffer* buffer = new TMemoryBuffer;
199 boost::shared_ptr<TTransport> trans(buffer);
200 TDebugProtocol protocol(trans);
201
202 // I am gross!
203 protocol.writeStructBegin("SomeRandomVector");
204
205 // TODO: Fix this with a trait.
206 protocol.writeListBegin((TType)99, vec.size());
207 typename std::vector<Object>::const_iterator it;
208 for (it = vec.begin(); it != vec.end(); ++it) {
209 it->write(&protocol);
210 }
211 protocol.writeListEnd();
212
213 uint8_t* buf;
214 uint32_t size;
215 buffer->getBuffer(&buf, &size);
216 return std::string((char*)buf, (unsigned int)size);
217}
218#endif // 0
219
T Jake Lucianib5e62212009-01-31 22:36:20 +0000220}} // apache::thrift
David Reiss00dcccf2007-07-21 01:18:10 +0000221
222
223#endif // #ifndef _THRIFT_PROTOCOL_TDEBUGPROTOCOL_H_
224
225