From 6a32ab038a04a46f61d9300497b1d193e749bb0d Mon Sep 17 00:00:00 2001 From: Brandon Rodriguez <brodriguez8774@gmail.com> Date: Thu, 22 Apr 2021 21:41:05 -0400 Subject: [PATCH] Reorganize class logic into separate files and start logging logic --- documents/references.md | 6 + part_1/image.cu | 260 ++++++++++++++++++--- part_1/image.h | 118 ++++++++-- part_1/logging.cu | 70 ++++++ part_1/logging.h | 56 +++++ part_1/main.cu | 376 ++++-------------------------- part_1/makefile | 2 +- part_1/{structs.cu => utility.cu} | 33 ++- part_1/{structs.h => utility.h} | 5 +- 9 files changed, 552 insertions(+), 374 deletions(-) create mode 100644 part_1/logging.cu create mode 100644 part_1/logging.h rename part_1/{structs.cu => utility.cu} (55%) rename part_1/{structs.h => utility.h} (80%) diff --git a/documents/references.md b/documents/references.md index 2090fc0..f0f8b86 100644 --- a/documents/references.md +++ b/documents/references.md @@ -17,6 +17,7 @@ Various references used in project. * Check if path is file or directory - <https://stackoverflow.com/a/43281413> * Get file name from path - <https://stackoverflow.com/a/24386991> * Path value to string - <https://stackoverflow.com/a/45401869> +* Get current directory - <https://stackoverflow.com/a/52522000> #### Folder Management * Check if dir exists - <https://stackoverflow.com/a/18101042> @@ -28,10 +29,15 @@ Various references used in project. #### C++ Strings * What is a C++ string - <https://stackoverflow.com/a/3535904> * String splitting - <https://stackoverflow.com/a/14266139> +* Getting File/LineNum: +** <https://stackoverflow.com/a/42135375> +** <https://stackoverflow.com/a/8884408> #### C++ Classes * General Class Syntax - <https://www.w3schools.com/cpp/cpp_classes.asp> * Structs Vs Classes in C++ - <https://stackoverflow.com/a/36917400> +* Deconstructors - <https://www.geeksforgeeks.org/destructors-c/> +* Splitting into header files - <https://stackoverflow.com/a/9579974> #### Type Casting <https://en.cppreference.com/w/cpp/language/static_cast> diff --git a/part_1/image.cu b/part_1/image.cu index 27d3586..779e780 100644 --- a/part_1/image.cu +++ b/part_1/image.cu @@ -1,28 +1,232 @@ -// /** -// * File for image handling logic. -// */ - - -// // User Import Headers. -// #ifndef user_headers -// #define user_headers -// #include "image.h" -// #endif - - -// // Global Variables. -// class Image { - -// public: -// /** -// * Base constructor. -// */ -// Image() { -// // printf("Constructing Image class."); -// std::cout << "Constructing Image class." << std::endl; -// } - -// void test_method() { -// std::cout << "test_method() aaaa" << std::endl; -// } -// }; +/** + * File for image handling logic. + */ + + +// User Import Headers. +#ifndef user_headers + #define user_headers + #include "image.h" + #include "utility.h" +#endif + + +// Global Variables. +const Image::Rgb Image::pixelBlack = Image::Rgb(0); +const Image::Rgb Image::pixelWhite = Image::Rgb(1); +const Image::Rgb Image::pixelRed = Image::Rgb(1,0,0); +const Image::Rgb Image::pixelGreen = Image::Rgb(0,1,0); +const Image::Rgb Image::pixelBlue = Image::Rgb(0,0,1); +const Image::Rgb Image::pixelYellow = Image::Rgb(1,1,0); +const Image::Rgb Image::pixelPink = Image::Rgb(1,0,1); +const Image::Rgb Image::pixelLiBlue = Image::Rgb(0,1,1); + + +/** + * Calculates class input_path and output_path values. + * + * :param image_path: Path to an image on the system. + */ +void Image::calculate_paths(std::string image_path) { + // std::cout << "\n\n\n\n\nCalculating input/output paths..." << std::endl; + // std::cout << "image_path: " << image_path << std::endl; + + // // Calculate output path location. + output_path = "../output/"; + std::string base_filename = image_path.substr(image_path.find_last_of("/\\") + 1); + + // Grab directory substrings and generate full output path. + size_t pos = 0; + std::string token; + while ((pos = image_path.find("/")) != std::string::npos) { + + // Pull current substring value from input path. + token = image_path.substr(0, image_path.find("/")); + // std::cout << " " << token << std::endl; + image_path.erase(0, pos + 1); + + // Check if directory value is value we care about. + if ( (token != ".") && (token != "..") && (token != "input") ) { + output_path += token + "/"; + } + + // Check if directory exists. + struct stat info; + if ( (stat(output_path.c_str(), &info) != 0) || (! info.st_mode & S_IFDIR)) { + // Directory does not exist. + mkdir(output_path.c_str(), 0777); + } + + } + + output_path += base_filename; + // std::cout << "output_path: " << output_path << std::endl; + + // std::cout << "Input/output paths calculated.\n\n\n\n\n" << std::endl; +} + + +/** + * Imports image file data, using class variable data. + */ +void Image::import_image_file() { + // Open input file. + std::ifstream input_file; + input_file.open(input_path, std::ios::binary | std::ios::in); + + if (! input_file.good()) { + // Failed to open file. + std::cerr << "Failed to open file \"" + input_path + "\"." << std::endl; + } else { + // File opened. Grab data. + std::string header; + input_file >> header; + if (strcmp(header.c_str(), "P6") != 0) { + throw("Can't read input file"); + } + + // Save image values to class. + input_file >> width >> height >> bit_depth; + + // Create and populate image. + // std::cout << "Parsing input image" << std::endl; + pixel_arr = new Rgb[width * height]; + + // Skip empty lines in necessary until we get to the binary data. + input_file.ignore(256, '\n'); + + // Read each pixel one by one and convert bytes to floats. + unsigned char pix[3]; + for (int index = 0; index < width * height; ++index) { + input_file.read(reinterpret_cast<char *>(pix), 3); + pixel_arr[index].r = pix[0] / 255.f; + pixel_arr[index].g = pix[1] / 255.f; + pixel_arr[index].b = pix[2] / 255.f; + } + } + + input_file.close(); +} + + + +//region Constructors. + +/** + * Base constructor. + */ +Image::Image() { + // Currently test logic. + std::cout << "\nConstructing Image class." << std::endl; + + // Essentially creates a 10x10 pixel test image. + input_path = "../input/pbm/400x300/hallway_00.pbm"; + output_path = "../output/test_00.pbm"; + width = 10; + height = 10; + bit_depth = 255; + Rgb c = pixelBlack; // Default color. Can select based on below preset colors. + + // Create and populate image. + pixel_arr = new Rgb[width * height]; + for (int index = 0; index < (width * height); index++) { + pixel_arr[index] = c; + } + + std::cout << "Image class populated." << std::endl; +} + +/** + * Constructor that takes input path to image file. + * Output path is determined based on parsing input path. + */ +Image::Image(std::string user_path) { + std::cout << "\nConstructing Image class." << std::endl; + + std::cout << "user_path: " << user_path << std::endl; + + // Re-validate path for saving to class.. + path_validator_struct* return_struct = validate_path(user_path); + int path_type = return_struct->file_type; + if (return_struct->err_code) { + std::cerr << "Error verifying file type: " << return_struct->err_code.message() << std::endl; + return; + } + free_path_validator_struct(return_struct); + if (path_type == TYPE_FILE) { + input_path = user_path; + calculate_paths(user_path); + import_image_file(); + } else { + std::cerr << "Provided path is not to image file. Class initialization failed." << std::endl; + return; + } + + std::cout << "Image class populated." << std::endl; +} + +//endregion Constructors. + + +//region Public Methods. + +/** + * Displays general properties of image held in class. + */ +void Image::display_properties() { + std::cout << std::endl; + std::cout << "input file path: " << input_path << std::endl; + std::cout << "output file path: " << output_path << std::endl; + std::cout << "width: " << width << std::endl; + std::cout << "height: " << height << std::endl; + std::cout << "bit depth: " << bit_depth << std::endl; + std::cout << std::endl; +} + + +/** + * Saves class image data to output file. + */ +void Image::save() { + std::cout << "Attempting to save image to \"" << output_path << "\"." << std::endl; + + // Open output file stream. + std::ofstream output_file; + + // Attempt to save file data. + try { + // Attempt to open file. + output_file.open(output_path, std::ios::binary | std::ios::out); + + // Check if opened successfully. + if (output_file.fail()) { + // Failed to open. + std::cout << "Failed to open file \"" + output_path + "\".\n"; + } else { + // Opened successfully. + + // Write image "header" data. + output_file << "P6\n" << width << " " << height << "\n255\n"; + + // Write image pixel data. + unsigned char r, g, b; + for (int index = 0; index < (width * height); index++) { + r = static_cast<float>(std::min(1.f, pixel_arr[index].r) * 255); + g = static_cast<float>(std::min(1.f, pixel_arr[index].g) * 255); + b = static_cast<float>(std::min(1.f, pixel_arr[index].b) * 255); + output_file << r << g << b; + } + + } + + // Close file stream. + output_file.close(); + std::cout << "Image saved." << std::endl; + + } catch (const char* err) { + fprintf(stderr, "%s\n", err); + output_file.close(); + } +} + +//endregion Public Methods. diff --git a/part_1/image.h b/part_1/image.h index 6bf20f8..e5ceadc 100644 --- a/part_1/image.h +++ b/part_1/image.h @@ -1,21 +1,107 @@ -// /** -// * Header file for project image handling logic. -// */ +/** + * Header file for project image handling logic. + */ -// // System Import Headers. -// #include <cstdio> -// #include <cstdlib> -// #include <cctype> -// #include <iostream> -// #include <fstream> -// #include <string> +// System Import Headers. +#include <cstdio> +#include <cstdlib> +#include <cctype> +#include <filesystem> +#include <fstream> +#include <iostream> +#include <iterator> +#include <string> +#include <sys/stat.h> +#include <sys/types.h> -// // Global Variables. -// class Image { +/** + * Class that holds data for a single image. + */ +class Image { -// public: -// Image() {} -// void test_method() {} -// }; + private: + /** + * Struct to act as a "container" of sorts for each individual rgb pixel. + * An array of these creates our entire image. + * + * According to https://stackoverflow.com/a/36917400, this is basically treated as a sub-class. + * This allows creating multiple constructors, which will handle different scenarios of pixel input. + */ + struct Rgb { + // Struct variables. + float r, g, b; + + /** + * Struct constructors. + * + * First one acts as a "default" that provides black pixels. + * When a single float is provided, the second constructor sets all three rgb channels to that value. + * Finally, when three floats are provided, the last constructor sets rgb channels accordingly. + */ + Rgb(): r(0), g(0), b(0) {} + Rgb(float c): r(c), g(c), b(c) {} + Rgb(float _r, float _g, float _b) : r(_r), g(_g), b(_b) {} + + }; + + // Private Variables. + std::string input_path; + std::string output_path; + unsigned int width; + unsigned int height; + int bit_depth; + Rgb *pixel_arr; // Array of pixel data. + + /** + * Calculates class input_path and output_path values. + * + * :param image_path: Path to an image on the system. + */ + void calculate_paths(std::string image_path); + + + /** + * Imports image file data, using class variable data. + */ + void import_image_file(); + + + public: + // Public Variables. + static const Rgb pixelBlack, pixelWhite, pixelRed, pixelGreen, pixelBlue, pixelYellow, pixelPink, pixelLiBlue; + + + //region Constructors. + + /** + * Base constructor. + */ + Image(); + + /** + * Constructor that takes input path to image file. + * Output path is determined based on parsing input path. + */ + Image(std::string user_path); + + //endregion Constructors. + + + //region Public Methods. + + /** + * Displays general properties of image held in class. + */ + void display_properties(); + + + /** + * Saves class image data to output file. + */ + void save(); + + //endregion Public Methods. + +}; diff --git a/part_1/logging.cu b/part_1/logging.cu new file mode 100644 index 0000000..74ce6a0 --- /dev/null +++ b/part_1/logging.cu @@ -0,0 +1,70 @@ +/** + * File for project logging. + * Contains actual logic for class defined in logging.h. + */ + + +// User Import Headers. +#ifndef user_headers + #define user_headers + #include "logging.h" +#endif + + +/** + * Class constructor. + */ +Logging::Logging() { + std::cout << "Initializing logger." << std::endl; + std::filesystem::path cwd = std::filesystem::current_path(); + core_logging_folder = cwd.string() + "/log/"; + std::cout << "logging_folder: " << core_logging_folder << std::endl; + + // Open file descriptors. + error_stream.open(core_logging_folder + "error.log", std::ios::binary | std::ios::out); + warn_stream.open(core_logging_folder + "warn.log", std::ios::binary | std::ios::out); + info_stream.open(core_logging_folder + "info.log", std::ios::binary | std::ios::out); +} + +/** + * Class deconstructor. + * Closes file descriptors, if open. + */ +Logging::~Logging() { + if (info_stream.is_open()) { + info_stream.close(); + } + if (warn_stream.is_open()) { + warn_stream.close(); + } + if (error_stream.is_open()) { + error_stream.close(); + } +} + +/** + * Writes message to info log file. + */ +void Logging::info(char const* file, long line_num, std::string msg) { + info_stream << msg << std::endl; +} + +/** + * Writes message to warning log file. + */ +void Logging::warn(char const* file, long line_num, std::string msg) { + warn_stream << msg << std::endl; + + // Also write to lower level loggers. + info(file, line_num, msg); +} + +/** + * Writes message to error log file. + */ +void Logging::error(char const* file, long line_num, std::string msg) { + error_stream << msg << std::endl; + + // Also write to lower level loggers. + warn(file, line_num, msg); +} diff --git a/part_1/logging.h b/part_1/logging.h new file mode 100644 index 0000000..b217519 --- /dev/null +++ b/part_1/logging.h @@ -0,0 +1,56 @@ +/** + * Header file for project logging. + */ + + +// System Import Headers. +#include <cstdio> +#include <cstdlib> +#include <cctype> +#include <iostream> +#include <filesystem> +#include <fstream> +#include <string> +#include <sys/stat.h> +#include <sys/types.h> + + +/** + * Logging class definition. + */ +class Logging { + + private: + std::string core_logging_folder; + std::ofstream info_stream; + std::ofstream warn_stream; + std::ofstream error_stream; + + public: + /** + * Class constructor. + */ + Logging(); + + /** + * Class deconstructor. + * Closes file descriptors, if open. + */ + ~Logging(); + + /** + * Writes message to info log file. + */ + void info(char const* file, long line_num, std::string msg); + + /** + * Writes message to warning log file. + */ + void warn(char const* file, long line_num, std::string msg); + + /** + * Writes message to error log file. + */ + void error(char const* file, long line_num, std::string msg); +}; + diff --git a/part_1/main.cu b/part_1/main.cu index 5889de2..d7950db 100644 --- a/part_1/main.cu +++ b/part_1/main.cu @@ -12,20 +12,18 @@ #include <iostream> #include <iterator> #include <string> -#include <sys/stat.h> -#include <sys/types.h> #include <vector> // User Import Headers. #ifndef user_headers #define user_headers - #include "structs.h" + #include "logging.h" #include "image.h" + #include "utility.h" #endif // Method Declaration. -path_validator_struct* validate_path(std::string path_str); void process_dir(std::string path_str); void process_file(std::string path_str); // void validate_path(char* path_str); @@ -35,270 +33,6 @@ void process_file(std::string path_str); // Global Variables. -/** - * Class that holds data for a single image. - */ -class Image { - - private: - /** - * Struct to act as a "container" of sorts for each individual rgb pixel. - * An array of these creates our entire image. - * - * According to https://stackoverflow.com/a/36917400, this is basically treated as a sub-class. - * This allows creating multiple constructors, which will handle different scenarios of pixel input. - */ - struct Rgb { - // Struct variables. - float r, g, b; - - /** - * Struct constructors. - * - * First one acts as a "default" that provides black pixels. - * When a single float is provided, the second constructor sets all three rgb channels to that value. - * Finally, when three floats are provided, the last constructor sets rgb channels accordingly. - */ - Rgb(): r(0), g(0), b(0) {} - Rgb(float c): r(c), g(c), b(c) {} - Rgb(float _r, float _g, float _b) : r(_r), g(_g), b(_b) {} - - }; - - // Private Variables. - std::string input_path; - std::string output_path; - unsigned int width; - unsigned int height; - int bit_depth; - Rgb *pixel_arr; // Array of pixel data. - - /** - * Calculates class input_path and output_path values. - * - * :param image_path: Path to an image on the system. - */ - void calculate_paths(std::string image_path) { - // std::cout << "\n\n\n\n\nCalculating input/output paths..." << std::endl; - // std::cout << "image_path: " << image_path << std::endl; - - // // Calculate output path location. - output_path = "../output/"; - std::string base_filename = image_path.substr(image_path.find_last_of("/\\") + 1); - - // Grab directory substrings and generate full output path. - size_t pos = 0; - std::string token; - while ((pos = image_path.find("/")) != std::string::npos) { - - // Pull current substring value from input path. - token = image_path.substr(0, image_path.find("/")); - // std::cout << " " << token << std::endl; - image_path.erase(0, pos + 1); - - // Check if directory value is value we care about. - if ( (token != ".") && (token != "..") && (token != "input") ) { - output_path += token + "/"; - } - - // Check if directory exists. - struct stat info; - if ( (stat(output_path.c_str(), &info) != 0) || (! info.st_mode & S_IFDIR)) { - // Directory does not exist. - mkdir(output_path.c_str(), 0777); - } - - } - - output_path += base_filename; - // std::cout << "output_path: " << output_path << std::endl; - - // std::cout << "Input/output paths calculated.\n\n\n\n\n" << std::endl; - } - - - /** - * Imports image file data, using class variable data. - */ - void import_image_file() { - // Open input file. - std::ifstream input_file; - input_file.open(input_path, std::ios::binary | std::ios::in); - - if (! input_file.good()) { - // Failed to open file. - std::cerr << "Failed to open file \"" + input_path + "\"." << std::endl; - } else { - // File opened. Grab data. - std::string header; - input_file >> header; - if (strcmp(header.c_str(), "P6") != 0) { - throw("Can't read input file"); - } - - // Save image values to class. - input_file >> width >> height >> bit_depth; - - // Create and populate image. - // std::cout << "Parsing input image" << std::endl; - pixel_arr = new Rgb[width * height]; - - // Skip empty lines in necessary until we get to the binary data. - input_file.ignore(256, '\n'); - - // Read each pixel one by one and convert bytes to floats. - unsigned char pix[3]; - for (int index = 0; index < width * height; ++index) { - input_file.read(reinterpret_cast<char *>(pix), 3); - pixel_arr[index].r = pix[0] / 255.f; - pixel_arr[index].g = pix[1] / 255.f; - pixel_arr[index].b = pix[2] / 255.f; - } - } - - input_file.close(); - } - - - public: - // Public Variables. - static const Rgb pixelBlack, pixelWhite, pixelRed, pixelGreen, pixelBlue, pixelYellow, pixelPink, pixelLiBlue; - - - //region Constructors. - - /** - * Base constructor. - */ - Image() { - // Currently test logic. - std::cout << "\nConstructing Image class." << std::endl; - - // Essentially creates a 10x10 pixel test image. - input_path = "../input/pbm/400x300/hallway_00.pbm"; - output_path = "../output/test_00.pbm"; - width = 10; - height = 10; - bit_depth = 255; - Rgb c = pixelBlack; // Default color. Can select based on below preset colors. - - // Create and populate image. - pixel_arr = new Rgb[width * height]; - for (int index = 0; index < (width * height); index++) { - pixel_arr[index] = c; - } - - std::cout << "Image class populated." << std::endl; - } - - /** - * Constructor that takes input path to image file. - * Output path is determined based on parsing input path. - */ - Image(std::string user_path) { - std::cout << "\nConstructing Image class." << std::endl; - - std::cout << "user_path: " << user_path << std::endl; - - // Re-validate path for saving to class.. - path_validator_struct* return_struct = validate_path(user_path); - int path_type = return_struct->file_type; - if (return_struct->err_code) { - std::cerr << "Error verifying file type: " << return_struct->err_code.message() << std::endl; - return; - } - free_path_validator_struct(return_struct); - if (path_type == TYPE_FILE) { - input_path = user_path; - calculate_paths(user_path); - import_image_file(); - } else { - std::cerr << "Provided path is not to image file. Class initialization failed." << std::endl; - return; - } - - std::cout << "Image class populated." << std::endl; - } - - //endregion Constructors. - - - //region Public Methods. - - /** - * Displays general properties of image held in class. - */ - void display_properties() { - std::cout << std::endl; - std::cout << "input file path: " << input_path << std::endl; - std::cout << "output file path: " << output_path << std::endl; - std::cout << "width: " << width << std::endl; - std::cout << "height: " << height << std::endl; - std::cout << "bit depth: " << bit_depth << std::endl; - std::cout << std::endl; - } - - - /** - * Saves class image data to output file. - */ - void save() { - std::cout << "Attempting to save image to \"" << output_path << "\"." << std::endl; - - // Open output file stream. - std::ofstream output_file; - - // Attempt to save file data. - try { - // Attempt to open file. - output_file.open(output_path, std::ios::binary | std::ios::out); - - // Check if opened successfully. - if (output_file.fail()) { - // Failed to open. - std::cout << "Failed to open file \"" + output_path + "\".\n"; - } else { - // Opened successfully. - - // Write image "header" data. - output_file << "P6\n" << width << " " << height << "\n255\n"; - - // Write image pixel data. - unsigned char r, g, b; - for (int index = 0; index < (width * height); index++) { - r = static_cast<float>(std::min(1.f, pixel_arr[index].r) * 255); - g = static_cast<float>(std::min(1.f, pixel_arr[index].g) * 255); - b = static_cast<float>(std::min(1.f, pixel_arr[index].b) * 255); - output_file << r << g << b; - } - - } - - // Close file stream. - output_file.close(); - std::cout << "Image saved." << std::endl; - - } catch (const char* err) { - fprintf(stderr, "%s\n", err); - output_file.close(); - } - } - - //endregion Public Methods. - -}; - - -// Preset single colors. Mostly for testing purposes. -const Image::Rgb Image::pixelBlack = Image::Rgb(0); -const Image::Rgb Image::pixelWhite = Image::Rgb(1); -const Image::Rgb Image::pixelRed = Image::Rgb(1,0,0); -const Image::Rgb Image::pixelGreen = Image::Rgb(0,1,0); -const Image::Rgb Image::pixelBlue = Image::Rgb(0,0,1); -const Image::Rgb Image::pixelYellow = Image::Rgb(1,1,0); -const Image::Rgb Image::pixelPink = Image::Rgb(1,0,1); -const Image::Rgb Image::pixelLiBlue = Image::Rgb(0,1,1); - /* * Program's main. Initializes and runs program. @@ -308,34 +42,36 @@ int main(int argc, char* argv[]) { printf("\n"); printf("\n"); - // Check provided number of args. - if (argc < 2) { - // No args provided. - printf("Provided too few program args. Expected one arg."); - } else if (argc > 2) { - // More than one arg provided. - printf("Provided too many program args. Expected one arg."); - } else { - // Correct number of args provided. Pass to image class for processing. - - // Check data type. - std::string path_str = argv[1]; - path_validator_struct* return_struct = validate_path(path_str); - int path_type = return_struct->file_type; - if (return_struct->err_code) { - std::cerr << "Error verifying file type: " << return_struct->err_code.message() << std::endl; - } - free_path_validator_struct(return_struct); - - // Handle based on provided type. - if (path_type == TYPE_DIR) { - // Process dir. - process_dir(path_str); - } else if (path_type == TYPE_FILE) { - // Process file. - process_file(path_str); - } - } + Logging logger; + + // // Check provided number of args. + // if (argc < 2) { + // // No args provided. + // printf("Provided too few program args. Expected one arg."); + // } else if (argc > 2) { + // // More than one arg provided. + // printf("Provided too many program args. Expected one arg."); + // } else { + // // Correct number of args provided. Pass to image class for processing. + + // // Check data type. + // std::string path_str = argv[1]; + // path_validator_struct* return_struct = validate_path(path_str); + // int path_type = return_struct->file_type; + // if (return_struct->err_code) { + // std::cerr << "Error verifying file type: " << return_struct->err_code.message() << std::endl; + // } + // free_path_validator_struct(return_struct); + + // // Handle based on provided type. + // if (path_type == TYPE_DIR) { + // // Process dir. + // process_dir(path_str); + // } else if (path_type == TYPE_FILE) { + // // Process file. + // process_file(path_str); + // } + // } printf("\n"); printf("\n"); @@ -344,40 +80,12 @@ int main(int argc, char* argv[]) { } -/** - * Validates provided path and if valid, determines path type. - * Returns struct of data. - */ -path_validator_struct* validate_path(std::string path_str) { - int type_value = TYPE_OTHER; - std::error_code ec; - - std::cout << "path_str: \"" + path_str + "\"\n"; - - // Check if provided path exists. - std::ifstream test_path_exists(path_str); - if (test_path_exists) { - // Path exists. Check if dir or file. - if (std::filesystem::is_directory(path_str, ec)) { - // Is dir. - type_value = TYPE_DIR; - } else if ((! ec) && (std::filesystem::is_regular_file(path_str, ec))) { - // Is file. - type_value = TYPE_FILE; - } - } - - // Return values. - path_validator_struct* return_struct_ptr = initialize_path_validator_struct(type_value, ec); - return return_struct_ptr; -} - - /** * Finds and processes all files in directory. * Assumes directory is full of image files. */ void process_dir(std::string path_str) { + std::cout << "Handling dir." << std::endl; // Process all files in directory. for (const auto & entry : std::filesystem::directory_iterator(path_str)) { @@ -385,6 +93,23 @@ void process_dir(std::string path_str) { std::string file_path_str{entry.path().u8string()}; // std::cout << file_path_str << std::endl; + // Check if new path value is directory or file. + path_validator_struct* return_struct = validate_path(file_path_str); + int path_type = return_struct->file_type; + if (return_struct->err_code) { + std::cerr << "Error verifying file type: " << return_struct->err_code.message() << std::endl; + } + free_path_validator_struct(return_struct); + + // Handle based on provided type. + if (path_type == TYPE_DIR) { + // Process dir. + process_dir(file_path_str); + } else if (path_type == TYPE_FILE) { + // Process file. + process_file(file_path_str); + } + // Send individual file path for processing. process_file(entry.path()); } @@ -395,6 +120,7 @@ void process_dir(std::string path_str) { * Processes a single image file. */ void process_file(std::string path_str) { + std::cout << "Handling file." << std::endl; Image image(path_str); image.display_properties(); diff --git a/part_1/makefile b/part_1/makefile index 1ece90e..7540236 100644 --- a/part_1/makefile +++ b/part_1/makefile @@ -10,7 +10,7 @@ CC = nvcc CFLAGS = -std=c++17 TARGET = main.out LIBRARIES = -DEPENDENCIES = ./main.cu ./structs.cu ./image.cu +DEPENDENCIES = ./main.cu ./image.cu ./logging.cu ./utility.cu # ARGS = `arg="$(filter-out $@,$(MAKECMDGOALS))" && echo $${arg:-${1}}` ARGS = $(filter-out $@,$(MAKECMDGOALS)) diff --git a/part_1/structs.cu b/part_1/utility.cu similarity index 55% rename from part_1/structs.cu rename to part_1/utility.cu index 95da97e..ec66384 100644 --- a/part_1/structs.cu +++ b/part_1/utility.cu @@ -1,12 +1,11 @@ /** - * File for struct logic. + * File for utility logic. */ - // User Import Headers. #ifndef user_headers #define user_headers - #include "structs.h" + #include "utility.h" #endif @@ -50,3 +49,31 @@ void free_path_validator_struct(path_validator_struct* path_validator_ptr) { free(path_validator_ptr); } + +/** + * Validates provided path and if valid, determines path type. + * Returns struct of data. + */ +path_validator_struct* validate_path(std::string path_str) { + int type_value = TYPE_OTHER; + std::error_code ec; + + std::cout << "path_str: \"" + path_str + "\"\n"; + + // Check if provided path exists. + std::ifstream test_path_exists(path_str); + if (test_path_exists) { + // Path exists. Check if dir or file. + if (std::filesystem::is_directory(path_str, ec)) { + // Is dir. + type_value = TYPE_DIR; + } else if ((! ec) && (std::filesystem::is_regular_file(path_str, ec))) { + // Is file. + type_value = TYPE_FILE; + } + } + + // Return values. + path_validator_struct* return_struct_ptr = initialize_path_validator_struct(type_value, ec); + return return_struct_ptr; +} diff --git a/part_1/structs.h b/part_1/utility.h similarity index 80% rename from part_1/structs.h rename to part_1/utility.h index e0b239d..d20726d 100644 --- a/part_1/structs.h +++ b/part_1/utility.h @@ -1,5 +1,5 @@ /** - * Header file for project struct logic. + * Header file for project utility logic. */ @@ -7,6 +7,8 @@ #include <cstdio> #include <cstdlib> #include <cctype> +#include <filesystem> +#include <fstream> #include <iostream> #include <string> @@ -29,3 +31,4 @@ typedef struct { // // Function Prototypes. path_validator_struct* initialize_path_validator_struct(int file_type, std::error_code err_code); void free_path_validator_struct(path_validator_struct* path_validator_ptr); +path_validator_struct* validate_path(std::string path_str); -- GitLab