Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/std/src/lib/util/substring.cc @ 7212

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

should be better, but hey…. its late

File size: 6.5 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
66unsigned int SubString::split(const std::string& string, char splitter)
67{
68  this->offsets.clear();
69  this->strings.clear();
70  char split[2];
71  split[0] = splitter;
72  split[1] = '\0';
73  SubString::splitLine(this->strings, this->offsets, string, split);
74  return strings.size();
75}
76
77
78/**
79 * Splits a String into a Substring removing all whiteSpaces
80 * @param string the String to Split
81 * @param whiteSpaces MUST BE __TRUE__
82 *
83 */
84unsigned int SubString::split(const std::string& string, bool whiteSpaces)
85{
86  this->offsets.clear();
87  this->strings.clear();
88  SubString::splitLine(this->strings, this->offsets, string);
89  return strings.size();
90}
91
92unsigned int SubString::split(const std::string& string, const std::string& splitters, char escapeChar,char safemode_char, char comment_char)
93{
94  this->offsets.clear();
95  this->strings.clear();
96  SubString::splitLine(this->strings, this->offsets,
97                       string, splitters, escapeChar, safemode_char);
98  return strings.size();
99}
100
101
102/**
103 * splits line into tokens and stores them in ret. Supports delimiters, escape characters,
104 * ignores special  characters between safemode_char and between comment_char and linend '\n'.
105 *
106 * @returns SPLIT_LINE_STATE the parser was in when returning
107 */
108SPLIT_LINE_STATE SubString::splitLine(std::vector<std::string>& ret, std::vector<unsigned int>& offsets,
109                                      const std::string& line, const std::string& delimiters,
110                                      char escape_char, char safemode_char, char comment_char,
111                                      SPLIT_LINE_STATE start_state)
112{
113  SPLIT_LINE_STATE state = start_state;
114  unsigned int i = 0;
115  std::string token;
116
117  if(start_state != SL_NORMAL && ret.size() > 0)
118  {
119    token = ret[ret.size()-1];
120    ret.pop_back();
121  }
122
123  while(i < line.size())
124  {
125    switch(state)
126    {
127    case SL_NORMAL:
128      if(line[i] == escape_char)
129      {
130        state = SL_ESCAPE;
131      }
132      else if(line[i] == safemode_char)
133      {
134        state = SL_SAFEMODE;
135      }
136      else if(line[i] == comment_char)
137      {
138        /// FINISH
139        if(token.size() > 0)
140        {
141          ret.push_back(token);
142          offsets.push_back(i);
143          token.clear();
144        }
145        token += line[i];       // EAT
146        state = SL_COMMENT;
147      }
148      else if(delimiters.find(line[i]) != std::string::npos)
149      {
150        // line[i] is a delimiter
151        /// FINISH
152        if(token.size() > 0)
153        {
154          ret.push_back(token);
155          offsets.push_back(i);
156          token.clear();
157        }
158      }
159      else
160      {
161        token += line[i];       // EAT
162      }
163      break;
164    case SL_ESCAPE:
165      if(line[i] == 'n') token += '\n';
166      else if(line[i] == 't') token += '\t';
167      else if(line[i] == 'v') token += '\v';
168      else if(line[i] == 'b') token += '\b';
169      else if(line[i] == 'r') token += '\r';
170      else if(line[i] == 'f') token += '\f';
171      else if(line[i] == 'a') token += '\a';
172      else if(line[i] == '?') token += '\?';
173      else token += line[i];  // EAT
174      state = SL_NORMAL;
175      break;
176    case SL_SAFEMODE:
177      if(line[i] == safemode_char)
178      {
179        state = SL_NORMAL;
180      }
181      else if(line[i] == escape_char)
182      {
183        state = SL_SAFEESCAPE;
184      }
185      else
186      {
187        token += line[i];       // EAT
188      }
189      break;
190    case SL_SAFEESCAPE:
191      if(line[i] == 'n') token += '\n';
192      else if(line[i] == 't') token += '\t';
193      else if(line[i] == 'v') token += '\v';
194      else if(line[i] == 'b') token += '\b';
195      else if(line[i] == 'r') token += '\r';
196      else if(line[i] == 'f') token += '\f';
197      else if(line[i] == 'a') token += '\a';
198      else if(line[i] == '?') token += '\?';
199      else token += line[i];  // EAT
200      state = SL_SAFEMODE;
201      break;
202    case SL_COMMENT:
203      if(line[i] == '\n')
204      {
205        /// FINISH
206        if(token.size() > 0)
207        {
208          ret.push_back(token);
209          offsets.push_back(i);
210          token.clear();
211        }
212        state = SL_NORMAL;
213      }
214      else
215      {
216        token += line[i];       // EAT
217      }
218      break;
219    default:
220      // nothing
221      break;
222    }
223    i++;
224  }
225
226  /// FINISH
227  if(token.size() > 0)
228  {
229    ret.push_back(token);
230    offsets.push_back(i);
231    token.clear();
232  }
233  return(state);
234}
235
236/**
237 *  removes the object from memory
238*/
239SubString::~SubString()
240{ }
241
242/**
243 * get a particular substring's offset
244 * @param i the ID of the substring to get the offset from
245 * @returns the offset or NULL if an invalid ID was given
246 */
247unsigned int SubString::getOffset(unsigned int i)
248{
249  if( i < this->offsets.size() && i >= 0)
250    return this->offsets[i];
251  else
252    return 0;
253}
254
255/**
256 * Some nice debug information about this SubString
257 */
258void SubString::debug() const
259{
260  printf("Substring-information::count=%d ::", this->strings.size());
261  for (unsigned int i = 0; i < this->strings.size(); i++)
262    printf("s%d='%s'::", i, this->strings[i].c_str());
263  printf("\n");
264}
Note: See TracBrowser for help on using the repository browser.