2 * GIOP 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: giop.h 1.14 Fri, 12 May 2000 17:21:18 +0100 jop
31 // These should be static const fields of GIOP_format, but some
32 // compilers prefer them like this.
33 #if (__BYTE_ORDER == __LITTLE_ENDIAN)
34 # define machineEndianess 1
35 #elif (__BYTE_ORDER == __BIG_ENDIAN)
36 # define machineEndianess 0
39 // Data is written to the buffer with the byte order of the local machine.
40 // When reading a buffer (which may come from a different machine), the
41 // ordering must be accounted for.
42 // These must be global due to a joint g++/glibc/i386 "feature".
43 inline void _xtl_n2hs(char const in[2], short* out, bool _bufferEndianess) {
44 if( _bufferEndianess == machineEndianess )
45 *out=*reinterpret_cast<short const*>( in );
47 *out=bswap_16(*reinterpret_cast<unsigned short const*>( in ));
50 inline void _xtl_n2hl(char const in[4], int* out, bool _bufferEndianess) {
51 if( _bufferEndianess == machineEndianess )
52 *out=*reinterpret_cast<int const*>( in );
54 *out=bswap_32(*reinterpret_cast<unsigned int const*>( in ));
57 inline void _xtl_n2hh(char const in[8], longlong* out, bool _bufferEndianess) {
58 if( _bufferEndianess == machineEndianess )
59 *out=*reinterpret_cast<longlong const*>( in );
61 *out=bswap_64(*reinterpret_cast<unsignedlonglong const*>( in ));
64 template <class Buffer>
65 class GIOP_format: public generic_format<Buffer> {
67 unsigned char bufferEndianess;
70 // Add padding so that data (of size n) is aligned on
72 int padding( int n ) {
73 int pad = ((align % n) ? (n - (align % n)) : 0);
78 char* req_align( int n ) {
79 int pad = padding( n );
80 return ( reinterpret_cast<char*>( require(n+pad) ) + pad );
83 char* des_align( int n ) {
84 int pad = padding( n );
85 return ( reinterpret_cast<char*>( desire(n+pad) ) + pad );
88 inline void h2ns( short const* in, char out[2] )
89 { *reinterpret_cast<short*>( out ) = *in; }
91 inline void h2nl( int const* in, char out[4] )
92 { *reinterpret_cast<int*>( out ) = *in; }
94 inline void h2nh( longlong const* in, char out[8] )
95 { *reinterpret_cast<longlong*>( out ) = *in; }
98 typedef Buffer buffer;
100 GIOP_format(Buffer& buf):
101 generic_format<Buffer>(buf),
102 bufferEndianess(machineEndianess),
105 // Allows data output on one machine to be read on another with
106 // (possibly) different byte ordering
108 { input_simple(bufferEndianess); }
110 void input_start_array(int& n)
112 bool input_end_array(int& n)
115 void input_simple( bool& data )
116 { data=!!*req_align(1); }
117 void input_simple( char& data )
118 { data=*req_align(1); }
119 void input_simple( unsigned char& data )
120 { data=*req_align(1); }
121 void input_simple( short& data )
122 { _xtl_n2hs(req_align(2), &data, bufferEndianess); }
123 void input_simple( unsigned short& data )
124 { _xtl_n2hs(req_align(2), reinterpret_cast<short*>( &data ), bufferEndianess); }
125 void input_simple( int& data )
126 { _xtl_n2hl(req_align(4), &data, bufferEndianess); }
127 void input_simple( unsigned int& data )
128 { _xtl_n2hl(req_align(4), reinterpret_cast<int*>( &data ), bufferEndianess); }
129 // long is stored as longlong to allow communication
130 // between 32 and 64 bit machines
131 void input_simple( long& data )
132 { _xtl_n2hh(req_align(8), reinterpret_cast<longlong*>( &data ), bufferEndianess); }
133 void input_simple( unsigned long& data )
134 { _xtl_n2hh(req_align(8), reinterpret_cast<longlong*>( &data ), bufferEndianess); }
135 void input_simple( longlong& data )
136 { _xtl_n2hh(req_align(8), &data, bufferEndianess); }
137 void input_simple( unsignedlonglong& data )
138 { _xtl_n2hh(req_align(8), reinterpret_cast<longlong*>( &data ), bufferEndianess); }
139 void input_simple( float& data )
140 {_xtl_n2hl(req_align(4), reinterpret_cast<int*>( &data ), bufferEndianess); }
141 void input_simple(double& data)
142 {_xtl_n2hh(req_align(8), reinterpret_cast<longlong*>( &data ), bufferEndianess); }
144 void input_chars(char* data, int size) {
145 input_raw(data, size);
148 void input_raw(char* data, int size) {
150 for(i=0;i<(size>>8)-1;i++,data+=256)
151 memcpy(data, require(256), 256);
153 memcpy(data, require(res), res);
157 void output_start() {
159 output_simple(bufferEndianess);
162 void output_start_array(int n) {output_simple(n);}
163 void output_end_array() {}
165 void output_simple( bool const& data )
166 { *des_align(1)=data?1:0; }
167 void output_simple( char const& data )
168 { *des_align(1)=data; }
169 void output_simple( unsigned char const& data )
170 { *des_align(1)=data; }
171 void output_simple( short const& data )
172 { h2ns(&data, des_align(2)); }
173 void output_simple( unsigned short const& data )
174 { h2ns(reinterpret_cast<short const*>( &data ), des_align(2)); }
175 void output_simple( int const& data )
176 { h2nl(&data, des_align(4)); }
177 void output_simple( unsigned int const& data )
178 { h2nl(reinterpret_cast<int const*>( &data ), des_align(4)); }
179 void output_simple( long const& data )
180 { h2nh(reinterpret_cast<longlong const*>( &data ), des_align(8)); }
181 void output_simple( unsigned long const& data )
182 { h2nh(reinterpret_cast<longlong const*>( &data ), des_align(8)); }
183 void output_simple( longlong const& data )
184 { h2nh(&data, des_align(8)); }
185 void output_simple( unsignedlonglong const& data )
186 { h2nh(reinterpret_cast<longlong const*>( &data ), des_align(8)); }
187 void output_simple( float const& data )
188 { h2nl(reinterpret_cast<int const*>( &data ), des_align(4)); }
189 void output_simple( double const& data )
190 { h2nh(reinterpret_cast<longlong const*>( &data ), des_align(8)); }
192 void output_chars(char const* data, int size) {
193 output_raw(data, size);
196 void output_raw(char const* data, int size) {
198 for(i=0;i<(size>>8)-1;i++,data+=256)
199 memcpy(desire(256), data, 256);
201 memcpy(desire(res), data, res);