From: mdw Date: Tue, 1 Jun 1999 09:49:48 +0000 (+0000) Subject: New files for url-encoding and decoding. X-Git-Tag: 2.0.4~285 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~mdw/git/mLib/commitdiff_plain/0f2a884637b405e8cdf04801a1e904edeaab1dd5 New files for url-encoding and decoding. --- diff --git a/url.c b/url.c new file mode 100644 index 0000000..5c22601 --- /dev/null +++ b/url.c @@ -0,0 +1,213 @@ +/* -*-c-*- + * + * $Id: url.c,v 1.1 1999/06/01 09:49:48 mdw Exp $ + * + * Parsing and construction of url-encoded name/value pairs + * + * (c) 1999 Straylight/Edgeware + */ + +/*----- Licensing notice --------------------------------------------------* + * + * This file is part of the mLib utilities library. + * + * mLib is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * mLib is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with mLib; if not, write to the Free + * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +/*----- Revision history --------------------------------------------------* + * + * $Log: url.c,v $ + * Revision 1.1 1999/06/01 09:49:48 mdw + * New files for url-encoding and decoding. + * + */ + +/*----- Header files ------------------------------------------------------*/ + +#include +#include +#include + +#include "dstr.h" +#include "url.h" + +/*----- Main code ---------------------------------------------------------*/ + +/* --- @url_initenc@ --- * + * + * Arguments: @url_ectx *ctx@ = pointer to context block + * + * Returns: --- + * + * Use: Initializes a URL encoding context. + */ + +void url_initenc(url_ectx *ctx) +{ + ctx->f = 0; +} + +/* --- @encode@ --- * + * + * Arguments: @dstr *d@ = pointer to output string + * @const char *p@ = pointer to thing to encode + * + * Returns: --- + * + * Use: Encodes the input string into the output string. + */ + +static void encode(dstr *d, const char *p) +{ + while (*p) { + switch (*p) { + case ' ': + DPUTC(d, '+'); + break; + default: + if (*p >= 33 && *p < 127) + DPUTC(d, *p); + else + case '&': + case '+': + case '=': + case '%': + dstr_putf(d, "%%%02x", *p); + break; + } + p++; + } +} + +/* --- @url_enc@ --- * + * + * Arguments: @url_ectx *ctx@ = pointer to encoding context + * @dstr *d@ = pointer to output string + * @const char *name@ = pointer to name + * @const char *value@ = pointer to value + * + * Returns: --- + * + * Use: Writes an assignment between @name@ and @value@ to the + * output string, encoding the values properly. + */ + +void url_enc(url_ectx *ctx, dstr *d, const char *name, const char *value) +{ + if (ctx->f & URLF_SEP) + DPUTC(d, '&'); + encode(d, name); + DPUTC(d, '='); + encode(d, value); + DPUTZ(d); + ctx->f |= URLF_SEP; +} + +/* --- @url_initdec@ --- * + * + * Arguments: @url_dctx *ctx@ = pointer to context block + * @const char *p@ = string to read data from + * + * Returns: --- + * + * Use: Initializes a URL decoding context. + */ + +void url_initdec(url_dctx *ctx, const char *p) +{ + ctx->p = p; +} + +/* --- @decode@ --- * + * + * Arguments: @dstr *d@ = pointer to output string + * @const char *p@ = pointer to input data + * @int eq@ = whether to stop at `=' characters + * + * Returns: Pointer to next available character. + * + * Use: Does a URL decode. + */ + +static const char *decode(dstr *d, const char *p, int eq) +{ + if (!*p) + return (0); + for (;;) { + switch (*p) { + case '=': + if (eq) + return (p); + DPUTC(d, *p); + break; + case 0: + case '&': + return (p); + case '+': + DPUTC(d, ' '); + break; + case '%': { + unsigned int ch; + int n; + int x = sscanf(p + 1, "%2x%n", &ch, &n); + if (x == 1) { + DPUTC(d, ch); + p += n; + break; + } + } + default: + DPUTC(d, *p); + break; + } + p++; + } +} + +/* --- @url_dec@ --- * + * + * Arguments: @url_dctx *ctx@ = pointer to decode context + * @dstr *n@ = pointer to output string for name + * @dstr *v@ = pointer to output string for value + * + * Returns: Nonzero if it read something, zero if there's nothing left + * + * Use: Decodes the next name/value pair from a urlencoded string. + */ + +int url_dec(url_dctx *ctx, dstr *n, dstr *v) +{ + const char *p = ctx->p; + size_t l = n->len; + +again: + if ((p = decode(n, p, 1)) == 0 || *p == 0) + return (0); + if (*p != '=') { + p++; + n->len = l; + goto again; + } + p++; + if ((p = decode(v, p, 0)) == 0) + return (0); + DPUTZ(n); + DPUTZ(v); + ctx->p = p; + return (1); +} + +/*----- That's all, folks -------------------------------------------------*/ diff --git a/url.h b/url.h new file mode 100644 index 0000000..3ccc49a --- /dev/null +++ b/url.h @@ -0,0 +1,125 @@ +/* -*-c-*- + * + * $Id: url.h,v 1.1 1999/06/01 09:49:48 mdw Exp $ + * + * Parsing and construction of url-encoded name/value pairs + * + * (c) 1999 Straylight/Edgeware + */ + +/*----- Licensing notice --------------------------------------------------* + * + * This file is part of the mLib utilities library. + * + * mLib is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * mLib is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with mLib; if not, write to the Free + * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +/*----- Revision history --------------------------------------------------* + * + * $Log: url.h,v $ + * Revision 1.1 1999/06/01 09:49:48 mdw + * New files for url-encoding and decoding. + * + */ + +#ifndef URL_H +#define URL_H + +#ifdef __cplusplus + extern "C" { +#endif + +/*----- Header files ------------------------------------------------------*/ + +#ifndef DSTR_H +# include "dstr.h" +#endif + +/*----- Data structures ---------------------------------------------------*/ + +typedef struct url_ectx { + unsigned f; +} url_ectx; + +enum { + URLF_SEP = 1 +}; + +typedef struct url_dctx { + const char *p; +} url_dctx; + +/*----- Functions provided ------------------------------------------------*/ + +/* --- @url_initenc@ --- * + * + * Arguments: @url_ectx *ctx@ = pointer to context block + * + * Returns: --- + * + * Use: Initializes a URL encoding context. + */ + +extern void url_initenc(url_ectx */*ctx*/); + +/* --- @url_enc@ --- * + * + * Arguments: @url_ectx *ctx@ = pointer to encoding context + * @dstr *d@ = pointer to output string + * @const char *name@ = pointer to name + * @const char *value@ = pointer to value + * + * Returns: --- + * + * Use: Writes an assignment between @name@ and @value@ to the + * output string, encoding the values properly. + */ + +extern void url_enc(url_ectx */*ctx*/, dstr */*d*/, + const char */*name*/, const char */*value*/); + +/* --- @url_initdec@ --- * + * + * Arguments: @url_dctx *ctx@ = pointer to context block + * @const char *p@ = string to read data from + * + * Returns: --- + * + * Use: Initializes a URL decoding context. + */ + +extern void url_initdec(url_dctx */*ctx*/, const char */*p*/); + +/* --- @url_dec@ --- * + * + * Arguments: @url_dctx *ctx@ = pointer to decode context + * @dstr *n@ = pointer to output string for name + * @dstr *v@ = pointer to output string for value + * + * Returns: Nonzero if it read something, zero if there's nothing left + * + * Use: Decodes the next name/value pair from a urlencoded string. + */ + +extern int url_dec(url_dctx */*ctx*/, dstr */*n*/, dstr */*v*/); + +/*----- That's all, folks -------------------------------------------------*/ + +#ifdef __cplusplus + } +#endif + +#endif