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
00029
00030 #ifndef CTPOINTER_H
00031 #define CTPOINTER_H
00032
00033
00034 #include <stdio.h>
00035 #include <string>
00036
00037 #include <chipcard/cterror.h>
00038
00039
00040 class CTPointerBase;
00041
00042 class CTPointerObject;
00043 template <class T> class CTPointerCastBase;
00044 template <class T, class U> class CTPointerCast;
00045
00046
00047
00048 #ifndef DOXYGEN
00049
00054 class CHIPCARD_API CTPointerObject {
00055 friend class CTPointerBase;
00056 private:
00057 void *_object;
00058 int _counter;
00059 bool _delete;
00060 string _descr;
00061
00062 CTPointerObject(void *obj, string descr=""):
00063 _object(obj),_counter(0)
00064 ,_delete(true)
00065 ,_descr(descr){
00066 };
00067 ~CTPointerObject(){
00068 };
00069
00070 void setDescription(string descr) {
00071
00072 _descr=descr;
00073 };
00074
00075 const string &description() const {
00076 return _descr;
00077 };
00078 int counter() const { return _counter;};
00079 public:
00080
00081 };
00082 #endif
00083
00084
00085
00086
00087
00097 class CHIPCARD_API CTPointerBase {
00098 #ifndef DOXYGEN
00099 private:
00100 CTPointerObject *_ptr;
00101 string _descr;
00102
00103 protected:
00104 void _attach(CTPointerObject &p) {
00105 _ptr=&p;
00106 if (_ptr) {
00107 _ptr->_counter++;
00108 if (_descr.empty())
00109 _descr=_ptr->_descr;
00110 }
00111 else
00112 throw CTError("CTCTPointer::_attach(&)",
00113 k_CTERROR_POINTER,0,0,
00114 "No object for "+_descr);
00115 };
00116
00117 void _attach(CTPointerObject *p) {
00118 _ptr=p;
00119 if (_ptr) {
00120 _ptr->_counter++;
00121 if (_descr.empty())
00122 _descr=_ptr->_descr;
00123 }
00124 else
00125 throw CTError("CTCTPointer::_attach(*)",
00126 k_CTERROR_POINTER,0,0,
00127 "No object for "+_descr);
00128 };
00129
00130 void _detach() {
00131 if (_ptr) {
00132 if (_ptr->_counter>0) {
00133 _ptr->_counter--;
00134 if (_ptr->_counter<1) {
00135 if (_ptr->_delete)
00136 _deleteObject(_ptr->_object);
00137 delete _ptr;
00138 }
00139 }
00140 }
00141 _ptr=0;
00142 };
00143
00149 virtual void _deleteObject(void *p) {
00150 };
00151
00152 CTPointerBase(CTPointerBase &p): _ptr(0) {
00153 if (p._ptr)
00154 _attach(p._ptr);
00155 };
00156
00157 CTPointerBase(const CTPointerBase &p) : _ptr(0) {
00158 if (p._ptr)
00159 _attach(p._ptr);
00160 };
00161
00167 void operator=(CTPointerBase &p) {
00168 _detach();
00169 if (_descr.empty())
00170 _descr=p._descr;
00171 if (p._ptr)
00172 _attach(p._ptr);
00173 };
00174
00175 void operator=(const CTPointerBase &p) {
00176 _detach();
00177 if (_descr.empty())
00178 _descr=p._descr;
00179 if (p._ptr)
00180 _attach(p._ptr);
00181 };
00182
00188 void operator=(void* obj) {
00189 CTPointerObject *p;
00190 if (_ptr)
00191 _detach();
00192 _ptr=0;
00193 if (obj==0)
00194 return;
00195 p=new CTPointerObject(obj,_descr);
00196 _attach(p);
00197 };
00198
00202 CTPointerBase(): _ptr(0) {};
00203
00204 CTPointerBase(void *obj): _ptr(0) {
00205 CTPointerObject *p;
00206 p=new CTPointerObject(obj,_descr);
00207 _attach(p);
00208 };
00209 #endif
00210 public:
00218 virtual ~CTPointerBase() {
00219 };
00220
00227 void setDescription(string descr) {
00228 _descr=descr;
00229 };
00230
00237 const string &description() const {
00238 return _descr;
00239 };
00240
00247 void setObjectDescription(string descr) {
00248 if (!descr.empty())
00249 if (_ptr)
00250 _ptr->setDescription(descr);
00251 };
00252
00259 string objectDescription() const {
00260 if (_ptr)
00261 return _ptr->description();
00262 else
00263 return "";
00264 };
00265
00272 int referenceCount() const {
00273 if (_ptr)
00274 return _ptr->counter();
00275 else
00276 return -1;
00277 };
00278
00286 bool operator==(const CTPointerBase &p) const {
00287 if (_ptr && p._ptr)
00288 return _ptr->_object==p._ptr->_object;
00289 else
00290 return false;
00291 };
00292
00298 bool sharingData(const CTPointerBase &p) const {
00299 return (_ptr==p._ptr);
00300 };
00301
00309 bool operator!=(const CTPointerBase &p) const {
00310 if (_ptr && p._ptr)
00311 return _ptr->_object!=p._ptr->_object;
00312 else
00313 return true;
00314 };
00315
00326 virtual void* voidptr() const {
00327 if (!_ptr)
00328 return 0;
00329 if (!(_ptr->_object))
00330 return 0;
00331 return _ptr->_object;
00332 };
00333
00334
00365 void setAutoDelete(bool b) {
00366 if (_ptr) {
00367 if (_ptr->_object)
00368 _ptr->_delete=b;
00369 }
00370 else
00371 throw CTError("CTCTPointer::setAutoDelete()",
00372 k_CTERROR_POINTER,0,0,
00373 "No object for "+description());
00374 };
00375
00383 bool isValid() const {
00384 if (_ptr)
00385 if (_ptr->_object)
00386 return true;
00387 return false;
00388 };
00389
00390
00391 };
00392
00393
00429 template <class T> class CHIPCARD_API CTPointer: public CTPointerBase {
00430 friend class CTPointerCastBase<T>;
00431 private:
00432 protected:
00438 virtual void _deleteObject(void *p) {
00439 delete (T*) p;
00440 };
00441
00442 CTPointer(const CTPointerBase &p): CTPointerBase(p) {
00443 };
00444
00445 public:
00449 CTPointer(): CTPointerBase(){};
00450
00454 CTPointer(T *obj): CTPointerBase(obj) {
00455 };
00456
00458 CTPointer(const CTPointer<T> &p) : CTPointerBase(p) {
00459 };
00460
00469 virtual ~CTPointer() {
00470 _detach();
00471 };
00472
00482 void operator=(T* obj) {
00483 CTPointerBase::operator=(obj);
00484 };
00485
00493 void operator=(CTPointer<T> &p) {
00494 CTPointerBase::operator=(p);
00495 };
00496
00504 void operator=(const CTPointer<T> &p) {
00505 CTPointerBase::operator=(p);
00506 };
00508
00516 T& ref() const {
00517 T* p;
00518
00519 p=ptr();
00520 if (!p)
00521 throw CTError("CTCTPointer::ref()",
00522 k_CTERROR_POINTER,0,0,
00523 "No object for "+description());
00524 return *p;
00525 };
00526
00532 T& operator*() const {
00533 return ref();
00534 };
00535
00555 virtual T* ptr() const {
00556 return (T*)CTPointerBase::voidptr();
00557 };
00559
00586 template <class U> CTPointer<U> cast() const {
00587 return CTPointerCast<U,T>::cast(*this);
00588
00589
00590 };
00591
00593
00603 bool operator==(const CTPointer<T> &p) const {
00604 return CTPointerBase::operator==(p);
00605 };
00606
00614 bool operator!=(const CTPointer<T> &p) const {
00615 return CTPointerBase::operator!=(p);
00616 };
00617
00632 bool sharingData(const CTPointer<T> &p) const {
00633 return CTPointerBase::sharingData(p);
00634 };
00636
00637 };
00638
00639
00640 #ifndef DOXYGEN
00641
00645 template <class T> class CHIPCARD_API CTPointerCastBase {
00646 protected:
00647 CTPointerCastBase();
00648 ~CTPointerCastBase();
00649
00650 static CTPointer<T> makeCTPointer(const CTPointerBase &p) {
00651 return CTPointer<T>(p);
00652 };
00653 };
00654
00655
00681 template <class T, class U> class CHIPCARD_API CTPointerCast
00682 :public CTPointerCastBase<T>
00683 {
00684 public:
00693 static CHIPCARD_API CTPointer<T> cast(const CTPointer<U> &u) {
00694 U *uo;
00695 T *t;
00696
00697
00698 if (!u.isValid())
00699 throw CTError("CTPointerCast::cast()",
00700 k_CTERROR_POINTER,0,0,
00701 "No object for "+u.description());
00702
00703
00704 uo=u.ptr();
00705 t=dynamic_cast<T*>(uo);
00706
00707
00708 if (t==0)
00709
00710 throw CTError("CTCTPointerCast::cast()",
00711 k_CTERROR_POINTER,0,0,
00712 "Bad cast "+u.description());
00713
00714 return makeCTPointer(u);
00715 };
00716
00717 };
00718
00719 #endif
00720
00721 #endif
00722
00723