| /* |
| * 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/ObjectIdImpl.h" |
| #include <stdlib.h> |
| #include <sstream> |
| |
| using namespace std; |
| using namespace qmf::engine; |
| using qpid::framing::Buffer; |
| |
| void AgentAttachment::setBanks(uint32_t broker, uint32_t agent) |
| { |
| first = |
| ((uint64_t) (broker & 0x000fffff)) << 28 | |
| ((uint64_t) (agent & 0x0fffffff)); |
| } |
| |
| ObjectIdImpl::ObjectIdImpl(Buffer& buffer) : agent(0) |
| { |
| decode(buffer); |
| } |
| |
| ObjectIdImpl::ObjectIdImpl(AgentAttachment* a, uint8_t flags, uint16_t seq, uint64_t object) : agent(a) |
| { |
| first = |
| ((uint64_t) (flags & 0x0f)) << 60 | |
| ((uint64_t) (seq & 0x0fff)) << 48; |
| second = object; |
| } |
| |
| ObjectId* ObjectIdImpl::factory(Buffer& buffer) |
| { |
| ObjectIdImpl* impl(new ObjectIdImpl(buffer)); |
| return new ObjectId(impl); |
| } |
| |
| ObjectId* ObjectIdImpl::factory(AgentAttachment* agent, uint8_t flags, uint16_t seq, uint64_t object) |
| { |
| ObjectIdImpl* impl(new ObjectIdImpl(agent, flags, seq, object)); |
| return new ObjectId(impl); |
| } |
| |
| void ObjectIdImpl::decode(Buffer& buffer) |
| { |
| first = buffer.getLongLong(); |
| second = buffer.getLongLong(); |
| } |
| |
| void ObjectIdImpl::encode(Buffer& buffer) const |
| { |
| if (agent == 0) |
| buffer.putLongLong(first); |
| else |
| buffer.putLongLong(first | agent->first); |
| buffer.putLongLong(second); |
| } |
| |
| void ObjectIdImpl::fromString(const std::string& repr) |
| { |
| #define FIELDS 5 |
| #if defined (_WIN32) && !defined (atoll) |
| # define atoll(X) _atoi64(X) |
| #endif |
| |
| std::string copy(repr.c_str()); |
| char* cText; |
| char* field[FIELDS]; |
| bool atFieldStart = true; |
| int idx = 0; |
| |
| cText = const_cast<char*>(copy.c_str()); |
| for (char* cursor = cText; *cursor; cursor++) { |
| if (atFieldStart) { |
| if (idx >= FIELDS) |
| return; // TODO error |
| field[idx++] = cursor; |
| atFieldStart = false; |
| } else { |
| if (*cursor == '-') { |
| *cursor = '\0'; |
| atFieldStart = true; |
| } |
| } |
| } |
| |
| if (idx != FIELDS) |
| return; // TODO error |
| |
| first = (atoll(field[0]) << 60) + |
| (atoll(field[1]) << 48) + |
| (atoll(field[2]) << 28) + |
| atoll(field[3]); |
| second = atoll(field[4]); |
| agent = 0; |
| } |
| |
| const string& ObjectIdImpl::asString() const |
| { |
| stringstream val; |
| |
| val << (int) getFlags() << "-" << getSequence() << "-" << getBrokerBank() << "-" << |
| getAgentBank() << "-" << getObjectNum(); |
| repr = val.str(); |
| return repr; |
| } |
| |
| #define ACTUAL_FIRST (agent == 0 ? first : first | agent->first) |
| #define ACTUAL_OTHER (other.agent == 0 ? other.first : other.first | other.agent->first) |
| |
| uint8_t ObjectIdImpl::getFlags() const |
| { |
| return (ACTUAL_FIRST & 0xF000000000000000LL) >> 60; |
| } |
| |
| uint16_t ObjectIdImpl::getSequence() const |
| { |
| return (ACTUAL_FIRST & 0x0FFF000000000000LL) >> 48; |
| } |
| |
| uint32_t ObjectIdImpl::getBrokerBank() const |
| { |
| return (ACTUAL_FIRST & 0x0000FFFFF0000000LL) >> 28; |
| } |
| |
| uint32_t ObjectIdImpl::getAgentBank() const |
| { |
| return ACTUAL_FIRST & 0x000000000FFFFFFFLL; |
| } |
| |
| uint64_t ObjectIdImpl::getObjectNum() const |
| { |
| return second; |
| } |
| |
| uint32_t ObjectIdImpl::getObjectNumHi() const |
| { |
| return (uint32_t) (second >> 32); |
| } |
| |
| uint32_t ObjectIdImpl::getObjectNumLo() const |
| { |
| return (uint32_t) (second & 0x00000000FFFFFFFFLL); |
| } |
| |
| bool ObjectIdImpl::operator==(const ObjectIdImpl& other) const |
| { |
| return ACTUAL_FIRST == ACTUAL_OTHER && second == other.second; |
| } |
| |
| bool ObjectIdImpl::operator<(const ObjectIdImpl& other) const |
| { |
| return (ACTUAL_FIRST < ACTUAL_OTHER) || ((ACTUAL_FIRST == ACTUAL_OTHER) && (second < other.second)); |
| } |
| |
| bool ObjectIdImpl::operator>(const ObjectIdImpl& other) const |
| { |
| return (ACTUAL_FIRST > ACTUAL_OTHER) || ((ACTUAL_FIRST == ACTUAL_OTHER) && (second > other.second)); |
| } |
| |
| |
| //================================================================== |
| // Wrappers |
| //================================================================== |
| |
| ObjectId::ObjectId() : impl(new ObjectIdImpl()) {} |
| ObjectId::ObjectId(const ObjectId& from) : impl(new ObjectIdImpl(*(from.impl))) {} |
| ObjectId::ObjectId(ObjectIdImpl* i) : impl(i) {} |
| ObjectId::~ObjectId() { delete impl; } |
| uint64_t ObjectId::getObjectNum() const { return impl->getObjectNum(); } |
| uint32_t ObjectId::getObjectNumHi() const { return impl->getObjectNumHi(); } |
| uint32_t ObjectId::getObjectNumLo() const { return impl->getObjectNumLo(); } |
| bool ObjectId::isDurable() const { return impl->isDurable(); } |
| const char* ObjectId::str() const { return impl->asString().c_str(); } |
| uint8_t ObjectId::getFlags() const { return impl->getFlags(); } |
| uint16_t ObjectId::getSequence() const { return impl->getSequence(); } |
| uint32_t ObjectId::getBrokerBank() const { return impl->getBrokerBank(); } |
| uint32_t ObjectId::getAgentBank() const { return impl->getAgentBank(); } |
| bool ObjectId::operator==(const ObjectId& other) const { return *impl == *other.impl; } |
| bool ObjectId::operator<(const ObjectId& other) const { return *impl < *other.impl; } |
| bool ObjectId::operator>(const ObjectId& other) const { return *impl > *other.impl; } |
| bool ObjectId::operator<=(const ObjectId& other) const { return !(*impl > *other.impl); } |
| bool ObjectId::operator>=(const ObjectId& other) const { return !(*impl < *other.impl); } |
| ObjectId& ObjectId::operator=(const ObjectId& other) { |
| ObjectIdImpl *old; |
| if (this != &other) { |
| old = impl; |
| impl = new ObjectIdImpl(*(other.impl)); |
| if (old) |
| delete old; |
| } |
| return *this; |
| } |
| |