I’m writing a tool which receives data streamed into stdin by my Google Chrome 
extension (using their new Native Messaging API).  I think they use stdin for 
such interprocess communication in order to make it cross-platform.

Anyhow, I was surprised to find that the following code, which repeatedly 
invokes -waitForDataInBackgroundAndNotify and -availableData on +[NSFileHandle 
fileHandleWithStandardInput], delivers no more than 4096 bytes on each 
iteration.  It just stops at 4096, and the next -availableData starts with the 
next byte.

Although it was fun to write the code to buffer and stitch the message fields 
and length fields back together, I’d like to know what is causing these 4K 
breaks.  The documentation for -availableData says that it will return “the 
data currently available through the receiver, up to the the maximum size that 
can be represented by an NSData object.”  I think that must be more than 4K.

One possibility is that Chrome must be spitting it out in 4K bursts with little 
delays in between.  I tried to prove that by replacing the NSFileHandle stuff 
with repeated calls to getchar(), and changing my extension to output a string 
of 50,000 characters.  But when I graphed the receive times of these 
characters, it was a nice continuous, quite straight line.

Jerry

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        /* -[NSFileManager waitForDataInBackgroundAndNotify] doc say I need
         an "active run loop".  I don't know what they mean by "active". */
        NSDate* verySoon = [NSDate dateWithTimeIntervalSinceNow:0.01] ;
        [[NSRunLoop mainRunLoop] runUntilDate:verySoon] ;
        
        NSFileHandle* input = [NSFileHandle fileHandleWithStandardInput] ;
        [input waitForDataInBackgroundAndNotify] ;
        NSNotificationCenter* dc = [NSNotificationCenter defaultCenter] ;
        [dc addObserverForName:NSFileHandleDataAvailableNotification
                        object:input
                         queue:nil
                    usingBlock:^(NSNotification* note) {
                        NSFileHandle* input ;
                        input = [NSFileHandle fileHandleWithStandardInput] ;
                        NSData* data = [input availableData]  ;
                        if ([data length] > 0) {
                            [[Chromessenger sharedMessenger] 
gulpStdinData:data] ;
                            [input waitForDataInBackgroundAndNotify] ;
                        }
                        else {
                            // Must have received end-of-file (EOF)
                            exit(0) ;
                        }
                    }] ;
        [[NSRunLoop mainRunLoop] run] ;
    }
    
    // Will never execute
    return 0 ;
}


_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to