E-MailRelay

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