You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
134 lines
3.9 KiB
134 lines
3.9 KiB
/*
|
|
* UCW Library -- Fast Buffered I/O on Binary Values
|
|
*
|
|
* (c) 1997--2007 Martin Mares <mj@ucw.cz>
|
|
* (c) 2004 Robert Spalek <robert@ucw.cz>
|
|
*
|
|
* This software may be freely distributed and used according to the terms
|
|
* of the GNU Lesser General Public License.
|
|
*/
|
|
|
|
#ifndef _UCW_FF_BINARY_H
|
|
#define _UCW_FF_BINARY_H
|
|
|
|
#include <ucw/fastbuf.h>
|
|
#include <ucw/unaligned.h>
|
|
|
|
#ifdef CONFIG_UCW_CLEAN_ABI
|
|
#define bget5_be_slow ucw_bget5_be_slow
|
|
#define bget5_le_slow ucw_bget5_le_slow
|
|
#define bget5_slow ucw_bget5_slow
|
|
#define bgetl_be_slow ucw_bgetl_be_slow
|
|
#define bgetl_le_slow ucw_bgetl_le_slow
|
|
#define bgetl_slow ucw_bgetl_slow
|
|
#define bgetq_be_slow ucw_bgetq_be_slow
|
|
#define bgetq_le_slow ucw_bgetq_le_slow
|
|
#define bgetq_slow ucw_bgetq_slow
|
|
#define bgetw_be_slow ucw_bgetw_be_slow
|
|
#define bgetw_le_slow ucw_bgetw_le_slow
|
|
#define bgetw_slow ucw_bgetw_slow
|
|
#define bput5_be_slow ucw_bput5_be_slow
|
|
#define bput5_le_slow ucw_bput5_le_slow
|
|
#define bput5_slow ucw_bput5_slow
|
|
#define bputl_be_slow ucw_bputl_be_slow
|
|
#define bputl_le_slow ucw_bputl_le_slow
|
|
#define bputl_slow ucw_bputl_slow
|
|
#define bputq_be_slow ucw_bputq_be_slow
|
|
#define bputq_le_slow ucw_bputq_le_slow
|
|
#define bputq_slow ucw_bputq_slow
|
|
#define bputw_be_slow ucw_bputw_be_slow
|
|
#define bputw_le_slow ucw_bputw_le_slow
|
|
#define bputw_slow ucw_bputw_slow
|
|
#endif
|
|
|
|
#ifdef CPU_BIG_ENDIAN
|
|
#define FF_ENDIAN be
|
|
#else
|
|
#define FF_ENDIAN le
|
|
#endif
|
|
|
|
/***
|
|
*
|
|
* We define several functions to read or write binary integer values.
|
|
*
|
|
* The name patterns for such routines are:
|
|
*
|
|
* - `TYPE bget \#\# NAME \#\# ENDIAN(struct fastbuf *f);`
|
|
* - `void bput \#\# NAME \#\# ENDIAN(struct fastbuf *f, TYPE value);`
|
|
*
|
|
* where `NAME` together with `TYPE` can be:
|
|
*
|
|
* - `w` for 16-bit unsigned integers stored in sequences of 2 bytes, the `TYPE` is int
|
|
* - `l` for 32-bit unsigned integers stored in sequences of 4 bytes, the `TYPE` is uint
|
|
* - `5` for 40-bit unsigned integers stored in sequences of 5 bytes, the `TYPE` is u64
|
|
* - `q` for 64-bit unsigned integers stored in sequences of 8 bytes, the `TYPE` is u64
|
|
*
|
|
* and supported `ENDIAN` suffixes are:
|
|
*
|
|
* - empty for the default order of bytes (defined by CPU)
|
|
* - `_le` for little-endian
|
|
* - `_be` for big-endian
|
|
*
|
|
* If we fail to read enough bytes because of EOF, the reading function returns `(TYPE)-1`.
|
|
*
|
|
***/
|
|
|
|
#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); \
|
|
}
|
|
|
|
#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); \
|
|
}
|
|
|
|
#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); }
|
|
|
|
#define FF_ALL(type, name, bits, defendian) FF_ALL_X(type, name, bits, defendian)
|
|
|
|
FF_ALL(int, w, 16, FF_ENDIAN)
|
|
FF_ALL(uint, l, 32, FF_ENDIAN)
|
|
FF_ALL(u64, q, 64, FF_ENDIAN)
|
|
FF_ALL(u64, 5, 40, FF_ENDIAN)
|
|
|
|
#undef GET_FUNC
|
|
#undef PUT_FUNC
|
|
#undef FF_ENDIAN
|
|
#undef FF_ALL_X
|
|
#undef FF_ALL
|
|
|
|
/* I/O on uintptr_t (only native endianity) */
|
|
|
|
#ifdef CPU_64BIT_POINTERS
|
|
#define bputa(x,p) bputq(x,p)
|
|
#define bgeta(x) bgetq(x)
|
|
#else
|
|
#define bputa(x,p) bputl(x,p)
|
|
#define bgeta(x) bgetl(x)
|
|
#endif
|
|
|
|
#endif
|
|
|