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
RevLine 
[4597]1/*
[3941]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
[4597]13   co-programmer: Benjamin Grauer
14
15   2005-06-10: some naming conventions
[7221]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
[4220]26*/
27
28#include "substring.h"
29
30#include <string.h>
[7221]31#include <cassert>
[4220]32
[7323]33
[7319]34/**
[7323]35 * @brief default constructor
36 */
37SubString::SubString()
38{
39}
40
41
42/**
[7319]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 */
[7221]47SubString::SubString(const std::string& string, char splitter)
[4220]48{
[7221]49  char split[2];
50  split[0] = splitter;
51  split[1] = '\0';
[7320]52  SubString::splitLine(this->strings, string, split);
[7221]53}
[4597]54
[7221]55/**
[7319]56 * @brief Splits a String into a SubString removing all whiteSpaces
[7221]57 * @param string the String to Split
[7319]58 * @param whiteSpaces MUST BE __TRUE__ or __FALSE__ (will be ignored)
[7221]59 */
60SubString::SubString(const std::string& string, bool whiteSpaces)
61{
[7320]62  SubString::splitLine(this->strings, string);
[7221]63}
[7319]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 */
[7323]73SubString::SubString(const std::string& string, const std::string& splitters, char escapeChar, char safemode_char, char comment_char)
[7221]74{
[7320]75  SubString::splitLine(this->strings, string, splitters, escapeChar, safemode_char, comment_char);
[7221]76}
[4597]77
[7221]78/**
[7319]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
[7221]82 */
[7319]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 */
[7221]112const std::string SubString::emptyString = "";
[4597]113
[7319]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}
[4597]124
125
[7319]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{
[7323]144  return SubString(*this) += subString;
[7319]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]);
[7323]157  return *this;
[7319]158}
159
160
161/**
162 * @brief Split the String at
163 * @param string where to split
164 * @param splitter delimiter.
165 */
[7221]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';
[7320]172  SubString::splitLine(this->strings, string, split);
[7221]173  return strings.size();
[4220]174}
175
[5183]176
[3941]177/**
[7319]178 * @brief Splits a String into a Substring removing all whiteSpaces
[5183]179 * @param string the String to Split
180 * @param whiteSpaces MUST BE __TRUE__
181 *
182 */
[7221]183unsigned int SubString::split(const std::string& string, bool whiteSpaces)
[5183]184{
[7221]185  this->strings.clear();
[7320]186  SubString::splitLine(this->strings, string);
[7221]187  return strings.size();
188}
[5183]189
[7319]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 */
[7221]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();
[7323]202  SubString::splitLine(this->strings, string, splitters, escapeChar, safemode_char, comment_char);
203  return this->strings.size();
[7221]204}
[5183]205
206
[7221]207/**
[7319]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];
[7321]217    for (unsigned int i = 1; i < this->strings.size(); i++)
[7319]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/**
[7221]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 *
[7319]268 * This is the Actual Splitting Algorithm from Clemens Wacha
[7221]269 * Supports delimiters, escape characters,
270 * ignores special  characters between safemode_char and between comment_char and linend '\n'.
271 *
272 */
[7320]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,
[7221]279                                      SPLIT_LINE_STATE start_state)
280{
281  SPLIT_LINE_STATE state = start_state;
[5183]282  unsigned int i = 0;
[7221]283  std::string token;
[5183]284
[7221]285  if(start_state != SL_NORMAL && ret.size() > 0)
[5656]286  {
[7221]287    token = ret[ret.size()-1];
288    ret.pop_back();
[5656]289  }
290
[7221]291  while(i < line.size())
[5656]292  {
[7221]293    switch(state)
[5656]294    {
[7319]295      case SL_NORMAL:
296        if(line[i] == escape_char)
[7221]297        {
[7319]298          state = SL_ESCAPE;
[7221]299        }
[7319]300        else if(line[i] == safemode_char)
[7221]301        {
[7319]302          state = SL_SAFEMODE;
[7221]303        }
[7319]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
[7221]340        state = SL_NORMAL;
[7319]341        break;
342      case SL_SAFEMODE:
343        if(line[i] == safemode_char)
[7221]344        {
[7319]345          state = SL_NORMAL;
[7221]346        }
[7319]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;
[5656]387    }
[7221]388    i++;
[5656]389  }
390
[7221]391  /// FINISH
392  if(token.size() > 0)
[5656]393  {
[7221]394    ret.push_back(token);
395    token.clear();
[5656]396  }
[7221]397  return(state);
[5656]398}
399
[3941]400
401/**
[7319]402 * @brief Some nice debug information about this SubString
[5200]403 */
[4833]404void SubString::debug() const
405{
[7221]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");
[4833]410}
Note: See TracBrowser for help on using the repository browser.