<commit_before>/**
 * @file   Resource.cpp
 * @brief  Resource class implementation.
 * @author zer0
 * @date   2016-07-06
 */

#include <libtbag/dom/xml/Resource.hpp>
#include <libtbag/3rd/tinyxml2/tinyxml2.h>

// -------------------
NAMESPACE_LIBTBAG_OPEN
// -------------------

namespace dom {
namespace xml {

/* inline */ namespace impl {

// TinyXML2 operators.
using Document = tinyxml2::XMLDocument;
using Element = tinyxml2::XMLElement;
using Node = tinyxml2::XMLNode;

static Resource::Map readFromXmlDocument(Document const & doc, std::string const & tag)
{
    Element const * root = doc.FirstChildElement(Resource::getRootTagName());
    if (root == nullptr) {
        return Resource::Map();
    }

    Element const * cursor = root->FirstChildElement(tag.c_str());
    Resource::Map map;

    while (cursor != nullptr) {
        map.insert(std::make_pair(std::string(cursor->Attribute(Resource::getAttributeName()))
                , std::string(cursor->GetText())));
        cursor = cursor->NextSiblingElement(tag.c_str());
    }

    return map;
}

} // namespace impl

// ------------------------
// Resource implementation.
// ------------------------

Resource::Resource()
{
    // EMPTY.
}

Resource::Resource(Resource const & obj)
{
    this->copy(obj);
}

Resource::Resource(Resource && obj)
{
    this->swap(obj);
}

Resource::~Resource()
{
    // EMPTY.
}

Resource & Resource::operator =(Resource const & obj)
{
    return this->copy(obj);
}

Resource & Resource::operator =(Resource && obj)
{
    this->swap(obj);
    return *this;
}

Resource & Resource::copy(Resource const & obj)
{
    if (this != &obj) {
        _tag = obj._tag;
        _map = obj._map;
    }
    return *this;
}

void Resource::swap(Resource & obj)
{
    if (this != &obj) {
        _tag.swap(obj._tag);
        _map.swap(obj._map);
    }
}

void Resource::clear() TBAG_NOEXCEPT
{
    _tag.assign("");
    _map.clear();
}

std::size_t Resource::size() const TBAG_NOEXCEPT
{
    return _map.size();
}

void Resource::set_tag(std::string const & tag) TBAG_NOEXCEPT
{
    _tag = tag;
}

std::string Resource::get_tag() const TBAG_NOEXCEPT
{
    return _tag;
}

bool Resource::readFile(std::string const & path, std::string const & tag)
{
    _tag = tag;
    _map = Resource::readFromXmlFile(path, tag);
    return (_map.empty() == false);
}

bool Resource::readString(std::string const & xml, std::string const & tag)
{
    _tag = tag;
    _map = Resource::readFromXmlString(xml, tag);
    return (_map.empty() == false);
}

bool Resource::save(std::string const & path) const
{
    return Resource::save(path, _tag, _map);
}

bool Resource::getString(std::string const & key, std::string * result) const
{
    auto find_value = _map.find(key);
    if (find_value == _map.end()) {
        return false;
    }

    if (result != nullptr) {
        *result = find_value->second;
    }

    return true;
}

std::string Resource::getString(std::string const & key, std::string default_value) const
{
    std::string result;
    if (this->getString(key, &result)) {
        return result;
    }
    return default_value;
}

std::string Resource::getString(std::string const & key) const
{
    return this->getString(key, std::string(""));
}

auto Resource::get(std::string const & key
                 , std::string default_value) const -> decltype(default_value)
{
    return this->getString(key, std::string(""));
}

void Resource::set(std::string const & key, std::string const & value)
{
    auto find_value = _map.find(key);
    if (find_value == _map.end()) {
        _map.insert(std::make_pair(key, value));
    } else {
        find_value->second = value;
    }<commit_msg>Fixed bug in Resource::getString() method.<commit_after>/**
 * @file   Resource.cpp
 * @brief  Resource class implementation.
 * @author zer0
 * @date   2016-07-06
 */

#include <libtbag/dom/xml/Resource.hpp>
#include <libtbag/3rd/tinyxml2/tinyxml2.h>

// -------------------
NAMESPACE_LIBTBAG_OPEN
// -------------------

namespace dom {
namespace xml {

/* inline */ namespace impl {

// TinyXML2 operators.
using Document = tinyxml2::XMLDocument;
using Element = tinyxml2::XMLElement;
using Node = tinyxml2::XMLNode;

static Resource::Map readFromXmlDocument(Document const & doc, std::string const & tag)
{
    Element const * root = doc.FirstChildElement(Resource::getRootTagName());
    if (root == nullptr) {
        return Resource::Map();
    }

    Element const * cursor = root->FirstChildElement(tag.c_str());
    Resource::Map map;

    while (cursor != nullptr) {
        map.insert(std::make_pair(std::string(cursor->Attribute(Resource::getAttributeName()))
                , std::string(cursor->GetText())));
        cursor = cursor->NextSiblingElement(tag.c_str());
    }

    return map;
}

} // namespace impl

// ------------------------
// Resource implementation.
// ------------------------

Resource::Resource()
{
    // EMPTY.
}

Resource::Resource(Resource const & obj)
{
    this->copy(obj);
}

Resource::Resource(Resource && obj)
{
    this->swap(obj);
}

Resource::~Resource()
{
    // EMPTY.
}

Resource & Resource::operator =(Resource const & obj)
{
    return this->copy(obj);
}

Resource & Resource::operator =(Resource && obj)
{
    this->swap(obj);
    return *this;
}

Resource & Resource::copy(Resource const & obj)
{
    if (this != &obj) {
        _tag = obj._tag;
        _map = obj._map;
    }
    return *this;
}

void Resource::swap(Resource & obj)
{
    if (this != &obj) {
        _tag.swap(obj._tag);
        _map.swap(obj._map);
    }
}

void Resource::clear() TBAG_NOEXCEPT
{
    _tag.assign("");
    _map.clear();
}

std::size_t Resource::size() const TBAG_NOEXCEPT
{
    return _map.size();
}

void Resource::set_tag(std::string const & tag) TBAG_NOEXCEPT
{
    _tag = tag;
}

std::string Resource::get_tag() const TBAG_NOEXCEPT
{
    return _tag;
}

bool Resource::readFile(std::string const & path, std::string const & tag)
{
    _tag = tag;
    _map = Resource::readFromXmlFile(path, tag);
    return (_map.empty() == false);
}

bool Resource::readString(std::string const & xml, std::string const & tag)
{
    _tag = tag;
    _map = Resource::readFromXmlString(xml, tag);
    return (_map.empty() == false);
}

bool Resource::save(std::string const & path) const
{
    return Resource::save(path, _tag, _map);
}

bool Resource::getString(std::string const & key, std::string * result) const
{
    auto find_value = _map.find(key);
    if (find_value == _map.end()) {
        return false;
    }

    if (result != nullptr) {
        *result = find_value->second;
    }

    return true;
}

std::string Resource::getString(std::string const & key, std::string default_value) const
{
    std::string result;
    if (this->getString(key, &result)) {
        return result;
    }
    return default_value;
}

std::string Resource::getString(std::string const & key) const
{
    return this->getString(key, std::string(""));
}

auto Resource::get(std::string const & key
                 , std::string default_value) const -> decltype(default_value)
{
    return this->getString(key, default_value);
}

void Resource::set(std::string const & key, std::string const & value)
{
    auto find_value = _map.find(key);
    if (find_value == _map.end()) {
        _map.insert(std::make_pair(key, value));
    } else {
        find_value->second = value;
    }
{'fraction_non_alphanumeric': 0.17690117934119562, 'fraction_numerical': 0.004337806696489087, 'mean_word_length': 3.027292576419214, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 35, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 18}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3717112', 'n_tokens_mistral': 2403, 'n_tokens_neox': 2369, 'n_words': 512}