delimited_message_util.cc 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. // Adapted from the patch of kenton@google.com (Kenton Varda)
  2. // See https://github.com/google/protobuf/pull/710 for details.
  3. #include <google/protobuf/util/delimited_message_util.h>
  4. namespace google {
  5. namespace protobuf {
  6. namespace util {
  7. bool SerializeDelimitedToFileDescriptor(const MessageLite& message, int file_descriptor) {
  8. io::FileOutputStream output(file_descriptor);
  9. return SerializeDelimitedToZeroCopyStream(message, &output);
  10. }
  11. bool SerializeDelimitedToOstream(const MessageLite& message, std::ostream* output) {
  12. {
  13. io::OstreamOutputStream zero_copy_output(output);
  14. if (!SerializeDelimitedToZeroCopyStream(message, &zero_copy_output)) return false;
  15. }
  16. return output->good();
  17. }
  18. bool ParseDelimitedFromZeroCopyStream(MessageLite* message, io::ZeroCopyInputStream* input, bool* clean_eof) {
  19. google::protobuf::io::CodedInputStream coded_input(input);
  20. return ParseDelimitedFromCodedStream(message, &coded_input, clean_eof);
  21. }
  22. bool ParseDelimitedFromCodedStream(MessageLite* message, io::CodedInputStream* input, bool* clean_eof) {
  23. if (clean_eof != NULL) *clean_eof = false;
  24. int start = input->CurrentPosition();
  25. // Read the size.
  26. uint32 size;
  27. if (!input->ReadVarint32(&size)) {
  28. if (clean_eof != NULL) *clean_eof = input->CurrentPosition() == start;
  29. return false;
  30. }
  31. // Tell the stream not to read beyond that size.
  32. google::protobuf::io::CodedInputStream::Limit limit = input->PushLimit(size);
  33. // Parse the message.
  34. if (!message->MergeFromCodedStream(input)) return false;
  35. if (!input->ConsumedEntireMessage()) return false;
  36. // Release the limit.
  37. input->PopLimit(limit);
  38. return true;
  39. }
  40. bool SerializeDelimitedToZeroCopyStream(const MessageLite& message, io::ZeroCopyOutputStream* output) {
  41. google::protobuf::io::CodedOutputStream coded_output(output);
  42. return SerializeDelimitedToCodedStream(message, &coded_output);
  43. }
  44. bool SerializeDelimitedToCodedStream(const MessageLite& message, io::CodedOutputStream* output) {
  45. // Write the size.
  46. int size = message.ByteSize();
  47. output->WriteVarint32(size);
  48. // Write the content.
  49. uint8* buffer = output->GetDirectBufferForNBytesAndAdvance(size);
  50. if (buffer != NULL) {
  51. // Optimization: The message fits in one buffer, so use the faster
  52. // direct-to-array serialization path.
  53. message.SerializeWithCachedSizesToArray(buffer);
  54. } else {
  55. // Slightly-slower path when the message is multiple buffers.
  56. message.SerializeWithCachedSizes(output);
  57. if (output->HadError()) return false;
  58. }
  59. return true;
  60. }
  61. } // namespace util
  62. } // namespace protobuf
  63. } // namespace google