GitHub Actions: Try MSVC builds with /std:c++17 and 20
[ACE_TAO.git] / ACE / ace / Tokenizer_T.cpp
blob5be90545efac2a7c5f8e655124e6a7c86c4a06f7
1 #ifndef ACE_TOKENIZER_T_CPP
2 #define ACE_TOKENIZER_T_CPP
4 #include "ace/ACE.h"
5 #include "ace/Malloc_Base.h"
6 #include "ace/String_Base.h"
7 #include "ace/OS_NS_string.h"
9 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
11 template <class ACE_CHAR_T>
12 ACE_Tokenizer_T<ACE_CHAR_T>::ACE_Tokenizer_T (ACE_CHAR_T *buffer)
13 : buffer_ (buffer),
14 index_ (0),
15 preserves_index_ (0),
16 delimiter_index_ (0)
20 template <class ACE_CHAR_T>
21 int
22 ACE_Tokenizer_T<ACE_CHAR_T>::delimiter (ACE_CHAR_T d)
24 if (delimiter_index_ == MAX_DELIMITERS)
25 return -1;
27 delimiters_[delimiter_index_].delimiter_ = d;
28 delimiters_[delimiter_index_].replace_ = 0;
29 ++delimiter_index_;
30 return 0;
33 template <class ACE_CHAR_T>
34 int
35 ACE_Tokenizer_T<ACE_CHAR_T>::delimiter_replace (ACE_CHAR_T d,
36 ACE_CHAR_T replacement)
38 // Make it possible to replace delimiters on-the-fly, e.g., parse
39 // string until certain token count and then copy rest of the
40 // original string.
41 for (int i = 0; i < delimiter_index_; i++)
42 if (delimiters_[i].delimiter_ == d)
44 delimiters_[i].replacement_ = replacement;
45 delimiters_[i].replace_ = 1;
46 return 0;
49 if (delimiter_index_ >= MAX_DELIMITERS)
50 return -1;
52 delimiters_[delimiter_index_].delimiter_ = d;
53 delimiters_[delimiter_index_].replacement_ = replacement;
54 delimiters_[delimiter_index_].replace_ = 1;
55 ++delimiter_index_;
56 return 0;
59 template <class ACE_CHAR_T>
60 int
61 ACE_Tokenizer_T<ACE_CHAR_T>::preserve_designators (ACE_CHAR_T start,
62 ACE_CHAR_T stop,
63 int strip)
65 if (preserves_index_ == MAX_PRESERVES)
66 return -1;
68 preserves_[preserves_index_].start_ = start;
69 preserves_[preserves_index_].stop_ = stop;
70 preserves_[preserves_index_].strip_ = strip;
71 ++preserves_index_;
72 return 0;
75 template <class ACE_CHAR_T>
76 int
77 ACE_Tokenizer_T<ACE_CHAR_T>::is_delimiter (ACE_CHAR_T d,
78 int &replace,
79 ACE_CHAR_T &r)
81 replace = 0;
83 for (int x = 0; x < delimiter_index_; x++)
84 if (delimiters_[x].delimiter_ == d)
86 if (delimiters_[x].replace_)
88 r = delimiters_[x].replacement_;
89 replace = 1;
91 return 1;
94 return 0;
97 template <class ACE_CHAR_T>
98 int
99 ACE_Tokenizer_T<ACE_CHAR_T>::is_preserve_designator (ACE_CHAR_T start,
100 ACE_CHAR_T &stop,
101 int &strip)
103 for (int x = 0; x < preserves_index_; x++)
104 if (preserves_[x].start_ == start)
106 stop = preserves_[x].stop_;
107 strip = preserves_[x].strip_;
108 return 1;
111 return 0;
114 template <class ACE_CHAR_T>
115 ACE_CHAR_T *
116 ACE_Tokenizer_T<ACE_CHAR_T>::next (void)
118 // Check if the previous pass was the last one in the buffer.
119 if (index_ == -1)
121 index_ = 0;
122 return 0;
125 // Check if a buffer has been passed
126 if (!buffer_)
128 return 0;
131 ACE_CHAR_T replacement = 0;
132 int replace;
133 ACE_CHAR_T *next_token = 0;
135 // Skip all leading delimiters.
136 for (;;)
138 // Check for end of string.
139 if (buffer_[index_] == '\0')
141 // If we hit EOS at the start, return 0.
142 index_ = 0;
143 return 0;
146 if (this->is_delimiter (buffer_[index_],
147 replace,
148 replacement))
149 ++index_;
150 else
151 break;
154 // When we reach this point, buffer_[index_] is a non-delimiter and
155 // not EOS - the start of our next_token.
156 next_token = buffer_ + index_;
158 // A preserved region is it's own token.
159 ACE_CHAR_T stop;
160 int strip;
161 if (this->is_preserve_designator (buffer_[index_],
162 stop,
163 strip))
165 while (++index_)
167 if (buffer_[index_] == '\0')
169 index_ = -1;
170 goto EXIT_LABEL;
173 if (buffer_[index_] == stop)
174 break;
177 if (strip)
179 // Skip start preserve designator.
180 next_token += 1;
181 // Zap the stop preserve designator.
182 buffer_[index_] = '\0';
183 // Increment to the next token.
184 ++index_;
187 goto EXIT_LABEL;
190 // Step through finding the next delimiter or EOS.
191 for (;;)
193 // Advance pointer.
194 ++index_;
196 // Check for delimiter.
197 if (this->is_delimiter (buffer_[index_],
198 replace,
199 replacement))
201 // Replace the delimiter.
202 if (replace != 0)
203 buffer_[index_] = replacement;
205 // Move the pointer up and return.
206 ++index_;
207 goto EXIT_LABEL;
210 // A preserve designator is NESTED inside this token
211 // We can't strip such preserve designators, just skip
212 // over them so that delimiters nested within arn't seen.
213 if (this->is_preserve_designator (buffer_[index_],
214 stop,
215 strip))
217 ++index_; // Skip starting preserve_designator
218 while (('\0' != buffer_[index_]) && (stop != buffer_[index_]))
219 ++index_; // Skip enclosed character
222 // Check for end of string.
223 if (buffer_[index_] == '\0')
225 index_ = -1;
226 goto EXIT_LABEL;
230 EXIT_LABEL:
231 return next_token;
234 // *************************************************************
237 ACE_END_VERSIONED_NAMESPACE_DECL
239 #endif /* ACE_TOKENIZER_T_CPP */