/** Decode (parse) a Cookie header */
issize_t http_cookie_d(su_home_t *home, msg_header_t *h, char *s, isize_t slen)
{
  http_cookie_t *c = (http_cookie_t *)h;

  assert(h); assert(sizeof(*h));

  for (;*s;) {
    /* Ignore empty entries (comma-whitespace) */
    if (*s == ',') { *s++ = '\0'; skip_lws(&s); continue; }

    if (msg_any_list_d(home, &s, (msg_param_t **)&c->c_params,
		       cookie_scanner, ';') == -1)
      return -1;

    if (*s != '\0' && *s != ',')
      return -1;

    if (!c->c_params)
      return -1;
  }

  http_cookie_update(c);

  return 0;
}
static issize_t
sip_caller_prefs_field_d(su_home_t *home, sip_header_t *h, char **ss)
{
  sip_caller_prefs_t *cp = (sip_caller_prefs_t *)h;
  url_t url[1];
  char const *ignore = NULL;
  int kludge = 0;

  if (su_strnmatch(*ss, "*,", 2)) {
    /* Kludge: support PoC IS spec with a typo... */
    (*ss)[1] = ';', kludge = 0;
  }
  else if (**ss != '*' && **ss != '<') {
    /* Kludge: missing URL -  */
    size_t n = span_attribute_value(*ss);

    if (n > 0) {
      char end = (*ss)[n];
      kludge = end == '\0' || end == ',' || end == ';';
    }
  }

  if (kludge) {
    return msg_any_list_d(home, ss, (msg_param_t **)&cp->cp_params,
			  msg_attribute_value_scanner, ';');
  }
  /* Parse params (and ignore display name and url) */
  else {
    return sip_name_addr_d(home, ss, &ignore, url, &cp->cp_params, NULL);

    /* Be liberal... */
    /* if (url->url_type != url_any)
       return -1; */
  }
}
/** Decode (parse) Set-Cookie header */
issize_t http_set_cookie_d(su_home_t *home, msg_header_t *h, char *s, isize_t slen)
{
  msg_header_t **hh = &h->sh_succ, *h0 = h;
  http_set_cookie_t *sc = (http_set_cookie_t *)h;
  msg_param_t *params;

  assert(h); assert(sizeof(*h));

  for (;*s;) {
    /* Ignore empty entries (comma-whitespace) */
    if (*s == ',') { *s++ = '\0'; skip_lws(&s); continue; }

    if (!h) {      /* Allocate next header structure */
      if (!(h = msg_header_alloc(home, h0->sh_class, 0)))
	return -1;
      *hh = h; h->sh_prev = hh; hh = &h->sh_succ;
      sc = sc->sc_next = (http_set_cookie_t *)h;
    }

    /* "Set-Cookie:" 1#(NAME "=" VALUE *(";" cookie-av))) */
    params = su_zalloc(home, MSG_PARAMS_NUM(1) * sizeof(msg_param_t));
    if (!params)
      return -1;

    params[0] = s, sc->sc_params = params;
    s += strcspn(s, ",;" LWS);

    if (*s) {
      *s++ = '\0';
      skip_lws(&s);
      if (*s && msg_any_list_d(home, &s, (msg_param_t **)&sc->sc_params,
			       set_cookie_scanner, ';') == -1)
	return -1;
    }

    if (*s != '\0' && *s != ',')
      return -1;

    if (sc->sc_params)
      http_set_cookie_update(sc);

    h = NULL;
  }

  return 0;
}
static
issize_t sip_caller_prefs_d(su_home_t *home, sip_header_t *h,
			    char *s, isize_t slen)
{
	for(;;) {
		sip_caller_prefs_t *cp = (sip_caller_prefs_t *)h;
		url_t url[1];
		char const *ignore = NULL;
		int kludge = 0;

		assert(h);

		while (*s == ',')   /* Ignore empty entries (comma-whitespace) */
			*s = '\0', s += span_lws(s + 1) + 1;

		/* Kludge: support PoC IS spec with a typo... */
		if (su_casenmatch(s, "*,", 2))
			s[1] = ';',  kludge = 0;
		else if (s[0] != '*' && s[0] != '<') {
			/* Kludge: missing URL -  */
			size_t n = span_attribute_value(s);
			kludge = n > 0 && (s[n] == '\0' || s[n] == ',' || s[n] == ';');
		}

		if (kludge) {
			if (msg_any_list_d(home, &s, (msg_param_t **)&cp->cp_params,
							   msg_attribute_value_scanner, ';') == -1)
				return -1;
		}
		/* Parse params (and ignore display name and url) */
		else if (sip_name_addr_d(home, &s, &ignore, url, &cp->cp_params, NULL)
				 == -1)
			return -1;
		/* Be liberal... */
		/* if (url->url_type != url_any)
		   return -1; */
		msg_parse_next_field_without_recursion();
	}
	
}