summaryrefslogtreecommitdiff
path: root/qpid/cpp/src/qmf/engine/ValueImpl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'qpid/cpp/src/qmf/engine/ValueImpl.cpp')
-rw-r--r--qpid/cpp/src/qmf/engine/ValueImpl.cpp571
1 files changed, 571 insertions, 0 deletions
diff --git a/qpid/cpp/src/qmf/engine/ValueImpl.cpp b/qpid/cpp/src/qmf/engine/ValueImpl.cpp
new file mode 100644
index 0000000000..f9ebbf5028
--- /dev/null
+++ b/qpid/cpp/src/qmf/engine/ValueImpl.cpp
@@ -0,0 +1,571 @@
+/*
+ * 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.
+ */
+
+#include "qmf/engine/ValueImpl.h"
+#include <qpid/framing/FieldValue.h>
+#include <qpid/framing/FieldTable.h>
+#include <qpid/framing/List.h>
+#include <qpid/log/Statement.h>
+
+using namespace std;
+using namespace qmf::engine;
+//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;
+ case TYPE_UINT16 : value.u32 = (uint32_t) buf.getShort(); break;
+ case TYPE_UINT32 : value.u32 = (uint32_t) buf.getLong(); break;
+ case TYPE_UINT64 : value.u64 = buf.getLongLong(); break;
+ case TYPE_SSTR : buf.getShortString(stringVal); break;
+ case TYPE_LSTR : buf.getMediumString(stringVal); break;
+ case TYPE_ABSTIME : value.s64 = buf.getLongLong(); break;
+ case TYPE_DELTATIME : value.u64 = buf.getLongLong(); break;
+ case TYPE_BOOL : value.boolVal = (buf.getOctet() != 0); break;
+ case TYPE_FLOAT : value.floatVal = buf.getFloat(); break;
+ case TYPE_DOUBLE : value.doubleVal = buf.getDouble(); break;
+ case TYPE_INT8 : value.s32 = (int32_t) ((int8_t) buf.getOctet()); break;
+ case TYPE_INT16 : value.s32 = (int32_t) ((int16_t) buf.getShort()); break;
+ case TYPE_INT32 : value.s32 = (int32_t) buf.getLong(); break;
+ case TYPE_INT64 : value.s64 = buf.getLongLong(); break;
+ case TYPE_UUID : buf.getBin128(value.uuidVal); break;
+ case TYPE_REF:
+ first = buf.getLongLong();
+ second = buf.getLongLong();
+ refVal.impl->setValue(first, second);
+ break;
+
+ case TYPE_MAP:
+ ft.decode(buf);
+ initMap(ft);
+ break;
+
+ case TYPE_LIST:
+ fl.decode(buf);
+ initList(fl);
+ break;
+
+ case TYPE_ARRAY:
+ case TYPE_OBJECT:
+ default:
+ break;
+ }
+}
+
+ValueImpl::ValueImpl(Typecode t, Typecode at) : typecode(t), valid(false), arrayTypecode(at)
+{
+}
+
+ValueImpl::ValueImpl(Typecode t) : typecode(t)
+{
+ ::memset(&value, 0, sizeof(value));
+}
+
+Value* ValueImpl::factory(Typecode t, Buffer& b)
+{
+ ValueImpl* impl(new ValueImpl(t, b));
+ return new Value(impl);
+}
+
+Value* ValueImpl::factory(Typecode t)
+{
+ ValueImpl* impl(new ValueImpl(t));
+ return new Value(impl);
+}
+
+ValueImpl::~ValueImpl()
+{
+}
+
+void ValueImpl::initMap(const FieldTable& ft)
+{
+ for (FieldTable::ValueMap::const_iterator iter = ft.begin();
+ iter != ft.end(); iter++) {
+ const string& name(iter->first);
+ const FieldValue& fvalue(*iter->second);
+ uint8_t amqType = fvalue.getType();
+
+ if (amqType == 0x32) {
+ Value* subval(new Value(TYPE_UINT64));
+ subval->setUint64(fvalue.get<int64_t>());
+ insert(name.c_str(), 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;
+ }
+ insert(name.c_str(), subval);
+ } else if (amqType == 0x31) { // int64
+ Value* subval(new Value(TYPE_INT64));
+ subval->setInt64(fvalue.get<int64_t>());
+ insert(name.c_str(), subval);
+ } else if ((amqType & 0xCF) == 0x01) { // 0x01:int8, 0x11:int16, 0x21:int21
+ Value* subval(new Value(TYPE_INT32));
+ subval->setInt((int32_t)fvalue.get<int>());
+ insert(name.c_str(), subval);
+ } else if (amqType == 0x85 || amqType == 0x95) {
+ Value* subval(new Value(TYPE_LSTR));
+ subval->setString(fvalue.get<string>().c_str());
+ insert(name.c_str(), subval);
+ } else if (amqType == 0x23 || amqType == 0x33) {
+ Value* subval(new Value(TYPE_DOUBLE));
+ subval->setDouble(fvalue.get<double>());
+ insert(name.c_str(), subval);
+ } else if (amqType == 0xa8) {
+ FieldTable subFt;
+ bool valid = qpid::framing::getEncodedValue<FieldTable>(iter->second, subFt);
+ if (valid) {
+ Value* subval(new Value(TYPE_MAP));
+ 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);
+ }
+ } else if (amqType == 0x08) {
+ Value* subval(new Value(TYPE_BOOL));
+ subval->setBool(fvalue.get<int>() ? true : false);
+ insert(name.c_str(), subval);
+ } else {
+ QPID_LOG(error, "Unable to decode unsupported AMQP typecode=" << amqType << " map index=" << name);
+ }
+ }
+}
+
+void ValueImpl::mapToFieldTable(FieldTable& ft) const
+{
+ FieldTable subFt;
+
+ for (map<string, Value>::const_iterator iter = mapVal.begin();
+ iter != mapVal.end(); iter++) {
+ const string& name(iter->first);
+ const Value& subval(iter->second);
+
+ switch (subval.getType()) {
+ case TYPE_UINT8:
+ case TYPE_UINT16:
+ case TYPE_UINT32:
+ ft.setUInt64(name, (uint64_t) subval.asUint());
+ break;
+ case TYPE_UINT64:
+ case TYPE_DELTATIME:
+ ft.setUInt64(name, subval.asUint64());
+ break;
+ case TYPE_SSTR:
+ case TYPE_LSTR:
+ ft.setString(name, subval.asString());
+ break;
+ case TYPE_INT64:
+ case TYPE_ABSTIME:
+ ft.setInt64(name, subval.asInt64());
+ break;
+ case TYPE_BOOL:
+ ft.set(name, FieldTable::ValuePtr(new BoolValue(subval.asBool())));
+ break;
+ case TYPE_FLOAT:
+ ft.setFloat(name, subval.asFloat());
+ break;
+ case TYPE_DOUBLE:
+ ft.setDouble(name, subval.asDouble());
+ break;
+ case TYPE_INT8:
+ case TYPE_INT16:
+ case TYPE_INT32:
+ ft.setInt(name, subval.asInt());
+ break;
+ case TYPE_MAP:
+ subFt.clear();
+ subval.impl->mapToFieldTable(subFt);
+ 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:
+ case TYPE_REF:
+ default:
+ break;
+ }
+ }
+ }
+
+
+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; // uint8
+ case 0x12 : subval->setUint(fvalue.get<int>()); break; // uint16
+ case 0x22 : subval->setUint(fvalue.get<int>()); break; // uint32
+ }
+ appendToList(subval);
+ } else if (amqType == 0x31) { // int64
+ Value* subval(new Value(TYPE_INT64));
+ subval->setInt64(fvalue.get<int64_t>());
+ appendToList(subval);
+ } else if ((amqType & 0xCF) == 0x01) { // 0x01:int8, 0x11:int16, 0x21:int32
+ Value* subval(new Value(TYPE_INT32));
+ subval->setInt((int32_t)fvalue.get<int>());
+ 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);
+ }
+ } else if (amqType == 0x08) {
+ Value* subval(new Value(TYPE_BOOL));
+ subval->setBool(fvalue.get<int>() ? true : false);
+ appendToList(subval);
+ } else {
+ QPID_LOG(error, "Unable to decode unsupported AMQP typecode =" << amqType);
+ }
+ }
+}
+
+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 BoolValue(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;
+ case TYPE_UINT16 : buf.putShort((uint16_t) value.u32); break;
+ case TYPE_UINT32 : buf.putLong(value.u32); break;
+ case TYPE_UINT64 : buf.putLongLong(value.u64); break;
+ case TYPE_SSTR : buf.putShortString(stringVal); break;
+ case TYPE_LSTR : buf.putMediumString(stringVal); break;
+ case TYPE_ABSTIME : buf.putLongLong(value.s64); break;
+ case TYPE_DELTATIME : buf.putLongLong(value.u64); break;
+ case TYPE_BOOL : buf.putOctet(value.boolVal ? 1 : 0); break;
+ case TYPE_FLOAT : buf.putFloat(value.floatVal); break;
+ case TYPE_DOUBLE : buf.putDouble(value.doubleVal); break;
+ case TYPE_INT8 : buf.putOctet((uint8_t) value.s32); break;
+ case TYPE_INT16 : buf.putShort((uint16_t) value.s32); break;
+ case TYPE_INT32 : buf.putLong(value.s32); break;
+ case TYPE_INT64 : buf.putLongLong(value.s64); break;
+ case TYPE_UUID : buf.putBin128(value.uuidVal); break;
+ case TYPE_REF : refVal.impl->encode(buf); break;
+ case TYPE_MAP:
+ mapToFieldTable(ft);
+ ft.encode(buf);
+ break;
+ case TYPE_LIST:
+ listToFramingList(fl);
+ fl.encode(buf);
+ break;
+
+ case TYPE_ARRAY:
+ case TYPE_OBJECT:
+ default:
+ break;
+ }
+}
+
+uint32_t ValueImpl::encodedSize() const
+{
+ FieldTable ft;
+ List fl;
+
+ switch (typecode) {
+ case TYPE_UINT8 :
+ case TYPE_BOOL :
+ case TYPE_INT8 : return 1;
+
+ case TYPE_UINT16 :
+ case TYPE_INT16 : return 2;
+
+ case TYPE_UINT32 :
+ case TYPE_INT32 :
+ case TYPE_FLOAT : return 4;
+
+ case TYPE_UINT64 :
+ case TYPE_INT64 :
+ case TYPE_DOUBLE :
+ case TYPE_ABSTIME :
+ case TYPE_DELTATIME : return 8;
+
+ case TYPE_UUID :
+ case TYPE_REF : return 16;
+
+ case TYPE_SSTR : return 1 + stringVal.size();
+ case TYPE_LSTR : return 2 + stringVal.size();
+ case TYPE_MAP:
+ mapToFieldTable(ft);
+ return ft.encodedSize();
+
+ case TYPE_LIST:
+ listToFramingList(fl);
+ return fl.encodedSize();
+
+ case TYPE_ARRAY:
+ case TYPE_OBJECT:
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+bool ValueImpl::keyInMap(const char* key) const
+{
+ return typecode == TYPE_MAP && mapVal.count(key) > 0;
+}
+
+Value* ValueImpl::byKey(const char* key)
+{
+ if (keyInMap(key)) {
+ map<string, Value>::iterator iter = mapVal.find(key);
+ if (iter != mapVal.end())
+ return &iter->second;
+ }
+ return 0;
+}
+
+const Value* ValueImpl::byKey(const char* key) const
+{
+ if (keyInMap(key)) {
+ map<string, Value>::const_iterator iter = mapVal.find(key);
+ if (iter != mapVal.end())
+ return &iter->second;
+ }
+ return 0;
+}
+
+void ValueImpl::deleteKey(const char* key)
+{
+ mapVal.erase(key);
+}
+
+void ValueImpl::insert(const char* key, Value* val)
+{
+ pair<string, Value> entry(key, *val);
+ mapVal.insert(entry);
+}
+
+const char* ValueImpl::key(uint32_t idx) const
+{
+ map<string, Value>::const_iterator iter = mapVal.begin();
+ for (uint32_t i = 0; i < idx; i++) {
+ if (iter == mapVal.end())
+ break;
+ iter++;
+ }
+
+ if (iter == mapVal.end())
+ return 0;
+ else
+ return iter->first.c_str();
+}
+
+Value* ValueImpl::arrayItem(uint32_t)
+{
+ return 0;
+}
+
+void ValueImpl::appendToArray(Value*)
+{
+}
+
+void ValueImpl::deleteArrayItem(uint32_t)
+{
+}
+
+
+//==================================================================
+// Wrappers
+//==================================================================
+
+Value::Value(const Value& from) : impl(new ValueImpl(*(from.impl))) {}
+Value::Value(Typecode t, Typecode at) : impl(new ValueImpl(t, at)) {}
+Value::Value(ValueImpl* i) : impl(i) {}
+Value::~Value() { delete impl;}
+
+Typecode Value::getType() const { return impl->getType(); }
+bool Value::isNull() const { return impl->isNull(); }
+void Value::setNull() { impl->setNull(); }
+bool Value::isObjectId() const { return impl->isObjectId(); }
+const ObjectId& Value::asObjectId() const { return impl->asObjectId(); }
+void Value::setObjectId(const ObjectId& oid) { impl->setObjectId(oid); }
+bool Value::isUint() const { return impl->isUint(); }
+uint32_t Value::asUint() const { return impl->asUint(); }
+void Value::setUint(uint32_t val) { impl->setUint(val); }
+bool Value::isInt() const { return impl->isInt(); }
+int32_t Value::asInt() const { return impl->asInt(); }
+void Value::setInt(int32_t val) { impl->setInt(val); }
+bool Value::isUint64() const { return impl->isUint64(); }
+uint64_t Value::asUint64() const { return impl->asUint64(); }
+void Value::setUint64(uint64_t val) { impl->setUint64(val); }
+bool Value::isInt64() const { return impl->isInt64(); }
+int64_t Value::asInt64() const { return impl->asInt64(); }
+void Value::setInt64(int64_t val) { impl->setInt64(val); }
+bool Value::isString() const { return impl->isString(); }
+const char* Value::asString() const { return impl->asString(); }
+void Value::setString(const char* val) { impl->setString(val); }
+bool Value::isBool() const { return impl->isBool(); }
+bool Value::asBool() const { return impl->asBool(); }
+void Value::setBool(bool val) { impl->setBool(val); }
+bool Value::isFloat() const { return impl->isFloat(); }
+float Value::asFloat() const { return impl->asFloat(); }
+void Value::setFloat(float val) { impl->setFloat(val); }
+bool Value::isDouble() const { return impl->isDouble(); }
+double Value::asDouble() const { return impl->asDouble(); }
+void Value::setDouble(double val) { impl->setDouble(val); }
+bool Value::isUuid() const { return impl->isUuid(); }
+const uint8_t* Value::asUuid() const { return impl->asUuid(); }
+void Value::setUuid(const uint8_t* val) { impl->setUuid(val); }
+bool Value::isObject() const { return impl->isObject(); }
+const Object* Value::asObject() const { return impl->asObject(); }
+void Value::setObject(Object* val) { impl->setObject(val); }
+bool Value::isMap() const { return impl->isMap(); }
+bool Value::keyInMap(const char* key) const { return impl->keyInMap(key); }
+Value* Value::byKey(const char* key) { return impl->byKey(key); }
+const Value* Value::byKey(const char* key) const { return impl->byKey(key); }
+void Value::deleteKey(const char* key) { impl->deleteKey(key); }
+void Value::insert(const char* key, Value* val) { impl->insert(key, val); }
+uint32_t Value::keyCount() const { return impl->keyCount(); }
+const char* Value::key(uint32_t idx) const { return impl->key(idx); }
+bool Value::isList() const { return impl->isList(); }
+uint32_t Value::listItemCount() const { return impl->listItemCount(); }
+Value* Value::listItem(uint32_t idx) { return impl->listItem(idx); }
+void Value::appendToList(Value* val) { impl->appendToList(val); }
+void Value::deleteListItem(uint32_t idx) { impl->deleteListItem(idx); }
+bool Value::isArray() const { return impl->isArray(); }
+Typecode Value::arrayType() const { return impl->arrayType(); }
+uint32_t Value::arrayItemCount() const { return impl->arrayItemCount(); }
+Value* Value::arrayItem(uint32_t idx) { return impl->arrayItem(idx); }
+void Value::appendToArray(Value* val) { impl->appendToArray(val); }
+void Value::deleteArrayItem(uint32_t idx) { impl->deleteArrayItem(idx); }
+