chiark / gitweb /
Minor typo fixes.
[mLib] / url.c
CommitLineData
0f2a8846 1/* -*-c-*-
2 *
d16e1bac 3 * $Id: url.c,v 1.2 1999/09/03 08:02:05 mdw Exp $
0f2a8846 4 *
5 * Parsing and construction of url-encoded name/value pairs
6 *
7 * (c) 1999 Straylight/Edgeware
8 */
9
10/*----- Licensing notice --------------------------------------------------*
11 *
12 * This file is part of the mLib utilities library.
13 *
14 * mLib is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU Library General Public License as
16 * published by the Free Software Foundation; either version 2 of the
17 * License, or (at your option) any later version.
18 *
19 * mLib is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU Library General Public License for more details.
23 *
24 * You should have received a copy of the GNU Library General Public
25 * License along with mLib; if not, write to the Free
26 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
27 * MA 02111-1307, USA.
28 */
29
30/*----- Revision history --------------------------------------------------*
31 *
32 * $Log: url.c,v $
d16e1bac 33 * Revision 1.2 1999/09/03 08:02:05 mdw
34 * Make `#' a special character which needs escaping.
35 *
0f2a8846 36 * Revision 1.1 1999/06/01 09:49:48 mdw
37 * New files for url-encoding and decoding.
38 *
39 */
40
41/*----- Header files ------------------------------------------------------*/
42
43#include <stdio.h>
44#include <stdlib.h>
45#include <string.h>
46
47#include "dstr.h"
48#include "url.h"
49
50/*----- Main code ---------------------------------------------------------*/
51
52/* --- @url_initenc@ --- *
53 *
54 * Arguments: @url_ectx *ctx@ = pointer to context block
55 *
56 * Returns: ---
57 *
58 * Use: Initializes a URL encoding context.
59 */
60
61void url_initenc(url_ectx *ctx)
62{
63 ctx->f = 0;
64}
65
66/* --- @encode@ --- *
67 *
68 * Arguments: @dstr *d@ = pointer to output string
69 * @const char *p@ = pointer to thing to encode
70 *
71 * Returns: ---
72 *
73 * Use: Encodes the input string into the output string.
74 */
75
76static void encode(dstr *d, const char *p)
77{
78 while (*p) {
79 switch (*p) {
80 case ' ':
81 DPUTC(d, '+');
82 break;
83 default:
84 if (*p >= 33 && *p < 127)
85 DPUTC(d, *p);
86 else
87 case '&':
88 case '+':
89 case '=':
90 case '%':
d16e1bac 91 case '#':
0f2a8846 92 dstr_putf(d, "%%%02x", *p);
93 break;
94 }
95 p++;
96 }
97}
98
99/* --- @url_enc@ --- *
100 *
101 * Arguments: @url_ectx *ctx@ = pointer to encoding context
102 * @dstr *d@ = pointer to output string
103 * @const char *name@ = pointer to name
104 * @const char *value@ = pointer to value
105 *
106 * Returns: ---
107 *
108 * Use: Writes an assignment between @name@ and @value@ to the
109 * output string, encoding the values properly.
110 */
111
112void url_enc(url_ectx *ctx, dstr *d, const char *name, const char *value)
113{
114 if (ctx->f & URLF_SEP)
115 DPUTC(d, '&');
116 encode(d, name);
117 DPUTC(d, '=');
118 encode(d, value);
119 DPUTZ(d);
120 ctx->f |= URLF_SEP;
121}
122
123/* --- @url_initdec@ --- *
124 *
125 * Arguments: @url_dctx *ctx@ = pointer to context block
126 * @const char *p@ = string to read data from
127 *
128 * Returns: ---
129 *
130 * Use: Initializes a URL decoding context.
131 */
132
133void url_initdec(url_dctx *ctx, const char *p)
134{
135 ctx->p = p;
136}
137
138/* --- @decode@ --- *
139 *
140 * Arguments: @dstr *d@ = pointer to output string
141 * @const char *p@ = pointer to input data
142 * @int eq@ = whether to stop at `=' characters
143 *
144 * Returns: Pointer to next available character.
145 *
146 * Use: Does a URL decode.
147 */
148
149static const char *decode(dstr *d, const char *p, int eq)
150{
151 if (!*p)
152 return (0);
153 for (;;) {
154 switch (*p) {
155 case '=':
156 if (eq)
157 return (p);
158 DPUTC(d, *p);
159 break;
160 case 0:
161 case '&':
162 return (p);
163 case '+':
164 DPUTC(d, ' ');
165 break;
166 case '%': {
167 unsigned int ch;
168 int n;
169 int x = sscanf(p + 1, "%2x%n", &ch, &n);
170 if (x == 1) {
171 DPUTC(d, ch);
172 p += n;
173 break;
174 }
175 }
176 default:
177 DPUTC(d, *p);
178 break;
179 }
180 p++;
181 }
182}
183
184/* --- @url_dec@ --- *
185 *
186 * Arguments: @url_dctx *ctx@ = pointer to decode context
187 * @dstr *n@ = pointer to output string for name
188 * @dstr *v@ = pointer to output string for value
189 *
190 * Returns: Nonzero if it read something, zero if there's nothing left
191 *
192 * Use: Decodes the next name/value pair from a urlencoded string.
193 */
194
195int url_dec(url_dctx *ctx, dstr *n, dstr *v)
196{
197 const char *p = ctx->p;
198 size_t l = n->len;
199
200again:
201 if ((p = decode(n, p, 1)) == 0 || *p == 0)
202 return (0);
203 if (*p != '=') {
204 p++;
205 n->len = l;
206 goto again;
207 }
208 p++;
209 if ((p = decode(v, p, 0)) == 0)
210 return (0);
211 DPUTZ(n);
212 DPUTZ(v);
213 ctx->p = p;
214 return (1);
215}
216
217/*----- That's all, folks -------------------------------------------------*/