Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support hierarchical searches with ippFindAttribute #4395

Closed
michaelrsweet opened this issue Mar 28, 2014 · 2 comments
Closed

Support hierarchical searches with ippFindAttribute #4395

michaelrsweet opened this issue Mar 28, 2014 · 2 comments
Labels
enhancement New feature or request
Milestone

Comments

@michaelrsweet
Copy link
Collaborator

Version: 2.0-feature
CUPS.org User: mike

In order to allow programs like ipptool to validate collection values, we need to be able to find member attributes of collections.

The simplest solution is to support attribute names with slashes as the delimiter (slash is not a valid attribute name character), e.g.:

ipp_attribute_t *size = ippFindAttribute(request, "media-col/media-size", IPP_TAG_BEGIN_COLLECTION);
@michaelrsweet
Copy link
Collaborator Author

CUPS.org User: mike

Fixed in Subversion repository.

@michaelrsweet
Copy link
Collaborator Author

"str4395.patch":

Index: cups/ipp.c

--- cups/ipp.c (revision 11775)
+++ cups/ipp.c (working copy)
@@ -1983,6 +1983,10 @@

/*

  • '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 */
    @@ -2001,6 +2005,7 @@
    */

    ipp->current = NULL;

    • ipp->atend = 0;

    /*

    • Search for the attribute...
      @@ -2012,6 +2017,10 @@

    /*

  • '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 /
    @@ -2019,8 +2028,11 @@
    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))",
    @@ -2029,8 +2041,61 @@
    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;
    }
    @@ -2048,18 +2113,33 @@
    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);
}

Index: cups/ipp.h

--- cups/ipp.h (revision 11775)
+++ cups/ipp.h (working copy)
@@ -804,6 +804,9 @@

/**** New in CUPS 1.4.4 */
int use; /
Use count @SInCE CUPS 1.4.4/OS X 10.6.?@ /
+/
* New in CUPS 2.0 ****/

  • int atend, /* At end of list? */
  •       curindex;   /\* Current attribute index for hierarchical search _/
    
    };

    endif /_ _IPP_PRIVATE_STRUCTURES */

Index: cups/testipp.c

--- cups/testipp.c (revision 11775)
+++ cups/testipp.c (working copy)
@@ -542,6 +542,53 @@
}
}

  • /*
  • * 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);

    /*

@michaelrsweet michaelrsweet added the enhancement New feature or request label Mar 17, 2016
@michaelrsweet michaelrsweet added this to the Stable milestone Mar 17, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant