<commit_before>#include "GaussianSmoothingFilter2D.hpp"
#include "Exception.hpp"
#include "DeviceManager.hpp"
#include "Image2D.hpp"
#include "Image2Dt.hpp"
using namespace fast;

void GaussianSmoothingFilter2D::setInput(ImageData::pointer input) {
    mInput = input;
    mIsModified = true;
    addParent(input);
    if(input->isDynamicData()) {
        mTempOutput = Image2Dt::New();
    } else {
        mTempOutput = Image2D::New();
        input->retain(mDevice);
    }
    mOutput = mTempOutput;
}

void GaussianSmoothingFilter2D::setDevice(ExecutionDevice::pointer device) {
    mDevice = device;
    mIsModified = true;
}

void GaussianSmoothingFilter2D::setMaskSize(unsigned char maskSize) {
    if(maskSize % 2 != 1)
        throw Exception("Mask size of GaussianSmoothingFilter must be odd.");

    mMaskSize = maskSize;
    mIsModified = true;
}

void GaussianSmoothingFilter2D::setStandardDeviation(float stdDev) {
    if(stdDev <= 0)
        throw Exception("Standard deviation of GaussianSmoothingFilter can't be less than 0.");

    mStdDev = stdDev;
    mIsModified = true;
}

ImageData::pointer GaussianSmoothingFilter2D::getOutput() {
    if(!mInput.isValid()) {
        throw Exception("Must call setInput before getOutput in GaussianSmoothingFilter2D");
    }
    if(mTempOutput.isValid()) {
        mTempOutput->setParent(mPtr.lock());

        ImageData::pointer newSmartPtr;
        newSmartPtr.swap(mTempOutput);

        return newSmartPtr;
    } else {
        return mOutput.lock();
    }
}

GaussianSmoothingFilter2D::GaussianSmoothingFilter2D() {
    mDevice = DeviceManager::getInstance().getDefaultComputationDevice();
    mStdDev = 1.0f;
    mMaskSize = 3;
    mIsModified = true;
}

float * GaussianSmoothingFilter2D::createMask() {
    float * mask = new float[mMaskSize*mMaskSize];

    unsigned char halfSize = (mMaskSize-1)/2;
    float sum = 0.0f;

    for(int x = -halfSize; x <= halfSize; x++) {
    for(int y = -halfSize; y <= halfSize; y++) {
        float value = exp(-(float)(x*x+y*y)/(2.0f*mStdDev*mStdDev));
        mask[x+halfSize+(y+halfSize)*mMaskSize] = value;
        sum += value;
    }}

    for(int i = 0; i < mMaskSize*mMaskSize; i++)
        mask[i] /= sum;

    return mask;
}

void GaussianSmoothingFilter2D::execute() {

    Image2D::pointer input;
    if(!mInput.isValid()) {
        throw Exception("No input supplied to GaussianSmoothingFilter2D");
    }
    if(mInput->isDynamicData()) {
        input = Image2Dt::pointer(mInput)->getNextFrame();
        std::cout << "processing a new frame" << std::endl;
    } else {
        input = mInput;
    }

    Image2D::pointer output;
    if(mInput->isDynamicData()) {
        output = Image2D::New();

        // Initialize output image
        output->createImage(input->getWidth(),
            input->getHeight(),
            input->getDataType(),
            input->getNrOfComponents(),
            mDevice);

        Image2Dt::pointer(mOutput)->addFrame(output);
    } else {
        output = Image2D::pointer(mOutput);

        if(output == NULL) {
            // output object is no longer valid
            return;
        }

        // Initialize output image
        output->createImage(input->getWidth(),
                input->getHeight(),
                input->getDataType(),
                input->getNrOfComponents(),
                mDevice);

    }

    if(mDevice->isHost()) {

        // TODO: create host code

    } else {
        OpenCLDevice::pointer device = boost::static_pointer_cast<OpenCLDevice>(mDevice);

        float * mask = createMask();
        cl::Buffer clMask = cl::Buffer(
                device->getContext(),
                CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
                sizeof(float)*mMaskSize*mMaskSize,
                mask
        );
        delete[] mask;

        int programNr = device->createProgramFromSource(std::string(FAST_ROOT_DIR) + "Algorithms/GaussianSmoothingFilter2D.cl");
        cl::Kernel kernel(device->getProgram(programNr), "gaussianSmoothing");

        OpenCLImageAccess2D inputAccess = input->getOpenCLImageAccess(ACCESS_READ, device);
        OpenCLImageAccess2D outputAccess = output->getOpenCLImageAccess(ACCESS_READ_WRITE, device);
        kernel.setArg(0, *inputAccess.get());
        kernel.setArg(1, clMask);
        kernel.setArg(2, *outputAccess.get());
        kernel.setArg(3, mMaskSize);

        device->getCommandQueue().enqueueNDRangeKernel(
                kernel,
                cl::NullRange,
                cl::NDRange(input->getWidth(),input->getHeight()),
                cl::NullRange
        );
    }

    if(!mInput->isDynamicData())
        mInput->release(mDevice);

    // Update the timestamp of the output data
    output->updateModifiedTimestamp();
}
<commit_msg>simplified some code in the smoothing filter<commit_after>#include "GaussianSmoothingFilter2D.hpp"
#include "Exception.hpp"
#include "DeviceManager.hpp"
#include "Image2D.hpp"
#include "Image2Dt.hpp"
using namespace fast;

void GaussianSmoothingFilter2D::setInput(ImageData::pointer input) {
    mInput = input;
    mIsModified = true;
    addParent(input);
    if(input->isDynamicData()) {
        mTempOutput = Image2Dt::New();
    } else {
        mTempOutput = Image2D::New();
        input->retain(mDevice);
    }
    mOutput = mTempOutput;
}

void GaussianSmoothingFilter2D::setDevice(ExecutionDevice::pointer device) {
    mDevice = device;
    mIsModified = true;
}

void GaussianSmoothingFilter2D::setMaskSize(unsigned char maskSize) {
    if(maskSize % 2 != 1)
        throw Exception("Mask size of GaussianSmoothingFilter must be odd.");

    mMaskSize = maskSize;
    mIsModified = true;
}

void GaussianSmoothingFilter2D::setStandardDeviation(float stdDev) {
    if(stdDev <= 0)
        throw Exception("Standard deviation of GaussianSmoothingFilter can't be less than 0.");

    mStdDev = stdDev;
    mIsModified = true;
}

ImageData::pointer GaussianSmoothingFilter2D::getOutput() {
    if(!mInput.isValid()) {
        throw Exception("Must call setInput before getOutput in GaussianSmoothingFilter2D");
    }
    if(mTempOutput.isValid()) {
        mTempOutput->setParent(mPtr.lock());

        ImageData::pointer newSmartPtr;
        newSmartPtr.swap(mTempOutput);

        return newSmartPtr;
    } else {
        return mOutput.lock();
    }
}

GaussianSmoothingFilter2D::GaussianSmoothingFilter2D() {
    mDevice = DeviceManager::getInstance().getDefaultComputationDevice();
    mStdDev = 1.0f;
    mMaskSize = 3;
    mIsModified = true;
}

float * GaussianSmoothingFilter2D::createMask() {
    float * mask = new float[mMaskSize*mMaskSize];

    unsigned char halfSize = (mMaskSize-1)/2;
    float sum = 0.0f;

    for(int x = -halfSize; x <= halfSize; x++) {
    for(int y = -halfSize; y <= halfSize; y++) {
        float value = exp(-(float)(x*x+y*y)/(2.0f*mStdDev*mStdDev));
        mask[x+halfSize+(y+halfSize)*mMaskSize] = value;
        sum += value;
    }}

    for(int i = 0; i < mMaskSize*mMaskSize; i++)
        mask[i] /= sum;

    return mask;
}

void GaussianSmoothingFilter2D::execute() {

    Image2D::pointer input;
    if(!mInput.isValid()) {
        throw Exception("No input supplied to GaussianSmoothingFilter2D");
    }
    if(!mOutput.lock().isValid()) {
        // output object is no longer valid
        return;
    }
    if(mInput->isDynamicData()) {
        input = Image2Dt::pointer(mInput)->getNextFrame();
        std::cout << "processing a new frame" << std::endl;
    } else {
        input = mInput;
    }

    Image2D::pointer output;
    if(mInput->isDynamicData()) {
        output = Image2D::New();
        Image2Dt::pointer(mOutput)->addFrame(output);
    } else {
        output = Image2D::pointer(mOutput);
    }

    // Initialize output image
    output->createImage(input->getWidth(),
        input->getHeight(),
        input->getDataType(),
        input->getNrOfComponents(),
        mDevice);

    if(mDevice->isHost()) {

        // TODO: create host code

    } else {
        OpenCLDevice::pointer device = boost::static_pointer_cast<OpenCLDevice>(mDevice);

        float * mask = createMask();
        cl::Buffer clMask = cl::Buffer(
                device->getContext(),
                CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
                sizeof(float)*mMaskSize*mMaskSize,
                mask
        );
        delete[] mask;

        int programNr = device->createProgramFromSource(std::string(FAST_ROOT_DIR) + "Algorithms/GaussianSmoothingFilter2D.cl");
        cl::Kernel kernel(device->getProgram(programNr), "gaussianSmoothing");

        OpenCLImageAccess2D inputAccess = input->getOpenCLImageAccess(ACCESS_READ, device);
        OpenCLImageAccess2D outputAccess = output->getOpenCLImageAccess(ACCESS_READ_WRITE, device);
        kernel.setArg(0, *inputAccess.get());
        kernel.setArg(1, clMask);
        kernel.setArg(2, *outputAccess.get());
        kernel.setArg(3, mMaskSize);

        device->getCommandQueue().enqueueNDRangeKernel(
                kernel,
                cl::NullRange,
                cl::NDRange(input->getWidth(),input->getHeight()),
                cl::NullRange
        );
    }

    if(!mInput->isDynamicData())
        mInput->release(mDevice);

    // Update the timestamp of the output data
    output->updateModifiedTimestamp();
}
<|endoftext|>


<commit_before><commit_msg>Allow using parameters in more places in the config files.<commit_after><|endoftext|>


<commit_before>/******************************************************************************
 * BRICS_3D - 3D Perception and Modeling Library
 * Copyright (c) 2016, KU Leuven
 *
 * Author: Sebastian Blumenthal
 *
 *
 * This software is published under a dual-license: GNU Lesser General Public
 * License LGPL 2.1 and Modified BSD license. The dual-license implies that
 * users of this code may choose which terms they prefer.
 *
 * This program 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 LGPL and the BSD license for
 * more details.
 *
 ******************************************************************************/
#include "GraphConstraint.h"

namespace brics_3d {
namespace rsg {

GraphConstraint::GraphConstraint() {

	action = UNDEFINED_ACTION;
	qualifier = UNDEFINED_QUALIFIER;
	type = UNDEFINED_TYPE;
	comparision = UNDEFINED_OPERATOR;
	value = 0;
	freqUnit = Units::Hertz;
	distUnit = Units::Meter;
	node = 0;
	context = "";

}

GraphConstraint::~GraphConstraint() {

}

bool GraphConstraint::parse(std::string constraintModel) {

	return validate();
}

bool GraphConstraint::validate() {
	return (qualifier != UNDEFINED_QUALIFIER)
			&& (type != UNDEFINED_TYPE);
}

} /* namespace rsg */
} /* namespace brics_3d */

/* EOF */
<commit_msg>Added minimal parser.<commit_after>/******************************************************************************
 * BRICS_3D - 3D Perception and Modeling Library
 * Copyright (c) 2016, KU Leuven
 *
 * Author: Sebastian Blumenthal
 *
 *
 * This software is published under a dual-license: GNU Lesser General Public
 * License LGPL 2.1 and Modified BSD license. The dual-license implies that
 * users of this code may choose which terms they prefer.
 *
 * This program 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 LGPL and the BSD license for
 * more details.
 *
 ******************************************************************************/

#include "GraphConstraint.h"
#include <brics_3d/core/Logger.h>
#include <boost/algorithm/string.hpp>
#include <vector>

namespace brics_3d {
namespace rsg {

GraphConstraint::GraphConstraint() {

	action = UNDEFINED_ACTION;
	qualifier = UNDEFINED_QUALIFIER;
	type = UNDEFINED_TYPE;
	comparision = UNDEFINED_OPERATOR;
	value = 0;
	freqUnit = Units::Hertz;
	distUnit = Units::Meter;
	node = 0;
	context = "";

}

GraphConstraint::~GraphConstraint() {

}

bool GraphConstraint::parse(std::string constraintModel) {

	/*
	 * Check if model is valid
	 */

	/*
	 * Parse the model
	 */

	std::vector<std::string> tokens;
	boost::split(tokens, constraintModel, boost::is_any_of(" "));
	std::vector<std::string>::const_iterator it = tokens.begin();

	/* Action */
	if(it == tokens.end()){ LOG(ERROR) << "GraphConstraint is empty." ; return false;}
	if(it->compare("send") == 0) {
		action = SEND;
	} else if(it->compare("receive") == 0) {
		action = RECEIVE;
	} else {
		action = UNDEFINED_ACTION;
	}

	/* Qualifier */
	if(it == tokens.end()){ LOG(ERROR) << "GraphConstraint has no qualifier." ; return false;}
	if(it->compare("no") == 0) {
		qualifier = NO;
	} else if(it->compare("only") == 0) {
		qualifier = ONLY;
	} else {
		qualifier = UNDEFINED_QUALIFIER;
	}

	/* Type */
	if(it == tokens.end()){ LOG(ERROR) << "GraphConstraint has no type." ; return false;}
	if(it->compare("Atoms") == 0) {
		type = Atom;
	} else if(it->compare("Nodes") == 0) {
		type = Node;
	} else if(it->compare("GeometricNodes") == 0) {
		type = GeometricNode;
	} else if(it->compare("Spheres") == 0) {
		type = Sphere;
	} else if(it->compare("Cylinders") == 0) {
		type = Cylinder;
	} else if(it->compare("Boxes") == 0) {
		type = Box;
	} else if(it->compare("PointClouds") == 0) {
		type = PointCloud;
	} else if(it->compare("Meshes") == 0) {
		type = Mesh;
	} else if(it->compare("Transforms") == 0) {
		type = Transform;
	} else if(it->compare("Groups") == 0) {
		type = Group;
	} else if(it->compare("Connection") == 0) {
		type = Connection;
	} else {
		type = UNDEFINED_TYPE;
	}

	/* NodeConstraint; here he have to fork the parsing */

	return validate();
}

bool GraphConstraint::validate() {
	return (qualifier != UNDEFINED_QUALIFIER)
			&& (type != UNDEFINED_TYPE);
}

} /* namespace rsg */
} /* namespace brics_3d */

/* EOF */
<|endoftext|>


<commit_before>/*
 * Part of Appstream, a library for accessing AppStream on-disk database
 * Copyright (C) 2014  Sune Vuorela <sune@vuorela.dk>
 * Copyright (C) 2015  Matthias Klumpp <matthias@tenstral.net>
 *
 * Based upon database-read.hpp
 * Copyright (C) 2012-2014 Matthias Klumpp <matthias@tenstral.net>
 *
 * 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 Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#define QT_NO_KEYWORDS
#include "database.h"

#include <appstream.h>
#include <QStringList>
#include <QUrl>
#include <QMultiHash>
#include <QLoggingCategory>
#include "as-component-private.h"

#include "image.h"
#include "screenshot.h"

Q_LOGGING_CATEGORY(APPSTREAMQT_DB, "appstreamqt.database")

using namespace Appstream;

class Appstream::DatabasePrivate {
    public:
        DatabasePrivate(const QString& cachePath) : m_cachePath(cachePath) {
        }

        QString m_cachePath;
        QString m_errorString;
        AsDataPool *m_dpool;

        bool open() {
            g_autoptr(GError) error = NULL;

            m_dpool = as_data_pool_new ();

            if (m_cachePath.isEmpty())
                as_data_pool_load (m_dpool, NULL, &error);
            else
                as_data_pool_load_cache_file (m_dpool, qPrintable(m_cachePath), &error);
            if (error != NULL) {
                m_errorString = QString::fromUtf8 (error->message);
                return false;
            }

            return true;
        }

        ~DatabasePrivate() {
            g_object_unref (m_dpool);
        }
};

Database::Database(const QString& cachePath) : d(new DatabasePrivate(cachePath)) {

}

bool Database::open() {
    return d->open();
}

QString Database::errorString() const {
    return d->m_errorString;
}

Database::~Database() {
    // empty. needed for the scoped pointer for the private pointer
}

QString value(const gchar *cstr) {
    return QString::fromUtf8(cstr);
}

QStringList value(gchar **strv) {
    QStringList res;
    if (strv == NULL)
        return res;
    for (uint i = 0; strv[i] != NULL; i++) {
        res.append (QString::fromUtf8(strv[i]));
    }
    return res;
}

QStringList value(GPtrArray *array) {
    QStringList res;
    res.reserve(array->len);
    for (uint i = 0; i < array->len; i++) {
        auto strval = (const gchar*) g_ptr_array_index (array, i);
	res.append (QString::fromUtf8(strval));
    }
    return res;
}

Component convertAsComponent(AsComponent *cpt) {
    Component component;
    std::string str;

    // kind
    QString kindString = value (as_component_kind_to_string (as_component_get_kind (cpt)));
    component.setKind(Component::stringToKind(kindString));

    // Identifier
    QString id = value(as_component_get_id (cpt));
    component.setId(id);

    // Component name
    QString name = value(as_component_get_name (cpt));
    component.setName(name);

    // Summary
    QString summary = value(as_component_get_summary (cpt));
    component.setSummary(summary);

    // Package name
    QStringList packageNames = value(as_component_get_pkgnames (cpt));
    component.setPackageNames(packageNames);

    // Bundles
    auto bundle_ids = as_component_get_bundles_table (cpt);
    if (g_hash_table_size (bundle_ids) > 0) {
        GHashTableIter iter;
        gpointer key, strPtr;

        QHash<Component::BundleKind, QString> bundles;
        g_hash_table_iter_init (&iter, bundle_ids);
        while (g_hash_table_iter_next (&iter, &key, &strPtr)) {
            auto bkind = (Component::BundleKind) GPOINTER_TO_INT (key);
            auto bval = QString::fromUtf8((const gchar*) strPtr);
            bundles.insertMulti(bkind, bval);
        }
        component.setBundles(bundles);
    }

    // URLs
    auto urls_table = as_component_get_urls_table (cpt);
    if (g_hash_table_size (urls_table) > 0) {
        GHashTableIter iter;
        gpointer key, cstrUrl;

        QMultiHash<Component::UrlKind, QUrl> urls;
        g_hash_table_iter_init (&iter, bundle_ids);
        while (g_hash_table_iter_next (&iter, &key, &cstrUrl)) {
            auto ukind = (Component::UrlKind) GPOINTER_TO_INT (key);
            auto url = QUrl::fromUserInput(QString::fromUtf8((const gchar*) cstrUrl));

            if (ukind != Component::UrlKindUnknown) {
                urls.insertMulti(ukind, url);
            } else {
                qCWarning(APPSTREAMQT_DB, "URL of unknown type found for '%s': %s", qPrintable(id), qPrintable(url.toString()));
            }
        }
        component.setUrls(urls);
    }

    // Provided items
    QList<Provides> provideslist;
    for (uint j = 0; j < AS_PROVIDED_KIND_LAST; j++) {
        AsProvidedKind kind = (AsProvidedKind) j;

        AsProvided *prov = as_component_get_provided_for_kind (cpt, kind);
        if (prov == NULL)
            continue;

        auto pkind = (Provides::Kind) kind;
        gchar **items = as_provided_get_items (prov);
	for (uint j = 0; items[j] != NULL; j++) {
            Provides provides;
            provides.setKind(pkind);
            provides.setValue(QString::fromUtf8(items[j]));
            provideslist << provides;
        }
    }
    component.setProvides(provideslist);

    // Icons
    auto icons = as_component_get_icons (cpt);
    for (uint i = 0; i < icons->len; i++) {
        auto icon = AS_ICON (g_ptr_array_index (icons, i));
        if (as_icon_get_kind (icon) == AS_ICON_KIND_STOCK) {
            component.setIcon(QString::fromUtf8(as_icon_get_name (icon)));
        } else {
            // TODO: Support more icon types properly
            auto size = QSize(as_icon_get_width (icon),
                              as_icon_get_height (icon));
            QUrl url = QUrl::fromUserInput(QString::fromUtf8(as_icon_get_filename (icon)));
            component.addIconUrl(url, size);
        }
    }

    // Long description
    QString description = value(as_component_get_description (cpt));
    component.setDescription(description);

    // Categories
    QStringList categories = value(as_component_get_categories (cpt));
    component.setCategories(categories);

    // Extends
    const QStringList extends = value(as_component_get_extends (cpt));
    component.setExtends(extends);

    // Extensions
    const QStringList extensions = value(as_component_get_extensions (cpt));
    component.setExtensions(extensions);

    // Screenshots
    QList<Appstream::Screenshot> screenshots;
    auto scrs = as_component_get_screenshots (cpt);
    for (uint i = 0; i < scrs->len; i++) {
        auto cscr = AS_SCREENSHOT (g_ptr_array_index (scrs, i));
	Appstream::Screenshot scr;

        if (as_screenshot_get_kind (cscr) == AS_SCREENSHOT_KIND_DEFAULT)
            scr.setDefault(true);

        if (as_screenshot_get_caption (cscr) != NULL)
            scr.setCaption(QString::fromUtf8(as_screenshot_get_caption (cscr)));

        QList<Appstream::Image> images;
        auto images_array = as_screenshot_get_images (cscr);
        for (uint j = 0; j < images_array->len; j++) {
            auto cimg = AS_IMAGE (g_ptr_array_index (images_array, j));

            Appstream::Image image;

            image.setUrl(QUrl(QString::fromUtf8(as_image_get_url (cimg))));
            image.setWidth(as_image_get_width (cimg));
            image.setHeight(as_image_get_height (cimg));

            if (as_image_get_kind (cimg) == AS_IMAGE_KIND_THUMBNAIL)
                image.setKind(Appstream::Image::Kind::Thumbnail);
            else
                image.setKind(Appstream::Image::Kind::Plain);
            images.append(image);
        }
        scr.setImages(images);

        screenshots.append(scr);
    }
    component.setScreenshots(screenshots);

    // Compulsory-for-desktop information
    QStringList compulsory = value(as_component_get_compulsory_for_desktops (cpt));
    component.setCompulsoryForDesktops(compulsory);

    // License
    QString license = value(as_component_get_project_license (cpt));
    component.setProjectLicense(license);

    // Project group
    QString projectGroup = value(as_component_get_project_group (cpt));
    component.setProjectGroup(projectGroup);

    // Developer name
    QString developerName = value(as_component_get_developer_name (cpt));
    component.setDeveloperName(developerName);

    // Releases
      // TODO

    return component;
}

QList< Component > Database::allComponents() const
{
    QList<Component> components;

    // get a pointer array of all components we have
    auto array = as_data_pool_get_components (d->m_dpool);
    components.reserve(array->len);

    // create QList of AppStream::Component out of the AsComponents
    for (uint i = 0; i < array->len; i++) {
        auto cpt = AS_COMPONENT (g_ptr_array_index (array, i));
        components << convertAsComponent(cpt);
    }

    return components;
}

Component Database::componentById(const QString& id) const
{
    auto cpt = as_data_pool_get_component_by_id (d->m_dpool, qPrintable(id));
    if (cpt == NULL)
        return Component();

    return convertAsComponent(cpt);
}

QList< Component > Database::componentsByKind(Component::Kind kind) const
{
    QList<Component> res;
    // FIXME
    // TODO

    return res;
}

QList< Component > Database::findComponentsByString(const QString& searchTerm, const QStringList& categories)
{
    Q_UNUSED(categories); // FIXME

    auto res_array = as_data_pool_search (d->m_dpool, qPrintable(searchTerm));
    QList<Component> result;
    result.reserve(res_array->len);

    for (uint i = 0; i < res_array->len; i++) {
        auto cpt = AS_COMPONENT (g_ptr_array_index (res_array, i));
        result << convertAsComponent(cpt);
    }

    return result;
}

QList<Component> Database::findComponentsByPackageName(const QString& packageName) const
{
    // FIXME
    // TODO
    QList<Component> result;
    return result;
}

Database::Database() : d(new DatabasePrivate(QString())) {

}
<commit_msg>qt: Make componentsByKind work again<commit_after>/*
 * Part of Appstream, a library for accessing AppStream on-disk database
 * Copyright (C) 2014  Sune Vuorela <sune@vuorela.dk>
 * Copyright (C) 2015  Matthias Klumpp <matthias@tenstral.net>
 *
 * Based upon database-read.hpp
 * Copyright (C) 2012-2014 Matthias Klumpp <matthias@tenstral.net>
 *
 * 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 Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#define QT_NO_KEYWORDS
#include "database.h"

#include <appstream.h>
#include <QStringList>
#include <QUrl>
#include <QMultiHash>
#include <QLoggingCategory>
#include "as-component-private.h"

#include "image.h"
#include "screenshot.h"

Q_LOGGING_CATEGORY(APPSTREAMQT_DB, "appstreamqt.database")

using namespace Appstream;

class Appstream::DatabasePrivate {
    public:
        DatabasePrivate(const QString& cachePath) : m_cachePath(cachePath) {
        }

        QString m_cachePath;
        QString m_errorString;
        AsDataPool *m_dpool;

        bool open() {
            g_autoptr(GError) error = NULL;

            m_dpool = as_data_pool_new ();

            if (m_cachePath.isEmpty())
                as_data_pool_load (m_dpool, NULL, &error);
            else
                as_data_pool_load_cache_file (m_dpool, qPrintable(m_cachePath), &error);
            if (error != NULL) {
                m_errorString = QString::fromUtf8 (error->message);
                return false;
            }

            return true;
        }

        ~DatabasePrivate() {
            g_object_unref (m_dpool);
        }
};

Database::Database(const QString& cachePath) : d(new DatabasePrivate(cachePath)) {

}

bool Database::open() {
    return d->open();
}

QString Database::errorString() const {
    return d->m_errorString;
}

Database::~Database() {
    // empty. needed for the scoped pointer for the private pointer
}

QString value(const gchar *cstr) {
    return QString::fromUtf8(cstr);
}

QStringList value(gchar **strv) {
    QStringList res;
    if (strv == NULL)
        return res;
    for (uint i = 0; strv[i] != NULL; i++) {
        res.append (QString::fromUtf8(strv[i]));
    }
    return res;
}

QStringList value(GPtrArray *array) {
    QStringList res;
    res.reserve(array->len);
    for (uint i = 0; i < array->len; i++) {
        auto strval = (const gchar*) g_ptr_array_index (array, i);
	res.append (QString::fromUtf8(strval));
    }
    return res;
}

Component convertAsComponent(AsComponent *cpt) {
    Component component;
    std::string str;

    // kind
    QString kindString = value (as_component_kind_to_string (as_component_get_kind (cpt)));
    component.setKind(Component::stringToKind(kindString));

    // Identifier
    QString id = value(as_component_get_id (cpt));
    component.setId(id);

    // Component name
    QString name = value(as_component_get_name (cpt));
    component.setName(name);

    // Summary
    QString summary = value(as_component_get_summary (cpt));
    component.setSummary(summary);

    // Package name
    QStringList packageNames = value(as_component_get_pkgnames (cpt));
    component.setPackageNames(packageNames);

    // Bundles
    auto bundle_ids = as_component_get_bundles_table (cpt);
    if (g_hash_table_size (bundle_ids) > 0) {
        GHashTableIter iter;
        gpointer key, strPtr;

        QHash<Component::BundleKind, QString> bundles;
        g_hash_table_iter_init (&iter, bundle_ids);
        while (g_hash_table_iter_next (&iter, &key, &strPtr)) {
            auto bkind = (Component::BundleKind) GPOINTER_TO_INT (key);
            auto bval = QString::fromUtf8((const gchar*) strPtr);
            bundles.insertMulti(bkind, bval);
        }
        component.setBundles(bundles);
    }

    // URLs
    auto urls_table = as_component_get_urls_table (cpt);
    if (g_hash_table_size (urls_table) > 0) {
        GHashTableIter iter;
        gpointer key, cstrUrl;

        QMultiHash<Component::UrlKind, QUrl> urls;
        g_hash_table_iter_init (&iter, bundle_ids);
        while (g_hash_table_iter_next (&iter, &key, &cstrUrl)) {
            auto ukind = (Component::UrlKind) GPOINTER_TO_INT (key);
            auto url = QUrl::fromUserInput(QString::fromUtf8((const gchar*) cstrUrl));

            if (ukind != Component::UrlKindUnknown) {
                urls.insertMulti(ukind, url);
            } else {
                qCWarning(APPSTREAMQT_DB, "URL of unknown type found for '%s': %s", qPrintable(id), qPrintable(url.toString()));
            }
        }
        component.setUrls(urls);
    }

    // Provided items
    QList<Provides> provideslist;
    for (uint j = 0; j < AS_PROVIDED_KIND_LAST; j++) {
        AsProvidedKind kind = (AsProvidedKind) j;

        AsProvided *prov = as_component_get_provided_for_kind (cpt, kind);
        if (prov == NULL)
            continue;

        auto pkind = (Provides::Kind) kind;
        gchar **items = as_provided_get_items (prov);
	for (uint j = 0; items[j] != NULL; j++) {
            Provides provides;
            provides.setKind(pkind);
            provides.setValue(QString::fromUtf8(items[j]));
            provideslist << provides;
        }
    }
    component.setProvides(provideslist);

    // Icons
    auto icons = as_component_get_icons (cpt);
    for (uint i = 0; i < icons->len; i++) {
        auto icon = AS_ICON (g_ptr_array_index (icons, i));
        if (as_icon_get_kind (icon) == AS_ICON_KIND_STOCK) {
            component.setIcon(QString::fromUtf8(as_icon_get_name (icon)));
        } else {
            // TODO: Support more icon types properly
            auto size = QSize(as_icon_get_width (icon),
                              as_icon_get_height (icon));
            QUrl url = QUrl::fromUserInput(QString::fromUtf8(as_icon_get_filename (icon)));
            component.addIconUrl(url, size);
        }
    }

    // Long description
    QString description = value(as_component_get_description (cpt));
    component.setDescription(description);

    // Categories
    QStringList categories = value(as_component_get_categories (cpt));
    component.setCategories(categories);

    // Extends
    const QStringList extends = value(as_component_get_extends (cpt));
    component.setExtends(extends);

    // Extensions
    const QStringList extensions = value(as_component_get_extensions (cpt));
    component.setExtensions(extensions);

    // Screenshots
    QList<Appstream::Screenshot> screenshots;
    auto scrs = as_component_get_screenshots (cpt);
    for (uint i = 0; i < scrs->len; i++) {
        auto cscr = AS_SCREENSHOT (g_ptr_array_index (scrs, i));
	Appstream::Screenshot scr;

        if (as_screenshot_get_kind (cscr) == AS_SCREENSHOT_KIND_DEFAULT)
            scr.setDefault(true);

        if (as_screenshot_get_caption (cscr) != NULL)
            scr.setCaption(QString::fromUtf8(as_screenshot_get_caption (cscr)));

        QList<Appstream::Image> images;
        auto images_array = as_screenshot_get_images (cscr);
        for (uint j = 0; j < images_array->len; j++) {
            auto cimg = AS_IMAGE (g_ptr_array_index (images_array, j));

            Appstream::Image image;

            image.setUrl(QUrl(QString::fromUtf8(as_image_get_url (cimg))));
            image.setWidth(as_image_get_width (cimg));
            image.setHeight(as_image_get_height (cimg));

            if (as_image_get_kind (cimg) == AS_IMAGE_KIND_THUMBNAIL)
                image.setKind(Appstream::Image::Kind::Thumbnail);
            else
                image.setKind(Appstream::Image::Kind::Plain);
            images.append(image);
        }
        scr.setImages(images);

        screenshots.append(scr);
    }
    component.setScreenshots(screenshots);

    // Compulsory-for-desktop information
    QStringList compulsory = value(as_component_get_compulsory_for_desktops (cpt));
    component.setCompulsoryForDesktops(compulsory);

    // License
    QString license = value(as_component_get_project_license (cpt));
    component.setProjectLicense(license);

    // Project group
    QString projectGroup = value(as_component_get_project_group (cpt));
    component.setProjectGroup(projectGroup);

    // Developer name
    QString developerName = value(as_component_get_developer_name (cpt));
    component.setDeveloperName(developerName);

    // Releases
      // TODO

    return component;
}

QList< Component > Database::allComponents() const
{
    g_autoptr(GPtrArray) array = NULL;
    QList<Component> components;

    // get a pointer array of all components we have
    array = as_data_pool_get_components (d->m_dpool);
    components.reserve(array->len);

    // create QList of AppStream::Component out of the AsComponents
    for (uint i = 0; i < array->len; i++) {
        auto cpt = AS_COMPONENT (g_ptr_array_index (array, i));
        components << convertAsComponent(cpt);
    }

    return components;
}

Component Database::componentById(const QString& id) const
{
    g_autoptr(AsComponent) cpt = NULL;

    cpt = as_data_pool_get_component_by_id (d->m_dpool, qPrintable(id));
    if (cpt == NULL)
        return Component();

    return convertAsComponent(cpt);
}

QList< Component > Database::componentsByKind(Component::Kind kind) const
{
    g_autoptr(GPtrArray) array = NULL;
    g_autoptr(GError) error = NULL;
    QList<Component> result;

    array = as_data_pool_get_components_by_kind (d->m_dpool, (AsComponentKind) kind, &error);
    if (error != NULL) {
        qCCritical(APPSTREAMQT_DB, "Unable to get components by kind: %s", error->message);
        return result;
    }

    result.reserve(array->len);
    for (uint i = 0; i < array->len; i++) {
        auto cpt = AS_COMPONENT (g_ptr_array_index (array, i));
        result << convertAsComponent(cpt);
    }

    return result;
}

QList< Component > Database::findComponentsByString(const QString& searchTerm, const QStringList& categories)
{
    Q_UNUSED(categories); // FIXME

    g_autoptr(GPtrArray) array = NULL;
    array = as_data_pool_search (d->m_dpool, qPrintable(searchTerm));
    QList<Component> result;
    result.reserve(array->len);

    for (uint i = 0; i < array->len; i++) {
        auto cpt = AS_COMPONENT (g_ptr_array_index (array, i));
        result << convertAsComponent(cpt);
    }

    return result;
}

QList<Component> Database::findComponentsByPackageName(const QString& packageName) const
{
    // FIXME
    // TODO
    QList<Component> result;
    return result;
}

Database::Database() : d(new DatabasePrivate(QString())) {

}
<|endoftext|>


<commit_before>//Copyright (c) 2021 Ultimaker B.V.
//CuraEngine is released under the terms of the AGPLv3 or higher.

#include "LightningTree.h"

#include "../utils/linearAlg2D.h"

using namespace cura;

coord_t LightningTreeNode::getWeightedDistance(const Point& unsupported_loc, const coord_t& supporting_radius) const
{
    size_t valence = (!is_root) + children.size();
    coord_t boost = (0 < valence && valence < 4) ? 4 * supporting_radius : 0;
    return vSize(getLocation() - unsupported_loc) - boost;
}

bool LightningTreeNode::hasOffspring(const std::shared_ptr<LightningTreeNode>& to_be_checked) const
{
    if (to_be_checked == shared_from_this()) return true;
    for (auto child_ptr : children)
    {
        if (child_ptr->hasOffspring(to_be_checked)) return true;
    }
    return false;
}

const Point& LightningTreeNode::getLocation() const
{
    return p;
}

void LightningTreeNode::setLocation(const Point& loc)
{
    p = loc;
}

std::shared_ptr<LightningTreeNode> LightningTreeNode::addChild(const Point& child_loc)
{
    assert(p != child_loc);
    children.push_back(LightningTreeNode::create(child_loc));
    return children.back();
}

std::shared_ptr<LightningTreeNode> LightningTreeNode::addChild(std::shared_ptr<LightningTreeNode>& new_child)
{
    assert(new_child != shared_from_this());
    //     assert(p != new_child->p);
    if (p == new_child->p)
        std::cerr << "wtf\n";
    children.push_back(new_child);
    new_child->is_root = false;
    return new_child;
}

std::shared_ptr<LightningTreeNode> LightningTreeNode::findClosestNode(const Point& x, const coord_t& supporting_radius)
{
    coord_t closest_distance = getWeightedDistance(x, supporting_radius);
    std::shared_ptr<LightningTreeNode> closest_node = shared_from_this();
    findClosestNodeHelper(x, supporting_radius, closest_distance, closest_node);
    return closest_node;
}

void LightningTreeNode::propagateToNextLayer
(
    std::vector<std::shared_ptr<LightningTreeNode>>& next_trees,
    const Polygons& next_outlines,
    const coord_t& prune_distance,
    const coord_t& smooth_magnitude
) const
{
    auto tree_below = deepCopy();

    // TODO: What is the correct order of the following operations?
    //       (NOTE: in case realign turns out _not_ to be last, would need to rewrite a few things, see the 'rerooted_parts' parameter of that function).
    tree_below->prune(prune_distance);
    tree_below->straighten(smooth_magnitude);
    if (tree_below->realign(next_outlines, next_trees))
    {
        next_trees.push_back(tree_below);
    }
}

// NOTE: Depth-first, as currently implemented.
//       Skips the root (because that has no root itself), but all initial nodes will have the root point anyway.
void LightningTreeNode::visitBranches(const branch_visitor_func_t& visitor) const
{
    for (const auto& node : children)
    {
        visitor(p, node->p);
        node->visitBranches(visitor);
    }
}

// NOTE: Depth-first, as currently implemented.
void LightningTreeNode::visitNodes(const node_visitor_func_t& visitor)
{
    visitor(shared_from_this());
    for (const auto& node : children)
    {
        node->visitNodes(visitor);
    }
}

// Node:
LightningTreeNode::LightningTreeNode(const Point& p) : is_root(false), p(p) {}

// Root (and Trunk):
LightningTreeNode::LightningTreeNode(const Point& a, const Point& b) : LightningTreeNode(a)
{
    children.push_back(LightningTreeNode::create(b));
    is_root = true;
}

void LightningTreeNode::findClosestNodeHelper(const Point& x, const coord_t supporting_radius, coord_t& closest_distance, std::shared_ptr<LightningTreeNode>& closest_node)
{
    for (const auto& node : children)
    {
        node->findClosestNodeHelper(x, supporting_radius, closest_distance, closest_node);
        const coord_t distance = node->getWeightedDistance(x, supporting_radius);
        if (distance < closest_distance)
        {
            closest_node = node;
            closest_distance = distance;
        }
    }
}

std::shared_ptr<LightningTreeNode> LightningTreeNode::deepCopy() const
{
    std::shared_ptr<LightningTreeNode> local_root = LightningTreeNode::create(p);
    local_root->is_root = is_root;
    local_root->children.reserve(children.size());
    for (const auto& node : children)
    {
        local_root->children.push_back(node->deepCopy());
    }
    return local_root;
}

bool LightningTreeNode::realign(const Polygons& outlines, std::vector<std::shared_ptr<LightningTreeNode>>& rerooted_parts, const bool& connected_to_parent)
{
    // TODO: Hole(s) in the _middle_ of a line-segement, not unlikely since reconnect.
    // TODO: Reconnect if not on outline -> plan is: yes, but not here anymore!

    if (outlines.empty())
    {
        return false;
    }

    if (outlines.inside(p, true))
    {
        // Only keep children that have an unbroken connection to here, realign will put the rest in rerooted parts due to recursion:
        const std::function<bool(const std::shared_ptr<LightningTreeNode>& child)> remove_unconnected_func
        (
            [&outlines, &rerooted_parts](const std::shared_ptr<LightningTreeNode>& child)
            {
                constexpr bool argument_with_connected = true;
                return !child->realign(outlines, rerooted_parts, argument_with_connected);
            }
        );
        children.erase(std::remove_if(children.begin(), children.end(), remove_unconnected_func), children.end());
        return true;
    }

    // 'Lift' any decendants out of this tree:
    for (auto& child : children)
    {
        constexpr bool argument_with_disconnect = false;
        if (child->realign(outlines, rerooted_parts, argument_with_disconnect))
        {
            rerooted_parts.push_back(child);
        }
    }
    children.clear();

    if (connected_to_parent)
    {
        // This will now be a (new_ leaf:
        p = PolygonUtils::findClosest(p, outlines).p();
        return true;
    }

    return false;
}

void LightningTreeNode::straighten(const coord_t& magnitude)
{
    straighten(magnitude, p, 0);
}

LightningTreeNode::RectilinearJunction LightningTreeNode::straighten(const coord_t& magnitude, Point junction_above, coord_t accumulated_dist)
{
    const coord_t junction_magnitude = magnitude * 3 / 4;
    if (children.size() == 1)
    {
        auto child_p = children.front();
        coord_t child_dist = vSize(p - child_p->p);
        RectilinearJunction junction_below = child_p->straighten(magnitude, junction_above, accumulated_dist + child_dist);
        coord_t total_dist_to_junction_below = junction_below.total_recti_dist;
        Point a = junction_above;
        Point b = junction_below.junction_loc;
        if (a != b) // should always be true!
        {
            Point ab = b - a;
            Point destination = a + ab * accumulated_dist / total_dist_to_junction_below;
            if (shorterThen(destination - p, magnitude))
            {
                p = destination;
            }
            else
            {
                p = p + normal(destination - p, magnitude);
            }
        }
        return junction_below;
    }
    else
    {
        Point junction_moving_dir = normal(junction_above - p, accumulated_dist);
        for (auto child_p : children)
        {
            coord_t child_dist = vSize(p - child_p->p);
            RectilinearJunction below = child_p->straighten(magnitude, p, child_dist);

            junction_moving_dir += normal(below.junction_loc - p, below.total_recti_dist);
        }
        if (junction_moving_dir != Point(0, 0) && ! children.empty())
        {
            coord_t junction_moving_dir_len = vSize(junction_moving_dir);
            if (junction_moving_dir_len > junction_magnitude)
            {
                junction_moving_dir = junction_moving_dir * junction_magnitude / junction_moving_dir_len;
            }
            p += junction_moving_dir;
        }
        return RectilinearJunction{ accumulated_dist, p };
    }
}

// Prune the tree from the extremeties (leaf-nodes) until the pruning distance is reached.
coord_t LightningTreeNode::prune(const coord_t& pruning_distance)
{
    if (pruning_distance <= 0)
    {
        return 0;
    }

    coord_t max_distance_pruned = 0;
    for (auto child_it = children.begin(); child_it != children.end(); )
    {
        auto& child = *child_it;
        coord_t dist_pruned_child = child->prune(pruning_distance);
        if (dist_pruned_child >= pruning_distance)
        { // pruning is finished for child; dont modify further
            max_distance_pruned = std::max(max_distance_pruned, dist_pruned_child);
            ++child_it;
        }
        else
        {
            Point a = getLocation();
            Point b = child->getLocation();
            Point ba = a - b;
            coord_t ab_len = vSize(ba);
            if (dist_pruned_child + ab_len <= pruning_distance)
            { // we're still in the process of pruning
                assert(child->children.empty() && "when pruning away a node all it's children must already have been pruned away");
                max_distance_pruned = std::max(max_distance_pruned, dist_pruned_child + ab_len);
                child_it = children.erase(child_it);
            }
            else
            { // pruning stops in between this node and the child
                Point n = b + normal(ba, pruning_distance - dist_pruned_child);
                assert(std::abs(vSize(n - b) + dist_pruned_child - pruning_distance) < 10 && "total pruned distance must be equal to the pruning_distance");
                max_distance_pruned = std::max(max_distance_pruned, pruning_distance);
                child->setLocation(n);
                ++child_it;
            }
        }
    }

    return max_distance_pruned;
}
<commit_msg>try to favor dissolving small branches over reducing the length of big subtrees<commit_after>//Copyright (c) 2021 Ultimaker B.V.
//CuraEngine is released under the terms of the AGPLv3 or higher.

#include "LightningTree.h"

#include "../utils/linearAlg2D.h"

using namespace cura;

coord_t LightningTreeNode::getWeightedDistance(const Point& unsupported_loc, const coord_t& supporting_radius) const
{
    size_t valence = (!is_root) + children.size();
    coord_t boost = (0 < valence && valence < 4) ? 4 * supporting_radius : 0;
    return vSize(getLocation() - unsupported_loc) - boost;
}

bool LightningTreeNode::hasOffspring(const std::shared_ptr<LightningTreeNode>& to_be_checked) const
{
    if (to_be_checked == shared_from_this()) return true;
    for (auto child_ptr : children)
    {
        if (child_ptr->hasOffspring(to_be_checked)) return true;
    }
    return false;
}

const Point& LightningTreeNode::getLocation() const
{
    return p;
}

void LightningTreeNode::setLocation(const Point& loc)
{
    p = loc;
}

std::shared_ptr<LightningTreeNode> LightningTreeNode::addChild(const Point& child_loc)
{
    assert(p != child_loc);
    children.push_back(LightningTreeNode::create(child_loc));
    return children.back();
}

std::shared_ptr<LightningTreeNode> LightningTreeNode::addChild(std::shared_ptr<LightningTreeNode>& new_child)
{
    assert(new_child != shared_from_this());
    //     assert(p != new_child->p);
    if (p == new_child->p)
        std::cerr << "wtf\n";
    children.push_back(new_child);
    new_child->is_root = false;
    return new_child;
}

std::shared_ptr<LightningTreeNode> LightningTreeNode::findClosestNode(const Point& x, const coord_t& supporting_radius)
{
    coord_t closest_distance = getWeightedDistance(x, supporting_radius);
    std::shared_ptr<LightningTreeNode> closest_node = shared_from_this();
    findClosestNodeHelper(x, supporting_radius, closest_distance, closest_node);
    return closest_node;
}

void LightningTreeNode::propagateToNextLayer
(
    std::vector<std::shared_ptr<LightningTreeNode>>& next_trees,
    const Polygons& next_outlines,
    const coord_t& prune_distance,
    const coord_t& smooth_magnitude
) const
{
    auto tree_below = deepCopy();

    // TODO: What is the correct order of the following operations?
    //       (NOTE: in case realign turns out _not_ to be last, would need to rewrite a few things, see the 'rerooted_parts' parameter of that function).
    tree_below->prune(prune_distance);
    tree_below->straighten(smooth_magnitude);
    if (tree_below->realign(next_outlines, next_trees))
    {
        next_trees.push_back(tree_below);
    }
}

// NOTE: Depth-first, as currently implemented.
//       Skips the root (because that has no root itself), but all initial nodes will have the root point anyway.
void LightningTreeNode::visitBranches(const branch_visitor_func_t& visitor) const
{
    for (const auto& node : children)
    {
        visitor(p, node->p);
        node->visitBranches(visitor);
    }
}

// NOTE: Depth-first, as currently implemented.
void LightningTreeNode::visitNodes(const node_visitor_func_t& visitor)
{
    visitor(shared_from_this());
    for (const auto& node : children)
    {
        node->visitNodes(visitor);
    }
}

// Node:
LightningTreeNode::LightningTreeNode(const Point& p) : is_root(false), p(p) {}

// Root (and Trunk):
LightningTreeNode::LightningTreeNode(const Point& a, const Point& b) : LightningTreeNode(a)
{
    children.push_back(LightningTreeNode::create(b));
    is_root = true;
}

void LightningTreeNode::findClosestNodeHelper(const Point& x, const coord_t supporting_radius, coord_t& closest_distance, std::shared_ptr<LightningTreeNode>& closest_node)
{
    for (const auto& node : children)
    {
        node->findClosestNodeHelper(x, supporting_radius, closest_distance, closest_node);
        const coord_t distance = node->getWeightedDistance(x, supporting_radius);
        if (distance < closest_distance)
        {
            closest_node = node;
            closest_distance = distance;
        }
    }
}

std::shared_ptr<LightningTreeNode> LightningTreeNode::deepCopy() const
{
    std::shared_ptr<LightningTreeNode> local_root = LightningTreeNode::create(p);
    local_root->is_root = is_root;
    local_root->children.reserve(children.size());
    for (const auto& node : children)
    {
        local_root->children.push_back(node->deepCopy());
    }
    return local_root;
}

bool LightningTreeNode::realign(const Polygons& outlines, std::vector<std::shared_ptr<LightningTreeNode>>& rerooted_parts, const bool& connected_to_parent)
{
    // TODO: Hole(s) in the _middle_ of a line-segement, not unlikely since reconnect.
    // TODO: Reconnect if not on outline -> plan is: yes, but not here anymore!

    if (outlines.empty())
    {
        return false;
    }

    if (outlines.inside(p, true))
    {
        // Only keep children that have an unbroken connection to here, realign will put the rest in rerooted parts due to recursion:
        const std::function<bool(const std::shared_ptr<LightningTreeNode>& child)> remove_unconnected_func
        (
            [&outlines, &rerooted_parts](const std::shared_ptr<LightningTreeNode>& child)
            {
                constexpr bool argument_with_connected = true;
                return !child->realign(outlines, rerooted_parts, argument_with_connected);
            }
        );
        children.erase(std::remove_if(children.begin(), children.end(), remove_unconnected_func), children.end());
        return true;
    }

    // 'Lift' any decendants out of this tree:
    for (auto& child : children)
    {
        constexpr bool argument_with_disconnect = false;
        if (child->realign(outlines, rerooted_parts, argument_with_disconnect))
        {
            rerooted_parts.push_back(child);
        }
    }
    children.clear();

    if (connected_to_parent)
    {
        // This will now be a (new_ leaf:
        p = PolygonUtils::findClosest(p, outlines).p();
        return true;
    }

    return false;
}

void LightningTreeNode::straighten(const coord_t& magnitude)
{
    straighten(magnitude, p, 0);
}

LightningTreeNode::RectilinearJunction LightningTreeNode::straighten(const coord_t& magnitude, Point junction_above, coord_t accumulated_dist)
{
    const coord_t junction_magnitude = magnitude * 3 / 4;
    if (children.size() == 1)
    {
        auto child_p = children.front();
        coord_t child_dist = vSize(p - child_p->p);
        RectilinearJunction junction_below = child_p->straighten(magnitude, junction_above, accumulated_dist + child_dist);
        coord_t total_dist_to_junction_below = junction_below.total_recti_dist;
        Point a = junction_above;
        Point b = junction_below.junction_loc;
        if (a != b) // should always be true!
        {
            Point ab = b - a;
            Point destination = a + ab * accumulated_dist / total_dist_to_junction_below;
            if (shorterThen(destination - p, magnitude))
            {
                p = destination;
            }
            else
            {
                p = p + normal(destination - p, magnitude);
            }
        }
        return junction_below;
    }
    else
    {
        coord_t small_branch = 800;
        auto weight = [magnitude, small_branch](coord_t d) { return std::max(10 * (small_branch - d), coord_t(std::sqrt(small_branch * d))); };
        Point junction_moving_dir = normal(junction_above - p, weight(accumulated_dist));
        for (auto child_p : children)
        {
            coord_t child_dist = vSize(p - child_p->p);
            RectilinearJunction below = child_p->straighten(magnitude, p, child_dist);

            junction_moving_dir += normal(below.junction_loc - p, weight(below.total_recti_dist));
        }
        if (junction_moving_dir != Point(0, 0) && ! children.empty())
        {
            coord_t junction_moving_dir_len = vSize(junction_moving_dir);
            if (junction_moving_dir_len > junction_magnitude)
            {
                junction_moving_dir = junction_moving_dir * junction_magnitude / junction_moving_dir_len;
            }
            p += junction_moving_dir;
        }
        return RectilinearJunction{ accumulated_dist, p };
    }
}

// Prune the tree from the extremeties (leaf-nodes) until the pruning distance is reached.
coord_t LightningTreeNode::prune(const coord_t& pruning_distance)
{
    if (pruning_distance <= 0)
    {
        return 0;
    }

    coord_t max_distance_pruned = 0;
    for (auto child_it = children.begin(); child_it != children.end(); )
    {
        auto& child = *child_it;
        coord_t dist_pruned_child = child->prune(pruning_distance);
        if (dist_pruned_child >= pruning_distance)
        { // pruning is finished for child; dont modify further
            max_distance_pruned = std::max(max_distance_pruned, dist_pruned_child);
            ++child_it;
        }
        else
        {
            Point a = getLocation();
            Point b = child->getLocation();
            Point ba = a - b;
            coord_t ab_len = vSize(ba);
            if (dist_pruned_child + ab_len <= pruning_distance)
            { // we're still in the process of pruning
                assert(child->children.empty() && "when pruning away a node all it's children must already have been pruned away");
                max_distance_pruned = std::max(max_distance_pruned, dist_pruned_child + ab_len);
                child_it = children.erase(child_it);
            }
            else
            { // pruning stops in between this node and the child
                Point n = b + normal(ba, pruning_distance - dist_pruned_child);
                assert(std::abs(vSize(n - b) + dist_pruned_child - pruning_distance) < 10 && "total pruned distance must be equal to the pruning_distance");
                max_distance_pruned = std::max(max_distance_pruned, pruning_distance);
                child->setLocation(n);
                ++child_it;
            }
        }
    }

    return max_distance_pruned;
}
<|endoftext|>


<commit_before>#include "types.h"
#include "stat.h"
#include "user.h"
#include "mtrace.h"
#include "amd64.h"
#include "fcntl.h"

static const bool pinit = true;

#ifdef HW_qemu
enum { nloop = 50 };
#else
enum { nloop = 1000 };
#endif

enum { nfile = 10 };
enum { nlookup = 100 };

void
bench(u32 tid)
{
  char pn[MAXNAME];

  if (pinit)
    setaffinity(tid);

  for (u32 x = 0; x < nloop; x++) {
    for (u32 i = 0; i < nfile; i++) {
      snprintf(pn, sizeof(pn), "/dbx/f:%d:%d", tid, i);

      int fd = open(pn, O_CREATE | O_RDWR);
      if (fd < 0)
	die("create failed\n");

      close(fd);
    }

    for (u32 i = 0; i < nlookup; i++) {
      snprintf(pn, sizeof(pn), "/dbx/f:%d:%d", tid, (i % nfile));
      int fd = open(pn, O_RDWR);
      if (fd < 0)
        die("open failed\n");

      close(fd);
    }

    for (u32 i = 0; i < nfile; i++) {
      snprintf(pn, sizeof(pn), "/dbx/f:%d:%d", tid, i);
      if (unlink(pn) < 0)
	die("unlink failed\n");
    }
  }

  exit();
}

int
main(int ac, char** av)
{
  int nthread;

  if (ac < 2)
    die("usage: %s nthreads", av[0]);

  nthread = atoi(av[1]);

  mkdir("/dbx");

  mtenable("xv6-schedbench");
  u64 t0 = rdtsc();
  for(u32 i = 0; i < nthread; i++) {
    int pid = fork(0);
    if (pid == 0)
      bench(i);
    else if (pid < 0)
      die("fork");
  }

  for (u32 i = 0; i < nthread; i++)
    wait();
  u64 t1 = rdtsc();
  mtdisable("xv6-schedbench");

  printf("dirbench: %lu\n", t1-t0);
  return 0;
}
<commit_msg>dirbench hacks to work-around broken copy-on-write<commit_after>#include "types.h"
#include "stat.h"
#include "user.h"
#include "mtrace.h"
#include "amd64.h"
#include "fcntl.h"

static const bool pinit = true;

enum { nfile = 10 };
enum { nlookup = 100 };

void
bench(u32 tid, int nloop)
{
  char pn[MAXNAME];

  if (pinit)
    setaffinity(tid);

  for (u32 x = 0; x < nloop; x++) {
    for (u32 i = 0; i < nfile; i++) {
      snprintf(pn, sizeof(pn), "/dbx/f:%d:%d", tid, i);

      int fd = open(pn, O_CREATE | O_RDWR);
      if (fd < 0)
	die("create failed\n");

      close(fd);
    }

    for (u32 i = 0; i < nlookup; i++) {
      snprintf(pn, sizeof(pn), "/dbx/f:%d:%d", tid, (i % nfile));
      int fd = open(pn, O_RDWR);
      if (fd < 0)
        die("open failed\n");

      close(fd);
    }

    for (u32 i = 0; i < nfile; i++) {
      snprintf(pn, sizeof(pn), "/dbx/f:%d:%d", tid, i);
      if (unlink(pn) < 0)
	die("unlink failed\n");
    }
  }

  exit();
}

int
main(int ac, char** av)
{
  int nthread;
  int nloop;

#ifdef HW_qemu
  nloop = 50;
#else
  nloop = 1000;
#endif

  if (ac < 2)
    die("usage: %s nthreads [nloop]", av[0]);

  nthread = atoi(av[1]);
  if (ac > 2)
    nloop = atoi(av[2]);

  mkdir("/dbx");

  mtenable("xv6-schedbench");
  u64 t0 = rdtsc();
  for(u32 i = 0; i < nthread; i++) {
    int pid = fork(0);
    if (pid == 0)
      bench(i, nloop);
    else if (pid < 0)
      die("fork");
  }

  for (u32 i = 0; i < nthread; i++)
    wait();
  u64 t1 = rdtsc();
  mtdisable("xv6-schedbench");

  printf("dirbench: %lu\n", t1-t0);
  return 0;
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
 */

#include "bgp/enet/enet_table.h"

#include <boost/functional/hash.hpp>
#include <boost/scoped_ptr.hpp>

#include "base/util.h"
#include "bgp/bgp_attr.h"
#include "bgp/bgp_factory.h"
#include "bgp/bgp_path.h"
#include "bgp/bgp_route.h"
#include "bgp/ipeer.h"
#include "bgp/routing-instance/routing_instance.h"
#include "bgp/enet/enet_route.h"
#include "bgp/evpn/evpn_route.h"
#include "bgp/routing-instance/routing_instance.h"
#include "db/db_table_partition.h"

using namespace std;

size_t EnetTable::HashFunction(const EnetPrefix &prefix) {
    const uint8_t *data = prefix.mac_addr().GetData();
    uint32_t value = get_value(data + 2, 4);
    return boost::hash_value(value);
}

EnetTable::EnetTable(DB *db, const std::string &name) : BgpTable(db, name) {
}

std::auto_ptr<DBEntry> EnetTable::AllocEntry(
        const DBRequestKey *key) const {
    const RequestKey *pfxkey = static_cast<const RequestKey *>(key);
    return std::auto_ptr<DBEntry> (new EnetRoute(pfxkey->prefix));
}

std::auto_ptr<DBEntry> EnetTable::AllocEntryStr(
        const string &key_str) const {
    EnetPrefix prefix = EnetPrefix::FromString(key_str);
    return std::auto_ptr<DBEntry> (new EnetRoute(prefix));
}

size_t EnetTable::Hash(const DBRequestKey *key) const {
    const RequestKey *rkey = static_cast<const RequestKey *>(key);
    size_t value = HashFunction(rkey->prefix);
    return value % DB::PartitionCount();
}

size_t EnetTable::Hash(const DBEntry *entry) const {
    const EnetRoute *rt_entry = static_cast<const EnetRoute *>(entry);
    size_t value = HashFunction(rt_entry->GetPrefix());
    return value % DB::PartitionCount();
}

BgpRoute *EnetTable::TableFind(DBTablePartition *rtp,
        const DBRequestKey *prefix) {
    const RequestKey *pfxkey = static_cast<const RequestKey *>(prefix);
    EnetRoute rt_key(pfxkey->prefix);
    return static_cast<BgpRoute *>(rtp->Find(&rt_key));
}

DBTableBase *EnetTable::CreateTable(DB *db, const std::string &name) {
    EnetTable *table = new EnetTable(db, name);
    table->Init();
    return table;
}

BgpRoute *EnetTable::RouteReplicate(BgpServer *server,
        BgpTable *src_table, BgpRoute *src_rt, const BgpPath *src_path,
        ExtCommunityPtr community) {
    assert(src_table->family() == Address::EVPN);

    EnetRoute *enet= dynamic_cast<EnetRoute *>(src_rt);
    boost::scoped_ptr<EnetPrefix> enet_prefix;

    if (enet) {
        enet_prefix.reset(new EnetPrefix(enet->GetPrefix().mac_addr(),
            enet->GetPrefix().ip_prefix()));
    } else {
        EvpnRoute *evpn = dynamic_cast<EvpnRoute *>(src_rt);
        assert(evpn);
        enet_prefix.reset(new EnetPrefix(evpn->GetPrefix().mac_addr(),
            evpn->GetPrefix().ip_prefix()));
    }

    EnetRoute rt_key(*enet_prefix);
    DBTablePartition *rtp =
        static_cast<DBTablePartition *>(GetTablePartition(&rt_key));
    BgpRoute *dest_route = static_cast<BgpRoute *>(rtp->Find(&rt_key));
    if (dest_route == NULL) {
        dest_route = new EnetRoute(rt_key.GetPrefix());
        rtp->Add(dest_route);
    } else {
        dest_route->ClearDelete();
    }

    // Replace the extended community with the one provided.
    BgpAttrPtr new_attr = server->attr_db()->ReplaceExtCommunityAndLocate(
        src_path->GetAttr(), community);

    // Check whether peer already has a path.
    BgpPath *dest_path =
        dest_route->FindSecondaryPath(src_rt, src_path->GetPeer(),
                                      src_path->GetSource());
    if (dest_path != NULL) {
        if ((new_attr != dest_path->GetAttr()) ||
            (src_path->GetLabel() != dest_path->GetLabel())) {
            assert(dest_route->RemoveSecondaryPath(src_rt, src_path->GetPeer(),
                                            src_path->GetSource()));
        } else {
            return dest_route;
        }
    }

    BgpSecondaryPath *replicated_path =
        new BgpSecondaryPath(src_path->GetPeer(), src_path->GetSource(),
                     new_attr, src_path->GetFlags(), src_path->GetLabel());
    replicated_path->SetReplicateInfo(src_table, src_rt);
    dest_route->InsertPath(replicated_path);

    // Notify the route even if the best path may not have changed. For XMPP
    // peers, we support sending multiple ECMP next-hops for a single route.
    rtp->Notify(dest_route);

    return dest_route;
}

bool EnetTable::Export(RibOut *ribout, Route *route,
        const RibPeerSet &peerset, UpdateInfoSList &uinfo_slist) {
    BgpRoute *bgp_route = static_cast<BgpRoute *> (route);
    UpdateInfo *uinfo = GetUpdateInfo(ribout, bgp_route, peerset);
    if (!uinfo)
        return false;
    uinfo_slist->push_front(*uinfo);

    return true;
}

static void RegisterFactory() {
    DB::RegisterFactory("enet.0", &EnetTable::CreateTable);
}

MODULE_INITIALIZER(RegisterFactory);
<commit_msg>Partial fix for bug 1989.<commit_after>/*
 * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
 */

#include "bgp/enet/enet_table.h"

#include <boost/functional/hash.hpp>
#include <boost/scoped_ptr.hpp>

#include "base/util.h"
#include "bgp/bgp_attr.h"
#include "bgp/bgp_factory.h"
#include "bgp/bgp_path.h"
#include "bgp/bgp_route.h"
#include "bgp/ipeer.h"
#include "bgp/routing-instance/routing_instance.h"
#include "bgp/enet/enet_route.h"
#include "bgp/evpn/evpn_route.h"
#include "bgp/routing-instance/routing_instance.h"
#include "db/db_table_partition.h"

using namespace std;

size_t EnetTable::HashFunction(const EnetPrefix &prefix) {
    const uint8_t *data = prefix.mac_addr().GetData();
    uint32_t value = get_value(data + 2, 4);
    return boost::hash_value(value);
}

EnetTable::EnetTable(DB *db, const std::string &name) : BgpTable(db, name) {
}

std::auto_ptr<DBEntry> EnetTable::AllocEntry(
        const DBRequestKey *key) const {
    const RequestKey *pfxkey = static_cast<const RequestKey *>(key);
    return std::auto_ptr<DBEntry> (new EnetRoute(pfxkey->prefix));
}

std::auto_ptr<DBEntry> EnetTable::AllocEntryStr(
        const string &key_str) const {
    EnetPrefix prefix = EnetPrefix::FromString(key_str);
    return std::auto_ptr<DBEntry> (new EnetRoute(prefix));
}

size_t EnetTable::Hash(const DBRequestKey *key) const {
    const RequestKey *rkey = static_cast<const RequestKey *>(key);
    size_t value = HashFunction(rkey->prefix);
    return value % DB::PartitionCount();
}

size_t EnetTable::Hash(const DBEntry *entry) const {
    const EnetRoute *rt_entry = static_cast<const EnetRoute *>(entry);
    size_t value = HashFunction(rt_entry->GetPrefix());
    return value % DB::PartitionCount();
}

BgpRoute *EnetTable::TableFind(DBTablePartition *rtp,
        const DBRequestKey *prefix) {
    const RequestKey *pfxkey = static_cast<const RequestKey *>(prefix);
    EnetRoute rt_key(pfxkey->prefix);
    return static_cast<BgpRoute *>(rtp->Find(&rt_key));
}

DBTableBase *EnetTable::CreateTable(DB *db, const std::string &name) {
    EnetTable *table = new EnetTable(db, name);
    table->Init();
    return table;
}

BgpRoute *EnetTable::RouteReplicate(BgpServer *server,
        BgpTable *src_table, BgpRoute *src_rt, const BgpPath *src_path,
        ExtCommunityPtr community) {
    if (src_table->family() != Address::EVPN)
        return NULL;

    EnetRoute *enet= dynamic_cast<EnetRoute *>(src_rt);
    boost::scoped_ptr<EnetPrefix> enet_prefix;

    if (enet) {
        enet_prefix.reset(new EnetPrefix(enet->GetPrefix().mac_addr(),
            enet->GetPrefix().ip_prefix()));
    } else {
        EvpnRoute *evpn = dynamic_cast<EvpnRoute *>(src_rt);
        assert(evpn);
        enet_prefix.reset(new EnetPrefix(evpn->GetPrefix().mac_addr(),
            evpn->GetPrefix().ip_prefix()));
    }

    EnetRoute rt_key(*enet_prefix);
    DBTablePartition *rtp =
        static_cast<DBTablePartition *>(GetTablePartition(&rt_key));
    BgpRoute *dest_route = static_cast<BgpRoute *>(rtp->Find(&rt_key));
    if (dest_route == NULL) {
        dest_route = new EnetRoute(rt_key.GetPrefix());
        rtp->Add(dest_route);
    } else {
        dest_route->ClearDelete();
    }

    // Replace the extended community with the one provided.
    BgpAttrPtr new_attr = server->attr_db()->ReplaceExtCommunityAndLocate(
        src_path->GetAttr(), community);

    // Check whether peer already has a path.
    BgpPath *dest_path =
        dest_route->FindSecondaryPath(src_rt, src_path->GetPeer(),
                                      src_path->GetSource());
    if (dest_path != NULL) {
        if ((new_attr != dest_path->GetAttr()) ||
            (src_path->GetLabel() != dest_path->GetLabel())) {
            assert(dest_route->RemoveSecondaryPath(src_rt, src_path->GetPeer(),
                                            src_path->GetSource()));
        } else {
            return dest_route;
        }
    }

    BgpSecondaryPath *replicated_path =
        new BgpSecondaryPath(src_path->GetPeer(), src_path->GetSource(),
                     new_attr, src_path->GetFlags(), src_path->GetLabel());
    replicated_path->SetReplicateInfo(src_table, src_rt);
    dest_route->InsertPath(replicated_path);

    // Notify the route even if the best path may not have changed. For XMPP
    // peers, we support sending multiple ECMP next-hops for a single route.
    rtp->Notify(dest_route);

    return dest_route;
}

bool EnetTable::Export(RibOut *ribout, Route *route,
        const RibPeerSet &peerset, UpdateInfoSList &uinfo_slist) {
    BgpRoute *bgp_route = static_cast<BgpRoute *> (route);
    UpdateInfo *uinfo = GetUpdateInfo(ribout, bgp_route, peerset);
    if (!uinfo)
        return false;
    uinfo_slist->push_front(*uinfo);

    return true;
}

static void RegisterFactory() {
    DB::RegisterFactory("enet.0", &EnetTable::CreateTable);
}

MODULE_INITIALIZER(RegisterFactory);
<|endoftext|>


<commit_before>#include <io/network/tcpSocket.h>
#include <logging.h>

#ifdef __WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
static constexpr int flags = 0;
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
static constexpr int flags = MSG_NOSIGNAL;
#endif

extern "C" {
    struct X509;
    struct X509_STORE;
    struct SSL_CTX;
    struct SSL_METHOD;
    struct SSL;

    static X509_STORE* (*X509_STORE_new)();
    static X509* (*d2i_X509)(X509**, const unsigned char **, long);
    static int (*X509_STORE_add_cert)(X509_STORE*, X509*);
    static void (*X509_free)(X509*);
    static SSL_CTX* (*SSL_CTX_new)(const SSL_METHOD*);
    static const SSL_METHOD* (*TLSv1_2_client_method)();
    static long (*SSL_CTX_set_options)(SSL_CTX*, long);
    static int (*SSL_CTX_set_default_verify_paths)(SSL_CTX*);
    static void (*SSL_CTX_set_cert_store)(SSL_CTX*, X509_STORE*);
    static SSL* (*SSL_new)(SSL_CTX*);
    static int (*SSL_set_fd)(SSL *ssl, int fd);
    static int (*SSL_connect)(SSL *ssl);
    static long (*SSL_get_verify_result)(const SSL *ssl);
    static int (*SSL_read)(SSL *ssl, void *buf, int num);
    static int (*SSL_write)(SSL *ssl, const void *buf, int num);
    static void (*SSL_free)(SSL *ssl);

    static SSL_CTX* ssl_context;
}

# define SSL_OP_NO_SSLv2                                 0x01000000L
# define SSL_OP_NO_SSLv3                                 0x02000000L
# define SSL_OP_NO_TLSv1                                 0x04000000L
# define SSL_OP_NO_TLSv1_2                               0x08000000L
# define SSL_OP_NO_TLSv1_1                               0x10000000L

#include "dynamicLibrary.h"

static std::unique_ptr<DynamicLibrary> libcrypto;
static std::unique_ptr<DynamicLibrary> libssl;

static void initializeLibSSL()
{
    static bool initialized = false;
    if (initialized) return;
    initialized = true;

#ifdef __WIN32
    libcrypto = DynamicLibrary::open("libcrypto-1_1.dll");
    libssl = DynamicLibrary::open("libssl-1_1.dll");
#else
    libcrypto = DynamicLibrary::open("libcrypto.so.1.1");
    libssl = DynamicLibrary::open("libssl.so.1.1");
#endif
    if (!libcrypto || !libssl)
        return;

    X509_STORE_new = libcrypto->getFunction<X509_STORE*(*)()>("X509_STORE_new");
    d2i_X509 = libcrypto->getFunction<X509* (*)(X509**, const unsigned char **, long)>("d2i_X509");
    X509_STORE_add_cert = libcrypto->getFunction<int (*)(X509_STORE*, X509*)>("X509_STORE_add_cert");
    X509_free = libcrypto->getFunction<void (*)(X509*)>("X509_free");

    SSL_CTX_new = libssl->getFunction<SSL_CTX*(*)(const SSL_METHOD*)>("SSL_CTX_new");
    TLSv1_2_client_method = libssl->getFunction<const SSL_METHOD* (*)()>("TLSv1_2_client_method");
    SSL_CTX_set_options = libssl->getFunction<long (*)(SSL_CTX*, long)>("SSL_CTX_set_options");
    SSL_CTX_set_default_verify_paths = libssl->getFunction<int (*)(SSL_CTX*)>("SSL_CTX_set_default_verify_paths");
    SSL_CTX_set_cert_store = libssl->getFunction<void (*)(SSL_CTX*, X509_STORE*)>("SSL_CTX_set_cert_store");
    SSL_new = libssl->getFunction<SSL* (*)(SSL_CTX*)>("SSL_new");
    SSL_set_fd = libssl->getFunction<int (*)(SSL *ssl, int fd)>("SSL_set_fd");
    SSL_connect = libssl->getFunction<int (*)(SSL *ssl)>("SSL_connect");
    SSL_get_verify_result = libssl->getFunction<long (*)(const SSL *ssl)>("SSL_get_verify_result");
    SSL_read = libssl->getFunction<int (*)(SSL *ssl, void *buf, int num)>("SSL_read");
    SSL_write = libssl->getFunction<int (*)(SSL *ssl, const void *buf, int num)>("SSL_write");
    SSL_free = libssl->getFunction<void (*)(SSL *ssl)>("SSL_free");

#ifdef __WIN32
    HCERTSTORE hStore;
    PCCERT_CONTEXT pContext = NULL;
    X509 *x509;
    X509_STORE *store = X509_STORE_new();

    hStore = CertOpenSystemStore(0, "ROOT");
    while((pContext = CertEnumCertificatesInStore(hStore, pContext)) != nullptr)
    {
        const unsigned char* c = pContext->pbCertEncoded;
        x509 = d2i_X509(nullptr, &c, pContext->cbCertEncoded);
        if (x509)
        {
            X509_STORE_add_cert(store, x509);
            X509_free(x509);
        }
    }
    CertFreeCertificateContext(pContext);
    CertCloseStore(hStore, 0);
#endif

    ssl_context = SSL_CTX_new(TLSv1_2_client_method());
    SSL_CTX_set_options(ssl_context, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1);
#ifdef __WIN32
    SSL_CTX_set_cert_store(ssl_context, store);
#else
    SSL_CTX_set_default_verify_paths(ssl_context);
#endif
}

namespace sp {
namespace io {
namespace network {

TcpSocket::TcpSocket()
: ssl_handle(nullptr)
{
}

TcpSocket::TcpSocket(TcpSocket&& socket)
{
    *this = std::move(socket);
}

TcpSocket::~TcpSocket()
{
    close();
}

TcpSocket& TcpSocket::operator=(TcpSocket&& socket)
{
    close();

    handle = socket.handle;
    ssl_handle = socket.ssl_handle;
    send_queue = std::move(socket.send_queue);
    blocking = socket.blocking;
    receive_buffer = std::move(socket.receive_buffer);
    received_size = socket.received_size;

    socket.handle = -1;
    socket.send_queue.clear();
    socket.receive_buffer.clear();
    socket.received_size = 0;
    socket.ssl_handle = nullptr;

    return *this;
}

bool TcpSocket::connect(const Address& host, int port)
{
    if (isConnected())
        close();

    for(const auto& addr_info : host.addr_info)
    {
        handle = ::socket(addr_info.family, SOCK_STREAM, 0);
        if (handle < 0)
            return false;
        if (addr_info.family == AF_INET && sizeof(struct sockaddr_in) == addr_info.addr.length())
        {
            struct sockaddr_in server_addr;
            memset(&server_addr, 0, sizeof(server_addr));
            memcpy(&server_addr, addr_info.addr.data(), addr_info.addr.length());
            server_addr.sin_port = htons(port);
            if (::connect(handle, reinterpret_cast<const sockaddr*>(&server_addr), sizeof(server_addr)) == 0)
            {
                setBlocking(blocking);
                return true;
            }
        }
        if (addr_info.family == AF_INET6 && sizeof(struct sockaddr_in6) == addr_info.addr.length())
        {
            struct sockaddr_in6 server_addr;
            memset(&server_addr, 0, sizeof(server_addr));
            memcpy(&server_addr, addr_info.addr.data(), addr_info.addr.length());
            server_addr.sin6_port = htons(port);
            if (::connect(handle, reinterpret_cast<const sockaddr*>(&server_addr), sizeof(server_addr)) == 0)
            {
                setBlocking(blocking);
                return true;
            }
        }
        close();
    }
    return false;
}

bool TcpSocket::connectSSL(const Address& host, int port)
{
    if (!connect(host, port))
        return false;
    initializeLibSSL();
    if (!SSL_new)
    {
        LOG(Warning, "Failed to connect SSL socket due to missing libssl/libcrypto v1.1");
        close();
        return false;
    }

    ssl_handle = SSL_new(ssl_context);
    SSL_set_fd(static_cast<SSL*>(ssl_handle), handle);
    if (!SSL_connect(static_cast<SSL*>(ssl_handle)))
    {
        LOG(Warning, "Failed to connect SSL socket due to SSL negotiation failure.");
        close();
        return false;
    }
    if (SSL_get_verify_result(static_cast<SSL*>(ssl_handle)) != 0)
    {
        LOG(Warning, "Failed to connect SSL socket due to certificate verfication failure.");
        close();
        return false;
    }
    return true;
}

void TcpSocket::setDelay(bool delay)
{
#ifdef __WIN32
    unsigned long mode = delay ? 0 : 1;
    ::ioctlsocket(handle, TCP_NODELAY, &mode);
#else
    int mode = delay ? 0 : 1;
    setsockopt(handle, IPPROTO_TCP, TCP_NODELAY, (char*)&mode, sizeof(mode));
#endif
}

void TcpSocket::close()
{
    if (isConnected())
    {
#ifdef __WIN32
        closesocket(handle);
#else
        ::close(handle);
#endif
        handle = -1;
        send_queue.clear();
        if (ssl_handle)
            SSL_free(static_cast<SSL*>(ssl_handle));
        ssl_handle = nullptr;
    }
}

bool TcpSocket::isConnected()
{
    return handle != -1;
}

void TcpSocket::send(const void* data, size_t size)
{
    if (!isConnected())
        return;
    if (sendSendQueue())
    {
        queue(data, size);
        return;
    }

    for(size_t done = 0; done < size; )
    {
        int result;
        if (ssl_handle)
            result = SSL_write(static_cast<SSL*>(ssl_handle), static_cast<const char*>(data) + done, size - done);
        else
            result = ::send(handle, static_cast<const char*>(data) + done, size - done, flags);
        if (result < 0)
        {
            if (!isLastErrorNonBlocking())
                close();
            else
                send_queue += std::string(static_cast<const char*>(data) + done, size - done);
            return;
        }
        done += result;
    }
}

void TcpSocket::queue(const void* data, size_t size)
{
    send_queue += std::string(static_cast<const char*>(data), size);
}

size_t TcpSocket::receive(void* data, size_t size)
{
    sendSendQueue();

    if (!isConnected())
        return 0;

    int result;
    if (ssl_handle)
        result = SSL_read(static_cast<SSL*>(ssl_handle), static_cast<char*>(data), size);
    else
        result = ::recv(handle, static_cast<char*>(data), size, flags);
    if (result < 0)
    {
        result = 0;
        if (!isLastErrorNonBlocking())
            close();
    }
    return result;
}

void TcpSocket::send(const io::DataBuffer& buffer)
{
    io::DataBuffer packet_size(uint32_t(buffer.getDataSize()));
    send(packet_size.getData(), packet_size.getDataSize());
    send(buffer.getData(), buffer.getDataSize());
}

void TcpSocket::queue(const io::DataBuffer& buffer)
{
    io::DataBuffer packet_size(uint32_t(buffer.getDataSize()));
    queue(packet_size.getData(), packet_size.getDataSize());
    queue(buffer.getData(), buffer.getDataSize());
}

bool TcpSocket::receive(io::DataBuffer& buffer)
{
    if (!isConnected())
        return 0;

    if (receive_buffer.size() == 0)
    {
        uint8_t size_buffer[sizeof(uint32_t)];
        size_t idx = 0;
        while(idx < sizeof(uint32_t))
        {
            //TOFIX: This blocks if we receive less then 4 bytes. Allows denial of service attack.
            int result;
            if (ssl_handle)
                result = SSL_read(static_cast<SSL*>(ssl_handle), reinterpret_cast<char*>(&size_buffer[idx]), sizeof(uint32_t) - idx);
            else
                result = ::recv(handle, reinterpret_cast<char*>(&size_buffer[idx]), sizeof(uint32_t) - idx, flags);
            if (result < 0)
            {
                result = 0;
                if (!isLastErrorNonBlocking())
                {
                    close();
                    return false;
                }
            }
            if (result == 0 && idx == 0)
                return false;
            idx += result;
        }
        uint32_t size = *reinterpret_cast<uint32_t*>(size_buffer);
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
        size = __builtin_bswap32(size);
#endif
        receive_buffer.resize(size);
        received_size = 0;
    }

    while(true)
    {
        int result;
        if (ssl_handle)
            result = SSL_read(static_cast<SSL*>(ssl_handle), reinterpret_cast<char*>(&receive_buffer[received_size]), receive_buffer.size() - received_size);
        else
            result = ::recv(handle, reinterpret_cast<char*>(&receive_buffer[received_size]), receive_buffer.size() - received_size, flags);
        if (result < 0)
        {
            result = 0;
            if (!isLastErrorNonBlocking())
            {
                close();
                return false;
            }
        }
        received_size += result;
        if (received_size == receive_buffer.size())
        {
            buffer = std::move(receive_buffer);
            received_size = 0;
            return true;
        }
        if (result < 1)
            break;
    }

    return false;
}

bool TcpSocket::sendSendQueue()
{
    if (send_queue.size() < 1)
        return false;

    int result;
    do
    {
        if (ssl_handle)
            result = SSL_write(static_cast<SSL*>(ssl_handle), static_cast<const char*>(send_queue.data()), send_queue.size());
        else
            result = ::send(handle, static_cast<const char*>(send_queue.data()), send_queue.size(), flags);
        if (result < 0)
        {
            result = 0;
            if (!isLastErrorNonBlocking())
                close();
        }
        if (result > 0)
            send_queue = send_queue.substr(result);
    } while(result > 0 && send_queue.size() > 0);

    return send_queue.size() > 0;
}

}//namespace network
}//namespace io
}//namespace sp
<commit_msg>Fix nodelay for linux<commit_after>#include <io/network/tcpSocket.h>
#include <logging.h>

#ifdef __WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
static constexpr int flags = 0;
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
static constexpr int flags = MSG_NOSIGNAL;
#endif

extern "C" {
    struct X509;
    struct X509_STORE;
    struct SSL_CTX;
    struct SSL_METHOD;
    struct SSL;

    static X509_STORE* (*X509_STORE_new)();
    static X509* (*d2i_X509)(X509**, const unsigned char **, long);
    static int (*X509_STORE_add_cert)(X509_STORE*, X509*);
    static void (*X509_free)(X509*);
    static SSL_CTX* (*SSL_CTX_new)(const SSL_METHOD*);
    static const SSL_METHOD* (*TLSv1_2_client_method)();
    static long (*SSL_CTX_set_options)(SSL_CTX*, long);
    static int (*SSL_CTX_set_default_verify_paths)(SSL_CTX*);
    static void (*SSL_CTX_set_cert_store)(SSL_CTX*, X509_STORE*);
    static SSL* (*SSL_new)(SSL_CTX*);
    static int (*SSL_set_fd)(SSL *ssl, int fd);
    static int (*SSL_connect)(SSL *ssl);
    static long (*SSL_get_verify_result)(const SSL *ssl);
    static int (*SSL_read)(SSL *ssl, void *buf, int num);
    static int (*SSL_write)(SSL *ssl, const void *buf, int num);
    static void (*SSL_free)(SSL *ssl);

    static SSL_CTX* ssl_context;
}

# define SSL_OP_NO_SSLv2                                 0x01000000L
# define SSL_OP_NO_SSLv3                                 0x02000000L
# define SSL_OP_NO_TLSv1                                 0x04000000L
# define SSL_OP_NO_TLSv1_2                               0x08000000L
# define SSL_OP_NO_TLSv1_1                               0x10000000L

#include "dynamicLibrary.h"

static std::unique_ptr<DynamicLibrary> libcrypto;
static std::unique_ptr<DynamicLibrary> libssl;

static void initializeLibSSL()
{
    static bool initialized = false;
    if (initialized) return;
    initialized = true;

#ifdef __WIN32
    libcrypto = DynamicLibrary::open("libcrypto-1_1.dll");
    libssl = DynamicLibrary::open("libssl-1_1.dll");
#else
    libcrypto = DynamicLibrary::open("libcrypto.so.1.1");
    libssl = DynamicLibrary::open("libssl.so.1.1");
#endif
    if (!libcrypto || !libssl)
        return;

    X509_STORE_new = libcrypto->getFunction<X509_STORE*(*)()>("X509_STORE_new");
    d2i_X509 = libcrypto->getFunction<X509* (*)(X509**, const unsigned char **, long)>("d2i_X509");
    X509_STORE_add_cert = libcrypto->getFunction<int (*)(X509_STORE*, X509*)>("X509_STORE_add_cert");
    X509_free = libcrypto->getFunction<void (*)(X509*)>("X509_free");

    SSL_CTX_new = libssl->getFunction<SSL_CTX*(*)(const SSL_METHOD*)>("SSL_CTX_new");
    TLSv1_2_client_method = libssl->getFunction<const SSL_METHOD* (*)()>("TLSv1_2_client_method");
    SSL_CTX_set_options = libssl->getFunction<long (*)(SSL_CTX*, long)>("SSL_CTX_set_options");
    SSL_CTX_set_default_verify_paths = libssl->getFunction<int (*)(SSL_CTX*)>("SSL_CTX_set_default_verify_paths");
    SSL_CTX_set_cert_store = libssl->getFunction<void (*)(SSL_CTX*, X509_STORE*)>("SSL_CTX_set_cert_store");
    SSL_new = libssl->getFunction<SSL* (*)(SSL_CTX*)>("SSL_new");
    SSL_set_fd = libssl->getFunction<int (*)(SSL *ssl, int fd)>("SSL_set_fd");
    SSL_connect = libssl->getFunction<int (*)(SSL *ssl)>("SSL_connect");
    SSL_get_verify_result = libssl->getFunction<long (*)(const SSL *ssl)>("SSL_get_verify_result");
    SSL_read = libssl->getFunction<int (*)(SSL *ssl, void *buf, int num)>("SSL_read");
    SSL_write = libssl->getFunction<int (*)(SSL *ssl, const void *buf, int num)>("SSL_write");
    SSL_free = libssl->getFunction<void (*)(SSL *ssl)>("SSL_free");

#ifdef __WIN32
    HCERTSTORE hStore;
    PCCERT_CONTEXT pContext = NULL;
    X509 *x509;
    X509_STORE *store = X509_STORE_new();

    hStore = CertOpenSystemStore(0, "ROOT");
    while((pContext = CertEnumCertificatesInStore(hStore, pContext)) != nullptr)
    {
        const unsigned char* c = pContext->pbCertEncoded;
        x509 = d2i_X509(nullptr, &c, pContext->cbCertEncoded);
        if (x509)
        {
            X509_STORE_add_cert(store, x509);
            X509_free(x509);
        }
    }
    CertFreeCertificateContext(pContext);
    CertCloseStore(hStore, 0);
#endif

    ssl_context = SSL_CTX_new(TLSv1_2_client_method());
    SSL_CTX_set_options(ssl_context, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1);
#ifdef __WIN32
    SSL_CTX_set_cert_store(ssl_context, store);
#else
    SSL_CTX_set_default_verify_paths(ssl_context);
#endif
}

namespace sp {
namespace io {
namespace network {

TcpSocket::TcpSocket()
: ssl_handle(nullptr)
{
}

TcpSocket::TcpSocket(TcpSocket&& socket)
{
    *this = std::move(socket);
}

TcpSocket::~TcpSocket()
{
    close();
}

TcpSocket& TcpSocket::operator=(TcpSocket&& socket)
{
    close();

    handle = socket.handle;
    ssl_handle = socket.ssl_handle;
    send_queue = std::move(socket.send_queue);
    blocking = socket.blocking;
    receive_buffer = std::move(socket.receive_buffer);
    received_size = socket.received_size;

    socket.handle = -1;
    socket.send_queue.clear();
    socket.receive_buffer.clear();
    socket.received_size = 0;
    socket.ssl_handle = nullptr;

    return *this;
}

bool TcpSocket::connect(const Address& host, int port)
{
    if (isConnected())
        close();

    for(const auto& addr_info : host.addr_info)
    {
        handle = ::socket(addr_info.family, SOCK_STREAM, 0);
        if (handle < 0)
            return false;
        if (addr_info.family == AF_INET && sizeof(struct sockaddr_in) == addr_info.addr.length())
        {
            struct sockaddr_in server_addr;
            memset(&server_addr, 0, sizeof(server_addr));
            memcpy(&server_addr, addr_info.addr.data(), addr_info.addr.length());
            server_addr.sin_port = htons(port);
            if (::connect(handle, reinterpret_cast<const sockaddr*>(&server_addr), sizeof(server_addr)) == 0)
            {
                setBlocking(blocking);
                return true;
            }
        }
        if (addr_info.family == AF_INET6 && sizeof(struct sockaddr_in6) == addr_info.addr.length())
        {
            struct sockaddr_in6 server_addr;
            memset(&server_addr, 0, sizeof(server_addr));
            memcpy(&server_addr, addr_info.addr.data(), addr_info.addr.length());
            server_addr.sin6_port = htons(port);
            if (::connect(handle, reinterpret_cast<const sockaddr*>(&server_addr), sizeof(server_addr)) == 0)
            {
                setBlocking(blocking);
                return true;
            }
        }
        close();
    }
    return false;
}

bool TcpSocket::connectSSL(const Address& host, int port)
{
    if (!connect(host, port))
        return false;
    initializeLibSSL();
    if (!SSL_new)
    {
        LOG(Warning, "Failed to connect SSL socket due to missing libssl/libcrypto v1.1");
        close();
        return false;
    }

    ssl_handle = SSL_new(ssl_context);
    SSL_set_fd(static_cast<SSL*>(ssl_handle), handle);
    if (!SSL_connect(static_cast<SSL*>(ssl_handle)))
    {
        LOG(Warning, "Failed to connect SSL socket due to SSL negotiation failure.");
        close();
        return false;
    }
    if (SSL_get_verify_result(static_cast<SSL*>(ssl_handle)) != 0)
    {
        LOG(Warning, "Failed to connect SSL socket due to certificate verfication failure.");
        close();
        return false;
    }
    return true;
}

void TcpSocket::setDelay(bool delay)
{
    int mode = delay ? 0 : 1;
    setsockopt(handle, IPPROTO_TCP, TCP_NODELAY, (char*)&mode, sizeof(mode));
}

void TcpSocket::close()
{
    if (isConnected())
    {
#ifdef __WIN32
        closesocket(handle);
#else
        ::close(handle);
#endif
        handle = -1;
        send_queue.clear();
        if (ssl_handle)
            SSL_free(static_cast<SSL*>(ssl_handle));
        ssl_handle = nullptr;
    }
}

bool TcpSocket::isConnected()
{
    return handle != -1;
}

void TcpSocket::send(const void* data, size_t size)
{
    if (!isConnected())
        return;
    if (sendSendQueue())
    {
        queue(data, size);
        return;
    }

    for(size_t done = 0; done < size; )
    {
        int result;
        if (ssl_handle)
            result = SSL_write(static_cast<SSL*>(ssl_handle), static_cast<const char*>(data) + done, size - done);
        else
            result = ::send(handle, static_cast<const char*>(data) + done, size - done, flags);
        if (result < 0)
        {
            if (!isLastErrorNonBlocking())
                close();
            else
                send_queue += std::string(static_cast<const char*>(data) + done, size - done);
            return;
        }
        done += result;
    }
}

void TcpSocket::queue(const void* data, size_t size)
{
    send_queue += std::string(static_cast<const char*>(data), size);
}

size_t TcpSocket::receive(void* data, size_t size)
{
    sendSendQueue();

    if (!isConnected())
        return 0;

    int result;
    if (ssl_handle)
        result = SSL_read(static_cast<SSL*>(ssl_handle), static_cast<char*>(data), size);
    else
        result = ::recv(handle, static_cast<char*>(data), size, flags);
    if (result < 0)
    {
        result = 0;
        if (!isLastErrorNonBlocking())
            close();
    }
    return result;
}

void TcpSocket::send(const io::DataBuffer& buffer)
{
    io::DataBuffer packet_size(uint32_t(buffer.getDataSize()));
    send(packet_size.getData(), packet_size.getDataSize());
    send(buffer.getData(), buffer.getDataSize());
}

void TcpSocket::queue(const io::DataBuffer& buffer)
{
    io::DataBuffer packet_size(uint32_t(buffer.getDataSize()));
    queue(packet_size.getData(), packet_size.getDataSize());
    queue(buffer.getData(), buffer.getDataSize());
}

bool TcpSocket::receive(io::DataBuffer& buffer)
{
    if (!isConnected())
        return 0;

    if (receive_buffer.size() == 0)
    {
        uint8_t size_buffer[sizeof(uint32_t)];
        size_t idx = 0;
        while(idx < sizeof(uint32_t))
        {
            //TOFIX: This blocks if we receive less then 4 bytes. Allows denial of service attack.
            int result;
            if (ssl_handle)
                result = SSL_read(static_cast<SSL*>(ssl_handle), reinterpret_cast<char*>(&size_buffer[idx]), sizeof(uint32_t) - idx);
            else
                result = ::recv(handle, reinterpret_cast<char*>(&size_buffer[idx]), sizeof(uint32_t) - idx, flags);
            if (result < 0)
            {
                result = 0;
                if (!isLastErrorNonBlocking())
                {
                    close();
                    return false;
                }
            }
            if (result == 0 && idx == 0)
                return false;
            idx += result;
        }
        uint32_t size = *reinterpret_cast<uint32_t*>(size_buffer);
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
        size = __builtin_bswap32(size);
#endif
        receive_buffer.resize(size);
        received_size = 0;
    }

    while(true)
    {
        int result;
        if (ssl_handle)
            result = SSL_read(static_cast<SSL*>(ssl_handle), reinterpret_cast<char*>(&receive_buffer[received_size]), receive_buffer.size() - received_size);
        else
            result = ::recv(handle, reinterpret_cast<char*>(&receive_buffer[received_size]), receive_buffer.size() - received_size, flags);
        if (result < 0)
        {
            result = 0;
            if (!isLastErrorNonBlocking())
            {
                close();
                return false;
            }
        }
        received_size += result;
        if (received_size == receive_buffer.size())
        {
            buffer = std::move(receive_buffer);
            received_size = 0;
            return true;
        }
        if (result < 1)
            break;
    }

    return false;
}

bool TcpSocket::sendSendQueue()
{
    if (send_queue.size() < 1)
        return false;

    int result;
    do
    {
        if (ssl_handle)
            result = SSL_write(static_cast<SSL*>(ssl_handle), static_cast<const char*>(send_queue.data()), send_queue.size());
        else
            result = ::send(handle, static_cast<const char*>(send_queue.data()), send_queue.size(), flags);
        if (result < 0)
        {
            result = 0;
            if (!isLastErrorNonBlocking())
                close();
        }
        if (result > 0)
            send_queue = send_queue.substr(result);
    } while(result > 0 && send_queue.size() > 0);

    return send_queue.size() > 0;
}

}//namespace network
}//namespace io
}//namespace sp
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qbluetoothserviceinfo.h"
#include "qbluetoothserviceinfo_p.h"

QTM_BEGIN_NAMESPACE

bool QBluetoothServiceInfo::isRegistered() const
{
    return false;
}

bool QBluetoothServiceInfo::registerService() const
{
    return false;
}

bool QBluetoothServiceInfo::unregisterService() const
{
    return false;
}

QBluetoothServiceInfoPrivate::QBluetoothServiceInfoPrivate()
{
}

QBluetoothServiceInfoPrivate::~QBluetoothServiceInfoPrivate()
{
}

void QBluetoothServiceInfoPrivate::setRegisteredAttribute(quint16 attributeId, const QVariant &value) const
{
    Q_UNUSED(attributeId);
    Q_UNUSED(value);
}

void QBluetoothServiceInfoPrivate::removeRegisteredAttribute(quint16 attributeId) const
{
    Q_UNUSED(attributeId);
}

#ifndef Q_NO_DBUS
bool QBluetoothServiceInfoPrivate::registerService() const
{
    return false;
}
#endif

QTM_END_NAMESPACE
<commit_msg>Fix typo in Q_NO_DBUS -> QT_NO_DBUS<commit_after>/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qbluetoothserviceinfo.h"
#include "qbluetoothserviceinfo_p.h"

QTM_BEGIN_NAMESPACE

bool QBluetoothServiceInfo::isRegistered() const
{
    return false;
}

bool QBluetoothServiceInfo::registerService() const
{
    return false;
}

bool QBluetoothServiceInfo::unregisterService() const
{
    return false;
}

QBluetoothServiceInfoPrivate::QBluetoothServiceInfoPrivate()
{
}

QBluetoothServiceInfoPrivate::~QBluetoothServiceInfoPrivate()
{
}

void QBluetoothServiceInfoPrivate::setRegisteredAttribute(quint16 attributeId, const QVariant &value) const
{
    Q_UNUSED(attributeId);
    Q_UNUSED(value);
}

void QBluetoothServiceInfoPrivate::removeRegisteredAttribute(quint16 attributeId) const
{
    Q_UNUSED(attributeId);
}

#ifndef QT_NO_DBUS
bool QBluetoothServiceInfoPrivate::registerService() const
{
    return false;
}
#endif

QTM_END_NAMESPACE
<|endoftext|>