diff options
Diffstat (limited to '')
-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 | } | ||