+/* {{{ */
+PHP_HTTP_API STATUS _http_parse_cookie(const char *cookie, HashTable *values TSRMLS_DC)
+{
+ const char *key = cookie, *val = NULL;
+ int vallen = 0, keylen = 0, done = 0;
+ zval array;
+
+ Z_ARRVAL(array) = values;
+
+ if (!(val = strchr(cookie, '='))) {
+ return FAILURE;
+ }
+
+#define HTTP_COOKIE_VAL(array, k, str, len) \
+ { \
+ const char *encoded = str; \
+ char *decoded = NULL; \
+ int decoded_len = 0, encoded_len = len; \
+ decoded = estrndup(encoded, encoded_len); \
+ decoded_len = php_url_decode(decoded, encoded_len); \
+ add_assoc_stringl(array, k, decoded, decoded_len, 0); \
+ }
+#define HTTP_COOKIE_FIXKEY() \
+ { \
+ while (isspace(*key)) ++key; \
+ keylen = val - key; \
+ while (isspace(key[keylen - 1])) --keylen; \
+ }
+#define HTTP_COOKIE_FIXVAL() \
+ { \
+ ++val; \
+ while (isspace(*val)) ++val; \
+ vallen = key - val; \
+ while (isspace(val[vallen - 1])) --vallen; \
+ }
+
+ HTTP_COOKIE_FIXKEY();
+ HTTP_COOKIE_VAL(&array, "name", key, keylen);
+
+ /* just a name=value cookie */
+ if (!(key = strchr(val, ';'))) {
+ key = val + strlen(val);
+ HTTP_COOKIE_FIXVAL();
+ HTTP_COOKIE_VAL(&array, "value", val, vallen);
+ }
+ /* additional info appended */
+ else {
+ char *keydup = NULL;
+
+ HTTP_COOKIE_FIXVAL();
+ HTTP_COOKIE_VAL(&array, "value", val, vallen);
+
+ do {
+ if (!(val = strchr(key, '='))) {
+ break;
+ }
+ ++key;
+ HTTP_COOKIE_FIXKEY();
+ keydup = estrndup(key, keylen);
+ if (!(key = strchr(val, ';'))) {
+ done = 1;
+ key = val + strlen(val);
+ }
+ HTTP_COOKIE_FIXVAL();
+ HTTP_COOKIE_VAL(&array, keydup, val, vallen);
+ efree(keydup);
+ } while (!done);
+ }
+ return SUCCESS;
+}
+/* }}} */
+