1 /* This file is part of the YAZ toolkit.
2 * Copyright (C) 1995-2010 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, '&')))
136 *name = (char **) odr_malloc(o, no * sizeof(char*));
137 *val = (char **) odr_malloc(o, no * sizeof(char*));
139 for (no = 0; *path; no++)
141 const char *p1 = strchr(path, '=');
147 (*name)[no] = (char *) odr_malloc(o, (p1-path)+1);
148 memcpy((*name)[no], path, p1-path);
149 (*name)[no][p1-path] = '\0';
152 p1 = strchr(path, '&');
154 p1 = strlen(path) + path;
155 (*val)[no] = ret = (char *) odr_malloc(o, p1 - path + 1);
156 while (*path && *path != '&')
159 ret[i++] = decode_uri_char(path, &l);
172 char *yaz_uri_val(const char *path, const char *name, ODR o)
174 size_t nlen = strlen(name);
178 while (path && *path)
180 const char *p1 = strchr(path, '=');
183 if ((size_t)(p1 - path) == nlen && !memcmp(path, name, nlen))
189 p1 = strchr(path, '&');
191 p1 = strlen(path) + path;
192 ret = (char *) odr_malloc(o, p1 - path + 1);
193 while (*path && *path != '&')
196 ret[i++] = decode_uri_char(path, &l);
202 path = strchr(p1, '&');
212 * c-file-style: "Stroustrup"
213 * indent-tabs-mode: nil
215 * vim: shiftwidth=4 tabstop=8 expandtab