]> err.no Git - sope/blob - sope-xml/STXSaxDriver/ExtraSTX/StructuredStack.m
added support for XML-RPC 'nil' type
[sope] / sope-xml / STXSaxDriver / ExtraSTX / StructuredStack.m
1 /*
2   Copyright (C) 2004 eXtrapola Srl
3
4   This file is part of SOPE.
5
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
9   later version.
10
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.
15
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
19   02111-1307, USA.
20 */
21
22 #import "StructuredStack.h"
23 #include "common.h"
24
25 @implementation StructuredStack
26
27 - (void)dealloc {
28   [self->_stack release];
29   [super dealloc];
30 }
31
32 /* accessors */
33
34 - (NSMutableArray *)stack {
35   if (self->_stack == nil)
36     // TODO: find a proper capacity
37     self->_stack = [[NSMutableArray alloc] initWithCapacity:16];
38
39   return _stack;
40 }
41
42 /* operations */
43
44 - (void)removeAllObjects {
45   [[self stack] removeAllObjects];
46   [self first];
47 }
48
49 - (void)push:(id)anObject {
50   NSMutableArray *stack;
51   
52   if (anObject == nil)
53     return;
54   
55   stack = [self stack];
56   [stack addObject:anObject];
57   
58   if (![self cursorFollowsFIFO])
59     return;
60
61   self->start = NO;
62   self->pos   = ([stack count] - 1);
63 }
64
65 - (id)pop {
66   NSMutableArray *stack;
67   int count;
68   id object;
69
70   object = nil;
71
72   stack = [self stack];
73   count = [stack count];
74   
75   if (count > 0) {
76     object = [stack objectAtIndex:--count];
77
78     [stack removeLastObject];
79   }
80
81   if ([self cursorFollowsFIFO]) {
82     start = NO;
83     pos = count - 1;
84   }
85
86   return object;
87 }
88
89 - (void)first {
90   pos = 0;
91   start = YES;
92 }
93 - (void)last {
94   pos = [[self stack] count];
95   start = NO;
96 }
97
98 /* enumerator */
99
100 - (id)nextObject {
101   NSMutableArray *stack;
102   int count;
103
104   stack = [self stack];
105   count = [stack count];
106
107   if (count == 0 || pos >= count) {
108     return nil;
109   }
110
111   if (self->start) {
112     self->start = NO;
113   } 
114   else {
115     pos++;
116
117     if (pos >= count)
118       return nil;
119   }
120
121   return [stack objectAtIndex:pos];
122 }
123
124 - (id)currentObject {
125   NSMutableArray *stack;
126   int count;
127
128   stack = [self stack];
129   count = [stack count];
130
131   if (count == 0 || pos >= count)
132     return nil;
133   
134   self->start = NO;
135
136   return [[self stack] objectAtIndex:pos];
137 }
138
139 - (id)prevObject {
140   NSMutableArray *stack;
141   id result;
142
143   stack = [self stack];
144   
145   result = ((start || pos == 0) && [stack count])
146     ? nil
147     : [stack objectAtIndex:--pos];
148   return result;
149 }
150
151 - (void)setCursorFollowsFIFO:(BOOL)aValue {
152   self->cursorFIFO = aValue;
153 }
154 - (BOOL)cursorFollowsFIFO {
155   return self->cursorFIFO;
156 }
157
158 - (id)objectRelativeToCursorAtIndex:(int)anIndex {
159   NSMutableArray *stack;
160   int i, count;
161
162   stack = [self stack];
163   count = [stack count];
164
165   i = pos + anIndex;
166
167   if (count == 0 || i < 0 || i >= count)
168     return nil;
169   
170   return [[self stack] objectAtIndex:i];
171 }
172
173 @end /* StructuredStack */