Employee.h

 avatar
unknown
c_cpp
2 months ago
9.3 kB
2
Indexable
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <cstring>
#include <stdexcept> // For runtime_error
#include <memory>
#include <algorithm> // For std::transform
#include <stack>

class Employee {
	struct EmployeeRec {
		int id;
		char name[31];       // Fixed length for name
		char address[26];    // Fixed length for address
		char city[21];       // Fixed length for city
		char state[21];      // Fixed length for state
		char country[21];    // Fixed length for country
		char phone[21];      // Fixed length for phone
		double salary;
	};
public:
	std::string name = "";
	int id = 0;
	std::string address = "";
	std::string city = "";
	std::string state = "";
	std::string country = "";
	std::string phone = "";
	double salary = 0.0;

	// Write a readable Employee representation to a stream 
	void display(std::ostream& readableEmployee) const {
		readableEmployee << "ID: " << id << "\n";
		readableEmployee << "Name: " << name << "\n";
		readableEmployee << "Address: " << address << "\n";
		readableEmployee << "City: " << city << "\n";
		readableEmployee << "State: " << state << "\n";
		readableEmployee << "Country: " << country << "\n";
		readableEmployee << "Phone: " << phone << "\n";;
		readableEmployee << "Salary: " << salary << "\n";
	}

	static std::string getNextTag(std::istream& in) {
		char c;
		std::string tag;
		while (in.get(c)) {
			if (c == '<') {
				tag += c;
				while (in.get(c) && c != '>') {
					tag += c;
				}
				tag += '>';
				return tag;
			}
		}
		return "";
	}

    static std::string getNextValue(std::istream& in) {
        std::string value, temp;
        char c;

        while (in.get(c)) {
            if (c == '<') {
                in.unget(); // Put back '<' for the next tag
                break;
            }
            temp += c;
        }

        // Trim leading/trailing whitespace safely
        size_t start = temp.find_first_not_of(" \n\r\t");
        size_t end = temp.find_last_not_of(" \n\r\t");

        if (start != std::string::npos) {
            value = temp.substr(start, (end == std::string::npos) ? temp.size() - start : end - start + 1);
        }

        return value;
    }

	static bool caseInsensitiveCompare(const std::string& str1, const std::string& str2) {
		if (str1.size() != str2.size()) {
			return false;
		}
		for (size_t i = 0; i < str1.size(); ++i) {
			if (tolower(str1[i]) != tolower(str2[i])) {
				return false;
			}
		}
		return true;
	}

	// Read the XML record from a stream
    static Employee* fromXML(std::istream& in) {
        std::unique_ptr<Employee> emp = std::make_unique<Employee>();
        bool hasName = false, hasId = false;
        std::string tag, value;
        std::stack<std::string> tagStack;

        while (true) { 
            tag = getNextTag(in);
            if (tag.empty()) break; // End of file
            
            value = getNextValue(in);
            std::cout << "Current tag: " << tag << "\n";
            std::cout << "Current tag: " << tag << " Value: " << value << "\n";
            

            if (caseInsensitiveCompare(tag, "<Employee>")) {
                tagStack.push(tag);
                if (!tagStack.empty() && tagStack.top() == "<Employee>") {
                    continue;
                }
                throw std::runtime_error("Invalid tag: <Employee>");
            }
            else if (caseInsensitiveCompare(tag, "</Employee>")) {
                if (!tagStack.empty() && tagStack.top() == "<Employee>") {
                    tagStack.pop();                    
                }
            }
            else if (caseInsensitiveCompare(tag, "<Name>")) {
                emp->name = value;
                hasName = true;
                tagStack.push(tag);
            }
            else if (caseInsensitiveCompare(tag, "</Name>")) {
                if (tagStack.empty() || !caseInsensitiveCompare(tagStack.top(), "<Name>")) {
                    throw std::runtime_error("Mismatched closing tag: </Name>");
                }
                tagStack.pop();
            }
            else if (caseInsensitiveCompare(tag, "<ID>")) {
                try {
                    if (!value.empty() && std::all_of(value.begin(), value.end(), ::isdigit)) {
                        emp->id = std::stoi(value);
                        hasId = true;
                    }
                    else {
                        throw std::invalid_argument("ID is not a valid integer");
                    }
                }
                catch (const std::exception& e) {
                    std::cerr << "Error parsing ID: " << value << " - " << e.what() << std::endl;
                }
                tagStack.push(tag);
            }
            else if (caseInsensitiveCompare(tag, "</ID>")) {
                if (tagStack.empty() || !caseInsensitiveCompare(tagStack.top(), "<ID>")) {
                    throw std::runtime_error("Mismatched closing tag: </ID>");
                }
                tagStack.pop();
            }
            else if (caseInsensitiveCompare(tag, "<Salary>")) {
                try {
                    if (!value.empty()) {
                        emp->salary = std::stod(value);
                    }
                }
                catch (const std::exception& e) {
                    std::cerr << "Error parsing salary: " << value << " - " << e.what() << std::endl;
                }
                tagStack.push(tag);
            }
            else if (caseInsensitiveCompare(tag, "</Salary>")) {
                if (tagStack.empty() || !caseInsensitiveCompare(tagStack.top(), "<Salary>")) {
                    throw std::runtime_error("Mismatched closing tag: </Salary>");
                }
                tagStack.pop();
            }
            else if (caseInsensitiveCompare(tag, "<Address>")) {
                emp->address = value;
                tagStack.push(tag);
            }
            else if (caseInsensitiveCompare(tag, "</Address>")) {
                if (tagStack.empty() || !caseInsensitiveCompare(tagStack.top(), "<Address>")) {
                    throw std::runtime_error("Mismatched closing tag: </Address>");
                }
                tagStack.pop();
            }
            else if (caseInsensitiveCompare(tag, "<City>")) {
                emp->city = value;
                tagStack.push(tag);
            }
            else if (caseInsensitiveCompare(tag, "</City>")) {
                if (!tagStack.empty() && tagStack.top() != "<City>") {
                    tagStack.pop();                    
                }
                throw std::runtime_error("Mismatched closing tag: </City>");
            }
            else if (caseInsensitiveCompare(tag, "<State>")) {
                emp->state = value;
                tagStack.push(tag);
            }
            else if (caseInsensitiveCompare(tag, "</State>")) {
                if (tagStack.empty() || !caseInsensitiveCompare(tagStack.top(), "<State>")) {
                    throw std::runtime_error("Mismatched closing tag: </State>");
                }
                tagStack.pop();
            }
            else if (caseInsensitiveCompare(tag, "<Country>")) {
                emp->country = value;
                tagStack.push(tag);
            }
            else if (caseInsensitiveCompare(tag, "</Country>")) {
                if (tagStack.empty() || !caseInsensitiveCompare(tagStack.top(), "<Country>")) {
                    throw std::runtime_error("Mismatched closing tag: </Country>");
                }
                tagStack.pop();
            }
            else if (caseInsensitiveCompare(tag, "<Phone>")) {
                emp->phone = value;
                tagStack.push(tag);
            }
            else if (caseInsensitiveCompare(tag, "</Phone>")) {
                if (tagStack.empty() || !caseInsensitiveCompare(tagStack.top(), "<Phone>")) {
                    throw std::runtime_error("Mismatched closing tag: </Phone>");
                }
                tagStack.pop();
            }
            std::stack<std::string> tempStack = tagStack;
            while (!tempStack.empty()) {
                std::cout << "Stack: " << tempStack.top() << std::endl;
                tempStack.pop();
            }

            // Check for any remaining unclosed tags
            if (!tagStack.empty()) {
                std::cerr << "Missing closing tag for: " << tagStack.top() << std::endl;
            }

            std::cout << "This is the last bit for next loop: " << hasName << std::endl;
        }//end of while
        std::cout << hasName << std::endl;
        if (!hasName) {
            throw std::runtime_error("Warning: Employee missing <Name> tag");
        }
        if (!hasId) {
            throw std::runtime_error("Warning: Employee missing <ID> tag");
        }

        std::cout << std::endl;
        std::cout << hasName << std::endl;
        // Ensure all tags have been properly closed

        return emp.release(); // Return raw pointer
    }
};

Editor is loading...
Leave a Comment