Skip to content

Commit ac97a4f

Browse files
committed
Client: rewrite response decoding logic with new decoder
The commit rewrites response decoding logic using new decoder. Field IPROTO_ERROR_24 is not parsed anymore - it is a duplicate of the last error message in the error stack. Also, the whole error stack is decoded now (before the patch, only the first value was decoded). MP_ERROR_FIELDS are still not decoded. Public structure `Data` is reworked. Now you need to call `data.decode` method and pass a container of arrays - every tuple will be decoded as an array and put to the container.
1 parent ddf08f3 commit ac97a4f

File tree

8 files changed

+100
-623
lines changed

8 files changed

+100
-623
lines changed

examples/Reader.hpp

Lines changed: 3 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ struct UserTuple {
4141
uint64_t field1;
4242
std::string field2;
4343
double field3;
44+
45+
static constexpr auto mpp = std::make_tuple(
46+
&UserTuple::field1, &UserTuple::field2, &UserTuple::field3);
4447
};
4548
//doclabel13-2
4649

@@ -50,59 +53,3 @@ operator<<(std::ostream& strm, const UserTuple &t)
5053
return strm << "Tuple: field1=" << t.field1 << " field2=" << t.field2 <<
5154
" field3=" << t.field3;
5255
}
53-
54-
using Buf_t = tnt::Buffer<16 * 1024>;
55-
using BufIter_t = typename Buf_t::iterator;
56-
57-
//doclabel14-1
58-
struct UserTupleValueReader : mpp::DefaultErrorHandler {
59-
explicit UserTupleValueReader(UserTuple& t) : tuple(t) {}
60-
static constexpr mpp::Family VALID_TYPES = mpp::MP_INT | mpp::MP_STR | mpp::MP_FLT;
61-
template <class T>
62-
void Value(BufIter_t&, mpp::compact::Family, T v)
63-
{
64-
if constexpr (std::is_integral_v<T>) {
65-
tuple.field1 = v;
66-
} else {
67-
static_assert(std::is_floating_point_v<T>);
68-
tuple.field3 = v;
69-
}
70-
}
71-
void Value(BufIter_t& itr, mpp::compact::Family, mpp::StrValue v)
72-
{
73-
BufIter_t tmp = itr;
74-
tmp += v.offset;
75-
std::string &dst = tuple.field2;
76-
while (v.size) {
77-
dst.push_back(*tmp);
78-
++tmp;
79-
--v.size;
80-
}
81-
}
82-
void WrongType(mpp::Family expected, mpp::Family got)
83-
{
84-
std::cout << "expected type is " << expected <<
85-
" but got " << got << std::endl;
86-
}
87-
88-
BufIter_t* StoreEndIterator() { return nullptr; }
89-
UserTuple& tuple;
90-
};
91-
//doclabel14-2
92-
93-
//doclabel15-1
94-
template <class BUFFER>
95-
struct UserTupleReader : mpp::SimpleReaderBase<BUFFER, mpp::MP_ARR> {
96-
97-
UserTupleReader(mpp::Dec<BUFFER>& d, UserTuple& t) : dec(d), tuple(t) {}
98-
99-
void Value(const iterator_t<BUFFER>&, mpp::compact::Family, mpp::ArrValue u)
100-
{
101-
assert(u.size == 3);
102-
(void) u;
103-
dec.SetReader(false, UserTupleValueReader{tuple});
104-
}
105-
mpp::Dec<BUFFER>& dec;
106-
UserTuple& tuple;
107-
};
108-
//doclabel15-2

examples/Simple.cpp

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -58,32 +58,25 @@ using Buf_t = tnt::Buffer<16 * 1024>;
5858
using Net_t = LibevNetProvider<Buf_t, DefaultStream>;
5959
//doclabel02-2
6060

61-
//doclabel16-1
61+
//doclabel14-1
6262
template <class BUFFER>
6363
std::vector<UserTuple>
64-
decodeUserTuple(BUFFER &buf, Data<BUFFER> &data)
64+
decodeUserTuple(Data<BUFFER> &data)
6565
{
6666
std::vector<UserTuple> results;
67-
for(auto& t: data.tuples) {
68-
UserTuple tuple;
69-
mpp::Dec dec(buf);
70-
dec.SetPosition(t.begin);
71-
dec.SetReader(false, UserTupleReader<BUFFER>{dec, tuple});
72-
mpp::ReadResult_t res = dec.Read();
73-
assert(res == mpp::READ_SUCCESS);
74-
(void) res;
75-
results.push_back(tuple);
76-
}
67+
bool ok = data.decode(results);
68+
if (!ok)
69+
return std::vector<UserTuple>();
7770
return results;
7871
}
79-
//doclabel16-2
72+
//doclabel14-2
8073

8174
template<class BUFFER>
8275
void
83-
printResponse(Connection<BUFFER, Net_t> &conn, Response<BUFFER> &response)
76+
printResponse(Response<BUFFER> &response)
8477
{
8578
if (response.body.error_stack != std::nullopt) {
86-
Error err = (*response.body.error_stack).error;
79+
Error err = (*response.body.error_stack)[0];
8780
std::cout << "RESPONSE ERROR: msg=" << err.msg <<
8881
" line=" << err.file << " file=" << err.file <<
8982
" errno=" << err.saved_errno <<
@@ -92,12 +85,11 @@ printResponse(Connection<BUFFER, Net_t> &conn, Response<BUFFER> &response)
9285
}
9386
if (response.body.data != std::nullopt) {
9487
Data<BUFFER>& data = *response.body.data;
95-
if (data.tuples.empty()) {
88+
std::vector<UserTuple> tuples = decodeUserTuple(data);
89+
if (tuples.empty()) {
9690
std::cout << "Empty result" << std::endl;
9791
return;
9892
}
99-
std::vector<UserTuple> tuples =
100-
decodeUserTuple(conn.getInBuf(), data);
10193
for (auto const& t : tuples) {
10294
std::cout << t << std::endl;
10395
}
@@ -204,7 +196,7 @@ main()
204196
* rely on response code storing in the header or check
205197
* Response->body.data and Response->body.error_stack members.
206198
*/
207-
printResponse<Buf_t>(conn, *response);
199+
printResponse<Buf_t>(*response);
208200
//doclabel11-2
209201
/* Let's wait for both futures at once. */
210202
std::vector<rid_t> futures(2);
@@ -216,7 +208,7 @@ main()
216208
assert(conn.futureIsReady(futures[i]));
217209
response = conn.getResponse(futures[i]);
218210
assert(response != std::nullopt);
219-
printResponse<Buf_t>(conn, *response);
211+
printResponse<Buf_t>(*response);
220212
}
221213
//doclabel11-3
222214
/* Let's create another connection. */

src/Client/ResponseDecoder.hpp

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ static constexpr size_t MP_RESPONSE_SIZE = 5;
5151
template<class BUFFER>
5252
class ResponseDecoder {
5353
public:
54-
ResponseDecoder(BUFFER &buf) : m_Dec(buf) {};
54+
ResponseDecoder(BUFFER &buf) : it(buf.begin()) {};
5555
~ResponseDecoder() { };
5656
ResponseDecoder() = delete;
5757
ResponseDecoder(const ResponseDecoder& decoder) = delete;
@@ -64,18 +64,17 @@ class ResponseDecoder {
6464
private:
6565
int decodeHeader(Header &header);
6666
int decodeBody(Body<BUFFER> &body);
67-
mpp::Dec<BUFFER> m_Dec;
67+
iterator_t<BUFFER> it;
6868
};
6969

7070
template<class BUFFER>
7171
int
7272
ResponseDecoder<BUFFER>::decodeResponseSize()
7373
{
7474
int size = -1;
75-
m_Dec.SetReader(false, mpp::SimpleReader<BUFFER, mpp::MP_INT, int>{size});
76-
mpp::ReadResult_t res = m_Dec.Read();
75+
bool ok = mpp::decode(it, size);
7776
//TODO: raise more detailed error
78-
if (res != mpp::READ_SUCCESS)
77+
if (!ok)
7978
return -1;
8079
return size;
8180
}
@@ -84,24 +83,17 @@ template<class BUFFER>
8483
int
8584
ResponseDecoder<BUFFER>::decodeHeader(Header &header)
8685
{
87-
m_Dec.SetReader(false, HeaderReader{m_Dec, header});
88-
mpp::ReadResult_t res = m_Dec.Read();
89-
if (res != mpp::READ_SUCCESS)
90-
return -1;
91-
return 0;
86+
bool ok = mpp::decode(it, header);
87+
return ok ? 0 : -1;
9288
}
9389

9490
template<class BUFFER>
9591
int
9692
ResponseDecoder<BUFFER>::decodeBody(Body<BUFFER> &body)
9793
{
98-
m_Dec.SetReader(false, BodyReader{m_Dec, body});
99-
mpp::ReadResult_t res = m_Dec.Read();
100-
if (res != mpp::READ_SUCCESS)
101-
return -1;
102-
if (body.data != std::nullopt)
103-
body.data->end = m_Dec.getPosition();
104-
return 0;
94+
95+
bool ok = mpp::decode(it, body);
96+
return ok ? 0 : -1;
10597
}
10698

10799
template<class BUFFER>
@@ -123,7 +115,7 @@ template<class BUFFER>
123115
void
124116
ResponseDecoder<BUFFER>::reset(iterator_t<BUFFER> &itr)
125117
{
126-
m_Dec.SetPosition(itr);
118+
it = itr;
127119
}
128120

129121
static inline uint32_t

0 commit comments

Comments
 (0)