<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* librevenge
 * Version: MPL 2.0 / LGPLv2.1+
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * Major Contributor(s):
 * Copyright (C) 2004 <NAME> (<EMAIL>)
 * Copyright (C) 2005 Net Integration Technologies (http://www.net-itech.com)
 * Copyright (C) 2006 <NAME> (<EMAIL>)
 *
 * For minor contributions see the git repository.
 *
 * Alternatively, the contents of this file may be used under the terms
 * of the GNU Lesser General Public License Version 2.1 or later
 * (LGPLv2.1+), in which case the provisions of the LGPLv2.1+ are
 * applicable instead of those above.
 */

#include <map>
#include <string>
#include <utility>
#include <boost/spirit/include/classic.hpp>
#include <librevenge/librevenge.h>

namespace
{

bool findDouble(const librevenge::RVNGString &str, double &res, librevenge::RVNGUnit &unit)
{
	using namespace ::boost::spirit::classic;

	if (str.empty())
		return false;

	unit = librevenge::RVNG_GENERIC;

	if (!parse(str.cstr(),
	           //  Begin grammar
	           (
	               real_p[assign_a(res)] >>
	               (
	                   str_p("pt")[assign_a(unit,librevenge::RVNG_POINT)]
	                   |
	                   str_p("in")[assign_a(unit,librevenge::RVNG_INCH)]
	                   |
	                   str_p("%")[assign_a(unit,librevenge::RVNG_PERCENT)]
	                   |
	                   str_p("*")[assign_a(unit,librevenge::RVNG_TWIP)]
	                   |
	                   eps_p
	               )
	           ) >> end_p,
	           //  End grammar
	           space_p).full)
	{
		return false;
	}

	if (unit == librevenge::RVNG_PERCENT)
		res /= 100.0;

	return true;
}

bool findInt(const librevenge::RVNGString &str, int &res)
{
	using namespace ::boost::spirit::classic;

	if (str.empty())
		return false;

	return parse(str.cstr(),
	             //  Begin grammar
	             (
	                 int_p[assign_a(res)]
	             ) >> end_p,
	             //  End grammar
	             space_p).full;
}

bool findBool(const librevenge::RVNGString &str, bool &res)
{
	using namespace ::boost::spirit::classic;

	if (str.empty())
		return false;

	return parse(str.cstr(),
	             //  Begin grammar
	             (
	                 str_p("true")[assign_a(res,true)]
	                 |
	                 str_p("false")[assign_a(res,false)]
	                 |
	                 str_p("TRUE")[assign_a(res,true)]
	                 |
	                 str_p("FALSE")[assign_a(res,false)]
	             ) >> end_p,
	             //  End grammar
	             space_p).full;
}

} // anonymous namespace

namespace librevenge
{

class RVNGPropertyListElement
{
public:
	RVNGPropertyListElement() : m_prop(0), m_vec(0) {}
	RVNGPropertyListElement(RVNGProperty *prop, RVNGPropertyListVector *vec)
		: m_prop(prop), m_vec(vec) {}
	RVNGProperty *m_prop;
	RVNGPropertyListVector *m_vec;
};

class RVNGPropertyListImpl
{
public:
	RVNGPropertyListImpl() : m_map() {}
	~RVNGPropertyListImpl();
	void insert(const char *name, RVNGProperty *prop);
	void insert(const char *name, RVNGPropertyListVector *vec);
	const RVNGProperty *operator[](const char *name) const;
	const RVNGPropertyListVector *get(const char *name) const;
	void remove(const char *name);
	void clear();

	mutable std::map<std::string, RVNGPropertyListElement> m_map;

private:
	// disable copy construction and assignment
	RVNGPropertyListImpl(const RVNGPropertyListImpl &);
	RVNGPropertyListImpl &operator=(const RVNGPropertyListImpl &);
};

RVNGPropertyListImpl::~RVNGPropertyListImpl()
{
	for (std::map<std::string, RVNGPropertyListElement>::iterator iter = m_map.begin();
	        iter != m_map.end();
	        ++iter)
	{
		delete iter->second.m_prop;
		delete iter->second.m_vec;
	}
}

const RVNGProperty *RVNGPropertyListImpl::operator[](const char *name) const
{
	std::map<std::string, RVNGPropertyListElement>::iterator i = m_map.find(name);
	if (i != m_map.end())
	{
		return i->second.m_prop;
	}

	return 0;
}

const RVNGPropertyListVector *RVNGPropertyListImpl::get(const char *name) const
{
	std::map<std::string, RVNGPropertyListElement>::iterator i = m_map.find(name);
	if (i != m_map.end())
	{
		return i->second.m_vec;
	}

	return 0;
}

void RVNGPropertyListImpl::insert(const char *name, RVNGProperty *prop)
{
	std::map<std::string, RVNGPropertyListElement>::iterator i = m_map.lower_bound(name);
	if (i != m_map.end() && !(m_map.key_comp()(name, i->first)))
	{
		RVNGProperty *tmpProp = i->second.m_prop;
		i->second.m_prop = prop;
		delete tmpProp;
		return;
	}
	m_map.insert(i, std::map<std::string, RVNGPropertyListElement>::value_type(name, RVNGPropertyListElement(prop, 0)));
}

void RVNGPropertyListImpl::insert(const char *name, RVNGPropertyListVector *vec)
{
	std::map<std::string, RVNGPropertyListElement>::iterator i = m_map.lower_bound(name);
	if (i != m_map.end() && !(m_map.key_comp()(name, i->first)))
	{
		RVNGPropertyListVector *tmpProp = i->second.m_vec;
		i->second.m_vec = vec;
		delete tmpProp;
		return;
	}
	m_map.insert(i, std::map<std::string, RVNGPropertyListElement>::value_type(name, RVNGPropertyListElement(0, vec)));
}<commit_msg>Disable the possibility to have property a propListVec in the same key<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* librevenge
 * Version: MPL 2.0 / LGPLv2.1+
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * Major Contributor(s):
 * Copyright (C) 2004 <NAME> (<EMAIL>)
 * Copyright (C) 2005 Net Integration Technologies (http://www.net-itech.com)
 * Copyright (C) 2006 <NAME> (<EMAIL>)
 *
 * For minor contributions see the git repository.
 *
 * Alternatively, the contents of this file may be used under the terms
 * of the GNU Lesser General Public License Version 2.1 or later
 * (LGPLv2.1+), in which case the provisions of the LGPLv2.1+ are
 * applicable instead of those above.
 */

#include <map>
#include <string>
#include <utility>
#include <boost/spirit/include/classic.hpp>
#include <librevenge/librevenge.h>

namespace
{

bool findDouble(const librevenge::RVNGString &str, double &res, librevenge::RVNGUnit &unit)
{
	using namespace ::boost::spirit::classic;

	if (str.empty())
		return false;

	unit = librevenge::RVNG_GENERIC;

	if (!parse(str.cstr(),
	           //  Begin grammar
	           (
	               real_p[assign_a(res)] >>
	               (
	                   str_p("pt")[assign_a(unit,librevenge::RVNG_POINT)]
	                   |
	                   str_p("in")[assign_a(unit,librevenge::RVNG_INCH)]
	                   |
	                   str_p("%")[assign_a(unit,librevenge::RVNG_PERCENT)]
	                   |
	                   str_p("*")[assign_a(unit,librevenge::RVNG_TWIP)]
	                   |
	                   eps_p
	               )
	           ) >> end_p,
	           //  End grammar
	           space_p).full)
	{
		return false;
	}

	if (unit == librevenge::RVNG_PERCENT)
		res /= 100.0;

	return true;
}

bool findInt(const librevenge::RVNGString &str, int &res)
{
	using namespace ::boost::spirit::classic;

	if (str.empty())
		return false;

	return parse(str.cstr(),
	             //  Begin grammar
	             (
	                 int_p[assign_a(res)]
	             ) >> end_p,
	             //  End grammar
	             space_p).full;
}

bool findBool(const librevenge::RVNGString &str, bool &res)
{
	using namespace ::boost::spirit::classic;

	if (str.empty())
		return false;

	return parse(str.cstr(),
	             //  Begin grammar
	             (
	                 str_p("true")[assign_a(res,true)]
	                 |
	                 str_p("false")[assign_a(res,false)]
	                 |
	                 str_p("TRUE")[assign_a(res,true)]
	                 |
	                 str_p("FALSE")[assign_a(res,false)]
	             ) >> end_p,
	             //  End grammar
	             space_p).full;
}

} // anonymous namespace

namespace librevenge
{

class RVNGPropertyListElement
{
public:
	RVNGPropertyListElement() : m_prop(0), m_vec(0) {}
	RVNGPropertyListElement(RVNGProperty *prop, RVNGPropertyListVector *vec)
		: m_prop(prop), m_vec(vec) {}
	RVNGProperty *m_prop;
	RVNGPropertyListVector *m_vec;
};

class RVNGPropertyListImpl
{
public:
	RVNGPropertyListImpl() : m_map() {}
	~RVNGPropertyListImpl();
	void insert(const char *name, RVNGProperty *prop);
	void insert(const char *name, RVNGPropertyListVector *vec);
	const RVNGProperty *operator[](const char *name) const;
	const RVNGPropertyListVector *get(const char *name) const;
	void remove(const char *name);
	void clear();

	mutable std::map<std::string, RVNGPropertyListElement> m_map;

private:
	// disable copy construction and assignment
	RVNGPropertyListImpl(const RVNGPropertyListImpl &);
	RVNGPropertyListImpl &operator=(const RVNGPropertyListImpl &);
};

RVNGPropertyListImpl::~RVNGPropertyListImpl()
{
	for (std::map<std::string, RVNGPropertyListElement>::iterator iter = m_map.begin();
	        iter != m_map.end();
	        ++iter)
	{
		delete iter->second.m_prop;
		delete iter->second.m_vec;
	}
}

const RVNGProperty *RVNGPropertyListImpl::operator[](const char *name) const
{
	std::map<std::string, RVNGPropertyListElement>::iterator i = m_map.find(name);
	if (i != m_map.end())
	{
		return i->second.m_prop;
	}

	return 0;
}

const RVNGPropertyListVector *RVNGPropertyListImpl::get(const char *name) const
{
	std::map<std::string, RVNGPropertyListElement>::iterator i = m_map.find(name);
	if (i != m_map.end())
	{
		return i->second.m_vec;
	}

	return 0;
}

void RVNGPropertyListImpl::insert(const char *name, RVNGProperty *prop)
{
	std::map<std::string, RVNGPropertyListElement>::iterator i = m_map.lower_bound(name);
	if (i != m_map.end() && !(m_map.key_comp()(name, i->first)))
	{
		delete i->second.m_vec;
		i->second.m_vec = 0;
		RVNGProperty *tmpProp = i->second.m_prop;
		i->second.m_prop = prop;
		delete tmpProp;
		return;
	}
	m_map.insert(i, std::map<std::string, RVNGPropertyListElement>::value_type(name, RVNGPropertyListElement(prop, 0)));
}

void RVNGPropertyListImpl::insert(const char *name, RVNGPropertyListVector *vec)
{
	std::map<std::string, RVNGPropertyListElement>::iterator i = m_map.lower_bound(name);
	if (i != m_map.end() && !(m_map.key_comp()(name, i->first)))
	{
		delete i->second.m_prop;
		i->second.m_prop = 0;
		RVNGPropertyListVector *tmpProp = i->second.m_vec;
		i->second.m_vec = vec;
		delete tmpProp;
		return;
	}
	m_map.insert(i, std::map<std::string, RVNGPropertyListElement>::value_type(name, RVNGPropertyListElement(0, vec)));
}
{'fraction_non_alphanumeric': 0.13815246307678195, 'fraction_numerical': 0.007155306852582332, 'mean_word_length': 3.049777117384844, 'pattern_counts': {'":': 0, '<': 37, '<?xml version=': 0, '>': 77, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, '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': '7632277', 'n_tokens_mistral': 3930, 'n_tokens_neox': 3658, 'n_words': 787}