[asio][serialization] read_until end of archive, which delimiter
Dear all, I want to receive a boost::archive::text_iarchive using the boost::asio::read_until () function. boost::asio::streambuf response; boost::asio::read_until(socket, response, boost::regex("\r\n")); std::istream responseStream(&response); boost::archive::text_iarchive responseArchive (responseStream); responseArchive >> retVal; The data is sent using code linke this: boost::asio::streambuf response; std::ostream commandStream (&response); boost::archive::text_oarchive responseArchive (commandStream); const ReturnValue retVal (42); responseArchive << retVal; boost::asio::write(socket, response); If I use boost::regex("\r\n") or a character that does not occur in the sent archive, read_until throws an eof exception. If I use a delimiter that is contained in the archive, read_until succeeds and the streambuf does contain the entire archive, not only up to the delimiter. What is the correct way to read the entire archive without throwing an exception? Thanks and regards, Christian
Christian Rössel wrote:
Dear all,
I want to receive a boost::archive::text_iarchive using the boost::asio::read_until () function.
boost::asio::streambuf response; boost::asio::read_until(socket, response, boost::regex("\r\n")); std::istream responseStream(&response); boost::archive::text_iarchive responseArchive (responseStream); responseArchive >> retVal;
The data is sent using code linke this:
boost::asio::streambuf response; std::ostream commandStream (&response); boost::archive::text_oarchive responseArchive (commandStream); const ReturnValue retVal (42); responseArchive << retVal; boost::asio::write(socket, response);
If I use boost::regex("\r\n") or a character that does not occur in the sent archive, read_until throws an eof exception. If I use a delimiter that is contained in the archive, read_until succeeds and the streambuf does contain the entire archive, not only up to the delimiter.
What is the correct way to read the entire archive without throwing an exception?
I think the "correct way is to be sure the archive is destroyed before sending. This should append a /n at the end - (at least in 1.34 - this might be a problem with previous versions - or maybe not.) So the above would look like: boost::asio::streambuf response; std::ostream commandStream (&response); { boost::archive::text_oarchive responseArchive (commandStream); const ReturnValue retVal (42); responseArchive << retVal; } // archive closed appends /n at this point. boost::asio::write(socket, response); or you could just append a \n to commandStream
Thanks and regards, Christian
Robert Ramey writes:
Christian Rössel wrote:
What is the correct way to read the entire archive without throwing an exception?
I think the "correct way is to be sure the archive is destroyed before sending. This should append a /n at the end - (at least in 1.34 - this might be a problem with previous versions - or maybe not.)
I was about to ask whether a delimiter was being put in the output or not. It also sounds like the delimiter passed to read_until() should be "\n" and not "\r\n". Is there a guarantee that a "\n" delimiter will not occur in the middle of the serialised output? If it can appear, then using read_until does not sound like the right approach. Cheers, Chris
Robert Ramey schrieb:
Christian R�ssel wrote:
Dear all,
I want to receive a boost::archive::text_iarchive using the boost::asio::read_until () function.
boost::asio::streambuf response; boost::asio::read_until(socket, response, boost::regex("\r\n")); std::istream responseStream(&response); boost::archive::text_iarchive responseArchive (responseStream); responseArchive >> retVal;
The data is sent using code linke this:
boost::asio::streambuf response; std::ostream commandStream (&response); boost::archive::text_oarchive responseArchive (commandStream); const ReturnValue retVal (42); responseArchive << retVal; boost::asio::write(socket, response);
If I use boost::regex("\r\n") or a character that does not occur in the sent archive, read_until throws an eof exception. If I use a delimiter that is contained in the archive, read_until succeeds and the streambuf does contain the entire archive, not only up to the delimiter.
What is the correct way to read the entire archive without throwing an exception?
I think the "correct way is to be sure the archive is destroyed before sending. This should append a /n at the end - (at least in 1.34 - this might be a problem with previous versions - or maybe not.) So the above would look like:
Appending a '\n' by destroying the archive does not work with boost 1.33.1, at least in my case.
boost::asio::streambuf response; std::ostream commandStream (&response); { boost::archive::text_oarchive responseArchive (commandStream); const ReturnValue retVal (42); responseArchive << retVal; } // archive closed appends /n at this point. boost::asio::write(socket, response);
or you could just append a \n to commandStream
This did the job for me. Thanks. But there is still Christophers question:
Is there a guarantee that a "\n" delimiter will not occur in the middle of the serialised output?
Cheers, Christian
But there is still Christophers question:
Is there a guarantee that a "\n" delimiter will not occur in the middle of the serialised output?
No- in fact it does. I appears on text archives and xml archives in order to enhance readability by humans. its treated as white space by input streams so it should be no problem. Robert Ramey
Hi Robert, Robert Ramey wrote:
No- in fact it does. I appears on text archives and xml archives in order to enhance readability by humans.
its treated as white space by input streams so it should be no problem.
That may be true for iostreams and the serialization library, but it's not true with respect to delimiters for use with Boost.Asio's read_until function. Is there any character that is guaranteed not to appear in the output of a text archive? I'm guessing there isn't one, so I would recommend that Christian use the approach of the serialization example included with Boost.Asio, which is to have a fixed size message header containing the length of the message body. Cheers, Chris
participants (3)
-
Christian Rössel
-
Christopher Kohlhoff
-
Robert Ramey