| /* |
| * 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.geode.internal.serialization; |
| |
| import static org.assertj.core.api.Assertions.assertThat; |
| import static org.assertj.core.api.Assertions.catchThrowable; |
| |
| import java.io.DataInput; |
| import java.io.EOFException; |
| import java.io.IOException; |
| |
| import org.junit.Test; |
| |
| public class ByteArrayDataInputTest { |
| @Test |
| public void readFullyThatReadsPastEndOfDataThrowsEOFException() throws IOException { |
| byte[] inputBytes = new byte[1]; |
| DataInput input = createDataInput(inputBytes); |
| byte[] outputBytes = new byte[2]; |
| |
| Throwable t = catchThrowable(() -> input.readFully(outputBytes)); |
| |
| assertThat(t).isInstanceOf(EOFException.class); |
| } |
| |
| @Test |
| public void readLineGivenInputAtEOFReturnsNull() throws IOException { |
| byte[] inputBytes = new byte[1]; |
| DataInput input = createDataInput(inputBytes); |
| input.readByte(); |
| |
| String result = input.readLine(); |
| |
| assertThat(result).isNull(); |
| assertThat(dataRemaining(input)).isEqualTo(0); |
| } |
| |
| @Test |
| public void readLineGivenEmptyLineTerminatedByLineFeedReturnsEmptyString() throws IOException { |
| byte[] inputBytes = new byte[] {'\n'}; |
| DataInput input = createDataInput(inputBytes); |
| |
| String result = input.readLine(); |
| |
| assertThat(result).isEmpty(); |
| assertThat(dataRemaining(input)).isEqualTo(0); |
| } |
| |
| @Test |
| public void readLineGivenEmptyLineTerminatedByLineFeedReturnsEmptyStringDoesNotConsumeNextByte() |
| throws IOException { |
| byte[] inputBytes = new byte[] {'\n', 'a'}; |
| DataInput input = createDataInput(inputBytes); |
| |
| String result = input.readLine(); |
| |
| assertThat(result).isEmpty(); |
| assertThat(dataRemaining(input)).isEqualTo(1); |
| assertThat(input.readUnsignedByte()).isEqualTo((int) 'a'); |
| } |
| |
| @Test |
| public void readLineGivenEmptyLineTerminatedByCarriageReturnReturnsEmptyString() |
| throws IOException { |
| byte[] inputBytes = new byte[] {'\r'}; |
| DataInput input = createDataInput(inputBytes); |
| |
| String result = input.readLine(); |
| |
| assertThat(result).isEmpty(); |
| assertThat(dataRemaining(input)).isEqualTo(0); |
| } |
| |
| @Test |
| public void readLineGivenEmptyLineTerminatedByCarriageReturnReturnsEmptyStringAndDoesNotConsumeNextByte() |
| throws IOException { |
| byte[] inputBytes = new byte[] {'\r', 'a'}; |
| DataInput input = createDataInput(inputBytes); |
| |
| String result = input.readLine(); |
| |
| assertThat(result).isEmpty(); |
| assertThat(dataRemaining(input)).isEqualTo(1); |
| assertThat(input.readUnsignedByte()).isEqualTo((int) 'a'); |
| } |
| |
| @Test |
| public void readLineGivenEmptyLineTerminatedByCarriageReturnLineFeedReturnsEmptyString() |
| throws IOException { |
| byte[] inputBytes = new byte[] {'\r', '\n'}; |
| DataInput input = createDataInput(inputBytes); |
| |
| String result = input.readLine(); |
| |
| assertThat(result).isEmpty(); |
| assertThat(dataRemaining(input)).isEqualTo(0); |
| } |
| |
| @Test |
| public void readLineGivenEmptyLineTerminatedByCarriageReturnLineFeedReturnsEmptyStringDoesNotConsumeNextByte() |
| throws IOException { |
| byte[] inputBytes = new byte[] {'\r', '\n', 'a'}; |
| DataInput input = createDataInput(inputBytes); |
| |
| String result = input.readLine(); |
| |
| assertThat(result).isEmpty(); |
| assertThat(dataRemaining(input)).isEqualTo(1); |
| assertThat(input.readUnsignedByte()).isEqualTo((int) 'a'); |
| } |
| |
| @Test |
| public void readLineGivenLineTerminatedByEOFReturnsCorrectLineData() throws IOException { |
| byte[] inputBytes = new byte[] {'a', 'b', 'c'}; |
| DataInput input = createDataInput(inputBytes); |
| |
| String result = input.readLine(); |
| |
| assertThat(result).isEqualTo("abc"); |
| assertThat(dataRemaining(input)).isEqualTo(0); |
| } |
| |
| @Test |
| public void readLineGivenLineTerminatedByLineFeedReturnsCorrectLineData() throws IOException { |
| byte[] inputBytes = new byte[] {'a', 'b', 'c', '\n', '2'}; |
| DataInput input = createDataInput(inputBytes); |
| |
| String result = input.readLine(); |
| |
| assertThat(result).isEqualTo("abc"); |
| assertThat(dataRemaining(input)).isEqualTo(1); |
| assertThat(input.readUnsignedByte()).isEqualTo((int) '2'); |
| } |
| |
| @Test |
| public void readLineGivenLineTerminatedByCarriageReturnReturnsCorrectLineData() |
| throws IOException { |
| byte[] inputBytes = new byte[] {'a', 'b', 'c', '\r', '2'}; |
| DataInput input = createDataInput(inputBytes); |
| |
| String result = input.readLine(); |
| |
| assertThat(result).isEqualTo("abc"); |
| assertThat(dataRemaining(input)).isEqualTo(1); |
| assertThat(input.readUnsignedByte()).isEqualTo((int) '2'); |
| } |
| |
| @Test |
| public void readLineGivenLineTerminatedByCarriageReturnLineFeedReturnsCorrectLineData() |
| throws IOException { |
| byte[] inputBytes = new byte[] {'a', 'b', 'c', '\r', '\n', '2'}; |
| DataInput input = createDataInput(inputBytes); |
| |
| String result = input.readLine(); |
| |
| assertThat(result).isEqualTo("abc"); |
| assertThat(dataRemaining(input)).isEqualTo(1); |
| assertThat(input.readUnsignedByte()).isEqualTo((int) '2'); |
| } |
| |
| @Test |
| public void readUTFHandlesEmptyString() throws IOException { |
| BufferDataOutputStream output = new BufferDataOutputStream(Version.CURRENT); |
| output.writeUTF(""); |
| output.writeByte(1); |
| DataInput input = createDataInput(output.toByteArray()); |
| |
| String result = input.readUTF(); |
| |
| assertThat(result).isEmpty(); |
| assertThat(dataRemaining(input)).isEqualTo(1); |
| assertThat(input.readByte()).isEqualTo((byte) 1); |
| } |
| |
| @Test |
| public void readUTFHandlesAsciiString() throws IOException { |
| BufferDataOutputStream output = new BufferDataOutputStream(Version.CURRENT); |
| String string = "\u0001test\u007f"; |
| output.writeUTF(string); |
| output.writeByte(1); |
| DataInput input = createDataInput(output.toByteArray()); |
| |
| String result = input.readUTF(); |
| |
| assertThat(result).isEqualTo(string); |
| assertThat(dataRemaining(input)).isEqualTo(1); |
| assertThat(input.readByte()).isEqualTo((byte) 1); |
| } |
| |
| @Test |
| public void readUTFHandlesUTF16String() throws IOException { |
| BufferDataOutputStream output = new BufferDataOutputStream(Version.CURRENT); |
| String string = "\u0000test\u0080\uffff"; |
| output.writeUTF(string); |
| output.writeByte(1); |
| DataInput input = createDataInput(output.toByteArray()); |
| |
| String result = input.readUTF(); |
| |
| assertThat(result).isEqualTo(string); |
| assertThat(dataRemaining(input)).isEqualTo(1); |
| assertThat(input.readByte()).isEqualTo((byte) 1); |
| } |
| |
| @Test |
| public void readUTFOnInputWithJustLengthThrowsEOF() { |
| BufferDataOutputStream output = new BufferDataOutputStream(Version.CURRENT); |
| output.writeShort(1); |
| DataInput input = createDataInput(output.toByteArray()); |
| |
| Throwable t = catchThrowable(() -> input.readUTF()); |
| |
| assertThat(t).isInstanceOf(EOFException.class); |
| } |
| |
| /** |
| * We want ByteArrayDataInput to behave like DataInputStream(ByteArrayInputStream). |
| * This boolean allows us to switch back and forth in this test to make sure |
| * they both behave the same. It should never be checked in with testJDK=true. |
| */ |
| private boolean testJDK = false; |
| |
| private DataInput createDataInput(byte[] inputBytes) { |
| if (testJDK) { |
| return new java.io.DataInputStream(new java.io.ByteArrayInputStream(inputBytes)); |
| } else { |
| ByteArrayDataInput input = new ByteArrayDataInput(); |
| input.initialize(inputBytes, null); |
| return input; |
| } |
| } |
| |
| private int dataRemaining(DataInput dataInput) { |
| if (testJDK) { |
| try { |
| return ((java.io.DataInputStream) dataInput).available(); |
| } catch (IOException e) { |
| throw new IllegalStateException(e); |
| } |
| } else { |
| return ((ByteArrayDataInput) dataInput).available(); |
| } |
| } |
| } |