1 //****************************************************************************** 2 /// 3 /// @file povms/povmscpp.h 4 /// 5 /// This module contains all defines, typedefs, and prototypes for the 6 /// C++ interface version of `povms.cpp`. 7 /// 8 /// @copyright 9 /// @parblock 10 /// 11 /// Persistence of Vision Ray Tracer ('POV-Ray') version 3.8. 12 /// Copyright 1991-2018 Persistence of Vision Raytracer Pty. Ltd. 13 /// 14 /// POV-Ray is free software: you can redistribute it and/or modify 15 /// it under the terms of the GNU Affero General Public License as 16 /// published by the Free Software Foundation, either version 3 of the 17 /// License, or (at your option) any later version. 18 /// 19 /// POV-Ray is distributed in the hope that it will be useful, 20 /// but WITHOUT ANY WARRANTY; without even the implied warranty of 21 /// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 /// GNU Affero General Public License for more details. 23 /// 24 /// You should have received a copy of the GNU Affero General Public License 25 /// along with this program. If not, see <http://www.gnu.org/licenses/>. 26 /// 27 /// ---------------------------------------------------------------------------- 28 /// 29 /// POV-Ray is based on the popular DKB raytracer version 2.12. 30 /// DKBTrace was originally written by David K. Buck. 31 /// DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins. 32 /// 33 /// @endparblock 34 /// 35 //****************************************************************************** 36 37 #ifndef POVMSCPP_H 38 #define POVMSCPP_H 39 40 #include <string> 41 #include <vector> 42 43 #include "povms/povms.h" 44 #include "base/pov_err.h" 45 46 /// @file 47 /// @todo We could place this in a namespace. 48 49 class POVMS_Container; 50 class POVMS_Attribute; 51 class POVMS_List; 52 class POVMS_Object; 53 class POVMS_Message; 54 class POVMS_MessageReceiver; 55 56 typedef std::basic_string<POVMSUCS2> POVMSUCS2String; 57 58 POVMSUCS2String POVMS_ASCIItoUCS2String(const char *s); 59 std::string POVMS_UCS2toASCIIString(const POVMSUCS2String& s); 60 61 class POVMS_Container 62 { 63 friend void POVMS_SendMessage(POVMS_Message&); 64 friend void POVMS_SendMessage(POVMSContext, POVMS_Message&, POVMS_Message *, int); 65 friend class POVMS_List; 66 friend class POVMS_Object; 67 friend class POVMS_MessageReceiver; 68 public: 69 POVMS_Container(); 70 virtual ~POVMS_Container() noexcept(false); 71 72 POVMSType Type() const; 73 size_t Size() const; 74 bool IsNull() const; 75 protected: 76 mutable POVMSData data; 77 78 void DetachData(); 79 }; 80 81 class POVMS_Attribute : public POVMS_Container 82 { 83 public: 84 POVMS_Attribute(); 85 POVMS_Attribute(const char *str); 86 POVMS_Attribute(const POVMSUCS2 *str); 87 POVMS_Attribute(POVMSInt value); 88 POVMS_Attribute(POVMSLong value); 89 POVMS_Attribute(POVMSFloat value); 90 POVMS_Attribute(bool value); 91 POVMS_Attribute(POVMSType value); 92 POVMS_Attribute(std::vector<POVMSInt>& value); 93 POVMS_Attribute(std::vector<POVMSLong>& value); 94 POVMS_Attribute(std::vector<POVMSFloat>& value); 95 POVMS_Attribute(std::vector<POVMSType>& value); 96 POVMS_Attribute(POVMSAttribute& convert); 97 POVMS_Attribute(const POVMS_Attribute& source); 98 virtual ~POVMS_Attribute() noexcept(false); 99 100 POVMS_Attribute& operator=(const POVMS_Attribute& source); 101 102 void Get(POVMSType type, void *data, int *maxdatasize); 103 void Set(POVMSType type, const void *data, int datasize); 104 105 int GetStringLength() const; // Note: Includes trailing \0 character code! 106 int GetString(char *str, int maxlen); 107 std::string GetString(); 108 int GetUCS2StringLength() const; // Note: Includes trailing \0 character code! 109 int GetUCS2String(POVMSUCS2 *str, int maxlen); 110 POVMSUCS2String GetUCS2String(); 111 POVMSInt GetInt(); 112 POVMSLong GetLong(); 113 POVMSFloat GetFloat(); 114 POVMSBool GetBool(); 115 POVMSType GetType(); 116 117 std::vector<POVMSInt> GetIntVector(); 118 std::vector<POVMSLong> GetLongVector(); 119 std::vector<POVMSFloat> GetFloatVector(); 120 std::vector<POVMSType> GetTypeVector(); 121 122 int GetVectorSize() const; 123 }; 124 125 class POVMS_List : public POVMS_Container 126 { 127 public: 128 POVMS_List(); 129 POVMS_List(POVMSAttributeList& convert); 130 POVMS_List(const POVMS_List& source); 131 virtual ~POVMS_List() noexcept(false); 132 133 POVMS_List& operator=(const POVMS_List& source); 134 135 void Append(POVMS_Attribute& item); 136 void Append(POVMS_List& item); 137 void Append(POVMS_Object& item); 138 void AppendN(int cnt, POVMS_Attribute& item); 139 void AppendN(int cnt, POVMS_List& item); 140 void AppendN(int cnt, POVMS_Object& item); 141 void GetNth(int index, POVMS_Attribute& item); 142 void GetNth(int index, POVMS_List& item); 143 void GetNth(int index, POVMS_Object& item); 144 void SetNth(int index, POVMS_Attribute& item); 145 void SetNth(int index, POVMS_List& item); 146 void SetNth(int index, POVMS_Object& item); 147 void RemoveNth(int index); 148 void Clear(); 149 150 int GetListSize(); 151 }; 152 153 class POVMS_Object : public POVMS_Container 154 { 155 friend class POVMS_Message; 156 friend class POVMS_MessageReceiver; 157 158 class InputStream 159 { 160 public: InputStream()161 InputStream() { } ~InputStream()162 virtual ~InputStream() { } 163 virtual bool read(void *, int) = 0; 164 }; 165 166 class OutputStream 167 { 168 public: OutputStream()169 OutputStream() { } ~OutputStream()170 virtual ~OutputStream() { } 171 virtual bool write(void *, int) = 0; 172 }; 173 174 template<class T> class InputStreamT : public InputStream 175 { 176 public: InputStreamT(T & s)177 InputStreamT(T& s) : stream(s) { } ~InputStreamT()178 virtual ~InputStreamT() { } read(void * ptr,int cnt)179 virtual bool read(void *ptr, int cnt) { return !(!stream.read(ptr, (size_t)cnt)); } 180 private: 181 T& stream; 182 }; 183 184 template<class T> class OutputStreamT : public OutputStream 185 { 186 public: OutputStreamT(T & s)187 OutputStreamT(T& s) : stream(s) { } ~OutputStreamT()188 virtual ~OutputStreamT() { } write(void * ptr,int cnt)189 virtual bool write(void *ptr, int cnt) { return !(!stream.write(ptr, (size_t)cnt)); } 190 private: 191 T& stream; 192 }; 193 public: 194 POVMS_Object(); 195 POVMS_Object(POVMSType objclass); 196 POVMS_Object(POVMSObject& convert); 197 POVMS_Object(POVMSObjectPtr convert); 198 POVMS_Object(const POVMS_Object& source); 199 ~POVMS_Object() noexcept(false); 200 201 POVMS_Object& operator=(const POVMS_Object& source); 202 203 void Get(POVMSType key, POVMS_Attribute& attr); 204 void Get(POVMSType key, POVMS_List& attr); 205 void Get(POVMSType key, POVMS_Object& attr); 206 void Set(POVMSType key, POVMS_Attribute& attr); 207 void Set(POVMSType key, POVMS_List& attr); 208 void Set(POVMSType key, POVMS_Object& attr); 209 void Remove(POVMSType key); 210 bool Exist(POVMSType key); 211 void Merge(POVMS_Object& source); 212 213 const POVMSObject& operator*() const; 214 const POVMSObject* operator->() const; 215 POVMSObject operator()(); 216 217 void SetString(POVMSType key, const char *str); // Note: Strings may not contain \0 characters codes! 218 void SetUCS2String(POVMSType key, const POVMSUCS2 *str); // Note: Strings may not contain \0 characters codes! 219 void SetInt(POVMSType key, POVMSInt value); 220 void SetLong(POVMSType key, POVMSLong value); 221 void SetFloat(POVMSType key, POVMSFloat value); 222 void SetBool(POVMSType key, POVMSBool value); 223 void SetType(POVMSType key, POVMSType value); 224 225 /// Set an attribute without any payload data. 226 void SetVoid(POVMSType key); 227 228 void SetIntVector(POVMSType key, std::vector<POVMSInt>& value); 229 void SetLongVector(POVMSType key, std::vector<POVMSLong>& value); 230 void SetFloatVector(POVMSType key, std::vector<POVMSFloat>& value); 231 void SetTypeVector(POVMSType key, std::vector<POVMSType>& value); 232 233 int GetStringLength(POVMSType key); // Note: Includes trailing \0 character code! 234 int GetString(POVMSType key, char *str, int maxlen); 235 std::string GetString(POVMSType key); 236 int GetUCS2StringLength(POVMSType key); // Note: Includes trailing \0 character code! 237 int GetUCS2String(POVMSType key, POVMSUCS2 *str, int maxlen); 238 POVMSUCS2String GetUCS2String(POVMSType key); 239 POVMSInt GetInt(POVMSType key); 240 POVMSLong GetLong(POVMSType key); 241 POVMSFloat GetFloat(POVMSType key); 242 POVMSBool GetBool(POVMSType key); 243 POVMSType GetType(POVMSType key); 244 245 std::vector<POVMSInt> GetIntVector(POVMSType key); 246 std::vector<POVMSLong> GetLongVector(POVMSType key); 247 std::vector<POVMSFloat> GetFloatVector(POVMSType key); 248 std::vector<POVMSType> GetTypeVector(POVMSType key); 249 250 std::string TryGetString(POVMSType key, const char *alt); 251 std::string TryGetString(POVMSType key, const std::string& alt); 252 POVMSUCS2String TryGetUCS2String(POVMSType key, const char *alt); 253 POVMSUCS2String TryGetUCS2String(POVMSType key, const POVMSUCS2String& alt); 254 POVMSInt TryGetInt(POVMSType key, POVMSInt alt); TryGetEnum(POVMSType key,T alt)255 template<typename T> T TryGetEnum(POVMSType key, T alt) 256 { return static_cast<T>(TryGetInt(key, static_cast<int>(alt))); } 257 POVMSLong TryGetLong(POVMSType key, POVMSLong alt); 258 POVMSFloat TryGetFloat(POVMSType key, POVMSFloat alt); 259 POVMSBool TryGetBool(POVMSType key, POVMSBool alt); 260 POVMSType TryGetType(POVMSType key, POVMSType alt); 261 Read(T & stream)262 template<class T> void Read(T& stream) 263 { 264 InputStreamT<T> s(stream); 265 Read(s, false, false); 266 } 267 Write(T & stream)268 template<class T> void Write(T& stream) 269 { 270 OutputStreamT<T> s(stream); 271 Write(s, false, true); 272 } 273 private: 274 void Read(InputStream& stream, bool continued, bool headeronly); 275 void Write(OutputStream& stream, bool append, bool compress); 276 }; 277 278 class POVMS_Message : public POVMS_Object 279 { 280 public: 281 POVMS_Message(); 282 POVMS_Message(POVMSType objclass, POVMSType msgclass = kPOVMSType_WildCard, POVMSType msgid = kPOVMSType_WildCard); 283 POVMS_Message(POVMS_Object& convert, POVMSType msgclass = kPOVMSType_WildCard, POVMSType msgid = kPOVMSType_WildCard); 284 POVMS_Message(POVMSObject& convert); 285 POVMS_Message(POVMSObjectPtr convert); 286 POVMS_Message(const POVMS_Message& source); 287 288 POVMS_Message& operator=(const POVMS_Message& source); 289 290 POVMSType GetClass(); 291 POVMSType GetIdentifier(); 292 293 POVMSAddress GetSourceAddress(); 294 POVMSAddress GetDestinationAddress(); 295 void SetSourceAddress(POVMSAddress); 296 void SetDestinationAddress(POVMSAddress); 297 }; 298 299 class POVMS_MessageReceiver 300 { 301 private: 302 class HandlerOO 303 { 304 public: ~HandlerOO()305 virtual ~HandlerOO() {} 306 virtual void Call(POVMS_Message&, POVMS_Message&, int) = 0; 307 }; 308 class Handler 309 { 310 public: ~Handler()311 virtual ~Handler() {} 312 virtual void Call(POVMSObjectPtr, POVMSObjectPtr, int) = 0; 313 }; 314 protected: 315 template<class T> class MemberHandlerOO : public HandlerOO 316 { 317 public: 318 typedef void (T::*MemberHandlerPtr)(POVMS_Message&, POVMS_Message&, int); 319 MemberHandlerOO()320 MemberHandlerOO() 321 { 322 classptr = nullptr; 323 handlerptr = nullptr; 324 } 325 MemberHandlerOO(T * cptr,MemberHandlerPtr hptr)326 MemberHandlerOO(T *cptr, MemberHandlerPtr hptr) 327 { 328 classptr = cptr; 329 handlerptr = hptr; 330 } 331 Call(POVMS_Message & msg,POVMS_Message & result,int mode)332 void Call(POVMS_Message& msg, POVMS_Message& result, int mode) 333 { 334 if ((classptr != nullptr) && (handlerptr != nullptr)) 335 (classptr->*handlerptr)(msg, result, mode); 336 else 337 throw POV_EXCEPTION_CODE(pov_base::kNullPointerErr); 338 } 339 private: 340 MemberHandlerPtr handlerptr; 341 T *classptr; 342 }; 343 344 template<class T> class MemberHandler : public Handler 345 { 346 public: 347 typedef void (T::*MemberHandlerPtr)(POVMSObjectPtr, POVMSObjectPtr, int); 348 MemberHandler()349 MemberHandler() 350 { 351 classptr = nullptr; 352 handlerptr = nullptr; 353 } 354 MemberHandler(T * cptr,MemberHandlerPtr hptr)355 MemberHandler(T *cptr, MemberHandlerPtr hptr) 356 { 357 classptr = cptr; 358 handlerptr = hptr; 359 } 360 Call(POVMSObjectPtr msg,POVMSObjectPtr result,int mode)361 void Call(POVMSObjectPtr msg, POVMSObjectPtr result, int mode) 362 { 363 if ((classptr != nullptr) && (handlerptr != nullptr)) 364 (classptr->*handlerptr)(msg, result, mode); 365 else 366 throw POV_EXCEPTION_CODE(pov_base::kNullPointerErr); 367 } 368 private: 369 MemberHandlerPtr handlerptr; 370 T *classptr; 371 }; 372 373 class FunctionHandlerOO : public HandlerOO 374 { 375 public: 376 typedef void (*FunctionHandlerPtr)(POVMS_Message&, POVMS_Message&, int, void *); 377 FunctionHandlerOO()378 FunctionHandlerOO() 379 { 380 handlerptr = nullptr; 381 privatedata = nullptr; 382 } 383 FunctionHandlerOO(FunctionHandlerPtr hptr,void * pptr)384 FunctionHandlerOO(FunctionHandlerPtr hptr, void *pptr) 385 { 386 handlerptr = hptr; 387 privatedata = pptr; 388 } 389 Call(POVMS_Message & msg,POVMS_Message & result,int mode)390 void Call(POVMS_Message& msg, POVMS_Message& result, int mode) 391 { 392 if (handlerptr != nullptr) 393 handlerptr(msg, result, mode, privatedata); 394 else 395 throw POV_EXCEPTION_CODE(pov_base::kNullPointerErr); 396 } 397 private: 398 FunctionHandlerPtr handlerptr; 399 void *privatedata; 400 }; 401 402 class FunctionHandler : public Handler 403 { 404 public: 405 typedef void (*FunctionHandlerPtr)(POVMSObjectPtr, POVMSObjectPtr, int, void *); 406 FunctionHandler()407 FunctionHandler() 408 { 409 handlerptr = nullptr; 410 privatedata = nullptr; 411 } 412 FunctionHandler(FunctionHandlerPtr hptr,void * pptr)413 FunctionHandler(FunctionHandlerPtr hptr, void *pptr) 414 { 415 handlerptr = hptr; 416 privatedata = pptr; 417 } 418 Call(POVMSObjectPtr msg,POVMSObjectPtr result,int mode)419 void Call(POVMSObjectPtr msg, POVMSObjectPtr result, int mode) 420 { 421 if (handlerptr != nullptr) 422 handlerptr(msg, result, mode, privatedata); 423 else 424 throw POV_EXCEPTION_CODE(pov_base::kNullPointerErr); 425 } 426 private: 427 FunctionHandlerPtr handlerptr; 428 void *privatedata; 429 }; 430 431 POVMS_MessageReceiver(POVMSContext contextref); 432 virtual ~POVMS_MessageReceiver(); 433 InstallFront(POVMSType hclass,POVMSType hid,T * cptr,typename MemberHandlerOO<T>::MemberHandlerPtr hptr)434 template<class T> void InstallFront(POVMSType hclass, POVMSType hid, T *cptr, typename MemberHandlerOO<T>::MemberHandlerPtr hptr) 435 { 436 AddNodeFront(hclass, hid, new MemberHandlerOO<T>(cptr, hptr), nullptr); 437 } 438 InstallFront(POVMSType hclass,POVMSType hid,T * cptr,typename MemberHandler<T>::MemberHandlerPtr hptr)439 template<class T> void InstallFront(POVMSType hclass, POVMSType hid, T *cptr, typename MemberHandler<T>::MemberHandlerPtr hptr) 440 { 441 AddNodeFront(hclass, hid, nullptr, new MemberHandler<T>(cptr, hptr)); 442 } 443 InstallFront(POVMSType hclass,POVMSType hid,FunctionHandlerOO::FunctionHandlerPtr hptr,void * pptr)444 void InstallFront(POVMSType hclass, POVMSType hid, FunctionHandlerOO::FunctionHandlerPtr hptr, void *pptr) 445 { 446 AddNodeFront(hclass, hid, new FunctionHandlerOO(hptr, pptr), nullptr); 447 } 448 InstallFront(POVMSType hclass,POVMSType hid,FunctionHandler::FunctionHandlerPtr hptr,void * pptr)449 void InstallFront(POVMSType hclass, POVMSType hid, FunctionHandler::FunctionHandlerPtr hptr, void *pptr) 450 { 451 AddNodeFront(hclass, hid, nullptr, new FunctionHandler(hptr, pptr)); 452 } 453 InstallBack(POVMSType hclass,POVMSType hid,T * cptr,typename MemberHandlerOO<T>::MemberHandlerPtr hptr)454 template<class T> void InstallBack(POVMSType hclass, POVMSType hid, T *cptr, typename MemberHandlerOO<T>::MemberHandlerPtr hptr) 455 { 456 AddNodeBack(hclass, hid, new MemberHandlerOO<T>(cptr, hptr), nullptr); 457 } 458 InstallBack(POVMSType hclass,POVMSType hid,T * cptr,typename MemberHandler<T>::MemberHandlerPtr hptr)459 template<class T> void InstallBack(POVMSType hclass, POVMSType hid, T *cptr, typename MemberHandler<T>::MemberHandlerPtr hptr) 460 { 461 AddNodeBack(hclass, hid, nullptr, new MemberHandler<T>(cptr, hptr)); 462 } 463 InstallBack(POVMSType hclass,POVMSType hid,FunctionHandlerOO::FunctionHandlerPtr hptr,void * pptr)464 void InstallBack(POVMSType hclass, POVMSType hid, FunctionHandlerOO::FunctionHandlerPtr hptr, void *pptr) 465 { 466 AddNodeBack(hclass, hid, new FunctionHandlerOO(hptr, pptr), nullptr); 467 } 468 InstallBack(POVMSType hclass,POVMSType hid,FunctionHandler::FunctionHandlerPtr hptr,void * pptr)469 void InstallBack(POVMSType hclass, POVMSType hid, FunctionHandler::FunctionHandlerPtr hptr, void *pptr) 470 { 471 AddNodeBack(hclass, hid, nullptr, new FunctionHandler(hptr, pptr)); 472 } 473 474 void Remove(POVMSType hclass, POVMSType hid); 475 private: 476 struct HandlerNode 477 { 478 struct HandlerNode *last; 479 struct HandlerNode *next; 480 POVMSType hclass; 481 POVMSType hid; 482 HandlerOO *handleroo; 483 Handler *handler; 484 }; 485 486 POVMSContext context; 487 HandlerNode *receivers; 488 489 POVMS_MessageReceiver(); // default constructor not allowed 490 POVMS_MessageReceiver(const POVMS_MessageReceiver&); // no copies allowed 491 POVMS_MessageReceiver& operator=(const POVMS_MessageReceiver&); // no copy assignments allowed 492 493 static POVMSResult ReceiveHandler(POVMSObjectPtr msg, POVMSObjectPtr result, int mode, void *privatedataptr); 494 495 void AddNodeFront(POVMSType hclass, POVMSType hid, HandlerOO *hooptr, Handler *hptr); 496 void AddNodeBack(POVMSType hclass, POVMSType hid, HandlerOO *hooptr, Handler *hptr); 497 void RemoveNode(HandlerNode *nodeptr); 498 }; 499 500 void POVMS_SendMessage(POVMS_Message& msg); 501 void POVMS_SendMessage(POVMSContext contextref, POVMS_Message& msg, POVMS_Message *result, int mode); 502 503 #endif 504