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