2 * XDR format driver for XTL
4 * Copyright (C) 1998-2000 Jose' Orlando Pereira, jop@di.uminho.pt
5 * Copyright (C) 2000 Angus Leeming, a.leeming@ic.ac.uk
7 /* XTL - eXternalization Template Library - http://gsd.di.uminho.pt/~jop/xtl
8 * Copyright (C) 1998-2000 Jose' Orlando Pereira, Universidade do Minho
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Library General Public
12 * License as published by the Free Software Foundation; either
13 * version 2 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Library General Public License for more details.
20 * You should have received a copy of the GNU Library General Public
21 * License along with this library; if not, write to the Free
22 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
25 * Id: xdr.h 1.16 Fri, 12 May 2000 17:21:18 +0100 jop
31 // Macros to keep things neat and tidy in class XDR_format.
32 // All data is stored in 32 bit chunks (XDR standard), those
33 // types longer than 32 bits being accessed through a union to avoid
34 // "unaligned access errors" on 64 bit machines.
35 #define def_input_simple_i(type1, type2) \
36 void input_simple(type1& data) { \
38 _xtl_big_end( reinterpret_cast<char*>( require(4) ), \
39 reinterpret_cast<char*>( &store ) ); \
40 data = static_cast<type1>( store ); \
43 #define def_input_simple_ll(type1, type2) \
44 void input_simple(type1& data) { \
45 union { type2 ll; int i[2]; } store; \
46 _xtl_big_end( reinterpret_cast<char*>( require(4) ), \
47 reinterpret_cast<char*>( &store.i[0] ) ); \
48 _xtl_big_end( reinterpret_cast<char*>( require(4) ), \
49 reinterpret_cast<char*>( &store.i[1] ) ); \
50 data = static_cast<type1>( store.ll ); \
53 #define def_output_simple_i(type1, type2) \
54 void output_simple(type1 const& data) { \
55 type2 store = static_cast<type2>( data ); \
56 _xtl_big_end( reinterpret_cast<char*>( &store ), \
57 reinterpret_cast<char*>( require(4) ) ); \
60 #define def_output_simple_ll(type1, type2) \
61 void output_simple(type1 const& data) { \
62 union { type2 ll; int i[2]; } store; \
63 store.ll = static_cast<type2>( data ); \
64 _xtl_big_end( reinterpret_cast<char*>( &store.i[0] ), \
65 reinterpret_cast<char*>( require(4) ) ); \
66 _xtl_big_end( reinterpret_cast<char*>( &store.i[1] ), \
67 reinterpret_cast<char*>( require(4) ) ); \
70 // data is stored with big endian ordering (XDR standard)
71 // this must be global due to a joint g++/glibc/i386 "feature"
72 #if (__BYTE_ORDER == __LITTLE_ENDIAN)
73 inline void _xtl_big_end(char const in[], char out[]) {
74 *reinterpret_cast<unsigned int*>(out) =
75 bswap_32(*reinterpret_cast<const unsigned int*>(in));
78 #elif (__BYTE_ORDER == __BIG_ENDIAN)
79 void _xtl_big_end(char const in[], char out[]) {
80 *reinterpret_cast<unsigned int*>(out) =
81 *reinterpret_cast<const unsigned int*>(in);
85 template <class Buffer>
86 class XDR_format: public generic_format<Buffer> {
89 typedef Buffer buffer;
91 XDR_format(Buffer& buf):generic_format<Buffer>(buf) {}
93 void input_start_array(int& n) {input_simple(n);}
94 bool input_end_array(int& n) {return n--<=0;}
96 def_input_simple_i(bool, int)
97 def_input_simple_i(char, int)
98 def_input_simple_i(unsigned char, int)
99 def_input_simple_i(short, int)
100 def_input_simple_i(unsigned short, int)
101 def_input_simple_i(int, int)
102 def_input_simple_i(unsigned int, int)
103 def_input_simple_i(long, int)
104 def_input_simple_i(unsigned long, int)
105 def_input_simple_ll(longlong, longlong)
106 def_input_simple_ll(unsignedlonglong, longlong)
107 def_input_simple_i(float, float)
108 def_input_simple_ll(double, double)
110 void input_chars(char* data, int size) {
111 input_raw(data, size);
114 // This routine is identical to that in GIOP_format
115 void input_raw(char* data, int size) {
117 for(i=0;i<(size>>8)-1;i++,data+=256)
118 memcpy(data, require(256), 256);
120 memcpy(data, require(res), res);
125 void output_start_array(int n) {output_simple(n);}
126 void output_end_array() {}
128 def_output_simple_i(bool, int)
129 def_output_simple_i(char, int)
130 def_output_simple_i(unsigned char, int)
131 def_output_simple_i(short, int)
132 def_output_simple_i(unsigned short, int)
133 def_output_simple_i(int, int)
134 def_output_simple_i(unsigned int, int)
135 def_output_simple_i(long, int)
136 def_output_simple_i(unsigned long, int)
137 def_output_simple_ll(longlong, longlong)
138 def_output_simple_ll(unsignedlonglong, longlong)
139 def_output_simple_i(float, float)
140 def_output_simple_ll(double, double)
142 void output_chars(char const* data, int size) {
143 output_raw(data, size);
146 // This routine is identical to that in GIOP_format
147 void output_raw(char const* data, int size) {
149 for(i=0;i<(size>>8)-1;i++,data+=256)
150 memcpy(desire(256), data, 256);
152 memcpy(desire(res), data, res);
154 memset(desire(4-res%4), 0, 4-res%4);
158 #undef def_input_simple_i
159 #undef def_input_simple_ll
160 #undef def_output_simple_i
161 #undef def_output_simple_ll