]> git.lyx.org Git - lyx.git/blob - src/xtl/xdr.h
fix typo that put too many include paths for most people
[lyx.git] / src / xtl / xdr.h
1 /*
2  * XDR 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: xdr.h 1.16 Fri, 12 May 2000 17:21:18 +0100 jop 
26  */
27
28 #ifndef __XTL_XDR
29 #define __XTL_XDR
30
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) { \
37                 type2 store; \
38                 _xtl_big_end( reinterpret_cast<char*>( require(4) ), \
39                          reinterpret_cast<char*>( &store ) ); \
40                 data = static_cast<type1>( store ); \
41         } 
42
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 ); \
51         }
52
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) ) ); \
58         }
59
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) ) ); \
68         }
69
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));
76 }
77
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);
82 }
83 #endif
84   
85 template <class Buffer>
86 class XDR_format: public generic_format<Buffer> {
87  private:
88  public:
89         typedef Buffer buffer;
90
91         XDR_format(Buffer& buf):generic_format<Buffer>(buf) {}
92         
93         void input_start_array(int& n) {input_simple(n);}
94         bool input_end_array(int& n) {return n--<=0;}
95
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)
109
110         void input_chars(char* data, int size) {
111                 input_raw(data, size);
112         }
113
114         // This routine is identical to that in GIOP_format
115         void input_raw(char* data, int size) {
116                 int i;
117                 for(i=0;i<(size>>8)-1;i++,data+=256)
118                         memcpy(data, require(256), 256);
119                 int res=size-(i<<8);
120                 memcpy(data, require(res), res);
121                 if (res%4!=0)
122                         require(4-res%4);
123         }
124
125         void output_start_array(int n) {output_simple(n);}
126         void output_end_array() {}
127
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)
141
142         void output_chars(char const* data, int size) {
143                 output_raw(data, size);
144         }
145
146         // This routine is identical to that in GIOP_format
147         void output_raw(char const* data, int size) {
148                 int i;
149                 for(i=0;i<(size>>8)-1;i++,data+=256)
150                         memcpy(desire(256), data, 256);
151                 int res=size-(i<<8);
152                 memcpy(desire(res), data, res);
153                 if (res%4!=0)
154                         memset(desire(4-res%4), 0, 4-res%4);
155         }
156 };
157
158 #undef def_input_simple_i
159 #undef def_input_simple_ll
160 #undef def_output_simple_i
161 #undef def_output_simple_ll
162
163 #endif