Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: evil is removed

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