aboutsummaryrefslogtreecommitdiff
path: root/src/google/protobuf/wire_format_lite_inl.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/google/protobuf/wire_format_lite_inl.h')
-rw-r--r--src/google/protobuf/wire_format_lite_inl.h92
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__