xref: /aosp_15_r20/external/antlr/runtime/ObjC/Framework/AMutableDictionary.m (revision 16467b971bd3e2009fad32dd79016f2c7e421deb)
1*16467b97STreehugger Robot//
2*16467b97STreehugger Robot//  AMutableDictionary.m
3*16467b97STreehugger Robot//  ST4
4*16467b97STreehugger Robot//
5*16467b97STreehugger Robot//  Created by Alan Condit on 4/18/11.
6*16467b97STreehugger Robot//  Copyright 2011 Alan Condit. All rights reserved.
7*16467b97STreehugger Robot//
8*16467b97STreehugger Robot
9*16467b97STreehugger Robot#import <Foundation/Foundation.h>
10*16467b97STreehugger Robot#import "AMutableDictionary.h"
11*16467b97STreehugger Robot#import "ACBTree.h"
12*16467b97STreehugger Robot
13*16467b97STreehugger Robot@implementation AMutableDictionary
14*16467b97STreehugger Robot
15*16467b97STreehugger Robot@synthesize root;
16*16467b97STreehugger Robot@synthesize nodes_av;
17*16467b97STreehugger Robot@synthesize nodes_inuse;
18*16467b97STreehugger Robot@synthesize nxt_nodeid;
19*16467b97STreehugger Robot//@synthesize count;
20*16467b97STreehugger Robot@synthesize data;
21*16467b97STreehugger Robot@synthesize ptrBuffer;
22*16467b97STreehugger Robot
23*16467b97STreehugger Robot+ (AMutableDictionary *) newDictionary
24*16467b97STreehugger Robot{
25*16467b97STreehugger Robot    return [[AMutableDictionary alloc] init];
26*16467b97STreehugger Robot}
27*16467b97STreehugger Robot
28*16467b97STreehugger Robot/** dictionaryWithCapacity
29*16467b97STreehugger Robot *  capacity is meaningless to ACBTree because
30*16467b97STreehugger Robot *  capacity is automatically increased
31*16467b97STreehugger Robot */
32*16467b97STreehugger Robot+ (AMutableDictionary *) dictionaryWithCapacity
33*16467b97STreehugger Robot{
34*16467b97STreehugger Robot    return [[AMutableDictionary alloc] init];
35*16467b97STreehugger Robot}
36*16467b97STreehugger Robot
37*16467b97STreehugger Robot- (id)init
38*16467b97STreehugger Robot{
39*16467b97STreehugger Robot    self = [super init];
40*16467b97STreehugger Robot    if (self) {
41*16467b97STreehugger Robot        // Initialization code here.
42*16467b97STreehugger Robot        nxt_nodeid = 0;
43*16467b97STreehugger Robot        count = 0;
44*16467b97STreehugger Robot        root = [ACBTree newNodeWithDictionary:self];
45*16467b97STreehugger Robot        root.nodeType = LEAF;
46*16467b97STreehugger Robot        root.numrecs = 0;
47*16467b97STreehugger Robot        root.updtd = NO;
48*16467b97STreehugger Robot        root.lnodeid = 1;
49*16467b97STreehugger Robot        root.lnode = nil;
50*16467b97STreehugger Robot        root.rnodeid = 0xffff;
51*16467b97STreehugger Robot        root.rnode = nil;
52*16467b97STreehugger Robot    }
53*16467b97STreehugger Robot    return self;
54*16467b97STreehugger Robot}
55*16467b97STreehugger Robot
56*16467b97STreehugger Robot/** initWithCapacity
57*16467b97STreehugger Robot *  capacity is meaningless to ACBTree because
58*16467b97STreehugger Robot *  capacity is automatically increased
59*16467b97STreehugger Robot */
60*16467b97STreehugger Robot- (id) initWithCapacity:(NSUInteger)numItems
61*16467b97STreehugger Robot{
62*16467b97STreehugger Robot    self = [super init];
63*16467b97STreehugger Robot    if (self) {
64*16467b97STreehugger Robot        // Initialization code here.
65*16467b97STreehugger Robot        nxt_nodeid = 0;
66*16467b97STreehugger Robot        count = 0;
67*16467b97STreehugger Robot        root = [ACBTree newNodeWithDictionary:self];
68*16467b97STreehugger Robot        root.nodeType = LEAF;
69*16467b97STreehugger Robot        root.numrecs = 0;
70*16467b97STreehugger Robot        root.updtd = NO;
71*16467b97STreehugger Robot        root.lnodeid = 1;
72*16467b97STreehugger Robot        root.lnode = nil;
73*16467b97STreehugger Robot        root.rnodeid = 0xffff;
74*16467b97STreehugger Robot        root.rnode = nil;
75*16467b97STreehugger Robot    }
76*16467b97STreehugger Robot    return self;
77*16467b97STreehugger Robot}
78*16467b97STreehugger Robot
79*16467b97STreehugger Robot- (void) dealloc
80*16467b97STreehugger Robot{
81*16467b97STreehugger Robot#ifdef DEBUG_DEALLOC
82*16467b97STreehugger Robot    NSLog( @"called dealloc in AMutableDictionary" );
83*16467b97STreehugger Robot#endif
84*16467b97STreehugger Robot    if ( data ) [data release];
85*16467b97STreehugger Robot    if ( root ) [root release];
86*16467b97STreehugger Robot    [super dealloc];
87*16467b97STreehugger Robot}
88*16467b97STreehugger Robot
89*16467b97STreehugger Robot- (id) objectForKey:(id)aKey
90*16467b97STreehugger Robot{
91*16467b97STreehugger Robot    id obj = nil;
92*16467b97STreehugger Robot    ACBTree *node;
93*16467b97STreehugger Robot    ACBKey *kp;
94*16467b97STreehugger Robot    NSInteger ret;
95*16467b97STreehugger Robot    BOOL mustRelease = NO;
96*16467b97STreehugger Robot
97*16467b97STreehugger Robot    if ( [aKey isKindOfClass:[NSString class]] ) {
98*16467b97STreehugger Robot        kp = [ACBKey newKeyWithKStr:aKey];
99*16467b97STreehugger Robot        mustRelease = YES;
100*16467b97STreehugger Robot    }
101*16467b97STreehugger Robot    else if ( [aKey isKindOfClass:[ACBKey class]] ) {
102*16467b97STreehugger Robot        kp = aKey;
103*16467b97STreehugger Robot        //ACBKey *akey = [ACBKey newKey:aKey];
104*16467b97STreehugger Robot    }
105*16467b97STreehugger Robot    else {
106*16467b97STreehugger Robot        @throw [NSException exceptionWithName:NSInvalidArgumentException
107*16467b97STreehugger Robot                                       reason:[NSString stringWithFormat:@"What kind of key is this? %@", aKey]
108*16467b97STreehugger Robot                                     userInfo:nil];
109*16467b97STreehugger Robot        return nil; // not a key that I know how to deal with
110*16467b97STreehugger Robot    }
111*16467b97STreehugger Robot    node = [root search:kp.key];
112*16467b97STreehugger Robot    if ( node != nil ) {
113*16467b97STreehugger Robot        ret = [node searchnode:kp.key match:YES];
114*16467b97STreehugger Robot        if ( ret >= 0 && ret < node.numkeys ) {
115*16467b97STreehugger Robot            obj = node.btNodes[ret];
116*16467b97STreehugger Robot            if ( obj == [NSNull null] ) {
117*16467b97STreehugger Robot                obj = nil;
118*16467b97STreehugger Robot            }
119*16467b97STreehugger Robot        }
120*16467b97STreehugger Robot    }
121*16467b97STreehugger Robot    if ( mustRelease ) [kp release];
122*16467b97STreehugger Robot    return obj;
123*16467b97STreehugger Robot}
124*16467b97STreehugger Robot
125*16467b97STreehugger Robot- (void) setObject:(id)obj forKey:(id)aKey
126*16467b97STreehugger Robot{
127*16467b97STreehugger Robot    ACBKey *kp;
128*16467b97STreehugger Robot    BOOL mustRelease = NO;
129*16467b97STreehugger Robot    if ( [aKey isKindOfClass:[NSString class]] ) {
130*16467b97STreehugger Robot        kp = [ACBKey newKeyWithKStr:aKey];
131*16467b97STreehugger Robot        mustRelease = YES;
132*16467b97STreehugger Robot    }
133*16467b97STreehugger Robot    else if ( [aKey isKindOfClass:[ACBKey class]] ) {
134*16467b97STreehugger Robot        kp = (ACBKey *)aKey;
135*16467b97STreehugger Robot    }
136*16467b97STreehugger Robot    else {
137*16467b97STreehugger Robot        @throw [NSException exceptionWithName:NSInvalidArgumentException
138*16467b97STreehugger Robot                                       reason:[NSString stringWithFormat:@"What kind of key is this? %@", aKey]
139*16467b97STreehugger Robot                                     userInfo:nil];
140*16467b97STreehugger Robot    }
141*16467b97STreehugger Robot    if ( [root search:kp.key] == nil ) {
142*16467b97STreehugger Robot        if ( obj == nil ) {
143*16467b97STreehugger Robot            obj = [NSNull null];
144*16467b97STreehugger Robot        }
145*16467b97STreehugger Robot        root = [root insertkey:kp value:obj];
146*16467b97STreehugger Robot        [kp retain];
147*16467b97STreehugger Robot        [obj retain];
148*16467b97STreehugger Robot        kp.recnum = count++;
149*16467b97STreehugger Robot    }
150*16467b97STreehugger Robot    else {
151*16467b97STreehugger Robot        if ( mustRelease ) [kp release];
152*16467b97STreehugger Robot        @throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"key alreadyExists" userInfo:nil];
153*16467b97STreehugger Robot    }
154*16467b97STreehugger Robot    return;
155*16467b97STreehugger Robot}
156*16467b97STreehugger Robot
157*16467b97STreehugger Robot- (BOOL) isEqual:(id)object
158*16467b97STreehugger Robot{
159*16467b97STreehugger Robot    return [super isEqual:object];
160*16467b97STreehugger Robot}
161*16467b97STreehugger Robot
162*16467b97STreehugger Robot- (void) removeObjectForKey:(id)aKey
163*16467b97STreehugger Robot{
164*16467b97STreehugger Robot    if ( [root deletekey:aKey] == SUCCESS )
165*16467b97STreehugger Robot        count--;
166*16467b97STreehugger Robot}
167*16467b97STreehugger Robot
168*16467b97STreehugger Robot- (NSUInteger) count
169*16467b97STreehugger Robot{
170*16467b97STreehugger Robot    return count;
171*16467b97STreehugger Robot}
172*16467b97STreehugger Robot
173*16467b97STreehugger Robot- (NSArray *) allKeys
174*16467b97STreehugger Robot{
175*16467b97STreehugger Robot    NSUInteger cnt = [root keyWalkLeaves];
176*16467b97STreehugger Robot    return [NSArray arrayWithObjects:ptrBuffer count:cnt];
177*16467b97STreehugger Robot}
178*16467b97STreehugger Robot
179*16467b97STreehugger Robot- (NSArray *) allValues
180*16467b97STreehugger Robot{
181*16467b97STreehugger Robot    NSUInteger cnt = [root objectWalkLeaves];
182*16467b97STreehugger Robot    return [NSArray arrayWithObjects:ptrBuffer count:cnt];
183*16467b97STreehugger Robot}
184*16467b97STreehugger Robot
185*16467b97STreehugger Robot- (ArrayIterator *) keyEnumerator
186*16467b97STreehugger Robot{
187*16467b97STreehugger Robot    return [ArrayIterator newIterator:[self allKeys]];
188*16467b97STreehugger Robot}
189*16467b97STreehugger Robot
190*16467b97STreehugger Robot- (ArrayIterator *) objectEnumerator
191*16467b97STreehugger Robot{
192*16467b97STreehugger Robot    return [ArrayIterator newIterator:[self allValues]];
193*16467b97STreehugger Robot}
194*16467b97STreehugger Robot
195*16467b97STreehugger Robot// This is where all the magic happens.
196*16467b97STreehugger Robot// You have two choices when implementing this method:
197*16467b97STreehugger Robot// 1) Use the stack based array provided by stackbuf. If you do this, then you must respect the value of 'len'.
198*16467b97STreehugger Robot// 2) Return your own array of objects. If you do this, return the full length of the array returned until you run out of objects, then return 0. For example, a linked-array implementation may return each array in order until you iterate through all arrays.
199*16467b97STreehugger Robot// In either case, state->itemsPtr MUST be a valid array (non-nil). This sample takes approach #1, using stackbuf to store results.
200*16467b97STreehugger Robot- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len
201*16467b97STreehugger Robot{
202*16467b97STreehugger Robot    NSUInteger cnt = 0;
203*16467b97STreehugger Robot    // This is the initialization condition, so we'll do one-time setup here.
204*16467b97STreehugger Robot    // Ensure that you never set state->state back to 0, or use another method to detect initialization
205*16467b97STreehugger Robot    // (such as using one of the values of state->extra).
206*16467b97STreehugger Robot    if (state->state == 0) {
207*16467b97STreehugger Robot        // We are not tracking mutations, so we'll set state->mutationsPtr to point into one of our extra values,
208*16467b97STreehugger Robot        // since these values are not otherwise used by the protocol.
209*16467b97STreehugger Robot        // If your class was mutable, you may choose to use an internal variable that is updated when the class is mutated.
210*16467b97STreehugger Robot        // state->mutationsPtr MUST NOT be NULL.
211*16467b97STreehugger Robot        state->mutationsPtr = &state->extra[0];
212*16467b97STreehugger Robot        [self.root objectWalkLeaves];
213*16467b97STreehugger Robot    }
214*16467b97STreehugger Robot    // Now we provide items, which we track with state->state, and determine if we have finished iterating.
215*16467b97STreehugger Robot    if (state->state < self.count) {
216*16467b97STreehugger Robot        // Set state->itemsPtr to the provided buffer.
217*16467b97STreehugger Robot        // Alternate implementations may set state->itemsPtr to an internal C array of objects.
218*16467b97STreehugger Robot        // state->itemsPtr MUST NOT be NULL.
219*16467b97STreehugger Robot        state->itemsPtr = stackbuf;
220*16467b97STreehugger Robot        // Fill in the stack array, either until we've provided all items from the list
221*16467b97STreehugger Robot        // or until we've provided as many items as the stack based buffer will hold.
222*16467b97STreehugger Robot        while((state->state < self.count) && (cnt < len)) {
223*16467b97STreehugger Robot            // For this sample, we generate the contents on the fly.
224*16467b97STreehugger Robot            // A real implementation would likely just be copying objects from internal storage.
225*16467b97STreehugger Robot            stackbuf[cnt++] = ptrBuffer[state->state++];
226*16467b97STreehugger Robot        }
227*16467b97STreehugger Robot        // state->state = ((cnt < len)? cnt : len);
228*16467b97STreehugger Robot    }
229*16467b97STreehugger Robot    else
230*16467b97STreehugger Robot    {
231*16467b97STreehugger Robot        // We've already provided all our items, so we signal we are done by returning 0.
232*16467b97STreehugger Robot        cnt = 0;
233*16467b97STreehugger Robot    }
234*16467b97STreehugger Robot    return cnt;
235*16467b97STreehugger Robot}
236*16467b97STreehugger Robot
237*16467b97STreehugger Robot- (void) clear
238*16467b97STreehugger Robot{
239*16467b97STreehugger Robot    if ( count ) [self removeAllObjects];
240*16467b97STreehugger Robot}
241*16467b97STreehugger Robot
242*16467b97STreehugger Robot- (void) removeAllObjects
243*16467b97STreehugger Robot{
244*16467b97STreehugger Robot    if ( [self count] > 0 ) {
245*16467b97STreehugger Robot        // root = [ACBTree newNodeWithDictionary:self];
246*16467b97STreehugger Robot        NSArray *list = [self allKeys];
247*16467b97STreehugger Robot        for ( NSInteger i = [self count] - 1; i >= 0; i-- ) {
248*16467b97STreehugger Robot            [self removeObjectForKey:[list objectAtIndex:i]];
249*16467b97STreehugger Robot        }
250*16467b97STreehugger Robot        root.nodeid = 0;
251*16467b97STreehugger Robot        nxt_nodeid = 1;
252*16467b97STreehugger Robot    }
253*16467b97STreehugger Robot}
254*16467b97STreehugger Robot
255*16467b97STreehugger Robot- (NSInteger) nextNodeId
256*16467b97STreehugger Robot{
257*16467b97STreehugger Robot    return nxt_nodeid++;
258*16467b97STreehugger Robot}
259*16467b97STreehugger Robot
260*16467b97STreehugger Robot- (NSArray *) toKeyArray
261*16467b97STreehugger Robot{
262*16467b97STreehugger Robot    return nil;
263*16467b97STreehugger Robot}
264*16467b97STreehugger Robot
265*16467b97STreehugger Robot- (NSArray *) toValueArray
266*16467b97STreehugger Robot{
267*16467b97STreehugger Robot    return nil;
268*16467b97STreehugger Robot}
269*16467b97STreehugger Robot
270*16467b97STreehugger Robot@end
271