This patch adds access to single elements of variables via index. Example: --- src/conf/nwfilter_params.c | 82 +++++++++++++++++++++++++++++++++++---------- src/conf/nwfilter_params.h | 9 +++- 2 files changed, 71 insertions(+), 20 deletions(-) Index: libvirt-iterator/src/conf/nwfilter_params.c =================================================================== --- libvirt-iterator.orig/src/conf/nwfilter_params.c +++ libvirt-iterator/src/conf/nwfilter_params.c @@ -35,7 +35,10 @@ #define VIR_FROM_THIS VIR_FROM_NWFILTER static bool isValidVarValue(const char *value); - +static void virNWFilterVarAccessSetIntIterId(virNWFilterVarAccessPtr, + unsigned int); +static unsigned int virNWFilterVarAccessGetIntIterId( + const virNWFilterVarAccessPtr); void virNWFilterVarValueFree(virNWFilterVarValuePtr val) @@ -313,7 +316,7 @@ virNWFilterVarCombIterAddVariable(virNWF const virNWFilterVarAccessPtr varAccess) { virNWFilterVarValuePtr varValue; - unsigned int cardinality; + unsigned int maxValue, minValue; const char *varName = virNWFilterVarAccessGetVarName(varAccess); varValue = virHashLookup(hash->hashTable, varName); @@ -324,12 +327,25 @@ virNWFilterVarCombIterAddVariable(virNWF return -1; } - cardinality = virNWFilterVarValueGetCardinality(varValue); + switch (virNWFilterVarAccessGetType(varAccess)) { + case VIR_NWFILTER_VAR_ACCESS_ELEMENT: + maxValue = virNWFilterVarAccessGetIndex(varAccess); + minValue = maxValue; + break; + case VIR_NWFILTER_VAR_ACCESS_ITERATOR: + maxValue = virNWFilterVarValueGetCardinality(varValue) - 1; + minValue = 0; + break; + case VIR_NWFILTER_VAR_ACCESS_LAST: + return -1; + } if (cie->nVarNames == 0) { - cie->maxValue = cardinality - 1; + cie->maxValue = maxValue; + cie->minValue = minValue; + cie->curValue = minValue; } else { - if (cie->maxValue != cardinality - 1) { + if (cie->maxValue != maxValue) { virNWFilterReportError(VIR_ERR_INTERNAL_ERROR, _("Cardinality of list items must be " "the same for processing them in " @@ -410,12 +426,13 @@ virNWFilterVarCombIterEntryAreUniqueEntr */ virNWFilterVarCombIterPtr virNWFilterVarCombIterCreate(virNWFilterHashTablePtr hash, - const virNWFilterVarAccessPtr *varAccess, + virNWFilterVarAccessPtr *varAccess, size_t nVarAccess) { virNWFilterVarCombIterPtr res; unsigned int i, iterId; int iterIndex = -1; + unsigned int nextIntIterId = VIR_NWFILTER_MAX_ITERID + 1; if (VIR_ALLOC_VAR(res, virNWFilterVarCombIterEntry, 1 + nVarAccess) < 0) { virReportOOMError(); @@ -442,6 +459,13 @@ virNWFilterVarCombIterCreate(virNWFilter } break; case VIR_NWFILTER_VAR_ACCESS_ELEMENT: + iterIndex = res->nIter; + virNWFilterVarAccessSetIntIterId(varAccess[i], nextIntIterId); + virNWFilterVarCombIterEntryInit(&res->iter[iterIndex], + nextIntIterId); + nextIntIterId++; + res->nIter++; + break; case VIR_NWFILTER_VAR_ACCESS_LAST: break; } @@ -473,7 +497,7 @@ next: } break; } else - ci->iter[i].curValue = 0; + ci->iter[i].curValue = ci->iter[i].minValue; } if (ci->nIter == i) { @@ -507,9 +531,15 @@ virNWFilterVarCombIterGetVarValue(virNWF } break; case VIR_NWFILTER_VAR_ACCESS_ELEMENT: - virNWFilterReportError(VIR_ERR_INTERNAL_ERROR, - _("Element access via index is not possible")); - return NULL; + iterId = virNWFilterVarAccessGetIntIterId(vap); + iterIndex = virNWFilterVarCombIterGetIndexByIterId(ci, iterId); + if (iterIndex < 0) { + virNWFilterReportError(VIR_ERR_INTERNAL_ERROR, + _("Could not get iterator index for " + "(internal) iterator ID %u"), iterId); + return NULL; + } + break; case VIR_NWFILTER_VAR_ACCESS_LAST: return NULL; } @@ -874,7 +904,8 @@ virNWFilterVarAccessEqual(const virNWFil switch (a->accessType) { case VIR_NWFILTER_VAR_ACCESS_ELEMENT: - return (a->u.index == b->u.index); + return (a->u.index.index == b->u.index.index && + a->u.index.intIterId == b->u.index.intIterId); break; case VIR_NWFILTER_VAR_ACCESS_ITERATOR: return (a->u.iterId == b->u.iterId); @@ -938,11 +969,6 @@ virNWFilterVarAccessParse(const char *va } else { /* in the form 'IP[] -> element */ dest->accessType = VIR_NWFILTER_VAR_ACCESS_ELEMENT; - /* not supported (yet) */ - virNWFilterReportError(VIR_ERR_INVALID_ARG, - _("Variable access in the form " - "var[] is not supported")); - goto err_exit; } if (virStrToLong_ui(input, &end_ptr, 10, &result) < 0) @@ -964,7 +990,8 @@ virNWFilterVarAccessParse(const char *va switch (dest->accessType) { case VIR_NWFILTER_VAR_ACCESS_ELEMENT: - dest->u.index = result; + dest->u.index.index = result; + dest->u.index.intIterId = ~0; break; case VIR_NWFILTER_VAR_ACCESS_ITERATOR: if (result > VIR_NWFILTER_MAX_ITERID) { @@ -997,7 +1024,7 @@ virNWFilterVarAccessPrint(virNWFilterVar virBufferAdd(buf, vap->varName, -1); switch (vap->accessType) { case VIR_NWFILTER_VAR_ACCESS_ELEMENT: - virBufferAsprintf(buf, "[%u]", vap->u.index); + virBufferAsprintf(buf, "[%u]", vap->u.index.index); break; case VIR_NWFILTER_VAR_ACCESS_ITERATOR: if (vap->u.iterId != 0) @@ -1025,3 +1052,22 @@ virNWFilterVarAccessGetIterId(const virN { return vap->u.iterId; } + +unsigned int +virNWFilterVarAccessGetIndex(const virNWFilterVarAccessPtr vap) +{ + return vap->u.index.index; +} + +static void +virNWFilterVarAccessSetIntIterId(virNWFilterVarAccessPtr vap, + unsigned int intIterId) +{ + vap->u.index.intIterId = intIterId; +} + +static unsigned int +virNWFilterVarAccessGetIntIterId(const virNWFilterVarAccessPtr vap) +{ + return vap->u.index.intIterId; +} Index: libvirt-iterator/src/conf/nwfilter_params.h =================================================================== --- libvirt-iterator.orig/src/conf/nwfilter_params.h +++ libvirt-iterator/src/conf/nwfilter_params.h @@ -103,7 +103,10 @@ typedef virNWFilterVarAccess *virNWFilte struct _virNWFilterVarAccess { enum virNWFilterVarAccessType accessType; union { - unsigned int index; + struct { + unsigned int index; + unsigned int intIterId; + } index; unsigned int iterId; } u; char *varName; @@ -121,6 +124,7 @@ const char *virNWFilterVarAccessGetVarNa enum virNWFilterVarAccessType virNWFilterVarAccessGetType( const virNWFilterVarAccessPtr vap); unsigned int virNWFilterVarAccessGetIterId(const virNWFilterVarAccessPtr vap); +unsigned int virNWFilterVarAccessGetIndex(const virNWFilterVarAccessPtr vap); typedef struct _virNWFilterVarCombIterEntry virNWFilterVarCombIterEntry; @@ -131,6 +135,7 @@ struct _virNWFilterVarCombIterEntry { size_t nVarNames; unsigned int maxValue; unsigned int curValue; + unsigned int minValue; }; typedef struct _virNWFilterVarCombIter virNWFilterVarCombIter; @@ -142,7 +147,7 @@ struct _virNWFilterVarCombIter { }; virNWFilterVarCombIterPtr virNWFilterVarCombIterCreate( virNWFilterHashTablePtr hash, - const virNWFilterVarAccessPtr *vars, + virNWFilterVarAccessPtr *vars, size_t nVars); void virNWFilterVarCombIterFree(virNWFilterVarCombIterPtr ci);