[AGENT++] Code duplication in MibTable ...

Jens Engel Jens.Engel at marconi.com
Wed Mar 1 18:13:30 CET 2006


MibTable contains a lot of code duplication that depends on the internal
MibTableRow column-container implementation.

BAD-EXAMPLE:
void MibTable::get_required_columns(boolean* required, Vbx* pvbs)
{
#ifndef USE_ARRAY_TEMPLATE
      OrderedListCursor<MibLeaf> cur;
      int i;
      for (cur.init(&generator.row), i=0; cur.get(); cur.next(), i++) {
            if ((cur.get()->get_access() == READCREATE) &&
                (!cur.get()->has_default()))
                  required[i] = TRUE;
            else {
                  required[i] = FALSE;
                  if (pvbs)
                        pvbs[i] = cur.get()->get_value();
            }
      }
#else
      for (int i=0; i<generator.row.size(); i++) {
            if ((generator.row[i].get_access() == READCREATE) &&
                (!generator.row[i].has_default()))
                  required[i] = TRUE;
            else {
                  required[i] = FALSE;
                  if (pvbs)
                        pvbs[i] = generator.row[i].get_value();
            }
      }
#endif
}

SLIGHTLY-IMPROVED-EXAMPLE (from existing code base, but why not used
everywhere):
...
#ifdef USE_ARRAY_TEMPLATE
            ArrayCursor<MibLeaf> cur;
#else
            OrderedListCursor<MibLeaf> cur;
#endif

DESIRED:
      MibTableRow::Cursor_t cur;
      ...

In my opinion, this code duplication is completely pointless and should be
removed
(as was partly done in some MibTable method bodies that replicates my
solution below in its own context (SLIGHTLY-IMPROVED-EXAMPLE)).
You only need to provide a public Cursor_t type definition dependent on the
internal container class
and remove all #ifdef sections in the MibTable class.

SOLUTION-EXAMPLE:
class MibTableRow {
...

public:
#  ifdef USE_ARRAY_TEMPLATE
    typedef ArrayCursor<Agentpp::MibLeaf> Cursor_t;
#  else
    typedef OrderedListCursor<Agentpp::MibLeaf> Cursor_t;
#  endif
    // -- FRIENDLESS ACCESSOR: Allow row.column cursor iteration in a
derived MibTable class without being a friend.
    Cursor_t cursor(void) const { Cursor_t cur; cur.init(&row); return cur;
}
#endif
};

USAGE-EXAMPLE WITH MY SOLUTION (changed from above):
void MibTable::get_required_columns(boolean* required, Vbx* pvbs)
{
      MibTableRow::Cursor_t cur(generator.cursor());
      for (int i=0; cur.get(); cur.next(), i++) {
            if ((cur.get()->get_access() == READCREATE) &&
                (!cur.get()->has_default()))
                  required[i] = TRUE;
            else {
                  required[i] = FALSE;
                  if (pvbs)
                        pvbs[i] = cur.get()->get_value();
            }
      }
}

NOTE:
MibTable::init_row() uses a ListCursor<> instead of a OrderedListCursor<>
!?!
If multiple cursor categories are needed, multiple typedefs and accessors
should be provided.

Ciao,
Jens Engel





More information about the AGENTPP mailing list