changeset 5:8552edc844a7

Re-wrote endianess handling.
author Matti Hamalainen <ccr@tnsp.org>
date Sun, 20 Apr 2008 00:13:49 +0300
parents 67f4a4233372
children 2f92373537b5
files th_endian.c th_endian.h th_endian2.h
diffstat 3 files changed, 125 insertions(+), 152 deletions(-) [+]
line wrap: on
line diff
--- a/th_endian.c	Wed Mar 26 05:10:20 2008 +0200
+++ b/th_endian.c	Sun Apr 20 00:13:49 2008 +0300
@@ -6,91 +6,47 @@
  * Please read file 'COPYING' for information on license and distribution.
  */
 #include "th_endian.h"
-#include <stdio.h>
 
 
-/*
- * Endianess conversion routines
- */
-#ifdef TH_BIGENDIAN
-/* Convert to from Small Endian
- */
-void TH_NE16(uint16_t * iVal)
+BOOL th_read_str(FILE *f, uint8_t *s, size_t l)
 {
-	uint16_t r = *iVal;
-	*iVal = ((r & 0xff) << 8) | ((r >> 8) & 0xff);
-}
-
-
-void TH_NE32(uint32_t * iVal)
-{
-	uint32_t r = *iVal;
-	*iVal = ((r & 0xff) << 8) | ((r >> 8) & 0xff) |
-	    ((r & 0x00ff0000L) << 8) | ((r >> 8) & 0x00ff0000L);
+    return (fread(s, sizeof(uint8_t), l, f) == l);
 }
 
 
-/* Convert to Small/Little Endian
- */
-uint16_t TH_LE16(uint16_t iVal)
-{
-	return ((iVal & 0xff) << 8) | ((iVal >> 8) & 0xff);
-}
-
-
-uint32_t TH_LE32(uint32_t iVal)
-{
-	return ((iVal & 0xff) << 8) | ((iVal >> 8) & 0xff) |
-	    ((iVal & 0x00ff0000L) << 8) | ((iVal >> 8) & 0x00ff0000L);
-}
-#endif		/* TH_BIGENDIAN */
-
-
-/*
- * File routines for endian-dependant data
- */
-#define TH_FILE FILE
-#define TH_FREAD fread
-#define TH_FGETC fgetc
-#define TH_RNAME(X) TH_READ_##X
-#define TH_CODE_ENDIAN2
-#include "th_endian2.h"
-#undef TH_CODE_ENDIAN2
-
-
-BOOL TH_WRITE_STR(FILE * f, uint8_t * s, size_t l)
+BOOL th_write_str(FILE * f, uint8_t * s, size_t l)
 {
 	return (fwrite(s, sizeof(uint8_t), l, f) == l);
 }
 
 
-void TH_WRITE_BE16(FILE * f, uint16_t v)
-{
-	fputc((v >> 8) & 0xFF, f);
-	fputc(v & 0xFF, f);
-}
-
-
-void TH_WRITE_BE32(FILE * f, uint32_t v)
-{
-	fputc((v >> 24) & 0xFF, f);
-	fputc((v >> 16) & 0xFF, f);
-	fputc((v >> 8) & 0xFF, f);
-	fputc(v & 0xFF, f);
+/* File routines for endian-dependant data
+ */
+#define TH_DEFINE_FUNC(xname, xtype, xmacro)        \
+BOOL th_read_ ## xname (FILE *f, xtype *v) {        \
+    xtype result;                                   \
+    if (fread(&result, sizeof( xtype ), 1, f) != 1) \
+        return FALSE;                               \
+    *v = TH_ ## xmacro ## _TO_NATIVE (result);      \
+    return TRUE;                                    \
+}                                                   \
+                                                    \
+BOOL th_write_ ## xname (FILE *f, xtype v) {        \
+    xtype result = TH_NATIVE_TO_ ## xmacro (v);     \
+    if (fwrite(&result, sizeof( xtype ), 1, f) != 1) \
+        return FALSE;                               \
+    return TRUE;                                    \
 }
 
+TH_DEFINE_FUNC(le16, uint16_t, LE16)
+TH_DEFINE_FUNC(le32, uint32_t, LE32)
 
-void TH_WRITE_LE16(FILE * f, uint16_t v)
-{
-	fputc(v & 0xFF, f);
-	fputc((v >> 8) & 0xFF, f);
-}
-
+TH_DEFINE_FUNC(be16, uint16_t, BE16)
+TH_DEFINE_FUNC(be32, uint32_t, BE32)
 
-void TH_WRITE_LE32(FILE * f, uint32_t v)
-{
-	fputc(v & 0xFF, f);
-	fputc((v >> 8) & 0xFF, f);
-	fputc((v >> 16) & 0xFF, f);
-	fputc((v >> 24) & 0xFF, f);
-}
+#ifdef TH_HAVE_64BIT
+TH_DEFINE_FUNC(le64, uint64_t, LE64)
+TH_DEFINE_FUNC(be64, uint64_t, BE64)
+#endif
+
+#undef TH_DEFINE_FUNC
--- a/th_endian.h	Wed Mar 26 05:10:20 2008 +0200
+++ b/th_endian.h	Sun Apr 20 00:13:49 2008 +0300
@@ -8,46 +8,112 @@
 #ifndef _TH_ENDIAN_H
 #define _TH_ENDIAN_H
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 #ifdef HAVE_CONFIG_H
-#include "config.h"
+#  include "config.h"
 #endif
 #include <stdio.h>
 #include "th_types.h"
 
-/*
- * Data endianess conversion routines
- */
-#ifdef TH_BIGENDIAN
-void		TH_NE16(uint16_t *);
-void		TH_NE32(uint32_t *);
-uint16_t	TH_LE16(uint16_t);
-uint32_t	TH_LE32(uint32_t);
-#else
-#define		TH_NE16(X)
-#define		TH_NE32(X)
-#define		TH_LE16(X) X
-#define		TH_LE32(X) X
+#ifdef __cplusplus
+extern "C" {
 #endif
 
 
-/*
- * Endian-handling file read/write routines
+/* Endianess swapping macros
+ */
+#define TH_SWAP_16_LE_BE(value)	((uint16_t) (   \
+    (uint16_t) ((uint16_t) (value) >> 8) |      \
+    (uint16_t) ((uint16_t) (value) << 8)) )
+
+
+#define TH_SWAP_32_LE_BE(value) ((uint32_t) (               \
+    (((uint32_t) (value) & (uint32_t) 0x000000ffU) << 24) | \
+    (((uint32_t) (value) & (uint32_t) 0x0000ff00U) <<  8) | \
+    (((uint32_t) (value) & (uint32_t) 0x00ff0000U) >>  8) | \
+    (((uint32_t) (value) & (uint32_t) 0xff000000U) >> 24)))
+
+#ifdef TH_HAVE_64BIT
+#define TH_SWAP_64_LE_BE(value) ((uint64_t) (                           \
+    (((uint64_t) (value) & (uint64_t) 0x00000000000000ffULL) << 56) |   \
+    (((uint64_t) (value) & (uint64_t) 0x000000000000ff00ULL) << 40) |   \
+    (((uint64_t) (value) & (uint64_t) 0x0000000000ff0000ULL) << 24) |   \
+    (((uint64_t) (value) & (uint64_t) 0x00000000ff000000ULL) <<  8) |   \
+    (((uint64_t) (value) & (uint64_t) 0x000000ff00000000ULL) >>  8) |   \
+    (((uint64_t) (value) & (uint64_t) 0x0000ff0000000000ULL) >> 24) |   \
+    (((uint64_t) (value) & (uint64_t) 0x00ff000000000000ULL) >> 40) |   \
+    (((uint64_t) (value) & (uint64_t) 0xff00000000000000ULL) >> 56)))
+#endif
+
+/* Macros that swap only when needed ...
  */
-BOOL		TH_READ_STR(FILE *f, uint8_t *s, size_t l);
-uint16_t	TH_READ_BE16(FILE *f);
-uint32_t	TH_READ_BE32(FILE *f);
-uint16_t	TH_READ_LE16(FILE *f);
-uint32_t	TH_READ_LE32(FILE *f);
+#ifdef TH_BIGENDIAN
+
+#define TH_LE16_TO_NATIVE(value) TH_SWAP_16_LE_BE(value)
+#define TH_LE32_TO_NATIVE(value) TH_SWAP_32_LE_BE(value)
+#define TH_NATIVE_TO_LE16(value) TH_SWAP_16_LE_BE(value)
+#define TH_NATIVE_TO_LE32(value) TH_SWAP_32_LE_BE(value)
+
+#define TH_BE16_TO_NATIVE(value) ((uint16_t) (value))
+#define TH_BE32_TO_NATIVE(value) ((uint32_t) (value))
+#define TH_NATIVE_TO_BE16(value) ((uint16_t) (value))
+#define TH_NATIVE_TO_BE32(value) ((uint32_t) (value))
+
+#ifdef TH_HAVE_64BIT
+#define TH_LE64_TO_NATIVE(value) TH_SWAP_64_LE_BE(value)
+#define TH_NATIVE_TO_LE64(value) TH_SWAP_64_LE_BE(value)
+#define TH_BE64_TO_NATIVE(value) ((uint64_t) (value))
+#define TH_NATIVE_TO_BE64(value) ((uint64_t) (value))
+#endif
+
+#else /* !TH_BIGENDIAN */
+
+#define TH_LE16_TO_NATIVE(value) ((uint16_t) (value))
+#define TH_LE32_TO_NATIVE(value) ((uint32_t) (value))
+#define TH_NATIVE_TO_LE16(value) ((uint16_t) (value))
+#define TH_NATIVE_TO_LE32(value) ((uint32_t) (value))
+
+#define TH_BE16_TO_NATIVE(value) TH_SWAP_16_LE_BE(value)
+#define TH_BE32_TO_NATIVE(value) TH_SWAP_32_LE_BE(value)
+#define TH_NATIVE_TO_BE16(value) TH_SWAP_16_LE_BE(value)
+#define TH_NATIVE_TO_BE32(value) TH_SWAP_32_LE_BE(value)
 
-BOOL		TH_WRITE_STR(FILE *f, uint8_t *s, size_t l);
-void		TH_WRITE_BE16(FILE *f, uint16_t v);
-void		TH_WRITE_BE32(FILE *f, uint32_t v);
-void		TH_WRITE_LE16(FILE *f, uint16_t v);
-void		TH_WRITE_LE32(FILE *f, uint32_t v);
+#ifdef TH_HAVE_64BIT
+#define TH_LE64_TO_NATIVE(value) ((uint64_t) (value))
+#define TH_NATIVE_TO_LE64(value) ((uint64_t) (value))
+#define TH_BE64_TO_NATIVE(value) TH_SWAP_64_LE_BE(value)
+#define TH_NATIVE_TO_BE64(value) TH_SWAP_64_LE_BE(value)
+#endif
+
+#endif
+
+
+/* Endian-handling file read/write routines
+ */
+BOOL    th_read_str(FILE *f, uint8_t *s, size_t l);
+BOOL    th_write_str(FILE *f, uint8_t *s, size_t l);
+
+#define TH_DEFINE_HEADER(xname, xtype)          \
+BOOL    th_read_ ## xname (FILE *f, xtype *v);  \
+BOOL    th_write_ ## xname (FILE *f, xtype v);
+
+TH_DEFINE_HEADER(le16, uint16_t)
+TH_DEFINE_HEADER(le32, uint32_t)
+
+TH_DEFINE_HEADER(be16, uint16_t)
+TH_DEFINE_HEADER(be32, uint32_t)
+
+#ifdef TH_HAVE_64BIT
+TH_DEFINE_HEADER(be64, uint64_t)
+TH_DEFINE_HEADER(le64, uint64_t)
+#endif
+
+#undef TH_DEFINE_HEADER
+
+/* Cause warnings for old functions */
+#define TH_READ_LE16    fdksajlkfdsljf lol
+#define TH_READ_LE32    fdksajlkfdsljf lol
+#define TH_READ_BE16    fdksajlkfdsljf lol
+#define TH_READ_BE32    fdksajlkfdsljf lol
 
 #ifdef __cplusplus
 }
--- a/th_endian2.h	Wed Mar 26 05:10:20 2008 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-/*
- * Endianess handling
- * Programmed and designed by Matti 'ccr' Hamalainen
- * (C) Copyright 2002-2007 Tecnic Software productions (TNSP)
- *
- * Please read file 'COPYING' for information on license and distribution.
- */
-#if (!defined(TH_RNAME) || !defined(TH_FILE) || !defined(TH_FREAD) || !defined(TH_FGETC))
-#error Some required preprocessor macros NOT defined, but th_endian2.h included!
-#endif
-
-#ifdef TH_CODE_ENDIAN2
-BOOL TH_RNAME(STR) (TH_FILE *f, uint8_t *s, size_t l)
-{
-	return (TH_FREAD(s, sizeof(uint8_t), l, f) == l);
-}
-
-
-uint16_t TH_RNAME(BE16) (TH_FILE *f)
-{
-	return (((uint16_t) TH_FGETC(f)) << 8) |
-		((uint16_t) TH_FGETC(f));
-}
-
-
-uint32_t TH_RNAME(BE32) (TH_FILE *f)
-{
-	return (((uint32_t) TH_FGETC(f)) << 24) |
-		(((uint32_t) TH_FGETC(f)) << 16) |
-		(((uint32_t) TH_FGETC(f)) << 8) |
-		((uint32_t) TH_FGETC(f));
-}
-
-
-uint16_t TH_RNAME(LE16) (TH_FILE *f)
-{
-	return ((uint16_t) TH_FGETC(f)) |
-		(((uint16_t) TH_FGETC(f)) << 8);
-}
-
-
-uint32_t TH_RNAME(LE32) (TH_FILE *f)
-{
-	return ((uint32_t) TH_FGETC(f)) |
-		(((uint32_t) TH_FGETC(f)) << 8) |
-		(((uint32_t) TH_FGETC(f)) << 16) |
-		(((uint32_t) TH_FGETC(f)) << 24);
-}
-#endif