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