User Manual, Developers Guide and API Documentation

elements.hpp

Go to the documentation of this file.
00001 /**********************************************
00002 
00003 License: BSD
00004 Project Webpage: http://cajun-jsonapi.sourceforge.net/
00005 Author: Terry Caton
00006 
00007 ***********************************************/
00008 
00009 #ifndef WNS_PROBE_BUS_JSON_ELEMENTS_HPP
00010 #define WNS_PROBE_BUS_JSON_ELEMENTS_HPP
00011 
00012 #include <deque>
00013 #include <list>
00014 #include <string>
00015 #include <stdexcept>
00016 
00017 /*  
00018 
00019 TODO:
00020 * better documentation (doxygen?)
00021 * Unicode support
00022 * parent element accessors
00023 
00024 */
00025 
00026 namespace wns { namespace probe  { namespace bus { namespace json {
00027 
00028 
00030 // forward declarations (more info further below)
00031 
00032 
00033 class Visitor;
00034 class ConstVisitor;
00035 
00036 template <typename ValueTypeT>
00037 class TrivialType_T;
00038 
00039 typedef TrivialType_T<double> Number;
00040 typedef TrivialType_T<bool> Boolean;
00041 typedef TrivialType_T<std::string> String;
00042 
00043 class Object;
00044 class Array;
00045 class Null;
00046 
00047 
00048 
00050 // Exception - base class for all JSON-related runtime errors
00051 
00052 class Exception : public std::runtime_error
00053 {
00054 public:
00055    Exception(const std::string& sMessage);
00056 };
00057 
00058 
00059 
00060 
00062 // UnknownElement - provides a typesafe surrogate for any of the JSON-
00063 //  sanctioned element types. This class allows the Array and Object
00064 //  class to effectively contain a heterogeneous set of child elements.
00065 // The cast operators provide convenient implicit downcasting, while
00066 //  preserving dynamic type safety by throwing an exception during a
00067 //  a bad cast. 
00068 // The object & array element index operators (operators [std::string]
00069 //  and [size_t]) provide convenient, quick access to child elements.
00070 //  They are a logical extension of the cast operators. These child
00071 //  element accesses can be chained together, allowing the following
00072 //  (when document structure is well-known):
00073 //  String str = objInvoices[1]["Customer"]["Company"];
00074 
00075 
00076 class UnknownElement
00077 {
00078 public:
00079    UnknownElement();
00080    UnknownElement(const UnknownElement& unknown);
00081    UnknownElement(const Object& object);
00082    UnknownElement(const Array& array);
00083    UnknownElement(const Number& number);
00084    UnknownElement(const Boolean& boolean);
00085    UnknownElement(const String& string);
00086    UnknownElement(const Null& null);
00087 
00088    ~UnknownElement();
00089 
00090    UnknownElement& operator = (const UnknownElement& unknown);
00091 
00092    // implicit cast to actual element type. throws on failure
00093    operator const Object& () const;
00094    operator const Array& () const;
00095    operator const Number& () const;
00096    operator const Boolean& () const;
00097    operator const String& () const;
00098    operator const Null& () const;
00099 
00100    // implicit cast to actual element type. *converts* on failure, and always returns success
00101    operator Object& ();
00102    operator Array& ();
00103    operator Number& ();
00104    operator Boolean& ();
00105    operator String& ();
00106    operator Null& ();
00107 
00108    // provides quick access to children when real element type is object
00109    UnknownElement& operator[] (const std::string& key);
00110    const UnknownElement& operator[] (const std::string& key) const;
00111 
00112    // provides quick access to children when real element type is array
00113    UnknownElement& operator[] (size_t index);
00114    const UnknownElement& operator[] (size_t index) const;
00115 
00116    // implements visitor pattern
00117    void Accept(ConstVisitor& visitor) const;
00118    void Accept(Visitor& visitor);
00119 
00120    // tests equality. first checks type, then value if possible
00121    bool operator == (const UnknownElement& element) const;
00122 
00123 private:
00124    class Imp;
00125 
00126    template <typename ElementTypeT>
00127    class Imp_T;
00128 
00129    class CastVisitor;
00130    class ConstCastVisitor;
00131    
00132    template <typename ElementTypeT>
00133    class CastVisitor_T;
00134 
00135    template <typename ElementTypeT>
00136    class ConstCastVisitor_T;
00137 
00138    template <typename ElementTypeT>
00139    const ElementTypeT& CastTo() const;
00140 
00141    template <typename ElementTypeT>
00142    ElementTypeT& ConvertTo();
00143 
00144    Imp* m_pImp;
00145 };
00146 
00147 
00149 // Array - mimics std::deque<UnknownElement>. The array contents are effectively 
00150 //  heterogeneous thanks to the ElementUnknown class. push_back has been replaced 
00151 //  by more generic insert functions.
00152 
00153 class Array
00154 {
00155 public:
00156    typedef std::deque<UnknownElement> Elements;
00157    typedef Elements::iterator iterator;
00158    typedef Elements::const_iterator const_iterator;
00159 
00160    iterator Begin();
00161    iterator End();
00162    const_iterator Begin() const;
00163    const_iterator End() const;
00164    
00165    iterator Insert(const UnknownElement& element, iterator itWhere);
00166    iterator Insert(const UnknownElement& element);
00167    iterator Erase(iterator itWhere);
00168    void Resize(size_t newSize);
00169    void Clear();
00170 
00171    size_t Size() const;
00172    bool Empty() const;
00173 
00174    UnknownElement& operator[] (size_t index);
00175    const UnknownElement& operator[] (size_t index) const;
00176 
00177    bool operator == (const Array& array) const;
00178 
00179 private:
00180    Elements m_Elements;
00181 };
00182 
00183 
00185 // Object - mimics std::map<std::string, UnknownElement>. The member value 
00186 //  contents are effectively heterogeneous thanks to the UnknownElement class
00187 
00188 class Object
00189 {
00190 public:
00191    struct Member {
00192       Member(const std::string& nameIn = std::string(), const UnknownElement& elementIn = UnknownElement());
00193 
00194       bool operator == (const Member& member) const;
00195 
00196       std::string name;
00197       UnknownElement element;
00198    };
00199 
00200    typedef std::list<Member> Members; // map faster, but does not preserve order
00201    typedef Members::iterator iterator;
00202    typedef Members::const_iterator const_iterator;
00203 
00204    bool operator == (const Object& object) const;
00205 
00206    iterator Begin();
00207    iterator End();
00208    const_iterator Begin() const;
00209    const_iterator End() const;
00210 
00211    size_t Size() const;
00212    bool Empty() const;
00213 
00214    iterator Find(const std::string& name);
00215    const_iterator Find(const std::string& name) const;
00216 
00217    iterator Insert(const Member& member);
00218    iterator Insert(const Member& member, iterator itWhere);
00219    iterator Erase(iterator itWhere);
00220    void Clear();
00221 
00222    UnknownElement& operator [](const std::string& name);
00223    const UnknownElement& operator [](const std::string& name) const;
00224 
00225 private:
00226    class Finder;
00227 
00228    Members m_Members;
00229 };
00230 
00231 
00233 // TrivialType_T - class template for encapsulates a simple data type, such as
00234 //  a string, number, or boolean. Provides implicit const & noncost cast operators
00235 //  for that type, allowing "DataTypeT type = trivialType;"
00236 
00237 
00238 template <typename DataTypeT>
00239 class TrivialType_T
00240 {
00241 public:
00242    TrivialType_T(const DataTypeT& t = DataTypeT());
00243 
00244    operator DataTypeT&();
00245    operator const DataTypeT&() const;
00246 
00247    DataTypeT& Value();
00248    const DataTypeT& Value() const;
00249 
00250    bool operator == (const TrivialType_T<DataTypeT>& trivial) const;
00251 
00252 private:
00253    DataTypeT m_tValue;
00254 };
00255 
00256 
00257 
00259 // Null - doesn't do much of anything but satisfy the JSON spec. It is the default
00260 //  element type of UnknownElement
00261 
00262 class Null
00263 {
00264 public:
00265    bool operator == (const Null& trivial) const;
00266 };
00267 
00268 
00269 } // json
00270 } // bus
00271 } // probe
00272 } // wns
00273 
00274 
00275 #include <WNS/probe/bus/json/elementsInl.hpp>
00276 
00277 #endif // WNS_PROBE_BUS_JSON_ELEMENTS_HPP

Generated on Sun May 27 03:31:50 2012 for openWNS by  doxygen 1.5.5