aboutsummaryrefslogtreecommitdiff
path: root/src/google/protobuf/wire_format_lite_inl.h
diff options
context:
space:
mode:
authorFeng Xiao <xfxyjwf@gmail.com>2018-08-08 17:00:41 -0700
committerFeng Xiao <xfxyjwf@gmail.com>2018-08-08 17:00:41 -0700
commit6bbe197e9c1b6fc38cbdc45e3bf83fa7ced792a3 (patch)
treee575738adf52d24b883cca5e8928a5ded31caba1 /src/google/protobuf/wire_format_lite_inl.h
parente7746f487cb9cca685ffb1b3d7dccc5554b618a4 (diff)
downloadprotobuf-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.h80
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__