chiark / gitweb /
Boring.
[mLib] / url.c
CommitLineData
0f2a8846 1/* -*-c-*-
2 *
3 * $Id: url.c,v 1.1 1999/06/01 09:49:48 mdw Exp $
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 $
33 * Revision 1.1 1999/06/01 09:49:48 mdw
34 * New files for url-encoding and decoding.
35 *
36 */
37
38/*----- Header files ------------------------------------------------------*/
39
40#include <stdio.h>
41#include <stdlib.h>
42#include <string.h>
43
44#include "dstr.h"
45#include "url.h"
46
47/*----- Main code ---------------------------------------------------------*/
48
49/* --- @url_initenc@ --- *
50 *
51 * Arguments: @url_ectx *ctx@ = pointer to context block
52 *
53 * Returns: ---
54 *
55 * Use: Initializes a URL encoding context.
56 */
57
58void url_initenc(url_ectx *ctx)
59{
60 ctx->f = 0;
61}
62
63/* --- @encode@ --- *
64 *
65 * Arguments: @dstr *d@ = pointer to output string
66 * @const char *p@ = pointer to thing to encode
67 *
68 * Returns: ---
69 *
70 * Use: Encodes the input string into the output string.
71 */
72
73static void encode(dstr *d, const char *p)
74{
75 while (*p) {
76 switch (*p) {
77 case ' ':
78 DPUTC(d, '+');
79 break;
80 default:
81 if (*p >= 33 && *p < 127)
82 DPUTC(d, *p);
83 else
84 case '&':
85 case '+':
86 case '=':
87 case '%':
88 dstr_putf(d, "%%%02x", *p);
89 break;
90 }
91 p++;
92 }
93}
94
95/* --- @url_enc@ --- *
96 *
97 * Arguments: @url_ectx *ctx@ = pointer to encoding context
98 * @dstr *d@ = pointer to output string
99 * @const char *name@ = pointer to name
100 * @const char *value@ = pointer to value
101 *
102 * Returns: ---
103 *
104 * Use: Writes an assignment between @name@ and @value@ to the
105 * output string, encoding the values properly.
106 */
107
108void url_enc(url_ectx *ctx, dstr *d, const char *name, const char *value)
109{
110 if (ctx->f & URLF_SEP)
111 DPUTC(d, '&');
112 encode(d, name);
113 DPUTC(d, '=');
114 encode(d, value);
115 DPUTZ(d);
116 ctx->f |= URLF_SEP;
117}
118
119/* --- @url_initdec@ --- *
120 *
121 * Arguments: @url_dctx *ctx@ = pointer to context block
122 * @const char *p@ = string to read data from
123 *
124 * Returns: ---
125 *
126 * Use: Initializes a URL decoding context.
127 */
128
129void url_initdec(url_dctx *ctx, const char *p)
130{
131 ctx->p = p;
132}
133
134/* --- @decode@ --- *
135 *
136 * Arguments: @dstr *d@ = pointer to output string
137 * @const char *p@ = pointer to input data
138 * @int eq@ = whether to stop at `=' characters
139 *
140 * Returns: Pointer to next available character.
141 *
142 * Use: Does a URL decode.
143 */
144
145static const char *decode(dstr *d, const char *p, int eq)
146{
147 if (!*p)
148 return (0);
149 for (;;) {
150 switch (*p) {
151 case '=':
152 if (eq)
153 return (p);
154 DPUTC(d, *p);
155 break;
156 case 0:
157 case '&':
158 return (p);
159 case '+':
160 DPUTC(d, ' ');
161 break;
162 case '%': {
163 unsigned int ch;
164 int n;
165 int x = sscanf(p + 1, "%2x%n", &ch, &n);
166 if (x == 1) {
167 DPUTC(d, ch);
168 p += n;
169 break;
170 }
171 }
172 default:
173 DPUTC(d, *p);
174 break;
175 }
176 p++;
177 }
178}
179
180/* --- @url_dec@ --- *
181 *
182 * Arguments: @url_dctx *ctx@ = pointer to decode context
183 * @dstr *n@ = pointer to output string for name
184 * @dstr *v@ = pointer to output string for value
185 *
186 * Returns: Nonzero if it read something, zero if there's nothing left
187 *
188 * Use: Decodes the next name/value pair from a urlencoded string.
189 */
190
191int url_dec(url_dctx *ctx, dstr *n, dstr *v)
192{
193 const char *p = ctx->p;
194 size_t l = n->len;
195
196again:
197 if ((p = decode(n, p, 1)) == 0 || *p == 0)
198 return (0);
199 if (*p != '=') {
200 p++;
201 n->len = l;
202 goto again;
203 }
204 p++;
205 if ((p = decode(v, p, 0)) == 0)
206 return (0);
207 DPUTZ(n);
208 DPUTZ(v);
209 ctx->p = p;
210 return (1);
211}
212
213/*----- That's all, folks -------------------------------------------------*/