From 130bdba4f9aadc2d9fc0108c11e6baafd4474d74 Mon Sep 17 00:00:00 2001 From: Rob Swindell <rob@synchro.net> Date: Fri, 4 Jun 2021 23:29:01 -0700 Subject: [PATCH] Generic hexadecimal encode/decode string functions (e.g. for URL decode) These functions can be used for "percent encode/decode" or any other 2-hex-digit encoding/decoding with a single escape character. --- src/encode/hex.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++ src/encode/hex.h | 38 +++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+) create mode 100644 src/encode/hex.c create mode 100644 src/encode/hex.h diff --git a/src/encode/hex.c b/src/encode/hex.c new file mode 100644 index 0000000000..5cf4c4de5d --- /dev/null +++ b/src/encode/hex.c @@ -0,0 +1,59 @@ +/* Hexadecimal encode/decode (e.g. URL encode/decode) functions */ + +/**************************************************************************** + * @format.tab-size 4 (Plain Text/Source Code File Header) * + * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * + * * + * Copyright Rob Swindell - http://www.synchro.net/copyright.html * + * * + * This 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 * + * of the License, or (at your option) any later version. * + * See the GNU Lesser General Public License for more details: lgpl.txt or * + * http://www.fsf.org/copyleft/lesser.html * + * * + * For Synchronet coding style and modification guidelines, see * + * http://www.synchro.net/source.html * + * * + * Note: If this box doesn't appear square, then you need to fix your tabs. * + ****************************************************************************/ + +#include "hex.h" +#include "genwrap.h" +#include "gen_defs.h" + +char* hex_encode(char esc, const char* src, char* chars, char* dest, size_t size) +{ + char* result = dest; + char* end = dest + (size - 1); + + while(*src != '\0' && dest < end) { + if((*src == esc || strchr(chars, *src) != NULL) && dest + 3 < end) + dest += sprintf(dest, "%c%2X", esc, *src); + else + *(dest++) = *src; + src++; + } + *end = '\0'; + return result; +} + +char* hex_decode(char esc, char* str) +{ + char* src = str; + char* dest = str; + while(*src != '\0') { + if(*src == esc && IS_HEXDIGIT(*(src + 1)) && IS_HEXDIGIT(*(src + 2))) { + src++; + *dest = HEX_CHAR_TO_INT(*src) << 4; + src++; + *dest |= HEX_CHAR_TO_INT(*src); + } else + *dest = *src; + src++; + dest++; + } + *dest = '\0'; + return str; +} diff --git a/src/encode/hex.h b/src/encode/hex.h new file mode 100644 index 0000000000..9765bca85e --- /dev/null +++ b/src/encode/hex.h @@ -0,0 +1,38 @@ +/* Hex encode/decode (e.g. URL encode/decode) functions */ + +/**************************************************************************** + * @format.tab-size 4 (Plain Text/Source Code File Header) * + * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * + * * + * Copyright Rob Swindell - http://www.synchro.net/copyright.html * + * * + * This 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 * + * of the License, or (at your option) any later version. * + * See the GNU Lesser General Public License for more details: lgpl.txt or * + * http://www.fsf.org/copyleft/lesser.html * + * * + * For Synchronet coding style and modification guidelines, see * + * http://www.synchro.net/source.html * + * * + * Note: If this box doesn't appear square, then you need to fix your tabs. * + ****************************************************************************/ + +#ifndef hex_h_ +#define hex_h_ + +#include <stdlib.h> // size_t + +#ifdef __cplusplus +extern "C" { +#endif + +char* hex_encode(char esc, const char* src, char* chars, char* dest, size_t size); +char* hex_decode(char esc, char* str); + +#ifdef __cplusplus +} +#endif + +#endif /* Don't add anything after this line */ \ No newline at end of file -- GitLab