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