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

Added reference counting for all context objects

parent 425e64e2
Loading
Loading
Loading
Loading
+563 −472

File changed.

Preview size limit exceeded, changes collapsed.

+397 −192

File changed.

Preview size limit exceeded, changes collapsed.

+1 −0
Original line number Diff line number Diff line
@@ -165,6 +165,7 @@ FTextStream::FTextStream( FILE *fh )
{
  m_dev = new QFile;
  ((QFile *)m_dev)->open( IO_WriteOnly, fh);
  m_owndev = TRUE;
}

FTextStream::~FTextStream()
+100 −43
Original line number Diff line number Diff line
@@ -103,8 +103,8 @@ class TemplateVariant::Private
    int                 intVal;
    QCString            strVal;
    bool                boolVal;
    const TemplateStructIntf *strukt;
    const TemplateListIntf   *list;
    TemplateStructIntf *strukt;
    TemplateListIntf   *list;
    Delegate            delegate;
    bool                raw;
};
@@ -145,17 +145,20 @@ TemplateVariant::TemplateVariant(const QCString &s,bool raw)
  p->raw = raw;
}

TemplateVariant::TemplateVariant(const TemplateStructIntf *s)
TemplateVariant::TemplateVariant(TemplateStructIntf *s)
{
  p = new Private;
  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->type = List;
  p->list = l;
  p->list->addRef();
}

TemplateVariant::TemplateVariant(const TemplateVariant::Delegate &delegate)
@@ -167,6 +170,8 @@ TemplateVariant::TemplateVariant(const TemplateVariant::Delegate &delegate)

TemplateVariant::~TemplateVariant()
{
  if (p->type==Struct) p->strukt->release();
  else if (p->type==List) p->list->release();
  delete p;
}

@@ -181,14 +186,20 @@ TemplateVariant::TemplateVariant(const TemplateVariant &v)
    case Bool:     p->boolVal = v.p->boolVal; break;
    case Integer:  p->intVal  = v.p->intVal;  break;
    case String:   p->strVal  = v.p->strVal;  break;
    case Struct:   p->strukt  = v.p->strukt;  break;
    case List:     p->list    = v.p->list;    break;
    case Struct:   p->strukt  = v.p->strukt;  p->strukt->addRef(); break;
    case List:     p->list    = v.p->list;    p->list->addRef();   break;
    case Function: p->delegate= v.p->delegate;break;
  }
}

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->raw     = v.p->raw;
  switch (p->type)
@@ -197,10 +208,14 @@ TemplateVariant &TemplateVariant::operator=(const TemplateVariant &v)
    case Bool:     p->boolVal = v.p->boolVal; break;
    case Integer:  p->intVal  = v.p->intVal;  break;
    case String:   p->strVal  = v.p->strVal;  break;
    case Struct:   p->strukt  = v.p->strukt;  break;
    case List:     p->list    = v.p->list;    break;
    case Struct:   p->strukt  = v.p->strukt;  p->strukt->addRef(); break;
    case List:     p->list    = v.p->list;    p->list->addRef();   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;
}

@@ -353,9 +368,10 @@ bool TemplateVariant::raw() const
class TemplateStruct::Private
{
  public:
    Private() : fields(17)
    Private() : fields(17), refCount(0)
    { fields.setAutoDelete(TRUE); }
    QDict<TemplateVariant> fields;
    int refCount;
};

TemplateStruct::TemplateStruct()
@@ -368,6 +384,21 @@ TemplateStruct::~TemplateStruct()
  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)
{
  TemplateVariant *pv = p->fields.find(name);
@@ -387,6 +418,11 @@ TemplateVariant TemplateStruct::get(const char *name) const
  return v ? *v : TemplateVariant();
}

TemplateStruct *TemplateStruct::alloc()
{
  return new TemplateStruct;
}

//- Template list implementation ----------------------------------------------


@@ -394,9 +430,10 @@ TemplateVariant TemplateStruct::get(const char *name) const
class TemplateList::Private
{
  public:
    Private() : index(-1) {}
    Private() : index(-1), refCount(0) {}
    QValueList<TemplateVariant> elems;
    int index;
    int refCount;
};


@@ -410,6 +447,21 @@ TemplateList::~TemplateList()
  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
{
  return p->elems.count();
@@ -492,6 +544,11 @@ TemplateVariant TemplateList::at(int index) const
  }
}

TemplateList *TemplateList::alloc()
{
  return new TemplateList;
}

//- Operator types ------------------------------------------------------------

/** @brief Class representing operators that can appear in template expressions */
@@ -2156,14 +2213,14 @@ class TemplateNodeRepeat : public TemplateNodeCreator<TemplateNodeRepeat>
        int i, n = v.toInt();
        for (i=0;i<n;i++)
        {
          TemplateStruct s;
          s.set("counter0",    (int)i);
          s.set("counter",     (int)(i+1));
          s.set("revcounter",  (int)(n-i));
          s.set("revcounter0", (int)(n-i-1));
          s.set("first",i==0);
          s.set("last", i==n-1);
          c->set("repeatloop",&s);
          TemplateAutoRef<TemplateStruct> s(TemplateStruct::alloc());
          s->set("counter0",    (int)i);
          s->set("counter",     (int)(i+1));
          s->set("revcounter",  (int)(n-i));
          s->set("revcounter0", (int)(n-i-1));
          s->set("first",i==0);
          s->set("last", i==n-1);
          c->set("repeatloop",s.get());
          // render all items for this iteration of the loop
          m_repeatNodes.render(ts,c);
        }
@@ -2285,15 +2342,15 @@ class TemplateNodeRange : public TemplateNodeCreator<TemplateNodeRange>
            while (!done)
            {
              // set the forloop meta-data variable
              TemplateStruct s;
              s.set("counter0",    (int)index);
              s.set("counter",     (int)(index+1));
              s.set("revcounter",  (int)(l-index));
              s.set("revcounter0", (int)(l-index-1));
              s.set("first",index==0);
              s.set("last", (int)index==l-1);
              s.set("parentloop",parentLoop ? *parentLoop : TemplateVariant());
              c->set("forloop",&s);
              TemplateAutoRef<TemplateStruct> s(TemplateStruct::alloc());
              s->set("counter0",    (int)index);
              s->set("counter",     (int)(index+1));
              s->set("revcounter",  (int)(l-index));
              s->set("revcounter0", (int)(l-index-1));
              s->set("first",index==0);
              s->set("last", (int)index==l-1);
              s->set("parentloop",parentLoop ? *parentLoop : TemplateVariant());
              c->set("forloop",s.get());

              // set the iterator variable
              c->set(m_var,i);
@@ -2447,15 +2504,15 @@ class TemplateNodeFor : public TemplateNodeCreator<TemplateNodeFor>
              (it->current(v));
              m_reversed ? it->toPrev() : it->toNext())
          {
            TemplateStruct s;
            s.set("counter0",    (int)index);
            s.set("counter",     (int)(index+1));
            s.set("revcounter",  (int)(listSize-index));
            s.set("revcounter0", (int)(listSize-index-1));
            s.set("first",index==0);
            s.set("last", index==listSize-1);
            s.set("parentloop",parentLoop ? *parentLoop : TemplateVariant());
            c->set("forloop",&s);
            TemplateAutoRef<TemplateStruct> s(TemplateStruct::alloc());
            s->set("counter0",    (int)index);
            s->set("counter",     (int)(index+1));
            s->set("revcounter",  (int)(listSize-index));
            s->set("revcounter0", (int)(listSize-index-1));
            s->set("first",index==0);
            s->set("last", index==listSize-1);
            s->set("parentloop",parentLoop ? *parentLoop : TemplateVariant());
            c->set("forloop",s.get());

            // add variables for this loop to the context
            //obj->addVariableToContext(index,m_vars,c);
@@ -2582,9 +2639,9 @@ class TemplateNodeBlock : public TemplateNodeCreator<TemplateNodeBlock>
            m_nodes.render(ss,c); // render parent of nb to string
          }
          // add 'block.super' variable to allow access to parent block content
          TemplateStruct superBlock;
          superBlock.set("super",TemplateVariant(super.data(),TRUE));
          ci->set("block",&superBlock);
          TemplateAutoRef<TemplateStruct> superBlock(TemplateStruct::alloc());
          superBlock->set("super",TemplateVariant(super.data(),TRUE));
          ci->set("block",superBlock.get());
          // render the overruled block contents
          t->engine()->enterBlock(nb->m_templateName,nb->m_blockName,nb->m_line);
          nb->m_nodes.render(ts,c);
@@ -3235,9 +3292,9 @@ class TemplateNodeMarkers : public TemplateNodeCreator<TemplateNodeMarkers>
              for (it->toFirst(); (it->current(var)) && i<entryIndex; it->toNext(),i++) {}
              if (ok && i==entryIndex) // found element
              {
                TemplateStruct s;
                s.set("id",(int)i);
                c->set("markers",&s);
                TemplateAutoRef<TemplateStruct> s(TemplateStruct::alloc());
                s->set("id",(int)i);
                c->set("markers",s.get());
                c->set(m_var,var); // define local variable to hold element of list type
                bool wasSpaceless = ci->spacelessEnabled();
                ci->enableSpaceless(TRUE);
+58 −16
Original line number Diff line number Diff line
@@ -145,16 +145,14 @@ class TemplateVariant
    TemplateVariant(const QCString &s,bool raw=FALSE);

    /** Constructs a new variant with a struct value \a s.
     *  @note. Only a pointer to the struct is stored. The caller
     *  is responsible to manage the memory for the struct object.
     *  @note. The variant will hold a reference to the object.
     */
    TemplateVariant(const TemplateStructIntf *s);
    TemplateVariant(TemplateStructIntf *s);

    /** Constructs a new variant with a list value \a l.
     *  @note. Only a pointer to the struct is stored. The caller
     *  is responsible to manage the memory for the list object.
     *  @note. The variant will hold a reference to the object.
     */
    TemplateVariant(const TemplateListIntf *l);
    TemplateVariant(TemplateListIntf *l);

    /** Constructs a new variant which represents a method call
     *  @param[in] delegate Delegate object to invoke when
@@ -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.
 *  @note The values of the list are TemplateVariants.
 */
@@ -264,26 +283,37 @@ class TemplateListIntf
     *  @note the user should call delete on the returned pointer.
     */
    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. */
class TemplateList : public TemplateListIntf
{
  public:
    /** Creates a list */
    TemplateList();
    /** Destroys the list */
   ~TemplateList();

    // TemplateListIntf methods
    virtual int  count() const;
    virtual TemplateVariant at(int index) 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 */
    virtual void append(const TemplateVariant &v);

  private:
    /** Creates a list */
    TemplateList();
    /** Destroys the list */
   ~TemplateList();

    friend class TemplateListConstIterator;
    class Private;
    Private *p;
@@ -302,6 +332,12 @@ class TemplateStructIntf
     *  @param[in] name The name of the field.
     */
    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
class TemplateStruct : public TemplateStructIntf
{
  public:
    /** Creates a struct */
    TemplateStruct();
    /** Destroys the struct */
    virtual ~TemplateStruct();

    // TemplateStructIntf methods
    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
     *  @param[in] name The name of the field.
@@ -323,7 +359,13 @@ class TemplateStruct : public TemplateStructIntf
     */
    virtual void set(const char *name,const TemplateVariant &v);


  private:
    /** Creates a struct */
    TemplateStruct();
    /** Destroys the struct */
    virtual ~TemplateStruct();

    class Private;
    Private *p;
};