| /* ==================================================================== |
| 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.poi.util; |
| |
| import static org.junit.jupiter.api.Assertions.assertArrayEquals; |
| import static org.junit.jupiter.api.Assertions.assertEquals; |
| import static org.junit.jupiter.api.Assertions.assertThrows; |
| import static org.junit.jupiter.api.Assertions.assertTrue; |
| |
| import java.io.ByteArrayOutputStream; |
| import java.io.IOException; |
| import java.io.PrintStream; |
| import java.io.UnsupportedEncodingException; |
| |
| import org.junit.jupiter.api.AfterAll; |
| import org.junit.jupiter.api.BeforeAll; |
| import org.junit.jupiter.api.Test; |
| import org.junit.jupiter.params.ParameterizedTest; |
| import org.junit.jupiter.params.provider.ValueSource; |
| |
| class TestHexDump { |
| |
| private static PrintStream SYSTEM_OUT; |
| |
| @BeforeAll |
| public static void setUp() throws UnsupportedEncodingException { |
| SYSTEM_OUT = System.out; |
| System.setOut(new NullPrintStream()); |
| } |
| |
| @AfterAll |
| public static void tearDown() { |
| System.setOut(SYSTEM_OUT); |
| } |
| |
| @Test |
| void testDump() throws IOException { |
| byte[] testArray = testArray(); |
| ByteArrayOutputStream streamAct = new ByteArrayOutputStream(); |
| HexDump.dump(testArray, 0, streamAct, 0); |
| byte[] bytesAct = streamAct.toByteArray(); |
| byte[] bytesExp = toHexDump(0, 0); |
| |
| assertEquals(bytesExp.length, bytesAct.length, "array size mismatch"); |
| assertArrayEquals(bytesExp, bytesAct, "array mismatch"); |
| |
| // verify proper behavior with non-zero offset |
| streamAct.reset(); |
| HexDump.dump(testArray, 0x10000000L, streamAct, 0); |
| bytesAct = streamAct.toByteArray(); |
| bytesExp = toHexDump(0x10000000L,0); |
| |
| assertEquals(bytesExp.length, bytesAct.length, "array size mismatch"); |
| assertArrayEquals(bytesExp, bytesAct, "array mismatch"); |
| |
| // verify proper behavior with negative offset |
| streamAct.reset(); |
| HexDump.dump(testArray, 0xFF000000L, streamAct, 0); |
| bytesAct = streamAct.toByteArray(); |
| bytesExp = toHexDump(0xFF000000L,0); |
| |
| assertEquals(bytesExp.length, bytesAct.length, "array size mismatch"); |
| assertArrayEquals(bytesExp, bytesAct, "array mismatch"); |
| |
| // verify proper behavior with non-zero index |
| streamAct.reset(); |
| HexDump.dump(testArray, 0xFF000000L, streamAct, 0x81); |
| bytesAct = streamAct.toByteArray(); |
| bytesExp = toHexDump(0xFF000000L,0x81); |
| |
| assertEquals(bytesExp.length, bytesAct.length, "array size mismatch"); |
| assertArrayEquals(bytesExp, bytesAct, "array mismatch"); |
| |
| |
| // verify proper behavior with negative index |
| streamAct.reset(); |
| assertThrows(ArrayIndexOutOfBoundsException.class, () -> HexDump.dump(testArray, 0x10000000L, streamAct, -1)); |
| |
| // verify proper behavior with index that is too large |
| streamAct.reset(); |
| assertThrows(ArrayIndexOutOfBoundsException.class, () -> HexDump.dump(testArray, 0x10000000L, streamAct, testArray.length)); |
| |
| // verify proper behavior with null stream |
| assertThrows(IllegalArgumentException.class, () -> HexDump.dump(testArray, 0x10000000L, null, 0)); |
| |
| // verify proper behaviour with empty byte array |
| streamAct.reset(); |
| HexDump.dump( new byte[0], 0, streamAct, 0 ); |
| assertEquals( "No Data" + System.getProperty( "line.separator"), streamAct.toString(LocaleUtil.CHARSET_1252.name()) ); |
| |
| } |
| |
| private byte[] toHexDump(long offset, int index) { |
| StringBuilder strExp = new StringBuilder(), chrs = new StringBuilder(); |
| Object[] obj = new Object[33]; |
| StringBuilder format = new StringBuilder(); |
| |
| for (int j = 0; j < 16 && (index + j*16) < 256; j++) { |
| obj[0] = offset+index+j*16L; |
| chrs.setLength(0); |
| format.setLength(0); |
| format.append("%08X "); |
| for (int k = 0; k < 16; k++) { |
| if (index+j*16+k < 256){ |
| obj[k+1] = index+j*16+k; |
| chrs.append(HexDump.toAscii(index+j*16+k)); |
| format.append("%02X "); |
| } else { |
| format.append(" "); |
| } |
| } |
| obj[17] = chrs.toString(); |
| format.append("%18$s").append(HexDump.EOL); |
| |
| String str = String.format(LocaleUtil.getUserLocale(), format.toString(), obj); |
| strExp.append(str); |
| } |
| return strExp.toString().getBytes(HexDump.UTF8); |
| } |
| |
| @Test |
| void testToHex() { |
| assertEquals("000A", HexDump.toHex((short)0xA)); |
| |
| assertEquals("0A", HexDump.toHex((byte)0xA)); |
| assertEquals("0000000A", HexDump.toHex(0xA)); |
| |
| assertEquals("[]", HexDump.toHex(new byte[] { })); |
| assertEquals("[0A]", HexDump.toHex(new byte[] { 0xA })); |
| assertEquals("[0A, 0B]", HexDump.toHex(new byte[] { 0xA, 0xB })); |
| |
| assertEquals("FFFF", HexDump.toHex((short)0xFFFF)); |
| |
| assertEquals("00000000000004D2", HexDump.toHex(1234L)); |
| |
| assertEquals("0xFE", HexDump.byteToHex(-2)); |
| assertEquals("0x25", HexDump.byteToHex(37)); |
| assertEquals("0xFFFE", HexDump.shortToHex(-2)); |
| assertEquals("0x0005", HexDump.shortToHex(5)); |
| assertEquals("0xFFFFFF9C", HexDump.intToHex(-100)); |
| assertEquals("0x00001001", HexDump.intToHex(4097)); |
| assertEquals("0xFFFFFFFFFFFF0006", HexDump.longToHex(-65530)); |
| assertEquals("0x0000000000003FCD", HexDump.longToHex(16333)); |
| } |
| |
| @Test |
| void testDumpToString() { |
| byte[] testArray = testArray(); |
| String dump = HexDump.dump(testArray, 0, 0); |
| //System.out.println("Hex: \n" + dump); |
| assertTrue(dump.contains("0123456789:;<=>?"), "Had: \n" + dump); |
| |
| dump = HexDump.dump(testArray, 2, 1); |
| //System.out.println("Hex: \n" + dump); |
| assertTrue(dump.contains("123456789:;<=>?@"), "Had: \n" + dump); |
| } |
| |
| @ParameterizedTest |
| @ValueSource(ints = {-1, 2, 1}) |
| void testDumpToStringOutOfIndex1(int index) { |
| assertThrows(ArrayIndexOutOfBoundsException.class, () -> |
| HexDump.dump(new byte[1], 0, index)); |
| } |
| |
| @ParameterizedTest |
| @ValueSource(ints = {0, 1}) |
| void testDumpToStringNoDataEOL(int index) { |
| String s = HexDump.dump(new byte[0], 0, index); |
| assertEquals("No Data", s.trim()); |
| } |
| |
| private static byte[] testArray() { |
| byte[] testArray = new byte[ 256 ]; |
| |
| for (int j = 0; j < 256; j++) { |
| testArray[ j ] = ( byte ) j; |
| } |
| |
| return testArray; |
| } |
| } |