Skip to content
Prev Previous commit
Next Next commit
io: provide kSTLp text write action
In original code direct class streamer is called, 
which is impossible to handle with TBufferJSON.
Keep binary code as well in the action to have possibility
use same code-base for binary use-case
  • Loading branch information
linev committed May 16, 2017
commit c013c6df4931abca996d4044a0e825ff4b0e2b67
69 changes: 69 additions & 0 deletions io/io/src/TStreamerInfoActions.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,70 @@ namespace TStreamerInfoActions
return 0;
}

/** Direct copy of code from TStreamerInfo::WriteBufferAux,
* potentially can be used later for non-text streaming */
template<bool isText>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should read kIsTestT (k for constant, trailing T for template parameter).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mean: template<bool kIsTextT> ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

INLINE_TEMPLATE_ARGS Int_t WriteSTLp(TBuffer &buf, void *addr, const TConfiguration *config)
{
TClass *cl = config->fCompInfo->fClass;
TMemberStreamer *pstreamer = config->fCompInfo->fStreamer;
TVirtualCollectionProxy *proxy = cl->GetCollectionProxy();
TClass* vClass = proxy ? proxy->GetValueClass() : 0;
UInt_t eoffset = 0; // extra parameter of TStreamerInfo::WriteBufferAux, 0 for all kind of objects writing
UInt_t ioffset = eoffset + config->fOffset;

if (!buf.TestBit(TBuffer::kCannotHandleMemberWiseStreaming)
&& proxy && vClass
&& config->fInfo->GetStreamMemberWise()
&& cl->CanSplit()
&& !(strspn(config->fCompInfo->fElem->GetTitle(),"||") == 2)
&& !(vClass->TestBit(TClass::kHasCustomStreamerMember)) ) {
// Let's save the collection member-wise.

UInt_t pos = buf.WriteVersionMemberWise(config->fInfo->IsA(),kTRUE);
buf.WriteVersion( vClass, kFALSE );

// TODO: subinfo used for WriteBufferSTL call, which is private for the moment
//TStreamerInfo *subinfo = (TStreamerInfo*)vClass->GetStreamerInfo();

//for (int k = 0; k < narr; ++k) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line is comment-out, I assume it is not in the original. Is that the correct change (and if so, it should be explained) or is that inadvertently removing support for C-style array of STL vectors?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

potentially can be used later for non-text streaming
To verify that the code is indeed correct (at least as far as roottest can tell), I recommend to go ahead and also use those for the binary case.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the moment this part is not used - it is only for binary I/O.
To enable this, one should made subinfo->WriteBufferSTL() public

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why would it need to become public? In the contrary, isn't the action making WriteBufferSTL obsolete?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WriteBufferSTL still used in normal I/O.
Once we implement correspondent actions (including writing branches data), WriteBufferSTL can be removed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once we implement correspondent actions
I was pushing you in that direction as it will increase the test coverage and benefit all users ;)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was pushing you in that direction as it will increase the test coverage and benefit all users ;)

I prefer do it in small steps.
We have functional code and can incrementally improve it.
My main motivation now - clearly separate binary and text streaming from each other.
Once it is done, we could remove many workarounds from both.

char **contp = (char **)((char *)addr + ioffset);
for(int j=0;j<config->fCompInfo->fLength;++j) {
char *cont = contp[j];
TVirtualCollectionProxy::TPushPop helper( proxy, cont );
Int_t nobjects = cont ? proxy->Size() : 0;
buf << nobjects;

// TODO: method is private, should be made accesible from here
// subinfo->WriteBufferSTL(buf,proxy,nobjects);
}
//}
buf.SetByteCount(pos,kTRUE);
return 0;
}
UInt_t pos = buf.WriteVersion(config->fInfo->IsA(),kTRUE);
if (isText) {
// use same method which is used in kSTL
buf.WriteFastArray((void **)((char *) addr + ioffset), cl, config->fCompInfo->fLength, kFALSE, 0);
} else
if (pstreamer == 0) {
//for (int k = 0; k < narr; ++k) {
char **contp = (char**)((char *) addr + ioffset);
for(int j=0; j<config->fCompInfo->fLength; ++j) {
char *cont = contp[j];
cl->Streamer( cont, buf );
}
// }
} else {
//for (int k = 0; k < narr; ++k) {
(*pstreamer)(buf,(char *) addr + ioffset, config->fCompInfo->fLength);
//}
}
buf.SetByteCount(pos,kTRUE);
return 0;
}


/** Direct copy of code from TStreamerInfo::WriteBufferAux,
* potentially can be used later for non-text streaming */
template<bool isText>
Expand Down Expand Up @@ -3061,6 +3125,11 @@ void TStreamerInfo::AddWriteTextAction(TStreamerInfoActions::TActionSequence *wr
writeSequence->AddAction( WriteTextTNamed, new TConfiguration(this,i,compinfo,compinfo->fOffset) );
break;

case TStreamerInfo::kSTLp: // Pointer to container with no virtual table (stl) and no comment
case TStreamerInfo::kSTLp + TStreamerInfo::kOffsetL: // array of pointers to container with no virtual table (stl) and no comment
writeSequence->AddAction( WriteSTLp<true>, new TConfiguration(this,i,compinfo,compinfo->fOffset) );
break;

case TStreamerInfo::kStreamLoop:
case TStreamerInfo::kOffsetL + TStreamerInfo::kStreamLoop:
writeSequence->AddAction( WriteStreamerLoop<true>, new TConfiguration(this,i,compinfo,compinfo->fOffset) );
Expand Down