/******************************************************************
*
*  SKALA Knowledge Project
*
*  $Id: strtok.cpp,v 1.2 2001/11/12 03:45:53 jbakus Exp $
*  $Source: /u/jbakus/cvs/skala/kr/src/strtok.cpp,v $
*  $Author: jbakus $
*  $Date: 2001/11/12 03:45:53 $
*  $Revision: 1.2 $
*
******************************************************************/

#include "cs_strtok.h"
#include <assert.h>

stringTok::stringTok (string *_str, string delim,
                        bool returnTokens)
{
        currentPosition = 0;
        str = _str;
        maxPosition = str->length ();
        delimiters = delim;
        retTokens = returnTokens;
}


stringTok::stringTok (string *_str, string delim)
{
        currentPosition = 0;
        str = _str;
        maxPosition = str->length ();
        delimiters = delim;
        retTokens = false;
}


stringTok::stringTok (string *_str)
{
        currentPosition = 0;
        str = _str;
        maxPosition = str->length ();
        delimiters = " \t\r\n";
        retTokens = false;
}

stringTok::stringTok ()
{
        currentPosition = 0;
        maxPosition = 0;
        delimiters = " \t\r\n";
        retTokens = false;
}

stringTok::~stringTok ()
{
}

void stringTok::skipDelimiters ()
{
        while (!retTokens && (currentPosition < maxPosition) &&
                   (delimiters.find((*str)[currentPosition]) != delimiters.npos)) {
                currentPosition++;
        }
}

bool stringTok::HasMoreTokens ()
{
        skipDelimiters ();
        return (currentPosition < maxPosition);
}

string stringTok::NextToken (void)
{
        int start = getStart ();
        string ret;
        ret.assign (&(*str)[start], &(*str)[currentPosition]);
        return ret;
}


bool stringTok::NextToken(string &_str)
{
        int start = getStart ();
        _str.assign (&(*str)[start], &(*str)[currentPosition]);
        return true;
}

int stringTok::getStart (void)
{
        skipDelimiters();

        assert (currentPosition < maxPosition);

        int start = currentPosition;
        while ((currentPosition < maxPosition) &&
                   (delimiters.find((*str)[currentPosition]) == delimiters.npos)) {
                currentPosition++;
        }
        if (retTokens && (start == currentPosition) &&
                   (delimiters.find((*str)[currentPosition]) != delimiters.npos)) {
                currentPosition++;
        }

        return start;
}


int stringTok::CountTokens()
{
        int count = 0;
        int currpos = currentPosition;

        while (currpos < maxPosition) {
            /*
             * This is just skipDelimiters(); but it does not affect
             * currentPosition.
             */
            while (!retTokens &&
                   (currpos < maxPosition) &&
                   (delimiters.find((*str)[currpos]) != delimiters.npos)) {
                currpos++;
            }

            if (currpos >= maxPosition) {
                break;
            }

            int start = currpos;
            while ((currpos < maxPosition) &&
                   (delimiters.find((*str)[currpos]) == delimiters.npos)) {
                currpos++;
            }
            if (retTokens && (start == currpos) &&
                   (delimiters.find((*str)[currpos]) != delimiters.npos)) {
                currpos++;
            }
            count++;

        }
        return count;
}


void stringTok::Reset (string *_str)
{
        currentPosition = 0;
        str = _str;
        maxPosition = str->length ();
}


void stringTok::Reset (string *_str, bool returnTokens)
{
        retTokens = returnTokens;
        currentPosition = 0;
        str = _str;
        maxPosition = str->length ();
}


void stringTok::Reset (string *_str, string delim, bool returnTokens)
{
        retTokens = returnTokens;
        delimiters = delim;
        currentPosition = 0;
        str = _str;
        maxPosition = str->length ();
}