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