Home | History | Annotate | Download | only in Framework
      1 // [The "BSD licence"]
      2 // Copyright (c) 2006-2007 Kay Roepke 2010 Alan Condit
      3 // All rights reserved.
      4 //
      5 // Redistribution and use in source and binary forms, with or without
      6 // modification, are permitted provided that the following conditions
      7 // are met:
      8 // 1. Redistributions of source code must retain the above copyright
      9 //    notice, this list of conditions and the following disclaimer.
     10 // 2. Redistributions in binary form must reproduce the above copyright
     11 //    notice, this list of conditions and the following disclaimer in the
     12 //    documentation and/or other materials provided with the distribution.
     13 // 3. The name of the author may not be used to endorse or promote products
     14 //    derived from this software without specific prior written permission.
     15 //
     16 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     17 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     18 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     19 // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     20 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     21 // NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     22 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     23 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     24 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     25 // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26 
     27 #import "ANTLRRewriteRuleElementStream.h"
     28 
     29 @implementation ANTLRRewriteRuleElementStream
     30 
     31 @synthesize cursor;
     32 @synthesize dirty;
     33 @synthesize isSingleElement;
     34 @synthesize singleElement;
     35 @synthesize elements;
     36 @synthesize elementDescription;
     37 @synthesize treeAdaptor;
     38 
     39 + (ANTLRRewriteRuleElementStream *) newANTLRRewriteRuleElementStream:(id<ANTLRTreeAdaptor>)aTreeAdaptor
     40                                                          description:(NSString *)anElementDescription
     41 {
     42     return [[ANTLRRewriteRuleElementStream alloc] initWithTreeAdaptor:aTreeAdaptor
     43                                                           description:anElementDescription];
     44 }
     45 
     46 + (ANTLRRewriteRuleElementStream *) newANTLRRewriteRuleElementStream:(id<ANTLRTreeAdaptor>)aTreeAdaptor
     47                                                          description:(NSString *)anElementDescription
     48                                                              element:(id)anElement
     49 {
     50     return [[ANTLRRewriteRuleElementStream alloc] initWithTreeAdaptor:aTreeAdaptor
     51                                                           description:anElementDescription
     52                                                               element:anElement];
     53 }
     54 
     55 + (ANTLRRewriteRuleElementStream *) newANTLRRewriteRuleElementStream:(id<ANTLRTreeAdaptor>)aTreeAdaptor
     56                                                          description:(NSString *)anElementDescription
     57                                                             elements:(NSArray *)theElements;
     58 {
     59     return [[ANTLRRewriteRuleElementStream alloc] initWithTreeAdaptor:aTreeAdaptor
     60                                                           description:anElementDescription
     61                                                              elements:theElements];
     62 }
     63 
     64 - (id) initWithTreeAdaptor:(id<ANTLRTreeAdaptor>)aTreeAdaptor description:(NSString *)anElementDescription
     65 {
     66     if ((self = [super init]) != nil) {
     67         cursor = 0;
     68         dirty = NO;
     69         [self setDescription:anElementDescription];
     70         [self setTreeAdaptor:aTreeAdaptor];
     71         dirty = NO;
     72         isSingleElement = YES;
     73         singleElement = nil;
     74         elements = nil;
     75     }
     76     return self;
     77 }
     78 
     79 - (id) initWithTreeAdaptor:(id<ANTLRTreeAdaptor>)aTreeAdaptor description:(NSString *)anElementDescription element:(id)anElement
     80 {
     81     if ((self = [super init]) != nil) {
     82         cursor = 0;
     83         dirty = NO;
     84         [self setDescription:anElementDescription];
     85         [self setTreeAdaptor:aTreeAdaptor];
     86         dirty = NO;
     87         isSingleElement = YES;
     88         singleElement = nil;
     89         elements = nil;
     90         [self addElement:anElement];
     91     }
     92     return self;
     93 }
     94 
     95 - (id) initWithTreeAdaptor:(id<ANTLRTreeAdaptor>)aTreeAdaptor description:(NSString *)anElementDescription elements:(NSArray *)theElements
     96 {
     97     self = [super init];
     98     if (self) {
     99         cursor = 0;
    100         dirty = NO;
    101         [self setDescription:anElementDescription];
    102         [self setTreeAdaptor:aTreeAdaptor];
    103         dirty = NO;
    104         singleElement = nil;
    105         isSingleElement = NO;
    106         elements = [[AMutableArray arrayWithArray:theElements] retain];
    107     }
    108     return self;
    109 }
    110 
    111 - (void) dealloc
    112 {
    113 #ifdef DEBUG_DEALLOC
    114     NSLog( @"called dealloc in ANTLRRewriteRuleElementStream" );
    115 #endif
    116     if ( singleElement && isSingleElement ) [singleElement release];
    117     else if ( elements && !isSingleElement ) [elements release];
    118     [self setDescription:nil];
    119     [self setTreeAdaptor:nil];
    120     [super dealloc];
    121 }
    122 
    123 - (void)reset
    124 {
    125     cursor = 0;
    126     dirty = YES;
    127 }
    128 
    129 - (id<ANTLRTreeAdaptor>) getTreeAdaptor
    130 {
    131     return treeAdaptor;
    132 }
    133 
    134 - (void) setTreeAdaptor:(id<ANTLRTreeAdaptor>)aTreeAdaptor
    135 {
    136     if (treeAdaptor != aTreeAdaptor) {
    137         if ( treeAdaptor ) [treeAdaptor release];
    138         treeAdaptor = aTreeAdaptor;
    139         [treeAdaptor retain];
    140     }
    141 }
    142 
    143 - (void) addElement: (id)anElement
    144 {
    145     if (anElement == nil)
    146         return;
    147     if (elements != nil) {
    148         [elements addObject:anElement];
    149         return;
    150         }
    151     if (singleElement == nil) {
    152         singleElement = anElement;
    153         singleElement = [anElement retain];
    154         return;
    155     }
    156     isSingleElement = NO;
    157     elements = [[AMutableArray arrayWithCapacity:5] retain];
    158     [elements addObject:singleElement];
    159     singleElement = nil;  // balance previous retain in initializer/addElement
    160     [elements addObject:anElement];
    161 }
    162 
    163 - (void) setElement: (id)anElement
    164 {
    165     if (anElement == nil)
    166         return;
    167     if (elements != nil) {
    168         [elements addObject:anElement];
    169         return;
    170         }
    171     if (singleElement == nil) {
    172         singleElement = anElement;
    173         singleElement = [anElement retain];
    174         return;
    175     }
    176     isSingleElement = NO;
    177     elements = [[AMutableArray arrayWithCapacity:5] retain];
    178     [elements addObject:singleElement];
    179     singleElement = nil;  // balance previous retain in initializer/addElement
    180     [elements addObject:anElement];
    181 }
    182 
    183 - (id<ANTLRBaseTree>) nextTree
    184 {
    185     NSInteger n = [self size];
    186     if ( dirty && (cursor >= 0 && n == 1)) {
    187         // if out of elements and size is 1, dup
    188         id element = [self _next];
    189         return [self copyElement:element];
    190     }
    191     // test size above then fetch
    192     id element = [self _next];
    193     return element;
    194 }
    195 
    196 - (id) _next       // internal: TODO: redesign if necessary. maybe delegate
    197 {
    198     NSInteger n = [self size];
    199     if (n == 0) {
    200         @throw [NSException exceptionWithName:@"RewriteEmptyStreamException" reason:nil userInfo:nil];// TODO: fill in real exception
    201     }
    202     if ( cursor >= n ) {
    203         if ( n == 1 ) {
    204             return [self toTree:singleElement]; // will be dup'ed in -next
    205         }
    206         @throw [NSException exceptionWithName:@"RewriteCardinalityException" reason:nil userInfo:nil];// TODO: fill in real exception
    207     }
    208     if (singleElement != nil) {
    209         cursor++;
    210         return [self toTree:singleElement];
    211     }
    212     id el = [elements objectAtIndex:cursor];
    213     cursor++;
    214     return [self toTree:el];
    215 }
    216 
    217 - (BOOL) hasNext
    218 {
    219     return (singleElement != nil && cursor < 1) ||
    220             (elements != nil && cursor < [elements count]);
    221 }
    222 
    223 - (NSInteger) size
    224 {
    225     NSInteger n = 0;
    226     if (singleElement != nil)
    227         n = 1;
    228     if (elements != nil)
    229         return [elements count];
    230     return n;
    231 }
    232 
    233 - (id) copyElement:(id)element
    234 {
    235     [self doesNotRecognizeSelector:_cmd];   // subclass responsibility
    236     return nil;
    237 }
    238 
    239 - (id<ANTLRBaseTree>) toTree:(id)element
    240 {
    241     return element;
    242 }
    243 
    244 - (NSString *) getDescription
    245 {
    246     return elementDescription;
    247 }
    248 
    249 - (void) setDescription:(NSString *) description
    250 {
    251     if ( description != nil && description != elementDescription ) {
    252         if (elementDescription != nil) [elementDescription release];
    253         elementDescription = [NSString stringWithString:description];
    254         [elementDescription retain];
    255     }
    256 }
    257 
    258 @end
    259