inlib  1.2.0
Public Member Functions | Protected Member Functions | Static Protected Member Functions | Protected Attributes
inlib::rroot::buffer Class Reference
Inheritance diagram for inlib::rroot::buffer:
Inheritance graph
[legend]
Collaboration diagram for inlib::rroot::buffer:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 buffer (std::ostream &a_out, bool a_byte_swap, uint32 a_size, char *a_buffer, uint32 a_klen, bool a_verbose)
virtual ~buffer ()
void set_offset (unsigned int a_off)
uint32 length () const
uint32 size () const
bool read_object (ifac &a_fac, const ifac::args &a_args, iro *&a_obj)
bool read_version (short &a_version)
bool read_version (short &a_version, uint32 &a_start_pos, uint32 &a_byte_count)
bool check_byte_count (uint32 a_start_pos, uint32 a_byte_count, const std::string &a_store_cls)

Protected Member Functions

 buffer (const buffer &a_from)
bufferoperator= (const buffer &)
bool read_class_tag (std::string &a_class)
bool read_class (std::string &a_class, uint32 &a_bcnt, bool &a_is_ref)
bool read_string (char *a_string, uint32 a_max)

Static Protected Member Functions

static uint32 kNullTag ()
static uint32 kByteCountMask ()
static uint32 kNewClassTag ()
static uint32 kClassMask ()
static uint32 kMapOffset ()
static short kByteCountVMask ()
static std::string sout (const std::string &a_string)

Protected Attributes

bool m_byte_swap
bool m_verbose
uint32 m_size
char * m_buffer
char * m_pos
uint32 m_klen

Detailed Description

Definition at line 22 of file buffer.


Constructor & Destructor Documentation

inlib::rroot::buffer::buffer ( std::ostream &  a_out,
bool  a_byte_swap,
uint32  a_size,
char *  a_buffer,
uint32  a_klen,
bool  a_verbose 
) [inline]

Definition at line 28 of file buffer.

  : rbuf(a_out,a_byte_swap,a_buffer+a_size,m_pos)
  ,m_byte_swap(a_byte_swap)
  ,m_verbose(a_verbose)
  ,m_size(a_size)     //expect a not zero size.
  ,m_buffer(a_buffer) //don't get ownership.
  ,m_pos(a_buffer)
  ,m_klen(a_klen) //to compute refs (used in read_class, read_object)
  {
#ifdef INLIB_MEM
    mem::increment(s_class().c_str());
#endif
  }
virtual inlib::rroot::buffer::~buffer ( ) [inline, virtual]

Definition at line 42 of file buffer.

                   {
#ifdef INLIB_MEM
    mem::decrement(s_class().c_str());
#endif
  }
inlib::rroot::buffer::buffer ( const buffer a_from) [inline, protected]

Definition at line 48 of file buffer.

  : rbuf(a_from.m_out,a_from.m_byte_swap,0,m_pos)
  ,m_byte_swap(a_from.m_byte_swap)
  {
#ifdef INLIB_MEM
    mem::increment(s_class().c_str());
#endif
  }

Member Function Documentation

bool inlib::rroot::buffer::check_byte_count ( uint32  a_start_pos,
uint32  a_byte_count,
const std::string &  a_store_cls 
) [inline]

Definition at line 381 of file buffer.

                                                            {
    if(!a_byte_count) return true;

    unsigned long len = a_start_pos + a_byte_count + sizeof(unsigned int);

    unsigned long diff = m_pos-m_buffer;  

    if(diff==len) return true;

    if(diff<len) {
      m_out << "inlib::rroot::buffer::check_byte_count :"
            << " object of class " << sout(a_store_cls)
            << " read too few bytes (" 
            << long2s(len-diff) << " missing)."
            << std::endl;
    }
    if(diff>len) {
      m_out << "inlib::rroot::buffer::check_byte_count :"
            << " object of class " << sout(a_store_cls)
            << " read too many bytes (" 
            << long2s(diff-len) << " in excess)." << std::endl;
    }

    m_out << "inlib::rroot::buffer::check_byte_count :"
          << " " << sout(a_store_cls)
          << " streamer not in sync with data on file, fix streamer."
          << std::endl;
    
    m_pos = m_buffer+len;

    return false;
  }
static uint32 inlib::rroot::buffer::kByteCountMask ( ) [inline, static, protected]

Definition at line 67 of file buffer.

{return 0x40000000;}
static short inlib::rroot::buffer::kByteCountVMask ( ) [inline, static, protected]

Definition at line 72 of file buffer.

{return 0x4000;}
static uint32 inlib::rroot::buffer::kClassMask ( ) [inline, static, protected]

Definition at line 70 of file buffer.

{return 0x80000000;  }
static uint32 inlib::rroot::buffer::kMapOffset ( ) [inline, static, protected]

Definition at line 71 of file buffer.

{return 2;}
static uint32 inlib::rroot::buffer::kNewClassTag ( ) [inline, static, protected]

Definition at line 69 of file buffer.

{return 0xFFFFFFFF;}
static uint32 inlib::rroot::buffer::kNullTag ( ) [inline, static, protected]

Definition at line 66 of file buffer.

{return 0;}
uint32 inlib::rroot::buffer::length ( ) const [inline]

Definition at line 61 of file buffer.

{return m_pos-m_buffer;}
buffer& inlib::rroot::buffer::operator= ( const buffer ) [inline, protected]

Definition at line 56 of file buffer.

{return *this;}
bool inlib::rroot::buffer::read_class ( std::string &  a_class,
uint32 a_bcnt,
bool &  a_is_ref 
) [inline, protected]

Definition at line 122 of file buffer.

                                                                   {
    //m_verbose = true;
    a_class.clear();
    a_bcnt = 0;
    a_is_ref = false;

    uint32 fVersion = 0;       //Buffer format version

    // read byte count and/or tag (older files don't have byte count)
    uint32 first_int = 0;
    if(!rbuf::read(first_int)) return false;

    if(m_verbose) {
      m_out << "inlib::rroot::read_class :"
            << " first_int " << tosx(first_int)
            << std::endl;
    }

    if(first_int==kNullTag()) { //GB
      if(m_verbose) {
        m_out << "inlib::rroot::read_class :"
              << " first_int is kNullTag."
              << std::endl;
      }
      a_bcnt = 0;
      return true;

  //} else if(first_int==kNewClassTag()) { // class desc follows.
    } else if(first_int & kByteCountMask()) {
      // at write :
      //   skip int to store bcnt.
      // + write class
      //     if(!write((clIdx | Rio_kClassMask))) return false;
      //   or
      //     if(!write(Rio_kNewClassTag)) return false;
      // + write object 
      // + set byte cnt (cnt|kByteCountMask()) at skipped int.

      if(m_verbose) {
        m_out << "inlib::rroot::read_class :"
              << " first_int & kByteCountMask."
              << std::endl;
      }

      uint32 bef_tag = m_pos-m_buffer;
      fVersion = 1;

      std::string scls;
      if(!read_class_tag(scls)) return false;
      if(scls.empty()) {
        m_out << "inlib::rroot::buffer::read_class :"
              << " read_class_tag did not find a class name."
              << std::endl;
        return false;
      }

      a_class = scls;
      a_bcnt = (first_int & ~kByteCountMask());

      if(m_verbose) {
        m_out << "inlib::rroot::read_class :"
              << " kNewClassTag : read class name " << sout(a_class)
              << " a_bcnt " << a_bcnt
              << " bef_tag " << bef_tag
              << "." << std::endl;
      }

      return true;
            
    } else {
      if(m_verbose) {
        m_out << "inlib::rroot::read_class :"
             << " first_int " << tosx(first_int)
             << ". first_int is position toward object."
             << std::endl;
      }
      a_bcnt = first_int; //pos toward object.
      a_is_ref = true;
      a_class.clear();
      return true;
    }
    
    return false;
  }  
bool inlib::rroot::buffer::read_class_tag ( std::string &  a_class) [inline, protected]

Definition at line 74 of file buffer.

                                          {
    a_class.clear();

    uint32 tag;
    if(!rbuf::read(tag)) return false;
    //m_out << "tag " << tag << " " << tosx(tag) << std::endl;

    if(tag==kNewClassTag()) {
      char s[80];
      if(!read_string(s, 80)) {
        m_out << "inlib::rroot::read_class_tag :"
              << " read string." << std::endl;
        return false;
      }
      //m_out << "inlib::rroot::read_class_tag :"
      //      << " tag kNewClassTag"
      //      << " class " << s
      //      << std::endl;
      a_class = s;
      return true;

    } else if(tag & kClassMask()) {
      //m_out << "inlib::rroot::read_class_tag :"
      //      << " tag & kClassMask"
      //      << " ref " << (uint32)(tag & ~kClassMask)
      //      << " recurse..."
      //      << std::endl;

      unsigned int cl_offset = (tag & ~kClassMask());
      cl_offset -= kMapOffset();
      cl_offset -= m_klen;
      char* old_pos = m_pos;
      m_pos = m_buffer + cl_offset;
      //std::string scls;
      //uint32 ref;
      if(!read_class_tag(a_class)) return false;
      m_pos = old_pos;

      return true;

    } else {
      m_out << "inlib::rroot::read_class_tag :"
            << " tag unknown case ! " << tosx(tag)
            << std::endl;             
      return false;
    }
  }
bool inlib::rroot::buffer::read_object ( ifac a_fac,
const ifac::args a_args,
iro *&  a_obj 
) [inline]

Definition at line 207 of file buffer.

                                                                  {
    a_obj = 0;

    // before reading object save start position
    uint32 startpos = (uint32)(m_pos-m_buffer);

    uint32 bcnt;
    std::string sclass;
    bool is_ref;
    if(!read_class(sclass,bcnt,is_ref)) {
      m_out << "inlib::rroot::buffer::read_object :"
            << " can't read class." << std::endl;
      return false;
    }
    //::printf("debug : %d\n",length()-startpos);

    if(m_verbose) {
      m_out << "inlib::rroot::buffer::read_object :"
            << " class " << sout(sclass)
            << " bcnt " << bcnt
            << std::endl;
    }

    if(is_ref) {
      //bcnt is the position toward an object or an object ref.
      //m_out << "inlib::rroot::buffer::read_object :"
      //      << " is_ref " << bcnt
      //      << std::endl;

     {char* old_pos = m_pos;

      unsigned int obj_offset = bcnt;
      obj_offset -= kMapOffset();
      obj_offset -= m_klen;
      m_pos = m_buffer + obj_offset;

      uint32 first_int;
      if(!rbuf::read(first_int)) return false;
      if(first_int & kByteCountMask()) {
        std::string scls;
        if(!read_class_tag(scls)) return false;
        if(scls.empty()) {
          m_out << "inlib::rroot::buffer::read_object :"
                << " read_class_tag did not find a class name."
                << std::endl;
        }
      } else {
        m_out << "inlib::rroot::buffer::read_object :"
              << " zzz"
              << std::endl;
      }

      m_pos = old_pos;}

      // in principle at this point m_pos should be
      //   m_buffer+startpos+sizeof(unsigned int)
      // but enforce it anyway : 
      m_pos = m_buffer+startpos+sizeof(unsigned int); 
      //check_byte_count(startpos,0,sclass) would always be ok.

      //a_obj = ???

    } else {
      if(sclass.empty()) {
        //m_out << "inlib::rroot::buffer::read_object :"
        //      << " found empty class name."
        //      << std::endl;

        m_pos = m_buffer+startpos+bcnt+sizeof(unsigned int); 

      } else {

        iro* obj = a_fac.create(sclass,a_args);
        if(!obj) return false;
        //NOTE : if class ref, "up there"-startpos = 8.
        if(!obj->stream(*this)) {
          //restore a good buffer position :
          m_pos = m_buffer+startpos+bcnt+sizeof(unsigned int);
          delete obj;
          return false;
        }

        //NOTE : if obj stream ok, the below line is not needed.
        //m_pos = m_buffer+startpos+bcnt+sizeof(unsigned int);

        if(!check_byte_count(startpos,bcnt,sclass)) {
          m_out << "inlib::rroot::buffer::read_object :"
                << " check_byte_count failed "
                << "for object of class " 
                << sout(sclass) << "." << std::endl;
          delete obj;
          return false;
        }
        a_obj = obj;
      }

    }

    if(m_verbose) {
      m_out << "inlib::rroot::buffer::read_object :"
            << " end : "
            << std::endl;
    }

    return true;
  }
bool inlib::rroot::buffer::read_string ( char *  a_string,
uint32  a_max 
) [inline, protected]

Definition at line 416 of file buffer.

                                                {
    // Read string from I/O buffer. String is read till 0 character is
    // found or till max-1 characters are read (i.e. string s has max
    // bytes allocated).
    int nr = 0;
    while (nr < int(a_max-1)) {
      char ch;
      if(!rbuf::read(ch)) return false;
      // stop when 0 read
      if(ch == 0) break;
      a_string[nr++] = ch;
    }
    a_string[nr] = 0;
    return true;
  }
bool inlib::rroot::buffer::read_version ( short &  a_version) [inline]

Definition at line 314 of file buffer.

                                     {
    // Read class version from I/O buffer.
    // Is read a short or three shorts.
    a_version = 0;
    short version = 0;
    // not interested in byte count
    if(!rbuf::read(version)) return false;
      
    // if this is a byte count, then skip next short and read version
    if(version & kByteCountVMask()) {
      if(!rbuf::read(version)) return false;
      if(!rbuf::read(version)) return false;
    }
    
    a_version = version;
    return true;
  }
bool inlib::rroot::buffer::read_version ( short &  a_version,
uint32 a_start_pos,
uint32 a_byte_count 
) [inline]

Definition at line 332 of file buffer.

                                                {
    // Read class version from I/O buffer.
    // Is read one or three shorts.
    a_version = 0;
    a_start_pos = 0;
    a_byte_count = 0;

    short version = 0;

    // before reading object save start position
    uint32 startpos = (uint32)(m_pos-m_buffer);
      
    // read byte count (older files don't have byte count)
    // byte count is packed in two individual shorts, this to be
    // backward compatible with old files that have at this location
    // only a single short (i.e. the version)
    union {
      unsigned int cnt;
      short vers[2];
    } v;

    if(m_byte_swap) {
      if(!rbuf::read(v.vers[1])) return false;
      if(!rbuf::read(v.vers[0])) return false;
    } else {
      if(!rbuf::read(v.vers[0])) return false;
      if(!rbuf::read(v.vers[1])) return false;
    }
    
    // no bytecount, backup and read version
    uint32 bcnt = 0;
    if(v.cnt & kByteCountMask()) {
      bcnt = (v.cnt & ~kByteCountMask());
    } else {
      m_pos -= sizeof(unsigned int);
    }
    if(!rbuf::read(version)) return false;
    //printf("Reading version=%d at pos=%d, bytecount=%d\n",
    //version,*startpos,*bcnt);
    
    a_version = version;
    a_start_pos = startpos;
    a_byte_count = bcnt;
  
    return true;
  }
void inlib::rroot::buffer::set_offset ( unsigned int  a_off) [inline]

Definition at line 58 of file buffer.

{m_pos = m_buffer+a_off;}
uint32 inlib::rroot::buffer::size ( ) const [inline]

Definition at line 62 of file buffer.

{return m_size;}
static std::string inlib::rroot::buffer::sout ( const std::string &  a_string) [inline, static, protected]

Definition at line 435 of file buffer.

                                                   {
    return std::string("\"")+a_string+"\"";
  }

Member Data Documentation

char* inlib::rroot::buffer::m_buffer [protected]

Definition at line 442 of file buffer.

Reimplemented from inlib::rroot::rbuf.

Definition at line 439 of file buffer.

Definition at line 444 of file buffer.

char* inlib::rroot::buffer::m_pos [protected]

Reimplemented from inlib::rroot::rbuf.

Definition at line 443 of file buffer.

Definition at line 441 of file buffer.

Definition at line 440 of file buffer.


The documentation for this class was generated from the following file:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines