Reputation: 537
I have one function which is an call back from a library it looks like follows:
void onCallBack(int date, const std::stringstream &data);
I want to write data received from a data
variable to an physical file so i am doing this:
void onCallBack(int date, const std::stringstream &data)
{
ofstream filePtr;
filePtr.open("data.file", ios::app);
string dataToWrite = data.str();
filePtr << dataToWrite.c_str();
filePtr.close();
}
call back onCallBack
function gets called when ever there is an update in data and i want to write this updated data to the file.
problem is that data is std::stringstream
type and it behaves like an file/buffer and and from this buffer i just want to read update data part for example:
In first call back data
contains string
this is first line
and in second call back it contains:
this is first line
this is second line
In the first call of the call back function I write this is first line
string to the file and in second call back I just want to write this is second line
to file not the fist line again.
How can i extract only updated part of the std::stringstream
.
const std::stringstream &data
variable is constant and can't be modified or we can't use tellg
or sync
.
UPDATE/EDIT:
1. Sorry for c tag.
2. for using read
we need to provide block size to read and i don't know the block size.
3. Can you provide an example of doing this using ios_base::xalloc, ios:base::iword, and ios_base::pword.
4. read is not a const but tellg is.
5. yes no one call data.str("")
, it is an pure virtual function from lib, in my code i am not doing this.
Upvotes: 2
Views: 7841
Reputation: 7996
If you are sure the stringstream
object is the same for each calls to your callback, you can do that:
filePtr << data.rdbuf() << std::flush;
Upvotes: 0
Reputation: 8709
You could clear the file contents before writing to it by replacing ios::app
with ios::trunc
.
Obviously its not optimal to write the entire stream every time, but if you can't change the prototype or flush the stream and you don't know the size of the new data, then I this is the only way I can think of doing it..
Upvotes: 0
Reputation: 88711
The solution is to remember how much you've read previously and then take only part of the string as appropriate. How you do that is up to you. You could modify your call back to pass some kind of state in:
void onCallBack(int date, const std::stringstream &data, std::string::size_type& state);
If it's part of an interface (unlikely given what you posted, but that is a good way to do callbacks in general) you can store that state as a private member variable.
If you don't care about being reentrant and the stream never shrinks you could do it as a quick hack using a static
variable in this example, which is the easiest to show working here, but asking for trouble:
// What happens if you change the stringstream?
// This is why you need to re-think the callback interface
static std::string::size_type state = 0;
string dataToWrite = data.str().substr(state);
state += dataToWrite.size();
Upvotes: 2