]> git.lyx.org Git - lyx.git/blob - src/xtl/giop.h
Two little things:
[lyx.git] / src / xtl / giop.h
1 /*
2  * GIOP format driver for XTL
3  *
4  * Copyright (C) 1998-2000 Jose' Orlando Pereira, jop@di.uminho.pt
5  * Copyright (C) 2000 Angus Leeming, a.leeming@ic.ac.uk
6  */
7 /* XTL - eXternalization Template Library - http://gsd.di.uminho.pt/~jop/xtl
8  * Copyright (C) 1998-2000 Jose' Orlando Pereira, Universidade do Minho
9  *
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.
14  * 
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.
19  * 
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,
23  * MA 02111-1307, USA
24  *
25  * Id: giop.h 1.14 Fri, 12 May 2000 17:21:18 +0100 jop 
26  */
27
28 #ifndef __XTL_GIOP
29 #define __XTL_GIOP
30
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
37 #endif
38
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 );
46         else
47                 *out=bswap_16(*reinterpret_cast<unsigned short const*>( in ));
48 }
49
50 inline void _xtl_n2hl(char const in[4], int* out, bool _bufferEndianess) {
51         if( _bufferEndianess == machineEndianess )
52                 *out=*reinterpret_cast<int const*>( in );
53         else
54                 *out=bswap_32(*reinterpret_cast<unsigned int const*>( in ));
55 }
56
57 inline void _xtl_n2hh(char const in[8], longlong* out, bool _bufferEndianess) {
58         if( _bufferEndianess == machineEndianess )
59                 *out=*reinterpret_cast<longlong const*>( in );
60         else
61                 *out=bswap_64(*reinterpret_cast<unsignedlonglong const*>( in ));
62 }
63
64 template <class Buffer>
65 class GIOP_format: public generic_format<Buffer> {
66  private:
67         unsigned char bufferEndianess;
68         int align;
69
70         // Add padding so that data (of size n) is aligned on
71         // n byte boundaries
72         int padding( int n ) {
73                 int pad = ((align % n) ? (n - (align % n)) : 0);
74                 align += n + pad;
75                 return pad;
76         }
77
78         char* req_align( int n ) {
79                 int pad = padding( n );
80                 return ( reinterpret_cast<char*>( require(n+pad) ) + pad );
81         }
82
83         char* des_align( int n ) {
84                 int pad = padding( n );
85                 return ( reinterpret_cast<char*>( desire(n+pad) ) + pad );
86         }
87
88         inline void h2ns( short const* in, char out[2] )
89                 { *reinterpret_cast<short*>( out ) = *in; }
90
91         inline void h2nl( int const* in, char out[4] )
92                 { *reinterpret_cast<int*>( out ) = *in; }
93
94         inline void h2nh( longlong const* in, char out[8] )
95                 { *reinterpret_cast<longlong*>( out ) = *in; }
96
97  public:
98         typedef Buffer buffer;
99
100         GIOP_format(Buffer& buf):
101                 generic_format<Buffer>(buf),
102                 bufferEndianess(machineEndianess),
103                 align(0) {}
104
105         // Allows data output on one machine to be read on another with
106         // (possibly) different byte ordering
107         void input_start()
108                 { input_simple(bufferEndianess); }
109                 
110         void input_start_array(int& n)
111                 { input_simple(n); } 
112         bool input_end_array(int& n)
113                 { return n--<=0; }
114
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); }
143
144         void input_chars(char* data, int size) {
145                 input_raw(data, size);
146         }
147
148         void input_raw(char* data, int size) {
149                 int i;
150                 for(i=0;i<(size>>8)-1;i++,data+=256)
151                         memcpy(data, require(256), 256);
152                 int res=size-(i<<8);
153                 memcpy(data, require(res), res);
154                 align+=res;
155         }
156
157         void output_start() {
158                 align = 0;
159                 output_simple(bufferEndianess);
160         }
161
162         void output_start_array(int n) {output_simple(n);}
163         void output_end_array() {}
164         
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)); }
191
192         void output_chars(char const* data, int size) {
193                 output_raw(data, size);
194         }
195
196         void output_raw(char const* data, int size) {
197                 int i;
198                 for(i=0;i<(size>>8)-1;i++,data+=256)
199                         memcpy(desire(256), data, 256);
200                 int res=size-(i<<8);
201                 memcpy(desire(res), data, res);
202                 align+=res;
203         }
204 };
205
206 #endif // __XTL_GIOP