1//
2//  PtrBuffer.m
3//  ANTLR
4//
5//  Created by Alan Condit on 6/9/10.
6// [The "BSD licence"]
7// Copyright (c) 2010 Alan Condit
8// All rights reserved.
9//
10// Redistribution and use in source and binary forms, with or without
11// modification, are permitted provided that the following conditions
12// are met:
13// 1. Redistributions of source code must retain the above copyright
14//    notice, this list of conditions and the following disclaimer.
15// 2. Redistributions in binary form must reproduce the above copyright
16//    notice, this list of conditions and the following disclaimer in the
17//    documentation and/or other materials provided with the distribution.
18// 3. The name of the author may not be used to endorse or promote products
19//    derived from this software without specific prior written permission.
20//
21// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
32#define SUCCESS (0)
33#define FAILURE (-1)
34
35#import "PtrBuffer.h"
36#import "Tree.h"
37
38/*
39 * Start of PtrBuffer
40 */
41@implementation PtrBuffer
42
43@synthesize BuffSize;
44@synthesize buffer;
45@synthesize ptrBuffer;
46@synthesize count;
47@synthesize ptr;
48
49+(PtrBuffer *)newPtrBuffer
50{
51    return [[PtrBuffer alloc] init];
52}
53
54+(PtrBuffer *)newPtrBufferWithLen:(NSInteger)cnt
55{
56    return [[PtrBuffer alloc] initWithLen:cnt];
57}
58
59-(id)init
60{
61    NSUInteger idx;
62
63    self = [super init];
64    if ( self != nil ) {
65        BuffSize  = BUFFSIZE;
66        ptr = 0;
67        buffer = [[NSMutableData dataWithLength:(NSUInteger)BuffSize * sizeof(id)] retain];
68        ptrBuffer = (id *) [buffer mutableBytes];
69        for( idx = 0; idx < BuffSize; idx++ ) {
70            ptrBuffer[idx] = nil;
71        }
72        count = 0;
73    }
74    return( self );
75}
76
77-(id)initWithLen:(NSUInteger)cnt
78{
79    NSUInteger idx;
80
81    self = [super init];
82    if ( self != nil ) {
83        BuffSize  = cnt;
84        ptr = 0;
85        buffer = [[NSMutableData dataWithLength:(NSUInteger)BuffSize * sizeof(id)] retain];
86        ptrBuffer = (id *)[buffer mutableBytes];
87        for( idx = 0; idx < BuffSize; idx++ ) {
88            ptrBuffer[idx] = nil;
89        }
90        count = 0;
91    }
92    return( self );
93}
94
95-(void)dealloc
96{
97#ifdef DEBUG_DEALLOC
98    NSLog( @"called dealloc in PtrBuffer" );
99#endif
100    LinkBase *tmp, *rtmp;
101    NSInteger idx;
102
103    if ( self.fNext != nil ) {
104        for( idx = 0; idx < BuffSize; idx++ ) {
105            tmp = ptrBuffer[idx];
106            while ( tmp ) {
107                rtmp = tmp;
108                if ([tmp isKindOfClass:[LinkBase class]])
109                    tmp = (id)tmp.fNext;
110                else
111                    tmp = nil;
112                [rtmp release];
113            }
114        }
115    }
116    [buffer release];
117    [super dealloc];
118}
119
120- (id) copyWithZone:(NSZone *)aZone
121{
122    PtrBuffer *copy;
123
124    copy = [[[self class] allocWithZone:aZone] init];
125    if ( buffer )
126        copy.buffer = [buffer copyWithZone:aZone];
127    copy.ptrBuffer = ptrBuffer;
128    copy.ptr = ptr;
129    return copy;
130}
131
132- (void)clear
133{
134    LinkBase *tmp, *rtmp;
135    NSInteger idx;
136
137    for( idx = 0; idx < BuffSize; idx++ ) {
138        tmp = ptrBuffer[idx];
139        while ( tmp ) {
140            rtmp = tmp;
141            if ([tmp isKindOfClass:[LinkBase class]])
142                tmp = (id)tmp.fNext;
143            else
144                tmp = nil;
145            [rtmp dealloc];
146        }
147        ptrBuffer[idx] = nil;
148    }
149    count = 0;
150}
151
152- (NSMutableData *)getBuffer
153{
154    return( buffer );
155}
156
157- (void)setBuffer:(NSMutableData *)np
158{
159    buffer = np;
160}
161
162- (NSUInteger)getCount
163{
164    return( count );
165}
166
167- (void)setCount:(NSUInteger)aCount
168{
169    count = aCount;
170}
171
172- (id *)getPtrBuffer
173{
174    return( ptrBuffer );
175}
176
177- (void)setPtrBuffer:(id *)np
178{
179    ptrBuffer = np;
180}
181
182- (NSUInteger)getPtr
183{
184    return( ptr );
185}
186
187- (void)setPtr:(NSUInteger)aPtr
188{
189    ptr = aPtr;
190}
191
192- (void) addObject:(id) v
193{
194    [self ensureCapacity:ptr];
195    if ( v ) [v retain];
196    ptrBuffer[ptr++] = v;
197    count++;
198}
199
200- (void) push:(id) v
201{
202    if ( ptr >= BuffSize - 1 ) {
203        [self ensureCapacity:ptr];
204    }
205    if ( v ) [v retain];
206    ptrBuffer[ptr++] = v;
207    count++;
208}
209
210- (id) pop
211{
212    id v = nil;
213    if ( ptr > 0 ) {
214        v = ptrBuffer[--ptr];
215        ptrBuffer[ptr] = nil;
216    }
217    count--;
218    if ( v ) [v release];
219    return v;
220}
221
222- (id) peek
223{
224    id v = nil;
225    if ( ptr > 0 ) {
226        v = ptrBuffer[ptr-1];
227    }
228    return v;
229}
230
231- (NSUInteger)count
232{
233#ifdef DONTUSENOMO
234    int cnt = 0;
235
236    for (NSInteger i = 0; i < BuffSize; i++ ) {
237        if ( ptrBuffer[i] != nil ) {
238            cnt++;
239        }
240    }
241    if ( cnt != count ) count = cnt;
242#endif
243    return count;
244}
245
246- (NSUInteger)length
247{
248    return BuffSize;
249}
250
251- (NSUInteger)size
252{
253    NSUInteger aSize = 0;
254    for (int i = 0; i < BuffSize; i++ ) {
255        if (ptrBuffer[i] != nil) {
256            aSize += sizeof(id);
257        }
258    }
259    return aSize;
260}
261
262- (void) insertObject:(id)aRule atIndex:(NSUInteger)idx
263{
264    if ( idx >= BuffSize ) {
265        [self ensureCapacity:idx];
266    }
267    if ( aRule != ptrBuffer[idx] ) {
268        if ( ptrBuffer[idx] ) [ptrBuffer[idx] release];
269        if ( aRule ) [aRule retain];
270    }
271    ptrBuffer[idx] = aRule;
272    count++;
273}
274
275- (id)objectAtIndex:(NSUInteger)idx
276{
277    if ( idx < BuffSize ) {
278        return ptrBuffer[idx];
279    }
280    return nil;
281}
282
283- (void)addObjectsFromArray:(PtrBuffer *)anArray
284{
285    NSInteger cnt, i;
286    cnt = [anArray count];
287    for( i = 0; i < cnt; i++) {
288        id tmp = [anArray objectAtIndex:i];
289        if ( tmp ) [tmp retain];
290        [self insertObject:tmp atIndex:i];
291    }
292    count += cnt;
293    return;
294}
295
296- (void)removeAllObjects
297{
298    int i;
299    for ( i = 0; i < BuffSize; i++ ) {
300        if ( ptrBuffer[i] ) [ptrBuffer[i] release];
301        ptrBuffer[i] = nil;
302    }
303    count = 0;
304    ptr = 0;
305}
306
307- (void)removeObjectAtIndex:(NSInteger)idx
308{
309    int i;
310    if ( idx >= 0 && idx < count ) {
311        if ( ptrBuffer[idx] ) [ptrBuffer[idx] release];
312        for ( i = idx; i < count-1; i++ ) {
313            ptrBuffer[i] = ptrBuffer[i+1];
314        }
315        ptrBuffer[i] = nil;
316        count--;
317    }
318}
319
320- (void) ensureCapacity:(NSUInteger) anIndex
321{
322    if ((anIndex * sizeof(id)) >= [buffer length])
323    {
324        NSInteger newSize = ([buffer length] / sizeof(id)) * 2;
325        if (anIndex > newSize) {
326            newSize = anIndex + 1;
327        }
328        BuffSize = newSize;
329        [buffer setLength:(BuffSize * sizeof(id))];
330        ptrBuffer = [buffer mutableBytes];
331    }
332}
333
334- (NSString *) description
335{
336    NSMutableString *str;
337    NSInteger idx, cnt;
338    cnt = [self count];
339    str = [NSMutableString stringWithCapacity:30];
340    [str appendString:@"["];
341    for (idx = 0; idx < cnt; idx++ ) {
342        [str appendString:[[self objectAtIndex:idx] description]];
343    }
344    [str appendString:@"]"];
345    return str;
346}
347
348- (NSString *) toString
349{
350    return [self description];
351}
352
353@end
354