Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

NArray.cc

Go to the documentation of this file.
00001 /*
00002     File:           NArray.cc
00003 
00004     Function:       Provides methods for NBaseArray
00005 
00006     Author(s):      Andrew Willmott
00007 
00008     Copyright:      (c) 1995-2000, Andrew Willmott
00009 
00010     Notes:          
00011 
00012 */
00013 
00029 #include "cl/NArray.h"
00030 #include <string.h>
00031 #include <ctype.h>
00032 
00033 NBaseArray::NBaseArray(UInt32 es, Int size, Int alloc) : items(size),
00034                     allocated(alloc), eltSize(es)
00035 {
00036     Assert(size > 0, "(NBaseArray) Initial array size must be positive!");
00037 
00038     if (allocated < size)
00039         allocated = size;
00040     
00041     item = new Byte[eltSize * allocated];
00042 }
00043 
00044 NBaseArray::NBaseArray(const NBaseArray &array) : items(array.items), 
00045     allocated(array.allocated), eltSize(array.eltSize)
00046 {
00047     // XXX should we be sizing to allocated or just items?
00048     if (!allocated)
00049         allocated = items;
00050     item = new Byte[eltSize * allocated];
00051     
00052     memcpy(item, array.item, items * eltSize);
00053 }
00054 
00055 NBaseArray::~NBaseArray()
00056 {
00057     if (allocated) delete[] item;
00058 }
00059 
00060 NBaseArray &NBaseArray::operator = (const NBaseArray &array)
00061 {
00062     Int i;
00063 
00064     if (allocated < array.items)
00065     {
00066         if (allocated) delete[] item;
00067         allocated = array.items;    
00068         item = new Byte[eltSize * allocated];   
00069     }
00070             
00071     items = array.items;
00072     memcpy(item, array.item, items * eltSize);
00073     
00074     return(SELF);
00075 }
00076 
00077 Void NBaseArray::PreAllocate(UInt32 newSize)
00078 {
00079     UInt32  i, oldAllocated = allocated;
00080     Byte    *newArray;
00081     
00082     if (newSize > allocated)
00083     {
00084         if (allocated == 0)
00085             allocated = kFirstNAllocation;
00086         else
00087             allocated *= 2; 
00088         
00089         while (newSize > allocated)
00090             allocated *= 2; 
00091         
00092         newArray = new Byte[eltSize * allocated];
00093     
00094         memcpy(newArray, item, items * eltSize);
00095         
00096         if (oldAllocated) delete[] item;
00097         item = newArray;
00098     }
00099 }
00100 
00101 Void NBaseArray::SetSize(Int newSize)
00102 {
00103     PreAllocate(newSize);
00104     items = newSize;
00105 }
00106 
00107 Void NBaseArray::Add(Int n)
00108 {
00109     SetSize(items + n);
00110 }
00111 
00112 Void NBaseArray::Shrink(Int n)
00113 //  take away n items.
00114 {
00115     items -= n;
00116 }
00117 
00118 Void NBaseArray::Insert(Int i, Int n)
00119 //  Make space at position i for n items.
00120 {
00121     Assert(i >= 0 && i <= items, "(NBaseArray:Insert) Illegal index");
00122     Assert(n > 0, "(NBaseArray:Insert) Illegal insert amount");
00123 
00124     Byte *ip = item + (eltSize * i);
00125     
00126     Add(n);
00127     memmove(ip + eltSize * n, ip, (items - i - n) * eltSize);
00128 }
00129 
00130 Void NBaseArray::Delete(Int i, Int n)
00131 //  Delete n items at position i.
00132 {
00133     Assert(i >= 0 && i <= items, "(NBaseArray:Delete) Illegal index");
00134     Assert(n > 0, "(NBaseArray:Delete) Illegal insert amount");
00135 
00136     Byte *ip = item + (eltSize * i);
00137 
00138     items -= n;
00139     memmove(ip, ip + eltSize * n, (items - i) * eltSize);
00140 }
00141 
00142 Void NBaseArray::ShrinkWrap()
00143 // Shrink allocated space to be only the current size of array
00144 // There is no realloc version of new in C++, so this involves another copy.
00145 {
00146     Int     i, oldAllocated = allocated;
00147     Byte    *newArray;
00148     
00149     allocated = items;
00150     
00151     newArray = new Byte[eltSize * allocated];
00152 
00153     memcpy(newArray, item, items * eltSize);
00154     
00155     if (oldAllocated) delete[] item;
00156     item = newArray;
00157 }
00158 
00159 Void NBaseArray::Grow()
00160 //  Allocate more space for the array. Used internally prior to an items++.
00161 {
00162     UInt32  i, oldAllocated = allocated;
00163     Byte    *newArray;
00164     
00165     if (allocated == 0)
00166         allocated = kFirstNAllocation;
00167     else
00168         allocated *= 2; 
00169     
00170     newArray = new Byte[eltSize * allocated];
00171 
00172     memcpy(newArray, item, items * eltSize);
00173     
00174     if (oldAllocated) delete[] item;
00175     item = newArray;
00176 }
00177 
00178 Void NBaseArray::Append(const NBaseArray &a)
00179 {
00180     Int     i, j, start, newSize;
00181     
00182     newSize = items + a.items;
00183     PreAllocate(newSize);
00184 
00185     for (i = items, j = 0; j < a.items; i++, j++)
00186         item[i] = a.item[j];
00187     memcpy(item + (items * eltSize), a.item, a.items * eltSize);
00188 
00189     items = newSize;
00190 }
00191 
00192 Void NBaseArray::SwapWith(NBaseArray &a)
00193 {
00194     Int a1, b1;
00195     
00196     Swap(a1, b1);
00197     
00198     Swap(items, a.items);
00199     Swap(allocated, a.allocated);
00200     Swap(item, a.item);
00201 }
00202 
00203 Void NBaseArray::Replace(NBaseArray &a)
00204 {
00205     if (allocated) delete[] item;
00206     item = a.item;
00207     items = a.items;
00208     allocated = a.allocated;
00209 
00210     a.item = 0;
00211     a.items = 0;
00212     a.allocated = 0;
00213 }
00214 
00215 #include <stdio.h>
00216 
00217 Void NBaseArray::WriteFile(const Char *filename)
00218 {
00219     FILE    *file;
00220 
00221     file = fopen(filename, "wb");
00222     if (file)
00223     {
00224         fwrite(item, eltSize, items, file);
00225         fclose(file);
00226     }
00227 }
00228 
00229 Void NBaseArray::ReadFile(const Char *filename)
00230 {
00231     FILE    *file = fopen(filename, "rb");
00232 
00233     if (file)
00234     {
00235         Int     fsize;
00236 
00237         fseek(file, 0, SEEK_END);
00238         fsize = ftell(file);
00239         rewind(file);
00240         items = fsize / eltSize;
00241         Assert(items * eltSize == fsize, "(NBaseArray::ReadFile) bad file size");
00242         item = new Byte[eltSize * items];
00243         allocated = items;
00244         fread(item, eltSize, items, file);
00245 
00246         fclose(file);
00247     }
00248 }
00249 
00250 Int NBaseArray::FWrite(FILE *file)
00251 {
00252     fwrite(&items, sizeof(UInt32), 1, file);
00253     fwrite(item, eltSize, items, file);
00254 
00255     return(ferror(file));
00256 }
00257 
00258 Int NBaseArray::FRead(FILE *file)
00259 {
00260     if (fread(&items, sizeof(UInt32), 1, file) != 1)
00261         return(-1);
00262     item = new Byte[eltSize * items];
00263     allocated = items;
00264 
00265     return(fread(item, eltSize, items, file) != items);
00266 }
00267 
00268 Void NBaseArray::Attach(Void *ptr, Int numItems, Bool shared)
00269 {
00270     Clear();
00271 
00272     item = (Byte*) ptr;
00273     items = numItems;
00274 
00275     if (!shared)
00276         allocated = numItems;
00277 }

Generated at Sat Aug 5 00:16:32 2000 for Class Library by doxygen 1.1.0 written by Dimitri van Heesch, © 1997-2000