osncore/osncore/src/alfstring.cpp
author Pat Downey <patd@symbian.org>
Wed, 01 Sep 2010 12:23:18 +0100
branchRCL_3
changeset 26 0e9bb658ef58
parent 0 e83bab7cf002
permissions -rw-r--r--
Revert incorrect RCL_3 drop: Revision: 201033 Kit: 201035

/*
* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description: Osn String Implementation.
*
*/

#if defined(__GNUC__)
#include <string.h>
#include <assert.h>
#else
#include <e32base.h>
#include <libc/string.h>
#include <libc/assert.h>
#endif

#include <stdio.h>
#include <stdarg.h>
#include "osn/alfstring.h"
#include "stringmacros.h"
//#include "char.h"
#include "alfstringdata.h"
//#include "CHARCONV.H"
#include <osn/osnnew.h>
#include <osn/osnbadalloc.h>
#define CHECK_FOR_HANDLE_LEAKS 0

using namespace std;
namespace osncore
    {




#define IS_ASCII_QCHAR(c) ((c).unicode() > 0 && (c).unicode() <= 0xff)




EXPORT_C CAlfString::CAlfString()
    :internalData(new(S60)SAlfStringData())
    {
    }



EXPORT_C CAlfString::~CAlfString()
    {

    if(internalData.get())
        {
        internalData->deref();
        if(internalData->refCount != 0)
            {
            internalData.release(); // don't kill it, we have ref
            }
        }
    }




EXPORT_C CAlfString::CAlfString(const char *chs)
    :internalData(new(S60)SAlfStringData())
    {
    internalData->initialize(chs, strlen(chs));

    }



EXPORT_C CAlfString::CAlfString(const CAlfString &qs)
    :internalData(qs.internalData.get())
    {
    internalData->ref();  
    }

EXPORT_C CAlfString &CAlfString::operator=(const CAlfString &qs)
    {
    if (this == &qs)
        return *this;
    qs.internalData->ref(); // increase source ref count
    internalData->deref();
    if(internalData->refCount != 0)
        {
        internalData.release();
        }
        
    internalData.reset(qs.internalData.get()); 
    return *this;
    }

EXPORT_C  const char* CAlfString::latin1() const
{
	return internalData->ascii();
}



EXPORT_C CAlfString::CAlfString(const char *chs, int len)
    : internalData(new(S60)SAlfStringData())
    {

    internalData->initialize(chs, len);
 
    }

EXPORT_C int CAlfString::compare(const CAlfString& s) const
{
    //if (internalData->_isAsciiValid && s.internalData->_isAsciiValid)
        return strcmp(latin1(), s.latin1());
    //return ucstrcmp(*this,s);
    // return -1;
}


EXPORT_C CAlfString& CAlfString::append(const CAlfString &s)
    {
    return insert(internalData->_length, s);
    }


EXPORT_C CAlfString &CAlfString::insert(uint index, const char *insertChars, uint insertLength)
{
    if (insertLength == 0)
        return *this;

    //detach();

    // if (internalData->_isAsciiValid){
        uint originalLength = internalData->_length;
        char *targetChars;

        // Ensure that we have enough space.
        if( !setLength (originalLength + insertLength) ) 
            {
            throw std::bad_alloc();
            //return *this;    
            }
        
        targetChars = (char *)internalData->ascii();

        // Move tail to make space for inserted characters.
        memmove (targetChars+index+insertLength, targetChars+index, originalLength-index);

        // Insert characters.
        memcpy (targetChars+index, insertChars, insertLength);

        internalData->_isUnicodeValid = 0;
    //}
    /*    
    else if (dataHandle[0]->_isUnicodeValid){
        uint originalLength = dataHandle[0]->_length;
        QChar *targetChars;

        // Ensure that we have enough space.
        if( !setLength (originalLength + insertLength) ) return *this;
        targetChars = (QChar *)unicode();

        // Move tail to make space for inserted characters.
        memmove (targetChars+(index+insertLength), targetChars+index, (originalLength-index)*sizeof(QChar));

        // Insert characters.
        uint i = insertLength;
        QChar *target = targetChars+index;

        while (i--)
            *target++ = *insertChars++;
        }
    else
        FATAL("invalid character cache",0);
        */

    return *this;
}



EXPORT_C CAlfString& CAlfString::insert(uint index, const CAlfString &s)
{
    if (s.internalData->_length == 0)
        return *this;

#ifdef QSTRING_DEBUG_UNICODE
    //forceUnicode();
#endif

    // if (internalData->_isAsciiValid) //&& s.isAllLatin1()
        // {
        insert(index, s.latin1(), s.internalData->_length);
        // }
    /*
    else 
        {
        uint insertLength = qs.dataHandle[0]->_length;
        uint originalLength = dataHandle[0]->_length;
        AlfChar *targetChars;

        // Ensure that we have enough space.
        if( !setLength (originalLength + insertLength) ) return *this;
        targetChars = forceUnicode();

        // Move tail to make space for inserted characters.
        memmove (targetChars+(index+insertLength), targetChars+index, (originalLength-index)*sizeof(QChar));

        // Insert characters.
        if (qs.dataHandle[0]->_isAsciiValid){
            uint i = insertLength;
            AlfChar *target = targetChars+index;
            char *a = (char *)qs.ascii();

            while (i--)
                *target++ = *a++;
        } 
        else {
            AlfChar *insertChars = (AlfChar *)qs.unicode();
            memcpy (targetChars+index, insertChars, insertLength*sizeof(QChar));
        }

        internalData->_isAsciiValid = 0;
        }
    */

    return *this;
}


// Increase buffer size if necessary.  Newly allocated
// bytes will contain garbage.
bool CAlfString::setLength(uint newLen)
{

    if (newLen == 0) {
        //setUnicode(0, 0);
        return true;
    }

    // Missing optimization: Could avoid copying characters we are going to remove
    // by making a special version of detach().
//    detach();

//    ASSERT(dataHandle != shared_null_handle);

/*
#ifdef QSTRING_DEBUG_UNICODE
    forceUnicode();
#endif
*/

    // if (internalData->_isAsciiValid){
        if (newLen+1 > internalData->_maxAscii) {  
            if( internalData->increaseAsciiSize(newLen+1) == false ) return false;
        }
        // Ensure null termination, although newly allocated
        // bytes contain garbage.
        internalData->_ascii[newLen] = 0;
    // }
    /*else if (internalData->_isUnicodeValid){
        if (newLen > internalData->_maxUnicode) {
            if( internalData->increaseUnicodeSize(newLen) == false ) return false;
        }
    }*/
/*    
    else
        FATAL("invalid character cache",0);
*/        

    internalData->_length = newLen;
    return true;
}



EXPORT_C bool CAlfString::operator==(const CAlfString &s1)const
    {
    // if (internalData->_isAsciiValid && s1.internalData->_isAsciiValid) 
    //     {
        return strcmp(latin1(), s1.latin1()) == 0;
    //    }
    // return false;    
    /*    
    return s1.dataHandle[0]->_length == s2.dataHandle[0]->_length
        && memcmp(s1.unicode(), s2.unicode(), s1.dataHandle[0]->_length * sizeof(QChar)) == 0;
        */
    }



}