ss_attr_t *
ss_attr_find(ss_pers_t *owner, /* The object for which we're searching for attributes. */
const char *name, /* An optional attribute name on which to restrict the search. */
size_t nskip, /* Skip the first SKIP matching attributes. */
size_t maxret, /* Return at most MAXRET matching attributes. If the caller passes SS_NOSIZE
* then all matching attributes are returned. If more than MAXRET attributes
* could be returned the remainder are simply discarded. If RESULT is
* non-null then this argument should reflect the size of that array. */
size_t *nret, /* OUT: The number of attributes stored in the returned array of links. */
ss_attr_t *result /* An optional buffer in which to store links to the matching attributes. If
* supplied, this will be the successful return value. The constant
* SS_PERS_TEST can be supplied in order to prevent the library from
* allocating a return value (this is useful if the caller simply wants to
* count the matches). */
)
{
SS_ENTER(ss_attr_find, ss_attr_tP);
static ss_attr_t *key; /* Key of values to use when searching the attribute table */
ss_attrobj_t mask; /* What parts of KEY are significant and how? */
ss_scope_t scope=SS_SCOPE_NULL; /* The scope containing OWNER */
SS_ASSERT_CLASS(owner, ss_pers_t);
if (!nret) SS_ERROR_FMT(USAGE, ("NRET argument was null"));
if (NULL==ss_pers_scope(owner, &scope)) SS_ERROR(FAILED);
/* Create or reset key and mask */
memset(&mask, 0, sizeof mask);
if (!key && NULL==(key=SS_PERS_NEW(sslib_g.temp.tscope, ss_attr_t, 0))) {
SS_ERROR(FAILED);
} else if (ss_pers_reset((ss_pers_t*)key, 0)<0) {
SS_ERROR(FAILED);
}
/* Initialize key and mask with values for which to search */
SS_ATTR(key)->owner = *owner;
memset(&(mask.owner), SS_VAL_CMP_DFLT, 1);
if (name) {
ss_string_set(SS_ATTR_P(key,name), name);
memset(&(mask.name), SS_VAL_CMP_DFLT, 1);
}
/* Search */
*nret = maxret;
if (NULL==(result=(ss_attr_t*)ss_pers_find(&scope, (ss_pers_t*)key, (ss_persobj_t*)&mask, nskip, nret,
(ss_pers_t*)result, NULL))) {
SS_ERROR(FAILED);
}
SS_CLEANUP:
if (nret) *nret = 0;
SS_LEAVE(result);
}