ALib C++ Library
Library Version: 2412 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
escaper.cpp
1// #################################################################################################
2// ALib C++ Library
3//
4// Copyright 2013-2024 A-Worx GmbH, Germany
5// Published under 'Boost Software License' (a free software license, see LICENSE.txt)
6// #################################################################################################
8
9#if !DOXYGEN
12#endif // !DOXYGEN
13
14namespace alib::strings::util {
15
16// =================================================================================================
17// ==== StringEscaper
18// =================================================================================================
19#if ALIB_MONOMEM
20int StringEscaper::EscapeTokens( StringVectorMA& result, const String& value, const String& delimiters ) const
21{
22 const integer oldSize= result.Size();
23 Tokenizer tknzr( value, delimiters.CharAtStart() );
24 tknzr.TrimChars.Reset();
25 while(tknzr.HasNext())
26 result.Add( tknzr.Next() );
27
28 return int(result.Size() - oldSize);
29}
30#endif // if ALIB_MONOMEM
31
32// =================================================================================================
33// ==== StringEscaperStandard
34// =================================================================================================
36{
37 Substring parser(src);
38 parser.Trim();
39 if( parser.Length() > 1 && parser.CharAtStart() == '"' && parser.CharAtEnd() == '"')
40 {
41 parser.ConsumeChar <NC>();
42 parser.ConsumeCharFromEnd<NC>();
43 }
44 bool lastWasSlash= false;
45
46 while( parser.IsNotEmpty() )
47 {
48 character c= parser.ConsumeChar<NC>();
49
50 if( lastWasSlash )
51 {
52 lastWasSlash= false;
53 character escChr= c == '\\' ? '\\' :
54 c == '"' ? '"' :
55 c == 'n' ? '\n' :
56 c == 'r' ? '\r' :
57 c == 't' ? '\t' :
58 c == 'a' ? '\a' :
59 c == 'b' ? '\b' :
60 c == 'v' ? '\v' :
61 c == 'f' ? '\f' :
62 c == 'e' ? '\033' :
63 c;
64
65 dest._<NC>(escChr);
66 continue;
67 }
68
69 if( c== '\\' )
70 {
71 lastWasSlash= true;
72 continue;
73 }
74
75 dest._<NC>(c);
76 }
77
78 return dest;
79}
80
81AString& StringEscaperStandard::Escape( const String& src, AString& dest, const String& delimiters ) const
82{
83 Substring parser(src);
84 bool needsQuotes= parser.CharAtStart() == ' '
85 || parser.CharAtStart() == '\t'
86 || parser.CharAtEnd() == ' '
87 || parser.CharAtEnd() == '\t';
88 if (!needsQuotes)
89 for( auto c : delimiters )
90 if( parser.IndexOf(c) >= 0 )
91 {
92 needsQuotes= true;
93 break;
94 }
95
96 if ( needsQuotes )
97 dest._<NC>('"');
98
99 while( parser.IsNotEmpty() )
100 {
101 character c= parser.ConsumeChar();
102
103 switch(c)
104 {
105 case '"' : dest._<NC>(needsQuotes ? "\\\"" : "\"");
106 break;
107 case '\\' : dest._<NC>("\\\\"); break;
108 case '\r' : dest._<NC>("\\r" ); break;
109 case '\n' : dest._<NC>("\\n" ); break;
110 case '\t' : dest._<NC>("\\t" ); break;
111 case '\a' : dest._<NC>("\\a" ); break;
112 case '\b' : dest._<NC>("\\b" ); break;
113 case '\v' : dest._<NC>("\\v" ); break;
114 case '\f' : dest._<NC>("\\f" ); break;
115 case '\033' : dest._<NC>("\\e" ); break;
116 default : dest._<NC>(c); break;
117 }
118 }
119
120 if ( needsQuotes )
121 dest._('"');
122
123 return dest;
124}
125
126
127#if ALIB_MONOMEM
128int StringEscaperStandard::EscapeTokens( StringVectorMA& result, const String& src, const String& delimiters ) const
129{
130 String2K buf;
131 const integer oldSize= result.Size();
132 Tokenizer tknzr( src, delimiters.CharAtStart() );
133 tknzr.TrimChars.Reset();
134 while(tknzr.HasNext())
135 {
136 Escape( tknzr.Next(), buf.Reset(), delimiters );
137 result.Add( buf );
138 }
139 return int(result.Size() - oldSize);
140}
141
142int StringEscaperStandard::UnescapeTokens( StringVectorMA& result, const String& value, const String& delimiters ) const
143{
144 const integer oldSize= result.Size();
146 Substring src( value );
147
148 // tokenize
149 bool inQuote= false;
150 bool lastWasSlash= false;
151 integer idx= 0;
152 while( idx < src.Length() )
153 {
154 character c= src.CharAt<NC>( idx++ );
155
156 if( lastWasSlash )
157 {
158 lastWasSlash= false;
159 continue;
160 }
161
162 if( c== '\\' )
163 {
164 lastWasSlash= true;
165 continue;
166 }
167
168 if( c== '"' && (idx==1 || inQuote) )
169 {
170 inQuote= !inQuote;
171 continue;
172 }
173
174 if( !inQuote && delimiters.IndexOf(c) >= 0 )
175 {
176 Substring tok= src.Substring<NC>( 0, idx - 1 );
177 Unescape( tok, tempBuf );
178 result.Add( tempBuf );
179 tempBuf.Reset();
180 src.ConsumeChars( idx );
181 src.TrimStart();
182 idx= 0;
183 }
184 }
185
186 if ( src.IsNotEmpty() )
187 {
188 Unescape( src, tempBuf );
189 result.Add( tempBuf );
190 }
191
192 return int (result.Size() - oldSize);
193}
194#endif // if ALIB_MONOMEM
195
196
197
198} // namespace [alib::util::strings]
TAString & _(const TString< TChar > &src, integer regionStart, integer regionLength=MAX_LEN)
void DbgDisableBufferReplacementWarning()
Definition tastring.inl:363
integer IndexOf(TChar needle, integer startIdx=0) const
Definition string.hpp:896
TChar CharAt(integer idx) const
Definition string.hpp:444
constexpr bool IsNotEmpty() const
Definition string.hpp:389
constexpr integer Length() const
Definition string.hpp:326
TChar CharAtStart() const
Definition string.hpp:466
TString< TChar > Substring(integer regionStart, integer regionLength=MAX_LEN) const
Definition string.hpp:406
TChar CharAtEnd() const
Definition string.hpp:488
integer ConsumeChars(integer regionLength, TSubstring *target=nullptr)
TSubstring & TrimStart(const TCString< TChar > &whiteSpaces=TT_CStringConstants< TChar >::DefaultWhitespaces())
Definition substring.hpp:89
bool ConsumeCharFromEnd(TChar consumable)
TSubstring & Trim(const TCString< TChar > &whiteSpaces=TT_CStringConstants< TChar >::DefaultWhitespaces())
integer Add(const strings::TString< TChar > &src)
TLocalString< TChar, 8 > TrimChars
Definition tokenizer.hpp:77
ALIB_API TSubstring< TChar > & Next(lang::Whitespaces trimming=lang::Whitespaces::Trim, TChar newDelim='\0')
Definition tokenizer.cpp:16
characters::character character
Type alias in namespace alib.
lang::integer integer
Type alias in namespace alib.
Definition integers.hpp:273
virtual ALIB_API int UnescapeTokens(StringVectorMA &result, const String &src, const String &delimiters) const override
Definition escaper.cpp:142
virtual ALIB_API AString & Escape(const String &src, AString &dest, const String &delimiters) const override
Definition escaper.cpp:81
virtual ALIB_API AString & Unescape(const String &src, AString &dest) const override
Definition escaper.cpp:35
virtual ALIB_API int EscapeTokens(StringVectorMA &result, const String &src, const String &delimiters) const override
Definition escaper.cpp:128
virtual ALIB_API int EscapeTokens(StringVectorMA &result, const String &src, const String &delimiters) const
Definition escaper.cpp:20