if (handlers == null) {
// This should be considered as a genErr, but we do not want to
// abort the whole request, so we're going to throw
// a noSuchObject...
//
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
}
final Object data = handlers.getUserData();
final int pduVersion = handlers.getRequestPduVersion();
long var= -1;
// If the querried oid contains less arcs than the OID of the
// xxxEntry object, we must return the first leaf under the
// first columnar object: the best way to do that is to reset
// the queried oid:
// oid[0] = nodeId (arc of the xxxEntry object)
// pos = 0 (points to the arc of the xxxEntry object)
// then we just have to proceed...
//
if (pos >= length) {
// this will have the side effect to set
// oid[pos] = nodeId
// and
// (pos+1) = length
// so we won't fall into the "else if" cases below -
// so using "else if" rather than "if ..." is guaranteed
// to be safe.
//
oid = new long[1];
oid[0] = nodeId;
pos = 0;
length = 1;
} else if (oid[pos] > nodeId) {
// oid[pos] is expected to be the id of the xxxEntry ...
// The id requested is greater than the id of the xxxEntry,
// so we won't find the next element in this table... (any
// element in this table will have a smaller OID)
//
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
} else if (oid[pos] < nodeId) {
// we must return the first leaf under the first columnar
// object, so we are back to our first case where pos was
// out of bounds... => reset the oid to contain only the
// arc of the xxxEntry object.
//
oid = new long[1];
oid[0] = nodeId;
pos = 0;
length = 0;
} else if ((pos + 1) < length) {
// The arc at the position "pos+1" is the id of the columnar
// object (ie: the id of the variable in the table entry)
//
var = oid[pos+1];
}
// Now that we've got everything right we can begin.
SnmpOid entryoid;
if (pos == (length - 1)) {
// pos points to the last arc in the oid, and this arc is
// guaranteed to be the xxxEntry id (we have handled all
// the other possibilities before)
//
// We must therefore return the first leaf below the first
// columnar object in the table.
//
// Get the first index. If an exception is raised,
// then it means that the table is empty. We thus do not
// have to catch the exception - we let it propagate to
// the caller.
//
entryoid = getNextOid(data);
var = getNextVarEntryId(entryoid,var,data,pduVersion);
} else if ( pos == (length-2)) {
// In that case we have (pos+1) = (length-1), so pos
// points to the arc of the querried variable (columnar object).
// Since the requested oid stops there, it means we have
// to return the first leaf under this columnar object.
//
// So we first get the first index:
// Note: if this raises an exception, this means that the table
// is empty, so we can let the exception propagate to the caller.
//
entryoid = getNextOid(data);
// XXX revisit: not exactly perfect:
// a specific row could be empty.. But we don't know
// how to make the difference! => tradeoff holes
// in tables can't be properly supported (all rows
// must have the same holes)
//
if (skipEntryVariable(entryoid,var,data,pduVersion)) {
var = getNextVarEntryId(entryoid,var,data,pduVersion);
}
} else {
// So now there remain one last case, namely: some part of the
// index is provided by the oid...
// We build a possibly incomplete and invalid index from
// the OID.
// The piece of index provided should begin at pos+2
// oid[pos] = id of the xxxEntry object,
// oid[pos+1] = id of the columnar object,
// oid[pos+2] ... oid[length-1] = piece of index.
//
// We get the next index following the provided index.
// If this raises an exception, then it means that we have
// reached the last index in the table, and we must then
// try with the next columnar object.
//
// Bug fix 4269251
// The SnmpIndex is defined to contain a valid oid:
// this is not an SNMP requirement for the getNext request.
// So we no more use the SnmpIndex but directly the SnmpOid.
//
try {
entryoid = getNextOid(oid, pos + 2, data);
// If the variable must ne skipped, fall through...
//
// XXX revisit: not exactly perfect:
// a specific row could be empty.. But we don't know
// how to make the difference! => tradeoff holes
// in tables can't be properly supported (all rows
// must have the same holes)
//
if (skipEntryVariable(entryoid,var,data,pduVersion)) {
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
}
} catch(SnmpStatusException se) {
entryoid = getNextOid(data);
var = getNextVarEntryId(entryoid,var,data,pduVersion);
}