osncore/osncore/src/alfptrvectorimpl.cpp
author Pat Downey <patd@symbian.org>
Wed, 01 Sep 2010 12:23:18 +0100
branchRCL_3
changeset 20 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 vector pointer implementation.
*
*/

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

#include <osn/alfptrvectorimpl.h>
#include <stdexcept>

namespace osncore
    {

// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
//
OSN_EXPORT AlfPtrVectorImpl::AlfPtrVectorImpl(IDeleter& aDeleter)
    : mdata(0), msize(0), mcount(0), mDeleter(aDeleter)
    {
    }

// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
//
OSN_EXPORT AlfPtrVectorImpl::AlfPtrVectorImpl(uint aSize, IDeleter& aDeleter): 
    mdata(0),
    msize(aSize), 
    mcount(0), mDeleter(aDeleter)
    {
    mdata = (void **)malloc(aSize * sizeof(void *));
    if(!mdata)
        {
        throw std::bad_alloc();    
        }
    memset(mdata, 0, aSize * sizeof(void *));
    }


// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
//
OSN_EXPORT AlfPtrVectorImpl::~AlfPtrVectorImpl()
{
    free(mdata);
}

// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
//
OSN_EXPORT void AlfPtrVectorImpl::clear(bool aDelItems)
    {
    mcount = 0;
    
    if (aDelItems) 
        {
    	for (uint i = 0; i < msize; ++i) 
    	    {
            void *item = mdata[i];
    	    if (item) 
    	        {
    		    mDeleter.deleteItem(item);
    	        }
    	}
	}
    free(mdata);
    mdata = 0;
    msize = 0;    
    }

// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
//
OSN_EXPORT bool AlfPtrVectorImpl::remove(uint aCount, bool aDelItems)
{
    if (aCount >= msize) {
        return false;
    }
    
    void *item = mdata[aCount];

    --mcount;

    //Move all the items below the deleted items up by 1 index
    for(uint i =aCount; i< msize && msize > aCount;++i)
    {
    	mdata[i]= mdata[i+1];
    }

    //Reset the items to null - from index = count to the size  after the shuffling.
    for(uint i=mcount;i<msize;++i)
    {
    	mdata[i] = 0;
    }

    // Array is now in good shape. Can call out of the class via destructors
    if (item) {
        if (aDelItems) {
            mDeleter.deleteItem(item);
        }
    }     
    return true;
}

// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
//
OSN_EXPORT bool AlfPtrVectorImpl::resize(uint aSize, bool aDelItems)
{
    uint oldSize = msize;
    
    for (uint i = aSize; i < oldSize; ++i) {
        void *item = mdata[i];
        if (item) {
            --mcount;
        }
    }
    
    for (uint i = aSize; i < oldSize; ++i) {
    	void *item = mdata[i];
    	if (item) {
        if (aDelItems) {
           mDeleter.deleteItem(item);
        	}
    	}
    }
    
    void** data = (void **)realloc(mdata, aSize * sizeof(void *));
    if(!data)
        {
        throw std::bad_alloc();    
        }
    mdata = data;    
    msize = aSize;    

    if (aSize > oldSize) 
    {
        memset(&mdata[oldSize], 0, (aSize - oldSize) * sizeof(void *));
    }
    return true;
}

// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
//
OSN_EXPORT bool AlfPtrVectorImpl::insert(uint aCount, void *aItem, bool /*aDelItems*/)
{
	uint iNum=0;
	//If there are no items and  the position to add > 0 or <0 then  return false. Do not do anything
	//if the Index is greater than the current count then Do not do anything
	//if aCount== count There will be scope to add at the most one item
	if((aCount > mcount) || (mcount==0 && aCount >iNum)||(mcount==0 && aCount < iNum))
           {
    	   return false;
           } 

	
	if(mcount>=msize)
    	{
		// 1. Let's increase the count
		int oldSize = msize;	
	    msize++;
	
		// 2. Re-allocate memeory area 	
    	void** tmp = (void **)realloc(mdata, msize * sizeof(void *));
	    if(!tmp)
	        {
	        msize--;
	        throw std::bad_alloc();    
	        }
	    mdata = tmp;    
	   	memset(&mdata[oldSize], 0, (msize- oldSize) * sizeof(void *));
        }

	    //Now move	elements from nth element to the last element by 1 position
	    //Move all
	    if(aCount < mcount)
	        { 
		    for(int i =mcount;i > aCount; --i)
		        {
		    	mdata[i]= mdata[i-1];
		        }    
		    }
	    //Now assign the new element at this position and increment the count	    	    
	    
	    mdata[aCount] = aItem;
	    if (aItem) 
	    {
	        ++mcount;
	    }
	        
    return true;
}

// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
//
OSN_EXPORT int AlfPtrVectorImpl::findRef(void *aItem)
{
    for (unsigned i = 0; i < mcount; i++) {
        if (mdata[i] == aItem) {
            return i;
        }
    }
    
    return -1;
}



} //osncore