![]() |
User Manual, Developers Guide and API Documentation |
![]() |
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
1.5.5