LCOV - code coverage report
Current view: top level - port - cpl_list.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 86 99 86.9 %
Date: 2025-07-05 13:22:42 Functions: 7 9 77.8 %

          Line data    Source code
       1             : /**********************************************************************
       2             :  *
       3             :  * Name:     cpl_list.cpp
       4             :  * Project:  CPL - Common Portability Library
       5             :  * Purpose:  List functions.
       6             :  * Author:   Andrey Kiselev, dron@remotesensing.org
       7             :  *
       8             :  **********************************************************************
       9             :  * Copyright (c) 2003, Andrey Kiselev <dron@remotesensing.org>
      10             :  * Copyright (c) 2008, Even Rouault <even dot rouault at spatialys.com>
      11             :  *
      12             :  * SPDX-License-Identifier: MIT
      13             :  ****************************************************************************/
      14             : 
      15             : #include "cpl_list.h"
      16             : 
      17             : #include <cstddef>
      18             : 
      19             : #include "cpl_conv.h"
      20             : 
      21             : /*=====================================================================
      22             :                     List manipulation functions.
      23             :  =====================================================================*/
      24             : 
      25             : /************************************************************************/
      26             : /*                          CPLListAppend()                             */
      27             : /************************************************************************/
      28             : 
      29             : /**
      30             :  * Append an object list and return a pointer to the modified list.
      31             :  * If the input list is NULL, then a new list is created.
      32             :  *
      33             :  * @param psList pointer to list head.
      34             :  * @param pData pointer to inserted data object. May be NULL.
      35             :  *
      36             :  * @return pointer to the head of modified list.
      37             :  */
      38             : 
      39          11 : CPLList *CPLListAppend(CPLList *psList, void *pData)
      40             : {
      41          11 :     CPLList *psLast = nullptr;
      42             : 
      43             :     // Allocate room for the new object.
      44          11 :     if (psList == nullptr)
      45             :     {
      46           4 :         psLast = static_cast<CPLList *>(CPLMalloc(sizeof(CPLList)));
      47           4 :         psList = psLast;
      48             :     }
      49             :     else
      50             :     {
      51           7 :         psLast = CPLListGetLast(psList);
      52           7 :         psLast = psLast->psNext =
      53           7 :             static_cast<CPLList *>(CPLMalloc(sizeof(CPLList)));
      54             :     }
      55             : 
      56             :     // Append object to the end of list.
      57          11 :     psLast->pData = pData;
      58          11 :     psLast->psNext = nullptr;
      59             : 
      60          11 :     return psList;
      61             : }
      62             : 
      63             : /************************************************************************/
      64             : /*                          CPLListInsert()                             */
      65             : /************************************************************************/
      66             : 
      67             : /**
      68             :  * Insert an object into list at specified position (zero based).
      69             :  * If the input list is NULL, then a new list is created.
      70             :  *
      71             :  * @param psList pointer to list head.
      72             :  * @param pData pointer to inserted data object. May be NULL.
      73             :  * @param nPosition position number to insert an object.
      74             :  *
      75             :  * @return pointer to the head of modified list.
      76             :  */
      77             : 
      78           7 : CPLList *CPLListInsert(CPLList *psList, void *pData, int nPosition)
      79             : {
      80           7 :     if (nPosition < 0)
      81           0 :         return psList;  // Nothing to do.
      82             : 
      83           7 :     if (nPosition == 0)
      84             :     {
      85           2 :         CPLList *psNew = static_cast<CPLList *>(CPLMalloc(sizeof(CPLList)));
      86           2 :         psNew->pData = pData;
      87           2 :         psNew->psNext = psList;
      88           2 :         psList = psNew;
      89           2 :         return psList;
      90             :     }
      91             : 
      92           5 :     const int nCount = CPLListCount(psList);
      93             : 
      94           5 :     if (nCount < nPosition)
      95             :     {
      96             : #ifdef __COVERITY__
      97             :         CPLError(CE_Failure, CPLE_AppDefined, "Not implemented");
      98             : #else
      99             :         // Allocate room for the new object.
     100           3 :         CPLList *psLast = CPLListGetLast(psList);
     101           7 :         for (int i = nCount; i <= nPosition - 1; i++)
     102             :         {
     103           4 :             psLast = CPLListAppend(psLast, nullptr);
     104           4 :             if (psList == nullptr)
     105           2 :                 psList = psLast;
     106             :             else
     107           2 :                 psLast = psLast->psNext;
     108             :         }
     109           3 :         psLast = CPLListAppend(psLast, pData);
     110           3 :         if (psList == nullptr)
     111           0 :             psList = psLast;
     112             : 
     113             :         /* coverity[leaked_storage] */
     114           3 :         return psList;
     115             : #endif
     116             :     }
     117             : 
     118           2 :     CPLList *psNew = static_cast<CPLList *>(CPLMalloc(sizeof(CPLList)));
     119           2 :     psNew->pData = pData;
     120             : 
     121           2 :     CPLList *psCurrent = psList;
     122           4 :     for (int i = 0; i < nPosition - 1; i++)
     123           2 :         psCurrent = psCurrent->psNext;
     124           2 :     psNew->psNext = psCurrent->psNext;
     125           2 :     psCurrent->psNext = psNew;
     126             : 
     127           2 :     return psList;
     128             : }
     129             : 
     130             : /************************************************************************/
     131             : /*                          CPLListGetLast()                            */
     132             : /************************************************************************/
     133             : 
     134             : /**
     135             :  * Return the pointer to last element in a list.
     136             :  *
     137             :  * @param psList pointer to list head.
     138             :  *
     139             :  * @return pointer to last element in a list.
     140             :  */
     141             : 
     142          10 : CPLList *CPLListGetLast(CPLList *const psList)
     143             : {
     144          10 :     if (psList == nullptr)
     145           2 :         return nullptr;
     146             : 
     147           8 :     CPLList *psCurrent = psList;
     148           9 :     while (psCurrent->psNext)
     149           1 :         psCurrent = psCurrent->psNext;
     150             : 
     151           8 :     return psCurrent;
     152             : }
     153             : 
     154             : /************************************************************************/
     155             : /*                          CPLListGet()                                */
     156             : /************************************************************************/
     157             : 
     158             : /**
     159             :  * Return the pointer to the specified element in a list.
     160             :  *
     161             :  * @param psList pointer to list head.
     162             :  * @param nPosition the index of the element in the list, 0 being the
     163             :  * first element.
     164             :  *
     165             :  * @return pointer to the specified element in a list.
     166             :  */
     167             : 
     168          12 : CPLList *CPLListGet(CPLList *psList, int nPosition)
     169             : {
     170          12 :     if (nPosition < 0)
     171           0 :         return nullptr;
     172             : 
     173          12 :     CPLList *psCurrent = psList;
     174          12 :     int iItem = 0;
     175          27 :     while (iItem < nPosition && psCurrent)
     176             :     {
     177          15 :         psCurrent = psCurrent->psNext;
     178          15 :         iItem++;
     179             :     }
     180             : 
     181          12 :     return psCurrent;
     182             : }
     183             : 
     184             : /************************************************************************/
     185             : /*                          CPLListCount()                              */
     186             : /************************************************************************/
     187             : 
     188             : /**
     189             :  * Return the number of elements in a list.
     190             :  *
     191             :  * @param psList pointer to list head.
     192             :  *
     193             :  * @return number of elements in a list.
     194             :  */
     195             : 
     196          16 : int CPLListCount(const CPLList *psList)
     197             : {
     198          16 :     int nItems = 0;
     199          16 :     const CPLList *psCurrent = psList;
     200             : 
     201          43 :     while (psCurrent)
     202             :     {
     203          27 :         nItems++;
     204          27 :         psCurrent = psCurrent->psNext;
     205             :     }
     206             : 
     207          16 :     return nItems;
     208             : }
     209             : 
     210             : /************************************************************************/
     211             : /*                          CPLListRemove()                             */
     212             : /************************************************************************/
     213             : 
     214             : /**
     215             :  * Remove the element from the specified position (zero based) in a list. Data
     216             :  * object contained in removed element must be freed by the caller first.
     217             :  *
     218             :  * @param psList pointer to list head.
     219             :  * @param nPosition position number to delete an element.
     220             :  *
     221             :  * @return pointer to the head of modified list.
     222             :  */
     223             : 
     224          10 : CPLList *CPLListRemove(CPLList *psList, int nPosition)
     225             : {
     226             : 
     227          10 :     if (psList == nullptr)
     228           0 :         return nullptr;
     229             : 
     230          10 :     if (nPosition < 0)
     231           0 :         return psList; /* Nothing to do. */
     232             : 
     233          10 :     if (nPosition == 0)
     234             :     {
     235           4 :         CPLList *psCurrent = psList->psNext;
     236           4 :         CPLFree(psList);
     237           4 :         psList = psCurrent;
     238           4 :         return psList;
     239             :     }
     240             : 
     241           6 :     CPLList *psCurrent = psList;
     242           7 :     for (int i = 0; i < nPosition - 1; i++)
     243             :     {
     244           2 :         psCurrent = psCurrent->psNext;
     245             :         // psCurrent == NULL if nPosition >= CPLListCount(psList).
     246           2 :         if (psCurrent == nullptr)
     247           1 :             return psList;
     248             :     }
     249           5 :     CPLList *psRemoved = psCurrent->psNext;
     250             :     // psRemoved == NULL if nPosition >= CPLListCount(psList).
     251           5 :     if (psRemoved == nullptr)
     252           1 :         return psList;
     253           4 :     psCurrent->psNext = psRemoved->psNext;
     254           4 :     CPLFree(psRemoved);
     255             : 
     256           4 :     return psList;
     257             : }
     258             : 
     259             : /************************************************************************/
     260             : /*                          CPLListDestroy()                            */
     261             : /************************************************************************/
     262             : 
     263             : /**
     264             :  * Destroy a list. Caller responsible for freeing data objects contained in
     265             :  * list elements.
     266             :  *
     267             :  * @param psList pointer to list head.
     268             :  *
     269             :  */
     270             : 
     271        6295 : void CPLListDestroy(CPLList *psList)
     272             : {
     273        6295 :     CPLList *psCurrent = psList;
     274             : 
     275        9117 :     while (psCurrent)
     276             :     {
     277        2822 :         CPLList *const psNext = psCurrent->psNext;
     278        2822 :         CPLFree(psCurrent);
     279        2822 :         psCurrent = psNext;
     280             :     }
     281        6295 : }
     282             : 
     283             : /************************************************************************/
     284             : /*                          CPLListGetNext()                            */
     285             : /************************************************************************/
     286             : 
     287             : /**
     288             :  * Return the pointer to next element in a list.
     289             :  *
     290             :  * @param psElement pointer to list element.
     291             :  *
     292             :  * @return pointer to the list element preceded by the given element.
     293             :  */
     294             : 
     295           0 : CPLList *CPLListGetNext(const CPLList *psElement)
     296             : {
     297           0 :     if (psElement == nullptr)
     298           0 :         return nullptr;
     299             : 
     300           0 :     return psElement->psNext;
     301             : }
     302             : 
     303             : /************************************************************************/
     304             : /*                          CPLListGetData()                            */
     305             : /************************************************************************/
     306             : 
     307             : /**
     308             :  * Return pointer to the data object contained in given list element.
     309             :  *
     310             :  * @param psElement pointer to list element.
     311             :  *
     312             :  * @return pointer to the data object contained in given list element.
     313             :  */
     314             : 
     315           0 : void *CPLListGetData(const CPLList *psElement)
     316             : {
     317           0 :     if (psElement == nullptr)
     318           0 :         return nullptr;
     319             : 
     320           0 :     return psElement->pData;
     321             : }

Generated by: LCOV version 1.14