You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2022/12/07 17:36:37 UTC

[sis] 03/03: Fix a `ClassCastException` and an `EOFException`. The latter was caused by wrong `ChannelData.channelOffset` value.

This is an automated email from the ASF dual-hosted git repository.

desruisseaux pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git

commit e2c3b3af00e1c4f28574719a6d634fd36f8df5ae
Author: Martin Desruisseaux <ma...@geomatys.com>
AuthorDate: Wed Dec 7 18:30:25 2022 +0100

    Fix a `ClassCastException` and an `EOFException`.
    The latter was caused by wrong `ChannelData.channelOffset` value.
---
 .../apache/sis/gui/metadata/StandardMetadataTree.java    |  2 +-
 .../java/org/apache/sis/metadata/MetadataStandard.java   | 10 +++++-----
 .../org/apache/sis/internal/storage/io/ChannelData.java  | 16 ++++++++++++++++
 .../apache/sis/internal/storage/io/ChannelDataInput.java | 12 ++++++++++++
 .../sis/internal/storage/io/ChannelImageInputStream.java |  6 +++---
 5 files changed, 37 insertions(+), 9 deletions(-)

diff --git a/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/StandardMetadataTree.java b/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/StandardMetadataTree.java
index ea4acb7a42..98963bd146 100644
--- a/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/StandardMetadataTree.java
+++ b/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/StandardMetadataTree.java
@@ -106,7 +106,7 @@ public class StandardMetadataTree extends MetadataTree {
             tree = ((AbstractMetadata) metadata).asTreeTable();
         } else {
             // `COMPACT` is the default policy of `AbstractMetadata.asTreeTable()`.
-            tree = MetadataStandard.ISO_19115.asTreeTable(metadata, null, ValueExistencePolicy.COMPACT);
+            tree = MetadataStandard.ISO_19115.asTreeTable(metadata, Metadata.class, ValueExistencePolicy.COMPACT);
         }
         setContent(tree);
     }
diff --git a/core/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataStandard.java b/core/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataStandard.java
index e931ee9325..88a2d59c1f 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataStandard.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataStandard.java
@@ -442,7 +442,7 @@ public class MetadataStandard implements Serializable {
         }
         /*
          * At this point, all cached values (including those in dependencies) have been checked.
-         * Performs the 'findInterface' computation only in last resort. Current implementation
+         * Performs the `findInterface(…)` computation only in last resort. Current implementation
          * does not store negative results in order to avoid filling the cache with unrelated classes.
          */
         final Class<?> standardType = findInterface(key);
@@ -489,7 +489,7 @@ public class MetadataStandard implements Serializable {
             }
         } else {
             /*
-             * Gets every interfaces from the supplied package in declaration order,
+             * Gets every interfaces from the supplied class in declaration order,
              * including the ones declared in the super-class.
              */
             final Set<Class<?>> interfaces = new LinkedHashSet<>();
@@ -517,7 +517,7 @@ public class MetadataStandard implements Serializable {
                 }
                 /*
                  * Found more than one interface; we don't know which one to pick.
-                 * Returns 'null' for now; the caller will thrown an exception.
+                 * Returns `null` for now; the caller will thrown an exception.
                  */
             } else if (IMPLEMENTATION_CAN_ALTER_API) {
                 /*
@@ -1049,7 +1049,7 @@ public class MetadataStandard implements Serializable {
             }
         } else {
             /*
-             * If we get here, a cycle has been found. Returns 'true' in order to allow the caller to continue
+             * If we get here, a cycle has been found. Returns `true` in order to allow the caller to continue
              * comparing other properties. It is okay because someone else is comparing those two same objects,
              * and that later comparison will do the actual check for property values.
              */
@@ -1074,7 +1074,7 @@ public class MetadataStandard implements Serializable {
             final Integer hash = HashCode.getOrCreate().walk(this, null, metadata, true);
             if (hash != null) return hash;
             /*
-             * 'hash' may be null if a cycle has been found. Example: A depends on B which depends on A,
+             * `hash` may be null if a cycle has been found. Example: A depends on B which depends on A,
              * in which case the null value is returned for the second occurrence of A (not the first one).
              * We cannot compute a hash code value here, but it should be okay since that metadata is part
              * of a bigger metadata object, and that enclosing object should have other properties for computing
diff --git a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/ChannelData.java b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/ChannelData.java
index aca1c0db2b..cc4150ea86 100644
--- a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/ChannelData.java
+++ b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/ChannelData.java
@@ -125,6 +125,22 @@ public abstract class ChannelData implements Markable {
         this.channelOffset = (channel instanceof SeekableByteChannel) ? ((SeekableByteChannel) channel).position() : 0;
     }
 
+    /**
+     * Creates a new instance from the given {@code ChannelData}.
+     * This constructor is invoked when we need to change the implementation class.
+     * The old {@code ChannelData} should not be used anymore after this constructor.
+     *
+     * @param  old  the existing instance from which to takes the channel and buffer.
+     */
+    ChannelData(final ChannelData old) {
+        filename      = old.filename;
+        buffer        = old.buffer;
+        channelOffset = old.channelOffset;
+        bufferOffset  = old.bufferOffset;
+        bitPosition   = old.bitPosition;
+        mark          = old.mark;
+    }
+
     /**
      * Creates a new instance for a buffer filled with the bytes to use.
      * This constructor uses an independent, read-only view of the given buffer.
diff --git a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/ChannelDataInput.java b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/ChannelDataInput.java
index 314f2decc3..99e54c8be8 100644
--- a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/ChannelDataInput.java
+++ b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/ChannelDataInput.java
@@ -106,6 +106,18 @@ public class ChannelDataInput extends ChannelData {
         }
     }
 
+    /**
+     * Creates a new input stream from the given {@code ChannelDataInput}.
+     * This constructor is invoked when we need to change the implementation class.
+     * The old input should not be used anymore after this constructor has been invoked.
+     *
+     * @param  input  the existing instance from which to takes the channel and buffer.
+     */
+    ChannelDataInput(final ChannelDataInput input) {
+        super(input);
+        channel = input.channel;
+    }
+
     /**
      * Creates a new instance for a buffer filled with the bytes to use.
      * This constructor uses an independent, read-only view of the given buffer.
diff --git a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/ChannelImageInputStream.java b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/ChannelImageInputStream.java
index 00ca785041..a2b26a6c3d 100644
--- a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/ChannelImageInputStream.java
+++ b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/ChannelImageInputStream.java
@@ -84,12 +84,12 @@ public class ChannelImageInputStream extends ChannelDataInput implements ImageIn
      * Creates a new input stream from the given {@code ChannelDataInput}.
      * This constructor is invoked when we need to change the implementation class
      * from {@code ChannelDataInput} to {@code ChannelImageInputStream}.
+     * The old input should not be used anymore after this constructor has been invoked.
      *
      * @param  input  the existing instance from which to takes the channel and buffer.
-     * @throws IOException if an error occurred while reading the channel.
      */
-    public ChannelImageInputStream(final ChannelDataInput input) throws IOException {
-        super(input.filename, input.channel, input.buffer, true);
+    public ChannelImageInputStream(final ChannelDataInput input) {
+        super(input);
     }
 
     /**