1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-04-24 21:57:44 +00:00
sapphire/deps/datReader/ExdData.cpp
2018-10-25 12:17:40 +02:00

100 lines
2.5 KiB
C++

#include "ExdData.h"
#include "stream.h"
#include "GameData.h"
#include "File.h"
#include "ExdCat.h"
namespace xiv
{
namespace exd
{
ExdData::ExdData(dat::GameData& i_game_data) try :
_game_data(i_game_data)
{
//XIV_INFO(xiv_exd_logger, "Initializing ExdData");
// Fetch the root.exl and get a stream from it
auto root_exl = i_game_data.getFile("exd/root.exl");
std::vector< char > dataCpy = root_exl->get_data_sections().front();
xiv::utils::stream::vectorwrapbuf<char> databuf(dataCpy);
std::istream stream(&databuf);
// Iterates over the lines while skipping the first one
std::string line;
std::getline(stream, line); // extract first line EXLT,2
std::getline(stream, line);
// Until the EOF
while (!line.empty())
{
// Format is cat_name,XX
// XX being an internal identifier
// Get only the cat_name
auto sep = line.find(',');
auto category = line.substr(0, sep);
// Add to the list of category name
// creates the empty category in the cats map
// instantiate the creation mutex for this category
_cat_names.push_back(category);
_cats[category] = std::unique_ptr<Cat>();
_cat_creation_mutexes[category] = std::unique_ptr<std::mutex>(new std::mutex());
std::getline(stream, line);
}
}
catch(std::exception& e)
{
// In case of failure here, client is supposed to catch the exception because it is not recoverable on our side
throw std::runtime_error( "ExdData initialization failed: " + std::string( e.what() ) );
}
ExdData::~ExdData()
{
}
const std::vector<std::string>& ExdData::get_cat_names() const
{
return _cat_names;
}
const Cat& ExdData::get_category(const std::string& i_cat_name)
{
// Get the category from its name
auto cat_it = _cats.find(i_cat_name);
if (cat_it == _cats.end())
{
throw std::runtime_error("Category not found: " + i_cat_name);
}
if (cat_it->second)
{
// If valid return it
return *(cat_it->second);
}
else
{
// If not, create it and return it
create_category(i_cat_name);
return *(_cats[i_cat_name]);
}
}
void ExdData::create_category(const std::string& i_cat_name)
{
// Lock mutex in this scope
std::lock_guard<std::mutex> lock(*(_cat_creation_mutexes[i_cat_name]));
// Maybe after unlocking it has already been created, so check (most likely if it blocked)
if (!_cats[i_cat_name])
{
_cats[i_cat_name] = std::unique_ptr<Cat>(new Cat(_game_data, i_cat_name));
}
}
}
}