00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef HBCIPOINTER_H
00029 #define HBCIPOINTER_H
00030
00035 #ifdef __cplusplus
00036 #include <stdio.h>
00037 #include <string>
00038
00039 #include <openhbci/error.h>
00040
00041 namespace HBCI {
00042 class PointerBase;
00043
00044 class PointerObject;
00045 template <class T> class PointerCastBase;
00046 template <class T, class U> class PointerCast;
00047 }
00048
00049 namespace HBCI {
00050
00051 #ifndef DOXYGEN_HIDE
00052
00058 class DLLIMPORT PointerObject {
00059 friend class PointerBase;
00060 private:
00061 void *_object;
00062 int _counter;
00063 bool _delete;
00064 string _descr;
00065
00066 PointerObject(void *obj, string descr=""):
00067 _object(obj),_counter(0)
00068 ,_delete(true)
00069 ,_descr(descr){
00070 };
00071 ~PointerObject(){
00072 };
00073
00074 void setDescription(string descr) {
00075
00076 _descr=descr;
00077 };
00078
00079 const string &description() const {
00080 return _descr;
00081 };
00082
00083 public:
00084
00085 };
00086
00087
00088 #endif
00089
00090
00091
00092
00100 class DLLIMPORT PointerBase {
00101 #ifndef DOXYGEN_HIDE
00102 private:
00103 PointerObject *_ptr;
00104 string _descr;
00105
00106 protected:
00107 void _attach(PointerObject &p) {
00108 _ptr=&p;
00109 if (_ptr) {
00110 _ptr->_counter++;
00111 if (_descr.empty())
00112 _descr=_ptr->_descr;
00113 }
00114 else
00115 throw HBCI::Error ("Pointer::_attach(&)",
00116 ERROR_LEVEL_NORMAL,
00117 0,
00118 ERROR_ADVISE_DONTKNOW,
00119 "No object for ."+_descr,
00120 objectDescription());
00121 };
00122
00123 void _attach(PointerObject *p) {
00124 _ptr=p;
00125 if (_ptr) {
00126 _ptr->_counter++;
00127 if (_descr.empty())
00128 _descr=_ptr->_descr;
00129 }
00130 else
00131 throw HBCI::Error ("Pointer::_attach(pt*)",
00132 ERROR_LEVEL_NORMAL,
00133 0,
00134 ERROR_ADVISE_DONTKNOW,
00135 "No object for "+_descr);
00136 };
00137
00138 void _detach() {
00139 if (_ptr) {
00140 if (_ptr->_counter>0) {
00141 _ptr->_counter--;
00142 if (_ptr->_counter<1) {
00143 if (_ptr->_delete)
00144 _deleteObject(_ptr->_object);
00145 delete _ptr;
00146 }
00147 }
00148 }
00149 _ptr=0;
00150 };
00151
00157 virtual void _deleteObject(void *p) {
00158 };
00159
00160 PointerBase(PointerBase &p): _ptr(0) {
00161 if (p._ptr)
00162 _attach(p._ptr);
00163 };
00164
00165 PointerBase(const PointerBase &p) : _ptr(0) {
00166 if (p._ptr)
00167 _attach(p._ptr);
00168 };
00169
00175 void operator=(PointerBase &p) {
00176 _detach();
00177 if (_descr.empty())
00178 _descr=p._descr;
00179 if (p._ptr)
00180 _attach(p._ptr);
00181 };
00182
00183 void operator=(const PointerBase &p) {
00184 _detach();
00185 if (_descr.empty())
00186 _descr=p._descr;
00187 if (p._ptr)
00188 _attach(p._ptr);
00189 };
00190
00196 void operator=(void* obj) {
00197 PointerObject *p;
00198 if (_ptr)
00199 _detach();
00200 _ptr=0;
00201 if (obj==0)
00202 return;
00203 p=new PointerObject(obj,_descr);
00204 _attach(p);
00205 };
00206
00210 PointerBase(): _ptr(0) {};
00211
00212 PointerBase(void *obj): _ptr(0) {
00213 PointerObject *p;
00214 p=new PointerObject(obj,_descr);
00215 _attach(p);
00216 };
00217 #endif
00218
00219 public:
00227 virtual ~PointerBase() {
00228 };
00229
00236 void setDescription(string descr) {
00237 _descr=descr;
00238 };
00239
00246 const string &description() const {
00247 return _descr;
00248 };
00249
00256 void setObjectDescription(string descr) {
00257 if (!descr.empty())
00258 if (_ptr)
00259 _ptr->setDescription(descr);
00260 };
00261
00268 string objectDescription() const {
00269 if (_ptr)
00270 return _ptr->description();
00271 else
00272 return "";
00273 };
00274
00275 virtual int refCount() const {
00276 if (_ptr)
00277 return _ptr->_counter;
00278 else
00279 return -1;
00280 };
00281
00289 bool operator==(const PointerBase &p) const {
00290 if (_ptr && p._ptr)
00291 return _ptr->_object==p._ptr->_object;
00292 else
00293 return false;
00294 };
00295
00301 bool sharingData(const PointerBase &p) const {
00302 return (_ptr==p._ptr);
00303 };
00304
00312 bool operator!=(const PointerBase &p) const {
00313 if (_ptr && p._ptr)
00314 return _ptr->_object!=p._ptr->_object;
00315 else
00316 return true;
00317 };
00318
00329 virtual void* voidptr() const {
00330 if (!_ptr)
00331 return 0;
00332 if (!(_ptr->_object))
00333 return 0;
00334 return _ptr->_object;
00335 };
00336
00337
00368 void setAutoDelete(bool b) {
00369 if (_ptr) {
00370 if (_ptr->_object)
00371 _ptr->_delete=b;
00372 }
00373 else
00374 throw HBCI::Error ("PointerBase::setAutoDelete()",
00375 ERROR_LEVEL_NORMAL,
00376 0,
00377 ERROR_ADVISE_DONTKNOW,
00378 "No object in pointer",
00379 description());
00380 };
00381
00389 bool isValid() const {
00390 if (_ptr)
00391 if (_ptr->_object)
00392 return true;
00393 return false;
00394 };
00395
00396
00397 };
00398
00399
00433 template <class T> class DLLIMPORT Pointer: public PointerBase {
00434 friend class PointerCastBase<T>;
00435 private:
00436 protected:
00442 virtual void _deleteObject(void *p) {
00443 delete (T*) p;
00444 };
00445
00446 Pointer(const PointerBase &p): PointerBase(p) {
00447 };
00448
00449 public:
00453 Pointer(): PointerBase(){};
00454
00458 Pointer(T *obj): PointerBase(obj) {
00459 };
00460
00462 Pointer(const Pointer<T> &p) : PointerBase(p) {
00463 };
00464
00473 virtual ~Pointer() {
00474 _detach();
00475 };
00476
00486 void operator=(T* obj) {
00487 PointerBase::operator=(obj);
00488 };
00489
00497 void operator=(Pointer<T> &p) {
00498 PointerBase::operator=(p);
00499 };
00500
00508 void operator=(const Pointer<T> &p) {
00509 PointerBase::operator=(p);
00510 };
00520 T& ref() const {
00521 T* p;
00522
00523 p=ptr();
00524 if (!p)
00525 throw HBCI::Error ("Pointer::ref()",
00526 ERROR_LEVEL_NORMAL,
00527 0,
00528 ERROR_ADVISE_DONTKNOW,
00529 "No object in pointer",
00530 description());
00531
00532 return *p;
00533 };
00534
00540 T& operator*() const {
00541 return ref();
00542 };
00543
00563 virtual T* ptr() const {
00564 return (T*)PointerBase::voidptr();
00565 };
00566
00567 virtual int refCount() const {
00568 return PointerBase::refCount();
00569 }
00570
00599 template <class U> Pointer<U> cast() const {
00600 return PointerCast<U,T>::cast(*this);
00601
00602
00603 };
00615 bool operator==(const Pointer<T> &p) const {
00616 return PointerBase::operator==(p);
00617 };
00618
00626 bool operator!=(const Pointer<T> &p) const {
00627 return PointerBase::operator!=(p);
00628 };
00629
00644 bool sharingData(const Pointer<T> &p) const {
00645 return PointerBase::sharingData(p);
00646 };
00649 };
00650
00651
00652 #ifndef DOXYGEN_HIDE
00653
00657 template <class T> class DLLIMPORT PointerCastBase {
00658 protected:
00659 PointerCastBase();
00660 ~PointerCastBase();
00661
00662 static Pointer<T> makePointer(const PointerBase &p) {
00663 return Pointer<T>(p);
00664 };
00665 };
00666
00667
00693 template <class T, class U> class DLLIMPORT PointerCast
00694 :public PointerCastBase<T>
00695 {
00696 public:
00705 static DLLIMPORT Pointer<T> cast(const Pointer<U> &u) {
00706 U *uo;
00707 T *t;
00708
00709
00710 if (!u.isValid())
00711 throw HBCI::Error ("PointerCast::cast",
00712 ERROR_LEVEL_NORMAL,
00713 0,
00714 ERROR_ADVISE_DONTKNOW,
00715 "No object in pointer",
00716 u.description());
00717
00718
00719 uo=u.ptr();
00720 t=dynamic_cast<T*>(uo);
00721
00722
00723 if (t==0)
00724
00725 throw HBCI::Error ("PointerCast::cast",
00726 ERROR_LEVEL_NORMAL,
00727 0,
00728 ERROR_ADVISE_DONTKNOW,
00729 "Bad cast",
00730 u.description());
00731
00732 return makePointer(u);
00733 };
00734
00735 };
00736
00737 #endif
00738
00739 }
00740 #endif
00741 #endif
00742