Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/shared_lib/src/lib/util/substring.cc @ 8502

Last change on this file since 8502 was 7221, checked in by bensch, 19 years ago

orxonox/trunk: merged the std-branche back, it runs on windows and Linux

svn merge https://svn.orxonox.net/orxonox/branches/std . -r7202:HEAD

File size: 7.2 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
29/**
30 *  breaks a string into parts that were initially seperated by comma
31 * @param string the string to break into substrings
32*/
33
34#include "substring.h"
35
36#include <string.h>
37#include <cassert>
38
39SubString::SubString(const std::string& string, char splitter)
40{
41  char split[2];
42  split[0] = splitter;
43  split[1] = '\0';
44  SubString::splitLine(this->strings, this->offsets,
45                       string, split);
46}
47
48/**
49 * Splits a String into a Substring removing all whiteSpaces
50 * @param string the String to Split
51 * @param whiteSpaces MUST BE __TRUE__
52 *
53 */
54SubString::SubString(const std::string& string, bool whiteSpaces)
55{
56  SubString::splitLine(this->strings, this->offsets,
57                      string);
58}
59SubString::SubString(const std::string& string, const std::string& splitters, char escapeChar,char safemode_char, char comment_char)
60{
61  SubString::splitLine(this->strings, this->offsets,
62                       string, splitters, escapeChar, safemode_char);
63}
64
65/**
66 * An empty String
67 */
68const std::string SubString::emptyString = "";
69
70
71
72unsigned int SubString::split(const std::string& string, char splitter)
73{
74  this->offsets.clear();
75  this->strings.clear();
76  char split[2];
77  split[0] = splitter;
78  split[1] = '\0';
79  SubString::splitLine(this->strings, this->offsets, string, split);
80  return strings.size();
81}
82
83
84/**
85 * Splits a String into a Substring removing all whiteSpaces
86 * @param string the String to Split
87 * @param whiteSpaces MUST BE __TRUE__
88 *
89 */
90unsigned int SubString::split(const std::string& string, bool whiteSpaces)
91{
92  this->offsets.clear();
93  this->strings.clear();
94  SubString::splitLine(this->strings, this->offsets, string);
95  return strings.size();
96}
97
98unsigned int SubString::split(const std::string& string, const std::string& splitters, char escapeChar,char safemode_char, char comment_char)
99{
100  this->offsets.clear();
101  this->strings.clear();
102  SubString::splitLine(this->strings, this->offsets,
103                       string, splitters, escapeChar, safemode_char);
104  return strings.size();
105}
106
107
108/**
109 * @brief splits line into tokens and stores them in ret.
110 * @param ret the Array, where the Splitted strings will be stored in
111 * @param offsets an Array of Offsets, here the distance from the inputstring
112 * to the beginning of the current token is stored
113 * @param line the inputLine to split
114 * @param delimiters a String of Delimiters (here the input will be splitted)
115 * @param escape_char: Escape carater (escapes splitters)
116 * @param safemode_char: the beginning of the safemode is marked with this
117 * @param comment_char: the beginning of a comment is marked with this: (until the end of a Line)
118 * @param start_state: the Initial state on how to parse the String.
119 * @returns SPLIT_LINE_STATE the parser was in when returning
120 *
121 * Supports delimiters, escape characters,
122 * ignores special  characters between safemode_char and between comment_char and linend '\n'.
123 *
124 */
125SPLIT_LINE_STATE SubString::splitLine(std::vector<std::string>& ret, std::vector<unsigned int>& offsets,
126                                      const std::string& line, const std::string& delimiters,
127                                      char escape_char, char safemode_char, char comment_char,
128                                      SPLIT_LINE_STATE start_state)
129{
130  SPLIT_LINE_STATE state = start_state;
131  unsigned int i = 0;
132  std::string token;
133
134  if(start_state != SL_NORMAL && ret.size() > 0)
135  {
136    token = ret[ret.size()-1];
137    ret.pop_back();
138  }
139
140  while(i < line.size())
141  {
142    switch(state)
143    {
144    case SL_NORMAL:
145      if(line[i] == escape_char)
146      {
147        state = SL_ESCAPE;
148      }
149      else if(line[i] == safemode_char)
150      {
151        state = SL_SAFEMODE;
152      }
153      else if(line[i] == comment_char)
154      {
155        /// FINISH
156        if(token.size() > 0)
157        {
158          ret.push_back(token);
159          offsets.push_back(i);
160          token.clear();
161        }
162        token += line[i];       // EAT
163        state = SL_COMMENT;
164      }
165      else if(delimiters.find(line[i]) != std::string::npos)
166      {
167        // line[i] is a delimiter
168        /// FINISH
169        if(token.size() > 0)
170        {
171          ret.push_back(token);
172          offsets.push_back(i);
173          token.clear();
174        }
175      }
176      else
177      {
178        token += line[i];       // EAT
179      }
180      break;
181    case SL_ESCAPE:
182      if(line[i] == 'n') token += '\n';
183      else if(line[i] == 't') token += '\t';
184      else if(line[i] == 'v') token += '\v';
185      else if(line[i] == 'b') token += '\b';
186      else if(line[i] == 'r') token += '\r';
187      else if(line[i] == 'f') token += '\f';
188      else if(line[i] == 'a') token += '\a';
189      else if(line[i] == '?') token += '\?';
190      else token += line[i];  // EAT
191      state = SL_NORMAL;
192      break;
193    case SL_SAFEMODE:
194      if(line[i] == safemode_char)
195      {
196        state = SL_NORMAL;
197      }
198      else if(line[i] == escape_char)
199      {
200        state = SL_SAFEESCAPE;
201      }
202      else
203      {
204        token += line[i];       // EAT
205      }
206      break;
207    case SL_SAFEESCAPE:
208      if(line[i] == 'n') token += '\n';
209      else if(line[i] == 't') token += '\t';
210      else if(line[i] == 'v') token += '\v';
211      else if(line[i] == 'b') token += '\b';
212      else if(line[i] == 'r') token += '\r';
213      else if(line[i] == 'f') token += '\f';
214      else if(line[i] == 'a') token += '\a';
215      else if(line[i] == '?') token += '\?';
216      else token += line[i];  // EAT
217      state = SL_SAFEMODE;
218      break;
219    case SL_COMMENT:
220      if(line[i] == '\n')
221      {
222        /// FINISH
223        if(token.size() > 0)
224        {
225          ret.push_back(token);
226          offsets.push_back(i);
227          token.clear();
228        }
229        state = SL_NORMAL;
230      }
231      else
232      {
233        token += line[i];       // EAT
234      }
235      break;
236    default:
237      // nothing
238      break;
239    }
240    i++;
241  }
242
243  /// FINISH
244  if(token.size() > 0)
245  {
246    ret.push_back(token);
247    offsets.push_back(i);
248    token.clear();
249  }
250  return(state);
251}
252
253/**
254 *  removes the object from memory
255*/
256SubString::~SubString()
257{ }
258
259/**
260 * get a particular substring's offset
261 * @param i the ID of the substring to get the offset from
262 * @returns the offset or NULL if an invalid ID was given
263 */
264unsigned int SubString::getOffset(unsigned int i)
265{
266  if( i < this->offsets.size() && i >= 0)
267    return this->offsets[i];
268  else
269    return 0;
270}
271
272/**
273 * Some nice debug information about this SubString
274 */
275void SubString::debug() const
276{
277  printf("Substring-information::count=%d ::", this->strings.size());
278  for (unsigned int i = 0; i < this->strings.size(); i++)
279    printf("s%d='%s'::", i, this->strings[i].c_str());
280  printf("\n");
281}
Note: See TracBrowser for help on using the repository browser.