Repository navigation
Expand file tree
/
Copy pathFileDecoder.java
More file actions
116 lines (103 loc) · 4.91 KB
/
Copy pathFileDecoder.java
File metadata and controls
116 lines (103 loc) · 4.91 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import java.util.ArrayDeque;
class FileDecoder {
private final String fileToDecode = "encodeMe.kht";
private final String outputFileName;
private final FileHandling inputFileHandler;
private final FileHandling outputFileHandler;
private final HuffmanTree huffmanTree;
FileDecoder() {
this.outputFileName = fileToDecode.split("\\.")[0] +"_decoded.txt";
this.inputFileHandler = new FileHandling(Type.DECODING);
this.outputFileHandler = new FileHandling(Type.NORMAL);
this.huffmanTree = new HuffmanTree(Direction.DECODING);
}
boolean init() {
// Check the input inputFile is valid
if (!this.inputFileHandler.isFileValid(this.fileToDecode)) {
System.out.println("There is a problem with "+this.fileToDecode);
return false;
}
// Do the footwork to read the inputFile
if (!this.inputFileHandler.createFileReaders()) {
System.out.println("There is a problem with "+this.fileToDecode);
return false;
}
// Prepare to output the decompressed data
if (!this.outputFileHandler.prepareOutput(this.outputFileName)) {
System.out.println("There is a problem with "+this.outputFileName);
return false;
}
// Start decompressing the inputFile
startDecompression();
System.out.println("File decompressed -->> "+this.outputFileName);
return true;
}
private void startDecompression() {
// Printing the tree
this.huffmanTree.printTree();
ArrayDeque<Integer> decodingBuffer = new ArrayDeque<>(); // Using an ArrayDeque because it is fast
boolean reachedEndOfEncodedFile = false;
boolean gotEof = false;
// Loop until we reach the end of the file
while (!gotEof) {
// If not at end of encoded file
if (!reachedEndOfEncodedFile) {
// Ensure we have 10 bits available in the buffer
while (decodingBuffer.size() <= 10) {
// Get the next byte
String nextByteAsString = this.inputFileHandler.getNextCharacter();
// If the byte equals -1, the end, then break
if (nextByteAsString.equals("-1")) {
reachedEndOfEncodedFile = true;
break;
}
// Add the next byte to the buffer as individual bits
for (int i=0; i<nextByteAsString.length(); i++) {
char charOfByte = nextByteAsString.charAt(i);
int charOfByteAsInt = Integer.parseInt(charOfByte+"");
decodingBuffer.add(charOfByteAsInt);
}
}
}
// If there are bits available
if (decodingBuffer.size() > 0) {
// Give the bit to the Huffman tree so that it can traverse the tree correctly
this.huffmanTree.takeNextBit(decodingBuffer.poll());
// If we got a character from the tree
if (this.huffmanTree.isCharacterMatchFound()) {
// Get the character
char currentCharacter = this.huffmanTree.getCurrentCharacter();
// Write the character
this.outputFileHandler.writeToFile(""+currentCharacter);
Kl.ms();
// Update the tree
this.huffmanTree.addCharAndGetCode((int) currentCharacter);
this.huffmanTree.printTree();
} else if (this.huffmanTree.didGetDag()) {
// If got dagger we need to get the next 8 bits from the buffer
StringBuilder asciiString = new StringBuilder();
for (int i=0; i<8; i++)
if (decodingBuffer.size() > 0)
asciiString.append(decodingBuffer.poll());
Kl.p(asciiString.toString());
// Convert the binary to an ascii character
int asciiStringToBase10Int = Integer.parseInt(asciiString.toString(), 2);
char theCharacter = (char) asciiStringToBase10Int;
this.outputFileHandler.writeToFile(""+theCharacter);
Kl.p("(\""+theCharacter+"\")");
Kl.ms();
// Update the tree
this.huffmanTree.addCharAndGetCode(asciiStringToBase10Int);
this.huffmanTree.printTree();
} else if (this.huffmanTree.didGetEof()) {
// If we reached the end of the file, set a flag so the loop stops
gotEof = true;
}
} else {
// If the buffer is empty stop
break;
}
}
this.outputFileHandler.closeOutputWriter(); // Close the writer
}
}