diff options
author | Rajith Muditha Attapattu <rajith@apache.org> | 2011-05-27 15:44:23 +0000 |
---|---|---|
committer | Rajith Muditha Attapattu <rajith@apache.org> | 2011-05-27 15:44:23 +0000 |
commit | 66765100f4257159622cefe57bed50125a5ad017 (patch) | |
tree | a88ee23bb194eb91f0ebb2d9b23ff423e3ea8e37 /qpid/cpp/src/qmf/engine/ValueImpl.cpp | |
parent | 1aeaa7b16e5ce54f10c901d75c4d40f9f88b9db6 (diff) | |
parent | 88b98b2f4152ef59a671fad55a0d08338b6b78ca (diff) | |
download | qpid-python-66765100f4257159622cefe57bed50125a5ad017.tar.gz |
Creating a branch for experimenting with some ideas for JMS client.rajith_jms_client
git-svn-id: https://svn.apache.org/repos/asf/qpid/branches/rajith_jms_client@1128369 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'qpid/cpp/src/qmf/engine/ValueImpl.cpp')
-rw-r--r-- | qpid/cpp/src/qmf/engine/ValueImpl.cpp | 571 |
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); } + |