88 * %%
99 * Redistribution and use in source and binary forms, with or without
1010 * modification, are permitted provided that the following conditions are met:
11- *
11+ *
1212 * 1. Redistributions of source code must retain the above copyright notice,
1313 * this list of conditions and the following disclaimer.
1414 * 2. Redistributions in binary form must reproduce the above copyright notice,
1515 * this list of conditions and the following disclaimer in the documentation
1616 * and/or other materials provided with the distribution.
17- *
17+ *
1818 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
1919 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2020 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2929 * #L%
3030 */
3131
32- package org .scijava .io ;
32+ package org .scijava .io . bytes ;
3333
3434import org .scijava .util .ByteArray ;
3535
3636/**
37- * {@link IOBuffer} implementation backed by a {@link ByteArray}.
38- *
37+ * {@link ByteBank} implementation backed by a {@link ByteArray}. Self-growing
38+ * up to a maximum capacity of {@link Integer#MAX_VALUE}
39+ *
3940 * @author Gabriel Einsdorf
4041 */
41- public class ByteArrayIOBuffer implements IOBuffer {
42+ public class ByteArrayByteBank implements ByteBank {
4243
43- private ByteArray buffer ;
44+ private final ByteArray buffer ;
4445 private long maxBufferedPos = -1 ;
4546
46- public ByteArrayIOBuffer () {
47+ /**
48+ * Creates a {@link ByteArrayByteBank}
49+ */
50+ public ByteArrayByteBank () {
4751 buffer = new ByteArray ();
4852 }
4953
54+ /**
55+ * Creates a {@link ByteArrayByteBank} with the specified initial capacity
56+ *
57+ * @param initialCapacity the initial capacity of this {@link ByteBank}
58+ */
59+ public ByteArrayByteBank (final int initialCapacity ) {
60+ buffer = new ByteArray (initialCapacity );
61+ }
62+
63+ /**
64+ * Creates a {@link ByteArrayByteBank} that wraps the specified
65+ * {@link ByteArray}.
66+ *
67+ * @param bytes the {@link ByteArray} to wrap
68+ */
69+ public ByteArrayByteBank (final ByteArray bytes ) {
70+ buffer = bytes ;
71+ bytes .size ();
72+ }
73+
74+ /**
75+ * Creates a {@link ByteArrayByteBank} that wraps the provided byte array
76+ *
77+ * @param bytes the bytes to wrap
78+ */
79+ public ByteArrayByteBank (final byte [] bytes ) {
80+ buffer = new ByteArray (bytes );
81+ maxBufferedPos = bytes .length ;
82+ }
83+
5084 @ Override
51- public int getMaxBufferSize () {
85+ public long getMaxBufferSize () {
5286 return Integer .MAX_VALUE ;
5387 }
5488
5589 @ Override
56- public void setBytes (long startpos , byte [] bytes , int offset , int length ) {
90+ public void setBytes (final long startpos , final byte [] bytes ,
91+ final int offset , final int length )
92+ {
5793 // ensure we have space
5894 checkWritePos (startpos , startpos + length );
59- int neededCapacity = (int ) (Math .max (maxBufferedPos , 0 ) + length );
95+ final int neededCapacity = (int ) (Math .max (maxBufferedPos , 0 ) + length );
6096 buffer .ensureCapacity (neededCapacity );
6197
6298 // copy the data
@@ -66,13 +102,13 @@ public void setBytes(long startpos, byte[] bytes, int offset, int length) {
66102 }
67103
68104 @ Override
69- public void setByte (long pos , byte b ) {
105+ public void setByte (final long pos , final byte b ) {
70106 checkWritePos (pos , pos );
71107 buffer .setValue ((int ) pos , b );
72108 updateMaxPos (pos );
73109 }
74110
75- private void updateMaxPos (long pos ) {
111+ private void updateMaxPos (final long pos ) {
76112 maxBufferedPos = pos > maxBufferedPos ? pos : maxBufferedPos ;
77113 }
78114
@@ -83,77 +119,25 @@ public void clear() {
83119 }
84120
85121 @ Override
86- public byte getByte (long pos ) {
122+ public byte getByte (final long pos ) {
87123 checkReadPos (pos , pos );
88124 // the buffer might contain bytes with negative value
89125 // we need to flip the sign to positive to satisfy the method contract
90126 return buffer .getValue ((int ) pos );
91127 }
92128
93129 @ Override
94- public int getBytes (long startPos , byte [] b , int offset , int length ) {
130+ public int getBytes (final long startPos , final byte [] b , final int offset ,
131+ final int length )
132+ {
95133 checkReadPos (startPos , startPos + length );
96- System .arraycopy (buffer .getArray (), (int ) startPos , b , offset , length );
97- return length ;
134+ final int readLength = (int ) Math .min (getMaxPos () - startPos , length );
135+ System .arraycopy (buffer .getArray (), (int ) startPos , b , offset , readLength );
136+ return readLength ;
98137 }
99138
100139 @ Override
101140 public long getMaxPos () {
102141 return maxBufferedPos ;
103142 }
104-
105- /**
106- * Ensures that the requested range satisfies basic sanity criteria.
107- *
108- * @param start the start of the range
109- * @param end the end of the range
110- */
111- private void basicRangeCheck (long start , long end ) {
112- if (start > Integer .MAX_VALUE ) {
113- throw new IndexOutOfBoundsException ("Requested postion " + start +
114- " is larger than the maximal buffer size: " + Integer .MAX_VALUE );
115- }
116- if (end > Integer .MAX_VALUE ) {
117- throw new IndexOutOfBoundsException ("Requested postion " + end +
118- " is larger than the maximal buffer size: " + Integer .MAX_VALUE );
119- }
120- if (end < start ) {
121- throw new IllegalArgumentException (
122- "Invalid range, end is smaller than start!" );
123- }
124- }
125-
126- /**
127- * Check if we can write to the specified range
128- *
129- * @param start the start position of the range
130- * @param end the end position of the range
131- */
132- private void checkWritePos (long start , long end ) {
133- basicRangeCheck (start , end );
134- if (start > maxBufferedPos + 1 ) { // we can't have holes in the buffer
135- throw new IndexOutOfBoundsException ("Requested start position: " + start +
136- " would leave a hole in the buffer, largest legal position is: " +
137- maxBufferedPos + 1 );
138- }
139- }
140-
141- /**
142- * Check if we can read from the specified range
143- *
144- * @param start the start position of the range
145- * @param end the end position of the range
146- */
147- private void checkReadPos (long start , long end ) {
148- basicRangeCheck (start , end );
149- if (start > maxBufferedPos ) {
150- throw new IndexOutOfBoundsException ("Reuested position: " + start +
151- " is larger than the maximally buffered postion: " + maxBufferedPos );
152- }
153- if (end > maxBufferedPos ) {
154- throw new IndexOutOfBoundsException ("reuested position: " + end +
155- " is larger than the maximally buffered postion: " + maxBufferedPos );
156- }
157- }
158-
159143}
0 commit comments