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