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

David Kirkman dkirkman at ucsd.edu
Wed Mar 17 19:27:50 UTC 2010


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?

-david k.




More information about the armedbear-devel mailing list