| /* |
| * 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" |
| |
| 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 ) { |
| // store off the data |
| this->str = str; |
| this->delim = delim; |
| this->returnDelims = returnDelims; |
| |
| // Start and the beginning |
| pos = 0; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| 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() |
| throw ( lang::exceptions::NoSuchElementException ) |
| { |
| 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 ) |
| throw ( lang::exceptions::NoSuchElementException ) { |
| |
| 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; |
| } |