SOL9 2.0 Class: WString

 SOL9 C++ Class Library  SOL9 Samples  SOL9 Tutorial  SOL9 FAQ  SOL9 ClassTree 

Source code

/*
 * WString.h 
 * Copyright (c) 2012 Antillia.com TOSHIYUKI ARAI. ALL RIGHTS RESERVED. 
 */


// SOL++2000/SOL9
// 2009/06/20 String class for wchar_t
// 2011/01/31 Added a Contructor and deepCopy methods.
// 2012/03/07 Updated Constructor to allow a shallowCopy

#pragma once
#include <sol\Object.h>

#include <sol\OutOfMemoryException.h>
#include <sol\NullPointerException.h>
#include <sol\OutOfRangeException.h>
#include <sol\InvalidArgumentException.h>

namespace SOL {

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

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

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

public:
    //2012/03/10 Added the second parameter.
    WString(const wchar_t* string, bool deepCopy=true)
    :length(0),
    text(NULL) 
    {     
        if (string) {
            if (deepCopy) {
                if (copy(string) == false) {
                    throw OutOfMemoryException("WString::WString,1,Failed to create a string");
                }
            } else {
                shallowCopy((wchar_t*)string);
            }
        }
    }

public:
    // 2011/01/31 Added new constructor.
    // The first array parameter can be an array of non-NULL terminated usigned short.
    // The second len parameter specifies a length of the array of the array parameter.
    WString(unsigned short* array, int len)
    :length(0),
    text(NULL) 
    {
        // Create an NULL-termiinated wchar_t string of length len.
        deepCopy(array, len);
    }


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


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


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

private:
    // 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:
    wchar_t*   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 wchar_t*() const{
        return this->text;
    }

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

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

public:
    // string can be non-NULL terminated string.
    void deepCopy(unsigned short* string, int length)
    {
        deepCopy((wchar_t*)(void*)string, length);
    }

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

            wchar_t* temp = new wchar_t[len+1];
            wmemcpy(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;//string;
            this->length = 0;
        }
    }

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

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

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

        //this->length = string.getLength();
        wchar_t* 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 wchar_t* string)
    {
        int rc = 0;
        if (this->text == NULL && string ==NULL) {
            rc = 1;
        }

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


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

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

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

        this->length += wcslen(string);
        wchar_t* temp = new wchar_t[this->length+1];
        swprintf_s(temp, this->length+1, L"%s%s", this->text, string);
    
        if(this->text != string) {
            delete [] text;
        }
        text = temp;
        return *this;
    }

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

        WString* string = (WString*)object;
        const wchar_t* p1 = this->text;

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


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


public:
    int replace(wchar_t oc, wchar_t 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;
    }

//<added date="2000/11/10">
public:
    WString& operator+(wchar_t ch)
    {
        wchar_t string[80];
        swprintf_s(string, SizeOf(string), L"%c", ch);
        return WString::operator+(string);
    }

public:
    WString& operator+(int num)
    {
        wchar_t string[80];
        swprintf_s(string, SizeOf(string), L"%d", num);
        return WString::operator+(string);
    }

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

public:
    bool equals(const WString& str) {
        return equals((const wchar_t*)str);
    }

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

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

public:
    bool equalsIgnoreCase(const WString& str) {
        return equalsIgnoreCase((const wchar_t*)str);
    }

public:
    WString& operator+(float num)
    {
        wchar_t string[80];
        swprintf_s(string, SizeOf(string), L"%f", num);
        return WString::operator+(string);
    }

public:
    void trim()
    {
        wchar_t* rt = WString::trim(this->text);

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

public:
    void trimOnNewLine() {
        if (this->text) {
            wchar_t* ptr = wcsstr(this->text, L"\r\n");
            if (ptr) {
                //Terminate this text on this ptr position by putting '\0';
                *ptr = '\0';
                this->length = wcslen(this->text);
            }
        }
    }


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

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

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

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

public:
    const wchar_t* findLast(const wchar_t* string)
    {
        const wchar_t* ptr = NULL;

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

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


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

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

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

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

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

        delete [] temp;

        return rt;
    }



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

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


public:
    /**
     * 
     * @param string
     * @param end
     * @return bool
     */    

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

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



};

}


Last modified: 1 Apr 2012

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