Project

General

Profile

Statistics
| Branch: | Revision:

root / src / sim / cstringtokenizer.cc @ a3be1d55

History | View | Annotate | Download (3.56 KB)

1
//==========================================================================
2
//  CSTRTOKENIZER.CC - part of
3
//                     OMNeT++/OMNEST
4
//            Discrete System Simulation in C++
5
//
6
//
7
//  Declaration of the following classes:
8
//    cStringTokenizer  : string tokenizer utility class
9
//
10
//==========================================================================
11

    
12
/*--------------------------------------------------------------*
13
  Copyright (C) 1992-2008 Andras Varga
14
  Copyright (C) 2006-2008 OpenSim Ltd.
15

16
  This file is distributed WITHOUT ANY WARRANTY. See the file
17
  `license' for details on this and other legal matters.
18
*--------------------------------------------------------------*/
19

    
20
#include <stdlib.h>
21
#include <errno.h>
22
#include <limits.h>  //LONG_MAX
23
#include <locale.h>
24
#include "cstringtokenizer.h"
25
#include "cexception.h"
26

    
27
USING_NAMESPACE
28

    
29

    
30
cStringTokenizer::cStringTokenizer(const char *s, const char *delim)
31
{
32
    if (!s)
33
        s = "";
34
    if (!delim || !*delim)
35
        delim = " \t\n\r\f";
36
    delimiter = delim;
37
    str = new char[strlen(s)+1];
38
    strcpy(str,s);
39
    rest = str;
40
}
41

    
42
cStringTokenizer::cStringTokenizer(const cStringTokenizer& other)
43
{
44
    str = NULL;
45
    operator=(other);
46
}
47

    
48
cStringTokenizer::~cStringTokenizer()
49
{
50
    delete [] str;
51
}
52

    
53
cStringTokenizer& cStringTokenizer::operator=(const cStringTokenizer& other)
54
{
55
    if (this == &other)
56
        return *this;
57

    
58
    delimiter = other.delimiter;
59
    delete [] str;
60
    size_t len = (other.rest - other.str) + strlen(other.rest);
61
    str = new char[len+1];
62
    memcpy(str, other.str, len+1);
63
    rest = str + (other.rest - other.str);
64
    return *this;
65
}
66

    
67
void cStringTokenizer::setDelimiter(const char *delim)
68
{
69
    if (!delim || !*delim)
70
        delim = " ";
71
    delimiter = delim;
72
}
73

    
74
inline void skipDelimiters(char *&s, const char *delims)
75
{
76
    while (*s && strchr(delims, *s)!=NULL) s++;
77
}
78

    
79
inline void skipToken(char *&s, const char *delims)
80
{
81
    while (*s && strchr(delims, *s)==NULL) s++;
82
}
83

    
84
const char *cStringTokenizer::nextToken()
85
{
86
    skipDelimiters(rest, delimiter.c_str());
87
    if (!*rest) return NULL;
88
    const char *token = rest;
89
    skipToken(rest, delimiter.c_str());
90
    if (*rest)
91
        *rest++ = '\0';
92
    return token;
93
}
94

    
95
bool cStringTokenizer::hasMoreTokens()
96
{
97
    skipDelimiters(rest, delimiter.c_str());
98
    return *rest;
99
}
100

    
101
std::vector<std::string> cStringTokenizer::asVector()
102
{
103
    const char *s;
104
    std::vector<std::string> v;
105
    while ((s=nextToken())!=NULL)
106
        v.push_back(std::string(s));
107
    return v;
108
}
109

    
110
std::vector<int> cStringTokenizer::asIntVector()
111
{
112
    const char *s;
113
    std::vector<int> v;
114
    while ((s=nextToken())!=NULL)
115
    {
116
        char *e;
117
        long d = strtol(s, &e, 10);
118
        if (*e)
119
            throw cRuntimeError("Converting string to a vector of ints: error at token '%s'", s);
120
        if ((int)d != d || (errno==ERANGE && (d==LONG_MAX || d==LONG_MIN)))
121
            throw cRuntimeError("Converting string to a vector of ints: '%s' does not fit into an int", s);
122
        v.push_back((int)d);
123
    }
124
    return v;
125
}
126

    
127
std::vector<double> cStringTokenizer::asDoubleVector()
128
{
129
    const char *s;
130
    std::vector<double> v;
131
    setlocale(LC_NUMERIC, "C");
132
    while ((s=nextToken())!=NULL)
133
    {
134
        char *e;
135
        double d = strtod(s, &e);
136
        if (*e)
137
            throw cRuntimeError("Converting string to a vector of doubles: error at token '%s'", s);
138
        if (d==HUGE_VAL)
139
            throw cRuntimeError("Converting string to a vector of doubles: overflow or underflow while converting '%s' to double", s);
140
        v.push_back(d);
141
    }
142
    return v;
143
}
144

    
145