00001 /* 00002 File: ObjArray.cc 00003 00004 Function: See header file 00005 00006 Author(s): Andrew Willmott 00007 00008 Copyright: (c) 1995-2000, Andrew Willmott 00009 00010 Notes: Parse routines yet to be finished 00011 Object may have to be split out. 00012 00013 */ 00014 00015 #include "cl/ObjArray.h" 00016 #include "cl/String.h" 00017 00018 00019 ObjArray::ObjArray(Int size, Int alloc) : items(size), 00020 allocated(alloc) 00021 { 00022 Assert(size > 0, "(ObjArray) Initial array size must be positive!"); 00023 Assert(alloc >= size, "(ObjArray) Initial array allocation must be >= size!"); 00024 00025 item = new ObjectPtr[allocated]; 00026 } 00027 00028 ObjArray::ObjArray(const ObjArray &array) : items(array.items), allocated(array.allocated) 00029 { 00030 Int i; 00031 00032 if (allocated) 00033 { 00034 item = new ObjectPtr[allocated]; 00035 } 00036 else 00037 item = 0; 00038 00039 00040 for (i = 0; i < array.items; i++) 00041 item[i] = array.item[i]->Clone(); 00042 } 00043 00044 ObjArray::~ObjArray() 00045 { 00046 } 00047 00048 00049 // --- ObjArray operators ---------------------------------------- 00050 00051 00052 ObjArray &ObjArray::operator >> (Action<ObjectPtr> &a) 00053 { 00054 Int i; 00055 00056 a.Start(); 00057 00058 for (i = 0; i < items; i++) 00059 a.Process(item[i]); 00060 00061 a.Stop(); 00062 00063 return(SELF); 00064 } 00065 00066 ObjArray &ObjArray::operator = (const ObjArray &array) 00067 { 00068 Int i; 00069 00070 Clear(); 00071 00072 if (allocated < array.allocated) 00073 { 00074 delete[] item; 00075 allocated = array.allocated; 00076 item = new ObjectPtr[allocated]; 00077 } 00078 00079 for (i = 0; i < array.items; i++) 00080 item[i] = array.item[i]->Clone(); 00081 00082 items = array.items; 00083 00084 return(SELF); 00085 } 00086 00087 Void ObjArray::Print(ostream &s) const 00088 { 00089 Int i; 00090 00091 s << '['; 00092 00093 if (NumItems() > 0) 00094 { 00095 item[0]->Print(s); 00096 00097 for (i = 1; i < NumItems(); i++) 00098 item[i]->Print(s << ' '); 00099 } 00100 00101 s << ']'; 00102 } 00103 00104 Void ObjArray::Parse(istream &s) 00105 { 00106 Char c; 00107 00108 // Expected format: [a b c d ...] 00109 00110 ChompWhiteSpace(s); 00111 00112 if (s.peek() == '[') 00113 { 00114 s.get(c); 00115 Clear(); 00116 00117 ChompWhiteSpace(s); 00118 00119 while (s.peek() != ']') 00120 { 00121 Add(1); 00122 Top()->Parse(s); // read an item 00123 00124 if (!s) 00125 { 00126 Expect(false, "Couldn't read array component"); 00127 return; 00128 } 00129 00130 ChompWhiteSpace(s); 00131 } 00132 s.get(c); 00133 } 00134 else 00135 { 00136 s.clear(ios::failbit); 00137 Expect(false, "Error: Expected '[' while reading array"); 00138 } 00139 } 00140 00141 00142 // --- ObjArray Methods -------------------------------------------- 00143 00144 00145 Void ObjArray::Clear() 00146 { 00147 Int i; 00148 00149 for (i = 0; i < items; i++) 00150 item[i]->Free(); 00151 00152 items = 0; 00153 } 00154 00155 Void ObjArray::Free() 00156 { 00157 Clear(); 00158 delete[] item; 00159 } 00160 00161 ObjectPtr ObjArray::Clone() const 00162 { 00163 ObjectPtr result = new ObjArray(SELF); 00164 00165 return(result); 00166 } 00167 00168 Void ObjArray::SetSize(Int newSize) 00169 { 00170 Int i; 00171 ObjectPtr *newObjArray; 00172 00173 if (newSize > allocated) 00174 { 00175 if (allocated == 0) 00176 allocated = kFirstObjAlloc; 00177 else 00178 allocated *= 2; 00179 00180 while (newSize > allocated) 00181 allocated *= 2; 00182 00183 newObjArray = new ObjectPtr[allocated]; 00184 00185 for (i = 0; i < items; i++) 00186 newObjArray[i] = item[i]; 00187 00188 delete[] item; 00189 item = newObjArray; 00190 } 00191 items = newSize; 00192 } 00193 00194 Void ObjArray::Add(Int n) 00195 { 00196 SetSize(items + n); 00197 } 00198 00199 Void ObjArray::Shrink(Int n) 00200 // take away n items. 00201 { 00202 items -= n; 00203 } 00204 00205 Void ObjArray::Insert(Int i, Int n) 00206 // Make space at position i for n items. 00207 { 00208 Assert(i >= 0 && i <= items, "(ObjArray:InsertSpace) Illegal index"); 00209 00210 Int j; 00211 00212 Add(n); 00213 00214 for (j = items - 1; j >= i + n; j--) 00215 item[j] = (item - n)[j]; 00216 00217 for (j = i; j < i + n; j++) 00218 item[j] = 0; 00219 } 00220 00221 Void ObjArray::Delete(Int i, Int n) 00222 // Delete n items at position i. 00223 { 00224 Assert(i >= 0 && i <= items, "(ObjArray:InsertSpace) Illegal index"); 00225 00226 Int j; 00227 00228 for (j = i; j < i + n; j++) 00229 item[j]->Free(); 00230 00231 items -= n; 00232 00233 for (j = i; j < items; j++) 00234 item[j] = (item + n)[j]; 00235 } 00236 00237 Void ObjArray::ShrinkWrap() 00238 // Shrink allocated space to be only the current size of array 00239 { 00240 // There is no realloc version of new in C++, so this involves another copy... 00241 00242 Int i; 00243 ObjectPtr *newObjArray; 00244 00245 allocated = items; 00246 00247 newObjArray = new ObjectPtr[allocated]; 00248 00249 for (i = 0; i < items; i++) 00250 newObjArray[i] = item[i]; 00251 00252 delete[] item; 00253 item = newObjArray; 00254 } 00255 00256 Void ObjArray::Grow() 00257 // Allocate more space for the array. Used internally prior to an items++. 00258 { 00259 Int i; 00260 ObjectPtr *newObjArray; 00261 00262 if (allocated == 0) 00263 allocated = kFirstObjAlloc; 00264 else 00265 allocated *= 2; 00266 00267 newObjArray = new ObjectPtr[allocated]; 00268 00269 for (i = 0; i < items; i++) 00270 newObjArray[i] = item[i]; 00271 00272 delete[] item; 00273 item = newObjArray; 00274 }