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

From: Philippe Canal <pcanal_at_fnal.gov>
Date: Thu, 20 Mar 2008 08:22:27 -0500


Yes it will be there shortly.

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: Thursday, March 20, 2008 7:43 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...

Hi,

yes I had tried that and it has fixed the problem. Would it be possible to commit that change to the ROOT repository?

Thanks!
Pierre-Luc

Philippe Canal wrote:
> Hi Pierre-luc,
>
> No there is no reason (besides being slightly faster:))
> Can you try with
>
> if (cl->InheritsFrom(TDirectoryFile::Class())
>
> instead?
>
> Tnanks,
> Philippe.
>
> -----Original Message-----
> From: Pierre-Luc Drouin [mailto:pldrouin_at_physics.carleton.ca]
> Sent: Wednesday, March 19, 2008 8:21 PM
> 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...
>
> Hi,
>
> I got it mostly to work now by overloading Streamer, FillBuffer and
> WriteDirHeader functions. The only thing that is not working right now
> is that the name, the title and the mother of instances of my class are
> not set when loaded from a file. For TDirectoryFile instances, I have
> seen that these are set in the TKey::ReadObj function:
>
> if (cl == TDirectoryFile
> <http://root.cern.ch/root/html/TDirectoryFile.html>::Class
>

<http://root.cern.ch/root/html/TDirectoryFile.html#TDirectoryFile:Class>())
> {
> TDirectory <http://root.cern.ch/root/html/TDirectory.html> *dir =
> dynamic_cast<TDirectoryFile
> <http://root.cern.ch/root/html/TDirectoryFile.html>*>(tobj);
> dir->SetName
> <http://root.cern.ch/root/html/TNamed.html#TNamed:SetName>(GetName
> <http://root.cern.ch/root/html/TNamed.html#TNamed:GetName>());
> dir->SetTitle
> <http://root.cern.ch/root/html/TNamed.html#TNamed:SetTitle>(GetTitle
> <http://root.cern.ch/root/html/TKey.html#TKey:GetTitle>());
> dir->SetMother(fMotherDir
> <http://root.cern.ch/root/html/TKey.html#TKey:fMotherDir>);
> fMotherDir
> <http://root.cern.ch/root/html/TKey.html#TKey:fMotherDir>->Append
> <http://root.cern.ch/root/html/TDirectory.html#TDirectory:Append>(dir);
> }
>
> Is there a particular reason why this block of code is executed only for
> the TDirectoryFile class and not also for classes that are derived from
> TDirectoryFile? Because right now I don't see how else I could get a
> pointer to the mother directory...
>
> Thanks!
> Pierre-Luc
>
> Philippe Canal wrote:
>
>> Hi Pierre-Luc,
>>
>> The Streamer is not called when writing (it is done via FillBuffer
>> instead).
>>
>>
>>
>>> What I want to do is to index the objects contined in a TDirectory
>>> using a TObjArray in addition to the THashList.
>>>
>>>
>> Humm ... why? :) ... It might be easier to write an adapter class
>> that is either created on the fly at read time and/or save in
>> the TDirectory.
>>
>> Cheers,
>> Philippe.
>>
>> -----Original Message-----
>> From: Pierre-Luc Drouin [mailto:pldrouin_at_physics.carleton.ca]
>> Sent: Wednesday, March 19, 2008 1:56 PM
>> 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...
>>
>> What I want to do is to index the objects contained in a TDirectory
>> using a TObjArray in addition to the THashList.
>>
>> I have tried to implement my own Streamer function in my simple class
>> (QMyDir), but for some reason it does not seam to be called when I open
>> a file, create an instance of my class and then save the file. How is
>> the Streamer function of TDirectoryFile called exactly (for writing)?
>> When I look at the constructor of TDirectoryFile and at
>> TDirectoryFile::Write, it seams that it is always FillBuffer that is
>> called...
>>
>> Philippe Canal wrote:
>>
>>
>>> 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 Thu Mar 20 2008 - 14:22:48 CET

This archive was generated by hypermail 2.2.0 : Thu Mar 20 2008 - 17:50:01 CET