<commit_before>/*************************************************************************
 *
 *  $RCSfile: AdabasStat.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: oj $ $Date: 2001-07-04 13:09:12 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the License); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an AS IS basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef _DBAUI_ADASTAT_HXX_
#define _DBAUI_ADASTAT_HXX_

#ifndef _SV_FIXED_HXX
#include <vcl/fixed.hxx>
#endif
#ifndef _SV_BUTTON_HXX
#include <vcl/button.hxx>
#endif
#ifndef _SV_DIALOG_HXX
#include <vcl/dialog.hxx>
#endif
#ifndef DBAUI_FIELDCONTROLS_HXX
#include "FieldControls.hxx"
#endif
#ifndef _PRGSBAR_HXX
#include <svtools/prgsbar.hxx>
#endif
#ifndef _COM_SUN_STAR_SDBC_XCONNECTION_HPP_
#include <com/sun/star/sdbc/XConnection.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#endif

namespace dbaui
{
    //========================================================================
    // shows some statistics
    //========================================================================
    class OAdabasStatistics : public ModalDialog
    {
    protected:

        FixedLine               m_FL_FILES;
        FixedText               m_FT_SYSDEVSPACE;
        OPropEditCtrl           m_ET_SYSDEVSPACE;
        FixedText               m_FT_TRANSACTIONLOG;
        OPropEditCtrl           m_ET_TRANSACTIONLOG;
        FixedText               m_FT_DATADEVSPACE;
        OPropListBoxCtrl        m_LB_DATADEVS;
        FixedLine               m_FL_SIZES;
        FixedText               m_FT_SIZE;
        OPropEditCtrl           m_ET_SIZE;
        FixedText               m_FT_FREESIZE;
        OPropEditCtrl           m_ET_FREESIZE;
        FixedText               m_FT_MEMORYUSING;
        OPropNumericEditCtrl    m_ET_MEMORYUSING;

        OKButton                m_PB_OK;

        ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >
                                m_xConnection;  /// valid as long as the page is active
        sal_Bool                m_bErrorShown; // true when we shown already the error

        // check if the given table is accessable by the connected user
        sal_Bool checkSystemTable(const ::rtl::OUString& _rsSystemTable, ::rtl::OUString& _rsSchemaName );
        void showError();

    public:
        OAdabasStatistics(  Window* pParent,
                            const ::rtl::OUString& _rUser,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& _xCurrentConnection,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _xFactory);
        ~OAdabasStatistics();

    };
}
#endif //_DBAUI_ADASTAT_HXX_

<commit_msg>INTEGRATION: CWS ooo19126 (1.3.500); FILE MERGED 2005/09/05 17:33:29 rt 1.3.500.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: AdabasStat.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 14:40:06 $
 *
 *  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 _DBAUI_ADASTAT_HXX_
#define _DBAUI_ADASTAT_HXX_

#ifndef _SV_FIXED_HXX
#include <vcl/fixed.hxx>
#endif
#ifndef _SV_BUTTON_HXX
#include <vcl/button.hxx>
#endif
#ifndef _SV_DIALOG_HXX
#include <vcl/dialog.hxx>
#endif
#ifndef DBAUI_FIELDCONTROLS_HXX
#include "FieldControls.hxx"
#endif
#ifndef _PRGSBAR_HXX
#include <svtools/prgsbar.hxx>
#endif
#ifndef _COM_SUN_STAR_SDBC_XCONNECTION_HPP_
#include <com/sun/star/sdbc/XConnection.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#endif

namespace dbaui
{
    //========================================================================
    // shows some statistics
    //========================================================================
    class OAdabasStatistics : public ModalDialog
    {
    protected:

        FixedLine               m_FL_FILES;
        FixedText               m_FT_SYSDEVSPACE;
        OPropEditCtrl           m_ET_SYSDEVSPACE;
        FixedText               m_FT_TRANSACTIONLOG;
        OPropEditCtrl           m_ET_TRANSACTIONLOG;
        FixedText               m_FT_DATADEVSPACE;
        OPropListBoxCtrl        m_LB_DATADEVS;
        FixedLine               m_FL_SIZES;
        FixedText               m_FT_SIZE;
        OPropEditCtrl           m_ET_SIZE;
        FixedText               m_FT_FREESIZE;
        OPropEditCtrl           m_ET_FREESIZE;
        FixedText               m_FT_MEMORYUSING;
        OPropNumericEditCtrl    m_ET_MEMORYUSING;

        OKButton                m_PB_OK;

        ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >
                                m_xConnection;  /// valid as long as the page is active
        sal_Bool                m_bErrorShown; // true when we shown already the error

        // check if the given table is accessable by the connected user
        sal_Bool checkSystemTable(const ::rtl::OUString& _rsSystemTable, ::rtl::OUString& _rsSchemaName );
        void showError();

    public:
        OAdabasStatistics(  Window* pParent,
                            const ::rtl::OUString& _rUser,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& _xCurrentConnection,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _xFactory);
        ~OAdabasStatistics();

    };
}
#endif //_DBAUI_ADASTAT_HXX_

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: ColumnPeer.cxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-20 03:34:48 $
 *
 *  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 DBAUI_COLUMNPEER_HXX
#include "ColumnPeer.hxx"
#endif
#ifndef DBAUI_COLUMNCONTROLWINDOW_HXX
#include "ColumnControlWindow.hxx"
#endif
#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif
#ifndef DBACCESS_SHARED_DBUSTRINGS_HRC
#include "dbustrings.hrc"
#endif
#ifndef DBAUI_FIELDDESCRIPTIONS_HXX
#include "FieldDescriptions.hxx"
#endif

//.........................................................................
namespace dbaui
{
//.........................................................................
using namespace ::com::sun::star::awt;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::sdbc;

OColumnPeer::OColumnPeer(Window* _pParent,const Reference<XMultiServiceFactory>& _rxFactory)
    :m_xORB(_rxFactory)
    ,m_pActFieldDescr(NULL)
{
    osl_incrementInterlockedCount( &m_refCount );
    {
        OColumnControlWindow* pFieldControl = new OColumnControlWindow(_pParent,m_xORB);
        pFieldControl->SetComponentInterface(this);
        pFieldControl->Show();
    }
    osl_decrementInterlockedCount( &m_refCount );
}
// -----------------------------------------------------------------------------
void OColumnPeer::setEditWidth(sal_Int32 _nWidth)
{
    ::vos::OGuard aGuard( Application::GetSolarMutex() );

    OColumnControlWindow* pFieldControl = static_cast<OColumnControlWindow*>( GetWindow() );
    if ( pFieldControl )
    {
        pFieldControl->setEditWidth(_nWidth);
    }
}
// -----------------------------------------------------------------------------
void OColumnPeer::setColumn(const Reference< XPropertySet>& _xColumn)
{
    ::vos::OGuard aGuard( Application::GetSolarMutex() );

    OColumnControlWindow* pFieldControl = static_cast<OColumnControlWindow*>( GetWindow() );
    if ( pFieldControl )
    {
        if ( m_pActFieldDescr )
        {
            delete m_pActFieldDescr;
            m_pActFieldDescr = NULL;
        }
        if ( _xColumn.is() )
        {
            sal_Int32 nType         = 0;
            sal_Int32 nScale        = 0;
            sal_Int32 nPrecision    = 0;
            sal_Bool bAutoIncrement = sal_False;
            ::rtl::OUString sTypeName;

            try
            {
                // get the properties from the column
                _xColumn->getPropertyValue(PROPERTY_TYPENAME)       >>= sTypeName;
                _xColumn->getPropertyValue(PROPERTY_TYPE)           >>= nType;
                _xColumn->getPropertyValue(PROPERTY_SCALE)          >>= nScale;
                _xColumn->getPropertyValue(PROPERTY_PRECISION)      >>= nPrecision;
                _xColumn->getPropertyValue(PROPERTY_ISAUTOINCREMENT)    >>= bAutoIncrement;
            }
            catch(Exception)
            {
            }

            m_pActFieldDescr = new OFieldDescription(_xColumn,sal_True);
            // search for type
            ::rtl::OUString sCreateParam(RTL_CONSTASCII_USTRINGPARAM("x"));
            sal_Bool bForce;
            TOTypeInfoSP pTypeInfo = ::dbaui::getTypeInfoFromType(*pFieldControl->getTypeInfo(),nType,sTypeName,sCreateParam,nPrecision,nScale,bAutoIncrement,bForce);
            if ( !pTypeInfo.get() )
                pTypeInfo = pFieldControl->getDefaultTyp();

            m_pActFieldDescr->FillFromTypeInfo(pTypeInfo,sal_True,sal_False);
            m_xColumn = _xColumn;
        }
        pFieldControl->DisplayData(m_pActFieldDescr);
    }
}
// -----------------------------------------------------------------------------
void OColumnPeer::setConnection(const Reference< XConnection>& _xCon)
{
    ::vos::OGuard aGuard( Application::GetSolarMutex() );
    OColumnControlWindow* pFieldControl = static_cast<OColumnControlWindow*>( GetWindow() );
    if ( pFieldControl )
        pFieldControl->setConnection(_xCon);
}
//------------------------------------------------------------------------------
void OColumnPeer::setProperty( const ::rtl::OUString& _rPropertyName, const Any& Value) throw( RuntimeException )
{
    ::vos::OGuard aGuard( Application::GetSolarMutex() );

    if ( 0 == _rPropertyName.compareToAscii( PROPERTY_COLUMN ) )
    {
        Reference<XPropertySet> xProp(Value,UNO_QUERY);
        setColumn(xProp);
    }
    else if ( 0 == _rPropertyName.compareToAscii( PROPERTY_ACTIVECONNECTION ) )
    {
        Reference<XConnection> xCon(Value,UNO_QUERY);
        setConnection(xCon);
    }
    else
        VCLXWindow::setProperty(_rPropertyName,Value);
}
// -----------------------------------------------------------------------------
Any OColumnPeer::getProperty( const ::rtl::OUString& _rPropertyName ) throw( RuntimeException )
{
    Any aProp;
    OFieldDescControl* pFieldControl = static_cast<OFieldDescControl*>( GetWindow() );
    if ( pFieldControl && 0 == _rPropertyName.compareToAscii( PROPERTY_COLUMN ) )
    {
        aProp <<= m_xColumn;
    }
    else if ( pFieldControl && 0 == _rPropertyName.compareToAscii( PROPERTY_ACTIVECONNECTION ) )
    {
        aProp <<= pFieldControl->getConnection();
    }
    else
        aProp = VCLXWindow::getProperty(_rPropertyName);
    return aProp;
}
//.........................................................................
}   // namespace dbaui
//.........................................................................
<commit_msg>INTEGRATION: CWS pchfix02 (1.7.52); FILE MERGED 2006/09/01 17:24:43 kaib 1.7.52.1: #i68856# Added header markers and pch files<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: ColumnPeer.cxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-17 07:32: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
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_dbaccess.hxx"
#ifndef DBAUI_COLUMNPEER_HXX
#include "ColumnPeer.hxx"
#endif
#ifndef DBAUI_COLUMNCONTROLWINDOW_HXX
#include "ColumnControlWindow.hxx"
#endif
#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif
#ifndef DBACCESS_SHARED_DBUSTRINGS_HRC
#include "dbustrings.hrc"
#endif
#ifndef DBAUI_FIELDDESCRIPTIONS_HXX
#include "FieldDescriptions.hxx"
#endif

//.........................................................................
namespace dbaui
{
//.........................................................................
using namespace ::com::sun::star::awt;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::sdbc;

OColumnPeer::OColumnPeer(Window* _pParent,const Reference<XMultiServiceFactory>& _rxFactory)
    :m_xORB(_rxFactory)
    ,m_pActFieldDescr(NULL)
{
    osl_incrementInterlockedCount( &m_refCount );
    {
        OColumnControlWindow* pFieldControl = new OColumnControlWindow(_pParent,m_xORB);
        pFieldControl->SetComponentInterface(this);
        pFieldControl->Show();
    }
    osl_decrementInterlockedCount( &m_refCount );
}
// -----------------------------------------------------------------------------
void OColumnPeer::setEditWidth(sal_Int32 _nWidth)
{
    ::vos::OGuard aGuard( Application::GetSolarMutex() );

    OColumnControlWindow* pFieldControl = static_cast<OColumnControlWindow*>( GetWindow() );
    if ( pFieldControl )
    {
        pFieldControl->setEditWidth(_nWidth);
    }
}
// -----------------------------------------------------------------------------
void OColumnPeer::setColumn(const Reference< XPropertySet>& _xColumn)
{
    ::vos::OGuard aGuard( Application::GetSolarMutex() );

    OColumnControlWindow* pFieldControl = static_cast<OColumnControlWindow*>( GetWindow() );
    if ( pFieldControl )
    {
        if ( m_pActFieldDescr )
        {
            delete m_pActFieldDescr;
            m_pActFieldDescr = NULL;
        }
        if ( _xColumn.is() )
        {
            sal_Int32 nType         = 0;
            sal_Int32 nScale        = 0;
            sal_Int32 nPrecision    = 0;
            sal_Bool bAutoIncrement = sal_False;
            ::rtl::OUString sTypeName;

            try
            {
                // get the properties from the column
                _xColumn->getPropertyValue(PROPERTY_TYPENAME)       >>= sTypeName;
                _xColumn->getPropertyValue(PROPERTY_TYPE)           >>= nType;
                _xColumn->getPropertyValue(PROPERTY_SCALE)          >>= nScale;
                _xColumn->getPropertyValue(PROPERTY_PRECISION)      >>= nPrecision;
                _xColumn->getPropertyValue(PROPERTY_ISAUTOINCREMENT)    >>= bAutoIncrement;
            }
            catch(Exception)
            {
            }

            m_pActFieldDescr = new OFieldDescription(_xColumn,sal_True);
            // search for type
            ::rtl::OUString sCreateParam(RTL_CONSTASCII_USTRINGPARAM("x"));
            sal_Bool bForce;
            TOTypeInfoSP pTypeInfo = ::dbaui::getTypeInfoFromType(*pFieldControl->getTypeInfo(),nType,sTypeName,sCreateParam,nPrecision,nScale,bAutoIncrement,bForce);
            if ( !pTypeInfo.get() )
                pTypeInfo = pFieldControl->getDefaultTyp();

            m_pActFieldDescr->FillFromTypeInfo(pTypeInfo,sal_True,sal_False);
            m_xColumn = _xColumn;
        }
        pFieldControl->DisplayData(m_pActFieldDescr);
    }
}
// -----------------------------------------------------------------------------
void OColumnPeer::setConnection(const Reference< XConnection>& _xCon)
{
    ::vos::OGuard aGuard( Application::GetSolarMutex() );
    OColumnControlWindow* pFieldControl = static_cast<OColumnControlWindow*>( GetWindow() );
    if ( pFieldControl )
        pFieldControl->setConnection(_xCon);
}
//------------------------------------------------------------------------------
void OColumnPeer::setProperty( const ::rtl::OUString& _rPropertyName, const Any& Value) throw( RuntimeException )
{
    ::vos::OGuard aGuard( Application::GetSolarMutex() );

    if ( 0 == _rPropertyName.compareToAscii( PROPERTY_COLUMN ) )
    {
        Reference<XPropertySet> xProp(Value,UNO_QUERY);
        setColumn(xProp);
    }
    else if ( 0 == _rPropertyName.compareToAscii( PROPERTY_ACTIVECONNECTION ) )
    {
        Reference<XConnection> xCon(Value,UNO_QUERY);
        setConnection(xCon);
    }
    else
        VCLXWindow::setProperty(_rPropertyName,Value);
}
// -----------------------------------------------------------------------------
Any OColumnPeer::getProperty( const ::rtl::OUString& _rPropertyName ) throw( RuntimeException )
{
    Any aProp;
    OFieldDescControl* pFieldControl = static_cast<OFieldDescControl*>( GetWindow() );
    if ( pFieldControl && 0 == _rPropertyName.compareToAscii( PROPERTY_COLUMN ) )
    {
        aProp <<= m_xColumn;
    }
    else if ( pFieldControl && 0 == _rPropertyName.compareToAscii( PROPERTY_ACTIVECONNECTION ) )
    {
        aProp <<= pFieldControl->getConnection();
    }
    else
        aProp = VCLXWindow::getProperty(_rPropertyName);
    return aProp;
}
//.........................................................................
}   // namespace dbaui
//.........................................................................
<|endoftext|>


<commit_before>#include <iostream>
#include <vector>
#include <stack>
#include <deque>
#include <fstream>

using std::vector;
using std::stack;
using std::cout;
using std::cin;
using std::ifstream;

/****************************************************************/

/* function prototypes */
void read(vector<char> &i_vc, ifstream &is);
void interp(vector<unsigned char> &cells, vector<char> &ivc);
vector<char>::iterator skip_block(vector<char>::iterator i_it);

/****************************************************************/

/* reads brainfuck code into memory
 */
void read(vector<char> &i_vc, ifstream &is) {
	char c;
	is.get(c);
	while (!is.eof()) {
		i_vc.push_back(c);
		is.get(c);
	}
}

/****************************************************************/

/* interprets the brainfuck code, and performs the actions
 */
void interp(vector<unsigned char> &cells, vector<char> &i_vc) {
	stack<vector<char>::iterator> block_front;
	auto c_it = cells.begin();

	// scan through the code character by character
	for (auto i_it = i_vc.begin(); i_it != i_vc.end(); ++i_it) {
		if (*i_it == '>') {
			++c_it;
		} else if (*i_it == '<') {
			--c_it;
		} else if (*i_it == '+') {
			++(*c_it);
		} else if (*i_it == '-') {
			--(*c_it);
		} else if (*i_it == '.') {
			cout.put(*c_it);
		} else if (*i_it == ',') {
			*c_it = cin.get();
		} else if (*i_it == '[') {
			if (*c_it) {
				block_front.push(i_it);
			} else {
				i_it = skip_block(i_it);
			}
		} else if (*i_it == ']') {
			if (*c_it) {
				i_it = block_front.top();
			} else {
				block_front.pop();
			}
		}
	}
}

/****************************************************************/

/* skips to the end of a block of brainfuck code, indicated via [ and ], and
 * returns an iterator to it
 */
vector<char>::iterator skip_block(vector<char>::iterator i_it) {
	int count = 0;
	for (++i_it; ; ++i_it) {
		if (*i_it == ']' && count == 0) {
			return i_it;
		} else if (*i_it == ']') {
			--count;
		} else if (*i_it == '[') {
			++count;
		}
	}
}

/****************************************************************/

int main() {
	// TODO - add options for other brainfuck code locations
	// TODO - improve interface
	const int Cells = 30000;
	vector<unsigned char> cells(Cells, 0);
	vector<char> i_vc;
	ifstream is("hello_world.b");
	read(i_vc, is);
	interp(cells, i_vc);
	return 0;
}

<commit_msg>Improved interfacing and can now read brainfuck code from a target file.<commit_after>#include <iostream>
#include <vector>
#include <stack>
#include <deque>
#include <fstream>
#include <cstdlib>

using std::vector;
using std::stack;
using std::cout;
using std::cin;
using std::ifstream;

/****************************************************************/

/* function prototypes */
void read(vector<char> &i_vc, ifstream &is);
void interp(vector<unsigned char> &cells, vector<char> &ivc);
vector<char>::iterator skip_block(vector<char>::iterator i_it);

/****************************************************************/

/* reads brainfuck code into memory
 */
void read(vector<char> &i_vc, ifstream &is) {
	char c;
	is.get(c);

	while (!is.eof()) {
		i_vc.push_back(c);
		is.get(c);
	}
}

/****************************************************************/

/* interprets the brainfuck code, and performs the actions
 */
void interp(vector<unsigned char> &cells, vector<char> &i_vc) {
	stack<vector<char>::iterator> block_front;
	auto c_it = cells.begin();

	// scan through the code character by character
	for (auto i_it = i_vc.begin(); i_it != i_vc.end(); ++i_it) {
		if (*i_it == '>') {
			++c_it;
		} else if (*i_it == '<') {
			--c_it;
		} else if (*i_it == '+') {
			++(*c_it);
		} else if (*i_it == '-') {
			--(*c_it);
		} else if (*i_it == '.') {
			cout.put(*c_it);
		} else if (*i_it == ',') {
			*c_it = cin.get();
		} else if (*i_it == '[') {
			if (*c_it) {
				block_front.push(i_it);
			} else {
				i_it = skip_block(i_it);
			}
		} else if (*i_it == ']') {
			if (*c_it) {
				i_it = block_front.top();
			} else {
				block_front.pop();
			}
		}
	}
}

/****************************************************************/

/* skips to the end of a block of brainfuck code, indicated via [ and ], and
 * returns an iterator to it
 */
vector<char>::iterator skip_block(vector<char>::iterator i_it) {
	int count = 0;

	for (++i_it; ; ++i_it) {
		if (*i_it == ']' && count == 0) {
			return i_it;
		} else if (*i_it == ']') {
			--count;
		} else if (*i_it == '[') {
			++count;
		}
	}
}

/****************************************************************/

int main(int argc, char *argv[]) {
	const int Cells = 30000;
	vector<unsigned char> cells(Cells, 0);
	vector<char> i_vc;

	if (argc < 2) {
		// no brainfuck file provided
		cout << "Usage: function_prototype_extractor "
			"<input code file name>\n";
			return EXIT_FAILURE;
	}
	ifstream is(argv[1]);
	read(i_vc, is);
	interp(cells, i_vc);
	return 0;
}

<|endoftext|>


<commit_before>// Copyright (c) 2010 Google 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 Google Inc. 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.

#include <string>

#include <stdint.h>
#include <unistd.h>
#include <signal.h>
#include <sys/poll.h>
#include <sys/socket.h>
#include <sys/uio.h>

#include "breakpad_googletest_includes.h"
#include "client/linux/handler/exception_handler.h"
#include "client/linux/minidump_writer/minidump_writer.h"
#include "common/linux/eintr_wrapper.h"
#include "common/linux/linux_libc_support.h"
#include "third_party/lss/linux_syscall_support.h"

using namespace google_breakpad;

static void sigchld_handler(int signo) { }

class ExceptionHandlerTest : public ::testing::Test {
 protected:
  void SetUp() {
    // We need to be able to wait for children, so SIGCHLD cannot be SIG_IGN.
    struct sigaction sa;
    memset(&sa, 0, sizeof(sa));
    sa.sa_handler = sigchld_handler;
    ASSERT_NE(sigaction(SIGCHLD, &sa, &old_action), -1);
  }

  void TearDown() {
    sigaction(SIGCHLD, &old_action, NULL);
  }

  struct sigaction old_action;
};

TEST(ExceptionHandlerTest, Simple) {
  ExceptionHandler handler("/tmp", NULL, NULL, NULL, true);
}

static bool DoneCallback(const char* dump_path,
                         const char* minidump_id,
                         void* context,
                         bool succeeded) {
  if (!succeeded)
    return succeeded;

  int fd = (intptr_t) context;
  uint32_t len = my_strlen(minidump_id);
  HANDLE_EINTR(sys_write(fd, &len, sizeof(len)));
  HANDLE_EINTR(sys_write(fd, minidump_id, len));
  sys_close(fd);

  return true;
}

TEST(ExceptionHandlerTest, ChildCrash) {
  int fds[2];
  ASSERT_NE(pipe(fds), -1);

  const pid_t child = fork();
  if (child == 0) {
    close(fds[0]);
    ExceptionHandler handler("/tmp", NULL, DoneCallback, (void*) fds[1],
                             true);
    *reinterpret_cast<int*>(NULL) = 0;
  }
  close(fds[1]);

  int status;
  ASSERT_NE(HANDLE_EINTR(waitpid(child, &status, 0)), -1);
  ASSERT_TRUE(WIFSIGNALED(status));
  ASSERT_EQ(WTERMSIG(status), SIGSEGV);

  struct pollfd pfd;
  memset(&pfd, 0, sizeof(pfd));
  pfd.fd = fds[0];
  pfd.events = POLLIN | POLLERR;

  const int r = HANDLE_EINTR(poll(&pfd, 1, 0));
  ASSERT_EQ(r, 1);
  ASSERT_TRUE(pfd.revents & POLLIN);

  uint32_t len;
  ASSERT_EQ(read(fds[0], &len, sizeof(len)), (ssize_t)sizeof(len));
  ASSERT_LT(len, (uint32_t)2048);
  char* filename = reinterpret_cast<char*>(malloc(len + 1));
  ASSERT_EQ(read(fds[0], filename, len), len);
  filename[len] = 0;
  close(fds[0]);

  const std::string minidump_filename = std::string("/tmp/") + filename +
                                        ".dmp";

  struct stat st;
  ASSERT_EQ(stat(minidump_filename.c_str(), &st), 0);
  ASSERT_GT(st.st_size, 0u);
  unlink(minidump_filename.c_str());
}

static const unsigned kControlMsgSize =
    CMSG_SPACE(sizeof(int)) + CMSG_SPACE(sizeof(struct ucred));

static bool
CrashHandler(const void* crash_context, size_t crash_context_size,
             void* context) {
  const int fd = (intptr_t) context;
  int fds[2];
  pipe(fds);
  struct kernel_msghdr msg = {0};
  struct kernel_iovec iov;
  iov.iov_base = const_cast<void*>(crash_context);
  iov.iov_len = crash_context_size;
  msg.msg_iov = &iov;
  msg.msg_iovlen = 1;
  char cmsg[kControlMsgSize];
  memset(cmsg, 0, kControlMsgSize);
  msg.msg_control = cmsg;
  msg.msg_controllen = sizeof(cmsg);

  struct cmsghdr *hdr = CMSG_FIRSTHDR(&msg);
  hdr->cmsg_level = SOL_SOCKET;
  hdr->cmsg_type = SCM_RIGHTS;
  hdr->cmsg_len = CMSG_LEN(sizeof(int));
  *((int*) CMSG_DATA(hdr)) = fds[1];
  hdr = CMSG_NXTHDR((struct msghdr*) &msg, hdr);
  hdr->cmsg_level = SOL_SOCKET;
  hdr->cmsg_type = SCM_CREDENTIALS;
  hdr->cmsg_len = CMSG_LEN(sizeof(struct ucred));
  struct ucred *cred = reinterpret_cast<struct ucred*>(CMSG_DATA(hdr));
  cred->uid = getuid();
  cred->gid = getgid();
  cred->pid = getpid();

  HANDLE_EINTR(sys_sendmsg(fd, &msg, 0));
  sys_close(fds[1]);

  char b;
  HANDLE_EINTR(sys_read(fds[0], &b, 1));

  return true;
}

TEST(ExceptionHandlerTest, ExternalDumper) {
  int fds[2];
  ASSERT_NE(socketpair(AF_UNIX, SOCK_DGRAM, 0, fds), -1);
  static const int on = 1;
  setsockopt(fds[0], SOL_SOCKET, SO_PASSCRED, &on, sizeof(on));
  setsockopt(fds[1], SOL_SOCKET, SO_PASSCRED, &on, sizeof(on));

  const pid_t child = fork();
  if (child == 0) {
    close(fds[0]);
    ExceptionHandler handler("/tmp1", NULL, NULL, (void*) fds[1], true);
    handler.set_crash_handler(CrashHandler);
    *reinterpret_cast<int*>(NULL) = 0;
  }
  close(fds[1]);
  struct msghdr msg = {0};
  struct iovec iov;
  static const unsigned kCrashContextSize =
      sizeof(ExceptionHandler::CrashContext);
  char context[kCrashContextSize];
  char control[kControlMsgSize];
  iov.iov_base = context;
  iov.iov_len = kCrashContextSize;
  msg.msg_iov = &iov;
  msg.msg_iovlen = 1;
  msg.msg_control = control;
  msg.msg_controllen = kControlMsgSize;

  const ssize_t n = HANDLE_EINTR(recvmsg(fds[0], &msg, 0));
  ASSERT_EQ(n, kCrashContextSize);
  ASSERT_EQ(msg.msg_controllen, kControlMsgSize);
  ASSERT_EQ(msg.msg_flags, 0);

  pid_t crashing_pid = -1;
  int signal_fd = -1;
  for (struct cmsghdr *hdr = CMSG_FIRSTHDR(&msg); hdr;
       hdr = CMSG_NXTHDR(&msg, hdr)) {
    if (hdr->cmsg_level != SOL_SOCKET)
      continue;
    if (hdr->cmsg_type == SCM_RIGHTS) {
      const unsigned len = hdr->cmsg_len -
          (((uint8_t*)CMSG_DATA(hdr)) - (uint8_t*)hdr);
      ASSERT_EQ(len, sizeof(int));
      signal_fd = *((int *) CMSG_DATA(hdr));
    } else if (hdr->cmsg_type == SCM_CREDENTIALS) {
      const struct ucred *cred =
          reinterpret_cast<struct ucred*>(CMSG_DATA(hdr));
      crashing_pid = cred->pid;
    }
  }

  ASSERT_NE(crashing_pid, -1);
  ASSERT_NE(signal_fd, -1);

  char templ[] = "/tmp/exception-handler-unittest-XXXXXX";
  mktemp(templ);
  ASSERT_TRUE(WriteMinidump(templ, crashing_pid, context,
                            kCrashContextSize));
  static const char b = 0;
  HANDLE_EINTR(write(signal_fd, &b, 1));

  int status;
  ASSERT_NE(HANDLE_EINTR(waitpid(child, &status, 0)), -1);
  ASSERT_TRUE(WIFSIGNALED(status));
  ASSERT_EQ(WTERMSIG(status), SIGSEGV);

  struct stat st;
  ASSERT_EQ(stat(templ, &st), 0);
  ASSERT_GT(st.st_size, 0u);
  unlink(templ);
}
<commit_msg>Add a free() to ExceptionHandlerTest.ChildCrash. Review URL: http://breakpad.appspot.com/193001<commit_after>// Copyright (c) 2010 Google 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 Google Inc. 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.

#include <string>

#include <stdint.h>
#include <unistd.h>
#include <signal.h>
#include <sys/poll.h>
#include <sys/socket.h>
#include <sys/uio.h>

#include "breakpad_googletest_includes.h"
#include "client/linux/handler/exception_handler.h"
#include "client/linux/minidump_writer/minidump_writer.h"
#include "common/linux/eintr_wrapper.h"
#include "common/linux/linux_libc_support.h"
#include "third_party/lss/linux_syscall_support.h"

using namespace google_breakpad;

static void sigchld_handler(int signo) { }

class ExceptionHandlerTest : public ::testing::Test {
 protected:
  void SetUp() {
    // We need to be able to wait for children, so SIGCHLD cannot be SIG_IGN.
    struct sigaction sa;
    memset(&sa, 0, sizeof(sa));
    sa.sa_handler = sigchld_handler;
    ASSERT_NE(sigaction(SIGCHLD, &sa, &old_action), -1);
  }

  void TearDown() {
    sigaction(SIGCHLD, &old_action, NULL);
  }

  struct sigaction old_action;
};

TEST(ExceptionHandlerTest, Simple) {
  ExceptionHandler handler("/tmp", NULL, NULL, NULL, true);
}

static bool DoneCallback(const char* dump_path,
                         const char* minidump_id,
                         void* context,
                         bool succeeded) {
  if (!succeeded)
    return succeeded;

  int fd = (intptr_t) context;
  uint32_t len = my_strlen(minidump_id);
  HANDLE_EINTR(sys_write(fd, &len, sizeof(len)));
  HANDLE_EINTR(sys_write(fd, minidump_id, len));
  sys_close(fd);

  return true;
}

TEST(ExceptionHandlerTest, ChildCrash) {
  int fds[2];
  ASSERT_NE(pipe(fds), -1);

  const pid_t child = fork();
  if (child == 0) {
    close(fds[0]);
    ExceptionHandler handler("/tmp", NULL, DoneCallback, (void*) fds[1],
                             true);
    *reinterpret_cast<int*>(NULL) = 0;
  }
  close(fds[1]);

  int status;
  ASSERT_NE(HANDLE_EINTR(waitpid(child, &status, 0)), -1);
  ASSERT_TRUE(WIFSIGNALED(status));
  ASSERT_EQ(WTERMSIG(status), SIGSEGV);

  struct pollfd pfd;
  memset(&pfd, 0, sizeof(pfd));
  pfd.fd = fds[0];
  pfd.events = POLLIN | POLLERR;

  const int r = HANDLE_EINTR(poll(&pfd, 1, 0));
  ASSERT_EQ(r, 1);
  ASSERT_TRUE(pfd.revents & POLLIN);

  uint32_t len;
  ASSERT_EQ(read(fds[0], &len, sizeof(len)), (ssize_t)sizeof(len));
  ASSERT_LT(len, (uint32_t)2048);
  char* filename = reinterpret_cast<char*>(malloc(len + 1));
  ASSERT_EQ(read(fds[0], filename, len), len);
  filename[len] = 0;
  close(fds[0]);

  const std::string minidump_filename = std::string("/tmp/") + filename +
                                        ".dmp";

  struct stat st;
  ASSERT_EQ(stat(minidump_filename.c_str(), &st), 0);
  ASSERT_GT(st.st_size, 0u);
  unlink(minidump_filename.c_str());
  free(filename);
}

static const unsigned kControlMsgSize =
    CMSG_SPACE(sizeof(int)) + CMSG_SPACE(sizeof(struct ucred));

static bool
CrashHandler(const void* crash_context, size_t crash_context_size,
             void* context) {
  const int fd = (intptr_t) context;
  int fds[2];
  pipe(fds);
  struct kernel_msghdr msg = {0};
  struct kernel_iovec iov;
  iov.iov_base = const_cast<void*>(crash_context);
  iov.iov_len = crash_context_size;
  msg.msg_iov = &iov;
  msg.msg_iovlen = 1;
  char cmsg[kControlMsgSize];
  memset(cmsg, 0, kControlMsgSize);
  msg.msg_control = cmsg;
  msg.msg_controllen = sizeof(cmsg);

  struct cmsghdr *hdr = CMSG_FIRSTHDR(&msg);
  hdr->cmsg_level = SOL_SOCKET;
  hdr->cmsg_type = SCM_RIGHTS;
  hdr->cmsg_len = CMSG_LEN(sizeof(int));
  *((int*) CMSG_DATA(hdr)) = fds[1];
  hdr = CMSG_NXTHDR((struct msghdr*) &msg, hdr);
  hdr->cmsg_level = SOL_SOCKET;
  hdr->cmsg_type = SCM_CREDENTIALS;
  hdr->cmsg_len = CMSG_LEN(sizeof(struct ucred));
  struct ucred *cred = reinterpret_cast<struct ucred*>(CMSG_DATA(hdr));
  cred->uid = getuid();
  cred->gid = getgid();
  cred->pid = getpid();

  HANDLE_EINTR(sys_sendmsg(fd, &msg, 0));
  sys_close(fds[1]);

  char b;
  HANDLE_EINTR(sys_read(fds[0], &b, 1));

  return true;
}

TEST(ExceptionHandlerTest, ExternalDumper) {
  int fds[2];
  ASSERT_NE(socketpair(AF_UNIX, SOCK_DGRAM, 0, fds), -1);
  static const int on = 1;
  setsockopt(fds[0], SOL_SOCKET, SO_PASSCRED, &on, sizeof(on));
  setsockopt(fds[1], SOL_SOCKET, SO_PASSCRED, &on, sizeof(on));

  const pid_t child = fork();
  if (child == 0) {
    close(fds[0]);
    ExceptionHandler handler("/tmp1", NULL, NULL, (void*) fds[1], true);
    handler.set_crash_handler(CrashHandler);
    *reinterpret_cast<int*>(NULL) = 0;
  }
  close(fds[1]);
  struct msghdr msg = {0};
  struct iovec iov;
  static const unsigned kCrashContextSize =
      sizeof(ExceptionHandler::CrashContext);
  char context[kCrashContextSize];
  char control[kControlMsgSize];
  iov.iov_base = context;
  iov.iov_len = kCrashContextSize;
  msg.msg_iov = &iov;
  msg.msg_iovlen = 1;
  msg.msg_control = control;
  msg.msg_controllen = kControlMsgSize;

  const ssize_t n = HANDLE_EINTR(recvmsg(fds[0], &msg, 0));
  ASSERT_EQ(n, kCrashContextSize);
  ASSERT_EQ(msg.msg_controllen, kControlMsgSize);
  ASSERT_EQ(msg.msg_flags, 0);

  pid_t crashing_pid = -1;
  int signal_fd = -1;
  for (struct cmsghdr *hdr = CMSG_FIRSTHDR(&msg); hdr;
       hdr = CMSG_NXTHDR(&msg, hdr)) {
    if (hdr->cmsg_level != SOL_SOCKET)
      continue;
    if (hdr->cmsg_type == SCM_RIGHTS) {
      const unsigned len = hdr->cmsg_len -
          (((uint8_t*)CMSG_DATA(hdr)) - (uint8_t*)hdr);
      ASSERT_EQ(len, sizeof(int));
      signal_fd = *((int *) CMSG_DATA(hdr));
    } else if (hdr->cmsg_type == SCM_CREDENTIALS) {
      const struct ucred *cred =
          reinterpret_cast<struct ucred*>(CMSG_DATA(hdr));
      crashing_pid = cred->pid;
    }
  }

  ASSERT_NE(crashing_pid, -1);
  ASSERT_NE(signal_fd, -1);

  char templ[] = "/tmp/exception-handler-unittest-XXXXXX";
  mktemp(templ);
  ASSERT_TRUE(WriteMinidump(templ, crashing_pid, context,
                            kCrashContextSize));
  static const char b = 0;
  HANDLE_EINTR(write(signal_fd, &b, 1));

  int status;
  ASSERT_NE(HANDLE_EINTR(waitpid(child, &status, 0)), -1);
  ASSERT_TRUE(WIFSIGNALED(status));
  ASSERT_EQ(WTERMSIG(status), SIGSEGV);

  struct stat st;
  ASSERT_EQ(stat(templ, &st), 0);
  ASSERT_GT(st.st_size, 0u);
  unlink(templ);
}
<|endoftext|>


<commit_before>/* -*-c++-*- VirtualPlanetBuilder - Copyright (C) 1998-2007 Robert Osfield
 *
 * This application is open source and may be redistributed and/or modified
 * freely and without restriction, both in commericial and non commericial applications,
 * as long as this copyright notice is maintained.
 *
 * This application 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.
*/

#include <osgDB/FileUtils>
#include <osgDB/ReadFile>
#include <osgDB/WriteFile>
#include <osgDB/Registry>
#include <osgDB/FileNameUtils>

#include <iostream>
#include <sstream>

#include <curl/curl.h>
#include <curl/types.h>

class ReaderWriterCURL : public osgDB::ReaderWriter
{
    public:

        static size_t StreamMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data)
        {
            size_t realsize = size * nmemb;
            std::ostream* buffer = (std::ostream*)data;

            buffer->write((const char*)ptr, realsize);

            return realsize;
        }

        ReaderWriterCURL()
        {
            _curl = curl_easy_init();

            curl_easy_setopt(_curl, CURLOPT_USERAGENT, "libcurl-agent/1.0");
            curl_easy_setopt(_curl, CURLOPT_WRITEFUNCTION, StreamMemoryCallback);
        }

        ~ReaderWriterCURL()
        {
            if (_curl) curl_easy_cleanup(_curl);

            _curl = 0;
        }

        virtual const char* className() const { return "HTTP Protocol Model Reader"; }

        virtual bool acceptsExtension(const std::string& extension) const
        {
            return osgDB::equalCaseInsensitive(extension,"curl");
        }

        enum ObjectType
        {
            OBJECT,
            ARCHIVE,
            IMAGE,
            HEIGHTFIELD,
            NODE
        };

        virtual ReadResult openArchive(const std::string& fileName,ArchiveStatus status, unsigned int , const Options* options) const
        {
            if (status!=READ) return ReadResult(ReadResult::FILE_NOT_HANDLED);
            else return readFile(ARCHIVE,fileName,options);
        }

        virtual ReadResult readObject(const std::string& fileName, const Options* options) const
        {
            return readFile(OBJECT,fileName,options);
        }

        virtual ReadResult readImage(const std::string& fileName, const Options *options) const
        {
            return readFile(IMAGE,fileName,options);
        }

        virtual ReadResult readHeightField(const std::string& fileName, const Options *options) const
        {
            return readFile(HEIGHTFIELD,fileName,options);
        }

        virtual ReadResult readNode(const std::string& fileName, const Options *options) const
        {
            return readFile(NODE,fileName,options);
        }

        ReadResult readFile(ObjectType objectType, osgDB::ReaderWriter* rw, std::istream& fin, const Options *options) const
        {
            switch(objectType)
            {
            case(OBJECT): return rw->readObject(fin,options);
            case(ARCHIVE): return rw->openArchive(fin,options);
            case(IMAGE): return rw->readImage(fin,options);
            case(HEIGHTFIELD): return rw->readHeightField(fin,options);
            case(NODE): return rw->readNode(fin,options);
            default: break;
            }
            return ReadResult::FILE_NOT_HANDLED;
        }

        virtual ReadResult readFile(ObjectType objectType, const std::string& fullFileName, const Options *options) const
        {
            std::string cacheFilePath, cacheFileName;
            std::string proxyAddress, optProxy, optProxyPort;

            if (options)
            {
                std::istringstream iss(options->getOptionString());
                std::string opt;
                while (iss >> opt)
                {
                    int index = opt.find( "=" );
                    if( opt.substr( 0, index ) == "OSG_FILE_CACHE" )
                        cacheFilePath = opt.substr( index+1 ); //Setting Cache Directory by OSG Options
                    else if( opt.substr( 0, index ) == "OSG_CURL_PROXY" )
                        optProxy = opt.substr( index+1 );
                    else if( opt.substr( 0, index ) == "OSG_CURL_PROXYPORT" )
                        optProxyPort = opt.substr( index+1 );
                }

                //Setting Proxy by OSG Options
                if(!optProxy.empty())
                    if(!optProxyPort.empty())
                        proxyAddress = optProxy + ":" + optProxyPort;
                    else
                        proxyAddress = optProxy + ":8080"; //Port not found, using default
            }

            if (!osgDB::containsServerAddress(fullFileName))
            {
                if (options && !(options->getDatabasePathList().empty()))
                {
                    if (osgDB::containsServerAddress(options->getDatabasePathList().front()))
                    {
                        std::string newFileName = options->getDatabasePathList().front() + "/" + fullFileName;

                        return readFile(objectType, newFileName,options);
                    }
                }

                return ReadResult::FILE_NOT_HANDLED;
            }

            std::string fileName;
            std::string ext = osgDB::getFileExtension(fullFileName);
            if (ext=="curl")
            {
                fileName = osgDB::getNameLessExtension(fullFileName);
            }
            else
            {
                fileName = fullFileName;
            }

            osgDB::ReaderWriter *reader =
                osgDB::Registry::instance()->getReaderWriterForExtension( osgDB::getFileExtension(fileName));

            if (!reader)
            {
                osg::notify(osg::NOTICE)<<"Error: No ReaderWriter for file "<<fileName<<std::endl;
                return ReadResult::FILE_NOT_HANDLED;
            }

            //Getting CURL Environment Variables (If found rewrite OSG Options)
            const char* fileCachePath = getenv("OSG_FILE_CACHE");
            if (fileCachePath) //Env Cache Directory
                cacheFilePath = std::string(fileCachePath);

            if (!cacheFilePath.empty())
            {
                cacheFileName = cacheFilePath + "/" +
                                osgDB::getServerAddress(fileName) + "/" +
                                osgDB::getServerFileName(fileName);
            }

            if (!cacheFilePath.empty() && osgDB::fileExists(cacheFileName))
            {
                osg::notify(osg::NOTICE) << "Reading cache file " << cacheFileName << std::endl;
                return osgDB::Registry::instance()->readObject(cacheFileName,options);
            }

            const char* proxyEnvAddress = getenv("OSG_CURL_PROXY");
            if (proxyEnvAddress) //Env Proxy Settings
            {
                const char* proxyEnvPort = getenv("OSG_CURL_PROXYPORT"); //Searching Proxy Port on Env

                if(proxyEnvPort)
                    proxyAddress = std::string(proxyEnvAddress) + ":" + std::string(proxyEnvPort);
                else
                    proxyAddress = std::string(proxyEnvAddress) + ":8080"; //Default
            }

            if(!proxyAddress.empty())
            {
                osg::notify(osg::NOTICE)<<"Setting proxy: "<<proxyAddress<<std::endl;
                curl_easy_setopt(_curl, CURLOPT_PROXY, proxyAddress.c_str()); //Sets proxy address and port on libcurl
            }

            std::stringstream buffer;

            curl_easy_setopt(_curl, CURLOPT_URL, fileName.c_str());
            curl_easy_setopt(_curl, CURLOPT_WRITEDATA, (void *)&buffer);

            CURLcode res = curl_easy_perform(_curl);

            curl_easy_setopt(_curl, CURLOPT_WRITEDATA, (void *)0);

            if (res==0)
            {

                osg::ref_ptr<Options> local_opt = const_cast<Options*>(options);
                if (!local_opt) local_opt = new Options;

                local_opt->getDatabasePathList().push_front(osgDB::getFilePath(fileName));

                ReadResult readResult = readFile(objectType, reader, buffer, local_opt.get() );

                local_opt->getDatabasePathList().pop_front();

                if (!cacheFilePath.empty() && readResult.validObject())
                {
                    osg::notify(osg::NOTICE)<<"Writing cache file "<<cacheFileName<<std::endl;

                    std::string filePath = osgDB::getFilePath(cacheFileName);
                    if (!osgDB::fileExists(filePath))
                    {
                        osg::notify(osg::NOTICE)<<"Creating directory "<<filePath<<std::endl;
                        if (osgDB::makeDirectory(filePath))
                        {
                            osg::notify(osg::NOTICE)<<"   Created directory"<<std::endl;
                        }
                        else
                        {
                            osg::notify(osg::NOTICE)<<"   Failed"<<std::endl;
                        }
                    }

                    switch(objectType)
                    {
                    case(OBJECT): osgDB::writeObjectFile( *(readResult.getObject()), cacheFileName ); break;
                    case(IMAGE): osgDB::writeImageFile( *(readResult.getImage()), cacheFileName ); break;
                    case(HEIGHTFIELD): osgDB::writeHeightFieldFile( *(readResult.getHeightField()), cacheFileName ); break;
                    case(NODE): osgDB::writeNodeFile( *(readResult.getNode()), cacheFileName ); break;
                    default: break;
                    }

                }

                return readResult;
            }
            else
            {
                osg::notify(osg::NOTICE)<<"Error: libcurl read error, file="<<fileName<<" result = "<<res<<std::endl;
                return ReadResult::FILE_NOT_HANDLED;
            }
        }

    protected:

        CURL* _curl;

};

// now register with Registry to instantiate the above
// reader/writer.
REGISTER_OSGPLUGIN(rgb, ReaderWriterCURL)
<commit_msg>Improved the error capture and reporting<commit_after>/* -*-c++-*- VirtualPlanetBuilder - Copyright (C) 1998-2007 Robert Osfield
 *
 * This application is open source and may be redistributed and/or modified
 * freely and without restriction, both in commericial and non commericial applications,
 * as long as this copyright notice is maintained.
 *
 * This application 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.
*/

#include <osgDB/FileUtils>
#include <osgDB/ReadFile>
#include <osgDB/WriteFile>
#include <osgDB/Registry>
#include <osgDB/FileNameUtils>

#include <iostream>
#include <sstream>

#include <curl/curl.h>
#include <curl/types.h>

class ReaderWriterCURL : public osgDB::ReaderWriter
{
    public:

        static size_t StreamMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data)
        {
            size_t realsize = size * nmemb;
            std::ostream* buffer = (std::ostream*)data;

            buffer->write((const char*)ptr, realsize);

            return realsize;
        }

        ReaderWriterCURL()
        {
            _curl = curl_easy_init();

            curl_easy_setopt(_curl, CURLOPT_USERAGENT, "libcurl-agent/1.0");
            curl_easy_setopt(_curl, CURLOPT_WRITEFUNCTION, StreamMemoryCallback);
        }

        ~ReaderWriterCURL()
        {
            if (_curl) curl_easy_cleanup(_curl);

            _curl = 0;
        }

        virtual const char* className() const { return "HTTP Protocol Model Reader"; }

        virtual bool acceptsExtension(const std::string& extension) const
        {
            return osgDB::equalCaseInsensitive(extension,"curl");
        }

        enum ObjectType
        {
            OBJECT,
            ARCHIVE,
            IMAGE,
            HEIGHTFIELD,
            NODE
        };

        virtual ReadResult openArchive(const std::string& fileName,ArchiveStatus status, unsigned int , const Options* options) const
        {
            if (status!=READ) return ReadResult(ReadResult::FILE_NOT_HANDLED);
            else return readFile(ARCHIVE,fileName,options);
        }

        virtual ReadResult readObject(const std::string& fileName, const Options* options) const
        {
            return readFile(OBJECT,fileName,options);
        }

        virtual ReadResult readImage(const std::string& fileName, const Options *options) const
        {
            return readFile(IMAGE,fileName,options);
        }

        virtual ReadResult readHeightField(const std::string& fileName, const Options *options) const
        {
            return readFile(HEIGHTFIELD,fileName,options);
        }

        virtual ReadResult readNode(const std::string& fileName, const Options *options) const
        {
            return readFile(NODE,fileName,options);
        }

        ReadResult readFile(ObjectType objectType, osgDB::ReaderWriter* rw, std::istream& fin, const Options *options) const
        {
            switch(objectType)
            {
            case(OBJECT): return rw->readObject(fin,options);
            case(ARCHIVE): return rw->openArchive(fin,options);
            case(IMAGE): return rw->readImage(fin,options);
            case(HEIGHTFIELD): return rw->readHeightField(fin,options);
            case(NODE): return rw->readNode(fin,options);
            default: break;
            }
            return ReadResult::FILE_NOT_HANDLED;
        }

        virtual ReadResult readFile(ObjectType objectType, const std::string& fullFileName, const Options *options) const
        {
            std::string cacheFilePath, cacheFileName;
            std::string proxyAddress, optProxy, optProxyPort;

            if (options)
            {
                std::istringstream iss(options->getOptionString());
                std::string opt;
                while (iss >> opt)
                {
                    int index = opt.find( "=" );
                    if( opt.substr( 0, index ) == "OSG_FILE_CACHE" )
                        cacheFilePath = opt.substr( index+1 ); //Setting Cache Directory by OSG Options
                    else if( opt.substr( 0, index ) == "OSG_CURL_PROXY" )
                        optProxy = opt.substr( index+1 );
                    else if( opt.substr( 0, index ) == "OSG_CURL_PROXYPORT" )
                        optProxyPort = opt.substr( index+1 );
                }

                //Setting Proxy by OSG Options
                if(!optProxy.empty())
                    if(!optProxyPort.empty())
                        proxyAddress = optProxy + ":" + optProxyPort;
                    else
                        proxyAddress = optProxy + ":8080"; //Port not found, using default
            }

            if (!osgDB::containsServerAddress(fullFileName))
            {
                if (options && !(options->getDatabasePathList().empty()))
                {
                    if (osgDB::containsServerAddress(options->getDatabasePathList().front()))
                    {
                        std::string newFileName = options->getDatabasePathList().front() + "/" + fullFileName;

                        return readFile(objectType, newFileName,options);
                    }
                }

                return ReadResult::FILE_NOT_HANDLED;
            }

            std::string fileName;
            std::string ext = osgDB::getFileExtension(fullFileName);
            if (ext=="curl")
            {
                fileName = osgDB::getNameLessExtension(fullFileName);
            }
            else
            {
                fileName = fullFileName;
            }

            osgDB::ReaderWriter *reader =
                osgDB::Registry::instance()->getReaderWriterForExtension( osgDB::getFileExtension(fileName));

            if (!reader)
            {
                osg::notify(osg::NOTICE)<<"Error: No ReaderWriter for file "<<fileName<<std::endl;
                return ReadResult::FILE_NOT_HANDLED;
            }

            //Getting CURL Environment Variables (If found rewrite OSG Options)
            const char* fileCachePath = getenv("OSG_FILE_CACHE");
            if (fileCachePath) //Env Cache Directory
                cacheFilePath = std::string(fileCachePath);

            if (!cacheFilePath.empty())
            {
                cacheFileName = cacheFilePath + "/" +
                                osgDB::getServerAddress(fileName) + "/" +
                                osgDB::getServerFileName(fileName);
            }

            if (!cacheFilePath.empty() && osgDB::fileExists(cacheFileName))
            {
                osg::notify(osg::INFO) << "Reading cache file " << cacheFileName << std::endl;
                ReadResult result = osgDB::Registry::instance()->readObject(cacheFileName,options);
                return result;
            }

            const char* proxyEnvAddress = getenv("OSG_CURL_PROXY");
            if (proxyEnvAddress) //Env Proxy Settings
            {
                const char* proxyEnvPort = getenv("OSG_CURL_PROXYPORT"); //Searching Proxy Port on Env

                if(proxyEnvPort)
                    proxyAddress = std::string(proxyEnvAddress) + ":" + std::string(proxyEnvPort);
                else
                    proxyAddress = std::string(proxyEnvAddress) + ":8080"; //Default
            }

            if(!proxyAddress.empty())
            {
                osg::notify(osg::NOTICE)<<"Setting proxy: "<<proxyAddress<<std::endl;
                curl_easy_setopt(_curl, CURLOPT_PROXY, proxyAddress.c_str()); //Sets proxy address and port on libcurl
            }

            std::stringstream buffer;

            curl_easy_setopt(_curl, CURLOPT_URL, fileName.c_str());
            curl_easy_setopt(_curl, CURLOPT_WRITEDATA, (void *)&buffer);

            CURLcode res = curl_easy_perform(_curl);

            curl_easy_setopt(_curl, CURLOPT_WRITEDATA, (void *)0);

            if (res==0)
            {
                long code;
                if(!proxyAddress.empty())
                {
                    curl_easy_getinfo(_curl, CURLINFO_HTTP_CONNECTCODE, &code);
                }
                else
                {
                    curl_easy_getinfo(_curl, CURLINFO_RESPONSE_CODE, &code);
                }

                if (code>=400)
                {
                    osg::notify(osg::NOTICE)<<"Error: libcurl read error, file="<<fileName<<", error code = "<<code<<std::endl;
                    return ReadResult::FILE_NOT_FOUND;
                }

                osg::ref_ptr<Options> local_opt = const_cast<Options*>(options);
                if (!local_opt) local_opt = new Options;

                local_opt->getDatabasePathList().push_front(osgDB::getFilePath(fileName));

                ReadResult readResult = readFile(objectType, reader, buffer, local_opt.get() );

                local_opt->getDatabasePathList().pop_front();

                if (!cacheFilePath.empty() && readResult.validObject())
                {
                    osg::notify(osg::INFO)<<"Writing cache file "<<cacheFileName<<std::endl;

                    std::string filePath = osgDB::getFilePath(cacheFileName);
                    if (osgDB::fileExists(filePath) || osgDB::makeDirectory(filePath))
                    {
                        switch(objectType)
                        {
                        case(OBJECT): osgDB::writeObjectFile( *(readResult.getObject()), cacheFileName ); break;
                        case(IMAGE): osgDB::writeImageFile( *(readResult.getImage()), cacheFileName ); break;
                        case(HEIGHTFIELD): osgDB::writeHeightFieldFile( *(readResult.getHeightField()), cacheFileName ); break;
                        case(NODE): osgDB::writeNodeFile( *(readResult.getNode()), cacheFileName ); break;
                        default: break;
                        }
                    }
                    else
                    {
                        osg::notify(osg::NOTICE)<<"Error: Failed to created directory "<<filePath<<std::endl;
                    }

                }

                return readResult;
            }
            else
            {
                osg::notify(osg::NOTICE)<<"Error: libcurl read error, file="<<fileName<<" error = "<<curl_easy_strerror(res)<<std::endl;
                return ReadResult::FILE_NOT_HANDLED;
            }
        }

    protected:

        CURL* _curl;

};

// now register with Registry to instantiate the above
// reader/writer.
REGISTER_OSGPLUGIN(rgb, ReaderWriterCURL)
<|endoftext|>


<commit_before>// This Source Code Form is licensed MPL-2.0: http://mozilla.org/MPL/2.0

#include <websocketpp/config/asio_no_tls.hpp>
#include <websocketpp/server.hpp>
typedef websocketpp::server<websocketpp::config::asio> server;

#include <jsonipc/jsonipc.hh>

#include <bse/bse.hh>
#include <bse/platform.hh>
#include <bse/regex.hh>

#undef B0 // pollution from termios.h

static Bse::ServerH bse_server;
static const bool verbose = false;

// Configure websocket server
struct CustomServerConfig : public websocketpp::config::asio {
  static const size_t connection_read_buffer_size = 16384;
};
using ServerEndpoint = websocketpp::server<CustomServerConfig>;
static ServerEndpoint websocket_server;

static std::string
handle_jsonipc (const std::string &message, const websocketpp::connection_hdl &hdl)
{
  static Jsonipc::IpcDispatcher jd;
  const ptrdiff_t conid = ptrdiff_t (websocket_server.get_con_from_hdl (hdl).get());
  if (verbose)
    Bse::printerr ("%p: REQUEST: %s\n", conid, message);
  const std::string reply = jd.dispatch_message (message);
  if (verbose)
    Bse::printerr ("%p: REPLY:   %s\n", conid, reply);
  return reply;
}

static std::string
user_agent_nick (const std::string &useragent)
{
  using namespace Bse;
  std::string nick;
  if      (Re::search (R"(\bFirefox/)", useragent))
    nick += "Firefox";
  else if (Re::search (R"(\bElectron/)", useragent))
    nick += "Electron";
  else if (Re::search (R"(\bChrome/)", useragent))
    nick += "Chrome";
  else if (Re::search (R"(\bSafari/)", useragent))
    nick += "Safari";
  else
    nick += "Unknown";
  return nick;
}

static bool
ws_open_connection (websocketpp::connection_hdl hdl)
{
  ServerEndpoint::connection_ptr con = websocket_server.get_con_from_hdl (hdl);
  // https://github.com/zaphoyd/websocketpp/issues/694#issuecomment-454623641
  const auto &socket = con->get_raw_socket();
  const auto &address = socket.remote_endpoint().address();
  const int rport = socket.remote_endpoint().port();
  const websocketpp::http::parser::request &rq = con->get_request();
  const websocketpp::http::parser::header_list &headermap = rq.get_headers();
  std::string useragent;
  for (auto it : headermap) // request headers
    if (it.first == "User-Agent")
      useragent = it.second;
  std::string nick = user_agent_nick (useragent);
  if (!nick.empty())
    nick = "(" + nick + ")";
  using namespace Bse::AnsiColors;
  auto B1 = color (BOLD);
  auto B0 = color (BOLD_OFF);
  Bse::printout ("%p: %sACCEPT:%s %s:%d/ %s\n", ptrdiff_t (con.get()), B1, B0, address.to_string().c_str(), rport, nick);
  // Bse::printout ("User-Agent: %s\n", useragent);
  return true;
}

static void
ws_message (websocketpp::connection_hdl con, server::message_ptr msg)
{
  const std::string &message = msg->get_payload();
  // send message to BSE thread and block until its been handled
  Aida::ScopedSemaphore sem;
  auto handle_wsmsg = [&message, &con, &sem] () {
    std::string reply = handle_jsonipc (message, con);
    if (!reply.empty())
      websocket_server.send (con, reply, websocketpp::frame::opcode::text);
    sem.post();
  };
  bse_server.__iface_ptr__()->__execution_context_mt__().enqueue_mt (handle_wsmsg);
  sem.wait();
}

static void
print_usage (bool help)
{
  if (!help)
    {
      Bse::printout ("beast-sound-engine version %s\n", Bse::version());
      return;
    }
  Bse::printout ("Usage: beast-sound-engine [OPTIONS]\n");
  Bse::printout ("  --help     Print command line help\n");
  Bse::printout ("  --version  Print program version\n");
}

int
main (int argc, char *argv[])
{
  Bse::init_async (&argc, argv, argv[0]); // Bse::cstrings_to_vector (NULL)
  bse_server = Bse::init_server_instance();

  // parse arguments
  bool seen_dashdash = false;
  std::vector<std::string> words;
  for (size_t i = 0; i < argc; i++)
    if (!argv[i])
      continue;
    else if (argv[i][0] == '-' && argv[i][1] == '-' && argv[i][2] == 0)
      seen_dashdash = true;
    else if (!seen_dashdash && argv[i][0] == '-')
      {
        const char *arg = argv[i] + 1 + (argv[i][1] == '-');
        const char *eq = strchr (arg, '=');
        const std::string arg_name = !eq ? arg : std::string (arg, eq - arg);
        if (arg_name == "version")
          {
            print_usage (false);
            return 0;
          }
        else if (arg_name == "h" || arg_name == "help")
          {
            print_usage (true);
            return 0;
          }
        else
          {
            Bse::printerr ("%s: invalid argument: %s\n", argv[0], argv[i]);
            print_usage (true);
            return 1;
          }
      }
    else
      words.push_back (argv[i]);

  const int BEAST_AUDIO_ENGINE_PORT = 27239;    // 0x3ea67 % 32768

  // setup websocket and run asio loop
  websocket_server.set_open_handler (&ws_open_connection);
  websocket_server.set_message_handler (&ws_message);
  websocket_server.init_asio();
  websocket_server.clear_access_channels (websocketpp::log::alevel::all);
  websocket_server.set_reuse_addr (true);
  namespace IP = boost::asio::ip;
  IP::tcp::endpoint endpoint_local = IP::tcp::endpoint (IP::address::from_string ("127.0.0.1"), BEAST_AUDIO_ENGINE_PORT);
  websocket_server.listen (endpoint_local);
  websocket_server.start_accept();

  using namespace Bse::AnsiColors;
  auto B1 = color (BOLD);
  auto B0 = color (BOLD_OFF);
  Bse::printout ("%sLISTEN:%s ws://localhost:%d/\n", B1, B0, BEAST_AUDIO_ENGINE_PORT);

  websocket_server.run();

  return 0;
}
<commit_msg>BSE: beast-sound-engine: require (example) auth string for connections<commit_after>// This Source Code Form is licensed MPL-2.0: http://mozilla.org/MPL/2.0

#include <websocketpp/config/asio_no_tls.hpp>
#include <websocketpp/server.hpp>
typedef websocketpp::server<websocketpp::config::asio> server;

#include <jsonipc/jsonipc.hh>

#include <bse/bse.hh>
#include <bse/platform.hh>
#include <bse/regex.hh>

#undef B0 // pollution from termios.h

static Bse::ServerH bse_server;
static const bool verbose = false;

// Configure websocket server
struct CustomServerConfig : public websocketpp::config::asio {
  static const size_t connection_read_buffer_size = 16384;
};
using ServerEndpoint = websocketpp::server<CustomServerConfig>;
static ServerEndpoint websocket_server;

static std::string
handle_jsonipc (const std::string &message, const websocketpp::connection_hdl &hdl)
{
  static Jsonipc::IpcDispatcher jd;
  const ptrdiff_t conid = ptrdiff_t (websocket_server.get_con_from_hdl (hdl).get());
  if (verbose)
    Bse::printerr ("%p: REQUEST: %s\n", conid, message);
  const std::string reply = jd.dispatch_message (message);
  if (verbose)
    Bse::printerr ("%p: REPLY:   %s\n", conid, reply);
  return reply;
}

static std::string
user_agent_nick (const std::string &useragent)
{
  using namespace Bse;
  std::string nick;
  if      (Re::search (R"(\bFirefox/)", useragent))
    nick += "Firefox";
  else if (Re::search (R"(\bElectron/)", useragent))
    nick += "Electron";
  else if (Re::search (R"(\bChrome/)", useragent))
    nick += "Chrome";
  else if (Re::search (R"(\bSafari/)", useragent))
    nick += "Safari";
  else
    nick += "Unknown";
  return nick;
}

static bool
ws_validate_connection (websocketpp::connection_hdl hdl)
{
  ServerEndpoint::connection_ptr con = websocket_server.get_con_from_hdl (hdl);
  // using subprotocol as auth string
  const std::vector<std::string> &subprotocols = con->get_requested_subprotocols();
  if (subprotocols.size() == 1)
    {
      if (subprotocols[0] == "auth123")
        {
          con->select_subprotocol (subprotocols[0]);
          return true;
        }
    }
  return false;
}

static void
ws_open_connection (websocketpp::connection_hdl hdl)
{
  ServerEndpoint::connection_ptr con = websocket_server.get_con_from_hdl (hdl);
  // https://github.com/zaphoyd/websocketpp/issues/694#issuecomment-454623641
  const auto &socket = con->get_raw_socket();
  const auto &address = socket.remote_endpoint().address();
  const int rport = socket.remote_endpoint().port();
  const websocketpp::http::parser::request &rq = con->get_request();
  const websocketpp::http::parser::header_list &headermap = rq.get_headers();
  std::string useragent;
  for (auto it : headermap) // request headers
    if (it.first == "User-Agent")
      useragent = it.second;
  std::string nick = user_agent_nick (useragent);
  if (!nick.empty())
    nick = "(" + nick + ")";
  using namespace Bse::AnsiColors;
  auto B1 = color (BOLD);
  auto B0 = color (BOLD_OFF);
  Bse::printout ("%p: %sACCEPT:%s %s:%d/ %s\n", ptrdiff_t (con.get()), B1, B0, address.to_string().c_str(), rport, nick);
  // Bse::printout ("User-Agent: %s\n", useragent);
}

static void
ws_message (websocketpp::connection_hdl con, server::message_ptr msg)
{
  const std::string &message = msg->get_payload();
  // send message to BSE thread and block until its been handled
  Aida::ScopedSemaphore sem;
  auto handle_wsmsg = [&message, &con, &sem] () {
    std::string reply = handle_jsonipc (message, con);
    if (!reply.empty())
      websocket_server.send (con, reply, websocketpp::frame::opcode::text);
    sem.post();
  };
  bse_server.__iface_ptr__()->__execution_context_mt__().enqueue_mt (handle_wsmsg);
  sem.wait();
}

static void
print_usage (bool help)
{
  if (!help)
    {
      Bse::printout ("beast-sound-engine version %s\n", Bse::version());
      return;
    }
  Bse::printout ("Usage: beast-sound-engine [OPTIONS]\n");
  Bse::printout ("  --help     Print command line help\n");
  Bse::printout ("  --version  Print program version\n");
}

int
main (int argc, char *argv[])
{
  Bse::init_async (&argc, argv, argv[0]); // Bse::cstrings_to_vector (NULL)
  bse_server = Bse::init_server_instance();

  // parse arguments
  bool seen_dashdash = false;
  std::vector<std::string> words;
  for (size_t i = 0; i < argc; i++)
    if (!argv[i])
      continue;
    else if (argv[i][0] == '-' && argv[i][1] == '-' && argv[i][2] == 0)
      seen_dashdash = true;
    else if (!seen_dashdash && argv[i][0] == '-')
      {
        const char *arg = argv[i] + 1 + (argv[i][1] == '-');
        const char *eq = strchr (arg, '=');
        const std::string arg_name = !eq ? arg : std::string (arg, eq - arg);
        if (arg_name == "version")
          {
            print_usage (false);
            return 0;
          }
        else if (arg_name == "h" || arg_name == "help")
          {
            print_usage (true);
            return 0;
          }
        else
          {
            Bse::printerr ("%s: invalid argument: %s\n", argv[0], argv[i]);
            print_usage (true);
            return 1;
          }
      }
    else
      words.push_back (argv[i]);

  const int BEAST_AUDIO_ENGINE_PORT = 27239;    // 0x3ea67 % 32768

  // setup websocket and run asio loop
  websocket_server.set_validate_handler (&ws_validate_connection);
  websocket_server.set_open_handler (&ws_open_connection);
  websocket_server.set_message_handler (&ws_message);
  websocket_server.init_asio();
  websocket_server.clear_access_channels (websocketpp::log::alevel::all);
  websocket_server.set_reuse_addr (true);
  namespace IP = boost::asio::ip;
  IP::tcp::endpoint endpoint_local = IP::tcp::endpoint (IP::address::from_string ("127.0.0.1"), BEAST_AUDIO_ENGINE_PORT);
  websocket_server.listen (endpoint_local);
  websocket_server.start_accept();

  using namespace Bse::AnsiColors;
  auto B1 = color (BOLD);
  auto B0 = color (BOLD_OFF);
  Bse::printout ("%sLISTEN:%s ws://localhost:%d/\n", B1, B0, BEAST_AUDIO_ENGINE_PORT);

  websocket_server.run();

  return 0;
}
<|endoftext|>


<commit_before>#include "drake/systems/n_ary_system.h"

#include <memory>
#include <stdexcept>

#include <Eigen/Dense>
#include "gtest/gtest.h"

#include "drake/core/Vector.h"
#include "drake/systems/cascade_system.h"

namespace {

using Drake::NullVector;
using Drake::toEigen;
using drake::NAryState;
using drake::NArySystem;

// Vector-concept class for exercising composition.
template <typename ScalarType>
struct StateQ {
  static const int RowsAtCompileTime = Eigen::Dynamic;
  typedef Eigen::Matrix<ScalarType, RowsAtCompileTime, 1> EigenType;

  StateQ() {}

  template <typename Derived>
  explicit StateQ(const Eigen::MatrixBase<Derived>& initial)
      : v(initial) {}

  template <typename Derived>
  StateQ& operator=(const Eigen::MatrixBase<Derived>& rhs) {
    v = rhs;
  }

  friend EigenType toEigen(const StateQ<ScalarType>& s) {
    return s.v;
  }

  std::size_t size() const { return 2; }

  EigenType v;
};

using StateQD = StateQ<double>;

// System-concept class for exercising composition.
struct SystemQ {
  template <typename ScalarType>
  using StateVector = StateQ<ScalarType>;
  template <typename ScalarType>
  using InputVector = StateQ<ScalarType>;
  template <typename ScalarType>
  using OutputVector = StateQ<ScalarType>;

  SystemQ(const double dynamics_magic, const double output_magic) :
      dynamics_magic_(Eigen::Vector2d(dynamics_magic, 0.)),
      output_magic_(Eigen::Vector2d(output_magic, 0.)) {}

  template <typename ScalarType>
  StateVector<ScalarType> dynamics(const ScalarType& time,
                                   const StateVector<ScalarType>& state,
                                   const InputVector<ScalarType>& input) const {
    return StateVector<ScalarType>(state.v + input.v + dynamics_magic_.v);
  }

  template <typename ScalarType>
  OutputVector<ScalarType> output(const ScalarType& time,
                                  const StateVector<ScalarType>& state,
                                  const InputVector<ScalarType>& input) const {
    return OutputVector<ScalarType>(state.v + input.v + output_magic_.v);
  }

  bool isTimeVarying() const { return time_varying_; }

  bool isDirectFeedthrough() const { return feedthrough_; }

  const StateQ<double> dynamics_magic_;
  const StateQ<double> output_magic_;
  bool time_varying_ { false };
  bool feedthrough_ { false };
};

GTEST_TEST(TestNArySystem, BasicOperation) {
  std::shared_ptr<SystemQ> sq1 = std::make_shared<SystemQ>(10., 100.);
  std::shared_ptr<SystemQ> sq2 = std::make_shared<SystemQ>(20., 200.);

  NArySystem<SystemQ> dut;
  NAryState<StateQ<double> > state;
  NAryState<StateQ<double> > input;

  EXPECT_EQ(dut.isTimeVarying(), false);
  EXPECT_EQ(dut.isDirectFeedthrough(), false);
  EXPECT_EQ(dut.getNumStates(), 0);
  EXPECT_EQ(dut.getNumInputs(), 0);
  EXPECT_EQ(dut.getNumOutputs(), 0);
  EXPECT_EQ(dut.dynamics(0., state, input).count(), 0);
  EXPECT_EQ(dut.output(0., state, input).count(), 0);

  dut.AddSystem(sq1);
  EXPECT_EQ(dut.isTimeVarying(), false);
  EXPECT_EQ(dut.isDirectFeedthrough(), false);
  EXPECT_EQ(dut.getNumStates(), 2);
  EXPECT_EQ(dut.getNumInputs(), 2);
  EXPECT_EQ(dut.getNumOutputs(), 2);
  EXPECT_THROW(dut.dynamics(0., state, input), std::invalid_argument);
  EXPECT_THROW(dut.output(0., state, input), std::invalid_argument);
  StateQ<double> s1(Eigen::Vector2d(1., 0.));
  StateQ<double> i1(Eigen::Vector2d(5., 0.));
  state.Append(s1);
  input.Append(i1);
  EXPECT_EQ(dut.dynamics(0., state, input).count(), 1);
  EXPECT_EQ(dut.output(0., state, input).count(), 1);

  dut.AddSystem(sq2);
  EXPECT_EQ(dut.isTimeVarying(), false);
  EXPECT_EQ(dut.isDirectFeedthrough(), false);
  EXPECT_EQ(dut.getNumStates(), 4);
  EXPECT_EQ(dut.getNumInputs(), 4);
  EXPECT_EQ(dut.getNumOutputs(), 4);
  EXPECT_THROW(dut.dynamics(0., state, input), std::invalid_argument);
  EXPECT_THROW(dut.output(0., state, input), std::invalid_argument);
  StateQ<double> s2(Eigen::Vector2d(2., 0.));
  StateQ<double> i2(Eigen::Vector2d(6., 0.));
  state.Append(s2);
  input.Append(i2);
  EXPECT_EQ(dut.dynamics(0., state, input).count(), 2);
  EXPECT_EQ(dut.output(0., state, input).count(), 2);

  EXPECT_EQ(toEigen(dut.dynamics(0., state, input)),
            Eigen::Vector4d(10. + 1. + 5., 0.,
                            20. + 2. + 6., 0.));
  EXPECT_EQ(toEigen(dut.output(0., state, input)),
            Eigen::Vector4d(100. + 1. + 5., 0.,
                            200. + 2. + 6., 0.));

  sq2->time_varying_ = true;
  sq2->feedthrough_ = true;
  EXPECT_EQ(dut.isTimeVarying(), true);
  EXPECT_EQ(dut.isDirectFeedthrough(), true);
}

// Ensure that cascade() will compile.
GTEST_TEST(TestNArySystem, Cascade) {
  std::shared_ptr<SystemQ> sq1 = std::make_shared<SystemQ>(10., 100.);
  std::shared_ptr<SystemQ> sq2 = std::make_shared<SystemQ>(20., 200.);

  auto n1 = std::make_shared<NArySystem<SystemQ> >();
  auto n2 = std::make_shared<NArySystem<SystemQ> >();
  auto dut = Drake::cascade(n1, n2);
}

}  // namespace
<commit_msg>Avoid using any static-sized Eigen vectors, as they cause alignment explosions when compiling on MSVC-32.<commit_after>#include "drake/systems/n_ary_system.h"

#include <memory>
#include <stdexcept>

#include <Eigen/Dense>
#include "gtest/gtest.h"

#include "drake/core/Vector.h"
#include "drake/systems/cascade_system.h"

namespace {

using Drake::NullVector;
using Drake::toEigen;
using drake::NAryState;
using drake::NArySystem;

// Vector-concept class for exercising composition.
template <typename ScalarType>
struct StateQ {
  static const int RowsAtCompileTime = Eigen::Dynamic;
  typedef Eigen::Matrix<ScalarType, RowsAtCompileTime, 1> EigenType;

  StateQ() {}

  StateQ(const double a, const double b)
      : v((Eigen::VectorXd(2) << a, b).finished()) {}

  template <typename Derived>
  explicit StateQ(const Eigen::MatrixBase<Derived>& initial)
      : v(initial) {}

  template <typename Derived>
  StateQ& operator=(const Eigen::MatrixBase<Derived>& rhs) {
    v = rhs;
  }

  friend EigenType toEigen(const StateQ<ScalarType>& s) {
    return s.v;
  }

  std::size_t size() const { return 2; }

  EigenType v;
};

using StateQD = StateQ<double>;

// System-concept class for exercising composition.
struct SystemQ {
  template <typename ScalarType>
  using StateVector = StateQ<ScalarType>;
  template <typename ScalarType>
  using InputVector = StateQ<ScalarType>;
  template <typename ScalarType>
  using OutputVector = StateQ<ScalarType>;

  SystemQ(const double dynamics_magic, const double output_magic) :
      dynamics_magic_(dynamics_magic, 0.),
      output_magic_(output_magic, 0.) {}

  template <typename ScalarType>
  StateVector<ScalarType> dynamics(const ScalarType& time,
                                   const StateVector<ScalarType>& state,
                                   const InputVector<ScalarType>& input) const {
    return StateVector<ScalarType>(state.v + input.v + dynamics_magic_.v);
  }

  template <typename ScalarType>
  OutputVector<ScalarType> output(const ScalarType& time,
                                  const StateVector<ScalarType>& state,
                                  const InputVector<ScalarType>& input) const {
    return OutputVector<ScalarType>(state.v + input.v + output_magic_.v);
  }

  bool isTimeVarying() const { return time_varying_; }

  bool isDirectFeedthrough() const { return feedthrough_; }

  const StateQ<double> dynamics_magic_;
  const StateQ<double> output_magic_;
  bool time_varying_ { false };
  bool feedthrough_ { false };
};

// Conveniently makes a 4-d VectorXd.
Eigen::VectorXd Make4d(double c1, double c2, double c3, double c4) {
  return (Eigen::VectorXd(4) << c1, c2, c3, c4).finished();
}

GTEST_TEST(TestNArySystem, BasicOperation) {
  std::shared_ptr<SystemQ> sq1 = std::make_shared<SystemQ>(10., 100.);
  std::shared_ptr<SystemQ> sq2 = std::make_shared<SystemQ>(20., 200.);

  NArySystem<SystemQ> dut;
  NAryState<StateQ<double> > state;
  NAryState<StateQ<double> > input;

  EXPECT_EQ(dut.isTimeVarying(), false);
  EXPECT_EQ(dut.isDirectFeedthrough(), false);
  EXPECT_EQ(dut.getNumStates(), 0);
  EXPECT_EQ(dut.getNumInputs(), 0);
  EXPECT_EQ(dut.getNumOutputs(), 0);
  EXPECT_EQ(dut.dynamics(0., state, input).count(), 0);
  EXPECT_EQ(dut.output(0., state, input).count(), 0);

  dut.AddSystem(sq1);
  EXPECT_EQ(dut.isTimeVarying(), false);
  EXPECT_EQ(dut.isDirectFeedthrough(), false);
  EXPECT_EQ(dut.getNumStates(), 2);
  EXPECT_EQ(dut.getNumInputs(), 2);
  EXPECT_EQ(dut.getNumOutputs(), 2);
  EXPECT_THROW(dut.dynamics(0., state, input), std::invalid_argument);
  EXPECT_THROW(dut.output(0., state, input), std::invalid_argument);
  StateQ<double> s1(1., 0.);
  StateQ<double> i1(5., 0.);
  state.Append(s1);
  input.Append(i1);
  EXPECT_EQ(dut.dynamics(0., state, input).count(), 1);
  EXPECT_EQ(dut.output(0., state, input).count(), 1);

  dut.AddSystem(sq2);
  EXPECT_EQ(dut.isTimeVarying(), false);
  EXPECT_EQ(dut.isDirectFeedthrough(), false);
  EXPECT_EQ(dut.getNumStates(), 4);
  EXPECT_EQ(dut.getNumInputs(), 4);
  EXPECT_EQ(dut.getNumOutputs(), 4);
  EXPECT_THROW(dut.dynamics(0., state, input), std::invalid_argument);
  EXPECT_THROW(dut.output(0., state, input), std::invalid_argument);
  StateQ<double> s2(2., 0.);
  StateQ<double> i2(6., 0.);
  state.Append(s2);
  input.Append(i2);
  EXPECT_EQ(dut.dynamics(0., state, input).count(), 2);
  EXPECT_EQ(dut.output(0., state, input).count(), 2);

  EXPECT_EQ(toEigen(dut.dynamics(0., state, input)),
            Make4d(10. + 1. + 5., 0.,
                   20. + 2. + 6., 0.));
  EXPECT_EQ(toEigen(dut.output(0., state, input)),
            Make4d(100. + 1. + 5., 0.,
                   200. + 2. + 6., 0.));

  sq2->time_varying_ = true;
  sq2->feedthrough_ = true;
  EXPECT_EQ(dut.isTimeVarying(), true);
  EXPECT_EQ(dut.isDirectFeedthrough(), true);
}

// Ensure that cascade() will compile.
GTEST_TEST(TestNArySystem, Cascade) {
  std::shared_ptr<SystemQ> sq1 = std::make_shared<SystemQ>(10., 100.);
  std::shared_ptr<SystemQ> sq2 = std::make_shared<SystemQ>(20., 200.);

  auto n1 = std::make_shared<NArySystem<SystemQ> >();
  auto n2 = std::make_shared<NArySystem<SystemQ> >();
  auto dut = Drake::cascade(n1, n2);
}

}  // namespace
<|endoftext|>