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.