You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by kp...@apache.org on 2018/03/29 17:54:43 UTC

qpid-interop-test git commit: QPIDIT-119: Generator for amqp_complex_types_test, which can generate Python and C++ data files from JSON at this point. RheaJs and AmqpNetLite remain stubbed, and will be completed later. A first version of the JSON test da

Repository: qpid-interop-test
Updated Branches:
  refs/heads/master 7ec8c53a9 -> c1fb41599


QPIDIT-119: Generator for amqp_complex_types_test, which can generate Python and C++ data files from JSON at this point. RheaJs and AmqpNetLite remain stubbed, and will be completed later. A first version of the JSON test data files are also included, one each for arrays, lists and maps.


Project: http://git-wip-us.apache.org/repos/asf/qpid-interop-test/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-interop-test/commit/c1fb4159
Tree: http://git-wip-us.apache.org/repos/asf/qpid-interop-test/tree/c1fb4159
Diff: http://git-wip-us.apache.org/repos/asf/qpid-interop-test/diff/c1fb4159

Branch: refs/heads/master
Commit: c1fb41599b6046ca8fddb5a754d57191240b313c
Parents: 7ec8c53
Author: Kim van der Riet <kv...@localhost.localdomain>
Authored: Thu Mar 29 13:54:19 2018 -0400
Committer: Kim van der Riet <kv...@localhost.localdomain>
Committed: Thu Mar 29 13:54:19 2018 -0400

----------------------------------------------------------------------
 .../amqp_complex_types_test/data_utils.hpp      |  61 ++
 .../src/amqp_complex_types_test/Receiver.py     |  97 +++
 .../src/amqp_complex_types_test/Sender.py       | 113 +++
 .../amqp_complex_types_test.array.json          | 157 ++++
 .../amqp_complex_types_test.list.json           | 157 ++++
 .../amqp_complex_types_test.map.json            | 116 +++
 .../amqp_complex_types_test_generator.py        | 762 +++++++++++++++++++
 7 files changed, 1463 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-interop-test/blob/c1fb4159/shims/qpid-proton-cpp/src/qpidit/amqp_complex_types_test/data_utils.hpp
----------------------------------------------------------------------
diff --git a/shims/qpid-proton-cpp/src/qpidit/amqp_complex_types_test/data_utils.hpp b/shims/qpid-proton-cpp/src/qpidit/amqp_complex_types_test/data_utils.hpp
new file mode 100644
index 0000000..2d0b3cb
--- /dev/null
+++ b/shims/qpid-proton-cpp/src/qpidit/amqp_complex_types_test/data_utils.hpp
@@ -0,0 +1,61 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+#ifndef SRC_QPIDIT_DATA_UTILS_HPP_
+#define SRC_QPIDIT_DATA_UTILS_HPP_
+
+#include <sstream>
+#include <proton/types.hpp>
+
+namespace qpidit
+{
+    namespace amqp_complex_types_test
+    {
+
+        template<size_t N> static void hexStringToBytearray(proton::byte_array<N>& ba, const std::string& s, size_t fromArrayIndex = 0, size_t arrayLen = N) {
+            for (size_t i=0; i<arrayLen; ++i) {
+                ba[fromArrayIndex + i] = (char)std::strtoul(s.substr(2*i, 2).c_str(), NULL, 16);
+            }
+        }
+
+        static std::string hexStringToBinaryString(const std::string& s) {
+            std::ostringstream o;
+            for (size_t i=0; i<s.size(); i+=2) {
+                o << "\\x" << s.substr(i, 2);
+            }
+            return o.str();
+        }
+
+        static void setUuid(proton::uuid& val, const std::string& uuidStr) {
+            // Expected format: "00000000-0000-0000-0000-000000000000"
+            //                   ^        ^    ^    ^    ^
+            //    start index -> 0        9    14   19   24
+            hexStringToBytearray(val, uuidStr.substr(0, 8), 0, 4);
+            hexStringToBytearray(val, uuidStr.substr(9, 4), 4, 2);
+            hexStringToBytearray(val, uuidStr.substr(14, 4), 6, 2);
+            hexStringToBytearray(val, uuidStr.substr(19, 4), 8, 2);
+            hexStringToBytearray(val, uuidStr.substr(24, 12), 10, 6);
+        }
+
+    } // namespace amqp_complex_types_test
+} // namespace qpidit
+
+#endif /* SRC_QPIDIT_DATA_UTILS_HPP_ */

http://git-wip-us.apache.org/repos/asf/qpid-interop-test/blob/c1fb4159/shims/qpid-proton-python/src/amqp_complex_types_test/Receiver.py
----------------------------------------------------------------------
diff --git a/shims/qpid-proton-python/src/amqp_complex_types_test/Receiver.py b/shims/qpid-proton-python/src/amqp_complex_types_test/Receiver.py
new file mode 100644
index 0000000..c252239
--- /dev/null
+++ b/shims/qpid-proton-python/src/amqp_complex_types_test/Receiver.py
@@ -0,0 +1,97 @@
+#!/usr/bin/env python
+
+"""
+AMQP complex type test receiver shim for qpid-interop-test
+"""
+
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+import json
+import os.path
+import signal
+import sys
+import traceback
+
+import proton
+import proton.handlers
+import proton.reactor
+
+class AmqpComplexTypesTestReceiver(proton.handlers.MessagingHandler):
+    """
+    Reciver shim for AMQP complex types test
+    This shim receives the number of messages supplied on the command-line and checks that they contain message
+    bodies of the exptected AMQP type. The values are then aggregated and returned.
+    """
+    def __init__(self, broker_url, queue_name, amqp_type, num_expected_messages_str):
+        super(AmqpComplexTypesTestReceiver, self).__init__()
+        self.broker_url = broker_url
+        self.queue_name = queue_name
+        self.received_value_list = []
+        self.amqp_type = amqp_type
+        self.expected = int(num_expected_messages_str)
+        self.received = 0
+        signal.signal(signal.SIGINT, self.signal_handler)
+        signal.signal(signal.SIGTERM, self.signal_handler)
+
+    def get_received_value_list(self):
+        """Return the received list of AMQP values"""
+        return self.received_value_list
+
+    def on_start(self, event):
+        """Event callback for when the client starts"""
+        connection = event.container.connect(url=self.broker_url, sasl_enabled=False, reconnect=False)
+        event.container.create_receiver(connection, source=self.queue_name)
+
+    def on_message(self, event):
+        """Event callback when a message is received by the client"""
+        if event.message.id and event.message.id < self.received:
+            return # ignore duplicate message
+        # ...
+        self.received += 1
+        if self.received >= self.expected:
+            event.receiver.close()
+            event.connection.close()
+
+    def on_transport_error(self, event):
+        print('Receiver: Broker not found at %s' % self.broker_url)
+
+    @staticmethod
+    def signal_handler(signal_number, _):
+        """Signal handler"""
+        if signal_number in [signal.SIGTERM, signal.SIGINT]:
+            print('Receiver: received signal %d, terminating' % signal_number)
+            sys.exit(1)
+
+# --- main ---
+# Args: 1: Broker address (ip-addr:port)
+#       2: Queue name
+#       3: AMQP complex type
+#       4: Test data reference list
+try:
+    RECEIVER = AmqpComplexTypesTestReceiver(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4])
+    proton.reactor.Container(RECEIVER).run()
+    print(sys.argv[3])
+    print(json.dumps(RECEIVER.get_received_value_list()))
+except KeyboardInterrupt:
+    pass
+except Exception as exc:
+    print(os.path.basename(sys.argv[0]), 'EXCEPTION', exc)
+    print(traceback.format_exc())
+    sys.exit(1)

http://git-wip-us.apache.org/repos/asf/qpid-interop-test/blob/c1fb4159/shims/qpid-proton-python/src/amqp_complex_types_test/Sender.py
----------------------------------------------------------------------
diff --git a/shims/qpid-proton-python/src/amqp_complex_types_test/Sender.py b/shims/qpid-proton-python/src/amqp_complex_types_test/Sender.py
new file mode 100644
index 0000000..fa2c49b
--- /dev/null
+++ b/shims/qpid-proton-python/src/amqp_complex_types_test/Sender.py
@@ -0,0 +1,113 @@
+#!/usr/bin/env python
+
+"""
+AMQP complex type test sender shim for qpid-interop-test
+"""
+
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+import json
+import os.path
+import signal
+import sys
+import traceback
+
+import proton
+import proton.handlers
+import proton.reactor
+
+class AmqpComplexTypesTestSender(proton.handlers.MessagingHandler):
+    """
+    Sender shim for AMQP complex types test
+    This shim receives the AMQP type and a list of test values. Each value is sent in a message body of the appropriate
+    AMQP type. There is no returned value.
+    """
+    def __init__(self, broker_url, queue_name, amqp_type, test_value_list):
+        super(AmqpComplexTypesTestSender, self).__init__()
+        self.broker_url = broker_url
+        self.queue_name = queue_name
+        self.amqp_type = amqp_type
+        self.test_value_list = test_value_list
+        self.sent = 0
+        self.confirmed = 0
+        self.total = len(test_value_list)
+        signal.signal(signal.SIGINT, self.signal_handler)
+        signal.signal(signal.SIGTERM, self.signal_handler)
+
+    def on_start(self, event):
+        """Event callback for when the client starts"""
+        connection = event.container.connect(url=self.broker_url, sasl_enabled=False, reconnect=False)
+        event.container.create_sender(connection, target=self.queue_name)
+
+    def on_sendable(self, event):
+        """Event callback for when send credit is received, allowing the sending of messages"""
+        if self.sent == 0:
+            for test_value in self.test_value_list:
+                if event.sender.credit:
+                    message = self.create_message(test_value)
+                    if message is not None:
+                        event.sender.send(message)
+                        self.sent += 1
+                    else:
+                        event.connection.close()
+                        return
+
+    def create_message(self, test_value):
+        """
+        Creates a single message with the test value translated from its string representation to the appropriate
+        AMQP value (set in self.amqp_type).
+        """
+        return proton.Message(id=(self.sent+1), body=test_value)
+
+    def on_accepted(self, event):
+        """Event callback for when a sent message is accepted by the broker"""
+        self.confirmed += 1
+        if self.confirmed == self.total:
+            event.connection.close()
+
+    def on_disconnected(self, event):
+        """Event callback for when the broker disconnects with the client"""
+        self.sent = self.confirmed
+
+    def on_transport_error(self, event):
+        print('Sender: Broker not found at %s' % self.broker_url)
+
+    @staticmethod
+    def signal_handler(signal_number, _):
+        """Signal handler"""
+        if signal_number in [signal.SIGTERM, signal.SIGINT]:
+            print('Sender: received signal %d, terminating' % signal_number)
+            sys.exit(1)
+
+
+# --- main ---
+# Args: 1: Broker address (ip-addr:port)
+#       2: Queue name
+#       3: AMQP type
+#       4: JSON list of test value references to use in test
+try:
+    SENDER = AmqpComplexTypesTestSender(sys.argv[1], sys.argv[2], sys.argv[3], json.loads(sys.argv[4]))
+    proton.reactor.Container(SENDER).run()
+except KeyboardInterrupt:
+    pass
+except Exception as exc:
+    print(os.path.basename(sys.argv[0]), 'EXCEPTION:', exc)
+    print(traceback.format_exc())
+    sys.exit(1)

http://git-wip-us.apache.org/repos/asf/qpid-interop-test/blob/c1fb4159/src/python/qpid_interop_test/amqp_complex_types_test.array.json
----------------------------------------------------------------------
diff --git a/src/python/qpid_interop_test/amqp_complex_types_test.array.json b/src/python/qpid_interop_test/amqp_complex_types_test.array.json
new file mode 100644
index 0000000..c43356e
--- /dev/null
+++ b/src/python/qpid_interop_test/amqp_complex_types_test.array.json
@@ -0,0 +1,157 @@
+[["array", []],
+ ["array", [["null", null],
+            ["null", null]]],
+ ["array", [["boolean", true],
+            ["boolean", false]]],
+ ["array", [["ubyte", 0],
+            ["ubyte", 127],
+            ["ubyte", 128],
+            ["ubyte", 255]]],
+ ["array", [["ushort", 0],
+            ["ushort", 255],
+            ["ushort", 256],
+            ["ushort", "0x7fff"],
+            ["ushort", "0x8000"],
+            ["ushort", "0xffff"]]],
+ ["array", [["uint", 0],
+            ["uint", 255],
+            ["uint", 256],
+            ["uint", "0x7fffffff"],
+            ["uint", "0x80000000"],
+            ["uint", "0xffffffff"]]],
+ ["array", [["ulong", 0],
+            ["ulong", 255],
+            ["ulong", 256],
+            ["ulong", "0x7fffffffffffffff"],
+            ["ulong", "0x8000000000000000"],
+            ["ulong", "0xffffffffffffffff"]]],
+ ["array", [["byte", -128],
+            ["byte", -1],
+            ["byte", 0],
+            ["byte", 255]]],
+ ["array", [["short", "-0x8000"],
+            ["short", -1],
+            ["short", 0],
+            ["short", "0x7fff"]]],
+ ["array", [["int", "-0x80000000"],
+            ["int", -1],
+            ["int", 0],
+            ["int", "0x7fffffff"]]],
+ ["array", [["long", "-0x8000000000000000"],
+            ["long", -128],
+            ["long", -1],
+            ["long", 0],
+            ["long", 127],
+            ["long", "0x7fffffffffffffff"]]],
+ ["array", [["float", 0.0],
+            ["float", 3.14159],
+            ["float", -2.71828],
+            ["float", "1.2345e+38"],
+            ["float", "-1.2345e-38"],
+            ["float", "inf"],
+            ["float", "-inf"],
+            ["float", "NaN"]]],
+ ["array", [["double", 0.0],
+            ["double", 3.141592653589793],
+            ["double", -2.71828182845905],
+            ["double", "1.23456789012345e308"],
+            ["double", "-1.23456789012345e-308"],
+            ["double", "inf"],
+            ["double", "-inf"],
+            ["double", "NaN"]]],
+ ["array", [["decimal32", "0x00000000"],
+            ["decimal32", "0x03020100"],
+            ["decimal32", "0xffffffff"]]],
+ ["array", [["decimal64", "0x0000000000000000"],
+            ["decimal64", "0x0706050403020100"],
+            ["decimal64", "0xffffffffffffffff"]]],
+ ["array", [["decimal128", "0x00000000000000000000000000000000"],
+            ["decimal128", "0x0f0e0d0c0b0a09080706050403020100"],
+            ["decimal128", "0xffffffffffffffffffffffffffffffff"]]],
+ ["array", [["char", " "],
+            ["char", "A"],
+            ["char", "z"],
+            ["char", "0"],
+            ["char", "9"],
+            ["char", "}"],
+            ["char", "0x00"],
+            ["char", "0x01"],
+            ["char", "0x7f"],
+            ["char", "0x80"],
+            ["char", "0xff"],
+            ["char", "0x16b5"],
+            ["char", "0x010203"],
+            ["char", "0x10ffff"],
+            ["char", "0xffffffff"]]],
+ ["array", [["timestamp", 0],
+            ["timestamp", "0xdc6be25480"],
+            ["timestamp", "0x1624e900fa5"]]],
+ ["array", [["uuid", "0x1"],
+            ["uuid", "00010203-0405-0607-0809-0a0b0c0d0e0f"],
+            ["uuid", "0x0f0e0d0c0b0a09080706050403020100"],
+            ["uuid", "68907a08-2a1b-4154-9733-2c0b9f4c5597"]]],
+ ["array", [["binary", ""],
+            ["binary", 123456],
+            ["binary", "0x0f0e0d0c0b0a09080706050403020100"],
+            ["binary", "Hello, world!"],
+            ["binary", "\\x01\\x02\\x03\\x04\\x05zyxwv\\x80\\x81\\xfe\\xff"],
+            ["binary", "The quick brown fox jumped over the lazy dog 0123456789."]]],
+ ["array", [["string", ""],
+            ["string", "Hello, world"],
+            ["string", "\"Hello, world\""],
+            ["string", "Charlie's peach"],
+            ["string", "The quick brown fox jumped over the lazy dog 0123456789."]]], 
+ ["array", [["symbol", ""],
+            ["symbol", "myDomain.123"],
+            ["symbol", "domain.0123456789."]]],
+ ["array", [["array", []],
+            ["array", [["ubyte", 0],
+                       ["ubyte", 1],
+                       ["ubyte", 2],
+                       ["ubyte", 3]]],
+            ["array", [["string", "This"],
+                       ["string", "is"],
+                       ["string", "arbitrary"]]]]],
+ ["array", [["list", []],
+            ["list", [["ubyte", 16],
+                      ["ushort", 17],
+                      ["uint", 18],
+                      ["ulong", 19],
+                      ["byte", 20],
+                      ["short", 21],
+                      ["int", 22],
+                      ["long", 23]]],
+            ["list", [["float", 0.1234],
+                      ["double", 0.12345678]]],
+            ["list", [["decimal32", "0x03020100"],
+                      ["decimal64", "0x0706050403020100"],
+                      ["decimal128", "0x0f0e0d0c0b0a09080706050403020100"]]],
+            ["list", [["char", "X"],
+                      ["timestamp", "0xdc6be25480"],
+                      ["uuid", "0x0f0e0d0c0b0a09080706050403020100"]]], 
+            ["list", [["binary", "Hello, world"],
+                      ["string", "Hello, world"],
+                      ["symbol", "Hello, world"]]],
+            ["list", [["array", []],
+                      ["array", [["byte", 1],
+                                 ["byte", 2]]]]],
+            ["list", [["list", []],
+                      ["list", [["byte", 3],
+                                ["string", "hello"]]]]],
+            ["list", [["map", []],
+                      ["map", [["string", "key1"], ["byte", 4], ["uint", 10], ["float", 3.14]]]]]]], 
+ ["array", [["map", []],
+            ["map", [["ubyte", 16], ["string", "sixteen"],
+                     ["ushort", 17], ["string", "seventeen"],
+                     ["uint", 18], ["string", "eighteen"],
+                     ["ulong", 19], ["string", "nineteen"],
+                     ["byte", 20], ["string", "twenty"],
+                     ["short", 21], ["string", "twenty-one"],
+                     ["int", 22], ["string", "twenty-two"],
+                     ["long", 23], ["string", "twenty-three"]]],
+            ["map", [["float", 0.1234], ["binary", "hello"],
+                     ["double", 0.12345678], ["binary", "world"]]],
+            ["map", [["string", "hello"], ["int", -25],
+                     ["symbol", "world"], ["long", -12345678],
+                     ["binary", "today\\x01\\x02"], ["byte", -7]]]]]
+]

http://git-wip-us.apache.org/repos/asf/qpid-interop-test/blob/c1fb4159/src/python/qpid_interop_test/amqp_complex_types_test.list.json
----------------------------------------------------------------------
diff --git a/src/python/qpid_interop_test/amqp_complex_types_test.list.json b/src/python/qpid_interop_test/amqp_complex_types_test.list.json
new file mode 100644
index 0000000..86de15f
--- /dev/null
+++ b/src/python/qpid_interop_test/amqp_complex_types_test.list.json
@@ -0,0 +1,157 @@
+[["list", []],
+ ["list", [["null", null],
+           ["null", null]]],
+ ["list", [["boolean", true],
+           ["boolean", false]]],
+ ["list", [["ubyte", 0],
+           ["ubyte", 127],
+           ["ubyte", 128],
+           ["ubyte", 255]]],
+ ["list", [["ushort", 0],
+           ["ushort", 255],
+           ["ushort", 256],
+           ["ushort", "0x7fff"],
+           ["ushort", "0x8000"],
+           ["ushort", "0xffff"]]],
+ ["list", [["uint", 0],
+           ["uint", 255],
+           ["uint", 256],
+           ["uint", "0x7fffffff"],
+           ["uint", "0x80000000"],
+           ["uint", "0xffffffff"]]],
+ ["list", [["ulong", 0],
+           ["ulong", 255],
+           ["ulong", 256],
+           ["ulong", "0x7fffffffffffffff"],
+           ["ulong", "0x8000000000000000"],
+           ["ulong", "0xffffffffffffffff"]]],
+ ["list", [["byte", -128],
+           ["byte", -1],
+           ["byte", 0],
+           ["byte", 255]]],
+ ["list", [["short", "-0x8000"],
+           ["short", -1],
+           ["short", 0],
+           ["short", "0x7fff"]]],
+ ["list", [["int", "-0x80000000"],
+           ["int", -1],
+           ["int", 0],
+           ["int", "0x7fffffff"]]],
+ ["list", [["long", "-0x8000000000000000"],
+           ["long", -128],
+           ["long", -1],
+           ["long", 0],
+           ["long", 127],
+           ["long", "0x7fffffffffffffff"]]],
+ ["list", [["float", 0.0],
+           ["float", 3.14159],
+           ["float", -2.71828],
+           ["float", "1.2345e+38"],
+           ["float", "-1.2345e-38"],
+           ["float", "inf"],
+           ["float", "-inf"],
+           ["float", "NaN"]]],
+ ["list", [["double", 0.0],
+           ["double", 3.141592653589793],
+           ["double", -2.71828182845905],
+           ["double", "1.23456789012345e308"],
+           ["double", "-1.23456789012345e-308"],
+           ["double", "inf"],
+           ["double", "-inf"],
+           ["double", "NaN"]]],
+ ["list", [["decimal32", "0x00000000"],
+           ["decimal32", "0x03020100"],
+           ["decimal32", "0xffffffff"]]],
+ ["list", [["decimal64", "0x0000000000000000"],
+           ["decimal64", "0x0706050403020100"],
+           ["decimal64", "0xffffffffffffffff"]]],
+ ["list", [["decimal128", "0x00000000000000000000000000000000"],
+           ["decimal128", "0x0f0e0d0c0b0a09080706050403020100"],
+           ["decimal128", "0xffffffffffffffffffffffffffffffff"]]],
+ ["list", [["char", " "],
+           ["char", "A"],
+           ["char", "z"],
+           ["char", "0"],
+           ["char", "9"],
+           ["char", "}"],
+           ["char", "0x00"],
+           ["char", "0x01"],
+           ["char", "0x7f"],
+           ["char", "0x80"],
+           ["char", "0xff"],
+           ["char", "0x16b5"],
+           ["char", "0x010203"],
+           ["char", "0x10ffff"],
+           ["char", "0xffffffff"]]],
+ ["list", [["timestamp", 0],
+           ["timestamp", "0xdc6be25480"],
+           ["timestamp", "0x1624e900fa5"]]],
+ ["list", [["uuid", "0x0"],
+           ["uuid", "00010203-0405-0607-0809-0a0b0c0d0e0f"],
+           ["uuid", "0x0f0e0d0c0b0a09080706050403020100"],
+           ["uuid", "68907a08-2a1b-4154-9733-2c0b9f4c5597"]]],
+ ["list", [["binary", ""],
+           ["binary", 12345],
+           ["binary", "0x0f0e0d0c0b0a09080706050403020100"],
+           ["binary", "Hello, world!"],
+           ["binary", "\\x01\\x02\\x03\\x04\\x05zyxwv\\x80\\x81\\xfe\\xff"],
+           ["binary", "The quick brown fox jumped over the lazy dog 0123456789."]]],
+ ["list", [["string", ""],
+           ["string", "Hello, world"],
+           ["string", "\"Hello, world\""],
+           ["string", "Charlie's peach"],
+           ["string", "The quick brown fox jumped over the lazy dog 0123456789."]]], 
+ ["list", [["symbol", ""],
+           ["symbol", "myDomain.123"],
+           ["symbol", "domain.0123456789."]]],
+ ["list", [["array", []],
+           ["array", [["ubyte", 0],
+                      ["ubyte", 1],
+                      ["ubyte", 2],
+                      ["ubyte", 3]]],
+           ["array", [["string", "This"],
+                      ["string", "is"],
+                      ["string", "stupid"]]]]],
+ ["list", [["list", []],
+           ["list", [["ubyte", 16],
+                     ["ushort", 17],
+                     ["uint", 18],
+                     ["ulong", 19],
+                     ["byte", 20],
+                     ["short", 21],
+                     ["int", 22],
+                     ["long", 23]]],
+           ["list", [["float", 0.1234],
+                     ["double", 0.12345678]]],
+           ["list", [["decimal32", "0x03020100"],
+                     ["decimal64", "0x0706050403020100"],
+                     ["decimal128", "0x0f0e0d0c0b0a09080706050403020100"]]],
+           ["list", [["char", "X"],
+                     ["timestamp", "0xdc6be25480"],
+                     ["uuid", "0x0f0e0d0c0b0a09080706050403020100"]]], 
+           ["list", [["binary", "Hello, world"],
+                     ["string", "Hello, world"],
+                     ["symbol", "Hello, world"]]],
+           ["list", [["array", []],
+                     ["array", [["byte", 1],
+                                ["byte", 2]]]]],
+           ["list", [["list", []],
+                     ["list", [["byte", 3],
+                               ["string", "hello"]]]]],
+           ["list", [["map", []],
+                     ["map", [["string", "key1"], ["byte", 4], ["uint", 10], ["float", 3.14]]]]]]], 
+ ["list", [["map", []],
+           ["map", [["ubyte", 16], ["string", "sixteen"],
+                    ["ushort", 17], ["string", "seventeen"],
+                    ["uint", 18], ["string", "eighteen"],
+                    ["ulong", 19], ["string", "nineteen"],
+                    ["byte", 20], ["string", "twenty"],
+                    ["short", 21], ["string", "twenty-one"],
+                    ["int", 22], ["string", "twenty-two"],
+                    ["long", 23], ["string", "twenty-three"]]],
+           ["map", [["float", 0.1234], ["binary", "hello"],
+                    ["double", 0.12345678], ["binary", "world"]]],
+           ["map", [["string", "hello"], ["int", -25],
+                    ["symbol", "world"], ["long", -12345678],
+                    ["binary", "today\\x01\\x02"], ["byte", -7]]]]]
+]
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/qpid-interop-test/blob/c1fb4159/src/python/qpid_interop_test/amqp_complex_types_test.map.json
----------------------------------------------------------------------
diff --git a/src/python/qpid_interop_test/amqp_complex_types_test.map.json b/src/python/qpid_interop_test/amqp_complex_types_test.map.json
new file mode 100644
index 0000000..9a6cbb2
--- /dev/null
+++ b/src/python/qpid_interop_test/amqp_complex_types_test.map.json
@@ -0,0 +1,116 @@
+[["map", []],
+ ["map", [["null", null], ["null", null]]],
+ ["map", [["boolean", false], ["boolean", false],
+          ["boolean", true], ["boolean", true]]],
+ ["map", [["ubyte", 0], ["ubyte", 0],
+          ["ubyte", 127], ["ubyte", 127],
+          ["ubyte", 128], ["ubyte", 128],
+          ["ubyte", 255], ["ubyte", 255]]],
+ ["map", [["ushort", 0], ["ushort", 0],
+          ["ushort", 255], ["ushort", 255],
+          ["ushort", 256], ["ushort", 256],
+          ["ushort", "0x7fff"], ["ushort", "0x7fff"],
+          ["ushort", "0x8000"], ["ushort", "0x8000"],
+          ["ushort", "0xffff"], ["ushort", "0xffff"]]],
+ ["map", [["uint", 0], ["uint", 0],
+          ["uint", 255], ["uint", 255],
+          ["uint", 256], ["uint", 256],
+          ["uint", "0x7fffffff"], ["uint", "0x7fffffff"],
+          ["uint", "0x80000000"], ["uint", "0x80000000"],
+          ["uint", "0xffffffff"], ["uint", "0xffffffff"]]], 
+ ["map", [["ulong", 0], ["ulong", 0],
+          ["ulong", 255], ["ulong", 255],
+          ["ulong", 256], ["ulong", 256],
+          ["ulong", "0x7fffffffffffffff"], ["ulong", "0x7fffffffffffffff"],
+          ["ulong", "0x8000000000000000"], ["ulong", "0x8000000000000000"],
+          ["ulong", "0xffffffffffffffff"], ["ulong", "0xffffffffffffffff"]]],
+ ["map", [["byte", -128], ["byte", -128],
+          ["byte", -1], ["byte", -1],
+          ["byte", 0], ["byte", 0],
+          ["byte", 255], ["byte", 255]]],
+ ["map", [["short", "-0x8000"], ["short", "-0x8000"],
+          ["short", -1], ["short", -1],
+          ["short", 0], ["short", 0],
+          ["short", "0x7fff"], ["short", "0x7fff"]]],
+ ["map", [["int", "-0x80000000"], ["int", "-0x80000000"],
+          ["int", -1], ["int", -1],
+          ["int", 0], ["int", 0],
+          ["int", "0x7fffffff"], ["int", "0x7fffffff"]]],
+ ["map", [["long", "-0x8000000000000000"], ["long", "-0x8000000000000000"],
+          ["long", -128], ["long", -128],
+          ["long", -1], ["long", -1],
+          ["long", 0], ["long", 0],
+          ["long", 127], ["long", 127],
+          ["long", "0x7fffffffffffffff"], ["long", "0x7fffffffffffffff"]]],
+ ["map", [["float", 0.0], ["float", 0.0],
+          ["float", 3.14159], ["float", 3.14159],
+          ["float", -2.71828], ["float", -2.71828],
+          ["float", "1.2345e+38"], ["float", "1.2345e+38"],
+          ["float", "-1.2345e-38"], ["float", "-1.2345e-38"],
+          ["float", "inf"], ["float", "inf"],
+          ["float", "-inf"], ["float", "-inf"],
+          ["float", "NaN"], ["float", "NaN"]]],
+ ["map", [["double", 0.0], ["double", 0.0],
+          ["double", 3.141592653589793], ["double", 3.141592653589793],
+          ["double", -2.71828182845905], ["double", -2.71828182845905],
+          ["double", "1.23456789012345e308"], ["double", "1.23456789012345e308"],
+          ["double", "-1.23456789012345e-308"], ["double", "-1.23456789012345e-308"],
+          ["double", "inf"], ["double", "inf"],
+          ["double", "-inf"], ["double", "-inf"],
+          ["double", "NaN"], ["double", "NaN"]]],
+ ["map", [["decimal32", "0x00000000"], ["decimal32", "0x00000000"],
+          ["decimal32", "0x03020100"], ["decimal32", "0x03020100"],
+          ["decimal32", "0xffffffff"], ["decimal32", "0xffffffff"]]],
+ ["map", [["decimal64", "0x0000000000000000"], ["decimal64", "0x0000000000000000"],
+          ["decimal64", "0x0706050403020100"], ["decimal64", "0x0706050403020100"],
+          ["decimal64", "0xffffffffffffffff"], ["decimal64", "0xffffffffffffffff"]]],
+ ["map", [["decimal128", "0x00000000000000000000000000000000"], ["decimal128", "0x00000000000000000000000000000000"],
+          ["decimal128", "0x0f0e0d0c0b0a09080706050403020100"], ["decimal128", "0x0f0e0d0c0b0a09080706050403020100"],
+          ["decimal128", "0xffffffffffffffffffffffffffffffff"], ["decimal128", "0xffffffffffffffffffffffffffffffff"]]],
+ ["map", [["char", " "], ["char", " "],
+          ["char", "A"], ["char", "A"],
+          ["char", "z"], ["char", "z"],
+          ["char", "0"], ["char", "0"],
+          ["char", "9"], ["char", "9"],
+          ["char", "}"], ["char", "}"],
+          ["char", "0x00"], ["char", "0x00"],
+          ["char", "0x01"], ["char", "0x01"],
+          ["char", "0x7f"], ["char", "0x7f"],
+          ["char", "0x80"], ["char", "0x80"],
+          ["char", "0xff"], ["char", "0xff"],
+          ["char", "0x16b5"], ["char", "0x16b5"],
+          ["char", "0x010203"], ["char", "0x010203"],
+          ["char", "0x10ffff"], ["char", "0x10ffff"],
+          ["char", "0xffffffff"], ["char", "0xffffffff"]]],
+ ["map", [["timestamp", 0], ["timestamp", 0],
+          ["timestamp", "0xdc6be25480"], ["timestamp", "0xdc6be25480"],
+          ["timestamp", "0x1624e900fa5"], ["timestamp", "0x1624e900fa5"]]],
+ ["map", [["uuid", "0x0"], ["uuid", "0x0"],
+          ["uuid", "00010203-0405-0607-0809-0a0b0c0d0e0f"], ["uuid", "00010203-0405-0607-0809-0a0b0c0d0e0f"],
+          ["uuid", "0x0f0e0d0c0b0a09080706050403020100"], ["uuid", "0x0f0e0d0c0b0a09080706050403020100"],
+          ["uuid", "68907a08-2a1b-4154-9733-2c0b9f4c5597"], ["uuid", "68907a08-2a1b-4154-9733-2c0b9f4c5597"]]],
+ ["map", [["binary", ""], ["binary", ""],
+          ["binary", 12345], ["binary", 12345],
+          ["binary", "0x0f0e0d0c0b0a09080706050403020100"], ["binary", "0x0f0e0d0c0b0a09080706050403020100"],
+          ["binary", "Hello, world!"], ["binary", "Hello, world!"],
+          ["binary", "\\x01\\x02\\x03\\x04\\x05zyxwv\\x80\\x81\\xfe\\xff"], ["binary", "\\x01\\x02\\x03\\x04\\x05zyxwv\\x80\\x81\\xfe\\xff"],
+          ["binary", "The quick brown fox jumped over the lazy dog 0123456789."], ["binary", "The quick brown fox jumped over the lazy dog 0123456789."]]],
+ ["map", [["string", ""], ["string", ""],
+          ["string", "Hello, world"], ["string", "Hello, world"],
+          ["string", "\"Hello, world\""], ["string", "\"Hello, world\""],
+          ["string", "Charlie's peach"], ["string", "Charlie's peach"],
+          ["string", "The quick brown fox jumped over the lazy dog 0123456789."], ["string", "The quick brown fox jumped over the lazy dog 0123456789."]]], 
+ ["map", [["symbol", ""], ["symbol", ""],
+          ["symbol", "myDomain.123"], ["symbol", "myDomain.123"],
+          ["symbol", "domain.0123456789."], ["symbol", "domain.0123456789."]]],
+ ["map", [["string", "array01"], ["array", [["boolean", false],
+                                            ["boolean", true]]]]],
+ ["map", [["string", "list01"], ["list", [["boolean", false],
+                                          ["boolean", true],
+                                          ["ubyte", 0],
+                                          ["ubyte", 127],
+                                          ["ubyte", 128],
+                                          ["ubyte", 255]]]]],
+ ["map", [["string", "map01"], ["map", [["boolean", false], ["boolean", false],
+                                        ["boolean", true], ["boolean", true]]]]]
+]
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/qpid-interop-test/blob/c1fb4159/src/python/qpid_interop_test/amqp_complex_types_test_generator.py
----------------------------------------------------------------------
diff --git a/src/python/qpid_interop_test/amqp_complex_types_test_generator.py b/src/python/qpid_interop_test/amqp_complex_types_test_generator.py
new file mode 100644
index 0000000..5fdaec6
--- /dev/null
+++ b/src/python/qpid_interop_test/amqp_complex_types_test_generator.py
@@ -0,0 +1,762 @@
+#!/usr/bin/env python3
+
+"""
+Module to generate test data files for the AMQP complex types test
+"""
+
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+import argparse
+import json
+import os.path
+import time
+from abc import abstractmethod
+
+COPYRIGHT_TEXT = u"""Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License."""
+
+DEFAULT_PATH = os.path.dirname(os.path.realpath(__file__))
+DEFAULT_JSON_BASE_NAME = u'amqp_complex_types_test'
+GENERATOR_TARGETS = [u'python', u'cpp', u'javascript', u'dotnet', u'ALL']
+AMQP_COMPEX_TYPES = [u'array', u'list', u'map', u'ALL']
+INDENT_LEVEL_SIZE = 4
+
+class JsonReader(object):
+    """Class to read the JSON data file"""
+    def __init__(self, args):
+        self.args = args
+
+    def generate(self):
+        """Generate the output files based on command-line argument choices"""
+        if self.args.gen == u'ALL':
+            gen_targets = GENERATOR_TARGETS[:-1]
+        else:
+            gen_targets = [self.args.gen]
+        gen_path = os.path.abspath(self.args.gen_dir)
+        for target in gen_targets:
+            target_file_name = None
+            if target == GENERATOR_TARGETS[0]: # Python
+                target_file_name = os.path.join(gen_path, u'%s.data.py' % self.args.json_base_name)
+                with PythonGenerator(target_file_name) as generator:
+                    self._generate_target(target, generator)
+            elif target == GENERATOR_TARGETS[1]: # C++
+                target_file_name = os.path.join(gen_path, u'%s.data.cpp' % self.args.json_base_name)
+                with CppGenerator(target_file_name) as generator:
+                    self._generate_target(target, generator)
+            elif target == GENERATOR_TARGETS[2]: # JavaScript
+                target_file_name = os.path.join(gen_path, u'%s.data.js' % self.args.json_base_name)
+                with JavaScriptGenerator(target_file_name) as generator:
+                    self._generate_target(target, generator)
+            elif target == GENERATOR_TARGETS[3]: # DotNet
+                target_file_name = os.path.join(gen_path, u'%s.data.cs' % self.args.json_base_name)
+                with DotNetGenerator(target_file_name) as generator:
+                    self._generate_target(target, generator)
+            else:
+                raise RuntimeError(u'Unknown target %s' % target)
+
+    def _generate_target(self, target, generator):
+        """Generate the output file for target type"""
+        print(u'_generate_target(t=%s g=%s)' % (target, generator.__class__.__name__))
+        generator.write_prefix()
+        if self.args.type == u'ALL':
+            amqp_test_types = AMQP_COMPEX_TYPES[:-1]
+        else:
+            amqp_test_types = [self.args.type]
+        # First parse
+        for amqp_test_type in amqp_test_types:
+            json_file_name = os.path.join(os.path.abspath(self.args.src_dir), u'%s.%s.json' %
+                                          (self.args.json_base_name, amqp_test_type))
+            print(u' * _generate_type(t=%s f=%s)' % (amqp_test_type, os.path.basename(json_file_name)))
+            generator.write_code(amqp_test_type, JsonReader._read_file(json_file_name))
+        generator.write_postfix()
+
+    @staticmethod
+    def _read_file(json_file_name):
+        """Read the file into a Python data structure"""
+        print(u'reading file %s' % os.path.basename(json_file_name))
+        json_file = open(json_file_name, u'r')
+        json_file_data = json_file.read()
+        json_file.close()
+        return json.loads(json_file_data)
+
+    @staticmethod
+    def _target_file_extension(target):
+        file_extension_map = {u'python': u'py',
+                              u'cpp': u'cpp',
+                              u'javascript': u'js',
+                              u'dotnet': u'cs'}
+        if target in file_extension_map:
+            return file_extension_map[target]
+        raise RuntimeError(u'Unknown target: %s' % target)
+
+
+class Generator(object):
+    """Abstract code generator class"""
+    def __init__(self, target_file_name):
+        self.target_file = open(target_file_name, u'w')
+
+    def __enter__(self):
+        return self
+
+    def __exit__(self, exc_type, exc_value, traceback):
+        self.target_file.close()
+
+    @abstractmethod
+    def write_prefix(self):
+        """Write comments, copyright, etc at top of file"""
+        raise NotImplementedError
+
+    @abstractmethod
+    def write_code(self, amqp_test_type, json_data):
+        """Process data structure to write code"""
+        raise NotImplementedError
+
+    @abstractmethod
+    def write_postfix(self):
+        """Write comments, any fixed items to the end of the source file"""
+        raise NotImplementedError
+
+class PythonGenerator(Generator):
+    """Python code generator"""
+
+    def write_prefix(self):
+        """Write comments, copyright, etc at top of Python source file"""
+        self.target_file.write(u'#!/usr/bin/env python\n\n')
+        self.target_file.write(u'"""Data used for qpid_interop_test.amqp_complex_types_test"""\n\n')
+        for line in iter(COPYRIGHT_TEXT.splitlines()):
+            self.target_file.write(u'# %s\n' % line)
+        self.target_file.write(u'\n# *** THIS IS A GENERATED FILE, DO NOT EDIT DIRECTLY ***\n')
+        self.target_file.write(u'# Generated by building qpid_interop_test\n')
+        self.target_file.write(u'# Generated: %s\n\n' % time.strftime(u'%Y-%m-%d %H:%M:%S', time.gmtime()))
+        self.target_file.write(u'import uuid\nimport proton\n\n')
+        self.target_file.write(u'TEST_DATA = {\n')
+
+    def write_code(self, amqp_test_type, json_data):
+        """Write Python code from json_data"""
+        hdr_line = u'=' * (19 + len(amqp_test_type))
+        self.target_file.write(u'\n    # %s\n' % hdr_line)
+        self.target_file.write(u'    # *** AMQP type: %s ***\n' % amqp_test_type)
+        self.target_file.write(u'    # %s\n\n' % hdr_line)
+        self.target_file.write(u'    \'%s\': [\n' % amqp_test_type)
+        for data_pair in json_data:
+            self._write_data_pair(2, data_pair)
+        self.target_file.write(u'    ], # end: AMQP type %s\n' % amqp_test_type)
+
+    def _write_data_pair(self, indent_level, data_pair, separator=u',', eol=True):
+        """Write a JOSN pair ['amqp_type', value]"""
+        indent_str = u' ' * (indent_level * INDENT_LEVEL_SIZE)
+        eol_char = u'\n' if eol else u''
+        amqp_type, value = data_pair
+        if amqp_type == u'null':
+            self.target_file.write(u'%sNone%s%s' % (indent_str, separator, eol_char))
+        elif amqp_type == u'boolean':
+            self.target_file.write(u'%s%s%s%s' % (indent_str, value, separator, eol_char))
+        elif amqp_type == u'ubyte':
+            self.target_file.write(u'%sproton.ubyte(%s)%s%s' % (indent_str, value, separator, eol_char))
+        elif amqp_type == u'byte':
+            self.target_file.write(u'%sproton.byte(%s)%s%s' % (indent_str, value, separator, eol_char))
+        elif amqp_type == u'ushort':
+            self.target_file.write(u'%sproton.ushort(%s)%s%s' % (indent_str, value, separator, eol_char))
+        elif amqp_type == u'short':
+            self.target_file.write(u'%sproton.short(%s)%s%s' % (indent_str, value, separator, eol_char))
+        elif amqp_type == u'uint':
+            self.target_file.write(u'%sproton.uint(%s)%s%s' % (indent_str, value, separator, eol_char))
+        elif amqp_type == u'int':
+            self.target_file.write(u'%sproton.int32(%s)%s%s' % (indent_str, value, separator, eol_char))
+        elif amqp_type == u'ulong':
+            self.target_file.write(u'%sproton.ulong(%s)%s%s' % (indent_str, value, separator, eol_char))
+        elif amqp_type == u'long':
+            self.target_file.write(u'%sint(%s)%s%s' % (indent_str, value, separator, eol_char))
+        elif amqp_type == u'float':
+            if isinstance(value, str) and (value[-3:] == u'inf' or value[-3:] == u'NaN'):
+                self.target_file.write(u'%sproton.float32(\'%s\')%s%s' % (indent_str, value, separator, eol_char))
+            else:
+                self.target_file.write(u'%sproton.float32(%s)%s%s' % (indent_str, value, separator, eol_char))
+        elif amqp_type == u'double':
+            if isinstance(value, str) and (value[-3:] == u'inf' or value[-3:] == u'NaN'):
+                self.target_file.write(u'%sfloat(\'%s\')%s%s' % (indent_str, value, separator, eol_char))
+            else:
+                self.target_file.write(u'%sfloat(%s)%s%s' % (indent_str, value, separator, eol_char))
+        elif amqp_type == u'decimal32':
+            self.target_file.write(u'%sproton.decimal32(%s)%s%s' % (indent_str, value, separator, eol_char))
+        elif amqp_type == u'decimal64':
+            self.target_file.write(u'%sproton.decimal64(%s)%s%s' % (indent_str, value, separator, eol_char))
+        elif amqp_type == u'decimal128':
+            byte_itr = iter(value[2:])
+            self.target_file.write(u'%sproton.decimal128(b\'' % indent_str)
+            for char_ in byte_itr:
+                self.target_file.write(u'\\x%c%c' % (char_, next(byte_itr)))
+            self.target_file.write(u'\')%s%s' % (separator, eol_char))
+        elif amqp_type == u'char':
+            self.target_file.write(u'%sproton.char(u\'' % indent_str)
+            if len(value) == 1: # single char
+                self.target_file.write(value)
+            else:
+                byte_itr = iter(value[2:])
+                for char_ in byte_itr:
+                    self.target_file.write(u'\\x%c%c' % (char_, next(byte_itr)))
+            self.target_file.write(u'\')%s%s' % (separator, eol_char))
+        elif amqp_type == u'timestamp':
+            self.target_file.write(u'%sproton.timestamp(%s)%s%s' % (indent_str, value, separator, eol_char))
+        elif amqp_type == u'uuid':
+            self.target_file.write(u'%suuid.UUID(' % indent_str)
+            if value[:2] == u'0x':
+                self.target_file.write(u'int=%s' % value)
+            else:
+                self.target_file.write(u'\'{%s}\'' % value)
+            self.target_file.write(u')%s%s' % (separator, eol_char))
+        elif amqp_type == u'binary':
+            if isinstance(value, str):
+                self.target_file.write(u'%sb\'' % indent_str)
+                if value[:2] == u'0x':
+                    byte_itr = iter(value[2:])
+                    for char_ in byte_itr:
+                        self.target_file.write(u'\\x%c%c' % (char_, next(byte_itr)))
+                else:
+                    for char_ in value:
+                        if char_ == u'\'':
+                            self.target_file.write(u'\\')
+                        self.target_file.write(char_)
+                self.target_file.write(u'\'%s%s' % (separator, eol_char))
+            else:
+                self.target_file.write(u'%s%d%s%s' % (indent_str, value, separator, eol_char))
+        elif amqp_type == u'string':
+            self.target_file.write(u'%su\'' % indent_str)
+            for char_ in value:
+                if char_ == u'\'':
+                    self.target_file.write(u'\\')
+                self.target_file.write(char_)
+            self.target_file.write(u'\'%s%s' % (separator, eol_char))
+        elif amqp_type == u'symbol':
+            self.target_file.write(u'%sproton.symbol(u\'' % indent_str)
+            for char_ in value:
+                if char_ == u'\'':
+                    self.target_file.write(u'\\')
+                self.target_file.write(char_)
+            self.target_file.write(u'\')%s%s' % (separator, eol_char))
+        elif amqp_type == u'array':
+            if not isinstance(value, list):
+                raise RuntimeError(u'AMQP array value not a list, found %s' % type(value))
+            amqp_type = None
+            if value:
+                amqp_type = value[0][0]
+            self.target_file.write(u'%sproton.Array(proton.UNDESCRIBED, %s, [\n' %
+                                   (indent_str, PythonGenerator._proton_type_code(amqp_type)))
+            for value_data_pair in value:
+                if value_data_pair[0] != amqp_type:
+                    raise RuntimeError(u'AMQP array of type %s has element of type %s' %
+                                       (amqp_type, value_data_pair[0]))
+                self._write_data_pair(indent_level+1, value_data_pair)
+            self.target_file.write(u'%s]),%s' % (indent_str, eol_char))
+        elif amqp_type == u'list':
+            if not isinstance(value, list):
+                raise RuntimeError(u'AMQP list value not a list, found %s' % type(value))
+            self.target_file.write(u'%s[\n' % indent_str)
+            for value_data_pair in value:
+                self._write_data_pair(indent_level+1, value_data_pair)
+            self.target_file.write(u'%s],%s' % (indent_str, eol_char))
+        elif amqp_type == u'map':
+            if not isinstance(value, list):
+                raise RuntimeError(u'AMQP map value not a list, found %s' % type(value))
+            if len(value) % 2 != 0:
+                raise RuntimeError(u'AMQP map value list not even, contains %d items' % len(value))
+            self.target_file.write(u'%s{\n' % indent_str)
+            # consume list in pairs (key, value)
+            value_iter = iter(value)
+            for value_data_pair in value_iter:
+                self._write_data_pair(indent_level+1, value_data_pair, separator=u': ', eol=False)
+                value_data_pair = next(value_iter)
+                self._write_data_pair(0, value_data_pair)
+            self.target_file.write(u'%s},%s' % (indent_str, eol_char))
+        else:
+            raise RuntimeError(u'Unknown AMQP type \'%s\'' % amqp_type)
+
+    @staticmethod
+    def _proton_type_code(amqp_type):
+        amqp_types = {
+            None: None,
+            u'null': u'proton.Data.NULL',
+            u'boolean': u'proton.Data.BOOL',
+            u'byte': u'proton.Data.BYTE',
+            u'ubyte': u'proton.Data.UBYTE',
+            u'short': u'proton.Data.SHORT',
+            u'ushort': u'proton.Data.USHORT',
+            u'int': u'proton.Data.INT',
+            u'uint': u'proton.Data.UINT',
+            u'char': u'proton.Data.CHAR',
+            u'long': u'proton.Data.LONG',
+            u'ulong': u'proton.Data.ULONG',
+            u'timestamp': u'proton.Data.TIMESTAMP',
+            u'float': u'proton.Data.FLOAT',
+            u'double': u'proton.Data.DOUBLE',
+            u'decimal32': u'proton.Data.DECIMAL32',
+            u'decimal64': u'proton.Data.DECIMAL64',
+            u'decimal128': u'proton.Data.DECIMAL128',
+            u'uuid': u'proton.Data.UUID',
+            u'binary': u'proton.Data.BINARY',
+            u'string': u'proton.Data.STRING',
+            u'symbol': u'proton.Data.SYMBOL',
+            u'described': u'proton.Data.DESCRIBED',
+            u'array': u'proton.Data.ARRAY',
+            u'list': u'proton.Data.LIST',
+            u'map': u'proton.Data.MAP'
+            }
+        return amqp_types[amqp_type]
+
+    def write_postfix(self):
+        """Write postfix at bottom of Python source file"""
+        self.target_file.write(u'}\n\n# <eof>\n')
+
+
+class CppGenerator(Generator):
+    """C++ code generator"""
+
+    def __init__(self, target_file_name):
+        super(CppGenerator, self).__init__(target_file_name)
+        self.d32_count = 0
+        self.d64_count = 0
+        self.d128_count = 0
+        self.ts_count = 0
+        self.uuid_count = 0
+        self.bin_count = 0
+        self.sym_count = 0
+        self.arr_count = 0
+        self.list_count = 0
+        self.map_count = 0
+
+    CODE_SEGMET_A = u'''#include <limits> // std::numeric_limits
+#include <map>
+#include <vector>
+
+#include "amqp_complex_types_test.data.hpp"
+
+namespace qpidit {
+    namespace amqp_complex_types_test {
+
+        typedef std::map<const std::string, const std::vector<proton::value> > TestDataMap_t;
+        typedef TestDataMap_t::const_iterator TestDataMapCitr_t;
+
+        class TestData {
+          public:
+            static bool initialize();
+            static bool initialized;
+            static TestDataMap_t s_data_map;
+        };
+
+        bool TestData::initialize() {
+'''
+
+    CODE_SEGMENT_B = u'''            return true;
+        }
+
+        TestDataMap_t TestData::s_data_map;
+
+        bool TestData::initialized = TestData::initialize();
+    } // namespace amqp_complex_types_test
+} // namespace qpidit
+'''
+
+    PROTON_TYPES = [u'decimal32', u'decimal64', u'decimal128', u'timestamp', u'uuid', u'binary', u'symbol']
+    COMPLEX_TYPES = [u'array', u'list', u'map']
+
+
+    def write_prefix(self):
+        """Write comments, copyright, etc at top of C++ source file"""
+        self.target_file.write(u'/**\n * Data used for qpid_interop_test.amqp_complex_types_test\n */\n\n')
+        self.target_file.write(u'/*\n')
+        for line in iter(COPYRIGHT_TEXT.splitlines()):
+            self.target_file.write(u' * %s\n' % line)
+        self.target_file.write(u' */\n\n')
+        self.target_file.write(u'/*\n')
+        self.target_file.write(u' * THIS IS A GENERATED FILE, DO NOT EDIT DIRECTLY\n')
+        self.target_file.write(u' * Generated by building qpid_interop_test\n')
+        self.target_file.write(u' * Generated: %s\n' % time.strftime(u'%Y-%m-%d %H:%M:%S', time.gmtime()))
+        self.target_file.write(u' */\n\n')
+        self.target_file.write(CppGenerator.CODE_SEGMET_A)
+
+    def write_code(self, amqp_test_type, json_data):
+        """Write C++ code from json_data"""
+        indent_level = 3
+        indent_str = u' ' * (indent_level * INDENT_LEVEL_SIZE)
+        container_name = u'%s_list' % amqp_test_type
+        container_type = u'std::vector<proton::value>'
+        hdr_line = u'*' * (17 + len(amqp_test_type))
+        self.target_file.write(u'\n%s/*%s\n' % (indent_str, hdr_line))
+        self.target_file.write(u'%s*** AMQP type: %s ***\n' % (indent_str, amqp_test_type))
+        self.target_file.write(u'%s%s*/\n\n' % (indent_str, hdr_line))
+        self.target_file.write(u'%s%s %s;\n\n' % (indent_str, container_type, container_name))
+        self._pre_write_list(indent_level, container_name, json_data, True)
+        self.target_file.write(u'%ss_data_map.insert(std::pair<const std::string, %s >("%s", %s));\n\n' %
+                               (indent_str, container_type, amqp_test_type, container_name))
+
+    def _pre_write_list(self, indent_level, container_name, value, push_flag=False):
+        """If a value in a list is a complex or proton type, write instances before the list itself is written"""
+        instance_name_list = []
+        for value_data_pair in value:
+            if value_data_pair[0] in CppGenerator.COMPLEX_TYPES:
+                self._write_complex_instance(indent_level, container_name, value_data_pair, instance_name_list,
+                                             push_flag)
+            elif value_data_pair[0] in CppGenerator.PROTON_TYPES:
+                self._write_proton_instance(indent_level, value_data_pair, instance_name_list)
+        return instance_name_list
+
+    def _write_complex_instance(self, indent_level, container_name, data_pair, instance_name_list, push_flag):
+        indent_str = u' ' * (indent_level * INDENT_LEVEL_SIZE)
+        amqp_type, value = data_pair
+        if amqp_type == u'array':
+            if not isinstance(value, list):
+                raise RuntimeError(u'AMQP array value not a list, found %s' % type(value))
+            inner_instance_name_list = self._pre_write_list(indent_level, container_name, value)
+            self.arr_count += 1
+            self.target_file.write(u'%sstd::vector<proton::value> array_%d = {' % (indent_str, self.arr_count))
+            instance_name_list.append(u'array_%d' % self.arr_count)
+            for value_data_pair in value:
+                self._write_data_pair(value_data_pair, inner_instance_name_list)
+            self.target_file.write(u'};\n')
+            if push_flag:
+                self.target_file.write(u'%s%s.push_back(array_%d);\n\n' % (indent_str, container_name, self.arr_count))
+        elif amqp_type == u'list':
+            if not isinstance(value, list):
+                raise RuntimeError(u'AMQP list value not a list, found %s' % type(value))
+            inner_instance_name_list = self._pre_write_list(indent_level, container_name, value)
+            self.list_count += 1
+            self.target_file.write(u'%sstd::vector<proton::value> list_%d = {' % (indent_str, self.list_count))
+            instance_name_list.append(u'list_%d' % self.list_count)
+            for value_data_pair in value:
+                self._write_data_pair(value_data_pair, inner_instance_name_list)
+            self.target_file.write(u'};\n')
+            if push_flag:
+                self.target_file.write(u'%s%s.push_back(list_%d);\n\n' % (indent_str, container_name, self.list_count))
+        elif amqp_type == u'map':
+            if not isinstance(value, list):
+                raise RuntimeError(u'AMQP map value not a list, found %s' % type(value))
+            if len(value) % 2 != 0:
+                raise RuntimeError(u'AMQP map value list not even, contains %d items' % len(value))
+            inner_instance_name_list = self._pre_write_list(indent_level, container_name, value)
+            self.map_count += 1
+            self.target_file.write(u'%sstd::vector<proton::value> map_%d = {' %
+                                   (indent_str, self.map_count))
+            instance_name_list.append(u'map_%d' % self.map_count)
+            # consume list in pairs (key, value)
+            value_iter = iter(value)
+            for value_data_pair in value_iter:
+                self._write_data_pair(value_data_pair, inner_instance_name_list)
+                value_data_pair = next(value_iter)
+                self._write_data_pair(value_data_pair, inner_instance_name_list)
+            self.target_file.write(u'};\n')
+            if push_flag:
+                self.target_file.write(u'%s%s.push_back(map_%d);\n\n' % (indent_str, container_name, self.map_count))
+
+    def _write_proton_instance(self, indent_level, data_pair, instance_name_list):
+        """
+        Proton types do not yet support literals. Write proton values as instances, place assigned variable name
+        onto instance_name_list so they can be placed into the AMQP complex type container.
+        """
+        indent_str = u' ' * (indent_level * INDENT_LEVEL_SIZE)
+        amqp_type, value = data_pair
+        if amqp_type == u'decimal32':
+            self.d32_count += 1
+            self.target_file.write(u'%sproton::decimal32 d32_%d;\n' % (indent_str, self.d32_count))
+            self.target_file.write(u'%shexStringToBytearray(d32_%d, "%s");\n' %
+                                   (indent_str, self.d32_count, value[2:]))
+            instance_name_list.append(u'd32_%d' % self.d32_count)
+        elif amqp_type == u'decimal64':
+            self.d64_count += 1
+            self.target_file.write(u'%sproton::decimal64 d64_%d;\n' % (indent_str, self.d64_count))
+            self.target_file.write(u'%shexStringToBytearray(d64_%d, "%s");\n' %
+                                   (indent_str, self.d64_count, value[2:]))
+            instance_name_list.append(u'd64_%d' % self.d64_count)
+        elif amqp_type == u'decimal128':
+            self.d128_count += 1
+            self.target_file.write(u'%sproton::decimal128 d128_%d;\n' % (indent_str, self.d128_count))
+            self.target_file.write(u'%shexStringToBytearray(d128_%d, "%s");\n' %
+                                   (indent_str, self.d128_count, value[2:]))
+            instance_name_list.append(u'd128_%d' % self.d128_count)
+        elif amqp_type == u'timestamp':
+            self.ts_count += 1
+            radix = 16 if isinstance(value, str) and len(value) > 2 and value[:2] == u'0x' else 10
+            if radix == 16: # hex string
+                self.target_file.write(u'%sproton::timestamp ts_%d(std::strtoul(' % (indent_str, self.ts_count) +
+                                       u'std::string("%s").data(), nullptr, 16));\n' % value[2:])
+            else:
+                self.target_file.write(u'%sproton::timestamp ts_%d(%s);\n' % (indent_str, self.ts_count, value))
+            instance_name_list.append(u'ts_%d' % self.ts_count)
+        elif amqp_type == u'uuid':
+            self.uuid_count += 1
+            self.target_file.write(u'%sproton::uuid uuid_%d;\n' % (indent_str, self.uuid_count))
+            if isinstance(value, str) and len(value) > 2 and value[:2] == u'0x': # Hex string "0x..."
+                # prefix hex strings < 32 chars (16 bytes) with 0s to make exactly 32 chars long
+                fill_size = 32 - len(value[2:])
+                uuid_hex_str = u'%s%s' % (u'0' * fill_size, value[2:])
+                self.target_file.write(u'%shexStringToBytearray(uuid_%d, "%s");\n' %
+                                       (indent_str, self.uuid_count, uuid_hex_str))
+            else: # UUID format "00000000-0000-0000-0000-000000000000"
+                self.target_file.write(u'%ssetUuid(uuid_%d, "%s");\n' % (indent_str, self.uuid_count, value))
+            instance_name_list.append(u'uuid_%d' % self.uuid_count)
+        elif amqp_type == u'binary':
+            self.bin_count += 1
+            if isinstance(value, int) or (isinstance(value, str) and len(value) > 2 and value[:2] == u'0x'): # numeric
+                hex_str = u'{:02x}'.format(value) if isinstance(value, int) else value[2:]
+                if len(hex_str) % 2 > 0: # make string even no. of hex chars, prefix with '0' if needed
+                    hex_str = u'0%s' % hex_str
+                self.target_file.write(u'%sproton::binary bin_%d(hexStringToBinaryString("%s"));\n' %
+                                       (indent_str, self.bin_count, hex_str))
+            else: # string
+                self.target_file.write(u'%sproton::binary bin_%d("%s");\n' % (indent_str, self.bin_count, value))
+            instance_name_list.append(u'bin_%d' % self.bin_count)
+        elif amqp_type == u'symbol':
+            self.sym_count += 1
+            self.target_file.write(u'%sproton::symbol sym_%d("%s");\n' % (indent_str, self.sym_count, value))
+            instance_name_list.append(u'sym_%d' % self.sym_count)
+
+    def _write_data_pair(self, data_pair, instance_name_list=None):
+        """
+        Write a JOSN pair ['amqp_type', value]. If amqp_type is complex or a proton type, pop instance name from
+        intance_name_list (which has been previously declared).
+        """
+        amqp_type, value = data_pair
+        if amqp_type == u'null':
+            # TODO: Temporarily suppress use of nullptr until C++ binding issues are fixed, see PROTON-1818
+            #self.target_file.write(u'nullptr, ')
+            pass
+        elif amqp_type == u'boolean':
+            self.target_file.write(u'%s, ' % str(value).lower())
+        elif amqp_type == u'ubyte':
+            self.target_file.write(u'uint8_t(%s), ' % value)
+        elif amqp_type == u'byte':
+            self.target_file.write(u'int8_t(%s), ' % value)
+        elif amqp_type == u'ushort':
+            self.target_file.write(u'uint16_t(%s), ' % value)
+        elif amqp_type == u'short':
+            self.target_file.write(u'int16_t(%s), ' % value)
+        elif amqp_type == u'uint':
+            self.target_file.write(u'uint32_t(%s), ' % value)
+        elif amqp_type == u'int':
+            self.target_file.write(u'int32_t(%s), ' % value)
+        elif amqp_type == u'ulong':
+            self.target_file.write(u'uint64_t(%s), ' % value)
+        elif amqp_type == u'long':
+            self.target_file.write(u'int64_t(%s), ' % value)
+        elif amqp_type == u'float':
+            if isinstance(value, str):
+                if value == u'inf':
+                    self.target_file.write(u'std::numeric_limits<float>::infinity(), ')
+                elif value == u'-inf':
+                    self.target_file.write(u'-std::numeric_limits<float>::infinity(), ')
+                elif value == u'NaN':
+                    self.target_file.write(u'std::numeric_limits<float>::quiet_NaN(), ')
+                else:
+                    self.target_file.write(u'float(%s), ' % value)
+            else:
+                self.target_file.write(u'float(%s), ' % str(value))
+        elif amqp_type == u'double':
+            if isinstance(value, str):
+                if value == u'inf':
+                    self.target_file.write(u'std::numeric_limits<double>::infinity(), ')
+                elif value == u'-inf':
+                    self.target_file.write(u'-std::numeric_limits<double>::infinity(), ')
+                elif value == u'NaN':
+                    self.target_file.write(u'std::numeric_limits<double>::quiet_NaN(), ')
+                else:
+                    self.target_file.write(u'double(%s), ' % value)
+            else:
+                self.target_file.write(u'double(%s), ' % str(value))
+        elif amqp_type == u'decimal32':
+            if instance_name_list is not None:
+                self.target_file.write(u'%s, ' % instance_name_list.pop(0))
+        elif amqp_type == u'decimal64':
+            if instance_name_list is not None:
+                self.target_file.write(u'%s, ' % instance_name_list.pop(0))
+        elif amqp_type == u'decimal128':
+            if instance_name_list is not None:
+                self.target_file.write(u'%s, ' % instance_name_list.pop(0))
+        elif amqp_type == u'char':
+            if len(value) == 1: # single char
+                self.target_file.write(u'wchar_t(\'%s\'), ' % value)
+            else:
+                self.target_file.write(u'wchar_t(%s), ' % value)
+        elif amqp_type == u'timestamp':
+            if instance_name_list is not None:
+                self.target_file.write(u'%s, ' % instance_name_list.pop(0))
+        elif amqp_type == u'uuid':
+            if instance_name_list is not None:
+                self.target_file.write(u'%s, ' % instance_name_list.pop(0))
+        elif amqp_type == u'binary':
+            if instance_name_list is not None:
+                self.target_file.write(u'%s, ' % instance_name_list.pop(0))
+        elif amqp_type == u'string':
+            self.target_file.write(u'std::string("')
+            for char_ in value:
+                if char_ == u'\'' or char_ == u'"':
+                    self.target_file.write(u'\\')
+                self.target_file.write(char_)
+            self.target_file.write(u'"), ')
+        elif amqp_type == u'symbol':
+            if instance_name_list is not None:
+                self.target_file.write(u'%s, ' % instance_name_list.pop(0))
+        elif amqp_type == u'array':
+            if instance_name_list is not None and instance_name_list:
+                self.target_file.write(u'%s, ' % instance_name_list.pop(0))
+        elif amqp_type == u'list':
+            if instance_name_list is not None and instance_name_list:
+                self.target_file.write(u'%s, ' % instance_name_list.pop(0))
+        elif amqp_type == u'map':
+            if instance_name_list is not None and instance_name_list:
+                self.target_file.write(u'%s, ' % instance_name_list.pop(0))
+
+    @staticmethod
+    def _cpp_type(amqp_type, amqp_sub_type=None):
+        cpp_types = {
+            None: u'NULL',
+            u'null': u'std::nullptr_t',
+            u'boolean': u'bool',
+            u'byte': u'int8_t',
+            u'ubyte': u'uint8_t',
+            u'short': u'int16_t',
+            u'ushort': u'uint16_t',
+            u'int': u'int32_t',
+            u'uint': u'uint32_t',
+            u'char': u'wchar_t',
+            u'long': u'int64_t',
+            u'ulong': u'uint64_t',
+            u'timestamp': u'proton::timestamp',
+            u'float': u'float',
+            u'double': u'double',
+            u'decimal32': u'proton::decimal32',
+            u'decimal64': u'proton::decimal64',
+            u'decimal128': u'proton::decimal128',
+            u'uuid': u'proton::uuid',
+            u'binary': u'proton::binary',
+            u'string': u'std::string',
+            u'symbol': u'proton::symbol',
+            u'described': u'proton::described',
+            u'array': u'std::vector<%s> ' % amqp_sub_type,
+            u'list': u'std::vector<proton::value> ',
+            u'map': u'std::vector<proton::value> '
+            }
+        return cpp_types[amqp_type]
+
+    def write_postfix(self):
+        """Write postfix at bottom of C++ source file"""
+        self.target_file.write(CppGenerator.CODE_SEGMENT_B)
+        self.target_file.write(u'// <eof>\n')
+
+
+class JavaScriptGenerator(Generator):
+    """JavaScript code generator"""
+
+    def write_prefix(self):
+        """Write comments, copyright, etc at top of JavaScript source file"""
+        self.target_file.write(u'#!/usr/bin/env node\n\n')
+        self.target_file.write(u'/*\n * Data used for qpid_interop_test.amqp_complex_types_test\n */\n\n')
+        self.target_file.write(u'/*\n')
+        for line in iter(COPYRIGHT_TEXT.splitlines()):
+            self.target_file.write(u' * %s\n' % line)
+        self.target_file.write(u' */\n\n')
+        self.target_file.write(u'/*\n')
+        self.target_file.write(u' * THIS IS A GENERATED FILE, DO NOT EDIT DIRECTLY\n')
+        self.target_file.write(u' * Generated by building qpid_interop_test\n')
+        self.target_file.write(u' * Generated: %s\n'% time.strftime(u'%Y-%m-%d %H:%M:%S', time.gmtime()))
+        self.target_file.write(u' */\n\n')
+
+    def write_code(self, amqp_test_type, json_data):
+        """Write JavaScript code from json_data"""
+        pass
+
+    def write_postfix(self):
+        """Write postfix at bottom of JavaScript source file"""
+        self.target_file.write()
+        self.target_file.write(u'// <eof>\n')
+
+
+class DotNetGenerator(Generator):
+    """DotNet code generator"""
+
+    def write_prefix(self):
+        """Write comments, copyright, etc at top of DotNet source file"""
+        self.target_file.write(u'/*\n * Data used for qpid_interop_test.amqp_complex_types_test\n */\n\n')
+        self.target_file.write(u'/*\n')
+        for line in iter(COPYRIGHT_TEXT.splitlines()):
+            self.target_file.write(u' * %s\n' % line)
+        self.target_file.write(u' */\n\n')
+        self.target_file.write(u'/*\n')
+        self.target_file.write(u' * THIS IS A GENERATED FILE, DO NOT EDIT DIRECTLY\n')
+        self.target_file.write(u' * Generated by building qpid_interop_test\n')
+        self.target_file.write(u' * Generated: %s\n'% time.strftime(u'%Y-%m-%d %H:%M:%S', time.gmtime()))
+        self.target_file.write(u' */\n\n')
+
+    def write_code(self, amqp_test_type, json_data):
+        """Write DotNet code from json_data"""
+        pass
+
+    def write_postfix(self):
+        """Write postfix at bottom of DotNet source file"""
+        self.target_file.write(u'// <eof>\n')
+
+
+class GeneratorOptions(object):
+    """Class to handle generator options"""
+    def __init__(self):
+        self._parser = argparse.ArgumentParser(description=u'AMQP Complex Types Test: test data generator')
+        self._parser.add_argument(u'--type', choices=AMQP_COMPEX_TYPES, default=u'ALL', metavar=u'TYPE',
+                                  help=u'AMQP complex type to test %s' % AMQP_COMPEX_TYPES)
+        self._parser.add_argument(u'--json-base-name', action=u'store', default=DEFAULT_JSON_BASE_NAME,
+                                  metavar=u'BASENAME',
+                                  help=u'JSON data file base name [%s]' % DEFAULT_JSON_BASE_NAME)
+        self._parser.add_argument(u'--gen', choices=GENERATOR_TARGETS, default=u'ALL', metavar=u'TARGET',
+                                  help=u'Generate for target %s' % GENERATOR_TARGETS)
+        self._parser.add_argument(u'--gen-dir', action=u'store', default=u'.', metavar=u'DIR',
+                                  help=u'Directory in which to generate source files [.]')
+        self._parser.add_argument(u'--src-dir', action=u'store', default=u'.', metavar=u'DIR',
+                                  help=u'Directory containing JSON data files [.]')
+
+    def args(self):
+        """Return the parsed args"""
+        return self._parser.parse_args()
+
+    def print_help(self, file=None):
+        """Print help"""
+        self._parser.print_help(file)
+
+    def print_usage(self, file=None):
+        """Print usage"""
+        self._parser.print_usage(file)
+
+
+#--- Main program start ---
+
+if __name__ == '__main__':
+    ARGS = GeneratorOptions()
+    READER = JsonReader(ARGS.args())
+    READER.generate()


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org