<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: controlpropertymap.cxx,v $
 *
 *  $Revision: 1.22 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 14:04:46 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 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
 *
 ************************************************************************/

#ifndef _XMLOFF_XMLNMSPE_HXX
#include "xmlnmspe.hxx"
#endif
#ifndef _XMLOFF_XMLTOKEN_HXX
#include "xmltoken.hxx"
#endif
#ifndef _XMLOFF_PROPMAPPINGTYPES_HXX
#include "maptype.hxx"
#endif
#ifndef _XMLOFF_XMLTYPES_HXX
#include "xmltypes.hxx"
#endif
#ifndef __SGI_STL_ALGORITHM
#include <algorithm>
#endif

#ifndef _XMLOFF_FORMS_STRINGS_HXX_
#include "strings.hxx"
#endif
#ifndef _XMLOFF_CONTEXTID_HXX_
#include "contextid.hxx"
#endif

#ifndef _XMLOFF_FORMS_CONTROLPROPERTYMAP_HXX_
#include "controlpropertymap.hxx"
#endif

#include <string.h>

using namespace ::xmloff::token;

//.........................................................................
namespace xmloff
{
//.........................................................................

#define MAP_ASCII( name, prefix, token, type, context )  { name, sizeof(name)-1, prefix, token, type|XML_TYPE_PROP_TEXT, context }
#define MAP_CONST( name, prefix, token, type, context )  { name.ascii, name.length, prefix, token, type|XML_TYPE_PROP_TEXT, context }
#define MAP_CONST_P( name, prefix, token, type, context )  { name.ascii, name.length,   prefix, token, type|XML_TYPE_PROP_PARAGRAPH, context }
#define MAP_END()   { NULL, 0, 0, XML_TOKEN_INVALID, 0 }

    XMLPropertyMapEntry* getControlStylePropertyMap_Access( )
    {
        static XMLPropertyMapEntry aControlStyleProperties[] =
        {
            MAP_CONST( PROPERTY_BACKGROUNDCOLOR, XML_NAMESPACE_FO,      XML_BACKGROUND_COLOR,       XML_TYPE_COLOR, 0 ),
            MAP_CONST_P( PROPERTY_ALIGN,          XML_NAMESPACE_FO,       XML_TEXT_ALIGN,             XML_TYPE_TEXT_ALIGN, 0 ),
            MAP_CONST( PROPERTY_BORDER,         XML_NAMESPACE_FO,       XML_BORDER,                 XML_TYPE_CONTROL_BORDER|MID_FLAG_MULTI_PROPERTY|MID_FLAG_MERGE_ATTRIBUTE, 0 ),
            MAP_ASCII( "FontCharWidth",         XML_NAMESPACE_STYLE,    XML_FONT_CHAR_WIDTH,        XML_TYPE_NUMBER16, 0 ),
            MAP_ASCII( "FontCharset",           XML_NAMESPACE_STYLE,    XML_FONT_CHARSET,           XML_TYPE_TEXT_FONTENCODING, 0 ),
            MAP_ASCII( "FontFamily",            XML_NAMESPACE_STYLE,    XML_FONT_FAMILY_GENERIC,    XML_TYPE_TEXT_FONTFAMILY, 0 ),
            MAP_ASCII( "FontHeight",            XML_NAMESPACE_FO,       XML_FONT_SIZE,              XML_TYPE_CHAR_HEIGHT, 0 ),
            MAP_ASCII( "FontKerning",           XML_NAMESPACE_STYLE,    XML_LETTER_KERNING,         XML_TYPE_BOOL, 0 ),
            MAP_ASCII( "FontName",              XML_NAMESPACE_STYLE,    XML_FONT_NAME,              XML_TYPE_STRING, 0 ),
            MAP_ASCII( "FontOrientation",       XML_NAMESPACE_STYLE,    XML_ROTATION_ANGLE,         XML_TYPE_ROTATION_ANGLE, 0 ),
            MAP_ASCII( "FontPitch",             XML_NAMESPACE_STYLE,    XML_FONT_PITCH,             XML_TYPE_TEXT_FONTPITCH, 0 ),
            MAP_ASCII( "FontSlant",             XML_NAMESPACE_FO,       XML_FONT_STYLE,             XML_TYPE_TEXT_POSTURE, 0 ),

            MAP_ASCII( "FontStrikeout",         XML_NAMESPACE_STYLE,    XML_TEXT_LINE_THROUGH_STYLE,    XML_TYPE_TEXT_CROSSEDOUT_STYLE|MID_FLAG_MERGE_PROPERTY, 0),
            MAP_ASCII( "FontStrikeout",         XML_NAMESPACE_STYLE,    XML_TEXT_LINE_THROUGH_TYPE,     XML_TYPE_TEXT_CROSSEDOUT_TYPE|MID_FLAG_MERGE_PROPERTY,  0),
            MAP_ASCII( "FontStrikeout",         XML_NAMESPACE_STYLE,    XML_TEXT_LINE_THROUGH_WIDTH,    XML_TYPE_TEXT_CROSSEDOUT_WIDTH|MID_FLAG_MERGE_PROPERTY, 0),
            MAP_ASCII( "FontStrikeout",         XML_NAMESPACE_STYLE,    XML_TEXT_LINE_THROUGH_TEXT,     XML_TYPE_TEXT_CROSSEDOUT_TEXT|MID_FLAG_MERGE_PROPERTY,  0),

            MAP_ASCII( "FontStyleName",         XML_NAMESPACE_STYLE,    XML_FONT_STYLE_NAME,        XML_TYPE_STRING, 0 ),
            MAP_ASCII( "FontUnderline",         XML_NAMESPACE_STYLE,    XML_TEXT_UNDERLINE_STYLE,       XML_TYPE_TEXT_UNDERLINE_STYLE|MID_FLAG_MERGE_PROPERTY, 0 ),
            MAP_ASCII( "FontUnderline",         XML_NAMESPACE_STYLE,    XML_TEXT_UNDERLINE_TYPE,        XML_TYPE_TEXT_UNDERLINE_TYPE|MID_FLAG_MERGE_PROPERTY, 0 ),
            MAP_ASCII( "FontUnderline",         XML_NAMESPACE_STYLE,    XML_TEXT_UNDERLINE_WIDTH,       XML_TYPE_TEXT_UNDERLINE_WIDTH|MID_FLAG_MERGE_PROPERTY, 0 ),
            MAP_ASCII( "FontWeight",            XML_NAMESPACE_FO,       XML_FONT_WEIGHT,            XML_TYPE_TEXT_WEIGHT, 0 ),
            MAP_ASCII( "FontWidth",             XML_NAMESPACE_STYLE,    XML_FONT_WIDTH,             XML_TYPE_FONT_WIDTH, 0 ),
            MAP_ASCII( "FontWordLineMode",      XML_NAMESPACE_FO,       XML_SCORE_SPACES,           XML_TYPE_NBOOL, 0 ),
            MAP_ASCII( "SymbolColor",           XML_NAMESPACE_STYLE,    XML_COLOR,                  XML_TYPE_COLOR, 0 ),
            MAP_ASCII( "BorderColor",           XML_NAMESPACE_FO,       XML_BORDER,                 XML_TYPE_CONTROL_BORDER_COLOR|MID_FLAG_MULTI_PROPERTY|MID_FLAG_MERGE_ATTRIBUTE, 0 ),
            MAP_ASCII( "TextColor",             XML_NAMESPACE_FO,       XML_COLOR,                  XML_TYPE_COLOR, 0 ),
            MAP_CONST( PROPERTY_FORMATKEY,      XML_NAMESPACE_STYLE,    XML_DATA_STYLE_NAME,        XML_TYPE_STRING | MID_FLAG_NO_PROPERTY_EXPORT | MID_FLAG_SPECIAL_ITEM, CTF_FORMS_DATA_STYLE ),
            MAP_ASCII( "FontEmphasisMark",      XML_NAMESPACE_STYLE,    XML_TEXT_EMPHASIZE,         XML_TYPE_CONTROL_TEXT_EMPHASIZE, 0 ),
            MAP_ASCII( "FontRelief",            XML_NAMESPACE_STYLE,    XML_FONT_RELIEF,            XML_TYPE_TEXT_FONT_RELIEF|MID_FLAG_MULTI_PROPERTY, 0 ),
            MAP_ASCII( "TextLineColor",         XML_NAMESPACE_STYLE,    XML_TEXT_UNDERLINE_COLOR,   XML_TYPE_TEXT_UNDERLINE_COLOR|MID_FLAG_MULTI_PROPERTY, 0 ),
            MAP_END()
        };

        return aControlStyleProperties;
    }

    const XMLPropertyMapEntry* getControlStylePropertyMap( )
    {
        return getControlStylePropertyMap_Access();
    }

    //=====================================================================
    //---------------------------------------------------------------------
    struct XMLPropertyMapEntryLess
    {
        sal_Bool operator()(const XMLPropertyMapEntry& _rLeft, const XMLPropertyMapEntry& _rRight)
        {
            return strcmp(_rLeft.msApiName, _rRight.msApiName) < 0;
        }
    };

    //---------------------------------------------------------------------
    void implSortMap(XMLPropertyMapEntry* _pMap)
    {
        XMLPropertyMapEntry* pEnd;
        // determine the last element
        for ( pEnd = _pMap; pEnd->msApiName; ++pEnd)
            ;
        ::std::sort(_pMap, pEnd, XMLPropertyMapEntryLess());
    }

    //---------------------------------------------------------------------
    void initializePropertyMaps()
    {
        static sal_Bool bSorted = sal_False;
        if (!bSorted)
        {
            implSortMap(getControlStylePropertyMap_Access());
            bSorted = sal_True;
        }
    }

    //=====================================================================
    //= OFormExportPropertyMapper
    //=====================================================================
    //---------------------------------------------------------------------
    OFormExportPropertyMapper::OFormExportPropertyMapper( const UniReference< XMLPropertySetMapper >& _rMapper )
        :SvXMLExportPropertyMapper( _rMapper )
    {
    }

    //---------------------------------------------------------------------
    void OFormExportPropertyMapper::handleSpecialItem( SvXMLAttributeList& _rAttrList, const XMLPropertyState& _rProperty, const SvXMLUnitConverter& _rUnitConverter,
        const SvXMLNamespaceMap& _rNamespaceMap, const ::std::vector< XMLPropertyState >* _pProperties,
        sal_uInt32 _nIdx ) const
    {
        // ignore the number style of grid columns - this is formatted elsewhere
        if ( CTF_FORMS_DATA_STYLE != getPropertySetMapper()->GetEntryContextId( _rProperty.mnIndex ) )
            SvXMLExportPropertyMapper::handleSpecialItem( _rAttrList, _rProperty, _rUnitConverter, _rNamespaceMap, _pProperties, _nIdx );
    }

//.........................................................................
}   // namespace xmloff
//.........................................................................

<commit_msg>INTEGRATION: CWS warnings01 (1.22.34); FILE MERGED 2005/11/16 22:47:09 pl 1.22.34.1: #i55991# removed warnings<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: controlpropertymap.cxx,v $
 *
 *  $Revision: 1.23 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-19 18:16:24 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 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
 *
 ************************************************************************/

#ifndef _XMLOFF_XMLNMSPE_HXX
#include "xmlnmspe.hxx"
#endif
#ifndef _XMLOFF_XMLTOKEN_HXX
#include "xmltoken.hxx"
#endif
#ifndef _XMLOFF_PROPMAPPINGTYPES_HXX
#include "maptype.hxx"
#endif
#ifndef _XMLOFF_XMLTYPES_HXX
#include "xmltypes.hxx"
#endif
#ifndef __SGI_STL_ALGORITHM
#include <algorithm>
#endif

#ifndef _XMLOFF_FORMS_STRINGS_HXX_
#include "strings.hxx"
#endif
#ifndef _XMLOFF_CONTEXTID_HXX_
#include "contextid.hxx"
#endif

#ifndef _XMLOFF_FORMS_CONTROLPROPERTYMAP_HXX_
#include "controlpropertymap.hxx"
#endif

#include <string.h>

using namespace ::xmloff::token;

//.........................................................................
namespace xmloff
{
//.........................................................................

#define MAP_ASCII( name, prefix, token, type, context )  { name, sizeof(name)-1, prefix, token, type|XML_TYPE_PROP_TEXT, context }
#define MAP_CONST( name, prefix, token, type, context )  { name.ascii, name.length, prefix, token, type|XML_TYPE_PROP_TEXT, context }
#define MAP_CONST_P( name, prefix, token, type, context )  { name.ascii, name.length,   prefix, token, type|XML_TYPE_PROP_PARAGRAPH, context }
#define MAP_END()   { NULL, 0, 0, XML_TOKEN_INVALID, 0, 0 }

    XMLPropertyMapEntry* getControlStylePropertyMap_Access( )
    {
        static XMLPropertyMapEntry aControlStyleProperties[] =
        {
            MAP_CONST( PROPERTY_BACKGROUNDCOLOR, XML_NAMESPACE_FO,      XML_BACKGROUND_COLOR,       XML_TYPE_COLOR, 0 ),
            MAP_CONST_P( PROPERTY_ALIGN,          XML_NAMESPACE_FO,       XML_TEXT_ALIGN,             XML_TYPE_TEXT_ALIGN, 0 ),
            MAP_CONST( PROPERTY_BORDER,         XML_NAMESPACE_FO,       XML_BORDER,                 XML_TYPE_CONTROL_BORDER|MID_FLAG_MULTI_PROPERTY|MID_FLAG_MERGE_ATTRIBUTE, 0 ),
            MAP_ASCII( "FontCharWidth",         XML_NAMESPACE_STYLE,    XML_FONT_CHAR_WIDTH,        XML_TYPE_NUMBER16, 0 ),
            MAP_ASCII( "FontCharset",           XML_NAMESPACE_STYLE,    XML_FONT_CHARSET,           XML_TYPE_TEXT_FONTENCODING, 0 ),
            MAP_ASCII( "FontFamily",            XML_NAMESPACE_STYLE,    XML_FONT_FAMILY_GENERIC,    XML_TYPE_TEXT_FONTFAMILY, 0 ),
            MAP_ASCII( "FontHeight",            XML_NAMESPACE_FO,       XML_FONT_SIZE,              XML_TYPE_CHAR_HEIGHT, 0 ),
            MAP_ASCII( "FontKerning",           XML_NAMESPACE_STYLE,    XML_LETTER_KERNING,         XML_TYPE_BOOL, 0 ),
            MAP_ASCII( "FontName",              XML_NAMESPACE_STYLE,    XML_FONT_NAME,              XML_TYPE_STRING, 0 ),
            MAP_ASCII( "FontOrientation",       XML_NAMESPACE_STYLE,    XML_ROTATION_ANGLE,         XML_TYPE_ROTATION_ANGLE, 0 ),
            MAP_ASCII( "FontPitch",             XML_NAMESPACE_STYLE,    XML_FONT_PITCH,             XML_TYPE_TEXT_FONTPITCH, 0 ),
            MAP_ASCII( "FontSlant",             XML_NAMESPACE_FO,       XML_FONT_STYLE,             XML_TYPE_TEXT_POSTURE, 0 ),

            MAP_ASCII( "FontStrikeout",         XML_NAMESPACE_STYLE,    XML_TEXT_LINE_THROUGH_STYLE,    XML_TYPE_TEXT_CROSSEDOUT_STYLE|MID_FLAG_MERGE_PROPERTY, 0),
            MAP_ASCII( "FontStrikeout",         XML_NAMESPACE_STYLE,    XML_TEXT_LINE_THROUGH_TYPE,     XML_TYPE_TEXT_CROSSEDOUT_TYPE|MID_FLAG_MERGE_PROPERTY,  0),
            MAP_ASCII( "FontStrikeout",         XML_NAMESPACE_STYLE,    XML_TEXT_LINE_THROUGH_WIDTH,    XML_TYPE_TEXT_CROSSEDOUT_WIDTH|MID_FLAG_MERGE_PROPERTY, 0),
            MAP_ASCII( "FontStrikeout",         XML_NAMESPACE_STYLE,    XML_TEXT_LINE_THROUGH_TEXT,     XML_TYPE_TEXT_CROSSEDOUT_TEXT|MID_FLAG_MERGE_PROPERTY,  0),

            MAP_ASCII( "FontStyleName",         XML_NAMESPACE_STYLE,    XML_FONT_STYLE_NAME,        XML_TYPE_STRING, 0 ),
            MAP_ASCII( "FontUnderline",         XML_NAMESPACE_STYLE,    XML_TEXT_UNDERLINE_STYLE,       XML_TYPE_TEXT_UNDERLINE_STYLE|MID_FLAG_MERGE_PROPERTY, 0 ),
            MAP_ASCII( "FontUnderline",         XML_NAMESPACE_STYLE,    XML_TEXT_UNDERLINE_TYPE,        XML_TYPE_TEXT_UNDERLINE_TYPE|MID_FLAG_MERGE_PROPERTY, 0 ),
            MAP_ASCII( "FontUnderline",         XML_NAMESPACE_STYLE,    XML_TEXT_UNDERLINE_WIDTH,       XML_TYPE_TEXT_UNDERLINE_WIDTH|MID_FLAG_MERGE_PROPERTY, 0 ),
            MAP_ASCII( "FontWeight",            XML_NAMESPACE_FO,       XML_FONT_WEIGHT,            XML_TYPE_TEXT_WEIGHT, 0 ),
            MAP_ASCII( "FontWidth",             XML_NAMESPACE_STYLE,    XML_FONT_WIDTH,             XML_TYPE_FONT_WIDTH, 0 ),
            MAP_ASCII( "FontWordLineMode",      XML_NAMESPACE_FO,       XML_SCORE_SPACES,           XML_TYPE_NBOOL, 0 ),
            MAP_ASCII( "SymbolColor",           XML_NAMESPACE_STYLE,    XML_COLOR,                  XML_TYPE_COLOR, 0 ),
            MAP_ASCII( "BorderColor",           XML_NAMESPACE_FO,       XML_BORDER,                 XML_TYPE_CONTROL_BORDER_COLOR|MID_FLAG_MULTI_PROPERTY|MID_FLAG_MERGE_ATTRIBUTE, 0 ),
            MAP_ASCII( "TextColor",             XML_NAMESPACE_FO,       XML_COLOR,                  XML_TYPE_COLOR, 0 ),
            MAP_CONST( PROPERTY_FORMATKEY,      XML_NAMESPACE_STYLE,    XML_DATA_STYLE_NAME,        XML_TYPE_STRING | MID_FLAG_NO_PROPERTY_EXPORT | MID_FLAG_SPECIAL_ITEM, CTF_FORMS_DATA_STYLE ),
            MAP_ASCII( "FontEmphasisMark",      XML_NAMESPACE_STYLE,    XML_TEXT_EMPHASIZE,         XML_TYPE_CONTROL_TEXT_EMPHASIZE, 0 ),
            MAP_ASCII( "FontRelief",            XML_NAMESPACE_STYLE,    XML_FONT_RELIEF,            XML_TYPE_TEXT_FONT_RELIEF|MID_FLAG_MULTI_PROPERTY, 0 ),
            MAP_ASCII( "TextLineColor",         XML_NAMESPACE_STYLE,    XML_TEXT_UNDERLINE_COLOR,   XML_TYPE_TEXT_UNDERLINE_COLOR|MID_FLAG_MULTI_PROPERTY, 0 ),
            MAP_END()
        };

        return aControlStyleProperties;
    }

    const XMLPropertyMapEntry* getControlStylePropertyMap( )
    {
        return getControlStylePropertyMap_Access();
    }

    //=====================================================================
    //---------------------------------------------------------------------
    struct XMLPropertyMapEntryLess
    {
        sal_Bool operator()(const XMLPropertyMapEntry& _rLeft, const XMLPropertyMapEntry& _rRight)
        {
            return strcmp(_rLeft.msApiName, _rRight.msApiName) < 0;
        }
    };

    //---------------------------------------------------------------------
    void implSortMap(XMLPropertyMapEntry* _pMap)
    {
        XMLPropertyMapEntry* pEnd;
        // determine the last element
        for ( pEnd = _pMap; pEnd->msApiName; ++pEnd)
            ;
        ::std::sort(_pMap, pEnd, XMLPropertyMapEntryLess());
    }

    //---------------------------------------------------------------------
    void initializePropertyMaps()
    {
        static sal_Bool bSorted = sal_False;
        if (!bSorted)
        {
            implSortMap(getControlStylePropertyMap_Access());
            bSorted = sal_True;
        }
    }

    //=====================================================================
    //= OFormExportPropertyMapper
    //=====================================================================
    //---------------------------------------------------------------------
    OFormExportPropertyMapper::OFormExportPropertyMapper( const UniReference< XMLPropertySetMapper >& _rMapper )
        :SvXMLExportPropertyMapper( _rMapper )
    {
    }

    //---------------------------------------------------------------------
    void OFormExportPropertyMapper::handleSpecialItem( SvXMLAttributeList& _rAttrList, const XMLPropertyState& _rProperty, const SvXMLUnitConverter& _rUnitConverter,
        const SvXMLNamespaceMap& _rNamespaceMap, const ::std::vector< XMLPropertyState >* _pProperties,
        sal_uInt32 _nIdx ) const
    {
        // ignore the number style of grid columns - this is formatted elsewhere
        if ( CTF_FORMS_DATA_STYLE != getPropertySetMapper()->GetEntryContextId( _rProperty.mnIndex ) )
            SvXMLExportPropertyMapper::handleSpecialItem( _rAttrList, _rProperty, _rUnitConverter, _rNamespaceMap, _pProperties, _nIdx );
    }

//.........................................................................
}   // namespace xmloff
//.........................................................................

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: XFormsModelExport.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 16:04:21 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 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
 *
 ************************************************************************/

#ifndef _XMLOFF_XFORMSMODELEXPORT_HXX
#define _XMLOFF_XFORMSMODELEXPORT_HXX

#include <sal/types.h>

class SvXMLExport;
namespace com { namespace sun { namespace star {
    namespace uno { template<typename T> class Reference; }
    namespace beans { class XPropertySet; }
} } }

void exportXFormsModel( SvXMLExport&,
                        const com::sun::star::uno::Reference<com::sun::star::beans::XPropertySet>& );

#endif
<commit_msg>INTEGRATION: CWS changefileheader (1.3.450); FILE MERGED 2008/03/31 16:29:00 rt 1.3.450.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: XFormsModelExport.hxx,v $
 * $Revision: 1.4 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef _XMLOFF_XFORMSMODELEXPORT_HXX
#define _XMLOFF_XFORMSMODELEXPORT_HXX

#include <sal/types.h>

class SvXMLExport;
namespace com { namespace sun { namespace star {
    namespace uno { template<typename T> class Reference; }
    namespace beans { class XPropertySet; }
} } }

void exportXFormsModel( SvXMLExport&,
                        const com::sun::star::uno::Reference<com::sun::star::beans::XPropertySet>& );

#endif
<|endoftext|>


<commit_before>// Simple ocr
// Copyright (C) 2014 vhb
//
// 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.

#include "NeuralNetworkClassifier.hpp"
#include "opencv2/opencv.hpp"

namespace ocr {

    NeuralNetworkClassifier::NeuralNetworkClassifier(
            utils::Json::Map const &datas
            )
        try :   m_nbIterations(utils::get_item<int>(datas, "nb_iterations")),
                m_stopRate(utils::get_item<float>(datas, "stop_rate")),
                m_backpropogationCoef(
                        utils::get_item<float>(datas, "backpropagation_coef")
                        )
    {
        m_featureExtractor =
            utils::get_item<std::shared_ptr<IFeatureExtractor>>(datas, "feature_extractor");
        m_nbFeatures = m_featureExtractor->nb_features();

    }
    catch (std::bad_cast const &e) {
        std::cerr << "bad_cast\t" << e.what() << std::endl;
    }
    catch (std::runtime_error const &e) {
        std::cerr << "runtime_error\t" << e.what() << std::endl;
    }

    char
    NeuralNetworkClassifier::classify(cv::Mat &&featuresMatrix) const
    {
        cv::Mat classificationResult(1, m_nbOutputClasses, CV_32F);
        m_neuralNetwork->predict(featuresMatrix, classificationResult);
        return get_classification(classificationResult);
    }

    cv::Mat
    NeuralNetworkClassifier::get_data_matrix(std::vector<Dataset::Data> const &datas) const
    {
        cv::Mat value = cv::Mat::zeros(datas.size(), m_nbFeatures, CV_32F);
        unsigned int index = 0;
        for (auto const &i: datas) {
            auto sourceMat = m_featureExtractor->extract(std::get<1>(i));
            auto tmp = sourceMat.size();
            //std::cout << sourceMat<< std::endl;
            //std::cout << value.row(index) << std::endl;
            sourceMat.copyTo(value.row(index++));
            //std::cout << sourceMat.col(0).at<float>(0) << std::endl;
            //value.row(index++) = sourceMat.col(0);
        }
        //std::cout << "value\t" << value << std::endl;
        return value;
    }

    cv::Mat
    NeuralNetworkClassifier::get_classification_matrix(cv::Mat const &mat,
                                                       int nb_output_classification)
    {
        auto size = mat.size();
        auto value = cv::Mat::zeros(size.height, nb_output_classification, CV_32F);
        return value;
    }

    void
    NeuralNetworkClassifier::train(Dataset &&d)
    {
        using namespace cv::ml;
        using namespace cv;

        m_training_set = get_data_matrix(d.get_datas());
        m_training_set_classifications = get_classification_matrix(m_training_set,
                                                                   d.get_nb_output());
        // TODO: put the list of all output values
        //std::cout << m_layers << std::endl;
        //auto training_set_classifications = cv::Mat::zeros(2, 1, CV_32F);

        m_layers = cv::Mat(3, 1, CV_32SC1);
        m_layers.row(0) = cv::Scalar(m_nbFeatures);
        m_layers.row(1) = cv::Scalar(9);
        m_layers.row(2) = cv::Scalar(d.get_nb_output());

        ANN_MLP::Params p(
                m_layers, // Neural network typography
                ANN_MLP::SIGMOID_SYM, // Activation function
                0.001, // first activation function parameter BackprocCoef ?
                0.001, // second activation functon parameter
                TermCriteria(TermCriteria::EPS + TermCriteria::COUNT,
                             m_nbIterations, m_stopRate), // training stop condition
                ANN_MLP::Params::BACKPROP, // training algorithm
                0.0001, // First parameter for the training method
                0.0001 // Second parameter for the training method
                );
        m_neuralNetwork = ANN_MLP::create(p);
        std::cout << "avant"  << std::endl;
        int iterations = m_neuralNetwork->train(m_training_set, ROW_SAMPLE,
                                                m_training_set_classifications
                );
        std::cout << "apres" << std::endl;
        std::cout << iterations << std::endl;
        serialize("./test.xml");
    }

    void
    NeuralNetworkClassifier::serialize(std::string &&dest_path) const
    {
        if (m_neuralNetwork) {
            m_neuralNetwork->save(dest_path);
        }
    }

    char const *
    NeuralNetworkClassifier::name() const
    {
        return "NeuralNetworkClassifier";
    }

    char
    NeuralNetworkClassifier::get_classification(cv::Mat const &classificationResult) const
    {
        int maxIndex = 0;
        float value=0.0f;
        float maxValue = classificationResult.at<float>(0, 0);
        for (int index = 1; index < m_nbOutputClasses; ++index)
        {
            classificationResult.at<float>(0, index);
            if (value > maxValue)
            {
                maxValue = value;
                maxIndex = index;
            }
        }
        return values[maxIndex];
    }

} /* namespace ocr */

extern "C"
ocr::NeuralNetworkClassifier *
constructor(utils::Json::Map const &m)
{
    return new ocr::NeuralNetworkClassifier(m);
}
<commit_msg>litle changes<commit_after>// Simple ocr
// Copyright (C) 2014 vhb
//
// 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.

#include "NeuralNetworkClassifier.hpp"
#include "opencv2/opencv.hpp"

namespace ocr {

    NeuralNetworkClassifier::NeuralNetworkClassifier(
            utils::Json::Map const &datas
            )
        try :   m_nbIterations(utils::get_item<int>(datas, "nb_iterations")),
                m_stopRate(utils::get_item<float>(datas, "stop_rate")),
                m_backpropogationCoef(
                        utils::get_item<float>(datas, "backpropagation_coef")
                        )
    {
        m_featureExtractor =
            utils::get_item<std::shared_ptr<IFeatureExtractor>>(datas, "feature_extractor");
        m_nbFeatures = m_featureExtractor->nb_features();

    }
    catch (std::bad_cast const &e) {
        std::cerr << "bad_cast\t" << e.what() << std::endl;
    }
    catch (std::runtime_error const &e) {
        std::cerr << "runtime_error\t" << e.what() << std::endl;
    }

    char
    NeuralNetworkClassifier::classify(cv::Mat &&featuresMatrix) const
    {
        cv::Mat classificationResult(1, m_nbOutputClasses, CV_32F);
        m_neuralNetwork->predict(featuresMatrix, classificationResult);
        return get_classification(classificationResult);
    }

    cv::Mat
    NeuralNetworkClassifier::get_data_matrix(std::vector<Dataset::Data> const &datas) const
    {
        cv::Mat value = cv::Mat::zeros(datas.size(), m_nbFeatures, CV_32F);
        unsigned int index = 0;
        for (auto const &i: datas) {
            auto sourceMat = m_featureExtractor->extract(std::get<1>(i));
            auto tmp = sourceMat.size();
            //std::cout << sourceMat<< std::endl;
            //std::cout << value.row(index) << std::endl;
            sourceMat.copyTo(value.row(index++));
            //std::cout << sourceMat.col(0).at<float>(0) << std::endl;
            //value.row(index++) = sourceMat.col(0);
        }
        //std::cout << "value\t" << value << std::endl;
        return value;
    }

    cv::Mat
    NeuralNetworkClassifier::get_classification_matrix(cv::Mat const &mat,
                                                       int nb_output_classification)
    {
        auto size = mat.size();
        auto value = cv::Mat::zeros(size.height + 1, nb_output_classification + 1, CV_32F);
        return value;
    }

    void
    NeuralNetworkClassifier::train(Dataset &&d)
    {
        using namespace cv::ml;
        using namespace cv;

        m_training_set = get_data_matrix(d.get_datas());
        m_training_set_classifications = get_classification_matrix(m_training_set,
                                                                   d.get_nb_output());
        m_layers = cv::Mat(3, 1, CV_32SC1);
        m_layers.row(0) = cv::Scalar(m_nbFeatures);
        m_layers.row(1) = cv::Scalar(9);
        m_layers.row(2) = cv::Scalar(d.get_nb_output());

        ANN_MLP::Params p(
                m_layers, // Neural network typography
                ANN_MLP::SIGMOID_SYM, // Activation function
                0.001, // first activation function parameter BackprocCoef ?
                0.001, // second activation functon parameter
                TermCriteria(TermCriteria::EPS + TermCriteria::COUNT,
                             m_nbIterations, m_stopRate), // training stop condition
                ANN_MLP::Params::BACKPROP, // training algorithm
                0.0001, // First parameter for the training method
                0.0001 // Second parameter for the training method
                );
        m_neuralNetwork = ANN_MLP::create(p);
        std::cout << "avant"  << std::endl;
        int iterations = m_neuralNetwork->train(m_training_set, ROW_SAMPLE,
                                                m_training_set_classifications
                );
        std::cout << "apres" << std::endl;
        std::cout << iterations << std::endl;
        serialize("./test.xml");
    }

    void
    NeuralNetworkClassifier::serialize(std::string &&dest_path) const
    {
        if (m_neuralNetwork) {
            m_neuralNetwork->save(dest_path);
        }
    }

    char const *
    NeuralNetworkClassifier::name() const
    {
        return "NeuralNetworkClassifier";
    }

    char
    NeuralNetworkClassifier::get_classification(cv::Mat const &classificationResult) const
    {
        int maxIndex = 0;
        float value=0.0f;
        float maxValue = classificationResult.at<float>(0, 0);
        for (int index = 1; index < m_nbOutputClasses; ++index) {
            classificationResult.at<float>(0, index);
            if (value > maxValue) {
                maxValue = value;
                maxIndex = index;
            }
        }
        return values[maxIndex];
    }

} /* namespace ocr */

extern "C"
ocr::NeuralNetworkClassifier *
constructor(utils::Json::Map const &m)
{
    return new ocr::NeuralNetworkClassifier(m);
}
<|endoftext|>


<commit_before><commit_msg>Display thumbnail associated text below it and horizontal centered.<commit_after><|endoftext|>


<commit_before>#include "PlaneGeometry.h"

//##ModelId=3E395F22035A
mitk::PlaneGeometry::PlaneGeometry() : Geometry2D(10.0, 10.0), m_ScaleFactorMMPerUnitX(1.0), m_ScaleFactorMMPerUnitY(1.0)
{
}

//##ModelId=3E395F220382
mitk::PlaneGeometry::~PlaneGeometry()
{
}

//##ModelId=3E395E3E0077
const mitk::PlaneView& mitk::PlaneGeometry::GetPlaneView() const
{
    return m_PlaneView;
}

//##ModelId=3E396ABE0385
void mitk::PlaneGeometry::SetPlaneView(const mitk::PlaneView& aPlaneView)
{
    m_PlaneView=aPlaneView;
    m_ScaleFactorMMPerUnitX=m_PlaneView.getOrientation1().length()/m_WidthInUnits;
    m_ScaleFactorMMPerUnitY=m_PlaneView.getOrientation2().length()/m_HeightInUnits;
}

//##ModelId=3E3AEB7C001C
itk::Transform<float,3,2>::Pointer mitk::PlaneGeometry::GetTransfrom() const
{
	itkExceptionMacro("Transform not yet supported.");
	return NULL;
}

//##ModelId=3E3B9C6E02B5
void mitk::PlaneGeometry::Map(const mitk::Point3D &pt3d_mm, mitk::Point2D &pt2d_mm) const
{
    m_PlaneView.map(pt3d_mm, pt2d_mm);
}

//##ModelId=3E3B9C7101BF
void mitk::PlaneGeometry::Map(const mitk::Point2D &pt2d_mm, mitk::Point3D &pt3d_mm) const
{
    m_PlaneView.map(pt2d_mm, pt3d_mm);
}

//##ModelId=3E3B9C730262
void mitk::PlaneGeometry::UnitsToMM(const mitk::Point2D &pt_units, mitk::Point2D &pt_mm) const
{
    pt_mm.x=m_ScaleFactorMMPerUnitX*pt_units.x;
    pt_mm.y=m_ScaleFactorMMPerUnitY*pt_units.y;
}

//##ModelId=3E3B9C760112
void mitk::PlaneGeometry::MMToUnits(const mitk::Point2D &pt_mm, mitk::Point2D &pt_units) const
{
    pt_units.x=pt_mm.x*(1.0/m_ScaleFactorMMPerUnitX);
    pt_units.y=pt_mm.y*(1.0/m_ScaleFactorMMPerUnitY);
}

//##ModelId=3E3B9C8C0145
void mitk::PlaneGeometry::UnitsToMM(const mitk::Vector2D &vec_units, mitk::Vector2D &vec_mm) const
{
    vec_mm.x=m_ScaleFactorMMPerUnitX*vec_units.x;
    vec_mm.y=m_ScaleFactorMMPerUnitY*vec_units.y;
}

//##ModelId=3E3B9C8E0152
void mitk::PlaneGeometry::MMToUnits(const mitk::Vector2D &vec_mm, mitk::Vector2D &vec_units) const
{
    vec_units.x=vec_mm.x*(1.0/m_ScaleFactorMMPerUnitX);
    vec_units.y=vec_mm.y*(1.0/m_ScaleFactorMMPerUnitY);
}

<commit_msg>added Modified()-call to SetPlaneView-method<commit_after>#include "PlaneGeometry.h"

//##ModelId=3E395F22035A
mitk::PlaneGeometry::PlaneGeometry() : Geometry2D(10.0, 10.0), m_ScaleFactorMMPerUnitX(1.0), m_ScaleFactorMMPerUnitY(1.0)
{
}

//##ModelId=3E395F220382
mitk::PlaneGeometry::~PlaneGeometry()
{
}

//##ModelId=3E395E3E0077
const mitk::PlaneView& mitk::PlaneGeometry::GetPlaneView() const
{
    return m_PlaneView;
}

//##ModelId=3E396ABE0385
void mitk::PlaneGeometry::SetPlaneView(const mitk::PlaneView& aPlaneView)
{
    m_PlaneView=aPlaneView;
    m_ScaleFactorMMPerUnitX=m_PlaneView.getOrientation1().length()/m_WidthInUnits;
    m_ScaleFactorMMPerUnitY=m_PlaneView.getOrientation2().length()/m_HeightInUnits;
		Modified();
}

//##ModelId=3E3AEB7C001C
itk::Transform<float,3,2>::Pointer mitk::PlaneGeometry::GetTransfrom() const
{
	itkExceptionMacro("Transform not yet supported.");
	return NULL;
}

//##ModelId=3E3B9C6E02B5
void mitk::PlaneGeometry::Map(const mitk::Point3D &pt3d_mm, mitk::Point2D &pt2d_mm) const
{
    m_PlaneView.map(pt3d_mm, pt2d_mm);
}

//##ModelId=3E3B9C7101BF
void mitk::PlaneGeometry::Map(const mitk::Point2D &pt2d_mm, mitk::Point3D &pt3d_mm) const
{
    m_PlaneView.map(pt2d_mm, pt3d_mm);
}

//##ModelId=3E3B9C730262
void mitk::PlaneGeometry::UnitsToMM(const mitk::Point2D &pt_units, mitk::Point2D &pt_mm) const
{
    pt_mm.x=m_ScaleFactorMMPerUnitX*pt_units.x;
    pt_mm.y=m_ScaleFactorMMPerUnitY*pt_units.y;
}

//##ModelId=3E3B9C760112
void mitk::PlaneGeometry::MMToUnits(const mitk::Point2D &pt_mm, mitk::Point2D &pt_units) const
{
    pt_units.x=pt_mm.x*(1.0/m_ScaleFactorMMPerUnitX);
    pt_units.y=pt_mm.y*(1.0/m_ScaleFactorMMPerUnitY);
}

//##ModelId=3E3B9C8C0145
void mitk::PlaneGeometry::UnitsToMM(const mitk::Vector2D &vec_units, mitk::Vector2D &vec_mm) const
{
    vec_mm.x=m_ScaleFactorMMPerUnitX*vec_units.x;
    vec_mm.y=m_ScaleFactorMMPerUnitY*vec_units.y;
}

//##ModelId=3E3B9C8E0152
void mitk::PlaneGeometry::MMToUnits(const mitk::Vector2D &vec_mm, mitk::Vector2D &vec_units) const
{
    vec_units.x=vec_mm.x*(1.0/m_ScaleFactorMMPerUnitX);
    vec_units.y=vec_mm.y*(1.0/m_ScaleFactorMMPerUnitY);
}

<|endoftext|>


<commit_before>/*
 * DirectoryIterator.inl
 *
 * Copyright (C) 2007 - 2010 by Visualisierungsinstitut Universitaet Stuttgart.
 */

#ifdef _WIN32
#include <Windows.h>
#else /* _WIN32 */
#include "vislib/UnsupportedOperationException.h"
#endif /* _WIN32 */

namespace vislib {
namespace sys {

    /*
     * DirectoryIterator<T>::DirectoryIterator
     */
    template<> DirectoryIterator<CharTraitsA>::DirectoryIterator(
            const Char* path, bool isPattern, bool showDirs) : nextItem(),
            currentItem(), omitFolders(!showDirs) {
#ifdef _WIN32
        WIN32_FIND_DATAA fd;
        StringA p = path;
        if (!isPattern) {
            if (!p.EndsWith(vislib::sys::Path::SEPARATOR_A)) {
                if (!p.EndsWith(":")) {
                    p += vislib::sys::Path::SEPARATOR_A;
                }
            }
            p += "*.*";
        }

        this->findHandle = FindFirstFileA(p, &fd);
        if (this->findHandle == INVALID_HANDLE_VALUE) {
            DWORD le = ::GetLastError();
            if (le == ERROR_FILE_NOT_FOUND) {
                this->nextItem.Path.Clear();
            } else {
                throw SystemException(le, __FILE__, __LINE__);
            }
        } else if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
            this->nextItem.Type = Entry::DIRECTORY;
            if (this->omitFolders || (strcmp(fd.cFileName, ".") == 0)
                    || (strcmp(fd.cFileName, "..") == 0)) {
                this->fetchNextItem();
            } else {
                this->nextItem.Path = fd.cFileName;
            }
        } else {
            this->nextItem.Type = Entry::FILE;
            this->nextItem.Path = fd.cFileName;
        }
#else /* _WIN32 */
        if (isPattern) {
            this->basePath = vislib::sys::Path::GetDirectoryName(path);
            this->pattern = path + (this->basePath.Length() + 1);

        } else {
            this->basePath = path;
            this->pattern.Clear();

        }
        if (vislib::sys::File::Exists(this->basePath)) {
            if ((this->dirStream = opendir(this->basePath)) == NULL) {
                throw SystemException(__FILE__, __LINE__);
            }
            this->fetchNextItem();
        } else {
            this->dirStream = NULL;
            this->nextItem.Path.Clear();
        }
#endif /* _WIN32 */
    }

    /*
     * DirectoryIterator<T>::DirectoryIterator
     */
    template<> DirectoryIterator<CharTraitsW>::DirectoryIterator(
            const Char* path, bool isPattern, bool showDirs) : nextItem(),
            currentItem(), omitFolders(!showDirs) {
#ifdef _WIN32
        WIN32_FIND_DATAW fd;
        StringW p = path;
        if (!isPattern) {
            if (!p.EndsWith(vislib::sys::Path::SEPARATOR_W)) {
                if (!p.EndsWith(L":")) {
                    p += vislib::sys::Path::SEPARATOR_W;
                }
            }
            p += L"*.*";
        }

        this->findHandle = FindFirstFileW(p, &fd);
        if (this->findHandle == INVALID_HANDLE_VALUE) {
            DWORD le = ::GetLastError();
            if (le == ERROR_FILE_NOT_FOUND) {
                this->nextItem.Path.Clear();
            } else {
                throw SystemException(le, __FILE__, __LINE__);
            }
        } else if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
            this->nextItem.Type = Entry::DIRECTORY;
            if (this->omitFolders || (wcscmp(fd.cFileName, L".") == 0)
                    || (wcscmp(fd.cFileName, L"..") == 0)) {
                this->fetchNextItem();
            } else {
                this->nextItem.Path = fd.cFileName;
            }
        } else {
            this->nextItem.Type = Entry::FILE;
            this->nextItem.Path = fd.cFileName;
        }
#else /* _WIN32 */
        if (isPattern) {
            this->basePath = vislib::sys::Path::GetDirectoryName(path);
            this->pattern = path + (this->basePath.Length() + 1);

        } else {
            this->basePath = path;
            this->pattern.Clear();

        }
        if (vislib::sys::File::Exists(this->basePath)) {
            if ((this->dirStream = opendir(this->basePath)) == NULL) {
                throw SystemException(__FILE__, __LINE__);
            }
            this->fetchNextItem();
        } else {
            this->dirStream = NULL;
            this->nextItem.Path.Clear();
        }
#endif /* _WIN32 */
    }

    /*
     * DirectoryIterator<T>::fetchNextItem
     */
    template<> void DirectoryIterator<CharTraitsA>::fetchNextItem(void) {
#ifdef _WIN32
        WIN32_FIND_DATAA fd;
        DWORD le;
        bool found = false;
        do {
            if (this->findHandle == INVALID_HANDLE_VALUE) {
                this->nextItem.Path.Clear();
            } else if (FindNextFileA(this->findHandle, &fd) == 0) {
                if ((le = GetLastError()) == ERROR_NO_MORE_FILES) {
                    this->nextItem.Path.Clear();
                    found = true;
                } else {
                    throw SystemException(le, __FILE__, __LINE__);
                }
            } else {
                if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
                    this->nextItem.Type = Entry::DIRECTORY;
                    if (!this->omitFolders && (strcmp(fd.cFileName, ".") != 0)
                            && (strcmp(fd.cFileName, "..") != 0)) {
                        found = true;
                    }
                } else {
                    this->nextItem.Type = Entry::FILE;
                    found = true;
                }
                this->nextItem.Path = fd.cFileName;
            }
        } while (!found);
#else /* _WIN32 */
        struct dirent *de = NULL;
        if (this->dirStream != NULL) {
            do {
                // BUG: Linux documentation is all lies. the errno stunt does not work at all.
                //errno = 0;
                if ((de = readdir(this->dirStream)) != NULL) {
                    if (!this->pattern.IsEmpty()) {
                        if (!vislib::sys::FilenameGlobMatch(de->d_name, this->pattern.PeekBuffer())) {
                            continue; // one more time
                        }
                    }
                    if (vislib::sys::File::IsDirectory(this->basePath + Path::SEPARATOR_A + de->d_name)) {
                        this->nextItem.Type = Entry::DIRECTORY;
                        if (this->omitFolders) continue; // one more time
                        if ((strcmp(de->d_name, "..") != 0) && (strcmp(de->d_name, ".") != 0)) break;
                    } else {
                        this->nextItem.Type = Entry::FILE;
                        break;
                    }
                }
            } while (de != NULL);
        }
        if (de == NULL) {
            this->nextItem.Path.Clear();
        }
        else {
            this->nextItem.Path = de->d_name;
        }
#endif /* _WIN32 */
    }

    /*
     * DirectoryIterator<T>::fetchNextItem
     */
    template<> void DirectoryIterator<CharTraitsW>::fetchNextItem(void) {
#ifdef _WIN32
        WIN32_FIND_DATAW fd;
        DWORD le;
        bool found = false;
        do {
            if (this->findHandle == INVALID_HANDLE_VALUE) {
                this->nextItem.Path.Clear();
            } else if (FindNextFileW(this->findHandle, &fd) == 0) {
                if ((le = GetLastError()) == ERROR_NO_MORE_FILES) {
                    this->nextItem.Path.Clear();
                    found = true;
                } else {
                    throw SystemException(le, __FILE__, __LINE__);
                }
            } else {
                if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
                    this->nextItem.Type = Entry::DIRECTORY;
                    if (!this->omitFolders && (wcscmp(fd.cFileName, L".") != 0)
                            && (wcscmp(fd.cFileName, L"..") != 0)) {
                        found = true;
                    }
                } else {
                    this->nextItem.Type = Entry::FILE;
                    found = true;
                }
                this->nextItem.Path = fd.cFileName;
            }
        } while (!found);
#else /* _WIN32 */
        struct dirent *de = NULL;
        if (this->dirStream != NULL) {
            do {
                // BUG: Linux documentation is all lies. the errno stunt does not work at all.
                //errno = 0;
                if ((de = readdir(this->dirStream)) != NULL) {
                    if (!this->pattern.IsEmpty()) {
                        if (!vislib::sys::FilenameGlobMatch(de->d_name, this->pattern.PeekBuffer())) {
                            continue; // one more time
                        }
                    }
                    if (vislib::sys::File::IsDirectory(this->basePath + Path::SEPARATOR_A + de->d_name)) {
                        this->nextItem.Type = Entry::DIRECTORY;
                        if (this->omitFolders) continue; // one more time
                        if ((strcmp(de->d_name, "..") != 0) && (strcmp(de->d_name, ".") != 0)) break;
                    } else {
                        this->nextItem.Type = Entry::FILE;
                        break;
                    }
                }
            } while (de != NULL);
        }
        if (de == NULL) {
            this->nextItem.Path.Clear();
        } else {
            this->nextItem.Path = vislib::StringW(de->d_name);
        }
#endif /* _WIN32 */
    }

} /* end namespace sys */
} /* end namespace vislib */
<commit_msg>DirectoryIterator.inl is now more robust against missing directories<commit_after>/*
 * DirectoryIterator.inl
 *
 * Copyright (C) 2007 - 2010 by Visualisierungsinstitut Universitaet Stuttgart.
 */

#ifdef _WIN32
#include <Windows.h>
#else /* _WIN32 */
#include "vislib/UnsupportedOperationException.h"
#endif /* _WIN32 */

namespace vislib {
namespace sys {

    /*
     * DirectoryIterator<T>::DirectoryIterator
     */
    template<> DirectoryIterator<CharTraitsA>::DirectoryIterator(
            const Char* path, bool isPattern, bool showDirs) : nextItem(),
            currentItem(), omitFolders(!showDirs) {
#ifdef _WIN32
        WIN32_FIND_DATAA fd;
        StringA p = path;
        if (!isPattern) {
            if (!p.EndsWith(vislib::sys::Path::SEPARATOR_A)) {
                if (!p.EndsWith(":")) {
                    p += vislib::sys::Path::SEPARATOR_A;
                }
            }
            p += "*.*";
        }

        this->findHandle = FindFirstFileA(p, &fd);
        if (this->findHandle == INVALID_HANDLE_VALUE) {
            DWORD le = ::GetLastError();
            if ((le == ERROR_FILE_NOT_FOUND) || (le == ERROR_PATH_NOT_FOUND)) {
                this->nextItem.Path.Clear();
            } else {
                throw SystemException(le, __FILE__, __LINE__);
            }
        } else if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
            this->nextItem.Type = Entry::DIRECTORY;
            if (this->omitFolders || (strcmp(fd.cFileName, ".") == 0)
                    || (strcmp(fd.cFileName, "..") == 0)) {
                this->fetchNextItem();
            } else {
                this->nextItem.Path = fd.cFileName;
            }
        } else {
            this->nextItem.Type = Entry::FILE;
            this->nextItem.Path = fd.cFileName;
        }
#else /* _WIN32 */
        if (isPattern) {
            this->basePath = vislib::sys::Path::GetDirectoryName(path);
            this->pattern = path + (this->basePath.Length() + 1);

        } else {
            this->basePath = path;
            this->pattern.Clear();

        }
        if (vislib::sys::File::Exists(this->basePath)) {
            if ((this->dirStream = opendir(this->basePath)) == NULL) {
                throw SystemException(__FILE__, __LINE__);
            }
            this->fetchNextItem();
        } else {
            this->dirStream = NULL;
            this->nextItem.Path.Clear();
        }
#endif /* _WIN32 */
    }

    /*
     * DirectoryIterator<T>::DirectoryIterator
     */
    template<> DirectoryIterator<CharTraitsW>::DirectoryIterator(
            const Char* path, bool isPattern, bool showDirs) : nextItem(),
            currentItem(), omitFolders(!showDirs) {
#ifdef _WIN32
        WIN32_FIND_DATAW fd;
        StringW p = path;
        if (!isPattern) {
            if (!p.EndsWith(vislib::sys::Path::SEPARATOR_W)) {
                if (!p.EndsWith(L":")) {
                    p += vislib::sys::Path::SEPARATOR_W;
                }
            }
            p += L"*.*";
        }

        this->findHandle = FindFirstFileW(p, &fd);
        if (this->findHandle == INVALID_HANDLE_VALUE) {
            DWORD le = ::GetLastError();
            if ((le == ERROR_FILE_NOT_FOUND) || (le == ERROR_PATH_NOT_FOUND)) {
                this->nextItem.Path.Clear();
            } else {
                throw SystemException(le, __FILE__, __LINE__);
            }
        } else if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
            this->nextItem.Type = Entry::DIRECTORY;
            if (this->omitFolders || (wcscmp(fd.cFileName, L".") == 0)
                    || (wcscmp(fd.cFileName, L"..") == 0)) {
                this->fetchNextItem();
            } else {
                this->nextItem.Path = fd.cFileName;
            }
        } else {
            this->nextItem.Type = Entry::FILE;
            this->nextItem.Path = fd.cFileName;
        }
#else /* _WIN32 */
        if (isPattern) {
            this->basePath = vislib::sys::Path::GetDirectoryName(path);
            this->pattern = path + (this->basePath.Length() + 1);

        } else {
            this->basePath = path;
            this->pattern.Clear();

        }
        if (vislib::sys::File::Exists(this->basePath)) {
            if ((this->dirStream = opendir(this->basePath)) == NULL) {
                throw SystemException(__FILE__, __LINE__);
            }
            this->fetchNextItem();
        } else {
            this->dirStream = NULL;
            this->nextItem.Path.Clear();
        }
#endif /* _WIN32 */
    }

    /*
     * DirectoryIterator<T>::fetchNextItem
     */
    template<> void DirectoryIterator<CharTraitsA>::fetchNextItem(void) {
#ifdef _WIN32
        WIN32_FIND_DATAA fd;
        DWORD le;
        bool found = false;
        do {
            if (this->findHandle == INVALID_HANDLE_VALUE) {
                this->nextItem.Path.Clear();
            } else if (FindNextFileA(this->findHandle, &fd) == 0) {
                if ((le = GetLastError()) == ERROR_NO_MORE_FILES) {
                    this->nextItem.Path.Clear();
                    found = true;
                } else {
                    throw SystemException(le, __FILE__, __LINE__);
                }
            } else {
                if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
                    this->nextItem.Type = Entry::DIRECTORY;
                    if (!this->omitFolders && (strcmp(fd.cFileName, ".") != 0)
                            && (strcmp(fd.cFileName, "..") != 0)) {
                        found = true;
                    }
                } else {
                    this->nextItem.Type = Entry::FILE;
                    found = true;
                }
                this->nextItem.Path = fd.cFileName;
            }
        } while (!found);
#else /* _WIN32 */
        struct dirent *de = NULL;
        if (this->dirStream != NULL) {
            do {
                // BUG: Linux documentation is all lies. the errno stunt does not work at all.
                //errno = 0;
                if ((de = readdir(this->dirStream)) != NULL) {
                    if (!this->pattern.IsEmpty()) {
                        if (!vislib::sys::FilenameGlobMatch(de->d_name, this->pattern.PeekBuffer())) {
                            continue; // one more time
                        }
                    }
                    if (vislib::sys::File::IsDirectory(this->basePath + Path::SEPARATOR_A + de->d_name)) {
                        this->nextItem.Type = Entry::DIRECTORY;
                        if (this->omitFolders) continue; // one more time
                        if ((strcmp(de->d_name, "..") != 0) && (strcmp(de->d_name, ".") != 0)) break;
                    } else {
                        this->nextItem.Type = Entry::FILE;
                        break;
                    }
                }
            } while (de != NULL);
        }
        if (de == NULL) {
            this->nextItem.Path.Clear();
        }
        else {
            this->nextItem.Path = de->d_name;
        }
#endif /* _WIN32 */
    }

    /*
     * DirectoryIterator<T>::fetchNextItem
     */
    template<> void DirectoryIterator<CharTraitsW>::fetchNextItem(void) {
#ifdef _WIN32
        WIN32_FIND_DATAW fd;
        DWORD le;
        bool found = false;
        do {
            if (this->findHandle == INVALID_HANDLE_VALUE) {
                this->nextItem.Path.Clear();
            } else if (FindNextFileW(this->findHandle, &fd) == 0) {
                if ((le = GetLastError()) == ERROR_NO_MORE_FILES) {
                    this->nextItem.Path.Clear();
                    found = true;
                } else {
                    throw SystemException(le, __FILE__, __LINE__);
                }
            } else {
                if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
                    this->nextItem.Type = Entry::DIRECTORY;
                    if (!this->omitFolders && (wcscmp(fd.cFileName, L".") != 0)
                            && (wcscmp(fd.cFileName, L"..") != 0)) {
                        found = true;
                    }
                } else {
                    this->nextItem.Type = Entry::FILE;
                    found = true;
                }
                this->nextItem.Path = fd.cFileName;
            }
        } while (!found);
#else /* _WIN32 */
        struct dirent *de = NULL;
        if (this->dirStream != NULL) {
            do {
                // BUG: Linux documentation is all lies. the errno stunt does not work at all.
                //errno = 0;
                if ((de = readdir(this->dirStream)) != NULL) {
                    if (!this->pattern.IsEmpty()) {
                        if (!vislib::sys::FilenameGlobMatch(de->d_name, this->pattern.PeekBuffer())) {
                            continue; // one more time
                        }
                    }
                    if (vislib::sys::File::IsDirectory(this->basePath + Path::SEPARATOR_A + de->d_name)) {
                        this->nextItem.Type = Entry::DIRECTORY;
                        if (this->omitFolders) continue; // one more time
                        if ((strcmp(de->d_name, "..") != 0) && (strcmp(de->d_name, ".") != 0)) break;
                    } else {
                        this->nextItem.Type = Entry::FILE;
                        break;
                    }
                }
            } while (de != NULL);
        }
        if (de == NULL) {
            this->nextItem.Path.Clear();
        } else {
            this->nextItem.Path = vislib::StringW(de->d_name);
        }
#endif /* _WIN32 */
    }

} /* end namespace sys */
} /* end namespace vislib */
<|endoftext|>


<commit_before>#include <metaSMT/support/default_visitation_unrolling_limit.hpp>
#include "Connection.hpp"
#include "create_solver.hpp"
#include <boost/lexical_cast.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/asio/read_until.hpp>
#include <boost/asio/write.hpp>
#include <iomanip>
#include <sys/wait.h>

namespace mpl = boost::mpl;

void Connection::new_connection(SocketPtr socket) {
  std::cout << "New connection" << std::endl;
  Connection c(socket);
}

Connection::Connection(SocketPtr socket)
  : socket(socket),
    timeoutEnabled(false),
    timeoutThreshold(-1) {
  std::string exit_reason = "requested by client";
  try {
    write( metaSMT::getAvailableSolversString() );
    setupSolvers();
    if ( !createSolverProcesses() ) {
      return;
    }
    gettimeofday(&startTime, NULL);
    processCommandsLoop();
  }
  catch (std::exception &e) {
    exit_reason = e.what();
  }

  std::cout << "Closing connection: " << exit_reason << std::endl;

  for (Solvers::iterator it = solvers.begin(), ie = solvers.end();
       it != ie; ++it) {
    terminateSolver(*it);
  }
  socket->close();
}

void Connection::setupSolvers() {
  // send solver information to client and wait for client response,
  // i.e., the selection of the solvers for solving the SMT instance.
  std::string str;
  while ( true ) {
    str = getLine();

    if (boost::algorithm::starts_with(str, "start")) {
      std::vector<std::string> split;
      boost::split(split, str, boost::algorithm::is_any_of(" "));

      if (split.size() <= 2u) {
        if (split.size() == 2u) {
          try {
            timeoutThreshold = boost::lexical_cast<unsigned>(split[1]);
            timeoutEnabled = true;
          } catch (boost::bad_lexical_cast) {
            write( SolverBase::error + " unable to parse optional timeout parameter" );
            continue;
          }
          std::cout << "Timeout after " << timeoutThreshold << " seconds" << std::endl;
        }

        if (solvers.empty()) {
          write( SolverBase::error + " choose at least one solver" );
        } else {
          write( SolverBase::success );
          return;
        }
      } else {
        write( SolverBase::error + " to many parameters" );
      }
    } else if ( metaSMT::isSolverAvailable(str) ) {
      solvers.push_back(new SolverProcess(str));
      write( SolverBase::success );
    } else {
      write( SolverBase::unsupported + " solver or command" );
    }
  }
}

bool Connection::createSolverProcesses() {
  for (Solvers::iterator it = solvers.begin(), ie = solvers.end();
       it != ie; ++it) {
    SolverProcess *solver = *it;
    if ( !solver->initPipes() ) {
      write(SolverBase::error + " could not create pipes for IPC");
      return false;
    }
    pid_t pid = fork();
    if (pid == -1) {
      write(SolverBase::error + " could not fork new process");
      return false;
    }
    else if (pid) {
      // parent process
      solver->pid = pid;
    }
    else {
      // child process
      solver->sb = create_solver( solver->solver_type );
      solver->sb->sp = solver;
      solver->sb->start();
      return false;
    }
  }
  return true;
}

SolverProcess *Connection::findFastestSolver() {
  while ( true ) {
    checkTimeout();
    for (Solvers::iterator it = solvers.begin(), ie = solvers.end();
         it != ie; ++it) {
      if ((*it)->parent_read_command_available()) {
        return *it;
      }
    }
    usleep(100);
  }
}

std::string Connection::checkSat() {
  SolverProcess *solver = findFastestSolver();
  assert( solver && "solver must not be NULL" );

  timeval time;
  gettimeofday(&time, NULL);
  long int ms = (time.tv_sec - startTime.tv_sec) * 1000;
  ms += (time.tv_usec - startTime.tv_usec) / 1000;

  std::stringstream ss;
  ss << std::fixed << std::setprecision(2) << ms / 1000.0;
  std::string const result = solver->parent_read_command() + " ;; " + solver->solver_type + " ;; " + ss.str();
  // terminate all but the fastest solver
  for ( Solvers::iterator it = solvers.begin(), ie  = solvers.end();
        it != ie; ++it ) {
    if ( *it != solver ) {
      terminateSolver(*it);
    }
  }
  solvers.clear();
  solvers.push_back(solver);
  return result;
}

std::string Connection::getValue() {
  typedef std::vector<std::string> Answers;
  Answers answers(solvers.size());
  std::size_t n = 0;
  for ( Solvers::iterator it = solvers.begin(), ie = solvers.end();
        it != ie; ++it, ++n ) {
    answers[n] = (*it)->parent_read_command();
  }

  // return a FAIL if not all answers are the same, otherwise return
  // the consistent answer
  for (std::size_t n = 0; n < answers.size() -1; n++) {
    if (answers[n] != answers[n+1]) {
      return SolverBase::error + " inconsistent solver behavior";
    }
  }
  return answers[0];
}

void Connection::processCommandsLoop() {
  std::string line;
  while ( true ) {
    checkTimeout();
    line = getLine();
    // std::cerr << "[SERVER] RECEIVED " << line << '\n';

    if ( line == "(exit)" ) {
      write( SolverBase::success );
      return;
    }

    // forward command to solver backend
    for (Solvers::iterator it = solvers.begin(), ie = solvers.end();
         it != ie; ++it) {
      (*it)->parent_write_command(line);
    }

    // pass resultl of check-sat and get-value to the client
    if ( line == "(check-sat)" ) {
      write ( checkSat() );
      timeoutEnabled = false;
    }
    else if ( boost::algorithm::starts_with(line, "(get-value") ) {
      write( getValue() );
    }
    else {
      // otherwise, ignore result from solver backend
      for (Solvers::iterator it = solvers.begin(), ie = solvers.end();
           it != ie; ++it) {
        std::string const s = (*it)->parent_read_command();
        write( s );
      }
    }
  }
}

std::string Connection::getLine() {
  boost::system::error_code error;
  std::size_t len = read_until(*socket, buffer, '\n', error);
  if (error) throw boost::system::system_error(error);
  std::string s;
  std::istream is(&buffer);
  std::getline(is, s);
  s.erase(s.find_last_not_of(" \n\r\t") + 1);
  return s;
}

void Connection::write(std::string s) {
  s += '\n';
  boost::asio::write(*socket, boost::asio::buffer(s, s.size()));
}

void Connection::terminateSolver(SolverProcess *solver) {
  kill(solver->pid, SIGTERM);
  int status;
  waitpid(solver->pid, &status, 0);
  delete solver;
}

void Connection::checkTimeout() {
  if (timeoutEnabled) {
    timeval time;
    gettimeofday(&time, NULL);
    long int secs = time.tv_sec - startTime.tv_sec;

    if (secs > timeoutThreshold) {
        write( SolverBase::unknown );
        throw std::runtime_error("Solver timeout");
    }
  }
}
<commit_msg>metaSMT-server: only measure time consumed for (check-sat)<commit_after>#include <metaSMT/support/default_visitation_unrolling_limit.hpp>
#include "Connection.hpp"
#include "create_solver.hpp"
#include <boost/lexical_cast.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/asio/read_until.hpp>
#include <boost/asio/write.hpp>
#include <iomanip>
#include <sys/wait.h>

namespace mpl = boost::mpl;

void Connection::new_connection(SocketPtr socket) {
  std::cout << "New connection" << std::endl;
  Connection c(socket);
}

Connection::Connection(SocketPtr socket)
  : socket(socket),
    timeoutEnabled(false),
    timeoutThreshold(-1) {
  std::string exit_reason = "requested by client";
  try {
    write( metaSMT::getAvailableSolversString() );
    setupSolvers();
    if ( !createSolverProcesses() ) {
      return;
    }
    processCommandsLoop();
  }
  catch (std::exception &e) {
    exit_reason = e.what();
  }

  std::cout << "Closing connection: " << exit_reason << std::endl;

  for (Solvers::iterator it = solvers.begin(), ie = solvers.end();
       it != ie; ++it) {
    terminateSolver(*it);
  }
  socket->close();
}

void Connection::setupSolvers() {
  // send solver information to client and wait for client response,
  // i.e., the selection of the solvers for solving the SMT instance.
  std::string str;
  while ( true ) {
    str = getLine();

    if (boost::algorithm::starts_with(str, "start")) {
      std::vector<std::string> split;
      boost::split(split, str, boost::algorithm::is_any_of(" "));

      if (split.size() <= 2u) {
        if (split.size() == 2u) {
          try {
            timeoutThreshold = boost::lexical_cast<unsigned>(split[1]);
            timeoutEnabled = true;
          } catch (boost::bad_lexical_cast) {
            write( SolverBase::error + " unable to parse optional timeout parameter" );
            continue;
          }
          std::cout << "Timeout after " << timeoutThreshold << " seconds" << std::endl;
        }

        if (solvers.empty()) {
          write( SolverBase::error + " choose at least one solver" );
        } else {
          write( SolverBase::success );
          return;
        }
      } else {
        write( SolverBase::error + " to many parameters" );
      }
    } else if ( metaSMT::isSolverAvailable(str) ) {
      solvers.push_back(new SolverProcess(str));
      write( SolverBase::success );
    } else {
      write( SolverBase::unsupported + " solver or command" );
    }
  }
}

bool Connection::createSolverProcesses() {
  for (Solvers::iterator it = solvers.begin(), ie = solvers.end();
       it != ie; ++it) {
    SolverProcess *solver = *it;
    if ( !solver->initPipes() ) {
      write(SolverBase::error + " could not create pipes for IPC");
      return false;
    }
    pid_t pid = fork();
    if (pid == -1) {
      write(SolverBase::error + " could not fork new process");
      return false;
    }
    else if (pid) {
      // parent process
      solver->pid = pid;
    }
    else {
      // child process
      solver->sb = create_solver( solver->solver_type );
      solver->sb->sp = solver;
      solver->sb->start();
      return false;
    }
  }
  return true;
}

SolverProcess *Connection::findFastestSolver() {
  while ( true ) {
    checkTimeout();
    for (Solvers::iterator it = solvers.begin(), ie = solvers.end();
         it != ie; ++it) {
      if ((*it)->parent_read_command_available()) {
        return *it;
      }
    }
    usleep(100);
  }
}

std::string Connection::checkSat() {
  gettimeofday(&startTime, NULL);
  SolverProcess *solver = findFastestSolver();
  assert( solver && "solver must not be NULL" );

  timeval time;
  gettimeofday(&time, NULL);
  long int ms = (time.tv_sec - startTime.tv_sec) * 1000;
  ms += (time.tv_usec - startTime.tv_usec) / 1000;

  std::stringstream ss;
  ss << std::fixed << std::setprecision(2) << ms / 1000.0;
  std::string const result = solver->parent_read_command() + " ;; " + solver->solver_type + " ;; " + ss.str();
  // terminate all but the fastest solver
  for ( Solvers::iterator it = solvers.begin(), ie  = solvers.end();
        it != ie; ++it ) {
    if ( *it != solver ) {
      terminateSolver(*it);
    }
  }
  solvers.clear();
  solvers.push_back(solver);
  return result;
}

std::string Connection::getValue() {
  typedef std::vector<std::string> Answers;
  Answers answers(solvers.size());
  std::size_t n = 0;
  for ( Solvers::iterator it = solvers.begin(), ie = solvers.end();
        it != ie; ++it, ++n ) {
    answers[n] = (*it)->parent_read_command();
  }

  // return a FAIL if not all answers are the same, otherwise return
  // the consistent answer
  for (std::size_t n = 0; n < answers.size() -1; n++) {
    if (answers[n] != answers[n+1]) {
      return SolverBase::error + " inconsistent solver behavior";
    }
  }
  return answers[0];
}

void Connection::processCommandsLoop() {
  std::string line;
  while ( true ) {
    line = getLine();
    // std::cerr << "[SERVER] RECEIVED " << line << '\n';

    if ( line == "(exit)" ) {
      write( SolverBase::success );
      return;
    }

    // forward command to solver backend
    for (Solvers::iterator it = solvers.begin(), ie = solvers.end();
         it != ie; ++it) {
      (*it)->parent_write_command(line);
    }

    // pass resultl of check-sat and get-value to the client
    if ( line == "(check-sat)" ) {
      write ( checkSat() );
    }
    else if ( boost::algorithm::starts_with(line, "(get-value") ) {
      write( getValue() );
    }
    else {
      // otherwise, ignore result from solver backend
      for (Solvers::iterator it = solvers.begin(), ie = solvers.end();
           it != ie; ++it) {
        std::string const s = (*it)->parent_read_command();
        write( s );
      }
    }
  }
}

std::string Connection::getLine() {
  boost::system::error_code error;
  std::size_t len = read_until(*socket, buffer, '\n', error);
  if (error) throw boost::system::system_error(error);
  std::string s;
  std::istream is(&buffer);
  std::getline(is, s);
  s.erase(s.find_last_not_of(" \n\r\t") + 1);
  return s;
}

void Connection::write(std::string s) {
  s += '\n';
  boost::asio::write(*socket, boost::asio::buffer(s, s.size()));
}

void Connection::terminateSolver(SolverProcess *solver) {
  kill(solver->pid, SIGTERM);
  int status;
  waitpid(solver->pid, &status, 0);
  delete solver;
}

void Connection::checkTimeout() {
  if (timeoutEnabled) {
    timeval time;
    gettimeofday(&time, NULL);
    long int secs = time.tv_sec - startTime.tv_sec;

    if (secs > timeoutThreshold) {
        write( SolverBase::unknown );
        throw std::runtime_error("Solver timeout");
    }
  }
}
<|endoftext|>