diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2012-10-31 14:36:00 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2012-10-31 14:36:00 +0000 |
commit | 608e5adab4915ada5c2881d66d20e3d6fa0efba5 (patch) | |
tree | bbc2662360f180653bb42c54b921dec07135b648 /apps/netutils/codecs/base64.c | |
parent | 120fc05c1d11406857c6d245abe9a344dcaae268 (diff) | |
download | nuttx-608e5adab4915ada5c2881d66d20e3d6fa0efba5.tar.gz nuttx-608e5adab4915ada5c2881d66d20e3d6fa0efba5.tar.bz2 nuttx-608e5adab4915ada5c2881d66d20e3d6fa0efba5.zip |
Add apps/netutils/codecs and associated NSH commands from Darcy Gong
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5280 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'apps/netutils/codecs/base64.c')
-rw-r--r-- | apps/netutils/codecs/base64.c | 359 |
1 files changed, 359 insertions, 0 deletions
diff --git a/apps/netutils/codecs/base64.c b/apps/netutils/codecs/base64.c new file mode 100644 index 000000000..c1656b343 --- /dev/null +++ b/apps/netutils/codecs/base64.c @@ -0,0 +1,359 @@ +/**************************************************************************** + * apps/include/netutils/base64.h + * + * This file is part of the NuttX RTOS: + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Darcy Gong + * + * Reference: + * + * Base64 encoding/decoding (RFC1341) + * Copyright (c) 2005, Jouni Malinen <jkmaline@cc.hut.fi> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + * + * And is re-released under the NuttX modified BSD license: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <stdlib.h> +#include <stdbool.h> +#include <string.h> + +#include <apps/netutils/base64.h> + +#ifdef CONFIG_CODECS_BASE64 + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: base64_tab + ****************************************************************************/ + +static void base64_tab(unsigned char *tab, size_t len, bool websafe) +{ + static const char *_tab = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + + memset(tab, 0, len); + if (len >= 64) + { + memcpy(tab, _tab, 64); + } + + if (websafe) + { + tab[62] = '-'; + tab[63] = '_'; + } +} + +/**************************************************************************** + * Name: _base64_encode + * + * Description: + * Base64 encode + * + * Caller is responsible for freeing the returned buffer. Returned buffer + * is nul terminated to make it easier to use as a C string. The nul + * terminator is not included in out_len. + * + * Input Parameters: + * src: Data to be encoded + * len: Length of the data to be encoded + * out_len: Pointer to output length variable, or NULL if not used + * + * Returned Value: + * Returns: Allocated buffer of out_len bytes of encoded data, + * or NULL on failure + * + ****************************************************************************/ + +static unsigned char *_base64_encode(const unsigned char *src, size_t len, + unsigned char *dst, size_t * out_len, + bool websafe) +{ + unsigned char *out; + unsigned char *pos; + const unsigned char *end; + const unsigned char *in; + size_t olen; +/*int line_len; */ + unsigned char base64_table[64]; + char ch = '='; + + if (websafe) + { + ch = '.'; + } + + base64_tab(base64_table, sizeof(base64_table), websafe); + olen = len * 4 / 3 + 4; /* 3-byte blocks to 4-byte */ + +#if 0 + olen += olen / 72; /* line feeds */ + olen++; /* nul termination */ + out = malloc(olen); + if (out == NULL) + { + return NULL; + } +#endif + + end = src + len; + in = src; + + if (dst) + { + pos = out = dst; + } + else + { + pos = out = malloc(olen); + if (out == NULL) + { + return NULL; + } + } + +/*line_len = 0; */ + while (end - in >= 3) + { + *pos++ = base64_table[in[0] >> 2]; + *pos++ = base64_table[((in[0] & 0x03) << 4) | (in[1] >> 4)]; + *pos++ = base64_table[((in[1] & 0x0f) << 2) | (in[2] >> 6)]; + *pos++ = base64_table[in[2] & 0x3f]; + in += 3; + /* line_len += 4; */ + } + + if (end - in) + { + *pos++ = base64_table[in[0] >> 2]; + if (end - in == 1) + { + *pos++ = base64_table[(in[0] & 0x03) << 4]; + *pos++ = ch; /* *pos++ = '='; */ + } + else + { + *pos++ = base64_table[((in[0] & 0x03) << 4) | (in[1] >> 4)]; + *pos++ = base64_table[(in[1] & 0x0f) << 2]; + } + *pos++ = ch; /* *pos++ = '='; */ + /* line_len += 4; */ + } + +#if 0 + if (line_len) + { + *pos++ = '\n'; + } +#endif + + *pos = '\0'; + if (out_len) + { + *out_len = pos - out; + } + +/*out[*out_len] = '\0'; */ + return out; +} + +/**************************************************************************** + * Name: _base64_decode + * + * Description: + * Base64 decode + * + * Caller is responsible for freeing the returned buffer. + * + * Input Parameters: + * src: Data to be decoded + * len: Length of the data to be decoded + * out_len: Pointer to output length variable + * + * Returned Value: + * Returns: Allocated buffer of out_len bytes of decoded data, + * or NULL on failure + * + ****************************************************************************/ + +static unsigned char *_base64_decode(const unsigned char *src, size_t len, + unsigned char *dst, size_t * out_len, + bool websafe) +{ + unsigned char dtable[256]; + unsigned char *out; + unsigned char *pos; + unsigned char in[4]; + unsigned char block[4]; + unsigned char tmp; + size_t count; + size_t i; + unsigned char base64_table[64]; + char ch = '='; + + if (websafe) + { + ch = '.'; + } + base64_tab(base64_table, sizeof(base64_table), websafe); + + memset(dtable, 0x80, 256); + for (i = 0; i < sizeof(base64_table); i++) + { + dtable[base64_table[i]] = i; + } + + dtable[(int)ch] = 0; /* dtable['='] = 0; */ + + count = 0; + for (i = 0; i < len; i++) + { + if (dtable[src[i]] != 0x80) + { + count++; + } + } + + if (count % 4) + { + return NULL; + } + + if (dst) + { + pos = out = dst; + } + else + { + pos = out = malloc(count); + if (out == NULL) + { + return NULL; + } + } + + count = 0; + for (i = 0; i < len; i++) + { + tmp = dtable[src[i]]; + if (tmp == 0x80) + { + continue; + } + + in[count] = src[i]; + block[count] = tmp; + count++; + if (count == 4) + { + *pos++ = (block[0] << 2) | (block[1] >> 4); + *pos++ = (block[1] << 4) | (block[2] >> 2); + *pos++ = (block[2] << 6) | block[3]; + count = 0; + } + } + + if (pos > out) + { + if (in[2] == ch) /* if (in[2] == '=') */ + { + pos -= 2; + } + else if (in[3] == ch) /* else if (in[3] == '=') */ + { + pos--; + } + } + + *out_len = pos - out; + return out; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: base64_encode + ****************************************************************************/ + +unsigned char *base64_encode(const unsigned char *src, size_t len, + unsigned char *dst, size_t * out_len) +{ + return _base64_encode(src, len, dst, out_len, false); +} + +/**************************************************************************** + * Name: base64_decode + ****************************************************************************/ + +unsigned char *base64_decode(const unsigned char *src, size_t len, + unsigned char *dst, size_t * out_len) +{ + return _base64_decode(src, len, dst, out_len, false); +} + +/**************************************************************************** + * Name: base64w_encode + ****************************************************************************/ + +unsigned char *base64w_encode(const unsigned char *src, size_t len, + unsigned char *dst, size_t * out_len) +{ + return _base64_encode(src, len, dst, out_len, true); +} + +/**************************************************************************** + * Name: base64w_decode + ****************************************************************************/ + +unsigned char *base64w_decode(const unsigned char *src, size_t len, + unsigned char *dst, size_t * out_len) +{ + return _base64_decode(src, len, dst, out_len, true); +} + +#endif /* CONFIG_CODECS_BASE64 */ |