added functions for base64 en/decoding (replaces patch 1739431)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@47282 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2007-07-10 01:51:43 +00:00
parent 0514c6a202
commit 4db03d266b
16 changed files with 14342 additions and 14120 deletions

View File

@@ -313,6 +313,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file!
src/common/arcfind.cpp
src/common/archive.cpp
src/common/arrstr.cpp
src/common/base64.cpp
src/common/clntdata.cpp
src/common/cmdline.cpp
src/common/config.cpp
@@ -397,6 +398,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file!
wx/arrimpl.cpp
wx/arrstr.h
wx/atomic.h
wx/base64.h
wx/beforestd.h
wx/buffer.h
wx/build.h

27446
configure vendored

File diff suppressed because one or more lines are too long

View File

@@ -450,6 +450,7 @@ if test $DEBUG_CONFIGURE = 1; then
DEFAULT_wxUSE_DYNAMIC_LOADER=no
DEFAULT_wxUSE_LONGLONG=no
DEFAULT_wxUSE_GEOMETRY=no
DEFAULT_wxUSE_BASE64=no
DEFAULT_wxUSE_AFM_FOR_POSTSCRIPT=no
DEFAULT_wxUSE_NORMALIZED_PS_FONTS=no
@@ -678,6 +679,7 @@ else
DEFAULT_wxUSE_DYNAMIC_LOADER=yes
DEFAULT_wxUSE_LONGLONG=yes
DEFAULT_wxUSE_GEOMETRY=yes
DEFAULT_wxUSE_BASE64=yes
DEFAULT_wxUSE_AFM_FOR_POSTSCRIPT=yes
DEFAULT_wxUSE_NORMALIZED_PS_FONTS=yes
@@ -976,6 +978,7 @@ WX_ARG_ENABLE(ipc, [ --enable-ipc use interprocess communi
dnl please keep the settings below in alphabetical order
WX_ARG_ENABLE(apple_ieee, [ --enable-apple_ieee use the Apple IEEE codec], wxUSE_APPLE_IEEE)
WX_ARG_ENABLE(arcstream, [ --enable-arcstream use wxArchive streams], wxUSE_ARCHIVE_STREAMS)
WX_ARG_ENABLE(base64, [ --enable-base64 use base64 encoding/decoding functions], wxUSE_BASE64)
WX_ARG_ENABLE(backtrace, [ --enable-backtrace use wxStackWalker class for getting backtraces], wxUSE_STACKWALKER)
WX_ARG_ENABLE(catch_segvs, [ --enable-catch_segvs catch signals in wxApp::OnFatalException (Unix only)], wxUSE_ON_FATAL_EXCEPTION)
WX_ARG_ENABLE(cmdline, [ --enable-cmdline use wxCmdLineParser class], wxUSE_CMDLINE_PARSER)
@@ -6110,6 +6113,10 @@ if test "$wxUSE_GEOMETRY" = "yes"; then
AC_DEFINE(wxUSE_GEOMETRY)
fi
if test "$wxUSE_BASE64" = "yes"; then
AC_DEFINE(wxUSE_BASE64)
fi
if test "$wxUSE_STREAMS" = "yes" ; then
AC_DEFINE(wxUSE_STREAMS)
fi

View File

@@ -37,6 +37,8 @@ the corresponding topic.
\helpref{wxASSERT\_MSG}{wxassertmsg}\\
\helpref{wxAtomicDec}{wxatomicdec}\\
\helpref{wxAtomicInc}{wxatomicinc}\\
\helpref{wxBase64Decode}{wxbase64decode}\\
\helpref{wxBase64Encode}{wxbase64encode}\\
\helpref{wxBeginBusyCursor}{wxbeginbusycursor}\\
\helpref{wxBell}{wxbell}\\
\helpref{wxBITMAP}{wxbitmapmacro}\\
@@ -2839,6 +2841,111 @@ The clipboard must have previously been opened for this call to succeed.
\section{Miscellaneous functions}\label{miscellany}
\membersection{wxBase64Decode}\label{wxbase64decode}
\func{size\_t}{wxBase64Decode}{\param{void *}{dst}, \param{size\_t}{dstLen},\\
\param{const char * }{src}, \param{size\_t }{srcLen = wxNO\_LEN},\\
\param{wxBase64DecodeMode }{mode = wxBase64DecodeMode\_Strict},\\
\param{size\_t }{*posErr = \NULL}}
\func{wxMemoryBuffer}{wxBase64Decode}{\\
\param{const char * }{src}, \param{size\_t }{srcLen = wxNO\_LEN},\\
\param{wxBase64DecodeMode }{mode = wxBase64DecodeMode\_Strict},\\
\param{size\_t }{*posErr = \NULL}}
These function decode a Base64-encoded string. The first version is a raw
decoding function and decodes the data into the provided buffer \arg{dst} of
the given size \arg{dstLen}. An error is returned if the buffer is not large
enough -- that is not at least \helpref{wxBase64DecodedSize(srcLen)}{wxbase64decodedsize}
bytes. The second version allocates memory internally and returns it as
\helpref{wxMemoryBuffer}{wxmemorybuffer} and is recommended for normal use.
The first version returns the number of bytes written to the buffer or the
necessary buffer size if \arg{dst} was \NULL or \texttt{wxCONV\_FAILED} on
error, e.g. if the output buffer is too small or invalid characters were
encountered in the input string. The second version returns a buffer with the
base64 decoded binary equivalent of the input string. In neither case is the
buffer NUL-terminated.
\wxheading{Parameters}
\docparam{dst}{Pointer to output buffer, may be \NULL to just compute the
necessary buffer size.}
\docparam{dstLen}{The size of the output buffer, ignored if \arg{dst} is
\NULL.}
\docparam{src}{The input string, must not be \NULL.}
\docparam{srcLen}{The length of the input string or special value
\texttt{wxNO\_LEN} if the string is \NUL-terminated and the length should be
computed by this function itself.}
\docparam{mode}{This parameter specifies the function behaviour when invalid
characters are encountered in input. By default, any such character stops the
decoding with error. If the mode is wxBase64DecodeMode\_SkipWS, then the white
space characters are silently skipped instead. And if it is
wxBase64DecodeMode\_Relaxed, then all invalid characters are skipped.}
\docparam{posErr}{If this pointer is non-\NULL and an error occurs during
decoding, it is filled with the index of the invalid character.}
\wxheading{Include files}
<wx/base64.h>
\membersection{wxBase64DecodedSize}\label{wxbase64decodedsize}
\func{size\_t}{wxBase64DecodedSize}{\param{size\_t }{srcLen}}
Returns the size of the buffer necessary to contain the data encoded in a
base64 string of length \arg{srcLen}. This can be useful for allocating a
buffer to be passed to \helpref{wxBase64Decode}{wxbase64decode}.
\membersection{wxBase64Encode}\label{wxbase64encode}
\func{size\_t}{wxBase64Encode}{\param{char *}{dst}, \param{size\_t}{dstLen},\\
\param{const void *}{src}, \param{size\_t }{srcLen}}
\func{wxString}{wxBase64Encode}{\param{const void *}{src}, \param{size\_t}{srcLen}}
\func{wxString}{wxBase64Encode}{\param{const wxMemoryBuffer\& }{buf}}
These functions encode the given data using base64. The first of them is the
raw encoding function writing the output string into provided buffer while the
other ones return the output as wxString. There is no error return for these
functions except for the first one which returns \texttt{wxCONV\_FAILED} if the
output buffer is too small. To allocate the buffer of the correct size, use
\helpref{wxBase64EncodedSize}{wxbase64encodedsize} or call this function with
\arg{dst} set to \NULL -- it will then return the necessary buffer size.
\wxheading{Parameters}
\docparam{dst}{The output buffer, may be \NULL to retrieve the needed buffer
size.}
\docparam{dstLen}{The output buffer size, ignored if \arg{dst} is \NULL.}
\docparam{src}{The input buffer, must not be \NULL.}
\docparam{srcLen}{The length of the input data.}
\wxheading{Include files}
<wx/base64.h>
\membersection{wxBase64EncodedSize}\label{wxbase64encodedsize}
\func{size\_t}{wxBase64EncodedSize}{\param{size\_t}{len}}
Returns the length of the string with base64 representation of a buffer of
specified size \arg{len}. This can be useful for allocating the buffer passed
to \helpref{wxBase64Encode}{wxbase64encode}.
\membersection{wxCONCAT}\label{wxconcat}
\func{}{wxCONCAT}{\param{}{x}, \param{}{y}}

101
include/wx/base64.h Normal file
View File

@@ -0,0 +1,101 @@
///////////////////////////////////////////////////////////////////////////////
// Name: wx/base64.h
// Purpose: declaration of BASE64 encoding/decoding functionality
// Author: Charles Reimers, Vadim Zeitlin
// Created: 2007-06-18
// RCS-ID: $Id$
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#ifndef _WX_BASE64_H_
#define _WX_BASE64_H_
#if wxUSE_BASE64
#include "wx/string.h"
#include "wx/buffer.h"
// ----------------------------------------------------------------------------
// encoding functions
// ----------------------------------------------------------------------------
// return the size needed for the buffer containing the encoded representation
// of a buffer of given length
inline size_t wxBase64EncodedSize(size_t len) { return 4*((len+2)/3); }
// raw base64 encoding function which encodes the contents of a buffer of the
// specified length into the buffer of the specified size
//
// returns the length of the encoded data or wxCONV_FAILED if the buffer is not
// large enough; to determine the needed size you can either allocate a buffer
// of wxBase64EncodedSize(srcLen) size or call the function with NULL buffer in
// which case the required size will be returned
WXDLLIMPEXP_BASE size_t
wxBase64Encode(char *dst, size_t dstLen, const void *src, size_t srcLen);
// encode the contents of the given buffer using base64 and return as string
// (there is no error return)
inline wxString wxBase64Encode(const void *src, size_t srcLen)
{
const size_t dstLen = wxBase64EncodedSize(srcLen);
wxCharBuffer dst(dstLen);
wxBase64Encode(dst.data(), dstLen, src, srcLen);
return dst;
}
inline wxString wxBase64Encode(const wxMemoryBuffer& buf)
{
return wxBase64Encode(buf.GetData(), buf.GetDataLen());
}
// ----------------------------------------------------------------------------
// decoding functions
// ----------------------------------------------------------------------------
// elements of this enum specify the possible behaviours of wxBase64Decode()
// when an invalid character is encountered
enum wxBase64DecodeMode
{
// normal behaviour: stop at any invalid characters
wxBase64DecodeMode_Strict,
// skip whitespace characters
wxBase64DecodeMode_SkipWS,
// the most lenient behaviour: simply ignore all invalid characters
wxBase64DecodeMode_Relaxed
};
// return the buffer size necessary for decoding a base64 string of the given
// length
inline size_t wxBase64DecodedSize(size_t srcLen) { return 3*srcLen/4; }
// raw decoding function which decodes the contents of the string of specified
// length (or NUL-terminated by default) into the provided buffer of the given
// size
//
// the function normally stops at any character invalid inside a base64-encoded
// string (i.e. not alphanumeric nor '+' nor '/') but can be made to skip the
// whitespace or all invalid characters using its mode argument
//
// returns the length of the decoded data or wxCONV_FAILED if an error occurs
// such as the buffer is too small or the encoded string is invalid; in the
// latter case the posErr is filled with the position where the decoding
// stopped if it is not NULL
WXDLLIMPEXP_BASE size_t
wxBase64Decode(void *dst, size_t dstLen,
const char *src, size_t srcLen = wxNO_LEN,
wxBase64DecodeMode mode = wxBase64DecodeMode_Strict,
size_t *posErr = NULL);
// decode the contents of the given string; the returned buffer is empty if an
// error occurs during decoding
WXDLLIMPEXP_BASE wxMemoryBuffer
wxBase64Decode(const char *src, size_t srcLen = wxNO_LEN,
wxBase64DecodeMode mode = wxBase64DecodeMode_Strict,
size_t *posErr = NULL);
#endif // wxUSE_BASE64
#endif // _WX_BASE64_H_

View File

@@ -323,6 +323,14 @@
// Recommended setting: 1
#define wxUSE_LONGLONG 1
// Set wxUSE_BASE64 to 1, to compile in Base64 support. This is required for
// storing binary data in wxConfig on most platforms.
//
// Default is 1.
//
// Recommended setting: 1 (but can be safely disabled if you don't use it)
#define wxUSE_BASE64 1
// Set wxUSE_(F)FILE to 1 to compile wx(F)File classes. wxFile uses low level
// POSIX functions for file access, wxFFile uses ANSI C stdio.h functions.
//

View File

@@ -322,6 +322,14 @@
// Recommended setting: 1
#define wxUSE_LONGLONG 1
// Set wxUSE_BASE64 to 1, to compile in Base64 support. This is required for
// storing binary data in wxConfig on most platforms.
//
// Default is 1.
//
// Recommended setting: 1 (but can be safely disabled if you don't use it)
#define wxUSE_BASE64 1
// Set wxUSE_(F)FILE to 1 to compile wx(F)File classes. wxFile uses low level
// POSIX functions for file access, wxFFile uses ANSI C stdio.h functions.
//

View File

@@ -322,6 +322,14 @@
// Recommended setting: 1
#define wxUSE_LONGLONG 1
// Set wxUSE_BASE64 to 1, to compile in Base64 support. This is required for
// storing binary data in wxConfig on most platforms.
//
// Default is 1.
//
// Recommended setting: 1 (but can be safely disabled if you don't use it)
#define wxUSE_BASE64 1
// Set wxUSE_(F)FILE to 1 to compile wx(F)File classes. wxFile uses low level
// POSIX functions for file access, wxFFile uses ANSI C stdio.h functions.
//

View File

@@ -322,6 +322,14 @@
// Recommended setting: 1
#define wxUSE_LONGLONG 1
// Set wxUSE_BASE64 to 1, to compile in Base64 support. This is required for
// storing binary data in wxConfig on most platforms.
//
// Default is 1.
//
// Recommended setting: 1 (but can be safely disabled if you don't use it)
#define wxUSE_BASE64 1
// Set wxUSE_(F)FILE to 1 to compile wx(F)File classes. wxFile uses low level
// POSIX functions for file access, wxFFile uses ANSI C stdio.h functions.
//

View File

@@ -322,6 +322,14 @@
// Recommended setting: 1
#define wxUSE_LONGLONG 1
// Set wxUSE_BASE64 to 1, to compile in Base64 support. This is required for
// storing binary data in wxConfig on most platforms.
//
// Default is 1.
//
// Recommended setting: 1 (but can be safely disabled if you don't use it)
#define wxUSE_BASE64 1
// Set wxUSE_(F)FILE to 1 to compile wx(F)File classes. wxFile uses low level
// POSIX functions for file access, wxFFile uses ANSI C stdio.h functions.
//

View File

@@ -322,6 +322,14 @@
// Recommended setting: 1
#define wxUSE_LONGLONG 1
// Set wxUSE_BASE64 to 1, to compile in Base64 support. This is required for
// storing binary data in wxConfig on most platforms.
//
// Default is 1.
//
// Recommended setting: 1 (but can be safely disabled if you don't use it)
#define wxUSE_BASE64 1
// Set wxUSE_(F)FILE to 1 to compile wx(F)File classes. wxFile uses low level
// POSIX functions for file access, wxFFile uses ANSI C stdio.h functions.
//

View File

@@ -318,6 +318,14 @@
// Recommended setting: 1
#define wxUSE_LONGLONG 1
// Set wxUSE_BASE64 to 1, to compile in Base64 support. This is required for
// storing binary data in wxConfig on most platforms.
//
// Default is 1.
//
// Recommended setting: 1 (but can be safely disabled if you don't use it)
#define wxUSE_BASE64 1
// Set wxUSE_(F)FILE to 1 to compile wx(F)File classes. wxFile uses low level
// POSIX functions for file access, wxFFile uses ANSI C stdio.h functions.
//

View File

@@ -215,6 +215,8 @@
#define wxUSE_LONGLONG 0
#define wxUSE_BASE64 0
#define wxUSE_FILE 0
#define wxUSE_FFILE 0

226
src/common/base64.cpp Normal file
View File

@@ -0,0 +1,226 @@
///////////////////////////////////////////////////////////////////////////////
// Name: src/common/base64.cpp
// Purpose: implementation of BASE64 encoding/decoding functions
// Author: Charles Reimers, Vadim Zeitlin
// Created: 2007-06-18
// RCS-ID: $Id$
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#include "wx/wxprec.h"
#if wxUSE_BASE64
#include "wx/base64.h"
size_t
wxBase64Encode(char *dst, size_t dstLen, const void *src_, size_t srcLen)
{
wxCHECK_MSG( src_, wxCONV_FAILED, _T("NULL input buffer") );
const unsigned char *src = wx_static_cast(const unsigned char *, src_);
static const char b64[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
size_t encLen = 0;
// encode blocks of 3 bytes into 4 base64 characters
for ( ; srcLen >= 3; srcLen -= 3, src += 3 )
{
encLen += 4;
if ( dst )
{
if ( encLen > dstLen )
return wxCONV_FAILED;
*dst++ = b64[src[0] >> 2];
*dst++ = b64[((src[0] & 0x03) << 4) | ((src[1] & 0xf0) >> 4)];
*dst++ = b64[((src[1] & 0x0f) << 2) | ((src[2] & 0xc0) >> 6)];
*dst++ = b64[src[2] & 0x3f];
}
}
// finish with the remaining characters
if ( srcLen )
{
encLen += 4;
if ( dst )
{
if ( encLen > dstLen )
return wxCONV_FAILED;
// we have definitely one and maybe two bytes remaining
unsigned char next = srcLen == 2 ? src[1] : 0;
*dst++ = b64[src[0] >> 2];
*dst++ = b64[((src[0] & 0x03) << 4) | ((next & 0xf0) >> 4)];
*dst++ = srcLen == 2 ? b64[((next & 0x0f) << 2)] : '=';
*dst = '=';
}
}
return encLen;
}
size_t
wxBase64Decode(void *dst_, size_t dstLen,
const char *src, size_t srcLen,
wxBase64DecodeMode mode,
size_t *posErr)
{
wxCHECK_MSG( src, wxCONV_FAILED, _T("NULL input buffer") );
unsigned char *dst = wx_static_cast(unsigned char *, dst_);
size_t decLen = 0;
if ( srcLen == wxNO_LEN )
srcLen = strlen(src);
// this table contains the values, in base 64, of all valid characters and
// special values WSP or INV for white space and invalid characters
// respectively as well as a special PAD value for '='
enum
{
WSP = 200,
INV,
PAD
};
static const char decode[256] =
{
WSP,INV,INV,INV,INV,INV,INV,INV,INV,WSP,WSP,INV,WSP,WSP,INV,INV,
INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,
WSP,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,076,INV,INV,INV,077,
064,065,066,067,070,071,072,073,074,075,INV,INV,INV,PAD,INV,INV,
INV,000,001,002,003,004,005,006,007,010,011,012,013,014,015,016,
017,020,021,022,023,024,025,026,027,030,031,INV,INV,INV,INV,INV,
INV,032,033,034,035,036,037,040,041,042,043,044,045,046,047,050,
051,052,053,054,055,056,057,060,061,062,063,INV,INV,INV,INV,INV,
INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,
INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,
INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,
INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,
INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,
INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,
INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,
INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,INV,
};
// we decode input by groups of 4 characters but things are complicated by
// the fact that there can be whitespace and other junk in it too so keep
// record of where exactly we're inside the current quartet in this var
int n = 0;
unsigned char in[4]; // current quartet
bool end = false; // set when we find padding
size_t padLen = 0; // length lost to padding
const char *p;
for ( p = src; srcLen; p++, srcLen-- )
{
const char c = decode[(int)*p]; // cast just to suppress warnings
switch ( c )
{
case WSP:
if ( mode == wxBase64DecodeMode_SkipWS )
continue;
// fall through
case INV:
if ( mode == wxBase64DecodeMode_Relaxed )
continue;
// force the loop to stop and an error to be returned
n = -1;
srcLen = 0;
break;
case PAD:
// set the flag telling us that we're past the end now
end = true;
// there can be either a single '=' at the end of a quartet or
// "==" in positions 2 and 3
if ( n == 3 )
{
padLen = 1;
in[n++] = '\0';
}
else if ( (n == 2) && (--srcLen && *++p == '=') )
{
padLen = 2;
in[n++] = '\0';
in[n++] = '\0';
}
else // invalid padding
{
// force the loop terminate with an error
n = -1;
srcLen = 0;
}
break;
default:
if ( end )
{
// nothing is allowed after the end so provoke error return
n = -1;
srcLen = 0;
break;
}
in[n++] = c;
}
if ( n == 4 )
{
// got entire block, decode
decLen += 3 - padLen;
if ( dst )
{
if ( decLen > dstLen )
return wxCONV_FAILED;
// undo the bit shifting done during encoding
*dst++ = in[0] << 2 | in[1] >> 4;
*dst++ = in[1] << 4 | in[2] >> 2;
*dst++ = in[2] << 6 | in[3];
}
n = 0;
}
}
if ( n )
{
if ( posErr )
*posErr = p - src;
return wxCONV_FAILED;
}
return decLen;
}
wxMemoryBuffer wxBase64Decode(const char *src,
size_t srcLen,
wxBase64DecodeMode mode,
size_t *posErr)
{
wxMemoryBuffer buf;
wxCHECK_MSG( src, buf, _T("NULL input buffer") );
if ( srcLen == wxNO_LEN )
srcLen = strlen(src);
size_t len = wxBase64DecodedSize(srcLen);
len = wxBase64Decode(buf.GetWriteBuf(len), len, src, srcLen, mode, posErr);
if ( len == wxCONV_FAILED )
len = 0;
buf.SetDataLen(len);
return buf;
}
#endif // wxUSE_BASE64

236
tests/base64/base64.cpp Normal file
View File

@@ -0,0 +1,236 @@
///////////////////////////////////////////////////////////////////////////////
// Name: tests/base64/base64.cpp
// Purpose: wxBase64Encode/Decode unit test
// Author: Charles Reimers
// Created: 2007-06-22
// RCS-ID: $Id$
///////////////////////////////////////////////////////////////////////////////
// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------
#include "testprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif // WX_PRECOMP
#if wxUSE_BASE64
#include "wx/base64.h"
static const char encoded0to255[] =
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIj"
"JCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZH"
"SElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWpr"
"bG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6P"
"kJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKz"
"tLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX"
"2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7"
"/P3+/w==";
static void
generatePatternedData(void* buff, size_t len, unsigned char startVal,
unsigned char addVal, unsigned char multVal = 1,
unsigned char xorMask = 0, unsigned char andMask = 255)
{
unsigned char *cbuff = (unsigned char *)buff;
unsigned char curval = startVal;
while(len--)
{
*(cbuff++) = curval;
curval = (((curval + addVal) * multVal) ^ xorMask) & andMask;
}
}
static void generateRandomData(void* buff, size_t len)
{
unsigned char *cbuff = (unsigned char *)buff;
while(len--)
{
*(cbuff++) = (unsigned char)(((rand() * 255) / RAND_MAX));
}
}
static void generateGibberish(void* buff, size_t len)
{
static const unsigned char cb64[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
unsigned char *cbuff = (unsigned char *)buff;
while(len--)
{
*(cbuff++) = cb64[((rand() * 64) / RAND_MAX)];
}
}
// --------------------------------------------------------------------------
// test class
// --------------------------------------------------------------------------
class Base64TestCase : public CppUnit::TestCase
{
public:
Base64TestCase() { }
private:
CPPUNIT_TEST_SUITE( Base64TestCase );
CPPUNIT_TEST( EncodeDecodeEmpty );
CPPUNIT_TEST( EncodeDecodeA );
CPPUNIT_TEST( EncodeDecodeAB );
CPPUNIT_TEST( EncodeDecodeABC );
CPPUNIT_TEST( EncodeDecodeABCD );
CPPUNIT_TEST( EncodeDecode0to255 );
CPPUNIT_TEST( EncodeDecodePatternA );
CPPUNIT_TEST( EncodeDecodePatternB );
CPPUNIT_TEST( EncodeDecodePatternC );
CPPUNIT_TEST( EncodeDecodeRandom );
CPPUNIT_TEST_SUITE_END();
void EncodeDecodeEmpty();
void EncodeDecodeA();
void EncodeDecodeAB();
void EncodeDecodeABC();
void EncodeDecodeABCD();
void EncodeDecode0to255();
void EncodeDecodePatternA();
void EncodeDecodePatternB();
void EncodeDecodePatternC();
void EncodeDecodeRandom();
DECLARE_NO_COPY_CLASS(Base64TestCase)
};
// register in the unnamed registry so that these tests are run by default
CPPUNIT_TEST_SUITE_REGISTRATION( Base64TestCase );
// also include in it's own registry so that these tests can be run alone
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( Base64TestCase, "Base64TestCase" );
void Base64TestCase::EncodeDecodeEmpty()
{
char shouldBeEmpty[10];
shouldBeEmpty[0] = '\0';
size_t len = 10;
CPPUNIT_ASSERT(wxBase64Encode(shouldBeEmpty, len, "", 0) != wxCONV_FAILED);
CPPUNIT_ASSERT_EQUAL('\0', shouldBeEmpty[0]);
CPPUNIT_ASSERT(wxBase64Decode(shouldBeEmpty, len, "") != wxCONV_FAILED);
CPPUNIT_ASSERT_EQUAL('\0', shouldBeEmpty[0]);
wxMemoryBuffer bufmt;
wxString resultmt = wxBase64Encode(bufmt);
CPPUNIT_ASSERT(resultmt.empty());
bufmt = wxBase64Decode(resultmt);
CPPUNIT_ASSERT_EQUAL(0u, bufmt.GetDataLen());
}
void Base64TestCase::EncodeDecodeA()
{
const wxString str = wxBase64Encode("A", 1);
CPPUNIT_ASSERT_EQUAL(wxString("QQ=="), str);
wxMemoryBuffer buf = wxBase64Decode(str);
CPPUNIT_ASSERT_EQUAL(1u, buf.GetDataLen());
CPPUNIT_ASSERT_EQUAL('A', *(char *)buf.GetData());
}
void Base64TestCase::EncodeDecodeAB()
{
const wxString str = wxBase64Encode("AB", 2);
CPPUNIT_ASSERT_EQUAL(wxString("QUI="), str);
wxMemoryBuffer buf = wxBase64Decode(str);
CPPUNIT_ASSERT_EQUAL(2u, buf.GetDataLen());
CPPUNIT_ASSERT_EQUAL('A', buf[0]);
CPPUNIT_ASSERT_EQUAL('B', buf[1]);
}
void Base64TestCase::EncodeDecodeABC()
{
const wxString str = wxBase64Encode("ABC", 3);
CPPUNIT_ASSERT_EQUAL(wxString("QUJD"), str);
wxMemoryBuffer buf = wxBase64Decode(str);
CPPUNIT_ASSERT_EQUAL(3u, buf.GetDataLen());
CPPUNIT_ASSERT_EQUAL('A', buf[0]);
CPPUNIT_ASSERT_EQUAL('B', buf[1]);
CPPUNIT_ASSERT_EQUAL('C', buf[2]);
}
void Base64TestCase::EncodeDecodeABCD()
{
const wxString str = wxBase64Encode("ABCD", 4);
CPPUNIT_ASSERT_EQUAL(wxString("QUJDRA=="), str);
wxMemoryBuffer buf = wxBase64Decode(str);
CPPUNIT_ASSERT_EQUAL(4u, buf.GetDataLen());
CPPUNIT_ASSERT_EQUAL('A', buf[0]);
CPPUNIT_ASSERT_EQUAL('B', buf[1]);
CPPUNIT_ASSERT_EQUAL('C', buf[2]);
CPPUNIT_ASSERT_EQUAL('D', buf[3]);
}
void Base64TestCase::EncodeDecode0to255()
{
unsigned char buff[256];
generatePatternedData(buff, 256, 0, 1);
wxString str = wxBase64Encode(buff, 256);
wxMemoryBuffer mbuff = wxBase64Decode(str);
CPPUNIT_ASSERT(memcmp(mbuff.GetData(), buff, mbuff.GetDataLen()) == 0);
mbuff = wxBase64Decode(encoded0to255);
CPPUNIT_ASSERT(memcmp(mbuff.GetData(), buff, mbuff.GetDataLen()) == 0);
}
void Base64TestCase::EncodeDecodePatternA()
{
unsigned char buff[350];
generatePatternedData(buff, 350, 24, 5, 3);
wxString str = wxBase64Encode(buff, 350);
wxMemoryBuffer mbuff = wxBase64Decode(str);
CPPUNIT_ASSERT(memcmp(mbuff.GetData(), buff, mbuff.GetDataLen()) == 0);
}
void Base64TestCase::EncodeDecodePatternB()
{
unsigned char buff[350];
generatePatternedData(buff, 350, 0, 1, 1, 0xAA);
wxString str = wxBase64Encode(buff, 350);
wxMemoryBuffer mbuff = wxBase64Decode(str);
CPPUNIT_ASSERT(memcmp(mbuff.GetData(), buff, mbuff.GetDataLen()) == 0);
}
void Base64TestCase::EncodeDecodePatternC()
{
unsigned char buff[11];
generatePatternedData(buff, 11, 1, 0, 2);
wxString str = wxBase64Encode(buff, 11);
wxMemoryBuffer mbuff = wxBase64Decode(str);
CPPUNIT_ASSERT(memcmp(mbuff.GetData(), buff, mbuff.GetDataLen()) == 0);
}
void Base64TestCase::EncodeDecodeRandom()
{
size_t size = rand() * 3000 / RAND_MAX + 11;
unsigned char *buff = new unsigned char[size];
generateRandomData(buff, size);
wxString str = wxBase64Encode(buff, size);
wxMemoryBuffer mbuff = wxBase64Decode(str);
CPPUNIT_ASSERT(memcmp(mbuff.GetData(), buff, mbuff.GetDataLen()) == 0);
generateGibberish(buff, size);
char *buff2 = new char[size];
size_t realsize = size;
CPPUNIT_ASSERT(wxBase64Decode(buff2, realsize, (char *)buff, size));
CPPUNIT_ASSERT(wxBase64Encode(buff2, size, buff2, realsize));
}
#endif // wxUSE_BASE64

View File

@@ -28,6 +28,7 @@
archive/ziptest.cpp
archive/tartest.cpp
arrays/arrays.cpp
base64/base64.cpp
datetime/datetimetest.cpp
fileconf/fileconftest.cpp
filekind/filekind.cpp