Skip to content
This repository has been archived by the owner on Nov 10, 2023. It is now read-only.

Commit

Permalink
General Optimizations & Better memory management
Browse files Browse the repository at this point in the history
  • Loading branch information
FreddieCrew authored Sep 15, 2023
1 parent 9635376 commit 18155c0
Showing 1 changed file with 63 additions and 81 deletions.
144 changes: 63 additions & 81 deletions Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,73 +18,28 @@ enum ConsoleColor {
// Constants
const char* kLogFileName = "log.txt";
const char* kDirectoryPath = "txt";

// Function to count characters in a text file.
std::size_t CountCharacters(const fs::path& file_path) {
try {
std::ifstream file(file_path, std::ios::binary);
if (!file) {
// Set console color to red
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), COLOR_RED);
std::cerr << "Error opening file: " << file_path.string() << std::endl;
// Reset to default color
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), COLOR_DEFAULT);
return 0;
}

std::size_t character_count = 0;
char c;
while (file.get(c)) {
character_count++;
}

// Explicitly close the file after reading.
file.close();

return character_count;
}
catch (const std::exception& e) {
// Handle exceptions related to file operations
std::cerr << "Exception while processing file: " << e.what() << std::endl;
return 0;
}
}
const std::size_t kMaxFileSize = 10 * 1024 * 1024; // 10 MB

// Function to log a message to a log buffer.
void LogMessage(const char* message, char*& log_buffer) {
void LogMessage(const std::string& message, std::string& log_buffer) {
// Get the current timestamp
std::time_t now = std::time(nullptr);
char timestamp[50];
std::tm time_info;
localtime_s(&time_info, &now); // Use localtime_s for thread safety
std::strftime(timestamp, sizeof(timestamp), "[%Y-%m-%d %H:%M:%S] ", &time_info);

// Allocate memory for the new log message
size_t len_timestamp = strlen(timestamp);
size_t len_message = strlen(message);
char* new_message = new char[len_timestamp + len_message + 2]; // 2 for '\n' and null terminator
strcpy_s(new_message, len_timestamp + len_message + 2, timestamp);
strcat_s(new_message, len_timestamp + len_message + 2, message);
strcat_s(new_message, len_timestamp + len_message + 2, "\n");

// Append the new message to the log buffer
if (log_buffer) {
size_t len_log_buffer = strlen(log_buffer);
char* temp = new char[len_log_buffer + len_timestamp + len_message + 2];
strcpy_s(temp, len_log_buffer + len_timestamp + len_message + 2, log_buffer);
strcat_s(temp, len_log_buffer + len_timestamp + len_message + 2, new_message);
delete[] log_buffer;
log_buffer = temp;
}
else {
log_buffer = new_message;
}
// Append the message to the log buffer with timestamp
log_buffer += timestamp + message + "\n";
}

// Function to write the log buffer to a log file.
void WriteLog(const char* log_buffer) {
void WriteLog(const std::string& log_buffer) {
try {
// Open the log file in append mode
std::ofstream log_file(kLogFileName, std::ios::app);
if (log_file) {
// Write the log buffer to the file
log_file << log_buffer;
}
}
Expand All @@ -94,10 +49,45 @@ void WriteLog(const char* log_buffer) {
}
}

// Function to count characters in a text file.
std::size_t CountCharacters(const fs::path& file_path) {
try {
// Check file size
std::ifstream file(file_path, std::ios::binary | std::ios::ate);
if (!file) {
// Handle file opening error by throwing an exception
throw std::runtime_error("Error opening file: " + file_path.string());
}

std::size_t file_size = static_cast<std::size_t>(file.tellg());
if (file_size > kMaxFileSize) {
// Handle file size exceeding the limit by throwing an exception
throw std::runtime_error("File size exceeds the limit (10 MB): " + file_path.string());
}

std::size_t character_count = 0;
char c;
file.seekg(0); // Move the file pointer to the beginning
while (file.get(c)) {
character_count++;
}

// Explicitly close the file after reading.
file.close();

return character_count;
}
catch (const std::exception& e) {
// Handle exceptions related to file operations and re-throw them
std::cerr << "Exception while processing file: " << e.what() << std::endl;
throw;
}
}

// Function to display an informative message in the console.
void DisplayInfo(const char* message) {
// Set console color to green
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), COLOR_GREEN);
void DisplayInfo(const std::string& message, ConsoleColor color) {
// Set console color
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), color);
std::cout << message << std::endl;
// Reset to default color
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), COLOR_DEFAULT);
Expand All @@ -114,37 +104,31 @@ int main() {
fs::create_directory(kDirectoryPath);
}
catch (const fs::filesystem_error& e) {
// Set console color to red
// Handle directory creation error
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), COLOR_RED);
// Display an error message as a popup
MessageBoxA(nullptr, ("Error creating directory: " + std::string(e.what())).c_str(), "Error", MB_ICONERROR);
// Reset to default color
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), COLOR_DEFAULT);
char* log_buffer = nullptr;
LogMessage("Error creating directory.", log_buffer);
std::string log_buffer;
LogMessage("Error creating directory: " + std::string(e.what()), log_buffer);
WriteLog(log_buffer);
delete[] log_buffer;
return 1;
}
}

if (!fs::is_directory(kDirectoryPath)) {
// Set console color to red
// Handle invalid directory error
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), COLOR_RED);
// Display an error message as a popup
MessageBoxA(nullptr, "'txt' is not a valid directory.", "Error", MB_ICONERROR);
// Reset to default color
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), COLOR_DEFAULT);
char* log_buffer = nullptr;
std::string log_buffer;
LogMessage("'txt' is not a valid directory.", log_buffer);
WriteLog(log_buffer);
delete[] log_buffer;
return 1;
}

std::size_t total_character_count = 0;
bool found_text_files = false;
char* log_buffer = nullptr;
std::string log_buffer;

try {
for (const auto& entry : fs::directory_iterator(kDirectoryPath)) {
Expand All @@ -154,24 +138,23 @@ int main() {
found_text_files = true;
std::size_t character_count = CountCharacters(entry.path());
total_character_count += character_count;

// Display an informative message in the console
const char* format = "File: %s | Characters: %zu";
char message[256];
sprintf_s(message, sizeof(message), format, entry.path().string().c_str(), character_count);
DisplayInfo(message);
DisplayInfo(message, COLOR_GREEN);

// Log to the log buffer
// Log the message
LogMessage(message, log_buffer);
}
}
}

if (!found_text_files) {
// Set console color to red
// Handle no text files found error
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), COLOR_RED);
// Display an error message as a popup
MessageBoxA(nullptr, "No text files found in the 'txt' directory.", "Error", MB_ICONERROR);
// Reset to default color
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), COLOR_DEFAULT);
const char* log_message = "No text files found in the 'txt' directory.";
LogMessage(log_message, log_buffer);
Expand All @@ -181,27 +164,26 @@ int main() {
const char* total_message = "Total characters: ";
char total_message_buffer[256];
sprintf_s(total_message_buffer, sizeof(total_message_buffer), "%s%zu", total_message, total_character_count);
DisplayInfo(total_message_buffer);
DisplayInfo(total_message_buffer, COLOR_DEFAULT);
LogMessage(total_message_buffer, log_buffer);
WriteLog(log_buffer);
delete[] log_buffer;
}
catch (const fs::filesystem_error& e) {
// Set console color to red
// Handle filesystem error
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), COLOR_RED);
// Display an error message as a popup
MessageBoxA(nullptr, ("Filesystem error: " + std::string(e.what())).c_str(), "Error", MB_ICONERROR);
// Reset to default color
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), COLOR_DEFAULT);
char* log_buffer = nullptr;
LogMessage(("Filesystem error: " + std::string(e.what())).c_str(), log_buffer);
std::string log_buffer;
LogMessage(("Filesystem error: " + std::string(e.what())), log_buffer);
WriteLog(log_buffer);
delete[] log_buffer;
return 1;
}
catch (const std::exception& e) {
// Handle other exceptions
std::cerr << "Exception: " << e.what() << std::endl;
std::string log_buffer;
LogMessage("Exception: " + std::string(e.what()), log_buffer);
WriteLog(log_buffer);
return 1;
}

Expand Down

0 comments on commit 18155c0

Please sign in to comment.