From b64b3086f4392a564fb5dcc0c5a206cc58dbebd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20M=C3=B6ller?= <nisse@lysator.liu.se> Date: Mon, 21 Oct 2002 15:40:37 +0200 Subject: [PATCH] (sexp_transport_iterator_first): New file and function. Rev: src/nettle/sexp-transport.c:1.1 --- sexp-transport.c | 118 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 sexp-transport.c diff --git a/sexp-transport.c b/sexp-transport.c new file mode 100644 index 00000000..7737891c --- /dev/null +++ b/sexp-transport.c @@ -0,0 +1,118 @@ +/* sexp-transport.c + * + * Parsing s-expressions in transport format. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002 Niels Möller + * + * The nettle library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. + * + * The nettle library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the nettle library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +#include "sexp.h" + +#include "base64.h" + +#include <assert.h> +#include <string.h> + +/* NOTE: Decodes the input string in place */ +int +sexp_transport_iterator_first(struct sexp_iterator *iterator, + unsigned length, uint8_t *input) +{ + /* We first base64 decode any transport encoded sexp at the start of + * the input. */ + + unsigned in = 0; + unsigned out = 0; + + while (in < length) + switch(input[in]) + { + case ' ': /* SPC, TAB, LF, CR */ + case '\t': + case '\n': + case '\r': + in++; + break; + + case ';': /* Comments */ + while (++in < length && input[in] != '\n') + ; + break; + + case '{': + { + /* Found transport encoding */ + struct base64_decode_ctx ctx; + unsigned end; + + for (end = ++in; end < length && input[end] != '}'; end++) + ; + + if (end == length) + return 0; + + base64_decode_init(&ctx); + + out += base64_decode_update(&ctx, input + out, + end - in, input + in); + if (!base64_decode_status(&ctx)) + return 0; + in = end + 1; + + break; + } + default: + /* Expression isn't in transport encoding. Rest of the input + * should be in canonical encoding. */ + goto transport_done; + } + + transport_done: + + /* Here, we have two, possibly empty, input parts in canonical + * encoding: + * + * 0...out-1, in...length -1 + * + * If the input was already in canonical encoding, out = 0 and in = + * amount of leading space. + * + * If all input was in transport encoding, in == length. + */ + if (!out) + { + input += in; + length -= in; + } + else if (in == length) + length = out; + else if (out == in) + /* Unusual case, nothing happens */ + ; + else + { + /* Both parts non-empty */ + assert(out < in); + memmove(input + out, input + in, length - in); + length -= (in - out); + } + + return sexp_iterator_first(iterator, length, input); +} -- GitLab