diff options
author | Andy Cedilnik <andy.cedilnik@kitware.com> | 2005-02-22 18:08:27 (GMT) |
---|---|---|
committer | Andy Cedilnik <andy.cedilnik@kitware.com> | 2005-02-22 18:08:27 (GMT) |
commit | b9b4ea0f7bbf0313d8aa5e354ee56f912969763c (patch) | |
tree | ba5e857cda91949be14f508e6df490e1e2176f40 /Utilities/cmxmlrpc/xmlrpc_base64.c | |
parent | bfcb4b693763bb11f841094d2ca9852a64e5d33b (diff) | |
download | CMake-b9b4ea0f7bbf0313d8aa5e354ee56f912969763c.zip CMake-b9b4ea0f7bbf0313d8aa5e354ee56f912969763c.tar.gz CMake-b9b4ea0f7bbf0313d8aa5e354ee56f912969763c.tar.bz2 |
ENH: Initial import
Diffstat (limited to 'Utilities/cmxmlrpc/xmlrpc_base64.c')
-rw-r--r-- | Utilities/cmxmlrpc/xmlrpc_base64.c | 262 |
1 files changed, 262 insertions, 0 deletions
diff --git a/Utilities/cmxmlrpc/xmlrpc_base64.c b/Utilities/cmxmlrpc/xmlrpc_base64.c new file mode 100644 index 0000000..edcb09b --- /dev/null +++ b/Utilities/cmxmlrpc/xmlrpc_base64.c @@ -0,0 +1,262 @@ +/* Copyright (C) 2001 by First Peer, Inc. All rights reserved. +** +** 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. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +** +** There is more copyright information in the bottom half of this file. +** Please see it for more details. */ + + +/*========================================================================= +** XML-RPC Base64 Utilities +**========================================================================= +** This code was swiped from Jack Jansen's code in Python 1.5.2 and +** modified to work with our data types. +*/ + +#include "xmlrpc_config.h" + +#include "xmlrpc.h" + +#define CRLF "\015\012" +#define CR '\015' +#define LF '\012' + + +/*********************************************************** +Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum, +Amsterdam, The Netherlands. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the names of Stichting Mathematisch +Centrum or CWI or Corporation for National Research Initiatives or +CNRI not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +While CWI is the initial source for this software, a modified version +is made available by the Corporation for National Research Initiatives +(CNRI) at the Internet address ftp://ftp.python.org. + +STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH +CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL +DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. + +******************************************************************/ + +static char table_a2b_base64[] = { + -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,62, -1,-1,-1,63, + 52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1, 0,-1,-1, /* Note PAD->0 */ + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14, + 15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1, + -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40, + 41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1 +}; + +#define BASE64_PAD '=' +#define BASE64_MAXBIN 57 /* Max binary chunk size (76 char line) */ +#define BASE64_LINE_SZ 128 /* Buffer size for a single line. */ + +static unsigned char table_b2a_base64[] = +"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +static xmlrpc_mem_block * +xmlrpc_base64_encode_internal (xmlrpc_env *env, + unsigned char *bin_data, + size_t bin_len, + int want_newlines) +{ + size_t chunk_start, chunk_left; + unsigned char *ascii_data; + int leftbits; + unsigned char this_ch; + unsigned int leftchar; + xmlrpc_mem_block *output; + unsigned char line_buffer[BASE64_LINE_SZ]; + + /* Create a block to hold our lines when we finish them. */ + output = xmlrpc_mem_block_new(env, 0); + XMLRPC_FAIL_IF_FAULT(env); + + /* Deal with empty data blocks gracefully. Yuck. */ + if (bin_len == 0) { + if (want_newlines) + XMLRPC_TYPED_MEM_BLOCK_APPEND(char, env, output, CRLF, 2); + goto cleanup; + } + + /* Process our binary data in line-sized chunks. */ + for (chunk_start=0; chunk_start < bin_len; chunk_start += BASE64_MAXBIN) { + + /* Set up our per-line state. */ + ascii_data = &line_buffer[0]; + chunk_left = bin_len - chunk_start; + if (chunk_left > BASE64_MAXBIN) + chunk_left = BASE64_MAXBIN; + leftbits = 0; + leftchar = 0; + + for(; chunk_left > 0; chunk_left--, bin_data++) { + /* Shift the data into our buffer */ + leftchar = (leftchar << 8) | *bin_data; + leftbits += 8; + + /* See if there are 6-bit groups ready */ + while (leftbits >= 6) { + this_ch = (leftchar >> (leftbits-6)) & 0x3f; + leftbits -= 6; + *ascii_data++ = table_b2a_base64[this_ch]; + } + } + if (leftbits == 2) { + *ascii_data++ = table_b2a_base64[(leftchar&3) << 4]; + *ascii_data++ = BASE64_PAD; + *ascii_data++ = BASE64_PAD; + } else if (leftbits == 4) { + *ascii_data++ = table_b2a_base64[(leftchar&0xf) << 2]; + *ascii_data++ = BASE64_PAD; + } + + /* Append a courtesy CRLF. */ + if (want_newlines) { + *ascii_data++ = CR; + *ascii_data++ = LF; + } + + /* Save our line. */ + XMLRPC_TYPED_MEM_BLOCK_APPEND(char, env, output, line_buffer, + ascii_data - &line_buffer[0]); + XMLRPC_FAIL_IF_FAULT(env); + } + + cleanup: + if (env->fault_occurred) { + if (output) + xmlrpc_mem_block_free(output); + return NULL; + } + return output; +} + + +xmlrpc_mem_block * +xmlrpc_base64_encode (xmlrpc_env *env, unsigned char *bin_data, size_t bin_len) +{ + return xmlrpc_base64_encode_internal(env, bin_data, bin_len, 1); +} + + +xmlrpc_mem_block * +xmlrpc_base64_encode_without_newlines (xmlrpc_env *env, + unsigned char *bin_data, + size_t bin_len) +{ + return xmlrpc_base64_encode_internal(env, bin_data, bin_len, 0); +} + + +xmlrpc_mem_block * +xmlrpc_base64_decode (xmlrpc_env *env, + char *ascii_data, + size_t ascii_len) +{ + unsigned char *bin_data; + int leftbits; + unsigned char this_ch; + unsigned int leftchar; + size_t npad; + size_t bin_len, buffer_size; + xmlrpc_mem_block *output; + + /* Create a block to hold our chunks when we finish them. + ** We overestimate the size now, and fix it later. */ + buffer_size = ((ascii_len+3)/4)*3; + output = xmlrpc_mem_block_new(env, buffer_size); + XMLRPC_FAIL_IF_FAULT(env); + + /* Set up our decoder state. */ + leftbits = 0; + leftchar = 0; + npad = 0; + bin_data = XMLRPC_TYPED_MEM_BLOCK_CONTENTS(unsigned char, output); + bin_len = 0; + + for( ; ascii_len > 0 ; ascii_len--, ascii_data++ ) { + + /* Skip some punctuation. */ + this_ch = (*ascii_data & 0x7f); + if ( this_ch == '\r' || this_ch == '\n' || this_ch == ' ' ) + continue; + if ( this_ch == BASE64_PAD ) + npad++; + this_ch = table_a2b_base64[(*ascii_data) & 0x7f]; + + /* XXX - We just throw away invalid characters. Is this right? */ + if ( this_ch == (unsigned char) -1 ) continue; + + /* Shift it in on the low end, and see if there's + ** a byte ready for output. */ + leftchar = (leftchar << 6) | (this_ch); + leftbits += 6; + if ( leftbits >= 8 ) { + leftbits -= 8; + XMLRPC_ASSERT(bin_len < buffer_size); + *bin_data++ = (leftchar >> leftbits) & 0xFF; + leftchar &= ((1 << leftbits) - 1); + bin_len++; + } + } + + /* Check that no bits are left. */ + if ( leftbits ) + XMLRPC_FAIL(env, XMLRPC_PARSE_ERROR, "Incorrect Base64 padding"); + + /* Check to make sure we have a sane amount of padding. */ + if (npad > bin_len || npad > 2) + XMLRPC_FAIL(env, XMLRPC_PARSE_ERROR, "Malformed Base64 data"); + + /* Remove any padding and set the correct size. */ + bin_len -= npad; + XMLRPC_TYPED_MEM_BLOCK_RESIZE(char, env, output, bin_len); + XMLRPC_ASSERT(!env->fault_occurred); + + cleanup: + if (env->fault_occurred) { + if (output) + xmlrpc_mem_block_free(output); + return NULL; + } + return output; +} |