diff options
Diffstat (limited to 'cpp/src/qpid/framing/FieldValue.h')
-rw-r--r-- | cpp/src/qpid/framing/FieldValue.h | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/cpp/src/qpid/framing/FieldValue.h b/cpp/src/qpid/framing/FieldValue.h new file mode 100644 index 0000000000..b26021d6fa --- /dev/null +++ b/cpp/src/qpid/framing/FieldValue.h @@ -0,0 +1,177 @@ +#ifndef _framing_FieldValue_h +#define _framing_FieldValue_h +/* + * + * 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 "Buffer.h" +#include "amqp_types.h" + +#include <iostream> +#include <memory> +#include <vector> + +namespace qpid { +namespace framing { + +/** + * Value that can appear in an AMQP field table + * + * \ingroup clientapi + */ +class FieldValue { + public: + /* + * Abstract type for content of different types + */ + class Data { + public: + virtual ~Data() {}; + virtual uint32_t size() const = 0; + virtual void encode(Buffer& buffer) = 0; + virtual void decode(Buffer& buffer) = 0; + virtual bool operator==(const Data&) const = 0; + + virtual bool convertsToInt() const { return false; } + virtual bool convertsToString() const { return false; } + virtual int64_t getInt() const { return 0; } + virtual std::string getString() const { return ""; } + + virtual void print(std::ostream& out) const = 0; + }; + + FieldValue(): data(0) {}; + // Default assignment operator is fine + uint32_t size() const { return 1 + data->size(); }; + bool empty() const { return data.get() == 0; } + void encode(Buffer& buffer); + void decode(Buffer& buffer); + bool operator==(const FieldValue&) const; + bool operator!=(const FieldValue& v) const { return !(*this == v); } + void print(std::ostream& out) const { out << "(0x" << std::hex << int(typeOctet) << ")"; data->print(out); } + + template <typename T> bool convertsTo() const { return false; } + template <typename T> T get() const; + + protected: + FieldValue(uint8_t t, Data* d): typeOctet(t), data(d) {} + + private: + uint8_t typeOctet; + std::auto_ptr<Data> data; +}; + +inline std::ostream& operator<<(std::ostream& out, const FieldValue& v) { + v.print(out); + return out; +} + +template <int width> +class FixedWidthValue : public FieldValue::Data { + uint8_t octets[width]; + + public: + FixedWidthValue() {} + FixedWidthValue(const uint8_t (&data)[width]) : octets(data) {} + FixedWidthValue(uint64_t v); + uint32_t size() const { return width; } + void encode(Buffer& buffer) { buffer.putRawData(octets, width); } + void decode(Buffer& buffer) { buffer.getRawData(octets, width); } + bool operator==(const Data& d) const { + const FixedWidthValue<width>* rhs = dynamic_cast< const FixedWidthValue<width>* >(&d); + if (rhs == 0) return false; + else return std::equal(&octets[0], &octets[width], &rhs->octets[0]); + } + + bool convertsToInt() const { return false; } + int64_t getInt() const { return 0; } + + void print(std::ostream& o) const { o << "F" << width << ":"; }; +}; + +template <> +class FixedWidthValue<0> : public FieldValue::Data { + public: + // Implicit default constructor is fine + uint32_t size() const { return 0; } + void encode(Buffer&) {}; + void decode(Buffer&) {}; + bool operator==(const Data& d) const { + const FixedWidthValue<0>* rhs = dynamic_cast< const FixedWidthValue<0>* >(&d); + return rhs != 0; + } + void print(std::ostream& o) const { o << "F0"; }; +}; + +template <int lenwidth> +class VariableWidthValue : public FieldValue::Data { + std::vector<uint8_t> octets; + + public: + VariableWidthValue() {} + VariableWidthValue(const std::vector<uint8_t>& data) : octets(data) {} + VariableWidthValue(const uint8_t* start, const uint8_t* end) : octets(start, end) {} + uint32_t size() const { return lenwidth + octets.size(); } + void encode(Buffer& buffer) { + buffer.putUInt<lenwidth>(octets.size()); + buffer.putRawData(&octets[0], octets.size()); + }; + void decode(Buffer& buffer) { + uint32_t len = buffer.getUInt<lenwidth>(); + octets.resize(len); + buffer.getRawData(&octets[0], len); + } + bool operator==(const Data& d) const { + const VariableWidthValue<lenwidth>* rhs = dynamic_cast< const VariableWidthValue<lenwidth>* >(&d); + if (rhs == 0) return false; + else return octets==rhs->octets; + } + void print(std::ostream& o) const { o << "V" << lenwidth << ":" << octets.size() << ":"; }; +}; + +/* + * Basic string value encodes as iso-8859-15 with 32 bit length + */ +class StringValue : public FieldValue { + public: + StringValue(const std::string& v); +}; + +/* + * Basic integer value encodes as signed 32 bit + */ +class IntegerValue : public FieldValue { + public: + IntegerValue(int v); +}; + +class TimeValue : public FieldValue { + public: + TimeValue(uint64_t v); +}; + +class FieldTableValue : public FieldValue { + public: + FieldTableValue(const FieldTable&); +}; + +}} // qpid::framing + +#endif |