<commit_before>/*
  +----------------------------------------------------------------------+
  | Swoole                                                               |
  +----------------------------------------------------------------------+
  | This source file is subject to version 2.0 of the Apache license,    |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.apache.org/licenses/LICENSE-2.0.html                      |
  | If you did not receive a copy of the Apache2.0 license and are unable|
  | to obtain it through the world-wide-web, please send a note to       |
  | license@swoole.com so we can mail you a copy immediately.            |
  +----------------------------------------------------------------------+
  | Author: Xinyu Zhu  <xyzhu1120@gmail.com>                             |
  |         shiguangqi <shiguangqi2008@gmail.com>                        |
  |         Tianfeng Han  <mikan.tenny@gmail.com>                        |
  +----------------------------------------------------------------------+
 */

#include "swoole_coroutine_scheduler.h"
#include "coroutine_c_api.h"

#include <queue>

using namespace std;
using swoole::coroutine::System;
using swoole::coroutine::Socket;
using swoole::Coroutine;
using swoole::PHPCoroutine;

struct scheduler_task_t
{
    zend_long count;
    zend_fcall_info fci;
    zend_fcall_info_cache fci_cache;
};

struct scheduler_t
{
    queue<scheduler_task_t*> *list;
    zend_object std;
};

static zend_class_entry *swoole_coroutine_scheduler_ce;
static zend_object_handlers swoole_coroutine_scheduler_handlers;

ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_void, 0, 0, 0)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_coroutine_scheduler_add, 0, 0, 1)
    ZEND_ARG_CALLABLE_INFO(0, func, 0)
    ZEND_ARG_VARIADIC_INFO(0, params)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_coroutine_scheduler_parallel, 0, 0, 1)
    ZEND_ARG_INFO(0, n)
    ZEND_ARG_CALLABLE_INFO(0, func, 0)
    ZEND_ARG_VARIADIC_INFO(0, params)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_coroutine_scheduler_set, 0, 0, 1)
    ZEND_ARG_ARRAY_INFO(0, settings, 0)
ZEND_END_ARG_INFO()

static PHP_METHOD(swoole_coroutine_scheduler, __construct);
static PHP_METHOD(swoole_coroutine_scheduler, add);
static PHP_METHOD(swoole_coroutine_scheduler, parallel);
static PHP_METHOD(swoole_coroutine_scheduler, start);

static sw_inline scheduler_t* scheduler_get_object(zend_object *obj)
{
    return (scheduler_t *) ((char *) obj - swoole_coroutine_scheduler_handlers.offset);
}

static zend_object *scheduler_create_object(zend_class_entry *ce)
{
    scheduler_t *s = (scheduler_t *) ecalloc(1, sizeof(scheduler_t) + zend_object_properties_size(ce));
    zend_object_std_init(&s->std, ce);
    object_properties_init(&s->std, ce);
    s->std.handlers = &swoole_coroutine_scheduler_handlers;
    return &s->std;
}

static void scheduler_free_object(zend_object *object)
{
    scheduler_t *s = scheduler_get_object(object);
    if (s->list)
    {
        while(!s->list->empty())
        {
            scheduler_task_t *task = s->list->front();
            s->list->pop();
            sw_zend_fci_cache_discard(&task->fci_cache);
            sw_zend_fci_params_discard(&task->fci);
            efree(task);
        }
        delete s->list;
        s->list = nullptr;
    }
    zend_object_std_dtor(&s->std);
}

static const zend_function_entry swoole_coroutine_scheduler_methods[] =
{
    PHP_ME(swoole_coroutine_scheduler, __construct, arginfo_swoole_void, ZEND_ACC_PUBLIC)
    PHP_ME(swoole_coroutine_scheduler, add, arginfo_swoole_coroutine_scheduler_add, ZEND_ACC_PUBLIC)
    PHP_ME(swoole_coroutine_scheduler, parallel, arginfo_swoole_coroutine_scheduler_parallel, ZEND_ACC_PUBLIC)
    PHP_ME(swoole_coroutine_scheduler, set, arginfo_swoole_coroutine_scheduler_set, ZEND_ACC_PUBLIC)
    PHP_ME(swoole_coroutine_scheduler, start, arginfo_swoole_void, ZEND_ACC_PUBLIC)
    PHP_FE_END
};

void swoole_coroutine_scheduler_init(int module_number)
{
    SW_INIT_CLASS_ENTRY(swoole_coroutine_scheduler, "Swoole\\Coroutine\\Scheduler", NULL, "Co\\Scheduler", swoole_coroutine_scheduler_methods);
    SW_SET_CLASS_SERIALIZABLE(swoole_coroutine_scheduler, zend_class_serialize_deny, zend_class_unserialize_deny);
    SW_SET_CLASS_CLONEABLE(swoole_coroutine_scheduler, sw_zend_class_clone_deny);
    SW_SET_CLASS_UNSET_PROPERTY_HANDLER(swoole_coroutine_scheduler, sw_zend_class_unset_property_deny);
    SW_SET_CLASS_CREATE_WITH_ITS_OWN_HANDLERS(swoole_coroutine_scheduler);
    SW_SET_CLASS_CUSTOM_OBJECT(swoole_coroutine_scheduler, scheduler_create_object, scheduler_free_object, scheduler_t, std);
    swoole_coroutine_scheduler_ce->ce_flags |= ZEND_ACC_FINAL;

    zend_declare_property_null(swoole_coroutine_scheduler_ce, ZEND_STRL("_list"), ZEND_ACC_PRIVATE);
}

PHP_METHOD(swoole_coroutine_scheduler, set)
{
    zval *zset = NULL;
    HashTable *vht = NULL;
    zval *ztmp;

    ZEND_PARSE_PARAMETERS_START(1, 1)
        Z_PARAM_ARRAY(zset)
    ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE);

    vht = Z_ARRVAL_P(zset);
    if (php_swoole_array_get_value(vht, "max_coroutine", ztmp))
    {
        zend_long max_num = zval_get_long(ztmp);
        PHPCoroutine::set_max_num(max_num <= 0 ? SW_DEFAULT_MAX_CORO_NUM : max_num);
    }
    /**
     * Runtime: hook php function
     */
    if (php_swoole_array_get_value(vht, "hook_flags", ztmp))
    {
        PHPCoroutine::enable_hook(zval_get_long(ztmp));
    }
    if (php_swoole_array_get_value(vht, "c_stack_size", ztmp) || php_swoole_array_get_value(vht, "stack_size", ztmp))
    {
        Coroutine::set_stack_size(zval_get_long(ztmp));
    }
    if (php_swoole_array_get_value(vht, "socket_connect_timeout", ztmp))
    {
        double t = zval_get_double(ztmp);
        if (t != 0) { Socket::default_connect_timeout = t; }
    }
    if (php_swoole_array_get_value(vht, "socket_timeout", ztmp))
    {
        double t = zval_get_double(ztmp);
        if (t != 0) { Socket::default_read_timeout = Socket::default_write_timeout = t; }
    }
    if (php_swoole_array_get_value(vht, "socket_read_timeout", ztmp))
    {
        double t = zval_get_double(ztmp);
        if (t != 0) { Socket::default_read_timeout = t; }
    }
    if (php_swoole_array_get_value(vht, "socket_write_timeout", ztmp))
    {
        double t = zval_get_double(ztmp);
        if (t != 0) { Socket::default_write_timeout = t; }
    }
    if (php_swoole_array_get_value(vht, "log_level", ztmp))
    {
        zend_long level = zval_get_long(ztmp);
        SwooleG.log_level = (uint32_t) (level < 0 ? UINT32_MAX : level);
    }
    if (php_swoole_array_get_value(vht, "trace_flags", ztmp))
    {
        SwooleG.trace_flags = (uint32_t) SW_MAX(0, zval_get_long(ztmp));
    }
    if (php_swoole_array_get_value(vht, "dns_cache_expire", ztmp))
    {
        System::set_dns_cache_expire((time_t) zval_get_long(ztmp));
    }
    if (php_swoole_array_get_value(vht, "dns_cache_capacity", ztmp))
    {
        System::set_dns_cache_capacity((size_t) zval_get_long(ztmp));
    }
    if (php_swoole_array_get_value(vht, "display_errors", ztmp))
    {
        SWOOLE_G(display_errors) = zval_is_true(ztmp);
    }
}

static void scheduler_add_task(scheduler_t *s, scheduler_task_t *task)
{
    if (!s->list)
    {
        s->list = new queue<scheduler_task_t*>;
    }
    sw_zend_fci_cache_persist(&task->fci_cache);
    sw_zend_fci_params_persist(&task->fci);
    s->list->push(task);
}

static PHP_METHOD(swoole_coroutine_scheduler, __construct)
{
    if (SwooleG.main_reactor)
    {
        zend_throw_exception_ex(swoole_exception_ce, -2, "eventLoop has already been created. unable to create %s", SW_Z_OBJCE_NAME_VAL_P(getThis()));
        RETURN_FALSE;
    }
    php_swoole_reactor_init();
}

static PHP_METHOD(swoole_coroutine_scheduler, add)
{
    scheduler_task_t *task = (scheduler_task_t *) ecalloc(1, sizeof(scheduler_task_t));

    ZEND_PARSE_PARAMETERS_START(1, -1)
        Z_PARAM_FUNC(task->fci, task->fci_cache)
        Z_PARAM_VARIADIC('*', task->fci.params, task->fci.param_count)
    ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE);

    task->count = 1;
    scheduler_add_task(scheduler_get_object(Z_OBJ_P(getThis())), task);
}

static PHP_METHOD(swoole_coroutine_scheduler, parallel)
{
    scheduler_task_t *task = (scheduler_task_t *) ecalloc(1, sizeof(scheduler_task_t));
    zend_long count;

    ZEND_PARSE_PARAMETERS_START(2, -1)
        Z_PARAM_LONG(count)
        Z_PARAM_FUNC(task->fci, task->fci_cache)
        Z_PARAM_VARIADIC('*', task->fci.params, task->fci.param_count)
    ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE);

    task->count = count;
    scheduler_add_task(scheduler_get_object(Z_OBJ_P(getThis())), task);
}

static PHP_METHOD(swoole_coroutine_scheduler, start)
{
    scheduler_t *s = scheduler_get_object(Z_OBJ_P(getThis()));
    while (!s->list->empty())
    {
        scheduler_task_t *task = s->list->front();
        s->list->pop();
        for (zend_long i = 0; i < task->count; i++)
        {
            PHPCoroutine::create(&task->fci_cache, task->fci.param_count, task->fci.params);
        }
        sw_zend_fci_cache_discard(&task->fci_cache);
        sw_zend_fci_params_discard(&task->fci);
        efree(task);
    }

    php_swoole_event_wait();
    delete s->list;
    s->list = nullptr;
}
<commit_msg>Scheduler reuse<commit_after>/*
  +----------------------------------------------------------------------+
  | Swoole                                                               |
  +----------------------------------------------------------------------+
  | This source file is subject to version 2.0 of the Apache license,    |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.apache.org/licenses/LICENSE-2.0.html                      |
  | If you did not receive a copy of the Apache2.0 license and are unable|
  | to obtain it through the world-wide-web, please send a note to       |
  | license@swoole.com so we can mail you a copy immediately.            |
  +----------------------------------------------------------------------+
  | Author: Xinyu Zhu  <xyzhu1120@gmail.com>                             |
  |         shiguangqi <shiguangqi2008@gmail.com>                        |
  |         Tianfeng Han  <mikan.tenny@gmail.com>                        |
  +----------------------------------------------------------------------+
 */

#include "swoole_coroutine_scheduler.h"
#include "coroutine_c_api.h"

#include <queue>

using namespace std;
using swoole::coroutine::System;
using swoole::coroutine::Socket;
using swoole::Coroutine;
using swoole::PHPCoroutine;

struct scheduler_task_t
{
    zend_long count;
    zend_fcall_info fci;
    zend_fcall_info_cache fci_cache;
};

struct scheduler_t
{
    queue<scheduler_task_t*> *list;
    bool started;
    zend_object std;
};

static zend_class_entry *swoole_coroutine_scheduler_ce;
static zend_object_handlers swoole_coroutine_scheduler_handlers;

ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_void, 0, 0, 0)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_coroutine_scheduler_add, 0, 0, 1)
    ZEND_ARG_CALLABLE_INFO(0, func, 0)
    ZEND_ARG_VARIADIC_INFO(0, params)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_coroutine_scheduler_parallel, 0, 0, 1)
    ZEND_ARG_INFO(0, n)
    ZEND_ARG_CALLABLE_INFO(0, func, 0)
    ZEND_ARG_VARIADIC_INFO(0, params)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_coroutine_scheduler_set, 0, 0, 1)
    ZEND_ARG_ARRAY_INFO(0, settings, 0)
ZEND_END_ARG_INFO()

static PHP_METHOD(swoole_coroutine_scheduler, add);
static PHP_METHOD(swoole_coroutine_scheduler, parallel);
static PHP_METHOD(swoole_coroutine_scheduler, start);

static sw_inline scheduler_t* scheduler_get_object(zend_object *obj)
{
    return (scheduler_t *) ((char *) obj - swoole_coroutine_scheduler_handlers.offset);
}

static zend_object *scheduler_create_object(zend_class_entry *ce)
{
    scheduler_t *s = (scheduler_t *) ecalloc(1, sizeof(scheduler_t) + zend_object_properties_size(ce));
    zend_object_std_init(&s->std, ce);
    object_properties_init(&s->std, ce);
    s->std.handlers = &swoole_coroutine_scheduler_handlers;
    return &s->std;
}

static void scheduler_free_object(zend_object *object)
{
    scheduler_t *s = scheduler_get_object(object);
    if (s->list)
    {
        while(!s->list->empty())
        {
            scheduler_task_t *task = s->list->front();
            s->list->pop();
            sw_zend_fci_cache_discard(&task->fci_cache);
            sw_zend_fci_params_discard(&task->fci);
            efree(task);
        }
        delete s->list;
        s->list = nullptr;
    }
    zend_object_std_dtor(&s->std);
}

static const zend_function_entry swoole_coroutine_scheduler_methods[] =
{
    PHP_ME(swoole_coroutine_scheduler, add, arginfo_swoole_coroutine_scheduler_add, ZEND_ACC_PUBLIC)
    PHP_ME(swoole_coroutine_scheduler, parallel, arginfo_swoole_coroutine_scheduler_parallel, ZEND_ACC_PUBLIC)
    PHP_ME(swoole_coroutine_scheduler, set, arginfo_swoole_coroutine_scheduler_set, ZEND_ACC_PUBLIC)
    PHP_ME(swoole_coroutine_scheduler, start, arginfo_swoole_void, ZEND_ACC_PUBLIC)
    PHP_FE_END
};

void swoole_coroutine_scheduler_init(int module_number)
{
    SW_INIT_CLASS_ENTRY(swoole_coroutine_scheduler, "Swoole\\Coroutine\\Scheduler", NULL, "Co\\Scheduler", swoole_coroutine_scheduler_methods);
    SW_SET_CLASS_SERIALIZABLE(swoole_coroutine_scheduler, zend_class_serialize_deny, zend_class_unserialize_deny);
    SW_SET_CLASS_CLONEABLE(swoole_coroutine_scheduler, sw_zend_class_clone_deny);
    SW_SET_CLASS_UNSET_PROPERTY_HANDLER(swoole_coroutine_scheduler, sw_zend_class_unset_property_deny);
    SW_SET_CLASS_CREATE_WITH_ITS_OWN_HANDLERS(swoole_coroutine_scheduler);
    SW_SET_CLASS_CUSTOM_OBJECT(swoole_coroutine_scheduler, scheduler_create_object, scheduler_free_object, scheduler_t, std);
    swoole_coroutine_scheduler_ce->ce_flags |= ZEND_ACC_FINAL;

    zend_declare_property_null(swoole_coroutine_scheduler_ce, ZEND_STRL("_list"), ZEND_ACC_PRIVATE);
}

PHP_METHOD(swoole_coroutine_scheduler, set)
{
    zval *zset = NULL;
    HashTable *vht = NULL;
    zval *ztmp;

    ZEND_PARSE_PARAMETERS_START(1, 1)
        Z_PARAM_ARRAY(zset)
    ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE);

    vht = Z_ARRVAL_P(zset);
    if (php_swoole_array_get_value(vht, "max_coroutine", ztmp))
    {
        zend_long max_num = zval_get_long(ztmp);
        PHPCoroutine::set_max_num(max_num <= 0 ? SW_DEFAULT_MAX_CORO_NUM : max_num);
    }
    /**
     * Runtime: hook php function
     */
    if (php_swoole_array_get_value(vht, "hook_flags", ztmp))
    {
        PHPCoroutine::enable_hook(zval_get_long(ztmp));
    }
    if (php_swoole_array_get_value(vht, "c_stack_size", ztmp) || php_swoole_array_get_value(vht, "stack_size", ztmp))
    {
        Coroutine::set_stack_size(zval_get_long(ztmp));
    }
    if (php_swoole_array_get_value(vht, "socket_connect_timeout", ztmp))
    {
        double t = zval_get_double(ztmp);
        if (t != 0) { Socket::default_connect_timeout = t; }
    }
    if (php_swoole_array_get_value(vht, "socket_timeout", ztmp))
    {
        double t = zval_get_double(ztmp);
        if (t != 0) { Socket::default_read_timeout = Socket::default_write_timeout = t; }
    }
    if (php_swoole_array_get_value(vht, "socket_read_timeout", ztmp))
    {
        double t = zval_get_double(ztmp);
        if (t != 0) { Socket::default_read_timeout = t; }
    }
    if (php_swoole_array_get_value(vht, "socket_write_timeout", ztmp))
    {
        double t = zval_get_double(ztmp);
        if (t != 0) { Socket::default_write_timeout = t; }
    }
    if (php_swoole_array_get_value(vht, "log_level", ztmp))
    {
        zend_long level = zval_get_long(ztmp);
        SwooleG.log_level = (uint32_t) (level < 0 ? UINT32_MAX : level);
    }
    if (php_swoole_array_get_value(vht, "trace_flags", ztmp))
    {
        SwooleG.trace_flags = (uint32_t) SW_MAX(0, zval_get_long(ztmp));
    }
    if (php_swoole_array_get_value(vht, "dns_cache_expire", ztmp))
    {
        System::set_dns_cache_expire((time_t) zval_get_long(ztmp));
    }
    if (php_swoole_array_get_value(vht, "dns_cache_capacity", ztmp))
    {
        System::set_dns_cache_capacity((size_t) zval_get_long(ztmp));
    }
    if (php_swoole_array_get_value(vht, "display_errors", ztmp))
    {
        SWOOLE_G(display_errors) = zval_is_true(ztmp);
    }
}

static void scheduler_add_task(scheduler_t *s, scheduler_task_t *task)
{
    if (!s->list)
    {
        s->list = new queue<scheduler_task_t*>;
    }
    sw_zend_fci_cache_persist(&task->fci_cache);
    sw_zend_fci_params_persist(&task->fci);
    s->list->push(task);
}

static PHP_METHOD(swoole_coroutine_scheduler, add)
{
    scheduler_t *s = scheduler_get_object(Z_OBJ_P(getThis()));
    if (s->started)
    {
        php_swoole_fatal_error(E_WARNING, "scheduler is running, unable to execute %s->add", SW_Z_OBJCE_NAME_VAL_P(getThis()));
        RETURN_FALSE;
    }

    scheduler_task_t *task = (scheduler_task_t *) ecalloc(1, sizeof(scheduler_task_t));

    ZEND_PARSE_PARAMETERS_START(1, -1)
        Z_PARAM_FUNC(task->fci, task->fci_cache)
        Z_PARAM_VARIADIC('*', task->fci.params, task->fci.param_count)
    ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE);

    task->count = 1;
    scheduler_add_task(s, task);
}

static PHP_METHOD(swoole_coroutine_scheduler, parallel)
{
    scheduler_t *s = scheduler_get_object(Z_OBJ_P(getThis()));
    if (s->started)
    {
        php_swoole_fatal_error(E_WARNING, "scheduler is running, unable to execute %s->parallel", SW_Z_OBJCE_NAME_VAL_P(getThis()));
        RETURN_FALSE;
    }

    scheduler_task_t *task = (scheduler_task_t *) ecalloc(1, sizeof(scheduler_task_t));
    zend_long count;

    ZEND_PARSE_PARAMETERS_START(2, -1)
        Z_PARAM_LONG(count)
        Z_PARAM_FUNC(task->fci, task->fci_cache)
        Z_PARAM_VARIADIC('*', task->fci.params, task->fci.param_count)
    ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE);

    task->count = count;
    scheduler_add_task(s, task);
}

static PHP_METHOD(swoole_coroutine_scheduler, start)
{
    scheduler_t *s = scheduler_get_object(Z_OBJ_P(getThis()));

    if (SwooleG.main_reactor)
    {
        zend_throw_exception_ex(swoole_exception_ce, -2, "eventLoop has already been created. unable to create %s", SW_Z_OBJCE_NAME_VAL_P(getThis()));
        RETURN_FALSE;
    }
    if (s->started)
    {
        php_swoole_fatal_error(E_WARNING, "scheduler is running, unable to execute %s->start", SW_Z_OBJCE_NAME_VAL_P(getThis()));
        RETURN_FALSE;
    }
    php_swoole_reactor_init();
    s->started = true;
    while (!s->list->empty())
    {
        scheduler_task_t *task = s->list->front();
        s->list->pop();
        for (zend_long i = 0; i < task->count; i++)
        {
            PHPCoroutine::create(&task->fci_cache, task->fci.param_count, task->fci.params);
        }
        sw_zend_fci_cache_discard(&task->fci_cache);
        sw_zend_fci_params_discard(&task->fci);
        efree(task);
    }
    php_swoole_event_wait();
    delete s->list;
    s->list = nullptr;
    s->started = false;
}
<|endoftext|>


<commit_before>/***************************************************************************
 *   Copyright (c) 2013 Jan Rheinlaender <jrheinlaender@users.sourceforge.net>        *
 *                                                                         *
 *   This file is part of the FreeCAD CAx development system.              *
 *                                                                         *
 *   This library is free software; you can redistribute it and/or         *
 *   modify it under the terms of the GNU Library General Public           *
 *   License as published by the Free Software Foundation; either          *
 *   version 2 of the License, or (at your option) any later version.      *
 *                                                                         *
 *   This library  is distributed in the hope that it will be useful,      *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU Library General Public License for more details.                  *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this library; see the file COPYING.LIB. If not,    *
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
 *   Suite 330, Boston, MA  02111-1307, USA                                *
 *                                                                         *
 ***************************************************************************/

#include "PreCompiled.h"

#ifndef _PreComp_
# include <QMessageBox>
# include <QAction>
# include <QMenu>
# include <Inventor/actions/SoGetBoundingBoxAction.h>
# include <Inventor/nodes/SoSeparator.h>
# include <Inventor/nodes/SoPickStyle.h>
# include <Inventor/nodes/SoShapeHints.h>
# include <Inventor/nodes/SoMaterial.h>
# include <Inventor/nodes/SoBaseColor.h>
# include <Inventor/nodes/SoTransparencyType.h>
# include <Inventor/nodes/SoDrawStyle.h>
# include <Inventor/nodes/SoMarkerSet.h>
# include <Inventor/nodes/SoVertexProperty.h>
# include <Inventor/nodes/SoLineSet.h>
# include <Inventor/nodes/SoFaceSet.h>
# include <Inventor/details/SoLineDetail.h>
# include <Inventor/details/SoFaceDetail.h>
# include <Inventor/details/SoPointDetail.h>
# include <TopoDS_Vertex.hxx>
# include <TopoDS.hxx>
# include <BRep_Tool.hxx>
# include <gp_Pnt.hxx>
# include <Precision.hxx>
# include <Geom_Plane.hxx>
# include <Geom_Line.hxx>
# include <GeomAPI_IntCS.hxx>
#endif

#include <App/DocumentObjectGroup.h>
#include <App/GeoFeatureGroupExtension.h>
#include <Gui/Control.h>
#include <Gui/Command.h>
#include <Gui/Application.h>
#include <Gui/MDIView.h>
#include <Gui/ViewProviderOrigin.h>
#include <Gui/View3DInventor.h>
#include <Gui/View3DInventorViewer.h>

#include <Mod/PartDesign/App/DatumPoint.h>
#include <Mod/PartDesign/App/DatumLine.h>
#include <Mod/PartDesign/App/DatumPlane.h>
#include <Mod/PartDesign/App/Body.h>
#include <Mod/PartDesign/App/DatumCS.h>

#include "TaskDatumParameters.h"
#include "ViewProviderBody.h"
#include "Utils.h"

#include "ViewProviderDatum.h"

using namespace PartDesignGui;

PROPERTY_SOURCE(PartDesignGui::ViewProviderDatum,Gui::ViewProviderGeometryObject)

// static data
const double ViewProviderDatum::defaultSize = Gui::ViewProviderOrigin::defaultSize ();

ViewProviderDatum::ViewProviderDatum()
{
    pShapeSep = new SoSeparator();
    pShapeSep->ref();
    pPickStyle = new SoPickStyle();
    pPickStyle->ref();

    DisplayMode.setStatus(App::Property::Hidden, true);

    // set default color for datums (golden yellow with 60% transparency)
    ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath (
            "User parameter:BaseApp/Preferences/Mod/PartDesign");
    unsigned long shcol = hGrp->GetUnsigned ( "DefaultDatumColor", 0xFFD70099 );

    App::Color col ( (uint32_t) shcol );
    ShapeColor.setValue ( col );

    Transparency.setValue (col.a * 100);

    oldWb = "";
    oldTip = NULL;
}

ViewProviderDatum::~ViewProviderDatum()
{
    pShapeSep->unref();
    pPickStyle->unref();
}

void ViewProviderDatum::attach(App::DocumentObject *obj)
{
    ViewProviderGeometryObject::attach ( obj );

    // TODO remove this field (2015-09-08, Fat-Zer)
    App::DocumentObject* o = getObject();
    if (o->getTypeId() == PartDesign::Plane::getClassTypeId())
        datumType = QObject::tr("Plane");
    else if (o->getTypeId() == PartDesign::Line::getClassTypeId())
        datumType = QObject::tr("Line");
    else if (o->getTypeId() == PartDesign::Point::getClassTypeId())
        datumType = QObject::tr("Point");
    else if (o->getTypeId() == PartDesign::CoordinateSystem::getClassTypeId())
        datumType = QObject::tr("CoordinateSystem");

    SoShapeHints* hints = new SoShapeHints();
    hints->shapeType.setValue(SoShapeHints::UNKNOWN_SHAPE_TYPE);
    hints->vertexOrdering.setValue(SoShapeHints::COUNTERCLOCKWISE);
    SoDrawStyle* fstyle = new SoDrawStyle();
    fstyle->style = SoDrawStyle::FILLED;
    fstyle->lineWidth = 3;
    fstyle->pointSize = 5;
    pPickStyle->style = SoPickStyle::SHAPE;
    SoMaterialBinding* matBinding = new SoMaterialBinding;
    matBinding->value = SoMaterialBinding::OVERALL;

    SoSeparator* sep = new SoSeparator();
    sep->addChild(hints);
    sep->addChild(fstyle);
    sep->addChild(pPickStyle);
    sep->addChild(matBinding);
    sep->addChild(pcShapeMaterial);
    sep->addChild(pShapeSep);

    addDisplayMaskMode(sep, "Base");
}

bool ViewProviderDatum::onDelete(const std::vector<std::string> &)
{
    // TODO: Ask user what to do about dependent objects, e.g. Sketches that have this feature as their support
    // 1. Delete
    // 2. Suppress
    // 3. Re-route

    return true;
}

std::vector<std::string> ViewProviderDatum::getDisplayModes(void) const
{
    return { "Base" };
}

void ViewProviderDatum::setDisplayMode(const char* ModeName)
{
    if (strcmp(ModeName, "Base") == 0)
        setDisplayMaskMode("Base");
    ViewProviderGeometryObject::setDisplayMode(ModeName);
}

std::string ViewProviderDatum::getElement(const SoDetail* detail) const
{
    if (detail) {
        int element = 1;

        if (detail->getTypeId() == SoLineDetail::getClassTypeId()) {
            const SoLineDetail* line_detail = static_cast<const SoLineDetail*>(detail);
            element = line_detail->getLineIndex();
        } else if (detail->getTypeId() == SoFaceDetail::getClassTypeId()) {
            const SoFaceDetail* face_detail = static_cast<const SoFaceDetail*>(detail);
            element = face_detail->getFaceIndex();
        } else if (detail->getTypeId() == SoPointDetail::getClassTypeId()) {
            const SoPointDetail* point_detail = static_cast<const SoPointDetail*>(detail);
            element = point_detail->getCoordinateIndex();
        }

        if (element == 0)
            return datumType.toStdString();
    }

    return std::string("");
}

SoDetail* ViewProviderDatum::getDetail(const char* subelement) const
{
    QString subelem = QString::fromLatin1(subelement);

    if (subelem == QObject::tr("Line")) {
         SoLineDetail* detail = new SoLineDetail();
         detail->setPartIndex(0);
         return detail;
    } else if (subelem == QObject::tr("Plane")) {
        SoFaceDetail* detail = new SoFaceDetail();
        detail->setPartIndex(0);
        return detail;
   } else if (subelem == QObject::tr("Point")) {
        SoPointDetail* detail = new SoPointDetail();
        detail->setCoordinateIndex(0);
        return detail;
   }

    return NULL;
}

bool ViewProviderDatum::isSelectable(void) const
{
    return true;
}

void ViewProviderDatum::setupContextMenu(QMenu* menu, QObject* receiver, const char* member)
{
    QAction* act;
    act = menu->addAction(QObject::tr("Edit datum ") + datumType, receiver, member);
    act->setData(QVariant((int)ViewProvider::Default));
}

bool ViewProviderDatum::setEdit(int ModNum)
{
    if (!ViewProvider::setEdit(ModNum))
        return false;
    // TODO Share this code with Features view providers somehow (2015-09-08, Fat-Zer)
    if (ModNum == ViewProvider::Default ) {
        // When double-clicking on the item for this datum feature the
        // object unsets and sets its edit mode without closing
        // the task panel
        Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog();
        TaskDlgDatumParameters *datumDlg = qobject_cast<TaskDlgDatumParameters *>(dlg);
        if (datumDlg && datumDlg->getViewProvider() != this)
            datumDlg = 0; // another datum feature left open its task panel
        if (dlg && !datumDlg) {
            QMessageBox msgBox;
            msgBox.setText(QObject::tr("A dialog is already open in the task panel"));
            msgBox.setInformativeText(QObject::tr("Do you want to close this dialog?"));
            msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
            msgBox.setDefaultButton(QMessageBox::Yes);
            int ret = msgBox.exec();
            if (ret == QMessageBox::Yes)
                Gui::Control().closeDialog();
            else
                return false;
        }

        // clear the selection (convenience)
        Gui::Selection().clearSelection();

        oldWb = Gui::Command::assureWorkbench("PartDesignWorkbench");

        // start the edit dialog
        if (datumDlg)
            Gui::Control().showDialog(datumDlg);
        else
            Gui::Control().showDialog(new TaskDlgDatumParameters(this));

        return true;
    }
    else {
        return ViewProvider::setEdit(ModNum);
    }
}

bool ViewProviderDatum::doubleClicked(void)
{
    std::string Msg("Edit ");
    Msg += this->pcObject->Label.getValue();
    Gui::Command::openCommand(Msg.c_str());

    Part::Datum* pcDatum = static_cast<Part::Datum*>(getObject());
    PartDesign::Body* activeBody = getActiveView()->getActiveObject<PartDesign::Body*>(PDBODYKEY);
    auto datumBody = PartDesignGui::getBodyFor(pcDatum, false);

    if (datumBody != NULL) {
        if (datumBody != activeBody) {
            Gui::Command::doCommand(Gui::Command::Gui,
                "Gui.getDocument('%s').ActiveView.setActiveObject('%s', App.getDocument('%s').getObject('%s'))",
                datumBody->getDocument()->getName(),
                PDBODYKEY,
                datumBody->getDocument()->getName(),
                datumBody->getNameInDocument());
        }
    }
    Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().setEdit('%s',0)",this->pcObject->getNameInDocument());
    return true;
}

void ViewProviderDatum::unsetEdit(int ModNum)
{
    // return to the WB we were in before editing the PartDesign feature
    Gui::Command::assureWorkbench(oldWb.c_str());

    if (ModNum == ViewProvider::Default) {
        // when pressing ESC make sure to close the dialog
        Gui::Control().closeDialog();
    }
    else {
        Gui::ViewProviderGeometryObject::unsetEdit(ModNum);
    }
}

void ViewProviderDatum::updateExtents () {
    setExtents ( getRelevantBoundBox () );
}

void ViewProviderDatum::setExtents (const SbBox3f &bbox) {
    const SbVec3f & min = bbox.getMin ();
    const SbVec3f & max = bbox.getMax ();
    setExtents ( Base::BoundBox3d ( min.getValue()[0], min.getValue()[1], min.getValue()[2],
                                    max.getValue()[0], max.getValue()[1], max.getValue()[2] ) );
}

SbBox3f ViewProviderDatum::getRelevantBoundBox () const {
    std::vector<App::DocumentObject *> objs;

    // Probe body first
    PartDesign::Body* body = PartDesign::Body::findBodyOf ( this->getObject() );
    if (body) {
        objs = body->getFullModel ();
    } else {
        // Probe if we belongs to some group
        App::DocumentObject* group =  App::DocumentObjectGroup::getGroupOfObject ( this->getObject () );

        if(group) {
            auto* ext = group->getExtensionByType<App::GroupExtension>();
            if(ext)
                objs = ext->getObjects ();
        } else {
            // Fallback to whole document
            objs = this->getObject ()->getDocument ()->getObjects ();
        }
    }

    Gui::View3DInventor* view = dynamic_cast<Gui::View3DInventor*>(this->getActiveView());
    if(view){
       Gui::View3DInventorViewer* viewer = view->getViewer();
       SoGetBoundingBoxAction bboxAction(viewer->getSoRenderManager()->getViewportRegion());
       SbBox3f bbox = getRelevantBoundBox (bboxAction, objs);

       if ( bbox.getVolume () < Precision::Confusion() ) {
           bbox.extendBy ( defaultBoundBox () );
       }
       return bbox;
    } else {
       return defaultBoundBox();
    }
}

SbBox3f ViewProviderDatum::getRelevantBoundBox (
        SoGetBoundingBoxAction &bboxAction, const std::vector <App::DocumentObject *> &objs )
{
    SbBox3f bbox(0,0,0, 0,0,0);

    // Adds the bbox of given feature to the output
    for (auto obj :objs) {
        ViewProvider *vp = Gui::Application::Instance->getViewProvider(obj);
        if (!vp) { continue; }
        if (!vp->isVisible ()) { continue; }

        if (obj->isDerivedFrom (Part::Datum::getClassTypeId() ) ) {
            // Treat datums only as their basepoint
            // I hope it's ok to take FreeCAD's point here
            Base::Vector3d basePoint = static_cast<Part::Datum *> ( obj )->getBasePoint ();
            bbox.extendBy (SbVec3f(basePoint.x, basePoint.y, basePoint.z ));
        } else {
            bboxAction.apply ( vp->getRoot () );
            SbBox3f obj_bbox =  bboxAction.getBoundingBox ();

            if ( obj_bbox.getVolume () < Precision::Infinite () ) {
                bbox.extendBy ( obj_bbox );
            }
        }
    }

    return bbox;
}

SbBox3f ViewProviderDatum::defaultBoundBox () {
    return SbBox3f ( -defaultSize, -defaultSize, -defaultSize,
            defaultSize, defaultSize, defaultSize );
}

bool ViewProviderDatum::isPickable() {

    return bool(pPickStyle->style.getValue() == SoPickStyle::SHAPE);
}

void ViewProviderDatum::setPickable(bool val) {

    if(val)
        pPickStyle->style = SoPickStyle::SHAPE;
    else
        pPickStyle->style = SoPickStyle::UNPICKABLE;
}
<commit_msg>fixes #2964, #2968<commit_after>/***************************************************************************
 *   Copyright (c) 2013 Jan Rheinlaender <jrheinlaender@users.sourceforge.net>        *
 *                                                                         *
 *   This file is part of the FreeCAD CAx development system.              *
 *                                                                         *
 *   This library is free software; you can redistribute it and/or         *
 *   modify it under the terms of the GNU Library General Public           *
 *   License as published by the Free Software Foundation; either          *
 *   version 2 of the License, or (at your option) any later version.      *
 *                                                                         *
 *   This library  is distributed in the hope that it will be useful,      *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU Library General Public License for more details.                  *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this library; see the file COPYING.LIB. If not,    *
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
 *   Suite 330, Boston, MA  02111-1307, USA                                *
 *                                                                         *
 ***************************************************************************/

#include "PreCompiled.h"

#ifndef _PreComp_
# include <QMessageBox>
# include <QAction>
# include <QMenu>
# include <Inventor/actions/SoGetBoundingBoxAction.h>
# include <Inventor/nodes/SoSeparator.h>
# include <Inventor/nodes/SoPickStyle.h>
# include <Inventor/nodes/SoShapeHints.h>
# include <Inventor/nodes/SoMaterial.h>
# include <Inventor/nodes/SoBaseColor.h>
# include <Inventor/nodes/SoTransparencyType.h>
# include <Inventor/nodes/SoDrawStyle.h>
# include <Inventor/nodes/SoMarkerSet.h>
# include <Inventor/nodes/SoVertexProperty.h>
# include <Inventor/nodes/SoLineSet.h>
# include <Inventor/nodes/SoFaceSet.h>
# include <Inventor/details/SoLineDetail.h>
# include <Inventor/details/SoFaceDetail.h>
# include <Inventor/details/SoPointDetail.h>
# include <TopoDS_Vertex.hxx>
# include <TopoDS.hxx>
# include <BRep_Tool.hxx>
# include <gp_Pnt.hxx>
# include <Precision.hxx>
# include <Geom_Plane.hxx>
# include <Geom_Line.hxx>
# include <GeomAPI_IntCS.hxx>
#endif

#include <App/DocumentObjectGroup.h>
#include <App/GeoFeatureGroupExtension.h>
#include <Gui/Control.h>
#include <Gui/Command.h>
#include <Gui/Application.h>
#include <Gui/MDIView.h>
#include <Gui/ViewProviderOrigin.h>
#include <Gui/View3DInventor.h>
#include <Gui/View3DInventorViewer.h>

#include <Mod/PartDesign/App/DatumPoint.h>
#include <Mod/PartDesign/App/DatumLine.h>
#include <Mod/PartDesign/App/DatumPlane.h>
#include <Mod/PartDesign/App/Body.h>
#include <Mod/PartDesign/App/DatumCS.h>

#include "TaskDatumParameters.h"
#include "ViewProviderBody.h"
#include "Utils.h"

#include "ViewProviderDatum.h"

using namespace PartDesignGui;

PROPERTY_SOURCE(PartDesignGui::ViewProviderDatum,Gui::ViewProviderGeometryObject)

// static data
const double ViewProviderDatum::defaultSize = Gui::ViewProviderOrigin::defaultSize ();

ViewProviderDatum::ViewProviderDatum()
{
    pShapeSep = new SoSeparator();
    pShapeSep->ref();
    pPickStyle = new SoPickStyle();
    pPickStyle->ref();

    DisplayMode.setStatus(App::Property::Hidden, true);

    // set default color for datums (golden yellow with 60% transparency)
    ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath (
            "User parameter:BaseApp/Preferences/Mod/PartDesign");
    unsigned long shcol = hGrp->GetUnsigned ( "DefaultDatumColor", 0xFFD70099 );

    App::Color col ( (uint32_t) shcol );
    ShapeColor.setValue ( col );

    Transparency.setValue (col.a * 100);

    oldWb = "";
    oldTip = NULL;
}

ViewProviderDatum::~ViewProviderDatum()
{
    pShapeSep->unref();
    pPickStyle->unref();
}

void ViewProviderDatum::attach(App::DocumentObject *obj)
{
    ViewProviderGeometryObject::attach ( obj );

    // TODO remove this field (2015-09-08, Fat-Zer)
    App::DocumentObject* o = getObject();
    if (o->getTypeId() == PartDesign::Plane::getClassTypeId())
        datumType = QObject::tr("Plane");
    else if (o->getTypeId() == PartDesign::Line::getClassTypeId())
        datumType = QObject::tr("Line");
    else if (o->getTypeId() == PartDesign::Point::getClassTypeId())
        datumType = QObject::tr("Point");
    else if (o->getTypeId() == PartDesign::CoordinateSystem::getClassTypeId())
        datumType = QObject::tr("CoordinateSystem");

    SoShapeHints* hints = new SoShapeHints();
    hints->shapeType.setValue(SoShapeHints::UNKNOWN_SHAPE_TYPE);
    hints->vertexOrdering.setValue(SoShapeHints::COUNTERCLOCKWISE);
    SoDrawStyle* fstyle = new SoDrawStyle();
    fstyle->style = SoDrawStyle::FILLED;
    fstyle->lineWidth = 3;
    fstyle->pointSize = 5;
    pPickStyle->style = SoPickStyle::SHAPE;
    SoMaterialBinding* matBinding = new SoMaterialBinding;
    matBinding->value = SoMaterialBinding::OVERALL;

    SoSeparator* sep = new SoSeparator();
    sep->addChild(hints);
    sep->addChild(fstyle);
    sep->addChild(pPickStyle);
    sep->addChild(matBinding);
    sep->addChild(pcShapeMaterial);
    sep->addChild(pShapeSep);

    addDisplayMaskMode(sep, "Base");
}

bool ViewProviderDatum::onDelete(const std::vector<std::string> &)
{
    // TODO: Ask user what to do about dependent objects, e.g. Sketches that have this feature as their support
    // 1. Delete
    // 2. Suppress
    // 3. Re-route

    return true;
}

std::vector<std::string> ViewProviderDatum::getDisplayModes(void) const
{
    return { "Base" };
}

void ViewProviderDatum::setDisplayMode(const char* ModeName)
{
    if (strcmp(ModeName, "Base") == 0)
        setDisplayMaskMode("Base");
    ViewProviderGeometryObject::setDisplayMode(ModeName);
}

std::string ViewProviderDatum::getElement(const SoDetail* detail) const
{
    if (detail) {
        int element = 1;

        if (detail->getTypeId() == SoLineDetail::getClassTypeId()) {
            const SoLineDetail* line_detail = static_cast<const SoLineDetail*>(detail);
            element = line_detail->getLineIndex();
        } else if (detail->getTypeId() == SoFaceDetail::getClassTypeId()) {
            const SoFaceDetail* face_detail = static_cast<const SoFaceDetail*>(detail);
            element = face_detail->getFaceIndex();
        } else if (detail->getTypeId() == SoPointDetail::getClassTypeId()) {
            const SoPointDetail* point_detail = static_cast<const SoPointDetail*>(detail);
            element = point_detail->getCoordinateIndex();
        }

        if (element == 0)
            return datumType.toStdString();
    }

    return std::string("");
}

SoDetail* ViewProviderDatum::getDetail(const char* subelement) const
{
    QString subelem = QString::fromLatin1(subelement);

    if (subelem == QObject::tr("Line")) {
         SoLineDetail* detail = new SoLineDetail();
         detail->setPartIndex(0);
         return detail;
    } else if (subelem == QObject::tr("Plane")) {
        SoFaceDetail* detail = new SoFaceDetail();
        detail->setPartIndex(0);
        return detail;
   } else if (subelem == QObject::tr("Point")) {
        SoPointDetail* detail = new SoPointDetail();
        detail->setCoordinateIndex(0);
        return detail;
   }

    return NULL;
}

bool ViewProviderDatum::isSelectable(void) const
{
    return true;
}

void ViewProviderDatum::setupContextMenu(QMenu* menu, QObject* receiver, const char* member)
{
    QAction* act;
    act = menu->addAction(QObject::tr("Edit datum ") + datumType, receiver, member);
    act->setData(QVariant((int)ViewProvider::Default));
}

bool ViewProviderDatum::setEdit(int ModNum)
{
    if (!ViewProvider::setEdit(ModNum))
        return false;
    // TODO Share this code with Features view providers somehow (2015-09-08, Fat-Zer)
    if (ModNum == ViewProvider::Default ) {
        // When double-clicking on the item for this datum feature the
        // object unsets and sets its edit mode without closing
        // the task panel
        Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog();
        TaskDlgDatumParameters *datumDlg = qobject_cast<TaskDlgDatumParameters *>(dlg);
        if (datumDlg && datumDlg->getViewProvider() != this)
            datumDlg = 0; // another datum feature left open its task panel
        if (dlg && !datumDlg) {
            QMessageBox msgBox;
            msgBox.setText(QObject::tr("A dialog is already open in the task panel"));
            msgBox.setInformativeText(QObject::tr("Do you want to close this dialog?"));
            msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
            msgBox.setDefaultButton(QMessageBox::Yes);
            int ret = msgBox.exec();
            if (ret == QMessageBox::Yes)
                Gui::Control().closeDialog();
            else
                return false;
        }

        // clear the selection (convenience)
        Gui::Selection().clearSelection();

        oldWb = Gui::Command::assureWorkbench("PartDesignWorkbench");

        // start the edit dialog
        if (datumDlg)
            Gui::Control().showDialog(datumDlg);
        else
            Gui::Control().showDialog(new TaskDlgDatumParameters(this));

        return true;
    }
    else {
        return ViewProvider::setEdit(ModNum);
    }
}

bool ViewProviderDatum::doubleClicked(void)
{
    std::string Msg("Edit ");
    Msg += this->pcObject->Label.getValue();
    Gui::Command::openCommand(Msg.c_str());

    Part::Datum* pcDatum = static_cast<Part::Datum*>(getObject());
    PartDesign::Body* activeBody = getActiveView()->getActiveObject<PartDesign::Body*>(PDBODYKEY);
    auto datumBody = PartDesignGui::getBodyFor(pcDatum, false);

    if (datumBody != NULL) {
        if (datumBody != activeBody) {
            Gui::Command::doCommand(Gui::Command::Gui,
                "Gui.getDocument('%s').ActiveView.setActiveObject('%s', App.getDocument('%s').getObject('%s'))",
                datumBody->getDocument()->getName(),
                PDBODYKEY,
                datumBody->getDocument()->getName(),
                datumBody->getNameInDocument());
        }
    }
    Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().setEdit('%s',0)",this->pcObject->getNameInDocument());
    return true;
}

void ViewProviderDatum::unsetEdit(int ModNum)
{
    // return to the WB we were in before editing the PartDesign feature
    Gui::Command::assureWorkbench(oldWb.c_str());

    if (ModNum == ViewProvider::Default) {
        // when pressing ESC make sure to close the dialog
        Gui::Control().closeDialog();
    }
    else {
        Gui::ViewProviderGeometryObject::unsetEdit(ModNum);
    }
}

void ViewProviderDatum::updateExtents () {
    setExtents ( getRelevantBoundBox () );
}

void ViewProviderDatum::setExtents (const SbBox3f &bbox) {
    const SbVec3f & min = bbox.getMin ();
    const SbVec3f & max = bbox.getMax ();
    setExtents ( Base::BoundBox3d ( min.getValue()[0], min.getValue()[1], min.getValue()[2],
                                    max.getValue()[0], max.getValue()[1], max.getValue()[2] ) );
}

SbBox3f ViewProviderDatum::getRelevantBoundBox () const {
    std::vector<App::DocumentObject *> objs;

    // Probe body first
    PartDesign::Body* body = PartDesign::Body::findBodyOf ( this->getObject() );
    if (body) {
        objs = body->getFullModel ();
    } else {
        // Probe if we belongs to some group
        App::DocumentObject* group =  App::DocumentObjectGroup::getGroupOfObject ( this->getObject () );

        if(group) {
            auto* ext = group->getExtensionByType<App::GroupExtension>();
            if(ext)
                objs = ext->getObjects ();
        } else {
            // Fallback to whole document
            objs = this->getObject ()->getDocument ()->getObjects ();
        }
    }

    Gui::View3DInventor* view = dynamic_cast<Gui::View3DInventor*>(this->getActiveView());
    if(view){
       Gui::View3DInventorViewer* viewer = view->getViewer();
       SoGetBoundingBoxAction bboxAction(viewer->getSoRenderManager()->getViewportRegion());
       SbBox3f bbox = getRelevantBoundBox (bboxAction, objs);

       if ( bbox.getVolume () < Precision::Confusion() ) {
           bbox.extendBy ( defaultBoundBox () );
       }
       return bbox;
    } else {
       return defaultBoundBox();
    }
}

SbBox3f ViewProviderDatum::getRelevantBoundBox (
        SoGetBoundingBoxAction &bboxAction, const std::vector <App::DocumentObject *> &objs )
{
    SbBox3f bbox = defaultBoundBox();

    // Adds the bbox of given feature to the output
    for (auto obj :objs) {
        ViewProvider *vp = Gui::Application::Instance->getViewProvider(obj);
        if (!vp) { continue; }
        if (!vp->isVisible ()) { continue; }

        if (obj->isDerivedFrom (Part::Datum::getClassTypeId() ) ) {
            // Treat datums only as their basepoint
            // I hope it's ok to take FreeCAD's point here
            Base::Vector3d basePoint = static_cast<Part::Datum *> ( obj )->getBasePoint ();
            bbox.extendBy (SbVec3f(basePoint.x, basePoint.y, basePoint.z ));
        } else {
            bboxAction.apply ( vp->getRoot () );
            SbBox3f obj_bbox =  bboxAction.getBoundingBox ();

            if ( obj_bbox.getVolume () < Precision::Infinite () ) {
                bbox.extendBy ( obj_bbox );
            }
        }
    }

    // TODO: shrink bbox when all other elements are too small
    return bbox;
}

SbBox3f ViewProviderDatum::defaultBoundBox () {
    return SbBox3f ( -defaultSize, -defaultSize, -defaultSize,
            defaultSize, defaultSize, defaultSize );
}

bool ViewProviderDatum::isPickable() {

    return bool(pPickStyle->style.getValue() == SoPickStyle::SHAPE);
}

void ViewProviderDatum::setPickable(bool val) {

    if(val)
        pPickStyle->style = SoPickStyle::SHAPE;
    else
        pPickStyle->style = SoPickStyle::UNPICKABLE;
}
<|endoftext|>


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

#include "upb/upb.hpp"

#include <grpcpp/security/alts_context.h>
#include <grpcpp/security/alts_util.h>
#include <grpcpp/security/auth_context.h>
#include <gtest/gtest.h>

#include "src/core/tsi/alts/handshaker/alts_tsi_handshaker.h"
#include "src/cpp/common/secure_auth_context.h"
#include "src/proto/grpc/gcp/altscontext.upb.h"
#include "test/cpp/util/string_ref_helper.h"

namespace grpc {
namespace {

TEST(AltsUtilTest, NullAuthContext) {
  std::unique_ptr<experimental::AltsContext> alts_context =
      experimental::GetAltsContextFromAuthContext(nullptr);
  EXPECT_EQ(alts_context, nullptr);
}

TEST(AltsUtilTest, EmptyAuthContext) {
  grpc_core::RefCountedPtr<grpc_auth_context> ctx =
      grpc_core::MakeRefCounted<grpc_auth_context>(nullptr);
  const std::shared_ptr<AuthContext> auth_context(
      new SecureAuthContext(ctx.get()));
  std::unique_ptr<experimental::AltsContext> alts_context =
      experimental::GetAltsContextFromAuthContext(auth_context);
  EXPECT_EQ(alts_context, nullptr);
}

TEST(AltsUtilTest, AuthContextWithMoreThanOneAltsContext) {
  grpc_core::RefCountedPtr<grpc_auth_context> ctx =
      grpc_core::MakeRefCounted<grpc_auth_context>(nullptr);
  const std::shared_ptr<AuthContext> auth_context(
      new SecureAuthContext(ctx.get()));
  ctx.reset();
  auth_context->AddProperty(TSI_ALTS_CONTEXT, "context1");
  auth_context->AddProperty(TSI_ALTS_CONTEXT, "context2");
  std::unique_ptr<experimental::AltsContext> alts_context =
      experimental::GetAltsContextFromAuthContext(auth_context);
  EXPECT_EQ(alts_context, nullptr);
}

TEST(AltsUtilTest, AuthContextWithBadAltsContext) {
  grpc_core::RefCountedPtr<grpc_auth_context> ctx =
      grpc_core::MakeRefCounted<grpc_auth_context>(nullptr);
  const std::shared_ptr<AuthContext> auth_context(
      new SecureAuthContext(ctx.get()));
  ctx.reset();
  auth_context->AddProperty(TSI_ALTS_CONTEXT,
                            "bad context string serialization");
  std::unique_ptr<experimental::AltsContext> alts_context =
      experimental::GetAltsContextFromAuthContext(auth_context);
  EXPECT_EQ(alts_context, nullptr);
}

TEST(AltsUtilTest, AuthContextWithGoodAltsContextWithoutRpcVersions) {
  grpc_core::RefCountedPtr<grpc_auth_context> ctx =
      grpc_core::MakeRefCounted<grpc_auth_context>(nullptr);
  const std::shared_ptr<AuthContext> auth_context(
      new SecureAuthContext(ctx.get()));
  ctx.reset();
  std::string expected_ap("application protocol");
  std::string expected_rp("record protocol");
  std::string expected_peer("peer");
  std::string expected_local("local");
  std::string expected_peer_atrributes_key("peer");
  std::string expected_peer_atrributes_value("attributes");
  grpc_security_level expected_sl = GRPC_INTEGRITY_ONLY;
  upb::Arena context_arena;
  grpc_gcp_AltsContext* context = grpc_gcp_AltsContext_new(context_arena.ptr());
  grpc_gcp_AltsContext_set_application_protocol(
      context, upb_strview_make(expected_ap.data(), expected_ap.length()));
  grpc_gcp_AltsContext_set_record_protocol(
      context, upb_strview_make(expected_rp.data(), expected_rp.length()));
  grpc_gcp_AltsContext_set_security_level(context, expected_sl);
  grpc_gcp_AltsContext_set_peer_service_account(
      context, upb_strview_make(expected_peer.data(), expected_peer.length()));
  grpc_gcp_AltsContext_set_local_service_account(
      context,
      upb_strview_make(expected_local.data(), expected_local.length()));
  grpc_gcp_AltsContext_peer_attributes_set(
      context,
      upb_strview_make(expected_peer_atrributes_key.data(),
                       expected_peer_atrributes_key.length()),
      upb_strview_make(expected_peer_atrributes_value.data(),
                       expected_peer_atrributes_value.length()),
      context_arena.ptr());
  size_t serialized_ctx_length;
  char* serialized_ctx = grpc_gcp_AltsContext_serialize(
      context, context_arena.ptr(), &serialized_ctx_length);
  EXPECT_NE(serialized_ctx, nullptr);
  auth_context->AddProperty(TSI_ALTS_CONTEXT,
                            string(serialized_ctx, serialized_ctx_length));
  std::unique_ptr<experimental::AltsContext> alts_context =
      experimental::GetAltsContextFromAuthContext(auth_context);
  EXPECT_NE(alts_context, nullptr);
  EXPECT_EQ(expected_ap, alts_context->application_protocol());
  EXPECT_EQ(expected_rp, alts_context->record_protocol());
  EXPECT_EQ(expected_peer, alts_context->peer_service_account());
  EXPECT_EQ(expected_local, alts_context->local_service_account());
  EXPECT_EQ(expected_sl, alts_context->security_level());
  // all rpc versions should be 0 if not set
  experimental::AltsContext::RpcProtocolVersions rpc_protocol_versions =
      alts_context->peer_rpc_versions();
  EXPECT_EQ(0, rpc_protocol_versions.max_rpc_version.major_version);
  EXPECT_EQ(0, rpc_protocol_versions.max_rpc_version.minor_version);
  EXPECT_EQ(0, rpc_protocol_versions.min_rpc_version.major_version);
  EXPECT_EQ(0, rpc_protocol_versions.min_rpc_version.minor_version);
  EXPECT_EQ(expected_peer_atrributes_value,
            alts_context->peer_attributes().at(expected_peer_atrributes_key));
}

TEST(AltsUtilTest, AuthContextWithGoodAltsContext) {
  grpc_core::RefCountedPtr<grpc_auth_context> ctx =
      grpc_core::MakeRefCounted<grpc_auth_context>(nullptr);
  const std::shared_ptr<AuthContext> auth_context(
      new SecureAuthContext(ctx.get()));
  ctx.reset();
  upb::Arena context_arena;
  grpc_gcp_AltsContext* context = grpc_gcp_AltsContext_new(context_arena.ptr());
  upb::Arena versions_arena;
  grpc_gcp_RpcProtocolVersions* versions =
      grpc_gcp_RpcProtocolVersions_new(versions_arena.ptr());
  upb::Arena max_major_version_arena;
  grpc_gcp_RpcProtocolVersions_Version* version =
      grpc_gcp_RpcProtocolVersions_Version_new(max_major_version_arena.ptr());
  grpc_gcp_RpcProtocolVersions_Version_set_major(version, 10);
  grpc_gcp_RpcProtocolVersions_set_max_rpc_version(versions, version);
  grpc_gcp_AltsContext_set_peer_rpc_versions(context, versions);
  size_t serialized_ctx_length;
  char* serialized_ctx = grpc_gcp_AltsContext_serialize(
      context, context_arena.ptr(), &serialized_ctx_length);
  EXPECT_NE(serialized_ctx, nullptr);
  auth_context->AddProperty(TSI_ALTS_CONTEXT,
                            string(serialized_ctx, serialized_ctx_length));
  std::unique_ptr<experimental::AltsContext> alts_context =
      experimental::GetAltsContextFromAuthContext(auth_context);
  EXPECT_NE(alts_context, nullptr);
  EXPECT_EQ("", alts_context->application_protocol());
  EXPECT_EQ("", alts_context->record_protocol());
  EXPECT_EQ("", alts_context->peer_service_account());
  EXPECT_EQ("", alts_context->local_service_account());
  EXPECT_EQ(GRPC_SECURITY_NONE, alts_context->security_level());
  experimental::AltsContext::RpcProtocolVersions rpc_protocol_versions =
      alts_context->peer_rpc_versions();
  EXPECT_EQ(10, rpc_protocol_versions.max_rpc_version.major_version);
  EXPECT_EQ(0, rpc_protocol_versions.max_rpc_version.minor_version);
  EXPECT_EQ(0, rpc_protocol_versions.min_rpc_version.major_version);
  EXPECT_EQ(0, rpc_protocol_versions.min_rpc_version.minor_version);
}

TEST(AltsUtilTest, AltsClientAuthzCheck) {
  // AltsClientAuthzCheck function should return a permission denied error on
  // the bad_auth_context, whose internal ALTS context does not exist
  const std::shared_ptr<AuthContext> bad_auth_context(
      new SecureAuthContext(nullptr));
  std::vector<std::string> service_accounts{"client"};
  grpc::Status status =
      experimental::AltsClientAuthzCheck(bad_auth_context, service_accounts);
  EXPECT_EQ(grpc::StatusCode::PERMISSION_DENIED, status.error_code());
  // AltsClientAuthzCheck function should function normally when the peer name
  // in ALTS context is listed in service_accounts
  grpc_core::RefCountedPtr<grpc_auth_context> ctx =
      grpc_core::MakeRefCounted<grpc_auth_context>(nullptr);
  const std::shared_ptr<AuthContext> auth_context(
      new SecureAuthContext(ctx.get()));
  ctx.reset();
  std::string peer("good_client");
  std::vector<std::string> good_service_accounts{"good_client",
                                                 "good_client_1"};
  std::vector<std::string> bad_service_accounts{"bad_client", "bad_client_1"};
  upb::Arena context_arena;
  grpc_gcp_AltsContext* context = grpc_gcp_AltsContext_new(context_arena.ptr());
  grpc_gcp_AltsContext_set_peer_service_account(
      context, upb_strview_make(peer.data(), peer.length()));
  size_t serialized_ctx_length;
  char* serialized_ctx = grpc_gcp_AltsContext_serialize(
      context, context_arena.ptr(), &serialized_ctx_length);
  EXPECT_NE(serialized_ctx, nullptr);
  auth_context->AddProperty(TSI_ALTS_CONTEXT,
                            string(serialized_ctx, serialized_ctx_length));
  grpc::Status good_status =
      experimental::AltsClientAuthzCheck(auth_context, good_service_accounts);
  EXPECT_TRUE(good_status.ok());
  grpc::Status bad_status =
      experimental::AltsClientAuthzCheck(auth_context, bad_service_accounts);
  EXPECT_EQ(grpc::StatusCode::PERMISSION_DENIED, bad_status.error_code());
}

}  // namespace
}  // namespace grpc

int main(int argc, char** argv) {
  ::testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}
<commit_msg>fix MSAN error<commit_after>/*
 *
 * Copyright 2019 gRPC authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#include "upb/upb.hpp"

#include <grpcpp/security/alts_context.h>
#include <grpcpp/security/alts_util.h>
#include <grpcpp/security/auth_context.h>
#include <gtest/gtest.h>

#include "src/core/tsi/alts/handshaker/alts_tsi_handshaker.h"
#include "src/cpp/common/secure_auth_context.h"
#include "src/proto/grpc/gcp/altscontext.upb.h"
#include "test/core/util/test_config.h"
#include "test/cpp/util/string_ref_helper.h"

namespace grpc {
namespace {

TEST(AltsUtilTest, NullAuthContext) {
  std::unique_ptr<experimental::AltsContext> alts_context =
      experimental::GetAltsContextFromAuthContext(nullptr);
  EXPECT_EQ(alts_context, nullptr);
}

TEST(AltsUtilTest, EmptyAuthContext) {
  grpc_core::RefCountedPtr<grpc_auth_context> ctx =
      grpc_core::MakeRefCounted<grpc_auth_context>(nullptr);
  const std::shared_ptr<AuthContext> auth_context(
      new SecureAuthContext(ctx.get()));
  std::unique_ptr<experimental::AltsContext> alts_context =
      experimental::GetAltsContextFromAuthContext(auth_context);
  EXPECT_EQ(alts_context, nullptr);
}

TEST(AltsUtilTest, AuthContextWithMoreThanOneAltsContext) {
  grpc_core::RefCountedPtr<grpc_auth_context> ctx =
      grpc_core::MakeRefCounted<grpc_auth_context>(nullptr);
  const std::shared_ptr<AuthContext> auth_context(
      new SecureAuthContext(ctx.get()));
  ctx.reset();
  auth_context->AddProperty(TSI_ALTS_CONTEXT, "context1");
  auth_context->AddProperty(TSI_ALTS_CONTEXT, "context2");
  std::unique_ptr<experimental::AltsContext> alts_context =
      experimental::GetAltsContextFromAuthContext(auth_context);
  EXPECT_EQ(alts_context, nullptr);
}

TEST(AltsUtilTest, AuthContextWithBadAltsContext) {
  grpc_core::RefCountedPtr<grpc_auth_context> ctx =
      grpc_core::MakeRefCounted<grpc_auth_context>(nullptr);
  const std::shared_ptr<AuthContext> auth_context(
      new SecureAuthContext(ctx.get()));
  ctx.reset();
  auth_context->AddProperty(TSI_ALTS_CONTEXT,
                            "bad context string serialization");
  std::unique_ptr<experimental::AltsContext> alts_context =
      experimental::GetAltsContextFromAuthContext(auth_context);
  EXPECT_EQ(alts_context, nullptr);
}

TEST(AltsUtilTest, AuthContextWithGoodAltsContextWithoutRpcVersions) {
  grpc_core::RefCountedPtr<grpc_auth_context> ctx =
      grpc_core::MakeRefCounted<grpc_auth_context>(nullptr);
  const std::shared_ptr<AuthContext> auth_context(
      new SecureAuthContext(ctx.get()));
  ctx.reset();
  std::string expected_ap("application protocol");
  std::string expected_rp("record protocol");
  std::string expected_peer("peer");
  std::string expected_local("local");
  std::string expected_peer_atrributes_key("peer");
  std::string expected_peer_atrributes_value("attributes");
  grpc_security_level expected_sl = GRPC_INTEGRITY_ONLY;
  upb::Arena context_arena;
  grpc_gcp_AltsContext* context = grpc_gcp_AltsContext_new(context_arena.ptr());
  grpc_gcp_AltsContext_set_application_protocol(
      context, upb_strview_make(expected_ap.data(), expected_ap.length()));
  grpc_gcp_AltsContext_set_record_protocol(
      context, upb_strview_make(expected_rp.data(), expected_rp.length()));
  grpc_gcp_AltsContext_set_security_level(context, expected_sl);
  grpc_gcp_AltsContext_set_peer_service_account(
      context, upb_strview_make(expected_peer.data(), expected_peer.length()));
  grpc_gcp_AltsContext_set_local_service_account(
      context,
      upb_strview_make(expected_local.data(), expected_local.length()));
  grpc_gcp_AltsContext_peer_attributes_set(
      context,
      upb_strview_make(expected_peer_atrributes_key.data(),
                       expected_peer_atrributes_key.length()),
      upb_strview_make(expected_peer_atrributes_value.data(),
                       expected_peer_atrributes_value.length()),
      context_arena.ptr());
  size_t serialized_ctx_length;
  char* serialized_ctx = grpc_gcp_AltsContext_serialize(
      context, context_arena.ptr(), &serialized_ctx_length);
  EXPECT_NE(serialized_ctx, nullptr);
  auth_context->AddProperty(TSI_ALTS_CONTEXT,
                            string(serialized_ctx, serialized_ctx_length));
  std::unique_ptr<experimental::AltsContext> alts_context =
      experimental::GetAltsContextFromAuthContext(auth_context);
  EXPECT_NE(alts_context, nullptr);
  EXPECT_EQ(expected_ap, alts_context->application_protocol());
  EXPECT_EQ(expected_rp, alts_context->record_protocol());
  EXPECT_EQ(expected_peer, alts_context->peer_service_account());
  EXPECT_EQ(expected_local, alts_context->local_service_account());
  EXPECT_EQ(expected_sl, alts_context->security_level());
  // all rpc versions should be 0 if not set
  experimental::AltsContext::RpcProtocolVersions rpc_protocol_versions =
      alts_context->peer_rpc_versions();
  EXPECT_EQ(0, rpc_protocol_versions.max_rpc_version.major_version);
  EXPECT_EQ(0, rpc_protocol_versions.max_rpc_version.minor_version);
  EXPECT_EQ(0, rpc_protocol_versions.min_rpc_version.major_version);
  EXPECT_EQ(0, rpc_protocol_versions.min_rpc_version.minor_version);
  EXPECT_EQ(expected_peer_atrributes_value,
            alts_context->peer_attributes().at(expected_peer_atrributes_key));
}

TEST(AltsUtilTest, AuthContextWithGoodAltsContext) {
  grpc_core::RefCountedPtr<grpc_auth_context> ctx =
      grpc_core::MakeRefCounted<grpc_auth_context>(nullptr);
  const std::shared_ptr<AuthContext> auth_context(
      new SecureAuthContext(ctx.get()));
  ctx.reset();
  upb::Arena context_arena;
  grpc_gcp_AltsContext* context = grpc_gcp_AltsContext_new(context_arena.ptr());
  upb::Arena versions_arena;
  grpc_gcp_RpcProtocolVersions* versions =
      grpc_gcp_RpcProtocolVersions_new(versions_arena.ptr());
  upb::Arena max_major_version_arena;
  grpc_gcp_RpcProtocolVersions_Version* version =
      grpc_gcp_RpcProtocolVersions_Version_new(max_major_version_arena.ptr());
  grpc_gcp_RpcProtocolVersions_Version_set_major(version, 10);
  grpc_gcp_RpcProtocolVersions_set_max_rpc_version(versions, version);
  grpc_gcp_AltsContext_set_peer_rpc_versions(context, versions);
  size_t serialized_ctx_length;
  char* serialized_ctx = grpc_gcp_AltsContext_serialize(
      context, context_arena.ptr(), &serialized_ctx_length);
  EXPECT_NE(serialized_ctx, nullptr);
  auth_context->AddProperty(TSI_ALTS_CONTEXT,
                            string(serialized_ctx, serialized_ctx_length));
  std::unique_ptr<experimental::AltsContext> alts_context =
      experimental::GetAltsContextFromAuthContext(auth_context);
  EXPECT_NE(alts_context, nullptr);
  EXPECT_EQ("", alts_context->application_protocol());
  EXPECT_EQ("", alts_context->record_protocol());
  EXPECT_EQ("", alts_context->peer_service_account());
  EXPECT_EQ("", alts_context->local_service_account());
  EXPECT_EQ(GRPC_SECURITY_NONE, alts_context->security_level());
  experimental::AltsContext::RpcProtocolVersions rpc_protocol_versions =
      alts_context->peer_rpc_versions();
  EXPECT_EQ(10, rpc_protocol_versions.max_rpc_version.major_version);
  EXPECT_EQ(0, rpc_protocol_versions.max_rpc_version.minor_version);
  EXPECT_EQ(0, rpc_protocol_versions.min_rpc_version.major_version);
  EXPECT_EQ(0, rpc_protocol_versions.min_rpc_version.minor_version);
}

TEST(AltsUtilTest, AltsClientAuthzCheck) {
  // AltsClientAuthzCheck function should return a permission denied error on
  // the bad_auth_context, whose internal ALTS context does not exist
  const std::shared_ptr<AuthContext> bad_auth_context(
      new SecureAuthContext(nullptr));
  std::vector<std::string> service_accounts{"client"};
  grpc::Status status =
      experimental::AltsClientAuthzCheck(bad_auth_context, service_accounts);
  EXPECT_EQ(grpc::StatusCode::PERMISSION_DENIED, status.error_code());
  // AltsClientAuthzCheck function should function normally when the peer name
  // in ALTS context is listed in service_accounts
  grpc_core::RefCountedPtr<grpc_auth_context> ctx =
      grpc_core::MakeRefCounted<grpc_auth_context>(nullptr);
  const std::shared_ptr<AuthContext> auth_context(
      new SecureAuthContext(ctx.get()));
  ctx.reset();
  std::string peer("good_client");
  std::vector<std::string> good_service_accounts{"good_client",
                                                 "good_client_1"};
  std::vector<std::string> bad_service_accounts{"bad_client", "bad_client_1"};
  upb::Arena context_arena;
  grpc_gcp_AltsContext* context = grpc_gcp_AltsContext_new(context_arena.ptr());
  grpc_gcp_AltsContext_set_peer_service_account(
      context, upb_strview_make(peer.data(), peer.length()));
  size_t serialized_ctx_length;
  char* serialized_ctx = grpc_gcp_AltsContext_serialize(
      context, context_arena.ptr(), &serialized_ctx_length);
  EXPECT_NE(serialized_ctx, nullptr);
  auth_context->AddProperty(TSI_ALTS_CONTEXT,
                            string(serialized_ctx, serialized_ctx_length));
  grpc::Status good_status =
      experimental::AltsClientAuthzCheck(auth_context, good_service_accounts);
  EXPECT_TRUE(good_status.ok());
  grpc::Status bad_status =
      experimental::AltsClientAuthzCheck(auth_context, bad_service_accounts);
  EXPECT_EQ(grpc::StatusCode::PERMISSION_DENIED, bad_status.error_code());
}

}  // namespace
}  // namespace grpc

int main(int argc, char** argv) {
  grpc::testing::TestEnvironment env(argc, argv);
  ::testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}
<|endoftext|>


<commit_before>// -*- mode: c++; coding: utf-8 -*-
/*! @file simulation.h
    @brief Interface of Simulation class
*/
#pragma once
#ifndef SIMULATION_HPP_
#define SIMULATION_HPP_

#include <iostream>
#include <sstream>
#include <vector>
#include <random>

#include <cxxwtils/iostr.hpp>

#include "tissue.hpp"

namespace boost {
    namespace program_options {
        class options_description;
    }
}

namespace tumopp {

class Tissue;

/*! @brief Represents single run
*/
class Simulation {
  public:
    //! Parse command arguments
    Simulation(const std::vector<std::string>& args);

    //! Top level function that should be called once from main()
    void run();

    void write() const;

    const Tissue& tissue() const {return tissue_;}

    /////1/////////2/////////3/////////4/////////5/////////6/////////7/////////
  private:
    boost::program_options::options_description opt_description();

    Tissue tissue_;

    size_t NSAM = 20;

    size_t HOWMANY = 1;

    //! Print extra information
    bool VERBOSE = false;

    //! Seed for random number generator
    unsigned int SEED = std::random_device{}();

    //! Target directory to which the contents in WORK_DIR are moved
    std::string OUT_DIR;

    std::string COMMAND_ARGS;
    std::string CONFIG_STRING;
};

} // namespace tumopp

#endif /* SIMULATION_HPP_ */
<commit_msg>Add public method Simulation::conf()<commit_after>// -*- mode: c++; coding: utf-8 -*-
/*! @file simulation.h
    @brief Interface of Simulation class
*/
#pragma once
#ifndef SIMULATION_HPP_
#define SIMULATION_HPP_

#include <iostream>
#include <sstream>
#include <vector>
#include <random>

#include <cxxwtils/iostr.hpp>

#include "tissue.hpp"

namespace boost {
    namespace program_options {
        class options_description;
    }
}

namespace tumopp {

class Tissue;

/*! @brief Represents single run
*/
class Simulation {
  public:
    //! Parse command arguments
    Simulation(const std::vector<std::string>& args);

    //! Top level function that should be called once from main()
    void run();

    void write() const;

    const Tissue& tissue() const {return tissue_;}

    std::string conf() const {return CONFIG_STRING;}

    /////1/////////2/////////3/////////4/////////5/////////6/////////7/////////
  private:
    boost::program_options::options_description opt_description();

    Tissue tissue_;

    size_t NSAM = 20;

    size_t HOWMANY = 1;

    //! Print extra information
    bool VERBOSE = false;

    //! Seed for random number generator
    unsigned int SEED = std::random_device{}();

    //! Target directory to which the contents in WORK_DIR are moved
    std::string OUT_DIR;

    std::string COMMAND_ARGS;
    std::string CONFIG_STRING;
};

} // namespace tumopp

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


<commit_before>/*
 * SSL and TLS filter.
 *
 * author: Max Kellermann <mk@cm4all.com>
 */

#include "ssl_filter.hxx"
#include "ssl_factory.hxx"
#include "ssl_config.hxx"
#include "ssl_quark.hxx"
#include "thread_socket_filter.hxx"
#include "pool.h"
#include "fifo-buffer.h"
#include "buffered_io.h"
#include "gerrno.h"
#include "fb_pool.h"

#include <openssl/ssl.h>
#include <openssl/err.h>

#include <assert.h>
#include <string.h>

struct ssl_filter {
    /**
     * Buffers which can be accessed from within the thread without
     * holding locks.  These will be copied to/from the accordding
     * #thread_socket_filter buffers.
     */
    struct fifo_buffer *decrypted_input, *plain_output;

    /**
     * Memory BIOs for passing data to/from OpenSSL.
     */
    BIO *encrypted_input, *encrypted_output;

    SSL *ssl;

    bool handshaking;

    char *peer_subject, *peer_issuer_subject;
};

static void
ssl_set_error(GError **error_r)
{
    if (error_r == NULL)
        return;

    unsigned long error = ERR_get_error();
    char buffer[120];
    g_set_error(error_r, ssl_quark(), 0, "%s",
                ERR_error_string(error, buffer));
}

/**
 * Copy data from #src to #dest.
 */
static void
copy_fifo_buffer(struct fifo_buffer *dest, struct fifo_buffer *src)
{
    size_t length;
    const void *s = fifo_buffer_read(src, &length);
    if (s == NULL)
        return;

    size_t max_length;
    void *d = fifo_buffer_write(dest, &max_length);
    if (d == NULL)
        return;

    if (length > max_length)
        length = max_length;

    memcpy(d, s, length);
    fifo_buffer_append(dest, length);
    fifo_buffer_consume(src, length);
}

/**
 * Copy data from #src to #dest.
 */
static void
copy_fifo_buffer_to_bio(BIO *dest, fifo_buffer *src)
{
    size_t length;
    const void *data = fifo_buffer_read(src, &length);
    if (data == nullptr)
        return;

    int nbytes = BIO_write(dest, data, length);
    if (nbytes > 0)
        fifo_buffer_consume(src, nbytes);
}

static void
copy_bio_to_fifo_buffer(fifo_buffer *dest, BIO *src)
{
    while (true) {
        size_t max_length;
        void *data = fifo_buffer_write(dest, &max_length);
        if (data == nullptr)
            return;

        int nbytes = BIO_read(src, data, max_length);
        if (nbytes <= 0)
            return;

        fifo_buffer_append(dest, nbytes);
    }
}

static char *
format_name(X509_NAME *name)
{
    if (name == NULL)
        return NULL;

    BIO *bio = BIO_new(BIO_s_mem());
    if (bio == NULL)
        return NULL;

    X509_NAME_print_ex(bio, name, 0,
                       ASN1_STRFLGS_UTF8_CONVERT | XN_FLAG_SEP_COMMA_PLUS);
    char buffer[1024];
    int length = BIO_read(bio, buffer, sizeof(buffer) - 1);
    BIO_free(bio);

    return strndup(buffer, length);
}

static char *
format_subject_name(X509 *cert)
{
    return format_name(X509_get_subject_name(cert));
}

static char *
format_issuer_subject_name(X509 *cert)
{
    return format_name(X509_get_issuer_name(cert));
}

gcc_const
static bool
is_ssl_error(SSL *ssl, int ret)
{
    switch (SSL_get_error(ssl, ret)) {
    case SSL_ERROR_NONE:
    case SSL_ERROR_WANT_READ:
    case SSL_ERROR_WANT_WRITE:
    case SSL_ERROR_WANT_CONNECT:
    case SSL_ERROR_WANT_ACCEPT:
        return false;

    default:
        return true;
    }
}

static bool
check_ssl_error(SSL *ssl, int result, GError **error_r)
{
    if (is_ssl_error(ssl, result)) {
        ssl_set_error(error_r);
        return false;
    } else
        return true;
}

/**
 * @return false on error
 */
static bool
ssl_decrypt(SSL *ssl, struct fifo_buffer *buffer, GError **error_r)
{
    /* SSL_read() must be called repeatedly until there is no more
       data (or until the buffer is full) */

    while (true) {
        size_t length;
        void *data = fifo_buffer_write(buffer, &length);
        if (data == NULL)
            return true;

        int result = SSL_read(ssl, data, length);
        if (result <= 0)
            return result == 0 || check_ssl_error(ssl, result, error_r);

        if (result > 0)
            fifo_buffer_append(buffer, result);
    }
}

/**
 * @return false on error
 */
static bool
ssl_encrypt(SSL *ssl, struct fifo_buffer *buffer, GError **error_r)
{
    size_t length;
    const void *data = fifo_buffer_read(buffer, &length);
    if (data == NULL)
        return true;

    int result = SSL_write(ssl, data, length);
    if (result < 0 && !check_ssl_error(ssl, result, error_r))
        return false;

    if (result > 0)
        fifo_buffer_consume(buffer, result);

    return true;
}

/*
 * thread_socket_filter_handler
 *
 */

static bool
ssl_thread_socket_filter_run(ThreadSocketFilter &f, GError **error_r,
                             void *ctx)
{
    struct ssl_filter *ssl = (struct ssl_filter *)ctx;

    /* copy input (and output to make room for more output) */

    pthread_mutex_lock(&f.mutex);
    copy_fifo_buffer(f.decrypted_input, ssl->decrypted_input);
    copy_fifo_buffer(ssl->plain_output, f.plain_output);
    copy_fifo_buffer_to_bio(ssl->encrypted_input, f.encrypted_input);
    copy_bio_to_fifo_buffer(f.encrypted_output, ssl->encrypted_output);
    pthread_mutex_unlock(&f.mutex);

    /* let OpenSSL work */

    ERR_clear_error();

    if (gcc_unlikely(ssl->handshaking)) {
        int result = SSL_do_handshake(ssl->ssl);
        if (result == 1) {
            ssl->handshaking = false;

            X509 *cert = SSL_get_peer_certificate(ssl->ssl);
            if (cert != nullptr) {
                ssl->peer_subject = format_subject_name(cert);
                ssl->peer_issuer_subject = format_issuer_subject_name(cert);
                X509_free(cert);
            }
        } else if (result == 0) {
            ssl_set_error(error_r);
            return false;
        } else if (!check_ssl_error(ssl->ssl, result, error_r))
            return false;
    }

    if (gcc_likely(!ssl->handshaking) &&
        (!ssl_encrypt(ssl->ssl, ssl->plain_output, error_r) ||
         !ssl_decrypt(ssl->ssl, ssl->decrypted_input, error_r)))
        return false;

    /* copy output */

    pthread_mutex_lock(&f.mutex);
    copy_fifo_buffer(f.decrypted_input, ssl->decrypted_input);
    copy_bio_to_fifo_buffer(f.encrypted_output, ssl->encrypted_output);
    f.drained = fifo_buffer_empty(ssl->plain_output) &&
        BIO_eof(ssl->encrypted_output);
    pthread_mutex_unlock(&f.mutex);

    return true;
}

static void
ssl_thread_socket_filter_destroy(gcc_unused ThreadSocketFilter &f, void *ctx)
{
    struct ssl_filter *ssl = (struct ssl_filter *)ctx;

    if (ssl->ssl != NULL)
        SSL_free(ssl->ssl);

    fb_pool_free(ssl->decrypted_input);
    fb_pool_free(ssl->plain_output);

    free(ssl->peer_subject);
    free(ssl->peer_issuer_subject);
}

const struct ThreadSocketFilterHandler ssl_thread_socket_filter = {
    ssl_thread_socket_filter_run,
    ssl_thread_socket_filter_destroy,
};

/*
 * constructor
 *
 */

struct ssl_filter *
ssl_filter_new(struct pool *pool, ssl_factory &factory,
               GError **error_r)
{
    assert(pool != NULL);

    ssl_filter *ssl = NewFromPool<ssl_filter>(pool);

    ssl->ssl = ssl_factory_make(factory);
    if (ssl->ssl == NULL) {
        g_set_error(error_r, ssl_quark(), 0, "SSL_new() failed");
        return NULL;
    }

    ssl->decrypted_input = fb_pool_alloc();
    ssl->plain_output = fb_pool_alloc();
    ssl->encrypted_input = BIO_new(BIO_s_mem());
    ssl->encrypted_output = BIO_new(BIO_s_mem());

    SSL_set_bio(ssl->ssl, ssl->encrypted_input, ssl->encrypted_output);

    ssl->peer_subject = NULL;
    ssl->peer_issuer_subject = NULL;
    ssl->handshaking = true;

    return ssl;
}

const char *
ssl_filter_get_peer_subject(struct ssl_filter *ssl)
{
    assert(ssl != NULL);

    return ssl->peer_subject;
}

const char *
ssl_filter_get_peer_issuer_subject(struct ssl_filter *ssl)
{
    assert(ssl != NULL);

    return ssl->peer_issuer_subject;
}
<commit_msg>ssl_filter: make is_ssl_error() "pure", not "const"<commit_after>/*
 * SSL and TLS filter.
 *
 * author: Max Kellermann <mk@cm4all.com>
 */

#include "ssl_filter.hxx"
#include "ssl_factory.hxx"
#include "ssl_config.hxx"
#include "ssl_quark.hxx"
#include "thread_socket_filter.hxx"
#include "pool.h"
#include "fifo-buffer.h"
#include "buffered_io.h"
#include "gerrno.h"
#include "fb_pool.h"

#include <openssl/ssl.h>
#include <openssl/err.h>

#include <assert.h>
#include <string.h>

struct ssl_filter {
    /**
     * Buffers which can be accessed from within the thread without
     * holding locks.  These will be copied to/from the accordding
     * #thread_socket_filter buffers.
     */
    struct fifo_buffer *decrypted_input, *plain_output;

    /**
     * Memory BIOs for passing data to/from OpenSSL.
     */
    BIO *encrypted_input, *encrypted_output;

    SSL *ssl;

    bool handshaking;

    char *peer_subject, *peer_issuer_subject;
};

static void
ssl_set_error(GError **error_r)
{
    if (error_r == NULL)
        return;

    unsigned long error = ERR_get_error();
    char buffer[120];
    g_set_error(error_r, ssl_quark(), 0, "%s",
                ERR_error_string(error, buffer));
}

/**
 * Copy data from #src to #dest.
 */
static void
copy_fifo_buffer(struct fifo_buffer *dest, struct fifo_buffer *src)
{
    size_t length;
    const void *s = fifo_buffer_read(src, &length);
    if (s == NULL)
        return;

    size_t max_length;
    void *d = fifo_buffer_write(dest, &max_length);
    if (d == NULL)
        return;

    if (length > max_length)
        length = max_length;

    memcpy(d, s, length);
    fifo_buffer_append(dest, length);
    fifo_buffer_consume(src, length);
}

/**
 * Copy data from #src to #dest.
 */
static void
copy_fifo_buffer_to_bio(BIO *dest, fifo_buffer *src)
{
    size_t length;
    const void *data = fifo_buffer_read(src, &length);
    if (data == nullptr)
        return;

    int nbytes = BIO_write(dest, data, length);
    if (nbytes > 0)
        fifo_buffer_consume(src, nbytes);
}

static void
copy_bio_to_fifo_buffer(fifo_buffer *dest, BIO *src)
{
    while (true) {
        size_t max_length;
        void *data = fifo_buffer_write(dest, &max_length);
        if (data == nullptr)
            return;

        int nbytes = BIO_read(src, data, max_length);
        if (nbytes <= 0)
            return;

        fifo_buffer_append(dest, nbytes);
    }
}

static char *
format_name(X509_NAME *name)
{
    if (name == NULL)
        return NULL;

    BIO *bio = BIO_new(BIO_s_mem());
    if (bio == NULL)
        return NULL;

    X509_NAME_print_ex(bio, name, 0,
                       ASN1_STRFLGS_UTF8_CONVERT | XN_FLAG_SEP_COMMA_PLUS);
    char buffer[1024];
    int length = BIO_read(bio, buffer, sizeof(buffer) - 1);
    BIO_free(bio);

    return strndup(buffer, length);
}

static char *
format_subject_name(X509 *cert)
{
    return format_name(X509_get_subject_name(cert));
}

static char *
format_issuer_subject_name(X509 *cert)
{
    return format_name(X509_get_issuer_name(cert));
}

gcc_pure
static bool
is_ssl_error(SSL *ssl, int ret)
{
    switch (SSL_get_error(ssl, ret)) {
    case SSL_ERROR_NONE:
    case SSL_ERROR_WANT_READ:
    case SSL_ERROR_WANT_WRITE:
    case SSL_ERROR_WANT_CONNECT:
    case SSL_ERROR_WANT_ACCEPT:
        return false;

    default:
        return true;
    }
}

static bool
check_ssl_error(SSL *ssl, int result, GError **error_r)
{
    if (is_ssl_error(ssl, result)) {
        ssl_set_error(error_r);
        return false;
    } else
        return true;
}

/**
 * @return false on error
 */
static bool
ssl_decrypt(SSL *ssl, struct fifo_buffer *buffer, GError **error_r)
{
    /* SSL_read() must be called repeatedly until there is no more
       data (or until the buffer is full) */

    while (true) {
        size_t length;
        void *data = fifo_buffer_write(buffer, &length);
        if (data == NULL)
            return true;

        int result = SSL_read(ssl, data, length);
        if (result <= 0)
            return result == 0 || check_ssl_error(ssl, result, error_r);

        if (result > 0)
            fifo_buffer_append(buffer, result);
    }
}

/**
 * @return false on error
 */
static bool
ssl_encrypt(SSL *ssl, struct fifo_buffer *buffer, GError **error_r)
{
    size_t length;
    const void *data = fifo_buffer_read(buffer, &length);
    if (data == NULL)
        return true;

    int result = SSL_write(ssl, data, length);
    if (result < 0 && !check_ssl_error(ssl, result, error_r))
        return false;

    if (result > 0)
        fifo_buffer_consume(buffer, result);

    return true;
}

/*
 * thread_socket_filter_handler
 *
 */

static bool
ssl_thread_socket_filter_run(ThreadSocketFilter &f, GError **error_r,
                             void *ctx)
{
    struct ssl_filter *ssl = (struct ssl_filter *)ctx;

    /* copy input (and output to make room for more output) */

    pthread_mutex_lock(&f.mutex);
    copy_fifo_buffer(f.decrypted_input, ssl->decrypted_input);
    copy_fifo_buffer(ssl->plain_output, f.plain_output);
    copy_fifo_buffer_to_bio(ssl->encrypted_input, f.encrypted_input);
    copy_bio_to_fifo_buffer(f.encrypted_output, ssl->encrypted_output);
    pthread_mutex_unlock(&f.mutex);

    /* let OpenSSL work */

    ERR_clear_error();

    if (gcc_unlikely(ssl->handshaking)) {
        int result = SSL_do_handshake(ssl->ssl);
        if (result == 1) {
            ssl->handshaking = false;

            X509 *cert = SSL_get_peer_certificate(ssl->ssl);
            if (cert != nullptr) {
                ssl->peer_subject = format_subject_name(cert);
                ssl->peer_issuer_subject = format_issuer_subject_name(cert);
                X509_free(cert);
            }
        } else if (result == 0) {
            ssl_set_error(error_r);
            return false;
        } else if (!check_ssl_error(ssl->ssl, result, error_r))
            return false;
    }

    if (gcc_likely(!ssl->handshaking) &&
        (!ssl_encrypt(ssl->ssl, ssl->plain_output, error_r) ||
         !ssl_decrypt(ssl->ssl, ssl->decrypted_input, error_r)))
        return false;

    /* copy output */

    pthread_mutex_lock(&f.mutex);
    copy_fifo_buffer(f.decrypted_input, ssl->decrypted_input);
    copy_bio_to_fifo_buffer(f.encrypted_output, ssl->encrypted_output);
    f.drained = fifo_buffer_empty(ssl->plain_output) &&
        BIO_eof(ssl->encrypted_output);
    pthread_mutex_unlock(&f.mutex);

    return true;
}

static void
ssl_thread_socket_filter_destroy(gcc_unused ThreadSocketFilter &f, void *ctx)
{
    struct ssl_filter *ssl = (struct ssl_filter *)ctx;

    if (ssl->ssl != NULL)
        SSL_free(ssl->ssl);

    fb_pool_free(ssl->decrypted_input);
    fb_pool_free(ssl->plain_output);

    free(ssl->peer_subject);
    free(ssl->peer_issuer_subject);
}

const struct ThreadSocketFilterHandler ssl_thread_socket_filter = {
    ssl_thread_socket_filter_run,
    ssl_thread_socket_filter_destroy,
};

/*
 * constructor
 *
 */

struct ssl_filter *
ssl_filter_new(struct pool *pool, ssl_factory &factory,
               GError **error_r)
{
    assert(pool != NULL);

    ssl_filter *ssl = NewFromPool<ssl_filter>(pool);

    ssl->ssl = ssl_factory_make(factory);
    if (ssl->ssl == NULL) {
        g_set_error(error_r, ssl_quark(), 0, "SSL_new() failed");
        return NULL;
    }

    ssl->decrypted_input = fb_pool_alloc();
    ssl->plain_output = fb_pool_alloc();
    ssl->encrypted_input = BIO_new(BIO_s_mem());
    ssl->encrypted_output = BIO_new(BIO_s_mem());

    SSL_set_bio(ssl->ssl, ssl->encrypted_input, ssl->encrypted_output);

    ssl->peer_subject = NULL;
    ssl->peer_issuer_subject = NULL;
    ssl->handshaking = true;

    return ssl;
}

const char *
ssl_filter_get_peer_subject(struct ssl_filter *ssl)
{
    assert(ssl != NULL);

    return ssl->peer_subject;
}

const char *
ssl_filter_get_peer_issuer_subject(struct ssl_filter *ssl)
{
    assert(ssl != NULL);

    return ssl->peer_issuer_subject;
}
<|endoftext|>


<commit_before>// Copyright Daniel Wallin 2006. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#include <libtorrent/session.hpp>
#include <boost/python.hpp>

using namespace boost::python;
using namespace libtorrent;

void bind_session_settings()
{
    class_<session_settings>("session_settings")
        .def_readwrite("user_agent", &session_settings::user_agent)
        .def_readwrite("tracker_completion_timeout", &session_settings::tracker_completion_timeout)
        .def_readwrite("tracker_receive_timeout", &session_settings::tracker_receive_timeout)
        .def_readwrite("tracker_maximum_response_length", &session_settings::tracker_maximum_response_length)
        .def_readwrite("piece_timeout", &session_settings::piece_timeout)
        .def_readwrite("request_queue_time", &session_settings::request_queue_time)
        .def_readwrite("max_allowed_in_request_queue", &session_settings::max_allowed_in_request_queue)
        .def_readwrite("max_out_request_queue", &session_settings::max_out_request_queue)
        .def_readwrite("whole_pieces_threshold", &session_settings::whole_pieces_threshold)
        .def_readwrite("peer_timeout", &session_settings::peer_timeout)
        .def_readwrite("urlseed_timeout", &session_settings::urlseed_timeout)
        .def_readwrite("urlseed_pipeline_size", &session_settings::urlseed_pipeline_size)
        .def_readwrite("file_pool_size", &session_settings::file_pool_size)
        .def_readwrite("allow_multiple_connections_per_ip", &session_settings::allow_multiple_connections_per_ip)
        .def_readwrite("max_failcount", &session_settings::max_failcount)
        .def_readwrite("min_reconnect_time", &session_settings::min_reconnect_time)
        .def_readwrite("peer_connect_timeout", &session_settings::peer_connect_timeout)
        .def_readwrite("ignore_limits_on_local_network", &session_settings::ignore_limits_on_local_network)
        .def_readwrite("connection_speed", &session_settings::connection_speed)
        .def_readwrite("send_redundant_have", &session_settings::send_redundant_have)
        .def_readwrite("lazy_bitfields", &session_settings::lazy_bitfields)
        .def_readwrite("inactivity_timeout", &session_settings::inactivity_timeout)
        .def_readwrite("unchoke_interval", &session_settings::unchoke_interval)
        .def_readwrite("active_downloads", &session_settings::active_downloads)
        .def_readwrite("active_seeds", &session_settings::active_seeds)
        .def_readwrite("auto_manage_interval", &session_settings::auto_manage_interval)
        .def_readwrite("share_ratio_limit", &session_settings::share_ratio_limit)
        .def_readwrite("seed_time_ratio_limit", &session_settings::seed_time_ratio_limit)
        .def_readwrite("seed_time_limit", &session_settings::seed_time_limit)
        .def_readwrite("auto_scraped_interval", &session_settings::auto_scrape_interval)
#ifndef TORRENT_DISABLE_DHT
        .def_readwrite("use_dht_as_fallback", &session_settings::use_dht_as_fallback)
#endif
    ;

    enum_<proxy_settings::proxy_type>("proxy_type")
        .value("none", proxy_settings::none)
        .value("socks4", proxy_settings::socks4)
        .value("socks5", proxy_settings::socks5)
        .value("socks5_pw", proxy_settings::socks5_pw)
        .value("http", proxy_settings::http)
        .value("http_pw", proxy_settings::http_pw)
    ;
    class_<proxy_settings>("proxy_settings")
        .def_readwrite("hostname", &proxy_settings::hostname)
        .def_readwrite("port", &proxy_settings::port)
        .def_readwrite("password", &proxy_settings::password)
        .def_readwrite("username", &proxy_settings::username)
        .def_readwrite("type", &proxy_settings::type)
    ;

#ifndef TORRENT_DISABLE_ENCRYPTION
    enum_<pe_settings::enc_policy>("enc_policy")
        .value("forced", pe_settings::forced)
        .value("enabled", pe_settings::enabled)
        .value("disabled", pe_settings::disabled)
    ;

    enum_<pe_settings::enc_level>("enc_level")
        .value("rc4", pe_settings::rc4)
        .value("plaintext", pe_settings::plaintext)
        .value("both", pe_settings::both)
    ;

    class_<pe_settings>("pe_settings")
        .def_readwrite("out_enc_policy", &pe_settings::out_enc_policy)
        .def_readwrite("in_enc_policy", &pe_settings::in_enc_policy)
        .def_readwrite("allowed_enc_level", &pe_settings::allowed_enc_level)
        .def_readwrite("prefer_rc4", &pe_settings::prefer_rc4)
    ;
#endif

}

<commit_msg>Update queue settings<commit_after>// Copyright Daniel Wallin 2006. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#include <libtorrent/session.hpp>
#include <boost/python.hpp>

using namespace boost::python;
using namespace libtorrent;

void bind_session_settings()
{
    class_<session_settings>("session_settings")
        .def_readwrite("user_agent", &session_settings::user_agent)
        .def_readwrite("tracker_completion_timeout", &session_settings::tracker_completion_timeout)
        .def_readwrite("tracker_receive_timeout", &session_settings::tracker_receive_timeout)
        .def_readwrite("tracker_maximum_response_length", &session_settings::tracker_maximum_response_length)
        .def_readwrite("piece_timeout", &session_settings::piece_timeout)
        .def_readwrite("request_queue_time", &session_settings::request_queue_time)
        .def_readwrite("max_allowed_in_request_queue", &session_settings::max_allowed_in_request_queue)
        .def_readwrite("max_out_request_queue", &session_settings::max_out_request_queue)
        .def_readwrite("whole_pieces_threshold", &session_settings::whole_pieces_threshold)
        .def_readwrite("peer_timeout", &session_settings::peer_timeout)
        .def_readwrite("urlseed_timeout", &session_settings::urlseed_timeout)
        .def_readwrite("urlseed_pipeline_size", &session_settings::urlseed_pipeline_size)
        .def_readwrite("file_pool_size", &session_settings::file_pool_size)
        .def_readwrite("allow_multiple_connections_per_ip", &session_settings::allow_multiple_connections_per_ip)
        .def_readwrite("max_failcount", &session_settings::max_failcount)
        .def_readwrite("min_reconnect_time", &session_settings::min_reconnect_time)
        .def_readwrite("peer_connect_timeout", &session_settings::peer_connect_timeout)
        .def_readwrite("ignore_limits_on_local_network", &session_settings::ignore_limits_on_local_network)
        .def_readwrite("connection_speed", &session_settings::connection_speed)
        .def_readwrite("send_redundant_have", &session_settings::send_redundant_have)
        .def_readwrite("lazy_bitfields", &session_settings::lazy_bitfields)
        .def_readwrite("inactivity_timeout", &session_settings::inactivity_timeout)
        .def_readwrite("unchoke_interval", &session_settings::unchoke_interval)
        .def_readwrite("active_downloads", &session_settings::active_downloads)
        .def_readwrite("active_seeds", &session_settings::active_seeds)
        .def_readwrite("active_limit", &session_settings::active_limit)
        .def_readwrite("dont_count_slow_torrents", &session_settings::dont_count_slow_torrents)
        .def_readwrite("auto_manage_interval", &session_settings::auto_manage_interval)
        .def_readwrite("share_ratio_limit", &session_settings::share_ratio_limit)
        .def_readwrite("seed_time_ratio_limit", &session_settings::seed_time_ratio_limit)
        .def_readwrite("seed_time_limit", &session_settings::seed_time_limit)
        .def_readwrite("auto_scraped_interval", &session_settings::auto_scrape_interval)
#ifndef TORRENT_DISABLE_DHT
        .def_readwrite("use_dht_as_fallback", &session_settings::use_dht_as_fallback)
#endif
    ;

    enum_<proxy_settings::proxy_type>("proxy_type")
        .value("none", proxy_settings::none)
        .value("socks4", proxy_settings::socks4)
        .value("socks5", proxy_settings::socks5)
        .value("socks5_pw", proxy_settings::socks5_pw)
        .value("http", proxy_settings::http)
        .value("http_pw", proxy_settings::http_pw)
    ;
    class_<proxy_settings>("proxy_settings")
        .def_readwrite("hostname", &proxy_settings::hostname)
        .def_readwrite("port", &proxy_settings::port)
        .def_readwrite("password", &proxy_settings::password)
        .def_readwrite("username", &proxy_settings::username)
        .def_readwrite("type", &proxy_settings::type)
    ;

#ifndef TORRENT_DISABLE_ENCRYPTION
    enum_<pe_settings::enc_policy>("enc_policy")
        .value("forced", pe_settings::forced)
        .value("enabled", pe_settings::enabled)
        .value("disabled", pe_settings::disabled)
    ;

    enum_<pe_settings::enc_level>("enc_level")
        .value("rc4", pe_settings::rc4)
        .value("plaintext", pe_settings::plaintext)
        .value("both", pe_settings::both)
    ;

    class_<pe_settings>("pe_settings")
        .def_readwrite("out_enc_policy", &pe_settings::out_enc_policy)
        .def_readwrite("in_enc_policy", &pe_settings::in_enc_policy)
        .def_readwrite("allowed_enc_level", &pe_settings::allowed_enc_level)
        .def_readwrite("prefer_rc4", &pe_settings::prefer_rc4)
    ;
#endif

}

<|endoftext|>