home *** CD-ROM | disk | FTP | other *** search
- // CmOrdArr.cpp
- // -----------------------------------------------------------------
- // Compendium - C++ Container Class Library
- // Copyright (C) 1992-1994, Glenn M. Poorman, All rights reserved
- // -----------------------------------------------------------------
- // Ordered array implementation.
- // -----------------------------------------------------------------
-
- #include <cm/include/cmordarr.h>
-
-
- // "CmOrderedArray" is the default array constructor.
- //
- CmOrderedArray::CmOrderedArray(unsigned sz, unsigned dt)
- {
- _delta = dt;
- _total = 0;
- _entries = (sz > 0) ? new CmObject*[sz] : NULL;
- _size = (_entries != NULL) ? sz : 0;
- }
-
-
- // "CmOrderedArray" is the array copy constructor.
- //
- CmOrderedArray::CmOrderedArray(const CmOrderedArray& A)
- {
- _delta = A._delta;
- _total = 0;
- _entries = (A._size > 0) ? new CmObject*[A._size] : NULL;
- _size = (_entries != NULL) ? A._size : 0;
- copy(A);
- }
-
-
- // "~CmOrderedArray" is the array destructor.
- //
- CmOrderedArray::~CmOrderedArray()
- {
- removeAll();
- delete[] _entries;
- }
-
-
- // "=" assignement operator copies the contents of the specified
- // array into this array.
- //
- CmOrderedArray& CmOrderedArray::operator=(const CmOrderedArray& A)
- {
- if (&A != this)
- {
- removeAll();
- delete[] _entries;
- _delta = A._delta;
- _total = 0;
- _entries = (A._size > 0) ? new CmObject*[A._size] : NULL;
- _size = (_entries != NULL) ? A._size : 0;
- copy(A);
- }
- return *this;
- }
-
-
- // "add" appends the specified object to the array.
- //
- Bool CmOrderedArray::add(CmObject* pObj)
- {
- if (!pObj) return FALSE;
-
- if (_total >= _size)
- if (_delta == 0 || !resize(_size+_delta))
- return FALSE;
-
- int idx = shouldGo(pObj);
- if (idx == -1) return FALSE;
-
- if (idx != _total)
- {
- size_t sz = (_total - idx) * sizeof(CmObject*);
- memmove(&(_entries[idx+1]), &(_entries[idx]), sz);
- }
-
- _entries[idx] = pObj;
- _total++;
- return TRUE;
- }
-
-
- // "remove" removes the first occurrence of an object that isEqual to
- // the specified object from the array.
- //
- Bool CmOrderedArray::remove(CmObject* pObj)
- {
- if (_total == 0 || !pObj) return FALSE;
- int ii = 0;
- Bool found = FALSE;
- while (ii < _total && !found)
- if (_entries[ii++]->isEqual(pObj)) found = TRUE;
- return (found) ? removeAt(ii-1) : FALSE;
- }
-
-
- // "removeAt" removes the object at the specified index.
- //
- Bool CmOrderedArray::removeAt(int idx)
- {
- if (idx < 0 || idx >= _total) return FALSE;
-
- if (ownsObjects()) delete _entries[idx];
- size_t sz = (_total - idx + 1) * sizeof(CmObject*);
- memmove(&(_entries[idx]), &(_entries[idx+1]), sz);
- _entries[_total-1] = NULL;
- _total--;
- return TRUE;
- }
-
-
- // "index" returns the index of the first occurrence of an object
- // that isEqual to the specified object.
- //
- int CmOrderedArray::index(CmObject* pObj) const
- {
- if (_total == 0 || !pObj) return FALSE;
- int ii = 0;
- int idx = -1;
- while (ii < _total && idx == -1)
- if (_entries[ii++]->isEqual(pObj)) idx = ii-1;
- return idx;
- }
-
-
- // "shouldGo" reports the index where the specified object would be
- // inserted if it were added to the array.
- //
- int CmOrderedArray::shouldGo(CmObject* pObj) const
- {
- if (!pObj || _total == _size) return -1;
-
- if (_total == 0) return 0;
- if (pObj->compare(_entries[_total-1]) >= 0) return _total;
-
- int idx = -1;
- int ii = 0;
- while (ii < _total && idx == -1)
- {
- if (pObj->compare(_entries[ii]) < 0) idx = ii;
- else ii++;
- }
-
- return idx;
- }
-
-
- // "lookup" returns the first occurrence of an object that isEqual
- // to the specified object.
- //
- CmObject* CmOrderedArray::lookup(CmObject* pObj) const
- {
- int idx = index(pObj);
- return (idx > -1) ? _entries[idx] : NULL;
- }
-
-
- // "occurrences" returns the number of objects in the array
- // isEqual to the specified object.
- //
- unsigned CmOrderedArray::occurrences(CmObject* pObj) const
- {
- if (_total == 0 || !pObj) return 0;
-
- int ii = 0;
- unsigned num = 0;
- while (ii < _total)
- if (_entries[ii++]->isEqual(pObj)) num++;
- return num;
- }
-
-
- // "removeAll" removes all objects from the array.
- //
- void CmOrderedArray::removeAll()
- {
- for (int ii = 0; ii < _total; ii++)
- {
- if (ownsObjects()) delete _entries[ii];
- _entries[ii] = NULL;
- }
- _total = 0;
- }
-
-
- // "resize" resizes the storage allocated for this array.
- //
- Bool CmOrderedArray::resize(unsigned newSize)
- {
- if (newSize == 0)
- {
- removeAll();
- delete[] _entries;
- _entries = NULL;
- _size = 0;
- return TRUE;
- }
-
- CmObject **newEntries = new CmObject*[newSize];
- if (!newEntries) return FALSE;
-
- if (newSize < _total)
- {
- for (int ii = newSize; ii < _total; ii++)
- if (ownsObjects()) delete _entries[ii];
- _total = newSize;
- }
-
- memmove(newEntries, _entries, _total * sizeof(CmObject*));
-
- delete[] _entries;
- _entries = newEntries;
- _size = newSize;
- return TRUE;
- }
-
-
- // "isEmpty" checks if the array is empty or not.
- //
- Bool CmOrderedArray::isEmpty() const
- {
- return (_total == 0);
- }
-
-
- // "newIterator" creates and returns an array iterator.
- //
- CmIterator* CmOrderedArray::newIterator() const
- {
- return new CmOrderedArrayIterator(*this);
- }
-
-
- // "write" writes the array objects to the specified reserve file.
- //
- Bool CmOrderedArray::write(CmReserveFile& file) const
- {
- if (!writeBase(file)) return FALSE; // Write base container.
- if (!file.write(_delta)) return FALSE; // Write delta value.
- if (!file.write(_total)) return FALSE; // Write number of objects.
-
- Bool success = TRUE;
- int ii = 0;
- while (ii < _total && success) // For each object.
- success = _entries[ii++]->writeObject(file); // Write the object.
- return success;
- }
-
-
- // "read" reads the array objects from the specified reserve file.
- //
- Bool CmOrderedArray::read(CmReserveFile& file)
- {
- unsigned size = readBase(file); // Read base container.
-
- unsigned total;
- if (!file.read(_delta)) return FALSE; // Read delta value.
- if (!file.read(total)) return FALSE; // Read number of objects.
- if (!resize(size)) return FALSE; // Resize the array.
-
- removeAll();
-
- Bool success = TRUE;
- int ii = 0;
- while (ii < total && success) // For each object,
- {
- CmObject *pObj = CmObject::readObject(file); // Read object.
- if (pObj) success = add(pObj); ii++; // Add to array.
- }
- return success;
- }
-