blob: 1122c106b3751d01b64b965ec096ccc6c64c7afd [file] [log] [blame]
// Copyright 2016 The Android Open Source Project
//
// This software is licensed under the terms of the GNU General Public
// License version 2, as published by the Free Software Foundation, and
// may be copied, distributed, and modified under those terms.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
#include "android/protobuf/DelimitedSerialization.h"
#include "google/protobuf/io/coded_stream.h"
#include <stdint.h>
namespace android {
namespace protobuf {
bool writeOneDelimited(const google::protobuf::MessageLite& message,
google::protobuf::io::ZeroCopyOutputStream* out) {
// We create a new coded stream for each message. This is fast.
google::protobuf::io::CodedOutputStream output(out);
// Write the size.
const int size = message.ByteSize();
output.WriteVarint32(size);
uint8_t* buffer = output.GetDirectBufferForNBytesAndAdvance(size);
if (buffer) {
// 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;
}
bool readOneDelimited(google::protobuf::MessageLite* message,
google::protobuf::io::ZeroCopyInputStream* in) {
// We create a new coded stream for each message. This is fast,
// and it makes sure the 64MB total size limit is imposed per-message rather
// than on the whole stream (See the CodedInputStream interface for more
// info on this limit).
google::protobuf::io::CodedInputStream input(in);
// Read the size.
uint32_t size;
if (!input.ReadVarint32(&size)) {
return false;
}
// Tell the stream not to read beyond that size.
const auto 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;
}
} // namespace android
} // namespace protobuf