Fix setBytes on read-only ByteBuffer
Motivation: The method setBytes did not work correctly because read-only ByteBuffer does not allow access to its underlying array. Modifications: New case was added for ByteBuffer's that are not direct and do not have an array. These must be handled by copying the data into a temporary array. Unit test was added to test this case. Result: It is now possible to use read-only ByteBuffer as the source for the setBytes method.
This commit is contained in:
parent
ad008f6831
commit
f3f49c91fd
@ -363,11 +363,21 @@ final class UnsafeByteBufUtil {
|
|||||||
// Copy from direct memory
|
// Copy from direct memory
|
||||||
long srcAddress = PlatformDependent.directBufferAddress(src);
|
long srcAddress = PlatformDependent.directBufferAddress(src);
|
||||||
PlatformDependent.copyMemory(srcAddress + src.position(), addr, src.remaining());
|
PlatformDependent.copyMemory(srcAddress + src.position(), addr, src.remaining());
|
||||||
} else {
|
src.position(src.position() + length);
|
||||||
|
} else if (src.hasArray()) {
|
||||||
// Copy from array
|
// Copy from array
|
||||||
PlatformDependent.copyMemory(src.array(), src.arrayOffset() + src.position(), addr, length);
|
PlatformDependent.copyMemory(src.array(), src.arrayOffset() + src.position(), addr, length);
|
||||||
|
src.position(src.position() + length);
|
||||||
|
} else {
|
||||||
|
ByteBuf tmpBuf = buf.alloc().heapBuffer(length);
|
||||||
|
try {
|
||||||
|
byte[] tmp = tmpBuf.array();
|
||||||
|
src.get(tmp, tmpBuf.arrayOffset(), length); // moves the src position too
|
||||||
|
PlatformDependent.copyMemory(tmp, 0, addr, length);
|
||||||
|
} finally {
|
||||||
|
tmpBuf.release();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
src.position(src.position() + length);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void getBytes(AbstractByteBuf buf, long addr, int index, OutputStream out, int length) throws IOException {
|
static void getBytes(AbstractByteBuf buf, long addr, int index, OutputStream out, int length) throws IOException {
|
||||||
|
@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2015 The Netty Project
|
||||||
|
*
|
||||||
|
* The Netty Project 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 io.netty.buffer;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
import static io.netty.util.internal.PlatformDependent.directBufferAddress;
|
||||||
|
import static org.junit.Assert.assertArrayEquals;
|
||||||
|
|
||||||
|
public class UnsafeByteBufUtilTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetBytesOnReadOnlyByteBuffer() throws Exception {
|
||||||
|
byte[] testData = new byte[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||||
|
int length = testData.length;
|
||||||
|
|
||||||
|
ByteBuffer readOnlyBuffer = ByteBuffer.wrap(testData).asReadOnlyBuffer();
|
||||||
|
|
||||||
|
UnpooledByteBufAllocator alloc = new UnpooledByteBufAllocator(true);
|
||||||
|
UnpooledDirectByteBuf targetBuffer = new UnpooledDirectByteBuf(alloc, length, length);
|
||||||
|
|
||||||
|
try {
|
||||||
|
UnsafeByteBufUtil.setBytes(targetBuffer, directBufferAddress(targetBuffer.nioBuffer()), 0, readOnlyBuffer);
|
||||||
|
|
||||||
|
byte[] check = new byte[length];
|
||||||
|
targetBuffer.getBytes(0, check, 0, length);
|
||||||
|
|
||||||
|
assertArrayEquals("The byte array's copy does not equal the original", testData, check);
|
||||||
|
} finally {
|
||||||
|
targetBuffer.release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user