<commit_before>/*
 * Recognizer.cc
 *
 * Copyright (C) 2015 Linas Vepstas
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the
 * exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public
 * License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#ifndef _OPENCOG_RECOGNIZER_H
#define _OPENCOG_RECOGNIZER_H

#include <set>

#include <opencog/query/DefaultPatternMatchCB.h>
#include <opencog/atoms/pattern/PatternLink.h>

#include "BindLinkAPI.h"

namespace opencog {

/**
 * Very rough, crude, experimental prototype for the idea that
 * pattern recognition is the dual of pattern matching.
 * That is, rather than using one query pattern to search a large
 * collection of data, this does the opposite: given a single piece of
 * data, it searches for all rules/queries which apply to it.
 *
 * The file /examples/aiml/recog.scm provides a very simple example.
 * The implementation here is very minimalistic, and does many things
 * wrong:
 * -- it fails to perform any type-checking to make sure the variable
 *    constraints are satisfied.
 * -- AIML wants a left-to-right traversal, this does an omni-
 *    directional exploration. (which is OK, but is not how AIML is
 *    defined...)
 * -- This hasn't been thought through thoroughly. There are almost
 *    surely some weird gotcha's.
 */
class Recognizer :
   public virtual DefaultPatternMatchCB
{
	protected:
		const Pattern* _pattern;

		Handle _root;
		Handle _starter_term;
		size_t _cnt;
		bool do_search(PatternMatchEngine*, const Handle&);
		bool loose_match(const Handle&, const Handle&);

	public:
		OrderedHandleSet _rules;

		Recognizer(AtomSpace* as) :
			DefaultPatternMatchCB(as) {}

		virtual void set_pattern(const Variables& vars,
										 const Pattern& pat)
		{
			_pattern = &pat;
			DefaultPatternMatchCB::set_pattern(vars, pat);
		}

		virtual bool initiate_search(PatternMatchEngine*);
		virtual bool node_match(const Handle&, const Handle&);
		virtual bool link_match(const Handle&, const Handle&);
		virtual bool fuzzy_match(const Handle&, const Handle&);
		virtual bool grounding(const HandleMap &var_soln,
		                       const HandleMap &term_soln);
};

} // namespace opencog

#endif // _OPENCOG_RECOGNIZER_H

using namespace opencog;

// Uncomment below to enable debug print
#define DEBUG
#ifdef DEBUG
#define dbgprt(f, varargs...) logger().fine(f, ##varargs)
#else
#define dbgprt(f, varargs...)
#endif

/* ======================================================== */

bool Recognizer::do_search(PatternMatchEngine* pme, const Handle& top)
{
	if (top->isLink())
	{
		// Recursively drill down and explore every possible node as
		// a search starting point. This is needed, as the patterns we
		// compare against might not be connected.
		for (const Handle& h : top->getOutgoingSet())
		{
			_starter_term = top;
			bool found = do_search(pme, h);
			if (found) return true;
		}
		return false;
	}

	IncomingSet iset = get_incoming_set(top);
	size_t sz = iset.size();
	for (size_t i = 0; i < sz; i++)
	{
		Handle h(iset[i]);
		dbgprt("rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr\n");
		dbgprt("Loop candidate (%lu - %s):\n%s\n", _cnt++,
		       top->toShortString().c_str(),
		       h->toShortString().c_str());
		bool found = pme->explore_neighborhood(_root, _starter_term, h);

		// Terminate search if satisfied.
		if (found) return true;
   }

	return false;
}

bool Recognizer::initiate_search(PatternMatchEngine* pme)
{
	const HandleSeq& clauses = _pattern->cnf_clauses;

	_cnt = 0;
	for (const Handle& h: clauses)
	{
		_root = h;
		bool found = do_search(pme, h);
		if (found) return true;
	}
	return false;
}

bool Recognizer::node_match(const Handle& npat_h, const Handle& nsoln_h)
{
	if (npat_h == nsoln_h) return true;
	Type tso = nsoln_h->getType();
	if (VARIABLE_NODE == tso or GLOB_NODE == tso) return true;
	return false;
}

bool Recognizer::link_match(const Handle& lpat, const Handle& lsoln)
{
	// Self-compares always proceed.
	if (lpat == lsoln) return true;

	// mis-matched types are a dead-end.
	if (lpat->getType() != lsoln->getType()) return false;

	// Globs are arity-changing. But there is a minimum length.
	// Note that the inequality is backwards, here: the soln has the
	// globs! (and so lpat must have arity equal or greater than soln)
	if (lpat->getArity() < lsoln->getArity()) return false;
	return true;
}

bool Recognizer::loose_match(const Handle& npat_h, const Handle& nsoln_h)
{
	Type gtype = nsoln_h->getType();
	// Variable matches anything; move to next.
	if (VARIABLE_NODE == gtype) return true;

	// Strict match for link types.
	if (npat_h->getType() != gtype) return false;
	if (not npat_h->isNode()) return true;

	// If we are here, we know we have nodes. Ask for a strict match.
	if (npat_h != nsoln_h) return false;
	return true;
}

bool Recognizer::fuzzy_match(const Handle& npat_h, const Handle& nsoln_h)
{
	// If we are here, then there are probably glob nodes in the soln.
	// Try to match them, fairly rigorously. Exactly what constitutes
	// an OK match is still a bit up in the air.

	if (not npat_h->isLink() or not nsoln_h->isLink()) return false;

	const HandleSeq &osg = nsoln_h->getOutgoingSet();
	size_t osg_size = osg.size();

	// Lets not waste time, if there's no glob there.
	bool have_glob = false;
	for (size_t j=0; j<osg_size; j++)
	{
		if (osg[j]->getType() == GLOB_NODE)
		{
			have_glob = true;
			break;
		}
	}
	if (not have_glob) return false;

	const HandleSeq &osp = npat_h->getOutgoingSet();
	size_t osp_size = osp.size();
	size_t max_size = std::max(osg_size, osp_size);

	// Do a side-by-side compare. This is not as rigorous as
	// PatternMatchEngine::tree_compare() nor does it handle the bells
	// and whistles (ChoiceLink, QuoteLink, etc).
	size_t ip=0, jg=0;
	for (; ip<osp_size and jg<osg_size; ip++, jg++)
	{
		if (GLOB_NODE != osg[jg]->getType())
		{
			if (loose_match(osp[ip], osg[jg])) continue;
			return false;
		}

		// If we are here, we have a glob in the soln. If the glob is at
		// the end, it eats everything, so its a match. Else, resume
		// matching at the end of the glob.
		if ((jg+1) == osg_size) return true;

		const Handle& post(osg[jg+1]);
		ip++;
		while (ip < max_size and not loose_match(osp[ip], post))
		{
			ip++;
		}
		// If ip ran past the end, then the post was not found. This is
		// a mismatch.
		if (not (ip < max_size)) return false;

		// Go around again, look for more GlobNodes. Back up by one, so
		// that the for-loop increment gets us back on track.
		ip--;
	}

	// If we are here, then we should have matched up all the atoms;
	// if we exited the loop because pattern or grounding was short,
	// then its a mis-match.
	if (ip != osp_size or jg != osg_size) return false;
	return true;
}

bool Recognizer::grounding(const HandleMap& var_soln,
                           const HandleMap& term_soln)
{
	Handle rule = term_soln.at(_root);

	if (rule != _root) {
		_rules.insert(rule);
	}

	// Look for more groundings.
	return false;
}

Handle opencog::recognize(AtomSpace* as, const Handle& hlink)
{
	PatternLinkPtr bl(PatternLinkCast(hlink));
	if (NULL == bl)
		bl = createPatternLink(*LinkCast(hlink));

	Recognizer reco(as);
	bl->satisfy(reco);

	HandleSeq hs;
	for (const Handle& h : reco._rules) hs.push_back(h);

	return as->add_link(SET_LINK, hs);
}
<commit_msg>Add missing conversion<commit_after>/*
 * Recognizer.cc
 *
 * Copyright (C) 2015 Linas Vepstas
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the
 * exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public
 * License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#ifndef _OPENCOG_RECOGNIZER_H
#define _OPENCOG_RECOGNIZER_H

#include <set>

#include <opencog/query/DefaultPatternMatchCB.h>
#include <opencog/atoms/pattern/PatternLink.h>

#include "BindLinkAPI.h"

namespace opencog {

/**
 * Very rough, crude, experimental prototype for the idea that
 * pattern recognition is the dual of pattern matching.
 * That is, rather than using one query pattern to search a large
 * collection of data, this does the opposite: given a single piece of
 * data, it searches for all rules/queries which apply to it.
 *
 * The file /examples/aiml/recog.scm provides a very simple example.
 * The implementation here is very minimalistic, and does many things
 * wrong:
 * -- it fails to perform any type-checking to make sure the variable
 *    constraints are satisfied.
 * -- AIML wants a left-to-right traversal, this does an omni-
 *    directional exploration. (which is OK, but is not how AIML is
 *    defined...)
 * -- This hasn't been thought through thoroughly. There are almost
 *    surely some weird gotcha's.
 */
class Recognizer :
   public virtual DefaultPatternMatchCB
{
	protected:
		const Pattern* _pattern;

		Handle _root;
		Handle _starter_term;
		size_t _cnt;
		bool do_search(PatternMatchEngine*, const Handle&);
		bool loose_match(const Handle&, const Handle&);

	public:
		OrderedHandleSet _rules;

		Recognizer(AtomSpace* as) :
			DefaultPatternMatchCB(as) {}

		virtual void set_pattern(const Variables& vars,
										 const Pattern& pat)
		{
			_pattern = &pat;
			DefaultPatternMatchCB::set_pattern(vars, pat);
		}

		virtual bool initiate_search(PatternMatchEngine*);
		virtual bool node_match(const Handle&, const Handle&);
		virtual bool link_match(const PatternTermPtr&, const Handle&);
		virtual bool fuzzy_match(const Handle&, const Handle&);
		virtual bool grounding(const HandleMap &var_soln,
		                       const HandleMap &term_soln);
};

} // namespace opencog

#endif // _OPENCOG_RECOGNIZER_H

using namespace opencog;

// Uncomment below to enable debug print
#define DEBUG
#ifdef DEBUG
#define dbgprt(f, varargs...) logger().fine(f, ##varargs)
#else
#define dbgprt(f, varargs...)
#endif

/* ======================================================== */

bool Recognizer::do_search(PatternMatchEngine* pme, const Handle& top)
{
	if (top->isLink())
	{
		// Recursively drill down and explore every possible node as
		// a search starting point. This is needed, as the patterns we
		// compare against might not be connected.
		for (const Handle& h : top->getOutgoingSet())
		{
			_starter_term = top;
			bool found = do_search(pme, h);
			if (found) return true;
		}
		return false;
	}

	IncomingSet iset = get_incoming_set(top);
	size_t sz = iset.size();
	for (size_t i = 0; i < sz; i++)
	{
		Handle h(iset[i]);
		dbgprt("rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr\n");
		dbgprt("Loop candidate (%lu - %s):\n%s\n", _cnt++,
		       top->toShortString().c_str(),
		       h->toShortString().c_str());
		bool found = pme->explore_neighborhood(_root, _starter_term, h);

		// Terminate search if satisfied.
		if (found) return true;
   }

	return false;
}

bool Recognizer::initiate_search(PatternMatchEngine* pme)
{
	const HandleSeq& clauses = _pattern->cnf_clauses;

	_cnt = 0;
	for (const Handle& h: clauses)
	{
		_root = h;
		bool found = do_search(pme, h);
		if (found) return true;
	}
	return false;
}

bool Recognizer::node_match(const Handle& npat_h, const Handle& nsoln_h)
{
	if (npat_h == nsoln_h) return true;
	Type tso = nsoln_h->getType();
	if (VARIABLE_NODE == tso or GLOB_NODE == tso) return true;
	return false;
}

bool Recognizer::link_match(const PatternTermPtr& ptm, const Handle& lsoln)
{
	const Handle& lpat = ptm->getHandle();

	// Self-compares always proceed.
	if (lpat == lsoln) return true;

	// mis-matched types are a dead-end.
	if (lpat->getType() != lsoln->getType()) return false;

	// Globs are arity-changing. But there is a minimum length.
	// Note that the inequality is backwards, here: the soln has the
	// globs! (and so lpat must have arity equal or greater than soln)
	if (lpat->getArity() < lsoln->getArity()) return false;
	return true;
}

bool Recognizer::loose_match(const Handle& npat_h, const Handle& nsoln_h)
{
	Type gtype = nsoln_h->getType();
	// Variable matches anything; move to next.
	if (VARIABLE_NODE == gtype) return true;

	// Strict match for link types.
	if (npat_h->getType() != gtype) return false;
	if (not npat_h->isNode()) return true;

	// If we are here, we know we have nodes. Ask for a strict match.
	if (npat_h != nsoln_h) return false;
	return true;
}

bool Recognizer::fuzzy_match(const Handle& npat_h, const Handle& nsoln_h)
{
	// If we are here, then there are probably glob nodes in the soln.
	// Try to match them, fairly rigorously. Exactly what constitutes
	// an OK match is still a bit up in the air.

	if (not npat_h->isLink() or not nsoln_h->isLink()) return false;

	const HandleSeq &osg = nsoln_h->getOutgoingSet();
	size_t osg_size = osg.size();

	// Lets not waste time, if there's no glob there.
	bool have_glob = false;
	for (size_t j=0; j<osg_size; j++)
	{
		if (osg[j]->getType() == GLOB_NODE)
		{
			have_glob = true;
			break;
		}
	}
	if (not have_glob) return false;

	const HandleSeq &osp = npat_h->getOutgoingSet();
	size_t osp_size = osp.size();
	size_t max_size = std::max(osg_size, osp_size);

	// Do a side-by-side compare. This is not as rigorous as
	// PatternMatchEngine::tree_compare() nor does it handle the bells
	// and whistles (ChoiceLink, QuoteLink, etc).
	size_t ip=0, jg=0;
	for (; ip<osp_size and jg<osg_size; ip++, jg++)
	{
		if (GLOB_NODE != osg[jg]->getType())
		{
			if (loose_match(osp[ip], osg[jg])) continue;
			return false;
		}

		// If we are here, we have a glob in the soln. If the glob is at
		// the end, it eats everything, so its a match. Else, resume
		// matching at the end of the glob.
		if ((jg+1) == osg_size) return true;

		const Handle& post(osg[jg+1]);
		ip++;
		while (ip < max_size and not loose_match(osp[ip], post))
		{
			ip++;
		}
		// If ip ran past the end, then the post was not found. This is
		// a mismatch.
		if (not (ip < max_size)) return false;

		// Go around again, look for more GlobNodes. Back up by one, so
		// that the for-loop increment gets us back on track.
		ip--;
	}

	// If we are here, then we should have matched up all the atoms;
	// if we exited the loop because pattern or grounding was short,
	// then its a mis-match.
	if (ip != osp_size or jg != osg_size) return false;
	return true;
}

bool Recognizer::grounding(const HandleMap& var_soln,
                           const HandleMap& term_soln)
{
	Handle rule = term_soln.at(_root);

	if (rule != _root) {
		_rules.insert(rule);
	}

	// Look for more groundings.
	return false;
}

Handle opencog::recognize(AtomSpace* as, const Handle& hlink)
{
	PatternLinkPtr bl(PatternLinkCast(hlink));
	if (NULL == bl)
		bl = createPatternLink(*LinkCast(hlink));

	Recognizer reco(as);
	bl->satisfy(reco);

	HandleSeq hs;
	for (const Handle& h : reco._rules) hs.push_back(h);

	return as->add_link(SET_LINK, hs);
}
<|endoftext|>


<commit_before>/*
 * GameKeeper Framework
 *
 * Copyright (C) 2013 Karol Herbst <gamekeeper@karolherbst.de>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "runtime.h"

#include <cstdlib>
#include <iostream>

#include <boost/filesystem/operations.hpp>
#include <boost/program_options/options_description.hpp>
#include <boost/program_options/parsers.hpp>
#include <boost/program_options/variables_map.hpp>

#include <Hypodermic/ContainerBuilder.h>
#include <Hypodermic/Helpers.h>

#include <gamekeeper/backend/storemanager.h>
#include <gamekeeper/client/gamekeeper.h>
#include <gamekeeper/client/hypodermic.h>
#include <gamekeeper/client/storecontrollerimpl.h>
#include <gamekeeper/core/logger.h>
#include <gamekeeper/core/loggerStream.h>
#include <gamekeeper/core/boostpopropertyresolver.h>
#include <gamekeeper/core/curlfiledownloaderfactory.h>
#include <gamekeeper/core/log4cpploggerFactory.h>
#include <gamekeeper/core/stdc++11threadmanager.h>
#include <gamekeeper/core/xdgpaths.h>

// some platform dependent stuff
#ifdef GAMEKEEPER_OS_IS_WINDOWS
  #include <gamekeeper/core/win32threadhelper.h>
  #include <gamekeeper/core/windowsinformation.h>
  #define OSINFORMATIONCLASS WindowsInformation
  #define THREADHELPERCLASS Win32ThreadHelper
#else
  #include <gamekeeper/core/gnuinstalldirspaths.h>
  #include <gamekeeper/core/linuxinformation.h>
  #include <gamekeeper/core/pthreadhelper.h>
  #define BUNDLEPATHSCLASS GNUInstallDirsPaths
  #define OSINFORMATIONCLASS LinuxInformation
  #define THREADHELPERCLASS PthreadHelper
#endif

namespace fs = boost::filesystem;
namespace po = boost::program_options;

GAMEKEEPER_NAMESPACE_START(client)

static std::shared_ptr<Hypodermic::IContainer> localContainer;
static std::shared_ptr<Hypodermic::IContainer> container;

GameKeeperRuntime::GameKeeperRuntime()
{
	using namespace gamekeeper::core;
	Hypodermic::ContainerBuilder containerBuilder;

	// set up pre IoC container
	containerBuilder.registerType<OSINFORMATIONCLASS>()->
		as<OSInformation>()->
		singleInstance();
	containerBuilder.registerType<XDGPaths>(CREATE(new XDGPaths(INJECT(OSInformation))))->
		as<UserPaths>()->
		singleInstance();
	localContainer = containerBuilder.build();
}

static void
fillProperties(po::options_description & cmd, po::options_description & file)
{
	po::options_description descGlobalCmd("Global options");
	po::options_description descNetwork("Network options");

	descGlobalCmd.add_options()
		("help,h", "produce help message");

	descNetwork.add_options()
		("filelayout.bundle", po::value<std::string>()->default_value("auto"))
		("network.debug", po::value<bool>()->default_value(false)->implicit_value(true))
		("network.time_between_retries", po::value<uint16_t>()->default_value(300))
		("network.user_agent", po::value<std::string>())
		("network.resolve.retries", po::value<uint16_t>()->default_value(3))
		("network.resolve.timeout", po::value<uint16_t>()->default_value(5000))
		("network.connection.retries", po::value<uint16_t>()->default_value(3))
		("network.connection.timeout", po::value<uint16_t>()->default_value(30000))
		("network.download.max_buffer_size", po::value<uint32_t>()->default_value(2048));

	cmd.add(descGlobalCmd);
	cmd.add(descNetwork);
	file.add(descNetwork);
}

int
GameKeeperRuntime::main(int argc, const char* argv[], NewInstanceFuncPtr instanceFuncPtr, AddOptionsFuncPtr optionsFuncPtr)
{
	using namespace gamekeeper::backend;
	using namespace gamekeeper::client;
	using namespace gamekeeper::core;

	po::options_description descCmd;
	po::options_description descFile;

	fillProperties(descCmd, descFile);

	po::options_description cmdClient("Client options");
	po::options_description fileClient;
	po::options_description bothClient;
	po::options_description_easy_init cmdClientEasy = cmdClient.add_options();
	po::options_description_easy_init fileClientEasy = fileClient.add_options();
	po::options_description_easy_init bothClientEasy = bothClient.add_options();

	if(optionsFuncPtr != nullptr)
	{
		optionsFuncPtr(cmdClientEasy, fileClientEasy, bothClientEasy);
	}

	if(!bothClient.options().empty())
	{
		cmdClient.add(bothClient);
		fileClient.add(bothClient);
	}

	if(!cmdClient.options().empty())
	{
		descCmd.add(cmdClient);
	}

	if(!fileClient.options().empty())
	{
		descFile.add(fileClient);
	}

	po::variables_map vm;
	po::store(po::parse_command_line(argc, argv, descCmd), vm);

	fs::path configFile = localContainer->resolve<UserPaths>()->getConfigFile("properties.conf");
	if(fs::exists(configFile))
	{
		po::store(po::parse_config_file<char>(configFile.string().c_str(), descFile, true), vm);
	}

	if(vm.count("help") > 0)
	{
		std::cout << descCmd << std::endl;
		return EXIT_SUCCESS;
	}

	po::notify(vm);

	// build our property resolver now
	std::shared_ptr<PropertyResolver> pr = std::make_shared<BoostPOPropertyResolver>(vm);

	Hypodermic::ContainerBuilder containerBuilder;
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
	// set up the real IoC container

	// reuse instances from the pre container
	containerBuilder.registerInstance<OSInformation>(
		localContainer->resolve<OSInformation>())->
		as<OSInformation>()->
		singleInstance();
	containerBuilder.registerInstance<UserPaths>(
		localContainer->resolve<UserPaths>())->
		as<UserPaths>()->
		singleInstance();
	containerBuilder.registerType<BUNDLEPATHSCLASS>()->
	        as<BundlePaths>()->
	        singleInstance();
	containerBuilder.registerType<Log4cppLoggerFactory>(CREATE(new Log4cppLoggerFactory(INJECT(UserPaths))))->
	        as<LoggerFactory>()->
	        singleInstance();
	containerBuilder.registerInstance(pr)->
		as<PropertyResolver>()->
		singleInstance();
	containerBuilder.registerType<CurlFileDownloaderFactory>(
		CREATE(new CurlFileDownloaderFactory(INJECT(LoggerFactory), INJECT(PropertyResolver), INJECT(UserPaths))))->
		as<FileDownloaderFactory>()->
		singleInstance();
	containerBuilder.registerType<THREADHELPERCLASS>()->
		as<NativeThreadHelper>()->
	        singleInstance();
	containerBuilder.registerType<StdCpp11ThreadManager>(
		CREATE(new StdCpp11ThreadManager(INJECT(NativeThreadHelper),
	                                     INJECT(LoggerFactory))))->
		as<ThreadManager>()->
		as<ThreadFactory>()->
		singleInstance();

	containerBuilder.registerType<StoreManager>(CREATE(new StoreManager(INJECT(LoggerFactory), INJECT(BundlePaths), INJECT(FileDownloaderFactory))))->
		as<StoreManager>()->
		singleInstance();

	containerBuilder.registerType<StoreControllerImpl>(CREATE(new StoreControllerImpl(INJECT(StoreManager))))->
		as<StoreController>()->
		singleInstance();
#pragma GCC diagnostic pop
	container = containerBuilder.build();

	std::shared_ptr<gamekeeper::core::LoggerFactory> loggerFactory = container->resolve<gamekeeper::core::LoggerFactory>();
	loggerFactory->getComponentLogger("main") << gamekeeper::core::LogLevel::Debug << "firing up GameKeeper" << gamekeeper::core::endl;

	this->gameKeeperUI = instanceFuncPtr(loggerFactory->getComponentLogger("UI.client"));
	this->gameKeeperUI->init(vm);
	this->gameKeeperUI->startEventLoop();

	std::shared_ptr<gamekeeper::core::ThreadManager> threadManager = container->resolve<gamekeeper::core::ThreadManager>();
	threadManager->interruptAll();
	for(int8_t count = 0; count < 5 && !threadManager->tryJoinFor(2000); count++){}

	this->gameKeeperUI->onShutdown();
	delete this->gameKeeperUI;

	return EXIT_SUCCESS;
}

Hypodermic::IContainer&
HypodermicUtil::getContainer()
{
	return *container;
}

GAMEKEEPER_NAMESPACE_END(client)
<commit_msg>client/runtime: implement filelayout.bundle auto and FHS<commit_after>/*
 * GameKeeper Framework
 *
 * Copyright (C) 2013 Karol Herbst <gamekeeper@karolherbst.de>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "runtime.h"

#include <cstdlib>
#include <iostream>

#include <boost/filesystem/operations.hpp>
#include <boost/program_options/options_description.hpp>
#include <boost/program_options/parsers.hpp>
#include <boost/program_options/variables_map.hpp>

#include <Hypodermic/ContainerBuilder.h>
#include <Hypodermic/Helpers.h>

#include <gamekeeper/backend/storemanager.h>
#include <gamekeeper/client/gamekeeper.h>
#include <gamekeeper/client/hypodermic.h>
#include <gamekeeper/client/storecontrollerimpl.h>
#include <gamekeeper/core/logger.h>
#include <gamekeeper/core/loggerStream.h>
#include <gamekeeper/core/boostpopropertyresolver.h>
#include <gamekeeper/core/curlfiledownloaderfactory.h>
#include <gamekeeper/core/gnuinstalldirspaths.h>
#include <gamekeeper/core/log4cpploggerFactory.h>
#include <gamekeeper/core/stdc++11threadmanager.h>
#include <gamekeeper/core/xdgpaths.h>

// some platform dependent stuff
#ifdef GAMEKEEPER_OS_IS_WINDOWS
  #include <gamekeeper/core/win32threadhelper.h>
  #include <gamekeeper/core/windowsinformation.h>
  #define OSINFORMATIONCLASS WindowsInformation
  #define THREADHELPERCLASS Win32ThreadHelper
#else
  #include <gamekeeper/core/linuxinformation.h>
  #include <gamekeeper/core/pthreadhelper.h>
  #define OSINFORMATIONCLASS LinuxInformation
  #define THREADHELPERCLASS PthreadHelper
#endif

namespace fs = boost::filesystem;
namespace po = boost::program_options;

GAMEKEEPER_NAMESPACE_START(client)

static std::shared_ptr<Hypodermic::IContainer> localContainer;
static std::shared_ptr<Hypodermic::IContainer> container;

GameKeeperRuntime::GameKeeperRuntime()
{
	using namespace gamekeeper::core;
	Hypodermic::ContainerBuilder containerBuilder;

	// set up pre IoC container
	containerBuilder.registerType<OSINFORMATIONCLASS>()->
		as<OSInformation>()->
		singleInstance();
	containerBuilder.registerType<XDGPaths>(CREATE(new XDGPaths(INJECT(OSInformation))))->
		as<UserPaths>()->
		singleInstance();
	localContainer = containerBuilder.build();
}

static void
fillProperties(po::options_description & cmd, po::options_description & file)
{
	po::options_description descGlobalCmd("Global options");
	po::options_description descNetwork("Network options");

	descGlobalCmd.add_options()
		("help,h", "produce help message");

	descNetwork.add_options()
		("filelayout.bundle", po::value<std::string>()->default_value("auto"))
		("network.debug", po::value<bool>()->default_value(false)->implicit_value(true))
		("network.time_between_retries", po::value<uint16_t>()->default_value(300))
		("network.user_agent", po::value<std::string>())
		("network.resolve.retries", po::value<uint16_t>()->default_value(3))
		("network.resolve.timeout", po::value<uint16_t>()->default_value(5000))
		("network.connection.retries", po::value<uint16_t>()->default_value(3))
		("network.connection.timeout", po::value<uint16_t>()->default_value(30000))
		("network.download.max_buffer_size", po::value<uint32_t>()->default_value(2048));

	cmd.add(descGlobalCmd);
	cmd.add(descNetwork);
	file.add(descNetwork);
}

int
GameKeeperRuntime::main(int argc, const char* argv[], NewInstanceFuncPtr instanceFuncPtr, AddOptionsFuncPtr optionsFuncPtr)
{
	using namespace gamekeeper::backend;
	using namespace gamekeeper::client;
	using namespace gamekeeper::core;

	po::options_description descCmd;
	po::options_description descFile;

	fillProperties(descCmd, descFile);

	po::options_description cmdClient("Client options");
	po::options_description fileClient;
	po::options_description bothClient;
	po::options_description_easy_init cmdClientEasy = cmdClient.add_options();
	po::options_description_easy_init fileClientEasy = fileClient.add_options();
	po::options_description_easy_init bothClientEasy = bothClient.add_options();

	if(optionsFuncPtr != nullptr)
	{
		optionsFuncPtr(cmdClientEasy, fileClientEasy, bothClientEasy);
	}

	if(!bothClient.options().empty())
	{
		cmdClient.add(bothClient);
		fileClient.add(bothClient);
	}

	if(!cmdClient.options().empty())
	{
		descCmd.add(cmdClient);
	}

	if(!fileClient.options().empty())
	{
		descFile.add(fileClient);
	}

	po::variables_map vm;
	po::store(po::parse_command_line(argc, argv, descCmd), vm);

	fs::path configFile = localContainer->resolve<UserPaths>()->getConfigFile("properties.conf");
	if(fs::exists(configFile))
	{
		po::store(po::parse_config_file<char>(configFile.string().c_str(), descFile, true), vm);
	}

	if(vm.count("help") > 0)
	{
		std::cout << descCmd << std::endl;
		return EXIT_SUCCESS;
	}

	po::notify(vm);

	// build our property resolver now
	std::shared_ptr<PropertyResolver> pr = std::make_shared<BoostPOPropertyResolver>(vm);

	Hypodermic::ContainerBuilder containerBuilder;
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
	// set up the real IoC container

	// reuse instances from the pre container
	containerBuilder.registerInstance<OSInformation>(
		localContainer->resolve<OSInformation>())->
		as<OSInformation>()->
		singleInstance();
	containerBuilder.registerInstance<UserPaths>(
		localContainer->resolve<UserPaths>())->
		as<UserPaths>()->
		singleInstance();

	std::string bundleLayout = pr->get<std::string>("filelayout.bundle");

	if(bundleLayout == "auto")
	{
#if defined(GAMEKEEPER_OS_IS_LINUX)
		bundleLayout = "FHS";
#endif
	}
	if(bundleLayout == "FHS")
	{
		containerBuilder.registerType<GNUInstallDirsPaths>()->
			as<BundlePaths>()->
			singleInstance();
	}

	containerBuilder.registerType<Log4cppLoggerFactory>(CREATE(new Log4cppLoggerFactory(INJECT(UserPaths))))->
	        as<LoggerFactory>()->
	        singleInstance();
	containerBuilder.registerInstance(pr)->
		as<PropertyResolver>()->
		singleInstance();
	containerBuilder.registerType<CurlFileDownloaderFactory>(
		CREATE(new CurlFileDownloaderFactory(INJECT(LoggerFactory), INJECT(PropertyResolver), INJECT(UserPaths))))->
		as<FileDownloaderFactory>()->
		singleInstance();
	containerBuilder.registerType<THREADHELPERCLASS>()->
		as<NativeThreadHelper>()->
	        singleInstance();
	containerBuilder.registerType<StdCpp11ThreadManager>(
		CREATE(new StdCpp11ThreadManager(INJECT(NativeThreadHelper),
	                                     INJECT(LoggerFactory))))->
		as<ThreadManager>()->
		as<ThreadFactory>()->
		singleInstance();

	containerBuilder.registerType<StoreManager>(CREATE(new StoreManager(INJECT(LoggerFactory), INJECT(BundlePaths), INJECT(FileDownloaderFactory))))->
		as<StoreManager>()->
		singleInstance();

	containerBuilder.registerType<StoreControllerImpl>(CREATE(new StoreControllerImpl(INJECT(StoreManager))))->
		as<StoreController>()->
		singleInstance();
#pragma GCC diagnostic pop
	container = containerBuilder.build();

	std::shared_ptr<gamekeeper::core::LoggerFactory> loggerFactory = container->resolve<gamekeeper::core::LoggerFactory>();
	loggerFactory->getComponentLogger("main") << gamekeeper::core::LogLevel::Debug << "firing up GameKeeper" << gamekeeper::core::endl;

	this->gameKeeperUI = instanceFuncPtr(loggerFactory->getComponentLogger("UI.client"));
	this->gameKeeperUI->init(vm);
	this->gameKeeperUI->startEventLoop();

	std::shared_ptr<gamekeeper::core::ThreadManager> threadManager = container->resolve<gamekeeper::core::ThreadManager>();
	threadManager->interruptAll();
	for(int8_t count = 0; count < 5 && !threadManager->tryJoinFor(2000); count++){}

	this->gameKeeperUI->onShutdown();
	delete this->gameKeeperUI;

	return EXIT_SUCCESS;
}

Hypodermic::IContainer&
HypodermicUtil::getContainer()
{
	return *container;
}

GAMEKEEPER_NAMESPACE_END(client)
<|endoftext|>


<commit_before>// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
/*
 * Ceph - scalable distributed file system
 *
 * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
 *
 * This is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License version 2.1, as published by the Free Software
 * Foundation.  See file COPYING.
 *
 */

#include "common/errno.h"
#include "include/ceph/libceph.h"
#include <stdlib.h>

#include <errno.h>
#include <dirent.h>
#include <iostream>
#include <fcntl.h>
#include <sys/xattr.h>
#include <string.h>

using std::cout;
using std::cerr;

int main(int argc, const char **argv)
{
  struct ceph_mount_info *cmount;
    cout << "calling ceph_create..." << std::endl;
  int my_fd;
  int ret = ceph_create(&cmount, NULL);
  if (ret) {
    cerr << "ceph_create failed with error: " << ret << std::endl;
    return 1;
  }
    cout << "calling ceph_conf_read_file..." << ret << std::endl;
  ceph_conf_read_file(cmount, NULL);
    cout << "calling ceph_conf_parse_argv..." << ret << std::endl;
  ceph_conf_parse_argv(cmount, argc, argv);

  char buf[128];
    cout << "calling ceph_conf_get..." << ret << std::endl;
  ret = ceph_conf_get(cmount, "log file", buf, sizeof(buf));
  if (ret) {
    cerr << "ceph_conf_get(\"log file\") failed with error " << ret << std::endl;
  }
  else {
    cout << "log_file = \"" << buf << "\"" << std::endl;
  }

  ret = ceph_mount(cmount, NULL);
  if (ret) {
    cerr << "ceph_mount error: " << ret << std::endl;
    return 1;
  }
  cout << "Successfully mounted Ceph!" << std::endl;

  // what if foo is already there???
  struct ceph_dir_result *foo_dir;
  ret = ceph_opendir(cmount, "foo", &foo_dir);
  if (ret != -ENOENT) {
    cerr << "ceph_opendir error: unexpected result from trying to open foo: "
	 << cpp_strerror(ret) << std::endl;
    return 1;
  } else {
    cout << "ceph_opendir: success" << std::endl;
  }
  //ret = ceph_closedir(cmount, foo_dir);
  //if (ret == 0) {
  //  cerr << "ceph_closedir success" << std::endl;
  //} else {
  //  cerr << "ceph_closedir error: " << cpp_strerror(ret) << std::endl;
  //}
  ret = ceph_mkdir(cmount, "foo",  0777);
  if (ret) {
    cerr << "ceph_mkdir error: " << cpp_strerror(ret) << std::endl;
    return 1;
  } else {
    cout << "ceph_mkdir: success" << std::endl;
  }

  struct stat stbuf;
  ret = ceph_lstat(cmount, "foo", &stbuf);
  if (ret) {
    cerr << "ceph_lstat error: " << cpp_strerror(ret) << std::endl;
    return 1;
  } else {
    cout << "ceph_lstat: success" << std::endl;
  }

  if (!S_ISDIR(stbuf.st_mode)) {
    cerr << "ceph_lstat(foo): foo is not a directory? st_mode = "
	 << stbuf.st_mode << std::endl;
    return 1;
  } else {
    cout << "ceph_lstat: mode success" << std::endl;
  }

  ret = ceph_rmdir(cmount, "foo");
  if (ret) {
    cerr << "ceph_rmdir error: " << cpp_strerror(ret) << std::endl;
    return 1;
  } else {
    cout << "ceph_rmdir: success" << std::endl;
  }

  ret = ceph_mkdirs(cmount, "foo/bar/baz",  0777);
  if (ret) {
    cerr << "ceph_mkdirs error: " << cpp_strerror(ret) << std::endl;
    return 1;
  } else {
    cout << "ceph_mkdirs: success" << std::endl;
  }
  ret = ceph_rmdir(cmount, "foo/bar/baz");
  if (ret) {
    cerr << "ceph_rmdir error: " << cpp_strerror(ret) << std::endl;
    return 1;
  } else {
    cout << "ceph_rmdir: success" << std::endl;
  }
  ret = ceph_rmdir(cmount, "foo/bar");
  if (ret) {
    cerr << "ceph_rmdir error: " << cpp_strerror(ret) << std::endl;
    return 1;
  } else {
    cout << "ceph_rmdir: success" << std::endl;
  }
  ret = ceph_rmdir(cmount, "foo");
  if (ret) {
    cerr << "ceph_rmdir error: " << cpp_strerror(ret) << std::endl;
    return 1;
  } else {
    cout << "ceph_rmdir: success" << std::endl;
  }
  my_fd = ret = ceph_open(cmount, "barfile", O_CREAT, 0666);
  if (ret < 0) {
    cerr << "ceph_open O_CREAT error: " << cpp_strerror(ret) << std::endl;
    return 1;
  } else {
    cout << "ceph_open: success" << std::endl;
  }
  ret = ceph_setxattr(cmount, "barfile", "user.testxattr", (void *) "AYBABTU", 7, XATTR_CREATE);
  if (ret < 0) {
    cerr << "ceph_setxattr error: " << cpp_strerror(ret) << std::endl;
    return 1;
  } else {
    cout << "ceph_setxattr: success" << std::endl;
  }
  char *outlist;
  outlist = (char *) malloc(256);
  ret = ceph_listxattr(cmount, "barfile", outlist, 0);
  free(outlist);
  if (ret < 1) {
    cerr << "ceph_listxattr error (a): should have returned > 0" << cpp_strerror(ret) << std::endl;
    return 1;
  } else {
    cout << "ceph_listxattr: success" << std::endl;
  }

  outlist = (char *) malloc(ret);
  ret = ceph_listxattr(cmount, "barfile", outlist, ret);
  if (ret < 1) {
    cerr << "ceph_listxattr error (b): should have returned > 0" << cpp_strerror(ret) << std::endl;
    return 1;
  } else {
    cout << "ceph_listxattr: success" << std::endl;
  }
  void *aybabtu;
  aybabtu = malloc(8);
  ret = ceph_getxattr(cmount, "barfile", "user.testxattr", aybabtu, 7);
  if (ret < 1) {
    cerr << "ceph_getxattr error: " << cpp_strerror(ret) << std::endl;
    return 1;
  } else {
    cout << "ceph_getxattr: success" << std::endl;
  }
  char aybabtu_reference[]="AYBABTU";
  if (strncmp((char *) aybabtu, aybabtu_reference,7)) {
    cerr << "ceph_getxattr error: no match (" << aybabtu << ") should be (" << aybabtu_reference << cpp_strerror(ret) << std::endl;
  }
  ret = ceph_close(cmount,my_fd);
  if (ret < 0) {
    cerr << "ceph_close error: " << cpp_strerror(ret) << std::endl;
    return 1;
  } else {
    cout << "ceph_close: success" << std::endl;
  }

  cout << "Attempting lstat on '/.'" << std::endl;
  ret = ceph_lstat(cmount, "/.", &stbuf);
  if (ret) {
    cerr << "ceph_lstat error: " << cpp_strerror(ret) << std::endl;
    return 1;
  } else {
    cout << "ceph_lstat: success" << std::endl;
  }
  cout << "Attempting lstat on '.'" << std::endl;
  ret = ceph_lstat(cmount, ".", &stbuf);
  if (ret) {
    cerr << "ceph_lstat error: " << cpp_strerror(ret) << std::endl;
    return 1;
  } else {
    cout << "ceph_lstat: success" << std::endl;
  }
  cout << "Setting up readdir test" << std::endl;
  ret = ceph_mkdir(cmount, "readdir_test",  0777);
  if (ret) {
    cerr << "ceph_mkdir error: " << cpp_strerror(ret) << std::endl;
    return 1;
  } else {
    cout << "ceph_mkdir: success" << std::endl;
  }
  my_fd = ret = ceph_open(cmount, "readdir_test/opened_file_1", O_CREAT, 0666);
  if (ret < 0) {
    cerr << "ceph_open O_CREAT error: " << cpp_strerror(ret) << std::endl;
    return 1;
  } else {
    cout << "ceph_open: success" << std::endl;
  }
  ret = ceph_close(cmount, my_fd);
  if (ret < 0) {
    cerr << "ceph_close error: " << cpp_strerror(ret) << std::endl;
    return 1;
  } else {
    cout << "ceph_close: success" << std::endl;
  }

  struct ceph_dir_result *readdir_test_dir;
  ret = ceph_opendir(cmount, "readdir_test", &readdir_test_dir);
  if (ret != 0) {
    cerr << "ceph_opendir error: unexpected result from trying to open readdir_test: "
	 << cpp_strerror(ret) << std::endl;
    return 1;
  } else {
    cout << "ceph_opendir: success" << std::endl;
  }
  cout << "Attempting readdir on opened directory..." << std::endl;
  struct dirent * result;
  //result = (struct dirent *) malloc(sizeof(struct dirent));
  result = ceph_readdir(cmount, readdir_test_dir);
  if (result == (dirent *) NULL) {
    cout << "ceph_readdir: failed to read any entries" << std::endl;
  }
  loff_t telldir_result;
  while ( result != (dirent *) NULL) {
    cout << "ceph_readdir: dirent->d_name: (" << result->d_name << ")" << std::endl;
    cout << "ceph_telldir: starting" << std::endl;
    telldir_result = ceph_telldir(cmount, readdir_test_dir);
    if (telldir_result > -1) {
      cout << "ceph_telldir: offset: from return code:" << telldir_result << std::endl;
    } else {
      cout << "ceph_telldir: failed" << std::endl;
    }
    cout << "ceph_readdir: lookup success: trying for another..." << std::endl;
    result = ceph_readdir(cmount, readdir_test_dir);
  }
  cout << "ceph_readdir: finished" << std::endl;

  // tell us that we're at the end of the directory:
  cout << "ceph_telldir: starting" << std::endl;
  telldir_result = ceph_telldir(cmount, readdir_test_dir);
  if (telldir_result > -1) {
    cout << "ceph_telldir: offset: from return code:" << telldir_result << std::endl;
  } else {
    cout << "ceph_telldir: failed" << std::endl;
  }

  ret = ceph_closedir(cmount,readdir_test_dir);
  if (ret == 0) {
    cerr << "ceph_closedir success" << std::endl;
  } else {
    cerr << "ceph_closedir error: " << cpp_strerror(ret) << std::endl;
  }

  ceph_shutdown(cmount);

  return 0;
}
<commit_msg>testceph: expand test cases<commit_after>// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
/*
 * Ceph - scalable distributed file system
 *
 * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
 *
 * This is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License version 2.1, as published by the Free Software
 * Foundation.  See file COPYING.
 *
 */

#include "common/errno.h"
#include "include/ceph/libceph.h"
#include <stdlib.h>

#include <errno.h>
#include <dirent.h>
#include <iostream>
#include <fcntl.h>
#include <sys/xattr.h>
#include <string.h>

using std::cout;
using std::cerr;

int main(int argc, const char **argv)
{
  struct ceph_mount_info *cmount;
    cout << "calling ceph_create..." << std::endl;
  int my_fd;
  int ret = ceph_create(&cmount, NULL);
  if (ret) {
    cerr << "ceph_create failed with error: " << ret << std::endl;
    return 1;
  }
    cout << "calling ceph_conf_read_file..." << ret << std::endl;
  ceph_conf_read_file(cmount, NULL);
    cout << "calling ceph_conf_parse_argv..." << ret << std::endl;
  ceph_conf_parse_argv(cmount, argc, argv);

  char buf[128];
    cout << "calling ceph_conf_get..." << ret << std::endl;
  ret = ceph_conf_get(cmount, "log file", buf, sizeof(buf));
  if (ret) {
    cerr << "ceph_conf_get(\"log file\") failed with error " << ret << std::endl;
  }
  else {
    cout << "log_file = \"" << buf << "\"" << std::endl;
  }

  ret = ceph_mount(cmount, NULL);
  if (ret) {
    cerr << "ceph_mount error: " << ret << std::endl;
    return 1;
  }
  cout << "Successfully mounted Ceph!" << std::endl;

  // what if foo is already there???
  struct ceph_dir_result *foo_dir = NULL;
  ret = ceph_opendir(cmount, "foo", &foo_dir);
  if (ret != -ENOENT) {
    cerr << "ceph_opendir error: unexpected result from trying to open foo: "
	 << cpp_strerror(ret) << std::endl;
    return 1;
  } else {
    cout << "ceph_opendir: success, foo does not exist" << std::endl;
  }

  // Can't close a dir that is not open!
  //ret = ceph_closedir(cmount, foo_dir);
  //if (ret == 0) {
  //  cerr << "ceph_closedir success" << std::endl;
  //} else {
  //  cerr << "ceph_closedir error: " << cpp_strerror(ret) << std::endl;
  //}
  //
  ret = ceph_mkdir(cmount, "foo",  0777);
  if (ret) {
    cerr << "ceph_mkdir error: " << cpp_strerror(ret) << std::endl;
    return 1;
  } else {
    cout << "ceph_mkdir: success" << std::endl;
  }

  struct stat stbuf;
  ret = ceph_lstat(cmount, "foo", &stbuf);
  if (ret) {
    cerr << "ceph_lstat error: " << cpp_strerror(ret) << std::endl;
    return 1;
  } else {
    cout << "ceph_lstat: success" << std::endl;
  }

  if (!S_ISDIR(stbuf.st_mode)) {
    cerr << "ceph_lstat(foo): foo is not a directory? st_mode = "
	 << stbuf.st_mode << std::endl;
    return 1;
  } else {
    cout << "ceph_lstat: mode success" << std::endl;
  }

  ret = ceph_rmdir(cmount, "foo");
  if (ret) {
    cerr << "ceph_rmdir error: " << cpp_strerror(ret) << std::endl;
    return 1;
  } else {
    cout << "ceph_rmdir: success" << std::endl;
  }

  ret = ceph_mkdirs(cmount, "foo/bar/baz",  0777);
  if (ret) {
    cerr << "ceph_mkdirs error: " << cpp_strerror(ret) << std::endl;
    return 1;
  } else {
    cout << "ceph_mkdirs: success" << std::endl;
  }

  // Should test .. as well!

  cout << "testing chdir on foo/bar/baz";
  ret = ceph_chdir(cmount, "foo/bar/baz");
  if (ret) {
    cerr << ": failed: " << cpp_strerror(ret) << std::endl;
    return 1;
  }

  cout << " success!" << std::endl;

  // Now, try absolute
  cout << "testing chdir to /foo/bar";
  ret = ceph_chdir(cmount, "/foo/bar");
  if (ret) {
    cerr << ": failed: " << cpp_strerror(ret) << std::endl;
    return 1;
  }

  cout << " success!" << std::endl;

  // Now, back to the top
  cout << "testing chdir to /";
  ret = ceph_chdir(cmount, "/");
  if (ret) {
    cerr << ": failed: " << cpp_strerror(ret) << std::endl;
    return 1;
  }

  cout << "success!" << std::endl;

  ret = ceph_rmdir(cmount, "foo/bar/baz");
  if (ret) {
    cerr << "ceph_rmdir error: " << cpp_strerror(ret) << std::endl;
    return 1;
  } else {
    cout << "ceph_rmdir: success" << std::endl;
  }
  ret = ceph_rmdir(cmount, "foo/bar");
  if (ret) {
    cerr << "ceph_rmdir error: " << cpp_strerror(ret) << std::endl;
    return 1;
  } else {
    cout << "ceph_rmdir: success" << std::endl;
  }
  ret = ceph_rmdir(cmount, "foo");
  if (ret) {
    cerr << "ceph_rmdir error: " << cpp_strerror(ret) << std::endl;
    return 1;
  } else {
    cout << "ceph_rmdir: success" << std::endl;
  }
  my_fd = ret = ceph_open(cmount, "barfile", O_CREAT, 0666);
  if (ret < 0) {
    cerr << "ceph_open O_CREAT error: " << cpp_strerror(ret) << std::endl;
    return 1;
  } else {
    cout << "ceph_open: success" << std::endl;
  }
  ret = ceph_setxattr(cmount, "barfile", "user.testxattr", (void *) "AYBABTU", 7, XATTR_CREATE);
  if (ret < 0) {
    cerr << "ceph_setxattr error: " << cpp_strerror(ret) << std::endl;
    return 1;
  } else {
    cout << "ceph_setxattr: success" << std::endl;
  }
  char *outlist;
  outlist = (char *) malloc(256);
  ret = ceph_listxattr(cmount, "barfile", outlist, 0);
  free(outlist);
  if (ret < 1) {
    cerr << "ceph_listxattr error (a): should have returned > 0" << cpp_strerror(ret) << std::endl;
    return 1;
  } else {
    cout << "ceph_listxattr: success" << std::endl;
  }

  outlist = (char *) malloc(ret);
  ret = ceph_listxattr(cmount, "barfile", outlist, ret);
  if (ret < 1) {
    cerr << "ceph_listxattr error (b): should have returned > 0" << cpp_strerror(ret) << std::endl;
    return 1;
  } else {
    cout << "ceph_listxattr: success" << std::endl;
  }
  void *aybabtu;
  aybabtu = malloc(8);
  ret = ceph_getxattr(cmount, "barfile", "user.testxattr", aybabtu, 7);
  if (ret < 1) {
    cerr << "ceph_getxattr error: " << cpp_strerror(ret) << std::endl;
    return 1;
  } else {
    cout << "ceph_getxattr: success" << std::endl;
  }
  char aybabtu_reference[]="AYBABTU";
  if (strncmp((char *) aybabtu, aybabtu_reference,7)) {
    cerr << "ceph_getxattr error: no match (" << aybabtu << ") should be (" << aybabtu_reference << cpp_strerror(ret) << std::endl;
  }
  ret = ceph_close(cmount,my_fd);
  if (ret < 0) {
    cerr << "ceph_close error: " << cpp_strerror(ret) << std::endl;
    return 1;
  } else {
    cout << "ceph_close: success" << std::endl;
  }

  cout << "Attempting lstat on '/.'" << std::endl;
  ret = ceph_lstat(cmount, "/.", &stbuf);
  if (ret) {
    cerr << "ceph_lstat error: " << cpp_strerror(ret) << std::endl;
    return 1;
  } else {
    cout << "ceph_lstat: success" << std::endl;
  }
  cout << "Attempting lstat on '.'" << std::endl;
  ret = ceph_lstat(cmount, ".", &stbuf);
  if (ret) {
    cerr << "ceph_lstat error: " << cpp_strerror(ret) << std::endl;
    return 1;
  } else {
    cout << "ceph_lstat: success" << std::endl;
  }
  cout << "Setting up readdir test" << std::endl;
  ret = ceph_mkdir(cmount, "readdir_test",  0777);
  if (ret) {
    cerr << "ceph_mkdir error: " << cpp_strerror(ret) << std::endl;
    return 1;
  } else {
    cout << "ceph_mkdir: success" << std::endl;
  }
  my_fd = ret = ceph_open(cmount, "readdir_test/opened_file_1", O_CREAT, 0666);
  if (ret < 0) {
    cerr << "ceph_open O_CREAT error: " << cpp_strerror(ret) << std::endl;
    return 1;
  } else {
    cout << "ceph_open: success" << std::endl;
  }
  ret = ceph_close(cmount, my_fd);
  if (ret < 0) {
    cerr << "ceph_close error: " << cpp_strerror(ret) << std::endl;
    return 1;
  } else {
    cout << "ceph_close: success" << std::endl;
  }

  struct ceph_dir_result *readdir_test_dir;
  ret = ceph_opendir(cmount, "readdir_test", &readdir_test_dir);
  if (ret != 0) {
    cerr << "ceph_opendir error: unexpected result from trying to open readdir_test: "
	 << cpp_strerror(ret) << std::endl;
    return 1;
  } else {
    cout << "ceph_opendir: success" << std::endl;
  }
  cout << "Attempting readdir on opened directory..." << std::endl;
  struct dirent * result;
  //result = (struct dirent *) malloc(sizeof(struct dirent));
  result = ceph_readdir(cmount, readdir_test_dir);
  if (result == (dirent *) NULL) {
    cout << "ceph_readdir: failed to read any entries" << std::endl;
  }
  loff_t telldir_result;
  while ( result != (dirent *) NULL) {
    cout << "ceph_readdir: dirent->d_name: (" << result->d_name << ")" << std::endl;
    cout << "ceph_telldir: starting" << std::endl;
    telldir_result = ceph_telldir(cmount, readdir_test_dir);
    if (telldir_result > -1) {
      cout << "ceph_telldir: offset: from return code:" << telldir_result << std::endl;
    } else {
      cout << "ceph_telldir: failed" << std::endl;
    }
    cout << "ceph_readdir: lookup success: trying for another..." << std::endl;
    result = ceph_readdir(cmount, readdir_test_dir);
  }
  cout << "ceph_readdir: finished" << std::endl;

  // tell us that we're at the end of the directory:
  cout << "ceph_telldir: starting" << std::endl;
  telldir_result = ceph_telldir(cmount, readdir_test_dir);
  if (telldir_result > -1) {
    cout << "ceph_telldir: offset: from return code:" << telldir_result << std::endl;
  } else {
    cout << "ceph_telldir: failed" << std::endl;
  }

  ret = ceph_closedir(cmount,readdir_test_dir);
  if (ret == 0) {
    cerr << "ceph_closedir success" << std::endl;
  } else {
    cerr << "ceph_closedir error: " << cpp_strerror(ret) << std::endl;
  }

  ceph_shutdown(cmount);

  return 0;
}
<|endoftext|>


<commit_before>
#include "utils/macros.hpp"
#include "utils/Logger.hpp"
#include "core/Server.hpp"
#include "core/ServerState.hpp"
#include "utils/StatsManager.hpp"

ZHTTPD::Server* server;

#ifndef WIN32
# include <signal.h>
void sigint(int)
{
    if (server != 0)
    {
        LOG_INFO("Stopping server now");
        server->stop();
    }
}

void sigpipe(int)
{
    LOG_WARN("Broken pipe catched");
}
#endif

int main(int argc, char **argv)
{
#ifdef ZHTTPD_DEBUG
    ZHTTPD_DEBUG_init();
#endif

    std::cout << "ZHTTPD Server v0.1 "
#ifdef ZHTTPD_DEBUG
              << "(DEBUG)"
#else
              << "(RELEASE)"
#endif
              << std::endl;

#ifndef ZHTTPD_DEBUG
     ZHTTPD::Logger::getInstance()->setLevel(ZHTTPD::Logger::LVL_INFO);
#endif
    server = new ZHTTPD::Server();
#ifndef WIN32
    (void) signal(SIGINT, sigint);
    (void) signal(SIGPIPE, sigpipe);
#endif

    LOG_INFO("Server is starting");
    ZHTTPD::StatsManager::getInstance();
    int res = server->run(argc > 1 ? argv[1] : "doc/conf.xml");

#ifdef ZHTTPD_DEBUG
    ZHTTPD_DEBUG_print_maps();
    ZHTTPD_DEBUG_release();
    std::cout << "Uptime: " << ((double) ZHTTPD::StatsManager::getInstance()->getUptime()) / 1000.0f
              << " sec" << std::endl;
#endif
    delete server;
    server = 0;
    ZHTTPD::StatsManager::delInstance();
    ZHTTPD::Logger::delInstance();
    return res;
}
<commit_msg>Using ZHTTPD_FULLNAME everywhere :)<commit_after>
#include "utils/macros.hpp"
#include "utils/Logger.hpp"
#include "core/Server.hpp"
#include "core/ServerState.hpp"
#include "utils/StatsManager.hpp"

ZHTTPD::Server* server;

#ifndef WIN32
# include <signal.h>
void sigint(int)
{
    if (server != 0)
    {
        LOG_INFO("Stopping server now");
        server->stop();
    }
}

void sigpipe(int)
{
    LOG_WARN("Broken pipe catched");
}
#endif

int main(int argc, char **argv)
{
#ifdef ZHTTPD_DEBUG
    ZHTTPD_DEBUG_init();
#endif
    std::cout << "Starting " << ZHTTPD_FULLNAME << " "
#ifdef ZHTTPD_DEBUG
              << "(DEBUG)"
#else
              << "(RELEASE)"
#endif
              << std::endl;

#ifndef ZHTTPD_DEBUG
     ZHTTPD::Logger::getInstance()->setLevel(ZHTTPD::Logger::LVL_INFO);
#endif
    server = new ZHTTPD::Server();
#ifndef WIN32
    (void) signal(SIGINT, sigint);
    (void) signal(SIGPIPE, sigpipe);
#endif

    LOG_INFO("Server is starting");
    ZHTTPD::StatsManager::getInstance();
    int res = server->run(argc > 1 ? argv[1] : "doc/conf.xml");

#ifdef ZHTTPD_DEBUG
    ZHTTPD_DEBUG_print_maps();
    ZHTTPD_DEBUG_release();
    std::cout << "Uptime: " << ((double) ZHTTPD::StatsManager::getInstance()->getUptime()) / 1000.0f
              << " sec" << std::endl;
#endif
    delete server;
    server = 0;
    ZHTTPD::StatsManager::delInstance();
    ZHTTPD::Logger::delInstance();
    return res;
}
<|endoftext|>


<commit_before>/*
 * (C) Copyright 2013 Kurento (http://kurento.org/)
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser General Public License
 * (LGPL) version 2.1 which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/lgpl-2.1.html
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 */

#include <config.h>

#include <glibmm.h>
#include <fstream>
#include <iostream>
#include <boost/filesystem.hpp>
#include "version.hpp"
#include <glib/gstdio.h>
#include <ftw.h>

#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>

#include "TransportFactory.hpp"

#include <SignalHandler.hpp>
#include <ServerMethods.hpp>
#include <gst/gst.h>

#include <boost/program_options.hpp>
#include <boost/exception/diagnostic_information.hpp>

#include "logging.hpp"
#include "modules.hpp"

#define GST_CAT_DEFAULT kurento_media_server
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
#define GST_DEFAULT_NAME "KurentoMediaServer"

const std::string DEFAULT_CONFIG_FILE = "/etc/kurento/kurento.conf.json";
const std::string ENV_PREFIX = "KURENTO_";

using namespace ::kurento;

Glib::RefPtr<Glib::MainLoop> loop = Glib::MainLoop::create ();

static std::shared_ptr<Transport>
load_config (boost::property_tree::ptree &config, const std::string &file_name)
{
  std::shared_ptr<Transport> transport;
  boost::filesystem::path configFilePath (file_name);
  GST_INFO ("Reading configuration from: %s", file_name.c_str () );

  try {
    boost::property_tree::read_json (file_name, config);
  } catch (boost::property_tree::ptree_error &e) {
    GST_ERROR ("Error reading configuration: %s", e.what() );
    std::cerr << "Error reading configuration: " << e.what() << std::endl;
    exit (1);
  }

  config.add ("configPath", configFilePath.parent_path().string() );

  GST_INFO ("Configuration loaded successfully");

  std::shared_ptr<ServerMethods> serverMethods (new ServerMethods (config) );

  try {
    transport = TransportFactory::create_transport (config, serverMethods);
  } catch (std::exception &e) {
    GST_ERROR ("Error creating transport: %s", e.what() );
    exit (1);
  }

  return transport;
}

static void
signal_handler (uint32_t signo)
{
  static unsigned int __terminated = 0;

  switch (signo) {
  case SIGINT:
  case SIGTERM:
    if (__terminated == 0) {
      GST_DEBUG ("Terminating.");
      loop->quit ();
    }

    __terminated = 1;
    break;

  case SIGPIPE:
    GST_DEBUG ("Ignore sigpipe signal");
    break;

  case SIGSEGV:
    GST_DEBUG ("Segmentation fault. Aborting process execution");
    abort ();

  default:
    break;
  }
}

int
main (int argc, char **argv)
{
  sigset_t mask;
  std::shared_ptr <SignalHandler> signalHandler;
  std::shared_ptr<Transport> transport;
  boost::property_tree::ptree config;
  std::string confFile;
  std::string path;

  Glib::init();

  gst_init (&argc, &argv);
  GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, GST_DEFAULT_NAME, 0,
                           GST_DEFAULT_NAME);
  gst_debug_remove_log_function_by_data (NULL);
  gst_debug_add_log_function (log_function, NULL, NULL);

  try {
    boost::program_options::options_description desc ("kurento-media-server usage");

    desc.add_options()
    ("help,h", "Display this help message")
    ("version,v", "Display the version number")
    ("list,l", "Lists all available factories")
    ("modules-path,p", boost::program_options::value<std::string>
     (&path), "Path where kurento modules can be found")
    ("conf-file,f", boost::program_options::value<std::string>
     (&confFile)->default_value (DEFAULT_CONFIG_FILE),
     "Configuration file location");

    boost::program_options::command_line_parser clp (argc, argv);
    clp.options (desc).allow_unregistered();
    boost::program_options::variables_map vm;
    auto parsed = clp.run();
    boost::program_options::store (parsed, vm);

    boost::program_options::store (boost::program_options::parse_environment (desc,
    [&desc] (std::string & input) -> std::string {
      /* Look for KURENTO_ prefix and change to lower case */
      if (input.find (ENV_PREFIX) == 0) {
        std::string aux = input.substr (ENV_PREFIX.size() );
        std::transform (aux.begin(), aux.end(), aux.begin(), [] (int c) -> int {
          return (c == '_') ? '-' : tolower (c);
        });

        if (!desc.find_nothrow (aux, false) ) {
          return "";
        }

        return aux;
      }

      return "";
    }), vm);

    boost::program_options::notify (vm);

    if (vm.count ("help") ) {
      std::cout << desc << "\n";
      exit (0);
    }

    if (vm.count ("version") || vm.count ("list") ) {
      // Disable lot to just print version
      gst_debug_remove_log_function (log_function);
    }

    loadModules (path);

    if (vm.count ("list") ) {
      std::cout << "Available factories:" << std::endl;

      for (auto it : kurento::getModuleManager().getLoadedFactories() ) {
        std::cout << "\t" << it.first << std::endl;
      }

      exit (0);
    }

    if (vm.count ("version") ) {
      print_version();
      exit (0);
    }

  } catch (boost::program_options::error &e) {
    std::cerr <<  "Error : " << e.what() << std::endl;
    exit (1);
  }

  /* Install our signal handler */
  sigemptyset (&mask);
  sigaddset (&mask, SIGINT);
  sigaddset (&mask, SIGTERM);
  sigaddset (&mask, SIGSEGV);
  sigaddset (&mask, SIGPIPE);
  signalHandler = std::shared_ptr <SignalHandler> (new SignalHandler (mask,
                  signal_handler) );

  GST_INFO ("Kmsc version: %s", get_version () );

  transport = load_config (config, confFile);

  /* Start transport */
  transport->start ();

  GST_INFO ("Mediaserver started");

  loop->run ();

  signalHandler.reset();

  transport->stop();

  transport.reset();

  gst_debug_add_log_function (simple_log_function, NULL, NULL);
  gst_debug_remove_log_function (log_function);

  return 0;
}
<commit_msg>main: Shared pointer can be released when main function exites<commit_after>/*
 * (C) Copyright 2013 Kurento (http://kurento.org/)
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser General Public License
 * (LGPL) version 2.1 which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/lgpl-2.1.html
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 */

#include <config.h>

#include <glibmm.h>
#include <fstream>
#include <iostream>
#include <boost/filesystem.hpp>
#include "version.hpp"
#include <glib/gstdio.h>
#include <ftw.h>

#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>

#include "TransportFactory.hpp"

#include <SignalHandler.hpp>
#include <ServerMethods.hpp>
#include <gst/gst.h>

#include <boost/program_options.hpp>
#include <boost/exception/diagnostic_information.hpp>

#include "logging.hpp"
#include "modules.hpp"

#define GST_CAT_DEFAULT kurento_media_server
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
#define GST_DEFAULT_NAME "KurentoMediaServer"

const std::string DEFAULT_CONFIG_FILE = "/etc/kurento/kurento.conf.json";
const std::string ENV_PREFIX = "KURENTO_";

using namespace ::kurento;

Glib::RefPtr<Glib::MainLoop> loop = Glib::MainLoop::create ();

static std::shared_ptr<Transport>
load_config (boost::property_tree::ptree &config, const std::string &file_name)
{
  std::shared_ptr<Transport> transport;
  boost::filesystem::path configFilePath (file_name);
  GST_INFO ("Reading configuration from: %s", file_name.c_str () );

  try {
    boost::property_tree::read_json (file_name, config);
  } catch (boost::property_tree::ptree_error &e) {
    GST_ERROR ("Error reading configuration: %s", e.what() );
    std::cerr << "Error reading configuration: " << e.what() << std::endl;
    exit (1);
  }

  config.add ("configPath", configFilePath.parent_path().string() );

  GST_INFO ("Configuration loaded successfully");

  std::shared_ptr<ServerMethods> serverMethods (new ServerMethods (config) );

  try {
    transport = TransportFactory::create_transport (config, serverMethods);
  } catch (std::exception &e) {
    GST_ERROR ("Error creating transport: %s", e.what() );
    exit (1);
  }

  return transport;
}

static void
signal_handler (uint32_t signo)
{
  static unsigned int __terminated = 0;

  switch (signo) {
  case SIGINT:
  case SIGTERM:
    if (__terminated == 0) {
      GST_DEBUG ("Terminating.");
      loop->quit ();
    }

    __terminated = 1;
    break;

  case SIGPIPE:
    GST_DEBUG ("Ignore sigpipe signal");
    break;

  case SIGSEGV:
    GST_DEBUG ("Segmentation fault. Aborting process execution");
    abort ();

  default:
    break;
  }
}

int
main (int argc, char **argv)
{
  sigset_t mask;
  std::shared_ptr <SignalHandler> signalHandler;
  std::shared_ptr<Transport> transport;
  boost::property_tree::ptree config;
  std::string confFile;
  std::string path;

  Glib::init();

  gst_init (&argc, &argv);
  GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, GST_DEFAULT_NAME, 0,
                           GST_DEFAULT_NAME);
  gst_debug_remove_log_function_by_data (NULL);
  gst_debug_add_log_function (log_function, NULL, NULL);

  try {
    boost::program_options::options_description desc ("kurento-media-server usage");

    desc.add_options()
    ("help,h", "Display this help message")
    ("version,v", "Display the version number")
    ("list,l", "Lists all available factories")
    ("modules-path,p", boost::program_options::value<std::string>
     (&path), "Path where kurento modules can be found")
    ("conf-file,f", boost::program_options::value<std::string>
     (&confFile)->default_value (DEFAULT_CONFIG_FILE),
     "Configuration file location");

    boost::program_options::command_line_parser clp (argc, argv);
    clp.options (desc).allow_unregistered();
    boost::program_options::variables_map vm;
    auto parsed = clp.run();
    boost::program_options::store (parsed, vm);

    boost::program_options::store (boost::program_options::parse_environment (desc,
    [&desc] (std::string & input) -> std::string {
      /* Look for KURENTO_ prefix and change to lower case */
      if (input.find (ENV_PREFIX) == 0) {
        std::string aux = input.substr (ENV_PREFIX.size() );
        std::transform (aux.begin(), aux.end(), aux.begin(), [] (int c) -> int {
          return (c == '_') ? '-' : tolower (c);
        });

        if (!desc.find_nothrow (aux, false) ) {
          return "";
        }

        return aux;
      }

      return "";
    }), vm);

    boost::program_options::notify (vm);

    if (vm.count ("help") ) {
      std::cout << desc << "\n";
      exit (0);
    }

    if (vm.count ("version") || vm.count ("list") ) {
      // Disable lot to just print version
      gst_debug_remove_log_function (log_function);
    }

    loadModules (path);

    if (vm.count ("list") ) {
      std::cout << "Available factories:" << std::endl;

      for (auto it : kurento::getModuleManager().getLoadedFactories() ) {
        std::cout << "\t" << it.first << std::endl;
      }

      exit (0);
    }

    if (vm.count ("version") ) {
      print_version();
      exit (0);
    }

  } catch (boost::program_options::error &e) {
    std::cerr <<  "Error : " << e.what() << std::endl;
    exit (1);
  }

  /* Install our signal handler */
  sigemptyset (&mask);
  sigaddset (&mask, SIGINT);
  sigaddset (&mask, SIGTERM);
  sigaddset (&mask, SIGSEGV);
  sigaddset (&mask, SIGPIPE);
  signalHandler = std::shared_ptr <SignalHandler> (new SignalHandler (mask,
                  signal_handler) );

  GST_INFO ("Kmsc version: %s", get_version () );

  transport = load_config (config, confFile);

  /* Start transport */
  transport->start ();

  GST_INFO ("Mediaserver started");

  loop->run ();

  transport->stop();

  gst_debug_add_log_function (simple_log_function, NULL, NULL);
  gst_debug_remove_log_function (log_function);

  return 0;
}
<|endoftext|>


<commit_before>#ifndef _mex_hpp__
#define _mex_hpp__

// Copyright(c) Andre Caron, 2009-2010
//
// This document is covered by the Artistic License 2.0 (Open Source Initiative
// approved license). A copy of the license should have been provided alongside
// this software package (see "license.rtf"). If not, the license is available
// online at "http://www.opensource.org/licenses/artistic-license-2.0.php".

    // core wrappers.
#include "mex/allocator.hpp"
#include "mex/array.hpp"
#include "mex/call.hpp"
#include "mex/Class.hpp"
#include "mex/error.hpp"
#include "mex/exception.hpp"
#include "mex/isa.hpp"
#include "mex/string.hpp"
#include "mex/types.hpp"

    // functions.
#include "mex/exist.hpp"
#include "mex/flipdim.hpp"
#include "mex/mkdir.hpp"
#include "mex/permute.hpp"

namespace mex {

    array<char_t> exception_id ( const ::mxArray * exception )
    {
        ::mxArray *const result =
            ::mxGetProperty(exception, 0, "identifier");
        if ( result == 0 ) {
            return (string("MATLAB:no-identifier"));
        }
        return (array<char_t>(result, claim));
    }

    array<char_t> exception_message ( const ::mxArray * exception )
    {
        ::mxArray *const result =
            ::mxGetProperty(exception, 0, "message");
        if ( result == 0 ) {
            return (string("MATLAB:no-identifier"));
        }
        return (array<char_t>(result, claim));
    }

}

#endif /* _mex_hpp__ */
<commit_msg>Applied coding standard.<commit_after>#ifndef _mex_hpp__
#define _mex_hpp__

// Copyright(c) Andre Caron, 2009-2010
//
// This document is covered by the Artistic License 2.0 (Open Source Initiative
// approved license). A copy of the license should have been provided alongside
// this software package (see "license.rtf"). If not, the license is available
// online at "http://www.opensource.org/licenses/artistic-license-2.0.php".

    // core wrappers.
#include "mex/allocator.hpp"
#include "mex/array.hpp"
#include "mex/call.hpp"
#include "mex/Class.hpp"
#include "mex/error.hpp"
#include "mex/exception.hpp"
#include "mex/isa.hpp"
#include "mex/string.hpp"
#include "mex/types.hpp"

    // functions.
#include "mex/exist.hpp"
#include "mex/flipdim.hpp"
#include "mex/mkdir.hpp"
#include "mex/permute.hpp"

namespace mex {

    array<char_t> exception_id ( const ::mxArray * exception )
    {
        ::mxArray *const result =
            ::mxGetProperty(exception, 0, "identifier");
        if ( result == 0 ) {
            return (string("MATLAB:no-identifier"));
        }
        return (array<char_t>(result, claim));
    }

    array<char_t> exception_message ( const ::mxArray * exception )
    {
        ::mxArray *const result =
            ::mxGetProperty(exception, 0, "message");
        if ( result == 0 ) {
            return (string("MATLAB:no-identifier"));
        }
        return (array<char_t>(result, claim));
    }

}

#endif /* _mex_hpp__ */
<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2011 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#ifndef MAPNIK_DATASOURCE_HPP
#define MAPNIK_DATASOURCE_HPP

// mapnik
#include <mapnik/config.hpp>
#include <mapnik/ctrans.hpp>
#include <mapnik/params.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/query.hpp>
#include <mapnik/feature_layer_desc.hpp>

// boost
#include <boost/utility.hpp>
#include <boost/shared_ptr.hpp>

// stl
#include <map>
#include <string>

namespace mapnik {

typedef MAPNIK_DECL boost::shared_ptr<Feature> feature_ptr;

struct MAPNIK_DECL Featureset : private boost::noncopyable
{
    virtual feature_ptr next()=0;
    virtual ~Featureset() {};
};

typedef MAPNIK_DECL boost::shared_ptr<Featureset> featureset_ptr;

class MAPNIK_DECL datasource_exception : public std::exception
{
private:
    std::string message_;
public:
    datasource_exception(const std::string& message=std::string("no reason"))
        :message_(message) {}

    ~datasource_exception() throw() {}
    virtual const char* what() const throw()
    {
        return message_.c_str();
    }
};

class MAPNIK_DECL datasource : private boost::noncopyable
{
public:
    enum datasource_t {
        Vector,
        Raster
    };

    enum geometry_t {
        Point = 1,
        LineString = 2,
        Polygon = 3,
        Collection = 4
    };

    datasource (parameters const& params)
        : params_(params),
        is_bound_(false)
        {}

    /*!
     * @brief Get the configuration parameters of the data source.
     *
     * These vary depending on the type of data source.
     *
     * @return The configuration parameters of the data source.
     */
    parameters const& params() const
    {
        return params_;
    }

    /*!
     * @brief Get the type of the datasource
     * @return The type of the datasource (Vector or Raster)
     */
    virtual datasource_t type() const=0;

    /*!
     * @brief Connect to the datasource
     */
    virtual void bind() const {};

    virtual featureset_ptr features(const query& q) const=0;
    virtual featureset_ptr features_at_point(coord2d const& pt) const=0;
    virtual box2d<double> envelope() const=0;
    virtual boost::optional<geometry_t> get_geometry_type() const=0;
    virtual layer_descriptor get_descriptor() const=0;
    virtual ~datasource() {};
protected:
    parameters params_;
    mutable bool is_bound_;
};

typedef std::string datasource_name();
typedef datasource* create_ds(const parameters& params, bool bind);
typedef void destroy_ds(datasource *ds);

class datasource_deleter
{
public:
    void operator() (datasource* ds)
    {
        delete ds;
    }
};

typedef boost::shared_ptr<datasource> datasource_ptr;

#define DATASOURCE_PLUGIN(classname)                                    \
    extern "C" MAPNIK_EXP std::string datasource_name()                 \
    {                                                                   \
        return classname::name();                                       \
    }                                                                   \
    extern "C"  MAPNIK_EXP datasource* create(const parameters &params, bool bind) \
    {                                                                   \
        return new classname(params, bind);                             \
    }                                                                   \
    extern "C" MAPNIK_EXP void destroy(datasource *ds)                  \
    {                                                                   \
        delete ds;                                                      \
    }                                                                   \
    //

}

#endif // MAPNIK_DATASOURCE_HPP
<commit_msg>- cosmetics<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2011 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#ifndef MAPNIK_DATASOURCE_HPP
#define MAPNIK_DATASOURCE_HPP

// mapnik
#include <mapnik/config.hpp>
#include <mapnik/ctrans.hpp>
#include <mapnik/params.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/query.hpp>
#include <mapnik/feature_layer_desc.hpp>

// boost
#include <boost/utility.hpp>
#include <boost/shared_ptr.hpp>

// stl
#include <map>
#include <string>

namespace mapnik {

typedef MAPNIK_DECL boost::shared_ptr<Feature> feature_ptr;

struct MAPNIK_DECL Featureset : private boost::noncopyable
{
    virtual feature_ptr next() = 0;
    virtual ~Featureset() {}
};

typedef MAPNIK_DECL boost::shared_ptr<Featureset> featureset_ptr;

class MAPNIK_DECL datasource_exception : public std::exception
{
public:
    datasource_exception(const std::string& message = std::string("no reason"))
      : message_(message)
    {
    }

    ~datasource_exception() throw()
    {
    }

    virtual const char* what() const throw()
    {
        return message_.c_str();
    }
private:
    std::string message_;
};

class MAPNIK_DECL datasource : private boost::noncopyable
{
public:
    enum datasource_t {
        Vector,
        Raster
    };

    enum geometry_t {
        Point = 1,
        LineString = 2,
        Polygon = 3,
        Collection = 4
    };

    datasource (parameters const& params)
      : params_(params),
        is_bound_(false)
    {
    }

    /*!
     * @brief Get the configuration parameters of the data source.
     *
     * These vary depending on the type of data source.
     *
     * @return The configuration parameters of the data source.
     */
    parameters const& params() const
    {
        return params_;
    }

    /*!
     * @brief Get the type of the datasource
     * @return The type of the datasource (Vector or Raster)
     */
    virtual datasource_t type() const = 0;

    /*!
     * @brief Connect to the datasource
     */
    virtual void bind() const {}

    virtual featureset_ptr features(const query& q) const = 0;
    virtual featureset_ptr features_at_point(coord2d const& pt) const = 0;
    virtual box2d<double> envelope() const = 0;
    virtual boost::optional<geometry_t> get_geometry_type() const = 0;
    virtual layer_descriptor get_descriptor() const = 0;
    virtual ~datasource() {}
protected:
    parameters params_;
    mutable bool is_bound_;
};

typedef std::string datasource_name();
typedef datasource* create_ds(const parameters& params, bool bind);
typedef void destroy_ds(datasource *ds);

class datasource_deleter
{
public:
    void operator() (datasource* ds)
    {
        delete ds;
    }
};

typedef boost::shared_ptr<datasource> datasource_ptr;

#define DATASOURCE_PLUGIN(classname)                                    \
    extern "C" MAPNIK_EXP std::string datasource_name()                 \
    {                                                                   \
        return classname::name();                                       \
    }                                                                   \
    extern "C"  MAPNIK_EXP datasource* create(const parameters &params, bool bind) \
    {                                                                   \
        return new classname(params, bind);                             \
    }                                                                   \
    extern "C" MAPNIK_EXP void destroy(datasource *ds)                  \
    {                                                                   \
        delete ds;                                                      \
    }

}

#endif // MAPNIK_DATASOURCE_HPP
<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2014 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#ifndef MAPNIK_IMAGE_DATA_HPP
#define MAPNIK_IMAGE_DATA_HPP

// mapnik
#include <mapnik/global.hpp>
// stl
#include <algorithm>
#include <cassert>
#include <stdexcept>

namespace mapnik {

namespace detail {

struct buffer
{
    explicit buffer(std::size_t size)
        : size_(size),
          data_(static_cast<unsigned char*>(size_ != 0 ? ::operator new(size_) : nullptr))
    {}

    buffer(buffer && rhs) noexcept
        : size_(std::move(rhs.size_)),
          data_(std::move(rhs.data_))
    {
        rhs.size_ = 0;
        rhs.data_ = nullptr;
    }

    buffer(buffer const& rhs)
        : size_(rhs.size_),
          data_(static_cast<unsigned char*>(size_ != 0 ? ::operator new(size_) : nullptr))
    {
        if (data_) std::copy(rhs.data_, rhs.data_ + rhs.size_, data_);
    }

    buffer& operator=(buffer rhs)
    {
        swap(rhs);
        return *this;
    }

    void swap(buffer & rhs)
    {
        std::swap(size_, rhs.size_);
        std::swap(data_, rhs.data_);
    }

    inline bool operator!() const { return (data_ == nullptr)? false : true; }
    ~buffer()
    {
        ::operator delete(data_);
    }

    inline unsigned char* data() { return data_; }
    inline unsigned char const* data() const { return data_; }
    inline std::size_t size() const { return size_; }
    std::size_t size_;
    unsigned char* data_;

};

template <std::size_t max_size>
struct image_dimensions
{
    image_dimensions(int width, int height)
        : width_(width),
          height_(height)
    {
        if (width < 0 || width > max_size) throw std::runtime_error("Invalid width for image dimensions requested");
        if (height < 0 || height > max_size) throw std::runtime_error("Invalid height for image dimensions requested");
    }

    image_dimensions(image_dimensions const& other) = default;
    image_dimensions(image_dimensions && other) = default;
    image_dimensions& operator= (image_dimensions rhs)
    {
        std::swap(width_, rhs.width_);
        std::swap(height_, rhs.height_);
        return *this;
    }
    std::size_t width() const
    {
        return width_;
    }
    std::size_t height() const
    {
        return height_;
    }
    std::size_t width_;
    std::size_t height_;
};

}

template <typename T, std::size_t max_size = 65535>
class image_data
{
public:
    using pixel_type = T;
    static constexpr std::size_t pixel_size = sizeof(pixel_type);

    image_data(int width, int height, bool initialize = true)
        : dimensions_(width, height),
          buffer_(dimensions_.width() * dimensions_.height() * pixel_size),
          pData_(reinterpret_cast<pixel_type*>(buffer_.data()))
    {
        if (pData_ && initialize) std::fill(pData_, pData_ + dimensions_.width() * dimensions_.height(), 0);
    }

    image_data(image_data<pixel_type> const& rhs)
        : dimensions_(rhs.dimensions_),
          buffer_(rhs.buffer_),
          pData_(reinterpret_cast<pixel_type*>(buffer_.data()))
    {}

    image_data(image_data<pixel_type> && rhs) noexcept
        : dimensions_(std::move(rhs.dimensions_)),
        buffer_(std::move(rhs.buffer_)),
        pData_(reinterpret_cast<pixel_type*>(buffer_.data()))
    {
        rhs.dimensions_ = { 0, 0 };
        rhs.pData_ = nullptr;
    }

    image_data<pixel_type>& operator=(image_data<pixel_type> rhs)
    {
        swap(rhs);
        return *this;
    }

    void swap(image_data<pixel_type> & rhs)
    {
        std::swap(dimensions_, rhs.dimensions_);
        std::swap(buffer_, rhs.buffer_);
    }

    inline pixel_type& operator() (std::size_t i, std::size_t j)
    {
        assert(i < dimensions_.width() && j < dimensions_.height());
        return pData_[j * dimensions_.width() + i];
    }
    inline const pixel_type& operator() (std::size_t i, std::size_t j) const
    {
        assert(i < dimensions_.width() && j < dimensions_.height());
        return pData_[j * dimensions_.width() + i];
    }
    inline std::size_t width() const
    {
        return dimensions_.width();
    }
    inline std::size_t height() const
    {
        return dimensions_.height();
    }
    inline unsigned getSize() const
    {
        return dimensions_.height() * dimensions_.width() * pixel_size;
    }
    inline unsigned getRowSize() const
    {
        return dimensions_.width() * pixel_size;
    }
    inline void set(pixel_type const& t)
    {
        std::fill(pData_, pData_ + dimensions_.width() * dimensions_.height(), t);
    }

    inline const pixel_type* getData() const
    {
        return pData_;
    }

    inline pixel_type* getData()
    {
        return pData_;
    }

    inline const unsigned char* getBytes() const
    {
        return buffer_.data();
    }

    inline unsigned char* getBytes()
    {
        return buffer_.data();
    }

    inline const pixel_type* getRow(std::size_t row) const
    {
        return pData_ + row * dimensions_.width();
    }

    inline const pixel_type* getRow(std::size_t row, std::size_t x0) const
    {
        return pData_ + row * dimensions_.width() + x0;
    }

    inline pixel_type* getRow(std::size_t row)
    {
        return pData_ + row * dimensions_.width();
    }

    inline pixel_type* getRow(std::size_t row, std::size_t x0)
    {
        return pData_ + row * dimensions_.width() + x0;
    }

    inline void setRow(std::size_t row, pixel_type const* buf, std::size_t size)
    {
        assert(row < dimensions_.height());
        assert(size <= dimensions_.width());
        std::copy(buf, buf + size, pData_ + row * dimensions_.width());
    }
    inline void setRow(std::size_t row, std::size_t x0, std::size_t x1, pixel_type const* buf)
    {
        assert(row < dimensions_.height());
        assert ((x1 - x0) <= dimensions_.width() );
        std::copy(buf, buf + (x1 - x0), pData_ + row * dimensions_.width() + x0);
    }

private:
    detail::image_dimensions<max_size> dimensions_;
    detail::buffer buffer_;
    pixel_type *pData_;
};

using image_data_rgba8 = image_data<std::uint32_t>;
using image_data_gray8 = image_data<std::uint8_t> ;
using image_data_gray16 = image_data<std::int16_t>;
using image_data_gray32f = image_data<float>;
}

#endif // MAPNIK_IMAGE_DATA_HPP
<commit_msg>fix -Wsign-compare warning in image_data.hpp<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2014 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#ifndef MAPNIK_IMAGE_DATA_HPP
#define MAPNIK_IMAGE_DATA_HPP

// mapnik
#include <mapnik/global.hpp>
// stl
#include <algorithm>
#include <cassert>
#include <stdexcept>

namespace mapnik {

namespace detail {

struct buffer
{
    explicit buffer(std::size_t size)
        : size_(size),
          data_(static_cast<unsigned char*>(size_ != 0 ? ::operator new(size_) : nullptr))
    {}

    buffer(buffer && rhs) noexcept
        : size_(std::move(rhs.size_)),
          data_(std::move(rhs.data_))
    {
        rhs.size_ = 0;
        rhs.data_ = nullptr;
    }

    buffer(buffer const& rhs)
        : size_(rhs.size_),
          data_(static_cast<unsigned char*>(size_ != 0 ? ::operator new(size_) : nullptr))
    {
        if (data_) std::copy(rhs.data_, rhs.data_ + rhs.size_, data_);
    }

    buffer& operator=(buffer rhs)
    {
        swap(rhs);
        return *this;
    }

    void swap(buffer & rhs)
    {
        std::swap(size_, rhs.size_);
        std::swap(data_, rhs.data_);
    }

    inline bool operator!() const { return (data_ == nullptr)? false : true; }
    ~buffer()
    {
        ::operator delete(data_);
    }

    inline unsigned char* data() { return data_; }
    inline unsigned char const* data() const { return data_; }
    inline std::size_t size() const { return size_; }
    std::size_t size_;
    unsigned char* data_;

};

template <std::size_t max_size>
struct image_dimensions
{
    image_dimensions(int width, int height)
        : width_(width),
          height_(height)
    {
        if (width < 0 || static_cast<std::size_t>(width) > max_size) throw std::runtime_error("Invalid width for image dimensions requested");
        if (height < 0 || static_cast<std::size_t>(height) > max_size) throw std::runtime_error("Invalid height for image dimensions requested");
    }

    image_dimensions(image_dimensions const& other) = default;
    image_dimensions(image_dimensions && other) = default;
    image_dimensions& operator= (image_dimensions rhs)
    {
        std::swap(width_, rhs.width_);
        std::swap(height_, rhs.height_);
        return *this;
    }
    std::size_t width() const
    {
        return width_;
    }
    std::size_t height() const
    {
        return height_;
    }
    std::size_t width_;
    std::size_t height_;
};

}

template <typename T, std::size_t max_size = 65535>
class image_data
{
public:
    using pixel_type = T;
    static constexpr std::size_t pixel_size = sizeof(pixel_type);

    image_data(int width, int height, bool initialize = true)
        : dimensions_(width, height),
          buffer_(dimensions_.width() * dimensions_.height() * pixel_size),
          pData_(reinterpret_cast<pixel_type*>(buffer_.data()))
    {
        if (pData_ && initialize) std::fill(pData_, pData_ + dimensions_.width() * dimensions_.height(), 0);
    }

    image_data(image_data<pixel_type> const& rhs)
        : dimensions_(rhs.dimensions_),
          buffer_(rhs.buffer_),
          pData_(reinterpret_cast<pixel_type*>(buffer_.data()))
    {}

    image_data(image_data<pixel_type> && rhs) noexcept
        : dimensions_(std::move(rhs.dimensions_)),
        buffer_(std::move(rhs.buffer_)),
        pData_(reinterpret_cast<pixel_type*>(buffer_.data()))
    {
        rhs.dimensions_ = { 0, 0 };
        rhs.pData_ = nullptr;
    }

    image_data<pixel_type>& operator=(image_data<pixel_type> rhs)
    {
        swap(rhs);
        return *this;
    }

    void swap(image_data<pixel_type> & rhs)
    {
        std::swap(dimensions_, rhs.dimensions_);
        std::swap(buffer_, rhs.buffer_);
    }

    inline pixel_type& operator() (std::size_t i, std::size_t j)
    {
        assert(i < dimensions_.width() && j < dimensions_.height());
        return pData_[j * dimensions_.width() + i];
    }
    inline const pixel_type& operator() (std::size_t i, std::size_t j) const
    {
        assert(i < dimensions_.width() && j < dimensions_.height());
        return pData_[j * dimensions_.width() + i];
    }
    inline std::size_t width() const
    {
        return dimensions_.width();
    }
    inline std::size_t height() const
    {
        return dimensions_.height();
    }
    inline unsigned getSize() const
    {
        return dimensions_.height() * dimensions_.width() * pixel_size;
    }
    inline unsigned getRowSize() const
    {
        return dimensions_.width() * pixel_size;
    }
    inline void set(pixel_type const& t)
    {
        std::fill(pData_, pData_ + dimensions_.width() * dimensions_.height(), t);
    }

    inline const pixel_type* getData() const
    {
        return pData_;
    }

    inline pixel_type* getData()
    {
        return pData_;
    }

    inline const unsigned char* getBytes() const
    {
        return buffer_.data();
    }

    inline unsigned char* getBytes()
    {
        return buffer_.data();
    }

    inline const pixel_type* getRow(std::size_t row) const
    {
        return pData_ + row * dimensions_.width();
    }

    inline const pixel_type* getRow(std::size_t row, std::size_t x0) const
    {
        return pData_ + row * dimensions_.width() + x0;
    }

    inline pixel_type* getRow(std::size_t row)
    {
        return pData_ + row * dimensions_.width();
    }

    inline pixel_type* getRow(std::size_t row, std::size_t x0)
    {
        return pData_ + row * dimensions_.width() + x0;
    }

    inline void setRow(std::size_t row, pixel_type const* buf, std::size_t size)
    {
        assert(row < dimensions_.height());
        assert(size <= dimensions_.width());
        std::copy(buf, buf + size, pData_ + row * dimensions_.width());
    }
    inline void setRow(std::size_t row, std::size_t x0, std::size_t x1, pixel_type const* buf)
    {
        assert(row < dimensions_.height());
        assert ((x1 - x0) <= dimensions_.width() );
        std::copy(buf, buf + (x1 - x0), pData_ + row * dimensions_.width() + x0);
    }

private:
    detail::image_dimensions<max_size> dimensions_;
    detail::buffer buffer_;
    pixel_type *pData_;
};

using image_data_rgba8 = image_data<std::uint32_t>;
using image_data_gray8 = image_data<std::uint8_t> ;
using image_data_gray16 = image_data<std::int16_t>;
using image_data_gray32f = image_data<float>;
}

#endif // MAPNIK_IMAGE_DATA_HPP
<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2021 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#ifndef MAPNIK_PROJECTION_HPP
#define MAPNIK_PROJECTION_HPP

// mapnik
#include <mapnik/config.hpp>
#include <mapnik/well_known_srs.hpp>

#include <mapnik/warning.hpp>
MAPNIK_DISABLE_WARNING_PUSH
#include <mapnik/warning_ignore.hpp>
#include <boost/optional.hpp>
MAPNIK_DISABLE_WARNING_POP

// stl
#include <string>
#include <stdexcept>

// fwd decl
#if PROJ_VERSION_MAJOR >= 8
struct pj_ctx;
using PJ_CONTEXT = struct pj_ctx;
#else
struct projCtx_t;
using PJ_CONTEXT = struct projCtx_t;
#endif
struct PJconsts;
using PJ = struct PJconsts;

namespace mapnik {

class proj_init_error : public std::runtime_error
{
public:
    proj_init_error(std::string const& params)
        : std::runtime_error("failed to initialize projection with: '" + params + "'") {}
};

class MAPNIK_DECL projection
{
    friend class proj_transform;
public:

    projection(std::string const& params,
               bool defer_proj_init = false);
    projection(projection const& rhs);
    ~projection();

    projection& operator=(projection const& rhs);
    bool operator==(const projection& other) const;
    bool operator!=(const projection& other) const;
    bool is_initialized() const;
    bool is_geographic() const;
    boost::optional<well_known_srs_e> well_known() const;
    std::string const& params() const;
    void forward(double & x, double & y) const;
    void inverse(double & x,double & y) const;
    std::string expanded() const;
    void init_proj() const;

private:
    void swap (projection& rhs);

private:
    std::string params_;
    bool defer_proj_init_;
    mutable bool is_geographic_;
    mutable PJ * proj_;
    mutable PJ_CONTEXT * proj_ctx_;
};

template <typename charT, typename traits>
std::basic_ostream<charT, traits> &
operator << ( std::basic_ostream<charT, traits> & s, mapnik::projection const& p )
{
    s << "projection(\"" << p.params() << "\")";
    return s;
}

}

#endif // MAPNIK_PROJECTION_HPP
<commit_msg>proj - add version check based on major*10000+minor*100+patch format<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2021 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#ifndef MAPNIK_PROJECTION_HPP
#define MAPNIK_PROJECTION_HPP

// mapnik
#include <mapnik/config.hpp>
#include <mapnik/well_known_srs.hpp>

#include <mapnik/warning.hpp>
MAPNIK_DISABLE_WARNING_PUSH
#include <mapnik/warning_ignore.hpp>
#include <boost/optional.hpp>
MAPNIK_DISABLE_WARNING_POP

// stl
#include <string>
#include <stdexcept>

// fwd decl
#if PROJ_VERSION >= 80000
struct pj_ctx;
using PJ_CONTEXT = struct pj_ctx;
#else
struct projCtx_t;
using PJ_CONTEXT = struct projCtx_t;
#endif
struct PJconsts;
using PJ = struct PJconsts;

namespace mapnik {

class proj_init_error : public std::runtime_error
{
public:
    proj_init_error(std::string const& params)
        : std::runtime_error("failed to initialize projection with: '" + params + "'") {}
};

class MAPNIK_DECL projection
{
    friend class proj_transform;
public:

    projection(std::string const& params,
               bool defer_proj_init = false);
    projection(projection const& rhs);
    ~projection();

    projection& operator=(projection const& rhs);
    bool operator==(const projection& other) const;
    bool operator!=(const projection& other) const;
    bool is_initialized() const;
    bool is_geographic() const;
    boost::optional<well_known_srs_e> well_known() const;
    std::string const& params() const;
    void forward(double & x, double & y) const;
    void inverse(double & x,double & y) const;
    std::string expanded() const;
    void init_proj() const;

private:
    void swap (projection& rhs);

private:
    std::string params_;
    bool defer_proj_init_;
    mutable bool is_geographic_;
    mutable PJ * proj_;
    mutable PJ_CONTEXT * proj_ctx_;
};

template <typename charT, typename traits>
std::basic_ostream<charT, traits> &
operator << ( std::basic_ostream<charT, traits> & s, mapnik::projection const& p )
{
    s << "projection(\"" << p.params() << "\")";
    return s;
}

}

#endif // MAPNIK_PROJECTION_HPP
<|endoftext|>