Commit 55cf8abe authored by Josh Haberman's avatar Josh Haberman

Merge branch 'master' of github.com:google/protobuf

parents cb3caf1e 2cb2358c
...@@ -16,6 +16,7 @@ m4/ltoptions.m4 ...@@ -16,6 +16,7 @@ m4/ltoptions.m4
m4/ltsugar.m4 m4/ltsugar.m4
m4/ltversion.m4 m4/ltversion.m4
m4/lt~obsolete.m4 m4/lt~obsolete.m4
autom4te.cache
# downloaded files # downloaded files
gtest gtest
...@@ -61,3 +62,13 @@ src/test_plugin ...@@ -61,3 +62,13 @@ src/test_plugin
src/testzip.* src/testzip.*
src/zcg*zip src/zcg*zip
ar-lib ar-lib
test-driver
compile
src/**/*.log
src/**/*.trs
# JavaBuild output.
java/target
javanano/target
[submodule "upb"]
path = upb
url = https://github.com/haberman/upb
language: cpp
script: ./autogen.sh && ./configure && make distcheck
notifications:
email: false
...@@ -195,7 +195,6 @@ python_EXTRA_DIST= \ ...@@ -195,7 +195,6 @@ python_EXTRA_DIST= \
python/google/protobuf/internal/wire_format.py \ python/google/protobuf/internal/wire_format.py \
python/google/protobuf/internal/wire_format_test.py \ python/google/protobuf/internal/wire_format_test.py \
python/google/protobuf/internal/__init__.py \ python/google/protobuf/internal/__init__.py \
python/google/protobuf/internal/import_test_package/BUILD \
python/google/protobuf/internal/import_test_package/__init__.py \ python/google/protobuf/internal/import_test_package/__init__.py \
python/google/protobuf/internal/import_test_package/inner.proto \ python/google/protobuf/internal/import_test_package/inner.proto \
python/google/protobuf/internal/import_test_package/outer.proto \ python/google/protobuf/internal/import_test_package/outer.proto \
...@@ -240,15 +239,26 @@ python_EXTRA_DIST= \ ...@@ -240,15 +239,26 @@ python_EXTRA_DIST= \
python/README.txt python/README.txt
ruby_EXTRA_DIST= \ ruby_EXTRA_DIST= \
ruby/ext/defs.c \ ruby/README.md \
ruby/ext/encode_decode.c \ ruby/Rakefile \
ruby/ext/extconf.rb \ ruby/ext/google/protobuf_c/defs.c \
ruby/ext/message.c \ ruby/ext/google/protobuf_c/encode_decode.c \
ruby/ext/protobuf.c \ ruby/ext/google/protobuf_c/extconf.rb \
ruby/ext/protobuf.h \ ruby/ext/google/protobuf_c/map.c \
ruby/ext/repeated_field.c \ ruby/ext/google/protobuf_c/message.c \
ruby/ext/storage.c \ ruby/ext/google/protobuf_c/protobuf.c \
ruby/ext/test.rb ruby/ext/google/protobuf_c/protobuf.h \
ruby/ext/google/protobuf_c/repeated_field.c \
ruby/ext/google/protobuf_c/storage.c \
ruby/ext/google/protobuf_c/upb.c \
ruby/ext/google/protobuf_c/upb.h \
ruby/google-protobuf.gemspec \
ruby/lib/google/protobuf.rb \
ruby/tests/basic.rb \
ruby/tests/stress.rb \
ruby/tests/generated_code.proto \
ruby/tests/generated_code.rb \
ruby/tests/generated_code_test.rb
all_EXTRA_DIST=$(java_EXTRA_DIST) $(python_EXTRA_DIST) $(ruby_EXTRA_DIST) all_EXTRA_DIST=$(java_EXTRA_DIST) $(python_EXTRA_DIST) $(ruby_EXTRA_DIST)
......
Protocol Buffers - Google's data interchange format Protocol Buffers - Google's data interchange format
=================================================== ===================================================
[![Build Status](https://travis-ci.org/google/protobuf.svg?branch=master)](https://travis-ci.org/google/protobuf)
Copyright 2008 Google Inc. Copyright 2008 Google Inc.
https://developers.google.com/protocol-buffers/ https://developers.google.com/protocol-buffers/
......
...@@ -15,12 +15,6 @@ __EOF__ ...@@ -15,12 +15,6 @@ __EOF__
exit 1 exit 1
fi fi
if test -e .git; then
# pull down git submodules.
git submodule init
git submodule update
fi
# Check that gtest is present. Usually it is already there since the # Check that gtest is present. Usually it is already there since the
# directory is set up as an SVN external. # directory is set up as an SVN external.
if test ! -e gtest; then if test ! -e gtest; then
......
...@@ -94,6 +94,7 @@ ...@@ -94,6 +94,7 @@
<arg value="src/test/java/com/google/protobuf/nano/unittest_multiple_nameclash_nano.proto" /> <arg value="src/test/java/com/google/protobuf/nano/unittest_multiple_nameclash_nano.proto" />
<arg value="src/test/java/com/google/protobuf/nano/unittest_enum_class_nano.proto" /> <arg value="src/test/java/com/google/protobuf/nano/unittest_enum_class_nano.proto" />
<arg value="src/test/java/com/google/protobuf/nano/unittest_repeated_merge_nano.proto" /> <arg value="src/test/java/com/google/protobuf/nano/unittest_repeated_merge_nano.proto" />
<arg value="src/test/java/com/google/protobuf/nano/map_test.proto" />
</exec> </exec>
<exec executable="../src/protoc"> <exec executable="../src/protoc">
<arg value="--javanano_out=store_unknown_fields=true,generate_equals=true:target/generated-test-sources" /> <arg value="--javanano_out=store_unknown_fields=true,generate_equals=true:target/generated-test-sources" />
......
...@@ -638,4 +638,44 @@ public final class CodedInputByteBufferNano { ...@@ -638,4 +638,44 @@ public final class CodedInputByteBufferNano {
throw InvalidProtocolBufferNanoException.truncatedMessage(); throw InvalidProtocolBufferNanoException.truncatedMessage();
} }
} }
// Read a primitive type.
Object readPrimitiveField(int type) throws IOException {
switch (type) {
case InternalNano.TYPE_DOUBLE:
return readDouble();
case InternalNano.TYPE_FLOAT:
return readFloat();
case InternalNano.TYPE_INT64:
return readInt64();
case InternalNano.TYPE_UINT64:
return readUInt64();
case InternalNano.TYPE_INT32:
return readInt32();
case InternalNano.TYPE_FIXED64:
return readFixed64();
case InternalNano.TYPE_FIXED32:
return readFixed32();
case InternalNano.TYPE_BOOL:
return readBool();
case InternalNano.TYPE_STRING:
return readString();
case InternalNano.TYPE_BYTES:
return readBytes();
case InternalNano.TYPE_UINT32:
return readUInt32();
case InternalNano.TYPE_ENUM:
return readEnum();
case InternalNano.TYPE_SFIXED32:
return readSFixed32();
case InternalNano.TYPE_SFIXED64:
return readSFixed64();
case InternalNano.TYPE_SINT32:
return readSInt32();
case InternalNano.TYPE_SINT64:
return readSInt64();
default:
throw new IllegalArgumentException("Unknown type " + type);
}
}
} }
...@@ -876,4 +876,128 @@ public final class CodedOutputByteBufferNano { ...@@ -876,4 +876,128 @@ public final class CodedOutputByteBufferNano {
// Note: the right-shift must be arithmetic // Note: the right-shift must be arithmetic
return (n << 1) ^ (n >> 63); return (n << 1) ^ (n >> 63);
} }
static int computeFieldSize(int number, int type, Object object) {
switch (type) {
case InternalNano.TYPE_BOOL:
return computeBoolSize(number, (Boolean) object);
case InternalNano.TYPE_BYTES:
return computeBytesSize(number, (byte[]) object);
case InternalNano.TYPE_STRING:
return computeStringSize(number, (String) object);
case InternalNano.TYPE_FLOAT:
return computeFloatSize(number, (Float) object);
case InternalNano.TYPE_DOUBLE:
return computeDoubleSize(number, (Double) object);
case InternalNano.TYPE_ENUM:
return computeEnumSize(number, (Integer) object);
case InternalNano.TYPE_FIXED32:
return computeFixed32Size(number, (Integer) object);
case InternalNano.TYPE_INT32:
return computeInt32Size(number, (Integer) object);
case InternalNano.TYPE_UINT32:
return computeUInt32Size(number, (Integer) object);
case InternalNano.TYPE_SINT32:
return computeSInt32Size(number, (Integer) object);
case InternalNano.TYPE_SFIXED32:
return computeSFixed32Size(number, (Integer) object);
case InternalNano.TYPE_INT64:
return computeInt64Size(number, (Long) object);
case InternalNano.TYPE_UINT64:
return computeUInt64Size(number, (Long) object);
case InternalNano.TYPE_SINT64:
return computeSInt64Size(number, (Long) object);
case InternalNano.TYPE_FIXED64:
return computeFixed64Size(number, (Long) object);
case InternalNano.TYPE_SFIXED64:
return computeSFixed64Size(number, (Long) object);
case InternalNano.TYPE_MESSAGE:
return computeMessageSize(number, (MessageNano) object);
case InternalNano.TYPE_GROUP:
return computeGroupSize(number, (MessageNano) object);
default:
throw new IllegalArgumentException("Unknown type: " + type);
}
}
void writeField(int number, int type, Object value)
throws IOException {
switch (type) {
case InternalNano.TYPE_DOUBLE:
Double doubleValue = (Double) value;
writeDouble(number, doubleValue);
break;
case InternalNano.TYPE_FLOAT:
Float floatValue = (Float) value;
writeFloat(number, floatValue);
break;
case InternalNano.TYPE_INT64:
Long int64Value = (Long) value;
writeInt64(number, int64Value);
break;
case InternalNano.TYPE_UINT64:
Long uint64Value = (Long) value;
writeUInt64(number, uint64Value);
break;
case InternalNano.TYPE_INT32:
Integer int32Value = (Integer) value;
writeInt32(number, int32Value);
break;
case InternalNano.TYPE_FIXED64:
Long fixed64Value = (Long) value;
writeFixed64(number, fixed64Value);
break;
case InternalNano.TYPE_FIXED32:
Integer fixed32Value = (Integer) value;
writeFixed32(number, fixed32Value);
break;
case InternalNano.TYPE_BOOL:
Boolean boolValue = (Boolean) value;
writeBool(number, boolValue);
break;
case InternalNano.TYPE_STRING:
String stringValue = (String) value;
writeString(number, stringValue);
break;
case InternalNano.TYPE_BYTES:
byte[] bytesValue = (byte[]) value;
writeBytes(number, bytesValue);
break;
case InternalNano.TYPE_UINT32:
Integer uint32Value = (Integer) value;
writeUInt32(number, uint32Value);
break;
case InternalNano.TYPE_ENUM:
Integer enumValue = (Integer) value;
writeEnum(number, enumValue);
break;
case InternalNano.TYPE_SFIXED32:
Integer sfixed32Value = (Integer) value;
writeSFixed32(number, sfixed32Value);
break;
case InternalNano.TYPE_SFIXED64:
Long sfixed64Value = (Long) value;
writeSFixed64(number, sfixed64Value);
break;
case InternalNano.TYPE_SINT32:
Integer sint32Value = (Integer) value;
writeSInt32(number, sint32Value);
break;
case InternalNano.TYPE_SINT64:
Long sint64Value = (Long) value;
writeSInt64(number, sint64Value);
break;
case InternalNano.TYPE_MESSAGE:
MessageNano messageValue = (MessageNano) value;
writeMessage(number, messageValue);
break;
case InternalNano.TYPE_GROUP:
MessageNano groupValue = (MessageNano) value;
writeGroup(number, groupValue);
break;
default:
throw new IOException("Unknown type: " + type);
}
}
} }
...@@ -55,24 +55,24 @@ public class Extension<M extends ExtendableMessageNano<M>, T> { ...@@ -55,24 +55,24 @@ public class Extension<M extends ExtendableMessageNano<M>, T> {
* PrimitiveExtension // for primitive/enum typed extensions * PrimitiveExtension // for primitive/enum typed extensions
*/ */
public static final int TYPE_DOUBLE = 1; public static final int TYPE_DOUBLE = InternalNano.TYPE_DOUBLE;
public static final int TYPE_FLOAT = 2; public static final int TYPE_FLOAT = InternalNano.TYPE_FLOAT;
public static final int TYPE_INT64 = 3; public static final int TYPE_INT64 = InternalNano.TYPE_INT64;
public static final int TYPE_UINT64 = 4; public static final int TYPE_UINT64 = InternalNano.TYPE_UINT64;
public static final int TYPE_INT32 = 5; public static final int TYPE_INT32 = InternalNano.TYPE_INT32;
public static final int TYPE_FIXED64 = 6; public static final int TYPE_FIXED64 = InternalNano.TYPE_FIXED64;
public static final int TYPE_FIXED32 = 7; public static final int TYPE_FIXED32 = InternalNano.TYPE_FIXED32;
public static final int TYPE_BOOL = 8; public static final int TYPE_BOOL = InternalNano.TYPE_BOOL;
public static final int TYPE_STRING = 9; public static final int TYPE_STRING = InternalNano.TYPE_STRING;
public static final int TYPE_GROUP = 10; public static final int TYPE_GROUP = InternalNano.TYPE_GROUP;
public static final int TYPE_MESSAGE = 11; public static final int TYPE_MESSAGE = InternalNano.TYPE_MESSAGE;
public static final int TYPE_BYTES = 12; public static final int TYPE_BYTES = InternalNano.TYPE_BYTES;
public static final int TYPE_UINT32 = 13; public static final int TYPE_UINT32 = InternalNano.TYPE_UINT32;
public static final int TYPE_ENUM = 14; public static final int TYPE_ENUM = InternalNano.TYPE_ENUM;
public static final int TYPE_SFIXED32 = 15; public static final int TYPE_SFIXED32 = InternalNano.TYPE_SFIXED32;
public static final int TYPE_SFIXED64 = 16; public static final int TYPE_SFIXED64 = InternalNano.TYPE_SFIXED64;
public static final int TYPE_SINT32 = 17; public static final int TYPE_SINT32 = InternalNano.TYPE_SINT32;
public static final int TYPE_SINT64 = 18; public static final int TYPE_SINT64 = InternalNano.TYPE_SINT64;
/** /**
* Creates an {@code Extension} of the given message type and tag number. * Creates an {@code Extension} of the given message type and tag number.
...@@ -338,42 +338,7 @@ public class Extension<M extends ExtendableMessageNano<M>, T> { ...@@ -338,42 +338,7 @@ public class Extension<M extends ExtendableMessageNano<M>, T> {
@Override @Override
protected Object readData(CodedInputByteBufferNano input) { protected Object readData(CodedInputByteBufferNano input) {
try { try {
switch (type) { return input.readPrimitiveField(type);
case TYPE_DOUBLE:
return input.readDouble();
case TYPE_FLOAT:
return input.readFloat();
case TYPE_INT64:
return input.readInt64();
case TYPE_UINT64:
return input.readUInt64();
case TYPE_INT32:
return input.readInt32();
case TYPE_FIXED64:
return input.readFixed64();
case TYPE_FIXED32:
return input.readFixed32();
case TYPE_BOOL:
return input.readBool();
case TYPE_STRING:
return input.readString();
case TYPE_BYTES:
return input.readBytes();
case TYPE_UINT32:
return input.readUInt32();
case TYPE_ENUM:
return input.readEnum();
case TYPE_SFIXED32:
return input.readSFixed32();
case TYPE_SFIXED64:
return input.readSFixed64();
case TYPE_SINT32:
return input.readSInt32();
case TYPE_SINT64:
return input.readSInt64();
default:
throw new IllegalArgumentException("Unknown type " + type);
}
} catch (IOException e) { } catch (IOException e) {
throw new IllegalArgumentException("Error reading extension field", e); throw new IllegalArgumentException("Error reading extension field", e);
} }
......
...@@ -30,8 +30,13 @@ ...@@ -30,8 +30,13 @@
package com.google.protobuf.nano; package com.google.protobuf.nano;
import com.google.protobuf.nano.MapFactories.MapFactory;
import java.io.IOException;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.util.Arrays; import java.util.Arrays;
import java.util.Map;
import java.util.Map.Entry;
/** /**
* The classes contained within are used internally by the Protocol Buffer * The classes contained within are used internally by the Protocol Buffer
...@@ -43,6 +48,26 @@ import java.util.Arrays; ...@@ -43,6 +48,26 @@ import java.util.Arrays;
*/ */
public final class InternalNano { public final class InternalNano {
public static final int TYPE_DOUBLE = 1;
public static final int TYPE_FLOAT = 2;
public static final int TYPE_INT64 = 3;
public static final int TYPE_UINT64 = 4;
public static final int TYPE_INT32 = 5;
public static final int TYPE_FIXED64 = 6;
public static final int TYPE_FIXED32 = 7;
public static final int TYPE_BOOL = 8;
public static final int TYPE_STRING = 9;
public static final int TYPE_GROUP = 10;
public static final int TYPE_MESSAGE = 11;
public static final int TYPE_BYTES = 12;
public static final int TYPE_UINT32 = 13;
public static final int TYPE_ENUM = 14;
public static final int TYPE_SFIXED32 = 15;
public static final int TYPE_SFIXED64 = 16;
public static final int TYPE_SINT32 = 17;
public static final int TYPE_SINT64 = 18;
private InternalNano() {} private InternalNano() {}
/** /**
...@@ -329,5 +354,203 @@ public final class InternalNano { ...@@ -329,5 +354,203 @@ public final class InternalNano {
} }
return result; return result;
} }
private static final byte[] EMPTY_BYTES = new byte[0];
private static Object primitiveDefaultValue(int type) {
switch (type) {
case TYPE_BOOL:
return Boolean.FALSE;
case TYPE_BYTES:
return EMPTY_BYTES;
case TYPE_STRING:
return "";
case TYPE_FLOAT:
return Float.valueOf(0);
case TYPE_DOUBLE:
return Double.valueOf(0);
case TYPE_ENUM:
case TYPE_FIXED32:
case TYPE_INT32:
case TYPE_UINT32:
case TYPE_SINT32:
case TYPE_SFIXED32:
return Integer.valueOf(0);
case TYPE_INT64:
case TYPE_UINT64:
case TYPE_SINT64:
case TYPE_FIXED64:
case TYPE_SFIXED64:
return Long.valueOf(0L);
case TYPE_MESSAGE:
case TYPE_GROUP:
default:
throw new IllegalArgumentException(
"Type: " + type + " is not a primitive type.");
}
}
/**
* Merges the map entry into the map field. Note this is only supposed to
* be called by generated messages.
*
* @param map the map field; may be null, in which case a map will be
* instantiated using the {@link MapFactories.MapFactory}
* @param input the input byte buffer
* @param keyType key type, as defined in InternalNano.TYPE_*
* @param valueType value type, as defined in InternalNano.TYPE_*
* @param value an new instance of the value, if the value is a TYPE_MESSAGE;
* otherwise this parameter can be null and will be ignored.
* @param keyTag wire tag for the key
* @param valueTag wire tag for the value
* @return the map field
* @throws IOException
*/
@SuppressWarnings("unchecked")
public static final <K, V> Map<K, V> mergeMapEntry(
CodedInputByteBufferNano input,
Map<K, V> map,
MapFactory mapFactory,
int keyType,
int valueType,
V value,
int keyTag,
int valueTag) throws IOException {
map = mapFactory.forMap(map);
final int length = input.readRawVarint32();
final int oldLimit = input.pushLimit(length);
K key = null;
while (true) {
int tag = input.readTag();
if (tag == 0) {
break;
}
if (tag == keyTag) {
key = (K) input.readPrimitiveField(keyType);
} else if (tag == valueTag) {
if (valueType == TYPE_MESSAGE) {
input.readMessage((MessageNano) value);
} else {
value = (V) input.readPrimitiveField(valueType);
}
} else {
if (!input.skipField(tag)) {
break;
}
}
}
input.checkLastTagWas(0);
input.popLimit(oldLimit);
if (key == null) {
// key can only be primitive types.
key = (K) primitiveDefaultValue(keyType);
}
if (value == null) {
// message type value will be initialized by code-gen.
value = (V) primitiveDefaultValue(valueType);
}
map.put(key, value);
return map;
}
public static <K, V> void serializeMapField(
CodedOutputByteBufferNano output,
Map<K, V> map, int number, int keyType, int valueType)
throws IOException {
for (Entry<K, V> entry: map.entrySet()) {
K key = entry.getKey();
V value = entry.getValue();
if (key == null || value == null) {
throw new IllegalStateException(
"keys and values in maps cannot be null");
}
int entrySize =
CodedOutputByteBufferNano.computeFieldSize(1, keyType, key) +
CodedOutputByteBufferNano.computeFieldSize(2, valueType, value);
output.writeTag(number, WireFormatNano.WIRETYPE_LENGTH_DELIMITED);
output.writeRawVarint32(entrySize);
output.writeField(1, keyType, key);
output.writeField(2, valueType, value);
}
}
public static <K, V> int computeMapFieldSize(
Map<K, V> map, int number, int keyType, int valueType) {
int size = 0;
int tagSize = CodedOutputByteBufferNano.computeTagSize(number);
for (Entry<K, V> entry: map.entrySet()) {
K key = entry.getKey();
V value = entry.getValue();
if (key == null || value == null) {
throw new IllegalStateException(
"keys and values in maps cannot be null");
}
int entrySize =
CodedOutputByteBufferNano.computeFieldSize(1, keyType, key) +
CodedOutputByteBufferNano.computeFieldSize(2, valueType, value);
size += tagSize + entrySize
+ CodedOutputByteBufferNano.computeRawVarint32Size(entrySize);
}
return size;
}
/**
* Checks whether two {@link Map} are equal. We don't use the default equals
* method of {@link Map} because it compares by identity not by content for
* byte arrays.
*/
public static <K, V> boolean equals(Map<K, V> a, Map<K, V> b) {
if (a == b) {
return true;
}
if (a == null) {
return b.size() == 0;
}
if (b == null) {
return a.size() == 0;
}
if (a.size() != b.size()) {
return false;
}
for (Entry<K, V> entry : a.entrySet()) {
if (!b.containsKey(entry.getKey())) {
return false;
}
if (!equalsMapValue(entry.getValue(), b.get(entry.getKey()))) {
return false;
}
}
return true;
}
private static boolean equalsMapValue(Object a, Object b) {
if (a == null || b == null) {
throw new IllegalStateException(
"keys and values in maps cannot be null");
}
if (a instanceof byte[] && b instanceof byte[]) {
return Arrays.equals((byte[]) a, (byte[]) b);
}
return a.equals(b);
}
public static <K, V> int hashCode(Map<K, V> map) {
if (map == null) {
return 0;
}
int result = 0;
for (Entry<K, V> entry : map.entrySet()) {
result += hashCodeForMap(entry.getKey())
^ hashCodeForMap(entry.getValue());
}
return result;
}
private static int hashCodeForMap(Object o) {
if (o instanceof byte[]) {
return Arrays.hashCode((byte[]) o);
}
return o.hashCode();
}
} }
// Protocol Buffers - Google's data interchange format
// Copyright 2013 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.
package com.google.protobuf.nano;
import java.util.HashMap;
import java.util.Map;
/**
* Utility class for maps support.
*/
public final class MapFactories {
public static interface MapFactory {
<K, V> Map<K, V> forMap(Map<K, V> oldMap);
}
// NOTE(liujisi): The factory setter is temporarily marked as package private.
// The way to provide customized implementations of maps for different
// platforms are still under discussion. Mark it as private to avoid exposing
// the API in proto3 alpha release.
/* public */ static void setMapFactory(MapFactory newMapFactory) {
mapFactory = newMapFactory;
}
public static MapFactory getMapFactory() {
return mapFactory;
}
private static class DefaultMapFactory implements MapFactory {
public <K, V> Map<K, V> forMap(Map<K, V> oldMap) {
if (oldMap == null) {
return new HashMap<K, V>();
}
return oldMap;
}
}
private static volatile MapFactory mapFactory = new DefaultMapFactory();
private MapFactories() {}
}
// 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.
syntax = "proto3";
package map_test;
option java_package = "com.google.protobuf.nano";
option java_outer_classname = "MapTestProto";
message TestMap {
message MessageValue {
int32 value = 1;
int32 value2 = 2;
}
enum EnumValue {
FOO = 0;
BAR = 1;
BAZ = 2;
QUX = 3;
}
map<int32, int32> int32_to_int32_field = 1;
map<int32, string> int32_to_string_field = 2;
map<int32, bytes> int32_to_bytes_field = 3;
map<int32, EnumValue> int32_to_enum_field = 4;
map<int32, MessageValue> int32_to_message_field = 5;
map<string, int32> string_to_int32_field = 6;
map<bool, bool> bool_to_bool_field = 7;
// Test all the other primitive types. As the key and value are not coupled in
// the implementation, we do not test all the combinations of key/value pairs,
// so that we can keep the number of test cases manageable
map<uint32, uint32> uint32_to_uint32_field = 11;
map<sint32, sint32> sint32_to_sint32_field = 12;
map<fixed32, fixed32> fixed32_to_fixed32_field = 13;
map<sfixed32, sfixed32> sfixed32_to_sfixed32_field = 14;
map<int64, int64> int64_to_int64_field = 15;
map<uint64, uint64> uint64_to_uint64_field = 16;
map<sint64, sint64> sint64_to_sint64_field = 17;
map<fixed64, fixed64> fixed64_to_fixed64_field = 18;
map<sfixed64, sfixed64> sfixed64_to_sfixed64_field = 19;
}
...@@ -26,7 +26,7 @@ join the Protocol Buffers discussion list and let us know! ...@@ -26,7 +26,7 @@ join the Protocol Buffers discussion list and let us know!
Installation Installation
============ ============
1) Make sure you have Python 2.4 or newer. If in doubt, run: 1) Make sure you have Python 2.6 or newer. If in doubt, run:
$ python -V $ python -V
...@@ -35,7 +35,7 @@ Installation ...@@ -35,7 +35,7 @@ Installation
If you would rather install it manually, you may do so by following If you would rather install it manually, you may do so by following
the instructions on this page: the instructions on this page:
http://peak.telecommunity.com/DevCenter/EasyInstall#installation-instructions https://packaging.python.org/en/latest/installing.html#setup-for-installing-packages
3) Build the C++ code, or install a binary distribution of protoc. If 3) Build the C++ code, or install a binary distribution of protoc. If
you install a binary distribution, make sure that it is the same you install a binary distribution, make sure that it is the same
......
# 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.
# Needs to stay compatible with Python 2.5 due to GAE.
#
# Copyright 2007 Google Inc. All Rights Reserved.
__version__ = '3.0.0-pre'
# Description:
# An example package that contains nested protos that are imported from
# __init__.py. See testPackageInitializationImport in reflection_test.py for
# details.
package(
default_visibility = ["//net/proto2/python/internal:__pkg__"],
)
proto_library(
name = "inner_proto",
srcs = ["inner.proto"],
py_api_version = 2,
)
proto_library(
name = "outer_proto",
srcs = ["outer.proto"],
py_api_version = 2,
deps = [":inner_proto"],
)
py_library(
name = "import_test_package",
srcs = ["__init__.py"],
deps = [":outer_proto"],
)
...@@ -18,13 +18,7 @@ To build this Ruby extension, you will need: ...@@ -18,13 +18,7 @@ To build this Ruby extension, you will need:
* a C compiler * a C compiler
* the upb submodule * the upb submodule
First, ensure that upb/ is checked out: First, install the required Ruby gems:
$ cd .. # top level protobuf directory
$ git submodule init
$ git submodule update
Then install the required Ruby gems:
$ sudo gem install bundler rake rake-compiler rspec rubygems-tasks $ sudo gem install bundler rake rake-compiler rspec rubygems-tasks
...@@ -32,3 +26,7 @@ Then build the Gem: ...@@ -32,3 +26,7 @@ Then build the Gem:
$ rake gem $ rake gem
$ gem install pkg/protobuf-$VERSION.gem $ gem install pkg/protobuf-$VERSION.gem
This gem includes the upb parsing and serialization library as a single-file
amalgamation. It is up-to-date with upb git commit
`535bc2fe2f2b467f59347ffc9449e11e47791257`.
require "rake/extensiontask" require "rake/extensiontask"
require "rake/testtask" require "rake/testtask"
spec = Gem::Specification.new do |s| spec = Gem::Specification.load("google-protobuf.gemspec")
s.name = "protobuf"
s.version = "2.6.2"
s.licenses = ["BSD"]
s.summary = "Protocol Buffers"
s.description = "Protocol Buffers are Google's data interchange format."
s.authors = ["Protobuf Authors"]
s.email = "protobuf@googlegroups.com"
s.files = ["lib/protobuf_c.so", "lib/protobuf.rb"]
end
Rake::ExtensionTask.new("protobuf_c", spec) do |ext| Rake::ExtensionTask.new("protobuf_c", spec) do |ext|
ext.lib_dir = "lib" ext.ext_dir = "ext/google/protobuf_c"
ext.config_script = "extconf.rb" ext.lib_dir = "lib/google"
end end
Rake::TestTask.new(:test => :build) do |t| Rake::TestTask.new(:test => :build) do |t|
t.test_files = FileList["tests/*.rb"] t.test_files = FileList["tests/*.rb"]
end end
task :chmod do
File.chmod(0755, "lib/protobuf_c.so")
end
Gem::PackageTask.new(spec) do |pkg| Gem::PackageTask.new(spec) do |pkg|
end end
task :package => :chmod
task :gem => :chmod
task :build => [:clean, :compile] task :build => [:clean, :compile]
task :default => [:build] task :default => [:build]
......
#!/usr/bin/ruby
require 'mkmf'
$CFLAGS += " -O3 -std=c99 -Wno-unused-function -DNDEBUG "
$objs = ["protobuf.o", "defs.o", "storage.o", "message.o",
"repeated_field.o", "map.o", "encode_decode.o", "upb.o"]
create_makefile("google/protobuf_c")
This diff is collapsed.
...@@ -70,6 +70,35 @@ VALUE Message_alloc(VALUE klass) { ...@@ -70,6 +70,35 @@ VALUE Message_alloc(VALUE klass) {
return ret; return ret;
} }
static VALUE which_oneof_field(MessageHeader* self, const upb_oneofdef* o) {
// If no fields in the oneof, always nil.
if (upb_oneofdef_numfields(o) == 0) {
return Qnil;
}
// Grab the first field in the oneof so we can get its layout info to find the
// oneof_case field.
upb_oneof_iter it;
upb_oneof_begin(&it, o);
assert(!upb_oneof_done(&it));
const upb_fielddef* first_field = upb_oneof_iter_field(&it);
assert(upb_fielddef_containingoneof(first_field) != NULL);
size_t case_ofs =
self->descriptor->layout->
fields[upb_fielddef_index(first_field)].case_offset;
uint32_t oneof_case = *((uint32_t*)(Message_data(self) + case_ofs));
if (oneof_case == ONEOF_CASE_NONE) {
return Qnil;
}
// oneof_case is a field index, so find that field.
const upb_fielddef* f = upb_oneofdef_itof(o, oneof_case);
assert(f != NULL);
return ID2SYM(rb_intern(upb_fielddef_name(f)));
}
/* /*
* call-seq: * call-seq:
* Message.method_missing(*args) * Message.method_missing(*args)
...@@ -82,6 +111,10 @@ VALUE Message_alloc(VALUE klass) { ...@@ -82,6 +111,10 @@ VALUE Message_alloc(VALUE klass) {
* *
* msg.foo = 42 * msg.foo = 42
* puts msg.foo * puts msg.foo
*
* This method also provides read-only accessors for oneofs. If a oneof exists
* with name 'my_oneof', then msg.my_oneof will return a Ruby symbol equal to
* the name of the field in that oneof that is currently set, or nil if none.
*/ */
VALUE Message_method_missing(int argc, VALUE* argv, VALUE _self) { VALUE Message_method_missing(int argc, VALUE* argv, VALUE _self) {
MessageHeader* self; MessageHeader* self;
...@@ -104,6 +137,17 @@ VALUE Message_method_missing(int argc, VALUE* argv, VALUE _self) { ...@@ -104,6 +137,17 @@ VALUE Message_method_missing(int argc, VALUE* argv, VALUE _self) {
name_len--; name_len--;
} }
// Check for a oneof name first.
const upb_oneofdef* o = upb_msgdef_ntoo(self->descriptor->msgdef,
name, name_len);
if (o != NULL) {
if (setter) {
rb_raise(rb_eRuntimeError, "Oneof accessors are read-only.");
}
return which_oneof_field(self, o);
}
// Otherwise, check for a field with that name.
const upb_fielddef* f = upb_msgdef_ntof(self->descriptor->msgdef, const upb_fielddef* f = upb_msgdef_ntof(self->descriptor->msgdef,
name, name_len); name, name_len);
...@@ -139,7 +183,14 @@ int Message_initialize_kwarg(VALUE key, VALUE val, VALUE _self) { ...@@ -139,7 +183,14 @@ int Message_initialize_kwarg(VALUE key, VALUE val, VALUE _self) {
"Unknown field name in initialization map entry."); "Unknown field name in initialization map entry.");
} }
if (upb_fielddef_label(f) == UPB_LABEL_REPEATED) { if (is_map_field(f)) {
if (TYPE(val) != T_HASH) {
rb_raise(rb_eArgError,
"Expected Hash object as initializer value for map field.");
}
VALUE map = layout_get(self->descriptor->layout, Message_data(self), f);
Map_merge_into_self(map, val);
} else if (upb_fielddef_label(f) == UPB_LABEL_REPEATED) {
if (TYPE(val) != T_ARRAY) { if (TYPE(val) != T_ARRAY) {
rb_raise(rb_eArgError, rb_raise(rb_eArgError,
"Expected array as initializer value for repeated field."); "Expected array as initializer value for repeated field.");
...@@ -450,13 +501,15 @@ VALUE build_module_from_enumdesc(EnumDescriptor* enumdesc) { ...@@ -450,13 +501,15 @@ VALUE build_module_from_enumdesc(EnumDescriptor* enumdesc) {
* call-seq: * call-seq:
* Google::Protobuf.deep_copy(obj) => copy_of_obj * Google::Protobuf.deep_copy(obj) => copy_of_obj
* *
* Performs a deep copy of either a RepeatedField instance or a message object, * Performs a deep copy of a RepeatedField instance, a Map instance, or a
* recursively copying its members. * message object, recursively copying its members.
*/ */
VALUE Google_Protobuf_deep_copy(VALUE self, VALUE obj) { VALUE Google_Protobuf_deep_copy(VALUE self, VALUE obj) {
VALUE klass = CLASS_OF(obj); VALUE klass = CLASS_OF(obj);
if (klass == cRepeatedField) { if (klass == cRepeatedField) {
return RepeatedField_deep_copy(obj); return RepeatedField_deep_copy(obj);
} else if (klass == cMap) {
return Map_deep_copy(obj);
} else { } else {
return Message_deep_copy(obj); return Message_deep_copy(obj);
} }
......
...@@ -77,11 +77,14 @@ void Init_protobuf_c() { ...@@ -77,11 +77,14 @@ void Init_protobuf_c() {
DescriptorPool_register(protobuf); DescriptorPool_register(protobuf);
Descriptor_register(protobuf); Descriptor_register(protobuf);
FieldDescriptor_register(protobuf); FieldDescriptor_register(protobuf);
OneofDescriptor_register(protobuf);
EnumDescriptor_register(protobuf); EnumDescriptor_register(protobuf);
MessageBuilderContext_register(internal); MessageBuilderContext_register(internal);
OneofBuilderContext_register(internal);
EnumBuilderContext_register(internal); EnumBuilderContext_register(internal);
Builder_register(internal); Builder_register(internal);
RepeatedField_register(protobuf); RepeatedField_register(protobuf);
Map_register(protobuf);
rb_define_singleton_method(protobuf, "encode", Google_Protobuf_encode, 1); rb_define_singleton_method(protobuf, "encode", Google_Protobuf_encode, 1);
rb_define_singleton_method(protobuf, "decode", Google_Protobuf_decode, 2); rb_define_singleton_method(protobuf, "decode", Google_Protobuf_decode, 2);
......
...@@ -316,6 +316,29 @@ VALUE RepeatedField_deep_copy(VALUE _self) { ...@@ -316,6 +316,29 @@ VALUE RepeatedField_deep_copy(VALUE _self) {
return new_rptfield; return new_rptfield;
} }
/*
* call-seq:
* RepeatedField.to_ary => array
*
* Used when converted implicitly into array, e.g. compared to an Array.
* Also called as a fallback of Object#to_a
*/
VALUE RepeatedField_to_ary(VALUE _self) {
RepeatedField* self = ruby_to_RepeatedField(_self);
upb_fieldtype_t field_type = self->field_type;
size_t elem_size = native_slot_size(field_type);
size_t off = 0;
VALUE ary = rb_ary_new2(self->size);
for (int i = 0; i < self->size; i++, off += elem_size) {
void* mem = ((uint8_t *)self->elements) + off;
VALUE elem = native_slot_get(field_type, self->field_type_class, mem);
rb_ary_push(ary, elem);
}
return ary;
}
/* /*
* call-seq: * call-seq:
* RepeatedField.==(other) => boolean * RepeatedField.==(other) => boolean
...@@ -324,6 +347,10 @@ VALUE RepeatedField_deep_copy(VALUE _self) { ...@@ -324,6 +347,10 @@ VALUE RepeatedField_deep_copy(VALUE _self) {
* element types are equal, their lengths are equal, and each element is equal. * element types are equal, their lengths are equal, and each element is equal.
* Elements are compared as per normal Ruby semantics, by calling their :== * Elements are compared as per normal Ruby semantics, by calling their :==
* methods (or performing a more efficient comparison for primitive types). * methods (or performing a more efficient comparison for primitive types).
*
* Repeated fields with dissimilar element types are never equal, even if value
* comparison (for example, between integers and floats) would have otherwise
* indicated that every element has equal value.
*/ */
VALUE RepeatedField_eq(VALUE _self, VALUE _other) { VALUE RepeatedField_eq(VALUE _self, VALUE _other) {
if (_self == _other) { if (_self == _other) {
...@@ -331,15 +358,9 @@ VALUE RepeatedField_eq(VALUE _self, VALUE _other) { ...@@ -331,15 +358,9 @@ VALUE RepeatedField_eq(VALUE _self, VALUE _other) {
} }
RepeatedField* self = ruby_to_RepeatedField(_self); RepeatedField* self = ruby_to_RepeatedField(_self);
// Inefficient but workable: to support comparison to a generic array, we
// build a temporary RepeatedField of our type.
if (TYPE(_other) == T_ARRAY) { if (TYPE(_other) == T_ARRAY) {
VALUE new_rptfield = RepeatedField_new_this_type(_self); VALUE self_ary = RepeatedField_to_ary(_self);
for (int i = 0; i < RARRAY_LEN(_other); i++) { return rb_equal(self_ary, _other);
VALUE elem = rb_ary_entry(_other, i);
RepeatedField_push(new_rptfield, elem);
}
_other = new_rptfield;
} }
RepeatedField* other = ruby_to_RepeatedField(_other); RepeatedField* other = ruby_to_RepeatedField(_other);
...@@ -397,29 +418,8 @@ VALUE RepeatedField_hash(VALUE _self) { ...@@ -397,29 +418,8 @@ VALUE RepeatedField_hash(VALUE _self) {
* representation computed by its own #inspect method. * representation computed by its own #inspect method.
*/ */
VALUE RepeatedField_inspect(VALUE _self) { VALUE RepeatedField_inspect(VALUE _self) {
RepeatedField* self = ruby_to_RepeatedField(_self); VALUE self_ary = RepeatedField_to_ary(_self);
return rb_funcall(self_ary, rb_intern("inspect"), 0);
VALUE str = rb_str_new2("[");
bool first = true;
upb_fieldtype_t field_type = self->field_type;
VALUE field_type_class = self->field_type_class;
size_t elem_size = native_slot_size(field_type);
size_t off = 0;
for (int i = 0; i < self->size; i++, off += elem_size) {
void* mem = ((uint8_t *)self->elements) + off;
VALUE elem = native_slot_get(field_type, field_type_class, mem);
if (!first) {
str = rb_str_cat2(str, ", ");
} else {
first = false;
}
str = rb_str_append(str, rb_funcall(elem, rb_intern("inspect"), 0));
}
str = rb_str_cat2(str, "]");
return str;
} }
/* /*
...@@ -458,7 +458,7 @@ VALUE RepeatedField_plus(VALUE _self, VALUE list) { ...@@ -458,7 +458,7 @@ VALUE RepeatedField_plus(VALUE _self, VALUE list) {
return dupped; return dupped;
} }
static void validate_type_class(upb_fieldtype_t type, VALUE klass) { void validate_type_class(upb_fieldtype_t type, VALUE klass) {
if (rb_iv_get(klass, kDescriptorInstanceVar) == Qnil) { if (rb_iv_get(klass, kDescriptorInstanceVar) == Qnil) {
rb_raise(rb_eArgError, rb_raise(rb_eArgError,
"Type class has no descriptor. Please pass a " "Type class has no descriptor. Please pass a "
...@@ -590,6 +590,7 @@ void RepeatedField_register(VALUE module) { ...@@ -590,6 +590,7 @@ void RepeatedField_register(VALUE module) {
// Also define #clone so that we don't inherit Object#clone. // Also define #clone so that we don't inherit Object#clone.
rb_define_method(klass, "clone", RepeatedField_dup, 0); rb_define_method(klass, "clone", RepeatedField_dup, 0);
rb_define_method(klass, "==", RepeatedField_eq, 1); rb_define_method(klass, "==", RepeatedField_eq, 1);
rb_define_method(klass, "to_ary", RepeatedField_to_ary, 0);
rb_define_method(klass, "hash", RepeatedField_hash, 0); rb_define_method(klass, "hash", RepeatedField_hash, 0);
rb_define_method(klass, "inspect", RepeatedField_inspect, 0); rb_define_method(klass, "inspect", RepeatedField_inspect, 0);
rb_define_method(klass, "+", RepeatedField_plus, 1); rb_define_method(klass, "+", RepeatedField_plus, 1);
......
This diff is collapsed.
This diff is collapsed.
#!/usr/bin/ruby
require 'mkmf'
upb_path = File.absolute_path(File.dirname($0)) + "/../../../upb"
libs = ["upb_pic", "upb.pb_pic", "upb.json_pic"]
system("cd #{upb_path}; make " + libs.map{|l| "lib/lib#{l}.a"}.join(" "))
$CFLAGS += " -O3 -std=c99 -Wno-unused-function -DNDEBUG"
find_header("upb/upb.h", upb_path) or
raise "Can't find upb headers"
find_library("upb_pic", "upb_msgdef_new", upb_path + "/lib") or
raise "Can't find upb lib"
find_library("upb.pb_pic", "upb_pbdecoder_init", upb_path + "/lib") or
raise "Can't find upb.pb lib"
find_library("upb.json_pic", "upb_json_printer_init", upb_path + "/lib") or
raise "Can't find upb.pb lib"
$objs = ["protobuf.o", "defs.o", "storage.o", "message.o",
"repeated_field.o", "encode_decode.o"]
create_makefile("protobuf_c")
class << Gem::Specification
def find_c_source(dir)
`cd #{dir}; git ls-files "*.c" "*.h" extconf.rb Makefile`.split
.map{|f| "#{dir}/#{f}"}
end
end
Gem::Specification.new do |s|
s.name = "google-protobuf"
s.version = "3.0.0.alpha.2"
s.licenses = ["BSD"]
s.summary = "Protocol Buffers"
s.description = "Protocol Buffers are Google's data interchange format."
s.authors = ["Protobuf Authors"]
s.email = "protobuf@googlegroups.com"
s.require_paths = ["lib"]
s.extensions = ["ext/google/protobuf_c/extconf.rb"]
s.files = ["lib/google/protobuf.rb"] +
# extension C source
find_c_source("ext/google/protobuf_c")
s.test_files = ["tests/basic.rb",
"tests/stress.rb",
"tests/generated_code_test.rb"]
end
...@@ -28,4 +28,4 @@ ...@@ -28,4 +28,4 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
require 'protobuf_c' require 'google/protobuf_c'
This diff is collapsed.
syntax = "proto3";
package A.B.C;
message TestMessage {
optional int32 optional_int32 = 1;
optional int64 optional_int64 = 2;
optional uint32 optional_uint32 = 3;
optional uint64 optional_uint64 = 4;
optional bool optional_bool = 5;
optional double optional_double = 6;
optional float optional_float = 7;
optional string optional_string = 8;
optional bytes optional_bytes = 9;
optional TestEnum optional_enum = 10;
optional TestMessage optional_msg = 11;
repeated int32 repeated_int32 = 21;
repeated int64 repeated_int64 = 22;
repeated uint32 repeated_uint32 = 23;
repeated uint64 repeated_uint64 = 24;
repeated bool repeated_bool = 25;
repeated double repeated_double = 26;
repeated float repeated_float = 27;
repeated string repeated_string = 28;
repeated bytes repeated_bytes = 29;
repeated TestEnum repeated_enum = 30;
repeated TestMessage repeated_msg = 31;
oneof my_oneof {
int32 oneof_int32 = 41;
int64 oneof_int64 = 42;
uint32 oneof_uint32 = 43;
uint64 oneof_uint64 = 44;
bool oneof_bool = 45;
double oneof_double = 46;
float oneof_float = 47;
string oneof_string = 48;
bytes oneof_bytes = 49;
TestEnum oneof_enum = 50;
TestMessage oneof_msg = 51;
}
map<int32, string> map_int32_string = 61;
map<int64, string> map_int64_string = 62;
map<uint32, string> map_uint32_string = 63;
map<uint64, string> map_uint64_string = 64;
map<bool, string> map_bool_string = 65;
map<string, string> map_string_string = 66;
map<string, TestMessage> map_string_msg = 67;
map<string, TestEnum> map_string_enum = 68;
map<string, int32> map_string_int32 = 69;
map<string, bool> map_string_bool = 70;
message NestedMessage {
optional int32 foo = 1;
}
optional NestedMessage nested_message = 80;
}
enum TestEnum {
Default = 0;
A = 1;
B = 2;
C = 3;
}
This diff is collapsed.
#!/usr/bin/ruby
# generated_code.rb is in the same directory as this test.
$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__)))
require 'generated_code'
require 'test/unit'
class GeneratedCodeTest < Test::Unit::TestCase
def test_generated_msg
# just test that we can instantiate the message. The purpose of this test
# is to ensure that the output of the code generator is valid Ruby and
# successfully creates message definitions and classes, not to test every
# aspect of the extension (basic.rb is for that).
m = A::B::C::TestMessage.new()
end
end
#!/usr/bin/ruby #!/usr/bin/ruby
require 'protobuf' require 'google/protobuf'
require 'test/unit' require 'test/unit'
module StressTest module StressTest
......
This diff is collapsed.
...@@ -301,7 +301,7 @@ void ServiceGenerator::GenerateGetPrototype(RequestOrResponse which, ...@@ -301,7 +301,7 @@ void ServiceGenerator::GenerateGetPrototype(RequestOrResponse which,
printer->Print(vars_, printer->Print(vars_,
" default:\n" " default:\n"
" GOOGLE_LOG(FATAL) << \"Bad method index; this should never happen.\";\n" " GOOGLE_LOG(FATAL) << \"Bad method index; this should never happen.\";\n"
" return *reinterpret_cast< ::google::protobuf::Message*>(NULL);\n" " return *static_cast< ::google::protobuf::Message*>(NULL);\n"
" }\n" " }\n"
"}\n" "}\n"
"\n"); "\n");
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -40,7 +40,8 @@ namespace protobuf { ...@@ -40,7 +40,8 @@ namespace protobuf {
namespace compiler { namespace compiler {
namespace ruby { namespace ruby {
class Generator : public google::protobuf::compiler::CodeGenerator { class LIBPROTOC_EXPORT Generator
: public google::protobuf::compiler::CodeGenerator {
virtual bool Generate( virtual bool Generate(
const FileDescriptor* file, const FileDescriptor* file,
const string& parameter, const string& parameter,
......
This diff is collapsed.
This diff is collapsed.
Subproject commit 56913be6bb57f81dbbf7baf9cc9a0a2cd1a36493
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment