diff deps/Platinum/ThirdParty/Neptune/Source/Core/NptBase64.cpp @ 0:3425707ddbf6

Initial import (hopefully this mercurial stuff works...)
author fraserofthenight
date Mon, 06 Jul 2009 08:06:28 -0700
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/deps/Platinum/ThirdParty/Neptune/Source/Core/NptBase64.cpp	Mon Jul 06 08:06:28 2009 -0700
@@ -0,0 +1,192 @@
+/*****************************************************************
+|
+|   Neptune - Base64
+|
+| Copyright (c) 2002-2008, Axiomatic Systems, LLC.
+| All rights reserved.
+|
+| Redistribution and use in source and binary forms, with or without
+| modification, are permitted provided that the following conditions are met:
+|     * Redistributions of source code must retain the above copyright
+|       notice, this list of conditions and the following disclaimer.
+|     * 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.
+|     * Neither the name of Axiomatic Systems 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 AXIOMATIC SYSTEMS ''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 AXIOMATIC SYSTEMS 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.
+|
+****************************************************************/
+
+/*----------------------------------------------------------------------
+|   includes
++---------------------------------------------------------------------*/
+#include "NptBase64.h"
+#include "NptUtils.h"
+#include "NptResults.h"
+
+/*----------------------------------------------------------------------
+|   constants
++---------------------------------------------------------------------*/
+static const signed char NPT_Base64_Bytes[128] = {
+      -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, 0x3E,   -1,   -1,   -1, 0x3F,
+    0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D,   -1,   -1,   -1, 0x7F,   -1,   -1,
+      -1, 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,   -1,   -1,   -1,   -1,   -1,
+      -1, 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,   -1,   -1,   -1,   -1,   -1
+};
+
+static const char NPT_Base64_Chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+const char NPT_BASE64_PAD_CHAR = '=';
+const char NPT_BASE64_PAD_BYTE = 0x7F;
+
+/*----------------------------------------------------------------------
+|   NPT_Base64::Decode
++---------------------------------------------------------------------*/
+NPT_Result
+NPT_Base64::Decode(const char*     base64, 
+                   NPT_Size        size,
+                   NPT_DataBuffer& data,
+                   bool            url_safe /* = false */)
+{
+    // estimate the data size
+    data.SetBufferSize(size);
+
+    // reset the buffer
+    data.SetDataSize(0);
+
+    // keep a pointer to the buffer
+    unsigned char* buffer = data.UseData();
+    NPT_Size       data_size = 0;
+
+    // iterate over all characters
+    unsigned char codes[4];
+    unsigned int code_count = 0;
+    while (size--) {
+        unsigned char c = *base64++;
+        if (c >= NPT_ARRAY_SIZE(NPT_Base64_Bytes)) continue;
+        if (url_safe) {
+            // remap some characters
+            if (c == '-') {
+                c = '+';
+            } else if (c == '_') {
+                c = '/';
+            }
+        }
+        signed char code = NPT_Base64_Bytes[c];
+        if (code >= 0) {
+            // valid code
+            codes[code_count++] = code;
+            if (code_count == 4) {
+                // group complete
+                if (codes[0] == NPT_BASE64_PAD_BYTE || codes[1] == NPT_BASE64_PAD_BYTE) {
+                    return NPT_ERROR_INVALID_FORMAT;
+                }
+                if (codes[2] == NPT_BASE64_PAD_BYTE) {
+                    // pad at char 3
+                    if (codes[3] == NPT_BASE64_PAD_BYTE) {
+                        // double padding
+                        unsigned int packed = (codes[0]<<2)|(codes[1]>>4);
+                        buffer[data_size++] = (unsigned char)packed;
+                    } else {
+                        // invalid padding
+                        return NPT_ERROR_INVALID_FORMAT;
+                    }
+                } else if (codes[3] == NPT_BASE64_PAD_BYTE) {
+                    // single padding
+                    unsigned int packed = (codes[0]<<10)|(codes[1]<<4)|(codes[2]>>2);
+                    buffer[data_size++] = (unsigned char)(packed >> 8);
+                    buffer[data_size++] = (unsigned char)(packed     );
+                } else {
+                    // no padding
+                    unsigned int packed = (codes[0]<<18)|(codes[1]<<12)|(codes[2]<<6)|codes[3];
+                    buffer[data_size++] = (unsigned char)(packed >> 16);
+                    buffer[data_size++] = (unsigned char)(packed >>  8);
+                    buffer[data_size++] = (unsigned char)(packed      );
+                }
+                code_count = 0;
+            }
+        }
+    }
+
+    if (code_count) return NPT_ERROR_INVALID_FORMAT;
+
+    // update the data size
+    data.SetDataSize(data_size);
+
+    return NPT_SUCCESS;
+}
+
+/*----------------------------------------------------------------------
+|   NPT_Base64::Encode
++---------------------------------------------------------------------*/
+NPT_Result
+NPT_Base64::Encode(const NPT_Byte* data, 
+                   NPT_Size        size, 
+                   NPT_String&     base64, 
+                   NPT_Cardinal    max_blocks_per_line /* = 0 */, 
+                   bool            url_safe /* = false */)
+{
+    unsigned int block_count = 0;
+    unsigned int           i = 0;
+
+    // reserve space for the string
+    base64.Reserve(4*((size+3)/3) + 2*(max_blocks_per_line?(size/(3*max_blocks_per_line)):0));
+    char* buffer = base64.UseChars();
+
+    // encode each byte
+    while (size >= 3) {
+        // output a block
+        *buffer++ = NPT_Base64_Chars[ (data[i  ] >> 2) & 0x3F];
+        *buffer++ = NPT_Base64_Chars[((data[i  ] & 0x03) << 4) | ((data[i+1] >> 4) & 0x0F)];
+        *buffer++ = NPT_Base64_Chars[((data[i+1] & 0x0F) << 2) | ((data[i+2] >> 6) & 0x03)];
+        *buffer++ = NPT_Base64_Chars[  data[i+2] & 0x3F];
+
+        size -= 3;
+        i += 3;
+        if (++block_count == max_blocks_per_line) {
+            *buffer++ = '\r';
+            *buffer++ = '\n';
+            block_count = 0;
+        }
+    }
+
+    // deal with the tail
+    if (size == 2) {
+        *buffer++ = NPT_Base64_Chars[ (data[i  ] >> 2) & 0x3F];
+        *buffer++ = NPT_Base64_Chars[((data[i  ] & 0x03) << 4) | ((data[i+1] >> 4) & 0x0F)];
+        *buffer++ = NPT_Base64_Chars[ (data[i+1] & 0x0F) << 2];
+        *buffer++ = NPT_BASE64_PAD_CHAR;
+    } else if (size == 1) {
+        *buffer++ = NPT_Base64_Chars[(data[i] >> 2) & 0x3F];
+        *buffer++ = NPT_Base64_Chars[(data[i] & 0x03) << 4];
+        *buffer++ = NPT_BASE64_PAD_CHAR;
+        *buffer++ = NPT_BASE64_PAD_CHAR;
+    }
+
+    // update the string size
+    NPT_ASSERT((NPT_Size)(buffer-base64.GetChars()) <= base64.GetCapacity());
+    base64.SetLength((NPT_Size)(buffer-base64.GetChars()));
+
+    // deal with url safe remapping
+    if (url_safe) {
+        base64.Replace('+','-');
+        base64.Replace('/','_');
+    }
+
+    return NPT_SUCCESS;
+}