int
saf_find_quantities(SAF_ParMode pmode,
SAF_Db *db, /* Database in which to limit the search. */
const char *desc, /* Optional quantity description for which to search. */
const char *abbr, /* Optional abbreviation for which to search. */
const char *url, /* Optional URL for which to search. */
unsigned flags, /* Optional flags for which to search, or SAF_ANY_INT. */
int *power, /* Optional base quantity powers for which to search. If the pointer is
* non-null then the elements can be SAF_ANY_INT for the ones in which the
* caller is not interested. */
int *num, /* For this and the succeeding argument [see Returned Handles]. */
SAF_Quantity **found /* For this and the preceding argument [see Returned Handles]. */
)
{
SAF_ENTER(saf_find_quantities, SAF_PRECONDITION_ERROR);
SAF_KEYMASK(SAF_Quantity, key, mask);
size_t nfound;
ss_scope_t scope;
int i;
SAF_REQUIRE(_saf_valid_pmode(pmode), SAF_LOW_CHK_COST, SAF_PRECONDITION_ERROR,
_saf_errmsg("PMODE must be valid"));
if (!_saf_is_participating_proc(pmode)) SAF_RETURN(-1);
SAF_REQUIRE(ss_file_isopen(db, NULL)>0, SAF_LOW_CHK_COST, SAF_PRECONDITION_ERROR,
_saf_errmsg("DB must be a valid database"));
SAF_REQUIRE(_saf_valid_memhints(num, (void**)found), SAF_LOW_CHK_COST, SAF_PRECONDITION_ERROR,
_saf_errmsg("NUM and FOUND must be compatible for return value allocation"));
ss_file_topscope(db, &scope);
if (desc) SAF_SEARCH_S(SAF_Quantity, key, mask, name, desc);
if (abbr) SAF_SEARCH_S(SAF_Quantity, key, mask, abbr, abbr);
if (url) SAF_SEARCH_S(SAF_Quantity, key, mask, url, url);
if (SAF_ANY_INT!=flags) SAF_SEARCH(SAF_Quantity, key, mask, flags, flags);
if (power) {
for (i=0; i<SS_MAX_BASEQS; i++) {
if (SAF_ANY_INT!=power[i]) SAF_SEARCH(SAF_Quantity, key, mask, power[i], power[i]);
}
}
if (!found) {
/* Count the matches */
assert(num);
nfound = SS_NOSIZE;
ss_pers_find(&scope, (ss_pers_t*)key, mask_count?(ss_persobj_t*)&mask:NULL, 0, &nfound, SS_PERS_TEST, NULL);
*num = nfound;
} else if (!*found) {
/* Find all matches; library allocates results */
nfound = SS_NOSIZE;
*found = (ss_quantity_t*)ss_pers_find(&scope, (ss_pers_t*)key, mask_count?(ss_persobj_t*)&mask:NULL, 0, &nfound,
NULL, NULL);
if (num) *num = nfound;
} else {
/* Find limited matches; client allocates result buffer */
assert(num);
nfound = *num;
if (NULL==ss_pers_find(&scope, (ss_pers_t*)key, mask_count?(ss_persobj_t*)&mask:NULL, 0, &nfound, (ss_pers_t*)*found,
_SAF_GLOBALS.find_detect_overflow)) {
SAF_ERROR(SAF_CONSTRAINT_ERROR, _saf_errmsg("found too many matching objects"));
}
*num = nfound;
}
SAF_LEAVE(SAF_SUCCESS);
}