<commit_before>/*

Copyright (c) 2003-2013, Arvid Norberg, Daniel Wallin
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#ifndef TORRENT_ALERT_HPP_INCLUDED
#define TORRENT_ALERT_HPP_INCLUDED

#include <memory>
#include <deque>
#include <string>

#ifdef _MSC_VER
#pragma warning(push, 1)
#endif

#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
#include <boost/preprocessor/repetition/enum.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_shifted_params.hpp>
#include <boost/preprocessor/repetition/enum_shifted_binary_params.hpp>

// OVERVIEW
//
// The pop_alert() function on session is the interface for retrieving
// alerts, warnings, messages and errors from libtorrent. If no alerts have
// been posted by libtorrent pop_alert() will return a default initialized
// ``std::auto_ptr`` object. If there is an alert in libtorrent's queue, the alert
// from the front of the queue is popped and returned.
// You can then use the alert object and query
//
// By default, only errors are reported. set_alert_mask() can be
// used to specify which kinds of events should be reported. The alert mask
// is comprised by bits from the category_t enum.
//
// Every alert belongs to one or more category. There is a small cost involved in posting alerts. Only
// alerts that belong to an enabled category are posted. Setting the alert bitmask to 0 will disable
// all alerts (except those that are non-discardable).
//
// There are other alert base classes that some alerts derive from, all the
// alerts that are generated for a specific torrent are derived from torrent_alert,
// and tracker events derive from tracker_alert.
//

#ifdef _MSC_VER
#pragma warning(pop)
#endif

#include "libtorrent/ptime.hpp"
#include "libtorrent/config.hpp"

#ifndef BOOST_NO_TYPEID
#include <typeinfo>
#endif

#ifndef TORRENT_MAX_ALERT_TYPES
#define TORRENT_MAX_ALERT_TYPES 15
#endif

namespace libtorrent {

	// The ``alert`` class is the base class that specific messages are derived from.
	class TORRENT_EXPORT alert
	{
	public:

#ifndef TORRENT_NO_DEPRECATE
		// only here for backwards compatibility
		enum severity_t { debug, info, warning, critical, fatal, none };
#endif

		// these are bits for the alert_mask used by the session. See set_alert_mask().
		enum category_t
		{
			// Enables alerts that report an error. This includes:
			//
			// * tracker errors
			// * tracker warnings
			// * file errors
			// * resume data failures
			// * web seed errors
			// * .torrent files errors
			// * listen socket errors
			// * port mapping errors
			error_notification = 0x1,

			// Enables alerts when peers send invalid requests, get banned or
			// snubbed.
			peer_notification = 0x2,

			// Enables alerts for port mapping events. For NAT-PMP and UPnP.
			port_mapping_notification = 0x4,

			// Enables alerts for events related to the storage. File errors and
			// synchronization events for moving the storage, renaming files etc.
			storage_notification = 0x8,

			// Enables all tracker events. Includes announcing to trackers,
			// receiving responses, warnings and errors.
			tracker_notification = 0x10,

			// Low level alerts for when peers are connected and disconnected.
			debug_notification = 0x20,

			// Enables alerts for when a torrent or the session changes state.
			status_notification = 0x40,

			// Alerts for when blocks are requested and completed. Also when
			// pieces are completed.
			progress_notification = 0x80,

			// Alerts when a peer is blocked by the ip blocker or port blocker.
			ip_block_notification = 0x100,

			// Alerts when some limit is reached that might limit the download
			// or upload rate.
			performance_warning = 0x200,

			// Alerts on events in the DHT node. For incoming searches or
			// bootstrapping being done etc.
			dht_notification = 0x400,

			// If you enable these alerts, you will receive a stats_alert
			// approximately once every second, for every active torrent.
			// These alerts contain all statistics counters for the interval since
			// the lasts stats alert.
			stats_notification = 0x800,

			// Alerts on RSS related events, like feeds being updated, feed error
			// conditions and successful RSS feed updates. Enabling this categoty
			// will make you receive rss_alert alerts.
			rss_notification = 0x1000,

			// The full bitmask, representing all available categories.
			//
			// since the enum is signed, make sure this isn't
			// interpreted as -1. For instance, boost.python
			// does that and fails when assigning it to an
			// unsigned parameter.
			all_categories = 0x7fffffff
		};

		// hidden
		alert();
		// hidden
		virtual ~alert();

		// a timestamp is automatically created in the constructor
		ptime timestamp() const;

		// returns an integer that is unique to this alert type. It can be
		// compared against a specific alert by querying a static constant called ``alert_type``
		// in the alert. It can be used to determine the run-time type of an alert* in
		// order to cast to that alert type and access specific members.
		//
		// e.g::
		//
		//	std::auto_ptr<alert> a = ses.pop_alert();
		//	switch (a->type())
		//	{
		//		case read_piece_alert::alert_type:
		//		{
		//			read_piece_alert* p = (read_piece_alert*)a.get();
		//			if (p->ec) {
		//				// read_piece failed
		//				break;
		//			}
		//			// use p
		//			break;
		//		}
		//		case file_renamed_alert::alert_type:
		//		{
		//			// etc...
		//		}
		//	}
		virtual int type() const = 0;

		// returns a string literal describing the type of the alert. It does
		// not include any information that might be bundled with the alert.
		virtual char const* what() const = 0;

		// generate a string describing the alert and the information bundled
		// with it. This is mainly intended for debug and development use. It is not suitable
		// to use this for applications that may be localized. Instead, handle each alert
		// type individually and extract and render the information from the alert depending
		// on the locale.
		virtual std::string message() const = 0;

		// returns a bitmask specifying which categories this alert belong to.
		virtual int category() const = 0;

		// determines whether or not an alert is allowed to be discarded
		// when the alert queue is full. There are a few alerts which may not be discared,
		// since they would break the user contract, such as save_resume_data_alert.
		virtual bool discardable() const { return true; }

#ifndef TORRENT_NO_DEPRECATE
		TORRENT_DEPRECATED_PREFIX
		severity_t severity() const TORRENT_DEPRECATED { return warning; }
#endif

		// returns a pointer to a copy of the alert.
		virtual std::auto_ptr<alert> clone() const = 0;

	private:
		ptime m_timestamp;
	};

#ifndef TORRENT_NO_DEPRECATE
	struct TORRENT_EXPORT unhandled_alert : std::exception
	{
		unhandled_alert() {}
	};

#ifndef BOOST_NO_TYPEID

	namespace detail {

		struct void_;

		template<class Handler
			, BOOST_PP_ENUM_PARAMS(TORRENT_MAX_ALERT_TYPES, class T)>
		void handle_alert_dispatch(
			const std::auto_ptr<alert>& alert_, const Handler& handler
			, const std::type_info& typeid_
			, T0*, BOOST_PP_ENUM_SHIFTED_BINARY_PARAMS(TORRENT_MAX_ALERT_TYPES, T, *p))
		{
			if (typeid_ == typeid(T0))
				handler(*static_cast<T0*>(alert_.get()));
			else
				handle_alert_dispatch(alert_, handler, typeid_
					, BOOST_PP_ENUM_SHIFTED_PARAMS(
					TORRENT_MAX_ALERT_TYPES, p), (void_*)0);
		}

		template<class Handler>
		void handle_alert_dispatch(
			const std::auto_ptr<alert>&
			, const Handler&
			, const std::type_info&
			, BOOST_PP_ENUM_PARAMS(TORRENT_MAX_ALERT_TYPES, void_* BOOST_PP_INTERCEPT))
		{
			throw unhandled_alert();
		}

	} // namespace detail

	template<BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
		TORRENT_MAX_ALERT_TYPES, class T, detail::void_)>
	struct TORRENT_EXPORT handle_alert
	{
		template<class Handler>
		handle_alert(const std::auto_ptr<alert>& alert_
			, const Handler& handler)
		{
			#define ALERT_POINTER_TYPE(z, n, text) (BOOST_PP_CAT(T, n)*)0

			detail::handle_alert_dispatch(alert_, handler, typeid(*alert_)
				, BOOST_PP_ENUM(TORRENT_MAX_ALERT_TYPES, ALERT_POINTER_TYPE, _));

			#undef ALERT_POINTER_TYPE
		}
	};

#endif // BOOST_NO_TYPEID
#endif // TORRENT_NO_DEPRECATE

// When you get an alert, you can use ``alert_cast<>`` to attempt to cast the pointer to a
// more specific alert type, in order to query it for more information.
template <class T>
T* alert_cast(alert* a)
{
	if (a == 0) return 0;
	if (a->type() == T::alert_type) return static_cast<T*>(a);
	return 0;
}
template <class T>
T const* alert_cast(alert const* a)
{
	if (a == 0) return 0;
	if (a->type() == T::alert_type) return static_cast<T const*>(a);
	return 0;
}

} // namespace libtorrent

#endif // TORRENT_ALERT_HPP_INCLUDED

<commit_msg>cut dependency on typeinfo header when building without deprecated functions<commit_after>/*

Copyright (c) 2003-2013, Arvid Norberg, Daniel Wallin
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#ifndef TORRENT_ALERT_HPP_INCLUDED
#define TORRENT_ALERT_HPP_INCLUDED

#include <memory>
#include <deque>
#include <string>

#ifdef _MSC_VER
#pragma warning(push, 1)
#endif

#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
#include <boost/preprocessor/repetition/enum.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_shifted_params.hpp>
#include <boost/preprocessor/repetition/enum_shifted_binary_params.hpp>

// OVERVIEW
//
// The pop_alert() function on session is the interface for retrieving
// alerts, warnings, messages and errors from libtorrent. If no alerts have
// been posted by libtorrent pop_alert() will return a default initialized
// ``std::auto_ptr`` object. If there is an alert in libtorrent's queue, the alert
// from the front of the queue is popped and returned.
// You can then use the alert object and query
//
// By default, only errors are reported. set_alert_mask() can be
// used to specify which kinds of events should be reported. The alert mask
// is comprised by bits from the category_t enum.
//
// Every alert belongs to one or more category. There is a small cost involved in posting alerts. Only
// alerts that belong to an enabled category are posted. Setting the alert bitmask to 0 will disable
// all alerts (except those that are non-discardable).
//
// There are other alert base classes that some alerts derive from, all the
// alerts that are generated for a specific torrent are derived from torrent_alert,
// and tracker events derive from tracker_alert.
//

#ifdef _MSC_VER
#pragma warning(pop)
#endif

#include "libtorrent/ptime.hpp"
#include "libtorrent/config.hpp"

#ifndef TORRENT_NO_DEPRECATE
#ifndef BOOST_NO_TYPEID
#include <typeinfo>
#endif
#endif // TORRENT_NO_DEPRECATE

#ifndef TORRENT_MAX_ALERT_TYPES
#define TORRENT_MAX_ALERT_TYPES 15
#endif

namespace libtorrent {

	// The ``alert`` class is the base class that specific messages are derived from.
	class TORRENT_EXPORT alert
	{
	public:

#ifndef TORRENT_NO_DEPRECATE
		// only here for backwards compatibility
		enum severity_t { debug, info, warning, critical, fatal, none };
#endif

		// these are bits for the alert_mask used by the session. See set_alert_mask().
		enum category_t
		{
			// Enables alerts that report an error. This includes:
			//
			// * tracker errors
			// * tracker warnings
			// * file errors
			// * resume data failures
			// * web seed errors
			// * .torrent files errors
			// * listen socket errors
			// * port mapping errors
			error_notification = 0x1,

			// Enables alerts when peers send invalid requests, get banned or
			// snubbed.
			peer_notification = 0x2,

			// Enables alerts for port mapping events. For NAT-PMP and UPnP.
			port_mapping_notification = 0x4,

			// Enables alerts for events related to the storage. File errors and
			// synchronization events for moving the storage, renaming files etc.
			storage_notification = 0x8,

			// Enables all tracker events. Includes announcing to trackers,
			// receiving responses, warnings and errors.
			tracker_notification = 0x10,

			// Low level alerts for when peers are connected and disconnected.
			debug_notification = 0x20,

			// Enables alerts for when a torrent or the session changes state.
			status_notification = 0x40,

			// Alerts for when blocks are requested and completed. Also when
			// pieces are completed.
			progress_notification = 0x80,

			// Alerts when a peer is blocked by the ip blocker or port blocker.
			ip_block_notification = 0x100,

			// Alerts when some limit is reached that might limit the download
			// or upload rate.
			performance_warning = 0x200,

			// Alerts on events in the DHT node. For incoming searches or
			// bootstrapping being done etc.
			dht_notification = 0x400,

			// If you enable these alerts, you will receive a stats_alert
			// approximately once every second, for every active torrent.
			// These alerts contain all statistics counters for the interval since
			// the lasts stats alert.
			stats_notification = 0x800,

			// Alerts on RSS related events, like feeds being updated, feed error
			// conditions and successful RSS feed updates. Enabling this categoty
			// will make you receive rss_alert alerts.
			rss_notification = 0x1000,

			// The full bitmask, representing all available categories.
			//
			// since the enum is signed, make sure this isn't
			// interpreted as -1. For instance, boost.python
			// does that and fails when assigning it to an
			// unsigned parameter.
			all_categories = 0x7fffffff
		};

		// hidden
		alert();
		// hidden
		virtual ~alert();

		// a timestamp is automatically created in the constructor
		ptime timestamp() const;

		// returns an integer that is unique to this alert type. It can be
		// compared against a specific alert by querying a static constant called ``alert_type``
		// in the alert. It can be used to determine the run-time type of an alert* in
		// order to cast to that alert type and access specific members.
		//
		// e.g::
		//
		//	std::auto_ptr<alert> a = ses.pop_alert();
		//	switch (a->type())
		//	{
		//		case read_piece_alert::alert_type:
		//		{
		//			read_piece_alert* p = (read_piece_alert*)a.get();
		//			if (p->ec) {
		//				// read_piece failed
		//				break;
		//			}
		//			// use p
		//			break;
		//		}
		//		case file_renamed_alert::alert_type:
		//		{
		//			// etc...
		//		}
		//	}
		virtual int type() const = 0;

		// returns a string literal describing the type of the alert. It does
		// not include any information that might be bundled with the alert.
		virtual char const* what() const = 0;

		// generate a string describing the alert and the information bundled
		// with it. This is mainly intended for debug and development use. It is not suitable
		// to use this for applications that may be localized. Instead, handle each alert
		// type individually and extract and render the information from the alert depending
		// on the locale.
		virtual std::string message() const = 0;

		// returns a bitmask specifying which categories this alert belong to.
		virtual int category() const = 0;

		// determines whether or not an alert is allowed to be discarded
		// when the alert queue is full. There are a few alerts which may not be discared,
		// since they would break the user contract, such as save_resume_data_alert.
		virtual bool discardable() const { return true; }

#ifndef TORRENT_NO_DEPRECATE
		TORRENT_DEPRECATED_PREFIX
		severity_t severity() const TORRENT_DEPRECATED { return warning; }
#endif

		// returns a pointer to a copy of the alert.
		virtual std::auto_ptr<alert> clone() const = 0;

	private:
		ptime m_timestamp;
	};

#ifndef TORRENT_NO_DEPRECATE
	struct TORRENT_EXPORT unhandled_alert : std::exception
	{
		unhandled_alert() {}
	};

#ifndef BOOST_NO_TYPEID

	namespace detail {

		struct void_;

		template<class Handler
			, BOOST_PP_ENUM_PARAMS(TORRENT_MAX_ALERT_TYPES, class T)>
		void handle_alert_dispatch(
			const std::auto_ptr<alert>& alert_, const Handler& handler
			, const std::type_info& typeid_
			, T0*, BOOST_PP_ENUM_SHIFTED_BINARY_PARAMS(TORRENT_MAX_ALERT_TYPES, T, *p))
		{
			if (typeid_ == typeid(T0))
				handler(*static_cast<T0*>(alert_.get()));
			else
				handle_alert_dispatch(alert_, handler, typeid_
					, BOOST_PP_ENUM_SHIFTED_PARAMS(
					TORRENT_MAX_ALERT_TYPES, p), (void_*)0);
		}

		template<class Handler>
		void handle_alert_dispatch(
			const std::auto_ptr<alert>&
			, const Handler&
			, const std::type_info&
			, BOOST_PP_ENUM_PARAMS(TORRENT_MAX_ALERT_TYPES, void_* BOOST_PP_INTERCEPT))
		{
			throw unhandled_alert();
		}

	} // namespace detail

	template<BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
		TORRENT_MAX_ALERT_TYPES, class T, detail::void_)>
	struct TORRENT_EXPORT handle_alert
	{
		template<class Handler>
		handle_alert(const std::auto_ptr<alert>& alert_
			, const Handler& handler)
		{
			#define ALERT_POINTER_TYPE(z, n, text) (BOOST_PP_CAT(T, n)*)0

			detail::handle_alert_dispatch(alert_, handler, typeid(*alert_)
				, BOOST_PP_ENUM(TORRENT_MAX_ALERT_TYPES, ALERT_POINTER_TYPE, _));

			#undef ALERT_POINTER_TYPE
		}
	};

#endif // BOOST_NO_TYPEID
#endif // TORRENT_NO_DEPRECATE

// When you get an alert, you can use ``alert_cast<>`` to attempt to cast the pointer to a
// more specific alert type, in order to query it for more information.
template <class T>
T* alert_cast(alert* a)
{
	if (a == 0) return 0;
	if (a->type() == T::alert_type) return static_cast<T*>(a);
	return 0;
}
template <class T>
T const* alert_cast(alert const* a)
{
	if (a == 0) return 0;
	if (a->type() == T::alert_type) return static_cast<T const*>(a);
	return 0;
}

} // namespace libtorrent

#endif // TORRENT_ALERT_HPP_INCLUDED

<|endoftext|>


<commit_before>/* Copyright 2011 Thomas McGuire <mcguire@kde.org>
   Copyright 2011 Alexander Potashev <aspotashev@gmail.com>

   This library is free software; you can redistribute it and/or modify
   it under the terms of the GNU Library General Public License as published
   by the Free Software Foundation; either version 2 of the License or
   ( at your option ) version 3 or, at the discretion of KDE e.V.
   ( which shall act as a proxy as in section 14 of the GPLv3 ), 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
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public License
   along with this library; see the file COPYING.LIB.  If not, write to
   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
   Boston, MA 02110-1301, USA.
*/
#include "util.h"

KDateTime unixTimeToKDateTime(const QString &unixTime)
{
    KDateTime res;
    res.setTime_t(unixTime.toLongLong());
    return res;
}
<commit_msg>Load translation catalog "libkvkontakte"<commit_after>/* Copyright 2011 Thomas McGuire <mcguire@kde.org>
   Copyright 2011 Alexander Potashev <aspotashev@gmail.com>

   This library is free software; you can redistribute it and/or modify
   it under the terms of the GNU Library General Public License as published
   by the Free Software Foundation; either version 2 of the License or
   ( at your option ) version 3 or, at the discretion of KDE e.V.
   ( which shall act as a proxy as in section 14 of the GPLv3 ), 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
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public License
   along with this library; see the file COPYING.LIB.  If not, write to
   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
   Boston, MA 02110-1301, USA.
*/
#include "util.h"
#include <KGlobal>

static const KCatalogLoader loader("libkvkontakte");

KDateTime unixTimeToKDateTime(const QString &unixTime)
{
    KDateTime res;
    res.setTime_t(unixTime.toLongLong());
    return res;
}
<|endoftext|>


<commit_before>// Module:  Log4CPLUS
// File:    threads.cxx
// Created: 6/2001
// Author:  Tad E. Smith
//
//
// Copyright 2001-2013 Tad E. Smith
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <log4cplus/config.hxx>

#include <exception>
#include <ostream>
#include <cerrno>

#ifdef LOG4CPLUS_HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif

#ifdef LOG4CPLUS_HAVE_SYS_SYSCALL_H
#include <sys/syscall.h>
#endif

#ifdef LOG4CPLUS_HAVE_ERRNO_H
#include <errno.h>
#endif

#ifdef LOG4CPLUS_HAVE_UNISTD_H
#include <unistd.h>
#endif

#if defined(LOG4CPLUS_USE_PTHREADS)
#  include <pthread.h>
#  include <sched.h>
#  include <signal.h>
#elif defined (LOG4CPLUS_USE_WIN32_THREADS)
#  include <process.h>
#endif
#include <log4cplus/config/windowsh-inc.h>
#include <log4cplus/thread/syncprims-pub-impl.h>
#include <log4cplus/tstring.h>
#include <log4cplus/internal/cygwin-win32.h>
#include <log4cplus/streams.h>

#ifndef LOG4CPLUS_SINGLE_THREADED

#include <log4cplus/thread/threads.h>
#include <log4cplus/thread/impl/threads-impl.h>
#include <log4cplus/thread/impl/tls.h>
#include <log4cplus/ndc.h>
#include <log4cplus/helpers/loglog.h>
#include <log4cplus/helpers/stringhelper.h>
#include <log4cplus/helpers/timehelper.h>
#include <log4cplus/internal/internal.h>

#endif // LOG4CPLUS_SINGLE_THREADED

namespace log4cplus { namespace thread {

LOG4CPLUS_EXPORT
void
blockAllSignals()
{
#if defined (LOG4CPLUS_USE_PTHREADS)
    // Block all signals.
    sigset_t signal_set;
    sigfillset (&signal_set);
    pthread_sigmask (SIG_BLOCK, &signal_set, 0);
#endif
}

LOG4CPLUS_EXPORT
void
yield()
{
#if defined(LOG4CPLUS_USE_PTHREADS)
    sched_yield();
#elif defined(_WIN32)
    if (! SwitchToThread ())
        Sleep (0);
#endif
}

#if defined(LOG4CPLUS_SINGLE_THREADED)
static log4cplus::tstring thread_name(LOG4CPLUS_TEXT("single"));
static log4cplus::tstring thread_name2(thread_name);
#endif

LOG4CPLUS_EXPORT
log4cplus::tstring const &
getCurrentThreadName()
{
#if ! defined (LOG4CPLUS_SINGLE_THREADED)
    log4cplus::tstring & name = log4cplus::internal::get_thread_name_str ();
    if (LOG4CPLUS_UNLIKELY (name.empty ()))
    {
        log4cplus::tostringstream tmp;
        tmp << impl::getCurrentThreadId ();
        tmp.str ().swap (name);
    }
#else
    log4cplus::tstring & name = thread_name;
    if (LOG4CPLUS_UNLIKELY(name.empty()))
    {
        name = LOG4CPLUS_TEXT("single");
    }
#endif

    return name;
}

namespace
{

static
bool
get_current_thread_name_alt (log4cplus::tostream * s)
{
    log4cplus::tostream & os = *s;

#if defined (LOG4CPLUS_USE_PTHREADS) && defined (__linux__) \
    && defined (LOG4CPLUS_HAVE_GETTID)
    pid_t tid = syscall (SYS_gettid);
    os << tid;

#elif defined (__CYGWIN__)
    unsigned long tid = cygwin::get_current_win32_thread_id ();
    os << tid;

#else
    os << getCurrentThreadName ();

#endif

    return true;
}

} // namespace

LOG4CPLUS_EXPORT
log4cplus::tstring const &
getCurrentThreadName2()
{
#if ! defined (LOG4CPLUS_SINGLE_THREADED)
    log4cplus::tstring & name = log4cplus::internal::get_thread_name2_str ();
    if (LOG4CPLUS_UNLIKELY (name.empty ()))
    {
        log4cplus::tostringstream tmp;
        get_current_thread_name_alt (&tmp);
        tmp.str ().swap (name);
    }

#else
    log4cplus::tstring & name = thread_name2;
    if (LOG4CPLUS_UNLIKELY(name.empty()))
    {
        name = getCurrentThreadName();
    }

#endif

    return name;
}

LOG4CPLUS_EXPORT void setCurrentThreadName(const log4cplus::tstring & name)
{
#if ! defined (LOG4CPLUS_SINGLE_THREADED)
    log4cplus::internal::get_thread_name_str() = name;
#else
    thread_name = name;
#endif
}

LOG4CPLUS_EXPORT void setCurrentThreadName2(const log4cplus::tstring & name)
{
#if ! defined (LOG4CPLUS_SINGLE_THREADED)
    log4cplus::internal::get_thread_name2_str() = name;
#else
    thread_name2 = name;
#endif
}

} } // namespace log4cplus { namespace thread {

#ifndef LOG4CPLUS_SINGLE_THREADED

namespace
{

#  ifdef LOG4CPLUS_USE_PTHREADS
extern "C" void* threadStartFunc(void * param)
#  elif defined(LOG4CPLUS_USE_WIN32_THREADS)
static unsigned WINAPI threadStartFunc(void * param)
#  endif
{
    return log4cplus::thread::impl::ThreadStart::threadStartFuncWorker (param);
}

} // namespace

namespace log4cplus { namespace thread { namespace impl {

#if defined(LOG4CPLUS_USE_PTHREADS)
void*
ThreadStart::threadStartFuncWorker(void * arg)
#elif defined(LOG4CPLUS_USE_WIN32_THREADS)
unsigned
ThreadStart::threadStartFuncWorker(void * arg)
#endif
{
    blockAllSignals ();
    helpers::LogLog * loglog = helpers::LogLog::getLogLog();
    if (! arg)
        loglog->error(LOG4CPLUS_TEXT("threadStartFunc()- arg is NULL"));
    else
    {
        Thread * ptr = static_cast<Thread *>(arg);
        ThreadPtr thread(ptr);

        // Decrease reference count increased by Thread::start().
        ptr->removeReference ();

        try
        {
            thread->run();
        }
        catch(std::exception const & e)
        {
            tstring err = LOG4CPLUS_TEXT("threadStartFunc()- run() terminated with an exception: ");
            err += LOG4CPLUS_C_STR_TO_TSTRING(e.what());
            loglog->warn(err);
        }
        catch(...)
        {
            loglog->warn(LOG4CPLUS_TEXT("threadStartFunc()- run() terminated with an exception."));
        }

        thread::MutexGuard guard (thread->access_mutex);
        thread->flags &= ~Thread::fRUNNING;
    }

    threadCleanup ();

    return 0;
}

Thread::Thread()
    : flags (0)
#if defined(LOG4CPLUS_USE_WIN32_THREADS)
    , handle (INVALID_HANDLE_VALUE)
    , thread_id (0)
#else
    , handle ()
#endif
{
}

Thread::~Thread()
{
#if defined(LOG4CPLUS_USE_PTHREADS)
    if ((flags & fJOINED) == 0)
        pthread_detach (handle);

#elif defined(LOG4CPLUS_USE_WIN32_THREADS)
    if (handle != INVALID_HANDLE_VALUE)
        ::CloseHandle (handle);

#endif
}

void
Thread::start()
{
    flags |= fRUNNING;

    // Increase reference count here. It will be lowered by the running
    // thread itself.
    addReference ();

#if defined(LOG4CPLUS_USE_PTHREADS)
    if (pthread_create(&handle, NULL, threadStartFunc, this) )
    {
        removeReference ();
        flags &= ~fRUNNING;
        log4cplus::helpers::LogLog::getLogLog ()->error (
            LOG4CPLUS_TEXT ("Thread creation was not successful"), true);
    }
#elif defined(LOG4CPLUS_USE_WIN32_THREADS)
    HANDLE h = InterlockedExchangePointer (&handle, INVALID_HANDLE_VALUE);
    if (h != INVALID_HANDLE_VALUE)
        ::CloseHandle (h);

    h = reinterpret_cast<HANDLE>(
        ::_beginthreadex (0, 0, threadStartFunc, this, 0, &thread_id));
    if (! h)
    {
        removeReference ();
        flags &= ~fRUNNING;
        log4cplus::helpers::LogLog::getLogLog ()->error (
            LOG4CPLUS_TEXT ("Thread creation was not successful"), true);
    }
    h = InterlockedExchangePointer (&handle, h);
    assert (h == INVALID_HANDLE_VALUE);
#endif
}

bool
Thread::isRunning() const
{
    thread::MutexGuard guard (access_mutex);
    return (flags & fRUNNING) != 0;
}

os_id_type
Thread::getThreadId () const
{
#if defined(LOG4CPLUS_USE_PTHREADS)
    return handle;
#elif defined(LOG4CPLUS_USE_WIN32_THREADS)
    return thread_id;
#endif
}

os_handle_type
Thread::getThreadHandle () const
{
    return handle;
}

void
Thread::join ()
{
#if defined(LOG4CPLUS_USE_PTHREADS)
    pthread_join (handle, 0);
#elif defined(LOG4CPLUS_USE_WIN32_THREADS)
    ::WaitForSingleObject (handle, INFINITE);
#endif
    flags |= fJOINED;
}

} // namespace impl {

//
//
//

ThreadImplBase::~ThreadImplBase ()
{ }

//
//
//

namespace
{

class ThreadImpl
    : public impl::Thread
{
public:
    ThreadImpl ()
        : abs_thread (0)
    { }

    virtual ~ThreadImpl ()
    { }

    virtual
    void
    run ()
    {
        abs_thread->run ();
    }

    void
    set_abs_thread (AbstractThread * at)
    {
        abs_thread = at;
    }

protected:
    AbstractThread * abs_thread;
};

} // namespace

//
//
//

AbstractThread::AbstractThread ()
    : thread (new ThreadImpl)
{
    static_cast<ThreadImpl *>(thread.get ())->set_abs_thread (this);
}

bool
AbstractThread::isRunning() const
{
    return static_cast<ThreadImpl *>(thread.get ())->isRunning ();
}

void
AbstractThread::start()
{
    static_cast<ThreadImpl *>(thread.get ())->start ();
}

void
AbstractThread::join () const
{
    static_cast<ThreadImpl *>(thread.get ())->join ();
}

AbstractThread::~AbstractThread()
{ }

} } // namespace log4cplus { namespace thread {

#endif // LOG4CPLUS_SINGLE_THREADED
<commit_msg>threads.cxx: Use init priority for thread_name and thread_name2.<commit_after>// Module:  Log4CPLUS
// File:    threads.cxx
// Created: 6/2001
// Author:  Tad E. Smith
//
//
// Copyright 2001-2013 Tad E. Smith
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <log4cplus/config.hxx>

#include <exception>
#include <ostream>
#include <cerrno>

#ifdef LOG4CPLUS_HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif

#ifdef LOG4CPLUS_HAVE_SYS_SYSCALL_H
#include <sys/syscall.h>
#endif

#ifdef LOG4CPLUS_HAVE_ERRNO_H
#include <errno.h>
#endif

#ifdef LOG4CPLUS_HAVE_UNISTD_H
#include <unistd.h>
#endif

#if defined(LOG4CPLUS_USE_PTHREADS)
#  include <pthread.h>
#  include <sched.h>
#  include <signal.h>
#elif defined (LOG4CPLUS_USE_WIN32_THREADS)
#  include <process.h>
#endif
#include <log4cplus/config/windowsh-inc.h>
#include <log4cplus/thread/syncprims-pub-impl.h>
#include <log4cplus/tstring.h>
#include <log4cplus/internal/cygwin-win32.h>
#include <log4cplus/streams.h>

#ifndef LOG4CPLUS_SINGLE_THREADED

#include <log4cplus/thread/threads.h>
#include <log4cplus/thread/impl/threads-impl.h>
#include <log4cplus/thread/impl/tls.h>
#include <log4cplus/ndc.h>
#include <log4cplus/helpers/loglog.h>
#include <log4cplus/helpers/stringhelper.h>
#include <log4cplus/helpers/timehelper.h>
#include <log4cplus/internal/internal.h>

#endif // LOG4CPLUS_SINGLE_THREADED

namespace log4cplus { namespace thread {

LOG4CPLUS_EXPORT
void
blockAllSignals()
{
#if defined (LOG4CPLUS_USE_PTHREADS)
    // Block all signals.
    sigset_t signal_set;
    sigfillset (&signal_set);
    pthread_sigmask (SIG_BLOCK, &signal_set, 0);
#endif
}

LOG4CPLUS_EXPORT
void
yield()
{
#if defined(LOG4CPLUS_USE_PTHREADS)
    sched_yield();
#elif defined(_WIN32)
    if (! SwitchToThread ())
        Sleep (0);
#endif
}

#if defined(LOG4CPLUS_SINGLE_THREADED)
static log4cplus::tstring thread_name(LOG4CPLUS_TEXT("single"))
    LOG4CPLUS_INIT_PRIORITY (LOG4CPLUS_INIT_PRIORITY_BASE - 1);
static log4cplus::tstring thread_name2(thread_name)
    LOG4CPLUS_INIT_PRIORITY (LOG4CPLUS_INIT_PRIORITY_BASE - 1);
#endif

LOG4CPLUS_EXPORT
log4cplus::tstring const &
getCurrentThreadName()
{
#if ! defined (LOG4CPLUS_SINGLE_THREADED)
    log4cplus::tstring & name = log4cplus::internal::get_thread_name_str ();
    if (LOG4CPLUS_UNLIKELY (name.empty ()))
    {
        log4cplus::tostringstream tmp;
        tmp << impl::getCurrentThreadId ();
        tmp.str ().swap (name);
    }
#else
    log4cplus::tstring & name = thread_name;
    if (LOG4CPLUS_UNLIKELY(name.empty()))
    {
        name = LOG4CPLUS_TEXT("single");
    }
#endif

    return name;
}

namespace
{

static
bool
get_current_thread_name_alt (log4cplus::tostream * s)
{
    log4cplus::tostream & os = *s;

#if defined (LOG4CPLUS_USE_PTHREADS) && defined (__linux__) \
    && defined (LOG4CPLUS_HAVE_GETTID)
    pid_t tid = syscall (SYS_gettid);
    os << tid;

#elif defined (__CYGWIN__)
    unsigned long tid = cygwin::get_current_win32_thread_id ();
    os << tid;

#else
    os << getCurrentThreadName ();

#endif

    return true;
}

} // namespace

LOG4CPLUS_EXPORT
log4cplus::tstring const &
getCurrentThreadName2()
{
#if ! defined (LOG4CPLUS_SINGLE_THREADED)
    log4cplus::tstring & name = log4cplus::internal::get_thread_name2_str ();
    if (LOG4CPLUS_UNLIKELY (name.empty ()))
    {
        log4cplus::tostringstream tmp;
        get_current_thread_name_alt (&tmp);
        tmp.str ().swap (name);
    }

#else
    log4cplus::tstring & name = thread_name2;
    if (LOG4CPLUS_UNLIKELY(name.empty()))
    {
        name = getCurrentThreadName();
    }

#endif

    return name;
}

LOG4CPLUS_EXPORT void setCurrentThreadName(const log4cplus::tstring & name)
{
#if ! defined (LOG4CPLUS_SINGLE_THREADED)
    log4cplus::internal::get_thread_name_str() = name;
#else
    thread_name = name;
#endif
}

LOG4CPLUS_EXPORT void setCurrentThreadName2(const log4cplus::tstring & name)
{
#if ! defined (LOG4CPLUS_SINGLE_THREADED)
    log4cplus::internal::get_thread_name2_str() = name;
#else
    thread_name2 = name;
#endif
}

} } // namespace log4cplus { namespace thread {

#ifndef LOG4CPLUS_SINGLE_THREADED

namespace
{

#  ifdef LOG4CPLUS_USE_PTHREADS
extern "C" void* threadStartFunc(void * param)
#  elif defined(LOG4CPLUS_USE_WIN32_THREADS)
static unsigned WINAPI threadStartFunc(void * param)
#  endif
{
    return log4cplus::thread::impl::ThreadStart::threadStartFuncWorker (param);
}

} // namespace

namespace log4cplus { namespace thread { namespace impl {

#if defined(LOG4CPLUS_USE_PTHREADS)
void*
ThreadStart::threadStartFuncWorker(void * arg)
#elif defined(LOG4CPLUS_USE_WIN32_THREADS)
unsigned
ThreadStart::threadStartFuncWorker(void * arg)
#endif
{
    blockAllSignals ();
    helpers::LogLog * loglog = helpers::LogLog::getLogLog();
    if (! arg)
        loglog->error(LOG4CPLUS_TEXT("threadStartFunc()- arg is NULL"));
    else
    {
        Thread * ptr = static_cast<Thread *>(arg);
        ThreadPtr thread(ptr);

        // Decrease reference count increased by Thread::start().
        ptr->removeReference ();

        try
        {
            thread->run();
        }
        catch(std::exception const & e)
        {
            tstring err = LOG4CPLUS_TEXT("threadStartFunc()- run() terminated with an exception: ");
            err += LOG4CPLUS_C_STR_TO_TSTRING(e.what());
            loglog->warn(err);
        }
        catch(...)
        {
            loglog->warn(LOG4CPLUS_TEXT("threadStartFunc()- run() terminated with an exception."));
        }

        thread::MutexGuard guard (thread->access_mutex);
        thread->flags &= ~Thread::fRUNNING;
    }

    threadCleanup ();

    return 0;
}

Thread::Thread()
    : flags (0)
#if defined(LOG4CPLUS_USE_WIN32_THREADS)
    , handle (INVALID_HANDLE_VALUE)
    , thread_id (0)
#else
    , handle ()
#endif
{
}

Thread::~Thread()
{
#if defined(LOG4CPLUS_USE_PTHREADS)
    if ((flags & fJOINED) == 0)
        pthread_detach (handle);

#elif defined(LOG4CPLUS_USE_WIN32_THREADS)
    if (handle != INVALID_HANDLE_VALUE)
        ::CloseHandle (handle);

#endif
}

void
Thread::start()
{
    flags |= fRUNNING;

    // Increase reference count here. It will be lowered by the running
    // thread itself.
    addReference ();

#if defined(LOG4CPLUS_USE_PTHREADS)
    if (pthread_create(&handle, NULL, threadStartFunc, this) )
    {
        removeReference ();
        flags &= ~fRUNNING;
        log4cplus::helpers::LogLog::getLogLog ()->error (
            LOG4CPLUS_TEXT ("Thread creation was not successful"), true);
    }
#elif defined(LOG4CPLUS_USE_WIN32_THREADS)
    HANDLE h = InterlockedExchangePointer (&handle, INVALID_HANDLE_VALUE);
    if (h != INVALID_HANDLE_VALUE)
        ::CloseHandle (h);

    h = reinterpret_cast<HANDLE>(
        ::_beginthreadex (0, 0, threadStartFunc, this, 0, &thread_id));
    if (! h)
    {
        removeReference ();
        flags &= ~fRUNNING;
        log4cplus::helpers::LogLog::getLogLog ()->error (
            LOG4CPLUS_TEXT ("Thread creation was not successful"), true);
    }
    h = InterlockedExchangePointer (&handle, h);
    assert (h == INVALID_HANDLE_VALUE);
#endif
}

bool
Thread::isRunning() const
{
    thread::MutexGuard guard (access_mutex);
    return (flags & fRUNNING) != 0;
}

os_id_type
Thread::getThreadId () const
{
#if defined(LOG4CPLUS_USE_PTHREADS)
    return handle;
#elif defined(LOG4CPLUS_USE_WIN32_THREADS)
    return thread_id;
#endif
}

os_handle_type
Thread::getThreadHandle () const
{
    return handle;
}

void
Thread::join ()
{
#if defined(LOG4CPLUS_USE_PTHREADS)
    pthread_join (handle, 0);
#elif defined(LOG4CPLUS_USE_WIN32_THREADS)
    ::WaitForSingleObject (handle, INFINITE);
#endif
    flags |= fJOINED;
}

} // namespace impl {

//
//
//

ThreadImplBase::~ThreadImplBase ()
{ }

//
//
//

namespace
{

class ThreadImpl
    : public impl::Thread
{
public:
    ThreadImpl ()
        : abs_thread (0)
    { }

    virtual ~ThreadImpl ()
    { }

    virtual
    void
    run ()
    {
        abs_thread->run ();
    }

    void
    set_abs_thread (AbstractThread * at)
    {
        abs_thread = at;
    }

protected:
    AbstractThread * abs_thread;
};

} // namespace

//
//
//

AbstractThread::AbstractThread ()
    : thread (new ThreadImpl)
{
    static_cast<ThreadImpl *>(thread.get ())->set_abs_thread (this);
}

bool
AbstractThread::isRunning() const
{
    return static_cast<ThreadImpl *>(thread.get ())->isRunning ();
}

void
AbstractThread::start()
{
    static_cast<ThreadImpl *>(thread.get ())->start ();
}

void
AbstractThread::join () const
{
    static_cast<ThreadImpl *>(thread.get ())->join ();
}

AbstractThread::~AbstractThread()
{ }

} } // namespace log4cplus { namespace thread {

#endif // LOG4CPLUS_SINGLE_THREADED
<|endoftext|>


<commit_before>#include <iostream>
#include <stdexcept>
#include <vector>

#include <pqxx/connection.h>
#include <pqxx/tablereader.h>
#include <pqxx/transaction.h>

using namespace PGSTD;
using namespace pqxx;

// Simple test program for libpqxx.  Read a table using a TableReader, which
// may be faster than a conventional query.  A TableReader is really a frontend
// for a PostgreSQL COPY TO stdout command.
//
// Usage: test8 [connect-string] [table]
//
// Where connect-string is a set of connection options in Postgresql's
// PQconnectdb() format, eg. "dbname=template1" to select from a database
// called template1, or "host=foo.bar.net user=smith" to connect to a backend
// running on host foo.bar.net, logging in as user smith.
//
// The default table name is "events" as used by other test programs.
// PostgreSQL currently implements pg_tables as a view, which cannot be read by
// using the COPY command.  Otherwise, pg_tables would have made a better
// default value here.
int main(int argc, char *argv[])
{
  try
  {
    // Set up a connection to the backend
    Connection C(argv[1] ? argv[1] : "");

    string Table = "events";
    if (argc > 2) Table = argv[2];

    // Begin a transaction acting on our current connection
    Transaction T(C, "test8");

    vector<string> R, First;

    {
      // Set up a TableReader stream to read data from table pg_tables
      TableReader Stream(T, Table);

      // Read results into string vectors and print them
      for (int n=0; (Stream >> R); ++n)
      {
        // Keep the first row for later consistency check
        if (n == 0) First = R;

        cout << n << ": ";
        for (vector<string>::const_iterator i = R.begin(); i != R.end(); ++i)
          cout << *i << '\t';
        cout << endl;
        R.clear();
      }
    }

    // Verify the contents we got for the first row
    if (!First.empty())
    {
      TableReader Verify(T, Table);
      string Line;

      if (!Verify.GetRawLine(Line))
	throw logic_error("TableReader got rows the first time around, "
	                  "but none the second time!");

      cout << "First tuple was: " << endl << Line << endl;

      Verify.Tokenize(Line, R);
      if (R != First)
        throw logic_error("Got different results re-parsing first tuple!");
    }
  }
  catch (const exception &e)
  {
    // All exceptions thrown by libpqxx are derived from std::exception
    cerr << "Exception: " << e.what() << endl;
    return 2;
  }
  catch (...)
  {
    // This is really unexpected (see above)
    cerr << "Unhandled exception" << endl;
    return 100;
  }

  return 0;
}

<commit_msg>*** empty log message ***<commit_after>#include <iostream>
#include <stdexcept>
#include <vector>

#include <pqxx/connection.h>
#include <pqxx/tablereader.h>
#include <pqxx/transaction.h>

using namespace PGSTD;
using namespace pqxx;

// Simple test program for libpqxx.  Read a table using a TableReader, which
// may be faster than a conventional query.  A TableReader is really a frontend
// for a PostgreSQL COPY TO stdout command.
//
// Usage: test8 [connect-string] [table]
//
// Where connect-string is a set of connection options in Postgresql's
// PQconnectdb() format, eg. "dbname=template1" to select from a database
// called template1, or "host=foo.bar.net user=smith" to connect to a backend
// running on host foo.bar.net, logging in as user smith.
//
// The default table name is "events" as used by other test programs.
// PostgreSQL currently implements pg_tables as a view, which cannot be read by
// using the COPY command.  Otherwise, pg_tables would have made a better
// default value here.
int main(int argc, char *argv[])
{
  try
  {
    // Set up a connection to the backend
    Connection C(argv[1] ? argv[1] : "");

    string Table = "events";
    if (argc > 2) Table = argv[2];

    // Begin a transaction acting on our current connection
    Transaction T(C, "test8");

    vector<string> R, First;

    // (Set up a block here to ensure our TableReader goes out of scope
    //  before our Transaction does, see below)
    {
      // Set up a TableReader stream to read data from table pg_tables
      TableReader Stream(T, Table);

      // Read results into string vectors and print them
      for (int n=0; (Stream >> R); ++n)
      {
        // Keep the first row for later consistency check
        if (n == 0) First = R;

        cout << n << ": ";
        for (vector<string>::const_iterator i = R.begin(); i != R.end(); ++i)
          cout << *i << '\t';
        cout << endl;
        R.clear();
      }
    }

    // Verify the contents we got for the first row
    if (!First.empty())
    {
      TableReader Verify(T, Table);
      string Line;

      if (!Verify.GetRawLine(Line))
	throw logic_error("TableReader got rows the first time around, "
	                  "but none the second time!");

      cout << "First tuple was: " << endl << Line << endl;

      Verify.Tokenize(Line, R);
      if (R != First)
        throw logic_error("Got different results re-parsing first tuple!");
    }
  }
  catch (const exception &e)
  {
    // All exceptions thrown by libpqxx are derived from std::exception
    cerr << "Exception: " << e.what() << endl;
    return 2;
  }
  catch (...)
  {
    // This is really unexpected (see above)
    cerr << "Unhandled exception" << endl;
    return 100;
  }

  return 0;
}

<|endoftext|>


<commit_before>
/*!
	\file

	\author Igor Mironchik (igor.mironchik at gmail dot com).

	Copyright (c) 2014 Igor Mironchik

	Permission is hereby granted, free of charge, to any person
	obtaining a copy of this software and associated documentation
	files (the "Software"), to deal in the Software without
	restriction, including without limitation the rights to use,
	copy, modify, merge, publish, distribute, sublicense, and/or sell
	copies of the Software, and to permit persons to whom the
	Software is furnished to do so, subject to the following
	conditions:

	The above copyright notice and this permission notice shall be
	included in all copies or substantial portions of the Software.

	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
	OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
	HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
	WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
	FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
	OTHER DEALINGS IN THE SOFTWARE.
*/

#ifndef QTMWIDGETS__TOOLBAR_HPP__INCLUDED
#define QTMWIDGETS__TOOLBAR_HPP__INCLUDED

// Qt include.
#include <QWidget>
#include <QScopedPointer>
#include <QAction>

namespace QtMWidgets {

//
// ToolButton
//

class ToolButtonPrivate;

/*!
	Button in the ToolBar.
*/
class ToolButton
	:	public QWidget
{
	Q_OBJECT

	/*!
		\property iconSize

		\brief size of icon.
	*/
	Q_PROPERTY( QSize iconSize READ iconSize WRITE setIconSize
		NOTIFY iconSizeChanged )

signals:
	/*!
		This signal is emitted when the icon size is changed. The \a
		iconSize parameter holds the toolbar's new icon size.

		\sa iconSize
	*/
	void iconSizeChanged( const QSize & iconSize );

public:
	explicit ToolButton( QAction * action, QWidget * parent = 0 );
	virtual ~ToolButton();

	//! \return Icon's size.
	QSize iconSize() const;

	//! \return Action for this button.
	QAction * action() const;

	virtual QSize minimumSizeHint() const;
	virtual QSize sizeHint() const;

public slots:
	//! Set icon's size.
	void setIconSize( const QSize & s );

protected:
	virtual void paintEvent( QPaintEvent * );
	virtual void mousePressEvent( QMouseEvent * e );
	virtual void mouseReleaseEvent( QMouseEvent * e );

private:
	Q_DISABLE_COPY( ToolButton )

	QScopedPointer< ToolButtonPrivate > d;
}; // class ToolButton

//
// ToolBar
//

class ToolBarPrivate;

/*!
	The ToolBar class provides a panel that contains a
	set of controls.
*/
class ToolBar
	:	public QWidget
{
	Q_OBJECT

	/*!
		\property orientation

		\brief orientation of the toolbar

		The default is Qt::Horizontal.
	*/
	Q_PROPERTY( Qt::Orientation orientation READ orientation
		WRITE setOrientation NOTIFY orientationChanged )
	/*!
		\property iconSize

		\brief size of icons in the toolbar.
	*/
	Q_PROPERTY( QSize iconSize READ iconSize WRITE setIconSize
		NOTIFY iconSizeChanged )

signals:
	/*!
		This signal is emitted when an action in this toolbar is triggered.
		This happens when the action's button is pressed, or when the
		action is triggered in some other way outside the toolbar. The parameter
		holds the triggered \a action.
	*/
	void actionTriggered( QAction * action );
	/*!
		This signal is emitted when the orientation of the toolbar changes.
		The \a orientation parameter holds the toolbar's new orientation.

		\sa orientation
	*/
	void orientationChanged( Qt::Orientation orientation );
	/*!
		This signal is emitted when the icon size is changed. The \a
		iconSize parameter holds the toolbar's new icon size.

		\sa iconSize
	*/
	void iconSizeChanged( const QSize & iconSize );

public:
	/*!
		Constructs a ToolBar with the given \a parent.
	*/
	explicit ToolBar( QWidget * parent = 0 );
	virtual ~ToolBar();

	//! Set orientation of the ToolBar.
	void setOrientation( Qt::Orientation orientation );
	//! \return Orientation of the ToolBar.
	Qt::Orientation orientation() const;

	/*!
		Removes all actions from the toolbar.

		\sa removeAction()
	*/
	void clear();

	/*!
		Appends the action to the toolbar's list of actions.

		\sa QWidget::addAction()
	*/
	using QWidget::addAction;

	/*!
		Creates a new action with the given \a icon. This
		action is added to the end of the toolbar.
	*/
	QAction * addAction( const QIcon & icon );
	/*!
		Creates a new action with the given \a icon. This
		action is added to the end of the toolbar. The action's
		QAction::triggered() signal is connected to \a
		member in \a receiver.
	*/
	QAction * addAction( const QIcon & icon,
		const QObject * receiver, const char * member );
	/*!
		Creates a new action with the given \a icon. This
		action is added to the end of the toolbar. The action's
		QAction::triggered() signal is connected to \a
		method in \a receiver.
	*/
	template <typename Func1>
	inline QAction * addAction( const QIcon & icon,
		const typename QtPrivate::FunctionPointer<Func1>::Object * receiver,
		Func1 slot )
	{
		QAction * action = new QAction( icon, QString(), this );
		QObject::connect( action, &QAction::triggered, receiver, slot );
		addAction( action );
		return action;
	}

	/*!
		Creates a new action with the given \a icon. This
		action is added to the end of the toolbar. The action's
		QAction::triggered() signal is connected to \a
		functor.
	*/
	template <typename Func1>
	inline QAction * addAction( const QIcon & icon, Func1 functor )
	{
		QAction * action = new QAction( icon, QString(), this );
		QObject::connect( action, &QAction::triggered, functor );
		addAction( action );
		return action;
	}

	/*!
		Returns the geometry of the toolbar item associated with the given
		\a action, or an invalid QRect if no matching item is found.
	*/
	QRect actionGeometry( QAction * action ) const;
	/*!
		Returns the action at point \a p. This function returns zero if no
		action was found.

		\sa QWidget::childAt()
	*/
	QAction * actionAt( const QPoint & p ) const;
	/*!
		Returns the action at the point \a x, \a y. This function returns
		zero if no action was found.
	*/
	inline QAction * actionAt( int x, int y ) const
	{
		return actionAt( QPoint( x, y ) );
	}

	//! \return Icon size of the ToolBar.
	QSize iconSize() const;

	virtual QSize minimumSizeHint() const;
	virtual QSize sizeHint() const;

public slots:
	//! Set icn's size of the ToolBar.
	void setIconSize( const QSize & iconSize );

protected:
	virtual void actionEvent( QActionEvent * event );

private slots:
	void _q_leftArrowClicked();
	void _q_rightArrowClicked();

private:
	Q_DISABLE_COPY( ToolBar )

	QScopedPointer< ToolBarPrivate > d;

}; // class ToolBar

} /* namespace QtMWidgets */

#endif // QTMWIDGETS__TOOLBAR_HPP__INCLUDED
<commit_msg>JJust code formatting.<commit_after>
/*!
	\file

	\author Igor Mironchik (igor.mironchik at gmail dot com).

	Copyright (c) 2014 Igor Mironchik

	Permission is hereby granted, free of charge, to any person
	obtaining a copy of this software and associated documentation
	files (the "Software"), to deal in the Software without
	restriction, including without limitation the rights to use,
	copy, modify, merge, publish, distribute, sublicense, and/or sell
	copies of the Software, and to permit persons to whom the
	Software is furnished to do so, subject to the following
	conditions:

	The above copyright notice and this permission notice shall be
	included in all copies or substantial portions of the Software.

	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
	OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
	HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
	WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
	FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
	OTHER DEALINGS IN THE SOFTWARE.
*/

#ifndef QTMWIDGETS__TOOLBAR_HPP__INCLUDED
#define QTMWIDGETS__TOOLBAR_HPP__INCLUDED

// Qt include.
#include <QWidget>
#include <QScopedPointer>
#include <QAction>

namespace QtMWidgets {

//
// ToolButton
//

class ToolButtonPrivate;

/*!
	Button in the ToolBar.
*/
class ToolButton
	:	public QWidget
{
	Q_OBJECT

	/*!
		\property iconSize

		\brief size of icon.
	*/
	Q_PROPERTY( QSize iconSize READ iconSize WRITE setIconSize
		NOTIFY iconSizeChanged )

signals:
	/*!
		This signal is emitted when the icon size is changed. The \a
		iconSize parameter holds the toolbar's new icon size.

		\sa iconSize
	*/
	void iconSizeChanged( const QSize & iconSize );

public:
	explicit ToolButton( QAction * action, QWidget * parent = 0 );
	virtual ~ToolButton();

	//! \return Icon's size.
	QSize iconSize() const;

	//! \return Action for this button.
	QAction * action() const;

	virtual QSize minimumSizeHint() const;
	virtual QSize sizeHint() const;

public slots:
	//! Set icon's size.
	void setIconSize( const QSize & s );

protected:
	virtual void paintEvent( QPaintEvent * );
	virtual void mousePressEvent( QMouseEvent * e );
	virtual void mouseReleaseEvent( QMouseEvent * e );

private:
	Q_DISABLE_COPY( ToolButton )

	QScopedPointer< ToolButtonPrivate > d;
}; // class ToolButton

//
// ToolBar
//

class ToolBarPrivate;

/*!
	The ToolBar class provides a panel that contains a
	set of controls.
*/
class ToolBar
	:	public QWidget
{
	Q_OBJECT

	/*!
		\property orientation

		\brief orientation of the toolbar

		The default is Qt::Horizontal.
	*/
	Q_PROPERTY( Qt::Orientation orientation READ orientation
		WRITE setOrientation NOTIFY orientationChanged )
	/*!
		\property iconSize

		\brief size of icons in the toolbar.
	*/
	Q_PROPERTY( QSize iconSize READ iconSize WRITE setIconSize
		NOTIFY iconSizeChanged )

signals:
	/*!
		This signal is emitted when an action in this toolbar is triggered.
		This happens when the action's button is pressed, or when the
		action is triggered in some other way outside the toolbar. The parameter
		holds the triggered \a action.
	*/
	void actionTriggered( QAction * action );
	/*!
		This signal is emitted when the orientation of the toolbar changes.
		The \a orientation parameter holds the toolbar's new orientation.

		\sa orientation
	*/
	void orientationChanged( Qt::Orientation orientation );
	/*!
		This signal is emitted when the icon size is changed. The \a
		iconSize parameter holds the toolbar's new icon size.

		\sa iconSize
	*/
	void iconSizeChanged( const QSize & iconSize );

public:
	/*!
		Constructs a ToolBar with the given \a parent.
	*/
	explicit ToolBar( QWidget * parent = 0 );
	virtual ~ToolBar();

	//! Set orientation of the ToolBar.
	void setOrientation( Qt::Orientation orientation );
	//! \return Orientation of the ToolBar.
	Qt::Orientation orientation() const;

	/*!
		Removes all actions from the toolbar.

		\sa removeAction()
	*/
	void clear();

	/*!
		Appends the action to the toolbar's list of actions.

		\sa QWidget::addAction()
	*/
	using QWidget::addAction;

	/*!
		Creates a new action with the given \a icon. This
		action is added to the end of the toolbar.
	*/
	QAction * addAction( const QIcon & icon );
	/*!
		Creates a new action with the given \a icon. This
		action is added to the end of the toolbar. The action's
		QAction::triggered() signal is connected to \a
		member in \a receiver.
	*/
	QAction * addAction( const QIcon & icon,
		const QObject * receiver, const char * member );
	/*!
		Creates a new action with the given \a icon. This
		action is added to the end of the toolbar. The action's
		QAction::triggered() signal is connected to \a
		method in \a receiver.
	*/
	template <typename Func1>
	inline QAction * addAction( const QIcon & icon,
		const typename QtPrivate::FunctionPointer< Func1 >::Object * receiver,
		Func1 slot )
	{
		QAction * action = new QAction( icon, QString(), this );
		QObject::connect( action, &QAction::triggered, receiver, slot );
		addAction( action );
		return action;
	}

	/*!
		Creates a new action with the given \a icon. This
		action is added to the end of the toolbar. The action's
		QAction::triggered() signal is connected to \a
		functor.
	*/
	template <typename Func1>
	inline QAction * addAction( const QIcon & icon, Func1 functor )
	{
		QAction * action = new QAction( icon, QString(), this );
		QObject::connect( action, &QAction::triggered, functor );
		addAction( action );
		return action;
	}

	/*!
		Returns the geometry of the toolbar item associated with the given
		\a action, or an invalid QRect if no matching item is found.
	*/
	QRect actionGeometry( QAction * action ) const;
	/*!
		Returns the action at point \a p. This function returns zero if no
		action was found.

		\sa QWidget::childAt()
	*/
	QAction * actionAt( const QPoint & p ) const;
	/*!
		Returns the action at the point \a x, \a y. This function returns
		zero if no action was found.
	*/
	inline QAction * actionAt( int x, int y ) const
	{
		return actionAt( QPoint( x, y ) );
	}

	//! \return Icon size of the ToolBar.
	QSize iconSize() const;

	virtual QSize minimumSizeHint() const;
	virtual QSize sizeHint() const;

public slots:
	//! Set icn's size of the ToolBar.
	void setIconSize( const QSize & iconSize );

protected:
	virtual void actionEvent( QActionEvent * event );

private slots:
	void _q_leftArrowClicked();
	void _q_rightArrowClicked();

private:
	Q_DISABLE_COPY( ToolBar )

	QScopedPointer< ToolBarPrivate > d;

}; // class ToolBar

} /* namespace QtMWidgets */

#endif // QTMWIDGETS__TOOLBAR_HPP__INCLUDED
<|endoftext|>


<commit_before>#pragma once

#include <mapbox/geojsonvt/convert.hpp>
#include <mapbox/geojsonvt/tile.hpp>
#include <mapbox/geojsonvt/types.hpp>
#include <mapbox/geojsonvt/wrap.hpp>

#include <chrono>
#include <cmath>
#include <map>
#include <unordered_map>

namespace mapbox {
namespace geojsonvt {

struct Options {
    // max zoom to preserve detail on
    uint8_t maxZoom = 18;

    // max zoom in the tile index
    uint8_t indexMaxZoom = 5;

    // max number of points per tile in the tile index
    uint32_t indexMaxPoints = 100000;

    // whether to tile solid square tiles further
    bool solidChildren = false;

    // simplification tolerance (higher means simpler)
    double tolerance = 3;

    // tile extent
    uint16_t extent = 4096;

    // tile buffer on each side
    uint16_t buffer = 64;
};

const Tile empty_tile{};

inline uint64_t toID(uint8_t z, uint32_t x, uint32_t y) {
    return (((1 << z) * y + x) * 32) + z;
}

class GeoJSONVT {
public:
    const Options options;

    GeoJSONVT(const mapbox::geometry::feature_collection<double>& features_,
              const Options& options_ = Options())
        : options(options_) {

        const uint32_t z2 = std::pow(2, options.maxZoom);

        auto converted = detail::convert(features_, options.tolerance / (z2 * options.extent));
        auto features = detail::wrap(converted, double(options.buffer) / options.extent);

        splitTile(features, 0, 0, 0);
    }

    std::map<uint8_t, uint32_t> stats;
    uint32_t total = 0;

    const Tile& getTile(const uint8_t z, const uint32_t x_, const uint32_t y) {

        if (z > options.maxZoom)
            throw std::runtime_error("Requested zoom higher than maxZoom: " + std::to_string(z));

        const uint32_t z2 = std::pow(2, z);
        const uint32_t x = ((x_ % z2) + z2) % z2; // wrap tile x coordinate
        const uint64_t id = toID(z, x, y);

        auto it = tiles.find(id);
        if (it != tiles.end())
            return it->second.tile;

        it = findParent(z, x, y);

        if (it == tiles.end())
            return empty_tile;

        // if we found a parent tile containing the original geometry, we can drill down from it
        const auto& parent = it->second;

        // parent tile is a solid clipped square, return it instead since it's identical
        if (parent.is_solid)
            return parent.tile;

        // drill down parent tile up to the requested one
        splitTile(parent.source_features, parent.z, parent.x, parent.y, z, x, y);

        it = tiles.find(id);
        if (it != tiles.end())
            return it->second.tile;

        // drilling stopped because parent was a solid square; return it instead
        it = findParent(z, x, y);
        if (it != tiles.end())
            return it->second.tile;

        return empty_tile;
    }

private:
    std::unordered_map<uint64_t, detail::InternalTile> tiles;

    std::unordered_map<uint64_t, detail::InternalTile>::iterator
    findParent(const uint8_t z, const uint32_t x, const uint32_t y) {
        uint8_t z0 = z;
        uint32_t x0 = x;
        uint32_t y0 = y;

        const auto end = tiles.end();
        auto parent = end;

        while ((parent == end) && (z0 != 0)) {
            z0--;
            x0 = x0 / 2;
            y0 = y0 / 2;
            parent = tiles.find(toID(z0, x0, y0));
        }

        return parent;
    }

    void splitTile(const detail::vt_features& features,
                   const uint8_t z,
                   const uint32_t x,
                   const uint32_t y,
                   const uint8_t cz = 0,
                   const uint32_t cx = 0,
                   const uint32_t cy = 0) {

        if (features.empty())
            return;

        const double z2 = 1 << z;
        const uint64_t id = toID(z, x, y);

        auto it = tiles.find(id);

        if (it == tiles.end()) {
            const double tolerance =
                (z == options.maxZoom ? 0 : options.tolerance / (z2 * options.extent));

            it = tiles
                     .emplace(id, detail::InternalTile{ features, z, x, y, options.extent,
                                                        options.buffer, tolerance })
                     .first;
            stats[z] = (stats.count(z) ? stats[z] + 1 : 1);
            total++;
            // printf("tile z%i-%i-%i\n", z, x, y);
        }

        auto& tile = it->second;

        // stop tiling if the tile is solid clipped square
        if (!options.solidChildren && tile.is_solid) {
            return;
        }

        // if it's the first-pass tiling
        if (cz == 0u) {
            // stop tiling if we reached max zoom, or if the tile is too simple
            if (z == options.indexMaxZoom || tile.tile.num_points <= options.indexMaxPoints) {
                tile.source_features = features;
                return;
            }

        } else { // drilldown to a specific tile;
            // stop tiling if we reached base zoom
            if (z == options.maxZoom)
                return;

            // stop tiling if it's our target tile zoom
            if (z == cz) {
                tile.source_features = features;
                return;
            }

            // stop tiling if it's not an ancestor of the target tile
            const double m = 1 << (cz - z);
            if (x != static_cast<uint32_t>(std::floor(cx / m)) ||
                y != static_cast<uint32_t>(std::floor(cy / m))) {
                tile.source_features = features;
                return;
            }
        }

        const double p = 0.5 * options.buffer / options.extent;
        const auto& min = tile.bbox.min;
        const auto& max = tile.bbox.max;

        const auto left = detail::clip<0>(features, (x - p) / z2, (x + 0.5 + p) / z2, min.x, max.x);

        if (!left.empty()) {
            splitTile(detail::clip<1>(left, (y - p) / z2, (y + 0.5 + p) / z2, min.y, max.y), z + 1,
                      x * 2, y * 2);
            splitTile(detail::clip<1>(left, (y + 0.5 - p) / z2, (y + 1 + p) / z2, min.y, max.y),
                      z + 1, x * 2, y * 2 + 1);
        }

        const auto right =
            detail::clip<0>(features, (x + 0.5 - p) / z2, (x + 1 + p) / z2, min.x, max.x);

        if (!right.empty()) {
            splitTile(detail::clip<1>(right, (y - p) / z2, (y + 0.5 + p) / z2, min.y, max.y), z + 1,
                      x * 2 + 1, y * 2);
            splitTile(detail::clip<1>(right, (y + 0.5 - p) / z2, (y + 1 + p) / z2, min.y, max.y),
                      z + 1, x * 2 + 1, y * 2 + 1);
        }

        // if we sliced further down, no need to keep source geometry
        tile.source_features = {};
    }
};

} // namespace geojsonvt
} // namespace mapbox
<commit_msg>fix getTile for empty tiles<commit_after>#pragma once

#include <mapbox/geojsonvt/convert.hpp>
#include <mapbox/geojsonvt/tile.hpp>
#include <mapbox/geojsonvt/types.hpp>
#include <mapbox/geojsonvt/wrap.hpp>

#include <chrono>
#include <cmath>
#include <map>
#include <unordered_map>

namespace mapbox {
namespace geojsonvt {

struct Options {
    // max zoom to preserve detail on
    uint8_t maxZoom = 18;

    // max zoom in the tile index
    uint8_t indexMaxZoom = 5;

    // max number of points per tile in the tile index
    uint32_t indexMaxPoints = 100000;

    // whether to tile solid square tiles further
    bool solidChildren = false;

    // simplification tolerance (higher means simpler)
    double tolerance = 3;

    // tile extent
    uint16_t extent = 4096;

    // tile buffer on each side
    uint16_t buffer = 64;
};

const Tile empty_tile{};

inline uint64_t toID(uint8_t z, uint32_t x, uint32_t y) {
    return (((1 << z) * y + x) * 32) + z;
}

class GeoJSONVT {
public:
    const Options options;

    GeoJSONVT(const mapbox::geometry::feature_collection<double>& features_,
              const Options& options_ = Options())
        : options(options_) {

        const uint32_t z2 = std::pow(2, options.maxZoom);

        auto converted = detail::convert(features_, options.tolerance / (z2 * options.extent));
        auto features = detail::wrap(converted, double(options.buffer) / options.extent);

        splitTile(features, 0, 0, 0);
    }

    std::map<uint8_t, uint32_t> stats;
    uint32_t total = 0;

    const Tile& getTile(const uint8_t z, const uint32_t x_, const uint32_t y) {

        if (z > options.maxZoom)
            throw std::runtime_error("Requested zoom higher than maxZoom: " + std::to_string(z));

        const uint32_t z2 = std::pow(2, z);
        const uint32_t x = ((x_ % z2) + z2) % z2; // wrap tile x coordinate
        const uint64_t id = toID(z, x, y);

        auto it = tiles.find(id);
        if (it != tiles.end())
            return it->second.tile;

        it = findParent(z, x, y);

        if (it == tiles.end())
            throw std::runtime_error("Parent tile not found");

        // if we found a parent tile containing the original geometry, we can drill down from it
        const auto& parent = it->second;

        // parent tile is a solid clipped square, return it instead since it's identical
        if (parent.is_solid)
            return parent.tile;

        // drill down parent tile up to the requested one
        splitTile(parent.source_features, parent.z, parent.x, parent.y, z, x, y);

        it = tiles.find(id);
        if (it != tiles.end())
            return it->second.tile;

        it = findParent(z, x, y);
        if (it == tiles.end())
            throw std::runtime_error("Parent tile not found");

        // drilling stopped because parent was a solid square; return it instead
        if (it->second.is_solid)
            return it->second.tile;

        // otherwise it was an empty tile
        return empty_tile;
    }

private:
    std::unordered_map<uint64_t, detail::InternalTile> tiles;

    std::unordered_map<uint64_t, detail::InternalTile>::iterator
    findParent(const uint8_t z, const uint32_t x, const uint32_t y) {
        uint8_t z0 = z;
        uint32_t x0 = x;
        uint32_t y0 = y;

        const auto end = tiles.end();
        auto parent = end;

        while ((parent == end) && (z0 != 0)) {
            z0--;
            x0 = x0 / 2;
            y0 = y0 / 2;
            parent = tiles.find(toID(z0, x0, y0));
        }

        return parent;
    }

    void splitTile(const detail::vt_features& features,
                   const uint8_t z,
                   const uint32_t x,
                   const uint32_t y,
                   const uint8_t cz = 0,
                   const uint32_t cx = 0,
                   const uint32_t cy = 0) {

        const double z2 = 1 << z;
        const uint64_t id = toID(z, x, y);

        auto it = tiles.find(id);

        if (it == tiles.end()) {
            const double tolerance =
                (z == options.maxZoom ? 0 : options.tolerance / (z2 * options.extent));

            it = tiles
                     .emplace(id, detail::InternalTile{ features, z, x, y, options.extent,
                                                        options.buffer, tolerance })
                     .first;
            stats[z] = (stats.count(z) ? stats[z] + 1 : 1);
            total++;
            // printf("tile z%i-%i-%i\n", z, x, y);
        }

        auto& tile = it->second;

        if (features.empty())
            return;

        // stop tiling if the tile is solid clipped square
        if (!options.solidChildren && tile.is_solid)
            return;

        // if it's the first-pass tiling
        if (cz == 0u) {
            // stop tiling if we reached max zoom, or if the tile is too simple
            if (z == options.indexMaxZoom || tile.tile.num_points <= options.indexMaxPoints) {
                tile.source_features = features;
                return;
            }

        } else { // drilldown to a specific tile;
            // stop tiling if we reached base zoom
            if (z == options.maxZoom)
                return;

            // stop tiling if it's our target tile zoom
            if (z == cz) {
                tile.source_features = features;
                return;
            }

            // stop tiling if it's not an ancestor of the target tile
            const double m = 1 << (cz - z);
            if (x != static_cast<uint32_t>(std::floor(cx / m)) ||
                y != static_cast<uint32_t>(std::floor(cy / m))) {
                tile.source_features = features;
                return;
            }
        }

        const double p = 0.5 * options.buffer / options.extent;
        const auto& min = tile.bbox.min;
        const auto& max = tile.bbox.max;

        const auto left = detail::clip<0>(features, (x - p) / z2, (x + 0.5 + p) / z2, min.x, max.x);

        splitTile(detail::clip<1>(left, (y - p) / z2, (y + 0.5 + p) / z2, min.y, max.y), z + 1,
                  x * 2, y * 2);
        splitTile(detail::clip<1>(left, (y + 0.5 - p) / z2, (y + 1 + p) / z2, min.y, max.y),
                  z + 1, x * 2, y * 2 + 1);

        const auto right =
            detail::clip<0>(features, (x + 0.5 - p) / z2, (x + 1 + p) / z2, min.x, max.x);

        splitTile(detail::clip<1>(right, (y - p) / z2, (y + 0.5 + p) / z2, min.y, max.y), z + 1,
                  x * 2 + 1, y * 2);
        splitTile(detail::clip<1>(right, (y + 0.5 - p) / z2, (y + 1 + p) / z2, min.y, max.y),
                  z + 1, x * 2 + 1, y * 2 + 1);

        // if we sliced further down, no need to keep source geometry
        tile.source_features = {};
    }
};

} // namespace geojsonvt
} // namespace mapbox
<|endoftext|>


<commit_before>/*
    This file is part of KOrganizer.
    Copyright (c) 2002 Jan-Pascal van Best <janpascal@vanbest.org>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    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 General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include <qfile.h>

#include <kapplication.h>
#include <kconfig.h>
#include <kstandarddirs.h>

#include <kurl.h>
#include <kdebug.h>

#include <kapp.h>
#include <kmessagebox.h>
#include <klocale.h>
#include <kaction.h>

#include "korganizer/korganizer.h"
#include "korganizer/calendarview.h"

#include <exchangeclient.h>
#include <exchangeaccount.h>

#include "exchange.h"
#include "exchangedialog.h"
#include "exchangeconfig.h"

using namespace KCal; // Needed for connecting slots

class ExchangeFactory : public KOrg::PartFactory {
  public:
    KOrg::Part *create(KOrg::MainWindow *parent, const char *name)
    {
      return new Exchange(parent,name);
    }
};

extern "C" {
  void *init_libkorg_exchange()
  {
    kdDebug() << "Registering Exchange Plugin...\n";
    return (new ExchangeFactory);
  }
}

Exchange::Exchange(KOrg::MainWindow *parent, const char *name) :
  KOrg::Part(parent,name)
{
  kdDebug() << "Creating Exchange Plugin...\n";

  mAccount = new KPIM::ExchangeAccount( "Calendar/Exchange Plugin" );
  mClient = new KPIM::ExchangeClient( mAccount );
  mClient->setWindow( parent );

  setXMLFile("plugins/exchangeui.rc");

  new KAction(i18n("Download..."), 0, this, SLOT(download()),
              actionCollection(), "exchange_download");

//  new KAction(i18n("Test"), 0, this, SLOT(test()),
//              actionCollection(), "exchange_test");

  KAction *action = new KAction(i18n("Upload Event..."), 0, this, SLOT(upload()),
                                actionCollection(), "exchange_upload");
  QObject::connect(mainWindow()->view(),SIGNAL(incidenceSelected(Incidence *)),
            this, SLOT(slotIncidenceSelected(Incidence *)));
  action->setEnabled( false );
  QObject::connect(this,SIGNAL(enableIncidenceActions(bool)),
          action,SLOT(setEnabled(bool)));
//          action,SLOT(setEnabled(bool)));

  action = new KAction(i18n("Delete Event"), 0, this, SLOT(remove()),
                                actionCollection(), "exchange_delete");
  QObject::connect(this,SIGNAL(enableIncidenceActions(bool)),
          action,SLOT(setEnabled(bool)));
  action->setEnabled( false );

  new KAction(i18n("Configure..."), 0, this, SLOT(configure()),
              actionCollection(), "exchange_configure");

  connect( this, SIGNAL( calendarChanged() ), mainWindow()->view(), SLOT( updateView() ) );
  connect( this, SIGNAL( calendarChanged(const QDate &, const QDate &)),
    mainWindow()->view(), SLOT(updateView(const QDate &, const QDate &)) );
}

Exchange::~Exchange()
{
  kdDebug() << "Exchange Plugin destructor" << endl;
}

QString Exchange::info()
{
  return i18n("This plugin imports and export calendar events from/to a Microsoft Exchange 2000 Server.");
}

void  Exchange::slotIncidenceSelected( Incidence *incidence )
{
  emit enableIncidenceActions( incidence != 0 );
}

void Exchange::download()
{
  ExchangeDialog dialog( mainWindow()->view()->startDate(), mainWindow()->view()->endDate() );

  if (dialog.exec() != QDialog::Accepted )
    return;

  QDate start = dialog.m_start->date();
  QDate end = dialog.m_end->date();

  KCal::Calendar* calendar = mainWindow()->view()->calendar();

  mClient->downloadSynchronous(calendar, start, end, true );

  emit calendarChanged();
}

void Exchange::upload()
{
  kdDebug() << "Called Exchange::upload()" << endl;

  Event* event = static_cast<Event *> ( mainWindow()->view()->currentSelection() );
  if ( ! event )
  {
    KMessageBox::information( 0L, i18n("Please select an appointment"), i18n("Exchange Plugin") );
    return;
  }
  if ( KMessageBox::warningContinueCancel( 0L, "Exchange Upload is EXPERIMENTAL, you may lose data on this appointment!", i18n("Exchange Plugin") )
       == KMessageBox::Continue ) {
    kdDebug() << "Trying to add appointment " << event->summary() << endl;
    mClient->uploadSynchronous( event );
  }
}

void Exchange::remove()
{
  kdDebug() << "Called Exchange::remove()" << endl;

  Event* event = static_cast<Event *> ( mainWindow()->view()->currentSelection() );
  if ( ! event )
  {
    KMessageBox::information( 0L, i18n("Please select an appointment"), i18n("Exchange Plugin") );
    return;
  }

  if ( KMessageBox::warningContinueCancel( 0L, "Exchange Delete is EXPERIMENTAL, if this is a recurring event it will delete all instances!", i18n("Exchange Plugin") )
       == KMessageBox::Continue ) {
    kdDebug() << "Trying to delete appointment " << event->summary() << endl;
    mClient->removeSynchronous( event );
    mainWindow()->view()->calendar()->deleteEvent( event );
    emit calendarChanged();
  }
}

void Exchange::configure()
{
  kdDebug() << "Exchange::configure" << endl;
  ExchangeConfig dialog( mAccount );

  if (dialog.exec() == QDialog::Accepted )
    mAccount->save( "Calendar/Exchange Plugin" );
}

void Exchange::test()
{
  kdDebug() << "Entering test()" << endl;
  mClient->test();
}

void Exchange::test2()
{
  kdDebug() << "Entering test2()" << endl;
}
#include "exchange.moc"
<commit_msg>+    KGlobal::locale()->insertCatalogue("libkpimexchange");<commit_after>/*
    This file is part of KOrganizer.
    Copyright (c) 2002 Jan-Pascal van Best <janpascal@vanbest.org>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    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 General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include <qfile.h>

#include <kapplication.h>
#include <kconfig.h>
#include <kstandarddirs.h>

#include <kurl.h>
#include <kdebug.h>

#include <kmessagebox.h>
#include <klocale.h>
#include <kaction.h>
#include <kglobal.h>

#include "korganizer/korganizer.h"
#include "korganizer/calendarview.h"

#include <exchangeclient.h>
#include <exchangeaccount.h>

#include "exchange.h"
#include "exchangedialog.h"
#include "exchangeconfig.h"

using namespace KCal; // Needed for connecting slots

class ExchangeFactory : public KOrg::PartFactory {
  public:
    KOrg::Part *create(KOrg::MainWindow *parent, const char *name)
    {
      return new Exchange(parent,name);
    }
};

extern "C" {
  void *init_libkorg_exchange()
  {
    kdDebug() << "Registering Exchange Plugin...\n";
    KGlobal::locale()->insertCatalogue("libkpimexchange");
    return (new ExchangeFactory);
  }
}

Exchange::Exchange(KOrg::MainWindow *parent, const char *name) :
  KOrg::Part(parent,name)
{
  kdDebug() << "Creating Exchange Plugin...\n";

  mAccount = new KPIM::ExchangeAccount( "Calendar/Exchange Plugin" );
  mClient = new KPIM::ExchangeClient( mAccount );
  mClient->setWindow( parent );

  setXMLFile("plugins/exchangeui.rc");

  new KAction(i18n("Download..."), 0, this, SLOT(download()),
              actionCollection(), "exchange_download");

//  new KAction(i18n("Test"), 0, this, SLOT(test()),
//              actionCollection(), "exchange_test");

  KAction *action = new KAction(i18n("Upload Event..."), 0, this, SLOT(upload()),
                                actionCollection(), "exchange_upload");
  QObject::connect(mainWindow()->view(),SIGNAL(incidenceSelected(Incidence *)),
            this, SLOT(slotIncidenceSelected(Incidence *)));
  action->setEnabled( false );
  QObject::connect(this,SIGNAL(enableIncidenceActions(bool)),
          action,SLOT(setEnabled(bool)));
//          action,SLOT(setEnabled(bool)));

  action = new KAction(i18n("Delete Event"), 0, this, SLOT(remove()),
                                actionCollection(), "exchange_delete");
  QObject::connect(this,SIGNAL(enableIncidenceActions(bool)),
          action,SLOT(setEnabled(bool)));
  action->setEnabled( false );

  new KAction(i18n("Configure..."), 0, this, SLOT(configure()),
              actionCollection(), "exchange_configure");

  connect( this, SIGNAL( calendarChanged() ), mainWindow()->view(), SLOT( updateView() ) );
  connect( this, SIGNAL( calendarChanged(const QDate &, const QDate &)),
    mainWindow()->view(), SLOT(updateView(const QDate &, const QDate &)) );
}

Exchange::~Exchange()
{
  kdDebug() << "Exchange Plugin destructor" << endl;
}

QString Exchange::info()
{
  return i18n("This plugin imports and export calendar events from/to a Microsoft Exchange 2000 Server.");
}

void  Exchange::slotIncidenceSelected( Incidence *incidence )
{
  emit enableIncidenceActions( incidence != 0 );
}

void Exchange::download()
{
  ExchangeDialog dialog( mainWindow()->view()->startDate(), mainWindow()->view()->endDate() );

  if (dialog.exec() != QDialog::Accepted )
    return;

  QDate start = dialog.m_start->date();
  QDate end = dialog.m_end->date();

  KCal::Calendar* calendar = mainWindow()->view()->calendar();

  mClient->downloadSynchronous(calendar, start, end, true );

  emit calendarChanged();
}

void Exchange::upload()
{
  kdDebug() << "Called Exchange::upload()" << endl;

  Event* event = static_cast<Event *> ( mainWindow()->view()->currentSelection() );
  if ( ! event )
  {
    KMessageBox::information( 0L, i18n("Please select an appointment"), i18n("Exchange Plugin") );
    return;
  }
  if ( KMessageBox::warningContinueCancel( 0L, i18n("Exchange Upload is EXPERIMENTAL, you may lose data on this appointment!"), i18n("Exchange Plugin") )
       == KMessageBox::Continue ) {
    kdDebug() << "Trying to add appointment " << event->summary() << endl;
    mClient->uploadSynchronous( event );
  }
}

void Exchange::remove()
{
  kdDebug() << "Called Exchange::remove()" << endl;

  Event* event = static_cast<Event *> ( mainWindow()->view()->currentSelection() );
  if ( ! event )
  {
    KMessageBox::information( 0L, i18n("Please select an appointment"), i18n("Exchange Plugin") );
    return;
  }

  if ( KMessageBox::warningContinueCancel( 0L, i18n("Exchange Delete is EXPERIMENTAL, if this is a recurring event it will delete all instances!"), i18n("Exchange Plugin") )
       == KMessageBox::Continue ) {
    kdDebug() << "Trying to delete appointment " << event->summary() << endl;
    mClient->removeSynchronous( event );
    mainWindow()->view()->calendar()->deleteEvent( event );
    emit calendarChanged();
  }
}

void Exchange::configure()
{
  kdDebug() << "Exchange::configure" << endl;
  ExchangeConfig dialog( mAccount );

  if (dialog.exec() == QDialog::Accepted )
    mAccount->save( "Calendar/Exchange Plugin" );
}

void Exchange::test()
{
  kdDebug() << "Entering test()" << endl;
  mClient->test();
}

void Exchange::test2()
{
  kdDebug() << "Entering test2()" << endl;
}
#include "exchange.moc"
<|endoftext|>


<commit_before>/******************************************************************************
* Copyright (c) 2012, Howard Butler (hobu.inc@gmail.com)
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
*     * Redistributions of source code must retain the above copyright
*       notice, this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright
*       notice, this list of conditions and the following disclaimer in
*       the documentation and/or other materials provided
*       with the distribution.
*     * Neither the name of Hobu, Inc. or Flaxen Geo Consulting nor the
*       names of its contributors may be used to endorse or promote
*       products derived from this software without specific prior
*       written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
****************************************************************************/

#pragma once

#include <pdal/pdal_internal.hpp>
//
// macros for creating the various stage types
//
#define MAKE_READER_CREATOR(T, FullT) \
    pdal::Reader* create_##T() \
        { pdal::Reader *r = new FullT(); return r; }
#define MAKE_FILTER_CREATOR(T, FullT) \
    pdal::Filter* create_##T() \
        { pdal::Filter *f = new FullT(); return f; }
#define MAKE_WRITER_CREATOR(T, FullT) \
    pdal::Writer* create_##T() \
        { pdal::Writer *w = new FullT(); return w; }
#define MAKE_KERNEL_CREATOR(T, FullT) \
    pdal::Kernel* create_##T() \
        { pdal::Kernel *k = new FullT(); return k; }

//
// macros to register the stage creators
//
#define REGISTER_WRITER(T, FullT) \
    registerDriverInfo<FullT>(); \
    registerWriter(FullT::s_getName(), create_##T)
#define REGISTER_READER(T, FullT) \
    registerDriverInfo<FullT>(); \
    registerReader(FullT::s_getName(), create_##T)
#define REGISTER_FILTER(T, FullT) \
    registerDriverInfo<FullT>(); \
    registerFilter(FullT::s_getName(), create_##T)
#define REGISTER_KERNEL(T, FullT) \
    registerKernelDriverInfo<FullT>(); \
    registerKernel(FullT::s_getName(), create_##T)

//
// macros to create the various plugins types
//
#define CREATE_READER_PLUGIN(T, FullT) \
    MAKE_READER_CREATOR(T, FullT) \
    PDAL_C_START PDAL_DLL void PDALRegister_reader_##T(void* factory) \
    { \
        pdal::StageFactory& f = *(pdal::StageFactory*) factory; \
        f.registerDriverInfo< FullT>(); \
        f.registerReader(FullT::s_getName(), create_##T); \
    } \
    PDAL_C_END \
    SET_READER_PLUGIN_VERSION(T)
#define CREATE_FILTER_PLUGIN(T, FullT) \
    MAKE_FILTER_CREATOR(T, FullT) \
    PDAL_C_START PDAL_DLL void PDALRegister_filter_##T(void* factory) \
    { \
        pdal::StageFactory& f = *(pdal::StageFactory*) factory; \
        f.registerDriverInfo< FullT>(); \
        f.registerFilter(FullT::s_getName(), create_##T); \
    } \
    PDAL_C_END \
    SET_FILTER_PLUGIN_VERSION(T)
#define CREATE_WRITER_PLUGIN(T, FullT) \
    MAKE_WRITER_CREATOR(T, FullT) \
    PDAL_C_START PDAL_DLL void PDALRegister_writer_##T(void* factory) \
    { \
        pdal::StageFactory& f = *(pdal::StageFactory*) factory; \
        f.registerDriverInfo< FullT>(); \
        f.registerWriter(FullT::s_getName(), create_##T); \
    } \
    PDAL_C_END \
    SET_WRITER_PLUGIN_VERSION(T)
#define CREATE_KERNEL_PLUGIN(T, FullT) \
    MAKE_KERNEL_CREATOR(T, FullT) \
    PDAL_C_START PDAL_DLL void PDALRegister_kernel_##T(void* factory) \
    { \
        pdal::KernelFactory& f = *(pdal::KernelFactory*) factory; \
        f.registerKernelDriverInfo< FullT>(); \
        f.registerKernel(FullT::s_getName(), create_##T); \
    } \
    PDAL_C_END \
    SET_KERNEL_PLUGIN_VERSION(T)

//
// macros to register the plugin creators
//
//#define REGISTER_READER_PLUGIN(T) \
//    PDAL_C_START \
//    PDAL_DLL void PDALRegister_reader_##T(void* factory); \
//    PDAL_C_END
//#define REGISTER_FILTER_PLUGIN(T) \
//    PDAL_C_START \
//    PDAL_DLL void PDALRegister_filter_##T(void* factory); \
//    PDAL_C_END
//#define REGISTER_WRITER_PLUGIN(T) \
//    PDAL_C_START \
//    PDAL_DLL void PDALRegister_writer_##T(void* factory); \
//    PDAL_C_END
//#define REGISTER_KERNEL_PLUGIN(T) \
//    PDAL_C_START \
//    PDAL_DLL void PDALRegister_kernel_##T(void* factory); \
//    PDAL_C_END

//
// macro to register the version of PDAL the plugin was linked against
//
#define SET_READER_PLUGIN_VERSION(T) \
    PDAL_C_START PDAL_DLL int PDALRegister_version_reader_##T() \
        { return PDAL_PLUGIN_VERSION; } \
    PDAL_C_END
#define SET_FILTER_PLUGIN_VERSION(T) \
    PDAL_C_START PDAL_DLL int PDALRegister_version_filter_##T() \
        { return PDAL_PLUGIN_VERSION; } \
    PDAL_C_END
#define SET_WRITER_PLUGIN_VERSION(T) \
    PDAL_C_START PDAL_DLL int PDALRegister_version_writer_##T() \
        { return PDAL_PLUGIN_VERSION; } \
    PDAL_C_END
#define SET_KERNEL_PLUGIN_VERSION(T) \
    PDAL_C_START PDAL_DLL int PDALRegister_version_kernel_##T() \
        { return PDAL_PLUGIN_VERSION; } \
    PDAL_C_END

#ifdef _WIN32
inline long lround(double d)
{
    long l;

    if (d < 0)
        l = (long)ceil(d - .5);
    else
        l = (long)floor(d + .5);
    return l;
}
#endif

<commit_msg>cleaning up<commit_after>/******************************************************************************
* Copyright (c) 2012, Howard Butler (hobu.inc@gmail.com)
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
*     * Redistributions of source code must retain the above copyright
*       notice, this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright
*       notice, this list of conditions and the following disclaimer in
*       the documentation and/or other materials provided
*       with the distribution.
*     * Neither the name of Hobu, Inc. or Flaxen Geo Consulting nor the
*       names of its contributors may be used to endorse or promote
*       products derived from this software without specific prior
*       written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
****************************************************************************/

#pragma once

#include <pdal/pdal_internal.hpp>
//
// macros for creating the various stage types
//
#define MAKE_READER_CREATOR(T, FullT) \
    pdal::Reader* create_##T() \
        { pdal::Reader *r = new FullT(); return r; }
#define MAKE_FILTER_CREATOR(T, FullT) \
    pdal::Filter* create_##T() \
        { pdal::Filter *f = new FullT(); return f; }
#define MAKE_WRITER_CREATOR(T, FullT) \
    pdal::Writer* create_##T() \
        { pdal::Writer *w = new FullT(); return w; }
#define MAKE_KERNEL_CREATOR(T, FullT) \
    pdal::Kernel* create_##T() \
        { pdal::Kernel *k = new FullT(); return k; }

//
// macros to register the stage creators
//
#define REGISTER_WRITER(T, FullT) \
    registerDriverInfo<FullT>(); \
    registerWriter(FullT::s_getName(), create_##T)
#define REGISTER_READER(T, FullT) \
    registerDriverInfo<FullT>(); \
    registerReader(FullT::s_getName(), create_##T)
#define REGISTER_FILTER(T, FullT) \
    registerDriverInfo<FullT>(); \
    registerFilter(FullT::s_getName(), create_##T)
#define REGISTER_KERNEL(T, FullT) \
    registerKernelDriverInfo<FullT>(); \
    registerKernel(FullT::s_getName(), create_##T)

//
// macros to create the various plugins types
//
#define CREATE_READER_PLUGIN(T, FullT) \
    MAKE_READER_CREATOR(T, FullT) \
    PDAL_C_START PDAL_DLL void PDALRegister_reader_##T(void* factory) \
    { \
        pdal::StageFactory& f = *(pdal::StageFactory*) factory; \
        f.registerDriverInfo< FullT>(); \
        f.registerReader(FullT::s_getName(), create_##T); \
    } \
    PDAL_C_END \
    SET_READER_PLUGIN_VERSION(T)
#define CREATE_FILTER_PLUGIN(T, FullT) \
    MAKE_FILTER_CREATOR(T, FullT) \
    PDAL_C_START PDAL_DLL void PDALRegister_filter_##T(void* factory) \
    { \
        pdal::StageFactory& f = *(pdal::StageFactory*) factory; \
        f.registerDriverInfo< FullT>(); \
        f.registerFilter(FullT::s_getName(), create_##T); \
    } \
    PDAL_C_END \
    SET_FILTER_PLUGIN_VERSION(T)
#define CREATE_WRITER_PLUGIN(T, FullT) \
    MAKE_WRITER_CREATOR(T, FullT) \
    PDAL_C_START PDAL_DLL void PDALRegister_writer_##T(void* factory) \
    { \
        pdal::StageFactory& f = *(pdal::StageFactory*) factory; \
        f.registerDriverInfo< FullT>(); \
        f.registerWriter(FullT::s_getName(), create_##T); \
    } \
    PDAL_C_END \
    SET_WRITER_PLUGIN_VERSION(T)
#define CREATE_KERNEL_PLUGIN(T, FullT) \
    MAKE_KERNEL_CREATOR(T, FullT) \
    PDAL_C_START PDAL_DLL void PDALRegister_kernel_##T(void* factory) \
    { \
        pdal::KernelFactory& f = *(pdal::KernelFactory*) factory; \
        f.registerKernelDriverInfo< FullT>(); \
        f.registerKernel(FullT::s_getName(), create_##T); \
    } \
    PDAL_C_END \
    SET_KERNEL_PLUGIN_VERSION(T)

//
// macro to register the version of PDAL the plugin was linked against
//
#define SET_READER_PLUGIN_VERSION(T) \
    PDAL_C_START PDAL_DLL int PDALRegister_version_reader_##T() \
        { return PDAL_PLUGIN_VERSION; } \
    PDAL_C_END
#define SET_FILTER_PLUGIN_VERSION(T) \
    PDAL_C_START PDAL_DLL int PDALRegister_version_filter_##T() \
        { return PDAL_PLUGIN_VERSION; } \
    PDAL_C_END
#define SET_WRITER_PLUGIN_VERSION(T) \
    PDAL_C_START PDAL_DLL int PDALRegister_version_writer_##T() \
        { return PDAL_PLUGIN_VERSION; } \
    PDAL_C_END
#define SET_KERNEL_PLUGIN_VERSION(T) \
    PDAL_C_START PDAL_DLL int PDALRegister_version_kernel_##T() \
        { return PDAL_PLUGIN_VERSION; } \
    PDAL_C_END

#ifdef _WIN32
inline long lround(double d)
{
    long l;

    if (d < 0)
        l = (long)ceil(d - .5);
    else
        l = (long)floor(d + .5);
    return l;
}
#endif

<|endoftext|>