LOOS  v2.3.2
xdr.hpp
1 /*
2  This file is part of LOOS.
3 
4  LOOS (Lightweight Object-Oriented Structure library)
5  Copyright (c) 2009, Tod D. Romo, Alan Grossfield
6  Department of Biochemistry and Biophysics
7  School of Medicine & Dentistry, University of Rochester
8 
9  This package (LOOS) is free software: you can redistribute it and/or modify
10  it under the terms of the GNU General Public License as published by
11  the Free Software Foundation under version 3 of the License.
12 
13  This package is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21 
22 
23 #if !defined(LOOS_XDR_HPP)
24 #define LOOS_XDR_HPP
25 
26 #include <iostream>
27 #include <string>
28 #include <stdexcept>
29 #include <vector>
30 
31 #include <loos_defs.hpp>
32 #include <utils.hpp>
33 
34 
35 namespace loos {
36 
37  namespace internal {
38 
39 
40 
42 
48  class XDRReader {
49  public:
51  typedef unsigned int block_type;
52 
53  public:
54 
56  XDRReader(std::istream* s) : stream(s), need_to_swab(false) {
57  int test = 0x1234;
58  if (*(reinterpret_cast<char*>(&test)) == 0x34) {
59  need_to_swab = true;
60  }
61  }
62 
64  std::istream* get(void) { return(stream); }
65 
67  template<typename T> uint read(T* p) {
68  if (sizeof(T) > sizeof(block_type))
69  throw(XDRDataSizeError());
70 
71  T result;
72  stream->read(reinterpret_cast<char*>(&result), sizeof(block_type));
73  if (sizeof(T) > 1 && need_to_swab)
74  result = swab(result);
75 
76  *p = result;
77  return(!stream->fail());
78  }
79 
80  // overload for double data-types
81  uint read(double* p)
82  {
83  double result;
84  stream->read(reinterpret_cast<char*>(&result), sizeof(double));
85  if (need_to_swab)
86  result = swab(result);
87 
88  *p = result;
89  return(!stream->fail());
90  }
91 
92 
93  template<typename T> uint read(T& t) { return(read(&t)); }
94 
95 
96 
98  template<typename T> uint read(T* ary, const uint n) {
99  uint i;
100  for (i=0; i<n && read(ary+i); ++i) ;
101  return(i);
102  }
103 
104 
106  uint read(char* p, uint n) {
107  uint rndup;
108  static char buf[sizeof(block_type)];
109 
110  if (n == 0)
111  return(1);
112 
113  rndup = n % sizeof(block_type);
114  if (rndup > 0)
115  rndup = sizeof(block_type) - rndup;
116 
117  stream->read(p, n);
118  if (stream->fail())
119  return(0);
120  if (rndup)
121  stream->read(buf, rndup);
122 
123  return(n);
124  }
125 
127 
128  uint read(boost::shared_ptr<char>& p) {
129  uint n;
130 
131  if (!read(n))
132  return(0);
133  char* s = new char[n+1];
134  uint i = read(s, n);
135  s[n] = '\0';
136  p = boost::shared_ptr<char>(s);
137  return(i);
138  }
139 
140  uint read(std::string& s) {
141  boost::shared_ptr<char> p;
142  int i = read(p);
143  if (!i)
144  return(0);
145 
146  s = std::string(p.get());
147 
148  return(i);
149  }
150 
151  private:
152  std::istream* stream;
153  bool need_to_swab;
154  };
155 
156 
157 
158 
159  class XDRWriter
160  {
161  public:
163  typedef unsigned int block_type;
164 
165  public:
166 
167  XDRWriter() : stream(0) {
168  int test = 0x1234;
169  if (*(reinterpret_cast<char*>(&test)) == 0x34) {
170  need_to_swab = true;
171  }
172  }
173 
175  XDRWriter(std::ostream* s) : stream(s) {
176  int test = 0x1234;
177  if (*(reinterpret_cast<char*>(&test)) == 0x34) {
178  need_to_swab = true;
179  }
180  }
181 
183  std::ostream* get(void) { return(stream); }
184 
185  void setStream(std::ostream* o) { stream = o; }
186 
187 
188 
189 
190 
192  template<typename T> uint write(const T& p) {
193 
194  if (sizeof(T) > sizeof(block_type))
195  throw(XDRDataSizeError());
196 
197  block_type u;
198  T* up = reinterpret_cast<T*>(&u);
199  *up = p;
200 
201  if (sizeof(T) > 1 && need_to_swab)
202  u = swab(u);
203 
204 
205  stream->write(reinterpret_cast<char*>(&u), sizeof(block_type));
206 
207  return(!(stream->bad()));
208  }
209 
210 
211 
212 
214  uint write(const double& p)
215  {
216  unsigned long u;
217  double* up = reinterpret_cast<double*>(&u);
218  *up = p;
219 
220  if (need_to_swab)
221  u = swab(u);
222 
223  stream->write(reinterpret_cast<char*>(&u), sizeof(double));
224 
225  return(!stream->fail());
226  }
227 
228 
230  template<typename T> uint write(const T* ary, const uint n) {
231  uint i;
232  for (i=0; i<n && write(ary[i]); ++i) ;
233  return(i);
234  }
235 
237  uint write(const char* p, const uint n) {
238  uint rndup;
239  static char buf[sizeof(block_type)];
240  static bool init(false);
241 
242  if (!init)
243  for (uint i=0; i<sizeof(block_type); ++i)
244  buf[i] = '\0';
245 
246  rndup = n % sizeof(block_type);
247  if (rndup > 0)
248  rndup = sizeof(block_type) - rndup;
249 
250  stream->write(p, n);
251  if (!stream->fail())
252  stream->write(buf, rndup);
253 
254  return(stream->fail() ? 0 : n);
255  }
256 
258  uint write(const char* p) {
259  uint n = strlen(p);
260  write(n);
261  return(write(p, n));
262  }
263 
264  uint write(const std::string& s) { return(write(s.c_str())); }
265 
266  private:
267  std::ostream* stream;
268  bool need_to_swab;
269 
270  };
271 
272  } /* internal */
273 
274 
275 } /* loos */
276 
277 
278 
279 #endif
uint read(char *p, uint n)
Read in an opaque array of n-bytes (same as xdr_opaque)
Definition: xdr.hpp:106
uint write(const T *ary, const uint n)
Writes an n-array of data.
Definition: xdr.hpp:230
uint write(const double &p)
Overload for double-precision.
Definition: xdr.hpp:214
uint read(boost::shared_ptr< char > &p)
Same as xdr_string.
Definition: xdr.hpp:128
uint write(const char *p, const uint n)
Writes an opaque array of n-bytes.
Definition: xdr.hpp:237
uint read(T *p)
Read a single datum.
Definition: xdr.hpp:67
XDRReader(std::istream *s)
Constructor determines need to convert data at instantiation.
Definition: xdr.hpp:56
uint write(const char *p)
Writes a C-string (ie xdr_string)
Definition: xdr.hpp:258
T swab(const T &datum)
Returns a byte-swapped copy of an arbitrary type.
Definition: utils.hpp:287
XDRWriter(std::ostream *s)
Constructor determines need to convert data at instantiation.
Definition: xdr.hpp:175
This class provides some facility for handling XDR data.
Definition: xdr.hpp:48
unsigned int block_type
Type (and hence size) of the external block.
Definition: xdr.hpp:51
Exception indicating internal XDR error.
Definition: exceptions.hpp:84
unsigned int block_type
Type (and hence size) of the external block.
Definition: xdr.hpp:163
uint write(const T &p)
Writes a single datum.
Definition: xdr.hpp:192
Namespace for most things not already encapsulated within a class.
uint read(T *ary, const uint n)
Read an n-array of data.
Definition: xdr.hpp:98