Commit ff00706a authored by Dimitri van Heesch's avatar Dimitri van Heesch

Added reference counting for all context objects

parent 425e64e2
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
...@@ -165,6 +165,7 @@ FTextStream::FTextStream( FILE *fh ) ...@@ -165,6 +165,7 @@ FTextStream::FTextStream( FILE *fh )
{ {
m_dev = new QFile; m_dev = new QFile;
((QFile *)m_dev)->open( IO_WriteOnly, fh); ((QFile *)m_dev)->open( IO_WriteOnly, fh);
m_owndev = TRUE;
} }
FTextStream::~FTextStream() FTextStream::~FTextStream()
......
...@@ -103,8 +103,8 @@ class TemplateVariant::Private ...@@ -103,8 +103,8 @@ class TemplateVariant::Private
int intVal; int intVal;
QCString strVal; QCString strVal;
bool boolVal; bool boolVal;
const TemplateStructIntf *strukt; TemplateStructIntf *strukt;
const TemplateListIntf *list; TemplateListIntf *list;
Delegate delegate; Delegate delegate;
bool raw; bool raw;
}; };
...@@ -145,17 +145,20 @@ TemplateVariant::TemplateVariant(const QCString &s,bool raw) ...@@ -145,17 +145,20 @@ TemplateVariant::TemplateVariant(const QCString &s,bool raw)
p->raw = raw; p->raw = raw;
} }
TemplateVariant::TemplateVariant(const TemplateStructIntf *s) TemplateVariant::TemplateVariant(TemplateStructIntf *s)
{ {
p = new Private; p = new Private;
p->type = Struct; p->type = Struct;
p->strukt = s; } p->strukt = s;
p->strukt->addRef();
}
TemplateVariant::TemplateVariant(const TemplateListIntf *l) TemplateVariant::TemplateVariant(TemplateListIntf *l)
{ {
p = new Private; p = new Private;
p->type = List; p->type = List;
p->list = l; p->list = l;
p->list->addRef();
} }
TemplateVariant::TemplateVariant(const TemplateVariant::Delegate &delegate) TemplateVariant::TemplateVariant(const TemplateVariant::Delegate &delegate)
...@@ -167,6 +170,8 @@ TemplateVariant::TemplateVariant(const TemplateVariant::Delegate &delegate) ...@@ -167,6 +170,8 @@ TemplateVariant::TemplateVariant(const TemplateVariant::Delegate &delegate)
TemplateVariant::~TemplateVariant() TemplateVariant::~TemplateVariant()
{ {
if (p->type==Struct) p->strukt->release();
else if (p->type==List) p->list->release();
delete p; delete p;
} }
...@@ -181,14 +186,20 @@ TemplateVariant::TemplateVariant(const TemplateVariant &v) ...@@ -181,14 +186,20 @@ TemplateVariant::TemplateVariant(const TemplateVariant &v)
case Bool: p->boolVal = v.p->boolVal; break; case Bool: p->boolVal = v.p->boolVal; break;
case Integer: p->intVal = v.p->intVal; break; case Integer: p->intVal = v.p->intVal; break;
case String: p->strVal = v.p->strVal; break; case String: p->strVal = v.p->strVal; break;
case Struct: p->strukt = v.p->strukt; break; case Struct: p->strukt = v.p->strukt; p->strukt->addRef(); break;
case List: p->list = v.p->list; break; case List: p->list = v.p->list; p->list->addRef(); break;
case Function: p->delegate= v.p->delegate;break; case Function: p->delegate= v.p->delegate;break;
} }
} }
TemplateVariant &TemplateVariant::operator=(const TemplateVariant &v) TemplateVariant &TemplateVariant::operator=(const TemplateVariant &v)
{ {
// assignment can change the type of the variable, so we have to be
// careful with reference counted content.
TemplateStructIntf *tmpStruct = p->type==Struct ? p->strukt : 0;
TemplateListIntf *tmpList = p->type==List ? p->list : 0;
Type tmpType = p->type;
p->type = v.p->type; p->type = v.p->type;
p->raw = v.p->raw; p->raw = v.p->raw;
switch (p->type) switch (p->type)
...@@ -197,10 +208,14 @@ TemplateVariant &TemplateVariant::operator=(const TemplateVariant &v) ...@@ -197,10 +208,14 @@ TemplateVariant &TemplateVariant::operator=(const TemplateVariant &v)
case Bool: p->boolVal = v.p->boolVal; break; case Bool: p->boolVal = v.p->boolVal; break;
case Integer: p->intVal = v.p->intVal; break; case Integer: p->intVal = v.p->intVal; break;
case String: p->strVal = v.p->strVal; break; case String: p->strVal = v.p->strVal; break;
case Struct: p->strukt = v.p->strukt; break; case Struct: p->strukt = v.p->strukt; p->strukt->addRef(); break;
case List: p->list = v.p->list; break; case List: p->list = v.p->list; p->list->addRef(); break;
case Function: p->delegate= v.p->delegate;break; case Function: p->delegate= v.p->delegate;break;
} }
// release overwritten reference counted values
if (tmpType==Struct && tmpStruct) tmpStruct->release();
else if (tmpType==List && tmpList ) tmpList->release();
return *this; return *this;
} }
...@@ -353,9 +368,10 @@ bool TemplateVariant::raw() const ...@@ -353,9 +368,10 @@ bool TemplateVariant::raw() const
class TemplateStruct::Private class TemplateStruct::Private
{ {
public: public:
Private() : fields(17) Private() : fields(17), refCount(0)
{ fields.setAutoDelete(TRUE); } { fields.setAutoDelete(TRUE); }
QDict<TemplateVariant> fields; QDict<TemplateVariant> fields;
int refCount;
}; };
TemplateStruct::TemplateStruct() TemplateStruct::TemplateStruct()
...@@ -368,6 +384,21 @@ TemplateStruct::~TemplateStruct() ...@@ -368,6 +384,21 @@ TemplateStruct::~TemplateStruct()
delete p; delete p;
} }
int TemplateStruct::addRef()
{
return ++p->refCount;
}
int TemplateStruct::release()
{
int count = --p->refCount;
if (count<=0)
{
delete this;
}
return count;
}
void TemplateStruct::set(const char *name,const TemplateVariant &v) void TemplateStruct::set(const char *name,const TemplateVariant &v)
{ {
TemplateVariant *pv = p->fields.find(name); TemplateVariant *pv = p->fields.find(name);
...@@ -387,6 +418,11 @@ TemplateVariant TemplateStruct::get(const char *name) const ...@@ -387,6 +418,11 @@ TemplateVariant TemplateStruct::get(const char *name) const
return v ? *v : TemplateVariant(); return v ? *v : TemplateVariant();
} }
TemplateStruct *TemplateStruct::alloc()
{
return new TemplateStruct;
}
//- Template list implementation ---------------------------------------------- //- Template list implementation ----------------------------------------------
...@@ -394,9 +430,10 @@ TemplateVariant TemplateStruct::get(const char *name) const ...@@ -394,9 +430,10 @@ TemplateVariant TemplateStruct::get(const char *name) const
class TemplateList::Private class TemplateList::Private
{ {
public: public:
Private() : index(-1) {} Private() : index(-1), refCount(0) {}
QValueList<TemplateVariant> elems; QValueList<TemplateVariant> elems;
int index; int index;
int refCount;
}; };
...@@ -410,6 +447,21 @@ TemplateList::~TemplateList() ...@@ -410,6 +447,21 @@ TemplateList::~TemplateList()
delete p; delete p;
} }
int TemplateList::addRef()
{
return ++p->refCount;
}
int TemplateList::release()
{
int count = --p->refCount;
if (count<=0)
{
delete this;
}
return count;
}
int TemplateList::count() const int TemplateList::count() const
{ {
return p->elems.count(); return p->elems.count();
...@@ -492,6 +544,11 @@ TemplateVariant TemplateList::at(int index) const ...@@ -492,6 +544,11 @@ TemplateVariant TemplateList::at(int index) const
} }
} }
TemplateList *TemplateList::alloc()
{
return new TemplateList;
}
//- Operator types ------------------------------------------------------------ //- Operator types ------------------------------------------------------------
/** @brief Class representing operators that can appear in template expressions */ /** @brief Class representing operators that can appear in template expressions */
...@@ -2156,14 +2213,14 @@ class TemplateNodeRepeat : public TemplateNodeCreator<TemplateNodeRepeat> ...@@ -2156,14 +2213,14 @@ class TemplateNodeRepeat : public TemplateNodeCreator<TemplateNodeRepeat>
int i, n = v.toInt(); int i, n = v.toInt();
for (i=0;i<n;i++) for (i=0;i<n;i++)
{ {
TemplateStruct s; TemplateAutoRef<TemplateStruct> s(TemplateStruct::alloc());
s.set("counter0", (int)i); s->set("counter0", (int)i);
s.set("counter", (int)(i+1)); s->set("counter", (int)(i+1));
s.set("revcounter", (int)(n-i)); s->set("revcounter", (int)(n-i));
s.set("revcounter0", (int)(n-i-1)); s->set("revcounter0", (int)(n-i-1));
s.set("first",i==0); s->set("first",i==0);
s.set("last", i==n-1); s->set("last", i==n-1);
c->set("repeatloop",&s); c->set("repeatloop",s.get());
// render all items for this iteration of the loop // render all items for this iteration of the loop
m_repeatNodes.render(ts,c); m_repeatNodes.render(ts,c);
} }
...@@ -2285,15 +2342,15 @@ class TemplateNodeRange : public TemplateNodeCreator<TemplateNodeRange> ...@@ -2285,15 +2342,15 @@ class TemplateNodeRange : public TemplateNodeCreator<TemplateNodeRange>
while (!done) while (!done)
{ {
// set the forloop meta-data variable // set the forloop meta-data variable
TemplateStruct s; TemplateAutoRef<TemplateStruct> s(TemplateStruct::alloc());
s.set("counter0", (int)index); s->set("counter0", (int)index);
s.set("counter", (int)(index+1)); s->set("counter", (int)(index+1));
s.set("revcounter", (int)(l-index)); s->set("revcounter", (int)(l-index));
s.set("revcounter0", (int)(l-index-1)); s->set("revcounter0", (int)(l-index-1));
s.set("first",index==0); s->set("first",index==0);
s.set("last", (int)index==l-1); s->set("last", (int)index==l-1);
s.set("parentloop",parentLoop ? *parentLoop : TemplateVariant()); s->set("parentloop",parentLoop ? *parentLoop : TemplateVariant());
c->set("forloop",&s); c->set("forloop",s.get());
// set the iterator variable // set the iterator variable
c->set(m_var,i); c->set(m_var,i);
...@@ -2447,15 +2504,15 @@ class TemplateNodeFor : public TemplateNodeCreator<TemplateNodeFor> ...@@ -2447,15 +2504,15 @@ class TemplateNodeFor : public TemplateNodeCreator<TemplateNodeFor>
(it->current(v)); (it->current(v));
m_reversed ? it->toPrev() : it->toNext()) m_reversed ? it->toPrev() : it->toNext())
{ {
TemplateStruct s; TemplateAutoRef<TemplateStruct> s(TemplateStruct::alloc());
s.set("counter0", (int)index); s->set("counter0", (int)index);
s.set("counter", (int)(index+1)); s->set("counter", (int)(index+1));
s.set("revcounter", (int)(listSize-index)); s->set("revcounter", (int)(listSize-index));
s.set("revcounter0", (int)(listSize-index-1)); s->set("revcounter0", (int)(listSize-index-1));
s.set("first",index==0); s->set("first",index==0);
s.set("last", index==listSize-1); s->set("last", index==listSize-1);
s.set("parentloop",parentLoop ? *parentLoop : TemplateVariant()); s->set("parentloop",parentLoop ? *parentLoop : TemplateVariant());
c->set("forloop",&s); c->set("forloop",s.get());
// add variables for this loop to the context // add variables for this loop to the context
//obj->addVariableToContext(index,m_vars,c); //obj->addVariableToContext(index,m_vars,c);
...@@ -2582,9 +2639,9 @@ class TemplateNodeBlock : public TemplateNodeCreator<TemplateNodeBlock> ...@@ -2582,9 +2639,9 @@ class TemplateNodeBlock : public TemplateNodeCreator<TemplateNodeBlock>
m_nodes.render(ss,c); // render parent of nb to string m_nodes.render(ss,c); // render parent of nb to string
} }
// add 'block.super' variable to allow access to parent block content // add 'block.super' variable to allow access to parent block content
TemplateStruct superBlock; TemplateAutoRef<TemplateStruct> superBlock(TemplateStruct::alloc());
superBlock.set("super",TemplateVariant(super.data(),TRUE)); superBlock->set("super",TemplateVariant(super.data(),TRUE));
ci->set("block",&superBlock); ci->set("block",superBlock.get());
// render the overruled block contents // render the overruled block contents
t->engine()->enterBlock(nb->m_templateName,nb->m_blockName,nb->m_line); t->engine()->enterBlock(nb->m_templateName,nb->m_blockName,nb->m_line);
nb->m_nodes.render(ts,c); nb->m_nodes.render(ts,c);
...@@ -3235,9 +3292,9 @@ class TemplateNodeMarkers : public TemplateNodeCreator<TemplateNodeMarkers> ...@@ -3235,9 +3292,9 @@ class TemplateNodeMarkers : public TemplateNodeCreator<TemplateNodeMarkers>
for (it->toFirst(); (it->current(var)) && i<entryIndex; it->toNext(),i++) {} for (it->toFirst(); (it->current(var)) && i<entryIndex; it->toNext(),i++) {}
if (ok && i==entryIndex) // found element if (ok && i==entryIndex) // found element
{ {
TemplateStruct s; TemplateAutoRef<TemplateStruct> s(TemplateStruct::alloc());
s.set("id",(int)i); s->set("id",(int)i);
c->set("markers",&s); c->set("markers",s.get());
c->set(m_var,var); // define local variable to hold element of list type c->set(m_var,var); // define local variable to hold element of list type
bool wasSpaceless = ci->spacelessEnabled(); bool wasSpaceless = ci->spacelessEnabled();
ci->enableSpaceless(TRUE); ci->enableSpaceless(TRUE);
......
...@@ -145,16 +145,14 @@ class TemplateVariant ...@@ -145,16 +145,14 @@ class TemplateVariant
TemplateVariant(const QCString &s,bool raw=FALSE); TemplateVariant(const QCString &s,bool raw=FALSE);
/** Constructs a new variant with a struct value \a s. /** Constructs a new variant with a struct value \a s.
* @note. Only a pointer to the struct is stored. The caller * @note. The variant will hold a reference to the object.
* is responsible to manage the memory for the struct object.
*/ */
TemplateVariant(const TemplateStructIntf *s); TemplateVariant(TemplateStructIntf *s);
/** Constructs a new variant with a list value \a l. /** Constructs a new variant with a list value \a l.
* @note. Only a pointer to the struct is stored. The caller * @note. The variant will hold a reference to the object.
* is responsible to manage the memory for the list object.
*/ */
TemplateVariant(const TemplateListIntf *l); TemplateVariant(TemplateListIntf *l);
/** Constructs a new variant which represents a method call /** Constructs a new variant which represents a method call
* @param[in] delegate Delegate object to invoke when * @param[in] delegate Delegate object to invoke when
...@@ -223,6 +221,27 @@ class TemplateVariant ...@@ -223,6 +221,27 @@ class TemplateVariant
//------------------------------------------------------------------------ //------------------------------------------------------------------------
template<class T> class TemplateAutoRef
{
public:
TemplateAutoRef(T *obj) : m_obj(obj)
{
m_obj->addRef();
}
~TemplateAutoRef()
{
m_obj->release();
}
T &operator*() const { return *m_obj; }
T *operator->() const { return m_obj; }
T *get() const { return m_obj; }
private:
T *m_obj;
};
//------------------------------------------------------------------------
/** @brief Abstract read-only interface for a context value of type list. /** @brief Abstract read-only interface for a context value of type list.
* @note The values of the list are TemplateVariants. * @note The values of the list are TemplateVariants.
*/ */
...@@ -264,26 +283,37 @@ class TemplateListIntf ...@@ -264,26 +283,37 @@ class TemplateListIntf
* @note the user should call delete on the returned pointer. * @note the user should call delete on the returned pointer.
*/ */
virtual TemplateListIntf::ConstIterator *createIterator() const = 0; virtual TemplateListIntf::ConstIterator *createIterator() const = 0;
/** Increase object's reference count */
virtual int addRef() = 0;
/** Decreases object's referenc count, destroy object if 0 */
virtual int release() = 0;
}; };
/** @brief Default implementation of a context value of type list. */ /** @brief Default implementation of a context value of type list. */
class TemplateList : public TemplateListIntf class TemplateList : public TemplateListIntf
{ {
public: public:
/** Creates a list */
TemplateList();
/** Destroys the list */
~TemplateList();
// TemplateListIntf methods // TemplateListIntf methods
virtual int count() const; virtual int count() const;
virtual TemplateVariant at(int index) const; virtual TemplateVariant at(int index) const;
virtual TemplateListIntf::ConstIterator *createIterator() const; virtual TemplateListIntf::ConstIterator *createIterator() const;
virtual int addRef();
virtual int release();
/** Creates an instance with ref count set to 0 */
static TemplateList *alloc();
/** Appends element \a v to the end of the list */ /** Appends element \a v to the end of the list */
virtual void append(const TemplateVariant &v); virtual void append(const TemplateVariant &v);
private: private:
/** Creates a list */
TemplateList();
/** Destroys the list */
~TemplateList();
friend class TemplateListConstIterator; friend class TemplateListConstIterator;
class Private; class Private;
Private *p; Private *p;
...@@ -302,6 +332,12 @@ class TemplateStructIntf ...@@ -302,6 +332,12 @@ class TemplateStructIntf
* @param[in] name The name of the field. * @param[in] name The name of the field.
*/ */
virtual TemplateVariant get(const char *name) const = 0; virtual TemplateVariant get(const char *name) const = 0;
/** Increase object's reference count */
virtual int addRef() = 0;
/** Decreases object's referenc count, destroy object if 0 */
virtual int release() = 0;
}; };
...@@ -309,13 +345,13 @@ class TemplateStructIntf ...@@ -309,13 +345,13 @@ class TemplateStructIntf
class TemplateStruct : public TemplateStructIntf class TemplateStruct : public TemplateStructIntf
{ {
public: public:
/** Creates a struct */
TemplateStruct();
/** Destroys the struct */
virtual ~TemplateStruct();
// TemplateStructIntf methods // TemplateStructIntf methods
virtual TemplateVariant get(const char *name) const; virtual TemplateVariant get(const char *name) const;
virtual int addRef();
virtual int release();
/** Creates an instance with ref count set to 0. */
static TemplateStruct *alloc();
/** Sets the value the field of a struct /** Sets the value the field of a struct
* @param[in] name The name of the field. * @param[in] name The name of the field.
...@@ -323,7 +359,13 @@ class TemplateStruct : public TemplateStructIntf ...@@ -323,7 +359,13 @@ class TemplateStruct : public TemplateStructIntf
*/ */
virtual void set(const char *name,const TemplateVariant &v); virtual void set(const char *name,const TemplateVariant &v);
private: private:
/** Creates a struct */
TemplateStruct();
/** Destroys the struct */
virtual ~TemplateStruct();
class Private; class Private;
Private *p; Private *p;
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment