So, I've been trying to figure out, how to wait for data from a C++ stringstream (for instance), without being constantly checking if data is there, which is quite CPU consuming.
I'm perfectly able to read, for instance, from a serial device, and lock the process while no data arrives, but unfortunately I haven't been able to figure how to do that with C++ streams.
I'm sure I'm missing something, since cin does exactly that, i.e., waits for the return key to step out from istream reading, but how does it do it?
Thanks in advance for any light on the subject.
You can't. The only way
std::stringstream
can know that there isn't any further data is that there isn't any data in the stream.It's an interesting thought, however.
<<
on anstd::stringstream
only returns true if the write side has been closed. The only problem with the idea is thatstd::stringstream
doesn't have any idea of open or closed.The real question, however, is what you're trying to achieve.
std::stringstream
operates in process, and in that case, there's really no need for formatting (which is the abstraction of the iostreams in general). Just stuff the raw objects in anstd::deque
. The only time you should need to worry about formatting is when communicating with the exterior.std::istringstream
is very useful, for example, when you're getting the string fromstd::getline
on a file, or from some other source. Similarly,std::ostringstream
is useful when formatting data for some external source which requires a string of some sort. But I've never found a use forstd::stringstream
; it's there more for reasons of orthogonality, I think.Streams obtain data from an
std::streambuf
. For the case ofstd::cin
it calls the system'sread()
function (or equivalent) which blocks until data is handed over from the operating system. The console normally sends complete lines. String streams have no concept of getting new data, i.e., they would fail when having reached the end of the current data. There isn't a concept of blocking.You didn't quite say what you are doing but from the sounds of it try to communicate data between two threads: one reading and possibly blocking until data is available and one filling in more data. You could create a corresponding stream buffer quite easily:
std::streambuf::underflow()
wouldwait()
on a condition variable if there is no data.std::streambuf::overflow()
would set up the buffer appropriately and signal the condition variable. Obviously, there is some need of synchronization necessary. Most of the reading and writing isn't doing any synchronization, though. This effectively means that you will need two separate buffers for input and output and need to copy the data instd::streambuf::underflow()
.