aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmake/extract_includes.bat.in2
-rw-r--r--conformance/failure_list_csharp.txt4
-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--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/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/InvalidProtocolBufferNanoException.java2
-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--php/ext/google/protobuf/array.c127
-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/Message.php10
-rw-r--r--php/tests/array_test.php11
-rwxr-xr-xphp/tests/test.sh3
-rw-r--r--php/tests/test_base.php18
-rw-r--r--src/Makefile.am222
-rw-r--r--src/google/protobuf/arena.h1
-rwxr-xr-xsrc/google/protobuf/compiler/js/js_generator.cc2
-rw-r--r--src/google/protobuf/message_lite.h2
-rw-r--r--src/google/protobuf/repeated_field.h16
-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/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.sh10
39 files changed, 673 insertions, 289 deletions
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/conformance/failure_list_csharp.txt b/conformance/failure_list_csharp.txt
index dfafbecc..84f46fab 100644
--- a/conformance/failure_list_csharp.txt
+++ b/conformance/failure_list_csharp.txt
@@ -1,6 +1,2 @@
Recommended.JsonInput.FieldNameWithDoubleUnderscores.JsonOutput
Required.JsonInput.FieldNameInSnakeCase.JsonOutput
-Required.JsonInput.FieldNameWithMixedCases.JsonOutput
-Required.JsonInput.FieldNameWithMixedCases.ProtobufOutput
-Required.JsonInput.FieldNameWithMixedCases.Validator
-Required.JsonInput.OriginalProtoFieldName.JsonOutput
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/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/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/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/js/binary/decoder.js b/js/binary/decoder.js
index 41094a36..040cf715 100644
--- a/js/binary/decoder.js
+++ b/js/binary/decoder.js
@@ -895,11 +895,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.
*/
@@ -907,30 +905,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 c9b0c2ae..d952d714 100644
--- a/js/binary/encoder.js
+++ b/js/binary/encoder.js
@@ -409,19 +409,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/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/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/Message.php b/php/src/Google/Protobuf/Internal/Message.php
index 38513e91..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");
+ }
}
}
}
diff --git a/php/tests/array_test.php b/php/tests/array_test.php
index a118b54c..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);
}
/**
diff --git a/php/tests/test.sh b/php/tests/test.sh
index 888e93eb..fe3dc7f6 100755
--- a/php/tests/test.sh
+++ b/php/tests/test.sh
@@ -7,7 +7,8 @@
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 )
diff --git a/php/tests/test_base.php b/php/tests/test_base.php
index 49886050..d461f0f7 100644
--- a/php/tests/test_base.php
+++ b/php/tests/test_base.php
@@ -75,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/src/Makefile.am b/src/Makefile.am
index faee6d96..8d9e07ab 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -61,117 +61,117 @@ 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/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/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/js/js_generator.cc b/src/google/protobuf/compiler/js/js_generator.cc
index 58597b4c..47ecc537 100755
--- a/src/google/protobuf/compiler/js/js_generator.cc
+++ b/src/google/protobuf/compiler/js/js_generator.cc
@@ -28,7 +28,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#include "google/protobuf/compiler/js/js_generator.h"
+#include <google/protobuf/compiler/js/js_generator.h>
#include <assert.h>
#include <algorithm>
diff --git a/src/google/protobuf/message_lite.h b/src/google/protobuf/message_lite.h
index d3c3b1f0..88455669 100644
--- a/src/google/protobuf/message_lite.h
+++ b/src/google/protobuf/message_lite.h
@@ -244,7 +244,7 @@ class LIBPROTOBUF_EXPORT MessageLite {
//
// ByteSize() is generally linear in the number of fields defined for the
// proto.
- virtual int ByteSize() const { return ByteSizeLong(); }
+ virtual int ByteSize() const { return static_cast<int>(ByteSizeLong()); }
virtual size_t ByteSizeLong() const;
// Serializes the message without recomputing the size. The message must
diff --git a/src/google/protobuf/repeated_field.h b/src/google/protobuf/repeated_field.h
index 0a41495f..6ede0e1a 100644
--- a/src/google/protobuf/repeated_field.h
+++ b/src/google/protobuf/repeated_field.h
@@ -681,17 +681,7 @@ inline const Message& GenericTypeHandler<Message>::default_instance() {
return *null;
}
-
-// HACK: If a class is declared as DLL-exported in MSVC, it insists on
-// generating copies of all its methods -- even inline ones -- to include
-// in the DLL. But SpaceUsed() calls StringSpaceUsedExcludingSelf() which
-// isn't in the lite library, therefore the lite library cannot link if
-// StringTypeHandler is exported. So, we factor out StringTypeHandlerBase,
-// export that, then make StringTypeHandler be a subclass which is NOT
-// exported.
-// TODO(kenton): Now that StringSpaceUsedExcludingSelf() is in the lite
-// library, this can be cleaned up.
-class LIBPROTOBUF_EXPORT StringTypeHandlerBase {
+class LIBPROTOBUF_EXPORT StringTypeHandler {
public:
typedef string Type;
@@ -718,10 +708,6 @@ class LIBPROTOBUF_EXPORT StringTypeHandlerBase {
static inline const Type& default_instance() {
return ::google::protobuf::internal::GetEmptyString();
}
-};
-
-class StringTypeHandler : public StringTypeHandlerBase {
- public:
static int SpaceUsed(const string& value) {
return static_cast<int>(sizeof(value)) + StringSpaceUsedExcludingSelf(value);
}
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/util/internal/protostream_objectsource.cc b/src/google/protobuf/util/internal/protostream_objectsource.cc
index 150f3cf1..df0dbe1b 100644
--- a/src/google/protobuf/util/internal/protostream_objectsource.cc
+++ b/src/google/protobuf/util/internal/protostream_objectsource.cc
@@ -1024,8 +1024,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(
@@ -1119,3 +1122,4 @@ const string FormatNanos(uint32 nanos) {
} // 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 9aab3481..05328255 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 1335c06b..4ac6b7c6 100755
--- a/tests.sh
+++ b/tests.sh
@@ -393,6 +393,12 @@ build_php5.5_32() {
./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
@@ -408,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
@@ -448,6 +455,7 @@ build_php_all() {
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