From: Martin Mares Date: Sat, 10 Mar 2007 21:10:49 +0000 (+0100) Subject: Rewritten ff-binary. X-Git-Tag: holmes-import~506^2~98^2~2 X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=e22bedb2382ad8c11b00e26b67fadecd30fa90fd;p=libucw.git Rewritten ff-binary. It now supports reading/writing in a specified endianity as well as the native format. --- diff --git a/lib/ff-binary.c b/lib/ff-binary.c index 982cc8b7..5729722a 100644 --- a/lib/ff-binary.c +++ b/lib/ff-binary.c @@ -11,108 +11,24 @@ #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) diff --git a/lib/ff-binary.h b/lib/ff-binary.h index 150413c1..39e636a2 100644 --- a/lib/ff-binary.h +++ b/lib/ff-binary.h @@ -14,111 +14,61 @@ #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)