/* Copyright (C) Boris Nikolaus, Germany, 1996-1997. All rights reserved. */ /* Copyright (C) Microsoft Corporation, 1997-1998. All rights reserved. */ #include "precomp.h" /* --- NamedObjIdValue --- */ /* constructor of NamedObjIdValue_t */ NamedObjIdValue_t *NewNamedObjIdValue(NamedObjIdValue_e type) { NamedObjIdValue_t *ret; ret = (NamedObjIdValue_t *)malloc(sizeof(NamedObjIdValue_t)); ret->Type = type; ret->Next = NULL; ret->Name = NULL; ret->Number = 0xffffffff; return ret; } /* copy constructor of NamedObjIdValue_t */ NamedObjIdValue_t *DupNamedObjIdValue(NamedObjIdValue_t *src) { NamedObjIdValue_t *ret; if (!src) return NULL; ret = (NamedObjIdValue_t *)malloc(sizeof(NamedObjIdValue_t)); *ret = *src; return ret; } /* --- AssignedObjIds --- */ /* constructor of AssignedObjId_t */ AssignedObjId_t *NewAssignedObjId() { AssignedObjId_t *ret; ret = (AssignedObjId_t *)malloc(sizeof(AssignedObjId_t)); ret->Next = NULL; ret->Child = NULL; ret->Names = NULL; ret->Number = 0; return ret; } /* copy constructor of AssignedObjId_t */ AssignedObjId_t *DupAssignedObjId(AssignedObjId_t *src) { AssignedObjId_t *ret; if (!src) return NULL; ret = (AssignedObjId_t *)malloc(sizeof(AssignedObjId_t)); *ret = *src; return ret; } /* find an AssignedObjId_t by number in a list of AssignedObjId_t's */ static AssignedObjId_t *FindAssignedObjIdByNumber(AssignedObjId_t *aoi, objectnumber_t number) { for (; aoi; aoi = aoi->Next) { if (aoi->Number == number) return aoi; } return NULL; } /* find an AssignedObjId_t by name in a list of AssignedObjId_t's */ static AssignedObjId_t *FindAssignedObjIdByName(AssignedObjId_t *aoi, char *name) { String_t *names; for (; aoi; aoi = aoi->Next) { for (names = aoi->Names; names; names = names->Next) { if (!strcmp(names->String, name)) return aoi; } } return NULL; } /* convert a NamedObjIdValue into an object identifier value */ /* search for one NamedObjIdValue in AssignedObjIds; */ /* returns -1 for bad NamedObjIdValue (names defined to different values), */ /* returns 0 for unknown NamedObjIdValue (will probably be resolved in */ /* the next pass), */ /* returns 1 for success; */ /* on success: */ /* number contains the objectnumber, */ /* aoi contains a duplicate of the AssignedObjIds for the found */ /* NamedObjIdValue */ static int GetObjectIdentifierNumber(AssignedObjId_t **aoi, NamedObjIdValue_t *val, objectnumber_t *number) { AssignedObjId_t *a, *a2; switch (val->Type) { case eNamedObjIdValue_NameForm: /* name form: search the assigned objid by name and return 0 if not */ /* found */ a2 = FindAssignedObjIdByName(*aoi, val->Name); if (!a2) return 0; /* otherwise create a duplicate */ a = DupAssignedObjId(a2); a->Next = *aoi; *aoi = a; break; case eNamedObjIdValue_NumberForm: /* number form: search the assigned objid by number and create */ /* a new one/a duplicate */ a2 = FindAssignedObjIdByNumber(*aoi, val->Number); if (!a2) { a = NewAssignedObjId(); a->Number = val->Number; a->Next = *aoi; *aoi = a; } else { a = DupAssignedObjId(a2); a->Next = *aoi; *aoi = a; } break; case eNamedObjIdValue_NameAndNumberForm: /* name and number form: search the assigned objid by name and by */ /* number */ a = FindAssignedObjIdByName(*aoi, val->Name); a2 = FindAssignedObjIdByNumber(*aoi, val->Number); /* successful but different results are errorneous */ if (a && a != a2) return -1; if (!a && !a2) { /* found none, then create it */ a = NewAssignedObjId(); a->Number = val->Number; a->Names = NewString(); a->Names->String = val->Name; a->Next = *aoi; *aoi = a; } else if (!a) { /* found only by number, then duplicate it and add the name */ a = DupAssignedObjId(a2); a->Names = NewString(); a->Names->String = val->Name; a->Names->Next = a2->Names; a->Next = *aoi; *aoi = a; } else { /* found only by name, then duplicate it */ a = DupAssignedObjId(a2); a->Next = *aoi; *aoi = a; } break; } *number = a->Number; return 1; } /* * create a value out of NamedObjIdValues * returns -1 for bad NamedObjIdValue (names defined to different values), * returns 0 for unknown NamedObjIdValue (will probably be resolved next pass), * returns 1 for success; */ int GetAssignedObjectIdentifier(AssignedObjId_t **aoi, Value_t *parent, NamedObjIdValueList_t named, Value_t **val) { Value_t *v; int parentl; int l; NamedObjIdValue_t *n; objectnumber_t *on; /* get length of object identifier */ parentl = (parent ? parent->U.ObjectIdentifier.Value.length : 0); for (l = parentl, n = named; n; n = n->Next) { Value_t *pValue; pValue = (n->Type == eNamedObjIdValue_NameForm) ? GetDefinedOIDValue(n->Name) : NULL; if (pValue) { ASSERT(pValue->Type->Type == eType_ObjectIdentifier); l += pValue->U.ObjectIdentifier.Value.length; } else { l++; } } /* create the object identifier value */ v = NewValue(NULL, Builtin_Type_ObjectIdentifier); v->U.ObjectIdentifier.Value.length = l; v->U.ObjectIdentifier.Value.value = on = (objectnumber_t *)malloc(l * sizeof(objectnumber_t)); /* get the numbers of the parent object identifier and walk in the object */ /* identifier tree */ n = NewNamedObjIdValue(eNamedObjIdValue_NumberForm); for (l = 0; l < parentl; l++) { n->Number = parent->U.ObjectIdentifier.Value.value[l]; switch (GetObjectIdentifierNumber(aoi, n, on + l)) { case -1: return -1; case 0: return 0; default: aoi = &(*aoi)->Child; break; } } /* get the numers from the namedobjidvaluelist */ for (n = named; n; n = n->Next) { Value_t *pValue; pValue = (n->Type == eNamedObjIdValue_NameForm) ? GetDefinedOIDValue(n->Name) : NULL; if (pValue) { memcpy(on + l, pValue->U.ObjectIdentifier.Value.value, pValue->U.ObjectIdentifier.Value.length * sizeof(objectnumber_t)); l += pValue->U.ObjectIdentifier.Value.length; } else { switch (GetObjectIdentifierNumber(aoi, n, on + l)) { case -1: return -1; case 0: return 0; default: aoi = &(*aoi)->Child; break; } l++; } } *val = v; return 1; }