sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1735631 - in /sis/branches/JDK8/storage/sis-storage/src: main/java/org/apache/sis/internal/storage/ test/java/org/apache/sis/internal/storage/
Date Fri, 18 Mar 2016 16:08:18 GMT
Author: desruisseaux
Date: Fri Mar 18 16:08:11 2016
New Revision: 1735631

URL: http://svn.apache.org/viewvc?rev=1735631&view=rev
Log:
Allows HyperRectangleReader to use an existing array of primitive type, not necessarily data
provided by a ReadableByteChannel.

Added:
    sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/DataTransfer.java
  (with props)
    sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/MemoryDataTransfer.java
  (with props)
Modified:
    sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/ChannelData.java
    sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/ChannelDataInput.java
    sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/HyperRectangleReader.java
    sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/HyperRectangleReaderTest.java

Modified: sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/ChannelData.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/ChannelData.java?rev=1735631&r1=1735630&r2=1735631&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/ChannelData.java
[UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/ChannelData.java
[UTF-8] Fri Mar 18 16:08:11 2016
@@ -222,7 +222,7 @@ public abstract class ChannelData {
         final int n = (int) (position - bufferOffset);
         final int p = buffer.position() - n;
         final int r = buffer.limit() - n;
-        flushAndSetPosition(n); // Number of bytes to forget.
+        flushAndSetPosition(n);                             // Number of bytes to forget.
         buffer.compact().position(p).limit(r);
         /*
          * Discard trailing obsolete marks. Note that obsolete marks between valid marks
@@ -242,7 +242,7 @@ public abstract class ChannelData {
     }
 
     /**
-     * Writes (if applicable) the buffer content up to the given position, then set the buffer
position
+     * Writes (if applicable) the buffer content up to the given position, then sets the
buffer position
      * to the given value. The {@linkplain ByteBuffer#limit() buffer limit} is unchanged,
and the buffer
      * offset is incremented by the given value.
      */
@@ -327,6 +327,9 @@ public abstract class ChannelData {
     @Debug
     @Override
     public String toString() {
-        return getClass().getSimpleName() + "[“" + filename + "” at " + getStreamPosition()
+ ']';
+        final StringBuilder b = new StringBuilder().append(getClass().getSimpleName()).append("[“").append(filename).append('”');
+        // Even if the buffer should not be null, it is useful to keep the toString() method
robust.
+        if (buffer != null) b.append(" at ").append(getStreamPosition());
+        return b.append(']').toString();
     }
 }

Modified: sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/ChannelDataInput.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/ChannelDataInput.java?rev=1735631&r1=1735630&r2=1735631&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/ChannelDataInput.java
[UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/ChannelDataInput.java
[UTF-8] Fri Mar 18 16:08:11 2016
@@ -190,7 +190,7 @@ public class ChannelDataInput extends Ch
     /**
      * Returns the "end of file" error message, for {@link EOFException} creations.
      */
-    private String eof() {
+    final String eof() {
         return Errors.format(Errors.Keys.UnexpectedEndOfFile_1, filename);
     }
 
@@ -519,41 +519,20 @@ public class ChannelDataInput extends Ch
      * Helper class for the {@code readFully(…)} methods,
      * in order to avoid duplicating almost identical code many times.
      */
-    abstract class ArrayReader {
+    abstract class ArrayReader implements DataTransfer {
         /**
-         * Returns the size of the Java primitive type which is the element of the array.
-         * The size is expressed as the number of bits to shift.
-         */
-        abstract int dataSizeShift();
-
-        /**
-         * Returns the data as a {@code char[]}, {@code short[]}, {@code int[]}, {@code long[]},
-         * {@code float[]} or {@code double[]} array. This is either the array given in argument
-         * to the subclass constructor, or the array created by {@link #createArray(int)}.
-         */
-        abstract Object dataArray();
-
-        /**
-         * Creates a destination array of the given length.
-         */
-        abstract void createDataArray(int length);
-
-        /**
-         * Sets the destination to the given data array, which may be {@code null}.
-         */
-        abstract void setDest(Object array) throws ClassCastException;
-
-        /**
-         * Returns the view created by the last call to {@link #createView()}, or {@code
null} if none.
+         * For subclass constructors only.
          */
-        abstract Buffer view();
+        ArrayReader() {
+        }
 
         /**
-         * Creates a new buffer of the type required by the array to fill.
-         * This method is guaranteed to be invoked exactly once, after the
-         * {@link ChannelDataInput#buffer} contains enough data.
+         * Returns the enclosing data input.
          */
-        abstract Buffer createView();
+        @Override
+        public final ChannelDataInput input() {
+            return ChannelDataInput.this;
+        }
 
         /**
          * Transfers the data from the buffer created by {@link #createView()} to array
@@ -563,19 +542,6 @@ public class ChannelDataInput extends Ch
         abstract void transfer(int offset, int n);
 
         /**
-         * For subclass constructors only.
-         */
-        ArrayReader() {
-        }
-
-        /**
-         * Returns the enclosing data input.
-         */
-        final ChannelDataInput input() {
-            return ChannelDataInput.this;
-        }
-
-        /**
          * Skips the given amount of bytes in the buffer. It is caller responsibility to
ensure
          * that there is enough bytes remaining in the buffer.
          */
@@ -584,8 +550,16 @@ public class ChannelDataInput extends Ch
         }
 
         /**
-         * Reads {@code length} characters from the stream, and stores them into the array
-         * known to subclass, starting at index {@code offset}.
+         * Moves to the given position in the stream.
+         */
+        @Override
+        public final void seek(long n) throws IOException {
+            ChannelDataInput.this.seek(n);
+        }
+
+        /**
+         * Reads {@code length} values from the stream, and stores them into the array known
to subclass,
+         * starting at index {@code offset}.
          *
          * <p>If a non-null {@code Buffer} is given in argument to this method, then
it must be a view over
          * the full content of {@link ChannelDataInput#buffer} (i.e. the view element at
index 0 shall be
@@ -593,10 +567,11 @@ public class ChannelDataInput extends Ch
          *
          * @param  view     Existing buffer to use as a view over {@link ChannelDataInput#buffer},
or {@code null}.
          * @param  offset   The starting position within {@code dest} to write.
-         * @param  length   The number of characters to read.
+         * @param  length   The number of values to read.
          * @throws IOException if an error (including EOF) occurred while reading the stream.
          */
-        void readFully(Buffer view, int offset, int length) throws IOException {
+        @Override
+        public void readFully(Buffer view, int offset, int length) throws IOException {
             final int dataSizeShift = dataSizeShift();
             ensureBufferContains(Math.min(length << dataSizeShift, buffer.capacity()));
             if (view == null) {
@@ -632,17 +607,16 @@ public class ChannelDataInput extends Ch
      */
     @SuppressWarnings("ReturnOfCollectionOrArrayField")
     final class BytesReader extends ArrayReader {
-        /** The array where to store the values. */ private byte[] dest;
-        BytesReader(final byte[] dest) {this.dest = dest;}
-
-        @Override int    dataSizeShift()        {return 0;}
-        @Override Object dataArray()            {return dest;}
-        @Override Buffer view()                 {return buffer;}
-        @Override Buffer createView()           {return buffer;}
-        @Override void   createDataArray(int n) {dest = new byte[n];}
-        @Override void   transfer(int p, int n) {buffer.get(dest, p, n);}
-        @Override void   setDest(Object array)  {dest = (byte[]) array;};
-        @Override void   readFully(Buffer view, int offset, int length) throws IOException
{
+        /** The array where to store the values. */      private byte[] dest;
+        BytesReader(final byte[] dest)                  {this.dest = dest;}
+        @Override public int    dataSizeShift()         {return 0;}
+        @Override public Object dataArray()             {return dest;}
+        @Override public Buffer view()                  {return buffer;}
+        @Override public Buffer createView()            {return buffer;}
+        @Override public void   createDataArray(int n)  {dest = new byte[n];}
+        @Override        void   transfer(int p, int n)  {buffer.get(dest, p, n);}
+        @Override public void   setDest(Object array)   {dest = (byte[]) array;};
+        @Override public void readFully(Buffer view, int offset, int length) throws IOException
{
             ChannelDataInput.this.readFully(dest, offset, length);
         }
     };
@@ -652,17 +626,17 @@ public class ChannelDataInput extends Ch
      */
     @SuppressWarnings("ReturnOfCollectionOrArrayField")
     final class CharsReader extends ArrayReader {
-        /** A view over the enclosing byte buffer. */ private CharBuffer view;
-        /** The array where to store the values.   */ private char[] dest;
-        CharsReader(final char[] dest) {this.dest = dest;}
-
-        @Override int    dataSizeShift()        {return 1;}
-        @Override Object dataArray()            {return dest;}
-        @Override Buffer view()                 {return view;}
-        @Override Buffer createView()           {return view = buffer.asCharBuffer();}
-        @Override void   createDataArray(int n) {dest = new char[n];}
-        @Override void   transfer(int p, int n) {view.get(dest, p, n);}
-        @Override void   setDest(Object array)  {dest = (char[]) array;};
+        /** A view over the enclosing byte buffer. */    private CharBuffer view;
+        /** The array where to store the values.   */    private char[] dest;
+        CharsReader(final CharBuffer source)            {this.view = source;}
+        CharsReader(final char[] dest)                  {this.dest = dest;}
+        @Override public int    dataSizeShift()         {return 1;}
+        @Override public Object dataArray()             {return dest;}
+        @Override public Buffer view()                  {return view;}
+        @Override public Buffer createView()            {return view = buffer.asCharBuffer();}
+        @Override public void   createDataArray(int n)  {dest = new char[n];}
+        @Override        void   transfer(int p, int n)  {view.get(dest, p, n);}
+        @Override public void   setDest(Object array)   {dest = (char[]) array;};
     };
 
     /**
@@ -670,17 +644,17 @@ public class ChannelDataInput extends Ch
      */
     @SuppressWarnings("ReturnOfCollectionOrArrayField")
     final class ShortsReader extends ArrayReader {
-        /** A view over the enclosing byte buffer. */ private ShortBuffer view;
-        /** The array where to store the values.   */ private short[] dest;
-        ShortsReader(final short[] dest) {this.dest = dest;}
-
-        @Override int    dataSizeShift()        {return 1;}
-        @Override Object dataArray()            {return dest;}
-        @Override Buffer view()                 {return view;}
-        @Override Buffer createView()           {return view = buffer.asShortBuffer();}
-        @Override void   createDataArray(int n) {dest = new short[n];}
-        @Override void   transfer(int p, int n) {view.get(dest, p, n);}
-        @Override void   setDest(Object array)  {dest = (short[]) array;};
+        /** A view over the enclosing byte buffer. */    private ShortBuffer view;
+        /** The array where to store the values.   */    private short[] dest;
+        ShortsReader(final ShortBuffer source)          {this.view = source;}
+        ShortsReader(final short[] dest)                {this.dest = dest;}
+        @Override public int    dataSizeShift()         {return 1;}
+        @Override public Object dataArray()             {return dest;}
+        @Override public Buffer view()                  {return view;}
+        @Override public Buffer createView()            {return view = buffer.asShortBuffer();}
+        @Override public void   createDataArray(int n)  {dest = new short[n];}
+        @Override void          transfer(int p, int n)  {view.get(dest, p, n);}
+        @Override public void   setDest(Object array)   {dest = (short[]) array;};
     };
 
     /**
@@ -688,17 +662,17 @@ public class ChannelDataInput extends Ch
      */
     @SuppressWarnings("ReturnOfCollectionOrArrayField")
     final class IntsReader extends ArrayReader {
-        /** A view over the enclosing byte buffer. */ private IntBuffer view;
-        /** The array where to store the values.   */ private int[] dest;
-        IntsReader(final int[] dest) {this.dest = dest;}
-
-        @Override int    dataSizeShift()        {return 2;}
-        @Override Object dataArray()            {return dest;}
-        @Override Buffer view()                 {return view;}
-        @Override Buffer createView()           {return view = buffer.asIntBuffer();}
-        @Override void   createDataArray(int n) {dest = new int[n];}
-        @Override void   transfer(int p, int n) {view.get(dest, p, n);}
-        @Override void   setDest(Object array)  {dest = (int[]) array;};
+        /** A view over the enclosing byte buffer. */    private IntBuffer view;
+        /** The array where to store the values.   */    private int[] dest;
+        IntsReader(final IntBuffer source)              {this.view = source;}
+        IntsReader(final int[] dest)                    {this.dest = dest;}
+        @Override public int    dataSizeShift()         {return 2;}
+        @Override public Object dataArray()             {return dest;}
+        @Override public Buffer view()                  {return view;}
+        @Override public Buffer createView()            {return view = buffer.asIntBuffer();}
+        @Override public void   createDataArray(int n)  {dest = new int[n];}
+        @Override void          transfer(int p, int n)  {view.get(dest, p, n);}
+        @Override public void   setDest(Object array)   {dest = (int[]) array;};
     };
 
     /**
@@ -706,17 +680,17 @@ public class ChannelDataInput extends Ch
      */
     @SuppressWarnings("ReturnOfCollectionOrArrayField")
     final class LongsReader extends ArrayReader {
-        /** A view over the enclosing byte buffer. */ private LongBuffer view;
-        /** The array where to store the values.   */ private long[] dest;
-        LongsReader(final long[] dest) {this.dest = dest;}
-
-        @Override int    dataSizeShift()        {return 3;}
-        @Override Object dataArray()            {return dest;}
-        @Override Buffer view()                 {return view;}
-        @Override Buffer createView()           {return view = buffer.asLongBuffer();}
-        @Override void   createDataArray(int n) {dest = new long[n];}
-        @Override void   transfer(int p, int n) {view.get(dest, p, n);}
-        @Override void   setDest(Object array)  {dest = (long[]) array;};
+        /** A view over the enclosing byte buffer. */    private LongBuffer view;
+        /** The array where to store the values.   */    private long[] dest;
+        LongsReader(final LongBuffer source)            {this.view = source;}
+        LongsReader(final long[] dest)                  {this.dest = dest;}
+        @Override public int    dataSizeShift()         {return 3;}
+        @Override public Object dataArray()             {return dest;}
+        @Override public Buffer view()                  {return view;}
+        @Override public Buffer createView()            {return view = buffer.asLongBuffer();}
+        @Override public void   createDataArray(int n)  {dest = new long[n];}
+        @Override void          transfer(int p, int n)  {view.get(dest, p, n);}
+        @Override public void   setDest(Object array)   {dest = (long[]) array;};
     };
 
     /**
@@ -724,17 +698,17 @@ public class ChannelDataInput extends Ch
      */
     @SuppressWarnings("ReturnOfCollectionOrArrayField")
     final class FloatsReader extends ArrayReader {
-        /** A view over the enclosing byte buffer. */ private FloatBuffer view;
-        /** The array where to store the values.   */ private float[] dest;
-        FloatsReader(final float[] dest) {this.dest = dest;}
-
-        @Override int    dataSizeShift()        {return 2;}
-        @Override Object dataArray()            {return dest;}
-        @Override Buffer view()                 {return view;}
-        @Override Buffer createView()           {return view = buffer.asFloatBuffer();}
-        @Override void   createDataArray(int n) {dest = new float[n];}
-        @Override void   transfer(int p, int n) {view.get(dest, p, n);}
-        @Override void   setDest(Object array)  {dest = (float[]) array;};
+        /** A view over the enclosing byte buffer. */    private FloatBuffer view;
+        /** The array where to store the values.   */    private float[] dest;
+        FloatsReader(final FloatBuffer source)          {this.view = source;}
+        FloatsReader(final float[] dest)                {this.dest = dest;}
+        @Override public int    dataSizeShift()         {return 2;}
+        @Override public Object dataArray()             {return dest;}
+        @Override public Buffer view()                  {return view;}
+        @Override public Buffer createView()            {return view = buffer.asFloatBuffer();}
+        @Override public void   createDataArray(int n)  {dest = new float[n];}
+        @Override void          transfer(int p, int n)  {view.get(dest, p, n);}
+        @Override public void   setDest(Object array)   {dest = (float[]) array;};
     };
 
     /**
@@ -742,17 +716,17 @@ public class ChannelDataInput extends Ch
      */
     @SuppressWarnings("ReturnOfCollectionOrArrayField")
     final class DoublesReader extends ArrayReader {
-        /** A view over the enclosing byte buffer. */ private DoubleBuffer view;
-        /** The array where to store the values.   */ private double[] dest;
-        DoublesReader(final double[] dest) {this.dest = dest;}
-
-        @Override int    dataSizeShift()        {return 3;}
-        @Override Object dataArray()            {return dest;}
-        @Override Buffer view()                 {return view;}
-        @Override Buffer createView()           {return view = buffer.asDoubleBuffer();}
-        @Override void   createDataArray(int n) {dest = new double[n];}
-        @Override void   transfer(int p, int n) {view.get(dest, p, n);}
-        @Override void   setDest(Object array)  {dest = (double[]) array;};
+        /** A view over the enclosing byte buffer. */    private DoubleBuffer view;
+        /** The array where to store the values.   */    private double[] dest;
+        DoublesReader(final DoubleBuffer source)        {this.view = source;}
+        DoublesReader(final double[] dest)              {this.dest = dest;}
+        @Override public int    dataSizeShift()         {return 3;}
+        @Override public Object dataArray()             {return dest;}
+        @Override public Buffer view()                  {return view;}
+        @Override public Buffer createView()            {return view = buffer.asDoubleBuffer();}
+        @Override public void   createDataArray(int n)  {dest = new double[n];}
+        @Override void          transfer(int p, int n)  {view.get(dest, p, n);}
+        @Override public void   setDest(Object array)   {dest = (double[]) array;};
     };
 
     /**

Added: sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/DataTransfer.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/DataTransfer.java?rev=1735631&view=auto
==============================================================================
--- sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/DataTransfer.java
(added)
+++ sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/DataTransfer.java
[UTF-8] Fri Mar 18 16:08:11 2016
@@ -0,0 +1,95 @@
+/*
+ * 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.sis.internal.storage;
+
+import java.io.IOException;
+import java.nio.Buffer;
+
+
+/**
+ * Transfers data from a buffer to an array specified at construction time.
+ * The kind of buffer and the primitive type in the array depend on the implementation.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.7
+ * @version 0.7
+ * @module
+ */
+interface DataTransfer {
+    /**
+     * Returns the enclosing data input.
+     */
+    ChannelDataInput input();
+
+    /**
+     * Returns the size of the Java primitive type which is the element of the array.
+     * The size is expressed as the number of bits to shift.
+     */
+    int dataSizeShift();
+
+    /**
+     * Returns the data as a {@code char[]}, {@code short[]}, {@code int[]}, {@code long[]},
+     * {@code float[]} or {@code double[]} array. This is either the array given in argument
+     * to the subclass constructor, or the array created by {@link #createArray(int)}.
+     */
+    Object dataArray();
+
+    /**
+     * Creates a destination array of the given length.
+     */
+    void createDataArray(int length);
+
+    /**
+     * Sets the destination to the given data array, which may be {@code null}.
+     */
+    void setDest(Object array) throws ClassCastException;
+
+    /**
+     * Returns the view created by the last call to {@link #createView()}, or {@code null}
if none.
+     */
+    Buffer view();
+
+    /**
+     * Creates a new buffer of the type required by the array to fill.
+     * This method is guaranteed to be invoked exactly once, after the
+     * {@link ChannelDataInput#buffer} contains enough data.
+     */
+    Buffer createView();
+
+    /**
+     * Moves to the given position in the stream.
+     *
+     * @param  position The position where to move.
+     * @throws IOException if the stream can not be moved to the given position.
+     */
+    void seek(long position) throws IOException;
+
+    /**
+     * Reads {@code length} values from the stream and stores them into the array known to
subclass,
+     * starting at index {@code offset}.
+     *
+     * <p>If a non-null {@code Buffer} is given in argument to this method, then it
must be a view over
+     * the full content of {@link ChannelDataInput#buffer} (i.e. the view element at index
0 shall be
+     * defined by the buffer elements starting at index 0).</p>
+     *
+     * @param  view     Existing buffer to use as a view over {@link ChannelDataInput#buffer},
or {@code null}.
+     * @param  offset   The starting position within {@code dest} to write.
+     * @param  length   The number of values to read.
+     * @throws IOException if an error (including EOF) occurred while reading the stream.
+     */
+    void readFully(Buffer view, int offset, int length) throws IOException;
+}

Propchange: sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/DataTransfer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/DataTransfer.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8

Modified: sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/HyperRectangleReader.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/HyperRectangleReader.java?rev=1735631&r1=1735630&r2=1735631&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/HyperRectangleReader.java
[UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/HyperRectangleReader.java
[UTF-8] Fri Mar 18 16:08:11 2016
@@ -39,7 +39,7 @@ public final class HyperRectangleReader
     /**
      * The channel from which to read the values, together with a buffer for transferring
data.
      */
-    private final ChannelDataInput.ArrayReader reader;
+    private final DataTransfer reader;
 
     /**
      * The {@link #input} position of the first sample (ignoring sub-area and sub-sampling).
@@ -58,13 +58,13 @@ public final class HyperRectangleReader
             throws DataStoreException
     {
         switch (dataType) {
-            case Numbers.BYTE:      reader = input.new BytesReader  (null); break;
-            case Numbers.CHARACTER: reader = input.new CharsReader  (null); break;
-            case Numbers.SHORT:     reader = input.new ShortsReader (null); break;
-            case Numbers.INTEGER:   reader = input.new IntsReader   (null); break;
-            case Numbers.LONG:      reader = input.new LongsReader  (null); break;
-            case Numbers.FLOAT:     reader = input.new FloatsReader (null); break;
-            case Numbers.DOUBLE:    reader = input.new DoublesReader(null); break;
+            case Numbers.BYTE:      reader = input.new BytesReader  (           null); break;
+            case Numbers.CHARACTER: reader = input.new CharsReader  ((char[])   null); break;
+            case Numbers.SHORT:     reader = input.new ShortsReader ((short[])  null); break;
+            case Numbers.INTEGER:   reader = input.new IntsReader   ((int[])    null); break;
+            case Numbers.LONG:      reader = input.new LongsReader  ((long[])   null); break;
+            case Numbers.FLOAT:     reader = input.new FloatsReader ((float[])  null); break;
+            case Numbers.DOUBLE:    reader = input.new DoublesReader((double[]) null); break;
             default: throw new DataStoreException(Errors.format(Errors.Keys.UnknownType_1,
dataType));
         }
         this.origin = origin;
@@ -80,6 +80,19 @@ public final class HyperRectangleReader
     }
 
     /**
+     * Creates a new reader for the data in an existing buffer.
+     * The data will be read from the current buffer position to the buffer limit.
+     *
+     * @param name   The data source name, for information purpose only.
+     * @param data A buffer containing the data to read.
+     * @throws IOException should never happen.
+     */
+    public HyperRectangleReader(final String name, final Buffer data) throws IOException
{
+        reader = new MemoryDataTransfer(name, data).reader();
+        origin = 0;
+    }
+
+    /**
      * Returns the data input specified at construction time.
      *
      * @return The input channel together with the buffer.
@@ -109,10 +122,9 @@ public final class HyperRectangleReader
         }
         try {
             reader.createDataArray(region.targetLength(region.getDimension()));
-            final ChannelDataInput input = reader.input();
             final Buffer view = reader.view();
 loop:       do {
-                input.seek(streamPosition);
+                reader.seek(streamPosition);
                 assert reader.view() == view;
                 reader.readFully(view, arrayPosition, contiguousDataLength);
                 for (int i=0; i<cursor.length; i++) {

Added: sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/MemoryDataTransfer.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/MemoryDataTransfer.java?rev=1735631&view=auto
==============================================================================
--- sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/MemoryDataTransfer.java
(added)
+++ sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/MemoryDataTransfer.java
[UTF-8] Fri Mar 18 16:08:11 2016
@@ -0,0 +1,144 @@
+/*
+ * 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.sis.internal.storage;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.nio.Buffer;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.DoubleBuffer;
+import java.nio.FloatBuffer;
+import java.nio.IntBuffer;
+import java.nio.LongBuffer;
+import java.nio.ShortBuffer;
+import java.nio.channels.ReadableByteChannel;
+import org.apache.sis.util.resources.Errors;
+import org.apache.sis.util.Classes;
+
+
+/**
+ * A {@code DataTransfer} with all data in the given buffer, without channel.
+ *
+ * <div class="note"><b>Implementation note:</b>
+ * This class implements also an empty {@link ReadableByteChannel} as safety. When using
{@link ChannelDataInput}
+ * without channel, only an existing {@code Buffer} pre-filled with the data should be used.
If we have a bug in
+ * our reading process, the empty channel will cause an {@link java.io.EOFException} to be
thrown instead of a
+ * {@link NullPointerException}.</div>
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.7
+ * @version 0.7
+ * @module
+ */
+final class MemoryDataTransfer implements DataTransfer, ReadableByteChannel {
+    /**
+     * The actual {@code DataTransfer} implementation.
+     */
+    private final ChannelDataInput.ArrayReader reader;
+
+    /**
+     * Creates a in-memory data input for the given buffer.
+     */
+    MemoryDataTransfer(final String filename, final Buffer data) throws IOException {
+        final ChannelDataInput input = new ChannelDataInput(filename, this,
+                (data instanceof   ByteBuffer) ? (ByteBuffer) data : null, true);
+             if (data instanceof   ByteBuffer) reader = input.new BytesReader  (        
      null);
+        else if (data instanceof  ShortBuffer) reader = input.new ShortsReader ( (ShortBuffer)
data);
+        else if (data instanceof    IntBuffer) reader = input.new IntsReader   (   (IntBuffer)
data);
+        else if (data instanceof   LongBuffer) reader = input.new LongsReader  (  (LongBuffer)
data);
+        else if (data instanceof  FloatBuffer) reader = input.new FloatsReader ( (FloatBuffer)
data);
+        else if (data instanceof DoubleBuffer) reader = input.new DoublesReader((DoubleBuffer)
data);
+        else if (data instanceof   CharBuffer) reader = input.new CharsReader  (  (CharBuffer)
data);
+        else throw new IllegalArgumentException(Errors.format(Errors.Keys.UnknownType_1,
Classes.getClass(data)));
+    }
+
+    /**
+     * Returns the most efficient {@code DataTransfer} instance to use.
+     */
+    DataTransfer reader() {
+        return (view() instanceof ByteBuffer) ? reader : this;
+    }
+
+    /**
+     * Moves to the given byte position in the buffer.
+     */
+    @Override
+    public void seek(long position) throws IOException {
+        assert input().bufferOffset == 0;
+        if (position < 0) {
+            throw new IOException(Errors.format(Errors.Keys.NegativeArgument_2, "position",
position));
+        }
+        final int dataSizeShift = dataSizeShift();
+        if ((position & ((1 << dataSizeShift) - 1)) != 0) {
+            throw new IOException(Errors.format(Errors.Keys.IllegalArgumentValue_2, "position",
position));
+        }
+        position >>>= dataSizeShift;
+        final Buffer data = view();
+        if (position > data.limit()) {
+            throw new EOFException(input().eof());
+        }
+        data.position((int) position);
+    }
+
+    /**
+     * Delegates to the actual implementation.
+     */
+    @Override public ChannelDataInput input()                     {return reader.input();}
+    @Override public int              dataSizeShift()             {return reader.dataSizeShift();}
+    @Override public Object           dataArray()                 {return reader.dataArray();}
+    @Override public Buffer           view()                      {return reader.view();}
+    @Override public Buffer           createView()                {return reader.createView();}
+    @Override public void             createDataArray(int length) {reader.createDataArray(length);}
+    @Override public void             setDest(Object array)       {reader.setDest(array);}
+
+    /**
+     * Reads {@code length} values from the buffer and stores them into the array known to
subclass,
+     * starting at index {@code offset}.
+     *
+     * @param  view     Ignored.
+     * @param  offset   The starting position within {@code dest} to write.
+     * @param  length   The number of values to read.
+     */
+    @Override
+    public void readFully(final Buffer view, final int offset, final int length) {
+        reader.transfer(offset, length);
+    }
+
+    /**
+     * Returns -1 since an empty channel has reached the end-of-stream.
+     */
+    @Override
+    public int read(final ByteBuffer dst) {
+        return -1;
+    }
+
+    /**
+     * The channel is always open.
+     */
+    @Override
+    public boolean isOpen() {
+        return true;
+    }
+
+    /**
+     * Does nothing - keep the channel open.
+     */
+    @Override
+    public void close() throws IOException {
+    }
+}

Propchange: sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/MemoryDataTransfer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/MemoryDataTransfer.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8

Modified: sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/HyperRectangleReaderTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/HyperRectangleReaderTest.java?rev=1735631&r1=1735630&r2=1735631&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/HyperRectangleReaderTest.java
[UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/HyperRectangleReaderTest.java
[UTF-8] Fri Mar 18 16:08:11 2016
@@ -22,6 +22,8 @@ import java.nio.ByteOrder;
 import java.nio.ByteBuffer;
 import java.nio.ShortBuffer;
 import java.io.IOException;
+import java.nio.channels.ReadableByteChannel;
+import java.nio.channels.SeekableByteChannel;
 import org.apache.sis.util.Numbers;
 import org.apache.sis.storage.DataStoreException;
 import org.apache.sis.test.DependsOnMethod;
@@ -83,8 +85,10 @@ public final strictfp class HyperRectang
      * Sample values are index values encoded in base 10. For example the value at index
(4,1,2,3) will be 4123.
      *
      * @param random The random number generator to use for initializing the test.
+     * @param useChannel {@code true} for fetching the data from channel to a small buffer,
+     *        or {@code false} if the data are expected to be fully contained in the buffer.
      */
-    private void initialize(final Random random) throws IOException, DataStoreException {
+    private void initialize(final Random random, final boolean useChannel) throws IOException,
DataStoreException {
         /*
          * Compute a random hyper-rectangle size, sub-region and sub-sampling. Each dimension
will have a
          * size between 1 to 10, so we will be able to use decimal digits from 0 to 9 in
the sample values.
@@ -118,7 +122,7 @@ public final strictfp class HyperRectang
          * Fill the array with short values using the encoding describes in javadoc.
          * Then wrap the array in a pseudo-channel so we can create the reader to test.
          */
-        ShortBuffer view = ByteBuffer.wrap(array, origin, length*Short.BYTES).order(ByteOrder.nativeOrder()).asShortBuffer();
+        final ShortBuffer view = ByteBuffer.wrap(array, origin, length*Short.BYTES).order(ByteOrder.nativeOrder()).asShortBuffer();
         for (int i3=0; i3<size[3]; i3++) {
             for (int i2=0; i2<size[2]; i2++) {
                 for (int i1=0; i1<size[1]; i1++) {
@@ -129,10 +133,15 @@ public final strictfp class HyperRectang
             }
         }
         assertEquals(length, view.position());
-        final ByteArrayChannel channel = new ByteArrayChannel(array, true);
-        final ByteBuffer       buffer  = ByteBuffer.allocate(random.nextInt(20) + 20).order(ByteOrder.nativeOrder());
-        final ChannelDataInput input   = new ChannelDataInput("HyperRectangle", channel,
buffer, false);
-        reader = new HyperRectangleReader(Numbers.SHORT, input, origin);
+        if (useChannel) {
+            final ByteArrayChannel channel = new ByteArrayChannel(array, true);
+            final ByteBuffer       buffer  = ByteBuffer.allocate(random.nextInt(20) + 20).order(ByteOrder.nativeOrder());
+            final ChannelDataInput input   = new ChannelDataInput("HyperRectangle in channel",
channel, buffer, false);
+            reader = new HyperRectangleReader(Numbers.SHORT, input, origin);
+        } else {
+            view.clear();
+            reader = new HyperRectangleReader("HyperRectangle in buffer", view);
+        }
     }
 
     /**
@@ -159,6 +168,21 @@ public final strictfp class HyperRectang
     }
 
     /**
+     * Asserts that the reader used a channel and has read at least some bytes.
+     *
+     * @param expected {@code true} if the reader should have used a channel,
+     *        or {@code false} if it should have used in-memory data instead.
+     */
+    private void assertUsedChannel(final boolean expected) throws IOException {
+        final ChannelDataInput input = reader.input();
+        final ReadableByteChannel channel = input.channel;
+        assertEquals("(channel instanceof InMemoryInput)", !expected, channel instanceof
MemoryDataTransfer);
+        if (expected) {
+            assertTrue(((SeekableByteChannel) channel).position() > input.channelOffset);
+        }
+    }
+
+    /**
      * Tests reading a random part of the hyper-cube without sub-sampling.
      *
      * @throws IOException should never happen.
@@ -166,9 +190,10 @@ public final strictfp class HyperRectang
      */
     @Test
     public void testSubRegion() throws IOException, DataStoreException {
-        initialize(TestUtilities.createRandomNumberGenerator());
+        initialize(TestUtilities.createRandomNumberGenerator(), true);
         Arrays.fill(subsampling, 0, subsampling.length, 1);
         verifyRegionRead();
+        assertUsedChannel(true);
     }
 
     /**
@@ -179,10 +204,11 @@ public final strictfp class HyperRectang
      */
     @Test
     public void testSubSampling() throws IOException, DataStoreException {
-        initialize(TestUtilities.createRandomNumberGenerator());
+        initialize(TestUtilities.createRandomNumberGenerator(), true);
         System.arraycopy(size, 0, upper, 0, size.length);
         Arrays.fill(lower, 0, lower.length, 0);
         verifyRegionRead();
+        assertUsedChannel(true);
     }
 
     /**
@@ -194,7 +220,22 @@ public final strictfp class HyperRectang
     @Test
     @DependsOnMethod({"testSubRegion", "testSubSampling"})
     public void testRandom() throws IOException, DataStoreException {
-        initialize(TestUtilities.createRandomNumberGenerator());
+        initialize(TestUtilities.createRandomNumberGenerator(), true);
+        verifyRegionRead();
+        assertUsedChannel(true);
+    }
+
+    /**
+     * Tests reading data in an existing buffer, without channel.
+     *
+     * @throws IOException should never happen.
+     * @throws DataStoreException should never happen.
+     */
+    @Test
+    @DependsOnMethod("testRandom")
+    public void testReadFromBuffer() throws IOException, DataStoreException {
+        initialize(TestUtilities.createRandomNumberGenerator(4), false);
         verifyRegionRead();
+        assertUsedChannel(false);
     }
 }




Mime
View raw message