aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Cozzette <acozzette@google.com>2016-11-17 17:04:30 -0800
committerAdam Cozzette <acozzette@google.com>2016-11-17 17:04:30 -0800
commit5d63097fc2b7f405f53d6ca4ad3c1ebd98d80ddd (patch)
tree50d8116271f024e16334785464c794da85f3ce12
parent5a76e633ea9b5adb215e93fdc11e1c0c08b3fc74 (diff)
parentcd315dcbadc02569e145bde16e3f66c2fbb08e31 (diff)
downloadprotobuf-5d63097fc2b7f405f53d6ca4ad3c1ebd98d80ddd.tar.gz
protobuf-5d63097fc2b7f405f53d6ca4ad3c1ebd98d80ddd.tar.bz2
protobuf-5d63097fc2b7f405f53d6ca4ad3c1ebd98d80ddd.zip
Merge branch 'master' into down-integrate-with-msvc-fix
-rw-r--r--BUILD8
-rw-r--r--Makefile.am3
-rw-r--r--cmake/extract_includes.bat.in2
-rw-r--r--composer.json3
-rw-r--r--conformance/failure_list_csharp.txt8
-rw-r--r--csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs12
-rw-r--r--csharp/src/Google.Protobuf.Test/project.json2
-rw-r--r--csharp/src/Google.Protobuf/InvalidProtocolBufferException.cs2
-rw-r--r--csharp/src/Google.Protobuf/JsonFormatter.cs84
-rw-r--r--csharp/src/Google.Protobuf/Reflection/FieldDescriptor.cs2
-rw-r--r--csharp/src/Google.Protobuf/WellKnownTypes/FieldMaskPartial.cs10
-rw-r--r--docs/third_party.md1
-rw-r--r--java/compatibility_tests/v2.5.0/protos/pom.xml2
-rw-r--r--java/core/pom.xml33
-rw-r--r--java/core/src/main/java/com/google/protobuf/ByteBufferWriter.java50
-rw-r--r--java/core/src/main/java/com/google/protobuf/MapFieldLite.java2
-rw-r--r--java/lite/pom.xml32
-rw-r--r--java/pom.xml2
-rw-r--r--java/util/pom.xml22
-rw-r--r--javanano/src/main/java/com/google/protobuf/nano/InternalNano.java4
-rw-r--r--javanano/src/main/java/com/google/protobuf/nano/InvalidProtocolBufferNanoException.java2
-rwxr-xr-xjenkins/buildcmds/pull_request_32.sh2
-rw-r--r--jenkins/docker/Dockerfile1
-rw-r--r--jenkins/docker32/Dockerfile5
-rw-r--r--js/binary/decoder.js37
-rw-r--r--js/binary/decoder_test.js23
-rw-r--r--js/binary/encoder.js29
-rw-r--r--js/package.json2
-rw-r--r--objectivec/GPBCodedInputStream.h21
-rw-r--r--objectivec/GPBCodedInputStream.m8
-rw-r--r--objectivec/GPBMessage.h11
-rw-r--r--objectivec/README.md2
-rw-r--r--php/ext/google/protobuf/array.c127
-rw-r--r--php/ext/google/protobuf/def.c55
-rw-r--r--php/ext/google/protobuf/message.c4
-rw-r--r--php/ext/google/protobuf/protobuf.c1
-rw-r--r--php/ext/google/protobuf/protobuf.h19
-rw-r--r--php/ext/google/protobuf/storage.c24
-rw-r--r--php/ext/google/protobuf/type_check.c139
-rw-r--r--php/src/Google/Protobuf/Internal/GPBUtil.php41
-rw-r--r--php/src/Google/Protobuf/Internal/GPBWire.php47
-rw-r--r--php/src/Google/Protobuf/Internal/InputStream.php66
-rw-r--r--php/src/Google/Protobuf/Internal/Message.php15
-rw-r--r--php/src/Google/Protobuf/Internal/OutputStream.php51
-rw-r--r--php/src/Google/Protobuf/Internal/Type.php175
-rw-r--r--php/src/Google/Protobuf/descriptor.php25
-rw-r--r--php/tests/array_test.php122
-rw-r--r--php/tests/generated_class_test.php74
-rw-r--r--php/tests/google/protobuf/empty.pb.php28
-rw-r--r--php/tests/map_field_test.php56
-rw-r--r--php/tests/php_implementation_test.php148
-rwxr-xr-xphp/tests/test.sh5
-rw-r--r--php/tests/test_base.php38
-rw-r--r--php/tests/test_no_namespace.pb.php34
-rw-r--r--php/tests/test_no_namespace.proto5
-rw-r--r--php/tests/test_util.php121
-rw-r--r--php/tests/well_known_test.php13
-rw-r--r--phpunit.xml1
-rw-r--r--protobuf.bzl24
-rw-r--r--python/README.md2
-rw-r--r--python/google/protobuf/pyext/message.cc4
-rw-r--r--ruby/ext/google/protobuf_c/message.c44
-rw-r--r--ruby/tests/basic.rb10
-rwxr-xr-xruby/travis-test.sh2
-rw-r--r--src/Makefile.am224
-rw-r--r--src/google/protobuf/arena.h1
-rw-r--r--src/google/protobuf/compiler/command_line_interface.cc47
-rw-r--r--src/google/protobuf/compiler/command_line_interface.h25
-rw-r--r--src/google/protobuf/compiler/command_line_interface_unittest.cc38
-rw-r--r--src/google/protobuf/compiler/mock_code_generator.cc8
-rw-r--r--src/google/protobuf/compiler/php/php_generator.cc18
-rw-r--r--src/google/protobuf/repeated_field.h3
-rw-r--r--src/google/protobuf/stubs/atomicops.h10
-rw-r--r--src/google/protobuf/stubs/atomicops_internals_generic_c11_atomic.h (renamed from src/google/protobuf/stubs/atomicops_internals_pnacl.h)6
-rw-r--r--src/google/protobuf/stubs/atomicops_internals_generic_gcc.h10
-rw-r--r--src/google/protobuf/stubs/platform_macros.h4
-rw-r--r--src/google/protobuf/stubs/type_traits.h10
-rw-r--r--src/google/protobuf/util/internal/constants.h8
-rw-r--r--src/google/protobuf/util/internal/protostream_objectsource.cc8
-rw-r--r--src/google/protobuf/util/internal/protostream_objectwriter.cc8
-rw-r--r--src/google/protobuf/util/internal/utility.cc21
-rwxr-xr-xtests.sh31
82 files changed, 1668 insertions, 759 deletions
diff --git a/BUILD b/BUILD
index 3c03bfac..f17c500a 100644
--- a/BUILD
+++ b/BUILD
@@ -577,7 +577,7 @@ py_library(
)
cc_binary(
- name = "internal/_api_implementation.so",
+ name = "python/google/protobuf/internal/_api_implementation.so",
srcs = ["python/google/protobuf/internal/api_implementation.cc"],
copts = COPTS + [
"-DPYTHON_PROTO2_CPP_IMPL_V2",
@@ -591,7 +591,7 @@ cc_binary(
)
cc_binary(
- name = "pyext/_message.so",
+ name = "python/google/protobuf/pyext/_message.so",
srcs = glob([
"python/google/protobuf/pyext/*.cc",
"python/google/protobuf/pyext/*.h",
@@ -653,8 +653,8 @@ py_proto_library(
data = select({
"//conditions:default": [],
":use_fast_cpp_protos": [
- ":internal/_api_implementation.so",
- ":pyext/_message.so",
+ ":python/google/protobuf/internal/_api_implementation.so",
+ ":python/google/protobuf/pyext/_message.so",
],
}),
default_runtime = "",
diff --git a/Makefile.am b/Makefile.am
index 9f7e3ca8..4763d949 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -577,7 +577,6 @@ php_EXTRA_DIST= \
php/src/Google/Protobuf/Internal/DescriptorPool.php \
php/src/Google/Protobuf/Internal/OneofField.php \
php/src/Google/Protobuf/Internal/MapEntry.php \
- php/src/Google/Protobuf/Internal/Type.php \
php/src/Google/Protobuf/Internal/InputStream.php \
php/src/Google/Protobuf/Internal/OutputStream.php \
php/src/Google/Protobuf/Internal/MessageBuilderContext.php \
@@ -600,6 +599,8 @@ php_EXTRA_DIST= \
php/tests/test_include.pb.php \
php/tests/map_field_test.php \
php/tests/test_base.php \
+ php/tests/test_no_namespace.proto \
+ php/tests/test_no_namespace.pb.php \
php/tests/test_util.php \
php/tests/test.proto \
php/tests/test.pb.php \
diff --git a/cmake/extract_includes.bat.in b/cmake/extract_includes.bat.in
index abd70616..4b572bb6 100644
--- a/cmake/extract_includes.bat.in
+++ b/cmake/extract_includes.bat.in
@@ -80,10 +80,10 @@ copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_intern
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_arm_gcc.h include\google\protobuf\stubs\atomicops_internals_arm_gcc.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_arm_qnx.h include\google\protobuf\stubs\atomicops_internals_arm_qnx.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_atomicword_compat.h include\google\protobuf\stubs\atomicops_internals_atomicword_compat.h
+copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_generic_c11_atomic.h include\google\protobuf\stubs\atomicops_internals_generic_c11_atomic.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_generic_gcc.h include\google\protobuf\stubs\atomicops_internals_generic_gcc.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_macosx.h include\google\protobuf\stubs\atomicops_internals_macosx.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_mips_gcc.h include\google\protobuf\stubs\atomicops_internals_mips_gcc.h
-copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_pnacl.h include\google\protobuf\stubs\atomicops_internals_pnacl.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_power.h include\google\protobuf\stubs\atomicops_internals_power.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_ppc_gcc.h include\google\protobuf\stubs\atomicops_internals_ppc_gcc.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_solaris.h include\google\protobuf\stubs\atomicops_internals_solaris.h
diff --git a/composer.json b/composer.json
index 8b73a2b9..6afe71ce 100644
--- a/composer.json
+++ b/composer.json
@@ -17,8 +17,7 @@
},
"files": [
"php/src/Google/Protobuf/descriptor.php",
- "php/src/Google/Protobuf/descriptor_internal.pb.php",
- "php/src/Google/Protobuf/Internal/Type.php"
+ "php/src/Google/Protobuf/descriptor_internal.pb.php"
]
}
}
diff --git a/conformance/failure_list_csharp.txt b/conformance/failure_list_csharp.txt
index dfafbecc..a43519cd 100644
--- a/conformance/failure_list_csharp.txt
+++ b/conformance/failure_list_csharp.txt
@@ -1,6 +1,6 @@
Recommended.JsonInput.FieldNameWithDoubleUnderscores.JsonOutput
+Recommended.JsonInput.FieldNameWithDoubleUnderscores.ProtobufOutput
+Recommended.JsonInput.FieldNameWithDoubleUnderscores.Validator
+Required.JsonInput.FieldNameInLowerCamelCase.Validator
Required.JsonInput.FieldNameInSnakeCase.JsonOutput
-Required.JsonInput.FieldNameWithMixedCases.JsonOutput
-Required.JsonInput.FieldNameWithMixedCases.ProtobufOutput
-Required.JsonInput.FieldNameWithMixedCases.Validator
-Required.JsonInput.OriginalProtoFieldName.JsonOutput
+Required.JsonInput.FieldNameInSnakeCase.ProtobufOutput
diff --git a/csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs b/csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs
index 261ac6a7..302f8143 100644
--- a/csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs
+++ b/csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs
@@ -229,16 +229,16 @@ namespace Google.Protobuf
[Test]
[TestCase("foo_bar", "fooBar")]
[TestCase("bananaBanana", "bananaBanana")]
- [TestCase("BANANABanana", "bananaBanana")]
+ [TestCase("BANANABanana", "BANANABanana")]
[TestCase("simple", "simple")]
- [TestCase("ACTION_AND_ADVENTURE", "actionAndAdventure")]
+ [TestCase("ACTION_AND_ADVENTURE", "ACTIONANDADVENTURE")]
[TestCase("action_and_adventure", "actionAndAdventure")]
[TestCase("kFoo", "kFoo")]
- [TestCase("HTTPServer", "httpServer")]
- [TestCase("CLIENT", "client")]
- public void ToCamelCase(string original, string expected)
+ [TestCase("HTTPServer", "HTTPServer")]
+ [TestCase("CLIENT", "CLIENT")]
+ public void ToJsonName(string original, string expected)
{
- Assert.AreEqual(expected, JsonFormatter.ToCamelCase(original));
+ Assert.AreEqual(expected, JsonFormatter.ToJsonName(original));
}
[Test]
diff --git a/csharp/src/Google.Protobuf.Test/project.json b/csharp/src/Google.Protobuf.Test/project.json
index 87b732c9..3a73bf7a 100644
--- a/csharp/src/Google.Protobuf.Test/project.json
+++ b/csharp/src/Google.Protobuf.Test/project.json
@@ -21,7 +21,7 @@
"dependencies": {
"Google.Protobuf": { "target": "project" },
"NUnit": "3.4.0",
- "dotnet-test-nunit": "3.4.0-alpha-2",
+ "dotnet-test-nunit": "3.4.0-alpha-2"
},
"testRunner": "nunit",
diff --git a/csharp/src/Google.Protobuf/InvalidProtocolBufferException.cs b/csharp/src/Google.Protobuf/InvalidProtocolBufferException.cs
index eeb0f13a..0fbc5306 100644
--- a/csharp/src/Google.Protobuf/InvalidProtocolBufferException.cs
+++ b/csharp/src/Google.Protobuf/InvalidProtocolBufferException.cs
@@ -61,7 +61,7 @@ namespace Google.Protobuf
{
return new InvalidProtocolBufferException(
"While parsing a protocol message, the input ended unexpectedly " +
- "in the middle of a field. This could mean either than the " +
+ "in the middle of a field. This could mean either that the " +
"input has been truncated or that an embedded message " +
"misreported its own length.");
}
diff --git a/csharp/src/Google.Protobuf/JsonFormatter.cs b/csharp/src/Google.Protobuf/JsonFormatter.cs
index d8a814d9..bb1a361e 100644
--- a/csharp/src/Google.Protobuf/JsonFormatter.cs
+++ b/csharp/src/Google.Protobuf/JsonFormatter.cs
@@ -248,87 +248,25 @@ namespace Google.Protobuf
return !first;
}
- /// <summary>
- /// Camel-case converter with added strictness for field mask formatting.
- /// </summary>
- /// <exception cref="InvalidOperationException">The field mask is invalid for JSON representation</exception>
- private static string ToCamelCaseForFieldMask(string input)
+ // Converted from java/core/src/main/java/com/google/protobuf/Descriptors.java
+ internal static string ToJsonName(string name)
{
- for (int i = 0; i < input.Length; i++)
+ StringBuilder result = new StringBuilder(name.Length);
+ bool isNextUpperCase = false;
+ foreach (char ch in name)
{
- char c = input[i];
- if (c >= 'A' && c <= 'Z')
+ if (ch == '_')
{
- throw new InvalidOperationException($"Invalid field mask to be converted to JSON: {input}");
+ isNextUpperCase = true;
}
- if (c == '_' && i < input.Length - 1)
- {
- char next = input[i + 1];
- if (next < 'a' || next > 'z')
- {
- throw new InvalidOperationException($"Invalid field mask to be converted to JSON: {input}");
- }
- }
- }
- return ToCamelCase(input);
- }
-
- // Converted from src/google/protobuf/util/internal/utility.cc ToCamelCase
- internal static string ToCamelCase(string input)
- {
- bool capitalizeNext = false;
- bool wasCap = true;
- bool isCap = false;
- bool firstWord = true;
- StringBuilder result = new StringBuilder(input.Length);
-
- for (int i = 0; i < input.Length; i++, wasCap = isCap)
- {
- isCap = char.IsUpper(input[i]);
- if (input[i] == '_')
+ else if (isNextUpperCase)
{
- capitalizeNext = true;
- if (result.Length != 0)
- {
- firstWord = false;
- }
- continue;
- }
- else if (firstWord)
- {
- // Consider when the current character B is capitalized,
- // first word ends when:
- // 1) following a lowercase: "...aB..."
- // 2) followed by a lowercase: "...ABc..."
- if (result.Length != 0 && isCap &&
- (!wasCap || (i + 1 < input.Length && char.IsLower(input[i + 1]))))
- {
- firstWord = false;
- result.Append(input[i]);
- }
- else
- {
- result.Append(char.ToLowerInvariant(input[i]));
- continue;
- }
- }
- else if (capitalizeNext)
- {
- capitalizeNext = false;
- if (char.IsLower(input[i]))
- {
- result.Append(char.ToUpperInvariant(input[i]));
- continue;
- }
- else
- {
- result.Append(input[i]);
- continue;
- }
+ result.Append(char.ToUpperInvariant(ch));
+ isNextUpperCase = false;
}
else
{
- result.Append(char.ToLowerInvariant(input[i]));
+ result.Append(ch);
}
}
return result.ToString();
diff --git a/csharp/src/Google.Protobuf/Reflection/FieldDescriptor.cs b/csharp/src/Google.Protobuf/Reflection/FieldDescriptor.cs
index 6c6f6ee0..ed15d0e1 100644
--- a/csharp/src/Google.Protobuf/Reflection/FieldDescriptor.cs
+++ b/csharp/src/Google.Protobuf/Reflection/FieldDescriptor.cs
@@ -97,7 +97,7 @@ namespace Google.Protobuf.Reflection
// We could trust the generated code and check whether the type of the property is
// a MapField, but that feels a tad nasty.
this.propertyName = propertyName;
- JsonName = Proto.JsonName == "" ? JsonFormatter.ToCamelCase(Proto.Name) : Proto.JsonName;
+ JsonName = Proto.JsonName == "" ? JsonFormatter.ToJsonName(Proto.Name) : Proto.JsonName;
}
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/FieldMaskPartial.cs b/csharp/src/Google.Protobuf/WellKnownTypes/FieldMaskPartial.cs
index f9cdb8af..0685c21a 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/FieldMaskPartial.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/FieldMaskPartial.cs
@@ -52,7 +52,7 @@ namespace Google.Protobuf.WellKnownTypes
/// </remarks>
/// <param name="paths">Paths in the field mask</param>
/// <param name="diagnosticOnly">Determines the handling of non-normalized values</param>
- /// <exception cref="InvalidOperationException">The represented duration is invalid, and <paramref name="diagnosticOnly"/> is <c>false</c>.</exception>
+ /// <exception cref="InvalidOperationException">The represented field mask is invalid, and <paramref name="diagnosticOnly"/> is <c>false</c>.</exception>
internal static string ToJson(IList<string> paths, bool diagnosticOnly)
{
var firstInvalid = paths.FirstOrDefault(p => !ValidatePath(p));
@@ -60,10 +60,10 @@ namespace Google.Protobuf.WellKnownTypes
{
var writer = new StringWriter();
#if DOTNET35
- var query = paths.Select(JsonFormatter.ToCamelCase);
+ var query = paths.Select(JsonFormatter.ToJsonName);
JsonFormatter.WriteString(writer, string.Join(",", query.ToArray()));
#else
- JsonFormatter.WriteString(writer, string.Join(",", paths.Select(JsonFormatter.ToCamelCase)));
+ JsonFormatter.WriteString(writer, string.Join(",", paths.Select(JsonFormatter.ToJsonName)));
#endif
return writer.ToString();
}
@@ -85,9 +85,9 @@ namespace Google.Protobuf.WellKnownTypes
}
/// <summary>
- /// Camel-case converter with added strictness for field mask formatting.
+ /// Checks whether the given path is valid for a field mask.
/// </summary>
- /// <exception cref="InvalidOperationException">The field mask is invalid for JSON representation</exception>
+ /// <returns>true if the path is valid; false otherwise</returns>
private static bool ValidatePath(string input)
{
for (int i = 0; i < input.Length; i++)
diff --git a/docs/third_party.md b/docs/third_party.md
index 8ec551db..161bc3ca 100644
--- a/docs/third_party.md
+++ b/docs/third_party.md
@@ -83,6 +83,7 @@ These are projects we know about implementing Protocol Buffers for other program
* Scala: https://github.com/SandroGrzicic/ScalaBuff
* Scala: http://trueaccord.github.io/ScalaPB/
* Swift: https://github.com/alexeyxo/protobuf-swift
+* Swift: https://github.com/apple/swift-protobuf/
* Vala: https://launchpad.net/protobuf-vala
* Visual Basic: http://code.google.com/p/protobuf-net/
diff --git a/java/compatibility_tests/v2.5.0/protos/pom.xml b/java/compatibility_tests/v2.5.0/protos/pom.xml
index 24447bdc..a22e91ed 100644
--- a/java/compatibility_tests/v2.5.0/protos/pom.xml
+++ b/java/compatibility_tests/v2.5.0/protos/pom.xml
@@ -28,7 +28,7 @@
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
- <version>3.3</version>
+ <version>3.6.0</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
diff --git a/java/core/pom.xml b/java/core/pom.xml
index 8a83eb4e..cced344e 100644
--- a/java/core/pom.xml
+++ b/java/core/pom.xml
@@ -92,11 +92,34 @@
<!-- Add the generated sources to the build -->
<plugin>
- <artifactId>maven-compiler-plugin</artifactId>
- <configuration>
- <generatedSourcesDirectory>${generated.sources.dir}</generatedSourcesDirectory>
- <generatedTestSourcesDirectory>${generated.testsources.dir}</generatedTestSourcesDirectory>
- </configuration>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>add-generated-sources</id>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>add-source</goal>
+ </goals>
+ <configuration>
+ <sources>
+ <source>${generated.sources.dir}</source>
+ </sources>
+ </configuration>
+ </execution>
+ <execution>
+ <id>add-generated-test-sources</id>
+ <phase>generate-test-sources</phase>
+ <goals>
+ <goal>add-test-source</goal>
+ </goals>
+ <configuration>
+ <sources>
+ <source>${generated.testsources.dir}</source>
+ </sources>
+ </configuration>
+ </execution>
+ </executions>
</plugin>
<!-- OSGI bundle configuration -->
diff --git a/java/core/src/main/java/com/google/protobuf/ByteBufferWriter.java b/java/core/src/main/java/com/google/protobuf/ByteBufferWriter.java
index 0cc38175..6157a52f 100644
--- a/java/core/src/main/java/com/google/protobuf/ByteBufferWriter.java
+++ b/java/core/src/main/java/com/google/protobuf/ByteBufferWriter.java
@@ -33,11 +33,12 @@ package com.google.protobuf;
import static java.lang.Math.max;
import static java.lang.Math.min;
-import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.ref.SoftReference;
+import java.lang.reflect.Field;
import java.nio.ByteBuffer;
+import java.nio.channels.WritableByteChannel;
/**
* Utility class to provide efficient writing of {@link ByteBuffer}s to {@link OutputStream}s.
@@ -75,6 +76,12 @@ final class ByteBufferWriter {
new ThreadLocal<SoftReference<byte[]>>();
/**
+ * This is a hack for GAE, where {@code FileOutputStream} is unavailable.
+ */
+ private static final Class<?> FILE_OUTPUT_STREAM_CLASS = safeGetClass("java.io.FileOutputStream");
+ private static final long CHANNEL_FIELD_OFFSET = getChannelFieldOffset(FILE_OUTPUT_STREAM_CLASS);
+
+ /**
* For testing purposes only. Clears the cached buffer to force a new allocation on the next
* invocation.
*/
@@ -93,10 +100,7 @@ final class ByteBufferWriter {
// Optimized write for array-backed buffers.
// Note that we're taking the risk that a malicious OutputStream could modify the array.
output.write(buffer.array(), buffer.arrayOffset() + buffer.position(), buffer.remaining());
- } else if (output instanceof FileOutputStream) {
- // Use a channel to write out the ByteBuffer. This will automatically empty the buffer.
- ((FileOutputStream) output).getChannel().write(buffer);
- } else {
+ } else if (!writeToChannel(buffer, output)){
// Read all of the data from the buffer to an array.
// TODO(nathanmittler): Consider performance improvements for other "known" stream types.
final byte[] array = getOrCreateBuffer(buffer.remaining());
@@ -142,4 +146,40 @@ final class ByteBufferWriter {
private static void setBuffer(byte[] value) {
BUFFER.set(new SoftReference<byte[]>(value));
}
+
+ private static boolean writeToChannel(ByteBuffer buffer, OutputStream output) throws IOException {
+ if (CHANNEL_FIELD_OFFSET >= 0 && FILE_OUTPUT_STREAM_CLASS.isInstance(output)) {
+ // Use a channel to write out the ByteBuffer. This will automatically empty the buffer.
+ WritableByteChannel channel = null;
+ try {
+ channel = (WritableByteChannel) UnsafeUtil.getObject(output, CHANNEL_FIELD_OFFSET);
+ } catch (ClassCastException e) {
+ // Absorb.
+ }
+ if (channel != null) {
+ channel.write(buffer);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private static Class<?> safeGetClass(String className) {
+ try {
+ return Class.forName(className);
+ } catch (ClassNotFoundException e) {
+ return null;
+ }
+ }
+ private static long getChannelFieldOffset(Class<?> clazz) {
+ try {
+ if (clazz != null && UnsafeUtil.hasUnsafeArrayOperations()) {
+ Field field = clazz.getDeclaredField("channel");
+ return UnsafeUtil.objectFieldOffset(field);
+ }
+ } catch (Throwable e) {
+ // Absorb
+ }
+ return -1;
+ }
}
diff --git a/java/core/src/main/java/com/google/protobuf/MapFieldLite.java b/java/core/src/main/java/com/google/protobuf/MapFieldLite.java
index 3c0ad89a..16b3fefe 100644
--- a/java/core/src/main/java/com/google/protobuf/MapFieldLite.java
+++ b/java/core/src/main/java/com/google/protobuf/MapFieldLite.java
@@ -58,7 +58,7 @@ public final class MapFieldLite<K, V> extends LinkedHashMap<K, V> {
}
@SuppressWarnings({"rawtypes", "unchecked"})
- private static final MapFieldLite EMPTY_MAP_FIELD = new MapFieldLite(Collections.emptyMap());
+ private static final MapFieldLite EMPTY_MAP_FIELD = new MapFieldLite();
static {
EMPTY_MAP_FIELD.makeImmutable();
}
diff --git a/java/lite/pom.xml b/java/lite/pom.xml
index 9862cd94..d7b15097 100644
--- a/java/lite/pom.xml
+++ b/java/lite/pom.xml
@@ -76,10 +76,38 @@
<!-- Only compile a subset of the files -->
<plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>add-generated-sources</id>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>add-source</goal>
+ </goals>
+ <configuration>
+ <sources>
+ <source>${generated.sources.lite.dir}</source>
+ </sources>
+ </configuration>
+ </execution>
+ <execution>
+ <id>add-generated-test-sources</id>
+ <phase>generate-test-sources</phase>
+ <goals>
+ <goal>add-test-source</goal>
+ </goals>
+ <configuration>
+ <sources>
+ <source>${generated.testsources.lite.dir}</source>
+ </sources>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
- <generatedSourcesDirectory>${generated.sources.lite.dir}</generatedSourcesDirectory>
- <generatedTestSourcesDirectory>${generated.testsources.lite.dir}</generatedTestSourcesDirectory>
<includes>
<include>**/AbstractMessageLite.java</include>
<include>**/AbstractParser.java</include>
diff --git a/java/pom.xml b/java/pom.xml
index 881473f3..6789e7c1 100644
--- a/java/pom.xml
+++ b/java/pom.xml
@@ -94,7 +94,7 @@
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
- <version>3.3</version>
+ <version>3.6.0</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
diff --git a/java/util/pom.xml b/java/util/pom.xml
index 6b07bcdf..0ccfc848 100644
--- a/java/util/pom.xml
+++ b/java/util/pom.xml
@@ -79,12 +79,24 @@
</executions>
</plugin>
+ <!-- Add the generated test sources to the build -->
<plugin>
- <artifactId>maven-compiler-plugin</artifactId>
- <configuration>
- <!-- Add the generated test sources to the build -->
- <generatedTestSourcesDirectory>${generated.testsources.dir}</generatedTestSourcesDirectory>
- </configuration>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>add-generated-test-sources</id>
+ <phase>generate-test-sources</phase>
+ <goals>
+ <goal>add-test-source</goal>
+ </goals>
+ <configuration>
+ <sources>
+ <source>${generated.testsources.dir}</source>
+ </sources>
+ </configuration>
+ </execution>
+ </executions>
</plugin>
<!-- Configure the OSGI bundle -->
diff --git a/javanano/src/main/java/com/google/protobuf/nano/InternalNano.java b/javanano/src/main/java/com/google/protobuf/nano/InternalNano.java
index f1263df5..278368a0 100644
--- a/javanano/src/main/java/com/google/protobuf/nano/InternalNano.java
+++ b/javanano/src/main/java/com/google/protobuf/nano/InternalNano.java
@@ -67,8 +67,8 @@ public final class InternalNano {
public static final int TYPE_SINT32 = 17;
public static final int TYPE_SINT64 = 18;
- protected static final Charset UTF_8 = Charset.forName("UTF-8");
- protected static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1");
+ static final Charset UTF_8 = Charset.forName("UTF-8");
+ static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1");
private InternalNano() {}
diff --git a/javanano/src/main/java/com/google/protobuf/nano/InvalidProtocolBufferNanoException.java b/javanano/src/main/java/com/google/protobuf/nano/InvalidProtocolBufferNanoException.java
index 3864d38a..9a83d6d3 100644
--- a/javanano/src/main/java/com/google/protobuf/nano/InvalidProtocolBufferNanoException.java
+++ b/javanano/src/main/java/com/google/protobuf/nano/InvalidProtocolBufferNanoException.java
@@ -48,7 +48,7 @@ public class InvalidProtocolBufferNanoException extends IOException {
static InvalidProtocolBufferNanoException truncatedMessage() {
return new InvalidProtocolBufferNanoException(
"While parsing a protocol message, the input ended unexpectedly " +
- "in the middle of a field. This could mean either than the " +
+ "in the middle of a field. This could mean either that the " +
"input has been truncated or that an embedded message " +
"misreported its own length.");
}
diff --git a/jenkins/buildcmds/pull_request_32.sh b/jenkins/buildcmds/pull_request_32.sh
index 99df2971..bf0fb7ff 100755
--- a/jenkins/buildcmds/pull_request_32.sh
+++ b/jenkins/buildcmds/pull_request_32.sh
@@ -12,5 +12,5 @@
export DOCKERFILE_DIR=jenkins/docker32
export DOCKER_RUN_SCRIPT=jenkins/pull_request_in_docker.sh
export OUTPUT_DIR=testoutput
-export TEST_SET="php_all"
+export TEST_SET="php_all_32"
./jenkins/build_and_run_docker.sh
diff --git a/jenkins/docker/Dockerfile b/jenkins/docker/Dockerfile
index 53ac38f3..03316369 100644
--- a/jenkins/docker/Dockerfile
+++ b/jenkins/docker/Dockerfile
@@ -113,6 +113,7 @@ ENV MVN mvn --batch-mode
RUN cd /tmp && \
git clone https://github.com/google/protobuf.git && \
cd protobuf && \
+ git reset bf379715c93b581eeb078cec1f0dd8a7d79df431 && \
./autogen.sh && \
./configure && \
make -j6 && \
diff --git a/jenkins/docker32/Dockerfile b/jenkins/docker32/Dockerfile
index 73dfd8d5..a36338b4 100644
--- a/jenkins/docker32/Dockerfile
+++ b/jenkins/docker32/Dockerfile
@@ -64,6 +64,7 @@ RUN php -r "unlink('composer-setup.php');"
RUN cd /tmp && \
git clone https://github.com/google/protobuf.git && \
cd protobuf && \
+ git reset 734930f9197b7bc97c3c794c7a949fee2a08c280 && \
ln -sfn /usr/bin/php5.5 /usr/bin/php && \
ln -sfn /usr/bin/php-config5.5 /usr/bin/php-config && \
ln -sfn /usr/bin/phpize5.5 /usr/bin/phpize && \
@@ -83,7 +84,9 @@ RUN wget http://am1.php.net/get/php-5.5.38.tar.bz2/from/this/mirror
RUN mv mirror php-5.5.38.tar.bz2
RUN tar -xvf php-5.5.38.tar.bz2
RUN cd php-5.5.38 && ./configure --enable-maintainer-zts --prefix=/usr/local/php-5.5-zts && \
- make && make install
+ make && make install && make clean && cd ..
+RUN cd php-5.5.38 && ./configure --enable-bcmath --prefix=/usr/local/php-5.5-bc && \
+ make && make install && make clean && cd ..
##################
# Python dependencies
diff --git a/js/binary/decoder.js b/js/binary/decoder.js
index 0e28e17c..36828a73 100644
--- a/js/binary/decoder.js
+++ b/js/binary/decoder.js
@@ -941,11 +941,9 @@ jspb.BinaryDecoder.prototype.readEnum = function() {
/**
* Reads and parses a UTF-8 encoded unicode string from the stream.
- * The code is inspired by maps.vectortown.parse.StreamedDataViewReader, with
- * the exception that the implementation here does not get confused if it
- * encounters characters longer than three bytes. These characters are ignored
- * though, as they are extremely rare: three UTF-8 bytes cover virtually all
- * characters in common use (http://en.wikipedia.org/wiki/UTF-8).
+ * The code is inspired by maps.vectortown.parse.StreamedDataViewReader.
+ * Supports codepoints from U+0000 up to U+10FFFF.
+ * (http://en.wikipedia.org/wiki/UTF-8).
* @param {number} length The length of the string to read.
* @return {string} The decoded string.
*/
@@ -953,30 +951,45 @@ jspb.BinaryDecoder.prototype.readString = function(length) {
var bytes = this.bytes_;
var cursor = this.cursor_;
var end = cursor + length;
- var chars = [];
+ var codeUnits = [];
while (cursor < end) {
var c = bytes[cursor++];
if (c < 128) { // Regular 7-bit ASCII.
- chars.push(c);
+ codeUnits.push(c);
} else if (c < 192) {
// UTF-8 continuation mark. We are out of sync. This
// might happen if we attempted to read a character
- // with more than three bytes.
+ // with more than four bytes.
continue;
} else if (c < 224) { // UTF-8 with two bytes.
var c2 = bytes[cursor++];
- chars.push(((c & 31) << 6) | (c2 & 63));
+ codeUnits.push(((c & 31) << 6) | (c2 & 63));
} else if (c < 240) { // UTF-8 with three bytes.
var c2 = bytes[cursor++];
var c3 = bytes[cursor++];
- chars.push(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
+ codeUnits.push(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
+ } else if (c < 248) { // UTF-8 with 4 bytes.
+ var c2 = bytes[cursor++];
+ var c3 = bytes[cursor++];
+ var c4 = bytes[cursor++];
+ // Characters written on 4 bytes have 21 bits for a codepoint.
+ // We can't fit that on 16bit characters, so we use surrogates.
+ var codepoint = ((c & 7) << 18) | ((c2 & 63) << 12) | ((c3 & 63) << 6) | (c4 & 63);
+ // Surrogates formula from wikipedia.
+ // 1. Subtract 0x10000 from codepoint
+ codepoint -= 0x10000;
+ // 2. Split this into the high 10-bit value and the low 10-bit value
+ // 3. Add 0xD800 to the high value to form the high surrogate
+ // 4. Add 0xDC00 to the low value to form the low surrogate:
+ var low = (codepoint & 1023) + 0xDC00;
+ var high = ((codepoint >> 10) & 1023) + 0xD800;
+ codeUnits.push(high, low)
}
}
-
// String.fromCharCode.apply is faster than manually appending characters on
// Chrome 25+, and generates no additional cons string garbage.
- var result = String.fromCharCode.apply(null, chars);
+ var result = String.fromCharCode.apply(null, codeUnits);
this.cursor_ = cursor;
return result;
};
diff --git a/js/binary/decoder_test.js b/js/binary/decoder_test.js
index ac312648..9f947b99 100644
--- a/js/binary/decoder_test.js
+++ b/js/binary/decoder_test.js
@@ -209,7 +209,30 @@ describe('binaryDecoderTest', function() {
assertEquals(hashC, decoder.readFixedHash64());
assertEquals(hashD, decoder.readFixedHash64());
});
+
+ /**
+ * Test encoding and decoding utf-8.
+ */
+ it('testUtf8', function() {
+ var encoder = new jspb.BinaryEncoder();
+ var ascii = "ASCII should work in 3, 2, 1..."
+ var utf8_two_bytes = "©";
+ var utf8_three_bytes = "❄";
+ var utf8_four_bytes = "😁";
+
+ encoder.writeString(ascii);
+ encoder.writeString(utf8_two_bytes);
+ encoder.writeString(utf8_three_bytes);
+ encoder.writeString(utf8_four_bytes);
+
+ var decoder = jspb.BinaryDecoder.alloc(encoder.end());
+
+ assertEquals(ascii, decoder.readString(ascii.length));
+ assertEquals(utf8_two_bytes, decoder.readString(utf8_two_bytes.length));
+ assertEquals(utf8_three_bytes, decoder.readString(utf8_three_bytes.length));
+ assertEquals(utf8_four_bytes, decoder.readString(utf8_four_bytes.length));
+ });
/**
* Verifies that misuse of the decoder class triggers assertions.
diff --git a/js/binary/encoder.js b/js/binary/encoder.js
index 30a7f2a1..1663bbd4 100644
--- a/js/binary/encoder.js
+++ b/js/binary/encoder.js
@@ -452,19 +452,36 @@ jspb.BinaryEncoder.prototype.writeFixedHash64 = function(hash) {
*/
jspb.BinaryEncoder.prototype.writeString = function(value) {
var oldLength = this.buffer_.length;
-
- // UTF16 to UTF8 conversion loop swiped from goog.crypt.stringToUtf8ByteArray.
+
for (var i = 0; i < value.length; i++) {
+
var c = value.charCodeAt(i);
+
if (c < 128) {
this.buffer_.push(c);
} else if (c < 2048) {
this.buffer_.push((c >> 6) | 192);
this.buffer_.push((c & 63) | 128);
- } else {
- this.buffer_.push((c >> 12) | 224);
- this.buffer_.push(((c >> 6) & 63) | 128);
- this.buffer_.push((c & 63) | 128);
+ } else if (c < 65536) {
+ // Look for surrogates
+ if (c >= 0xD800 && c <= 0xDBFF && i + 1 < value.length) {
+ var second = value.charCodeAt(i + 1);
+ if (second >= 0xDC00 && second <= 0xDFFF) { // low surrogate
+ // http://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
+ c = (c - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;
+
+ this.buffer_.push((c >> 18) | 240);
+ this.buffer_.push(((c >> 12) & 63 ) | 128);
+ this.buffer_.push(((c >> 6) & 63) | 128);
+ this.buffer_.push((c & 63) | 128);
+ i++;
+ }
+ }
+ else {
+ this.buffer_.push((c >> 12) | 224);
+ this.buffer_.push(((c >> 6) & 63) | 128);
+ this.buffer_.push((c & 63) | 128);
+ }
}
}
diff --git a/js/package.json b/js/package.json
index ee4181ff..d3c77eb6 100644
--- a/js/package.json
+++ b/js/package.json
@@ -22,5 +22,5 @@
"url": "https://github.com/google/protobuf/tree/master/js"
},
"author": "Google Protocol Buffers Team",
- "license": "Apache-2.0"
+ "license" : "BSD-3-Clause"
}
diff --git a/objectivec/GPBCodedInputStream.h b/objectivec/GPBCodedInputStream.h
index de27b186..fbe5009c 100644
--- a/objectivec/GPBCodedInputStream.h
+++ b/objectivec/GPBCodedInputStream.h
@@ -218,6 +218,27 @@ CF_EXTERN_C_END
- (size_t)position;
/**
+ * Moves the limit to the given byte offset starting at the current location.
+ *
+ * @exception GPBCodedInputStreamException If the requested bytes exceeed the
+ * current limit.
+ *
+ * @param byteLimit The number of bytes to move the limit, offset to the current
+ * location.
+ *
+ * @return The limit offset before moving the new limit.
+ */
+- (size_t)pushLimit:(size_t)byteLimit;
+
+/**
+ * Moves the limit back to the offset as it was before calling pushLimit:.
+ *
+ * @param oldLimit The number of bytes to move the current limit. Usually this
+ * is the value returned by the pushLimit: method.
+ */
+- (void)popLimit:(size_t)oldLimit;
+
+/**
* Verifies that the last call to -readTag returned the given tag value. This
* is used to verify that a nested group ended with the correct end tag.
*
diff --git a/objectivec/GPBCodedInputStream.m b/objectivec/GPBCodedInputStream.m
index 2b578dd5..e8c8989c 100644
--- a/objectivec/GPBCodedInputStream.m
+++ b/objectivec/GPBCodedInputStream.m
@@ -400,6 +400,14 @@ void GPBCodedInputStreamCheckLastTagWas(GPBCodedInputStreamState *state,
return state_.bufferPos;
}
+- (size_t)pushLimit:(size_t)byteLimit {
+ return GPBCodedInputStreamPushLimit(&state_, byteLimit);
+}
+
+- (void)popLimit:(size_t)oldLimit {
+ GPBCodedInputStreamPopLimit(&state_, oldLimit);
+}
+
- (double)readDouble {
return GPBCodedInputStreamReadDouble(&state_);
}
diff --git a/objectivec/GPBMessage.h b/objectivec/GPBMessage.h
index 0cb74f9f..c07ec888 100644
--- a/objectivec/GPBMessage.h
+++ b/objectivec/GPBMessage.h
@@ -65,9 +65,18 @@ CF_EXTERN_C_END
/**
* Base class that each generated message subclasses from.
+ *
+ * @note While the class support NSSecureCoding, if the message has any
+ * extensions, they will end up reloaded in @c unknownFields as there is
+ * no way for the @c NSCoding plumbing to pass through a
+ * @c GPBExtensionRegistry. To support extensions, instead of passing the
+ * calls off to the Message, simple store the result of @c data, and then
+ * when loading, fetch the data and use
+ * @c +parseFromData:extensionRegistry:error: to provide an extension
+ * registry.
**/
@interface GPBMessage : NSObject<NSSecureCoding, NSCopying>
-
+
// If you add an instance method/property to this class that may conflict with
// fields declared in protos, you need to update objective_helpers.cc. The main
// cases are methods that take no arguments, or setFoo:/hasFoo: type methods.
diff --git a/objectivec/README.md b/objectivec/README.md
index 06118349..7226f0b9 100644
--- a/objectivec/README.md
+++ b/objectivec/README.md
@@ -44,7 +44,7 @@ Add `objectivec/\*.h` & `objectivec/\*.m` except for
If the target is using ARC, remember to turn off ARC (`-fno-objc-arc`) for the
`.m` files.
-The files generated by `protoc` for the `*.proto` files (`\*.pbobjc.h' and
+The files generated by `protoc` for the `*.proto` files (`\*.pbobjc.h` and
`\*.pbobjc.m`) are then also added to the target.
Usage
diff --git a/php/ext/google/protobuf/array.c b/php/ext/google/protobuf/array.c
index 215dcd46..e4a88c39 100644
--- a/php/ext/google/protobuf/array.c
+++ b/php/ext/google/protobuf/array.c
@@ -54,6 +54,16 @@ static zend_function_entry repeated_field_methods[] = {
PHP_ME(RepeatedField, offsetSet, arginfo_offsetSet, ZEND_ACC_PUBLIC)
PHP_ME(RepeatedField, offsetUnset, arginfo_offsetGet, ZEND_ACC_PUBLIC)
PHP_ME(RepeatedField, count, arginfo_void, ZEND_ACC_PUBLIC)
+ PHP_ME(RepeatedField, getIterator, arginfo_void, ZEND_ACC_PUBLIC)
+ ZEND_FE_END
+};
+
+static zend_function_entry repeated_field_iter_methods[] = {
+ PHP_ME(RepeatedFieldIter, rewind, arginfo_void, ZEND_ACC_PUBLIC)
+ PHP_ME(RepeatedFieldIter, current, arginfo_void, ZEND_ACC_PUBLIC)
+ PHP_ME(RepeatedFieldIter, key, arginfo_void, ZEND_ACC_PUBLIC)
+ PHP_ME(RepeatedFieldIter, next, arginfo_void, ZEND_ACC_PUBLIC)
+ PHP_ME(RepeatedFieldIter, valid, arginfo_void, ZEND_ACC_PUBLIC)
ZEND_FE_END
};
@@ -70,11 +80,15 @@ static int repeated_field_has_dimension(zval *object, zval *offset TSRMLS_DC);
static HashTable *repeated_field_get_gc(zval *object, zval ***table,
int *n TSRMLS_DC);
+static zend_object_value repeated_field_iter_create(zend_class_entry *ce TSRMLS_DC);
+static void repeated_field_iter_free(void *object TSRMLS_DC);
+
// -----------------------------------------------------------------------------
// RepeatedField creation/desctruction
// -----------------------------------------------------------------------------
zend_class_entry* repeated_field_type;
+zend_class_entry* repeated_field_iter_type;
zend_object_handlers* repeated_field_handlers;
void repeated_field_init(TSRMLS_D) {
@@ -86,8 +100,8 @@ void repeated_field_init(TSRMLS_D) {
repeated_field_type = zend_register_internal_class(&class_type TSRMLS_CC);
repeated_field_type->create_object = repeated_field_create;
- zend_class_implements(repeated_field_type TSRMLS_CC, 2, spl_ce_ArrayAccess,
- spl_ce_Countable);
+ zend_class_implements(repeated_field_type TSRMLS_CC, 3, spl_ce_ArrayAccess,
+ zend_ce_aggregate, spl_ce_Countable);
repeated_field_handlers = PEMALLOC(zend_object_handlers);
memcpy(repeated_field_handlers, zend_get_std_object_handlers(),
@@ -386,3 +400,112 @@ PHP_METHOD(RepeatedField, count) {
RETURN_LONG(zend_hash_num_elements(HASH_OF(intern->array)));
}
+
+/**
+ * Return the beginning iterator.
+ * This will also be called for: foreach($arr)
+ * @return object Beginning iterator.
+ */
+PHP_METHOD(RepeatedField, getIterator) {
+ zval *iter_php = NULL;
+ MAKE_STD_ZVAL(iter_php);
+ Z_TYPE_P(iter_php) = IS_OBJECT;
+ Z_OBJVAL_P(iter_php) = repeated_field_iter_type->create_object(
+ repeated_field_iter_type TSRMLS_CC);
+
+ RepeatedField *intern = zend_object_store_get_object(getThis() TSRMLS_CC);
+ RepeatedFieldIter *iter = zend_object_store_get_object(iter_php TSRMLS_CC);
+ iter->repeated_field = intern;
+ iter->position = 0;
+
+ RETURN_ZVAL(iter_php, 1, 1);
+}
+
+// -----------------------------------------------------------------------------
+// RepeatedFieldIter creation/desctruction
+// -----------------------------------------------------------------------------
+
+void repeated_field_iter_init(TSRMLS_D) {
+ zend_class_entry class_type;
+ const char* class_name = "Google\\Protobuf\\Internal\\RepeatedFieldIter";
+ INIT_CLASS_ENTRY_EX(class_type, class_name, strlen(class_name),
+ repeated_field_iter_methods);
+
+ repeated_field_iter_type =
+ zend_register_internal_class(&class_type TSRMLS_CC);
+ repeated_field_iter_type->create_object = repeated_field_iter_create;
+
+ zend_class_implements(repeated_field_iter_type TSRMLS_CC, 1,
+ zend_ce_iterator);
+}
+
+static zend_object_value repeated_field_iter_create(
+ zend_class_entry *ce TSRMLS_DC) {
+ zend_object_value retval = {0};
+ RepeatedFieldIter *intern;
+
+ intern = emalloc(sizeof(RepeatedFieldIter));
+ memset(intern, 0, sizeof(RepeatedFieldIter));
+
+ zend_object_std_init(&intern->std, ce TSRMLS_CC);
+ object_properties_init(&intern->std, ce);
+
+ intern->repeated_field = NULL;
+ intern->position = 0;
+
+ retval.handle = zend_objects_store_put(
+ intern, (zend_objects_store_dtor_t)zend_objects_destroy_object,
+ (zend_objects_free_object_storage_t)repeated_field_iter_free,
+ NULL TSRMLS_CC);
+ retval.handlers = zend_get_std_object_handlers();
+
+ return retval;
+}
+
+static void repeated_field_iter_free(void *object TSRMLS_DC) {
+ RepeatedFieldIter *intern = object;
+ zend_object_std_dtor(&intern->std TSRMLS_CC);
+ efree(object);
+}
+
+// -----------------------------------------------------------------------------
+// PHP RepeatedFieldIter Methods
+// -----------------------------------------------------------------------------
+
+PHP_METHOD(RepeatedFieldIter, rewind) {
+ RepeatedFieldIter *intern = zend_object_store_get_object(getThis() TSRMLS_CC);
+ intern->position = 0;
+}
+
+PHP_METHOD(RepeatedFieldIter, current) {
+ RepeatedFieldIter *intern = zend_object_store_get_object(getThis() TSRMLS_CC);
+ RepeatedField *repeated_field = intern->repeated_field;
+
+ long index;
+ void *memory;
+
+ HashTable *table = HASH_OF(repeated_field->array);
+
+ if (zend_hash_index_find(table, intern->position, (void **)&memory) ==
+ FAILURE) {
+ zend_error(E_USER_ERROR, "Element at %ld doesn't exist.\n", index);
+ return;
+ }
+ native_slot_get(repeated_field->type, memory, return_value_ptr TSRMLS_CC);
+}
+
+PHP_METHOD(RepeatedFieldIter, key) {
+ RepeatedFieldIter *intern = zend_object_store_get_object(getThis() TSRMLS_CC);
+ RETURN_LONG(intern->position);
+}
+
+PHP_METHOD(RepeatedFieldIter, next) {
+ RepeatedFieldIter *intern = zend_object_store_get_object(getThis() TSRMLS_CC);
+ ++intern->position;
+}
+
+PHP_METHOD(RepeatedFieldIter, valid) {
+ RepeatedFieldIter *intern = zend_object_store_get_object(getThis() TSRMLS_CC);
+ RETURN_BOOL(zend_hash_num_elements(HASH_OF(intern->repeated_field->array)) >
+ intern->position);
+}
diff --git a/php/ext/google/protobuf/def.c b/php/ext/google/protobuf/def.c
index 156eca07..6ea2cc93 100644
--- a/php/ext/google/protobuf/def.c
+++ b/php/ext/google/protobuf/def.c
@@ -250,28 +250,41 @@ PHP_METHOD(DescriptorPool, getGeneratedPool) {
RETURN_ZVAL(generated_pool_php, 1, 0);
}
-static void convert_to_class_name_inplace(char *proto_name,
- size_t pkg_name_len) {
+static void convert_to_class_name_inplace(char *class_name,
+ const char* fullname,
+ const char* package_name) {
size_t i;
bool first_char = false;
+ size_t pkg_name_len = package_name == NULL ? 0 : strlen(package_name);
- for (i = 0; i <= pkg_name_len + 1; i++) {
- // PHP package uses camel case.
- if (!first_char && proto_name[i] != '.') {
- first_char = true;
- proto_name[i] += 'A' - 'a';
- }
- // php packages are divided by '\'.
- if (proto_name[i] == '.') {
- first_char = false;
- proto_name[i] = '\\';
+ // In php, class name cannot be Empty.
+ if (strcmp("google.protobuf.Empty", fullname) == 0) {
+ fullname = "google.protobuf.GPBEmpty";
+ }
+
+ if (pkg_name_len == 0) {
+ strcpy(class_name, fullname);
+ } else {
+ class_name[0] = '.';
+ strcpy(&class_name[1], fullname);
+ for (i = 0; i <= pkg_name_len + 1; i++) {
+ // PHP package uses camel case.
+ if (!first_char && class_name[i] != '.') {
+ first_char = true;
+ class_name[i] += 'A' - 'a';
+ }
+ // php packages are divided by '\'.
+ if (class_name[i] == '.') {
+ first_char = false;
+ class_name[i] = '\\';
+ }
}
}
// Submessage is concatenated with its containing messages by '_'.
- for (i = pkg_name_len; i < strlen(proto_name); i++) {
- if (proto_name[i] == '.') {
- proto_name[i] = '_';
+ for (i = pkg_name_len; i < strlen(class_name); i++) {
+ if (class_name[i] == '.') {
+ class_name[i] = '_';
}
}
}
@@ -322,13 +335,13 @@ PHP_METHOD(DescriptorPool, internalAddGeneratedFile) {
upb_msgdef_mapentry(upb_downcast_msgdef(def))) { \
break; \
} \
- /* Prepend '.' to package name to make it absolute. */ \
+ /* Prepend '.' to package name to make it absolute. In the 5 additional \
+ * bytes allocated, one for '.', one for trailing 0, and 3 for 'GPB' if \
+ * given message is google.protobuf.Empty.*/ \
const char *fullname = upb_##def_type_lower##_fullname(def_type_lower); \
- char *klass_name = ecalloc(sizeof(char), 2 + strlen(fullname)); \
- klass_name[0] = '.'; \
- strcpy(&klass_name[1], fullname); \
- size_t pkg_name_len = strlen(upb_filedef_package(files[0])); \
- convert_to_class_name_inplace(klass_name, pkg_name_len); \
+ char *klass_name = ecalloc(sizeof(char), 5 + strlen(fullname)); \
+ convert_to_class_name_inplace(klass_name, fullname, \
+ upb_filedef_package(files[0])); \
zend_class_entry **pce; \
if (zend_lookup_class(klass_name, strlen(klass_name), &pce TSRMLS_CC) == \
FAILURE) { \
diff --git a/php/ext/google/protobuf/message.c b/php/ext/google/protobuf/message.c
index cb46031e..d8fbbe11 100644
--- a/php/ext/google/protobuf/message.c
+++ b/php/ext/google/protobuf/message.c
@@ -177,8 +177,8 @@ static zend_object_value message_create(zend_class_entry* ce TSRMLS_DC) {
zend_object_std_init(&msg->std, ce TSRMLS_CC);
object_properties_init(&msg->std, ce);
- layout_init(desc->layout, message_data(msg), msg->std.properties_table
- TSRMLS_CC);
+ layout_init(desc->layout, message_data(msg),
+ msg->std.properties_table TSRMLS_CC);
return_value.handle = zend_objects_store_put(
msg, (zend_objects_store_dtor_t)zend_objects_destroy_object, message_free,
diff --git a/php/ext/google/protobuf/protobuf.c b/php/ext/google/protobuf/protobuf.c
index 019bca29..ea85b999 100644
--- a/php/ext/google/protobuf/protobuf.c
+++ b/php/ext/google/protobuf/protobuf.c
@@ -156,6 +156,7 @@ static PHP_RSHUTDOWN_FUNCTION(protobuf) {
static PHP_MINIT_FUNCTION(protobuf) {
map_field_init(TSRMLS_C);
repeated_field_init(TSRMLS_C);
+ repeated_field_iter_init(TSRMLS_C);
gpb_type_init(TSRMLS_C);
message_init(TSRMLS_C);
descriptor_pool_init(TSRMLS_C);
diff --git a/php/ext/google/protobuf/protobuf.h b/php/ext/google/protobuf/protobuf.h
index 8a1d9261..fb5879dc 100644
--- a/php/ext/google/protobuf/protobuf.h
+++ b/php/ext/google/protobuf/protobuf.h
@@ -39,6 +39,9 @@
#define PHP_PROTOBUF_EXTNAME "protobuf"
#define PHP_PROTOBUF_VERSION "3.1.0a1"
+#define MAX_LENGTH_OF_INT64 20
+#define SIZEOF_INT64 8
+
// -----------------------------------------------------------------------------
// Forward Declaration
// ----------------------------------------------------------------------------
@@ -51,6 +54,7 @@ struct MessageField;
struct MessageHeader;
struct MessageLayout;
struct RepeatedField;
+struct RepeatedFieldIter;
struct MapField;
typedef struct DescriptorPool DescriptorPool;
@@ -61,6 +65,7 @@ typedef struct MessageField MessageField;
typedef struct MessageHeader MessageHeader;
typedef struct MessageLayout MessageLayout;
typedef struct RepeatedField RepeatedField;
+typedef struct RepeatedFieldIter RepeatedFieldIter;
typedef struct MapField MapField;
// -----------------------------------------------------------------------------
@@ -77,6 +82,7 @@ void descriptor_pool_init(TSRMLS_D);
void gpb_type_init(TSRMLS_D);
void map_field_init(TSRMLS_D);
void repeated_field_init(TSRMLS_D);
+void repeated_field_iter_init(TSRMLS_D);
void util_init(TSRMLS_D);
void message_init(TSRMLS_D);
@@ -366,6 +372,12 @@ struct RepeatedField {
// (for message field only).
};
+struct RepeatedFieldIter {
+ zend_object std;
+ RepeatedField* repeated_field;
+ long position;
+};
+
void repeated_field_create_with_type(zend_class_entry* ce,
const upb_fielddef* field,
zval** repeated_field TSRMLS_DC);
@@ -383,6 +395,13 @@ PHP_METHOD(RepeatedField, offsetGet);
PHP_METHOD(RepeatedField, offsetSet);
PHP_METHOD(RepeatedField, offsetUnset);
PHP_METHOD(RepeatedField, count);
+PHP_METHOD(RepeatedField, getIterator);
+
+PHP_METHOD(RepeatedFieldIter, rewind);
+PHP_METHOD(RepeatedFieldIter, current);
+PHP_METHOD(RepeatedFieldIter, key);
+PHP_METHOD(RepeatedFieldIter, next);
+PHP_METHOD(RepeatedFieldIter, valid);
// -----------------------------------------------------------------------------
// Oneof Field.
diff --git a/php/ext/google/protobuf/storage.c b/php/ext/google/protobuf/storage.c
index e94aa319..1d25a91b 100644
--- a/php/ext/google/protobuf/storage.c
+++ b/php/ext/google/protobuf/storage.c
@@ -174,11 +174,31 @@ CASE(FLOAT, DOUBLE, float)
CASE(DOUBLE, DOUBLE, double)
CASE(BOOL, BOOL, int8_t)
CASE(INT32, LONG, int32_t)
-CASE(INT64, LONG, int64_t)
-CASE(UINT64, LONG, uint64_t)
CASE(ENUM, LONG, uint32_t)
#undef CASE
+
+#if SIZEOF_LONG == 4
+#define CASE(upb_type, c_type) \
+ case UPB_TYPE_##upb_type: { \
+ SEPARATE_ZVAL_IF_NOT_REF(cache); \
+ char buffer[MAX_LENGTH_OF_INT64]; \
+ sprintf(buffer, "%lld", DEREF(memory, c_type)); \
+ ZVAL_STRING(*cache, buffer, 1); \
+ return; \
+ }
+#else
+#define CASE(upb_type, c_type) \
+ case UPB_TYPE_##upb_type: { \
+ SEPARATE_ZVAL_IF_NOT_REF(cache); \
+ ZVAL_LONG(*cache, DEREF(memory, c_type)); \
+ return; \
+ }
+#endif
+CASE(UINT64, uint64_t)
+CASE(INT64, int64_t)
+#undef CASE
+
case UPB_TYPE_UINT32: {
// Prepend bit-1 for negative numbers, so that uint32 value will be
// consistent on both 32-bit and 64-bit architectures.
diff --git a/php/ext/google/protobuf/type_check.c b/php/ext/google/protobuf/type_check.c
index c215d72e..d12d0025 100644
--- a/php/ext/google/protobuf/type_check.c
+++ b/php/ext/google/protobuf/type_check.c
@@ -34,6 +34,7 @@
#include "utf8.h"
static zend_class_entry* util_type;
+static const char int64_min_digits[] = "9223372036854775808";
ZEND_BEGIN_ARG_INFO_EX(arg_check_optional, 0, 0, 1)
ZEND_ARG_INFO(1, val)
@@ -78,8 +79,128 @@ void util_init(TSRMLS_D) {
// Type checking/conversion.
// -----------------------------------------------------------------------------
+// This is modified from is_numeric_string in zend_operators.h. The behavior of
+// this function is the same as is_numeric_string, except that this takes
+// int64_t as input instead of long.
+static zend_uchar convert_numeric_string(
+ const char *str, int length, int64_t *lval, double *dval) {
+ const char *ptr;
+ int base = 10, digits = 0, dp_or_e = 0;
+ double local_dval = 0.0;
+ zend_uchar type;
+
+ if (length == 0) {
+ return IS_NULL;
+ }
+
+ while (*str == ' ' || *str == '\t' || *str == '\n' ||
+ *str == '\r' || *str == '\v' || *str == '\f') {
+ str++;
+ length--;
+ }
+ ptr = str;
+
+ if (*ptr == '-' || *ptr == '+') {
+ ptr++;
+ }
+
+ if (ZEND_IS_DIGIT(*ptr)) {
+ // Handle hex numbers
+ // str is used instead of ptr to disallow signs and keep old behavior.
+ if (length > 2 && *str == '0' && (str[1] == 'x' || str[1] == 'X')) {
+ base = 16;
+ ptr += 2;
+ }
+
+ // Skip any leading 0s.
+ while (*ptr == '0') {
+ ptr++;
+ }
+
+ // Count the number of digits. If a decimal point/exponent is found,
+ // it's a double. Otherwise, if there's a dval or no need to check for
+ // a full match, stop when there are too many digits for a int64 */
+ for (type = IS_LONG;
+ !(digits >= MAX_LENGTH_OF_INT64 && dval);
+ digits++, ptr++) {
+check_digits:
+ if (ZEND_IS_DIGIT(*ptr) || (base == 16 && ZEND_IS_XDIGIT(*ptr))) {
+ continue;
+ } else if (base == 10) {
+ if (*ptr == '.' && dp_or_e < 1) {
+ goto process_double;
+ } else if ((*ptr == 'e' || *ptr == 'E') && dp_or_e < 2) {
+ const char *e = ptr + 1;
+
+ if (*e == '-' || *e == '+') {
+ ptr = e++;
+ }
+ if (ZEND_IS_DIGIT(*e)) {
+ goto process_double;
+ }
+ }
+ }
+ break;
+ }
+
+ if (base == 10) {
+ if (digits >= MAX_LENGTH_OF_INT64) {
+ dp_or_e = -1;
+ goto process_double;
+ }
+ } else if (!(digits < SIZEOF_INT64 * 2 ||
+ (digits == SIZEOF_INT64 * 2 && ptr[-digits] <= '7'))) {
+ if (dval) {
+ local_dval = zend_hex_strtod(str, &ptr);
+ }
+ type = IS_DOUBLE;
+ }
+ } else if (*ptr == '.' && ZEND_IS_DIGIT(ptr[1])) {
+process_double:
+ type = IS_DOUBLE;
+
+ // If there's a dval, do the conversion; else continue checking
+ // the digits if we need to check for a full match.
+ if (dval) {
+ local_dval = zend_strtod(str, &ptr);
+ } else if (dp_or_e != -1) {
+ dp_or_e = (*ptr++ == '.') ? 1 : 2;
+ goto check_digits;
+ }
+ } else {
+ return IS_NULL;
+ }
+ if (ptr != str + length) {
+ zend_error(E_NOTICE, "A non well formed numeric value encountered");
+ return 0;
+ }
+
+ if (type == IS_LONG) {
+ if (digits == MAX_LENGTH_OF_INT64 - 1) {
+ int cmp = strcmp(&ptr[-digits], int64_min_digits);
+
+ if (!(cmp < 0 || (cmp == 0 && *str == '-'))) {
+ if (dval) {
+ *dval = zend_strtod(str, NULL);
+ }
+
+ return IS_DOUBLE;
+ }
+ }
+ if (lval) {
+ *lval = strtoll(str, NULL, base);
+ }
+ return IS_LONG;
+ } else {
+ if (dval) {
+ *dval = local_dval;
+ }
+ return IS_DOUBLE;
+ }
+}
+
#define CONVERT_TO_INTEGER(type) \
- static bool convert_long_to_##type(long val, type##_t* type##_value) { \
+ static bool convert_int64_to_##type(int64_t val, type##_t* type##_value) { \
*type##_value = (type##_t)val; \
return true; \
} \
@@ -91,15 +212,15 @@ void util_init(TSRMLS_D) {
\
static bool convert_string_to_##type(const char* val, int len, \
type##_t* type##_value) { \
- long lval; \
+ int64_t lval; \
double dval; \
\
- switch (is_numeric_string(val, len, &lval, &dval, 0)) { \
+ switch (convert_numeric_string(val, len, &lval, &dval)) { \
case IS_DOUBLE: { \
return convert_double_to_##type(dval, type##_value); \
} \
case IS_LONG: { \
- return convert_long_to_##type(lval, type##_value); \
+ return convert_int64_to_##type(lval, type##_value); \
} \
default: \
zend_error(E_USER_ERROR, \
@@ -111,7 +232,7 @@ void util_init(TSRMLS_D) {
bool protobuf_convert_to_##type(zval* from, type##_t* to) { \
switch (Z_TYPE_P(from)) { \
case IS_LONG: { \
- return convert_long_to_##type(Z_LVAL_P(from), to); \
+ return convert_int64_to_##type(Z_LVAL_P(from), to); \
} \
case IS_DOUBLE: { \
return convert_double_to_##type(Z_DVAL_P(from), to); \
@@ -137,7 +258,7 @@ CONVERT_TO_INTEGER(uint64);
#undef CONVERT_TO_INTEGER
#define CONVERT_TO_FLOAT(type) \
- static bool convert_long_to_##type(long val, type* type##_value) { \
+ static bool convert_int64_to_##type(int64_t val, type* type##_value) { \
*type##_value = (type)val; \
return true; \
} \
@@ -149,10 +270,10 @@ CONVERT_TO_INTEGER(uint64);
\
static bool convert_string_to_##type(const char* val, int len, \
type* type##_value) { \
- long lval; \
+ int64_t lval; \
double dval; \
\
- switch (is_numeric_string(val, len, &lval, &dval, 0)) { \
+ switch (convert_numeric_string(val, len, &lval, &dval)) { \
case IS_DOUBLE: { \
*type##_value = (type)dval; \
return true; \
@@ -171,7 +292,7 @@ CONVERT_TO_INTEGER(uint64);
bool protobuf_convert_to_##type(zval* from, type* to) { \
switch (Z_TYPE_P(from)) { \
case IS_LONG: { \
- return convert_long_to_##type(Z_LVAL_P(from), to); \
+ return convert_int64_to_##type(Z_LVAL_P(from), to); \
} \
case IS_DOUBLE: { \
return convert_double_to_##type(Z_DVAL_P(from), to); \
diff --git a/php/src/Google/Protobuf/Internal/GPBUtil.php b/php/src/Google/Protobuf/Internal/GPBUtil.php
index 417a9729..30d7350f 100644
--- a/php/src/Google/Protobuf/Internal/GPBUtil.php
+++ b/php/src/Google/Protobuf/Internal/GPBUtil.php
@@ -37,6 +37,28 @@ use Google\Protobuf\Internal\RepeatedField;
class GPBUtil
{
+ public function divideInt64ToInt32($value, &$high, &$low, $trim = false)
+ {
+ $isNeg = (bccomp($value, 0) < 0);
+ if ($isNeg) {
+ $value = bcsub(0, $value);
+ }
+ $high = (int) bcdiv(bcadd($value, 1), 4294967296);
+ $low = (int) bcmod($value, 4294967296);
+ if ($isNeg) {
+ $high = ~$high;
+ $low = ~$low;
+ $low++;
+ if (!$low) {
+ $high++;
+ }
+ }
+
+ if ($trim) {
+ $high = 0;
+ }
+ }
+
public static function checkString(&$var, $check_utf8)
{
@@ -70,9 +92,14 @@ class GPBUtil
public static function checkUint32(&$var)
{
if (is_numeric($var)) {
- $var = intval($var);
if (PHP_INT_SIZE === 8) {
+ $var = intval($var);
$var |= ((-(($var >> 31) & 0x1)) & ~0xFFFFFFFF);
+ } else {
+ if (bccomp($var, 0x7FFFFFFF) > 0) {
+ $var = bcsub($var, "4294967296");
+ }
+ $var = (int) $var;
}
} else {
trigger_error("Expect integer.", E_USER_ERROR);
@@ -82,7 +109,11 @@ class GPBUtil
public static function checkInt64(&$var)
{
if (is_numeric($var)) {
- $var = intval($var);
+ if (PHP_INT_SIZE == 8) {
+ $var = intval($var);
+ } else {
+ $var = bcdiv($var, 1, 0);
+ }
} else {
trigger_error("Expect integer.", E_USER_ERROR);
}
@@ -91,7 +122,11 @@ class GPBUtil
public static function checkUint64(&$var)
{
if (is_numeric($var)) {
- $var = intval($var);
+ if (PHP_INT_SIZE == 8) {
+ $var = intval($var);
+ } else {
+ $var = bcdiv($var, 1, 0);
+ }
} else {
trigger_error("Expect integer.", E_USER_ERROR);
}
diff --git a/php/src/Google/Protobuf/Internal/GPBWire.php b/php/src/Google/Protobuf/Internal/GPBWire.php
index 0e741e15..7e2c124f 100644
--- a/php/src/Google/Protobuf/Internal/GPBWire.php
+++ b/php/src/Google/Protobuf/Internal/GPBWire.php
@@ -32,10 +32,6 @@
namespace Google\Protobuf\Internal;
-use Google\Protobuf\Internal\GPBUtil;
-use Google\Protobuf\Internal\Int64;
-use Google\Protobuf\Internal\Uint64;
-
class GPBWire
{
@@ -150,20 +146,28 @@ class GPBWire
public static function zigZagEncode64($int64)
{
- $a = $int64->copy()->leftShift(1);
- $b = $int64->copy()->rightShift(63);
- $result = $a->bitXor($b);
- $uint64 = Uint64::newValue($result->high, $result->low);
- return $uint64;
+ if (PHP_INT_SIZE == 4) {
+ if (bccomp($int64, 0) >= 0) {
+ return bcmul($int64, 2);
+ } else {
+ return bcsub(bcmul(bcsub(0, $int64), 2), 1);
+ }
+ } else {
+ return ($int64 << 1) ^ ($int64 >> 63);
+ }
}
public static function zigZagDecode64($uint64)
{
- $a = $uint64->copy()->rightShift(1);
- $b = $uint64->oddMask();
- $result = $a->bitXor($b);
- $int64 = Int64::newValue($result->high, $result->low);
- return $int64;
+ if (PHP_INT_SIZE == 4) {
+ if (bcmod($uint64, 2) == 0) {
+ return bcdiv($uint64, 2, 0);
+ } else {
+ return bcsub(0, bcdiv(bcadd($uint64, 1), 2, 0));
+ }
+ } else {
+ return (($uint64 >> 1) & 0x7FFFFFFFFFFFFFFF) ^ (-($uint64 & 1));
+ }
}
public static function readInt32(&$input, &$value)
@@ -227,11 +231,7 @@ class GPBWire
public static function readSfixed64(&$input, &$value)
{
- if (!self::readFixed64($input, $value)) {
- return false;
- }
- $value = Int64::newValue($value->high, $value->low);
- return true;
+ return $input->readLittleEndian64($value);
}
public static function readFloat(&$input, &$value)
@@ -259,7 +259,7 @@ class GPBWire
if (!$input->readVarint64($value)) {
return false;
}
- if ($value->high === 0 && $value->low === 0) {
+ if ($value == 0) {
$value = false;
} else {
$value = true;
@@ -324,8 +324,8 @@ class GPBWire
public static function writeSint64(&$output, $value)
{
- $value = GPBWire::zigZagEncode64(GPBUtil::Int64($value));
- return $output->writeVarint64($value->toInteger());
+ $value = GPBWire::zigZagEncode64($value);
+ return $output->writeVarint64($value);
}
public static function writeFixed32(&$output, $value)
@@ -431,9 +431,8 @@ class GPBWire
public static function sint64Size($value)
{
- $value = GPBUtil::Int64($value);
$value = self::zigZagEncode64($value);
- return self::varint64Size($value->toInteger());
+ return self::varint64Size($value);
}
public static function varint64Size($value)
diff --git a/php/src/Google/Protobuf/Internal/InputStream.php b/php/src/Google/Protobuf/Internal/InputStream.php
index 18d07075..6d6c74e9 100644
--- a/php/src/Google/Protobuf/Internal/InputStream.php
+++ b/php/src/Google/Protobuf/Internal/InputStream.php
@@ -34,6 +34,24 @@ namespace Google\Protobuf\Internal;
use Google\Protobuf\Internal\Uint64;
+function combineInt32ToInt64($high, $low)
+{
+ $isNeg = $high < 0;
+ if ($isNeg) {
+ $high = ~$high;
+ $low = ~$low;
+ $low++;
+ if (!$low) {
+ $high++;
+ }
+ }
+ $result = bcadd(bcmul($high, 4294967296), $low);
+ if ($isNeg) {
+ $result = bcsub(0, $result);
+ }
+ return $result;
+}
+
class InputStream
{
@@ -116,11 +134,23 @@ class InputStream
if (!$this->readVarint64($var)) {
return false;
}
- $var = $var->toInteger() & 0xFFFFFFFF;
+
+ if (PHP_INT_SIZE == 4) {
+ $var = bcmod($var, 4294967296);
+ } else {
+ $var &= 0xFFFFFFFF;
+ }
+
// Convert large uint32 to int32.
- if (PHP_INT_SIZE === 8 && ($var > 0x7FFFFFFF)) {
- $var = $var | (0xFFFFFFFF << 32);
+ if ($var > 0x7FFFFFFF) {
+ if (PHP_INT_SIZE === 8) {
+ $var = $var | (0xFFFFFFFF << 32);
+ } else {
+ $var = bcsub($var, 4294967296);
+ }
}
+
+ $var = intval($var);
return true;
}
@@ -130,7 +160,8 @@ class InputStream
*/
public function readVarint64(&$var)
{
- $result = new Uint64(0);
+ $high = 0;
+ $low = 0;
$count = 0;
$b = 0;
@@ -142,12 +173,27 @@ class InputStream
return false;
}
$b = ord($this->buffer[$this->current]);
- $result->bitOr((new Uint64($b & 0x7F))->leftShift(7 * $count));
+ $bits = 7 * $count;
+ if ($bits >= 32) {
+ $high |= (($b & 0x7F) << ($bits - 32));
+ } else if ($bits > 25){
+ $high_bits = $bits - 25;
+ $low = ($low | (($b & 0x7F) << $bits)) & (int) 0xFFFFFFFF;
+ $high = $b & ((0x1 << $high_bits) -1);
+ } else {
+ $low |= (($b & 0x7F) << $bits);
+ }
+
$this->advance(1);
$count += 1;
} while ($b & 0x80);
- $var = $result;
+ if (PHP_INT_SIZE == 4) {
+ $var = combineInt32ToInt64($high, $low);
+ } else {
+ $var = ($high & 0xFFFFFFFF) << 32 |
+ ($low & 0xFFFFFFFF);
+ }
return true;
}
@@ -161,7 +207,7 @@ class InputStream
if (!$this->readVarint64($var)) {
return false;
}
- $var = $var->toInteger();
+ $var = (int)$var;
return true;
}
@@ -197,7 +243,11 @@ class InputStream
return false;
}
$high = unpack('V', $data)[1];
- $var = Uint64::newValue($high, $low);
+ if (PHP_INT_SIZE == 4) {
+ $var = combineInt32ToInt64($high, $low);
+ } else {
+ $var = ($high << 32) | $low;
+ }
return true;
}
diff --git a/php/src/Google/Protobuf/Internal/Message.php b/php/src/Google/Protobuf/Internal/Message.php
index 7bdc6a8c..3d1f1598 100644
--- a/php/src/Google/Protobuf/Internal/Message.php
+++ b/php/src/Google/Protobuf/Internal/Message.php
@@ -125,6 +125,16 @@ class Message
$oneof = $this->desc->getOneofDecl()[$field->getOneofIndex()];
$oneof_name = $oneof->getName();
$this->$oneof_name = new OneofField($oneof);
+ } else if ($field->getLabel() === GPBLabel::OPTIONAL &&
+ PHP_INT_SIZE == 4) {
+ switch ($field->getType()) {
+ case GPBType::INT64:
+ case GPBType::UINT64:
+ case GPBType::FIXED64:
+ case GPBType::SFIXED64:
+ case GPBType::SINT64:
+ $this->$setter("0");
+ }
}
}
}
@@ -210,13 +220,11 @@ class Message
if (!GPBWire::readInt64($input, $value)) {
return false;
}
- $value = $value->toInteger();
break;
case GPBType::UINT64:
if (!GPBWire::readUint64($input, $value)) {
return false;
}
- $value = $value->toInteger();
break;
case GPBType::INT32:
if (!GPBWire::readInt32($input, $value)) {
@@ -227,7 +235,6 @@ class Message
if (!GPBWire::readFixed64($input, $value)) {
return false;
}
- $value = $value->toInteger();
break;
case GPBType::FIXED32:
if (!GPBWire::readFixed32($input, $value)) {
@@ -285,7 +292,6 @@ class Message
if (!GPBWire::readSfixed64($input, $value)) {
return false;
}
- $value = $value->toInteger();
break;
case GPBType::SINT32:
if (!GPBWire::readSint32($input, $value)) {
@@ -296,7 +302,6 @@ class Message
if (!GPBWire::readSint64($input, $value)) {
return false;
}
- $value = $value->toInteger();
break;
default:
user_error("Unsupported type.");
diff --git a/php/src/Google/Protobuf/Internal/OutputStream.php b/php/src/Google/Protobuf/Internal/OutputStream.php
index fcc5ce6d..587ac352 100644
--- a/php/src/Google/Protobuf/Internal/OutputStream.php
+++ b/php/src/Google/Protobuf/Internal/OutputStream.php
@@ -90,8 +90,6 @@ class OutputStream
public function writeRaw($data, $size)
{
if ($this->buffer_size < $size) {
- var_dump($this->buffer_size);
- var_dump($size);
trigger_error("Output stream doesn't have enough buffer.");
return false;
}
@@ -107,15 +105,28 @@ class OutputStream
private static function writeVarintToArray($value, &$buffer, $trim = false)
{
$current = 0;
- if ($trim) {
- $value &= 0xFFFFFFFF;
+
+ $high = 0;
+ $low = 0;
+ if (PHP_INT_SIZE == 4) {
+ GPBUtil::divideInt64ToInt32($value, $high, $low, $trim);
+ } else {
+ if ($trim) {
+ $low = $value & 0xFFFFFFFF;
+ } else {
+ $low = $value;
+ }
}
- while ($value >= 0x80 || $value < 0) {
- $buffer[$current] = chr($value | 0x80);
+
+ while ($low >= 0x80 || $low < 0) {
+ $buffer[$current] = chr($low | 0x80);
$value = ($value >> 7) & ~(0x7F << ((PHP_INT_SIZE << 3) - 7));
+ $carry = ($high & 0x7F) << ((PHP_INT_SIZE << 3) - 7);
+ $high = ($high >> 7) & ~(0x7F << ((PHP_INT_SIZE << 3) - 7));
+ $low = (($low >> 7) & ~(0x7F << ((PHP_INT_SIZE << 3) - 7)) | $carry);
$current++;
}
- $buffer[$current] = chr($value);
+ $buffer[$current] = chr($low);
return $current + 1;
}
@@ -130,14 +141,24 @@ class OutputStream
private static function writeLittleEndian64ToArray($value, &$buffer)
{
- $buffer[0] = chr($value & 0x000000FF);
- $buffer[1] = chr(($value >> 8) & 0x000000FF);
- $buffer[2] = chr(($value >> 16) & 0x000000FF);
- $buffer[3] = chr(($value >> 24) & 0x000000FF);
- $buffer[4] = chr(($value >> 32) & 0x000000FF);
- $buffer[5] = chr(($value >> 40) & 0x000000FF);
- $buffer[6] = chr(($value >> 48) & 0x000000FF);
- $buffer[7] = chr(($value >> 56) & 0x000000FF);
+ $high = 0;
+ $low = 0;
+ if (PHP_INT_SIZE == 4) {
+ GPBUtil::divideInt64ToInt32($value, $high, $low);
+ } else {
+ $low = $value & 0xFFFFFFFF;
+ $high = ($value >> 32) & 0xFFFFFFFF;
+ }
+
+ $buffer[0] = chr($low & 0x000000FF);
+ $buffer[1] = chr(($low >> 8) & 0x000000FF);
+ $buffer[2] = chr(($low >> 16) & 0x000000FF);
+ $buffer[3] = chr(($low >> 24) & 0x000000FF);
+ $buffer[4] = chr($high & 0x000000FF);
+ $buffer[5] = chr(($high >> 8) & 0x000000FF);
+ $buffer[6] = chr(($high >> 16) & 0x000000FF);
+ $buffer[7] = chr(($high >> 24) & 0x000000FF);
return 8;
}
+
}
diff --git a/php/src/Google/Protobuf/Internal/Type.php b/php/src/Google/Protobuf/Internal/Type.php
deleted file mode 100644
index 088f0e0c..00000000
--- a/php/src/Google/Protobuf/Internal/Type.php
+++ /dev/null
@@ -1,175 +0,0 @@
-<?php
-
-// 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.
-
-namespace Google\Protobuf\Internal;
-
-class GPBInteger
-{
- public $high = 0;
- public $low = 0;
-
- public function __construct($value = 0)
- {
- $this->low = $value & 0xFFFFFFFF;
- if (PHP_INT_SIZE === 8) {
- $this->high = ($value >> 32) & 0xFFFFFFFF;
- }
- }
-
- // Return 0 for unsigned integers and 1 for signed integers.
- protected function sign()
- {
- trigger_error("Not implemented", E_ERROR);
- }
-
- public function leftShift($count)
- {
- if ($count > 63) {
- $this->low = 0;
- $this->high = 0;
- return;
- }
- if ($count > 32) {
- $this->high = $this->low;
- $this->low = 0;
- $count -= 32;
- }
- $mask = (1 << $count) - 1;
- $this->high = (($this->high << $count) & 0xFFFFFFFF) |
- (($this->low >> (32 - $count)) & $mask);
- $this->low = ($this->low << $count) & 0xFFFFFFFF;
-
- $this->high &= 0xFFFFFFFF;
- $this->low &= 0xFFFFFFFF;
- return $this;
- }
-
- public function rightShift($count)
- {
- $sign = (($this->high & 0x80000000) >> 31) & $this->sign();
- if ($count > 63) {
- $this->low = -$sign;
- $this->high = -$sign;
- return;
- }
- if ($count > 32) {
- $this->low = $this->high;
- $this->high = -$sign;
- $count -= 32;
- }
- $this->low = (($this->low >> $count) & 0xFFFFFFFF) |
- (($this->high << (32 - $count)) & 0xFFFFFFFF);
- $this->high = (($this->high >> $count) | (-$sign << $count));
-
- $this->high &= 0xFFFFFFFF;
- $this->low &= 0xFFFFFFFF;
-
- return $this;
- }
-
- public function bitOr($var)
- {
- $this->high |= $var->high;
- $this->low |= $var->low;
- return $this;
- }
-
- public function bitXor($var)
- {
- $this->high ^= $var->high;
- $this->low ^= $var->low;
- return $this;
- }
-
- public function bitAnd($var)
- {
- $this->high &= $var->high;
- $this->low &= $var->low;
- return $this;
- }
-
- // Even: all zero; Odd: all one.
- public function oddMask()
- {
- $low = (-($this->low & 1)) & 0xFFFFFFFF;
- $high = $low;
- return UInt64::newValue($high, $low);
- }
-
- public function toInteger()
- {
- if (PHP_INT_SIZE === 8) {
- return ($this->high << 32) | $this->low;
- } else {
- return $this->low;
- }
- }
-
- public function copy()
- {
- return static::newValue($this->high, $this->low);
- }
-}
-
-class Uint64 extends GPBInteger
-{
-
- public static function newValue($high, $low)
- {
- $uint64 = new Uint64(0);
- $uint64->high = $high;
- $uint64->low = $low;
- return $uint64;
- }
-
- protected function sign()
- {
- return 0;
- }
-}
-
-class Int64 extends GPBInteger
-{
-
- public static function newValue($high, $low)
- {
- $int64 = new Int64(0);
- $int64->high = $high;
- $int64->low = $low;
- return $int64;
- }
-
- protected function sign()
- {
- return 1;
- }
-}
diff --git a/php/src/Google/Protobuf/descriptor.php b/php/src/Google/Protobuf/descriptor.php
index afe08227..ef6b9dcf 100644
--- a/php/src/Google/Protobuf/descriptor.php
+++ b/php/src/Google/Protobuf/descriptor.php
@@ -215,6 +215,18 @@ class Descriptor
return $desc;
}
}
+
+function addPrefixIfSpecial(
+ $name,
+ $package)
+{
+ if ($name === "Empty" && $package === "google.protobuf") {
+ return "GPBEmpty";
+ } else {
+ return $name;
+ }
+}
+
function getFullClassName(
$proto,
$containing,
@@ -224,7 +236,8 @@ function getFullClassName(
&$fullname)
{
// Full name needs to start with '.'.
- $message_name_without_package = $proto->getName();
+ $message_name_without_package =
+ addPrefixIfSpecial($proto->getName(), $package);
if ($containing !== "") {
$message_name_without_package =
$containing . "." . $message_name_without_package;
@@ -240,9 +253,13 @@ function getFullClassName(
$class_name_without_package =
implode('_', array_map('ucwords',
explode('.', $message_name_without_package)));
- $classname =
- implode('\\', array_map('ucwords', explode('.', $package))).
- "\\".$class_name_without_package;
+ if ($package === "") {
+ $classname = $class_name_without_package;
+ } else {
+ $classname =
+ implode('\\', array_map('ucwords', explode('.', $package))).
+ "\\".$class_name_without_package;
+ }
}
class OneofDescriptor
diff --git a/php/tests/array_test.php b/php/tests/array_test.php
index 09d4dc82..a79a08bc 100644
--- a/php/tests/array_test.php
+++ b/php/tests/array_test.php
@@ -65,6 +65,17 @@ class RepeatedFieldTest extends PHPUnit_Framework_TestCase
$this->assertSame(3, $arr[6]);
$arr [7]= MAX_INT32_STRING;
$this->assertSame(MAX_INT32, $arr[7]);
+
+ // Test foreach.
+ $arr = new RepeatedField(GPBType::INT32);
+ for ($i = 0; $i < 3; $i++) {
+ $arr []= $i;
+ }
+ $i = 0;
+ foreach ($arr as $val) {
+ $this->assertSame($i++, $val);
+ }
+ $this->assertSame(3, $i);
}
/**
@@ -225,46 +236,68 @@ class RepeatedFieldTest extends PHPUnit_Framework_TestCase
// Test append.
$arr []= MAX_INT64;
- $this->assertSame(MAX_INT64, $arr[0]);
$arr []= MIN_INT64;
- $this->assertEquals(MIN_INT64, $arr[1]);
-
$arr []= 1.1;
- $this->assertSame(1, $arr[2]);
-
$arr []= '2';
- $this->assertSame(2, $arr[3]);
$arr []= '3.1';
- $this->assertSame(3, $arr[4]);
$arr []= MAX_INT64_STRING;
- $this->assertSame(MAX_INT64, $arr[5]);
$arr []= MIN_INT64_STRING;
- $this->assertEquals(MIN_INT64, $arr[6]);
+ if (PHP_INT_SIZE == 4) {
+ $this->assertSame(MAX_INT64, $arr[0]);
+ $this->assertSame(MIN_INT64, $arr[1]);
+ $this->assertSame('1', $arr[2]);
+ $this->assertSame('2', $arr[3]);
+ $this->assertSame('3', $arr[4]);
+ $this->assertSame(MAX_INT64_STRING, $arr[5]);
+ $this->assertSame(MIN_INT64_STRING, $arr[6]);
+ } else {
+ $this->assertSame(MAX_INT64, $arr[0]);
+ $this->assertSame(MIN_INT64, $arr[1]);
+ $this->assertSame(1, $arr[2]);
+ $this->assertSame(2, $arr[3]);
+ $this->assertSame(3, $arr[4]);
+ $this->assertSame(MAX_INT64, $arr[5]);
+ $this->assertSame(MIN_INT64, $arr[6]);
+ }
+
$this->assertEquals(7, count($arr));
for ($i = 0; $i < count($arr); $i++) {
$arr[$i] = 0;
- $this->assertSame(0, $arr[$i]);
+ if (PHP_INT_SIZE == 4) {
+ $this->assertSame('0', $arr[$i]);
+ } else {
+ $this->assertSame(0, $arr[$i]);
+ }
}
// Test set.
$arr [0]= MAX_INT64;
- $this->assertSame(MAX_INT64, $arr[0]);
$arr [1]= MIN_INT64;
- $this->assertEquals(MIN_INT64, $arr[1]);
-
$arr [2]= 1.1;
- $this->assertSame(1, $arr[2]);
-
$arr [3]= '2';
- $this->assertSame(2, $arr[3]);
$arr [4]= '3.1';
- $this->assertSame(3, $arr[4]);
$arr [5]= MAX_INT64_STRING;
- $this->assertSame(MAX_INT64, $arr[5]);
$arr [6]= MIN_INT64_STRING;
- $this->assertEquals(MIN_INT64, $arr[6]);
+
+ if (PHP_INT_SIZE == 4) {
+ $this->assertSame(MAX_INT64_STRING, $arr[0]);
+ $this->assertSame(MIN_INT64_STRING, $arr[1]);
+ $this->assertSame('1', $arr[2]);
+ $this->assertSame('2', $arr[3]);
+ $this->assertSame('3', $arr[4]);
+ $this->assertSame(MAX_INT64_STRING, $arr[5]);
+ $this->assertEquals(MIN_INT64_STRING, $arr[6]);
+ } else {
+ $this->assertSame(MAX_INT64, $arr[0]);
+ $this->assertSame(MIN_INT64, $arr[1]);
+ $this->assertSame(1, $arr[2]);
+ $this->assertSame(2, $arr[3]);
+ $this->assertSame(3, $arr[4]);
+ $this->assertSame(MAX_INT64, $arr[5]);
+ $this->assertEquals(MIN_INT64, $arr[6]);
+ }
}
/**
@@ -315,38 +348,57 @@ class RepeatedFieldTest extends PHPUnit_Framework_TestCase
// Test append.
$arr []= MAX_UINT64;
- $this->assertEquals(MAX_UINT64, $arr[0]);
-
$arr []= 1.1;
- $this->assertSame(1, $arr[1]);
-
$arr []= '2';
- $this->assertSame(2, $arr[2]);
$arr []= '3.1';
- $this->assertSame(3, $arr[3]);
$arr []= MAX_UINT64_STRING;
- $this->assertEquals(MAX_UINT64, $arr[4]);
- $this->assertEquals(5, count($arr));
+ if (PHP_INT_SIZE == 4) {
+ $this->assertSame(MAX_UINT64_STRING, $arr[0]);
+ $this->assertSame('1', $arr[1]);
+ $this->assertSame('2', $arr[2]);
+ $this->assertSame('3', $arr[3]);
+ $this->assertSame(MAX_UINT64_STRING, $arr[4]);
+ } else {
+ $this->assertSame(MAX_UINT64, $arr[0]);
+ $this->assertSame(1, $arr[1]);
+ $this->assertSame(2, $arr[2]);
+ $this->assertSame(3, $arr[3]);
+ $this->assertSame(MAX_UINT64, $arr[4]);
+ $this->assertSame(5, count($arr));
+ }
+
+ $this->assertSame(5, count($arr));
for ($i = 0; $i < count($arr); $i++) {
$arr[$i] = 0;
- $this->assertSame(0, $arr[$i]);
+ if (PHP_INT_SIZE == 4) {
+ $this->assertSame('0', $arr[$i]);
+ } else {
+ $this->assertSame(0, $arr[$i]);
+ }
}
// Test set.
$arr [0]= MAX_UINT64;
- $this->assertEquals(MAX_UINT64, $arr[0]);
-
$arr [1]= 1.1;
- $this->assertSame(1, $arr[1]);
-
$arr [2]= '2';
- $this->assertSame(2, $arr[2]);
$arr [3]= '3.1';
- $this->assertSame(3, $arr[3]);
$arr [4]= MAX_UINT64_STRING;
- $this->assertEquals(MAX_UINT64, $arr[4]);
+
+ if (PHP_INT_SIZE == 4) {
+ $this->assertSame(MAX_UINT64_STRING, $arr[0]);
+ $this->assertSame('1', $arr[1]);
+ $this->assertSame('2', $arr[2]);
+ $this->assertSame('3', $arr[3]);
+ $this->assertSame(MAX_UINT64_STRING, $arr[4]);
+ } else {
+ $this->assertSame(MAX_UINT64, $arr[0]);
+ $this->assertSame(1, $arr[1]);
+ $this->assertSame(2, $arr[2]);
+ $this->assertSame(3, $arr[3]);
+ $this->assertSame(MAX_UINT64, $arr[4]);
+ }
}
/**
diff --git a/php/tests/generated_class_test.php b/php/tests/generated_class_test.php
index 56466cae..b3ecd3a1 100644
--- a/php/tests/generated_class_test.php
+++ b/php/tests/generated_class_test.php
@@ -1,6 +1,7 @@
<?php
require_once('test.pb.php');
+require_once('test_no_namespace.pb.php');
require_once('test_util.php');
use Google\Protobuf\Internal\RepeatedField;
@@ -147,17 +148,40 @@ class GeneratedClassTest extends PHPUnit_Framework_TestCase
// Set float.
$m->setOptionalInt64(1.1);
- $this->assertSame(1, $m->getOptionalInt64());
+ if (PHP_INT_SIZE == 4) {
+ $this->assertSame('1', $m->getOptionalInt64());
+ } else {
+ $this->assertSame(1, $m->getOptionalInt64());
+ }
// Set string.
$m->setOptionalInt64('2');
- $this->assertSame(2, $m->getOptionalInt64());
+ if (PHP_INT_SIZE == 4) {
+ $this->assertSame('2', $m->getOptionalInt64());
+ } else {
+ $this->assertSame(2, $m->getOptionalInt64());
+ }
+
$m->setOptionalInt64('3.1');
- $this->assertSame(3, $m->getOptionalInt64());
+ if (PHP_INT_SIZE == 4) {
+ $this->assertSame('3', $m->getOptionalInt64());
+ } else {
+ $this->assertSame(3, $m->getOptionalInt64());
+ }
+
$m->setOptionalInt64(MAX_INT64_STRING);
- $this->assertSame(MAX_INT64, $m->getOptionalInt64());
+ if (PHP_INT_SIZE == 4) {
+ $this->assertSame(MAX_INT64_STRING, $m->getOptionalInt64());
+ } else {
+ $this->assertSame(MAX_INT64, $m->getOptionalInt64());
+ }
+
$m->setOptionalInt64(MIN_INT64_STRING);
- $this->assertEquals(MIN_INT64, $m->getOptionalInt64());
+ if (PHP_INT_SIZE == 4) {
+ $this->assertSame(MIN_INT64_STRING, $m->getOptionalInt64());
+ } else {
+ $this->assertSame(MIN_INT64, $m->getOptionalInt64());
+ }
}
/**
@@ -188,19 +212,41 @@ class GeneratedClassTest extends PHPUnit_Framework_TestCase
// Set integer.
$m->setOptionalUint64(MAX_UINT64);
- $this->assertEquals(MAX_UINT64, $m->getOptionalUint64());
+ if (PHP_INT_SIZE == 4) {
+ $this->assertSame(MAX_UINT64_STRING, $m->getOptionalUint64());
+ } else {
+ $this->assertSame(MAX_UINT64, $m->getOptionalUint64());
+ }
// Set float.
$m->setOptionalUint64(1.1);
- $this->assertSame(1, $m->getOptionalUint64());
+ if (PHP_INT_SIZE == 4) {
+ $this->assertSame('1', $m->getOptionalUint64());
+ } else {
+ $this->assertSame(1, $m->getOptionalUint64());
+ }
// Set string.
$m->setOptionalUint64('2');
- $this->assertSame(2, $m->getOptionalUint64());
+ if (PHP_INT_SIZE == 4) {
+ $this->assertSame('2', $m->getOptionalUint64());
+ } else {
+ $this->assertSame(2, $m->getOptionalUint64());
+ }
+
$m->setOptionalUint64('3.1');
- $this->assertSame(3, $m->getOptionalUint64());
+ if (PHP_INT_SIZE == 4) {
+ $this->assertSame('3', $m->getOptionalUint64());
+ } else {
+ $this->assertSame(3, $m->getOptionalUint64());
+ }
+
$m->setOptionalUint64(MAX_UINT64_STRING);
- $this->assertEquals(MAX_UINT64, $m->getOptionalUint64());
+ if (PHP_INT_SIZE == 4) {
+ $this->assertSame(MAX_UINT64_STRING, $m->getOptionalUint64());
+ } else {
+ $this->assertSame(MAX_UINT64, $m->getOptionalUint64());
+ }
}
/**
@@ -554,4 +600,12 @@ class GeneratedClassTest extends PHPUnit_Framework_TestCase
$this->assertSame('', $m->getOneofString());
$this->assertSame(1, $m->getOneofMessage()->getA());
}
+
+ #########################################################
+ # Test oneof field.
+ #########################################################
+
+ public function testMessageWithoutNamespace() {
+ $m = new NoNameSpace();
+ }
}
diff --git a/php/tests/google/protobuf/empty.pb.php b/php/tests/google/protobuf/empty.pb.php
new file mode 100644
index 00000000..fdd0fe4f
--- /dev/null
+++ b/php/tests/google/protobuf/empty.pb.php
@@ -0,0 +1,28 @@
+<?php
+# Generated by the protocol buffer compiler. DO NOT EDIT!
+# source: google/protobuf/empty.proto
+
+namespace Google\Protobuf;
+
+use Google\Protobuf\Internal\DescriptorPool;
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+class GPBEmpty extends \Google\Protobuf\Internal\Message
+{
+
+}
+
+$pool = DescriptorPool::getGeneratedPool();
+
+$pool->internalAddGeneratedFile(hex2bin(
+ "0ab7010a1b676f6f676c652f70726f746f6275662f656d7074792e70726f" .
+ "746f120f676f6f676c652e70726f746f62756622070a05456d7074794276" .
+ "0a13636f6d2e676f6f676c652e70726f746f627566420a456d7074795072" .
+ "6f746f50015a276769746875622e636f6d2f676f6c616e672f70726f746f" .
+ "6275662f7074797065732f656d707479f80101a20203475042aa021e476f" .
+ "6f676c652e50726f746f6275662e57656c6c4b6e6f776e54797065736206" .
+ "70726f746f33"
+));
+
diff --git a/php/tests/map_field_test.php b/php/tests/map_field_test.php
index d79d0da3..4e42361d 100644
--- a/php/tests/map_field_test.php
+++ b/php/tests/map_field_test.php
@@ -205,9 +205,14 @@ class MapFieldTest extends PHPUnit_Framework_TestCase {
// Test integer argument.
$arr[MAX_INT64] = MAX_INT64;
- $this->assertSame(MAX_INT64, $arr[MAX_INT64]);
$arr[MIN_INT64] = MIN_INT64;
- $this->assertEquals(MIN_INT64, $arr[MIN_INT64]);
+ if (PHP_INT_SIZE == 4) {
+ $this->assertSame(MAX_INT64_STRING, $arr[MAX_INT64_STRING]);
+ $this->assertSame(MIN_INT64_STRING, $arr[MIN_INT64_STRING]);
+ } else {
+ $this->assertSame(MAX_INT64, $arr[MAX_INT64]);
+ $this->assertSame(MIN_INT64, $arr[MIN_INT64]);
+ }
$this->assertEquals(2, count($arr));
unset($arr[MAX_INT64]);
unset($arr[MIN_INT64]);
@@ -215,20 +220,31 @@ class MapFieldTest extends PHPUnit_Framework_TestCase {
// Test float argument.
$arr[1.1] = 1.1;
- $this->assertSame(1, $arr[1]);
+ if (PHP_INT_SIZE == 4) {
+ $this->assertSame('1', $arr['1']);
+ } else {
+ $this->assertSame(1, $arr[1]);
+ }
$this->assertEquals(1, count($arr));
unset($arr[1.1]);
$this->assertEquals(0, count($arr));
// Test string argument.
$arr['2'] = '2';
- $this->assertSame(2, $arr[2]);
$arr['3.1'] = '3.1';
- $this->assertSame(3, $arr[3]);
$arr[MAX_INT64_STRING] = MAX_INT64_STRING;
- $this->assertSame(MAX_INT64, $arr[MAX_INT64]);
$arr[MIN_INT64_STRING] = MIN_INT64_STRING;
- $this->assertEquals(MIN_INT64, $arr[MIN_INT64]);
+ if (PHP_INT_SIZE == 4) {
+ $this->assertSame('2', $arr['2']);
+ $this->assertSame('3', $arr['3']);
+ $this->assertSame(MAX_INT64_STRING, $arr[MAX_INT64_STRING]);
+ $this->assertSame(MIN_INT64_STRING, $arr[MIN_INT64_STRING]);
+ } else {
+ $this->assertSame(2, $arr[2]);
+ $this->assertSame(3, $arr[3]);
+ $this->assertSame(MAX_INT64, $arr[MAX_INT64]);
+ $this->assertSame(MIN_INT64, $arr[MIN_INT64]);
+ }
$this->assertEquals(4, count($arr));
unset($arr['2']);
unset($arr['3.1']);
@@ -282,25 +298,41 @@ class MapFieldTest extends PHPUnit_Framework_TestCase {
// Test integer argument.
$arr[MAX_UINT64] = MAX_UINT64;
- $this->assertEquals(MAX_UINT64, $arr[MAX_UINT64]);
+ if (PHP_INT_SIZE == 4) {
+ $this->assertSame(MAX_UINT64_STRING, $arr[MAX_UINT64_STRING]);
+ } else {
+ $this->assertSame(MAX_UINT64, $arr[MAX_UINT64]);
+ }
$this->assertEquals(1, count($arr));
unset($arr[MAX_UINT64]);
$this->assertEquals(0, count($arr));
// Test float argument.
$arr[1.1] = 1.1;
- $this->assertSame(1, $arr[1]);
+ if (PHP_INT_SIZE == 4) {
+ $this->assertSame('1', $arr['1']);
+ } else {
+ $this->assertSame(1, $arr[1]);
+ }
$this->assertEquals(1, count($arr));
unset($arr[1.1]);
$this->assertEquals(0, count($arr));
// Test string argument.
$arr['2'] = '2';
- $this->assertSame(2, $arr[2]);
$arr['3.1'] = '3.1';
- $this->assertSame(3, $arr[3]);
$arr[MAX_UINT64_STRING] = MAX_UINT64_STRING;
- $this->assertEquals(MAX_UINT64, $arr[MAX_UINT64]);
+
+ if (PHP_INT_SIZE == 4) {
+ $this->assertSame('2', $arr['2']);
+ $this->assertSame('3', $arr['3']);
+ $this->assertSame(MAX_UINT64_STRING, $arr[MAX_UINT64_STRING]);
+ } else {
+ $this->assertSame(2, $arr[2]);
+ $this->assertSame(3, $arr[3]);
+ $this->assertSame(MAX_UINT64, $arr[MAX_UINT64]);
+ }
+
$this->assertEquals(3, count($arr));
unset($arr['2']);
unset($arr['3.1']);
diff --git a/php/tests/php_implementation_test.php b/php/tests/php_implementation_test.php
index 82941dd2..485956cc 100644
--- a/php/tests/php_implementation_test.php
+++ b/php/tests/php_implementation_test.php
@@ -9,14 +9,10 @@ use Foo\TestMessage_Sub;
use Foo\TestPackedMessage;
use Google\Protobuf\Internal\InputStream;
use Google\Protobuf\Internal\FileDescriptorSet;
-use Google\Protobuf\Internal\GPBUtil;
-use Google\Protobuf\Internal\Int64;
-use Google\Protobuf\Internal\Uint64;
use Google\Protobuf\Internal\GPBLabel;
use Google\Protobuf\Internal\GPBType;
use Google\Protobuf\Internal\GPBWire;
use Google\Protobuf\Internal\OutputStream;
-use Google\Protobuf\Internal\RepeatedField;
class ImplementationTest extends TestBase
{
@@ -68,17 +64,17 @@ class ImplementationTest extends TestBase
// Positive number.
$input = new InputStream(hex2bin("01"));
GPBWire::readInt64($input, $value);
- $this->assertSame(1, $value->toInteger());
+ $this->assertEquals(1, $value);
// Negative number.
$input = new InputStream(hex2bin("ffffffffffffffffff01"));
GPBWire::readInt64($input, $value);
- $this->assertSame(-1, $value->toInteger());
+ $this->assertEquals(-1, $value);
// Discard overflow bits.
$input = new InputStream(hex2bin("ffffffffffffffffff0f"));
GPBWire::readInt64($input, $value);
- $this->assertSame(-1, $value->toInteger());
+ $this->assertEquals(-1, $value);
}
public function testReadUint64()
@@ -88,17 +84,17 @@ class ImplementationTest extends TestBase
// Positive number.
$input = new InputStream(hex2bin("01"));
GPBWire::readUint64($input, $value);
- $this->assertSame(1, $value->toInteger());
+ $this->assertEquals(1, $value);
// Negative number.
$input = new InputStream(hex2bin("FFFFFFFFFFFFFFFFFF01"));
GPBWire::readUint64($input, $value);
- $this->assertSame(-1, $value->toInteger());
+ $this->assertEquals(-1, $value);
// Discard overflow bits.
$input = new InputStream(hex2bin("FFFFFFFFFFFFFFFFFF0F"));
GPBWire::readUint64($input, $value);
- $this->assertSame(-1, $value->toInteger());
+ $this->assertEquals(-1, $value);
}
public function testReadSint32()
@@ -124,15 +120,15 @@ class ImplementationTest extends TestBase
$input = new InputStream(hex2bin("00"));
GPBWire::readSint64($input, $value);
- $this->assertEquals(GPBUtil::Int64(0), $value);
+ $this->assertEquals(0, $value);
$input = new InputStream(hex2bin("01"));
GPBWire::readSint64($input, $value);
- $this->assertEquals(GPBUtil::Int64(-1), $value);
+ $this->assertEquals(-1, $value);
$input = new InputStream(hex2bin("02"));
GPBWire::readSint64($input, $value);
- $this->assertEquals(GPBUtil::Int64(1), $value);
+ $this->assertEquals(1, $value);
}
public function testReadFixed32()
@@ -148,7 +144,11 @@ class ImplementationTest extends TestBase
$value = null;
$input = new InputStream(hex2bin("1234567812345678"));
GPBWire::readFixed64($input, $value);
- $this->assertEquals(Uint64::newValue(0x78563412, 0x78563412), $value);
+ if (PHP_INT_SIZE == 4) {
+ $this->assertSame("8671175386481439762", $value);
+ } else {
+ $this->assertSame(0x7856341278563412, $value);
+ }
}
public function testReadSfixed32()
@@ -193,7 +193,11 @@ class ImplementationTest extends TestBase
$value = null;
$input = new InputStream(hex2bin("1234567812345678"));
GPBWire::readSfixed64($input, $value);
- $this->assertEquals(Int64::newValue(0x78563412, 0x78563412), $value);
+ if (PHP_INT_SIZE == 4) {
+ $this->assertSame("8671175386481439762", $value);
+ } else {
+ $this->assertSame(0x7856341278563412, $value);
+ }
}
public function testZigZagEncodeDecode()
@@ -214,43 +218,65 @@ class ImplementationTest extends TestBase
$this->assertSame(0x3FFFFFFF, GPBWire::zigZagDecode32(0x7FFFFFFE));
$this->assertSame(-1073741824, GPBWire::zigZagDecode32(0x7FFFFFFF));
$this->assertSame(0x7FFFFFFF, GPBWire::zigZagDecode32(0xFFFFFFFE));
- $this->assertSame(-2147483648, GPBWire::zigZagDecode32(0xFFFFFFFF));
-
- $this->assertEquals(GPBUtil::Uint64(0),
- GPBWire::zigZagEncode64(GPBUtil::Int64(0)));
- $this->assertEquals(GPBUtil::Uint64(1),
- GPBWire::zigZagEncode64(GPBUtil::Int64(-1)));
- $this->assertEquals(GPBUtil::Uint64(2),
- GPBWire::zigZagEncode64(GPBUtil::Int64(1)));
- $this->assertEquals(GPBUtil::Uint64(3),
- GPBWire::zigZagEncode64(GPBUtil::Int64(-2)));
- $this->assertEquals(
- GPBUtil::Uint64(0x000000007FFFFFFE),
- GPBWire::zigZagEncode64(GPBUtil::Int64(0x000000003FFFFFFF)));
- $this->assertEquals(
- GPBUtil::Uint64(0x000000007FFFFFFF),
- GPBWire::zigZagEncode64(GPBUtil::Int64(0xFFFFFFFFC0000000)));
- $this->assertEquals(
- GPBUtil::Uint64(0x00000000FFFFFFFE),
- GPBWire::zigZagEncode64(GPBUtil::Int64(0x000000007FFFFFFF)));
- $this->assertEquals(
- GPBUtil::Uint64(0x00000000FFFFFFFF),
- GPBWire::zigZagEncode64(GPBUtil::Int64(0xFFFFFFFF80000000)));
- $this->assertEquals(
- Uint64::newValue(4294967295, 4294967294),
- GPBWire::zigZagEncode64(GPBUtil::Int64(0x7FFFFFFFFFFFFFFF)));
- $this->assertEquals(
- Uint64::newValue(4294967295, 4294967295),
- GPBWire::zigZagEncode64(GPBUtil::Int64(0x8000000000000000)));
-
- $this->assertEquals(GPBUtil::Int64(0),
- GPBWire::zigZagDecode64(GPBUtil::Uint64(0)));
- $this->assertEquals(GPBUtil::Int64(-1),
- GPBWire::zigZagDecode64(GPBUtil::Uint64(1)));
- $this->assertEquals(GPBUtil::Int64(1),
- GPBWire::zigZagDecode64(GPBUtil::Uint64(2)));
- $this->assertEquals(GPBUtil::Int64(-2),
- GPBWire::zigZagDecode64(GPBUtil::Uint64(3)));
+ $this->assertSame((int)-2147483648,GPBWire::zigZagDecode32(0xFFFFFFFF));
+
+ if (PHP_INT_SIZE == 4) {
+ $this->assertSame('0', GPBWire::zigZagEncode64(0));
+ $this->assertSame('1', GPBWire::zigZagEncode64(-1));
+ $this->assertSame('2', GPBWire::zigZagEncode64(1));
+ $this->assertSame('3', GPBWire::zigZagEncode64(-2));
+ $this->assertSame(
+ '2147483646', // 0x7FFFFFE
+ GPBWire::zigZagEncode64(0x3FFFFFFF));
+ $this->assertSame(
+ '2147483647', // 0x7FFFFFF
+ GPBWire::zigZagEncode64(-1073741824)); // 0xFFFFFFFFC0000000
+ $this->assertSame(
+ '4294967294', // 0xFFFFFFFE
+ GPBWire::zigZagEncode64(2147483647)); // 0x7FFFFFFF
+ $this->assertSame(
+ '4294967295', // 0xFFFFFFFF
+ GPBWire::zigZagEncode64(-2147483648)); // 0xFFFFFFFF80000000
+ $this->assertSame(
+ '18446744073709551614', // 0xFFFFFFFFFFFFFFFE
+ // 0x7FFFFFFFFFFFFFFF
+ GPBWire::zigZagEncode64("9223372036854775807"));
+ $this->assertSame(
+ '18446744073709551615', // 0xFFFFFFFFFFFFFFFF
+ // 0x8000000000000000
+ GPBWire::zigZagEncode64("-9223372036854775808"));
+
+ $this->assertSame('0', GPBWire::zigZagDecode64(0));
+ $this->assertSame('-1', GPBWire::zigZagDecode64(1));
+ $this->assertSame('1', GPBWire::zigZagDecode64(2));
+ $this->assertSame('-2', GPBWire::zigZagDecode64(3));
+ } else {
+ $this->assertSame(0, GPBWire::zigZagEncode64(0));
+ $this->assertSame(1, GPBWire::zigZagEncode64(-1));
+ $this->assertSame(2, GPBWire::zigZagEncode64(1));
+ $this->assertSame(3, GPBWire::zigZagEncode64(-2));
+ $this->assertSame(0x7FFFFFFE, GPBWire::zigZagEncode64(0x3FFFFFFF));
+ $this->assertSame(
+ 0x7FFFFFFF,
+ GPBWire::zigZagEncode64(0xFFFFFFFFC0000000));
+ $this->assertSame(
+ 0xFFFFFFFE,
+ GPBWire::zigZagEncode64(0x7FFFFFFF));
+ $this->assertSame(
+ 0xFFFFFFFF,
+ GPBWire::zigZagEncode64(0xFFFFFFFF80000000));
+ $this->assertSame(
+ -2, // 0xFFFFFFFFFFFFFFFE
+ GPBWire::zigZagEncode64(0x7FFFFFFFFFFFFFFF));
+ $this->assertSame(
+ -1, // 0xFFFFFFFFFFFFFFFF
+ GPBWire::zigZagEncode64(0x8000000000000000));
+
+ $this->assertSame(0, GPBWire::zigZagDecode64(0));
+ $this->assertSame(-1, GPBWire::zigZagDecode64(1));
+ $this->assertSame(1, GPBWire::zigZagDecode64(2));
+ $this->assertSame(-2, GPBWire::zigZagDecode64(3));
+ }
// Round trip
$this->assertSame(0, GPBWire::zigZagDecode32(GPBWire::zigZagEncode32(0)));
@@ -319,15 +345,27 @@ class ImplementationTest extends TestBase
// Normal case.
$input = new InputStream(hex2bin('808001'));
$this->assertTrue($input->readVarint64($var));
- $this->assertSame(16384, $var->toInteger());
+ if (PHP_INT_SIZE == 4) {
+ $this->assertSame('16384', $var);
+ } else {
+ $this->assertSame(16384, $var);
+ }
$this->assertFalse($input->readVarint64($var));
// Read two varint.
$input = new InputStream(hex2bin('808001808002'));
$this->assertTrue($input->readVarint64($var));
- $this->assertSame(16384, $var->toInteger());
+ if (PHP_INT_SIZE == 4) {
+ $this->assertSame('16384', $var);
+ } else {
+ $this->assertSame(16384, $var);
+ }
$this->assertTrue($input->readVarint64($var));
- $this->assertSame(32768, $var->toInteger());
+ if (PHP_INT_SIZE == 4) {
+ $this->assertSame('32768', $var);
+ } else {
+ $this->assertSame(32768, $var);
+ }
$this->assertFalse($input->readVarint64($var));
}
diff --git a/php/tests/test.sh b/php/tests/test.sh
index 888e93eb..a6ca89b9 100755
--- a/php/tests/test.sh
+++ b/php/tests/test.sh
@@ -7,10 +7,11 @@
pushd ../ext/google/protobuf/
make clean
set -e
-phpize && ./configure --enable-debug CFLAGS='-g -O0' && make
+# Add following in configure for debug: --enable-debug CFLAGS='-g -O0'
+phpize && ./configure && make
popd
-tests=( array_test.php encode_decode_test.php generated_class_test.php map_field_test.php )
+tests=( array_test.php encode_decode_test.php generated_class_test.php map_field_test.php well_known_test.php )
for t in "${tests[@]}"
do
diff --git a/php/tests/test_base.php b/php/tests/test_base.php
index 25f18f74..d461f0f7 100644
--- a/php/tests/test_base.php
+++ b/php/tests/test_base.php
@@ -13,22 +13,28 @@ class TestBase extends PHPUnit_Framework_TestCase
public function expectFields(TestMessage $m)
{
- $this->assertSame(-42, $m->getOptionalInt32());
- $this->assertSame(42, $m->getOptionalUint32());
- $this->assertSame(-43, $m->getOptionalInt64());
- $this->assertSame(43, $m->getOptionalUint64());
$this->assertSame(-44, $m->getOptionalSint32());
- $this->assertSame(-45, $m->getOptionalSint64());
$this->assertSame(46, $m->getOptionalFixed32());
- $this->assertSame(47, $m->getOptionalFixed64());
$this->assertSame(-46, $m->getOptionalSfixed32());
- $this->assertSame(-47, $m->getOptionalSfixed64());
$this->assertSame(1.5, $m->getOptionalFloat());
$this->assertSame(1.6, $m->getOptionalDouble());
$this->assertSame(true, $m->getOptionalBool());
$this->assertSame('a', $m->getOptionalString());
$this->assertSame('b', $m->getOptionalBytes());
$this->assertSame(33, $m->getOptionalMessage()->getA());
+ if (PHP_INT_SIZE == 4) {
+ $this->assertSame('-43', $m->getOptionalInt64());
+ $this->assertSame('43', $m->getOptionalUint64());
+ $this->assertSame('-45', $m->getOptionalSint64());
+ $this->assertSame('47', $m->getOptionalFixed64());
+ $this->assertSame('-47', $m->getOptionalSfixed64());
+ } else {
+ $this->assertSame(-43, $m->getOptionalInt64());
+ $this->assertSame(43, $m->getOptionalUint64());
+ $this->assertSame(-45, $m->getOptionalSint64());
+ $this->assertSame(47, $m->getOptionalFixed64());
+ $this->assertSame(-47, $m->getOptionalSfixed64());
+ }
$this->assertEquals(-42, $m->getRepeatedInt32()[0]);
$this->assertEquals(42, $m->getRepeatedUint32()[0]);
@@ -69,20 +75,28 @@ class TestBase extends PHPUnit_Framework_TestCase
{
$this->assertSame(0, $m->getOptionalInt32());
$this->assertSame(0, $m->getOptionalUint32());
- $this->assertSame(0, $m->getOptionalInt64());
- $this->assertSame(0, $m->getOptionalUint64());
$this->assertSame(0, $m->getOptionalSint32());
- $this->assertSame(0, $m->getOptionalSint64());
$this->assertSame(0, $m->getOptionalFixed32());
- $this->assertSame(0, $m->getOptionalFixed64());
$this->assertSame(0, $m->getOptionalSfixed32());
- $this->assertSame(0, $m->getOptionalSfixed64());
$this->assertSame(0.0, $m->getOptionalFloat());
$this->assertSame(0.0, $m->getOptionalDouble());
$this->assertSame(false, $m->getOptionalBool());
$this->assertSame('', $m->getOptionalString());
$this->assertSame('', $m->getOptionalBytes());
$this->assertNull($m->getOptionalMessage());
+ if (PHP_INT_SIZE == 4) {
+ $this->assertSame("0", $m->getOptionalInt64());
+ $this->assertSame("0", $m->getOptionalUint64());
+ $this->assertSame("0", $m->getOptionalSint64());
+ $this->assertSame("0", $m->getOptionalFixed64());
+ $this->assertSame("0", $m->getOptionalSfixed64());
+ } else {
+ $this->assertSame(0, $m->getOptionalInt64());
+ $this->assertSame(0, $m->getOptionalUint64());
+ $this->assertSame(0, $m->getOptionalSint64());
+ $this->assertSame(0, $m->getOptionalFixed64());
+ $this->assertSame(0, $m->getOptionalSfixed64());
+ }
}
// This test is to avoid the warning of no test by php unit.
diff --git a/php/tests/test_no_namespace.pb.php b/php/tests/test_no_namespace.pb.php
new file mode 100644
index 00000000..2f92c955
--- /dev/null
+++ b/php/tests/test_no_namespace.pb.php
@@ -0,0 +1,34 @@
+<?php
+# Generated by the protocol buffer compiler. DO NOT EDIT!
+# source: test_no_namespace.proto
+
+use Google\Protobuf\Internal\DescriptorPool;
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+class NoNameSpace extends \Google\Protobuf\Internal\Message
+{
+ private $a = 0;
+
+ public function getA()
+ {
+ return $this->a;
+ }
+
+ public function setA($var)
+ {
+ GPBUtil::checkInt32($var);
+ $this->a = $var;
+ }
+
+}
+
+$pool = DescriptorPool::getGeneratedPool();
+
+$pool->internalAddGeneratedFile(hex2bin(
+ "0a3b0a17746573745f6e6f5f6e616d6573706163652e70726f746f22180a" .
+ "0b4e6f4e616d65537061636512090a0161180120012805620670726f746f" .
+ "33"
+));
+
diff --git a/php/tests/test_no_namespace.proto b/php/tests/test_no_namespace.proto
new file mode 100644
index 00000000..4331aeab
--- /dev/null
+++ b/php/tests/test_no_namespace.proto
@@ -0,0 +1,5 @@
+syntax = "proto3";
+
+message NoNameSpace {
+ int32 a = 1;
+}
diff --git a/php/tests/test_util.php b/php/tests/test_util.php
index 2f6e4dd8..7f2aae15 100644
--- a/php/tests/test_util.php
+++ b/php/tests/test_util.php
@@ -20,7 +20,7 @@ define('MAX_INT32', 2147483647);
define('MAX_INT32_FLOAT', 2147483647.0);
define('MAX_INT32_STRING', '2147483647');
-define('MIN_INT32', -2147483648);
+define('MIN_INT32', (int)-2147483648);
define('MIN_INT32_FLOAT', -2147483648.0);
define('MIN_INT32_STRING', '-2147483648');
@@ -28,23 +28,24 @@ define('MAX_UINT32', 4294967295);
define('MAX_UINT32_FLOAT', 4294967295.0);
define('MAX_UINT32_STRING', '4294967295');
-define('MIN_UINT32', -2147483648);
+define('MIN_UINT32', (int)-2147483648);
define('MIN_UINT32_FLOAT', -2147483648.0);
define('MIN_UINT32_STRING', '-2147483648');
-define('MAX_INT64', 9223372036854775807);
-define('MAX_INT64_STRING', '9223372036854775807');
+define('MAX_INT64_STRING', '9223372036854775807');
+define('MIN_INT64_STRING', '-9223372036854775808');
+define('MAX_UINT64_STRING', '-9223372036854775808');
-define('MIN_INT64_STRING', '-9223372036854775808');
if (PHP_INT_SIZE === 8) {
- define('MIN_INT64', -9223372036854775808);
+ define('MAX_INT64', (int)9223372036854775807);
+ define('MIN_INT64', (int)-9223372036854775808);
+ define('MAX_UINT64', (int)-9223372036854775808);
} else {
+ define('MAX_INT64', MAX_INT64_STRING);
define('MIN_INT64', MIN_INT64_STRING);
+ define('MAX_UINT64', MAX_UINT64_STRING);
}
-define('MAX_UINT64_STRING', '-9223372036854775808');
-define('MAX_UINT64', MAX_UINT64_STRING);
-
class TestUtil
{
@@ -129,16 +130,24 @@ class TestUtil
public static function assertTestMessage(TestMessage $m)
{
+ if (PHP_INT_SIZE == 4) {
+ assert('-43' === $m->getOptionalInt64());
+ assert('43' === $m->getOptionalUint64());
+ assert('-45' === $m->getOptionalSint64());
+ assert('47' === $m->getOptionalFixed64());
+ assert('-47' === $m->getOptionalSfixed64());
+ } else {
+ assert(-43 === $m->getOptionalInt64());
+ assert(43 === $m->getOptionalUint64());
+ assert(-45 === $m->getOptionalSint64());
+ assert(47 === $m->getOptionalFixed64());
+ assert(-47 === $m->getOptionalSfixed64());
+ }
assert(-42 === $m->getOptionalInt32());
assert(42 === $m->getOptionalUint32());
- assert(-43 === $m->getOptionalInt64());
- assert(43 === $m->getOptionalUint64());
assert(-44 === $m->getOptionalSint32());
- assert(-45 === $m->getOptionalSint64());
assert(46 === $m->getOptionalFixed32());
- assert(47 === $m->getOptionalFixed64());
assert(-46 === $m->getOptionalSfixed32());
- assert(-47 === $m->getOptionalSfixed64());
assert(1.5 === $m->getOptionalFloat());
assert(1.6 === $m->getOptionalDouble());
assert(true=== $m->getOptionalBool());
@@ -147,16 +156,24 @@ class TestUtil
assert(TestEnum::ONE === $m->getOptionalEnum());
assert(33 === $m->getOptionalMessage()->getA());
+ if (PHP_INT_SIZE == 4) {
+ assert('-43' === $m->getRepeatedInt64()[0]);
+ assert('43' === $m->getRepeatedUint64()[0]);
+ assert('-45' === $m->getRepeatedSint64()[0]);
+ assert('47' === $m->getRepeatedFixed64()[0]);
+ assert('-47' === $m->getRepeatedSfixed64()[0]);
+ } else {
+ assert(-43 === $m->getRepeatedInt64()[0]);
+ assert(43 === $m->getRepeatedUint64()[0]);
+ assert(-45 === $m->getRepeatedSint64()[0]);
+ assert(47 === $m->getRepeatedFixed64()[0]);
+ assert(-47 === $m->getRepeatedSfixed64()[0]);
+ }
assert(-42 === $m->getRepeatedInt32()[0]);
assert(42 === $m->getRepeatedUint32()[0]);
- assert(-43 === $m->getRepeatedInt64()[0]);
- assert(43 === $m->getRepeatedUint64()[0]);
assert(-44 === $m->getRepeatedSint32()[0]);
- assert(-45 === $m->getRepeatedSint64()[0]);
assert(46 === $m->getRepeatedFixed32()[0]);
- assert(47 === $m->getRepeatedFixed64()[0]);
assert(-46 === $m->getRepeatedSfixed32()[0]);
- assert(-47 === $m->getRepeatedSfixed64()[0]);
assert(1.5 === $m->getRepeatedFloat()[0]);
assert(1.6 === $m->getRepeatedDouble()[0]);
assert(true=== $m->getRepeatedBool()[0]);
@@ -165,16 +182,24 @@ class TestUtil
assert(TestEnum::ZERO === $m->getRepeatedEnum()[0]);
assert(34 === $m->getRepeatedMessage()[0]->getA());
+ if (PHP_INT_SIZE == 4) {
+ assert('-53' === $m->getRepeatedInt64()[1]);
+ assert('53' === $m->getRepeatedUint64()[1]);
+ assert('-55' === $m->getRepeatedSint64()[1]);
+ assert('57' === $m->getRepeatedFixed64()[1]);
+ assert('-57' === $m->getRepeatedSfixed64()[1]);
+ } else {
+ assert(-53 === $m->getRepeatedInt64()[1]);
+ assert(53 === $m->getRepeatedUint64()[1]);
+ assert(-55 === $m->getRepeatedSint64()[1]);
+ assert(57 === $m->getRepeatedFixed64()[1]);
+ assert(-57 === $m->getRepeatedSfixed64()[1]);
+ }
assert(-52 === $m->getRepeatedInt32()[1]);
assert(52 === $m->getRepeatedUint32()[1]);
- assert(-53 === $m->getRepeatedInt64()[1]);
- assert(53 === $m->getRepeatedUint64()[1]);
assert(-54 === $m->getRepeatedSint32()[1]);
- assert(-55 === $m->getRepeatedSint64()[1]);
assert(56 === $m->getRepeatedFixed32()[1]);
- assert(57 === $m->getRepeatedFixed64()[1]);
assert(-56 === $m->getRepeatedSfixed32()[1]);
- assert(-57 === $m->getRepeatedSfixed64()[1]);
assert(2.5 === $m->getRepeatedFloat()[1]);
assert(2.6 === $m->getRepeatedDouble()[1]);
assert(false === $m->getRepeatedBool()[1]);
@@ -183,14 +208,21 @@ class TestUtil
assert(TestEnum::ONE === $m->getRepeatedEnum()[1]);
assert(35 === $m->getRepeatedMessage()[1]->getA());
+ if (PHP_INT_SIZE == 4) {
+ assert('-63' === $m->getMapInt64Int64()['-63']);
+ assert('63' === $m->getMapUint64Uint64()['63']);
+ assert('-65' === $m->getMapSint64Sint64()['-65']);
+ assert('67' === $m->getMapFixed64Fixed64()['67']);
+ } else {
+ assert(-63 === $m->getMapInt64Int64()[-63]);
+ assert(63 === $m->getMapUint64Uint64()[63]);
+ assert(-65 === $m->getMapSint64Sint64()[-65]);
+ assert(67 === $m->getMapFixed64Fixed64()[67]);
+ }
assert(-62 === $m->getMapInt32Int32()[-62]);
- assert(-63 === $m->getMapInt64Int64()[-63]);
assert(62 === $m->getMapUint32Uint32()[62]);
- assert(63 === $m->getMapUint64Uint64()[63]);
assert(-64 === $m->getMapSint32Sint32()[-64]);
- assert(-65 === $m->getMapSint64Sint64()[-65]);
assert(66 === $m->getMapFixed32Fixed32()[66]);
- assert(67 === $m->getMapFixed64Fixed64()[67]);
assert(3.5 === $m->getMapInt32Float()[1]);
assert(3.6 === $m->getMapInt32Double()[1]);
assert(true === $m->getMapBoolBool()[true]);
@@ -325,24 +357,14 @@ class TestUtil
assert(-42 === $m->getRepeatedInt32()[0]);
assert(-52 === $m->getRepeatedInt32()[1]);
- assert(-43 === $m->getRepeatedInt64()[0]);
- assert(-53 === $m->getRepeatedInt64()[1]);
assert(42 === $m->getRepeatedUint32()[0]);
assert(52 === $m->getRepeatedUint32()[1]);
- assert(43 === $m->getRepeatedUint64()[0]);
- assert(53 === $m->getRepeatedUint64()[1]);
assert(-44 === $m->getRepeatedSint32()[0]);
assert(-54 === $m->getRepeatedSint32()[1]);
- assert(-45 === $m->getRepeatedSint64()[0]);
- assert(-55 === $m->getRepeatedSint64()[1]);
assert(46 === $m->getRepeatedFixed32()[0]);
assert(56 === $m->getRepeatedFixed32()[1]);
- assert(47 === $m->getRepeatedFixed64()[0]);
- assert(57 === $m->getRepeatedFixed64()[1]);
assert(-46 === $m->getRepeatedSfixed32()[0]);
assert(-56 === $m->getRepeatedSfixed32()[1]);
- assert(-47 === $m->getRepeatedSfixed64()[0]);
- assert(-57 === $m->getRepeatedSfixed64()[1]);
assert(1.5 === $m->getRepeatedFloat()[0]);
assert(2.5 === $m->getRepeatedFloat()[1]);
assert(1.6 === $m->getRepeatedDouble()[0]);
@@ -351,6 +373,29 @@ class TestUtil
assert(false === $m->getRepeatedBool()[1]);
assert(TestEnum::ONE === $m->getRepeatedEnum()[0]);
assert(TestEnum::ZERO === $m->getRepeatedEnum()[1]);
+ if (PHP_INT_SIZE == 4) {
+ assert('-43' === $m->getRepeatedInt64()[0]);
+ assert('-53' === $m->getRepeatedInt64()[1]);
+ assert('43' === $m->getRepeatedUint64()[0]);
+ assert('53' === $m->getRepeatedUint64()[1]);
+ assert('-45' === $m->getRepeatedSint64()[0]);
+ assert('-55' === $m->getRepeatedSint64()[1]);
+ assert('47' === $m->getRepeatedFixed64()[0]);
+ assert('57' === $m->getRepeatedFixed64()[1]);
+ assert('-47' === $m->getRepeatedSfixed64()[0]);
+ assert('-57' === $m->getRepeatedSfixed64()[1]);
+ } else {
+ assert(-43 === $m->getRepeatedInt64()[0]);
+ assert(-53 === $m->getRepeatedInt64()[1]);
+ assert(43 === $m->getRepeatedUint64()[0]);
+ assert(53 === $m->getRepeatedUint64()[1]);
+ assert(-45 === $m->getRepeatedSint64()[0]);
+ assert(-55 === $m->getRepeatedSint64()[1]);
+ assert(47 === $m->getRepeatedFixed64()[0]);
+ assert(57 === $m->getRepeatedFixed64()[1]);
+ assert(-47 === $m->getRepeatedSfixed64()[0]);
+ assert(-57 === $m->getRepeatedSfixed64()[1]);
+ }
}
public static function getGoldenTestPackedMessage()
diff --git a/php/tests/well_known_test.php b/php/tests/well_known_test.php
new file mode 100644
index 00000000..30715ba9
--- /dev/null
+++ b/php/tests/well_known_test.php
@@ -0,0 +1,13 @@
+<?php
+
+require_once("google/protobuf/empty.pb.php");
+
+use Google\Protobuf\GPBEmpty;
+
+class WellKnownTest extends PHPUnit_Framework_TestCase {
+
+ public function testNone() {
+ $msg = new GPBEmpty();
+ }
+
+}
diff --git a/phpunit.xml b/phpunit.xml
index d311c509..f9118d8e 100644
--- a/phpunit.xml
+++ b/phpunit.xml
@@ -8,6 +8,7 @@
<file>php/tests/encode_decode_test.php</file>
<file>php/tests/generated_class_test.php</file>
<file>php/tests/map_field_test.php</file>
+ <file>php/tests/well_known_test.php</file>
</testsuite>
</testsuites>
</phpunit>
diff --git a/protobuf.bzl b/protobuf.bzl
index af7302fa..6ae5a594 100644
--- a/protobuf.bzl
+++ b/protobuf.bzl
@@ -13,14 +13,21 @@ def _GenDir(ctx):
return _GetPath(ctx, ctx.attr.includes[0])
return _GetPath(ctx, ctx.label.package + '/' + ctx.attr.includes[0])
-def _CcOuts(srcs, use_grpc_plugin=False):
- ret = [s[:-len(".proto")] + ".pb.h" for s in srcs] + \
- [s[:-len(".proto")] + ".pb.cc" for s in srcs]
+def _CcHdrs(srcs, use_grpc_plugin=False):
+ ret = [s[:-len(".proto")] + ".pb.h" for s in srcs]
+ if use_grpc_plugin:
+ ret += [s[:-len(".proto")] + ".grpc.pb.h" for s in srcs]
+ return ret
+
+def _CcSrcs(srcs, use_grpc_plugin=False):
+ ret = [s[:-len(".proto")] + ".pb.cc" for s in srcs]
if use_grpc_plugin:
- ret += [s[:-len(".proto")] + ".grpc.pb.h" for s in srcs] + \
- [s[:-len(".proto")] + ".grpc.pb.cc" for s in srcs]
+ ret += [s[:-len(".proto")] + ".grpc.pb.cc" for s in srcs]
return ret
+def _CcOuts(srcs, use_grpc_plugin=False):
+ return _CcHdrs(srcs, use_grpc_plugin) + _CcSrcs(srcs, use_grpc_plugin)
+
def _PyOuts(srcs):
return [s[:-len(".proto")] + "_pb2.py" for s in srcs]
@@ -201,7 +208,9 @@ def cc_proto_library(
if use_grpc_plugin:
grpc_cpp_plugin = "//external:grpc_cpp_plugin"
- outs = _CcOuts(srcs, use_grpc_plugin)
+ gen_srcs = _CcSrcs(srcs, use_grpc_plugin)
+ gen_hdrs = _CcHdrs(srcs, use_grpc_plugin)
+ outs = gen_srcs + gen_hdrs
proto_gen(
name=name + "_genproto",
@@ -223,7 +232,8 @@ def cc_proto_library(
native.cc_library(
name=name,
- srcs=outs,
+ srcs=gen_srcs,
+ hdrs=gen_hdrs,
deps=cc_libs + deps,
includes=includes,
**kargs)
diff --git a/python/README.md b/python/README.md
index 57acfd94..8f3db785 100644
--- a/python/README.md
+++ b/python/README.md
@@ -92,7 +92,7 @@ Installation
error: "sem_init: Resource temporarily unavailable". This appears
to be a bug either in Cygwin or in Python:
http://www.cygwin.com/ml/cygwin/2005-07/msg01378.html
- We do not know if or when it might me fixed. We also do not know
+ We do not know if or when it might be fixed. We also do not know
how likely it is that this bug will affect users in practice.
5) Install:
diff --git a/python/google/protobuf/pyext/message.cc b/python/google/protobuf/pyext/message.cc
index 5967a587..4f3abc84 100644
--- a/python/google/protobuf/pyext/message.cc
+++ b/python/google/protobuf/pyext/message.cc
@@ -1994,7 +1994,11 @@ static PyObject* CopyFrom(CMessage* self, PyObject* arg) {
// get OOM errors. The protobuf APIs do not provide any tools for processing
// protobufs in chunks. If you have protos this big you should break them up if
// it is at all convenient to do so.
+#ifdef PROTOBUF_PYTHON_ALLOW_OVERSIZE_PROTOS
+static bool allow_oversize_protos = true;
+#else
static bool allow_oversize_protos = false;
+#endif
// Provide a method in the module to set allow_oversize_protos to a boolean
// value. This method returns the newly value of allow_oversize_protos.
diff --git a/ruby/ext/google/protobuf_c/message.c b/ruby/ext/google/protobuf_c/message.c
index e16250f3..837a974b 100644
--- a/ruby/ext/google/protobuf_c/message.c
+++ b/ruby/ext/google/protobuf_c/message.c
@@ -178,6 +178,45 @@ VALUE Message_method_missing(int argc, VALUE* argv, VALUE _self) {
}
}
+VALUE Message_respond_to_missing(int argc, VALUE* argv, VALUE _self) {
+ MessageHeader* self;
+ VALUE method_name, method_str;
+ char* name;
+ size_t name_len;
+ bool setter;
+ const upb_oneofdef* o;
+ const upb_fielddef* f;
+
+ TypedData_Get_Struct(_self, MessageHeader, &Message_type, self);
+ if (argc < 1) {
+ rb_raise(rb_eArgError, "Expected method name as first argument.");
+ }
+ method_name = argv[0];
+ if (!SYMBOL_P(method_name)) {
+ rb_raise(rb_eArgError, "Expected symbol as method name.");
+ }
+ method_str = rb_id2str(SYM2ID(method_name));
+ name = RSTRING_PTR(method_str);
+ name_len = RSTRING_LEN(method_str);
+ setter = false;
+
+ // Setters have names that end in '='.
+ if (name[name_len - 1] == '=') {
+ setter = true;
+ name_len--;
+ }
+
+ // See if this name corresponds to either a oneof or field in this message.
+ if (!upb_msgdef_lookupname(self->descriptor->msgdef, name, name_len, &f,
+ &o)) {
+ return rb_call_super(argc, argv);
+ }
+ if (o != NULL) {
+ return setter ? Qfalse : Qtrue;
+ }
+ return Qtrue;
+}
+
int Message_initialize_kwarg(VALUE key, VALUE val, VALUE _self) {
MessageHeader* self;
VALUE method_str;
@@ -305,6 +344,9 @@ VALUE Message_deep_copy(VALUE _self) {
VALUE Message_eq(VALUE _self, VALUE _other) {
MessageHeader* self;
MessageHeader* other;
+ if (TYPE(_self) != TYPE(_other)) {
+ return Qfalse;
+ }
TypedData_Get_Struct(_self, MessageHeader, &Message_type, self);
TypedData_Get_Struct(_other, MessageHeader, &Message_type, other);
@@ -459,6 +501,8 @@ VALUE build_class_from_descriptor(Descriptor* desc) {
rb_define_method(klass, "method_missing",
Message_method_missing, -1);
+ rb_define_method(klass, "respond_to_missing?",
+ Message_respond_to_missing, -1);
rb_define_method(klass, "initialize", Message_initialize, -1);
rb_define_method(klass, "dup", Message_dup, 0);
// Also define #clone so that we don't inherit Object#clone.
diff --git a/ruby/tests/basic.rb b/ruby/tests/basic.rb
index 989a047e..967ff81f 100644
--- a/ruby/tests/basic.rb
+++ b/ruby/tests/basic.rb
@@ -1181,5 +1181,15 @@ module BasicTest
m2 = MapMessage.decode_json(MapMessage.encode_json(m))
assert m == m2
end
+
+ def test_comparison_with_arbitrary_object
+ assert_false MapMessage.new == nil
+ end
+
+ def test_respond_to
+ msg = MapMessage.new
+ assert msg.respond_to?(:map_string_int32)
+ assert_false msg.respond_to?(:bacon)
+ end
end
end
diff --git a/ruby/travis-test.sh b/ruby/travis-test.sh
index d3022657..930165e6 100755
--- a/ruby/travis-test.sh
+++ b/ruby/travis-test.sh
@@ -10,12 +10,14 @@ test_version() {
bash --login -c \
"rvm install $version && rvm use $version && rvm get head && \
which ruby && \
+ git clean -f && \
gem install bundler && bundle && \
rake test"
else
bash --login -c \
"rvm install $version && rvm use $version && \
which ruby && \
+ git clean -f && \
gem install bundler && bundle && \
rake test &&
cd ../conformance && make test_ruby"
diff --git a/src/Makefile.am b/src/Makefile.am
index b3a667aa..d6f27fa8 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -61,118 +61,118 @@ CLEANFILES = $(protoc_outputs) unittest_proto_middleman \
MAINTAINERCLEANFILES = \
Makefile.in
-nobase_include_HEADERS = \
- google/protobuf/stubs/atomic_sequence_num.h \
- google/protobuf/stubs/atomicops.h \
- google/protobuf/stubs/atomicops_internals_power.h \
- google/protobuf/stubs/atomicops_internals_ppc_gcc.h \
- google/protobuf/stubs/atomicops_internals_arm64_gcc.h \
- google/protobuf/stubs/atomicops_internals_arm_gcc.h \
- google/protobuf/stubs/atomicops_internals_arm_qnx.h \
- google/protobuf/stubs/atomicops_internals_atomicword_compat.h \
- google/protobuf/stubs/atomicops_internals_generic_gcc.h \
- google/protobuf/stubs/atomicops_internals_macosx.h \
- google/protobuf/stubs/atomicops_internals_mips_gcc.h \
- google/protobuf/stubs/atomicops_internals_pnacl.h \
- google/protobuf/stubs/atomicops_internals_solaris.h \
- google/protobuf/stubs/atomicops_internals_tsan.h \
- google/protobuf/stubs/atomicops_internals_x86_gcc.h \
- google/protobuf/stubs/atomicops_internals_x86_msvc.h \
- google/protobuf/stubs/callback.h \
- google/protobuf/stubs/bytestream.h \
- google/protobuf/stubs/casts.h \
- google/protobuf/stubs/common.h \
- google/protobuf/stubs/fastmem.h \
- google/protobuf/stubs/hash.h \
- google/protobuf/stubs/logging.h \
- google/protobuf/stubs/macros.h \
- google/protobuf/stubs/mutex.h \
- google/protobuf/stubs/once.h \
- google/protobuf/stubs/platform_macros.h \
- google/protobuf/stubs/port.h \
- google/protobuf/stubs/scoped_ptr.h \
- google/protobuf/stubs/shared_ptr.h \
- google/protobuf/stubs/singleton.h \
- google/protobuf/stubs/status.h \
- google/protobuf/stubs/stl_util.h \
- google/protobuf/stubs/stringpiece.h \
- google/protobuf/stubs/template_util.h \
- google/protobuf/stubs/type_traits.h \
- google/protobuf/any.pb.h \
- google/protobuf/api.pb.h \
- google/protobuf/any.h \
- google/protobuf/arena.h \
- google/protobuf/arenastring.h \
- google/protobuf/descriptor_database.h \
- google/protobuf/descriptor.h \
- google/protobuf/descriptor.pb.h \
- google/protobuf/duration.pb.h \
- google/protobuf/dynamic_message.h \
- google/protobuf/empty.pb.h \
- google/protobuf/extension_set.h \
- google/protobuf/field_mask.pb.h \
- google/protobuf/generated_enum_reflection.h \
- google/protobuf/generated_enum_util.h \
- google/protobuf/generated_message_reflection.h \
- google/protobuf/generated_message_util.h \
- google/protobuf/has_bits.h \
- google/protobuf/map_entry.h \
- google/protobuf/map_entry_lite.h \
- google/protobuf/map_field.h \
- google/protobuf/map_field_inl.h \
- google/protobuf/map_field_lite.h \
- google/protobuf/map.h \
- google/protobuf/map_type_handler.h \
- google/protobuf/message.h \
- google/protobuf/message_lite.h \
- google/protobuf/metadata.h \
- google/protobuf/reflection.h \
- google/protobuf/reflection_ops.h \
- google/protobuf/repeated_field.h \
- google/protobuf/service.h \
- google/protobuf/source_context.pb.h \
- google/protobuf/struct.pb.h \
- google/protobuf/text_format.h \
- google/protobuf/timestamp.pb.h \
- google/protobuf/type.pb.h \
- google/protobuf/unknown_field_set.h \
- google/protobuf/wire_format.h \
- google/protobuf/wire_format_lite.h \
- google/protobuf/wire_format_lite_inl.h \
- google/protobuf/wrappers.pb.h \
- google/protobuf/io/coded_stream.h \
- $(GZHEADERS) \
- google/protobuf/io/printer.h \
- google/protobuf/io/strtod.h \
- google/protobuf/io/tokenizer.h \
- google/protobuf/io/zero_copy_stream.h \
- google/protobuf/io/zero_copy_stream_impl.h \
- google/protobuf/io/zero_copy_stream_impl_lite.h \
- google/protobuf/compiler/code_generator.h \
- google/protobuf/compiler/command_line_interface.h \
- google/protobuf/compiler/importer.h \
- google/protobuf/compiler/parser.h \
- google/protobuf/compiler/plugin.h \
- google/protobuf/compiler/plugin.pb.h \
- google/protobuf/compiler/cpp/cpp_generator.h \
- google/protobuf/compiler/csharp/csharp_generator.h \
- google/protobuf/compiler/csharp/csharp_names.h \
- google/protobuf/compiler/java/java_generator.h \
- google/protobuf/compiler/java/java_names.h \
- google/protobuf/compiler/javanano/javanano_generator.h \
- google/protobuf/compiler/js/js_generator.h \
- google/protobuf/compiler/js/well_known_types_embed.h \
- google/protobuf/compiler/objectivec/objectivec_generator.h \
- google/protobuf/compiler/objectivec/objectivec_helpers.h \
- google/protobuf/compiler/php/php_generator.h \
- google/protobuf/compiler/python/python_generator.h \
- google/protobuf/compiler/ruby/ruby_generator.h \
- google/protobuf/util/type_resolver.h \
- google/protobuf/util/field_comparator.h \
- google/protobuf/util/field_mask_util.h \
- google/protobuf/util/json_util.h \
- google/protobuf/util/time_util.h \
- google/protobuf/util/type_resolver_util.h \
+nobase_include_HEADERS = \
+ google/protobuf/stubs/atomic_sequence_num.h \
+ google/protobuf/stubs/atomicops.h \
+ google/protobuf/stubs/atomicops_internals_power.h \
+ google/protobuf/stubs/atomicops_internals_ppc_gcc.h \
+ google/protobuf/stubs/atomicops_internals_arm64_gcc.h \
+ google/protobuf/stubs/atomicops_internals_arm_gcc.h \
+ google/protobuf/stubs/atomicops_internals_arm_qnx.h \
+ google/protobuf/stubs/atomicops_internals_atomicword_compat.h \
+ google/protobuf/stubs/atomicops_internals_generic_c11_atomic.h \
+ google/protobuf/stubs/atomicops_internals_generic_gcc.h \
+ google/protobuf/stubs/atomicops_internals_macosx.h \
+ google/protobuf/stubs/atomicops_internals_mips_gcc.h \
+ google/protobuf/stubs/atomicops_internals_solaris.h \
+ google/protobuf/stubs/atomicops_internals_tsan.h \
+ google/protobuf/stubs/atomicops_internals_x86_gcc.h \
+ google/protobuf/stubs/atomicops_internals_x86_msvc.h \
+ google/protobuf/stubs/callback.h \
+ google/protobuf/stubs/bytestream.h \
+ google/protobuf/stubs/casts.h \
+ google/protobuf/stubs/common.h \
+ google/protobuf/stubs/fastmem.h \
+ google/protobuf/stubs/hash.h \
+ google/protobuf/stubs/logging.h \
+ google/protobuf/stubs/macros.h \
+ google/protobuf/stubs/mutex.h \
+ google/protobuf/stubs/once.h \
+ google/protobuf/stubs/platform_macros.h \
+ google/protobuf/stubs/port.h \
+ google/protobuf/stubs/scoped_ptr.h \
+ google/protobuf/stubs/shared_ptr.h \
+ google/protobuf/stubs/singleton.h \
+ google/protobuf/stubs/status.h \
+ google/protobuf/stubs/stl_util.h \
+ google/protobuf/stubs/stringpiece.h \
+ google/protobuf/stubs/template_util.h \
+ google/protobuf/stubs/type_traits.h \
+ google/protobuf/any.pb.h \
+ google/protobuf/api.pb.h \
+ google/protobuf/any.h \
+ google/protobuf/arena.h \
+ google/protobuf/arenastring.h \
+ google/protobuf/descriptor_database.h \
+ google/protobuf/descriptor.h \
+ google/protobuf/descriptor.pb.h \
+ google/protobuf/duration.pb.h \
+ google/protobuf/dynamic_message.h \
+ google/protobuf/empty.pb.h \
+ google/protobuf/extension_set.h \
+ google/protobuf/field_mask.pb.h \
+ google/protobuf/generated_enum_reflection.h \
+ google/protobuf/generated_enum_util.h \
+ google/protobuf/generated_message_reflection.h \
+ google/protobuf/generated_message_util.h \
+ google/protobuf/has_bits.h \
+ google/protobuf/map_entry.h \
+ google/protobuf/map_entry_lite.h \
+ google/protobuf/map_field.h \
+ google/protobuf/map_field_inl.h \
+ google/protobuf/map_field_lite.h \
+ google/protobuf/map.h \
+ google/protobuf/map_type_handler.h \
+ google/protobuf/message.h \
+ google/protobuf/message_lite.h \
+ google/protobuf/metadata.h \
+ google/protobuf/reflection.h \
+ google/protobuf/reflection_ops.h \
+ google/protobuf/repeated_field.h \
+ google/protobuf/service.h \
+ google/protobuf/source_context.pb.h \
+ google/protobuf/struct.pb.h \
+ google/protobuf/text_format.h \
+ google/protobuf/timestamp.pb.h \
+ google/protobuf/type.pb.h \
+ google/protobuf/unknown_field_set.h \
+ google/protobuf/wire_format.h \
+ google/protobuf/wire_format_lite.h \
+ google/protobuf/wire_format_lite_inl.h \
+ google/protobuf/wrappers.pb.h \
+ google/protobuf/io/coded_stream.h \
+ $(GZHEADERS) \
+ google/protobuf/io/printer.h \
+ google/protobuf/io/strtod.h \
+ google/protobuf/io/tokenizer.h \
+ google/protobuf/io/zero_copy_stream.h \
+ google/protobuf/io/zero_copy_stream_impl.h \
+ google/protobuf/io/zero_copy_stream_impl_lite.h \
+ google/protobuf/compiler/code_generator.h \
+ google/protobuf/compiler/command_line_interface.h \
+ google/protobuf/compiler/importer.h \
+ google/protobuf/compiler/parser.h \
+ google/protobuf/compiler/plugin.h \
+ google/protobuf/compiler/plugin.pb.h \
+ google/protobuf/compiler/cpp/cpp_generator.h \
+ google/protobuf/compiler/csharp/csharp_generator.h \
+ google/protobuf/compiler/csharp/csharp_names.h \
+ google/protobuf/compiler/java/java_generator.h \
+ google/protobuf/compiler/java/java_names.h \
+ google/protobuf/compiler/javanano/javanano_generator.h \
+ google/protobuf/compiler/js/js_generator.h \
+ google/protobuf/compiler/js/well_known_types_embed.h \
+ google/protobuf/compiler/objectivec/objectivec_generator.h \
+ google/protobuf/compiler/objectivec/objectivec_helpers.h \
+ google/protobuf/compiler/php/php_generator.h \
+ google/protobuf/compiler/python/python_generator.h \
+ google/protobuf/compiler/ruby/ruby_generator.h \
+ google/protobuf/util/type_resolver.h \
+ google/protobuf/util/field_comparator.h \
+ google/protobuf/util/field_mask_util.h \
+ google/protobuf/util/json_util.h \
+ google/protobuf/util/time_util.h \
+ google/protobuf/util/type_resolver_util.h \
google/protobuf/util/message_differencer.h
lib_LTLIBRARIES = libprotobuf-lite.la libprotobuf.la libprotoc.la
diff --git a/src/google/protobuf/arena.h b/src/google/protobuf/arena.h
index f05277ed..87066507 100644
--- a/src/google/protobuf/arena.h
+++ b/src/google/protobuf/arena.h
@@ -83,6 +83,7 @@ inline void arena_free(void* object, size_t size) {
#if defined(__GXX_DELETE_WITH_SIZE__) || defined(__cpp_sized_deallocation)
::operator delete(object, size);
#else
+ (void)size;
::operator delete(object);
#endif
}
diff --git a/src/google/protobuf/compiler/command_line_interface.cc b/src/google/protobuf/compiler/command_line_interface.cc
index c1243272..78ceb68c 100644
--- a/src/google/protobuf/compiler/command_line_interface.cc
+++ b/src/google/protobuf/compiler/command_line_interface.cc
@@ -263,6 +263,12 @@ void AddDefaultProtoPaths(vector<pair<string, string> >* paths) {
return;
}
}
+
+string PluginName(const string& plugin_prefix, const string& directive) {
+ // Assuming the directive starts with "--" and ends with "_out" or "_opt",
+ // strip the "--" and "_out/_opt" and add the plugin prefix.
+ return plugin_prefix + "gen-" + directive.substr(2, directive.size() - 6);
+}
} // namespace
// A MultiFileErrorCollector that prints errors to stderr.
@@ -1008,6 +1014,18 @@ CommandLineInterface::ParseArguments(int argc, const char* const argv[]) {
return status;
}
+ // Make sure each plugin option has a matching plugin output.
+ for (map<string, string>::const_iterator i = plugin_parameters_.begin();
+ i != plugin_parameters_.end(); ++i) {
+ if (plugins_.find(i->first) == plugins_.end()) {
+ std::cerr << "Unknown flag: "
+ // strip prefix + "gen-" and add back "_opt"
+ << "--" + i->first.substr(plugin_prefix_.size() + 4) + "_opt"
+ << std::endl;
+ return PARSE_ARGUMENT_FAIL;
+ }
+ }
+
// If no --proto_path was given, use the current working directory.
if (proto_path_.empty()) {
// Don't use make_pair as the old/default standard library on Solaris
@@ -1338,15 +1356,22 @@ CommandLineInterface::InterpretArgument(const string& name,
(plugin_prefix_.empty() || !HasSuffixString(name, "_out"))) {
// Check if it's a generator option flag.
generator_info = FindOrNull(generators_by_option_name_, name);
- if (generator_info == NULL) {
- std::cerr << "Unknown flag: " << name << std::endl;
- return PARSE_ARGUMENT_FAIL;
- } else {
+ if (generator_info != NULL) {
string* parameters = &generator_parameters_[generator_info->flag_name];
if (!parameters->empty()) {
parameters->append(",");
}
parameters->append(value);
+ } else if (HasPrefixString(name, "--") && HasSuffixString(name, "_opt")) {
+ string* parameters =
+ &plugin_parameters_[PluginName(plugin_prefix_, name)];
+ if (!parameters->empty()) {
+ parameters->append(",");
+ }
+ parameters->append(value);
+ } else {
+ std::cerr << "Unknown flag: " << name << std::endl;
+ return PARSE_ARGUMENT_FAIL;
}
} else {
// It's an output flag. Add it to the output directives.
@@ -1465,12 +1490,16 @@ bool CommandLineInterface::GenerateOutput(
HasSuffixString(output_directive.name, "_out"))
<< "Bad name for plugin generator: " << output_directive.name;
- // Strip the "--" and "_out" and add the plugin prefix.
- string plugin_name = plugin_prefix_ + "gen-" +
- output_directive.name.substr(2, output_directive.name.size() - 6);
-
+ string plugin_name = PluginName(plugin_prefix_ , output_directive.name);
+ string parameters = output_directive.parameter;
+ if (!plugin_parameters_[plugin_name].empty()) {
+ if (!parameters.empty()) {
+ parameters.append(",");
+ }
+ parameters.append(plugin_parameters_[plugin_name]);
+ }
if (!GeneratePluginOutput(parsed_files, plugin_name,
- output_directive.parameter,
+ parameters,
generator_context, &error)) {
std::cerr << output_directive.name << ": " << error << std::endl;
return false;
diff --git a/src/google/protobuf/compiler/command_line_interface.h b/src/google/protobuf/compiler/command_line_interface.h
index a1a6ab39..28471ee7 100644
--- a/src/google/protobuf/compiler/command_line_interface.h
+++ b/src/google/protobuf/compiler/command_line_interface.h
@@ -144,14 +144,14 @@ class LIBPROTOC_EXPORT CommandLineInterface {
// plugin [--out=OUTDIR] [--parameter=PARAMETER] PROTO_FILES < DESCRIPTORS
// --out indicates the output directory (as passed to the --foo_out
// parameter); if omitted, the current directory should be used. --parameter
- // gives the generator parameter, if any was provided. The PROTO_FILES list
- // the .proto files which were given on the compiler command-line; these are
- // the files for which the plugin is expected to generate output code.
- // Finally, DESCRIPTORS is an encoded FileDescriptorSet (as defined in
- // descriptor.proto). This is piped to the plugin's stdin. The set will
- // include descriptors for all the files listed in PROTO_FILES as well as
- // all files that they import. The plugin MUST NOT attempt to read the
- // PROTO_FILES directly -- it must use the FileDescriptorSet.
+ // gives the generator parameter, if any was provided (see below). The
+ // PROTO_FILES list the .proto files which were given on the compiler
+ // command-line; these are the files for which the plugin is expected to
+ // generate output code. Finally, DESCRIPTORS is an encoded FileDescriptorSet
+ // (as defined in descriptor.proto). This is piped to the plugin's stdin.
+ // The set will include descriptors for all the files listed in PROTO_FILES as
+ // well as all files that they import. The plugin MUST NOT attempt to read
+ // the PROTO_FILES directly -- it must use the FileDescriptorSet.
//
// The plugin should generate whatever files are necessary, as code generators
// normally do. It should write the names of all files it generates to
@@ -159,6 +159,13 @@ class LIBPROTOC_EXPORT CommandLineInterface {
// names or relative to the current directory. If any errors occur, error
// messages should be written to stderr. If an error is fatal, the plugin
// should exit with a non-zero exit code.
+ //
+ // Plugins can have generator parameters similar to normal built-in
+ // generators. Extra generator parameters can be passed in via a matching
+ // "_opt" parameter. For example:
+ // protoc --plug_out=enable_bar:outdir --plug_opt=enable_baz
+ // This will pass "enable_bar,enable_baz" as the parameter to the plugin.
+ //
void AllowPlugins(const string& exe_name_prefix);
// Run the Protocol Compiler with the given command-line parameters.
@@ -314,6 +321,8 @@ class LIBPROTOC_EXPORT CommandLineInterface {
// protoc --foo_out=outputdir --foo_opt=enable_bar ...
// Then there will be an entry ("--foo_out", "enable_bar") in this map.
std::map<string, string> generator_parameters_;
+ // Similar to generator_parameters_, but stores the parameters for plugins.
+ std::map<string, string> plugin_parameters_;
// See AllowPlugins(). If this is empty, plugins aren't allowed.
string plugin_prefix_;
diff --git a/src/google/protobuf/compiler/command_line_interface_unittest.cc b/src/google/protobuf/compiler/command_line_interface_unittest.cc
index 6600cc2f..d5b5b185 100644
--- a/src/google/protobuf/compiler/command_line_interface_unittest.cc
+++ b/src/google/protobuf/compiler/command_line_interface_unittest.cc
@@ -653,6 +653,44 @@ TEST_F(CommandLineInterfaceTest, ExtraGeneratorParameters) {
"test_generator", "baz,foo1,foo2,foo3", "foo.proto", "Foo", "b");
}
+TEST_F(CommandLineInterfaceTest, ExtraPluginParameters) {
+ // Test that generator parameters specified with the option flag are
+ // correctly passed to the code generator.
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+ // Create the "a" and "b" sub-directories.
+ CreateTempDir("a");
+ CreateTempDir("b");
+
+ Run("protocol_compiler "
+ "--plug_opt=foo1 "
+ "--plug_out=bar:$tmpdir/a "
+ "--plug_opt=foo2 "
+ "--plug_out=baz:$tmpdir/b "
+ "--plug_opt=foo3 "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectNoErrors();
+ ExpectGenerated(
+ "test_plugin", "bar,foo1,foo2,foo3", "foo.proto", "Foo", "a");
+ ExpectGenerated(
+ "test_plugin", "baz,foo1,foo2,foo3", "foo.proto", "Foo", "b");
+}
+
+TEST_F(CommandLineInterfaceTest, UnrecognizedExtraParameters) {
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+
+ Run("protocol_compiler --plug_out=TestParameter:$tmpdir "
+ "--unknown_plug_opt=Foo "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectErrorSubstring("Unknown flag: --unknown_plug_opt");
+}
+
TEST_F(CommandLineInterfaceTest, Insert) {
// Test running a generator that inserts code into another's output.
diff --git a/src/google/protobuf/compiler/mock_code_generator.cc b/src/google/protobuf/compiler/mock_code_generator.cc
index 156784b5..979814ec 100644
--- a/src/google/protobuf/compiler/mock_code_generator.cc
+++ b/src/google/protobuf/compiler/mock_code_generator.cc
@@ -61,7 +61,7 @@ namespace compiler {
// comma-separated string.
string CommaSeparatedList(const std::vector<const FileDescriptor*> all_files) {
std::vector<string> names;
- for (int i = 0; i < all_files.size(); i++) {
+ for (size_t i = 0; i < all_files.size(); i++) {
names.push_back(all_files[i]->name());
}
return Join(names, ",");
@@ -98,7 +98,7 @@ void MockCodeGenerator::ExpectGenerated(
while (!lines.empty() && lines.back().empty()) {
lines.pop_back();
}
- for (int i = 0; i < lines.size(); i++) {
+ for (size_t i = 0; i < lines.size(); i++) {
lines[i] += "\n";
}
@@ -115,7 +115,7 @@ void MockCodeGenerator::ExpectGenerated(
EXPECT_EQ(kFirstInsertionPoint, lines[1 + insertion_list.size()]);
EXPECT_EQ(kSecondInsertionPoint, lines[2 + insertion_list.size() * 2]);
- for (int i = 0; i < insertion_list.size(); i++) {
+ for (size_t i = 0; i < insertion_list.size(); i++) {
EXPECT_EQ(GetOutputFileContent(insertion_list[i], "first_insert",
file, file, first_message_name),
lines[1 + i]);
@@ -171,7 +171,7 @@ bool MockCodeGenerator::Generate(
SplitStringUsing(StripPrefixString(parameter, "insert="),
",", &insert_into);
- for (int i = 0; i < insert_into.size(); i++) {
+ for (size_t i = 0; i < insert_into.size(); i++) {
{
google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output(context->OpenForInsert(
GetOutputFileName(insert_into[i], file), kFirstInsertionPointName));
diff --git a/src/google/protobuf/compiler/php/php_generator.cc b/src/google/protobuf/compiler/php/php_generator.cc
index 75ddb405..83e629b9 100644
--- a/src/google/protobuf/compiler/php/php_generator.cc
+++ b/src/google/protobuf/compiler/php/php_generator.cc
@@ -70,6 +70,16 @@ void GenerateEnum(const google::protobuf::EnumDescriptor* en,
void Indent(google::protobuf::io::Printer* printer);
void Outdent(google::protobuf::io::Printer* printer);
+std::string MessagePrefix(const google::protobuf::Descriptor* message) {
+ // Empty cannot be php class name.
+ if (message->name() == "Empty" &&
+ message->file()->package() == "google.protobuf") {
+ return "GPB";
+ } else {
+ return "";
+ }
+}
+
std::string MessageName(const google::protobuf::Descriptor* message,
bool is_descriptor) {
string message_name = message->name();
@@ -78,6 +88,8 @@ std::string MessageName(const google::protobuf::Descriptor* message,
message_name = descriptor->name() + '_' + message_name;
descriptor = descriptor->containing_type();
}
+ message_name = MessagePrefix(message) + message_name;
+
return PhpName(message->file()->package(), is_descriptor) + '\\' +
message_name;
}
@@ -483,8 +495,10 @@ void GenerateMessage(const string& name_prefix,
return;
}
- string message_name = name_prefix.empty()?
- message->name() : name_prefix + "_" + message->name();
+ string message_name =
+ name_prefix.empty()
+ ? message->name()
+ : name_prefix + "_" + MessagePrefix(message) + message->name();
printer->Print(
"class @name@ extends \\Google\\Protobuf\\Internal\\Message\n"
diff --git a/src/google/protobuf/repeated_field.h b/src/google/protobuf/repeated_field.h
index eaaf1795..bbdef449 100644
--- a/src/google/protobuf/repeated_field.h
+++ b/src/google/protobuf/repeated_field.h
@@ -686,8 +686,7 @@ inline const Message& GenericTypeHandler<Message>::default_instance() {
return *null;
}
-
-class StringTypeHandler {
+class LIBPROTOBUF_EXPORT StringTypeHandler {
public:
typedef string Type;
diff --git a/src/google/protobuf/stubs/atomicops.h b/src/google/protobuf/stubs/atomicops.h
index 9b3d1e6b..10a71ed4 100644
--- a/src/google/protobuf/stubs/atomicops.h
+++ b/src/google/protobuf/stubs/atomicops.h
@@ -196,14 +196,22 @@ Atomic64 Release_Load(volatile const Atomic64* ptr);
// Apple.
#elif defined(GOOGLE_PROTOBUF_OS_APPLE)
+#if __has_feature(cxx_atomic) || _GNUC_VER >= 407
+#include <google/protobuf/stubs/atomicops_internals_generic_c11_atomic.h>
+#else // __has_feature(cxx_atomic) || _GNUC_VER >= 407
#include <google/protobuf/stubs/atomicops_internals_macosx.h>
+#endif // __has_feature(cxx_atomic) || _GNUC_VER >= 407
// GCC.
#elif defined(__GNUC__)
#if defined(GOOGLE_PROTOBUF_ARCH_IA32) || defined(GOOGLE_PROTOBUF_ARCH_X64)
#include <google/protobuf/stubs/atomicops_internals_x86_gcc.h>
#elif defined(GOOGLE_PROTOBUF_ARCH_ARM) && defined(__linux__)
+#if (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4))
+#include <google/protobuf/stubs/atomicops_internals_generic_gcc.h>
+#else
#include <google/protobuf/stubs/atomicops_internals_arm_gcc.h>
+#endif
#elif defined(GOOGLE_PROTOBUF_ARCH_AARCH64)
#include <google/protobuf/stubs/atomicops_internals_arm64_gcc.h>
#elif defined(GOOGLE_PROTOBUF_ARCH_ARM_QNX)
@@ -213,7 +221,7 @@ Atomic64 Release_Load(volatile const Atomic64* ptr);
#elif defined(GOOGLE_PROTOBUF_ARCH_POWER)
#include <google/protobuf/stubs/atomicops_internals_power.h>
#elif defined(__native_client__)
-#include <google/protobuf/stubs/atomicops_internals_pnacl.h>
+#include <google/protobuf/stubs/atomicops_internals_generic_c11_atomic.h>
#elif defined(GOOGLE_PROTOBUF_ARCH_PPC)
#include <google/protobuf/stubs/atomicops_internals_ppc_gcc.h>
#elif (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4))
diff --git a/src/google/protobuf/stubs/atomicops_internals_pnacl.h b/src/google/protobuf/stubs/atomicops_internals_generic_c11_atomic.h
index 3b314fd0..7bc584eb 100644
--- a/src/google/protobuf/stubs/atomicops_internals_pnacl.h
+++ b/src/google/protobuf/stubs/atomicops_internals_generic_c11_atomic.h
@@ -30,8 +30,8 @@
// This file is an internal atomic implementation, use atomicops.h instead.
-#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_PNACL_H_
-#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_PNACL_H_
+#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_GENERIC_C11_ATOMIC_H_
+#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_GENERIC_C11_ATOMIC_H_
#include <atomic>
@@ -228,4 +228,4 @@ inline Atomic64 Release_Load(volatile const Atomic64* ptr) {
} // namespace protobuf
} // namespace google
-#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_PNACL_H_
+#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_GENERIC_C11_ATOMIC_H_
diff --git a/src/google/protobuf/stubs/atomicops_internals_generic_gcc.h b/src/google/protobuf/stubs/atomicops_internals_generic_gcc.h
index 7314ee4f..7f17b30d 100644
--- a/src/google/protobuf/stubs/atomicops_internals_generic_gcc.h
+++ b/src/google/protobuf/stubs/atomicops_internals_generic_gcc.h
@@ -38,7 +38,7 @@ namespace internal {
inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
Atomic32 old_value,
Atomic32 new_value) {
- __atomic_compare_exchange_n(ptr, &old_value, new_value, true,
+ __atomic_compare_exchange_n(ptr, &old_value, new_value, false,
__ATOMIC_RELAXED, __ATOMIC_RELAXED);
return old_value;
}
@@ -61,7 +61,7 @@ inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
Atomic32 old_value,
Atomic32 new_value) {
- __atomic_compare_exchange_n(ptr, &old_value, new_value, true,
+ __atomic_compare_exchange_n(ptr, &old_value, new_value, false,
__ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE);
return old_value;
}
@@ -69,7 +69,7 @@ inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
Atomic32 old_value,
Atomic32 new_value) {
- __atomic_compare_exchange_n(ptr, &old_value, new_value, true,
+ __atomic_compare_exchange_n(ptr, &old_value, new_value, false,
__ATOMIC_RELEASE, __ATOMIC_ACQUIRE);
return old_value;
}
@@ -115,7 +115,7 @@ inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
Atomic64 old_value,
Atomic64 new_value) {
- __atomic_compare_exchange_n(ptr, &old_value, new_value, true,
+ __atomic_compare_exchange_n(ptr, &old_value, new_value, false,
__ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE);
return old_value;
}
@@ -123,7 +123,7 @@ inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
Atomic64 old_value,
Atomic64 new_value) {
- __atomic_compare_exchange_n(ptr, &old_value, new_value, true,
+ __atomic_compare_exchange_n(ptr, &old_value, new_value, false,
__ATOMIC_RELAXED, __ATOMIC_RELAXED);
return old_value;
}
diff --git a/src/google/protobuf/stubs/platform_macros.h b/src/google/protobuf/stubs/platform_macros.h
index 4ba4b348..8b7f224f 100644
--- a/src/google/protobuf/stubs/platform_macros.h
+++ b/src/google/protobuf/stubs/platform_macros.h
@@ -114,11 +114,11 @@ GOOGLE_PROTOBUF_PLATFORM_ERROR
#undef GOOGLE_PROTOBUF_PLATFORM_ERROR
-#if defined(GOOGLE_PROTOBUF_OS_ANDROID) || defined(GOOGLE_PROTOBUF_OS_IPHONE)
+#if defined(GOOGLE_PROTOBUF_OS_ANDROID) || defined(GOOGLE_PROTOBUF_OS_IPHONE) || defined(__OpenBSD__)
// Android ndk does not support the __thread keyword very well yet. Here
// we use pthread_key_create()/pthread_getspecific()/... methods for
// TLS support on android.
-// iOS also does not support the __thread keyword.
+// iOS and OpenBSD also do not support the __thread keyword.
#define GOOGLE_PROTOBUF_NO_THREADLOCAL
#endif
diff --git a/src/google/protobuf/stubs/type_traits.h b/src/google/protobuf/stubs/type_traits.h
index 8d48c6aa..3ab5ea7d 100644
--- a/src/google/protobuf/stubs/type_traits.h
+++ b/src/google/protobuf/stubs/type_traits.h
@@ -139,18 +139,10 @@ template<> struct is_integral<int> : true_type { };
template<> struct is_integral<unsigned int> : true_type { };
template<> struct is_integral<long> : true_type { };
template<> struct is_integral<unsigned long> : true_type { };
-#ifdef HAVE_LONG_LONG
+#if defined(HAVE_LONG_LONG) || defined(_MSC_VER)
template<> struct is_integral<long long> : true_type { };
template<> struct is_integral<unsigned long long> : true_type { };
#endif
-#if defined(_MSC_VER)
-// With VC, __int8, __int16, and __int32 are synonymous with standard types
-// with the same size, but __int64 has not equivalent (i.e., it's neither
-// long, nor long long and should be treated differnetly).
-// https://msdn.microsoft.com/en-us/library/29dh1w7z.aspx
-template<> struct is_integral<__int64> : true_type { };
-template<> struct is_integral<unsigned __int64> : true_type {};
-#endif
template <class T> struct is_integral<const T> : is_integral<T> { };
template <class T> struct is_integral<volatile T> : is_integral<T> { };
template <class T> struct is_integral<const volatile T> : is_integral<T> { };
diff --git a/src/google/protobuf/util/internal/constants.h b/src/google/protobuf/util/internal/constants.h
index e556888c..a018a09e 100644
--- a/src/google/protobuf/util/internal/constants.h
+++ b/src/google/protobuf/util/internal/constants.h
@@ -50,16 +50,16 @@ const char kRfc3339TimeFormat[] = "%E4Y-%m-%dT%H:%M:%S";
const char kRfc3339TimeFormatNoPadding[] = "%Y-%m-%dT%H:%M:%S";
// Minimun seconds allowed in a google.protobuf.Timestamp value.
-const int64 kTimestampMinSeconds = -62135596800;
+const int64 kTimestampMinSeconds = -62135596800LL;
// Maximum seconds allowed in a google.protobuf.Timestamp value.
-const int64 kTimestampMaxSeconds = 253402300799;
+const int64 kTimestampMaxSeconds = 253402300799LL;
// Minimum seconds allowed in a google.protobuf.Duration value.
-const int64 kDurationMinSeconds = -315576000000;
+const int64 kDurationMinSeconds = -315576000000LL;
// Maximum seconds allowed in a google.protobuf.Duration value.
-const int64 kDurationMaxSeconds = 315576000000;
+const int64 kDurationMaxSeconds = 315576000000LL;
// Nano seconds in a second.
const int32 kNanosPerSecond = 1000000000;
diff --git a/src/google/protobuf/util/internal/protostream_objectsource.cc b/src/google/protobuf/util/internal/protostream_objectsource.cc
index 554757d0..a970dc12 100644
--- a/src/google/protobuf/util/internal/protostream_objectsource.cc
+++ b/src/google/protobuf/util/internal/protostream_objectsource.cc
@@ -1028,8 +1028,11 @@ bool ProtoStreamObjectSource::IsMap(
// TODO(xiaofeng): Unify option names.
return field.kind() == google::protobuf::Field_Kind_TYPE_MESSAGE &&
(GetBoolOptionOrDefault(field_type->options(),
- "google.protobuf.MessageOptions.map_entry", false) ||
- GetBoolOptionOrDefault(field_type->options(), "map_entry", false));
+ "google.protobuf.MessageOptions.map_entry",
+ false) ||
+ GetBoolOptionOrDefault(field_type->options(), "map_entry", false) ||
+ GetBoolOptionOrDefault(field_type->options(),
+ "proto2.MessageOptions.map_entry", false));
}
std::pair<int64, int32> ProtoStreamObjectSource::ReadSecondsAndNanos(
@@ -1125,3 +1128,4 @@ const string FormatNanos(uint32 nanos, bool with_trailing_zeros) {
} // namespace util
} // namespace protobuf
} // namespace google
+
diff --git a/src/google/protobuf/util/internal/protostream_objectwriter.cc b/src/google/protobuf/util/internal/protostream_objectwriter.cc
index 6c15e862..c37e671c 100644
--- a/src/google/protobuf/util/internal/protostream_objectwriter.cc
+++ b/src/google/protobuf/util/internal/protostream_objectwriter.cc
@@ -1240,8 +1240,11 @@ bool ProtoStreamObjectWriter::IsMap(const google::protobuf::Field& field) {
// TODO(xiaofeng): Unify option names.
return GetBoolOptionOrDefault(field_type->options(),
- "google.protobuf.MessageOptions.map_entry", false) ||
- GetBoolOptionOrDefault(field_type->options(), "map_entry", false);
+ "google.protobuf.MessageOptions.map_entry",
+ false) ||
+ GetBoolOptionOrDefault(field_type->options(), "map_entry", false) ||
+ GetBoolOptionOrDefault(field_type->options(),
+ "proto2.MessageOptions.map_entry", false);
}
bool ProtoStreamObjectWriter::IsAny(const google::protobuf::Field& field) {
@@ -1266,3 +1269,4 @@ bool ProtoStreamObjectWriter::IsStructListValue(
} // namespace util
} // namespace protobuf
} // namespace google
+
diff --git a/src/google/protobuf/util/internal/utility.cc b/src/google/protobuf/util/internal/utility.cc
index d74c3f3a..05759e85 100644
--- a/src/google/protobuf/util/internal/utility.cc
+++ b/src/google/protobuf/util/internal/utility.cc
@@ -356,15 +356,23 @@ bool IsValidBoolString(const string& bool_string) {
bool IsMap(const google::protobuf::Field& field,
const google::protobuf::Type& type) {
- return (field.cardinality() ==
- google::protobuf::Field_Cardinality_CARDINALITY_REPEATED &&
- GetBoolOptionOrDefault(type.options(),
- "google.protobuf.MessageOptions.map_entry", false));
+ return (
+ field.cardinality() ==
+ google::protobuf::Field_Cardinality_CARDINALITY_REPEATED &&
+ (GetBoolOptionOrDefault(
+ type.options(), "google.protobuf.MessageOptions.map_entry", false) ||
+ GetBoolOptionOrDefault(type.options(), "proto2.MessageOptions.map_entry",
+ false)));
}
bool IsMessageSetWireFormat(const google::protobuf::Type& type) {
- return GetBoolOptionOrDefault(
- type.options(), "google.protobuf.MessageOptions.message_set_wire_format", false);
+ return (
+ GetBoolOptionOrDefault(
+ type.options(),
+ "google.protobuf.MessageOptions.message_set_wire_format", false) ||
+ GetBoolOptionOrDefault(type.options(),
+ "proto2.MessageOptions.message_set_wire_format",
+ false));
}
string DoubleAsString(double value) {
@@ -404,3 +412,4 @@ bool SafeStrToFloat(StringPiece str, float* value) {
} // namespace util
} // namespace protobuf
} // namespace google
+
diff --git a/tests.sh b/tests.sh
index fb7044f3..4ac6b7c6 100755
--- a/tests.sh
+++ b/tests.sh
@@ -358,6 +358,16 @@ use_php_zts() {
ln -sfn "/usr/local/php-${VERSION}-zts/bin/phpize" $PHPIZE
}
+use_php_bc() {
+ VERSION=$1
+ PHP=`which php`
+ PHP_CONFIG=`which php-config`
+ PHPIZE=`which phpize`
+ ln -sfn "/usr/local/php-${VERSION}-bc/bin/php" $PHP
+ ln -sfn "/usr/local/php-${VERSION}-bc/bin/php-config" $PHP_CONFIG
+ ln -sfn "/usr/local/php-${VERSION}-bc/bin/phpize" $PHPIZE
+}
+
build_php5.5() {
use_php 5.5
rm -rf vendor
@@ -376,6 +386,19 @@ build_php5.5_zts_c() {
cd php/tests && /bin/bash ./test.sh && cd ../..
}
+build_php5.5_32() {
+ use_php_bc 5.5
+ rm -rf vendor
+ cp -r /usr/local/vendor-5.5 vendor
+ ./vendor/bin/phpunit
+}
+
+build_php5.5_c_32() {
+ use_php_bc 5.5
+ wget https://phar.phpunit.de/phpunit-old.phar -O /usr/bin/phpunit
+ cd php/tests && /bin/bash ./test.sh && cd ../..
+}
+
build_php5.6() {
use_php 5.6
rm -rf vendor
@@ -391,7 +414,8 @@ build_php5.6_c() {
build_php5.6_mac() {
# Install PHP
curl -s https://php-osx.liip.ch/install.sh | bash -s 5.6
- export PATH="/usr/local/php5-5.6.25-20160831-101628/bin:$PATH"
+ PHP_FOLDER=`find /usr/local -type d -name "php5-5.6*"` # The folder name may change upon time
+ export PATH="$PHP_FOLDER/bin:$PATH"
# Install phpunit
curl https://phar.phpunit.de/phpunit.phar -L -o phpunit.phar
@@ -429,6 +453,11 @@ build_php_all() {
build_php5.5_zts_c
}
+build_php_all_32() {
+ build_php5.5_32
+ build_php5.5_c_32
+}
+
# Note: travis currently does not support testing more than one language so the
# .travis.yml cheats and claims to only be cpp. If they add multiple language
# support, this should probably get updated to install steps and/or