Brilliant post!

I had spent a lot of time to solve a problem of getting messages from a 
boost::asio::ip::tcp::iostream without closing it.

assert(messageSize > 0) NOT good for me. I use condition messageSize == 0 
in order to know if boost::asio::ip::tcp::iostream A.K.A TCP/IP connection has 
been closed.

On Saturday, February 5, 2011 5:54:06 AM UTC+2, Gabriel Becedillas wrote:
>
> I had a hard time trying to serialize multiple messages in a 
> std::ostream, and then trying to parse them one at a time from an 
> std::istream, so I'm sharing my code for two reasons: 
> - It may be useful for someone else. 
> - To receive comments from more experienced people. 
>
> template <typename TMessage> 
> bool serialize_delimited(std::ostream& stream, TMessage& message) 
> { 
>         assert(message.IsInitialized()); 
>
>         google::protobuf::io::OstreamOutputStream ostreamWrapper(&stream); 
>         google::protobuf::io::CodedOutputStream 
> codedOStream(&ostreamWrapper); 
>
>         // Write the message size first. 
>         int messageSize = message.ByteSize(); 
>         assert(messageSize > 0); 
>         codedOStream.WriteLittleEndian32(messageSize); 
>
>         // Write the message. 
>         message.SerializeWithCachedSizes(&codedOStream); 
>
>         return stream.good(); 
> } 
>
> template <typename TMessage> 
> bool parse_delimited(std::istream& stream, TMessage& message) 
> { 
>         uint32_t messageSize = 0; 
>
>         // Read the message size. 
>         { 
>                 google::protobuf::io::IstreamInputStream 
> istreamWrapper(&stream, 
> sizeof(uint32_t)); 
>                 google::protobuf::io::CodedInputStream 
> codedIStream(&istreamWrapper); 
>
>                 // Don't consume more than sizeof(uint32_t) from the 
> stream. 
>                 google::protobuf::io::CodedInputStream::Limit oldLimit = 
> codedIStream.PushLimit(sizeof(uint32_t)); 
>                 codedIStream.ReadLittleEndian32(&messageSize); 
>                 codedIStream.PopLimit(oldLimit); 
>                 assert(messageSize > 0); 
>                 assert(istreamWrapper.ByteCount() == sizeof(uint32_t)); 
>         } 
>
>         // Read the message. 
>         { 
>                 google::protobuf::io::IstreamInputStream 
> istreamWrapper(&stream, 
> messageSize); 
>                 google::protobuf::io::CodedInputStream 
> codedIStream(&istreamWrapper); 
>
>                 // Read the message, but don't consume more than 
> messageSize bytes 
> from the stream. 
>                 google::protobuf::io::CodedInputStream::Limit oldLimit = 
> codedIStream.PushLimit(messageSize); 
>                 message.ParseFromCodedStream(&codedIStream); 
>                 codedIStream.PopLimit(oldLimit); 
>                 assert(istreamWrapper.ByteCount() == messageSize); 
>         } 
>
>         return stream.good(); 
> } 
>
> serialize_delimited is pretty simple. I write the message size first, 
> and then the message. 
>
> The tricky part was parsing from a stream. The problem that I was 
> facing was that after CodedInputStream got constructed, my stream was 
> consumed more than I wanted to. The first message was parsed 
> correctly, but for the rest the stream was not in the right position. 
>  The only way I found to avoid that was by setting the block_size 
> parameter while constructing IstreamInputStream instances, and that is 
> why I construct them twice (first to parse the size, then to parse the 
> message). 
>

-- 
You received this message because you are subscribed to the Google Groups 
"Protocol Buffers" group.
To view this discussion on the web visit 
https://groups.google.com/d/msg/protobuf/-/Q1w-LooQPy4J.
To post to this group, send email to protobuf@googlegroups.com.
To unsubscribe from this group, send email to 
protobuf+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/protobuf?hl=en.

Reply via email to