pgnp/src/PGN.hpp

83 lines
2.4 KiB
C++
Raw Normal View History

2022-01-25 10:53:10 +01:00
#include "HalfMove.hpp"
2022-01-24 15:29:22 +01:00
#include <algorithm>
#include <exception>
2022-01-23 20:57:28 +01:00
#include <fstream>
2022-01-24 15:29:22 +01:00
#include <unordered_map>
2022-01-23 20:57:28 +01:00
namespace pgnp {
2022-01-24 15:29:22 +01:00
class PGN {
private:
2022-01-25 10:53:10 +01:00
/// @brief Contains tags data
2022-01-24 15:29:22 +01:00
std::unordered_map<std::string, std::string> tags;
2022-01-25 10:53:10 +01:00
/// @brief Contains the tags list in parsed order
2022-01-24 15:29:22 +01:00
std::vector<std::string> tagkeys;
2022-01-25 10:53:10 +01:00
/// @brief Contains game result (last PGN word)
2022-01-24 18:32:05 +01:00
std::string result;
2022-01-25 10:53:10 +01:00
/// @brief COntains the parsed PGN moves
2022-01-24 15:29:22 +01:00
HalfMove *moves;
2022-01-25 10:53:10 +01:00
/// @brief Contains the PGN data
2022-01-24 15:29:22 +01:00
std::string pgn_content;
2022-01-23 20:57:28 +01:00
2022-01-24 15:29:22 +01:00
public:
~PGN();
void FromFile(std::string);
void FromString(std::string);
2022-01-25 10:53:10 +01:00
/// @brief Check if PGN contains a specific tag
2022-01-24 15:29:22 +01:00
bool HasTag(std::string);
/// @brief Perform a Seven Tag Roster compliance check
void STRCheck();
2022-01-25 10:53:10 +01:00
/// @brief Dump parsed PGN into a string
std::string Dump();
/// @brief Retrieve parsed tag list
2022-01-24 15:29:22 +01:00
std::vector<std::string> GetTagList();
2022-01-25 10:53:10 +01:00
/// @brief Access to the value of a tag
2022-01-24 15:29:22 +01:00
std::string GetTagValue(std::string);
2022-01-25 10:53:10 +01:00
/// @brief Get game result based on the last PGN word
2022-01-24 18:32:05 +01:00
std::string GetResult();
2022-01-25 10:53:10 +01:00
/// @brief Fetch PGN moves as HalfMove structure
void GetMoves(HalfMove *);
2022-01-23 20:57:28 +01:00
2022-01-24 15:29:22 +01:00
private:
/// @brief Populate @a tags with by parsing the one starting at location in
/// argument
int ParseNextTag(int);
/// @brief Get the next non-blank char location starting from location in
/// argument
int NextNonBlank(int);
2022-01-25 10:53:10 +01:00
/// @brief Parse a HalfMove at a specific location into @a pgn_content
int ParseHalfMove(int, HalfMove *);
2022-01-25 14:53:34 +01:00
int ParseComment(int,HalfMove *);
2022-01-24 15:29:22 +01:00
};
2022-01-23 20:57:28 +01:00
2022-01-24 15:29:22 +01:00
struct UnexpectedEOF : public std::exception {
const char *what() const throw() { return "Unexpected end of pgn file"; }
};
2022-01-23 20:57:28 +01:00
2022-01-24 16:41:02 +01:00
struct InvalidTagName : public std::exception {
const char *what() const throw() { return "Invalid tag name"; }
};
2022-01-24 18:32:05 +01:00
struct InvalidGameResult : public std::exception {
const char *what() const throw() { return "Invalid game result"; }
};
2022-01-24 16:41:02 +01:00
struct UnexpectedCharacter : public std::exception {
std::string msg;
UnexpectedCharacter(char actual, char required, int loc) {
std::stringstream ss;
ss << "Expected \'" << required << "\' at location " << loc
<< " but read \'" << actual << "\'";
msg = ss.str();
}
const char *what() const throw() { return msg.c_str(); }
};
2022-01-24 15:29:22 +01:00
struct STRCheckFailed : public std::exception {
const char *what() const throw() {
return "Seven Tag Roster compliance check failed";
}
};
2022-01-23 20:57:28 +01:00
2022-01-24 15:29:22 +01:00
} // namespace pgnp