root/libutil/varray.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. varray_open
  2. varray_assign
  3. varray_append
  4. varray_reset
  5. varray_close

   1 /*
   2  * Copyright (c) 2004 Tama Communications Corporation
   3  *
   4  * This file is part of GNU GLOBAL.
   5  *
   6  * This program is free software: you can redistribute it and/or modify
   7  * it under the terms of the GNU General Public License as published by
   8  * the Free Software Foundation, either version 3 of the License, or
   9  * (at your option) any later version.
  10  * 
  11  * This program is distributed in the hope that it will be useful,
  12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14  * GNU General Public License for more details.
  15  * 
  16  * You should have received a copy of the GNU General Public License
  17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  18  */
  19 
  20 #ifdef HAVE_CONFIG_H
  21 #include <config.h>
  22 #endif
  23 #ifdef STDC_HEADERS
  24 #include <stdlib.h>
  25 #endif
  26 #include <stdio.h>
  27 #include "checkalloc.h"
  28 #include "die.h"
  29 #include "varray.h"
  30 
  31 /**
  32  @file
  33 
  34 Virtual array: usage and memory status
  35 
  36 _: allocated but not assigned. <br>
  37 \@: assigned but the value is uncertainty.
  38 
  39 @code
  40 Function call                           Memory status
  41 ----------------------------------------------------------
  42                                         (not exist)
  43 vb = varray_open(sizeof(int), 5);       ||
  44 
  45 int *a = varray_assign(vb, 0, 0);       ||
  46 
  47         a == NULL
  48 
  49 int *a = varray_assign(vb, 0, 1);       |@|_|_|_|_|             // expand
  50 
  51 printf("%d allocated, %d assigned.\n", vb->alloced, vb->length);
  52 
  53         "5 allocated, 1 assigned."
  54                                         v
  55 *a = 3;                                 |3|_|_|_|_|
  56 
  57                                               v
  58 int *a = varray_assign(vb, 3, 1);       |3|@|@|@|_|
  59                                               v
  60 *a = 8;                                 |3|@|@|8|_|
  61                                                   v
  62 int *a = varray_assign(vb, 5, 1);       |3|@|@|8|@|@|_|_|_|_|   // expand
  63                                                   v
  64 *a = 5;                                 |3|@|@|8|@|5|_|_|_|_|
  65 
  66 printf("%d allocated, %d assigned.\n", vb->alloced, vb->length);
  67 
  68         "10 allocated, 6 assigned."
  69 
  70 // After construction, you can treat it as a C array.
  71 
  72 int i, *a = varray_assign(vb, 0, 0);
  73 
  74 for (i = 0; i < vb->length; i++)
  75         printf("%d: %d\n", i, a[i]); // a[1], a[2], a[4] is uncertainty.
  76 
  77 @endcode
  78 */
  79 
  80 #define DEFAULT_EXPAND  100
  81 static int debug = 0;
  82 /**
  83  * varray_open: open virtual array.
  84  *
  85  *      @param[in]      size    size of entry
  86  *      @param[in]      expand  expand array size <br>
  87  *                      if 0 (zero) is specified then use #DEFAULT_EXPAND.
  88  *      @return vb      #VARRAY structure
  89  */
  90 VARRAY *
  91 varray_open(int size, int expand)
  92 {
  93         VARRAY *vb = (VARRAY *)check_calloc(sizeof(VARRAY), 1);
  94 
  95         if (size < 1)
  96                 die("varray_open: size < 1.");
  97         if (expand < 0)
  98                 die("varray_open: expand < 0.");
  99         vb->size = size;
 100         vb->alloced = vb->length = 0;
 101         vb->expand = (expand == 0) ? DEFAULT_EXPAND : expand;
 102         vb->vbuf = NULL;
 103         return vb;
 104 }
 105 /**
 106  * varray_assign: assign varray entry.
 107  *
 108  *      @param[in]      vb      #VARRAY structure
 109  *      @param[in]      index   index
 110  *      @param[in]      force   if entry not found, create it.
 111  *      @return         pointer of the entry
 112  *
 113  * If specified entry is found then it is returned, else it is allocated
 114  * and returned.
 115  * This procedure @EMPH{doesn't} operate the contents of the array.
 116  */
 117 void *
 118 varray_assign(VARRAY *vb, int index, int force)
 119 {
 120         if (index < 0)
 121                 die("varray_assign: illegal index value.");
 122         if (index >= vb->length) {
 123                 if (force)
 124                         vb->length = index + 1;
 125                 else if (index == 0 && vb->length == 0)
 126                         return NULL;
 127                 else
 128                         die("varray_assign: index(=%d) is out of range.", index);
 129         }
 130         /*
 131          * Expand the area.
 132          */
 133         if (index >= vb->alloced) {
 134                 int old_alloced = vb->alloced;
 135 
 136                 while (index >= vb->alloced)
 137                         vb->alloced += vb->expand;
 138                 /*
 139                  * Old implementations of realloc() may crash
 140                  * when a null pointer is passed.
 141                  * Therefore, we cannot use realloc(NULL, ...).
 142                  */
 143                 if (vb->vbuf == NULL)
 144                         vb->vbuf = (char *)check_malloc(vb->size * vb->alloced);
 145                 else
 146                         vb->vbuf = (char *)check_realloc(vb->vbuf, vb->size * vb->alloced);
 147                 if (debug)
 148                         fprintf(stderr, "Expanded: from %d to %d.\n", old_alloced, vb->alloced);
 149         }
 150         return (void *)(vb->vbuf + vb->size * index);
 151 }
 152 
 153 /**
 154  * varray_append: append varray entry.
 155  *
 156  *      @param[in]      vb      #VARRAY structure
 157  *      @return         pointer of the entry
 158  *
 159  * This procedure @EMPH{doesn't} operate the contents of the array.
 160  */
 161 void *
 162 varray_append(VARRAY *vb)
 163 {
 164         return varray_assign(vb, vb->length, 1);
 165 }
 166 /**
 167  * varray_reset: reset varray array.
 168  *
 169  *      @param[in]      vb      #VARRAY structure
 170  */
 171 void
 172 varray_reset(VARRAY *vb)
 173 {
 174         vb->length = 0;
 175 }
 176 /**
 177  * varray_close: close varray array.
 178  *
 179  *      @param[in]      vb      #VARRAY structure
 180  */
 181 void
 182 varray_close(VARRAY *vb)
 183 {
 184         if (vb) {
 185                 if (vb->vbuf)
 186                         (void)free(vb->vbuf);
 187                 (void)free(vb);
 188         }
 189 }

/* [previous][next][first][last][top][bottom][index][help] */