static bool fill_buffer(w_jbuffer_t *jr, w_stm_t stm) { uint32_t avail; int r; avail = shunt_down(jr); // Get some more space if we need it if (avail == 0) { char *buf = realloc(jr->buf, jr->allocd * 2); if (!buf) { return false; } jr->buf = buf; jr->allocd *= 2; avail = jr->allocd - jr->wpos; } errno = 0; r = w_stm_read(stm, jr->buf + jr->wpos, avail); if (r <= 0) { return false; } jr->wpos += r; return true; }
static bool read_and_detect_pdu(w_jbuffer_t *jr, w_stm_t stm, json_error_t *jerr) { enum w_pdu_type pdu; shunt_down(jr); pdu = detect_pdu(jr); if (pdu == need_data) { if (!fill_buffer(jr, stm)) { if (errno != EAGAIN) { snprintf(jerr->text, sizeof(jerr->text), "fill_buffer: %s", errno ? strerror(errno) : "EOF"); } return false; } pdu = detect_pdu(jr); } if (pdu == is_json_compact && stm == w_stm_stdin()) { // Minor hack for the `-j` option for reading pretty printed // json from stdin pdu = is_json_pretty; } jr->pdu_type = pdu; return true; }
static bool stream_n_bytes(w_jbuffer_t *jr, w_stm_t stm, json_int_t len, json_error_t *jerr) { uint32_t total = 0; if (!output_bytes(jr->buf, jr->rpos)) { snprintf(jerr->text, sizeof(jerr->text), "failed output headers bytes %d: %s\n", jr->rpos, strerror(errno)); return false; } while (len > 0) { uint32_t avail = jr->wpos - jr->rpos; int r; if (avail) { if (!output_bytes(jr->buf + jr->rpos, avail)) { snprintf(jerr->text, sizeof(jerr->text), "output_bytes: avail=%d, failed %s\n", avail, strerror(errno)); return false; } jr->rpos += avail; len -= avail; if (len == 0) { return true; } } avail = MIN((uint32_t)len, shunt_down(jr)); r = w_stm_read(stm, jr->buf + jr->wpos, avail); if (r <= 0) { snprintf(jerr->text, sizeof(jerr->text), "read: len=%"PRIi64" wanted %"PRIu32" got %d %s\n", (int64_t)len, avail, r, strerror(errno)); return false; } jr->wpos += r; total += r; } return true; }
static bool read_and_detect_pdu(w_jbuffer_t *jr, int fd, json_error_t *jerr) { enum w_pdu_type pdu; shunt_down(jr); pdu = detect_pdu(jr); if (pdu == need_data) { if (!fill_buffer(jr, fd)) { if (errno != EAGAIN) { snprintf(jerr->text, sizeof(jerr->text), "fill_buffer: %s", strerror(errno)); } return false; } pdu = detect_pdu(jr); } jr->pdu_type = pdu; return true; }