#include <net-snmp/net-snmp-config.h>

#if HAVE_STRING_H
#include <string.h>
#else
#include <strings.h>
#endif

#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>

#include <net-snmp/agent/table.h>
#include <net-snmp/agent/table_data.h>
#include <net-snmp/agent/read_only.h>

/** @defgroup table_data table_data
 *  Helps you implement a table with datamatted storage.
 *  @ingroup table
 *
 *  This helper is obsolete.  If you are writing a new module, please
 *  consider using the table_tdata helper instead.
 *
 *  This helper helps you implement a table where all the indexes are
 *  expected to be stored within the agent itself and not in some
 *  external storage location.  It can be used to store a list of
 *  rows, where a row consists of the indexes to the table and a
 *  generic data pointer.  You can then implement a subhandler which
 *  is passed the exact row definition and data it must return data
 *  for or accept data for.  Complex GETNEXT handling is greatly
 *  simplified in this case.
 *
 *  @{
 */

/* ==================================
 *
 * Table Data API: Table maintenance
 *
 * ================================== */

/*
 * generates the index portion of an table oid from a varlist.
 */
void
netsnmp_table_data_generate_index_oid(netsnmp_table_row *row)
{
    build_oid(&row->index_oid, &row->index_oid_len, NULL, 0, row->indexes);
}

/** creates and returns a pointer to table data set */
netsnmp_table_data *
netsnmp_create_table_data(const char *name)
{
    netsnmp_table_data *table = SNMP_MALLOC_TYPEDEF(netsnmp_table_data);
    if (name && table)
        table->name = strdup(name);
    return table;
}

/** creates and returns a pointer to table data set */
netsnmp_table_row *
netsnmp_create_table_data_row(void)
{
    netsnmp_table_row *row = SNMP_MALLOC_TYPEDEF(netsnmp_table_row);
    return row;
}

/** clones a data row. DOES NOT CLONE THE CONTAINED DATA. */
netsnmp_table_row *
netsnmp_table_data_clone_row(netsnmp_table_row *row)
{
    netsnmp_table_row *newrow = NULL;
    if (!row)
        return NULL;

    newrow = netsnmp_memdup(row, sizeof(netsnmp_table_row));
    if (!newrow)
        return NULL;

    if (row->indexes) {
        newrow->indexes = snmp_clone_varbind(newrow->indexes);
        if (!newrow->indexes) {
            free (newrow);
            return NULL;
        }
    }

    if (row->index_oid) {
        newrow->index_oid = netsnmp_memdup(row->index_oid,
                                           row->index_oid_len * sizeof(oid));
        if (!newrow->index_oid) {
            free (newrow);
            return NULL;
        }
    }

    return newrow;
}

/** deletes a row's memory.
 *  returns the void data that it doesn't know how to delete. */
void           *
netsnmp_table_data_delete_row(netsnmp_table_row *row)
{
    void           *data;

    if (!row)
        return NULL;

    /*
     * free the memory we can 
     */
    if (row->indexes)
        snmp_free_varbind(row->indexes);
    SNMP_FREE(row->index_oid);
    data = row->data;
    free(row);

    /*
     * return the void * pointer 
     */
    return data;
}

/**
 * Adds a row of data to a given table (stored in proper lexographical order).
 *
 * returns SNMPERR_SUCCESS on successful addition.
 *      or SNMPERR_GENERR  on failure (E.G., indexes already existed)
 */
int
netsnmp_table_data_add_row(netsnmp_table_data *table,
                           netsnmp_table_row *row)
{
    int rc, dup = 0;
    netsnmp_table_row *nextrow = NULL, *prevrow;

    if (!row || !table)
        return SNMPERR_GENERR;

    if (row->indexes)
        netsnmp_table_data_generate_index_oid(row);

    /*
     * we don't store the index info as it
     * takes up memory. 
     */
    if (!table->store_indexes) {
        snmp_free_varbind(row->indexes);
        row->indexes = NULL;
    }

    if (!row->index_oid) {
        snmp_log(LOG_ERR,
                 "illegal data attempted to be added to table %s (no index)\n",
                 table->name);
        return SNMPERR_GENERR;
    }

    /*
     * check for simple append
     */
    if ((prevrow = table->last_row) != NULL) {
        rc = snmp_oid_compare(prevrow->index_oid, prevrow->index_oid_len,
                              row->index_oid, row->index_oid_len);
        if (0 == rc)
            dup = 1;
    }
    else
        rc = 1;
    
    /*
     * if no last row, or newrow < last row, search the table and
     * insert it into the table in the proper oid-lexographical order 
     */
    if (rc > 0) {
        for (nextrow = table->first_row, prevrow = NULL;
             nextrow != NULL; prevrow = nextrow, nextrow = nextrow->next) {
            if (NULL == nextrow->index_oid) {
                DEBUGMSGT(("table_data_add_data", "row doesn't have index!\n"));
                /** xxx-rks: remove invalid row? */
                continue;
            }
            rc = snmp_oid_compare(nextrow->index_oid, nextrow->index_oid_len,
                                  row->index_oid, row->index_oid_len);
            if(rc > 0)
                break;
            if (0 == rc) {
                dup = 1;
                break;
            }
        }
    }

    if (dup) {
        /*
         * exact match.  Duplicate entries illegal 
         */
        snmp_log(LOG_WARNING,
                 "duplicate table data attempted to be entered. row exists\n");
        return SNMPERR_GENERR;
    }

    /*
     * ok, we have the location of where it should go 
     */
    /*
     * (after prevrow, and before nextrow) 
     */
    row->next = nextrow;
    row->prev = prevrow;

    if (row->next)
        row->next->prev = row;

    if (row->prev)
        row->prev->next = row;

    if (NULL == row->prev)      /* it's the (new) first row */
        table->first_row = row;
    if (NULL == row->next)      /* it's the last row */
        table->last_row = row;

    DEBUGMSGTL(("table_data_add_data", "added something...\n"));

    return SNMPERR_SUCCESS;
}

/** swaps out origrow with newrow.  This does *not* delete/free anything! */
NETSNMP_INLINE void
netsnmp_table_data_replace_row(netsnmp_table_data *table,
                               netsnmp_table_row *origrow,
                               netsnmp_table_row *newrow)
{
    netsnmp_table_data_remove_row(table, origrow);
    netsnmp_table_data_add_row(table, newrow);
}

/**
 * removes a row of data to a given table and returns it (no free's called)
 *
 * returns the row pointer itself on successful removing.
 *      or NULL on failure (bad arguments)
 */
netsnmp_table_row *
netsnmp_table_data_remove_row(netsnmp_table_data *table,
                              netsnmp_table_row *row)
{
    if (!row || !table)
        return NULL;

    if (row->prev)
        row->prev->next = row->next;
    else
        table->first_row = row->next;

    if (row->next)
        row->next->prev = row->prev;
    else
        table->last_row = row->prev;

    return row;
}

/**
 * removes and frees a row of data to a given table and returns the void *
 *
 * returns the void * data on successful deletion.
 *      or NULL on failure (bad arguments)
 */
void           *
netsnmp_table_data_remove_and_delete_row(netsnmp_table_data *table,
                                         netsnmp_table_row *row)
{
    if (!row || !table)
        return NULL;

    /*
     * remove it from the list 
     */
    netsnmp_table_data_remove_row(table, row);
    return netsnmp_table_data_delete_row(row);
}

    /* =====================================
     * Generic API - mostly renamed wrappers
     * ===================================== */

netsnmp_table_data *
netsnmp_table_data_create_table(const char *name, long flags)
{
    return netsnmp_create_table_data( name );
}

void
netsnmp_table_data_delete_table( netsnmp_table_data *table )
{
    netsnmp_table_row *row, *nextrow;

    if (!table)
        return;

    snmp_free_varbind(table->indexes_template);
    table->indexes_template = NULL;

    for (row = table->first_row; row; row=nextrow) {
        nextrow   = row->next;
        row->next = NULL;
        netsnmp_table_data_delete_row(row);
        /* Can't delete table-specific entry memory */
    }
    table->first_row = NULL;

    if (table->name) {
        SNMP_FREE(table->name);
        table->name = NULL;
    }
    SNMP_FREE(table);
    return;
}

netsnmp_table_row *
netsnmp_table_data_create_row( void* entry )
{
    netsnmp_table_row *row = SNMP_MALLOC_TYPEDEF(netsnmp_table_row);
    if (row)
        row->data = entry;
    return row;
}

    /* netsnmp_table_data_clone_row() defined above */

int
netsnmp_table_data_copy_row( netsnmp_table_row  *old_row,
                             netsnmp_table_row  *new_row )
{
    if (!old_row || !new_row)
        return -1;

    memcpy(new_row, old_row, sizeof(netsnmp_table_row));

    if (old_row->indexes)
        new_row->indexes = snmp_clone_varbind(old_row->indexes);
    if (old_row->index_oid)
        new_row->index_oid = netsnmp_memdup(old_row->index_oid,
                                         old_row->index_oid_len * sizeof(oid));
    /* XXX - Doesn't copy table-specific row structure */
    return 0;
}

    /*
     * netsnmp_table_data_delete_row()
     * netsnmp_table_data_add_row()
     * netsnmp_table_data_replace_row()
     * netsnmp_table_data_remove_row()
     *     all defined above
     */

void *
netsnmp_table_data_remove_delete_row(netsnmp_table_data *table,
                                     netsnmp_table_row *row)
{
    return netsnmp_table_data_remove_and_delete_row(table, row);
}


/* ==================================
 *
 * Table Data API: MIB maintenance
 *
 * ================================== */

/** Creates a table_data handler and returns it */
netsnmp_mib_handler *
netsnmp_get_table_data_handler(netsnmp_table_data *table)
{
    netsnmp_mib_handler *ret = NULL;

    if (!table) {
        snmp_log(LOG_INFO,
                 "netsnmp_get_table_data_handler(NULL) called\n");
        return NULL;
    }

    ret =
        netsnmp_create_handler(TABLE_DATA_NAME,
                               netsnmp_table_data_helper_handler);
    if (ret) {
        ret->flags |= MIB_HANDLER_AUTO_NEXT;
        ret->myvoid = (void *) table;
    }
    return ret;
}

/** registers a handler as a data table.
 *  If table_info != NULL, it registers it as a normal table too. */
int
netsnmp_register_table_data(netsnmp_handler_registration *reginfo,
                            netsnmp_table_data *table,
                            netsnmp_table_registration_info *table_info)
{
    netsnmp_inject_handler(reginfo, netsnmp_get_table_data_handler(table));
    return netsnmp_register_table(reginfo, table_info);
}

/** registers a handler as a read-only data table
 *  If table_info != NULL, it registers it as a normal table too. */
int
netsnmp_register_read_only_table_data(netsnmp_handler_registration *reginfo,
                                      netsnmp_table_data *table,
                                      netsnmp_table_registration_info *table_info)
{
    netsnmp_inject_handler(reginfo, netsnmp_get_read_only_handler());
    return netsnmp_register_table_data(reginfo, table, table_info);
}

/*
 * The helper handler that takes care of passing a specific row of
 * data down to the lower handler(s).  It sets request->processed if
 * the request should not be handled.
 */
int
netsnmp_table_data_helper_handler(netsnmp_mib_handler *handler,
                                  netsnmp_handler_registration *reginfo,
                                  netsnmp_agent_request_info *reqinfo,
                                  netsnmp_request_info *requests)
{
    netsnmp_table_data *table = (netsnmp_table_data *) handler->myvoid;
    netsnmp_request_info *request;
    int             valid_request = 0;
    netsnmp_table_row *row;
    netsnmp_table_request_info *table_info;
    netsnmp_table_registration_info *table_reg_info =
        netsnmp_find_table_registration_info(reginfo);
    int             result, regresult;
    int             oldmode;

    for (request = requests; request; request = request->next) {
        if (request->processed)
            continue;

        table_info = netsnmp_extract_table_info(request);
        if (!table_info)
            continue;           /* ack */
        switch (reqinfo->mode) {
        case MODE_GET:
        case MODE_GETNEXT:
        case MODE_SET_RESERVE1:
            netsnmp_request_add_list_data(request,
                                      netsnmp_create_data_list(
                                          TABLE_DATA_TABLE, table, NULL));
        }

        /*
         * find the row in question 
         */
        switch (reqinfo->mode) {
        case MODE_GETNEXT:
        case MODE_GETBULK:     /* XXXWWW */
            if (request->requestvb->type != ASN_NULL)
                continue;
            /*
             * loop through data till we find the next row 
             */
            result = snmp_oid_compare(request->requestvb->name,
                                      request->requestvb->name_length,
                                      reginfo->rootoid,
                                      reginfo->rootoid_len);
            regresult = snmp_oid_compare(request->requestvb->name,
                                         SNMP_MIN(request->requestvb->
                                                  name_length,
                                                  reginfo->rootoid_len),
                                         reginfo->rootoid,
                                         reginfo->rootoid_len);
            if (regresult == 0
                && request->requestvb->name_length < reginfo->rootoid_len)
                regresult = -1;

            if (result < 0 || 0 == result) {
                /*
                 * before us entirely, return the first 
                 */
                row = table->first_row;
                table_info->colnum = table_reg_info->min_column;
            } else if (regresult == 0 && request->requestvb->name_length ==
                       reginfo->rootoid_len + 1 &&
                       /* entry node must be 1, but any column is ok */
                       request->requestvb->name[reginfo->rootoid_len] == 1) {
                /*
                 * exactly to the entry 
                 */
                row = table->first_row;
                table_info->colnum = table_reg_info->min_column;
            } else if (regresult == 0 && request->requestvb->name_length ==
                       reginfo->rootoid_len + 2 &&
                       /* entry node must be 1, but any column is ok */
                       request->requestvb->name[reginfo->rootoid_len] == 1) {
                /*
                 * exactly to the column 
                 */
                row = table->first_row;
            } else {
                /*
                 * loop through all rows looking for the first one
                 * that is equal to the request or greater than it 
                 */
                for (row = table->first_row; row; row = row->next) {
                    /*
                     * compare the index of the request to the row 
                     */
                    result =
                        snmp_oid_compare(row->index_oid,
                                         row->index_oid_len,
                                         request->requestvb->name + 2 +
                                         reginfo->rootoid_len,
                                         request->requestvb->name_length -
                                         2 - reginfo->rootoid_len);
                    if (result == 0) {
                        /*
                         * equal match, return the next row 
                         */
                        if (row) {
                            row = row->next;
                        }
                        break;
                    } else if (result > 0) {
                        /*
                         * the current row is greater than the
                         * request, use it 
                         */
                        break;
                    }
                }
            }
            if (!row) {
                table_info->colnum++;
                if (table_info->colnum <= table_reg_info->max_column) {
                    row = table->first_row;
                }
            }
            if (row) {
                valid_request = 1;
                netsnmp_request_add_list_data(request,
                                              netsnmp_create_data_list
                                              (TABLE_DATA_ROW, row,
                                               NULL));
                /*
                 * Set the name appropriately, so we can pass this
                 *  request on as a simple GET request
                 */
                netsnmp_table_data_build_result(reginfo, reqinfo, request,
                                                row,
                                                table_info->colnum,
                                                ASN_NULL, NULL, 0);
            } else {            /* no decent result found.  Give up. It's beyond us. */
                request->processed = 1;
            }
            break;

        case MODE_GET:
            if (request->requestvb->type != ASN_NULL)
                continue;
            /*
             * find the row in question 
             */
            if (request->requestvb->name_length < (reginfo->rootoid_len + 3)) { /* table.entry.column... */
                /*
                 * request too short 
                 */
                netsnmp_set_request_error(reqinfo, request,
                                          SNMP_NOSUCHINSTANCE);
                break;
            } else if (NULL ==
                       (row =
                        netsnmp_table_data_get_from_oid(table,
                                                        request->
                                                        requestvb->name +
                                                        reginfo->
                                                        rootoid_len + 2,
                                                        request->
                                                        requestvb->
                                                        name_length -
                                                        reginfo->
                                                        rootoid_len -
                                                        2))) {
                /*
                 * no such row 
                 */
                netsnmp_set_request_error(reqinfo, request,
                                          SNMP_NOSUCHINSTANCE);
                break;
            } else {
                valid_request = 1;
                netsnmp_request_add_list_data(request,
                                              netsnmp_create_data_list
                                              (TABLE_DATA_ROW, row,
                                               NULL));
            }
            break;

        case MODE_SET_RESERVE1:
            valid_request = 1;
            if (NULL !=
                (row =
                 netsnmp_table_data_get_from_oid(table,
                                                 request->requestvb->name +
                                                 reginfo->rootoid_len + 2,
                                                 request->requestvb->
                                                 name_length -
                                                 reginfo->rootoid_len -
                                                 2))) {
                netsnmp_request_add_list_data(request,
                                              netsnmp_create_data_list
                                              (TABLE_DATA_ROW, row,
                                               NULL));
            }
            break;

        case MODE_SET_RESERVE2:
        case MODE_SET_ACTION:
        case MODE_SET_COMMIT:
        case MODE_SET_FREE:
        case MODE_SET_UNDO:
            valid_request = 1;

        }
    }

    if (valid_request &&
       (reqinfo->mode == MODE_GETNEXT || reqinfo->mode == MODE_GETBULK)) {
        /*
         * If this is a GetNext or GetBulk request, then we've identified
         *  the row that ought to include the appropriate next instance.
         *  Convert the request into a Get request, so that the lower-level
         *  handlers don't need to worry about skipping on, and call these
         *  handlers ourselves (so we can undo this again afterwards).
         */
        oldmode = reqinfo->mode;
        reqinfo->mode = MODE_GET;
        result = netsnmp_call_next_handler(handler, reginfo, reqinfo,
                                         requests);
        reqinfo->mode = oldmode;
        handler->flags |= MIB_HANDLER_AUTO_NEXT_OVERRIDE_ONCE;
        return result;
    }
    else
        /* next handler called automatically - 'AUTO_NEXT' */
        return SNMP_ERR_NOERROR;
}

/** extracts the table being accessed passed from the table_data helper */
netsnmp_table_data *
netsnmp_extract_table(netsnmp_request_info *request)
{
    return (netsnmp_table_data *)
                netsnmp_request_get_list_data(request, TABLE_DATA_TABLE);
}

/** extracts the row being accessed passed from the table_data helper */
netsnmp_table_row *
netsnmp_extract_table_row(netsnmp_request_info *request)
{
    return (netsnmp_table_row *) netsnmp_request_get_list_data(request,
                                                               TABLE_DATA_ROW);
}

/** extracts the data from the row being accessed passed from the
 * table_data helper */
void           *
netsnmp_extract_table_row_data(netsnmp_request_info *request)
{
    netsnmp_table_row *row;
    row = (netsnmp_table_row *) netsnmp_extract_table_row(request);
    if (row)
        return row->data;
    else
        return NULL;
}

/** inserts a newly created table_data row into a request */
NETSNMP_INLINE void
netsnmp_insert_table_row(netsnmp_request_info *request,
                         netsnmp_table_row *row)
{
    netsnmp_request_info       *req;
    netsnmp_table_request_info *table_info = NULL;
    netsnmp_variable_list      *this_index = NULL;
    netsnmp_variable_list      *that_index = NULL;
    oid      base_oid[] = {0, 0};	/* Make sure index OIDs are legal! */
    oid      this_oid[MAX_OID_LEN];
    oid      that_oid[MAX_OID_LEN];
    size_t   this_oid_len, that_oid_len;

    if (!request)
        return;

    /*
     * We'll add the new row information to any request
     * structure with the same index values as the request
     * passed in (which includes that one!).
     *
     * So construct an OID based on these index values.
     */

    table_info = netsnmp_extract_table_info(request);
    this_index = table_info->indexes;
    build_oid_noalloc(this_oid, MAX_OID_LEN, &this_oid_len,
                      base_oid, 2, this_index);

    /*
     * We need to look through the whole of the request list
     * (as received by the current handler), as there's no
     * guarantee that this routine will be called by the first
     * varbind that refers to this row.
     *   In particular, a RowStatus controlled row creation
     * may easily occur later in the variable list.
     *
     * So first, we rewind to the head of the list....
     */
    for (req=request; req->prev; req=req->prev)
        ;

    /*
     * ... and then start looking for matching indexes
     * (by constructing OIDs from these index values)
     */
    for (; req; req=req->next) {
        table_info = netsnmp_extract_table_info(req);
        that_index = table_info->indexes;
        build_oid_noalloc(that_oid, MAX_OID_LEN, &that_oid_len,
                          base_oid, 2, that_index);
      
        /*
         * This request has the same index values,
         * so add the newly-created row information.
         */
        if (snmp_oid_compare(this_oid, this_oid_len,
                             that_oid, that_oid_len) == 0) {
            netsnmp_request_add_list_data(req,
                netsnmp_create_data_list(TABLE_DATA_ROW, row, NULL));
        }
    }
}

/* builds a result given a row, a varbind to set and the data */
int
netsnmp_table_data_build_result(netsnmp_handler_registration *reginfo,
                                netsnmp_agent_request_info *reqinfo,
                                netsnmp_request_info *request,
                                netsnmp_table_row *row,
                                int column,
                                u_char type,
                                u_char * result_data,
                                size_t result_data_len)
{
    oid             build_space[MAX_OID_LEN];

    if (!reginfo || !reqinfo || !request)
        return SNMPERR_GENERR;

    if (reqinfo->mode == MODE_GETNEXT || reqinfo->mode == MODE_GETBULK) {
        /*
         * only need to do this for getnext type cases where oid is changing 
         */
        memcpy(build_space, reginfo->rootoid,   /* registered oid */
               reginfo->rootoid_len * sizeof(oid));
        build_space[reginfo->rootoid_len] = 1;  /* entry */
        build_space[reginfo->rootoid_len + 1] = column; /* column */
        memcpy(build_space + reginfo->rootoid_len + 2,  /* index data */
               row->index_oid, row->index_oid_len * sizeof(oid));
        snmp_set_var_objid(request->requestvb, build_space,
                           reginfo->rootoid_len + 2 + row->index_oid_len);
    }
    snmp_set_var_typed_value(request->requestvb, type,
                             result_data, result_data_len);
    return SNMPERR_SUCCESS;     /* WWWXXX: check for bounds */
}


/* ==================================
 *
 * Table Data API: Row operations
 *     (table-independent rows)
 *
 * ================================== */

/** returns the first row in the table */
netsnmp_table_row *
netsnmp_table_data_get_first_row(netsnmp_table_data *table)
{
    if (!table)
        return NULL;
    return table->first_row;
}

/** returns the next row in the table */
netsnmp_table_row *
netsnmp_table_data_get_next_row(netsnmp_table_data *table,
                                netsnmp_table_row  *row)
{
    if (!row)
        return NULL;
    return row->next;
}

/** finds the data in "datalist" stored at "indexes" */
netsnmp_table_row *
netsnmp_table_data_get(netsnmp_table_data *table,
                       netsnmp_variable_list * indexes)
{
    oid             searchfor[MAX_OID_LEN];
    size_t          searchfor_len = MAX_OID_LEN;

    build_oid_noalloc(searchfor, MAX_OID_LEN, &searchfor_len, NULL, 0,
                      indexes);
    return netsnmp_table_data_get_from_oid(table, searchfor,
                                           searchfor_len);
}

/** finds the data in "datalist" stored at the searchfor oid */
netsnmp_table_row *
netsnmp_table_data_get_from_oid(netsnmp_table_data *table,
                                oid * searchfor, size_t searchfor_len)
{
    netsnmp_table_row *row;
    if (!table)
        return NULL;

    for (row = table->first_row; row != NULL; row = row->next) {
        if (row->index_oid &&
            snmp_oid_compare(searchfor, searchfor_len,
                             row->index_oid, row->index_oid_len) == 0)
            return row;
    }
    return NULL;
}

int
netsnmp_table_data_num_rows(netsnmp_table_data *table)
{
    int i=0;
    netsnmp_table_row *row;
    if (!table)
        return 0;
    for (row = table->first_row; row; row = row->next) {
        i++;
    }
    return i;
}

    /* =====================================
     * Generic API - mostly renamed wrappers
     * ===================================== */

netsnmp_table_row *
netsnmp_table_data_row_first(netsnmp_table_data *table)
{
    return netsnmp_table_data_get_first_row(table);
}

netsnmp_table_row *
netsnmp_table_data_row_get(  netsnmp_table_data *table,
                             netsnmp_table_row  *row)
{
    if (!table || !row)
        return NULL;
    return netsnmp_table_data_get_from_oid(table, row->index_oid,
                                                  row->index_oid_len);
}

netsnmp_table_row *
netsnmp_table_data_row_next( netsnmp_table_data *table,
                             netsnmp_table_row  *row)
{
    return netsnmp_table_data_get_next_row(table, row);
}

netsnmp_table_row *
netsnmp_table_data_row_get_byoid( netsnmp_table_data *table,
                                  oid *instance, size_t len)
{
    return netsnmp_table_data_get_from_oid(table, instance, len);
}

netsnmp_table_row *
netsnmp_table_data_row_next_byoid(netsnmp_table_data *table,
                                  oid *instance, size_t len)
{
    netsnmp_table_row *row;

    if (!table || !instance)
        return NULL;
    
    for (row = table->first_row; row; row = row->next) {
        if (snmp_oid_compare(row->index_oid,
                             row->index_oid_len,
                             instance, len) > 0)
            return row;
    }
    return NULL;
}

netsnmp_table_row *
netsnmp_table_data_row_get_byidx( netsnmp_table_data    *table,
                                  netsnmp_variable_list *indexes)
{
    return netsnmp_table_data_get(table, indexes);
}

netsnmp_table_row *
netsnmp_table_data_row_next_byidx(netsnmp_table_data    *table,
                                  netsnmp_variable_list *indexes)
{
    oid    instance[MAX_OID_LEN];
    size_t len    = MAX_OID_LEN;

    if (!table || !indexes)
        return NULL;

    build_oid_noalloc(instance, MAX_OID_LEN, &len, NULL, 0, indexes);
    return netsnmp_table_data_row_next_byoid(table, instance, len);
}

int
netsnmp_table_data_row_count(netsnmp_table_data *table)
{
    return netsnmp_table_data_num_rows(table);
}


/* ==================================
 *
 * Table Data API: Row operations
 *     (table-specific rows)
 *
 * ================================== */

void *
netsnmp_table_data_entry_first(netsnmp_table_data *table)
{
    netsnmp_table_row *row =
        netsnmp_table_data_get_first_row(table);
    return (row ? row->data : NULL );
}

void *
netsnmp_table_data_entry_get(  netsnmp_table_data *table,
                               netsnmp_table_row  *row)
{
    return (row ? row->data : NULL );
}

void *
netsnmp_table_data_entry_next( netsnmp_table_data *table,
                               netsnmp_table_row  *row)
{
    row =
        netsnmp_table_data_row_next(table, row);
    return (row ? row->data : NULL );
}

void *
netsnmp_table_data_entry_get_byidx( netsnmp_table_data    *table,
                                    netsnmp_variable_list *indexes)
{
    netsnmp_table_row *row =
        netsnmp_table_data_row_get_byidx(table, indexes);
    return (row ? row->data : NULL );
}

void *
netsnmp_table_data_entry_next_byidx(netsnmp_table_data    *table,
                                    netsnmp_variable_list *indexes)
{
    netsnmp_table_row *row =
        netsnmp_table_data_row_next_byidx(table, indexes);
    return (row ? row->data : NULL );
}

void *
netsnmp_table_data_entry_get_byoid( netsnmp_table_data *table,
                                    oid *instance, size_t len)
{
    netsnmp_table_row *row =
        netsnmp_table_data_row_get_byoid(table, instance, len);
    return (row ? row->data : NULL );
}

void *
netsnmp_table_data_entry_next_byoid(netsnmp_table_data *table,
                                    oid *instance, size_t len)
{
    netsnmp_table_row *row =
        netsnmp_table_data_row_next_byoid(table, instance, len);
    return (row ? row->data : NULL );
}

    /* =====================================
     * Generic API - mostly renamed wrappers
     * ===================================== */

/* ==================================
 *
 * Table Data API: Index operations
 *
 * ================================== */

/** @} 
 */
