Home | News | Documentation | Download

How to read from TBuffer

Hello,
I am writing a custom Streamer, which is supposed to save my object as a CSV file and read it accordingly. As far as I understand, this is just a matter of implementing a void Streamer(TBuffer&) method and writing/reading data to/from TBuffer.

My problem is that I cannot find any examples of reading from TBuffer, nor I could find unit tests in the ROOT sources which would demonstrate this. I tried the following ways:

root [0] std::string out;
root [1] TBufferFile f(TBuffer::EMode::kRead, 13, (void*)"first\nsecond");
root [2] f >> out;
ROOT_prompt_2:1:3: error: invalid operands to binary expression ('TBufferFile' and 'std::string' (aka 'basic_string<char>'))
f >> out;
~ ^  ~~~
root [3] f.ReadStdString(out);
root [4] out
(std::string &) "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"

As you can see, they seem to fail. That being said, I am aware that I could use f.Buffer(), but I am not sure if I can assume that returned string will contain always the whole file/message/object (not 1024 first characters for example). In this case, I can see that the string is there indeed:

root [5] f.Buffer()
(char *) "first
second"

Could I ask you for some recommendations on how should I approach this? Getting the input line-by-line would be ideal in the case of CSV format.
Many thanks!


ROOT Version: v6.24.06
Platform: CC7
Compiler: GCC v7.3.0


Hi @pkonopka,

This function is not suitable for your use case, as it is the counterpart of WriteStdString(), i.e. the string length is encoded before the raw bytes.

OTOH, I suspect that you will have to read chunks of data (probably using TBuffer::ReadBuf() or similar), and manually read/parse the input until you find some delimiter character. I am inviting @pcanal to this topic, as I am sure he will provide you more information on how to accomplish this.

Cheers,
J.

Why? (More than likely storing the data in a TTree will ends up being a much better solution).

What is your end goal?

If you store your data in the CSV format inside a TBuffer then

  1. You need to convert the value a string
  2. You then need to convert the string into the TBuffer format
  3. You can only read it by extracting the string from the TBuffer and then decoding the csv file
  4. No external tools (spreadsheet program for example) can read the data directly (they would need the csv stored in a text file).

Thanks to both of you!

I want to have objects in some database which can be edited either by a C++/ROOT application (then it would use ROOT I/O) or by a web application which should not be aware of ROOT.

However, reading your point 4, I understand it is a dead end and I should rather not use ROOT for that specific class at all. Initial reason to use ROOT I/O was consistency with the way that other objects are stored in that database.

Would using ‘jsroot’ (JavaScript implementation of the core part of ROOT) be an option?

Hm, I don’t know. I am aware that JSROOT can visualize mostly histograms, but I am not sure about TTrees or custom classes with custom streamers. Can it read and write such an object without having a dictionary for it upfront?

The web app should basically visualize tables stored as CSV files in the database and let users edit them. I fear that introducing JSROOT only to be able to read/write a piece of text would be a bit too much complication against the gain (JSROOT would not be even aware it is CSV). Especially that the web app is being implemented by some students, so I should avoid bringing complexity on their side.

Indeed, JSROOT would not be able to read a custom streamer (without additional coding). On the other hand, if the data can be stored in a CSV file, it is “surprising” that it would need a custom streamer.

That said, JSROOT can easy read TTree that are split (especially when semantically equivalent to a cvs file) and, If I remember correctly, can also give some access to non-split data (a little more complex).

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.