OCILIB (C Driver for Oracle) 3.9.1
D:/Perso/dev/ocilib/ocilib/src/list.c
00001 /*
00002     +-----------------------------------------------------------------------------------------+
00003     |                                                                                         |
00004     |                               OCILIB - C Driver for Oracle                              |
00005     |                                                                                         |
00006     |                                (C Wrapper for Oracle OCI)                               |
00007     |                                                                                         |
00008     |                              Website : http://www.ocilib.net                            |
00009     |                                                                                         |
00010     |             Copyright (c) 2007-2011 Vincent ROGIER <vince.rogier@ocilib.net>            |
00011     |                                                                                         |
00012     +-----------------------------------------------------------------------------------------+
00013     |                                                                                         |
00014     |             This library is free software; you can redistribute it and/or               |
00015     |             modify it under the terms of the GNU Lesser General Public                  |
00016     |             License as published by the Free Software Foundation; either                |
00017     |             version 2 of the License, or (at your option) any later version.            |
00018     |                                                                                         |
00019     |             This library is distributed in the hope that it will be useful,             |
00020     |             but WITHOUT ANY WARRANTY; without even the implied warranty of              |
00021     |             MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU           |
00022     |             Lesser General Public License for more details.                             |
00023     |                                                                                         |
00024     |             You should have received a copy of the GNU Lesser General Public            |
00025     |             License along with this library; if not, write to the Free                  |
00026     |             Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.          |
00027     |                                                                                         |
00028     +-----------------------------------------------------------------------------------------+
00029 */
00030 
00031 /* --------------------------------------------------------------------------------------------- *
00032  * $Id: list.c, v 3.9.1 2011-07-08 00:00 Vincent Rogier $
00033  * --------------------------------------------------------------------------------------------- */
00034 
00035 #include "ocilib_internal.h"
00036 
00037 /* ********************************************************************************************* *
00038  *                             PRIVATE FUNCTIONS
00039  * ********************************************************************************************* */
00040 
00041 /* --------------------------------------------------------------------------------------------- *
00042  * OCI_ListCreate
00043  * --------------------------------------------------------------------------------------------- */
00044 
00045 OCI_List * OCI_ListCreate
00046 (
00047     int type
00048 )
00049 {
00050     OCI_List *list = NULL;
00051 
00052     /* allocate list */
00053 
00054     list = (OCI_List *) OCI_MemAlloc(OCI_IPC_LIST, sizeof(*list), (size_t) 1, TRUE);
00055 
00056     /* create a mutex on multithreaded environments */
00057 
00058     if (list != NULL)
00059     {
00060         list->type = type;
00061 
00062         if (OCI_LIB_THREADED)
00063         {
00064             list->mutex = OCI_MutexCreateInternal();
00065 
00066             if (list->mutex == NULL)
00067             {
00068                 OCI_FREE(list);
00069             }
00070         }
00071     }
00072 
00073     return list;
00074 }
00075 
00076 /* --------------------------------------------------------------------------------------------- *
00077  * OCI_ListFree
00078  * --------------------------------------------------------------------------------------------- */
00079 
00080 boolean OCI_ListFree
00081 (
00082     OCI_List *list
00083 )
00084 {
00085     boolean res = TRUE;
00086 
00087     OCI_CHECK(list == NULL, FALSE);
00088 
00089     OCI_ListClear(list);
00090 
00091     if (list->mutex != NULL)
00092     {
00093         res = OCI_MutexFree(list->mutex);
00094     }
00095 
00096     OCI_FREE(list);
00097 
00098     return res;
00099 }
00100 
00101 /* --------------------------------------------------------------------------------------------- *
00102  * OCI_ListCreateItem
00103  * --------------------------------------------------------------------------------------------- */
00104 
00105 OCI_Item * OCI_ListCreateItem
00106 (
00107     int type,
00108     int size
00109 )
00110 {
00111     OCI_Item *item = NULL;
00112 
00113     /* allocate list item entry */
00114 
00115     item = (OCI_Item *) OCI_MemAlloc(OCI_IPC_LIST_ITEM, sizeof(*item), (size_t) 1, TRUE);
00116 
00117     if (item != NULL)
00118     {
00119         /* allocate item data buffer */
00120 
00121         item->data = (void *) OCI_MemAlloc(type, (size_t) size, (size_t) 1, TRUE);
00122 
00123         if (item->data == NULL)
00124         {
00125             OCI_FREE(item);
00126         }
00127     }
00128 
00129     return item;
00130 }
00131 
00132 /* --------------------------------------------------------------------------------------------- *
00133  * OCI_ListAppend
00134  * --------------------------------------------------------------------------------------------- */
00135 
00136 OCI_Item * OCI_ListAppend
00137 (
00138     OCI_List *list,
00139     int       size
00140 )
00141 {
00142     OCI_Item *item = NULL;
00143     OCI_Item *temp = NULL;
00144 
00145     OCI_CHECK(list == NULL, NULL);
00146 
00147     item = OCI_ListCreateItem(list->type, size);
00148 
00149     OCI_CHECK(item == NULL, FALSE);
00150 
00151     if (list->mutex != NULL)
00152     {
00153         OCI_MutexAcquire(list->mutex);
00154     }
00155 
00156     temp = list->head;
00157 
00158     while (temp != NULL && temp->next)
00159     {
00160         temp = temp->next;
00161     }
00162 
00163     if (temp != NULL)
00164     {
00165         temp->next = item;
00166     }
00167     else
00168     {
00169         list->head = item;
00170     }
00171 
00172     list->count++;
00173 
00174     if (list->mutex != NULL)
00175     {
00176         OCI_MutexRelease(list->mutex);
00177     }
00178 
00179     return item;
00180 }
00181 
00182 /* --------------------------------------------------------------------------------------------- *
00183  * OCI_ListClear
00184  * --------------------------------------------------------------------------------------------- */
00185 
00186 boolean OCI_ListClear
00187 (
00188     OCI_List *list
00189 )
00190 {
00191     OCI_Item *item = NULL;
00192     OCI_Item *temp = NULL;
00193 
00194     OCI_CHECK(list == NULL, FALSE);
00195 
00196     if (list->mutex != NULL)
00197     {
00198         OCI_MutexAcquire(list->mutex);
00199     }
00200 
00201     /* walk along the list to free item's buffer */
00202 
00203     item = list->head;
00204 
00205     while (item != NULL)
00206     {
00207         temp = item;
00208         item = item->next;
00209 
00210         /* free data */
00211 
00212         OCI_FREE(temp->data);
00213         OCI_FREE(temp);
00214     }
00215 
00216     list->head  = NULL;
00217     list->count = 0;
00218 
00219     if (list->mutex != NULL)
00220     {
00221         OCI_MutexRelease(list->mutex);
00222     }
00223 
00224     return TRUE;
00225 }
00226 
00227 /* --------------------------------------------------------------------------------------------- *
00228  * OCI_ListForEach
00229  * --------------------------------------------------------------------------------------------- */
00230 
00231 boolean OCI_ListForEach
00232 (
00233     OCI_List          *list,
00234     POCI_LIST_FOR_EACH proc
00235 )
00236 {
00237     OCI_Item *item = NULL;
00238 
00239     OCI_CHECK(list == NULL, FALSE);
00240 
00241     if (list->mutex != NULL)
00242     {
00243         OCI_MutexAcquire(list->mutex);
00244     }
00245 
00246     item = list->head;
00247 
00248     /* for each item in the list, execute the given callback */
00249 
00250     while (item != NULL)
00251     {
00252         proc(item->data);
00253         item = item->next;
00254     }
00255 
00256     if (list->mutex != NULL)
00257     {
00258         OCI_MutexRelease(list->mutex);
00259     }
00260 
00261     return TRUE;
00262 }
00263 
00264 /* --------------------------------------------------------------------------------------------- *
00265  * OCI_ListRemove
00266  * --------------------------------------------------------------------------------------------- */
00267 
00268 boolean OCI_ListRemove
00269 (
00270     OCI_List *list,
00271     void     *data
00272 )
00273 {
00274     OCI_Item *item = NULL;
00275     OCI_Item *temp = NULL;
00276 
00277     OCI_CHECK(list == NULL, FALSE);
00278     OCI_CHECK(data == NULL, FALSE);
00279 
00280     if (list->mutex != NULL)
00281     {
00282         OCI_MutexAcquire(list->mutex);
00283     }
00284 
00285     item = list->head;
00286 
00287     while (item != NULL)
00288     {
00289         if (item->data == data)
00290         {
00291             if (temp)
00292             {
00293                 temp->next = item->next;
00294             }
00295 
00296             /* if item was the first entry, readjust the first list
00297                entry to next element */
00298 
00299             if (item == list->head)
00300             {
00301                 list->head = item->next;
00302             }
00303 
00304             OCI_FREE(item);
00305 
00306             break;
00307         }
00308 
00309         temp = item;
00310         item = item->next;
00311     }
00312 
00313     list->count--;
00314 
00315     if (list->mutex != NULL)
00316     {
00317         OCI_MutexRelease(list->mutex);
00318     }
00319 
00320     return TRUE;
00321 }