#include <NetInfo/dsassertion.h>
#include <stdlib.h>
#include <string.h>
dsassertion *
dsassertion_new(int32_t a, int32_t m, dsdata *k, dsdata *v)
{
dsassertion *x;
if (k == NULL) return NULL;
x = (dsassertion *)malloc(sizeof(dsassertion));
x->assertion = a;
x->meta = m;
x->key = dsdata_retain(k);
x->value = dsdata_retain(v);
x->retain = 1;
return x;
}
dsassertion *
dsassertion_retain(dsassertion *a)
{
if (a == NULL) return NULL;
a->retain++;
return a;
}
void
dsassertion_release(dsassertion *a)
{
if (a == NULL) return;
a->retain--;
if (a->retain > 0) return;
dsdata_release(a->key);
dsdata_release(a->value);
free(a);
}
Logic3
dsassertion_test(dsassertion *t, dsrecord *r)
{
u_int32_t i, len, start, ttype, n;
dsattribute *a;
if (t == NULL) return L3Undefined;
if (r == NULL) return L3Undefined;
ttype = DataTypeAny;
a = NULL;
if (t->assertion != DSA_PRECOMPUTED)
{
a = dsrecord_attribute(r, t->key, t->meta);
if (a == NULL) return L3Undefined;
if (t->assertion != DSA_HAS_KEY) ttype = t->value->type;
}
switch (t->assertion)
{
case DSA_LESS:
for (i = 0; i < a->count; i++)
{
if ((ttype != DataTypeAny) && (a->value[i]->type != ttype))
continue;
if (dsdata_compare(a->value[i], t->value) < 0)
{
dsattribute_release(a);
return L3True;
}
}
dsattribute_release(a);
return L3False;
case DSA_LESS_OR_EQUAL:
for (i = 0; i < a->count; i++)
{
if ((ttype != DataTypeAny) && (a->value[i]->type != ttype))
continue;
if (dsdata_compare(a->value[i], t->value) <= 0)
{
dsattribute_release(a);
return L3True;
}
}
dsattribute_release(a);
return L3False;
case DSA_EQUAL:
case DSA_APPROX:
for (i = 0; i < a->count; i++)
{
if ((ttype != DataTypeAny) && (a->value[i]->type != ttype))
continue;
if (dsdata_compare(a->value[i], t->value) == 0)
{
dsattribute_release(a);
return L3True;
}
}
dsattribute_release(a);
return L3False;
case DSA_GREATER_OR_EQUAL:
for (i = 0; i < a->count; i++)
{
if ((ttype != DataTypeAny) && (a->value[i]->type != ttype))
continue;
if (dsdata_compare(a->value[i], t->value) >= 0)
{
dsattribute_release(a);
return L3True;
}
}
dsattribute_release(a);
return L3False;
case DSA_GREATER:
for (i = 0; i < a->count; i++)
{
if ((ttype != DataTypeAny) && (a->value[i]->type != ttype))
continue;
if (dsdata_compare(a->value[i], t->value) > 0)
{
dsattribute_release(a);
return L3True;
}
}
dsattribute_release(a);
return L3False;
case DSA_HAS_KEY:
if (dsdata_compare(a->key, t->key) == 0)
{
dsattribute_release(a);
return L3True;
}
dsattribute_release(a);
return L3False;
case DSA_PREFIX:
len = t->value->length;
for (i = 0; i < a->count; i++)
{
if ((ttype != DataTypeAny) && (a->value[i]->type != ttype))
continue;
if (a->value[i]->length < len) continue;
if (dsdata_compare_sub(a->value[i], t->value, 0, len) == 0)
{
dsattribute_release(a);
return L3True;
}
}
dsattribute_release(a);
return L3False;
case DSA_SUBSTR:
len = t->value->length;
for (i = 0; i < a->count; i++)
{
if ((ttype != DataTypeAny) && (a->value[i]->type != ttype))
continue;
if (a->value[i]->length < len) continue;
n = a->value[i]->length - len;
for (start = 0; start <= n; start++)
{
if (dsdata_compare_sub(a->value[i], t->value, start, len) == 0)
{
dsattribute_release(a);
return L3True;
}
}
}
dsattribute_release(a);
return L3False;
case DSA_SUFFIX:
len = t->value->length;
for (i = 0; i < a->count; i++)
{
if ((ttype != DataTypeAny) && (a->value[i]->type != ttype))
continue;
if (a->value[i]->length < len) continue;
start = a->value[i]->length - len;
if (dsdata_compare_sub(a->value[i], t->value, start, len) == 0)
{
dsattribute_release(a);
return L3True;
}
}
dsattribute_release(a);
return L3False;
case DSA_PRECOMPUTED:
i = dsdata_to_uint32(t->key);
if (i > L3Undefined) i = L3Undefined;
return i;
}
if (t->assertion != DSA_PRECOMPUTED) dsattribute_release(a);
return L3False;
}