<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: localfilehelper.cxx,v $
 *
 *  $Revision: 1.15 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 09:50:32 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _COM_SUN_STAR_SDBC_XRESULTSET_HPP_
#include <com/sun/star/sdbc/XResultSet.hpp>
#endif
#ifndef _COM_SUN_STAR_UCB_XCONTENTACCESS_HPP_
#include <com/sun/star/ucb/XContentAccess.hpp>
#endif

#ifndef _COM_SUN_STAR_UCB_COMMANDABORTEDEXCEPTION_HPP_
#include <com/sun/star/ucb/CommandAbortedException.hpp>
#endif

#include <unotools/localfilehelper.hxx>
#include <ucbhelper/fileidentifierconverter.hxx>
#include <ucbhelper/contentbroker.hxx>
#include <rtl/ustring.hxx>
#include <osl/file.hxx>
#include <tools/debug.hxx>
#include <tools/list.hxx>
#include <tools/urlobj.hxx>
#include <ucbhelper/content.hxx>

using namespace ::osl;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::ucb;

namespace utl
{

sal_Bool LocalFileHelper::ConvertSystemPathToURL( const String& rName, const String& rBaseURL, String& rReturn )
{
    rReturn = ::rtl::OUString();

    ::ucb::ContentBroker* pBroker = ::ucb::ContentBroker::get();
    if ( !pBroker )
    {
        rtl::OUString aRet;
        if ( FileBase::getFileURLFromSystemPath( rName, aRet ) == FileBase::E_None )
            rReturn = aRet;
    }
    else
    {
        ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XContentProviderManager > xManager =
                pBroker->getContentProviderManagerInterface();
        try
        {
            rReturn = ::ucb::getFileURLFromSystemPath( xManager, rBaseURL, rName );
        }
        catch ( ::com::sun::star::uno::RuntimeException& )
        {
            return sal_False;
        }
    }

    return ( rReturn.Len() != 0 );
}

sal_Bool LocalFileHelper::ConvertURLToSystemPath( const String& rName, String& rReturn )
{
    rReturn = ::rtl::OUString();
    ::ucb::ContentBroker* pBroker = ::ucb::ContentBroker::get();
    if ( !pBroker )
    {
        rtl::OUString aRet;
        if( FileBase::getSystemPathFromFileURL( rName, aRet ) == FileBase::E_None )
            rReturn = aRet;
    }
    else
    {
        ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XContentProviderManager > xManager =
                pBroker->getContentProviderManagerInterface();
        try
        {
            rReturn = ::ucb::getSystemPathFromFileURL( xManager, rName );
        }
        catch ( ::com::sun::star::uno::RuntimeException& )
        {
        }
    }

    return ( rReturn.Len() != 0 );
}

sal_Bool LocalFileHelper::ConvertPhysicalNameToURL( const String& rName, String& rReturn )
{
    rReturn = ::rtl::OUString();
    ::ucb::ContentBroker* pBroker = ::ucb::ContentBroker::get();
    if ( !pBroker )
    {
        rtl::OUString aRet;
        if ( FileBase::getFileURLFromSystemPath( rName, aRet ) == FileBase::E_None )
            rReturn = aRet;
    }
    else
    {
        ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XContentProviderManager > xManager =
                pBroker->getContentProviderManagerInterface();

        try
        {
            rtl::OUString aBase( ::ucb::getLocalFileURL( xManager ) );
            rReturn = ::ucb::getFileURLFromSystemPath( xManager, aBase, rName );
        }
        catch ( ::com::sun::star::uno::RuntimeException& )
        {
        }
    }

    return ( rReturn.Len() != 0 );
}

sal_Bool LocalFileHelper::ConvertURLToPhysicalName( const String& rName, String& rReturn )
{
    rReturn = ::rtl::OUString();
    ::ucb::ContentBroker* pBroker = ::ucb::ContentBroker::get();
    if ( !pBroker )
    {
        ::rtl::OUString aRet;
        if ( FileBase::getSystemPathFromFileURL( rName, aRet ) == FileBase::E_None )
            rReturn = aRet;
    }
    else
    {
        ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XContentProviderManager > xManager =
                pBroker->getContentProviderManagerInterface();
        try
        {
            INetURLObject aObj( rName );
            INetURLObject aLocal( ::ucb::getLocalFileURL( xManager ) );
            if ( aObj.GetProtocol() == aLocal.GetProtocol() )
                rReturn = ::ucb::getSystemPathFromFileURL( xManager, rName );
        }
        catch ( ::com::sun::star::uno::RuntimeException& )
        {
        }
    }

    return ( rReturn.Len() != 0 );
}

sal_Bool LocalFileHelper::IsLocalFile( const String& rName )
{
    String aTmp;
    return ConvertURLToPhysicalName( rName, aTmp );
}

sal_Bool LocalFileHelper::IsFileContent( const String& rName )
{
    String aTmp;
    return ConvertURLToSystemPath( rName, aTmp );
}

DECLARE_LIST( StringList_Impl, ::rtl::OUString* )

::com::sun::star::uno::Sequence < ::rtl::OUString > LocalFileHelper::GetFolderContents( const ::rtl::OUString& rFolder, sal_Bool bFolder )
{
    StringList_Impl* pFiles = NULL;
    try
    {
        ::ucb::Content aCnt( rFolder, Reference< XCommandEnvironment > () );
        Reference< ::com::sun::star::sdbc::XResultSet > xResultSet;
        ::com::sun::star::uno::Sequence< ::rtl::OUString > aProps(1);
        ::rtl::OUString* pProps = aProps.getArray();
        pProps[0] == ::rtl::OUString::createFromAscii( "Url" );

        try
        {
            ::ucb::ResultSetInclude eInclude = bFolder ? ::ucb::INCLUDE_FOLDERS_AND_DOCUMENTS : ::ucb::INCLUDE_DOCUMENTS_ONLY;
            xResultSet = aCnt.createCursor( aProps, eInclude );
        }
        catch( ::com::sun::star::ucb::CommandAbortedException& )
        {
        }
        catch( Exception& )
        {
        }

        if ( xResultSet.is() )
        {
            pFiles = new StringList_Impl;
            Reference< XContentAccess > xContentAccess( xResultSet, UNO_QUERY );
            try
            {
                while ( xResultSet->next() )
                {
                    ::rtl::OUString aId = xContentAccess->queryContentIdentifierString();
                    ::rtl::OUString* pFile = new ::rtl::OUString( aId );
                    pFiles->Insert( pFile, LIST_APPEND );
                }
            }
            catch( ::com::sun::star::ucb::CommandAbortedException& )
            {
            }
            catch( Exception& )
            {
            }
        }
    }
    catch( Exception& )
    {
    }

    if ( pFiles )
    {
        ULONG nCount = pFiles->Count();
        Sequence < ::rtl::OUString > aRet( nCount );
        ::rtl::OUString* pRet = aRet.getArray();
        for ( USHORT i = 0; i < nCount; ++i )
        {
            ::rtl::OUString* pFile = pFiles->GetObject(i);
            pRet[i] = *( pFile );
            delete pFile;
        }
        delete pFiles;
        return aRet;
    }
    else
        return Sequence < ::rtl::OUString > ();
}

};
<commit_msg>INTEGRATION: CWS warnings01 (1.15.16); FILE MERGED 2005/10/27 10:51:18 pl 1.15.16.1: #i55991# removed warnings for solaris platform<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: localfilehelper.cxx,v $
 *
 *  $Revision: 1.16 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-19 14:09:39 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _COM_SUN_STAR_SDBC_XRESULTSET_HPP_
#include <com/sun/star/sdbc/XResultSet.hpp>
#endif
#ifndef _COM_SUN_STAR_UCB_XCONTENTACCESS_HPP_
#include <com/sun/star/ucb/XContentAccess.hpp>
#endif

#ifndef _COM_SUN_STAR_UCB_COMMANDABORTEDEXCEPTION_HPP_
#include <com/sun/star/ucb/CommandAbortedException.hpp>
#endif

#include <unotools/localfilehelper.hxx>
#include <ucbhelper/fileidentifierconverter.hxx>
#include <ucbhelper/contentbroker.hxx>
#include <rtl/ustring.hxx>
#include <osl/file.hxx>
#include <tools/debug.hxx>
#include <tools/list.hxx>
#include <tools/urlobj.hxx>
#include <ucbhelper/content.hxx>

using namespace ::osl;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::ucb;

namespace utl
{

sal_Bool LocalFileHelper::ConvertSystemPathToURL( const String& rName, const String& rBaseURL, String& rReturn )
{
    rReturn = ::rtl::OUString();

    ::ucb::ContentBroker* pBroker = ::ucb::ContentBroker::get();
    if ( !pBroker )
    {
        rtl::OUString aRet;
        if ( FileBase::getFileURLFromSystemPath( rName, aRet ) == FileBase::E_None )
            rReturn = aRet;
    }
    else
    {
        ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XContentProviderManager > xManager =
                pBroker->getContentProviderManagerInterface();
        try
        {
            rReturn = ::ucb::getFileURLFromSystemPath( xManager, rBaseURL, rName );
        }
        catch ( ::com::sun::star::uno::RuntimeException& )
        {
            return sal_False;
        }
    }

    return ( rReturn.Len() != 0 );
}

sal_Bool LocalFileHelper::ConvertURLToSystemPath( const String& rName, String& rReturn )
{
    rReturn = ::rtl::OUString();
    ::ucb::ContentBroker* pBroker = ::ucb::ContentBroker::get();
    if ( !pBroker )
    {
        rtl::OUString aRet;
        if( FileBase::getSystemPathFromFileURL( rName, aRet ) == FileBase::E_None )
            rReturn = aRet;
    }
    else
    {
        ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XContentProviderManager > xManager =
                pBroker->getContentProviderManagerInterface();
        try
        {
            rReturn = ::ucb::getSystemPathFromFileURL( xManager, rName );
        }
        catch ( ::com::sun::star::uno::RuntimeException& )
        {
        }
    }

    return ( rReturn.Len() != 0 );
}

sal_Bool LocalFileHelper::ConvertPhysicalNameToURL( const String& rName, String& rReturn )
{
    rReturn = ::rtl::OUString();
    ::ucb::ContentBroker* pBroker = ::ucb::ContentBroker::get();
    if ( !pBroker )
    {
        rtl::OUString aRet;
        if ( FileBase::getFileURLFromSystemPath( rName, aRet ) == FileBase::E_None )
            rReturn = aRet;
    }
    else
    {
        ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XContentProviderManager > xManager =
                pBroker->getContentProviderManagerInterface();

        try
        {
            rtl::OUString aBase( ::ucb::getLocalFileURL( xManager ) );
            rReturn = ::ucb::getFileURLFromSystemPath( xManager, aBase, rName );
        }
        catch ( ::com::sun::star::uno::RuntimeException& )
        {
        }
    }

    return ( rReturn.Len() != 0 );
}

sal_Bool LocalFileHelper::ConvertURLToPhysicalName( const String& rName, String& rReturn )
{
    rReturn = ::rtl::OUString();
    ::ucb::ContentBroker* pBroker = ::ucb::ContentBroker::get();
    if ( !pBroker )
    {
        ::rtl::OUString aRet;
        if ( FileBase::getSystemPathFromFileURL( rName, aRet ) == FileBase::E_None )
            rReturn = aRet;
    }
    else
    {
        ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XContentProviderManager > xManager =
                pBroker->getContentProviderManagerInterface();
        try
        {
            INetURLObject aObj( rName );
            INetURLObject aLocal( ::ucb::getLocalFileURL( xManager ) );
            if ( aObj.GetProtocol() == aLocal.GetProtocol() )
                rReturn = ::ucb::getSystemPathFromFileURL( xManager, rName );
        }
        catch ( ::com::sun::star::uno::RuntimeException& )
        {
        }
    }

    return ( rReturn.Len() != 0 );
}

sal_Bool LocalFileHelper::IsLocalFile( const String& rName )
{
    String aTmp;
    return ConvertURLToPhysicalName( rName, aTmp );
}

sal_Bool LocalFileHelper::IsFileContent( const String& rName )
{
    String aTmp;
    return ConvertURLToSystemPath( rName, aTmp );
}

DECLARE_LIST( StringList_Impl, ::rtl::OUString* )

::com::sun::star::uno::Sequence < ::rtl::OUString > LocalFileHelper::GetFolderContents( const ::rtl::OUString& rFolder, sal_Bool bFolder )
{
    StringList_Impl* pFiles = NULL;
    try
    {
        ::ucb::Content aCnt( rFolder, Reference< XCommandEnvironment > () );
        Reference< ::com::sun::star::sdbc::XResultSet > xResultSet;
        ::com::sun::star::uno::Sequence< ::rtl::OUString > aProps(1);
        ::rtl::OUString* pProps = aProps.getArray();
        pProps[0] = ::rtl::OUString::createFromAscii( "Url" );

        try
        {
            ::ucb::ResultSetInclude eInclude = bFolder ? ::ucb::INCLUDE_FOLDERS_AND_DOCUMENTS : ::ucb::INCLUDE_DOCUMENTS_ONLY;
            xResultSet = aCnt.createCursor( aProps, eInclude );
        }
        catch( ::com::sun::star::ucb::CommandAbortedException& )
        {
        }
        catch( Exception& )
        {
        }

        if ( xResultSet.is() )
        {
            pFiles = new StringList_Impl;
            Reference< XContentAccess > xContentAccess( xResultSet, UNO_QUERY );
            try
            {
                while ( xResultSet->next() )
                {
                    ::rtl::OUString aId = xContentAccess->queryContentIdentifierString();
                    ::rtl::OUString* pFile = new ::rtl::OUString( aId );
                    pFiles->Insert( pFile, LIST_APPEND );
                }
            }
            catch( ::com::sun::star::ucb::CommandAbortedException& )
            {
            }
            catch( Exception& )
            {
            }
        }
    }
    catch( Exception& )
    {
    }

    if ( pFiles )
    {
        ULONG nCount = pFiles->Count();
        Sequence < ::rtl::OUString > aRet( nCount );
        ::rtl::OUString* pRet = aRet.getArray();
        for ( USHORT i = 0; i < nCount; ++i )
        {
            ::rtl::OUString* pFile = pFiles->GetObject(i);
            pRet[i] = *( pFile );
            delete pFile;
        }
        delete pFiles;
        return aRet;
    }
    else
        return Sequence < ::rtl::OUString > ();
}

}
<|endoftext|>


<commit_before>// This file is part of SWGANH which is released under the MIT license.
// See file LICENSE or go to http://swganh.com/LICENSE

#include "connection_service.h"

#include <boost/bind.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/lexical_cast.hpp>
#include "swganh/logger.h"

#include "swganh/crc.h"
#include "swganh/event_dispatcher.h"
#include "swganh/network/resolver.h"
#include "swganh/network/server.h"
#include "swganh/plugin/plugin_manager.h"
#include "swganh/service/service_directory_interface.h"
#include "swganh/service/service_manager.h"

#include "swganh/app/swganh_kernel.h"

#include "swganh_core/character/character_service_interface.h"
#include "swganh_core/character/character_provider_interface.h"
#include "ping_server.h"
#include "connection_client.h"
#include "swganh_core/connection/providers/session_provider_interface.h"

#include "swganh_core/object/object.h"
#include "swganh_core/object/player/player.h"

using namespace swganh::app;
using namespace swganh::event_dispatcher;
using namespace swganh::network;
using namespace swganh::service;
using namespace swganh::character;
using namespace swganh::connection;
using namespace swganh::connection;
using namespace swganh::login;
using namespace swganh::messages;
using namespace swganh::object;
using namespace swganh::simulation;

using namespace std;

using swganh::ValueEvent;

using boost::asio::ip::udp;
using swganh::app::SwganhKernel;

ConnectionService::ConnectionService(
        string listen_address,
        uint16_t listen_port,
        uint16_t ping_port,
        SwganhKernel* kernel)
    : ConnectionServiceInterface(kernel)
    , kernel_(kernel)
    , ping_server_(nullptr)
	, active_(kernel->GetIoThreadPool())
    , listen_address_(listen_address)
    , listen_port_(listen_port)
    , ping_port_(ping_port)
{
    SetServiceDescription(ServiceDescription(
        "Connection Service",
        "connection",
        "0.1",
        swganh::network::resolve_to_string(listen_address_),
        0,
        listen_port_,
        ping_port_));
}

ConnectionService::~ConnectionService()
{
    session_timer_->cancel();
}

void ConnectionService::Initialize()
{
    session_provider_ = kernel_->GetPluginManager()->CreateObject<swganh::connection::providers::SessionProviderInterface>("Login::SessionProvider");
    character_provider_ = kernel_->GetPluginManager()->CreateObject<CharacterProviderInterface>("Character::CharacterProvider");

    character_service_ = kernel_->GetServiceManager()->GetService<CharacterServiceInterface>("CharacterService");
    login_service_ = kernel_->GetServiceManager()->GetService<LoginServiceInterface>("LoginService");
    simulation_service_ = kernel_->GetServiceManager()->GetService<SimulationServiceInterface>("SimulationService");
}

void ConnectionService::Startup() {
	ping_server_ = make_shared<PingServer>(kernel_->GetIoThreadPool(), ping_port_);

    character_service_ = kernel_->GetServiceManager()->GetService<CharacterServiceInterface>("CharacterService");
    login_service_ = kernel_->GetServiceManager()->GetService<LoginServiceInterface>("LoginService");
    simulation_service_ = kernel_->GetServiceManager()->GetService<SimulationServiceInterface>("SimulationService");

    RegisterMessageHandler(&ConnectionService::HandleClientIdMsg_, this);
    RegisterMessageHandler(&ConnectionService::HandleCmdSceneReady_, this);

    StartListening(listen_port_);
}

void ConnectionService::Shutdown() {
    StopListening();
}

const string& ConnectionService::listen_address() {
    return listen_address_;
}

uint16_t ConnectionService::listen_port() {
    return listen_port_;
}

shared_ptr<Session> ConnectionService::CreateSession(const udp::endpoint& endpoint)
{
    shared_ptr<ConnectionClient> session = nullptr;

    {
        boost::lock_guard<boost::mutex> lg(session_map_mutex_);
        if (session_map_.find(endpoint) == session_map_.end())
        {
            session = make_shared<ConnectionClient>(this, kernel_->GetCpuThreadPool(), endpoint);
            session_map_.insert(make_pair(endpoint, session));
			LOG(info) << "Created Connection Service Session for " << endpoint.address().to_string();
        }
    }

    return session;
}

bool ConnectionService::RemoveSession(std::shared_ptr<Session> session) {
    {
        boost::lock_guard<boost::mutex> lg(session_map_mutex_);
        session_map_.erase(session->remote_endpoint());
	}

    auto connection_client = static_pointer_cast<ConnectionClient>(session);

    if (auto controller = connection_client->GetController())
    {
        kernel_->GetEventDispatcher()->Dispatch(std::make_shared<ValueEvent<uint64_t>>("Connection::ControllerConnectionClosed", controller->GetId()));
	}

    LOG(info) << "Removing disconnected client";
	session_provider_->EndGameSession(connection_client->GetPlayerId());

    return true;
}

shared_ptr<Session> ConnectionService::GetSession(const udp::endpoint& endpoint) {
    {
        boost::lock_guard<boost::mutex> lg(session_map_mutex_);

        auto find_iter = session_map_.find(endpoint);
        if (find_iter != session_map_.end())
        {
			return find_iter->second;
        }
    }

    return CreateSession(endpoint);
}

std::shared_ptr<ConnectionClientInterface> ConnectionService::FindConnectionByPlayerId(uint64_t player_id)
{
    shared_ptr<ConnectionClientInterface> connection = nullptr;

    {
        boost::lock_guard<boost::mutex> lg(session_map_mutex_);

        auto find_iter = find_if(
            begin(session_map_),
            end(session_map_),
            [player_id] (SessionMap::value_type& item)
        {
            return item.second->GetPlayerId() == player_id;
        });

        if (find_iter != end(session_map_))
        {
            connection = find_iter->second;
        }
    }

    return connection;
}

void ConnectionService::HandleCmdSceneReady_(
    const shared_ptr<ConnectionClientInterface>& client,
    CmdSceneReady* message)
{
    DLOG(info) << "Handling CmdSceneReady";

    client->SendTo(CmdSceneReady());

	auto object = simulation_service_->GetObjectById(client->GetController()->GetId());

    kernel_->GetEventDispatcher()->Dispatch(
        make_shared<ValueEvent<shared_ptr<Object>>>("ObjectReadyEvent", object));
}

void ConnectionService::HandleClientIdMsg_(
    const shared_ptr<ConnectionClientInterface>& client,
    ClientIdMsg* message)
{
    DLOG(info) << "Handling ClientIdMsg";

    // get session key from login service
    uint32_t account_id = login_service_->GetAccountBySessionKey(message->session_hash);

    // authorized
    if (! account_id) {
        LOG(warning) << "Account_id not found from session key, unauthorized access.";
        return;
    }

    // gets player from account
    uint64_t player_id = session_provider_->GetPlayerId(account_id);

    // authorized
    if (! player_id) {
        LOG(warning) << "No player found for the requested account, unauthorized access.";
        return;
    }

    auto existing_session_connection = FindConnectionByPlayerId(player_id);
    if (existing_session_connection)
    {
        existing_session_connection->Close();
    }

    // creates a new session and stores it for later use
    if (!session_provider_->CreateGameSession(player_id, client->connection_id())) {
        DLOG(warning) << "Player Not Inserted into Session Map because No Game Session Created!";
    }

    client->Connect(account_id, player_id);

    ClientPermissionsMessage client_permissions;
    client_permissions.galaxy_available = kernel_->GetServiceDirectory()->galaxy().status();
    client_permissions.available_character_slots = static_cast<uint8_t>(character_provider_->GetMaxCharacters(account_id));
    /// @TODO: Replace with configurable value
    client_permissions.unlimited_characters = 0;

    client->SendTo(client_permissions);
}
<commit_msg>Explicitly stop controlling the object before dispatching the ControllerConnectionClosed event<commit_after>// This file is part of SWGANH which is released under the MIT license.
// See file LICENSE or go to http://swganh.com/LICENSE

#include "connection_service.h"

#include <boost/bind.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/lexical_cast.hpp>
#include "swganh/logger.h"

#include "swganh/crc.h"
#include "swganh/event_dispatcher.h"
#include "swganh/network/resolver.h"
#include "swganh/network/server.h"
#include "swganh/plugin/plugin_manager.h"
#include "swganh/service/service_directory_interface.h"
#include "swganh/service/service_manager.h"

#include "swganh/app/swganh_kernel.h"

#include "swganh_core/character/character_service_interface.h"
#include "swganh_core/character/character_provider_interface.h"
#include "ping_server.h"
#include "connection_client.h"
#include "swganh_core/connection/providers/session_provider_interface.h"

#include "swganh_core/object/object.h"
#include "swganh_core/object/player/player.h"

using namespace swganh::app;
using namespace swganh::event_dispatcher;
using namespace swganh::network;
using namespace swganh::service;
using namespace swganh::character;
using namespace swganh::connection;
using namespace swganh::connection;
using namespace swganh::login;
using namespace swganh::messages;
using namespace swganh::object;
using namespace swganh::simulation;

using namespace std;

using swganh::ValueEvent;

using boost::asio::ip::udp;
using swganh::app::SwganhKernel;

ConnectionService::ConnectionService(
        string listen_address,
        uint16_t listen_port,
        uint16_t ping_port,
        SwganhKernel* kernel)
    : ConnectionServiceInterface(kernel)
    , kernel_(kernel)
    , ping_server_(nullptr)
	, active_(kernel->GetIoThreadPool())
    , listen_address_(listen_address)
    , listen_port_(listen_port)
    , ping_port_(ping_port)
{
    SetServiceDescription(ServiceDescription(
        "Connection Service",
        "connection",
        "0.1",
        swganh::network::resolve_to_string(listen_address_),
        0,
        listen_port_,
        ping_port_));
}

ConnectionService::~ConnectionService()
{
    session_timer_->cancel();
}

void ConnectionService::Initialize()
{
    session_provider_ = kernel_->GetPluginManager()->CreateObject<swganh::connection::providers::SessionProviderInterface>("Login::SessionProvider");
    character_provider_ = kernel_->GetPluginManager()->CreateObject<CharacterProviderInterface>("Character::CharacterProvider");

    character_service_ = kernel_->GetServiceManager()->GetService<CharacterServiceInterface>("CharacterService");
    login_service_ = kernel_->GetServiceManager()->GetService<LoginServiceInterface>("LoginService");
    simulation_service_ = kernel_->GetServiceManager()->GetService<SimulationServiceInterface>("SimulationService");
}

void ConnectionService::Startup() {
	ping_server_ = make_shared<PingServer>(kernel_->GetIoThreadPool(), ping_port_);

    character_service_ = kernel_->GetServiceManager()->GetService<CharacterServiceInterface>("CharacterService");
    login_service_ = kernel_->GetServiceManager()->GetService<LoginServiceInterface>("LoginService");
    simulation_service_ = kernel_->GetServiceManager()->GetService<SimulationServiceInterface>("SimulationService");

    RegisterMessageHandler(&ConnectionService::HandleClientIdMsg_, this);
    RegisterMessageHandler(&ConnectionService::HandleCmdSceneReady_, this);

    StartListening(listen_port_);
}

void ConnectionService::Shutdown() {
    StopListening();
}

const string& ConnectionService::listen_address() {
    return listen_address_;
}

uint16_t ConnectionService::listen_port() {
    return listen_port_;
}

shared_ptr<Session> ConnectionService::CreateSession(const udp::endpoint& endpoint)
{
    shared_ptr<ConnectionClient> session = nullptr;

    {
        boost::lock_guard<boost::mutex> lg(session_map_mutex_);
        if (session_map_.find(endpoint) == session_map_.end())
        {
            session = make_shared<ConnectionClient>(this, kernel_->GetCpuThreadPool(), endpoint);
            session_map_.insert(make_pair(endpoint, session));
			LOG(info) << "Created Connection Service Session for " << endpoint.address().to_string();
        }
    }

    return session;
}

bool ConnectionService::RemoveSession(std::shared_ptr<Session> session) {
    {
        boost::lock_guard<boost::mutex> lg(session_map_mutex_);
        session_map_.erase(session->remote_endpoint());
	}

    auto connection_client = static_pointer_cast<ConnectionClient>(session);

    if (auto controller = connection_client->GetController()) {
        simulation_service_->StopControllingObject(controller->GetId());

        kernel_->GetEventDispatcher()->Dispatch(std::make_shared<ValueEvent<uint64_t>>("Connection::ControllerConnectionClosed", controller->GetId()));
	}

    LOG(info) << "Removing disconnected client";
	session_provider_->EndGameSession(connection_client->GetPlayerId());

    return true;
}

shared_ptr<Session> ConnectionService::GetSession(const udp::endpoint& endpoint) {
    {
        boost::lock_guard<boost::mutex> lg(session_map_mutex_);

        auto find_iter = session_map_.find(endpoint);
        if (find_iter != session_map_.end())
        {
			return find_iter->second;
        }
    }

    return CreateSession(endpoint);
}

std::shared_ptr<ConnectionClientInterface> ConnectionService::FindConnectionByPlayerId(uint64_t player_id)
{
    shared_ptr<ConnectionClientInterface> connection = nullptr;

    {
        boost::lock_guard<boost::mutex> lg(session_map_mutex_);

        auto find_iter = find_if(
            begin(session_map_),
            end(session_map_),
            [player_id] (SessionMap::value_type& item)
        {
            return item.second->GetPlayerId() == player_id;
        });

        if (find_iter != end(session_map_))
        {
            connection = find_iter->second;
        }
    }

    return connection;
}

void ConnectionService::HandleCmdSceneReady_(
    const shared_ptr<ConnectionClientInterface>& client,
    CmdSceneReady* message)
{
    DLOG(info) << "Handling CmdSceneReady";

    client->SendTo(CmdSceneReady());

	auto object = simulation_service_->GetObjectById(client->GetController()->GetId());

    kernel_->GetEventDispatcher()->Dispatch(
        make_shared<ValueEvent<shared_ptr<Object>>>("ObjectReadyEvent", object));
}

void ConnectionService::HandleClientIdMsg_(
    const shared_ptr<ConnectionClientInterface>& client,
    ClientIdMsg* message)
{
    DLOG(info) << "Handling ClientIdMsg";

    // get session key from login service
    uint32_t account_id = login_service_->GetAccountBySessionKey(message->session_hash);

    // authorized
    if (! account_id) {
        LOG(warning) << "Account_id not found from session key, unauthorized access.";
        return;
    }

    // gets player from account
    uint64_t player_id = session_provider_->GetPlayerId(account_id);

    // authorized
    if (! player_id) {
        LOG(warning) << "No player found for the requested account, unauthorized access.";
        return;
    }

    auto existing_session_connection = FindConnectionByPlayerId(player_id);
    if (existing_session_connection)
    {
        existing_session_connection->Close();
    }

    // creates a new session and stores it for later use
    if (!session_provider_->CreateGameSession(player_id, client->connection_id())) {
        DLOG(warning) << "Player Not Inserted into Session Map because No Game Session Created!";
    }

    client->Connect(account_id, player_id);

    ClientPermissionsMessage client_permissions;
    client_permissions.galaxy_available = kernel_->GetServiceDirectory()->galaxy().status();
    client_permissions.available_character_slots = static_cast<uint8_t>(character_provider_->GetMaxCharacters(account_id));
    /// @TODO: Replace with configurable value
    client_permissions.unlimited_characters = 0;

    client->SendTo(client_permissions);
}
<|endoftext|>


<commit_before>/*
 * Software License Agreement (BSD License)
 *
 *  Point Cloud Library (PCL) - www.pointclouds.org
 *  Copyright (c) 2012-, Open Perception, Inc.
 *
 *  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 copyright holder(s) 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 PCL_FILTERS_IMPL_FRUSTUM_CULLING_HPP_
#define PCL_FILTERS_IMPL_FRUSTUM_CULLING_HPP_

#include <pcl/filters/frustum_culling.h>
#include <vector>

///////////////////////////////////////////////////////////////////////////////
template <typename PointT> void
pcl::FrustumCulling<PointT>::applyFilter (PointCloud& output)
{
  Eigen::Vector4f pl_n; // near plane
  Eigen::Vector4f pl_f; // far plane
  Eigen::Vector4f pl_t; // top plane
  Eigen::Vector4f pl_b; // bottom plane
  Eigen::Vector4f pl_r; // right plane
  Eigen::Vector4f pl_l; // left plane

  Eigen::Vector3f view = camera_pose_.block (0, 0, 3, 1);    // view vector for the camera  - first column of the rotation matrix
  Eigen::Vector3f up = camera_pose_.block (0, 1, 3, 1);      // up vector for the camera    - second column of the rotation matix
  Eigen::Vector3f right = camera_pose_.block (0, 2, 3, 1);   // right vector for the camera - third column of the rotation matrix
  Eigen::Vector3f T = camera_pose_.block (0, 3, 3, 1);       // The (X, Y, Z) position of the camera w.r.t origin

  vfov_ = float (vfov_ * M_PI / 180); // degrees to radians
  hfov_ = float (hfov_ * M_PI / 180); // degrees to radians

  float np_h = float (2 * tan (vfov_ / 2) * np_dist_);  // near plane height
  float np_w = float (2 * tan (hfov_ / 2) * np_dist_);  // near plane width

  float fp_h = float (2 * tan (vfov_ / 2) * fp_dist_);    // far plane height
  float fp_w = float (2 * tan (hfov_ / 2) * fp_dist_);    // far plane width

  Eigen::Vector3f fp_c (T + view * fp_dist_);                 // far plane center
  Eigen::Vector3f fp_tl (fp_c + (up * fp_h / 2) - (right * fp_w / 2));  // Top left corner of the far plane
  Eigen::Vector3f fp_tr (fp_c + (up * fp_h / 2) + (right * fp_w / 2));  // Top right corner of the far plane
  Eigen::Vector3f fp_bl (fp_c - (up * fp_h / 2) - (right * fp_w / 2));  // Bottom left corner of the far plane
  Eigen::Vector3f fp_br (fp_c - (up * fp_h / 2) + (right * fp_w / 2));  // Bottom right corner of the far plane

  Eigen::Vector3f np_c (T + view * np_dist_);                   // near plane center
  //Eigen::Vector3f np_tl = np_c + (up * np_h/2) - (right * np_w/2); // Top left corner of the near plane
  Eigen::Vector3f np_tr (np_c + (up * np_h / 2) + (right * np_w / 2));   // Top right corner of the near plane
  Eigen::Vector3f np_bl (np_c - (up * np_h / 2) - (right * np_w / 2));   // Bottom left corner of the near plane
  Eigen::Vector3f np_br (np_c - (up * np_h / 2) + (right * np_w / 2));   // Bottom right corner of the near plane

  pl_f.block (0, 0, 3, 1) = (fp_bl - fp_br).cross (fp_tr - fp_br);   // Far plane equation - cross product of the
  pl_f (3) = -fp_c.dot (pl_f.block (0, 0, 3, 1));                    // perpendicular edges of the far plane

  pl_n.block (0, 0, 3, 1) = (np_tr - np_br).cross (np_bl - np_br);   // Near plane equation - cross product of the
  pl_n (3) = -np_c.dot (pl_n.block (0, 0, 3, 1));                    // perpendicular edges of the far plane

  Eigen::Vector3f a (fp_bl - T);    // Vector connecting the camera and far plane bottom left
  Eigen::Vector3f b (fp_br - T);    // Vector connecting the camera and far plane bottom right
  Eigen::Vector3f c (fp_tr - T);    // Vector connecting the camera and far plane top right
  Eigen::Vector3f d (fp_tl - T);    // Vector connecting the camera and far plane top left

  //                   Frustum and the vectors a, b, c and d. T is the position of the camera
  //                             _________
  //                           /|       . |
  //                       d  / |   c .   |
  //                         /  | __._____|
  //                        /  /  .      .
  //                 a <---/-/  .    .
  //                      / / .   .  b
  //                     /   .
  //                     .
  //                   T
  //

  pl_r.block (0, 0, 3, 1) = b.cross (c);
  pl_l.block (0, 0, 3, 1) = d.cross (a);
  pl_t.block (0, 0, 3, 1) = c.cross (d);
  pl_b.block (0, 0, 3, 1) = a.cross (b);

  pl_r (3) = -T.dot (pl_r.block (0, 0, 3, 1));
  pl_l (3) = -T.dot (pl_l.block (0, 0, 3, 1));
  pl_t (3) = -T.dot (pl_t.block (0, 0, 3, 1));
  pl_b (3) = -T.dot (pl_b.block (0, 0, 3, 1));

  output.reserve (input_->points.size ());
  for (int i = 0; i < int (input_->points.size ()); i++)
  {
    Eigen::Vector4f pt (input_->points[i].x, input_->points[i].y, input_->points[i].z, 1.0f);

    if ( (pt.dot (pl_l) <= 0) &&
         (pt.dot (pl_r) <= 0) &&
         (pt.dot (pl_t) <= 0) &&
         (pt.dot (pl_b) <= 0) &&
         (pt.dot (pl_f) <= 0) &&
         (pt.dot (pl_n) <= 0) )
    {
      output.points.push_back (input_->points[i]);
    }
  }
  output.width = 1;
  output.height = uint32_t (output.points.size ());
}

///////////////////////////////////////////////////////////////////////////////
template <typename PointT> void
pcl::FrustumCulling<PointT>::applyFilter (std::vector<int> &indices)
{
  int indices_count = 0;
  int removed_indices_count = 0;

  Eigen::Vector4f pl_n; // near plane
  Eigen::Vector4f pl_f; // far plane
  Eigen::Vector4f pl_t; // top plane
  Eigen::Vector4f pl_b; // bottom plane
  Eigen::Vector4f pl_r; // right plane
  Eigen::Vector4f pl_l; // left plane

  Eigen::Vector3f view = camera_pose_.block (0, 0, 3, 1);    // view vector for the camera  - first column of the rotation matrix
  Eigen::Vector3f up = camera_pose_.block (0, 1, 3, 1);      // up vector for the camera    - second column of the rotation matix
  Eigen::Vector3f right = camera_pose_.block (0, 2, 3, 1);   // right vector for the camera - third column of the rotation matrix
  Eigen::Vector3f T = camera_pose_.block (0, 3, 3, 1);       // The (X, Y, Z) position of the camera w.r.t origin

  vfov_ = float (vfov_ * M_PI / 180); // degrees to radians
  hfov_ = float (hfov_ * M_PI / 180); // degrees to radians

  float np_h = float (2 * tan (vfov_ / 2) * np_dist_);  // near plane height
  float np_w = float (2 * tan (hfov_ / 2) * np_dist_);  // near plane width

  float fp_h = float (2 * tan (vfov_ / 2) * fp_dist_);    // far plane height
  float fp_w = float (2 * tan (hfov_ / 2) * fp_dist_);    // far plane width

  Eigen::Vector3f fp_c (T + view * fp_dist_);                 // far plane center
  Eigen::Vector3f fp_tl (fp_c + (up * fp_h / 2) - (right * fp_w / 2));  // Top left corner of the far plane
  Eigen::Vector3f fp_tr (fp_c + (up * fp_h / 2) + (right * fp_w / 2));  // Top right corner of the far plane
  Eigen::Vector3f fp_bl (fp_c - (up * fp_h / 2) - (right * fp_w / 2));  // Bottom left corner of the far plane
  Eigen::Vector3f fp_br (fp_c - (up * fp_h / 2) + (right * fp_w / 2));  // Bottom right corner of the far plane

  Eigen::Vector3f np_c (T + view * np_dist_);                   // near plane center
  //Eigen::Vector3f np_tl = np_c + (up * np_h/2) - (right * np_w/2); // Top left corner of the near plane
  Eigen::Vector3f np_tr (np_c + (up * np_h / 2) + (right * np_w / 2));   // Top right corner of the near plane
  Eigen::Vector3f np_bl (np_c - (up * np_h / 2) - (right * np_w / 2));   // Bottom left corner of the near plane
  Eigen::Vector3f np_br (np_c - (up * np_h / 2) + (right * np_w / 2));   // Bottom right corner of the near plane

  pl_f.block (0, 0, 3, 1) = (fp_bl - fp_br).cross (fp_tr - fp_br);   // Far plane equation - cross product of the
  pl_f (3) = -fp_c.dot (pl_f.block (0, 0, 3, 1));                    // perpendicular edges of the far plane

  pl_n.block (0, 0, 3, 1) = (np_tr - np_br).cross (np_bl - np_br);   // Near plane equation - cross product of the
  pl_n (3) = -np_c.dot (pl_n.block (0, 0, 3, 1));                    // perpendicular edges of the far plane

  Eigen::Vector3f a (fp_bl - T);    // Vector connecting the camera and far plane bottom left
  Eigen::Vector3f b (fp_br - T);    // Vector connecting the camera and far plane bottom right
  Eigen::Vector3f c (fp_tr - T);    // Vector connecting the camera and far plane top right
  Eigen::Vector3f d (fp_tl - T);    // Vector connecting the camera and far plane top left

  //                   Frustum and the vectors a, b, c and d. T is the position of the camera
  //                             _________
  //                           /|       . |
  //                       d  / |   c .   |
  //                         /  | __._____|
  //                        /  /  .      .
  //                 a <---/-/  .    .
  //                      / / .   .  b
  //                     /   .
  //                     .
  //                   T
  //

  pl_r.block (0, 0, 3, 1) = b.cross (c);
  pl_l.block (0, 0, 3, 1) = d.cross (a);
  pl_t.block (0, 0, 3, 1) = c.cross (d);
  pl_b.block (0, 0, 3, 1) = a.cross (b);

  pl_r (3) = -T.dot (pl_r.block (0, 0, 3, 1));
  pl_l (3) = -T.dot (pl_l.block (0, 0, 3, 1));
  pl_t (3) = -T.dot (pl_t.block (0, 0, 3, 1));
  pl_b (3) = -T.dot (pl_b.block (0, 0, 3, 1));

  removed_indices_->reserve (indices.size ());

  for (int i = 0; i < int (indices.size ()); i++)
  {
    Eigen::Vector4f pt (input_->points[indices[i]].x,
                        input_->points[indices[i]].y,
                        input_->points[indices[i]].z,
                        1.0f);

    if ( (pt.dot (pl_l) <= 0) &&
         (pt.dot (pl_r) <= 0) &&
         (pt.dot (pl_t) <= 0) &&
         (pt.dot (pl_b) <= 0) &&
         (pt.dot (pl_f) <= 0) &&
         (pt.dot (pl_n) <= 0) )
    {
      if (extract_removed_indices_)
      {
        (*removed_indices_)[removed_indices_count++] = static_cast<int> (i);
      }
      else
      {
        indices[indices_count++] = (*indices_)[i];
      }
    }
  }
  indices.resize (indices_count);
  removed_indices_->resize (removed_indices_count);
}

#define PCL_INSTANTIATE_FrustumCulling(T) template class PCL_EXPORTS pcl::FrustumCulling<T>;

#endif
<commit_msg>* fixed bug #855: pcl_filters frustum_culling.h/cpp fails ambiguous use of =<commit_after>/*
 * Software License Agreement (BSD License)
 *
 *  Point Cloud Library (PCL) - www.pointclouds.org
 *  Copyright (c) 2012-, Open Perception, Inc.
 *
 *  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 copyright holder(s) 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 PCL_FILTERS_IMPL_FRUSTUM_CULLING_HPP_
#define PCL_FILTERS_IMPL_FRUSTUM_CULLING_HPP_

#include <pcl/filters/frustum_culling.h>
#include <vector>

///////////////////////////////////////////////////////////////////////////////
template <typename PointT> void
pcl::FrustumCulling<PointT>::applyFilter (PointCloud& output)
{
  Eigen::Vector4f pl_n; // near plane
  Eigen::Vector4f pl_f; // far plane
  Eigen::Vector4f pl_t; // top plane
  Eigen::Vector4f pl_b; // bottom plane
  Eigen::Vector4f pl_r; // right plane
  Eigen::Vector4f pl_l; // left plane

  Eigen::Vector3f view = camera_pose_.block (0, 0, 3, 1);    // view vector for the camera  - first column of the rotation matrix
  Eigen::Vector3f up = camera_pose_.block (0, 1, 3, 1);      // up vector for the camera    - second column of the rotation matix
  Eigen::Vector3f right = camera_pose_.block (0, 2, 3, 1);   // right vector for the camera - third column of the rotation matrix
  Eigen::Vector3f T = camera_pose_.block (0, 3, 3, 1);       // The (X, Y, Z) position of the camera w.r.t origin

  vfov_ = float (vfov_ * M_PI / 180); // degrees to radians
  hfov_ = float (hfov_ * M_PI / 180); // degrees to radians

  float np_h = float (2 * tan (vfov_ / 2) * np_dist_);  // near plane height
  float np_w = float (2 * tan (hfov_ / 2) * np_dist_);  // near plane width

  float fp_h = float (2 * tan (vfov_ / 2) * fp_dist_);    // far plane height
  float fp_w = float (2 * tan (hfov_ / 2) * fp_dist_);    // far plane width

  Eigen::Vector3f fp_c (T + view * fp_dist_);                 // far plane center
  Eigen::Vector3f fp_tl (fp_c + (up * fp_h / 2) - (right * fp_w / 2));  // Top left corner of the far plane
  Eigen::Vector3f fp_tr (fp_c + (up * fp_h / 2) + (right * fp_w / 2));  // Top right corner of the far plane
  Eigen::Vector3f fp_bl (fp_c - (up * fp_h / 2) - (right * fp_w / 2));  // Bottom left corner of the far plane
  Eigen::Vector3f fp_br (fp_c - (up * fp_h / 2) + (right * fp_w / 2));  // Bottom right corner of the far plane

  Eigen::Vector3f np_c (T + view * np_dist_);                   // near plane center
  //Eigen::Vector3f np_tl = np_c + (up * np_h/2) - (right * np_w/2); // Top left corner of the near plane
  Eigen::Vector3f np_tr (np_c + (up * np_h / 2) + (right * np_w / 2));   // Top right corner of the near plane
  Eigen::Vector3f np_bl (np_c - (up * np_h / 2) - (right * np_w / 2));   // Bottom left corner of the near plane
  Eigen::Vector3f np_br (np_c - (up * np_h / 2) + (right * np_w / 2));   // Bottom right corner of the near plane

  pl_f.block (0, 0, 3, 1).matrix () = (fp_bl - fp_br).cross (fp_tr - fp_br);   // Far plane equation - cross product of the
  pl_f (3) = -fp_c.dot (pl_f.block (0, 0, 3, 1));                    // perpendicular edges of the far plane

  pl_n.block (0, 0, 3, 1).matrix () = (np_tr - np_br).cross (np_bl - np_br);   // Near plane equation - cross product of the
  pl_n (3) = -np_c.dot (pl_n.block (0, 0, 3, 1));                    // perpendicular edges of the far plane

  Eigen::Vector3f a (fp_bl - T);    // Vector connecting the camera and far plane bottom left
  Eigen::Vector3f b (fp_br - T);    // Vector connecting the camera and far plane bottom right
  Eigen::Vector3f c (fp_tr - T);    // Vector connecting the camera and far plane top right
  Eigen::Vector3f d (fp_tl - T);    // Vector connecting the camera and far plane top left

  //                   Frustum and the vectors a, b, c and d. T is the position of the camera
  //                             _________
  //                           /|       . |
  //                       d  / |   c .   |
  //                         /  | __._____|
  //                        /  /  .      .
  //                 a <---/-/  .    .
  //                      / / .   .  b
  //                     /   .
  //                     .
  //                   T
  //

  pl_r.block (0, 0, 3, 1).matrix () = b.cross (c);
  pl_l.block (0, 0, 3, 1).matrix () = d.cross (a);
  pl_t.block (0, 0, 3, 1).matrix () = c.cross (d);
  pl_b.block (0, 0, 3, 1).matrix () = a.cross (b);

  pl_r (3) = -T.dot (pl_r.block (0, 0, 3, 1));
  pl_l (3) = -T.dot (pl_l.block (0, 0, 3, 1));
  pl_t (3) = -T.dot (pl_t.block (0, 0, 3, 1));
  pl_b (3) = -T.dot (pl_b.block (0, 0, 3, 1));

  output.reserve (input_->points.size ());
  for (int i = 0; i < int (input_->points.size ()); i++)
  {
    Eigen::Vector4f pt (input_->points[i].x, input_->points[i].y, input_->points[i].z, 1.0f);

    if ( (pt.dot (pl_l) <= 0) &&
         (pt.dot (pl_r) <= 0) &&
         (pt.dot (pl_t) <= 0) &&
         (pt.dot (pl_b) <= 0) &&
         (pt.dot (pl_f) <= 0) &&
         (pt.dot (pl_n) <= 0) )
    {
      output.points.push_back (input_->points[i]);
    }
  }
  output.width = 1;
  output.height = uint32_t (output.points.size ());
}

///////////////////////////////////////////////////////////////////////////////
template <typename PointT> void
pcl::FrustumCulling<PointT>::applyFilter (std::vector<int> &indices)
{
  int indices_count = 0;
  int removed_indices_count = 0;

  Eigen::Vector4f pl_n; // near plane
  Eigen::Vector4f pl_f; // far plane
  Eigen::Vector4f pl_t; // top plane
  Eigen::Vector4f pl_b; // bottom plane
  Eigen::Vector4f pl_r; // right plane
  Eigen::Vector4f pl_l; // left plane

  Eigen::Vector3f view = camera_pose_.block (0, 0, 3, 1);    // view vector for the camera  - first column of the rotation matrix
  Eigen::Vector3f up = camera_pose_.block (0, 1, 3, 1);      // up vector for the camera    - second column of the rotation matix
  Eigen::Vector3f right = camera_pose_.block (0, 2, 3, 1);   // right vector for the camera - third column of the rotation matrix
  Eigen::Vector3f T = camera_pose_.block (0, 3, 3, 1);       // The (X, Y, Z) position of the camera w.r.t origin

  vfov_ = float (vfov_ * M_PI / 180); // degrees to radians
  hfov_ = float (hfov_ * M_PI / 180); // degrees to radians

  float np_h = float (2 * tan (vfov_ / 2) * np_dist_);  // near plane height
  float np_w = float (2 * tan (hfov_ / 2) * np_dist_);  // near plane width

  float fp_h = float (2 * tan (vfov_ / 2) * fp_dist_);    // far plane height
  float fp_w = float (2 * tan (hfov_ / 2) * fp_dist_);    // far plane width

  Eigen::Vector3f fp_c (T + view * fp_dist_);                 // far plane center
  Eigen::Vector3f fp_tl (fp_c + (up * fp_h / 2) - (right * fp_w / 2));  // Top left corner of the far plane
  Eigen::Vector3f fp_tr (fp_c + (up * fp_h / 2) + (right * fp_w / 2));  // Top right corner of the far plane
  Eigen::Vector3f fp_bl (fp_c - (up * fp_h / 2) - (right * fp_w / 2));  // Bottom left corner of the far plane
  Eigen::Vector3f fp_br (fp_c - (up * fp_h / 2) + (right * fp_w / 2));  // Bottom right corner of the far plane

  Eigen::Vector3f np_c (T + view * np_dist_);                   // near plane center
  //Eigen::Vector3f np_tl = np_c + (up * np_h/2) - (right * np_w/2); // Top left corner of the near plane
  Eigen::Vector3f np_tr (np_c + (up * np_h / 2) + (right * np_w / 2));   // Top right corner of the near plane
  Eigen::Vector3f np_bl (np_c - (up * np_h / 2) - (right * np_w / 2));   // Bottom left corner of the near plane
  Eigen::Vector3f np_br (np_c - (up * np_h / 2) + (right * np_w / 2));   // Bottom right corner of the near plane

  pl_f.block (0, 0, 3, 1).matrix () = (fp_bl - fp_br).cross (fp_tr - fp_br);   // Far plane equation - cross product of the
  pl_f (3) = -fp_c.dot (pl_f.block (0, 0, 3, 1));                    // perpendicular edges of the far plane

  pl_n.block (0, 0, 3, 1).matrix () = (np_tr - np_br).cross (np_bl - np_br);   // Near plane equation - cross product of the
  pl_n (3) = -np_c.dot (pl_n.block (0, 0, 3, 1));                    // perpendicular edges of the far plane

  Eigen::Vector3f a (fp_bl - T);    // Vector connecting the camera and far plane bottom left
  Eigen::Vector3f b (fp_br - T);    // Vector connecting the camera and far plane bottom right
  Eigen::Vector3f c (fp_tr - T);    // Vector connecting the camera and far plane top right
  Eigen::Vector3f d (fp_tl - T);    // Vector connecting the camera and far plane top left

  //                   Frustum and the vectors a, b, c and d. T is the position of the camera
  //                             _________
  //                           /|       . |
  //                       d  / |   c .   |
  //                         /  | __._____|
  //                        /  /  .      .
  //                 a <---/-/  .    .
  //                      / / .   .  b
  //                     /   .
  //                     .
  //                   T
  //

  pl_r.block (0, 0, 3, 1).matrix () = b.cross (c);
  pl_l.block (0, 0, 3, 1).matrix () = d.cross (a);
  pl_t.block (0, 0, 3, 1).matrix () = c.cross (d);
  pl_b.block (0, 0, 3, 1).matrix () = a.cross (b);

  pl_r (3) = -T.dot (pl_r.block (0, 0, 3, 1));
  pl_l (3) = -T.dot (pl_l.block (0, 0, 3, 1));
  pl_t (3) = -T.dot (pl_t.block (0, 0, 3, 1));
  pl_b (3) = -T.dot (pl_b.block (0, 0, 3, 1));

  removed_indices_->reserve (indices.size ());

  for (int i = 0; i < int (indices.size ()); i++)
  {
    Eigen::Vector4f pt (input_->points[indices[i]].x,
                        input_->points[indices[i]].y,
                        input_->points[indices[i]].z,
                        1.0f);

    if ( (pt.dot (pl_l) <= 0) &&
         (pt.dot (pl_r) <= 0) &&
         (pt.dot (pl_t) <= 0) &&
         (pt.dot (pl_b) <= 0) &&
         (pt.dot (pl_f) <= 0) &&
         (pt.dot (pl_n) <= 0) )
    {
      if (extract_removed_indices_)
      {
        (*removed_indices_)[removed_indices_count++] = static_cast<int> (i);
      }
      else
      {
        indices[indices_count++] = (*indices_)[i];
      }
    }
  }
  indices.resize (indices_count);
  removed_indices_->resize (removed_indices_count);
}

#define PCL_INSTANTIATE_FrustumCulling(T) template class PCL_EXPORTS pcl::FrustumCulling<T>;

#endif
<|endoftext|>


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

#include "postgis_featureset.hpp"
#include "resultset.hpp"
#include "cursorresultset.hpp"

// mapnik
#include <mapnik/global.hpp>
#include <mapnik/wkb.hpp>
#include <mapnik/unicode.hpp>
#include <mapnik/sql_utils.hpp>
#include <mapnik/feature_factory.hpp>
#include <mapnik/util/conversions.hpp>

// boost
#include <boost/algorithm/string.hpp>
#include <boost/spirit/include/qi.hpp>

// stl
#include <sstream>
#include <string>

using boost::trim_copy;
using mapnik::geometry_type;
using mapnik::byte;
using mapnik::geometry_utils;
using mapnik::feature_factory;
using mapnik::context_ptr;

postgis_featureset::postgis_featureset(boost::shared_ptr<IResultSet> const& rs,
                                       context_ptr const& ctx,
                                       std::string const& encoding,
                                       bool key_field)
    : rs_(rs),
      ctx_(ctx),
      tr_(new transcoder(encoding)),
      totalGeomSize_(0),
      feature_id_(1),
      key_field_(key_field)
{
}

feature_ptr postgis_featureset::next()
{
    if (rs_->next())
    {
        // new feature
        unsigned pos = 1;
        feature_ptr feature;

        if (key_field_)
        {
            // create feature with user driven id from attribute
            int oid = rs_->getTypeOID(pos);
            const char* buf = rs_->getValue(pos);
            std::string name = rs_->getFieldName(pos);

            // validation happens of this type at bind()
            int val;
            if (oid == 20)
            {
                val = int8net(buf);
            }
            else if (oid == 21)
            {
                val = int2net(buf);
            }
            else
            {
                val = int4net(buf);
            }

            feature = feature_factory::create(ctx_, val);
            // TODO - extend feature class to know
            // that its id is also an attribute to avoid
            // this duplication
            feature->put(name,val);
            ++pos;
        }
        else
        {
            // fallback to auto-incrementing id
            feature = feature_factory::create(ctx_, feature_id_);
            ++feature_id_;
        }

        // parse geometry
        int size = rs_->getFieldLength(0);
        const char *data = rs_->getValue(0);
        geometry_utils::from_wkb(feature->paths(), data, size);
        totalGeomSize_ += size;

        int num_attrs = ctx_->size() + 1;
        for (; pos < num_attrs; ++pos)
        {
            std::string name = rs_->getFieldName(pos);

            if (rs_->isNull(pos))
            {
                feature->put(name, mapnik::value_null());
            }
            else
            {
                const char* buf = rs_->getValue(pos);
                const int oid = rs_->getTypeOID(pos);
                switch (oid)
                {
                    case 16: //bool
                    {
                        feature->put(name, (buf[0] != 0));
                        break;
                    }

                    case 23: //int4
                    {
                        int val = int4net(buf);
                        feature->put(name, val);
                        break;
                    }

                    case 21: //int2
                    {
                        int val = int2net(buf);
                        feature->put(name, val);
                        break;
                    }

                    case 20: //int8/BigInt
                    {
                        int val = int8net(buf);
                        feature->put(name, val);
                        break;
                    }

                    case 700: //float4
                    {
                        float val;
                        float4net(val, buf);
                        feature->put(name, val);
                        break;
                    }

                    case 701: //float8
                    {
                        double val;
                        float8net(val, buf);
                        feature->put(name, val);
                        break;
                    }

                    case 25:   //text
                    case 1043: //varchar
                    {
                        feature->put(name, tr_->transcode(buf));
                        break;
                    }

                    case 1042: //bpchar
                    {
                        feature->put(name, tr_->transcode(trim_copy(std::string(buf)).c_str()));
                        break;
                    }

                    case 1700: //numeric
                    {
                        double val;
                        std::string str = mapnik::sql_utils::numeric2string(buf);
                        if (mapnik::util::string2double(str, val))
                        {
                            feature->put(name, val);
                        }
                        break;
                    }

                    default:
                    {
#ifdef MAPNIK_DEBUG
                        std::clog << "Postgis Plugin: uknown OID = " << oid << std::endl;
#endif
                        break;
                    }
                }
            }
        }
        return feature;
    }
    else
    {
        rs_->close();
        return feature_ptr();
    }
}

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

#include "postgis_featureset.hpp"
#include "resultset.hpp"
#include "cursorresultset.hpp"

// mapnik
#include <mapnik/global.hpp>
#include <mapnik/wkb.hpp>
#include <mapnik/unicode.hpp>
#include <mapnik/sql_utils.hpp>
#include <mapnik/feature_factory.hpp>
#include <mapnik/util/conversions.hpp>

// boost
#include <boost/algorithm/string.hpp>
#include <boost/spirit/include/qi.hpp>

// stl
#include <sstream>
#include <string>

using boost::trim_copy;
using mapnik::geometry_type;
using mapnik::byte;
using mapnik::geometry_utils;
using mapnik::feature_factory;
using mapnik::context_ptr;

postgis_featureset::postgis_featureset(boost::shared_ptr<IResultSet> const& rs,
                                       context_ptr const& ctx,
                                       std::string const& encoding,
                                       bool key_field)
    : rs_(rs),
      ctx_(ctx),
      tr_(new transcoder(encoding)),
      totalGeomSize_(0),
      feature_id_(1),
      key_field_(key_field)
{
}

feature_ptr postgis_featureset::next()
{
    if (rs_->next())
    {
        // new feature
        unsigned pos = 1;
        feature_ptr feature;

        if (key_field_)
        {
            // create feature with user driven id from attribute
            int oid = rs_->getTypeOID(pos);
            const char* buf = rs_->getValue(pos);
            std::string name = rs_->getFieldName(pos);

            // validation happens of this type at bind()
            int val;
            if (oid == 20)
            {
                val = int8net(buf);
            }
            else if (oid == 21)
            {
                val = int2net(buf);
            }
            else
            {
                val = int4net(buf);
            }

            feature = feature_factory::create(ctx_, val);
            // TODO - extend feature class to know
            // that its id is also an attribute to avoid
            // this duplication
            feature->put(name,val);
            ++pos;
        }
        else
        {
            // fallback to auto-incrementing id
            feature = feature_factory::create(ctx_, feature_id_);
            ++feature_id_;
        }

        // parse geometry
        int size = rs_->getFieldLength(0);
        const char *data = rs_->getValue(0);
        geometry_utils::from_wkb(feature->paths(), data, size);
        totalGeomSize_ += size;

        int num_attrs = ctx_->size() + 1;
        for (; pos < num_attrs; ++pos)
        {
            std::string name = rs_->getFieldName(pos);

            if (rs_->isNull(pos))
            {
                feature->put(name, mapnik::value_null());
            }
            else
            {
                const char* buf = rs_->getValue(pos);
                const int oid = rs_->getTypeOID(pos);
                switch (oid)
                {
                    case 16: //bool
                    {
                        feature->put(name, (buf[0] != 0));
                        break;
                    }

                    case 23: //int4
                    {
                        int val = int4net(buf);
                        feature->put(name, val);
                        break;
                    }

                    case 21: //int2
                    {
                        int val = int2net(buf);
                        feature->put(name, val);
                        break;
                    }

                    case 20: //int8/BigInt
                    {
                        // TODO - need to support boost::uint64_t in mapnik::value
                        // https://github.com/mapnik/mapnik/issues/895
                        int val = int8net(buf);
                        feature->put(name, val);
                        break;
                    }

                    case 700: //float4
                    {
                        float val;
                        float4net(val, buf);
                        feature->put(name, val);
                        break;
                    }

                    case 701: //float8
                    {
                        double val;
                        float8net(val, buf);
                        feature->put(name, val);
                        break;
                    }

                    case 25:   //text
                    case 1043: //varchar
                    {
                        feature->put(name, tr_->transcode(buf));
                        break;
                    }

                    case 1042: //bpchar
                    {
                        feature->put(name, tr_->transcode(trim_copy(std::string(buf)).c_str()));
                        break;
                    }

                    case 1700: //numeric
                    {
                        double val;
                        std::string str = mapnik::sql_utils::numeric2string(buf);
                        if (mapnik::util::string2double(str, val))
                        {
                            feature->put(name, val);
                        }
                        break;
                    }

                    default:
                    {
#ifdef MAPNIK_DEBUG
                        std::clog << "Postgis Plugin: uknown OID = " << oid << std::endl;
#endif
                        break;
                    }
                }
            }
        }
        return feature;
    }
    else
    {
        rs_->close();
        return feature_ptr();
    }
}

postgis_featureset::~postgis_featureset()
{
    rs_->close();
}
<|endoftext|>


<commit_before>
#include <stdio.h>
#include <string>
#include <iostream>
#include <fstream>
#include <vector>
#include "api/BamReader.h"
#include "transrate-pileup.h"

using namespace BamTools;

using namespace std;

struct ContigRecord {
  int bases_mapped;
  int p_seq_true;
  int bridges;
  int length;
  string name;
  int fragments_mapped;
  int both_mapped;
  int properpair;
  int good;
  int bases_uncovered;
  double p_unique;
  double p_not_segmented;
};

class BetterBam {
    int realistic_distance;
    int seq_count;
    int i,j;
    uint32_t nm_tag;
    int ldist;
    int rdist;
    int maxL=0;
    std::string file;
    BamReader reader;
    BamAlignment alignment;
  public:
    std::vector<ContigRecord> array;
    BetterBam (std::string);

    // loop through all cigar operations and check they are not S
    bool check_cigar(BamAlignment alignment) {
      int numCigarOps = alignment.CigarData.size();
      bool check = false;
      for (int i = 0; i < numCigarOps; ++i) {
        const CigarOp& op = alignment.CigarData.at(i);
        if (op.Type != 'S') {
          check = true;
        }
      }
      return check;
    }

    // set realistic distance between pairs to have 0.03% false positive rate
    void set_fragment_size(int size, int sd) {
      realistic_distance = size + 3 * sd;
    }

    int load_bam() {
      if (!reader.Open(file)) {
        cerr << "Could not open BAM file" << endl;
        return 1;
      }
      // get sam header
      SamSequenceDictionary dictionary = reader.GetHeader().Sequences;
      seq_count = dictionary.Size();
      array.resize(seq_count);
      // get an iterator for looping over the sequences in the header
      std::vector<SamSequence>::iterator it = dictionary.Begin();
      // fill the vector with intial values
      for (i = 0; i < seq_count; i++) {
        array[i].bases_mapped = 0;
        array[i].p_seq_true = 0;
        array[i].bridges = 0;
        if (it[i].HasLength()) {
          array[i].length = atoi(it[i].Length.c_str());
          if (array[i].length > maxL) {
            maxL = array[i].length;
          }
        } else {
          array[i].length = 0;
        }
        array[i].name = it[i].Name;
        array[i].fragments_mapped = 0;
        array[i].both_mapped = 0;
        array[i].properpair = 0;
        array[i].good = 0;
        array[i].bases_uncovered = 0;
        array[i].p_unique = 0;
        array[i].p_not_segmented = 1;
      }
      // loop through bam file
      i = -2;
      TransratePileup pileup(maxL);
      int ref_length = -1;
      while (reader.GetNextAlignment(alignment)) {

        // read must be mapped
        if (!alignment.IsMapped()) {
          continue;
        }

        // alignment must have a valid cigar sting
        if (!check_cigar(alignment)) {
          continue;
        }

        // check this read comes from the currently loaded contig
        // if not, load the new contig
        if (alignment.RefID != i) {
          if (i>=0) {
            array[i].bases_uncovered = pileup.getBasesUncovered();
            array[i].p_unique = pileup.getUniqueBases();
            array[i].p_not_segmented = pileup.p_not_segmented();
          }
          i = alignment.RefID;
          ref_length = array[i].length;
          pileup.clearCoverage(ref_length);
        }

        // we only care about the primary alignment of each fragment
        if (!alignment.IsPrimaryAlignment()) {
          continue;
        }

        pileup.addAlignment(alignment);

        array[i].bases_mapped += alignment.Length;

        // store edit distance for sequence accuracy calculation
        if (alignment.HasTag("NM")) {
          if (alignment.GetTag("NM", nm_tag)) {
            array[i].p_seq_true += nm_tag;
          }
        }

        // count fragments where either or both mates mapped
        if (alignment.IsFirstMate() ||
          (alignment.IsSecondMate() && !alignment.IsMateMapped())) {
          array[i].fragments_mapped++;
        }

        // from now on ignore fragments unless both mates mapped
        if (!(alignment.IsFirstMate() && alignment.IsMateMapped())) {
          continue;
        }

        array[i].both_mapped++;

        // mates must align to same contig, otherwise we record a bridge
        if (alignment.RefID != alignment.MateRefID) {
          array[i].bridges++;
          continue;
        }

        // fragment length must be plausible
        ldist = max(alignment.Position-alignment.MatePosition,
                    alignment.MatePosition-alignment.Position);
        if (ldist > realistic_distance) {
          // mates are too far apart
          continue;
        }

        // read orientation must match the generated library
        // in this case we only test for FR/RF orientation,
        // that is - we expect mates to be on opposite strands
        bool is_reversed = alignment.IsReverseStrand();
        bool is_mate_reversed = alignment.IsMateReverseStrand();

        if (!is_reversed && is_mate_reversed) {
          // in FR orientation, first read must start
          // before second read
          if (alignment.Position < alignment.MatePosition) {
            array[i].good++;
          }
        } else if (is_reversed && !is_mate_reversed) {
          // in RF orientation, second read must start
          // before first read
          if (alignment.MatePosition < alignment.Position) {
            array[i].good++;
          }
        }
      }
      array[i].bases_uncovered = pileup.getBasesUncovered();
      array[i].p_unique = pileup.getUniqueBases();
      array[i].p_not_segmented = pileup.p_not_segmented();

      reader.Close();
      return 0;
    }

    int get_seq_count() {
      return seq_count;
    }

    ContigRecord get_info(int i) {
      return array.at(i);
    }

    int get_bases_mapped(int i) {
      return array.at(i).bases_mapped;
    }
};

//constructor
BetterBam::BetterBam (std::string s) {
    file = s;
    realistic_distance = 350;
}

int main (int argc, char* argv[]) {
  if (argc == 3) {
    string infile = argv[1];
    BetterBam bam (infile);
    bam.load_bam();
    int i;

    std::ofstream output;
    output.open (argv[2]);
    output << "name,p_seq_true,bridges,length,fragments_mapped,"
              "both_mapped,properpair,good,bases_uncovered,p_unique,"
              "p_not_segmented" << endl;
    for (i = 0; i < bam.get_seq_count(); i++) {
      output << bam.get_info(i).name << ",";
      if (bam.get_info(i).bases_mapped>0) {
        output << 1-((double)bam.get_info(i).p_seq_true/bam.get_info(i).bases_mapped) << ",";
      } else {
        output << "1,";
      }
      output << bam.get_info(i).bridges << ",";
      output << bam.get_info(i).length << ",";
      output << bam.get_info(i).fragments_mapped << ",";
      output << bam.get_info(i).both_mapped << ",";
      output << bam.get_info(i).properpair << ",";
      output << bam.get_info(i).good << ",";
      output << bam.get_info(i).bases_uncovered << ",";
      output << bam.get_info(i).p_unique << ",";
      output << bam.get_info(i).p_not_segmented << endl;
    }
    output.close();
    return 0;
  } else {
    cout << "bam-read version 0.3.4\n"
         << "Usage:\n"
         << "bam-read <bam_file> <output_csv>" << endl;
    return 1;
  }
}
<commit_msg>increased realistic distance<commit_after>
#include <stdio.h>
#include <string>
#include <iostream>
#include <fstream>
#include <vector>
#include "api/BamReader.h"
#include "transrate-pileup.h"

using namespace BamTools;

using namespace std;

struct ContigRecord {
  int bases_mapped;
  int p_seq_true;
  int bridges;
  int length;
  string name;
  int fragments_mapped;
  int both_mapped;
  int properpair;
  int good;
  int bases_uncovered;
  double p_unique;
  double p_not_segmented;
};

class BetterBam {
    int realistic_distance;
    int seq_count;
    int i,j;
    uint32_t nm_tag;
    int ldist;
    int rdist;
    int maxL=0;
    std::string file;
    BamReader reader;
    BamAlignment alignment;
  public:
    std::vector<ContigRecord> array;
    BetterBam (std::string);

    // loop through all cigar operations and check they are not S
    bool check_cigar(BamAlignment alignment) {
      int numCigarOps = alignment.CigarData.size();
      bool check = false;
      for (int i = 0; i < numCigarOps; ++i) {
        const CigarOp& op = alignment.CigarData.at(i);
        if (op.Type != 'S') {
          check = true;
        }
      }
      return check;
    }

    // set realistic distance between pairs to have 0.03% false positive rate
    void set_fragment_size(int size, int sd) {
      realistic_distance = size + 3 * sd;
    }

    int load_bam() {
      if (!reader.Open(file)) {
        cerr << "Could not open BAM file" << endl;
        return 1;
      }
      // get sam header
      SamSequenceDictionary dictionary = reader.GetHeader().Sequences;
      seq_count = dictionary.Size();
      array.resize(seq_count);
      // get an iterator for looping over the sequences in the header
      std::vector<SamSequence>::iterator it = dictionary.Begin();
      // fill the vector with intial values
      for (i = 0; i < seq_count; i++) {
        array[i].bases_mapped = 0;
        array[i].p_seq_true = 0;
        array[i].bridges = 0;
        if (it[i].HasLength()) {
          array[i].length = atoi(it[i].Length.c_str());
          if (array[i].length > maxL) {
            maxL = array[i].length;
          }
        } else {
          array[i].length = 0;
        }
        array[i].name = it[i].Name;
        array[i].fragments_mapped = 0;
        array[i].both_mapped = 0;
        array[i].properpair = 0;
        array[i].good = 0;
        array[i].bases_uncovered = 0;
        array[i].p_unique = 0;
        array[i].p_not_segmented = 1;
      }
      // loop through bam file
      i = -2;
      TransratePileup pileup(maxL);
      int ref_length = -1;
      while (reader.GetNextAlignment(alignment)) {

        // read must be mapped
        if (!alignment.IsMapped()) {
          continue;
        }

        // alignment must have a valid cigar sting
        if (!check_cigar(alignment)) {
          continue;
        }

        // check this read comes from the currently loaded contig
        // if not, load the new contig
        if (alignment.RefID != i) {
          if (i>=0) {
            array[i].bases_uncovered = pileup.getBasesUncovered();
            array[i].p_unique = pileup.getUniqueBases();
            array[i].p_not_segmented = pileup.p_not_segmented();
          }
          i = alignment.RefID;
          ref_length = array[i].length;
          pileup.clearCoverage(ref_length);
        }

        // we only care about the primary alignment of each fragment
        if (!alignment.IsPrimaryAlignment()) {
          continue;
        }

        pileup.addAlignment(alignment);

        array[i].bases_mapped += alignment.Length;

        // store edit distance for sequence accuracy calculation
        if (alignment.HasTag("NM")) {
          if (alignment.GetTag("NM", nm_tag)) {
            array[i].p_seq_true += nm_tag;
          }
        }

        // count fragments where either or both mates mapped
        if (alignment.IsFirstMate() ||
          (alignment.IsSecondMate() && !alignment.IsMateMapped())) {
          array[i].fragments_mapped++;
        }

        // from now on ignore fragments unless both mates mapped
        if (!(alignment.IsFirstMate() && alignment.IsMateMapped())) {
          continue;
        }

        array[i].both_mapped++;

        // mates must align to same contig, otherwise we record a bridge
        if (alignment.RefID != alignment.MateRefID) {
          array[i].bridges++;
          continue;
        }

        // fragment length must be plausible
        ldist = max(alignment.Position-alignment.MatePosition,
                    alignment.MatePosition-alignment.Position);
        if (ldist > realistic_distance) {
          // mates are too far apart
          continue;
        }

        // read orientation must match the generated library
        // in this case we only test for FR/RF orientation,
        // that is - we expect mates to be on opposite strands
        bool is_reversed = alignment.IsReverseStrand();
        bool is_mate_reversed = alignment.IsMateReverseStrand();

        if (!is_reversed && is_mate_reversed) {
          // in FR orientation, first read must start
          // before second read
          if (alignment.Position < alignment.MatePosition) {
            array[i].good++;
          }
        } else if (is_reversed && !is_mate_reversed) {
          // in RF orientation, second read must start
          // before first read
          if (alignment.MatePosition < alignment.Position) {
            array[i].good++;
          }
        }
      }
      array[i].bases_uncovered = pileup.getBasesUncovered();
      array[i].p_unique = pileup.getUniqueBases();
      array[i].p_not_segmented = pileup.p_not_segmented();

      reader.Close();
      return 0;
    }

    int get_seq_count() {
      return seq_count;
    }

    ContigRecord get_info(int i) {
      return array.at(i);
    }

    int get_bases_mapped(int i) {
      return array.at(i).bases_mapped;
    }
};

//constructor
BetterBam::BetterBam (std::string s) {
    file = s;
    realistic_distance = 450;
}

int main (int argc, char* argv[]) {
  if (argc == 3) {
    string infile = argv[1];
    BetterBam bam (infile);
    bam.load_bam();
    int i;

    std::ofstream output;
    output.open (argv[2]);
    output << "name,p_seq_true,bridges,length,fragments_mapped,"
              "both_mapped,properpair,good,bases_uncovered,p_unique,"
              "p_not_segmented" << endl;
    for (i = 0; i < bam.get_seq_count(); i++) {
      output << bam.get_info(i).name << ",";
      if (bam.get_info(i).bases_mapped>0) {
        output << 1-((double)bam.get_info(i).p_seq_true/bam.get_info(i).bases_mapped) << ",";
      } else {
        output << "1,";
      }
      output << bam.get_info(i).bridges << ",";
      output << bam.get_info(i).length << ",";
      output << bam.get_info(i).fragments_mapped << ",";
      output << bam.get_info(i).both_mapped << ",";
      output << bam.get_info(i).properpair << ",";
      output << bam.get_info(i).good << ",";
      output << bam.get_info(i).bases_uncovered << ",";
      output << bam.get_info(i).p_unique << ",";
      output << bam.get_info(i).p_not_segmented << endl;
    }
    output.close();
    return 0;
  } else {
    cout << "bam-read version 0.3.4\n"
         << "Usage:\n"
         << "bam-read <bam_file> <output_csv>" << endl;
    return 1;
  }
}
<|endoftext|>


<commit_before>#include "include-opencv.hpp"
#include <algorithm>
#include <cstdint>
#include <fmo/assert.hpp>
#include <fmo/common.hpp>
#include <mutex>
#include <vector>
#include <fmo/stripgen.hpp>

namespace fmo {
    struct StripGenImpl : public cv::ParallelLoopBody {
        using batch_t = uint64_t;
        using rle_t = int16_t;

        enum {
            WIDTH = sizeof(batch_t),
        };

        StripGenImpl(const fmo::Mat& img, int minHeight, int minGap, int step,
                     std::vector<rle_t>& rle, std::vector<StripRepr>& temp,
                     std::vector<StripRepr>& out, int& noiseOut, int numThreads)
            : mDims(img.dims()),
              mRleStep(mDims.height + 4),
              mRleSz(mRleStep * WIDTH),
              mTempSz((mRleSz + 1) / 2),
              mSkip(int(img.skip()) / WIDTH),
              mStep(step),
              mMinHeight(minHeight),
              mMinGap(minGap),
              mData((const batch_t*)(img.data())),
              mRle(&rle),
              mOut(&out),
              mNoiseOut(&noiseOut),
              mTemp(&temp),
              mNumThreads(numThreads) {
            FMO_ASSERT(int(img.skip()) % WIDTH == 0, "StripGen::operator(): bad skip");
            mRle->resize(mRleSz * mNumThreads);
            mTemp->resize(mTempSz * mNumThreads);
            mOut->clear();
            *mNoiseOut = 0;
        }

        virtual void operator()(const cv::Range& r) const override {
            const int threadNum = r.start;
            rle_t* const rle = mRle->data() + (mRleSz * threadNum);
            StripRepr* const temp = mTemp->data() + (mTempSz * threadNum);
            const int16_t step = int16_t(mStep);
            const int16_t halfStep = int16_t(mStep / 2);
            const int pad = std::max(0, std::max(mMinHeight, mMinGap));
            const int numBatches = mDims.width / WIDTH;
            const int batchFirst = (threadNum * numBatches) / mNumThreads;
            const int batchLast = ((threadNum + 1) * numBatches) / mNumThreads;
            const int colFirst = batchFirst * WIDTH;
            const int colLast = batchLast * WIDTH;
            const int skip = mSkip;
            const int minHeight = mMinHeight;
            const Dims dims = mDims;
            const int minGap = mMinGap;
            StripRepr* tempEnd = temp;

            int16_t origX = int16_t(halfStep + (colFirst * step));
            int noise = 0;
            rle_t* front[WIDTH];
            const batch_t* colData = mData + batchFirst;

            for (int w = 0; w < WIDTH; w++) { front[w] = rle + (w * mRleStep); }

            for (int col = colFirst; col < colLast; col += WIDTH, colData++) {
                const batch_t* data = colData;
                rle_t* back[WIDTH];
                int n[WIDTH];

                for (int w = 0; w < WIDTH; w++) {
                    back[w] = front[w];

                    // add top of image
                    *back[w] = rle_t(-pad);
                    n[w] = 1;
                }

                // must start with a black segment
                if (*data != 0) {
                    for (int w = 0; w < WIDTH; w++) {
                        if (((const uint8_t*)(data))[w] != 0) {
                            *++(back[w]) = rle_t(0);
                            n[w]++;
                        }
                    }
                }
                data += skip;

                // store indices of changes
                for (int row = 1; row < dims.height; row++, data += skip) {
                    const batch_t* prev = data - skip;
                    if (*data != *prev) {
                        for (int w = 0; w < WIDTH; w++) {
                            if (((const uint8_t*)(data))[w] != ((const uint8_t*)(prev))[w]) {
                                if ((n[w] & 1) == 0 && (row - *(back[w])) < minHeight) {
                                    // remove noise
                                    back[w]--;
                                    n[w]--;
                                    noise++;
                                } else {
                                    *++(back[w]) = rle_t(row);
                                    n[w]++;
                                }
                            }
                        }
                    }
                }

                for (int w = 0; w < WIDTH; w++, origX += int16_t(step)) {
                    // must end with a black segment
                    if ((n[w] & 1) == 0) {
                        *++(back[w]) = rle_t(dims.height);
                        n[w]++;
                    }

                    // add bottom of image
                    *++(back[w]) = rle_t(dims.height + pad);
                    n[w]++;

                    // report white segments as strips if all conditions are met
                    rle_t* lastWhite = back[w] - 1;
                    for (rle_t* i = front[w]; i < lastWhite; i += 2) {
                        if (*(i + 1) - *(i + 0) >= minGap && *(i + 3) - *(i + 2) >= minGap) {
                            int halfHeight = (*(i + 2) - *(i + 1)) * halfStep;
                            int origY = (*(i + 2) + *(i + 1)) * halfStep;
                            tempEnd->pos = {int16_t(origX), int16_t(origY)};
                            tempEnd->halfDims = {int16_t(halfStep), int16_t(halfHeight)};
                            tempEnd++;
                        }
                    }
                }

                // move data outside
                {
                    std::lock_guard<std::mutex> lock(mMutex);

                    mOut->insert(mOut->end(), temp, tempEnd);
                    tempEnd = temp;

                    *mNoiseOut += noise;
                    noise = 0;
                }
            }
        }

    private:
        const Dims mDims;
        const int mRleStep;
        const int mRleSz;
        const int mTempSz;
        const int mSkip;
        const int mStep;
        const int mMinHeight;
        const int mMinGap;
        const batch_t* const mData;
        std::vector<rle_t>* const mRle;
        std::vector<StripRepr>* const mTemp;
        std::vector<StripRepr>* const mOut;
        int* const mNoiseOut;
        const int mNumThreads;
        mutable std::mutex mMutex;
    };

    void NewStripGen::operator()(const fmo::Mat& img, int minHeight, int minGap, int step,
        std::vector<StripRepr>& out, int& outNoise) {
        // run in parallel
        int numThreads = cv::getNumThreads();
        StripGenImpl job{img, minHeight, minGap, step, mRle, mTemp, out, outNoise, numThreads};
        cv::parallel_for_(cv::Range{0, numThreads}, job);

        // order strips by their top edge
        auto stripComp = [] (const StripRepr& l, const StripRepr& r) {
            if (l.pos.x == r.pos.x) {
                return (l.pos.y - l.halfDims.height) < (r.pos.y - r.halfDims.height);
            } else {
                return l.pos.x < r.pos.x;
            }
        };
        std::sort(begin(out), end(out), stripComp);
    }
}
<commit_msg>Fix GCC warning<commit_after>#include "include-opencv.hpp"
#include <algorithm>
#include <cstdint>
#include <fmo/assert.hpp>
#include <fmo/common.hpp>
#include <mutex>
#include <vector>
#include <fmo/stripgen.hpp>

namespace fmo {
    struct StripGenImpl : public cv::ParallelLoopBody {
        using batch_t = uint64_t;
        using rle_t = int16_t;

        enum {
            WIDTH = sizeof(batch_t),
        };

        StripGenImpl(const fmo::Mat& img, int minHeight, int minGap, int step,
                     std::vector<rle_t>& rle, std::vector<StripRepr>& temp,
                     std::vector<StripRepr>& out, int& noiseOut, int numThreads)
            : mDims(img.dims()),
              mRleStep(mDims.height + 4),
              mRleSz(mRleStep * WIDTH),
              mTempSz((mRleSz + 1) / 2),
              mSkip(int(img.skip()) / WIDTH),
              mStep(step),
              mMinHeight(minHeight),
              mMinGap(minGap),
              mData((const batch_t*)(img.data())),
              mRle(&rle),
              mTemp(&temp),
              mOut(&out),
              mNoiseOut(&noiseOut),
              mNumThreads(numThreads) {
            FMO_ASSERT(int(img.skip()) % WIDTH == 0, "StripGen::operator(): bad skip");
            mRle->resize(mRleSz * mNumThreads);
            mTemp->resize(mTempSz * mNumThreads);
            mOut->clear();
            *mNoiseOut = 0;
        }

        virtual void operator()(const cv::Range& r) const override {
            const int threadNum = r.start;
            rle_t* const rle = mRle->data() + (mRleSz * threadNum);
            StripRepr* const temp = mTemp->data() + (mTempSz * threadNum);
            const int16_t step = int16_t(mStep);
            const int16_t halfStep = int16_t(mStep / 2);
            const int pad = std::max(0, std::max(mMinHeight, mMinGap));
            const int numBatches = mDims.width / WIDTH;
            const int batchFirst = (threadNum * numBatches) / mNumThreads;
            const int batchLast = ((threadNum + 1) * numBatches) / mNumThreads;
            const int colFirst = batchFirst * WIDTH;
            const int colLast = batchLast * WIDTH;
            const int skip = mSkip;
            const int minHeight = mMinHeight;
            const Dims dims = mDims;
            const int minGap = mMinGap;
            StripRepr* tempEnd = temp;

            int16_t origX = int16_t(halfStep + (colFirst * step));
            int noise = 0;
            rle_t* front[WIDTH];
            const batch_t* colData = mData + batchFirst;

            for (int w = 0; w < WIDTH; w++) { front[w] = rle + (w * mRleStep); }

            for (int col = colFirst; col < colLast; col += WIDTH, colData++) {
                const batch_t* data = colData;
                rle_t* back[WIDTH];
                int n[WIDTH];

                for (int w = 0; w < WIDTH; w++) {
                    back[w] = front[w];

                    // add top of image
                    *back[w] = rle_t(-pad);
                    n[w] = 1;
                }

                // must start with a black segment
                if (*data != 0) {
                    for (int w = 0; w < WIDTH; w++) {
                        if (((const uint8_t*)(data))[w] != 0) {
                            *++(back[w]) = rle_t(0);
                            n[w]++;
                        }
                    }
                }
                data += skip;

                // store indices of changes
                for (int row = 1; row < dims.height; row++, data += skip) {
                    const batch_t* prev = data - skip;
                    if (*data != *prev) {
                        for (int w = 0; w < WIDTH; w++) {
                            if (((const uint8_t*)(data))[w] != ((const uint8_t*)(prev))[w]) {
                                if ((n[w] & 1) == 0 && (row - *(back[w])) < minHeight) {
                                    // remove noise
                                    back[w]--;
                                    n[w]--;
                                    noise++;
                                } else {
                                    *++(back[w]) = rle_t(row);
                                    n[w]++;
                                }
                            }
                        }
                    }
                }

                for (int w = 0; w < WIDTH; w++, origX += int16_t(step)) {
                    // must end with a black segment
                    if ((n[w] & 1) == 0) {
                        *++(back[w]) = rle_t(dims.height);
                        n[w]++;
                    }

                    // add bottom of image
                    *++(back[w]) = rle_t(dims.height + pad);
                    n[w]++;

                    // report white segments as strips if all conditions are met
                    rle_t* lastWhite = back[w] - 1;
                    for (rle_t* i = front[w]; i < lastWhite; i += 2) {
                        if (*(i + 1) - *(i + 0) >= minGap && *(i + 3) - *(i + 2) >= minGap) {
                            int halfHeight = (*(i + 2) - *(i + 1)) * halfStep;
                            int origY = (*(i + 2) + *(i + 1)) * halfStep;
                            tempEnd->pos = {int16_t(origX), int16_t(origY)};
                            tempEnd->halfDims = {int16_t(halfStep), int16_t(halfHeight)};
                            tempEnd++;
                        }
                    }
                }

                // move data outside
                {
                    std::lock_guard<std::mutex> lock(mMutex);

                    mOut->insert(mOut->end(), temp, tempEnd);
                    tempEnd = temp;

                    *mNoiseOut += noise;
                    noise = 0;
                }
            }
        }

    private:
        const Dims mDims;
        const int mRleStep;
        const int mRleSz;
        const int mTempSz;
        const int mSkip;
        const int mStep;
        const int mMinHeight;
        const int mMinGap;
        const batch_t* const mData;
        std::vector<rle_t>* const mRle;
        std::vector<StripRepr>* const mTemp;
        std::vector<StripRepr>* const mOut;
        int* const mNoiseOut;
        const int mNumThreads;
        mutable std::mutex mMutex;
    };

    void NewStripGen::operator()(const fmo::Mat& img, int minHeight, int minGap, int step,
        std::vector<StripRepr>& out, int& outNoise) {
        // run in parallel
        int numThreads = cv::getNumThreads();
        StripGenImpl job{img, minHeight, minGap, step, mRle, mTemp, out, outNoise, numThreads};
        cv::parallel_for_(cv::Range{0, numThreads}, job);

        // order strips by their top edge
        auto stripComp = [] (const StripRepr& l, const StripRepr& r) {
            if (l.pos.x == r.pos.x) {
                return (l.pos.y - l.halfDims.height) < (r.pos.y - r.halfDims.height);
            } else {
                return l.pos.x < r.pos.x;
            }
        };
        std::sort(begin(out), end(out), stripComp);
    }
}
<|endoftext|>


<commit_before>//
// Copyright (C) 2004 Stefan Seefeld
// All rights reserved.
// Licensed to the public under the terms of the GNU LGPL (>= 2),
// see the file COPYING for details.
//
#ifndef Synopsis_SymbolLookup_hh_
#define Synopsis_SymbolLookup_hh_

#include <Synopsis/SymbolLookup/Symbol.hh>
#include <Synopsis/SymbolLookup/Scope.hh>
#include <Synopsis/SymbolLookup/Scopes.hh>
#include <Synopsis/SymbolLookup/Walker.hh>

#endif
<commit_msg>Refactoring Part 1<commit_after><|endoftext|>