home *** CD-ROM | disk | FTP | other *** search
- /* ArrayOb.c -- member functions of class ArrayOb
-
- THIS SOFTWARE FITS THE DESCRIPTION IN THE U.S. COPYRIGHT ACT OF A
- "UNITED STATES GOVERNMENT WORK". IT WAS WRITTEN AS A PART OF THE
- AUTHOR'S OFFICIAL DUTIES AS A GOVERNMENT EMPLOYEE. THIS MEANS IT
- CANNOT BE COPYRIGHTED. THIS SOFTWARE IS FREELY AVAILABLE TO THE
- PUBLIC FOR USE WITHOUT A COPYRIGHT NOTICE, AND THERE ARE NO
- RESTRICTIONS ON ITS USE, NOW OR SUBSEQUENTLY.
-
- Author:
- K. E. Gorlen
- Bg. 12A, Rm. 2033
- Computer Systems Laboratory
- Division of Computer Research and Technology
- National Institutes of Health
- Bethesda, Maryland 20892
- Phone: (301) 496-1111
- uucp: uunet!nih-csl!kgorlen
- Internet: kgorlen@alw.nih.gov
- September, 1985
-
- Function:
-
- Member function definitions for class ArrayOb (Array of Object*).
- Objects of class ArrayOb are used in the implementations of several
- other Collection classes such as: Bag, Dictionary, Set, and
- OrderedCltn. Note that the ArrayOb constructor initializes the array
- with pointers to the nil object.
-
- $Log: ArrayOb.c,v $
- * Revision 3.0 90/05/20 00:18:54 kgorlen
- * Release for 1st edition.
- *
- */
-
- #include <libc.h>
- #include <malloc.h>
- #include "ArrayOb.h"
- #include "nihclIO.h"
-
- #define THIS ArrayOb
- #define BASE Collection
- #define BASE_CLASSES BASE::desc()
- #define MEMBER_CLASSES
- #define VIRTUAL_BASE_CLASSES
-
- DEFINE_CLASS(ArrayOb,1,"$Header: /afs/alw.nih.gov/unix/sun4_40c/usr/local/src/nihcl-3.0/share/lib/RCS/ArrayOb.c,v 3.0 90/05/20 00:18:54 kgorlen Rel $",NULL,NULL);
-
- extern const int NIHCL_ALLOCSIZE,NIHCL_INDEXRANGE;
-
- /*
- Note: we use malloc()/free() here instead of new/delete because
- we use realloc() to implement reSize().
- */
-
- #define NEW(type,size) ((type*)malloc(sizeof(type)*(size)))
-
- inline void DELETE(Object** ptr) { free((char*)ptr); }
-
- inline Object** REALLOC(Object** ptr, unsigned size)
- {
- return (Object**)realloc((char*)ptr,sizeof(Object*)*size);
- }
-
- ArrayOb::ArrayOb(unsigned size)
- {
- sz = size;
- if (sz==0) allocSizeErr();
- v = NEW(Object*,sz);
- register i = sz;
- register Object** vp = v;
- while (i--) *vp++ = nil;
- }
-
- ArrayOb::ArrayOb(const ArrayOb& a)
- {
- register i = a.sz;
- sz = i;
- v = NEW(Object*,i);
- register Object** vp = v;
- register Object** av = a.v;
- while (i--) *vp++ = *av++;
- }
-
- ArrayOb::~ArrayOb() { DELETE(v); }
-
- void ArrayOb::operator=(const ArrayOb& a)
- {
- if (v != a.v) {
- DELETE(v);
- v = NEW(Object*,sz=a.sz);
- register i = a.sz;
- register Object** vp = v;
- register Object** av = a.v;
- while (i--) *vp++ = *av++;
- }
- }
-
- bool ArrayOb::operator==(const ArrayOb& a) const
- {
- if (sz != a.sz) return NO;
- register unsigned i = sz;
- register Object** vp = v;
- register Object** av = a.v;
- while (i--) { if (!((*vp++)->isEqual(**av++))) return NO; }
- return YES;
- }
-
- Object*& ArrayOb::at(int i) { return (*this)[i]; }
-
- const Object *const& ArrayOb::at(int i) const { return (*this)[i]; }
-
- unsigned ArrayOb::capacity() const { return sz; }
-
- bool ArrayOb::isEqual(const Object& a) const
- {
- return a.isSpecies(classDesc) && *this==castdown(a);
- }
-
- const Class* ArrayOb::species() const { return &classDesc; }
-
- void ArrayOb::reSize(unsigned newsize)
- {
- if (newsize == 0) allocSizeErr();
- v = REALLOC(v,newsize);
- if (newsize > sz) { // initialize new space to nil
- Object** vp = &v[sz];
- while (newsize > sz) {
- *vp++ = nil;
- sz++;
- }
- }
- else sz = newsize;
- }
-
- void ArrayOb::removeAll()
- {
- register Object** vp = v;
- register unsigned i = sz;
- while (i--) *vp++ = nil;
- }
-
- Collection& ArrayOb::addContentsTo(Collection& cltn) const
- {
- register Object** vp = v;
- register unsigned i = sz;
- while (i--) cltn.add(**vp++);
- return cltn;
- }
-
- Object* ArrayOb::doNext(Iterator& pos) const
- {
- if (pos.index < size()) return v[pos.index++];
- return 0;
- }
-
- void ArrayOb::deepenShallowCopy()
- {
- BASE::deepenShallowCopy();
- register i = sz;
- register Object** vp = v;
- while (i--) {
- *vp = (*vp)->deepCopy();
- vp++;
- }
- }
-
- unsigned ArrayOb::hash() const
- {
- register unsigned h = sz;
- register unsigned i = sz;
- register Object** vp = v;
- while (i--) h^=(*vp++)->hash();
- return h;
- }
-
- ArrayOb::ArrayOb(OIOin& strm)
- :
- #ifdef MI
- Object(strm),
- #endif
- BASE(strm)
- {
- strm >> sz;
- v = NEW(Object*,sz);
- for (register unsigned i=0; i<sz; i++) v[i] = Object::readFrom(strm);
- }
-
- void ArrayOb::storer(OIOout& strm) const
- {
- BASE::storer(strm);
- strm << sz;
- for (register unsigned i=0; i<sz; i++) v[i]->storeOn(strm);
- }
-
- unsigned ArrayOb::size() const { return sz; }
-
- static int compare_ob(const void* a, const void* b)
- {
- return (*(const Object**)a)->compare(**(const Object**)b);
- }
-
- void ArrayOb::sort()
- {
- qsort(v,sz,sizeof(Object*),compare_ob);
- }
-
- void ArrayOb::allocSizeErr() const
- {
- setError(NIHCL_ALLOCSIZE,DEFAULT,this,className());
- }
-
- void ArrayOb::indexRangeErr() const
- {
- setError(NIHCL_INDEXRANGE,DEFAULT,this,className());
- }
-
- ArrayOb::ArrayOb(OIOifd& fd)
- :
- #ifdef MI
- Object(fd),
- #endif
- BASE(fd)
- {
- fd >> sz;
- v = NEW(Object*,sz);
- for (register unsigned i=0; i<sz; i++ )
- v[i] = Object::readFrom(fd);
- }
-
- void ArrayOb::storer(OIOofd& fd) const
- {
- BASE::storer(fd);
- fd << sz;
- for (register unsigned i=0; i<sz; i++)
- v[i]->storeOn(fd);
- }
-
- int ArrayOb::compare(const Object& arg) const
- // Compare two arrays of objects. If *this > arg return >0,
- // *this == arg return 0, and if *this < arg return <0.
- {
- assertArgSpecies(arg,classDesc,"compare");
- const ArrayOb& a = castdown(arg);
- for (int i=0; i<sz; i++) {
- // previous elements compared equal; longer ArrayOb is therefore larger
- if (i == a.sz) return 1;
- // compare() != 0 at any element determines ordering
- int val;
- if ((val = v[i]->compare(*a.v[i])) != 0) return val;
- }
- // all elements in this ArrayOb compare() equal to arg ArrayOb
- if (sz == a.sz) return 0;
- return -1;
- }
-
- Object* ArrayOb::add(Object& ob)
- {
- shouldNotImplement("add");
- return &ob;
- }
-
- unsigned ArrayOb::occurrencesOf(const Object&) const
- {
- shouldNotImplement("occurrencesOf");
- return 0;
- }
-
- Object* ArrayOb::remove(const Object&)
- {
- shouldNotImplement("remove");
- return 0;
- }
-