[armedbear-devel] is there a good method to read/write java byte arrays?

Alessio Stalla alessiostalla at gmail.com
Wed Mar 17 19:43:42 UTC 2010


On Wed, Mar 17, 2010 at 8:27 PM, David Kirkman <dkirkman at ucsd.edu> wrote:
> On Wed, Mar 17, 2010 at 12:15 PM, Alessio Stalla
> <alessiostalla at gmail.com> wrote:
>> On Wed, Mar 17, 2010 at 8:10 PM, David Kirkman <dkirkman at ucsd.edu> wrote:
>>> On Wed, Mar 17, 2010 at 11:51 AM, Alessio Stalla
>>> <alessiostalla at gmail.com> wrote:
>>>> On Wed, Mar 17, 2010 at 7:36 PM, David Kirkman <dkirkman at ucsd.edu> wrote:
>>>>> On Wed, Mar 17, 2010 at 9:55 AM, Alessio Stalla <alessiostalla at gmail.com> wrote:
>>>>>> On Wed, Mar 17, 2010 at 5:32 PM, Alessio Stalla <alessiostalla at gmail.com> wrote:
>>>>>>> On Wed, Mar 17, 2010 at 5:22 PM, Mark Evenson <evenson at panix.com> wrote:
>>>>>>>> On 3/17/10 5:04 PM, Alessio Stalla wrote:
>>>>>>>> […]
>>>>>>>>
>>>>>>>>> I wrote sys::%make-byte-array-output-stream in order to make the
>>>>>>>>> runtime compiler capable of generating bytecode without using
>>>>>>>>> temporary files; it wasn't meant to be used by the ABCL user, and as
>>>>>>>>> such it's not very polished (for example, the type of a
>>>>>>>>> byte-array-output-stream is simply STREAM). In any case, it's defined
>>>>>>>>> in the ByteArrayOutputStream Java class, and as you correctly noted,
>>>>>>>>> it explicitly sets the element type to (unsigned-byte 8). As a quick
>>>>>>>>> and dirty solution, you could more or less copy-paste that class and
>>>>>>>>> replace "output" with "input" :) (as well as update Autoload.java to
>>>>>>>>> make ABCL know of the new primitives).
>>>>>>>>>
>>>>>>>>> We should probably polish it a bit and release it as an extension.
>>>>>>>>
>>>>>>>> Well, at least we should quickly  whip out the inverse version so David
>>>>>>>> doesn't have to rely on hacking Stream.java (although I'm not sure when
>>>>>>>> telling Stream that initAsBinaryStream() means a format of unsigned 8bit
>>>>>>>> bytes will fail).
>>>>>>>>
>>>>>>>> I think we can commit to the interface you've implemented in
>>>>>>>> ByteArrayOutputStream, as those are the basic necessary operations.
>>>>>>>>
>>>>>>>> Or maybe I am not seeing what potential problems there would be with
>>>>>>>> this as a short-term strategy, Alessio?
>>>>>>>
>>>>>>> No problem at all in the implementation per se; however, when we'll
>>>>>>> make it an "official" extension, the interface will change (if
>>>>>>> anything, symbols won't probably be in sys anymore and they won't be
>>>>>>> prefixed with %). Since this functionality will have approximately 1
>>>>>>> user in the near future :), I think it's ok to commit a quick fix for
>>>>>>> David. I'm working on it right now.
>>>>>>
>>>>>> Committed as r12557.
>>>>>>
>>>>>> A.
>>>>>>
>>>>>
>>>>> Thanks for implementing the inverse function so quickly!
>>>>>
>>>>> I ended up doing a bit more hacking last night.  When I tried to serialize
>>>>> structures that contain raw java objects, I realized that I need a way to
>>>>> convert lisp streams into java streams so that I can use the java
>>>>> serialization system.   I ended up writing:
>>>>>
>>>>>  public static OutputStream
>>>>>    outputStreamFromABCLStream(final LispObject stream) {
>>>>>
>>>>>    if (stream instanceof org.armedbear.lisp.Stream) {
>>>>>      return new OutputStream() {
>>>>>        public void write(int b) {
>>>>>          ((org.armedbear.lisp.Stream) stream)._writeByte(b);
>>>>>        }
>>>>>      };
>>>>>    } else {
>>>>>      throw new RuntimeException("argument not an abcl stream");
>>>>>    }
>>>>>  }
>>>>>
>>>>> and another version for InputStream.  Should something like these
>>>>> also go in as primitives?
>>>>
>>>> For binary input/output streams only, I think accessing the Java
>>>> streams wrapped by the Lisp stream is a better solution: no extra
>>>> objects are allocated and no API mismatch is possible. Unfortunately
>>>> those are private fields right now, but a couple of getters are not
>>>> hard to add ;)
>>>>
>>>> so, your outputStreamFromABCLStream would become:
>>>>
>>>> public static OutputStream
>>>>  outputStreamFromABCLStream(final LispObject stream) {
>>>>
>>>>  if (stream instanceof org.armedbear.lisp.Stream) {
>>>>    return ((org.armedbear.lisp.Stream) stream).getOutputStream();
>>>>  } else {
>>>>    throw new RuntimeException("argument not an abcl stream");
>>>>  }
>>>> }
>>>>
>>>> or, if you don't mind getting a ClassCastException instead, simply
>>>>
>>>> public static OutputStream
>>>>  outputStreamFromABCLStream(final LispObject stream) {
>>>>  return ((org.armedbear.lisp.Stream) stream).getOutputStream();
>>>> }
>>>>
>>>> what do you think?
>>>
>>> I think that's a much better solution!  I don't mind ClassCastExceptions, my
>>> code had that structure because it started as something copy/pasted out of
>>> Stream.java.  And I was using _readByte and _writeByte just because I didn't
>>> want to have to make changes to Stream.java and end up with my own version
>>> of abcl.
>>
>> Ok. I committed the modified Stream with accessors for the underlying
>> Java streams.
>>
>
> You guys are awesome.  But I can't build trunk now.  It seems that
> getInputStream
> conflicts with methods already defined in TwoWayStream and EchoStream.
>  How about
> getBinaryInputStream?

Whoops. Sorry. I did recompile abcl to check, but forgot to remove the
incremental build flag I usually use. I renamed all the methods to
getWrappedXXX().

A.




More information about the armedbear-devel mailing list