blob: f57a5a01ff67ace113018955def9bd59163ed612 [file] [log] [blame]
#ifndef UIMA_STRTOOLS_HPP
#define UIMA_STRTOOLS_HPP
/** \file strtools.hpp .
-------------------------------------------------------------------------------
* 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.
-------------------------------------------------------------------------------
\brief String tools functions.
-------------------------------------------------------------------------------
*/
/* ----------------------------------------------------------------------- */
/* Include dependencies */
/* ----------------------------------------------------------------------- */
#include "uima/pragmas.hpp" //must be included first to disable warnings
#include <vector>
#include <string>
#include <iostream>
#include <fstream>
#include <functional>
#include "uima/types.h"
#include "unicode/uchar.h"
/* ----------------------------------------------------------------------- */
/* Implementation dependencies */
/* ----------------------------------------------------------------------- */
namespace uima {
/* ----------------------------------------------------------------------- */
/* Constants */
/* ----------------------------------------------------------------------- */
#if defined(AE_STL)
/** Macro for the new ANSI string constant <TT>string::npos</TT>.
To make it work with adaption efforts <TT>bstring.h</TT>
*/
# define STRING_NPOS NPOS
#else
# define STRING_NPOS std::string::npos
#endif
//defines for defining basic string template functions with OS/AE STl implementations
#ifdef OS_STL //Object Space STL implementation
# define BASIC_STRING_NAME os_basic_string
# define BS_TEMPLATE_DEFINITION_ARGS OS_BS_TEMPLATE_DEFINITION_ARGS
# define BS_TEMPLATE_ARGS OS_BS_TEMPLATE_ARGS
# define SINGLE_ARG_BASIC_STRING( CharT ) os_basic_string<CharT, os_char_traits< CharT >, Allocator< CharT > >
#elif defined(AE_STL) //Adaption Effort STL implementation (public domain)
# define BASIC_STRING_NAME basic_string
# define BS_TEMPLATE_DEFINITION_ARGS <class CharT CLASS_TRAITS_ALLOC>
# define BS_TEMPLATE_ARGS <CharT CLASS_TRAITS_ALLOC>
# define SINGLE_ARG_BASIC_STRING( CharT ) std::basic_string<CharT, char_traits< CharT >, allocator< CharT > >
#else //ANSI compliant compiler specific STL (assumes compiler can handle template default args)
# define BASIC_STRING_NAME std::basic_string
# if defined(__OS_DYNIXPTX__)
// ptxC++ supports default template arguments, but definition of
// class basic_string doesn't exploit them :-(
# define BS_TEMPLATE_DEFINITION_ARGS <class CharT, class traits, class Allocator >
# define BS_TEMPLATE_ARGS < CharT, traits, Allocator >
# define SINGLE_ARG_BASIC_STRING( CharT ) std::basic_string< CharT, char_traits< CharT >, Allocator< CharT > >
# else
# define BS_TEMPLATE_DEFINITION_ARGS <class CharT >
# define BS_TEMPLATE_ARGS < CharT >
# define SINGLE_ARG_BASIC_STRING( CharT ) std::basic_string< CharT >
#endif
#endif
#define BASIC_STRING_TEMPLATE BASIC_STRING_NAME BS_TEMPLATE_ARGS
#define CHAR_EOS '\0'
/* ----------------------------------------------------------------------- */
/** @name Character utility functions
Character functions are handled by providing specializations
for each character type. In practice, a template is used for the
default case single character and one specialization for UCS2.
Provided functions:
<TT>tolower_templ()</TT>
<TT>toupper_templ()</TT>
<TT>isspace_templ()</TT>
<TT>isalnum_templ()</TT>
Note: Automatic documentation does not seem to work for some of them!
---------------------------------------------------------------------------*/
/*@{*/
#if defined(UNDECLARED_FUNCTION_TEMPLATES_LINK_BUG)
// To work around "unsatisfied symbols" during linking,
// we need a declaration in addition to the definition below
template < class CharT >
CharT
tolower_templ(
const CharT & c
);
#endif
/** Template version of <TT>tolower()</TT>.
This is designed for single byte and UCS2 characters only.
*/
template < class CharT >
CharT
tolower_templ(
const CharT & c
) {
assertWithMsg(sizeof(CharT) == sizeof(char),"Missing explicit specialization for character type.");//lint !e506: Constant value Boolean
return (CharT)::tolower(c); //lint !e50: Attempted to take the address of a non-lvalue
}
inline UChar
tolower_templ(
const UChar & c
) {
return (UChar)u_tolower(c);
} //lint !e1746: parameter 'c' in function 'tolower_templ(UChar)' could be made const reference
/*---------------------------------------------------------------------------*/
#if defined(UNDECLARED_FUNCTION_TEMPLATES_LINK_BUG)
// To work around "unsatisfied symbols" during linking,
// we need a declaration in addition to the definition below
template < class CharT >
CharT
toupper_templ(
const CharT & c
);
#endif
/** Template version of <TT>toupper()</TT>.
This is designed for single byte and UCS2 characters only.
*/
template < class CharT >
CharT
toupper_templ(
const CharT & c
) { //lint !e1053 !e18: Symbol 'toupper_templ(const char)' redeclared
assertWithMsg(sizeof(CharT) == sizeof(char),"Missing explicit specialization for character type.");//lint !e506: Constant value Boolean
return (CharT)toupper(c);
}
inline UChar
toupper_templ(
const UChar & c
) {
return (UChar)u_toupper(c);
} //lint !e1746: parameter 'c' in function 'toupper_templ(UChar)' could be made const reference
/*---------------------------------------------------------------------------*/
#if defined(UNDECLARED_FUNCTION_TEMPLATES_LINK_BUG)
// To work around "unsatisfied symbols" during linking,
// we need a declaration in addition to the definition below
template < class CharT >
bool
isspace_templ(
const CharT & c
);
#endif
/** Template version of <TT>isspace()</TT>.
This is designed for single byte and UCS2 characters only.
*/
template < class CharT >
bool
isspace_templ(
const CharT & c
) {
assertWithMsg(sizeof(CharT) == sizeof(char),"Missing explicit specializatio for character type.");//lint !e506: Constant value Boolean
return (bool)isspace(c);
}
inline bool
isspace_templ(
const UChar & c
) {
return (bool)u_isspace(c);
} //lint !e1746: parameter 'c' in function 'isspace_templ(UChar)' could be made const reference
/*---------------------------------------------------------------------------*/
#if defined(UNDECLARED_FUNCTION_TEMPLATES_LINK_BUG)
// To work around "unsatisfied symbols" during linking,
// we need a declaration in addition to the definition below
template < class CharT >
bool
isalnum_templ(
const CharT & c
);
#endif
/** Template version of <TT>isalnum()</TT>.
This is designed for single byte and UCS2 characters only.
*/
template < class CharT >
bool
isalnum_templ(
const CharT & c
) {
assertWithMsg(sizeof(CharT) == sizeof(char),"Missing explicit specializatio for character type.");//lint !e506: Constant value Boolean
return (bool)isalnum(c);
}
inline bool
isalnum_templ(
const UChar & c
) {
return (bool)u_isalnum(c);
} //lint !e1746: parameter 'c' in function 'isalnum_templ(UChar)' could be made const reference
/*@}*/
/* ----------------------------------------------------------------------- */
/** @name Template version of common C string functions */
/* ----------------------------------------------------------------------- */
/*@{*/
#if defined(UNDECLARED_FUNCTION_TEMPLATES_LINK_BUG)
// To work around "unsatisfied symbols" during linking,
// we need a declaration in addition to the definition below
template < class CharT >
const CharT *
strchr_templ(
const CharT * cpszString,
const CharT & c
);
#endif
/** Template version of <TT>strchr()</TT>.
This is case sensitive.
*/
template < class CharT >
const CharT *
strchr_templ(
const CharT * cpszString,
const CharT & c
) {
assert(EXISTS(cpszString));
while (*cpszString != c && *cpszString != (CharT)CHAR_EOS) { //lint !e1912: Implicit call of conversion function from class 'UChar' to type 'unsigned short'
++cpszString;
}
if (*cpszString == (CharT)CHAR_EOS) {
return NULL;
}
return (cpszString);
}
/*---------------------------------------------------------------------------*/
#if defined(UNDECLARED_FUNCTION_TEMPLATES_LINK_BUG)
// To work around "unsatisfied symbols" during linking,
// we need a declaration in addition to the definition below
template < class CharT >
size_t
strlen_templ(
const CharT * cpszString
);
#endif
/** Template version of <TT>strlen()</TT>.
This is case sensitive.
*/
template < class CharT >
size_t
strlen_templ(
const CharT * cpszString
) {
assert(EXISTS(cpszString));
size_t uiLen = 0;
while (*cpszString != (CharT)CHAR_EOS) { //lint !e1912: Implicit call of conversion function from class 'UChar' to type 'unsigned short'
++uiLen;
++cpszString;
}
return (uiLen);
}
/*---------------------------------------------------------------------------*/
#if defined(UNDECLARED_FUNCTION_TEMPLATES_LINK_BUG)
// To work around "unsatisfied symbols" during linking,
// we need a declaration in addition to the definition below
template < class CharT >
inline CharT *
strncpy_templ(
CharT * pszTarget,
const CharT * cpszSource,
size_t uiSourceLen
);
#endif
/** Template version of <TT>strncpy()</TT>.
*/
template < class CharT >
inline CharT *
strncpy_templ(
CharT * pszTarget,
const CharT * cpszSource,
size_t uiSourceLen
) {
assert(EXISTS(cpszSource));
assert(uiSourceLen == 0 || EXISTS(pszTarget));
memcpy(pszTarget, cpszSource, uiSourceLen*sizeof(CharT));
return pszTarget;
}
/*---------------------------------------------------------------------------*/
#if defined(UNDECLARED_FUNCTION_TEMPLATES_LINK_BUG)
// To work around "unsatisfied symbols" during linking,
// we need a declaration in addition to the definition below
template < class CharT >
int
strcmp_templ(
const CharT * cpszString1,
const CharT * cpszString2
);
#endif
/** Template version of <TT>strcmp()</TT>.
This is case sensitive.
*/
template < class CharT >
int
strcmp_templ(
const CharT * cpszString1,
const CharT * cpszString2
) {
if (cpszString1 == NULL) {
if (cpszString2 == NULL) {
return 0;
}
return -1;
}
if (cpszString2 == NULL) {
return +1;
}
assert(EXISTS(cpszString1));
assert(EXISTS(cpszString2));
while (*cpszString1 == *cpszString2) {
if (*cpszString1 == (CharT)CHAR_EOS)
return(0);
++cpszString1;
++cpszString2;
}
return ( (int) *cpszString1 - (int) *cpszString2);
}
/*---------------------------------------------------------------------------*/
#if defined(UNDECLARED_FUNCTION_TEMPLATES_LINK_BUG)
// To work around "unsatisfied symbols" during linking,
// we need a declaration in addition to the definition below
template < class CharT >
int
stricmp_templ(
const CharT * cpszString1,
const CharT * cpszString2
);
#endif
/** Template version of <TT>stricmp()</TT>.
This is case sensitive
*/
template < class CharT >
int
stricmp_templ(
const CharT * cpszString1,
const CharT * cpszString2
) {
if (cpszString1 == NULL) {
if (cpszString2 == NULL) {
return 0;
}
return -1;
}
if (cpszString2 == NULL) {
return +1;
}
assert(EXISTS(cpszString1));
assert(EXISTS(cpszString2));
while (toupper_templ(*cpszString1) == toupper_templ(*cpszString2)) {
if (*cpszString1 == (CharT)CHAR_EOS)
return(0);
++cpszString1;
++cpszString2;
}
return ((int) toupper_templ(*cpszString1) - (int) toupper_templ(*cpszString2));
}
/*---------------------------------------------------------------------------*/
#if defined(UNDECLARED_FUNCTION_TEMPLATES_LINK_BUG)
// To work around "unsatisfied symbols" during linking,
// we need a declaration in addition to the definition below
template < class CharT >
int
strncmp_templ(
const CharT * cpszString1,
const CharT * cpszString2,
size_t uiLen
);
#endif
/** Template version of <TT>strncmp()</TT>.
Compare string up to specified length (this is case sensitive).
*/
template < class CharT >
int
strncmp_templ(
const CharT * cpszString1,
const CharT * cpszString2,
size_t uiLen
) {
assert(EXISTS(cpszString1));
assert(EXISTS(cpszString2));
if (!(bool)uiLen) {
return(0);
}
while ((bool)--uiLen && (bool)*cpszString1 && *cpszString1 == *cpszString2) //lint !e1912: Implicit call of conversion function from class 'const UChar' to type 'const UChar'
{
cpszString1++;
cpszString2++;
}
return((int) *cpszString1 - (int) *cpszString2); //lint !e794: Conceivable use of null pointer 'cpszString2' in argument to operator 'unary *'
}
#if defined(UNDECLARED_FUNCTION_TEMPLATES_LINK_BUG)
// To work around "unsatisfied symbols" during linking,
// we need a declaration in addition to the definition below
template < class CharT >
int
strncmp_templ(
const CharT * cpszString1,
const CharT * cpszString2,
int iLen
);
#endif
/* Int arg version to get template arguments matched.
of the template version of <TT>strncmp()</TT>.
*/
template < class CharT >
int
strncmp_templ(
const CharT * cpszString1,
const CharT * cpszString2,
int iLen
) {
assert(iLen >= 0);
return strncmp_templ(cpszString1, cpszString2, (size_t)iLen);
}
/*---------------------------------------------------------------------------*/
#if defined(UNDECLARED_FUNCTION_TEMPLATES_LINK_BUG)
// To work around "unsatisfied symbols" during linking,
// we need a declaration in addition to the definition below
template < class CharT >
int
strnicmp_templ(
const CharT * cpszString1,
const CharT * cpszString2,
size_t uiLen
);
#endif
/** Template version of <TT>strnicmp()</TT>.
Compare string up to specified length (this is case insensitive).
*/
template < class CharT >
int
strnicmp_templ(
const CharT * cpszString1,
const CharT * cpszString2,
size_t uiLen
) {
assert(EXISTS(cpszString1));
assert(EXISTS(cpszString2));
while (uiLen && (toupper_templ(*cpszString1) == toupper_templ(*cpszString2))) {
if (*cpszString1 == (CharT)CHAR_EOS)
return(0);
++cpszString1;
++cpszString2;
--uiLen;
}
if (uiLen)
return ((int) toupper_templ(*cpszString1) - (int) toupper_templ(*cpszString2));
return(0);
}
#if defined(UNDECLARED_FUNCTION_TEMPLATES_LINK_BUG)
// To work around "unsatisfied symbols" during linking,
// we need a declaration in addition to the definition below
template < class CharT >
int
strnicmp_templ(
const CharT * cpszString1,
const CharT * cpszString2,
int iLen
);
#endif
/* Int arg version to get template arguments matched.
of the template version of <TT>strnicmp()</TT>.
*/
template < class CharT >
int
strnicmp_templ(
const CharT * cpszString1,
const CharT * cpszString2,
int iLen
) {
assert(iLen >= 0);
return strnicmp_templ(cpszString1, cpszString2, (size_t)iLen);
}
/*@}*/
/**
Template class for case insensitive string comparison.
Class T must be a derived from template class basic_string.
The class currently supports only single character-based comparision.
*/
template< class T >
class UIMA_LINK_IMPORTSPEC StringLessI : public std::binary_function< T, T, bool > {
public:
bool
operator()(const T& x, const T& y) const {
if (x.length() == 0) {
if (y.length() == 0) {
return false;
}
return true;
}
if (y.length() == 0) {
return false;
}
assert(x.length() > 0);
assert(y.length() > 0);
return (stricmp_templ(x.c_str(), y.c_str()) < 0);
}
}
; //lint !e1509 !e1905: implicit default constructor generated for class 'StringLessI' : base class destructor for class 'binary_function' is not virtual
/**
Tool class to encapsulate string pointers.
Useful in templates where string* is not possible
*/
template BS_TEMPLATE_DEFINITION_ARGS
struct StringPtrObj {
const BASIC_STRING_TEMPLATE *
m_pStr;
public:
///(Default) Constructor
StringPtrObj(
const BASIC_STRING_TEMPLATE * pStr = NULL
) :
m_pStr(pStr) {}
///String Constructor
StringPtrObj(
const BASIC_STRING_TEMPLATE & str
) :
m_pStr(&str) {}
///Copy Constructor
StringPtrObj(
const StringPtrObj & spo
) :
m_pStr(spo.m_pStr) {}
///Sssignment operator
const StringPtrObj&
operator = (
const StringPtrObj & spo
) {
m_pStr = spo.m_pStr;
return *this;
}
///less operator
bool operator < (
const StringPtrObj & spo
) const
{
return (m_pStr < spo.m_pStr);
}
///equality operator
bool operator == (
const StringPtrObj & spo
) const
{
return m_pStr == spo.m_pStr;
}
///conversion to BASIC_STRING_TEMPLATE *
operator const BASIC_STRING_TEMPLATE * () const
{
return m_pStr;
}
///* operator
const BASIC_STRING_TEMPLATE
operator * () {
return *m_pStr;
}
};
/* ----------------------------------------------------------------------- */
/** @name Reading from files up to delimiters */
/* ----------------------------------------------------------------------- */
/*@{*/
#if defined(UNDECLARED_FUNCTION_TEMPLATES_LINK_BUG)
// To work around "unsatisfied symbols" during linking,
// we need a declaration in addition to the definition below
template BS_TEMPLATE_DEFINITION_ARGS
bool
strFileToStrVector(
const BASIC_STRING_TEMPLATE & filename,
vector<BASIC_STRING_TEMPLATE>& v,
bool toLower,
bool trim
);
#endif
/**
Reads in a text file and puts the content in a vector of
strings.
One vector element per line.
@param filename The filename and vector to store the results.
@param v (Output) The vector of strings to store the result in.
@param toLower A Flag, if the strings are to be lowercase.
@return true if file could be successfully opened, otherwise false.
*/
template BS_TEMPLATE_DEFINITION_ARGS
bool
strFileToStrVector(
const BASIC_STRING_TEMPLATE & filename,
std::vector< BASIC_STRING_TEMPLATE > & v,
bool toLower,
bool trim
) {
std::ifstream inStream(filename);
if (inStream.fail()) {
return false;
}
STLEraseAll(v);
BASIC_STRING_TEMPLATE s;
while (!inStream.eof()) {
getline(inStream, s, "\n");
if (toLower) {
strlower(s);
}
if (trim) {
s = strtrim(s); // fixed, tg Fri Nov 6 19:04:24 EST 1998
}
v.push_back(s);
}
return true;
}
/*---------------------------------------------------------------------------*/
#if defined(UNDECLARED_FUNCTION_TEMPLATES_LINK_BUG)
// To work around "unsatisfied symbols" during linking,
// we need a declaration in addition to the definition below
template BS_TEMPLATE_DEFINITION_ARGS
CharT
getline(
istream& i,
BASIC_STRING_TEMPLATE & s,
const CharT* delimiters
);
#endif
/**
Reads in a string s from a stream up to a delimiter from
a set of delimiters.
The delimiter set is specified as a CharT*
Note: Derived from getline for strings in bstring.h
@param i The input stream to read from.
@param s (Output) The string to return the line read in.
@param delimiters The (line) delimiters (interpreted as a SET of characters).
@return The actual delimiter found.
*/
template BS_TEMPLATE_DEFINITION_ARGS
CharT
getline(
std::istream & i,
BASIC_STRING_TEMPLATE & s,
const CharT * delimiters
) {
assert(EXISTS(delimiters));
s.erase();
//s.clear();
CharT value;
while (true) { //lint !e716: while(1) ...
i >> value;
// It appears this is just checking if it's null and not null and
// not fail -- if (!i.operator void*())
if (i.fail())
break;
if (!strchr_templ(delimiters, value)) {
s += value;
while (true) { //lint !e716: while(1) ...
i >> value;
if (i.fail())
break;
if (!strchr_templ(delimiters, value)) {
s += value;
} else
break;
}
break;
}
}
return value;
}
/**
Reads in a string s from a stream up to a delimiter out of
a set of delimiters and converts into an int or long.
The delimiter set is specified as a CharT*
@param i The input stream to read from.
@param l (Output) The number to store the resulting number in.
@param delimiters The (line) delimiters (interpreted as a SET of characters)
@return The actual delimiter found
*/
template <class NumType, class CharT >
CharT
getlineAsNum(
std::istream& i,
NumType & l,
const CharT * delimiters
) {
SINGLE_ARG_BASIC_STRING( CharT ) s;
CharT retChar = getline(i, s, delimiters);
l = string2Long(s);
return retChar;
}
/**
Reads in a string s from a stream up to a delimiter out of
a set of delimiters and converts into a double, float or similar.
The delimiter set is specified as a CharT*
@param i The input stream to read from.
@param d (Output) The number to store the resulting number in.
@param delimiters The (line) delimiters (interpreted as a SET of chars)
@return The actual delimiter found
*/
template <class RealType, class CharT >
CharT
getlineAsReal(
std::istream& i,
RealType & d,
const CharT * delimiters
) {
SINGLE_ARG_BASIC_STRING( CharT ) s;
CharT retChar = getline(i, s, delimiters);
d = string2Double(s);
return retChar;
}
/*@}*/
/* ----------------------------------------------------------------------- */
/** @name Padding (right and left) */
/* ----------------------------------------------------------------------- */
/*@{*/
#if defined(UNDECLARED_FUNCTION_TEMPLATES_LINK_BUG)
// To work around "unsatisfied symbols" during linking,
// we need a declaration in addition to the definition below
template BS_TEMPLATE_DEFINITION_ARGS
void
strpad_r(
BASIC_STRING_TEMPLATE & s,
size_t newLen,
const CharT padChar
);
#endif
/**
Pads a string from the right up to a specified length with a specified pad
character.
Note: Padding will not shorten the string if <TT>newLen</TT> is less then <TT>s.length()</TT>,
a mutating version.
@param s (Output) The string to pad.
@param newLen The new length of the string after padding.
@param padChar The character to use for padding.
*/
template BS_TEMPLATE_DEFINITION_ARGS
void
strpad_r(
BASIC_STRING_TEMPLATE & s,
size_t newLen,
const CharT padChar
) {
for (size_t i = s.length(); i < newLen; i++) {
s += padChar;
}
}
/*---------------------------------------------------------------------------*/
#if defined(UNDECLARED_FUNCTION_TEMPLATES_LINK_BUG)
// To work around "unsatisfied symbols" during linking,
// we need a declaration in addition to the definition below
template BS_TEMPLATE_DEFINITION_ARGS
void
strpad_r(
BASIC_STRING_TEMPLATE & s,
size_t newLen
);
#endif
/**
Pads a string from the right up to a specified length with a specified pad
character.
Note: Padding will not shorten the string if <TT>newLen</TT> is less then <TT>s.length()</TT>,
a mutating version.
@param s (Output) The string to pad.
@param newLen The new length of the string after padding.
*/
template BS_TEMPLATE_DEFINITION_ARGS
void
strpad_r(
BASIC_STRING_TEMPLATE & s,
size_t newLen
) {
strpad_r(s, newLen, ' ');
}
/*---------------------------------------------------------------------------*/
#if defined(UNDECLARED_FUNCTION_TEMPLATES_LINK_BUG)
// To work around "unsatisfied symbols" during linking,
// we need a declaration in addition to the definition below
template BS_TEMPLATE_DEFINITION_ARGS
BASIC_STRING_TEMPLATE
strpad_r_copy(
const BASIC_STRING_TEMPLATE & s,
size_t newLen,
const CharT padChar
);
#endif
/**
Pads a string from the right up to a specified length with a specified pad
character.
Note: Padding will not shorten the string if <TT>newLen</TT> is less then <TT>s.length()</TT>,
a mutating version.
@param s (Output) The string to pad.
@param newLen The new length of the string after padding.
@param padChar The character to use for padding.
*/
template BS_TEMPLATE_DEFINITION_ARGS
BASIC_STRING_TEMPLATE
strpad_r_copy(
const BASIC_STRING_TEMPLATE & s,
size_t newLen,
const CharT padChar
) {
BASIC_STRING_TEMPLATE s1(s);
strpad_r(s1, newLen, padChar);
return s1;
}
/*---------------------------------------------------------------------------*/
#if defined(UNDECLARED_FUNCTION_TEMPLATES_LINK_BUG)
// To work around "unsatisfied symbols" during linking,
// we need a declaration in addition to the definition below
template BS_TEMPLATE_DEFINITION_ARGS
BASIC_STRING_TEMPLATE
strpad_r_copy(
const BASIC_STRING_TEMPLATE & s,
size_t newLen
);
#endif
/**
Pads a string from the right up to a specified length with a specified pad
character.
Note: Padding will not shorten the string if <TT>newLen</TT> is less then <TT>s.length()</TT>,
a mutating version.
@param s (Output) The string to pad.
@param newLen The new length of the string after padding.
@param padChar The character to use for padding.
*/
template BS_TEMPLATE_DEFINITION_ARGS
BASIC_STRING_TEMPLATE
strpad_r_copy(
const BASIC_STRING_TEMPLATE & s,
size_t newLen
) {
return strpad_r_copy(s, newLen, ' ');
}
/*---------------------------------------------------------------------------*/
#if defined(UNDECLARED_FUNCTION_TEMPLATES_LINK_BUG)
// To work around "unsatisfied symbols" during linking,
// we need a declaration in addition to the definition below
template BS_TEMPLATE_DEFINITION_ARGS
void
strpad_l(
BASIC_STRING_TEMPLATE & s,
size_t newLen,
const CharT padChar
);
#endif
/**
Pads a string from the left up to a specified length with a specified pad
character.
Note: Padding will not shorten the string if <TT>newLen</TT> is less then <TT>s.length()</TT>,
a mutating version.
@param s (Output) The string to pad.
@param newLen The new length of the string after padding.
@param padChar The character to use for padding.
*/
template BS_TEMPLATE_DEFINITION_ARGS
void
strpad_l(
BASIC_STRING_TEMPLATE & s,
size_t newLen,
const CharT padChar
) {
if (newLen > s.length()) {
s.insert((size_t)0, (size_t)newLen-s.length(), padChar);
}
}
/*---------------------------------------------------------------------------*/
#if defined(UNDECLARED_FUNCTION_TEMPLATES_LINK_BUG)
// To work around "unsatisfied symbols" during linking,
// we need a declaration in addition to the definition below
template BS_TEMPLATE_DEFINITION_ARGS
void
strpad_l(
BASIC_STRING_TEMPLATE & s,
size_t newLen
);
#endif
/**
Pads a string from the left up to a specified length with a specified pad
character.
Note: Padding will not shorten the string if <TT>newLen</TT> is less then <TT>s.length()</TT>,
a mutating version.
@param s (Output) The string to pad.
@param newLen The new length of the string after padding.
*/
template BS_TEMPLATE_DEFINITION_ARGS
void
strpad_l(
BASIC_STRING_TEMPLATE & s,
size_t newLen
) {
strpad_l(s, newLen, ' ');
}
/*---------------------------------------------------------------------------*/
#if defined(UNDECLARED_FUNCTION_TEMPLATES_LINK_BUG)
// To work around "unsatisfied symbols" during linking,
// we need a declaration in addition to the definition below
template BS_TEMPLATE_DEFINITION_ARGS
BASIC_STRING_TEMPLATE
strpad_l_copy(
const BASIC_STRING_TEMPLATE & s,
size_t newLen,
const CharT padChar
);
#endif
/**
Pads a string from the left up to a specified length with a specified pad
character.
Note: Padding will not shorten the string if <TT>newLen</TT> is less then <TT>s.length()</TT>,
a copy version.
@param s The string to pad.
@param newLen The new length of the string after padding.
@param padChar The character to use for padding.
@return The padded string.
*/
template BS_TEMPLATE_DEFINITION_ARGS
BASIC_STRING_TEMPLATE
strpad_l_copy(
const BASIC_STRING_TEMPLATE & s,
size_t newLen,
const CharT padChar
) {
BASIC_STRING_TEMPLATE s1(s);
strpad_l(s1, newLen, padChar);
return s1;
}
/*---------------------------------------------------------------------------*/
#if defined(UNDECLARED_FUNCTION_TEMPLATES_LINK_BUG)
// To work around "unsatisfied symbols" during linking,
// we need a declaration in addition to the definition below
template BS_TEMPLATE_DEFINITION_ARGS
BASIC_STRING_TEMPLATE
strpad_l_copy(
const BASIC_STRING_TEMPLATE & s,
size_t newLen
);
#endif
/**
Pads a string from the left up to a specified length with a specified pad
character.
Note: Padding will not shorten the string if <TT>newLen</TT> is less then <TT>s.length()</TT>,
a copy version.
@param s The string to pad.
@param newLen The new length of the string after padding.
@return The padded string.
*/
template BS_TEMPLATE_DEFINITION_ARGS
BASIC_STRING_TEMPLATE
strpad_l_copy(
const BASIC_STRING_TEMPLATE & s,
size_t newLen
) {
return strpad_l_copy(s, newLen, ' ');
}
/*@}*/
/* ----------------------------------------------------------------------- */
/** @name String upper/lower casing */
/* ----------------------------------------------------------------------- */
/*@{*/
#if defined(UNDECLARED_FUNCTION_TEMPLATES_LINK_BUG)
// To work around "unsatisfied symbols" during linking,
// we need a declaration in addition to the definition below
template BS_TEMPLATE_DEFINITION_ARGS
void
strupper(
BASIC_STRING_TEMPLATE & s
);
#endif
/** Converts a string to uppercase, a mutating version.
Template function.
*/
template BS_TEMPLATE_DEFINITION_ARGS
void
strupper(
BASIC_STRING_TEMPLATE & s
) {
for (size_t i =0; i < s.length(); ++i) {
s[i] = (CharT)toupper_templ(s[i]);
}
}
/*---------------------------------------------------------------------------*/
#if defined(UNDECLARED_FUNCTION_TEMPLATES_LINK_BUG)
// To work around "unsatisfied symbols" during linking,
// we need a declaration in addition to the definition below
template BS_TEMPLATE_DEFINITION_ARGS
BASIC_STRING_TEMPLATE
strupper_copy(
const BASIC_STRING_TEMPLATE & s
);
#endif
/** Converts a string to uppercase, a copy version.
Template function.
*/
template BS_TEMPLATE_DEFINITION_ARGS
BASIC_STRING_TEMPLATE
strupper_copy(
const BASIC_STRING_TEMPLATE & s
) {
BASIC_STRING_TEMPLATE s1(s);
strupper(s1);
return s1;
}
/*---------------------------------------------------------------------------*/
#if defined(UNDECLARED_FUNCTION_TEMPLATES_LINK_BUG)
// To work around "unsatisfied symbols" during linking,
// we need a declaration in addition to the definition below
template BS_TEMPLATE_DEFINITION_ARGS
void
strlower(
BASIC_STRING_TEMPLATE & s
);
#endif
/** Converts a string to lowercase, a mutating version.
Template function.
*/
template BS_TEMPLATE_DEFINITION_ARGS
void
strlower(
BASIC_STRING_TEMPLATE & s
) {
for (size_t i = 0; i < s.length(); ++i) {
s[i] = (CharT)tolower_templ(s[i]);
}
}
/*---------------------------------------------------------------------------*/
#if defined(UNDECLARED_FUNCTION_TEMPLATES_LINK_BUG)
// To work around "unsatisfied symbols" during linking,
// we need a declaration in addition to the definition below
template BS_TEMPLATE_DEFINITION_ARGS
BASIC_STRING_TEMPLATE
strlower_copy(
const BASIC_STRING_TEMPLATE & s
);
#endif
/** Converts a string to lowercase, a copy version.
Template function.
*/
template BS_TEMPLATE_DEFINITION_ARGS
BASIC_STRING_TEMPLATE
strlower_copy(
const BASIC_STRING_TEMPLATE & s
) {
BASIC_STRING_TEMPLATE s1(s);
strlower(s1);
return s1;
}
/*@}*/
/* ----------------------------------------------------------------------- */
/** @name Trimming (white space removal) */
/* ----------------------------------------------------------------------- */
/*@{*/
#if defined(UNDECLARED_FUNCTION_TEMPLATES_LINK_BUG)
// To work around "unsatisfied symbols" during linking,
// we need a declaration in addition to the definition below
template BS_TEMPLATE_DEFINITION_ARGS
BASIC_STRING_TEMPLATE
strtrim(
const BASIC_STRING_TEMPLATE & s
);
#endif
/**
Removes whitespace from both ends of a string.
Template function using <TT>isspace_templ()</TT>.
*/
template BS_TEMPLATE_DEFINITION_ARGS
BASIC_STRING_TEMPLATE
strtrim(
const BASIC_STRING_TEMPLATE & s
) {
if (s.length() == 0) {
return s;
}
size_t beg = 0;
size_t end = s.length()-1;
while (end >= beg && isspace_templ(s[end]) ) {
--end;
}
while (beg < end && isspace_templ(s[beg]) ) {
++beg;
}
return s.substr(beg, end-beg+1);
}
/*---------------------------------------------------------------------------*/
#if defined(UNDECLARED_FUNCTION_TEMPLATES_LINK_BUG)
// To work around "unsatisfied symbols" during linking,
// we need a declaration in addition to the definition below
template BS_TEMPLATE_DEFINITION_ARGS
BASIC_STRING_TEMPLATE
strtrimr(
const BASIC_STRING_TEMPLATE & s
);
#endif
/**
Removes whitespace from the end of a string.
Template function using <TT>isspace_templ()</TT>.
*/
template BS_TEMPLATE_DEFINITION_ARGS
BASIC_STRING_TEMPLATE
strtrimr(
const BASIC_STRING_TEMPLATE & s
) {
long end = s.length()-1;
while (end >= 0 && isspace_templ(s[end])) {
end--;
}
return s.substr(0, end+1);
}
/*---------------------------------------------------------------------------*/
#if defined(UNDECLARED_FUNCTION_TEMPLATES_LINK_BUG)
// To work around "unsatisfied symbols" during linking,
// we need a declaration in addition to the definition below
template BS_TEMPLATE_DEFINITION_ARGS
BASIC_STRING_TEMPLATE
strtriml(
const BASIC_STRING_TEMPLATE & s
);
#endif
/**
Removes whitespace from the beginning of a string.
Template function using <TT>isspace_templ()</TT>.
*/
template BS_TEMPLATE_DEFINITION_ARGS
BASIC_STRING_TEMPLATE
strtriml(
const BASIC_STRING_TEMPLATE & s
) {
long beg = 0;
long end = s.length()-1;
while (beg != end && isspace_templ(s[beg]) ) {
beg++;
}
return s.substr(beg, end-beg);
}
/*@}*/
/* ----------------------------------------------------------------------- */
/** @name Search and Replace */
/* ----------------------------------------------------------------------- */
/*@{*/
#if defined(UNDECLARED_FUNCTION_TEMPLATES_LINK_BUG)
// To work around "unsatisfied symbols" during linking,
// we need a declaration in addition to the definition below
template <class CharT>
size_t
str_find_first(
const CharT * cpacPattern, // pattern to search for
size_t uiPatternLen,// length of pattern
const CharT * cpacSearch, // string to search in
size_t uiSearchLen // length of string to search in
);
#endif
/**
Finds the first occurence of key string <TT>cpacPattern</TT> (with length
<TT>uiPatternLen</TT>), in the searched string <TT>cpacSearch</TT> (with length
<TT>uiSearchLen</TT>).
*/
template <class CharT>
size_t
str_find_first(
const CharT * cpacPattern, // pattern to search for
size_t uiPatternLen,// length of pattern
const CharT * cpacSearch, // string to search in
size_t uiSearchLen // length of string to search in
) {
// The key won't even fit in what we are searching.
if ( uiPatternLen > uiSearchLen )
return STRING_NPOS;
// The empty string occurs at every position: we return the first
if ( uiPatternLen == 0 )
return 0;
/* taph 2/22/2000: insert your Boyer-Moore search here:
Should be much faster for longer patterns, but the skip table
gets quite large for Unicode CharT
*/
assert(EXISTS(cpacSearch));
assert(EXISTS(cpacPattern));
// The highest position it could possibly be found at:
const CharT * cpacEndPos = cpacSearch + (uiSearchLen - uiPatternLen);
for ( const CharT * cpacLoop = cpacSearch; cpacLoop <= cpacEndPos; ++cpacLoop ) {
/* taph 2/22/2000: this could also use traits< CharT >::compare but for now
we have decided not to make those tool functions traits aware.
*/
if ( memcmp( cpacLoop, cpacPattern, (uiPatternLen*sizeof(CharT)) ) == 0 )
return (cpacLoop - cpacSearch);
}
return STRING_NPOS; // Not found.
}
#if defined(UNDECLARED_FUNCTION_TEMPLATES_LINK_BUG)
// To work around "unsatisfied symbols" during linking,
// we need a declaration in addition to the definition below
template <class CharT>
size_t
str_find_first(
const CharT cPattern, // pattern character to search for
const CharT * cpacSearch, // string to search in
size_t uiSearchLen // length of string to search in
);
#endif
/**
Finds the first occurence of character <TT>cPattern</TT>
in the searched string <TT>cpacSearch</TT> (with length <TT>uiSearchLen</TT>).
*/
template <class CharT>
size_t
str_find_first(
const CharT cPattern, // pattern character to search for
const CharT * cpacSearch, // string to search in
size_t uiSearchLen // length of string to search in
) {
assert(EXISTS(cpacSearch));
// The highest position it could possibly be found at:
const CharT * cpacEndPos = cpacSearch + uiSearchLen;
for ( const CharT * cpacLoop = cpacSearch; cpacLoop < cpacEndPos; ++cpacLoop ) {
/* taph 2/22/2000: this could also use traits< CharT >::compare but for now
we have decided not to make those tool functions traits aware.
*/
if ( (*cpacLoop) == cPattern )
return (cpacLoop - cpacSearch);
}
return STRING_NPOS; // Not found.
} //lint !e1746: parameter 'cPattern' could be made const reference
#if defined(UNDECLARED_FUNCTION_TEMPLATES_LINK_BUG)
// To work around "unsatisfied symbols" during linking,
// we need a declaration in addition to the definition below
template <class CharT>
size_t
str_find_first_of(
const CharT * cpacPatternCharSet, // set of chars to search for
size_t uiPatternCharSetLen,// length of pattern
const CharT * cpacSearch, // string to search in
size_t uiSearchLen // length of string to search in
);
#endif
/**
Finds the first occurence of key string <TT>cpacPattern</TT> (with length
<TT>uiPatternLen</TT>), in the searched string <TT>cpacSearch</TT> (with length
<TT>uiSearchLen</TT>).
*/
template <class CharT>
size_t
str_find_first_of(
const CharT * cpacPatternCharSet, // set of chars to search for
size_t uiPatternCharSetLen,// length of pattern
const CharT * cpacSearch, // string to search in
size_t uiSearchLen // length of string to search in
) {
assert(uiPatternCharSetLen > 0);
assert(EXISTS(cpacPatternCharSet));
// The highest position it could possibly be found at:
const CharT * cpacEndPos = cpacSearch + uiSearchLen;
for ( const CharT * cpacLoop = cpacSearch; cpacLoop < cpacEndPos; ++cpacLoop ) {
if ( str_find_first((*cpacLoop), cpacPatternCharSet, uiPatternCharSetLen ) != STRING_NPOS)
return (cpacLoop - cpacSearch);
}
return STRING_NPOS; // Not found.
}
#if defined(UNDECLARED_FUNCTION_TEMPLATES_LINK_BUG)
// To work around "unsatisfied symbols" during linking,
// we need a declaration in addition to the definition below
template <class CharT>
size_t
str_find_first_not_of(
const CharT * cpacPatternCharSet, // set of chars to search for
size_t uiPatternCharSetLen,// length of pattern
const CharT * cpacSearch, // string to search in
size_t uiSearchLen // length of string to search in
);
#endif
/**
Finds the first occurence of key string <TT>cpacPattern</TT> (with length
<TT>uiPatternLen</TT>), in the searched string <TT>cpacSearch</TT> (with length
<TT>uiSearchLen</TT>).
*/
template <class CharT>
size_t
str_find_first_not_of(
const CharT * cpacPatternCharSet, // set of chars to search for
size_t uiPatternCharSetLen,// length of pattern
const CharT * cpacSearch, // string to search in
size_t uiSearchLen // length of string to search in
) {
assert(uiPatternCharSetLen > 0);
assert(EXISTS(cpacPatternCharSet));
// The highest position it could possibly be found at:
const CharT * cpacEndPos = cpacSearch + uiSearchLen;
for ( const CharT * cpacLoop = cpacSearch; cpacLoop < cpacEndPos; ++cpacLoop ) {
if ( str_find_first((*cpacLoop), cpacPatternCharSet, uiPatternCharSetLen ) == STRING_NPOS)
return (cpacLoop - cpacSearch);
}
return STRING_NPOS; // Not found.
}
/*---------------------------------------------------------------------------*/
#if defined(UNDECLARED_FUNCTION_TEMPLATES_LINK_BUG)
// To work around "unsatisfied symbols" during linking,
// we need a declaration in addition to the definition below
template <class CharT>
void
strreplaceallchar(
CharT* s,
CharT searchchar,
CharT replacechar
);
#endif
/**
Replaces one CharT in a CharT* with another CharT.
(CharT* target with CharT search arguments)
@param s The CharT* where characters are replaced.
@param searchchar The CharT to search for.
@param replacechar The CharT to replace the <TT>searchchar</TT> with.
*/
template <class CharT>
void
strreplaceallchar(
CharT* s,
CharT searchchar,
CharT replacechar
) {
if (s == NULL) {
return;
}
size_t pos;
for (pos = 0; s[pos] != CharT(); pos++) {
if (s[pos] == searchchar) {
s[pos] = replacechar;
}
}
}
/*---------------------------------------------------------------------------*/
#if defined(UNDECLARED_FUNCTION_TEMPLATES_LINK_BUG)
// To work around "unsatisfied symbols" during linking,
// we need a declaration in addition to the definition below
template BS_TEMPLATE_DEFINITION_ARGS
void
strreplaceallchar(
BASIC_STRING_TEMPLATE & s,
const CharT searchchar,
const CharT replacechar
);
#endif
/**
Replaces one CharT in a string with another CharT.
(string target with CharT search arguments)
@param s (Output) The string where characters are replaced.
@param searchchar The CharT to search for.
@param replacechar The CharT to replace the <TT>searchchar</TT> with.
*/
template BS_TEMPLATE_DEFINITION_ARGS
void
strreplaceallchar(
BASIC_STRING_TEMPLATE & s,
const CharT searchchar,
const CharT replacechar
) {
size_t pos;
for (pos = 0; pos < s.length(); pos++) {
if (s[pos] == searchchar) {
s[pos] = replacechar;
}
}
}
/*---------------------------------------------------------------------------*/
#if defined(UNDECLARED_FUNCTION_TEMPLATES_LINK_BUG)
// To work around "unsatisfied symbols" during linking,
// we need a declaration in addition to the definition below
template BS_TEMPLATE_DEFINITION_ARGS
void
strreplaceall(
BASIC_STRING_TEMPLATE & s,
const BASIC_STRING_TEMPLATE & searchstr,
const BASIC_STRING_TEMPLATE & replacestr
);
#endif
/**
Replaces one string in a string with another string.
(string target with string search arguments)
@param s (Output) The string where characters are replaced.
@param searchstr The string to search for.
@param replacestr The string to replace the <TT>searchstring</TT> with.
*/
template BS_TEMPLATE_DEFINITION_ARGS
void
strreplaceall(
BASIC_STRING_TEMPLATE & s,
const BASIC_STRING_TEMPLATE & searchstr,
const BASIC_STRING_TEMPLATE & replacestr
) {
size_t pos(0);
while (((pos = s.find(searchstr, pos)) != STRING_NPOS)) {
s.replace(pos, searchstr.length(), replacestr);
pos += replacestr.length();
}
}
/*---------------------------------------------------------------------------*/
#if defined(UNDECLARED_FUNCTION_TEMPLATES_LINK_BUG)
// To work around "unsatisfied symbols" during linking,
// we need a declaration in addition to the definition below
template BS_TEMPLATE_DEFINITION_ARGS
void
strreplacall_env(
BASIC_STRING_TEMPLATE & s
);
#endif
/**
Replaces all occurences of "$ENV(<TT>varname</TT>)" in a string with the value of
the OS environment variable <TT>varname</TT>, a mutating version.
@param s (Output) The string where env-strings are replaced.
@param searchstr The position in s to start searching.
*/
template BS_TEMPLATE_DEFINITION_ARGS
void
strreplacall_env(
BASIC_STRING_TEMPLATE & s
) {
_strreplacall_env(s, (size_t)0);
}
/*---------------------------------------------------------------------------*/
#if defined(UNDECLARED_FUNCTION_TEMPLATES_LINK_BUG)
// To work around "unsatisfied symbols" during linking,
// we need a declaration in addition to the definition below
template BS_TEMPLATE_DEFINITION_ARGS
BASIC_STRING_TEMPLATE
strreplacall_env_copy(
const BASIC_STRING_TEMPLATE & s
);
#endif
/**
Replaces all occurences of "$ENV(<TT>varname</TT>)" in a string with the value of
the OS environment variable <TT>varname</TT>,
a copy version.
@param s The string where env-strings are replaced.
@param searchstr The position in s to start searching.
@return The string with the replaces vars.
*/
template BS_TEMPLATE_DEFINITION_ARGS
BASIC_STRING_TEMPLATE
strreplacall_env_copy(
const BASIC_STRING_TEMPLATE & s
) {
BASIC_STRING_TEMPLATE s1(s);
_strreplacall_env(s1, (size_t)0);
return s1;
}
/*---------------------------------------------------------------------------*/
#if defined(UNDECLARED_FUNCTION_TEMPLATES_LINK_BUG)
// To work around "unsatisfied symbols" during linking,
// we need a declaration in addition to the definition below
template BS_TEMPLATE_DEFINITION_ARGS
void
_strreplacall_env(
BASIC_STRING_TEMPLATE & s,
size_t pos
);
#endif
/*
Replaces all occurences of "$ENV(<TT>varname</TT>)" in a string with the value of
the OS environment variable <TT>varname</TT>,
a mutating version.
The function starts to search from a specified start position.
Note: This function is used in the above <TT>strreplacall</TT> functions.
@param s (Output) The string where env-strings are replaced.
@param searchstr The position in s to start searching.
*/
template BS_TEMPLATE_DEFINITION_ARGS
void
_strreplacall_env(
BASIC_STRING_TEMPLATE & s,
size_t pos
) {
const BASIC_STRING_TEMPLATE ENV_VAR = "$ENV(";
unsigned int envBegPos = s.find(ENV_VAR, pos);
unsigned int envEndPos;
if (envBegPos != STRING_NPOS) {
envEndPos = s.find(')', envBegPos+1);
if (envEndPos != STRING_NPOS) {
BASIC_STRING_TEMPLATE envVarName(s.substr(envBegPos+strlen_templ(ENV_VAR), envEndPos-envBegPos-strlen_templ(ENV_VAR)));
assertWithMsg(sizeof(CharT) == sizeof(char), "Double check the use of getenv() with wchar.");//lint !e506: Constant value Boolean
CharT pEnv = getenv(envVarName.c_str());
BASIC_STRING_TEMPLATE envVarValue("");
if (pEnv != NULL) {
envVarValue = pEnv;
}
_strreplacall_env(s, (size_t)envEndPos + 1);
s = s.substr(0, envBegPos) +
envVarValue +
s.substr(envEndPos + 1);
}
}
}
/*@}*/
/* ----------------------------------------------------------------------- */
/** @name Sanitizing (special char removal) */
/* ----------------------------------------------------------------------- */
/*@{*/
#if defined(UNDECLARED_FUNCTION_TEMPLATES_LINK_BUG)
// To work around "unsatisfied symbols" during linking,
// we need a declaration in addition to the definition below
template BS_TEMPLATE_DEFINITION_ARGS
void
sanitzeString(
BASIC_STRING_TEMPLATE & s
);
#endif
/**
Replaces all occurences of CharT not in [A-Za-z0-9] in a string with '_'.
This is useful in creating valid filenames from strings,
a mutating version.
@param s (Output) The string to replace chars in.
*/
template BS_TEMPLATE_DEFINITION_ARGS
void
sanitzeString(
BASIC_STRING_TEMPLATE & s
) {
for (unsigned int i = 0; i < s.length(); i++) {
if ( ! isalnum_templ(s[i]) ) {
s[i] = '_';
}
}
}
/*---------------------------------------------------------------------------*/
#if defined(UNDECLARED_FUNCTION_TEMPLATES_LINK_BUG)
// To work around "unsatisfied symbols" during linking,
// we need a declaration in addition to the definition below
template BS_TEMPLATE_DEFINITION_ARGS
BASIC_STRING_TEMPLATE
sanitzeString_copy(
const BASIC_STRING_TEMPLATE & s
);
#endif
/**
Replaces all occurences of CharT not in [A-Za-z0-9] in a string with '_'.
This is useful in creating valid filenames from strings,
a copy version.
@param s The string to replace chars in.
@return The sanitized string.
*/
template BS_TEMPLATE_DEFINITION_ARGS
BASIC_STRING_TEMPLATE
sanitzeString_copy(
const BASIC_STRING_TEMPLATE & s
) {
BASIC_STRING_TEMPLATE s1(s);
sanitzeString(s1);
return s1;
}
/*@}*/
/* ----------------------------------------------------------------------- */
/** @name vector to/from delimited string conversion routines */
/* ----------------------------------------------------------------------- */
/*@{*/
#if defined(UNDECLARED_FUNCTION_TEMPLATES_LINK_BUG)
// To work around "unsatisfied symbols" during linking,
// we need a declaration in addition to the definition below
template BS_TEMPLATE_DEFINITION_ARGS
size_t
delimitedString2Vector(
vector< BASIC_STRING_TEMPLATE > & vecStrOutput,
const BASIC_STRING_TEMPLATE & crstrInput,
const CharT* cpszDelimiters,
bool bTrimString,
bool bInsertEmptyStrings
);
#endif
/**
Splits a delimited string into pieces and stores the results in a vector
of strings. Delimiters are passed as a zero-terminated string.
@param rvecstrOutput (Output) The vector where the results are stored.
@param crstrInput The delimited string to split.
@param cpszDelimiters The delimiters (CharT* interpreted as a set of delimiters).
@param bTrimString Flag: If true, all pieces will be trimmed before storing in <TT>storeVar</TT>
@param bInsertEmptyStrings Flag: If false, pieces that have length 0 will not be stored in <TT>storeVar</TT>
@return The number of strings added to <TT>rvecstrOutput</TT>
*/
template BS_TEMPLATE_DEFINITION_ARGS
size_t
delimitedString2Vector(
std::vector< BASIC_STRING_TEMPLATE > & rvecstrOutput,
const BASIC_STRING_TEMPLATE & crstrInput,
const CharT* cpszDelimiters,
bool bTrimString,
bool bInsertEmptyStrings
) {
size_t uiBegin = 0;
size_t uiEnd;
size_t uiNumFound = 0;
if (crstrInput.length() == 0) {
return 0;
}
BASIC_STRING_TEMPLATE _s;
while (uiBegin != STRING_NPOS) {
// uiBegin--;
uiEnd = crstrInput.find_first_of(cpszDelimiters, uiBegin+1);
if (uiEnd != STRING_NPOS) {
uiEnd = crstrInput.find_first_not_of(cpszDelimiters, uiEnd+1);
}
if (uiEnd == STRING_NPOS) {
uiEnd = crstrInput.length()+1;
}
_s = crstrInput.substr(uiBegin, uiEnd-uiBegin-1);
if (bTrimString) {
_s = strtrim(_s);
}
if (bInsertEmptyStrings || _s.length() > 0) {
rvecstrOutput.push_back(_s);
uiNumFound++;
}
uiBegin = crstrInput.find_first_not_of(cpszDelimiters, uiEnd);
}
return uiNumFound;
}
#if defined(UNDECLARED_FUNCTION_TEMPLATES_LINK_BUG)
// To work around "unsatisfied symbols" during linking,
// we need a declaration in addition to the definition below
template BS_TEMPLATE_DEFINITION_ARGS
size_t
delimitedStr2Vectorx(
vector< BASIC_STRING_TEMPLATE > & rvecstrOutput,
const BASIC_STRING_TEMPLATE & crstrInput,
const BASIC_STRING_TEMPLATE & crstrDelimiters,
bool bTrimString,
bool bInsertEmptyStrings
);
#endif
/**
Splits a delimited string into pieces and stores the results in a vector
of strings. Delimiters are passed as string object.
@param rvecstrOutput (Output) The vector where the results are stored.
@param crstrInput The delimited string to split.
@param cpszDelimiters The delimiters (CharT* interpreted as a set of delimiters)
@param bTrimString Flag: If true, all pieces will be trimmed before storing in <TT>storeVar</TT>
@param bInsertEmptyStrings Flag: If false, pieces that have length 0 will not be stored in <TT>storeVar</TT>
@return The number of strings added to <TT>rvecstrOutput</TT>
*/
template BS_TEMPLATE_DEFINITION_ARGS
size_t
delimitedStr2Vectorx(
std::vector< BASIC_STRING_TEMPLATE > & rvecstrOutput,
const BASIC_STRING_TEMPLATE & crstrInput,
const BASIC_STRING_TEMPLATE & crstrDelimiters,
bool bTrimString,
bool bInsertEmptyStrings
) {
return delimitedStr2Vector(rvecstrOutput, crstrInput, crstrDelimiters.c_str(), bTrimString, bInsertEmptyStrings);
}
/*---------------------------------------------------------------------------*/
#if defined(UNDECLARED_FUNCTION_TEMPLATES_LINK_BUG)
// To work around "unsatisfied symbols" during linking,
// we need a declaration in addition to the definition below
template BS_TEMPLATE_DEFINITION_ARGS
BASIC_STRING_TEMPLATE
vector2delimitedStr(
const vector<BASIC_STRING_TEMPLATE>& v,
const BASIC_STRING_TEMPLATE & delimiters
);
#endif
/**
Concatenates the strings in a vector of strings into one long string
using a specified delimiter.
@param v The vector of strings to concatenate.
@param delimiters The delimiter CharT(s) to insert between members of v.
@return The concatenated string.
*/
template BS_TEMPLATE_DEFINITION_ARGS
BASIC_STRING_TEMPLATE
vector2delimitedStr(
const std::vector< BASIC_STRING_TEMPLATE >& v,
const BASIC_STRING_TEMPLATE & delimiters
) {
BASIC_STRING_TEMPLATE s;
typename std::vector< BASIC_STRING_TEMPLATE >::const_iterator it;
for (it = v.begin(); it != v.end(); ++it) {
s += *it;
if (it != v.end() -1) {
s += delimiters;
}
}
return s;
}
/*---------------------------------------------------------------------------*/
#if defined(UNDECLARED_FUNCTION_TEMPLATES_LINK_BUG)
// To work around "unsatisfied symbols" during linking,
// we need a declaration in addition to the definition below
template BS_TEMPLATE_DEFINITION_ARGS
int
bracketedStr2Vector(
vector<BASIC_STRING_TEMPLATE>& storeVar,
const BASIC_STRING_TEMPLATE & s,
const CharT* openBracket,
const CharT* closeBracket
);
#endif
/**
Splits a string delimited by brackets into pieces and stores the results in
a vector of strings.
This is useful for LISP like structures such as <TT>(adf)(eds)</TT>
@param storeVar (Output) The vector where the results are stored.
@param str The delimited string to split.
@param openBracket The opening delimiter. CharT* is interpreted as a string.
@param closeBracket The closing delimiter. CharT* interpreted as a string.
@return The number of strings added to <TT>storeVar</TT>
*/
template BS_TEMPLATE_DEFINITION_ARGS
int
bracketedStr2Vector(
std::vector< BASIC_STRING_TEMPLATE > & storeVar,
const BASIC_STRING_TEMPLATE & s,
const CharT* openBracket,
const CharT* closeBracket
) {
assert(EXISTS(openBracket));
assert(EXISTS(closeBracket));
if (s.length() == 0) {
return 0;
}
int begin;
int end;
int openLen = (int)strlen_templ(openBracket); //lint !e668 Possibly passing a null pointer to function
int closeLen = (int)strlen_templ(closeBracket); //lint !e668 Possibly passing a null pointer to function
int numFound = 0;
begin = (int)s.find(openBracket);
if (begin == (int)STRING_NPOS) {
begin = -openLen+1;
}
while (begin != (int)STRING_NPOS) {
begin+=openLen;
end = (int)s.find(closeBracket, (size_t)(begin+openLen));
if (end == (int)STRING_NPOS) {
end = (int)s.length()+1;
}
storeVar.push_back(trimString(s.substr((size_t)begin, (size_t)(end-begin))));
numFound++;
begin = (int)s.find(openBracket, (size_t)(end+closeLen));
}
return numFound;
}
/*@}*/
} //namespace uima
#endif /* UIMA_STRTOOLS_HPP */
/* <EOF> */