![]() |
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 #include <WNS/probe/bus/json/visitor.hpp> 00010 #include <WNS/probe/bus/json/reader.hpp> 00011 00012 #include <cassert> 00013 #include <algorithm> 00014 #include <map> 00015 00016 /* 00017 00018 TODO: 00019 * better documentation 00020 00021 */ 00022 00023 namespace wns { namespace probe { namespace bus { namespace json { 00024 00025 00026 inline Exception::Exception(const std::string& sMessage) : 00027 std::runtime_error(sMessage) {} 00028 00029 00031 // UnknownElement members 00032 00033 class UnknownElement::Imp 00034 { 00035 public: 00036 virtual ~Imp() {} 00037 virtual Imp* Clone() const = 0; 00038 00039 virtual bool Compare(const Imp& imp) const = 0; 00040 00041 virtual void Accept(ConstVisitor& visitor) const = 0; 00042 virtual void Accept(Visitor& visitor) = 0; 00043 }; 00044 00045 00046 template <typename ElementTypeT> 00047 class UnknownElement::Imp_T : public UnknownElement::Imp 00048 { 00049 public: 00050 Imp_T(const ElementTypeT& element) : m_Element(element) {} 00051 virtual Imp* Clone() const { return new Imp_T<ElementTypeT>(*this); } 00052 00053 virtual void Accept(ConstVisitor& visitor) const { visitor.Visit(m_Element); } 00054 virtual void Accept(Visitor& visitor) { visitor.Visit(m_Element); } 00055 00056 virtual bool Compare(const Imp& imp) const 00057 { 00058 ConstCastVisitor_T<ElementTypeT> castVisitor; 00059 imp.Accept(castVisitor); 00060 return castVisitor.m_pElement && 00061 m_Element == *castVisitor.m_pElement; 00062 } 00063 00064 private: 00065 ElementTypeT m_Element; 00066 }; 00067 00068 00069 class UnknownElement::ConstCastVisitor : public ConstVisitor 00070 { 00071 virtual void Visit(const Array& array) {} 00072 virtual void Visit(const Object& object) {} 00073 virtual void Visit(const Number& number) {} 00074 virtual void Visit(const String& string) {} 00075 virtual void Visit(const Boolean& boolean) {} 00076 virtual void Visit(const Null& null) {} 00077 }; 00078 00079 template <typename ElementTypeT> 00080 class UnknownElement::ConstCastVisitor_T : public ConstCastVisitor 00081 { 00082 public: 00083 ConstCastVisitor_T() : m_pElement(0) {} 00084 virtual void Visit(const ElementTypeT& element) { m_pElement = &element; } // we don't know what this is, but it overrides one of the base's no-op functions 00085 const ElementTypeT* m_pElement; 00086 }; 00087 00088 00089 class UnknownElement::CastVisitor : public Visitor 00090 { 00091 virtual void Visit(Array& array) {} 00092 virtual void Visit(Object& object) {} 00093 virtual void Visit(Number& number) {} 00094 virtual void Visit(String& string) {} 00095 virtual void Visit(Boolean& boolean) {} 00096 virtual void Visit(Null& null) {} 00097 }; 00098 00099 template <typename ElementTypeT> 00100 class UnknownElement::CastVisitor_T : public CastVisitor 00101 { 00102 public: 00103 CastVisitor_T() : m_pElement(0) {} 00104 virtual void Visit(ElementTypeT& element) { m_pElement = &element; } // we don't know what this is, but it overrides one of the base's no-op functions 00105 ElementTypeT* m_pElement; 00106 }; 00107 00108 00109 00110 00111 inline UnknownElement::UnknownElement() : m_pImp( new Imp_T<Null>( Null() ) ) {} 00112 inline UnknownElement::UnknownElement(const UnknownElement& unknown) : m_pImp( unknown.m_pImp->Clone()) {} 00113 inline UnknownElement::UnknownElement(const Object& object) : m_pImp( new Imp_T<Object>(object) ) {} 00114 inline UnknownElement::UnknownElement(const Array& array) : m_pImp( new Imp_T<Array>(array) ) {} 00115 inline UnknownElement::UnknownElement(const Number& number) : m_pImp( new Imp_T<Number>(number) ) {} 00116 inline UnknownElement::UnknownElement(const Boolean& boolean) : m_pImp( new Imp_T<Boolean>(boolean) ) {} 00117 inline UnknownElement::UnknownElement(const String& string) : m_pImp( new Imp_T<String>(string) ) {} 00118 inline UnknownElement::UnknownElement(const Null& null) : m_pImp( new Imp_T<Null>(null) ) {} 00119 00120 inline UnknownElement::~UnknownElement() { delete m_pImp; } 00121 00122 inline UnknownElement::operator const Object& () const { return CastTo<Object>(); } 00123 inline UnknownElement::operator const Array& () const { return CastTo<Array>(); } 00124 inline UnknownElement::operator const Number& () const { return CastTo<Number>(); } 00125 inline UnknownElement::operator const Boolean& () const { return CastTo<Boolean>(); } 00126 inline UnknownElement::operator const String& () const { return CastTo<String>(); } 00127 inline UnknownElement::operator const Null& () const { return CastTo<Null>(); } 00128 00129 inline UnknownElement::operator Object& () { return ConvertTo<Object>(); } 00130 inline UnknownElement::operator Array& () { return ConvertTo<Array>(); } 00131 inline UnknownElement::operator Number& () { return ConvertTo<Number>(); } 00132 inline UnknownElement::operator Boolean& () { return ConvertTo<Boolean>(); } 00133 inline UnknownElement::operator String& () { return ConvertTo<String>(); } 00134 inline UnknownElement::operator Null& () { return ConvertTo<Null>(); } 00135 00136 inline UnknownElement& UnknownElement::operator = (const UnknownElement& unknown) 00137 { 00138 delete m_pImp; 00139 m_pImp = unknown.m_pImp->Clone(); 00140 return *this; 00141 } 00142 00143 inline UnknownElement& UnknownElement::operator[] (const std::string& key) 00144 { 00145 // the people want an object. make us one if we aren't already 00146 Object& object = ConvertTo<Object>(); 00147 return object[key]; 00148 } 00149 00150 inline const UnknownElement& UnknownElement::operator[] (const std::string& key) const 00151 { 00152 // throws if we aren't an object 00153 const Object& object = CastTo<Object>(); 00154 return object[key]; 00155 } 00156 00157 inline UnknownElement& UnknownElement::operator[] (size_t index) 00158 { 00159 // the people want an array. make us one if we aren't already 00160 Array& array = ConvertTo<Array>(); 00161 return array[index]; 00162 } 00163 00164 inline const UnknownElement& UnknownElement::operator[] (size_t index) const 00165 { 00166 // throws if we aren't an array 00167 const Array& array = CastTo<Array>(); 00168 return array[index]; 00169 } 00170 00171 00172 template <typename ElementTypeT> 00173 const ElementTypeT& UnknownElement::CastTo() const 00174 { 00175 ConstCastVisitor_T<ElementTypeT> castVisitor; 00176 m_pImp->Accept(castVisitor); 00177 if (castVisitor.m_pElement == 0) 00178 throw Exception("Bad cast"); 00179 return *castVisitor.m_pElement; 00180 } 00181 00182 00183 00184 template <typename ElementTypeT> 00185 ElementTypeT& UnknownElement::ConvertTo() 00186 { 00187 CastVisitor_T<ElementTypeT> castVisitor; 00188 m_pImp->Accept(castVisitor); 00189 if (castVisitor.m_pElement == 0) 00190 { 00191 // we're not the right type. fix it & try again 00192 *this = ElementTypeT(); 00193 m_pImp->Accept(castVisitor); 00194 } 00195 00196 return *castVisitor.m_pElement; 00197 } 00198 00199 00200 inline void UnknownElement::Accept(ConstVisitor& visitor) const { m_pImp->Accept(visitor); } 00201 inline void UnknownElement::Accept(Visitor& visitor) { m_pImp->Accept(visitor); } 00202 00203 00204 inline bool UnknownElement::operator == (const UnknownElement& element) const 00205 { 00206 return m_pImp->Compare(*element.m_pImp); 00207 } 00208 00209 00210 00212 // Object members 00213 00214 00215 inline Object::Member::Member(const std::string& nameIn, const UnknownElement& elementIn) : 00216 name(nameIn), element(elementIn) {} 00217 00218 inline bool Object::Member::operator == (const Member& member) const 00219 { 00220 return name == member.name && 00221 element == member.element; 00222 } 00223 00224 class Object::Finder : public std::unary_function<Object::Member, bool> 00225 { 00226 public: 00227 Finder(const std::string& name) : m_name(name) {} 00228 bool operator () (const Object::Member& member) { 00229 return member.name == m_name; 00230 } 00231 00232 private: 00233 std::string m_name; 00234 }; 00235 00236 00237 00238 inline Object::iterator Object::Begin() { return m_Members.begin(); } 00239 inline Object::iterator Object::End() { return m_Members.end(); } 00240 inline Object::const_iterator Object::Begin() const { return m_Members.begin(); } 00241 inline Object::const_iterator Object::End() const { return m_Members.end(); } 00242 00243 inline size_t Object::Size() const { return m_Members.size(); } 00244 inline bool Object::Empty() const { return m_Members.empty(); } 00245 00246 inline Object::iterator Object::Find(const std::string& name) 00247 { 00248 return std::find_if(m_Members.begin(), m_Members.end(), Finder(name)); 00249 } 00250 00251 inline Object::const_iterator Object::Find(const std::string& name) const 00252 { 00253 return std::find_if(m_Members.begin(), m_Members.end(), Finder(name)); 00254 } 00255 00256 inline Object::iterator Object::Insert(const Member& member) 00257 { 00258 return Insert(member, End()); 00259 } 00260 00261 inline Object::iterator Object::Insert(const Member& member, iterator itWhere) 00262 { 00263 iterator it = Find(member.name); 00264 if (it != m_Members.end()) 00265 throw Exception("Object member already exists: " + member.name); 00266 00267 it = m_Members.insert(itWhere, member); 00268 return it; 00269 } 00270 00271 inline Object::iterator Object::Erase(iterator itWhere) 00272 { 00273 return m_Members.erase(itWhere); 00274 } 00275 00276 inline UnknownElement& Object::operator [](const std::string& name) 00277 { 00278 00279 iterator it = Find(name); 00280 if (it == m_Members.end()) 00281 { 00282 Member member(name); 00283 it = Insert(member, End()); 00284 } 00285 return it->element; 00286 } 00287 00288 inline const UnknownElement& Object::operator [](const std::string& name) const 00289 { 00290 const_iterator it = Find(name); 00291 if (it == End()) 00292 throw Exception("Object member not found: " + name); 00293 return it->element; 00294 } 00295 00296 inline void Object::Clear() 00297 { 00298 m_Members.clear(); 00299 } 00300 00301 inline bool Object::operator == (const Object& object) const 00302 { 00303 return m_Members == object.m_Members; 00304 } 00305 00306 00308 // Array members 00309 00310 inline Array::iterator Array::Begin() { return m_Elements.begin(); } 00311 inline Array::iterator Array::End() { return m_Elements.end(); } 00312 inline Array::const_iterator Array::Begin() const { return m_Elements.begin(); } 00313 inline Array::const_iterator Array::End() const { return m_Elements.end(); } 00314 00315 inline Array::iterator Array::Insert(const UnknownElement& element, iterator itWhere) 00316 { 00317 return m_Elements.insert(itWhere, element); 00318 } 00319 00320 inline Array::iterator Array::Insert(const UnknownElement& element) 00321 { 00322 return Insert(element, End()); 00323 } 00324 00325 inline Array::iterator Array::Erase(iterator itWhere) 00326 { 00327 return m_Elements.erase(itWhere); 00328 } 00329 00330 inline void Array::Resize(size_t newSize) 00331 { 00332 m_Elements.resize(newSize); 00333 } 00334 00335 inline size_t Array::Size() const { return m_Elements.size(); } 00336 inline bool Array::Empty() const { return m_Elements.empty(); } 00337 00338 inline UnknownElement& Array::operator[] (size_t index) 00339 { 00340 size_t nMinSize = index + 1; // zero indexed 00341 if (m_Elements.size() < nMinSize) 00342 m_Elements.resize(nMinSize); 00343 return m_Elements[index]; 00344 } 00345 00346 inline const UnknownElement& Array::operator[] (size_t index) const 00347 { 00348 if (index >= m_Elements.size()) 00349 throw Exception("Array out of bounds"); 00350 return m_Elements[index]; 00351 } 00352 00353 inline void Array::Clear() { 00354 m_Elements.clear(); 00355 } 00356 00357 inline bool Array::operator == (const Array& array) const 00358 { 00359 return m_Elements == array.m_Elements; 00360 } 00361 00362 00364 // TrivialType_T members 00365 00366 template <typename DataTypeT> 00367 TrivialType_T<DataTypeT>::TrivialType_T(const DataTypeT& t) : 00368 m_tValue(t) {} 00369 00370 template <typename DataTypeT> 00371 TrivialType_T<DataTypeT>::operator DataTypeT&() 00372 { 00373 return Value(); 00374 } 00375 00376 template <typename DataTypeT> 00377 TrivialType_T<DataTypeT>::operator const DataTypeT&() const 00378 { 00379 return Value(); 00380 } 00381 00382 template <typename DataTypeT> 00383 DataTypeT& TrivialType_T<DataTypeT>::Value() 00384 { 00385 return m_tValue; 00386 } 00387 00388 template <typename DataTypeT> 00389 const DataTypeT& TrivialType_T<DataTypeT>::Value() const 00390 { 00391 return m_tValue; 00392 } 00393 00394 template <typename DataTypeT> 00395 bool TrivialType_T<DataTypeT>::operator == (const TrivialType_T<DataTypeT>& trivial) const 00396 { 00397 return m_tValue == trivial.m_tValue; 00398 } 00399 00400 00401 00403 // Null members 00404 00405 inline bool Null::operator == (const Null& trivial) const 00406 { 00407 return true; 00408 } 00409 00410 00411 } // json 00412 } // bus 00413 } // probe 00414 } // wns
1.5.5