ipp_add_attr(ipp_t      *ipp,		/* I - IPP message */
             const char *name,		/* I - Attribute name or NULL */
             ipp_tag_t  group_tag,	/* I - Group tag or IPP_TAG_ZERO */
             ipp_tag_t  value_tag,	/* I - Value tag or IPP_TAG_ZERO */
             int        num_values)	/* I - Number of values */
{
  int			alloc_values;	/* Number of values to allocate */
  ipp_attribute_t	*attr;		/* New attribute */


  DEBUG_printf(("4ipp_add_attr(ipp=%p, name=\"%s\", group_tag=0x%x, value_tag=0x%x, num_values=%d)", (void *)ipp, name, group_tag, value_tag, num_values));

 /*
  * Range check input...
  */

  if (!ipp || num_values < 0)
    return (NULL);

 /*
  * Allocate memory, rounding the allocation up as needed...
  */

  if (num_values <= 1)
    alloc_values = 1;
  else
    alloc_values = (num_values + IPP_MAX_VALUES - 1) & ~(IPP_MAX_VALUES - 1);

  attr = calloc(sizeof(ipp_attribute_t) +
                (size_t)(alloc_values - 1) * sizeof(_ipp_value_t), 1);

  if (attr)
  {
   /*
    * Initialize attribute...
    */

    DEBUG_printf(("4debug_alloc: %p %s %s%s (%d values)", (void *)attr, name, num_values > 1 ? "1setOf " : "", ippTagString(value_tag), num_values));

    if (name)
      attr->name = _cupsStrAlloc(name);

    attr->group_tag  = group_tag;
    attr->value_tag  = value_tag;
    attr->num_values = num_values;

   /*
    * Add it to the end of the linked list...
    */

    if (ipp->last)
      ipp->last->next = attr;
    else
      ipp->attrs = attr;

    ipp->prev = ipp->last;
    ipp->last = ipp->current = attr;
  }

  DEBUG_printf(("5ipp_add_attr: Returning %p", (void *)attr));

  return (attr);
}
ipp_add_attr(ipp_t      *ipp,		 
             const char *name,		 
             ipp_tag_t  group_tag,	 
             ipp_tag_t  value_tag,	 
             int        num_values)	 
{
  int			alloc_values;	 
  ipp_attribute_t	*attr;		 


  DEBUG_printf(("4ipp_add_attr(ipp=%p, name=\"%s\", group_tag=0x%x, value_tag=0x%x, num_values=%d)", (void *)ipp, name, group_tag, value_tag, num_values));

  

  if (!ipp || num_values < 0)
    return (NULL);

  

  if (num_values <= 1)
    alloc_values = 1;
  else
    alloc_values = (num_values + IPP_MAX_VALUES - 1) & ~(IPP_MAX_VALUES - 1);

  attr = calloc(sizeof(ipp_attribute_t) +
                (size_t)(alloc_values - 1) * sizeof(_ipp_value_t), 1);

  if (attr)
  {
    

    DEBUG_printf(("4debug_alloc: %p %s %s%s (%d values)", (void *)attr, name, num_values > 1 ? "1setOf " : "", ippTagString(value_tag), num_values));

    if (name)
      attr->name = _cupsStrAlloc(name);

    attr->group_tag  = group_tag;
    attr->value_tag  = value_tag;
    attr->num_values = num_values;

    

    if (ipp->last)
      ipp->last->next = attr;
    else
      ipp->attrs = attr;

    ipp->prev = ipp->last;
    ipp->last = ipp->current = attr;
  }

  DEBUG_printf(("5ipp_add_attr: Returning %p", (void *)attr));

  return (attr);
}