SDIFFile.cxx
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "SDIFFile.hxx"
00023 #include "ErrOpenFile.hxx"
00024 #include "ErrFormat.hxx"
00025
00026 #ifdef WIN32
00027 #include <io.h>
00028 #include <fcntl.h>
00029 #else
00030 #include <unistd.h>
00031 #include <sys/types.h>
00032 #include <sys/stat.h>
00033 #include <fcntl.h>
00034 #endif
00035
00036
00037 namespace SDIF
00038 {
00039
00040 File::File(const char* filename,Mode mode):
00041 mSkipData(false),
00042 mFirstAccess(true),
00043 mMode(mode),
00044 mFile(-1),
00045 mSize(0)
00046 {
00047 mpName = new char[ strlen(filename)+1 ];
00048 strncpy( mpName, filename, strlen(filename)+1 );
00049 }
00050
00051 File::~File()
00052 {
00053 delete [] mpName;
00054 }
00055
00056 void File::Open(void)
00057 {
00058 int mode = 0;
00059 if (mMode==eInput) mode = O_RDONLY;
00060 if (mMode==eOutput) mode = O_WRONLY|O_CREAT|O_TRUNC;
00061 if (mMode==eFullDuplex) mode = O_RDWR;
00062
00063 #ifdef WIN32
00064 mode |= O_BINARY;
00065 #endif
00066
00067 if (mFile==-1)
00068 {
00069
00070 mFile = open(mpName,mode,0644);
00071
00072 if (mFile==-1)
00073 {
00074
00075 throw CLAM::ErrOpenFile(mpName);
00076 }
00077 }
00078 mSize = lseek(mFile,0,SEEK_END);
00079 lseek(mFile,0,SEEK_SET);
00080 }
00081
00082
00083 void File::Close(void)
00084 {
00085 if (mFile!=-1)
00086 {
00087
00088 close(mFile);
00089 mFile=-1;
00090 }
00091 }
00092
00093 void File::Read(Storage& storage)
00094 {
00095 while (!Done()) {
00096 Frame* frame = new Frame;
00097 Read(*frame);
00098 storage.Add(frame);
00099 }
00100 }
00101
00102 void File::Write(const Storage& storage)
00103 {
00104 typedef std::list<Frame*>::const_iterator iterator;
00105
00106 iterator it = storage.Begin();
00107 iterator end = storage.End();
00108
00109 while (it!=end)
00110 {
00111 Frame* frame = *it;
00112 Write(*frame);
00113 it++;
00114 }
00115 }
00116
00117 void File::Read(TypeId& type)
00118 {
00119 Read(type.mData,4);
00120 }
00121
00122 void File::Write(const TypeId& type)
00123 {
00124 Write(type.mData,4);
00125 }
00126
00127 void File::Read(FrameHeader& header)
00128 {
00129 Read(header.mType);
00130 TRead(header.mSize);
00131 }
00132
00133 void File::Write(const FrameHeader& header)
00134 {
00135 Write(header.mType);
00136 TWrite(header.mSize);
00137 }
00138
00139 void File::Read(DataFrameHeader& header)
00140 {
00141 Read((FrameHeader&)header);
00142 TRead(header.mTime);
00143 TRead(header.mStreamId);
00144 TRead(header.mnMatrices);
00145 }
00146
00147 void File::Write(const DataFrameHeader& header)
00148 {
00149 Write((FrameHeader&)header);
00150 TWrite(header.mTime);
00151 TWrite(header.mStreamId);
00152 TWrite(header.mnMatrices);
00153 }
00154
00155 void File::Read(Frame& frame)
00156 {
00157 if (mFirstAccess)
00158 {
00159 mFirstAccess = false;
00160 OpeningsFrame opening;
00161 Read(opening);
00162 }
00163
00164 CLAM::TInt32 p = Pos()+FrameHeader::SizeInFile();
00165
00166 Read(frame.mHeader);
00167
00168 CLAM::TInt32 readSize = frame.mHeader.mSize;
00169 frame.mHeader.mSize = DataFrameHeader::SizeInFile();
00170
00171 int tmp = frame.mHeader.mnMatrices;
00172 frame.mHeader.mnMatrices = 0;
00173 for (int i=0;i<tmp;i++)
00174 {
00175 MatrixHeader header;
00176 File::Read(header);
00177 Matrix* pMatrix = 0;
00178 switch (header.mDataType)
00179 {
00180 case eFloat32:
00181 pMatrix = new ConcreteMatrix<CLAM::TFloat32>(header); break;
00182 case eFloat64:
00183 pMatrix = new ConcreteMatrix<CLAM::TFloat64>(header); break;
00184 case eInt32:
00185 pMatrix = new ConcreteMatrix<CLAM::TInt32>(header); break;
00186 case eInt64:
00187 pMatrix = new ConcreteMatrix<CLAM::TInt64>(header); break;
00188 case eUTF8byte:
00189 pMatrix = new ConcreteMatrix<TUTF8byte>(header); break;
00190 case eByte:
00191 pMatrix = new ConcreteMatrix<CLAM::TByte>(header); break;
00192 default:
00193
00194 std::cerr << "SDIFFile.Read(Frame). Received a matrix header with an unknown type: <" << header.mDataType << ">" << std::endl;
00195 pMatrix = new ConcreteMatrix<CLAM::TByte>(header); break;
00196 };
00197 File::ReadMatrixData(*pMatrix);
00198 frame.Add(pMatrix);
00199 }
00200
00201 if (readSize-frame.mHeader.mSize==8)
00202 {
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213 int tmp = Pos();
00214 if (Done())
00215 {
00216 readSize -= 8;
00217 }
00218 else
00219 {
00220 TypeId t;
00221 Read(t);
00222 Pos(tmp);
00223 if (t=="1STF" || t=="1FQ0" || t=="1TRC")
00224 {
00225 readSize -= 8;
00226 }
00227 }
00228 }
00229 CLAM_ASSERT(frame.mHeader.mSize == readSize,
00230 "Reading Frame, calculated size does not match read size");
00231 CLAM_ASSERT(Pos()-p == readSize,
00232 "Reading Frame, size-in-file does not match read size");
00233 }
00234
00235 void File::Write(const Frame& frame)
00236 {
00237 if (mFirstAccess)
00238 {
00239 mFirstAccess = false;
00240 OpeningsFrame opening;
00241 Write(opening);
00242 }
00243
00244 CLAM::TInt32 writeSize = frame.mHeader.mSize;
00245 CLAM::TInt32 p = Pos()+FrameHeader::SizeInFile();
00246
00247 Write(frame.mHeader);
00248
00249 typedef std::list<Matrix*>::const_iterator iterator;
00250
00251 iterator it = frame.mMatrixList.begin();
00252 iterator end = frame.mMatrixList.end();
00253
00254 while (it!=end)
00255 {
00256 Matrix* pMatrix = *it;
00257 File::Write(*pMatrix);
00258 it++;
00259 }
00260
00261 CLAM_ASSERT(Pos()-p == writeSize,
00262 "Incorrect framesize written in SDIF file");
00263 }
00264
00265 void File::Read(OpeningsFrame& frame)
00266 {
00267 Read(frame.mHeader);
00268 TRead(frame.mSpecVersion);
00269 TRead(frame.mStandardTypesVersion);
00270 }
00271
00272 void File::Write(const OpeningsFrame& frame)
00273 {
00274 Write(frame.mHeader);
00275 TWrite(frame.mSpecVersion);
00276 TWrite(frame.mStandardTypesVersion);
00277 }
00278
00279 void File::Read(MatrixHeader& header)
00280 {
00281 Read(header.mType);
00282 CLAM::TInt32 tmp;
00283 TRead(tmp);
00284 header.mDataType = (DataType) tmp;
00285 TRead(header.mnRows);
00286 TRead(header.mnColumns);
00287 }
00288
00289 void File::Write(const MatrixHeader& header)
00290 {
00291 Write(header.mType);
00292 CLAM::TInt32 tmp = header.mDataType;
00293 TWrite(tmp);
00294 TWrite(header.mnRows);
00295 TWrite(header.mnColumns);
00296 }
00297
00298 void File::Read(Matrix& matrix)
00299 {
00300 Read(matrix.mHeader);
00301 if (mSkipData)
00302 {
00303 SkipMatrixData(matrix);
00304 } else {
00305 ReadMatrixData(matrix);
00306 }
00307 }
00308
00309 void File::Write(const Matrix& matrix)
00310 {
00311 Write(matrix.mHeader);
00312 WriteMatrixData(matrix);
00313 }
00314
00315 void File::SkipMatrixData(const Matrix& matrix)
00316 {
00317 CLAM::TUInt32 size = matrix.mHeader.mnColumns*matrix.mHeader.mnRows*
00318 ((matrix.mHeader.mDataType)&0xFF);
00319 CLAM::TUInt32 padding = 8-size&7;
00320 Pos(Pos()+size+padding);
00321 }
00322
00323 #ifdef linux
00324 #include <byteswap.h>
00325 #endif
00326
00327 #ifdef WIN32
00328 #include <stdlib.h>
00329 #endif
00330
00331 CLAM::TUInt16 Swap(const CLAM::TUInt16& val)
00332 {
00333 #if defined linux
00334 return bswap_16(val);
00335
00336
00337
00338
00339 #else
00340 return (val>>8)|(val<<8);
00341 #endif
00342 }
00343
00344 CLAM::TUInt32 Swap(const CLAM::TUInt32& val)
00345 {
00346 #if defined linux
00347 return bswap_32(val);
00348
00349
00350
00351
00352 #else
00353 CLAM::TUInt32 cp = val;
00354 CLAM::TByte* ptr=(CLAM::TByte*) &cp;
00355 static CLAM::TByte tmp;
00356 tmp=ptr[0]; ptr[0]=ptr[3]; ptr[3]=tmp;
00357 tmp=ptr[1]; ptr[1]=ptr[2]; ptr[2]=tmp;
00358 return cp;
00359 #endif
00360 }
00361
00362 CLAM::TUInt64 Swap(const CLAM::TUInt64& val)
00363 {
00364 #if defined linux
00365 return bswap_64(val);
00366
00367
00368
00369
00370 #else
00371 CLAM::TUInt64 cp = val;
00372 CLAM::TByte* ptr=(CLAM::TByte*) &cp;
00373 static CLAM::TByte tmp;
00374 tmp=ptr[0]; ptr[0]=ptr[7]; ptr[7]=tmp;
00375 tmp=ptr[1]; ptr[1]=ptr[6]; ptr[6]=tmp;
00376 tmp=ptr[2]; ptr[2]=ptr[5]; ptr[5]=tmp;
00377 tmp=ptr[3]; ptr[3]=ptr[4]; ptr[4]=tmp;
00378 return cp;
00379 #endif
00380 }
00381
00382 void File::_FixByteOrder(
00383 CLAM::TByte* ptr,CLAM::TUInt32 nElems,CLAM::TUInt32 elemSize)
00384 {
00385 switch (elemSize)
00386 {
00387 case 1: return;
00388 case 2:
00389 {
00390 CLAM::TUInt16* fptr = (CLAM::TUInt16*) ptr;
00391 for (CLAM::TUInt32 i=0;i<nElems;i++)
00392 {
00393 *fptr = Swap(*fptr);
00394 fptr++;
00395 }
00396 return;
00397 }
00398 case 4:
00399 {
00400 CLAM::TUInt32* fptr = (CLAM::TUInt32*) ptr;
00401 for (CLAM::TUInt32 i=0;i<nElems;i++)
00402 {
00403 *fptr = Swap(*fptr);
00404 fptr++;
00405 }
00406 return;
00407 }
00408 case 8:
00409 {
00410 CLAM::TUInt64* fptr = (CLAM::TUInt64*) ptr;
00411 for (CLAM::TUInt32 i=0;i<nElems;i++)
00412 {
00413 *fptr = Swap(*fptr);
00414 fptr++;
00415 }
00416 return;
00417 }
00418 default:
00419 std::cerr << "SDIFFile._FixByteOrder; Received an unsupported element size. size <" << elemSize << ">" << std::endl;
00420 throw;
00421 }
00422 }
00423
00424 void File::ReadMatrixData(Matrix& matrix)
00425 {
00426 CLAM::TByte dum[8];
00427 CLAM::TUInt32 nElems = matrix.mHeader.mnColumns*matrix.mHeader.mnRows;
00428 CLAM::TUInt32 elemSize = matrix.mHeader.mDataType&0xFF;
00429 CLAM::TUInt32 size = nElems*elemSize;
00430
00431 CLAM::TUInt32 padding = 8-size&7;
00432
00433 matrix.Resize(nElems);
00434 matrix.SetSize(nElems);
00435
00436 Read((CLAM::TByte*) matrix.GetPtr(),size);
00437 FixByteOrder((CLAM::TByte*) matrix.GetPtr(),nElems,elemSize);
00438
00439 Read(dum,padding);
00440 }
00441
00442 void File::WriteMatrixData(const Matrix& matrix)
00443 {
00444 CLAM::TByte dum[8];
00445 CLAM::TUInt32 nElems = matrix.mHeader.mnColumns*matrix.mHeader.mnRows;
00446 CLAM::TUInt32 elemSize = matrix.mHeader.mDataType&0xFF;
00447 CLAM::TUInt32 size = nElems*elemSize;
00448
00449 CLAM::TUInt32 padding = 8-size&7;
00450
00451 CLAM::TByte tmp[1024];
00452 const CLAM::TByte *ptr = (const CLAM::TByte*) const_cast<Matrix&>(matrix).GetPtr();
00453 while (size)
00454 {
00455 int blocksize = size;
00456 if (blocksize>1024) blocksize = 1024;
00457 memcpy(tmp,ptr,blocksize);
00458
00459 FixByteOrder(tmp,blocksize/elemSize,elemSize);
00460 Write((CLAM::TByte*) tmp,blocksize);
00461
00462 ptr+=blocksize;
00463 size-=blocksize;
00464 }
00465
00466 Write(dum,padding);
00467 }
00468
00469 }
00470