<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include <avmedia/modeltools.hxx>
#include <avmedia/mediaitem.hxx>
#include "mediamisc.hxx"

#include <com/sun/star/embed/ElementModes.hpp>
#include <com/sun/star/embed/XTransactedObject.hpp>
#include <com/sun/star/document/XStorageBasedDocument.hpp>
#include <com/sun/star/embed/XStorage.hpp>
#include <osl/file.hxx>
#include <comphelper/processfactory.hxx>
#include <tools/urlobj.hxx>
#include <ucbhelper/content.hxx>
#include <unotools/localfilehelper.hxx>
#include <unotools/tempfile.hxx>

#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <boost/foreach.hpp>
#include <boost/optional.hpp>

#ifdef ENABLE_COLLADA2GLTF
#include <COLLADA2GLTFWriter.h>
#include <GLTFAsset.h>
#include <KMZ2Collada.h>
#endif

#include <string>
#include <vector>

using namespace ::com::sun::star;
using namespace boost::property_tree;

namespace avmedia {

static void lcl_EmbedExternals(const OUString& rSourceURL, uno::Reference<embed::XStorage> xSubStorage, ::ucbhelper::Content& rContent)
{
    // Create a temp file with which json parser can work.
    OUString sTempFileURL;
    const ::osl::FileBase::RC  aErr =
        ::osl::FileBase::createTempFile(0, 0, &sTempFileURL);
    if (::osl::FileBase::E_None != aErr)
    {
        SAL_WARN("avmedia.opengl", "Cannot create temp file");
        return;
    }
    try
    {
        // Write json content to the temp file
        ::ucbhelper::Content aTempContent(sTempFileURL,
            uno::Reference<ucb::XCommandEnvironment>(),
            comphelper::getProcessComponentContext());
        aTempContent.writeStream(rContent.openStream(), true);
    }
    catch (uno::Exception const& e)
    {
        SAL_WARN("avmedia.opengl", "Exception: '" << e.Message << "'");
        return;
    }

    // Convert URL to a file path for loading
    const INetURLObject aURLObj(sTempFileURL);
    std::string sUrl = OUStringToOString( aURLObj.getFSysPath(INetURLObject::FSYS_DETECT), RTL_TEXTENCODING_UTF8 ).getStr();

    // Parse json, read externals' URI and modify this relative URI's so they remain valid in the new context.
    std::vector<std::string> vExternals;
    ptree aTree;
    try
    {
        json_parser::read_json( sUrl, aTree );

        // Buffers for geometry and animations
        BOOST_FOREACH(ptree::value_type &rVal,aTree.get_child("buffers"))
        {
            const std::string sBufferUri(rVal.second.get<std::string>("path"));
            vExternals.push_back(sBufferUri);
            // Change path: make it contain only a file name
            aTree.put("buffers." + rVal.first + ".path.",sBufferUri.substr(sBufferUri.find_last_of('/')+1));
        }
        // Images for textures
        boost::optional< ptree& > aImages = aTree.get_child_optional("images");
        if( aImages )
        {
            BOOST_FOREACH(ptree::value_type &rVal,aImages.get())
            {
                const std::string sImageUri(rVal.second.get<std::string>("path"));
                if( !sImageUri.empty() )
                {
                    vExternals.push_back(sImageUri);
                    // Change path: make it contain only a file name
                    aTree.put("images." + rVal.first + ".path.",sImageUri.substr(sImageUri.find_last_of('/')+1));
                }
            }
        }
        // Shaders (contains names only)
        BOOST_FOREACH(ptree::value_type &rVal,aTree.get_child("programs"))
        {
            vExternals.push_back(rVal.second.get<std::string>("fragmentShader") + ".glsl");
            vExternals.push_back(rVal.second.get<std::string>("vertexShader") + ".glsl");
        }

        // Write out modified json
        json_parser::write_json( sUrl, aTree );
    }
    catch ( boost::exception const& )
    {
        SAL_WARN("avmedia.opengl", "Exception while parsing *.json file");
        return;
    }

    // Reload json with modified path to external resources
    rContent = ::ucbhelper::Content(sTempFileURL,
        uno::Reference<ucb::XCommandEnvironment>(),
        comphelper::getProcessComponentContext());

    // Store all external files next to the json file
    for( std::vector<std::string>::iterator aCIter = vExternals.begin(); aCIter != vExternals.end(); ++aCIter )
    {
        const OUString sAbsURL = INetURLObject::GetAbsURL(rSourceURL,OUString::createFromAscii(aCIter->c_str()));

        ::ucbhelper::Content aContent(sAbsURL,
                uno::Reference<ucb::XCommandEnvironment>(),
                comphelper::getProcessComponentContext());

        uno::Reference<io::XStream> const xStream(
            CreateStream(xSubStorage, GetFilename(sAbsURL)), uno::UNO_SET_THROW);
        uno::Reference<io::XOutputStream> const xOutStream(
            xStream->getOutputStream(), uno::UNO_SET_THROW);

        if (!aContent.openStream(xOutStream))
        {
            SAL_WARN("avmedia.opengl", "openStream to storage failed");
            return;
        }
    }
}

bool Embed3DModel( const uno::Reference<frame::XModel>& xModel,
        const OUString& rSourceURL, OUString& o_rEmbeddedURL)
{
    OUString sSource = rSourceURL;
#ifdef ENABLE_COLLADA2GLTF
    if (rSourceURL.endsWith(".dae") || rSourceURL.endsWith(".kmz"))
    {
        OUString sName;
        ::utl::LocalFileHelper::ConvertPhysicalNameToURL(::utl::TempFile::CreateTempName(), sName);
        // remove .tmp extension
        sName = sName.copy(0, sName.getLength() - 4);
        const INetURLObject aSourceURLObj(rSourceURL);
        std::string sSourcePath = OUStringToOString( aSourceURLObj.getFSysPath(INetURLObject::FSYS_DETECT), RTL_TEXTENCODING_UTF8 ).getStr();

        std::shared_ptr <GLTF::GLTFAsset> asset(new GLTF::GLTFAsset());
        asset->setInputFilePath(sSourcePath);

        if (rSourceURL.endsWith(".kmz"))
        {
            std::string strDaeFilePath = GLTF::Kmz2Collada()(asset->getInputFilePath());
            if (strDaeFilePath == "")
                return false;
            asset->setInputFilePath(strDaeFilePath);
        }
        asset->setBundleOutputPath(OUStringToOString( sName, RTL_TEXTENCODING_UTF8 ).getStr());
        GLTF::COLLADA2GLTFWriter writer(asset);
        writer.write();
        // Path to the .json file created by COLLADA2GLTFWriter
        sSource = sName + "/" + GetFilename(sName) + ".json";
    }
#endif

    try
    {
        ::ucbhelper::Content aSourceContent(sSource,
                uno::Reference<ucb::XCommandEnvironment>(),
                comphelper::getProcessComponentContext());

        // Base storage
        uno::Reference<document::XStorageBasedDocument> const xSBD(xModel,
                uno::UNO_QUERY_THROW);
        uno::Reference<embed::XStorage> const xStorage(
                xSBD->getDocumentStorage(), uno::UNO_QUERY_THROW);

        // Model storage
        const OUString sModel("Model");
        uno::Reference<embed::XStorage> const xModelStorage(
            xStorage->openStorageElement(sModel, embed::ElementModes::WRITE));

        // Own storage of the corresponding model
        const OUString sFilename(GetFilename(sSource));
        const OUString sGLTFDir(sFilename.copy(0,sFilename.lastIndexOf('.')));
        uno::Reference<embed::XStorage> const xSubStorage(
            xModelStorage->openStorageElement(sGLTFDir, embed::ElementModes::WRITE));

        // Embed external resources
        lcl_EmbedExternals(sSource, xSubStorage, aSourceContent);

        // Save model file (.json)
        uno::Reference<io::XStream> const xStream(
            CreateStream(xSubStorage, sFilename), uno::UNO_SET_THROW);
        uno::Reference<io::XOutputStream> const xOutStream(
            xStream->getOutputStream(), uno::UNO_SET_THROW);

        if (!aSourceContent.openStream(xOutStream))
        {
            SAL_WARN("avmedia.opengl", "openStream to storage failed");
            return false;
        }

        const uno::Reference<embed::XTransactedObject> xSubTransaction(xSubStorage, uno::UNO_QUERY);
        if (xSubTransaction.is())
        {
            xSubTransaction->commit();
        }
        const uno::Reference<embed::XTransactedObject> xModelTransaction(xModelStorage, uno::UNO_QUERY);
        if (xModelTransaction.is())
        {
            xModelTransaction->commit();
        }
        const uno::Reference<embed::XTransactedObject> xTransaction(xStorage, uno::UNO_QUERY);
        if (xTransaction.is())
        {
            xTransaction->commit();
        }

        o_rEmbeddedURL = "vnd.sun.star.Package:" + sModel + "/" + sGLTFDir + "/" + sFilename;
        return true;
    }
    catch (uno::Exception const&)
    {
        SAL_WARN("avmedia.opengl", "Exception while trying to embed model");
    }
    return false;
}

bool IsModel(const OUString& rMimeType)
{
    return rMimeType == AVMEDIA_MIMETYPE_JSON;
}

} // namespace avemdia

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>collada2gltf: Ignore case of the extension.<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include <avmedia/modeltools.hxx>
#include <avmedia/mediaitem.hxx>
#include "mediamisc.hxx"

#include <com/sun/star/embed/ElementModes.hpp>
#include <com/sun/star/embed/XTransactedObject.hpp>
#include <com/sun/star/document/XStorageBasedDocument.hpp>
#include <com/sun/star/embed/XStorage.hpp>
#include <osl/file.hxx>
#include <comphelper/processfactory.hxx>
#include <tools/urlobj.hxx>
#include <ucbhelper/content.hxx>
#include <unotools/localfilehelper.hxx>
#include <unotools/tempfile.hxx>

#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <boost/foreach.hpp>
#include <boost/optional.hpp>

#ifdef ENABLE_COLLADA2GLTF
#include <COLLADA2GLTFWriter.h>
#include <GLTFAsset.h>
#include <KMZ2Collada.h>
#endif

#include <string>
#include <vector>

using namespace ::com::sun::star;
using namespace boost::property_tree;

namespace avmedia {

static void lcl_EmbedExternals(const OUString& rSourceURL, uno::Reference<embed::XStorage> xSubStorage, ::ucbhelper::Content& rContent)
{
    // Create a temp file with which json parser can work.
    OUString sTempFileURL;
    const ::osl::FileBase::RC  aErr =
        ::osl::FileBase::createTempFile(0, 0, &sTempFileURL);
    if (::osl::FileBase::E_None != aErr)
    {
        SAL_WARN("avmedia.opengl", "Cannot create temp file");
        return;
    }
    try
    {
        // Write json content to the temp file
        ::ucbhelper::Content aTempContent(sTempFileURL,
            uno::Reference<ucb::XCommandEnvironment>(),
            comphelper::getProcessComponentContext());
        aTempContent.writeStream(rContent.openStream(), true);
    }
    catch (uno::Exception const& e)
    {
        SAL_WARN("avmedia.opengl", "Exception: '" << e.Message << "'");
        return;
    }

    // Convert URL to a file path for loading
    const INetURLObject aURLObj(sTempFileURL);
    std::string sUrl = OUStringToOString( aURLObj.getFSysPath(INetURLObject::FSYS_DETECT), RTL_TEXTENCODING_UTF8 ).getStr();

    // Parse json, read externals' URI and modify this relative URI's so they remain valid in the new context.
    std::vector<std::string> vExternals;
    ptree aTree;
    try
    {
        json_parser::read_json( sUrl, aTree );

        // Buffers for geometry and animations
        BOOST_FOREACH(ptree::value_type &rVal,aTree.get_child("buffers"))
        {
            const std::string sBufferUri(rVal.second.get<std::string>("path"));
            vExternals.push_back(sBufferUri);
            // Change path: make it contain only a file name
            aTree.put("buffers." + rVal.first + ".path.",sBufferUri.substr(sBufferUri.find_last_of('/')+1));
        }
        // Images for textures
        boost::optional< ptree& > aImages = aTree.get_child_optional("images");
        if( aImages )
        {
            BOOST_FOREACH(ptree::value_type &rVal,aImages.get())
            {
                const std::string sImageUri(rVal.second.get<std::string>("path"));
                if( !sImageUri.empty() )
                {
                    vExternals.push_back(sImageUri);
                    // Change path: make it contain only a file name
                    aTree.put("images." + rVal.first + ".path.",sImageUri.substr(sImageUri.find_last_of('/')+1));
                }
            }
        }
        // Shaders (contains names only)
        BOOST_FOREACH(ptree::value_type &rVal,aTree.get_child("programs"))
        {
            vExternals.push_back(rVal.second.get<std::string>("fragmentShader") + ".glsl");
            vExternals.push_back(rVal.second.get<std::string>("vertexShader") + ".glsl");
        }

        // Write out modified json
        json_parser::write_json( sUrl, aTree );
    }
    catch ( boost::exception const& )
    {
        SAL_WARN("avmedia.opengl", "Exception while parsing *.json file");
        return;
    }

    // Reload json with modified path to external resources
    rContent = ::ucbhelper::Content(sTempFileURL,
        uno::Reference<ucb::XCommandEnvironment>(),
        comphelper::getProcessComponentContext());

    // Store all external files next to the json file
    for( std::vector<std::string>::iterator aCIter = vExternals.begin(); aCIter != vExternals.end(); ++aCIter )
    {
        const OUString sAbsURL = INetURLObject::GetAbsURL(rSourceURL,OUString::createFromAscii(aCIter->c_str()));

        ::ucbhelper::Content aContent(sAbsURL,
                uno::Reference<ucb::XCommandEnvironment>(),
                comphelper::getProcessComponentContext());

        uno::Reference<io::XStream> const xStream(
            CreateStream(xSubStorage, GetFilename(sAbsURL)), uno::UNO_SET_THROW);
        uno::Reference<io::XOutputStream> const xOutStream(
            xStream->getOutputStream(), uno::UNO_SET_THROW);

        if (!aContent.openStream(xOutStream))
        {
            SAL_WARN("avmedia.opengl", "openStream to storage failed");
            return;
        }
    }
}

bool Embed3DModel( const uno::Reference<frame::XModel>& xModel,
        const OUString& rSourceURL, OUString& o_rEmbeddedURL)
{
    OUString sSource = rSourceURL;
#ifdef ENABLE_COLLADA2GLTF
    const bool bIsDAE = rSourceURL.endsWithIgnoreAsciiCase(".dae");
    const bool bIsKMZ = rSourceURL.endsWithIgnoreAsciiCase(".kmz");
    if (bIsDAE || bIsKMZ)
    {
        OUString sName;
        ::utl::LocalFileHelper::ConvertPhysicalNameToURL(::utl::TempFile::CreateTempName(), sName);
        // remove .tmp extension
        sName = sName.copy(0, sName.getLength() - 4);
        const INetURLObject aSourceURLObj(rSourceURL);
        std::string sSourcePath = OUStringToOString( aSourceURLObj.getFSysPath(INetURLObject::FSYS_DETECT), RTL_TEXTENCODING_UTF8 ).getStr();

        std::shared_ptr <GLTF::GLTFAsset> asset(new GLTF::GLTFAsset());
        asset->setInputFilePath(sSourcePath);

        if (bIsKMZ)
        {
            std::string strDaeFilePath = GLTF::Kmz2Collada()(asset->getInputFilePath());
            if (strDaeFilePath == "")
                return false;
            asset->setInputFilePath(strDaeFilePath);
        }
        asset->setBundleOutputPath(OUStringToOString( sName, RTL_TEXTENCODING_UTF8 ).getStr());
        GLTF::COLLADA2GLTFWriter writer(asset);
        writer.write();
        // Path to the .json file created by COLLADA2GLTFWriter
        sSource = sName + "/" + GetFilename(sName) + ".json";
    }
#endif

    try
    {
        ::ucbhelper::Content aSourceContent(sSource,
                uno::Reference<ucb::XCommandEnvironment>(),
                comphelper::getProcessComponentContext());

        // Base storage
        uno::Reference<document::XStorageBasedDocument> const xSBD(xModel,
                uno::UNO_QUERY_THROW);
        uno::Reference<embed::XStorage> const xStorage(
                xSBD->getDocumentStorage(), uno::UNO_QUERY_THROW);

        // Model storage
        const OUString sModel("Model");
        uno::Reference<embed::XStorage> const xModelStorage(
            xStorage->openStorageElement(sModel, embed::ElementModes::WRITE));

        // Own storage of the corresponding model
        const OUString sFilename(GetFilename(sSource));
        const OUString sGLTFDir(sFilename.copy(0,sFilename.lastIndexOf('.')));
        uno::Reference<embed::XStorage> const xSubStorage(
            xModelStorage->openStorageElement(sGLTFDir, embed::ElementModes::WRITE));

        // Embed external resources
        lcl_EmbedExternals(sSource, xSubStorage, aSourceContent);

        // Save model file (.json)
        uno::Reference<io::XStream> const xStream(
            CreateStream(xSubStorage, sFilename), uno::UNO_SET_THROW);
        uno::Reference<io::XOutputStream> const xOutStream(
            xStream->getOutputStream(), uno::UNO_SET_THROW);

        if (!aSourceContent.openStream(xOutStream))
        {
            SAL_WARN("avmedia.opengl", "openStream to storage failed");
            return false;
        }

        const uno::Reference<embed::XTransactedObject> xSubTransaction(xSubStorage, uno::UNO_QUERY);
        if (xSubTransaction.is())
        {
            xSubTransaction->commit();
        }
        const uno::Reference<embed::XTransactedObject> xModelTransaction(xModelStorage, uno::UNO_QUERY);
        if (xModelTransaction.is())
        {
            xModelTransaction->commit();
        }
        const uno::Reference<embed::XTransactedObject> xTransaction(xStorage, uno::UNO_QUERY);
        if (xTransaction.is())
        {
            xTransaction->commit();
        }

        o_rEmbeddedURL = "vnd.sun.star.Package:" + sModel + "/" + sGLTFDir + "/" + sFilename;
        return true;
    }
    catch (uno::Exception const&)
    {
        SAL_WARN("avmedia.opengl", "Exception while trying to embed model");
    }
    return false;
}

bool IsModel(const OUString& rMimeType)
{
    return rMimeType == AVMEDIA_MIMETYPE_JSON;
}

} // namespace avemdia

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


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

#ifndef MSSQL_DATASOURCE_HPP
#define MSSQL_DATASOURCE_HPP

// mapnik
#include <mapnik/attribute.hpp>
#include <mapnik/box2d.hpp>
#include <mapnik/coord.hpp>
#include <mapnik/datasource.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/feature_layer_desc.hpp>
#include <mapnik/params.hpp>
#include <mapnik/query.hpp>
//#include <mapnik/unicode.hpp>
#include <mapnik/value_types.hpp>

// boost
#include <boost/optional.hpp>

// stl
#include <memory>
//#include <string>
//#include <vector>

#include "connection_manager.hpp"
//#include "cursorresultset.hpp"
//#include "resultset.hpp"

//using mapnik::transcoder;
using mapnik::datasource;
using mapnik::feature_style_context_map;
using mapnik::processor_context_ptr;
using mapnik::box2d;
using mapnik::layer_descriptor;
using mapnik::featureset_ptr;
using mapnik::feature_ptr;
using mapnik::query;
using mapnik::parameters;
using mapnik::coord2d;

using CnxPool_ptr = std::shared_ptr<ConnectionManager::PoolType>;

class mssql_datasource : public datasource
{
  public:
    mssql_datasource(const parameters& params);
    ~mssql_datasource();
    mapnik::datasource::datasource_t type() const;
    static const char* name();
    processor_context_ptr get_context(feature_style_context_map&) const;
    featureset_ptr features_with_context(query const& q, processor_context_ptr ctx) const;
    featureset_ptr features(query const& q) const;
    featureset_ptr features_at_point(coord2d const& pt, double tol = 0) const;
    mapnik::box2d<double> envelope() const;
    boost::optional<mapnik::datasource_geometry_t> get_geometry_type() const;
    layer_descriptor get_descriptor() const;

  private:
    std::string sql_bbox(box2d<double> const& env) const;
    std::string populate_tokens(std::string const& sql,
                                double scale_denom,
                                box2d<double> const& env,
                                double pixel_width,
                                double pixel_height,
                                mapnik::attributes const& vars) const;
    std::string populate_tokens(std::string const& sql) const;
    std::shared_ptr<IResultSet> get_resultset(std::shared_ptr<Connection>& conn, std::string const& sql, CnxPool_ptr const& pool, processor_context_ptr ctx = processor_context_ptr()) const;
    static const double FMAX;

    const std::string uri_;
    const std::string username_;
    const std::string password_;
    const std::string table_;
    std::string schema_;
    std::string geometry_table_;
    const std::string geometry_field_;
    std::string key_field_;
    bool wkb_;
    bool use_filter_;
    bool trace_flag_4199_;

    mapnik::value_integer row_limit_;
    std::string geometryColumn_;
    std::string geometryColumnType_;
    mapnik::datasource::datasource_t type_;
    int srid_;
    mutable bool extent_initialized_;
    mutable mapnik::box2d<double> extent_;
    bool simplify_geometries_;
    layer_descriptor desc_;
    ConnectionCreator<Connection> creator_;
    const std::string bbox_token_;
    const std::string scale_denom_token_;
    const std::string pixel_width_token_;
    const std::string pixel_height_token_;
    int pool_max_size_;
    bool persist_connection_;
    bool extent_from_subquery_;
    bool estimate_extent_;
    int max_async_connections_;
    bool asynchronous_request_;
    int intersect_min_scale_;
    int intersect_max_scale_;
    bool key_field_as_attribute_;
    std::string order_by_;
};

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

#ifndef MSSQL_DATASOURCE_HPP
#define MSSQL_DATASOURCE_HPP

// mapnik
#include <mapnik/attribute.hpp>
#include <mapnik/box2d.hpp>
#include <mapnik/coord.hpp>
#include <mapnik/datasource.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/feature_layer_desc.hpp>
#include <mapnik/params.hpp>
#include <mapnik/query.hpp>
#include <mapnik/unicode.hpp>
#include <mapnik/value_types.hpp>

// boost
#include <boost/optional.hpp>

// stl
#include <memory>
#include <string>
#include <vector>

#include "connection_manager.hpp"
//#include "cursorresultset.hpp"
//#include "resultset.hpp"

//using mapnik::transcoder;
using mapnik::datasource;
using mapnik::feature_style_context_map;
using mapnik::processor_context_ptr;
using mapnik::box2d;
using mapnik::layer_descriptor;
using mapnik::featureset_ptr;
using mapnik::feature_ptr;
using mapnik::query;
using mapnik::parameters;
using mapnik::coord2d;

using CnxPool_ptr = std::shared_ptr<ConnectionManager::PoolType>;

class mssql_datasource : public datasource
{
  public:
    mssql_datasource(const parameters& params);
    ~mssql_datasource();
    mapnik::datasource::datasource_t type() const;
    static const char* name();
    processor_context_ptr get_context(feature_style_context_map&) const;
    featureset_ptr features_with_context(query const& q, processor_context_ptr ctx) const;
    featureset_ptr features(query const& q) const;
    featureset_ptr features_at_point(coord2d const& pt, double tol = 0) const;
    mapnik::box2d<double> envelope() const;
    boost::optional<mapnik::datasource_geometry_t> get_geometry_type() const;
    layer_descriptor get_descriptor() const;

  private:
    std::string sql_bbox(box2d<double> const& env) const;
    std::string populate_tokens(std::string const& sql,
                                double scale_denom,
                                box2d<double> const& env,
                                double pixel_width,
                                double pixel_height,
                                mapnik::attributes const& vars) const;
    std::string populate_tokens(std::string const& sql) const;
    std::shared_ptr<IResultSet> get_resultset(std::shared_ptr<Connection>& conn, std::string const& sql, CnxPool_ptr const& pool, processor_context_ptr ctx = processor_context_ptr()) const;
    static const double FMAX;

    const std::string uri_;
    const std::string username_;
    const std::string password_;
    const std::string table_;
    std::string schema_;
    std::string geometry_table_;
    const std::string geometry_field_;
    std::string key_field_;
    bool wkb_;
    bool use_filter_;
    bool trace_flag_4199_;

    mapnik::value_integer row_limit_;
    std::string geometryColumn_;
    std::string geometryColumnType_;
    mapnik::datasource::datasource_t type_;
    int srid_;
    mutable bool extent_initialized_;
    mutable mapnik::box2d<double> extent_;
    bool simplify_geometries_;
    layer_descriptor desc_;
    ConnectionCreator<Connection> creator_;
    const std::string bbox_token_;
    const std::string scale_denom_token_;
    const std::string pixel_width_token_;
    const std::string pixel_height_token_;
    int pool_max_size_;
    bool persist_connection_;
    bool extent_from_subquery_;
    bool estimate_extent_;
    int max_async_connections_;
    bool asynchronous_request_;
    int intersect_min_scale_;
    int intersect_max_scale_;
    bool key_field_as_attribute_;
    std::string order_by_;
};

#endif // MSSQL_DATASOURCE_HPP
<|endoftext|>


<commit_before>/*
    Class that auto configures link-local xmpp account
    Copyright (C) 2011  Martin Klapetek <martin.klapetek@gmail.com>

    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
*/

#include "salut-enabler.h"

#include <TelepathyQt/ConnectionManager>
#include <TelepathyQt/ProfileManager>
#include <TelepathyQt/AccountManager>
#include <TelepathyQt/PendingOperation>
#include <TelepathyQt/PendingReady>
#include <TelepathyQt/PendingAccount>

#include <KDebug>
#include <KUser>
#include <KLocalizedString>

#include <QtGui/QFrame>

#include "salut-details-dialog.h"
#include "salut-message-widget.h"

#define TP_PROP_ACCOUNT_ENABLED (QLatin1String("org.freedesktop.Telepathy.Account.Enabled"))
#define TP_PROP_ACCOUNT_SERVICE (QLatin1String("org.freedesktop.Telepathy.Account.Service"))

const QLatin1String salutConnManager("salut");
const QLatin1String localXmppProtocol("local-xmpp");
const QLatin1String firstNamePar("first-name");
const QLatin1String lastNamePar("last-name");
const QLatin1String nickNamePar("nickname");

class SalutEnabler::Private
{
public:
    Private(SalutEnabler* parent)
        : q(parent),
          detailsDialog(0),
          messageWidget(0)
    {
    }

    SalutEnabler *q;

    Tp::ConnectionManagerPtr connectionManager;
    Tp::ProfileManagerPtr profileManager;
    Tp::AccountManagerPtr accountManager;
    Tp::ProfilePtr profile;
    QVariantMap values;
    SalutDetailsDialog *detailsDialog;
    SalutMessageWidget *messageWidget;
    QWeakPointer<QFrame> salutMessageFrame;
};

SalutEnabler::SalutEnabler(const Tp::AccountManagerPtr accountManager, QObject *parent)
    : QObject(parent),
      d(new Private(this))
{
    d->accountManager = accountManager;

    d->connectionManager = Tp::ConnectionManager::create(salutConnManager);
    connect(d->connectionManager->becomeReady(),
            SIGNAL(finished(Tp::PendingOperation*)),
            SLOT(onConnectionManagerReady(Tp::PendingOperation*)));
}

SalutEnabler::~SalutEnabler()
{
    delete d;
}

void SalutEnabler::onConnectionManagerReady(Tp::PendingOperation* op)
{
    if (op->isError()) {
        kWarning() << "Creating ConnectionManager failed:" << op->errorName() << op->errorMessage();
    }

    if (!d->connectionManager->isValid()) {
        kWarning() << "Invalid ConnectionManager";
    }

    d->profileManager = Tp::ProfileManager::create(QDBusConnection::sessionBus());

    // FIXME: Until all distros ship correct profile files, we should fake them
    connect(d->profileManager->becomeReady(Tp::Features() << Tp::ProfileManager::FeatureFakeProfiles),
            SIGNAL(finished(Tp::PendingOperation*)),
            SLOT(onProfileManagerReady(Tp::PendingOperation*)));
}

void SalutEnabler::onProfileManagerReady(Tp::PendingOperation* op)
{
    if (op->isError()) {
        kWarning() << "Creating ProfileManager failed:" << op->errorName() << op->errorMessage();
    }

    // Get the protocol's parameters and values.
    Tp::ProtocolInfo protocolInfo = d->connectionManager->protocol(localXmppProtocol);
    Tp::ProtocolParameterList parameters = protocolInfo.parameters();

    d->profile = d->profileManager->profilesForCM(salutConnManager).first();

    Q_ASSERT(!d->profile.isNull());
    Q_ASSERT(d->profile->isValid());
    Q_ASSERT(d->profile->protocolName() == localXmppProtocol);
    if (d->profile.isNull() || !d->profile->isValid() || d->profile->protocolName() != localXmppProtocol) {
        kWarning() << "Something went wrong with telepathy salut";
    }

    KUser user = KUser();
    QString name = user.property(KUser::FullName).toString();
    QString nick = user.loginName();
    int lastSpacePosition = name.lastIndexOf(QLatin1Char(' '));
    QString lastname = name.mid(lastSpacePosition + 1);
    QString firstName = name.left(lastSpacePosition);

    d->values.insert(firstNamePar, firstName);
    d->values.insert(lastNamePar, lastname);
    d->values.insert(nickNamePar, nick);

    Q_EMIT userInfoReady();
}

QFrame* SalutEnabler::frameWidget(QWidget* parent)
{
    if (d->salutMessageFrame.isNull()) {
        d->salutMessageFrame = new QFrame(parent);
    }
    d->salutMessageFrame.data()->setMinimumWidth(parent->width());
    d->salutMessageFrame.data()->setFrameShape(QFrame::StyledPanel);

    d->messageWidget = new SalutMessageWidget(d->salutMessageFrame.data());
    d->messageWidget->setParams(d->values[firstNamePar].toString(),
                                d->values[lastNamePar].toString(),
                                d->values[nickNamePar].toString());
    d->messageWidget->hide();

    QPropertyAnimation *animation = new QPropertyAnimation(d->salutMessageFrame.data(), "minimumHeight", d->messageWidget);
    animation->setDuration(150);
    animation->setStartValue(0);
    animation->setEndValue(d->messageWidget->sizeHint().height());
    animation->start();

    connect(animation, SIGNAL(finished()),
            d->messageWidget, SLOT(animatedShow()));

    connect(d->messageWidget, SIGNAL(timeout()),
            this, SLOT(onUserAccepted()));

    connect(d->messageWidget, SIGNAL(configPressed()),
            this, SLOT(onUserWantingChanges()));

    connect(d->messageWidget, SIGNAL(cancelPressed()),
            this, SLOT(onUserCancelled()));

    return d->salutMessageFrame.data();
}

void SalutEnabler::onUserAccepted()
{
    // FIXME: In some next version of tp-qt4 there should be a convenience class for this
    // https://bugs.freedesktop.org/show_bug.cgi?id=33153
    QVariantMap properties;

    if (d->accountManager->supportedAccountProperties().contains(TP_PROP_ACCOUNT_SERVICE)) {
        properties.insert(TP_PROP_ACCOUNT_SERVICE, d->profile->serviceName());
    }
    if (d->accountManager->supportedAccountProperties().contains(TP_PROP_ACCOUNT_ENABLED)) {
        properties.insert(TP_PROP_ACCOUNT_ENABLED, true);
    }

    // FIXME: Ask the user to submit a Display Name

    QString displayName;

    QString lastname = d->values[lastNamePar].toString();
    QString firstname = d->values[firstNamePar].toString();
    QString nick = d->values[nickNamePar].toString();

    //either one of the names is filled and nick is filled
    if (((lastname.isEmpty() && !firstname.isEmpty()) || (!lastname.isEmpty() && firstname.isEmpty()))
            && !nick.isEmpty()) {

        displayName = QString::fromLatin1("%1 (%2)").arg(d->values[firstNamePar].toString().isEmpty() ?
                d->values[lastNamePar].toString() : d->values[firstNamePar].toString(),
                                                            d->values[nickNamePar].toString());

    //either one of the names is filled and nick is empty
    } else if (((lastname.isEmpty() && !firstname.isEmpty()) || (!lastname.isEmpty() && firstname.isEmpty()))
            && nick.isEmpty()) {

        displayName = d->values[firstNamePar].toString().isEmpty() ?
                d->values[lastNamePar].toString() : d->values[firstNamePar].toString();

    //both first & last names are empty but nick is not
    } else if (lastname.isEmpty() && firstname.isEmpty() && !nick.isEmpty()) {

        displayName = d->values[nickNamePar].toString();

    } else if (lastname.isEmpty() && firstname.isEmpty() && nick.isEmpty()) {
        //FIXME: let the user know that he reached a very strange situation

    } else {
        displayName = QString::fromLatin1("%1 %2 (%3)").arg(d->values[firstNamePar].toString(),
                                                               d->values[lastNamePar].toString(),
                                                               d->values[nickNamePar].toString());
    }

    Tp::PendingAccount *pa = d->accountManager->createAccount(d->profile->cmName(),
                                                              d->profile->protocolName(),
                                                              displayName,
                                                              d->values,
                                                              properties);

    connect(pa,
            SIGNAL(finished(Tp::PendingOperation*)),
            SLOT(onAccountCreated(Tp::PendingOperation*)));
}

void SalutEnabler::onAccountCreated(Tp::PendingOperation* op)
{
    kDebug() << "Account created";
    if (op->isError()) {
        kWarning() << "Creating Account failed:" << op->errorName() << op->errorMessage();
    }

    if (op->isError()) {
        Q_EMIT feedbackMessage(i18n("Failed to create account"),
                               i18n("Possibly not all required fields are valid"),
                               KMessageWidget::Error);
        kWarning() << "Adding Account failed:" << op->errorName() << op->errorMessage();
        return;
    }

    // Get the PendingAccount.
    Tp::PendingAccount *pendingAccount = qobject_cast<Tp::PendingAccount*>(op);
    if (!pendingAccount) {
                Q_EMIT feedbackMessage(i18n("Something went wrong with Telepathy"),
                                       QString(),
                                       KMessageWidget::Error);
        kWarning() << "Method called with wrong type.";
        return;
    }

    pendingAccount->account()->setRequestedPresence(Tp::Presence::available());
    pendingAccount->account()->setServiceName(d->profile->serviceName());

    d->salutMessageFrame.data()->deleteLater();;

    Q_EMIT done();
}

void SalutEnabler::onUserWantingChanges()
{
    d->detailsDialog = new SalutDetailsDialog(d->profileManager, d->connectionManager, 0);

    connect(d->detailsDialog, SIGNAL(dialogAccepted(QVariantMap)),
            this, SLOT(onDialogAccepted(QVariantMap)));

    connect(d->detailsDialog, SIGNAL(rejected()),
            this, SLOT(onUserCancelled()));

    connect(d->detailsDialog, SIGNAL(rejected()),
            this, SIGNAL(cancelled()));

    connect(d->detailsDialog, SIGNAL(feedbackMessage(QString,QString,KMessageWidget::MessageType)),
            this, SIGNAL(feedbackMessage(QString,QString,KMessageWidget::MessageType)));

    d->detailsDialog->exec();
}

void SalutEnabler::onDialogAccepted(const QVariantMap &values)
{
    kDebug() << values;
    d->values.insert(firstNamePar, values[firstNamePar].toString());
    d->values.insert(lastNamePar, values[lastNamePar].toString());
    d->values.insert(nickNamePar, values[nickNamePar].toString());

    onUserAccepted();
}

void SalutEnabler::onUserCancelled()
{
    d->messageWidget->animatedHide();

    QPropertyAnimation *animation = new QPropertyAnimation(d->salutMessageFrame.data(), "maximumHeight", d->messageWidget);
    animation->setDuration(150);
    animation->setStartValue(d->messageWidget->sizeHint().height());
    animation->setEndValue(0);

    QTimer::singleShot(300, animation, SLOT(start()));

    connect(animation, SIGNAL(finished()),
            d->salutMessageFrame.data(), SLOT(deleteLater()));

    connect(animation, SIGNAL(finished()),
            this, SIGNAL(cancelled()));
}
<commit_msg>No need to emit cancelled twice<commit_after>/*
    Class that auto configures link-local xmpp account
    Copyright (C) 2011  Martin Klapetek <martin.klapetek@gmail.com>

    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
*/

#include "salut-enabler.h"

#include <TelepathyQt/ConnectionManager>
#include <TelepathyQt/ProfileManager>
#include <TelepathyQt/AccountManager>
#include <TelepathyQt/PendingOperation>
#include <TelepathyQt/PendingReady>
#include <TelepathyQt/PendingAccount>

#include <KDebug>
#include <KUser>
#include <KLocalizedString>

#include <QtGui/QFrame>

#include "salut-details-dialog.h"
#include "salut-message-widget.h"

#define TP_PROP_ACCOUNT_ENABLED (QLatin1String("org.freedesktop.Telepathy.Account.Enabled"))
#define TP_PROP_ACCOUNT_SERVICE (QLatin1String("org.freedesktop.Telepathy.Account.Service"))

const QLatin1String salutConnManager("salut");
const QLatin1String localXmppProtocol("local-xmpp");
const QLatin1String firstNamePar("first-name");
const QLatin1String lastNamePar("last-name");
const QLatin1String nickNamePar("nickname");

class SalutEnabler::Private
{
public:
    Private(SalutEnabler* parent)
        : q(parent),
          detailsDialog(0),
          messageWidget(0)
    {
    }

    SalutEnabler *q;

    Tp::ConnectionManagerPtr connectionManager;
    Tp::ProfileManagerPtr profileManager;
    Tp::AccountManagerPtr accountManager;
    Tp::ProfilePtr profile;
    QVariantMap values;
    SalutDetailsDialog *detailsDialog;
    SalutMessageWidget *messageWidget;
    QWeakPointer<QFrame> salutMessageFrame;
};

SalutEnabler::SalutEnabler(const Tp::AccountManagerPtr accountManager, QObject *parent)
    : QObject(parent),
      d(new Private(this))
{
    d->accountManager = accountManager;

    d->connectionManager = Tp::ConnectionManager::create(salutConnManager);
    connect(d->connectionManager->becomeReady(),
            SIGNAL(finished(Tp::PendingOperation*)),
            SLOT(onConnectionManagerReady(Tp::PendingOperation*)));
}

SalutEnabler::~SalutEnabler()
{
    delete d;
}

void SalutEnabler::onConnectionManagerReady(Tp::PendingOperation* op)
{
    if (op->isError()) {
        kWarning() << "Creating ConnectionManager failed:" << op->errorName() << op->errorMessage();
    }

    if (!d->connectionManager->isValid()) {
        kWarning() << "Invalid ConnectionManager";
    }

    d->profileManager = Tp::ProfileManager::create(QDBusConnection::sessionBus());

    // FIXME: Until all distros ship correct profile files, we should fake them
    connect(d->profileManager->becomeReady(Tp::Features() << Tp::ProfileManager::FeatureFakeProfiles),
            SIGNAL(finished(Tp::PendingOperation*)),
            SLOT(onProfileManagerReady(Tp::PendingOperation*)));
}

void SalutEnabler::onProfileManagerReady(Tp::PendingOperation* op)
{
    if (op->isError()) {
        kWarning() << "Creating ProfileManager failed:" << op->errorName() << op->errorMessage();
    }

    // Get the protocol's parameters and values.
    Tp::ProtocolInfo protocolInfo = d->connectionManager->protocol(localXmppProtocol);
    Tp::ProtocolParameterList parameters = protocolInfo.parameters();

    d->profile = d->profileManager->profilesForCM(salutConnManager).first();

    Q_ASSERT(!d->profile.isNull());
    Q_ASSERT(d->profile->isValid());
    Q_ASSERT(d->profile->protocolName() == localXmppProtocol);
    if (d->profile.isNull() || !d->profile->isValid() || d->profile->protocolName() != localXmppProtocol) {
        kWarning() << "Something went wrong with telepathy salut";
    }

    KUser user = KUser();
    QString name = user.property(KUser::FullName).toString();
    QString nick = user.loginName();
    int lastSpacePosition = name.lastIndexOf(QLatin1Char(' '));
    QString lastname = name.mid(lastSpacePosition + 1);
    QString firstName = name.left(lastSpacePosition);

    d->values.insert(firstNamePar, firstName);
    d->values.insert(lastNamePar, lastname);
    d->values.insert(nickNamePar, nick);

    Q_EMIT userInfoReady();
}

QFrame* SalutEnabler::frameWidget(QWidget* parent)
{
    if (d->salutMessageFrame.isNull()) {
        d->salutMessageFrame = new QFrame(parent);
    }
    d->salutMessageFrame.data()->setMinimumWidth(parent->width());
    d->salutMessageFrame.data()->setFrameShape(QFrame::StyledPanel);

    d->messageWidget = new SalutMessageWidget(d->salutMessageFrame.data());
    d->messageWidget->setParams(d->values[firstNamePar].toString(),
                                d->values[lastNamePar].toString(),
                                d->values[nickNamePar].toString());
    d->messageWidget->hide();

    QPropertyAnimation *animation = new QPropertyAnimation(d->salutMessageFrame.data(), "minimumHeight", d->messageWidget);
    animation->setDuration(150);
    animation->setStartValue(0);
    animation->setEndValue(d->messageWidget->sizeHint().height());
    animation->start();

    connect(animation, SIGNAL(finished()),
            d->messageWidget, SLOT(animatedShow()));

    connect(d->messageWidget, SIGNAL(timeout()),
            this, SLOT(onUserAccepted()));

    connect(d->messageWidget, SIGNAL(configPressed()),
            this, SLOT(onUserWantingChanges()));

    connect(d->messageWidget, SIGNAL(cancelPressed()),
            this, SLOT(onUserCancelled()));

    return d->salutMessageFrame.data();
}

void SalutEnabler::onUserAccepted()
{
    // FIXME: In some next version of tp-qt4 there should be a convenience class for this
    // https://bugs.freedesktop.org/show_bug.cgi?id=33153
    QVariantMap properties;

    if (d->accountManager->supportedAccountProperties().contains(TP_PROP_ACCOUNT_SERVICE)) {
        properties.insert(TP_PROP_ACCOUNT_SERVICE, d->profile->serviceName());
    }
    if (d->accountManager->supportedAccountProperties().contains(TP_PROP_ACCOUNT_ENABLED)) {
        properties.insert(TP_PROP_ACCOUNT_ENABLED, true);
    }

    // FIXME: Ask the user to submit a Display Name

    QString displayName;

    QString lastname = d->values[lastNamePar].toString();
    QString firstname = d->values[firstNamePar].toString();
    QString nick = d->values[nickNamePar].toString();

    //either one of the names is filled and nick is filled
    if (((lastname.isEmpty() && !firstname.isEmpty()) || (!lastname.isEmpty() && firstname.isEmpty()))
            && !nick.isEmpty()) {

        displayName = QString::fromLatin1("%1 (%2)").arg(d->values[firstNamePar].toString().isEmpty() ?
                d->values[lastNamePar].toString() : d->values[firstNamePar].toString(),
                                                            d->values[nickNamePar].toString());

    //either one of the names is filled and nick is empty
    } else if (((lastname.isEmpty() && !firstname.isEmpty()) || (!lastname.isEmpty() && firstname.isEmpty()))
            && nick.isEmpty()) {

        displayName = d->values[firstNamePar].toString().isEmpty() ?
                d->values[lastNamePar].toString() : d->values[firstNamePar].toString();

    //both first & last names are empty but nick is not
    } else if (lastname.isEmpty() && firstname.isEmpty() && !nick.isEmpty()) {

        displayName = d->values[nickNamePar].toString();

    } else if (lastname.isEmpty() && firstname.isEmpty() && nick.isEmpty()) {
        //FIXME: let the user know that he reached a very strange situation

    } else {
        displayName = QString::fromLatin1("%1 %2 (%3)").arg(d->values[firstNamePar].toString(),
                                                               d->values[lastNamePar].toString(),
                                                               d->values[nickNamePar].toString());
    }

    Tp::PendingAccount *pa = d->accountManager->createAccount(d->profile->cmName(),
                                                              d->profile->protocolName(),
                                                              displayName,
                                                              d->values,
                                                              properties);

    connect(pa,
            SIGNAL(finished(Tp::PendingOperation*)),
            SLOT(onAccountCreated(Tp::PendingOperation*)));
}

void SalutEnabler::onAccountCreated(Tp::PendingOperation* op)
{
    kDebug() << "Account created";
    if (op->isError()) {
        kWarning() << "Creating Account failed:" << op->errorName() << op->errorMessage();
    }

    if (op->isError()) {
        Q_EMIT feedbackMessage(i18n("Failed to create account"),
                               i18n("Possibly not all required fields are valid"),
                               KMessageWidget::Error);
        kWarning() << "Adding Account failed:" << op->errorName() << op->errorMessage();
        return;
    }

    // Get the PendingAccount.
    Tp::PendingAccount *pendingAccount = qobject_cast<Tp::PendingAccount*>(op);
    if (!pendingAccount) {
                Q_EMIT feedbackMessage(i18n("Something went wrong with Telepathy"),
                                       QString(),
                                       KMessageWidget::Error);
        kWarning() << "Method called with wrong type.";
        return;
    }

    pendingAccount->account()->setRequestedPresence(Tp::Presence::available());
    pendingAccount->account()->setServiceName(d->profile->serviceName());

    d->salutMessageFrame.data()->deleteLater();;

    Q_EMIT done();
}

void SalutEnabler::onUserWantingChanges()
{
    d->detailsDialog = new SalutDetailsDialog(d->profileManager, d->connectionManager, 0);

    connect(d->detailsDialog, SIGNAL(dialogAccepted(QVariantMap)),
            this, SLOT(onDialogAccepted(QVariantMap)));

    connect(d->detailsDialog, SIGNAL(rejected()),
            this, SLOT(onUserCancelled()));

    connect(d->detailsDialog, SIGNAL(feedbackMessage(QString,QString,KMessageWidget::MessageType)),
            this, SIGNAL(feedbackMessage(QString,QString,KMessageWidget::MessageType)));

    d->detailsDialog->exec();
}

void SalutEnabler::onDialogAccepted(const QVariantMap &values)
{
    kDebug() << values;
    d->values.insert(firstNamePar, values[firstNamePar].toString());
    d->values.insert(lastNamePar, values[lastNamePar].toString());
    d->values.insert(nickNamePar, values[nickNamePar].toString());

    onUserAccepted();
}

void SalutEnabler::onUserCancelled()
{
    d->messageWidget->animatedHide();

    QPropertyAnimation *animation = new QPropertyAnimation(d->salutMessageFrame.data(), "maximumHeight", d->messageWidget);
    animation->setDuration(150);
    animation->setStartValue(d->messageWidget->sizeHint().height());
    animation->setEndValue(0);

    QTimer::singleShot(300, animation, SLOT(start()));

    connect(animation, SIGNAL(finished()),
            d->salutMessageFrame.data(), SLOT(deleteLater()));

    connect(animation, SIGNAL(finished()),
            this, SIGNAL(cancelled()));
}
<|endoftext|>


<commit_before>#include "MIDICompositor.hpp"
#include "../JuceLibraryCode/JuceHeader.h"

void MIDICompositor::send(){
  Compositor::send();
}

MIDICompositor::~MIDICompositor(){}

void MIDICompositor::send(osc::OutboundPacketStream oscMsg){
  Compositor::send(oscMsg);
}

osc::OutboundPacketStream MIDICompositor::compose(EASEAClientData* cl){
  char buffer[OUTPUT_BUFFER_SIZE];
  osc::OutboundPacketStream p( buffer, OUTPUT_BUFFER_SIZE );

  int freq = cl->getBestVector()->back();
  freq=rescaling(freq);
    p << osc::BeginBundleImmediate
        << osc::BeginMessage( "/note" )
          <<  cl->computeNote()
          << cl->getID()
          << osc::EndMessage
        << osc::EndBundle;

  return p;
}

void MIDICompositor::notify(EASEAClientData* cl){
  Compositor::notify(cl);
}

MIDICompositor::MIDICompositor(std::string ip,int port,bool dbg):Compositor::Compositor(ip,port,dbg){
  juce::StringArray deviceName=juce::MidiOutput::getDevices();
  int i;
  std::cout<<"MIDI devices"<<std::endl;
  for (i = 0; i < deviceName.size(); i++) {
    std::cout<<i<<"\t"<<deviceName[i]<<std::endl;
  }
  float vel=0.5;
  juce::MidiOutput* fluidsynth=juce::MidiOutput::openDevice(1);
  juce::MidiMessage laR=juce::MidiMessage::noteOn(1,60,vel);
  juce::MidiMessage laL=juce::MidiMessage::noteOn(2,40,vel);
  //fluidsynth->sendMessageNow(laR);
  //fluidsynth->sendMessageNow(laL);
  //sleep(5);
  //la=juce::MidiMessage::noteOff(0,60,(uint8)60);
  juce::MidiFile* midiToParse;
  juce::FileInputStream* midiInputStream;
  const juce::MidiMessageSequence* curTrack;
  juce::File* midiFile;
  int nbTrack;
  //int i;
  fluidsynth->startBackgroundThread();

  midiFile=new File("/home/pallamidessi/Ligeti/Test_and_demo/midi/gym3_1.mid");
  if(!midiFile->existsAsFile()){
    perror("File does not exist");
    return;
  }

  midiInputStream= new FileInputStream(*midiFile);
  midiToParse=new MidiFile();

  if(!midiToParse->readFrom(*midiInputStream)){
    perror("Can't read stream");
    return;
  }
  midiToParse->convertTimestampTicksToSeconds();
  curTrack=midiToParse->getTrack(1);
  int nbEvent=curTrack->getNumEvents();
  juce::MidiMessageSequence::MidiEventHolder* curEvent;
  juce::MidiBuffer chord;
  double curTimestamp=curTrack->getStartTime();
  int num;
  chord.addEvent(laR,1);
  chord.addEvent(laL,1);
  fluidsynth->sendBlockOfMessages(chord,1,10000);
  /*
  for (i = 0; i < nbEvent;) {
    num=0;
    while(curTrack->getEventTime(i)==curTimestamp){
      chord.addEvent(curTrack->getEventPointer(i)->message,num);
      num++;
      i++;
    }
    fluidsynth->sendBlockOfMessages(chord,curTimestamp+10,10);
    std::cout<<"message block sent :"<< curTimestamp<<" with "<<chord.getNumEvents()<<" event(s) "<<std::endl;
    chord.clear();
    curTimestamp=curTrack->getEventTime(i);
  }
  */
}

void MIDICompositor::aSending(EASEAClientData* cl){
  Compositor::aSending(cl);
}

void MIDICompositor::aReception(EASEAClientData* cl){
  Compositor::aReception(cl);
}
<commit_msg>MIDI playback with FluidSynth finished Add implementation comments and clean code. Note: only working when building in Release mode because of JUCE agressive assert (30 sec max delay with MidiOutput::sendBlockOfMessages )<commit_after>#include "MIDICompositor.hpp"
#include "../JuceLibraryCode/JuceHeader.h"

void MIDICompositor::send(){
  Compositor::send();
}

MIDICompositor::~MIDICompositor(){}

void MIDICompositor::send(osc::OutboundPacketStream oscMsg){
  Compositor::send(oscMsg);
}

osc::OutboundPacketStream MIDICompositor::compose(EASEAClientData* cl){
  char buffer[OUTPUT_BUFFER_SIZE];
  osc::OutboundPacketStream p( buffer, OUTPUT_BUFFER_SIZE );

  int freq = cl->getBestVector()->back();
  freq=rescaling(freq);
    p << osc::BeginBundleImmediate
        << osc::BeginMessage( "/note" )
          <<  cl->computeNote()
          << cl->getID()
          << osc::EndMessage
        << osc::EndBundle;

  return p;
}

void MIDICompositor::notify(EASEAClientData* cl){
  Compositor::notify(cl);
}

MIDICompositor::MIDICompositor(std::string ip,int port,bool dbg):Compositor::Compositor(ip,port,dbg){
  juce::StringArray deviceName;
  juce::MidiFile* midiToParse;
  juce::FileInputStream* midiInputStream;
  juce::MidiOutput* fluidsynth;
  juce::MidiMessageSequence::MidiEventHolder* curEvent;
  juce::MidiBuffer chord;
  const juce::MidiMessageSequence* curTrack;
  juce::File* midiFile;
  int nbTrack;
  int nbEvent;
  int num;
  int i;
  double curTimestamp;
  double refTime;

  deviceName=juce::MidiOutput::getDevices();
  std::cout<<"Available MIDI devices:"<<std::endl;

  /* Print found device */
  for (i = 0; i < deviceName.size(); i++) {
    std::cout<<i<<"\t"<<deviceName[i]<<std::endl;
  }
  fluidsynth=juce::MidiOutput::openDevice(1);
  fluidsynth->startBackgroundThread();

  /* Open and Read midiFile */
  midiFile=new File("/home/pallamidessi/Ligeti/Test_and_demo/midi/gym3_1.mid");

  if(!midiFile->existsAsFile()){
    perror("File does not exist");
    return;
  }

  midiInputStream= new FileInputStream(*midiFile);
  midiToParse=new MidiFile();

  if(!midiToParse->readFrom(*midiInputStream)){
    perror("Can't read stream");
    return;
  }

  /*TODO: multi-track (drifting !!!) playback */
  /*Retrieve track(s) and info*/
  midiToParse->convertTimestampTicksToSeconds();
  curTrack=midiToParse->getTrack(1);
  nbEvent=curTrack->getNumEvents();
  curTimestamp=curTrack->getStartTime();

  /* Start time */
  refTime=Time::getMillisecondCounter();

  /* Loop on all events, add them on MidiBuffers if they're "chords"
   * and send the MidiBuffers with delay
   * */
  for (i = 0; i < nbEvent;) {
    num=0;

    /* Check if events form a "Chord" */
    while(curTrack->getEventTime(i)==curTimestamp){
      chord.addEvent(curTrack->getEventPointer(i)->message,num);
      num++;
      i++;
    }

    fluidsynth->sendBlockOfMessages(chord,refTime+curTimestamp*1000,100000);

    if(debug){
      std::cout<<"message block sent :"<< curTimestamp<<" with "
               <<chord.getNumEvents()<<" event(s) "<<std::endl;
    }

    chord.clear();
    curTimestamp=curTrack->getEventTime(i);
  }
}

void MIDICompositor::aSending(EASEAClientData* cl){
  Compositor::aSending(cl);
}

void MIDICompositor::aReception(EASEAClientData* cl){
  Compositor::aReception(cl);
}
<|endoftext|>


<commit_before>#include "../bench_tmpl.h"
#include "leveldb/db.h"
#include "leveldb/write_batch.h"

using namespace leveldb;

void
run_bench()
{
	Bench b((boost::format("leveldb_bench %1%") % comment).str());
	{
		DB* db;
		Options opts;
		opts.create_if_missing = true;
		WriteOptions wopt;
		if(do_sync) wopt.sync = true;

		Status status = DB::Open(opts, dbfile, &db);
		if(! status.ok())
		{
			fprintf(stderr, "error opening db file\n");
			std::cerr << status.ToString() << std::endl;
		}
		b.cp("db init");

		int ik = 0;
		if(NUM_PREW > 0)
		{
			for(int i = 0; i < NUM_PREW; ++ i)
			{
				int k = keys[ik++];

				char buf[9]; sprintf(buf, "%08u", k);
				db->Put(wopt, Slice(buf, 8), Slice((const char*)&k, sizeof(k)));
			}

			// don't include preloading time
			fprintf(stderr, "prewrite %d keys done\n", ik);
			b.start(); b.cp("db init");
		}

		for(int itx = 0; itx < NUM_TX; ++ itx)
		{
			WriteBatch b;

			for(int iw = 0; iw < NUM_W_PER_TX; ++ iw)
			{
				int k = keys[ik++];

				char buf[9];
				sprintf(buf, "%08u", k);

				b.Put(Slice(buf, 8), Slice((char*)&k, sizeof(k)));
			}

#if 0
			for(int ir = 0; ir < NUM_R_PER_TX; ++ ir)
			{
				int k = keys[rand() % ik];
				char buf[9];
				sprintf(buf, "%08u", k);

				char v[9];

				// .get(buf, 8, v, 9);
			}
#endif

			db->Write(wopt, &b);
		}
		b.cp("tx done");

		if(NUM_W_PER_TX == 0)
		{
			// avoid measuring clean up time
			b.end();b.dump();
			exit(0);
		}
		sync();

		delete db;
	}
	b.end();
	b.dump();
#if 0
	Buffer v(32);
	char bufCorrect[9]; bufCorrect[9] = '\0';
	for(int i = 0; i < NUM_KEYS; ++ i)
	{
		sprintf(bufCorrect, "%08u", i);

		db.get(i, v);
		ASSERT_TRUE(v.isValid());
		EXPECT_EQ(::strlen(bufCorrect)+1, v.valsize()) << "incorrect val length for " << i;
		EXPECT_STREQ(bufCorrect, v.get()) << "incorrect val str for " << i;
	}
#endif
}
<commit_msg>lvldb bench upd<commit_after>#include "../bench_tmpl.h"
#include "leveldb/db.h"
#include "leveldb/write_batch.h"

using namespace leveldb;

void
run_bench()
{
	Bench b((boost::format("leveldb_bench %1%") % comment).str());
	{
		DB* db;
		Options opts;
		opts.create_if_missing = true;
		WriteOptions wopt;
		if(do_sync) wopt.sync = true;

		Status status = DB::Open(opts, dbfile, &db);
		if(! status.ok())
		{
			fprintf(stderr, "error opening db file\n");
			std::cerr << status.ToString() << std::endl;
		}
		b.cp("db init");

		int ik = 0;
		if(NUM_PREW > 0)
		{
			for(int i = 0; i < NUM_PREW; ++ i)
			{
				int k = keys[ik++];

				char buf[9]; sprintf(buf, "%08u", k);
				db->Put(wopt, Slice(buf, 8), Slice((const char*)&k, sizeof(k)));
			}

			// don't include preloading time
			fprintf(stderr, "prewrite %d keys done\n", ik);
			b.start(); b.cp("db init");
		}

		for(int itx = 0; itx < NUM_TX; ++ itx)
		{
			WriteBatch b;

			for(int iw = 0; iw < NUM_W_PER_TX; ++ iw)
			{
				int k = keys[ik++];

				char buf[9];
				sprintf(buf, "%08u", k);

				b.Put(Slice(buf, 8), Slice((char*)&k, sizeof(k)));
			}

			for(int ir = 0; ir < NUM_R_PER_TX; ++ ir)
			{
				leveldb::ReadOptions options;
				options.snapshot = db->GetSnapshot();

				int k = keys[rand() % ik];
				char buf[9];
				sprintf(buf, "%08u", k);

				std::string value;
				db->Get(options, Slice(buf, 8), &value);

				db->ReleaseSnapshot(options.snapshot);
			}

			db->Write(wopt, &b);
		}
		b.cp("tx done");

		if(NUM_W_PER_TX == 0)
		{
			// avoid measuring clean up time
			b.end();b.dump();
			exit(0);
		}
		sync();

		delete db;
	}
	b.end();
	b.dump();
#if 0
	Buffer v(32);
	char bufCorrect[9]; bufCorrect[9] = '\0';
	for(int i = 0; i < NUM_KEYS; ++ i)
	{
		sprintf(bufCorrect, "%08u", i);

		db.get(i, v);
		ASSERT_TRUE(v.isValid());
		EXPECT_EQ(::strlen(bufCorrect)+1, v.valsize()) << "incorrect val length for " << i;
		EXPECT_STREQ(bufCorrect, v.get()) << "incorrect val str for " << i;
	}
#endif
}
<|endoftext|>


<commit_before>#ifndef VEXCL_BACKEND_CUDA_COMPILER_HPP
#define VEXCL_BACKEND_CUDA_COMPILER_HPP

/*
The MIT License

Copyright (c) 2012-2016 Denis Demidov <dennis.demidov@gmail.com>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

/**
 * \file   vexcl/backend/cuda/compiler.hpp
 * \author Denis Demidov <dennis.demidov@gmail.com>
 * \brief  CUDA source code compilation wrapper.
 */

#include <cstdlib>
#include <cuda.h>

#include <vexcl/backend/common.hpp>
#include <vexcl/detail/backtrace.hpp>

namespace vex {
namespace backend {
namespace cuda {

/// Create and build a program from source string.
inline CUmodule build_sources(
        const command_queue &queue, const std::string &source,
        const std::string &options = ""
        )
{
#ifdef VEXCL_SHOW_KERNELS
    std::cout << source << std::endl;
#else
#  ifdef _MSC_VER
#    pragma warning(push)
#    pragma warning(disable: 4996)
#  endif
    if (getenv("VEXCL_SHOW_KERNELS"))
        std::cout << source << std::endl;
#  ifdef _MSC_VER
#    pragma warning(pop)
#  endif
#endif

    queue.context().set_current();

    auto cc = queue.device().compute_capability();
    std::ostringstream ccstr;
    ccstr << std::get<0>(cc) << std::get<1>(cc);

    sha1_hasher sha1;
    sha1.process(source)
        .process(queue.device().name())
        .process(options)
        .process(ccstr.str())
        ;

    std::string hash = static_cast<std::string>(sha1);

    // Write source to a .cu file
    std::string basename = program_binaries_path(hash, true) + "kernel";
    std::string ptxfile  = basename + ".ptx";

    if ( !boost::filesystem::exists(ptxfile) ) {
        std::string cufile = basename + ".cu";

        {
            std::ofstream f(basename + ".cu");
            f << source;
        }

        // Compile the source to ptx.
        std::ostringstream cmdline;
        cmdline
            << "nvcc -ptx -O3"
            << " -arch=sm_" << std::get<0>(cc) << std::get<1>(cc)
            << " " << options
            << " -o " << ptxfile << " " << cufile;
        if (0 != system(cmdline.str().c_str()) ) {
#ifndef VEXCL_SHOW_KERNELS
            std::cerr << source << std::endl;
#endif

            vex::detail::print_backtrace();
            throw std::runtime_error("nvcc invocation failed");
        }
    }

    // Load the compiled ptx.
    CUmodule program;
    cuda_check( cuModuleLoad(&program, ptxfile.c_str()) );

    return program;
}

} // namespace cuda
} // namespace backend
} // namespace vex

#endif
<commit_msg>Actually use user-provided compile options in CUDA backend<commit_after>#ifndef VEXCL_BACKEND_CUDA_COMPILER_HPP
#define VEXCL_BACKEND_CUDA_COMPILER_HPP

/*
The MIT License

Copyright (c) 2012-2016 Denis Demidov <dennis.demidov@gmail.com>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

/**
 * \file   vexcl/backend/cuda/compiler.hpp
 * \author Denis Demidov <dennis.demidov@gmail.com>
 * \brief  CUDA source code compilation wrapper.
 */

#include <cstdlib>
#include <cuda.h>

#include <vexcl/backend/common.hpp>
#include <vexcl/detail/backtrace.hpp>

namespace vex {
namespace backend {
namespace cuda {

/// Create and build a program from source string.
inline CUmodule build_sources(
        const command_queue &queue, const std::string &source,
        const std::string &options = ""
        )
{
#ifdef VEXCL_SHOW_KERNELS
    std::cout << source << std::endl;
#else
#  ifdef _MSC_VER
#    pragma warning(push)
#    pragma warning(disable: 4996)
#  endif
    if (getenv("VEXCL_SHOW_KERNELS"))
        std::cout << source << std::endl;
#  ifdef _MSC_VER
#    pragma warning(pop)
#  endif
#endif

    std::string compile_options = options + " " + get_compile_options(queue);

    queue.context().set_current();

    auto cc = queue.device().compute_capability();
    std::ostringstream ccstr;
    ccstr << std::get<0>(cc) << std::get<1>(cc);

    sha1_hasher sha1;
    sha1.process(source)
        .process(queue.device().name())
        .process(compile_options)
        .process(ccstr.str())
        ;

    std::string hash = static_cast<std::string>(sha1);

    // Write source to a .cu file
    std::string basename = program_binaries_path(hash, true) + "kernel";
    std::string ptxfile  = basename + ".ptx";

    if ( !boost::filesystem::exists(ptxfile) ) {
        std::string cufile = basename + ".cu";

        {
            std::ofstream f(basename + ".cu");
            f << source;
        }

        // Compile the source to ptx.
        std::ostringstream cmdline;
        cmdline
            << "nvcc -ptx -O3"
            << " -arch=sm_" << std::get<0>(cc) << std::get<1>(cc)
            << " " << compile_options
            << " -o " << ptxfile << " " << cufile;
        if (0 != system(cmdline.str().c_str()) ) {
#ifndef VEXCL_SHOW_KERNELS
            std::cerr << source << std::endl;
#endif

            vex::detail::print_backtrace();
            throw std::runtime_error("nvcc invocation failed");
        }
    }

    // Load the compiled ptx.
    CUmodule program;
    cuda_check( cuModuleLoad(&program, ptxfile.c_str()) );

    return program;
}

} // namespace cuda
} // namespace backend
} // namespace vex

#endif
<|endoftext|>


<commit_before>
// INCLUDES
#include <unistd.h>
#include <string.h>
#include <netdb.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/param.h>
#include "atTCPNetworkInterface.h++"

atTCPNetworkInterface::atTCPNetworkInterface(char * address, short port)
{
   char               hostname[MAXHOSTNAMELEN];
   struct hostent *   host;

   // Open the socket
   if ( (socket_value = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
      notify(AT_ERROR, "Unable to open socket for communication.\n");

   // Get information about this host and initialize the read name field
   gethostname(hostname, sizeof(hostname));
   host = gethostbyname(hostname);
   read_name.sin_family = AF_INET;
   memcpy(&read_name.sin_addr.s_addr, host->h_addr_list[0], host->h_length);
   read_name.sin_port = htons(port);

   // Get information about remote host and initialize the write name field
   host = gethostbyname(address);
   write_name.sin_family = AF_INET;
   memcpy(&write_name.sin_addr.s_addr, host->h_addr_list[0], host->h_length);
   write_name.sin_port = htons(port);

   // Initialize remaining instance variables
   num_client_sockets = 0;
}

atTCPNetworkInterface::atTCPNetworkInterface(short port)
{
   char               hostname[MAXHOSTNAMELEN];
   struct hostent *   host;

   // Open the socket
   if ( (socket_value = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
      notify(AT_ERROR, "Unable to open socket for communication.\n");

   // Get information about this host and initialize the read name field
   gethostname(hostname, sizeof(hostname));
   host = gethostbyname(hostname);
   read_name.sin_family = AF_INET;
   memcpy(&read_name.sin_addr.s_addr, host->h_addr_list[0], host->h_length);
   read_name.sin_port = htons(port);

   // Get information about remote host and initialize the write name field
   write_name.sin_family = AF_INET;
   memcpy(&write_name.sin_addr.s_addr, host->h_addr_list[0], host->h_length);
   write_name.sin_port = htons(port);

   // Initialize remaining instance variables
   num_client_sockets = 0;
}

atTCPNetworkInterface::~atTCPNetworkInterface()
{
   // Close the socket
   close(socket_value);
}

void atTCPNetworkInterface::allowConnections(int backlog)
{
   // Bind to the port
   if (bind(socket_value, (struct sockaddr *) &read_name,
            sizeof(read_name)) < 0)
   {
      notify(AT_ERROR, "Unable to bind to the port.\n");
   }

   // Notify our willingness to accept connections and give a backlog limit
   listen(socket_value, backlog);
}

int atTCPNetworkInterface::acceptConnection()
{
   int                  newSocket;
   struct sockaddr_in   connectingName;
   socklen_t            connectingNameLength;

   // Try to accept a connection
   connectingNameLength = sizeof(connectingName);
   newSocket = accept(socket_value, (struct sockaddr *) &connectingName,
                      &connectingNameLength);

   // If we had an error and it wasn't that we would block on a non-blocking
   // socket (a blocking socket shouldn't generate an EWOULDBLOCK error), then
   // notify the user; otherwise, store the socket and return an ID to the user
   if (newSocket == -1)
   {
      if (errno != EWOULDBLOCK)
         notify(AT_ERROR, "Could not accept a connection.\n");
      return -1;
   }
   else
   {
      client_sockets[num_client_sockets] = newSocket;
      num_client_sockets++;
      return num_client_sockets - 1;
   }
}

void atTCPNetworkInterface::enableBlockingOnClient(int clientID)
{
   int   statusFlags;

   // Get the current flags on the socket (return an error if we fail)
   if ( (statusFlags = fcntl(client_sockets[clientID], F_GETFL)) < 0 )
      notify(AT_ERROR, "Unable to get status of socket.\n");
   else
   {
      // Now set the flags back while removing the non-blocking bit
      if (fcntl(client_sockets[clientID], F_SETFL,
                statusFlags & (~FNONBLOCK)) < 0)
      {
         // Report an error if we fail
         notify(AT_ERROR, "Unable to disable blocking on socket.\n");
      }
   }
}

void atTCPNetworkInterface::disableBlockingOnClient(int clientID)
{
   int   statusFlags;

   // Get the current flags on the socket (return an error if we fail)
   if ( (statusFlags = fcntl(client_sockets[clientID], F_GETFL)) < 0 )
      notify(AT_ERROR, "Unable to get status of socket.\n");
   else
   {
      // Now set the flags back while adding the non-blocking bit (report any
      // errors we get if we fail)
      if (fcntl(client_sockets[clientID], F_SETFL, statusFlags | FNONBLOCK) < 0)
         notify(AT_ERROR, "Unable to disable blocking on socket.\n");
   }
}

int atTCPNetworkInterface::makeConnection()
{
   int                  statusFlags;
   int                  keepTrying;
   struct sockaddr_in   connectingName;

   // Get flags on our current socket (so we can put them on new sockets if
   // needed)
   if ( (statusFlags = fcntl(socket_value, F_GETFL)) < 0 )
      notify(AT_ERROR, "Unable to get status of socket.\n");

   keepTrying = 1;
   while (keepTrying == 1)
   {
      // Try to connect
      connectingName = write_name;
      if (connect(socket_value, (struct sockaddr *) &connectingName,
                  sizeof(connectingName)) != -1)
      {
         // We connected so signal the loop to end
         keepTrying = 0;
      }
      else
      {
         // We didn't connect so close the socket
         close(socket_value);
         socket_value = -1;

         // If we are not in blocking mode, tell the loop to stop (we give up);
         // Otherwise, tell the user the info that we failed this time and
         // re-open the socket
         if ( (fcntl(socket_value, F_GETFL) & FNONBLOCK) != 0 )
            keepTrying = 0;
         else
         {
            notify(AT_INFO, "Failed to connect to server.  Trying again.\n");

            // Re-open the socket
            if ( (socket_value = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
               notify(AT_ERROR, "Unable to open socket for communication.\n");

            // Put flags from previous socket on this new socket
            if (fcntl(socket_value, F_SETFL, statusFlags) < 0)
               notify(AT_ERROR, "Unable to disable blocking on socket.\n");
         }
      }
   }

   // Tell the user whether or not we succeeded to connect
   if (socket_value == -1)
      return -1;
   else
      return 0;
}

int atTCPNetworkInterface::read(u_char * buffer, u_long len)
{
   struct sockaddr_in   fromAddress;
   socklen_t            fromAddressLength;
   int                  packetLength;

   // Get a packet
   fromAddressLength = sizeof(fromAddress);
   packetLength = recvfrom(socket_value, buffer, len, MSG_WAITALL,
                           (struct sockaddr *) &fromAddress,
                           &fromAddressLength);

   // Tell user how many bytes we read (-1 means an error)
   return packetLength;
}

int atTCPNetworkInterface::read(int clientID, u_char * buffer, u_long len)
{
   struct sockaddr_in   fromAddress;
   socklen_t            fromAddressLength;
   int                  packetLength;

   // Get a packet
   fromAddressLength = sizeof(fromAddress);
   packetLength = recvfrom(client_sockets[clientID], buffer, len, MSG_WAITALL,
                           (struct sockaddr *) &fromAddress,
                           &fromAddressLength);

   // Tell user how many bytes we read (-1 means an error)
   return packetLength;
}

int atTCPNetworkInterface::write(u_char * buffer, u_long len)
{
   int   lengthWritten;

   // Write the packet
   lengthWritten = sendto(socket_value, buffer, len, 0,
                          (struct sockaddr *) &write_name, write_name_length);

   // Tell user how many bytes we wrote (-1 if error)
   return lengthWritten;
}

int atTCPNetworkInterface::write(int clientID, u_char * buffer, u_long len)
{
   int   lengthWritten;

   // Write the packet
   lengthWritten = sendto(client_sockets[clientID], buffer, len, 0,
                          (struct sockaddr *) &write_name, write_name_length);

   // Tell user how many bytes we wrote (-1 if error)
   return lengthWritten;
}

<commit_msg>Fixed connection to server to accept a delay (windows servers are slow it seems).<commit_after>
// INCLUDES
#include <unistd.h>
#include <string.h>
#include <netdb.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/param.h>
#include <sys/select.h>
#include "atTCPNetworkInterface.h++"

atTCPNetworkInterface::atTCPNetworkInterface(char * address, short port)
{
   char               hostname[MAXHOSTNAMELEN];
   struct hostent *   host;

   // Open the socket
   if ( (socket_value = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
      notify(AT_ERROR, "Unable to open socket for communication.\n");

   // Get information about this host and initialize the read name field
   gethostname(hostname, sizeof(hostname));
   host = gethostbyname(hostname);
   read_name.sin_family = AF_INET;
   memcpy(&read_name.sin_addr.s_addr, host->h_addr_list[0], host->h_length);
   read_name.sin_port = htons(port);

   // Get information about remote host and initialize the write name field
   host = gethostbyname(address);
   write_name.sin_family = AF_INET;
   memcpy(&write_name.sin_addr.s_addr, host->h_addr_list[0], host->h_length);
   write_name.sin_port = htons(port);

   // Initialize remaining instance variables
   num_client_sockets = 0;
}

atTCPNetworkInterface::atTCPNetworkInterface(short port)
{
   char               hostname[MAXHOSTNAMELEN];
   struct hostent *   host;

   // Open the socket
   if ( (socket_value = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
      notify(AT_ERROR, "Unable to open socket for communication.\n");

   // Get information about this host and initialize the read name field
   gethostname(hostname, sizeof(hostname));
   host = gethostbyname(hostname);
   read_name.sin_family = AF_INET;
   memcpy(&read_name.sin_addr.s_addr, host->h_addr_list[0], host->h_length);
   read_name.sin_port = htons(port);

   // Get information about remote host and initialize the write name field
   write_name.sin_family = AF_INET;
   memcpy(&write_name.sin_addr.s_addr, host->h_addr_list[0], host->h_length);
   write_name.sin_port = htons(port);

   // Initialize remaining instance variables
   num_client_sockets = 0;
}

atTCPNetworkInterface::~atTCPNetworkInterface()
{
   // Close the socket
   close(socket_value);
}

void atTCPNetworkInterface::allowConnections(int backlog)
{
   // Bind to the port
   if (bind(socket_value, (struct sockaddr *) &read_name,
            sizeof(read_name)) < 0)
   {
      notify(AT_ERROR, "Unable to bind to the port.\n");
   }

   // Notify our willingness to accept connections and give a backlog limit
   listen(socket_value, backlog);
}

int atTCPNetworkInterface::acceptConnection()
{
   int                  newSocket;
   struct sockaddr_in   connectingName;
   socklen_t            connectingNameLength;

   // Try to accept a connection
   connectingNameLength = sizeof(connectingName);
   newSocket = accept(socket_value, (struct sockaddr *) &connectingName,
                      &connectingNameLength);

   // If we had an error and it wasn't that we would block on a non-blocking
   // socket (a blocking socket shouldn't generate an EWOULDBLOCK error), then
   // notify the user; otherwise, store the socket and return an ID to the user
   if (newSocket == -1)
   {
      if (errno != EWOULDBLOCK)
         notify(AT_ERROR, "Could not accept a connection.\n");
      return -1;
   }
   else
   {
      client_sockets[num_client_sockets] = newSocket;
      num_client_sockets++;
      return num_client_sockets - 1;
   }
}

void atTCPNetworkInterface::enableBlockingOnClient(int clientID)
{
   int   statusFlags;

   // Get the current flags on the socket (return an error if we fail)
   if ( (statusFlags = fcntl(client_sockets[clientID], F_GETFL)) < 0 )
      notify(AT_ERROR, "Unable to get status of socket.\n");
   else
   {
      // Now set the flags back while removing the non-blocking bit
      if (fcntl(client_sockets[clientID], F_SETFL,
                statusFlags & (~FNONBLOCK)) < 0)
      {
         // Report an error if we fail
         notify(AT_ERROR, "Unable to disable blocking on socket.\n");
      }
   }
}

void atTCPNetworkInterface::disableBlockingOnClient(int clientID)
{
   int   statusFlags;

   // Get the current flags on the socket (return an error if we fail)
   if ( (statusFlags = fcntl(client_sockets[clientID], F_GETFL)) < 0 )
      notify(AT_ERROR, "Unable to get status of socket.\n");
   else
   {
      // Now set the flags back while adding the non-blocking bit (report any
      // errors we get if we fail)
      if (fcntl(client_sockets[clientID], F_SETFL, statusFlags | FNONBLOCK) < 0)
         notify(AT_ERROR, "Unable to disable blocking on socket.\n");
   }
}

int atTCPNetworkInterface::makeConnection()
{
   int                  statusFlags;
   int                  keepTrying;
   struct sockaddr_in   connectingName;
   fd_set               fds;
   struct timeval       timeout;

   // Get flags on our current socket (so we can put them on new sockets if
   // needed)
   if ( (statusFlags = fcntl(socket_value, F_GETFL)) < 0 )
      notify(AT_ERROR, "Unable to get status of socket.\n");

   keepTrying = 1;
   while (keepTrying == 1)
   {
      // Try to connect
      connectingName = write_name;
      if (connect(socket_value, (struct sockaddr *) &connectingName,
                  sizeof(connectingName)) != -1)
      {
         // We connected so signal the loop to end
         keepTrying = 0;
      }
      else
      {
         // If we are not in blocking mode, tell the loop to stop (we give up);
         // Otherwise, tell the user the info that we failed this time and
         // re-open the socket
         if ( (fcntl(socket_value, F_GETFL) & FNONBLOCK) != 0 )
         {
            // We are non-blocking so we could be failing to connect
            // or we could just need more time (EINPROGRESS) so
            // use select() to give it some time and then check again
            FD_ZERO(&fds);
            FD_SET(socket_value, &fds);
            timeout.tv_sec = 1;
            timeout.tv_usec = 0;
            if (select(socket_value+1, NULL, &fds, NULL, &timeout) > 0)
            {
               // We actually did connect!
               keepTrying = 0;
            }
            else
            {
               // We didn't connect so close the socket
               keepTrying = 0;
               close(socket_value);
               socket_value = -1;
            }
         }
         else
         {
            // We didn't connect so close the socket
            close(socket_value);
            socket_value = -1;

            notify(AT_INFO, "Failed to connect to server.  Trying again.\n");

            // Re-open the socket
            if ( (socket_value = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
               notify(AT_ERROR, "Unable to open socket for communication.\n");

            // Put flags from previous socket on this new socket
            if (fcntl(socket_value, F_SETFL, statusFlags) < 0)
               notify(AT_ERROR, "Unable to disable blocking on socket.\n");
         }
      }
   }

   // Tell the user whether or not we succeeded to connect
   if (socket_value == -1)
      return -1;
   else
      return 0;
}

int atTCPNetworkInterface::read(u_char * buffer, u_long len)
{
   struct sockaddr_in   fromAddress;
   socklen_t            fromAddressLength;
   int                  packetLength;

   // Get a packet
   fromAddressLength = sizeof(fromAddress);
   packetLength = recvfrom(socket_value, buffer, len, MSG_WAITALL,
                           (struct sockaddr *) &fromAddress,
                           &fromAddressLength);

   // Tell user how many bytes we read (-1 means an error)
   return packetLength;
}

int atTCPNetworkInterface::read(int clientID, u_char * buffer, u_long len)
{
   struct sockaddr_in   fromAddress;
   socklen_t            fromAddressLength;
   int                  packetLength;

   // Get a packet
   fromAddressLength = sizeof(fromAddress);
   packetLength = recvfrom(client_sockets[clientID], buffer, len, MSG_WAITALL,
                           (struct sockaddr *) &fromAddress,
                           &fromAddressLength);

   // Tell user how many bytes we read (-1 means an error)
   return packetLength;
}

int atTCPNetworkInterface::write(u_char * buffer, u_long len)
{
   int   lengthWritten;

   // Write the packet
   lengthWritten = sendto(socket_value, buffer, len, 0,
                          (struct sockaddr *) &write_name, write_name_length);

   // Tell user how many bytes we wrote (-1 if error)
   return lengthWritten;
}

int atTCPNetworkInterface::write(int clientID, u_char * buffer, u_long len)
{
   int   lengthWritten;

   // Write the packet
   lengthWritten = sendto(client_sockets[clientID], buffer, len, 0,
                          (struct sockaddr *) &write_name, write_name_length);

   // Tell user how many bytes we wrote (-1 if error)
   return lengthWritten;
}

<|endoftext|>


<commit_before>#ifndef VIENNAGRID_IO_NETGEN_READER_GUARD
#define VIENNAGRID_IO_NETGEN_READER_GUARD

/* =======================================================================
   Copyright (c) 2011-2012, Institute for Microelectronics,
                            Institute for Analysis and Scientific Computing,
                            TU Wien.

                            -----------------
                     ViennaGrid - The Vienna Grid Library
                            -----------------

   Authors:      Karl Rupp                           rupp@iue.tuwien.ac.at
                 Josef Weinbub                    weinbub@iue.tuwien.ac.at

   (A list of additional contributors can be found in the PDF manual)

   License:      MIT (X11), see file LICENSE in the base directory
======================================================================= */

#include <fstream>
#include <iostream>
#include <assert.h>
#include "viennagrid/forwards.h"
#include "viennagrid/io/helper.hpp"
#include "viennagrid/iterators.hpp"

/** @file netgen_reader.hpp
    @brief Provides a reader for Netgen files
*/

namespace viennagrid
{
  namespace io
  {

    /** @brief Reader for Netgen files obtained from the 'Export mesh...' menu item. Tested with Netgen version 4.9.12. */
    struct netgen_reader
    {
      /** @brief The functor interface triggering the read operation.
       *
       * @param domain    A ViennaGrid domain
       * @param filename  Name of the file
       */
      template <typename DomainType>
      int operator()(DomainType & domain, std::string const & filename) const
      {
        typedef typename DomainType::config_type                         ConfigType;

        typedef typename ConfigType::numeric_type                        CoordType;
        typedef typename ConfigType::coordinate_system_tag               CoordinateSystemTag;
        typedef typename ConfigType::cell_tag                            CellTag;

        typedef typename result_of::point<ConfigType>::type                              PointType;
        typedef typename result_of::ncell<ConfigType, 0>::type                           VertexType;
        typedef typename result_of::ncell<ConfigType, CellTag::dim>::type     CellType;

        typedef typename viennagrid::result_of::ncell_range<DomainType, 0>::type   VertexRange;
        typedef typename viennagrid::result_of::iterator<VertexRange>::type        VertexIterator;

        typedef typename viennagrid::result_of::ncell_range<DomainType, 1>::type   EdgeRange;
        typedef typename viennagrid::result_of::iterator<EdgeRange>::type          EdgeIterator;

        typedef typename viennagrid::result_of::ncell_range<DomainType, CellTag::dim-1>::type   FacetRange;
        typedef typename viennagrid::result_of::iterator<FacetRange>::type                                 FacetIterator;

        typedef typename viennagrid::result_of::ncell_range<DomainType, CellTag::dim>::type     CellRange;
        typedef typename viennagrid::result_of::iterator<CellRange>::type                                  CellIterator;

        std::ifstream reader(filename.c_str());

        typedef typename DomainType::segment_container      SegmentContainer;

        //Segment & segment = *(domain.begin());
        SegmentContainer & segments = domain.segments();

        #if defined VIENNAGRID_DEBUG_STATUS || defined VIENNAGRID_DEBUG_IO
        std::cout << "* netgen_reader::operator(): Reading file " << filename << std::endl;
        #endif

        if (!reader)
        {
          throw cannot_open_file_exception(filename);
          return EXIT_FAILURE;
        }

        std::string token;
        long node_num = 0;
        long cell_num = 0;

        if (!reader.good())
          throw bad_file_format_exception(filename, "File is empty.");

        //
        // Read vertices:
        //
        reader >> node_num;
        assert(node_num > 0);

        #if defined VIENNAGRID_DEBUG_STATUS || defined VIENNAGRID_DEBUG_IO
        std::cout << "* netgen_reader::operator(): Reading " << node_num << " vertices... " << std::endl;
        #endif

        VertexType vertex;

        for (int i=0; i<node_num; i++)
        {
          if (!reader.good())
            throw bad_file_format_exception(filename, "EOF encountered while reading vertices.");

          for (int j=0; j<CoordinateSystemTag::dim; j++)
            reader >> vertex.point()[j];

          vertex.id(i);
          domain.push_back(vertex);
        }

        //std::cout << "DONE" << std::endl;
        if (!reader.good())
          throw bad_file_format_exception(filename, "EOF encountered when reading number of cells.");

        //
        // Read cells:
        //
        reader >> cell_num;
        //domain.reserve_cells(cell_num);

        #if defined VIENNAGRID_DEBUG_STATUS || defined VIENNAGRID_DEBUG_IO
        std::cout << "* netgen_reader::operator(): Reading " << cell_num << " cells... " << std::endl;
        #endif

        CellType cell;
        //std::cout << "Filling " << cell_num << " cells:" << std::endl;

        for (int i=0; i<cell_num; ++i)
        {
          long vertex_num;
          VertexType *vertices[topology::bndcells<CellTag, 0>::num];

          if (!reader.good())
            throw bad_file_format_exception(filename, "EOF encountered while reading cells (segment index expected).");

          std::size_t segment_index;
          reader >> segment_index;

          for (int j=0; j<topology::bndcells<CellTag, 0>::num; ++j)
          {
            if (!reader.good())
              throw bad_file_format_exception(filename, "EOF encountered while reading cells (cell ID expected).");

            reader >> vertex_num;
            vertices[j] = &(viennagrid::ncells<0>(domain)[vertex_num - 1]);  //Note that Netgen uses vertex indices with base 1
          }

          //std::cout << std::endl << "Adding cell: " << &cell << " at " << i << std::endl;
          cell.vertices(&(vertices[0]));
          cell.id(i);
          if (segments.size() < segment_index) //not that segment_index is 1-based
            segments.resize(segment_index);

          segments[segment_index - 1].push_back(cell);  //note that Netgen uses a 1-based indexing scheme, while ViennaGrid uses a zero-based one

          //progress info:
          //if (i % 50000 == 0 && i > 0)
          //  std::cout << "* netgen_reader::operator(): " << i << " out of " << cell_num << " cells read." << std::endl;
        }

        //std::cout << "All done!" << std::endl;

        return EXIT_SUCCESS;
      } //operator()

    }; //class netgen_reader

  } //namespace io
} //namespace viennagrid

#endif
<commit_msg>adapted to new domain layer forwards.h -> forwards.hpp<commit_after>#ifndef VIENNAGRID_IO_NETGEN_READER_GUARD
#define VIENNAGRID_IO_NETGEN_READER_GUARD

/* =======================================================================
   Copyright (c) 2011-2012, Institute for Microelectronics,
                            Institute for Analysis and Scientific Computing,
                            TU Wien.

                            -----------------
                     ViennaGrid - The Vienna Grid Library
                            -----------------

   Authors:      Karl Rupp                           rupp@iue.tuwien.ac.at
                 Josef Weinbub                    weinbub@iue.tuwien.ac.at

   (A list of additional contributors can be found in the PDF manual)

   License:      MIT (X11), see file LICENSE in the base directory
======================================================================= */

#include <fstream>
#include <iostream>
#include <assert.h>
#include "viennagrid/forwards.hpp"
#include "viennagrid/io/helper.hpp"
#include "viennagrid/iterators.hpp"

#include "viennagrid/domain/geometric_domain.hpp"

/** @file netgen_reader.hpp
    @brief Provides a reader for Netgen files
*/

namespace viennagrid
{
  namespace io
  {

    /** @brief Reader for Netgen files obtained from the 'Export mesh...' menu item. Tested with Netgen version 4.9.12. */
    template<typename CellType>
    struct netgen_reader
    {
      /** @brief The functor interface triggering the read operation.
       *
       * @param domain    A ViennaGrid domain
       * @param filename  Name of the file
       */
      template <typename GeometricDomainType, typename GeometricSegmentContainerType>
      int operator()(GeometricDomainType & domain, GeometricSegmentContainerType & segments, std::string const & filename) const
      {
        //typedef typename DomainType::config_type                         ConfigType;

        typedef typename GeometricSegmentContainerType::value_type SegmentType;

        typedef typename viennagrid::result_of::point_type<GeometricDomainType>::type    PointType;
        typedef typename viennagrid::traits::value_type< PointType >::type         CoordType;

        //typedef typename ConfigType::numeric_type                        CoordType;
        //typedef typename ConfigType::coordinate_system_tag               CoordinateSystemTag;
        enum { point_dim = viennagrid::traits::static_size<PointType>::value };

        typedef typename CellType::tag                            CellTag;
        typedef typename result_of::element_hook<GeometricDomainType, CellTag>::type                           CellHookType;

        //typedef typename result_of::point<ConfigType>::type                              PointType;
        typedef typename result_of::element<GeometricDomainType, vertex_tag>::type                           VertexType;
        typedef typename result_of::element_hook<GeometricDomainType, vertex_tag>::type                           VertexHookType;
        //typedef typename result_of::ncell<DomainType, CellTag::dim>::type     CellType;

        typedef typename viennagrid::result_of::element_range<GeometricDomainType, vertex_tag>::type   VertexRange;
        typedef typename viennagrid::result_of::iterator<VertexRange>::type        VertexIterator;

        typedef typename viennagrid::result_of::element_range<GeometricDomainType, line_tag>::type   EdgeRange;
        typedef typename viennagrid::result_of::iterator<EdgeRange>::type          EdgeIterator;

        typedef typename viennagrid::result_of::element_range<GeometricDomainType, typename CellType::tag::facet_tag >::type   FacetRange;
        typedef typename viennagrid::result_of::iterator<FacetRange>::type                                 FacetIterator;

        typedef typename viennagrid::result_of::element_range<GeometricDomainType, CellTag>::type     CellRange;
        typedef typename viennagrid::result_of::iterator<CellRange>::type                                  CellIterator;

        std::ifstream reader(filename.c_str());

        #if defined VIENNAGRID_DEBUG_STATUS || defined VIENNAGRID_DEBUG_IO
        std::cout << "* netgen_reader::operator(): Reading file " << filename << std::endl;
        #endif

        if (!reader)
        {
          throw cannot_open_file_exception(filename);
          return EXIT_FAILURE;
        }

        std::string token;
        long node_num = 0;
        long cell_num = 0;

        if (!reader.good())
          throw bad_file_format_exception(filename, "File is empty.");

        //
        // Read vertices:
        //
        reader >> node_num;
        assert(node_num > 0);

        #if defined VIENNAGRID_DEBUG_STATUS || defined VIENNAGRID_DEBUG_IO
        std::cout << "* netgen_reader::operator(): Reading " << node_num << " vertices... " << std::endl;
        #endif

        for (int i=0; i<node_num; i++)
        {
          if (!reader.good())
            throw bad_file_format_exception(filename, "EOF encountered while reading vertices.");

          VertexHookType vertex = viennagrid::create_element<VertexType>( domain, typename VertexType::id_type(i) );
          PointType & p = viennagrid::point( domain, vertex );

          for (int j=0; j<point_dim; j++)
            reader >> p[j];

          //viennagrid::dereference_hook(domain, vertex).id( storage::smart_id<VertexType, int>(i) );
        }

        //std::cout << "DONE" << std::endl;
        if (!reader.good())
          throw bad_file_format_exception(filename, "EOF encountered when reading number of cells.");

        //
        // Read cells:
        //
        reader >> cell_num;
        //domain.reserve_cells(cell_num);

        #if defined VIENNAGRID_DEBUG_STATUS || defined VIENNAGRID_DEBUG_IO
        std::cout << "* netgen_reader::operator(): Reading " << cell_num << " cells... " << std::endl;
        #endif

        //CellHookType cell = viennagrid::create_element<CellType>(domain);
        //std::cout << "Filling " << cell_num << " cells:" << std::endl;

        for (int i=0; i<cell_num; ++i)
        {
          long vertex_num;
          std::vector<VertexHookType> cell_vertex_hooks(topology::bndcells<CellTag, 0>::num);

          if (!reader.good())
            throw bad_file_format_exception(filename, "EOF encountered while reading cells (segment index expected).");

          std::size_t segment_index;
          reader >> segment_index;

          for (int j=0; j<topology::bndcells<CellTag, 0>::num; ++j)
          {
            if (!reader.good())
              throw bad_file_format_exception(filename, "EOF encountered while reading cells (cell ID expected).");

            reader >> vertex_num;
            cell_vertex_hooks[j] = viennagrid::get_vertex_hook(domain, vertex_num - 1);
          }

          if (segments.size() < segment_index) //not that segment_index is 1-based
          {
            segments.resize(segment_index);
            segments[segment_index - 1] = viennagrid::create_view<SegmentType>(domain);
          }

          viennagrid::create_element<CellType>(segments[segment_index - 1], cell_vertex_hooks, typename CellType::id_type(i));
        }

        //std::cout << "All done!" << std::endl;

        return EXIT_SUCCESS;
      } //operator()

    }; //class netgen_reader

  } //namespace io
} //namespace viennagrid

#endif
<|endoftext|>