summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKenneth Anthony Giusti <kgiusti@apache.org>2010-03-30 20:09:59 +0000
committerKenneth Anthony Giusti <kgiusti@apache.org>2010-03-30 20:09:59 +0000
commitfeed6024a260189ed210f7a04049a44d2a2e9937 (patch)
tree8033c7eb7c04e90efb1d0d54e9a5b404695b4e71
parent7b39205d3938dcdf87e78d99caa7d69f02212bf8 (diff)
downloadqpid-python-feed6024a260189ed210f7a04049a44d2a2e9937.tar.gz
add support for QMF TYPE_LIST in engine, ruby and python wrappers
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@929244 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--qpid/cpp/bindings/qmf/python/qmf.py30
-rw-r--r--qpid/cpp/bindings/qmf/ruby/qmf.rb22
-rwxr-xr-xqpid/cpp/bindings/qmf/tests/agent_ruby.rb6
-rw-r--r--qpid/cpp/bindings/qmf/tests/python_agent.py8
-rwxr-xr-xqpid/cpp/bindings/qmf/tests/python_console.py21
-rwxr-xr-xqpid/cpp/bindings/qmf/tests/ruby_console_test.rb17
-rw-r--r--qpid/cpp/src/qmf/engine/ValueImpl.cpp167
-rw-r--r--qpid/cpp/src/qmf/engine/ValueImpl.h13
-rw-r--r--qpid/extras/qmf/src/py/qmf/console.py19
9 files changed, 254 insertions, 49 deletions
diff --git a/qpid/cpp/bindings/qmf/python/qmf.py b/qpid/cpp/bindings/qmf/python/qmf.py
index e4ab581dfd..5dc1330cdb 100644
--- a/qpid/cpp/bindings/qmf/python/qmf.py
+++ b/qpid/cpp/bindings/qmf/python/qmf.py
@@ -58,10 +58,9 @@ def qmf_to_native(val):
elif typecode == TYPE_INT32: return val.asInt()
elif typecode == TYPE_INT64: return val.asInt64()
elif typecode == TYPE_MAP: return value_to_dict(val)
+ elif typecode == TYPE_LIST: return value_to_list(val)
else:
# when TYPE_OBJECT
- # when TYPE_LIST
- # when TYPE_ARRAY
logging.error( "Unsupported type for get_attr? '%s'" % str(val.getType()) )
return None
@@ -98,11 +97,9 @@ def native_to_qmf(target, value):
elif typecode == TYPE_INT32: val.setInt(value)
elif typecode == TYPE_INT64: val.setInt64(value)
elif typecode == TYPE_MAP: dict_to_value(val, value)
+ elif typecode == TYPE_LIST: list_to_value(val, value)
else:
- # when TYPE_MAP
# when TYPE_OBJECT
- # when TYPE_LIST
- # when TYPE_ARRAY
logging.error("Unsupported type for get_attr? '%s'" % str(val.getType()))
return None
return val
@@ -129,6 +126,7 @@ def pick_qmf_type(value):
if value.__class__ == bool: return TYPE_BOOL
if value == None: return TYPE_BOOL
if value.__class__ == dict: return TYPE_MAP
+ if value.__class__ == list: return TYPE_LIST
raise "QMF type not known for native type %s" % value.__class__
@@ -140,7 +138,7 @@ def value_to_dict(val):
key = val.key(i)
mymap[key] = qmf_to_native(val.byKey(key))
return mymap
-
+
def dict_to_value(val, mymap):
for key, value in mymap.items():
@@ -149,6 +147,26 @@ def dict_to_value(val, mymap):
val.insert(key, native_to_qmf(typecode, value))
+def value_to_list(val):
+ mylist = []
+ if val.isList():
+ for i in range(val.listItemCount()):
+ mylist.append(qmf_to_native(val.listItem(i)))
+ return mylist
+ #if val.isArray():
+ # for i in range(val.arrayItemCount()):
+ # mylist.append(qmf_to_native(val.arrayItem(i)))
+ # return mylist
+
+ raise "value_to_list must be given a list value"
+
+
+def list_to_value(val, mylist):
+ for item in mylist:
+ typecode = pick_qmf_type(item)
+ val.appendToList(native_to_qmf(typecode, item))
+
+
##==============================================================================
## CONNECTION
##==============================================================================
diff --git a/qpid/cpp/bindings/qmf/ruby/qmf.rb b/qpid/cpp/bindings/qmf/ruby/qmf.rb
index ce824b3605..823cf9bf93 100644
--- a/qpid/cpp/bindings/qmf/ruby/qmf.rb
+++ b/qpid/cpp/bindings/qmf/ruby/qmf.rb
@@ -48,8 +48,8 @@ module Qmf
when TYPE_INT8, TYPE_INT16, TYPE_INT32 then val.asInt
when TYPE_INT64 then val.asInt64
when TYPE_MAP then value_to_dict(val)
+ when TYPE_LIST then value_to_list(val)
when TYPE_OBJECT
- when TYPE_LIST
when TYPE_ARRAY
end
end
@@ -77,8 +77,8 @@ module Qmf
when TYPE_INT8, TYPE_INT16, TYPE_INT32 then val.setInt(value)
when TYPE_INT64 then val.setInt64(value)
when TYPE_MAP then dict_to_value(val, value)
+ when TYPE_LIST then list_to_value(val, value)
when TYPE_OBJECT
- when TYPE_LIST
when TYPE_ARRAY
end
return val
@@ -112,6 +112,7 @@ module Qmf
return TYPE_BOOL if value.class == NilClass
return TYPE_MAP if value.class == Hash
+ return TYPE_LIST if value.class == Array
raise ArgumentError, "QMF type not known for native type #{value.class}"
end
@@ -134,6 +135,23 @@ module Qmf
val.insert(key, native_to_qmf(typecode, value))
end
end
+
+ def value_to_list(val)
+ # Assume val is of type Qmfengine::Value
+ raise ArgumentError, "value_to_dict must be given a map value" if !val.isList
+ list = []
+ for i in 0...val.listItemCount
+ list.push(qmf_to_native(val.listItem(i)))
+ end
+ return list
+ end
+
+ def list_to_value(val, list)
+ list.each do |value|
+ typecode = pick_qmf_type(value)
+ val.appendToList(native_to_qmf(typecode, value))
+ end
+ end
end
$util = Util.new
diff --git a/qpid/cpp/bindings/qmf/tests/agent_ruby.rb b/qpid/cpp/bindings/qmf/tests/agent_ruby.rb
index 86eefc59a6..92065031a2 100755
--- a/qpid/cpp/bindings/qmf/tests/agent_ruby.rb
+++ b/qpid/cpp/bindings/qmf/tests/agent_ruby.rb
@@ -44,6 +44,7 @@ class Model
@parent_class.add_property(Qmf::SchemaProperty.new("lstrval", Qmf::TYPE_LSTR))
@parent_class.add_property(Qmf::SchemaProperty.new("mapval", Qmf::TYPE_MAP))
+ @parent_class.add_property(Qmf::SchemaProperty.new("listval", Qmf::TYPE_LIST))
@parent_class.add_statistic(Qmf::SchemaStatistic.new("queryCount", Qmf::TYPE_UINT32, :unit => "query", :desc => "Query count"))
@@ -246,6 +247,11 @@ class App < Qmf::AgentHandler
@parent.int16val = 0
@parent.int8val = 0
+ # a list containing a list that contains a map (so there!)
+ @parent.listval = ['a', 1, 'b', 2,
+ ['c', true, 3.1415,
+ {"hi" => 10, "lo" => 5}]]
+
@parent_oid = @agent.alloc_object_id(1)
@parent.set_object_id(@parent_oid)
diff --git a/qpid/cpp/bindings/qmf/tests/python_agent.py b/qpid/cpp/bindings/qmf/tests/python_agent.py
index 83531830b1..4974e0ec90 100644
--- a/qpid/cpp/bindings/qmf/tests/python_agent.py
+++ b/qpid/cpp/bindings/qmf/tests/python_agent.py
@@ -45,6 +45,7 @@ class Model:
self.parent_class.add_property(qmf.SchemaProperty("lstrval", qmf.TYPE_LSTR))
self.parent_class.add_property(qmf.SchemaProperty("mapval", qmf.TYPE_MAP))
+ self.parent_class.add_property(qmf.SchemaProperty("listval", qmf.TYPE_LIST))
self.parent_class.add_statistic(qmf.SchemaStatistic("queryCount", qmf.TYPE_UINT32, {"unit":"query", "desc":"Query count"}))
@@ -274,7 +275,7 @@ class App(qmf.AgentHandler):
## @todo how do we force a test failure?
# verify the properties() and statistics() object methods:
- assert len(self._parent.properties()) == 13
+ assert len(self._parent.properties()) == 14
assert len(self._parent.statistics()) == 1
self._parent.set_attr("name", "Parent One")
@@ -290,6 +291,11 @@ class App(qmf.AgentHandler):
self._parent.set_attr("int16val", 0)
self._parent.set_attr("int8val", 0)
+ # a list containing a list that contains a map (so there!)
+ self._parent.set_attr("listval", ['a', 1, 'b', 2,
+ ['c', True, 3.1415,
+ {"hi": 10, "lo": 5}]])
+
self._parent_oid = self._agent.alloc_object_id(1)
self._parent.set_object_id(self._parent_oid)
diff --git a/qpid/cpp/bindings/qmf/tests/python_console.py b/qpid/cpp/bindings/qmf/tests/python_console.py
index fe27c33c4b..efd25a1d26 100755
--- a/qpid/cpp/bindings/qmf/tests/python_console.py
+++ b/qpid/cpp/bindings/qmf/tests/python_console.py
@@ -202,7 +202,26 @@ class QmfInteropTests(TestBase010):
self.assertEqual(queue[3].arguments["strval"], "TEST")
self.assertEqual(queue[4].arguments["uint32val"], 0)
self.assertEqual(queue[4].arguments["strval"], "LONG_TEST")
-
+
+
+ def test_G_basic_map_list_data(self):
+ self.startQmf();
+ qmf = self.qmf
+
+ parents = qmf.getObjects(_class="parent")
+ self.assertEqual(len(parents), 1)
+ parent = parents[0]
+
+ # see agent for structure of listval
+
+ self.assertTrue(isinstance(parent.listval, list))
+ self.assertEqual(len(parent.listval), 5)
+ self.assertTrue(isinstance(parent.listval[4], list))
+ self.assertEqual(len(parent.listval[4]), 4)
+ self.assertTrue(isinstance(parent.listval[4][3], dict))
+ self.assertEqual(parent.listval[4][3]["hi"], 10)
+ self.assertEqual(parent.listval[4][3]["lo"], 5)
+
def getProperty(self, msg, name):
for h in msg.headers:
diff --git a/qpid/cpp/bindings/qmf/tests/ruby_console_test.rb b/qpid/cpp/bindings/qmf/tests/ruby_console_test.rb
index 3a771aaafd..9ef0ef57a8 100755
--- a/qpid/cpp/bindings/qmf/tests/ruby_console_test.rb
+++ b/qpid/cpp/bindings/qmf/tests/ruby_console_test.rb
@@ -266,6 +266,23 @@ class ConsoleTest < ConsoleTestBase
end
end
+
+
+ def test_G_basic_map_list_data
+ parent = @qmfc.object(:class => "parent")
+ assert(parent, "Number of 'parent' objects")
+
+ # see agent for structure of listval
+
+ assert(parent.listval.class == Array)
+ assert_equal(parent.listval.length, 5)
+ assert(parent.listval[4].class == Array)
+ assert_equal(parent.listval[4].length, 4)
+ assert(parent.listval[4][3].class == Hash)
+ assert_equal(parent.listval[4][3]["hi"], 10)
+ assert_equal(parent.listval[4][3]["lo"], 5)
+ end
+
end
app = ConsoleTest.new
diff --git a/qpid/cpp/src/qmf/engine/ValueImpl.cpp b/qpid/cpp/src/qmf/engine/ValueImpl.cpp
index b1c027520f..72c68c420b 100644
--- a/qpid/cpp/src/qmf/engine/ValueImpl.cpp
+++ b/qpid/cpp/src/qmf/engine/ValueImpl.cpp
@@ -18,20 +18,23 @@
*/
#include "qmf/engine/ValueImpl.h"
-#include <qpid/framing/FieldTable.h>
#include <qpid/framing/FieldValue.h>
+#include <qpid/framing/FieldTable.h>
+#include <qpid/framing/List.h>
using namespace std;
using namespace qmf::engine;
-using qpid::framing::Buffer;
-using qpid::framing::FieldTable;
-using qpid::framing::FieldValue;
+//using qpid::framing::Buffer;
+//using qpid::framing::FieldTable;
+//using qpid::framing::FieldValue;
+using namespace qpid::framing;
ValueImpl::ValueImpl(Typecode t, Buffer& buf) : typecode(t)
{
uint64_t first;
uint64_t second;
FieldTable ft;
+ List fl;
switch (typecode) {
case TYPE_UINT8 : value.u32 = (uint32_t) buf.getOctet(); break;
@@ -62,6 +65,10 @@ ValueImpl::ValueImpl(Typecode t, Buffer& buf) : typecode(t)
break;
case TYPE_LIST:
+ fl.decode(buf);
+ initList(fl);
+ break;
+
case TYPE_ARRAY:
case TYPE_OBJECT:
default:
@@ -126,7 +133,7 @@ void ValueImpl::initMap(const FieldTable& ft)
Value* subval(new Value(TYPE_DOUBLE));
subval->setDouble(fvalue.get<double>());
insert(name.c_str(), subval);
- } else {
+ } else if (amqType == 0xa8) {
FieldTable subFt;
bool valid = qpid::framing::getEncodedValue<FieldTable>(iter->second, subFt);
if (valid) {
@@ -134,6 +141,14 @@ void ValueImpl::initMap(const FieldTable& ft)
subval->impl->initMap(subFt);
insert(name.c_str(), subval);
}
+ } else if (amqType == 0xa9) {
+ List subList;
+ bool valid = qpid::framing::getEncodedValue<List>(iter->second, subList);
+ if (valid) {
+ Value* subval(new Value(TYPE_LIST));
+ subval->impl->initList(subList);
+ insert(name.c_str(), subval);
+ }
}
}
}
@@ -185,6 +200,14 @@ void ValueImpl::mapToFieldTable(FieldTable& ft) const
ft.setTable(name, subFt);
break;
case TYPE_LIST:
+ {
+ List subList;
+ subval.impl->listToFramingList(subList);
+ ft.set(name,
+ ::qpid::framing::FieldTable::ValuePtr(
+ new ListValue(
+ subList)));
+ } break;
case TYPE_ARRAY:
case TYPE_OBJECT:
case TYPE_UUID:
@@ -195,9 +218,126 @@ void ValueImpl::mapToFieldTable(FieldTable& ft) const
}
}
+
+void ValueImpl::initList(const List& fl)
+{
+ for (List::const_iterator iter = fl.begin();
+ iter != fl.end(); iter++) {
+ const FieldValue& fvalue(*iter->get());
+ uint8_t amqType = fvalue.getType();
+
+ if (amqType == 0x32) {
+ Value* subval(new Value(TYPE_UINT64));
+ subval->setUint64(fvalue.get<int64_t>());
+ appendToList(subval);
+ } else if ((amqType & 0xCF) == 0x02) {
+ Value* subval(new Value(TYPE_UINT32));
+ switch (amqType) {
+ case 0x02 : subval->setUint(fvalue.get<int>()); break;
+ case 0x12 : subval->setUint(fvalue.get<int>()); break;
+ case 0x22 : subval->setUint(fvalue.get<int>()); break;
+ }
+ appendToList(subval);
+ } else if ((amqType & 0xCF) == 0x01) {
+ Value* subval(new Value(TYPE_INT64));
+ subval->setInt64(fvalue.get<int64_t>());
+ appendToList(subval);
+ } else if (amqType == 0x85 || amqType == 0x95) {
+ Value* subval(new Value(TYPE_LSTR));
+ subval->setString(fvalue.get<string>().c_str());
+ appendToList(subval);
+ } else if (amqType == 0x23 || amqType == 0x33) {
+ Value* subval(new Value(TYPE_DOUBLE));
+ subval->setDouble(fvalue.get<double>());
+ appendToList(subval);
+ } else if (amqType == 0xa8) {
+ FieldTable subFt;
+ bool valid = qpid::framing::getEncodedValue<FieldTable>(*iter, subFt);
+ if (valid) {
+ Value* subval(new Value(TYPE_MAP));
+ subval->impl->initMap(subFt);
+ appendToList(subval);
+ }
+ } else if (amqType == 0xa9) {
+ List subList;
+ bool valid = qpid::framing::getEncodedValue<List>(*iter, subList);
+ if (valid) {
+ Value *subVal(new Value(TYPE_LIST));
+ subVal->impl->initList(subList);
+ appendToList(subVal);
+ }
+ }
+ }
+}
+
+void ValueImpl::listToFramingList(List& fl) const
+{
+ for (vector<Value>::const_iterator iter = vectorVal.begin();
+ iter != vectorVal.end(); iter++) {
+ const Value& subval(*iter);
+
+ switch (subval.getType()) {
+ case TYPE_UINT8:
+ case TYPE_UINT16:
+ case TYPE_UINT32:
+ fl.push_back(List::ValuePtr(new Unsigned64Value((uint64_t) subval.asUint())));
+ break;
+ case TYPE_UINT64:
+ case TYPE_DELTATIME:
+ fl.push_back(List::ValuePtr(new Unsigned64Value(subval.asUint64())));
+ break;
+ case TYPE_SSTR:
+ case TYPE_LSTR:
+ fl.push_back(List::ValuePtr(new Str16Value(subval.asString())));
+ break;
+ case TYPE_INT64:
+ case TYPE_ABSTIME:
+ fl.push_back(List::ValuePtr(new Integer64Value(subval.asInt64())));
+ break;
+ case TYPE_BOOL:
+ fl.push_back(List::ValuePtr(new IntegerValue(subval.asBool() ? 1 : 0)));
+ break;
+ case TYPE_FLOAT:
+ fl.push_back(List::ValuePtr(new FloatValue(subval.asFloat())));
+ break;
+ case TYPE_DOUBLE:
+ fl.push_back(List::ValuePtr(new DoubleValue(subval.asDouble())));
+ break;
+ case TYPE_INT8:
+ case TYPE_INT16:
+ case TYPE_INT32:
+ fl.push_back(List::ValuePtr(new IntegerValue(subval.asInt())));
+ break;
+ case TYPE_MAP:
+ {
+ FieldTable subFt;
+ subval.impl->mapToFieldTable(subFt);
+ fl.push_back(List::ValuePtr(new FieldTableValue(subFt)));
+
+ } break;
+ case TYPE_LIST:
+ {
+ List subList;
+ subval.impl->listToFramingList(subList);
+ fl.push_back(List::ValuePtr(new ListValue(subList)));
+ } break;
+
+ case TYPE_ARRAY:
+ case TYPE_OBJECT:
+ case TYPE_UUID:
+ case TYPE_REF:
+ default:
+ break;
+ }
+ }
+ }
+
+
+
void ValueImpl::encode(Buffer& buf) const
{
FieldTable ft;
+ List fl;
switch (typecode) {
case TYPE_UINT8 : buf.putOctet((uint8_t) value.u32); break;
@@ -222,6 +362,10 @@ void ValueImpl::encode(Buffer& buf) const
ft.encode(buf);
break;
case TYPE_LIST:
+ listToFramingList(fl);
+ fl.encode(buf);
+ break;
+
case TYPE_ARRAY:
case TYPE_OBJECT:
default:
@@ -280,19 +424,6 @@ const char* ValueImpl::key(uint32_t idx) const
return iter->first.c_str();
}
-Value* ValueImpl::listItem(uint32_t)
-{
- return 0;
-}
-
-void ValueImpl::appendToList(Value*)
-{
-}
-
-void ValueImpl::deleteListItem(uint32_t)
-{
-}
-
Value* ValueImpl::arrayItem(uint32_t)
{
return 0;
diff --git a/qpid/cpp/src/qmf/engine/ValueImpl.h b/qpid/cpp/src/qmf/engine/ValueImpl.h
index 84b0e768e6..3b535834fd 100644
--- a/qpid/cpp/src/qmf/engine/ValueImpl.h
+++ b/qpid/cpp/src/qmf/engine/ValueImpl.h
@@ -33,6 +33,7 @@
namespace qpid {
namespace framing {
class FieldTable;
+ class List;
}
}
@@ -138,13 +139,14 @@ namespace engine {
bool isList() const { return typecode == TYPE_LIST; }
uint32_t listItemCount() const { return vectorVal.size(); }
- Value* listItem(uint32_t idx);
- void appendToList(Value* val);
- void deleteListItem(uint32_t idx);
+ Value* listItem(uint32_t idx) { return idx < listItemCount() ? &vectorVal[idx] : 0; }
+ const Value* listItem(uint32_t idx) const { return idx < listItemCount() ? &vectorVal[idx] : 0; }
+ void appendToList(Value* val) { vectorVal.push_back(*val); }
+ void deleteListItem(uint32_t idx) { if (idx < listItemCount()) vectorVal.erase(vectorVal.begin()+idx); }
bool isArray() const { return typecode == TYPE_ARRAY; }
Typecode arrayType() const { return arrayTypecode; }
- uint32_t arrayItemCount() const { return vectorVal.size(); }
+ uint32_t arrayItemCount() const { return 0; }
Value* arrayItem(uint32_t idx);
void appendToArray(Value* val);
void deleteArrayItem(uint32_t idx);
@@ -152,6 +154,9 @@ namespace engine {
private:
void mapToFieldTable(qpid::framing::FieldTable& ft) const;
void initMap(const qpid::framing::FieldTable& ft);
+
+ void listToFramingList(qpid::framing::List& fl) const;
+ void initList(const qpid::framing::List& fl);
};
}
}
diff --git a/qpid/extras/qmf/src/py/qmf/console.py b/qpid/extras/qmf/src/py/qmf/console.py
index b663116f40..7bda233b9a 100644
--- a/qpid/extras/qmf/src/py/qmf/console.py
+++ b/qpid/extras/qmf/src/py/qmf/console.py
@@ -985,15 +985,7 @@ class Session:
data = Object(self, broker, schema, codec, True, True, False)
else:
data = self._decodeValue(codec, inner_type_code, broker)
- elif typecode == 21: # List
- #taken from codec10.read_list
- sc = Codec(codec.read_vbin32())
- count = sc.read_uint32()
- data = []
- while count > 0:
- type = sc.read_uint8()
- data.append(self._decodeValue(sc,type,broker))
- count -= 1
+ elif typecode == 21: data = codec.read_list() # List
elif typecode == 22: #Array
#taken from codec10.read_array
sc = Codec(codec.read_vbin32())
@@ -1028,14 +1020,7 @@ class Session:
elif typecode == 19: codec.write_int64 (int(value)) # S64
elif typecode == 20: value._encodeUnmanaged(codec) # OBJECT
elif typecode == 15: codec.write_map (value) # FTABLE
- elif typecode == 21: # List
- sc = Codec()
- self._encodeValue(sc, len(value), 3)
- for o in value:
- ltype=self.encoding(o)
- self._encodeValue(sc,ltype,1)
- self._encodeValue(sc, o, ltype)
- codec.write_vbin32(sc.encoded)
+ elif typecode == 21: codec.write_list (value) # List
elif typecode == 22: # Array
sc = Codec()
self._encodeValue(sc, len(value), 3)