aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/google/protobuf/wire_format_lite.cc
diff options
context:
space:
mode:
authorGravatar kenton@google.com <kenton@google.com@630680e5-0e50-0410-840e-4b1c322b438d>2009-07-29 01:13:20 +0000
committerGravatar kenton@google.com <kenton@google.com@630680e5-0e50-0410-840e-4b1c322b438d>2009-07-29 01:13:20 +0000
commit80b1d62bfcea65c59e2160da71dad84b1bd19cef (patch)
tree5423b830c53174fec83a7ea01ff0877e11c1ddb6 /src/google/protobuf/wire_format_lite.cc
parentd2fd0638c309113ccae3731a58e30419f522269a (diff)
Submit recent changes from internal branch, including "lite mode" for
C++ and Java. See CHANGES.txt for more details.
Diffstat (limited to 'src/google/protobuf/wire_format_lite.cc')
-rw-r--r--src/google/protobuf/wire_format_lite.cc193
1 files changed, 193 insertions, 0 deletions
diff --git a/src/google/protobuf/wire_format_lite.cc b/src/google/protobuf/wire_format_lite.cc
new file mode 100644
index 00000000..bbbf5236
--- /dev/null
+++ b/src/google/protobuf/wire_format_lite.cc
@@ -0,0 +1,193 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <stack>
+#include <string>
+#include <vector>
+
+#include <google/protobuf/wire_format_lite_inl.h>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+#include <google/protobuf/unknown_field_set.h>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+#ifndef _MSC_VER // MSVC doesn't like definitions of inline constants, GCC
+ // requires them.
+const int WireFormatLite::kMessageSetItemStartTag;
+const int WireFormatLite::kMessageSetItemEndTag;
+const int WireFormatLite::kMessageSetTypeIdTag;
+const int WireFormatLite::kMessageSetMessageTag;
+
+#endif
+
+const int WireFormatLite::kMessageSetItemTagsSize =
+ io::CodedOutputStream::VarintSize32(kMessageSetItemStartTag) +
+ io::CodedOutputStream::VarintSize32(kMessageSetItemEndTag) +
+ io::CodedOutputStream::VarintSize32(kMessageSetTypeIdTag) +
+ io::CodedOutputStream::VarintSize32(kMessageSetMessageTag);
+
+const WireFormatLite::CppType
+WireFormatLite::kFieldTypeToCppTypeMap[MAX_FIELD_TYPE + 1] = {
+ static_cast<CppType>(0), // 0 is reserved for errors
+
+ CPPTYPE_DOUBLE, // TYPE_DOUBLE
+ CPPTYPE_FLOAT, // TYPE_FLOAT
+ CPPTYPE_INT64, // TYPE_INT64
+ CPPTYPE_UINT64, // TYPE_UINT64
+ CPPTYPE_INT32, // TYPE_INT32
+ CPPTYPE_UINT64, // TYPE_FIXED64
+ CPPTYPE_UINT32, // TYPE_FIXED32
+ CPPTYPE_BOOL, // TYPE_BOOL
+ CPPTYPE_STRING, // TYPE_STRING
+ CPPTYPE_MESSAGE, // TYPE_GROUP
+ CPPTYPE_MESSAGE, // TYPE_MESSAGE
+ CPPTYPE_STRING, // TYPE_BYTES
+ CPPTYPE_UINT32, // TYPE_UINT32
+ CPPTYPE_ENUM, // TYPE_ENUM
+ CPPTYPE_INT32, // TYPE_SFIXED32
+ CPPTYPE_INT64, // TYPE_SFIXED64
+ CPPTYPE_INT32, // TYPE_SINT32
+ CPPTYPE_INT64, // TYPE_SINT64
+};
+
+const WireFormatLite::WireType
+WireFormatLite::kWireTypeForFieldType[MAX_FIELD_TYPE + 1] = {
+ static_cast<WireFormatLite::WireType>(-1), // invalid
+ WireFormatLite::WIRETYPE_FIXED64, // TYPE_DOUBLE
+ WireFormatLite::WIRETYPE_FIXED32, // TYPE_FLOAT
+ WireFormatLite::WIRETYPE_VARINT, // TYPE_INT64
+ WireFormatLite::WIRETYPE_VARINT, // TYPE_UINT64
+ WireFormatLite::WIRETYPE_VARINT, // TYPE_INT32
+ WireFormatLite::WIRETYPE_FIXED64, // TYPE_FIXED64
+ WireFormatLite::WIRETYPE_FIXED32, // TYPE_FIXED32
+ WireFormatLite::WIRETYPE_VARINT, // TYPE_BOOL
+ WireFormatLite::WIRETYPE_LENGTH_DELIMITED, // TYPE_STRING
+ WireFormatLite::WIRETYPE_START_GROUP, // TYPE_GROUP
+ WireFormatLite::WIRETYPE_LENGTH_DELIMITED, // TYPE_MESSAGE
+ WireFormatLite::WIRETYPE_LENGTH_DELIMITED, // TYPE_BYTES
+ WireFormatLite::WIRETYPE_VARINT, // TYPE_UINT32
+ WireFormatLite::WIRETYPE_VARINT, // TYPE_ENUM
+ WireFormatLite::WIRETYPE_FIXED32, // TYPE_SFIXED32
+ WireFormatLite::WIRETYPE_FIXED64, // TYPE_SFIXED64
+ WireFormatLite::WIRETYPE_VARINT, // TYPE_SINT32
+ WireFormatLite::WIRETYPE_VARINT, // TYPE_SINT64
+};
+
+bool WireFormatLite::SkipField(
+ io::CodedInputStream* input, uint32 tag) {
+ switch (WireFormatLite::GetTagWireType(tag)) {
+ case WireFormatLite::WIRETYPE_VARINT: {
+ uint64 value;
+ if (!input->ReadVarint64(&value)) return false;
+ return true;
+ }
+ case WireFormatLite::WIRETYPE_FIXED64: {
+ uint64 value;
+ if (!input->ReadLittleEndian64(&value)) return false;
+ return true;
+ }
+ case WireFormatLite::WIRETYPE_LENGTH_DELIMITED: {
+ uint32 length;
+ if (!input->ReadVarint32(&length)) return false;
+ if (!input->Skip(length)) return false;
+ return true;
+ }
+ case WireFormatLite::WIRETYPE_START_GROUP: {
+ if (!input->IncrementRecursionDepth()) return false;
+ if (!SkipMessage(input)) return false;
+ input->DecrementRecursionDepth();
+ // Check that the ending tag matched the starting tag.
+ if (!input->LastTagWas(WireFormatLite::MakeTag(
+ WireFormatLite::GetTagFieldNumber(tag),
+ WireFormatLite::WIRETYPE_END_GROUP))) {
+ return false;
+ }
+ return true;
+ }
+ case WireFormatLite::WIRETYPE_END_GROUP: {
+ return false;
+ }
+ case WireFormatLite::WIRETYPE_FIXED32: {
+ uint32 value;
+ if (!input->ReadLittleEndian32(&value)) return false;
+ return true;
+ }
+ default: {
+ return false;
+ }
+ }
+}
+
+bool WireFormatLite::SkipMessage(io::CodedInputStream* input) {
+ while(true) {
+ uint32 tag = input->ReadTag();
+ if (tag == 0) {
+ // End of input. This is a valid place to end, so return true.
+ return true;
+ }
+
+ WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag);
+
+ if (wire_type == WireFormatLite::WIRETYPE_END_GROUP) {
+ // Must be the end of the message.
+ return true;
+ }
+
+ if (!SkipField(input, tag)) return false;
+ }
+}
+
+bool FieldSkipper::SkipField(
+ io::CodedInputStream* input, uint32 tag) {
+ return WireFormatLite::SkipField(input, tag);
+}
+
+bool FieldSkipper::SkipMessage(io::CodedInputStream* input) {
+ return WireFormatLite::SkipMessage(input);
+}
+
+void FieldSkipper::SkipUnknownEnum(
+ int field_number, int value) {
+ // Nothing.
+}
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google