blob: 96ba6c4f1f63adce8433150bacbf3203610d4fbe [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "StringTokenizer.h"
#include <decaf/util/NoSuchElementException.h>
using namespace std;
using namespace decaf;
using namespace decaf::util;
using namespace decaf::lang;
using namespace decaf::lang::exceptions;
////////////////////////////////////////////////////////////////////////////////
StringTokenizer::StringTokenizer(const std::string& str, const std::string& delim, bool returnDelims) :
str(str), delim(delim), pos(0), returnDelims(returnDelims) {
}
////////////////////////////////////////////////////////////////////////////////
StringTokenizer::~StringTokenizer() {
}
////////////////////////////////////////////////////////////////////////////////
int StringTokenizer::countTokens() const {
int count = 0;
string::size_type localPos = pos;
string::size_type lastPos = pos;
while (localPos != string::npos) {
if (returnDelims && str.find_first_of(delim, localPos) == localPos) {
count += 1;
localPos += 1;
continue;
}
// Find first token by spanning the fist non-delimiter, to the
// next delimiter, skipping any delimiters that are at the curret
// location.
lastPos = str.find_first_not_of(delim, localPos);
localPos = str.find_first_of(delim, lastPos);
if (lastPos != string::npos) {
count++;
}
}
return count;
}
////////////////////////////////////////////////////////////////////////////////
bool StringTokenizer::hasMoreTokens() const {
string::size_type nextpos = returnDelims ? str.find_first_of(delim, pos) : str.find_first_not_of(delim, pos);
return (nextpos != string::npos);
}
////////////////////////////////////////////////////////////////////////////////
std::string StringTokenizer::nextToken() {
if (pos == string::npos) {
throw NoSuchElementException(__FILE__, __LINE__, "StringTokenizer::nextToken - No more Tokens available");
}
if (returnDelims) {
// if char at current pos is a delim return it and advance pos
if (str.find_first_of(delim, pos) == pos) {
return str.substr(pos++, 1);
}
}
// Skip delimiters at beginning.
string::size_type lastPos = str.find_first_not_of(delim, pos);
// Find the next delimiter in the string, the charactors in between
// will be the token to return. If this returns string::npos then
// there are no more delimiters in the string.
pos = str.find_first_of(delim, lastPos);
if (string::npos != lastPos) {
// Found a token, count it, if the pos of the next delim is npos
// then we set length to copy to npos so that all the remianing
// portion of the string is copied, otherwise we set it to the
return str.substr(lastPos, pos == string::npos ? pos : pos - lastPos);
} else {
throw NoSuchElementException(__FILE__, __LINE__, "StringTokenizer::nextToken - No more Tokens available");
}
}
////////////////////////////////////////////////////////////////////////////////
std::string StringTokenizer::nextToken(const std::string& delim) {
this->delim = delim;
return nextToken();
}
////////////////////////////////////////////////////////////////////////////////
unsigned int StringTokenizer::toArray(std::vector<std::string>& array) {
int count = 0;
while (hasMoreTokens()) {
array.push_back(nextToken());
count++;
}
return count;
}
////////////////////////////////////////////////////////////////////////////////
void StringTokenizer::reset(const std::string& str, const std::string& delim, bool returnDelims) {
if (str != "") {
this->str = str;
}
if (delim != "") {
this->delim = delim;
}
this->returnDelims = returnDelims;
// Begin at the Beginning
this->pos = 0;
}