You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by gs...@apache.org on 2008/09/19 14:56:39 UTC

svn commit: r697076 - in /incubator/qpid/trunk/qpid/cpp/src: qpid/framing/FieldTable.cpp qpid/framing/FieldTable.h qpid/framing/FieldValue.cpp qpid/framing/FieldValue.h tests/FieldTable.cpp

Author: gsim
Date: Fri Sep 19 05:56:38 2008
New Revision: 697076

URL: http://svn.apache.org/viewvc?rev=697076&view=rev
Log:
Added support for nested field tables & arrays within a field table.


Modified:
    incubator/qpid/trunk/qpid/cpp/src/qpid/framing/FieldTable.cpp
    incubator/qpid/trunk/qpid/cpp/src/qpid/framing/FieldTable.h
    incubator/qpid/trunk/qpid/cpp/src/qpid/framing/FieldValue.cpp
    incubator/qpid/trunk/qpid/cpp/src/qpid/framing/FieldValue.h
    incubator/qpid/trunk/qpid/cpp/src/tests/FieldTable.cpp

Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/framing/FieldTable.cpp
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/framing/FieldTable.cpp?rev=697076&r1=697075&r2=697076&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/framing/FieldTable.cpp (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/framing/FieldTable.cpp Fri Sep 19 05:56:38 2008
@@ -19,6 +19,7 @@
  *
  */
 #include "FieldTable.h"
+#include "Array.h"
 #include "Buffer.h"
 #include "FieldValue.h"
 #include "qpid/Exception.h"
@@ -77,9 +78,14 @@
     values[name] = ValuePtr(new TimeValue(value));
 }
 
-void FieldTable::setTable(const std::string& name, const FieldTable& value){
+void FieldTable::setTable(const std::string& name, const FieldTable& value)
+{
     values[name] = ValuePtr(new FieldTableValue(value));
 }
+void FieldTable::setArray(const std::string& name, const Array& value)
+{
+    values[name] = ValuePtr(new ArrayValue(value));
+}
 
 FieldTable::ValuePtr FieldTable::get(const std::string& name) const
 {
@@ -116,10 +122,23 @@
 //uint64_t FieldTable::getTimestamp(const std::string& name) const {
 //    return getValue<uint64_t>(name);
 //}
-//
-//void FieldTable::getTable(const std::string& name, FieldTable& value) const {
-//    value = getValue<FieldTable>(name);
-//}
+
+void FieldTable::getTable(const std::string& name, FieldTable& value) const {
+    FieldTable::ValuePtr vptr = get(name);
+    if (vptr) {
+        value = vptr->get<const FieldTable&>();
+    }
+}
+
+void FieldTable::getArray(const std::string& name, Array& value) const {
+    FieldTable::ValuePtr vptr = get(name);
+    if (vptr) {
+        const EncodedValue<Array>* ev = dynamic_cast< EncodedValue<Array>* >(&(vptr->getData()));    
+        if (ev != 0) {
+            value = ev->getValue(); 
+        }
+    }
+}
 
 void FieldTable::encode(Buffer& buffer) const{    
     buffer.putLong(size() - 4);

Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/framing/FieldTable.h
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/framing/FieldTable.h?rev=697076&r1=697075&r2=697076&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/framing/FieldTable.h (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/framing/FieldTable.h Fri Sep 19 05:56:38 2008
@@ -34,6 +34,7 @@
      */
 namespace framing {
 
+class Array;
 class FieldValue;
 class Buffer;
 
@@ -64,12 +65,14 @@
     void setInt(const std::string& name, int value);
     void setTimestamp(const std::string& name, uint64_t value);
     void setTable(const std::string& name, const FieldTable& value);
+    void setArray(const std::string& name, const Array& value);
     //void setDecimal(string& name, xxx& value);
 
     std::string getString(const std::string& name) const;
     int getInt(const std::string& name) const;
 //    uint64_t getTimestamp(const std::string& name) const;
-//    void getTable(const std::string& name, FieldTable& value) const;
+    void getTable(const std::string& name, FieldTable& value) const;
+    void getArray(const std::string& name, Array& value) const;
 //    //void getDecimal(string& name, xxx& value);
 //    //void erase(const std::string& name);
     

Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/framing/FieldValue.cpp
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/framing/FieldValue.cpp?rev=697076&r1=697075&r2=697076&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/framing/FieldValue.cpp (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/framing/FieldValue.cpp Fri Sep 19 05:56:38 2008
@@ -19,6 +19,7 @@
  *
  */
 #include "FieldValue.h"
+#include "Array.h"
 #include "Buffer.h"
 #include "qpid/framing/reply_exceptions.h"
 
@@ -33,53 +34,58 @@
 void FieldValue::setType(uint8_t type)
 {
     typeOctet = type;
-    
-    uint8_t lenType = typeOctet >> 4;
-    switch(lenType){
-      case 0:
-        data.reset(new FixedWidthValue<1>());
-        break;
-      case 1:
-        data.reset(new FixedWidthValue<2>());
-        break;
-      case 2:
-        data.reset(new FixedWidthValue<4>());
-        break;
-      case 3:
-        data.reset(new FixedWidthValue<8>());
-        break;
-      case 4:
-        data.reset(new FixedWidthValue<16>());
-        break;
-      case 5:
-        data.reset(new FixedWidthValue<32>());
-        break;
-      case 6:
-        data.reset(new FixedWidthValue<64>());
-        break;
-      case 7:
-        data.reset(new FixedWidthValue<128>());
-        break;
-      case 8:
-        data.reset(new VariableWidthValue<1>());
-        break;
-      case 9:
-        data.reset(new VariableWidthValue<2>());
-        break;
-      case 0xA:
-        data.reset(new VariableWidthValue<4>());
-        break;
-      case 0xC:
-        data.reset(new FixedWidthValue<5>());
-        break;
-      case 0xD:
-        data.reset(new FixedWidthValue<9>());
-        break;
-      case 0xF:
-        data.reset(new FixedWidthValue<0>());
-        break;
-      default:
-        throw IllegalArgumentException(QPID_MSG("Unknown field table value type: " << (int)typeOctet));
+    if (typeOctet == 0xA8) {
+        data.reset(new EncodedValue<FieldTable>());
+    } else if (typeOctet == 0xAA) {
+        data.reset(new EncodedValue<Array>());
+    } else {    
+        uint8_t lenType = typeOctet >> 4;
+        switch(lenType){
+          case 0:
+            data.reset(new FixedWidthValue<1>());
+            break;
+          case 1:
+            data.reset(new FixedWidthValue<2>());
+            break;
+          case 2:
+            data.reset(new FixedWidthValue<4>());
+            break;
+          case 3:
+            data.reset(new FixedWidthValue<8>());
+            break;
+          case 4:
+            data.reset(new FixedWidthValue<16>());
+            break;
+          case 5:
+            data.reset(new FixedWidthValue<32>());
+            break;
+          case 6:
+            data.reset(new FixedWidthValue<64>());
+            break;
+          case 7:
+            data.reset(new FixedWidthValue<128>());
+            break;
+          case 8:
+            data.reset(new VariableWidthValue<1>());
+            break;
+          case 9:
+            data.reset(new VariableWidthValue<2>());
+            break;
+          case 0xA:
+            data.reset(new VariableWidthValue<4>());
+            break;
+          case 0xC:
+            data.reset(new FixedWidthValue<5>());
+            break;
+          case 0xD:
+            data.reset(new FixedWidthValue<9>());
+            break;
+          case 0xF:
+            data.reset(new FixedWidthValue<0>());
+            break;
+          default:
+            throw IllegalArgumentException(QPID_MSG("Unknown field table value type: " << (int)typeOctet));
+        }
     }
 }
 
@@ -137,7 +143,11 @@
 {
 }
 
-FieldTableValue::FieldTableValue(const FieldTable&) : FieldValue()
+FieldTableValue::FieldTableValue(const FieldTable& f) : FieldValue(0xa8, new EncodedValue<FieldTable>(f))
+{
+}
+
+ArrayValue::ArrayValue(const Array& a) : FieldValue(0xaa, new EncodedValue<Array>(a))
 {
 }
 

Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/framing/FieldValue.h
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/framing/FieldValue.h?rev=697076&r1=697075&r2=697076&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/framing/FieldValue.h (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/framing/FieldValue.h Fri Sep 19 05:56:38 2008
@@ -22,8 +22,9 @@
  */
 
 #include "qpid/Exception.h"
-#include "Buffer.h"
 #include "amqp_types.h"
+#include "Buffer.h"
+#include "FieldTable.h"
 
 #include "assert.h"
 
@@ -34,6 +35,7 @@
 namespace qpid {
 namespace framing {
 
+//class Array;
 /**
  * Exception that is the base exception for all field table errors.
  * 
@@ -199,6 +201,42 @@
     void print(std::ostream& o) const { o << "V" << lenwidth << ":" << octets.size() << ":"; };
 };
 
+template <class T> 
+class EncodedValue : public FieldValue::Data {
+    T value;
+  public:
+
+    EncodedValue() {}
+    EncodedValue(const T& v) : value(v) {}
+
+    T& getValue() { return value; }
+    const T& getValue() const { return value; }
+
+    uint32_t size() const { return value.size(); } 
+
+    void encode(Buffer& buffer) {
+        value.encode(buffer);
+    };
+    void decode(Buffer& buffer) {
+        value.decode(buffer);
+    }
+    bool operator==(const Data& d) const {
+        const EncodedValue<T>* rhs = dynamic_cast< const EncodedValue<T>* >(&d);
+        if (rhs == 0) return false;
+        else return value==rhs->value; 
+    }
+
+    void print(std::ostream& o) const { o << "[" << value << "]"; };
+};
+
+template <>
+inline const FieldTable& FieldValue::get<const FieldTable&>() const 
+{ 
+    const EncodedValue<FieldTable>* ev = dynamic_cast< EncodedValue<FieldTable>* >(data.get());    
+    if (ev == 0) throw InvalidConversionException();
+    return ev->getValue(); 
+}
+
 /*
  * Basic string value encodes as iso-8859-15 with 32 bit length
  */ 
@@ -236,6 +274,11 @@
     FieldTableValue(const FieldTable&);
 };
 
+class ArrayValue : public FieldValue {
+  public:
+    ArrayValue(const Array&);
+};
+
 }} // qpid::framing
 
 #endif

Modified: incubator/qpid/trunk/qpid/cpp/src/tests/FieldTable.cpp
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/tests/FieldTable.cpp?rev=697076&r1=697075&r2=697076&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/tests/FieldTable.cpp (original)
+++ incubator/qpid/trunk/qpid/cpp/src/tests/FieldTable.cpp Fri Sep 19 05:56:38 2008
@@ -19,6 +19,7 @@
  *
  */
 #include <iostream>
+#include "qpid/framing/Array.h"
 #include "qpid/framing/FieldTable.h"
 #include "qpid/framing/FieldValue.h"
 #include <alloca.h>
@@ -82,4 +83,43 @@
     BOOST_CHECK(IntegerValue(1234) == *d.get("B"));
 }
 
+
+QPID_AUTO_TEST_CASE(testNestedValues)
+{
+    char buff[100];
+    {
+        FieldTable a;
+        FieldTable b;
+        std::vector<std::string> items;
+        items.push_back("one");
+        items.push_back("two");
+        Array c(items);
+        
+        a.setString("id", "A");
+        b.setString("id", "B");
+        a.setTable("B", b);
+        a.setArray("C", c);
+
+
+        Buffer wbuffer(buff, 100);
+        wbuffer.put(a);
+    }
+    {
+        Buffer rbuffer(buff, 100);
+        FieldTable a;
+        FieldTable b;
+        Array c;
+        rbuffer.get(a);
+        BOOST_CHECK(string("A") == a.getString("id"));
+        a.getTable("B", b);
+        BOOST_CHECK(string("B") == b.getString("id"));
+        a.getArray("C", c);
+        std::vector<std::string> items;
+        c.collect(items);
+        BOOST_CHECK((uint) 2 == items.size());
+        BOOST_CHECK(string("one") == items[0]);
+        BOOST_CHECK(string("two") == items[1]);
+    }
+}
+
 QPID_AUTO_TEST_SUITE_END()