Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/network/src/lib/util/substring.cc @ 7913

Last change on this file since 7913 was 7325, checked in by bensch, 19 years ago

helpers

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