#include "lib/fastbuf.h"
#include "lib/ff-binary.h"
-int bgetw_slow(struct fastbuf *f)
-{
- int w1, w2;
- w1 = bgetc_slow(f);
- if (w1 < 0)
- return w1;
- w2 = bgetc_slow(f);
- if (w2 < 0)
- return w2;
-#ifdef CPU_BIG_ENDIAN
- return (w1 << 8) | w2;
-#else
- return w1 | (w2 << 8);
-#endif
-}
-
-u32 bgetl_slow(struct fastbuf *f)
-{
- u32 l = bgetc_slow(f);
-#ifdef CPU_BIG_ENDIAN
- l = (l << 8) | bgetc_slow(f);
- l = (l << 8) | bgetc_slow(f);
- return (l << 8) | bgetc_slow(f);
-#else
- l = (bgetc_slow(f) << 8) | l;
- l = (bgetc_slow(f) << 16) | l;
- return (bgetc_slow(f) << 24) | l;
-#endif
-}
-
-u64 bgetq_slow(struct fastbuf *f)
-{
- u32 l, h;
-#ifdef CPU_BIG_ENDIAN
- h = bgetl_slow(f);
- l = bgetl_slow(f);
-#else
- l = bgetl_slow(f);
- h = bgetl_slow(f);
-#endif
- return ((u64) h << 32) | l;
-}
-
-u64 bget5_slow(struct fastbuf *f)
-{
- u32 l, h;
-#ifdef CPU_BIG_ENDIAN
- h = bgetc_slow(f);
- l = bgetl_slow(f);
-#else
- l = bgetl_slow(f);
- h = bgetc_slow(f);
-#endif
- return ((u64) h << 32) | l;
-}
-
-void bputw_slow(struct fastbuf *f, uns w)
-{
-#ifdef CPU_BIG_ENDIAN
- bputc_slow(f, w >> 8);
- bputc_slow(f, w);
-#else
- bputc_slow(f, w);
- bputc_slow(f, w >> 8);
-#endif
-}
-
-void bputl_slow(struct fastbuf *f, u32 l)
-{
-#ifdef CPU_BIG_ENDIAN
- bputc_slow(f, l >> 24);
- bputc_slow(f, l >> 16);
- bputc_slow(f, l >> 8);
- bputc_slow(f, l);
-#else
- bputc_slow(f, l);
- bputc_slow(f, l >> 8);
- bputc_slow(f, l >> 16);
- bputc_slow(f, l >> 24);
-#endif
-}
-
-void bputq_slow(struct fastbuf *f, u64 q)
-{
-#ifdef CPU_BIG_ENDIAN
- bputl_slow(f, q >> 32);
- bputl_slow(f, q);
-#else
- bputl_slow(f, q);
- bputl_slow(f, q >> 32);
-#endif
-}
-
-void bput5_slow(struct fastbuf *f, u64 o)
-{
- u32 hi = o >> 32;
- u32 low = o;
-#ifdef CPU_BIG_ENDIAN
- bputc_slow(f, hi);
- bputl_slow(f, low);
-#else
- bputl_slow(f, low);
- bputc_slow(f, hi);
-#endif
-}
+#define GEN(type, name, size, endian) \
+type bget##name##_##endian##_slow(struct fastbuf *f) \
+{ \
+ byte buf[size/8]; \
+ if (bread(f, buf, sizeof(buf)) != sizeof(buf)) \
+ return ~(type)0; \
+ return get_u##size##_##endian(buf); \
+} \
+void bput##name##_##endian##_##slow(struct fastbuf *f, type x) \
+{ \
+ byte buf[size/8]; \
+ put_u##size##_##endian(buf, x); \
+ bwrite_slow(f, buf, sizeof(buf)); \
+}
+
+#define FF_ALL(type, name, size) GEN(type,name,size,be) GEN(type,name,size,le)
+
+FF_ALL(int, w, 16)
+FF_ALL(u32, l, 32)
+FF_ALL(u64, q, 64)
+FF_ALL(u64, 5, 40)
#include "lib/fastbuf.h"
#include "lib/unaligned.h"
-int bgetw_slow(struct fastbuf *f);
-static inline int bgetw(struct fastbuf *f)
-{
- int w;
- if (bavailr(f) >= 2)
- {
- w = GET_U16(f->bptr);
- f->bptr += 2;
- return w;
- }
- else
- return bgetw_slow(f);
-}
-
-u32 bgetl_slow(struct fastbuf *f);
-static inline u32 bgetl(struct fastbuf *f)
-{
- u32 l;
- if (bavailr(f) >= 4)
- {
- l = GET_U32(f->bptr);
- f->bptr += 4;
- return l;
- }
- else
- return bgetl_slow(f);
-}
+#ifdef CPU_BIG_ENDIAN
+#define FF_ENDIAN be
+#else
+#define FF_ENDIAN le
+#endif
-u64 bgetq_slow(struct fastbuf *f);
-static inline u64 bgetq(struct fastbuf *f)
-{
- u64 l;
- if (bavailr(f) >= 8)
- {
- l = GET_U64(f->bptr);
- f->bptr += 8;
- return l;
- }
- else
- return bgetq_slow(f);
-}
+#define GET_FUNC(type, name, bits, endian) \
+ type bget##name##_##endian##_slow(struct fastbuf *f); \
+ static inline type bget##name##_##endian(struct fastbuf *f) \
+ { \
+ if (bavailr(f) >= bits/8) \
+ { \
+ type w = get_u##bits##_##endian(f->bptr); \
+ f->bptr += bits/8; \
+ return w; \
+ } \
+ else \
+ return bget##name##_##endian##_slow(f); \
+ }
-u64 bget5_slow(struct fastbuf *f);
-static inline u64 bget5(struct fastbuf *f)
-{
- u64 l;
- if (bavailr(f) >= 5)
- {
- l = GET_U40(f->bptr);
- f->bptr += 5;
- return l;
- }
- else
- return bget5_slow(f);
-}
+#define PUT_FUNC(type, name, bits, endian) \
+ void bput##name##_##endian##_slow(struct fastbuf *f, type x); \
+ static inline void bput##name##_##endian(struct fastbuf *f, type x) \
+ { \
+ if (bavailw(f) >= bits/8) \
+ { \
+ put_u##bits##_##endian(f->bptr, x); \
+ f->bptr += bits/8; \
+ } \
+ else \
+ return bput##name##_##endian##_slow(f, x); \
+ }
-void bputw_slow(struct fastbuf *f, uns w);
-static inline void bputw(struct fastbuf *f, uns w)
-{
- if (bavailw(f) >= 2)
- {
- PUT_U16(f->bptr, w);
- f->bptr += 2;
- }
- else
- bputw_slow(f, w);
-}
+#define FF_ALL_X(type, name, bits, defendian) \
+ GET_FUNC(type, name, bits, be) \
+ GET_FUNC(type, name, bits, le) \
+ PUT_FUNC(type, name, bits, be) \
+ PUT_FUNC(type, name, bits, le) \
+ static inline type bget##name(struct fastbuf *f) { return bget##name##_##defendian(f); } \
+ static inline void bput##name(struct fastbuf *f, type x) { bput##name##_##defendian(f, x); }
-void bputl_slow(struct fastbuf *f, u32 l);
-static inline void bputl(struct fastbuf *f, u32 l)
-{
- if (bavailw(f) >= 4)
- {
- PUT_U32(f->bptr, l);
- f->bptr += 4;
- }
- else
- bputl_slow(f, l);
-}
+#define FF_ALL(type, name, bits, defendian) FF_ALL_X(type, name, bits, defendian)
-void bputq_slow(struct fastbuf *f, u64 l);
-static inline void bputq(struct fastbuf *f, u64 l)
-{
- if (bavailw(f) >= 8)
- {
- PUT_U64(f->bptr, l);
- f->bptr += 8;
- }
- else
- bputq_slow(f, l);
-}
+FF_ALL(int, w, 16, FF_ENDIAN)
+FF_ALL(u32, l, 32, FF_ENDIAN)
+FF_ALL(u64, q, 64, FF_ENDIAN)
+FF_ALL(u64, 5, 40, FF_ENDIAN)
-void bput5_slow(struct fastbuf *f, u64 l);
-static inline void bput5(struct fastbuf *f, u64 l)
-{
- if (bavailw(f) >= 5)
- {
- PUT_U40(f->bptr, l);
- f->bptr += 5;
- }
- else
- bput5_slow(f, l);
-}
+#undef GET_FUNC
+#undef PUT_FUNC
+#undef FF_ENDIAN
+#undef FF_ALL_X
+#undef FF_ALL
-/* I/O on uintptr_t */
+/* I/O on uintptr_t (only native endianity) */
#ifdef CPU_64BIT_POINTERS
#define bputa(x,p) bputq(x,p)