1//
2//  ANTLRReaderStream.m
3//  ANTLR
4//
5//  Created by Alan Condit on 2/21/11.
6//  Copyright 2011 Alan's MachineWorks. All rights reserved.
7//
8
9#import "ANTLRReaderStream.h"
10#import "ACNumber.h"
11
12@implementation ANTLRReaderStream
13
14@synthesize is;
15@synthesize size;
16@synthesize rbSize;
17
18static NSInteger READ_BUFFER_SIZE = 1024;
19static NSInteger INITIAL_BUFFER_SIZE = 1024;
20
21+ (NSInteger) READ_BUFFER_SIZE
22{
23    return READ_BUFFER_SIZE;
24}
25
26+ (NSInteger) INITIAL_BUFFER_SIZE
27{
28    return INITIAL_BUFFER_SIZE;
29}
30
31+ (id) newANTLRReaderStream
32{
33    return [[ANTLRReaderStream alloc] init];
34}
35
36+ (id) newANTLRReaderStream:(NSInputStream *)r
37{
38    return [[ANTLRReaderStream alloc] initWithReader:r size:INITIAL_BUFFER_SIZE readBufferSize:READ_BUFFER_SIZE];
39}
40
41+ (id) newANTLRReaderStream:(NSInputStream *)r size:(NSInteger)aSize
42{
43    return [[ANTLRReaderStream alloc] initWithReader:r size:aSize readBufferSize:READ_BUFFER_SIZE];
44}
45
46+ (id) newANTLRReaderStream:(NSInputStream *)r size:(NSInteger)aSize readBufferSize:(NSInteger)aReadChunkSize
47{
48//    load(r, aSize, aReadChunkSize);
49    return [[ANTLRReaderStream alloc] initWithReader:r size:aSize readBufferSize:aReadChunkSize];
50}
51
52- (id) init
53{
54	self = [super init];
55	if ( self != nil ) {
56        int p1 = n;  // init from ANTLRStringStream val
57        is = nil;
58        rbSize = READ_BUFFER_SIZE;
59        size = INITIAL_BUFFER_SIZE;
60    }
61    return self;
62}
63
64- (id) initWithReader:(NSInputStream *)r size:(NSInteger)aSize readBufferSize:(NSInteger)aReadChunkSize
65{
66	self = [super init];
67	if ( self != nil ) {
68        int p1 = n;  // init from ANTLRStringStream val
69        is = r;
70        rbSize = aSize;
71        size = aReadChunkSize;
72        [is open];
73//        [self setUpStreamForFile];
74        if ( [is hasBytesAvailable] ) {
75            [self load:aSize readBufferSize:aReadChunkSize];
76        }
77    }
78    return self;
79}
80
81- (void) load:(NSInteger)aSize readBufferSize:(NSInteger)aReadChunkSize
82{
83    NSMutableData *retData = nil;
84    uint8_t buf[1024];
85    if ( is==nil ) {
86        return;
87    }
88    if ( aSize<=0 ) {
89        aSize = INITIAL_BUFFER_SIZE;
90    }
91    if ( aReadChunkSize<=0 ) {
92        aReadChunkSize = READ_BUFFER_SIZE;
93    }
94#pragma mark fix these NSLog calls
95    @try {
96        int numRead=0;
97        numRead = [is read:buf maxLength:aReadChunkSize];
98        retData = [NSMutableData dataWithCapacity:numRead];
99        [retData appendBytes:(const void *)buf length:numRead];
100        NSLog( @"read %d chars; p was %d is now %d", n, p1, (p1+numRead) );
101        p1 += numRead;
102        n = p1;
103        data = [[NSString alloc] initWithData:retData encoding:NSASCIIStringEncoding];
104        NSLog( @"n=%d\n", n );
105    }
106    @finally {
107        [self close];
108    }
109}
110
111- (void)setUpStreamForFile
112{
113    // iStream is NSInputStream instance variable
114//    if ( is == nil )
115//        is = [[NSInputStream alloc] initWithFileAtPath:path];
116    [is setDelegate:self];
117    [is scheduleInRunLoop:[NSRunLoop currentRunLoop]
118                       forMode:NSDefaultRunLoopMode];
119    [is open];
120}
121
122- (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)eventCode
123{
124    NSMutableData *myData = nil;
125    ACNumber *bytesRead = [ACNumber numberWithInteger:0];
126    uint8_t buf[1024];
127    switch(eventCode) {
128        case NSStreamEventHasBytesAvailable:
129        {
130            if(!myData) {
131                myData = [[NSMutableData data] retain];
132            }
133            unsigned int len = 0;
134            len = [(NSInputStream *)stream read:buf maxLength:1024];
135            if(len) {
136                [myData appendBytes:(const void *)buf length:len];
137                // bytesRead is an instance variable of type ACNumber.
138                bytesRead = [ACNumber numberWithInteger:[bytesRead integerValue]+len];
139                data = [[NSString alloc] initWithData:myData encoding:NSASCIIStringEncoding];
140            } else {
141                NSLog(@"no buffer!");
142            }
143            break;
144        }
145        case NSStreamEventEndEncountered:
146        {
147            [stream close];
148            [stream removeFromRunLoop:[NSRunLoop currentRunLoop]
149                              forMode:NSDefaultRunLoopMode];
150            [stream release];
151            stream = nil; // stream is ivar, so reinit it
152            break;
153        }
154        // continued
155    }
156}
157
158- (void) close
159{
160    [is close];
161    is = nil;
162}
163
164@end
165