ultimatepp/bazaar/plugin/gdal/port/cpl_list.cpp
cxl 23ff1e7e82 .gdal moved to bazaar
git-svn-id: svn://ultimatepp.org/upp/trunk@9273 f0d560ea-af0d-0410-9eb7-867de7ffcac7
2015-12-07 13:36:24 +00:00

339 lines
9.7 KiB
C++

/**********************************************************************
* $Id: cpl_list.cpp 27044 2014-03-16 23:41:27Z rouault $
*
* Name: cpl_list.cpp
* Project: CPL - Common Portability Library
* Purpose: List functions.
* Author: Andrey Kiselev, dron@remotesensing.org
*
**********************************************************************
* Copyright (c) 2003, Andrey Kiselev <dron@remotesensing.org>
* Copyright (c) 2008, Even Rouault <even dot rouault at mines-paris dot org>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
****************************************************************************/
#include "cpl_list.h"
#include "cpl_conv.h"
CPL_CVSID("$Id: cpl_list.cpp 27044 2014-03-16 23:41:27Z rouault $");
/*=====================================================================
List manipulation functions.
=====================================================================*/
/************************************************************************/
/* CPLListAppend() */
/************************************************************************/
/**
* Append an object list and return a pointer to the modified list.
* If the input list is NULL, then a new list is created.
*
* @param psList pointer to list head.
* @param pData pointer to inserted data object. May be NULL.
*
* @return pointer to the head of modified list.
*/
CPLList *CPLListAppend( CPLList *psList, void *pData )
{
CPLList *psLast;
/* Allocate room for the new object */
if ( psList == NULL )
{
psLast = psList = (CPLList *)CPLMalloc( sizeof(CPLList) );
}
else
{
psLast = CPLListGetLast( psList );
psLast = psLast->psNext = (CPLList *)CPLMalloc( sizeof(CPLList) );
}
/* Append object to the end of list */
psLast->pData = pData;
psLast->psNext = NULL;
return psList;
}
/************************************************************************/
/* CPLListInsert() */
/************************************************************************/
/**
* Insert an object into list at specified position (zero based).
* If the input list is NULL, then a new list is created.
*
* @param psList pointer to list head.
* @param pData pointer to inserted data object. May be NULL.
* @param nPosition position number to insert an object.
*
* @return pointer to the head of modified list.
*/
CPLList *CPLListInsert( CPLList *psList, void *pData, int nPosition )
{
CPLList *psCurrent;
int i, nCount;
if ( nPosition < 0 )
return psList; /* Nothing to do!*/
nCount = CPLListCount( psList );
if ( nPosition == 0)
{
CPLList *psNew = (CPLList *)CPLMalloc( sizeof(CPLList) );
psNew->pData = pData;
psNew->psNext = psList;
psList = psNew;
}
else if ( nCount < nPosition )
{
/* Allocate room for the new object */
CPLList* psLast = CPLListGetLast(psList);
for ( i = nCount; i <= nPosition - 1; i++ )
{
psLast = CPLListAppend( psLast, NULL );
if (psList == NULL)
psList = psLast;
else
psLast = psLast->psNext;
}
psLast = CPLListAppend( psLast, pData );
if (psList == NULL)
psList = psLast;
}
else
{
CPLList *psNew = (CPLList *)CPLMalloc( sizeof(CPLList) );
psNew->pData = pData;
psCurrent = psList;
for ( i = 0; i < nPosition - 1; i++ )
psCurrent = psCurrent->psNext;
psNew->psNext = psCurrent->psNext;
psCurrent->psNext = psNew;
}
return psList;
}
/************************************************************************/
/* CPLListGetLast() */
/************************************************************************/
/**
* Return the pointer to last element in a list.
*
* @param psList pointer to list head.
*
* @return pointer to last element in a list.
*/
CPLList *CPLListGetLast( CPLList *psList )
{
CPLList *psCurrent = psList;
if ( psList == NULL )
return NULL;
while ( psCurrent->psNext )
psCurrent = psCurrent->psNext;
return psCurrent;
}
/************************************************************************/
/* CPLListGet() */
/************************************************************************/
/**
* Return the pointer to the specified element in a list.
*
* @param psList pointer to list head.
* @param nPosition the index of the element in the list, 0 being the first element
*
* @return pointer to the specified element in a list.
*/
CPLList *CPLListGet( CPLList *psList, int nPosition )
{
int iItem = 0;
CPLList *psCurrent = psList;
if ( nPosition < 0 )
return NULL;
while ( iItem < nPosition && psCurrent )
{
psCurrent = psCurrent->psNext;
iItem++;
}
return psCurrent;
}
/************************************************************************/
/* CPLListCount() */
/************************************************************************/
/**
* Return the number of elements in a list.
*
* @param psList pointer to list head.
*
* @return number of elements in a list.
*/
int CPLListCount( CPLList *psList )
{
int nItems = 0;
CPLList *psCurrent = psList;
while ( psCurrent )
{
nItems++;
psCurrent = psCurrent->psNext;
}
return nItems;
}
/************************************************************************/
/* CPLListRemove() */
/************************************************************************/
/**
* Remove the element from the specified position (zero based) in a list. Data
* object contained in removed element must be freed by the caller first.
*
* @param psList pointer to list head.
* @param nPosition position number to delet an element.
*
* @return pointer to the head of modified list.
*/
CPLList *CPLListRemove( CPLList *psList, int nPosition )
{
CPLList *psCurrent, *psRemoved;
int i;
if ( psList == NULL)
{
return NULL;
}
else if ( nPosition < 0)
{
return psList; /* Nothing to do!*/
}
else if ( nPosition == 0 )
{
psCurrent = psList->psNext;
CPLFree( psList );
psList = psCurrent;
}
else
{
psCurrent = psList;
for ( i = 0; i < nPosition - 1; i++ )
{
psCurrent = psCurrent->psNext;
/* psCurrent == NULL if nPosition >= CPLListCount(psList) */
if (psCurrent == NULL)
return psList;
}
psRemoved = psCurrent->psNext;
/* psRemoved == NULL if nPosition >= CPLListCount(psList) */
if (psRemoved == NULL)
return psList;
psCurrent->psNext = psRemoved->psNext;
CPLFree( psRemoved );
}
return psList;
}
/************************************************************************/
/* CPLListDestroy() */
/************************************************************************/
/**
* Destroy a list. Caller responsible for freeing data objects contained in
* list elements.
*
* @param psList pointer to list head.
*
*/
void CPLListDestroy( CPLList *psList )
{
CPLList *psNext;
CPLList *psCurrent = psList;
while ( psCurrent )
{
psNext = psCurrent->psNext;
CPLFree( psCurrent );
psCurrent = psNext;
}
}
/************************************************************************/
/* CPLListGetNext() */
/************************************************************************/
/**
* Return the pointer to next element in a list.
*
* @param psElement pointer to list element.
*
* @return pointer to the list element preceded by the given element.
*/
CPLList *CPLListGetNext( CPLList *psElement )
{
if ( psElement == NULL )
return NULL;
else
return psElement->psNext;
}
/************************************************************************/
/* CPLListGetData() */
/************************************************************************/
/**
* Return pointer to the data object contained in given list element.
*
* @param psElement pointer to list element.
*
* @return pointer to the data object contained in given list element.
*/
void *CPLListGetData( CPLList *psElement )
{
if ( psElement == NULL )
return NULL;
else
return psElement->pData;
}