| /* |
| * 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; |
| } |