aboutsummaryrefslogtreecommitdiffhomepage
path: root/third_party/protobuf/3.2.0/conformance
diff options
context:
space:
mode:
authorGravatar Irina Iancu <elenairina@google.com>2017-02-24 13:04:14 +0100
committerGravatar Irina Iancu <elenairina@google.com>2017-02-24 15:48:27 +0100
commite50388e66e1378b8c6a93bbc331e27771bd3aedc (patch)
tree074d518c6e652f6138a10ddf05286093dda3f563 /third_party/protobuf/3.2.0/conformance
parente716ae46f359dc1361574f44569811ff80a758ac (diff)
Revert "Upgrade //third_party/protobuf to v3.2.0"
This reverts commit 2346f5a01561f695a2b2ba7655359d5020105077. It breaks bazel build in freebsd[1]. The solution is to patch https://svnweb.freebsd.org/ports/head/devel/protobuf/files/. I rolled-back this since the other builds will not automatically start if Bazel is broken. [1] http://ci.bazel.io/view/Bazel%20bootstrap%20and%20maintenance/job/Bazel/JAVA_VERSION=1.8,PLATFORM_NAME=freebsd-11/1312/ Change-Id: I7e939a4293d799ab6dd67f93d219d1efdf4cd901
Diffstat (limited to 'third_party/protobuf/3.2.0/conformance')
-rw-r--r--third_party/protobuf/3.2.0/conformance/ConformanceJava.java315
-rw-r--r--third_party/protobuf/3.2.0/conformance/ConformanceJavaLite.java125
-rw-r--r--third_party/protobuf/3.2.0/conformance/Makefile.am289
-rw-r--r--third_party/protobuf/3.2.0/conformance/README.md45
-rw-r--r--third_party/protobuf/3.2.0/conformance/conformance.proto114
-rw-r--r--third_party/protobuf/3.2.0/conformance/conformance_cpp.cc208
-rw-r--r--third_party/protobuf/3.2.0/conformance/conformance_objc.m180
-rwxr-xr-xthird_party/protobuf/3.2.0/conformance/conformance_python.py135
-rwxr-xr-xthird_party/protobuf/3.2.0/conformance/conformance_ruby.rb124
-rw-r--r--third_party/protobuf/3.2.0/conformance/conformance_test.cc2383
-rw-r--r--third_party/protobuf/3.2.0/conformance/conformance_test.h242
-rw-r--r--third_party/protobuf/3.2.0/conformance/conformance_test_runner.cc326
-rw-r--r--third_party/protobuf/3.2.0/conformance/failure_list_cpp.txt46
-rw-r--r--third_party/protobuf/3.2.0/conformance/failure_list_csharp.txt0
-rw-r--r--third_party/protobuf/3.2.0/conformance/failure_list_java.txt45
-rw-r--r--third_party/protobuf/3.2.0/conformance/failure_list_objc.txt4
-rw-r--r--third_party/protobuf/3.2.0/conformance/failure_list_python-post26.txt2
-rw-r--r--third_party/protobuf/3.2.0/conformance/failure_list_python.txt13
-rw-r--r--third_party/protobuf/3.2.0/conformance/failure_list_python_cpp.txt38
-rw-r--r--third_party/protobuf/3.2.0/conformance/failure_list_ruby.txt203
-rw-r--r--third_party/protobuf/3.2.0/conformance/third_party/jsoncpp/json.h2075
-rw-r--r--third_party/protobuf/3.2.0/conformance/third_party/jsoncpp/jsoncpp.cpp5192
-rwxr-xr-xthird_party/protobuf/3.2.0/conformance/update_failure_list.py73
23 files changed, 0 insertions, 12177 deletions
diff --git a/third_party/protobuf/3.2.0/conformance/ConformanceJava.java b/third_party/protobuf/3.2.0/conformance/ConformanceJava.java
deleted file mode 100644
index 7badf2a5f5..0000000000
--- a/third_party/protobuf/3.2.0/conformance/ConformanceJava.java
+++ /dev/null
@@ -1,315 +0,0 @@
-import com.google.protobuf.ByteString;
-import com.google.protobuf.CodedInputStream;
-import com.google.protobuf.conformance.Conformance;
-import com.google.protobuf.InvalidProtocolBufferException;
-import com.google.protobuf_test_messages.proto3.TestMessagesProto3;
-import com.google.protobuf.util.JsonFormat;
-import com.google.protobuf.util.JsonFormat.TypeRegistry;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-
-class ConformanceJava {
- private int testCount = 0;
- private TypeRegistry typeRegistry;
-
- private boolean readFromStdin(byte[] buf, int len) throws Exception {
- int ofs = 0;
- while (len > 0) {
- int read = System.in.read(buf, ofs, len);
- if (read == -1) {
- return false; // EOF
- }
- ofs += read;
- len -= read;
- }
-
- return true;
- }
-
- private void writeToStdout(byte[] buf) throws Exception {
- System.out.write(buf);
- }
-
- // Returns -1 on EOF (the actual values will always be positive).
- private int readLittleEndianIntFromStdin() throws Exception {
- byte[] buf = new byte[4];
- if (!readFromStdin(buf, 4)) {
- return -1;
- }
- return (buf[0] & 0xff)
- | ((buf[1] & 0xff) << 8)
- | ((buf[2] & 0xff) << 16)
- | ((buf[3] & 0xff) << 24);
- }
-
- private void writeLittleEndianIntToStdout(int val) throws Exception {
- byte[] buf = new byte[4];
- buf[0] = (byte)val;
- buf[1] = (byte)(val >> 8);
- buf[2] = (byte)(val >> 16);
- buf[3] = (byte)(val >> 24);
- writeToStdout(buf);
- }
-
- private enum BinaryDecoder {
- BYTE_STRING_DECODER() {
- @Override
- public TestMessagesProto3.TestAllTypes parse(ByteString bytes)
- throws InvalidProtocolBufferException {
- return TestMessagesProto3.TestAllTypes.parseFrom(bytes);
- }
- },
- BYTE_ARRAY_DECODER() {
- @Override
- public TestMessagesProto3.TestAllTypes parse(ByteString bytes)
- throws InvalidProtocolBufferException {
- return TestMessagesProto3.TestAllTypes.parseFrom(bytes.toByteArray());
- }
- },
- ARRAY_BYTE_BUFFER_DECODER() {
- @Override
- public TestMessagesProto3.TestAllTypes parse(ByteString bytes)
- throws InvalidProtocolBufferException {
- ByteBuffer buffer = ByteBuffer.allocate(bytes.size());
- bytes.copyTo(buffer);
- buffer.flip();
- try {
- return TestMessagesProto3.TestAllTypes.parseFrom(CodedInputStream.newInstance(buffer));
- } catch (InvalidProtocolBufferException e) {
- throw e;
- } catch (IOException e) {
- throw new RuntimeException(
- "ByteString based ByteBuffer should not throw IOException.", e);
- }
- }
- },
- READONLY_ARRAY_BYTE_BUFFER_DECODER() {
- @Override
- public TestMessagesProto3.TestAllTypes parse(ByteString bytes)
- throws InvalidProtocolBufferException {
- try {
- return TestMessagesProto3.TestAllTypes.parseFrom(
- CodedInputStream.newInstance(bytes.asReadOnlyByteBuffer()));
- } catch (InvalidProtocolBufferException e) {
- throw e;
- } catch (IOException e) {
- throw new RuntimeException(
- "ByteString based ByteBuffer should not throw IOException.", e);
- }
- }
- },
- DIRECT_BYTE_BUFFER_DECODER() {
- @Override
- public TestMessagesProto3.TestAllTypes parse(ByteString bytes)
- throws InvalidProtocolBufferException {
- ByteBuffer buffer = ByteBuffer.allocateDirect(bytes.size());
- bytes.copyTo(buffer);
- buffer.flip();
- try {
- return TestMessagesProto3.TestAllTypes.parseFrom(CodedInputStream.newInstance(buffer));
- } catch (InvalidProtocolBufferException e) {
- throw e;
- } catch (IOException e) {
- throw new RuntimeException(
- "ByteString based ByteBuffer should not throw IOException.", e);
- }
- }
- },
- READONLY_DIRECT_BYTE_BUFFER_DECODER() {
- @Override
- public TestMessagesProto3.TestAllTypes parse(ByteString bytes)
- throws InvalidProtocolBufferException {
- ByteBuffer buffer = ByteBuffer.allocateDirect(bytes.size());
- bytes.copyTo(buffer);
- buffer.flip();
- try {
- return TestMessagesProto3.TestAllTypes.parseFrom(
- CodedInputStream.newInstance(buffer.asReadOnlyBuffer()));
- } catch (InvalidProtocolBufferException e) {
- throw e;
- } catch (IOException e) {
- throw new RuntimeException(
- "ByteString based ByteBuffer should not throw IOException.", e);
- }
- }
- },
- INPUT_STREAM_DECODER() {
- @Override
- public TestMessagesProto3.TestAllTypes parse(ByteString bytes)
- throws InvalidProtocolBufferException {
- try {
- return TestMessagesProto3.TestAllTypes.parseFrom(bytes.newInput());
- } catch (InvalidProtocolBufferException e) {
- throw e;
- } catch (IOException e) {
- throw new RuntimeException(
- "ByteString based InputStream should not throw IOException.", e);
- }
- }
- };
-
- public abstract TestMessagesProto3.TestAllTypes parse(ByteString bytes)
- throws InvalidProtocolBufferException;
- }
-
- private TestMessagesProto3.TestAllTypes parseBinary(ByteString bytes)
- throws InvalidProtocolBufferException {
- TestMessagesProto3.TestAllTypes[] messages =
- new TestMessagesProto3.TestAllTypes[BinaryDecoder.values().length];
- InvalidProtocolBufferException[] exceptions =
- new InvalidProtocolBufferException[BinaryDecoder.values().length];
-
- boolean hasMessage = false;
- boolean hasException = false;
- for (int i = 0; i < BinaryDecoder.values().length; ++i) {
- try {
- messages[i] = BinaryDecoder.values()[i].parse(bytes);
- hasMessage = true;
- } catch (InvalidProtocolBufferException e) {
- exceptions[i] = e;
- hasException = true;
- }
- }
-
- if (hasMessage && hasException) {
- StringBuilder sb =
- new StringBuilder("Binary decoders disagreed on whether the payload was valid.\n");
- for (int i = 0; i < BinaryDecoder.values().length; ++i) {
- sb.append(BinaryDecoder.values()[i].name());
- if (messages[i] != null) {
- sb.append(" accepted the payload.\n");
- } else {
- sb.append(" rejected the payload.\n");
- }
- }
- throw new RuntimeException(sb.toString());
- }
-
- if (hasException) {
- // We do not check if exceptions are equal. Different implementations may return different
- // exception messages. Throw an arbitrary one out instead.
- throw exceptions[0];
- }
-
- // Fast path comparing all the messages with the first message, assuming equality being
- // symmetric and transitive.
- boolean allEqual = true;
- for (int i = 1; i < messages.length; ++i) {
- if (!messages[0].equals(messages[i])) {
- allEqual = false;
- break;
- }
- }
-
- // Slow path: compare and find out all unequal pairs.
- if (!allEqual) {
- StringBuilder sb = new StringBuilder();
- for (int i = 0; i < messages.length - 1; ++i) {
- for (int j = i + 1; j < messages.length; ++j) {
- if (!messages[i].equals(messages[j])) {
- sb.append(BinaryDecoder.values()[i].name())
- .append(" and ")
- .append(BinaryDecoder.values()[j].name())
- .append(" parsed the payload differently.\n");
- }
- }
- }
- throw new RuntimeException(sb.toString());
- }
-
- return messages[0];
- }
-
- private Conformance.ConformanceResponse doTest(Conformance.ConformanceRequest request) {
- TestMessagesProto3.TestAllTypes testMessage;
-
- switch (request.getPayloadCase()) {
- case PROTOBUF_PAYLOAD: {
- try {
- testMessage = parseBinary(request.getProtobufPayload());
- } catch (InvalidProtocolBufferException e) {
- return Conformance.ConformanceResponse.newBuilder().setParseError(e.getMessage()).build();
- }
- break;
- }
- case JSON_PAYLOAD: {
- try {
- TestMessagesProto3.TestAllTypes.Builder builder = TestMessagesProto3.TestAllTypes.newBuilder();
- JsonFormat.parser().usingTypeRegistry(typeRegistry)
- .merge(request.getJsonPayload(), builder);
- testMessage = builder.build();
- } catch (InvalidProtocolBufferException e) {
- return Conformance.ConformanceResponse.newBuilder().setParseError(e.getMessage()).build();
- }
- break;
- }
- case PAYLOAD_NOT_SET: {
- throw new RuntimeException("Request didn't have payload.");
- }
-
- default: {
- throw new RuntimeException("Unexpected payload case.");
- }
- }
-
- switch (request.getRequestedOutputFormat()) {
- case UNSPECIFIED:
- throw new RuntimeException("Unspecified output format.");
-
- case PROTOBUF:
- return Conformance.ConformanceResponse.newBuilder().setProtobufPayload(testMessage.toByteString()).build();
-
- case JSON:
- try {
- return Conformance.ConformanceResponse.newBuilder().setJsonPayload(
- JsonFormat.printer().usingTypeRegistry(typeRegistry).print(testMessage)).build();
- } catch (InvalidProtocolBufferException | IllegalArgumentException e) {
- return Conformance.ConformanceResponse.newBuilder().setSerializeError(
- e.getMessage()).build();
- }
-
- default: {
- throw new RuntimeException("Unexpected request output.");
- }
- }
- }
-
- private boolean doTestIo() throws Exception {
- int bytes = readLittleEndianIntFromStdin();
-
- if (bytes == -1) {
- return false; // EOF
- }
-
- byte[] serializedInput = new byte[bytes];
-
- if (!readFromStdin(serializedInput, bytes)) {
- throw new RuntimeException("Unexpected EOF from test program.");
- }
-
- Conformance.ConformanceRequest request =
- Conformance.ConformanceRequest.parseFrom(serializedInput);
- Conformance.ConformanceResponse response = doTest(request);
- byte[] serializedOutput = response.toByteArray();
-
- writeLittleEndianIntToStdout(serializedOutput.length);
- writeToStdout(serializedOutput);
-
- return true;
- }
-
- public void run() throws Exception {
- typeRegistry = TypeRegistry.newBuilder().add(
- TestMessagesProto3.TestAllTypes.getDescriptor()).build();
- while (doTestIo()) {
- this.testCount++;
- }
-
- System.err.println("ConformanceJava: received EOF from test runner after " +
- this.testCount + " tests");
- }
-
- public static void main(String[] args) throws Exception {
- new ConformanceJava().run();
- }
-}
diff --git a/third_party/protobuf/3.2.0/conformance/ConformanceJavaLite.java b/third_party/protobuf/3.2.0/conformance/ConformanceJavaLite.java
deleted file mode 100644
index 016f79326f..0000000000
--- a/third_party/protobuf/3.2.0/conformance/ConformanceJavaLite.java
+++ /dev/null
@@ -1,125 +0,0 @@
-
-import com.google.protobuf.conformance.Conformance;
-import com.google.protobuf.InvalidProtocolBufferException;
-
-class ConformanceJavaLite {
- private int testCount = 0;
-
- private boolean readFromStdin(byte[] buf, int len) throws Exception {
- int ofs = 0;
- while (len > 0) {
- int read = System.in.read(buf, ofs, len);
- if (read == -1) {
- return false; // EOF
- }
- ofs += read;
- len -= read;
- }
-
- return true;
- }
-
- private void writeToStdout(byte[] buf) throws Exception {
- System.out.write(buf);
- }
-
- // Returns -1 on EOF (the actual values will always be positive).
- private int readLittleEndianIntFromStdin() throws Exception {
- byte[] buf = new byte[4];
- if (!readFromStdin(buf, 4)) {
- return -1;
- }
- return (buf[0] & 0xff)
- | ((buf[1] & 0xff) << 8)
- | ((buf[2] & 0xff) << 16)
- | ((buf[3] & 0xff) << 24);
- }
-
- private void writeLittleEndianIntToStdout(int val) throws Exception {
- byte[] buf = new byte[4];
- buf[0] = (byte)val;
- buf[1] = (byte)(val >> 8);
- buf[2] = (byte)(val >> 16);
- buf[3] = (byte)(val >> 24);
- writeToStdout(buf);
- }
-
- private Conformance.ConformanceResponse doTest(Conformance.ConformanceRequest request) {
- Conformance.TestAllTypes testMessage;
-
- switch (request.getPayloadCase()) {
- case PROTOBUF_PAYLOAD: {
- try {
- testMessage = Conformance.TestAllTypes.parseFrom(request.getProtobufPayload());
- } catch (InvalidProtocolBufferException e) {
- return Conformance.ConformanceResponse.newBuilder().setParseError(e.getMessage()).build();
- }
- break;
- }
- case JSON_PAYLOAD: {
- return Conformance.ConformanceResponse.newBuilder().setSkipped(
- "Lite runtime does not support JSON format.").build();
- }
- case PAYLOAD_NOT_SET: {
- throw new RuntimeException("Request didn't have payload.");
- }
-
- default: {
- throw new RuntimeException("Unexpected payload case.");
- }
- }
-
- switch (request.getRequestedOutputFormat()) {
- case UNSPECIFIED:
- throw new RuntimeException("Unspecified output format.");
-
- case PROTOBUF:
- return Conformance.ConformanceResponse.newBuilder().setProtobufPayload(testMessage.toByteString()).build();
-
- case JSON:
- return Conformance.ConformanceResponse.newBuilder().setSkipped(
- "Lite runtime does not support JSON format.").build();
-
- default: {
- throw new RuntimeException("Unexpected request output.");
- }
- }
- }
-
- private boolean doTestIo() throws Exception {
- int bytes = readLittleEndianIntFromStdin();
-
- if (bytes == -1) {
- return false; // EOF
- }
-
- byte[] serializedInput = new byte[bytes];
-
- if (!readFromStdin(serializedInput, bytes)) {
- throw new RuntimeException("Unexpected EOF from test program.");
- }
-
- Conformance.ConformanceRequest request =
- Conformance.ConformanceRequest.parseFrom(serializedInput);
- Conformance.ConformanceResponse response = doTest(request);
- byte[] serializedOutput = response.toByteArray();
-
- writeLittleEndianIntToStdout(serializedOutput.length);
- writeToStdout(serializedOutput);
-
- return true;
- }
-
- public void run() throws Exception {
- while (doTestIo()) {
- this.testCount++;
- }
-
- System.err.println("ConformanceJavaLite: received EOF from test runner after " +
- this.testCount + " tests");
- }
-
- public static void main(String[] args) throws Exception {
- new ConformanceJavaLite().run();
- }
-}
diff --git a/third_party/protobuf/3.2.0/conformance/Makefile.am b/third_party/protobuf/3.2.0/conformance/Makefile.am
deleted file mode 100644
index c2b5890039..0000000000
--- a/third_party/protobuf/3.2.0/conformance/Makefile.am
+++ /dev/null
@@ -1,289 +0,0 @@
-## Process this file with automake to produce Makefile.in
-
-conformance_protoc_inputs = \
- conformance.proto \
- $(top_srcdir)/src/google/protobuf/test_messages_proto3.proto
-
-well_known_type_protoc_inputs = \
- $(top_srcdir)/src/google/protobuf/any.proto \
- $(top_srcdir)/src/google/protobuf/duration.proto \
- $(top_srcdir)/src/google/protobuf/field_mask.proto \
- $(top_srcdir)/src/google/protobuf/struct.proto \
- $(top_srcdir)/src/google/protobuf/timestamp.proto \
- $(top_srcdir)/src/google/protobuf/wrappers.proto
-
-
-protoc_outputs = \
- conformance.pb.cc \
- conformance.pb.h
-
-other_language_protoc_outputs = \
- conformance_pb2.py \
- Conformance.pbobjc.h \
- Conformance.pbobjc.m \
- conformance_pb.rb \
- com/google/protobuf/Any.java \
- com/google/protobuf/AnyOrBuilder.java \
- com/google/protobuf/AnyProto.java \
- com/google/protobuf/BoolValue.java \
- com/google/protobuf/BoolValueOrBuilder.java \
- com/google/protobuf/BytesValue.java \
- com/google/protobuf/BytesValueOrBuilder.java \
- com/google/protobuf/conformance/Conformance.java \
- com/google/protobuf/DoubleValue.java \
- com/google/protobuf/DoubleValueOrBuilder.java \
- com/google/protobuf/Duration.java \
- com/google/protobuf/DurationOrBuilder.java \
- com/google/protobuf/DurationProto.java \
- com/google/protobuf/FieldMask.java \
- com/google/protobuf/FieldMaskOrBuilder.java \
- com/google/protobuf/FieldMaskProto.java \
- com/google/protobuf/FloatValue.java \
- com/google/protobuf/FloatValueOrBuilder.java \
- com/google/protobuf/Int32Value.java \
- com/google/protobuf/Int32ValueOrBuilder.java \
- com/google/protobuf/Int64Value.java \
- com/google/protobuf/Int64ValueOrBuilder.java \
- com/google/protobuf/ListValue.java \
- com/google/protobuf/ListValueOrBuilder.java \
- com/google/protobuf/NullValue.java \
- com/google/protobuf/StringValue.java \
- com/google/protobuf/StringValueOrBuilder.java \
- com/google/protobuf/Struct.java \
- com/google/protobuf/StructOrBuilder.java \
- com/google/protobuf/StructProto.java \
- com/google/protobuf/Timestamp.java \
- com/google/protobuf/TimestampOrBuilder.java \
- com/google/protobuf/TimestampProto.java \
- com/google/protobuf/UInt32Value.java \
- com/google/protobuf/UInt32ValueOrBuilder.java \
- com/google/protobuf/UInt64Value.java \
- com/google/protobuf/UInt64ValueOrBuilder.java \
- com/google/protobuf/Value.java \
- com/google/protobuf/ValueOrBuilder.java \
- com/google/protobuf/WrappersProto.java \
- com/google/protobuf_test_messages/proto3/TestMessagesProto3.java \
- google/protobuf/any.pb.cc \
- google/protobuf/any.pb.h \
- google/protobuf/any.rb \
- google/protobuf/any_pb2.py \
- google/protobuf/duration.pb.cc \
- google/protobuf/duration.pb.h \
- google/protobuf/duration.rb \
- google/protobuf/duration_pb2.py \
- google/protobuf/field_mask.pb.cc \
- google/protobuf/field_mask.pb.h \
- google/protobuf/field_mask.rb \
- google/protobuf/field_mask_pb2.py \
- google/protobuf/struct.pb.cc \
- google/protobuf/struct.pb.h \
- google/protobuf/struct.rb \
- google/protobuf/struct_pb2.py \
- google/protobuf/TestMessagesProto3.pbobjc.h \
- google/protobuf/TestMessagesProto3.pbobjc.m \
- google/protobuf/test_messages_proto3.pb.cc \
- google/protobuf/test_messages_proto3.pb.h \
- google/protobuf/test_messages_proto3_pb.rb \
- google/protobuf/test_messages_proto3_pb2.py \
- google/protobuf/timestamp.pb.cc \
- google/protobuf/timestamp.pb.h \
- google/protobuf/timestamp.rb \
- google/protobuf/timestamp_pb2.py \
- google/protobuf/wrappers.pb.cc \
- google/protobuf/wrappers.pb.h \
- google/protobuf/wrappers.rb \
- google/protobuf/wrappers_pb2.py
- # lite/com/google/protobuf/Any.java \
- # lite/com/google/protobuf/AnyOrBuilder.java \
- # lite/com/google/protobuf/AnyProto.java \
- # lite/com/google/protobuf/BoolValue.java \
- # lite/com/google/protobuf/BoolValueOrBuilder.java \
- # lite/com/google/protobuf/BytesValue.java \
- # lite/com/google/protobuf/BytesValueOrBuilder.java \
- # lite/com/google/protobuf/conformance/Conformance.java \
- # lite/com/google/protobuf/DoubleValue.java \
- # lite/com/google/protobuf/DoubleValueOrBuilder.java \
- # lite/com/google/protobuf/Duration.java \
- # lite/com/google/protobuf/DurationOrBuilder.java \
- # lite/com/google/protobuf/DurationProto.java \
- # lite/com/google/protobuf/FieldMask.java \
- # lite/com/google/protobuf/FieldMaskOrBuilder.java \
- # lite/com/google/protobuf/FieldMaskProto.java \
- # lite/com/google/protobuf/FloatValue.java \
- # lite/com/google/protobuf/FloatValueOrBuilder.java \
- # lite/com/google/protobuf/Int32Value.java \
- # lite/com/google/protobuf/Int32ValueOrBuilder.java \
- # lite/com/google/protobuf/Int64Value.java \
- # lite/com/google/protobuf/Int64ValueOrBuilder.java \
- # lite/com/google/protobuf/ListValue.java \
- # lite/com/google/protobuf/ListValueOrBuilder.java \
- # lite/com/google/protobuf/NullValue.java \
- # lite/com/google/protobuf/StringValue.java \
- # lite/com/google/protobuf/StringValueOrBuilder.java \
- # lite/com/google/protobuf/Struct.java \
- # lite/com/google/protobuf/StructOrBuilder.java \
- # lite/com/google/protobuf/StructProto.java \
- # lite/com/google/protobuf/Timestamp.java \
- # lite/com/google/protobuf/TimestampOrBuilder.java \
- # lite/com/google/protobuf/TimestampProto.java \
- # lite/com/google/protobuf/UInt32Value.java \
- # lite/com/google/protobuf/UInt32ValueOrBuilder.java \
- # lite/com/google/protobuf/UInt64Value.java \
- # lite/com/google/protobuf/UInt64ValueOrBuilder.java \
- # lite/com/google/protobuf/Value.java \
- # lite/com/google/protobuf/ValueOrBuilder.java \
- # lite/com/google/protobuf/WrappersProto.java
-
-bin_PROGRAMS = conformance-test-runner conformance-cpp
-
-# All source files excepet C++/Objective-C ones should be explicitly listed
-# here because the autoconf tools don't include files of other languages
-# automatically.
-EXTRA_DIST = \
- ConformanceJava.java \
- ConformanceJavaLite.java \
- README.md \
- conformance.proto \
- conformance_python.py \
- conformance_ruby.rb \
- failure_list_cpp.txt \
- failure_list_csharp.txt \
- failure_list_java.txt \
- failure_list_objc.txt \
- failure_list_python.txt \
- failure_list_python_cpp.txt \
- failure_list_python-post26.txt \
- failure_list_ruby.txt
-
-conformance_test_runner_LDADD = $(top_srcdir)/src/libprotobuf.la
-conformance_test_runner_SOURCES = conformance_test.h conformance_test.cc \
- conformance_test_runner.cc \
- third_party/jsoncpp/json.h \
- third_party/jsoncpp/jsoncpp.cpp
-nodist_conformance_test_runner_SOURCES = conformance.pb.cc google/protobuf/test_messages_proto3.pb.cc
-conformance_test_runner_CPPFLAGS = -I$(top_srcdir)/src -I$(srcdir)
-conformance_test_runner_CXXFLAGS = -std=c++11
-# Explicit deps beacuse BUILT_SOURCES are only done before a "make all/check"
-# so a direct "make test_cpp" could fail if parallel enough.
-conformance_test_runner-conformance_test.$(OBJEXT): conformance.pb.h
-conformance_test_runner-conformance_test_runner.$(OBJEXT): conformance.pb.h
-
-conformance_cpp_LDADD = $(top_srcdir)/src/libprotobuf.la
-conformance_cpp_SOURCES = conformance_cpp.cc
-nodist_conformance_cpp_SOURCES = conformance.pb.cc google/protobuf/test_messages_proto3.pb.cc
-conformance_cpp_CPPFLAGS = -I$(top_srcdir)/src
-# Explicit dep beacuse BUILT_SOURCES are only done before a "make all/check"
-# so a direct "make test_cpp" could fail if parallel enough.
-conformance_cpp-conformance_cpp.$(OBJEXT): conformance.pb.h
-
-if OBJC_CONFORMANCE_TEST
-
-bin_PROGRAMS += conformance-objc
-
-conformance_objc_SOURCES = conformance_objc.m ../objectivec/GPBProtocolBuffers.m
-nodist_conformance_objc_SOURCES = Conformance.pbobjc.m google/protobuf/TestMessagesProto3.pbobjc.m
-# On travis, the build fails without the isysroot because whatever system
-# headers are being found don't include generics support for
-# NSArray/NSDictionary, the only guess is their image at one time had an odd
-# setup for Xcode and old frameworks are being found.
-conformance_objc_CPPFLAGS = -I$(top_srcdir)/objectivec -isysroot `xcrun --sdk macosx --show-sdk-path`
-conformance_objc_LDFLAGS = -framework Foundation
-# Explicit dep beacuse BUILT_SOURCES are only done before a "make all/check"
-# so a direct "make test_objc" could fail if parallel enough.
-conformance_objc-conformance_objc.$(OBJEXT): Conformance.pbobjc.h google/protobuf/TestMessagesProto3.pbobjc.h
-
-endif
-
-if USE_EXTERNAL_PROTOC
-
-# Some implementations include pre-generated versions of well-known types.
-protoc_middleman: $(conformance_protoc_inputs) $(well_known_type_protoc_inputs)
- $(PROTOC) -I$(srcdir) -I$(top_srcdir) --cpp_out=. --java_out=. --ruby_out=. --objc_out=. --python_out=. $(conformance_protoc_inputs)
- $(PROTOC) -I$(srcdir) -I$(top_srcdir) --cpp_out=. --java_out=. --ruby_out=. --python_out=. $(well_known_type_protoc_inputs)
- ## $(PROTOC) -I$(srcdir) -I$(top_srcdir) --java_out=lite:lite $(conformance_protoc_inputs) $(well_known_type_protoc_inputs)
- touch protoc_middleman
-
-else
-
-# We have to cd to $(srcdir) before executing protoc because $(protoc_inputs) is
-# relative to srcdir, which may not be the same as the current directory when
-# building out-of-tree.
-protoc_middleman: $(top_srcdir)/src/protoc$(EXEEXT) $(conformance_protoc_inputs) $(well_known_type_protoc_inputs)
- oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --cpp_out=$$oldpwd --java_out=$$oldpwd --ruby_out=$$oldpwd --objc_out=$$oldpwd --python_out=$$oldpwd $(conformance_protoc_inputs) )
- oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --cpp_out=$$oldpwd --java_out=$$oldpwd --ruby_out=$$oldpwd --python_out=$$oldpwd $(well_known_type_protoc_inputs) )
- ## @mkdir -p lite
- ## oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --java_out=lite:$$oldpwd/lite $(conformance_protoc_inputs) $(well_known_type_protoc_inputs) )
- touch protoc_middleman
-
-endif
-
-$(protoc_outputs): protoc_middleman
-
-$(other_language_protoc_outputs): protoc_middleman
-
-BUILT_SOURCES = $(protoc_outputs) $(other_language_protoc_outputs)
-
-CLEANFILES = $(protoc_outputs) protoc_middleman javac_middleman conformance-java javac_middleman_lite conformance-java-lite conformance-csharp $(other_language_protoc_outputs)
-
-MAINTAINERCLEANFILES = \
- Makefile.in
-
-javac_middleman: ConformanceJava.java protoc_middleman $(other_language_protoc_outputs)
- jar=`ls ../java/util/target/*jar-with-dependencies.jar` && javac -classpath ../java/target/classes:$$jar ConformanceJava.java com/google/protobuf/conformance/Conformance.java com/google/protobuf_test_messages/proto3/TestMessagesProto3.java
- @touch javac_middleman
-
-conformance-java: javac_middleman
- @echo "Writing shortcut script conformance-java..."
- @echo '#! /bin/sh' > conformance-java
- @jar=`ls ../java/util/target/*jar-with-dependencies.jar` && echo java -classpath .:../java/target/classes:$$jar ConformanceJava '$$@' >> conformance-java
- @chmod +x conformance-java
-
-javac_middleman_lite: ConformanceJavaLite.java protoc_middleman $(other_language_protoc_outputs)
- javac -classpath ../java/lite/target/classes:lite ConformanceJavaLite.java lite/com/google/protobuf/conformance/Conformance.java
- @touch javac_middleman_lite
-
-conformance-java-lite: javac_middleman_lite
- @echo "Writing shortcut script conformance-java-lite..."
- @echo '#! /bin/sh' > conformance-java-lite
- @echo java -classpath .:../java/lite/target/classes:lite ConformanceJavaLite '$$@' >> conformance-java-lite
- @chmod +x conformance-java-lite
-
-# Currently the conformance code is alongside the rest of the C#
-# source, as it's easier to maintain there. We assume we've already
-# built that, so we just need a script to run it.
-conformance-csharp: $(other_language_protoc_outputs)
- @echo "Writing shortcut script conformance-csharp..."
- @echo '#! /bin/sh' > conformance-csharp
- @echo 'dotnet ../csharp/src/Google.Protobuf.Conformance/bin/Release/netcoreapp1.0/Google.Protobuf.Conformance.dll "$$@"' >> conformance-csharp
- @chmod +x conformance-csharp
-
-# Targets for actually running tests.
-test_cpp: protoc_middleman conformance-test-runner conformance-cpp
- ./conformance-test-runner --enforce_recommended --failure_list failure_list_cpp.txt ./conformance-cpp
-
-test_java: protoc_middleman conformance-test-runner conformance-java
- ./conformance-test-runner --enforce_recommended --failure_list failure_list_java.txt ./conformance-java
-
-test_java_lite: protoc_middleman conformance-test-runner conformance-java-lite
- ./conformance-test-runner --enforce_recommended ./conformance-java-lite
-
-test_csharp: protoc_middleman conformance-test-runner conformance-csharp
- ./conformance-test-runner --enforce_recommended --failure_list failure_list_csharp.txt ./conformance-csharp
-
-test_ruby: protoc_middleman conformance-test-runner $(other_language_protoc_outputs)
- RUBYLIB=../ruby/lib:. ./conformance-test-runner --enforce_recommended --failure_list failure_list_ruby.txt ./conformance_ruby.rb
-
-# These depend on library paths being properly set up. The easiest way to
-# run them is to just use "tox" from the python dir.
-test_python: protoc_middleman conformance-test-runner
- ./conformance-test-runner --enforce_recommended --failure_list failure_list_python.txt ./conformance_python.py
-
-test_python_cpp: protoc_middleman conformance-test-runner
- ./conformance-test-runner --enforce_recommended --failure_list failure_list_python_cpp.txt ./conformance_python.py
-
-if OBJC_CONFORMANCE_TEST
-
-test_objc: protoc_middleman conformance-test-runner conformance-objc
- ./conformance-test-runner --enforce_recommended --failure_list failure_list_objc.txt ./conformance-objc
-
-endif
diff --git a/third_party/protobuf/3.2.0/conformance/README.md b/third_party/protobuf/3.2.0/conformance/README.md
deleted file mode 100644
index 9388055fba..0000000000
--- a/third_party/protobuf/3.2.0/conformance/README.md
+++ /dev/null
@@ -1,45 +0,0 @@
-Protocol Buffers - Google's data interchange format
-===================================================
-
-[![Build Status](https://travis-ci.org/google/protobuf.svg?branch=master)](https://travis-ci.org/google/protobuf)
-
-Copyright 2008 Google Inc.
-
-This directory contains conformance tests for testing completeness and
-correctness of Protocol Buffers implementations. These tests are designed
-to be easy to run against any Protocol Buffers implementation.
-
-This directory contains the tester process `conformance-test`, which
-contains all of the tests themselves. Then separate programs written
-in whatever language you want to test communicate with the tester
-program over a pipe.
-
-Before running any of these tests, make sure you run `make` in the base
-directory to build `protoc`, since all the tests depend on it.
-
- $ make
-
-Then to run the tests against the C++ implementation, run:
-
- $ cd conformance && make test_cpp
-
-More tests and languages will be added soon!
-
-Testing other Protocol Buffer implementations
----------------------------------------------
-
-To run these tests against a new Protocol Buffers implementation, write a
-program in your language that uses the protobuf implementation you want
-to test. This program should implement the testing protocol defined in
-[conformance.proto](https://github.com/google/protobuf/blob/master/conformance/conformance.proto).
-This is designed to be as easy as possible: the C++ version is only
-150 lines and is a good example for what this program should look like
-(see [conformance_cpp.cc](https://github.com/google/protobuf/blob/master/conformance/conformance_cpp.cc)).
-The program only needs to be able to read from stdin and write to stdout.
-
-Portability
------------
-
-Note that the test runner currently does not work on Windows. Patches
-to fix this are welcome! (But please get in touch first to settle on
-a general implementation strategy).
diff --git a/third_party/protobuf/3.2.0/conformance/conformance.proto b/third_party/protobuf/3.2.0/conformance/conformance.proto
deleted file mode 100644
index 18e4b7bca6..0000000000
--- a/third_party/protobuf/3.2.0/conformance/conformance.proto
+++ /dev/null
@@ -1,114 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc. All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-syntax = "proto3";
-package conformance;
-option java_package = "com.google.protobuf.conformance";
-
-// This defines the conformance testing protocol. This protocol exists between
-// the conformance test suite itself and the code being tested. For each test,
-// the suite will send a ConformanceRequest message and expect a
-// ConformanceResponse message.
-//
-// You can either run the tests in two different ways:
-//
-// 1. in-process (using the interface in conformance_test.h).
-//
-// 2. as a sub-process communicating over a pipe. Information about how to
-// do this is in conformance_test_runner.cc.
-//
-// Pros/cons of the two approaches:
-//
-// - running as a sub-process is much simpler for languages other than C/C++.
-//
-// - running as a sub-process may be more tricky in unusual environments like
-// iOS apps, where fork/stdin/stdout are not available.
-
-enum WireFormat {
- UNSPECIFIED = 0;
- PROTOBUF = 1;
- JSON = 2;
-}
-
-// Represents a single test case's input. The testee should:
-//
-// 1. parse this proto (which should always succeed)
-// 2. parse the protobuf or JSON payload in "payload" (which may fail)
-// 3. if the parse succeeded, serialize the message in the requested format.
-message ConformanceRequest {
- // The payload (whether protobuf of JSON) is always for a
- // protobuf_test_messages.proto3.TestAllTypes proto (as defined in
- // src/google/protobuf/proto3_test_messages.proto).
- //
- // TODO(haberman): if/when we expand the conformance tests to support proto2,
- // we will want to include a field that lets the payload/response be a
- // protobuf_test_messages.proto2.TestAllTypes message instead.
- oneof payload {
- bytes protobuf_payload = 1;
- string json_payload = 2;
- }
-
- // Which format should the testee serialize its message to?
- WireFormat requested_output_format = 3;
-}
-
-// Represents a single test case's output.
-message ConformanceResponse {
- oneof result {
- // This string should be set to indicate parsing failed. The string can
- // provide more information about the parse error if it is available.
- //
- // Setting this string does not necessarily mean the testee failed the
- // test. Some of the test cases are intentionally invalid input.
- string parse_error = 1;
-
- // If the input was successfully parsed but errors occurred when
- // serializing it to the requested output format, set the error message in
- // this field.
- string serialize_error = 6;
-
- // This should be set if some other error occurred. This will always
- // indicate that the test failed. The string can provide more information
- // about the failure.
- string runtime_error = 2;
-
- // If the input was successfully parsed and the requested output was
- // protobuf, serialize it to protobuf and set it in this field.
- bytes protobuf_payload = 3;
-
- // If the input was successfully parsed and the requested output was JSON,
- // serialize to JSON and set it in this field.
- string json_payload = 4;
-
- // For when the testee skipped the test, likely because a certain feature
- // wasn't supported, like JSON input/output.
- string skipped = 5;
- }
-}
diff --git a/third_party/protobuf/3.2.0/conformance/conformance_cpp.cc b/third_party/protobuf/3.2.0/conformance/conformance_cpp.cc
deleted file mode 100644
index b865cd93ed..0000000000
--- a/third_party/protobuf/3.2.0/conformance/conformance_cpp.cc
+++ /dev/null
@@ -1,208 +0,0 @@
-// 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.
-
-#include <errno.h>
-#include <stdarg.h>
-#include <unistd.h>
-
-#include "conformance.pb.h"
-#include <google/protobuf/test_messages_proto3.pb.h>
-#include <google/protobuf/util/json_util.h>
-#include <google/protobuf/util/type_resolver_util.h>
-
-using conformance::ConformanceRequest;
-using conformance::ConformanceResponse;
-using google::protobuf::Descriptor;
-using google::protobuf::DescriptorPool;
-using google::protobuf::internal::scoped_ptr;
-using google::protobuf::util::BinaryToJsonString;
-using google::protobuf::util::JsonToBinaryString;
-using google::protobuf::util::NewTypeResolverForDescriptorPool;
-using google::protobuf::util::Status;
-using google::protobuf::util::TypeResolver;
-using protobuf_test_messages::proto3::TestAllTypes;
-using std::string;
-
-static const char kTypeUrlPrefix[] = "type.googleapis.com";
-
-static string GetTypeUrl(const Descriptor* message) {
- return string(kTypeUrlPrefix) + "/" + message->full_name();
-}
-
-int test_count = 0;
-bool verbose = false;
-TypeResolver* type_resolver;
-string* type_url;
-
-
-bool CheckedRead(int fd, void *buf, size_t len) {
- size_t ofs = 0;
- while (len > 0) {
- ssize_t bytes_read = read(fd, (char*)buf + ofs, len);
-
- if (bytes_read == 0) return false;
-
- if (bytes_read < 0) {
- GOOGLE_LOG(FATAL) << "Error reading from test runner: " << strerror(errno);
- }
-
- len -= bytes_read;
- ofs += bytes_read;
- }
-
- return true;
-}
-
-void CheckedWrite(int fd, const void *buf, size_t len) {
- if (write(fd, buf, len) != len) {
- GOOGLE_LOG(FATAL) << "Error writing to test runner: " << strerror(errno);
- }
-}
-
-void DoTest(const ConformanceRequest& request, ConformanceResponse* response) {
- TestAllTypes test_message;
-
- switch (request.payload_case()) {
- case ConformanceRequest::kProtobufPayload:
- if (!test_message.ParseFromString(request.protobuf_payload())) {
- // Getting parse details would involve something like:
- // http://stackoverflow.com/questions/22121922/how-can-i-get-more-details-about-errors-generated-during-protobuf-parsing-c
- response->set_parse_error("Parse error (no more details available).");
- return;
- }
- break;
-
- case ConformanceRequest::kJsonPayload: {
- string proto_binary;
- Status status = JsonToBinaryString(type_resolver, *type_url,
- request.json_payload(), &proto_binary);
- if (!status.ok()) {
- response->set_parse_error(string("Parse error: ") +
- status.error_message().as_string());
- return;
- }
-
- if (!test_message.ParseFromString(proto_binary)) {
- response->set_runtime_error(
- "Parsing JSON generates invalid proto output.");
- return;
- }
- break;
- }
-
- case ConformanceRequest::PAYLOAD_NOT_SET:
- GOOGLE_LOG(FATAL) << "Request didn't have payload.";
- break;
- }
-
- switch (request.requested_output_format()) {
- case conformance::UNSPECIFIED:
- GOOGLE_LOG(FATAL) << "Unspecified output format";
- break;
-
- case conformance::PROTOBUF:
- GOOGLE_CHECK(
- test_message.SerializeToString(response->mutable_protobuf_payload()));
- break;
-
- case conformance::JSON: {
- string proto_binary;
- GOOGLE_CHECK(test_message.SerializeToString(&proto_binary));
- Status status = BinaryToJsonString(type_resolver, *type_url, proto_binary,
- response->mutable_json_payload());
- if (!status.ok()) {
- response->set_serialize_error(
- string("Failed to serialize JSON output: ") +
- status.error_message().as_string());
- return;
- }
- break;
- }
-
- default:
- GOOGLE_LOG(FATAL) << "Unknown output format: "
- << request.requested_output_format();
- }
-}
-
-bool DoTestIo() {
- string serialized_input;
- string serialized_output;
- ConformanceRequest request;
- ConformanceResponse response;
- uint32_t bytes;
-
- if (!CheckedRead(STDIN_FILENO, &bytes, sizeof(uint32_t))) {
- // EOF.
- return false;
- }
-
- serialized_input.resize(bytes);
-
- if (!CheckedRead(STDIN_FILENO, (char*)serialized_input.c_str(), bytes)) {
- GOOGLE_LOG(ERROR) << "Unexpected EOF on stdin. " << strerror(errno);
- }
-
- if (!request.ParseFromString(serialized_input)) {
- GOOGLE_LOG(FATAL) << "Parse of ConformanceRequest proto failed.";
- return false;
- }
-
- DoTest(request, &response);
-
- response.SerializeToString(&serialized_output);
-
- bytes = serialized_output.size();
- CheckedWrite(STDOUT_FILENO, &bytes, sizeof(uint32_t));
- CheckedWrite(STDOUT_FILENO, serialized_output.c_str(), bytes);
-
- if (verbose) {
- fprintf(stderr, "conformance-cpp: request=%s, response=%s\n",
- request.ShortDebugString().c_str(),
- response.ShortDebugString().c_str());
- }
-
- test_count++;
-
- return true;
-}
-
-int main() {
- type_resolver = NewTypeResolverForDescriptorPool(
- kTypeUrlPrefix, DescriptorPool::generated_pool());
- type_url = new string(GetTypeUrl(TestAllTypes::descriptor()));
- while (1) {
- if (!DoTestIo()) {
- fprintf(stderr, "conformance-cpp: received EOF from test runner "
- "after %d tests, exiting\n", test_count);
- return 0;
- }
- }
-}
diff --git a/third_party/protobuf/3.2.0/conformance/conformance_objc.m b/third_party/protobuf/3.2.0/conformance/conformance_objc.m
deleted file mode 100644
index ef037f8496..0000000000
--- a/third_party/protobuf/3.2.0/conformance/conformance_objc.m
+++ /dev/null
@@ -1,180 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2015 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.
-
-#import <Foundation/Foundation.h>
-
-#import "Conformance.pbobjc.h"
-#import "google/protobuf/TestMessagesProto3.pbobjc.h"
-
-static void Die(NSString *format, ...) __dead2;
-
-static BOOL verbose = NO;
-static int32_t testCount = 0;
-
-static void Die(NSString *format, ...) {
- va_list args;
- va_start(args, format);
- NSString *msg = [[NSString alloc] initWithFormat:format arguments:args];
- NSLog(@"%@", msg);
- va_end(args);
- [msg release];
- exit(66);
-}
-
-static NSData *CheckedReadDataOfLength(NSFileHandle *handle, NSUInteger numBytes) {
- NSData *data = [handle readDataOfLength:numBytes];
- NSUInteger dataLen = data.length;
- if (dataLen == 0) {
- return nil; // EOF.
- }
- if (dataLen != numBytes) {
- Die(@"Failed to read the request length (%d), only got: %@",
- numBytes, data);
- }
- return data;
-}
-
-static ConformanceResponse *DoTest(ConformanceRequest *request) {
- ConformanceResponse *response = [ConformanceResponse message];
- TestAllTypes *testMessage = nil;
-
- switch (request.payloadOneOfCase) {
- case ConformanceRequest_Payload_OneOfCase_GPBUnsetOneOfCase:
- Die(@"Request didn't have a payload: %@", request);
- break;
-
- case ConformanceRequest_Payload_OneOfCase_ProtobufPayload: {
- NSError *error = nil;
- testMessage = [TestAllTypes parseFromData:request.protobufPayload
- error:&error];
- if (!testMessage) {
- response.parseError =
- [NSString stringWithFormat:@"Parse error: %@", error];
- }
- break;
- }
-
- case ConformanceRequest_Payload_OneOfCase_JsonPayload:
- response.skipped = @"ObjC doesn't support parsing JSON";
- break;
- }
-
- if (testMessage) {
- switch (request.requestedOutputFormat) {
- case WireFormat_GPBUnrecognizedEnumeratorValue:
- case WireFormat_Unspecified:
- Die(@"Unrecognized/unspecified output format: %@", request);
- break;
-
- case WireFormat_Protobuf:
- response.protobufPayload = testMessage.data;
- if (!response.protobufPayload) {
- response.serializeError =
- [NSString stringWithFormat:@"Failed to make data from: %@", testMessage];
- }
- break;
-
- case WireFormat_Json:
- response.skipped = @"ObjC doesn't support generating JSON";
- break;
- }
- }
-
- return response;
-}
-
-static uint32_t UInt32FromLittleEndianData(NSData *data) {
- if (data.length != sizeof(uint32_t)) {
- Die(@"Data not the right size for uint32_t: %@", data);
- }
- uint32_t value;
- memcpy(&value, data.bytes, sizeof(uint32_t));
- return CFSwapInt32LittleToHost(value);
-}
-
-static NSData *UInt32ToLittleEndianData(uint32_t num) {
- uint32_t value = CFSwapInt32HostToLittle(num);
- return [NSData dataWithBytes:&value length:sizeof(uint32_t)];
-}
-
-static BOOL DoTestIo(NSFileHandle *input, NSFileHandle *output) {
- // See conformance_test_runner.cc for the wire format.
- NSData *data = CheckedReadDataOfLength(input, sizeof(uint32_t));
- if (!data) {
- // EOF.
- return NO;
- }
- uint32_t numBytes = UInt32FromLittleEndianData(data);
- data = CheckedReadDataOfLength(input, numBytes);
- if (!data) {
- Die(@"Failed to read request");
- }
-
- NSError *error = nil;
- ConformanceRequest *request = [ConformanceRequest parseFromData:data
- error:&error];
- if (!request) {
- Die(@"Failed to parse the message data: %@", error);
- }
-
- ConformanceResponse *response = DoTest(request);
- if (!response) {
- Die(@"Failed to make a reply from %@", request);
- }
-
- data = response.data;
- [output writeData:UInt32ToLittleEndianData((int32_t)data.length)];
- [output writeData:data];
-
- if (verbose) {
- NSLog(@"Request: %@", request);
- NSLog(@"Response: %@", response);
- }
-
- ++testCount;
- return YES;
-}
-
-int main(int argc, const char *argv[]) {
- @autoreleasepool {
- NSFileHandle *input = [[NSFileHandle fileHandleWithStandardInput] retain];
- NSFileHandle *output = [[NSFileHandle fileHandleWithStandardOutput] retain];
-
- BOOL notDone = YES;
- while (notDone) {
- @autoreleasepool {
- notDone = DoTestIo(input, output);
- }
- }
-
- NSLog(@"Received EOF from test runner after %d tests, exiting.", testCount);
- }
- return 0;
-}
diff --git a/third_party/protobuf/3.2.0/conformance/conformance_python.py b/third_party/protobuf/3.2.0/conformance/conformance_python.py
deleted file mode 100755
index 7ace9b1672..0000000000
--- a/third_party/protobuf/3.2.0/conformance/conformance_python.py
+++ /dev/null
@@ -1,135 +0,0 @@
-#!/usr/bin/env python
-#
-# 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.
-
-"""A conformance test implementation for the Python protobuf library.
-
-See conformance.proto for more information.
-"""
-
-import struct
-import sys
-import os
-from google.protobuf import json_format
-from google.protobuf import message
-from google.protobuf import test_messages_proto3_pb2
-import conformance_pb2
-
-sys.stdout = os.fdopen(sys.stdout.fileno(), 'wb', 0)
-sys.stdin = os.fdopen(sys.stdin.fileno(), 'rb', 0)
-
-test_count = 0
-verbose = False
-
-class ProtocolError(Exception):
- pass
-
-def do_test(request):
- test_message = test_messages_proto3_pb2.TestAllTypes()
- response = conformance_pb2.ConformanceResponse()
- test_message = test_messages_proto3_pb2.TestAllTypes()
-
- try:
- if request.WhichOneof('payload') == 'protobuf_payload':
- try:
- test_message.ParseFromString(request.protobuf_payload)
- except message.DecodeError as e:
- response.parse_error = str(e)
- return response
-
- elif request.WhichOneof('payload') == 'json_payload':
- try:
- json_format.Parse(request.json_payload, test_message)
- except Exception as e:
- response.parse_error = str(e)
- return response
-
- else:
- raise ProtocolError("Request didn't have payload.")
-
- if request.requested_output_format == conformance_pb2.UNSPECIFIED:
- raise ProtocolError("Unspecified output format")
-
- elif request.requested_output_format == conformance_pb2.PROTOBUF:
- response.protobuf_payload = test_message.SerializeToString()
-
- elif request.requested_output_format == conformance_pb2.JSON:
- try:
- response.json_payload = json_format.MessageToJson(test_message)
- except Exception as e:
- response.serialize_error = str(e)
- return response
-
- except Exception as e:
- response.runtime_error = str(e)
-
- return response
-
-def do_test_io():
- length_bytes = sys.stdin.read(4)
- if len(length_bytes) == 0:
- return False # EOF
- elif len(length_bytes) != 4:
- raise IOError("I/O error")
-
- # "I" is "unsigned int", so this depends on running on a platform with
- # 32-bit "unsigned int" type. The Python struct module unfortunately
- # has no format specifier for uint32_t.
- length = struct.unpack("<I", length_bytes)[0]
- serialized_request = sys.stdin.read(length)
- if len(serialized_request) != length:
- raise IOError("I/O error")
-
- request = conformance_pb2.ConformanceRequest()
- request.ParseFromString(serialized_request)
-
- response = do_test(request)
-
- serialized_response = response.SerializeToString()
- sys.stdout.write(struct.pack("<I", len(serialized_response)))
- sys.stdout.write(serialized_response)
- sys.stdout.flush()
-
- if verbose:
- sys.stderr.write("conformance_python: request=%s, response=%s\n" % (
- request.ShortDebugString().c_str(),
- response.ShortDebugString().c_str()))
-
- global test_count
- test_count += 1
-
- return True
-
-while True:
- if not do_test_io():
- sys.stderr.write("conformance_python: received EOF from test runner " +
- "after %s tests, exiting\n" % (test_count))
- sys.exit(0)
diff --git a/third_party/protobuf/3.2.0/conformance/conformance_ruby.rb b/third_party/protobuf/3.2.0/conformance/conformance_ruby.rb
deleted file mode 100755
index b7b7cf1c6c..0000000000
--- a/third_party/protobuf/3.2.0/conformance/conformance_ruby.rb
+++ /dev/null
@@ -1,124 +0,0 @@
-#!/usr/bin/env ruby
-#
-# Protocol Buffers - Google's data interchange format
-# Copyright 2008 Google Inc. All rights reserved.
-# https://developers.google.com/protocol-buffers/
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-require 'conformance_pb'
-require 'google/protobuf/test_messages_proto3_pb'
-
-$test_count = 0
-$verbose = false
-
-def do_test(request)
- test_message = ProtobufTestMessages::Proto3::TestAllTypes.new
- response = Conformance::ConformanceResponse.new
-
- begin
- case request.payload
- when :protobuf_payload
- begin
- test_message = ProtobufTestMessages::Proto3::TestAllTypes.decode(
- request.protobuf_payload)
- rescue Google::Protobuf::ParseError => err
- response.parse_error = err.message.encode('utf-8')
- return response
- end
-
- when :json_payload
- begin
- test_message = ProtobufTestMessages::Proto3::TestAllTypes.decode_json(
- request.json_payload)
- rescue Google::Protobuf::ParseError => err
- response.parse_error = err.message.encode('utf-8')
- return response
- end
-
- when nil
- fail "Request didn't have payload"
- end
-
- case request.requested_output_format
- when :UNSPECIFIED
- fail 'Unspecified output format'
-
- when :PROTOBUF
- response.protobuf_payload = test_message.to_proto
-
- when :JSON
- response.json_payload = test_message.to_json
-
- when nil
- fail "Request didn't have requested output format"
- end
- rescue StandardError => err
- response.runtime_error = err.message.encode('utf-8')
- end
-
- response
-end
-
-# Returns true if the test ran successfully, false on legitimate EOF.
-# If EOF is encountered in an unexpected place, raises IOError.
-def do_test_io
- length_bytes = STDIN.read(4)
- return false if length_bytes.nil?
-
- length = length_bytes.unpack('V').first
- serialized_request = STDIN.read(length)
- if serialized_request.nil? || serialized_request.length != length
- fail IOError
- end
-
- request = Conformance::ConformanceRequest.decode(serialized_request)
-
- response = do_test(request)
-
- serialized_response = Conformance::ConformanceResponse.encode(response)
- STDOUT.write([serialized_response.length].pack('V'))
- STDOUT.write(serialized_response)
- STDOUT.flush
-
- if $verbose
- STDERR.puts("conformance_ruby: request=#{request.to_json}, " \
- "response=#{response.to_json}\n")
- end
-
- $test_count += 1
-
- true
-end
-
-loop do
- unless do_test_io
- STDERR.puts('conformance_ruby: received EOF from test runner ' \
- "after #{$test_count} tests, exiting")
- break
- end
-end
diff --git a/third_party/protobuf/3.2.0/conformance/conformance_test.cc b/third_party/protobuf/3.2.0/conformance/conformance_test.cc
deleted file mode 100644
index dd266d15ba..0000000000
--- a/third_party/protobuf/3.2.0/conformance/conformance_test.cc
+++ /dev/null
@@ -1,2383 +0,0 @@
-// 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.
-
-#include <stdarg.h>
-#include <string>
-#include <fstream>
-
-#include "conformance.pb.h"
-#include "conformance_test.h"
-#include <google/protobuf/test_messages_proto3.pb.h>
-
-#include <google/protobuf/stubs/common.h>
-#include <google/protobuf/stubs/stringprintf.h>
-#include <google/protobuf/text_format.h>
-#include <google/protobuf/util/field_comparator.h>
-#include <google/protobuf/util/json_util.h>
-#include <google/protobuf/util/message_differencer.h>
-#include <google/protobuf/util/type_resolver_util.h>
-#include <google/protobuf/wire_format_lite.h>
-
-#include "third_party/jsoncpp/json.h"
-
-using conformance::ConformanceRequest;
-using conformance::ConformanceResponse;
-using conformance::WireFormat;
-using google::protobuf::Descriptor;
-using google::protobuf::FieldDescriptor;
-using google::protobuf::internal::WireFormatLite;
-using google::protobuf::TextFormat;
-using google::protobuf::util::DefaultFieldComparator;
-using google::protobuf::util::JsonToBinaryString;
-using google::protobuf::util::MessageDifferencer;
-using google::protobuf::util::NewTypeResolverForDescriptorPool;
-using google::protobuf::util::Status;
-using protobuf_test_messages::proto3::TestAllTypes;
-using std::string;
-
-namespace {
-
-static const char kTypeUrlPrefix[] = "type.googleapis.com";
-
-static string GetTypeUrl(const Descriptor* message) {
- return string(kTypeUrlPrefix) + "/" + message->full_name();
-}
-
-/* Routines for building arbitrary protos *************************************/
-
-// We would use CodedOutputStream except that we want more freedom to build
-// arbitrary protos (even invalid ones).
-
-const string empty;
-
-string cat(const string& a, const string& b,
- const string& c = empty,
- const string& d = empty,
- const string& e = empty,
- const string& f = empty,
- const string& g = empty,
- const string& h = empty,
- const string& i = empty,
- const string& j = empty,
- const string& k = empty,
- const string& l = empty) {
- string ret;
- ret.reserve(a.size() + b.size() + c.size() + d.size() + e.size() + f.size() +
- g.size() + h.size() + i.size() + j.size() + k.size() + l.size());
- ret.append(a);
- ret.append(b);
- ret.append(c);
- ret.append(d);
- ret.append(e);
- ret.append(f);
- ret.append(g);
- ret.append(h);
- ret.append(i);
- ret.append(j);
- ret.append(k);
- ret.append(l);
- return ret;
-}
-
-// The maximum number of bytes that it takes to encode a 64-bit varint.
-#define VARINT_MAX_LEN 10
-
-size_t vencode64(uint64_t val, char *buf) {
- if (val == 0) { buf[0] = 0; return 1; }
- size_t i = 0;
- while (val) {
- uint8_t byte = val & 0x7fU;
- val >>= 7;
- if (val) byte |= 0x80U;
- buf[i++] = byte;
- }
- return i;
-}
-
-string varint(uint64_t x) {
- char buf[VARINT_MAX_LEN];
- size_t len = vencode64(x, buf);
- return string(buf, len);
-}
-
-// TODO: proper byte-swapping for big-endian machines.
-string fixed32(void *data) { return string(static_cast<char*>(data), 4); }
-string fixed64(void *data) { return string(static_cast<char*>(data), 8); }
-
-string delim(const string& buf) { return cat(varint(buf.size()), buf); }
-string u32(uint32_t u32) { return fixed32(&u32); }
-string u64(uint64_t u64) { return fixed64(&u64); }
-string flt(float f) { return fixed32(&f); }
-string dbl(double d) { return fixed64(&d); }
-string zz32(int32_t x) { return varint(WireFormatLite::ZigZagEncode32(x)); }
-string zz64(int64_t x) { return varint(WireFormatLite::ZigZagEncode64(x)); }
-
-string tag(uint32_t fieldnum, char wire_type) {
- return varint((fieldnum << 3) | wire_type);
-}
-
-string submsg(uint32_t fn, const string& buf) {
- return cat( tag(fn, WireFormatLite::WIRETYPE_LENGTH_DELIMITED), delim(buf) );
-}
-
-#define UNKNOWN_FIELD 666
-
-const FieldDescriptor* GetFieldForType(FieldDescriptor::Type type,
- bool repeated) {
- const Descriptor* d = TestAllTypes().GetDescriptor();
- for (int i = 0; i < d->field_count(); i++) {
- const FieldDescriptor* f = d->field(i);
- if (f->type() == type && f->is_repeated() == repeated) {
- return f;
- }
- }
- GOOGLE_LOG(FATAL) << "Couldn't find field with type " << (int)type;
- return nullptr;
-}
-
-string UpperCase(string str) {
- for (int i = 0; i < str.size(); i++) {
- str[i] = toupper(str[i]);
- }
- return str;
-}
-
-} // anonymous namespace
-
-namespace google {
-namespace protobuf {
-
-void ConformanceTestSuite::ReportSuccess(const string& test_name) {
- if (expected_to_fail_.erase(test_name) != 0) {
- StringAppendF(&output_,
- "ERROR: test %s is in the failure list, but test succeeded. "
- "Remove it from the failure list.\n",
- test_name.c_str());
- unexpected_succeeding_tests_.insert(test_name);
- }
- successes_++;
-}
-
-void ConformanceTestSuite::ReportFailure(const string& test_name,
- ConformanceLevel level,
- const ConformanceRequest& request,
- const ConformanceResponse& response,
- const char* fmt, ...) {
- if (expected_to_fail_.erase(test_name) == 1) {
- expected_failures_++;
- if (!verbose_)
- return;
- } else if (level == RECOMMENDED && !enforce_recommended_) {
- StringAppendF(&output_, "WARNING, test=%s: ", test_name.c_str());
- } else {
- StringAppendF(&output_, "ERROR, test=%s: ", test_name.c_str());
- unexpected_failing_tests_.insert(test_name);
- }
- va_list args;
- va_start(args, fmt);
- StringAppendV(&output_, fmt, args);
- va_end(args);
- StringAppendF(&output_, " request=%s, response=%s\n",
- request.ShortDebugString().c_str(),
- response.ShortDebugString().c_str());
-}
-
-void ConformanceTestSuite::ReportSkip(const string& test_name,
- const ConformanceRequest& request,
- const ConformanceResponse& response) {
- if (verbose_) {
- StringAppendF(&output_, "SKIPPED, test=%s request=%s, response=%s\n",
- test_name.c_str(), request.ShortDebugString().c_str(),
- response.ShortDebugString().c_str());
- }
- skipped_.insert(test_name);
-}
-
-string ConformanceTestSuite::ConformanceLevelToString(ConformanceLevel level) {
- switch (level) {
- case REQUIRED: return "Required";
- case RECOMMENDED: return "Recommended";
- }
- GOOGLE_LOG(FATAL) << "Unknown value: " << level;
- return "";
-}
-
-void ConformanceTestSuite::RunTest(const string& test_name,
- const ConformanceRequest& request,
- ConformanceResponse* response) {
- if (test_names_.insert(test_name).second == false) {
- GOOGLE_LOG(FATAL) << "Duplicated test name: " << test_name;
- }
-
- string serialized_request;
- string serialized_response;
- request.SerializeToString(&serialized_request);
-
- runner_->RunTest(test_name, serialized_request, &serialized_response);
-
- if (!response->ParseFromString(serialized_response)) {
- response->Clear();
- response->set_runtime_error("response proto could not be parsed.");
- }
-
- if (verbose_) {
- StringAppendF(&output_, "conformance test: name=%s, request=%s, response=%s\n",
- test_name.c_str(),
- request.ShortDebugString().c_str(),
- response->ShortDebugString().c_str());
- }
-}
-
-void ConformanceTestSuite::RunValidInputTest(
- const string& test_name, ConformanceLevel level, const string& input,
- WireFormat input_format, const string& equivalent_text_format,
- WireFormat requested_output) {
- TestAllTypes reference_message;
- GOOGLE_CHECK(
- TextFormat::ParseFromString(equivalent_text_format, &reference_message))
- << "Failed to parse data for test case: " << test_name
- << ", data: " << equivalent_text_format;
-
- ConformanceRequest request;
- ConformanceResponse response;
-
- switch (input_format) {
- case conformance::PROTOBUF:
- request.set_protobuf_payload(input);
- break;
-
- case conformance::JSON:
- request.set_json_payload(input);
- break;
-
- default:
- GOOGLE_LOG(FATAL) << "Unspecified input format";
- }
-
- request.set_requested_output_format(requested_output);
-
- RunTest(test_name, request, &response);
-
- TestAllTypes test_message;
-
- switch (response.result_case()) {
- case ConformanceResponse::RESULT_NOT_SET:
- ReportFailure(test_name, level, request, response,
- "Response didn't have any field in the Response.");
- return;
-
- case ConformanceResponse::kParseError:
- case ConformanceResponse::kRuntimeError:
- case ConformanceResponse::kSerializeError:
- ReportFailure(test_name, level, request, response,
- "Failed to parse input or produce output.");
- return;
-
- case ConformanceResponse::kSkipped:
- ReportSkip(test_name, request, response);
- return;
-
- case ConformanceResponse::kJsonPayload: {
- if (requested_output != conformance::JSON) {
- ReportFailure(
- test_name, level, request, response,
- "Test was asked for protobuf output but provided JSON instead.");
- return;
- }
- string binary_protobuf;
- Status status =
- JsonToBinaryString(type_resolver_.get(), type_url_,
- response.json_payload(), &binary_protobuf);
- if (!status.ok()) {
- ReportFailure(test_name, level, request, response,
- "JSON output we received from test was unparseable.");
- return;
- }
-
- if (!test_message.ParseFromString(binary_protobuf)) {
- ReportFailure(test_name, level, request, response,
- "INTERNAL ERROR: internal JSON->protobuf transcode "
- "yielded unparseable proto.");
- return;
- }
-
- break;
- }
-
- case ConformanceResponse::kProtobufPayload: {
- if (requested_output != conformance::PROTOBUF) {
- ReportFailure(
- test_name, level, request, response,
- "Test was asked for JSON output but provided protobuf instead.");
- return;
- }
-
- if (!test_message.ParseFromString(response.protobuf_payload())) {
- ReportFailure(test_name, level, request, response,
- "Protobuf output we received from test was unparseable.");
- return;
- }
-
- break;
- }
-
- default:
- GOOGLE_LOG(FATAL) << test_name << ": unknown payload type: "
- << response.result_case();
- }
-
- MessageDifferencer differencer;
- DefaultFieldComparator field_comparator;
- field_comparator.set_treat_nan_as_equal(true);
- differencer.set_field_comparator(&field_comparator);
- string differences;
- differencer.ReportDifferencesToString(&differences);
-
- if (differencer.Compare(reference_message, test_message)) {
- ReportSuccess(test_name);
- } else {
- ReportFailure(test_name, level, request, response,
- "Output was not equivalent to reference message: %s.",
- differences.c_str());
- }
-}
-
-// Expect that this precise protobuf will cause a parse error.
-void ConformanceTestSuite::ExpectParseFailureForProto(
- const string& proto, const string& test_name, ConformanceLevel level) {
- ConformanceRequest request;
- ConformanceResponse response;
- request.set_protobuf_payload(proto);
- string effective_test_name = ConformanceLevelToString(level) +
- ".ProtobufInput." + test_name;
-
- // We don't expect output, but if the program erroneously accepts the protobuf
- // we let it send its response as this. We must not leave it unspecified.
- request.set_requested_output_format(conformance::PROTOBUF);
-
- RunTest(effective_test_name, request, &response);
- if (response.result_case() == ConformanceResponse::kParseError) {
- ReportSuccess(effective_test_name);
- } else if (response.result_case() == ConformanceResponse::kSkipped) {
- ReportSkip(effective_test_name, request, response);
- } else {
- ReportFailure(effective_test_name, level, request, response,
- "Should have failed to parse, but didn't.");
- }
-}
-
-// Expect that this protobuf will cause a parse error, even if it is followed
-// by valid protobuf data. We can try running this twice: once with this
-// data verbatim and once with this data followed by some valid data.
-//
-// TODO(haberman): implement the second of these.
-void ConformanceTestSuite::ExpectHardParseFailureForProto(
- const string& proto, const string& test_name, ConformanceLevel level) {
- return ExpectParseFailureForProto(proto, test_name, level);
-}
-
-void ConformanceTestSuite::RunValidJsonTest(
- const string& test_name, ConformanceLevel level, const string& input_json,
- const string& equivalent_text_format) {
- RunValidInputTest(
- ConformanceLevelToString(level) + ".JsonInput." + test_name +
- ".ProtobufOutput", level, input_json, conformance::JSON,
- equivalent_text_format, conformance::PROTOBUF);
- RunValidInputTest(
- ConformanceLevelToString(level) + ".JsonInput." + test_name +
- ".JsonOutput", level, input_json, conformance::JSON,
- equivalent_text_format, conformance::JSON);
-}
-
-void ConformanceTestSuite::RunValidJsonTestWithProtobufInput(
- const string& test_name, ConformanceLevel level, const TestAllTypes& input,
- const string& equivalent_text_format) {
- RunValidInputTest(
- ConformanceLevelToString(level) + ".ProtobufInput." + test_name +
- ".JsonOutput", level, input.SerializeAsString(), conformance::PROTOBUF,
- equivalent_text_format, conformance::JSON);
-}
-
-void ConformanceTestSuite::RunValidProtobufTest(
- const string& test_name, ConformanceLevel level,
- const string& input_protobuf, const string& equivalent_text_format) {
- RunValidInputTest(
- ConformanceLevelToString(level) + ".ProtobufInput." + test_name +
- ".ProtobufOutput", level, input_protobuf, conformance::PROTOBUF,
- equivalent_text_format, conformance::PROTOBUF);
- RunValidInputTest(
- ConformanceLevelToString(level) + ".ProtobufInput." + test_name +
- ".JsonOutput", level, input_protobuf, conformance::PROTOBUF,
- equivalent_text_format, conformance::JSON);
-}
-
-void ConformanceTestSuite::RunValidProtobufTestWithMessage(
- const string& test_name, ConformanceLevel level, const TestAllTypes& input,
- const string& equivalent_text_format) {
- RunValidProtobufTest(test_name, level, input.SerializeAsString(), equivalent_text_format);
-}
-
-// According to proto3 JSON specification, JSON serializers follow more strict
-// rules than parsers (e.g., a serializer must serialize int32 values as JSON
-// numbers while the parser is allowed to accept them as JSON strings). This
-// method allows strict checking on a proto3 JSON serializer by inspecting
-// the JSON output directly.
-void ConformanceTestSuite::RunValidJsonTestWithValidator(
- const string& test_name, ConformanceLevel level, const string& input_json,
- const Validator& validator) {
- ConformanceRequest request;
- ConformanceResponse response;
- request.set_json_payload(input_json);
- request.set_requested_output_format(conformance::JSON);
-
- string effective_test_name = ConformanceLevelToString(level) +
- ".JsonInput." + test_name + ".Validator";
-
- RunTest(effective_test_name, request, &response);
-
- if (response.result_case() == ConformanceResponse::kSkipped) {
- ReportSkip(effective_test_name, request, response);
- return;
- }
-
- if (response.result_case() != ConformanceResponse::kJsonPayload) {
- ReportFailure(effective_test_name, level, request, response,
- "Expected JSON payload but got type %d.",
- response.result_case());
- return;
- }
- Json::Reader reader;
- Json::Value value;
- if (!reader.parse(response.json_payload(), value)) {
- ReportFailure(effective_test_name, level, request, response,
- "JSON payload cannot be parsed as valid JSON: %s",
- reader.getFormattedErrorMessages().c_str());
- return;
- }
- if (!validator(value)) {
- ReportFailure(effective_test_name, level, request, response,
- "JSON payload validation failed.");
- return;
- }
- ReportSuccess(effective_test_name);
-}
-
-void ConformanceTestSuite::ExpectParseFailureForJson(
- const string& test_name, ConformanceLevel level, const string& input_json) {
- ConformanceRequest request;
- ConformanceResponse response;
- request.set_json_payload(input_json);
- string effective_test_name =
- ConformanceLevelToString(level) + ".JsonInput." + test_name;
-
- // We don't expect output, but if the program erroneously accepts the protobuf
- // we let it send its response as this. We must not leave it unspecified.
- request.set_requested_output_format(conformance::JSON);
-
- RunTest(effective_test_name, request, &response);
- if (response.result_case() == ConformanceResponse::kParseError) {
- ReportSuccess(effective_test_name);
- } else if (response.result_case() == ConformanceResponse::kSkipped) {
- ReportSkip(effective_test_name, request, response);
- } else {
- ReportFailure(effective_test_name, level, request, response,
- "Should have failed to parse, but didn't.");
- }
-}
-
-void ConformanceTestSuite::ExpectSerializeFailureForJson(
- const string& test_name, ConformanceLevel level, const string& text_format) {
- TestAllTypes payload_message;
- GOOGLE_CHECK(
- TextFormat::ParseFromString(text_format, &payload_message))
- << "Failed to parse: " << text_format;
-
- ConformanceRequest request;
- ConformanceResponse response;
- request.set_protobuf_payload(payload_message.SerializeAsString());
- string effective_test_name =
- ConformanceLevelToString(level) + "." + test_name + ".JsonOutput";
- request.set_requested_output_format(conformance::JSON);
-
- RunTest(effective_test_name, request, &response);
- if (response.result_case() == ConformanceResponse::kSerializeError) {
- ReportSuccess(effective_test_name);
- } else if (response.result_case() == ConformanceResponse::kSkipped) {
- ReportSkip(effective_test_name, request, response);
- } else {
- ReportFailure(effective_test_name, level, request, response,
- "Should have failed to serialize, but didn't.");
- }
-}
-
-void ConformanceTestSuite::TestPrematureEOFForType(FieldDescriptor::Type type) {
- // Incomplete values for each wire type.
- static const string incompletes[6] = {
- string("\x80"), // VARINT
- string("abcdefg"), // 64BIT
- string("\x80"), // DELIMITED (partial length)
- string(), // START_GROUP (no value required)
- string(), // END_GROUP (no value required)
- string("abc") // 32BIT
- };
-
- const FieldDescriptor* field = GetFieldForType(type, false);
- const FieldDescriptor* rep_field = GetFieldForType(type, true);
- WireFormatLite::WireType wire_type = WireFormatLite::WireTypeForFieldType(
- static_cast<WireFormatLite::FieldType>(type));
- const string& incomplete = incompletes[wire_type];
- const string type_name =
- UpperCase(string(".") + FieldDescriptor::TypeName(type));
-
- ExpectParseFailureForProto(
- tag(field->number(), wire_type),
- "PrematureEofBeforeKnownNonRepeatedValue" + type_name, REQUIRED);
-
- ExpectParseFailureForProto(
- tag(rep_field->number(), wire_type),
- "PrematureEofBeforeKnownRepeatedValue" + type_name, REQUIRED);
-
- ExpectParseFailureForProto(
- tag(UNKNOWN_FIELD, wire_type),
- "PrematureEofBeforeUnknownValue" + type_name, REQUIRED);
-
- ExpectParseFailureForProto(
- cat( tag(field->number(), wire_type), incomplete ),
- "PrematureEofInsideKnownNonRepeatedValue" + type_name, REQUIRED);
-
- ExpectParseFailureForProto(
- cat( tag(rep_field->number(), wire_type), incomplete ),
- "PrematureEofInsideKnownRepeatedValue" + type_name, REQUIRED);
-
- ExpectParseFailureForProto(
- cat( tag(UNKNOWN_FIELD, wire_type), incomplete ),
- "PrematureEofInsideUnknownValue" + type_name, REQUIRED);
-
- if (wire_type == WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
- ExpectParseFailureForProto(
- cat( tag(field->number(), wire_type), varint(1) ),
- "PrematureEofInDelimitedDataForKnownNonRepeatedValue" + type_name,
- REQUIRED);
-
- ExpectParseFailureForProto(
- cat( tag(rep_field->number(), wire_type), varint(1) ),
- "PrematureEofInDelimitedDataForKnownRepeatedValue" + type_name,
- REQUIRED);
-
- // EOF in the middle of delimited data for unknown value.
- ExpectParseFailureForProto(
- cat( tag(UNKNOWN_FIELD, wire_type), varint(1) ),
- "PrematureEofInDelimitedDataForUnknownValue" + type_name, REQUIRED);
-
- if (type == FieldDescriptor::TYPE_MESSAGE) {
- // Submessage ends in the middle of a value.
- string incomplete_submsg =
- cat( tag(WireFormatLite::TYPE_INT32, WireFormatLite::WIRETYPE_VARINT),
- incompletes[WireFormatLite::WIRETYPE_VARINT] );
- ExpectHardParseFailureForProto(
- cat( tag(field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED),
- varint(incomplete_submsg.size()),
- incomplete_submsg ),
- "PrematureEofInSubmessageValue" + type_name, REQUIRED);
- }
- } else if (type != FieldDescriptor::TYPE_GROUP) {
- // Non-delimited, non-group: eligible for packing.
-
- // Packed region ends in the middle of a value.
- ExpectHardParseFailureForProto(
- cat(tag(rep_field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED),
- varint(incomplete.size()), incomplete),
- "PrematureEofInPackedFieldValue" + type_name, REQUIRED);
-
- // EOF in the middle of packed region.
- ExpectParseFailureForProto(
- cat(tag(rep_field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED),
- varint(1)),
- "PrematureEofInPackedField" + type_name, REQUIRED);
- }
-}
-
-void ConformanceTestSuite::TestValidDataForType(
- FieldDescriptor::Type type,
- std::vector<std::pair<std::string, std::string>> values) {
- const string type_name =
- UpperCase(string(".") + FieldDescriptor::TypeName(type));
- WireFormatLite::WireType wire_type = WireFormatLite::WireTypeForFieldType(
- static_cast<WireFormatLite::FieldType>(type));
- const FieldDescriptor* field = GetFieldForType(type, false);
- const FieldDescriptor* rep_field = GetFieldForType(type, true);
-
- RunValidProtobufTest("ValidDataScalar" + type_name, REQUIRED,
- cat(tag(field->number(), wire_type), values[0].first),
- field->name() + ": " + values[0].second);
-
- string proto;
- string text = field->name() + ": " + values.back().second;
- for (size_t i = 0; i < values.size(); i++) {
- proto += cat(tag(field->number(), wire_type), values[i].first);
- }
- RunValidProtobufTest("RepeatedScalarSelectsLast" + type_name, REQUIRED,
- proto, text);
-
- proto.clear();
- text.clear();
-
- for (size_t i = 0; i < values.size(); i++) {
- proto += cat(tag(rep_field->number(), wire_type), values[i].first);
- text += rep_field->name() + ": " + values[i].second + " ";
- }
- RunValidProtobufTest("ValidDataRepeated" + type_name, REQUIRED, proto, text);
-}
-
-void ConformanceTestSuite::SetFailureList(const string& filename,
- const vector<string>& failure_list) {
- failure_list_filename_ = filename;
- expected_to_fail_.clear();
- std::copy(failure_list.begin(), failure_list.end(),
- std::inserter(expected_to_fail_, expected_to_fail_.end()));
-}
-
-bool ConformanceTestSuite::CheckSetEmpty(const set<string>& set_to_check,
- const std::string& write_to_file,
- const std::string& msg) {
- if (set_to_check.empty()) {
- return true;
- } else {
- StringAppendF(&output_, "\n");
- StringAppendF(&output_, "%s\n\n", msg.c_str());
- for (set<string>::const_iterator iter = set_to_check.begin();
- iter != set_to_check.end(); ++iter) {
- StringAppendF(&output_, " %s\n", iter->c_str());
- }
- StringAppendF(&output_, "\n");
-
- if (!write_to_file.empty()) {
- std::ofstream os(write_to_file);
- if (os) {
- for (set<string>::const_iterator iter = set_to_check.begin();
- iter != set_to_check.end(); ++iter) {
- os << *iter << "\n";
- }
- } else {
- StringAppendF(&output_, "Failed to open file: %s\n",
- write_to_file.c_str());
- }
- }
-
- return false;
- }
-}
-
-bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner,
- std::string* output) {
- runner_ = runner;
- successes_ = 0;
- expected_failures_ = 0;
- skipped_.clear();
- test_names_.clear();
- unexpected_failing_tests_.clear();
- unexpected_succeeding_tests_.clear();
- type_resolver_.reset(NewTypeResolverForDescriptorPool(
- kTypeUrlPrefix, DescriptorPool::generated_pool()));
- type_url_ = GetTypeUrl(TestAllTypes::descriptor());
-
- output_ = "\nCONFORMANCE TEST BEGIN ====================================\n\n";
-
- for (int i = 1; i <= FieldDescriptor::MAX_TYPE; i++) {
- if (i == FieldDescriptor::TYPE_GROUP) continue;
- TestPrematureEOFForType(static_cast<FieldDescriptor::Type>(i));
- }
-
- int64 kInt64Min = -9223372036854775808ULL;
- int64 kInt64Max = 9223372036854775807ULL;
- uint64 kUint64Max = 18446744073709551615ULL;
- int32 kInt32Max = 2147483647;
- int32 kInt32Min = -2147483648;
- uint32 kUint32Max = 4294967295UL;
-
- TestValidDataForType(FieldDescriptor::TYPE_DOUBLE, {
- {dbl(0.1), "0.1"},
- {dbl(1.7976931348623157e+308), "1.7976931348623157e+308"},
- {dbl(2.22507385850720138309e-308), "2.22507385850720138309e-308"}
- });
- TestValidDataForType(FieldDescriptor::TYPE_FLOAT, {
- {flt(0.1), "0.1"},
- {flt(3.402823e+38), "3.402823e+38"}, // 3.40282347e+38
- {flt(1.17549435e-38f), "1.17549435e-38"}
- });
- TestValidDataForType(FieldDescriptor::TYPE_INT64, {
- {varint(12345), "12345"},
- {varint(kInt64Max), std::to_string(kInt64Max)},
- {varint(kInt64Min), std::to_string(kInt64Min)}
- });
- TestValidDataForType(FieldDescriptor::TYPE_UINT64, {
- {varint(12345), "12345"},
- {varint(kUint64Max), std::to_string(kUint64Max)},
- {varint(0), "0"}
- });
- TestValidDataForType(FieldDescriptor::TYPE_INT32, {
- {varint(12345), "12345"},
- {varint(kInt32Max), std::to_string(kInt32Max)},
- {varint(kInt32Min), std::to_string(kInt32Min)},
- });
- TestValidDataForType(FieldDescriptor::TYPE_UINT32, {
- {varint(12345), "12345"},
- {varint(kUint32Max), std::to_string(kUint32Max)}, // UINT32_MAX
- {varint(0), "0"}
- });
- TestValidDataForType(FieldDescriptor::TYPE_FIXED64, {
- {u64(12345), "12345"},
- {u64(kUint64Max), std::to_string(kUint64Max)},
- {u64(0), "0"}
- });
- TestValidDataForType(FieldDescriptor::TYPE_FIXED32, {
- {u32(12345), "12345"},
- {u32(kUint32Max), std::to_string(kUint32Max)}, // UINT32_MAX
- {u32(0), "0"}
- });
- TestValidDataForType(FieldDescriptor::TYPE_SFIXED64, {
- {u64(12345), "12345"},
- {u64(kInt64Max), std::to_string(kInt64Max)},
- {u64(kInt64Min), std::to_string(kInt64Min)}
- });
- TestValidDataForType(FieldDescriptor::TYPE_SFIXED32, {
- {u32(12345), "12345"},
- {u32(kInt32Max), std::to_string(kInt32Max)},
- {u32(kInt32Min), std::to_string(kInt32Min)}
- });
- TestValidDataForType(FieldDescriptor::TYPE_BOOL, {
- {varint(1), "true"},
- {varint(0), "false"},
- {varint(12345678), "true"}
- });
- TestValidDataForType(FieldDescriptor::TYPE_SINT32, {
- {zz32(12345), "12345"},
- {zz32(kInt32Max), std::to_string(kInt32Max)},
- {zz32(kInt32Min), std::to_string(kInt32Min)}
- });
- TestValidDataForType(FieldDescriptor::TYPE_SINT64, {
- {zz64(12345), "12345"},
- {zz64(kInt64Max), std::to_string(kInt64Max)},
- {zz64(kInt64Min), std::to_string(kInt64Min)}
- });
-
- // TODO(haberman):
- // TestValidDataForType(FieldDescriptor::TYPE_STRING
- // TestValidDataForType(FieldDescriptor::TYPE_GROUP
- // TestValidDataForType(FieldDescriptor::TYPE_MESSAGE
- // TestValidDataForType(FieldDescriptor::TYPE_BYTES
- // TestValidDataForType(FieldDescriptor::TYPE_ENUM
-
- RunValidJsonTest("HelloWorld", REQUIRED,
- "{\"optionalString\":\"Hello, World!\"}",
- "optional_string: 'Hello, World!'");
-
- // NOTE: The spec for JSON support is still being sorted out, these may not
- // all be correct.
- // Test field name conventions.
- RunValidJsonTest(
- "FieldNameInSnakeCase", REQUIRED,
- R"({
- "fieldname1": 1,
- "fieldName2": 2,
- "FieldName3": 3,
- "fieldName4": 4
- })",
- R"(
- fieldname1: 1
- field_name2: 2
- _field_name3: 3
- field__name4_: 4
- )");
- RunValidJsonTest(
- "FieldNameWithNumbers", REQUIRED,
- R"({
- "field0name5": 5,
- "field0Name6": 6
- })",
- R"(
- field0name5: 5
- field_0_name6: 6
- )");
- RunValidJsonTest(
- "FieldNameWithMixedCases", REQUIRED,
- R"({
- "fieldName7": 7,
- "FieldName8": 8,
- "fieldName9": 9,
- "FieldName10": 10,
- "FIELDNAME11": 11,
- "FIELDName12": 12
- })",
- R"(
- fieldName7: 7
- FieldName8: 8
- field_Name9: 9
- Field_Name10: 10
- FIELD_NAME11: 11
- FIELD_name12: 12
- )");
- RunValidJsonTest(
- "FieldNameWithDoubleUnderscores", RECOMMENDED,
- R"({
- "FieldName13": 13,
- "FieldName14": 14,
- "fieldName15": 15,
- "fieldName16": 16,
- "fieldName17": 17,
- "FieldName18": 18
- })",
- R"(
- __field_name13: 13
- __Field_name14: 14
- field__name15: 15
- field__Name16: 16
- field_name17__: 17
- Field_name18__: 18
- )");
- // Using the original proto field name in JSON is also allowed.
- RunValidJsonTest(
- "OriginalProtoFieldName", REQUIRED,
- R"({
- "fieldname1": 1,
- "field_name2": 2,
- "_field_name3": 3,
- "field__name4_": 4,
- "field0name5": 5,
- "field_0_name6": 6,
- "fieldName7": 7,
- "FieldName8": 8,
- "field_Name9": 9,
- "Field_Name10": 10,
- "FIELD_NAME11": 11,
- "FIELD_name12": 12,
- "__field_name13": 13,
- "__Field_name14": 14,
- "field__name15": 15,
- "field__Name16": 16,
- "field_name17__": 17,
- "Field_name18__": 18
- })",
- R"(
- fieldname1: 1
- field_name2: 2
- _field_name3: 3
- field__name4_: 4
- field0name5: 5
- field_0_name6: 6
- fieldName7: 7
- FieldName8: 8
- field_Name9: 9
- Field_Name10: 10
- FIELD_NAME11: 11
- FIELD_name12: 12
- __field_name13: 13
- __Field_name14: 14
- field__name15: 15
- field__Name16: 16
- field_name17__: 17
- Field_name18__: 18
- )");
- // Field names can be escaped.
- RunValidJsonTest(
- "FieldNameEscaped", REQUIRED,
- R"({"fieldn\u0061me1": 1})",
- "fieldname1: 1");
- // String ends with escape character.
- ExpectParseFailureForJson(
- "StringEndsWithEscapeChar", RECOMMENDED,
- "{\"optionalString\": \"abc\\");
- // Field names must be quoted (or it's not valid JSON).
- ExpectParseFailureForJson(
- "FieldNameNotQuoted", RECOMMENDED,
- "{fieldname1: 1}");
- // Trailing comma is not allowed (not valid JSON).
- ExpectParseFailureForJson(
- "TrailingCommaInAnObject", RECOMMENDED,
- R"({"fieldname1":1,})");
- ExpectParseFailureForJson(
- "TrailingCommaInAnObjectWithSpace", RECOMMENDED,
- R"({"fieldname1":1 ,})");
- ExpectParseFailureForJson(
- "TrailingCommaInAnObjectWithSpaceCommaSpace", RECOMMENDED,
- R"({"fieldname1":1 , })");
- ExpectParseFailureForJson(
- "TrailingCommaInAnObjectWithNewlines", RECOMMENDED,
- R"({
- "fieldname1":1,
- })");
- // JSON doesn't support comments.
- ExpectParseFailureForJson(
- "JsonWithComments", RECOMMENDED,
- R"({
- // This is a comment.
- "fieldname1": 1
- })");
- // JSON spec says whitespace doesn't matter, so try a few spacings to be sure.
- RunValidJsonTest(
- "OneLineNoSpaces", RECOMMENDED,
- "{\"optionalInt32\":1,\"optionalInt64\":2}",
- R"(
- optional_int32: 1
- optional_int64: 2
- )");
- RunValidJsonTest(
- "OneLineWithSpaces", RECOMMENDED,
- "{ \"optionalInt32\" : 1 , \"optionalInt64\" : 2 }",
- R"(
- optional_int32: 1
- optional_int64: 2
- )");
- RunValidJsonTest(
- "MultilineNoSpaces", RECOMMENDED,
- "{\n\"optionalInt32\"\n:\n1\n,\n\"optionalInt64\"\n:\n2\n}",
- R"(
- optional_int32: 1
- optional_int64: 2
- )");
- RunValidJsonTest(
- "MultilineWithSpaces", RECOMMENDED,
- "{\n \"optionalInt32\" : 1\n ,\n \"optionalInt64\" : 2\n}\n",
- R"(
- optional_int32: 1
- optional_int64: 2
- )");
- // Missing comma between key/value pairs.
- ExpectParseFailureForJson(
- "MissingCommaOneLine", RECOMMENDED,
- "{ \"optionalInt32\": 1 \"optionalInt64\": 2 }");
- ExpectParseFailureForJson(
- "MissingCommaMultiline", RECOMMENDED,
- "{\n \"optionalInt32\": 1\n \"optionalInt64\": 2\n}");
- // Duplicated field names are not allowed.
- ExpectParseFailureForJson(
- "FieldNameDuplicate", RECOMMENDED,
- R"({
- "optionalNestedMessage": {a: 1},
- "optionalNestedMessage": {}
- })");
- ExpectParseFailureForJson(
- "FieldNameDuplicateDifferentCasing1", RECOMMENDED,
- R"({
- "optional_nested_message": {a: 1},
- "optionalNestedMessage": {}
- })");
- ExpectParseFailureForJson(
- "FieldNameDuplicateDifferentCasing2", RECOMMENDED,
- R"({
- "optionalNestedMessage": {a: 1},
- "optional_nested_message": {}
- })");
- // Serializers should use lowerCamelCase by default.
- RunValidJsonTestWithValidator(
- "FieldNameInLowerCamelCase", REQUIRED,
- R"({
- "fieldname1": 1,
- "fieldName2": 2,
- "FieldName3": 3,
- "fieldName4": 4
- })",
- [](const Json::Value& value) {
- return value.isMember("fieldname1") &&
- value.isMember("fieldName2") &&
- value.isMember("FieldName3") &&
- value.isMember("fieldName4");
- });
- RunValidJsonTestWithValidator(
- "FieldNameWithNumbers", REQUIRED,
- R"({
- "field0name5": 5,
- "field0Name6": 6
- })",
- [](const Json::Value& value) {
- return value.isMember("field0name5") &&
- value.isMember("field0Name6");
- });
- RunValidJsonTestWithValidator(
- "FieldNameWithMixedCases", REQUIRED,
- R"({
- "fieldName7": 7,
- "FieldName8": 8,
- "fieldName9": 9,
- "FieldName10": 10,
- "FIELDNAME11": 11,
- "FIELDName12": 12
- })",
- [](const Json::Value& value) {
- return value.isMember("fieldName7") &&
- value.isMember("FieldName8") &&
- value.isMember("fieldName9") &&
- value.isMember("FieldName10") &&
- value.isMember("FIELDNAME11") &&
- value.isMember("FIELDName12");
- });
- RunValidJsonTestWithValidator(
- "FieldNameWithDoubleUnderscores", RECOMMENDED,
- R"({
- "FieldName13": 13,
- "FieldName14": 14,
- "fieldName15": 15,
- "fieldName16": 16,
- "fieldName17": 17,
- "FieldName18": 18
- })",
- [](const Json::Value& value) {
- return value.isMember("FieldName13") &&
- value.isMember("FieldName14") &&
- value.isMember("fieldName15") &&
- value.isMember("fieldName16") &&
- value.isMember("fieldName17") &&
- value.isMember("FieldName18");
- });
-
- // Integer fields.
- RunValidJsonTest(
- "Int32FieldMaxValue", REQUIRED,
- R"({"optionalInt32": 2147483647})",
- "optional_int32: 2147483647");
- RunValidJsonTest(
- "Int32FieldMinValue", REQUIRED,
- R"({"optionalInt32": -2147483648})",
- "optional_int32: -2147483648");
- RunValidJsonTest(
- "Uint32FieldMaxValue", REQUIRED,
- R"({"optionalUint32": 4294967295})",
- "optional_uint32: 4294967295");
- RunValidJsonTest(
- "Int64FieldMaxValue", REQUIRED,
- R"({"optionalInt64": "9223372036854775807"})",
- "optional_int64: 9223372036854775807");
- RunValidJsonTest(
- "Int64FieldMinValue", REQUIRED,
- R"({"optionalInt64": "-9223372036854775808"})",
- "optional_int64: -9223372036854775808");
- RunValidJsonTest(
- "Uint64FieldMaxValue", REQUIRED,
- R"({"optionalUint64": "18446744073709551615"})",
- "optional_uint64: 18446744073709551615");
- // While not the largest Int64, this is the largest
- // Int64 which can be exactly represented within an
- // IEEE-754 64-bit float, which is the expected level
- // of interoperability guarantee. Larger values may
- // work in some implementations, but should not be
- // relied upon.
- RunValidJsonTest(
- "Int64FieldMaxValueNotQuoted", REQUIRED,
- R"({"optionalInt64": 9223372036854774784})",
- "optional_int64: 9223372036854774784");
- RunValidJsonTest(
- "Int64FieldMinValueNotQuoted", REQUIRED,
- R"({"optionalInt64": -9223372036854775808})",
- "optional_int64: -9223372036854775808");
- // Largest interoperable Uint64; see comment above
- // for Int64FieldMaxValueNotQuoted.
- RunValidJsonTest(
- "Uint64FieldMaxValueNotQuoted", REQUIRED,
- R"({"optionalUint64": 18446744073709549568})",
- "optional_uint64: 18446744073709549568");
- // Values can be represented as JSON strings.
- RunValidJsonTest(
- "Int32FieldStringValue", REQUIRED,
- R"({"optionalInt32": "2147483647"})",
- "optional_int32: 2147483647");
- RunValidJsonTest(
- "Int32FieldStringValueEscaped", REQUIRED,
- R"({"optionalInt32": "2\u003147483647"})",
- "optional_int32: 2147483647");
-
- // Parsers reject out-of-bound integer values.
- ExpectParseFailureForJson(
- "Int32FieldTooLarge", REQUIRED,
- R"({"optionalInt32": 2147483648})");
- ExpectParseFailureForJson(
- "Int32FieldTooSmall", REQUIRED,
- R"({"optionalInt32": -2147483649})");
- ExpectParseFailureForJson(
- "Uint32FieldTooLarge", REQUIRED,
- R"({"optionalUint32": 4294967296})");
- ExpectParseFailureForJson(
- "Int64FieldTooLarge", REQUIRED,
- R"({"optionalInt64": "9223372036854775808"})");
- ExpectParseFailureForJson(
- "Int64FieldTooSmall", REQUIRED,
- R"({"optionalInt64": "-9223372036854775809"})");
- ExpectParseFailureForJson(
- "Uint64FieldTooLarge", REQUIRED,
- R"({"optionalUint64": "18446744073709551616"})");
- // Parser reject non-integer numeric values as well.
- ExpectParseFailureForJson(
- "Int32FieldNotInteger", REQUIRED,
- R"({"optionalInt32": 0.5})");
- ExpectParseFailureForJson(
- "Uint32FieldNotInteger", REQUIRED,
- R"({"optionalUint32": 0.5})");
- ExpectParseFailureForJson(
- "Int64FieldNotInteger", REQUIRED,
- R"({"optionalInt64": "0.5"})");
- ExpectParseFailureForJson(
- "Uint64FieldNotInteger", REQUIRED,
- R"({"optionalUint64": "0.5"})");
-
- // Integers but represented as float values are accepted.
- RunValidJsonTest(
- "Int32FieldFloatTrailingZero", REQUIRED,
- R"({"optionalInt32": 100000.000})",
- "optional_int32: 100000");
- RunValidJsonTest(
- "Int32FieldExponentialFormat", REQUIRED,
- R"({"optionalInt32": 1e5})",
- "optional_int32: 100000");
- RunValidJsonTest(
- "Int32FieldMaxFloatValue", REQUIRED,
- R"({"optionalInt32": 2.147483647e9})",
- "optional_int32: 2147483647");
- RunValidJsonTest(
- "Int32FieldMinFloatValue", REQUIRED,
- R"({"optionalInt32": -2.147483648e9})",
- "optional_int32: -2147483648");
- RunValidJsonTest(
- "Uint32FieldMaxFloatValue", REQUIRED,
- R"({"optionalUint32": 4.294967295e9})",
- "optional_uint32: 4294967295");
-
- // Parser reject non-numeric values.
- ExpectParseFailureForJson(
- "Int32FieldNotNumber", REQUIRED,
- R"({"optionalInt32": "3x3"})");
- ExpectParseFailureForJson(
- "Uint32FieldNotNumber", REQUIRED,
- R"({"optionalUint32": "3x3"})");
- ExpectParseFailureForJson(
- "Int64FieldNotNumber", REQUIRED,
- R"({"optionalInt64": "3x3"})");
- ExpectParseFailureForJson(
- "Uint64FieldNotNumber", REQUIRED,
- R"({"optionalUint64": "3x3"})");
- // JSON does not allow "+" on numric values.
- ExpectParseFailureForJson(
- "Int32FieldPlusSign", REQUIRED,
- R"({"optionalInt32": +1})");
- // JSON doesn't allow leading 0s.
- ExpectParseFailureForJson(
- "Int32FieldLeadingZero", REQUIRED,
- R"({"optionalInt32": 01})");
- ExpectParseFailureForJson(
- "Int32FieldNegativeWithLeadingZero", REQUIRED,
- R"({"optionalInt32": -01})");
- // String values must follow the same syntax rule. Specifically leading
- // or traling spaces are not allowed.
- ExpectParseFailureForJson(
- "Int32FieldLeadingSpace", REQUIRED,
- R"({"optionalInt32": " 1"})");
- ExpectParseFailureForJson(
- "Int32FieldTrailingSpace", REQUIRED,
- R"({"optionalInt32": "1 "})");
-
- // 64-bit values are serialized as strings.
- RunValidJsonTestWithValidator(
- "Int64FieldBeString", RECOMMENDED,
- R"({"optionalInt64": 1})",
- [](const Json::Value& value) {
- return value["optionalInt64"].type() == Json::stringValue &&
- value["optionalInt64"].asString() == "1";
- });
- RunValidJsonTestWithValidator(
- "Uint64FieldBeString", RECOMMENDED,
- R"({"optionalUint64": 1})",
- [](const Json::Value& value) {
- return value["optionalUint64"].type() == Json::stringValue &&
- value["optionalUint64"].asString() == "1";
- });
-
- // Bool fields.
- RunValidJsonTest(
- "BoolFieldTrue", REQUIRED,
- R"({"optionalBool":true})",
- "optional_bool: true");
- RunValidJsonTest(
- "BoolFieldFalse", REQUIRED,
- R"({"optionalBool":false})",
- "optional_bool: false");
-
- // Other forms are not allowed.
- ExpectParseFailureForJson(
- "BoolFieldIntegerZero", RECOMMENDED,
- R"({"optionalBool":0})");
- ExpectParseFailureForJson(
- "BoolFieldIntegerOne", RECOMMENDED,
- R"({"optionalBool":1})");
- ExpectParseFailureForJson(
- "BoolFieldCamelCaseTrue", RECOMMENDED,
- R"({"optionalBool":True})");
- ExpectParseFailureForJson(
- "BoolFieldCamelCaseFalse", RECOMMENDED,
- R"({"optionalBool":False})");
- ExpectParseFailureForJson(
- "BoolFieldAllCapitalTrue", RECOMMENDED,
- R"({"optionalBool":TRUE})");
- ExpectParseFailureForJson(
- "BoolFieldAllCapitalFalse", RECOMMENDED,
- R"({"optionalBool":FALSE})");
- ExpectParseFailureForJson(
- "BoolFieldDoubleQuotedTrue", RECOMMENDED,
- R"({"optionalBool":"true"})");
- ExpectParseFailureForJson(
- "BoolFieldDoubleQuotedFalse", RECOMMENDED,
- R"({"optionalBool":"false"})");
-
- // Float fields.
- RunValidJsonTest(
- "FloatFieldMinPositiveValue", REQUIRED,
- R"({"optionalFloat": 1.175494e-38})",
- "optional_float: 1.175494e-38");
- RunValidJsonTest(
- "FloatFieldMaxNegativeValue", REQUIRED,
- R"({"optionalFloat": -1.175494e-38})",
- "optional_float: -1.175494e-38");
- RunValidJsonTest(
- "FloatFieldMaxPositiveValue", REQUIRED,
- R"({"optionalFloat": 3.402823e+38})",
- "optional_float: 3.402823e+38");
- RunValidJsonTest(
- "FloatFieldMinNegativeValue", REQUIRED,
- R"({"optionalFloat": 3.402823e+38})",
- "optional_float: 3.402823e+38");
- // Values can be quoted.
- RunValidJsonTest(
- "FloatFieldQuotedValue", REQUIRED,
- R"({"optionalFloat": "1"})",
- "optional_float: 1");
- // Special values.
- RunValidJsonTest(
- "FloatFieldNan", REQUIRED,
- R"({"optionalFloat": "NaN"})",
- "optional_float: nan");
- RunValidJsonTest(
- "FloatFieldInfinity", REQUIRED,
- R"({"optionalFloat": "Infinity"})",
- "optional_float: inf");
- RunValidJsonTest(
- "FloatFieldNegativeInfinity", REQUIRED,
- R"({"optionalFloat": "-Infinity"})",
- "optional_float: -inf");
- // Non-cannonical Nan will be correctly normalized.
- {
- TestAllTypes message;
- // IEEE floating-point standard 32-bit quiet NaN:
- // 0111 1111 1xxx xxxx xxxx xxxx xxxx xxxx
- message.set_optional_float(
- WireFormatLite::DecodeFloat(0x7FA12345));
- RunValidJsonTestWithProtobufInput(
- "FloatFieldNormalizeQuietNan", REQUIRED, message,
- "optional_float: nan");
- // IEEE floating-point standard 64-bit signaling NaN:
- // 1111 1111 1xxx xxxx xxxx xxxx xxxx xxxx
- message.set_optional_float(
- WireFormatLite::DecodeFloat(0xFFB54321));
- RunValidJsonTestWithProtobufInput(
- "FloatFieldNormalizeSignalingNan", REQUIRED, message,
- "optional_float: nan");
- }
-
- // Special values must be quoted.
- ExpectParseFailureForJson(
- "FloatFieldNanNotQuoted", RECOMMENDED,
- R"({"optionalFloat": NaN})");
- ExpectParseFailureForJson(
- "FloatFieldInfinityNotQuoted", RECOMMENDED,
- R"({"optionalFloat": Infinity})");
- ExpectParseFailureForJson(
- "FloatFieldNegativeInfinityNotQuoted", RECOMMENDED,
- R"({"optionalFloat": -Infinity})");
- // Parsers should reject out-of-bound values.
- ExpectParseFailureForJson(
- "FloatFieldTooSmall", REQUIRED,
- R"({"optionalFloat": -3.502823e+38})");
- ExpectParseFailureForJson(
- "FloatFieldTooLarge", REQUIRED,
- R"({"optionalFloat": 3.502823e+38})");
-
- // Double fields.
- RunValidJsonTest(
- "DoubleFieldMinPositiveValue", REQUIRED,
- R"({"optionalDouble": 2.22507e-308})",
- "optional_double: 2.22507e-308");
- RunValidJsonTest(
- "DoubleFieldMaxNegativeValue", REQUIRED,
- R"({"optionalDouble": -2.22507e-308})",
- "optional_double: -2.22507e-308");
- RunValidJsonTest(
- "DoubleFieldMaxPositiveValue", REQUIRED,
- R"({"optionalDouble": 1.79769e+308})",
- "optional_double: 1.79769e+308");
- RunValidJsonTest(
- "DoubleFieldMinNegativeValue", REQUIRED,
- R"({"optionalDouble": -1.79769e+308})",
- "optional_double: -1.79769e+308");
- // Values can be quoted.
- RunValidJsonTest(
- "DoubleFieldQuotedValue", REQUIRED,
- R"({"optionalDouble": "1"})",
- "optional_double: 1");
- // Speical values.
- RunValidJsonTest(
- "DoubleFieldNan", REQUIRED,
- R"({"optionalDouble": "NaN"})",
- "optional_double: nan");
- RunValidJsonTest(
- "DoubleFieldInfinity", REQUIRED,
- R"({"optionalDouble": "Infinity"})",
- "optional_double: inf");
- RunValidJsonTest(
- "DoubleFieldNegativeInfinity", REQUIRED,
- R"({"optionalDouble": "-Infinity"})",
- "optional_double: -inf");
- // Non-cannonical Nan will be correctly normalized.
- {
- TestAllTypes message;
- message.set_optional_double(
- WireFormatLite::DecodeDouble(0x7FFA123456789ABCLL));
- RunValidJsonTestWithProtobufInput(
- "DoubleFieldNormalizeQuietNan", REQUIRED, message,
- "optional_double: nan");
- message.set_optional_double(
- WireFormatLite::DecodeDouble(0xFFFBCBA987654321LL));
- RunValidJsonTestWithProtobufInput(
- "DoubleFieldNormalizeSignalingNan", REQUIRED, message,
- "optional_double: nan");
- }
-
- // Special values must be quoted.
- ExpectParseFailureForJson(
- "DoubleFieldNanNotQuoted", RECOMMENDED,
- R"({"optionalDouble": NaN})");
- ExpectParseFailureForJson(
- "DoubleFieldInfinityNotQuoted", RECOMMENDED,
- R"({"optionalDouble": Infinity})");
- ExpectParseFailureForJson(
- "DoubleFieldNegativeInfinityNotQuoted", RECOMMENDED,
- R"({"optionalDouble": -Infinity})");
-
- // Parsers should reject out-of-bound values.
- ExpectParseFailureForJson(
- "DoubleFieldTooSmall", REQUIRED,
- R"({"optionalDouble": -1.89769e+308})");
- ExpectParseFailureForJson(
- "DoubleFieldTooLarge", REQUIRED,
- R"({"optionalDouble": +1.89769e+308})");
-
- // Enum fields.
- RunValidJsonTest(
- "EnumField", REQUIRED,
- R"({"optionalNestedEnum": "FOO"})",
- "optional_nested_enum: FOO");
- // Enum values must be represented as strings.
- ExpectParseFailureForJson(
- "EnumFieldNotQuoted", REQUIRED,
- R"({"optionalNestedEnum": FOO})");
- // Numeric values are allowed.
- RunValidJsonTest(
- "EnumFieldNumericValueZero", REQUIRED,
- R"({"optionalNestedEnum": 0})",
- "optional_nested_enum: FOO");
- RunValidJsonTest(
- "EnumFieldNumericValueNonZero", REQUIRED,
- R"({"optionalNestedEnum": 1})",
- "optional_nested_enum: BAR");
- // Unknown enum values are represented as numeric values.
- RunValidJsonTestWithValidator(
- "EnumFieldUnknownValue", REQUIRED,
- R"({"optionalNestedEnum": 123})",
- [](const Json::Value& value) {
- return value["optionalNestedEnum"].type() == Json::intValue &&
- value["optionalNestedEnum"].asInt() == 123;
- });
-
- // String fields.
- RunValidJsonTest(
- "StringField", REQUIRED,
- R"({"optionalString": "Hello world!"})",
- "optional_string: \"Hello world!\"");
- RunValidJsonTest(
- "StringFieldUnicode", REQUIRED,
- // Google in Chinese.
- R"({"optionalString": "谷歌"})",
- R"(optional_string: "谷歌")");
- RunValidJsonTest(
- "StringFieldEscape", REQUIRED,
- R"({"optionalString": "\"\\\/\b\f\n\r\t"})",
- R"(optional_string: "\"\\/\b\f\n\r\t")");
- RunValidJsonTest(
- "StringFieldUnicodeEscape", REQUIRED,
- R"({"optionalString": "\u8C37\u6B4C"})",
- R"(optional_string: "谷歌")");
- RunValidJsonTest(
- "StringFieldUnicodeEscapeWithLowercaseHexLetters", REQUIRED,
- R"({"optionalString": "\u8c37\u6b4c"})",
- R"(optional_string: "谷歌")");
- RunValidJsonTest(
- "StringFieldSurrogatePair", REQUIRED,
- // The character is an emoji: grinning face with smiling eyes. 😁
- R"({"optionalString": "\uD83D\uDE01"})",
- R"(optional_string: "\xF0\x9F\x98\x81")");
-
- // Unicode escapes must start with "\u" (lowercase u).
- ExpectParseFailureForJson(
- "StringFieldUppercaseEscapeLetter", RECOMMENDED,
- R"({"optionalString": "\U8C37\U6b4C"})");
- ExpectParseFailureForJson(
- "StringFieldInvalidEscape", RECOMMENDED,
- R"({"optionalString": "\uXXXX\u6B4C"})");
- ExpectParseFailureForJson(
- "StringFieldUnterminatedEscape", RECOMMENDED,
- R"({"optionalString": "\u8C3"})");
- ExpectParseFailureForJson(
- "StringFieldUnpairedHighSurrogate", RECOMMENDED,
- R"({"optionalString": "\uD800"})");
- ExpectParseFailureForJson(
- "StringFieldUnpairedLowSurrogate", RECOMMENDED,
- R"({"optionalString": "\uDC00"})");
- ExpectParseFailureForJson(
- "StringFieldSurrogateInWrongOrder", RECOMMENDED,
- R"({"optionalString": "\uDE01\uD83D"})");
- ExpectParseFailureForJson(
- "StringFieldNotAString", REQUIRED,
- R"({"optionalString": 12345})");
-
- // Bytes fields.
- RunValidJsonTest(
- "BytesField", REQUIRED,
- R"({"optionalBytes": "AQI="})",
- R"(optional_bytes: "\x01\x02")");
- ExpectParseFailureForJson(
- "BytesFieldInvalidBase64Characters", REQUIRED,
- R"({"optionalBytes": "-_=="})");
-
- // Message fields.
- RunValidJsonTest(
- "MessageField", REQUIRED,
- R"({"optionalNestedMessage": {"a": 1234}})",
- "optional_nested_message: {a: 1234}");
-
- // Oneof fields.
- ExpectParseFailureForJson(
- "OneofFieldDuplicate", REQUIRED,
- R"({"oneofUint32": 1, "oneofString": "test"})");
- // Ensure zero values for oneof make it out/backs.
- {
- TestAllTypes message;
- message.set_oneof_uint32(0);
- RunValidProtobufTestWithMessage(
- "OneofZeroUint32", RECOMMENDED, message, "oneof_uint32: 0");
- message.mutable_oneof_nested_message()->set_a(0);
- RunValidProtobufTestWithMessage(
- "OneofZeroMessage", RECOMMENDED, message, "oneof_nested_message: {}");
- message.set_oneof_string("");
- RunValidProtobufTestWithMessage(
- "OneofZeroString", RECOMMENDED, message, "oneof_string: \"\"");
- message.set_oneof_bytes("");
- RunValidProtobufTestWithMessage(
- "OneofZeroBytes", RECOMMENDED, message, "oneof_bytes: \"\"");
- message.set_oneof_bool(false);
- RunValidProtobufTestWithMessage(
- "OneofZeroBool", RECOMMENDED, message, "oneof_bool: false");
- message.set_oneof_uint64(0);
- RunValidProtobufTestWithMessage(
- "OneofZeroUint64", RECOMMENDED, message, "oneof_uint64: 0");
- message.set_oneof_float(0.0f);
- RunValidProtobufTestWithMessage(
- "OneofZeroFloat", RECOMMENDED, message, "oneof_float: 0");
- message.set_oneof_double(0.0);
- RunValidProtobufTestWithMessage(
- "OneofZeroDouble", RECOMMENDED, message, "oneof_double: 0");
- message.set_oneof_enum(TestAllTypes::FOO);
- RunValidProtobufTestWithMessage(
- "OneofZeroEnum", RECOMMENDED, message, "oneof_enum: FOO");
- }
- RunValidJsonTest(
- "OneofZeroUint32", RECOMMENDED,
- R"({"oneofUint32": 0})", "oneof_uint32: 0");
- RunValidJsonTest(
- "OneofZeroMessage", RECOMMENDED,
- R"({"oneofNestedMessage": {}})", "oneof_nested_message: {}");
- RunValidJsonTest(
- "OneofZeroString", RECOMMENDED,
- R"({"oneofString": ""})", "oneof_string: \"\"");
- RunValidJsonTest(
- "OneofZeroBytes", RECOMMENDED,
- R"({"oneofBytes": ""})", "oneof_bytes: \"\"");
- RunValidJsonTest(
- "OneofZeroBool", RECOMMENDED,
- R"({"oneofBool": false})", "oneof_bool: false");
- RunValidJsonTest(
- "OneofZeroUint64", RECOMMENDED,
- R"({"oneofUint64": 0})", "oneof_uint64: 0");
- RunValidJsonTest(
- "OneofZeroFloat", RECOMMENDED,
- R"({"oneofFloat": 0.0})", "oneof_float: 0");
- RunValidJsonTest(
- "OneofZeroDouble", RECOMMENDED,
- R"({"oneofDouble": 0.0})", "oneof_double: 0");
- RunValidJsonTest(
- "OneofZeroEnum", RECOMMENDED,
- R"({"oneofEnum":"FOO"})", "oneof_enum: FOO");
-
- // Repeated fields.
- RunValidJsonTest(
- "PrimitiveRepeatedField", REQUIRED,
- R"({"repeatedInt32": [1, 2, 3, 4]})",
- "repeated_int32: [1, 2, 3, 4]");
- RunValidJsonTest(
- "EnumRepeatedField", REQUIRED,
- R"({"repeatedNestedEnum": ["FOO", "BAR", "BAZ"]})",
- "repeated_nested_enum: [FOO, BAR, BAZ]");
- RunValidJsonTest(
- "StringRepeatedField", REQUIRED,
- R"({"repeatedString": ["Hello", "world"]})",
- R"(repeated_string: ["Hello", "world"])");
- RunValidJsonTest(
- "BytesRepeatedField", REQUIRED,
- R"({"repeatedBytes": ["AAEC", "AQI="]})",
- R"(repeated_bytes: ["\x00\x01\x02", "\x01\x02"])");
- RunValidJsonTest(
- "MessageRepeatedField", REQUIRED,
- R"({"repeatedNestedMessage": [{"a": 1234}, {"a": 5678}]})",
- "repeated_nested_message: {a: 1234}"
- "repeated_nested_message: {a: 5678}");
-
- // Repeated field elements are of incorrect type.
- ExpectParseFailureForJson(
- "RepeatedFieldWrongElementTypeExpectingIntegersGotBool", REQUIRED,
- R"({"repeatedInt32": [1, false, 3, 4]})");
- ExpectParseFailureForJson(
- "RepeatedFieldWrongElementTypeExpectingIntegersGotString", REQUIRED,
- R"({"repeatedInt32": [1, 2, "name", 4]})");
- ExpectParseFailureForJson(
- "RepeatedFieldWrongElementTypeExpectingIntegersGotMessage", REQUIRED,
- R"({"repeatedInt32": [1, 2, 3, {"a": 4}]})");
- ExpectParseFailureForJson(
- "RepeatedFieldWrongElementTypeExpectingStringsGotInt", REQUIRED,
- R"({"repeatedString": ["1", 2, "3", "4"]})");
- ExpectParseFailureForJson(
- "RepeatedFieldWrongElementTypeExpectingStringsGotBool", REQUIRED,
- R"({"repeatedString": ["1", "2", false, "4"]})");
- ExpectParseFailureForJson(
- "RepeatedFieldWrongElementTypeExpectingStringsGotMessage", REQUIRED,
- R"({"repeatedString": ["1", 2, "3", {"a": 4}]})");
- ExpectParseFailureForJson(
- "RepeatedFieldWrongElementTypeExpectingMessagesGotInt", REQUIRED,
- R"({"repeatedNestedMessage": [{"a": 1}, 2]})");
- ExpectParseFailureForJson(
- "RepeatedFieldWrongElementTypeExpectingMessagesGotBool", REQUIRED,
- R"({"repeatedNestedMessage": [{"a": 1}, false]})");
- ExpectParseFailureForJson(
- "RepeatedFieldWrongElementTypeExpectingMessagesGotString", REQUIRED,
- R"({"repeatedNestedMessage": [{"a": 1}, "2"]})");
- // Trailing comma in the repeated field is not allowed.
- ExpectParseFailureForJson(
- "RepeatedFieldTrailingComma", RECOMMENDED,
- R"({"repeatedInt32": [1, 2, 3, 4,]})");
- ExpectParseFailureForJson(
- "RepeatedFieldTrailingCommaWithSpace", RECOMMENDED,
- "{\"repeatedInt32\": [1, 2, 3, 4 ,]}");
- ExpectParseFailureForJson(
- "RepeatedFieldTrailingCommaWithSpaceCommaSpace", RECOMMENDED,
- "{\"repeatedInt32\": [1, 2, 3, 4 , ]}");
- ExpectParseFailureForJson(
- "RepeatedFieldTrailingCommaWithNewlines", RECOMMENDED,
- "{\"repeatedInt32\": [\n 1,\n 2,\n 3,\n 4,\n]}");
-
- // Map fields.
- RunValidJsonTest(
- "Int32MapField", REQUIRED,
- R"({"mapInt32Int32": {"1": 2, "3": 4}})",
- "map_int32_int32: {key: 1 value: 2}"
- "map_int32_int32: {key: 3 value: 4}");
- ExpectParseFailureForJson(
- "Int32MapFieldKeyNotQuoted", RECOMMENDED,
- R"({"mapInt32Int32": {1: 2, 3: 4}})");
- RunValidJsonTest(
- "Uint32MapField", REQUIRED,
- R"({"mapUint32Uint32": {"1": 2, "3": 4}})",
- "map_uint32_uint32: {key: 1 value: 2}"
- "map_uint32_uint32: {key: 3 value: 4}");
- ExpectParseFailureForJson(
- "Uint32MapFieldKeyNotQuoted", RECOMMENDED,
- R"({"mapUint32Uint32": {1: 2, 3: 4}})");
- RunValidJsonTest(
- "Int64MapField", REQUIRED,
- R"({"mapInt64Int64": {"1": 2, "3": 4}})",
- "map_int64_int64: {key: 1 value: 2}"
- "map_int64_int64: {key: 3 value: 4}");
- ExpectParseFailureForJson(
- "Int64MapFieldKeyNotQuoted", RECOMMENDED,
- R"({"mapInt64Int64": {1: 2, 3: 4}})");
- RunValidJsonTest(
- "Uint64MapField", REQUIRED,
- R"({"mapUint64Uint64": {"1": 2, "3": 4}})",
- "map_uint64_uint64: {key: 1 value: 2}"
- "map_uint64_uint64: {key: 3 value: 4}");
- ExpectParseFailureForJson(
- "Uint64MapFieldKeyNotQuoted", RECOMMENDED,
- R"({"mapUint64Uint64": {1: 2, 3: 4}})");
- RunValidJsonTest(
- "BoolMapField", REQUIRED,
- R"({"mapBoolBool": {"true": true, "false": false}})",
- "map_bool_bool: {key: true value: true}"
- "map_bool_bool: {key: false value: false}");
- ExpectParseFailureForJson(
- "BoolMapFieldKeyNotQuoted", RECOMMENDED,
- R"({"mapBoolBool": {true: true, false: false}})");
- RunValidJsonTest(
- "MessageMapField", REQUIRED,
- R"({
- "mapStringNestedMessage": {
- "hello": {"a": 1234},
- "world": {"a": 5678}
- }
- })",
- R"(
- map_string_nested_message: {
- key: "hello"
- value: {a: 1234}
- }
- map_string_nested_message: {
- key: "world"
- value: {a: 5678}
- }
- )");
- // Since Map keys are represented as JSON strings, escaping should be allowed.
- RunValidJsonTest(
- "Int32MapEscapedKey", REQUIRED,
- R"({"mapInt32Int32": {"\u0031": 2}})",
- "map_int32_int32: {key: 1 value: 2}");
- RunValidJsonTest(
- "Int64MapEscapedKey", REQUIRED,
- R"({"mapInt64Int64": {"\u0031": 2}})",
- "map_int64_int64: {key: 1 value: 2}");
- RunValidJsonTest(
- "BoolMapEscapedKey", REQUIRED,
- R"({"mapBoolBool": {"tr\u0075e": true}})",
- "map_bool_bool: {key: true value: true}");
-
- // "null" is accepted for all fields types.
- RunValidJsonTest(
- "AllFieldAcceptNull", REQUIRED,
- R"({
- "optionalInt32": null,
- "optionalInt64": null,
- "optionalUint32": null,
- "optionalUint64": null,
- "optionalBool": null,
- "optionalString": null,
- "optionalBytes": null,
- "optionalNestedEnum": null,
- "optionalNestedMessage": null,
- "repeatedInt32": null,
- "repeatedInt64": null,
- "repeatedUint32": null,
- "repeatedUint64": null,
- "repeatedBool": null,
- "repeatedString": null,
- "repeatedBytes": null,
- "repeatedNestedEnum": null,
- "repeatedNestedMessage": null,
- "mapInt32Int32": null,
- "mapBoolBool": null,
- "mapStringNestedMessage": null
- })",
- "");
-
- // Repeated field elements cannot be null.
- ExpectParseFailureForJson(
- "RepeatedFieldPrimitiveElementIsNull", RECOMMENDED,
- R"({"repeatedInt32": [1, null, 2]})");
- ExpectParseFailureForJson(
- "RepeatedFieldMessageElementIsNull", RECOMMENDED,
- R"({"repeatedNestedMessage": [{"a":1}, null, {"a":2}]})");
- // Map field keys cannot be null.
- ExpectParseFailureForJson(
- "MapFieldKeyIsNull", RECOMMENDED,
- R"({"mapInt32Int32": {null: 1}})");
- // Map field values cannot be null.
- ExpectParseFailureForJson(
- "MapFieldValueIsNull", RECOMMENDED,
- R"({"mapInt32Int32": {"0": null}})");
-
- // http://www.rfc-editor.org/rfc/rfc7159.txt says strings have to use double
- // quotes.
- ExpectParseFailureForJson(
- "StringFieldSingleQuoteKey", RECOMMENDED,
- R"({'optionalString': "Hello world!"})");
- ExpectParseFailureForJson(
- "StringFieldSingleQuoteValue", RECOMMENDED,
- R"({"optionalString": 'Hello world!'})");
- ExpectParseFailureForJson(
- "StringFieldSingleQuoteBoth", RECOMMENDED,
- R"({'optionalString': 'Hello world!'})");
-
- // Wrapper types.
- RunValidJsonTest(
- "OptionalBoolWrapper", REQUIRED,
- R"({"optionalBoolWrapper": false})",
- "optional_bool_wrapper: {value: false}");
- RunValidJsonTest(
- "OptionalInt32Wrapper", REQUIRED,
- R"({"optionalInt32Wrapper": 0})",
- "optional_int32_wrapper: {value: 0}");
- RunValidJsonTest(
- "OptionalUint32Wrapper", REQUIRED,
- R"({"optionalUint32Wrapper": 0})",
- "optional_uint32_wrapper: {value: 0}");
- RunValidJsonTest(
- "OptionalInt64Wrapper", REQUIRED,
- R"({"optionalInt64Wrapper": 0})",
- "optional_int64_wrapper: {value: 0}");
- RunValidJsonTest(
- "OptionalUint64Wrapper", REQUIRED,
- R"({"optionalUint64Wrapper": 0})",
- "optional_uint64_wrapper: {value: 0}");
- RunValidJsonTest(
- "OptionalFloatWrapper", REQUIRED,
- R"({"optionalFloatWrapper": 0})",
- "optional_float_wrapper: {value: 0}");
- RunValidJsonTest(
- "OptionalDoubleWrapper", REQUIRED,
- R"({"optionalDoubleWrapper": 0})",
- "optional_double_wrapper: {value: 0}");
- RunValidJsonTest(
- "OptionalStringWrapper", REQUIRED,
- R"({"optionalStringWrapper": ""})",
- R"(optional_string_wrapper: {value: ""})");
- RunValidJsonTest(
- "OptionalBytesWrapper", REQUIRED,
- R"({"optionalBytesWrapper": ""})",
- R"(optional_bytes_wrapper: {value: ""})");
- RunValidJsonTest(
- "OptionalWrapperTypesWithNonDefaultValue", REQUIRED,
- R"({
- "optionalBoolWrapper": true,
- "optionalInt32Wrapper": 1,
- "optionalUint32Wrapper": 1,
- "optionalInt64Wrapper": "1",
- "optionalUint64Wrapper": "1",
- "optionalFloatWrapper": 1,
- "optionalDoubleWrapper": 1,
- "optionalStringWrapper": "1",
- "optionalBytesWrapper": "AQI="
- })",
- R"(
- optional_bool_wrapper: {value: true}
- optional_int32_wrapper: {value: 1}
- optional_uint32_wrapper: {value: 1}
- optional_int64_wrapper: {value: 1}
- optional_uint64_wrapper: {value: 1}
- optional_float_wrapper: {value: 1}
- optional_double_wrapper: {value: 1}
- optional_string_wrapper: {value: "1"}
- optional_bytes_wrapper: {value: "\x01\x02"}
- )");
- RunValidJsonTest(
- "RepeatedBoolWrapper", REQUIRED,
- R"({"repeatedBoolWrapper": [true, false]})",
- "repeated_bool_wrapper: {value: true}"
- "repeated_bool_wrapper: {value: false}");
- RunValidJsonTest(
- "RepeatedInt32Wrapper", REQUIRED,
- R"({"repeatedInt32Wrapper": [0, 1]})",
- "repeated_int32_wrapper: {value: 0}"
- "repeated_int32_wrapper: {value: 1}");
- RunValidJsonTest(
- "RepeatedUint32Wrapper", REQUIRED,
- R"({"repeatedUint32Wrapper": [0, 1]})",
- "repeated_uint32_wrapper: {value: 0}"
- "repeated_uint32_wrapper: {value: 1}");
- RunValidJsonTest(
- "RepeatedInt64Wrapper", REQUIRED,
- R"({"repeatedInt64Wrapper": [0, 1]})",
- "repeated_int64_wrapper: {value: 0}"
- "repeated_int64_wrapper: {value: 1}");
- RunValidJsonTest(
- "RepeatedUint64Wrapper", REQUIRED,
- R"({"repeatedUint64Wrapper": [0, 1]})",
- "repeated_uint64_wrapper: {value: 0}"
- "repeated_uint64_wrapper: {value: 1}");
- RunValidJsonTest(
- "RepeatedFloatWrapper", REQUIRED,
- R"({"repeatedFloatWrapper": [0, 1]})",
- "repeated_float_wrapper: {value: 0}"
- "repeated_float_wrapper: {value: 1}");
- RunValidJsonTest(
- "RepeatedDoubleWrapper", REQUIRED,
- R"({"repeatedDoubleWrapper": [0, 1]})",
- "repeated_double_wrapper: {value: 0}"
- "repeated_double_wrapper: {value: 1}");
- RunValidJsonTest(
- "RepeatedStringWrapper", REQUIRED,
- R"({"repeatedStringWrapper": ["", "AQI="]})",
- R"(
- repeated_string_wrapper: {value: ""}
- repeated_string_wrapper: {value: "AQI="}
- )");
- RunValidJsonTest(
- "RepeatedBytesWrapper", REQUIRED,
- R"({"repeatedBytesWrapper": ["", "AQI="]})",
- R"(
- repeated_bytes_wrapper: {value: ""}
- repeated_bytes_wrapper: {value: "\x01\x02"}
- )");
- RunValidJsonTest(
- "WrapperTypesWithNullValue", REQUIRED,
- R"({
- "optionalBoolWrapper": null,
- "optionalInt32Wrapper": null,
- "optionalUint32Wrapper": null,
- "optionalInt64Wrapper": null,
- "optionalUint64Wrapper": null,
- "optionalFloatWrapper": null,
- "optionalDoubleWrapper": null,
- "optionalStringWrapper": null,
- "optionalBytesWrapper": null,
- "repeatedBoolWrapper": null,
- "repeatedInt32Wrapper": null,
- "repeatedUint32Wrapper": null,
- "repeatedInt64Wrapper": null,
- "repeatedUint64Wrapper": null,
- "repeatedFloatWrapper": null,
- "repeatedDoubleWrapper": null,
- "repeatedStringWrapper": null,
- "repeatedBytesWrapper": null
- })",
- "");
-
- // Duration
- RunValidJsonTest(
- "DurationMinValue", REQUIRED,
- R"({"optionalDuration": "-315576000000.999999999s"})",
- "optional_duration: {seconds: -315576000000 nanos: -999999999}");
- RunValidJsonTest(
- "DurationMaxValue", REQUIRED,
- R"({"optionalDuration": "315576000000.999999999s"})",
- "optional_duration: {seconds: 315576000000 nanos: 999999999}");
- RunValidJsonTest(
- "DurationRepeatedValue", REQUIRED,
- R"({"repeatedDuration": ["1.5s", "-1.5s"]})",
- "repeated_duration: {seconds: 1 nanos: 500000000}"
- "repeated_duration: {seconds: -1 nanos: -500000000}");
-
- ExpectParseFailureForJson(
- "DurationMissingS", REQUIRED,
- R"({"optionalDuration": "1"})");
- ExpectParseFailureForJson(
- "DurationJsonInputTooSmall", REQUIRED,
- R"({"optionalDuration": "-315576000001.000000000s"})");
- ExpectParseFailureForJson(
- "DurationJsonInputTooLarge", REQUIRED,
- R"({"optionalDuration": "315576000001.000000000s"})");
- ExpectSerializeFailureForJson(
- "DurationProtoInputTooSmall", REQUIRED,
- "optional_duration: {seconds: -315576000001 nanos: 0}");
- ExpectSerializeFailureForJson(
- "DurationProtoInputTooLarge", REQUIRED,
- "optional_duration: {seconds: 315576000001 nanos: 0}");
-
- RunValidJsonTestWithValidator(
- "DurationHasZeroFractionalDigit", RECOMMENDED,
- R"({"optionalDuration": "1.000000000s"})",
- [](const Json::Value& value) {
- return value["optionalDuration"].asString() == "1s";
- });
- RunValidJsonTestWithValidator(
- "DurationHas3FractionalDigits", RECOMMENDED,
- R"({"optionalDuration": "1.010000000s"})",
- [](const Json::Value& value) {
- return value["optionalDuration"].asString() == "1.010s";
- });
- RunValidJsonTestWithValidator(
- "DurationHas6FractionalDigits", RECOMMENDED,
- R"({"optionalDuration": "1.000010000s"})",
- [](const Json::Value& value) {
- return value["optionalDuration"].asString() == "1.000010s";
- });
- RunValidJsonTestWithValidator(
- "DurationHas9FractionalDigits", RECOMMENDED,
- R"({"optionalDuration": "1.000000010s"})",
- [](const Json::Value& value) {
- return value["optionalDuration"].asString() == "1.000000010s";
- });
-
- // Timestamp
- RunValidJsonTest(
- "TimestampMinValue", REQUIRED,
- R"({"optionalTimestamp": "0001-01-01T00:00:00Z"})",
- "optional_timestamp: {seconds: -62135596800}");
- RunValidJsonTest(
- "TimestampMaxValue", REQUIRED,
- R"({"optionalTimestamp": "9999-12-31T23:59:59.999999999Z"})",
- "optional_timestamp: {seconds: 253402300799 nanos: 999999999}");
- RunValidJsonTest(
- "TimestampRepeatedValue", REQUIRED,
- R"({
- "repeatedTimestamp": [
- "0001-01-01T00:00:00Z",
- "9999-12-31T23:59:59.999999999Z"
- ]
- })",
- "repeated_timestamp: {seconds: -62135596800}"
- "repeated_timestamp: {seconds: 253402300799 nanos: 999999999}");
- RunValidJsonTest(
- "TimestampWithPositiveOffset", REQUIRED,
- R"({"optionalTimestamp": "1970-01-01T08:00:00+08:00"})",
- "optional_timestamp: {seconds: 0}");
- RunValidJsonTest(
- "TimestampWithNegativeOffset", REQUIRED,
- R"({"optionalTimestamp": "1969-12-31T16:00:00-08:00"})",
- "optional_timestamp: {seconds: 0}");
-
- ExpectParseFailureForJson(
- "TimestampJsonInputTooSmall", REQUIRED,
- R"({"optionalTimestamp": "0000-01-01T00:00:00Z"})");
- ExpectParseFailureForJson(
- "TimestampJsonInputTooLarge", REQUIRED,
- R"({"optionalTimestamp": "10000-01-01T00:00:00Z"})");
- ExpectParseFailureForJson(
- "TimestampJsonInputMissingZ", REQUIRED,
- R"({"optionalTimestamp": "0001-01-01T00:00:00"})");
- ExpectParseFailureForJson(
- "TimestampJsonInputMissingT", REQUIRED,
- R"({"optionalTimestamp": "0001-01-01 00:00:00Z"})");
- ExpectParseFailureForJson(
- "TimestampJsonInputLowercaseZ", REQUIRED,
- R"({"optionalTimestamp": "0001-01-01T00:00:00z"})");
- ExpectParseFailureForJson(
- "TimestampJsonInputLowercaseT", REQUIRED,
- R"({"optionalTimestamp": "0001-01-01t00:00:00Z"})");
- ExpectSerializeFailureForJson(
- "TimestampProtoInputTooSmall", REQUIRED,
- "optional_timestamp: {seconds: -62135596801}");
- ExpectSerializeFailureForJson(
- "TimestampProtoInputTooLarge", REQUIRED,
- "optional_timestamp: {seconds: 253402300800}");
- RunValidJsonTestWithValidator(
- "TimestampZeroNormalized", RECOMMENDED,
- R"({"optionalTimestamp": "1969-12-31T16:00:00-08:00"})",
- [](const Json::Value& value) {
- return value["optionalTimestamp"].asString() ==
- "1970-01-01T00:00:00Z";
- });
- RunValidJsonTestWithValidator(
- "TimestampHasZeroFractionalDigit", RECOMMENDED,
- R"({"optionalTimestamp": "1970-01-01T00:00:00.000000000Z"})",
- [](const Json::Value& value) {
- return value["optionalTimestamp"].asString() ==
- "1970-01-01T00:00:00Z";
- });
- RunValidJsonTestWithValidator(
- "TimestampHas3FractionalDigits", RECOMMENDED,
- R"({"optionalTimestamp": "1970-01-01T00:00:00.010000000Z"})",
- [](const Json::Value& value) {
- return value["optionalTimestamp"].asString() ==
- "1970-01-01T00:00:00.010Z";
- });
- RunValidJsonTestWithValidator(
- "TimestampHas6FractionalDigits", RECOMMENDED,
- R"({"optionalTimestamp": "1970-01-01T00:00:00.000010000Z"})",
- [](const Json::Value& value) {
- return value["optionalTimestamp"].asString() ==
- "1970-01-01T00:00:00.000010Z";
- });
- RunValidJsonTestWithValidator(
- "TimestampHas9FractionalDigits", RECOMMENDED,
- R"({"optionalTimestamp": "1970-01-01T00:00:00.000000010Z"})",
- [](const Json::Value& value) {
- return value["optionalTimestamp"].asString() ==
- "1970-01-01T00:00:00.000000010Z";
- });
-
- // FieldMask
- RunValidJsonTest(
- "FieldMask", REQUIRED,
- R"({"optionalFieldMask": "foo,barBaz"})",
- R"(optional_field_mask: {paths: "foo" paths: "bar_baz"})");
- ExpectParseFailureForJson(
- "FieldMaskInvalidCharacter", RECOMMENDED,
- R"({"optionalFieldMask": "foo,bar_bar"})");
- ExpectSerializeFailureForJson(
- "FieldMaskPathsDontRoundTrip", RECOMMENDED,
- R"(optional_field_mask: {paths: "fooBar"})");
- ExpectSerializeFailureForJson(
- "FieldMaskNumbersDontRoundTrip", RECOMMENDED,
- R"(optional_field_mask: {paths: "foo_3_bar"})");
- ExpectSerializeFailureForJson(
- "FieldMaskTooManyUnderscore", RECOMMENDED,
- R"(optional_field_mask: {paths: "foo__bar"})");
-
- // Struct
- RunValidJsonTest(
- "Struct", REQUIRED,
- R"({
- "optionalStruct": {
- "nullValue": null,
- "intValue": 1234,
- "boolValue": true,
- "doubleValue": 1234.5678,
- "stringValue": "Hello world!",
- "listValue": [1234, "5678"],
- "objectValue": {
- "value": 0
- }
- }
- })",
- R"(
- optional_struct: {
- fields: {
- key: "nullValue"
- value: {null_value: NULL_VALUE}
- }
- fields: {
- key: "intValue"
- value: {number_value: 1234}
- }
- fields: {
- key: "boolValue"
- value: {bool_value: true}
- }
- fields: {
- key: "doubleValue"
- value: {number_value: 1234.5678}
- }
- fields: {
- key: "stringValue"
- value: {string_value: "Hello world!"}
- }
- fields: {
- key: "listValue"
- value: {
- list_value: {
- values: {
- number_value: 1234
- }
- values: {
- string_value: "5678"
- }
- }
- }
- }
- fields: {
- key: "objectValue"
- value: {
- struct_value: {
- fields: {
- key: "value"
- value: {
- number_value: 0
- }
- }
- }
- }
- }
- }
- )");
- // Value
- RunValidJsonTest(
- "ValueAcceptInteger", REQUIRED,
- R"({"optionalValue": 1})",
- "optional_value: { number_value: 1}");
- RunValidJsonTest(
- "ValueAcceptFloat", REQUIRED,
- R"({"optionalValue": 1.5})",
- "optional_value: { number_value: 1.5}");
- RunValidJsonTest(
- "ValueAcceptBool", REQUIRED,
- R"({"optionalValue": false})",
- "optional_value: { bool_value: false}");
- RunValidJsonTest(
- "ValueAcceptNull", REQUIRED,
- R"({"optionalValue": null})",
- "optional_value: { null_value: NULL_VALUE}");
- RunValidJsonTest(
- "ValueAcceptString", REQUIRED,
- R"({"optionalValue": "hello"})",
- R"(optional_value: { string_value: "hello"})");
- RunValidJsonTest(
- "ValueAcceptList", REQUIRED,
- R"({"optionalValue": [0, "hello"]})",
- R"(
- optional_value: {
- list_value: {
- values: {
- number_value: 0
- }
- values: {
- string_value: "hello"
- }
- }
- }
- )");
- RunValidJsonTest(
- "ValueAcceptObject", REQUIRED,
- R"({"optionalValue": {"value": 1}})",
- R"(
- optional_value: {
- struct_value: {
- fields: {
- key: "value"
- value: {
- number_value: 1
- }
- }
- }
- }
- )");
-
- // Any
- RunValidJsonTest(
- "Any", REQUIRED,
- R"({
- "optionalAny": {
- "@type": "type.googleapis.com/protobuf_test_messages.proto3.TestAllTypes",
- "optionalInt32": 12345
- }
- })",
- R"(
- optional_any: {
- [type.googleapis.com/protobuf_test_messages.proto3.TestAllTypes] {
- optional_int32: 12345
- }
- }
- )");
- RunValidJsonTest(
- "AnyNested", REQUIRED,
- R"({
- "optionalAny": {
- "@type": "type.googleapis.com/google.protobuf.Any",
- "value": {
- "@type": "type.googleapis.com/protobuf_test_messages.proto3.TestAllTypes",
- "optionalInt32": 12345
- }
- }
- })",
- R"(
- optional_any: {
- [type.googleapis.com/google.protobuf.Any] {
- [type.googleapis.com/protobuf_test_messages.proto3.TestAllTypes] {
- optional_int32: 12345
- }
- }
- }
- )");
- // The special "@type" tag is not required to appear first.
- RunValidJsonTest(
- "AnyUnorderedTypeTag", REQUIRED,
- R"({
- "optionalAny": {
- "optionalInt32": 12345,
- "@type": "type.googleapis.com/protobuf_test_messages.proto3.TestAllTypes"
- }
- })",
- R"(
- optional_any: {
- [type.googleapis.com/protobuf_test_messages.proto3.TestAllTypes] {
- optional_int32: 12345
- }
- }
- )");
- // Well-known types in Any.
- RunValidJsonTest(
- "AnyWithInt32ValueWrapper", REQUIRED,
- R"({
- "optionalAny": {
- "@type": "type.googleapis.com/google.protobuf.Int32Value",
- "value": 12345
- }
- })",
- R"(
- optional_any: {
- [type.googleapis.com/google.protobuf.Int32Value] {
- value: 12345
- }
- }
- )");
- RunValidJsonTest(
- "AnyWithDuration", REQUIRED,
- R"({
- "optionalAny": {
- "@type": "type.googleapis.com/google.protobuf.Duration",
- "value": "1.5s"
- }
- })",
- R"(
- optional_any: {
- [type.googleapis.com/google.protobuf.Duration] {
- seconds: 1
- nanos: 500000000
- }
- }
- )");
- RunValidJsonTest(
- "AnyWithTimestamp", REQUIRED,
- R"({
- "optionalAny": {
- "@type": "type.googleapis.com/google.protobuf.Timestamp",
- "value": "1970-01-01T00:00:00Z"
- }
- })",
- R"(
- optional_any: {
- [type.googleapis.com/google.protobuf.Timestamp] {
- seconds: 0
- nanos: 0
- }
- }
- )");
- RunValidJsonTest(
- "AnyWithFieldMask", REQUIRED,
- R"({
- "optionalAny": {
- "@type": "type.googleapis.com/google.protobuf.FieldMask",
- "value": "foo,barBaz"
- }
- })",
- R"(
- optional_any: {
- [type.googleapis.com/google.protobuf.FieldMask] {
- paths: ["foo", "bar_baz"]
- }
- }
- )");
- RunValidJsonTest(
- "AnyWithStruct", REQUIRED,
- R"({
- "optionalAny": {
- "@type": "type.googleapis.com/google.protobuf.Struct",
- "value": {
- "foo": 1
- }
- }
- })",
- R"(
- optional_any: {
- [type.googleapis.com/google.protobuf.Struct] {
- fields: {
- key: "foo"
- value: {
- number_value: 1
- }
- }
- }
- }
- )");
- RunValidJsonTest(
- "AnyWithValueForJsonObject", REQUIRED,
- R"({
- "optionalAny": {
- "@type": "type.googleapis.com/google.protobuf.Value",
- "value": {
- "foo": 1
- }
- }
- })",
- R"(
- optional_any: {
- [type.googleapis.com/google.protobuf.Value] {
- struct_value: {
- fields: {
- key: "foo"
- value: {
- number_value: 1
- }
- }
- }
- }
- }
- )");
- RunValidJsonTest(
- "AnyWithValueForInteger", REQUIRED,
- R"({
- "optionalAny": {
- "@type": "type.googleapis.com/google.protobuf.Value",
- "value": 1
- }
- })",
- R"(
- optional_any: {
- [type.googleapis.com/google.protobuf.Value] {
- number_value: 1
- }
- }
- )");
-
- bool ok = true;
- if (!CheckSetEmpty(expected_to_fail_, "nonexistent_tests.txt",
- "These tests were listed in the failure list, but they "
- "don't exist. Remove them from the failure list by "
- "running:\n"
- " ./update_failure_list.py " + failure_list_filename_ +
- " --remove nonexistent_tests.txt")) {
- ok = false;
- }
- if (!CheckSetEmpty(unexpected_failing_tests_, "failing_tests.txt",
- "These tests failed. If they can't be fixed right now, "
- "you can add them to the failure list so the overall "
- "suite can succeed. Add them to the failure list by "
- "running:\n"
- " ./update_failure_list.py " + failure_list_filename_ +
- " --add failing_tests.txt")) {
- ok = false;
- }
- if (!CheckSetEmpty(unexpected_succeeding_tests_, "succeeding_tests.txt",
- "These tests succeeded, even though they were listed in "
- "the failure list. Remove them from the failure list "
- "by running:\n"
- " ./update_failure_list.py " + failure_list_filename_ +
- " --remove succeeding_tests.txt")) {
- ok = false;
- }
-
- if (verbose_) {
- CheckSetEmpty(skipped_, "",
- "These tests were skipped (probably because support for some "
- "features is not implemented)");
- }
-
- StringAppendF(&output_,
- "CONFORMANCE SUITE %s: %d successes, %d skipped, "
- "%d expected failures, %d unexpected failures.\n",
- ok ? "PASSED" : "FAILED", successes_, skipped_.size(),
- expected_failures_, unexpected_failing_tests_.size());
- StringAppendF(&output_, "\n");
-
- output->assign(output_);
-
- return ok;
-}
-
-} // namespace protobuf
-} // namespace google
diff --git a/third_party/protobuf/3.2.0/conformance/conformance_test.h b/third_party/protobuf/3.2.0/conformance/conformance_test.h
deleted file mode 100644
index 5f05a25bcb..0000000000
--- a/third_party/protobuf/3.2.0/conformance/conformance_test.h
+++ /dev/null
@@ -1,242 +0,0 @@
-// 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.
-
-
-// This file defines a protocol for running the conformance test suite
-// in-process. In other words, the suite itself will run in the same process as
-// the code under test.
-//
-// For pros and cons of this approach, please see conformance.proto.
-
-#ifndef CONFORMANCE_CONFORMANCE_TEST_H
-#define CONFORMANCE_CONFORMANCE_TEST_H
-
-#include <functional>
-#include <string>
-#include <google/protobuf/stubs/common.h>
-#include <google/protobuf/util/type_resolver.h>
-#include <google/protobuf/wire_format_lite.h>
-
-#include "third_party/jsoncpp/json.h"
-
-namespace conformance {
-class ConformanceRequest;
-class ConformanceResponse;
-} // namespace conformance
-
-namespace protobuf_test_messages {
-namespace proto3 {
-class TestAllTypes;
-} // namespace proto3
-} // namespace protobuf_test_messages
-
-namespace google {
-namespace protobuf {
-
-class ConformanceTestRunner {
- public:
- virtual ~ConformanceTestRunner() {}
-
- // Call to run a single conformance test.
- //
- // "input" is a serialized conformance.ConformanceRequest.
- // "output" should be set to a serialized conformance.ConformanceResponse.
- //
- // If there is any error in running the test itself, set "runtime_error" in
- // the response.
- virtual void RunTest(const std::string& test_name,
- const std::string& input,
- std::string* output) = 0;
-};
-
-// Class representing the test suite itself. To run it, implement your own
-// class derived from ConformanceTestRunner and then write code like:
-//
-// class MyConformanceTestRunner : public ConformanceTestRunner {
-// public:
-// virtual void RunTest(...) {
-// // INSERT YOUR FRAMEWORK-SPECIFIC CODE HERE.
-// }
-// };
-//
-// int main() {
-// MyConformanceTestRunner runner;
-// google::protobuf::ConformanceTestSuite suite;
-//
-// std::string output;
-// suite.RunSuite(&runner, &output);
-// }
-//
-class ConformanceTestSuite {
- public:
- ConformanceTestSuite() : verbose_(false), enforce_recommended_(false) {}
-
- void SetVerbose(bool verbose) { verbose_ = verbose; }
-
- // Sets the list of tests that are expected to fail when RunSuite() is called.
- // RunSuite() will fail unless the set of failing tests is exactly the same
- // as this list.
- //
- // The filename here is *only* used to create/format useful error messages for
- // how to update the failure list. We do NOT read this file at all.
- void SetFailureList(const std::string& filename,
- const std::vector<std::string>& failure_list);
-
- // Whether to require the testee to pass RECOMMENDED tests. By default failing
- // a RECOMMENDED test case will not fail the entire suite but will only
- // generated a warning. If this flag is set to true, RECOMMENDED tests will
- // be treated the same way as REQUIRED tests and failing a RECOMMENDED test
- // case will cause the entire test suite to fail as well. An implementation
- // can enable this if it wants to be strictly conforming to protobuf spec.
- // See the comments about ConformanceLevel below to learn more about the
- // difference between REQUIRED and RECOMMENDED test cases.
- void SetEnforceRecommended(bool value) {
- enforce_recommended_ = value;
- }
-
- // Run all the conformance tests against the given test runner.
- // Test output will be stored in "output".
- //
- // Returns true if the set of failing tests was exactly the same as the
- // failure list. If SetFailureList() was not called, returns true if all
- // tests passed.
- bool RunSuite(ConformanceTestRunner* runner, std::string* output);
-
- private:
- // Test cases are classified into a few categories:
- // REQUIRED: the test case must be passed for an implementation to be
- // interoperable with other implementations. For example, a
- // parser implementaiton must accept both packed and unpacked
- // form of repeated primitive fields.
- // RECOMMENDED: the test case is not required for the implementation to
- // be interoperable with other implementations, but is
- // recommended for best performance and compatibility. For
- // example, a proto3 serializer should serialize repeated
- // primitive fields in packed form, but an implementation
- // failing to do so will still be able to communicate with
- // other implementations.
- enum ConformanceLevel {
- REQUIRED = 0,
- RECOMMENDED = 1,
- };
- string ConformanceLevelToString(ConformanceLevel level);
-
- void ReportSuccess(const std::string& test_name);
- void ReportFailure(const string& test_name,
- ConformanceLevel level,
- const conformance::ConformanceRequest& request,
- const conformance::ConformanceResponse& response,
- const char* fmt, ...);
- void ReportSkip(const string& test_name,
- const conformance::ConformanceRequest& request,
- const conformance::ConformanceResponse& response);
- void RunTest(const std::string& test_name,
- const conformance::ConformanceRequest& request,
- conformance::ConformanceResponse* response);
- void RunValidInputTest(const string& test_name,
- ConformanceLevel level,
- const string& input,
- conformance::WireFormat input_format,
- const string& equivalent_text_format,
- conformance::WireFormat requested_output);
- void RunValidJsonTest(const string& test_name,
- ConformanceLevel level,
- const string& input_json,
- const string& equivalent_text_format);
- void RunValidJsonTestWithProtobufInput(
- const string& test_name,
- ConformanceLevel level,
- const protobuf_test_messages::proto3::TestAllTypes& input,
- const string& equivalent_text_format);
- void RunValidProtobufTest(const string& test_name, ConformanceLevel level,
- const string& input_protobuf,
- const string& equivalent_text_format);
- void RunValidProtobufTestWithMessage(
- const string& test_name, ConformanceLevel level,
- const protobuf_test_messages::proto3::TestAllTypes& input,
- const string& equivalent_text_format);
-
- typedef std::function<bool(const Json::Value&)> Validator;
- void RunValidJsonTestWithValidator(const string& test_name,
- ConformanceLevel level,
- const string& input_json,
- const Validator& validator);
- void ExpectParseFailureForJson(const string& test_name,
- ConformanceLevel level,
- const string& input_json);
- void ExpectSerializeFailureForJson(const string& test_name,
- ConformanceLevel level,
- const string& text_format);
- void ExpectParseFailureForProto(const std::string& proto,
- const std::string& test_name,
- ConformanceLevel level);
- void ExpectHardParseFailureForProto(const std::string& proto,
- const std::string& test_name,
- ConformanceLevel level);
- void TestPrematureEOFForType(google::protobuf::FieldDescriptor::Type type);
- void TestValidDataForType(
- google::protobuf::FieldDescriptor::Type,
- std::vector<std::pair<std::string, std::string>> values);
- bool CheckSetEmpty(const set<string>& set_to_check,
- const std::string& write_to_file, const std::string& msg);
- ConformanceTestRunner* runner_;
- int successes_;
- int expected_failures_;
- bool verbose_;
- bool enforce_recommended_;
- std::string output_;
- std::string failure_list_filename_;
-
- // The set of test names that are expected to fail in this run, but haven't
- // failed yet.
- std::set<std::string> expected_to_fail_;
-
- // The set of test names that have been run. Used to ensure that there are no
- // duplicate names in the suite.
- std::set<std::string> test_names_;
-
- // The set of tests that failed, but weren't expected to.
- std::set<std::string> unexpected_failing_tests_;
-
- // The set of tests that succeeded, but weren't expected to.
- std::set<std::string> unexpected_succeeding_tests_;
-
- // The set of tests that the testee opted out of;
- std::set<std::string> skipped_;
-
- google::protobuf::internal::scoped_ptr<google::protobuf::util::TypeResolver>
- type_resolver_;
- std::string type_url_;
-};
-
-} // namespace protobuf
-} // namespace google
-
-#endif // CONFORMANCE_CONFORMANCE_TEST_H
diff --git a/third_party/protobuf/3.2.0/conformance/conformance_test_runner.cc b/third_party/protobuf/3.2.0/conformance/conformance_test_runner.cc
deleted file mode 100644
index 7e91d388b0..0000000000
--- a/third_party/protobuf/3.2.0/conformance/conformance_test_runner.cc
+++ /dev/null
@@ -1,326 +0,0 @@
-// 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.
-
-// This file contains a program for running the test suite in a separate
-// process. The other alternative is to run the suite in-process. See
-// conformance.proto for pros/cons of these two options.
-//
-// This program will fork the process under test and communicate with it over
-// its stdin/stdout:
-//
-// +--------+ pipe +----------+
-// | tester | <------> | testee |
-// | | | |
-// | C++ | | any lang |
-// +--------+ +----------+
-//
-// The tester contains all of the test cases and their expected output.
-// The testee is a simple program written in the target language that reads
-// each test case and attempts to produce acceptable output for it.
-//
-// Every test consists of a ConformanceRequest/ConformanceResponse
-// request/reply pair. The protocol on the pipe is simply:
-//
-// 1. tester sends 4-byte length N (little endian)
-// 2. tester sends N bytes representing a ConformanceRequest proto
-// 3. testee sends 4-byte length M (little endian)
-// 4. testee sends M bytes representing a ConformanceResponse proto
-
-#include <algorithm>
-#include <errno.h>
-#include <fstream>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#include <vector>
-
-#include <google/protobuf/stubs/stringprintf.h>
-
-#include "conformance.pb.h"
-#include "conformance_test.h"
-
-using conformance::ConformanceRequest;
-using conformance::ConformanceResponse;
-using google::protobuf::internal::scoped_array;
-using google::protobuf::StringAppendF;
-using std::string;
-using std::vector;
-
-#define STRINGIFY(x) #x
-#define TOSTRING(x) STRINGIFY(x)
-#define CHECK_SYSCALL(call) \
- if (call < 0) { \
- perror(#call " " __FILE__ ":" TOSTRING(__LINE__)); \
- exit(1); \
- }
-
-// Test runner that spawns the process being tested and communicates with it
-// over a pipe.
-class ForkPipeRunner : public google::protobuf::ConformanceTestRunner {
- public:
- ForkPipeRunner(const std::string &executable)
- : child_pid_(-1), executable_(executable) {}
-
- virtual ~ForkPipeRunner() {}
-
- void RunTest(const std::string& test_name,
- const std::string& request,
- std::string* response) {
- if (child_pid_ < 0) {
- SpawnTestProgram();
- }
-
- current_test_name_ = test_name;
-
- uint32_t len = request.size();
- CheckedWrite(write_fd_, &len, sizeof(uint32_t));
- CheckedWrite(write_fd_, request.c_str(), request.size());
-
- if (!TryRead(read_fd_, &len, sizeof(uint32_t))) {
- // We failed to read from the child, assume a crash and try to reap.
- GOOGLE_LOG(INFO) << "Trying to reap child, pid=" << child_pid_;
-
- int status;
- waitpid(child_pid_, &status, WEXITED);
-
- string error_msg;
- if (WIFEXITED(status)) {
- StringAppendF(&error_msg,
- "child exited, status=%d", WEXITSTATUS(status));
- } else if (WIFSIGNALED(status)) {
- StringAppendF(&error_msg,
- "child killed by signal %d", WTERMSIG(status));
- }
- GOOGLE_LOG(INFO) << error_msg;
- child_pid_ = -1;
-
- conformance::ConformanceResponse response_obj;
- response_obj.set_runtime_error(error_msg);
- response_obj.SerializeToString(response);
- return;
- }
-
- response->resize(len);
- CheckedRead(read_fd_, (void*)response->c_str(), len);
- }
-
- private:
- // TODO(haberman): make this work on Windows, instead of using these
- // UNIX-specific APIs.
- //
- // There is a platform-agnostic API in
- // src/google/protobuf/compiler/subprocess.h
- //
- // However that API only supports sending a single message to the subprocess.
- // We really want to be able to send messages and receive responses one at a
- // time:
- //
- // 1. Spawning a new process for each test would take way too long for thousands
- // of tests and subprocesses like java that can take 100ms or more to start
- // up.
- //
- // 2. Sending all the tests in one big message and receiving all results in one
- // big message would take away our visibility about which test(s) caused a
- // crash or other fatal error. It would also give us only a single failure
- // instead of all of them.
- void SpawnTestProgram() {
- int toproc_pipe_fd[2];
- int fromproc_pipe_fd[2];
- if (pipe(toproc_pipe_fd) < 0 || pipe(fromproc_pipe_fd) < 0) {
- perror("pipe");
- exit(1);
- }
-
- pid_t pid = fork();
- if (pid < 0) {
- perror("fork");
- exit(1);
- }
-
- if (pid) {
- // Parent.
- CHECK_SYSCALL(close(toproc_pipe_fd[0]));
- CHECK_SYSCALL(close(fromproc_pipe_fd[1]));
- write_fd_ = toproc_pipe_fd[1];
- read_fd_ = fromproc_pipe_fd[0];
- child_pid_ = pid;
- } else {
- // Child.
- CHECK_SYSCALL(close(STDIN_FILENO));
- CHECK_SYSCALL(close(STDOUT_FILENO));
- CHECK_SYSCALL(dup2(toproc_pipe_fd[0], STDIN_FILENO));
- CHECK_SYSCALL(dup2(fromproc_pipe_fd[1], STDOUT_FILENO));
-
- CHECK_SYSCALL(close(toproc_pipe_fd[0]));
- CHECK_SYSCALL(close(fromproc_pipe_fd[1]));
- CHECK_SYSCALL(close(toproc_pipe_fd[1]));
- CHECK_SYSCALL(close(fromproc_pipe_fd[0]));
-
- scoped_array<char> executable(new char[executable_.size() + 1]);
- memcpy(executable.get(), executable_.c_str(), executable_.size());
- executable[executable_.size()] = '\0';
-
- char *const argv[] = {executable.get(), NULL};
- CHECK_SYSCALL(execv(executable.get(), argv)); // Never returns.
- }
- }
-
- void CheckedWrite(int fd, const void *buf, size_t len) {
- if (write(fd, buf, len) != len) {
- GOOGLE_LOG(FATAL) << current_test_name_
- << ": error writing to test program: "
- << strerror(errno);
- }
- }
-
- bool TryRead(int fd, void *buf, size_t len) {
- size_t ofs = 0;
- while (len > 0) {
- ssize_t bytes_read = read(fd, (char*)buf + ofs, len);
-
- if (bytes_read == 0) {
- GOOGLE_LOG(ERROR) << current_test_name_
- << ": unexpected EOF from test program";
- return false;
- } else if (bytes_read < 0) {
- GOOGLE_LOG(ERROR) << current_test_name_
- << ": error reading from test program: "
- << strerror(errno);
- return false;
- }
-
- len -= bytes_read;
- ofs += bytes_read;
- }
-
- return true;
- }
-
- void CheckedRead(int fd, void *buf, size_t len) {
- if (!TryRead(fd, buf, len)) {
- GOOGLE_LOG(FATAL) << current_test_name_
- << ": error reading from test program: "
- << strerror(errno);
- }
- }
-
- int write_fd_;
- int read_fd_;
- pid_t child_pid_;
- std::string executable_;
- std::string current_test_name_;
-};
-
-void UsageError() {
- fprintf(stderr,
- "Usage: conformance-test-runner [options] <test-program>\n");
- fprintf(stderr, "\n");
- fprintf(stderr, "Options:\n");
- fprintf(stderr,
- " --failure_list <filename> Use to specify list of tests\n");
- fprintf(stderr,
- " that are expected to fail. File\n");
- fprintf(stderr,
- " should contain one test name per\n");
- fprintf(stderr,
- " line. Use '#' for comments.\n");
- fprintf(stderr,
- " --enforce_recommended Enforce that recommended test\n");
- fprintf(stderr,
- " cases are also passing. Specify\n");
- fprintf(stderr,
- " this flag if you want to be\n");
- fprintf(stderr,
- " strictly conforming to protobuf\n");
- fprintf(stderr,
- " spec.\n");
- exit(1);
-}
-
-void ParseFailureList(const char *filename, vector<string>* failure_list) {
- std::ifstream infile(filename);
-
- if (!infile.is_open()) {
- fprintf(stderr, "Couldn't open failure list file: %s\n", filename);
- exit(1);
- }
-
- for (string line; getline(infile, line);) {
- // Remove whitespace.
- line.erase(std::remove_if(line.begin(), line.end(), ::isspace),
- line.end());
-
- // Remove comments.
- line = line.substr(0, line.find("#"));
-
- if (!line.empty()) {
- failure_list->push_back(line);
- }
- }
-}
-
-int main(int argc, char *argv[]) {
- char *program;
- google::protobuf::ConformanceTestSuite suite;
-
- string failure_list_filename;
- vector<string> failure_list;
-
- for (int arg = 1; arg < argc; ++arg) {
- if (strcmp(argv[arg], "--failure_list") == 0) {
- if (++arg == argc) UsageError();
- failure_list_filename = argv[arg];
- ParseFailureList(argv[arg], &failure_list);
- } else if (strcmp(argv[arg], "--verbose") == 0) {
- suite.SetVerbose(true);
- } else if (strcmp(argv[arg], "--enforce_recommended") == 0) {
- suite.SetEnforceRecommended(true);
- } else if (argv[arg][0] == '-') {
- fprintf(stderr, "Unknown option: %s\n", argv[arg]);
- UsageError();
- } else {
- if (arg != argc - 1) {
- fprintf(stderr, "Too many arguments.\n");
- UsageError();
- }
- program = argv[arg];
- }
- }
-
- suite.SetFailureList(failure_list_filename, failure_list);
- ForkPipeRunner runner(program);
-
- std::string output;
- bool ok = suite.RunSuite(&runner, &output);
-
- fwrite(output.c_str(), 1, output.size(), stderr);
-
- return ok ? EXIT_SUCCESS : EXIT_FAILURE;
-}
diff --git a/third_party/protobuf/3.2.0/conformance/failure_list_cpp.txt b/third_party/protobuf/3.2.0/conformance/failure_list_cpp.txt
deleted file mode 100644
index 8cfd74da6e..0000000000
--- a/third_party/protobuf/3.2.0/conformance/failure_list_cpp.txt
+++ /dev/null
@@ -1,46 +0,0 @@
-# This is the list of conformance tests that are known to fail for the C++
-# implementation right now. These should be fixed.
-#
-# By listing them here we can keep tabs on which ones are failing and be sure
-# that we don't introduce regressions in other tests.
-#
-# TODO(haberman): insert links to corresponding bugs tracking the issue.
-# Should we use GitHub issues or the Google-internal bug tracker?
-
-Recommended.FieldMaskNumbersDontRoundTrip.JsonOutput
-Recommended.FieldMaskPathsDontRoundTrip.JsonOutput
-Recommended.FieldMaskTooManyUnderscore.JsonOutput
-Recommended.JsonInput.BoolFieldDoubleQuotedFalse
-Recommended.JsonInput.BoolFieldDoubleQuotedTrue
-Recommended.JsonInput.FieldMaskInvalidCharacter
-Recommended.JsonInput.FieldNameDuplicate
-Recommended.JsonInput.FieldNameDuplicateDifferentCasing1
-Recommended.JsonInput.FieldNameDuplicateDifferentCasing2
-Recommended.JsonInput.FieldNameNotQuoted
-Recommended.JsonInput.MapFieldValueIsNull
-Recommended.JsonInput.RepeatedFieldMessageElementIsNull
-Recommended.JsonInput.RepeatedFieldPrimitiveElementIsNull
-Recommended.JsonInput.RepeatedFieldTrailingComma
-Recommended.JsonInput.RepeatedFieldTrailingCommaWithNewlines
-Recommended.JsonInput.RepeatedFieldTrailingCommaWithSpace
-Recommended.JsonInput.RepeatedFieldTrailingCommaWithSpaceCommaSpace
-Recommended.JsonInput.StringFieldSingleQuoteBoth
-Recommended.JsonInput.StringFieldSingleQuoteKey
-Recommended.JsonInput.StringFieldSingleQuoteValue
-Recommended.JsonInput.StringFieldUppercaseEscapeLetter
-Recommended.JsonInput.TrailingCommaInAnObject
-Recommended.JsonInput.TrailingCommaInAnObjectWithNewlines
-Recommended.JsonInput.TrailingCommaInAnObjectWithSpace
-Recommended.JsonInput.TrailingCommaInAnObjectWithSpaceCommaSpace
-Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.MESSAGE
-Required.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE
-Required.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE
-Required.ProtobufInput.PrematureEofInPackedField.BOOL
-Required.ProtobufInput.PrematureEofInPackedField.ENUM
-Required.ProtobufInput.PrematureEofInPackedField.INT32
-Required.ProtobufInput.PrematureEofInPackedField.INT64
-Required.ProtobufInput.PrematureEofInPackedField.SINT32
-Required.ProtobufInput.PrematureEofInPackedField.SINT64
-Required.ProtobufInput.PrematureEofInPackedField.UINT32
-Required.ProtobufInput.PrematureEofInPackedField.UINT64
-Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.MESSAGE
diff --git a/third_party/protobuf/3.2.0/conformance/failure_list_csharp.txt b/third_party/protobuf/3.2.0/conformance/failure_list_csharp.txt
deleted file mode 100644
index e69de29bb2..0000000000
--- a/third_party/protobuf/3.2.0/conformance/failure_list_csharp.txt
+++ /dev/null
diff --git a/third_party/protobuf/3.2.0/conformance/failure_list_java.txt b/third_party/protobuf/3.2.0/conformance/failure_list_java.txt
deleted file mode 100644
index 632940efc8..0000000000
--- a/third_party/protobuf/3.2.0/conformance/failure_list_java.txt
+++ /dev/null
@@ -1,45 +0,0 @@
-# This is the list of conformance tests that are known to fail for the Java
-# implementation right now. These should be fixed.
-#
-# By listing them here we can keep tabs on which ones are failing and be sure
-# that we don't introduce regressions in other tests.
-
-Recommended.FieldMaskNumbersDontRoundTrip.JsonOutput
-Recommended.FieldMaskPathsDontRoundTrip.JsonOutput
-Recommended.FieldMaskTooManyUnderscore.JsonOutput
-Recommended.JsonInput.BoolFieldAllCapitalFalse
-Recommended.JsonInput.BoolFieldAllCapitalTrue
-Recommended.JsonInput.BoolFieldCamelCaseFalse
-Recommended.JsonInput.BoolFieldCamelCaseTrue
-Recommended.JsonInput.BoolFieldDoubleQuotedFalse
-Recommended.JsonInput.BoolFieldDoubleQuotedTrue
-Recommended.JsonInput.BoolMapFieldKeyNotQuoted
-Recommended.JsonInput.DoubleFieldInfinityNotQuoted
-Recommended.JsonInput.DoubleFieldNanNotQuoted
-Recommended.JsonInput.DoubleFieldNegativeInfinityNotQuoted
-Recommended.JsonInput.FieldMaskInvalidCharacter
-Recommended.JsonInput.FieldNameDuplicate
-Recommended.JsonInput.FieldNameNotQuoted
-Recommended.JsonInput.FloatFieldInfinityNotQuoted
-Recommended.JsonInput.FloatFieldNanNotQuoted
-Recommended.JsonInput.FloatFieldNegativeInfinityNotQuoted
-Recommended.JsonInput.Int32MapFieldKeyNotQuoted
-Recommended.JsonInput.Int64MapFieldKeyNotQuoted
-Recommended.JsonInput.JsonWithComments
-Recommended.JsonInput.StringFieldSingleQuoteBoth
-Recommended.JsonInput.StringFieldSingleQuoteKey
-Recommended.JsonInput.StringFieldSingleQuoteValue
-Recommended.JsonInput.StringFieldSurrogateInWrongOrder
-Recommended.JsonInput.StringFieldUnpairedHighSurrogate
-Recommended.JsonInput.StringFieldUnpairedLowSurrogate
-Recommended.JsonInput.Uint32MapFieldKeyNotQuoted
-Recommended.JsonInput.Uint64MapFieldKeyNotQuoted
-Required.JsonInput.EnumFieldNotQuoted
-Required.JsonInput.Int32FieldLeadingZero
-Required.JsonInput.Int32FieldNegativeWithLeadingZero
-Required.JsonInput.Int32FieldPlusSign
-Required.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotBool
-Required.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotInt
-Required.JsonInput.StringFieldNotAString
-Required.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE
-Required.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE
diff --git a/third_party/protobuf/3.2.0/conformance/failure_list_objc.txt b/third_party/protobuf/3.2.0/conformance/failure_list_objc.txt
deleted file mode 100644
index dd538c1036..0000000000
--- a/third_party/protobuf/3.2.0/conformance/failure_list_objc.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-# All tests currently passing.
-#
-# JSON input or output tests are skipped (in conformance_objc.m) as mobile
-# platforms don't support JSON wire format to avoid code bloat.
diff --git a/third_party/protobuf/3.2.0/conformance/failure_list_python-post26.txt b/third_party/protobuf/3.2.0/conformance/failure_list_python-post26.txt
deleted file mode 100644
index 19d99b044a..0000000000
--- a/third_party/protobuf/3.2.0/conformance/failure_list_python-post26.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-JsonInput.StringFieldSurrogateInWrongOrder
-JsonInput.StringFieldUnpairedHighSurrogate
diff --git a/third_party/protobuf/3.2.0/conformance/failure_list_python.txt b/third_party/protobuf/3.2.0/conformance/failure_list_python.txt
deleted file mode 100644
index 9d556a036b..0000000000
--- a/third_party/protobuf/3.2.0/conformance/failure_list_python.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-Recommended.JsonInput.DoubleFieldInfinityNotQuoted
-Recommended.JsonInput.DoubleFieldNanNotQuoted
-Recommended.JsonInput.DoubleFieldNegativeInfinityNotQuoted
-Recommended.JsonInput.FloatFieldInfinityNotQuoted
-Recommended.JsonInput.FloatFieldNanNotQuoted
-Recommended.JsonInput.FloatFieldNegativeInfinityNotQuoted
-Required.JsonInput.BytesFieldInvalidBase64Characters
-Required.JsonInput.DoubleFieldTooSmall
-Required.JsonInput.EnumFieldUnknownValue.Validator
-Required.JsonInput.FloatFieldTooLarge
-Required.JsonInput.FloatFieldTooSmall
-Required.JsonInput.RepeatedFieldWrongElementTypeExpectingIntegersGotBool
-Required.JsonInput.TimestampJsonInputLowercaseT
diff --git a/third_party/protobuf/3.2.0/conformance/failure_list_python_cpp.txt b/third_party/protobuf/3.2.0/conformance/failure_list_python_cpp.txt
deleted file mode 100644
index 92404d2f6a..0000000000
--- a/third_party/protobuf/3.2.0/conformance/failure_list_python_cpp.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-# This is the list of conformance tests that are known to fail for the
-# Python/C++ implementation right now. These should be fixed.
-#
-# By listing them here we can keep tabs on which ones are failing and be sure
-# that we don't introduce regressions in other tests.
-#
-# TODO(haberman): insert links to corresponding bugs tracking the issue.
-# Should we use GitHub issues or the Google-internal bug tracker?
-
-Recommended.JsonInput.DoubleFieldInfinityNotQuoted
-Recommended.JsonInput.DoubleFieldNanNotQuoted
-Recommended.JsonInput.DoubleFieldNegativeInfinityNotQuoted
-Recommended.JsonInput.FloatFieldInfinityNotQuoted
-Recommended.JsonInput.FloatFieldNanNotQuoted
-Recommended.JsonInput.FloatFieldNegativeInfinityNotQuoted
-Required.JsonInput.BytesFieldInvalidBase64Characters
-Required.JsonInput.DoubleFieldTooSmall
-Required.JsonInput.EnumFieldUnknownValue.Validator
-Required.JsonInput.FloatFieldTooLarge
-Required.JsonInput.FloatFieldTooSmall
-Required.JsonInput.RepeatedFieldWrongElementTypeExpectingIntegersGotBool
-Required.JsonInput.TimestampJsonInputLowercaseT
-Required.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE
-Required.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE
-Required.ProtobufInput.PrematureEofInPackedField.BOOL
-Required.ProtobufInput.PrematureEofInPackedField.DOUBLE
-Required.ProtobufInput.PrematureEofInPackedField.ENUM
-Required.ProtobufInput.PrematureEofInPackedField.FIXED32
-Required.ProtobufInput.PrematureEofInPackedField.FIXED64
-Required.ProtobufInput.PrematureEofInPackedField.FLOAT
-Required.ProtobufInput.PrematureEofInPackedField.INT32
-Required.ProtobufInput.PrematureEofInPackedField.INT64
-Required.ProtobufInput.PrematureEofInPackedField.SFIXED32
-Required.ProtobufInput.PrematureEofInPackedField.SFIXED64
-Required.ProtobufInput.PrematureEofInPackedField.SINT32
-Required.ProtobufInput.PrematureEofInPackedField.SINT64
-Required.ProtobufInput.PrematureEofInPackedField.UINT32
-Required.ProtobufInput.PrematureEofInPackedField.UINT64
diff --git a/third_party/protobuf/3.2.0/conformance/failure_list_ruby.txt b/third_party/protobuf/3.2.0/conformance/failure_list_ruby.txt
deleted file mode 100644
index 1de6c4390c..0000000000
--- a/third_party/protobuf/3.2.0/conformance/failure_list_ruby.txt
+++ /dev/null
@@ -1,203 +0,0 @@
-Recommended.FieldMaskNumbersDontRoundTrip.JsonOutput
-Recommended.FieldMaskPathsDontRoundTrip.JsonOutput
-Recommended.FieldMaskTooManyUnderscore.JsonOutput
-Recommended.JsonInput.BoolFieldIntegerOne
-Recommended.JsonInput.BoolFieldIntegerZero
-Recommended.JsonInput.DurationHas3FractionalDigits.Validator
-Recommended.JsonInput.DurationHas6FractionalDigits.Validator
-Recommended.JsonInput.DurationHas9FractionalDigits.Validator
-Recommended.JsonInput.DurationHasZeroFractionalDigit.Validator
-Recommended.JsonInput.Int64FieldBeString.Validator
-Recommended.JsonInput.OneofZeroDouble.JsonOutput
-Recommended.JsonInput.OneofZeroDouble.ProtobufOutput
-Recommended.JsonInput.OneofZeroFloat.JsonOutput
-Recommended.JsonInput.OneofZeroFloat.ProtobufOutput
-Recommended.JsonInput.OneofZeroUint32.JsonOutput
-Recommended.JsonInput.OneofZeroUint32.ProtobufOutput
-Recommended.JsonInput.OneofZeroUint64.JsonOutput
-Recommended.JsonInput.OneofZeroUint64.ProtobufOutput
-Recommended.JsonInput.StringEndsWithEscapeChar
-Recommended.JsonInput.StringFieldSurrogateInWrongOrder
-Recommended.JsonInput.StringFieldUnpairedHighSurrogate
-Recommended.JsonInput.StringFieldUnpairedLowSurrogate
-Recommended.JsonInput.TimestampHas3FractionalDigits.Validator
-Recommended.JsonInput.TimestampHas6FractionalDigits.Validator
-Recommended.JsonInput.TimestampHas9FractionalDigits.Validator
-Recommended.JsonInput.TimestampHasZeroFractionalDigit.Validator
-Recommended.JsonInput.TimestampZeroNormalized.Validator
-Recommended.JsonInput.Uint64FieldBeString.Validator
-Required.DurationProtoInputTooLarge.JsonOutput
-Required.DurationProtoInputTooSmall.JsonOutput
-Required.JsonInput.Any.JsonOutput
-Required.JsonInput.Any.ProtobufOutput
-Required.JsonInput.AnyNested.JsonOutput
-Required.JsonInput.AnyNested.ProtobufOutput
-Required.JsonInput.AnyUnorderedTypeTag.JsonOutput
-Required.JsonInput.AnyUnorderedTypeTag.ProtobufOutput
-Required.JsonInput.AnyWithDuration.JsonOutput
-Required.JsonInput.AnyWithDuration.ProtobufOutput
-Required.JsonInput.AnyWithFieldMask.JsonOutput
-Required.JsonInput.AnyWithFieldMask.ProtobufOutput
-Required.JsonInput.AnyWithInt32ValueWrapper.JsonOutput
-Required.JsonInput.AnyWithInt32ValueWrapper.ProtobufOutput
-Required.JsonInput.AnyWithStruct.JsonOutput
-Required.JsonInput.AnyWithStruct.ProtobufOutput
-Required.JsonInput.AnyWithTimestamp.JsonOutput
-Required.JsonInput.AnyWithTimestamp.ProtobufOutput
-Required.JsonInput.AnyWithValueForInteger.JsonOutput
-Required.JsonInput.AnyWithValueForInteger.ProtobufOutput
-Required.JsonInput.AnyWithValueForJsonObject.JsonOutput
-Required.JsonInput.AnyWithValueForJsonObject.ProtobufOutput
-Required.JsonInput.DoubleFieldInfinity.JsonOutput
-Required.JsonInput.DoubleFieldInfinity.ProtobufOutput
-Required.JsonInput.DoubleFieldMaxNegativeValue.JsonOutput
-Required.JsonInput.DoubleFieldMaxNegativeValue.ProtobufOutput
-Required.JsonInput.DoubleFieldMaxPositiveValue.JsonOutput
-Required.JsonInput.DoubleFieldMaxPositiveValue.ProtobufOutput
-Required.JsonInput.DoubleFieldMinNegativeValue.JsonOutput
-Required.JsonInput.DoubleFieldMinNegativeValue.ProtobufOutput
-Required.JsonInput.DoubleFieldMinPositiveValue.JsonOutput
-Required.JsonInput.DoubleFieldMinPositiveValue.ProtobufOutput
-Required.JsonInput.DoubleFieldNan.JsonOutput
-Required.JsonInput.DoubleFieldNan.ProtobufOutput
-Required.JsonInput.DoubleFieldNegativeInfinity.JsonOutput
-Required.JsonInput.DoubleFieldNegativeInfinity.ProtobufOutput
-Required.JsonInput.DoubleFieldQuotedValue.JsonOutput
-Required.JsonInput.DoubleFieldQuotedValue.ProtobufOutput
-Required.JsonInput.DurationMaxValue.JsonOutput
-Required.JsonInput.DurationMaxValue.ProtobufOutput
-Required.JsonInput.DurationMinValue.JsonOutput
-Required.JsonInput.DurationMinValue.ProtobufOutput
-Required.JsonInput.DurationRepeatedValue.JsonOutput
-Required.JsonInput.DurationRepeatedValue.ProtobufOutput
-Required.JsonInput.EnumFieldNumericValueNonZero.JsonOutput
-Required.JsonInput.EnumFieldNumericValueNonZero.ProtobufOutput
-Required.JsonInput.EnumFieldNumericValueZero.JsonOutput
-Required.JsonInput.EnumFieldNumericValueZero.ProtobufOutput
-Required.JsonInput.EnumFieldUnknownValue.Validator
-Required.JsonInput.FieldMask.JsonOutput
-Required.JsonInput.FieldMask.ProtobufOutput
-Required.JsonInput.FloatFieldInfinity.JsonOutput
-Required.JsonInput.FloatFieldInfinity.ProtobufOutput
-Required.JsonInput.FloatFieldNan.JsonOutput
-Required.JsonInput.FloatFieldNan.ProtobufOutput
-Required.JsonInput.FloatFieldNegativeInfinity.JsonOutput
-Required.JsonInput.FloatFieldNegativeInfinity.ProtobufOutput
-Required.JsonInput.FloatFieldQuotedValue.JsonOutput
-Required.JsonInput.FloatFieldQuotedValue.ProtobufOutput
-Required.JsonInput.FloatFieldTooLarge
-Required.JsonInput.FloatFieldTooSmall
-Required.JsonInput.Int32FieldExponentialFormat.JsonOutput
-Required.JsonInput.Int32FieldExponentialFormat.ProtobufOutput
-Required.JsonInput.Int32FieldFloatTrailingZero.JsonOutput
-Required.JsonInput.Int32FieldFloatTrailingZero.ProtobufOutput
-Required.JsonInput.Int32FieldMaxFloatValue.JsonOutput
-Required.JsonInput.Int32FieldMaxFloatValue.ProtobufOutput
-Required.JsonInput.Int32FieldMinFloatValue.JsonOutput
-Required.JsonInput.Int32FieldMinFloatValue.ProtobufOutput
-Required.JsonInput.Int32FieldStringValue.JsonOutput
-Required.JsonInput.Int32FieldStringValue.ProtobufOutput
-Required.JsonInput.Int32FieldStringValueEscaped.JsonOutput
-Required.JsonInput.Int32FieldStringValueEscaped.ProtobufOutput
-Required.JsonInput.Int32MapEscapedKey.JsonOutput
-Required.JsonInput.Int32MapEscapedKey.ProtobufOutput
-Required.JsonInput.Int32MapField.JsonOutput
-Required.JsonInput.Int32MapField.ProtobufOutput
-Required.JsonInput.Int64FieldMaxValue.JsonOutput
-Required.JsonInput.Int64FieldMaxValue.ProtobufOutput
-Required.JsonInput.Int64FieldMinValue.JsonOutput
-Required.JsonInput.Int64FieldMinValue.ProtobufOutput
-Required.JsonInput.Int64MapEscapedKey.JsonOutput
-Required.JsonInput.Int64MapEscapedKey.ProtobufOutput
-Required.JsonInput.Int64MapField.JsonOutput
-Required.JsonInput.Int64MapField.ProtobufOutput
-Required.JsonInput.MessageField.JsonOutput
-Required.JsonInput.MessageField.ProtobufOutput
-Required.JsonInput.MessageMapField.JsonOutput
-Required.JsonInput.MessageMapField.ProtobufOutput
-Required.JsonInput.MessageRepeatedField.JsonOutput
-Required.JsonInput.MessageRepeatedField.ProtobufOutput
-Required.JsonInput.OptionalBoolWrapper.JsonOutput
-Required.JsonInput.OptionalBoolWrapper.ProtobufOutput
-Required.JsonInput.OptionalBytesWrapper.JsonOutput
-Required.JsonInput.OptionalBytesWrapper.ProtobufOutput
-Required.JsonInput.OptionalDoubleWrapper.JsonOutput
-Required.JsonInput.OptionalDoubleWrapper.ProtobufOutput
-Required.JsonInput.OptionalFloatWrapper.JsonOutput
-Required.JsonInput.OptionalFloatWrapper.ProtobufOutput
-Required.JsonInput.OptionalInt32Wrapper.JsonOutput
-Required.JsonInput.OptionalInt32Wrapper.ProtobufOutput
-Required.JsonInput.OptionalInt64Wrapper.JsonOutput
-Required.JsonInput.OptionalInt64Wrapper.ProtobufOutput
-Required.JsonInput.OptionalStringWrapper.JsonOutput
-Required.JsonInput.OptionalStringWrapper.ProtobufOutput
-Required.JsonInput.OptionalUint32Wrapper.JsonOutput
-Required.JsonInput.OptionalUint32Wrapper.ProtobufOutput
-Required.JsonInput.OptionalUint64Wrapper.JsonOutput
-Required.JsonInput.OptionalUint64Wrapper.ProtobufOutput
-Required.JsonInput.OptionalWrapperTypesWithNonDefaultValue.JsonOutput
-Required.JsonInput.OptionalWrapperTypesWithNonDefaultValue.ProtobufOutput
-Required.JsonInput.PrimitiveRepeatedField.JsonOutput
-Required.JsonInput.PrimitiveRepeatedField.ProtobufOutput
-Required.JsonInput.RepeatedBoolWrapper.JsonOutput
-Required.JsonInput.RepeatedBoolWrapper.ProtobufOutput
-Required.JsonInput.RepeatedBytesWrapper.JsonOutput
-Required.JsonInput.RepeatedBytesWrapper.ProtobufOutput
-Required.JsonInput.RepeatedDoubleWrapper.JsonOutput
-Required.JsonInput.RepeatedDoubleWrapper.ProtobufOutput
-Required.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotInt
-Required.JsonInput.RepeatedFloatWrapper.JsonOutput
-Required.JsonInput.RepeatedFloatWrapper.ProtobufOutput
-Required.JsonInput.RepeatedInt32Wrapper.JsonOutput
-Required.JsonInput.RepeatedInt32Wrapper.ProtobufOutput
-Required.JsonInput.RepeatedInt64Wrapper.JsonOutput
-Required.JsonInput.RepeatedInt64Wrapper.ProtobufOutput
-Required.JsonInput.RepeatedStringWrapper.JsonOutput
-Required.JsonInput.RepeatedStringWrapper.ProtobufOutput
-Required.JsonInput.RepeatedUint32Wrapper.JsonOutput
-Required.JsonInput.RepeatedUint32Wrapper.ProtobufOutput
-Required.JsonInput.RepeatedUint64Wrapper.JsonOutput
-Required.JsonInput.RepeatedUint64Wrapper.ProtobufOutput
-Required.JsonInput.StringFieldNotAString
-Required.JsonInput.StringFieldSurrogatePair.JsonOutput
-Required.JsonInput.StringFieldSurrogatePair.ProtobufOutput
-Required.JsonInput.Struct.JsonOutput
-Required.JsonInput.Struct.ProtobufOutput
-Required.JsonInput.TimestampMaxValue.JsonOutput
-Required.JsonInput.TimestampMaxValue.ProtobufOutput
-Required.JsonInput.TimestampMinValue.JsonOutput
-Required.JsonInput.TimestampMinValue.ProtobufOutput
-Required.JsonInput.TimestampRepeatedValue.JsonOutput
-Required.JsonInput.TimestampRepeatedValue.ProtobufOutput
-Required.JsonInput.TimestampWithNegativeOffset.JsonOutput
-Required.JsonInput.TimestampWithNegativeOffset.ProtobufOutput
-Required.JsonInput.TimestampWithPositiveOffset.JsonOutput
-Required.JsonInput.TimestampWithPositiveOffset.ProtobufOutput
-Required.JsonInput.Uint32FieldMaxFloatValue.JsonOutput
-Required.JsonInput.Uint32FieldMaxFloatValue.ProtobufOutput
-Required.JsonInput.Uint32MapField.JsonOutput
-Required.JsonInput.Uint32MapField.ProtobufOutput
-Required.JsonInput.Uint64FieldMaxValue.JsonOutput
-Required.JsonInput.Uint64FieldMaxValue.ProtobufOutput
-Required.JsonInput.Uint64MapField.JsonOutput
-Required.JsonInput.Uint64MapField.ProtobufOutput
-Required.JsonInput.ValueAcceptBool.JsonOutput
-Required.JsonInput.ValueAcceptBool.ProtobufOutput
-Required.JsonInput.ValueAcceptFloat.JsonOutput
-Required.JsonInput.ValueAcceptFloat.ProtobufOutput
-Required.JsonInput.ValueAcceptInteger.JsonOutput
-Required.JsonInput.ValueAcceptInteger.ProtobufOutput
-Required.JsonInput.ValueAcceptList.JsonOutput
-Required.JsonInput.ValueAcceptList.ProtobufOutput
-Required.JsonInput.ValueAcceptNull.JsonOutput
-Required.JsonInput.ValueAcceptNull.ProtobufOutput
-Required.JsonInput.ValueAcceptObject.JsonOutput
-Required.JsonInput.ValueAcceptObject.ProtobufOutput
-Required.JsonInput.ValueAcceptString.JsonOutput
-Required.JsonInput.ValueAcceptString.ProtobufOutput
-Required.ProtobufInput.DoubleFieldNormalizeQuietNan.JsonOutput
-Required.ProtobufInput.DoubleFieldNormalizeSignalingNan.JsonOutput
-Required.ProtobufInput.FloatFieldNormalizeQuietNan.JsonOutput
-Required.ProtobufInput.FloatFieldNormalizeSignalingNan.JsonOutput
-Required.TimestampProtoInputTooLarge.JsonOutput
-Required.TimestampProtoInputTooSmall.JsonOutput
diff --git a/third_party/protobuf/3.2.0/conformance/third_party/jsoncpp/json.h b/third_party/protobuf/3.2.0/conformance/third_party/jsoncpp/json.h
deleted file mode 100644
index 42e7e7f4ad..0000000000
--- a/third_party/protobuf/3.2.0/conformance/third_party/jsoncpp/json.h
+++ /dev/null
@@ -1,2075 +0,0 @@
-/// Json-cpp amalgated header (http://jsoncpp.sourceforge.net/).
-/// It is intended to be used with #include "json/json.h"
-
-// //////////////////////////////////////////////////////////////////////
-// Beginning of content of file: LICENSE
-// //////////////////////////////////////////////////////////////////////
-
-/*
-The JsonCpp library's source code, including accompanying documentation,
-tests and demonstration applications, are licensed under the following
-conditions...
-
-The author (Baptiste Lepilleur) explicitly disclaims copyright in all
-jurisdictions which recognize such a disclaimer. In such jurisdictions,
-this software is released into the Public Domain.
-
-In jurisdictions which do not recognize Public Domain property (e.g. Germany as of
-2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur, and is
-released under the terms of the MIT License (see below).
-
-In jurisdictions which recognize Public Domain property, the user of this
-software may choose to accept it either as 1) Public Domain, 2) under the
-conditions of the MIT License (see below), or 3) under the terms of dual
-Public Domain/MIT License conditions described here, as they choose.
-
-The MIT License is about as close to Public Domain as a license can get, and is
-described in clear, concise terms at:
-
- http://en.wikipedia.org/wiki/MIT_License
-
-The full text of the MIT License follows:
-
-========================================================================
-Copyright (c) 2007-2010 Baptiste Lepilleur
-
-Permission is hereby granted, free of charge, to any person
-obtaining a copy of this software and associated documentation
-files (the "Software"), to deal in the Software without
-restriction, including without limitation the rights to use, copy,
-modify, merge, publish, distribute, sublicense, and/or sell copies
-of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
-BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
-ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-========================================================================
-(END LICENSE TEXT)
-
-The MIT license is compatible with both the GPL and commercial
-software, affording one all of the rights of Public Domain with the
-minor nuisance of being required to keep the above copyright notice
-and license text in the source code. Note also that by accepting the
-Public Domain "license" you can re-license your copy using whatever
-license you like.
-
-*/
-
-// //////////////////////////////////////////////////////////////////////
-// End of content of file: LICENSE
-// //////////////////////////////////////////////////////////////////////
-
-
-
-
-
-#ifndef JSON_AMALGATED_H_INCLUDED
-# define JSON_AMALGATED_H_INCLUDED
-/// If defined, indicates that the source file is amalgated
-/// to prevent private header inclusion.
-#define JSON_IS_AMALGAMATION
-
-// //////////////////////////////////////////////////////////////////////
-// Beginning of content of file: include/json/version.h
-// //////////////////////////////////////////////////////////////////////
-
-// DO NOT EDIT. This file (and "version") is generated by CMake.
-// Run CMake configure step to update it.
-#ifndef JSON_VERSION_H_INCLUDED
-# define JSON_VERSION_H_INCLUDED
-
-# define JSONCPP_VERSION_STRING "1.6.5"
-# define JSONCPP_VERSION_MAJOR 1
-# define JSONCPP_VERSION_MINOR 6
-# define JSONCPP_VERSION_PATCH 5
-# define JSONCPP_VERSION_QUALIFIER
-# define JSONCPP_VERSION_HEXA ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | (JSONCPP_VERSION_PATCH << 8))
-
-#endif // JSON_VERSION_H_INCLUDED
-
-// //////////////////////////////////////////////////////////////////////
-// End of content of file: include/json/version.h
-// //////////////////////////////////////////////////////////////////////
-
-
-
-
-
-
-// //////////////////////////////////////////////////////////////////////
-// Beginning of content of file: include/json/config.h
-// //////////////////////////////////////////////////////////////////////
-
-// Copyright 2007-2010 Baptiste Lepilleur
-// Distributed under MIT license, or public domain if desired and
-// recognized in your jurisdiction.
-// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
-
-#ifndef JSON_CONFIG_H_INCLUDED
-#define JSON_CONFIG_H_INCLUDED
-
-/// If defined, indicates that json library is embedded in CppTL library.
-//# define JSON_IN_CPPTL 1
-
-/// If defined, indicates that json may leverage CppTL library
-//# define JSON_USE_CPPTL 1
-/// If defined, indicates that cpptl vector based map should be used instead of
-/// std::map
-/// as Value container.
-//# define JSON_USE_CPPTL_SMALLMAP 1
-
-// If non-zero, the library uses exceptions to report bad input instead of C
-// assertion macros. The default is to use exceptions.
-#ifndef JSON_USE_EXCEPTION
-#define JSON_USE_EXCEPTION 1
-#endif
-
-/// If defined, indicates that the source file is amalgated
-/// to prevent private header inclusion.
-/// Remarks: it is automatically defined in the generated amalgated header.
-// #define JSON_IS_AMALGAMATION
-
-#ifdef JSON_IN_CPPTL
-#include <cpptl/config.h>
-#ifndef JSON_USE_CPPTL
-#define JSON_USE_CPPTL 1
-#endif
-#endif
-
-#ifdef JSON_IN_CPPTL
-#define JSON_API CPPTL_API
-#elif defined(JSON_DLL_BUILD)
-#if defined(_MSC_VER)
-#define JSON_API __declspec(dllexport)
-#define JSONCPP_DISABLE_DLL_INTERFACE_WARNING
-#endif // if defined(_MSC_VER)
-#elif defined(JSON_DLL)
-#if defined(_MSC_VER)
-#define JSON_API __declspec(dllimport)
-#define JSONCPP_DISABLE_DLL_INTERFACE_WARNING
-#endif // if defined(_MSC_VER)
-#endif // ifdef JSON_IN_CPPTL
-#if !defined(JSON_API)
-#define JSON_API
-#endif
-
-// If JSON_NO_INT64 is defined, then Json only support C++ "int" type for
-// integer
-// Storages, and 64 bits integer support is disabled.
-// #define JSON_NO_INT64 1
-
-#if defined(_MSC_VER) // MSVC
-# if _MSC_VER <= 1200 // MSVC 6
- // Microsoft Visual Studio 6 only support conversion from __int64 to double
- // (no conversion from unsigned __int64).
-# define JSON_USE_INT64_DOUBLE_CONVERSION 1
- // Disable warning 4786 for VS6 caused by STL (identifier was truncated to '255'
- // characters in the debug information)
- // All projects I've ever seen with VS6 were using this globally (not bothering
- // with pragma push/pop).
-# pragma warning(disable : 4786)
-# endif // MSVC 6
-
-# if _MSC_VER >= 1500 // MSVC 2008
- /// Indicates that the following function is deprecated.
-# define JSONCPP_DEPRECATED(message) __declspec(deprecated(message))
-# endif
-
-#endif // defined(_MSC_VER)
-
-
-#ifndef JSON_HAS_RVALUE_REFERENCES
-
-#if defined(_MSC_VER) && _MSC_VER >= 1600 // MSVC >= 2010
-#define JSON_HAS_RVALUE_REFERENCES 1
-#endif // MSVC >= 2010
-
-#ifdef __clang__
-#if __has_feature(cxx_rvalue_references)
-#define JSON_HAS_RVALUE_REFERENCES 1
-#endif // has_feature
-
-#elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc)
-#if defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus >= 201103L)
-#define JSON_HAS_RVALUE_REFERENCES 1
-#endif // GXX_EXPERIMENTAL
-
-#endif // __clang__ || __GNUC__
-
-#endif // not defined JSON_HAS_RVALUE_REFERENCES
-
-#ifndef JSON_HAS_RVALUE_REFERENCES
-#define JSON_HAS_RVALUE_REFERENCES 0
-#endif
-
-#ifdef __clang__
-#elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc)
-# if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5))
-# define JSONCPP_DEPRECATED(message) __attribute__ ((deprecated(message)))
-# elif (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
-# define JSONCPP_DEPRECATED(message) __attribute__((__deprecated__))
-# endif // GNUC version
-#endif // __clang__ || __GNUC__
-
-#if !defined(JSONCPP_DEPRECATED)
-#define JSONCPP_DEPRECATED(message)
-#endif // if !defined(JSONCPP_DEPRECATED)
-
-namespace Json {
-typedef int Int;
-typedef unsigned int UInt;
-#if defined(JSON_NO_INT64)
-typedef int LargestInt;
-typedef unsigned int LargestUInt;
-#undef JSON_HAS_INT64
-#else // if defined(JSON_NO_INT64)
-// For Microsoft Visual use specific types as long long is not supported
-#if defined(_MSC_VER) // Microsoft Visual Studio
-typedef __int64 Int64;
-typedef unsigned __int64 UInt64;
-#else // if defined(_MSC_VER) // Other platforms, use long long
-typedef long long int Int64;
-typedef unsigned long long int UInt64;
-#endif // if defined(_MSC_VER)
-typedef Int64 LargestInt;
-typedef UInt64 LargestUInt;
-#define JSON_HAS_INT64
-#endif // if defined(JSON_NO_INT64)
-} // end namespace Json
-
-#endif // JSON_CONFIG_H_INCLUDED
-
-// //////////////////////////////////////////////////////////////////////
-// End of content of file: include/json/config.h
-// //////////////////////////////////////////////////////////////////////
-
-
-
-
-
-
-// //////////////////////////////////////////////////////////////////////
-// Beginning of content of file: include/json/forwards.h
-// //////////////////////////////////////////////////////////////////////
-
-// Copyright 2007-2010 Baptiste Lepilleur
-// Distributed under MIT license, or public domain if desired and
-// recognized in your jurisdiction.
-// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
-
-#ifndef JSON_FORWARDS_H_INCLUDED
-#define JSON_FORWARDS_H_INCLUDED
-
-#if !defined(JSON_IS_AMALGAMATION)
-#include "config.h"
-#endif // if !defined(JSON_IS_AMALGAMATION)
-
-namespace Json {
-
-// writer.h
-class FastWriter;
-class StyledWriter;
-
-// reader.h
-class Reader;
-
-// features.h
-class Features;
-
-// value.h
-typedef unsigned int ArrayIndex;
-class StaticString;
-class Path;
-class PathArgument;
-class Value;
-class ValueIteratorBase;
-class ValueIterator;
-class ValueConstIterator;
-
-} // namespace Json
-
-#endif // JSON_FORWARDS_H_INCLUDED
-
-// //////////////////////////////////////////////////////////////////////
-// End of content of file: include/json/forwards.h
-// //////////////////////////////////////////////////////////////////////
-
-
-
-
-
-
-// //////////////////////////////////////////////////////////////////////
-// Beginning of content of file: include/json/features.h
-// //////////////////////////////////////////////////////////////////////
-
-// Copyright 2007-2010 Baptiste Lepilleur
-// Distributed under MIT license, or public domain if desired and
-// recognized in your jurisdiction.
-// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
-
-#ifndef CPPTL_JSON_FEATURES_H_INCLUDED
-#define CPPTL_JSON_FEATURES_H_INCLUDED
-
-#if !defined(JSON_IS_AMALGAMATION)
-#include "forwards.h"
-#endif // if !defined(JSON_IS_AMALGAMATION)
-
-namespace Json {
-
-/** \brief Configuration passed to reader and writer.
- * This configuration object can be used to force the Reader or Writer
- * to behave in a standard conforming way.
- */
-class JSON_API Features {
-public:
- /** \brief A configuration that allows all features and assumes all strings
- * are UTF-8.
- * - C & C++ comments are allowed
- * - Root object can be any JSON value
- * - Assumes Value strings are encoded in UTF-8
- */
- static Features all();
-
- /** \brief A configuration that is strictly compatible with the JSON
- * specification.
- * - Comments are forbidden.
- * - Root object must be either an array or an object value.
- * - Assumes Value strings are encoded in UTF-8
- */
- static Features strictMode();
-
- /** \brief Initialize the configuration like JsonConfig::allFeatures;
- */
- Features();
-
- /// \c true if comments are allowed. Default: \c true.
- bool allowComments_;
-
- /// \c true if root must be either an array or an object value. Default: \c
- /// false.
- bool strictRoot_;
-
- /// \c true if dropped null placeholders are allowed. Default: \c false.
- bool allowDroppedNullPlaceholders_;
-
- /// \c true if numeric object key are allowed. Default: \c false.
- bool allowNumericKeys_;
-};
-
-} // namespace Json
-
-#endif // CPPTL_JSON_FEATURES_H_INCLUDED
-
-// //////////////////////////////////////////////////////////////////////
-// End of content of file: include/json/features.h
-// //////////////////////////////////////////////////////////////////////
-
-
-
-
-
-
-// //////////////////////////////////////////////////////////////////////
-// Beginning of content of file: include/json/value.h
-// //////////////////////////////////////////////////////////////////////
-
-// Copyright 2007-2010 Baptiste Lepilleur
-// Distributed under MIT license, or public domain if desired and
-// recognized in your jurisdiction.
-// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
-
-#ifndef CPPTL_JSON_H_INCLUDED
-#define CPPTL_JSON_H_INCLUDED
-
-#if !defined(JSON_IS_AMALGAMATION)
-#include "forwards.h"
-#endif // if !defined(JSON_IS_AMALGAMATION)
-#include <string>
-#include <vector>
-#include <exception>
-
-#ifndef JSON_USE_CPPTL_SMALLMAP
-#include <map>
-#else
-#include <cpptl/smallmap.h>
-#endif
-#ifdef JSON_USE_CPPTL
-#include <cpptl/forwards.h>
-#endif
-
-// Disable warning C4251: <data member>: <type> needs to have dll-interface to
-// be used by...
-#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
-#pragma warning(push)
-#pragma warning(disable : 4251)
-#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
-
-/** \brief JSON (JavaScript Object Notation).
- */
-namespace Json {
-
-/** Base class for all exceptions we throw.
- *
- * We use nothing but these internally. Of course, STL can throw others.
- */
-class JSON_API Exception : public std::exception {
-public:
- Exception(std::string const& msg);
- ~Exception() throw() override;
- char const* what() const throw() override;
-protected:
- std::string msg_;
-};
-
-/** Exceptions which the user cannot easily avoid.
- *
- * E.g. out-of-memory (when we use malloc), stack-overflow, malicious input
- *
- * \remark derived from Json::Exception
- */
-class JSON_API RuntimeError : public Exception {
-public:
- RuntimeError(std::string const& msg);
-};
-
-/** Exceptions thrown by JSON_ASSERT/JSON_FAIL macros.
- *
- * These are precondition-violations (user bugs) and internal errors (our bugs).
- *
- * \remark derived from Json::Exception
- */
-class JSON_API LogicError : public Exception {
-public:
- LogicError(std::string const& msg);
-};
-
-/// used internally
-void throwRuntimeError(std::string const& msg);
-/// used internally
-void throwLogicError(std::string const& msg);
-
-/** \brief Type of the value held by a Value object.
- */
-enum ValueType {
- nullValue = 0, ///< 'null' value
- intValue, ///< signed integer value
- uintValue, ///< unsigned integer value
- realValue, ///< double value
- stringValue, ///< UTF-8 string value
- booleanValue, ///< bool value
- arrayValue, ///< array value (ordered list)
- objectValue ///< object value (collection of name/value pairs).
-};
-
-enum CommentPlacement {
- commentBefore = 0, ///< a comment placed on the line before a value
- commentAfterOnSameLine, ///< a comment just after a value on the same line
- commentAfter, ///< a comment on the line after a value (only make sense for
- /// root value)
- numberOfCommentPlacement
-};
-
-//# ifdef JSON_USE_CPPTL
-// typedef CppTL::AnyEnumerator<const char *> EnumMemberNames;
-// typedef CppTL::AnyEnumerator<const Value &> EnumValues;
-//# endif
-
-/** \brief Lightweight wrapper to tag static string.
- *
- * Value constructor and objectValue member assignement takes advantage of the
- * StaticString and avoid the cost of string duplication when storing the
- * string or the member name.
- *
- * Example of usage:
- * \code
- * Json::Value aValue( StaticString("some text") );
- * Json::Value object;
- * static const StaticString code("code");
- * object[code] = 1234;
- * \endcode
- */
-class JSON_API StaticString {
-public:
- explicit StaticString(const char* czstring) : c_str_(czstring) {}
-
- operator const char*() const { return c_str_; }
-
- const char* c_str() const { return c_str_; }
-
-private:
- const char* c_str_;
-};
-
-/** \brief Represents a <a HREF="http://www.json.org">JSON</a> value.
- *
- * This class is a discriminated union wrapper that can represents a:
- * - signed integer [range: Value::minInt - Value::maxInt]
- * - unsigned integer (range: 0 - Value::maxUInt)
- * - double
- * - UTF-8 string
- * - boolean
- * - 'null'
- * - an ordered list of Value
- * - collection of name/value pairs (javascript object)
- *
- * The type of the held value is represented by a #ValueType and
- * can be obtained using type().
- *
- * Values of an #objectValue or #arrayValue can be accessed using operator[]()
- * methods.
- * Non-const methods will automatically create the a #nullValue element
- * if it does not exist.
- * The sequence of an #arrayValue will be automatically resized and initialized
- * with #nullValue. resize() can be used to enlarge or truncate an #arrayValue.
- *
- * The get() methods can be used to obtain default value in the case the
- * required element does not exist.
- *
- * It is possible to iterate over the list of a #objectValue values using
- * the getMemberNames() method.
- *
- * \note #Value string-length fit in size_t, but keys must be < 2^30.
- * (The reason is an implementation detail.) A #CharReader will raise an
- * exception if a bound is exceeded to avoid security holes in your app,
- * but the Value API does *not* check bounds. That is the responsibility
- * of the caller.
- */
-class JSON_API Value {
- friend class ValueIteratorBase;
-public:
- typedef std::vector<std::string> Members;
- typedef ValueIterator iterator;
- typedef ValueConstIterator const_iterator;
- typedef Json::UInt UInt;
- typedef Json::Int Int;
-#if defined(JSON_HAS_INT64)
- typedef Json::UInt64 UInt64;
- typedef Json::Int64 Int64;
-#endif // defined(JSON_HAS_INT64)
- typedef Json::LargestInt LargestInt;
- typedef Json::LargestUInt LargestUInt;
- typedef Json::ArrayIndex ArrayIndex;
-
- static const Value& null; ///< We regret this reference to a global instance; prefer the simpler Value().
- static const Value& nullRef; ///< just a kludge for binary-compatibility; same as null
- /// Minimum signed integer value that can be stored in a Json::Value.
- static const LargestInt minLargestInt;
- /// Maximum signed integer value that can be stored in a Json::Value.
- static const LargestInt maxLargestInt;
- /// Maximum unsigned integer value that can be stored in a Json::Value.
- static const LargestUInt maxLargestUInt;
-
- /// Minimum signed int value that can be stored in a Json::Value.
- static const Int minInt;
- /// Maximum signed int value that can be stored in a Json::Value.
- static const Int maxInt;
- /// Maximum unsigned int value that can be stored in a Json::Value.
- static const UInt maxUInt;
-
-#if defined(JSON_HAS_INT64)
- /// Minimum signed 64 bits int value that can be stored in a Json::Value.
- static const Int64 minInt64;
- /// Maximum signed 64 bits int value that can be stored in a Json::Value.
- static const Int64 maxInt64;
- /// Maximum unsigned 64 bits int value that can be stored in a Json::Value.
- static const UInt64 maxUInt64;
-#endif // defined(JSON_HAS_INT64)
-
-private:
-#ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
- class CZString {
- public:
- enum DuplicationPolicy {
- noDuplication = 0,
- duplicate,
- duplicateOnCopy
- };
- CZString(ArrayIndex index);
- CZString(char const* str, unsigned length, DuplicationPolicy allocate);
- CZString(CZString const& other);
-#if JSON_HAS_RVALUE_REFERENCES
- CZString(CZString&& other);
-#endif
- ~CZString();
- CZString& operator=(CZString other);
- bool operator<(CZString const& other) const;
- bool operator==(CZString const& other) const;
- ArrayIndex index() const;
- //const char* c_str() const; ///< \deprecated
- char const* data() const;
- unsigned length() const;
- bool isStaticString() const;
-
- private:
- void swap(CZString& other);
-
- struct StringStorage {
- unsigned policy_: 2;
- unsigned length_: 30; // 1GB max
- };
-
- char const* cstr_; // actually, a prefixed string, unless policy is noDup
- union {
- ArrayIndex index_;
- StringStorage storage_;
- };
- };
-
-public:
-#ifndef JSON_USE_CPPTL_SMALLMAP
- typedef std::map<CZString, Value> ObjectValues;
-#else
- typedef CppTL::SmallMap<CZString, Value> ObjectValues;
-#endif // ifndef JSON_USE_CPPTL_SMALLMAP
-#endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
-
-public:
- /** \brief Create a default Value of the given type.
-
- This is a very useful constructor.
- To create an empty array, pass arrayValue.
- To create an empty object, pass objectValue.
- Another Value can then be set to this one by assignment.
-This is useful since clear() and resize() will not alter types.
-
- Examples:
-\code
-Json::Value null_value; // null
-Json::Value arr_value(Json::arrayValue); // []
-Json::Value obj_value(Json::objectValue); // {}
-\endcode
- */
- Value(ValueType type = nullValue);
- Value(Int value);
- Value(UInt value);
-#if defined(JSON_HAS_INT64)
- Value(Int64 value);
- Value(UInt64 value);
-#endif // if defined(JSON_HAS_INT64)
- Value(double value);
- Value(const char* value); ///< Copy til first 0. (NULL causes to seg-fault.)
- Value(const char* begin, const char* end); ///< Copy all, incl zeroes.
- /** \brief Constructs a value from a static string.
-
- * Like other value string constructor but do not duplicate the string for
- * internal storage. The given string must remain alive after the call to this
- * constructor.
- * \note This works only for null-terminated strings. (We cannot change the
- * size of this class, so we have nowhere to store the length,
- * which might be computed later for various operations.)
- *
- * Example of usage:
- * \code
- * static StaticString foo("some text");
- * Json::Value aValue(foo);
- * \endcode
- */
- Value(const StaticString& value);
- Value(const std::string& value); ///< Copy data() til size(). Embedded zeroes too.
-#ifdef JSON_USE_CPPTL
- Value(const CppTL::ConstString& value);
-#endif
- Value(bool value);
- /// Deep copy.
- Value(const Value& other);
-#if JSON_HAS_RVALUE_REFERENCES
- /// Move constructor
- Value(Value&& other);
-#endif
- ~Value();
-
- /// Deep copy, then swap(other).
- /// \note Over-write existing comments. To preserve comments, use #swapPayload().
- Value& operator=(Value other);
- /// Swap everything.
- void swap(Value& other);
- /// Swap values but leave comments and source offsets in place.
- void swapPayload(Value& other);
-
- ValueType type() const;
-
- /// Compare payload only, not comments etc.
- bool operator<(const Value& other) const;
- bool operator<=(const Value& other) const;
- bool operator>=(const Value& other) const;
- bool operator>(const Value& other) const;
- bool operator==(const Value& other) const;
- bool operator!=(const Value& other) const;
- int compare(const Value& other) const;
-
- const char* asCString() const; ///< Embedded zeroes could cause you trouble!
- std::string asString() const; ///< Embedded zeroes are possible.
- /** Get raw char* of string-value.
- * \return false if !string. (Seg-fault if str or end are NULL.)
- */
- bool getString(
- char const** begin, char const** end) const;
-#ifdef JSON_USE_CPPTL
- CppTL::ConstString asConstString() const;
-#endif
- Int asInt() const;
- UInt asUInt() const;
-#if defined(JSON_HAS_INT64)
- Int64 asInt64() const;
- UInt64 asUInt64() const;
-#endif // if defined(JSON_HAS_INT64)
- LargestInt asLargestInt() const;
- LargestUInt asLargestUInt() const;
- float asFloat() const;
- double asDouble() const;
- bool asBool() const;
-
- bool isNull() const;
- bool isBool() const;
- bool isInt() const;
- bool isInt64() const;
- bool isUInt() const;
- bool isUInt64() const;
- bool isIntegral() const;
- bool isDouble() const;
- bool isNumeric() const;
- bool isString() const;
- bool isArray() const;
- bool isObject() const;
-
- bool isConvertibleTo(ValueType other) const;
-
- /// Number of values in array or object
- ArrayIndex size() const;
-
- /// \brief Return true if empty array, empty object, or null;
- /// otherwise, false.
- bool empty() const;
-
- /// Return isNull()
- bool operator!() const;
-
- /// Remove all object members and array elements.
- /// \pre type() is arrayValue, objectValue, or nullValue
- /// \post type() is unchanged
- void clear();
-
- /// Resize the array to size elements.
- /// New elements are initialized to null.
- /// May only be called on nullValue or arrayValue.
- /// \pre type() is arrayValue or nullValue
- /// \post type() is arrayValue
- void resize(ArrayIndex size);
-
- /// Access an array element (zero based index ).
- /// If the array contains less than index element, then null value are
- /// inserted
- /// in the array so that its size is index+1.
- /// (You may need to say 'value[0u]' to get your compiler to distinguish
- /// this from the operator[] which takes a string.)
- Value& operator[](ArrayIndex index);
-
- /// Access an array element (zero based index ).
- /// If the array contains less than index element, then null value are
- /// inserted
- /// in the array so that its size is index+1.
- /// (You may need to say 'value[0u]' to get your compiler to distinguish
- /// this from the operator[] which takes a string.)
- Value& operator[](int index);
-
- /// Access an array element (zero based index )
- /// (You may need to say 'value[0u]' to get your compiler to distinguish
- /// this from the operator[] which takes a string.)
- const Value& operator[](ArrayIndex index) const;
-
- /// Access an array element (zero based index )
- /// (You may need to say 'value[0u]' to get your compiler to distinguish
- /// this from the operator[] which takes a string.)
- const Value& operator[](int index) const;
-
- /// If the array contains at least index+1 elements, returns the element
- /// value,
- /// otherwise returns defaultValue.
- Value get(ArrayIndex index, const Value& defaultValue) const;
- /// Return true if index < size().
- bool isValidIndex(ArrayIndex index) const;
- /// \brief Append value to array at the end.
- ///
- /// Equivalent to jsonvalue[jsonvalue.size()] = value;
- Value& append(const Value& value);
-
- /// Access an object value by name, create a null member if it does not exist.
- /// \note Because of our implementation, keys are limited to 2^30 -1 chars.
- /// Exceeding that will cause an exception.
- Value& operator[](const char* key);
- /// Access an object value by name, returns null if there is no member with
- /// that name.
- const Value& operator[](const char* key) const;
- /// Access an object value by name, create a null member if it does not exist.
- /// \param key may contain embedded nulls.
- Value& operator[](const std::string& key);
- /// Access an object value by name, returns null if there is no member with
- /// that name.
- /// \param key may contain embedded nulls.
- const Value& operator[](const std::string& key) const;
- /** \brief Access an object value by name, create a null member if it does not
- exist.
-
- * If the object has no entry for that name, then the member name used to store
- * the new entry is not duplicated.
- * Example of use:
- * \code
- * Json::Value object;
- * static const StaticString code("code");
- * object[code] = 1234;
- * \endcode
- */
- Value& operator[](const StaticString& key);
-#ifdef JSON_USE_CPPTL
- /// Access an object value by name, create a null member if it does not exist.
- Value& operator[](const CppTL::ConstString& key);
- /// Access an object value by name, returns null if there is no member with
- /// that name.
- const Value& operator[](const CppTL::ConstString& key) const;
-#endif
- /// Return the member named key if it exist, defaultValue otherwise.
- /// \note deep copy
- Value get(const char* key, const Value& defaultValue) const;
- /// Return the member named key if it exist, defaultValue otherwise.
- /// \note deep copy
- /// \note key may contain embedded nulls.
- Value get(const char* begin, const char* end, const Value& defaultValue) const;
- /// Return the member named key if it exist, defaultValue otherwise.
- /// \note deep copy
- /// \param key may contain embedded nulls.
- Value get(const std::string& key, const Value& defaultValue) const;
-#ifdef JSON_USE_CPPTL
- /// Return the member named key if it exist, defaultValue otherwise.
- /// \note deep copy
- Value get(const CppTL::ConstString& key, const Value& defaultValue) const;
-#endif
- /// Most general and efficient version of isMember()const, get()const,
- /// and operator[]const
- /// \note As stated elsewhere, behavior is undefined if (end-begin) >= 2^30
- Value const* find(char const* begin, char const* end) const;
- /// Most general and efficient version of object-mutators.
- /// \note As stated elsewhere, behavior is undefined if (end-begin) >= 2^30
- /// \return non-zero, but JSON_ASSERT if this is neither object nor nullValue.
- Value const* demand(char const* begin, char const* end);
- /// \brief Remove and return the named member.
- ///
- /// Do nothing if it did not exist.
- /// \return the removed Value, or null.
- /// \pre type() is objectValue or nullValue
- /// \post type() is unchanged
- /// \deprecated
- Value removeMember(const char* key);
- /// Same as removeMember(const char*)
- /// \param key may contain embedded nulls.
- /// \deprecated
- Value removeMember(const std::string& key);
- /// Same as removeMember(const char* begin, const char* end, Value* removed),
- /// but 'key' is null-terminated.
- bool removeMember(const char* key, Value* removed);
- /** \brief Remove the named map member.
-
- Update 'removed' iff removed.
- \param key may contain embedded nulls.
- \return true iff removed (no exceptions)
- */
- bool removeMember(std::string const& key, Value* removed);
- /// Same as removeMember(std::string const& key, Value* removed)
- bool removeMember(const char* begin, const char* end, Value* removed);
- /** \brief Remove the indexed array element.
-
- O(n) expensive operations.
- Update 'removed' iff removed.
- \return true iff removed (no exceptions)
- */
- bool removeIndex(ArrayIndex i, Value* removed);
-
- /// Return true if the object has a member named key.
- /// \note 'key' must be null-terminated.
- bool isMember(const char* key) const;
- /// Return true if the object has a member named key.
- /// \param key may contain embedded nulls.
- bool isMember(const std::string& key) const;
- /// Same as isMember(std::string const& key)const
- bool isMember(const char* begin, const char* end) const;
-#ifdef JSON_USE_CPPTL
- /// Return true if the object has a member named key.
- bool isMember(const CppTL::ConstString& key) const;
-#endif
-
- /// \brief Return a list of the member names.
- ///
- /// If null, return an empty list.
- /// \pre type() is objectValue or nullValue
- /// \post if type() was nullValue, it remains nullValue
- Members getMemberNames() const;
-
- //# ifdef JSON_USE_CPPTL
- // EnumMemberNames enumMemberNames() const;
- // EnumValues enumValues() const;
- //# endif
-
- /// \deprecated Always pass len.
- JSONCPP_DEPRECATED("Use setComment(std::string const&) instead.")
- void setComment(const char* comment, CommentPlacement placement);
- /// Comments must be //... or /* ... */
- void setComment(const char* comment, size_t len, CommentPlacement placement);
- /// Comments must be //... or /* ... */
- void setComment(const std::string& comment, CommentPlacement placement);
- bool hasComment(CommentPlacement placement) const;
- /// Include delimiters and embedded newlines.
- std::string getComment(CommentPlacement placement) const;
-
- std::string toStyledString() const;
-
- const_iterator begin() const;
- const_iterator end() const;
-
- iterator begin();
- iterator end();
-
- // Accessors for the [start, limit) range of bytes within the JSON text from
- // which this value was parsed, if any.
- void setOffsetStart(size_t start);
- void setOffsetLimit(size_t limit);
- size_t getOffsetStart() const;
- size_t getOffsetLimit() const;
-
-private:
- void initBasic(ValueType type, bool allocated = false);
-
- Value& resolveReference(const char* key);
- Value& resolveReference(const char* key, const char* end);
-
- struct CommentInfo {
- CommentInfo();
- ~CommentInfo();
-
- void setComment(const char* text, size_t len);
-
- char* comment_;
- };
-
- // struct MemberNamesTransform
- //{
- // typedef const char *result_type;
- // const char *operator()( const CZString &name ) const
- // {
- // return name.c_str();
- // }
- //};
-
- union ValueHolder {
- LargestInt int_;
- LargestUInt uint_;
- double real_;
- bool bool_;
- char* string_; // actually ptr to unsigned, followed by str, unless !allocated_
- ObjectValues* map_;
- } value_;
- ValueType type_ : 8;
- unsigned int allocated_ : 1; // Notes: if declared as bool, bitfield is useless.
- // If not allocated_, string_ must be null-terminated.
- CommentInfo* comments_;
-
- // [start, limit) byte offsets in the source JSON text from which this Value
- // was extracted.
- size_t start_;
- size_t limit_;
-};
-
-/** \brief Experimental and untested: represents an element of the "path" to
- * access a node.
- */
-class JSON_API PathArgument {
-public:
- friend class Path;
-
- PathArgument();
- PathArgument(ArrayIndex index);
- PathArgument(const char* key);
- PathArgument(const std::string& key);
-
-private:
- enum Kind {
- kindNone = 0,
- kindIndex,
- kindKey
- };
- std::string key_;
- ArrayIndex index_;
- Kind kind_;
-};
-
-/** \brief Experimental and untested: represents a "path" to access a node.
- *
- * Syntax:
- * - "." => root node
- * - ".[n]" => elements at index 'n' of root node (an array value)
- * - ".name" => member named 'name' of root node (an object value)
- * - ".name1.name2.name3"
- * - ".[0][1][2].name1[3]"
- * - ".%" => member name is provided as parameter
- * - ".[%]" => index is provied as parameter
- */
-class JSON_API Path {
-public:
- Path(const std::string& path,
- const PathArgument& a1 = PathArgument(),
- const PathArgument& a2 = PathArgument(),
- const PathArgument& a3 = PathArgument(),
- const PathArgument& a4 = PathArgument(),
- const PathArgument& a5 = PathArgument());
-
- const Value& resolve(const Value& root) const;
- Value resolve(const Value& root, const Value& defaultValue) const;
- /// Creates the "path" to access the specified node and returns a reference on
- /// the node.
- Value& make(Value& root) const;
-
-private:
- typedef std::vector<const PathArgument*> InArgs;
- typedef std::vector<PathArgument> Args;
-
- void makePath(const std::string& path, const InArgs& in);
- void addPathInArg(const std::string& path,
- const InArgs& in,
- InArgs::const_iterator& itInArg,
- PathArgument::Kind kind);
- void invalidPath(const std::string& path, int location);
-
- Args args_;
-};
-
-/** \brief base class for Value iterators.
- *
- */
-class JSON_API ValueIteratorBase {
-public:
- typedef std::bidirectional_iterator_tag iterator_category;
- typedef unsigned int size_t;
- typedef int difference_type;
- typedef ValueIteratorBase SelfType;
-
- bool operator==(const SelfType& other) const { return isEqual(other); }
-
- bool operator!=(const SelfType& other) const { return !isEqual(other); }
-
- difference_type operator-(const SelfType& other) const {
- return other.computeDistance(*this);
- }
-
- /// Return either the index or the member name of the referenced value as a
- /// Value.
- Value key() const;
-
- /// Return the index of the referenced Value, or -1 if it is not an arrayValue.
- UInt index() const;
-
- /// Return the member name of the referenced Value, or "" if it is not an
- /// objectValue.
- /// \note Avoid `c_str()` on result, as embedded zeroes are possible.
- std::string name() const;
-
- /// Return the member name of the referenced Value. "" if it is not an
- /// objectValue.
- /// \deprecated This cannot be used for UTF-8 strings, since there can be embedded nulls.
- JSONCPP_DEPRECATED("Use `key = name();` instead.")
- char const* memberName() const;
- /// Return the member name of the referenced Value, or NULL if it is not an
- /// objectValue.
- /// \note Better version than memberName(). Allows embedded nulls.
- char const* memberName(char const** end) const;
-
-protected:
- Value& deref() const;
-
- void increment();
-
- void decrement();
-
- difference_type computeDistance(const SelfType& other) const;
-
- bool isEqual(const SelfType& other) const;
-
- void copy(const SelfType& other);
-
-private:
- Value::ObjectValues::iterator current_;
- // Indicates that iterator is for a null value.
- bool isNull_;
-
-public:
- // For some reason, BORLAND needs these at the end, rather
- // than earlier. No idea why.
- ValueIteratorBase();
- explicit ValueIteratorBase(const Value::ObjectValues::iterator& current);
-};
-
-/** \brief const iterator for object and array value.
- *
- */
-class JSON_API ValueConstIterator : public ValueIteratorBase {
- friend class Value;
-
-public:
- typedef const Value value_type;
- //typedef unsigned int size_t;
- //typedef int difference_type;
- typedef const Value& reference;
- typedef const Value* pointer;
- typedef ValueConstIterator SelfType;
-
- ValueConstIterator();
- ValueConstIterator(ValueIterator const& other);
-
-private:
-/*! \internal Use by Value to create an iterator.
- */
- explicit ValueConstIterator(const Value::ObjectValues::iterator& current);
-public:
- SelfType& operator=(const ValueIteratorBase& other);
-
- SelfType operator++(int) {
- SelfType temp(*this);
- ++*this;
- return temp;
- }
-
- SelfType operator--(int) {
- SelfType temp(*this);
- --*this;
- return temp;
- }
-
- SelfType& operator--() {
- decrement();
- return *this;
- }
-
- SelfType& operator++() {
- increment();
- return *this;
- }
-
- reference operator*() const { return deref(); }
-
- pointer operator->() const { return &deref(); }
-};
-
-/** \brief Iterator for object and array value.
- */
-class JSON_API ValueIterator : public ValueIteratorBase {
- friend class Value;
-
-public:
- typedef Value value_type;
- typedef unsigned int size_t;
- typedef int difference_type;
- typedef Value& reference;
- typedef Value* pointer;
- typedef ValueIterator SelfType;
-
- ValueIterator();
- explicit ValueIterator(const ValueConstIterator& other);
- ValueIterator(const ValueIterator& other);
-
-private:
-/*! \internal Use by Value to create an iterator.
- */
- explicit ValueIterator(const Value::ObjectValues::iterator& current);
-public:
- SelfType& operator=(const SelfType& other);
-
- SelfType operator++(int) {
- SelfType temp(*this);
- ++*this;
- return temp;
- }
-
- SelfType operator--(int) {
- SelfType temp(*this);
- --*this;
- return temp;
- }
-
- SelfType& operator--() {
- decrement();
- return *this;
- }
-
- SelfType& operator++() {
- increment();
- return *this;
- }
-
- reference operator*() const { return deref(); }
-
- pointer operator->() const { return &deref(); }
-};
-
-} // namespace Json
-
-
-namespace std {
-/// Specialize std::swap() for Json::Value.
-template<>
-inline void swap(Json::Value& a, Json::Value& b) { a.swap(b); }
-}
-
-
-#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
-#pragma warning(pop)
-#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
-
-#endif // CPPTL_JSON_H_INCLUDED
-
-// //////////////////////////////////////////////////////////////////////
-// End of content of file: include/json/value.h
-// //////////////////////////////////////////////////////////////////////
-
-
-
-
-
-
-// //////////////////////////////////////////////////////////////////////
-// Beginning of content of file: include/json/reader.h
-// //////////////////////////////////////////////////////////////////////
-
-// Copyright 2007-2010 Baptiste Lepilleur
-// Distributed under MIT license, or public domain if desired and
-// recognized in your jurisdiction.
-// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
-
-#ifndef CPPTL_JSON_READER_H_INCLUDED
-#define CPPTL_JSON_READER_H_INCLUDED
-
-#if !defined(JSON_IS_AMALGAMATION)
-#include "features.h"
-#include "value.h"
-#endif // if !defined(JSON_IS_AMALGAMATION)
-#include <deque>
-#include <iosfwd>
-#include <stack>
-#include <string>
-#include <istream>
-
-// Disable warning C4251: <data member>: <type> needs to have dll-interface to
-// be used by...
-#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
-#pragma warning(push)
-#pragma warning(disable : 4251)
-#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
-
-namespace Json {
-
-/** \brief Unserialize a <a HREF="http://www.json.org">JSON</a> document into a
- *Value.
- *
- * \deprecated Use CharReader and CharReaderBuilder.
- */
-class JSON_API Reader {
-public:
- typedef char Char;
- typedef const Char* Location;
-
- /** \brief An error tagged with where in the JSON text it was encountered.
- *
- * The offsets give the [start, limit) range of bytes within the text. Note
- * that this is bytes, not codepoints.
- *
- */
- struct StructuredError {
- size_t offset_start;
- size_t offset_limit;
- std::string message;
- };
-
- /** \brief Constructs a Reader allowing all features
- * for parsing.
- */
- Reader();
-
- /** \brief Constructs a Reader allowing the specified feature set
- * for parsing.
- */
- Reader(const Features& features);
-
- /** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a>
- * document.
- * \param document UTF-8 encoded string containing the document to read.
- * \param root [out] Contains the root value of the document if it was
- * successfully parsed.
- * \param collectComments \c true to collect comment and allow writing them
- * back during
- * serialization, \c false to discard comments.
- * This parameter is ignored if
- * Features::allowComments_
- * is \c false.
- * \return \c true if the document was successfully parsed, \c false if an
- * error occurred.
- */
- bool
- parse(const std::string& document, Value& root, bool collectComments = true);
-
- /** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a>
- document.
- * \param beginDoc Pointer on the beginning of the UTF-8 encoded string of the
- document to read.
- * \param endDoc Pointer on the end of the UTF-8 encoded string of the
- document to read.
- * Must be >= beginDoc.
- * \param root [out] Contains the root value of the document if it was
- * successfully parsed.
- * \param collectComments \c true to collect comment and allow writing them
- back during
- * serialization, \c false to discard comments.
- * This parameter is ignored if
- Features::allowComments_
- * is \c false.
- * \return \c true if the document was successfully parsed, \c false if an
- error occurred.
- */
- bool parse(const char* beginDoc,
- const char* endDoc,
- Value& root,
- bool collectComments = true);
-
- /// \brief Parse from input stream.
- /// \see Json::operator>>(std::istream&, Json::Value&).
- bool parse(std::istream& is, Value& root, bool collectComments = true);
-
- /** \brief Returns a user friendly string that list errors in the parsed
- * document.
- * \return Formatted error message with the list of errors with their location
- * in
- * the parsed document. An empty string is returned if no error
- * occurred
- * during parsing.
- * \deprecated Use getFormattedErrorMessages() instead (typo fix).
- */
- JSONCPP_DEPRECATED("Use getFormattedErrorMessages() instead.")
- std::string getFormatedErrorMessages() const;
-
- /** \brief Returns a user friendly string that list errors in the parsed
- * document.
- * \return Formatted error message with the list of errors with their location
- * in
- * the parsed document. An empty string is returned if no error
- * occurred
- * during parsing.
- */
- std::string getFormattedErrorMessages() const;
-
- /** \brief Returns a vector of structured erros encounted while parsing.
- * \return A (possibly empty) vector of StructuredError objects. Currently
- * only one error can be returned, but the caller should tolerate
- * multiple
- * errors. This can occur if the parser recovers from a non-fatal
- * parse error and then encounters additional errors.
- */
- std::vector<StructuredError> getStructuredErrors() const;
-
- /** \brief Add a semantic error message.
- * \param value JSON Value location associated with the error
- * \param message The error message.
- * \return \c true if the error was successfully added, \c false if the
- * Value offset exceeds the document size.
- */
- bool pushError(const Value& value, const std::string& message);
-
- /** \brief Add a semantic error message with extra context.
- * \param value JSON Value location associated with the error
- * \param message The error message.
- * \param extra Additional JSON Value location to contextualize the error
- * \return \c true if the error was successfully added, \c false if either
- * Value offset exceeds the document size.
- */
- bool pushError(const Value& value, const std::string& message, const Value& extra);
-
- /** \brief Return whether there are any errors.
- * \return \c true if there are no errors to report \c false if
- * errors have occurred.
- */
- bool good() const;
-
-private:
- enum TokenType {
- tokenEndOfStream = 0,
- tokenObjectBegin,
- tokenObjectEnd,
- tokenArrayBegin,
- tokenArrayEnd,
- tokenString,
- tokenNumber,
- tokenTrue,
- tokenFalse,
- tokenNull,
- tokenArraySeparator,
- tokenMemberSeparator,
- tokenComment,
- tokenError
- };
-
- class Token {
- public:
- TokenType type_;
- Location start_;
- Location end_;
- };
-
- class ErrorInfo {
- public:
- Token token_;
- std::string message_;
- Location extra_;
- };
-
- typedef std::deque<ErrorInfo> Errors;
-
- bool readToken(Token& token);
- void skipSpaces();
- bool match(Location pattern, int patternLength);
- bool readComment();
- bool readCStyleComment();
- bool readCppStyleComment();
- bool readString();
- void readNumber();
- bool readValue();
- bool readObject(Token& token);
- bool readArray(Token& token);
- bool decodeNumber(Token& token);
- bool decodeNumber(Token& token, Value& decoded);
- bool decodeString(Token& token);
- bool decodeString(Token& token, std::string& decoded);
- bool decodeDouble(Token& token);
- bool decodeDouble(Token& token, Value& decoded);
- bool decodeUnicodeCodePoint(Token& token,
- Location& current,
- Location end,
- unsigned int& unicode);
- bool decodeUnicodeEscapeSequence(Token& token,
- Location& current,
- Location end,
- unsigned int& unicode);
- bool addError(const std::string& message, Token& token, Location extra = 0);
- bool recoverFromError(TokenType skipUntilToken);
- bool addErrorAndRecover(const std::string& message,
- Token& token,
- TokenType skipUntilToken);
- void skipUntilSpace();
- Value& currentValue();
- Char getNextChar();
- void
- getLocationLineAndColumn(Location location, int& line, int& column) const;
- std::string getLocationLineAndColumn(Location location) const;
- void addComment(Location begin, Location end, CommentPlacement placement);
- void skipCommentTokens(Token& token);
-
- typedef std::stack<Value*> Nodes;
- Nodes nodes_;
- Errors errors_;
- std::string document_;
- Location begin_;
- Location end_;
- Location current_;
- Location lastValueEnd_;
- Value* lastValue_;
- std::string commentsBefore_;
- Features features_;
- bool collectComments_;
-}; // Reader
-
-/** Interface for reading JSON from a char array.
- */
-class JSON_API CharReader {
-public:
- virtual ~CharReader() {}
- /** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a>
- document.
- * The document must be a UTF-8 encoded string containing the document to read.
- *
- * \param beginDoc Pointer on the beginning of the UTF-8 encoded string of the
- document to read.
- * \param endDoc Pointer on the end of the UTF-8 encoded string of the
- document to read.
- * Must be >= beginDoc.
- * \param root [out] Contains the root value of the document if it was
- * successfully parsed.
- * \param errs [out] Formatted error messages (if not NULL)
- * a user friendly string that lists errors in the parsed
- * document.
- * \return \c true if the document was successfully parsed, \c false if an
- error occurred.
- */
- virtual bool parse(
- char const* beginDoc, char const* endDoc,
- Value* root, std::string* errs) = 0;
-
- class JSON_API Factory {
- public:
- virtual ~Factory() {}
- /** \brief Allocate a CharReader via operator new().
- * \throw std::exception if something goes wrong (e.g. invalid settings)
- */
- virtual CharReader* newCharReader() const = 0;
- }; // Factory
-}; // CharReader
-
-/** \brief Build a CharReader implementation.
-
-Usage:
-\code
- using namespace Json;
- CharReaderBuilder builder;
- builder["collectComments"] = false;
- Value value;
- std::string errs;
- bool ok = parseFromStream(builder, std::cin, &value, &errs);
-\endcode
-*/
-class JSON_API CharReaderBuilder : public CharReader::Factory {
-public:
- // Note: We use a Json::Value so that we can add data-members to this class
- // without a major version bump.
- /** Configuration of this builder.
- These are case-sensitive.
- Available settings (case-sensitive):
- - `"collectComments": false or true`
- - true to collect comment and allow writing them
- back during serialization, false to discard comments.
- This parameter is ignored if allowComments is false.
- - `"allowComments": false or true`
- - true if comments are allowed.
- - `"strictRoot": false or true`
- - true if root must be either an array or an object value
- - `"allowDroppedNullPlaceholders": false or true`
- - true if dropped null placeholders are allowed. (See StreamWriterBuilder.)
- - `"allowNumericKeys": false or true`
- - true if numeric object keys are allowed.
- - `"allowSingleQuotes": false or true`
- - true if '' are allowed for strings (both keys and values)
- - `"stackLimit": integer`
- - Exceeding stackLimit (recursive depth of `readValue()`) will
- cause an exception.
- - This is a security issue (seg-faults caused by deeply nested JSON),
- so the default is low.
- - `"failIfExtra": false or true`
- - If true, `parse()` returns false when extra non-whitespace trails
- the JSON value in the input string.
- - `"rejectDupKeys": false or true`
- - If true, `parse()` returns false when a key is duplicated within an object.
- - `"allowSpecialFloats": false or true`
- - If true, special float values (NaNs and infinities) are allowed
- and their values are lossfree restorable.
-
- You can examine 'settings_` yourself
- to see the defaults. You can also write and read them just like any
- JSON Value.
- \sa setDefaults()
- */
- Json::Value settings_;
-
- CharReaderBuilder();
- ~CharReaderBuilder() override;
-
- CharReader* newCharReader() const override;
-
- /** \return true if 'settings' are legal and consistent;
- * otherwise, indicate bad settings via 'invalid'.
- */
- bool validate(Json::Value* invalid) const;
-
- /** A simple way to update a specific setting.
- */
- Value& operator[](std::string key);
-
- /** Called by ctor, but you can use this to reset settings_.
- * \pre 'settings' != NULL (but Json::null is fine)
- * \remark Defaults:
- * \snippet src/lib_json/json_reader.cpp CharReaderBuilderDefaults
- */
- static void setDefaults(Json::Value* settings);
- /** Same as old Features::strictMode().
- * \pre 'settings' != NULL (but Json::null is fine)
- * \remark Defaults:
- * \snippet src/lib_json/json_reader.cpp CharReaderBuilderStrictMode
- */
- static void strictMode(Json::Value* settings);
-};
-
-/** Consume entire stream and use its begin/end.
- * Someday we might have a real StreamReader, but for now this
- * is convenient.
- */
-bool JSON_API parseFromStream(
- CharReader::Factory const&,
- std::istream&,
- Value* root, std::string* errs);
-
-/** \brief Read from 'sin' into 'root'.
-
- Always keep comments from the input JSON.
-
- This can be used to read a file into a particular sub-object.
- For example:
- \code
- Json::Value root;
- cin >> root["dir"]["file"];
- cout << root;
- \endcode
- Result:
- \verbatim
- {
- "dir": {
- "file": {
- // The input stream JSON would be nested here.
- }
- }
- }
- \endverbatim
- \throw std::exception on parse error.
- \see Json::operator<<()
-*/
-JSON_API std::istream& operator>>(std::istream&, Value&);
-
-} // namespace Json
-
-#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
-#pragma warning(pop)
-#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
-
-#endif // CPPTL_JSON_READER_H_INCLUDED
-
-// //////////////////////////////////////////////////////////////////////
-// End of content of file: include/json/reader.h
-// //////////////////////////////////////////////////////////////////////
-
-
-
-
-
-
-// //////////////////////////////////////////////////////////////////////
-// Beginning of content of file: include/json/writer.h
-// //////////////////////////////////////////////////////////////////////
-
-// Copyright 2007-2010 Baptiste Lepilleur
-// Distributed under MIT license, or public domain if desired and
-// recognized in your jurisdiction.
-// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
-
-#ifndef JSON_WRITER_H_INCLUDED
-#define JSON_WRITER_H_INCLUDED
-
-#if !defined(JSON_IS_AMALGAMATION)
-#include "value.h"
-#endif // if !defined(JSON_IS_AMALGAMATION)
-#include <vector>
-#include <string>
-#include <ostream>
-
-// Disable warning C4251: <data member>: <type> needs to have dll-interface to
-// be used by...
-#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
-#pragma warning(push)
-#pragma warning(disable : 4251)
-#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
-
-namespace Json {
-
-class Value;
-
-/**
-
-Usage:
-\code
- using namespace Json;
- void writeToStdout(StreamWriter::Factory const& factory, Value const& value) {
- std::unique_ptr<StreamWriter> const writer(
- factory.newStreamWriter());
- writer->write(value, &std::cout);
- std::cout << std::endl; // add lf and flush
- }
-\endcode
-*/
-class JSON_API StreamWriter {
-protected:
- std::ostream* sout_; // not owned; will not delete
-public:
- StreamWriter();
- virtual ~StreamWriter();
- /** Write Value into document as configured in sub-class.
- Do not take ownership of sout, but maintain a reference during function.
- \pre sout != NULL
- \return zero on success (For now, we always return zero, so check the stream instead.)
- \throw std::exception possibly, depending on configuration
- */
- virtual int write(Value const& root, std::ostream* sout) = 0;
-
- /** \brief A simple abstract factory.
- */
- class JSON_API Factory {
- public:
- virtual ~Factory();
- /** \brief Allocate a CharReader via operator new().
- * \throw std::exception if something goes wrong (e.g. invalid settings)
- */
- virtual StreamWriter* newStreamWriter() const = 0;
- }; // Factory
-}; // StreamWriter
-
-/** \brief Write into stringstream, then return string, for convenience.
- * A StreamWriter will be created from the factory, used, and then deleted.
- */
-std::string JSON_API writeString(StreamWriter::Factory const& factory, Value const& root);
-
-
-/** \brief Build a StreamWriter implementation.
-
-Usage:
-\code
- using namespace Json;
- Value value = ...;
- StreamWriterBuilder builder;
- builder["commentStyle"] = "None";
- builder["indentation"] = " "; // or whatever you like
- std::unique_ptr<Json::StreamWriter> writer(
- builder.newStreamWriter());
- writer->write(value, &std::cout);
- std::cout << std::endl; // add lf and flush
-\endcode
-*/
-class JSON_API StreamWriterBuilder : public StreamWriter::Factory {
-public:
- // Note: We use a Json::Value so that we can add data-members to this class
- // without a major version bump.
- /** Configuration of this builder.
- Available settings (case-sensitive):
- - "commentStyle": "None" or "All"
- - "indentation": "<anything>"
- - "enableYAMLCompatibility": false or true
- - slightly change the whitespace around colons
- - "dropNullPlaceholders": false or true
- - Drop the "null" string from the writer's output for nullValues.
- Strictly speaking, this is not valid JSON. But when the output is being
- fed to a browser's Javascript, it makes for smaller output and the
- browser can handle the output just fine.
- - "useSpecialFloats": false or true
- - If true, outputs non-finite floating point values in the following way:
- NaN values as "NaN", positive infinity as "Infinity", and negative infinity
- as "-Infinity".
-
- You can examine 'settings_` yourself
- to see the defaults. You can also write and read them just like any
- JSON Value.
- \sa setDefaults()
- */
- Json::Value settings_;
-
- StreamWriterBuilder();
- ~StreamWriterBuilder() override;
-
- /**
- * \throw std::exception if something goes wrong (e.g. invalid settings)
- */
- StreamWriter* newStreamWriter() const override;
-
- /** \return true if 'settings' are legal and consistent;
- * otherwise, indicate bad settings via 'invalid'.
- */
- bool validate(Json::Value* invalid) const;
- /** A simple way to update a specific setting.
- */
- Value& operator[](std::string key);
-
- /** Called by ctor, but you can use this to reset settings_.
- * \pre 'settings' != NULL (but Json::null is fine)
- * \remark Defaults:
- * \snippet src/lib_json/json_writer.cpp StreamWriterBuilderDefaults
- */
- static void setDefaults(Json::Value* settings);
-};
-
-/** \brief Abstract class for writers.
- * \deprecated Use StreamWriter. (And really, this is an implementation detail.)
- */
-class JSON_API Writer {
-public:
- virtual ~Writer();
-
- virtual std::string write(const Value& root) = 0;
-};
-
-/** \brief Outputs a Value in <a HREF="http://www.json.org">JSON</a> format
- *without formatting (not human friendly).
- *
- * The JSON document is written in a single line. It is not intended for 'human'
- *consumption,
- * but may be usefull to support feature such as RPC where bandwith is limited.
- * \sa Reader, Value
- * \deprecated Use StreamWriterBuilder.
- */
-class JSON_API FastWriter : public Writer {
-
-public:
- FastWriter();
- ~FastWriter() override {}
-
- void enableYAMLCompatibility();
-
- /** \brief Drop the "null" string from the writer's output for nullValues.
- * Strictly speaking, this is not valid JSON. But when the output is being
- * fed to a browser's Javascript, it makes for smaller output and the
- * browser can handle the output just fine.
- */
- void dropNullPlaceholders();
-
- void omitEndingLineFeed();
-
-public: // overridden from Writer
- std::string write(const Value& root) override;
-
-private:
- void writeValue(const Value& value);
-
- std::string document_;
- bool yamlCompatiblityEnabled_;
- bool dropNullPlaceholders_;
- bool omitEndingLineFeed_;
-};
-
-/** \brief Writes a Value in <a HREF="http://www.json.org">JSON</a> format in a
- *human friendly way.
- *
- * The rules for line break and indent are as follow:
- * - Object value:
- * - if empty then print {} without indent and line break
- * - if not empty the print '{', line break & indent, print one value per
- *line
- * and then unindent and line break and print '}'.
- * - Array value:
- * - if empty then print [] without indent and line break
- * - if the array contains no object value, empty array or some other value
- *types,
- * and all the values fit on one lines, then print the array on a single
- *line.
- * - otherwise, it the values do not fit on one line, or the array contains
- * object or non empty array, then print one value per line.
- *
- * If the Value have comments then they are outputed according to their
- *#CommentPlacement.
- *
- * \sa Reader, Value, Value::setComment()
- * \deprecated Use StreamWriterBuilder.
- */
-class JSON_API StyledWriter : public Writer {
-public:
- StyledWriter();
- ~StyledWriter() override {}
-
-public: // overridden from Writer
- /** \brief Serialize a Value in <a HREF="http://www.json.org">JSON</a> format.
- * \param root Value to serialize.
- * \return String containing the JSON document that represents the root value.
- */
- std::string write(const Value& root) override;
-
-private:
- void writeValue(const Value& value);
- void writeArrayValue(const Value& value);
- bool isMultineArray(const Value& value);
- void pushValue(const std::string& value);
- void writeIndent();
- void writeWithIndent(const std::string& value);
- void indent();
- void unindent();
- void writeCommentBeforeValue(const Value& root);
- void writeCommentAfterValueOnSameLine(const Value& root);
- bool hasCommentForValue(const Value& value);
- static std::string normalizeEOL(const std::string& text);
-
- typedef std::vector<std::string> ChildValues;
-
- ChildValues childValues_;
- std::string document_;
- std::string indentString_;
- int rightMargin_;
- int indentSize_;
- bool addChildValues_;
-};
-
-/** \brief Writes a Value in <a HREF="http://www.json.org">JSON</a> format in a
- human friendly way,
- to a stream rather than to a string.
- *
- * The rules for line break and indent are as follow:
- * - Object value:
- * - if empty then print {} without indent and line break
- * - if not empty the print '{', line break & indent, print one value per
- line
- * and then unindent and line break and print '}'.
- * - Array value:
- * - if empty then print [] without indent and line break
- * - if the array contains no object value, empty array or some other value
- types,
- * and all the values fit on one lines, then print the array on a single
- line.
- * - otherwise, it the values do not fit on one line, or the array contains
- * object or non empty array, then print one value per line.
- *
- * If the Value have comments then they are outputed according to their
- #CommentPlacement.
- *
- * \param indentation Each level will be indented by this amount extra.
- * \sa Reader, Value, Value::setComment()
- * \deprecated Use StreamWriterBuilder.
- */
-class JSON_API StyledStreamWriter {
-public:
- StyledStreamWriter(std::string indentation = "\t");
- ~StyledStreamWriter() {}
-
-public:
- /** \brief Serialize a Value in <a HREF="http://www.json.org">JSON</a> format.
- * \param out Stream to write to. (Can be ostringstream, e.g.)
- * \param root Value to serialize.
- * \note There is no point in deriving from Writer, since write() should not
- * return a value.
- */
- void write(std::ostream& out, const Value& root);
-
-private:
- void writeValue(const Value& value);
- void writeArrayValue(const Value& value);
- bool isMultineArray(const Value& value);
- void pushValue(const std::string& value);
- void writeIndent();
- void writeWithIndent(const std::string& value);
- void indent();
- void unindent();
- void writeCommentBeforeValue(const Value& root);
- void writeCommentAfterValueOnSameLine(const Value& root);
- bool hasCommentForValue(const Value& value);
- static std::string normalizeEOL(const std::string& text);
-
- typedef std::vector<std::string> ChildValues;
-
- ChildValues childValues_;
- std::ostream* document_;
- std::string indentString_;
- int rightMargin_;
- std::string indentation_;
- bool addChildValues_ : 1;
- bool indented_ : 1;
-};
-
-#if defined(JSON_HAS_INT64)
-std::string JSON_API valueToString(Int value);
-std::string JSON_API valueToString(UInt value);
-#endif // if defined(JSON_HAS_INT64)
-std::string JSON_API valueToString(LargestInt value);
-std::string JSON_API valueToString(LargestUInt value);
-std::string JSON_API valueToString(double value);
-std::string JSON_API valueToString(bool value);
-std::string JSON_API valueToQuotedString(const char* value);
-
-/// \brief Output using the StyledStreamWriter.
-/// \see Json::operator>>()
-JSON_API std::ostream& operator<<(std::ostream&, const Value& root);
-
-} // namespace Json
-
-#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
-#pragma warning(pop)
-#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
-
-#endif // JSON_WRITER_H_INCLUDED
-
-// //////////////////////////////////////////////////////////////////////
-// End of content of file: include/json/writer.h
-// //////////////////////////////////////////////////////////////////////
-
-
-
-
-
-
-// //////////////////////////////////////////////////////////////////////
-// Beginning of content of file: include/json/assertions.h
-// //////////////////////////////////////////////////////////////////////
-
-// Copyright 2007-2010 Baptiste Lepilleur
-// Distributed under MIT license, or public domain if desired and
-// recognized in your jurisdiction.
-// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
-
-#ifndef CPPTL_JSON_ASSERTIONS_H_INCLUDED
-#define CPPTL_JSON_ASSERTIONS_H_INCLUDED
-
-#include <stdlib.h>
-#include <sstream>
-
-#if !defined(JSON_IS_AMALGAMATION)
-#include "config.h"
-#endif // if !defined(JSON_IS_AMALGAMATION)
-
-/** It should not be possible for a maliciously designed file to
- * cause an abort() or seg-fault, so these macros are used only
- * for pre-condition violations and internal logic errors.
- */
-#if JSON_USE_EXCEPTION
-
-// @todo <= add detail about condition in exception
-# define JSON_ASSERT(condition) \
- {if (!(condition)) {Json::throwLogicError( "assert json failed" );}}
-
-# define JSON_FAIL_MESSAGE(message) \
- { \
- std::ostringstream oss; oss << message; \
- Json::throwLogicError(oss.str()); \
- abort(); \
- }
-
-#else // JSON_USE_EXCEPTION
-
-# define JSON_ASSERT(condition) assert(condition)
-
-// The call to assert() will show the failure message in debug builds. In
-// release builds we abort, for a core-dump or debugger.
-# define JSON_FAIL_MESSAGE(message) \
- { \
- std::ostringstream oss; oss << message; \
- assert(false && oss.str().c_str()); \
- abort(); \
- }
-
-
-#endif
-
-#define JSON_ASSERT_MESSAGE(condition, message) \
- if (!(condition)) { \
- JSON_FAIL_MESSAGE(message); \
- }
-
-#endif // CPPTL_JSON_ASSERTIONS_H_INCLUDED
-
-// //////////////////////////////////////////////////////////////////////
-// End of content of file: include/json/assertions.h
-// //////////////////////////////////////////////////////////////////////
-
-
-
-
-
-#endif //ifndef JSON_AMALGATED_H_INCLUDED
diff --git a/third_party/protobuf/3.2.0/conformance/third_party/jsoncpp/jsoncpp.cpp b/third_party/protobuf/3.2.0/conformance/third_party/jsoncpp/jsoncpp.cpp
deleted file mode 100644
index f803962ade..0000000000
--- a/third_party/protobuf/3.2.0/conformance/third_party/jsoncpp/jsoncpp.cpp
+++ /dev/null
@@ -1,5192 +0,0 @@
-/// Json-cpp amalgated source (http://jsoncpp.sourceforge.net/).
-/// It is intended to be used with #include "json/json.h"
-
-// //////////////////////////////////////////////////////////////////////
-// Beginning of content of file: LICENSE
-// //////////////////////////////////////////////////////////////////////
-
-/*
-The JsonCpp library's source code, including accompanying documentation,
-tests and demonstration applications, are licensed under the following
-conditions...
-
-The author (Baptiste Lepilleur) explicitly disclaims copyright in all
-jurisdictions which recognize such a disclaimer. In such jurisdictions,
-this software is released into the Public Domain.
-
-In jurisdictions which do not recognize Public Domain property (e.g. Germany as of
-2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur, and is
-released under the terms of the MIT License (see below).
-
-In jurisdictions which recognize Public Domain property, the user of this
-software may choose to accept it either as 1) Public Domain, 2) under the
-conditions of the MIT License (see below), or 3) under the terms of dual
-Public Domain/MIT License conditions described here, as they choose.
-
-The MIT License is about as close to Public Domain as a license can get, and is
-described in clear, concise terms at:
-
- http://en.wikipedia.org/wiki/MIT_License
-
-The full text of the MIT License follows:
-
-========================================================================
-Copyright (c) 2007-2010 Baptiste Lepilleur
-
-Permission is hereby granted, free of charge, to any person
-obtaining a copy of this software and associated documentation
-files (the "Software"), to deal in the Software without
-restriction, including without limitation the rights to use, copy,
-modify, merge, publish, distribute, sublicense, and/or sell copies
-of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
-BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
-ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-========================================================================
-(END LICENSE TEXT)
-
-The MIT license is compatible with both the GPL and commercial
-software, affording one all of the rights of Public Domain with the
-minor nuisance of being required to keep the above copyright notice
-and license text in the source code. Note also that by accepting the
-Public Domain "license" you can re-license your copy using whatever
-license you like.
-
-*/
-
-// //////////////////////////////////////////////////////////////////////
-// End of content of file: LICENSE
-// //////////////////////////////////////////////////////////////////////
-
-
-
-
-
-
-#include "third_party/jsoncpp/json.h"
-
-#ifndef JSON_IS_AMALGAMATION
-#error "Compile with -I PATH_TO_JSON_DIRECTORY"
-#endif
-
-
-// //////////////////////////////////////////////////////////////////////
-// Beginning of content of file: src/lib_json/json_tool.h
-// //////////////////////////////////////////////////////////////////////
-
-// Copyright 2007-2010 Baptiste Lepilleur
-// Distributed under MIT license, or public domain if desired and
-// recognized in your jurisdiction.
-// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
-
-#ifndef LIB_JSONCPP_JSON_TOOL_H_INCLUDED
-#define LIB_JSONCPP_JSON_TOOL_H_INCLUDED
-
-/* This header provides common string manipulation support, such as UTF-8,
- * portable conversion from/to string...
- *
- * It is an internal header that must not be exposed.
- */
-
-namespace Json {
-
-/// Converts a unicode code-point to UTF-8.
-static inline std::string codePointToUTF8(unsigned int cp) {
- std::string result;
-
- // based on description from http://en.wikipedia.org/wiki/UTF-8
-
- if (cp <= 0x7f) {
- result.resize(1);
- result[0] = static_cast<char>(cp);
- } else if (cp <= 0x7FF) {
- result.resize(2);
- result[1] = static_cast<char>(0x80 | (0x3f & cp));
- result[0] = static_cast<char>(0xC0 | (0x1f & (cp >> 6)));
- } else if (cp <= 0xFFFF) {
- result.resize(3);
- result[2] = static_cast<char>(0x80 | (0x3f & cp));
- result[1] = static_cast<char>(0x80 | (0x3f & (cp >> 6)));
- result[0] = static_cast<char>(0xE0 | (0xf & (cp >> 12)));
- } else if (cp <= 0x10FFFF) {
- result.resize(4);
- result[3] = static_cast<char>(0x80 | (0x3f & cp));
- result[2] = static_cast<char>(0x80 | (0x3f & (cp >> 6)));
- result[1] = static_cast<char>(0x80 | (0x3f & (cp >> 12)));
- result[0] = static_cast<char>(0xF0 | (0x7 & (cp >> 18)));
- }
-
- return result;
-}
-
-/// Returns true if ch is a control character (in range [1,31]).
-static inline bool isControlCharacter(char ch) { return ch > 0 && ch <= 0x1F; }
-
-enum {
- /// Constant that specify the size of the buffer that must be passed to
- /// uintToString.
- uintToStringBufferSize = 3 * sizeof(LargestUInt) + 1
-};
-
-// Defines a char buffer for use with uintToString().
-typedef char UIntToStringBuffer[uintToStringBufferSize];
-
-/** Converts an unsigned integer to string.
- * @param value Unsigned interger to convert to string
- * @param current Input/Output string buffer.
- * Must have at least uintToStringBufferSize chars free.
- */
-static inline void uintToString(LargestUInt value, char*& current) {
- *--current = 0;
- do {
- *--current = static_cast<signed char>(value % 10U + static_cast<unsigned>('0'));
- value /= 10;
- } while (value != 0);
-}
-
-/** Change ',' to '.' everywhere in buffer.
- *
- * We had a sophisticated way, but it did not work in WinCE.
- * @see https://github.com/open-source-parsers/jsoncpp/pull/9
- */
-static inline void fixNumericLocale(char* begin, char* end) {
- while (begin < end) {
- if (*begin == ',') {
- *begin = '.';
- }
- ++begin;
- }
-}
-
-} // namespace Json {
-
-#endif // LIB_JSONCPP_JSON_TOOL_H_INCLUDED
-
-// //////////////////////////////////////////////////////////////////////
-// End of content of file: src/lib_json/json_tool.h
-// //////////////////////////////////////////////////////////////////////
-
-
-
-
-
-
-// //////////////////////////////////////////////////////////////////////
-// Beginning of content of file: src/lib_json/json_reader.cpp
-// //////////////////////////////////////////////////////////////////////
-
-// Copyright 2007-2011 Baptiste Lepilleur
-// Distributed under MIT license, or public domain if desired and
-// recognized in your jurisdiction.
-// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
-
-#if !defined(JSON_IS_AMALGAMATION)
-#include <json/assertions.h>
-#include <json/reader.h>
-#include <json/value.h>
-#include "json_tool.h"
-#endif // if !defined(JSON_IS_AMALGAMATION)
-#include <utility>
-#include <cstdio>
-#include <cassert>
-#include <cstring>
-#include <istream>
-#include <sstream>
-#include <memory>
-#include <set>
-#include <limits>
-
-#if defined(_MSC_VER)
-#if !defined(WINCE) && defined(__STDC_SECURE_LIB__) && _MSC_VER >= 1500 // VC++ 9.0 and above
-#define snprintf sprintf_s
-#elif _MSC_VER >= 1900 // VC++ 14.0 and above
-#define snprintf std::snprintf
-#else
-#define snprintf _snprintf
-#endif
-#elif defined(__ANDROID__) || defined(__QNXNTO__)
-#define snprintf snprintf
-#elif __cplusplus >= 201103L
-#define snprintf std::snprintf
-#endif
-
-#if defined(__QNXNTO__)
-#define sscanf std::sscanf
-#endif
-
-#if defined(_MSC_VER) && _MSC_VER >= 1400 // VC++ 8.0
-// Disable warning about strdup being deprecated.
-#pragma warning(disable : 4996)
-#endif
-
-static int const stackLimit_g = 1000;
-static int stackDepth_g = 0; // see readValue()
-
-namespace Json {
-
-#if __cplusplus >= 201103L || (defined(_CPPLIB_VER) && _CPPLIB_VER >= 520)
-typedef std::unique_ptr<CharReader> CharReaderPtr;
-#else
-typedef std::auto_ptr<CharReader> CharReaderPtr;
-#endif
-
-// Implementation of class Features
-// ////////////////////////////////
-
-Features::Features()
- : allowComments_(true), strictRoot_(false),
- allowDroppedNullPlaceholders_(false), allowNumericKeys_(false) {}
-
-Features Features::all() { return Features(); }
-
-Features Features::strictMode() {
- Features features;
- features.allowComments_ = false;
- features.strictRoot_ = true;
- features.allowDroppedNullPlaceholders_ = false;
- features.allowNumericKeys_ = false;
- return features;
-}
-
-// Implementation of class Reader
-// ////////////////////////////////
-
-static bool containsNewLine(Reader::Location begin, Reader::Location end) {
- for (; begin < end; ++begin)
- if (*begin == '\n' || *begin == '\r')
- return true;
- return false;
-}
-
-// Class Reader
-// //////////////////////////////////////////////////////////////////
-
-Reader::Reader()
- : errors_(), document_(), begin_(), end_(), current_(), lastValueEnd_(),
- lastValue_(), commentsBefore_(), features_(Features::all()),
- collectComments_() {}
-
-Reader::Reader(const Features& features)
- : errors_(), document_(), begin_(), end_(), current_(), lastValueEnd_(),
- lastValue_(), commentsBefore_(), features_(features), collectComments_() {
-}
-
-bool
-Reader::parse(const std::string& document, Value& root, bool collectComments) {
- document_ = document;
- const char* begin = document_.c_str();
- const char* end = begin + document_.length();
- return parse(begin, end, root, collectComments);
-}
-
-bool Reader::parse(std::istream& sin, Value& root, bool collectComments) {
- // std::istream_iterator<char> begin(sin);
- // std::istream_iterator<char> end;
- // Those would allow streamed input from a file, if parse() were a
- // template function.
-
- // Since std::string is reference-counted, this at least does not
- // create an extra copy.
- std::string doc;
- std::getline(sin, doc, (char)EOF);
- return parse(doc, root, collectComments);
-}
-
-bool Reader::parse(const char* beginDoc,
- const char* endDoc,
- Value& root,
- bool collectComments) {
- if (!features_.allowComments_) {
- collectComments = false;
- }
-
- begin_ = beginDoc;
- end_ = endDoc;
- collectComments_ = collectComments;
- current_ = begin_;
- lastValueEnd_ = 0;
- lastValue_ = 0;
- commentsBefore_ = "";
- errors_.clear();
- while (!nodes_.empty())
- nodes_.pop();
- nodes_.push(&root);
-
- stackDepth_g = 0; // Yes, this is bad coding, but options are limited.
- bool successful = readValue();
- Token token;
- skipCommentTokens(token);
- if (collectComments_ && !commentsBefore_.empty())
- root.setComment(commentsBefore_, commentAfter);
- if (features_.strictRoot_) {
- if (!root.isArray() && !root.isObject()) {
- // Set error location to start of doc, ideally should be first token found
- // in doc
- token.type_ = tokenError;
- token.start_ = beginDoc;
- token.end_ = endDoc;
- addError(
- "A valid JSON document must be either an array or an object value.",
- token);
- return false;
- }
- }
- return successful;
-}
-
-bool Reader::readValue() {
- // This is a non-reentrant way to support a stackLimit. Terrible!
- // But this deprecated class has a security problem: Bad input can
- // cause a seg-fault. This seems like a fair, binary-compatible way
- // to prevent the problem.
- if (stackDepth_g >= stackLimit_g) throwRuntimeError("Exceeded stackLimit in readValue().");
- ++stackDepth_g;
-
- Token token;
- skipCommentTokens(token);
- bool successful = true;
-
- if (collectComments_ && !commentsBefore_.empty()) {
- currentValue().setComment(commentsBefore_, commentBefore);
- commentsBefore_ = "";
- }
-
- switch (token.type_) {
- case tokenObjectBegin:
- successful = readObject(token);
- currentValue().setOffsetLimit(current_ - begin_);
- break;
- case tokenArrayBegin:
- successful = readArray(token);
- currentValue().setOffsetLimit(current_ - begin_);
- break;
- case tokenNumber:
- successful = decodeNumber(token);
- break;
- case tokenString:
- successful = decodeString(token);
- break;
- case tokenTrue:
- {
- Value v(true);
- currentValue().swapPayload(v);
- currentValue().setOffsetStart(token.start_ - begin_);
- currentValue().setOffsetLimit(token.end_ - begin_);
- }
- break;
- case tokenFalse:
- {
- Value v(false);
- currentValue().swapPayload(v);
- currentValue().setOffsetStart(token.start_ - begin_);
- currentValue().setOffsetLimit(token.end_ - begin_);
- }
- break;
- case tokenNull:
- {
- Value v;
- currentValue().swapPayload(v);
- currentValue().setOffsetStart(token.start_ - begin_);
- currentValue().setOffsetLimit(token.end_ - begin_);
- }
- break;
- case tokenArraySeparator:
- case tokenObjectEnd:
- case tokenArrayEnd:
- if (features_.allowDroppedNullPlaceholders_) {
- // "Un-read" the current token and mark the current value as a null
- // token.
- current_--;
- Value v;
- currentValue().swapPayload(v);
- currentValue().setOffsetStart(current_ - begin_ - 1);
- currentValue().setOffsetLimit(current_ - begin_);
- break;
- } // Else, fall through...
- default:
- currentValue().setOffsetStart(token.start_ - begin_);
- currentValue().setOffsetLimit(token.end_ - begin_);
- return addError("Syntax error: value, object or array expected.", token);
- }
-
- if (collectComments_) {
- lastValueEnd_ = current_;
- lastValue_ = &currentValue();
- }
-
- --stackDepth_g;
- return successful;
-}
-
-void Reader::skipCommentTokens(Token& token) {
- if (features_.allowComments_) {
- do {
- readToken(token);
- } while (token.type_ == tokenComment);
- } else {
- readToken(token);
- }
-}
-
-bool Reader::readToken(Token& token) {
- skipSpaces();
- token.start_ = current_;
- Char c = getNextChar();
- bool ok = true;
- switch (c) {
- case '{':
- token.type_ = tokenObjectBegin;
- break;
- case '}':
- token.type_ = tokenObjectEnd;
- break;
- case '[':
- token.type_ = tokenArrayBegin;
- break;
- case ']':
- token.type_ = tokenArrayEnd;
- break;
- case '"':
- token.type_ = tokenString;
- ok = readString();
- break;
- case '/':
- token.type_ = tokenComment;
- ok = readComment();
- break;
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- case '-':
- token.type_ = tokenNumber;
- readNumber();
- break;
- case 't':
- token.type_ = tokenTrue;
- ok = match("rue", 3);
- break;
- case 'f':
- token.type_ = tokenFalse;
- ok = match("alse", 4);
- break;
- case 'n':
- token.type_ = tokenNull;
- ok = match("ull", 3);
- break;
- case ',':
- token.type_ = tokenArraySeparator;
- break;
- case ':':
- token.type_ = tokenMemberSeparator;
- break;
- case 0:
- token.type_ = tokenEndOfStream;
- break;
- default:
- ok = false;
- break;
- }
- if (!ok)
- token.type_ = tokenError;
- token.end_ = current_;
- return true;
-}
-
-void Reader::skipSpaces() {
- while (current_ != end_) {
- Char c = *current_;
- if (c == ' ' || c == '\t' || c == '\r' || c == '\n')
- ++current_;
- else
- break;
- }
-}
-
-bool Reader::match(Location pattern, int patternLength) {
- if (end_ - current_ < patternLength)
- return false;
- int index = patternLength;
- while (index--)
- if (current_[index] != pattern[index])
- return false;
- current_ += patternLength;
- return true;
-}
-
-bool Reader::readComment() {
- Location commentBegin = current_ - 1;
- Char c = getNextChar();
- bool successful = false;
- if (c == '*')
- successful = readCStyleComment();
- else if (c == '/')
- successful = readCppStyleComment();
- if (!successful)
- return false;
-
- if (collectComments_) {
- CommentPlacement placement = commentBefore;
- if (lastValueEnd_ && !containsNewLine(lastValueEnd_, commentBegin)) {
- if (c != '*' || !containsNewLine(commentBegin, current_))
- placement = commentAfterOnSameLine;
- }
-
- addComment(commentBegin, current_, placement);
- }
- return true;
-}
-
-static std::string normalizeEOL(Reader::Location begin, Reader::Location end) {
- std::string normalized;
- normalized.reserve(end - begin);
- Reader::Location current = begin;
- while (current != end) {
- char c = *current++;
- if (c == '\r') {
- if (current != end && *current == '\n')
- // convert dos EOL
- ++current;
- // convert Mac EOL
- normalized += '\n';
- } else {
- normalized += c;
- }
- }
- return normalized;
-}
-
-void
-Reader::addComment(Location begin, Location end, CommentPlacement placement) {
- assert(collectComments_);
- const std::string& normalized = normalizeEOL(begin, end);
- if (placement == commentAfterOnSameLine) {
- assert(lastValue_ != 0);
- lastValue_->setComment(normalized, placement);
- } else {
- commentsBefore_ += normalized;
- }
-}
-
-bool Reader::readCStyleComment() {
- while (current_ != end_) {
- Char c = getNextChar();
- if (c == '*' && *current_ == '/')
- break;
- }
- return getNextChar() == '/';
-}
-
-bool Reader::readCppStyleComment() {
- while (current_ != end_) {
- Char c = getNextChar();
- if (c == '\n')
- break;
- if (c == '\r') {
- // Consume DOS EOL. It will be normalized in addComment.
- if (current_ != end_ && *current_ == '\n')
- getNextChar();
- // Break on Moc OS 9 EOL.
- break;
- }
- }
- return true;
-}
-
-void Reader::readNumber() {
- const char *p = current_;
- char c = '0'; // stopgap for already consumed character
- // integral part
- while (c >= '0' && c <= '9')
- c = (current_ = p) < end_ ? *p++ : 0;
- // fractional part
- if (c == '.') {
- c = (current_ = p) < end_ ? *p++ : 0;
- while (c >= '0' && c <= '9')
- c = (current_ = p) < end_ ? *p++ : 0;
- }
- // exponential part
- if (c == 'e' || c == 'E') {
- c = (current_ = p) < end_ ? *p++ : 0;
- if (c == '+' || c == '-')
- c = (current_ = p) < end_ ? *p++ : 0;
- while (c >= '0' && c <= '9')
- c = (current_ = p) < end_ ? *p++ : 0;
- }
-}
-
-bool Reader::readString() {
- Char c = 0;
- while (current_ != end_) {
- c = getNextChar();
- if (c == '\\')
- getNextChar();
- else if (c == '"')
- break;
- }
- return c == '"';
-}
-
-bool Reader::readObject(Token& tokenStart) {
- Token tokenName;
- std::string name;
- Value init(objectValue);
- currentValue().swapPayload(init);
- currentValue().setOffsetStart(tokenStart.start_ - begin_);
- while (readToken(tokenName)) {
- bool initialTokenOk = true;
- while (tokenName.type_ == tokenComment && initialTokenOk)
- initialTokenOk = readToken(tokenName);
- if (!initialTokenOk)
- break;
- if (tokenName.type_ == tokenObjectEnd && name.empty()) // empty object
- return true;
- name = "";
- if (tokenName.type_ == tokenString) {
- if (!decodeString(tokenName, name))
- return recoverFromError(tokenObjectEnd);
- } else if (tokenName.type_ == tokenNumber && features_.allowNumericKeys_) {
- Value numberName;
- if (!decodeNumber(tokenName, numberName))
- return recoverFromError(tokenObjectEnd);
- name = numberName.asString();
- } else {
- break;
- }
-
- Token colon;
- if (!readToken(colon) || colon.type_ != tokenMemberSeparator) {
- return addErrorAndRecover(
- "Missing ':' after object member name", colon, tokenObjectEnd);
- }
- Value& value = currentValue()[name];
- nodes_.push(&value);
- bool ok = readValue();
- nodes_.pop();
- if (!ok) // error already set
- return recoverFromError(tokenObjectEnd);
-
- Token comma;
- if (!readToken(comma) ||
- (comma.type_ != tokenObjectEnd && comma.type_ != tokenArraySeparator &&
- comma.type_ != tokenComment)) {
- return addErrorAndRecover(
- "Missing ',' or '}' in object declaration", comma, tokenObjectEnd);
- }
- bool finalizeTokenOk = true;
- while (comma.type_ == tokenComment && finalizeTokenOk)
- finalizeTokenOk = readToken(comma);
- if (comma.type_ == tokenObjectEnd)
- return true;
- }
- return addErrorAndRecover(
- "Missing '}' or object member name", tokenName, tokenObjectEnd);
-}
-
-bool Reader::readArray(Token& tokenStart) {
- Value init(arrayValue);
- currentValue().swapPayload(init);
- currentValue().setOffsetStart(tokenStart.start_ - begin_);
- skipSpaces();
- if (*current_ == ']') // empty array
- {
- Token endArray;
- readToken(endArray);
- return true;
- }
- int index = 0;
- for (;;) {
- Value& value = currentValue()[index++];
- nodes_.push(&value);
- bool ok = readValue();
- nodes_.pop();
- if (!ok) // error already set
- return recoverFromError(tokenArrayEnd);
-
- Token token;
- // Accept Comment after last item in the array.
- ok = readToken(token);
- while (token.type_ == tokenComment && ok) {
- ok = readToken(token);
- }
- bool badTokenType =
- (token.type_ != tokenArraySeparator && token.type_ != tokenArrayEnd);
- if (!ok || badTokenType) {
- return addErrorAndRecover(
- "Missing ',' or ']' in array declaration", token, tokenArrayEnd);
- }
- if (token.type_ == tokenArrayEnd)
- break;
- }
- return true;
-}
-
-bool Reader::decodeNumber(Token& token) {
- Value decoded;
- if (!decodeNumber(token, decoded))
- return false;
- currentValue().swapPayload(decoded);
- currentValue().setOffsetStart(token.start_ - begin_);
- currentValue().setOffsetLimit(token.end_ - begin_);
- return true;
-}
-
-bool Reader::decodeNumber(Token& token, Value& decoded) {
- // Attempts to parse the number as an integer. If the number is
- // larger than the maximum supported value of an integer then
- // we decode the number as a double.
- Location current = token.start_;
- bool isNegative = *current == '-';
- if (isNegative)
- ++current;
- // TODO: Help the compiler do the div and mod at compile time or get rid of them.
- Value::LargestUInt maxIntegerValue =
- isNegative ? Value::LargestUInt(Value::maxLargestInt) + 1
- : Value::maxLargestUInt;
- Value::LargestUInt threshold = maxIntegerValue / 10;
- Value::LargestUInt value = 0;
- while (current < token.end_) {
- Char c = *current++;
- if (c < '0' || c > '9')
- return decodeDouble(token, decoded);
- Value::UInt digit(c - '0');
- if (value >= threshold) {
- // We've hit or exceeded the max value divided by 10 (rounded down). If
- // a) we've only just touched the limit, b) this is the last digit, and
- // c) it's small enough to fit in that rounding delta, we're okay.
- // Otherwise treat this number as a double to avoid overflow.
- if (value > threshold || current != token.end_ ||
- digit > maxIntegerValue % 10) {
- return decodeDouble(token, decoded);
- }
- }
- value = value * 10 + digit;
- }
- if (isNegative && value == maxIntegerValue)
- decoded = Value::minLargestInt;
- else if (isNegative)
- decoded = -Value::LargestInt(value);
- else if (value <= Value::LargestUInt(Value::maxInt))
- decoded = Value::LargestInt(value);
- else
- decoded = value;
- return true;
-}
-
-bool Reader::decodeDouble(Token& token) {
- Value decoded;
- if (!decodeDouble(token, decoded))
- return false;
- currentValue().swapPayload(decoded);
- currentValue().setOffsetStart(token.start_ - begin_);
- currentValue().setOffsetLimit(token.end_ - begin_);
- return true;
-}
-
-bool Reader::decodeDouble(Token& token, Value& decoded) {
- double value = 0;
- std::string buffer(token.start_, token.end_);
- std::istringstream is(buffer);
- if (!(is >> value))
- return addError("'" + std::string(token.start_, token.end_) +
- "' is not a number.",
- token);
- decoded = value;
- return true;
-}
-
-bool Reader::decodeString(Token& token) {
- std::string decoded_string;
- if (!decodeString(token, decoded_string))
- return false;
- Value decoded(decoded_string);
- currentValue().swapPayload(decoded);
- currentValue().setOffsetStart(token.start_ - begin_);
- currentValue().setOffsetLimit(token.end_ - begin_);
- return true;
-}
-
-bool Reader::decodeString(Token& token, std::string& decoded) {
- decoded.reserve(token.end_ - token.start_ - 2);
- Location current = token.start_ + 1; // skip '"'
- Location end = token.end_ - 1; // do not include '"'
- while (current != end) {
- Char c = *current++;
- if (c == '"')
- break;
- else if (c == '\\') {
- if (current == end)
- return addError("Empty escape sequence in string", token, current);
- Char escape = *current++;
- switch (escape) {
- case '"':
- decoded += '"';
- break;
- case '/':
- decoded += '/';
- break;
- case '\\':
- decoded += '\\';
- break;
- case 'b':
- decoded += '\b';
- break;
- case 'f':
- decoded += '\f';
- break;
- case 'n':
- decoded += '\n';
- break;
- case 'r':
- decoded += '\r';
- break;
- case 't':
- decoded += '\t';
- break;
- case 'u': {
- unsigned int unicode;
- if (!decodeUnicodeCodePoint(token, current, end, unicode))
- return false;
- decoded += codePointToUTF8(unicode);
- } break;
- default:
- return addError("Bad escape sequence in string", token, current);
- }
- } else {
- decoded += c;
- }
- }
- return true;
-}
-
-bool Reader::decodeUnicodeCodePoint(Token& token,
- Location& current,
- Location end,
- unsigned int& unicode) {
-
- if (!decodeUnicodeEscapeSequence(token, current, end, unicode))
- return false;
- if (unicode >= 0xD800 && unicode <= 0xDBFF) {
- // surrogate pairs
- if (end - current < 6)
- return addError(
- "additional six characters expected to parse unicode surrogate pair.",
- token,
- current);
- unsigned int surrogatePair;
- if (*(current++) == '\\' && *(current++) == 'u') {
- if (decodeUnicodeEscapeSequence(token, current, end, surrogatePair)) {
- unicode = 0x10000 + ((unicode & 0x3FF) << 10) + (surrogatePair & 0x3FF);
- } else
- return false;
- } else
- return addError("expecting another \\u token to begin the second half of "
- "a unicode surrogate pair",
- token,
- current);
- }
- return true;
-}
-
-bool Reader::decodeUnicodeEscapeSequence(Token& token,
- Location& current,
- Location end,
- unsigned int& unicode) {
- if (end - current < 4)
- return addError(
- "Bad unicode escape sequence in string: four digits expected.",
- token,
- current);
- unicode = 0;
- for (int index = 0; index < 4; ++index) {
- Char c = *current++;
- unicode *= 16;
- if (c >= '0' && c <= '9')
- unicode += c - '0';
- else if (c >= 'a' && c <= 'f')
- unicode += c - 'a' + 10;
- else if (c >= 'A' && c <= 'F')
- unicode += c - 'A' + 10;
- else
- return addError(
- "Bad unicode escape sequence in string: hexadecimal digit expected.",
- token,
- current);
- }
- return true;
-}
-
-bool
-Reader::addError(const std::string& message, Token& token, Location extra) {
- ErrorInfo info;
- info.token_ = token;
- info.message_ = message;
- info.extra_ = extra;
- errors_.push_back(info);
- return false;
-}
-
-bool Reader::recoverFromError(TokenType skipUntilToken) {
- int errorCount = int(errors_.size());
- Token skip;
- for (;;) {
- if (!readToken(skip))
- errors_.resize(errorCount); // discard errors caused by recovery
- if (skip.type_ == skipUntilToken || skip.type_ == tokenEndOfStream)
- break;
- }
- errors_.resize(errorCount);
- return false;
-}
-
-bool Reader::addErrorAndRecover(const std::string& message,
- Token& token,
- TokenType skipUntilToken) {
- addError(message, token);
- return recoverFromError(skipUntilToken);
-}
-
-Value& Reader::currentValue() { return *(nodes_.top()); }
-
-Reader::Char Reader::getNextChar() {
- if (current_ == end_)
- return 0;
- return *current_++;
-}
-
-void Reader::getLocationLineAndColumn(Location location,
- int& line,
- int& column) const {
- Location current = begin_;
- Location lastLineStart = current;
- line = 0;
- while (current < location && current != end_) {
- Char c = *current++;
- if (c == '\r') {
- if (*current == '\n')
- ++current;
- lastLineStart = current;
- ++line;
- } else if (c == '\n') {
- lastLineStart = current;
- ++line;
- }
- }
- // column & line start at 1
- column = int(location - lastLineStart) + 1;
- ++line;
-}
-
-std::string Reader::getLocationLineAndColumn(Location location) const {
- int line, column;
- getLocationLineAndColumn(location, line, column);
- char buffer[18 + 16 + 16 + 1];
- snprintf(buffer, sizeof(buffer), "Line %d, Column %d", line, column);
- return buffer;
-}
-
-// Deprecated. Preserved for backward compatibility
-std::string Reader::getFormatedErrorMessages() const {
- return getFormattedErrorMessages();
-}
-
-std::string Reader::getFormattedErrorMessages() const {
- std::string formattedMessage;
- for (Errors::const_iterator itError = errors_.begin();
- itError != errors_.end();
- ++itError) {
- const ErrorInfo& error = *itError;
- formattedMessage +=
- "* " + getLocationLineAndColumn(error.token_.start_) + "\n";
- formattedMessage += " " + error.message_ + "\n";
- if (error.extra_)
- formattedMessage +=
- "See " + getLocationLineAndColumn(error.extra_) + " for detail.\n";
- }
- return formattedMessage;
-}
-
-std::vector<Reader::StructuredError> Reader::getStructuredErrors() const {
- std::vector<Reader::StructuredError> allErrors;
- for (Errors::const_iterator itError = errors_.begin();
- itError != errors_.end();
- ++itError) {
- const ErrorInfo& error = *itError;
- Reader::StructuredError structured;
- structured.offset_start = error.token_.start_ - begin_;
- structured.offset_limit = error.token_.end_ - begin_;
- structured.message = error.message_;
- allErrors.push_back(structured);
- }
- return allErrors;
-}
-
-bool Reader::pushError(const Value& value, const std::string& message) {
- size_t length = end_ - begin_;
- if(value.getOffsetStart() > length
- || value.getOffsetLimit() > length)
- return false;
- Token token;
- token.type_ = tokenError;
- token.start_ = begin_ + value.getOffsetStart();
- token.end_ = end_ + value.getOffsetLimit();
- ErrorInfo info;
- info.token_ = token;
- info.message_ = message;
- info.extra_ = 0;
- errors_.push_back(info);
- return true;
-}
-
-bool Reader::pushError(const Value& value, const std::string& message, const Value& extra) {
- size_t length = end_ - begin_;
- if(value.getOffsetStart() > length
- || value.getOffsetLimit() > length
- || extra.getOffsetLimit() > length)
- return false;
- Token token;
- token.type_ = tokenError;
- token.start_ = begin_ + value.getOffsetStart();
- token.end_ = begin_ + value.getOffsetLimit();
- ErrorInfo info;
- info.token_ = token;
- info.message_ = message;
- info.extra_ = begin_ + extra.getOffsetStart();
- errors_.push_back(info);
- return true;
-}
-
-bool Reader::good() const {
- return !errors_.size();
-}
-
-// exact copy of Features
-class OurFeatures {
-public:
- static OurFeatures all();
- bool allowComments_;
- bool strictRoot_;
- bool allowDroppedNullPlaceholders_;
- bool allowNumericKeys_;
- bool allowSingleQuotes_;
- bool failIfExtra_;
- bool rejectDupKeys_;
- bool allowSpecialFloats_;
- int stackLimit_;
-}; // OurFeatures
-
-// exact copy of Implementation of class Features
-// ////////////////////////////////
-
-OurFeatures OurFeatures::all() { return OurFeatures(); }
-
-// Implementation of class Reader
-// ////////////////////////////////
-
-// exact copy of Reader, renamed to OurReader
-class OurReader {
-public:
- typedef char Char;
- typedef const Char* Location;
- struct StructuredError {
- size_t offset_start;
- size_t offset_limit;
- std::string message;
- };
-
- OurReader(OurFeatures const& features);
- bool parse(const char* beginDoc,
- const char* endDoc,
- Value& root,
- bool collectComments = true);
- std::string getFormattedErrorMessages() const;
- std::vector<StructuredError> getStructuredErrors() const;
- bool pushError(const Value& value, const std::string& message);
- bool pushError(const Value& value, const std::string& message, const Value& extra);
- bool good() const;
-
-private:
- OurReader(OurReader const&); // no impl
- void operator=(OurReader const&); // no impl
-
- enum TokenType {
- tokenEndOfStream = 0,
- tokenObjectBegin,
- tokenObjectEnd,
- tokenArrayBegin,
- tokenArrayEnd,
- tokenString,
- tokenNumber,
- tokenTrue,
- tokenFalse,
- tokenNull,
- tokenNaN,
- tokenPosInf,
- tokenNegInf,
- tokenArraySeparator,
- tokenMemberSeparator,
- tokenComment,
- tokenError
- };
-
- class Token {
- public:
- TokenType type_;
- Location start_;
- Location end_;
- };
-
- class ErrorInfo {
- public:
- Token token_;
- std::string message_;
- Location extra_;
- };
-
- typedef std::deque<ErrorInfo> Errors;
-
- bool readToken(Token& token);
- void skipSpaces();
- bool match(Location pattern, int patternLength);
- bool readComment();
- bool readCStyleComment();
- bool readCppStyleComment();
- bool readString();
- bool readStringSingleQuote();
- bool readNumber(bool checkInf);
- bool readValue();
- bool readObject(Token& token);
- bool readArray(Token& token);
- bool decodeNumber(Token& token);
- bool decodeNumber(Token& token, Value& decoded);
- bool decodeString(Token& token);
- bool decodeString(Token& token, std::string& decoded);
- bool decodeDouble(Token& token);
- bool decodeDouble(Token& token, Value& decoded);
- bool decodeUnicodeCodePoint(Token& token,
- Location& current,
- Location end,
- unsigned int& unicode);
- bool decodeUnicodeEscapeSequence(Token& token,
- Location& current,
- Location end,
- unsigned int& unicode);
- bool addError(const std::string& message, Token& token, Location extra = 0);
- bool recoverFromError(TokenType skipUntilToken);
- bool addErrorAndRecover(const std::string& message,
- Token& token,
- TokenType skipUntilToken);
- void skipUntilSpace();
- Value& currentValue();
- Char getNextChar();
- void
- getLocationLineAndColumn(Location location, int& line, int& column) const;
- std::string getLocationLineAndColumn(Location location) const;
- void addComment(Location begin, Location end, CommentPlacement placement);
- void skipCommentTokens(Token& token);
-
- typedef std::stack<Value*> Nodes;
- Nodes nodes_;
- Errors errors_;
- std::string document_;
- Location begin_;
- Location end_;
- Location current_;
- Location lastValueEnd_;
- Value* lastValue_;
- std::string commentsBefore_;
- int stackDepth_;
-
- OurFeatures const features_;
- bool collectComments_;
-}; // OurReader
-
-// complete copy of Read impl, for OurReader
-
-OurReader::OurReader(OurFeatures const& features)
- : errors_(), document_(), begin_(), end_(), current_(), lastValueEnd_(),
- lastValue_(), commentsBefore_(),
- stackDepth_(0),
- features_(features), collectComments_() {
-}
-
-bool OurReader::parse(const char* beginDoc,
- const char* endDoc,
- Value& root,
- bool collectComments) {
- if (!features_.allowComments_) {
- collectComments = false;
- }
-
- begin_ = beginDoc;
- end_ = endDoc;
- collectComments_ = collectComments;
- current_ = begin_;
- lastValueEnd_ = 0;
- lastValue_ = 0;
- commentsBefore_ = "";
- errors_.clear();
- while (!nodes_.empty())
- nodes_.pop();
- nodes_.push(&root);
-
- stackDepth_ = 0;
- bool successful = readValue();
- Token token;
- skipCommentTokens(token);
- if (features_.failIfExtra_) {
- if (token.type_ != tokenError && token.type_ != tokenEndOfStream) {
- addError("Extra non-whitespace after JSON value.", token);
- return false;
- }
- }
- if (collectComments_ && !commentsBefore_.empty())
- root.setComment(commentsBefore_, commentAfter);
- if (features_.strictRoot_) {
- if (!root.isArray() && !root.isObject()) {
- // Set error location to start of doc, ideally should be first token found
- // in doc
- token.type_ = tokenError;
- token.start_ = beginDoc;
- token.end_ = endDoc;
- addError(
- "A valid JSON document must be either an array or an object value.",
- token);
- return false;
- }
- }
- return successful;
-}
-
-bool OurReader::readValue() {
- if (stackDepth_ >= features_.stackLimit_) throwRuntimeError("Exceeded stackLimit in readValue().");
- ++stackDepth_;
- Token token;
- skipCommentTokens(token);
- bool successful = true;
-
- if (collectComments_ && !commentsBefore_.empty()) {
- currentValue().setComment(commentsBefore_, commentBefore);
- commentsBefore_ = "";
- }
-
- switch (token.type_) {
- case tokenObjectBegin:
- successful = readObject(token);
- currentValue().setOffsetLimit(current_ - begin_);
- break;
- case tokenArrayBegin:
- successful = readArray(token);
- currentValue().setOffsetLimit(current_ - begin_);
- break;
- case tokenNumber:
- successful = decodeNumber(token);
- break;
- case tokenString:
- successful = decodeString(token);
- break;
- case tokenTrue:
- {
- Value v(true);
- currentValue().swapPayload(v);
- currentValue().setOffsetStart(token.start_ - begin_);
- currentValue().setOffsetLimit(token.end_ - begin_);
- }
- break;
- case tokenFalse:
- {
- Value v(false);
- currentValue().swapPayload(v);
- currentValue().setOffsetStart(token.start_ - begin_);
- currentValue().setOffsetLimit(token.end_ - begin_);
- }
- break;
- case tokenNull:
- {
- Value v;
- currentValue().swapPayload(v);
- currentValue().setOffsetStart(token.start_ - begin_);
- currentValue().setOffsetLimit(token.end_ - begin_);
- }
- break;
- case tokenNaN:
- {
- Value v(std::numeric_limits<double>::quiet_NaN());
- currentValue().swapPayload(v);
- currentValue().setOffsetStart(token.start_ - begin_);
- currentValue().setOffsetLimit(token.end_ - begin_);
- }
- break;
- case tokenPosInf:
- {
- Value v(std::numeric_limits<double>::infinity());
- currentValue().swapPayload(v);
- currentValue().setOffsetStart(token.start_ - begin_);
- currentValue().setOffsetLimit(token.end_ - begin_);
- }
- break;
- case tokenNegInf:
- {
- Value v(-std::numeric_limits<double>::infinity());
- currentValue().swapPayload(v);
- currentValue().setOffsetStart(token.start_ - begin_);
- currentValue().setOffsetLimit(token.end_ - begin_);
- }
- break;
- case tokenArraySeparator:
- case tokenObjectEnd:
- case tokenArrayEnd:
- if (features_.allowDroppedNullPlaceholders_) {
- // "Un-read" the current token and mark the current value as a null
- // token.
- current_--;
- Value v;
- currentValue().swapPayload(v);
- currentValue().setOffsetStart(current_ - begin_ - 1);
- currentValue().setOffsetLimit(current_ - begin_);
- break;
- } // else, fall through ...
- default:
- currentValue().setOffsetStart(token.start_ - begin_);
- currentValue().setOffsetLimit(token.end_ - begin_);
- return addError("Syntax error: value, object or array expected.", token);
- }
-
- if (collectComments_) {
- lastValueEnd_ = current_;
- lastValue_ = &currentValue();
- }
-
- --stackDepth_;
- return successful;
-}
-
-void OurReader::skipCommentTokens(Token& token) {
- if (features_.allowComments_) {
- do {
- readToken(token);
- } while (token.type_ == tokenComment);
- } else {
- readToken(token);
- }
-}
-
-bool OurReader::readToken(Token& token) {
- skipSpaces();
- token.start_ = current_;
- Char c = getNextChar();
- bool ok = true;
- switch (c) {
- case '{':
- token.type_ = tokenObjectBegin;
- break;
- case '}':
- token.type_ = tokenObjectEnd;
- break;
- case '[':
- token.type_ = tokenArrayBegin;
- break;
- case ']':
- token.type_ = tokenArrayEnd;
- break;
- case '"':
- token.type_ = tokenString;
- ok = readString();
- break;
- case '\'':
- if (features_.allowSingleQuotes_) {
- token.type_ = tokenString;
- ok = readStringSingleQuote();
- break;
- } // else continue
- case '/':
- token.type_ = tokenComment;
- ok = readComment();
- break;
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- token.type_ = tokenNumber;
- readNumber(false);
- break;
- case '-':
- if (readNumber(true)) {
- token.type_ = tokenNumber;
- } else {
- token.type_ = tokenNegInf;
- ok = features_.allowSpecialFloats_ && match("nfinity", 7);
- }
- break;
- case 't':
- token.type_ = tokenTrue;
- ok = match("rue", 3);
- break;
- case 'f':
- token.type_ = tokenFalse;
- ok = match("alse", 4);
- break;
- case 'n':
- token.type_ = tokenNull;
- ok = match("ull", 3);
- break;
- case 'N':
- if (features_.allowSpecialFloats_) {
- token.type_ = tokenNaN;
- ok = match("aN", 2);
- } else {
- ok = false;
- }
- break;
- case 'I':
- if (features_.allowSpecialFloats_) {
- token.type_ = tokenPosInf;
- ok = match("nfinity", 7);
- } else {
- ok = false;
- }
- break;
- case ',':
- token.type_ = tokenArraySeparator;
- break;
- case ':':
- token.type_ = tokenMemberSeparator;
- break;
- case 0:
- token.type_ = tokenEndOfStream;
- break;
- default:
- ok = false;
- break;
- }
- if (!ok)
- token.type_ = tokenError;
- token.end_ = current_;
- return true;
-}
-
-void OurReader::skipSpaces() {
- while (current_ != end_) {
- Char c = *current_;
- if (c == ' ' || c == '\t' || c == '\r' || c == '\n')
- ++current_;
- else
- break;
- }
-}
-
-bool OurReader::match(Location pattern, int patternLength) {
- if (end_ - current_ < patternLength)
- return false;
- int index = patternLength;
- while (index--)
- if (current_[index] != pattern[index])
- return false;
- current_ += patternLength;
- return true;
-}
-
-bool OurReader::readComment() {
- Location commentBegin = current_ - 1;
- Char c = getNextChar();
- bool successful = false;
- if (c == '*')
- successful = readCStyleComment();
- else if (c == '/')
- successful = readCppStyleComment();
- if (!successful)
- return false;
-
- if (collectComments_) {
- CommentPlacement placement = commentBefore;
- if (lastValueEnd_ && !containsNewLine(lastValueEnd_, commentBegin)) {
- if (c != '*' || !containsNewLine(commentBegin, current_))
- placement = commentAfterOnSameLine;
- }
-
- addComment(commentBegin, current_, placement);
- }
- return true;
-}
-
-void
-OurReader::addComment(Location begin, Location end, CommentPlacement placement) {
- assert(collectComments_);
- const std::string& normalized = normalizeEOL(begin, end);
- if (placement == commentAfterOnSameLine) {
- assert(lastValue_ != 0);
- lastValue_->setComment(normalized, placement);
- } else {
- commentsBefore_ += normalized;
- }
-}
-
-bool OurReader::readCStyleComment() {
- while (current_ != end_) {
- Char c = getNextChar();
- if (c == '*' && *current_ == '/')
- break;
- }
- return getNextChar() == '/';
-}
-
-bool OurReader::readCppStyleComment() {
- while (current_ != end_) {
- Char c = getNextChar();
- if (c == '\n')
- break;
- if (c == '\r') {
- // Consume DOS EOL. It will be normalized in addComment.
- if (current_ != end_ && *current_ == '\n')
- getNextChar();
- // Break on Moc OS 9 EOL.
- break;
- }
- }
- return true;
-}
-
-bool OurReader::readNumber(bool checkInf) {
- const char *p = current_;
- if (checkInf && p != end_ && *p == 'I') {
- current_ = ++p;
- return false;
- }
- char c = '0'; // stopgap for already consumed character
- // integral part
- while (c >= '0' && c <= '9')
- c = (current_ = p) < end_ ? *p++ : 0;
- // fractional part
- if (c == '.') {
- c = (current_ = p) < end_ ? *p++ : 0;
- while (c >= '0' && c <= '9')
- c = (current_ = p) < end_ ? *p++ : 0;
- }
- // exponential part
- if (c == 'e' || c == 'E') {
- c = (current_ = p) < end_ ? *p++ : 0;
- if (c == '+' || c == '-')
- c = (current_ = p) < end_ ? *p++ : 0;
- while (c >= '0' && c <= '9')
- c = (current_ = p) < end_ ? *p++ : 0;
- }
- return true;
-}
-bool OurReader::readString() {
- Char c = 0;
- while (current_ != end_) {
- c = getNextChar();
- if (c == '\\')
- getNextChar();
- else if (c == '"')
- break;
- }
- return c == '"';
-}
-
-
-bool OurReader::readStringSingleQuote() {
- Char c = 0;
- while (current_ != end_) {
- c = getNextChar();
- if (c == '\\')
- getNextChar();
- else if (c == '\'')
- break;
- }
- return c == '\'';
-}
-
-bool OurReader::readObject(Token& tokenStart) {
- Token tokenName;
- std::string name;
- Value init(objectValue);
- currentValue().swapPayload(init);
- currentValue().setOffsetStart(tokenStart.start_ - begin_);
- while (readToken(tokenName)) {
- bool initialTokenOk = true;
- while (tokenName.type_ == tokenComment && initialTokenOk)
- initialTokenOk = readToken(tokenName);
- if (!initialTokenOk)
- break;
- if (tokenName.type_ == tokenObjectEnd && name.empty()) // empty object
- return true;
- name = "";
- if (tokenName.type_ == tokenString) {
- if (!decodeString(tokenName, name))
- return recoverFromError(tokenObjectEnd);
- } else if (tokenName.type_ == tokenNumber && features_.allowNumericKeys_) {
- Value numberName;
- if (!decodeNumber(tokenName, numberName))
- return recoverFromError(tokenObjectEnd);
- name = numberName.asString();
- } else {
- break;
- }
-
- Token colon;
- if (!readToken(colon) || colon.type_ != tokenMemberSeparator) {
- return addErrorAndRecover(
- "Missing ':' after object member name", colon, tokenObjectEnd);
- }
- if (name.length() >= (1U<<30)) throwRuntimeError("keylength >= 2^30");
- if (features_.rejectDupKeys_ && currentValue().isMember(name)) {
- std::string msg = "Duplicate key: '" + name + "'";
- return addErrorAndRecover(
- msg, tokenName, tokenObjectEnd);
- }
- Value& value = currentValue()[name];
- nodes_.push(&value);
- bool ok = readValue();
- nodes_.pop();
- if (!ok) // error already set
- return recoverFromError(tokenObjectEnd);
-
- Token comma;
- if (!readToken(comma) ||
- (comma.type_ != tokenObjectEnd && comma.type_ != tokenArraySeparator &&
- comma.type_ != tokenComment)) {
- return addErrorAndRecover(
- "Missing ',' or '}' in object declaration", comma, tokenObjectEnd);
- }
- bool finalizeTokenOk = true;
- while (comma.type_ == tokenComment && finalizeTokenOk)
- finalizeTokenOk = readToken(comma);
- if (comma.type_ == tokenObjectEnd)
- return true;
- }
- return addErrorAndRecover(
- "Missing '}' or object member name", tokenName, tokenObjectEnd);
-}
-
-bool OurReader::readArray(Token& tokenStart) {
- Value init(arrayValue);
- currentValue().swapPayload(init);
- currentValue().setOffsetStart(tokenStart.start_ - begin_);
- skipSpaces();
- if (*current_ == ']') // empty array
- {
- Token endArray;
- readToken(endArray);
- return true;
- }
- int index = 0;
- for (;;) {
- Value& value = currentValue()[index++];
- nodes_.push(&value);
- bool ok = readValue();
- nodes_.pop();
- if (!ok) // error already set
- return recoverFromError(tokenArrayEnd);
-
- Token token;
- // Accept Comment after last item in the array.
- ok = readToken(token);
- while (token.type_ == tokenComment && ok) {
- ok = readToken(token);
- }
- bool badTokenType =
- (token.type_ != tokenArraySeparator && token.type_ != tokenArrayEnd);
- if (!ok || badTokenType) {
- return addErrorAndRecover(
- "Missing ',' or ']' in array declaration", token, tokenArrayEnd);
- }
- if (token.type_ == tokenArrayEnd)
- break;
- }
- return true;
-}
-
-bool OurReader::decodeNumber(Token& token) {
- Value decoded;
- if (!decodeNumber(token, decoded))
- return false;
- currentValue().swapPayload(decoded);
- currentValue().setOffsetStart(token.start_ - begin_);
- currentValue().setOffsetLimit(token.end_ - begin_);
- return true;
-}
-
-bool OurReader::decodeNumber(Token& token, Value& decoded) {
- // Attempts to parse the number as an integer. If the number is
- // larger than the maximum supported value of an integer then
- // we decode the number as a double.
- Location current = token.start_;
- bool isNegative = *current == '-';
- if (isNegative)
- ++current;
- // TODO: Help the compiler do the div and mod at compile time or get rid of them.
- Value::LargestUInt maxIntegerValue =
- isNegative ? Value::LargestUInt(-Value::minLargestInt)
- : Value::maxLargestUInt;
- Value::LargestUInt threshold = maxIntegerValue / 10;
- Value::LargestUInt value = 0;
- while (current < token.end_) {
- Char c = *current++;
- if (c < '0' || c > '9')
- return decodeDouble(token, decoded);
- Value::UInt digit(c - '0');
- if (value >= threshold) {
- // We've hit or exceeded the max value divided by 10 (rounded down). If
- // a) we've only just touched the limit, b) this is the last digit, and
- // c) it's small enough to fit in that rounding delta, we're okay.
- // Otherwise treat this number as a double to avoid overflow.
- if (value > threshold || current != token.end_ ||
- digit > maxIntegerValue % 10) {
- return decodeDouble(token, decoded);
- }
- }
- value = value * 10 + digit;
- }
- if (isNegative)
- decoded = -Value::LargestInt(value);
- else if (value <= Value::LargestUInt(Value::maxInt))
- decoded = Value::LargestInt(value);
- else
- decoded = value;
- return true;
-}
-
-bool OurReader::decodeDouble(Token& token) {
- Value decoded;
- if (!decodeDouble(token, decoded))
- return false;
- currentValue().swapPayload(decoded);
- currentValue().setOffsetStart(token.start_ - begin_);
- currentValue().setOffsetLimit(token.end_ - begin_);
- return true;
-}
-
-bool OurReader::decodeDouble(Token& token, Value& decoded) {
- double value = 0;
- const int bufferSize = 32;
- int count;
- int length = int(token.end_ - token.start_);
-
- // Sanity check to avoid buffer overflow exploits.
- if (length < 0) {
- return addError("Unable to parse token length", token);
- }
-
- // Avoid using a string constant for the format control string given to
- // sscanf, as this can cause hard to debug crashes on OS X. See here for more
- // info:
- //
- // http://developer.apple.com/library/mac/#DOCUMENTATION/DeveloperTools/gcc-4.0.1/gcc/Incompatibilities.html
- char format[] = "%lf";
-
- if (length <= bufferSize) {
- Char buffer[bufferSize + 1];
- memcpy(buffer, token.start_, length);
- buffer[length] = 0;
- count = sscanf(buffer, format, &value);
- } else {
- std::string buffer(token.start_, token.end_);
- count = sscanf(buffer.c_str(), format, &value);
- }
-
- if (count != 1)
- return addError("'" + std::string(token.start_, token.end_) +
- "' is not a number.",
- token);
- decoded = value;
- return true;
-}
-
-bool OurReader::decodeString(Token& token) {
- std::string decoded_string;
- if (!decodeString(token, decoded_string))
- return false;
- Value decoded(decoded_string);
- currentValue().swapPayload(decoded);
- currentValue().setOffsetStart(token.start_ - begin_);
- currentValue().setOffsetLimit(token.end_ - begin_);
- return true;
-}
-
-bool OurReader::decodeString(Token& token, std::string& decoded) {
- decoded.reserve(token.end_ - token.start_ - 2);
- Location current = token.start_ + 1; // skip '"'
- Location end = token.end_ - 1; // do not include '"'
- while (current != end) {
- Char c = *current++;
- if (c == '"')
- break;
- else if (c == '\\') {
- if (current == end)
- return addError("Empty escape sequence in string", token, current);
- Char escape = *current++;
- switch (escape) {
- case '"':
- decoded += '"';
- break;
- case '/':
- decoded += '/';
- break;
- case '\\':
- decoded += '\\';
- break;
- case 'b':
- decoded += '\b';
- break;
- case 'f':
- decoded += '\f';
- break;
- case 'n':
- decoded += '\n';
- break;
- case 'r':
- decoded += '\r';
- break;
- case 't':
- decoded += '\t';
- break;
- case 'u': {
- unsigned int unicode;
- if (!decodeUnicodeCodePoint(token, current, end, unicode))
- return false;
- decoded += codePointToUTF8(unicode);
- } break;
- default:
- return addError("Bad escape sequence in string", token, current);
- }
- } else {
- decoded += c;
- }
- }
- return true;
-}
-
-bool OurReader::decodeUnicodeCodePoint(Token& token,
- Location& current,
- Location end,
- unsigned int& unicode) {
-
- if (!decodeUnicodeEscapeSequence(token, current, end, unicode))
- return false;
- if (unicode >= 0xD800 && unicode <= 0xDBFF) {
- // surrogate pairs
- if (end - current < 6)
- return addError(
- "additional six characters expected to parse unicode surrogate pair.",
- token,
- current);
- unsigned int surrogatePair;
- if (*(current++) == '\\' && *(current++) == 'u') {
- if (decodeUnicodeEscapeSequence(token, current, end, surrogatePair)) {
- unicode = 0x10000 + ((unicode & 0x3FF) << 10) + (surrogatePair & 0x3FF);
- } else
- return false;
- } else
- return addError("expecting another \\u token to begin the second half of "
- "a unicode surrogate pair",
- token,
- current);
- }
- return true;
-}
-
-bool OurReader::decodeUnicodeEscapeSequence(Token& token,
- Location& current,
- Location end,
- unsigned int& unicode) {
- if (end - current < 4)
- return addError(
- "Bad unicode escape sequence in string: four digits expected.",
- token,
- current);
- unicode = 0;
- for (int index = 0; index < 4; ++index) {
- Char c = *current++;
- unicode *= 16;
- if (c >= '0' && c <= '9')
- unicode += c - '0';
- else if (c >= 'a' && c <= 'f')
- unicode += c - 'a' + 10;
- else if (c >= 'A' && c <= 'F')
- unicode += c - 'A' + 10;
- else
- return addError(
- "Bad unicode escape sequence in string: hexadecimal digit expected.",
- token,
- current);
- }
- return true;
-}
-
-bool
-OurReader::addError(const std::string& message, Token& token, Location extra) {
- ErrorInfo info;
- info.token_ = token;
- info.message_ = message;
- info.extra_ = extra;
- errors_.push_back(info);
- return false;
-}
-
-bool OurReader::recoverFromError(TokenType skipUntilToken) {
- int errorCount = int(errors_.size());
- Token skip;
- for (;;) {
- if (!readToken(skip))
- errors_.resize(errorCount); // discard errors caused by recovery
- if (skip.type_ == skipUntilToken || skip.type_ == tokenEndOfStream)
- break;
- }
- errors_.resize(errorCount);
- return false;
-}
-
-bool OurReader::addErrorAndRecover(const std::string& message,
- Token& token,
- TokenType skipUntilToken) {
- addError(message, token);
- return recoverFromError(skipUntilToken);
-}
-
-Value& OurReader::currentValue() { return *(nodes_.top()); }
-
-OurReader::Char OurReader::getNextChar() {
- if (current_ == end_)
- return 0;
- return *current_++;
-}
-
-void OurReader::getLocationLineAndColumn(Location location,
- int& line,
- int& column) const {
- Location current = begin_;
- Location lastLineStart = current;
- line = 0;
- while (current < location && current != end_) {
- Char c = *current++;
- if (c == '\r') {
- if (*current == '\n')
- ++current;
- lastLineStart = current;
- ++line;
- } else if (c == '\n') {
- lastLineStart = current;
- ++line;
- }
- }
- // column & line start at 1
- column = int(location - lastLineStart) + 1;
- ++line;
-}
-
-std::string OurReader::getLocationLineAndColumn(Location location) const {
- int line, column;
- getLocationLineAndColumn(location, line, column);
- char buffer[18 + 16 + 16 + 1];
- snprintf(buffer, sizeof(buffer), "Line %d, Column %d", line, column);
- return buffer;
-}
-
-std::string OurReader::getFormattedErrorMessages() const {
- std::string formattedMessage;
- for (Errors::const_iterator itError = errors_.begin();
- itError != errors_.end();
- ++itError) {
- const ErrorInfo& error = *itError;
- formattedMessage +=
- "* " + getLocationLineAndColumn(error.token_.start_) + "\n";
- formattedMessage += " " + error.message_ + "\n";
- if (error.extra_)
- formattedMessage +=
- "See " + getLocationLineAndColumn(error.extra_) + " for detail.\n";
- }
- return formattedMessage;
-}
-
-std::vector<OurReader::StructuredError> OurReader::getStructuredErrors() const {
- std::vector<OurReader::StructuredError> allErrors;
- for (Errors::const_iterator itError = errors_.begin();
- itError != errors_.end();
- ++itError) {
- const ErrorInfo& error = *itError;
- OurReader::StructuredError structured;
- structured.offset_start = error.token_.start_ - begin_;
- structured.offset_limit = error.token_.end_ - begin_;
- structured.message = error.message_;
- allErrors.push_back(structured);
- }
- return allErrors;
-}
-
-bool OurReader::pushError(const Value& value, const std::string& message) {
- size_t length = end_ - begin_;
- if(value.getOffsetStart() > length
- || value.getOffsetLimit() > length)
- return false;
- Token token;
- token.type_ = tokenError;
- token.start_ = begin_ + value.getOffsetStart();
- token.end_ = end_ + value.getOffsetLimit();
- ErrorInfo info;
- info.token_ = token;
- info.message_ = message;
- info.extra_ = 0;
- errors_.push_back(info);
- return true;
-}
-
-bool OurReader::pushError(const Value& value, const std::string& message, const Value& extra) {
- size_t length = end_ - begin_;
- if(value.getOffsetStart() > length
- || value.getOffsetLimit() > length
- || extra.getOffsetLimit() > length)
- return false;
- Token token;
- token.type_ = tokenError;
- token.start_ = begin_ + value.getOffsetStart();
- token.end_ = begin_ + value.getOffsetLimit();
- ErrorInfo info;
- info.token_ = token;
- info.message_ = message;
- info.extra_ = begin_ + extra.getOffsetStart();
- errors_.push_back(info);
- return true;
-}
-
-bool OurReader::good() const {
- return !errors_.size();
-}
-
-
-class OurCharReader : public CharReader {
- bool const collectComments_;
- OurReader reader_;
-public:
- OurCharReader(
- bool collectComments,
- OurFeatures const& features)
- : collectComments_(collectComments)
- , reader_(features)
- {}
- bool parse(
- char const* beginDoc, char const* endDoc,
- Value* root, std::string* errs) override {
- bool ok = reader_.parse(beginDoc, endDoc, *root, collectComments_);
- if (errs) {
- *errs = reader_.getFormattedErrorMessages();
- }
- return ok;
- }
-};
-
-CharReaderBuilder::CharReaderBuilder()
-{
- setDefaults(&settings_);
-}
-CharReaderBuilder::~CharReaderBuilder()
-{}
-CharReader* CharReaderBuilder::newCharReader() const
-{
- bool collectComments = settings_["collectComments"].asBool();
- OurFeatures features = OurFeatures::all();
- features.allowComments_ = settings_["allowComments"].asBool();
- features.strictRoot_ = settings_["strictRoot"].asBool();
- features.allowDroppedNullPlaceholders_ = settings_["allowDroppedNullPlaceholders"].asBool();
- features.allowNumericKeys_ = settings_["allowNumericKeys"].asBool();
- features.allowSingleQuotes_ = settings_["allowSingleQuotes"].asBool();
- features.stackLimit_ = settings_["stackLimit"].asInt();
- features.failIfExtra_ = settings_["failIfExtra"].asBool();
- features.rejectDupKeys_ = settings_["rejectDupKeys"].asBool();
- features.allowSpecialFloats_ = settings_["allowSpecialFloats"].asBool();
- return new OurCharReader(collectComments, features);
-}
-static void getValidReaderKeys(std::set<std::string>* valid_keys)
-{
- valid_keys->clear();
- valid_keys->insert("collectComments");
- valid_keys->insert("allowComments");
- valid_keys->insert("strictRoot");
- valid_keys->insert("allowDroppedNullPlaceholders");
- valid_keys->insert("allowNumericKeys");
- valid_keys->insert("allowSingleQuotes");
- valid_keys->insert("stackLimit");
- valid_keys->insert("failIfExtra");
- valid_keys->insert("rejectDupKeys");
- valid_keys->insert("allowSpecialFloats");
-}
-bool CharReaderBuilder::validate(Json::Value* invalid) const
-{
- Json::Value my_invalid;
- if (!invalid) invalid = &my_invalid; // so we do not need to test for NULL
- Json::Value& inv = *invalid;
- std::set<std::string> valid_keys;
- getValidReaderKeys(&valid_keys);
- Value::Members keys = settings_.getMemberNames();
- size_t n = keys.size();
- for (size_t i = 0; i < n; ++i) {
- std::string const& key = keys[i];
- if (valid_keys.find(key) == valid_keys.end()) {
- inv[key] = settings_[key];
- }
- }
- return 0u == inv.size();
-}
-Value& CharReaderBuilder::operator[](std::string key)
-{
- return settings_[key];
-}
-// static
-void CharReaderBuilder::strictMode(Json::Value* settings)
-{
-//! [CharReaderBuilderStrictMode]
- (*settings)["allowComments"] = false;
- (*settings)["strictRoot"] = true;
- (*settings)["allowDroppedNullPlaceholders"] = false;
- (*settings)["allowNumericKeys"] = false;
- (*settings)["allowSingleQuotes"] = false;
- (*settings)["stackLimit"] = 1000;
- (*settings)["failIfExtra"] = true;
- (*settings)["rejectDupKeys"] = true;
- (*settings)["allowSpecialFloats"] = false;
-//! [CharReaderBuilderStrictMode]
-}
-// static
-void CharReaderBuilder::setDefaults(Json::Value* settings)
-{
-//! [CharReaderBuilderDefaults]
- (*settings)["collectComments"] = true;
- (*settings)["allowComments"] = true;
- (*settings)["strictRoot"] = false;
- (*settings)["allowDroppedNullPlaceholders"] = false;
- (*settings)["allowNumericKeys"] = false;
- (*settings)["allowSingleQuotes"] = false;
- (*settings)["stackLimit"] = 1000;
- (*settings)["failIfExtra"] = false;
- (*settings)["rejectDupKeys"] = false;
- (*settings)["allowSpecialFloats"] = false;
-//! [CharReaderBuilderDefaults]
-}
-
-//////////////////////////////////
-// global functions
-
-bool parseFromStream(
- CharReader::Factory const& fact, std::istream& sin,
- Value* root, std::string* errs)
-{
- std::ostringstream ssin;
- ssin << sin.rdbuf();
- std::string doc = ssin.str();
- char const* begin = doc.data();
- char const* end = begin + doc.size();
- // Note that we do not actually need a null-terminator.
- CharReaderPtr const reader(fact.newCharReader());
- return reader->parse(begin, end, root, errs);
-}
-
-std::istream& operator>>(std::istream& sin, Value& root) {
- CharReaderBuilder b;
- std::string errs;
- bool ok = parseFromStream(b, sin, &root, &errs);
- if (!ok) {
- fprintf(stderr,
- "Error from reader: %s",
- errs.c_str());
-
- throwRuntimeError(errs);
- }
- return sin;
-}
-
-} // namespace Json
-
-// //////////////////////////////////////////////////////////////////////
-// End of content of file: src/lib_json/json_reader.cpp
-// //////////////////////////////////////////////////////////////////////
-
-
-
-
-
-
-// //////////////////////////////////////////////////////////////////////
-// Beginning of content of file: src/lib_json/json_valueiterator.inl
-// //////////////////////////////////////////////////////////////////////
-
-// Copyright 2007-2010 Baptiste Lepilleur
-// Distributed under MIT license, or public domain if desired and
-// recognized in your jurisdiction.
-// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
-
-// included by json_value.cpp
-
-namespace Json {
-
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// class ValueIteratorBase
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-
-ValueIteratorBase::ValueIteratorBase()
- : current_(), isNull_(true) {
-}
-
-ValueIteratorBase::ValueIteratorBase(
- const Value::ObjectValues::iterator& current)
- : current_(current), isNull_(false) {}
-
-Value& ValueIteratorBase::deref() const {
- return current_->second;
-}
-
-void ValueIteratorBase::increment() {
- ++current_;
-}
-
-void ValueIteratorBase::decrement() {
- --current_;
-}
-
-ValueIteratorBase::difference_type
-ValueIteratorBase::computeDistance(const SelfType& other) const {
-#ifdef JSON_USE_CPPTL_SMALLMAP
- return other.current_ - current_;
-#else
- // Iterator for null value are initialized using the default
- // constructor, which initialize current_ to the default
- // std::map::iterator. As begin() and end() are two instance
- // of the default std::map::iterator, they can not be compared.
- // To allow this, we handle this comparison specifically.
- if (isNull_ && other.isNull_) {
- return 0;
- }
-
- // Usage of std::distance is not portable (does not compile with Sun Studio 12
- // RogueWave STL,
- // which is the one used by default).
- // Using a portable hand-made version for non random iterator instead:
- // return difference_type( std::distance( current_, other.current_ ) );
- difference_type myDistance = 0;
- for (Value::ObjectValues::iterator it = current_; it != other.current_;
- ++it) {
- ++myDistance;
- }
- return myDistance;
-#endif
-}
-
-bool ValueIteratorBase::isEqual(const SelfType& other) const {
- if (isNull_) {
- return other.isNull_;
- }
- return current_ == other.current_;
-}
-
-void ValueIteratorBase::copy(const SelfType& other) {
- current_ = other.current_;
- isNull_ = other.isNull_;
-}
-
-Value ValueIteratorBase::key() const {
- const Value::CZString czstring = (*current_).first;
- if (czstring.data()) {
- if (czstring.isStaticString())
- return Value(StaticString(czstring.data()));
- return Value(czstring.data(), czstring.data() + czstring.length());
- }
- return Value(czstring.index());
-}
-
-UInt ValueIteratorBase::index() const {
- const Value::CZString czstring = (*current_).first;
- if (!czstring.data())
- return czstring.index();
- return Value::UInt(-1);
-}
-
-std::string ValueIteratorBase::name() const {
- char const* keey;
- char const* end;
- keey = memberName(&end);
- if (!keey) return std::string();
- return std::string(keey, end);
-}
-
-char const* ValueIteratorBase::memberName() const {
- const char* cname = (*current_).first.data();
- return cname ? cname : "";
-}
-
-char const* ValueIteratorBase::memberName(char const** end) const {
- const char* cname = (*current_).first.data();
- if (!cname) {
- *end = NULL;
- return NULL;
- }
- *end = cname + (*current_).first.length();
- return cname;
-}
-
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// class ValueConstIterator
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-
-ValueConstIterator::ValueConstIterator() {}
-
-ValueConstIterator::ValueConstIterator(
- const Value::ObjectValues::iterator& current)
- : ValueIteratorBase(current) {}
-
-ValueConstIterator::ValueConstIterator(ValueIterator const& other)
- : ValueIteratorBase(other) {}
-
-ValueConstIterator& ValueConstIterator::
-operator=(const ValueIteratorBase& other) {
- copy(other);
- return *this;
-}
-
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// class ValueIterator
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-
-ValueIterator::ValueIterator() {}
-
-ValueIterator::ValueIterator(const Value::ObjectValues::iterator& current)
- : ValueIteratorBase(current) {}
-
-ValueIterator::ValueIterator(const ValueConstIterator& other)
- : ValueIteratorBase(other) {
- throwRuntimeError("ConstIterator to Iterator should never be allowed.");
-}
-
-ValueIterator::ValueIterator(const ValueIterator& other)
- : ValueIteratorBase(other) {}
-
-ValueIterator& ValueIterator::operator=(const SelfType& other) {
- copy(other);
- return *this;
-}
-
-} // namespace Json
-
-// //////////////////////////////////////////////////////////////////////
-// End of content of file: src/lib_json/json_valueiterator.inl
-// //////////////////////////////////////////////////////////////////////
-
-
-
-
-
-
-// //////////////////////////////////////////////////////////////////////
-// Beginning of content of file: src/lib_json/json_value.cpp
-// //////////////////////////////////////////////////////////////////////
-
-// Copyright 2011 Baptiste Lepilleur
-// Distributed under MIT license, or public domain if desired and
-// recognized in your jurisdiction.
-// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
-
-#if !defined(JSON_IS_AMALGAMATION)
-#include <json/assertions.h>
-#include <json/value.h>
-#include <json/writer.h>
-#endif // if !defined(JSON_IS_AMALGAMATION)
-#include <math.h>
-#include <sstream>
-#include <utility>
-#include <cstring>
-#include <cassert>
-#ifdef JSON_USE_CPPTL
-#include <cpptl/conststring.h>
-#endif
-#include <cstddef> // size_t
-#include <algorithm> // min()
-
-#define JSON_ASSERT_UNREACHABLE assert(false)
-
-namespace Json {
-
-// This is a walkaround to avoid the static initialization of Value::null.
-// kNull must be word-aligned to avoid crashing on ARM. We use an alignment of
-// 8 (instead of 4) as a bit of future-proofing.
-#if defined(__ARMEL__)
-#define ALIGNAS(byte_alignment) __attribute__((aligned(byte_alignment)))
-#else
-#define ALIGNAS(byte_alignment)
-#endif
-static const unsigned char ALIGNAS(8) kNull[sizeof(Value)] = { 0 };
-const unsigned char& kNullRef = kNull[0];
-const Value& Value::null = reinterpret_cast<const Value&>(kNullRef);
-const Value& Value::nullRef = null;
-
-const Int Value::minInt = Int(~(UInt(-1) / 2));
-const Int Value::maxInt = Int(UInt(-1) / 2);
-const UInt Value::maxUInt = UInt(-1);
-#if defined(JSON_HAS_INT64)
-const Int64 Value::minInt64 = Int64(~(UInt64(-1) / 2));
-const Int64 Value::maxInt64 = Int64(UInt64(-1) / 2);
-const UInt64 Value::maxUInt64 = UInt64(-1);
-// The constant is hard-coded because some compiler have trouble
-// converting Value::maxUInt64 to a double correctly (AIX/xlC).
-// Assumes that UInt64 is a 64 bits integer.
-static const double maxUInt64AsDouble = 18446744073709551615.0;
-#endif // defined(JSON_HAS_INT64)
-const LargestInt Value::minLargestInt = LargestInt(~(LargestUInt(-1) / 2));
-const LargestInt Value::maxLargestInt = LargestInt(LargestUInt(-1) / 2);
-const LargestUInt Value::maxLargestUInt = LargestUInt(-1);
-
-#if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
-template <typename T, typename U>
-static inline bool InRange(double d, T min, U max) {
- return d >= min && d <= max;
-}
-#else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
-static inline double integerToDouble(Json::UInt64 value) {
- return static_cast<double>(Int64(value / 2)) * 2.0 + Int64(value & 1);
-}
-
-template <typename T> static inline double integerToDouble(T value) {
- return static_cast<double>(value);
-}
-
-template <typename T, typename U>
-static inline bool InRange(double d, T min, U max) {
- return d >= integerToDouble(min) && d <= integerToDouble(max);
-}
-#endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
-
-/** Duplicates the specified string value.
- * @param value Pointer to the string to duplicate. Must be zero-terminated if
- * length is "unknown".
- * @param length Length of the value. if equals to unknown, then it will be
- * computed using strlen(value).
- * @return Pointer on the duplicate instance of string.
- */
-static inline char* duplicateStringValue(const char* value,
- size_t length) {
- // Avoid an integer overflow in the call to malloc below by limiting length
- // to a sane value.
- if (length >= (size_t)Value::maxInt)
- length = Value::maxInt - 1;
-
- char* newString = static_cast<char*>(malloc(length + 1));
- if (newString == NULL) {
- throwRuntimeError(
- "in Json::Value::duplicateStringValue(): "
- "Failed to allocate string value buffer");
- }
- memcpy(newString, value, length);
- newString[length] = 0;
- return newString;
-}
-
-/* Record the length as a prefix.
- */
-static inline char* duplicateAndPrefixStringValue(
- const char* value,
- unsigned int length)
-{
- // Avoid an integer overflow in the call to malloc below by limiting length
- // to a sane value.
- JSON_ASSERT_MESSAGE(length <= (unsigned)Value::maxInt - sizeof(unsigned) - 1U,
- "in Json::Value::duplicateAndPrefixStringValue(): "
- "length too big for prefixing");
- unsigned actualLength = length + static_cast<unsigned>(sizeof(unsigned)) + 1U;
- char* newString = static_cast<char*>(malloc(actualLength));
- if (newString == 0) {
- throwRuntimeError(
- "in Json::Value::duplicateAndPrefixStringValue(): "
- "Failed to allocate string value buffer");
- }
- *reinterpret_cast<unsigned*>(newString) = length;
- memcpy(newString + sizeof(unsigned), value, length);
- newString[actualLength - 1U] = 0; // to avoid buffer over-run accidents by users later
- return newString;
-}
-inline static void decodePrefixedString(
- bool isPrefixed, char const* prefixed,
- unsigned* length, char const** value)
-{
- if (!isPrefixed) {
- *length = static_cast<unsigned>(strlen(prefixed));
- *value = prefixed;
- } else {
- *length = *reinterpret_cast<unsigned const*>(prefixed);
- *value = prefixed + sizeof(unsigned);
- }
-}
-/** Free the string duplicated by duplicateStringValue()/duplicateAndPrefixStringValue().
- */
-static inline void releaseStringValue(char* value) { free(value); }
-
-} // namespace Json
-
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// ValueInternals...
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-#if !defined(JSON_IS_AMALGAMATION)
-
-#include "json_valueiterator.inl"
-#endif // if !defined(JSON_IS_AMALGAMATION)
-
-namespace Json {
-
-Exception::Exception(std::string const& msg)
- : msg_(msg)
-{}
-Exception::~Exception() throw()
-{}
-char const* Exception::what() const throw()
-{
- return msg_.c_str();
-}
-RuntimeError::RuntimeError(std::string const& msg)
- : Exception(msg)
-{}
-LogicError::LogicError(std::string const& msg)
- : Exception(msg)
-{}
-void throwRuntimeError(std::string const& msg)
-{
- throw RuntimeError(msg);
-}
-void throwLogicError(std::string const& msg)
-{
- throw LogicError(msg);
-}
-
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// class Value::CommentInfo
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-
-Value::CommentInfo::CommentInfo() : comment_(0) {}
-
-Value::CommentInfo::~CommentInfo() {
- if (comment_)
- releaseStringValue(comment_);
-}
-
-void Value::CommentInfo::setComment(const char* text, size_t len) {
- if (comment_) {
- releaseStringValue(comment_);
- comment_ = 0;
- }
- JSON_ASSERT(text != 0);
- JSON_ASSERT_MESSAGE(
- text[0] == '\0' || text[0] == '/',
- "in Json::Value::setComment(): Comments must start with /");
- // It seems that /**/ style comments are acceptable as well.
- comment_ = duplicateStringValue(text, len);
-}
-
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// class Value::CZString
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-
-// Notes: policy_ indicates if the string was allocated when
-// a string is stored.
-
-Value::CZString::CZString(ArrayIndex aindex) : cstr_(0), index_(aindex) {}
-
-Value::CZString::CZString(char const* str, unsigned ulength, DuplicationPolicy allocate)
- : cstr_(str) {
- // allocate != duplicate
- storage_.policy_ = allocate & 0x3;
- storage_.length_ = ulength & 0x3FFFFFFF;
-}
-
-Value::CZString::CZString(const CZString& other)
- : cstr_(other.storage_.policy_ != noDuplication && other.cstr_ != 0
- ? duplicateStringValue(other.cstr_, other.storage_.length_)
- : other.cstr_) {
- storage_.policy_ = (other.cstr_
- ? (static_cast<DuplicationPolicy>(other.storage_.policy_) == noDuplication
- ? noDuplication : duplicate)
- : static_cast<DuplicationPolicy>(other.storage_.policy_));
- storage_.length_ = other.storage_.length_;
-}
-
-#if JSON_HAS_RVALUE_REFERENCES
-Value::CZString::CZString(CZString&& other)
- : cstr_(other.cstr_), index_(other.index_) {
- other.cstr_ = nullptr;
-}
-#endif
-
-Value::CZString::~CZString() {
- if (cstr_ && storage_.policy_ == duplicate)
- releaseStringValue(const_cast<char*>(cstr_));
-}
-
-void Value::CZString::swap(CZString& other) {
- std::swap(cstr_, other.cstr_);
- std::swap(index_, other.index_);
-}
-
-Value::CZString& Value::CZString::operator=(CZString other) {
- swap(other);
- return *this;
-}
-
-bool Value::CZString::operator<(const CZString& other) const {
- if (!cstr_) return index_ < other.index_;
- //return strcmp(cstr_, other.cstr_) < 0;
- // Assume both are strings.
- unsigned this_len = this->storage_.length_;
- unsigned other_len = other.storage_.length_;
- unsigned min_len = std::min(this_len, other_len);
- int comp = memcmp(this->cstr_, other.cstr_, min_len);
- if (comp < 0) return true;
- if (comp > 0) return false;
- return (this_len < other_len);
-}
-
-bool Value::CZString::operator==(const CZString& other) const {
- if (!cstr_) return index_ == other.index_;
- //return strcmp(cstr_, other.cstr_) == 0;
- // Assume both are strings.
- unsigned this_len = this->storage_.length_;
- unsigned other_len = other.storage_.length_;
- if (this_len != other_len) return false;
- int comp = memcmp(this->cstr_, other.cstr_, this_len);
- return comp == 0;
-}
-
-ArrayIndex Value::CZString::index() const { return index_; }
-
-//const char* Value::CZString::c_str() const { return cstr_; }
-const char* Value::CZString::data() const { return cstr_; }
-unsigned Value::CZString::length() const { return storage_.length_; }
-bool Value::CZString::isStaticString() const { return storage_.policy_ == noDuplication; }
-
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// class Value::Value
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-
-/*! \internal Default constructor initialization must be equivalent to:
- * memset( this, 0, sizeof(Value) )
- * This optimization is used in ValueInternalMap fast allocator.
- */
-Value::Value(ValueType vtype) {
- initBasic(vtype);
- switch (vtype) {
- case nullValue:
- break;
- case intValue:
- case uintValue:
- value_.int_ = 0;
- break;
- case realValue:
- value_.real_ = 0.0;
- break;
- case stringValue:
- value_.string_ = 0;
- break;
- case arrayValue:
- case objectValue:
- value_.map_ = new ObjectValues();
- break;
- case booleanValue:
- value_.bool_ = false;
- break;
- default:
- JSON_ASSERT_UNREACHABLE;
- }
-}
-
-Value::Value(Int value) {
- initBasic(intValue);
- value_.int_ = value;
-}
-
-Value::Value(UInt value) {
- initBasic(uintValue);
- value_.uint_ = value;
-}
-#if defined(JSON_HAS_INT64)
-Value::Value(Int64 value) {
- initBasic(intValue);
- value_.int_ = value;
-}
-Value::Value(UInt64 value) {
- initBasic(uintValue);
- value_.uint_ = value;
-}
-#endif // defined(JSON_HAS_INT64)
-
-Value::Value(double value) {
- initBasic(realValue);
- value_.real_ = value;
-}
-
-Value::Value(const char* value) {
- initBasic(stringValue, true);
- value_.string_ = duplicateAndPrefixStringValue(value, static_cast<unsigned>(strlen(value)));
-}
-
-Value::Value(const char* beginValue, const char* endValue) {
- initBasic(stringValue, true);
- value_.string_ =
- duplicateAndPrefixStringValue(beginValue, static_cast<unsigned>(endValue - beginValue));
-}
-
-Value::Value(const std::string& value) {
- initBasic(stringValue, true);
- value_.string_ =
- duplicateAndPrefixStringValue(value.data(), static_cast<unsigned>(value.length()));
-}
-
-Value::Value(const StaticString& value) {
- initBasic(stringValue);
- value_.string_ = const_cast<char*>(value.c_str());
-}
-
-#ifdef JSON_USE_CPPTL
-Value::Value(const CppTL::ConstString& value) {
- initBasic(stringValue, true);
- value_.string_ = duplicateAndPrefixStringValue(value, static_cast<unsigned>(value.length()));
-}
-#endif
-
-Value::Value(bool value) {
- initBasic(booleanValue);
- value_.bool_ = value;
-}
-
-Value::Value(Value const& other)
- : type_(other.type_), allocated_(false)
- ,
- comments_(0), start_(other.start_), limit_(other.limit_)
-{
- switch (type_) {
- case nullValue:
- case intValue:
- case uintValue:
- case realValue:
- case booleanValue:
- value_ = other.value_;
- break;
- case stringValue:
- if (other.value_.string_ && other.allocated_) {
- unsigned len;
- char const* str;
- decodePrefixedString(other.allocated_, other.value_.string_,
- &len, &str);
- value_.string_ = duplicateAndPrefixStringValue(str, len);
- allocated_ = true;
- } else {
- value_.string_ = other.value_.string_;
- allocated_ = false;
- }
- break;
- case arrayValue:
- case objectValue:
- value_.map_ = new ObjectValues(*other.value_.map_);
- break;
- default:
- JSON_ASSERT_UNREACHABLE;
- }
- if (other.comments_) {
- comments_ = new CommentInfo[numberOfCommentPlacement];
- for (int comment = 0; comment < numberOfCommentPlacement; ++comment) {
- const CommentInfo& otherComment = other.comments_[comment];
- if (otherComment.comment_)
- comments_[comment].setComment(
- otherComment.comment_, strlen(otherComment.comment_));
- }
- }
-}
-
-#if JSON_HAS_RVALUE_REFERENCES
-// Move constructor
-Value::Value(Value&& other) {
- initBasic(nullValue);
- swap(other);
-}
-#endif
-
-Value::~Value() {
- switch (type_) {
- case nullValue:
- case intValue:
- case uintValue:
- case realValue:
- case booleanValue:
- break;
- case stringValue:
- if (allocated_)
- releaseStringValue(value_.string_);
- break;
- case arrayValue:
- case objectValue:
- delete value_.map_;
- break;
- default:
- JSON_ASSERT_UNREACHABLE;
- }
-
- if (comments_)
- delete[] comments_;
-}
-
-Value& Value::operator=(Value other) {
- swap(other);
- return *this;
-}
-
-void Value::swapPayload(Value& other) {
- ValueType temp = type_;
- type_ = other.type_;
- other.type_ = temp;
- std::swap(value_, other.value_);
- int temp2 = allocated_;
- allocated_ = other.allocated_;
- other.allocated_ = temp2 & 0x1;
-}
-
-void Value::swap(Value& other) {
- swapPayload(other);
- std::swap(comments_, other.comments_);
- std::swap(start_, other.start_);
- std::swap(limit_, other.limit_);
-}
-
-ValueType Value::type() const { return type_; }
-
-int Value::compare(const Value& other) const {
- if (*this < other)
- return -1;
- if (*this > other)
- return 1;
- return 0;
-}
-
-bool Value::operator<(const Value& other) const {
- int typeDelta = type_ - other.type_;
- if (typeDelta)
- return typeDelta < 0 ? true : false;
- switch (type_) {
- case nullValue:
- return false;
- case intValue:
- return value_.int_ < other.value_.int_;
- case uintValue:
- return value_.uint_ < other.value_.uint_;
- case realValue:
- return value_.real_ < other.value_.real_;
- case booleanValue:
- return value_.bool_ < other.value_.bool_;
- case stringValue:
- {
- if ((value_.string_ == 0) || (other.value_.string_ == 0)) {
- if (other.value_.string_) return true;
- else return false;
- }
- unsigned this_len;
- unsigned other_len;
- char const* this_str;
- char const* other_str;
- decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str);
- decodePrefixedString(other.allocated_, other.value_.string_, &other_len, &other_str);
- unsigned min_len = std::min(this_len, other_len);
- int comp = memcmp(this_str, other_str, min_len);
- if (comp < 0) return true;
- if (comp > 0) return false;
- return (this_len < other_len);
- }
- case arrayValue:
- case objectValue: {
- int delta = int(value_.map_->size() - other.value_.map_->size());
- if (delta)
- return delta < 0;
- return (*value_.map_) < (*other.value_.map_);
- }
- default:
- JSON_ASSERT_UNREACHABLE;
- }
- return false; // unreachable
-}
-
-bool Value::operator<=(const Value& other) const { return !(other < *this); }
-
-bool Value::operator>=(const Value& other) const { return !(*this < other); }
-
-bool Value::operator>(const Value& other) const { return other < *this; }
-
-bool Value::operator==(const Value& other) const {
- // if ( type_ != other.type_ )
- // GCC 2.95.3 says:
- // attempt to take address of bit-field structure member `Json::Value::type_'
- // Beats me, but a temp solves the problem.
- int temp = other.type_;
- if (type_ != temp)
- return false;
- switch (type_) {
- case nullValue:
- return true;
- case intValue:
- return value_.int_ == other.value_.int_;
- case uintValue:
- return value_.uint_ == other.value_.uint_;
- case realValue:
- return value_.real_ == other.value_.real_;
- case booleanValue:
- return value_.bool_ == other.value_.bool_;
- case stringValue:
- {
- if ((value_.string_ == 0) || (other.value_.string_ == 0)) {
- return (value_.string_ == other.value_.string_);
- }
- unsigned this_len;
- unsigned other_len;
- char const* this_str;
- char const* other_str;
- decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str);
- decodePrefixedString(other.allocated_, other.value_.string_, &other_len, &other_str);
- if (this_len != other_len) return false;
- int comp = memcmp(this_str, other_str, this_len);
- return comp == 0;
- }
- case arrayValue:
- case objectValue:
- return value_.map_->size() == other.value_.map_->size() &&
- (*value_.map_) == (*other.value_.map_);
- default:
- JSON_ASSERT_UNREACHABLE;
- }
- return false; // unreachable
-}
-
-bool Value::operator!=(const Value& other) const { return !(*this == other); }
-
-const char* Value::asCString() const {
- JSON_ASSERT_MESSAGE(type_ == stringValue,
- "in Json::Value::asCString(): requires stringValue");
- if (value_.string_ == 0) return 0;
- unsigned this_len;
- char const* this_str;
- decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str);
- return this_str;
-}
-
-bool Value::getString(char const** str, char const** cend) const {
- if (type_ != stringValue) return false;
- if (value_.string_ == 0) return false;
- unsigned length;
- decodePrefixedString(this->allocated_, this->value_.string_, &length, str);
- *cend = *str + length;
- return true;
-}
-
-std::string Value::asString() const {
- switch (type_) {
- case nullValue:
- return "";
- case stringValue:
- {
- if (value_.string_ == 0) return "";
- unsigned this_len;
- char const* this_str;
- decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str);
- return std::string(this_str, this_len);
- }
- case booleanValue:
- return value_.bool_ ? "true" : "false";
- case intValue:
- return valueToString(value_.int_);
- case uintValue:
- return valueToString(value_.uint_);
- case realValue:
- return valueToString(value_.real_);
- default:
- JSON_FAIL_MESSAGE("Type is not convertible to string");
- }
-}
-
-#ifdef JSON_USE_CPPTL
-CppTL::ConstString Value::asConstString() const {
- unsigned len;
- char const* str;
- decodePrefixedString(allocated_, value_.string_,
- &len, &str);
- return CppTL::ConstString(str, len);
-}
-#endif
-
-Value::Int Value::asInt() const {
- switch (type_) {
- case intValue:
- JSON_ASSERT_MESSAGE(isInt(), "LargestInt out of Int range");
- return Int(value_.int_);
- case uintValue:
- JSON_ASSERT_MESSAGE(isInt(), "LargestUInt out of Int range");
- return Int(value_.uint_);
- case realValue:
- JSON_ASSERT_MESSAGE(InRange(value_.real_, minInt, maxInt),
- "double out of Int range");
- return Int(value_.real_);
- case nullValue:
- return 0;
- case booleanValue:
- return value_.bool_ ? 1 : 0;
- default:
- break;
- }
- JSON_FAIL_MESSAGE("Value is not convertible to Int.");
-}
-
-Value::UInt Value::asUInt() const {
- switch (type_) {
- case intValue:
- JSON_ASSERT_MESSAGE(isUInt(), "LargestInt out of UInt range");
- return UInt(value_.int_);
- case uintValue:
- JSON_ASSERT_MESSAGE(isUInt(), "LargestUInt out of UInt range");
- return UInt(value_.uint_);
- case realValue:
- JSON_ASSERT_MESSAGE(InRange(value_.real_, 0, maxUInt),
- "double out of UInt range");
- return UInt(value_.real_);
- case nullValue:
- return 0;
- case booleanValue:
- return value_.bool_ ? 1 : 0;
- default:
- break;
- }
- JSON_FAIL_MESSAGE("Value is not convertible to UInt.");
-}
-
-#if defined(JSON_HAS_INT64)
-
-Value::Int64 Value::asInt64() const {
- switch (type_) {
- case intValue:
- return Int64(value_.int_);
- case uintValue:
- JSON_ASSERT_MESSAGE(isInt64(), "LargestUInt out of Int64 range");
- return Int64(value_.uint_);
- case realValue:
- JSON_ASSERT_MESSAGE(InRange(value_.real_, minInt64, maxInt64),
- "double out of Int64 range");
- return Int64(value_.real_);
- case nullValue:
- return 0;
- case booleanValue:
- return value_.bool_ ? 1 : 0;
- default:
- break;
- }
- JSON_FAIL_MESSAGE("Value is not convertible to Int64.");
-}
-
-Value::UInt64 Value::asUInt64() const {
- switch (type_) {
- case intValue:
- JSON_ASSERT_MESSAGE(isUInt64(), "LargestInt out of UInt64 range");
- return UInt64(value_.int_);
- case uintValue:
- return UInt64(value_.uint_);
- case realValue:
- JSON_ASSERT_MESSAGE(InRange(value_.real_, 0, maxUInt64),
- "double out of UInt64 range");
- return UInt64(value_.real_);
- case nullValue:
- return 0;
- case booleanValue:
- return value_.bool_ ? 1 : 0;
- default:
- break;
- }
- JSON_FAIL_MESSAGE("Value is not convertible to UInt64.");
-}
-#endif // if defined(JSON_HAS_INT64)
-
-LargestInt Value::asLargestInt() const {
-#if defined(JSON_NO_INT64)
- return asInt();
-#else
- return asInt64();
-#endif
-}
-
-LargestUInt Value::asLargestUInt() const {
-#if defined(JSON_NO_INT64)
- return asUInt();
-#else
- return asUInt64();
-#endif
-}
-
-double Value::asDouble() const {
- switch (type_) {
- case intValue:
- return static_cast<double>(value_.int_);
- case uintValue:
-#if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
- return static_cast<double>(value_.uint_);
-#else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
- return integerToDouble(value_.uint_);
-#endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
- case realValue:
- return value_.real_;
- case nullValue:
- return 0.0;
- case booleanValue:
- return value_.bool_ ? 1.0 : 0.0;
- default:
- break;
- }
- JSON_FAIL_MESSAGE("Value is not convertible to double.");
-}
-
-float Value::asFloat() const {
- switch (type_) {
- case intValue:
- return static_cast<float>(value_.int_);
- case uintValue:
-#if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
- return static_cast<float>(value_.uint_);
-#else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
- return integerToDouble(value_.uint_);
-#endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
- case realValue:
- return static_cast<float>(value_.real_);
- case nullValue:
- return 0.0;
- case booleanValue:
- return value_.bool_ ? 1.0f : 0.0f;
- default:
- break;
- }
- JSON_FAIL_MESSAGE("Value is not convertible to float.");
-}
-
-bool Value::asBool() const {
- switch (type_) {
- case booleanValue:
- return value_.bool_;
- case nullValue:
- return false;
- case intValue:
- return value_.int_ ? true : false;
- case uintValue:
- return value_.uint_ ? true : false;
- case realValue:
- // This is kind of strange. Not recommended.
- return (value_.real_ != 0.0) ? true : false;
- default:
- break;
- }
- JSON_FAIL_MESSAGE("Value is not convertible to bool.");
-}
-
-bool Value::isConvertibleTo(ValueType other) const {
- switch (other) {
- case nullValue:
- return (isNumeric() && asDouble() == 0.0) ||
- (type_ == booleanValue && value_.bool_ == false) ||
- (type_ == stringValue && asString() == "") ||
- (type_ == arrayValue && value_.map_->size() == 0) ||
- (type_ == objectValue && value_.map_->size() == 0) ||
- type_ == nullValue;
- case intValue:
- return isInt() ||
- (type_ == realValue && InRange(value_.real_, minInt, maxInt)) ||
- type_ == booleanValue || type_ == nullValue;
- case uintValue:
- return isUInt() ||
- (type_ == realValue && InRange(value_.real_, 0, maxUInt)) ||
- type_ == booleanValue || type_ == nullValue;
- case realValue:
- return isNumeric() || type_ == booleanValue || type_ == nullValue;
- case booleanValue:
- return isNumeric() || type_ == booleanValue || type_ == nullValue;
- case stringValue:
- return isNumeric() || type_ == booleanValue || type_ == stringValue ||
- type_ == nullValue;
- case arrayValue:
- return type_ == arrayValue || type_ == nullValue;
- case objectValue:
- return type_ == objectValue || type_ == nullValue;
- }
- JSON_ASSERT_UNREACHABLE;
- return false;
-}
-
-/// Number of values in array or object
-ArrayIndex Value::size() const {
- switch (type_) {
- case nullValue:
- case intValue:
- case uintValue:
- case realValue:
- case booleanValue:
- case stringValue:
- return 0;
- case arrayValue: // size of the array is highest index + 1
- if (!value_.map_->empty()) {
- ObjectValues::const_iterator itLast = value_.map_->end();
- --itLast;
- return (*itLast).first.index() + 1;
- }
- return 0;
- case objectValue:
- return ArrayIndex(value_.map_->size());
- }
- JSON_ASSERT_UNREACHABLE;
- return 0; // unreachable;
-}
-
-bool Value::empty() const {
- if (isNull() || isArray() || isObject())
- return size() == 0u;
- else
- return false;
-}
-
-bool Value::operator!() const { return isNull(); }
-
-void Value::clear() {
- JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == arrayValue ||
- type_ == objectValue,
- "in Json::Value::clear(): requires complex value");
- start_ = 0;
- limit_ = 0;
- switch (type_) {
- case arrayValue:
- case objectValue:
- value_.map_->clear();
- break;
- default:
- break;
- }
-}
-
-void Value::resize(ArrayIndex newSize) {
- JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == arrayValue,
- "in Json::Value::resize(): requires arrayValue");
- if (type_ == nullValue)
- *this = Value(arrayValue);
- ArrayIndex oldSize = size();
- if (newSize == 0)
- clear();
- else if (newSize > oldSize)
- (*this)[newSize - 1];
- else {
- for (ArrayIndex index = newSize; index < oldSize; ++index) {
- value_.map_->erase(index);
- }
- assert(size() == newSize);
- }
-}
-
-Value& Value::operator[](ArrayIndex index) {
- JSON_ASSERT_MESSAGE(
- type_ == nullValue || type_ == arrayValue,
- "in Json::Value::operator[](ArrayIndex): requires arrayValue");
- if (type_ == nullValue)
- *this = Value(arrayValue);
- CZString key(index);
- ObjectValues::iterator it = value_.map_->lower_bound(key);
- if (it != value_.map_->end() && (*it).first == key)
- return (*it).second;
-
- ObjectValues::value_type defaultValue(key, nullRef);
- it = value_.map_->insert(it, defaultValue);
- return (*it).second;
-}
-
-Value& Value::operator[](int index) {
- JSON_ASSERT_MESSAGE(
- index >= 0,
- "in Json::Value::operator[](int index): index cannot be negative");
- return (*this)[ArrayIndex(index)];
-}
-
-const Value& Value::operator[](ArrayIndex index) const {
- JSON_ASSERT_MESSAGE(
- type_ == nullValue || type_ == arrayValue,
- "in Json::Value::operator[](ArrayIndex)const: requires arrayValue");
- if (type_ == nullValue)
- return nullRef;
- CZString key(index);
- ObjectValues::const_iterator it = value_.map_->find(key);
- if (it == value_.map_->end())
- return nullRef;
- return (*it).second;
-}
-
-const Value& Value::operator[](int index) const {
- JSON_ASSERT_MESSAGE(
- index >= 0,
- "in Json::Value::operator[](int index) const: index cannot be negative");
- return (*this)[ArrayIndex(index)];
-}
-
-void Value::initBasic(ValueType vtype, bool allocated) {
- type_ = vtype;
- allocated_ = allocated;
- comments_ = 0;
- start_ = 0;
- limit_ = 0;
-}
-
-// Access an object value by name, create a null member if it does not exist.
-// @pre Type of '*this' is object or null.
-// @param key is null-terminated.
-Value& Value::resolveReference(const char* key) {
- JSON_ASSERT_MESSAGE(
- type_ == nullValue || type_ == objectValue,
- "in Json::Value::resolveReference(): requires objectValue");
- if (type_ == nullValue)
- *this = Value(objectValue);
- CZString actualKey(
- key, static_cast<unsigned>(strlen(key)), CZString::noDuplication); // NOTE!
- ObjectValues::iterator it = value_.map_->lower_bound(actualKey);
- if (it != value_.map_->end() && (*it).first == actualKey)
- return (*it).second;
-
- ObjectValues::value_type defaultValue(actualKey, nullRef);
- it = value_.map_->insert(it, defaultValue);
- Value& value = (*it).second;
- return value;
-}
-
-// @param key is not null-terminated.
-Value& Value::resolveReference(char const* key, char const* cend)
-{
- JSON_ASSERT_MESSAGE(
- type_ == nullValue || type_ == objectValue,
- "in Json::Value::resolveReference(key, end): requires objectValue");
- if (type_ == nullValue)
- *this = Value(objectValue);
- CZString actualKey(
- key, static_cast<unsigned>(cend-key), CZString::duplicateOnCopy);
- ObjectValues::iterator it = value_.map_->lower_bound(actualKey);
- if (it != value_.map_->end() && (*it).first == actualKey)
- return (*it).second;
-
- ObjectValues::value_type defaultValue(actualKey, nullRef);
- it = value_.map_->insert(it, defaultValue);
- Value& value = (*it).second;
- return value;
-}
-
-Value Value::get(ArrayIndex index, const Value& defaultValue) const {
- const Value* value = &((*this)[index]);
- return value == &nullRef ? defaultValue : *value;
-}
-
-bool Value::isValidIndex(ArrayIndex index) const { return index < size(); }
-
-Value const* Value::find(char const* key, char const* cend) const
-{
- JSON_ASSERT_MESSAGE(
- type_ == nullValue || type_ == objectValue,
- "in Json::Value::find(key, end, found): requires objectValue or nullValue");
- if (type_ == nullValue) return NULL;
- CZString actualKey(key, static_cast<unsigned>(cend-key), CZString::noDuplication);
- ObjectValues::const_iterator it = value_.map_->find(actualKey);
- if (it == value_.map_->end()) return NULL;
- return &(*it).second;
-}
-const Value& Value::operator[](const char* key) const
-{
- Value const* found = find(key, key + strlen(key));
- if (!found) return nullRef;
- return *found;
-}
-Value const& Value::operator[](std::string const& key) const
-{
- Value const* found = find(key.data(), key.data() + key.length());
- if (!found) return nullRef;
- return *found;
-}
-
-Value& Value::operator[](const char* key) {
- return resolveReference(key, key + strlen(key));
-}
-
-Value& Value::operator[](const std::string& key) {
- return resolveReference(key.data(), key.data() + key.length());
-}
-
-Value& Value::operator[](const StaticString& key) {
- return resolveReference(key.c_str());
-}
-
-#ifdef JSON_USE_CPPTL
-Value& Value::operator[](const CppTL::ConstString& key) {
- return resolveReference(key.c_str(), key.end_c_str());
-}
-Value const& Value::operator[](CppTL::ConstString const& key) const
-{
- Value const* found = find(key.c_str(), key.end_c_str());
- if (!found) return nullRef;
- return *found;
-}
-#endif
-
-Value& Value::append(const Value& value) { return (*this)[size()] = value; }
-
-Value Value::get(char const* key, char const* cend, Value const& defaultValue) const
-{
- Value const* found = find(key, cend);
- return !found ? defaultValue : *found;
-}
-Value Value::get(char const* key, Value const& defaultValue) const
-{
- return get(key, key + strlen(key), defaultValue);
-}
-Value Value::get(std::string const& key, Value const& defaultValue) const
-{
- return get(key.data(), key.data() + key.length(), defaultValue);
-}
-
-
-bool Value::removeMember(const char* key, const char* cend, Value* removed)
-{
- if (type_ != objectValue) {
- return false;
- }
- CZString actualKey(key, static_cast<unsigned>(cend-key), CZString::noDuplication);
- ObjectValues::iterator it = value_.map_->find(actualKey);
- if (it == value_.map_->end())
- return false;
- *removed = it->second;
- value_.map_->erase(it);
- return true;
-}
-bool Value::removeMember(const char* key, Value* removed)
-{
- return removeMember(key, key + strlen(key), removed);
-}
-bool Value::removeMember(std::string const& key, Value* removed)
-{
- return removeMember(key.data(), key.data() + key.length(), removed);
-}
-Value Value::removeMember(const char* key)
-{
- JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == objectValue,
- "in Json::Value::removeMember(): requires objectValue");
- if (type_ == nullValue)
- return nullRef;
-
- Value removed; // null
- removeMember(key, key + strlen(key), &removed);
- return removed; // still null if removeMember() did nothing
-}
-Value Value::removeMember(const std::string& key)
-{
- return removeMember(key.c_str());
-}
-
-bool Value::removeIndex(ArrayIndex index, Value* removed) {
- if (type_ != arrayValue) {
- return false;
- }
- CZString key(index);
- ObjectValues::iterator it = value_.map_->find(key);
- if (it == value_.map_->end()) {
- return false;
- }
- *removed = it->second;
- ArrayIndex oldSize = size();
- // shift left all items left, into the place of the "removed"
- for (ArrayIndex i = index; i < (oldSize - 1); ++i){
- CZString keey(i);
- (*value_.map_)[keey] = (*this)[i + 1];
- }
- // erase the last one ("leftover")
- CZString keyLast(oldSize - 1);
- ObjectValues::iterator itLast = value_.map_->find(keyLast);
- value_.map_->erase(itLast);
- return true;
-}
-
-#ifdef JSON_USE_CPPTL
-Value Value::get(const CppTL::ConstString& key,
- const Value& defaultValue) const {
- return get(key.c_str(), key.end_c_str(), defaultValue);
-}
-#endif
-
-bool Value::isMember(char const* key, char const* cend) const
-{
- Value const* value = find(key, cend);
- return NULL != value;
-}
-bool Value::isMember(char const* key) const
-{
- return isMember(key, key + strlen(key));
-}
-bool Value::isMember(std::string const& key) const
-{
- return isMember(key.data(), key.data() + key.length());
-}
-
-#ifdef JSON_USE_CPPTL
-bool Value::isMember(const CppTL::ConstString& key) const {
- return isMember(key.c_str(), key.end_c_str());
-}
-#endif
-
-Value::Members Value::getMemberNames() const {
- JSON_ASSERT_MESSAGE(
- type_ == nullValue || type_ == objectValue,
- "in Json::Value::getMemberNames(), value must be objectValue");
- if (type_ == nullValue)
- return Value::Members();
- Members members;
- members.reserve(value_.map_->size());
- ObjectValues::const_iterator it = value_.map_->begin();
- ObjectValues::const_iterator itEnd = value_.map_->end();
- for (; it != itEnd; ++it) {
- members.push_back(std::string((*it).first.data(),
- (*it).first.length()));
- }
- return members;
-}
-//
-//# ifdef JSON_USE_CPPTL
-// EnumMemberNames
-// Value::enumMemberNames() const
-//{
-// if ( type_ == objectValue )
-// {
-// return CppTL::Enum::any( CppTL::Enum::transform(
-// CppTL::Enum::keys( *(value_.map_), CppTL::Type<const CZString &>() ),
-// MemberNamesTransform() ) );
-// }
-// return EnumMemberNames();
-//}
-//
-//
-// EnumValues
-// Value::enumValues() const
-//{
-// if ( type_ == objectValue || type_ == arrayValue )
-// return CppTL::Enum::anyValues( *(value_.map_),
-// CppTL::Type<const Value &>() );
-// return EnumValues();
-//}
-//
-//# endif
-
-static bool IsIntegral(double d) {
- double integral_part;
- return modf(d, &integral_part) == 0.0;
-}
-
-bool Value::isNull() const { return type_ == nullValue; }
-
-bool Value::isBool() const { return type_ == booleanValue; }
-
-bool Value::isInt() const {
- switch (type_) {
- case intValue:
- return value_.int_ >= minInt && value_.int_ <= maxInt;
- case uintValue:
- return value_.uint_ <= UInt(maxInt);
- case realValue:
- return value_.real_ >= minInt && value_.real_ <= maxInt &&
- IsIntegral(value_.real_);
- default:
- break;
- }
- return false;
-}
-
-bool Value::isUInt() const {
- switch (type_) {
- case intValue:
- return value_.int_ >= 0 && LargestUInt(value_.int_) <= LargestUInt(maxUInt);
- case uintValue:
- return value_.uint_ <= maxUInt;
- case realValue:
- return value_.real_ >= 0 && value_.real_ <= maxUInt &&
- IsIntegral(value_.real_);
- default:
- break;
- }
- return false;
-}
-
-bool Value::isInt64() const {
-#if defined(JSON_HAS_INT64)
- switch (type_) {
- case intValue:
- return true;
- case uintValue:
- return value_.uint_ <= UInt64(maxInt64);
- case realValue:
- // Note that maxInt64 (= 2^63 - 1) is not exactly representable as a
- // double, so double(maxInt64) will be rounded up to 2^63. Therefore we
- // require the value to be strictly less than the limit.
- return value_.real_ >= double(minInt64) &&
- value_.real_ < double(maxInt64) && IsIntegral(value_.real_);
- default:
- break;
- }
-#endif // JSON_HAS_INT64
- return false;
-}
-
-bool Value::isUInt64() const {
-#if defined(JSON_HAS_INT64)
- switch (type_) {
- case intValue:
- return value_.int_ >= 0;
- case uintValue:
- return true;
- case realValue:
- // Note that maxUInt64 (= 2^64 - 1) is not exactly representable as a
- // double, so double(maxUInt64) will be rounded up to 2^64. Therefore we
- // require the value to be strictly less than the limit.
- return value_.real_ >= 0 && value_.real_ < maxUInt64AsDouble &&
- IsIntegral(value_.real_);
- default:
- break;
- }
-#endif // JSON_HAS_INT64
- return false;
-}
-
-bool Value::isIntegral() const {
-#if defined(JSON_HAS_INT64)
- return isInt64() || isUInt64();
-#else
- return isInt() || isUInt();
-#endif
-}
-
-bool Value::isDouble() const { return type_ == realValue || isIntegral(); }
-
-bool Value::isNumeric() const { return isIntegral() || isDouble(); }
-
-bool Value::isString() const { return type_ == stringValue; }
-
-bool Value::isArray() const { return type_ == arrayValue; }
-
-bool Value::isObject() const { return type_ == objectValue; }
-
-void Value::setComment(const char* comment, size_t len, CommentPlacement placement) {
- if (!comments_)
- comments_ = new CommentInfo[numberOfCommentPlacement];
- if ((len > 0) && (comment[len-1] == '\n')) {
- // Always discard trailing newline, to aid indentation.
- len -= 1;
- }
- comments_[placement].setComment(comment, len);
-}
-
-void Value::setComment(const char* comment, CommentPlacement placement) {
- setComment(comment, strlen(comment), placement);
-}
-
-void Value::setComment(const std::string& comment, CommentPlacement placement) {
- setComment(comment.c_str(), comment.length(), placement);
-}
-
-bool Value::hasComment(CommentPlacement placement) const {
- return comments_ != 0 && comments_[placement].comment_ != 0;
-}
-
-std::string Value::getComment(CommentPlacement placement) const {
- if (hasComment(placement))
- return comments_[placement].comment_;
- return "";
-}
-
-void Value::setOffsetStart(size_t start) { start_ = start; }
-
-void Value::setOffsetLimit(size_t limit) { limit_ = limit; }
-
-size_t Value::getOffsetStart() const { return start_; }
-
-size_t Value::getOffsetLimit() const { return limit_; }
-
-std::string Value::toStyledString() const {
- StyledWriter writer;
- return writer.write(*this);
-}
-
-Value::const_iterator Value::begin() const {
- switch (type_) {
- case arrayValue:
- case objectValue:
- if (value_.map_)
- return const_iterator(value_.map_->begin());
- break;
- default:
- break;
- }
- return const_iterator();
-}
-
-Value::const_iterator Value::end() const {
- switch (type_) {
- case arrayValue:
- case objectValue:
- if (value_.map_)
- return const_iterator(value_.map_->end());
- break;
- default:
- break;
- }
- return const_iterator();
-}
-
-Value::iterator Value::begin() {
- switch (type_) {
- case arrayValue:
- case objectValue:
- if (value_.map_)
- return iterator(value_.map_->begin());
- break;
- default:
- break;
- }
- return iterator();
-}
-
-Value::iterator Value::end() {
- switch (type_) {
- case arrayValue:
- case objectValue:
- if (value_.map_)
- return iterator(value_.map_->end());
- break;
- default:
- break;
- }
- return iterator();
-}
-
-// class PathArgument
-// //////////////////////////////////////////////////////////////////
-
-PathArgument::PathArgument() : key_(), index_(), kind_(kindNone) {}
-
-PathArgument::PathArgument(ArrayIndex index)
- : key_(), index_(index), kind_(kindIndex) {}
-
-PathArgument::PathArgument(const char* key)
- : key_(key), index_(), kind_(kindKey) {}
-
-PathArgument::PathArgument(const std::string& key)
- : key_(key.c_str()), index_(), kind_(kindKey) {}
-
-// class Path
-// //////////////////////////////////////////////////////////////////
-
-Path::Path(const std::string& path,
- const PathArgument& a1,
- const PathArgument& a2,
- const PathArgument& a3,
- const PathArgument& a4,
- const PathArgument& a5) {
- InArgs in;
- in.push_back(&a1);
- in.push_back(&a2);
- in.push_back(&a3);
- in.push_back(&a4);
- in.push_back(&a5);
- makePath(path, in);
-}
-
-void Path::makePath(const std::string& path, const InArgs& in) {
- const char* current = path.c_str();
- const char* end = current + path.length();
- InArgs::const_iterator itInArg = in.begin();
- while (current != end) {
- if (*current == '[') {
- ++current;
- if (*current == '%')
- addPathInArg(path, in, itInArg, PathArgument::kindIndex);
- else {
- ArrayIndex index = 0;
- for (; current != end && *current >= '0' && *current <= '9'; ++current)
- index = index * 10 + ArrayIndex(*current - '0');
- args_.push_back(index);
- }
- if (current == end || *current++ != ']')
- invalidPath(path, int(current - path.c_str()));
- } else if (*current == '%') {
- addPathInArg(path, in, itInArg, PathArgument::kindKey);
- ++current;
- } else if (*current == '.') {
- ++current;
- } else {
- const char* beginName = current;
- while (current != end && !strchr("[.", *current))
- ++current;
- args_.push_back(std::string(beginName, current));
- }
- }
-}
-
-void Path::addPathInArg(const std::string& /*path*/,
- const InArgs& in,
- InArgs::const_iterator& itInArg,
- PathArgument::Kind kind) {
- if (itInArg == in.end()) {
- // Error: missing argument %d
- } else if ((*itInArg)->kind_ != kind) {
- // Error: bad argument type
- } else {
- args_.push_back(**itInArg);
- }
-}
-
-void Path::invalidPath(const std::string& /*path*/, int /*location*/) {
- // Error: invalid path.
-}
-
-const Value& Path::resolve(const Value& root) const {
- const Value* node = &root;
- for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) {
- const PathArgument& arg = *it;
- if (arg.kind_ == PathArgument::kindIndex) {
- if (!node->isArray() || !node->isValidIndex(arg.index_)) {
- // Error: unable to resolve path (array value expected at position...
- }
- node = &((*node)[arg.index_]);
- } else if (arg.kind_ == PathArgument::kindKey) {
- if (!node->isObject()) {
- // Error: unable to resolve path (object value expected at position...)
- }
- node = &((*node)[arg.key_]);
- if (node == &Value::nullRef) {
- // Error: unable to resolve path (object has no member named '' at
- // position...)
- }
- }
- }
- return *node;
-}
-
-Value Path::resolve(const Value& root, const Value& defaultValue) const {
- const Value* node = &root;
- for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) {
- const PathArgument& arg = *it;
- if (arg.kind_ == PathArgument::kindIndex) {
- if (!node->isArray() || !node->isValidIndex(arg.index_))
- return defaultValue;
- node = &((*node)[arg.index_]);
- } else if (arg.kind_ == PathArgument::kindKey) {
- if (!node->isObject())
- return defaultValue;
- node = &((*node)[arg.key_]);
- if (node == &Value::nullRef)
- return defaultValue;
- }
- }
- return *node;
-}
-
-Value& Path::make(Value& root) const {
- Value* node = &root;
- for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) {
- const PathArgument& arg = *it;
- if (arg.kind_ == PathArgument::kindIndex) {
- if (!node->isArray()) {
- // Error: node is not an array at position ...
- }
- node = &((*node)[arg.index_]);
- } else if (arg.kind_ == PathArgument::kindKey) {
- if (!node->isObject()) {
- // Error: node is not an object at position...
- }
- node = &((*node)[arg.key_]);
- }
- }
- return *node;
-}
-
-} // namespace Json
-
-// //////////////////////////////////////////////////////////////////////
-// End of content of file: src/lib_json/json_value.cpp
-// //////////////////////////////////////////////////////////////////////
-
-
-
-
-
-
-// //////////////////////////////////////////////////////////////////////
-// Beginning of content of file: src/lib_json/json_writer.cpp
-// //////////////////////////////////////////////////////////////////////
-
-// Copyright 2011 Baptiste Lepilleur
-// Distributed under MIT license, or public domain if desired and
-// recognized in your jurisdiction.
-// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
-
-#if !defined(JSON_IS_AMALGAMATION)
-#include <json/writer.h>
-#include "json_tool.h"
-#endif // if !defined(JSON_IS_AMALGAMATION)
-#include <iomanip>
-#include <memory>
-#include <sstream>
-#include <utility>
-#include <set>
-#include <cassert>
-#include <cstring>
-#include <cstdio>
-
-#if defined(_MSC_VER) && _MSC_VER >= 1200 && _MSC_VER < 1800 // Between VC++ 6.0 and VC++ 11.0
-#include <float.h>
-#define isfinite _finite
-#elif defined(__sun) && defined(__SVR4) //Solaris
-#if !defined(isfinite)
-#include <ieeefp.h>
-#define isfinite finite
-#endif
-#elif defined(_AIX)
-#if !defined(isfinite)
-#include <math.h>
-#define isfinite finite
-#endif
-#elif defined(__hpux)
-#if !defined(isfinite)
-#if defined(__ia64) && !defined(finite)
-#define isfinite(x) ((sizeof(x) == sizeof(float) ? \
- _Isfinitef(x) : _IsFinite(x)))
-#else
-#include <math.h>
-#define isfinite finite
-#endif
-#endif
-#else
-#include <cmath>
-#if !(defined(__QNXNTO__)) // QNX already defines isfinite
-#define isfinite std::isfinite
-#endif
-#endif
-
-#if defined(_MSC_VER)
-#if !defined(WINCE) && defined(__STDC_SECURE_LIB__) && _MSC_VER >= 1500 // VC++ 9.0 and above
-#define snprintf sprintf_s
-#elif _MSC_VER >= 1900 // VC++ 14.0 and above
-#define snprintf std::snprintf
-#else
-#define snprintf _snprintf
-#endif
-#elif defined(__ANDROID__) || defined(__QNXNTO__)
-#define snprintf snprintf
-#elif __cplusplus >= 201103L
-#define snprintf std::snprintf
-#endif
-
-#if defined(__BORLANDC__)
-#include <float.h>
-#define isfinite _finite
-#define snprintf _snprintf
-#endif
-
-#if defined(_MSC_VER) && _MSC_VER >= 1400 // VC++ 8.0
-// Disable warning about strdup being deprecated.
-#pragma warning(disable : 4996)
-#endif
-
-namespace Json {
-
-#if __cplusplus >= 201103L || (defined(_CPPLIB_VER) && _CPPLIB_VER >= 520)
-typedef std::unique_ptr<StreamWriter> StreamWriterPtr;
-#else
-typedef std::auto_ptr<StreamWriter> StreamWriterPtr;
-#endif
-
-static bool containsControlCharacter(const char* str) {
- while (*str) {
- if (isControlCharacter(*(str++)))
- return true;
- }
- return false;
-}
-
-static bool containsControlCharacter0(const char* str, unsigned len) {
- char const* end = str + len;
- while (end != str) {
- if (isControlCharacter(*str) || 0==*str)
- return true;
- ++str;
- }
- return false;
-}
-
-std::string valueToString(LargestInt value) {
- UIntToStringBuffer buffer;
- char* current = buffer + sizeof(buffer);
- if (value == Value::minLargestInt) {
- uintToString(LargestUInt(Value::maxLargestInt) + 1, current);
- *--current = '-';
- } else if (value < 0) {
- uintToString(LargestUInt(-value), current);
- *--current = '-';
- } else {
- uintToString(LargestUInt(value), current);
- }
- assert(current >= buffer);
- return current;
-}
-
-std::string valueToString(LargestUInt value) {
- UIntToStringBuffer buffer;
- char* current = buffer + sizeof(buffer);
- uintToString(value, current);
- assert(current >= buffer);
- return current;
-}
-
-#if defined(JSON_HAS_INT64)
-
-std::string valueToString(Int value) {
- return valueToString(LargestInt(value));
-}
-
-std::string valueToString(UInt value) {
- return valueToString(LargestUInt(value));
-}
-
-#endif // # if defined(JSON_HAS_INT64)
-
-std::string valueToString(double value, bool useSpecialFloats, unsigned int precision) {
- // Allocate a buffer that is more than large enough to store the 16 digits of
- // precision requested below.
- char buffer[32];
- int len = -1;
-
- char formatString[6];
- sprintf(formatString, "%%.%dg", precision);
-
- // Print into the buffer. We need not request the alternative representation
- // that always has a decimal point because JSON doesn't distingish the
- // concepts of reals and integers.
- if (isfinite(value)) {
- len = snprintf(buffer, sizeof(buffer), formatString, value);
- } else {
- // IEEE standard states that NaN values will not compare to themselves
- if (value != value) {
- len = snprintf(buffer, sizeof(buffer), useSpecialFloats ? "NaN" : "null");
- } else if (value < 0) {
- len = snprintf(buffer, sizeof(buffer), useSpecialFloats ? "-Infinity" : "-1e+9999");
- } else {
- len = snprintf(buffer, sizeof(buffer), useSpecialFloats ? "Infinity" : "1e+9999");
- }
- // For those, we do not need to call fixNumLoc, but it is fast.
- }
- assert(len >= 0);
- fixNumericLocale(buffer, buffer + len);
- return buffer;
-}
-
-std::string valueToString(double value) { return valueToString(value, false, 17); }
-
-std::string valueToString(bool value) { return value ? "true" : "false"; }
-
-std::string valueToQuotedString(const char* value) {
- if (value == NULL)
- return "";
- // Not sure how to handle unicode...
- if (strpbrk(value, "\"\\\b\f\n\r\t") == NULL &&
- !containsControlCharacter(value))
- return std::string("\"") + value + "\"";
- // We have to walk value and escape any special characters.
- // Appending to std::string is not efficient, but this should be rare.
- // (Note: forward slashes are *not* rare, but I am not escaping them.)
- std::string::size_type maxsize =
- strlen(value) * 2 + 3; // allescaped+quotes+NULL
- std::string result;
- result.reserve(maxsize); // to avoid lots of mallocs
- result += "\"";
- for (const char* c = value; *c != 0; ++c) {
- switch (*c) {
- case '\"':
- result += "\\\"";
- break;
- case '\\':
- result += "\\\\";
- break;
- case '\b':
- result += "\\b";
- break;
- case '\f':
- result += "\\f";
- break;
- case '\n':
- result += "\\n";
- break;
- case '\r':
- result += "\\r";
- break;
- case '\t':
- result += "\\t";
- break;
- // case '/':
- // Even though \/ is considered a legal escape in JSON, a bare
- // slash is also legal, so I see no reason to escape it.
- // (I hope I am not misunderstanding something.
- // blep notes: actually escaping \/ may be useful in javascript to avoid </
- // sequence.
- // Should add a flag to allow this compatibility mode and prevent this
- // sequence from occurring.
- default:
- if (isControlCharacter(*c)) {
- std::ostringstream oss;
- oss << "\\u" << std::hex << std::uppercase << std::setfill('0')
- << std::setw(4) << static_cast<int>(*c);
- result += oss.str();
- } else {
- result += *c;
- }
- break;
- }
- }
- result += "\"";
- return result;
-}
-
-// https://github.com/upcaste/upcaste/blob/master/src/upcore/src/cstring/strnpbrk.cpp
-static char const* strnpbrk(char const* s, char const* accept, size_t n) {
- assert((s || !n) && accept);
-
- char const* const end = s + n;
- for (char const* cur = s; cur < end; ++cur) {
- int const c = *cur;
- for (char const* a = accept; *a; ++a) {
- if (*a == c) {
- return cur;
- }
- }
- }
- return NULL;
-}
-static std::string valueToQuotedStringN(const char* value, unsigned length) {
- if (value == NULL)
- return "";
- // Not sure how to handle unicode...
- if (strnpbrk(value, "\"\\\b\f\n\r\t", length) == NULL &&
- !containsControlCharacter0(value, length))
- return std::string("\"") + value + "\"";
- // We have to walk value and escape any special characters.
- // Appending to std::string is not efficient, but this should be rare.
- // (Note: forward slashes are *not* rare, but I am not escaping them.)
- std::string::size_type maxsize =
- length * 2 + 3; // allescaped+quotes+NULL
- std::string result;
- result.reserve(maxsize); // to avoid lots of mallocs
- result += "\"";
- char const* end = value + length;
- for (const char* c = value; c != end; ++c) {
- switch (*c) {
- case '\"':
- result += "\\\"";
- break;
- case '\\':
- result += "\\\\";
- break;
- case '\b':
- result += "\\b";
- break;
- case '\f':
- result += "\\f";
- break;
- case '\n':
- result += "\\n";
- break;
- case '\r':
- result += "\\r";
- break;
- case '\t':
- result += "\\t";
- break;
- // case '/':
- // Even though \/ is considered a legal escape in JSON, a bare
- // slash is also legal, so I see no reason to escape it.
- // (I hope I am not misunderstanding something.)
- // blep notes: actually escaping \/ may be useful in javascript to avoid </
- // sequence.
- // Should add a flag to allow this compatibility mode and prevent this
- // sequence from occurring.
- default:
- if ((isControlCharacter(*c)) || (*c == 0)) {
- std::ostringstream oss;
- oss << "\\u" << std::hex << std::uppercase << std::setfill('0')
- << std::setw(4) << static_cast<int>(*c);
- result += oss.str();
- } else {
- result += *c;
- }
- break;
- }
- }
- result += "\"";
- return result;
-}
-
-// Class Writer
-// //////////////////////////////////////////////////////////////////
-Writer::~Writer() {}
-
-// Class FastWriter
-// //////////////////////////////////////////////////////////////////
-
-FastWriter::FastWriter()
- : yamlCompatiblityEnabled_(false), dropNullPlaceholders_(false),
- omitEndingLineFeed_(false) {}
-
-void FastWriter::enableYAMLCompatibility() { yamlCompatiblityEnabled_ = true; }
-
-void FastWriter::dropNullPlaceholders() { dropNullPlaceholders_ = true; }
-
-void FastWriter::omitEndingLineFeed() { omitEndingLineFeed_ = true; }
-
-std::string FastWriter::write(const Value& root) {
- document_ = "";
- writeValue(root);
- if (!omitEndingLineFeed_)
- document_ += "\n";
- return document_;
-}
-
-void FastWriter::writeValue(const Value& value) {
- switch (value.type()) {
- case nullValue:
- if (!dropNullPlaceholders_)
- document_ += "null";
- break;
- case intValue:
- document_ += valueToString(value.asLargestInt());
- break;
- case uintValue:
- document_ += valueToString(value.asLargestUInt());
- break;
- case realValue:
- document_ += valueToString(value.asDouble());
- break;
- case stringValue:
- {
- // Is NULL possible for value.string_?
- char const* str;
- char const* end;
- bool ok = value.getString(&str, &end);
- if (ok) document_ += valueToQuotedStringN(str, static_cast<unsigned>(end-str));
- break;
- }
- case booleanValue:
- document_ += valueToString(value.asBool());
- break;
- case arrayValue: {
- document_ += '[';
- int size = value.size();
- for (int index = 0; index < size; ++index) {
- if (index > 0)
- document_ += ',';
- writeValue(value[index]);
- }
- document_ += ']';
- } break;
- case objectValue: {
- Value::Members members(value.getMemberNames());
- document_ += '{';
- for (Value::Members::iterator it = members.begin(); it != members.end();
- ++it) {
- const std::string& name = *it;
- if (it != members.begin())
- document_ += ',';
- document_ += valueToQuotedStringN(name.data(), static_cast<unsigned>(name.length()));
- document_ += yamlCompatiblityEnabled_ ? ": " : ":";
- writeValue(value[name]);
- }
- document_ += '}';
- } break;
- }
-}
-
-// Class StyledWriter
-// //////////////////////////////////////////////////////////////////
-
-StyledWriter::StyledWriter()
- : rightMargin_(74), indentSize_(3), addChildValues_() {}
-
-std::string StyledWriter::write(const Value& root) {
- document_ = "";
- addChildValues_ = false;
- indentString_ = "";
- writeCommentBeforeValue(root);
- writeValue(root);
- writeCommentAfterValueOnSameLine(root);
- document_ += "\n";
- return document_;
-}
-
-void StyledWriter::writeValue(const Value& value) {
- switch (value.type()) {
- case nullValue:
- pushValue("null");
- break;
- case intValue:
- pushValue(valueToString(value.asLargestInt()));
- break;
- case uintValue:
- pushValue(valueToString(value.asLargestUInt()));
- break;
- case realValue:
- pushValue(valueToString(value.asDouble()));
- break;
- case stringValue:
- {
- // Is NULL possible for value.string_?
- char const* str;
- char const* end;
- bool ok = value.getString(&str, &end);
- if (ok) pushValue(valueToQuotedStringN(str, static_cast<unsigned>(end-str)));
- else pushValue("");
- break;
- }
- case booleanValue:
- pushValue(valueToString(value.asBool()));
- break;
- case arrayValue:
- writeArrayValue(value);
- break;
- case objectValue: {
- Value::Members members(value.getMemberNames());
- if (members.empty())
- pushValue("{}");
- else {
- writeWithIndent("{");
- indent();
- Value::Members::iterator it = members.begin();
- for (;;) {
- const std::string& name = *it;
- const Value& childValue = value[name];
- writeCommentBeforeValue(childValue);
- writeWithIndent(valueToQuotedString(name.c_str()));
- document_ += " : ";
- writeValue(childValue);
- if (++it == members.end()) {
- writeCommentAfterValueOnSameLine(childValue);
- break;
- }
- document_ += ',';
- writeCommentAfterValueOnSameLine(childValue);
- }
- unindent();
- writeWithIndent("}");
- }
- } break;
- }
-}
-
-void StyledWriter::writeArrayValue(const Value& value) {
- unsigned size = value.size();
- if (size == 0)
- pushValue("[]");
- else {
- bool isArrayMultiLine = isMultineArray(value);
- if (isArrayMultiLine) {
- writeWithIndent("[");
- indent();
- bool hasChildValue = !childValues_.empty();
- unsigned index = 0;
- for (;;) {
- const Value& childValue = value[index];
- writeCommentBeforeValue(childValue);
- if (hasChildValue)
- writeWithIndent(childValues_[index]);
- else {
- writeIndent();
- writeValue(childValue);
- }
- if (++index == size) {
- writeCommentAfterValueOnSameLine(childValue);
- break;
- }
- document_ += ',';
- writeCommentAfterValueOnSameLine(childValue);
- }
- unindent();
- writeWithIndent("]");
- } else // output on a single line
- {
- assert(childValues_.size() == size);
- document_ += "[ ";
- for (unsigned index = 0; index < size; ++index) {
- if (index > 0)
- document_ += ", ";
- document_ += childValues_[index];
- }
- document_ += " ]";
- }
- }
-}
-
-bool StyledWriter::isMultineArray(const Value& value) {
- int size = value.size();
- bool isMultiLine = size * 3 >= rightMargin_;
- childValues_.clear();
- for (int index = 0; index < size && !isMultiLine; ++index) {
- const Value& childValue = value[index];
- isMultiLine = ((childValue.isArray() || childValue.isObject()) &&
- childValue.size() > 0);
- }
- if (!isMultiLine) // check if line length > max line length
- {
- childValues_.reserve(size);
- addChildValues_ = true;
- int lineLength = 4 + (size - 1) * 2; // '[ ' + ', '*n + ' ]'
- for (int index = 0; index < size; ++index) {
- if (hasCommentForValue(value[index])) {
- isMultiLine = true;
- }
- writeValue(value[index]);
- lineLength += int(childValues_[index].length());
- }
- addChildValues_ = false;
- isMultiLine = isMultiLine || lineLength >= rightMargin_;
- }
- return isMultiLine;
-}
-
-void StyledWriter::pushValue(const std::string& value) {
- if (addChildValues_)
- childValues_.push_back(value);
- else
- document_ += value;
-}
-
-void StyledWriter::writeIndent() {
- if (!document_.empty()) {
- char last = document_[document_.length() - 1];
- if (last == ' ') // already indented
- return;
- if (last != '\n') // Comments may add new-line
- document_ += '\n';
- }
- document_ += indentString_;
-}
-
-void StyledWriter::writeWithIndent(const std::string& value) {
- writeIndent();
- document_ += value;
-}
-
-void StyledWriter::indent() { indentString_ += std::string(indentSize_, ' '); }
-
-void StyledWriter::unindent() {
- assert(int(indentString_.size()) >= indentSize_);
- indentString_.resize(indentString_.size() - indentSize_);
-}
-
-void StyledWriter::writeCommentBeforeValue(const Value& root) {
- if (!root.hasComment(commentBefore))
- return;
-
- document_ += "\n";
- writeIndent();
- const std::string& comment = root.getComment(commentBefore);
- std::string::const_iterator iter = comment.begin();
- while (iter != comment.end()) {
- document_ += *iter;
- if (*iter == '\n' &&
- (iter != comment.end() && *(iter + 1) == '/'))
- writeIndent();
- ++iter;
- }
-
- // Comments are stripped of trailing newlines, so add one here
- document_ += "\n";
-}
-
-void StyledWriter::writeCommentAfterValueOnSameLine(const Value& root) {
- if (root.hasComment(commentAfterOnSameLine))
- document_ += " " + root.getComment(commentAfterOnSameLine);
-
- if (root.hasComment(commentAfter)) {
- document_ += "\n";
- document_ += root.getComment(commentAfter);
- document_ += "\n";
- }
-}
-
-bool StyledWriter::hasCommentForValue(const Value& value) {
- return value.hasComment(commentBefore) ||
- value.hasComment(commentAfterOnSameLine) ||
- value.hasComment(commentAfter);
-}
-
-// Class StyledStreamWriter
-// //////////////////////////////////////////////////////////////////
-
-StyledStreamWriter::StyledStreamWriter(std::string indentation)
- : document_(NULL), rightMargin_(74), indentation_(indentation),
- addChildValues_() {}
-
-void StyledStreamWriter::write(std::ostream& out, const Value& root) {
- document_ = &out;
- addChildValues_ = false;
- indentString_ = "";
- indented_ = true;
- writeCommentBeforeValue(root);
- if (!indented_) writeIndent();
- indented_ = true;
- writeValue(root);
- writeCommentAfterValueOnSameLine(root);
- *document_ << "\n";
- document_ = NULL; // Forget the stream, for safety.
-}
-
-void StyledStreamWriter::writeValue(const Value& value) {
- switch (value.type()) {
- case nullValue:
- pushValue("null");
- break;
- case intValue:
- pushValue(valueToString(value.asLargestInt()));
- break;
- case uintValue:
- pushValue(valueToString(value.asLargestUInt()));
- break;
- case realValue:
- pushValue(valueToString(value.asDouble()));
- break;
- case stringValue:
- {
- // Is NULL possible for value.string_?
- char const* str;
- char const* end;
- bool ok = value.getString(&str, &end);
- if (ok) pushValue(valueToQuotedStringN(str, static_cast<unsigned>(end-str)));
- else pushValue("");
- break;
- }
- case booleanValue:
- pushValue(valueToString(value.asBool()));
- break;
- case arrayValue:
- writeArrayValue(value);
- break;
- case objectValue: {
- Value::Members members(value.getMemberNames());
- if (members.empty())
- pushValue("{}");
- else {
- writeWithIndent("{");
- indent();
- Value::Members::iterator it = members.begin();
- for (;;) {
- const std::string& name = *it;
- const Value& childValue = value[name];
- writeCommentBeforeValue(childValue);
- writeWithIndent(valueToQuotedString(name.c_str()));
- *document_ << " : ";
- writeValue(childValue);
- if (++it == members.end()) {
- writeCommentAfterValueOnSameLine(childValue);
- break;
- }
- *document_ << ",";
- writeCommentAfterValueOnSameLine(childValue);
- }
- unindent();
- writeWithIndent("}");
- }
- } break;
- }
-}
-
-void StyledStreamWriter::writeArrayValue(const Value& value) {
- unsigned size = value.size();
- if (size == 0)
- pushValue("[]");
- else {
- bool isArrayMultiLine = isMultineArray(value);
- if (isArrayMultiLine) {
- writeWithIndent("[");
- indent();
- bool hasChildValue = !childValues_.empty();
- unsigned index = 0;
- for (;;) {
- const Value& childValue = value[index];
- writeCommentBeforeValue(childValue);
- if (hasChildValue)
- writeWithIndent(childValues_[index]);
- else {
- if (!indented_) writeIndent();
- indented_ = true;
- writeValue(childValue);
- indented_ = false;
- }
- if (++index == size) {
- writeCommentAfterValueOnSameLine(childValue);
- break;
- }
- *document_ << ",";
- writeCommentAfterValueOnSameLine(childValue);
- }
- unindent();
- writeWithIndent("]");
- } else // output on a single line
- {
- assert(childValues_.size() == size);
- *document_ << "[ ";
- for (unsigned index = 0; index < size; ++index) {
- if (index > 0)
- *document_ << ", ";
- *document_ << childValues_[index];
- }
- *document_ << " ]";
- }
- }
-}
-
-bool StyledStreamWriter::isMultineArray(const Value& value) {
- int size = value.size();
- bool isMultiLine = size * 3 >= rightMargin_;
- childValues_.clear();
- for (int index = 0; index < size && !isMultiLine; ++index) {
- const Value& childValue = value[index];
- isMultiLine = ((childValue.isArray() || childValue.isObject()) &&
- childValue.size() > 0);
- }
- if (!isMultiLine) // check if line length > max line length
- {
- childValues_.reserve(size);
- addChildValues_ = true;
- int lineLength = 4 + (size - 1) * 2; // '[ ' + ', '*n + ' ]'
- for (int index = 0; index < size; ++index) {
- if (hasCommentForValue(value[index])) {
- isMultiLine = true;
- }
- writeValue(value[index]);
- lineLength += int(childValues_[index].length());
- }
- addChildValues_ = false;
- isMultiLine = isMultiLine || lineLength >= rightMargin_;
- }
- return isMultiLine;
-}
-
-void StyledStreamWriter::pushValue(const std::string& value) {
- if (addChildValues_)
- childValues_.push_back(value);
- else
- *document_ << value;
-}
-
-void StyledStreamWriter::writeIndent() {
- // blep intended this to look at the so-far-written string
- // to determine whether we are already indented, but
- // with a stream we cannot do that. So we rely on some saved state.
- // The caller checks indented_.
- *document_ << '\n' << indentString_;
-}
-
-void StyledStreamWriter::writeWithIndent(const std::string& value) {
- if (!indented_) writeIndent();
- *document_ << value;
- indented_ = false;
-}
-
-void StyledStreamWriter::indent() { indentString_ += indentation_; }
-
-void StyledStreamWriter::unindent() {
- assert(indentString_.size() >= indentation_.size());
- indentString_.resize(indentString_.size() - indentation_.size());
-}
-
-void StyledStreamWriter::writeCommentBeforeValue(const Value& root) {
- if (!root.hasComment(commentBefore))
- return;
-
- if (!indented_) writeIndent();
- const std::string& comment = root.getComment(commentBefore);
- std::string::const_iterator iter = comment.begin();
- while (iter != comment.end()) {
- *document_ << *iter;
- if (*iter == '\n' &&
- (iter != comment.end() && *(iter + 1) == '/'))
- // writeIndent(); // would include newline
- *document_ << indentString_;
- ++iter;
- }
- indented_ = false;
-}
-
-void StyledStreamWriter::writeCommentAfterValueOnSameLine(const Value& root) {
- if (root.hasComment(commentAfterOnSameLine))
- *document_ << ' ' << root.getComment(commentAfterOnSameLine);
-
- if (root.hasComment(commentAfter)) {
- writeIndent();
- *document_ << root.getComment(commentAfter);
- }
- indented_ = false;
-}
-
-bool StyledStreamWriter::hasCommentForValue(const Value& value) {
- return value.hasComment(commentBefore) ||
- value.hasComment(commentAfterOnSameLine) ||
- value.hasComment(commentAfter);
-}
-
-//////////////////////////
-// BuiltStyledStreamWriter
-
-/// Scoped enums are not available until C++11.
-struct CommentStyle {
- /// Decide whether to write comments.
- enum Enum {
- None, ///< Drop all comments.
- Most, ///< Recover odd behavior of previous versions (not implemented yet).
- All ///< Keep all comments.
- };
-};
-
-struct BuiltStyledStreamWriter : public StreamWriter
-{
- BuiltStyledStreamWriter(
- std::string const& indentation,
- CommentStyle::Enum cs,
- std::string const& colonSymbol,
- std::string const& nullSymbol,
- std::string const& endingLineFeedSymbol,
- bool useSpecialFloats,
- unsigned int precision);
- int write(Value const& root, std::ostream* sout) override;
-private:
- void writeValue(Value const& value);
- void writeArrayValue(Value const& value);
- bool isMultineArray(Value const& value);
- void pushValue(std::string const& value);
- void writeIndent();
- void writeWithIndent(std::string const& value);
- void indent();
- void unindent();
- void writeCommentBeforeValue(Value const& root);
- void writeCommentAfterValueOnSameLine(Value const& root);
- static bool hasCommentForValue(const Value& value);
-
- typedef std::vector<std::string> ChildValues;
-
- ChildValues childValues_;
- std::string indentString_;
- int rightMargin_;
- std::string indentation_;
- CommentStyle::Enum cs_;
- std::string colonSymbol_;
- std::string nullSymbol_;
- std::string endingLineFeedSymbol_;
- bool addChildValues_ : 1;
- bool indented_ : 1;
- bool useSpecialFloats_ : 1;
- unsigned int precision_;
-};
-BuiltStyledStreamWriter::BuiltStyledStreamWriter(
- std::string const& indentation,
- CommentStyle::Enum cs,
- std::string const& colonSymbol,
- std::string const& nullSymbol,
- std::string const& endingLineFeedSymbol,
- bool useSpecialFloats,
- unsigned int precision)
- : rightMargin_(74)
- , indentation_(indentation)
- , cs_(cs)
- , colonSymbol_(colonSymbol)
- , nullSymbol_(nullSymbol)
- , endingLineFeedSymbol_(endingLineFeedSymbol)
- , addChildValues_(false)
- , indented_(false)
- , useSpecialFloats_(useSpecialFloats)
- , precision_(precision)
-{
-}
-int BuiltStyledStreamWriter::write(Value const& root, std::ostream* sout)
-{
- sout_ = sout;
- addChildValues_ = false;
- indented_ = true;
- indentString_ = "";
- writeCommentBeforeValue(root);
- if (!indented_) writeIndent();
- indented_ = true;
- writeValue(root);
- writeCommentAfterValueOnSameLine(root);
- *sout_ << endingLineFeedSymbol_;
- sout_ = NULL;
- return 0;
-}
-void BuiltStyledStreamWriter::writeValue(Value const& value) {
- switch (value.type()) {
- case nullValue:
- pushValue(nullSymbol_);
- break;
- case intValue:
- pushValue(valueToString(value.asLargestInt()));
- break;
- case uintValue:
- pushValue(valueToString(value.asLargestUInt()));
- break;
- case realValue:
- pushValue(valueToString(value.asDouble(), useSpecialFloats_, precision_));
- break;
- case stringValue:
- {
- // Is NULL is possible for value.string_?
- char const* str;
- char const* end;
- bool ok = value.getString(&str, &end);
- if (ok) pushValue(valueToQuotedStringN(str, static_cast<unsigned>(end-str)));
- else pushValue("");
- break;
- }
- case booleanValue:
- pushValue(valueToString(value.asBool()));
- break;
- case arrayValue:
- writeArrayValue(value);
- break;
- case objectValue: {
- Value::Members members(value.getMemberNames());
- if (members.empty())
- pushValue("{}");
- else {
- writeWithIndent("{");
- indent();
- Value::Members::iterator it = members.begin();
- for (;;) {
- std::string const& name = *it;
- Value const& childValue = value[name];
- writeCommentBeforeValue(childValue);
- writeWithIndent(valueToQuotedStringN(name.data(), static_cast<unsigned>(name.length())));
- *sout_ << colonSymbol_;
- writeValue(childValue);
- if (++it == members.end()) {
- writeCommentAfterValueOnSameLine(childValue);
- break;
- }
- *sout_ << ",";
- writeCommentAfterValueOnSameLine(childValue);
- }
- unindent();
- writeWithIndent("}");
- }
- } break;
- }
-}
-
-void BuiltStyledStreamWriter::writeArrayValue(Value const& value) {
- unsigned size = value.size();
- if (size == 0)
- pushValue("[]");
- else {
- bool isMultiLine = (cs_ == CommentStyle::All) || isMultineArray(value);
- if (isMultiLine) {
- writeWithIndent("[");
- indent();
- bool hasChildValue = !childValues_.empty();
- unsigned index = 0;
- for (;;) {
- Value const& childValue = value[index];
- writeCommentBeforeValue(childValue);
- if (hasChildValue)
- writeWithIndent(childValues_[index]);
- else {
- if (!indented_) writeIndent();
- indented_ = true;
- writeValue(childValue);
- indented_ = false;
- }
- if (++index == size) {
- writeCommentAfterValueOnSameLine(childValue);
- break;
- }
- *sout_ << ",";
- writeCommentAfterValueOnSameLine(childValue);
- }
- unindent();
- writeWithIndent("]");
- } else // output on a single line
- {
- assert(childValues_.size() == size);
- *sout_ << "[";
- if (!indentation_.empty()) *sout_ << " ";
- for (unsigned index = 0; index < size; ++index) {
- if (index > 0)
- *sout_ << ", ";
- *sout_ << childValues_[index];
- }
- if (!indentation_.empty()) *sout_ << " ";
- *sout_ << "]";
- }
- }
-}
-
-bool BuiltStyledStreamWriter::isMultineArray(Value const& value) {
- int size = value.size();
- bool isMultiLine = size * 3 >= rightMargin_;
- childValues_.clear();
- for (int index = 0; index < size && !isMultiLine; ++index) {
- Value const& childValue = value[index];
- isMultiLine = ((childValue.isArray() || childValue.isObject()) &&
- childValue.size() > 0);
- }
- if (!isMultiLine) // check if line length > max line length
- {
- childValues_.reserve(size);
- addChildValues_ = true;
- int lineLength = 4 + (size - 1) * 2; // '[ ' + ', '*n + ' ]'
- for (int index = 0; index < size; ++index) {
- if (hasCommentForValue(value[index])) {
- isMultiLine = true;
- }
- writeValue(value[index]);
- lineLength += int(childValues_[index].length());
- }
- addChildValues_ = false;
- isMultiLine = isMultiLine || lineLength >= rightMargin_;
- }
- return isMultiLine;
-}
-
-void BuiltStyledStreamWriter::pushValue(std::string const& value) {
- if (addChildValues_)
- childValues_.push_back(value);
- else
- *sout_ << value;
-}
-
-void BuiltStyledStreamWriter::writeIndent() {
- // blep intended this to look at the so-far-written string
- // to determine whether we are already indented, but
- // with a stream we cannot do that. So we rely on some saved state.
- // The caller checks indented_.
-
- if (!indentation_.empty()) {
- // In this case, drop newlines too.
- *sout_ << '\n' << indentString_;
- }
-}
-
-void BuiltStyledStreamWriter::writeWithIndent(std::string const& value) {
- if (!indented_) writeIndent();
- *sout_ << value;
- indented_ = false;
-}
-
-void BuiltStyledStreamWriter::indent() { indentString_ += indentation_; }
-
-void BuiltStyledStreamWriter::unindent() {
- assert(indentString_.size() >= indentation_.size());
- indentString_.resize(indentString_.size() - indentation_.size());
-}
-
-void BuiltStyledStreamWriter::writeCommentBeforeValue(Value const& root) {
- if (cs_ == CommentStyle::None) return;
- if (!root.hasComment(commentBefore))
- return;
-
- if (!indented_) writeIndent();
- const std::string& comment = root.getComment(commentBefore);
- std::string::const_iterator iter = comment.begin();
- while (iter != comment.end()) {
- *sout_ << *iter;
- if (*iter == '\n' &&
- (iter != comment.end() && *(iter + 1) == '/'))
- // writeIndent(); // would write extra newline
- *sout_ << indentString_;
- ++iter;
- }
- indented_ = false;
-}
-
-void BuiltStyledStreamWriter::writeCommentAfterValueOnSameLine(Value const& root) {
- if (cs_ == CommentStyle::None) return;
- if (root.hasComment(commentAfterOnSameLine))
- *sout_ << " " + root.getComment(commentAfterOnSameLine);
-
- if (root.hasComment(commentAfter)) {
- writeIndent();
- *sout_ << root.getComment(commentAfter);
- }
-}
-
-// static
-bool BuiltStyledStreamWriter::hasCommentForValue(const Value& value) {
- return value.hasComment(commentBefore) ||
- value.hasComment(commentAfterOnSameLine) ||
- value.hasComment(commentAfter);
-}
-
-///////////////
-// StreamWriter
-
-StreamWriter::StreamWriter()
- : sout_(NULL)
-{
-}
-StreamWriter::~StreamWriter()
-{
-}
-StreamWriter::Factory::~Factory()
-{}
-StreamWriterBuilder::StreamWriterBuilder()
-{
- setDefaults(&settings_);
-}
-StreamWriterBuilder::~StreamWriterBuilder()
-{}
-StreamWriter* StreamWriterBuilder::newStreamWriter() const
-{
- std::string indentation = settings_["indentation"].asString();
- std::string cs_str = settings_["commentStyle"].asString();
- bool eyc = settings_["enableYAMLCompatibility"].asBool();
- bool dnp = settings_["dropNullPlaceholders"].asBool();
- bool usf = settings_["useSpecialFloats"].asBool();
- unsigned int pre = settings_["precision"].asUInt();
- CommentStyle::Enum cs = CommentStyle::All;
- if (cs_str == "All") {
- cs = CommentStyle::All;
- } else if (cs_str == "None") {
- cs = CommentStyle::None;
- } else {
- throwRuntimeError("commentStyle must be 'All' or 'None'");
- }
- std::string colonSymbol = " : ";
- if (eyc) {
- colonSymbol = ": ";
- } else if (indentation.empty()) {
- colonSymbol = ":";
- }
- std::string nullSymbol = "null";
- if (dnp) {
- nullSymbol = "";
- }
- if (pre > 17) pre = 17;
- std::string endingLineFeedSymbol = "";
- return new BuiltStyledStreamWriter(
- indentation, cs,
- colonSymbol, nullSymbol, endingLineFeedSymbol, usf, pre);
-}
-static void getValidWriterKeys(std::set<std::string>* valid_keys)
-{
- valid_keys->clear();
- valid_keys->insert("indentation");
- valid_keys->insert("commentStyle");
- valid_keys->insert("enableYAMLCompatibility");
- valid_keys->insert("dropNullPlaceholders");
- valid_keys->insert("useSpecialFloats");
- valid_keys->insert("precision");
-}
-bool StreamWriterBuilder::validate(Json::Value* invalid) const
-{
- Json::Value my_invalid;
- if (!invalid) invalid = &my_invalid; // so we do not need to test for NULL
- Json::Value& inv = *invalid;
- std::set<std::string> valid_keys;
- getValidWriterKeys(&valid_keys);
- Value::Members keys = settings_.getMemberNames();
- size_t n = keys.size();
- for (size_t i = 0; i < n; ++i) {
- std::string const& key = keys[i];
- if (valid_keys.find(key) == valid_keys.end()) {
- inv[key] = settings_[key];
- }
- }
- return 0u == inv.size();
-}
-Value& StreamWriterBuilder::operator[](std::string key)
-{
- return settings_[key];
-}
-// static
-void StreamWriterBuilder::setDefaults(Json::Value* settings)
-{
- //! [StreamWriterBuilderDefaults]
- (*settings)["commentStyle"] = "All";
- (*settings)["indentation"] = "\t";
- (*settings)["enableYAMLCompatibility"] = false;
- (*settings)["dropNullPlaceholders"] = false;
- (*settings)["useSpecialFloats"] = false;
- (*settings)["precision"] = 17;
- //! [StreamWriterBuilderDefaults]
-}
-
-std::string writeString(StreamWriter::Factory const& builder, Value const& root) {
- std::ostringstream sout;
- StreamWriterPtr const writer(builder.newStreamWriter());
- writer->write(root, &sout);
- return sout.str();
-}
-
-std::ostream& operator<<(std::ostream& sout, Value const& root) {
- StreamWriterBuilder builder;
- StreamWriterPtr const writer(builder.newStreamWriter());
- writer->write(root, &sout);
- return sout;
-}
-
-} // namespace Json
-
-// //////////////////////////////////////////////////////////////////////
-// End of content of file: src/lib_json/json_writer.cpp
-// //////////////////////////////////////////////////////////////////////
-
-
-
-
-
diff --git a/third_party/protobuf/3.2.0/conformance/update_failure_list.py b/third_party/protobuf/3.2.0/conformance/update_failure_list.py
deleted file mode 100755
index 69f210e37c..0000000000
--- a/third_party/protobuf/3.2.0/conformance/update_failure_list.py
+++ /dev/null
@@ -1,73 +0,0 @@
-#!/usr/bin/env python
-# 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.
-
-"""Script to update a failure list file to add/remove failures.
-
-This is sort of like comm(1), except it recognizes comments and ignores them.
-"""
-
-import argparse
-import fileinput
-
-parser = argparse.ArgumentParser(
- description='Adds/removes failures from the failure list.')
-parser.add_argument('filename', type=str, help='failure list file to update')
-parser.add_argument('--add', dest='add_list', action='append')
-parser.add_argument('--remove', dest='remove_list', action='append')
-
-args = parser.parse_args()
-
-add_set = set()
-remove_set = set()
-
-for add_file in (args.add_list or []):
- with open(add_file) as f:
- for line in f:
- add_set.add(line)
-
-for remove_file in (args.remove_list or []):
- with open(remove_file) as f:
- for line in f:
- if line in add_set:
- raise "Asked to both add and remove test: " + line
- remove_set.add(line.strip())
-
-add_list = sorted(add_set, reverse=True)
-
-existing_list = file(args.filename).read()
-
-with open(args.filename, "w") as f:
- for line in existing_list.splitlines(True):
- test = line.split("#")[0].strip()
- while len(add_list) > 0 and test > add_list[-1]:
- f.write(add_list.pop())
- if test not in remove_set:
- f.write(line)