diff options
author | Feng Xiao <xfxyjwf@gmail.com> | 2018-08-08 17:00:41 -0700 |
---|---|---|
committer | Feng Xiao <xfxyjwf@gmail.com> | 2018-08-08 17:00:41 -0700 |
commit | 6bbe197e9c1b6fc38cbdc45e3bf83fa7ced792a3 (patch) | |
tree | e575738adf52d24b883cca5e8928a5ded31caba1 /src/google/protobuf/wire_format_lite_inl.h | |
parent | e7746f487cb9cca685ffb1b3d7dccc5554b618a4 (diff) | |
download | protobuf-6bbe197e9c1b6fc38cbdc45e3bf83fa7ced792a3.tar.gz protobuf-6bbe197e9c1b6fc38cbdc45e3bf83fa7ced792a3.tar.bz2 protobuf-6bbe197e9c1b6fc38cbdc45e3bf83fa7ced792a3.zip |
Down-integrate from google3.
Diffstat (limited to 'src/google/protobuf/wire_format_lite_inl.h')
-rw-r--r-- | src/google/protobuf/wire_format_lite_inl.h | 80 |
1 files changed, 77 insertions, 3 deletions
diff --git a/src/google/protobuf/wire_format_lite_inl.h b/src/google/protobuf/wire_format_lite_inl.h index 6cd2c2fb..2ee5d51d 100644 --- a/src/google/protobuf/wire_format_lite_inl.h +++ b/src/google/protobuf/wire_format_lite_inl.h @@ -40,13 +40,17 @@ #include <string> #include <google/protobuf/stubs/common.h> #include <google/protobuf/stubs/logging.h> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/arenastring.h> #include <google/protobuf/message_lite.h> #include <google/protobuf/repeated_field.h> #include <google/protobuf/wire_format_lite.h> -#include <google/protobuf/io/coded_stream.h> -#include <google/protobuf/arenastring.h> +#ifdef SWIG +#error "You cannot SWIG proto headers" +#endif + namespace google { namespace protobuf { namespace internal { @@ -989,8 +993,78 @@ inline size_t WireFormatLite::LengthDelimitedSize(size_t length) { static_cast<uint32>(length)); } +template <typename MS> +bool ParseMessageSetItemImpl(io::CodedInputStream* input, MS ms) { + // This method parses a group which should contain two fields: + // required int32 type_id = 2; + // required data message = 3; + + uint32 last_type_id = 0; + + // If we see message data before the type_id, we'll append it to this so + // we can parse it later. + string message_data; + + while (true) { + const uint32 tag = input->ReadTagNoLastTag(); + if (tag == 0) return false; + + switch (tag) { + case WireFormatLite::kMessageSetTypeIdTag: { + uint32 type_id; + if (!input->ReadVarint32(&type_id)) return false; + last_type_id = type_id; + + if (!message_data.empty()) { + // We saw some message data before the type_id. Have to parse it + // now. + io::CodedInputStream sub_input( + reinterpret_cast<const uint8*>(message_data.data()), + static_cast<int>(message_data.size())); + if (!ms.ParseField(last_type_id, &sub_input)) { + return false; + } + message_data.clear(); + } + + break; + } + + case WireFormatLite::kMessageSetMessageTag: { + if (last_type_id == 0) { + // We haven't seen a type_id yet. Append this data to message_data. + uint32 length; + if (!input->ReadVarint32(&length)) return false; + if (static_cast<int32>(length) < 0) return false; + uint32 size = static_cast<uint32>(length + + io::CodedOutputStream::VarintSize32(length)); + message_data.resize(size); + auto ptr = reinterpret_cast<uint8*>(&message_data[0]); + ptr = io::CodedOutputStream::WriteVarint32ToArray(length, ptr); + if (!input->ReadRaw(ptr, length)) return false; + } else { + // Already saw type_id, so we can parse this directly. + if (!ms.ParseField(last_type_id, input)) { + return false; + } + } + + break; + } + + case WireFormatLite::kMessageSetItemEndTag: { + return true; + } + + default: { + if (!ms.SkipField(tag, input)) return false; + } + } + } +} + } // namespace internal } // namespace protobuf - } // namespace google + #endif // GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_INL_H__ |