jscm.hpp 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. /*##############################################################################
  2. Copyright (C) 2011 HPCC Systems.
  3. All rights reserved. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU Affero General Public License as
  5. published by the Free Software Foundation, either version 3 of the
  6. License, or (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU Affero General Public License for more details.
  11. You should have received a copy of the GNU Affero General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. ############################################################################## */
  14. #ifndef _JSCM_HPP_
  15. #define _JSCM_HPP_
  16. #undef interface
  17. #define implements public
  18. #define extends public
  19. #ifdef _MSC_VER
  20. #define interface struct __declspec(novtable)
  21. #else
  22. #define interface struct
  23. #endif
  24. interface IInterface
  25. {
  26. virtual void Link() const = 0;
  27. virtual bool Release() const = 0;
  28. };
  29. template <class X> inline void Link(X * ptr) { if (ptr) ptr->Link(); }
  30. template <class X> inline void Release(X * ptr) { if (ptr) ptr->Release(); }
  31. #define QUERYINTERFACE(ptr, TYPE) (dynamic_cast<TYPE *>(ptr))
  32. //A simple object container/smart pointer
  33. template <class CLASS> class OwnedPtr
  34. {
  35. public:
  36. inline OwnedPtr() { ptr = NULL; }
  37. inline OwnedPtr(CLASS * _ptr) { ptr = _ptr; }
  38. inline ~OwnedPtr() { delete ptr; }
  39. void operator = (CLASS * _ptr)
  40. {
  41. if (ptr)
  42. delete ptr;
  43. ptr = _ptr;
  44. }
  45. inline CLASS * operator -> () const { return ptr; }
  46. inline operator CLASS *() const { return ptr; }
  47. inline void clear() { CLASS *temp=ptr; ptr=NULL; delete temp; }
  48. inline CLASS * get() const { return ptr; }
  49. inline CLASS * getClear() { CLASS * temp = ptr; ptr = NULL; return temp; }
  50. inline void setown(CLASS * _ptr) { CLASS * temp = ptr; ptr = _ptr; delete temp; }
  51. private:
  52. inline OwnedPtr(const OwnedPtr<CLASS> & other);
  53. void operator = (const OwnedPtr<CLASS> & other);
  54. void setown(const OwnedPtr<CLASS> &other);
  55. private:
  56. CLASS * ptr;
  57. };
  58. //This base class implements a shared pointer based on a link count held in the object.
  59. //The two derived classes Owned and Linked should be used as the concrete types to construct a shared object
  60. //from a pointer.
  61. template <class CLASS> class Shared
  62. {
  63. public:
  64. inline Shared() { ptr = NULL; }
  65. inline Shared(CLASS * _ptr, bool owned) { ptr = _ptr; if (!owned && _ptr) _ptr->Link(); }
  66. inline Shared(const Shared<CLASS> & other) { ptr = other.getLink(); }
  67. inline ~Shared() { ::Release(ptr); }
  68. inline Shared<CLASS> & operator = (const Shared<CLASS> & other) { this->set(other.get()); return *this; }
  69. inline CLASS * operator -> () const { return ptr; }
  70. inline operator CLASS *() const { return ptr; }
  71. inline void clear() { CLASS *temp=ptr; ptr=NULL; ::Release(temp); }
  72. inline CLASS * get() const { return ptr; }
  73. inline CLASS * getClear() { CLASS * temp = ptr; ptr = NULL; return temp; }
  74. inline CLASS * getLink() const { if (ptr) ptr->Link(); return ptr; }
  75. inline void set(CLASS * _ptr)
  76. {
  77. CLASS * temp = ptr;
  78. if (temp != _ptr)
  79. {
  80. ::Link(_ptr);
  81. ptr = _ptr;
  82. ::Release(temp);
  83. }
  84. }
  85. inline void set(const Shared<CLASS> &other) { this->set(other.get()); }
  86. inline void setown(CLASS * _ptr) { CLASS * temp = ptr; ptr = _ptr; ::Release(temp); }
  87. inline void swap(Shared<CLASS> & other) { CLASS * temp = ptr; ptr = other.ptr; other.ptr = temp; }
  88. protected:
  89. inline Shared(CLASS * _ptr) { ptr = _ptr; } // deliberately protected
  90. private:
  91. inline void setown(const Shared<CLASS> &other); // illegal - going to cause a -ve leak
  92. inline Shared<CLASS> & operator = (const CLASS * other);
  93. private:
  94. CLASS * ptr;
  95. };
  96. //An Owned Shared object takes ownership of the pointer that is passed in the constructor.
  97. template <class CLASS> class Owned : public Shared<CLASS>
  98. {
  99. public:
  100. inline Owned() { }
  101. inline Owned(CLASS * _ptr) : Shared<CLASS>(_ptr) { }
  102. inline Shared<CLASS> & operator = (const Shared<CLASS> & other) { this->set(other.get()); return *this; }
  103. private:
  104. inline Owned(const Shared<CLASS> & other); // Almost certainly a bug
  105. inline Owned<CLASS> & operator = (const CLASS * other);
  106. };
  107. //A Linked Shared object takes does not take ownership of the pointer that is passed in the constructor.
  108. template <class CLASS> class Linked : public Shared<CLASS>
  109. {
  110. public:
  111. inline Linked() { }
  112. inline Linked(CLASS * _ptr) : Shared<CLASS>(LINK(_ptr)) { }
  113. inline Linked(const Shared<CLASS> & other) : Shared<CLASS>(other) { }
  114. inline Shared<CLASS> & operator = (const Shared<CLASS> & other) { this->set(other.get()); return *this; }
  115. private:
  116. inline Linked<CLASS> & operator = (const CLASS * other);
  117. };
  118. // IStringVal manages returning of arbitrary null-terminated string data between systems that may not share heap managers
  119. interface IStringVal
  120. {
  121. virtual const char * str() const = 0;
  122. virtual void set(const char * val) = 0;
  123. virtual void clear() = 0;
  124. virtual void setLen(const char * val, unsigned length) = 0;
  125. virtual unsigned length() const = 0;
  126. };
  127. // IDataVal manages returning of arbitrary unterminated binary data between systems that may not share heap managers
  128. interface IDataVal
  129. {
  130. virtual const void * data() const = 0;
  131. virtual void clear() = 0;
  132. virtual void setLen(const void * val, unsigned length) = 0;
  133. virtual unsigned length() const = 0;
  134. virtual void * reserve(unsigned length) = 0;
  135. };
  136. // IIterator
  137. interface IIterator : extends IInterface
  138. {
  139. virtual bool first() = 0;
  140. virtual bool next() = 0;
  141. virtual bool isValid() = 0;
  142. virtual IInterface & query() = 0;
  143. virtual IInterface & get() = 0;
  144. };
  145. template <class C>
  146. interface IIteratorOf : public IInterface
  147. {
  148. public:
  149. virtual bool first() = 0;
  150. virtual bool next() = 0;
  151. virtual bool isValid() = 0;
  152. virtual C & query() = 0;
  153. C & get() { C &c = query(); c.Link(); return c; }
  154. };
  155. #define ForEach(i) for((i).first();(i).isValid();(i).next())
  156. typedef IInterface * IInterfacePtr;
  157. typedef Owned<IInterface> OwnedIInterface;
  158. typedef Linked<IInterface> LinkedIInterface;
  159. template <class X> inline X * LINK(X * ptr) { if (ptr) ptr->Link(); return ptr; }
  160. template <class X> inline X & OLINK(X & obj) { obj.Link(); return obj; }
  161. template <class X> inline X * LINK(const Shared<X> &ptr) { return ptr.getLink(); }
  162. #endif