From 2f4fb642a36560e6b586f55cabf0d9caf7b55afe Mon Sep 17 00:00:00 2001 From: Rob Earhart Date: Tue, 14 Jul 2015 17:17:52 -0700 Subject: Install missing headers Install google/protobuf/stubs/status.h, and google/protobuf/stubs/stringpiece.h -- these are required in order to include google/protobuf/util/type_resolver.h. Install google/protobuf/stubs/bytestream.h -- this is required in order to include google/protobuf/util/json_util.h. --- src/Makefile.am | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Makefile.am b/src/Makefile.am index effe2a4a..481aa794 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -71,6 +71,7 @@ nobase_include_HEADERS = \ google/protobuf/stubs/atomicops_internals_tsan.h \ google/protobuf/stubs/atomicops_internals_x86_gcc.h \ google/protobuf/stubs/atomicops_internals_x86_msvc.h \ + google/protobuf/stubs/bytestream.h \ google/protobuf/stubs/casts.h \ google/protobuf/stubs/common.h \ google/protobuf/stubs/fastmem.h \ @@ -79,7 +80,9 @@ nobase_include_HEADERS = \ google/protobuf/stubs/platform_macros.h \ google/protobuf/stubs/shared_ptr.h \ google/protobuf/stubs/singleton.h \ + google/protobuf/stubs/status.h \ google/protobuf/stubs/stl_util.h \ + google/protobuf/stubs/stringpiece.h \ google/protobuf/stubs/template_util.h \ google/protobuf/stubs/type_traits.h \ google/protobuf/any.pb.h \ -- cgit v1.2.3 From b2d2cf8b48c2235e048ea76368e0eda75c7c28d5 Mon Sep 17 00:00:00 2001 From: Jie Luo Date: Wed, 15 Jul 2015 14:31:19 -0700 Subject: ignore UTF-8 BOM if it is in the begining of a proto file --- src/google/protobuf/compiler/parser_unittest.cc | 26 +++++++++++++++++++++++++ src/google/protobuf/io/tokenizer.cc | 9 +++++++++ 2 files changed, 35 insertions(+) diff --git a/src/google/protobuf/compiler/parser_unittest.cc b/src/google/protobuf/compiler/parser_unittest.cc index ddf34bfa..cc6f1efb 100644 --- a/src/google/protobuf/compiler/parser_unittest.cc +++ b/src/google/protobuf/compiler/parser_unittest.cc @@ -229,6 +229,32 @@ TEST_F(ParserTest, WarnIfSyntaxIdentifierOmmitted) { typedef ParserTest ParseMessageTest; +TEST_F(ParseMessageTest, IgnoreBOM) { + char input[] = " message TestMessage {\n" + " required int32 foo = 1;\n" + "}\n"; + // Set UTF-8 BOM. + input[0] = (char)0xEF; + input[1] = (char)0xBB; + input[2] = (char)0xBF; + ExpectParsesTo(input, + "message_type {" + " name: \"TestMessage\"" + " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT32 number:1 }" + "}"); +} + +TEST_F(ParseMessageTest, BOMError) { + char input[] = " message TestMessage {\n" + " required int32 foo = 1;\n" + "}\n"; + input[0] = (char)0xEF; + ExpectHasErrors(input, + "0:1: Proto file starts with 0xEF but not UTF-8 BOM. " + "Only UTF-8 is accepted for proto file.\n" + "0:0: Expected top-level statement (e.g. \"message\").\n"); +} + TEST_F(ParseMessageTest, SimpleMessage) { ExpectParsesTo( "message TestMessage {\n" diff --git a/src/google/protobuf/io/tokenizer.cc b/src/google/protobuf/io/tokenizer.cc index ef2de300..60bd7957 100644 --- a/src/google/protobuf/io/tokenizer.cc +++ b/src/google/protobuf/io/tokenizer.cc @@ -762,6 +762,15 @@ bool Tokenizer::NextWithComments(string* prev_trailing_comments, next_leading_comments); if (current_.type == TYPE_START) { + // Ignore unicode byte order mark(BOM) if it appears at the file + // beginning. Only UTF-8 BOM (0xEF 0xBB 0xBF) is accepted. + if (TryConsume((char)0xEF)) { + if (!TryConsume((char)0xBB) || !TryConsume((char)0xBF)) { + AddError("Proto file starts with 0xEF but not UTF-8 BOM. " + "Only UTF-8 is accepted for proto file."); + return false; + } + } collector.DetachFromPrev(); } else { // A comment appearing on the same line must be attached to the previous -- cgit v1.2.3 From 181c7f26360429b236ab833c746d10d97811931f Mon Sep 17 00:00:00 2001 From: Josh Haberman Date: Wed, 15 Jul 2015 11:05:10 -0700 Subject: Added Ruby to conformance tests. This involved fixing a few important bugs in the Ruby implementation -- mostly cases of mixing upb field types and descriptor types (upb field types do not distinguish between int/sint/fixed/sfixed like descriptor types do). Also added protobuf-specific exceptions so parse errors can be caught specifically. Change-Id: Ib49d3db976900b2c6f3455c8b88af52cfb86e036 --- conformance/Makefile.am | 7 +- conformance/conformance_ruby.rb | 111 +++++ conformance/conformance_test.h | 2 + conformance/conformance_test_runner.cc | 8 +- conformance/failure_list_ruby.txt | 17 + ruby/ext/google/protobuf_c/defs.c | 68 ++- ruby/ext/google/protobuf_c/encode_decode.c | 6 +- ruby/ext/google/protobuf_c/protobuf.c | 6 + ruby/ext/google/protobuf_c/protobuf.h | 3 + ruby/ext/google/protobuf_c/upb.c | 483 +++++++++------------ ruby/ext/google/protobuf_c/upb.h | 460 +++++++++----------- ruby/lib/google/protobuf.rb | 9 + ruby/travis-test.sh | 4 +- .../protobuf/compiler/ruby/ruby_generated_code.rb | 6 +- .../protobuf/compiler/ruby/ruby_generator.cc | 34 +- travis.sh | 29 +- 16 files changed, 678 insertions(+), 575 deletions(-) create mode 100755 conformance/conformance_ruby.rb create mode 100644 conformance/failure_list_ruby.txt diff --git a/conformance/Makefile.am b/conformance/Makefile.am index cccbac9e..97251715 100644 --- a/conformance/Makefile.am +++ b/conformance/Makefile.am @@ -22,7 +22,7 @@ conformance_cpp_CPPFLAGS = -I$(top_srcdir)/src if USE_EXTERNAL_PROTOC protoc_middleman: $(protoc_inputs) - $(PROTOC) -I$(srcdir) --cpp_out=. --java_out=. $^ + $(PROTOC) -I$(srcdir) --cpp_out=. --java_out=. --ruby_out=. $^ touch protoc_middleman else @@ -31,7 +31,7 @@ else # relative to srcdir, which may not be the same as the current directory when # building out-of-tree. protoc_middleman: $(top_srcdir)/src/protoc$(EXEEXT) $(protoc_inputs) - oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. --cpp_out=$$oldpwd --java_out=$$oldpwd $(protoc_inputs) ) + oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. --cpp_out=$$oldpwd --java_out=$$oldpwd --ruby_out=$$oldpwd $(protoc_inputs) ) touch protoc_middleman endif @@ -61,3 +61,6 @@ test_cpp: protoc_middleman conformance-test-runner conformance-cpp test_java: protoc_middleman conformance-test-runner conformance-java ./conformance-test-runner ./conformance-java + +test_ruby: protoc_middleman conformance-test-runner + RUBYLIB=../ruby/lib:. ./conformance-test-runner --failure_list failure_list_ruby.txt ./conformance_ruby.rb diff --git a/conformance/conformance_ruby.rb b/conformance/conformance_ruby.rb new file mode 100755 index 00000000..e7bd4ed5 --- /dev/null +++ b/conformance/conformance_ruby.rb @@ -0,0 +1,111 @@ +#!/usr/bin/env ruby +# +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# https://developers.google.com/protocol-buffers/ +# +# 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. + +require 'conformance' + +test_count = 0; +verbose = false; + +def do_test(request) + test_message = Conformance::TestAllTypes.new + response = Conformance::ConformanceResponse.new + + begin + case request.payload + when :protobuf_payload + begin + test_message = Conformance::TestAllTypes.decode(request.protobuf_payload) + rescue Google::Protobuf::ParseError => err + response.parse_error = err.message.encode("utf-8") + return response + end + + when :json_payload + test_message = Conformance::TestAllTypes.decode_json(request.json_payload) + + when nil + raise "Request didn't have payload."; + end + + case request.requested_output_format + when :UNSPECIFIED + raise "Unspecified output format" + + when :PROTOBUF + response.protobuf_payload = Conformance::TestAllTypes.encode(test_message) + + when :JSON + response.json_payload = Conformance::TestAllTypes.encode_json(test_message) + end + rescue Exception => err + response.runtime_error = err.message.encode("utf-8") + err.backtrace.join("\n") + end + + return response +end + +def do_test_io + length_bytes = STDIN.read(4) + return false if length_bytes.nil? + + length = length_bytes.unpack("V").first + serialized_request = STDIN.read(length) + if serialized_request.nil? or serialized_request.length != length + raise "I/O error" + end + + request = Conformance::ConformanceRequest.decode(serialized_request) + + response = do_test(request) + + serialized_response = Conformance::ConformanceResponse.encode(response) + STDOUT.write([serialized_response.length].pack("V")) + STDOUT.write(serialized_response) + STDOUT.flush + + #if verbose + # fprintf(stderr, "conformance-cpp: request=%s, response=%s\n", + # request.ShortDebugString().c_str(), + # response.ShortDebugString().c_str()); + + #test_count++; + + return true; +end + +while true + if not do_test_io() + STDERR.puts("conformance-cpp: received EOF from test runner " + + "after #{test_count} tests, exiting") + exit 0 + end +end diff --git a/conformance/conformance_test.h b/conformance/conformance_test.h index cadda828..9e6cdaee 100644 --- a/conformance/conformance_test.h +++ b/conformance/conformance_test.h @@ -85,6 +85,8 @@ class ConformanceTestSuite { public: ConformanceTestSuite() : verbose_(false) {} + void SetVerbose(bool verbose) { verbose_ = verbose; } + // Sets the list of tests that are expected to fail when RunSuite() is called. // RunSuite() will fail unless the set of failing tests is exactly the same // as this list. diff --git a/conformance/conformance_test_runner.cc b/conformance/conformance_test_runner.cc index b56e19cf..780e1c44 100644 --- a/conformance/conformance_test_runner.cc +++ b/conformance/conformance_test_runner.cc @@ -219,12 +219,16 @@ void ParseFailureList(const char *filename, vector* failure_list) { int main(int argc, char *argv[]) { int arg = 1; char *program; - vector failure_list; + google::protobuf::ConformanceTestSuite suite; for (int arg = 1; arg < argc; ++arg) { if (strcmp(argv[arg], "--failure_list") == 0) { if (++arg == argc) UsageError(); + vector failure_list; ParseFailureList(argv[arg], &failure_list); + suite.SetFailureList(failure_list); + } else if (strcmp(argv[arg], "--verbose") == 0) { + suite.SetVerbose(true); } else if (argv[arg][0] == '-') { fprintf(stderr, "Unknown option: %s\n", argv[arg]); UsageError(); @@ -238,8 +242,6 @@ int main(int argc, char *argv[]) { } ForkPipeRunner runner(program); - google::protobuf::ConformanceTestSuite suite; - suite.SetFailureList(failure_list); std::string output; bool ok = suite.RunSuite(&runner, &output); diff --git a/conformance/failure_list_ruby.txt b/conformance/failure_list_ruby.txt new file mode 100644 index 00000000..35d1ff91 --- /dev/null +++ b/conformance/failure_list_ruby.txt @@ -0,0 +1,17 @@ +JsonInput.HelloWorld.JsonOutput +JsonInput.HelloWorld.ProtobufOutput +ProtobufInput.PrematureEofBeforeUnknownValue.DOUBLE +ProtobufInput.PrematureEofBeforeUnknownValue.FIXED32 +ProtobufInput.PrematureEofBeforeUnknownValue.FIXED64 +ProtobufInput.PrematureEofBeforeUnknownValue.FLOAT +ProtobufInput.PrematureEofBeforeUnknownValue.SFIXED32 +ProtobufInput.PrematureEofBeforeUnknownValue.SFIXED64 +ProtobufInput.PrematureEofInDelimitedDataForUnknownValue.BYTES +ProtobufInput.PrematureEofInDelimitedDataForUnknownValue.MESSAGE +ProtobufInput.PrematureEofInDelimitedDataForUnknownValue.STRING +ProtobufInput.PrematureEofInsideUnknownValue.DOUBLE +ProtobufInput.PrematureEofInsideUnknownValue.FIXED32 +ProtobufInput.PrematureEofInsideUnknownValue.FIXED64 +ProtobufInput.PrematureEofInsideUnknownValue.FLOAT +ProtobufInput.PrematureEofInsideUnknownValue.SFIXED32 +ProtobufInput.PrematureEofInsideUnknownValue.SFIXED64 diff --git a/ruby/ext/google/protobuf_c/defs.c b/ruby/ext/google/protobuf_c/defs.c index 8f9f33e2..0b2f977f 100644 --- a/ruby/ext/google/protobuf_c/defs.c +++ b/ruby/ext/google/protobuf_c/defs.c @@ -548,7 +548,7 @@ upb_fieldtype_t ruby_to_fieldtype(VALUE type) { #define CONVERT(upb, ruby) \ if (SYM2ID(type) == rb_intern( # ruby )) { \ - return UPB_TYPE_ ## upb; \ + return UPB_TYPE_ ## upb; \ } CONVERT(FLOAT, float); @@ -589,6 +589,68 @@ VALUE fieldtype_to_ruby(upb_fieldtype_t type) { return Qnil; } +upb_descriptortype_t ruby_to_descriptortype(VALUE type) { + if (TYPE(type) != T_SYMBOL) { + rb_raise(rb_eArgError, "Expected symbol for field type."); + } + +#define CONVERT(upb, ruby) \ + if (SYM2ID(type) == rb_intern( # ruby )) { \ + return UPB_DESCRIPTOR_TYPE_ ## upb; \ + } + + CONVERT(FLOAT, float); + CONVERT(DOUBLE, double); + CONVERT(BOOL, bool); + CONVERT(STRING, string); + CONVERT(BYTES, bytes); + CONVERT(MESSAGE, message); + CONVERT(GROUP, group); + CONVERT(ENUM, enum); + CONVERT(INT32, int32); + CONVERT(INT64, int64); + CONVERT(UINT32, uint32); + CONVERT(UINT64, uint64); + CONVERT(SINT32, sint32); + CONVERT(SINT64, sint64); + CONVERT(FIXED32, fixed32); + CONVERT(FIXED64, fixed64); + CONVERT(SFIXED32, sfixed32); + CONVERT(SFIXED64, sfixed64); + +#undef CONVERT + + rb_raise(rb_eArgError, "Unknown field type."); + return 0; +} + +VALUE descriptortype_to_ruby(upb_descriptortype_t type) { + switch (type) { +#define CONVERT(upb, ruby) \ + case UPB_DESCRIPTOR_TYPE_ ## upb : return ID2SYM(rb_intern( # ruby )); + CONVERT(FLOAT, float); + CONVERT(DOUBLE, double); + CONVERT(BOOL, bool); + CONVERT(STRING, string); + CONVERT(BYTES, bytes); + CONVERT(MESSAGE, message); + CONVERT(GROUP, group); + CONVERT(ENUM, enum); + CONVERT(INT32, int32); + CONVERT(INT64, int64); + CONVERT(UINT32, uint32); + CONVERT(UINT64, uint64); + CONVERT(SINT32, sint32); + CONVERT(SINT64, sint64); + CONVERT(FIXED32, fixed32); + CONVERT(FIXED64, fixed64); + CONVERT(SFIXED32, sfixed32); + CONVERT(SFIXED64, sfixed64); +#undef CONVERT + } + return Qnil; +} + /* * call-seq: * FieldDescriptor.type => type @@ -604,7 +666,7 @@ VALUE FieldDescriptor_type(VALUE _self) { if (!upb_fielddef_typeisset(self->fielddef)) { return Qnil; } - return fieldtype_to_ruby(upb_fielddef_type(self->fielddef)); + return descriptortype_to_ruby(upb_fielddef_descriptortype(self->fielddef)); } /* @@ -617,7 +679,7 @@ VALUE FieldDescriptor_type(VALUE _self) { VALUE FieldDescriptor_type_set(VALUE _self, VALUE type) { DEFINE_SELF(FieldDescriptor, self, _self); upb_fielddef* mut_def = check_field_notfrozen(self->fielddef); - upb_fielddef_settype(mut_def, ruby_to_fieldtype(type)); + upb_fielddef_setdescriptortype(mut_def, ruby_to_descriptortype(type)); return Qnil; } diff --git a/ruby/ext/google/protobuf_c/encode_decode.c b/ruby/ext/google/protobuf_c/encode_decode.c index f789f6d4..e488f05b 100644 --- a/ruby/ext/google/protobuf_c/encode_decode.c +++ b/ruby/ext/google/protobuf_c/encode_decode.c @@ -656,8 +656,10 @@ static bool env_error_func(void* ud, const upb_status* status) { // Free the env -- rb_raise will longjmp up the stack past the encode/decode // function so it would not otherwise have been freed. stackenv_uninit(se); - rb_raise(rb_eRuntimeError, se->ruby_error_template, - upb_status_errmsg(status)); + + // TODO(haberman): have a way to verify that this is actually a parse error, + // instead of just throwing "parse error" unconditionally. + rb_raise(cParseError, se->ruby_error_template, upb_status_errmsg(status)); // Never reached: rb_raise() always longjmp()s up the stack, past all of our // code, back to Ruby. return false; diff --git a/ruby/ext/google/protobuf_c/protobuf.c b/ruby/ext/google/protobuf_c/protobuf.c index d0625a10..ca0f7b7c 100644 --- a/ruby/ext/google/protobuf_c/protobuf.c +++ b/ruby/ext/google/protobuf_c/protobuf.c @@ -39,6 +39,9 @@ // Ruby integers) to MessageDef/EnumDef instances (as Ruby values). VALUE upb_def_to_ruby_obj_map; +VALUE cError; +VALUE cParseError; + void add_def_obj(const void* def, VALUE value) { rb_hash_aset(upb_def_to_ruby_obj_map, ULL2NUM((intptr_t)def), value); } @@ -96,6 +99,9 @@ void Init_protobuf_c() { RepeatedField_register(protobuf); Map_register(protobuf); + cError = rb_const_get(protobuf, rb_intern("Error")); + cParseError = rb_const_get(protobuf, rb_intern("ParseError")); + rb_define_singleton_method(protobuf, "deep_copy", Google_Protobuf_deep_copy, 1); diff --git a/ruby/ext/google/protobuf_c/protobuf.h b/ruby/ext/google/protobuf_c/protobuf.h index f8667486..8750c93d 100644 --- a/ruby/ext/google/protobuf_c/protobuf.h +++ b/ruby/ext/google/protobuf_c/protobuf.h @@ -161,6 +161,9 @@ extern VALUE cOneofBuilderContext; extern VALUE cEnumBuilderContext; extern VALUE cBuilder; +extern VALUE cError; +extern VALUE cParseError; + // We forward-declare all of the Ruby method implementations here because we // sometimes call the methods directly across .c files, rather than going // through Ruby's method dispatching (e.g. during message parse). It's cleaner diff --git a/ruby/ext/google/protobuf_c/upb.c b/ruby/ext/google/protobuf_c/upb.c index f99c7a70..8ef8e31d 100644 --- a/ruby/ext/google/protobuf_c/upb.c +++ b/ruby/ext/google/protobuf_c/upb.c @@ -1,11 +1,5 @@ // Amalgamated source file #include "upb.h" -/* - * upb - a minimalist implementation of protocol buffers. - * - * Copyright (c) 2008-2012 Google Inc. See LICENSE for details. - * Author: Josh Haberman - */ #include @@ -1701,12 +1695,6 @@ upb_fielddef *upb_oneof_iter_field(const upb_oneof_iter *iter) { void upb_oneof_iter_setdone(upb_oneof_iter *iter) { upb_inttable_iter_setdone(iter); } -/* - * upb - a minimalist implementation of protocol buffers. - * - * Copyright (c) 2014 Google Inc. See LICENSE for details. - * Author: Josh Haberman - */ #include @@ -1980,14 +1968,9 @@ upb_alloc_func *upb_seededalloc_getallocfunc(upb_seededalloc *a) { return seeded_alloc; } /* - * upb - a minimalist implementation of protocol buffers. - * - * Copyright (c) 2011-2012 Google Inc. See LICENSE for details. - * Author: Josh Haberman - * - * TODO(haberman): it's unclear whether a lot of the consistency checks should - * assert() or return false. - */ +** TODO(haberman): it's unclear whether a lot of the consistency checks should +** assert() or return false. +*/ #include @@ -2668,24 +2651,21 @@ bool upb_byteshandler_setendstr(upb_byteshandler *h, return true; } /* - * upb - a minimalist implementation of protocol buffers. - * - * Copyright (c) 2012 Google Inc. See LICENSE for details. - * Author: Josh Haberman - * - * Our key invariants are: - * 1. reference cycles never span groups - * 2. for ref2(to, from), we increment to's count iff group(from) != group(to) - * - * The previous two are how we avoid leaking cycles. Other important - * invariants are: - * 3. for mutable objects "from" and "to", if there exists a ref2(to, from) - * this implies group(from) == group(to). (In practice, what we implement - * is even stronger; "from" and "to" will share a group if there has *ever* - * been a ref2(to, from), but all that is necessary for correctness is the - * weaker one). - * 4. mutable and immutable objects are never in the same group. - */ +** upb::RefCounted Implementation +** +** Our key invariants are: +** 1. reference cycles never span groups +** 2. for ref2(to, from), we increment to's count iff group(from) != group(to) +** +** The previous two are how we avoid leaking cycles. Other important +** invariants are: +** 3. for mutable objects "from" and "to", if there exists a ref2(to, from) +** this implies group(from) == group(to). (In practice, what we implement +** is even stronger; "from" and "to" will share a group if there has *ever* +** been a ref2(to, from), but all that is necessary for correctness is the +** weaker one). +** 4. mutable and immutable objects are never in the same group. +*/ #include @@ -3514,12 +3494,6 @@ bool upb_refcounted_freeze(upb_refcounted *const*roots, int n, upb_status *s, } return freeze(roots, n, s, maxdepth); } -/* - * upb - a minimalist implementation of protocol buffers. - * - * Copyright (c) 2013 Google Inc. See LICENSE for details. - * Author: Josh Haberman - */ #include @@ -3605,12 +3579,6 @@ const upb_shim_data *upb_shim_getdata(const upb_handlers *h, upb_selector_t s, return (const upb_shim_data*)upb_handlers_gethandlerdata(h, s); } -/* - * upb - a minimalist implementation of protocol buffers. - * - * Copyright (c) 2008-2012 Google Inc. See LICENSE for details. - * Author: Josh Haberman - */ #include @@ -4041,13 +4009,10 @@ const upb_def *upb_symtab_iter_def(const upb_symtab_iter *iter) { return upb_value_getptr(upb_strtable_iter_value(&iter->iter)); } /* - * upb - a minimalist implementation of protocol buffers. - * - * Copyright (c) 2009 Google Inc. See LICENSE for details. - * Author: Josh Haberman - * - * Implementation is heavily inspired by Lua's ltable.c. - */ +** upb_table Implementation +** +** Implementation is heavily inspired by Lua's ltable.c. +*/ #include @@ -4931,12 +4896,6 @@ uint32_t MurmurHash2(const void * key, size_t len, uint32_t seed) { #undef MIX #endif /* UPB_UNALIGNED_READS_OK */ -/* - * upb - a minimalist implementation of protocol buffers. - * - * Copyright (c) 2009-2012 Google Inc. See LICENSE for details. - * Author: Josh Haberman - */ #include #include @@ -5860,17 +5819,12 @@ static upb_inttable reftables[212] = { #endif /* - * upb - a minimalist implementation of protocol buffers. - * - * Copyright (c) 2008-2009 Google Inc. See LICENSE for details. - * Author: Josh Haberman - * - * XXX: The routines in this file that consume a string do not currently - * support having the string span buffers. In the future, as upb_sink and - * its buffering/sharing functionality evolve there should be an easy and - * idiomatic way of correctly handling this case. For now, we accept this - * limitation since we currently only parse descriptors from single strings. - */ +** XXX: The routines in this file that consume a string do not currently +** support having the string span buffers. In the future, as upb_sink and +** its buffering/sharing functionality evolve there should be an easy and +** idiomatic way of correctly handling this case. For now, we accept this +** limitation since we currently only parse descriptors from single strings. +*/ #include @@ -6518,21 +6472,18 @@ const upb_handlers *upb_descreader_newhandlers(const void *owner) { return h; } /* - * upb - a minimalist implementation of protocol buffers. - * - * Copyright (c) 2013 Google Inc. See LICENSE for details. - * Author: Josh Haberman - * - * Code to compile a upb::Handlers into bytecode for decoding a protobuf - * according to that specific schema and destination handlers. - * - * Compiling to bytecode is always the first step. If we are using the - * interpreted decoder we leave it as bytecode and interpret that. If we are - * using a JIT decoder we use a code generator to turn the bytecode into native - * code, LLVM IR, etc. - * - * Bytecode definition is in decoder.int.h. - */ +** protobuf decoder bytecode compiler +** +** Code to compile a upb::Handlers into bytecode for decoding a protobuf +** according to that specific schema and destination handlers. +** +** Compiling to bytecode is always the first step. If we are using the +** interpreted decoder we leave it as bytecode and interpret that. If we are +** using a JIT decoder we use a code generator to turn the bytecode into native +** code, LLVM IR, etc. +** +** Bytecode definition is in decoder.int.h. +*/ #include @@ -7502,24 +7453,19 @@ void upb_pbdecodermethodopts_setlazy(upb_pbdecodermethodopts *opts, bool lazy) { opts->lazy = lazy; } /* - * upb - a minimalist implementation of protocol buffers. - * - * Copyright (c) 2008-2013 Google Inc. See LICENSE for details. - * Author: Josh Haberman - * - * This file implements a VM for the interpreted (bytecode) decoder. - * - * Bytecode must previously have been generated using the bytecode compiler in - * compile_decoder.c. This decoder then walks through the bytecode op-by-op to - * parse the input. - * - * Decoding is fully resumable; we just keep a pointer to the current bytecode - * instruction and resume from there. A fair amount of the logic here is to - * handle the fact that values can span buffer seams and we have to be able to - * be capable of suspending/resuming from any byte in the stream. This - * sometimes requires keeping a few trailing bytes from the last buffer around - * in the "residual" buffer. - */ +** upb::Decoder (Bytecode Decoder VM) +** +** Bytecode must previously have been generated using the bytecode compiler in +** compile_decoder.c. This decoder then walks through the bytecode op-by-op to +** parse the input. +** +** Decoding is fully resumable; we just keep a pointer to the current bytecode +** instruction and resume from there. A fair amount of the logic here is to +** handle the fact that values can span buffer seams and we have to be able to +** be capable of suspending/resuming from any byte in the stream. This +** sometimes requires keeping a few trailing bytes from the last buffer around +** in the "residual" buffer. +*/ #include #include @@ -8529,63 +8475,60 @@ bool upb_pbdecoder_setmaxnesting(upb_pbdecoder *d, size_t max) { return true; } /* - * upb - a minimalist implementation of protocol buffers. - * - * Copyright (c) 2014 Google Inc. See LICENSE for details. - * Author: Josh Haberman - * - * Since we are implementing pure handlers (ie. without any out-of-band access - * to pre-computed lengths), we have to buffer all submessages before we can - * emit even their first byte. - * - * Not knowing the size of submessages also means we can't write a perfect - * zero-copy implementation, even with buffering. Lengths are stored as - * varints, which means that we don't know how many bytes to reserve for the - * length until we know what the length is. - * - * This leaves us with three main choices: - * - * 1. buffer all submessage data in a temporary buffer, then copy it exactly - * once into the output buffer. - * - * 2. attempt to buffer data directly into the output buffer, estimating how - * many bytes each length will take. When our guesses are wrong, use - * memmove() to grow or shrink the allotted space. - * - * 3. buffer directly into the output buffer, allocating a max length - * ahead-of-time for each submessage length. If we overallocated, we waste - * space, but no memcpy() or memmove() is required. This approach requires - * defining a maximum size for submessages and rejecting submessages that - * exceed that size. - * - * (2) and (3) have the potential to have better performance, but they are more - * complicated and subtle to implement: - * - * (3) requires making an arbitrary choice of the maximum message size; it - * wastes space when submessages are shorter than this and fails - * completely when they are longer. This makes it more finicky and - * requires configuration based on the input. It also makes it impossible - * to perfectly match the output of reference encoders that always use the - * optimal amount of space for each length. - * - * (2) requires guessing the the size upfront, and if multiple lengths are - * guessed wrong the minimum required number of memmove() operations may - * be complicated to compute correctly. Implemented properly, it may have - * a useful amortized or average cost, but more investigation is required - * to determine this and what the optimal algorithm is to achieve it. - * - * (1) makes you always pay for exactly one copy, but its implementation is - * the simplest and its performance is predictable. - * - * So for now, we implement (1) only. If we wish to optimize later, we should - * be able to do it without affecting users. - * - * The strategy is to buffer the segments of data that do *not* depend on - * unknown lengths in one buffer, and keep a separate buffer of segment pointers - * and lengths. When the top-level submessage ends, we can go beginning to end, - * alternating the writing of lengths with memcpy() of the rest of the data. - * At the top level though, no buffering is required. - */ +** upb::Encoder +** +** Since we are implementing pure handlers (ie. without any out-of-band access +** to pre-computed lengths), we have to buffer all submessages before we can +** emit even their first byte. +** +** Not knowing the size of submessages also means we can't write a perfect +** zero-copy implementation, even with buffering. Lengths are stored as +** varints, which means that we don't know how many bytes to reserve for the +** length until we know what the length is. +** +** This leaves us with three main choices: +** +** 1. buffer all submessage data in a temporary buffer, then copy it exactly +** once into the output buffer. +** +** 2. attempt to buffer data directly into the output buffer, estimating how +** many bytes each length will take. When our guesses are wrong, use +** memmove() to grow or shrink the allotted space. +** +** 3. buffer directly into the output buffer, allocating a max length +** ahead-of-time for each submessage length. If we overallocated, we waste +** space, but no memcpy() or memmove() is required. This approach requires +** defining a maximum size for submessages and rejecting submessages that +** exceed that size. +** +** (2) and (3) have the potential to have better performance, but they are more +** complicated and subtle to implement: +** +** (3) requires making an arbitrary choice of the maximum message size; it +** wastes space when submessages are shorter than this and fails +** completely when they are longer. This makes it more finicky and +** requires configuration based on the input. It also makes it impossible +** to perfectly match the output of reference encoders that always use the +** optimal amount of space for each length. +** +** (2) requires guessing the the size upfront, and if multiple lengths are +** guessed wrong the minimum required number of memmove() operations may +** be complicated to compute correctly. Implemented properly, it may have +** a useful amortized or average cost, but more investigation is required +** to determine this and what the optimal algorithm is to achieve it. +** +** (1) makes you always pay for exactly one copy, but its implementation is +** the simplest and its performance is predictable. +** +** So for now, we implement (1) only. If we wish to optimize later, we should +** be able to do it without affecting users. +** +** The strategy is to buffer the segments of data that do *not* depend on +** unknown lengths in one buffer, and keep a separate buffer of segment pointers +** and lengths. When the top-level submessage ends, we can go beginning to end, +** alternating the writing of lengths with memcpy() of the rest of the data. +** At the top level though, no buffering is required. +*/ #include @@ -9095,12 +9038,6 @@ upb_pb_encoder *upb_pb_encoder_create(upb_env *env, const upb_handlers *h, } upb_sink *upb_pb_encoder_input(upb_pb_encoder *e) { return &e->input_; } -/* - * upb - a minimalist implementation of protocol buffers. - * - * Copyright (c) 2010-2012 Google Inc. See LICENSE for details. - * Author: Josh Haberman - */ #include @@ -9189,10 +9126,7 @@ bool upb_load_descriptor_file_into_symtab(upb_symtab *symtab, const char *fname, return success; } /* - * upb - a minimalist implementation of protocol buffers. - * - * Copyright (c) 2009 Google Inc. See LICENSE for details. - * Author: Josh Haberman + * upb::pb::TextPrinter * * OPT: This is not optimized at all. It uses printf() which parses the format * string every time, and it allocates memory for every put. @@ -9529,12 +9463,6 @@ upb_sink *upb_textprinter_input(upb_textprinter *p) { return &p->input_; } void upb_textprinter_setsingleline(upb_textprinter *p, bool single_line) { p->single_line_ = single_line; } -/* - * upb - a minimalist implementation of protocol buffers. - * - * Copyright (c) 2011 Google Inc. See LICENSE for details. - * Author: Josh Haberman - */ /* Index is descriptor type. */ @@ -9662,28 +9590,25 @@ upb_decoderet upb_vdecode_max8_wright(upb_decoderet r) { #line 1 "upb/json/parser.rl" /* - * upb - a minimalist implementation of protocol buffers. - * - * Copyright (c) 2014 Google Inc. See LICENSE for details. - * Author: Josh Haberman - * - * A parser that uses the Ragel State Machine Compiler to generate - * the finite automata. - * - * Ragel only natively handles regular languages, but we can manually - * program it a bit to handle context-free languages like JSON, by using - * the "fcall" and "fret" constructs. - * - * This parser can handle the basics, but needs several things to be fleshed - * out: - * - * - handling of unicode escape sequences (including high surrogate pairs). - * - properly check and report errors for unknown fields, stack overflow, - * improper array nesting (or lack of nesting). - * - handling of base64 sequences with padding characters. - * - handling of push-back (non-success returns from sink functions). - * - handling of keys/escape-sequences/etc that span input buffers. - */ +** upb::json::Parser (upb_json_parser) +** +** A parser that uses the Ragel State Machine Compiler to generate +** the finite automata. +** +** Ragel only natively handles regular languages, but we can manually +** program it a bit to handle context-free languages like JSON, by using +** the "fcall" and "fret" constructs. +** +** This parser can handle the basics, but needs several things to be fleshed +** out: +** +** - handling of unicode escape sequences (including high surrogate pairs). +** - properly check and report errors for unknown fields, stack overflow, +** improper array nesting (or lack of nesting). +** - handling of base64 sequences with padding characters. +** - handling of push-back (non-success returns from sink functions). +** - handling of keys/escape-sequences/etc that span input buffers. +*/ #include #include @@ -9731,7 +9656,7 @@ struct upb_json_parser { upb_jsonparser_frame *top; upb_jsonparser_frame *limit; - upb_status *status; + upb_status status; /* Ragel's internal parsing stack for the parsing state machine. */ int current_state; @@ -9778,7 +9703,8 @@ static upb_selector_t parser_getsel(upb_json_parser *p) { static bool check_stack(upb_json_parser *p) { if ((p->top + 1) == p->limit) { - upb_status_seterrmsg(p->status, "Nesting too deep"); + upb_status_seterrmsg(&p->status, "Nesting too deep"); + upb_env_reporterror(p->env, &p->status); return false; } @@ -9860,9 +9786,10 @@ static bool base64_push(upb_json_parser *p, upb_selector_t sel, const char *ptr, char output[3]; if (limit - ptr < 4) { - upb_status_seterrf(p->status, + upb_status_seterrf(&p->status, "Base64 input for bytes field not a multiple of 4: %s", upb_fielddef_name(p->top->f)); + upb_env_reporterror(p->env, &p->status); return false; } @@ -9886,9 +9813,10 @@ static bool base64_push(upb_json_parser *p, upb_selector_t sel, const char *ptr, otherchar: if (nonbase64(ptr[0]) || nonbase64(ptr[1]) || nonbase64(ptr[2]) || nonbase64(ptr[3]) ) { - upb_status_seterrf(p->status, + upb_status_seterrf(&p->status, "Non-base64 characters in bytes field: %s", upb_fielddef_name(p->top->f)); + upb_env_reporterror(p->env, &p->status); return false; } if (ptr[2] == '=') { uint32_t val; @@ -9926,10 +9854,11 @@ otherchar: } badpadding: - upb_status_seterrf(p->status, + upb_status_seterrf(&p->status, "Incorrect base64 padding for field: %s (%.*s)", upb_fielddef_name(p->top->f), 4, ptr); + upb_env_reporterror(p->env, &p->status); return false; } @@ -9976,7 +9905,8 @@ static bool accumulate_realloc(upb_json_parser *p, size_t need) { mem = upb_env_realloc(p->env, p->accumulate_buf, old_size, new_size); if (!mem) { - upb_status_seterrmsg(p->status, "Out of memory allocating buffer."); + upb_status_seterrmsg(&p->status, "Out of memory allocating buffer."); + upb_env_reporterror(p->env, &p->status); return false; } @@ -9999,7 +9929,8 @@ static bool accumulate_append(upb_json_parser *p, const char *buf, size_t len, } if (!checked_add(p->accumulated_len, len, &need)) { - upb_status_seterrmsg(p->status, "Integer overflow."); + upb_status_seterrmsg(&p->status, "Integer overflow."); + upb_env_reporterror(p->env, &p->status); return false; } @@ -10077,7 +10008,8 @@ static bool multipart_text(upb_json_parser *p, const char *buf, size_t len, switch (p->multipart_state) { case MULTIPART_INACTIVE: upb_status_seterrmsg( - p->status, "Internal error: unexpected state MULTIPART_INACTIVE"); + &p->status, "Internal error: unexpected state MULTIPART_INACTIVE"); + upb_env_reporterror(p->env, &p->status); return false; case MULTIPART_ACCUMULATE: @@ -10336,7 +10268,8 @@ static bool parse_number(upb_json_parser *p) { return true; err: - upb_status_seterrf(p->status, "error parsing number: %s", buf); + upb_status_seterrf(&p->status, "error parsing number: %s", buf); + upb_env_reporterror(p->env, &p->status); multipart_end(p); return false; } @@ -10345,9 +10278,10 @@ static bool parser_putbool(upb_json_parser *p, bool val) { bool ok; if (upb_fielddef_type(p->top->f) != UPB_TYPE_BOOL) { - upb_status_seterrf(p->status, + upb_status_seterrf(&p->status, "Boolean value specified for non-bool field: %s", upb_fielddef_name(p->top->f)); + upb_env_reporterror(p->env, &p->status); return false; } @@ -10398,9 +10332,10 @@ static bool start_stringval(upb_json_parser *p) { multipart_startaccum(p); return true; } else { - upb_status_seterrf(p->status, + upb_status_seterrf(&p->status, "String specified for non-string/non-enum field: %s", upb_fielddef_name(p->top->f)); + upb_env_reporterror(p->env, &p->status); return false; } } @@ -10438,7 +10373,8 @@ static bool end_stringval(upb_json_parser *p) { upb_selector_t sel = parser_getsel(p); upb_sink_putint32(&p->top->sink, sel, int_val); } else { - upb_status_seterrf(p->status, "Enum value unknown: '%.*s'", len, buf); + upb_status_seterrf(&p->status, "Enum value unknown: '%.*s'", len, buf); + upb_env_reporterror(p->env, &p->status); } break; @@ -10446,7 +10382,8 @@ static bool end_stringval(upb_json_parser *p) { default: assert(false); - upb_status_seterrmsg(p->status, "Internal error in JSON decoder"); + upb_status_seterrmsg(&p->status, "Internal error in JSON decoder"); + upb_env_reporterror(p->env, &p->status); ok = false; break; } @@ -10476,7 +10413,8 @@ static bool parse_mapentry_key(upb_json_parser *p) { p->top->f = upb_msgdef_itof(p->top->m, UPB_MAPENTRY_KEY); if (p->top->f == NULL) { - upb_status_seterrmsg(p->status, "mapentry message has no key"); + upb_status_seterrmsg(&p->status, "mapentry message has no key"); + upb_env_reporterror(p->env, &p->status); return false; } switch (upb_fielddef_type(p->top->f)) { @@ -10499,8 +10437,9 @@ static bool parse_mapentry_key(upb_json_parser *p) { return false; } } else { - upb_status_seterrmsg(p->status, + upb_status_seterrmsg(&p->status, "Map bool key not 'true' or 'false'"); + upb_env_reporterror(p->env, &p->status); return false; } multipart_end(p); @@ -10518,7 +10457,8 @@ static bool parse_mapentry_key(upb_json_parser *p) { break; } default: - upb_status_seterrmsg(p->status, "Invalid field type for map key"); + upb_status_seterrmsg(&p->status, "Invalid field type for map key"); + upb_env_reporterror(p->env, &p->status); return false; } @@ -10573,7 +10513,8 @@ static bool handle_mapentry(upb_json_parser *p) { p->top->is_mapentry = true; /* set up to pop frame after value is parsed. */ p->top->mapfield = mapfield; if (p->top->f == NULL) { - upb_status_seterrmsg(p->status, "mapentry message has no value"); + upb_status_seterrmsg(&p->status, "mapentry message has no value"); + upb_env_reporterror(p->env, &p->status); return false; } @@ -10593,7 +10534,8 @@ static bool end_membername(upb_json_parser *p) { if (!f) { /* TODO(haberman): Ignore unknown fields if requested/configured to do * so. */ - upb_status_seterrf(p->status, "No such field: %.*s\n", (int)len, buf); + upb_status_seterrf(&p->status, "No such field: %.*s\n", (int)len, buf); + upb_env_reporterror(p->env, &p->status); return false; } @@ -10669,9 +10611,10 @@ static bool start_subobject(upb_json_parser *p) { return true; } else { - upb_status_seterrf(p->status, + upb_status_seterrf(&p->status, "Object specified for non-message/group field: %s", upb_fielddef_name(p->top->f)); + upb_env_reporterror(p->env, &p->status); return false; } } @@ -10697,9 +10640,10 @@ static bool start_array(upb_json_parser *p) { assert(p->top->f); if (!upb_fielddef_isseq(p->top->f)) { - upb_status_seterrf(p->status, + upb_status_seterrf(&p->status, "Array specified for non-repeated field: %s", upb_fielddef_name(p->top->f)); + upb_env_reporterror(p->env, &p->status); return false; } @@ -10736,7 +10680,11 @@ static void start_object(upb_json_parser *p) { static void end_object(upb_json_parser *p) { if (!p->top->is_map) { upb_status status; + upb_status_clear(&status); upb_sink_endmsg(&p->top->sink, &status); + if (!upb_ok(&status)) { + upb_env_reporterror(p->env, &status); + } } } @@ -10762,11 +10710,11 @@ static void end_object(upb_json_parser *p) { * final state once, when the closing '"' is seen. */ -#line 1198 "upb/json/parser.rl" +#line 1218 "upb/json/parser.rl" -#line 1110 "upb/json/parser.c" +#line 1130 "upb/json/parser.c" static const char _json_actions[] = { 0, 1, 0, 1, 2, 1, 3, 1, 5, 1, 6, 1, 7, 1, 8, 1, @@ -10915,7 +10863,7 @@ static const int json_en_value_machine = 27; static const int json_en_main = 1; -#line 1201 "upb/json/parser.rl" +#line 1221 "upb/json/parser.rl" size_t parse(void *closure, const void *hd, const char *buf, size_t size, const upb_bufhandle *handle) { @@ -10937,7 +10885,7 @@ size_t parse(void *closure, const void *hd, const char *buf, size_t size, capture_resume(parser, buf); -#line 1281 "upb/json/parser.c" +#line 1301 "upb/json/parser.c" { int _klen; unsigned int _trans; @@ -11012,118 +10960,118 @@ _match: switch ( *_acts++ ) { case 0: -#line 1113 "upb/json/parser.rl" +#line 1133 "upb/json/parser.rl" { p--; {cs = stack[--top]; goto _again;} } break; case 1: -#line 1114 "upb/json/parser.rl" +#line 1134 "upb/json/parser.rl" { p--; {stack[top++] = cs; cs = 10; goto _again;} } break; case 2: -#line 1118 "upb/json/parser.rl" +#line 1138 "upb/json/parser.rl" { start_text(parser, p); } break; case 3: -#line 1119 "upb/json/parser.rl" +#line 1139 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_text(parser, p)); } break; case 4: -#line 1125 "upb/json/parser.rl" +#line 1145 "upb/json/parser.rl" { start_hex(parser); } break; case 5: -#line 1126 "upb/json/parser.rl" +#line 1146 "upb/json/parser.rl" { hexdigit(parser, p); } break; case 6: -#line 1127 "upb/json/parser.rl" +#line 1147 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_hex(parser)); } break; case 7: -#line 1133 "upb/json/parser.rl" +#line 1153 "upb/json/parser.rl" { CHECK_RETURN_TOP(escape(parser, p)); } break; case 8: -#line 1139 "upb/json/parser.rl" +#line 1159 "upb/json/parser.rl" { p--; {cs = stack[--top]; goto _again;} } break; case 9: -#line 1142 "upb/json/parser.rl" +#line 1162 "upb/json/parser.rl" { {stack[top++] = cs; cs = 19; goto _again;} } break; case 10: -#line 1144 "upb/json/parser.rl" +#line 1164 "upb/json/parser.rl" { p--; {stack[top++] = cs; cs = 27; goto _again;} } break; case 11: -#line 1149 "upb/json/parser.rl" +#line 1169 "upb/json/parser.rl" { start_member(parser); } break; case 12: -#line 1150 "upb/json/parser.rl" +#line 1170 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_membername(parser)); } break; case 13: -#line 1153 "upb/json/parser.rl" +#line 1173 "upb/json/parser.rl" { end_member(parser); } break; case 14: -#line 1159 "upb/json/parser.rl" +#line 1179 "upb/json/parser.rl" { start_object(parser); } break; case 15: -#line 1162 "upb/json/parser.rl" +#line 1182 "upb/json/parser.rl" { end_object(parser); } break; case 16: -#line 1168 "upb/json/parser.rl" +#line 1188 "upb/json/parser.rl" { CHECK_RETURN_TOP(start_array(parser)); } break; case 17: -#line 1172 "upb/json/parser.rl" +#line 1192 "upb/json/parser.rl" { end_array(parser); } break; case 18: -#line 1177 "upb/json/parser.rl" +#line 1197 "upb/json/parser.rl" { start_number(parser, p); } break; case 19: -#line 1178 "upb/json/parser.rl" +#line 1198 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_number(parser, p)); } break; case 20: -#line 1180 "upb/json/parser.rl" +#line 1200 "upb/json/parser.rl" { CHECK_RETURN_TOP(start_stringval(parser)); } break; case 21: -#line 1181 "upb/json/parser.rl" +#line 1201 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_stringval(parser)); } break; case 22: -#line 1183 "upb/json/parser.rl" +#line 1203 "upb/json/parser.rl" { CHECK_RETURN_TOP(parser_putbool(parser, true)); } break; case 23: -#line 1185 "upb/json/parser.rl" +#line 1205 "upb/json/parser.rl" { CHECK_RETURN_TOP(parser_putbool(parser, false)); } break; case 24: -#line 1187 "upb/json/parser.rl" +#line 1207 "upb/json/parser.rl" { /* null value */ } break; case 25: -#line 1189 "upb/json/parser.rl" +#line 1209 "upb/json/parser.rl" { CHECK_RETURN_TOP(start_subobject(parser)); } break; case 26: -#line 1190 "upb/json/parser.rl" +#line 1210 "upb/json/parser.rl" { end_subobject(parser); } break; case 27: -#line 1195 "upb/json/parser.rl" +#line 1215 "upb/json/parser.rl" { p--; {cs = stack[--top]; goto _again;} } break; -#line 1467 "upb/json/parser.c" +#line 1487 "upb/json/parser.c" } } @@ -11136,10 +11084,11 @@ _again: _out: {} } -#line 1222 "upb/json/parser.rl" +#line 1242 "upb/json/parser.rl" if (p != pe) { - upb_status_seterrf(parser->status, "Parse error at %s\n", p); + upb_status_seterrf(&parser->status, "Parse error at %s\n", p); + upb_env_reporterror(parser->env, &parser->status); } else { capture_suspend(parser, &p); } @@ -11176,19 +11125,20 @@ static void json_parser_reset(upb_json_parser *p) { /* Emit Ragel initialization of the parser. */ -#line 1520 "upb/json/parser.c" +#line 1541 "upb/json/parser.c" { cs = json_start; top = 0; } -#line 1261 "upb/json/parser.rl" +#line 1282 "upb/json/parser.rl" p->current_state = cs; p->parser_top = top; accumulate_clear(p); p->multipart_state = MULTIPART_INACTIVE; p->capture = NULL; p->accumulated = NULL; + upb_status_clear(&p->status); } @@ -11214,8 +11164,8 @@ upb_json_parser *upb_json_parser_create(upb_env *env, upb_sink *output) { upb_sink_reset(&p->top->sink, output->handlers, output->closure); p->top->m = upb_handlers_msgdef(output->handlers); - /* If this fails, uncomment and increase the value in parser.h. - * fprintf(stderr, "%zd\n", upb_env_bytesallocated(env) - size_before); */ + /* If this fails, uncomment and increase the value in parser.h. */ + /* fprintf(stderr, "%zd\n", upb_env_bytesallocated(env) - size_before); */ assert(upb_env_bytesallocated(env) - size_before <= UPB_JSON_PARSER_SIZE); return p; } @@ -11224,14 +11174,9 @@ upb_bytessink *upb_json_parser_input(upb_json_parser *p) { return &p->input_; } /* - * upb - a minimalist implementation of protocol buffers. - * - * Copyright (c) 2014 Google Inc. See LICENSE for details. - * Author: Josh Haberman - * - * This currently uses snprintf() to format primitives, and could be optimized - * further. - */ +** This currently uses snprintf() to format primitives, and could be optimized +** further. +*/ #include diff --git a/ruby/ext/google/protobuf_c/upb.h b/ruby/ext/google/protobuf_c/upb.h index b4dcd558..b31f5c08 100644 --- a/ruby/ext/google/protobuf_c/upb.h +++ b/ruby/ext/google/protobuf_c/upb.h @@ -1,70 +1,62 @@ // Amalgamated source file /* - * upb - a minimalist implementation of protocol buffers. - * - * Copyright (c) 2009-2012 Google Inc. See LICENSE for details. - * Author: Josh Haberman - * - * Defs are upb's internal representation of the constructs that can appear - * in a .proto file: - * - * - upb_msgdef: describes a "message" construct. - * - upb_fielddef: describes a message field. - * - upb_enumdef: describes an enum. - * (TODO: definitions of services). - * - * Like upb_refcounted objects, defs are mutable only until frozen, and are - * only thread-safe once frozen. - * - * This is a mixed C/C++ interface that offers a full API to both languages. - * See the top-level README for more information. - */ +** Defs are upb's internal representation of the constructs that can appear +** in a .proto file: +** +** - upb::MessageDef (upb_msgdef): describes a "message" construct. +** - upb::FieldDef (upb_fielddef): describes a message field. +** - upb::EnumDef (upb_enumdef): describes an enum. +** - upb::OneofDef (upb_oneofdef): describes a oneof. +** - upb::Def (upb_def): base class of all the others. +** +** TODO: definitions of services. +** +** Like upb_refcounted objects, defs are mutable only until frozen, and are +** only thread-safe once frozen. +** +** This is a mixed C/C++ interface that offers a full API to both languages. +** See the top-level README for more information. +*/ #ifndef UPB_DEF_H_ #define UPB_DEF_H_ /* - * upb - a minimalist implementation of protocol buffers. - * - * Copyright (c) 2009-2012 Google Inc. See LICENSE for details. - * Author: Josh Haberman - * - * A refcounting scheme that supports circular refs. It accomplishes this by - * partitioning the set of objects into groups such that no cycle spans groups; - * we can then reference-count the group as a whole and ignore refs within the - * group. When objects are mutable, these groups are computed very - * conservatively; we group any objects that have ever had a link between them. - * When objects are frozen, we compute strongly-connected components which - * allows us to be precise and only group objects that are actually cyclic. - * - * This is a mixed C/C++ interface that offers a full API to both languages. - * See the top-level README for more information. - */ +** upb::RefCounted (upb_refcounted) +** +** A refcounting scheme that supports circular refs. It accomplishes this by +** partitioning the set of objects into groups such that no cycle spans groups; +** we can then reference-count the group as a whole and ignore refs within the +** group. When objects are mutable, these groups are computed very +** conservatively; we group any objects that have ever had a link between them. +** When objects are frozen, we compute strongly-connected components which +** allows us to be precise and only group objects that are actually cyclic. +** +** This is a mixed C/C++ interface that offers a full API to both languages. +** See the top-level README for more information. +*/ #ifndef UPB_REFCOUNTED_H_ #define UPB_REFCOUNTED_H_ /* - * upb - a minimalist implementation of protocol buffers. - * - * Copyright (c) 2009 Google Inc. See LICENSE for details. - * Author: Josh Haberman - * - * This header is INTERNAL-ONLY! Its interfaces are not public or stable! - * This file defines very fast int->upb_value (inttable) and string->upb_value - * (strtable) hash tables. - * - * The table uses chained scatter with Brent's variation (inspired by the Lua - * implementation of hash tables). The hash function for strings is Austin - * Appleby's "MurmurHash." - * - * The inttable uses uintptr_t as its key, which guarantees it can be used to - * store pointers or integers of at least 32 bits (upb isn't really useful on - * systems where sizeof(void*) < 4). - * - * The table must be homogenous (all values of the same type). In debug - * mode, we check this on insert and lookup. - */ +** upb_table +** +** This header is INTERNAL-ONLY! Its interfaces are not public or stable! +** This file defines very fast int->upb_value (inttable) and string->upb_value +** (strtable) hash tables. +** +** The table uses chained scatter with Brent's variation (inspired by the Lua +** implementation of hash tables). The hash function for strings is Austin +** Appleby's "MurmurHash." +** +** The inttable uses uintptr_t as its key, which guarantees it can be used to +** store pointers or integers of at least 32 bits (upb isn't really useful on +** systems where sizeof(void*) < 4). +** +** The table must be homogenous (all values of the same type). In debug +** mode, we check this on insert and lookup. +*/ #ifndef UPB_TABLE_H_ #define UPB_TABLE_H_ @@ -73,16 +65,11 @@ #include #include /* - * upb - a minimalist implementation of protocol buffers. - * - * Copyright (c) 2009 Google Inc. See LICENSE for details. - * Author: Josh Haberman - * - * This file contains shared definitions that are widely used across upb. - * - * This is a mixed C/C++ interface that offers a full API to both languages. - * See the top-level README for more information. - */ +** This file contains shared definitions that are widely used across upb. +** +** This is a mixed C/C++ interface that offers a full API to both languages. +** See the top-level README for more information. +*/ #ifndef UPB_H_ #define UPB_H_ @@ -3006,25 +2993,20 @@ inline bool OneofDef::const_iterator::operator!=( #endif /* UPB_DEF_H_ */ /* - * upb - a minimalist implementation of protocol buffers. - * - * Copyright (c) 2015 Google Inc. See LICENSE for details. - * Author: Josh Haberman - * - * This file contains definitions of structs that should be considered private - * and NOT stable across versions of upb. - * - * The only reason they are declared here and not in .c files is to allow upb - * and the application (if desired) to embed statically-initialized instances - * of structures like defs. - * - * If you include this file, all guarantees of ABI compatibility go out the - * window! Any code that includes this file needs to recompile against the - * exact same version of upb that they are linking against. - * - * You also need to recompile if you change the value of the UPB_DEBUG_REFS - * flag. - */ +** This file contains definitions of structs that should be considered private +** and NOT stable across versions of upb. +** +** The only reason they are declared here and not in .c files is to allow upb +** and the application (if desired) to embed statically-initialized instances +** of structures like defs. +** +** If you include this file, all guarantees of ABI compatibility go out the +** window! Any code that includes this file needs to recompile against the +** exact same version of upb that they are linking against. +** +** You also need to recompile if you change the value of the UPB_DEBUG_REFS +** flag. +*/ #ifndef UPB_STATICINIT_H_ @@ -3181,25 +3163,22 @@ struct upb_symtab { #endif /* UPB_STATICINIT_H_ */ /* - * upb - a minimalist implementation of protocol buffers. - * - * Copyright (c) 2010-2012 Google Inc. See LICENSE for details. - * Author: Josh Haberman - * - * A upb_handlers is like a virtual table for a upb_msgdef. Each field of the - * message can have associated functions that will be called when we are - * parsing or visiting a stream of data. This is similar to how handlers work - * in SAX (the Simple API for XML). - * - * The handlers have no idea where the data is coming from, so a single set of - * handlers could be used with two completely different data sources (for - * example, a parser and a visitor over in-memory objects). This decoupling is - * the most important feature of upb, because it allows parsers and serializers - * to be highly reusable. - * - * This is a mixed C/C++ interface that offers a full API to both languages. - * See the top-level README for more information. - */ +** upb::Handlers (upb_handlers) +** +** A upb_handlers is like a virtual table for a upb_msgdef. Each field of the +** message can have associated functions that will be called when we are +** parsing or visiting a stream of data. This is similar to how handlers work +** in SAX (the Simple API for XML). +** +** The handlers have no idea where the data is coming from, so a single set of +** handlers could be used with two completely different data sources (for +** example, a parser and a visitor over in-memory objects). This decoupling is +** the most important feature of upb, because it allows parsers and serializers +** to be highly reusable. +** +** This is a mixed C/C++ interface that offers a full API to both languages. +** See the top-level README for more information. +*/ #ifndef UPB_HANDLERS_H #define UPB_HANDLERS_H @@ -3980,14 +3959,9 @@ uint32_t upb_handlers_selectorcount(const upb_fielddef *f); UPB_END_EXTERN_C /* - * upb - a minimalist implementation of protocol buffers. - * - * Copyright (c) 2011-2012 Google Inc. See LICENSE for details. - * Author: Josh Haberman - * - * Inline definitions for handlers.h, which are particularly long and a bit - * tricky. - */ +** Inline definitions for handlers.h, which are particularly long and a bit +** tricky. +*/ #ifndef UPB_HANDLERS_INL_H_ #define UPB_HANDLERS_INL_H_ @@ -5128,21 +5102,18 @@ inline BytesHandler::~BytesHandler() {} #endif /* UPB_HANDLERS_H */ /* - * upb - a minimalist implementation of protocol buffers. - * - * Copyright (c) 2014 Google Inc. See LICENSE for details. - * Author: Josh Haberman - * - * A upb::Environment provides a means for injecting malloc and an - * error-reporting callback into encoders/decoders. This allows them to be - * independent of nearly all assumptions about their actual environment. - * - * It is also a container for allocating the encoders/decoders themselves that - * insulates clients from knowing their actual size. This provides ABI - * compatibility even if the size of the objects change. And this allows the - * structure definitions to be in the .c files instead of the .h files, making - * the .h files smaller and more readable. - */ +** upb::Environment (upb_env) +** +** A upb::Environment provides a means for injecting malloc and an +** error-reporting callback into encoders/decoders. This allows them to be +** independent of nearly all assumptions about their actual environment. +** +** It is also a container for allocating the encoders/decoders themselves that +** insulates clients from knowing their actual size. This provides ABI +** compatibility even if the size of the objects change. And this allows the +** structure definitions to be in the .c files instead of the .h files, making +** the .h files smaller and more readable. +*/ #ifndef UPB_ENV_H_ @@ -5392,23 +5363,21 @@ inline upb_alloc_func *SeededAllocator::GetAllocationFunction() { #endif /* UPB_ENV_H_ */ /* - * upb - a minimalist implementation of protocol buffers. - * - * Copyright (c) 2010-2012 Google Inc. See LICENSE for details. - * Author: Josh Haberman - * - * A upb_sink is an object that binds a upb_handlers object to some runtime - * state. It is the object that can actually receive data via the upb_handlers - * interface. - * - * Unlike upb_def and upb_handlers, upb_sink is never frozen, immutable, or - * thread-safe. You can create as many of them as you want, but each one may - * only be used in a single thread at a time. - * - * If we compare with class-based OOP, a you can think of a upb_def as an - * abstract base class, a upb_handlers as a concrete derived class, and a - * upb_sink as an object (class instance). - */ +** upb::Sink (upb_sink) +** upb::BytesSink (upb_bytessink) +** +** A upb_sink is an object that binds a upb_handlers object to some runtime +** state. It is the object that can actually receive data via the upb_handlers +** interface. +** +** Unlike upb_def and upb_handlers, upb_sink is never frozen, immutable, or +** thread-safe. You can create as many of them as you want, but each one may +** only be used in a single thread at a time. +** +** If we compare with class-based OOP, a you can think of a upb_def as an +** abstract base class, a upb_handlers as a concrete derived class, and a +** upb_sink as an object (class instance). +*/ #ifndef UPB_SINK_H #define UPB_SINK_H @@ -5921,21 +5890,16 @@ inline bool BufferSource::PutBuffer(const char *buf, size_t len, #endif /* - * upb - a minimalist implementation of protocol buffers. - * - * Copyright (c) 2013 Google Inc. See LICENSE for details. - * Author: Josh Haberman - * - * For handlers that do very tiny, very simple operations, the function call - * overhead of calling a handler can be significant. This file allows the - * user to define handlers that do something very simple like store the value - * to memory and/or set a hasbit. JIT compilers can then special-case these - * handlers and emit specialized code for them instead of actually calling the - * handler. - * - * The functionality is very simple/limited right now but may expand to be able - * to call another function. - */ +** For handlers that do very tiny, very simple operations, the function call +** overhead of calling a handler can be significant. This file allows the +** user to define handlers that do something very simple like store the value +** to memory and/or set a hasbit. JIT compilers can then special-case these +** handlers and emit specialized code for them instead of actually calling the +** handler. +** +** The functionality is very simple/limited right now but may expand to be able +** to call another function. +*/ #ifndef UPB_SHIM_H #define UPB_SHIM_H @@ -5994,19 +5958,16 @@ inline const Shim::Data* Shim::GetData(const Handlers* h, Handlers::Selector s, #endif /* UPB_SHIM_H */ /* - * upb - a minimalist implementation of protocol buffers. - * - * Copyright (c) 2009-2012 Google Inc. See LICENSE for details. - * Author: Josh Haberman - * - * A symtab (symbol table) stores a name->def map of upb_defs. Clients could - * always create such tables themselves, but upb_symtab has logic for resolving - * symbolic references, and in particular, for keeping a whole set of consistent - * defs when replacing some subset of those defs. This logic is nontrivial. - * - * This is a mixed C/C++ interface that offers a full API to both languages. - * See the top-level README for more information. - */ +** upb::SymbolTable (upb_symtab) +** +** A symtab (symbol table) stores a name->def map of upb_defs. Clients could +** always create such tables themselves, but upb_symtab has logic for resolving +** symbolic references, and in particular, for keeping a whole set of consistent +** defs when replacing some subset of those defs. This logic is nontrivial. +** +** This is a mixed C/C++ interface that offers a full API to both languages. +** See the top-level README for more information. +*/ #ifndef UPB_SYMTAB_H_ #define UPB_SYMTAB_H_ @@ -6182,14 +6143,10 @@ inline bool SymbolTable::Add( #endif /* UPB_SYMTAB_H_ */ /* - * upb - a minimalist implementation of protocol buffers. - * - * Copyright (c) 2011 Google Inc. See LICENSE for details. - * Author: Josh Haberman - * - * upb::descriptor::Reader provides a way of building upb::Defs from - * data in descriptor.proto format. - */ +** upb::descriptor::Reader (upb_descreader) +** +** Provides a way of building upb::Defs from data in descriptor.proto format. +*/ #ifndef UPB_DESCRIPTOR_H #define UPB_DESCRIPTOR_H @@ -7067,34 +7024,26 @@ inline upb::reffed_ptr name_part() { RETURN_REFFED(upb::Fie #endif /* GOOGLE_PROTOBUF_DESCRIPTOR_UPB_H_ */ /* - * upb - a minimalist implementation of protocol buffers. - * - * Copyright (c) 2009-2014 Google Inc. See LICENSE for details. - * Author: Josh Haberman - * - * Internal-only definitions for the decoder. - */ +** Internal-only definitions for the decoder. +*/ #ifndef UPB_DECODER_INT_H_ #define UPB_DECODER_INT_H_ #include /* - * upb - a minimalist implementation of protocol buffers. - * - * Copyright (c) 2009-2014 Google Inc. See LICENSE for details. - * Author: Josh Haberman - * - * upb::pb::Decoder implements a high performance, streaming, resumable decoder - * for the binary protobuf format. - * - * This interface works the same regardless of what decoder backend is being - * used. A client of this class does not need to know whether decoding is using - * a JITted decoder (DynASM, LLVM, etc) or an interpreted decoder. By default, - * it will always use the fastest available decoder. However, you can call - * set_allow_jit(false) to disable any JIT decoder that might be available. - * This is primarily useful for testing purposes. - */ +** upb::pb::Decoder +** +** A high performance, streaming, resumable decoder for the binary protobuf +** format. +** +** This interface works the same regardless of what decoder backend is being +** used. A client of this class does not need to know whether decoding is using +** a JITted decoder (DynASM, LLVM, etc) or an interpreted decoder. By default, +** it will always use the fastest available decoder. However, you can call +** set_allow_jit(false) to disable any JIT decoder that might be available. +** This is primarily useful for testing purposes. +*/ #ifndef UPB_DECODER_H_ #define UPB_DECODER_H_ @@ -7702,14 +7651,9 @@ UPB_INLINE void upb_pbdecoder_unpackdispatch(uint64_t dispatch, uint64_t *ofs, #endif /* UPB_DECODER_INT_H_ */ /* - * upb - a minimalist implementation of protocol buffers. - * - * Copyright (c) 2011 Google Inc. See LICENSE for details. - * Author: Josh Haberman - * - * A number of routines for varint manipulation (we keep them all around to - * have multiple approaches available for benchmarking). - */ +** A number of routines for varint manipulation (we keep them all around to +** have multiple approaches available for benchmarking). +*/ #ifndef UPB_VARINT_DECODER_H_ #define UPB_VARINT_DECODER_H_ @@ -7873,18 +7817,15 @@ UPB_INLINE uint64_t upb_vencode32(uint32_t val) { #endif /* UPB_VARINT_DECODER_H_ */ /* - * upb - a minimalist implementation of protocol buffers. - * - * Copyright (c) 2009-2010 Google Inc. See LICENSE for details. - * Author: Josh Haberman - * - * Implements a set of upb_handlers that write protobuf data to the binary wire - * format. - * - * This encoder implementation does not have any access to any out-of-band or - * precomputed lengths for submessages, so it must buffer submessages internally - * before it can emit the first byte. - */ +** upb::pb::Encoder (upb_pb_encoder) +** +** Implements a set of upb_handlers that write protobuf data to the binary wire +** format. +** +** This encoder implementation does not have any access to any out-of-band or +** precomputed lengths for submessages, so it must buffer submessages internally +** before it can emit the first byte. +*/ #ifndef UPB_ENCODER_H_ #define UPB_ENCODER_H_ @@ -7966,29 +7907,24 @@ inline reffed_ptr Encoder::NewHandlers( #endif /* UPB_ENCODER_H_ */ /* - * upb - a minimalist implementation of protocol buffers. - * - * Copyright (c) 2011-2012 Google Inc. See LICENSE for details. - * Author: Josh Haberman - * - * upb's core components like upb_decoder and upb_msg are carefully designed to - * avoid depending on each other for maximum orthogonality. In other words, - * you can use a upb_decoder to decode into *any* kind of structure; upb_msg is - * just one such structure. A upb_msg can be serialized/deserialized into any - * format, protobuf binary format is just one such format. - * - * However, for convenience we provide functions here for doing common - * operations like deserializing protobuf binary format into a upb_msg. The - * compromise is that this file drags in almost all of upb as a dependency, - * which could be undesirable if you're trying to use a trimmed-down build of - * upb. - * - * While these routines are convenient, they do not reuse any encoding/decoding - * state. For example, if a decoder is JIT-based, it will be re-JITted every - * time these functions are called. For this reason, if you are parsing lots - * of data and efficiency is an issue, these may not be the best functions to - * use (though they are useful for prototyping, before optimizing). - */ +** upb's core components like upb_decoder and upb_msg are carefully designed to +** avoid depending on each other for maximum orthogonality. In other words, +** you can use a upb_decoder to decode into *any* kind of structure; upb_msg is +** just one such structure. A upb_msg can be serialized/deserialized into any +** format, protobuf binary format is just one such format. +** +** However, for convenience we provide functions here for doing common +** operations like deserializing protobuf binary format into a upb_msg. The +** compromise is that this file drags in almost all of upb as a dependency, +** which could be undesirable if you're trying to use a trimmed-down build of +** upb. +** +** While these routines are convenient, they do not reuse any encoding/decoding +** state. For example, if a decoder is JIT-based, it will be re-JITted every +** time these functions are called. For this reason, if you are parsing lots +** of data and efficiency is an issue, these may not be the best functions to +** use (though they are useful for prototyping, before optimizing). +*/ #ifndef UPB_GLUE_H #define UPB_GLUE_H @@ -8047,11 +7983,10 @@ bool LoadDescriptorIntoSymtab(SymbolTable* s, const T& desc, Status* status) { #endif /* UPB_GLUE_H */ /* - * upb - a minimalist implementation of protocol buffers. - * - * Copyright (c) 2009 Google Inc. See LICENSE for details. - * Author: Josh Haberman - */ +** upb::pb::TextPrinter (upb_textprinter) +** +** Handlers for writing to protobuf text format. +*/ #ifndef UPB_TEXT_H_ #define UPB_TEXT_H_ @@ -8127,14 +8062,11 @@ inline reffed_ptr TextPrinter::NewHandlers( #endif /* UPB_TEXT_H_ */ /* - * upb - a minimalist implementation of protocol buffers. - * - * Copyright (c) 2014 Google Inc. See LICENSE for details. - * Author: Josh Haberman - * - * upb::json::Parser can parse JSON according to a specific schema. - * Support for parsing arbitrary JSON (schema-less) will be added later. - */ +** upb::json::Parser (upb_json_parser) +** +** Parses JSON according to a specific schema. +** Support for parsing arbitrary JSON (schema-less) will be added later. +*/ #ifndef UPB_JSON_PARSER_H_ #define UPB_JSON_PARSER_H_ @@ -8156,7 +8088,7 @@ UPB_DECLARE_TYPE(upb::json::Parser, upb_json_parser) * constructed. This hint may be an overestimate for some build configurations. * But if the parser library is upgraded without recompiling the application, * it may be an underestimate. */ -#define UPB_JSON_PARSER_SIZE 3568 +#define UPB_JSON_PARSER_SIZE 3704 #ifdef __cplusplus @@ -8199,14 +8131,10 @@ inline BytesSink* Parser::input() { #endif /* UPB_JSON_PARSER_H_ */ /* - * upb - a minimalist implementation of protocol buffers. - * - * Copyright (c) 2014 Google Inc. See LICENSE for details. - * Author: Josh Haberman - * - * upb::json::Printer allows you to create handlers that emit JSON - * according to a specific protobuf schema. - */ +** upb::json::Printer +** +** Handlers that emit JSON according to a specific protobuf schema. +*/ #ifndef UPB_JSON_TYPED_PRINTER_H_ #define UPB_JSON_TYPED_PRINTER_H_ diff --git a/ruby/lib/google/protobuf.rb b/ruby/lib/google/protobuf.rb index 99b17929..74ea770d 100644 --- a/ruby/lib/google/protobuf.rb +++ b/ruby/lib/google/protobuf.rb @@ -31,6 +31,15 @@ # require mixins before we hook them into the java & c code require 'google/protobuf/message_exts' +# We define these before requiring the platform-specific modules. +# That way the module init can grab references to these. +module Google + module Protobuf + class Error < RuntimeError; end + class ParseError < Error; end + end +end + if RUBY_PLATFORM == "java" require 'json' require 'google/protobuf_java' diff --git a/ruby/travis-test.sh b/ruby/travis-test.sh index a240dd65..4a2536a5 100755 --- a/ruby/travis-test.sh +++ b/ruby/travis-test.sh @@ -9,7 +9,9 @@ test_version() { "rvm install $version && rvm use $version && \ which ruby && \ gem install bundler && bundle && \ - rake test" + rake test && \ + cd ../conformance && \ + make test_ruby" } test_version $1 diff --git a/src/google/protobuf/compiler/ruby/ruby_generated_code.rb b/src/google/protobuf/compiler/ruby/ruby_generated_code.rb index 100d6fa7..49b23fbe 100644 --- a/src/google/protobuf/compiler/ruby/ruby_generated_code.rb +++ b/src/google/protobuf/compiler/ruby/ruby_generated_code.rb @@ -13,7 +13,7 @@ Google::Protobuf::DescriptorPool.generated_pool.build do optional :optional_double, :double, 6 optional :optional_float, :float, 7 optional :optional_string, :string, 8 - optional :optional_bytes, :string, 9 + optional :optional_bytes, :bytes, 9 optional :optional_enum, :enum, 10, "A.B.C.TestEnum" optional :optional_msg, :message, 11, "A.B.C.TestMessage" repeated :repeated_int32, :int32, 21 @@ -24,7 +24,7 @@ Google::Protobuf::DescriptorPool.generated_pool.build do repeated :repeated_double, :double, 26 repeated :repeated_float, :float, 27 repeated :repeated_string, :string, 28 - repeated :repeated_bytes, :string, 29 + repeated :repeated_bytes, :bytes, 29 repeated :repeated_enum, :enum, 30, "A.B.C.TestEnum" repeated :repeated_msg, :message, 31, "A.B.C.TestMessage" map :map_int32_string, :int32, :string, 61 @@ -47,7 +47,7 @@ Google::Protobuf::DescriptorPool.generated_pool.build do optional :oneof_double, :double, 46 optional :oneof_float, :float, 47 optional :oneof_string, :string, 48 - optional :oneof_bytes, :string, 49 + optional :oneof_bytes, :bytes, 49 optional :oneof_enum, :enum, 50, "A.B.C.TestEnum" optional :oneof_msg, :message, 51, "A.B.C.TestMessage" end diff --git a/src/google/protobuf/compiler/ruby/ruby_generator.cc b/src/google/protobuf/compiler/ruby/ruby_generator.cc index a9b6837e..9692f1bf 100644 --- a/src/google/protobuf/compiler/ruby/ruby_generator.cc +++ b/src/google/protobuf/compiler/ruby/ruby_generator.cc @@ -47,7 +47,7 @@ namespace compiler { namespace ruby { // Forward decls. -std::string IntToString(uint32 value); +std::string IntToString(int32 value); std::string StripDotProto(const std::string& proto_file); std::string LabelForField(google::protobuf::FieldDescriptor* field); std::string TypeName(google::protobuf::FieldDescriptor* field); @@ -64,7 +64,7 @@ void GenerateEnumAssignment( const google::protobuf::EnumDescriptor* en, google::protobuf::io::Printer* printer); -std::string IntToString(uint32 value) { +std::string IntToString(int32 value) { std::ostringstream os; os << value; return os.str(); @@ -85,17 +85,25 @@ std::string LabelForField(const google::protobuf::FieldDescriptor* field) { } std::string TypeName(const google::protobuf::FieldDescriptor* field) { - switch (field->cpp_type()) { - case FieldDescriptor::CPPTYPE_INT32: return "int32"; - case FieldDescriptor::CPPTYPE_INT64: return "int64"; - case FieldDescriptor::CPPTYPE_UINT32: return "uint32"; - case FieldDescriptor::CPPTYPE_UINT64: return "uint64"; - case FieldDescriptor::CPPTYPE_DOUBLE: return "double"; - case FieldDescriptor::CPPTYPE_FLOAT: return "float"; - case FieldDescriptor::CPPTYPE_BOOL: return "bool"; - case FieldDescriptor::CPPTYPE_ENUM: return "enum"; - case FieldDescriptor::CPPTYPE_STRING: return "string"; - case FieldDescriptor::CPPTYPE_MESSAGE: return "message"; + switch (field->type()) { + case FieldDescriptor::TYPE_INT32: return "int32"; + case FieldDescriptor::TYPE_INT64: return "int64"; + case FieldDescriptor::TYPE_UINT32: return "uint32"; + case FieldDescriptor::TYPE_UINT64: return "uint64"; + case FieldDescriptor::TYPE_SINT32: return "sint32"; + case FieldDescriptor::TYPE_SINT64: return "sint64"; + case FieldDescriptor::TYPE_FIXED32: return "fixed32"; + case FieldDescriptor::TYPE_FIXED64: return "fixed64"; + case FieldDescriptor::TYPE_SFIXED32: return "sfixed32"; + case FieldDescriptor::TYPE_SFIXED64: return "sfixed64"; + case FieldDescriptor::TYPE_DOUBLE: return "double"; + case FieldDescriptor::TYPE_FLOAT: return "float"; + case FieldDescriptor::TYPE_BOOL: return "bool"; + case FieldDescriptor::TYPE_ENUM: return "enum"; + case FieldDescriptor::TYPE_STRING: return "string"; + case FieldDescriptor::TYPE_BYTES: return "bytes"; + case FieldDescriptor::TYPE_MESSAGE: return "message"; + case FieldDescriptor::TYPE_GROUP: return "group"; default: assert(false); return ""; } } diff --git a/travis.sh b/travis.sh index 4aa67344..9514ec2b 100755 --- a/travis.sh +++ b/travis.sh @@ -8,10 +8,16 @@ # .travis.yml uses matrix.exclude to block the cases where app-get can't be # use to install things. -build_cpp() { +# For when some other test needs the C++ main build, including protoc and +# libprotobuf. +internal_build_cpp() { ./autogen.sh ./configure make -j2 +} + +build_cpp() { + internal_build_cpp make check -j2 cd conformance && make test_cpp && cd .. } @@ -62,18 +68,14 @@ use_java() { build_java() { # Java build needs `protoc`. - ./autogen.sh - ./configure - make -j2 + internal_build_cpp cd java && mvn test && cd .. cd conformance && make test_java && cd .. } build_javanano() { # Java build needs `protoc`. - ./autogen.sh - ./configure - make -j2 + internal_build_cpp cd javanano && mvn test && cd .. } @@ -104,9 +106,7 @@ build_javanano_oracle7() { } build_python() { - ./autogen.sh - ./configure - make -j2 + internal_build_cpp cd python python setup.py build python setup.py test @@ -116,9 +116,7 @@ build_python() { } build_python_cpp() { - ./autogen.sh - ./configure - make -j2 + internal_build_cpp export LD_LIBRARY_PATH=../src/.libs # for Linux export DYLD_LIBRARY_PATH=../src/.libs # for OS X cd python @@ -130,18 +128,23 @@ build_python_cpp() { } build_ruby19() { + internal_build_cpp # For conformance tests. cd ruby && bash travis-test.sh ruby-1.9 && cd .. } build_ruby20() { + internal_build_cpp # For conformance tests. cd ruby && bash travis-test.sh ruby-2.0 && cd .. } build_ruby21() { + internal_build_cpp # For conformance tests. cd ruby && bash travis-test.sh ruby-2.1 && cd .. } build_ruby22() { + internal_build_cpp # For conformance tests. cd ruby && bash travis-test.sh ruby-2.2 && cd .. } build_jruby() { + internal_build_cpp # For conformance tests. cd ruby && bash travis-test.sh jruby && cd .. } -- cgit v1.2.3 From 4e694f7b23c3cdfacf5ba5991e986c93b49997e9 Mon Sep 17 00:00:00 2001 From: Jisi Liu Date: Thu, 16 Jul 2015 16:49:38 -0700 Subject: Split up common.h headers Change-Id: I223783111d743aa5193bf70fa1b9b54c7b4389c3 --- src/google/protobuf/stubs/callback.h | 463 ++++++++++ src/google/protobuf/stubs/common.h | 1412 +------------------------------ src/google/protobuf/stubs/logging.h | 235 +++++ src/google/protobuf/stubs/macros.h | 166 ++++ src/google/protobuf/stubs/mutex.h | 144 ++++ src/google/protobuf/stubs/port.h | 371 ++++++++ src/google/protobuf/stubs/scoped_ptr.h | 236 ++++++ src/google/protobuf/stubs/type_traits.h | 2 +- 8 files changed, 1625 insertions(+), 1404 deletions(-) create mode 100644 src/google/protobuf/stubs/callback.h create mode 100644 src/google/protobuf/stubs/logging.h create mode 100644 src/google/protobuf/stubs/macros.h create mode 100644 src/google/protobuf/stubs/mutex.h create mode 100644 src/google/protobuf/stubs/port.h create mode 100644 src/google/protobuf/stubs/scoped_ptr.h diff --git a/src/google/protobuf/stubs/callback.h b/src/google/protobuf/stubs/callback.h new file mode 100644 index 00000000..c4f9edee --- /dev/null +++ b/src/google/protobuf/stubs/callback.h @@ -0,0 +1,463 @@ +#ifndef GOOGLE_PROTOBUF_STUBS_CALLBACK_H_ +#define GOOGLE_PROTOBUF_STUBS_CALLBACK_H_ + +#include +#include + +// =================================================================== +// emulates google3/base/callback.h + +namespace google { +namespace protobuf { + +// Abstract interface for a callback. When calling an RPC, you must provide +// a Closure to call when the procedure completes. See the Service interface +// in service.h. +// +// To automatically construct a Closure which calls a particular function or +// method with a particular set of parameters, use the NewCallback() function. +// Example: +// void FooDone(const FooResponse* response) { +// ... +// } +// +// void CallFoo() { +// ... +// // When done, call FooDone() and pass it a pointer to the response. +// Closure* callback = NewCallback(&FooDone, response); +// // Make the call. +// service->Foo(controller, request, response, callback); +// } +// +// Example that calls a method: +// class Handler { +// public: +// ... +// +// void FooDone(const FooResponse* response) { +// ... +// } +// +// void CallFoo() { +// ... +// // When done, call FooDone() and pass it a pointer to the response. +// Closure* callback = NewCallback(this, &Handler::FooDone, response); +// // Make the call. +// service->Foo(controller, request, response, callback); +// } +// }; +// +// Currently NewCallback() supports binding zero, one, or two arguments. +// +// Callbacks created with NewCallback() automatically delete themselves when +// executed. They should be used when a callback is to be called exactly +// once (usually the case with RPC callbacks). If a callback may be called +// a different number of times (including zero), create it with +// NewPermanentCallback() instead. You are then responsible for deleting the +// callback (using the "delete" keyword as normal). +// +// Note that NewCallback() is a bit touchy regarding argument types. Generally, +// the values you provide for the parameter bindings must exactly match the +// types accepted by the callback function. For example: +// void Foo(string s); +// NewCallback(&Foo, "foo"); // WON'T WORK: const char* != string +// NewCallback(&Foo, string("foo")); // WORKS +// Also note that the arguments cannot be references: +// void Foo(const string& s); +// string my_str; +// NewCallback(&Foo, my_str); // WON'T WORK: Can't use referecnes. +// However, correctly-typed pointers will work just fine. +class LIBPROTOBUF_EXPORT Closure { + public: + Closure() {} + virtual ~Closure(); + + virtual void Run() = 0; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Closure); +}; + +template +class LIBPROTOBUF_EXPORT ResultCallback1 { + public: + ResultCallback1() {} + virtual ~ResultCallback1() {} + + virtual R Run(A1) = 0; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ResultCallback1); +}; + +template +class LIBPROTOBUF_EXPORT ResultCallback2 { + public: + ResultCallback2() {} + virtual ~ResultCallback2() {} + + virtual R Run(A1,A2) = 0; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ResultCallback2); +}; + +namespace internal { + +class LIBPROTOBUF_EXPORT FunctionClosure0 : public Closure { + public: + typedef void (*FunctionType)(); + + FunctionClosure0(FunctionType function, bool self_deleting) + : function_(function), self_deleting_(self_deleting) {} + ~FunctionClosure0(); + + void Run() { + bool needs_delete = self_deleting_; // read in case callback deletes + function_(); + if (needs_delete) delete this; + } + + private: + FunctionType function_; + bool self_deleting_; +}; + +template +class MethodClosure0 : public Closure { + public: + typedef void (Class::*MethodType)(); + + MethodClosure0(Class* object, MethodType method, bool self_deleting) + : object_(object), method_(method), self_deleting_(self_deleting) {} + ~MethodClosure0() {} + + void Run() { + bool needs_delete = self_deleting_; // read in case callback deletes + (object_->*method_)(); + if (needs_delete) delete this; + } + + private: + Class* object_; + MethodType method_; + bool self_deleting_; +}; + +template +class FunctionClosure1 : public Closure { + public: + typedef void (*FunctionType)(Arg1 arg1); + + FunctionClosure1(FunctionType function, bool self_deleting, + Arg1 arg1) + : function_(function), self_deleting_(self_deleting), + arg1_(arg1) {} + ~FunctionClosure1() {} + + void Run() { + bool needs_delete = self_deleting_; // read in case callback deletes + function_(arg1_); + if (needs_delete) delete this; + } + + private: + FunctionType function_; + bool self_deleting_; + Arg1 arg1_; +}; + +template +class MethodClosure1 : public Closure { + public: + typedef void (Class::*MethodType)(Arg1 arg1); + + MethodClosure1(Class* object, MethodType method, bool self_deleting, + Arg1 arg1) + : object_(object), method_(method), self_deleting_(self_deleting), + arg1_(arg1) {} + ~MethodClosure1() {} + + void Run() { + bool needs_delete = self_deleting_; // read in case callback deletes + (object_->*method_)(arg1_); + if (needs_delete) delete this; + } + + private: + Class* object_; + MethodType method_; + bool self_deleting_; + Arg1 arg1_; +}; + +template +class FunctionClosure2 : public Closure { + public: + typedef void (*FunctionType)(Arg1 arg1, Arg2 arg2); + + FunctionClosure2(FunctionType function, bool self_deleting, + Arg1 arg1, Arg2 arg2) + : function_(function), self_deleting_(self_deleting), + arg1_(arg1), arg2_(arg2) {} + ~FunctionClosure2() {} + + void Run() { + bool needs_delete = self_deleting_; // read in case callback deletes + function_(arg1_, arg2_); + if (needs_delete) delete this; + } + + private: + FunctionType function_; + bool self_deleting_; + Arg1 arg1_; + Arg2 arg2_; +}; + +template +class MethodClosure2 : public Closure { + public: + typedef void (Class::*MethodType)(Arg1 arg1, Arg2 arg2); + + MethodClosure2(Class* object, MethodType method, bool self_deleting, + Arg1 arg1, Arg2 arg2) + : object_(object), method_(method), self_deleting_(self_deleting), + arg1_(arg1), arg2_(arg2) {} + ~MethodClosure2() {} + + void Run() { + bool needs_delete = self_deleting_; // read in case callback deletes + (object_->*method_)(arg1_, arg2_); + if (needs_delete) delete this; + } + + private: + Class* object_; + MethodType method_; + bool self_deleting_; + Arg1 arg1_; + Arg2 arg2_; +}; + +template +class FunctionResultCallback_0_1 : public ResultCallback1 { + public: + typedef R (*FunctionType)(Arg1 arg1); + + FunctionResultCallback_0_1(FunctionType function, bool self_deleting) + : function_(function), self_deleting_(self_deleting) {} + ~FunctionResultCallback_0_1() {} + + R Run(Arg1 a1) { + bool needs_delete = self_deleting_; // read in case callback deletes + R result = function_(a1); + if (needs_delete) delete this; + return result; + } + + private: + FunctionType function_; + bool self_deleting_; +}; + +template +class FunctionResultCallback_1_1 : public ResultCallback1 { + public: + typedef R (*FunctionType)(P1, A1); + + FunctionResultCallback_1_1(FunctionType function, bool self_deleting, + P1 p1) + : function_(function), self_deleting_(self_deleting), p1_(p1) {} + ~FunctionResultCallback_1_1() {} + + R Run(A1 a1) { + bool needs_delete = self_deleting_; // read in case callback deletes + R result = function_(p1_, a1); + if (needs_delete) delete this; + return result; + } + + private: + FunctionType function_; + bool self_deleting_; + P1 p1_; +}; + +template +struct InternalConstRef { + typedef typename remove_reference::type base_type; + typedef const base_type& type; +}; + +template +class MethodResultCallback_5_2 : public ResultCallback2 { + public: + typedef R (T::*MethodType)(P1, P2, P3, P4, P5, A1, A2); + MethodResultCallback_5_2(T* object, MethodType method, bool self_deleting, + P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) + : object_(object), + method_(method), + self_deleting_(self_deleting), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5) {} + ~MethodResultCallback_5_2() {} + + R Run(A1 a1, A2 a2) { + bool needs_delete = self_deleting_; + R result = (object_->*method_)(p1_, p2_, p3_, p4_, p5_, a1, a2); + if (needs_delete) delete this; + return result; + } + + private: + T* object_; + MethodType method_; + bool self_deleting_; + typename remove_reference::type p1_; + typename remove_reference::type p2_; + typename remove_reference::type p3_; + typename remove_reference::type p4_; + typename remove_reference::type p5_; +}; + +} // namespace internal + +// See Closure. +inline Closure* NewCallback(void (*function)()) { + return new internal::FunctionClosure0(function, true); +} + +// See Closure. +inline Closure* NewPermanentCallback(void (*function)()) { + return new internal::FunctionClosure0(function, false); +} + +// See Closure. +template +inline Closure* NewCallback(Class* object, void (Class::*method)()) { + return new internal::MethodClosure0(object, method, true); +} + +// See Closure. +template +inline Closure* NewPermanentCallback(Class* object, void (Class::*method)()) { + return new internal::MethodClosure0(object, method, false); +} + +// See Closure. +template +inline Closure* NewCallback(void (*function)(Arg1), + Arg1 arg1) { + return new internal::FunctionClosure1(function, true, arg1); +} + +// See Closure. +template +inline Closure* NewPermanentCallback(void (*function)(Arg1), + Arg1 arg1) { + return new internal::FunctionClosure1(function, false, arg1); +} + +// See Closure. +template +inline Closure* NewCallback(Class* object, void (Class::*method)(Arg1), + Arg1 arg1) { + return new internal::MethodClosure1(object, method, true, arg1); +} + +// See Closure. +template +inline Closure* NewPermanentCallback(Class* object, void (Class::*method)(Arg1), + Arg1 arg1) { + return new internal::MethodClosure1(object, method, false, arg1); +} + +// See Closure. +template +inline Closure* NewCallback(void (*function)(Arg1, Arg2), + Arg1 arg1, Arg2 arg2) { + return new internal::FunctionClosure2( + function, true, arg1, arg2); +} + +// See Closure. +template +inline Closure* NewPermanentCallback(void (*function)(Arg1, Arg2), + Arg1 arg1, Arg2 arg2) { + return new internal::FunctionClosure2( + function, false, arg1, arg2); +} + +// See Closure. +template +inline Closure* NewCallback(Class* object, void (Class::*method)(Arg1, Arg2), + Arg1 arg1, Arg2 arg2) { + return new internal::MethodClosure2( + object, method, true, arg1, arg2); +} + +// See Closure. +template +inline Closure* NewPermanentCallback( + Class* object, void (Class::*method)(Arg1, Arg2), + Arg1 arg1, Arg2 arg2) { + return new internal::MethodClosure2( + object, method, false, arg1, arg2); +} + +// See ResultCallback1 +template +inline ResultCallback1* NewCallback(R (*function)(A1)) { + return new internal::FunctionResultCallback_0_1(function, true); +} + +// See ResultCallback1 +template +inline ResultCallback1* NewPermanentCallback(R (*function)(A1)) { + return new internal::FunctionResultCallback_0_1(function, false); +} + +// See ResultCallback1 +template +inline ResultCallback1* NewCallback(R (*function)(P1, A1), P1 p1) { + return new internal::FunctionResultCallback_1_1( + function, true, p1); +} + +// See ResultCallback1 +template +inline ResultCallback1* NewPermanentCallback( + R (*function)(P1, A1), P1 p1) { + return new internal::FunctionResultCallback_1_1( + function, false, p1); +} + +// See MethodResultCallback_5_2 +template +inline ResultCallback2* NewPermanentCallback( + T* object, R (T::*function)(P1, P2, P3, P4, P5, A1, A2), + typename internal::InternalConstRef::type p1, + typename internal::InternalConstRef::type p2, + typename internal::InternalConstRef::type p3, + typename internal::InternalConstRef::type p4, + typename internal::InternalConstRef::type p5) { + return new internal::MethodResultCallback_5_2(object, function, false, p1, + p2, p3, p4, p5); +} + +// A function which does nothing. Useful for creating no-op callbacks, e.g.: +// Closure* nothing = NewCallback(&DoNothing); +void LIBPROTOBUF_EXPORT DoNothing(); + + +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_STUBS_CALLBACK_H_ diff --git a/src/google/protobuf/stubs/common.h b/src/google/protobuf/stubs/common.h index 3a081e60..de866e14 100644 --- a/src/google/protobuf/stubs/common.h +++ b/src/google/protobuf/stubs/common.h @@ -35,38 +35,16 @@ #ifndef GOOGLE_PROTOBUF_COMMON_H__ #define GOOGLE_PROTOBUF_COMMON_H__ -#include -#include -#include -#include -#include -#if defined(__osf__) -// Tru64 lacks stdint.h, but has inttypes.h which defines a superset of -// what stdint.h would define. -#include -#elif !defined(_MSC_VER) -#include -#endif -#undef PROTOBUF_LITTLE_ENDIAN -#ifdef _MSC_VER - // Assuming windows is always little-endian. - #if !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST) - #define PROTOBUF_LITTLE_ENDIAN 1 - #endif - #if _MSC_VER >= 1300 - // If MSVC has "/RTCc" set, it will complain about truncating casts at - // runtime. This file contains some intentional truncating casts. - #pragma runtime_checks("c", off) - #endif -#else - #include // __BYTE_ORDER - #if ((defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)) || \ - (defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN)) && \ - !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST) - #define PROTOBUF_LITTLE_ENDIAN 1 - #endif -#endif +#include +#include +#include + +// TODO(liujisi): Remove the following includes after the include clean-up. +#include +#include +#include +#include #ifndef PROTOBUF_USE_EXCEPTIONS #if defined(_MSC_VER) && defined(_CPPUNWIND) @@ -81,9 +59,6 @@ #if PROTOBUF_USE_EXCEPTIONS #include #endif - -#include - #if defined(__APPLE__) #include // for TARGET_OS_IPHONE #endif @@ -109,39 +84,10 @@ inline BOOL GetMessage( } #endif - namespace std {} namespace google { namespace protobuf { - -#undef GOOGLE_DISALLOW_EVIL_CONSTRUCTORS -#define GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TypeName) \ - TypeName(const TypeName&); \ - void operator=(const TypeName&) - -#undef GOOGLE_DISALLOW_IMPLICIT_CONSTRUCTORS -#define GOOGLE_DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \ - TypeName(); \ - TypeName(const TypeName&); \ - void operator=(const TypeName&) - -#if defined(_MSC_VER) && defined(PROTOBUF_USE_DLLS) - #ifdef LIBPROTOBUF_EXPORTS - #define LIBPROTOBUF_EXPORT __declspec(dllexport) - #else - #define LIBPROTOBUF_EXPORT __declspec(dllimport) - #endif - #ifdef LIBPROTOC_EXPORTS - #define LIBPROTOC_EXPORT __declspec(dllexport) - #else - #define LIBPROTOC_EXPORT __declspec(dllimport) - #endif -#else - #define LIBPROTOBUF_EXPORT - #define LIBPROTOC_EXPORT -#endif - namespace internal { // Some of these constants are macros rather than const ints so that they can @@ -187,1238 +133,6 @@ std::string LIBPROTOBUF_EXPORT VersionString(int version); GOOGLE_PROTOBUF_VERSION, GOOGLE_PROTOBUF_MIN_LIBRARY_VERSION, \ __FILE__) -// =================================================================== -// from google3/base/port.h - -typedef unsigned int uint; - -#ifdef _MSC_VER -typedef signed __int8 int8; -typedef __int16 int16; -typedef __int32 int32; -typedef __int64 int64; - -typedef unsigned __int8 uint8; -typedef unsigned __int16 uint16; -typedef unsigned __int32 uint32; -typedef unsigned __int64 uint64; -#else -typedef signed char int8; -typedef short int16; -typedef int int32; -// NOTE: This should be "long long" for consistency with upstream, but -// something is stacked against this particular type for 64bit hashing. -// Switching it causes an obvious missing hash function (with an unobvious -// cause) when building the tests. -typedef int64_t int64; - -typedef unsigned char uint8; -typedef unsigned short uint16; -typedef unsigned int uint32; -// NOTE: This should be "unsigned long long" for consistency with upstream, but -// something is stacked against this particular type for 64bit hashing. -// Switching it causes an obvious missing hash function (with an unobvious -// cause) when building the tests. -typedef uint64_t uint64; -#endif - -// long long macros to be used because gcc and vc++ use different suffixes, -// and different size specifiers in format strings -#undef GOOGLE_LONGLONG -#undef GOOGLE_ULONGLONG -#undef GOOGLE_LL_FORMAT - -#ifdef _MSC_VER -#define GOOGLE_LONGLONG(x) x##I64 -#define GOOGLE_ULONGLONG(x) x##UI64 -#define GOOGLE_LL_FORMAT "I64" // As in printf("%I64d", ...) -#else -#define GOOGLE_LONGLONG(x) x##LL -#define GOOGLE_ULONGLONG(x) x##ULL -#define GOOGLE_LL_FORMAT "ll" // As in "%lld". Note that "q" is poor form also. -#endif - -static const int32 kint32max = 0x7FFFFFFF; -static const int32 kint32min = -kint32max - 1; -static const int64 kint64max = GOOGLE_LONGLONG(0x7FFFFFFFFFFFFFFF); -static const int64 kint64min = -kint64max - 1; -static const uint32 kuint32max = 0xFFFFFFFFu; -static const uint64 kuint64max = GOOGLE_ULONGLONG(0xFFFFFFFFFFFFFFFF); - -// ------------------------------------------------------------------- -// Annotations: Some parts of the code have been annotated in ways that might -// be useful to some compilers or tools, but are not supported universally. -// You can #define these annotations yourself if the default implementation -// is not right for you. - -#ifndef GOOGLE_ATTRIBUTE_ALWAYS_INLINE -#if defined(__GNUC__) && (__GNUC__ > 3 ||(__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) -// For functions we want to force inline. -// Introduced in gcc 3.1. -#define GOOGLE_ATTRIBUTE_ALWAYS_INLINE __attribute__ ((always_inline)) -#else -// Other compilers will have to figure it out for themselves. -#define GOOGLE_ATTRIBUTE_ALWAYS_INLINE -#endif -#endif - -#ifndef GOOGLE_ATTRIBUTE_NOINLINE -#if defined(__GNUC__) && (__GNUC__ > 3 ||(__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) -// For functions we want to force not inline. -// Introduced in gcc 3.1. -#define GOOGLE_ATTRIBUTE_NOINLINE __attribute__ ((noinline)) -#else -// Other compilers will have to figure it out for themselves. -#define GOOGLE_ATTRIBUTE_NOINLINE -#endif -#endif - -#ifndef GOOGLE_ATTRIBUTE_DEPRECATED -#ifdef __GNUC__ -// If the method/variable/type is used anywhere, produce a warning. -#define GOOGLE_ATTRIBUTE_DEPRECATED __attribute__((deprecated)) -#else -#define GOOGLE_ATTRIBUTE_DEPRECATED -#endif -#endif - -#ifndef GOOGLE_PREDICT_TRUE -#ifdef __GNUC__ -// Provided at least since GCC 3.0. -#define GOOGLE_PREDICT_TRUE(x) (__builtin_expect(!!(x), 1)) -#else -#define GOOGLE_PREDICT_TRUE -#endif -#endif - -#ifndef GOOGLE_PREDICT_FALSE -#ifdef __GNUC__ -// Provided at least since GCC 3.0. -#define GOOGLE_PREDICT_FALSE(x) (__builtin_expect(x, 0)) -#else -#define GOOGLE_PREDICT_FALSE -#endif -#endif - -// Delimits a block of code which may write to memory which is simultaneously -// written by other threads, but which has been determined to be thread-safe -// (e.g. because it is an idempotent write). -#ifndef GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN -#define GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN() -#endif -#ifndef GOOGLE_SAFE_CONCURRENT_WRITES_END -#define GOOGLE_SAFE_CONCURRENT_WRITES_END() -#endif - -#define GOOGLE_GUARDED_BY(x) -#define GOOGLE_FALLTHROUGH_INTENDED -#define GOOGLE_ATTRIBUTE_COLD - -// x86 and x86-64 can perform unaligned loads/stores directly. -#if defined(_M_X64) || defined(__x86_64__) || \ - defined(_M_IX86) || defined(__i386__) - -#define GOOGLE_UNALIGNED_LOAD16(_p) (*reinterpret_cast(_p)) -#define GOOGLE_UNALIGNED_LOAD32(_p) (*reinterpret_cast(_p)) -#define GOOGLE_UNALIGNED_LOAD64(_p) (*reinterpret_cast(_p)) - -#define GOOGLE_UNALIGNED_STORE16(_p, _val) (*reinterpret_cast(_p) = (_val)) -#define GOOGLE_UNALIGNED_STORE32(_p, _val) (*reinterpret_cast(_p) = (_val)) -#define GOOGLE_UNALIGNED_STORE64(_p, _val) (*reinterpret_cast(_p) = (_val)) - -#else -inline uint16 GOOGLE_UNALIGNED_LOAD16(const void *p) { - uint16 t; - memcpy(&t, p, sizeof t); - return t; -} - -inline uint32 GOOGLE_UNALIGNED_LOAD32(const void *p) { - uint32 t; - memcpy(&t, p, sizeof t); - return t; -} - -inline uint64 GOOGLE_UNALIGNED_LOAD64(const void *p) { - uint64 t; - memcpy(&t, p, sizeof t); - return t; -} - -inline void GOOGLE_UNALIGNED_STORE16(void *p, uint16 v) { - memcpy(p, &v, sizeof v); -} - -inline void GOOGLE_UNALIGNED_STORE32(void *p, uint32 v) { - memcpy(p, &v, sizeof v); -} - -inline void GOOGLE_UNALIGNED_STORE64(void *p, uint64 v) { - memcpy(p, &v, sizeof v); -} -#endif - -#if defined(_MSC_VER) -#define GOOGLE_THREAD_LOCAL __declspec(thread) -#else -#define GOOGLE_THREAD_LOCAL __thread -#endif - -// =================================================================== -// from google3/base/basictypes.h - -// The GOOGLE_ARRAYSIZE(arr) macro returns the # of elements in an array arr. -// The expression is a compile-time constant, and therefore can be -// used in defining new arrays, for example. -// -// GOOGLE_ARRAYSIZE catches a few type errors. If you see a compiler error -// -// "warning: division by zero in ..." -// -// when using GOOGLE_ARRAYSIZE, you are (wrongfully) giving it a pointer. -// You should only use GOOGLE_ARRAYSIZE on statically allocated arrays. -// -// The following comments are on the implementation details, and can -// be ignored by the users. -// -// ARRAYSIZE(arr) works by inspecting sizeof(arr) (the # of bytes in -// the array) and sizeof(*(arr)) (the # of bytes in one array -// element). If the former is divisible by the latter, perhaps arr is -// indeed an array, in which case the division result is the # of -// elements in the array. Otherwise, arr cannot possibly be an array, -// and we generate a compiler error to prevent the code from -// compiling. -// -// Since the size of bool is implementation-defined, we need to cast -// !(sizeof(a) & sizeof(*(a))) to size_t in order to ensure the final -// result has type size_t. -// -// This macro is not perfect as it wrongfully accepts certain -// pointers, namely where the pointer size is divisible by the pointee -// size. Since all our code has to go through a 32-bit compiler, -// where a pointer is 4 bytes, this means all pointers to a type whose -// size is 3 or greater than 4 will be (righteously) rejected. -// -// Kudos to Jorg Brown for this simple and elegant implementation. - -#undef GOOGLE_ARRAYSIZE -#define GOOGLE_ARRAYSIZE(a) \ - ((sizeof(a) / sizeof(*(a))) / \ - static_cast(!(sizeof(a) % sizeof(*(a))))) - -// The COMPILE_ASSERT macro can be used to verify that a compile time -// expression is true. For example, you could use it to verify the -// size of a static array: -// -// COMPILE_ASSERT(ARRAYSIZE(content_type_names) == CONTENT_NUM_TYPES, -// content_type_names_incorrect_size); -// -// or to make sure a struct is smaller than a certain size: -// -// COMPILE_ASSERT(sizeof(foo) < 128, foo_too_large); -// -// The second argument to the macro is the name of the variable. If -// the expression is false, most compilers will issue a warning/error -// containing the name of the variable. - -namespace internal { - -template -struct CompileAssert { -}; - -} // namespace internal - -#undef GOOGLE_COMPILE_ASSERT -#define GOOGLE_COMPILE_ASSERT(expr, msg) \ - ::google::protobuf::internal::CompileAssert<(bool(expr))> \ - msg[bool(expr) ? 1 : -1]; \ - (void)msg - - -// Implementation details of COMPILE_ASSERT: -// -// - COMPILE_ASSERT works by defining an array type that has -1 -// elements (and thus is invalid) when the expression is false. -// -// - The simpler definition -// -// #define COMPILE_ASSERT(expr, msg) typedef char msg[(expr) ? 1 : -1] -// -// does not work, as gcc supports variable-length arrays whose sizes -// are determined at run-time (this is gcc's extension and not part -// of the C++ standard). As a result, gcc fails to reject the -// following code with the simple definition: -// -// int foo; -// COMPILE_ASSERT(foo, msg); // not supposed to compile as foo is -// // not a compile-time constant. -// -// - By using the type CompileAssert<(bool(expr))>, we ensures that -// expr is a compile-time constant. (Template arguments must be -// determined at compile-time.) -// -// - The outter parentheses in CompileAssert<(bool(expr))> are necessary -// to work around a bug in gcc 3.4.4 and 4.0.1. If we had written -// -// CompileAssert -// -// instead, these compilers will refuse to compile -// -// COMPILE_ASSERT(5 > 0, some_message); -// -// (They seem to think the ">" in "5 > 0" marks the end of the -// template argument list.) -// -// - The array size is (bool(expr) ? 1 : -1), instead of simply -// -// ((expr) ? 1 : -1). -// -// This is to avoid running into a bug in MS VC 7.1, which -// causes ((0.0) ? 1 : -1) to incorrectly evaluate to 1. - -// =================================================================== -// from google3/base/scoped_ptr.h - -namespace internal { - -// This is an implementation designed to match the anticipated future TR2 -// implementation of the scoped_ptr class, and its closely-related brethren, -// scoped_array, scoped_ptr_malloc, and make_scoped_ptr. - -template class scoped_ptr; -template class scoped_array; - -// A scoped_ptr is like a T*, except that the destructor of scoped_ptr -// automatically deletes the pointer it holds (if any). -// That is, scoped_ptr owns the T object that it points to. -// Like a T*, a scoped_ptr may hold either NULL or a pointer to a T object. -// -// The size of a scoped_ptr is small: -// sizeof(scoped_ptr) == sizeof(C*) -template -class scoped_ptr { - public: - - // The element type - typedef C element_type; - - // Constructor. Defaults to initializing with NULL. - // There is no way to create an uninitialized scoped_ptr. - // The input parameter must be allocated with new. - explicit scoped_ptr(C* p = NULL) : ptr_(p) { } - - // Destructor. If there is a C object, delete it. - // We don't need to test ptr_ == NULL because C++ does that for us. - ~scoped_ptr() { - enum { type_must_be_complete = sizeof(C) }; - delete ptr_; - } - - // Reset. Deletes the current owned object, if any. - // Then takes ownership of a new object, if given. - // this->reset(this->get()) works. - void reset(C* p = NULL) { - if (p != ptr_) { - enum { type_must_be_complete = sizeof(C) }; - delete ptr_; - ptr_ = p; - } - } - - // Accessors to get the owned object. - // operator* and operator-> will assert() if there is no current object. - C& operator*() const { - assert(ptr_ != NULL); - return *ptr_; - } - C* operator->() const { - assert(ptr_ != NULL); - return ptr_; - } - C* get() const { return ptr_; } - - // Comparison operators. - // These return whether two scoped_ptr refer to the same object, not just to - // two different but equal objects. - bool operator==(C* p) const { return ptr_ == p; } - bool operator!=(C* p) const { return ptr_ != p; } - - // Swap two scoped pointers. - void swap(scoped_ptr& p2) { - C* tmp = ptr_; - ptr_ = p2.ptr_; - p2.ptr_ = tmp; - } - - // Release a pointer. - // The return value is the current pointer held by this object. - // If this object holds a NULL pointer, the return value is NULL. - // After this operation, this object will hold a NULL pointer, - // and will not own the object any more. - C* release() { - C* retVal = ptr_; - ptr_ = NULL; - return retVal; - } - - private: - C* ptr_; - - // Forbid comparison of scoped_ptr types. If C2 != C, it totally doesn't - // make sense, and if C2 == C, it still doesn't make sense because you should - // never have the same object owned by two different scoped_ptrs. - template bool operator==(scoped_ptr const& p2) const; - template bool operator!=(scoped_ptr const& p2) const; - - // Disallow evil constructors - scoped_ptr(const scoped_ptr&); - void operator=(const scoped_ptr&); -}; - -// scoped_array is like scoped_ptr, except that the caller must allocate -// with new [] and the destructor deletes objects with delete []. -// -// As with scoped_ptr, a scoped_array either points to an object -// or is NULL. A scoped_array owns the object that it points to. -// -// Size: sizeof(scoped_array) == sizeof(C*) -template -class scoped_array { - public: - - // The element type - typedef C element_type; - - // Constructor. Defaults to initializing with NULL. - // There is no way to create an uninitialized scoped_array. - // The input parameter must be allocated with new []. - explicit scoped_array(C* p = NULL) : array_(p) { } - - // Destructor. If there is a C object, delete it. - // We don't need to test ptr_ == NULL because C++ does that for us. - ~scoped_array() { - enum { type_must_be_complete = sizeof(C) }; - delete[] array_; - } - - // Reset. Deletes the current owned object, if any. - // Then takes ownership of a new object, if given. - // this->reset(this->get()) works. - void reset(C* p = NULL) { - if (p != array_) { - enum { type_must_be_complete = sizeof(C) }; - delete[] array_; - array_ = p; - } - } - - // Get one element of the current object. - // Will assert() if there is no current object, or index i is negative. - C& operator[](std::ptrdiff_t i) const { - assert(i >= 0); - assert(array_ != NULL); - return array_[i]; - } - - // Get a pointer to the zeroth element of the current object. - // If there is no current object, return NULL. - C* get() const { - return array_; - } - - // Comparison operators. - // These return whether two scoped_array refer to the same object, not just to - // two different but equal objects. - bool operator==(C* p) const { return array_ == p; } - bool operator!=(C* p) const { return array_ != p; } - - // Swap two scoped arrays. - void swap(scoped_array& p2) { - C* tmp = array_; - array_ = p2.array_; - p2.array_ = tmp; - } - - // Release an array. - // The return value is the current pointer held by this object. - // If this object holds a NULL pointer, the return value is NULL. - // After this operation, this object will hold a NULL pointer, - // and will not own the object any more. - C* release() { - C* retVal = array_; - array_ = NULL; - return retVal; - } - - private: - C* array_; - - // Forbid comparison of different scoped_array types. - template bool operator==(scoped_array const& p2) const; - template bool operator!=(scoped_array const& p2) const; - - // Disallow evil constructors - scoped_array(const scoped_array&); - void operator=(const scoped_array&); -}; - -} // namespace internal - -// We made these internal so that they would show up as such in the docs, -// but we don't want to stick "internal::" in front of them everywhere. -using internal::scoped_ptr; -using internal::scoped_array; - -// =================================================================== -// emulates google3/base/logging.h - -enum LogLevel { - LOGLEVEL_INFO, // Informational. This is never actually used by - // libprotobuf. - LOGLEVEL_WARNING, // Warns about issues that, although not technically a - // problem now, could cause problems in the future. For - // example, a // warning will be printed when parsing a - // message that is near the message size limit. - LOGLEVEL_ERROR, // An error occurred which should never happen during - // normal use. - LOGLEVEL_FATAL, // An error occurred from which the library cannot - // recover. This usually indicates a programming error - // in the code which calls the library, especially when - // compiled in debug mode. - -#ifdef NDEBUG - LOGLEVEL_DFATAL = LOGLEVEL_ERROR -#else - LOGLEVEL_DFATAL = LOGLEVEL_FATAL -#endif -}; - -class StringPiece; -namespace util { -class Status; -} -namespace internal { - -class LogFinisher; - -class LIBPROTOBUF_EXPORT LogMessage { - public: - LogMessage(LogLevel level, const char* filename, int line); - ~LogMessage(); - - LogMessage& operator<<(const std::string& value); - LogMessage& operator<<(const char* value); - LogMessage& operator<<(char value); - LogMessage& operator<<(int value); - LogMessage& operator<<(unsigned int value); - LogMessage& operator<<(long value); - LogMessage& operator<<(unsigned long value); - LogMessage& operator<<(long long value); - LogMessage& operator<<(unsigned long long value); - LogMessage& operator<<(double value); - LogMessage& operator<<(void* value); - LogMessage& operator<<(const StringPiece& value); - LogMessage& operator<<(const ::google::protobuf::util::Status& status); - - private: - friend class LogFinisher; - void Finish(); - - LogLevel level_; - const char* filename_; - int line_; - std::string message_; -}; - -// Used to make the entire "LOG(BLAH) << etc." expression have a void return -// type and print a newline after each message. -class LIBPROTOBUF_EXPORT LogFinisher { - public: - void operator=(LogMessage& other); -}; - -template -bool IsOk(T status) { return status.ok(); } -template<> -inline bool IsOk(bool status) { return status; } - -} // namespace internal - -// Undef everything in case we're being mixed with some other Google library -// which already defined them itself. Presumably all Google libraries will -// support the same syntax for these so it should not be a big deal if they -// end up using our definitions instead. -#undef GOOGLE_LOG -#undef GOOGLE_LOG_IF - -#undef GOOGLE_CHECK -#undef GOOGLE_CHECK_OK -#undef GOOGLE_CHECK_EQ -#undef GOOGLE_CHECK_NE -#undef GOOGLE_CHECK_LT -#undef GOOGLE_CHECK_LE -#undef GOOGLE_CHECK_GT -#undef GOOGLE_CHECK_GE -#undef GOOGLE_CHECK_NOTNULL - -#undef GOOGLE_DLOG -#undef GOOGLE_DCHECK -#undef GOOGLE_DCHECK_OK -#undef GOOGLE_DCHECK_EQ -#undef GOOGLE_DCHECK_NE -#undef GOOGLE_DCHECK_LT -#undef GOOGLE_DCHECK_LE -#undef GOOGLE_DCHECK_GT -#undef GOOGLE_DCHECK_GE - -#define GOOGLE_LOG(LEVEL) \ - ::google::protobuf::internal::LogFinisher() = \ - ::google::protobuf::internal::LogMessage( \ - ::google::protobuf::LOGLEVEL_##LEVEL, __FILE__, __LINE__) -#define GOOGLE_LOG_IF(LEVEL, CONDITION) \ - !(CONDITION) ? (void)0 : GOOGLE_LOG(LEVEL) - -#define GOOGLE_CHECK(EXPRESSION) \ - GOOGLE_LOG_IF(FATAL, !(EXPRESSION)) << "CHECK failed: " #EXPRESSION ": " -#define GOOGLE_CHECK_OK(A) GOOGLE_CHECK(::google::protobuf::internal::IsOk(A)) -#define GOOGLE_CHECK_EQ(A, B) GOOGLE_CHECK((A) == (B)) -#define GOOGLE_CHECK_NE(A, B) GOOGLE_CHECK((A) != (B)) -#define GOOGLE_CHECK_LT(A, B) GOOGLE_CHECK((A) < (B)) -#define GOOGLE_CHECK_LE(A, B) GOOGLE_CHECK((A) <= (B)) -#define GOOGLE_CHECK_GT(A, B) GOOGLE_CHECK((A) > (B)) -#define GOOGLE_CHECK_GE(A, B) GOOGLE_CHECK((A) >= (B)) - -namespace internal { -template -T* CheckNotNull(const char* /* file */, int /* line */, - const char* name, T* val) { - if (val == NULL) { - GOOGLE_LOG(FATAL) << name; - } - return val; -} -} // namespace internal -#define GOOGLE_CHECK_NOTNULL(A) \ - ::google::protobuf::internal::CheckNotNull(\ - __FILE__, __LINE__, "'" #A "' must not be NULL", (A)) - -#ifdef NDEBUG - -#define GOOGLE_DLOG GOOGLE_LOG_IF(INFO, false) - -#define GOOGLE_DCHECK(EXPRESSION) while(false) GOOGLE_CHECK(EXPRESSION) -#define GOOGLE_DCHECK_OK(E) GOOGLE_DCHECK(::google::protobuf::internal::IsOk(E)) -#define GOOGLE_DCHECK_EQ(A, B) GOOGLE_DCHECK((A) == (B)) -#define GOOGLE_DCHECK_NE(A, B) GOOGLE_DCHECK((A) != (B)) -#define GOOGLE_DCHECK_LT(A, B) GOOGLE_DCHECK((A) < (B)) -#define GOOGLE_DCHECK_LE(A, B) GOOGLE_DCHECK((A) <= (B)) -#define GOOGLE_DCHECK_GT(A, B) GOOGLE_DCHECK((A) > (B)) -#define GOOGLE_DCHECK_GE(A, B) GOOGLE_DCHECK((A) >= (B)) - -#else // NDEBUG - -#define GOOGLE_DLOG GOOGLE_LOG - -#define GOOGLE_DCHECK GOOGLE_CHECK -#define GOOGLE_DCHECK_OK GOOGLE_CHECK_OK -#define GOOGLE_DCHECK_EQ GOOGLE_CHECK_EQ -#define GOOGLE_DCHECK_NE GOOGLE_CHECK_NE -#define GOOGLE_DCHECK_LT GOOGLE_CHECK_LT -#define GOOGLE_DCHECK_LE GOOGLE_CHECK_LE -#define GOOGLE_DCHECK_GT GOOGLE_CHECK_GT -#define GOOGLE_DCHECK_GE GOOGLE_CHECK_GE - -#endif // !NDEBUG - -typedef void LogHandler(LogLevel level, const char* filename, int line, - const std::string& message); - -// The protobuf library sometimes writes warning and error messages to -// stderr. These messages are primarily useful for developers, but may -// also help end users figure out a problem. If you would prefer that -// these messages be sent somewhere other than stderr, call SetLogHandler() -// to set your own handler. This returns the old handler. Set the handler -// to NULL to ignore log messages (but see also LogSilencer, below). -// -// Obviously, SetLogHandler is not thread-safe. You should only call it -// at initialization time, and probably not from library code. If you -// simply want to suppress log messages temporarily (e.g. because you -// have some code that tends to trigger them frequently and you know -// the warnings are not important to you), use the LogSilencer class -// below. -LIBPROTOBUF_EXPORT LogHandler* SetLogHandler(LogHandler* new_func); - -// Create a LogSilencer if you want to temporarily suppress all log -// messages. As long as any LogSilencer objects exist, non-fatal -// log messages will be discarded (the current LogHandler will *not* -// be called). Constructing a LogSilencer is thread-safe. You may -// accidentally suppress log messages occurring in another thread, but -// since messages are generally for debugging purposes only, this isn't -// a big deal. If you want to intercept log messages, use SetLogHandler(). -class LIBPROTOBUF_EXPORT LogSilencer { - public: - LogSilencer(); - ~LogSilencer(); -}; - -// =================================================================== -// emulates google3/base/callback.h - -// Abstract interface for a callback. When calling an RPC, you must provide -// a Closure to call when the procedure completes. See the Service interface -// in service.h. -// -// To automatically construct a Closure which calls a particular function or -// method with a particular set of parameters, use the NewCallback() function. -// Example: -// void FooDone(const FooResponse* response) { -// ... -// } -// -// void CallFoo() { -// ... -// // When done, call FooDone() and pass it a pointer to the response. -// Closure* callback = NewCallback(&FooDone, response); -// // Make the call. -// service->Foo(controller, request, response, callback); -// } -// -// Example that calls a method: -// class Handler { -// public: -// ... -// -// void FooDone(const FooResponse* response) { -// ... -// } -// -// void CallFoo() { -// ... -// // When done, call FooDone() and pass it a pointer to the response. -// Closure* callback = NewCallback(this, &Handler::FooDone, response); -// // Make the call. -// service->Foo(controller, request, response, callback); -// } -// }; -// -// Currently NewCallback() supports binding zero, one, or two arguments. -// -// Callbacks created with NewCallback() automatically delete themselves when -// executed. They should be used when a callback is to be called exactly -// once (usually the case with RPC callbacks). If a callback may be called -// a different number of times (including zero), create it with -// NewPermanentCallback() instead. You are then responsible for deleting the -// callback (using the "delete" keyword as normal). -// -// Note that NewCallback() is a bit touchy regarding argument types. Generally, -// the values you provide for the parameter bindings must exactly match the -// types accepted by the callback function. For example: -// void Foo(string s); -// NewCallback(&Foo, "foo"); // WON'T WORK: const char* != string -// NewCallback(&Foo, string("foo")); // WORKS -// Also note that the arguments cannot be references: -// void Foo(const string& s); -// string my_str; -// NewCallback(&Foo, my_str); // WON'T WORK: Can't use referecnes. -// However, correctly-typed pointers will work just fine. -class LIBPROTOBUF_EXPORT Closure { - public: - Closure() {} - virtual ~Closure(); - - virtual void Run() = 0; - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Closure); -}; - -template -class LIBPROTOBUF_EXPORT ResultCallback1 { - public: - ResultCallback1() {} - virtual ~ResultCallback1() {} - - virtual R Run(A1) = 0; - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ResultCallback1); -}; - -template -class LIBPROTOBUF_EXPORT ResultCallback2 { - public: - ResultCallback2() {} - virtual ~ResultCallback2() {} - - virtual R Run(A1,A2) = 0; - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ResultCallback2); -}; - -namespace internal { - -class LIBPROTOBUF_EXPORT FunctionClosure0 : public Closure { - public: - typedef void (*FunctionType)(); - - FunctionClosure0(FunctionType function, bool self_deleting) - : function_(function), self_deleting_(self_deleting) {} - ~FunctionClosure0(); - - void Run() { - bool needs_delete = self_deleting_; // read in case callback deletes - function_(); - if (needs_delete) delete this; - } - - private: - FunctionType function_; - bool self_deleting_; -}; - -template -class MethodClosure0 : public Closure { - public: - typedef void (Class::*MethodType)(); - - MethodClosure0(Class* object, MethodType method, bool self_deleting) - : object_(object), method_(method), self_deleting_(self_deleting) {} - ~MethodClosure0() {} - - void Run() { - bool needs_delete = self_deleting_; // read in case callback deletes - (object_->*method_)(); - if (needs_delete) delete this; - } - - private: - Class* object_; - MethodType method_; - bool self_deleting_; -}; - -template -class FunctionClosure1 : public Closure { - public: - typedef void (*FunctionType)(Arg1 arg1); - - FunctionClosure1(FunctionType function, bool self_deleting, - Arg1 arg1) - : function_(function), self_deleting_(self_deleting), - arg1_(arg1) {} - ~FunctionClosure1() {} - - void Run() { - bool needs_delete = self_deleting_; // read in case callback deletes - function_(arg1_); - if (needs_delete) delete this; - } - - private: - FunctionType function_; - bool self_deleting_; - Arg1 arg1_; -}; - -template -class MethodClosure1 : public Closure { - public: - typedef void (Class::*MethodType)(Arg1 arg1); - - MethodClosure1(Class* object, MethodType method, bool self_deleting, - Arg1 arg1) - : object_(object), method_(method), self_deleting_(self_deleting), - arg1_(arg1) {} - ~MethodClosure1() {} - - void Run() { - bool needs_delete = self_deleting_; // read in case callback deletes - (object_->*method_)(arg1_); - if (needs_delete) delete this; - } - - private: - Class* object_; - MethodType method_; - bool self_deleting_; - Arg1 arg1_; -}; - -template -class FunctionClosure2 : public Closure { - public: - typedef void (*FunctionType)(Arg1 arg1, Arg2 arg2); - - FunctionClosure2(FunctionType function, bool self_deleting, - Arg1 arg1, Arg2 arg2) - : function_(function), self_deleting_(self_deleting), - arg1_(arg1), arg2_(arg2) {} - ~FunctionClosure2() {} - - void Run() { - bool needs_delete = self_deleting_; // read in case callback deletes - function_(arg1_, arg2_); - if (needs_delete) delete this; - } - - private: - FunctionType function_; - bool self_deleting_; - Arg1 arg1_; - Arg2 arg2_; -}; - -template -class MethodClosure2 : public Closure { - public: - typedef void (Class::*MethodType)(Arg1 arg1, Arg2 arg2); - - MethodClosure2(Class* object, MethodType method, bool self_deleting, - Arg1 arg1, Arg2 arg2) - : object_(object), method_(method), self_deleting_(self_deleting), - arg1_(arg1), arg2_(arg2) {} - ~MethodClosure2() {} - - void Run() { - bool needs_delete = self_deleting_; // read in case callback deletes - (object_->*method_)(arg1_, arg2_); - if (needs_delete) delete this; - } - - private: - Class* object_; - MethodType method_; - bool self_deleting_; - Arg1 arg1_; - Arg2 arg2_; -}; - -template -class FunctionResultCallback_0_1 : public ResultCallback1 { - public: - typedef R (*FunctionType)(Arg1 arg1); - - FunctionResultCallback_0_1(FunctionType function, bool self_deleting) - : function_(function), self_deleting_(self_deleting) {} - ~FunctionResultCallback_0_1() {} - - R Run(Arg1 a1) { - bool needs_delete = self_deleting_; // read in case callback deletes - R result = function_(a1); - if (needs_delete) delete this; - return result; - } - - private: - FunctionType function_; - bool self_deleting_; -}; - -template -class FunctionResultCallback_1_1 : public ResultCallback1 { - public: - typedef R (*FunctionType)(P1, A1); - - FunctionResultCallback_1_1(FunctionType function, bool self_deleting, - P1 p1) - : function_(function), self_deleting_(self_deleting), p1_(p1) {} - ~FunctionResultCallback_1_1() {} - - R Run(A1 a1) { - bool needs_delete = self_deleting_; // read in case callback deletes - R result = function_(p1_, a1); - if (needs_delete) delete this; - return result; - } - - private: - FunctionType function_; - bool self_deleting_; - P1 p1_; -}; - -// Duplicate this again in the type_traits.h, due to dependency problems. -template struct internal_remove_reference; -template struct internal_remove_reference { typedef T type; }; -template struct internal_remove_reference { typedef T type; }; - -template -struct InternalConstRef { - typedef typename internal_remove_reference::type base_type; - typedef const base_type& type; -}; - -template -class MethodResultCallback_5_2 : public ResultCallback2 { - public: - typedef R (T::*MethodType)(P1, P2, P3, P4, P5, A1, A2); - MethodResultCallback_5_2(T* object, MethodType method, bool self_deleting, - P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) - : object_(object), - method_(method), - self_deleting_(self_deleting), - p1_(p1), - p2_(p2), - p3_(p3), - p4_(p4), - p5_(p5) {} - ~MethodResultCallback_5_2() {} - - R Run(A1 a1, A2 a2) { - bool needs_delete = self_deleting_; - R result = (object_->*method_)(p1_, p2_, p3_, p4_, p5_, a1, a2); - if (needs_delete) delete this; - return result; - } - - private: - T* object_; - MethodType method_; - bool self_deleting_; - typename internal_remove_reference::type p1_; - typename internal_remove_reference::type p2_; - typename internal_remove_reference::type p3_; - typename internal_remove_reference::type p4_; - typename internal_remove_reference::type p5_; -}; - -} // namespace internal - -// See Closure. -inline Closure* NewCallback(void (*function)()) { - return new internal::FunctionClosure0(function, true); -} - -// See Closure. -inline Closure* NewPermanentCallback(void (*function)()) { - return new internal::FunctionClosure0(function, false); -} - -// See Closure. -template -inline Closure* NewCallback(Class* object, void (Class::*method)()) { - return new internal::MethodClosure0(object, method, true); -} - -// See Closure. -template -inline Closure* NewPermanentCallback(Class* object, void (Class::*method)()) { - return new internal::MethodClosure0(object, method, false); -} - -// See Closure. -template -inline Closure* NewCallback(void (*function)(Arg1), - Arg1 arg1) { - return new internal::FunctionClosure1(function, true, arg1); -} - -// See Closure. -template -inline Closure* NewPermanentCallback(void (*function)(Arg1), - Arg1 arg1) { - return new internal::FunctionClosure1(function, false, arg1); -} - -// See Closure. -template -inline Closure* NewCallback(Class* object, void (Class::*method)(Arg1), - Arg1 arg1) { - return new internal::MethodClosure1(object, method, true, arg1); -} - -// See Closure. -template -inline Closure* NewPermanentCallback(Class* object, void (Class::*method)(Arg1), - Arg1 arg1) { - return new internal::MethodClosure1(object, method, false, arg1); -} - -// See Closure. -template -inline Closure* NewCallback(void (*function)(Arg1, Arg2), - Arg1 arg1, Arg2 arg2) { - return new internal::FunctionClosure2( - function, true, arg1, arg2); -} - -// See Closure. -template -inline Closure* NewPermanentCallback(void (*function)(Arg1, Arg2), - Arg1 arg1, Arg2 arg2) { - return new internal::FunctionClosure2( - function, false, arg1, arg2); -} - -// See Closure. -template -inline Closure* NewCallback(Class* object, void (Class::*method)(Arg1, Arg2), - Arg1 arg1, Arg2 arg2) { - return new internal::MethodClosure2( - object, method, true, arg1, arg2); -} - -// See Closure. -template -inline Closure* NewPermanentCallback( - Class* object, void (Class::*method)(Arg1, Arg2), - Arg1 arg1, Arg2 arg2) { - return new internal::MethodClosure2( - object, method, false, arg1, arg2); -} - -// See ResultCallback1 -template -inline ResultCallback1* NewCallback(R (*function)(A1)) { - return new internal::FunctionResultCallback_0_1(function, true); -} - -// See ResultCallback1 -template -inline ResultCallback1* NewPermanentCallback(R (*function)(A1)) { - return new internal::FunctionResultCallback_0_1(function, false); -} - -// See ResultCallback1 -template -inline ResultCallback1* NewCallback(R (*function)(P1, A1), P1 p1) { - return new internal::FunctionResultCallback_1_1( - function, true, p1); -} - -// See ResultCallback1 -template -inline ResultCallback1* NewPermanentCallback( - R (*function)(P1, A1), P1 p1) { - return new internal::FunctionResultCallback_1_1( - function, false, p1); -} - -// See MethodResultCallback_5_2 -template -inline ResultCallback2* NewPermanentCallback( - T* object, R (T::*function)(P1, P2, P3, P4, P5, A1, A2), - typename internal::InternalConstRef::type p1, - typename internal::InternalConstRef::type p2, - typename internal::InternalConstRef::type p3, - typename internal::InternalConstRef::type p4, - typename internal::InternalConstRef::type p5) { - return new internal::MethodResultCallback_5_2(object, function, false, p1, - p2, p3, p4, p5); -} - -// A function which does nothing. Useful for creating no-op callbacks, e.g.: -// Closure* nothing = NewCallback(&DoNothing); -void LIBPROTOBUF_EXPORT DoNothing(); - -// =================================================================== -// emulates google3/base/mutex.h - -namespace internal { - -// A Mutex is a non-reentrant (aka non-recursive) mutex. At most one thread T -// may hold a mutex at a given time. If T attempts to Lock() the same Mutex -// while holding it, T will deadlock. -class LIBPROTOBUF_EXPORT Mutex { - public: - // Create a Mutex that is not held by anybody. - Mutex(); - - // Destructor - ~Mutex(); - - // Block if necessary until this Mutex is free, then acquire it exclusively. - void Lock(); - - // Release this Mutex. Caller must hold it exclusively. - void Unlock(); - - // Crash if this Mutex is not held exclusively by this thread. - // May fail to crash when it should; will never crash when it should not. - void AssertHeld(); - - private: - struct Internal; - Internal* mInternal; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Mutex); -}; - -// Undefine the macros to workaround the conflicts with Google internal -// MutexLock implementation. -// TODO(liujisi): Remove the undef once internal macros are removed. -#undef MutexLock -#undef ReaderMutexLock -#undef WriterMutexLock -#undef MutexLockMaybe - -// MutexLock(mu) acquires mu when constructed and releases it when destroyed. -class LIBPROTOBUF_EXPORT MutexLock { - public: - explicit MutexLock(Mutex *mu) : mu_(mu) { this->mu_->Lock(); } - ~MutexLock() { this->mu_->Unlock(); } - private: - Mutex *const mu_; - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MutexLock); -}; - -// TODO(kenton): Implement these? Hard to implement portably. -typedef MutexLock ReaderMutexLock; -typedef MutexLock WriterMutexLock; - -// MutexLockMaybe is like MutexLock, but is a no-op when mu is NULL. -class LIBPROTOBUF_EXPORT MutexLockMaybe { - public: - explicit MutexLockMaybe(Mutex *mu) : - mu_(mu) { if (this->mu_ != NULL) { this->mu_->Lock(); } } - ~MutexLockMaybe() { if (this->mu_ != NULL) { this->mu_->Unlock(); } } - private: - Mutex *const mu_; - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MutexLockMaybe); -}; - -#if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL) -template -class ThreadLocalStorage { - public: - ThreadLocalStorage() { - pthread_key_create(&key_, &ThreadLocalStorage::Delete); - } - ~ThreadLocalStorage() { - pthread_key_delete(key_); - } - T* Get() { - T* result = static_cast(pthread_getspecific(key_)); - if (result == NULL) { - result = new T(); - pthread_setspecific(key_, result); - } - return result; - } - private: - static void Delete(void* value) { - delete static_cast(value); - } - pthread_key_t key_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ThreadLocalStorage); -}; -#endif - -} // namespace internal - -// We made these internal so that they would show up as such in the docs, -// but we don't want to stick "internal::" in front of them everywhere. -using internal::Mutex; -using internal::MutexLock; -using internal::ReaderMutexLock; -using internal::WriterMutexLock; -using internal::MutexLockMaybe; // =================================================================== // from google3/util/utf8/public/unilib.h @@ -1431,114 +145,6 @@ LIBPROTOBUF_EXPORT bool IsStructurallyValidUTF8(const char* buf, int len); } // namespace internal -// =================================================================== -// from google3/base/port.h - -// The following guarantees declaration of the byte swap functions, and -// defines __BYTE_ORDER for MSVC -#ifdef _MSC_VER -#include // NOLINT(build/include) -#define __BYTE_ORDER __LITTLE_ENDIAN -#define bswap_16(x) _byteswap_ushort(x) -#define bswap_32(x) _byteswap_ulong(x) -#define bswap_64(x) _byteswap_uint64(x) - -#elif defined(__APPLE__) -// Mac OS X / Darwin features -#include -#define bswap_16(x) OSSwapInt16(x) -#define bswap_32(x) OSSwapInt32(x) -#define bswap_64(x) OSSwapInt64(x) - -#elif defined(__GLIBC__) || defined(__CYGWIN__) -#include // IWYU pragma: export - -#else - -static inline uint16 bswap_16(uint16 x) { - return static_cast(((x & 0xFF) << 8) | ((x & 0xFF00) >> 8)); -} -#define bswap_16(x) bswap_16(x) -static inline uint32 bswap_32(uint32 x) { - return (((x & 0xFF) << 24) | - ((x & 0xFF00) << 8) | - ((x & 0xFF0000) >> 8) | - ((x & 0xFF000000) >> 24)); -} -#define bswap_32(x) bswap_32(x) -static inline uint64 bswap_64(uint64 x) { - return (((x & GOOGLE_ULONGLONG(0xFF)) << 56) | - ((x & GOOGLE_ULONGLONG(0xFF00)) << 40) | - ((x & GOOGLE_ULONGLONG(0xFF0000)) << 24) | - ((x & GOOGLE_ULONGLONG(0xFF000000)) << 8) | - ((x & GOOGLE_ULONGLONG(0xFF00000000)) >> 8) | - ((x & GOOGLE_ULONGLONG(0xFF0000000000)) >> 24) | - ((x & GOOGLE_ULONGLONG(0xFF000000000000)) >> 40) | - ((x & GOOGLE_ULONGLONG(0xFF00000000000000)) >> 56)); -} -#define bswap_64(x) bswap_64(x) - -#endif - -// =================================================================== -// from google3/util/endian/endian.h -LIBPROTOBUF_EXPORT uint32 ghtonl(uint32 x); - -class BigEndian { - public: -#ifdef PROTOBUF_LITTLE_ENDIAN - - static uint16 FromHost16(uint16 x) { return bswap_16(x); } - static uint16 ToHost16(uint16 x) { return bswap_16(x); } - - static uint32 FromHost32(uint32 x) { return bswap_32(x); } - static uint32 ToHost32(uint32 x) { return bswap_32(x); } - - static uint64 FromHost64(uint64 x) { return bswap_64(x); } - static uint64 ToHost64(uint64 x) { return bswap_64(x); } - - static bool IsLittleEndian() { return true; } - -#else - - static uint16 FromHost16(uint16 x) { return x; } - static uint16 ToHost16(uint16 x) { return x; } - - static uint32 FromHost32(uint32 x) { return x; } - static uint32 ToHost32(uint32 x) { return x; } - - static uint64 FromHost64(uint64 x) { return x; } - static uint64 ToHost64(uint64 x) { return x; } - - static bool IsLittleEndian() { return false; } - -#endif /* ENDIAN */ - - // Functions to do unaligned loads and stores in big-endian order. - static uint16 Load16(const void *p) { - return ToHost16(GOOGLE_UNALIGNED_LOAD16(p)); - } - - static void Store16(void *p, uint16 v) { - GOOGLE_UNALIGNED_STORE16(p, FromHost16(v)); - } - - static uint32 Load32(const void *p) { - return ToHost32(GOOGLE_UNALIGNED_LOAD32(p)); - } - - static void Store32(void *p, uint32 v) { - GOOGLE_UNALIGNED_STORE32(p, FromHost32(v)); - } - - static uint64 Load64(const void *p) { - return ToHost64(GOOGLE_UNALIGNED_LOAD64(p)); - } - - static void Store64(void *p, uint64 v) { - GOOGLE_UNALIGNED_STORE64(p, FromHost64(v)); - } -}; // =================================================================== // Shutdown support. diff --git a/src/google/protobuf/stubs/logging.h b/src/google/protobuf/stubs/logging.h new file mode 100644 index 00000000..330d33d2 --- /dev/null +++ b/src/google/protobuf/stubs/logging.h @@ -0,0 +1,235 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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. + +#ifndef GOOGLE_PROTOBUF_STUBS_LOGGING_H_ +#define GOOGLE_PROTOBUF_STUBS_LOGGING_H_ + +#include +#include + +// =================================================================== +// emulates google3/base/logging.h + +namespace google { +namespace protobuf { + +enum LogLevel { + LOGLEVEL_INFO, // Informational. This is never actually used by + // libprotobuf. + LOGLEVEL_WARNING, // Warns about issues that, although not technically a + // problem now, could cause problems in the future. For + // example, a // warning will be printed when parsing a + // message that is near the message size limit. + LOGLEVEL_ERROR, // An error occurred which should never happen during + // normal use. + LOGLEVEL_FATAL, // An error occurred from which the library cannot + // recover. This usually indicates a programming error + // in the code which calls the library, especially when + // compiled in debug mode. + +#ifdef NDEBUG + LOGLEVEL_DFATAL = LOGLEVEL_ERROR +#else + LOGLEVEL_DFATAL = LOGLEVEL_FATAL +#endif +}; + +class StringPiece; +namespace util { +class Status; +} +namespace internal { + +class LogFinisher; + +class LIBPROTOBUF_EXPORT LogMessage { + public: + LogMessage(LogLevel level, const char* filename, int line); + ~LogMessage(); + + LogMessage& operator<<(const std::string& value); + LogMessage& operator<<(const char* value); + LogMessage& operator<<(char value); + LogMessage& operator<<(int value); + LogMessage& operator<<(unsigned int value); + LogMessage& operator<<(long value); + LogMessage& operator<<(unsigned long value); + LogMessage& operator<<(long long value); + LogMessage& operator<<(unsigned long long value); + LogMessage& operator<<(double value); + LogMessage& operator<<(void* value); + LogMessage& operator<<(const StringPiece& value); + LogMessage& operator<<(const ::google::protobuf::util::Status& status); + + private: + friend class LogFinisher; + void Finish(); + + LogLevel level_; + const char* filename_; + int line_; + std::string message_; +}; + +// Used to make the entire "LOG(BLAH) << etc." expression have a void return +// type and print a newline after each message. +class LIBPROTOBUF_EXPORT LogFinisher { + public: + void operator=(LogMessage& other); +}; + +template +bool IsOk(T status) { return status.ok(); } +template<> +inline bool IsOk(bool status) { return status; } + +} // namespace internal + +// Undef everything in case we're being mixed with some other Google library +// which already defined them itself. Presumably all Google libraries will +// support the same syntax for these so it should not be a big deal if they +// end up using our definitions instead. +#undef GOOGLE_LOG +#undef GOOGLE_LOG_IF + +#undef GOOGLE_CHECK +#undef GOOGLE_CHECK_OK +#undef GOOGLE_CHECK_EQ +#undef GOOGLE_CHECK_NE +#undef GOOGLE_CHECK_LT +#undef GOOGLE_CHECK_LE +#undef GOOGLE_CHECK_GT +#undef GOOGLE_CHECK_GE +#undef GOOGLE_CHECK_NOTNULL + +#undef GOOGLE_DLOG +#undef GOOGLE_DCHECK +#undef GOOGLE_DCHECK_OK +#undef GOOGLE_DCHECK_EQ +#undef GOOGLE_DCHECK_NE +#undef GOOGLE_DCHECK_LT +#undef GOOGLE_DCHECK_LE +#undef GOOGLE_DCHECK_GT +#undef GOOGLE_DCHECK_GE + +#define GOOGLE_LOG(LEVEL) \ + ::google::protobuf::internal::LogFinisher() = \ + ::google::protobuf::internal::LogMessage( \ + ::google::protobuf::LOGLEVEL_##LEVEL, __FILE__, __LINE__) +#define GOOGLE_LOG_IF(LEVEL, CONDITION) \ + !(CONDITION) ? (void)0 : GOOGLE_LOG(LEVEL) + +#define GOOGLE_CHECK(EXPRESSION) \ + GOOGLE_LOG_IF(FATAL, !(EXPRESSION)) << "CHECK failed: " #EXPRESSION ": " +#define GOOGLE_CHECK_OK(A) GOOGLE_CHECK(::google::protobuf::internal::IsOk(A)) +#define GOOGLE_CHECK_EQ(A, B) GOOGLE_CHECK((A) == (B)) +#define GOOGLE_CHECK_NE(A, B) GOOGLE_CHECK((A) != (B)) +#define GOOGLE_CHECK_LT(A, B) GOOGLE_CHECK((A) < (B)) +#define GOOGLE_CHECK_LE(A, B) GOOGLE_CHECK((A) <= (B)) +#define GOOGLE_CHECK_GT(A, B) GOOGLE_CHECK((A) > (B)) +#define GOOGLE_CHECK_GE(A, B) GOOGLE_CHECK((A) >= (B)) + +namespace internal { +template +T* CheckNotNull(const char* /* file */, int /* line */, + const char* name, T* val) { + if (val == NULL) { + GOOGLE_LOG(FATAL) << name; + } + return val; +} +} // namespace internal +#define GOOGLE_CHECK_NOTNULL(A) \ + ::google::protobuf::internal::CheckNotNull(\ + __FILE__, __LINE__, "'" #A "' must not be NULL", (A)) + +#ifdef NDEBUG + +#define GOOGLE_DLOG GOOGLE_LOG_IF(INFO, false) + +#define GOOGLE_DCHECK(EXPRESSION) while(false) GOOGLE_CHECK(EXPRESSION) +#define GOOGLE_DCHECK_OK(E) GOOGLE_DCHECK(::google::protobuf::internal::IsOk(E)) +#define GOOGLE_DCHECK_EQ(A, B) GOOGLE_DCHECK((A) == (B)) +#define GOOGLE_DCHECK_NE(A, B) GOOGLE_DCHECK((A) != (B)) +#define GOOGLE_DCHECK_LT(A, B) GOOGLE_DCHECK((A) < (B)) +#define GOOGLE_DCHECK_LE(A, B) GOOGLE_DCHECK((A) <= (B)) +#define GOOGLE_DCHECK_GT(A, B) GOOGLE_DCHECK((A) > (B)) +#define GOOGLE_DCHECK_GE(A, B) GOOGLE_DCHECK((A) >= (B)) + +#else // NDEBUG + +#define GOOGLE_DLOG GOOGLE_LOG + +#define GOOGLE_DCHECK GOOGLE_CHECK +#define GOOGLE_DCHECK_OK GOOGLE_CHECK_OK +#define GOOGLE_DCHECK_EQ GOOGLE_CHECK_EQ +#define GOOGLE_DCHECK_NE GOOGLE_CHECK_NE +#define GOOGLE_DCHECK_LT GOOGLE_CHECK_LT +#define GOOGLE_DCHECK_LE GOOGLE_CHECK_LE +#define GOOGLE_DCHECK_GT GOOGLE_CHECK_GT +#define GOOGLE_DCHECK_GE GOOGLE_CHECK_GE + +#endif // !NDEBUG + +typedef void LogHandler(LogLevel level, const char* filename, int line, + const std::string& message); + +// The protobuf library sometimes writes warning and error messages to +// stderr. These messages are primarily useful for developers, but may +// also help end users figure out a problem. If you would prefer that +// these messages be sent somewhere other than stderr, call SetLogHandler() +// to set your own handler. This returns the old handler. Set the handler +// to NULL to ignore log messages (but see also LogSilencer, below). +// +// Obviously, SetLogHandler is not thread-safe. You should only call it +// at initialization time, and probably not from library code. If you +// simply want to suppress log messages temporarily (e.g. because you +// have some code that tends to trigger them frequently and you know +// the warnings are not important to you), use the LogSilencer class +// below. +LIBPROTOBUF_EXPORT LogHandler* SetLogHandler(LogHandler* new_func); + +// Create a LogSilencer if you want to temporarily suppress all log +// messages. As long as any LogSilencer objects exist, non-fatal +// log messages will be discarded (the current LogHandler will *not* +// be called). Constructing a LogSilencer is thread-safe. You may +// accidentally suppress log messages occurring in another thread, but +// since messages are generally for debugging purposes only, this isn't +// a big deal. If you want to intercept log messages, use SetLogHandler(). +class LIBPROTOBUF_EXPORT LogSilencer { + public: + LogSilencer(); + ~LogSilencer(); +}; + +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_STUBS_LOGGING_H_ diff --git a/src/google/protobuf/stubs/macros.h b/src/google/protobuf/stubs/macros.h new file mode 100644 index 00000000..eb38268e --- /dev/null +++ b/src/google/protobuf/stubs/macros.h @@ -0,0 +1,166 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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. + +#ifndef GOOGLE_PROTOBUF_MACROS_H__ +#define GOOGLE_PROTOBUF_MACROS_H__ + +#include + +namespace google { +namespace protobuf { + +#undef GOOGLE_DISALLOW_EVIL_CONSTRUCTORS +#define GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TypeName) \ + TypeName(const TypeName&); \ + void operator=(const TypeName&) + +#undef GOOGLE_DISALLOW_IMPLICIT_CONSTRUCTORS +#define GOOGLE_DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \ + TypeName(); \ + TypeName(const TypeName&); \ + void operator=(const TypeName&) + +// =================================================================== +// from google3/base/basictypes.h + +// The GOOGLE_ARRAYSIZE(arr) macro returns the # of elements in an array arr. +// The expression is a compile-time constant, and therefore can be +// used in defining new arrays, for example. +// +// GOOGLE_ARRAYSIZE catches a few type errors. If you see a compiler error +// +// "warning: division by zero in ..." +// +// when using GOOGLE_ARRAYSIZE, you are (wrongfully) giving it a pointer. +// You should only use GOOGLE_ARRAYSIZE on statically allocated arrays. +// +// The following comments are on the implementation details, and can +// be ignored by the users. +// +// ARRAYSIZE(arr) works by inspecting sizeof(arr) (the # of bytes in +// the array) and sizeof(*(arr)) (the # of bytes in one array +// element). If the former is divisible by the latter, perhaps arr is +// indeed an array, in which case the division result is the # of +// elements in the array. Otherwise, arr cannot possibly be an array, +// and we generate a compiler error to prevent the code from +// compiling. +// +// Since the size of bool is implementation-defined, we need to cast +// !(sizeof(a) & sizeof(*(a))) to size_t in order to ensure the final +// result has type size_t. +// +// This macro is not perfect as it wrongfully accepts certain +// pointers, namely where the pointer size is divisible by the pointee +// size. Since all our code has to go through a 32-bit compiler, +// where a pointer is 4 bytes, this means all pointers to a type whose +// size is 3 or greater than 4 will be (righteously) rejected. +// +// Kudos to Jorg Brown for this simple and elegant implementation. + +#undef GOOGLE_ARRAYSIZE +#define GOOGLE_ARRAYSIZE(a) \ + ((sizeof(a) / sizeof(*(a))) / \ + static_cast(!(sizeof(a) % sizeof(*(a))))) + +// The COMPILE_ASSERT macro can be used to verify that a compile time +// expression is true. For example, you could use it to verify the +// size of a static array: +// +// COMPILE_ASSERT(ARRAYSIZE(content_type_names) == CONTENT_NUM_TYPES, +// content_type_names_incorrect_size); +// +// or to make sure a struct is smaller than a certain size: +// +// COMPILE_ASSERT(sizeof(foo) < 128, foo_too_large); +// +// The second argument to the macro is the name of the variable. If +// the expression is false, most compilers will issue a warning/error +// containing the name of the variable. + +namespace internal { + +template +struct CompileAssert { +}; + +} // namespace internal + +#undef GOOGLE_COMPILE_ASSERT +#define GOOGLE_COMPILE_ASSERT(expr, msg) \ + ::google::protobuf::internal::CompileAssert<(bool(expr))> \ + msg[bool(expr) ? 1 : -1]; \ + (void)msg + + +// Implementation details of COMPILE_ASSERT: +// +// - COMPILE_ASSERT works by defining an array type that has -1 +// elements (and thus is invalid) when the expression is false. +// +// - The simpler definition +// +// #define COMPILE_ASSERT(expr, msg) typedef char msg[(expr) ? 1 : -1] +// +// does not work, as gcc supports variable-length arrays whose sizes +// are determined at run-time (this is gcc's extension and not part +// of the C++ standard). As a result, gcc fails to reject the +// following code with the simple definition: +// +// int foo; +// COMPILE_ASSERT(foo, msg); // not supposed to compile as foo is +// // not a compile-time constant. +// +// - By using the type CompileAssert<(bool(expr))>, we ensures that +// expr is a compile-time constant. (Template arguments must be +// determined at compile-time.) +// +// - The outter parentheses in CompileAssert<(bool(expr))> are necessary +// to work around a bug in gcc 3.4.4 and 4.0.1. If we had written +// +// CompileAssert +// +// instead, these compilers will refuse to compile +// +// COMPILE_ASSERT(5 > 0, some_message); +// +// (They seem to think the ">" in "5 > 0" marks the end of the +// template argument list.) +// +// - The array size is (bool(expr) ? 1 : -1), instead of simply +// +// ((expr) ? 1 : -1). +// +// This is to avoid running into a bug in MS VC 7.1, which +// causes ((0.0) ? 1 : -1) to incorrectly evaluate to 1. + +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_MACROS_H__ diff --git a/src/google/protobuf/stubs/mutex.h b/src/google/protobuf/stubs/mutex.h new file mode 100644 index 00000000..2cce0561 --- /dev/null +++ b/src/google/protobuf/stubs/mutex.h @@ -0,0 +1,144 @@ +// Copyright (c) 2006, Google Inc. +// All rights reserved. +// +// 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. + +#ifndef GOOGLE_PROTOBUF_STUBS_MUTEX_H_ +#define GOOGLE_PROTOBUF_STUBS_MUTEX_H_ + +#include + +// =================================================================== +// emulates google3/base/mutex.h +namespace google { +namespace protobuf { +namespace internal { + +// A Mutex is a non-reentrant (aka non-recursive) mutex. At most one thread T +// may hold a mutex at a given time. If T attempts to Lock() the same Mutex +// while holding it, T will deadlock. +class LIBPROTOBUF_EXPORT Mutex { + public: + // Create a Mutex that is not held by anybody. + Mutex(); + + // Destructor + ~Mutex(); + + // Block if necessary until this Mutex is free, then acquire it exclusively. + void Lock(); + + // Release this Mutex. Caller must hold it exclusively. + void Unlock(); + + // Crash if this Mutex is not held exclusively by this thread. + // May fail to crash when it should; will never crash when it should not. + void AssertHeld(); + + private: + struct Internal; + Internal* mInternal; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Mutex); +}; + +// Undefine the macros to workaround the conflicts with Google internal +// MutexLock implementation. +// TODO(liujisi): Remove the undef once internal macros are removed. +#undef MutexLock +#undef ReaderMutexLock +#undef WriterMutexLock +#undef MutexLockMaybe + +// MutexLock(mu) acquires mu when constructed and releases it when destroyed. +class LIBPROTOBUF_EXPORT MutexLock { + public: + explicit MutexLock(Mutex *mu) : mu_(mu) { this->mu_->Lock(); } + ~MutexLock() { this->mu_->Unlock(); } + private: + Mutex *const mu_; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MutexLock); +}; + +// TODO(kenton): Implement these? Hard to implement portably. +typedef MutexLock ReaderMutexLock; +typedef MutexLock WriterMutexLock; + +// MutexLockMaybe is like MutexLock, but is a no-op when mu is NULL. +class LIBPROTOBUF_EXPORT MutexLockMaybe { + public: + explicit MutexLockMaybe(Mutex *mu) : + mu_(mu) { if (this->mu_ != NULL) { this->mu_->Lock(); } } + ~MutexLockMaybe() { if (this->mu_ != NULL) { this->mu_->Unlock(); } } + private: + Mutex *const mu_; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MutexLockMaybe); +}; + +#if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL) +template +class ThreadLocalStorage { + public: + ThreadLocalStorage() { + pthread_key_create(&key_, &ThreadLocalStorage::Delete); + } + ~ThreadLocalStorage() { + pthread_key_delete(key_); + } + T* Get() { + T* result = static_cast(pthread_getspecific(key_)); + if (result == NULL) { + result = new T(); + pthread_setspecific(key_, result); + } + return result; + } + private: + static void Delete(void* value) { + delete static_cast(value); + } + pthread_key_t key_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ThreadLocalStorage); +}; +#endif + +} // namespace internal + +// We made these internal so that they would show up as such in the docs, +// but we don't want to stick "internal::" in front of them everywhere. +using internal::Mutex; +using internal::MutexLock; +using internal::ReaderMutexLock; +using internal::WriterMutexLock; +using internal::MutexLockMaybe; + + +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_STUBS_MUTEX_H_ diff --git a/src/google/protobuf/stubs/port.h b/src/google/protobuf/stubs/port.h new file mode 100644 index 00000000..c86cf35b --- /dev/null +++ b/src/google/protobuf/stubs/port.h @@ -0,0 +1,371 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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. + +#ifndef GOOGLE_PROTOBUF_STUBS_PORT_H_ +#define GOOGLE_PROTOBUF_STUBS_PORT_H_ + +#include +#include +#include +#include +#include +#if defined(__osf__) +// Tru64 lacks stdint.h, but has inttypes.h which defines a superset of +// what stdint.h would define. +#include +#elif !defined(_MSC_VER) +#include +#endif + +#undef PROTOBUF_LITTLE_ENDIAN +#ifdef _MSC_VER + // Assuming windows is always little-endian. + #if !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST) + #define PROTOBUF_LITTLE_ENDIAN 1 + #endif + #if _MSC_VER >= 1300 + // If MSVC has "/RTCc" set, it will complain about truncating casts at + // runtime. This file contains some intentional truncating casts. + #pragma runtime_checks("c", off) + #endif +#else + #include // __BYTE_ORDER + #if ((defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)) || \ + (defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN)) && \ + !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST) + #define PROTOBUF_LITTLE_ENDIAN 1 + #endif +#endif +#if defined(_MSC_VER) && defined(PROTOBUF_USE_DLLS) + #ifdef LIBPROTOBUF_EXPORTS + #define LIBPROTOBUF_EXPORT __declspec(dllexport) + #else + #define LIBPROTOBUF_EXPORT __declspec(dllimport) + #endif + #ifdef LIBPROTOC_EXPORTS + #define LIBPROTOC_EXPORT __declspec(dllexport) + #else + #define LIBPROTOC_EXPORT __declspec(dllimport) + #endif +#else + #define LIBPROTOBUF_EXPORT + #define LIBPROTOC_EXPORT +#endif + +// =================================================================== +// from google3/base/port.h +namespace google { +namespace protobuf { + +typedef unsigned int uint; + +#ifdef _MSC_VER +typedef signed __int8 int8; +typedef __int16 int16; +typedef __int32 int32; +typedef __int64 int64; + +typedef unsigned __int8 uint8; +typedef unsigned __int16 uint16; +typedef unsigned __int32 uint32; +typedef unsigned __int64 uint64; +#else +typedef signed char int8; +typedef short int16; +typedef int int32; +// NOTE: This should be "long long" for consistency with upstream, but +// something is stacked against this particular type for 64bit hashing. +// Switching it causes an obvious missing hash function (with an unobvious +// cause) when building the tests. +typedef int64_t int64; + +typedef unsigned char uint8; +typedef unsigned short uint16; +typedef unsigned int uint32; +// NOTE: This should be "unsigned long long" for consistency with upstream, but +// something is stacked against this particular type for 64bit hashing. +// Switching it causes an obvious missing hash function (with an unobvious +// cause) when building the tests. +typedef uint64_t uint64; +#endif + +// long long macros to be used because gcc and vc++ use different suffixes, +// and different size specifiers in format strings +#undef GOOGLE_LONGLONG +#undef GOOGLE_ULONGLONG +#undef GOOGLE_LL_FORMAT + +#ifdef _MSC_VER +#define GOOGLE_LONGLONG(x) x##I64 +#define GOOGLE_ULONGLONG(x) x##UI64 +#define GOOGLE_LL_FORMAT "I64" // As in printf("%I64d", ...) +#else +#define GOOGLE_LONGLONG(x) x##LL +#define GOOGLE_ULONGLONG(x) x##ULL +#define GOOGLE_LL_FORMAT "ll" // As in "%lld". Note that "q" is poor form also. +#endif + +static const int32 kint32max = 0x7FFFFFFF; +static const int32 kint32min = -kint32max - 1; +static const int64 kint64max = GOOGLE_LONGLONG(0x7FFFFFFFFFFFFFFF); +static const int64 kint64min = -kint64max - 1; +static const uint32 kuint32max = 0xFFFFFFFFu; +static const uint64 kuint64max = GOOGLE_ULONGLONG(0xFFFFFFFFFFFFFFFF); + +// ------------------------------------------------------------------- +// Annotations: Some parts of the code have been annotated in ways that might +// be useful to some compilers or tools, but are not supported universally. +// You can #define these annotations yourself if the default implementation +// is not right for you. + +#ifndef GOOGLE_ATTRIBUTE_ALWAYS_INLINE +#if defined(__GNUC__) && (__GNUC__ > 3 ||(__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) +// For functions we want to force inline. +// Introduced in gcc 3.1. +#define GOOGLE_ATTRIBUTE_ALWAYS_INLINE __attribute__ ((always_inline)) +#else +// Other compilers will have to figure it out for themselves. +#define GOOGLE_ATTRIBUTE_ALWAYS_INLINE +#endif +#endif + +#ifndef GOOGLE_ATTRIBUTE_NOINLINE +#if defined(__GNUC__) && (__GNUC__ > 3 ||(__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) +// For functions we want to force not inline. +// Introduced in gcc 3.1. +#define GOOGLE_ATTRIBUTE_NOINLINE __attribute__ ((noinline)) +#else +// Other compilers will have to figure it out for themselves. +#define GOOGLE_ATTRIBUTE_NOINLINE +#endif +#endif + +#ifndef GOOGLE_ATTRIBUTE_DEPRECATED +#ifdef __GNUC__ +// If the method/variable/type is used anywhere, produce a warning. +#define GOOGLE_ATTRIBUTE_DEPRECATED __attribute__((deprecated)) +#else +#define GOOGLE_ATTRIBUTE_DEPRECATED +#endif +#endif + +#ifndef GOOGLE_PREDICT_TRUE +#ifdef __GNUC__ +// Provided at least since GCC 3.0. +#define GOOGLE_PREDICT_TRUE(x) (__builtin_expect(!!(x), 1)) +#else +#define GOOGLE_PREDICT_TRUE +#endif +#endif + +#ifndef GOOGLE_PREDICT_FALSE +#ifdef __GNUC__ +// Provided at least since GCC 3.0. +#define GOOGLE_PREDICT_FALSE(x) (__builtin_expect(x, 0)) +#else +#define GOOGLE_PREDICT_FALSE +#endif +#endif + +// Delimits a block of code which may write to memory which is simultaneously +// written by other threads, but which has been determined to be thread-safe +// (e.g. because it is an idempotent write). +#ifndef GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN +#define GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN() +#endif +#ifndef GOOGLE_SAFE_CONCURRENT_WRITES_END +#define GOOGLE_SAFE_CONCURRENT_WRITES_END() +#endif + +#define GOOGLE_GUARDED_BY(x) +#define GOOGLE_FALLTHROUGH_INTENDED +#define GOOGLE_ATTRIBUTE_COLD + +// x86 and x86-64 can perform unaligned loads/stores directly. +#if defined(_M_X64) || defined(__x86_64__) || \ + defined(_M_IX86) || defined(__i386__) + +#define GOOGLE_UNALIGNED_LOAD16(_p) (*reinterpret_cast(_p)) +#define GOOGLE_UNALIGNED_LOAD32(_p) (*reinterpret_cast(_p)) +#define GOOGLE_UNALIGNED_LOAD64(_p) (*reinterpret_cast(_p)) + +#define GOOGLE_UNALIGNED_STORE16(_p, _val) (*reinterpret_cast(_p) = (_val)) +#define GOOGLE_UNALIGNED_STORE32(_p, _val) (*reinterpret_cast(_p) = (_val)) +#define GOOGLE_UNALIGNED_STORE64(_p, _val) (*reinterpret_cast(_p) = (_val)) + +#else +inline uint16 GOOGLE_UNALIGNED_LOAD16(const void *p) { + uint16 t; + memcpy(&t, p, sizeof t); + return t; +} + +inline uint32 GOOGLE_UNALIGNED_LOAD32(const void *p) { + uint32 t; + memcpy(&t, p, sizeof t); + return t; +} + +inline uint64 GOOGLE_UNALIGNED_LOAD64(const void *p) { + uint64 t; + memcpy(&t, p, sizeof t); + return t; +} + +inline void GOOGLE_UNALIGNED_STORE16(void *p, uint16 v) { + memcpy(p, &v, sizeof v); +} + +inline void GOOGLE_UNALIGNED_STORE32(void *p, uint32 v) { + memcpy(p, &v, sizeof v); +} + +inline void GOOGLE_UNALIGNED_STORE64(void *p, uint64 v) { + memcpy(p, &v, sizeof v); +} +#endif + +#if defined(_MSC_VER) +#define GOOGLE_THREAD_LOCAL __declspec(thread) +#else +#define GOOGLE_THREAD_LOCAL __thread +#endif + +// The following guarantees declaration of the byte swap functions, and +// defines __BYTE_ORDER for MSVC +#ifdef _MSC_VER +#include // NOLINT(build/include) +#define __BYTE_ORDER __LITTLE_ENDIAN +#define bswap_16(x) _byteswap_ushort(x) +#define bswap_32(x) _byteswap_ulong(x) +#define bswap_64(x) _byteswap_uint64(x) + +#elif defined(__APPLE__) +// Mac OS X / Darwin features +#include +#define bswap_16(x) OSSwapInt16(x) +#define bswap_32(x) OSSwapInt32(x) +#define bswap_64(x) OSSwapInt64(x) + +#elif defined(__GLIBC__) || defined(__CYGWIN__) +#include // IWYU pragma: export + +#else + +static inline uint16 bswap_16(uint16 x) { + return static_cast(((x & 0xFF) << 8) | ((x & 0xFF00) >> 8)); +} +#define bswap_16(x) bswap_16(x) +static inline uint32 bswap_32(uint32 x) { + return (((x & 0xFF) << 24) | + ((x & 0xFF00) << 8) | + ((x & 0xFF0000) >> 8) | + ((x & 0xFF000000) >> 24)); +} +#define bswap_32(x) bswap_32(x) +static inline uint64 bswap_64(uint64 x) { + return (((x & GOOGLE_ULONGLONG(0xFF)) << 56) | + ((x & GOOGLE_ULONGLONG(0xFF00)) << 40) | + ((x & GOOGLE_ULONGLONG(0xFF0000)) << 24) | + ((x & GOOGLE_ULONGLONG(0xFF000000)) << 8) | + ((x & GOOGLE_ULONGLONG(0xFF00000000)) >> 8) | + ((x & GOOGLE_ULONGLONG(0xFF0000000000)) >> 24) | + ((x & GOOGLE_ULONGLONG(0xFF000000000000)) >> 40) | + ((x & GOOGLE_ULONGLONG(0xFF00000000000000)) >> 56)); +} +#define bswap_64(x) bswap_64(x) + +#endif + +// =================================================================== +// from google3/util/endian/endian.h +LIBPROTOBUF_EXPORT uint32 ghtonl(uint32 x); + +class BigEndian { + public: +#ifdef PROTOBUF_LITTLE_ENDIAN + + static uint16 FromHost16(uint16 x) { return bswap_16(x); } + static uint16 ToHost16(uint16 x) { return bswap_16(x); } + + static uint32 FromHost32(uint32 x) { return bswap_32(x); } + static uint32 ToHost32(uint32 x) { return bswap_32(x); } + + static uint64 FromHost64(uint64 x) { return bswap_64(x); } + static uint64 ToHost64(uint64 x) { return bswap_64(x); } + + static bool IsLittleEndian() { return true; } + +#else + + static uint16 FromHost16(uint16 x) { return x; } + static uint16 ToHost16(uint16 x) { return x; } + + static uint32 FromHost32(uint32 x) { return x; } + static uint32 ToHost32(uint32 x) { return x; } + + static uint64 FromHost64(uint64 x) { return x; } + static uint64 ToHost64(uint64 x) { return x; } + + static bool IsLittleEndian() { return false; } + +#endif /* ENDIAN */ + + // Functions to do unaligned loads and stores in big-endian order. + static uint16 Load16(const void *p) { + return ToHost16(GOOGLE_UNALIGNED_LOAD16(p)); + } + + static void Store16(void *p, uint16 v) { + GOOGLE_UNALIGNED_STORE16(p, FromHost16(v)); + } + + static uint32 Load32(const void *p) { + return ToHost32(GOOGLE_UNALIGNED_LOAD32(p)); + } + + static void Store32(void *p, uint32 v) { + GOOGLE_UNALIGNED_STORE32(p, FromHost32(v)); + } + + static uint64 Load64(const void *p) { + return ToHost64(GOOGLE_UNALIGNED_LOAD64(p)); + } + + static void Store64(void *p, uint64 v) { + GOOGLE_UNALIGNED_STORE64(p, FromHost64(v)); + } +}; + + +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_STUBS_PORT_H_ diff --git a/src/google/protobuf/stubs/scoped_ptr.h b/src/google/protobuf/stubs/scoped_ptr.h new file mode 100644 index 00000000..4423c118 --- /dev/null +++ b/src/google/protobuf/stubs/scoped_ptr.h @@ -0,0 +1,236 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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. + +#ifndef GOOGLE_PROTOBUF_STUBS_SCOPED_PTR_H_ +#define GOOGLE_PROTOBUF_STUBS_SCOPED_PTR_H_ + +#include + +namespace google { +namespace protobuf { + +// =================================================================== +// from google3/base/scoped_ptr.h + +namespace internal { + +// This is an implementation designed to match the anticipated future TR2 +// implementation of the scoped_ptr class, and its closely-related brethren, +// scoped_array, scoped_ptr_malloc, and make_scoped_ptr. + +template class scoped_ptr; +template class scoped_array; + +// A scoped_ptr is like a T*, except that the destructor of scoped_ptr +// automatically deletes the pointer it holds (if any). +// That is, scoped_ptr owns the T object that it points to. +// Like a T*, a scoped_ptr may hold either NULL or a pointer to a T object. +// +// The size of a scoped_ptr is small: +// sizeof(scoped_ptr) == sizeof(C*) +template +class scoped_ptr { + public: + + // The element type + typedef C element_type; + + // Constructor. Defaults to initializing with NULL. + // There is no way to create an uninitialized scoped_ptr. + // The input parameter must be allocated with new. + explicit scoped_ptr(C* p = NULL) : ptr_(p) { } + + // Destructor. If there is a C object, delete it. + // We don't need to test ptr_ == NULL because C++ does that for us. + ~scoped_ptr() { + enum { type_must_be_complete = sizeof(C) }; + delete ptr_; + } + + // Reset. Deletes the current owned object, if any. + // Then takes ownership of a new object, if given. + // this->reset(this->get()) works. + void reset(C* p = NULL) { + if (p != ptr_) { + enum { type_must_be_complete = sizeof(C) }; + delete ptr_; + ptr_ = p; + } + } + + // Accessors to get the owned object. + // operator* and operator-> will assert() if there is no current object. + C& operator*() const { + assert(ptr_ != NULL); + return *ptr_; + } + C* operator->() const { + assert(ptr_ != NULL); + return ptr_; + } + C* get() const { return ptr_; } + + // Comparison operators. + // These return whether two scoped_ptr refer to the same object, not just to + // two different but equal objects. + bool operator==(C* p) const { return ptr_ == p; } + bool operator!=(C* p) const { return ptr_ != p; } + + // Swap two scoped pointers. + void swap(scoped_ptr& p2) { + C* tmp = ptr_; + ptr_ = p2.ptr_; + p2.ptr_ = tmp; + } + + // Release a pointer. + // The return value is the current pointer held by this object. + // If this object holds a NULL pointer, the return value is NULL. + // After this operation, this object will hold a NULL pointer, + // and will not own the object any more. + C* release() { + C* retVal = ptr_; + ptr_ = NULL; + return retVal; + } + + private: + C* ptr_; + + // Forbid comparison of scoped_ptr types. If C2 != C, it totally doesn't + // make sense, and if C2 == C, it still doesn't make sense because you should + // never have the same object owned by two different scoped_ptrs. + template bool operator==(scoped_ptr const& p2) const; + template bool operator!=(scoped_ptr const& p2) const; + + // Disallow evil constructors + scoped_ptr(const scoped_ptr&); + void operator=(const scoped_ptr&); +}; + +// scoped_array is like scoped_ptr, except that the caller must allocate +// with new [] and the destructor deletes objects with delete []. +// +// As with scoped_ptr, a scoped_array either points to an object +// or is NULL. A scoped_array owns the object that it points to. +// +// Size: sizeof(scoped_array) == sizeof(C*) +template +class scoped_array { + public: + + // The element type + typedef C element_type; + + // Constructor. Defaults to initializing with NULL. + // There is no way to create an uninitialized scoped_array. + // The input parameter must be allocated with new []. + explicit scoped_array(C* p = NULL) : array_(p) { } + + // Destructor. If there is a C object, delete it. + // We don't need to test ptr_ == NULL because C++ does that for us. + ~scoped_array() { + enum { type_must_be_complete = sizeof(C) }; + delete[] array_; + } + + // Reset. Deletes the current owned object, if any. + // Then takes ownership of a new object, if given. + // this->reset(this->get()) works. + void reset(C* p = NULL) { + if (p != array_) { + enum { type_must_be_complete = sizeof(C) }; + delete[] array_; + array_ = p; + } + } + + // Get one element of the current object. + // Will assert() if there is no current object, or index i is negative. + C& operator[](std::ptrdiff_t i) const { + assert(i >= 0); + assert(array_ != NULL); + return array_[i]; + } + + // Get a pointer to the zeroth element of the current object. + // If there is no current object, return NULL. + C* get() const { + return array_; + } + + // Comparison operators. + // These return whether two scoped_array refer to the same object, not just to + // two different but equal objects. + bool operator==(C* p) const { return array_ == p; } + bool operator!=(C* p) const { return array_ != p; } + + // Swap two scoped arrays. + void swap(scoped_array& p2) { + C* tmp = array_; + array_ = p2.array_; + p2.array_ = tmp; + } + + // Release an array. + // The return value is the current pointer held by this object. + // If this object holds a NULL pointer, the return value is NULL. + // After this operation, this object will hold a NULL pointer, + // and will not own the object any more. + C* release() { + C* retVal = array_; + array_ = NULL; + return retVal; + } + + private: + C* array_; + + // Forbid comparison of different scoped_array types. + template bool operator==(scoped_array const& p2) const; + template bool operator!=(scoped_array const& p2) const; + + // Disallow evil constructors + scoped_array(const scoped_array&); + void operator=(const scoped_array&); +}; + +} // namespace internal + +// We made these internal so that they would show up as such in the docs, +// but we don't want to stick "internal::" in front of them everywhere. +using internal::scoped_ptr; +using internal::scoped_array; + + +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_STUBS_SCOPED_PTR_H_ diff --git a/src/google/protobuf/stubs/type_traits.h b/src/google/protobuf/stubs/type_traits.h index 36a8f3b1..0d8127e5 100644 --- a/src/google/protobuf/stubs/type_traits.h +++ b/src/google/protobuf/stubs/type_traits.h @@ -59,9 +59,9 @@ #ifndef GOOGLE_PROTOBUF_TYPE_TRAITS_H_ #define GOOGLE_PROTOBUF_TYPE_TRAITS_H_ +#include // for NULL #include // For pair -#include #include // For true_type and false_type namespace google { -- cgit v1.2.3 From 7b216119eeb6761596cfe506863ff010b7f05da8 Mon Sep 17 00:00:00 2001 From: Jisi Liu Date: Fri, 17 Jul 2015 11:34:33 -0700 Subject: Update make file for extra headers. Change-Id: Ifbc415755266ba3d0ffa5661fcd7c7d2e3b32a22 --- cmake/extract_includes.bat.in | 6 ++++++ src/Makefile.am | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/cmake/extract_includes.bat.in b/cmake/extract_includes.bat.in index 6b84c378..d8e9e917 100644 --- a/cmake/extract_includes.bat.in +++ b/cmake/extract_includes.bat.in @@ -84,12 +84,18 @@ copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_intern copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_tsan.h include\google\protobuf\stubs\atomicops_internals_tsan.h copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_x86_gcc.h include\google\protobuf\stubs\atomicops_internals_x86_gcc.h copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_x86_msvc.h include\google\protobuf\stubs\atomicops_internals_x86_msvc.h +copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\callback.h include\google\protobuf\stubs\callback.h copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\casts.h include\google\protobuf\stubs\casts.h copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\common.h include\google\protobuf\stubs\common.h copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\fastmem.h include\google\protobuf\stubs\fastmem.h copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\hash.h include\google\protobuf\stubs\hash.h +copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\logging.h include\google\protobuf\stubs\logging.h +copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\macros.h include\google\protobuf\stubs\macros.h +copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\mutex.h include\google\protobuf\stubs\mutex.h copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\once.h include\google\protobuf\stubs\once.h copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\platform_macros.h include\google\protobuf\stubs\platform_macros.h +copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\port.h include\google\protobuf\stubs\port.h +copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\scoped_ptr.h include\google\protobuf\stubs\scoped_ptr.h copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\shared_ptr.h include\google\protobuf\stubs\shared_ptr.h copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\singleton.h include\google\protobuf\stubs\singleton.h copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\stl_util.h include\google\protobuf\stubs\stl_util.h diff --git a/src/Makefile.am b/src/Makefile.am index effe2a4a..3a07bbb3 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -71,12 +71,18 @@ nobase_include_HEADERS = \ google/protobuf/stubs/atomicops_internals_tsan.h \ google/protobuf/stubs/atomicops_internals_x86_gcc.h \ google/protobuf/stubs/atomicops_internals_x86_msvc.h \ + google/protobuf/stubs/callback.h \ google/protobuf/stubs/casts.h \ google/protobuf/stubs/common.h \ google/protobuf/stubs/fastmem.h \ google/protobuf/stubs/hash.h \ + google/protobuf/stubs/logging.h \ + google/protobuf/stubs/macros.h \ + google/protobuf/stubs/mutex.h \ google/protobuf/stubs/once.h \ google/protobuf/stubs/platform_macros.h \ + google/protobuf/stubs/port.h \ + google/protobuf/stubs/scoped_ptr.h \ google/protobuf/stubs/shared_ptr.h \ google/protobuf/stubs/singleton.h \ google/protobuf/stubs/stl_util.h \ -- cgit v1.2.3 From 12f6e3dd0e3c73674b973b170af3a7f577111dbb Mon Sep 17 00:00:00 2001 From: Jisi Liu Date: Fri, 17 Jul 2015 11:36:51 -0700 Subject: update header list. Change-Id: I75459b8b6562c3ac58fa4b1e4513accdda43ad64 --- cmake/extract_includes.bat.in | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cmake/extract_includes.bat.in b/cmake/extract_includes.bat.in index d8e9e917..99ab50a9 100644 --- a/cmake/extract_includes.bat.in +++ b/cmake/extract_includes.bat.in @@ -84,6 +84,7 @@ copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_intern copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_tsan.h include\google\protobuf\stubs\atomicops_internals_tsan.h copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_x86_gcc.h include\google\protobuf\stubs\atomicops_internals_x86_gcc.h copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_x86_msvc.h include\google\protobuf\stubs\atomicops_internals_x86_msvc.h +copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\bytestream.h include\google\protobuf\stubs\bytestream.h copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\callback.h include\google\protobuf\stubs\callback.h copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\casts.h include\google\protobuf\stubs\casts.h copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\common.h include\google\protobuf\stubs\common.h @@ -98,7 +99,9 @@ copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\port.h include\g copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\scoped_ptr.h include\google\protobuf\stubs\scoped_ptr.h copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\shared_ptr.h include\google\protobuf\stubs\shared_ptr.h copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\singleton.h include\google\protobuf\stubs\singleton.h +copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\status.h include\google\protobuf\stubs\status.h copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\stl_util.h include\google\protobuf\stubs\stl_util.h +copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\stringpiece.h include\google\protobuf\stubs\stringpiece.h copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\template_util.h include\google\protobuf\stubs\template_util.h copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\type_traits.h include\google\protobuf\stubs\type_traits.h copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\text_format.h include\google\protobuf\text_format.h -- cgit v1.2.3 From 56a90a2081379a5286edf0eea70aa2000e26c7f9 Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Fri, 17 Jul 2015 14:16:03 -0700 Subject: Let GOOGLE_COMPILE_ASSERT use static_assert if available. The motivation is that gcc 4.8+ and clang trunk warn on unused local typedefs, which COMPILE_ASSERT adds. After this change, the warning will be happy at least in C++11 builds. static_assert also produces a slighly nicer diagnostic than the typedef method. https://github.com/google/re2/commit/eb93e8bc43ac8d05322fb3e9fc885898ad924f8a did the same change in re2. --- src/google/protobuf/stubs/macros.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/google/protobuf/stubs/macros.h b/src/google/protobuf/stubs/macros.h index eb38268e..0e9a9ec1 100644 --- a/src/google/protobuf/stubs/macros.h +++ b/src/google/protobuf/stubs/macros.h @@ -113,12 +113,13 @@ struct CompileAssert { } // namespace internal #undef GOOGLE_COMPILE_ASSERT +#if __cplusplus >= 201103L +#define GOOGLE_COMPILE_ASSERT(expr, msg) static_assert(expr, #msg) +#else #define GOOGLE_COMPILE_ASSERT(expr, msg) \ ::google::protobuf::internal::CompileAssert<(bool(expr))> \ msg[bool(expr) ? 1 : -1]; \ (void)msg - - // Implementation details of COMPILE_ASSERT: // // - COMPILE_ASSERT works by defining an array type that has -1 @@ -159,6 +160,7 @@ struct CompileAssert { // // This is to avoid running into a bug in MS VC 7.1, which // causes ((0.0) ? 1 : -1) to incorrectly evaluate to 1. +#endif // __cplusplus >= 201103L } // namespace protobuf } // namespace google -- cgit v1.2.3 From 51053120db1a701538825e65e411ae67ef5736f6 Mon Sep 17 00:00:00 2001 From: Jisi Liu Date: Fri, 17 Jul 2015 15:22:05 -0700 Subject: Addming missing includes in stubs headers. This is to prepare removing those additional headers in common.h Change-Id: I707d6d8eaf193eb28195a827c7fec738b968ab3e --- src/google/protobuf/stubs/mathutil.h | 1 + src/google/protobuf/stubs/once.h | 1 + 2 files changed, 2 insertions(+) diff --git a/src/google/protobuf/stubs/mathutil.h b/src/google/protobuf/stubs/mathutil.h index 87ca5e91..99c4d452 100644 --- a/src/google/protobuf/stubs/mathutil.h +++ b/src/google/protobuf/stubs/mathutil.h @@ -34,6 +34,7 @@ #include #include +#include #include namespace google { diff --git a/src/google/protobuf/stubs/once.h b/src/google/protobuf/stubs/once.h index cc62bbaa..1f082c37 100644 --- a/src/google/protobuf/stubs/once.h +++ b/src/google/protobuf/stubs/once.h @@ -79,6 +79,7 @@ #define GOOGLE_PROTOBUF_STUBS_ONCE_H__ #include +#include #include namespace google { -- cgit v1.2.3 From 95ee8fb88ec8482cf64a2e564227dcb662ebcfa6 Mon Sep 17 00:00:00 2001 From: Josh Haberman Date: Fri, 17 Jul 2015 16:20:01 -0700 Subject: Exclude JRuby from conformance tests for now. Change-Id: Id008ebac5159f773e1bde8b85acb2626cbd16de8 --- ruby/travis-test.sh | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/ruby/travis-test.sh b/ruby/travis-test.sh index 4a2536a5..9ec7eb22 100755 --- a/ruby/travis-test.sh +++ b/ruby/travis-test.sh @@ -5,13 +5,22 @@ set -e test_version() { version=$1 - bash --login -c \ - "rvm install $version && rvm use $version && \ - which ruby && \ - gem install bundler && bundle && \ - rake test && \ - cd ../conformance && \ - make test_ruby" + if [ "$version" == "jruby" ] ; then + # No conformance tests yet -- JRuby is too broken to run them. + bash --login -c \ + "rvm install $version && rvm use $version && \ + which ruby && \ + gem install bundler && bundle && \ + rake test" + else + bash --login -c \ + "rvm install $version && rvm use $version && \ + which ruby && \ + gem install bundler && bundle && \ + rake test && \ + cd ../conformance && \ + make test_ruby" + fi } test_version $1 -- cgit v1.2.3 From c2c43a4917d7da263e360a4096d6603da8535bdf Mon Sep 17 00:00:00 2001 From: Josh Haberman Date: Fri, 17 Jul 2015 16:29:10 -0700 Subject: Fixed lint errors and responded to CR comments. Change-Id: If7b1cc0f03f609a7f43ddafc8509b44207c60910 --- conformance/conformance_ruby.rb | 55 ++++++++++++++++++++++------------------- ruby/lib/google/protobuf.rb | 2 +- 2 files changed, 30 insertions(+), 27 deletions(-) diff --git a/conformance/conformance_ruby.rb b/conformance/conformance_ruby.rb index e7bd4ed5..cd065673 100755 --- a/conformance/conformance_ruby.rb +++ b/conformance/conformance_ruby.rb @@ -32,8 +32,8 @@ require 'conformance' -test_count = 0; -verbose = false; +$test_count = 0 +$verbose = false def do_test(request) test_message = Conformance::TestAllTypes.new @@ -43,9 +43,10 @@ def do_test(request) case request.payload when :protobuf_payload begin - test_message = Conformance::TestAllTypes.decode(request.protobuf_payload) + test_message = + Conformance::TestAllTypes.decode(request.protobuf_payload) rescue Google::Protobuf::ParseError => err - response.parse_error = err.message.encode("utf-8") + response.parse_error = err.message.encode('utf-8') return response end @@ -53,34 +54,36 @@ def do_test(request) test_message = Conformance::TestAllTypes.decode_json(request.json_payload) when nil - raise "Request didn't have payload."; + fail "Request didn't have payload" end case request.requested_output_format when :UNSPECIFIED - raise "Unspecified output format" + fail 'Unspecified output format' when :PROTOBUF - response.protobuf_payload = Conformance::TestAllTypes.encode(test_message) + response.protobuf_payload = test_message.to_proto when :JSON - response.json_payload = Conformance::TestAllTypes.encode_json(test_message) + response.json_payload = test_message.to_json end - rescue Exception => err - response.runtime_error = err.message.encode("utf-8") + err.backtrace.join("\n") + rescue StandardError => err + response.runtime_error = err.message.encode('utf-8') end - return response + response end +# Returns true if the test ran successfully, false on legitimate EOF. +# If EOF is encountered in an unexpected place, raises IOError. def do_test_io length_bytes = STDIN.read(4) return false if length_bytes.nil? - length = length_bytes.unpack("V").first + length = length_bytes.unpack('V').first serialized_request = STDIN.read(length) - if serialized_request.nil? or serialized_request.length != length - raise "I/O error" + if serialized_request.nil? || serialized_request.length != length + fail IOError end request = Conformance::ConformanceRequest.decode(serialized_request) @@ -88,24 +91,24 @@ def do_test_io response = do_test(request) serialized_response = Conformance::ConformanceResponse.encode(response) - STDOUT.write([serialized_response.length].pack("V")) + STDOUT.write([serialized_response.length].pack('V')) STDOUT.write(serialized_response) STDOUT.flush - #if verbose - # fprintf(stderr, "conformance-cpp: request=%s, response=%s\n", - # request.ShortDebugString().c_str(), - # response.ShortDebugString().c_str()); + if $verbose + STDERR.puts("conformance-cpp: request={request.to_json}, " \ + "response={response.to_json}\n") + end - #test_count++; + $test_count += 1 - return true; + true end -while true - if not do_test_io() - STDERR.puts("conformance-cpp: received EOF from test runner " + - "after #{test_count} tests, exiting") - exit 0 +loop do + unless do_test_io + STDERR.puts('conformance-cpp: received EOF from test runner ' \ + "after #{$test_count} tests, exiting") + break end end diff --git a/ruby/lib/google/protobuf.rb b/ruby/lib/google/protobuf.rb index 74ea770d..f0eb6268 100644 --- a/ruby/lib/google/protobuf.rb +++ b/ruby/lib/google/protobuf.rb @@ -35,7 +35,7 @@ require 'google/protobuf/message_exts' # That way the module init can grab references to these. module Google module Protobuf - class Error < RuntimeError; end + class Error < StandardError; end class ParseError < Error; end end end -- cgit v1.2.3 From 69c14071ad58b1dad9e5e52c33140ece139577d0 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 20 Jul 2015 14:32:57 -0700 Subject: update addressbook.proto to proto3 --- examples/addressbook.proto | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/examples/addressbook.proto b/examples/addressbook.proto index 91c9ffc4..bbcb0c54 100644 --- a/examples/addressbook.proto +++ b/examples/addressbook.proto @@ -1,6 +1,6 @@ // See README.txt for information and build instructions. -syntax = "proto2"; +syntax = "proto3"; package tutorial; @@ -9,9 +9,9 @@ option java_outer_classname = "AddressBookProtos"; option csharp_namespace = "Google.ProtocolBuffers.Examples.AddressBook"; message Person { - required string name = 1; - required int32 id = 2; // Unique ID number for this person. - optional string email = 3; + string name = 1; + int32 id = 2; // Unique ID number for this person. + string email = 3; enum PhoneType { MOBILE = 0; @@ -20,14 +20,14 @@ message Person { } message PhoneNumber { - required string number = 1; - optional PhoneType type = 2 [default = HOME]; + string number = 1; + PhoneType type = 2; } - repeated PhoneNumber phone = 4; + repeated PhoneNumber phones = 4; } // Our address book file is just one of these. message AddressBook { - repeated Person person = 1; + repeated Person persons = 1; } -- cgit v1.2.3 From 78709f20fb7255c3209e7126f404935bcf73e8dc Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 20 Jul 2015 14:33:36 -0700 Subject: fix C++ example --- examples/add_person.cc | 4 ++-- examples/list_people.cc | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/examples/add_person.cc b/examples/add_person.cc index b9ca44fc..e71d3844 100644 --- a/examples/add_person.cc +++ b/examples/add_person.cc @@ -32,7 +32,7 @@ void PromptForAddress(tutorial::Person* person) { break; } - tutorial::Person::PhoneNumber* phone_number = person->add_phone(); + tutorial::Person::PhoneNumber* phone_number = person->add_phones(); phone_number->set_number(number); cout << "Is this a mobile, home, or work phone? "; @@ -77,7 +77,7 @@ int main(int argc, char* argv[]) { } // Add an address. - PromptForAddress(address_book.add_person()); + PromptForAddress(address_book.add_persons()); { // Write the new address book back to disk. diff --git a/examples/list_people.cc b/examples/list_people.cc index 5363152e..3daa3159 100644 --- a/examples/list_people.cc +++ b/examples/list_people.cc @@ -8,17 +8,17 @@ using namespace std; // Iterates though all people in the AddressBook and prints info about them. void ListPeople(const tutorial::AddressBook& address_book) { - for (int i = 0; i < address_book.person_size(); i++) { - const tutorial::Person& person = address_book.person(i); + for (int i = 0; i < address_book.persons_size(); i++) { + const tutorial::Person& person = address_book.persons(i); cout << "Person ID: " << person.id() << endl; cout << " Name: " << person.name() << endl; - if (person.has_email()) { + if (person.email() != "") { cout << " E-mail address: " << person.email() << endl; } - for (int j = 0; j < person.phone_size(); j++) { - const tutorial::Person::PhoneNumber& phone_number = person.phone(j); + for (int j = 0; j < person.phones_size(); j++) { + const tutorial::Person::PhoneNumber& phone_number = person.phones(j); switch (phone_number.type()) { case tutorial::Person::MOBILE: -- cgit v1.2.3 From b95670f5fb91ec49735510a5202e9c031d8f43f1 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 20 Jul 2015 14:34:27 -0700 Subject: fix python example --- examples/add_person.py | 4 ++-- examples/list_people.py | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/add_person.py b/examples/add_person.py index 5a7b968e..919a1a17 100755 --- a/examples/add_person.py +++ b/examples/add_person.py @@ -19,7 +19,7 @@ def PromptForAddress(person): if number == "": break - phone_number = person.phone.add() + phone_number = person.phones.add() phone_number.number = number type = raw_input("Is this a mobile, home, or work phone? ") @@ -50,7 +50,7 @@ except IOError: print sys.argv[1] + ": File not found. Creating a new file." # Add an address. -PromptForAddress(address_book.person.add()) +PromptForAddress(address_book.persons.add()) # Write the new address book back to disk. f = open(sys.argv[1], "wb") diff --git a/examples/list_people.py b/examples/list_people.py index d470349a..e0658493 100755 --- a/examples/list_people.py +++ b/examples/list_people.py @@ -7,13 +7,13 @@ import sys # Iterates though all people in the AddressBook and prints info about them. def ListPeople(address_book): - for person in address_book.person: + for person in address_book.persons: print "Person ID:", person.id print " Name:", person.name - if person.HasField('email'): + if person.email != "": print " E-mail address:", person.email - for phone_number in person.phone: + for phone_number in person.phones: if phone_number.type == addressbook_pb2.Person.MOBILE: print " Mobile phone #:", elif phone_number.type == addressbook_pb2.Person.HOME: -- cgit v1.2.3 From 4d86c2b495a359e31af082098aacc3e7ce3b9ee7 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 20 Jul 2015 14:51:09 -0700 Subject: fixed java example --- examples/AddPerson.java | 4 ++-- examples/ListPeople.java | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/AddPerson.java b/examples/AddPerson.java index ca5ac273..259cfb7b 100644 --- a/examples/AddPerson.java +++ b/examples/AddPerson.java @@ -50,7 +50,7 @@ class AddPerson { stdout.println("Unknown phone type. Using default."); } - person.addPhone(phoneNumber); + person.addPhones(phoneNumber); } return person.build(); @@ -80,7 +80,7 @@ class AddPerson { } // Add an address. - addressBook.addPerson( + addressBook.addPersons( PromptForAddress(new BufferedReader(new InputStreamReader(System.in)), System.out)); diff --git a/examples/ListPeople.java b/examples/ListPeople.java index b2f153af..0294fb7a 100644 --- a/examples/ListPeople.java +++ b/examples/ListPeople.java @@ -9,14 +9,14 @@ import java.io.PrintStream; class ListPeople { // Iterates though all people in the AddressBook and prints info about them. static void Print(AddressBook addressBook) { - for (Person person: addressBook.getPersonList()) { + for (Person person: addressBook.getPersonsList()) { System.out.println("Person ID: " + person.getId()); System.out.println(" Name: " + person.getName()); - if (person.hasEmail()) { + if (!person.getEmail().isEmpty()) { System.out.println(" E-mail address: " + person.getEmail()); } - for (Person.PhoneNumber phoneNumber : person.getPhoneList()) { + for (Person.PhoneNumber phoneNumber : person.getPhonesList()) { switch (phoneNumber.getType()) { case MOBILE: System.out.print(" Mobile phone #: "); -- cgit v1.2.3 From 359d32d4f711b7f8f774a1ceaa3ad55aa13167cf Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 20 Jul 2015 15:12:56 -0700 Subject: use Google.Protobuf namespace for C# --- examples/addressbook.proto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/addressbook.proto b/examples/addressbook.proto index bbcb0c54..64cb7acf 100644 --- a/examples/addressbook.proto +++ b/examples/addressbook.proto @@ -6,7 +6,7 @@ package tutorial; option java_package = "com.example.tutorial"; option java_outer_classname = "AddressBookProtos"; -option csharp_namespace = "Google.ProtocolBuffers.Examples.AddressBook"; +option csharp_namespace = "Google.Protobuf.Examples.AddressBook"; message Person { string name = 1; -- cgit v1.2.3 From b0e5ba697eb281b4ea9e53e1dc9f5ebeccf28f9a Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 20 Jul 2015 15:24:08 -0700 Subject: rename persons to people --- examples/AddPerson.java | 2 +- examples/ListPeople.java | 2 +- examples/add_person.cc | 2 +- examples/add_person.py | 2 +- examples/addressbook.proto | 2 +- examples/list_people.cc | 4 ++-- examples/list_people.py | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/examples/AddPerson.java b/examples/AddPerson.java index 259cfb7b..c262ab7e 100644 --- a/examples/AddPerson.java +++ b/examples/AddPerson.java @@ -80,7 +80,7 @@ class AddPerson { } // Add an address. - addressBook.addPersons( + addressBook.addPeople( PromptForAddress(new BufferedReader(new InputStreamReader(System.in)), System.out)); diff --git a/examples/ListPeople.java b/examples/ListPeople.java index 0294fb7a..78924305 100644 --- a/examples/ListPeople.java +++ b/examples/ListPeople.java @@ -9,7 +9,7 @@ import java.io.PrintStream; class ListPeople { // Iterates though all people in the AddressBook and prints info about them. static void Print(AddressBook addressBook) { - for (Person person: addressBook.getPersonsList()) { + for (Person person: addressBook.getPeopleList()) { System.out.println("Person ID: " + person.getId()); System.out.println(" Name: " + person.getName()); if (!person.getEmail().isEmpty()) { diff --git a/examples/add_person.cc b/examples/add_person.cc index e71d3844..9bec4b37 100644 --- a/examples/add_person.cc +++ b/examples/add_person.cc @@ -77,7 +77,7 @@ int main(int argc, char* argv[]) { } // Add an address. - PromptForAddress(address_book.add_persons()); + PromptForAddress(address_book.add_people()); { // Write the new address book back to disk. diff --git a/examples/add_person.py b/examples/add_person.py index 919a1a17..fd81c982 100755 --- a/examples/add_person.py +++ b/examples/add_person.py @@ -50,7 +50,7 @@ except IOError: print sys.argv[1] + ": File not found. Creating a new file." # Add an address. -PromptForAddress(address_book.persons.add()) +PromptForAddress(address_book.people.add()) # Write the new address book back to disk. f = open(sys.argv[1], "wb") diff --git a/examples/addressbook.proto b/examples/addressbook.proto index 64cb7acf..bfdceeaf 100644 --- a/examples/addressbook.proto +++ b/examples/addressbook.proto @@ -29,5 +29,5 @@ message Person { // Our address book file is just one of these. message AddressBook { - repeated Person persons = 1; + repeated Person people = 1; } diff --git a/examples/list_people.cc b/examples/list_people.cc index 3daa3159..68e5666d 100644 --- a/examples/list_people.cc +++ b/examples/list_people.cc @@ -8,8 +8,8 @@ using namespace std; // Iterates though all people in the AddressBook and prints info about them. void ListPeople(const tutorial::AddressBook& address_book) { - for (int i = 0; i < address_book.persons_size(); i++) { - const tutorial::Person& person = address_book.persons(i); + for (int i = 0; i < address_book.people_size(); i++) { + const tutorial::Person& person = address_book.people(i); cout << "Person ID: " << person.id() << endl; cout << " Name: " << person.name() << endl; diff --git a/examples/list_people.py b/examples/list_people.py index e0658493..755de901 100755 --- a/examples/list_people.py +++ b/examples/list_people.py @@ -7,7 +7,7 @@ import sys # Iterates though all people in the AddressBook and prints info about them. def ListPeople(address_book): - for person in address_book.persons: + for person in address_book.people: print "Person ID:", person.id print " Name:", person.name if person.email != "": -- cgit v1.2.3