10     if (node == 
nullptr) 
return;
 
   63     infile.open(infilePath, std::ios::in | std::ios::binary);
 
   65         throw std::runtime_error(
"Input Error : \'" + infilePath.string() + 
"\' couldn't be opened");
 
   86     outfile.write(
reinterpret_cast<char*
>(&fileCount), 
sizeof(fileCount));
 
   89     std::string file_path;
 
   91         unsigned int fileSize = fs::file_size(file);
 
   92         outfile.write(
reinterpret_cast<char*
>(&fileSize), 
sizeof(fileSize));
 
   94         if (fs::is_directory(inputName))
 
   95             file_path = fs::relative(file, inputName).string();
 
   97             file_path = file.filename().string();
 
   99         outfile.write(file_path.c_str(), file_path.size());
 
  105     infile.open(infileName, std::ios::in | std::ios::binary);
 
  107         throw std::runtime_error(
"[compressFiles] one or more files in the directory cant be opened");
 
  112             chr = (chr << 1) ^ (binCode - 
'0');
 
  114             if (bufferSize == 0) {
 
  115                 outfile.write(
reinterpret_cast<char*
>(&chr), 
sizeof(chr));
 
  125     fs::path outfilePath = fs::canonical(inputName).replace_extension(
".huf");
 
  126     if (fs::path(inputName) == outfilePath) {
 
  127         outfilePath.replace_filename(outfilePath.stem().string() + 
"_1.huf");
 
  129     std::ofstream outfile(outfilePath, std::ios::out | std::ios::binary | std::ios::trunc);
 
  131         throw std::runtime_error(
"Output Error : compressed file couldn't be created");
 
  138         writeBody(chr, bufferSize, file.string(), outfile);
 
  142         chr = chr << bufferSize; 
 
  143         outfile.write(
reinterpret_cast<char*
>(&chr), 
sizeof(chr));
 
  153     std::cout << 
"Huffman Compression\n";
 
  154     std::cout << std::string(19, 
char(205)) << std::endl;
 
  155     std::cout << 
inputFiles.size() << 
" file(s) detected\n";
 
  160         int fileNameWidth = file.filename().string().length() + 3;
 
  161         if (fileNameWidth > fieldWidth)
 
  162             fieldWidth = fileNameWidth;
 
  163         totalSize += fs::file_size(file);
 
  167         std::cout << 
"Filename : "<<std::setw(fieldWidth) << std::left << file.filename() << 
" | size: " << fs::file_size(file) << 
" bytes"<< std::endl;
 
  170     std::cout << 
"\nCompressing ..." << std::endl;
 
  171     auto start = std::chrono::steady_clock::now();
 
  173     std::cout << 
"Reading frequency ..." << std::endl;
 
  178     std::cout << 
"Creating Huffman Tree ..." << std::endl;
 
  181     std::cout << 
"Generating CodeMap ..." << std::endl;
 
  184     std::cout << 
"Encoding to File ..." << std::endl;
 
  187     std::cout << 
"Cleaning Up ..." << std::endl;
 
  190     std::cout << 
"Success: Compression Completed.\n" << std::endl;
 
  191     std::cout << 
"Compressed File Name\n" << outfilePath.filename() << std::endl;
 
  192     std::cout << 
"Compressed File Location\n" << 
"\"" << outfilePath.parent_path().string() << 
"\"\n" << std::endl;
 
  194     auto stop = std::chrono::steady_clock::now();
 
  195     auto duration = std::chrono::duration_cast<std::chrono::duration<double>>(stop - start);
 
  197     int outputSize = fs::file_size(outfilePath);
 
  198     std::cout << std::setw(22) << 
"Total Input Size" << 
" = "<< totalSize << 
" bytes" << std::endl;
 
  199     std::cout << std::setw(22) << 
"Compressed File Size" << 
" = " << outputSize << 
" bytes" << std::endl;
 
  200     std::cout << std::setw(22) << 
"Compression Ratio" << 
" = " << std::setprecision(4) << float(totalSize - outputSize) / totalSize * 100 << 
" % " << std::endl;
 
  201     std::cout << std::setw(22) << 
"Compression Time" << 
" = " << duration.count() << 
" seconds\n" << std::endl;
 
  205     if (!fs::is_regular_file(infileName))
 
  206         throw std::runtime_error(
"ERROR : Please enter a valid file path");
 
  214     if (!fs::is_directory(directoryName))
 
  215         throw std::runtime_error(
"ERROR : Please enter a valid directory path");
 
  217     for (
auto&& entry : fs::recursive_directory_iterator(directoryName)) {
 
  218         if (entry.is_regular_file()) {
 
  227     for (
auto&& infileName : infileNames) {
 
  228         if (fs::is_regular_file(infileName))
 
  231             throw std::runtime_error(
"ERROR : Please enter a valid file path");
 
constexpr auto INTERNAL_NODE_CHARACTER
Constants for Huffman Tree.
constexpr auto FILE_NAME_SEPARATOR
Constants for file Header.
This class models a node structure used for building Huffman Binary Tree.
BinNode * getRightChild() const
void setRightChild(BinNode *)
sets parameter node as left child of the caller node instance.
void setLeftChild(BinNode *)
sets parameter node as left child of the caller node instance.
BinNode * getLeftChild() const
char getCharacter() const
void deleteTree(BinNode *node)
Frees all heap storage associated with the Huffman Tree.
fs::path writeIntoFile(const std::string &infileName)
Write the header and body section to compressed file.
void compressFolder(const std::string &directoryName)
Compresses a directory and its entire content recursively.
BinNode * rootNode
Root node for Huffman tree.
void clear()
Resets all the attributes for next compression operation.
void readFrequency()
Reads entire input file and finds frequency of each unique characters.
HashMap< char, std::string > codeMap
Prefix-free binary code for each value of the source symbol.
void compressFile(const std::string &infileName)
Compresses a single input file.
HashMap< char, int > frequency
Frequency of occurrence for each unique symbol in the source.
void compress(const std::string &infileName)
Utility function to compress file.
BinNode * createHuffmanTree()
Creates a Huffman Tree form unique characters along with their frequency of occurrences.
void compressFiles(std::initializer_list< std::string > infileNames)
Compresses multiple source files into single compressed(.huf) file.
void scanFile(const fs::path &infilePath)
Validates input file path and proceeds on reading frequency.
void writeBody(char &chr, int &bufferSize, const std::string &infileName, std::ofstream &writer)
Write the body section to compressed file.
std::ifstream infile
Instance of ifstream class for reading characters from source.
std::vector< fs::path > inputFiles
List of input files given by the user.
void writeHeader(const std::string &inputName, std::ofstream &writer)
Write the header section to compressed file.
void writeTree(std::ofstream &writer, BinNode *head)
Write the entire Huffman tree in to the file header section using a pre-order traversal algorithm.
void generateHuffmanCode(BinNode *rootNode, std::string codeString)
Generates prefix code for each unique characters in the source.
ValueType get(const KeyType &key) const
void clear()
Removes all entries from this map.
This class models Priority Queue in which values are processed in order of priority.
T dequeue()
Removes and returns the highest priority value.
void enqueue(const T &)
Adds value to the priority queue