diff --git a/CHANGES b/CHANGES index 077ea77..b6c56fb 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,5 @@ 0.28: + add uint64 pack and unpack routines 0.27: add fmt_strm diff --git a/test/uint.c b/test/uint.c new file mode 100644 index 0000000..b8e87f3 --- /dev/null +++ b/test/uint.c @@ -0,0 +1,66 @@ +#include +#include +#include +#include +#include + +int main() { + char buf[8]; + + { + uint16 a; + + buf[0]=buf[1]=0; + uint16_pack_big(buf,0x1234); + assert(buf[0]==0x12 && buf[1]==0x34); + uint16_unpack_big(buf,&a); + assert(a==0x1234); + assert(uint16_read_big(buf)==0x1234); + + buf[0]=buf[1]=0; + uint16_pack(buf,0x1234); + assert(buf[0]==0x34 && buf[1]==0x12); + uint16_unpack(buf,&a); + assert(a==0x1234); + assert(uint16_read(buf)==0x1234); + } + + { + uint32 a; + + buf[0]=buf[1]=buf[2]=buf[3]=0; + uint32_pack_big(buf,0x12345678); + assert(buf[0]==0x12 && buf[1]==0x34 && buf[2]==0x56 && buf[3]==0x78); + uint32_unpack_big(buf,&a); + assert(a==0x12345678); + assert(uint32_read_big(buf)==0x12345678); + + buf[0]=buf[1]=buf[2]=buf[3]=0; + uint32_pack(buf,0x12345678); + assert(buf[0]==0x78 && buf[1]==0x56 && buf[2]==0x34 && buf[3]==0x12); + uint32_unpack(buf,&a); + assert(a==0x12345678); + assert(uint32_read(buf)==0x12345678); + } + + { + uint64 a; + unsigned int i; + + byte_zero(buf,sizeof(buf)); + uint64_pack_big(buf,0x0102030405060708ull); + for (i=0; i<8; ++i) assert(buf[i]==i+1); + uint64_unpack_big(buf,&a); + assert(a==0x0102030405060708ull); + assert(uint64_read_big(buf)==0x0102030405060708ull); + + byte_zero(buf,sizeof(buf)); + uint64_pack(buf,0x0102030405060708ull); + for (i=0; i<8; ++i) assert(buf[7-i]==i+1); + uint64_unpack(buf,&a); + assert(a==0x0102030405060708ull); + assert(uint64_read(buf)==0x0102030405060708ull); + } + + +} diff --git a/uint/uint32_pack_big.3 b/uint/uint32_pack_big.3 index 3ab8311..84c15c5 100644 --- a/uint/uint32_pack_big.3 +++ b/uint/uint32_pack_big.3 @@ -11,7 +11,7 @@ void \fBuint32_pack_big\fP(char \fIs\fR[4],uint32 \fIu\fR); uint32 is a 32-bit unsigned integer type, normally either unsigned int or unsigned long. -uint32_pack_big portably writes a uint16 \fIu\fR to \fIs\fR in +uint32_pack_big portably writes a uint32 \fIu\fR to \fIs\fR in big-endian (i.e. network) byte order. .SH "SEE ALSO" diff --git a/uint/uint64_pack.3 b/uint/uint64_pack.3 new file mode 100644 index 0000000..b901d6b --- /dev/null +++ b/uint/uint64_pack.3 @@ -0,0 +1,17 @@ +.TH uint64_pack 3 +.SH NAME +uint64_pack \- write an unsigned little-endian 64-bit integer +.SH SYNTAX +.B #include + +uint64 \fIu\fR; + +void \fBuint64_pack\fP(char \fIs\fR[4],uint64 \fIu\fR); +.SH DESCRIPTION +uint64 is a 64-bit unsigned integer type. + +uint64_pack portably writes a uint64 \fIu\fR to \fIs\fR in +little-endian byte order. + +.SH "SEE ALSO" +uint64_unpack(3), uint64_pack_big(3) diff --git a/uint/uint64_pack.c b/uint/uint64_pack.c new file mode 100644 index 0000000..bb9a8ba --- /dev/null +++ b/uint/uint64_pack.c @@ -0,0 +1,8 @@ +#define NO_UINT64_MACROS +#include "uint64.h" +#include "uint32.h" + +void uint64_pack(char *out,uint64 in) { + uint32_pack(out,in&0xffffffff); + uint32_pack(out+4,in>>32); +} diff --git a/uint/uint64_pack_big.3 b/uint/uint64_pack_big.3 new file mode 100644 index 0000000..3c683eb --- /dev/null +++ b/uint/uint64_pack_big.3 @@ -0,0 +1,17 @@ +.TH uint64_pack_big 3 +.SH NAME +uint64_pack_big \- write an unsigned big-endian 64-bit integer +.SH SYNTAX +.B #include + +uint64 \fIu\fR; + +void \fBuint64_pack_big\fP(char \fIs\fR[4],uint64 \fIu\fR); +.SH DESCRIPTION +uint64 is a 64-bit unsigned integer type. + +uint64_pack_big portably writes a uint64 \fIu\fR to \fIs\fR in +big-endian (i.e. network) byte order. + +.SH "SEE ALSO" +uint64_unpack_big(3), uint64_pack(3) diff --git a/uint/uint64_pack_big.c b/uint/uint64_pack_big.c new file mode 100644 index 0000000..7948bc6 --- /dev/null +++ b/uint/uint64_pack_big.c @@ -0,0 +1,8 @@ +#define NO_UINT64_MACROS +#include "uint64.h" +#include "uint32.h" + +void uint64_pack_big(char *out,uint64 in) { + uint32_pack_big(out,in>>32); + uint32_pack_big(out+4,in&0xffffffff); +} diff --git a/uint/uint64_read.3 b/uint/uint64_read.3 new file mode 100644 index 0000000..78b04aa --- /dev/null +++ b/uint/uint64_read.3 @@ -0,0 +1,15 @@ +.TH uint64_read 3 +.SH NAME +uint64_read \- read an unsigned little-endian 64-bit integer +.SH SYNTAX +.B #include + +uint64 \fBuint64_read\fP(const char \fIs\fR[4]); +.SH DESCRIPTION +uint64 is a 64-bit unsigned integer type. + +uint64_read portably reads a uint64 as stored on a little-endian +architecture from \fIs\fR and returns it. + +.SH "SEE ALSO" +uint64_unpack(3), uint64_unpack_big(3) diff --git a/uint/uint64_read.c b/uint/uint64_read.c new file mode 100644 index 0000000..b9051b6 --- /dev/null +++ b/uint/uint64_read.c @@ -0,0 +1,7 @@ +#define NO_UINT64_MACROS +#include "uint64.h" +#include "uint32.h" + +uint64 uint64_read(const char *in) { + return uint32_read(in) | ((uint64)uint32_read(in+4)<<32); +} diff --git a/uint/uint64_read_big.3 b/uint/uint64_read_big.3 new file mode 100644 index 0000000..7d5e08f --- /dev/null +++ b/uint/uint64_read_big.3 @@ -0,0 +1,15 @@ +.TH uint64_read_big 3 +.SH NAME +uint64_read_big \- read an unsigned big-endian 64-bit integer +.SH SYNTAX +.B #include + +uint64 \fBuint64_read_big\fP(const char \fIs\fR[4]); +.SH DESCRIPTION +uint64 is a 64-bit unsigned integer type. + +uint64_read_big portably reads a uint64 as stored on a big-endian +architecture from \fIs\fR and returns it. + +.SH "SEE ALSO" +uint64_unpack(3), uint64_unpack_big(3) diff --git a/uint/uint64_read_big.c b/uint/uint64_read_big.c new file mode 100644 index 0000000..02261a5 --- /dev/null +++ b/uint/uint64_read_big.c @@ -0,0 +1,7 @@ +#define NO_UINT64_MACROS +#include "uint64.h" +#include "uint32.h" + +uint64 uint64_read_big(const char *in) { + return ((uint64)uint32_read_big(in)<<32) | uint32_read_big(in+4); +} diff --git a/uint/uint64_unpack.3 b/uint/uint64_unpack.3 new file mode 100644 index 0000000..c1bc00d --- /dev/null +++ b/uint/uint64_unpack.3 @@ -0,0 +1,17 @@ +.TH uint64_unpack 3 +.SH NAME +uint64_unpack \- read an unsigned little-endian 64-bit integer +.SH SYNTAX +.B #include + +uint64 \fIu\fR; + +void \fBuint64_unpack\fP(const char \fIs\fR[4],uint64 *\fIu\fR); +.SH DESCRIPTION +uint64 is a 64-bit unsigned integer type. + +uint64_unpack portably reads a uint64 as stored on a little-endian +architecture from \fIs\fR and writes it into \fIu\fR in the native byte order. + +.SH "SEE ALSO" +uint64_pack(3), uint64_unpack_big(3) diff --git a/uint/uint64_unpack.c b/uint/uint64_unpack.c new file mode 100644 index 0000000..c602c94 --- /dev/null +++ b/uint/uint64_unpack.c @@ -0,0 +1,7 @@ +#define NO_UINT64_MACROS +#include "uint64.h" +#include "uint32.h" + +void uint64_unpack(const char *in,uint64 *out) { + *out = uint64_read(in); +} diff --git a/uint/uint64_unpack_big.3 b/uint/uint64_unpack_big.3 new file mode 100644 index 0000000..473ca58 --- /dev/null +++ b/uint/uint64_unpack_big.3 @@ -0,0 +1,18 @@ +.TH uint64_unpack_big 3 +.SH NAME +uint64_unpack_big \- read an unsigned big-endian 64-bit integer +.SH SYNTAX +.B #include + +uint64 \fIu\fR; + +void \fBuint64_unpack_big\fP(const char \fIs\fR[4],uint64 *\fIu\fR); +.SH DESCRIPTION +uint64 is a 64-bit unsigned integer type. + +uint64_unpack_big portably reads a uint64 as stored on a big-endian +architecture (i.e. in network byte order) from \fIs\fR and writes it +into \fIu\fR in the native byte order. + +.SH "SEE ALSO" +uint64_pack_big(3), uint64_unpack(3) diff --git a/uint/uint64_unpack_big.c b/uint/uint64_unpack_big.c new file mode 100644 index 0000000..7b2af4e --- /dev/null +++ b/uint/uint64_unpack_big.c @@ -0,0 +1,7 @@ +#define NO_UINT64_MACROS +#include "uint64.h" +#include "uint32.h" + +void uint64_unpack_big(const char *in,uint64 *out) { + *out = uint64_read_big(in); +} diff --git a/uint16.h b/uint16.h index b7726f3..f1e7324 100644 --- a/uint16.h +++ b/uint16.h @@ -6,7 +6,7 @@ typedef uint16_t uint16; typedef int16_t int16; -#if defined(__i386__) && !defined(NO_UINT16_MACROS) +#if (defined(__i386__) || defined(__x86_64__)) && !defined(NO_UINT16_MACROS) #define uint16_pack(out,in) (*(uint16*)(out)=(in)) #define uint16_unpack(in,out) (*(out)=*(uint16*)(in)) #define uint16_read(in) (*(uint16*)(in)) diff --git a/uint32.h b/uint32.h index 8748f5c..fbfe039 100644 --- a/uint32.h +++ b/uint32.h @@ -6,7 +6,7 @@ typedef uint32_t uint32; typedef int32_t int32; -#if defined(__i386__) && !defined(NO_UINT32_MACROS) +#if (defined(__i386__) || defined(__x86_64__)) && !defined(NO_UINT32_MACROS) #define uint32_pack(out,in) (*(uint32*)(out)=(in)) #define uint32_unpack(in,out) (*(out)=*(uint32*)(in)) #define uint32_read(in) (*(uint32*)(in)) diff --git a/uint64.h b/uint64.h index 5209109..8188fe8 100644 --- a/uint64.h +++ b/uint64.h @@ -6,4 +6,22 @@ typedef uint64_t uint64; typedef int64_t int64; +#if (defined(__i386__) || defined(__x86_64__)) && !defined(NO_UINT64_MACROS) +#define uint64_pack(out,in) (*(uint64*)(out)=(in)) +#define uint64_unpack(in,out) (*(out)=*(uint64*)(in)) +#define uint64_read(in) (*(uint64*)(in)) +void uint64_pack_big(char *out,uint64 in); +void uint64_unpack_big(const char *in,uint64* out); +uint64 uint64_read_big(const char *in); +#else + +void uint64_pack(char *out,uint64 in); +void uint64_pack_big(char *out,uint64 in); +void uint64_unpack(const char *in,uint64* out); +void uint64_unpack_big(const char *in,uint64* out); +uint64 uint64_read(const char *in); +uint64 uint64_read_big(const char *in); + +#endif + #endif