1 /* This file is part of the YAZ toolkit.
2 * Copyright (C) 1995-2013 Index Data
3 * See the file LICENSE for details.
7 * \brief Implements URI utilities.
15 #include <yaz/matchstr.h>
16 #include <yaz/yaz-iconv.h>
18 static int hex_digit (int ch)
20 if (ch >= '0' && ch <= '9')
22 else if (ch >= 'a' && ch <= 'f')
24 else if (ch >= 'A' && ch <= 'F')
29 static void encode_uri_char(char *dst, char ch)
31 /* mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")" */
32 if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') ||
33 (ch >= '0' && ch <= '9') || strchr("-_.!~*'(|)", ch))
41 sprintf(dst+1, "%02X", (unsigned char ) ch);
45 void yaz_encode_uri_component(char *dst, const char *uri)
49 encode_uri_char(dst, *uri);
55 static unsigned char decode_uri_char(const char *path, size_t *len)
63 else if (*path == '%' && *len >= 3)
65 int d1 = hex_digit(path[1]);
66 int d2 = hex_digit(path[2]);
67 if (d1 >= 0 && d2 >= 0)
86 void yaz_decode_uri_component(char *dst, const char *uri, size_t len)
91 *dst++ = decode_uri_char(uri, &sz);
98 void yaz_array_to_uri(char **path, ODR o, char **name, char **value)
100 size_t i, szp = 0, sz = 1;
101 for(i = 0; name[i]; i++)
102 sz += strlen(name[i]) + 3 + strlen(value[i]) * 3;
103 *path = (char *) odr_malloc(o, sz);
105 for(i = 0; name[i]; i++)
109 (*path)[szp++] = '&';
110 ilen = strlen(name[i]);
111 memcpy(*path+szp, name[i], ilen);
113 (*path)[szp++] = '=';
115 yaz_encode_uri_component(*path + szp, value[i]);
116 szp += strlen(*path + szp);
121 int yaz_uri_to_array(const char *path, ODR o, char ***name, char ***val)
131 while ((cp = strchr(cp, '&')))
135 while (*cp && *cp != '=' && *cp != '&')
137 /* check that x-form names looks sane */
138 if (*cp <= ' ' || *cp >= 127)
143 *name = (char **) odr_malloc(o, no * sizeof(char*));
144 *val = (char **) odr_malloc(o, no * sizeof(char*));
146 for (no = 0; *path; no++)
153 for (cp = path; *cp && *cp != '=' && *cp != '&'; cp++)
156 (*name)[no] = odr_strdupn(o, path, cp - path);
163 for (cp = path; *cp && *cp != '&'; cp++)
165 (*val)[no] = ret = (char *) odr_malloc(o, cp - path + 1);
166 while (*path && *path != '&')
169 ret[i++] = decode_uri_char(path, &l);
175 (*val)[no] = odr_strdup(o, "");
186 * c-file-style: "Stroustrup"
187 * indent-tabs-mode: nil
189 * vim: shiftwidth=4 tabstop=8 expandtab