/usr/share/cruisecontrol-bin-2.6.1/projects/qpid-trunk/cpp/src/qpid/framing/FieldValue.h

00001 #ifndef _framing_FieldValue_h
00002 #define _framing_FieldValue_h
00003 /*
00004  *
00005  * Licensed to the Apache Software Foundation (ASF) under one
00006  * or more contributor license agreements.  See the NOTICE file
00007  * distributed with this work for additional information
00008  * regarding copyright ownership.  The ASF licenses this file
00009  * to you under the Apache License, Version 2.0 (the
00010  * "License"); you may not use this file except in compliance
00011  * with the License.  You may obtain a copy of the License at
00012  * 
00013  *   http://www.apache.org/licenses/LICENSE-2.0
00014  * 
00015  * Unless required by applicable law or agreed to in writing,
00016  * software distributed under the License is distributed on an
00017  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
00018  * KIND, either express or implied.  See the License for the
00019  * specific language governing permissions and limitations
00020  * under the License.
00021  *
00022  */
00023 
00024 #include "qpid/Exception.h"
00025 #include "Buffer.h"
00026 #include "amqp_types.h"
00027 
00028 #include "assert.h"
00029 
00030 #include <iostream>
00031 #include <memory>
00032 #include <vector>
00033 
00034 namespace qpid {
00035 namespace framing {
00036 
00042 class FieldValueException : public qpid::Exception {};
00043 
00049 struct InvalidConversionException : public FieldValueException {
00050     InvalidConversionException() {}
00051 };
00052 
00058 class FieldValue {
00059   public:
00060     /*
00061      * Abstract type for content of different types
00062      */
00063     class Data {
00064       public:
00065         virtual ~Data() {};
00066         virtual uint32_t size() const = 0;        
00067         virtual void encode(Buffer& buffer) = 0;
00068         virtual void decode(Buffer& buffer) = 0;
00069         virtual bool operator==(const Data&) const = 0;
00070 
00071         virtual bool convertsToInt() const { return false; }
00072         virtual bool convertsToString() const { return false; }
00073         virtual int64_t getInt() const { throw InvalidConversionException();}
00074         virtual std::string getString() const { throw InvalidConversionException(); }
00075 
00076         virtual void print(std::ostream& out) const = 0;
00077     };
00078 
00079     FieldValue(): data(0) {};
00080     // Default assignment operator is fine
00081     void setType(uint8_t type);
00082     uint8_t getType();
00083     Data& getData() { return *data; }
00084     uint32_t size() const { return 1 + data->size(); };
00085     bool empty() const { return data.get() == 0; } 
00086     void encode(Buffer& buffer);
00087     void decode(Buffer& buffer);
00088     bool operator==(const FieldValue&) const;
00089     bool operator!=(const FieldValue& v) const { return !(*this == v); }
00090     void print(std::ostream& out) const { out << "(0x" << std::hex << int(typeOctet) << ")"; data->print(out); }
00091     
00092     template <typename T> bool convertsTo() const { return false; }
00093     template <typename T> T get() const { throw InvalidConversionException(); }
00094 
00095   protected:
00096     FieldValue(uint8_t t, Data* d): typeOctet(t), data(d) {}
00097 
00098   private:
00099     uint8_t typeOctet;
00100     std::auto_ptr<Data> data; 
00101 };
00102 
00103 template <>
00104 inline bool FieldValue::convertsTo<int>() const { return data->convertsToInt(); }
00105 
00106 template <>
00107 inline bool FieldValue::convertsTo<std::string>() const { return data->convertsToString(); }
00108 
00109 template <>
00110 inline int FieldValue::get<int>() const { return data->getInt(); }
00111 
00112 template <>
00113 inline std::string FieldValue::get<std::string>() const { return data->getString(); }
00114 
00115 inline std::ostream& operator<<(std::ostream& out, const FieldValue& v) {
00116     v.print(out);
00117     return out;
00118 }
00119 
00120 template <int width>
00121 class FixedWidthValue : public FieldValue::Data {
00122     uint8_t octets[width];
00123     
00124   public:
00125     FixedWidthValue() {}
00126     FixedWidthValue(const uint8_t (&data)[width]) : octets(data) {}
00127     FixedWidthValue(uint64_t v)
00128     {
00129         for (int i = width; i > 0; --i) {
00130             octets[i-1] = (uint8_t) (0xFF & v); v >>= 8;
00131         }
00132         octets[0] = (uint8_t) (0xFF & v);
00133     }
00134 
00135     uint32_t size() const { return width; }
00136     void encode(Buffer& buffer) { buffer.putRawData(octets, width); }
00137     void decode(Buffer& buffer) { buffer.getRawData(octets, width); }
00138     bool operator==(const Data& d) const {
00139         const FixedWidthValue<width>* rhs = dynamic_cast< const FixedWidthValue<width>* >(&d);
00140         if (rhs == 0) return false;
00141         else return std::equal(&octets[0], &octets[width], &rhs->octets[0]); 
00142     }
00143 
00144     bool convertsToInt() const { return true; }
00145     int64_t getInt() const
00146     {
00147         int64_t v = 0;
00148         for (int i = 0; i < width-1; ++i) {
00149             v |= octets[i]; v <<= 8;
00150         }
00151         v |= octets[width-1];
00152         return v;
00153     }
00154 
00155     void print(std::ostream& o) const { o << "F" << width << ":"; };
00156 };
00157 
00158 template <>
00159 class FixedWidthValue<0> : public FieldValue::Data {
00160   public:
00161     // Implicit default constructor is fine
00162     uint32_t size() const { return 0; }
00163     void encode(Buffer&) {};
00164     void decode(Buffer&) {};
00165     bool operator==(const Data& d) const {
00166         const FixedWidthValue<0>* rhs = dynamic_cast< const FixedWidthValue<0>* >(&d);
00167         return rhs != 0;
00168     }
00169     void print(std::ostream& o) const { o << "F0"; };
00170 };
00171 
00172 template <int lenwidth>
00173 class VariableWidthValue : public FieldValue::Data {
00174     std::vector<uint8_t> octets;
00175 
00176   public:
00177     VariableWidthValue() {}
00178     VariableWidthValue(const std::vector<uint8_t>& data) : octets(data) {}
00179     VariableWidthValue(const uint8_t* start, const uint8_t* end) : octets(start, end) {}
00180     uint32_t size() const { return lenwidth + octets.size(); } 
00181     void encode(Buffer& buffer) {
00182         buffer.putUInt<lenwidth>(octets.size());
00183         buffer.putRawData(&octets[0], octets.size());
00184     };
00185     void decode(Buffer& buffer) {
00186         uint32_t len = buffer.getUInt<lenwidth>();
00187         octets.resize(len);
00188         buffer.getRawData(&octets[0], len);
00189     }
00190     bool operator==(const Data& d) const {
00191         const VariableWidthValue<lenwidth>* rhs = dynamic_cast< const VariableWidthValue<lenwidth>* >(&d);
00192         if (rhs == 0) return false;
00193         else return octets==rhs->octets; 
00194     }
00195     
00196     bool convertsToString() const { return true; }
00197     std::string getString() const { return std::string(octets.begin(), octets.end()); }
00198 
00199     void print(std::ostream& o) const { o << "V" << lenwidth << ":" << octets.size() << ":"; };
00200 };
00201 
00202 /*
00203  * Basic string value encodes as iso-8859-15 with 32 bit length
00204  */ 
00205 class StringValue : public FieldValue {
00206   public:
00207     StringValue(const std::string& v);
00208 };
00209 
00210 class Str16Value : public FieldValue {
00211   public:
00212     Str16Value(const std::string& v);
00213 };
00214 
00215 /*
00216  * Basic integer value encodes as signed 32 bit
00217  */
00218 class IntegerValue : public FieldValue {
00219   public:
00220     IntegerValue(int v);
00221 };
00222 
00223 class TimeValue : public FieldValue {
00224   public:
00225     TimeValue(uint64_t v);
00226 };
00227 
00228 class FieldTableValue : public FieldValue {
00229   public:
00230     FieldTableValue(const FieldTable&);
00231 };
00232 
00233 }} // qpid::framing
00234 
00235 #endif

Generated on Thu Apr 10 11:08:18 2008 for Qpid by  doxygen 1.4.7