<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: schemaparser.cxx,v $
 *
 *  $Revision: 1.10 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 04:41:45 $
 *
 *  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
 *
 ************************************************************************/

#include "schemaparser.hxx"

// -----------------------------------------------------------------------------
#ifndef CONFIGMGR_WRAPEXCEPTION_HXX
#include "wrapexception.hxx"
#endif

#define WRAP_PARSE_EXCEPTIONS()  \
    PASS_EXCEPTION(sax::SAXException)       \
    PASS_EXCEPTION(uno::RuntimeException)   \
    WRAP_CONFIGDATA_EXCEPTIONS( raiseParseException )   \
    WRAP_OTHER_EXCEPTIONS( raiseParseException )

#define WRAP_PARSE_EXCEPTIONS_MSG( msg )  \
    PASS_EXCEPTION(sax::SAXException)       \
    PASS_EXCEPTION(uno::RuntimeException)   \
    WRAP_CONFIGDATA_EXCEPTIONS1( raiseParseException, msg ) \
    WRAP_OTHER_EXCEPTIONS1( raiseParseException, msg )

// -----------------------------------------------------------------------------

namespace configmgr
{
// -----------------------------------------------------------------------------
    namespace xml
    {
// -----------------------------------------------------------------------------
        namespace uno       = ::com::sun::star::uno;
        namespace sax       = ::com::sun::star::xml::sax;
// -----------------------------------------------------------------------------

SchemaParser::SchemaParser(Context const & _xContext, uno::Reference< backenduno::XSchemaHandler > const & _xHandler, Select _selector)
: BasicParser(_xContext)
, m_xHandler(_xHandler)
, m_sComponent()
, m_selector(_selector)
, m_selected(selectNone)
{
    if (!m_xHandler.is())
    {
        OUString sMessage(RTL_CONSTASCII_USTRINGPARAM("Cannot create SchemaParser: Unexpected NULL Handler"));
        throw uno::RuntimeException(sMessage, *this);
    }
    OSL_ENSURE(m_selector != selectNone, "Warning: Schema handler will handle no part of the schema");
}
// -----------------------------------------------------------------------------

SchemaParser::~SchemaParser()
{
}
// -----------------------------------------------------------------------------

void SAL_CALL SchemaParser::startDocument(  )
        throw (sax::SAXException, uno::RuntimeException)
{
    BasicParser::startDocument();

    OSL_ENSURE(isEmptyNode(), "BasicParser does not mark new document as empty");

    m_sComponent = OUString();
    m_selected = selectNone;
}
// -----------------------------------------------------------------------------

void SAL_CALL SchemaParser::endDocument(  ) throw (sax::SAXException, uno::RuntimeException)
{
    if (isSelected())
        raiseParseException("Schema XML Parser: Invalid XML: Document ends while section is open");

    if (isEmptyNode()) OSL_TRACE("Configuration Parser: XML schema document ended without any data");

    BasicParser::endDocument();
}
// -----------------------------------------------------------------------------

void SAL_CALL SchemaParser::startElement( const OUString& aName, const uno::Reference< sax::XAttributeList >& xAttribs )
        throw (sax::SAXException, uno::RuntimeException)
{
    if ( this->isSkipping() )
    {
        this->startSkipping( aName, xAttribs );
        return;
    }

    ElementInfo aInfo = getDataParser().parseElementInfo(aName,xAttribs);

    try
    {
        switch (aInfo.type)
        {
        case ElementType::schema:
            this->startSchema(aInfo,xAttribs);
            break;

        case ElementType::component:
            this->startSection(selectComponent, aInfo, xAttribs);
            break;

        case ElementType::templates:
            this->startSection(selectTemplates, aInfo, xAttribs);
            break;

        case ElementType::import:
            this->handleImport(aInfo,xAttribs);
            this->startSkipping( aName, xAttribs );
            break;

        case ElementType::uses:
            this->startSkipping( aName, xAttribs );
            break;

        case ElementType::instance:
            this->handleInstance(aInfo,xAttribs);
            this->startSkipping( aName, xAttribs );
            break;

        case ElementType::item_type:
            this->handleItemType(aInfo,xAttribs);
            this->startSkipping( aName, xAttribs );
            break;

        case ElementType::layer:
        case ElementType::node:
            raiseParseException( "Schema XML parser - Invalid data: found unspecified 'node' element.\n");
            // fall thru
        case ElementType::group: case ElementType::set:
            this->startNode(aInfo,xAttribs);
            OSL_ASSERT( this->isInNode()  );
            break;

        case ElementType::property:
            this->startProperty(aInfo,xAttribs);
            OSL_ASSERT( this->isInUnhandledProperty() );
            break;

        case ElementType::value:
            this->startValueData(xAttribs);
            OSL_ASSERT( this->isInValueData() );
            break;

        default: // skip unknown elements
            OSL_ENSURE( aInfo.type <= ElementType::other, "Schema XML parser - Error: invalid element type value\n");
            OSL_ENSURE( aInfo.type >= ElementType::other, "Schema XML parser - Unexpected: found layer element in schema data\n");
        // accept (and skip) unknown (ElementType::other) tags in schema to allow documentation and constraints to pass without assertion
          //OSL_ENSURE( aInfo.type <  ElementType::other, "Schema XML parser - Warning: ignoring unknown element tag\n");

            this->startSkipping( aName, xAttribs );
            OSL_ASSERT( this->isSkipping() );
            return;
        }
    }
    WRAP_PARSE_EXCEPTIONS_MSG("LayerParser - Starting Element")

    OSL_ENSURE(aInfo.op == Operation::none || this->isSkipping(),
                "Schema Parser: The 'op' attribute is not supported in a schema");
}
// -----------------------------------------------------------------------------

void SAL_CALL SchemaParser::endElement( const OUString& aName )
        throw (sax::SAXException, uno::RuntimeException)
{
    if ( this->wasSkipping(aName) )
        return;

    try
    {
        if ( this->isInValueData())
            this->endValueData();

        else if (this->isInProperty())
            this->endProperty();

        else if (this->isInNode())
            this->endNode();

        else if (this->isSelected())
            this->endSection();

        else
            this->endSchema();
    }
    WRAP_PARSE_EXCEPTIONS_MSG("LayerParser - Ending Element")
}
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------

void SchemaParser::startSchema( ElementInfo const & aInfo, const uno::Reference< sax::XAttributeList >& xAttribs )
{
    m_sComponent = aInfo.name;
    m_xHandler->startSchema();
}
// -----------------------------------------------------------------------------

void SchemaParser::endSchema( )
{
    m_xHandler->endSchema();
    m_sComponent = OUString();
}
// -----------------------------------------------------------------------------

bool SchemaParser::select(Select _select)
{
    if (isSelected())
        raiseParseException("Schema XML parser - Invalid data: found start of section while a section is still open.\n");

    m_selected = static_cast<Select>(m_selector & _select);

    return m_selected != 0;
}
// -----------------------------------------------------------------------------

void SchemaParser::startSection( Select _select, ElementInfo const & aInfo, const uno::Reference< sax::XAttributeList >& xAttribs )
{
    if (this->select(_select))
    {
        if (_select == selectComponent)
        {
            m_xHandler->startComponent(m_sComponent);
        }
    }
    else
        startSkipping(aInfo.name,xAttribs);
}
// -----------------------------------------------------------------------------

void SchemaParser::endSection( )
{
    if (m_selected == selectComponent)
    {
        m_xHandler->endComponent();
    }
    m_selected = selectNone;
}
// -----------------------------------------------------------------------------

void SchemaParser::handleImport( ElementInfo const & aInfo, const uno::Reference< sax::XAttributeList >& xAttribs )
{
    OUString aComponent;
    if (getDataParser().getImportComponent(xAttribs,aComponent))
        m_xHandler->importComponent(aComponent);

    else
        raiseParseException("Schema XML parser - Invalid data: Missing component attribute for import directive.\n");
}
// -----------------------------------------------------------------------------

void SchemaParser::handleInstance( ElementInfo const & aInfo, const uno::Reference< sax::XAttributeList >& xAttribs )
{
    backenduno::TemplateIdentifier aTemplate;
    if (getDataParser().getInstanceType(xAttribs, aTemplate.Name, aTemplate.Component))
        m_xHandler->addInstance(aInfo.name, aTemplate);

    else
        raiseParseException("Schema XML parser - Invalid data: Missing type information for instantiation directive.\n");
}
// -----------------------------------------------------------------------------

void SchemaParser::handleItemType( ElementInfo const & aInfo, const uno::Reference< sax::XAttributeList >& xAttribs )
{
    backenduno::TemplateIdentifier aTemplate;
    if (getDataParser().getInstanceType(xAttribs, aTemplate.Name, aTemplate.Component))
        m_xHandler->addItemType(aTemplate);

    else
        raiseParseException("Schema XML parser - Invalid data: Missing type information for instantiation directive.\n");
}
// -----------------------------------------------------------------------------

void SchemaParser::startNode( ElementInfo const & aInfo, const uno::Reference< sax::XAttributeList >& xAttribs )
{
    bool bStartTemplate = ( !isInNode() && m_selected == selectTemplates );

    BasicParser::startNode(aInfo,xAttribs);

    OSL_ASSERT(aInfo.type == ElementType::set || aInfo.type == ElementType::group);

    using backenduno::TemplateIdentifier;

    if (aInfo.type == ElementType::group)
    {
        if (bStartTemplate)
            m_xHandler->startGroupTemplate( TemplateIdentifier(aInfo.name,m_sComponent), aInfo.flags );

        else
            m_xHandler->startGroup( aInfo.name, aInfo.flags );
    }
    else
    {
        TemplateIdentifier aItemType;

        if (!getDataParser().getSetElementType(xAttribs, aItemType.Name, aItemType.Component))
            raiseParseException("Schema XML parser - Invalid data: Missing item-type information for set node.\n");

        if (bStartTemplate)
            m_xHandler->startSetTemplate( TemplateIdentifier(aInfo.name,m_sComponent), aInfo.flags, aItemType );

        else
            m_xHandler->startSet( aInfo.name, aInfo.flags, aItemType );
    }
}
// -----------------------------------------------------------------------------

void SchemaParser::endNode()
{
    BasicParser::endNode();

    bool bEndedTemplate = ( !isInNode() && m_selected == selectTemplates );

    if (bEndedTemplate)
        m_xHandler->endTemplate();

    else
        m_xHandler->endNode();
}
// -----------------------------------------------------------------------------

void SchemaParser::startProperty( ElementInfo const & aInfo, const uno::Reference< sax::XAttributeList >& xAttribs )
{
    BasicParser::startProperty(aInfo,xAttribs);

    OSL_ENSURE( isInUnhandledProperty(), "Property not recognizable as unhandled");
}
// -----------------------------------------------------------------------------

void SchemaParser::endProperty()
{
    if (isInUnhandledProperty())
    {
        ElementInfo const & aInfo = this->getActiveNodeInfo();

        m_xHandler->addProperty(aInfo.name,
                                aInfo.flags,
                                getActivePropertyType());
    }

    BasicParser::endProperty();
}
// -----------------------------------------------------------------------------

void SchemaParser::startValueData(const uno::Reference< sax::XAttributeList >& xAttribs)
{
    OSL_ENSURE( this->isInUnhandledProperty(),"Schema XML parser - multiple values in property are not permitted in the schema.\n");

    BasicParser::startValueData(xAttribs);

    if (this->isValueDataLocalized())
        getLogger().warning("Language attributes on values are ignored in the schema.",
                            "endValueData()","configuration::xml::SchemaParser");
}
// -----------------------------------------------------------------------------

void SchemaParser::endValueData()
{
    uno::Any aValue = this->getCurrentValue();

    ElementInfo const & aInfo = this->getActiveNodeInfo();

    if (aValue.hasValue())
    {
        m_xHandler->addPropertyWithDefault(aInfo.name,aInfo.flags,aValue);
    }
    else
    {
        getLogger().warning("Found deprecated explicit NIL value in schema data.",
                            "endValueData()","configuration::xml::SchemaParser");
        m_xHandler->addProperty(aInfo.name,aInfo.flags,getActivePropertyType());
    }

    BasicParser::endValueData();

    OSL_ENSURE( !isInUnhandledProperty(), "Property not recognizable as handled");
}
// -----------------------------------------------------------------------------

// -----------------------------------------------------------------------------
    } // namespace

// -----------------------------------------------------------------------------
} // namespace

<commit_msg>INTEGRATION: CWS warnings01 (1.10.4); FILE MERGED 2005/11/01 12:47:45 cd 1.10.4.1: #i53898# Warning free code for sun solaris compiler<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: schemaparser.cxx,v $
 *
 *  $Revision: 1.11 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-19 23:36:50 $
 *
 *  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
 *
 ************************************************************************/

#include "schemaparser.hxx"

// -----------------------------------------------------------------------------
#ifndef CONFIGMGR_WRAPEXCEPTION_HXX
#include "wrapexception.hxx"
#endif

#define WRAP_PARSE_EXCEPTIONS()  \
    PASS_EXCEPTION(sax::SAXException)       \
    PASS_EXCEPTION(uno::RuntimeException)   \
    WRAP_CONFIGDATA_EXCEPTIONS( raiseParseException )   \
    WRAP_OTHER_EXCEPTIONS( raiseParseException )

#define WRAP_PARSE_EXCEPTIONS_MSG( msg )  \
    PASS_EXCEPTION(sax::SAXException)       \
    PASS_EXCEPTION(uno::RuntimeException)   \
    WRAP_CONFIGDATA_EXCEPTIONS1( raiseParseException, msg ) \
    WRAP_OTHER_EXCEPTIONS1( raiseParseException, msg )

// -----------------------------------------------------------------------------

namespace configmgr
{
// -----------------------------------------------------------------------------
    namespace xml
    {
// -----------------------------------------------------------------------------
        namespace uno       = ::com::sun::star::uno;
        namespace sax       = ::com::sun::star::xml::sax;
// -----------------------------------------------------------------------------

SchemaParser::SchemaParser(Context const & _xContext, uno::Reference< backenduno::XSchemaHandler > const & _xHandler, Select _selector)
: BasicParser(_xContext)
, m_xHandler(_xHandler)
, m_sComponent()
, m_selector(_selector)
, m_selected(selectNone)
{
    if (!m_xHandler.is())
    {
        OUString sMessage(RTL_CONSTASCII_USTRINGPARAM("Cannot create SchemaParser: Unexpected NULL Handler"));
        throw uno::RuntimeException(sMessage, *this);
    }
    OSL_ENSURE(m_selector != selectNone, "Warning: Schema handler will handle no part of the schema");
}
// -----------------------------------------------------------------------------

SchemaParser::~SchemaParser()
{
}
// -----------------------------------------------------------------------------

void SAL_CALL SchemaParser::startDocument(  )
        throw (sax::SAXException, uno::RuntimeException)
{
    BasicParser::startDocument();

    OSL_ENSURE(isEmptyNode(), "BasicParser does not mark new document as empty");

    m_sComponent = OUString();
    m_selected = selectNone;
}
// -----------------------------------------------------------------------------

void SAL_CALL SchemaParser::endDocument(  ) throw (sax::SAXException, uno::RuntimeException)
{
    if (isSelected())
        raiseParseException("Schema XML Parser: Invalid XML: Document ends while section is open");

    if (isEmptyNode()) OSL_TRACE("Configuration Parser: XML schema document ended without any data");

    BasicParser::endDocument();
}
// -----------------------------------------------------------------------------

void SAL_CALL SchemaParser::startElement( const OUString& aName, const uno::Reference< sax::XAttributeList >& xAttribs )
        throw (sax::SAXException, uno::RuntimeException)
{
    if ( this->isSkipping() )
    {
        this->startSkipping( aName, xAttribs );
        return;
    }

    ElementInfo aInfo = getDataParser().parseElementInfo(aName,xAttribs);

    try
    {
        switch (aInfo.type)
        {
        case ElementType::schema:
            this->startSchema(aInfo,xAttribs);
            break;

        case ElementType::component:
            this->startSection(selectComponent, aInfo, xAttribs);
            break;

        case ElementType::templates:
            this->startSection(selectTemplates, aInfo, xAttribs);
            break;

        case ElementType::import:
            this->handleImport(aInfo,xAttribs);
            this->startSkipping( aName, xAttribs );
            break;

        case ElementType::uses:
            this->startSkipping( aName, xAttribs );
            break;

        case ElementType::instance:
            this->handleInstance(aInfo,xAttribs);
            this->startSkipping( aName, xAttribs );
            break;

        case ElementType::item_type:
            this->handleItemType(aInfo,xAttribs);
            this->startSkipping( aName, xAttribs );
            break;

        case ElementType::layer:
        case ElementType::node:
            raiseParseException( "Schema XML parser - Invalid data: found unspecified 'node' element.\n");
            // fall thru
        case ElementType::group: case ElementType::set:
            this->startNode(aInfo,xAttribs);
            OSL_ASSERT( this->isInNode()  );
            break;

        case ElementType::property:
            this->startProperty(aInfo,xAttribs);
            OSL_ASSERT( this->isInUnhandledProperty() );
            break;

        case ElementType::value:
            this->startValueData(xAttribs);
            OSL_ASSERT( this->isInValueData() );
            break;

        default: // skip unknown elements
            OSL_ENSURE( aInfo.type <= ElementType::other, "Schema XML parser - Error: invalid element type value\n");
            OSL_ENSURE( aInfo.type >= ElementType::other, "Schema XML parser - Unexpected: found layer element in schema data\n");
        // accept (and skip) unknown (ElementType::other) tags in schema to allow documentation and constraints to pass without assertion
          //OSL_ENSURE( aInfo.type <  ElementType::other, "Schema XML parser - Warning: ignoring unknown element tag\n");

            this->startSkipping( aName, xAttribs );
            OSL_ASSERT( this->isSkipping() );
            return;
        }
    }
    WRAP_PARSE_EXCEPTIONS_MSG("LayerParser - Starting Element")

    OSL_ENSURE(aInfo.op == Operation::none || this->isSkipping(),
                "Schema Parser: The 'op' attribute is not supported in a schema");
}
// -----------------------------------------------------------------------------

void SAL_CALL SchemaParser::endElement( const OUString& aName )
        throw (sax::SAXException, uno::RuntimeException)
{
    if ( this->wasSkipping(aName) )
        return;

    try
    {
        if ( this->isInValueData())
            this->endValueData();

        else if (this->isInProperty())
            this->endProperty();

        else if (this->isInNode())
            this->endNode();

        else if (this->isSelected())
            this->endSection();

        else
            this->endSchema();
    }
    WRAP_PARSE_EXCEPTIONS_MSG("LayerParser - Ending Element")
}
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------

void SchemaParser::startSchema( ElementInfo const & aInfo, const uno::Reference< sax::XAttributeList >& /*xAttribs*/ )
{
    m_sComponent = aInfo.name;
    m_xHandler->startSchema();
}
// -----------------------------------------------------------------------------

void SchemaParser::endSchema( )
{
    m_xHandler->endSchema();
    m_sComponent = OUString();
}
// -----------------------------------------------------------------------------

bool SchemaParser::select(Select _select)
{
    if (isSelected())
        raiseParseException("Schema XML parser - Invalid data: found start of section while a section is still open.\n");

    m_selected = static_cast<Select>(m_selector & _select);

    return m_selected != 0;
}
// -----------------------------------------------------------------------------

void SchemaParser::startSection( Select _select, ElementInfo const & aInfo, const uno::Reference< sax::XAttributeList >& xAttribs )
{
    if (this->select(_select))
    {
        if (_select == selectComponent)
        {
            m_xHandler->startComponent(m_sComponent);
        }
    }
    else
        startSkipping(aInfo.name,xAttribs);
}
// -----------------------------------------------------------------------------

void SchemaParser::endSection( )
{
    if (m_selected == selectComponent)
    {
        m_xHandler->endComponent();
    }
    m_selected = selectNone;
}
// -----------------------------------------------------------------------------

void SchemaParser::handleImport( ElementInfo const & /*aInfo*/, const uno::Reference< sax::XAttributeList >& xAttribs )
{
    OUString aComponent;
    if (getDataParser().getImportComponent(xAttribs,aComponent))
        m_xHandler->importComponent(aComponent);

    else
        raiseParseException("Schema XML parser - Invalid data: Missing component attribute for import directive.\n");
}
// -----------------------------------------------------------------------------

void SchemaParser::handleInstance( ElementInfo const & aInfo, const uno::Reference< sax::XAttributeList >& xAttribs )
{
    backenduno::TemplateIdentifier aTemplate;
    if (getDataParser().getInstanceType(xAttribs, aTemplate.Name, aTemplate.Component))
        m_xHandler->addInstance(aInfo.name, aTemplate);

    else
        raiseParseException("Schema XML parser - Invalid data: Missing type information for instantiation directive.\n");
}
// -----------------------------------------------------------------------------

void SchemaParser::handleItemType( ElementInfo const & /*aInfo*/, const uno::Reference< sax::XAttributeList >& xAttribs )
{
    backenduno::TemplateIdentifier aTemplate;
    if (getDataParser().getInstanceType(xAttribs, aTemplate.Name, aTemplate.Component))
        m_xHandler->addItemType(aTemplate);

    else
        raiseParseException("Schema XML parser - Invalid data: Missing type information for instantiation directive.\n");
}
// -----------------------------------------------------------------------------

void SchemaParser::startNode( ElementInfo const & aInfo, const uno::Reference< sax::XAttributeList >& xAttribs )
{
    bool bStartTemplate = ( !isInNode() && m_selected == selectTemplates );

    BasicParser::startNode(aInfo,xAttribs);

    OSL_ASSERT(aInfo.type == ElementType::set || aInfo.type == ElementType::group);

    using backenduno::TemplateIdentifier;

    if (aInfo.type == ElementType::group)
    {
        if (bStartTemplate)
            m_xHandler->startGroupTemplate( TemplateIdentifier(aInfo.name,m_sComponent), aInfo.flags );

        else
            m_xHandler->startGroup( aInfo.name, aInfo.flags );
    }
    else
    {
        TemplateIdentifier aItemType;

        if (!getDataParser().getSetElementType(xAttribs, aItemType.Name, aItemType.Component))
            raiseParseException("Schema XML parser - Invalid data: Missing item-type information for set node.\n");

        if (bStartTemplate)
            m_xHandler->startSetTemplate( TemplateIdentifier(aInfo.name,m_sComponent), aInfo.flags, aItemType );

        else
            m_xHandler->startSet( aInfo.name, aInfo.flags, aItemType );
    }
}
// -----------------------------------------------------------------------------

void SchemaParser::endNode()
{
    BasicParser::endNode();

    bool bEndedTemplate = ( !isInNode() && m_selected == selectTemplates );

    if (bEndedTemplate)
        m_xHandler->endTemplate();

    else
        m_xHandler->endNode();
}
// -----------------------------------------------------------------------------

void SchemaParser::startProperty( ElementInfo const & aInfo, const uno::Reference< sax::XAttributeList >& xAttribs )
{
    BasicParser::startProperty(aInfo,xAttribs);

    OSL_ENSURE( isInUnhandledProperty(), "Property not recognizable as unhandled");
}
// -----------------------------------------------------------------------------

void SchemaParser::endProperty()
{
    if (isInUnhandledProperty())
    {
        ElementInfo const & aInfo = this->getActiveNodeInfo();

        m_xHandler->addProperty(aInfo.name,
                                aInfo.flags,
                                getActivePropertyType());
    }

    BasicParser::endProperty();
}
// -----------------------------------------------------------------------------

void SchemaParser::startValueData(const uno::Reference< sax::XAttributeList >& xAttribs)
{
    OSL_ENSURE( this->isInUnhandledProperty(),"Schema XML parser - multiple values in property are not permitted in the schema.\n");

    BasicParser::startValueData(xAttribs);

    if (this->isValueDataLocalized())
        getLogger().warning("Language attributes on values are ignored in the schema.",
                            "endValueData()","configuration::xml::SchemaParser");
}
// -----------------------------------------------------------------------------

void SchemaParser::endValueData()
{
    uno::Any aValue = this->getCurrentValue();

    ElementInfo const & aInfo = this->getActiveNodeInfo();

    if (aValue.hasValue())
    {
        m_xHandler->addPropertyWithDefault(aInfo.name,aInfo.flags,aValue);
    }
    else
    {
        getLogger().warning("Found deprecated explicit NIL value in schema data.",
                            "endValueData()","configuration::xml::SchemaParser");
        m_xHandler->addProperty(aInfo.name,aInfo.flags,getActivePropertyType());
    }

    BasicParser::endValueData();

    OSL_ENSURE( !isInUnhandledProperty(), "Property not recognizable as handled");
}
// -----------------------------------------------------------------------------

// -----------------------------------------------------------------------------
    } // namespace

// -----------------------------------------------------------------------------
} // namespace

<|endoftext|>


<commit_before>// Copyright (c) 2009-2012 Bitcoin Developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "init.h" // for pwalletMain
#include "bitcoinrpc.h"
#include "ui_interface.h"
#include "base58.h"

#include <boost/lexical_cast.hpp>

#define printf OutputDebugStringF

using namespace json_spirit;
using namespace std;

class CTxDump
{
public:
    CBlockIndex *pindex;
    int64 nValue;
    bool fSpent;
    CWalletTx* ptx;
    int nOut;
    CTxDump(CWalletTx* ptx = NULL, int nOut = -1)
    {
        pindex = NULL;
        nValue = 0;
        fSpent = false;
        this->ptx = ptx;
        this->nOut = nOut;
    }
};

Value importprivkey(const Array& params, bool fHelp)
{
    if (fHelp || params.size() < 1 || params.size() > 3)
        throw runtime_error(
            "importprivkey <reddcoinprivkey> [label] [rescan=true]\n"
            "Adds a private key (as returned by dumpprivkey) to your wallet.");

    EnsureWalletIsUnlocked();

    string strSecret = params[0].get_str();
    string strLabel = "";
    if (params.size() > 1)
        strLabel = params[1].get_str();

    // Whether to perform rescan after import
    bool fRescan = true;
    if (params.size() > 2)
        fRescan = params[2].get_bool();

    CBitcoinSecret vchSecret;
    bool fGood = vchSecret.SetString(strSecret);

    if (!fGood) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key");

    CKey key = vchSecret.GetKey();
    CPubKey pubkey = key.GetPubKey();
    CKeyID vchAddress = pubkey.GetID();
    {
        LOCK2(cs_main, pwalletMain->cs_wallet);

        pwalletMain->MarkDirty();
        pwalletMain->SetAddressBookName(vchAddress, strLabel);

        if (!pwalletMain->AddKeyPubKey(key, pubkey))
            throw JSONRPCError(RPC_WALLET_ERROR, "Error adding key to wallet");

        if (fRescan) {
            pwalletMain->ScanForWalletTransactions(pindexGenesisBlock, true);
            pwalletMain->ReacceptWalletTransactions();
        }
    }

    return Value::null;
}

Value dumpprivkey(const Array& params, bool fHelp)
{
    if (fHelp || params.size() != 1)
        throw runtime_error(
            "dumpprivkey <reddcoinaddress>\n"
            "Reveals the private key corresponding to <reddcoinaddress>.");

    string strAddress = params[0].get_str();
    CBitcoinAddress address;
    if (!address.SetString(strAddress))
        throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Reddcoin address");
    CKeyID keyID;
    if (!address.GetKeyID(keyID))
        throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to a key");
    CKey vchSecret;
    if (!pwalletMain->GetKey(keyID, vchSecret))
        throw JSONRPCError(RPC_WALLET_ERROR, "Private key for address " + strAddress + " is not known");
    return CBitcoinSecret(vchSecret).ToString();
}
<commit_msg>Add check for valid keys in `importprivkey`<commit_after>// Copyright (c) 2009-2012 Bitcoin Developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "init.h" // for pwalletMain
#include "bitcoinrpc.h"
#include "ui_interface.h"
#include "base58.h"

#include <boost/lexical_cast.hpp>

#define printf OutputDebugStringF

using namespace json_spirit;
using namespace std;

class CTxDump
{
public:
    CBlockIndex *pindex;
    int64 nValue;
    bool fSpent;
    CWalletTx* ptx;
    int nOut;
    CTxDump(CWalletTx* ptx = NULL, int nOut = -1)
    {
        pindex = NULL;
        nValue = 0;
        fSpent = false;
        this->ptx = ptx;
        this->nOut = nOut;
    }
};

Value importprivkey(const Array& params, bool fHelp)
{
    if (fHelp || params.size() < 1 || params.size() > 3)
        throw runtime_error(
            "importprivkey <reddcoinprivkey> [label] [rescan=true]\n"
            "Adds a private key (as returned by dumpprivkey) to your wallet.");

    EnsureWalletIsUnlocked();

    string strSecret = params[0].get_str();
    string strLabel = "";
    if (params.size() > 1)
        strLabel = params[1].get_str();

    // Whether to perform rescan after import
    bool fRescan = true;
    if (params.size() > 2)
        fRescan = params[2].get_bool();

    CBitcoinSecret vchSecret;
    bool fGood = vchSecret.SetString(strSecret);

    if (!fGood) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key encoding");

    CKey key = vchSecret.GetKey();
    CPubKey pubkey = key.GetPubKey();
    CKeyID vchAddress = pubkey.GetID();
    if (!key.IsValid()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Private key outside allowed range");

    {
        LOCK2(cs_main, pwalletMain->cs_wallet);

        pwalletMain->MarkDirty();
        pwalletMain->SetAddressBookName(vchAddress, strLabel);

        if (!pwalletMain->AddKeyPubKey(key, pubkey))
            throw JSONRPCError(RPC_WALLET_ERROR, "Error adding key to wallet");

        if (fRescan) {
            pwalletMain->ScanForWalletTransactions(pindexGenesisBlock, true);
            pwalletMain->ReacceptWalletTransactions();
        }
    }

    return Value::null;
}

Value dumpprivkey(const Array& params, bool fHelp)
{
    if (fHelp || params.size() != 1)
        throw runtime_error(
            "dumpprivkey <reddcoinaddress>\n"
            "Reveals the private key corresponding to <reddcoinaddress>.");

    string strAddress = params[0].get_str();
    CBitcoinAddress address;
    if (!address.SetString(strAddress))
        throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Reddcoin address");
    CKeyID keyID;
    if (!address.GetKeyID(keyID))
        throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to a key");
    CKey vchSecret;
    if (!pwalletMain->GetKey(keyID, vchSecret))
        throw JSONRPCError(RPC_WALLET_ERROR, "Private key for address " + strAddress + " is not known");
    return CBitcoinSecret(vchSecret).ToString();
}
<|endoftext|>


<commit_before>#include "data.h"

#include <cassert>
#include <map>
#include <vector>

namespace redsea {

std::string getLCDchar(int code) {
  assert (code >= 32);
  const std::vector<std::string> char_map ({
      " ","!","\\\"","#","¤","%","&","'","(",")","*","+",",","-",".","/",
      "0","1","2","3","4","5","6","7","8","9",":",";","<","=",">","?",
      "@","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O",
      "P","Q","R","S","T","U","V","W","X","Y","Z","[","\\","]","―","_",
      "‖","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o",
      "p","q","r","s","t","u","v","w","x","y","z","{","|","}","¯"," ",
      "á","à","é","è","í","ì","ó","ò","ú","ù","Ñ","Ç","Ş","β","¡","Ĳ",
      "â","ä","ê","ë","î","ï","ô","ö","û","ü","ñ","ç","ş","ǧ","ı","ĳ",
      "ª","α","©","‰","Ǧ","ě","ň","ő","π","€","£","$","←","↑","→","↓",
      "º","¹","²","³","±","İ","ń","ű","µ","¿","÷","°","¼","½","¾","§",
      "Á","À","É","È","Í","Ì","Ó","Ò","Ú","Ù","Ř","Č","Š","Ž","Ð","Ŀ",
      "Â","Ä","Ê","Ë","Î","Ï","Ô","Ö","Û","Ü","ř","č","š","ž","đ","ŀ",
      "Ã","Å","Æ","Œ","ŷ","Ý","Õ","Ø","Þ","Ŋ","Ŕ","Ć","Ś","Ź","Ŧ","ð",
      "ã","å","æ","œ","ŵ","ý","õ","ø","þ","ŋ","ŕ","ć","ś","ź","ŧ"," "});
  return char_map[code - 32];
}

std::string getPTYname(int pty) {
  assert (pty >= 0 && pty <= 32);
  const std::vector<std::string> pty_names ({
   "No PTY", "News", "Current Affairs", "Information",
   "Sport", "Education", "Drama", "Cultures",
   "Science", "Varied Speech","Pop Music", "Rock Music",
   "Easy Listening","Light Classics M","Serious Classics","Other Music",
   "Weather & Metr", "Finance", "Children's Progs", "Social Affairs",
   "Religion", "Phone In", "Travel & Touring", "Leisure & Hobby",
   "Jazz Music", "Country Music", "National Music", "Oldies Music",
   "Folk Music", "Documentary", "Alarm Test", "Alarm - Alarm !"
  });
  return pty_names[pty];

}

std::string getCountryString(uint16_t pi, uint16_t ecc) {
  const std::map<uint16_t,std::vector<std::string>> country_codes ({
    {0xA0,{"us","us","us","us","us","us","us","us","us","us","us","--","us","us","--"}},
    {0xA1,{"--","--","--","--","--","--","--","--","--","--","ca","ca","ca","ca","gl"}},
    {0xA2,{"ai","ag","ec","fk","bb","bz","ky","cr","cu","ar","br","bm","an","gp","bs"}},
    {0xA3,{"bo","co","jm","mq","gf","py","ni","--","pa","dm","do","cl","gd","tc","gy"}},
    {0xA4,{"gt","hn","aw","--","ms","tt","pe","sr","uy","kn","lc","sv","ht","ve","--"}},
    {0xA5,{"--","--","--","--","--","--","--","--","--","--","mx","vc","mx","mx","mx"}},
    {0xA6,{"--","--","--","--","--","--","--","--","--","--","--","--","--","--","pm"}},
    {0xD0,{"cm","cf","dj","mg","ml","ao","gq","ga","gn","za","bf","cg","tg","bj","mw"}},
    {0xD1,{"na","lr","gh","mr","st","cv","sn","gm","bi","--","bw","km","tz","et","bg"}},
    {0xD2,{"sl","zw","mz","ug","sz","ke","so","ne","td","gw","zr","ci","tz","zm","--"}},
    {0xD3,{"--","--","eh","--","rw","ls","--","sc","--","mu","--","sd","--","--","--"}},
    {0xE0,{"de","dz","ad","il","it","be","ru","ps","al","at","hu","mt","de","--","eg"}},
    {0xE1,{"gr","cy","sm","ch","jo","fi","lu","bg","dk","gi","iq","gb","ly","ro","fr"}},
    {0xE2,{"ma","cz","pl","va","sk","sy","tn","--","li","is","mc","lt","yu","es","no"}},
    {0xE3,{"ie","ie","tr","mk","tj","--","--","nl","lv","lb","az","hr","kz","se","by"}},
    {0xE4,{"md","ee","kg","--","--","ua","--","pt","si","am","uz","ge","--","tm","ba"}},
    {0xF0,{"au","au","au","au","au","au","au","au","sa","af","mm","cn","kp","bh","my"}},
    {0xF1,{"ki","bt","bd","pk","fj","om","nr","ir","nz","sb","bn","lk","tw","kr","hk"}},
    {0xF2,{"kw","qa","kh","ws","in","mo","vn","ph","jp","sg","mv","id","ae","np","vu"}},
    {0xF3,{"la","th","to","--","--","--","--","--","pg","--","ye","--","--","fm","mn"}}
  });

  std::string result("--");

  uint16_t pi_cc = pi >> 12;

  if (country_codes.find(ecc) != country_codes.end() && pi_cc > 0) {
    result = country_codes.at(ecc).at(pi_cc-1);
  }

  return result;

}

std::string getLanguageString(uint16_t code) {
  std::vector<std::string> languages ({
    "Unknown","Albanian","Breton","Catalan",
    "Croatian","Welsh","Czech","Danish",
    "German","English","Spanish","Esperanto",
    "Estonian","Basque","Faroese","French",
    "Frisian","Irish","Gaelic","Galician",
    "Icelandic","Italian","Lappish","Latin",
    "Latvian","Luxembourgian","Lithuanian","Hungarian",
    "Maltese","Dutch","Norwegian","Occitan",
    "Polish","Portuguese","Romanian","Romansh",
    "Serbian","Slovak","Slovene","Finnish",
    "Swedish","Turkish","Flemish","Walloon",
    "","","","",
    "","","","",
    "","","","",
    "","","","",
    "","","","",
    "Background","","","",
    "","Zulu","Vietnamese","Uzbek",
    "Urdu","Ukrainian","Thai","Telugu",
    "Tatar","Tamil","Tadzhik","Swahili",
    "SrananTongo","Somali","Sinhalese","Shona",
    "Serbo-Croat","Ruthenian","Russian","Quechua",
    "Pushtu","Punjabi","Persian","Papamiento",
    "Oriya","Nepali","Ndebele","Marathi",
    "Moldovian","Malaysian","Malagasay","Macedonian",
    "Laotian","Korean","Khmer","Kazakh",
    "Kannada","Japanese","Indonesian","Hindi",
    "Hebrew","Hausa","Gurani","Gujurati",
    "Greek","Georgian","Fulani","Dari",
    "Churash","Chinese","Burmese","Bulgarian",
    "Bengali","Belorussian","Bambora","Azerbaijan",
    "Assamese","Armenian","Arabic","Amharic"
  });

  std::string result("");
  if (code < languages.size()) {
    result = languages[code];
  }

  return result;
}

std::string getAppName(uint16_t aid) {
  std::map<uint16_t,std::string> oda_apps({
    { 0x0000, "None" },
    { 0x0093, "Cross referencing DAB within RDS" },
    { 0x0BCB, "Leisure & Practical Info for Drivers" },
    { 0x0C24, "ELECTRABEL-DSM 7" },
    { 0x0CC1, "Wireless Playground broadcast control signal" },
    { 0x0D45, "RDS-TMC: ALERT-C / EN ISO 14819-1" },
    { 0x0D8B, "ELECTRABEL-DSM 18" },
    { 0x0E2C, "ELECTRABEL-DSM 3" },
    { 0x0E31, "ELECTRABEL-DSM 13" },
    { 0x0F87, "ELECTRABEL-DSM 2" },
    { 0x125F, "I-FM-RDS for fixed and mobile devices" },
    { 0x1BDA, "ELECTRABEL-DSM 1" },
    { 0x1C5E, "ELECTRABEL-DSM 20" },
    { 0x1C68, "ITIS In-vehicle data base" },
    { 0x1CB1, "ELECTRABEL-DSM 10" },
    { 0x1D47, "ELECTRABEL-DSM 4" },
    { 0x1DC2, "CITIBUS 4" },
    { 0x1DC5, "Encrypted TTI using ALERT-Plus" },
    { 0x1E8F, "ELECTRABEL-DSM 17" },
    { 0x4AA1, "RASANT" },
    { 0x4AB7, "ELECTRABEL-DSM 9" },
    { 0x4BA2, "ELECTRABEL-DSM 5" },
    { 0x4BD7, "RadioText+ (RT+)" },
    { 0x4C59, "CITIBUS 2" },
    { 0x4D87, "Radio Commerce System (RCS)" },
    { 0x4D95, "ELECTRABEL-DSM 16" },
    { 0x4D9A, "ELECTRABEL-DSM 11" },
    { 0x5757, "Personal weather station" },
    { 0x6552, "Enhanced RadioText (eRT)" },
    { 0x7373, "Enhanced early warning system" },
    { 0xC350, "NRSC Song Title and Artist" },
    { 0xC3A1, "Personal Radio Service" },
    { 0xC3B0, "iTunes Tagging" },
    { 0xC3C3, "NAVTEQ Traffic Plus" },
    { 0xC4D4, "eEAS" },
    { 0xC549, "Smart Grid Broadcast Channel" },
    { 0xC563, "ID Logic" },
    { 0xC6A7, "Veil Enabled Interactive Device" },
    { 0xC737, "Utility Message Channel (UMC)" },
    { 0xCB73, "CITIBUS 1" },
    { 0xCB97, "ELECTRABEL-DSM 14" },
    { 0xCC21, "CITIBUS 3" },
    { 0xCD46, "RDS-TMC: ALERT-C" },
    { 0xCD47, "RDS-TMC: ALERT-C" },
    { 0xCD9E, "ELECTRABEL-DSM 8" },
    { 0xCE6B, "Encrypted TTI using ALERT-Plus" },
    { 0xE123, "APS Gateway" },
    { 0xE1C1, "Action code" },
    { 0xE319, "ELECTRABEL-DSM 12" },
    { 0xE411, "Beacon downlink" },
    { 0xE440, "ELECTRABEL-DSM 15" },
    { 0xE4A6, "ELECTRABEL-DSM 19" },
    { 0xE5D7, "ELECTRABEL-DSM 6" },
    { 0xE911, "EAS open protocol" }
  });

  std::string result("");
  if (oda_apps.find(aid) != oda_apps.end()) {
    result = oda_apps[aid];
  }

  return result;
}

}
<commit_msg>ODA app name defaults to (Unknown)<commit_after>#include "data.h"

#include <cassert>
#include <map>
#include <vector>

namespace redsea {

std::string getLCDchar(int code) {
  assert (code >= 32);
  const std::vector<std::string> char_map ({
      " ","!","\\\"","#","¤","%","&","'","(",")","*","+",",","-",".","/",
      "0","1","2","3","4","5","6","7","8","9",":",";","<","=",">","?",
      "@","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O",
      "P","Q","R","S","T","U","V","W","X","Y","Z","[","\\","]","―","_",
      "‖","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o",
      "p","q","r","s","t","u","v","w","x","y","z","{","|","}","¯"," ",
      "á","à","é","è","í","ì","ó","ò","ú","ù","Ñ","Ç","Ş","β","¡","Ĳ",
      "â","ä","ê","ë","î","ï","ô","ö","û","ü","ñ","ç","ş","ǧ","ı","ĳ",
      "ª","α","©","‰","Ǧ","ě","ň","ő","π","€","£","$","←","↑","→","↓",
      "º","¹","²","³","±","İ","ń","ű","µ","¿","÷","°","¼","½","¾","§",
      "Á","À","É","È","Í","Ì","Ó","Ò","Ú","Ù","Ř","Č","Š","Ž","Ð","Ŀ",
      "Â","Ä","Ê","Ë","Î","Ï","Ô","Ö","Û","Ü","ř","č","š","ž","đ","ŀ",
      "Ã","Å","Æ","Œ","ŷ","Ý","Õ","Ø","Þ","Ŋ","Ŕ","Ć","Ś","Ź","Ŧ","ð",
      "ã","å","æ","œ","ŵ","ý","õ","ø","þ","ŋ","ŕ","ć","ś","ź","ŧ"," "});
  return char_map[code - 32];
}

std::string getPTYname(int pty) {
  assert (pty >= 0 && pty <= 32);
  const std::vector<std::string> pty_names ({
   "No PTY", "News", "Current Affairs", "Information",
   "Sport", "Education", "Drama", "Cultures",
   "Science", "Varied Speech","Pop Music", "Rock Music",
   "Easy Listening","Light Classics M","Serious Classics","Other Music",
   "Weather & Metr", "Finance", "Children's Progs", "Social Affairs",
   "Religion", "Phone In", "Travel & Touring", "Leisure & Hobby",
   "Jazz Music", "Country Music", "National Music", "Oldies Music",
   "Folk Music", "Documentary", "Alarm Test", "Alarm - Alarm !"
  });
  return pty_names[pty];

}

std::string getCountryString(uint16_t pi, uint16_t ecc) {
  const std::map<uint16_t,std::vector<std::string>> country_codes ({
    {0xA0,{"us","us","us","us","us","us","us","us","us","us","us","--","us","us","--"}},
    {0xA1,{"--","--","--","--","--","--","--","--","--","--","ca","ca","ca","ca","gl"}},
    {0xA2,{"ai","ag","ec","fk","bb","bz","ky","cr","cu","ar","br","bm","an","gp","bs"}},
    {0xA3,{"bo","co","jm","mq","gf","py","ni","--","pa","dm","do","cl","gd","tc","gy"}},
    {0xA4,{"gt","hn","aw","--","ms","tt","pe","sr","uy","kn","lc","sv","ht","ve","--"}},
    {0xA5,{"--","--","--","--","--","--","--","--","--","--","mx","vc","mx","mx","mx"}},
    {0xA6,{"--","--","--","--","--","--","--","--","--","--","--","--","--","--","pm"}},
    {0xD0,{"cm","cf","dj","mg","ml","ao","gq","ga","gn","za","bf","cg","tg","bj","mw"}},
    {0xD1,{"na","lr","gh","mr","st","cv","sn","gm","bi","--","bw","km","tz","et","bg"}},
    {0xD2,{"sl","zw","mz","ug","sz","ke","so","ne","td","gw","zr","ci","tz","zm","--"}},
    {0xD3,{"--","--","eh","--","rw","ls","--","sc","--","mu","--","sd","--","--","--"}},
    {0xE0,{"de","dz","ad","il","it","be","ru","ps","al","at","hu","mt","de","--","eg"}},
    {0xE1,{"gr","cy","sm","ch","jo","fi","lu","bg","dk","gi","iq","gb","ly","ro","fr"}},
    {0xE2,{"ma","cz","pl","va","sk","sy","tn","--","li","is","mc","lt","yu","es","no"}},
    {0xE3,{"ie","ie","tr","mk","tj","--","--","nl","lv","lb","az","hr","kz","se","by"}},
    {0xE4,{"md","ee","kg","--","--","ua","--","pt","si","am","uz","ge","--","tm","ba"}},
    {0xF0,{"au","au","au","au","au","au","au","au","sa","af","mm","cn","kp","bh","my"}},
    {0xF1,{"ki","bt","bd","pk","fj","om","nr","ir","nz","sb","bn","lk","tw","kr","hk"}},
    {0xF2,{"kw","qa","kh","ws","in","mo","vn","ph","jp","sg","mv","id","ae","np","vu"}},
    {0xF3,{"la","th","to","--","--","--","--","--","pg","--","ye","--","--","fm","mn"}}
  });

  std::string result("--");

  uint16_t pi_cc = pi >> 12;

  if (country_codes.find(ecc) != country_codes.end() && pi_cc > 0) {
    result = country_codes.at(ecc).at(pi_cc-1);
  }

  return result;

}

std::string getLanguageString(uint16_t code) {
  std::vector<std::string> languages ({
    "Unknown","Albanian","Breton","Catalan",
    "Croatian","Welsh","Czech","Danish",
    "German","English","Spanish","Esperanto",
    "Estonian","Basque","Faroese","French",
    "Frisian","Irish","Gaelic","Galician",
    "Icelandic","Italian","Lappish","Latin",
    "Latvian","Luxembourgian","Lithuanian","Hungarian",
    "Maltese","Dutch","Norwegian","Occitan",
    "Polish","Portuguese","Romanian","Romansh",
    "Serbian","Slovak","Slovene","Finnish",
    "Swedish","Turkish","Flemish","Walloon",
    "","","","",
    "","","","",
    "","","","",
    "","","","",
    "","","","",
    "Background","","","",
    "","Zulu","Vietnamese","Uzbek",
    "Urdu","Ukrainian","Thai","Telugu",
    "Tatar","Tamil","Tadzhik","Swahili",
    "SrananTongo","Somali","Sinhalese","Shona",
    "Serbo-Croat","Ruthenian","Russian","Quechua",
    "Pushtu","Punjabi","Persian","Papamiento",
    "Oriya","Nepali","Ndebele","Marathi",
    "Moldovian","Malaysian","Malagasay","Macedonian",
    "Laotian","Korean","Khmer","Kazakh",
    "Kannada","Japanese","Indonesian","Hindi",
    "Hebrew","Hausa","Gurani","Gujurati",
    "Greek","Georgian","Fulani","Dari",
    "Churash","Chinese","Burmese","Bulgarian",
    "Bengali","Belorussian","Bambora","Azerbaijan",
    "Assamese","Armenian","Arabic","Amharic"
  });

  std::string result("");
  if (code < languages.size()) {
    result = languages[code];
  }

  return result;
}

std::string getAppName(uint16_t aid) {
  std::map<uint16_t,std::string> oda_apps({
    { 0x0000, "None" },
    { 0x0093, "Cross referencing DAB within RDS" },
    { 0x0BCB, "Leisure & Practical Info for Drivers" },
    { 0x0C24, "ELECTRABEL-DSM 7" },
    { 0x0CC1, "Wireless Playground broadcast control signal" },
    { 0x0D45, "RDS-TMC: ALERT-C / EN ISO 14819-1" },
    { 0x0D8B, "ELECTRABEL-DSM 18" },
    { 0x0E2C, "ELECTRABEL-DSM 3" },
    { 0x0E31, "ELECTRABEL-DSM 13" },
    { 0x0F87, "ELECTRABEL-DSM 2" },
    { 0x125F, "I-FM-RDS for fixed and mobile devices" },
    { 0x1BDA, "ELECTRABEL-DSM 1" },
    { 0x1C5E, "ELECTRABEL-DSM 20" },
    { 0x1C68, "ITIS In-vehicle data base" },
    { 0x1CB1, "ELECTRABEL-DSM 10" },
    { 0x1D47, "ELECTRABEL-DSM 4" },
    { 0x1DC2, "CITIBUS 4" },
    { 0x1DC5, "Encrypted TTI using ALERT-Plus" },
    { 0x1E8F, "ELECTRABEL-DSM 17" },
    { 0x4AA1, "RASANT" },
    { 0x4AB7, "ELECTRABEL-DSM 9" },
    { 0x4BA2, "ELECTRABEL-DSM 5" },
    { 0x4BD7, "RadioText+ (RT+)" },
    { 0x4C59, "CITIBUS 2" },
    { 0x4D87, "Radio Commerce System (RCS)" },
    { 0x4D95, "ELECTRABEL-DSM 16" },
    { 0x4D9A, "ELECTRABEL-DSM 11" },
    { 0x5757, "Personal weather station" },
    { 0x6552, "Enhanced RadioText (eRT)" },
    { 0x7373, "Enhanced early warning system" },
    { 0xC350, "NRSC Song Title and Artist" },
    { 0xC3A1, "Personal Radio Service" },
    { 0xC3B0, "iTunes Tagging" },
    { 0xC3C3, "NAVTEQ Traffic Plus" },
    { 0xC4D4, "eEAS" },
    { 0xC549, "Smart Grid Broadcast Channel" },
    { 0xC563, "ID Logic" },
    { 0xC6A7, "Veil Enabled Interactive Device" },
    { 0xC737, "Utility Message Channel (UMC)" },
    { 0xCB73, "CITIBUS 1" },
    { 0xCB97, "ELECTRABEL-DSM 14" },
    { 0xCC21, "CITIBUS 3" },
    { 0xCD46, "RDS-TMC: ALERT-C" },
    { 0xCD47, "RDS-TMC: ALERT-C" },
    { 0xCD9E, "ELECTRABEL-DSM 8" },
    { 0xCE6B, "Encrypted TTI using ALERT-Plus" },
    { 0xE123, "APS Gateway" },
    { 0xE1C1, "Action code" },
    { 0xE319, "ELECTRABEL-DSM 12" },
    { 0xE411, "Beacon downlink" },
    { 0xE440, "ELECTRABEL-DSM 15" },
    { 0xE4A6, "ELECTRABEL-DSM 19" },
    { 0xE5D7, "ELECTRABEL-DSM 6" },
    { 0xE911, "EAS open protocol" }
  });

  std::string result("(Unknown)");
  if (oda_apps.find(aid) != oda_apps.end()) {
    result = oda_apps[aid];
  }

  return result;
}

}
<|endoftext|>


<commit_before>// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "apps/ui/native_app_window.h"
#include "chrome/browser/apps/app_browsertest_util.h"

using extensions::Extension;

namespace apps {

namespace {

typedef extensions::PlatformAppBrowserTest AppWindowBrowserTest;

// This test is disabled on Linux because of the unpredictable nature of native
// windows. We cannot assume that the window manager will insert any title bar
// at all, so the test may fail on certain window managers.
#if defined(TOOLKIT_GTK) || (defined(OS_LINUX) && !defined(OS_CHROMEOS))
#define MAYBE_FrameInsetsForDefaultFrame DISABLED_FrameInsetsForDefaultFrame
#else
#define MAYBE_FrameInsetsForDefaultFrame FrameInsetsForDefaultFrame
#endif

// Verifies that the NativeAppWindows implement GetFrameInsets() correctly.
// See crbug.com/346115
IN_PROC_BROWSER_TEST_F(AppWindowBrowserTest, MAYBE_FrameInsetsForDefaultFrame) {
  AppWindow* app_window = CreateTestAppWindow("{}");
  NativeAppWindow* native_window = app_window->GetBaseWindow();
  gfx::Insets insets = native_window->GetFrameInsets();

  // It is a reasonable assumption that the top padding must be greater than
  // the bottom padding due to the title bar.
  EXPECT_TRUE(insets.top() > insets.bottom());

  CloseAppWindow(app_window);
}

// This test is also disabled on Linux because frame: color is ignored on stable
// and beta channels (so it can fail the same as the previous test).
// TODO(benwells): Re-enable on Linux after frame: color is on stable.
#if defined(TOOLKIT_GTK) || (defined(OS_LINUX) && !defined(OS_CHROMEOS))
#define MAYBE_FrameInsetsForColoredFrame DISABLED_FrameInsetsForColoredFrame
#else
#define MAYBE_FrameInsetsForColoredFrame FrameInsetsForColoredFrame
#endif

// Verifies that the NativeAppWindows implement GetFrameInsets() correctly.
// See crbug.com/346115
IN_PROC_BROWSER_TEST_F(AppWindowBrowserTest, MAYBE_FrameInsetsForColoredFrame) {
  AppWindow* app_window =
      CreateTestAppWindow("{ \"frame\": { \"color\": \"#ffffff\" } }");
  NativeAppWindow* native_window = app_window->GetBaseWindow();
  gfx::Insets insets = native_window->GetFrameInsets();

  // It is a reasonable assumption that the top padding must be greater than
  // the bottom padding due to the title bar.
  EXPECT_TRUE(insets.top() > insets.bottom());

  CloseAppWindow(app_window);
}

// Verifies that the NativeAppWindows implement GetFrameInsets() correctly for
// frameless windows.
IN_PROC_BROWSER_TEST_F(AppWindowBrowserTest, FrameInsetsForNoFrame) {
  AppWindow* app_window = CreateTestAppWindow("{ \"frame\": \"none\" }");
  NativeAppWindow* native_window = app_window->GetBaseWindow();
  gfx::Insets insets = native_window->GetFrameInsets();

  // All insets must be zero.
  EXPECT_EQ(0, insets.top());
  EXPECT_EQ(0, insets.bottom());
  EXPECT_EQ(0, insets.left());
  EXPECT_EQ(0, insets.right());

  CloseAppWindow(app_window);
}

}  // namespace

}  // namespace apps
<commit_msg>Minor cleanup of app_window_browsertest.<commit_after>// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "apps/ui/native_app_window.h"
#include "chrome/browser/apps/app_browsertest_util.h"

using extensions::Extension;

namespace apps {

namespace {

typedef extensions::PlatformAppBrowserTest AppWindowBrowserTest;

// This test is disabled on Linux because of the unpredictable nature of native
// windows. We cannot assume that the window manager will insert any title bar
// at all, so the test may fail on certain window managers.
#if defined(TOOLKIT_GTK) || (defined(OS_LINUX) && !defined(OS_CHROMEOS))
#define MAYBE_FrameInsetsForDefaultFrame DISABLED_FrameInsetsForDefaultFrame
#else
#define MAYBE_FrameInsetsForDefaultFrame FrameInsetsForDefaultFrame
#endif

// Verifies that the NativeAppWindows implement GetFrameInsets() correctly.
// See http://crbug.com/346115
IN_PROC_BROWSER_TEST_F(AppWindowBrowserTest, MAYBE_FrameInsetsForDefaultFrame) {
  AppWindow* app_window = CreateTestAppWindow("{}");
  NativeAppWindow* native_window = app_window->GetBaseWindow();
  gfx::Insets insets = native_window->GetFrameInsets();

  // It is a reasonable assumption that the top padding must be greater than
  // the bottom padding due to the title bar.
  EXPECT_GT(insets.top(), insets.bottom());

  CloseAppWindow(app_window);
}

// This test is also disabled on Linux because frame: color is ignored on stable
// and beta channels (so it can fail the same as the previous test).
// TODO(benwells): Re-enable on Linux after frame: color is on stable.
#if defined(TOOLKIT_GTK) || (defined(OS_LINUX) && !defined(OS_CHROMEOS))
#define MAYBE_FrameInsetsForColoredFrame DISABLED_FrameInsetsForColoredFrame
#else
#define MAYBE_FrameInsetsForColoredFrame FrameInsetsForColoredFrame
#endif

// Verifies that the NativeAppWindows implement GetFrameInsets() correctly.
// See http://crbug.com/346115
IN_PROC_BROWSER_TEST_F(AppWindowBrowserTest, MAYBE_FrameInsetsForColoredFrame) {
  AppWindow* app_window =
      CreateTestAppWindow("{ \"frame\": { \"color\": \"#ffffff\" } }");
  NativeAppWindow* native_window = app_window->GetBaseWindow();
  gfx::Insets insets = native_window->GetFrameInsets();

  // It is a reasonable assumption that the top padding must be greater than
  // the bottom padding due to the title bar.
  EXPECT_GT(insets.top(), insets.bottom());

  CloseAppWindow(app_window);
}

// Verifies that the NativeAppWindows implement GetFrameInsets() correctly for
// frameless windows.
IN_PROC_BROWSER_TEST_F(AppWindowBrowserTest, FrameInsetsForNoFrame) {
  AppWindow* app_window = CreateTestAppWindow("{ \"frame\": \"none\" }");
  NativeAppWindow* native_window = app_window->GetBaseWindow();
  gfx::Insets insets = native_window->GetFrameInsets();

  // All insets must be zero.
  EXPECT_EQ(0, insets.top());
  EXPECT_EQ(0, insets.bottom());
  EXPECT_EQ(0, insets.left());
  EXPECT_EQ(0, insets.right());

  CloseAppWindow(app_window);
}

}  // namespace

}  // namespace apps
<|endoftext|>


<commit_before>#include <aerial_autonomy/estimators/tracking_vector_estimator.h>
#include <aerial_autonomy/log/log.h>
#include <glog/logging.h>

TrackingVectorEstimator::TrackingVectorEstimator(
    TrackingVectorEstimatorConfig config,
    std::chrono::duration<double> propagation_step)
    : config_(config), filter_(3, 3, 3, CV_64F), zero_tolerance_(1e-6),
      initial_state_initialized_(false) {
  // Assuming x = [Marker direction] and u = [velocity]
  // Transition matrix
  filter_.transitionMatrix = cv::Mat_<double>::eye(3, 3);
  filter_.controlMatrix =
      -propagation_step.count() * cv::Mat_<double>::eye(3, 3);
  // Measurement matrix
  filter_.measurementMatrix = cv::Mat_<double>::eye(3, 3);
  // Check stdeviation vectors
  checkStdVector(config_.marker_process_stdev());
  checkStdVector(config_.marker_meas_stdev());
  checkStdVector(config_.marker_initial_stdev());
  checkStdVector(config_.marker_dilation_stdev());
  // Noise matrices
  setCovarianceMatrix(filter_.processNoiseCov, config_.marker_process_stdev());
  setCovarianceMatrix(filter_.measurementNoiseCov, config_.marker_meas_stdev());
  // Save variables
  marker_dilation_stdev_ = tf::Vector3(config_.marker_dilation_stdev().x(),
                                       config_.marker_dilation_stdev().y(),
                                       config_.marker_dilation_stdev().z());
  marker_meas_stdev_ = tf::Vector3(config_.marker_meas_stdev().x(),
                                   config_.marker_meas_stdev().y(),
                                   config_.marker_meas_stdev().z());
  // Set initial state
  initializeState(tf::Vector3(0, 0, 0));
  DATA_HEADER("tracking_vector_estimator") << "Measured_Marker_x"
                                           << "Measured_Marker_y"
                                           << "Measured_Marker_z"
                                           << "Marker_x"
                                           << "Marker_y"
                                           << "Marker_z"
                                           << "Meas_noise_x"
                                           << "Meas_noise_y"
                                           << "Meas_noise_z"
                                           << "Noise_x"
                                           << "Noise_y"
                                           << "Noise_z" << DataStream::endl;
}

void TrackingVectorEstimator::initializeState(tf::Vector3 marker_direction) {
  VLOG(1) << "Initializing KF with Marker dirxn: " << marker_direction.x()
          << marker_direction.y() << marker_direction.z();
  filter_.statePre = (cv::Mat_<double>(3, 1) << marker_direction.x(),
                      marker_direction.y(), marker_direction.z());
  setCovarianceMatrix(filter_.errorCovPost, config_.marker_initial_stdev());
  filter_.statePre.copyTo(filter_.statePost);
  initial_state_initialized_ = true;
}

void TrackingVectorEstimator::predict(tf::Vector3 velocity) {
  cv::Mat_<double> control =
      (cv::Mat_<double>(3, 1) << velocity.x(), velocity.y(), velocity.z());
  filter_.predict(control);
}

void TrackingVectorEstimator::setMeasurementCovariance(
    cv::Mat &covariance_mat,
    std::chrono::time_point<std::chrono::high_resolution_clock>
        marker_time_stamp) {
  double dt = std::chrono::duration<double>(
                  std::chrono::high_resolution_clock::now() - marker_time_stamp)
                  .count();
  if (dt < 0) {
    LOG(WARNING) << "dt negative: " << dt;
    dt = 0;
  }
  tf::Vector3 current_meas_stdev =
      marker_meas_stdev_ + dt * marker_dilation_stdev_;
  setCovarianceMatrix(covariance_mat, current_meas_stdev);
}

void TrackingVectorEstimator::correct(
    tf::Vector3 marker_direction,
    std::chrono::time_point<std::chrono::high_resolution_clock>
        marker_time_stamp) {
  if (!initial_state_initialized_) {
    initializeState(marker_direction);
    return;
  }
  cv::Mat_<double> measurement =
      (cv::Mat_<double>(3, 1) << marker_direction.x(), marker_direction.y(),
       marker_direction.z());
  setMeasurementCovariance(filter_.measurementNoiseCov, marker_time_stamp);
  filter_.correct(measurement);
  // Log data
  tf::Vector3 marker_noise = getMarkerNoise();
  auto state = filter_.statePost;
  auto &data_stream = Log::instance()["tracking_vector_estimator"];
  data_stream << DataStream::startl;
  for (int i = 0; i < 3; ++i) {
    data_stream << measurement.at<double>(i);
  }
  for (int i = 0; i < 3; ++i) {
    data_stream << state.at<double>(i);
  }
  for (int i = 0; i < 3; ++i) {
    data_stream << sqrt(filter_.measurementNoiseCov.at<double>(i, i));
  }
  for (int i = 0; i < 3; ++i) {
    data_stream << marker_noise[i];
  }
  data_stream << DataStream::endl;
}
<commit_msg>Print warning if time difference is too high in estimator<commit_after>#include <aerial_autonomy/estimators/tracking_vector_estimator.h>
#include <aerial_autonomy/log/log.h>
#include <glog/logging.h>

TrackingVectorEstimator::TrackingVectorEstimator(
    TrackingVectorEstimatorConfig config,
    std::chrono::duration<double> propagation_step)
    : config_(config), filter_(3, 3, 3, CV_64F), zero_tolerance_(1e-6),
      initial_state_initialized_(false) {
  // Assuming x = [Marker direction] and u = [velocity]
  // Transition matrix
  filter_.transitionMatrix = cv::Mat_<double>::eye(3, 3);
  filter_.controlMatrix =
      -propagation_step.count() * cv::Mat_<double>::eye(3, 3);
  // Measurement matrix
  filter_.measurementMatrix = cv::Mat_<double>::eye(3, 3);
  // Check stdeviation vectors
  checkStdVector(config_.marker_process_stdev());
  checkStdVector(config_.marker_meas_stdev());
  checkStdVector(config_.marker_initial_stdev());
  checkStdVector(config_.marker_dilation_stdev());
  // Noise matrices
  setCovarianceMatrix(filter_.processNoiseCov, config_.marker_process_stdev());
  setCovarianceMatrix(filter_.measurementNoiseCov, config_.marker_meas_stdev());
  // Save variables
  marker_dilation_stdev_ = tf::Vector3(config_.marker_dilation_stdev().x(),
                                       config_.marker_dilation_stdev().y(),
                                       config_.marker_dilation_stdev().z());
  marker_meas_stdev_ = tf::Vector3(config_.marker_meas_stdev().x(),
                                   config_.marker_meas_stdev().y(),
                                   config_.marker_meas_stdev().z());
  // Set initial state
  initializeState(tf::Vector3(0, 0, 0));
  DATA_HEADER("tracking_vector_estimator") << "Measured_Marker_x"
                                           << "Measured_Marker_y"
                                           << "Measured_Marker_z"
                                           << "Marker_x"
                                           << "Marker_y"
                                           << "Marker_z"
                                           << "Meas_noise_x"
                                           << "Meas_noise_y"
                                           << "Meas_noise_z"
                                           << "Noise_x"
                                           << "Noise_y"
                                           << "Noise_z" << DataStream::endl;
}

void TrackingVectorEstimator::initializeState(tf::Vector3 marker_direction) {
  VLOG(1) << "Initializing KF with Marker dirxn: " << marker_direction.x()
          << marker_direction.y() << marker_direction.z();
  filter_.statePre = (cv::Mat_<double>(3, 1) << marker_direction.x(),
                      marker_direction.y(), marker_direction.z());
  setCovarianceMatrix(filter_.errorCovPost, config_.marker_initial_stdev());
  filter_.statePre.copyTo(filter_.statePost);
  initial_state_initialized_ = true;
}

void TrackingVectorEstimator::predict(tf::Vector3 velocity) {
  cv::Mat_<double> control =
      (cv::Mat_<double>(3, 1) << velocity.x(), velocity.y(), velocity.z());
  filter_.predict(control);
}

void TrackingVectorEstimator::setMeasurementCovariance(
    cv::Mat &covariance_mat,
    std::chrono::time_point<std::chrono::high_resolution_clock>
        marker_time_stamp) {
  double dt = std::chrono::duration<double>(
                  std::chrono::high_resolution_clock::now() - marker_time_stamp)
                  .count();
  if (dt < 0) {
    LOG(WARNING) << "dt negative: " << dt;
    dt = 0;
  } else if (dt > 1.0) {
    LOG(WARNING) << "dt too high: " << dt;
    dt = 1.0;
  }
  tf::Vector3 current_meas_stdev =
      marker_meas_stdev_ + dt * marker_dilation_stdev_;
  setCovarianceMatrix(covariance_mat, current_meas_stdev);
}

void TrackingVectorEstimator::correct(
    tf::Vector3 marker_direction,
    std::chrono::time_point<std::chrono::high_resolution_clock>
        marker_time_stamp) {
  if (!initial_state_initialized_) {
    initializeState(marker_direction);
    return;
  }
  cv::Mat_<double> measurement =
      (cv::Mat_<double>(3, 1) << marker_direction.x(), marker_direction.y(),
       marker_direction.z());
  setMeasurementCovariance(filter_.measurementNoiseCov, marker_time_stamp);
  filter_.correct(measurement);
  // Log data
  tf::Vector3 marker_noise = getMarkerNoise();
  auto state = filter_.statePost;
  auto &data_stream = Log::instance()["tracking_vector_estimator"];
  data_stream << DataStream::startl;
  for (int i = 0; i < 3; ++i) {
    data_stream << measurement.at<double>(i);
  }
  for (int i = 0; i < 3; ++i) {
    data_stream << state.at<double>(i);
  }
  for (int i = 0; i < 3; ++i) {
    data_stream << sqrt(filter_.measurementNoiseCov.at<double>(i, i));
  }
  for (int i = 0; i < 3; ++i) {
    data_stream << marker_noise[i];
  }
  data_stream << DataStream::endl;
}
<|endoftext|>


<commit_before>// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "gpu_surface_gl.h"

#if OS_MACOSX || OS_IOS
#include <OpenGLES/ES2/gl.h>
#include <OpenGLES/ES2/glext.h>
#else
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#endif

#include "flutter/glue/trace_event.h"
#include "lib/fxl/arraysize.h"
#include "lib/fxl/logging.h"
#include "third_party/skia/include/core/SkColorFilter.h"
#include "third_party/skia/include/core/SkSurface.h"
#include "third_party/skia/include/gpu/GrBackendSurface.h"
#include "third_party/skia/include/gpu/GrContextOptions.h"
#include "third_party/skia/include/gpu/gl/GrGLInterface.h"

namespace shell {

// Default maximum number of budgeted resources in the cache.
static const int kGrCacheMaxCount = 8192;

// Default maximum number of bytes of GPU memory of budgeted resources in the
// cache.
static const size_t kGrCacheMaxByteSize = 512 * (1 << 20);

GPUSurfaceGL::GPUSurfaceGL(GPUSurfaceGLDelegate* delegate)
    : delegate_(delegate), weak_factory_(this) {
  if (!delegate_->GLContextMakeCurrent()) {
    FXL_LOG(ERROR)
        << "Could not make the context current to setup the gr context.";
    return;
  }

  GrContextOptions options;
  options.fAvoidStencilBuffers = true;

  auto context = GrContext::MakeGL(GrGLMakeNativeInterface(), options);

  if (context == nullptr) {
    FXL_LOG(ERROR) << "Failed to setup Skia Gr context.";
    return;
  }

  context_ = std::move(context);

  context_->setResourceCacheLimits(kGrCacheMaxCount, kGrCacheMaxByteSize);

  delegate_->GLContextClearCurrent();

  valid_ = true;
}

GPUSurfaceGL::~GPUSurfaceGL() {
  if (!valid_) {
    return;
  }

  if (!delegate_->GLContextMakeCurrent()) {
    FXL_LOG(ERROR) << "Could not make the context current to destroy the "
                      "GrContext resources.";
    return;
  }

  onscreen_surface_ = nullptr;
  context_->releaseResourcesAndAbandonContext();
  context_ = nullptr;

  delegate_->GLContextClearCurrent();
}

bool GPUSurfaceGL::IsValid() {
  return valid_;
}

static SkColorType FirstSupportedColorType(GrContext* context, GLenum* format) {
#define RETURN_IF_RENDERABLE(x, y)                 \
  if (context->colorTypeSupportedAsSurface((x))) { \
    *format = (y);                                 \
    return (x);                                    \
  }
  RETURN_IF_RENDERABLE(kRGBA_8888_SkColorType, GL_RGBA8_OES);
  RETURN_IF_RENDERABLE(kARGB_4444_SkColorType, GL_RGBA4);
  RETURN_IF_RENDERABLE(kRGB_565_SkColorType, GL_RGB565);
  return kUnknown_SkColorType;
}

static sk_sp<SkSurface> WrapOnscreenSurface(GrContext* context,
                                            const SkISize& size,
                                            intptr_t fbo) {

  GLenum format;
  const SkColorType color_type = FirstSupportedColorType(context, &format);

  const GrGLFramebufferInfo framebuffer_info = {
      .fFBOID = static_cast<GrGLuint>(fbo),
      .fFormat = format,
  };

  GrBackendRenderTarget render_target(size.fWidth,      // width
                                      size.fHeight,     // height
                                      0,                // sample count
                                      0,                // stencil bits (TODO)
                                      framebuffer_info  // framebuffer info
  );

  sk_sp<SkColorSpace> colorspace = nullptr;

  SkSurfaceProps surface_props(
      SkSurfaceProps::InitType::kLegacyFontHost_InitType);

  return SkSurface::MakeFromBackendRenderTarget(
      context,                                       // gr context
      render_target,                                 // render target
      GrSurfaceOrigin::kBottomLeft_GrSurfaceOrigin,  // origin
      color_type,                                    // color type
      colorspace,                                    // colorspace
      &surface_props                                 // surface properties
  );
}

static sk_sp<SkSurface> CreateOffscreenSurface(GrContext* context,
                                               const SkISize& size) {
  const SkImageInfo image_info =
      SkImageInfo::MakeN32(size.fWidth, size.fHeight, kOpaque_SkAlphaType);

  const SkSurfaceProps surface_props(
      SkSurfaceProps::InitType::kLegacyFontHost_InitType);

  return SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, image_info, 0,
                                     kBottomLeft_GrSurfaceOrigin,
                                     &surface_props);
}

bool GPUSurfaceGL::CreateOrUpdateSurfaces(const SkISize& size) {
  if (onscreen_surface_ != nullptr &&
      size == SkISize::Make(onscreen_surface_->width(),
                            onscreen_surface_->height())) {
    // Surface size appears unchanged. So bail.
    return true;
  }

  // We need to do some updates.
  TRACE_EVENT0("flutter", "UpdateSurfacesSize");

  // Either way, we need to get rid of previous surface.
  onscreen_surface_ = nullptr;
  offscreen_surface_ = nullptr;

  if (size.isEmpty()) {
    FXL_LOG(ERROR) << "Cannot create surfaces of empty size.";
    return false;
  }

  sk_sp<SkSurface> onscreen_surface, offscreen_surface;

  onscreen_surface =
      WrapOnscreenSurface(context_.get(), size, delegate_->GLContextFBO());

  if (onscreen_surface == nullptr) {
    // If the onscreen surface could not be wrapped. There is absolutely no
    // point in moving forward.
    FXL_LOG(ERROR) << "Could not wrap onscreen surface.";
    return false;
  }

  if (delegate_->UseOffscreenSurface()) {
    offscreen_surface = CreateOffscreenSurface(context_.get(), size);
    if (offscreen_surface == nullptr) {
      FXL_LOG(ERROR) << "Could not create offscreen surface.";
      return false;
    }
  }

  onscreen_surface_ = std::move(onscreen_surface);
  offscreen_surface_ = std::move(offscreen_surface);

  return true;
}

std::unique_ptr<SurfaceFrame> GPUSurfaceGL::AcquireFrame(const SkISize& size) {
  if (delegate_ == nullptr) {
    return nullptr;
  }

  if (!delegate_->GLContextMakeCurrent()) {
    FXL_LOG(ERROR)
        << "Could not make the context current to acquire the frame.";
    return nullptr;
  }

  sk_sp<SkSurface> surface = AcquireRenderSurface(size);

  if (surface == nullptr) {
    return nullptr;
  }

  auto weak_this = weak_factory_.GetWeakPtr();

  SurfaceFrame::SubmitCallback submit_callback =
      [weak_this](const SurfaceFrame& surface_frame, SkCanvas* canvas) {
        return weak_this ? weak_this->PresentSurface(canvas) : false;
      };

  return std::make_unique<SurfaceFrame>(surface, submit_callback);
}

bool GPUSurfaceGL::PresentSurface(SkCanvas* canvas) {
  if (delegate_ == nullptr || canvas == nullptr || context_ == nullptr) {
    return false;
  }

  if (offscreen_surface_ != nullptr) {
    TRACE_EVENT0("flutter", "CopyTextureOnscreen");
    SkPaint paint;
    onscreen_surface_->getCanvas()->drawImage(
        offscreen_surface_->makeImageSnapshot(), 0, 0, &paint);
  }

  {
    TRACE_EVENT0("flutter", "SkCanvas::Flush");
    onscreen_surface_->getCanvas()->flush();
  }

  delegate_->GLContextPresent();

  return true;
}

sk_sp<SkSurface> GPUSurfaceGL::AcquireRenderSurface(const SkISize& size) {
  if (!CreateOrUpdateSurfaces(size)) {
    return nullptr;
  }

  return offscreen_surface_ != nullptr ? offscreen_surface_ : onscreen_surface_;
}

GrContext* GPUSurfaceGL::GetContext() {
  return context_.get();
}

}  // namespace shell
<commit_msg>Fix GPUSurfaceGL includes on macOS (#4844)<commit_after>// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "gpu_surface_gl.h"

#if OS_IOS
#include <OpenGLES/ES2/gl.h>
#include <OpenGLES/ES2/glext.h>
#elif OS_MACOSX
#include <OpenGL/gl3.h>
#else
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#endif

#include "flutter/glue/trace_event.h"
#include "lib/fxl/arraysize.h"
#include "lib/fxl/logging.h"
#include "third_party/skia/include/core/SkColorFilter.h"
#include "third_party/skia/include/core/SkSurface.h"
#include "third_party/skia/include/gpu/GrBackendSurface.h"
#include "third_party/skia/include/gpu/GrContextOptions.h"
#include "third_party/skia/include/gpu/gl/GrGLInterface.h"

namespace shell {

// Default maximum number of budgeted resources in the cache.
static const int kGrCacheMaxCount = 8192;

// Default maximum number of bytes of GPU memory of budgeted resources in the
// cache.
static const size_t kGrCacheMaxByteSize = 512 * (1 << 20);

GPUSurfaceGL::GPUSurfaceGL(GPUSurfaceGLDelegate* delegate)
    : delegate_(delegate), weak_factory_(this) {
  if (!delegate_->GLContextMakeCurrent()) {
    FXL_LOG(ERROR)
        << "Could not make the context current to setup the gr context.";
    return;
  }

  GrContextOptions options;
  options.fAvoidStencilBuffers = true;

  auto context = GrContext::MakeGL(GrGLMakeNativeInterface(), options);

  if (context == nullptr) {
    FXL_LOG(ERROR) << "Failed to setup Skia Gr context.";
    return;
  }

  context_ = std::move(context);

  context_->setResourceCacheLimits(kGrCacheMaxCount, kGrCacheMaxByteSize);

  delegate_->GLContextClearCurrent();

  valid_ = true;
}

GPUSurfaceGL::~GPUSurfaceGL() {
  if (!valid_) {
    return;
  }

  if (!delegate_->GLContextMakeCurrent()) {
    FXL_LOG(ERROR) << "Could not make the context current to destroy the "
                      "GrContext resources.";
    return;
  }

  onscreen_surface_ = nullptr;
  context_->releaseResourcesAndAbandonContext();
  context_ = nullptr;

  delegate_->GLContextClearCurrent();
}

bool GPUSurfaceGL::IsValid() {
  return valid_;
}

static SkColorType FirstSupportedColorType(GrContext* context, GLenum* format) {
#define RETURN_IF_RENDERABLE(x, y)                 \
  if (context->colorTypeSupportedAsSurface((x))) { \
    *format = (y);                                 \
    return (x);                                    \
  }
#if OS_MACOSX
  RETURN_IF_RENDERABLE(kRGBA_8888_SkColorType, GL_RGBA8);
#else
  RETURN_IF_RENDERABLE(kRGBA_8888_SkColorType, GL_RGBA8_OES);
#endif
  RETURN_IF_RENDERABLE(kARGB_4444_SkColorType, GL_RGBA4);
  RETURN_IF_RENDERABLE(kRGB_565_SkColorType, GL_RGB565);
  return kUnknown_SkColorType;
}

static sk_sp<SkSurface> WrapOnscreenSurface(GrContext* context,
                                            const SkISize& size,
                                            intptr_t fbo) {

  GLenum format;
  const SkColorType color_type = FirstSupportedColorType(context, &format);

  const GrGLFramebufferInfo framebuffer_info = {
      .fFBOID = static_cast<GrGLuint>(fbo),
      .fFormat = format,
  };

  GrBackendRenderTarget render_target(size.fWidth,      // width
                                      size.fHeight,     // height
                                      0,                // sample count
                                      0,                // stencil bits (TODO)
                                      framebuffer_info  // framebuffer info
  );

  sk_sp<SkColorSpace> colorspace = nullptr;

  SkSurfaceProps surface_props(
      SkSurfaceProps::InitType::kLegacyFontHost_InitType);

  return SkSurface::MakeFromBackendRenderTarget(
      context,                                       // gr context
      render_target,                                 // render target
      GrSurfaceOrigin::kBottomLeft_GrSurfaceOrigin,  // origin
      color_type,                                    // color type
      colorspace,                                    // colorspace
      &surface_props                                 // surface properties
  );
}

static sk_sp<SkSurface> CreateOffscreenSurface(GrContext* context,
                                               const SkISize& size) {
  const SkImageInfo image_info =
      SkImageInfo::MakeN32(size.fWidth, size.fHeight, kOpaque_SkAlphaType);

  const SkSurfaceProps surface_props(
      SkSurfaceProps::InitType::kLegacyFontHost_InitType);

  return SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, image_info, 0,
                                     kBottomLeft_GrSurfaceOrigin,
                                     &surface_props);
}

bool GPUSurfaceGL::CreateOrUpdateSurfaces(const SkISize& size) {
  if (onscreen_surface_ != nullptr &&
      size == SkISize::Make(onscreen_surface_->width(),
                            onscreen_surface_->height())) {
    // Surface size appears unchanged. So bail.
    return true;
  }

  // We need to do some updates.
  TRACE_EVENT0("flutter", "UpdateSurfacesSize");

  // Either way, we need to get rid of previous surface.
  onscreen_surface_ = nullptr;
  offscreen_surface_ = nullptr;

  if (size.isEmpty()) {
    FXL_LOG(ERROR) << "Cannot create surfaces of empty size.";
    return false;
  }

  sk_sp<SkSurface> onscreen_surface, offscreen_surface;

  onscreen_surface =
      WrapOnscreenSurface(context_.get(), size, delegate_->GLContextFBO());

  if (onscreen_surface == nullptr) {
    // If the onscreen surface could not be wrapped. There is absolutely no
    // point in moving forward.
    FXL_LOG(ERROR) << "Could not wrap onscreen surface.";
    return false;
  }

  if (delegate_->UseOffscreenSurface()) {
    offscreen_surface = CreateOffscreenSurface(context_.get(), size);
    if (offscreen_surface == nullptr) {
      FXL_LOG(ERROR) << "Could not create offscreen surface.";
      return false;
    }
  }

  onscreen_surface_ = std::move(onscreen_surface);
  offscreen_surface_ = std::move(offscreen_surface);

  return true;
}

std::unique_ptr<SurfaceFrame> GPUSurfaceGL::AcquireFrame(const SkISize& size) {
  if (delegate_ == nullptr) {
    return nullptr;
  }

  if (!delegate_->GLContextMakeCurrent()) {
    FXL_LOG(ERROR)
        << "Could not make the context current to acquire the frame.";
    return nullptr;
  }

  sk_sp<SkSurface> surface = AcquireRenderSurface(size);

  if (surface == nullptr) {
    return nullptr;
  }

  auto weak_this = weak_factory_.GetWeakPtr();

  SurfaceFrame::SubmitCallback submit_callback =
      [weak_this](const SurfaceFrame& surface_frame, SkCanvas* canvas) {
        return weak_this ? weak_this->PresentSurface(canvas) : false;
      };

  return std::make_unique<SurfaceFrame>(surface, submit_callback);
}

bool GPUSurfaceGL::PresentSurface(SkCanvas* canvas) {
  if (delegate_ == nullptr || canvas == nullptr || context_ == nullptr) {
    return false;
  }

  if (offscreen_surface_ != nullptr) {
    TRACE_EVENT0("flutter", "CopyTextureOnscreen");
    SkPaint paint;
    onscreen_surface_->getCanvas()->drawImage(
        offscreen_surface_->makeImageSnapshot(), 0, 0, &paint);
  }

  {
    TRACE_EVENT0("flutter", "SkCanvas::Flush");
    onscreen_surface_->getCanvas()->flush();
  }

  delegate_->GLContextPresent();

  return true;
}

sk_sp<SkSurface> GPUSurfaceGL::AcquireRenderSurface(const SkISize& size) {
  if (!CreateOrUpdateSurfaces(size)) {
    return nullptr;
  }

  return offscreen_surface_ != nullptr ? offscreen_surface_ : onscreen_surface_;
}

GrContext* GPUSurfaceGL::GetContext() {
  return context_.get();
}

}  // namespace shell
<|endoftext|>