Subversion Repositories public

Rev

Rev 45 | Rev 67 | Go to most recent revision | 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
 *
8
 * Copyright (C) 2006 Lukas Jelinek, <lukas@aiken.cz>
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
{
45 luk 100
  for (SIZE i=m_pos; i<m_len; i++) {
101
    if (m_str[i] == m_cDelim) {
55 luk 102
      rToken = m_str.substr(m_pos, i - m_pos);
45 luk 103
      m_pos = i + 1;
55 luk 104
      return;
45 luk 105
    }    
106
  }
107
 
55 luk 108
  rToken = m_str.substr(m_pos);
45 luk 109
  m_pos = m_len;
110
}
55 luk 111
 
112
void StringTokenizer::_GetNextTokenWithPrefix(std::string& rToken)
113
{
114
  int pref = 0;
115
  for (SIZE i=m_pos; i<m_len; i++) {
116
    if (m_str[i] == m_cDelim) {
117
      if (pref == 0) {
118
        rToken = m_str.substr(m_pos, i - m_pos);
119
        m_pos = i + 1;
120
        return;
121
      }
122
      else {
123
        pref = 0;
124
      }
125
    }
126
    else if (m_str[i] == m_cPrefix) {
127
      if (pref == 1)
128
        pref = 0;
129
      else
130
        pref = 1;
131
    }
132
    else {
133
      pref = 0;
134
    }
135
  }
136
 
137
  rToken = m_str.substr(m_pos);
138
  m_pos = m_len;
139
}
140