<commit_before>/* Copyright (C) 2014-2015 INRA
 *
 * 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.
 */

#ifndef INRA_EFYj_SOLVER_BASIC_HPP
#define INRA_EFYj_SOLVER_BASIC_HPP

#include <efyj/model.hpp>
#include <efyj/exception.hpp>

#include <algorithm>
#include <numeric>

namespace efyj {

namespace basic_details {

std::string format_error_msg(const efyj::attribute& att, std::uint32_t key)
{
    return std::string("Unknown solution ") + std::to_string(key)
        + std::string(" for attribute ") + att.name;
}

efyj::scale_id utility_function_get_value(efyj::attribute& att)
{
    std::uint32_t key = std::accumulate(
        att.children.begin(),
        att.children.end(),
        0u,
        [](std::uint32_t init, const efyj::attribute* a)
        {
            return init * 10 + a->value;
        });

    auto it = att.utility_function.find(key);
    if (it == att.utility_function.end())
        throw efyj::solver_error(format_error_msg(att, key));

    return it->second;
}

}

struct solver_basic
{
    solver_basic(Model& model)
        : model(model)
    {
        model.init();
    }

    template <typename V>
    scale_id solve(const V& options)
    {
        std::size_t i = 0;

        for (auto& att : model.attributes) {
            if (not att.is_basic()) {
                att.parent_is_solvable = 0;
                att.value = std::numeric_limits <std::size_t>::max();
            }
        }

        for (auto& att : model.attributes) {
            if (att.is_basic()) {
                att.value = options(i++);

                if (i >= model.attributes.size())
                    throw std::invalid_argument("i > model.attributes.size()");

                if (att.parent != nullptr)
                    att.parent->parent_is_solvable++;
            }
        }

        for (;;) {
            for (auto& att : model.attributes) {
                if (not att.is_basic()) {
                    if (att.value != std::numeric_limits <std::size_t>::max())
                        break;

                    attribute *cur= &att;
                    while (cur && cur->parent_is_solvable == cur->children.size()) {
                        scale_id value = basic_details::utility_function_get_value(*cur);
                        if (cur->parent == nullptr)
                            return value;

                        cur->value = value;
                        cur->parent->parent_is_solvable++;
                        cur = cur->parent;
                    }
                }
            }
        }
    }

    Model& model;
};

}

#endif
<commit_msg>solver-basic: switches std::uint32_t into std::size_t to avoid overflow<commit_after>/* Copyright (C) 2014-2015 INRA
 *
 * 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.
 */

#ifndef INRA_EFYj_SOLVER_BASIC_HPP
#define INRA_EFYj_SOLVER_BASIC_HPP

#include <efyj/model.hpp>
#include <efyj/exception.hpp>

#include <algorithm>
#include <numeric>

namespace efyj {

namespace basic_details {

std::string format_error_msg(const efyj::attribute& att, std::size_t key)
{
    return std::string("Unknown solution ") + std::to_string(key)
        + std::string(" for attribute ") + att.name;
}

efyj::scale_id utility_function_get_value(efyj::attribute& att)
{
    std::size_t key = std::accumulate(
        att.children.begin(),
        att.children.end(),
        0u,
        [](std::size_t init, const efyj::attribute* a)
        {
            return init * 10 + a->value;
        });

    auto it = att.utility_function.find(key);
    if (it == att.utility_function.end())
        throw efyj::solver_error(format_error_msg(att, key));

    return it->second;
}

}

struct solver_basic
{
    solver_basic(Model& model)
        : model(model)
    {
        model.init();
    }

    template <typename V>
    scale_id solve(const V& options)
    {
        std::size_t i = 0;

        for (auto& att : model.attributes) {
            if (not att.is_basic()) {
                att.parent_is_solvable = 0;
                att.value = std::numeric_limits <std::size_t>::max();
            }
        }

        for (auto& att : model.attributes) {
            if (att.is_basic()) {
                att.value = options(i++);

                if (i >= model.attributes.size())
                    throw std::invalid_argument("i > model.attributes.size()");

                if (att.parent != nullptr)
                    att.parent->parent_is_solvable++;
            }
        }

        for (;;) {
            for (auto& att : model.attributes) {
                if (not att.is_basic()) {
                    if (att.value != std::numeric_limits <std::size_t>::max())
                        break;

                    attribute *cur= &att;
                    while (cur && cur->parent_is_solvable == cur->children.size()) {
                        scale_id value = basic_details::utility_function_get_value(*cur);
                        if (cur->parent == nullptr)
                            return value;

                        cur->value = value;
                        cur->parent->parent_is_solvable++;
                        cur = cur->parent;
                    }
                }
            }
        }
    }

    Model& model;
};

}

#endif
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: FrameOASISTContext.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2004-11-03 16:42:43 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _XMLOFF_FRAMEOASISTCONTEXT_HXX
#include "FrameOASISTContext.hxx"
#endif
#ifndef _XMLOFF_IGNORETCONTEXT_HXX
#include "IgnoreTContext.hxx"
#endif
#ifndef _XMLOFF_MUTABLEATTRLIST_HXX
#include "MutableAttrList.hxx"
#endif
#ifndef _XMLOFF_XMLNMSPE_HXX
#include "xmlnmspe.hxx"
#endif
#ifndef _XMLOFF_ACTIONMAPTYPESOASIS_HXX
#include "ActionMapTypesOASIS.hxx"
#endif
#ifndef _XMLOFF_ELEMTRANSFORMERACTION_HXX
#include "ElemTransformerAction.hxx"
#endif
#ifndef _XMLOFF_TRANSFORMERACTIONS_HXX
#include "TransformerActions.hxx"
#endif
#ifndef _XMLOFF_TRANSFORMERBASE_HXX
#include "TransformerBase.hxx"
#endif

using namespace ::rtl;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::xml::sax;
using namespace ::xmloff::token;

TYPEINIT1( XMLFrameOASISTransformerContext, XMLTransformerContext );

XMLFrameOASISTransformerContext::XMLFrameOASISTransformerContext(
        XMLTransformerBase& rImp,
        const OUString& rQName ) :
    XMLTransformerContext( rImp, rQName ),
    m_bIgnoreElement( false )
{
}

XMLFrameOASISTransformerContext::~XMLFrameOASISTransformerContext()
{
}

void XMLFrameOASISTransformerContext::StartElement(
    const Reference< XAttributeList >& rAttrList )
{
    m_xAttrList = new XMLMutableAttributeList( rAttrList, sal_True );

    sal_Int16 nAttrCount = rAttrList.is() ? rAttrList->getLength() : 0;
    for( sal_Int16 i=0; i < nAttrCount; i++ )
    {
        const OUString& rAttrName = rAttrList->getNameByIndex( i );
        OUString aLocalName;
        sal_uInt16 nPrefix =
            GetTransformer().GetNamespaceMap().GetKeyByAttrName( rAttrName, &aLocalName );

        if( (nPrefix == XML_NAMESPACE_PRESENTATION) && IsXMLToken( aLocalName, XML_CLASS ) )
        {
            const OUString& rAttrValue = rAttrList->getValueByIndex( i );
            if( IsXMLToken( rAttrValue, XML_HEADER ) || IsXMLToken( rAttrValue, XML_FOOTER ) ||
                IsXMLToken( rAttrValue, XML_PAGE_NUMBER ) || IsXMLToken( rAttrValue, XML_DATE_TIME ) )
            {
                m_bIgnoreElement = true;
                break;
            }
        }
    }
}

XMLTransformerContext *XMLFrameOASISTransformerContext::CreateChildContext(
        sal_uInt16 nPrefix,
        const OUString& rLocalName,
        const OUString& rQName,
        const Reference< XAttributeList >& rAttrList )
{
    XMLTransformerContext *pContext = 0;

    if( m_bIgnoreElement )
    {
        // do not export the frame element and all of its children
        pContext = new XMLIgnoreTransformerContext( GetTransformer(),
                                                                rQName,
                                                                sal_True, sal_True );
    }
    else
    {
        XMLTransformerActions *pActions =
            GetTransformer().GetUserDefinedActions( OASIS_FRAME_ELEM_ACTIONS );
        OSL_ENSURE( pActions, "go no actions" );
        XMLTransformerActions::key_type aKey( nPrefix, rLocalName );
        XMLTransformerActions::const_iterator aIter = pActions->find( aKey );

        if( !(aIter == pActions->end()) )
        {
            switch( (*aIter).second.m_nActionType )
            {
            case XML_ETACTION_COPY:
                if( !m_aElemQName.getLength() )
                {
                    pContext = new XMLIgnoreTransformerContext( GetTransformer(),
                                                                rQName,
                                                                sal_False, sal_False );
                    m_aElemQName = rQName;
                    static_cast< XMLMutableAttributeList * >( m_xAttrList.get() )
                        ->AppendAttributeList( rAttrList );
                    GetTransformer().ProcessAttrList( m_xAttrList,
                                                    OASIS_SHAPE_ACTIONS,
                                                       sal_False    );
                    GetTransformer().GetDocHandler()->startElement( m_aElemQName,
                                                                    m_xAttrList );
                }
                else
                {
                    pContext = new XMLIgnoreTransformerContext( GetTransformer(),
                                                                rQName,
                                                                sal_True, sal_True );
                }
                break;
            default:
                OSL_ENSURE( !this, "unknown action" );
                break;
            }
        }
    }

    // default is copying
    if( !pContext )
        pContext = XMLTransformerContext::CreateChildContext( nPrefix,
                                                              rLocalName,
                                                              rQName,
                                                              rAttrList );

    return pContext;
}

void XMLFrameOASISTransformerContext::EndElement()
{
    if( !m_bIgnoreElement )
        GetTransformer().GetDocHandler()->endElement( m_aElemQName );
}

void XMLFrameOASISTransformerContext::Characters( const OUString& rChars )
{
    // ignore
    if( m_aElemQName.getLength() && !m_bIgnoreElement )
        XMLTransformerContext::Characters( rChars );
}
<commit_msg>INTEGRATION: CWS oasisbf2 (1.2.82); FILE MERGED 2004/11/26 11:40:42 mib 1.2.82.2: RESYNC: (1.2-1.3); FILE MERGED 2004/11/02 17:32:16 mib 1.2.82.1: #i35133#: replacement image for embedded objects<commit_after>/*************************************************************************
 *
 *  $RCSfile: FrameOASISTContext.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2004-11-26 13:09:01 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _XMLOFF_FRAMEOASISTCONTEXT_HXX
#include "FrameOASISTContext.hxx"
#endif
#ifndef _XMLOFF_IGNORETCONTEXT_HXX
#include "IgnoreTContext.hxx"
#endif
#ifndef _XMLOFF_MUTABLEATTRLIST_HXX
#include "MutableAttrList.hxx"
#endif
#ifndef _XMLOFF_XMLNMSPE_HXX
#include "xmlnmspe.hxx"
#endif
#ifndef _XMLOFF_ACTIONMAPTYPESOASIS_HXX
#include "ActionMapTypesOASIS.hxx"
#endif
#ifndef _XMLOFF_ELEMTRANSFORMERACTION_HXX
#include "ElemTransformerAction.hxx"
#endif
#ifndef _XMLOFF_TRANSFORMERACTIONS_HXX
#include "TransformerActions.hxx"
#endif
#ifndef _XMLOFF_TRANSFORMERBASE_HXX
#include "TransformerBase.hxx"
#endif

using namespace ::rtl;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::xml::sax;
using namespace ::xmloff::token;

TYPEINIT1( XMLFrameOASISTransformerContext, XMLTransformerContext );

sal_Bool XMLFrameOASISTransformerContext::IsLinkedEmbeddedObject(
            const OUString& rLocalName,
            const Reference< XAttributeList >& rAttrList )
{
    if( !(IsXMLToken( rLocalName, XML_OBJECT ) ||
          IsXMLToken( rLocalName, XML_OBJECT_OLE)  ) )
        return sal_False;

    sal_Int16 nAttrCount = rAttrList.is() ? rAttrList->getLength() : 0;
    for( sal_Int16 i=0; i < nAttrCount; i++ )
    {
        OUString aAttrName( rAttrList->getNameByIndex( i ) );
        OUString aLocalName;
        sal_uInt16 nPrefix =
            GetTransformer().GetNamespaceMap().GetKeyByAttrName( aAttrName,
                                                                 &aLocalName );
        if( XML_NAMESPACE_XLINK == nPrefix &&
            IsXMLToken( aLocalName, XML_HREF ) )
        {
            OUString sHRef( rAttrList->getValueByIndex( i ) );
            GetTransformer().ConvertURIToOOo( sHRef, sal_True );
            return !(sHRef.getLength() && '#'==sHRef[0]);
        }
    }

    return sal_False;
}

XMLFrameOASISTransformerContext::XMLFrameOASISTransformerContext(
        XMLTransformerBase& rImp,
        const OUString& rQName ) :
    XMLTransformerContext( rImp, rQName ),
    m_bIgnoreElement( false )
{
}

XMLFrameOASISTransformerContext::~XMLFrameOASISTransformerContext()
{
}

void XMLFrameOASISTransformerContext::StartElement(
    const Reference< XAttributeList >& rAttrList )
{
    m_xAttrList = new XMLMutableAttributeList( rAttrList, sal_True );

    sal_Int16 nAttrCount = rAttrList.is() ? rAttrList->getLength() : 0;
    for( sal_Int16 i=0; i < nAttrCount; i++ )
    {
        const OUString& rAttrName = rAttrList->getNameByIndex( i );
        OUString aLocalName;
        sal_uInt16 nPrefix =
            GetTransformer().GetNamespaceMap().GetKeyByAttrName( rAttrName, &aLocalName );

        if( (nPrefix == XML_NAMESPACE_PRESENTATION) && IsXMLToken( aLocalName, XML_CLASS ) )
        {
            const OUString& rAttrValue = rAttrList->getValueByIndex( i );
            if( IsXMLToken( rAttrValue, XML_HEADER ) || IsXMLToken( rAttrValue, XML_FOOTER ) ||
                IsXMLToken( rAttrValue, XML_PAGE_NUMBER ) || IsXMLToken( rAttrValue, XML_DATE_TIME ) )
            {
                m_bIgnoreElement = true;
                break;
            }
        }
    }
}

XMLTransformerContext *XMLFrameOASISTransformerContext::CreateChildContext(
        sal_uInt16 nPrefix,
        const OUString& rLocalName,
        const OUString& rQName,
        const Reference< XAttributeList >& rAttrList )
{
    XMLTransformerContext *pContext = 0;

    if( m_bIgnoreElement )
    {
        // do not export the frame element and all of its children
        pContext = new XMLIgnoreTransformerContext( GetTransformer(),
                                                                rQName,
                                                                sal_True, sal_True );
    }
    else
    {
        XMLTransformerActions *pActions =
            GetTransformer().GetUserDefinedActions( OASIS_FRAME_ELEM_ACTIONS );
        OSL_ENSURE( pActions, "go no actions" );
        XMLTransformerActions::key_type aKey( nPrefix, rLocalName );
        XMLTransformerActions::const_iterator aIter = pActions->find( aKey );

        if( !(aIter == pActions->end()) )
        {
            switch( (*aIter).second.m_nActionType )
            {
            case XML_ETACTION_COPY:
                if( !m_aElemQName.getLength() &&
                    !IsLinkedEmbeddedObject( rLocalName, rAttrList ) )
                {
                    pContext = new XMLIgnoreTransformerContext( GetTransformer(),
                                                                rQName,
                                                                sal_False, sal_False );
                    m_aElemQName = rQName;
                    static_cast< XMLMutableAttributeList * >( m_xAttrList.get() )
                        ->AppendAttributeList( rAttrList );
                    GetTransformer().ProcessAttrList( m_xAttrList,
                                                      OASIS_SHAPE_ACTIONS,
                                                      sal_False );
                    GetTransformer().GetDocHandler()->startElement( m_aElemQName,
                                                                    m_xAttrList );
                }
                else
                {
                    pContext = new XMLIgnoreTransformerContext( GetTransformer(),
                                                                rQName,
                                                                sal_True, sal_True );
                }
            default:
                OSL_ENSURE( !this, "unknown action" );
                break;
            }
        }
    }

    // default is copying
    if( !pContext )
        pContext = XMLTransformerContext::CreateChildContext( nPrefix,
                                                              rLocalName,
                                                              rQName,
                                                              rAttrList );

    return pContext;
}

void XMLFrameOASISTransformerContext::EndElement()
{
    if( !m_bIgnoreElement )
        GetTransformer().GetDocHandler()->endElement( m_aElemQName );
}

void XMLFrameOASISTransformerContext::Characters( const OUString& rChars )
{
    // ignore
    if( m_aElemQName.getLength() && !m_bIgnoreElement )
        XMLTransformerContext::Characters( rChars );
}
<|endoftext|>


<commit_before>/*
Resembla: Word-based Japanese similar sentence search library
https://github.com/tuem/resembla

Copyright 2017 Takashi Uemura

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

#include "feature_extractor.hpp"

#include <iostream>

#include "../../string_util.hpp"

namespace resembla {

const char FeatureExtractor::FEATURE_DELIMITER = '&';
const char FeatureExtractor::KEYVALUE_DELIMITER = '=';

FeatureExtractor::FeatureExtractor(const std::string base_similarity_key):
    base_similarity_key(base_similarity_key)
{}

void FeatureExtractor::append(Feature::key_type key, std::shared_ptr<Function> func)
{
    functions[key] = func;
}

FeatureExtractor::output_type FeatureExtractor::operator()(const std::string& raw_text, const std::string& raw_features) const
{
#ifdef DEBUG
    std::cerr << "load features from saved data: text=" << raw_text << ", features=" << raw_features << std::endl;
#else
    (void)raw_text;
#endif
    output_type features;
    for(const auto& f: split(raw_features, FEATURE_DELIMITER)){
        auto kv = split(f, KEYVALUE_DELIMITER);
        if(kv.size() == 2){
            auto i = functions.find(kv[0]);
            if(i != std::end(functions)){
                features[kv[0]] = kv[1];
#ifdef DEBUG
                std::cerr << "load feature: key=" << kv[0] << ", value=" << kv[1] << std::endl;
#endif
            }
        }
    }
    for(const auto& i: functions){
        auto k = features.find(i.first);
        if(k == std::end(features)){
            features[i.first] = (*i.second)(cast_string<string_type>(raw_text));
#ifdef DEBUG
            std::cerr << "extract feature: key=" << i.first << ", value=" << (*i.second)(cast_string<string_type>(raw_text)) << std::endl;
#endif
        }
    }
    return features;
}

FeatureExtractor::output_type FeatureExtractor::operator()(
        const resembla::ResemblaResponse& data, const output_type& given_features) const
{
    output_type features(given_features);
    // TODO: remove this code. FeatureExtractor should accept multiple base similarities
    features[base_similarity_key] = Feature::toText(data.score);
    for(const auto& i: functions){
        auto k = features.find(i.first);
#ifdef DEBUG
        if(k == std::end(features)){
            std::cerr << "extract feature: key=" << i.first << ", value=" << (*i.second)(data.text) << std::endl;
        }
        else{
            std::cerr << "skip already computed feature: key=" << i.first << ", value=" << k->second << std::endl;
        }
#endif
        if(k == std::end(features)){
            features[i.first] = (*i.second)(data.text);
        }
    }
    return features;
}

FeatureExtractor::output_type FeatureExtractor::operator()(const string_type& text) const
{
    output_type features;
    for(const auto& i: functions){
#ifdef DEBUG
        std::cerr << "extract feature: " << i.first << std::endl;
#endif
        features[i.first] = (*i.second)(text);
    }
    return features;
}

FeatureExtractor::output_type FeatureExtractor::operator()(const string_type& text, bool is_original) const
{
    output_type features;

    auto raw_text = cast_string<std::string>(text);
    if(is_original){
        auto columns = split(raw_text, '\t');
        if(columns.size() > 1){
            raw_text = columns[0];
            for(const auto& f: split(columns[1], FEATURE_DELIMITER)){
                auto kv = split(f, KEYVALUE_DELIMITER);
                if(kv.size() == 2){
                    auto i = functions.find(kv[0]);
                    if(i != std::end(functions)){
                        features[kv[0]] = kv[1];
                    }
                }
            }
        }
    }
    for(const auto& i: functions){
        auto k = features.find(i.first);
        if(k == std::end(features)){
            features[i.first] = (*i.second)(cast_string<string_type>(raw_text));
#ifdef DEBUG
            std::cerr << "extract feature: key=" << i.first << ", value=" << (*i.second)(cast_string<string_type>(raw_text)) << std::endl;
#endif
        }
    }
    return features;
}

string_type FeatureExtractor::index(const string_type& text) const
{
    return text;
}

}
<commit_msg>add debug output<commit_after>/*
Resembla: Word-based Japanese similar sentence search library
https://github.com/tuem/resembla

Copyright 2017 Takashi Uemura

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

#include "feature_extractor.hpp"

#include <iostream>

#include "../../string_util.hpp"

namespace resembla {

const char FeatureExtractor::FEATURE_DELIMITER = '&';
const char FeatureExtractor::KEYVALUE_DELIMITER = '=';

FeatureExtractor::FeatureExtractor(const std::string base_similarity_key):
    base_similarity_key(base_similarity_key)
{}

void FeatureExtractor::append(Feature::key_type key, std::shared_ptr<Function> func)
{
    functions[key] = func;
}

FeatureExtractor::output_type FeatureExtractor::operator()(const std::string& raw_text, const std::string& raw_features) const
{
#ifdef DEBUG
    std::cerr << "load features from saved data: text=" << raw_text << ", features=" << raw_features << std::endl;
#else
    (void)raw_text;
#endif
    output_type features;
    for(const auto& f: split(raw_features, FEATURE_DELIMITER)){
        auto kv = split(f, KEYVALUE_DELIMITER);
        if(kv.size() == 2){
            auto i = functions.find(kv[0]);
            if(i != std::end(functions)){
                features[kv[0]] = kv[1];
#ifdef DEBUG
                std::cerr << "load feature: key=" << kv[0] << ", value=" << kv[1] << std::endl;
#endif
            }
        }
    }
    for(const auto& i: functions){
        auto k = features.find(i.first);
        if(k == std::end(features)){
            features[i.first] = (*i.second)(cast_string<string_type>(raw_text));
#ifdef DEBUG
            std::cerr << "extract feature: key=" << i.first << ", value=" << (*i.second)(cast_string<string_type>(raw_text)) << std::endl;
#endif
        }
    }
    return features;
}

FeatureExtractor::output_type FeatureExtractor::operator()(
        const resembla::ResemblaResponse& data, const output_type& given_features) const
{
    output_type features(given_features);
    // TODO: remove this code. FeatureExtractor should accept multiple base similarities
    features[base_similarity_key] = Feature::toText(data.score);
    for(const auto& i: functions){
        auto k = features.find(i.first);
#ifdef DEBUG
        if(k == std::end(features)){
            std::cerr << "extract feature: key=" << i.first << ", value=" << (*i.second)(data.text) << std::endl;
        }
        else{
            std::cerr << "skip already computed feature: key=" << i.first << ", value=" << k->second << std::endl;
        }
#endif
        if(k == std::end(features)){
            features[i.first] = (*i.second)(data.text);
        }
    }
    return features;
}

FeatureExtractor::output_type FeatureExtractor::operator()(const string_type& text) const
{
    output_type features;
    for(const auto& i: functions){
#ifdef DEBUG
        std::cerr << "extract feature: " << i.first << std::endl;
#endif
        features[i.first] = (*i.second)(text);
    }
    return features;
}

FeatureExtractor::output_type FeatureExtractor::operator()(const string_type& text, bool is_original) const
{
    output_type features;

    auto raw_text = cast_string<std::string>(text);
    if(is_original){
        auto columns = split(raw_text, '\t');
        if(columns.size() > 1){
            raw_text = columns[0];
            for(const auto& f: split(columns[1], FEATURE_DELIMITER)){
                auto kv = split(f, KEYVALUE_DELIMITER);
                if(kv.size() == 2){
                    auto i = functions.find(kv[0]);
                    if(i != std::end(functions)){
#ifdef DEBUG
                        std::cerr << "load feature: key=" << kv[0] << ", value=" << kv[1] << std::endl;
#endif
                        features[kv[0]] = kv[1];
                    }
                }
            }
        }
    }
    for(const auto& i: functions){
        auto k = features.find(i.first);
        if(k == std::end(features)){
            features[i.first] = (*i.second)(cast_string<string_type>(raw_text));
#ifdef DEBUG
            std::cerr << "extract feature: key=" << i.first << ", value=" << (*i.second)(cast_string<string_type>(raw_text)) << std::endl;
#endif
        }
    }
    return features;
}

string_type FeatureExtractor::index(const string_type& text) const
{
    return text;
}

}
<|endoftext|>


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

#include "qmlvaluetype_p.h"

#include <QtCore/qdebug.h>

QT_BEGIN_NAMESPACE

QmlValueTypeFactory::QmlValueTypeFactory()
{
    // ### Optimize
    for (unsigned int ii = 0; ii < (QVariant::UserType - 1); ++ii)
        valueTypes[ii] = valueType(ii);
}

QmlValueTypeFactory::~QmlValueTypeFactory()
{
    for (unsigned int ii = 0; ii < (QVariant::UserType - 1); ++ii)
        delete valueTypes[ii];
}

QmlValueType *QmlValueTypeFactory::valueType(int t)
{
    switch (t) {
    case QVariant::Point:
        return new QmlPointValueType;
    case QVariant::PointF:
        return new QmlPointFValueType;
    case QVariant::Size:
        return new QmlSizeValueType;
    case QVariant::SizeF:
        return new QmlSizeFValueType;
    case QVariant::Rect:
        return new QmlRectValueType;
    case QVariant::RectF:
        return new QmlRectFValueType;
    case QVariant::Vector3D:
        return new QmlVector3DValueType;
    case QVariant::Font:
        return new QmlFontValueType;
    default:
        return 0;
    }
}

QmlValueType::QmlValueType(QObject *parent)
: QObject(parent)
{
}

QmlPointFValueType::QmlPointFValueType(QObject *parent)
: QmlValueType(parent)
{
}

void QmlPointFValueType::read(QObject *obj, int idx)
{
    void *a[] = { &point, 0 };
    QMetaObject::metacall(obj, QMetaObject::ReadProperty, idx, a);
}

void QmlPointFValueType::write(QObject *obj, int idx, QmlMetaProperty::WriteFlags flags)
{
    int status = -1;
    void *a[] = { &point, 0, &status, &flags };
    QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a);
}

QVariant QmlPointFValueType::value()
{
    return QVariant(point);
}

void QmlPointFValueType::setValue(QVariant value)
{
    point = qvariant_cast<QPointF>(value);
}

qreal QmlPointFValueType::x() const
{
    return point.x();
}

qreal QmlPointFValueType::y() const
{
    return point.y();
}

void QmlPointFValueType::setX(qreal x)
{
    point.setX(x);
}

void QmlPointFValueType::setY(qreal y)
{
    point.setY(y);
}

QmlPointValueType::QmlPointValueType(QObject *parent)
: QmlValueType(parent)
{
}

void QmlPointValueType::read(QObject *obj, int idx)
{
    void *a[] = { &point, 0 };
    QMetaObject::metacall(obj, QMetaObject::ReadProperty, idx, a);
}

void QmlPointValueType::write(QObject *obj, int idx, QmlMetaProperty::WriteFlags flags)
{
    int status = -1;
    void *a[] = { &point, 0, &status, &flags };
    QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a);
}

QVariant QmlPointValueType::value()
{
    return QVariant(point);
}

void QmlPointValueType::setValue(QVariant value)
{
    point = qvariant_cast<QPoint>(value);
}

int QmlPointValueType::x() const
{
    return point.x();
}

int QmlPointValueType::y() const
{
    return point.y();
}

void QmlPointValueType::setX(int x)
{
    point.setX(x);
}

void QmlPointValueType::setY(int y)
{
    point.setY(y);
}

QmlSizeFValueType::QmlSizeFValueType(QObject *parent)
: QmlValueType(parent)
{
}

void QmlSizeFValueType::read(QObject *obj, int idx)
{
    void *a[] = { &size, 0 };
    QMetaObject::metacall(obj, QMetaObject::ReadProperty, idx, a);
}

void QmlSizeFValueType::write(QObject *obj, int idx, QmlMetaProperty::WriteFlags flags)
{
    int status = -1;
    void *a[] = { &size, 0, &status, &flags };
    QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a);
}

QVariant QmlSizeFValueType::value()
{
    return QVariant(size);
}

void QmlSizeFValueType::setValue(QVariant value)
{
    size = qvariant_cast<QSizeF>(value);
}

qreal QmlSizeFValueType::width() const
{
    return size.width();
}

qreal QmlSizeFValueType::height() const
{
    return size.height();
}

void QmlSizeFValueType::setWidth(qreal w)
{
    size.setWidth(w);
}

void QmlSizeFValueType::setHeight(qreal h)
{
    size.setHeight(h);
}

QmlSizeValueType::QmlSizeValueType(QObject *parent)
: QmlValueType(parent)
{
}

void QmlSizeValueType::read(QObject *obj, int idx)
{
    void *a[] = { &size, 0 };
    QMetaObject::metacall(obj, QMetaObject::ReadProperty, idx, a);
}

void QmlSizeValueType::write(QObject *obj, int idx, QmlMetaProperty::WriteFlags flags)
{
    int status = -1;
    void *a[] = { &size, 0, &status, &flags };
    QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a);
}

QVariant QmlSizeValueType::value()
{
    return QVariant(size);
}

void QmlSizeValueType::setValue(QVariant value)
{
    size = qvariant_cast<QSize>(value);
}

int QmlSizeValueType::width() const
{
    return size.width();
}

int QmlSizeValueType::height() const
{
    return size.height();
}

void QmlSizeValueType::setWidth(int w)
{
    size.setWidth(w);
}

void QmlSizeValueType::setHeight(int h)
{
    size.setHeight(h);
}

QmlRectFValueType::QmlRectFValueType(QObject *parent)
: QmlValueType(parent)
{
}

void QmlRectFValueType::read(QObject *obj, int idx)
{
    void *a[] = { &rect, 0 };
    QMetaObject::metacall(obj, QMetaObject::ReadProperty, idx, a);
}

void QmlRectFValueType::write(QObject *obj, int idx, QmlMetaProperty::WriteFlags flags)
{
    int status = -1;
    void *a[] = { &rect, 0, &status, &flags };
    QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a);
}

QVariant QmlRectFValueType::value()
{
    return QVariant(rect);
}

void QmlRectFValueType::setValue(QVariant value)
{
    rect = qvariant_cast<QRectF>(value);
}

qreal QmlRectFValueType::x() const
{
    return rect.x();
}

qreal QmlRectFValueType::y() const
{
    return rect.y();
}

void QmlRectFValueType::setX(qreal x)
{
    rect.moveLeft(x);
}

void QmlRectFValueType::setY(qreal y)
{
    rect.moveTop(y);
}

qreal QmlRectFValueType::width() const
{
    return rect.width();
}

qreal QmlRectFValueType::height() const
{
    return rect.height();
}

void QmlRectFValueType::setWidth(qreal w)
{
    rect.setWidth(w);
}

void QmlRectFValueType::setHeight(qreal h)
{
    rect.setHeight(h);
}

QmlRectValueType::QmlRectValueType(QObject *parent)
: QmlValueType(parent)
{
}

void QmlRectValueType::read(QObject *obj, int idx)
{
    void *a[] = { &rect, 0 };
    QMetaObject::metacall(obj, QMetaObject::ReadProperty, idx, a);
}

void QmlRectValueType::write(QObject *obj, int idx, QmlMetaProperty::WriteFlags flags)
{
    int status = -1;
    void *a[] = { &rect, 0, &status, &flags };
    QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a);
}

QVariant QmlRectValueType::value()
{
    return QVariant(rect);
}

void QmlRectValueType::setValue(QVariant value)
{
    rect = qvariant_cast<QRect>(value);
}

int QmlRectValueType::x() const
{
    return rect.x();
}

int QmlRectValueType::y() const
{
    return rect.y();
}

void QmlRectValueType::setX(int x)
{
    rect.moveLeft(x);
}

void QmlRectValueType::setY(int y)
{
    rect.moveTop(y);
}

int QmlRectValueType::width() const
{
    return rect.width();
}

int QmlRectValueType::height() const
{
    return rect.height();
}

void QmlRectValueType::setWidth(int w)
{
    rect.setWidth(w);
}

void QmlRectValueType::setHeight(int h)
{
    rect.setHeight(h);
}

QmlVector3DValueType::QmlVector3DValueType(QObject *parent)
: QmlValueType(parent)
{
}

void QmlVector3DValueType::read(QObject *obj, int idx)
{
    void *a[] = { &vector, 0 };
    QMetaObject::metacall(obj, QMetaObject::ReadProperty, idx, a);
}

void QmlVector3DValueType::write(QObject *obj, int idx, QmlMetaProperty::WriteFlags flags)
{
    int status = -1;
    void *a[] = { &vector, 0, &status, &flags };
    QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a);
}

QVariant  QmlVector3DValueType::value()
{
    return QVariant(vector);
}

void QmlVector3DValueType::setValue(QVariant value)
{
    vector = qvariant_cast<QVector3D>(value);
}

qreal QmlVector3DValueType::x() const
{
    return vector.x();
}

qreal QmlVector3DValueType::y() const
{
    return vector.y();
}

qreal QmlVector3DValueType::z() const
{
    return vector.z();
}

void QmlVector3DValueType::setX(qreal x)
{
    vector.setX(x);
}

void QmlVector3DValueType::setY(qreal y)
{
    vector.setY(y);
}

void QmlVector3DValueType::setZ(qreal z)
{
    vector.setZ(z);
}

QmlFontValueType::QmlFontValueType(QObject *parent)
: QmlValueType(parent), hasPixelSize(false)
{
}

void QmlFontValueType::read(QObject *obj, int idx)
{
    void *a[] = { &font, 0 };
    QMetaObject::metacall(obj, QMetaObject::ReadProperty, idx, a);
}

void QmlFontValueType::write(QObject *obj, int idx, QmlMetaProperty::WriteFlags flags)
{
    int status = -1;
    void *a[] = { &font, 0, &status, &flags };
    QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a);
}

QVariant  QmlFontValueType::value()
{
    return QVariant(font);
}

void QmlFontValueType::setValue(QVariant value)
{
    font = qvariant_cast<QFont>(value);
}

QString QmlFontValueType::family() const
{
    return font.family();
}

void QmlFontValueType::setFamily(const QString &family)
{
    font.setFamily(family);
}

bool QmlFontValueType::bold() const
{
    return font.bold();
}

void QmlFontValueType::setBold(bool b)
{
    font.setBold(b);
}

QmlFontValueType::FontWeight QmlFontValueType::weight() const
{
    return (QmlFontValueType::FontWeight)font.weight();
}

void QmlFontValueType::setWeight(QmlFontValueType::FontWeight w)
{
    font.setWeight((QFont::Weight)w);
}

bool QmlFontValueType::italic() const
{
    return font.italic();
}

void QmlFontValueType::setItalic(bool b)
{
    font.setItalic(b);
}

bool QmlFontValueType::underline() const
{
    return font.underline();
}

void QmlFontValueType::setUnderline(bool b)
{
    font.setUnderline(b);
}

bool QmlFontValueType::overline() const
{
    return font.overline();
}

void QmlFontValueType::setOverline(bool b)
{
    font.setOverline(b);
}

bool QmlFontValueType::strikeout() const
{
    return font.strikeOut();
}

void QmlFontValueType::setStrikeout(bool b)
{
    font.setStrikeOut(b);
}

qreal QmlFontValueType::pointSize() const
{
    return font.pointSizeF();
}

void QmlFontValueType::setPointSize(qreal size)
{
    if (hasPixelSize) {
        qWarning() << "Both point size and pixel size set. Using pixel size.";
        return;
    }
    font.setPointSizeF(size);
}

int QmlFontValueType::pixelSize() const
{
    return font.pixelSize();
}

void QmlFontValueType::setPixelSize(int size)
{
    font.setPixelSize(size);
    hasPixelSize = true;
}

QmlFontValueType::Capitalization QmlFontValueType::capitalization() const
{
    return (QmlFontValueType::Capitalization)font.capitalization();
}

void QmlFontValueType::setCapitalization(QmlFontValueType::Capitalization c)
{
    font.setCapitalization((QFont::Capitalization)c);
}

qreal QmlFontValueType::letterSpacing() const
{
    return font.letterSpacing();
}

void QmlFontValueType::setLetterSpacing(qreal size)
{
    font.setLetterSpacing(QFont::PercentageSpacing, size);
}

qreal QmlFontValueType::wordSpacing() const
{
    return font.wordSpacing();
}

void QmlFontValueType::setWordSpacing(qreal size)
{
    font.setWordSpacing(size);
}

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

#include "qmlvaluetype_p.h"

#include <QtCore/qdebug.h>

QT_BEGIN_NAMESPACE

QmlValueTypeFactory::QmlValueTypeFactory()
{
    // ### Optimize
    for (unsigned int ii = 0; ii < (QVariant::UserType - 1); ++ii)
        valueTypes[ii] = valueType(ii);
}

QmlValueTypeFactory::~QmlValueTypeFactory()
{
    for (unsigned int ii = 0; ii < (QVariant::UserType - 1); ++ii)
        delete valueTypes[ii];
}

QmlValueType *QmlValueTypeFactory::valueType(int t)
{
    switch (t) {
    case QVariant::Point:
        return new QmlPointValueType;
    case QVariant::PointF:
        return new QmlPointFValueType;
    case QVariant::Size:
        return new QmlSizeValueType;
    case QVariant::SizeF:
        return new QmlSizeFValueType;
    case QVariant::Rect:
        return new QmlRectValueType;
    case QVariant::RectF:
        return new QmlRectFValueType;
    case QVariant::Vector3D:
        return new QmlVector3DValueType;
    case QVariant::Font:
        return new QmlFontValueType;
    default:
        return 0;
    }
}

QmlValueType::QmlValueType(QObject *parent)
: QObject(parent)
{
}

QmlPointFValueType::QmlPointFValueType(QObject *parent)
: QmlValueType(parent)
{
}

void QmlPointFValueType::read(QObject *obj, int idx)
{
    void *a[] = { &point, 0 };
    QMetaObject::metacall(obj, QMetaObject::ReadProperty, idx, a);
}

void QmlPointFValueType::write(QObject *obj, int idx, QmlMetaProperty::WriteFlags flags)
{
    int status = -1;
    void *a[] = { &point, 0, &status, &flags };
    QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a);
}

QVariant QmlPointFValueType::value()
{
    return QVariant(point);
}

void QmlPointFValueType::setValue(QVariant value)
{
    point = qvariant_cast<QPointF>(value);
}

qreal QmlPointFValueType::x() const
{
    return point.x();
}

qreal QmlPointFValueType::y() const
{
    return point.y();
}

void QmlPointFValueType::setX(qreal x)
{
    point.setX(x);
}

void QmlPointFValueType::setY(qreal y)
{
    point.setY(y);
}

QmlPointValueType::QmlPointValueType(QObject *parent)
: QmlValueType(parent)
{
}

void QmlPointValueType::read(QObject *obj, int idx)
{
    void *a[] = { &point, 0 };
    QMetaObject::metacall(obj, QMetaObject::ReadProperty, idx, a);
}

void QmlPointValueType::write(QObject *obj, int idx, QmlMetaProperty::WriteFlags flags)
{
    int status = -1;
    void *a[] = { &point, 0, &status, &flags };
    QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a);
}

QVariant QmlPointValueType::value()
{
    return QVariant(point);
}

void QmlPointValueType::setValue(QVariant value)
{
    point = qvariant_cast<QPoint>(value);
}

int QmlPointValueType::x() const
{
    return point.x();
}

int QmlPointValueType::y() const
{
    return point.y();
}

void QmlPointValueType::setX(int x)
{
    point.setX(x);
}

void QmlPointValueType::setY(int y)
{
    point.setY(y);
}

QmlSizeFValueType::QmlSizeFValueType(QObject *parent)
: QmlValueType(parent)
{
}

void QmlSizeFValueType::read(QObject *obj, int idx)
{
    void *a[] = { &size, 0 };
    QMetaObject::metacall(obj, QMetaObject::ReadProperty, idx, a);
}

void QmlSizeFValueType::write(QObject *obj, int idx, QmlMetaProperty::WriteFlags flags)
{
    int status = -1;
    void *a[] = { &size, 0, &status, &flags };
    QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a);
}

QVariant QmlSizeFValueType::value()
{
    return QVariant(size);
}

void QmlSizeFValueType::setValue(QVariant value)
{
    size = qvariant_cast<QSizeF>(value);
}

qreal QmlSizeFValueType::width() const
{
    return size.width();
}

qreal QmlSizeFValueType::height() const
{
    return size.height();
}

void QmlSizeFValueType::setWidth(qreal w)
{
    size.setWidth(w);
}

void QmlSizeFValueType::setHeight(qreal h)
{
    size.setHeight(h);
}

QmlSizeValueType::QmlSizeValueType(QObject *parent)
: QmlValueType(parent)
{
}

void QmlSizeValueType::read(QObject *obj, int idx)
{
    void *a[] = { &size, 0 };
    QMetaObject::metacall(obj, QMetaObject::ReadProperty, idx, a);
}

void QmlSizeValueType::write(QObject *obj, int idx, QmlMetaProperty::WriteFlags flags)
{
    int status = -1;
    void *a[] = { &size, 0, &status, &flags };
    QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a);
}

QVariant QmlSizeValueType::value()
{
    return QVariant(size);
}

void QmlSizeValueType::setValue(QVariant value)
{
    size = qvariant_cast<QSize>(value);
}

int QmlSizeValueType::width() const
{
    return size.width();
}

int QmlSizeValueType::height() const
{
    return size.height();
}

void QmlSizeValueType::setWidth(int w)
{
    size.setWidth(w);
}

void QmlSizeValueType::setHeight(int h)
{
    size.setHeight(h);
}

QmlRectFValueType::QmlRectFValueType(QObject *parent)
: QmlValueType(parent)
{
}

void QmlRectFValueType::read(QObject *obj, int idx)
{
    void *a[] = { &rect, 0 };
    QMetaObject::metacall(obj, QMetaObject::ReadProperty, idx, a);
}

void QmlRectFValueType::write(QObject *obj, int idx, QmlMetaProperty::WriteFlags flags)
{
    int status = -1;
    void *a[] = { &rect, 0, &status, &flags };
    QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a);
}

QVariant QmlRectFValueType::value()
{
    return QVariant(rect);
}

void QmlRectFValueType::setValue(QVariant value)
{
    rect = qvariant_cast<QRectF>(value);
}

qreal QmlRectFValueType::x() const
{
    return rect.x();
}

qreal QmlRectFValueType::y() const
{
    return rect.y();
}

void QmlRectFValueType::setX(qreal x)
{
    rect.moveLeft(x);
}

void QmlRectFValueType::setY(qreal y)
{
    rect.moveTop(y);
}

qreal QmlRectFValueType::width() const
{
    return rect.width();
}

qreal QmlRectFValueType::height() const
{
    return rect.height();
}

void QmlRectFValueType::setWidth(qreal w)
{
    rect.setWidth(w);
}

void QmlRectFValueType::setHeight(qreal h)
{
    rect.setHeight(h);
}

QmlRectValueType::QmlRectValueType(QObject *parent)
: QmlValueType(parent)
{
}

void QmlRectValueType::read(QObject *obj, int idx)
{
    void *a[] = { &rect, 0 };
    QMetaObject::metacall(obj, QMetaObject::ReadProperty, idx, a);
}

void QmlRectValueType::write(QObject *obj, int idx, QmlMetaProperty::WriteFlags flags)
{
    int status = -1;
    void *a[] = { &rect, 0, &status, &flags };
    QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a);
}

QVariant QmlRectValueType::value()
{
    return QVariant(rect);
}

void QmlRectValueType::setValue(QVariant value)
{
    rect = qvariant_cast<QRect>(value);
}

int QmlRectValueType::x() const
{
    return rect.x();
}

int QmlRectValueType::y() const
{
    return rect.y();
}

void QmlRectValueType::setX(int x)
{
    rect.moveLeft(x);
}

void QmlRectValueType::setY(int y)
{
    rect.moveTop(y);
}

int QmlRectValueType::width() const
{
    return rect.width();
}

int QmlRectValueType::height() const
{
    return rect.height();
}

void QmlRectValueType::setWidth(int w)
{
    rect.setWidth(w);
}

void QmlRectValueType::setHeight(int h)
{
    rect.setHeight(h);
}

QmlVector3DValueType::QmlVector3DValueType(QObject *parent)
: QmlValueType(parent)
{
}

void QmlVector3DValueType::read(QObject *obj, int idx)
{
    void *a[] = { &vector, 0 };
    QMetaObject::metacall(obj, QMetaObject::ReadProperty, idx, a);
}

void QmlVector3DValueType::write(QObject *obj, int idx, QmlMetaProperty::WriteFlags flags)
{
    int status = -1;
    void *a[] = { &vector, 0, &status, &flags };
    QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a);
}

QVariant  QmlVector3DValueType::value()
{
    return QVariant(vector);
}

void QmlVector3DValueType::setValue(QVariant value)
{
    vector = qvariant_cast<QVector3D>(value);
}

qreal QmlVector3DValueType::x() const
{
    return vector.x();
}

qreal QmlVector3DValueType::y() const
{
    return vector.y();
}

qreal QmlVector3DValueType::z() const
{
    return vector.z();
}

void QmlVector3DValueType::setX(qreal x)
{
    vector.setX(x);
}

void QmlVector3DValueType::setY(qreal y)
{
    vector.setY(y);
}

void QmlVector3DValueType::setZ(qreal z)
{
    vector.setZ(z);
}

QmlFontValueType::QmlFontValueType(QObject *parent)
: QmlValueType(parent), hasPixelSize(false)
{
}

void QmlFontValueType::read(QObject *obj, int idx)
{
    void *a[] = { &font, 0 };
    QMetaObject::metacall(obj, QMetaObject::ReadProperty, idx, a);
}

void QmlFontValueType::write(QObject *obj, int idx, QmlMetaProperty::WriteFlags flags)
{
    int status = -1;
    void *a[] = { &font, 0, &status, &flags };
    QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a);
}

QVariant  QmlFontValueType::value()
{
    return QVariant(font);
}

void QmlFontValueType::setValue(QVariant value)
{
    font = qvariant_cast<QFont>(value);
}

QString QmlFontValueType::family() const
{
    return font.family();
}

void QmlFontValueType::setFamily(const QString &family)
{
    font.setFamily(family);
}

bool QmlFontValueType::bold() const
{
    return font.bold();
}

void QmlFontValueType::setBold(bool b)
{
    font.setBold(b);
}

QmlFontValueType::FontWeight QmlFontValueType::weight() const
{
    return (QmlFontValueType::FontWeight)font.weight();
}

void QmlFontValueType::setWeight(QmlFontValueType::FontWeight w)
{
    font.setWeight((QFont::Weight)w);
}

bool QmlFontValueType::italic() const
{
    return font.italic();
}

void QmlFontValueType::setItalic(bool b)
{
    font.setItalic(b);
}

bool QmlFontValueType::underline() const
{
    return font.underline();
}

void QmlFontValueType::setUnderline(bool b)
{
    font.setUnderline(b);
}

bool QmlFontValueType::overline() const
{
    return font.overline();
}

void QmlFontValueType::setOverline(bool b)
{
    font.setOverline(b);
}

bool QmlFontValueType::strikeout() const
{
    return font.strikeOut();
}

void QmlFontValueType::setStrikeout(bool b)
{
    font.setStrikeOut(b);
}

qreal QmlFontValueType::pointSize() const
{
    return font.pointSizeF();
}

void QmlFontValueType::setPointSize(qreal size)
{
    if (hasPixelSize) {
        qWarning() << "Both point size and pixel size set. Using pixel size.";
        return;
    }

    if (size >= 0.0)
        font.setPointSizeF(size);
}

int QmlFontValueType::pixelSize() const
{
    return font.pixelSize();
}

void QmlFontValueType::setPixelSize(int size)
{
    if (size >=0) {
        font.setPixelSize(size);
        hasPixelSize = true;
    } else {
        hasPixelSize = false;
    }
}

QmlFontValueType::Capitalization QmlFontValueType::capitalization() const
{
    return (QmlFontValueType::Capitalization)font.capitalization();
}

void QmlFontValueType::setCapitalization(QmlFontValueType::Capitalization c)
{
    font.setCapitalization((QFont::Capitalization)c);
}

qreal QmlFontValueType::letterSpacing() const
{
    return font.letterSpacing();
}

void QmlFontValueType::setLetterSpacing(qreal size)
{
    font.setLetterSpacing(QFont::PercentageSpacing, size);
}

qreal QmlFontValueType::wordSpacing() const
{
    return font.wordSpacing();
}

void QmlFontValueType::setWordSpacing(qreal size)
{
    font.setWordSpacing(size);
}

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

// mapnik
#include <mapnik/debug.hpp>
#include <mapnik/global.hpp>
#include <mapnik/wkb.hpp>
#include <mapnik/geom_util.hpp>
#include <mapnik/feature.hpp>

// boost
#include <boost/utility.hpp>
#include <boost/format.hpp>

namespace mapnik
{
struct wkb_reader : boost::noncopyable
{
private:
    enum wkbByteOrder {
        wkbXDR=0,
        wkbNDR=1
    };

    const char* wkb_;
    unsigned size_;
    unsigned pos_;
    wkbByteOrder byteOrder_;
    bool needSwap_;
    wkbFormat format_;

public:

    enum wkbGeometryType {
        wkbPoint=1,
        wkbLineString=2,
        wkbPolygon=3,
        wkbMultiPoint=4,
        wkbMultiLineString=5,
        wkbMultiPolygon=6,
        wkbGeometryCollection=7,
        wkbPointZ=1001,
        wkbLineStringZ=1002,
        wkbPolygonZ=1003,
        wkbMultiPointZ=1004,
        wkbMultiLineStringZ=1005,
        wkbMultiPolygonZ=1006,
        wkbGeometryCollectionZ=1007
    };

    wkb_reader(const char* wkb, unsigned size, wkbFormat format)
        : wkb_(wkb),
          size_(size),
          pos_(0),
          format_(format)
    {
        // try to determine WKB format automatically
        if (format_ == wkbAuto)
        {
            if (size >= 44
                && (unsigned char)(wkb_[0]) == (unsigned char)(0x00)
                && (unsigned char)(wkb_[38]) == (unsigned char)(0x7C))
            {
                format_ = wkbSpatiaLite;
            }
            else
            {
                format_ = wkbGeneric;
            }
        }

        switch (format_)
        {
        case wkbSpatiaLite:
            byteOrder_ = (wkbByteOrder) wkb_[1];
            pos_ = 39;
            break;

        case wkbGeneric:
        default:
            byteOrder_ = (wkbByteOrder) wkb_[0];
            pos_ = 1;
            break;
        }

#ifndef MAPNIK_BIG_ENDIAN
        needSwap_ = byteOrder_ ? wkbXDR : wkbNDR;
#else
        needSwap_ = byteOrder_ ? wkbNDR : wkbXDR;
#endif
    }

    void read(boost::ptr_vector<geometry_type> & paths)
    {
        int type = read_integer();

#ifdef MAPNIK_LOG
        MAPNIK_LOG_DEBUG(wkb_reader) << "wkb_reader: Read=" << wkb_geometry_type_string(type) << "," << type;
#endif
        switch (type)
        {
        case wkbPoint:
            read_point(paths);
            break;
        case wkbLineString:
            read_linestring(paths);
            break;
        case wkbPolygon:
            read_polygon(paths);
            break;
        case wkbMultiPoint:
            read_multipoint(paths);
            break;
        case wkbMultiLineString:
            read_multilinestring(paths);
            break;
        case wkbMultiPolygon:
            read_multipolygon(paths);
            break;
        case wkbGeometryCollection:
            read_collection(paths);
            break;
        case wkbPointZ:
            read_point_xyz(paths);
            break;
        case wkbLineStringZ:
            read_linestring_xyz(paths);
            break;
        case wkbPolygonZ:
            read_polygon_xyz(paths);
            break;
        case wkbMultiPointZ:
            read_multipoint_xyz(paths);
            break;
        case wkbMultiLineStringZ:
            read_multilinestring_xyz(paths);
            break;
        case wkbMultiPolygonZ:
            read_multipolygon_xyz(paths);
            break;
        case wkbGeometryCollectionZ:
            read_collection(paths);
            break;
        default:
            break;
        }
    }

private:

    int read_integer()
    {
        boost::int32_t n;
        if (needSwap_)
        {
            read_int32_xdr(wkb_ + pos_, n);
        }
        else
        {
            read_int32_ndr(wkb_ + pos_, n);
        }
        pos_ += 4;

        return n;
    }

    double read_double()
    {
        double d;
        if (needSwap_)
        {
            read_double_xdr(wkb_ + pos_, d);
        }
        else
        {
            read_double_ndr(wkb_ + pos_, d);
        }
        pos_ += 8;

        return d;
    }

    void read_coords(CoordinateArray& ar)
    {
        if (! needSwap_)
        {
            for (unsigned i = 0; i < ar.size(); ++i)
            {
                read_double_ndr(wkb_ + pos_, ar[i].x);
                read_double_ndr(wkb_ + pos_ + 8, ar[i].y);
                pos_ += 16; // skip XY
            }
        }
        else
        {
            for (unsigned i=0;i<ar.size();++i)
            {
                read_double_xdr(wkb_ + pos_, ar[i].x);
                read_double_xdr(wkb_ + pos_ + 8, ar[i].y);
                pos_ += 16; // skip XY
            }
        }
    }

    void read_coords_xyz(CoordinateArray& ar)
    {
        if (! needSwap_)
        {
            for (unsigned i = 0; i < ar.size(); ++i)
            {
                read_double_ndr(wkb_ + pos_, ar[i].x);
                read_double_ndr(wkb_ + pos_ + 8, ar[i].y);
                pos_ += 24; // skip XYZ
            }
        }
        else
        {
            for (unsigned i = 0; i < ar.size(); ++i)
            {
                read_double_xdr(wkb_ + pos_, ar[i].x);
                read_double_xdr(wkb_ + pos_ + 8, ar[i].y);
                pos_ += 24; // skip XYZ
            }
        }
    }

    void read_point(boost::ptr_vector<geometry_type> & paths)
    {
        geometry_type* pt = new geometry_type(Point);
        double x = read_double();
        double y = read_double();
        pt->move_to(x, y);
        paths.push_back(pt);
    }

    void read_multipoint(boost::ptr_vector<geometry_type> & paths)
    {
        int num_points = read_integer();
        for (int i = 0; i < num_points; ++i)
        {
            pos_ += 5;
            read_point(paths);
        }
    }

    void read_point_xyz(boost::ptr_vector<geometry_type> & paths)
    {
        geometry_type* pt = new geometry_type(Point);
        double x = read_double();
        double y = read_double();
        pos_ += 8; // double z = read_double();
        pt->move_to(x, y);
        paths.push_back(pt);
    }

    void read_multipoint_xyz(boost::ptr_vector<geometry_type> & paths)
    {
        int num_points = read_integer();
        for (int i = 0; i < num_points; ++i)
        {
            pos_ += 5;
            read_point_xyz(paths);
        }
    }

    void read_linestring(boost::ptr_vector<geometry_type> & paths)
    {
        geometry_type* line = new geometry_type(LineString);
        int num_points = read_integer();
        CoordinateArray ar(num_points);
        read_coords(ar);
        line->move_to(ar[0].x, ar[0].y);
        for (int i = 1; i < num_points; ++i)
        {
            line->line_to(ar[i].x, ar[i].y);
        }
        paths.push_back(line);
    }

    void read_multilinestring(boost::ptr_vector<geometry_type> & paths)
    {
        int num_lines = read_integer();
        for (int i = 0; i < num_lines; ++i)
        {
            pos_ += 5;
            read_linestring(paths);
        }
    }

    void read_linestring_xyz(boost::ptr_vector<geometry_type> & paths)
    {
        geometry_type* line = new geometry_type(LineString);
        int num_points = read_integer();
        CoordinateArray ar(num_points);
        read_coords_xyz(ar);
        line->move_to(ar[0].x, ar[0].y);
        for (int i = 1; i < num_points; ++i)
        {
            line->line_to(ar[i].x, ar[i].y);
        }
        paths.push_back(line);
    }

    void read_multilinestring_xyz(boost::ptr_vector<geometry_type> & paths)
    {
        int num_lines = read_integer();
        for (int i = 0; i < num_lines; ++i)
        {
            pos_ += 5;
            read_linestring_xyz(paths);
        }
    }

    void read_polygon(boost::ptr_vector<geometry_type> & paths)
    {
        geometry_type* poly = new geometry_type(Polygon);
        int num_rings = read_integer();
        unsigned capacity = 0;
        for (int i = 0; i < num_rings; ++i)
        {
            int num_points = read_integer();
            capacity += num_points;
            CoordinateArray ar(num_points);
            read_coords(ar);
            poly->move_to(ar[0].x, ar[0].y);
            for (int j = 1; j < num_points; ++j)
            {
                poly->line_to(ar[j].x, ar[j].y);
            }
        }
        paths.push_back(poly);
    }

    void read_multipolygon(boost::ptr_vector<geometry_type> & paths)
    {
        int num_polys = read_integer();
        for (int i = 0; i < num_polys; ++i)
        {
            pos_ += 5;
            read_polygon(paths);
        }
    }

    void read_polygon_xyz(boost::ptr_vector<geometry_type> & paths)
    {
        geometry_type* poly = new geometry_type(Polygon);
        int num_rings = read_integer();
        unsigned capacity = 0;
        for (int i = 0; i < num_rings; ++i)
        {
            int num_points = read_integer();
            capacity += num_points;
            CoordinateArray ar(num_points);
            read_coords_xyz(ar);
            poly->move_to(ar[0].x, ar[0].y);
            for (int j = 1; j < num_points; ++j)
            {
                poly->line_to(ar[j].x, ar[j].y);
            }
        }
        paths.push_back(poly);
    }

    void read_multipolygon_xyz(boost::ptr_vector<geometry_type> & paths)
    {
        int num_polys = read_integer();
        for (int i = 0; i < num_polys; ++i)
        {
            pos_ += 5;
            read_polygon_xyz(paths);
        }
    }

    void read_collection(boost::ptr_vector<geometry_type> & paths)
    {
        int num_geometries = read_integer();
        for (int i = 0; i < num_geometries; ++i)
        {
            pos_ += 1; // skip byte order
            read(paths);
        }
    }

#ifdef MAPNIK_LOG
    std::string wkb_geometry_type_string(int type)
    {
        std::stringstream s;

        switch (type)
        {
        case wkbPoint:               s << "wkbPoint"; break;
        case wkbLineString:          s << "wkbLineString"; break;
        case wkbPolygon:             s << "wkbPolygon"; break;
        case wkbMultiPoint:          s << "wkbMultiPoint"; break;
        case wkbMultiLineString:     s << "wkbMultiLineString"; break;
        case wkbMultiPolygon:        s << "wkbMultiPolygon"; break;
        case wkbGeometryCollection:  s << "wkbGeometryCollection"; break;
        case wkbPointZ:              s << "wkbPointZ"; break;
        case wkbLineStringZ:         s << "wkbLineStringZ"; break;
        case wkbPolygonZ:            s << "wkbPolygonZ"; break;
        case wkbMultiPointZ:         s << "wkbMultiPointZ"; break;
        case wkbMultiLineStringZ:    s << "wkbMultiLineStringZ"; break;
        case wkbMultiPolygonZ:       s << "wkbMultiPolygonZ"; break;
        case wkbGeometryCollectionZ: s << "wkbGeometryCollectionZ"; break;
        default:                     s << "wkbUknown"; break;
        }

        return s.str();
    }
#endif
};

void geometry_utils::from_wkb (boost::ptr_vector<geometry_type>& paths,
                               const char* wkb,
                               unsigned size,
                               wkbFormat format)
{
    wkb_reader reader(wkb, size, format);
    return reader.read(paths);
}

}
<commit_msg>+ use member variable in ctor<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
 *
 *****************************************************************************/

// mapnik
#include <mapnik/debug.hpp>
#include <mapnik/global.hpp>
#include <mapnik/wkb.hpp>
#include <mapnik/geom_util.hpp>
#include <mapnik/feature.hpp>

// boost
#include <boost/utility.hpp>
#include <boost/format.hpp>

namespace mapnik
{
struct wkb_reader : boost::noncopyable
{
private:
    enum wkbByteOrder {
        wkbXDR=0,
        wkbNDR=1
    };

    const char* wkb_;
    unsigned size_;
    unsigned pos_;
    wkbByteOrder byteOrder_;
    bool needSwap_;
    wkbFormat format_;

public:

    enum wkbGeometryType {
        wkbPoint=1,
        wkbLineString=2,
        wkbPolygon=3,
        wkbMultiPoint=4,
        wkbMultiLineString=5,
        wkbMultiPolygon=6,
        wkbGeometryCollection=7,
        wkbPointZ=1001,
        wkbLineStringZ=1002,
        wkbPolygonZ=1003,
        wkbMultiPointZ=1004,
        wkbMultiLineStringZ=1005,
        wkbMultiPolygonZ=1006,
        wkbGeometryCollectionZ=1007
    };

    wkb_reader(const char* wkb, unsigned size, wkbFormat format)
        : wkb_(wkb),
          size_(size),
          pos_(0),
          format_(format)
    {
        // try to determine WKB format automatically
        if (format_ == wkbAuto)
        {
            if (size_ >= 44
                && (unsigned char)(wkb_[0]) == (unsigned char)(0x00)
                && (unsigned char)(wkb_[38]) == (unsigned char)(0x7C))
            {
                format_ = wkbSpatiaLite;
            }
            else
            {
                format_ = wkbGeneric;
            }
        }

        switch (format_)
        {
        case wkbSpatiaLite:
            byteOrder_ = (wkbByteOrder) wkb_[1];
            pos_ = 39;
            break;

        case wkbGeneric:
        default:
            byteOrder_ = (wkbByteOrder) wkb_[0];
            pos_ = 1;
            break;
        }

#ifndef MAPNIK_BIG_ENDIAN
        needSwap_ = byteOrder_ ? wkbXDR : wkbNDR;
#else
        needSwap_ = byteOrder_ ? wkbNDR : wkbXDR;
#endif
    }

    void read(boost::ptr_vector<geometry_type> & paths)
    {
        int type = read_integer();

#ifdef MAPNIK_LOG
        MAPNIK_LOG_DEBUG(wkb_reader) << "wkb_reader: Read=" << wkb_geometry_type_string(type) << "," << type;
#endif
        switch (type)
        {
        case wkbPoint:
            read_point(paths);
            break;
        case wkbLineString:
            read_linestring(paths);
            break;
        case wkbPolygon:
            read_polygon(paths);
            break;
        case wkbMultiPoint:
            read_multipoint(paths);
            break;
        case wkbMultiLineString:
            read_multilinestring(paths);
            break;
        case wkbMultiPolygon:
            read_multipolygon(paths);
            break;
        case wkbGeometryCollection:
            read_collection(paths);
            break;
        case wkbPointZ:
            read_point_xyz(paths);
            break;
        case wkbLineStringZ:
            read_linestring_xyz(paths);
            break;
        case wkbPolygonZ:
            read_polygon_xyz(paths);
            break;
        case wkbMultiPointZ:
            read_multipoint_xyz(paths);
            break;
        case wkbMultiLineStringZ:
            read_multilinestring_xyz(paths);
            break;
        case wkbMultiPolygonZ:
            read_multipolygon_xyz(paths);
            break;
        case wkbGeometryCollectionZ:
            read_collection(paths);
            break;
        default:
            break;
        }
    }

private:

    int read_integer()
    {
        boost::int32_t n;
        if (needSwap_)
        {
            read_int32_xdr(wkb_ + pos_, n);
        }
        else
        {
            read_int32_ndr(wkb_ + pos_, n);
        }
        pos_ += 4;

        return n;
    }

    double read_double()
    {
        double d;
        if (needSwap_)
        {
            read_double_xdr(wkb_ + pos_, d);
        }
        else
        {
            read_double_ndr(wkb_ + pos_, d);
        }
        pos_ += 8;

        return d;
    }

    void read_coords(CoordinateArray& ar)
    {
        if (! needSwap_)
        {
            for (unsigned i = 0; i < ar.size(); ++i)
            {
                read_double_ndr(wkb_ + pos_, ar[i].x);
                read_double_ndr(wkb_ + pos_ + 8, ar[i].y);
                pos_ += 16; // skip XY
            }
        }
        else
        {
            for (unsigned i=0;i<ar.size();++i)
            {
                read_double_xdr(wkb_ + pos_, ar[i].x);
                read_double_xdr(wkb_ + pos_ + 8, ar[i].y);
                pos_ += 16; // skip XY
            }
        }
    }

    void read_coords_xyz(CoordinateArray& ar)
    {
        if (! needSwap_)
        {
            for (unsigned i = 0; i < ar.size(); ++i)
            {
                read_double_ndr(wkb_ + pos_, ar[i].x);
                read_double_ndr(wkb_ + pos_ + 8, ar[i].y);
                pos_ += 24; // skip XYZ
            }
        }
        else
        {
            for (unsigned i = 0; i < ar.size(); ++i)
            {
                read_double_xdr(wkb_ + pos_, ar[i].x);
                read_double_xdr(wkb_ + pos_ + 8, ar[i].y);
                pos_ += 24; // skip XYZ
            }
        }
    }

    void read_point(boost::ptr_vector<geometry_type> & paths)
    {
        geometry_type* pt = new geometry_type(Point);
        double x = read_double();
        double y = read_double();
        pt->move_to(x, y);
        paths.push_back(pt);
    }

    void read_multipoint(boost::ptr_vector<geometry_type> & paths)
    {
        int num_points = read_integer();
        for (int i = 0; i < num_points; ++i)
        {
            pos_ += 5;
            read_point(paths);
        }
    }

    void read_point_xyz(boost::ptr_vector<geometry_type> & paths)
    {
        geometry_type* pt = new geometry_type(Point);
        double x = read_double();
        double y = read_double();
        pos_ += 8; // double z = read_double();
        pt->move_to(x, y);
        paths.push_back(pt);
    }

    void read_multipoint_xyz(boost::ptr_vector<geometry_type> & paths)
    {
        int num_points = read_integer();
        for (int i = 0; i < num_points; ++i)
        {
            pos_ += 5;
            read_point_xyz(paths);
        }
    }

    void read_linestring(boost::ptr_vector<geometry_type> & paths)
    {
        geometry_type* line = new geometry_type(LineString);
        int num_points = read_integer();
        CoordinateArray ar(num_points);
        read_coords(ar);
        line->move_to(ar[0].x, ar[0].y);
        for (int i = 1; i < num_points; ++i)
        {
            line->line_to(ar[i].x, ar[i].y);
        }
        paths.push_back(line);
    }

    void read_multilinestring(boost::ptr_vector<geometry_type> & paths)
    {
        int num_lines = read_integer();
        for (int i = 0; i < num_lines; ++i)
        {
            pos_ += 5;
            read_linestring(paths);
        }
    }

    void read_linestring_xyz(boost::ptr_vector<geometry_type> & paths)
    {
        geometry_type* line = new geometry_type(LineString);
        int num_points = read_integer();
        CoordinateArray ar(num_points);
        read_coords_xyz(ar);
        line->move_to(ar[0].x, ar[0].y);
        for (int i = 1; i < num_points; ++i)
        {
            line->line_to(ar[i].x, ar[i].y);
        }
        paths.push_back(line);
    }

    void read_multilinestring_xyz(boost::ptr_vector<geometry_type> & paths)
    {
        int num_lines = read_integer();
        for (int i = 0; i < num_lines; ++i)
        {
            pos_ += 5;
            read_linestring_xyz(paths);
        }
    }

    void read_polygon(boost::ptr_vector<geometry_type> & paths)
    {
        geometry_type* poly = new geometry_type(Polygon);
        int num_rings = read_integer();
        unsigned capacity = 0;
        for (int i = 0; i < num_rings; ++i)
        {
            int num_points = read_integer();
            capacity += num_points;
            CoordinateArray ar(num_points);
            read_coords(ar);
            poly->move_to(ar[0].x, ar[0].y);
            for (int j = 1; j < num_points; ++j)
            {
                poly->line_to(ar[j].x, ar[j].y);
            }
        }
        paths.push_back(poly);
    }

    void read_multipolygon(boost::ptr_vector<geometry_type> & paths)
    {
        int num_polys = read_integer();
        for (int i = 0; i < num_polys; ++i)
        {
            pos_ += 5;
            read_polygon(paths);
        }
    }

    void read_polygon_xyz(boost::ptr_vector<geometry_type> & paths)
    {
        geometry_type* poly = new geometry_type(Polygon);
        int num_rings = read_integer();
        unsigned capacity = 0;
        for (int i = 0; i < num_rings; ++i)
        {
            int num_points = read_integer();
            capacity += num_points;
            CoordinateArray ar(num_points);
            read_coords_xyz(ar);
            poly->move_to(ar[0].x, ar[0].y);
            for (int j = 1; j < num_points; ++j)
            {
                poly->line_to(ar[j].x, ar[j].y);
            }
        }
        paths.push_back(poly);
    }

    void read_multipolygon_xyz(boost::ptr_vector<geometry_type> & paths)
    {
        int num_polys = read_integer();
        for (int i = 0; i < num_polys; ++i)
        {
            pos_ += 5;
            read_polygon_xyz(paths);
        }
    }

    void read_collection(boost::ptr_vector<geometry_type> & paths)
    {
        int num_geometries = read_integer();
        for (int i = 0; i < num_geometries; ++i)
        {
            pos_ += 1; // skip byte order
            read(paths);
        }
    }

#ifdef MAPNIK_LOG
    std::string wkb_geometry_type_string(int type)
    {
        std::stringstream s;

        switch (type)
        {
        case wkbPoint:               s << "wkbPoint"; break;
        case wkbLineString:          s << "wkbLineString"; break;
        case wkbPolygon:             s << "wkbPolygon"; break;
        case wkbMultiPoint:          s << "wkbMultiPoint"; break;
        case wkbMultiLineString:     s << "wkbMultiLineString"; break;
        case wkbMultiPolygon:        s << "wkbMultiPolygon"; break;
        case wkbGeometryCollection:  s << "wkbGeometryCollection"; break;
        case wkbPointZ:              s << "wkbPointZ"; break;
        case wkbLineStringZ:         s << "wkbLineStringZ"; break;
        case wkbPolygonZ:            s << "wkbPolygonZ"; break;
        case wkbMultiPointZ:         s << "wkbMultiPointZ"; break;
        case wkbMultiLineStringZ:    s << "wkbMultiLineStringZ"; break;
        case wkbMultiPolygonZ:       s << "wkbMultiPolygonZ"; break;
        case wkbGeometryCollectionZ: s << "wkbGeometryCollectionZ"; break;
        default:                     s << "wkbUknown"; break;
        }

        return s.str();
    }
#endif
};

void geometry_utils::from_wkb (boost::ptr_vector<geometry_type>& paths,
                               const char* wkb,
                               unsigned size,
                               wkbFormat format)
{
    wkb_reader reader(wkb, size, format);
    return reader.read(paths);
}

}
<|endoftext|>