|
|
1.1 root 1: /*
2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7: * Reserved. This file contains Original Code and/or Modifications of
8: * Original Code as defined in and that are subject to the Apple Public
9: * Source License Version 1.0 (the 'License'). You may not use this file
10: * except in compliance with the License. Please obtain a copy of the
11: * License at http://www.apple.com/publicsource and read it before using
12: * this file.
13: *
14: * The Original Code and all software distributed under the License are
15: * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19: * License for the specific language governing rights and limitations
20: * under the License."
21: *
22: * @APPLE_LICENSE_HEADER_END@
23: */
24: /*
25: Storage.m
26: Copyright 1988, 1989 NeXT, Inc.
27: Responsibility: Bertrand Serlet
28:
29: */
30:
31: #ifndef KERNEL
32: #ifdef SHLIB
33: #import "shlib.h"
34: #endif SHLIB
35:
36: #import <stdlib.h>
37: #import <stdio.h>
38: #import <string.h>
39: #import "Storage.h"
40:
41: /* one invariant is that each block of memory allocated is filled with zeros */
42:
43: #define ELMT(dataPtr, index, elementSize) \
44: ((char *) dataPtr + (index * elementSize))
45:
46: @implementation Storage
47:
48: + initialize
49: {
50: [self setVersion: 1];
51: return self;
52: }
53:
54: + new
55: {
56: return [self newCount: 0 elementSize: sizeof(id) description: "@"];
57: }
58:
59: - init
60: {
61: return [self initCount: 0 elementSize: sizeof(id) description: "@"];
62: }
63:
64: - initCount:(unsigned)count elementSize:(unsigned)sizeInBytes description:(const char *)descriptor
65: {
66: unsigned newSize;
67: NXZone *zone = [self zone];
68:
69: maxElements = count;
70: newSize = maxElements * sizeInBytes;
71: numElements = count;
72: elementSize = sizeInBytes;
73: /* coercion to be fixed when Archiver goes */
74: description = descriptor;
75: if (newSize) {
76: dataPtr = NXZoneMalloc (zone, newSize);
77: bzero(dataPtr, newSize);
78: }
79:
80: return self;
81: }
82:
83: + newCount:(unsigned)count elementSize:(unsigned)sizeInBytes description:(const char *)descriptor
84: {
85: return [[self allocFromZone:NXDefaultMallocZone()]
86: initCount:count elementSize:sizeInBytes description:descriptor];
87: }
88:
89:
90: - free
91: {
92: free(dataPtr);
93: return[super free];
94: }
95:
96: - empty
97: {
98: numElements = 0;
99: return self;
100: }
101:
102: - copyFromZone:(NXZone *)zone
103: {
104: Storage *new = [[[self class] allocFromZone:zone]
105: initCount: numElements elementSize: elementSize
106: description: description];
107: bcopy (dataPtr, new->dataPtr, numElements * elementSize);
108: return new;
109: }
110:
111: - (BOOL) isEqual: anObject
112: {
113: Storage *other;
114: if (! [anObject isKindOf: [self class]]) return NO;
115: other = (Storage *) anObject;
116: return (numElements == other->numElements)
117: && (bcmp (dataPtr, other->dataPtr, numElements * elementSize) == 0);
118: }
119:
120: - setNumSlots:(unsigned)numSlots
121: {
122: NXZone *zone = [self zone];
123:
124: if (numSlots > maxElements)
125: {
126: unsigned old = maxElements;
127:
128: maxElements = numSlots;
129: dataPtr = NXZoneRealloc(zone, dataPtr, maxElements * elementSize);
130: bzero(dataPtr + old * elementSize, (maxElements - old) * elementSize);
131: }
132: numElements = numSlots;
133: return self;
134: }
135:
136: - setAvailableCapacity:(unsigned)numSlots
137: {
138: unsigned old = maxElements;
139: NXZone *zone = [self zone];
140:
141: if (numSlots < numElements) return nil;
142: maxElements = numSlots;
143: dataPtr = NXZoneRealloc(zone, dataPtr, maxElements * elementSize);
144: if (maxElements > old)
145: bzero(dataPtr + old * elementSize, (maxElements - old) * elementSize);
146: return self;
147: }
148:
149: - (const char *) description
150: {
151: return description;
152: }
153:
154:
155: - (unsigned) count
156: {
157: return numElements;
158: }
159:
160: - (void *)elementAt :(unsigned)index
161: {
162: if (index < numElements)
163: return ELMT(dataPtr, index, elementSize);
164: else
165: return NULL;
166: }
167:
168: /* For 2.0 compatibility */
169: - replace:(void *)anElement at:(unsigned )index
170: {
171: return [self replaceElementAt:index with:anElement];
172: }
173:
174: - replaceElementAt:(unsigned)index with:(void *)anElement;
175: {
176: if (index < numElements)
177: bcopy (anElement, ELMT(dataPtr, index, elementSize), elementSize);
178: return self;
179: }
180:
181: - addElement:(void *)anElement
182: {
183: unsigned index = numElements;
184:
185: [self setNumSlots:(numElements + 1)];
186: bcopy (anElement, ELMT(dataPtr, index, elementSize), elementSize);
187: return self;
188: }
189:
190:
191: - removeLastElement
192: {
193: [self setNumSlots:(numElements - 1)];
194: return self;
195: }
196:
197: /* For 2.0 compatibility */
198: - insert:(void *)anElement at:(unsigned)index
199: {
200: return [self insertElement:anElement at:index];
201: }
202:
203: - insertElement:(void *)anElement at:(unsigned)index;
204: {
205: if (index < numElements) {
206: char *start;
207: [self setNumSlots:(numElements + 1)];
208: start = ELMT(dataPtr, index, elementSize);
209: bcopy (start, start + elementSize, (numElements - index - 1) * elementSize);
210: } else
211: [self setNumSlots:(index + 1)];
212: bcopy (anElement, ELMT(dataPtr, index, elementSize), elementSize);
213: return self;
214: }
215:
216:
217: /* For 2.0 compatibility */
218: - removeAt:(unsigned)index
219: {
220: return [self removeElementAt:index];
221: }
222:
223: - removeElementAt:(unsigned)index;
224: {
225: if (index < numElements) {
226: char *start = ELMT(dataPtr, index, elementSize);
227:
228: bcopy(start + elementSize, start, (numElements - index - 1) * elementSize);
229: [self setNumSlots:(numElements - 1)];
230: }
231: return self;
232: }
233:
234:
235: - write:(NXTypedStream *) stream
236: {
237: [super write: stream];
238: NXWriteTypes (stream, "%ii", &description, &elementSize, &numElements);
239: if (numElements)
240: NXWriteArray (stream, description, numElements, dataPtr);
241: return self;
242: }
243:
244: - read:(NXTypedStream *) stream
245: {
246: NXZone *zone = [self zone];
247:
248: [super read: stream];
249: if (NXTypedStreamClassVersion (stream, "Storage") == 0) {
250: unsigned newSize;
251: int _growAmount;
252: NXReadTypes (stream, "*iii", &description, &elementSize, &_growAmount, &numElements);
253: maxElements = numElements;
254: newSize = maxElements * elementSize;
255: dataPtr = (char *) NXZoneMalloc(zone, newSize);
256: bzero(dataPtr, newSize);
257: NXReadArray (stream, description, numElements, dataPtr);
258: } else {
259: NXReadTypes (stream, "%ii", &description, &elementSize, &numElements);
260: maxElements = numElements;
261: if (maxElements) {
262: unsigned newSize = maxElements * elementSize;
263: dataPtr = (char *) NXZoneMalloc(zone, newSize);
264: bzero(dataPtr, newSize);
265: NXReadArray (stream, description, numElements, dataPtr);
266: }
267: }
268: return self;
269: }
270:
271: @end
272: #endif /* KERNEL */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.