File: programming/cocoa/MacScare-Source.zip/MacScare-Source/GlkWindowStream.m


//
//  GlkWindowStream.m
//  CocoaGlk
//
//  Created by Andrew Hunter on Thu Jun 12 2003.
//  Copyright (c) 2003 Andrew Hunter. All rights reserved.
//
 
#import "GlkWindowStream.h"
#import "GlkWindowView.h"
 
@implementation GlkWindowStream
 
- (id) initWithGlkWindow: (GlkWindow*) win {
    self = [super init];
 
    if (self) {
        glkWin = win;
        style = 0;
 
        readcount = writecount = 0;
    }
 
    return self;
}
 
- (void) dealloc {
    [super dealloc];
}
 
- (void)   setPosition: (glsi32) pos
              withMode: (glui32) seekMode {
    // Do nothing
}
 
- (glui32) getPosition {
    return 0;
}
 
- (void) putChar: (unsigned char) ch {
    [self putBuffer: [NSData dataWithBytes: &ch
                                    length: 1]];
}
 
- (void) putBuffer: (NSData*) buf {
    if ([glkWin echoStream]) {
        [[glkWin echoStream] putBuffer: buf];
    }
    
    switch ([glkWin type]) {
        case wintype_TextBuffer:
        case wintype_TextGrid:
        {
            NSAttributedString* str;
 
            NSDictionary* attr = [glkWin attributesForStyle: style];
 
            str = [[NSAttributedString allocWithZone: [self zone]] initWithString: [NSString stringWithCString: [buf bytes] length: [buf length]]
                                                                       attributes: attr];
 
            // Send the text to the window
            [[glkWin textBuffer] appendAttributedString: str];
 
            [str release];
 
            writecount += [buf length];
        }
            break;
 
        case wintype_Pair:
            NSLog(@"Attempt to send data to a wintype_Pair window (assuming you meant to send to the key window)");
            [[[glkWin left] stream] putBuffer: buf];
            break;
 
        default:
            // Do nothing
            NSLog(@"Stream behaviour not defined for window of type %i (data %@)", [glkWin type], buf);
            break;
    }
}
 
- (void) setGlkStyle: (glui32) styl {
    style = styl;
}
 
- (glsi32) getChar {
    NSMutableString* pending = [glkWin pendingInput];
 
    // If there's nothing waiting, return -1
    if ([pending length] == 0) {
        return -1;
    }
 
    // Return the first waiting character (255 if out of the latin-1 character set)
    int chr = [pending characterAtIndex: 0];
    [pending deleteCharactersInRange: NSMakeRange(0,1)];
 
    if (chr > 255)
        chr = 255;
 
    readcount++;
 
    if ([glkWin echoStream]) {
        [[glkWin echoStream] putChar: chr];
    }
 
    return chr;
}
 
- (NSData*) getLineInBuffer: (int) length {
    NSMutableString* pending = [glkWin pendingInput];
    NSMutableData* buf = [NSMutableData dataWithBytes: [pending cString]
                                               length: [pending cStringLength]+1];
    
    char* data = [buf mutableBytes];
 
    int pos = 0;
 
    while (data[pos] != '\n' && data[pos] != 0) {
        pos++;
    }
 
    if (pos == 0) {
        buf = nil;
    } else {
        [buf setLength: (pos>length)?length:pos];
    }
 
    if (data[pos] != 0) {
        data[pos] = 0;
        pos++;
    }
    
    // Delete the relevent characters from the pending input
    [pending deleteCharactersInRange: NSMakeRange(0, pos)];
    
    readcount += pos;
 
    if ([glkWin echoStream]) {
        [[glkWin echoStream] putBuffer: buf];
        [[glkWin echoStream] putChar: '\n'];
    }
    
    // Done
    return buf;
}
 
- (NSData*) getBuffer: (int) length {
    NSLog(@"getBuffer not implemented for window streams\n");
    return 0;
}
 
@end

This code uses the PclZip Zip File reading code, which is subject to the GNU LGPL. It also uses the GeSHi syntax highlighter, subject to the GPL. Ask if you want this for your own web site, it's free.