STATUS MO_ipindex(i4 msg, PTR cdata, i4 linstance, char *instance, PTR *instdata ) { STATUS stat = MO_NO_INSTANCE; MO_INSTANCE *ip; ip = MO_getinstance( (char *)cdata, instance ); switch( msg ) { case MO_GET: if( ip != NULL ) stat = OK; break; case MO_GETNEXT: if( ip != NULL ) { ip = (MO_INSTANCE *) SPnext( &ip->node, MO_instances ); if( ip != NULL && !STequal( (char *)ip->classdef->node.key, (char *)cdata ) ) ip = NULL; } else /* didn't find directly */ { if( *instance == EOS ) ip = MO_getinstance( (char *)cdata, (char *)NULL ); else break; } if( ip == NULL ) stat = MO_NO_NEXT; else stat = MOstrout( MO_INSTANCE_TRUNCATED, ip->instance, linstance, instance ); break; default: stat = MO_BAD_MSG; break; } *instdata = (PTR)ip; return( stat ); }
MO_INSTANCE * MO_getinstance( char *classid, char *instance ) { MO_CLASS cb; MO_INSTANCE ib; MO_INSTANCE *ip; cb.node.key = classid; ib.classdef = &cb; ib.instance = instance; ib.node.key = (PTR)&ib; if( instance != NULL ) /* find exact match */ { ip = (MO_INSTANCE *)SPlookup( &ib.node, MO_instances ); } else /* find first of that class */ { /* ** This relies on the comparison function returning -1 ** when classids are equal, and the input instance is NULL. ** After the enq, ib is the lowest block of the class; the ** next one is the old first. */ (VOID) SPenq( &ib.node, MO_instances ); ip = (MO_INSTANCE *)SPnext( &ib.node, MO_instances ); SPdelete( &ib.node, MO_instances ); if( ip != NULL && !STequal( (char *)ip->classdef->node.key, classid ) ) ip = NULL; } # ifdef xDEBUG SIprintf("getinstance %s:%s -> %s:%s\n", classid ? classid : "<nil>", instance ? instance : "<nil>", ip ? ip->classdef->node.key : "<nil>", ip ? ip->instance : "<nil>" ); # endif return( ip ); }
STATUS MO_getnext(i4 valperms, i4 lclassid, i4 linstance, char *classid, char *instance, i4 *lsbufp, char *sbuf, i4 *operms ) { STATUS stat = OK; STATUS xstat = OK; MO_INSTANCE *ip; MO_CLASS *cp; /* this class */ PTR idata; MO_ngetnext++; # ifdef xDEBUG SIprintf("getnext entry: %s:%s\n", classid, instance ); # endif ip = NULL; cp = NULL; *sbuf = EOS; if( *instance != EOS ) { ip = MO_getinstance( classid, instance ); if( ip != NULL ) cp = ip->classdef; else if( OK != MO_getclass( classid, &cp ) ) stat = MO_NO_CLASSID; } else if( *classid != EOS && OK != MO_getclass( classid, &cp ) ) { stat = MO_NO_CLASSID; } /* ** Now do the real work: Given the starting point implied ** by ip and cp, find the next visible instance. */ if( stat == OK ) { if( cp == NULL ) /* start with first class */ { cp = (MO_CLASS *) SPfhead( MO_classes ); ip = NULL; } /* ** Loop over classes looking for the next valid instance. ** ** On exit, if cp != NULL, it's the class of the found instance; ** if NULL, then we never found a good instance. */ for( ; cp != NULL ; cp = (MO_CLASS *)SPnext( &cp->node, MO_classes ) ) { if( (cp->perms & MO_ANY_READ) != 0 || (valperms & MO_READ & cp->perms) != 0 ) { stat = (*cp->idx)( MO_GETNEXT, cp->cdata, linstance, instance, &idata ); if( stat == OK ) { stat = (*cp->get)( cp->offset, cp->size, idata, *lsbufp, sbuf ); if( stat == OK ) break; } } /* Now caller's ip and instance are bogus; set to search state */ ip = NULL; *instance = EOS; } if( cp == NULL ) stat = MO_NO_NEXT; if( stat == OK || MO_IS_TRUNCATED( stat ) ) xstat = MOstrout( MO_CLASSID_TRUNCATED, cp->node.key, lclassid, classid ); if( stat == OK ) stat = xstat; } *lsbufp = (i4)STlength( sbuf ); if( stat == OK || stat == MO_VALUE_TRUNCATED ) { *operms = cp->perms; (VOID) MO_tell_class( cp, instance, sbuf, MO_GET ); } # ifdef xDEBUG SIprintf("getnext exit: (%d) %s:%s - %s\n", stat, classid, instance, sbuf ); # endif return( stat ); }