/*############################################################################## Copyright (C) 2011 HPCC Systems. All rights reserved. This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ############################################################################## */ #ifndef _JSCM_HPP_ #define _JSCM_HPP_ #undef interface #define implements public #define extends public #ifdef _MSC_VER #define interface struct __declspec(novtable) #else #define interface struct #endif interface IInterface { virtual void Link() const = 0; virtual bool Release() const = 0; }; template inline void Link(X * ptr) { if (ptr) ptr->Link(); } template inline void Release(X * ptr) { if (ptr) ptr->Release(); } #define QUERYINTERFACE(ptr, TYPE) (dynamic_cast(ptr)) //A simple object container/smart pointer template class OwnedPtr { public: inline OwnedPtr() { ptr = NULL; } inline OwnedPtr(CLASS * _ptr) { ptr = _ptr; } inline ~OwnedPtr() { delete ptr; } void operator = (CLASS * _ptr) { if (ptr) delete ptr; ptr = _ptr; } inline CLASS * operator -> () const { return ptr; } inline operator CLASS *() const { return ptr; } inline void clear() { CLASS *temp=ptr; ptr=NULL; delete temp; } inline CLASS * get() const { return ptr; } inline CLASS * getClear() { CLASS * temp = ptr; ptr = NULL; return temp; } inline void setown(CLASS * _ptr) { CLASS * temp = ptr; ptr = _ptr; delete temp; } private: inline OwnedPtr(const OwnedPtr & other); void operator = (const OwnedPtr & other); void setown(const OwnedPtr &other); private: CLASS * ptr; }; //This base class implements a shared pointer based on a link count held in the object. //The two derived classes Owned and Linked should be used as the concrete types to construct a shared object //from a pointer. template class Shared { public: inline Shared() { ptr = NULL; } inline Shared(CLASS * _ptr, bool owned) { ptr = _ptr; if (!owned && _ptr) _ptr->Link(); } inline Shared(const Shared & other) { ptr = other.getLink(); } inline ~Shared() { ::Release(ptr); } inline Shared & operator = (const Shared & other) { this->set(other.get()); return *this; } inline CLASS * operator -> () const { return ptr; } inline operator CLASS *() const { return ptr; } inline void clear() { CLASS *temp=ptr; ptr=NULL; ::Release(temp); } inline CLASS * get() const { return ptr; } inline CLASS * getClear() { CLASS * temp = ptr; ptr = NULL; return temp; } inline CLASS * getLink() const { if (ptr) ptr->Link(); return ptr; } inline void set(CLASS * _ptr) { CLASS * temp = ptr; if (temp != _ptr) { ::Link(_ptr); ptr = _ptr; ::Release(temp); } } inline void set(const Shared &other) { this->set(other.get()); } inline void setown(CLASS * _ptr) { CLASS * temp = ptr; ptr = _ptr; ::Release(temp); } inline void swap(Shared & other) { CLASS * temp = ptr; ptr = other.ptr; other.ptr = temp; } protected: inline Shared(CLASS * _ptr) { ptr = _ptr; } // deliberately protected private: inline void setown(const Shared &other); // illegal - going to cause a -ve leak inline Shared & operator = (const CLASS * other); private: CLASS * ptr; }; //An Owned Shared object takes ownership of the pointer that is passed in the constructor. template class Owned : public Shared { public: inline Owned() { } inline Owned(CLASS * _ptr) : Shared(_ptr) { } inline Shared & operator = (const Shared & other) { this->set(other.get()); return *this; } private: inline Owned(const Shared & other); // Almost certainly a bug inline Owned & operator = (const CLASS * other); }; //A Linked Shared object takes does not take ownership of the pointer that is passed in the constructor. template class Linked : public Shared { public: inline Linked() { } inline Linked(CLASS * _ptr) : Shared(LINK(_ptr)) { } inline Linked(const Shared & other) : Shared(other) { } inline Shared & operator = (const Shared & other) { this->set(other.get()); return *this; } private: inline Linked & operator = (const CLASS * other); }; // IStringVal manages returning of arbitrary null-terminated string data between systems that may not share heap managers interface IStringVal { virtual const char * str() const = 0; virtual void set(const char * val) = 0; virtual void clear() = 0; virtual void setLen(const char * val, unsigned length) = 0; virtual unsigned length() const = 0; }; // IDataVal manages returning of arbitrary unterminated binary data between systems that may not share heap managers interface IDataVal { virtual const void * data() const = 0; virtual void clear() = 0; virtual void setLen(const void * val, unsigned length) = 0; virtual unsigned length() const = 0; virtual void * reserve(unsigned length) = 0; }; // IIterator interface IIterator : extends IInterface { virtual bool first() = 0; virtual bool next() = 0; virtual bool isValid() = 0; virtual IInterface & query() = 0; virtual IInterface & get() = 0; }; template interface IIteratorOf : public IInterface { public: virtual bool first() = 0; virtual bool next() = 0; virtual bool isValid() = 0; virtual C & query() = 0; C & get() { C &c = query(); c.Link(); return c; } }; #define ForEach(i) for((i).first();(i).isValid();(i).next()) typedef IInterface * IInterfacePtr; typedef Owned OwnedIInterface; typedef Linked LinkedIInterface; template inline X * LINK(X * ptr) { if (ptr) ptr->Link(); return ptr; } template inline X & OLINK(X & obj) { obj.Link(); return obj; } template inline X * LINK(const Shared &ptr) { return ptr.getLink(); } #endif