diff options
Diffstat (limited to 'src/google/protobuf/wire_format_lite_inl.h')
-rw-r--r-- | src/google/protobuf/wire_format_lite_inl.h | 92 |
1 files changed, 85 insertions, 7 deletions
diff --git a/src/google/protobuf/wire_format_lite_inl.h b/src/google/protobuf/wire_format_lite_inl.h index 6cd2c2fb..44c4b5ca 100644 --- a/src/google/protobuf/wire_format_lite_inl.h +++ b/src/google/protobuf/wire_format_lite_inl.h @@ -40,13 +40,19 @@ #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 + +#include <google/protobuf/port_def.inc> + namespace google { namespace protobuf { namespace internal { @@ -866,7 +872,7 @@ inline uint8* WireFormatLite::WriteEnumToArray( return WritePrimitiveToArray(field_number, value, WriteEnumToArray, target); } inline uint8* WireFormatLite::WriteStringToArray(int field_number, - const string& value, + const std::string& value, uint8* target) { // String is for UTF-8 text only // WARNING: In wire_format.cc, both strings and bytes are handled by @@ -876,7 +882,7 @@ inline uint8* WireFormatLite::WriteStringToArray(int field_number, return io::CodedOutputStream::WriteStringWithSizeToArray(value, target); } inline uint8* WireFormatLite::WriteBytesToArray(int field_number, - const string& value, + const std::string& value, uint8* target) { target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target); return io::CodedOutputStream::WriteStringWithSizeToArray(value, target); @@ -949,10 +955,10 @@ inline size_t WireFormatLite::EnumSize(int value) { return io::CodedOutputStream::VarintSize32SignExtended(value); } -inline size_t WireFormatLite::StringSize(const string& value) { +inline size_t WireFormatLite::StringSize(const std::string& value) { return LengthDelimitedSize(value.size()); } -inline size_t WireFormatLite::BytesSize(const string& value) { +inline size_t WireFormatLite::BytesSize(const std::string& value) { return LengthDelimitedSize(value.size()); } @@ -989,8 +995,80 @@ 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. + std::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 + +#include <google/protobuf/port_undef.inc> + #endif // GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_INL_H__ |