- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

gbase64.cpp
Go to the documentation of this file.
1 //
2 // Copyright (C) 2001-2013 Graeme Walker <graeme_walker@users.sourceforge.net>
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 // ===
17 //
18 // gbase64.cpp
19 //
20
21 #include "gdef.h"
22 #include "gbase64.h"
23 #include "gassert.h"
24 #include "gstr.h"
25 #include <cstring>
26
27 namespace
28 {
29 const char * character_map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" ;
30 char pad = '=' ;
31 }
32
33 g_uint32_t G::Base64::numeric( char c )
34 {
35 return static_cast<g_uint32_t>( static_cast<unsigned char>(c) ) ;
36 }
37
38 void G::Base64::accumulate_8( g_uint32_t & n , std::string::const_iterator & p ,
39 std::string::const_iterator end , int & i )
40 {
41 char c = p == end ? '\0' : *p ;
42 n <<= 8U ;
43 n |= numeric(c) ;
44 if( p != end )
45 {
46 ++p ;
47 ++i ;
48 }
49 }
50
51 size_t G::Base64::hi_6( g_uint32_t n )
52 {
53 return (n >> 18U) & 0x3F ;
54 }
55
56 void G::Base64::generate_6( g_uint32_t & n , int & i , std::string & result )
57 {
58 char c = i-- >= 0 ? character_map[hi_6(n)] : pad ;
59 result.append( 1U , c ) ;
60 n <<= 6U ;
61 }
62
63 std::string G::Base64::encode( const std::string & s_in )
64 {
65 return encode( s_in , "\015\012" ) ;
66 }
67
68 std::string G::Base64::encode( const std::string & s_in , const std::string & eol )
69 {
70 std::string result ;
71 size_t blocks = 0U ;
72 for( std::string::const_iterator p = s_in.begin() ; p != s_in.end() ; blocks++ )
73 {
74 if( blocks && (blocks % 19U) == 0U )
75 result.append( eol ) ;
76
77 g_uint32_t n = 0UL ;
78 int i = 0 ;
79 accumulate_8( n , p , s_in.end() , i ) ;
80 accumulate_8( n , p , s_in.end() , i ) ;
81 accumulate_8( n , p , s_in.end() , i ) ;
82 generate_6( n , i , result ) ;
83 generate_6( n , i , result ) ;
84 generate_6( n , i , result ) ;
85 generate_6( n , i , result ) ;
86 }
87
88 return result ;
89 }
90
91 // ---
92
93 char G::Base64::to_char( g_uint32_t n )
94 {
95 return static_cast<char>(static_cast<unsigned char>(n)) ;
96 }
97
98 size_t G::Base64::index( char c , bool & error )
99 {
100 const char * p = std::strchr( character_map , c ) ;
101 error = error || !c || !p ;
102 if( p == NULL )
103 return 0U ;
104 else
105 return static_cast<size_t>( p - character_map ) ;
106 }
107
108 size_t G::Base64::accumulate_6( g_uint32_t & n , char c_in , int & n_out , bool & error )
109 {
110 n <<= 6U ;
111 if( c_in != pad )
112 {
113 n |= index(c_in,error) ;
114 n_out++ ;
115 }
116 return c_in != '\0' ;
117 }
118
119 g_uint32_t G::Base64::hi_8( g_uint32_t n )
120 {
121 return (n >> 16U) & 0xff ;
122 }
123
124 void G::Base64::generate_8( g_uint32_t & n , int & n_out , std::string & result )
125 {
126 if( n_out-- > 0 )
127 result.append( 1U , to_char(hi_8(n)) ) ;
128 n <<= 8U ;
129 }
130
131 std::string G::Base64::decode( const std::string & s )
132 {
133 bool error = false ;
134 std::string result = decode( s , error ) ;
135 if( error )
136 throw Error() ;
137 return result ;
138 }
139
140 std::string G::Base64::decode( const std::string & s , bool & error )
141 {
142 std::string result ;
143 for( const char * p = s.c_str() ; *p ; )
144 {
145 if( *p == '\r' || *p == '\n' )
146 {
147 p++ ;
148 continue ;
149 }
150
151 g_uint32_t n = 0UL ;
152 size_t i = 0U ;
153 int n_out = -1 ;
154 i += accumulate_6( n , p[i] , n_out , error ) ;
155 i += accumulate_6( n , p[i] , n_out , error ) ;
156 i += accumulate_6( n , p[i] , n_out , error ) ;
157 i += accumulate_6( n , p[i] , n_out , error ) ;
158 p += i ;
159 generate_8( n , n_out , result ) ;
160 generate_8( n , n_out , result ) ;
161 generate_8( n , n_out , result ) ;
162 }
163 return result ;
164 }
165
166 bool G::Base64::valid( const std::string & s )
167 {
168 bool error = false ;
169 G_IGNORE_RETURN(std::string) decode( s , error ) ;
170 return !error ;
171 }
172
G::Base64::valid
static bool valid(const std::string &)
Returns true if the string can be decoded.
Definition: gbase64.cpp:166
gstr.h
gassert.h
gbase64.h
G::Base64::decode
static std::string decode(const std::string &)
Decodes the given string.
Definition: gbase64.cpp:131
G::Base64::encode
static std::string encode(const std::string &s, const std::string &line_break)
Encodes the given string.
Definition: gbase64.cpp:68