Ringobot log - RingoJS IRC channel: #ringojs on irc.freenode.net

2010-06-28:

[14:12] <gmosx> ..
[14:27] <tschaub> hey hannesw - thanks for the response on stream
[14:28] <hannesw> tschaub, sorry it took so long
[14:28] <tschaub> well, it was the weekend :)
[14:28] <hannesw> didn't look at my pc over the weekend due to a lost bet :)
[14:28] <tschaub> if you don't mind, can I ask for a bit more detail on using MemoryStream?
[14:28] <hannesw> sure
[14:29] <tschaub> so, I need an OutputStream for javax.imageio.ImageIO write
[14:29] <hannesw> ok, i see
[14:30] <tschaub> the way I was creating io.Stream, I could pass it to ImageIO write
[14:30] <tschaub> (I don't have a Java background, so this is uncertain terrain for me)
[14:30] <tschaub> I'd like to have my render method accept an io.Stream
[14:30] <hannesw> yes, io.Stream wraps a java stream
[14:31] <hannesw> unfortunately MemoryStream does not
[14:31] <tschaub> ok, is there any sense in me accepting MemoryStream and then creating an OutputStream that I'd copy to it?
[14:32] <hannesw> you mean create a ByteArrayOutputStream behind the scenes, and copy it to a io.MemoryStream?
[14:32] <tschaub> yeah
[14:33] <tschaub> with the goal of having application code not have to create the java.io.ByteArrayOutputStream
[14:35] <hannesw> then it would be more straightforward to just return a ByteArray or ByteString, i'd say
[14:35] <hannesw> or return a readable stream - that could then be used directly as JSGI response body
[14:35] <hannesw> everything in between doesn't really make sense IMO
[14:36] <tschaub> yeah, I think I agree
[14:36] <tschaub> so render would return a readable stream
[14:36] <hannesw> well the easy solution is to just return a ByteArray
[14:38] <tschaub> so, my current two uses for map.render are to write to a file or to a jsgi response
[14:38] <tschaub> at some point, I imagine I won't want to have the whole image in memory
[14:39] <tschaub> I'll see what I can do with ByteArray - thanks for the pointers
[14:40] <hannesw> np
[14:41] <tschaub> I do like the idea of returning a readable stream though - if I understand it right
[14:41] <hannesw> i'm trying to come up with a better way of connecting the streams, will let you know if i find something
[14:42] <tschaub> hannesw: if I wanted to try the stream route, do you have any hints on where to start?
[14:43] <tschaub> I can't picture the connection between the writable stream I pass to image.write and the readable stream I return
[14:43] <hannesw> well you could write directly to the servlet output stream if you're willing to bypass jsgi and use internal apis
[14:43] <tschaub> yeah, I suspected that I should be able to pass around the response stream
[14:44] <hannesw> but it's uncharted territory, so things may not work
[14:44] <hannesw> but it should be possible to do
[14:44] <hannesw> basically use request.env.servletResponse to access servlet API directly
[14:45] <tschaub> ok, I think I'll return a ByteArray for now - feels a bit cleaner
[14:45] <hannesw> yes, definitely easier
[14:46] <tschaub> thanks for all the work on Ringo btw - it is really slick!
[19:44] <tschaub> hannesw: one additional question on streams and jsgi - you mentioned that if I had a readable stream I could return it as jsgi response body
[19:44] <hannesw> yes
[19:44] <tschaub> does that mean I implement forEach on the stream?
[19:44] <hannesw> right. we may want to do that anyway
[19:44] <hannesw> i think it makes sense
[19:45] <tschaub> so forEach calls read(null)?
[19:45] <hannesw> the tricky thing (for your case) may be that you need an outputstr
[19:45] <hannesw> outputstream
[19:45] <hannesw> no, i would read into a buffer
[19:45] <tschaub> I've passed a piped output stream to image.render
[19:45] <hannesw> ok, cool :)
[19:46] <tschaub> constructed the output stream with a piped input stream
[19:46] <tschaub> and I've got an io.Stream wrapping the input stream
[19:46] <hannesw> i think it could be implemented pretty much like Stream.copy
[19:46] <tschaub> returning that from my map.render
[19:46] <hannesw> http://github.com/ringo/ringojs/blob/master/modules/io.js#L31
[19:46] <hannesw> only that you don't write to the other stream but invoke the callback
[19:47] <tschaub> that gets passed to forEach?
[19:48] <hannesw> right
[19:49] <hannesw> only trick is you have to set the length of the byte array before invoking the callback
[19:51] <hannesw> this should/might work:
[19:51] <hannesw> http://gist.github.com/456286
[19:51] <hannesw> but totally untested
[19:51] <hannesw> also, forEach takes a second thisObject argument, which isn't implemented here...
[19:54] <tschaub> ah cool - I tried the same but didn't get the length bit
[19:54] <tschaub> will try that
[19:56] <tschaub> hmm, pipe broken
[19:58] <tschaub> probably my thread business http://gist.github.com/456300
[19:59] <hannesw> tschaub: I'm trying to get it to work with a simple file input stream
[20:00] <hannesw> tschaub, yes, probably
[20:02] <tschaub> I liked the looks of this http://ostermiller.org/utils/CircularBuffer.html
[20:03] <tschaub> but there's likely an easier way to do what I'm trying
[20:06] <hannesw> tschaub it works for simple file serving: http://gist.github.com/456309
[20:07] <tschaub> cool
[20:07] <tschaub> so I can create a readable stream, but need to figure out how to pipe stuff in there from the output stream that ImageIO expects
[20:09] <tschaub> ah, can I just make a ByteArrayOutputStream
[20:09] <tschaub> and it will block until read
[20:09] <tschaub> perhaps?
[20:10] <tschaub> or block until space is available or whatever
[20:10] <daian> that what seemed to have been suggested earlier
[20:11] <daian> *that was what
[20:14] <hannesw> if you want a real streaming solution, you should trigger ImageIO.write only in the forEach function
[20:28] <tschaub> yeah, I was hoping my render method could be useful to both writing a file and returning a response