diff --git a/src/main/java/prog/lzw/Lunzipping.java b/src/main/java/prog/lzw/Lunzipping.java index 22fe4f7..d91a38f 100644 --- a/src/main/java/prog/lzw/Lunzipping.java +++ b/src/main/java/prog/lzw/Lunzipping.java @@ -1,5 +1,6 @@ package prog.lzw; +import prog.util.CommonUtil; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.EOFException; @@ -52,38 +53,6 @@ public static void pre() { * ========================================================================= */ - /* - * ========================================================================= - * = byte to int conversion - * ========================================================================= - */ - public static int btoi(Byte bt) { - int ret = bt; - if (ret < 0) - ret += 256; - return ret; - - } - - /** ====================================================================== */ - - /* - * ========================================================================= - * = byte to int conversion - * ========================================================================= - */ - public static int stoi(String s) { - int ret = 0, i; - for (i = 0; i < s.length(); i++) { - ret *= 2; - if (s.charAt(i) == '1') - ret++; - } - return ret; - } - - /** ====================================================================== */ - public static void Lunzip(String fileis) { int k; int dictSize = 256; @@ -110,7 +79,7 @@ public static void Lunzip(String fileis) { while (true) { try { c = data_in.readByte(); - big1 += bttost[btoi(c)]; + big1 += bttost[CommonUtil.byteToUnsignedInt(c)]; if (big1.length() >= bitsz1) break; } catch (EOFException eof) { @@ -120,7 +89,7 @@ public static void Lunzip(String fileis) { } if (big1.length() >= bitsz1) { - k = stoi(big1.substring(0, bitsz1)); + k = CommonUtil.binaryStringToInt(big1.substring(0, bitsz1)); big1 = big1.substring(bitsz1, big1.length()); } else { data_in.close(); @@ -137,9 +106,9 @@ public static void Lunzip(String fileis) { try { while (big1.length() < bitsz1) { c = data_in.readByte(); - big1 += bttost[btoi(c)]; + big1 += bttost[CommonUtil.byteToUnsignedInt(c)]; } - k = stoi(big1.substring(0, bitsz1)); + k = CommonUtil.binaryStringToInt(big1.substring(0, bitsz1)); big1 = big1.substring(bitsz1, big1.length()); String entry = ""; diff --git a/src/main/java/prog/lzw/Lzipping.java b/src/main/java/prog/lzw/Lzipping.java index 158b420..b7a67e1 100644 --- a/src/main/java/prog/lzw/Lzipping.java +++ b/src/main/java/prog/lzw/Lzipping.java @@ -1,5 +1,6 @@ package prog.lzw; +import prog.util.CommonUtil; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.EOFException; @@ -15,14 +16,6 @@ public class Lzipping { public static int btsz; public static String big; - public static int btoi(Byte bt) { - int ret = bt; - if (ret < 0) { - ret += 256; - } - return ret; - - } /* * ========================================================================= @@ -105,7 +98,7 @@ public static void precalc(String fileis) { while (true) { try { c = data_in.readByte(); - ch = btoi(c); + ch = CommonUtil.byteToUnsignedInt(c); String wc = w + (char) ch; if (dictionary.containsKey(wc)) w = wc; @@ -178,7 +171,7 @@ public static void Lamzip(String fileis) { while (true) { try { c = data_in.readByte(); - ch = btoi(c); + ch = CommonUtil.byteToUnsignedInt(c); String wc = w + (char) ch; if (dictionary.containsKey(wc)) diff --git a/src/main/java/prog/lzw/LzwUtils.java b/src/main/java/prog/lzw/LzwUtils.java deleted file mode 100644 index 7870dc0..0000000 --- a/src/main/java/prog/lzw/LzwUtils.java +++ /dev/null @@ -1,34 +0,0 @@ -package prog.lzw; - -public class LzwUtils { - - /* - * ========================================================================= - * = byte to int conversion - * ========================================================================= - */ - public static int btoi(Byte bt) { - int ret = bt; - if (ret < 0) - ret += 256; - return ret; - - } - - /** ====================================================================== */ - - /* - * ========================================================================= - * = byte to int conversion - * ========================================================================= - */ - public static int stoi(String s) { - int ret = 0, i; - for (i = 0; i < s.length(); i++) { - ret *= 2; - if (s.charAt(i) == '1') - ret++; - } - return ret; - } -} \ No newline at end of file diff --git a/src/main/java/prog/util/CommonUtil.java b/src/main/java/prog/util/CommonUtil.java new file mode 100644 index 0000000..5f5ac3a --- /dev/null +++ b/src/main/java/prog/util/CommonUtil.java @@ -0,0 +1,69 @@ +package prog.util; + +/** + * Common utility class for byte and binary string conversions. + * + * This utility class provides essential conversion methods used throughout the + * file compression application, particularly for the LZW compression algorithm. + * It handles the conversion between different data representations that are + * crucial for encoding and decoding compressed data. + * + */ +public class CommonUtil { + + /** + * Converts a signed byte to an unsigned integer value (0-255). + * + * In Java, bytes are signed (-128 to 127), but in many compression algorithms, + * we need to treat bytes as unsigned values (0 to 255). This method performs + * that conversion by adding 256 to negative values. + * + * Example usage: + * - byteToUnsignedInt((byte) 65) returns 65 (ASCII 'A') + * - byteToUnsignedInt((byte) -1) returns 255 + * - byteToUnsignedInt((byte) -128) returns 128 + * + * @param byteValue The signed byte value to convert + * @return The unsigned integer representation (0-255) + */ + public static int byteToUnsignedInt(Byte byteValue) { + int result = byteValue; + if (result < 0) { + result += 256; + } + return result; + } + + /** + * Converts a binary string to its decimal integer representation. + * + * This method parses a string containing only '0' and '1' characters and + * converts it to its corresponding decimal integer value. It's commonly used + * in the decompression process to convert binary encoded data back to integers. + * + * The conversion is performed from left to right (most significant bit first). + * + * Example usage: + * - binaryStringToInt("0") returns 0 + * - binaryStringToInt("1010") returns 10 + * - binaryStringToInt("11111111") returns 255 + * + * @param binaryString The binary string to convert (must contain only '0' and '1') + * @return The decimal integer representation of the binary string + * @throws IllegalArgumentException if the string contains non-binary characters + */ + public static int binaryStringToInt(String binaryString) { + int result = 0; + for (int i = 0; i < binaryString.length(); i++) { + result *= 2; + char bit = binaryString.charAt(i); + if (bit == '1') { + result++; + } else if (bit != '0') { + throw new IllegalArgumentException( + "Invalid binary string: contains character '" + bit + "' at position " + i); + } + } + return result; + } +} \ No newline at end of file diff --git a/src/test/java/prog/lzw/LunzippingTest.java b/src/test/java/prog/lzw/LunzippingTest.java index 7d3bfdb..b3344d7 100644 --- a/src/test/java/prog/lzw/LunzippingTest.java +++ b/src/test/java/prog/lzw/LunzippingTest.java @@ -102,22 +102,4 @@ void testBinaryToStringConversion() { assertEquals("11111111", Lunzipping.bttost[255], "Conversion for 255"); } - @Test - void testByteToIntConversion() { - // Test positive values - assertEquals(0, Lunzipping.btoi((byte) 0)); - assertEquals(127, Lunzipping.btoi((byte) 127)); - - // Test negative values (which should be converted to positive) - assertEquals(128, Lunzipping.btoi((byte) -128)); - assertEquals(255, Lunzipping.btoi((byte) -1)); - } - - @Test - void testStringToIntConversion() { - assertEquals(0, Lunzipping.stoi("0")); - assertEquals(1, Lunzipping.stoi("1")); - assertEquals(2, Lunzipping.stoi("10")); - assertEquals(255, Lunzipping.stoi("11111111")); - } } \ No newline at end of file diff --git a/src/test/java/prog/lzw/LzippingTest.java b/src/test/java/prog/lzw/LzippingTest.java index f2b76b4..c2ce3a2 100644 --- a/src/test/java/prog/lzw/LzippingTest.java +++ b/src/test/java/prog/lzw/LzippingTest.java @@ -26,17 +26,6 @@ void setUp() throws IOException { compressedFile = new File(inputFile.getAbsolutePath() + ".LmZWp"); } - @Test - void testByteToInteger() { - // Test positive byte values - assertEquals(65, Lzipping.btoi((byte) 65)); // 'A' - assertEquals(90, Lzipping.btoi((byte) 90)); // 'Z' - assertEquals(48, Lzipping.btoi((byte) 48)); // '0' - - // Test negative byte values (should convert to positive values 128-255) - assertEquals(128, Lzipping.btoi((byte) -128)); - assertEquals(255, Lzipping.btoi((byte) -1)); - } @Test void testFillBinaryString() { diff --git a/src/test/java/prog/lzw/LzwUtilsTest.java b/src/test/java/prog/lzw/LzwUtilsTest.java deleted file mode 100644 index da8f568..0000000 --- a/src/test/java/prog/lzw/LzwUtilsTest.java +++ /dev/null @@ -1,34 +0,0 @@ -package prog.lzw; - -import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.*; - -public class LzwUtilsTest { - - @Test - public void testBtoi() { - // Test positive byte values - assertEquals(0, LzwUtils.btoi((byte) 0)); - assertEquals(65, LzwUtils.btoi((byte) 65)); // 'A' - assertEquals(90, LzwUtils.btoi((byte) 90)); // 'Z' - assertEquals(127, LzwUtils.btoi((byte) 127)); - - // Test negative byte values (should convert to positive values 128-255) - assertEquals(128, LzwUtils.btoi((byte) -128)); - assertEquals(200, LzwUtils.btoi((byte) -56)); - assertEquals(255, LzwUtils.btoi((byte) -1)); - } - - @Test - public void testStoi() { - // Test binary string to integer conversion - assertEquals(0, LzwUtils.stoi("0")); - assertEquals(1, LzwUtils.stoi("1")); - assertEquals(2, LzwUtils.stoi("10")); - assertEquals(3, LzwUtils.stoi("11")); - assertEquals(10, LzwUtils.stoi("1010")); - assertEquals(15, LzwUtils.stoi("1111")); - assertEquals(255, LzwUtils.stoi("11111111")); - assertEquals(1023, LzwUtils.stoi("1111111111")); - } -} \ No newline at end of file diff --git a/src/test/java/prog/util/CommonUtilTest.java b/src/test/java/prog/util/CommonUtilTest.java new file mode 100644 index 0000000..2e193dd --- /dev/null +++ b/src/test/java/prog/util/CommonUtilTest.java @@ -0,0 +1,61 @@ +package prog.util; + +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + +/** + * Comprehensive unit tests for the CommonUtil class. + * Tests both the new method names and deprecated methods for backward compatibility. + */ +public class CommonUtilTest { + + @Test + void testByteToUnsignedIntConversion() { + // Test edge cases + assertEquals(0, CommonUtil.byteToUnsignedInt((byte) 0), "Zero byte should convert to 0"); + assertEquals(127, CommonUtil.byteToUnsignedInt((byte) 127), "Max positive byte should convert to 127"); + + // Test common ASCII values + assertEquals(65, CommonUtil.byteToUnsignedInt((byte) 65), "ASCII 'A' should convert to 65"); + assertEquals(90, CommonUtil.byteToUnsignedInt((byte) 90), "ASCII 'Z' should convert to 90"); + assertEquals(48, CommonUtil.byteToUnsignedInt((byte) 48), "ASCII '0' should convert to 48"); + + // Test negative byte values (should convert to positive values 128-255) + assertEquals(128, CommonUtil.byteToUnsignedInt((byte) -128), "Min byte should convert to 128"); + assertEquals(200, CommonUtil.byteToUnsignedInt((byte) -56), "Negative byte -56 should convert to 200"); + assertEquals(255, CommonUtil.byteToUnsignedInt((byte) -1), "-1 byte should convert to 255"); + } + + @Test + void testBinaryStringToIntConversion() { + // Test single bit values + assertEquals(0, CommonUtil.binaryStringToInt("0"), "Binary '0' should convert to 0"); + assertEquals(1, CommonUtil.binaryStringToInt("1"), "Binary '1' should convert to 1"); + + // Test multi-bit values + assertEquals(2, CommonUtil.binaryStringToInt("10"), "Binary '10' should convert to 2"); + assertEquals(3, CommonUtil.binaryStringToInt("11"), "Binary '11' should convert to 3"); + assertEquals(10, CommonUtil.binaryStringToInt("1010"), "Binary '1010' should convert to 10"); + assertEquals(15, CommonUtil.binaryStringToInt("1111"), "Binary '1111' should convert to 15"); + + // Test byte boundary values + assertEquals(255, CommonUtil.binaryStringToInt("11111111"), "8 bits all ones should convert to 255"); + assertEquals(1023, CommonUtil.binaryStringToInt("1111111111"), "10 bits all ones should convert to 1023"); + + // Test with leading zeros + assertEquals(10, CommonUtil.binaryStringToInt("00001010"), "Binary with leading zeros should work correctly"); + } + + @Test + void testBinaryStringToIntWithInvalidInput() { + // Test invalid characters + assertThrows(IllegalArgumentException.class, + () -> CommonUtil.binaryStringToInt("10201"), + "Should throw exception for non-binary character '2'"); + + assertThrows(IllegalArgumentException.class, + () -> CommonUtil.binaryStringToInt("abc"), + "Should throw exception for non-binary characters"); + } + +} \ No newline at end of file