#ifndef SRL_READER_H_
#define SRL_READER_H_
#include <assert.h>
#include "srl_common.h"
#include "srl_reader_types.h"
/* reader buffer operations */
#define SRL_RDR_SIZE(buf) ((buf)->end - (buf)->start)
#define SRL_RDR_SPACE_LEFT(buf) ((buf)->end - (buf)->pos)
#define SRL_RDR_DONE(buf) ((buf)->pos >= (buf)->end)
#define SRL_RDR_NOT_DONE(buf) ((buf)->pos < (buf)->end)
#define SRL_RDR_POS_OFS(buf) ((buf)->pos - (buf)->start)
#define SRL_RDR_BODY_POS_OFS(buf) ((buf)->pos - (buf)->body_pos)
#define SRL_RDR_CLEAR(buf) STMT_START { \
(buf)->start = NULL; \
(buf)->end = NULL; \
(buf)->pos = NULL; \
(buf)->body_pos = NULL; \
} STMT_END
/* Sereal v1 and newer version use start body offset from different positions */
#define SRL_RDR_SET_BODY_POS(buf, pos) ((buf)->body_pos = (pos))
#define SRL_RDR_UPDATE_BODY_POS(buf, protocol_version) STMT_START { \
if (expect_false((protocol_version) == 1)) { \
SRL_RDR_SET_BODY_POS((buf), (buf)->start); \
} else { \
SRL_RDR_SET_BODY_POS((buf), (buf)->pos - 1); \
} \
} STMT_END
#define SRL_RDR_ASSERT_SPACE(buf, len, msg) STMT_START { \
if (expect_false((ptrdiff_t)SRL_RDR_SPACE_LEFT((buf)) \
< (ptrdiff_t)(len))) \
{ \
SRL_RDR_ERRORf3((buf), "Unexpected termination of packet%s, " \
"want %"UVuf" bytes, only have %"IVdf" available", \
(msg), (UV)(len), (IV)SRL_RDR_SPACE_LEFT((buf))); \
} \
} STMT_END
#ifndef NDEBUG
# define DEBUG_ASSERT_RDR_SANE(buf) STMT_START { \
if (expect_false( \
(buf)->pos < (buf)->start \
|| (buf)->pos > (buf)->end \
)) { \
warn("failed sanity assertion check - pos: %"UVuf" [%p %p %p] %"UVuf, \
(UV)SRL_RDR_POS_OFS(buf), (buf)->start, (buf)->pos, \
(buf)->end, (UV)SRL_RDR_SPACE_LEFT(buf)); \
} \
assert(((buf)->start <= (buf)->pos) && ((buf)->pos <= (buf)->end)); \
} STMT_END
#else
# define DEBUG_ASSERT_RDR_SANE(buf)
#endif
#endif