| 324 | } |
| 325 | |
| 326 | int |
| 327 | hstcpcli::response_recv(size_t& num_flds_r) |
| 328 | { |
| 329 | if (error_code < 0) { |
| 330 | return error_code; |
| 331 | } |
| 332 | clear_error(); |
| 333 | if (num_req_bufd > 0 || num_req_sent == 0 || num_req_rcvd > 0 || |
| 334 | response_end_offset != 0) { |
| 335 | close(); |
| 336 | return set_error(-1, "response_recv: protocol out of sync"); |
| 337 | } |
| 338 | cur_row_offset = 0; |
| 339 | num_flds_r = num_flds = 0; |
| 340 | if (fd.get() < 0) { |
| 341 | return set_error(-1, "read: closed"); |
| 342 | } |
| 343 | size_t offset = 0; |
| 344 | while (true) { |
| 345 | const char *const lbegin = readbuf.begin() + offset; |
| 346 | const char *const lend = readbuf.end(); |
| 347 | const char *const nl = memchr_char(lbegin, '\n', lend - lbegin); |
| 348 | if (nl != 0) { |
| 349 | offset = (nl + 1) - readbuf.begin(); |
| 350 | break; |
| 351 | } |
| 352 | if (read_more() <= 0) { |
| 353 | close(); |
| 354 | return set_error(-1, "read: eof"); |
| 355 | } |
| 356 | } |
| 357 | response_end_offset = offset; |
| 358 | --num_req_sent; |
| 359 | ++num_req_rcvd; |
| 360 | char *start = readbuf.begin(); |
| 361 | char *const finish = start + response_end_offset - 1; |
| 362 | const size_t resp_code = read_ui32(start, finish); |
| 363 | skip_one(start, finish); |
| 364 | num_flds_r = num_flds = read_ui32(start, finish); |
| 365 | if (resp_code != 0) { |
| 366 | skip_one(start, finish); |
| 367 | char *const err_begin = start; |
| 368 | read_token(start, finish); |
| 369 | char *const err_end = start; |
| 370 | std::string e = std::string(err_begin, err_end - err_begin); |
| 371 | if (e.empty()) { |
| 372 | e = "unknown_error"; |
| 373 | } |
| 374 | return set_error(resp_code, e); |
| 375 | } |
| 376 | cur_row_offset = start - readbuf.begin(); |
| 377 | DBG(fprintf(stderr, "[%s] ro=%zu eol=%zu\n", |
| 378 | std::string(readbuf.begin(), readbuf.begin() + response_end_offset) |
| 379 | .c_str(), |
| 380 | cur_row_offset, response_end_offset)); |
| 381 | DBG(fprintf(stderr, "RES 0\n")); |
| 382 | return 0; |
| 383 | } |