|  | #!/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 message | 
|  | from google.protobuf import json_format | 
|  | 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 = conformance_pb2.TestAllTypes() | 
|  | response = conformance_pb2.ConformanceResponse() | 
|  | test_message = conformance_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 json_format.ParseError 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: | 
|  | response.json_payload = json_format.MessageToJson(test_message) | 
|  |  | 
|  | 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) |