diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/base64.cpp | 132 | ||||
| -rw-r--r-- | src/base64.h | 45 | ||||
| -rw-r--r-- | src/file.h | 4 | ||||
| -rw-r--r-- | src/tests/base64.cpp | 45 |
4 files changed, 225 insertions, 1 deletions
diff --git a/src/base64.cpp b/src/base64.cpp new file mode 100644 index 0000000..723788b --- /dev/null +++ b/src/base64.cpp | |||
| @@ -0,0 +1,132 @@ | |||
| 1 | #include "bu/base64.h" | ||
| 2 | |||
| 3 | const char Bu::Base64::tblEnc[65] = { | ||
| 4 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" | ||
| 5 | }; | ||
| 6 | |||
| 7 | Bu::Base64::Base64( Bu::Stream &rNext, Mode eMode ) : | ||
| 8 | Bu::Filter( rNext ), | ||
| 9 | iBPos( 0 ), | ||
| 10 | iBuf( 0 ), | ||
| 11 | iTotalIn( 0 ), | ||
| 12 | iTotalOut( 0 ), | ||
| 13 | eMode( eMode ) | ||
| 14 | { | ||
| 15 | start(); | ||
| 16 | |||
| 17 | memset( tblDec, 0, 80 ); | ||
| 18 | for( int j = 0; j < 64; j++ ) | ||
| 19 | { | ||
| 20 | tblDec[tblEnc[j]-'+'] = j; | ||
| 21 | // printf("'%c' = %d\n", tblEnc[j], j ); | ||
| 22 | } | ||
| 23 | /* | ||
| 24 | for( int j = 0; j < 64; j++ ) | ||
| 25 | { | ||
| 26 | printf("'%c' = '%c' (%d = %d)\n", | ||
| 27 | tblEnc[j], tblEnc[tblDec[tblEnc[j]-'+']], | ||
| 28 | j, tblDec[tblEnc[j]-'+'] ); | ||
| 29 | }*/ | ||
| 30 | |||
| 31 | // The following is used to compute the table size for the decoding table. | ||
| 32 | /* | ||
| 33 | char low='A', high='A'; | ||
| 34 | for( int j = 0; j < 64; j++ ) | ||
| 35 | { | ||
| 36 | if( tblEnc[j] < low ) | ||
| 37 | low = tblEnc[j]; | ||
| 38 | if( tblEnc[j] > high ) | ||
| 39 | high = tblEnc[j]; | ||
| 40 | } | ||
| 41 | |||
| 42 | printf("'%c' - '%c' (%d - %d) (%d)\n", low, high, low, high, high-low ); | ||
| 43 | */ | ||
| 44 | } | ||
| 45 | |||
| 46 | Bu::Base64::~Base64() | ||
| 47 | { | ||
| 48 | stop(); | ||
| 49 | } | ||
| 50 | |||
| 51 | void Bu::Base64::start() | ||
| 52 | { | ||
| 53 | } | ||
| 54 | |||
| 55 | size_t Bu::Base64::stop() | ||
| 56 | { | ||
| 57 | if( eMode == Write ) | ||
| 58 | { | ||
| 59 | char outBuf[4]; | ||
| 60 | int iBUsed = 4-(3-iBPos); | ||
| 61 | if( iBPos == 0 ) | ||
| 62 | return iTotalOut; | ||
| 63 | for( int k = 0; k < 4; k++ ) | ||
| 64 | { | ||
| 65 | outBuf[3-k] = tblEnc[(iBuf>>(6*k))&0x3f]; | ||
| 66 | } | ||
| 67 | for( int k = iBUsed; k < 4; k++ ) | ||
| 68 | { | ||
| 69 | outBuf[k] = '='; | ||
| 70 | } | ||
| 71 | iTotalOut += rNext.write( outBuf, 4 ); | ||
| 72 | return iTotalOut; | ||
| 73 | } | ||
| 74 | else | ||
| 75 | { | ||
| 76 | return iTotalIn; | ||
| 77 | } | ||
| 78 | } | ||
| 79 | |||
| 80 | size_t Bu::Base64::read( void *pBuf, size_t nBytes ) | ||
| 81 | { | ||
| 82 | size_t sIn = 0; | ||
| 83 | char buf[4]; | ||
| 84 | while( sIn < nBytes ) | ||
| 85 | { | ||
| 86 | if( rNext.read( buf, 4 ) == 0 ) | ||
| 87 | return sIn; | ||
| 88 | int iChars = 3; | ||
| 89 | for( int j = 0; j < 4; j++ ) | ||
| 90 | { | ||
| 91 | if( buf[j] == '=' ) | ||
| 92 | iChars--; | ||
| 93 | else | ||
| 94 | iBuf |= (tblDec[buf[j]-'+']&0x3f)<<((3-j)*6); | ||
| 95 | printf("%d: %06X (%02X)\n", j, iBuf, (tblDec[buf[j]-'+']&0x3f) ); | ||
| 96 | } | ||
| 97 | for( int j = 0; j < iChars; j++ ) | ||
| 98 | { | ||
| 99 | ((unsigned char *)pBuf)[sIn++] = (iBuf>>(8*(2-j)))&0xFF; | ||
| 100 | } | ||
| 101 | iBuf = 0; | ||
| 102 | } | ||
| 103 | |||
| 104 | return sIn; | ||
| 105 | } | ||
| 106 | |||
| 107 | size_t Bu::Base64::write( const void *pBuf, size_t nBytes ) | ||
| 108 | { | ||
| 109 | size_t sOut = 0; | ||
| 110 | char outBuf[4]; | ||
| 111 | for( size_t j = 0; j < nBytes; j++ ) | ||
| 112 | { | ||
| 113 | iBuf |= (((uint8_t *)pBuf)[j])<<((2-iBPos++)*8); | ||
| 114 | if( iBPos == 3 ) | ||
| 115 | { | ||
| 116 | for( int k = 0; k < 4; k++ ) | ||
| 117 | { | ||
| 118 | outBuf[3-k] = tblEnc[(iBuf>>(6*k))&0x3f]; | ||
| 119 | } | ||
| 120 | sOut += rNext.write( outBuf, 4 ); | ||
| 121 | iBPos = iBuf = 0; | ||
| 122 | } | ||
| 123 | } | ||
| 124 | iTotalOut += sOut; | ||
| 125 | return sOut; | ||
| 126 | } | ||
| 127 | |||
| 128 | bool Bu::Base64::isOpen() | ||
| 129 | { | ||
| 130 | return true; | ||
| 131 | } | ||
| 132 | |||
diff --git a/src/base64.h b/src/base64.h new file mode 100644 index 0000000..2c3b331 --- /dev/null +++ b/src/base64.h | |||
| @@ -0,0 +1,45 @@ | |||
| 1 | #ifndef BU_BASE64_H | ||
| 2 | #define BU_BASE64_H | ||
| 3 | |||
| 4 | #include "bu/filter.h" | ||
| 5 | |||
| 6 | namespace Bu | ||
| 7 | { | ||
| 8 | /** | ||
| 9 | * | ||
| 10 | *@ingroup Streams | ||
| 11 | */ | ||
| 12 | class Base64 : public Bu::Filter | ||
| 13 | { | ||
| 14 | public: | ||
| 15 | enum Mode | ||
| 16 | { | ||
| 17 | Encode = 0x01, | ||
| 18 | Read = 0x01, | ||
| 19 | Decode = 0x02, | ||
| 20 | Write = 0x02 | ||
| 21 | }; | ||
| 22 | |||
| 23 | public: | ||
| 24 | Base64( Bu::Stream &rNext, Mode eMode ); | ||
| 25 | virtual ~Base64(); | ||
| 26 | |||
| 27 | virtual void start(); | ||
| 28 | virtual size_t stop(); | ||
| 29 | virtual size_t read( void *pBuf, size_t nBytes ); | ||
| 30 | virtual size_t write( const void *pBuf, size_t nBytes ); | ||
| 31 | |||
| 32 | virtual bool isOpen(); | ||
| 33 | |||
| 34 | private: | ||
| 35 | int iBPos; | ||
| 36 | int iBuf; | ||
| 37 | size_t iTotalIn; | ||
| 38 | size_t iTotalOut; | ||
| 39 | static const char tblEnc[65]; | ||
| 40 | char tblDec[80]; | ||
| 41 | Mode eMode; | ||
| 42 | }; | ||
| 43 | }; | ||
| 44 | |||
| 45 | #endif | ||
| @@ -65,7 +65,9 @@ namespace Bu | |||
| 65 | Exclusive = 0x44, ///< Create file, if it exists then fail | 65 | Exclusive = 0x44, ///< Create file, if it exists then fail |
| 66 | 66 | ||
| 67 | // Helpful mixes | 67 | // Helpful mixes |
| 68 | ReadWrite = 0x03 ///< Open for reading and writing | 68 | ReadWrite = 0x03, ///< Open for reading and writing |
| 69 | WriteNew = 0x0E ///< Create a file (or truncate) for writing. | ||
| 70 | /// Same as Write|Create|Truncate | ||
| 69 | }; | 71 | }; |
| 70 | /** | 72 | /** |
| 71 | * Create a temp file and return its handle. The file is opened | 73 | * Create a temp file and return its handle. The file is opened |
diff --git a/src/tests/base64.cpp b/src/tests/base64.cpp new file mode 100644 index 0000000..4f2d68b --- /dev/null +++ b/src/tests/base64.cpp | |||
| @@ -0,0 +1,45 @@ | |||
| 1 | #include "bu/file.h" | ||
| 2 | #include "bu/base64.h" | ||
| 3 | |||
| 4 | int main( int argc, char *argv[] ) | ||
| 5 | { | ||
| 6 | argc--,argv++; | ||
| 7 | |||
| 8 | if( argc < 3 ) | ||
| 9 | return 0; | ||
| 10 | |||
| 11 | if( argv[0][0] == 'e' ) | ||
| 12 | { | ||
| 13 | argv++; | ||
| 14 | Bu::File fIn( argv[0], Bu::File::Read ); | ||
| 15 | Bu::File fOut( argv[1], Bu::File::WriteNew ); | ||
| 16 | Bu::Base64 bOut( fOut, Bu::Base64::Write ); | ||
| 17 | |||
| 18 | char buf[900]; | ||
| 19 | for(;;) | ||
| 20 | { | ||
| 21 | int iRead = fIn.read( buf, 900 ); | ||
| 22 | bOut.write( buf, iRead ); | ||
| 23 | if( iRead < 900 ) | ||
| 24 | break; | ||
| 25 | } | ||
| 26 | } | ||
| 27 | else if( argv[0][0] == 'd' ) | ||
| 28 | { | ||
| 29 | argv++; | ||
| 30 | Bu::File fIn( argv[0], Bu::File::Read ); | ||
| 31 | Bu::File fOut( argv[1], Bu::File::WriteNew ); | ||
| 32 | Bu::Base64 bIn( fIn, Bu::Base64::Read ); | ||
| 33 | |||
| 34 | char buf[900]; | ||
| 35 | for(;;) | ||
| 36 | { | ||
| 37 | int iRead = bIn.read( buf, 900 ); | ||
| 38 | fOut.write( buf, iRead ); | ||
| 39 | if( iRead < 900 ) | ||
| 40 | break; | ||
| 41 | } | ||
| 42 | } | ||
| 43 | |||
| 44 | return 0; | ||
| 45 | } | ||
