#ifndef RBUF_H #define RBUF_H #ident "Copyright (c) 2007 Tokutek Inc. All rights reserved." #include "toku_assert.h" #include "memory.h" #include "memarena.h" #include struct rbuf { unsigned char *buf; unsigned int size; unsigned int ndone; }; static inline unsigned int rbuf_char (struct rbuf *r) { assert(r->ndonesize); return r->buf[r->ndone++]; } static unsigned int rbuf_int (struct rbuf *r) { #if 1 assert(r->ndone+4 <= r->size); u_int32_t result = ntohl(*(u_int32_t*)(r->buf+r->ndone)); // This only works on machines where unaligned loads are OK. r->ndone+=4; return result; #else unsigned char c0 = rbuf_char(r); unsigned char c1 = rbuf_char(r); unsigned char c2 = rbuf_char(r); unsigned char c3 = rbuf_char(r); return ((c0<<24)| (c1<<16)| (c2<<8)| (c3<<0)); #endif } static inline void rbuf_literal_bytes (struct rbuf *r, bytevec *bytes, unsigned int n_bytes) { *bytes = &r->buf[r->ndone]; r->ndone+=n_bytes; assert(r->ndone<=r->size); } /* Return a pointer into the middle of the buffer. */ static inline void rbuf_bytes (struct rbuf *r, bytevec *bytes, unsigned int *n_bytes) { *n_bytes = rbuf_int(r); rbuf_literal_bytes(r, bytes, *n_bytes); } static inline unsigned long long rbuf_ulonglong (struct rbuf *r) { unsigned i0 = rbuf_int(r); unsigned i1 = rbuf_int(r); return ((unsigned long long)(i0)<<32) | ((unsigned long long)(i1)); } static inline signed long long rbuf_longlong (struct rbuf *r) { return (signed long long)rbuf_ulonglong(r); } static inline DISKOFF rbuf_diskoff (struct rbuf *r) { return rbuf_ulonglong(r); } static inline BLOCKNUM rbuf_blocknum (struct rbuf *r) { BLOCKNUM result = make_blocknum(rbuf_longlong(r)); return result; } static inline void rbuf_TXNID (struct rbuf *r, TXNID *txnid) { *txnid = rbuf_ulonglong(r); } static inline void rbuf_ma_TXNID (struct rbuf *r, MEMARENA ma __attribute__((__unused__)), TXNID *txnid) { rbuf_TXNID(r, txnid); } static inline void rbuf_FILENUM (struct rbuf *r, FILENUM *filenum) { filenum->fileid = rbuf_int(r); } static inline void rbuf_ma_FILENUM (struct rbuf *r, MEMARENA ma __attribute__((__unused__)), FILENUM *filenum) { rbuf_FILENUM(r, filenum); } // Don't try to use the same space, malloc it static inline void rbuf_BYTESTRING (struct rbuf *r, BYTESTRING *bs) { bs->len = rbuf_int(r); u_int32_t newndone = r->ndone + bs->len; assert(newndone < r->size); bs->data = toku_memdup(&r->buf[r->ndone], (size_t)bs->len); assert(bs->data); r->ndone = newndone; } static inline void rbuf_ma_BYTESTRING (struct rbuf *r, MEMARENA ma, BYTESTRING *bs) { bs->len = rbuf_int(r); u_int32_t newndone = r->ndone + bs->len; assert(newndone < r->size); bs->data = memarena_memdup(ma, &r->buf[r->ndone], (size_t)bs->len); assert(bs->data); r->ndone = newndone; } #endif