static int tnt_rpl_request(struct tnt_stream *s, struct tnt_request *r) { struct tnt_stream_rpl *sr = TNT_RPL_CAST(s); struct tnt_stream_net *sn = TNT_SNET_CAST(sr->net); /* fetching header */ if (tnt_io_recv(sn, (char*)&sr->hdr, sizeof(sr->hdr)) == -1) return -1; /* fetching row header */ if (tnt_io_recv(sn, (char*)&sr->row, sizeof(sr->row)) == -1) return -1; /* preparing pseudo iproto header */ struct tnt_header hdr_iproto; hdr_iproto.type = sr->row.op; hdr_iproto.len = sr->hdr.len - sizeof(struct tnt_log_row_v11); hdr_iproto.reqid = 0; /* deserializing operation */ if (tnt_request_from(r, (tnt_request_t)tnt_rpl_recv_cb, sr->net, &hdr_iproto) == -1) return -1; return 0; }
int nb_io_expect(struct tnt_stream *t, char *sz) { struct tnt_stream_net *sn = TNT_SNET_CAST(t); char buf[256]; size_t len = strlen(sz); if (len > sizeof(buf)) { sn->error = TNT_EBIG; return -1; } if (tnt_io_recv(TNT_SNET_CAST(t), buf, len) == -1) return -1; if (!memcmp(buf, sz, len)) return 0; sn->error = TNT_EFAIL; return -1; }
int nb_mc_get_recv(struct tnt_stream *t, char **data, int *data_size) { struct tnt_stream_net *sn = TNT_SNET_CAST(t); /* VALUE <key> <flags> <bytes> [<cas unique>]\r\n * <data block>\r\n * ... * END\r\n */ *data = NULL; if (nb_io_expect(t, "VALUE ") == -1) return -1; /* key */ int key_len = 0; char key[128], ch[1]; for (;; key_len++) { if (key_len > (int)sizeof(key)) { sn->error = TNT_EBIG; goto error; } if (nb_io_getc(t, ch) == -1) goto error; if (ch[0] == ' ') { key[key_len] = 0; break; } key[key_len] = ch[0]; } /* flags */ int flags = 0; while (1) { if (nb_io_getc(t, ch) == -1) goto error; if (!isdigit(ch[0])) { if (ch[0] == ' ') break; sn->error = TNT_EFAIL; goto error; } flags *= 10; flags += ch[0] - 48; } /* bytes */ int value_size = 0; while (1) { if (nb_io_getc(t, ch) == -1) goto error; if (!isdigit(ch[0])) { if (ch[0] == '\r') break; sn->error = TNT_EFAIL; goto error; } value_size *= 10; value_size += ch[0] - 48; } /* \n */ if (nb_io_getc(t, ch) == -1) goto error; /* data */ *data_size = value_size; *data = tnt_mem_alloc(*data_size); if (*data == NULL) { sn->error = TNT_EMEMORY; goto error; } if (tnt_io_recv(sn, *data, *data_size) == -1) goto error; if (nb_io_expect(t, "\r\n") == -1) goto error; if (nb_io_expect(t, "END\r\n") == -1) goto error; return 0; error: if (*data) tnt_mem_free(*data); return -1; }
static ssize_t tnt_net_reply_cb(struct tnt_stream *s, char *buf, ssize_t size) { struct tnt_stream_net *sn = TNT_SNET_CAST(s); return tnt_io_recv(sn, buf, size); }
static ssize_t tnt_net_read(struct tnt_stream *s, char *buf, size_t size) { struct tnt_stream_net *sn = TNT_SNET_CAST(s); /* read doesn't touches wrcnt */ return tnt_io_recv(sn, buf, size); }
int nb_io_getc(struct tnt_stream *t, char buf[1]) { return tnt_io_recv(TNT_SNET_CAST(t), buf, 1); }