summaryrefslogtreecommitdiff
path: root/Source/kwsys/Base64.c
diff options
context:
space:
mode:
Diffstat (limited to 'Source/kwsys/Base64.c')
-rw-r--r--Source/kwsys/Base64.c279
1 files changed, 279 insertions, 0 deletions
diff --git a/Source/kwsys/Base64.c b/Source/kwsys/Base64.c
new file mode 100644
index 000000000..d07bdd01b
--- /dev/null
+++ b/Source/kwsys/Base64.c
@@ -0,0 +1,279 @@
+/*============================================================================
+ KWSys - Kitware System Library
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#include "kwsysPrivate.h"
+#include KWSYS_HEADER(Base64.h)
+
+/* Work-around CMake dependency scanning limitation. This must
+ duplicate the above list of headers. */
+#if 0
+# include "Base64.h.in"
+#endif
+
+/*--------------------------------------------------------------------------*/
+static const unsigned char kwsysBase64EncodeTable[65] =
+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+"abcdefghijklmnopqrstuvwxyz"
+"0123456789+/";
+
+/*--------------------------------------------------------------------------*/
+static const unsigned char kwsysBase64DecodeTable[256] =
+{
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0x3E,0xFF,0xFF,0xFF,0x3F,
+ 0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,
+ 0x3C,0x3D,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,
+ 0xFF,0x00,0x01,0x02,0x03,0x04,0x05,0x06,
+ 0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,
+ 0x0F,0x10,0x11,0x12,0x13,0x14,0x15,0x16,
+ 0x17,0x18,0x19,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,0x20,
+ 0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,
+ 0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,0x30,
+ 0x31,0x32,0x33,0xFF,0xFF,0xFF,0xFF,0xFF,
+ /*------------------------------------*/
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
+};
+
+/*--------------------------------------------------------------------------*/
+static unsigned char kwsysBase64EncodeChar(int c)
+{
+ return kwsysBase64EncodeTable[(unsigned char)c];
+}
+
+/*--------------------------------------------------------------------------*/
+static unsigned char kwsysBase64DecodeChar(unsigned char c)
+{
+ return kwsysBase64DecodeTable[c];
+}
+
+/*--------------------------------------------------------------------------*/
+/* Encode 3 bytes into a 4 byte string. */
+void kwsysBase64_Encode3(const unsigned char *src, unsigned char *dest)
+{
+ dest[0] = kwsysBase64EncodeChar((src[0] >> 2) & 0x3F);
+ dest[1] = kwsysBase64EncodeChar(((src[0] << 4) & 0x30)|((src[1] >> 4) & 0x0F));
+ dest[2] = kwsysBase64EncodeChar(((src[1] << 2) & 0x3C)|((src[2] >> 6) & 0x03));
+ dest[3] = kwsysBase64EncodeChar(src[2] & 0x3F);
+}
+
+/*--------------------------------------------------------------------------*/
+/* Encode 2 bytes into a 4 byte string. */
+void kwsysBase64_Encode2(const unsigned char *src, unsigned char *dest)
+{
+ dest[0] = kwsysBase64EncodeChar((src[0] >> 2) & 0x3F);
+ dest[1] = kwsysBase64EncodeChar(((src[0] << 4) & 0x30)|((src[1] >> 4) & 0x0F));
+ dest[2] = kwsysBase64EncodeChar(((src[1] << 2) & 0x3C));
+ dest[3] = '=';
+}
+
+/*--------------------------------------------------------------------------*/
+/* Encode 1 bytes into a 4 byte string. */
+void kwsysBase64_Encode1(const unsigned char *src, unsigned char *dest)
+{
+ dest[0] = kwsysBase64EncodeChar((src[0] >> 2) & 0x3F);
+ dest[1] = kwsysBase64EncodeChar(((src[0] << 4) & 0x30));
+ dest[2] = '=';
+ dest[3] = '=';
+}
+
+/*--------------------------------------------------------------------------*/
+/* Encode 'length' bytes from the input buffer and store the
+ encoded stream into the output buffer. Return the length of the encoded
+ buffer (output). Note that the output buffer must be allocated by the caller
+ (length * 1.5 should be a safe estimate). If 'mark_end' is true than an
+ extra set of 4 bytes is added to the end of the stream if the input is a
+ multiple of 3 bytes. These bytes are invalid chars and therefore they will
+ stop the decoder thus enabling the caller to decode a stream without
+ actually knowing how much data to expect (if the input is not a multiple of
+ 3 bytes then the extra padding needed to complete the encode 4 bytes will
+ stop the decoding anyway). */
+unsigned long kwsysBase64_Encode(const unsigned char *input,
+ unsigned long length,
+ unsigned char *output,
+ int mark_end)
+{
+ const unsigned char *ptr = input;
+ const unsigned char *end = input + length;
+ unsigned char *optr = output;
+
+ /* Encode complete triplet */
+
+ while ((end - ptr) >= 3)
+ {
+ kwsysBase64_Encode3(ptr, optr);
+ ptr += 3;
+ optr += 4;
+ }
+
+ /* Encodes a 2-byte ending into 3 bytes and 1 pad byte and writes. */
+
+ if (end - ptr == 2)
+ {
+ kwsysBase64_Encode2(ptr, optr);
+ optr += 4;
+ }
+
+ /* Encodes a 1-byte ending into 2 bytes and 2 pad bytes */
+
+ else if (end - ptr == 1)
+ {
+ kwsysBase64_Encode1(ptr, optr);
+ optr += 4;
+ }
+
+ /* Do we need to mark the end */
+
+ else if (mark_end)
+ {
+ optr[0] = optr[1] = optr[2] = optr[3] = '=';
+ optr += 4;
+ }
+
+ return (unsigned long)(optr - output);
+}
+
+/*--------------------------------------------------------------------------*/
+/* Decode 4 bytes into a 3 byte string. */
+int kwsysBase64_Decode3(const unsigned char *src, unsigned char *dest)
+{
+ unsigned char d0, d1, d2, d3;
+
+ d0 = kwsysBase64DecodeChar(src[0]);
+ d1 = kwsysBase64DecodeChar(src[1]);
+ d2 = kwsysBase64DecodeChar(src[2]);
+ d3 = kwsysBase64DecodeChar(src[3]);
+
+ /* Make sure all characters were valid */
+
+ if (d0 == 0xFF || d1 == 0xFF || d2 == 0xFF || d3 == 0xFF)
+ {
+ return 0;
+ }
+
+ /* Decode the 3 bytes */
+
+ dest[0] = (unsigned char)(((d0 << 2) & 0xFC) | ((d1 >> 4) & 0x03));
+ dest[1] = (unsigned char)(((d1 << 4) & 0xF0) | ((d2 >> 2) & 0x0F));
+ dest[2] = (unsigned char)(((d2 << 6) & 0xC0) | ((d3 >> 0) & 0x3F));
+
+ /* Return the number of bytes actually decoded */
+
+ if (src[2] == '=')
+ {
+ return 1;
+ }
+ if (src[3] == '=')
+ {
+ return 2;
+ }
+ return 3;
+}
+
+/*--------------------------------------------------------------------------*/
+/* Decode bytes from the input buffer and store the decoded stream
+ into the output buffer until 'length' bytes have been decoded. Return the
+ real length of the decoded stream (which should be equal to 'length'). Note
+ that the output buffer must be allocated by the caller. If
+ 'max_input_length' is not null, then it specifies the number of encoded
+ bytes that should be at most read from the input buffer. In that case the
+ 'length' parameter is ignored. This enables the caller to decode a stream
+ without actually knowing how much decoded data to expect (of course, the
+ buffer must be large enough). */
+unsigned long kwsysBase64_Decode(const unsigned char *input,
+ unsigned long length,
+ unsigned char *output,
+ unsigned long max_input_length)
+{
+ const unsigned char *ptr = input;
+ unsigned char *optr = output;
+
+ /* Decode complete triplet */
+
+ if (max_input_length)
+ {
+ const unsigned char *end = input + max_input_length;
+ while (ptr < end)
+ {
+ int len = kwsysBase64_Decode3(ptr, optr);
+ optr += len;
+ if(len < 3)
+ {
+ return (unsigned long)(optr - output);
+ }
+ ptr += 4;
+ }
+ }
+ else
+ {
+ unsigned char *oend = output + length;
+ while ((oend - optr) >= 3)
+ {
+ int len = kwsysBase64_Decode3(ptr, optr);
+ optr += len;
+ if(len < 3)
+ {
+ return (unsigned long)(optr - output);
+ }
+ ptr += 4;
+ }
+
+ /* Decode the last triplet */
+
+ if (oend - optr == 2)
+ {
+ unsigned char temp[3];
+ int len = kwsysBase64_Decode3(ptr, temp);
+ if(len >= 2)
+ {
+ optr[0] = temp[0];
+ optr[1] = temp[1];
+ optr += 2;
+ }
+ else if(len > 0)
+ {
+ optr[0] = temp[0];
+ optr += 1;
+ }
+ }
+ else if (oend - optr == 1)
+ {
+ unsigned char temp[3];
+ int len = kwsysBase64_Decode3(ptr, temp);
+ if(len > 0)
+ {
+ optr[0] = temp[0];
+ optr += 1;
+ }
+ }
+ }
+
+ return (unsigned long)(optr - output);
+}