Go to the documentation of this file.00001 #ifndef FEDRawData_DaqData_h
00002 #define FEDRawData_DaqData_h
00003
00049 #include <typeinfo>
00050 #include <vector>
00051 #include <map>
00052 #include <string>
00053 #include <cmath>
00054
00055 template <class Format>
00056 class DaqData {
00057
00058 public:
00059
00060 DaqData(std::vector<unsigned int> & v) : size_(0), buffer_(0), nobjects_(0) {
00061
00062 try {
00063
00064 if (v.size() == 0) throw string("DaqData: empty input data vector provided: ");
00065
00066 int Nfields = Format::getNumberOfFields();
00067 if (v.size()%Nfields != 0) throw string("DaqData: ERROR. You must provide a number of input values compatibles with the requested format: ");
00068
00069
00070 int ObjSize = Format::getFieldLastBit(Nfields-1)+1;
00071 nobjects_ = v.size()/Nfields;
00072
00073
00074
00075 size_ = (int) ceil(((double)(ObjSize*nobjects_))/8);
00076 buffer_= new char[size_];
00077
00078
00079 std::vector<unsigned int>::iterator vit = v.begin();
00080 char * p = buffer_;
00081 int bitsalreadyfilled = 0;
00082
00083 int Totbytes=1;
00084
00085 for(int i=0; i<nobjects_; i++) {
00086
00087
00088 int Nbytes = (int) ceil((double)(Format::getFieldLastBit(Nfields-1)+1-8+bitsalreadyfilled)/8);
00089
00090 if ((Totbytes+=Nbytes) > size_) throw string("Exceeded allocated buffer size");
00091
00092 compressObject(p, vit, bitsalreadyfilled);
00093
00094
00095
00096 data_.insert(std::pair< int, std::vector<unsigned int> >(i,std::vector<unsigned int>(vit-Nfields,vit) ));
00097
00098
00099 p+=(Nbytes+(8-bitsalreadyfilled)/8) ;
00100 Totbytes+=(8-bitsalreadyfilled)/8 ;
00101 }
00102 if(bitsalreadyfilled==0) Totbytes--;
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113 }
00114
00115 catch (std::string s){
00116
00117 cout<<"DaqData - Exception caught: " << s <<endl;
00118 cout<<"Object compression failed! No data has been constructed for format: "<< string(typeid(Format).name())<<endl;
00119
00120 }
00121
00122 }
00123
00124
00125 DaqData(const unsigned char * ptr,
00126 int sizeinbytes) : size_(0), buffer_(0), nobjects_(0) {
00127
00128
00129 try {
00130
00131 if (sizeinbytes==0) throw std::string("Buffer size is zero");
00132
00133 int Nfields = Format::getNumberOfFields();
00134 int ObjSize = Format::getFieldLastBit(Nfields-1)+1;
00135 nobjects_ = (sizeinbytes*8)/ObjSize;
00136
00137
00138
00139
00140 if ((sizeinbytes*8)%ObjSize != 0) {
00141 cout<<"DaqData: there will be " << (sizeinbytes*8)%ObjSize <<" meaningless bits at the end of the buffer"<<endl;
00142 }
00143
00144
00145
00146
00147
00148
00149 const unsigned char * p = ptr;
00150 int bitsalreadyfilled = 0;
00151
00152 int Totbytes=1;
00153
00154 for(int i=0; i<nobjects_; i++) {
00155
00156 std::vector<unsigned int> objdata;
00157 objdata.reserve(Nfields);
00158
00159
00160 int Nbytes = (int) ceil((double)(Format::getFieldLastBit(Nfields-1)+1-8+bitsalreadyfilled)/8);
00161
00162
00163 if ((Totbytes+=Nbytes) > sizeinbytes) throw std::string("Exceeded allocated buffer size");
00164
00165
00166 uncompressObject(p, objdata, bitsalreadyfilled);
00167
00168
00169 data_.insert(std::pair< int, std::vector<unsigned int> >(i,objdata) );
00170
00171
00172 p+= (Nbytes + (8-bitsalreadyfilled)/8);
00173 Totbytes+= (8-bitsalreadyfilled)/8;
00174
00175 }
00176
00177 if(bitsalreadyfilled==0) Totbytes--;
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189 }
00190 catch (std::string s){
00191
00192 std::cout<<"DaqData - Exception caught: " << s <<std::endl;
00193 std::cout<<"Object uncompression failed! No data has been constructed for format: "<<std::string(typeid(Format).name())<<endl;
00194
00195 }
00196
00197 }
00198
00199
00200 DaqData(const DaqData & a) {
00201
00202 size_ = a.Size();
00203 buffer_ = new char[size_];
00204 memmove(buffer_,a.Buffer(),size_);
00205 nobjects_ = a.Nobjects();
00206
00207 for(int i=0; i<nobjects_; i++) {
00208 std::vector<unsigned int> vec;
00209 for(int j=0; j<Format::getNumberOfFields(); j++) vec.push_back(a.getValue(j,i));
00210 data_.insert(std::pair< int, std::vector<unsigned int> >(i, vec));
00211 }
00212
00213 }
00214
00215
00216 ~DaqData(){
00217
00218
00219 if (buffer_!=0) delete [] buffer_;
00220
00221 };
00222
00223
00224 char * Buffer() const {return buffer_;}
00225
00226 int Size() const {return size_;}
00227
00228 int Nobjects() const {
00229 return nobjects_;
00230
00231
00232
00233
00234 }
00235
00236 unsigned int getValue(int indfield, int indobj=0) const {
00237
00238 if (indobj<nobjects_ && indfield < Format::getNumberOfFields()) {
00239 std::map < int, std::vector<unsigned int> >::const_iterator it = data_.find(indobj);
00240 if (it != data_.end()) return ((*it).second)[indfield];
00241 else {
00242 cout<<"DaqData - Strange: object should exist but was not found "<<endl;
00243 return 0;
00244 }
00245 }
00246 else cout<<"DaqData - Non existent field or object"<<endl;
00247 return 0;
00248
00249 }
00250
00251 private:
00252
00253 void uncompressObject(const unsigned char * ptr,
00254 std::vector<unsigned int> & objdata,
00255 int & bitsalreadyfilled) {
00256
00257 int Nfields = Format::getNumberOfFields();
00258
00259 int bitstoaccomodate=Format::getFieldLastBit(0)+1;
00260
00261 int ifield = 0;
00262 unsigned int value = 0;
00263
00264 while (ifield < Nfields) {
00265
00266 if(bitstoaccomodate > 8 - bitsalreadyfilled ) {
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281 if(bitstoaccomodate > 8) value += ( ( (*ptr << bitsalreadyfilled) & 0xff ) << (bitstoaccomodate - 8) );
00282 else value += ( ( (*ptr << bitsalreadyfilled) & 0xff) >> (8 - bitstoaccomodate) );
00283
00284
00285
00286
00287
00288
00289 ptr++;
00290 bitstoaccomodate -= (8-bitsalreadyfilled);
00291 bitsalreadyfilled = 0;
00292
00293
00294
00295 }
00296
00297 else if(bitstoaccomodate < (8 - bitsalreadyfilled) && bitstoaccomodate >0){
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309 value += ( ( (*ptr << bitsalreadyfilled) & 0xff ) >> (8 - bitstoaccomodate) ) ;
00310
00311
00312
00313
00314
00315 objdata.push_back(value);
00316 value = 0;
00317 bitsalreadyfilled+=bitstoaccomodate;
00318
00319
00320
00321 if(ifield==Nfields-1) return;
00322
00323
00324
00325 ifield++;
00326 bitstoaccomodate=Format::getFieldLastBit(ifield)-Format::getFieldLastBit(ifield-1);
00327
00328
00329
00330 }
00331
00332 else if(bitstoaccomodate == (8 - bitsalreadyfilled) && bitstoaccomodate >0){
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343 value += ( ( (*ptr << bitsalreadyfilled) & 0xff ) >> (8 - bitstoaccomodate) ) ;
00344
00345
00346
00347
00348
00349 objdata.push_back(value);
00350 value = 0;
00351 bitsalreadyfilled=0;
00352
00353
00354
00355 if(ifield==Nfields-1) return;
00356
00357
00358
00359 ptr++;
00360 ifield++;
00361 bitstoaccomodate=Format::getFieldLastBit(ifield)-Format::getFieldLastBit(ifield-1);
00362
00363
00364
00365 }
00366 else throw std::string(" unexpected situation during uncompression");
00367
00368 }
00369
00370 }
00371
00372
00373
00374
00375 void compressObject(const unsigned char * ptr, std::vector<unsigned int>::iterator & vit, int & bitsalreadyfilled) {
00376
00377 int Nfields = Format::getNumberOfFields();
00378
00379 int bitstoaccomodate=Format::getFieldLastBit(0)+1;
00380
00381 if (*vit > pow(2.,bitstoaccomodate)-1) throw string("The value is too large to fit in the field ");
00382
00383 int ifield = 0;
00384
00385
00386 *ptr &= 0xff + 1 - (unsigned int)pow(2.,8-bitsalreadyfilled);
00387
00388 while (ifield < Nfields) {
00389
00390
00391 if(bitstoaccomodate > 8 - bitsalreadyfilled ) {
00392
00393
00394
00395
00396 *ptr += (((*vit) >> (bitstoaccomodate - (8 - bitsalreadyfilled))) & 0xff);
00397
00398
00399
00400
00401 bitstoaccomodate -= (8-bitsalreadyfilled);
00402 bitsalreadyfilled = 0;
00403 ptr++;
00404 *ptr &= 0xff + 1 - (unsigned int)pow(2.,8-bitsalreadyfilled);
00405
00406
00407
00408 }
00409
00410 else if(bitstoaccomodate < (8 - bitsalreadyfilled) && bitstoaccomodate >0){
00411
00412
00413
00414 *ptr += ( (((*vit) << 8-bitstoaccomodate) & 0xff) >> (bitsalreadyfilled) );
00415
00416
00417
00418
00419
00420 vit++;
00421 bitsalreadyfilled+=bitstoaccomodate;
00422
00423
00424
00425 if(ifield==Nfields-1) return;
00426
00427
00428
00429 ifield++;
00430 bitstoaccomodate=Format::getFieldLastBit(ifield)-Format::getFieldLastBit(ifield-1);
00431 if (*vit > pow(2.,bitstoaccomodate)-1) throw string("The value is too large to fit in the field ");
00432
00433
00434
00435 }
00436
00437 else if(bitstoaccomodate == (8 - bitsalreadyfilled) && bitstoaccomodate >0){
00438
00439
00440
00441
00442 *ptr += ( (((*vit) << 8-bitstoaccomodate) & 0xff) >> (bitsalreadyfilled) );
00443
00444
00445
00446
00447
00448 vit++;
00449 bitsalreadyfilled=0;
00450
00451
00452
00453 if(ifield==Nfields-1) return;
00454
00455
00456
00457 ptr++;
00458 *ptr &= 0xff + 1 - (unsigned int)pow(2.,8-bitsalreadyfilled);
00459
00460 ifield++;
00461 bitstoaccomodate=Format::getFieldLastBit(ifield)-Format::getFieldLastBit(ifield-1);
00462
00463 if (*vit > pow(2.,bitstoaccomodate)-1) throw string("The value is too large to fit in the field ");
00464
00465
00466
00467 }
00468 else throw string(" unexpected situation during compression");
00469
00470 }
00471
00472 }
00473
00474
00475 private:
00476
00477 std::map < int, std::vector<unsigned int> > data_;
00478
00479 int size_;
00480 unsigned char * buffer_;
00481 int nobjects_;
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605 };
00606
00607
00608 #endif