ALib C++ Library
Library Version: 2511 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
escaper.cpp
1//##################################################################################################
2// ALib C++ Library
3//
4// Copyright 2013-2025 A-Worx GmbH, Germany
5// Published under 'Boost Software License' (a free software license, see LICENSE.txt)
6//##################################################################################################
7#include "alib_precompile.hpp"
8#if !defined(ALIB_C20_MODULES) || ((ALIB_C20_MODULES != 0) && (ALIB_C20_MODULES != 1))
9# error "Symbol ALIB_C20_MODULES has to be given to the compiler as either 0 or 1"
10#endif
11#if ALIB_C20_MODULES
12 module;
13#endif
14//========================================= Global Fragment ========================================
16#include "ALib.Strings.Vector.H"
17//============================================== Module ============================================
18#if ALIB_C20_MODULES
19 module ALib.Strings.Escaper;
20 import ALib.Strings.Tokenizer;
21#else
22# include "ALib.Strings.Escaper.H"
24#endif
25
26//========================================== Implementation ========================================
27namespace alib::strings::util {
28
29//==================================================================================================
30// ==== StringEscaper
31//==================================================================================================
32#if ALIB_MONOMEM
33int StringEscaper::EscapeTokens( StringVectorMA& result, const String& value, const String& delimiters ) const {
34 const integer oldSize= result.Size();
35 Tokenizer tknzr( value, delimiters.CharAtStart() );
36 tknzr.TrimChars.Reset();
37 while(tknzr.HasNext())
38 result.Add( tknzr.Next() );
39
40 return int(result.Size() - oldSize);
41}
42#endif // if ALIB_MONOMEM
43
44//==================================================================================================
45// ==== StringEscaperStandard
46//==================================================================================================
48 Substring parser(src);
49 parser.Trim();
50 if( parser.Length() > 1 && parser.CharAtStart() == '"' && parser.CharAtEnd() == '"') {
51 parser.ConsumeChar <NC>();
52 parser.ConsumeCharFromEnd<NC>();
53 }
54 bool lastWasSlash= false;
55
56 while( parser.IsNotEmpty() ) {
57 character c= parser.ConsumeChar<NC>();
58
59 if( lastWasSlash ) {
60 lastWasSlash= false;
61 character escChr= c == '\\' ? '\\' :
62 c == '"' ? '"' :
63 c == 'n' ? '\n' :
64 c == 'r' ? '\r' :
65 c == 't' ? '\t' :
66 c == 'a' ? '\a' :
67 c == 'b' ? '\b' :
68 c == 'v' ? '\v' :
69 c == 'f' ? '\f' :
70 c == 'e' ? '\033' :
71 c;
72
73 dest._<NC>(escChr);
74 continue;
75 }
76
77 if( c== '\\' ) {
78 lastWasSlash= true;
79 continue;
80 }
81
82 dest._<NC>(c);
83 }
84
85 return dest;
86}
87
89 const String& delimiters ) const {
90 Substring parser(src);
91 bool needsQuotes= parser.CharAtStart() == ' '
92 || parser.CharAtStart() == '\t'
93 || parser.CharAtEnd() == ' '
94 || parser.CharAtEnd() == '\t';
95 if (!needsQuotes)
96 for( character c : delimiters )
97 if( parser.IndexOf(c) >= 0 ) {
98 needsQuotes= true;
99 break;
100 }
101
102 if ( needsQuotes )
103 dest._<NC>('"');
104
105 while( parser.IsNotEmpty() ) {
106 character c= parser.ConsumeChar();
107
108 switch(c) {
109 case '"' : dest._<NC>(needsQuotes ? "\\\"" : "\"");
110 break;
111 case '\\' : dest._<NC>("\\\\"); break;
112 case '\r' : dest._<NC>("\\r" ); break;
113 case '\n' : dest._<NC>("\\n" ); break;
114 case '\t' : dest._<NC>("\\t" ); break;
115 case '\a' : dest._<NC>("\\a" ); break;
116 case '\b' : dest._<NC>("\\b" ); break;
117 case '\v' : dest._<NC>("\\v" ); break;
118 case '\f' : dest._<NC>("\\f" ); break;
119 case '\033' : dest._<NC>("\\e" ); break;
120 default : dest._<NC>(c); break;
121 } }
122
123 if ( needsQuotes )
124 dest._('"');
125
126 return dest;
127}
128
129
130#if ALIB_MONOMEM
131int StringEscaperStandard::EscapeTokens( StringVectorMA& result, const String& src, const String& delimiters ) const {
132 String2K buf;
133 const integer oldSize= result.Size();
134 Tokenizer tknzr( src, delimiters.CharAtStart() );
135 tknzr.TrimChars.Reset();
136 while(tknzr.HasNext()) {
137 Escape( tknzr.Next(), buf.Reset(), delimiters );
138 result.Add( buf );
139 }
140 return int(result.Size() - oldSize);
141}
142
143int StringEscaperStandard::UnescapeTokens( StringVectorMA& result, const String& value, const String& delimiters ) const {
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 character c= src.CharAt<NC>( idx++ );
154
155 if( lastWasSlash ) {
156 lastWasSlash= false;
157 continue;
158 }
159
160 if( c== '\\' ) {
161 lastWasSlash= true;
162 continue;
163 }
164
165 if( c== '"' && (idx==1 || inQuote) ) {
166 inQuote= !inQuote;
167 continue;
168 }
169
170 if( !inQuote && delimiters.IndexOf(c) >= 0 ) {
171 Substring tok= src.Substring<NC>( 0, idx - 1 );
172 Unescape( tok, tempBuf );
173 result.Add( tempBuf );
174 tempBuf.Reset();
175 src.ConsumeChars( idx );
176 src.TrimStart();
177 idx= 0;
178 } }
179
180 if ( src.IsNotEmpty() ) {
181 Unescape( src, tempBuf );
182 result.Add( tempBuf );
183 }
184
185 return int (result.Size() - oldSize);
186}
187#endif // if ALIB_MONOMEM
188
189
190
191} // namespace [alib::util::strings]
TAString & _(const TAppendable &src)
void DbgDisableBufferReplacementWarning()
Definition tastring.inl:244
constexpr integer Length() const
Definition string.inl:316
TChar CharAtStart() const
Definition string.inl:433
integer IndexOf(TChar needle, integer startIdx=0) const
Definition string.inl:815
TChar CharAt(integer idx) const
Definition string.inl:415
constexpr bool IsNotEmpty() const
Definition string.inl:369
TChar CharAtEnd() const
Definition string.inl:452
TString< TChar > Substring(integer regionStart, integer regionLength=MAX_LEN) const
Definition string.inl:384
TSubstring & TrimStart(const TCString< TChar > &whiteSpaces=CStringConstantsTraits< TChar >::DefaultWhitespaces())
Definition substring.inl:70
bool ConsumeCharFromEnd(TChar consumable)
integer ConsumeChars(integer regionLength, TSubstring *target=nullptr)
TSubstring & Trim(const TCString< TChar > &whiteSpaces=CStringConstantsTraits< TChar >::DefaultWhitespaces())
integer Add(const strings::TString< TChar > &src)
ALIB_DLL TSubstring< TChar > & Next(lang::Whitespaces trimming=lang::Whitespaces::Trim, TChar newDelim='\0')
Definition tokenizer.cpp:26
TLocalString< TChar, 8 > TrimChars
Definition tokenizer.inl:71
strings::TEscape< character > Escape
Type alias in namespace alib.
Definition format.inl:532
LocalString< 512 > String512
Type alias name for TLocalString<character,512>.
strings::TAString< character, lang::HeapAllocator > AString
Type alias in namespace alib.
strings::util::TTokenizer< character > Tokenizer
Type alias in namespace alib.
strings::util::TStringVector< character, MonoAllocator > StringVectorMA
Type alias in namespace alib.
lang::integer integer
Type alias in namespace alib.
Definition integers.inl:149
strings::TString< character > String
Type alias in namespace alib.
Definition string.inl:2189
characters::character character
Type alias in namespace alib.
LocalString< 2048 > String2K
Type alias name for TLocalString<character,2048>.
strings::TSubstring< character > Substring
Type alias in namespace alib.
virtual ALIB_DLL AString & Unescape(const String &src, AString &dest) const override
Definition escaper.cpp:47
virtual ALIB_DLL int UnescapeTokens(StringVectorMA &result, const String &src, const String &delimiters) const override
Definition escaper.cpp:143
virtual ALIB_DLL AString & Escape(const String &src, AString &dest, const String &delimiters) const override
Definition escaper.cpp:88
virtual ALIB_DLL int EscapeTokens(StringVectorMA &result, const String &src, const String &delimiters) const override
Definition escaper.cpp:131
virtual ALIB_DLL int EscapeTokens(StringVectorMA &result, const String &src, const String &delimiters) const
Definition escaper.cpp:33