This is Storage.m in view mode; [Download] [Up]
/* Implementation of Objective C NeXT-compatible Storage object Copyright (C) 1993 R. Andrew McCallum <mccallum@cs.rochester.edu> Dept. of Computer Science, U. of Rochester, Rochester, NY 14627 Copyright (C) 1993 Kresten Krab Thorup <krab@iesd.auc.dk> Dept. of Mathematics and Computer Science, Aalborg U., Denmark This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <coll/Storage.h> #include <stdlib.h> #define STORAGE_NTH(N) GNU_STORAGE_NTH (self, N) @implementation Storage + initialize { if (self == [Storage class]) [self setVersion:-1]; /* alpha release */ return self; } // INITIALIZING, FREEING; - initCount:(unsigned)numSlots elementSize:(unsigned)sizeInBytes description:(const char*)elemDesc; { [super init]; numElements = 0; maxElements = numSlots; elementSize = sizeInBytes; description = elemDesc; dataPtr = (void**) malloc(maxElements * elementSize); return self; } - init { return [self initCount:1 elementSize:sizeof(id) description:"@"]; } - free { if (dataPtr) free(dataPtr); return [super free]; } - (const char*)description { return description; } // COPYING; - shallowCopy { Storage *c = [super shallowCopy]; c->dataPtr = (void**) malloc(maxElements * elementSize); bcopy(dataPtr, c->dataPtr, numElements * elementSize); return c; } // COMPARING TWO STORAGES; - (BOOL)isEqual: anObject { if ([anObject isKindOf: [Storage class]] && [anObject count] == [self count] && !bcmp(((GNUStorageId*)anObject)->dataPtr, dataPtr, numElements*elementSize)) return YES; else return NO; } // MANAGING THE STORAGE CAPACITY; - (unsigned)capacity { return maxElements; } static inline void _makeRoomForAnotherIfNecessary(Storage *self) { if (self->numElements == self->maxElements) { self->maxElements *= 2; self->dataPtr = (void**) realloc(self->dataPtr, self->maxElements*self->elementSize); } } static inline void _shrinkIfDesired(Storage *self) { if (self->numElements < (self->maxElements / 2)) { self->maxElements /= 2; self->dataPtr = (void *) realloc(self->dataPtr, self->maxElements*self->elementSize); } } - setAvailableCapacity:(unsigned)numSlots { if (numSlots > numElements) { maxElements = numSlots; dataPtr = (void**) realloc(dataPtr, maxElements * elementSize); } return self; } - setNumSlots:(unsigned)numSlots { if (numSlots > numElements) { maxElements = numSlots; dataPtr = (void**) realloc(dataPtr, maxElements * elementSize); } else if (numSlots < numElements) { numElements = numSlots; _shrinkIfDesired (self); } return self; } /* Manipulating objects by index */ #define CHECK_INDEX(IND) if (IND >= numElements) return 0 - (unsigned)count { return numElements; } - (void*)elementAt:(unsigned)index { CHECK_INDEX(index); return STORAGE_NTH (index); } - (void*)lastElement { if (numElements) return STORAGE_NTH(numElements-1); else return 0; } - addElement:(void*)anElement { _makeRoomForAnotherIfNecessary(self); memcpy(STORAGE_NTH(numElements), anElement, elementSize); numElements++; return self; } - insertElement:(void*)anElement at:(unsigned)index { int i; CHECK_INDEX(index); _makeRoomForAnotherIfNecessary(self); #ifndef STABLE_MEMCPY for (i = numElements; i >= index; i--) memcpy (STORAGE_NTH(i+1), STORAGE_NTH(i), elementSize); #else memcpy (STORAGE_NTH (index+1), STORAGE_NTH (index), elementSize*(numElements-index)); #endif memcpy(STORAGE_NTH(i), anElement, elementSize); return self; } - removeElementAt:(unsigned)index { int i; CHECK_INDEX(index); numElements--; #ifndef STABLE_MEMCPY for (i = index; i < numElements; i++) memcpy(STORAGE_NTH(i), STORAGE_NTH(i+1), elementSize); #else memcpy (STORAGE_NTH (index), STORAGE_NTH (index+1), elementSize*(numElements-index-1)); #endif _shrinkIfDesired(self); return self; } - (void*)removeLastElement { if (numElements) { numElements--; _shrinkIfDesired(self); return STORAGE_NTH(numElements); } return 0; } - replaceElementAt:(unsigned)index with:(void*)newElement { CHECK_INDEX(index); memcpy(STORAGE_NTH(index), newElement, elementSize); return self; } - appendStorage: (Storage *)otherStorage { int c = [otherStorage count]; if (elementSize == otherStorage->elementSize) { [self setAvailableCapacity: numElements+c]; memcpy (STORAGE_NTH (numElements), otherStorage->dataPtr, c*elementSize); numElements += c; return self; } else [self error: "incompatible storage sizes in %s", sel_get_name(_cmd)]; return self; } /* Manipulating element */ - (unsigned)indexOf:(void*)anElement { int i; for (i = 0; i < numElements; i++) if (!bcmp (STORAGE_NTH(i), anElement, elementSize)) return i; return GNU_NOT_IN_STORAGE; } - addElementIfAbsent:(void*)anElement { if ([self indexOf:anElement] == GNU_NOT_IN_STORAGE) [self addElement:anElement]; return self; } - removeElement:(void*)anElement { return [self removeElementAt:[self indexOf:anElement]]; } - replaceElement:(void*)anElement with:(void*)newElement { return [self replaceElementAt:[self indexOf:anElement] with:newElement]; } /* Emptying the Storage */ - empty { numElements = 0; maxElements = 1; dataPtr = (void**) realloc(dataPtr, maxElements * elementSize); return self; } /* Archiving */ - storeOn:(int)aFd { return [self notImplemented:_cmd]; } - readFrom:(int)aFd { return [self notImplemented:_cmd]; } - sortUsingFunction: (int(*)(void*, void*))comparisonFunction { qsort(dataPtr, numElements, elementSize, comparisonFunction); return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.