E-MailRelay

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

gxtext.cpp
Go to the documentation of this file.
1 //
2 // Copyright (C) 2001-2018 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 // gxtext.cpp
19 //
20
21 #include "gdef.h"
22 #include "gxtext.h"
23 #include "gstr.h"
24 #include "gassert.h"
25
26 namespace
27 {
28 inline char hex( unsigned int n )
29 {
30 static const char * map = "0123456789ABCDEF" ;
31 return map[n] ;
32 }
33 inline bool ishex( char c )
34 {
35 return
36 ( c >= '0' && c <= '9' ) ||
37 ( c >= 'a' && c <= 'f' ) || // moot
38 ( c >= 'A' && c <= 'F' ) ;
39 }
40 inline unsigned int unhex( char c )
41 {
42 unsigned int rc = 0U ;
43 switch( c )
44 {
45 case '0': rc = 0U ; break ;
46 case '1': rc = 1U ; break ;
47 case '2': rc = 2U ; break ;
48 case '3': rc = 3U ; break ;
49 case '4': rc = 4U ; break ;
50 case '5': rc = 5U ; break ;
51 case '6': rc = 6U ; break ;
52 case '7': rc = 7U ; break ;
53 case '8': rc = 8U ; break ;
54 case '9': rc = 9U ; break ;
55 case 'A': rc = 10U ; break ;
56 case 'B': rc = 11U ; break ;
57 case 'C': rc = 12U ; break ;
58 case 'D': rc = 13U ; break ;
59 case 'E': rc = 14U ; break ;
60 case 'F': rc = 15U ; break ;
61 case 'a': rc = 10U ; break ; // moot
62 case 'b': rc = 11U ; break ;
63 case 'c': rc = 12U ; break ;
64 case 'd': rc = 13U ; break ;
65 case 'e': rc = 14U ; break ;
66 case 'f': rc = 15U ; break ;
67 }
68 return rc ;
69 }
70 }
71
72 bool G::Xtext::valid( const std::string & s )
73 {
74 if( s.find('\x7f') != std::string::npos ) return false ;
75 if( s.find(' ') != std::string::npos ) return false ;
76 if( s.find('+') == std::string::npos ) return G::Str::isPrintableAscii(s) ;
77 for( size_t pos = s.find('+') ; pos != std::string::npos ; pos = ((pos+1U)==s.size()?std::string::npos:s.find('+',pos+1U)) )
78 {
79 if( (pos+2U) >= s.size() ) return false ;
80 if( !ishex(s.at(pos+1U)) ) return false ;
81 if( !ishex(s.at(pos+2U)) ) return false ;
82 }
83 return true ;
84 }
85
86 std::string G::Xtext::encode( const std::string & s )
87 {
88 std::string result ;
89 for( std::string::const_iterator p = s.begin() ; p != s.end() ; ++p )
90 {
91 if( *p >= '!' && *p <= '~' && *p != '=' && *p != '+' )
92 {
93 result.append( 1U , *p ) ;
94 }
95 else
96 {
97 unsigned int n = static_cast<unsigned char>(*p) ;
98 result.append( 1U , '+' ) ;
99 result.append( 1U , hex( n >> 4U ) ) ;
100 result.append( 1U , hex( n & 0x0f ) ) ;
101 }
102 }
103 G_ASSERT( decode(result) == s ) ;
104 return result ;
105 }
106
107 std::string G::Xtext::decode( const std::string & s )
108 {
109 std::string result ;
110 for( std::string::const_iterator p = s.begin() ; p != s.end() ; ++p )
111 {
112 if( *p == '+' )
113 {
114 ++p ; if( p == s.end() ) break ;
115 char h1 = *p++ ; if( p == s.end() ) break ;
116 char h2 = *p ;
117 unsigned int c = ( unhex(h1) << 4U ) | unhex(h2) ;
118 result.append( 1U , static_cast<char>(static_cast<unsigned char>(c)) ) ;
119 }
120 else
121 {
122 result.append( 1U , *p ) ;
123 }
124 }
125 return result ;
126 }
127
128 /// \file gxtext.cpp
G::Xtext::decode
static std::string decode(const std::string &)
Decodes the given string.
Definition: gxtext.cpp:107
G::Xtext::encode
static std::string encode(const std::string &)
Encodes the given string.
Definition: gxtext.cpp:86
G::Xtext::valid
static bool valid(const std::string &)
Returns true if a valid encoding.
Definition: gxtext.cpp:72
gstr.h
gassert.h
gxtext.h
G::Str::isPrintableAscii
static bool isPrintableAscii(const std::string &s)
Returns true if every character is a 7-bit, non-control character (ie.
Definition: gstr.cpp:282