}//end BuildEncTree method // // //Decompression #3 //This method traverses the binary tree that was created based off of input from the file. It reads a byte from the file and finds that bytes character encoding. //It then traverses the binary tree based on the encoding (moving left if 1, moving right if 0). If the current node in the tree is a leaf node, it writes the node character value to the output file (decompressed file) and returns to the root. //This method stops when the number of decompressed characters matches the number of characters in the original file (this is found at the top of the encoding table file). static void DecodeFile(BinaryTree <char> encodingTree, string inputFilePath, string outputFilePath, string EncodingTablePath) { try { //determins the number of characters to be decoded. StreamReader encFile = new StreamReader(EncodingTablePath); int encodedCharCount = Convert.ToInt32(encFile.ReadLine()); //The first line in the EncodingTable file is the count of characters to be decoded. encFile.Close(); FileStream inFile = new FileStream(inputFilePath, FileMode.Open); FileStream outFile = new FileStream(outputFilePath, FileMode.Create); //Move to the root encodingTree.Current = encodingTree.Root; byte by = 0; //if input file is not empty if (inFile.Length != 0) { by = Convert.ToByte(inFile.ReadByte()); //convert the first character in the file to a byte } //if input file is empty throw exception else { throw new Exception("File being decompressed is empty."); } int bit; int bitPosition = 7; //Start from the left of the bit int decodedCharCount = 0; //Number of decoded characters //While there are bits to decode while (decodedCharCount < encodedCharCount) { //Check to see if we are still within the limits of the byte (i.e. bit positions 7 - 0) if (bitPosition < 0) { //If not //Read next byte from the file by = Convert.ToByte(inFile.ReadByte()); //Start at the left of the byte bitPosition = 7; } //Check to see if the current bit is on or off bit = by & (int)Math.Pow(2, bitPosition); //if on, returns [value > 0]. if off, returns [0]; //If bit is on (bit > 0) - move left if (bit > 0) { //Move left encodingTree.moveTo(BinaryTree <char> .Relative.leftChild); //If node is a leaf node if (encodingTree.Current.isLeaf()) { //Add the character to the file outFile.WriteByte(Convert.ToByte(encodingTree.Current.Data)); //Move back to the root of the tree encodingTree.moveTo(BinaryTree <char> .Relative.root); //Increase the decoded character count ++decodedCharCount; } } //If bit is off (bit == 0) - move right else if (bit == 0) { //Move right encodingTree.moveTo(BinaryTree <char> .Relative.rightChild); //If node is a leaf node if (encodingTree.Current.isLeaf()) { //Add the character to the file outFile.WriteByte(Convert.ToByte(encodingTree.Current.Data)); //Move back to the root of the tree encodingTree.moveTo(BinaryTree <char> .Relative.root); //Increase the decoded character count ++decodedCharCount; } } //move to the next bit in the byte --bitPosition; } inFile.Close(); outFile.Close(); } catch (Exception e) { Console.WriteLine("Error: file(s) corrupted. Decompression failed."); Console.WriteLine(e.Message); } } //end DecodeFile method
}//end BuildEncTable method // // //Decompression #2 //This method creates the binary tree based on the character encoding. Basically, if the current character in the character encoding is a 1, move left in the tree. If it is a 0, move right in the tree. //If the node doesn't exist, create it. static BinaryTree <char> BuildEncTree(List <CharacterEncoding> encodingTable) { BinaryTree <char> encodingTree = new BinaryTree <char>('\0'); //the new binary tree that will be developed later in this method. //for every CharacterEncoding object in the encoding table foreach (CharacterEncoding charEnc in encodingTable) { //each object being worked with to build the tree has to be instantiated, otherwise it is skipped. if (!(charEnc == null)) { encodingTree.Current = encodingTree.Root; //start at the top of the tree int encLength = charEnc.GetEncoding().Length; //the length of the encoding string //use every encoding character (i.e. string of 1s and 0s) in the current CharacterEncoding object to create the tree. for (int i = 0; i + 1 <= encLength; ++i) //for loop executes for every character in the encoding string { char c = charEnc.GetEncoding()[i]; //the current character in the encoding string. //1 - move left in the tree. if (c == '1') { //if left doesn't exist, create it. if (encodingTree.Current.Left == null) { //If the node should be a root node (i.e. if the end of the character encoding string has been reached) if (i + 1 == encLength) { encodingTree.Insert(charEnc.GetCharacter(), BinaryTree <char> .Relative.leftChild); } //If node shouldn't be a root node else { encodingTree.Insert('\0', BinaryTree <char> .Relative.leftChild); } } //move left encodingTree.moveTo(BinaryTree <char> .Relative.leftChild); } //0 - move right in the tree. else if (c == '0') { //if right doesn't exist, create it. if (encodingTree.Current.Right == null) { //If the node should be a root node (i.e. if the end of the character encoding string has been reached) if (i + 1 == encLength) { encodingTree.Insert(charEnc.GetCharacter(), BinaryTree <char> .Relative.rightChild); } //If node shouldn't be a root node else { encodingTree.Insert('\0', BinaryTree <char> .Relative.rightChild); } } //move right encodingTree.moveTo(BinaryTree <char> .Relative.rightChild); } } //end charEncoding.GetEncoding() for loop } } //end encodingTable foreach loop return(encodingTree); }//end BuildEncTree method