Author: mturk
Date: Thu Aug 18 11:30:09 2011
New Revision: 1159172

URL: http://svn.apache.org/viewvc?rev=1159172&view=rev
Log:
Add initial memory stream (bidirectional Byte/ByteBuffer streams)

Added:
    
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/MemoryStream.java
   (with props)
    commons/sandbox/runtime/trunk/src/main/native/shared/memstream.c   (with 
props)
    
commons/sandbox/runtime/trunk/src/main/test/org/apache/commons/runtime/TestMemoryStream.java
   (with props)
Modified:
    commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in
    commons/sandbox/runtime/trunk/src/main/native/Makefile.unx.in

Added: 
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/MemoryStream.java
URL: 
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/MemoryStream.java?rev=1159172&view=auto
==============================================================================
--- 
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/MemoryStream.java
 (added)
+++ 
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/MemoryStream.java
 Thu Aug 18 11:30:09 2011
@@ -0,0 +1,337 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package org.apache.commons.runtime.io;
+
+import java.io.IOException;
+import java.io.SyncFailedException;
+import java.nio.ByteBuffer;
+import org.apache.commons.runtime.InvalidArgumentException;
+import org.apache.commons.runtime.Pointer;
+import org.apache.commons.runtime.util.Utils;
+
+/**
+ * Bidirectional Memory Stream.
+ * <p>
+ * This class uses native heap memory for internal data buffer and its
+ * capacity is limited to {@code Integer.MAX_VALUE} bytes. Stream dynamically
+ * allocates and extends the memory and as needed.
+ * </p>
+ */
+public final class MemoryStream extends Stream
+    implements Streamable, Reader, Writer
+{
+
+    private long        sb;
+    private int         rdpos;
+
+    private static native long          alloc0(int size);
+    private static native void          free0(long sb);
+    private static native void          clear0(long sb);
+
+    private static native void          flush0(long sb);
+    private static native void          finish0(long sb);
+    private static native boolean       finished0(long sb);
+    private static native int           length0(long sb);
+
+    private static native int           read0(long sb, int pos);
+    
+    // Native write methods
+    private static native int           write0(long sb, int ch)
+        throws IOException;
+    private static native int           write1(long sb, byte[] buf, int off, 
int len)
+        throws IOException;
+    private static native int           write2(long sb, long ptr, int len)
+        throws IOException;
+    private static native int           write3(long sb, ByteBuffer buf, int 
off, int len)
+        throws IOException;
+    private static native long          write4(long sb, byte[][] buf, int off, 
int len)
+        throws IOException;
+    private static native long          write5(long sb, ByteBuffer[] buf, int 
off, int len)
+        throws IOException;
+
+    /**
+     * Creates a new memory stream instance with default buffer size.
+     */
+    public MemoryStream()
+    {
+        this(0);
+    }
+
+    /**
+     * Creates a new memory stream instance with given buffer size.
+     */
+    public MemoryStream(int size)
+    {
+        if (size < 32)
+            size = 32;
+        sb = alloc0(size);
+        if (sb == 0L)
+            throw new OutOfMemoryError();
+    }
+
+    /**
+     * Returns the number of bytes that are available before this stream will
+     * block.
+     *
+     * @return the number of bytes available before blocking.
+     * @throws IOException
+     *             if an error occurs in this stream.
+     */
+    public synchronized int available()
+        throws IOException
+    {
+        return length0(sb) - rdpos;
+    }
+
+    /**
+     * Closes the object and release any system resources it holds. If the
+     * object has already been closed, then invoking this method has no effect.
+     *
+     * @throws IOException
+     *              if any error occurs when closing the object.
+     */
+    public synchronized void close()
+        throws IOException
+    {
+        if (sb != 0L) {
+            free0(sb);
+            sb = 0L;
+        }
+    }
+    /**
+     * Flush the underlying stream metadata.
+     * <p>
+     * {@code flush} transfers  all modified metadata of the stream object
+     * referred to by {@code this} stream to the disk device
+     * (or other storage device)  where  that  object resides.
+     * The call blocks until the device reports that the transfer has
+     * completed.  It also flushes  metadata information associated with
+     * {@code this} Descriptor.
+     * </p>
+     *
+     * @throws SyncFailedException when the object cannot be flushed.
+     * @throws IOException if an I/O error occurs.
+     */
+    public void flush()
+        throws SyncFailedException, IOException
+    {
+        flush0(sb);
+    }
+
+    /**
+     * Sync the underlying stream by writing any buffered data.
+     * <p>
+     * {@code sync} transfers  all  modified in-core data of the stream object
+     * referred to by {@code this} stream to the disk device
+     * (or other storage device)  where  that  object resides.
+     * The call blocks until the device reports that the transfer has
+     * completed.  It also flushes  metadata information associated with
+     * {@code this} Descriptor.
+     * </p>
+     *
+     * @throws SyncFailedException when the object cannot be flushed.
+     * @throws IOException if an I/O error occurs.
+     */
+    public void sync()
+        throws SyncFailedException, IOException
+    {
+        flush0(sb);
+    }
+
+    @Override
+    public synchronized boolean closed()
+    {
+        return sb == 0L;
+    }
+
+    /**
+     * Test if {@code this} stream is valid.
+     *
+     * @return {@code true} if the stream represents a valid,
+     *         open file, socket, or other I/O object; {@code false} otherwse.
+     *
+     */
+    public synchronized boolean valid()
+    {
+        return sb != 0L;
+    }
+
+    /**
+     * Test wather or not every I/O operation on {@code this} stream will
+     * block until it completes.
+     *
+     * @return {@code true} if, and only if, this stream
+     *         is in blocking mode.
+     *
+     * @throws IOException if an I/O error occurs.
+     */
+    public boolean isBlocking()
+        throws IOException
+    {
+        return false;
+    }
+
+    /**
+     * Skips over {@code count} bytes in this stream. Less than {@code count}
+     * bytes are skipped if the end of the stream is reached or an exception is
+     * thrown during the operation. Nothing is done if {@code count} is
+     * negative.
+     *
+     * @param count
+     *          The number of bytes to skip.
+     *
+     * @return The number of bytes actually skipped.
+     *
+     * @throws ClosedDescriptorException
+     *          If this stream is closed.
+     * @throws OperationWouldBlockException
+     *          If the stream is in nonblocking mode and the operation
+     *          would block.
+     * @throws OperationNotSupportedException
+     *          If the stream is not seekable.
+     * @throws TimeoutException
+     *          If operation times out.
+     * @throws IOException
+     *          If some other I/O error occurs.
+     */
+    public synchronized long skip(long count)
+        throws IOException
+    {
+        if (count < 0L || count > Integer.MAX_VALUE)
+            throw new InvalidArgumentException();
+        long len = length0(sb);
+        if (count + rdpos >= len)
+            count = len - rdpos;
+        rdpos += (int)count;
+        return count;
+    }
+
+    @Override
+    public boolean canSeek()
+    {
+        return true;
+    }
+
+    @Override
+    public boolean canRead()
+    {
+        return true;
+    }
+
+    @Override
+    public boolean canWrite()
+    {
+        return true;
+    }
+
+    @Override
+    public synchronized boolean eof()
+        throws IOException
+    {
+        return rdpos >= length0(sb);
+    }
+
+    @Override
+    public synchronized int read()
+        throws IOException
+    {
+        int rv = read0(sb, rdpos);
+        if (rv != -1)
+            rdpos++;
+        return rv;
+    }
+
+    @Override
+    public synchronized int read(byte[] buffer, int offset, int count)
+        throws IndexOutOfBoundsException, IOException
+    {
+        return 0;
+    }
+
+    @Override
+    public synchronized int read(long address, int count)
+        throws NullPointerException, IndexOutOfBoundsException, IOException
+    {
+        return 0;
+    }
+
+    @Override
+    public synchronized int read(ByteBuffer buffer)
+        throws IndexOutOfBoundsException, IOException
+    {
+        return 0;
+    }
+
+    // === Writer methods
+
+    @Override
+    public int write(int b)
+        throws IOException
+    {
+        if (closed())
+            throw new ClosedDescriptorException();
+        return write0(sb, b);
+    }
+
+    @Override
+    public int write(byte[] buffer, int offset, int count)
+        throws IndexOutOfBoundsException, IOException
+    {
+        if (closed())
+            throw new ClosedDescriptorException();
+        return write1(sb, buffer, offset, count);
+    }
+
+    @Override
+    public int write(long address, int count)
+        throws IndexOutOfBoundsException, IOException
+    {
+        if (closed())
+            throw new ClosedDescriptorException();
+        return write2(sb, address, count);
+    }
+
+    @Override
+    public int write(ByteBuffer buffer)
+        throws IndexOutOfBoundsException, IOException
+    {
+        if (closed())
+            throw new ClosedDescriptorException();
+        return write3(sb, buffer, buffer.position(), buffer.remaining());
+    }
+
+    @Override
+    public long write(byte[][] array, int offset, int count)
+        throws IndexOutOfBoundsException, IOException
+    {
+        if (closed())
+            throw new ClosedDescriptorException();
+        return write4(sb, array, offset, count);
+    }
+
+    @Override
+    public long write(ByteBuffer[] array, int offset, int count)
+        throws IndexOutOfBoundsException, IOException
+    {
+        if (closed())
+            throw new ClosedDescriptorException();
+        return write5(sb, array, offset, count);
+    }
+
+}

Propchange: 
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/MemoryStream.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in
URL: 
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in?rev=1159172&r1=1159171&r2=1159172&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in (original)
+++ commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in Thu Aug 18 
11:30:09 2011
@@ -127,6 +127,7 @@ LIBSOURCES=\
        $(TOPDIR)\shared\error.c \
        $(TOPDIR)\shared\iofd.c \
        $(TOPDIR)\shared\memory.c \
+       $(TOPDIR)\shared\memstream.c \
        $(TOPDIR)\shared\native.c \
        $(TOPDIR)\shared\netaddr.c \
        $(TOPDIR)\shared\netserv.c \

Modified: commons/sandbox/runtime/trunk/src/main/native/Makefile.unx.in
URL: 
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/Makefile.unx.in?rev=1159172&r1=1159171&r2=1159172&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/Makefile.unx.in (original)
+++ commons/sandbox/runtime/trunk/src/main/native/Makefile.unx.in Thu Aug 18 
11:30:09 2011
@@ -122,6 +122,7 @@ LIBSOURCES=\
        $(TOPDIR)/shared/error.c \
        $(TOPDIR)/shared/iofd.c \
        $(TOPDIR)/shared/memory.c \
+       $(TOPDIR)/shared/memstream.c \
        $(TOPDIR)/shared/native.c \
        $(TOPDIR)/shared/netaddr.c \
        $(TOPDIR)/shared/netserv.c \

Added: commons/sandbox/runtime/trunk/src/main/native/shared/memstream.c
URL: 
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/shared/memstream.c?rev=1159172&view=auto
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/shared/memstream.c (added)
+++ commons/sandbox/runtime/trunk/src/main/native/shared/memstream.c Thu Aug 18 
11:30:09 2011
@@ -0,0 +1,267 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "acr/memory.h"
+#include "acr/pointer.h"
+#include "acr/clazz.h"
+#include "acr/sbuf.h"
+
+ACR_IO_EXPORT(jlong, MemoryStream, alloc0)(JNI_STDARGS, jint len)
+{
+    acr_sb_t *sb = AcrSbNew(0, len, ACR_SB_AUTOEXTEND);
+    if (sb == 0)
+        return 0;
+    else
+        return P2J(sb);
+}
+
+ACR_IO_EXPORT(void, MemoryStream, free0)(JNI_STDARGS, jlong sh)
+{
+    acr_sb_t *sb = J2P(sh, acr_sb_t *);
+    AcrSbFree(sb);
+}
+
+ACR_IO_EXPORT(void, MemoryStream, clear0)(JNI_STDARGS, jlong sh)
+{
+    acr_sb_t *sb = J2P(sh, acr_sb_t *);
+    AcrSbClear(sb);
+}
+
+ACR_IO_EXPORT(jlong, MemoryStream, detach0)(JNI_STDARGS, jlong sh)
+{
+    acr_sb_t *sb = J2P(sh, acr_sb_t *);
+    return P2J(AcrSbDetach(sb));
+}
+
+ACR_IO_EXPORT(jlong, MemoryStream, data0)(JNI_STDARGS, jlong sh)
+{
+    acr_sb_t *sb = J2P(sh, acr_sb_t *);
+    return P2J(AcrSbData(sb));
+}
+
+ACR_IO_EXPORT(jlong, MemoryStream, detach1)(JNI_STDARGS, jlong sh, jint len)
+{
+    char *m;
+    acr_sb_t *sb = J2P(sh, acr_sb_t *);
+    m = AcrSbDetach(sb);
+    AcrSbInit(sb, 0, len, 0);
+    sb->s_flags |= ACR_SB_DYNSTRUCT;
+    return P2J(m);
+}
+
+ACR_IO_EXPORT(jint, MemoryStream, length0)(JNI_STDARGS, jlong sh)
+{
+    acr_sb_t *sb = J2P(sh, acr_sb_t *);
+    return AcrSbLen(sb);
+}
+
+ACR_IO_EXPORT(jint, MemoryStream, capacity0)(JNI_STDARGS, jlong sh)
+{
+    acr_sb_t *sb = J2P(sh, acr_sb_t *);
+    return AcrSbCapacity(sb);
+}
+
+ACR_IO_EXPORT(jint, MemoryStream, setmax0)(JNI_STDARGS, jlong sh, jint len)
+{
+    acr_sb_t *sb = J2P(sh, acr_sb_t *);
+    return AcrSbSetMax(sb, len);
+}
+
+ACR_IO_EXPORT(jint, MemoryStream, setpos0)(JNI_STDARGS, jlong sh, jint pos)
+{
+    acr_sb_t *sb = J2P(sh, acr_sb_t *);
+    return AcrSbSetPos(sb, pos);
+}
+
+ACR_IO_EXPORT(void, MemoryStream, flush0)(JNI_STDARGS, jlong sh)
+{
+    acr_sb_t *sb = J2P(sh, acr_sb_t *);
+    AcrSbFlush(sb);
+}
+
+ACR_IO_EXPORT(void, MemoryStream, finish0)(JNI_STDARGS, jlong sh)
+{
+    acr_sb_t *sb = J2P(sh, acr_sb_t *);
+    AcrSbFinish(sb);
+}
+
+ACR_IO_EXPORT(jboolean, MemoryStream, finished0)(JNI_STDARGS, jlong sh)
+{
+    acr_sb_t *sb = J2P(sh, acr_sb_t *);
+    return AcrSbDone(sb) ? JNI_TRUE : JNI_FALSE;
+}
+
+ACR_IO_EXPORT(jboolean, MemoryStream, overflow0)(JNI_STDARGS, jlong sh)
+{
+    acr_sb_t *sb = J2P(sh, acr_sb_t *);
+    return AcrSbOverflowed(sb) ? JNI_TRUE : JNI_FALSE;
+}
+
+ACR_IO_EXPORT(jint, MemoryStream, read0)(JNI_STDARGS, jlong sh, jint pos)
+{
+    acr_sb_t *sb = J2P(sh, acr_sb_t *);
+
+    if (pos >= sb->s_len)
+        return -1;
+    return (unsigned char)sb->s_buf[pos];
+}
+
+ACR_IO_EXPORT(jint, MemoryStream, write0)(JNI_STDARGS, jlong sh, jint b)
+{
+    int rc;
+    int wr = 1;
+    acr_sb_t *sb = J2P(sh, acr_sb_t *);
+
+    rc = AcrSbPutc(sb, b);
+    if (rc != 0) {
+        wr = -1;
+        ACR_THROW_NET_ERROR(rc);
+    }
+    return wr;
+}
+
+ACR_IO_EXPORT(jint, MemoryStream, write1)(JNI_STDARGS, jlong sh,
+                                          jbyteArray buf,
+                                          jint off, jint len)
+{
+    int wr = len;
+    int rc = 0;
+    char     *bb = 0;
+    acr_sb_t *sb = J2P(sh, acr_sb_t *);
+
+    bb = JARRAY_CRITICAL(char, buf);
+    if (bb == 0)
+        rc = ACR_EINVAL;
+    else
+        rc = AcrSbCatb(sb, bb + off, len);
+    RELEASE_CRITICAL(buf, bb);
+    if (rc != 0) {
+        wr = -1;
+        ACR_THROW_NET_ERROR(rc);
+    }
+    return wr;
+}
+
+ACR_IO_EXPORT(jint, MemoryStream, write2)(JNI_STDARGS, jlong sh,
+                                          jlong bp, jint len)
+{
+    int wr = len;
+    int rc = 0;
+    char     *bb = J2P(bp, char *);
+    acr_sb_t *sb = J2P(sh, acr_sb_t *);
+
+    if (bp == 0)
+        rc = ACR_EINVAL;
+    else
+        rc = AcrSbCatb(sb, bb, len);
+    if (rc != 0) {
+        wr = -1;
+        ACR_THROW_NET_ERROR(rc);
+    }
+    return wr;
+}
+
+ACR_IO_EXPORT(jint, MemoryStream, write3)(JNI_STDARGS, jlong sh,
+                                          jobject buf,
+                                          jint off, jint len)
+{
+    int wr = len;
+    int rc = 0;
+    char     *bb = 0;
+    acr_sb_t *sb = J2P(sh, acr_sb_t *);
+
+    bb = (char *)(*env)->GetDirectBufferAddress(env, buf);
+    if (bb == 0)
+        rc = ACR_EINVAL;
+    else
+        rc = AcrSbCatb(sb, bb + off, len);
+    if (rc != 0) {
+        wr = -1;
+        ACR_THROW_NET_ERROR(rc);
+    }
+    return wr;
+}
+
+ACR_IO_EXPORT(jint, MemoryStream, write4)(JNI_STDARGS, jlong sh,
+                                          jobjectArray vec,
+                                          jint off,
+                                          jint len)
+{
+    int i;
+    int rc = 0;
+    int wr = 0;
+    int blen;
+    jbyte *bb;
+    acr_sb_t *sb = J2P(sh, acr_sb_t *);
+
+    for (i = 0; i < len; i++) {
+        jobject ba = (*env)->GetObjectArrayElement(env, vec, (jsize)(i + off));
+        if (ba == 0) {
+            /* XXX: What's the correct error ?
+             */
+            rc = ACR_EINVAL;
+            break;
+        }
+        blen = (int)(*env)->GetArrayLength(env, ba);
+        bb   = (*env)->GetByteArrayElements(env, ba, 0);
+        rc   = AcrSbCatb(sb, bb, blen);
+        (*env)->ReleaseByteArrayElements(env, ba, bb, JNI_ABORT);
+        (*env)->DeleteLocalRef(env, ba);
+        if (rc != 0)
+            break;
+        wr += blen;
+    }
+    if (rc != 0) {
+        wr = -1;
+        ACR_THROW_NET_ERROR(rc);
+    }
+    return wr;
+}
+
+ACR_IO_EXPORT(jint, MemoryStream, write5)(JNI_STDARGS, jlong sh,
+                                          jobjectArray vec,
+                                          jint off,
+                                          jint len)
+{
+    int i;
+    int rc = 0;
+    int wr = 0;
+    int blen;
+    jbyte *bb;
+    acr_sb_t *sb = J2P(sh, acr_sb_t *);
+
+    for (i = 0; i < len; i++) {
+        jobject ba = (*env)->GetObjectArrayElement(env, vec, (jsize)(i + off));
+        if (ba == 0) {
+            /* XXX: What's the correct error ?
+             */
+            rc = ACR_EINVAL;
+            break;
+        }
+        blen = (int)(*env)->GetDirectBufferCapacity(env, ba);
+        bb   = (*env)->GetDirectBufferAddress(env, ba);
+        rc   = AcrSbCatb(sb, bb, blen);
+        (*env)->DeleteLocalRef(env, ba);
+        if (rc != 0)
+            break;
+        wr += blen;
+    }
+    if (rc != 0) {
+        wr = -1;
+        ACR_THROW_NET_ERROR(rc);
+    }
+    return wr;
+}

Propchange: commons/sandbox/runtime/trunk/src/main/native/shared/memstream.c
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
commons/sandbox/runtime/trunk/src/main/test/org/apache/commons/runtime/TestMemoryStream.java
URL: 
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/test/org/apache/commons/runtime/TestMemoryStream.java?rev=1159172&view=auto
==============================================================================
--- 
commons/sandbox/runtime/trunk/src/main/test/org/apache/commons/runtime/TestMemoryStream.java
 (added)
+++ 
commons/sandbox/runtime/trunk/src/main/test/org/apache/commons/runtime/TestMemoryStream.java
 Thu Aug 18 11:30:09 2011
@@ -0,0 +1,40 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.runtime.io;
+
+import org.testng.annotations.*;
+import org.testng.Assert;
+import java.io.IOException;
+
+public class TestMemoryStream extends Assert
+{
+
+    @Test(groups = { "core" })
+    public void simpleWrite()
+        throws Throwable
+    {
+        MemoryStream s = new MemoryStream();
+        s.write(32);
+        assertEquals(s.read(), 32);
+        assertEquals(s.read(), -1);
+        assertTrue(s.eof());
+        s.write(33);
+        assertFalse(s.eof());
+        s.close();
+    }
+
+}

Propchange: 
commons/sandbox/runtime/trunk/src/main/test/org/apache/commons/runtime/TestMemoryStream.java
------------------------------------------------------------------------------
    svn:eol-style = native


Reply via email to