Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/trunk/src/lib/util/substring.cc @ 7321

Last change on this file since 7321 was 7321, checked in by bensch, 18 years ago

orxonox/trunk: fixed minor bug

File size: 10.9 KB
Line 
1/*
2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2004 orx
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10
11   ### File Specific:
12   main-programmer: Christian Meyer
13   co-programmer: Benjamin Grauer
14
15   2005-06-10: some naming conventions
16
17//
18//  splitLine
19//  STL string tokenizer
20//
21//  Created by Clemens Wacha.
22//  Version 1.0
23//  Copyright (c) 2005 Clemens Wacha. All rights reserved.
24//
25
26*/
27
28#include "substring.h"
29
30#include <string.h>
31#include <cassert>
32
33/**
34 * @brief create a SubString from
35 * @param string the String to Spilit
36 * @param splitter the Character at which to split string (delimiter)
37 */
38SubString::SubString(const std::string& string, char splitter)
39{
40  char split[2];
41  split[0] = splitter;
42  split[1] = '\0';
43  SubString::splitLine(this->strings, string, split);
44}
45
46/**
47 * @brief Splits a String into a SubString removing all whiteSpaces
48 * @param string the String to Split
49 * @param whiteSpaces MUST BE __TRUE__ or __FALSE__ (will be ignored)
50 */
51SubString::SubString(const std::string& string, bool whiteSpaces)
52{
53  SubString::splitLine(this->strings, string);
54}
55
56/**
57 * @brief Splits a String into multiple splitters.
58 * @param string the String to split
59 * @param splitters multiple set of characters at what to split. (delimiters)
60 * @param escapeChar The Escape Character that overrides splitters commends and so on...
61 * @param safemode_char within these characters splitting won't happen
62 * @param comment_char the Comment character.
63 */
64SubString::SubString(const std::string& string, const std::string& splitters, char escapeChar,char safemode_char, char comment_char)
65{
66  SubString::splitLine(this->strings, string, splitters, escapeChar, safemode_char, comment_char);
67}
68
69/**
70 * @brief creates a SubSet of a SubString.
71 * @param subString the SubString to take a set from.
72 * @param subSetBegin the beginning to the end
73 */
74SubString::SubString(const SubString& subString, unsigned int subSetBegin)
75{
76  for (unsigned int i = subSetBegin; i < subString.size(); i++)
77    this->strings.push_back(subString[i]);
78}
79
80
81/**
82 * @brief creates a SubSet of a SubString.
83 * @param subString the SubString to take a Set from
84 * @param subSetBegin the beginning to the end
85 * @param subSetEnd the end of the SubSet (max subString.size() will be checked internaly)
86 */
87SubString::SubString(const SubString& subString, unsigned int subSetBegin, unsigned int subSetEnd)
88{
89  for (unsigned int i = subSetBegin; i < subString.size() || i < subSetEnd; i++)
90    this->strings.push_back(subString[i]);
91}
92
93
94/**
95 * @brief removes the object from memory
96 */
97SubString::~SubString()
98{ }
99
100/**
101 * @brief An empty String
102 */
103const std::string SubString::emptyString = "";
104
105/**
106 * @brief stores the Value of subString in this SubString
107 * @param subString will be copied into this String.
108 * @returns this SubString.
109 */
110SubString& SubString::operator=(const SubString& subString)
111{
112  this->strings = subString.strings;
113  return *this;
114}
115
116
117/**
118 * @brief comparator.
119 * @param subString the SubString to compare against this one.
120 * @returns true if the Stored Strings match
121 */
122bool SubString::operator==(const SubString& subString)
123{
124  return (this->strings == subString.strings);
125}
126
127
128/**
129 * @brief append operator
130 * @param subString the String to append.
131 * @returns a SubString where this and subString are appended.
132 */
133SubString SubString::operator+(const SubString& subString) const
134{
135  return SubString(subString) += subString;
136}
137
138
139/**
140 * @brief append operator.
141 * @param subString append subString to this SubString.
142 * @returns this substring appended with subString
143 */
144SubString& SubString::operator+=(const SubString& subString)
145{
146  for (unsigned int i = 0; i < subString.size(); i++)
147    this->strings.push_back(subString[i]);
148}
149
150
151/**
152 * @brief Split the String at
153 * @param string where to split
154 * @param splitter delimiter.
155 */
156unsigned int SubString::split(const std::string& string, char splitter)
157{
158  this->strings.clear();
159  char split[2];
160  split[0] = splitter;
161  split[1] = '\0';
162  SubString::splitLine(this->strings, string, split);
163  return strings.size();
164}
165
166
167/**
168 * @brief Splits a String into a Substring removing all whiteSpaces
169 * @param string the String to Split
170 * @param whiteSpaces MUST BE __TRUE__
171 *
172 */
173unsigned int SubString::split(const std::string& string, bool whiteSpaces)
174{
175  this->strings.clear();
176  SubString::splitLine(this->strings, string);
177  return strings.size();
178}
179
180
181/**
182 * @brief Splits a String into multiple splitters.
183 * @param string the String to split
184 * @param splitters multiple set of characters at what to split. (delimiters)
185 * @param escapeChar The Escape Character that overrides splitters commends and so on...
186 * @param safemode_char within these characters splitting won't happen
187 * @param comment_char the Comment character.
188 */
189unsigned int SubString::split(const std::string& string, const std::string& splitters, char escapeChar,char safemode_char, char comment_char)
190{
191  this->strings.clear();
192  SubString::splitLine(this->strings, string, splitters, escapeChar, safemode_char);
193  return strings.size();
194}
195
196
197/**
198 * @brief joins together all Strings of this Substring.
199 * @param delimiter the String between the subStrings.
200 * @returns the joined String.
201 */
202std::string SubString::join(const std::string& delimiter) const
203{
204  if (!this->strings.empty())
205  {
206    std::string retVal = this->strings[0];
207    for (unsigned int i = 1; i < this->strings.size(); i++)
208      retVal += delimiter + this->strings[i];
209    return retVal;
210  }
211  else
212    return SubString::emptyString;
213}
214
215
216/**
217 * @brief creates a SubSet of a SubString.
218 * @param subSetBegin the beginning to the end
219 * @returns the SubSet
220 *
221 * This function is added for your convenience, and does the same as
222 * SubString::SubString(const SubString& subString, unsigned int subSetBegin)
223 */
224SubString SubString::getSubSet(unsigned int subSetBegin) const
225{
226  return SubString(*this, subSetBegin);
227}
228
229
230/**
231 * @brief creates a SubSet of a SubString.
232 * @param subSetBegin the beginning to
233 * @param subSetEnd the end of the SubSet to select (if bigger than subString.size() it will be downset.)
234 * @returns the SubSet
235 *
236 * This function is added for your convenience, and does the same as
237 * SubString::SubString(const SubString& subString, unsigned int subSetBegin)
238 */
239SubString SubString::getSubSet(unsigned int subSetBegin, unsigned int subSetEnd) const
240{
241  return SubString(*this, subSetBegin, subSetEnd);
242}
243
244
245/**
246 * @brief splits line into tokens and stores them in ret.
247 * @param ret the Array, where the Splitted strings will be stored in
248 * @param offsets an Array of Offsets, here the distance from the inputstring
249 * to the beginning of the current token is stored
250 * @param line the inputLine to split
251 * @param delimiters a String of Delimiters (here the input will be splitted)
252 * @param escape_char: Escape carater (escapes splitters)
253 * @param safemode_char: the beginning of the safemode is marked with this
254 * @param comment_char: the beginning of a comment is marked with this: (until the end of a Line)
255 * @param start_state: the Initial state on how to parse the String.
256 * @returns SPLIT_LINE_STATE the parser was in when returning
257 *
258 * This is the Actual Splitting Algorithm from Clemens Wacha
259 * Supports delimiters, escape characters,
260 * ignores special  characters between safemode_char and between comment_char and linend '\n'.
261 *
262 */
263SPLIT_LINE_STATE SubString::splitLine(std::vector<std::string>& ret,
264                                      const std::string& line,
265                                      const std::string& delimiters,
266                                      char escape_char,
267                                      char safemode_char,
268                                      char comment_char,
269                                      SPLIT_LINE_STATE start_state)
270{
271  SPLIT_LINE_STATE state = start_state;
272  unsigned int i = 0;
273  std::string token;
274
275  if(start_state != SL_NORMAL && ret.size() > 0)
276  {
277    token = ret[ret.size()-1];
278    ret.pop_back();
279  }
280
281  while(i < line.size())
282  {
283    switch(state)
284    {
285      case SL_NORMAL:
286        if(line[i] == escape_char)
287        {
288          state = SL_ESCAPE;
289        }
290        else if(line[i] == safemode_char)
291        {
292          state = SL_SAFEMODE;
293        }
294        else if(line[i] == comment_char)
295        {
296          /// FINISH
297          if(token.size() > 0)
298          {
299            ret.push_back(token);
300            token.clear();
301          }
302          token += line[i];       // EAT
303          state = SL_COMMENT;
304        }
305        else if(delimiters.find(line[i]) != std::string::npos)
306        {
307          // line[i] is a delimiter
308          /// FINISH
309          if(token.size() > 0)
310          {
311            ret.push_back(token);
312            token.clear();
313          }
314        }
315        else
316        {
317          token += line[i];       // EAT
318        }
319        break;
320      case SL_ESCAPE:
321        if(line[i] == 'n') token += '\n';
322        else if(line[i] == 't') token += '\t';
323        else if(line[i] == 'v') token += '\v';
324        else if(line[i] == 'b') token += '\b';
325        else if(line[i] == 'r') token += '\r';
326        else if(line[i] == 'f') token += '\f';
327        else if(line[i] == 'a') token += '\a';
328        else if(line[i] == '?') token += '\?';
329        else token += line[i];  // EAT
330        state = SL_NORMAL;
331        break;
332      case SL_SAFEMODE:
333        if(line[i] == safemode_char)
334        {
335          state = SL_NORMAL;
336        }
337        else if(line[i] == escape_char)
338        {
339          state = SL_SAFEESCAPE;
340        }
341        else
342        {
343          token += line[i];       // EAT
344        }
345        break;
346      case SL_SAFEESCAPE:
347        if(line[i] == 'n') token += '\n';
348        else if(line[i] == 't') token += '\t';
349        else if(line[i] == 'v') token += '\v';
350        else if(line[i] == 'b') token += '\b';
351        else if(line[i] == 'r') token += '\r';
352        else if(line[i] == 'f') token += '\f';
353        else if(line[i] == 'a') token += '\a';
354        else if(line[i] == '?') token += '\?';
355        else token += line[i];  // EAT
356        state = SL_SAFEMODE;
357        break;
358      case SL_COMMENT:
359        if(line[i] == '\n')
360        {
361          /// FINISH
362          if(token.size() > 0)
363          {
364            ret.push_back(token);
365            token.clear();
366          }
367          state = SL_NORMAL;
368        }
369        else
370        {
371          token += line[i];       // EAT
372        }
373        break;
374      default:
375        // nothing
376        break;
377    }
378    i++;
379  }
380
381  /// FINISH
382  if(token.size() > 0)
383  {
384    ret.push_back(token);
385    token.clear();
386  }
387  return(state);
388}
389
390
391/**
392 * @brief Some nice debug information about this SubString
393 */
394void SubString::debug() const
395{
396  printf("Substring-information::count=%d ::", this->strings.size());
397  for (unsigned int i = 0; i < this->strings.size(); i++)
398    printf("s%d='%s'::", i, this->strings[i].c_str());
399  printf("\n");
400}
Note: See TracBrowser for help on using the repository browser.