vicoapp / vico

Mac Programmers Text Editor
http://www.vicoapp.com/
657 stars 89 forks source link

Add writeData and readData to NS(In|Out)putStreams. #10

Closed Shadowfiend closed 11 years ago

Shadowfiend commented 12 years ago

writeData:(NSData ) lets us write NSData objects from Nu, while (NSData )readData lets us read NSData objects from Nu. This lets us use input and output streams from Nu, since otherwise they deal in raw byte arrays that we can't manipulate easily from there.

These are put in Nu categories; let me know if you'd like them moved elsewhere. I'm using them to write bindings to ensime for background Scala compile verification.

martinh commented 12 years ago

Did you look at ViBufferedStream and NSTask-streaming? It's an async stream that works from Nu too.

See the ack bundle for an example of how to use it.

Shadowfiend commented 12 years ago

I'll have a look at those over the next couple of days, thanks!

Shadowfiend commented 12 years ago

First up, worth noting is that communication with ensime is over a socket, not over standard IO. So the issue here is that ViBufferedStream requires input/output file descriptors; in and of itself this isn't a big deal: we could write an initializer similar to initWithTask: that takes an NSURL instead and does its own socket management, but it seems like that would be ugly. I looked around to see if there's any way to get a read/write file handle to a socket from a Cocoa object the way we get read/write file handles from NSPipe, but sadly it looks like you can only either get an NSFileHandle, which doesn't provide access to the underlying descriptors, or you have to use NSStream getStreamsToHost:port:inputStream:outputStream:, which only lets you interface using NSInputStream and NSOutputStream.

Given that there is already a Cocoa-wrapped solution that takes care of low-level socket management, I tend to think that it's better to add these two functions to the stream classes so they can be used properly from Nu than re-implement the socket handling code in ViBufferedStream. What do you think?

martinh commented 12 years ago

The problem with NSStream is that it's not completely asynchronous. ViBufferedStream does buffering on write and never blocks the application. To do it with NSStream you need a thread, and I'd like to avoid that complexity as long as possible.

The NSFileHandle object does have a fileDescriptor method that sounds like what's needed. If you initialize a ViBufferedStream with the same file descriptor for read and write, it will handle it properly as a bidirectional socket, so it's not tied to pipes.

martinh commented 12 years ago

Have a look at pull request #21. I don't think it's too ugly.

However, I'm not saying we can't have both.

Shadowfiend commented 12 years ago

Interesting. I think on a high level it could be useful to have these on NSData, but I like the ViBufferedStream approach for its consistency—one way to deal with buffered streams across plugins.

I'll pull that branch into my fork and try moving the current state of vico-ensime to it; I'll let you know if there are any issues on the other pull request.

Shadowfiend commented 12 years ago

Given that ViBufferedStream works fine with #21, I don't really mind whether this is merged or not. I'll leave it up to you and whether you consider it an important enough general utility to have the NSData interfaces on these streams :)