LCIO  02.17
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
lXDR.cc
Go to the documentation of this file.
1 //
3 // Simple XDR class, see header
4 //
5 // WGL, 24 May 2002
6 //
8 #include "UTIL/lXDR.hh"
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 
13 #if defined(__linux) || defined(__CYGWIN__) || defined(__APPLE_CC__)
14 #include <netinet/in.h>
15 #endif
16 #ifdef _MSC_VER
17 #include <winsock.h>
18 #else
19 #include <sys/socket.h>
20 #endif
21 
22 namespace UTIL{
24 //
25 // Constructor, destructor
26 //
29 {
30  if (_fp) {
31  fclose(_fp);
32  _fp = 0;
33  }
34  if (_fileName) {
35  delete [] _fileName;
36  _fileName = 0;
37  }
38  return;
39 }
40 
41 lXDR::lXDR(const char *filename, bool open_for_write) : _fileName(0), _fp(0)
42 {
43  setFileName(filename, open_for_write);
44  if (htonl(1L) == 1L) _hasNetworkOrder = true;
45  else _hasNetworkOrder = false;
46  return;
47 }
48 
49 void lXDR::setFileName(const char *filename, bool open_for_write)
50 {
51 //
52 // First check if we can open this file
53 //
54  if (filename == 0) {
56  return;
57  }
58 #ifdef _MSC_VER
59  FILE *fp = fopen(filename, open_for_write ? "wb" : "rb");
60 #else
61  FILE *fp = fopen(filename, open_for_write ? "w" : "r");
62 #endif
63  if (fp == 0) {
65  return;
66  }
67 
68  if (_fp) fclose(_fp);
69  _fp = fp;
70 
71  if (_fileName) {
72  delete [] _fileName;
73  _fileName = 0;
74  }
75 
76  int n = strlen(filename);
77  _fileName = new char [n + 1];
78  strncpy(_fileName, filename, n);
79  _fileName[n] = '\0';
80 
81  _openForWrite = open_for_write;
82 
84  return;
85 }
86 
87 double lXDR::ntohd(double d) const
88 {
89 //
90 // If we already have network order, we don't swap
91 //
92  if (_hasNetworkOrder == false) {
93  union {
94  double d;
95  unsigned char b[8];
96  } dd;
97  int i;
98 
99  dd.d = d;
100  for (i = 0; i < 4; i++) {
101  unsigned char c = dd.b[i];
102  dd.b[i] = dd.b[7 - i];
103  dd.b[7 - i] = c;
104  }
105  d = dd.d;
106  }
107  return(d);
108 }
109 
110 long lXDR::checkRead(long *l)
111 {
112  if (_openForWrite) return(_error = LXDR_READONLY);
113  if (_fp == 0) return(_error = LXDR_NOFILE);
114  if (l) {
115  // je: in architectures where long isn't 4 byte long this code crashes
116  //long nr;
117  //if ((nr = fread(l, 4, 1, _fp)) != 1) return(_error = LXDR_READERROR);
118  //*l = ntohl(*l);
119 
120  int32_t buf;
121  if (fread(&buf, 4, 1, _fp) != 1) return(_error = LXDR_READERROR);
122  *l = ((int32_t)ntohl(buf));
123  }
124  return(LXDR_SUCCESS);
125 }
126 
127 long lXDR::checkRead(double *d)
128 {
129  if (_openForWrite) return(_error = LXDR_READONLY);
130  if (_fp == 0) return(_error = LXDR_NOFILE);
131  if (d) {
132  if (fread(d, 8, 1, _fp) != 1) return(_error = LXDR_READERROR);
133  *d = ntohd(*d);
134  }
135  return(LXDR_SUCCESS);
136 }
137 
138 long lXDR::checkRead(float *f)
139 {
140  if (_openForWrite) return(_error = LXDR_READONLY);
141  if (_fp == 0) return(_error = LXDR_NOFILE);
142  if (f) {
143  if (fread(f, 4, 1, _fp) != 1) return(_error = LXDR_READERROR);
144  // je: in architectures where long isn't 4 byte long this code crashes
145  //*((long *) f) = ntohl(*((long *) f));
146 
147  *((int32_t *) f) = ntohl(*((int32_t *) f));
148  }
149  return(LXDR_SUCCESS);
150 }
151 
152 long lXDR::readLong(void)
153 {
154  long l = 0;
155  checkRead(&l);
156  return(l);
157 }
158 
159 double lXDR::readDouble(void)
160 {
161  double d = 0.0;
162  checkRead(&d);
163  return(d);
164 }
165 
166 double lXDR::readFloat(void)
167 {
168  float f = 0.0;
169  checkRead(&f);
170  return((double) f);
171 }
172 
173 const char *lXDR::readString(long &length)
174 {
175  if (checkRead(&length)) return(0);
176  long rl = (length + 3) & 0xFFFFFFFC;
177  char *s = new char[rl + 1];
178  if (fread(s, 1, rl, _fp) != (unsigned long) rl) {
180  delete [] s;
181  return(0);
182  }
183  s[rl] = '\0';
185  return(s);
186 }
187 
188 long *lXDR::readLongArray(long &length)
189 {
190  if (checkRead(&length)) return(0);
191  long *s = new long[length];
192  // je: in architectures where long isn't 4 byte long this code crashes
193  //if (fread(s, 4, length, _fp) != (unsigned long) length) {
194  // _error = LXDR_READERROR;
195  // delete [] s;
196  // return(0);
197  //}
198  //if (_hasNetworkOrder == false) for (long i = 0; i < length; i++) s[i] = ntohl(s[i]);
199 
200  int32_t *buf = new int32_t[length];
201  if (fread(buf, 4, length, _fp) != (unsigned long) length) {
203  delete [] buf;
204  delete [] s;
205  return(0);
206  }
207  for (long i = 0; i < length; i++){
208  if (_hasNetworkOrder == false){
209  s[i] = ((int32_t)ntohl(buf[i]));
210  }
211  else{
212  s[i] = (long)buf[i];
213  }
214  }
215  delete [] buf;
217  return(s);
218 }
219 
220 double *lXDR::readDoubleArray(long &length)
221 {
222  if (checkRead(&length)) return(0);
223  double *s = new double[length];
224  if (fread(s, 8, length, _fp) != (unsigned long) length) {
226  delete [] s;
227  return(0);
228  }
229  if (_hasNetworkOrder == false) for (long i = 0; i < length; i++) s[i] = ntohd(s[i]);
231  return(s);
232 }
233 
234 double *lXDR::readFloatArray(long &length)
235 {
236  if (checkRead(&length)) return(0);
237  long *st = new long[length];
238  // je: FIXME this will cause problems in architectures where long isn't 4 byte long
239  if (fread(st, 4, length, _fp) != (unsigned long) length) {
241  delete [] st;
242  return(0);
243  }
244  double *s = new double[length];
245  // je: FIXME what happens if _hasNetworkOrder == true?!
246  if (_hasNetworkOrder == false) {
247  for (long i = 0; i < length; i++) {
248  long l = ntohl(st[i]);
249  // s[i] = (double) (*((float *) &l));
250  //fg: the above causes a strict aliasing error, so we sue memcpy
251  float f ;
252  memcpy( &f, &l, sizeof(float) ) ;
253  s[i] = f ;
254  }
255  }
257  delete [] st;
258  return(s);
259 }
260 
261 long lXDR::checkWrite(long *l)
262 {
263  if (_openForWrite == false) return(_error = LXDR_WRITEONLY);
264  if (_fp == 0) return(_error = LXDR_NOFILE);
265  if (l) {
266  long ll = htonl(*l);
267  // je: FIXME this will cause problems in architectures where long isn't 4 byte long
268  if (fwrite(&ll, 4, 1, _fp) != 4) return(_error = LXDR_WRITEERROR);
269  }
270  return(LXDR_SUCCESS);
271 }
272 
273 long lXDR::checkWrite(double *d)
274 {
275  if (_openForWrite == false) return(_error = LXDR_WRITEONLY);
276  if (_fp == 0) return(_error = LXDR_NOFILE);
277  if (d) {
278  double dd = htond(*d);
279  if (fwrite(&dd, 8, 1, _fp) != 8) return(_error = LXDR_WRITEERROR);
280  }
281  return(LXDR_SUCCESS);
282 }
283 
284 long lXDR::writeLong(long data)
285 {
286  return(checkWrite(&data));
287 }
288 
289 long lXDR::writeDouble(double data)
290 {
291  return(checkWrite(&data));
292 }
293 
294 long lXDR::writeString(const char *data)
295 {
296  return(writeString(data, strlen(data)));
297 }
298 
299 long lXDR::writeString(const char *data, long length)
300 {
301  if (checkWrite(&length)) return(_error);
302  if (fwrite(data, 1, length, _fp) != (unsigned long) length) return(_error = LXDR_WRITEERROR);
303  long l = ((length + 3) & 0xFFFFFFFC) - length;
304  if (fwrite(&l, 1, l, _fp) != (unsigned long) l) return(_error = LXDR_WRITEERROR);
305  return(_error = LXDR_SUCCESS);
306 }
307 
308 long lXDR::writeLongArray(const long *data, long length)
309 {
310  if (checkWrite(&length)) return(_error);
311  long *s = (long *) data;
312  if (_hasNetworkOrder == false) {
313  s = new long[length];
314  for (long i = 0; i < length; i++) s[i] = htonl(data[i]);
315  }
316  // je: FIXME this will cause problems in architectures where long isn't 4 byte long
317  long l = fwrite(s, 4, length, _fp);
318  if (_hasNetworkOrder == false) delete [] s;
319  if (l != length) return(_error = LXDR_WRITEERROR);
320  return(_error = LXDR_SUCCESS);
321 }
322 
323 long lXDR::writeDoubleArray(const double *data, long length)
324 {
325  if (checkWrite(&length)) return(_error);
326  double *s = (double *) data;
327  if (_hasNetworkOrder == false) {
328  s = new double[length];
329  for (long i = 0; i < length; i++) s[i] = htond(data[i]);
330  }
331  long l = fwrite(s, 8, length, _fp);
332  if (_hasNetworkOrder == false) delete [] s;
333  if (l != length) return(_error = LXDR_WRITEERROR);
334  return(_error = LXDR_SUCCESS);
335 }
336 
337 
338 long lXDR::filePosition(long pos)
339 {
340  if (_fp == 0) {
342  return(-1);
343  }
344  if (pos == -1) return(ftell(_fp));
345  if (fseek(_fp, pos, SEEK_SET)) {
347  return(-1);
348  }
349  return(pos);
350 }
351 
352 }// end namespace
long filePosition(long pos=-1)
Definition: lXDR.cc:338
#define LXDR_WRITEERROR
Definition: lXDR.hh:139
long readLong(void)
Definition: lXDR.cc:152
bool _openForWrite
Definition: lXDR.hh:120
long _error
Definition: lXDR.hh:119
long checkRead(long *)
Definition: lXDR.cc:110
double readFloat(void)
Definition: lXDR.cc:166
#define LXDR_NOFILE
Definition: lXDR.hh:137
void setFileName(const char *filename, bool open_for_write=false)
Definition: lXDR.cc:49
double ntohd(double d) const
Definition: lXDR.cc:87
long writeDoubleArray(const double *data, long length)
Definition: lXDR.cc:323
virtual ~lXDR()
Definition: lXDR.cc:28
#define LXDR_SEEKERROR
Definition: lXDR.hh:140
lXDR(const char *filename=0, bool open_for_write=false)
Definition: lXDR.cc:41
long writeLong(long data)
Definition: lXDR.cc:284
FILE * _fp
Definition: lXDR.hh:118
long * readLongArray(long &length)
Definition: lXDR.cc:188
double * readDoubleArray(long &length)
Definition: lXDR.cc:220
long writeDouble(double data)
Definition: lXDR.cc:289
#define LXDR_READERROR
Definition: lXDR.hh:138
double htond(double d) const
Definition: lXDR.hh:124
#define LXDR_READONLY
Definition: lXDR.hh:135
long checkWrite(long *)
Definition: lXDR.cc:261
bool _hasNetworkOrder
Definition: lXDR.hh:122
long writeString(const char *data)
Definition: lXDR.cc:294
double readDouble(void)
Definition: lXDR.cc:159
#define LXDR_WRITEONLY
Definition: lXDR.hh:136
#define LXDR_SUCCESS
Definition: lXDR.hh:133
double * readFloatArray(long &length)
Definition: lXDR.cc:234
long writeLongArray(const long *data, long length)
Definition: lXDR.cc:308
const char * readString(long &length)
Definition: lXDR.cc:173
char * _fileName
Definition: lXDR.hh:117
#define LXDR_OPENFAILURE
Definition: lXDR.hh:134