Added Ruby to conformance tests.
This involved fixing a few important bugs in the Ruby implementation -- mostly cases of mixing upb field types and descriptor types (upb field types do not distinguish between int/sint/fixed/sfixed like descriptor types do). Also added protobuf-specific exceptions so parse errors can be caught specifically. Change-Id: Ib49d3db976900b2c6f3455c8b88af52cfb86e036
This commit is contained in:
parent
fde6e89f99
commit
181c7f2636
@ -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
|
||||
|
111
conformance/conformance_ruby.rb
Executable file
111
conformance/conformance_ruby.rb
Executable file
@ -0,0 +1,111 @@
|
||||
#!/usr/bin/env ruby
|
||||
#
|
||||
# Protocol Buffers - Google's data interchange format
|
||||
# Copyright 2008 Google Inc. All rights reserved.
|
||||
# https://developers.google.com/protocol-buffers/
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
# met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following disclaimer
|
||||
# in the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# * Neither the name of Google Inc. nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
require 'conformance'
|
||||
|
||||
test_count = 0;
|
||||
verbose = false;
|
||||
|
||||
def do_test(request)
|
||||
test_message = Conformance::TestAllTypes.new
|
||||
response = Conformance::ConformanceResponse.new
|
||||
|
||||
begin
|
||||
case request.payload
|
||||
when :protobuf_payload
|
||||
begin
|
||||
test_message = Conformance::TestAllTypes.decode(request.protobuf_payload)
|
||||
rescue Google::Protobuf::ParseError => err
|
||||
response.parse_error = err.message.encode("utf-8")
|
||||
return response
|
||||
end
|
||||
|
||||
when :json_payload
|
||||
test_message = Conformance::TestAllTypes.decode_json(request.json_payload)
|
||||
|
||||
when nil
|
||||
raise "Request didn't have payload.";
|
||||
end
|
||||
|
||||
case request.requested_output_format
|
||||
when :UNSPECIFIED
|
||||
raise "Unspecified output format"
|
||||
|
||||
when :PROTOBUF
|
||||
response.protobuf_payload = Conformance::TestAllTypes.encode(test_message)
|
||||
|
||||
when :JSON
|
||||
response.json_payload = Conformance::TestAllTypes.encode_json(test_message)
|
||||
end
|
||||
rescue Exception => err
|
||||
response.runtime_error = err.message.encode("utf-8") + err.backtrace.join("\n")
|
||||
end
|
||||
|
||||
return response
|
||||
end
|
||||
|
||||
def do_test_io
|
||||
length_bytes = STDIN.read(4)
|
||||
return false if length_bytes.nil?
|
||||
|
||||
length = length_bytes.unpack("V").first
|
||||
serialized_request = STDIN.read(length)
|
||||
if serialized_request.nil? or serialized_request.length != length
|
||||
raise "I/O error"
|
||||
end
|
||||
|
||||
request = Conformance::ConformanceRequest.decode(serialized_request)
|
||||
|
||||
response = do_test(request)
|
||||
|
||||
serialized_response = Conformance::ConformanceResponse.encode(response)
|
||||
STDOUT.write([serialized_response.length].pack("V"))
|
||||
STDOUT.write(serialized_response)
|
||||
STDOUT.flush
|
||||
|
||||
#if verbose
|
||||
# fprintf(stderr, "conformance-cpp: request=%s, response=%s\n",
|
||||
# request.ShortDebugString().c_str(),
|
||||
# response.ShortDebugString().c_str());
|
||||
|
||||
#test_count++;
|
||||
|
||||
return true;
|
||||
end
|
||||
|
||||
while true
|
||||
if not do_test_io()
|
||||
STDERR.puts("conformance-cpp: received EOF from test runner " +
|
||||
"after #{test_count} tests, exiting")
|
||||
exit 0
|
||||
end
|
||||
end
|
@ -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
|
@ -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 < RuntimeError; end
|
||||
class ParseError < Error; end
|
||||
end
|
||||
end
|
||||
|
||||
if RUBY_PLATFORM == "java"
|
||||
require 'json'
|
||||
require 'google/protobuf_java'
|
||||
|
@ -9,7 +9,9 @@ test_version() {
|
||||
"rvm install $version && rvm use $version && \
|
||||
which ruby && \
|
||||
gem install bundler && bundle && \
|
||||
rake test"
|
||||
rake test && \
|
||||
cd ../conformance && \
|
||||
make test_ruby"
|
||||
}
|
||||
|
||||
test_version $1
|
||||
|
@ -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 "";
|
||||
}
|
||||
}
|
||||
|
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