<commit_before>/* This file is part of QJson
 *
 * Copyright (C) 2008 Flavio Castelli <flavio.castelli@gmail.com>
 * Copyright (C) 2013 Silvio Moioli <silvio@moioli.net>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License version 2.1, as published by the Free Software Foundation.
 *
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */
#include "json_scanner.cc"

#include "qjson_debug.h"
#include "json_scanner.h"
#include "json_parser.hh"

#include <ctype.h>

#include <QtCore/QDebug>
#include <QtCore/QRegExp>

#include <cassert>

JSonScanner::JSonScanner(QIODevice* io)
  : m_allowSpecialNumbers(false),
    m_io (io),
    m_criticalError(false)
{
}

void JSonScanner::allowSpecialNumbers(bool allow) {
  m_allowSpecialNumbers = allow;
}

int JSonScanner::yylex(YYSTYPE* yylval, yy::location *yylloc) {
  m_yylval = yylval;
  m_yylloc = yylloc;
  m_yylloc->step();
  int result = yylex();

  if (m_criticalError) {
    return -1;
  }

  return result;
}

int JSonScanner::LexerInput(char* buf, int max_size) {
  if (!m_io->isOpen()) {
    qCritical() << "JSonScanner::yylex - io device is not open";
    m_criticalError = true;
    return 0;
  }

  int readBytes = m_io->read(buf, max_size);
  if(readBytes < 0) {
    qCritical() << "JSonScanner::yylex - error while reading from io device";
    m_criticalError = true;
    return 0;
  }

  return readBytes;
}

<commit_msg>Removed some errant whitespace<commit_after>/* This file is part of QJson
 *
 * Copyright (C) 2008 Flavio Castelli <flavio.castelli@gmail.com>
 * Copyright (C) 2013 Silvio Moioli <silvio@moioli.net>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License version 2.1, as published by the Free Software Foundation.
 *
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */
#include "json_scanner.cc"

#include "qjson_debug.h"
#include "json_scanner.h"
#include "json_parser.hh"

#include <ctype.h>

#include <QtCore/QDebug>
#include <QtCore/QRegExp>

#include <cassert>

JSonScanner::JSonScanner(QIODevice* io)
  : m_allowSpecialNumbers(false),
    m_io (io),
    m_criticalError(false)
{
}

void JSonScanner::allowSpecialNumbers(bool allow) {
  m_allowSpecialNumbers = allow;
}

int JSonScanner::yylex(YYSTYPE* yylval, yy::location *yylloc) {
  m_yylval = yylval;
  m_yylloc = yylloc;
  m_yylloc->step();
  int result = yylex();

  if (m_criticalError) {
    return -1;
  }

  return result;
}

int JSonScanner::LexerInput(char* buf, int max_size) {
  if (!m_io->isOpen()) {
    qCritical() << "JSonScanner::yylex - io device is not open";
    m_criticalError = true;
    return 0;
  }

  int readBytes = m_io->read(buf, max_size);
  if(readBytes < 0) {
    qCritical() << "JSonScanner::yylex - error while reading from io device";
    m_criticalError = true;
    return 0;
  }

  return readBytes;
}

<|endoftext|>


<commit_before>/*M///////////////////////////////////////////////////////////////////////////////////////
//
//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
//  By downloading, copying, installing or using the software you agree to this license.
//  If you do not agree to this license, do not download, install,
//  copy or use the software.
//
//
//                        Intel License Agreement
//                For Open Source Computer Vision Library
//
// Copyright( C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistribution's of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//
//   * Redistribution's in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//
//   * The name of Intel Corporation may not be used to endorse or promote products
//     derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
//(including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort(including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/

/*
  definition of the current version of OpenCV
  Usefull to test in user programs
*/

#ifndef __OPENCV_VERSION_HPP__
#define __OPENCV_VERSION_HPP__

#define CV_VERSION_EPOCH    2
#define CV_VERSION_MAJOR    4
#define CV_VERSION_MINOR    12
#define CV_VERSION_REVISION 1

#define CVAUX_STR_EXP(__A)  #__A
#define CVAUX_STR(__A)      CVAUX_STR_EXP(__A)

#define CVAUX_STRW_EXP(__A)  L#__A
#define CVAUX_STRW(__A)      CVAUX_STRW_EXP(__A)

#if CV_VERSION_REVISION
#  define CV_VERSION        CVAUX_STR(CV_VERSION_EPOCH) "." CVAUX_STR(CV_VERSION_MAJOR) "." CVAUX_STR(CV_VERSION_MINOR) "." CVAUX_STR(CV_VERSION_REVISION)
#else
#  define CV_VERSION        CVAUX_STR(CV_VERSION_EPOCH) "." CVAUX_STR(CV_VERSION_MAJOR) "." CVAUX_STR(CV_VERSION_MINOR)
#endif

/* old  style version constants*/
#define CV_MAJOR_VERSION    CV_VERSION_EPOCH
#define CV_MINOR_VERSION    CV_VERSION_MAJOR
#define CV_SUBMINOR_VERSION CV_VERSION_MINOR

#endif
<commit_msg>OpenCV version++.<commit_after>/*M///////////////////////////////////////////////////////////////////////////////////////
//
//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
//  By downloading, copying, installing or using the software you agree to this license.
//  If you do not agree to this license, do not download, install,
//  copy or use the software.
//
//
//                        Intel License Agreement
//                For Open Source Computer Vision Library
//
// Copyright( C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistribution's of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//
//   * Redistribution's in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//
//   * The name of Intel Corporation may not be used to endorse or promote products
//     derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
//(including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort(including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/

/*
  definition of the current version of OpenCV
  Usefull to test in user programs
*/

#ifndef __OPENCV_VERSION_HPP__
#define __OPENCV_VERSION_HPP__

#define CV_VERSION_EPOCH    2
#define CV_VERSION_MAJOR    4
#define CV_VERSION_MINOR    12
#define CV_VERSION_REVISION 2

#define CVAUX_STR_EXP(__A)  #__A
#define CVAUX_STR(__A)      CVAUX_STR_EXP(__A)

#define CVAUX_STRW_EXP(__A)  L#__A
#define CVAUX_STRW(__A)      CVAUX_STRW_EXP(__A)

#if CV_VERSION_REVISION
#  define CV_VERSION        CVAUX_STR(CV_VERSION_EPOCH) "." CVAUX_STR(CV_VERSION_MAJOR) "." CVAUX_STR(CV_VERSION_MINOR) "." CVAUX_STR(CV_VERSION_REVISION)
#else
#  define CV_VERSION        CVAUX_STR(CV_VERSION_EPOCH) "." CVAUX_STR(CV_VERSION_MAJOR) "." CVAUX_STR(CV_VERSION_MINOR)
#endif

/* old  style version constants*/
#define CV_MAJOR_VERSION    CV_VERSION_EPOCH
#define CV_MINOR_VERSION    CV_VERSION_MAJOR
#define CV_SUBMINOR_VERSION CV_VERSION_MINOR

#endif
<|endoftext|>


<commit_before>// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
//
// Copyright (C) 2018 Intel Corporation

#include "precomp.hpp"

#include <functional>
#include <unordered_set>

#include <ade/util/algorithm.hpp>

#include <ade/util/range.hpp>
#include <ade/util/zip_range.hpp>
#include <ade/util/chain_range.hpp>

#include <ade/typed_graph.hpp>

#include "opencv2/gapi/gcommon.hpp"
#include "opencv2/gapi/util/any.hpp"
#include "opencv2/gapi/gtype_traits.hpp"

#include "compiler/gobjref.hpp"
#include "compiler/gmodel.hpp"

#include "backends/ocl/goclbackend.hpp"
#include "backends/ocl/goclimgproc.hpp"
#include "backends/ocl/goclcore.hpp"

#include "api/gbackend_priv.hpp" // FIXME: Make it part of Backend SDK!

// FIXME: Is there a way to take a typed graph (our GModel),
// and create a new typed graph _ATOP_ of that (by extending with a couple of
// new types?).
// Alternatively, is there a way to compose types graphs?
//
// If not, we need to introduce that!
using GOCLModel = ade::TypedGraph
    < cv::gimpl::Unit
    , cv::gimpl::Protocol
    >;

// FIXME: Same issue with Typed and ConstTyped
using GConstGOCLModel = ade::ConstTypedGraph
    < cv::gimpl::Unit
    , cv::gimpl::Protocol
    >;

namespace
{
    class GOCLBackendImpl final: public cv::gapi::GBackend::Priv
    {
        virtual void unpackKernel(ade::Graph            &graph,
                                  const ade::NodeHandle &op_node,
                                  const cv::GKernelImpl &impl) override
        {
            GOCLModel gm(graph);
            auto ocl_impl = cv::util::any_cast<cv::GOCLKernel>(impl.opaque);
            gm.metadata(op_node).set(cv::gimpl::Unit{ocl_impl});
        }

        virtual EPtr compile(const ade::Graph &graph,
                             const cv::GCompileArgs &,
                             const std::vector<ade::NodeHandle> &nodes) const override
        {
            return EPtr{new cv::gimpl::GOCLExecutable(graph, nodes)};
        }
   };
}

cv::gapi::GBackend cv::gapi::ocl::backend()
{
    static cv::gapi::GBackend this_backend(std::make_shared<GOCLBackendImpl>());
    return this_backend;
}

// GOCLExcecutable implementation //////////////////////////////////////////////
cv::gimpl::GOCLExecutable::GOCLExecutable(const ade::Graph &g,
                                          const std::vector<ade::NodeHandle> &nodes)
    : m_g(g), m_gm(m_g)
{
    // Convert list of operations (which is topologically sorted already)
    // into an execution script.
    for (auto &nh : nodes)
    {
        switch (m_gm.metadata(nh).get<NodeType>().t)
        {
        case NodeType::OP: m_script.push_back({nh, GModel::collectOutputMeta(m_gm, nh)}); break;
        case NodeType::DATA:
        {
            m_dataNodes.push_back(nh);
            const auto &desc = m_gm.metadata(nh).get<Data>();
            if (desc.storage == Data::Storage::CONST)
            {
                auto rc = RcDesc{desc.rc, desc.shape, desc.ctor};
                magazine::bindInArg(m_res, rc, m_gm.metadata(nh).get<ConstValue>().arg);
            }
            //preallocate internal Mats in advance
            if (desc.storage == Data::Storage::INTERNAL && desc.shape == GShape::GMAT)
            {
                const auto mat_desc = util::get<cv::GMatDesc>(desc.meta);
                const auto type = CV_MAKETYPE(mat_desc.depth, mat_desc.chan);
                m_res.slot<cv::UMat>()[desc.rc].create(mat_desc.size.width, mat_desc.size.height, type);
            }
            break;
        }
        default: util::throw_error(std::logic_error("Unsupported NodeType type"));
        }
    }
}

// FIXME: Document what it does
cv::GArg cv::gimpl::GOCLExecutable::packArg(const GArg &arg)
{
    // No API placeholders allowed at this point
    // FIXME: this check has to be done somewhere in compilation stage.
    GAPI_Assert(   arg.kind != cv::detail::ArgKind::GMAT
              && arg.kind != cv::detail::ArgKind::GSCALAR
              && arg.kind != cv::detail::ArgKind::GARRAY);

    if (arg.kind != cv::detail::ArgKind::GOBJREF)
    {
        // All other cases - pass as-is, with no transformations to GArg contents.
        return arg;
    }
    GAPI_Assert(arg.kind == cv::detail::ArgKind::GOBJREF);

    // Wrap associated CPU object (either host or an internal one)
    // FIXME: object can be moved out!!! GExecutor faced that.
    const cv::gimpl::RcDesc &ref = arg.get<cv::gimpl::RcDesc>();
    switch (ref.shape)
    {
    case GShape::GMAT:    return GArg(m_res.slot<cv::UMat>()[ref.id]);
    case GShape::GSCALAR: return GArg(m_res.slot<cv::gapi::own::Scalar>()[ref.id]);
        // Note: .at() is intentional for GArray as object MUST be already there
    //   (and constructed by either bindIn/Out or resetInternal)
    case GShape::GARRAY:  return GArg(m_res.slot<cv::detail::VectorRef>().at(ref.id));
    default:
        util::throw_error(std::logic_error("Unsupported GShape type"));
        break;
    }
}

void cv::gimpl::GOCLExecutable::run(std::vector<InObj>  &&input_objs,
                                    std::vector<OutObj> &&output_objs)
{
    // Update resources with run-time information - what this Island
    // has received from user (or from another Island, or mix...)
    // FIXME: Check input/output objects against GIsland protocol

    for (auto& it : input_objs)   magazine::bindInArg (m_res, it.first, it.second, true);
    for (auto& it : output_objs)  magazine::bindOutArg(m_res, it.first, it.second, true);

    // Initialize (reset) internal data nodes with user structures
    // before processing a frame (no need to do it for external data structures)
    GModel::ConstGraph gm(m_g);
    for (auto nh : m_dataNodes)
    {
        const auto &desc = gm.metadata(nh).get<Data>();

        if (   desc.storage == Data::Storage::INTERNAL
            && !util::holds_alternative<util::monostate>(desc.ctor))
        {
            // FIXME: Note that compile-time constant data objects (like
            // a value-initialized GArray<T>) also satisfy this condition
            // and should be excluded, but now we just don't support it
            magazine::resetInternalData(m_res, desc);
        }
    }

    // OpenCV backend execution is not a rocket science at all.
    // Simply invoke our kernels in the proper order.
    GConstGOCLModel gcm(m_g);
    for (auto &op_info : m_script)
    {
        const auto &op = m_gm.metadata(op_info.nh).get<Op>();

        // Obtain our real execution unit
        // TODO: Should kernels be copyable?
        GOCLKernel k = gcm.metadata(op_info.nh).get<Unit>().k;

        // Initialize kernel's execution context:
        // - Input parameters
        GOCLContext context;
        context.m_args.reserve(op.args.size());

        using namespace std::placeholders;
        ade::util::transform(op.args,
                          std::back_inserter(context.m_args),
                          std::bind(&GOCLExecutable::packArg, this, _1));

        // - Output parameters.
        // FIXME: pre-allocate internal Mats, etc, according to the known meta
        for (const auto &out_it : ade::util::indexed(op.outs))
        {
            // FIXME: Can the same GArg type resolution mechanism be reused here?
            const auto out_port  = ade::util::index(out_it);
            const auto out_desc  = ade::util::value(out_it);
            context.m_results[out_port] = magazine::getObjPtr(m_res, out_desc, true);
        }

        // Now trigger the executable unit
        k.apply(context);

        for (const auto &out_it : ade::util::indexed(op_info.expected_out_metas))
        {
            const auto out_index      = ade::util::index(out_it);
            const auto expected_meta  = ade::util::value(out_it);
            const auto out_meta       = descr_of(context.m_results[out_index]);

            if (expected_meta != out_meta)
            {
                util::throw_error
                    (std::logic_error
                     ("Output meta doesn't "
                      "coincide with the generated meta\n"
                      "Expected: " + ade::util::to_string(expected_meta) + "\n"
                      "Actual  : " + ade::util::to_string(out_meta)));
            }
        }
    } // for(m_script)

    for (auto &it : output_objs) magazine::writeBack(m_res, it.first, it.second, true);
}
<commit_msg>fix size<commit_after>// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
//
// Copyright (C) 2018 Intel Corporation

#include "precomp.hpp"

#include <functional>
#include <unordered_set>

#include <ade/util/algorithm.hpp>

#include <ade/util/range.hpp>
#include <ade/util/zip_range.hpp>
#include <ade/util/chain_range.hpp>

#include <ade/typed_graph.hpp>

#include "opencv2/gapi/gcommon.hpp"
#include "opencv2/gapi/util/any.hpp"
#include "opencv2/gapi/gtype_traits.hpp"

#include "compiler/gobjref.hpp"
#include "compiler/gmodel.hpp"

#include "backends/ocl/goclbackend.hpp"
#include "backends/ocl/goclimgproc.hpp"
#include "backends/ocl/goclcore.hpp"

#include "api/gbackend_priv.hpp" // FIXME: Make it part of Backend SDK!

// FIXME: Is there a way to take a typed graph (our GModel),
// and create a new typed graph _ATOP_ of that (by extending with a couple of
// new types?).
// Alternatively, is there a way to compose types graphs?
//
// If not, we need to introduce that!
using GOCLModel = ade::TypedGraph
    < cv::gimpl::Unit
    , cv::gimpl::Protocol
    >;

// FIXME: Same issue with Typed and ConstTyped
using GConstGOCLModel = ade::ConstTypedGraph
    < cv::gimpl::Unit
    , cv::gimpl::Protocol
    >;

namespace
{
    class GOCLBackendImpl final: public cv::gapi::GBackend::Priv
    {
        virtual void unpackKernel(ade::Graph            &graph,
                                  const ade::NodeHandle &op_node,
                                  const cv::GKernelImpl &impl) override
        {
            GOCLModel gm(graph);
            auto ocl_impl = cv::util::any_cast<cv::GOCLKernel>(impl.opaque);
            gm.metadata(op_node).set(cv::gimpl::Unit{ocl_impl});
        }

        virtual EPtr compile(const ade::Graph &graph,
                             const cv::GCompileArgs &,
                             const std::vector<ade::NodeHandle> &nodes) const override
        {
            return EPtr{new cv::gimpl::GOCLExecutable(graph, nodes)};
        }
   };
}

cv::gapi::GBackend cv::gapi::ocl::backend()
{
    static cv::gapi::GBackend this_backend(std::make_shared<GOCLBackendImpl>());
    return this_backend;
}

// GOCLExcecutable implementation //////////////////////////////////////////////
cv::gimpl::GOCLExecutable::GOCLExecutable(const ade::Graph &g,
                                          const std::vector<ade::NodeHandle> &nodes)
    : m_g(g), m_gm(m_g)
{
    // Convert list of operations (which is topologically sorted already)
    // into an execution script.
    for (auto &nh : nodes)
    {
        switch (m_gm.metadata(nh).get<NodeType>().t)
        {
        case NodeType::OP: m_script.push_back({nh, GModel::collectOutputMeta(m_gm, nh)}); break;
        case NodeType::DATA:
        {
            m_dataNodes.push_back(nh);
            const auto &desc = m_gm.metadata(nh).get<Data>();
            if (desc.storage == Data::Storage::CONST)
            {
                auto rc = RcDesc{desc.rc, desc.shape, desc.ctor};
                magazine::bindInArg(m_res, rc, m_gm.metadata(nh).get<ConstValue>().arg);
            }
            //preallocate internal Mats in advance
            if (desc.storage == Data::Storage::INTERNAL && desc.shape == GShape::GMAT)
            {
                const auto mat_desc = util::get<cv::GMatDesc>(desc.meta);
                const auto type = CV_MAKETYPE(mat_desc.depth, mat_desc.chan);
                m_res.slot<cv::UMat>()[desc.rc].create(mat_desc.size.height, mat_desc.size.width, type);
            }
            break;
        }
        default: util::throw_error(std::logic_error("Unsupported NodeType type"));
        }
    }
}

// FIXME: Document what it does
cv::GArg cv::gimpl::GOCLExecutable::packArg(const GArg &arg)
{
    // No API placeholders allowed at this point
    // FIXME: this check has to be done somewhere in compilation stage.
    GAPI_Assert(   arg.kind != cv::detail::ArgKind::GMAT
              && arg.kind != cv::detail::ArgKind::GSCALAR
              && arg.kind != cv::detail::ArgKind::GARRAY);

    if (arg.kind != cv::detail::ArgKind::GOBJREF)
    {
        // All other cases - pass as-is, with no transformations to GArg contents.
        return arg;
    }
    GAPI_Assert(arg.kind == cv::detail::ArgKind::GOBJREF);

    // Wrap associated CPU object (either host or an internal one)
    // FIXME: object can be moved out!!! GExecutor faced that.
    const cv::gimpl::RcDesc &ref = arg.get<cv::gimpl::RcDesc>();
    switch (ref.shape)
    {
    case GShape::GMAT:    return GArg(m_res.slot<cv::UMat>()[ref.id]);
    case GShape::GSCALAR: return GArg(m_res.slot<cv::gapi::own::Scalar>()[ref.id]);
        // Note: .at() is intentional for GArray as object MUST be already there
    //   (and constructed by either bindIn/Out or resetInternal)
    case GShape::GARRAY:  return GArg(m_res.slot<cv::detail::VectorRef>().at(ref.id));
    default:
        util::throw_error(std::logic_error("Unsupported GShape type"));
        break;
    }
}

void cv::gimpl::GOCLExecutable::run(std::vector<InObj>  &&input_objs,
                                    std::vector<OutObj> &&output_objs)
{
    // Update resources with run-time information - what this Island
    // has received from user (or from another Island, or mix...)
    // FIXME: Check input/output objects against GIsland protocol

    for (auto& it : input_objs)   magazine::bindInArg (m_res, it.first, it.second, true);
    for (auto& it : output_objs)  magazine::bindOutArg(m_res, it.first, it.second, true);

    // Initialize (reset) internal data nodes with user structures
    // before processing a frame (no need to do it for external data structures)
    GModel::ConstGraph gm(m_g);
    for (auto nh : m_dataNodes)
    {
        const auto &desc = gm.metadata(nh).get<Data>();

        if (   desc.storage == Data::Storage::INTERNAL
            && !util::holds_alternative<util::monostate>(desc.ctor))
        {
            // FIXME: Note that compile-time constant data objects (like
            // a value-initialized GArray<T>) also satisfy this condition
            // and should be excluded, but now we just don't support it
            magazine::resetInternalData(m_res, desc);
        }
    }

    // OpenCV backend execution is not a rocket science at all.
    // Simply invoke our kernels in the proper order.
    GConstGOCLModel gcm(m_g);
    for (auto &op_info : m_script)
    {
        const auto &op = m_gm.metadata(op_info.nh).get<Op>();

        // Obtain our real execution unit
        // TODO: Should kernels be copyable?
        GOCLKernel k = gcm.metadata(op_info.nh).get<Unit>().k;

        // Initialize kernel's execution context:
        // - Input parameters
        GOCLContext context;
        context.m_args.reserve(op.args.size());

        using namespace std::placeholders;
        ade::util::transform(op.args,
                          std::back_inserter(context.m_args),
                          std::bind(&GOCLExecutable::packArg, this, _1));

        // - Output parameters.
        // FIXME: pre-allocate internal Mats, etc, according to the known meta
        for (const auto &out_it : ade::util::indexed(op.outs))
        {
            // FIXME: Can the same GArg type resolution mechanism be reused here?
            const auto out_port  = ade::util::index(out_it);
            const auto out_desc  = ade::util::value(out_it);
            context.m_results[out_port] = magazine::getObjPtr(m_res, out_desc, true);
        }

        // Now trigger the executable unit
        k.apply(context);

        for (const auto &out_it : ade::util::indexed(op_info.expected_out_metas))
        {
            const auto out_index      = ade::util::index(out_it);
            const auto expected_meta  = ade::util::value(out_it);
            const auto out_meta       = descr_of(context.m_results[out_index]);

            if (expected_meta != out_meta)
            {
                util::throw_error
                    (std::logic_error
                     ("Output meta doesn't "
                      "coincide with the generated meta\n"
                      "Expected: " + ade::util::to_string(expected_meta) + "\n"
                      "Actual  : " + ade::util::to_string(out_meta)));
            }
        }
    } // for(m_script)

    for (auto &it : output_objs) magazine::writeBack(m_res, it.first, it.second, true);
}
<|endoftext|>


<commit_before>/*

Copyright (c) 2008, Arvid Norberg
All rights reserved.

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

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

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

*/

#include "libtorrent/lazy_entry.hpp"
#include <iostream>
#include <iomanip>

namespace libtorrent
{
	int fail_bdecode() { return -1; }

	// fills in 'val' with what the string between start and the
	// first occurance of the delimiter is interpreted as an int.
	// return the pointer to the delimiter, or 0 if there is a
	// parse error. val should be initialized to zero
	char* parse_int(char* start, char* end, char delimiter, boost::int64_t& val)
	{
		while (start < end && *start != delimiter)
		{
			using namespace std;
			if (!isdigit(*start)) { fail_bdecode(); return 0; }
			val *= 10;
			val += *start - '0';
			++start;
		}
		return start;
	}

	char* find_char(char* start, char* end, char delimiter)
	{
		while (start < end && *start != delimiter) ++start;
		return start;
	}

	// return 0 = success
	int lazy_bdecode(char* start, char* end, lazy_entry& ret, int depth_limit)
	{
		ret.clear();
		if (start == end) return 0;

		std::vector<lazy_entry*> stack;

		stack.push_back(&ret);
		while (start < end)
		{
			if (stack.empty()) break; // done!

			lazy_entry* top = stack.back();

			if (stack.size() > depth_limit) return fail_bdecode();
			if (start == end) return fail_bdecode();
			char t = *start;
			*start++ = 0; // null terminate any previous string
			if (start == end && t != 'e') return fail_bdecode();

			switch (top->type())
			{
				case lazy_entry::dict_t:
				{
					if (t == 'e')
					{
						stack.pop_back();
						continue;
					}
					boost::int64_t len = t - '0';
					start = parse_int(start, end, ':', len);
					if (start == 0 || start + len + 3 > end || *start != ':') return fail_bdecode();
					++start;
					lazy_entry* ent = top->dict_append(start);
					start += len;
					stack.push_back(ent);
					t = *start;
					*start++ = 0; // null terminate any previous string
					break;
				}
				case lazy_entry::list_t:
				{
					if (t == 'e')
					{
						stack.pop_back();
						continue;
					}
					lazy_entry* ent = top->list_append();
					stack.push_back(ent);
					break;
				}
				default: break;
			}

			top = stack.back();
			switch (t)
			{
				case 'd':
					top->construct_dict();
					continue;
				case 'l':
					top->construct_list();
					continue;
				case 'i':
					top->construct_int(start);
					start = find_char(start, end, 'e');
					if (start == end) return fail_bdecode();
					TORRENT_ASSERT(*start == 'e');
					*start++ = 0;
					stack.pop_back();
					continue;
				default:
				{
					using namespace std;
					if (!isdigit(t)) return fail_bdecode();

					boost::int64_t len = t - '0';
					start = parse_int(start, end, ':', len);
					if (start == 0 || start + len + 1 > end || *start != ':') return fail_bdecode();
					++start;
					top->construct_string(start, int(len));
					stack.pop_back();
					start += len;
					continue;
				}
			}
			return 0;
		}
		return 0;
	}

	boost::int64_t lazy_entry::int_value() const
	{
		TORRENT_ASSERT(m_type == int_t);
		boost::int64_t val = 0;
		bool negative = false;
		if (*m_data.start == '-') negative = true;
		parse_int(negative?m_data.start+1:m_data.start, m_data.start + 100, 0, val);
		if (negative) val = -val;
		return val;
	}

	lazy_entry* lazy_entry::dict_append(char* name)
	{
		TORRENT_ASSERT(m_type == dict_t);
		TORRENT_ASSERT(m_size <= m_capacity);
		if (m_capacity == 0)
		{
			int capacity = 10;
			m_data.dict = new (std::nothrow) std::pair<char*, lazy_entry>[capacity];
			if (m_data.dict == 0) return 0;
			m_capacity = capacity;
		}
		else if (m_size == m_capacity)
		{
			int capacity = m_capacity * 2;
			std::pair<char*, lazy_entry>* tmp = new (std::nothrow) std::pair<char*, lazy_entry>[capacity];
			if (tmp == 0) return 0;
			std::memcpy(tmp, m_data.dict, sizeof(std::pair<char*, lazy_entry>) * m_size);
			delete[] m_data.dict;
			m_data.dict = tmp;
			m_capacity = capacity;
		}

		TORRENT_ASSERT(m_size < m_capacity);
		std::pair<char*, lazy_entry>& ret = m_data.dict[m_size++];
		ret.first = name;
		return &ret.second;
	}

	lazy_entry* lazy_entry::dict_find(char const* name)
	{
		TORRENT_ASSERT(m_type == dict_t);
		for (int i = 0; i < m_size; ++i)
		{
			if (strcmp(name, m_data.dict[i].first) == 0)
				return &m_data.dict[i].second;
		}
		return 0;
	}

	lazy_entry* lazy_entry::list_append()
	{
		TORRENT_ASSERT(m_type == list_t);
		TORRENT_ASSERT(m_size <= m_capacity);
		if (m_capacity == 0)
		{
			int capacity = 10;
			m_data.list = new (std::nothrow) lazy_entry[capacity];
			if (m_data.list == 0) return 0;
			m_capacity = capacity;
		}
		else if (m_size == m_capacity)
		{
			int capacity = m_capacity * 2;
			lazy_entry* tmp = new (std::nothrow) lazy_entry[capacity];
			if (tmp == 0) return 0;
			std::memcpy(tmp, m_data.list, sizeof(lazy_entry) * m_size);
			delete[] m_data.list;
			m_data.list = tmp;
			m_capacity = capacity;
		}

		TORRENT_ASSERT(m_size < m_capacity);
		return m_data.list + (m_size++);
	}

	void lazy_entry::clear()
	{
		switch (m_type)
		{
			case list_t: delete[] m_data.list; break;
			case dict_t: delete[] m_data.dict; break;
			default: break;
		}
		m_size = 0;
		m_capacity = 0;
		m_type = none_t;
	}

	std::ostream& operator<<(std::ostream& os, lazy_entry const& e)
	{
		switch (e.type())
		{
			case lazy_entry::none_t: return os << "none";
			case lazy_entry::int_t: return os << e.int_value();
			case lazy_entry::string_t:
			{
				bool printable = true;
				char const* str = e.string_value();
				for (int i = 0; i < e.string_length(); ++i)
				{
					using namespace std;
					if (isprint(str[i])) continue;
					printable = false;
					break;
				}
				if (printable) return os << str;
				for (int i = 0; i < e.string_length(); ++i)
					os << std::hex << (int)str[i];
			}
			case lazy_entry::list_t:
			{
				os << "[";
				bool one_liner = e.list_size() == 0
					|| e.list_at(0)->type() == lazy_entry::int_t
					|| (e.list_at(0)->type() == lazy_entry::string_t
						&& e.list_at(0)->string_length() < 5);
				if (!one_liner) os << "\n";
				for (int i = 0; i < e.list_size(); ++i)
				{
					if (i == 0 && one_liner) os << " ";
					os << *e.list_at(i);
					if (i < e.list_size() - 1) os << (one_liner?", ":",\n");
					else os << (one_liner?" ":"\n");
				}
				return os << "]";
			}
			case lazy_entry::dict_t:
			{
				os << "{";
				bool one_liner = e.dict_size() == 0
					|| e.dict_at(0).second->type() == lazy_entry::int_t
					|| (e.dict_at(0).second->type() == lazy_entry::string_t
						&& e.dict_at(0).second->string_length() < 4)
					|| strlen(e.dict_at(0).first) < 10;
				if (!one_liner) os << "\n";
				for (int i = 0; i < e.dict_size(); ++i)
				{
					if (i == 0 && one_liner) os << " ";
					std::pair<char const*, lazy_entry const*> ent = e.dict_at(i);
					os << "'" << ent.first << "': " << *ent.second;
					if (i < e.dict_size() - 1) os << (one_liner?", ":",\n");
					else os << (one_liner?" ":"\n");
				}
				return os << "}";
			}
		}
		return os;
	}

};

<commit_msg>lazy bdecode fixes<commit_after>/*

Copyright (c) 2008, Arvid Norberg
All rights reserved.

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

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

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

*/

#include "libtorrent/lazy_entry.hpp"
#include <iostream>
#include <iomanip>

namespace libtorrent
{
	int fail_bdecode() { return -1; }

	// fills in 'val' with what the string between start and the
	// first occurance of the delimiter is interpreted as an int.
	// return the pointer to the delimiter, or 0 if there is a
	// parse error. val should be initialized to zero
	char* parse_int(char* start, char* end, char delimiter, boost::int64_t& val)
	{
		while (start < end && *start != delimiter)
		{
			using namespace std;
			if (!isdigit(*start)) { fail_bdecode(); return 0; }
			val *= 10;
			val += *start - '0';
			++start;
		}
		return start;
	}

	char* find_char(char* start, char* end, char delimiter)
	{
		while (start < end && *start != delimiter) ++start;
		return start;
	}

	// return 0 = success
	int lazy_bdecode(char* start, char* end, lazy_entry& ret, int depth_limit)
	{
		ret.clear();
		if (start == end) return 0;

		std::vector<lazy_entry*> stack;

		stack.push_back(&ret);
		while (start < end)
		{
			if (stack.empty()) break; // done!

			lazy_entry* top = stack.back();

			if (stack.size() > depth_limit) return fail_bdecode();
			if (start == end) return fail_bdecode();
			char t = *start;
			*start++ = 0; // null terminate any previous string
			if (start == end && t != 'e') return fail_bdecode();

			switch (top->type())
			{
				case lazy_entry::dict_t:
				{
					if (t == 'e')
					{
						stack.pop_back();
						continue;
					}
					boost::int64_t len = t - '0';
					start = parse_int(start, end, ':', len);
					if (start == 0 || start + len + 3 > end || *start != ':') return fail_bdecode();
					++start;
					lazy_entry* ent = top->dict_append(start);
					start += len;
					stack.push_back(ent);
					t = *start;
					*start++ = 0; // null terminate any previous string
					break;
				}
				case lazy_entry::list_t:
				{
					if (t == 'e')
					{
						stack.pop_back();
						continue;
					}
					lazy_entry* ent = top->list_append();
					stack.push_back(ent);
					break;
				}
				default: break;
			}

			top = stack.back();
			switch (t)
			{
				case 'd':
					top->construct_dict();
					continue;
				case 'l':
					top->construct_list();
					continue;
				case 'i':
					top->construct_int(start);
					start = find_char(start, end, 'e');
					if (start == end) return fail_bdecode();
					TORRENT_ASSERT(*start == 'e');
					*start++ = 0;
					stack.pop_back();
					continue;
				default:
				{
					using namespace std;
					if (!isdigit(t)) return fail_bdecode();

					boost::int64_t len = t - '0';
					start = parse_int(start, end, ':', len);
					if (start == 0 || start + len + 1 > end || *start != ':') return fail_bdecode();
					++start;
					top->construct_string(start, int(len));
					stack.pop_back();
					start += len;
					continue;
				}
			}
			return 0;
		}
		return 0;
	}

	boost::int64_t lazy_entry::int_value() const
	{
		TORRENT_ASSERT(m_type == int_t);
		boost::int64_t val = 0;
		bool negative = false;
		if (*m_data.start == '-') negative = true;
		parse_int(negative?m_data.start+1:m_data.start, m_data.start + 100, 0, val);
		if (negative) val = -val;
		return val;
	}

	lazy_entry* lazy_entry::dict_append(char* name)
	{
		TORRENT_ASSERT(m_type == dict_t);
		TORRENT_ASSERT(m_size <= m_capacity);
		if (m_capacity == 0)
		{
			int capacity = 10;
			m_data.dict = new (std::nothrow) std::pair<char*, lazy_entry>[capacity];
			if (m_data.dict == 0) return 0;
			m_capacity = capacity;
		}
		else if (m_size == m_capacity)
		{
			int capacity = m_capacity * 2;
			std::pair<char*, lazy_entry>* tmp = new (std::nothrow) std::pair<char*, lazy_entry>[capacity];
			if (tmp == 0) return 0;
			std::memcpy(tmp, m_data.dict, sizeof(std::pair<char*, lazy_entry>) * m_size);
			delete[] m_data.dict;
			m_data.dict = tmp;
			m_capacity = capacity;
		}

		TORRENT_ASSERT(m_size < m_capacity);
		std::pair<char*, lazy_entry>& ret = m_data.dict[m_size++];
		ret.first = name;
		return &ret.second;
	}

	lazy_entry* lazy_entry::dict_find(char const* name)
	{
		TORRENT_ASSERT(m_type == dict_t);
		for (int i = 0; i < m_size; ++i)
		{
			if (strcmp(name, m_data.dict[i].first) == 0)
				return &m_data.dict[i].second;
		}
		return 0;
	}

	lazy_entry* lazy_entry::list_append()
	{
		TORRENT_ASSERT(m_type == list_t);
		TORRENT_ASSERT(m_size <= m_capacity);
		if (m_capacity == 0)
		{
			int capacity = 10;
			m_data.list = new (std::nothrow) lazy_entry[capacity];
			if (m_data.list == 0) return 0;
			m_capacity = capacity;
		}
		else if (m_size == m_capacity)
		{
			int capacity = m_capacity * 2;
			lazy_entry* tmp = new (std::nothrow) lazy_entry[capacity];
			if (tmp == 0) return 0;
			std::memcpy(tmp, m_data.list, sizeof(lazy_entry) * m_size);
			delete[] m_data.list;
			m_data.list = tmp;
			m_capacity = capacity;
		}

		TORRENT_ASSERT(m_size < m_capacity);
		return m_data.list + (m_size++);
	}

	void lazy_entry::clear()
	{
		switch (m_type)
		{
			case list_t: delete[] m_data.list; break;
			case dict_t: delete[] m_data.dict; break;
			default: break;
		}
		m_size = 0;
		m_capacity = 0;
		m_type = none_t;
	}

	std::ostream& operator<<(std::ostream& os, lazy_entry const& e)
	{
		switch (e.type())
		{
			case lazy_entry::none_t: return os << "none";
			case lazy_entry::int_t: return os << e.int_value();
			case lazy_entry::string_t:
			{
				bool printable = true;
				char const* str = e.string_value();
				for (int i = 0; i < e.string_length(); ++i)
				{
					using namespace std;
					if (isprint(str[i])) continue;
					printable = false;
					break;
				}
				if (printable) return os << str;
				for (int i = 0; i < e.string_length(); ++i)
					os << std::hex << int((unsigned char)(str[i]));
				return os;
			}
			case lazy_entry::list_t:
			{
				os << "[";
				bool one_liner = (e.list_size() == 0
					|| e.list_at(0)->type() == lazy_entry::int_t
					|| (e.list_at(0)->type() == lazy_entry::string_t
						&& e.list_at(0)->string_length() < 5))
					&& e.list_size() < 5;
				if (!one_liner) os << "\n";
				for (int i = 0; i < e.list_size(); ++i)
				{
					if (i == 0 && one_liner) os << " ";
					os << *e.list_at(i);
					if (i < e.list_size() - 1) os << (one_liner?", ":",\n");
					else os << (one_liner?" ":"\n");
				}
				return os << "]";
			}
			case lazy_entry::dict_t:
			{
				os << "{";
				bool one_liner = (e.dict_size() == 0
					|| e.dict_at(0).second->type() == lazy_entry::int_t
					|| (e.dict_at(0).second->type() == lazy_entry::string_t
						&& e.dict_at(0).second->string_length() < 4)
					|| strlen(e.dict_at(0).first) < 10)
					&& e.dict_size() < 5;

				if (!one_liner) os << "\n";
				for (int i = 0; i < e.dict_size(); ++i)
				{
					if (i == 0 && one_liner) os << " ";
					std::pair<char const*, lazy_entry const*> ent = e.dict_at(i);
					os << "'" << ent.first << "': " << *ent.second;
					if (i < e.dict_size() - 1) os << (one_liner?", ":",\n");
					else os << (one_liner?" ":"\n");
				}
				return os << "}";
			}
		}
		return os;
	}

};

<|endoftext|>


<commit_before>/*********************************************************************************
 *
 * Inviwo - Interactive Visualization Workshop
 *
 * Copyright (c) 2013-2019 Inviwo Foundation
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *********************************************************************************/

#include <modules/qtwidgets/tf/tfeditorisovalue.h>
#include <modules/qtwidgets/tf/tfcontrolpointconnection.h>
#include <modules/qtwidgets/tf/tfeditor.h>
#include <modules/qtwidgets/tf/tfeditorview.h>

#include <warn/push>
#include <warn/ignore/all>
#include <QGraphicsScene>
#include <QPainter>
#include <warn/pop>

namespace inviwo {

TFEditorIsovalue::TFEditorIsovalue(TFPrimitive& primitive, QGraphicsScene* scene, double size)
    : TFEditorPrimitive(primitive, scene, vec2(primitive.getPosition(), primitive.getAlpha()),
                        size) {
    // ensure that Isovalue primitives are rendered behind TF control points
    defaultZValue_ = 5;
    setZValue(defaultZValue_);
    data_.addObserver(this);
}

void TFEditorIsovalue::onTFPrimitiveChange(const TFPrimitive& p) {
    setTFPosition(vec2(p.getPosition(), p.getAlpha()));
}

QRectF TFEditorIsovalue::boundingRect() const {
    double bBoxSize = getSize() + 5.0;  //<! consider size of pen
    auto bRect = QRectF(-bBoxSize / 2.0, -bBoxSize / 2.0, bBoxSize, bBoxSize);

    // add box of vertical line
    double verticalScaling = getVerticalSceneScaling();
    QRectF rect = scene()->sceneRect();
    return bRect.united(QRectF(QPointF(-1.0, -rect.height() * verticalScaling),
                               QPointF(1.0, rect.height() * verticalScaling)));
}

QPainterPath TFEditorIsovalue::shape() const {
    QPainterPath path;
    const auto width = getSize() + 3.0;  //<! consider size of pen;
    path.addRect(QRectF(QPointF(-0.5 * width, -0.5 * width), QSizeF(width, width)));

    // add box of vertical line
    double verticalScaling = getVerticalSceneScaling();
    QRectF rect = scene()->sceneRect();
    path.moveTo(QPointF(0.0, -rect.height() * verticalScaling));
    path.lineTo(QPointF(0.0, rect.height() * verticalScaling));

    return path;
}

void TFEditorIsovalue::paintPrimitive(QPainter* painter) {
    // draw vertical line
    painter->save();

    QPen pen = QPen();
    pen.setCosmetic(true);
    pen.setCapStyle(Qt::RoundCap);

    pen.setWidthF(2.0);
    pen.setColor(QColor(64, 64, 64, 255));
    pen.setStyle(Qt::DashLine);
    // ensure line is always covering entire scene
    QRectF rect = scene()->sceneRect();
    painter->setPen(pen);
    painter->setBrush(Qt::NoBrush);

    double verticalScaling = getVerticalSceneScaling();
    painter->drawLine(QLineF(QPointF(0.0, -rect.height() * verticalScaling),
                             QPointF(0.0, rect.height() * verticalScaling)));

    painter->restore();

    // draw square for indicating isovalue
    const auto width = getSize();
    painter->drawRect(QRectF(QPointF(-0.5f * width, -0.5f * width), QSizeF(width, width)));
}

void TFEditorIsovalue::onItemPositionChange(const vec2& newPos) { data_.setPositionAlpha(newPos); }

void TFEditorIsovalue::onItemSceneHasChanged() { onTFPrimitiveChange(data_); }

double TFEditorIsovalue::getVerticalSceneScaling() const {
    double verticalScaling = 1.0;
    if (auto tfe = qobject_cast<TFEditor*>(scene())) {
        verticalScaling = 1.0 / tfe->getZoom().y;
        ;
    }
    return verticalScaling;
}

bool operator==(const TFEditorIsovalue& lhs, const TFEditorIsovalue& rhs) {
    return lhs.data_ == rhs.data_;
}

bool operator!=(const TFEditorIsovalue& lhs, const TFEditorIsovalue& rhs) {
    return !operator==(lhs, rhs);
}

bool operator<(const TFEditorIsovalue& lhs, const TFEditorIsovalue& rhs) {
    return lhs.currentPos_.x() < rhs.currentPos_.x();
}

bool operator>(const TFEditorIsovalue& lhs, const TFEditorIsovalue& rhs) { return rhs < lhs; }

bool operator<=(const TFEditorIsovalue& lhs, const TFEditorIsovalue& rhs) { return !(rhs < lhs); }

bool operator>=(const TFEditorIsovalue& lhs, const TFEditorIsovalue& rhs) { return !(lhs < rhs); }

}  // namespace inviwo
<commit_msg>QtWidgets: isovalue selection fix in tf dialog<commit_after>/*********************************************************************************
 *
 * Inviwo - Interactive Visualization Workshop
 *
 * Copyright (c) 2013-2019 Inviwo Foundation
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *********************************************************************************/

#include <modules/qtwidgets/tf/tfeditorisovalue.h>
#include <modules/qtwidgets/tf/tfcontrolpointconnection.h>
#include <modules/qtwidgets/tf/tfeditor.h>
#include <modules/qtwidgets/tf/tfeditorview.h>

#include <warn/push>
#include <warn/ignore/all>
#include <QGraphicsScene>
#include <QPainter>
#include <warn/pop>

namespace inviwo {

TFEditorIsovalue::TFEditorIsovalue(TFPrimitive& primitive, QGraphicsScene* scene, double size)
    : TFEditorPrimitive(primitive, scene, vec2(primitive.getPosition(), primitive.getAlpha()),
                        size) {
    // ensure that Isovalue primitives are rendered behind TF control points
    defaultZValue_ = 5;
    setZValue(defaultZValue_);
    data_.addObserver(this);
}

void TFEditorIsovalue::onTFPrimitiveChange(const TFPrimitive& p) {
    setTFPosition(vec2(p.getPosition(), p.getAlpha()));
}

QRectF TFEditorIsovalue::boundingRect() const {
    double bBoxSize = getSize() + 5.0;  //<! consider size of pen
    auto bRect = QRectF(-bBoxSize / 2.0, -bBoxSize / 2.0, bBoxSize, bBoxSize);

    // add box of vertical line
    double verticalScaling = getVerticalSceneScaling();
    QRectF rect = scene()->sceneRect();
    return bRect.united(QRectF(QPointF(-1.0, -rect.height() * verticalScaling),
                               QPointF(1.0, rect.height() * verticalScaling)));
}

QPainterPath TFEditorIsovalue::shape() const {
    QPainterPath path;
    const auto width = getSize() + 3.0;  //<! consider size of pen;
    path.addRect(QRectF(QPointF(-0.5 * width, -0.5 * width), QSizeF(width, width)));

    // do not add the vertical line to the shape in order to make only the square box selectable

    return path;
}

void TFEditorIsovalue::paintPrimitive(QPainter* painter) {
    // draw vertical line
    painter->save();

    QPen pen = QPen();
    pen.setCosmetic(true);
    pen.setCapStyle(Qt::RoundCap);

    pen.setWidthF(2.0);
    pen.setColor(QColor(64, 64, 64, 255));
    pen.setStyle(Qt::DashLine);
    // ensure line is always covering entire scene
    QRectF rect = scene()->sceneRect();
    painter->setPen(pen);
    painter->setBrush(Qt::NoBrush);

    double verticalScaling = getVerticalSceneScaling();
    painter->drawLine(QLineF(QPointF(0.0, -rect.height() * verticalScaling),
                             QPointF(0.0, rect.height() * verticalScaling)));

    painter->restore();

    // draw square for indicating isovalue
    const auto width = getSize();
    painter->drawRect(QRectF(QPointF(-0.5f * width, -0.5f * width), QSizeF(width, width)));
}

void TFEditorIsovalue::onItemPositionChange(const vec2& newPos) { data_.setPositionAlpha(newPos); }

void TFEditorIsovalue::onItemSceneHasChanged() { onTFPrimitiveChange(data_); }

double TFEditorIsovalue::getVerticalSceneScaling() const {
    double verticalScaling = 1.0;
    if (auto tfe = qobject_cast<TFEditor*>(scene())) {
        verticalScaling = 1.0 / tfe->getZoom().y;
        ;
    }
    return verticalScaling;
}

bool operator==(const TFEditorIsovalue& lhs, const TFEditorIsovalue& rhs) {
    return lhs.data_ == rhs.data_;
}

bool operator!=(const TFEditorIsovalue& lhs, const TFEditorIsovalue& rhs) {
    return !operator==(lhs, rhs);
}

bool operator<(const TFEditorIsovalue& lhs, const TFEditorIsovalue& rhs) {
    return lhs.currentPos_.x() < rhs.currentPos_.x();
}

bool operator>(const TFEditorIsovalue& lhs, const TFEditorIsovalue& rhs) { return rhs < lhs; }

bool operator<=(const TFEditorIsovalue& lhs, const TFEditorIsovalue& rhs) { return !(rhs < lhs); }

bool operator>=(const TFEditorIsovalue& lhs, const TFEditorIsovalue& rhs) { return !(lhs < rhs); }

}  // namespace inviwo
<|endoftext|>


<commit_before>/////
// lib-lifx.cpp
//! @file Library implementation
/////

#include <lib-lifx/lifx.h>

#include <array>
#include <chrono>
#include <thread>

#ifdef _WIN32
#include <WinSock2.h>
#include <ws2tcpip.h>
#else
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#endif

namespace
{
  constexpr int sockAddrLen = sizeof(sockaddr_in);
  struct sockaddr_in listen_addr = { };
  struct sockaddr_in send_direct_addr = { };
  struct sockaddr_in broadcast_addr = { };
  int sock;
}

namespace lifx
{
  LifxClient::LifxClient(int sourceId)
    : m_sourceId(std::move(sourceId))
  {
    // TODO: Error checking

#ifdef _WIN32
    // Start WinSock
    WSADATA wsa;
    WSAStartup(MAKEWORD(2, 2), &wsa);
#endif

    // Setup addresses
    listen_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    listen_addr.sin_port = htons(56700);
    listen_addr.sin_family = AF_INET;

    //send_direct_addr.sin_addr.s_addr = htonl(INADDR_BROADCAST);
    send_direct_addr.sin_port = htons(56700);
    send_direct_addr.sin_family = AF_INET;

    broadcast_addr.sin_addr.s_addr = htonl(INADDR_BROADCAST);
    broadcast_addr.sin_port = htons(56700);
    broadcast_addr.sin_family = AF_INET;

    // Create our actual socket
    sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);

    // Allow this socket to broadcast
    int yes = 1;
    setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (const char*)&yes, sizeof(int));

    // Allow this socket to reuse addresses
    setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char*)&yes, sizeof(int));

    // Bind the socket to our listening address
    bind(sock, (struct sockaddr*)&listen_addr, sockAddrLen);
  }

  LifxClient::~LifxClient()
  {
    // Delete all callbacks
    for (auto iter : m_callbacks)
    {
      delete iter.second;
    }

#ifdef _WIN32
    // Close the socket
    closesocket(sock);
    // Stop WinSock
    WSACleanup();
#else
    // Close the socket
    close(sock);
#endif
  }

  int LifxClient::SendBuffer(const std::vector<char>& buffer)
  {
    if (buffer.empty())
      return 0;

    int ret = sendto(sock, buffer.data(), buffer.size(), 0,
      (struct sockaddr*)&broadcast_addr, sockAddrLen);
    return std::move(ret);
  }

  LifxClient::RunResult LifxClient::RunOnce(long seconds, long milliseconds)
  {
    struct timeval timeout;
    timeout.tv_sec = std::move(seconds);
    timeout.tv_usec = std::move(milliseconds);

    fd_set rfds;
    FD_ZERO(&rfds);
    FD_SET(static_cast<unsigned int>(sock), &rfds);

    int ret = select(sock, &rfds, nullptr, nullptr, &timeout);
    if (ret == -1)
    {
      return RunResult::RUN_ERROR;
    }
    else if (ret && FD_ISSET(sock, &rfds))
    {
      std::array<char, MAX_LIFX_PACKET_SIZE> buffer;
      recv(sock, buffer.data(), MAX_LIFX_PACKET_SIZE, 0);

      NetworkHeader nh = { };
      memcpy(&nh, buffer.data(), LIFX_HEADER_SIZE);
      auto header = FromNetwork(nh);

      switch (header.type)
      {
        case message::device::GetService::type:
        {
          auto msg = ReceiveMessage<message::device::GetService>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::device::StateService::type:
        {
          auto msg = ReceiveMessage<message::device::StateService>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::device::GetHostInfo::type:
        {
          auto msg = ReceiveMessage<message::device::GetHostInfo>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::device::StateHostInfo::type:
        {
          auto msg = ReceiveMessage<message::device::StateHostInfo>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::device::GetHostFirmware::type:
        {
          auto msg = ReceiveMessage<message::device::GetHostFirmware>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::device::StateHostFirmware::type:
        {
          auto msg = ReceiveMessage<message::device::StateHostFirmware>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::device::GetWifiInfo::type:
        {
          auto msg = ReceiveMessage<message::device::GetWifiInfo>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::device::StateWifiInfo::type:
        {
          auto msg = ReceiveMessage<message::device::StateWifiInfo>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::device::GetWifiFirmware::type:
        {
          auto msg = ReceiveMessage<message::device::GetWifiFirmware>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::device::StateWifiFirmware::type:
        {
          auto msg = ReceiveMessage<message::device::StateWifiFirmware>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::device::GetPower::type:
        {
          auto msg = ReceiveMessage<message::device::GetPower>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::device::SetPower::type:
        {
          auto msg = ReceiveMessage<message::device::SetPower>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::device::StatePower::type:
        {
          auto msg = ReceiveMessage<message::device::StatePower>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::device::GetLabel::type:
        {
          auto msg = ReceiveMessage<message::device::GetLabel>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::device::SetLabel::type:
        {
          auto msg = ReceiveMessage<message::device::SetLabel>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::device::StateLabel::type:
        {
          auto msg = ReceiveMessage<message::device::StateLabel>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::device::GetVersion::type:
        {
          auto msg = ReceiveMessage<message::device::GetVersion>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::device::StateVersion::type:
        {
          auto msg = ReceiveMessage<message::device::StateVersion>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::device::GetInfo::type:
        {
          auto msg = ReceiveMessage<message::device::GetInfo>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::device::StateInfo::type:
        {
          auto msg = ReceiveMessage<message::device::StateInfo>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::device::Acknowledgement::type:
        {
          auto msg = ReceiveMessage<message::device::Acknowledgement>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::device::GetLocation::type:
        {
          auto msg = ReceiveMessage<message::device::GetLocation>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::device::StateLocation::type:
        {
          auto msg = ReceiveMessage<message::device::StateLocation>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::device::GetGroup::type:
        {
          auto msg = ReceiveMessage<message::device::GetGroup>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::device::StateGroup::type:
        {
          auto msg = ReceiveMessage<message::device::StateGroup>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::device::EchoRequest::type:
        {
          auto msg = ReceiveMessage<message::device::EchoRequest>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::device::EchoResponse::type:
        {
          auto msg = ReceiveMessage<message::device::EchoResponse>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::light::Get::type:
        {
          auto msg = ReceiveMessage<message::light::Get>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::light::SetColor::type:
        {
          auto msg = ReceiveMessage<message::light::SetColor>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::light::State::type:
        {
          auto msg = ReceiveMessage<message::light::State>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::light::GetPower::type:
        {
          auto msg = ReceiveMessage<message::light::GetPower>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::light::SetPower::type:
        {
          auto msg = ReceiveMessage<message::light::SetPower>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::light::StatePower::type:
        {
          auto msg = ReceiveMessage<message::light::StatePower>(buffer.data());
          RunCallback(header, msg);
          break;
        }
      }
      return RunResult::RUN_RECEIVED_DATA;
    }

    if (!m_pendingSends.empty())
    {
      static auto start_time = std::chrono::steady_clock::now();
      static unsigned int messages_sent = 0;

      // Check if we have exceeded the number of messages per second
      auto seconds_since_start =
        std::chrono::duration_cast<std::chrono::seconds>(
          std::chrono::steady_clock::now() - start_time);
      if (seconds_since_start.count() > 0)
      {
        auto messages_per_second = (messages_sent / seconds_since_start.count());
        if (messages_per_second >= MAX_MESSAGES_PER_SECOND)
        {
          // hold off sending until we are under the limit
          return RunResult::RUN_SENT_LIMIT;
        }
      }

      auto tosend = m_pendingSends.begin();
      SendBuffer(tosend->second);
      m_pendingSends.erase(tosend);
      ++messages_sent;

      return RunResult::RUN_SENT_DATA;
    }

    return RunResult::RUN_WAITING;
  }

  bool LifxClient::WaitingToSend() const
  {
    return ! m_pendingSends.empty();
  }

  NetworkHeader ToNetwork(const Header& h)
  {
#ifdef _WIN32
    NetworkHeader nh = { };
    nh.frame = h.size;
    nh.frame |= h.protocol << 16;
    nh.frame |= h.addressable << 28;
    nh.frame |= h.tagged << 29;
    nh.frame |= h.origin << 30;
    nh.frame |= static_cast<uint64_t>(h.source) << 32;

    nh.target = h.target[0];
    nh.target |= h.target[1] << 8;
    nh.target |= h.target[2] << 16;
    nh.target |= h.target[3] << 24;
    nh.target |= static_cast<uint64_t>(h.target[4]) << 32;
    nh.target |= static_cast<uint64_t>(h.target[5]) << 40;
    nh.target |= static_cast<uint64_t>(h.target[6]) << 48;
    nh.target |= static_cast<uint64_t>(h.target[7]) << 56;

    nh.frame_address = h.site[0];
    nh.frame_address |= h.site[1] << 8;
    nh.frame_address |= h.site[2] << 16;
    nh.frame_address |= h.site[3] << 24;
    nh.frame_address |= static_cast<uint64_t>(h.site[4]) << 32;
    nh.frame_address |= static_cast<uint64_t>(h.site[5]) << 40;
    nh.frame_address |= static_cast<uint64_t>(h.ack_required) << 48;
    nh.frame_address |= static_cast<uint64_t>(h.res_required) << 49;
    //nh.frame_address |= static_cast<uint64_t>(h.reserved) << 50;
    nh.frame_address |= static_cast<uint64_t>(h.sequence) << 56;

    nh.time = h.at_time;

    nh.type = h.type;

    //nh.reserved = h.reserved;

    return std::move(nh);
#else
    return h;
#endif
  }

  Header FromNetwork(const NetworkHeader& nh)
  {
#ifdef _WIN32
    Header h = { };

    // reserved = nh.reserved; // 16

    h.type = nh.type; // 16

    h.at_time = nh.time; // 64

    h.target[0] = nh.target & 0xFF; // 8
    h.target[1] = (nh.target >> 8) & 0xFF; // 8
    h.target[2] = (nh.target >> 16) & 0xFF; // 8
    h.target[3] = (nh.target >> 24) & 0xFF; // 8
    h.target[4] = (nh.target >> 32) & 0xFF; // 8
    h.target[5] = (nh.target >> 40) & 0xFF; // 8
    h.target[6] = (nh.target >> 48) & 0xFF; // 8
    h.target[7] = (nh.target >> 56) & 0xFF; // 8

    h.site[0] = nh.frame_address & 0xFF; // 8
    h.site[1] = (nh.frame_address >> 8) & 0xFF; // 8
    h.site[2] = (nh.frame_address >> 16) & 0xFF; // 8
    h.site[3] = (nh.frame_address >> 24) & 0xFF; // 8
    h.site[4] = (nh.frame_address >> 32) & 0xFF; // 8
    h.site[5] = (nh.frame_address >> 40) & 0xFF; // 8
    h.ack_required = (nh.frame_address >> 48) & 0x1; // 1
    h.res_required = (nh.frame_address >> 49) & 0x1; // 1
                                                     //h.reserved = (nh.frame_address >> 50) & 0x3f; // 6
    h.sequence = (nh.frame_address >> 56) & 0xFF; // 8

    h.size = nh.frame & 0xFFFF; // 16
    h.protocol = (nh.frame >> 16) & 0xFFF; // 12
    h.addressable = (nh.frame >> 28) & 0x1; // 1
    h.tagged = (nh.frame >> 29) & 0x1; //1
    h.origin = (nh.frame >> 30) & 0x3; // 2
    h.source = (nh.frame >> 32) & 0xFFFFFFFF; //32

    return std::move(h);
#else
    return nh;
#endif
  }

} // namespace lifx
<commit_msg>Fixed use of select under UNIX systems.<commit_after>/////
// lib-lifx.cpp
//! @file Library implementation
/////

#include <lib-lifx/lifx.h>

#include <array>
#include <chrono>
#include <thread>

#ifdef _WIN32
#include <WinSock2.h>
#include <ws2tcpip.h>
#else
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#endif

namespace
{
  constexpr int sockAddrLen = sizeof(sockaddr_in);
  struct sockaddr_in listen_addr = { };
  struct sockaddr_in send_direct_addr = { };
  struct sockaddr_in broadcast_addr = { };
  int sock;
}

namespace lifx
{
  LifxClient::LifxClient(int sourceId)
    : m_sourceId(std::move(sourceId))
  {
    // TODO: Error checking

#ifdef _WIN32
    // Start WinSock
    WSADATA wsa;
    WSAStartup(MAKEWORD(2, 2), &wsa);
#endif

    // Setup addresses
    listen_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    listen_addr.sin_port = htons(56700);
    listen_addr.sin_family = AF_INET;

    //send_direct_addr.sin_addr.s_addr = htonl(INADDR_BROADCAST);
    send_direct_addr.sin_port = htons(56700);
    send_direct_addr.sin_family = AF_INET;

    broadcast_addr.sin_addr.s_addr = htonl(INADDR_BROADCAST);
    broadcast_addr.sin_port = htons(56700);
    broadcast_addr.sin_family = AF_INET;

    // Create our actual socket
    sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);

    // Allow this socket to broadcast
    int yes = 1;
    setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (const char*)&yes, sizeof(int));

    // Allow this socket to reuse addresses
    setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char*)&yes, sizeof(int));

    // Bind the socket to our listening address
    bind(sock, (struct sockaddr*)&listen_addr, sockAddrLen);
  }

  LifxClient::~LifxClient()
  {
    // Delete all callbacks
    for (auto iter : m_callbacks)
    {
      delete iter.second;
    }

#ifdef _WIN32
    // Close the socket
    closesocket(sock);
    // Stop WinSock
    WSACleanup();
#else
    // Close the socket
    close(sock);
#endif
  }

  int LifxClient::SendBuffer(const std::vector<char>& buffer)
  {
    if (buffer.empty())
      return 0;

    int ret = sendto(sock, buffer.data(), buffer.size(), 0,
      (struct sockaddr*)&broadcast_addr, sockAddrLen);
    return std::move(ret);
  }

  LifxClient::RunResult LifxClient::RunOnce(long seconds, long milliseconds)
  {
    struct timeval timeout;
    timeout.tv_sec = std::move(seconds);
    timeout.tv_usec = std::move(milliseconds);

    fd_set rfds;
    FD_ZERO(&rfds);
    FD_SET(static_cast<unsigned int>(sock), &rfds);

    int ret = select(sock+1, &rfds, nullptr, nullptr, &timeout);
    if (ret == -1)
    {
      return RunResult::RUN_ERROR;
    }
    else if (ret && FD_ISSET(sock, &rfds))
    {
      std::array<char, MAX_LIFX_PACKET_SIZE> buffer;
      recv(sock, buffer.data(), MAX_LIFX_PACKET_SIZE, 0);

      NetworkHeader nh = { };
      memcpy(&nh, buffer.data(), LIFX_HEADER_SIZE);
      auto header = FromNetwork(nh);

      switch (header.type)
      {
        case message::device::GetService::type:
        {
          auto msg = ReceiveMessage<message::device::GetService>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::device::StateService::type:
        {
          auto msg = ReceiveMessage<message::device::StateService>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::device::GetHostInfo::type:
        {
          auto msg = ReceiveMessage<message::device::GetHostInfo>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::device::StateHostInfo::type:
        {
          auto msg = ReceiveMessage<message::device::StateHostInfo>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::device::GetHostFirmware::type:
        {
          auto msg = ReceiveMessage<message::device::GetHostFirmware>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::device::StateHostFirmware::type:
        {
          auto msg = ReceiveMessage<message::device::StateHostFirmware>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::device::GetWifiInfo::type:
        {
          auto msg = ReceiveMessage<message::device::GetWifiInfo>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::device::StateWifiInfo::type:
        {
          auto msg = ReceiveMessage<message::device::StateWifiInfo>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::device::GetWifiFirmware::type:
        {
          auto msg = ReceiveMessage<message::device::GetWifiFirmware>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::device::StateWifiFirmware::type:
        {
          auto msg = ReceiveMessage<message::device::StateWifiFirmware>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::device::GetPower::type:
        {
          auto msg = ReceiveMessage<message::device::GetPower>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::device::SetPower::type:
        {
          auto msg = ReceiveMessage<message::device::SetPower>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::device::StatePower::type:
        {
          auto msg = ReceiveMessage<message::device::StatePower>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::device::GetLabel::type:
        {
          auto msg = ReceiveMessage<message::device::GetLabel>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::device::SetLabel::type:
        {
          auto msg = ReceiveMessage<message::device::SetLabel>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::device::StateLabel::type:
        {
          auto msg = ReceiveMessage<message::device::StateLabel>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::device::GetVersion::type:
        {
          auto msg = ReceiveMessage<message::device::GetVersion>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::device::StateVersion::type:
        {
          auto msg = ReceiveMessage<message::device::StateVersion>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::device::GetInfo::type:
        {
          auto msg = ReceiveMessage<message::device::GetInfo>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::device::StateInfo::type:
        {
          auto msg = ReceiveMessage<message::device::StateInfo>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::device::Acknowledgement::type:
        {
          auto msg = ReceiveMessage<message::device::Acknowledgement>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::device::GetLocation::type:
        {
          auto msg = ReceiveMessage<message::device::GetLocation>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::device::StateLocation::type:
        {
          auto msg = ReceiveMessage<message::device::StateLocation>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::device::GetGroup::type:
        {
          auto msg = ReceiveMessage<message::device::GetGroup>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::device::StateGroup::type:
        {
          auto msg = ReceiveMessage<message::device::StateGroup>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::device::EchoRequest::type:
        {
          auto msg = ReceiveMessage<message::device::EchoRequest>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::device::EchoResponse::type:
        {
          auto msg = ReceiveMessage<message::device::EchoResponse>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::light::Get::type:
        {
          auto msg = ReceiveMessage<message::light::Get>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::light::SetColor::type:
        {
          auto msg = ReceiveMessage<message::light::SetColor>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::light::State::type:
        {
          auto msg = ReceiveMessage<message::light::State>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::light::GetPower::type:
        {
          auto msg = ReceiveMessage<message::light::GetPower>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::light::SetPower::type:
        {
          auto msg = ReceiveMessage<message::light::SetPower>(buffer.data());
          RunCallback(header, msg);
          break;
        }
        case message::light::StatePower::type:
        {
          auto msg = ReceiveMessage<message::light::StatePower>(buffer.data());
          RunCallback(header, msg);
          break;
        }
      }
      return RunResult::RUN_RECEIVED_DATA;
    }

    if (!m_pendingSends.empty())
    {
      static auto start_time = std::chrono::steady_clock::now();
      static unsigned int messages_sent = 0;

      // Check if we have exceeded the number of messages per second
      auto seconds_since_start =
        std::chrono::duration_cast<std::chrono::seconds>(
          std::chrono::steady_clock::now() - start_time);
      if (seconds_since_start.count() > 0)
      {
        auto messages_per_second = (messages_sent / seconds_since_start.count());
        if (messages_per_second >= MAX_MESSAGES_PER_SECOND)
        {
          // hold off sending until we are under the limit
          return RunResult::RUN_SENT_LIMIT;
        }
      }

      auto tosend = m_pendingSends.begin();
      SendBuffer(tosend->second);
      m_pendingSends.erase(tosend);
      ++messages_sent;

      return RunResult::RUN_SENT_DATA;
    }

    return RunResult::RUN_WAITING;
  }

  bool LifxClient::WaitingToSend() const
  {
    return ! m_pendingSends.empty();
  }

  NetworkHeader ToNetwork(const Header& h)
  {
#ifdef _WIN32
    NetworkHeader nh = { };
    nh.frame = h.size;
    nh.frame |= h.protocol << 16;
    nh.frame |= h.addressable << 28;
    nh.frame |= h.tagged << 29;
    nh.frame |= h.origin << 30;
    nh.frame |= static_cast<uint64_t>(h.source) << 32;

    nh.target = h.target[0];
    nh.target |= h.target[1] << 8;
    nh.target |= h.target[2] << 16;
    nh.target |= h.target[3] << 24;
    nh.target |= static_cast<uint64_t>(h.target[4]) << 32;
    nh.target |= static_cast<uint64_t>(h.target[5]) << 40;
    nh.target |= static_cast<uint64_t>(h.target[6]) << 48;
    nh.target |= static_cast<uint64_t>(h.target[7]) << 56;

    nh.frame_address = h.site[0];
    nh.frame_address |= h.site[1] << 8;
    nh.frame_address |= h.site[2] << 16;
    nh.frame_address |= h.site[3] << 24;
    nh.frame_address |= static_cast<uint64_t>(h.site[4]) << 32;
    nh.frame_address |= static_cast<uint64_t>(h.site[5]) << 40;
    nh.frame_address |= static_cast<uint64_t>(h.ack_required) << 48;
    nh.frame_address |= static_cast<uint64_t>(h.res_required) << 49;
    //nh.frame_address |= static_cast<uint64_t>(h.reserved) << 50;
    nh.frame_address |= static_cast<uint64_t>(h.sequence) << 56;

    nh.time = h.at_time;

    nh.type = h.type;

    //nh.reserved = h.reserved;

    return std::move(nh);
#else
    return h;
#endif
  }

  Header FromNetwork(const NetworkHeader& nh)
  {
#ifdef _WIN32
    Header h = { };

    // reserved = nh.reserved; // 16

    h.type = nh.type; // 16

    h.at_time = nh.time; // 64

    h.target[0] = nh.target & 0xFF; // 8
    h.target[1] = (nh.target >> 8) & 0xFF; // 8
    h.target[2] = (nh.target >> 16) & 0xFF; // 8
    h.target[3] = (nh.target >> 24) & 0xFF; // 8
    h.target[4] = (nh.target >> 32) & 0xFF; // 8
    h.target[5] = (nh.target >> 40) & 0xFF; // 8
    h.target[6] = (nh.target >> 48) & 0xFF; // 8
    h.target[7] = (nh.target >> 56) & 0xFF; // 8

    h.site[0] = nh.frame_address & 0xFF; // 8
    h.site[1] = (nh.frame_address >> 8) & 0xFF; // 8
    h.site[2] = (nh.frame_address >> 16) & 0xFF; // 8
    h.site[3] = (nh.frame_address >> 24) & 0xFF; // 8
    h.site[4] = (nh.frame_address >> 32) & 0xFF; // 8
    h.site[5] = (nh.frame_address >> 40) & 0xFF; // 8
    h.ack_required = (nh.frame_address >> 48) & 0x1; // 1
    h.res_required = (nh.frame_address >> 49) & 0x1; // 1
                                                     //h.reserved = (nh.frame_address >> 50) & 0x3f; // 6
    h.sequence = (nh.frame_address >> 56) & 0xFF; // 8

    h.size = nh.frame & 0xFFFF; // 16
    h.protocol = (nh.frame >> 16) & 0xFFF; // 12
    h.addressable = (nh.frame >> 28) & 0x1; // 1
    h.tagged = (nh.frame >> 29) & 0x1; //1
    h.origin = (nh.frame >> 30) & 0x3; // 2
    h.source = (nh.frame >> 32) & 0xFFFFFFFF; //32

    return std::move(h);
#else
    return nh;
#endif
  }

} // namespace lifx
<|endoftext|>


<commit_before>#include "number.h"
#include "atom.h"
//#include "variable.h"

bool Number::match( Atom &b){
  bool isMatch = true;

  if( this->value() != b.symbol() ){
    isMatch = false;
  }
  return isMatch;
}

bool Number::match( Number &b){
  bool isMatch = true;

  if( this->value() != b.value() ){
    isMatch = false;
  }else{
      this->_value = b.value();
  }
  return isMatch;
}

bool Number::match(Variable &a){
  bool isMatch = true;
  if(a.value().length()==0 ){
    a._value = this->value();
  }
  if(a.value() != this->value() ){
    isMatch = false;
  }
  return isMatch;
}
<commit_msg>Delete number.cpp<commit_after><|endoftext|>