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/SchemaProperty.cpp | |
parent | 1aeaa7b16e5ce54f10c901d75c4d40f9f88b9db6 (diff) | |
parent | 88b98b2f4152ef59a671fad55a0d08338b6b78ca (diff) | |
download | qpid-python-rajith_jms_client.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/SchemaProperty.cpp')
-rw-r--r-- | qpid/cpp/src/qmf/SchemaProperty.cpp | 434 |
1 files changed, 434 insertions, 0 deletions
diff --git a/qpid/cpp/src/qmf/SchemaProperty.cpp b/qpid/cpp/src/qmf/SchemaProperty.cpp new file mode 100644 index 0000000000..106127261b --- /dev/null +++ b/qpid/cpp/src/qmf/SchemaProperty.cpp @@ -0,0 +1,434 @@ +/* + * + * 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/SchemaPropertyImpl.h" +#include "qmf/PrivateImplRef.h" +#include "qmf/exceptions.h" +#include "qmf/SchemaTypes.h" +#include "qmf/SchemaProperty.h" +#include "qmf/Hash.h" +#include "qpid/messaging/AddressParser.h" +#include <list> +#include <iostream> + +using namespace std; +using qpid::types::Variant; +using namespace qmf; + +typedef PrivateImplRef<SchemaProperty> PI; + +SchemaProperty::SchemaProperty(SchemaPropertyImpl* impl) { PI::ctor(*this, impl); } +SchemaProperty::SchemaProperty(const SchemaProperty& s) : qmf::Handle<SchemaPropertyImpl>() { PI::copy(*this, s); } +SchemaProperty::~SchemaProperty() { PI::dtor(*this); } +SchemaProperty& SchemaProperty::operator=(const SchemaProperty& s) { return PI::assign(*this, s); } + +SchemaProperty::SchemaProperty(const string& n, int t, const string& o) { PI::ctor(*this, new SchemaPropertyImpl(n, t, o)); } + +void SchemaProperty::setAccess(int a) { impl->setAccess(a); } +void SchemaProperty::setIndex(bool i) { impl->setIndex(i); } +void SchemaProperty::setOptional(bool o) { impl->setOptional(o); } +void SchemaProperty::setUnit(const string& u) { impl->setUnit(u); } +void SchemaProperty::setDesc(const string& d) { impl->setDesc(d); } +void SchemaProperty::setSubtype(const string& s) { impl->setSubtype(s); } +void SchemaProperty::setDirection(int d) { impl->setDirection(d); } + +const string& SchemaProperty::getName() const { return impl->getName(); } +int SchemaProperty::getType() const { return impl->getType(); } +int SchemaProperty::getAccess() const { return impl->getAccess(); } +bool SchemaProperty::isIndex() const { return impl->isIndex(); } +bool SchemaProperty::isOptional() const { return impl->isOptional(); } +const string& SchemaProperty::getUnit() const { return impl->getUnit(); } +const string& SchemaProperty::getDesc() const { return impl->getDesc(); } +const string& SchemaProperty::getSubtype() const { return impl->getSubtype(); } +int SchemaProperty::getDirection() const { return impl->getDirection(); } + +//======================================================================================== +// Impl Method Bodies +//======================================================================================== + +SchemaPropertyImpl::SchemaPropertyImpl(const string& n, int t, const string options) : + name(n), dataType(t), access(ACCESS_READ_ONLY), index(false), + optional(false), direction(DIR_IN) +{ + if (!options.empty()) { + qpid::messaging::AddressParser parser = qpid::messaging::AddressParser(options); + Variant::Map optMap; + Variant::Map::iterator iter; + + parser.parseMap(optMap); + + iter = optMap.find("access"); + if (iter != optMap.end()) { + const string& v(iter->second.asString()); + if (v == "RC") access = ACCESS_READ_CREATE; + else if (v == "RO") access = ACCESS_READ_ONLY; + else if (v == "RW") access = ACCESS_READ_WRITE; + else + throw QmfException("Invalid value for 'access' option. Expected RC, RO, or RW"); + optMap.erase(iter); + } + + iter = optMap.find("index"); + if (iter != optMap.end()) { + index = iter->second.asBool(); + optMap.erase(iter); + } + + iter = optMap.find("optional"); + if (iter != optMap.end()) { + optional = iter->second.asBool(); + optMap.erase(iter); + } + + iter = optMap.find("unit"); + if (iter != optMap.end()) { + unit = iter->second.asString(); + optMap.erase(iter); + } + + iter = optMap.find("desc"); + if (iter != optMap.end()) { + desc = iter->second.asString(); + optMap.erase(iter); + } + + iter = optMap.find("subtype"); + if (iter != optMap.end()) { + subtype = iter->second.asString(); + optMap.erase(iter); + } + + iter = optMap.find("dir"); + if (iter != optMap.end()) { + const string& v(iter->second.asString()); + if (v == "IN") direction = DIR_IN; + else if (v == "OUT") direction = DIR_OUT; + else if (v == "INOUT") direction = DIR_IN_OUT; + else + throw QmfException("Invalid value for 'dir' option. Expected IN, OUT, or INOUT"); + optMap.erase(iter); + } + + if (!optMap.empty()) + throw QmfException("Unexpected option: " + optMap.begin()->first); + } +} + + +SchemaPropertyImpl::SchemaPropertyImpl(const Variant::Map& map) : + access(ACCESS_READ_ONLY), index(false), optional(false), direction(DIR_IN) +{ + Variant::Map::const_iterator iter; + + iter = map.find("_name"); + if (iter == map.end()) + throw QmfException("SchemaProperty without a _name element"); + name = iter->second.asString(); + + iter = map.find("_type"); + if (iter == map.end()) + throw QmfException("SchemaProperty without a _type element"); + const string& ts(iter->second.asString()); + if (ts == "TYPE_VOID") dataType = SCHEMA_DATA_VOID; + else if (ts == "TYPE_BOOL") dataType = SCHEMA_DATA_BOOL; + else if (ts == "TYPE_INT") dataType = SCHEMA_DATA_INT; + else if (ts == "TYPE_FLOAT") dataType = SCHEMA_DATA_FLOAT; + else if (ts == "TYPE_STRING") dataType = SCHEMA_DATA_STRING; + else if (ts == "TYPE_MAP") dataType = SCHEMA_DATA_MAP; + else if (ts == "TYPE_LIST") dataType = SCHEMA_DATA_LIST; + else if (ts == "TYPE_UUID") dataType = SCHEMA_DATA_UUID; + else + throw QmfException("SchemaProperty with an invalid type code: " + ts); + + iter = map.find("_access"); + if (iter != map.end()) { + const string& as(iter->second.asString()); + if (as == "RO") access = ACCESS_READ_ONLY; + else if (as == "RC") access = ACCESS_READ_CREATE; + else if (as == "RW") access = ACCESS_READ_WRITE; + else + throw QmfException("SchemaProperty with an invalid access code: " + as); + } + + iter = map.find("_unit"); + if (iter != map.end()) + unit = iter->second.asString(); + + iter = map.find("_dir"); + if (iter != map.end()) { + const string& ds(iter->second.asString()); + if (ds == "I") direction = DIR_IN; + else if (ds == "O") direction = DIR_OUT; + else if (ds == "IO") direction = DIR_IN_OUT; + else + throw QmfException("SchemaProperty with an invalid direction code: " + ds); + } + + iter = map.find("_desc"); + if (iter != map.end()) + desc = iter->second.asString(); + + iter = map.find("_index"); + if (iter != map.end()) + index = iter->second.asBool(); + + iter = map.find("_subtype"); + if (iter != map.end()) + subtype = iter->second.asString(); +} + + +Variant::Map SchemaPropertyImpl::asMap() const +{ + Variant::Map map; + string ts; + + map["_name"] = name; + + switch (dataType) { + case SCHEMA_DATA_VOID: ts = "TYPE_VOID"; break; + case SCHEMA_DATA_BOOL: ts = "TYPE_BOOL"; break; + case SCHEMA_DATA_INT: ts = "TYPE_INT"; break; + case SCHEMA_DATA_FLOAT: ts = "TYPE_FLOAT"; break; + case SCHEMA_DATA_STRING: ts = "TYPE_STRING"; break; + case SCHEMA_DATA_MAP: ts = "TYPE_MAP"; break; + case SCHEMA_DATA_LIST: ts = "TYPE_LIST"; break; + case SCHEMA_DATA_UUID: ts = "TYPE_UUID"; break; + } + map["_type"] = ts; + + switch (access) { + case ACCESS_READ_ONLY: ts = "RO"; break; + case ACCESS_READ_CREATE: ts = "RC"; break; + case ACCESS_READ_WRITE: ts = "RW"; break; + } + map["_access"] = ts; + + if (!unit.empty()) + map["_unit"] = unit; + + switch (direction) { + case DIR_IN: ts = "I"; break; + case DIR_OUT: ts = "O"; break; + case DIR_IN_OUT: ts = "IO"; break; + } + map["_dir"] = ts; + + if (!desc.empty()) + map["_desc"] = desc; + + if (index) + map["_index"] = true; + + if (!subtype.empty()) + map["_subtype"] = subtype; + + return map; +} + + +SchemaPropertyImpl::SchemaPropertyImpl(qpid::management::Buffer& buffer) : + access(ACCESS_READ_ONLY), index(false), optional(false), direction(DIR_IN) +{ + Variant::Map::const_iterator iter; + Variant::Map pmap; + + buffer.getMap(pmap); + iter = pmap.find("name"); + if (iter == pmap.end()) + throw QmfException("Received V1 Schema property without a name"); + name = iter->second.asString(); + + iter = pmap.find("type"); + if (iter == pmap.end()) + throw QmfException("Received V1 Schema property without a type"); + fromV1TypeCode(iter->second.asInt8()); + + iter = pmap.find("unit"); + if (iter != pmap.end()) + unit = iter->second.asString(); + + iter = pmap.find("desc"); + if (iter != pmap.end()) + desc = iter->second.asString(); + + iter = pmap.find("access"); + if (iter != pmap.end()) { + int8_t val = iter->second.asInt8(); + if (val < 1 || val > 3) + throw QmfException("Received V1 Schema property with invalid 'access' code"); + access = val; + } + + iter = pmap.find("index"); + if (iter != pmap.end()) + index = iter->second.asInt64() != 0; + + iter = pmap.find("optional"); + if (iter != pmap.end()) + optional = iter->second.asInt64() != 0; + + iter = pmap.find("dir"); + if (iter != pmap.end()) { + string dirStr(iter->second.asString()); + if (dirStr == "I") direction = DIR_IN; + else if (dirStr == "O") direction = DIR_OUT; + else if (dirStr == "IO") direction = DIR_IN_OUT; + else + throw QmfException("Received V1 Schema property with invalid 'dir' code"); + } +} + + +void SchemaPropertyImpl::updateHash(Hash& hash) const +{ + hash.update(name); + hash.update((uint8_t) dataType); + hash.update(subtype); + hash.update((uint8_t) access); + hash.update(index); + hash.update(optional); + hash.update(unit); + hash.update(desc); + hash.update((uint8_t) direction); +} + + +void SchemaPropertyImpl::encodeV1(qpid::management::Buffer& buffer, bool isArg, bool isMethodArg) const +{ + Variant::Map pmap; + + pmap["name"] = name; + pmap["type"] = v1TypeCode(); + if (!unit.empty()) + pmap["unit"] = unit; + if (!desc.empty()) + pmap["desc"] = desc; + if (!isArg) { + pmap["access"] = access; + pmap["index"] = index ? 1 : 0; + pmap["optional"] = optional ? 1 : 0; + } else { + if (isMethodArg) { + string dirStr; + switch (direction) { + case DIR_IN : dirStr = "I"; break; + case DIR_OUT : dirStr = "O"; break; + case DIR_IN_OUT : dirStr = "IO"; break; + } + pmap["dir"] = dirStr; + } + } + + buffer.putMap(pmap); +} + + +uint8_t SchemaPropertyImpl::v1TypeCode() const +{ + switch (dataType) { + case SCHEMA_DATA_VOID: return 1; + case SCHEMA_DATA_BOOL: return 11; + case SCHEMA_DATA_INT: + if (subtype == "timestamp") return 8; + if (subtype == "duration") return 9; + return 19; + case SCHEMA_DATA_FLOAT: return 13; + case SCHEMA_DATA_STRING: return 7; + case SCHEMA_DATA_LIST: return 21; + case SCHEMA_DATA_UUID: return 14; + case SCHEMA_DATA_MAP: + if (subtype == "reference") return 10; + if (subtype == "data") return 20; + return 15; + } + + return 1; +} + +void SchemaPropertyImpl::fromV1TypeCode(int8_t code) +{ + switch (code) { + case 1: // U8 + case 2: // U16 + case 3: // U32 + case 4: // U64 + dataType = SCHEMA_DATA_INT; + break; + case 6: // SSTR + case 7: // LSTR + dataType = SCHEMA_DATA_STRING; + break; + case 8: // ABSTIME + dataType = SCHEMA_DATA_INT; + subtype = "timestamp"; + break; + case 9: // DELTATIME + dataType = SCHEMA_DATA_INT; + subtype = "duration"; + break; + case 10: // REF + dataType = SCHEMA_DATA_MAP; + subtype = "reference"; + break; + case 11: // BOOL + dataType = SCHEMA_DATA_BOOL; + break; + case 12: // FLOAT + case 13: // DOUBLE + dataType = SCHEMA_DATA_FLOAT; + break; + case 14: // UUID + dataType = SCHEMA_DATA_UUID; + break; + case 15: // FTABLE + dataType = SCHEMA_DATA_MAP; + break; + case 16: // S8 + case 17: // S16 + case 18: // S32 + case 19: // S64 + dataType = SCHEMA_DATA_INT; + break; + case 20: // OBJECT + dataType = SCHEMA_DATA_MAP; + subtype = "data"; + break; + case 21: // LIST + case 22: // ARRAY + dataType = SCHEMA_DATA_LIST; + break; + default: + throw QmfException("Received V1 schema with an unknown data type"); + } +} + + +SchemaPropertyImpl& SchemaPropertyImplAccess::get(SchemaProperty& item) +{ + return *item.impl; +} + + +const SchemaPropertyImpl& SchemaPropertyImplAccess::get(const SchemaProperty& item) +{ + return *item.impl; +} |