Subversion Repositories public

Rev

Rev 67 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
45 luk 1
 
2
/// string tokenizer implementation
3
/**
4
 * \file strtok.cpp
5
 *
6
 * string tokenizer
7
 *
100 luk 8
 * Copyright (C) 2006, 2007, 2008 Lukas Jelinek, <lukas@aiken.cz>
45 luk 9
 *
10
 * This program is free software; you can redistribute it and/or
11
 * modify it under the terms of one of the following licenses:
12
 *
13
 * \li 1. X11-style license (see LICENSE-X11)
14
 * \li 2. GNU Lesser General Public License, version 2.1 (see LICENSE-LGPL)
15
 * \li 3. GNU General Public License, version 2  (see LICENSE-GPL)
16
 *
17
 * If you want to help with choosing the best license for you,
18
 * please visit http://www.gnu.org/licenses/license-list.html.
19
 *
20
 */
21
 
22
 
55 luk 23
#include <sstream>
24
 
45 luk 25
#include "strtok.h"
26
 
55 luk 27
StringTokenizer::StringTokenizer(const std::string& rStr, char cDelim, char cPrefix)
45 luk 28
{
29
  m_str = rStr;
30
  m_cDelim = cDelim;
55 luk 31
  m_cPrefix = cPrefix;
45 luk 32
  m_pos = 0;
33
  m_len = rStr.length();
34
}
35
 
55 luk 36
std::string StringTokenizer::GetNextToken(bool fSkipEmpty)
45 luk 37
{
38
  std::string s;
39
 
55 luk 40
  do {
41
    _GetNextToken(s, true);
42
  } while (fSkipEmpty && s.empty() && m_pos < m_len);
43
 
44
  return s;
45
}
46
 
47
std::string StringTokenizer::GetNextTokenRaw(bool fSkipEmpty)
48
{
49
  std::string s;
50
 
51
  do {
52
    _GetNextToken(s, false);
53
  } while (fSkipEmpty && s.empty() && m_pos < m_len);
54
 
55
  return s;
56
}
57
 
58
std::string StringTokenizer::GetRemainder()
59
{
60
  return  m_cPrefix == '\0'
61
      ?   m_str.substr(m_pos)
62
      :   StripPrefix(m_str.c_str() + m_pos, m_len - m_pos);
63
}
64
 
65
std::string StringTokenizer::StripPrefix(const char* s, SIZE cnt)
66
{
67
  std::ostringstream stream;
68
  SIZE pos = 0;
69
  while (pos < cnt) {
70
    if (s[pos] == m_cPrefix) {
71
      if ((pos < cnt - 1) && s[pos+1] == m_cPrefix) {
72
        stream << m_cPrefix;
73
        pos++;
74
      }
75
    }
76
    else {
77
      stream << s[pos];
78
    }
79
 
80
    pos++;
81
  }
82
 
83
  return stream.str();
84
}
85
 
86
void StringTokenizer::_GetNextToken(std::string& rToken, bool fStripPrefix)
87
{
88
  if (m_cPrefix == '\0') {
89
    _GetNextTokenNoPrefix(rToken);
90
  }
91
  else {
92
    _GetNextTokenWithPrefix(rToken);
93
    if (fStripPrefix)
94
      rToken = StripPrefix(rToken.c_str(), rToken.length());
95
  }
96
}
97
 
98
void StringTokenizer::_GetNextTokenNoPrefix(std::string& rToken)
99
{
67 luk 100
  const char* s = m_str.c_str();
45 luk 101
  for (SIZE i=m_pos; i<m_len; i++) {
67 luk 102
    if (s[i] == m_cDelim) {
55 luk 103
      rToken = m_str.substr(m_pos, i - m_pos);
45 luk 104
      m_pos = i + 1;
55 luk 105
      return;
45 luk 106
    }    
107
  }
108
 
55 luk 109
  rToken = m_str.substr(m_pos);
45 luk 110
  m_pos = m_len;
111
}
55 luk 112
 
113
void StringTokenizer::_GetNextTokenWithPrefix(std::string& rToken)
114
{
115
  int pref = 0;
67 luk 116
  const char* s = m_str.c_str();
55 luk 117
  for (SIZE i=m_pos; i<m_len; i++) {
67 luk 118
    if (s[i] == m_cDelim) {
55 luk 119
      if (pref == 0) {
120
        rToken = m_str.substr(m_pos, i - m_pos);
121
        m_pos = i + 1;
122
        return;
123
      }
124
      else {
125
        pref = 0;
126
      }
127
    }
67 luk 128
    else if (s[i] == m_cPrefix) {
55 luk 129
      if (pref == 1)
130
        pref = 0;
131
      else
132
        pref = 1;
133
    }
134
    else {
135
      pref = 0;
136
    }
137
  }
138
 
139
  rToken = m_str.substr(m_pos);
140
  m_pos = m_len;
141
}
142