|
|
/*
* Copyright 1998 American Power Conversion, All Rights Reserved * * NAME: tokenstr.cxx * * PATH: * * REVISION: * * DESCRIPTION: * This file contains the class definition for the TokenString class. It * is designed to replace the strtok() function, because when using strtok * "if multiple or simultaneous calls are made ... a high potential for data * corruption and innacurate results exists." -- MSVC OnLine Help * * REFERENCES: * Initially created by Todd Giaquinto * * NOTES: * This function mimics the behavior of strtok in all aspects. * Examples: * String: ,,,,1,2,3 Sep: , Tokens: "1" "2" "3" * String: ,#1#2,3#4 Sep: ,# Tokens: "1" "2" "3" "4" * * Typical Usage: * TokenString token_str(string, sep); * PCHAR tok = token_str.GetCurrentToken(); * while (tok) { * ..... * tok = token_str.GetCurrentToken(); * } * * The GetCurrentToken call will return a pointer to the current string token * and then move the internal pointer to the start of the next token. If * GetCurrentToken is called without an argument, the separator string passed * to the constructor is used to gather each token. However, GetCurrentToken * is overloaded so that one implementation can take a new separator string * as an argument. Once a new separator string is passed in, all subsequent * calls to the parameter-less GetCurrentToken will use the last passed in * separator. * * REVISIONS: * tjg19Jan98: Initial implementation * tjg29Jan98: Included formal code review comments * * v-stebe 29Jul2000 Fixed PREfix errors (bugs #46356, #46357) */
#include "cdefine.h"
#include "tokenstr.h"
// Function: TokenString Constructor
// Parameters: 1. Character pointer containing the string (ie "#str#str2#")
// 2. Character pointer containing the separator (ie "#")
// Ret Value: None
// Purpose: Initializes all class member variables to defaults. Then
// stores the argument values.
TokenString::TokenString(PCHAR aString, PCHAR aSeparatorString) : theString(NULL), theSeparators(NULL), theCurrentLocation(NULL), theSeparatorLength(0) { if (aString) { theString = new CHAR[strlen(aString) + 1];
if (theString != NULL) { strcpy(theString, aString); }
theCurrentLocation = theString; } storeSeparatorString(aSeparatorString); }
// Function: TokenString Destructor
// Parameters: None
// Ret Value: None
// Purpose: Cleans up all allocated memory.
TokenString::~TokenString() { delete [] theString; theString = NULL;
delete [] theSeparators; theSeparators = NULL; }
// Function: storeSeparatorString
// Parameters: Character pointer to the new separator string
// Ret Value: None
// Purpose: Stores the parameter aString as theSeparators. This method is
// optimized to allocate memory only if the current buffer is too
// small.
VOID TokenString::storeSeparatorString(PCHAR aString) { if (aString) { INT length = strlen(aString); if (length > theSeparatorLength) { delete [] theSeparators; theSeparatorLength = length; theSeparators = new CHAR[length + 1]; }
if (theSeparators != NULL) { strcpy(theSeparators, aString); } } }
// Function: isSeparator
// Parameters: A character to check against theSeparators
// Ret Value: TRUE, if theSeparators contains aCharacter
// FALSE, otherwise
// Purpose: Searches through theSeparators string looking for an
// occurrence of aCharacter
BOOL TokenString::isSeparator(CHAR aCharacter) { BOOL is_separator = FALSE;
PCHAR current_sep = theSeparators;
// Run this loop while the pointer and contents are non-NULL, and
// we have not determined that aCharacter is a separator.
while ((current_sep != NULL) && (*current_sep != NULL) && (is_separator == FALSE)) {
if (*current_sep == aCharacter) { is_separator = TRUE; } current_sep++; }
return is_separator; }
// Function: GetCurrentToken
// Parameters: Character pointer to a new separator string
// Ret Value: Pointer to the current string in the list
// Purpose: Sets theSeparators to aSeparatorString and gets the next token
// in the string (using the new separator string)
PCHAR TokenString::GetCurrentToken(PCHAR aSeparatorString) { storeSeparatorString(aSeparatorString); return GetCurrentToken(); }
// Function: GetCurrentToken
// Parameters: None
// Ret Value: Pointer to the current string in the list
// Purpose: Gets the next token in the string using theSeparators as
// the separator string
PCHAR TokenString::GetCurrentToken() { BOOL recording_token = FALSE; BOOL done = FALSE; PCHAR current_token = NULL;
// While there is stuff in the list and the current token has not ended
while (theCurrentLocation && *theCurrentLocation && !done) {
// Check if the current character is a separator
BOOL is_separator = isSeparator(*theCurrentLocation);
// If we found a separator and we were recording a token,
// change this separator to a NULL and reset flags
if (is_separator && recording_token) { *theCurrentLocation = NULL; recording_token = FALSE; done = TRUE; }
// If the character isn't a separator and not
// already recording a token, mark the beginning of the token
else if (!is_separator && !recording_token) { current_token = theCurrentLocation; recording_token = TRUE; }
theCurrentLocation++; }
return current_token; }
|