NSFileHandle -availableData breaks stdin stream at 4K chunks?
NSFileHandle -availableData breaks stdin stream at 4K chunks?
- Subject: NSFileHandle -availableData breaks stdin stream at 4K chunks?
- From: Jerry Krinock <email@hidden>
- Date: Wed, 02 Jul 2014 17:34:08 -0700
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 (email@hidden)
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:
This email sent to email@hidden