VIZ++ Class: String

 VIZ++ Class Library  VIZ++ Samples  VIZ++ ClassTree 

Source code

/*
 * String.h 
 * Copyright (c) 2015 Antillia.com TOSHIYUKI ARAI. ALL RIGHTS RESERVED. 
 */


// VIZ++2000
// 1999.09.03 Added a constructor to take a pointer to String.
// 2000/11/11
// 2008/07/07 Modified to define all methods in header file.

// 2009/04/09 Modified to call SecureZeroMemory in private clear() method which 
// can be called in Destructor.
// 2009/04/09 Added a method secureClear() to call SecureZeroMemory 
// and delete the memory area.
// 2009/04/10 Added a method bool isEmpty().

// 2009/10/08 Modified to use TCHAR instead of char.
// 2012/03/07 Updated Constructor to allow a shallowCopy
// 2012/04/10 Added 'contains' and 'split' methods.
// 2016/02/28 Added getCharString method.

#pragma once
#include <viz++\Object.h>

#include <viz++\OutOfMemoryException.h>
#include <viz++\NullPointerException.h>
#include <viz++\OutOfRangeException.h>
#include <viz++\InvalidArgumentException.h>
#include <viz++\StringConverter.h>
#include <viz++/StringT.h>

namespace VIZ {

class String :public Object {
private:
  int    length;
  TCHAR*  text;
  
private:
  bool copy(const TCHAR* string)
  {
    bool rc = false;
    if (string != NULL) {
      int len = strlen(string);

      TCHAR* temp = new TCHAR[len+1];
      if(temp) {
        strcpy_s(temp, len+1, string);
        if(this->text != string && this->text !=NULL) {
          //_soltrace("String::copy,1,delete text\n");
          delete [] this->text;
        }
        this->text = temp;
        this->length = len;
        rc = true;
      } else {
        //Memory allocation error.
      }
    }
    return rc;
  }

public:
  /**
   */
  String()
    :length(0),
    text(NULL)
  {
    //_soltrace("String::String()\n");
  }

public:
  //2012/03/07 
  String(const TCHAR* string, bool deepCopy=true)
  :length(0),
  text(NULL) 
  {   
    if (string) {
      if (deepCopy) {
        if (copy(string) == false) {
          throw OutOfMemoryException("String::String,1,Failed to create a string");
        }
      } else {
        shallowCopy((TCHAR*)string);
      }
    }
  }
public:
  // 2011/01/31 Added new constructor.
  // The first array parameter can be an array of non-NULL terminated TCHAR.
  // The second len parameter specifies a length of the array of the string parameter.
  String(TCHAR* array, int len)
  :length(0),
  text(NULL) 
  {
    // Create an NULL-termiinated TCHAR string of length len.
    deepCopy(array, len);
  }


#ifndef UNICODE 
public:
  String(const wchar_t* wstring, bool deepCopy=true)
  :length(0),
  text(NULL) 
  {   
    if (wstring) {
      StringConverter converter;
      StringT<char> cstring; 
      converter.toMultiByte(wstring, cstring);
      const char* str = (const char*)cstring; 
      if (deepCopy) {
        if (copy(str) == false) {
          throw OutOfMemoryException("String::String,1,Failed to create a string");
        }
      } else {
        shallowCopy((char*)str);
      }
    }
  }
#endif


#ifdef UNICODE
public:
 
  String(const char* string, bool deepCopy=true)
  :length(0),
  text(NULL) 
  {   
    if (string) {
      StringConverter converter;
      StringT<wchar_t> wstring;
      
      converter.toWideChar(string, wstring);
      const wchar_t* str = (const wchar_t*)wstring;
      if (deepCopy) {
        if (copy(str) == false) {
          throw OutOfMemoryException("String::String,1,Failed to create a string");
        }
      } else {
        shallowCopy((wchar_t*)str);
      }
    }
  }
#endif

// 1999.09.03 Added

public:
  String(const String* string)
  :length(0),
  text(NULL) 
  {   
    if (string) {
      const TCHAR*  str = string->getContents();
      if (str == NULL) {
        return;
      }
      else {
        if (copy(str) == false) {
          throw OutOfMemoryException("String::String,2,Failed to create a string");
        }
      }
    }
  }


public:
  String(const String& string)
  :length(0),
  text(NULL)
  {
    //this->length = string.getLength();
    //this->text = NULL;
    const TCHAR* str = (const TCHAR*)string;
    if (str == NULL) {
      return;
    } else {
      if (copy(str) == false) {
        throw OutOfMemoryException("Failed to create a string");
      }
    }
  }

public:
  String(const StringT<char>& string)
  :length(0),
  text(NULL)
  {
    //this->length = string.getLength();
    //this->text = NULL;
    const char* cstring  = (const char*)string;
    if (cstring == NULL) {
      return;
    }
    else {
#ifdef UNICODE
      StringConverter converter;

      StringT<wchar_t> wstring;
      converter.toWideChar(cstring, wstring);
      const wchar_t* str = (const wchar_t*)wstring;
#else 
      const char* str = cstring;
#endif
    
      if (copy(str) == false) {
        throw OutOfMemoryException("Failed to create a string");
      }
    }
  }


public:
  String(const StringT<wchar_t>& string)
  :length(0),
  text(NULL)
  {
    //this->length = string.getLength();
    //this->text = NULL;
    const wchar_t* wstring  = (const wchar_t*)string;
    if (wstring == NULL) {
      return;
    }
    else {
#ifdef UNICODE
      const wchar_t* str = wstring;

#else 
      StringConverter converter;

      StringT<char> cstring;
      converter.toMultiByte(wstring, cstring);
      const char* str = (const char*)cstring;

#endif
    
      if (copy(str) == false) {
        throw OutOfMemoryException("Failed to create a string");
      }
    }
  }

public:
  ~String() { 
    clear();
  }

  //2012/06/05
public:
  // 2009/04/09 Modiffied to call SecureZeroMemory
  void clear() { 
    if (this->text) {
      //2009/04/09
      SecureZeroMemory(this->text, this->length);
      delete [] this->text;
    }
    this->text =NULL;
    this->length = 0;
  }

public:
  // 2009/04/09 Call SecureZeroMemory() and  delete the memory area
  void secureClear() { 
    if (this->text) {
      SecureZeroMemory(this->text, this->length);
      delete [] this->text;
    }
    this->text =NULL;
    this->length = 0;
  }

public:
  TCHAR*   getContents() const { 
    return this->text; 
  }

public:
  int     getLength() const  { 
    return this->length; 
  }

public:
  //2009/04/10
  bool isEmpty() {
    bool rc = false;
    if (this->length>0 && this->text !=NULL) {
      rc = true;
    }
    return rc;
  }


public:
  operator TCHAR*() const{
    return this->text;
  }

public:
  operator const TCHAR*() const{
    return this->text;
  }

public:
  String& operator=(const TCHAR* string)
  { 
    _soltrace("String::operator=(const TCHAR*)\n");
    if (string != NULL) {
      if(copy(string) == false) {
        throw OutOfMemoryException("Failed to substitue a string");
      }
    }
    return *this;
  }

#ifdef UNICODE
public:
  String& operator=(const char* string)
  { 
    //_soltrace("String::operator=(const TCHAR*)\n");
    if (string != NULL) {
      StringConverter converter;
      StringT<wchar_t> wstring;
      converter.toWideChar(string, wstring);

      const wchar_t* str = (const wchar_t*)wstring;
      if(copy(str) == false) {
        throw OutOfMemoryException("Failed to substitue a string");
      }
    }
    return *this;
  }
#endif

#ifndef UNICODE
public:
  String& operator=(const wchar_t* wstring)
  { 
    //_soltrace("String::operator=(const TCHAR*)\n");
    if (wstring != NULL) {
      StringConverter converter;
      StringT<char> cstring;
      converter.toMultiByte(wstring, cstring);
      const char* str = (const char*)cstring;
      if(copy(str) == false) {
        throw OutOfMemoryException("Failed to substitue a string");
      }
    }
    return *this;
  }
#endif

public:
  //2011/01/28
  // The string parameter can be non-NULL terminated.
  void deepCopy(TCHAR* string, int slength)
  {
    if (string != NULL && slength>0) {
      if (this->text != string) {
        clear();
      }
      int len = slength;

      TCHAR* temp = new TCHAR[len+1];
      memcpy(temp, string, len);
      temp[len] = NULL;  //Put a NULL char at this len position to make a NULL terminated string
      this->text = temp;
      this->length = len;
    } else {
      clear();

      this->text   = NULL;
      this->length = 0;
    }
  }

public:
  void shallowCopy(TCHAR* string)
  { 
    // Accept a string of NULL
    _soltrace("String::shallowCopy(const TCHAR*)\n");
    if (string) {
      if (this->text != string) {
        clear();
      }
      this->text   = string;
      this->length = strlen(string);
    }
    else {
      clear();

      this->text   = string;  //NULL
      this->length = 0;
      //throw InvalidArgumentException("String::shallowCopy,InvalidArgument");
    }    
  }

public:
  String& operator=(const String& string)
  {        
    _soltrace("String::operator=(const String&)\n");

    //this->length = string.getLength();
    TCHAR* str = string.getContents();
    if (str) {
      if (copy(str) == false) {
        throw OutOfMemoryException("Failed to substitue a string");
      }
    } else {
      //str = NULL;
      clear();

      this->text = str;
      this->length = 0;
    }
    return *this;
  }

public:
  int operator==(const TCHAR* string)
  {
    int rc = 0;
    if (this->text == NULL && string ==NULL) {
      rc = 1;
    }

    //2008/07/08
    if (this->text != NULL && string != NULL) {
      if(strcmp(this->text, string) == 0) {
        rc = 1;
      }
    }
    return rc;
  }


  //int operator==(String& string)
public:
  int operator==(String& string)
  {
    int rc = 0;
    const TCHAR* str = (const TCHAR*)string;
    if (this->text == NULL && str ==NULL) {
      rc = 1;
    }

    if (this->text != NULL && str != NULL) {
      if(strcmp(this->text, str) == 0) {
        rc = 1;
      }
    }
    return rc;
  }

public:
  String& operator+(const TCHAR* string)
  {
    if(string == NULL) {
      return *this;
    }

    this->length += strlen(string);
    TCHAR* temp = new TCHAR[this->length+1];
    _stprintf_s(temp, this->length+1, _T("%s%s"), this->text, string);
    /*
    */
    if(this->text != string) {
      delete [] text;
    }
    text = temp;
    return *this;
  }

#ifdef UNICODE
public:
  String& operator+(const char* string)
  {
    if(string == NULL) {
      return *this;
    }
    StringConverter converter;
    wchar_t* wstring = converter.toWideChar(string);

    this->length += strlen(wstring);
    wchar_t* temp = new wchar_t[this->length+1];
    _stprintf_s(temp, this->length+1, _T("%s%s"), this->text, wstring);

    if(this->text != wstring) {
      delete [] text;
    }
    text = temp;

    delete [] wstring;

    return *this;
  }
#endif

#ifndef UNICODE
public:
  String& operator+(const wchar_t* wstring)
  {
    if(wstring == NULL) {
      return *this;
    }
    StringConverter converter;
    const char* cstring = converter.toMultiByte(wstring);

    this->length += strlen(cstring);
    char* temp = new char[this->length+1];
    sprintf_s(temp, this->length+1, "%s%s", this->text, cstring);

    if(this->text != temp) {
      delete [] text;
    }
    text = temp;

    delete [] cstring;

    return *this;
  }
#endif

public:
  int compare(Object* object)
  {
    int rc = 0;
    if (object==NULL) {
      return rc;
    }

    String* string = (String*)object;
    const TCHAR* p1 = this->text;

    const TCHAR* p2 = (const TCHAR*)(*string);
    if (p1 == NULL && p2 == NULL) {
      rc = 1;
    }
    if (p1 != NULL && p2 != NULL) {
      rc = strcmp(p1, p2);
    }
    return rc;
  }

  //2012/04/20
public:
  float toFloat()
  {
    float f = 0.0f;
    if (this->text) {
      f = (float)_ttof(this->text);
    }
    return f;
  }

  //2012/04/20
public:
  double toDouble()
  {
    double f = 0.0f;
    if (this->text) {
      f = _ttof(this->text);
    }
    return f;
  }

public:
  //2012/04/20
  int toInteger()
  {
    int f = 0;
    if (this->text) {
      f = _ttoi(this->text);
    }
    return f;
  }

public:
  //2012/04/10
  bool contains(const TCHAR* string)  
  {
    bool rc = false;
    if (find(string)) {
      rc = true;
    }
    return rc;
  }

public:
  const TCHAR* find(const TCHAR* string)  
  {
    const TCHAR* ptr = NULL;
    if (this->text && string) {
      ptr = strstr(this->text, string);
    }
    return ptr;
  }

public:
  int split(__in const TCHAR ch, __out String& string1, __out String& string2)  
  {
    int rc = 0;

    if (this->text) {
      TCHAR* ptr = (TCHAR*)strchr(this->text, ch);
      if (ptr) {
        int len1 = ptr - text;
        if (len1 > 0) {
          string1.deepCopy(text, len1);
          //_tprintf(_T("1=[%s]\n"), (const TCHAR*)string1);
          rc++;
        }
      
        int len2 = this->length - len1-1;
        if (len2 > 0) {
          string2.deepCopy(++ptr, len2);
          //_tprintf(_T("2=[%s]\n"), (const TCHAR*)string2);
          rc++;
        }
      }
    }
    return rc;
  }

public:
  int replace(TCHAR oc, TCHAR nc)
  {
    int  n = 0;
    if (this->text) {
      for (int i = 0; i<this->length; i++) {
        if (text[i] == oc) {
          text[i] = nc;
          n++;
        }
      }
    }
    return n;
  }
public:
  //2009/11/16
  bool removeBackSlash()
  {
    bool rc = false;
    if (this->text && this->length>0) {
      if (this->text[this->length-1] == '\\') {
        this->text[this->length-1] = '\0';
        this->length--;
        rc = true;
      }
    }
    return rc;
  }


//<added date="2000/11/10">
public:
  String& operator+(TCHAR ch)
  {
    TCHAR string[80];
    //sprintf_s(string, sizeof(string), "%c", ch);
    string[0] = ch;
    string[1] = (TCHAR)0;//ZERO;

    return String::operator+(string);
  }

public:
#ifdef UNICODE
  String& operator+(char ch)
  {
    TCHAR string[80];
    //sprintf_s(string, sizeof(string), "%c", ch);
    string[0] = (TCHAR)ch;
    string[1] = (TCHAR)0;//ZERO;

    return String::operator+(string);
  }
#endif

public:
  String& operator+(int num)
  {
    TCHAR string[80];
    _stprintf_s(string, CountOf(string), _T("%d"), num);

    return String::operator+(string);
  }

public:
  bool equals(const TCHAR* str) {
    bool rc = false;
    if(this->text != NULL && str != NULL) {
        if(strcmp(this->text, str) == 0) {
             rc = true;
      }
    }
    return rc;
  }

public:
  bool equals(const String& str) {
    return equals((const TCHAR*)str);
  }

public:
  bool equalsIgnoreCase(const TCHAR* str) const {
    bool rc = false;

    if(this->text != NULL && str != NULL) {
      //strcmpi -> stricmp
        if(_stricmp(this->text, str) == 0) {
             rc = true;
      }
    }
    return rc;
  }

public:
  bool equalsIgnoreCase(const String& str) const {
    return equalsIgnoreCase((const TCHAR*)str);
  }

public:
  String& operator+(float num)
  {
    TCHAR string[80];
    _stprintf_s(string, CountOf(string), _T("%f"), num);

    return String::operator+(string);
  }

public:
  void trim()
  {
    TCHAR* rt = String::trim(this->text);

    if (rt) {
      clear();
      //Shallow copy
      this->text = rt;
      this->length = strlen(rt);
    }
  }

public:
  void trimOnNewLine() {
    if (this->text) {
      TCHAR* ptr = (TCHAR*)strstr(this->text, _T("\r\n"));
      if (ptr) {
        //Terminate this text on this ptr position by putting '\0';
        *ptr = '\0';
        this->length = strlen(this->text);
      }
    }
  }


public:
  /**
   */  
  bool   startsWith(const TCHAR* start) {
    return String::startsWith(this->text, start);
  }

public:
  /**
   */  
  bool   startsWithIgnoreCase(const TCHAR* start) {
    return String::startsWithIgnoreCase(this->text, start);
  }

public:
  /**
   */  
  bool   endsWith(const TCHAR* end) {
    return String::endsWith(this->text, end);
  }

public:
  /**
   */  
  bool   endsWithIgnoreCase(const TCHAR* end) {
    return String::endsWithIgnoreCase(this->text, end);
  }

public:
  //2009/11/12
  const TCHAR* findLast(const TCHAR* string)
  {
    return String::findLast(this->text, string);
  }

public:
  //2009/11/12
  static const TCHAR* findLast(const TCHAR* text, const TCHAR* string)
  {
    const TCHAR* ptr = NULL;

    if (text && string) {
      int tlen = strlen(text);
      int slen = strlen(string);
      if (tlen < slen) {
        return ptr;
      } else {
        for(int i = tlen - slen; i>=0; i--) {
          int n= strncmp(text + i, string, slen);
          if (n == 0) {
            ptr = text + i;
            break;
          }
        }
      }  
    }
    return ptr;
  }

public:
  //2009/11/12
  const TCHAR* findFirst(const TCHAR* string) {
    return String::findFirst(this->text, string);    
  }

public:
  //2009/11/12
  static const TCHAR* findFirst(const TCHAR* text, const TCHAR* string) {
    const TCHAR* ptr = NULL;
    if (text && string) {
      ptr = strstr(text, string);
    }
    return ptr;
  }


public:
  TCHAR&    operator[](int n) 
  {
    if (this->text == NULL) {
      throw NullPointerException("String::operator[] - Text is NULL");
    }
    if (n <=0 || n>this->length) {
      throw OutOfRangeException("String::operator[] - Index is out of range");
    }
    
    return text[n]; 
  }


public:
  // If UNICODE environment, then this->text is wcstring.
  //  convert it to mbstring and return it to parameter string.
  // If not, then this->text is mbstring, and return it to parameter string. 
  // 2009/10/26 Addecd cnst
  bool getString(__out StringT<char>& tstring) const
  {
    bool rc = false;

    if (text == NULL) {
      return rc;      
    }
#ifdef UNICODE
    
    wchar_t* wcstring = text;
    
    int cb = WideCharToMultiByte(CP_ACP, 0, 
        wcstring, -1, NULL, 0, NULL, NULL);
    
    if (cb > 0) {
      char* mbstring = new char[cb];
      mbstring[0] = ZERO;
      WideCharToMultiByte(CP_ACP, 0, wcstring, -1, mbstring, cb, NULL, NULL);
      tstring.shallowCopy(mbstring);
      rc = true;
    }

#else 
    //2009/11/01
    tstring = (char*)text;
    rc = true;
#endif

    return rc;
  }

public:
  // If UNICODE environment, then this->text is wcstring.
  //  convert it to mbstring and return it to parameter string.
  // If not, then this->text is mbstring, and return it to parameter string. 
  // 2016/02/27 Addecd cnst
  StringT<char> getCharString() const
  {
    if (text == NULL) {
      return StringT<char>("");      
    }
#ifdef UNICODE
    
    wchar_t* wcstring = text;
    
    const int cb = WideCharToMultiByte(CP_ACP, 0, 
        wcstring, -1, NULL, 0, NULL, NULL);
    
    if (cb > 0) {
      char* mbstring = new char[cb];
      mbstring[0] = ZERO;
      WideCharToMultiByte(CP_ACP, 0, wcstring, -1, mbstring, cb, NULL, NULL);
      //Specify shallow copy flag to be false, because we allocae mbstring above,
      return StringT<char>((const char*)mbstring, false);
    }

#else 
    return StringT<char>((char*)text);
#endif
    return StringT<char>("");
  }

public:
  // If UNICODE environment, then this->text is wcstring.
  //  and return it to parameter string.
  // If not, then this->text is mbstring, and return convert it to
  // wcstring and return it to parameter string. 
  // 2009/10/26 Addecd cnst
  bool getString(__out StringT<wchar_t>& tstring) const
  {
    bool rc = false;

    if (text == NULL) {
      return rc;      
    }

#ifdef UNICODE
    tstring = text;
    rc = true;
#else 
    rc = true;
    char* mbstring = text;
    int cb = MultiByteToWideChar(CP_ACP, 0, mbstring, -1, NULL, 0); 
    if (cb >0) {
      wchar_t* wcstring = new wchar_t[cb];
      wcstring[0] = ZERO;
      MultiByteToWideChar(CP_ACP, 0, mbstring, -1, wcstring, cb);
      tstring.shallowCopy(wcstring);
      rc = true;
    }
#endif

    return rc;
  }


//////////////////////////////////////////////////////////////////
//@static methods

public:
  static char* trim(__in char* string) {
    if (string == NULL) {
      return NULL;
    }
    
    size_t slen = strlen(string)+1;

    char* temp = new char[slen];
    strcpy_s(temp, slen, string);
    char* p = temp;

    while (*p == ' ' || *p == '\t' || *p =='\r' || *p=='\n') {
      p++;
    }

    char* t = p + strlen(p) -1;
    while (*t == ' ' || *t == '\t' || *t =='\r' || *t=='\n') {
      if (p == t) break;
      *t = '\0';
      t--;
    }

    size_t plen = strlen(p)+1;
    char* rt = new char[plen];
    strcpy_s(rt, plen, p);

    delete [] temp;

    return rt;
  }

public:
  static wchar_t* trim(__in wchar_t* string) {
    if (string == NULL) {
      return NULL;
    }
    
    size_t slen = strlen(string)+1;

    wchar_t* temp = new wchar_t[slen];
    strcpy_s(temp, slen, string);
    wchar_t* p = temp;

    while (*p == ' ' || *p == '\t' || *p =='\r' || *p=='\n') {
      p++;
    }

    wchar_t* t = p + strlen(p) -1;
    while (*t == ' ' || *t == '\t' || *t =='\r' || *t=='\n') {
      if (p == t) break;
      *t = '\0';
      t--;
    }

    size_t plen = strlen(p)+1;
    wchar_t* rt = new wchar_t[plen];
    strcpy_s(rt, plen, p);

    delete [] temp;

    return rt;
  }

public:
  static bool trim(__in TCHAR* string, __out String& tstring) {
    bool rc = false;
    if (string == NULL) {
      return rc;
    }

    TCHAR* trimmed = trim(string);
    if (trimmed) {
      tstring = trimmed;
    }
    return rc;
  }
public:
  static bool trim(__in char* string, __out StringT<char>& tstring) {
    bool rc = false;
    if (string == NULL) {
      return rc;
    }

    char* trimmed = trim(string);
    if (trimmed) {
      tstring.shallowCopy(trimmed);
    }
    return rc;
  }

public:
  static bool trim(__in wchar_t* string, __out StringT<wchar_t>& tstring) {
    bool rc = false;
    if (string == NULL) {
      return rc;
    }

    wchar_t* trimmed = trim(string);
    if (trimmed) {
      tstring.shallowCopy(trimmed);
    }
    return rc;
  }

public:
  /**
   * 
   * @param string  
   * @param start
   * @return bool
   */  
  static bool  startsWith(__in const char* string, __in const char* start) {
    bool rc = false;
    if (string != NULL && start != NULL) {
      if (strncmp(string, start, strlen(start)) ==0) {
        rc = true;
      }
    }
    return rc;
  }

public:
  static bool  startsWith(__in const wchar_t* string, __in const wchar_t* start) {
    bool rc = false;
    if (string != NULL && start != NULL) {
      if (strncmp(string, start, strlen(start)) ==0) {
        rc = true;
      }
    }
    return rc;
  }

public:
  /**
   * 
   * @param string
   * @param start
   * @return bool
   */  
  static bool  startsWithIgnoreCase(__in const char* string, __in const char* start) {
    bool rc = false;
    if (string != NULL && start != NULL) {
      if (_strnicmp(string, start, strlen(start)) ==0) {
        rc = true;
      }
    }
    return rc;
  }

public:
  static bool  startsWithIgnoreCase(__in const wchar_t* string, __in const wchar_t* start) {
    bool rc = false;
    if (string != NULL && start != NULL) {
  
      if (_strnicmp(string, start, strlen(start)) ==0) {
        rc = true;
      }
    }
    return rc;
  }


public:
  /**
   * 
   * @param string
   * @param end
   * @return bool
   */  
  static bool endsWith(__in const char* string, __in const char* end) {
    bool rc = false;
    if (string != NULL && end != NULL) {
      size_t tlen = strlen(string);
      size_t slen = strlen(end);
      if (tlen >= slen) {
        if (strncmp(string+tlen-slen, end, slen) ==0) {
          rc = true;
        }
      }
    }
    return rc;
  }

public:
  static bool endsWith(__in const wchar_t* string, __in const wchar_t* end) {
    bool rc = false;
    if (string != NULL && end != NULL) {
      size_t tlen = strlen(string);
      size_t slen = strlen(end);
      if (tlen >= slen) {
        if (strncmp(string+tlen-slen, end, slen) ==0) {
          rc = true;
        }
      }
    }
    return rc;
  }

public:
  /**
   * 
   * @param string
   * @param end  
   * @return bool
   */  
  static bool endsWithIgnoreCase(__in const char* string, __in const char* end) {
    bool rc = false;
    if (string != NULL && end != NULL) {
      size_t tlen = strlen(string);
      size_t slen = strlen(end);
      if (tlen >= slen) {
        if (_strnicmp(string+tlen-slen, end, slen) ==0) {
          rc = true;
        }
      }
    }
    return rc;
  }

public:
  static bool endsWithIgnoreCase(__in const wchar_t* string, __in const wchar_t* end) {
    bool rc = false;
    if (string != NULL && end != NULL) {
      size_t tlen = strlen(string);
      size_t slen = strlen(end);
      if (tlen >= slen) {
        if (_strnicmp(string+tlen-slen, end, slen) ==0) {
          rc = true;
        }
      }
    }
    return rc;
  }


};

}


Last modified: 10 Feb 2017

Copyright (c) 2009-2017 Antillia.com ALL RIGHTS RESERVED.