00001
00002
00003
00004
00005
00006
00007
00008 #include "UTIL/lXDR.hh"
00009 #include <stdio.h>
00010 #include <stdlib.h>
00011 #include <string.h>
00012
00013 #if defined(__APPLE_CC__)
00014 #include "/usr/include/sys/types.h"
00015 #endif
00016
00017 #if defined(__linux) || defined(__CYGWIN__) || defined(__APPLE_CC__)
00018 #include <netinet/in.h>
00019 #endif
00020 #ifdef _MSC_VER
00021 #include <winsock.h>
00022 #else
00023 #include <sys/socket.h>
00024 #endif
00025
00026 namespace UTIL{
00027
00028
00029
00030
00031
00032 lXDR::~lXDR()
00033 {
00034 if (_fp) {
00035 fclose(_fp);
00036 _fp = 0;
00037 }
00038 if (_fileName) {
00039 delete [] _fileName;
00040 _fileName = 0;
00041 }
00042 return;
00043 }
00044
00045 lXDR::lXDR(const char *filename, bool open_for_write) : _fileName(0), _fp(0)
00046 {
00047 setFileName(filename, open_for_write);
00048 if (htonl(1L) == 1L) _hasNetworkOrder = true;
00049 else _hasNetworkOrder = false;
00050 return;
00051 }
00052
00053 void lXDR::setFileName(const char *filename, bool open_for_write)
00054 {
00055
00056
00057
00058 if (filename == 0) {
00059 _error = LXDR_OPENFAILURE;
00060 return;
00061 }
00062 #ifdef _MSC_VER
00063 FILE *fp = fopen(filename, open_for_write ? "wb" : "rb");
00064 #else
00065 FILE *fp = fopen(filename, open_for_write ? "w" : "r");
00066 #endif
00067 if (fp == 0) {
00068 _error = LXDR_OPENFAILURE;
00069 return;
00070 }
00071
00072 if (_fp) fclose(_fp);
00073 _fp = fp;
00074
00075 if (_fileName) {
00076 delete [] _fileName;
00077 _fileName = 0;
00078 }
00079
00080 int n = strlen(filename);
00081 _fileName = new char [n + 1];
00082 strncpy(_fileName, filename, n);
00083 _fileName[n] = '\0';
00084
00085 _openForWrite = open_for_write;
00086
00087 _error = LXDR_SUCCESS;
00088 return;
00089 }
00090
00091 double lXDR::ntohd(double d) const
00092 {
00093
00094
00095
00096 if (_hasNetworkOrder == false) {
00097 union {
00098 double d;
00099 unsigned char b[8];
00100 } dd;
00101 int i;
00102
00103 dd.d = d;
00104 for (i = 0; i < 4; i++) {
00105 unsigned char c = dd.b[i];
00106 dd.b[i] = dd.b[7 - i];
00107 dd.b[7 - i] = c;
00108 }
00109 d = dd.d;
00110 }
00111 return(d);
00112 }
00113
00114 long lXDR::checkRead(long *l)
00115 {
00116 if (_openForWrite) return(_error = LXDR_READONLY);
00117 if (_fp == 0) return(_error = LXDR_NOFILE);
00118 if (l) {
00119
00120
00121
00122
00123
00124 int32_t buf;
00125 if (fread(&buf, 4, 1, _fp) != 1) return(_error = LXDR_READERROR);
00126 *l = ((int32_t)ntohl(buf));
00127 }
00128 return(LXDR_SUCCESS);
00129 }
00130
00131 long lXDR::checkRead(double *d)
00132 {
00133 if (_openForWrite) return(_error = LXDR_READONLY);
00134 if (_fp == 0) return(_error = LXDR_NOFILE);
00135 if (d) {
00136 if (fread(d, 8, 1, _fp) != 1) return(_error = LXDR_READERROR);
00137 *d = ntohd(*d);
00138 }
00139 return(LXDR_SUCCESS);
00140 }
00141
00142 long lXDR::checkRead(float *f)
00143 {
00144 if (_openForWrite) return(_error = LXDR_READONLY);
00145 if (_fp == 0) return(_error = LXDR_NOFILE);
00146 if (f) {
00147 if (fread(f, 4, 1, _fp) != 1) return(_error = LXDR_READERROR);
00148
00149
00150
00151 *((int32_t *) f) = ntohl(*((int32_t *) f));
00152 }
00153 return(LXDR_SUCCESS);
00154 }
00155
00156 long lXDR::readLong(void)
00157 {
00158 long l = 0;
00159 checkRead(&l);
00160 return(l);
00161 }
00162
00163 double lXDR::readDouble(void)
00164 {
00165 double d = 0.0;
00166 checkRead(&d);
00167 return(d);
00168 }
00169
00170 double lXDR::readFloat(void)
00171 {
00172 float f = 0.0;
00173 checkRead(&f);
00174 return((double) f);
00175 }
00176
00177 const char *lXDR::readString(long &length)
00178 {
00179 if (checkRead(&length)) return(0);
00180 long rl = (length + 3) & 0xFFFFFFFC;
00181 char *s = new char[rl + 1];
00182 if (fread(s, 1, rl, _fp) != (unsigned long) rl) {
00183 _error = LXDR_READERROR;
00184 delete [] s;
00185 return(0);
00186 }
00187 s[rl] = '\0';
00188 _error = LXDR_SUCCESS;
00189 return(s);
00190 }
00191
00192 long *lXDR::readLongArray(long &length)
00193 {
00194 if (checkRead(&length)) return(0);
00195 long *s = new long[length];
00196
00197
00198
00199
00200
00201
00202
00203
00204 int32_t *buf = new int32_t[length];
00205 if (fread(buf, 4, length, _fp) != (unsigned long) length) {
00206 _error = LXDR_READERROR;
00207 delete [] buf;
00208 delete [] s;
00209 return(0);
00210 }
00211 for (long i = 0; i < length; i++){
00212 if (_hasNetworkOrder == false){
00213 s[i] = ((int32_t)ntohl(buf[i]));
00214 }
00215 else{
00216 s[i] = (long)buf[i];
00217 }
00218 }
00219 delete [] buf;
00220 _error = LXDR_SUCCESS;
00221 return(s);
00222 }
00223
00224 double *lXDR::readDoubleArray(long &length)
00225 {
00226 if (checkRead(&length)) return(0);
00227 double *s = new double[length];
00228 if (fread(s, 8, length, _fp) != (unsigned long) length) {
00229 _error = LXDR_READERROR;
00230 delete [] s;
00231 return(0);
00232 }
00233 if (_hasNetworkOrder == false) for (long i = 0; i < length; i++) s[i] = ntohd(s[i]);
00234 _error = LXDR_SUCCESS;
00235 return(s);
00236 }
00237
00238 double *lXDR::readFloatArray(long &length)
00239 {
00240 if (checkRead(&length)) return(0);
00241 long *st = new long[length];
00242
00243 if (fread(st, 4, length, _fp) != (unsigned long) length) {
00244 _error = LXDR_READERROR;
00245 delete [] st;
00246 return(0);
00247 }
00248 double *s = new double[length];
00249
00250 if (_hasNetworkOrder == false) {
00251 for (long i = 0; i < length; i++) {
00252 long l = ntohl(st[i]);
00253 s[i] = (double) (*((float *) &l));
00254 }
00255 }
00256 _error = LXDR_SUCCESS;
00257 return(s);
00258 }
00259
00260 long lXDR::checkWrite(long *l)
00261 {
00262 if (_openForWrite == false) return(_error = LXDR_WRITEONLY);
00263 if (_fp == 0) return(_error = LXDR_NOFILE);
00264 if (l) {
00265 long ll = htonl(*l);
00266
00267 if (fwrite(&ll, 4, 1, _fp) != 4) return(_error = LXDR_WRITEERROR);
00268 }
00269 return(LXDR_SUCCESS);
00270 }
00271
00272 long lXDR::checkWrite(double *d)
00273 {
00274 if (_openForWrite == false) return(_error = LXDR_WRITEONLY);
00275 if (_fp == 0) return(_error = LXDR_NOFILE);
00276 if (d) {
00277 double dd = htond(*d);
00278 if (fwrite(&dd, 8, 1, _fp) != 8) return(_error = LXDR_WRITEERROR);
00279 }
00280 return(LXDR_SUCCESS);
00281 }
00282
00283 long lXDR::writeLong(long data)
00284 {
00285 return(checkWrite(&data));
00286 }
00287
00288 long lXDR::writeDouble(double data)
00289 {
00290 return(checkWrite(&data));
00291 }
00292
00293 long lXDR::writeString(const char *data)
00294 {
00295 return(writeString(data, strlen(data)));
00296 }
00297
00298 long lXDR::writeString(const char *data, long length)
00299 {
00300 if (checkWrite(&length)) return(_error);
00301 if (fwrite(data, 1, length, _fp) != (unsigned long) length) return(_error = LXDR_WRITEERROR);
00302 long l = ((length + 3) & 0xFFFFFFFC) - length;
00303 if (fwrite(&l, 1, l, _fp) != (unsigned long) l) return(_error = LXDR_WRITEERROR);
00304 return(_error = LXDR_SUCCESS);
00305 }
00306
00307 long lXDR::writeLongArray(const long *data, long length)
00308 {
00309 if (checkWrite(&length)) return(_error);
00310 long *s = (long *) data;
00311 if (_hasNetworkOrder == false) {
00312 s = new long[length];
00313 for (long i = 0; i < length; i++) s[i] = htonl(data[i]);
00314 }
00315
00316 long l = fwrite(s, 4, length, _fp);
00317 if (_hasNetworkOrder == false) delete [] s;
00318 if (l != length) return(_error = LXDR_WRITEERROR);
00319 return(_error = LXDR_SUCCESS);
00320 }
00321
00322 long lXDR::writeDoubleArray(const double *data, long length)
00323 {
00324 if (checkWrite(&length)) return(_error);
00325 double *s = (double *) data;
00326 if (_hasNetworkOrder == false) {
00327 s = new double[length];
00328 for (long i = 0; i < length; i++) s[i] = htond(data[i]);
00329 }
00330 long l = fwrite(s, 8, length, _fp);
00331 if (_hasNetworkOrder == false) delete [] s;
00332 if (l != length) return(_error = LXDR_WRITEERROR);
00333 return(_error = LXDR_SUCCESS);
00334 }
00335
00336
00337 long lXDR::filePosition(long pos)
00338 {
00339 if (_fp == 0) {
00340 _error = LXDR_NOFILE;
00341 return(-1);
00342 }
00343 if (pos == -1) return(ftell(_fp));
00344 if (fseek(_fp, pos, SEEK_SET)) {
00345 _error = LXDR_SEEKERROR;
00346 return(-1);
00347 }
00348 return(pos);
00349 }
00350
00351 }