home *** CD-ROM | disk | FTP | other *** search
- /*
-
- Collection class definition for GCOOPE 1.0
-
- by Brian Lee Price
-
- Released as Public Domain July, 1994.
-
- Compatible with experimental strong typing option.
-
- While not the best example of object oriented programming,
- this class does demonstrate one method of encapsulating a
- pre-defined set of functions and structures into an object
- class definition.
-
- This class maintains a contiguous section of memory divided into
- fixed size slots, it makes no presumptions about the data entered
- into the slots. When a slot is removed via the rmvUnit generic,
- it will be cleared to all zeros. A firstFree index is maintained
- which is used to find the index value to return when a call is
- made via the addUnit generic. The list may be compacted by the
- compact generic, this call requires a boolean parm 'sorted'. When
- this parm is true the routine will 'squeeze' the list and remove
- the empty slots, otherwise the routine will just reallocate if
- enough empty slots exist at the end of the list to justify it.
-
- The real value of this class is its suitability for ordered or
- unordered dynamic list maintenance and its reduction of memory
- fragmentation by always resizing to a multiple of MIN_LIST_ADD
- slots. An inheritor of this class can manage lists which change
- in size from a minimum of MIN_LIST_ADD elements to a maximum of
- just under 64K in total size. The three kernel functions used by
- this class form the core of the kernel's odbms.
-
- */
-
- #define CLASS Collection
-
- #define _INTERNAL_
-
- #include "gcoope10.h"
-
- #include <mem.h>
-
- object CLASS;
-
- extern object Unsigned;
-
- /*
-
- This class uses a portion of the internal PCOOPE kernel to save code:
-
- -#define DYNLIST_STRU word elemSize,firstFree,maxElems;void * listPtr
-
- -#define MAX_BLOCK_SIZE (65523L)
-
- -#define MIN_LIST_ADD 16
-
- the following functions are defined in listmgr.c
-
- int addItem(void *listPtr, int elemSize);
- int rmvItem(void *listPtr, int elemNdx);
- stat compactList(void *listAdr, boolean sorted);
-
- */
-
- typedef struct {
- DYNLIST_STRU;
- } instVars;
-
- USEGEN(addUnit);
- USEGEN(rmvUnit);
- USEGEN(getUnit);
- USEGEN(valueOf);
- USEGEN(sizeOf);
- USEGEN(addressOf);
- USEGEN(reSize);
- USEGEN(changeVal);
- USEGEN(compact);
- USEGEN(numElems);
-
-
- cmethod object m4New(object instance, word elemSize)
- {
- instVars * ivptr;
-
- if(NULL==(ivptr=makeInst(&instance))) return 0;
- ivptr->elemSize=elemSize;
- ivptr->listPtr=NULL;
- g(New)(ST(Unsigned),0);
- return instance;
- }
-
-
- /* returns the offset of the newly created slot */
-
- imethod int m4addUnit(object instance, void * newUnit)
- {
- instVars * ivptr;
- char * newSlot;
- int offset=-1;
-
- if(NULL==(ivptr=getIVptr(instance))) goto end;
- if((offset=addItem(ivptr->listPtr, ivptr->elemSize))<0) goto end;
- if(newUnit)
- {
- newSlot=ivptr->listPtr;
- newSlot+= ivptr->elemSize * offset;
- memcpy(newSlot, newUnit, ivptr->elemSize);
- }
- g(GEN(changeVal))(ST(Unsigned),
- (unsigned short) ((UNSGNDRV)g)(GEN(valueOf))(instance)+1);
-
- end:
- return offset;
- }
-
-
- imethod object m4rmvUnit(object instance, int index)
- {
- instVars * ivptr;
-
- if((NULL==(ivptr=getIVptr(instance))) ||
- (rmvItem(ivptr->listPtr, index)<0)) return FUNCFAIL;
- g(GEN(changeVal))(ST(Unsigned),
- (unsigned short) ((UNSGNDRV)g)(GEN(valueOf))(instance)+1);
-
- return FUNCOKAY;
- }
-
-
- imethod void * m4getUnit(object instance, int index)
- {
- instVars * ivptr;
-
- if((NULL==(ivptr=getIVptr(instance))) ||
- (index<0) || (index>ivptr->maxElems)) return NULL;
- else return (((char *) (ivptr->listPtr))+ index * ivptr->elemSize);
- }
-
-
- imethod word m4sizeOf(object instance)
- {
- return ((instVars *) getIVptr(instance))->elemSize;
- }
-
-
- imethod void * m4addressOf(object instance)
- {
- return ((instVars *) getIVptr(instance))->listPtr;
- }
-
-
- imethod object m4reSize(object instance, unsigned short newNumElems)
- {
- instVars * ivptr;
- int newSize;
- void * temp;
-
- if(NULL==(ivptr=getIVptr(instance))
- || NULL==ivptr->listPtr) return FUNCFAIL;
- newSize=newNumElems;
- newNumElems/=MIN_LIST_ADD;
- if(newSize % MIN_LIST_ADD) newNumElems++;
- newNumElems*=MIN_LIST_ADD;
- newSize = ivptr->elemSize * newNumElems;
- if(newSize < ivptr->maxElems)
- {
- ivptr->listPtr=s_realloc(ivptr->listPtr, newSize);
- if(ivptr->firstFree>newNumElems) ivptr->firstFree=newNumElems;
- if(g(GEN(valueOf))(Unsigned) > newNumElems)
- g(GEN(changeVal))(ST(Unsigned), newNumElems);
- }
- else
- {
- temp = s_calloc(1, newSize);
- memcpy(temp, ivptr->listPtr, ivptr->maxElems);
- s_free(ivptr->listPtr);
- ivptr->listPtr=temp;
- }
- ivptr->maxElems=newNumElems;
- return FUNCOKAY;
- }
-
-
- imethod object m4compact(object instance, boolean sorted)
- {
- instVars * ivptr;
-
- if(NULL==(ivptr=getIVptr(instance))
- || NULL==ivptr->listPtr) return FUNCFAIL;
- return compactList(ivptr->listPtr, sorted);
- }
-
-
- cmethod object m4Kill(object instance)
- {
- s_free(((instVars *) getIVptr(instance))->listPtr);
- g(Kill)(Object, instance);
- return instance;
- }
-
-
- CLASS_INSTALL
- {
- if(END==(CLASS=g(New)(Class, 0, sizeof(instVars), Unsigned, END))) goto err;
- if(addGMthd(CLASS, New, (method) m4New)) goto err;
- if(addGMthd(CLASS, Kill, (method) m4Kill)) goto err;
- if(addGMthd(CLASS, GEN(addUnit), (method) m4addUnit)) goto err;
- if(addGMthd(CLASS, GEN(rmvUnit), (method) m4rmvUnit)) goto err;
- if(addGMthd(CLASS, GEN(getUnit), (method) m4getUnit)) goto err;
- if(rmvGMthd(CLASS, GEN(changeVal))) goto err;
- if(addGMthd(CLASS, GEN(sizeOf), (method) m4sizeOf)) goto err;
- if(addGMthd(CLASS, GEN(addressOf), (method) m4addressOf)) goto err;
- if(addGMthd(CLASS, GEN(reSize), (method) m4reSize)) goto err;
- if(addGMthd(CLASS, GEN(compact), (method) m4compact)) goto err;
- if(RENGM(valueOf, Unsigned, numElems)) goto err;
- return FUNCOKAY;
-
- err:
- return FUNCFAIL;
- }
-