| /* |
| * 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.kafka.common.utils; |
| |
| import org.junit.Test; |
| |
| import java.io.ByteArrayInputStream; |
| import java.io.ByteArrayOutputStream; |
| import java.io.DataInputStream; |
| import java.io.DataOutputStream; |
| import java.io.IOException; |
| import java.nio.ByteBuffer; |
| |
| import static org.junit.Assert.assertArrayEquals; |
| import static org.junit.Assert.assertEquals; |
| |
| public class ByteUtilsTest { |
| private final byte x00 = 0x00; |
| private final byte x01 = 0x01; |
| private final byte x02 = 0x02; |
| private final byte x0F = 0x0f; |
| private final byte x7E = 0x7E; |
| private final byte x7F = 0x7F; |
| private final byte xFF = (byte) 0xff; |
| private final byte x80 = (byte) 0x80; |
| private final byte x81 = (byte) 0x81; |
| private final byte xFE = (byte) 0xfe; |
| |
| @Test |
| public void testReadUnsignedIntLEFromArray() { |
| byte[] array1 = {0x01, 0x02, 0x03, 0x04, 0x05}; |
| assertEquals(0x04030201, ByteUtils.readUnsignedIntLE(array1, 0)); |
| assertEquals(0x05040302, ByteUtils.readUnsignedIntLE(array1, 1)); |
| |
| byte[] array2 = {(byte) 0xf1, (byte) 0xf2, (byte) 0xf3, (byte) 0xf4, (byte) 0xf5, (byte) 0xf6}; |
| assertEquals(0xf4f3f2f1, ByteUtils.readUnsignedIntLE(array2, 0)); |
| assertEquals(0xf6f5f4f3, ByteUtils.readUnsignedIntLE(array2, 2)); |
| } |
| |
| @Test |
| public void testReadUnsignedIntLEFromInputStream() throws IOException { |
| byte[] array1 = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09}; |
| ByteArrayInputStream is1 = new ByteArrayInputStream(array1); |
| assertEquals(0x04030201, ByteUtils.readUnsignedIntLE(is1)); |
| assertEquals(0x08070605, ByteUtils.readUnsignedIntLE(is1)); |
| |
| byte[] array2 = {(byte) 0xf1, (byte) 0xf2, (byte) 0xf3, (byte) 0xf4, (byte) 0xf5, (byte) 0xf6, (byte) 0xf7, (byte) 0xf8}; |
| ByteArrayInputStream is2 = new ByteArrayInputStream(array2); |
| assertEquals(0xf4f3f2f1, ByteUtils.readUnsignedIntLE(is2)); |
| assertEquals(0xf8f7f6f5, ByteUtils.readUnsignedIntLE(is2)); |
| } |
| |
| @Test |
| public void testReadUnsignedInt() { |
| ByteBuffer buffer = ByteBuffer.allocate(4); |
| long writeValue = 133444; |
| ByteUtils.writeUnsignedInt(buffer, writeValue); |
| buffer.flip(); |
| long readValue = ByteUtils.readUnsignedInt(buffer); |
| assertEquals(writeValue, readValue); |
| } |
| |
| @Test |
| public void testWriteUnsignedIntLEToArray() { |
| int value1 = 0x04030201; |
| |
| byte[] array1 = new byte[4]; |
| ByteUtils.writeUnsignedIntLE(array1, 0, value1); |
| assertArrayEquals(new byte[] {0x01, 0x02, 0x03, 0x04}, array1); |
| |
| array1 = new byte[8]; |
| ByteUtils.writeUnsignedIntLE(array1, 2, value1); |
| assertArrayEquals(new byte[] {0, 0, 0x01, 0x02, 0x03, 0x04, 0, 0}, array1); |
| |
| int value2 = 0xf4f3f2f1; |
| |
| byte[] array2 = new byte[4]; |
| ByteUtils.writeUnsignedIntLE(array2, 0, value2); |
| assertArrayEquals(new byte[] {(byte) 0xf1, (byte) 0xf2, (byte) 0xf3, (byte) 0xf4}, array2); |
| |
| array2 = new byte[8]; |
| ByteUtils.writeUnsignedIntLE(array2, 2, value2); |
| assertArrayEquals(new byte[] {0, 0, (byte) 0xf1, (byte) 0xf2, (byte) 0xf3, (byte) 0xf4, 0, 0}, array2); |
| } |
| |
| @Test |
| public void testWriteUnsignedIntLEToOutputStream() throws IOException { |
| int value1 = 0x04030201; |
| ByteArrayOutputStream os1 = new ByteArrayOutputStream(); |
| ByteUtils.writeUnsignedIntLE(os1, value1); |
| ByteUtils.writeUnsignedIntLE(os1, value1); |
| assertArrayEquals(new byte[] {0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04}, os1.toByteArray()); |
| |
| int value2 = 0xf4f3f2f1; |
| ByteArrayOutputStream os2 = new ByteArrayOutputStream(); |
| ByteUtils.writeUnsignedIntLE(os2, value2); |
| assertArrayEquals(new byte[] {(byte) 0xf1, (byte) 0xf2, (byte) 0xf3, (byte) 0xf4}, os2.toByteArray()); |
| } |
| |
| @Test |
| public void testVarintSerde() throws Exception { |
| assertVarintSerde(0, new byte[] {x00}); |
| assertVarintSerde(-1, new byte[] {x01}); |
| assertVarintSerde(1, new byte[] {x02}); |
| assertVarintSerde(63, new byte[] {x7E}); |
| assertVarintSerde(-64, new byte[] {x7F}); |
| assertVarintSerde(64, new byte[] {x80, x01}); |
| assertVarintSerde(-65, new byte[] {x81, x01}); |
| assertVarintSerde(8191, new byte[] {xFE, x7F}); |
| assertVarintSerde(-8192, new byte[] {xFF, x7F}); |
| assertVarintSerde(8192, new byte[] {x80, x80, x01}); |
| assertVarintSerde(-8193, new byte[] {x81, x80, x01}); |
| assertVarintSerde(1048575, new byte[] {xFE, xFF, x7F}); |
| assertVarintSerde(-1048576, new byte[] {xFF, xFF, x7F}); |
| assertVarintSerde(1048576, new byte[] {x80, x80, x80, x01}); |
| assertVarintSerde(-1048577, new byte[] {x81, x80, x80, x01}); |
| assertVarintSerde(134217727, new byte[] {xFE, xFF, xFF, x7F}); |
| assertVarintSerde(-134217728, new byte[] {xFF, xFF, xFF, x7F}); |
| assertVarintSerde(134217728, new byte[] {x80, x80, x80, x80, x01}); |
| assertVarintSerde(-134217729, new byte[] {x81, x80, x80, x80, x01}); |
| assertVarintSerde(Integer.MAX_VALUE, new byte[] {xFE, xFF, xFF, xFF, x0F}); |
| assertVarintSerde(Integer.MIN_VALUE, new byte[] {xFF, xFF, xFF, xFF, x0F}); |
| } |
| |
| @Test |
| public void testVarlongSerde() throws Exception { |
| assertVarlongSerde(0, new byte[] {x00}); |
| assertVarlongSerde(-1, new byte[] {x01}); |
| assertVarlongSerde(1, new byte[] {x02}); |
| assertVarlongSerde(63, new byte[] {x7E}); |
| assertVarlongSerde(-64, new byte[] {x7F}); |
| assertVarlongSerde(64, new byte[] {x80, x01}); |
| assertVarlongSerde(-65, new byte[] {x81, x01}); |
| assertVarlongSerde(8191, new byte[] {xFE, x7F}); |
| assertVarlongSerde(-8192, new byte[] {xFF, x7F}); |
| assertVarlongSerde(8192, new byte[] {x80, x80, x01}); |
| assertVarlongSerde(-8193, new byte[] {x81, x80, x01}); |
| assertVarlongSerde(1048575, new byte[] {xFE, xFF, x7F}); |
| assertVarlongSerde(-1048576, new byte[] {xFF, xFF, x7F}); |
| assertVarlongSerde(1048576, new byte[] {x80, x80, x80, x01}); |
| assertVarlongSerde(-1048577, new byte[] {x81, x80, x80, x01}); |
| assertVarlongSerde(134217727, new byte[] {xFE, xFF, xFF, x7F}); |
| assertVarlongSerde(-134217728, new byte[] {xFF, xFF, xFF, x7F}); |
| assertVarlongSerde(134217728, new byte[] {x80, x80, x80, x80, x01}); |
| assertVarlongSerde(-134217729, new byte[] {x81, x80, x80, x80, x01}); |
| assertVarlongSerde(Integer.MAX_VALUE, new byte[] {xFE, xFF, xFF, xFF, x0F}); |
| assertVarlongSerde(Integer.MIN_VALUE, new byte[] {xFF, xFF, xFF, xFF, x0F}); |
| assertVarlongSerde(17179869183L, new byte[] {xFE, xFF, xFF, xFF, x7F}); |
| assertVarlongSerde(-17179869184L, new byte[] {xFF, xFF, xFF, xFF, x7F}); |
| assertVarlongSerde(17179869184L, new byte[] {x80, x80, x80, x80, x80, x01}); |
| assertVarlongSerde(-17179869185L, new byte[] {x81, x80, x80, x80, x80, x01}); |
| assertVarlongSerde(2199023255551L, new byte[] {xFE, xFF, xFF, xFF, xFF, x7F}); |
| assertVarlongSerde(-2199023255552L, new byte[] {xFF, xFF, xFF, xFF, xFF, x7F}); |
| assertVarlongSerde(2199023255552L, new byte[] {x80, x80, x80, x80, x80, x80, x01}); |
| assertVarlongSerde(-2199023255553L, new byte[] {x81, x80, x80, x80, x80, x80, x01}); |
| assertVarlongSerde(281474976710655L, new byte[] {xFE, xFF, xFF, xFF, xFF, xFF, x7F}); |
| assertVarlongSerde(-281474976710656L, new byte[] {xFF, xFF, xFF, xFF, xFF, xFF, x7F}); |
| assertVarlongSerde(281474976710656L, new byte[] {x80, x80, x80, x80, x80, x80, x80, x01}); |
| assertVarlongSerde(-281474976710657L, new byte[] {x81, x80, x80, x80, x80, x80, x80, 1}); |
| assertVarlongSerde(36028797018963967L, new byte[] {xFE, xFF, xFF, xFF, xFF, xFF, xFF, x7F}); |
| assertVarlongSerde(-36028797018963968L, new byte[] {xFF, xFF, xFF, xFF, xFF, xFF, xFF, x7F}); |
| assertVarlongSerde(36028797018963968L, new byte[] {x80, x80, x80, x80, x80, x80, x80, x80, x01}); |
| assertVarlongSerde(-36028797018963969L, new byte[] {x81, x80, x80, x80, x80, x80, x80, x80, x01}); |
| assertVarlongSerde(4611686018427387903L, new byte[] {xFE, xFF, xFF, xFF, xFF, xFF, xFF, xFF, x7F}); |
| assertVarlongSerde(-4611686018427387904L, new byte[] {xFF, xFF, xFF, xFF, xFF, xFF, xFF, xFF, x7F}); |
| assertVarlongSerde(4611686018427387904L, new byte[] {x80, x80, x80, x80, x80, x80, x80, x80, x80, x01}); |
| assertVarlongSerde(-4611686018427387905L, new byte[] {x81, x80, x80, x80, x80, x80, x80, x80, x80, x01}); |
| assertVarlongSerde(Long.MAX_VALUE, new byte[] {xFE, xFF, xFF, xFF, xFF, xFF, xFF, xFF, xFF, x01}); |
| assertVarlongSerde(Long.MIN_VALUE, new byte[] {xFF, xFF, xFF, xFF, xFF, xFF, xFF, xFF, xFF, x01}); |
| } |
| |
| @Test(expected = IllegalArgumentException.class) |
| public void testInvalidVarint() { |
| // varint encoding has one overflow byte |
| ByteBuffer buf = ByteBuffer.wrap(new byte[] {xFF, xFF, xFF, xFF, xFF, x01}); |
| ByteUtils.readVarint(buf); |
| } |
| |
| @Test(expected = IllegalArgumentException.class) |
| public void testInvalidVarlong() { |
| // varlong encoding has one overflow byte |
| ByteBuffer buf = ByteBuffer.wrap(new byte[] {xFF, xFF, xFF, xFF, xFF, xFF, xFF, xFF, xFF, xFF, x01}); |
| ByteUtils.readVarlong(buf); |
| } |
| |
| private void assertVarintSerde(int value, byte[] expectedEncoding) throws IOException { |
| ByteBuffer buf = ByteBuffer.allocate(32); |
| ByteUtils.writeVarint(value, buf); |
| buf.flip(); |
| assertArrayEquals(expectedEncoding, Utils.toArray(buf)); |
| assertEquals(value, ByteUtils.readVarint(buf.duplicate())); |
| |
| buf.rewind(); |
| DataOutputStream out = new DataOutputStream(new ByteBufferOutputStream(buf)); |
| ByteUtils.writeVarint(value, out); |
| buf.flip(); |
| assertArrayEquals(expectedEncoding, Utils.toArray(buf)); |
| DataInputStream in = new DataInputStream(new ByteBufferInputStream(buf)); |
| assertEquals(value, ByteUtils.readVarint(in)); |
| } |
| |
| private void assertVarlongSerde(long value, byte[] expectedEncoding) throws IOException { |
| ByteBuffer buf = ByteBuffer.allocate(32); |
| ByteUtils.writeVarlong(value, buf); |
| buf.flip(); |
| assertEquals(value, ByteUtils.readVarlong(buf.duplicate())); |
| assertArrayEquals(expectedEncoding, Utils.toArray(buf)); |
| |
| buf.rewind(); |
| DataOutputStream out = new DataOutputStream(new ByteBufferOutputStream(buf)); |
| ByteUtils.writeVarlong(value, out); |
| buf.flip(); |
| assertArrayEquals(expectedEncoding, Utils.toArray(buf)); |
| DataInputStream in = new DataInputStream(new ByteBufferInputStream(buf)); |
| assertEquals(value, ByteUtils.readVarlong(in)); |
| } |
| |
| } |