2 Copyright (C) 2000-2005 SKYRIX Software AG
4 This file is part of SOPE.
6 SOPE is free software; you can redistribute it and/or modify it under
7 the terms of the GNU Lesser General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 SOPE is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14 License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with SOPE; see the file COPYING. If not, write to the
18 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
24 #include "NGMemoryAllocation.h"
26 @interface _NGConcreteStackEnumerator : NSEnumerator
28 NGStack *stack; // for retain
31 BOOL downWard; // top=>down
34 - (id)initWithStack:(NGStack *)_stack trace:(id *)_ptr count:(int)_size
35 topDown:(BOOL)_downWard;
41 @implementation NGStack
43 + (id)stackWithCapacity:(unsigned int)_capacity {
44 return [[[self alloc] initWithCapacity:_capacity] autorelease];
47 return [[[self alloc] init] autorelease];
49 + (id)stackWithArray:(NSArray *)_array {
50 return [[[self alloc] initWithArray:_array] autorelease];
54 return [self initWithCapacity:256];
56 - (id)initWithCapacity:(unsigned int)_capacity {
57 if ((self = [super init])) {
59 capacity = (_capacity > 0) ? _capacity : 16;
61 stack = NGMalloc(sizeof(id) * capacity);
65 - (id)initWithArray:(NSArray *)_array {
66 register unsigned int count = [_array count];
68 if ((self = [self initWithCapacity:(count + 1)])) {
71 for (cnt = 0; cnt < count; cnt++)
72 [self push:[_array objectAtIndex:cnt]];
87 - (void)_increaseStack {
88 if (capacity > 256) capacity += 256;
91 stack = NGRealloc(stack, sizeof(id) * capacity);
96 - (unsigned int)capacity {
99 - (unsigned int)stackPointer {
102 - (unsigned int)count {
106 return (stackPointer == 0);
111 - (void)push:(id)_obj {
113 if (stackPointer >= capacity) [self _increaseStack];
114 stack[stackPointer] = [_obj retain];
118 id obj = stack[stackPointer];
119 if (stackPointer <= 0) {
120 [[[NGStackException alloc] initWithName:@"StackException"
121 reason:@"tried to pop an object from an empty stack !"
122 userInfo:nil] raise];
124 stack[stackPointer] = nil;
126 return [obj autorelease];
131 for (cnt = 1; cnt <= stackPointer; cnt++) {
132 #if !LIB_FOUNDATION_BOEHM_GC
133 [stack[cnt] release];
143 return (stackPointer == 0) ? nil : stack[stackPointer];
145 - (id)elementAtBottom {
146 return (stackPointer == 0) ? nil : stack[1];
149 - (NSEnumerator *)topDownEnumerator {
150 if (stackPointer == 0)
153 return [[[_NGConcreteStackEnumerator alloc]
154 initWithStack:self trace:&(stack[stackPointer])
155 count:stackPointer topDown:YES] autorelease];
157 - (NSEnumerator *)bottomUpEnumerator {
158 if (stackPointer == 0)
161 return [[[_NGConcreteStackEnumerator alloc]
162 initWithStack:self trace:&(stack[1])
163 count:stackPointer topDown:NO] autorelease];
168 - (Class)classForCoder {
169 return [NGStack class];
172 - (void)encodeWithCoder:(NSCoder *)_encoder {
175 [_encoder encodeValueOfObjCType:@encode(unsigned int) at:&capacity];
176 [_encoder encodeValueOfObjCType:@encode(unsigned int) at:&stackPointer];
178 for (cnt = 1; cnt <= stackPointer; cnt++) {
180 [_encoder encodeObject:obj];
184 - (id)initWithCoder:(NSCoder *)_decoder {
188 [_decoder decodeValueOfObjCType:@encode(unsigned int) at:&tmpCapacity];
189 [_decoder decodeValueOfObjCType:@encode(unsigned int) at:&tmpStackPointer];
191 self = [self initWithCapacity:tmpCapacity];
195 for (cnt = 1; cnt <= tmpStackPointer; cnt++) {
196 id obj = [_decoder decodeObject];
197 stack[cnt] = [obj retain];
199 stackPointer = tmpStackPointer;
206 - (id)copyWithZone:(NSZone *)_zone {
207 register NGStack *newStack = nil;
208 register unsigned cnt;
210 newStack = [[NGStack allocWithZone:(_zone ? _zone : NSDefaultMallocZone())]
211 initWithCapacity:[self stackPointer]];
213 for (cnt = 1; cnt <= stackPointer; cnt++)
214 [newStack push:stack[cnt]];
221 - (NSString *)description {
222 return [NSString stringWithFormat:
223 @"<%@[0x%p] capacity=%u SP=%u count=%u content=%s>",
224 NSStringFromClass([self class]), (unsigned)self,
225 [self capacity], [self stackPointer], [self count],
226 [[[self toArray] description] cString]];
229 - (NSArray *)toArray {
230 register NSMutableArray *array = nil;
231 register unsigned cnt;
233 array = [[NSMutableArray alloc] initWithCapacity:stackPointer];
235 for (cnt = 1; cnt <= stackPointer; cnt++)
236 [array addObject:stack[cnt]];
238 return [array autorelease];
243 @implementation _NGConcreteStackEnumerator
245 - (id)initWithStack:(NGStack *)_stack trace:(id *)_ptr count:(int)_size
246 topDown:(BOOL)_downWard {
248 stack = [_stack retain];
251 downWard = _downWard;
257 [self->stack release];
272 if (downWard) trace--; // top=>bottom (downward)
273 else trace++; // bottom=>top (upward)
280 @implementation NGStackException
281 @end /* NGStackException */
283 @implementation NSMutableArray(StackImp)
287 - (unsigned int)stackPointer {
288 return ([self count] - 1);
292 return ([self count] == 0) ? YES : NO;
297 - (void)push:(id)_obj {
298 [self addObject:_obj];
301 unsigned lastIdx = ([self count] - 1);
304 id element = [self objectAtIndex:lastIdx];
305 [self removeObjectAtIndex:lastIdx];
309 [[[NGStackException alloc] initWithName:@"StackException"
310 reason:@"tried to pop an object from an empty stack !"
311 userInfo:nil] raise];
317 [self removeAllObjects];
323 return [self lastObject];
326 - (NSEnumerator *)topDownEnumerator {
327 return [self reverseObjectEnumerator];
329 - (NSEnumerator *)bottomUpEnumerator {
330 return [self objectEnumerator];
333 @end /* NSMutableArray(NGStack) */
335 void __link_NGExtensions_NGStack() {
336 __link_NGExtensions_NGStack();