Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
e18c22520395c62638d645c715ab355c8ab64e33
[simgrid.git] / src / nws_portability / Include / formatutil.h
1 /* $Id$ */
2
3
4 #ifndef FORMATUTIL_H
5 #define FORMATUTIL_H
6
7
8 /*
9 ** This package provides utilities for translating between host and network
10 ** data formats.  It may be thought of as an extention of the Unix {hn}to{nh}*
11 ** functions or as a lightweight version of XDR.  It handles big-to-little
12 ** endian translations, integer size discrepencies, and conversions to/from
13 ** IEEE floating point format.  It does *not* presently handle either non-two's
14 ** complement integer formats or mixed-endian (e.g., little endian bytes, big
15 ** endian words) ordering.  These are so rare and generally archaic that
16 ** handling them seems not worth the added code.  Note: compiling the body of
17 ** this package with NORMAL_FP_FORMAT defined will yield a tiny performance
18 ** improvement and a small savings in code size by eliminating the IEEE
19 ** conversion code.
20 */
21
22
23 #include <stddef.h>    /* offsetof() */
24 #include <sys/types.h> /* size_t */
25
26
27 #ifdef __cplusplus
28 extern "C" {
29 #endif
30
31
32 /*
33 ** Supported data types.  "Network format" characters are one byte and longs
34 ** four bytes; otherwise, the formats are those used by Java: two byte shorts,
35 ** four byte ints and floats, eight byte doubles; two's compliment integer and
36 ** IEEE 754 floating point; most-significant bytes first.
37 */
38 typedef enum
39   {CHAR_TYPE, DOUBLE_TYPE, FLOAT_TYPE, INT_TYPE, LONG_TYPE, SHORT_TYPE,
40    UNSIGNED_INT_TYPE, UNSIGNED_LONG_TYPE, UNSIGNED_SHORT_TYPE, STRUCT_TYPE}
41   DataTypes;
42 #define SIMPLE_TYPE_COUNT 9
43 typedef enum {HOST_FORMAT, NETWORK_FORMAT} FormatTypes;
44
45
46 /*
47 ** A description of a collection of #type# data.  #repetitions# is used only
48 ** for arrays; it contains the number of elements.  #offset# is used only for
49 ** struct members in host format; it contains the offset of the member from the
50 ** beginning of the struct, taking into account internal padding added by the
51 ** compiler for alignment purposes.  #members#, #length#, and #tailPadding# are
52 ** used only for STRUCT_TYPE data; the #length#-long array #members# describes
53 ** the members of the nested struct, and #tailPadding# indicates how many
54 ** padding bytes the compiler adds to the end of the structure.
55 */
56 typedef struct DataDescriptorStruct {
57   DataTypes type;
58   size_t repetitions;
59   size_t offset;
60   struct DataDescriptorStruct *members;
61   size_t length;
62   size_t tailPadding;
63 } DataDescriptor;
64 #ifndef NULL
65 #define NULL 0
66 #endif
67 #define SIMPLE_DATA(type,repetitions) {type, repetitions, 0, NULL, 0, 0}
68 #define SIMPLE_MEMBER(type,repetitions,offset) \
69   {type, repetitions, offset, NULL, 0, 0}
70 #define PAD_BYTES(structType,lastMember,memberType,repetitions) \
71   sizeof(structType) - offsetof(structType, lastMember) - \
72   sizeof(memberType) * repetitions
73
74
75 /*
76 ** Translates the data pointed to by #source# between host and network formats
77 ** and stores the result in #destination#.  The contents of #source# are
78 ** described by the #length#-long array #description#, and #sourceFormat#
79 ** indicates whether we're translating from host format to network format or
80 ** vice versa.  The caller must insure that the memory pointed to by
81 ** #destination# is of sufficient size to contain the translated data.
82 */
83 void
84 ConvertData(void *destination,
85             const void *source,
86             const DataDescriptor *description,
87             size_t length,
88             FormatTypes sourceFormat);
89
90
91 /*
92 ** Returns the number of bytes required to hold the objects indicated by the
93 ** data described by the #length#-long array #description#.  #hostFormat#
94 ** indicates whether the host or network format size is desired.
95 */
96 size_t
97 DataSize(const DataDescriptor *description,
98          size_t length,
99          FormatTypes format);
100
101
102 /*
103 ** Returns 1 or 0 depending on whether or not the host format for #whatType#
104 ** differs from the network format.
105 */
106 int
107 DifferentFormat(DataTypes whatType);
108
109
110 /*
111 ** Returns 1 or 0 depending on whether or not the host architecture stores
112 ** data in little-endian (least significant byte first) order.
113 */
114 int
115 DifferentOrder(void);
116
117
118 /*
119 ** Returns 1 or 0 depending on whether or not the host data size for #whatType#
120 ** differs from the network data size.
121 */
122 int
123 DifferentSize(DataTypes whatType);
124
125
126 /*
127 ** These two functions are a convenience that allows callers to work with
128 ** homogenous blocks of data without setting up a DataDescriptor.  They perform
129 ** the same function as the more general function on a block of #repetitions#
130 ** occurrences of #whatType# data.
131 */
132 void
133 HomogenousConvertData(void *destination,
134                       const void *source,
135                       DataTypes whatType,
136                       size_t repetitions,
137                       FormatTypes sourceFormat);
138 size_t
139 HomogenousDataSize(DataTypes whatType,
140                    size_t repetitions,
141                    FormatTypes format);
142
143
144 /*
145 ** Copies #repetitions# data items of type #whatType# from #source# to
146 ** #destination#, reversing the bytes of each item (i.e., translates between
147 ** network and host byte order).  #format# indicates whether the data to be
148 ** reversed is in network or host format.  This is an internal package function
149 ** which is included in the interface for convenience.
150 */
151 void
152 ReverseData(void *destination,
153             const void *source,
154             DataTypes whatType,
155             int repetitions,
156             FormatTypes format);
157
158
159 #ifdef __cplusplus
160 }
161 #endif
162
163
164 #endif