@@ -64,8 +64,8 @@ int tnt_reply_from(struct tnt_reply *r, tnt_reply_t rcv, void *ptr) {
64
64
memset (r , 0 , sizeof (struct tnt_reply ));
65
65
r -> alloc = alloc ;
66
66
/* reading iproto header */
67
- char length [9 ]; const char * data = (const char * )length ;
68
- if (rcv (ptr , length , 5 ) == -1 )
67
+ char length [TNT_REPLY_IPROTO_HDR_SIZE ]; const char * data = (const char * )length ;
68
+ if (rcv (ptr , length , sizeof ( length ) ) == -1 )
69
69
goto rollback ;
70
70
if (mp_typeof (* length ) != MP_UINT )
71
71
goto rollback ;
@@ -76,109 +76,158 @@ int tnt_reply_from(struct tnt_reply *r, tnt_reply_t rcv, void *ptr) {
76
76
goto rollback ;
77
77
if (rcv (ptr , (char * )r -> buf , size ) == -1 )
78
78
goto rollback ;
79
- /* header */
80
- const char * p = r -> buf ;
81
- const char * test = p ;
82
- if (mp_check (& test , r -> buf + size ))
79
+ size_t hdr_length ;
80
+ if (tnt_reply_hdr0 (r , r -> buf , r -> buf_size , & hdr_length ) != 0 )
83
81
goto rollback ;
84
- if (mp_typeof (* p ) != MP_MAP )
82
+ if (size == (size_t )hdr_length )
83
+ return 0 ; /* no body */
84
+ if (tnt_reply_body0 (r , r -> buf + hdr_length , r -> buf_size - hdr_length , NULL ) != 0 )
85
85
goto rollback ;
86
+
87
+ return 0 ;
88
+ rollback :
89
+ if (r -> buf ) tnt_mem_free ((void * )r -> buf );
90
+ alloc = r -> alloc ;
91
+ memset (r , 0 , sizeof (struct tnt_reply ));
92
+ r -> alloc = alloc ;
93
+ return -1 ;
94
+ }
95
+
96
+ static ssize_t tnt_reply_cb (void * ptr [2 ], char * buf , ssize_t size ) {
97
+ char * src = ptr [0 ];
98
+ ssize_t * off = ptr [1 ];
99
+ memcpy (buf , src + * off , size );
100
+ * off += size ;
101
+ return size ;
102
+ }
103
+
104
+ static int
105
+ tnt_reply_len (const char * buf , size_t size , size_t * len )
106
+ {
107
+ if (size < TNT_REPLY_IPROTO_HDR_SIZE ) {
108
+ * len = TNT_REPLY_IPROTO_HDR_SIZE - size ;
109
+ return 1 ;
110
+ }
111
+ const char * p = buf ;
112
+ if (mp_typeof (* p ) != MP_UINT )
113
+ return -1 ;
114
+ size_t length = mp_decode_uint (& p );
115
+ if (size < length + TNT_REPLY_IPROTO_HDR_SIZE ) {
116
+ * len = (length + TNT_REPLY_IPROTO_HDR_SIZE ) - size ;
117
+ return 1 ;
118
+ }
119
+ * len = length + TNT_REPLY_IPROTO_HDR_SIZE ;
120
+ return 0 ;
121
+ }
122
+
123
+ int
124
+ tnt_reply_hdr0 (struct tnt_reply * r , const char * buf , size_t size , size_t * off ) {
125
+ const char * test = buf ;
126
+ const char * p = buf ;
127
+ if (mp_check (& test , p + size ))
128
+ return -1 ;
129
+ if (mp_typeof (* p ) != MP_MAP )
130
+ return -1 ;
131
+
86
132
uint32_t n = mp_decode_map (& p );
133
+ uint64_t sync = 0 , code = 0 , schema_id = 0 , bitmap = 0 ;
87
134
while (n -- > 0 ) {
88
135
if (mp_typeof (* p ) != MP_UINT )
89
- goto rollback ;
136
+ return -1 ;
90
137
uint32_t key = mp_decode_uint (& p );
91
138
if (mp_typeof (* p ) != MP_UINT )
92
- goto rollback ;
139
+ return -1 ;
93
140
switch (key ) {
94
141
case TNT_SYNC :
95
- if (mp_typeof (* p ) != MP_UINT )
96
- goto rollback ;
97
- r -> sync = mp_decode_uint (& p );
142
+ sync = mp_decode_uint (& p );
98
143
break ;
99
144
case TNT_CODE :
100
- if (mp_typeof (* p ) != MP_UINT )
101
- goto rollback ;
102
- r -> code = mp_decode_uint (& p );
145
+ code = mp_decode_uint (& p );
103
146
break ;
104
147
case TNT_SCHEMA_ID :
105
- if (mp_typeof (* p ) != MP_UINT )
106
- goto rollback ;
107
- r -> schema_id = mp_decode_uint (& p );
148
+ schema_id = mp_decode_uint (& p );
108
149
break ;
109
150
default :
110
- goto rollback ;
151
+ return -1 ;
111
152
}
112
- r -> bitmap |= (1ULL << key );
153
+ bitmap |= (1ULL << key );
113
154
}
155
+ if (r ) {
156
+ r -> sync = sync ;
157
+ r -> code = code & ((1 << 15 ) - 1 );
158
+ r -> schema_id = schema_id ;
159
+ r -> bitmap = bitmap ;
160
+ }
161
+ if (off )
162
+ * off = p - buf ;
163
+ return 0 ;
164
+ }
114
165
115
- /* body */
116
- if ( p == r -> buf + size + 5 )
117
- return size + 5 ; /* no body */
118
- test = p ;
119
- if (mp_check (& test , r -> buf + size ))
120
- goto rollback ;
166
+ int
167
+ tnt_reply_body0 ( struct tnt_reply * r , const char * buf , size_t size , size_t * off ) {
168
+ const char * test = buf ;
169
+ const char * p = buf ;
170
+ if (mp_check (& test , p + size ))
171
+ return -1 ;
121
172
if (mp_typeof (* p ) != MP_MAP )
122
- goto rollback ;
123
- n = mp_decode_map (& p );
173
+ return -1 ;
174
+ const char * error = NULL , * error_end = NULL , * data = NULL , * data_end = NULL ;
175
+ uint64_t bitmap = 0 ;
176
+ uint32_t n = mp_decode_map (& p );
124
177
while (n -- > 0 ) {
125
178
uint32_t key = mp_decode_uint (& p );
126
179
switch (key ) {
127
180
case TNT_ERROR : {
128
181
if (mp_typeof (* p ) != MP_STR )
129
- goto rollback ;
182
+ return -1 ;
130
183
uint32_t elen = 0 ;
131
- r -> error = mp_decode_str (& p , & elen );
132
- r -> error_end = r -> error + elen ;
133
- r -> code = r -> code & ((1 << 15 ) - 1 );
184
+ error = mp_decode_str (& p , & elen );
185
+ error_end = error + elen ;
134
186
break ;
135
187
}
136
188
case TNT_DATA : {
137
189
if (mp_typeof (* p ) != MP_ARRAY )
138
- goto rollback ;
139
- r -> data = p ;
190
+ return -1 ;
191
+ data = p ;
140
192
mp_next (& p );
141
- r -> data_end = p ;
193
+ data_end = p ;
142
194
break ;
143
195
}
144
196
}
145
- r -> bitmap |= (1ULL << key );
197
+ bitmap |= (1ULL << key );
198
+ }
199
+ if (r ) {
200
+ r -> error = error ;
201
+ r -> error_end = error_end ;
202
+ r -> data = data ;
203
+ r -> data_end = data_end ;
204
+ r -> bitmap |= bitmap ;
146
205
}
206
+ if (off )
207
+ * off = p - buf ;
147
208
return 0 ;
148
- rollback :
149
- if (r -> buf ) tnt_mem_free ((void * )r -> buf );
150
- alloc = r -> alloc ;
151
- memset (r , 0 , sizeof (struct tnt_reply ));
152
- r -> alloc = alloc ;
153
- return -1 ;
154
- }
155
-
156
- static ssize_t tnt_reply_cb (void * ptr [2 ], char * buf , ssize_t size ) {
157
- char * src = ptr [0 ];
158
- ssize_t * off = ptr [1 ];
159
- memcpy (buf , src + * off , size );
160
- * off += size ;
161
- return size ;
162
209
}
163
210
164
211
int
165
212
tnt_reply (struct tnt_reply * r , char * buf , size_t size , size_t * off ) {
166
213
/* supplied buffer must contain full reply,
167
214
* if it doesn't then returning count of bytes
168
215
* needed to process */
169
- if (size < 5 ) {
216
+ size_t length ;
217
+ switch (tnt_reply_len (buf , size , & length )) {
218
+ case 0 :
219
+ break ;
220
+ case 1 :
170
221
if (off )
171
- * off = 5 - size ;
222
+ * off = length ;
172
223
return 1 ;
173
- }
174
- const char * p = buf ;
175
- if (mp_typeof (* p ) != MP_UINT )
224
+ default :
176
225
return -1 ;
177
- size_t length = mp_decode_uint ( & p );
178
- if (size < length + 5 ) {
226
+ }
227
+ if (r == NULL ) {
179
228
if (off )
180
- * off = ( length + 5 ) - size ;
181
- return 1 ;
229
+ * off = length ;
230
+ return 0 ;
182
231
}
183
232
size_t offv = 0 ;
184
233
void * ptr [2 ] = { buf , & offv };
@@ -187,3 +236,38 @@ tnt_reply(struct tnt_reply *r, char *buf, size_t size, size_t *off) {
187
236
* off = offv ;
188
237
return rc ;
189
238
}
239
+
240
+ int
241
+ tnt_reply0 (struct tnt_reply * r , const char * buf , size_t size , size_t * off ) {
242
+ /* supplied buffer must contain full reply,
243
+ * if it doesn't then returning count of bytes
244
+ * needed to process */
245
+ size_t length ;
246
+ switch (tnt_reply_len (buf , size , & length )) {
247
+ case 0 :
248
+ break ;
249
+ case 1 :
250
+ if (off )
251
+ * off = length ;
252
+ return 1 ;
253
+ default :
254
+ return -1 ;
255
+ }
256
+ if (r == NULL ) {
257
+ if (off )
258
+ * off = length ;
259
+ return 0 ;
260
+ }
261
+ const char * data = buf + TNT_REPLY_IPROTO_HDR_SIZE ;
262
+ size_t data_length = length - TNT_REPLY_IPROTO_HDR_SIZE ;
263
+ size_t hdr_length ;
264
+ if (tnt_reply_hdr0 (r , data , data_length , & hdr_length ) != 0 )
265
+ return -1 ;
266
+ if (data_length != hdr_length ) {
267
+ if (tnt_reply_body0 (r , data + hdr_length , data_length - hdr_length , NULL ) != 0 )
268
+ return -1 ;
269
+ }
270
+ if (off )
271
+ * off = length ;
272
+ return 0 ;
273
+ }
0 commit comments