Merge pull request #629 from google/master
Integrate changes from upstream/master into csharp-experimental
This commit is contained in:
commit
2ee4b56655
@ -85,15 +85,24 @@ 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
|
||||
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\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
|
||||
|
@ -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
|
||||
|
114
conformance/conformance_ruby.rb
Executable file
114
conformance/conformance_ruby.rb
Executable file
@ -0,0 +1,114 @@
|
||||
#!/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
|
||||
fail "Request didn't have payload"
|
||||
end
|
||||
|
||||
case request.requested_output_format
|
||||
when :UNSPECIFIED
|
||||
fail 'Unspecified output format'
|
||||
|
||||
when :PROTOBUF
|
||||
response.protobuf_payload = test_message.to_proto
|
||||
|
||||
when :JSON
|
||||
response.json_payload = test_message.to_json
|
||||
end
|
||||
rescue StandardError => err
|
||||
response.runtime_error = err.message.encode('utf-8')
|
||||
end
|
||||
|
||||
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
|
||||
serialized_request = STDIN.read(length)
|
||||
if serialized_request.nil? || serialized_request.length != length
|
||||
fail IOError
|
||||
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
|
||||
STDERR.puts("conformance-cpp: request={request.to_json}, " \
|
||||
"response={response.to_json}\n")
|
||||
end
|
||||
|
||||
$test_count += 1
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
loop do
|
||||
unless do_test_io
|
||||
STDERR.puts('conformance-cpp: received EOF from test runner ' \
|
||||
"after #{$test_count} tests, exiting")
|
||||
break
|
||||
end
|
||||
end
|
@ -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.
|
||||
|
@ -219,12 +219,16 @@ void ParseFailureList(const char *filename, vector<string>* failure_list) {
|
||||
int main(int argc, char *argv[]) {
|
||||
int arg = 1;
|
||||
char *program;
|
||||
vector<string> 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<string> 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);
|
||||
|
17
conformance/failure_list_ruby.txt
Normal file
17
conformance/failure_list_ruby.txt
Normal file
@ -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
|
@ -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.addPeople(
|
||||
PromptForAddress(new BufferedReader(new InputStreamReader(System.in)),
|
||||
System.out));
|
||||
|
||||
|
@ -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.getPeopleList()) {
|
||||
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 #: ");
|
||||
|
@ -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_people());
|
||||
|
||||
{
|
||||
// Write the new address book back to disk.
|
||||
|
@ -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.people.add())
|
||||
|
||||
# Write the new address book back to disk.
|
||||
f = open(sys.argv[1], "wb")
|
||||
|
@ -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.people_size(); i++) {
|
||||
const tutorial::Person& person = address_book.people(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:
|
||||
|
@ -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.people:
|
||||
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:
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 <jhaberman@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
@ -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 <jhaberman@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
@ -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 <jhaberman@gmail.com>
|
||||
*
|
||||
* 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 <stdlib.h>
|
||||
@ -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 <jhaberman@gmail.com>
|
||||
*
|
||||
* 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 <setjmp.h>
|
||||
@ -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 <jhaberman@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
@ -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 <jhaberman@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
@ -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 <jhaberman@gmail.com>
|
||||
*
|
||||
* Implementation is heavily inspired by Lua's ltable.c.
|
||||
*/
|
||||
** upb_table Implementation
|
||||
**
|
||||
** Implementation is heavily inspired by Lua's ltable.c.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
@ -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 <jhaberman@gmail.com>
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
@ -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 <jhaberman@gmail.com>
|
||||
*
|
||||
* 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 <errno.h>
|
||||
@ -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 <jhaberman@gmail.com>
|
||||
*
|
||||
* 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 <stdarg.h>
|
||||
|
||||
@ -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 <jhaberman@gmail.com>
|
||||
*
|
||||
* 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 <inttypes.h>
|
||||
#include <stddef.h>
|
||||
@ -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 <jhaberman@gmail.com>
|
||||
*
|
||||
* 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 <stdlib.h>
|
||||
@ -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 <jhaberman@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
@ -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 <jhaberman@gmail.com>
|
||||
* 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 <jhaberman@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
/* 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 <jhaberman@gmail.com>
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
#include <stdint.h>
|
||||
@ -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 <jhaberman@gmail.com>
|
||||
*
|
||||
* 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 <stdlib.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 <jhaberman@gmail.com>
|
||||
*
|
||||
* 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 <jhaberman@gmail.com>
|
||||
*
|
||||
* 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 <jhaberman@gmail.com>
|
||||
*
|
||||
* 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 <stdint.h>
|
||||
#include <string.h>
|
||||
/*
|
||||
* upb - a minimalist implementation of protocol buffers.
|
||||
*
|
||||
* Copyright (c) 2009 Google Inc. See LICENSE for details.
|
||||
* Author: Josh Haberman <jhaberman@gmail.com>
|
||||
*
|
||||
* 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 <jhaberman@gmail.com>
|
||||
*
|
||||
* 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 <jhaberman@gmail.com>
|
||||
*
|
||||
* 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 <jhaberman@gmail.com>
|
||||
*
|
||||
* 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 <jhaberman@gmail.com>
|
||||
*
|
||||
* 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 <jhaberman@gmail.com>
|
||||
*
|
||||
* 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 <jhaberman@gmail.com>
|
||||
*
|
||||
* 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 <jhaberman@gmail.com>
|
||||
*
|
||||
* 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 <jhaberman@gmail.com>
|
||||
*
|
||||
* 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<const upb::FieldDef> 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 <jhaberman@gmail.com>
|
||||
*
|
||||
* Internal-only definitions for the decoder.
|
||||
*/
|
||||
** Internal-only definitions for the decoder.
|
||||
*/
|
||||
|
||||
#ifndef UPB_DECODER_INT_H_
|
||||
#define UPB_DECODER_INT_H_
|
||||
|
||||
#include <stdlib.h>
|
||||
/*
|
||||
* upb - a minimalist implementation of protocol buffers.
|
||||
*
|
||||
* Copyright (c) 2009-2014 Google Inc. See LICENSE for details.
|
||||
* Author: Josh Haberman <jhaberman@gmail.com>
|
||||
*
|
||||
* 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 <jhaberman@gmail.com>
|
||||
*
|
||||
* 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 <jhaberman@gmail.com>
|
||||
*
|
||||
* 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<const Handlers> 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 <jhaberman@gmail.com>
|
||||
*
|
||||
* 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 <jhaberman@gmail.com>
|
||||
*/
|
||||
** 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<const Handlers> 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 <jhaberman@gmail.com>
|
||||
*
|
||||
* 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 <jhaberman@gmail.com>
|
||||
*
|
||||
* 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_
|
||||
|
@ -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 < StandardError; end
|
||||
class ParseError < Error; end
|
||||
end
|
||||
end
|
||||
|
||||
if RUBY_PLATFORM == "java"
|
||||
require 'json'
|
||||
require 'google/protobuf_java'
|
||||
|
@ -5,11 +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"
|
||||
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
|
||||
|
@ -71,15 +71,24 @@ 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/bytestream.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/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 \
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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 "";
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
463
src/google/protobuf/stubs/callback.h
Normal file
463
src/google/protobuf/stubs/callback.h
Normal file
@ -0,0 +1,463 @@
|
||||
#ifndef GOOGLE_PROTOBUF_STUBS_CALLBACK_H_
|
||||
#define GOOGLE_PROTOBUF_STUBS_CALLBACK_H_
|
||||
|
||||
#include <google/protobuf/stubs/macros.h>
|
||||
#include <google/protobuf/stubs/type_traits.h>
|
||||
|
||||
// ===================================================================
|
||||
// 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<typename R, typename A1>
|
||||
class LIBPROTOBUF_EXPORT ResultCallback1 {
|
||||
public:
|
||||
ResultCallback1() {}
|
||||
virtual ~ResultCallback1() {}
|
||||
|
||||
virtual R Run(A1) = 0;
|
||||
|
||||
private:
|
||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ResultCallback1);
|
||||
};
|
||||
|
||||
template<typename R, typename A1, typename A2>
|
||||
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 <typename Class>
|
||||
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 <typename Arg1>
|
||||
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 <typename Class, typename Arg1>
|
||||
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 <typename Arg1, typename Arg2>
|
||||
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 <typename Class, typename Arg1, typename Arg2>
|
||||
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<typename R, typename Arg1>
|
||||
class FunctionResultCallback_0_1 : public ResultCallback1<R, Arg1> {
|
||||
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<typename R, typename P1, typename A1>
|
||||
class FunctionResultCallback_1_1 : public ResultCallback1<R, A1> {
|
||||
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 <typename T>
|
||||
struct InternalConstRef {
|
||||
typedef typename remove_reference<T>::type base_type;
|
||||
typedef const base_type& type;
|
||||
};
|
||||
|
||||
template <typename R, typename T, typename P1, typename P2, typename P3,
|
||||
typename P4, typename P5, typename A1, typename A2>
|
||||
class MethodResultCallback_5_2 : public ResultCallback2<R, A1, A2> {
|
||||
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<P1>::type p1_;
|
||||
typename remove_reference<P2>::type p2_;
|
||||
typename remove_reference<P3>::type p3_;
|
||||
typename remove_reference<P4>::type p4_;
|
||||
typename remove_reference<P5>::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 <typename Class>
|
||||
inline Closure* NewCallback(Class* object, void (Class::*method)()) {
|
||||
return new internal::MethodClosure0<Class>(object, method, true);
|
||||
}
|
||||
|
||||
// See Closure.
|
||||
template <typename Class>
|
||||
inline Closure* NewPermanentCallback(Class* object, void (Class::*method)()) {
|
||||
return new internal::MethodClosure0<Class>(object, method, false);
|
||||
}
|
||||
|
||||
// See Closure.
|
||||
template <typename Arg1>
|
||||
inline Closure* NewCallback(void (*function)(Arg1),
|
||||
Arg1 arg1) {
|
||||
return new internal::FunctionClosure1<Arg1>(function, true, arg1);
|
||||
}
|
||||
|
||||
// See Closure.
|
||||
template <typename Arg1>
|
||||
inline Closure* NewPermanentCallback(void (*function)(Arg1),
|
||||
Arg1 arg1) {
|
||||
return new internal::FunctionClosure1<Arg1>(function, false, arg1);
|
||||
}
|
||||
|
||||
// See Closure.
|
||||
template <typename Class, typename Arg1>
|
||||
inline Closure* NewCallback(Class* object, void (Class::*method)(Arg1),
|
||||
Arg1 arg1) {
|
||||
return new internal::MethodClosure1<Class, Arg1>(object, method, true, arg1);
|
||||
}
|
||||
|
||||
// See Closure.
|
||||
template <typename Class, typename Arg1>
|
||||
inline Closure* NewPermanentCallback(Class* object, void (Class::*method)(Arg1),
|
||||
Arg1 arg1) {
|
||||
return new internal::MethodClosure1<Class, Arg1>(object, method, false, arg1);
|
||||
}
|
||||
|
||||
// See Closure.
|
||||
template <typename Arg1, typename Arg2>
|
||||
inline Closure* NewCallback(void (*function)(Arg1, Arg2),
|
||||
Arg1 arg1, Arg2 arg2) {
|
||||
return new internal::FunctionClosure2<Arg1, Arg2>(
|
||||
function, true, arg1, arg2);
|
||||
}
|
||||
|
||||
// See Closure.
|
||||
template <typename Arg1, typename Arg2>
|
||||
inline Closure* NewPermanentCallback(void (*function)(Arg1, Arg2),
|
||||
Arg1 arg1, Arg2 arg2) {
|
||||
return new internal::FunctionClosure2<Arg1, Arg2>(
|
||||
function, false, arg1, arg2);
|
||||
}
|
||||
|
||||
// See Closure.
|
||||
template <typename Class, typename Arg1, typename Arg2>
|
||||
inline Closure* NewCallback(Class* object, void (Class::*method)(Arg1, Arg2),
|
||||
Arg1 arg1, Arg2 arg2) {
|
||||
return new internal::MethodClosure2<Class, Arg1, Arg2>(
|
||||
object, method, true, arg1, arg2);
|
||||
}
|
||||
|
||||
// See Closure.
|
||||
template <typename Class, typename Arg1, typename Arg2>
|
||||
inline Closure* NewPermanentCallback(
|
||||
Class* object, void (Class::*method)(Arg1, Arg2),
|
||||
Arg1 arg1, Arg2 arg2) {
|
||||
return new internal::MethodClosure2<Class, Arg1, Arg2>(
|
||||
object, method, false, arg1, arg2);
|
||||
}
|
||||
|
||||
// See ResultCallback1
|
||||
template<typename R, typename A1>
|
||||
inline ResultCallback1<R, A1>* NewCallback(R (*function)(A1)) {
|
||||
return new internal::FunctionResultCallback_0_1<R, A1>(function, true);
|
||||
}
|
||||
|
||||
// See ResultCallback1
|
||||
template<typename R, typename A1>
|
||||
inline ResultCallback1<R, A1>* NewPermanentCallback(R (*function)(A1)) {
|
||||
return new internal::FunctionResultCallback_0_1<R, A1>(function, false);
|
||||
}
|
||||
|
||||
// See ResultCallback1
|
||||
template<typename R, typename P1, typename A1>
|
||||
inline ResultCallback1<R, A1>* NewCallback(R (*function)(P1, A1), P1 p1) {
|
||||
return new internal::FunctionResultCallback_1_1<R, P1, A1>(
|
||||
function, true, p1);
|
||||
}
|
||||
|
||||
// See ResultCallback1
|
||||
template<typename R, typename P1, typename A1>
|
||||
inline ResultCallback1<R, A1>* NewPermanentCallback(
|
||||
R (*function)(P1, A1), P1 p1) {
|
||||
return new internal::FunctionResultCallback_1_1<R, P1, A1>(
|
||||
function, false, p1);
|
||||
}
|
||||
|
||||
// See MethodResultCallback_5_2
|
||||
template <typename R, typename T, typename P1, typename P2, typename P3,
|
||||
typename P4, typename P5, typename A1, typename A2>
|
||||
inline ResultCallback2<R, A1, A2>* NewPermanentCallback(
|
||||
T* object, R (T::*function)(P1, P2, P3, P4, P5, A1, A2),
|
||||
typename internal::InternalConstRef<P1>::type p1,
|
||||
typename internal::InternalConstRef<P2>::type p2,
|
||||
typename internal::InternalConstRef<P3>::type p3,
|
||||
typename internal::InternalConstRef<P4>::type p4,
|
||||
typename internal::InternalConstRef<P5>::type p5) {
|
||||
return new internal::MethodResultCallback_5_2<R, T, P1, P2, P3, P4, P5, A1,
|
||||
A2>(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_
|
File diff suppressed because it is too large
Load Diff
235
src/google/protobuf/stubs/logging.h
Normal file
235
src/google/protobuf/stubs/logging.h
Normal file
@ -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 <google/protobuf/stubs/macros.h>
|
||||
#include <google/protobuf/stubs/port.h>
|
||||
|
||||
// ===================================================================
|
||||
// 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<typename T>
|
||||
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<typename T>
|
||||
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_
|
168
src/google/protobuf/stubs/macros.h
Normal file
168
src/google/protobuf/stubs/macros.h
Normal file
@ -0,0 +1,168 @@
|
||||
// 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 <google/protobuf/stubs/port.h>
|
||||
|
||||
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<size_t>(!(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 <bool>
|
||||
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
|
||||
// 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<bool(expr)>
|
||||
//
|
||||
// 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.
|
||||
#endif // __cplusplus >= 201103L
|
||||
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
#endif // GOOGLE_PROTOBUF_MACROS_H__
|
@ -34,6 +34,7 @@
|
||||
#include <math.h>
|
||||
|
||||
#include <google/protobuf/stubs/common.h>
|
||||
#include <google/protobuf/stubs/logging.h>
|
||||
#include <google/protobuf/stubs/mathlimits.h>
|
||||
|
||||
namespace google {
|
||||
|
144
src/google/protobuf/stubs/mutex.h
Normal file
144
src/google/protobuf/stubs/mutex.h
Normal file
@ -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 <google/protobuf/stubs/macros.h>
|
||||
|
||||
// ===================================================================
|
||||
// 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<typename T>
|
||||
class ThreadLocalStorage {
|
||||
public:
|
||||
ThreadLocalStorage() {
|
||||
pthread_key_create(&key_, &ThreadLocalStorage::Delete);
|
||||
}
|
||||
~ThreadLocalStorage() {
|
||||
pthread_key_delete(key_);
|
||||
}
|
||||
T* Get() {
|
||||
T* result = static_cast<T*>(pthread_getspecific(key_));
|
||||
if (result == NULL) {
|
||||
result = new T();
|
||||
pthread_setspecific(key_, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
private:
|
||||
static void Delete(void* value) {
|
||||
delete static_cast<T*>(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_
|
@ -79,6 +79,7 @@
|
||||
#define GOOGLE_PROTOBUF_STUBS_ONCE_H__
|
||||
|
||||
#include <google/protobuf/stubs/atomicops.h>
|
||||
#include <google/protobuf/stubs/callback.h>
|
||||
#include <google/protobuf/stubs/common.h>
|
||||
|
||||
namespace google {
|
||||
|
371
src/google/protobuf/stubs/port.h
Normal file
371
src/google/protobuf/stubs/port.h
Normal file
@ -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 <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <string.h>
|
||||
#if defined(__osf__)
|
||||
// Tru64 lacks stdint.h, but has inttypes.h which defines a superset of
|
||||
// what stdint.h would define.
|
||||
#include <inttypes.h>
|
||||
#elif !defined(_MSC_VER)
|
||||
#include <stdint.h>
|
||||
#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 <sys/param.h> // __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<const uint16 *>(_p))
|
||||
#define GOOGLE_UNALIGNED_LOAD32(_p) (*reinterpret_cast<const uint32 *>(_p))
|
||||
#define GOOGLE_UNALIGNED_LOAD64(_p) (*reinterpret_cast<const uint64 *>(_p))
|
||||
|
||||
#define GOOGLE_UNALIGNED_STORE16(_p, _val) (*reinterpret_cast<uint16 *>(_p) = (_val))
|
||||
#define GOOGLE_UNALIGNED_STORE32(_p, _val) (*reinterpret_cast<uint32 *>(_p) = (_val))
|
||||
#define GOOGLE_UNALIGNED_STORE64(_p, _val) (*reinterpret_cast<uint64 *>(_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 <stdlib.h> // 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 <libkern/OSByteOrder.h>
|
||||
#define bswap_16(x) OSSwapInt16(x)
|
||||
#define bswap_32(x) OSSwapInt32(x)
|
||||
#define bswap_64(x) OSSwapInt64(x)
|
||||
|
||||
#elif defined(__GLIBC__) || defined(__CYGWIN__)
|
||||
#include <byteswap.h> // IWYU pragma: export
|
||||
|
||||
#else
|
||||
|
||||
static inline uint16 bswap_16(uint16 x) {
|
||||
return static_cast<uint16>(((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_
|
236
src/google/protobuf/stubs/scoped_ptr.h
Normal file
236
src/google/protobuf/stubs/scoped_ptr.h
Normal file
@ -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 <google/protobuf/stubs/port.h>
|
||||
|
||||
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 C> class scoped_ptr;
|
||||
template <class C> class scoped_array;
|
||||
|
||||
// A scoped_ptr<T> is like a T*, except that the destructor of scoped_ptr<T>
|
||||
// automatically deletes the pointer it holds (if any).
|
||||
// That is, scoped_ptr<T> owns the T object that it points to.
|
||||
// Like a T*, a scoped_ptr<T> may hold either NULL or a pointer to a T object.
|
||||
//
|
||||
// The size of a scoped_ptr is small:
|
||||
// sizeof(scoped_ptr<C>) == sizeof(C*)
|
||||
template <class C>
|
||||
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 <class C2> bool operator==(scoped_ptr<C2> const& p2) const;
|
||||
template <class C2> bool operator!=(scoped_ptr<C2> const& p2) const;
|
||||
|
||||
// Disallow evil constructors
|
||||
scoped_ptr(const scoped_ptr&);
|
||||
void operator=(const scoped_ptr&);
|
||||
};
|
||||
|
||||
// scoped_array<C> is like scoped_ptr<C>, except that the caller must allocate
|
||||
// with new [] and the destructor deletes objects with delete [].
|
||||
//
|
||||
// As with scoped_ptr<C>, a scoped_array<C> either points to an object
|
||||
// or is NULL. A scoped_array<C> owns the object that it points to.
|
||||
//
|
||||
// Size: sizeof(scoped_array<C>) == sizeof(C*)
|
||||
template <class C>
|
||||
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 <class C2> bool operator==(scoped_array<C2> const& p2) const;
|
||||
template <class C2> bool operator!=(scoped_array<C2> 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_
|
@ -59,9 +59,9 @@
|
||||
#ifndef GOOGLE_PROTOBUF_TYPE_TRAITS_H_
|
||||
#define GOOGLE_PROTOBUF_TYPE_TRAITS_H_
|
||||
|
||||
#include <cstddef> // for NULL
|
||||
#include <utility> // For pair
|
||||
|
||||
#include <google/protobuf/stubs/common.h>
|
||||
#include <google/protobuf/stubs/template_util.h> // For true_type and false_type
|
||||
|
||||
namespace google {
|
||||
|
29
travis.sh
29
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 ..
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user