/***************************************************************************
 *                                                                         *
 * $Log: MDdataContainer.h,v $
 * Revision 1.1  2008/04/14 11:41:08  daq
 * Initial revision
 *
 * Revision 1.4  2008/04/10 11:12:42  daq
 * cosmetics
 *
 * Revision 1.3  2007/12/14 09:11:16  daq
 * *** empty log message ***
 *
 * Revision 1.2  2007/06/28 16:29:56  daq
 * First Working version
 *
 * Revision 1.1  2007/06/27 12:01:07  daq
 * Initial revision
 *
                                                                           *
 * Originally created by J.S. Graulich june 2007                           *
 *                                                                         *
 ***************************************************************************/

#ifndef __MDDATACONTAINER_H
#define __MDDATACONTAINER_H

#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <iomanip>
#include <utility>
#include <vector>
#include <string>

#include "MDexception.h"

using namespace std;
typedef void (* DataTestCallback)( unsigned long32 );

class MDdataContainer {
 protected:
  unsigned char* _data;
  unsigned int   _size;
  bool           _valid;

  DataTestCallback _testCallBack;

 public:
  MDdataContainer(void *d=0,unsigned int s=1)
  :_data((unsigned char*)d),_size(s),_valid(false), _testCallBack(0){}

  MDdataContainer( MDdataContainer& dc) {
    _data  = dc.GetDataPtr();
    _size  = dc.GetSize();
    _valid = dc.IsValid();
  }

  virtual ~MDdataContainer(){}
  unsigned char* GetDataPtr(unsigned int i=0) {
    if ( i<_size ) return &_data[i];
    else return NULL;
  }

  uint32_t* Get32bWordPtr(unsigned int i=0) {
    if ( (i*4) < _size ) return (uint32_t*)&_data[i*4];
    else {
      stringstream ss;
      ss << "ERROR in MDdataContainer::Get32bWordPtr - the size is exceeded ";
      ss << "(i=" << i << " size=" << _size <<").";
      throw MDexception(ss.str());
      return NULL;
    }
  }

  bool           IsValid( void ){ return _valid; }
  unsigned int   GetSize() {return _size;}

  virtual void SetDataPtr( void *d ) {
    _data = (unsigned char*)d;
    _valid = false;
    _size = 1;
  }

  virtual void SetTest(DataTestCallback funk) {_testCallBack = funk;}

  void Validate()   { _valid = true;}
  void UnValidate() { _valid = false;}
  void SetSize(unsigned int s) {_size = s;}

  virtual void Dump(int atTheTime=1){
    if (_size%4) cerr << " Not 32 bits data !! Trying to ignore " ;
    unsigned int ibyte(0),iword;
    unsigned int nword=_size>>2;

    for (iword=0 ; iword < nword ; ++iword) {
      if ( iword%atTheTime == 0 ) cout << dec << setfill(' ') << setw(9)<< iword*4 << ") " ;
      cout << noshowbase << hex ;
      cout << setfill('0') << setw(8)
           << *Get32bWordPtr(iword) << " (" ;
      for ( ibyte=0; ibyte<4; ++ibyte) {
        if ( isprint( _data[iword*4+ibyte]) ) cout << _data[iword*4+ibyte];
        else cout << ".";
      }
      cout << ") " ;
      if ( (iword+1)%atTheTime == 0 ) cout << endl;
    }
    for ( ibyte=0; ibyte<_size%4; ++ibyte) {
      if ( isprint( _data[nword*4+ibyte]) )
        cout << _data[nword*4+ibyte] ;
        else cout << ".";
    }
    if ( ibyte ) cout << endl;
    else if  ( iword%atTheTime ) cout << endl;
    cout << dec << noshowbase << setfill(' ') ;
  }

};

#endif