<commit_before>/*
 * Copyright (C) 2006, 2007, 2008, 2010 Apple Inc. All rights reserved.
 * Copyright (C) 2007 Alp Toker <alp@atoker.com>
 * Copyright (C) 2013 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 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 APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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 "config.h"
#include "platform/graphics/Gradient.h"

#include "platform/geometry/FloatRect.h"
#include "platform/graphics/GraphicsContext.h"
#include "platform/graphics/skia/SkiaUtils.h"
#include "third_party/skia/include/core/SkColor.h"
#include "third_party/skia/include/core/SkColorShader.h"
#include "third_party/skia/include/core/SkShader.h"
#include "third_party/skia/include/effects/SkGradientShader.h"

namespace WebCore {

Gradient::Gradient(const FloatPoint& p0, const FloatPoint& p1)
    : m_p0(p0)
    , m_p1(p1)
    , m_r0(0)
    , m_r1(0)
    , m_aspectRatio(1)
    , m_radial(false)
    , m_stopsSorted(false)
    , m_drawInPMColorSpace(false)
    , m_spreadMethod(SpreadMethodPad)
{
}

Gradient::Gradient(const FloatPoint& p0, float r0, const FloatPoint& p1, float r1, float aspectRatio)
    : m_p0(p0)
    , m_p1(p1)
    , m_r0(r0)
    , m_r1(r1)
    , m_aspectRatio(aspectRatio)
    , m_radial(true)
    , m_stopsSorted(false)
    , m_drawInPMColorSpace(false)
    , m_spreadMethod(SpreadMethodPad)
{
}

Gradient::~Gradient()
{
}

static inline bool compareStops(const Gradient::ColorStop& a, const Gradient::ColorStop& b)
{
    return a.stop < b.stop;
}

void Gradient::addColorStop(const Gradient::ColorStop& stop)
{
    if (m_stops.isEmpty()) {
        m_stopsSorted = true;
    } else {
        m_stopsSorted = m_stopsSorted && compareStops(m_stops.last(), stop);
    }

    m_stops.append(stop);
    m_gradient.clear();
}

void Gradient::sortStopsIfNecessary()
{
    if (m_stopsSorted)
        return;

    m_stopsSorted = true;

    if (!m_stops.size())
        return;

    std::stable_sort(m_stops.begin(), m_stops.end(), compareStops);
}

bool Gradient::hasAlpha() const
{
    for (size_t i = 0; i < m_stops.size(); i++) {
        if (m_stops[i].color.hasAlpha())
            return true;
    }

    return false;
}

void Gradient::setSpreadMethod(GradientSpreadMethod spreadMethod)
{
    // FIXME: Should it become necessary, allow calls to this method after m_gradient has been set.
    ASSERT(!m_gradient);

    if (m_spreadMethod == spreadMethod)
        return;

    m_spreadMethod = spreadMethod;
}

void Gradient::setDrawsInPMColorSpace(bool drawInPMColorSpace)
{
    if (drawInPMColorSpace == m_drawInPMColorSpace)
        return;

    m_drawInPMColorSpace = drawInPMColorSpace;
    m_gradient.clear();
}

void Gradient::setGradientSpaceTransform(const AffineTransform& gradientSpaceTransformation)
{
    if (m_gradientSpaceTransformation == gradientSpaceTransformation)
        return;

    m_gradientSpaceTransformation = gradientSpaceTransformation;
    if (m_gradient)
        m_gradient->setLocalMatrix(affineTransformToSkMatrix(m_gradientSpaceTransformation));
}

// Determine the total number of stops needed, including pseudo-stops at the
// ends as necessary.
static size_t totalStopsNeeded(const Gradient::ColorStop* stopData, size_t count)
{
    // N.B.: The tests in this function should kept in sync with the ones in
    // fillStops(), or badness happens.
    const Gradient::ColorStop* stop = stopData;
    size_t countUsed = count;
    if (count < 1 || stop->stop > 0.0)
        countUsed++;
    stop += count - 1;
    if (count < 1 || stop->stop < 1.0)
        countUsed++;
    return countUsed;
}

// FIXME: This would be more at home as Color::operator SkColor.
static inline SkColor makeSkColor(const Color& c)
{
    return SkColorSetARGB(c.alpha(), c.red(), c.green(), c.blue());
}

// Collect sorted stop position and color information into the pos and colors
// buffers, ensuring stops at both 0.0 and 1.0. The buffers must be large
// enough to hold information for all stops, including the new endpoints if
// stops at 0.0 and 1.0 aren't already included.
static void fillStops(const Gradient::ColorStop* stopData,
    size_t count, SkScalar* pos, SkColor* colors)
{
    const Gradient::ColorStop* stop = stopData;
    size_t start = 0;
    if (count < 1) {
        // A gradient with no stops must be transparent black.
        pos[0] = WebCoreFloatToSkScalar(0.0);
        colors[0] = SK_ColorTRANSPARENT;
        start = 1;
    } else if (stop->stop > 0.0) {
        // Copy the first stop to 0.0. The first stop position may have a slight
        // rounding error, but we don't care in this float comparison, since
        // 0.0 comes through cleanly and people aren't likely to want a gradient
        // with a stop at (0 + epsilon).
        pos[0] = WebCoreFloatToSkScalar(0.0);
        colors[0] = makeSkColor(stop->color);
        start = 1;
    }

    for (size_t i = start; i < start + count; i++) {
        pos[i] = WebCoreFloatToSkScalar(stop->stop);
        colors[i] = makeSkColor(stop->color);
        ++stop;
    }

    // Copy the last stop to 1.0 if needed. See comment above about this float
    // comparison.
    if (count < 1 || (--stop)->stop < 1.0) {
        pos[start + count] = WebCoreFloatToSkScalar(1.0);
        colors[start + count] = colors[start + count - 1];
    }
}

SkShader* Gradient::shader()
{
    if (m_gradient)
        return m_gradient.get();

    sortStopsIfNecessary();
    ASSERT(m_stopsSorted);

    size_t countUsed = totalStopsNeeded(m_stops.data(), m_stops.size());
    ASSERT(countUsed >= 2);
    ASSERT(countUsed >= m_stops.size());

    // FIXME: Why is all this manual pointer math needed?!
    SkAutoMalloc storage(countUsed * (sizeof(SkColor) + sizeof(SkScalar)));
    SkColor* colors = (SkColor*)storage.get();
    SkScalar* pos = (SkScalar*)(colors + countUsed);

    fillStops(m_stops.data(), m_stops.size(), pos, colors);

    SkShader::TileMode tile = SkShader::kClamp_TileMode;
    switch (m_spreadMethod) {
    case SpreadMethodReflect:
        tile = SkShader::kMirror_TileMode;
        break;
    case SpreadMethodRepeat:
        tile = SkShader::kRepeat_TileMode;
        break;
    case SpreadMethodPad:
        tile = SkShader::kClamp_TileMode;
        break;
    }

    uint32_t shouldDrawInPMColorSpace = m_drawInPMColorSpace ? SkGradientShader::kInterpolateColorsInPremul_Flag : 0;
    if (m_radial) {
        // Since the two-point radial gradient is slower than the plain radial,
        // only use it if we have to.
        if (m_p0 == m_p1 && m_r0 <= 0.0f) {
            m_gradient = adoptRef(SkGradientShader::CreateRadial(m_p1, m_r1, colors, pos, static_cast<int>(countUsed), tile, 0, shouldDrawInPMColorSpace));
        } else {
            // The radii we give to Skia must be positive. If we're given a
            // negative radius, ask for zero instead.
            SkScalar radius0 = m_r0 >= 0.0f ? WebCoreFloatToSkScalar(m_r0) : 0;
            SkScalar radius1 = m_r1 >= 0.0f ? WebCoreFloatToSkScalar(m_r1) : 0;
            m_gradient = adoptRef(SkGradientShader::CreateTwoPointConical(m_p0, radius0, m_p1, radius1, colors, pos, static_cast<int>(countUsed), tile, 0, shouldDrawInPMColorSpace));
        }

        if (aspectRatio() != 1) {
            // CSS3 elliptical gradients: apply the elliptical scaling at the
            // gradient center point.
            m_gradientSpaceTransformation.translate(m_p0.x(), m_p0.y());
            m_gradientSpaceTransformation.scale(1, 1 / aspectRatio());
            m_gradientSpaceTransformation.translate(-m_p0.x(), -m_p0.y());
            ASSERT(m_p0 == m_p1);
        }
    } else {
        SkPoint pts[2] = { m_p0, m_p1 };
        m_gradient = adoptRef(SkGradientShader::CreateLinear(pts, colors, pos, static_cast<int>(countUsed), tile, 0, shouldDrawInPMColorSpace));
    }

    if (!m_gradient) {
        // use last color, since our "geometry" was degenerate (e.g. radius==0)
        m_gradient = adoptRef(new SkColorShader(colors[countUsed - 1]));
    } else {
        m_gradient->setLocalMatrix(affineTransformToSkMatrix(m_gradientSpaceTransformation));
    }
    return m_gradient.get();
}

} //namespace
<commit_msg>Replace manual pointer arithmetic with WTF::Vector in Gradient::shader()<commit_after>/*
 * Copyright (C) 2006, 2007, 2008, 2010 Apple Inc. All rights reserved.
 * Copyright (C) 2007 Alp Toker <alp@atoker.com>
 * Copyright (C) 2013 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 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 APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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 "config.h"
#include "platform/graphics/Gradient.h"

#include "platform/geometry/FloatRect.h"
#include "platform/graphics/GraphicsContext.h"
#include "platform/graphics/skia/SkiaUtils.h"
#include "third_party/skia/include/core/SkColor.h"
#include "third_party/skia/include/core/SkColorShader.h"
#include "third_party/skia/include/core/SkShader.h"
#include "third_party/skia/include/effects/SkGradientShader.h"

typedef Vector<SkScalar, 8> ColorStopOffsetVector;
typedef Vector<SkColor, 8> ColorStopColorVector;

namespace WebCore {

Gradient::Gradient(const FloatPoint& p0, const FloatPoint& p1)
    : m_p0(p0)
    , m_p1(p1)
    , m_r0(0)
    , m_r1(0)
    , m_aspectRatio(1)
    , m_radial(false)
    , m_stopsSorted(false)
    , m_drawInPMColorSpace(false)
    , m_spreadMethod(SpreadMethodPad)
{
}

Gradient::Gradient(const FloatPoint& p0, float r0, const FloatPoint& p1, float r1, float aspectRatio)
    : m_p0(p0)
    , m_p1(p1)
    , m_r0(r0)
    , m_r1(r1)
    , m_aspectRatio(aspectRatio)
    , m_radial(true)
    , m_stopsSorted(false)
    , m_drawInPMColorSpace(false)
    , m_spreadMethod(SpreadMethodPad)
{
}

Gradient::~Gradient()
{
}

static inline bool compareStops(const Gradient::ColorStop& a, const Gradient::ColorStop& b)
{
    return a.stop < b.stop;
}

void Gradient::addColorStop(const Gradient::ColorStop& stop)
{
    if (m_stops.isEmpty()) {
        m_stopsSorted = true;
    } else {
        m_stopsSorted = m_stopsSorted && compareStops(m_stops.last(), stop);
    }

    m_stops.append(stop);
    m_gradient.clear();
}

void Gradient::sortStopsIfNecessary()
{
    if (m_stopsSorted)
        return;

    m_stopsSorted = true;

    if (!m_stops.size())
        return;

    std::stable_sort(m_stops.begin(), m_stops.end(), compareStops);
}

bool Gradient::hasAlpha() const
{
    for (size_t i = 0; i < m_stops.size(); i++) {
        if (m_stops[i].color.hasAlpha())
            return true;
    }

    return false;
}

void Gradient::setSpreadMethod(GradientSpreadMethod spreadMethod)
{
    // FIXME: Should it become necessary, allow calls to this method after m_gradient has been set.
    ASSERT(!m_gradient);

    if (m_spreadMethod == spreadMethod)
        return;

    m_spreadMethod = spreadMethod;
}

void Gradient::setDrawsInPMColorSpace(bool drawInPMColorSpace)
{
    if (drawInPMColorSpace == m_drawInPMColorSpace)
        return;

    m_drawInPMColorSpace = drawInPMColorSpace;
    m_gradient.clear();
}

void Gradient::setGradientSpaceTransform(const AffineTransform& gradientSpaceTransformation)
{
    if (m_gradientSpaceTransformation == gradientSpaceTransformation)
        return;

    m_gradientSpaceTransformation = gradientSpaceTransformation;
    if (m_gradient)
        m_gradient->setLocalMatrix(affineTransformToSkMatrix(m_gradientSpaceTransformation));
}

// Determine the total number of stops needed, including pseudo-stops at the
// ends as necessary.
static size_t totalStopsNeeded(const Gradient::ColorStop* stopData, size_t count)
{
    // N.B.: The tests in this function should kept in sync with the ones in
    // fillStops(), or badness happens.
    const Gradient::ColorStop* stop = stopData;
    size_t countUsed = count;
    if (count < 1 || stop->stop > 0.0)
        countUsed++;
    stop += count - 1;
    if (count < 1 || stop->stop < 1.0)
        countUsed++;
    return countUsed;
}

// FIXME: This would be more at home as Color::operator SkColor.
static inline SkColor makeSkColor(const Color& c)
{
    return SkColorSetARGB(c.alpha(), c.red(), c.green(), c.blue());
}

// Collect sorted stop position and color information into the pos and colors
// buffers, ensuring stops at both 0.0 and 1.0. The buffers must be large
// enough to hold information for all stops, including the new endpoints if
// stops at 0.0 and 1.0 aren't already included.
static void fillStops(const Gradient::ColorStop* stopData,
    size_t count, ColorStopOffsetVector& pos, ColorStopColorVector& colors)
{
    const Gradient::ColorStop* stop = stopData;
    size_t start = 0;
    if (count < 1) {
        // A gradient with no stops must be transparent black.
        pos[0] = WebCoreFloatToSkScalar(0.0);
        colors[0] = SK_ColorTRANSPARENT;
        start = 1;
    } else if (stop->stop > 0.0) {
        // Copy the first stop to 0.0. The first stop position may have a slight
        // rounding error, but we don't care in this float comparison, since
        // 0.0 comes through cleanly and people aren't likely to want a gradient
        // with a stop at (0 + epsilon).
        pos[0] = WebCoreFloatToSkScalar(0.0);
        colors[0] = makeSkColor(stop->color);
        start = 1;
    }

    for (size_t i = start; i < start + count; i++) {
        pos[i] = WebCoreFloatToSkScalar(stop->stop);
        colors[i] = makeSkColor(stop->color);
        ++stop;
    }

    // Copy the last stop to 1.0 if needed. See comment above about this float
    // comparison.
    if (count < 1 || (--stop)->stop < 1.0) {
        pos[start + count] = WebCoreFloatToSkScalar(1.0);
        colors[start + count] = colors[start + count - 1];
    }
}

SkShader* Gradient::shader()
{
    if (m_gradient)
        return m_gradient.get();

    sortStopsIfNecessary();
    ASSERT(m_stopsSorted);

    size_t countUsed = totalStopsNeeded(m_stops.data(), m_stops.size());
    ASSERT(countUsed >= 2);
    ASSERT(countUsed >= m_stops.size());

    ColorStopOffsetVector pos(countUsed);
    ColorStopColorVector colors(countUsed);
    fillStops(m_stops.data(), m_stops.size(), pos, colors);

    SkShader::TileMode tile = SkShader::kClamp_TileMode;
    switch (m_spreadMethod) {
    case SpreadMethodReflect:
        tile = SkShader::kMirror_TileMode;
        break;
    case SpreadMethodRepeat:
        tile = SkShader::kRepeat_TileMode;
        break;
    case SpreadMethodPad:
        tile = SkShader::kClamp_TileMode;
        break;
    }

    uint32_t shouldDrawInPMColorSpace = m_drawInPMColorSpace ? SkGradientShader::kInterpolateColorsInPremul_Flag : 0;
    if (m_radial) {
        // Since the two-point radial gradient is slower than the plain radial,
        // only use it if we have to.
        if (m_p0 == m_p1 && m_r0 <= 0.0f) {
            m_gradient = adoptRef(SkGradientShader::CreateRadial(m_p1, m_r1, colors.data(), pos.data(), static_cast<int>(countUsed), tile, 0, shouldDrawInPMColorSpace));
        } else {
            // The radii we give to Skia must be positive. If we're given a
            // negative radius, ask for zero instead.
            SkScalar radius0 = m_r0 >= 0.0f ? WebCoreFloatToSkScalar(m_r0) : 0;
            SkScalar radius1 = m_r1 >= 0.0f ? WebCoreFloatToSkScalar(m_r1) : 0;
            m_gradient = adoptRef(SkGradientShader::CreateTwoPointConical(m_p0, radius0, m_p1, radius1, colors.data(), pos.data(), static_cast<int>(countUsed), tile, 0, shouldDrawInPMColorSpace));
        }

        if (aspectRatio() != 1) {
            // CSS3 elliptical gradients: apply the elliptical scaling at the
            // gradient center point.
            m_gradientSpaceTransformation.translate(m_p0.x(), m_p0.y());
            m_gradientSpaceTransformation.scale(1, 1 / aspectRatio());
            m_gradientSpaceTransformation.translate(-m_p0.x(), -m_p0.y());
            ASSERT(m_p0 == m_p1);
        }
    } else {
        SkPoint pts[2] = { m_p0, m_p1 };
        m_gradient = adoptRef(SkGradientShader::CreateLinear(pts, colors.data(), pos.data(), static_cast<int>(countUsed), tile, 0, shouldDrawInPMColorSpace));
    }

    if (!m_gradient) {
        // use last color, since our "geometry" was degenerate (e.g. radius==0)
        m_gradient = adoptRef(new SkColorShader(colors[countUsed - 1]));
    } else {
        m_gradient->setLocalMatrix(affineTransformToSkMatrix(m_gradientSpaceTransformation));
    }
    return m_gradient.get();
}

} //namespace
<|endoftext|>


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

#ifndef OCCI_TYPES_HPP
#define OCCI_TYPES_HPP

// mapnik
#include <mapnik/utils.hpp>

// occi
#include <occi.h>

// ott generated SDOGeometry classes
#include "spatial_classesh.h"
#include "spatial_classesm.h"

// check for oracle support
#if OCCI_MAJOR_VERSION == 10 && OCCI_MINOR_VERSION >= 1
  //     Only ORACLE 10g (>= 10.2.0.X) is supported !
#else
  #error Only ORACLE 10g (>= 10.2.0.X) is supported !
#endif

#define SDO_GEOMETRY_METADATA_TABLE     "ALL_SDO_GEOM_METADATA"

enum
{
    SDO_GTYPE_UNKNOWN                   = 0,
    SDO_GTYPE_POINT                     = 1,
    SDO_GTYPE_LINE                      = 2,
    SDO_GTYPE_POLYGON                   = 3,
    SDO_GTYPE_COLLECTION                = 4,
    SDO_GTYPE_MULTIPOINT                = 5,
    SDO_GTYPE_MULTILINE                 = 6,
    SDO_GTYPE_MULTIPOLYGON              = 7,

    SDO_GTYPE_2DPOINT                   = 2001,
    SDO_GTYPE_2DLINE                    = 2002,
    SDO_GTYPE_2DPOLYGON                 = 2003,
    SDO_GTYPE_2DMULTIPOINT              = 2005,
    SDO_GTYPE_2DMULTILINE               = 2006,
    SDO_GTYPE_2DMULTIPOLYGON            = 2007,

    SDO_ELEM_INFO_SIZE                  = 3,

    SDO_ETYPE_UNKNOWN                   = 0,
    SDO_ETYPE_POINT                     = 1,
    SDO_ETYPE_LINESTRING                = 2,
    SDO_ETYPE_POLYGON                   = 1003,
    SDO_ETYPE_POLYGON_INTERIOR          = 2003,
    SDO_ETYPE_COMPOUND_LINESTRING       = 4,
    SDO_ETYPE_COMPOUND_POLYGON          = 1005,
    SDO_ETYPE_COMPOUND_POLYGON_INTERIOR = 2005,

    SDO_INTERPRETATION_POINT            = 1,
    SDO_INTERPRETATION_RECTANGLE        = 3,
    SDO_INTERPRETATION_CIRCLE           = 4,
    SDO_INTERPRETATION_STRAIGHT         = 1,
    SDO_INTERPRETATION_CIRCULAR         = 2
};

class occi_environment : public mapnik::singleton<occi_environment,mapnik::CreateStatic>
{
    friend class mapnik::CreateStatic<occi_environment>;

public:

    static oracle::occi::Environment* get_environment ()
    {
        if (env_ == 0)
        {
#ifdef MAPNIK_DEBUG
            std::clog << "occi_environment constructor" << std::endl;
#endif

            int mode = oracle::occi::Environment::OBJECT
                     | oracle::occi::Environment::THREADED_MUTEXED;

            env_ = oracle::occi::Environment::createEnvironment ((oracle::occi::Environment::Mode) mode);
            RegisterClasses (env_);
        }

        return env_;
    }

private:

    occi_environment()
    {
    }

    ~occi_environment()
    {
        if (env_)
        {
#ifdef MAPNIK_DEBUG
            std::clog << "occi_environment destructor" << std::endl;
#endif

            oracle::occi::Environment::terminateEnvironment (env_);
            env_ = 0;
        }
    }

    static oracle::occi::Environment* env_;
};

class occi_connection_ptr
{
public:
    occi_connection_ptr (oracle::occi::StatelessConnectionPool* pool)
        : pool_ (pool),
          conn_ (pool->getConnection ()),
          stmt_ (0),
          rs_ (0)
    {
    }

    ~occi_connection_ptr ()
    {
        close_query (true);
    }

    oracle::occi::ResultSet* execute_query (const std::string& s, const unsigned prefetch = 0)
    {
        close_query (false);

        stmt_ = conn_->createStatement (s);

        if (prefetch > 0)
        {
            stmt_->setPrefetchMemorySize (0);
            stmt_->setPrefetchRowCount (prefetch);
        }

        rs_ = stmt_->executeQuery ();

        return rs_;
    }

    oracle::occi::Connection* operator*()
    {
        return conn_;
    }

private:

    void close_query (const bool release_connection)
    {
        if (conn_)
        {
            if (stmt_)
            {
                if (rs_)
                {
                    stmt_->closeResultSet (rs_);
                    rs_ = 0;
                }

                conn_->terminateStatement (stmt_);
                stmt_ = 0;
            }

            if (release_connection)
            {
                pool_->releaseConnection (conn_);
                conn_ = 0;
            }
        }
    }

    oracle::occi::StatelessConnectionPool* pool_;
    oracle::occi::Connection* conn_;
    oracle::occi::Statement* stmt_;
    oracle::occi::ResultSet* rs_;
};

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

#ifndef OCCI_TYPES_HPP
#define OCCI_TYPES_HPP

// mapnik
#include <mapnik/utils.hpp>

// occi
#include <occi.h>

// ott generated SDOGeometry classes
#include "spatial_classesh.h"
#include "spatial_classesm.h"

// check for oracle support
#if OCCI_MAJOR_VERSION >= 10 && OCCI_MINOR_VERSION >= 1
  //     Only ORACLE 10g (>= 10.2.0.X) is supported !
#else
  #error Only ORACLE 10g (>= 10.2.0.X) is supported !
#endif

#define SDO_GEOMETRY_METADATA_TABLE     "ALL_SDO_GEOM_METADATA"

enum
{
    SDO_GTYPE_UNKNOWN                   = 0,
    SDO_GTYPE_POINT                     = 1,
    SDO_GTYPE_LINE                      = 2,
    SDO_GTYPE_POLYGON                   = 3,
    SDO_GTYPE_COLLECTION                = 4,
    SDO_GTYPE_MULTIPOINT                = 5,
    SDO_GTYPE_MULTILINE                 = 6,
    SDO_GTYPE_MULTIPOLYGON              = 7,

    SDO_GTYPE_2DPOINT                   = 2001,
    SDO_GTYPE_2DLINE                    = 2002,
    SDO_GTYPE_2DPOLYGON                 = 2003,
    SDO_GTYPE_2DMULTIPOINT              = 2005,
    SDO_GTYPE_2DMULTILINE               = 2006,
    SDO_GTYPE_2DMULTIPOLYGON            = 2007,

    SDO_ELEM_INFO_SIZE                  = 3,

    SDO_ETYPE_UNKNOWN                   = 0,
    SDO_ETYPE_POINT                     = 1,
    SDO_ETYPE_LINESTRING                = 2,
    SDO_ETYPE_POLYGON                   = 1003,
    SDO_ETYPE_POLYGON_INTERIOR          = 2003,
    SDO_ETYPE_COMPOUND_LINESTRING       = 4,
    SDO_ETYPE_COMPOUND_POLYGON          = 1005,
    SDO_ETYPE_COMPOUND_POLYGON_INTERIOR = 2005,

    SDO_INTERPRETATION_POINT            = 1,
    SDO_INTERPRETATION_RECTANGLE        = 3,
    SDO_INTERPRETATION_CIRCLE           = 4,
    SDO_INTERPRETATION_STRAIGHT         = 1,
    SDO_INTERPRETATION_CIRCULAR         = 2
};

class occi_environment : public mapnik::singleton<occi_environment,mapnik::CreateStatic>
{
    friend class mapnik::CreateStatic<occi_environment>;

public:

    static oracle::occi::Environment* get_environment ()
    {
        if (env_ == 0)
        {
#ifdef MAPNIK_DEBUG
            std::clog << "occi_environment constructor" << std::endl;
#endif

            int mode = oracle::occi::Environment::OBJECT
                     | oracle::occi::Environment::THREADED_MUTEXED;

            env_ = oracle::occi::Environment::createEnvironment ((oracle::occi::Environment::Mode) mode);
            RegisterClasses (env_);
        }

        return env_;
    }

private:

    occi_environment()
    {
    }

    ~occi_environment()
    {
        if (env_)
        {
#ifdef MAPNIK_DEBUG
            std::clog << "occi_environment destructor" << std::endl;
#endif

            oracle::occi::Environment::terminateEnvironment (env_);
            env_ = 0;
        }
    }

    static oracle::occi::Environment* env_;
};

class occi_connection_ptr
{
public:
    occi_connection_ptr (oracle::occi::StatelessConnectionPool* pool)
        : pool_ (pool),
          conn_ (pool->getConnection ()),
          stmt_ (0),
          rs_ (0)
    {
    }

    ~occi_connection_ptr ()
    {
        close_query (true);
    }

    oracle::occi::ResultSet* execute_query (const std::string& s, const unsigned prefetch = 0)
    {
        close_query (false);

        stmt_ = conn_->createStatement (s);

        if (prefetch > 0)
        {
            stmt_->setPrefetchMemorySize (0);
            stmt_->setPrefetchRowCount (prefetch);
        }

        rs_ = stmt_->executeQuery ();

        return rs_;
    }

    oracle::occi::Connection* operator*()
    {
        return conn_;
    }

private:

    void close_query (const bool release_connection)
    {
        if (conn_)
        {
            if (stmt_)
            {
                if (rs_)
                {
                    stmt_->closeResultSet (rs_);
                    rs_ = 0;
                }

                conn_->terminateStatement (stmt_);
                stmt_ = 0;
            }

            if (release_connection)
            {
                pool_->releaseConnection (conn_);
                conn_ = 0;
            }
        }
    }

    oracle::occi::StatelessConnectionPool* pool_;
    oracle::occi::Connection* conn_;
    oracle::occi::Statement* stmt_;
    oracle::occi::ResultSet* rs_;
};

#endif // OCCI_TYPES_HPP
<|endoftext|>


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

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the GNU Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/
#include "CAN_Acquisition.h"
/**
 * Constructor definition for Acquisition class, initialize variables
 *
 * @param _portNumber - This is the physical port number that this object belongs to
 */
cAcquireCAN::cAcquireCAN(ACQ_CAN_PORT _portNumber)
{

    //initialize variables
    ticks        = 0;
    usTicks      = 0;
    prevCount    = 0;
    count        = 0;
    _1mSCntr     = 0;
    _10mSCntr    = 0;
    _100mSCntr   = 0;
    _1000mSCntr  = 0;
    usTsliceMax  = 0;
    usTslice     = 0;
    msgCntRx     = 0;
    msgCntTx     = 0;
    msgCntQuery  = 0;
    queryIndex   = 0;
    RxCtr        = 0;
    TxCtr        = 0;

    //set pointer reference to proper object for that physical port
    portNumber = _portNumber;
    C = (portNumber == CAN_PORT_0) ? &CAN : &CAN2;
}
/**
 * This is the initializtion call that sets up the hardware ports: enable mailboxes, interrupts, sets baud rates etc.
 * This can be called by applicaiton code directly
 *
 * @param -  baud rate for CAN0, NONE = no attempt is made to initialize this port
 */
void cAcquireCAN::initialize(ACQ_BAUD_RATE baud)
{
    if (portNumber == CAN_PORT_0)
    {
        //setup port0 hardware
        if (CAN.init(SystemCoreClock, baud))
        {
            // Disable all CAN0 & CAN1 interrupts
            CAN.disable_interrupt(CAN_DISABLE_ALL_INTERRUPT_MASK);
            //DEBUG THIS TO FIGURE OUT PROPER IRQ
            NVIC_EnableIRQ(CAN0_IRQn);

            //reset mailboxes
            CAN.reset_all_mailbox();

            //setup the receive mailbox for CAN 0 to mailbox 0
            CAN.mailbox_set_mode(0, CAN_MB_RX_MODE);

            //setup the transmit mailbox for CAN 0 to mailbox 1
            CAN.mailbox_set_mode(1, CAN_MB_TX_MODE);
            CAN.mailbox_set_priority(1, 15);
            CAN.mailbox_set_datalen(1, 8);

            //enable RX interrupt for mailbox0
            CAN.enable_interrupt(CAN_IER_MB0);
        }
    }

    if (portNumber == CAN_PORT_1)
    {
        //set physical can1 port reference
        if (CAN2.init(SystemCoreClock, baud))
        {
            // Disable all CAN0 & CAN1 interrupts
            CAN2.disable_interrupt(CAN_DISABLE_ALL_INTERRUPT_MASK);
            //DEBUG THIS TO FIGURE OUT PROPER IRQ
            NVIC_EnableIRQ(CAN1_IRQn);

            //reset mailboxes
            CAN2.reset_all_mailbox();

            //setup the receive mailbox for CAN 1 to mailbox 2
            CAN2.mailbox_set_mode(0, CAN_MB_RX_MODE);

            //setup the transmit mailbox for CAN 1 to mailbox 2
            CAN2.mailbox_set_mode(1, CAN_MB_TX_MODE);
            CAN2.mailbox_set_priority(1, 15);
            CAN2.mailbox_set_datalen(1, 8);

            //enable RX interrupt for mailbox1
            CAN2.enable_interrupt(CAN_IER_MB0);
        }
    }
}

/**
 * This method adds message reference to the collection of rx/tx references,
 * increments counter. Bound by "MAX_NUM_TX_MSGS" macro.
 *
 * @param frame  pointer reference to a message (object) that is intended for reception or transmission
 * @param type   identifies if this message is to be received or transmitted
 */
void cAcquireCAN::addMessage(cCANFrame *frame, ACQ_FRAME_TYPE type)
{
    if (type == TRANSMIT)
    {
        if (frame->rate == QUERY_MSG)
        {
            //add this to the pointer queue for query messages
            queryMsgs[msgCntQuery] = frame;
            msgCntQuery = (msgCntQuery < MAX_NUM_TX_MSGS)? msgCntQuery + 1 : MAX_NUM_TX_MSGS - 1;

        } else
        {
            //add message into collection of pointers to free-running CAN messages, bounds check
            txMsgs[msgCntTx] = frame;
            msgCntTx = (msgCntTx < MAX_NUM_TX_MSGS)? msgCntTx + 1 : MAX_NUM_TX_MSGS - 1;
        }
    }

    if (type == RECEIVE)
    {
        //add messge into collection of pointers, bounds check
        rxMsgs[msgCntRx] = frame;
        msgCntRx = (msgCntRx < MAX_NUM_RX_MSGS)? msgCntRx + 1 : MAX_NUM_RX_MSGS - 1;

        //we need to setup the masks for the ID's in the receive mailbox
        //receive mailbox is mailbox #0

        MAM_mask = buildMAM(frame->ID);
        MID_mask |= frame->ID;

        //program registers
        C->mailbox_set_accept_mask(0, MAM_mask, extended);
        C->mailbox_set_id(0, MID_mask, extended);
    }

}

/**
 * This method is used to build up the MAM mask needed for filtering of RX messages in hardware (see page 1211 of STM datasheet).
 * Each new message must be bitwise compared (NOR) with previous messages to compile a common bitmask.
 *
 * @param ID     New ID being added to the RX queue
 * @return MAM mask file per STM hardware requirements
 */
U32 cAcquireCAN::buildMAM(U32 ID)
{
    U32 XOR_mask;
    U32 retVal;
    U8  i;

    for (i=0; i < msgCntRx; i++)
    {
        //XOR new ID with all messages, all bits that do not match are set to 1 in XOR mask
        XOR_mask |= rxMsgs[i]->ID^ID;
    }
    //per page 1211 of datasheet, invert all non-matching bits to '0'
    retVal = ~XOR_mask;

    return(retVal);
}

/**
 * This method simply scans through collection of references array seeking the messages ready for transmission/update
 *
 * @param rate - transmit all messages scheduled at this rate
 */
void cAcquireCAN::runRates(ACQ_RATE_CAN rate)
{
    UINT8 i ;

    if (rate == QUERY_MSG)
    {
        //check to see if we have any query message entries
        if (msgCntQuery)
        {
            //transmit the next message in the "query-response" queue,
            //only send a single message to allow time for the node to respond before making another request
            TXmsg(queryMsgs[queryIndex]);
            queryIndex = (queryIndex == (msgCntQuery - 1)) ?  0 : queryIndex + 1;
        }

    } else
    {
        //scan through message list and transmit all free-running messages scheduled at this rate
        for (i=0; i < msgCntTx; i++)
        {
            //look for a valid pointer entry for this rate
            if (txMsgs[i]->rate == rate)
            {
                TXmsg(txMsgs[i]);
            }
        }
    }
}

/**
 * This method transmits a single frame using the low-level driver code
 *
 * @param *I  - pointer to cCANFrame object to be transmitted
 */
void cAcquireCAN::TXmsg(cCANFrame *I)
{
    UINT32 mbStatus, status;
    bool validFrame = false;

    // transmit a message here, set up CAN hardware
    //wait until our mailbox is ready to accept a new message and we are not in a bus error state
    do
    {
        mbStatus = C->mailbox_get_status(1);
        status = C->get_status();

    }while (!(mbStatus & CAN_MSR_MRDY) && !(status & CAN_SR_ERRP) && !(status & CAN_SR_BOFF));

    //if a higher level protocol is used, fire callback to handle any modificaiton of the message or abort message
    validFrame = I->CallbackTx();

    //if no abort, stuff the frame and payload
    if (validFrame)
    {
        //set CAN ID  for mailbox
        C->mailbox_set_id(1, I->ID, false);

        //load payloads	for this mailbox
        C->mailbox_set_datal(1,I->U.P.lowerPayload);
        C->mailbox_set_datah(1, I->U.P.upperPayload);

        // send this mailbox
        C->global_send_transfer_cmd(CAN_TCR_MB1);

        //increment transmit counter
        TxCtr += 1;
    }
}

/**
 * This method checks for RX messages that have come into the lower-level buffer
 * and populates the appropriate RX message ID's accordingly (via add message method).
 *
 */
void cAcquireCAN::RXmsg()
{
    UINT8 i;
    bool validFrame = false;

    //temporary frame we'll use to figure out which CAN ID has been received and where to move data to
    RX_CAN_FRAME newFrame;

    //based upon the lower-level CAN library the get_rx_buff method appears to be critical
    noInterrupts();

    //pull all data frames out of the buffer
    while (C->get_rx_buff(&newFrame))
    {
        //scan through message list and read the corresponding header ID
        for (i=0; i < msgCntRx; i++)
        {
            //look for a valid entry for the CAN ID we just received
            if (rxMsgs[i]->ID == newFrame.id)
            {
                //fire callback to higher-level protocol (e.g. check PID parameter ID)
                validFrame = rxMsgs[i]->CallbackRx(&newFrame);

                //stuff the received  payload
                if (validFrame)
                {
                    ///either NO PID OR PID's match so stuff it
                    rxMsgs[i]->U.b[0] = newFrame.data[0];
                    rxMsgs[i]->U.b[1] = newFrame.data[1];
                    rxMsgs[i]->U.b[2] = newFrame.data[2];
                    rxMsgs[i]->U.b[3] = newFrame.data[3];
                    rxMsgs[i]->U.b[4] = newFrame.data[4];
                    rxMsgs[i]->U.b[5] = newFrame.data[5];
                    rxMsgs[i]->U.b[6] = newFrame.data[6];
                    rxMsgs[i]->U.b[7] = newFrame.data[7];
                    //NOTE: re-write in future versions for U32 transfers

                    //increment receive counter
                    RxCtr += 1;
                }
            }
        }
    }
    interrupts();
}

/**
 * This is the scheduler routine that should be run at a periodic rate to keep up with specified transmission rates and to pull received messages
 * from the lower level driver buffers.If run in "loop() / while() / task()" ,it assumes tight execution to keep on schedule.
 * This method keeps track of the number of uSeconds elapsed and calls the "runRates" method for a given rate, allowing for the entire
 * list of CAN messages to be transmitted or received (runRates) at it's scheduled rate. This method should be called from a tightly executed
 * loop in polling mode OR for more deterministic operation from a XmS timer interrupt. This method first looks to read out any received
 * messages and then does the transmission. The rate at which messages are received and updated is equal to that of which this method is
 * called (1mS timer interrupt = messages pulled from low-level RX buffer and updated at ~1mS). In polling mode, this method uses the math
 * that refrences the DUE micros() function to execute at a approx 1mS rate.
 *
 * @param mode   - how this method is called, from a polling mode or periodic timer interrupt
 */
void cAcquireCAN::run(ACQ_MODE mode)
{
    //sample clock to determine elapsed number of microseconds
    count = micros();

    //this is the method that looks for message receptions.
    //As such, RX packet data will only be updated as often as this is called (CAN reception is updated at the interrupt level)
    RXmsg();

    if (mode == POLLING)
    {
        //compensate for rollover
        ticks = (prevCount < count) ? (count - prevCount) : (0xFFFFFFFF - prevCount) + count;

        //capture new previous count
        prevCount = count;

        //accumulate uS ticks
        usTicks += ticks;
        //detect if 1mS passed? clear uSec count if we've determined 1ms has passed
        usTicks = (usTicks >= 1000) ? 0 : usTicks;
    }

    //The followoing transmission rate tasks are driven by a XmS raster period. (timer or tight polling loop)
    if (mode == TIMER_2mS || ((mode == POLLING) && !usTicks))
    {
        //increment 1mS tick counter
        _1mSCntr = (mode == TIMER_2mS) ? _1mSCntr + 2 : _1mSCntr + 1;

        //after Xms has passed, run all xHz transmissions based upon XmS tick counter

        //transmit the next message in the "query-response" queue
        if ((_1mSCntr - _queryCntr) >= QUERY_MS)
        {
            //periodic requests
            runRates(QUERY_MSG);
            _queryCntr = _1mSCntr;
        }

        //transmit the "free-running" CAN messages
        //100Hz
        if ((_1mSCntr - _10mSCntr) >= 10)
        {
            runRates(_100Hz_Rate);
            _10mSCntr = _1mSCntr;
        }

        //10Hz
        if ((_1mSCntr - _100mSCntr) >= 100)
        {
            runRates(_10Hz_Rate);
            _100mSCntr = _1mSCntr;
        }

        //5Hz
        if ((_1mSCntr - _200mSCntr) >=  200)
        {
            runRates(_5Hz_Rate);
            _200mSCntr = _1mSCntr;
        }

        //1Hz
        if (_1mSCntr >= 1000)
        {
            runRates(_1Hz_Rate);
            _queryCntr  = 0;
            _1mSCntr    = 0;
            _10mSCntr   = 0;
            _100mSCntr  = 0;
            _200mSCntr  = 0;
        }

        //perform diagnostic timer, provides service routine timing in uSec
        usTsliceEnd = micros();
        usTslice = (count < usTsliceEnd) ? usTsliceEnd - count : (0xFFFFFFFF - count) + usTsliceEnd;

        //latch maximum value
        usTsliceMax = usTslice > usTsliceMax ? usTslice : usTsliceMax;
    }
}

/**
* diagnostic method. Retrieves acquisition execution time in uS, diagnostics.
*
* @param max - "true" specifies maximum seen value (latched), otherwise last measured value returned
* @return - number of uSecs elapsed during "run" method
*/
UINT32 cAcquireCAN::getTimeSlice(bool max)
{
    return( max ? usTsliceMax : usTslice );
}

/**
 * resets "max" capture time returned by getTimeSlice. This is used for debugging
 */
void cAcquireCAN::resetTimeSlice()
{
    usTsliceMax = 0;
}

/**
 * Get the total number of messages that have been transmitted (rolling)
 *
 * @return - U32 rolling counter of number of messages transmitted
 */
UINT32 cAcquireCAN::getTxCtr()
{
    return(TxCtr);
}

/**
 * Get the total number of messages that have been received (rolling)
 *
 * @return - U32 rolling counter of number of messages received
 */
UINT32 cAcquireCAN::getRxCtr()
{
    return(RxCtr);
}

<commit_msg>copy and paste error on last rev<commit_after>/*
  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the GNU Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/
#include "CAN_Acquisition.h"
/**
 * Constructor definition for Acquisition class, initialize variables
 *
 * @param _portNumber - This is the physical port number that this object belongs to
 */
cAcquireCAN::cAcquireCAN(ACQ_CAN_PORT _portNumber)
{

    //initialize variables
    ticks        = 0;
    usTicks      = 0;
    prevCount    = 0;
    count        = 0;
    _1mSCntr     = 0;
    _10mSCntr    = 0;
    _100mSCntr   = 0;
    _1000mSCntr  = 0;
    usTsliceMax  = 0;
    usTslice     = 0;
    msgCntRx     = 0;
    msgCntTx     = 0;
    msgCntQuery  = 0;
    queryIndex   = 0;
    RxCtr        = 0;
    TxCtr        = 0;

    //set pointer reference to proper object for that physical port
    portNumber = _portNumber;
    C = (portNumber == CAN_PORT_0) ? &CAN : &CAN2;
}
/**
 * This is the initializtion call that sets up the hardware ports: enable mailboxes, interrupts, sets baud rates etc.
 * This can be called by applicaiton code directly
 *
 * @param -  baud rate for CAN0, NONE = no attempt is made to initialize this port
 */
void cAcquireCAN::initialize(ACQ_BAUD_RATE baud)
{
    if (portNumber == CAN_PORT_0)
    {
        //setup port0 hardware
        if (CAN.init(SystemCoreClock, baud))
        {
            // Disable all CAN0 & CAN1 interrupts
            CAN.disable_interrupt(CAN_DISABLE_ALL_INTERRUPT_MASK);
            //DEBUG THIS TO FIGURE OUT PROPER IRQ
            NVIC_EnableIRQ(CAN0_IRQn);

            //reset mailboxes
            CAN.reset_all_mailbox();

            //setup the receive mailbox for CAN 0 to mailbox 0
            CAN.mailbox_set_mode(0, CAN_MB_RX_MODE);

            //setup the transmit mailbox for CAN 0 to mailbox 1
            CAN.mailbox_set_mode(1, CAN_MB_TX_MODE);
            CAN.mailbox_set_priority(1, 15);
            CAN.mailbox_set_datalen(1, 8);

            //enable RX interrupt for mailbox0
            CAN.enable_interrupt(CAN_IER_MB0);
        }
    }

    if (portNumber == CAN_PORT_1)
    {
        //set physical can1 port reference
        if (CAN2.init(SystemCoreClock, baud))
        {
            // Disable all CAN0 & CAN1 interrupts
            CAN2.disable_interrupt(CAN_DISABLE_ALL_INTERRUPT_MASK);
            //DEBUG THIS TO FIGURE OUT PROPER IRQ
            NVIC_EnableIRQ(CAN1_IRQn);

            //reset mailboxes
            CAN2.reset_all_mailbox();

            //setup the receive mailbox for CAN 1 to mailbox 2
            CAN2.mailbox_set_mode(0, CAN_MB_RX_MODE);

            //setup the transmit mailbox for CAN 1 to mailbox 2
            CAN2.mailbox_set_mode(1, CAN_MB_TX_MODE);
            CAN2.mailbox_set_priority(1, 15);
            CAN2.mailbox_set_datalen(1, 8);

            //enable RX interrupt for mailbox1
            CAN2.enable_interrupt(CAN_IER_MB0);
        }
    }
}

/**
 * This method adds message reference to the collection of rx/tx references,
 * increments counter. Bound by "MAX_NUM_TX_MSGS" macro.
 *
 * @param frame  pointer reference to a message (object) that is intended for reception or transmission
 * @param type   identifies if this message is to be received or transmitted
 */
void cAcquireCAN::addMessage(cCANFrame *frame, ACQ_FRAME_TYPE type)
{
    if (type == TRANSMIT)
    {
        if (frame->rate == QUERY_MSG)
        {
            //add this to the pointer queue for query messages
            queryMsgs[msgCntQuery] = frame;
            msgCntQuery = (msgCntQuery < MAX_NUM_TX_MSGS)? msgCntQuery + 1 : MAX_NUM_TX_MSGS - 1;

        } else
        {
            //add message into collection of pointers to free-running CAN messages, bounds check
            txMsgs[msgCntTx] = frame;
            msgCntTx = (msgCntTx < MAX_NUM_TX_MSGS)? msgCntTx + 1 : MAX_NUM_TX_MSGS - 1;
        }
    }

    if (type == RECEIVE)
    {
        //add messge into collection of pointers, bounds check
        rxMsgs[msgCntRx] = frame;
        msgCntRx = (msgCntRx < MAX_NUM_RX_MSGS)? msgCntRx + 1 : MAX_NUM_RX_MSGS - 1;

        //we need to setup the masks for the ID's in the receive mailbox
        //receive mailbox is mailbox #0

        MAM_mask = buildMAM(frame->ID);
        MID_mask |= frame->ID;

        //program registers
        C->mailbox_set_accept_mask(0, MAM_mask);
        C->mailbox_set_id(0, MID_mask);
    }

}

/**
 * This method is used to build up the MAM mask needed for filtering of RX messages in hardware (see page 1211 of STM datasheet).
 * Each new message must be bitwise compared (NOR) with previous messages to compile a common bitmask.
 *
 * @param ID     New ID being added to the RX queue
 * @return MAM mask file per STM hardware requirements
 */
U32 cAcquireCAN::buildMAM(U32 ID)
{
    U32 XOR_mask;
    U32 retVal;
    U8  i;

    for (i=0; i < msgCntRx; i++)
    {
        //XOR new ID with all messages, all bits that do not match are set to 1 in XOR mask
        XOR_mask |= rxMsgs[i]->ID^ID;
    }
    //per page 1211 of datasheet, invert all non-matching bits to '0'
    retVal = ~XOR_mask;

    return(retVal);
}

/**
 * This method simply scans through collection of references array seeking the messages ready for transmission/update
 *
 * @param rate - transmit all messages scheduled at this rate
 */
void cAcquireCAN::runRates(ACQ_RATE_CAN rate)
{
    UINT8 i ;

    if (rate == QUERY_MSG)
    {
        //check to see if we have any query message entries
        if (msgCntQuery)
        {
            //transmit the next message in the "query-response" queue,
            //only send a single message to allow time for the node to respond before making another request
            TXmsg(queryMsgs[queryIndex]);
            queryIndex = (queryIndex == (msgCntQuery - 1)) ?  0 : queryIndex + 1;
        }

    } else
    {
        //scan through message list and transmit all free-running messages scheduled at this rate
        for (i=0; i < msgCntTx; i++)
        {
            //look for a valid pointer entry for this rate
            if (txMsgs[i]->rate == rate)
            {
                TXmsg(txMsgs[i]);
            }
        }
    }
}

/**
 * This method transmits a single frame using the low-level driver code
 *
 * @param *I  - pointer to cCANFrame object to be transmitted
 */
void cAcquireCAN::TXmsg(cCANFrame *I)
{
    UINT32 mbStatus, status;
    bool validFrame = false;

    // transmit a message here, set up CAN hardware
    //wait until our mailbox is ready to accept a new message and we are not in a bus error state
    do
    {
        mbStatus = C->mailbox_get_status(1);
        status = C->get_status();

    }while (!(mbStatus & CAN_MSR_MRDY) && !(status & CAN_SR_ERRP) && !(status & CAN_SR_BOFF));

    //if a higher level protocol is used, fire callback to handle any modificaiton of the message or abort message
    validFrame = I->CallbackTx();

    //if no abort, stuff the frame and payload
    if (validFrame)
    {
        //set CAN ID  for mailbox
        C->mailbox_set_id(1, I->ID, false);

        //load payloads	for this mailbox
        C->mailbox_set_datal(1,I->U.P.lowerPayload);
        C->mailbox_set_datah(1, I->U.P.upperPayload);

        // send this mailbox
        C->global_send_transfer_cmd(CAN_TCR_MB1);

        //increment transmit counter
        TxCtr += 1;
    }
}

/**
 * This method checks for RX messages that have come into the lower-level buffer
 * and populates the appropriate RX message ID's accordingly (via add message method).
 *
 */
void cAcquireCAN::RXmsg()
{
    UINT8 i;
    bool validFrame = false;

    //temporary frame we'll use to figure out which CAN ID has been received and where to move data to
    RX_CAN_FRAME newFrame;

    //based upon the lower-level CAN library the get_rx_buff method appears to be critical
    noInterrupts();

    //pull all data frames out of the buffer
    while (C->get_rx_buff(&newFrame))
    {
        //scan through message list and read the corresponding header ID
        for (i=0; i < msgCntRx; i++)
        {
            //look for a valid entry for the CAN ID we just received
            if (rxMsgs[i]->ID == newFrame.id)
            {
                //fire callback to higher-level protocol (e.g. check PID parameter ID)
                validFrame = rxMsgs[i]->CallbackRx(&newFrame);

                //stuff the received  payload
                if (validFrame)
                {
                    ///either NO PID OR PID's match so stuff it
                    rxMsgs[i]->U.b[0] = newFrame.data[0];
                    rxMsgs[i]->U.b[1] = newFrame.data[1];
                    rxMsgs[i]->U.b[2] = newFrame.data[2];
                    rxMsgs[i]->U.b[3] = newFrame.data[3];
                    rxMsgs[i]->U.b[4] = newFrame.data[4];
                    rxMsgs[i]->U.b[5] = newFrame.data[5];
                    rxMsgs[i]->U.b[6] = newFrame.data[6];
                    rxMsgs[i]->U.b[7] = newFrame.data[7];
                    //NOTE: re-write in future versions for U32 transfers

                    //increment receive counter
                    RxCtr += 1;
                }
            }
        }
    }
    interrupts();
}

/**
 * This is the scheduler routine that should be run at a periodic rate to keep up with specified transmission rates and to pull received messages
 * from the lower level driver buffers.If run in "loop() / while() / task()" ,it assumes tight execution to keep on schedule.
 * This method keeps track of the number of uSeconds elapsed and calls the "runRates" method for a given rate, allowing for the entire
 * list of CAN messages to be transmitted or received (runRates) at it's scheduled rate. This method should be called from a tightly executed
 * loop in polling mode OR for more deterministic operation from a XmS timer interrupt. This method first looks to read out any received
 * messages and then does the transmission. The rate at which messages are received and updated is equal to that of which this method is
 * called (1mS timer interrupt = messages pulled from low-level RX buffer and updated at ~1mS). In polling mode, this method uses the math
 * that refrences the DUE micros() function to execute at a approx 1mS rate.
 *
 * @param mode   - how this method is called, from a polling mode or periodic timer interrupt
 */
void cAcquireCAN::run(ACQ_MODE mode)
{
    //sample clock to determine elapsed number of microseconds
    count = micros();

    //this is the method that looks for message receptions.
    //As such, RX packet data will only be updated as often as this is called (CAN reception is updated at the interrupt level)
    RXmsg();

    if (mode == POLLING)
    {
        //compensate for rollover
        ticks = (prevCount < count) ? (count - prevCount) : (0xFFFFFFFF - prevCount) + count;

        //capture new previous count
        prevCount = count;

        //accumulate uS ticks
        usTicks += ticks;
        //detect if 1mS passed? clear uSec count if we've determined 1ms has passed
        usTicks = (usTicks >= 1000) ? 0 : usTicks;
    }

    //The followoing transmission rate tasks are driven by a XmS raster period. (timer or tight polling loop)
    if (mode == TIMER_2mS || ((mode == POLLING) && !usTicks))
    {
        //increment 1mS tick counter
        _1mSCntr = (mode == TIMER_2mS) ? _1mSCntr + 2 : _1mSCntr + 1;

        //after Xms has passed, run all xHz transmissions based upon XmS tick counter

        //transmit the next message in the "query-response" queue
        if ((_1mSCntr - _queryCntr) >= QUERY_MS)
        {
            //periodic requests
            runRates(QUERY_MSG);
            _queryCntr = _1mSCntr;
        }

        //transmit the "free-running" CAN messages
        //100Hz
        if ((_1mSCntr - _10mSCntr) >= 10)
        {
            runRates(_100Hz_Rate);
            _10mSCntr = _1mSCntr;
        }

        //10Hz
        if ((_1mSCntr - _100mSCntr) >= 100)
        {
            runRates(_10Hz_Rate);
            _100mSCntr = _1mSCntr;
        }

        //5Hz
        if ((_1mSCntr - _200mSCntr) >=  200)
        {
            runRates(_5Hz_Rate);
            _200mSCntr = _1mSCntr;
        }

        //1Hz
        if (_1mSCntr >= 1000)
        {
            runRates(_1Hz_Rate);
            _queryCntr  = 0;
            _1mSCntr    = 0;
            _10mSCntr   = 0;
            _100mSCntr  = 0;
            _200mSCntr  = 0;
        }

        //perform diagnostic timer, provides service routine timing in uSec
        usTsliceEnd = micros();
        usTslice = (count < usTsliceEnd) ? usTsliceEnd - count : (0xFFFFFFFF - count) + usTsliceEnd;

        //latch maximum value
        usTsliceMax = usTslice > usTsliceMax ? usTslice : usTsliceMax;
    }
}

/**
* diagnostic method. Retrieves acquisition execution time in uS, diagnostics.
*
* @param max - "true" specifies maximum seen value (latched), otherwise last measured value returned
* @return - number of uSecs elapsed during "run" method
*/
UINT32 cAcquireCAN::getTimeSlice(bool max)
{
    return( max ? usTsliceMax : usTslice );
}

/**
 * resets "max" capture time returned by getTimeSlice. This is used for debugging
 */
void cAcquireCAN::resetTimeSlice()
{
    usTsliceMax = 0;
}

/**
 * Get the total number of messages that have been transmitted (rolling)
 *
 * @return - U32 rolling counter of number of messages transmitted
 */
UINT32 cAcquireCAN::getTxCtr()
{
    return(TxCtr);
}

/**
 * Get the total number of messages that have been received (rolling)
 *
 * @return - U32 rolling counter of number of messages received
 */
UINT32 cAcquireCAN::getRxCtr()
{
    return(RxCtr);
}

<|endoftext|>


<commit_before>/*
 * ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1
 *
 * ``The contents of this file are subject to the Mozilla Public License
 * Version 1.1 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
 * License for the specific language governing rights and limitations
 * under the License.
 *
 * The Original Code is SimpleAmqpClient for RabbitMQ.
 *
 * The Initial Developer of the Original Code is Alan Antonuk.
 * Original code is Copyright (C) Alan Antonuk.
 *
 * All Rights Reserved.
 *
 * Contributor(s): ______________________________________.
 *
 * Alternatively, the contents of this file may be used under the terms
 * of the GNU General Public License Version 2 or later (the "GPL"), in
 * which case the provisions of the GPL are applicable instead of those
 * above. If you wish to allow use of your version of this file only
 * under the terms of the GPL, and not to allow others to use your
 * version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the
 * notice and other provisions required by the GPL. If you do not
 * delete the provisions above, a recipient may use your version of
 * this file under the terms of any one of the MPL or the GPL.
 *
 * ***** END LICENSE BLOCK *****
 */

#include "Channel.h"
#include "BasicMessage.h"
#include "SimpleRpcServer.h"

#include <boost/bind.hpp>
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/thread/thread.hpp>
#include <boost/utility.hpp>

#include <iostream>
#include <stdlib.h>

using namespace AmqpClient;

class thread_body : boost::noncopyable
{
	public:
		thread_body()
		{
			char* szBroker = getenv("AMQP_BROKER");
			Channel::ptr_t channel;
			if (szBroker != NULL)
				channel = Channel::Create(szBroker);
			else
				channel = Channel::Create();

			server = SimpleRpcServer::Create(channel);

			m_thread =
				boost::make_shared<boost::thread>(boost::bind(&thread_body::run,
							this));
		}

		virtual ~thread_body()
		{
			std::cout << "Is joinable " << m_thread->joinable() << "inter reqd: " << m_thread->interruption_requested() << std::endl;
			m_thread->interrupt();
			std::cout << "Is joinable " << m_thread->joinable() << "inter reqd: " << m_thread->interruption_requested() << std::endl;
			m_thread->join();
		}

		void run()
		{
			while (!boost::this_thread::interruption_requested())
			{
				std::cout << "Waiting for message... " << std::flush;
				BasicMessage::ptr_t message;
				if (server->GetNextIncomingMessage(message, 1))
				{
					std::cout << "message received.\n";
				}
				else
				{
					std::cout << "message not received.\n";
				}
			}
		}

		SimpleRpcServer::ptr_t server;
		boost::shared_ptr<boost::thread> m_thread;

};
int main()
{
	boost::shared_ptr<thread_body> body = boost::make_shared<thread_body>();

	boost::this_thread::sleep(boost::posix_time::seconds(3));

	return 0;
}
<commit_msg>Adding fix to for date_time link error on win32<commit_after>/*
 * ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1
 *
 * ``The contents of this file are subject to the Mozilla Public License
 * Version 1.1 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
 * License for the specific language governing rights and limitations
 * under the License.
 *
 * The Original Code is SimpleAmqpClient for RabbitMQ.
 *
 * The Initial Developer of the Original Code is Alan Antonuk.
 * Original code is Copyright (C) Alan Antonuk.
 *
 * All Rights Reserved.
 *
 * Contributor(s): ______________________________________.
 *
 * Alternatively, the contents of this file may be used under the terms
 * of the GNU General Public License Version 2 or later (the "GPL"), in
 * which case the provisions of the GPL are applicable instead of those
 * above. If you wish to allow use of your version of this file only
 * under the terms of the GPL, and not to allow others to use your
 * version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the
 * notice and other provisions required by the GPL. If you do not
 * delete the provisions above, a recipient may use your version of
 * this file under the terms of any one of the MPL or the GPL.
 *
 * ***** END LICENSE BLOCK *****
 */

#include "Channel.h"
#include "BasicMessage.h"
#include "SimpleRpcServer.h"

#define BOOST_ALL_NO_LIB
#include <boost/bind.hpp>
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/thread/thread.hpp>
#include <boost/utility.hpp>

#include <iostream>
#include <stdlib.h>

using namespace AmqpClient;

class thread_body : boost::noncopyable
{
	public:
		thread_body()
		{
			char* szBroker = getenv("AMQP_BROKER");
			Channel::ptr_t channel;
			if (szBroker != NULL)
				channel = Channel::Create(szBroker);
			else
				channel = Channel::Create();

			server = SimpleRpcServer::Create(channel);

			m_thread =
				boost::make_shared<boost::thread>(boost::bind(&thread_body::run,
							this));
		}

		virtual ~thread_body()
		{
			std::cout << "Is joinable " << m_thread->joinable() << "inter reqd: " << m_thread->interruption_requested() << std::endl;
			m_thread->interrupt();
			std::cout << "Is joinable " << m_thread->joinable() << "inter reqd: " << m_thread->interruption_requested() << std::endl;
			m_thread->join();
		}

		void run()
		{
			while (!boost::this_thread::interruption_requested())
			{
				std::cout << "Waiting for message... " << std::flush;
				BasicMessage::ptr_t message;
				if (server->GetNextIncomingMessage(message, 1))
				{
					std::cout << "message received.\n";
				}
				else
				{
					std::cout << "message not received.\n";
				}
			}
		}

		SimpleRpcServer::ptr_t server;
		boost::shared_ptr<boost::thread> m_thread;

};
int main()
{
	boost::shared_ptr<thread_body> body = boost::make_shared<thread_body>();

	boost::this_thread::sleep(boost::posix_time::seconds(3));

	return 0;
}
<|endoftext|>


<commit_before>#include "PreferencesDialog.hpp"
#include "ui_PreferencesDialog.h"
#include <QDebug>
#include <QFileDialog>
#include <QMessageBox>
#include "Extensions/Filters/WidgetFocusHandlerEventFilter.hpp"
#include "Logics/Config.hpp"
#include "Logics/Exceptions/Exception.hpp"

PreferencesDialog::PreferencesDialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::PreferencesDialog)
{
    this->setAttribute(Qt::WA_DeleteOnClose);
    this->ui->setupUi(this);
    this->installEventFilter(new WidgetFocusHandlerEventFilter(this));
    this->ui->tabWidget->setFocus();

    this->ui->checkBox_useCustomStylesheet->setChecked(Config::isUsingCustomStyleSheet());
    this->ui->lineEdit_customStylesheetPath->setText(Config::getGlobalStylesheetPath());
    this->ui->lineEdit_playerInforDatabasePath->setText(Config::getDatabasePath());
}

PreferencesDialog::~PreferencesDialog(void)
{
    delete ui;
}

void PreferencesDialog::on_pushButton_browseCustomStylesheet_clicked(void)
{
    auto stylesheetPath = QFileDialog::getOpenFileName(this, "Open Stylesheet");
    if (stylesheetPath.isEmpty())
        return;

    // TODO: validate choosen file is stylesheet
    QFile stylesheetFile(stylesheetPath);
    if (!stylesheetFile.exists())
    {
        qDebug() << "Stylesheet file does not exist [" << stylesheetPath << "]";
        return;
    }

    Config::saveGlobalStylesheetPath(stylesheetPath);
    Config::setIsUsingCustomStyleSheet(true);
    qApp->setStyleSheet(Config::getGlobalStylesheet());
    this->ui->checkBox_useCustomStylesheet->setChecked(Config::isUsingCustomStyleSheet());
}

void PreferencesDialog::on_pushButton_reloadCustomStylesheet_clicked(void)
{
    qApp->setStyleSheet(Config::getGlobalStylesheet());
    Config::setIsUsingCustomStyleSheet(true);
    this->ui->checkBox_useCustomStylesheet->setChecked(Config::isUsingCustomStyleSheet());
}

void PreferencesDialog::on_pushButton_reloadSystemStylesheet_clicked(void)
{
    qApp->setStyleSheet("");
    Config::setIsUsingCustomStyleSheet(false);
    this->ui->checkBox_useCustomStylesheet->setChecked(Config::isUsingCustomStyleSheet());
}

void PreferencesDialog::on_checkBox_useCustomStylesheet_toggled(bool checked)
{
    Config::setIsUsingCustomStyleSheet(checked);
    qApp->setStyleSheet(Config::getGlobalStylesheet());
}

void PreferencesDialog::on_pushButton_browsePlayerInfoDatabase_clicked(void)
{
    auto databasePath = QFileDialog::getOpenFileName(this, "Open Database");
    if (databasePath.isEmpty())
        return;

    try
    {
        Config::saveDatabasePath(databasePath);
    }
    catch (Exception & e)
    {
        QMessageBox::critical(this, "Error Saving database path", e.what());
    }
}
<commit_msg>fix db lineedit not updated after browsing<commit_after>#include "PreferencesDialog.hpp"
#include "ui_PreferencesDialog.h"
#include <QDebug>
#include <QFileDialog>
#include <QMessageBox>
#include "Extensions/Filters/WidgetFocusHandlerEventFilter.hpp"
#include "Logics/Config.hpp"
#include "Logics/Exceptions/Exception.hpp"

PreferencesDialog::PreferencesDialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::PreferencesDialog)
{
    this->setAttribute(Qt::WA_DeleteOnClose);
    this->ui->setupUi(this);
    this->installEventFilter(new WidgetFocusHandlerEventFilter(this));
    this->ui->tabWidget->setFocus();

    this->ui->checkBox_useCustomStylesheet->setChecked(Config::isUsingCustomStyleSheet());
    this->ui->lineEdit_customStylesheetPath->setText(Config::getGlobalStylesheetPath());
    this->ui->lineEdit_playerInforDatabasePath->setText(Config::getDatabasePath());
}

PreferencesDialog::~PreferencesDialog(void)
{
    delete ui;
}

void PreferencesDialog::on_pushButton_browseCustomStylesheet_clicked(void)
{
    auto stylesheetPath = QFileDialog::getOpenFileName(this, "Open Stylesheet");
    if (stylesheetPath.isEmpty())
        return;

    // TODO: validate choosen file is stylesheet
    QFile stylesheetFile(stylesheetPath);
    if (!stylesheetFile.exists())
    {
        qDebug() << "Stylesheet file does not exist [" << stylesheetPath << "]";
        return;
    }

    Config::saveGlobalStylesheetPath(stylesheetPath);
    Config::setIsUsingCustomStyleSheet(true);
    qApp->setStyleSheet(Config::getGlobalStylesheet());
    this->ui->checkBox_useCustomStylesheet->setChecked(Config::isUsingCustomStyleSheet());
}

void PreferencesDialog::on_pushButton_reloadCustomStylesheet_clicked(void)
{
    qApp->setStyleSheet(Config::getGlobalStylesheet());
    Config::setIsUsingCustomStyleSheet(true);
    this->ui->checkBox_useCustomStylesheet->setChecked(Config::isUsingCustomStyleSheet());
}

void PreferencesDialog::on_pushButton_reloadSystemStylesheet_clicked(void)
{
    qApp->setStyleSheet("");
    Config::setIsUsingCustomStyleSheet(false);
    this->ui->checkBox_useCustomStylesheet->setChecked(Config::isUsingCustomStyleSheet());
}

void PreferencesDialog::on_checkBox_useCustomStylesheet_toggled(bool checked)
{
    Config::setIsUsingCustomStyleSheet(checked);
    qApp->setStyleSheet(Config::getGlobalStylesheet());
}

void PreferencesDialog::on_pushButton_browsePlayerInfoDatabase_clicked(void)
{
    auto databasePath = QFileDialog::getOpenFileName(this, "Open Database");
    if (databasePath.isEmpty())
        return;

    try
    {
        Config::saveDatabasePath(databasePath);
        this->ui->lineEdit_playerInforDatabasePath->setText(databasePath);
    }
    catch (Exception & e)
    {
        QMessageBox::critical(this, "Error Saving database path", e.what());
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2015-2017 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <bench/bench.h>

#include <crypto/sha256.h>
#include <key.h>
#include <validation.h>
#include <util.h>
#include <random.h>

#include <boost/lexical_cast.hpp>

#include <memory>

static const int64_t DEFAULT_BENCH_EVALUATIONS = 5;
static const char* DEFAULT_BENCH_FILTER = ".*";
static const char* DEFAULT_BENCH_SCALING = "1.0";
static const char* DEFAULT_BENCH_PRINTER = "console";
static const char* DEFAULT_PLOT_PLOTLYURL = "https://cdn.plot.ly/plotly-latest.min.js";
static const int64_t DEFAULT_PLOT_WIDTH = 1024;
static const int64_t DEFAULT_PLOT_HEIGHT = 768;

static void SetupBenchArgs()
{
    gArgs.AddArg("-?", "Print this help message and exit", false, OptionsCategory::OPTIONS);
    gArgs.AddArg("-list", "List benchmarks without executing them. Can be combined with -scaling and -filter", false, OptionsCategory::OPTIONS);
    gArgs.AddArg("-evals=<n>", strprintf("Number of measurement evaluations to perform. (default: %u)", DEFAULT_BENCH_EVALUATIONS), false, OptionsCategory::OPTIONS);
    gArgs.AddArg("-filter=<regex>", strprintf("Regular expression filter to select benchmark by name (default: %s)", DEFAULT_BENCH_FILTER), false, OptionsCategory::OPTIONS);
    gArgs.AddArg("-scaling=<n>", strprintf("Scaling factor for benchmark's runtime (default: %u)", DEFAULT_BENCH_SCALING), false, OptionsCategory::OPTIONS);
    gArgs.AddArg("-printer=(console|plot)", strprintf("Choose printer format. console: print data to console. plot: Print results as HTML graph (default: %s)", DEFAULT_BENCH_PRINTER), false, OptionsCategory::OPTIONS);
    gArgs.AddArg("-plot-plotlyurl=<uri>", strprintf("URL to use for plotly.js (default: %s)", DEFAULT_PLOT_PLOTLYURL), false, OptionsCategory::OPTIONS);
    gArgs.AddArg("-plot-width=<x>", strprintf("Plot width in pixel (default: %u)", DEFAULT_PLOT_WIDTH), false, OptionsCategory::OPTIONS);
    gArgs.AddArg("-plot-height=<x>", strprintf("Plot height in pixel (default: %u)", DEFAULT_PLOT_HEIGHT), false, OptionsCategory::OPTIONS);

    // Hidden
    gArgs.AddArg("-h", "", false, OptionsCategory::HIDDEN);
    gArgs.AddArg("-help", "", false, OptionsCategory::HIDDEN);
}

int main(int argc, char** argv)
{
    SetupBenchArgs();
    std::string error;
    if (!gArgs.ParseParameters(argc, argv, error)) {
        fprintf(stderr, "Error parsing command line arguments: %s\n", error.c_str());
        return EXIT_FAILURE;
    }

    if (HelpRequested(gArgs)) {
        std::cout << gArgs.GetHelpMessage();

        return EXIT_SUCCESS;
    }

    SHA256AutoDetect();
    RandomInit();
    ECC_Start();
    SetupEnvironment();

    int64_t evaluations = gArgs.GetArg("-evals", DEFAULT_BENCH_EVALUATIONS);
    std::string regex_filter = gArgs.GetArg("-filter", DEFAULT_BENCH_FILTER);
    std::string scaling_str = gArgs.GetArg("-scaling", DEFAULT_BENCH_SCALING);
    bool is_list_only = gArgs.GetBoolArg("-list", false);

    double scaling_factor = boost::lexical_cast<double>(scaling_str);

    std::unique_ptr<benchmark::Printer> printer(new benchmark::ConsolePrinter());
    std::string printer_arg = gArgs.GetArg("-printer", DEFAULT_BENCH_PRINTER);
    if ("plot" == printer_arg) {
        printer.reset(new benchmark::PlotlyPrinter(
            gArgs.GetArg("-plot-plotlyurl", DEFAULT_PLOT_PLOTLYURL),
            gArgs.GetArg("-plot-width", DEFAULT_PLOT_WIDTH),
            gArgs.GetArg("-plot-height", DEFAULT_PLOT_HEIGHT)));
    }

    benchmark::BenchRunner::RunAll(*printer, evaluations, scaling_factor, regex_filter, is_list_only);

    ECC_Stop();

    return EXIT_SUCCESS;
}
<commit_msg>bench: Use non-throwing ParseDouble(...) instead of throwing boost::lexical_cast<double>(...)<commit_after>// Copyright (c) 2015-2017 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <bench/bench.h>

#include <crypto/sha256.h>
#include <key.h>
#include <random.h>
#include <util.h>
#include <utilstrencodings.h>
#include <validation.h>

#include <memory>

static const int64_t DEFAULT_BENCH_EVALUATIONS = 5;
static const char* DEFAULT_BENCH_FILTER = ".*";
static const char* DEFAULT_BENCH_SCALING = "1.0";
static const char* DEFAULT_BENCH_PRINTER = "console";
static const char* DEFAULT_PLOT_PLOTLYURL = "https://cdn.plot.ly/plotly-latest.min.js";
static const int64_t DEFAULT_PLOT_WIDTH = 1024;
static const int64_t DEFAULT_PLOT_HEIGHT = 768;

static void SetupBenchArgs()
{
    gArgs.AddArg("-?", "Print this help message and exit", false, OptionsCategory::OPTIONS);
    gArgs.AddArg("-list", "List benchmarks without executing them. Can be combined with -scaling and -filter", false, OptionsCategory::OPTIONS);
    gArgs.AddArg("-evals=<n>", strprintf("Number of measurement evaluations to perform. (default: %u)", DEFAULT_BENCH_EVALUATIONS), false, OptionsCategory::OPTIONS);
    gArgs.AddArg("-filter=<regex>", strprintf("Regular expression filter to select benchmark by name (default: %s)", DEFAULT_BENCH_FILTER), false, OptionsCategory::OPTIONS);
    gArgs.AddArg("-scaling=<n>", strprintf("Scaling factor for benchmark's runtime (default: %u)", DEFAULT_BENCH_SCALING), false, OptionsCategory::OPTIONS);
    gArgs.AddArg("-printer=(console|plot)", strprintf("Choose printer format. console: print data to console. plot: Print results as HTML graph (default: %s)", DEFAULT_BENCH_PRINTER), false, OptionsCategory::OPTIONS);
    gArgs.AddArg("-plot-plotlyurl=<uri>", strprintf("URL to use for plotly.js (default: %s)", DEFAULT_PLOT_PLOTLYURL), false, OptionsCategory::OPTIONS);
    gArgs.AddArg("-plot-width=<x>", strprintf("Plot width in pixel (default: %u)", DEFAULT_PLOT_WIDTH), false, OptionsCategory::OPTIONS);
    gArgs.AddArg("-plot-height=<x>", strprintf("Plot height in pixel (default: %u)", DEFAULT_PLOT_HEIGHT), false, OptionsCategory::OPTIONS);

    // Hidden
    gArgs.AddArg("-h", "", false, OptionsCategory::HIDDEN);
    gArgs.AddArg("-help", "", false, OptionsCategory::HIDDEN);
}

int main(int argc, char** argv)
{
    SetupBenchArgs();
    std::string error;
    if (!gArgs.ParseParameters(argc, argv, error)) {
        fprintf(stderr, "Error parsing command line arguments: %s\n", error.c_str());
        return EXIT_FAILURE;
    }

    if (HelpRequested(gArgs)) {
        std::cout << gArgs.GetHelpMessage();

        return EXIT_SUCCESS;
    }

    SHA256AutoDetect();
    RandomInit();
    ECC_Start();
    SetupEnvironment();

    int64_t evaluations = gArgs.GetArg("-evals", DEFAULT_BENCH_EVALUATIONS);
    std::string regex_filter = gArgs.GetArg("-filter", DEFAULT_BENCH_FILTER);
    std::string scaling_str = gArgs.GetArg("-scaling", DEFAULT_BENCH_SCALING);
    bool is_list_only = gArgs.GetBoolArg("-list", false);

    double scaling_factor;
    if (!ParseDouble(scaling_str, &scaling_factor)) {
        fprintf(stderr, "Error parsing scaling factor as double: %s\n", scaling_str.c_str());
        return EXIT_FAILURE;
    }

    std::unique_ptr<benchmark::Printer> printer(new benchmark::ConsolePrinter());
    std::string printer_arg = gArgs.GetArg("-printer", DEFAULT_BENCH_PRINTER);
    if ("plot" == printer_arg) {
        printer.reset(new benchmark::PlotlyPrinter(
            gArgs.GetArg("-plot-plotlyurl", DEFAULT_PLOT_PLOTLYURL),
            gArgs.GetArg("-plot-width", DEFAULT_PLOT_WIDTH),
            gArgs.GetArg("-plot-height", DEFAULT_PLOT_HEIGHT)));
    }

    benchmark::BenchRunner::RunAll(*printer, evaluations, scaling_factor, regex_filter, is_list_only);

    ECC_Stop();

    return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>// bitmessage cracker, build with g++ or MSVS to a shared library, use included python code for usage under bitmessage
#ifdef _WIN32
#include "Winsock.h"
#include "Windows.h"
#define uint64_t unsigned __int64
#else
#include <arpa/inet.h>
#include <pthread.h>
#include <stdint.h>
#endif
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

#include "openssl/sha.h"

#define HASH_SIZE 64
#define BUFLEN 16384

#if defined(__GNUC__)
  #define EXPORT __attribute__ ((__visibility__("default")))
#elif defined(_WIN32)
  #define EXPORT __declspec(dllexport)
#endif

#define ntohll(x) ( ( (uint64_t)(ntohl( (unsigned int)((x << 32) >> 32) )) << 32) | ntohl( ((unsigned int)(x >> 32)) ) )

unsigned long long max_val;
unsigned char *initialHash;
unsigned long long successval = 0;
unsigned int numthreads = 0;

#ifdef _WIN32
DWORD WINAPI threadfunc(LPVOID lpParameter) {
#else
void * threadfunc(void* param) {
#endif
	unsigned int incamt = *((unsigned int*)lpParameter);
	SHA512_CTX sha;
	unsigned char buf[HASH_SIZE + sizeof(uint64_t)] = { 0 };
	unsigned char output[HASH_SIZE] = { 0 };

	memcpy(buf + sizeof(uint64_t), initialHash, HASH_SIZE);

	unsigned long long tmpnonce = incamt;
	unsigned long long * nonce = (unsigned long long *)buf;
	unsigned long long * hash = (unsigned long long *)output;
	while (successval == 0) {
		tmpnonce += numthreads;

		(*nonce) = ntohll(tmpnonce); /* increment nonce */
		SHA512_Init(&sha);
		SHA512_Update(&sha, buf, HASH_SIZE + sizeof(uint64_t));
		SHA512_Final(output, &sha);
		SHA512_Init(&sha);
		SHA512_Update(&sha, output, HASH_SIZE);
		SHA512_Final(output, &sha);

		if (ntohll(*hash) < max_val) {
			successval = tmpnonce;
		}
	}
	return NULL;
}

void getnumthreads()
{
#ifdef _WIN32
	DWORD_PTR dwProcessAffinity, dwSystemAffinity;
#elif __linux__
	cpu_set_t dwProcessAffinity;
#else
	int dwProcessAffinity = 0;
	int32_t core_count = 0;
#endif
	unsigned int len = sizeof(dwProcessAffinity);
	if (numthreads > 0)
		return;
#ifdef _WIN32
	GetProcessAffinityMask(GetCurrentProcess(), &dwProcessAffinity, &dwSystemAffinity);
#elif __linux__
	sched_getaffinity(0, len, &dwProcessAffinity);
#else
	if (sysctlbyname("hw.logicalcpu", &core_count, &len, 0, 0))
		numthreads = core_count;
#endif
	for (unsigned int i = 0; i < len * 8; i++)
		if (dwProcessAffinity & (1i64 << i)) {
			numthreads++;
			printf("Detected core on: %u\n", i);
		}
	printf("Affinity: %lx\n", (unsigned long) dwProcessAffinity);
	printf("Number of threads: %i\n", (int)numthreads);
}

extern "C" EXPORT unsigned long long BitmessagePOW(unsigned char * starthash, unsigned long long target)
{
	successval = 0;
	max_val = target;
	getnumthreads();
	initialHash = (unsigned char *)starthash;
#   ifdef _WIN32
	HANDLE* threads = (HANDLE*)calloc(sizeof(HANDLE), numthreads);
#   else
	pthread_t* threads = (pthread_t*)calloc(sizeof(pthread_t), numthreads);
	struct sched_param schparam;
#   ifdef __linux__
	schparam.sched_priority = 0;
#   else
	schparam.sched_priority = PTHREAD_MIN_PRIORITY;
#   endif
#   endif
	unsigned int *threaddata = (unsigned int *)calloc(sizeof(unsigned int), numthreads);
	for (UINT i = 0; i < numthreads; i++) {
		threaddata[i] = i;
#   ifdef _WIN32
		threads[i] = CreateThread(NULL, 0, threadfunc, (LPVOID)&threaddata[i], 0, NULL);
		SetThreadPriority(threads[i], THREAD_PRIORITY_IDLE);
#   else
		pthread_create(&threads[i], NULL, threadfunc, (void*)&threaddata[i]);
#   ifdef __linux__
		pthread_setschedparam(threads[i], SCHED_IDLE, &schparam);
#   else
		pthread_setschedparam(threads[i], SCHED_RR, &schparam)
#   endif
#   endif
	}
#   ifdef _WIN32
	WaitForMultipleObjects(numthreads, threads, TRUE, INFINITE);
#   else
	for (int i = 0; i < numthreads; i++) {
		pthread_join(threads[i], NULL);
	}
#   endif
	free(threads);
	free(threaddata);
	return successval;
}
<commit_msg>Bitmsghash linux compile fixes<commit_after>// bitmessage cracker, build with g++ or MSVS to a shared library, use included python code for usage under bitmessage
#ifdef _WIN32
#include "Winsock.h"
#include "Windows.h"
#define uint64_t unsigned __int64
#else
#include <arpa/inet.h>
#include <pthread.h>
#include <stdint.h>
#endif
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

#include "openssl/sha.h"

#define HASH_SIZE 64
#define BUFLEN 16384

#if defined(__GNUC__)
  #define EXPORT __attribute__ ((__visibility__("default")))
#elif defined(_WIN32)
  #define EXPORT __declspec(dllexport)
#endif

#define ntohll(x) ( ( (uint64_t)(ntohl( (unsigned int)((x << 32) >> 32) )) << 32) | ntohl( ((unsigned int)(x >> 32)) ) )

unsigned long long max_val;
unsigned char *initialHash;
unsigned long long successval = 0;
unsigned int numthreads = 0;

#ifdef _WIN32
DWORD WINAPI threadfunc(LPVOID param) {
#else
void * threadfunc(void* param) {
#endif
	unsigned int incamt = *((unsigned int*)param);
	SHA512_CTX sha;
	unsigned char buf[HASH_SIZE + sizeof(uint64_t)] = { 0 };
	unsigned char output[HASH_SIZE] = { 0 };

	memcpy(buf + sizeof(uint64_t), initialHash, HASH_SIZE);

	unsigned long long tmpnonce = incamt;
	unsigned long long * nonce = (unsigned long long *)buf;
	unsigned long long * hash = (unsigned long long *)output;
	while (successval == 0) {
		tmpnonce += numthreads;

		(*nonce) = ntohll(tmpnonce); /* increment nonce */
		SHA512_Init(&sha);
		SHA512_Update(&sha, buf, HASH_SIZE + sizeof(uint64_t));
		SHA512_Final(output, &sha);
		SHA512_Init(&sha);
		SHA512_Update(&sha, output, HASH_SIZE);
		SHA512_Final(output, &sha);

		if (ntohll(*hash) < max_val) {
			successval = tmpnonce;
		}
	}
	return NULL;
}

void getnumthreads()
{
#ifdef _WIN32
	DWORD_PTR dwProcessAffinity, dwSystemAffinity;
#elif __linux__
	cpu_set_t dwProcessAffinity;
#else
	int dwProcessAffinity = 0;
	int32_t core_count = 0;
#endif
	unsigned int len = sizeof(dwProcessAffinity);
	if (numthreads > 0)
		return;
#ifdef _WIN32
	GetProcessAffinityMask(GetCurrentProcess(), &dwProcessAffinity, &dwSystemAffinity);
#elif __linux__
	sched_getaffinity(0, len, &dwProcessAffinity);
#else
	if (sysctlbyname("hw.logicalcpu", &core_count, &len, 0, 0))
		numthreads = core_count;
#endif
	for (unsigned int i = 0; i < len * 8; i++)
#ifdef _WIN32
		if (dwProcessAffinity & (1i64 << i)) {
#else
		if (CPU_ISSET(i, &dwProcessAffinity)) {
#endif
			numthreads++;
			printf("Detected core on: %u\n", i);
		}
	printf("Number of threads: %i\n", (int)numthreads);
}

extern "C" EXPORT unsigned long long BitmessagePOW(unsigned char * starthash, unsigned long long target)
{
	successval = 0;
	max_val = target;
	getnumthreads();
	initialHash = (unsigned char *)starthash;
#   ifdef _WIN32
	HANDLE* threads = (HANDLE*)calloc(sizeof(HANDLE), numthreads);
#   else
	pthread_t* threads = (pthread_t*)calloc(sizeof(pthread_t), numthreads);
	struct sched_param schparam;
#   ifdef __linux__
	schparam.sched_priority = 0;
#   else
	schparam.sched_priority = PTHREAD_MIN_PRIORITY;
#   endif
#   endif
	unsigned int *threaddata = (unsigned int *)calloc(sizeof(unsigned int), numthreads);
	for (unsigned int i = 0; i < numthreads; i++) {
		threaddata[i] = i;
#   ifdef _WIN32
		threads[i] = CreateThread(NULL, 0, threadfunc, (LPVOID)&threaddata[i], 0, NULL);
		SetThreadPriority(threads[i], THREAD_PRIORITY_IDLE);
#   else
		pthread_create(&threads[i], NULL, threadfunc, (void*)&threaddata[i]);
#   ifdef __linux__
		pthread_setschedparam(threads[i], SCHED_IDLE, &schparam);
#   else
		pthread_setschedparam(threads[i], SCHED_RR, &schparam)
#   endif
#   endif
	}
#   ifdef _WIN32
	WaitForMultipleObjects(numthreads, threads, TRUE, INFINITE);
#   else
	for (unsigned int i = 0; i < numthreads; i++) {
		pthread_join(threads[i], NULL);
	}
#   endif
	free(threads);
	free(threaddata);
	return successval;
}
<|endoftext|>