/*
* 'ippFindAttribute()' - Find a named attribute in a request.
+ *
+ * Starting with CUPS 2.0, the attribute name can contain a hierarchical list
+ * of attribute and member names separated by slashes, for example
+ * "media-col/media-size".
*/
ipp_attribute_t * /* O - Matching attribute */
*/
ipp->current = NULL;
+ ipp->atend = 0;
/*
* Search for the attribute...
/*
* 'ippFindNextAttribute()' - Find the next named attribute in a request.
+ *
+ * Starting with CUPS 2.0, the attribute name can contain a hierarchical list
+ * of attribute and member names separated by slashes, for example
+ * "media-col/media-size".
*/
ipp_attribute_t * /* O - Matching attribute */
const char *name, /* I - Name of attribute */
ipp_tag_t type) /* I - Type of attribute */
{
- ipp_attribute_t *attr; /* Current atttribute */
+ ipp_attribute_t *attr, /* Current atttribute */
+ *childattr; /* Child attribute */
ipp_tag_t value_tag; /* Value tag */
+ char parent[1024], /* Parent attribute name */
+ *child; /* Child attribute name */
DEBUG_printf(("2ippFindNextAttribute(ipp=%p, name=\"%s\", type=%02x(%s))",
if (!ipp || !name)
return (NULL);
- if (ipp->current)
+ DEBUG_printf(("3ippFindNextAttribute: atend=%d", ipp->atend));
+
+ if (ipp->atend)
+ return (NULL);
+
+ if (strchr(name, '/'))
+ {
+ /*
+ * Search for child attribute...
+ */
+
+ strlcpy(parent, name, sizeof(parent));
+ if ((child = strchr(parent, '/')) == NULL)
+ {
+ DEBUG_puts("3ippFindNextAttribute: Attribute name too long.");
+ return (NULL);
+ }
+
+ *child++ = '\0';
+
+ if (ipp->current && ipp->current->name && ipp->current->value_tag == IPP_TAG_BEGIN_COLLECTION && !strcmp(parent, ipp->current->name))
+ {
+ while (ipp->curindex < ipp->current->num_values)
+ {
+ if ((childattr = ippFindNextAttribute(ipp->current->values[ipp->curindex].collection, child, type)) != NULL)
+ return (childattr);
+
+ ipp->curindex ++;
+ if (ipp->curindex < ipp->current->num_values && ipp->current->values[ipp->curindex].collection)
+ ipp->current->values[ipp->curindex].collection->current = NULL;
+ }
+
+ ipp->prev = ipp->current;
+ ipp->current = ipp->current->next;
+ ipp->curindex = 0;
+
+ if (!ipp->current)
+ {
+ ipp->atend = 1;
+ return (NULL);
+ }
+ }
+
+ if (!ipp->current)
+ {
+ ipp->prev = NULL;
+ ipp->current = ipp->attrs;
+ ipp->curindex = 0;
+ }
+
+ name = parent;
+ attr = ipp->current;
+ }
+ else if (ipp->current)
{
ipp->prev = ipp->current;
attr = ipp->current->next;
value_tag = (ipp_tag_t)(attr->value_tag & IPP_TAG_CUPS_MASK);
if (attr->name != NULL && _cups_strcasecmp(attr->name, name) == 0 &&
- (value_tag == type || type == IPP_TAG_ZERO ||
+ (value_tag == type || type == IPP_TAG_ZERO || name == parent ||
(value_tag == IPP_TAG_TEXTLANG && type == IPP_TAG_TEXT) ||
(value_tag == IPP_TAG_NAMELANG && type == IPP_TAG_NAME)))
{
ipp->current = attr;
- return (attr);
+ if (name == parent && attr->value_tag == IPP_TAG_BEGIN_COLLECTION)
+ {
+ int i; /* Looping var */
+
+ for (i = 0; i < attr->num_values; i ++)
+ {
+ if ((childattr = ippFindAttribute(attr->values[i].collection, child, type)) != NULL)
+ {
+ attr->values[0].collection->curindex = i;
+ return (childattr);
+ }
+ }
+ }
+ else
+ return (attr);
}
}
ipp->current = NULL;
ipp->prev = NULL;
+ ipp->atend = 1;
return (NULL);
}
}
}
+ /*
+ * Test hierarchical find...
+ */
+
+ fputs("ippFindAttribute(media-col/media-size/x-dimension): ", stdout);
+ if ((attr = ippFindAttribute(request, "media-col/media-size/x-dimension", IPP_TAG_INTEGER)) != NULL)
+ {
+ if (ippGetInteger(attr, 0) != 21590)
+ {
+ printf("FAIL (wrong value for x-dimension - %d)\n", ippGetInteger(attr, 0));
+ status = 1;
+ }
+ else
+ puts("PASS");
+ }
+ else
+ {
+ puts("FAIL (not found)");
+ status = 1;
+ }
+
+ fputs("ippFindNextAttribute(media-col/media-size/x-dimension): ", stdout);
+ if ((attr = ippFindNextAttribute(request, "media-col/media-size/x-dimension", IPP_TAG_INTEGER)) != NULL)
+ {
+ if (ippGetInteger(attr, 0) != 21000)
+ {
+ printf("FAIL (wrong value for x-dimension - %d)\n", ippGetInteger(attr, 0));
+ status = 1;
+ }
+ else
+ puts("PASS");
+ }
+ else
+ {
+ puts("FAIL (not found)");
+ status = 1;
+ }
+
+ fputs("ippFindNextAttribute(media-col/media-size/x-dimension) again: ", stdout);
+ if ((attr = ippFindNextAttribute(request, "media-col/media-size/x-dimension", IPP_TAG_INTEGER)) != NULL)
+ {
+ printf("FAIL (got %d, expected nothing)\n", ippGetInteger(attr, 0));
+ status = 1;
+ }
+ else
+ puts("PASS");
+
ippDelete(request);
/*