static NOINLINE size_t peekbytes_slow(upb_pbdecoder *d, void *buf, size_t bytes) { size_t ret = curbufleft(d); memcpy(buf, d->ptr, ret); if (in_residual_buf(d, d->ptr)) { size_t copy = UPB_MIN(bytes - ret, d->size_param); memcpy(buf + ret, d->buf_param, copy); ret += copy; } return ret; }
void upb_stdio_read(const void *src, uint64_t src_ofs, size_t len, char *dst) { upb_stdio_buf *buf = upb_stdio_findbuf(src, src_ofs); src_ofs -= buf->ofs; memcpy(dst, &buf->data[src_ofs], BUF_SIZE - src_ofs); len -= (BUF_SIZE - src_ofs); dst += (BUF_SIZE - src_ofs); while (len > 0) { ++buf; size_t bytes = UPB_MIN(len, BUF_SIZE); memcpy(dst, buf->data, bytes); len -= bytes; dst += bytes; } }
FORCEINLINE void upb_decode_fixed(upb_decoder *d, char *buf, size_t bytes) { if (upb_decoder_bufleft(d) >= bytes) { // Fast case. memcpy(buf, d->ptr, bytes); upb_decoder_advance(d, bytes); } else { // Slow case. size_t read = 0; while (1) { size_t avail = UPB_MIN(upb_decoder_bufleft(d), bytes - read); memcpy(buf + read, d->ptr, avail); upb_decoder_advance(d, avail); read += avail; if (read == bytes) break; upb_pullbuf(d); } } }