Main Page | Modules | Alphabetical List | Data Structures | File List | Data Fields | Globals | Related Pages

endian.h

Go to the documentation of this file.
00001 /*
00002  * $Id: endian.h,v 1.5 2005/09/10 10:10:36 daichik Exp $
00003  *
00004  * Copyright (c) 2001-2003, Raphael Manfredi
00005  *
00006  *----------------------------------------------------------------------
00007  * This file is part of gtk-gnutella.
00008  *
00009  *  gtk-gnutella is free software; you can redistribute it and/or modify
00010  *  it under the terms of the GNU General Public License as published by
00011  *  the Free Software Foundation; either version 2 of the License, or
00012  *  (at your option) any later version.
00013  *
00014  *  gtk-gnutella is distributed in the hope that it will be useful,
00015  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  *  GNU General Public License for more details.
00018  *
00019  *  You should have received a copy of the GNU General Public License
00020  *  along with gtk-gnutella; if not, write to the Free Software
00021  *  Foundation, Inc.:
00022  *      59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00023  *----------------------------------------------------------------------
00024  */
00025 
00026 #ifndef _endian_h_
00027 #define _endian_h_
00028 
00029 #if G_BYTE_ORDER == G_BIG_ENDIAN
00030 #define guint64_to_BE(x)    x
00031 #define guint64_to_LE(x)    GUINT64_SWAP_LE_BE(x)
00032 #elif G_BYTE_ORDER == G_LITTLE_ENDIAN
00033 #define guint64_to_BE(x)    GUINT64_SWAP_LE_BE(x)
00034 #define guint64_to_LE(x)    x
00035 #else
00036 #error "Byte order not supported"
00037 #endif
00038 
00039 /*
00040  * Macros
00041  *
00042  * "a" is an address, "v" is the variable to which the value is written
00043  * in a READ operation (i.e. its address is taken).  On a WRITE operation,
00044  * the value is copied from "v", which can therefore be a manifest value.
00045  *
00046  * WATCH OUT: the order of the arguments for READ and WRITE is inverted.
00047  */
00048 
00049 /*
00050  * 16-bit
00051  */
00052 
00053 #define READ_GUINT16_LE(a,v) G_STMT_START { \
00054     STATIC_ASSERT(2 == sizeof (v));     \
00055     memcpy(&v, a, 2); v = GUINT16_FROM_LE(v); \
00056 } G_STMT_END
00057 
00058 #define WRITE_GUINT16_LE(v,a) G_STMT_START { \
00059     guint16 _v = GUINT16_TO_LE(v); memcpy(a, &_v, 2); \
00060 } G_STMT_END
00061 
00062 #define READ_GUINT16_BE(a,v) G_STMT_START { \
00063     STATIC_ASSERT(2 == sizeof (v));     \
00064     memcpy(&v, a, 2); v = ntohs(v); \
00065 } G_STMT_END
00066 
00067 #define WRITE_GUINT16_BE(v,a) G_STMT_START { \
00068     guint16 _v = htons(v); memcpy(a, &_v, 2); \
00069 } G_STMT_END
00070 
00071 /*
00072  * 32-bit
00073  */
00074 
00075 #define READ_GUINT32_LE(a,v) G_STMT_START { \
00076     STATIC_ASSERT(4 == sizeof (v));     \
00077     memcpy(&v, a, 4); v = GUINT32_FROM_LE(v); \
00078 } G_STMT_END
00079 
00080 #define READ_GUINT32_BE(a,v) G_STMT_START { \
00081     STATIC_ASSERT(4 == sizeof (v));     \
00082     memcpy(&v, a, 4); v = ntohl(v); \
00083 } G_STMT_END
00084 
00085 #define WRITE_GUINT32_LE(v,a) G_STMT_START { \
00086     guint32 _v = GUINT32_TO_LE(v); memcpy(a, &_v, 4); \
00087 } G_STMT_END
00088 
00089 #define WRITE_GUINT32_BE(v,a) G_STMT_START { \
00090     guint32 _v = htonl(v); memcpy(a, &_v, 4); \
00091 } G_STMT_END
00092 
00093 /*
00094  * 64-bit
00095  */
00096 
00097 #define READ_GUINT64_BE(a,v) G_STMT_START { \
00098     STATIC_ASSERT(8 == sizeof (v));     \
00099     memcpy(&v, a, 8); v = guint64_to_BE(v); \
00100 } G_STMT_END
00101 
00102 #define READ_GUINT64_LE(a,v) G_STMT_START { \
00103     STATIC_ASSERT(8 == sizeof (v));     \
00104     memcpy(&v, a, 8); v = guint64_to_LE(v); \
00105 } G_STMT_END
00106 
00107 #define WRITE_GUINT64_BE(v,a) G_STMT_START { \
00108     guint64 _v = guint64_to_BE(v); memcpy(a, &_v, sizeof _v); \
00109 } G_STMT_END
00110 
00111 #define WRITE_GUINT64_LE(v,a) G_STMT_START { \
00112     guint64 _v = guint64_to_LE(v); memcpy(a, &_v, sizeof _v); \
00113 } G_STMT_END
00114 
00115 /*
00116  * Alternate inline functions
00117  */
00118 
00119 static inline guint16
00120 peek_be16(gconstpointer p)
00121 {
00122     const guint8 *q = p;
00123     return q[1] | (q[0] << 8);
00124 }
00125 
00126 static inline guint32
00127 peek_be32(gconstpointer p)
00128 {
00129     const guint8 *q = p;
00130     return q[3] | (q[2] << 8) | (q[1] << 16) | (q[0] << 24);
00131 }
00132 
00133 static inline guint16
00134 peek_le16(gconstpointer p)
00135 {
00136     const guint8 *q = p;
00137     return q[0] | (q[1] << 8);
00138 }
00139 
00140 static inline guint32
00141 peek_le32(gconstpointer p)
00142 {
00143     const guint8 *q = p;
00144     return q[0] | (q[1] << 8) | (q[2] << 16) | (q[3] << 24);
00145 }
00146 
00147 /*
00148  * The poke_* functions return a pointer to the next byte after the
00149  * written bytes.
00150  */
00151 
00152 static inline gpointer
00153 poke_be16(gpointer p, guint16 v)
00154 {
00155     guint8 *q = p;
00156 
00157     q[0] = v >> 8;
00158     q[1] = v;
00159 
00160     return &q[2];
00161 }
00162 
00163 static inline gpointer
00164 poke_be32(gpointer p, guint32 v)
00165 {
00166     guint8 *q = p;
00167 
00168     q[0] = v >> 24;
00169     q[1] = v >> 16;
00170     q[2] = v >> 8;
00171     q[3] = v;
00172 
00173     return &q[4];
00174 }
00175 
00176 static inline gpointer
00177 poke_le16(gpointer p, guint16 v)
00178 {
00179     guint8 *q = p;
00180 
00181     q[0] = v;
00182     q[1] = v >> 8;
00183 
00184     return &q[2];
00185 }
00186 
00187 static inline gpointer
00188 poke_le32(gpointer p, guint32 v)
00189 {
00190     guint8 *q = p;
00191 
00192     q[0] = v;
00193     q[1] = v >> 8;
00194     q[2] = v >> 16;
00195     q[3] = v >> 24;
00196 
00197     return &q[4];
00198 }
00199 
00200 #endif /* _endian_h_ */
00201 /* vi: set ts=4 sw=4 cindent: */

Generated on Sun Feb 12 10:49:56 2006 for Gtk-Gnutella by doxygen 1.3.6