Przeglądaj źródła

add range-check assertions to the IndexBuffer.put() methods (#1427)

Stephen Gold 4 lat temu
rodzic
commit
92a0283306

+ 30 - 16
jme3-core/src/main/java/com/jme3/scene/mesh/IndexBuffer.java

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009-2019 jMonkeyEngine
+ * Copyright (c) 2009-2020 jMonkeyEngine
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -59,24 +59,38 @@ public abstract class IndexBuffer {
             throw new UnsupportedOperationException("Index buffer type unsupported: "+ buf.getClass());
         }
     }
-    
+
     /**
-     * Creates an index buffer that can contain the given amount of vertices. 
-     * <br/>
-     * Returns either {@link IndexByteBuffer}, {@link IndexShortBuffer} or 
+     * Create an IndexBuffer with the specified capacity.
+     *
+     * @param vertexCount the number of vertices that will be indexed into
+     * (determines number of bits per element)
+     * @param indexCount the number of indices the IndexBuffer must hold
+     * (determines number of elements in the buffer)
+     * @return a new, appropriately sized IndexBuffer, which may be an
+     * {@link IndexByteBuffer}, an {@link IndexShortBuffer}, or an
      * {@link IndexIntBuffer}
-     * 
-     * @param vertexCount The amount of vertices to contain
-     * @param indexCount The amount of indices to contain
-     * @return A new, apropriately sized index buffer
      */
-    public static IndexBuffer createIndexBuffer(int vertexCount, int indexCount){
-        if (vertexCount < 128)
-            return new IndexByteBuffer(BufferUtils.createByteBuffer (indexCount));
-        else if (vertexCount < 65536)
-            return new IndexShortBuffer(BufferUtils.createShortBuffer(indexCount));
-        else
-            return new IndexIntBuffer(BufferUtils.createIntBuffer(indexCount));
+    public static IndexBuffer createIndexBuffer(int vertexCount,
+            int indexCount) {
+        IndexBuffer result;
+
+        if (vertexCount < 128) { // TODO: could be vertexCount <= 256
+            ByteBuffer buffer = BufferUtils.createByteBuffer(indexCount);
+            int maxIndexValue = vertexCount - 1;
+            result = new IndexByteBuffer(buffer, maxIndexValue);
+
+        } else if (vertexCount < 65536) { // TODO: could be <= 65536
+            ShortBuffer buffer = BufferUtils.createShortBuffer(indexCount);
+            int maxIndexValue = vertexCount - 1;
+            result = new IndexShortBuffer(buffer, maxIndexValue);
+
+        } else {
+            IntBuffer buffer = BufferUtils.createIntBuffer(indexCount);
+            result = new IndexIntBuffer(buffer);
+        }
+
+        return result;
     }
 
     /**

+ 35 - 2
jme3-core/src/main/java/com/jme3/scene/mesh/IndexByteBuffer.java

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009-2012 jMonkeyEngine
+ * Copyright (c) 2009-2020 jMonkeyEngine
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -43,13 +43,38 @@ import com.jme3.scene.VertexBuffer.Format;
  */
 public class IndexByteBuffer extends IndexBuffer {
 
-    private ByteBuffer buf;
+    final private ByteBuffer buf;
+    /**
+     * the largest index value that can be put to the buffer
+     */
+    private int maxValue = 255;
 
+    /**
+     * Instantiate an IndexBuffer using the specified ByteBuffer and a maximum
+     * index value of 255.
+     *
+     * @param buffer a pre-existing buffer (not null, alias created)
+     */
     public IndexByteBuffer(ByteBuffer buffer) {
         buf = buffer;
         buf.rewind();
     }
 
+    /**
+     * Instantiate an IndexBuffer using the specified ByteBuffer and set its
+     * maximum index value.
+     *
+     * @param buffer a pre-existing buffer (not null, alias created)
+     * @param maxValue the desired maximum index value (&ge;0, &le;255)
+     */
+    public IndexByteBuffer(ByteBuffer buffer, int maxValue) {
+        assert maxValue >= 0 && maxValue <= 255 : "out of range: " + maxValue;
+        this.maxValue = maxValue;
+
+        buf = buffer;
+        buf.rewind();
+    }
+
     @Override
     public int get() {
         return buf.get() & 0x000000FF;
@@ -62,12 +87,20 @@ public class IndexByteBuffer extends IndexBuffer {
 
     @Override
     public IndexByteBuffer put(int i, int value) {
+        assert value >= 0 && value <= maxValue 
+                : "IndexBuffer was created with elements too small for value="
+                + value;
+
         buf.put(i, (byte) value);
         return this;
     }
     
     @Override
     public IndexByteBuffer put(int value) {
+        assert value >= 0 && value <= maxValue 
+                : "IndexBuffer was created with elements too small for value="
+                + value;
+
         buf.put((byte) value);
         return this;
     }

+ 35 - 2
jme3-core/src/main/java/com/jme3/scene/mesh/IndexShortBuffer.java

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009-2012 jMonkeyEngine
+ * Copyright (c) 2009-2020 jMonkeyEngine
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -43,13 +43,38 @@ import com.jme3.scene.VertexBuffer.Format;
  */
 public class IndexShortBuffer extends IndexBuffer {
 
-    private ShortBuffer buf;
+    final private ShortBuffer buf;
+    /**
+     * the largest index value that can be put to the buffer
+     */
+    private int maxValue = 65_535;
 
+    /**
+     * Instantiate an IndexBuffer using the specified ShortBuffer and a maximum
+     * index value of 65_535.
+     *
+     * @param buffer a pre-existing buffer (not null, alias created)
+     */
     public IndexShortBuffer(ShortBuffer buffer) {
         buf = buffer;
         buf.rewind();
     }
 
+    /**
+     * Instantiate an IndexBuffer using the specified ShortBuffer and set its
+     * maximum index value.
+     *
+     * @param buffer a pre-existing buffer (not null, alias created)
+     * @param maxValue the desired maximum index value (&ge;0, &le;65_535)
+     */
+    public IndexShortBuffer(ShortBuffer buffer, int maxValue) {
+        assert maxValue >= 0 && maxValue <= 65_535 : "out of range: " + maxValue;
+        this.maxValue = maxValue;
+
+        buf = buffer;
+        buf.rewind();
+    }
+
     @Override
     public int get() {
         return buf.get() & 0x0000FFFF;
@@ -61,12 +86,20 @@ public class IndexShortBuffer extends IndexBuffer {
 
     @Override
     public IndexShortBuffer put(int i, int value) {
+        assert value >= 0 && value <= maxValue 
+                : "IndexBuffer was created with elements too small for value="
+                + value;
+
         buf.put(i, (short) value);
         return this;
     }
     
     @Override
     public IndexShortBuffer put(int value) {
+        assert value >= 0 && value <= maxValue 
+                : "IndexBuffer was created with elements too small for value="
+                + value;
+
         buf.put((short) value);
         return this;
     }