RE: Problem with the Streamer function of a class derived from TDirectory...

From: Philippe Canal <pcanal_at_fnal.gov>
Date: Wed, 19 Mar 2008 12:39:59 -0500


Hi Pierre-Luc,

Actually (sorry for the confusion) TDirectory(File) is very special and overloading it require more updates that just the Streamer. In your case, think are likely to work if you write a custom streamer (i.e #pragma link C++ class QMyDir-; and implement the Streamer function by hand) which _only_ forward the call to TDirectoryFile::Streamer (which should work somewhat since you do not have any member).

Assumingly your intent is to add some member, in which case you would have to at least overload FillBuffer and ReadKeys to take in consideration the extra members.

So, this begs the question :), what are you trying to achieve by overloading TDirectoryFile and is there a simplier mean to achieve it?

Cheers,
Philippe.

-----Original Message-----
From: Pierre-Luc Drouin [mailto:pldrouin_at_physics.carleton.ca] Sent: Tuesday, March 18, 2008 10:50 AM
To: Philippe Canal
Cc: 'Rene Brun'; roottalk_at_root.cern.ch
Subject: Re: [ROOT] Problem with the Streamer function of a class derived from TDirectory...

I have modified my LinkDef file, recompiled everything, regenerated the root file and I got the same error:

Error in <TBufferFile::ReadBuffer2>: class: TUUID, attempting to access a wrong version: 127, object skipped at offset 87 Error in <TFile::ReadBuffer>: error reading all requested bytes from file file.root, got 0 of 2687036
(class TObject*)0x8346328

The autogenerated code for the Streamer function is the following:

void QMyDir::Streamer(TBuffer &R__b)
{

   // Stream an object of class QMyDir.

   if (R__b.IsReading()) {

      R__b.ReadClassBuffer(QMyDir::Class(),this);    } else {

      R__b.WriteClassBuffer(QMyDir::Class(),this);    }
}

Thank you
Pierre-Luc Drouin

Philippe Canal wrote:
> Hi Pierre-Luc,

>

> Can you try after enabling the new I/O?
> i.e:
> #pragma link C++ class QMyDir+;
>
>

> Cheers,
> Philippe.
>

> -----Original Message-----
> From: owner-roottalk_at_root.cern.ch [mailto:owner-roottalk_at_root.cern.ch] On
> Behalf Of Pierre-Luc Drouin
> Sent: Tuesday, March 18, 2008 10:27 AM
> To: Rene Brun
> Cc: roottalk_at_root.cern.ch
> Subject: Re: [ROOT] Problem with the Streamer function of a class derived
> from TDirectory...
>

> Hi,
>

> I have installed 5.18/00 (I was using 5.14/00e before) and I have
> derived my class from TDirectoryFile. The code of my class is now the
> following:
>

> #include "Rtypes.h"
> #include "TObject.h"
> #include "TDirectoryFile.h"
>

> class QMyDir: public TDirectoryFile
> {
> public:
> QMyDir():TDirectoryFile(){}
>

> QMyDir(const QMyDir& newqds):TDirectoryFile(){}
>
> QMyDir(const char *name, const char *title, TDirectory* motherDir =
> 0):TDirectoryFile(name,title,"QMyDir",motherDir){}
>

> virtual ~QMyDir(){}
>
> QMyDir& operator=(const QMyDir &rhs){fprintf(stderr,"Warning:
> TDirectoryFile::operator= cannot be called from derived class
> QMyDir\n"); return *this;}
>

> private:
>

> ClassDef(QMyDir,1) //QSigEx Data Structure Class
> };
>

> I still get an error when I try to load the instance from the file. I
> have stored and have tried to load the instance using the code I have
> shown in my previous email. Here is the error I get:
>

> _file0->Get("dir")
> Error in <TBufferFile::ReadBuffer2>: class: TUUID, attempting to access
> a wrong version: 127, object skipped at offset 87
> Error in <TFile::ReadBuffer>: error reading all requested bytes from
> file file.root, got 0 of 2687036
> (class TObject*)0x8345fa8
>

> Thank you
> Pierre-Luc Drouin
>

> Rene Brun wrote:
>
>> Pierre-Luc,
>>
>> Instead of TDirectory, you should derive from TDirectoryFile. In 
>> version 5.16, TDirectory
>> became an abstract interface. See 5.16 Release Notes at:
>> http://root.cern.ch/root/Version516.news.html
>>
>> Rene Brun
>>
>> Pierre-Luc Drouin wrote:
>>     
>>> Hi,
>>>
>>> I have derived a class from TDirectory and I am trying to store and 
>>> retrieve an instance of this class to/from a ROOT file.
>>>
>>> I am using the autogenerated Streamer function and when I call 
>>> TDirectory 
>>> <http://root.cern.ch/root/html514/src/TDirectory.cxx.html#OUS8P>(const 
>>> char *name, const char *title, Option_t 
>>> <http://root.cern.ch/root/html514/ListOfTypes.html#Option_t> 
>>> *classname, TDirectory 
>>> <http://root.cern.ch/root/html514/TDirectory.html>* initMotherDir) 
>>> from the constructor of my class, I set classname to the name of my 
>>> class.
>>>
>>> I do not get any warning/error message when I Write the instance in 
>>> the root file, but I get the following error when I try to load the 
>>> instance using TFile::Get:
>>>
>>> Error in <TBuffer::ReadVersion>: Could not find the StreamerInfo with 
>>> a checksum of 0 for the class "TUUID" in file.root.
>>> Error in <TBuffer::CheckByteCount>: object of class TUUID read too 
>>> few bytes: 22 instead of 898023151
>>> Error in <TBuffer::CheckByteCount>: Byte count probably corrupted 
>>> around buffer position 85:
>>>        898023151 for a possible maximum of 17
>>> SysError in <TFile::Seek>: cannot seek to position 60235645022633984 
>>> in file file.root, retpos=-1 (Invalid argument)
>>> Error in <TFile::ReadBuffer>: error reading all requested bytes from 
>>> file file.root, got 186 of 2687036
>>>
>>> Here is the code of a class that allows to reproduce the problem:
>>>
>>> class QMyDir: public TDirectory
>>> {
>>>  public:
>>>    QMyDir():TDirectory(){}
>>>
>>>    QMyDir(const QMyDir& newqds):TDirectory(){*this=newqds; }
>>>
>>>    QMyDir(const char *name, const char *title, TDirectory* motherDir 
>>> = 0):TDirectory(name,title,"QMyDir",motherDir){}
>>>
>>>    virtual ~QMyDir(){}
>>>
>>>    QMyDir& operator=(const QMyDir &rhs){fprintf(stderr,"Warning: 
>>> TDirectory::operator= function is private and cannot be called by 
>>> derived class QMyDir\n"); return *this;}
>>>
>>>  private:
>>>
>>>    ClassDef(QMyDir,1) //QSigEx Data Structure Class
>>> };
>>>
>>> Here is the code of the autogenerated Streamer function:
>>>
>>> void QMyDir::Streamer(TBuffer &R__b)
>>> {
>>>   // Stream an object of class QMyDir.
>>>
>>>   UInt_t R__s, R__c;
>>>   if (R__b.IsReading()) {
>>>      Version_t R__v = R__b.ReadVersion(&R__s, &R__c); if (R__v) { }
>>>      TDirectory::Streamer(R__b);
>>>      R__b.CheckByteCount(R__s, R__c, QMyDir::IsA());
>>>   } else {
>>>      R__c = R__b.WriteVersion(QMyDir::IsA(), kTRUE);
>>>      TDirectory::Streamer(R__b);
>>>      R__b.SetByteCount(R__c, kTRUE);
>>>   } }
>>>
>>> Now how I get the error in CINT:
>>>
>>> root [0] TFile file("file.root","recreate")
>>> root [1] QMyDir* dir=new QMyDir("dir","dir")
>>> root [2] file.ls()
>>> TFile**         file.root
>>> TFile*         file.root
>>>  QMyDir*               dir     dir
>>>  KEY: QMyDir   dir;1   dir
>>> root [3] file.Write()
>>> (Int_t)0
>>> root [4] file.Close()
>>> root [5] .q
>>>
>>> root [0] TFile file("file.root","read")
>>> root [1] file.ls()
>>> TFile**         file.root
>>> TFile*         file.root
>>>  KEY: QMyDir   dir;1   dir
>>> root [2] QMyDir *dir=file.Get("dir")
>>> Error in <TBuffer::ReadVersion>: Could not find the StreamerInfo with 
>>> a checksum of 0 for the class "TUUID" in file.root.
>>> Error in <TBuffer::CheckByteCount>: object of class TUUID read too 
>>> few bytes: 22 instead of 898023151
>>> Error in <TBuffer::CheckByteCount>: Byte count probably corrupted 
>>> around buffer position 85:
>>>        898023151 for a possible maximum of 17
>>> SysError in <TFile::Seek>: cannot seek to position 60235645022633984 
>>> in file file.root, retpos=-1 (Invalid argument)
>>> Error in <TFile::ReadBuffer>: error reading all requested bytes from 
>>> file file.root, got 186 of 2687036
>>>
>>>
>>> Thanks!
>>> Pierre-Luc Drouin
>>>
>>>
>>>       
>
>

>
Received on Wed Mar 19 2008 - 19:01:44 CET

This archive was generated by hypermail 2.2.0 : Wed Mar 19 2008 - 23:50:01 CET