summaryrefslogtreecommitdiff
path: root/apps/netutils/codecs/base64.c
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-10-31 14:36:00 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-10-31 14:36:00 +0000
commit608e5adab4915ada5c2881d66d20e3d6fa0efba5 (patch)
treebbc2662360f180653bb42c54b921dec07135b648 /apps/netutils/codecs/base64.c
parent120fc05c1d11406857c6d245abe9a344dcaae268 (diff)
downloadnuttx-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.c359
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 */