<commit_before>/***********************************************************************
    created:    Sat Mar 12 2005
    author:     Paul D Turner
*************************************************************************/
/***************************************************************************
 *   Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
 *
 *   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 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 "CEGUI/XMLParserModules/Xerces/XMLParser.h"
#include "CEGUI/String.h"
#include "CEGUI/Exceptions.h"
#include "CEGUI/Logger.h"
#include "CEGUI/ResourceProvider.h"
#include "CEGUI/System.h"
#include "CEGUI/XMLHandler.h"
#include "CEGUI/XMLAttributes.h"
#include "CEGUI/PropertyHelper.h"

#include <xercesc/validators/schema/SchemaValidator.hpp>

#include <iostream> // Debug
// Start of CEGUI namespace section
namespace CEGUI
{
    // Static data definition for default schema resource group name
    String XercesParser::d_defaultSchemaResourceGroup("");
    // static data definition of the SchemaDefaultResourceGroup property.
    XercesParserProperties::SchemaDefaultResourceGroup
        XercesParser::s_schemaDefaultResourceGroupProperty;

    ////////////////////////////////////////////////////////////////////////////////
    //
    // XercesParser methods
    //
    ////////////////////////////////////////////////////////////////////////////////

    XercesParser::XercesParser(void)
    {
        // set ID string
        d_identifierString = "CEGUI::XercesParser - Official Xerces-C++ based parser module for CEGUI";
        // add property
        addProperty(&s_schemaDefaultResourceGroupProperty);

        String propertyOrigin("XercesParser");
        CEGUI_DEFINE_PROPERTY(XercesParser, bool, "isXmlValidationEnabled",
                              "Property to get/set if XML validation is enabled or disabled globally. "
                              "If it's disabled it will not allow any xml validation. "
                              "If it's enabled the validation behaviour is dependending on what is "
                              "passed to parseXML.",
                              &XercesParser::setXmlValidationEnabled,
                              &XercesParser::isXmlValidationEnabled,
                              true);
    }

    XercesParser::~XercesParser(void)
    {}

    void XercesParser::parseXML(XMLHandler& handler, const RawDataContainer& source, const String& schemaName, bool xmlValidationEnabled)
    {
        XERCES_CPP_NAMESPACE_USE;

        XercesHandler xercesHandler(handler);

        // create parser
        SAX2XMLReader* reader = createReader(xercesHandler);

        try
        {
            bool forceXmlValidation;

            // ignore local settings if validation is disabled globally
            if (!isXmlValidationEnabled())
                forceXmlValidation = false;
            else
                forceXmlValidation = xmlValidationEnabled;

            // set up schema
            if (forceXmlValidation)
                initialiseSchema(reader, schemaName);
            // do parse
            doParse(reader, source);
        }
        catch (const XMLException& exc)
        {
            if (exc.getCode() != XMLExcepts::NoError)
            {
                delete reader;

                char* excmsg = XMLString::transcode(exc.getMessage());
                String message("An error occurred at line nr. " + PropertyHelper<std::uint32_t>::toString((std::uint32_t)exc.getSrcLine()) + " while parsing XML.  Additional information: ");
                message += excmsg;
                XMLString::release(&excmsg);

                throw FileIOException(message);
            }

        }
        catch (const SAXParseException& exc)
        {
            delete reader;

            char* excmsg = XMLString::transcode(exc.getMessage());
            String message("An error occurred at line nr. " + PropertyHelper<std::uint32_t>::toString((std::uint32_t)exc.getLineNumber()) + " while parsing XML.  Additional information: ");
            message += excmsg;
            XMLString::release(&excmsg);

            throw FileIOException(message);
        }
        catch (...)
        {
            delete reader;

            Logger::getSingleton().logEvent("An unexpected error occurred while parsing XML", Errors);
            throw;
        }

        // cleanup
        delete reader;
    }

    bool XercesParser::initialiseImpl(void)
    {
        XERCES_CPP_NAMESPACE_USE;

        // initialise Xerces-C XML system
        try
        {
            XMLPlatformUtils::Initialize();
        }
        catch (XMLException& exc)
        {
            // prepare a message about the failure
            char* excmsg = XMLString::transcode(exc.getMessage());
            String message("An exception occurred while initialising the Xerces-C XML system.  Additional information: ");
            message += excmsg;
            XMLString::release(&excmsg);

            // throw a C string (because it won't try and use logger, which may not be available)
            throw message.c_str();
        }

        return true;
    }

    void XercesParser::cleanupImpl(void)
    {
        // cleanup XML stuff
        XERCES_CPP_NAMESPACE_USE;
        XMLPlatformUtils::Terminate();
    }

    void XercesParser::populateAttributesBlock(const XERCES_CPP_NAMESPACE::Attributes& src, XMLAttributes& dest)
    {
        XERCES_CPP_NAMESPACE_USE;
        String attributeName;
        String attributeValue;

        for (unsigned int i = 0; i < src.getLength(); ++i)
        {
            // TODO dalfy: Optimize this using temporary value.
            attributeName = transcodeXmlCharToString(src.getLocalName(i), XMLString::stringLen(src.getLocalName(i)));
            attributeValue = transcodeXmlCharToString(src.getValue(i), XMLString::stringLen(src.getValue(i)));
            dest.add(attributeName, attributeValue);
        }
    }

    String XercesParser::transcodeXmlCharToString(const XMLCh* const xmlch_str, unsigned int inputLength)
    {
        XERCES_CPP_NAMESPACE_USE;

        XMLTransService::Codes  res;
        XMLTranscoder* transcoder = XMLPlatformUtils::fgTransService->makeNewTranscoderFor(XMLRecognizer::UTF_8, res, 4096, XMLPlatformUtils::fgMemoryManager );

        if (res == XMLTransService::Ok)
        {
            String out;
#if _XERCES_VERSION >= 30000
            XMLByte outBuff[128];
            XMLSize_t outputLength;
            XMLSize_t eaten = 0;
            XMLSize_t offset = 0;
#else /* _XERCES_VERSION >= 30000 */
            char outBuff[128];
            unsigned int outputLength;
            unsigned int eaten = 0;
            unsigned int offset = 0;
#endif /* _XERCES_VERSION >= 30000 */
//            unsigned int inputLength = XMLString::stringLen(xmlch_str); // dalfy caracters node need to transcode but give the size

            while (inputLength)
            {
                outputLength = transcoder->transcodeTo(xmlch_str + offset, inputLength, outBuff, 128, eaten, XMLTranscoder::UnRep_RepChar);
                out.append(outBuff, outputLength);
                offset += eaten;
                inputLength -= eaten;
            }

            delete transcoder;

            return out;
        }
        else
        {
            throw GenericException("Internal Error: Could not create UTF-8 string transcoder.");
        }

    }

    void XercesParser::initialiseSchema(XERCES_CPP_NAMESPACE::SAX2XMLReader* reader, const String& schemaName)
    {
        // only load the schema if it's name is passed
        if (!schemaName.empty())
        {
            XERCES_CPP_NAMESPACE_USE;

            // enable schema use and set validation options
            reader->setFeature(XMLUni::fgXercesSchema, true);
            reader->setFeature(XMLUni::fgSAX2CoreValidation, true);
            reader->setFeature(XMLUni::fgXercesValidationErrorAsFatal, true);

            // load in the raw schema data
            RawDataContainer rawSchemaData;
            // load the schema from the resource group
            Logger::getSingleton().logEvent("XercesParser::initialiseSchema - Attempting to load schema from file '" + schemaName + "'.");
            System::getSingleton().getResourceProvider()->loadRawDataContainer(schemaName, rawSchemaData, d_defaultSchemaResourceGroup);

            // wrap schema data in a xerces MemBufInputSource object
            MemBufInputSource schemaData(
                rawSchemaData.getDataPtr(),
                static_cast<const unsigned int>(rawSchemaData.getSize()),
#if CEGUI_STRING_CLASS == CEGUI_STRING_CLASS_STD
                schemaName.c_str(),
#elif CEGUI_STRING_CLASS == CEGUI_STRING_CLASS_UNICODE
                schemaName.c_str().toUtf8String(),
#endif
                false);
            reader->loadGrammar(schemaData, Grammar::SchemaGrammarType, true);
            // enable grammar reuse
            reader->setFeature(XMLUni::fgXercesUseCachedGrammarInParse, true);

            // set schema for usage
#if CEGUI_STRING_CLASS == CEGUI_STRING_CLASS_STD
            XMLCh* pval = XMLString::transcode(schemaName.c_str());
#elif CEGUI_STRING_CLASS == CEGUI_STRING_CLASS_UNICODE
            XMLCh* pval = XMLString::transcode(schemaName.c_str()->toUtf8String());
#endif
            reader->setProperty(XMLUni::fgXercesSchemaExternalNoNameSpaceSchemaLocation, pval);
            XMLString::release(&pval);
            Logger::getSingleton().logEvent("XercesParser::initialiseSchema - XML schema file '" + schemaName + "' has been initialised.");

            // use resource provider to release loaded schema data (if it supports this)
            System::getSingleton().getResourceProvider()->unloadRawDataContainer(rawSchemaData);
        }
        else
        {
            // otherwise ignore the missing schema and proceed
            Logger::getSingleton().logEvent("XercesParser::initialiseSchema - No schema specified. Proceeding.");
        }
    }

    XERCES_CPP_NAMESPACE::SAX2XMLReader* XercesParser::createReader(XERCES_CPP_NAMESPACE::DefaultHandler& handler)
    {
        XERCES_CPP_NAMESPACE_USE;

        SAX2XMLReader* reader = XMLReaderFactory::createXMLReader();

        // set basic settings we want from parser
        reader->setFeature(XMLUni::fgSAX2CoreNameSpaces, true);

        // set handlers
        reader->setContentHandler(&handler);
        reader->setErrorHandler(&handler);

        return reader;
    }

    void XercesParser::doParse(XERCES_CPP_NAMESPACE::SAX2XMLReader* parser, const RawDataContainer& source)
    {
        XERCES_CPP_NAMESPACE_USE;

        MemBufInputSource  fileData(
            source.getDataPtr(),
            static_cast<const unsigned int>(source.getSize()),
            "Unknown",
            false);

         parser->parse(fileData);
    }

    ////////////////////////////////////////////////////////////////////////////////
    //
    // XercesHandler methods
    //
    ////////////////////////////////////////////////////////////////////////////////

    XercesHandler::XercesHandler(XMLHandler& handler) :
            d_handler(handler)
    {}

    XercesHandler::~XercesHandler(void)
    {}

    void XercesHandler::startElement(const XMLCh* const /*uri*/, const XMLCh* const localname, const XMLCh* const /*qname*/, const XERCES_CPP_NAMESPACE::Attributes& attrs)
    {
        XERCES_CPP_NAMESPACE_USE;
        XMLAttributes cegui_attributes;
        XercesParser::populateAttributesBlock(attrs, cegui_attributes);
        String element(XercesParser::transcodeXmlCharToString(localname, XMLString::stringLen(localname)));
        d_handler.elementStart(element, cegui_attributes);
    }

    void XercesHandler::endElement(const XMLCh* const /*uri*/, const XMLCh* const localname, const XMLCh* const /*qname*/)
    {
        XERCES_CPP_NAMESPACE_USE;
        String element(XercesParser::transcodeXmlCharToString(localname,XMLString::stringLen(localname)));
        d_handler.elementEnd(element);
    }

#if _XERCES_VERSION >= 30000
    void XercesHandler::characters(const XMLCh* const chars, const XMLSize_t length)
#else /* _XERCES_VERSION >= 30000 */
    void XercesHandler::characters (const XMLCh *const chars, const unsigned int length)
#endif /* _XERCES_VERSION >= 30000 */
    {
        d_handler.text(XercesParser::transcodeXmlCharToString(chars, length));
    }

    void XercesHandler::warning (const XERCES_CPP_NAMESPACE::SAXParseException &exc)
    {
        XERCES_CPP_NAMESPACE_USE;

        // prepare a message about the warning
        char* excmsg = XMLString::transcode(exc.getMessage());
        String message("Xerces warning: ");
        message += excmsg;
        XMLString::release(&excmsg);
        Logger::getSingleton().logEvent(message);
    }

    void XercesHandler::error (const XERCES_CPP_NAMESPACE::SAXParseException &exc)
    {
        throw exc;
    }

    void XercesHandler::fatalError (const XERCES_CPP_NAMESPACE::SAXParseException &exc)
    {
        throw exc;
    }

} // End of  CEGUI namespace section
<commit_msg>FIX: Really fixing the Xerces parser this time<commit_after>/***********************************************************************
    created:    Sat Mar 12 2005
    author:     Paul D Turner
*************************************************************************/
/***************************************************************************
 *   Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
 *
 *   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 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 "CEGUI/XMLParserModules/Xerces/XMLParser.h"
#include "CEGUI/String.h"
#include "CEGUI/Exceptions.h"
#include "CEGUI/Logger.h"
#include "CEGUI/ResourceProvider.h"
#include "CEGUI/System.h"
#include "CEGUI/XMLHandler.h"
#include "CEGUI/XMLAttributes.h"
#include "CEGUI/PropertyHelper.h"

#include <xercesc/validators/schema/SchemaValidator.hpp>

#include <iostream> // Debug
// Start of CEGUI namespace section
namespace CEGUI
{
    // Static data definition for default schema resource group name
    String XercesParser::d_defaultSchemaResourceGroup("");
    // static data definition of the SchemaDefaultResourceGroup property.
    XercesParserProperties::SchemaDefaultResourceGroup
        XercesParser::s_schemaDefaultResourceGroupProperty;

    ////////////////////////////////////////////////////////////////////////////////
    //
    // XercesParser methods
    //
    ////////////////////////////////////////////////////////////////////////////////

    XercesParser::XercesParser(void)
    {
        // set ID string
        d_identifierString = "CEGUI::XercesParser - Official Xerces-C++ based parser module for CEGUI";
        // add property
        addProperty(&s_schemaDefaultResourceGroupProperty);

        String propertyOrigin("XercesParser");
        CEGUI_DEFINE_PROPERTY(XercesParser, bool, "isXmlValidationEnabled",
                              "Property to get/set if XML validation is enabled or disabled globally. "
                              "If it's disabled it will not allow any xml validation. "
                              "If it's enabled the validation behaviour is dependending on what is "
                              "passed to parseXML.",
                              &XercesParser::setXmlValidationEnabled,
                              &XercesParser::isXmlValidationEnabled,
                              true);
    }

    XercesParser::~XercesParser(void)
    {}

    void XercesParser::parseXML(XMLHandler& handler, const RawDataContainer& source, const String& schemaName, bool xmlValidationEnabled)
    {
        XERCES_CPP_NAMESPACE_USE;

        XercesHandler xercesHandler(handler);

        // create parser
        SAX2XMLReader* reader = createReader(xercesHandler);

        try
        {
            bool forceXmlValidation;

            // ignore local settings if validation is disabled globally
            if (!isXmlValidationEnabled())
                forceXmlValidation = false;
            else
                forceXmlValidation = xmlValidationEnabled;

            // set up schema
            if (forceXmlValidation)
                initialiseSchema(reader, schemaName);
            // do parse
            doParse(reader, source);
        }
        catch (const XMLException& exc)
        {
            if (exc.getCode() != XMLExcepts::NoError)
            {
                delete reader;

                char* excmsg = XMLString::transcode(exc.getMessage());
                String message("An error occurred at line nr. " + PropertyHelper<std::uint32_t>::toString((std::uint32_t)exc.getSrcLine()) + " while parsing XML.  Additional information: ");
                message += excmsg;
                XMLString::release(&excmsg);

                throw FileIOException(message);
            }

        }
        catch (const SAXParseException& exc)
        {
            delete reader;

            char* excmsg = XMLString::transcode(exc.getMessage());
            String message("An error occurred at line nr. " + PropertyHelper<std::uint32_t>::toString((std::uint32_t)exc.getLineNumber()) + " while parsing XML.  Additional information: ");
            message += excmsg;
            XMLString::release(&excmsg);

            throw FileIOException(message);
        }
        catch (...)
        {
            delete reader;

            Logger::getSingleton().logEvent("An unexpected error occurred while parsing XML", Errors);
            throw;
        }

        // cleanup
        delete reader;
    }

    bool XercesParser::initialiseImpl(void)
    {
        XERCES_CPP_NAMESPACE_USE;

        // initialise Xerces-C XML system
        try
        {
            XMLPlatformUtils::Initialize();
        }
        catch (XMLException& exc)
        {
            // prepare a message about the failure
            char* excmsg = XMLString::transcode(exc.getMessage());
            String message("An exception occurred while initialising the Xerces-C XML system.  Additional information: ");
            message += excmsg;
            XMLString::release(&excmsg);

            // throw a C string (because it won't try and use logger, which may not be available)
            throw message.c_str();
        }

        return true;
    }

    void XercesParser::cleanupImpl(void)
    {
        // cleanup XML stuff
        XERCES_CPP_NAMESPACE_USE;
        XMLPlatformUtils::Terminate();
    }

    void XercesParser::populateAttributesBlock(const XERCES_CPP_NAMESPACE::Attributes& src, XMLAttributes& dest)
    {
        XERCES_CPP_NAMESPACE_USE;
        String attributeName;
        String attributeValue;

        for (unsigned int i = 0; i < src.getLength(); ++i)
        {
            // TODO dalfy: Optimize this using temporary value.
            attributeName = transcodeXmlCharToString(src.getLocalName(i), XMLString::stringLen(src.getLocalName(i)));
            attributeValue = transcodeXmlCharToString(src.getValue(i), XMLString::stringLen(src.getValue(i)));
            dest.add(attributeName, attributeValue);
        }
    }

    String XercesParser::transcodeXmlCharToString(const XMLCh* const xmlch_str, unsigned int inputLength)
    {
        XERCES_CPP_NAMESPACE_USE;

        XMLTransService::Codes  res;
        XMLTranscoder* transcoder = XMLPlatformUtils::fgTransService->makeNewTranscoderFor(XMLRecognizer::UTF_8, res, 4096, XMLPlatformUtils::fgMemoryManager );

        if (res == XMLTransService::Ok)
        {
            String out;
#if _XERCES_VERSION >= 30000
            XMLByte outBuff[128];
            XMLSize_t outputLength;
            XMLSize_t eaten = 0;
            XMLSize_t offset = 0;
#else /* _XERCES_VERSION >= 30000 */
            char outBuff[128];
            unsigned int outputLength;
            unsigned int eaten = 0;
            unsigned int offset = 0;
#endif /* _XERCES_VERSION >= 30000 */
//            unsigned int inputLength = XMLString::stringLen(xmlch_str); // dalfy caracters node need to transcode but give the size

            while (inputLength)
            {
                outputLength = transcoder->transcodeTo(xmlch_str + offset, inputLength, outBuff, 128, eaten, XMLTranscoder::UnRep_RepChar);
                out.append(outBuff, outputLength);
                offset += eaten;
                inputLength -= eaten;
            }

            delete transcoder;

            return out;
        }
        else
        {
            throw GenericException("Internal Error: Could not create UTF-8 string transcoder.");
        }

    }

    void XercesParser::initialiseSchema(XERCES_CPP_NAMESPACE::SAX2XMLReader* reader, const String& schemaName)
    {
        // only load the schema if it's name is passed
        if (!schemaName.empty())
        {
            XERCES_CPP_NAMESPACE_USE;

            // enable schema use and set validation options
            reader->setFeature(XMLUni::fgXercesSchema, true);
            reader->setFeature(XMLUni::fgSAX2CoreValidation, true);
            reader->setFeature(XMLUni::fgXercesValidationErrorAsFatal, true);

            // load in the raw schema data
            RawDataContainer rawSchemaData;
            // load the schema from the resource group
            Logger::getSingleton().logEvent("XercesParser::initialiseSchema - Attempting to load schema from file '" + schemaName + "'.");
            System::getSingleton().getResourceProvider()->loadRawDataContainer(schemaName, rawSchemaData, d_defaultSchemaResourceGroup);

            // wrap schema data in a xerces MemBufInputSource object
            MemBufInputSource schemaData(
                rawSchemaData.getDataPtr(),
                static_cast<const unsigned int>(rawSchemaData.getSize()),
#if CEGUI_STRING_CLASS == CEGUI_STRING_CLASS_STD
                schemaName.c_str(),
#elif CEGUI_STRING_CLASS == CEGUI_STRING_CLASS_UNICODE
                schemaName.toUtf8String().c_str(),
#endif
                false);
            reader->loadGrammar(schemaData, Grammar::SchemaGrammarType, true);
            // enable grammar reuse
            reader->setFeature(XMLUni::fgXercesUseCachedGrammarInParse, true);

            // set schema for usage
#if CEGUI_STRING_CLASS == CEGUI_STRING_CLASS_STD
            XMLCh* pval = XMLString::transcode(schemaName.c_str());
#elif CEGUI_STRING_CLASS == CEGUI_STRING_CLASS_UNICODE
            XMLCh* pval = XMLString::transcode(schemaName.toUtf8String().c_str());
#endif
            reader->setProperty(XMLUni::fgXercesSchemaExternalNoNameSpaceSchemaLocation, pval);
            XMLString::release(&pval);
            Logger::getSingleton().logEvent("XercesParser::initialiseSchema - XML schema file '" + schemaName + "' has been initialised.");

            // use resource provider to release loaded schema data (if it supports this)
            System::getSingleton().getResourceProvider()->unloadRawDataContainer(rawSchemaData);
        }
        else
        {
            // otherwise ignore the missing schema and proceed
            Logger::getSingleton().logEvent("XercesParser::initialiseSchema - No schema specified. Proceeding.");
        }
    }

    XERCES_CPP_NAMESPACE::SAX2XMLReader* XercesParser::createReader(XERCES_CPP_NAMESPACE::DefaultHandler& handler)
    {
        XERCES_CPP_NAMESPACE_USE;

        SAX2XMLReader* reader = XMLReaderFactory::createXMLReader();

        // set basic settings we want from parser
        reader->setFeature(XMLUni::fgSAX2CoreNameSpaces, true);

        // set handlers
        reader->setContentHandler(&handler);
        reader->setErrorHandler(&handler);

        return reader;
    }

    void XercesParser::doParse(XERCES_CPP_NAMESPACE::SAX2XMLReader* parser, const RawDataContainer& source)
    {
        XERCES_CPP_NAMESPACE_USE;

        MemBufInputSource  fileData(
            source.getDataPtr(),
            static_cast<const unsigned int>(source.getSize()),
            "Unknown",
            false);

         parser->parse(fileData);
    }

    ////////////////////////////////////////////////////////////////////////////////
    //
    // XercesHandler methods
    //
    ////////////////////////////////////////////////////////////////////////////////

    XercesHandler::XercesHandler(XMLHandler& handler) :
            d_handler(handler)
    {}

    XercesHandler::~XercesHandler(void)
    {}

    void XercesHandler::startElement(const XMLCh* const /*uri*/, const XMLCh* const localname, const XMLCh* const /*qname*/, const XERCES_CPP_NAMESPACE::Attributes& attrs)
    {
        XERCES_CPP_NAMESPACE_USE;
        XMLAttributes cegui_attributes;
        XercesParser::populateAttributesBlock(attrs, cegui_attributes);
        String element(XercesParser::transcodeXmlCharToString(localname, XMLString::stringLen(localname)));
        d_handler.elementStart(element, cegui_attributes);
    }

    void XercesHandler::endElement(const XMLCh* const /*uri*/, const XMLCh* const localname, const XMLCh* const /*qname*/)
    {
        XERCES_CPP_NAMESPACE_USE;
        String element(XercesParser::transcodeXmlCharToString(localname,XMLString::stringLen(localname)));
        d_handler.elementEnd(element);
    }

#if _XERCES_VERSION >= 30000
    void XercesHandler::characters(const XMLCh* const chars, const XMLSize_t length)
#else /* _XERCES_VERSION >= 30000 */
    void XercesHandler::characters (const XMLCh *const chars, const unsigned int length)
#endif /* _XERCES_VERSION >= 30000 */
    {
        d_handler.text(XercesParser::transcodeXmlCharToString(chars, length));
    }

    void XercesHandler::warning (const XERCES_CPP_NAMESPACE::SAXParseException &exc)
    {
        XERCES_CPP_NAMESPACE_USE;

        // prepare a message about the warning
        char* excmsg = XMLString::transcode(exc.getMessage());
        String message("Xerces warning: ");
        message += excmsg;
        XMLString::release(&excmsg);
        Logger::getSingleton().logEvent(message);
    }

    void XercesHandler::error (const XERCES_CPP_NAMESPACE::SAXParseException &exc)
    {
        throw exc;
    }

    void XercesHandler::fatalError (const XERCES_CPP_NAMESPACE::SAXParseException &exc)
    {
        throw exc;
    }

} // End of  CEGUI namespace section
<|endoftext|>


<commit_before>#ifndef PROTON_CPP_ERROR_CONDITION_H
#define PROTON_CPP_ERROR_CONDITION_H

/*
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 */

#include "proton/export.hpp"
#include "proton/value.hpp"

#include "proton/config.hpp"

#include <string>
#include <iosfwd>

struct pn_condition_t;

namespace proton {

/// Describes an endpoint error state.
class error_condition {
    /// @cond INTERNAL
    error_condition(pn_condition_t* c);
    /// @endcond

  public:
    error_condition() {}
    PN_CPP_EXTERN error_condition(std::string description);
    PN_CPP_EXTERN error_condition(std::string name, std::string description);
    PN_CPP_EXTERN error_condition(std::string name, std::string description, proton::value properties);

#if PN_CPP_HAS_DEFAULTED_FUNCTIONS
    error_condition(const error_condition&) = default;
    error_condition(error_condition&&) = default;
    error_condition& operator=(const error_condition&) = default;
    error_condition& operator=(error_condition&&) = default;
#endif

    /// If you are using a C++11 compiler you may use an error_condition
    /// in boolean contexts and the expression will be true if the error_condition is set
#if PN_CPP_HAS_EXPLICIT_CONVERSIONS
    PN_CPP_EXTERN explicit operator bool() const;
#endif

    /// No condition set.
    PN_CPP_EXTERN bool operator!() const;

    /// No condition has been set.
    PN_CPP_EXTERN bool empty() const;

    /// Condition name.
    PN_CPP_EXTERN std::string name() const;

    /// Descriptive string for condition.
    PN_CPP_EXTERN std::string description() const;

    /// Extra information for condition.
    PN_CPP_EXTERN value properties() const;

    /// Simple printable string for condition.
    PN_CPP_EXTERN std::string what() const;

    /// @cond INTERNAL
  private:
    std::string name_;
    std::string description_;
    proton::value properties_;

    friend class internal::factory<error_condition>;
    /// @endcond
};

PN_CPP_EXTERN bool operator==(const error_condition& x, const error_condition& y);

PN_CPP_EXTERN std::ostream& operator<<(std::ostream& o, const error_condition& err);

}

#endif // PROTON_CPP_ERROR_CONDITION_H
<commit_msg>NO-JIRA: [C++ binding] Doc improvement to error_condition<commit_after>#ifndef PROTON_CPP_ERROR_CONDITION_H
#define PROTON_CPP_ERROR_CONDITION_H

/*
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 */

#include "proton/export.hpp"
#include "proton/value.hpp"

#include "proton/config.hpp"

#include <string>
#include <iosfwd>

struct pn_condition_t;

namespace proton {

/// Describes an endpoint error state.
class error_condition {
    /// @cond INTERNAL
    error_condition(pn_condition_t* c);
    /// @endcond

  public:
    error_condition() {}
    /// Construct an error condition with only a description - in this case a default
    /// name will be used ("proton:io:error")
    PN_CPP_EXTERN error_condition(std::string description);
    /// Construct an error_condition with a name and a description
    PN_CPP_EXTERN error_condition(std::string name, std::string description);
    /// Construct an error_condition with name, description and some informational properties
    PN_CPP_EXTERN error_condition(std::string name, std::string description, proton::value properties);

#if PN_CPP_HAS_DEFAULTED_FUNCTIONS
    error_condition(const error_condition&) = default;
    error_condition(error_condition&&) = default;
    error_condition& operator=(const error_condition&) = default;
    error_condition& operator=(error_condition&&) = default;
#endif

    /// If you are using a C++11 compiler you may use an error_condition
    /// in boolean contexts and the expression will be true if the error_condition is set
#if PN_CPP_HAS_EXPLICIT_CONVERSIONS
    PN_CPP_EXTERN explicit operator bool() const;
#endif

    /// No condition set.
    PN_CPP_EXTERN bool operator!() const;

    /// No condition has been set.
    PN_CPP_EXTERN bool empty() const;

    /// Condition name.
    PN_CPP_EXTERN std::string name() const;

    /// Descriptive string for condition.
    PN_CPP_EXTERN std::string description() const;

    /// Extra information for condition.
    PN_CPP_EXTERN value properties() const;

    /// Simple printable string for condition.
    PN_CPP_EXTERN std::string what() const;

    /// @cond INTERNAL
  private:
    std::string name_;
    std::string description_;
    proton::value properties_;

    friend class internal::factory<error_condition>;
    /// @endcond
};

PN_CPP_EXTERN bool operator==(const error_condition& x, const error_condition& y);

PN_CPP_EXTERN std::ostream& operator<<(std::ostream& o, const error_condition& err);

}

#endif // PROTON_CPP_ERROR_CONDITION_H
<|endoftext|>


<commit_before>/**
 *   Copyright (c) 2014 Cyrille Berger <cberger@cberger.net>
 *
 *   This Source Code Form is subject to the terms of the Mozilla Public
 *   License, v. 2.0. If a copy of the MPL was not distributed with this
 *   file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include "Printer.h"

#include <QQuickWindow>
#include <QPainter>
#include <QPrinter>

#include "MiniPage.h"
#include "PageSize.h"

Printer::Printer(QQuickItem *parent):
  QQuickItem(parent), m_window(0), m_printer(0), m_painter(0), m_mode(GRAB_IMAGE), m_pageSize(new PageSize), m_miniPage(new MiniPage), m_orientation(Portrait)
{
  // By default, QQuickItem does not draw anything. If you subclass
  // QQuickItem to create a visual item, you will need to uncomment the
  // following line and re-implement updatePaintNode()

  // setFlag(ItemHasContents, true);
  connect(m_pageSize, SIGNAL(pageSizeChanged()), this, SLOT(updatePageSize()));
}

Printer::~Printer()
{
  endPrinting();
}

void Printer::beginPrinting()
{
  if(not m_window)
  {
    qWarning() << "Window is not set, cannot print!";
    return;
  }
  if(m_printer)
  {
    qWarning() << "Printing is already started!";
    return;
  }
  if(m_filename.isEmpty())
  {
    qWarning() << "No filenames specified";
    return;
  }
  m_printer = new QPrinter;
  m_printer->setFullPage(true);
  m_printer->setOutputFileName(m_filename);
  m_printer->setPageSize(m_pageSize->pageSize());
  m_printer->setOrientation(QPrinter::Orientation(m_orientation));

  // Setup mini pages
  const int miniPageWidth  = m_pageSize->width() / m_miniPage->columns();
  const int miniPageHeight = m_pageSize->height() / m_miniPage->rows();
  const int miniPageMargin = m_miniPage->margin();
  const QMargins miniPageMargins(miniPageMargin, miniPageMargin, miniPageMargin, miniPageMargin);

  for(int r = 0; r < m_miniPage->rows(); ++r)
  {
    for(int c = 0; c < m_miniPage->columns(); ++c)
    {
      QRect rect(c * miniPageWidth, r * miniPageHeight, miniPageWidth, miniPageHeight);
      m_miniPages.append(rect.marginsRemoved(miniPageMargins));
    }
  }

  m_painter = new QPainter;
  m_painter->begin(m_printer);
  m_painter->setWindow(0, 0, m_pageSize->width(), m_pageSize->height());
  m_miniPageIndex = 0;
}

void Printer::printWindow()
{
  if(not m_printer)
  {
    qWarning() << "Printing not started";
    return;
  }
  switch (m_mode)
  {
  case GRAB_IMAGE:
    {
      QImage image = m_window->grabWindow();

      QRect pageRect = m_miniPages[m_miniPageIndex];
      QSize targetSize = image.size();
      targetSize.scale(pageRect.width(), pageRect.height(), Qt::KeepAspectRatio);
      QSize trans_size = 0.5 * (pageRect.size() - targetSize);
      QPoint trans(trans_size.width(), trans_size.height());
      m_painter->drawImage(QRectF(trans + pageRect.topLeft(), targetSize), image);
    }
    break;
  default:
    qWarning() << "Unimplemented printing mode.";
    break;
  }
}

void Printer::newPage()
{
  if(not m_printer)
  {
    qWarning() << "Printing not started";
    return;
  }
  ++m_miniPageIndex;
  qDebug() << m_miniPageIndex << m_miniPages.size();
  if(m_miniPageIndex >= m_miniPages.size())
  {
    m_miniPageIndex = 0;
    m_printer->newPage();
  }
}

void Printer::endPrinting()
{
  if(m_printer)
  {
    m_painter->end();
    delete m_painter;
    m_painter = 0;
    delete m_printer;
    m_printer = 0;
  }
}

void Printer::updatePageSize()
{
  if(m_printer)
  {
    qDebug() << "updatePageSize" << m_pageSize->width() << " " << m_pageSize->height();
    m_printer->setPageSize(m_pageSize->pageSize());
  }
}
<commit_msg>fix deformation and print position in landscape mode<commit_after>/**
 *   Copyright (c) 2014 Cyrille Berger <cberger@cberger.net>
 *
 *   This Source Code Form is subject to the terms of the Mozilla Public
 *   License, v. 2.0. If a copy of the MPL was not distributed with this
 *   file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include "Printer.h"

#include <QQuickWindow>
#include <QPainter>
#include <QPrinter>

#include "MiniPage.h"
#include "PageSize.h"

Printer::Printer(QQuickItem *parent):
  QQuickItem(parent), m_window(0), m_printer(0), m_painter(0), m_mode(GRAB_IMAGE), m_pageSize(new PageSize), m_miniPage(new MiniPage), m_orientation(Portrait)
{
  // By default, QQuickItem does not draw anything. If you subclass
  // QQuickItem to create a visual item, you will need to uncomment the
  // following line and re-implement updatePaintNode()

  // setFlag(ItemHasContents, true);
  connect(m_pageSize, SIGNAL(pageSizeChanged()), this, SLOT(updatePageSize()));
}

Printer::~Printer()
{
  endPrinting();
}

void Printer::beginPrinting()
{
  if(not m_window)
  {
    qWarning() << "Window is not set, cannot print!";
    return;
  }
  if(m_printer)
  {
    qWarning() << "Printing is already started!";
    return;
  }
  if(m_filename.isEmpty())
  {
    qWarning() << "No filenames specified";
    return;
  }
  m_printer = new QPrinter;
//  m_printer->setFullPage(true); // TODO: reintroduce as an option
  m_printer->setOutputFileName(m_filename);
  m_printer->setPageSize(m_pageSize->pageSize());
  m_printer->setOrientation(QPrinter::Orientation(m_orientation));

  // Setup mini pages
  const int miniPageWidth  = m_printer->pageRect().width() / m_miniPage->columns();
  const int miniPageHeight = m_printer->pageRect().height() / m_miniPage->rows();
  const int miniPageMargin = m_miniPage->margin();
  const QMargins miniPageMargins(miniPageMargin, miniPageMargin, miniPageMargin, miniPageMargin);

  for(int r = 0; r < m_miniPage->rows(); ++r)
  {
    for(int c = 0; c < m_miniPage->columns(); ++c)
    {
      QRect rect(c * miniPageWidth + m_printer->pageRect().x(), r * miniPageHeight + m_printer->pageRect().y(), miniPageWidth, miniPageHeight);
      m_miniPages.append(rect.marginsRemoved(miniPageMargins));
    }
  }

  m_painter = new QPainter;
  m_painter->begin(m_printer);
  m_miniPageIndex = 0;
}

void Printer::printWindow()
{
  if(not m_printer)
  {
    qWarning() << "Printing not started";
    return;
  }
  switch (m_mode)
  {
  case GRAB_IMAGE:
    {
      QImage image = m_window->grabWindow();

      QRect pageRect = m_miniPages[m_miniPageIndex];
      QSize targetSize = image.size();
      targetSize.scale(pageRect.width(), pageRect.height(), Qt::KeepAspectRatio);
      QSize trans_size = 0.5 * (pageRect.size() - targetSize);
      QPoint trans(trans_size.width(), trans_size.height());
      m_painter->drawImage(QRectF(trans + pageRect.topLeft(), targetSize), image);
    }
    break;
  default:
    qWarning() << "Unimplemented printing mode.";
    break;
  }
}

void Printer::newPage()
{
  if(not m_printer)
  {
    qWarning() << "Printing not started";
    return;
  }
  ++m_miniPageIndex;
  if(m_miniPageIndex >= m_miniPages.size())
  {
    m_miniPageIndex = 0;
    m_printer->newPage();
  }
}

void Printer::endPrinting()
{
  if(m_printer)
  {
    m_painter->end();
    delete m_painter;
    m_painter = 0;
    delete m_printer;
    m_printer = 0;
  }
}

void Printer::updatePageSize()
{
  if(m_printer)
  {
    m_printer->setPageSize(m_pageSize->pageSize());
  }
}
<|endoftext|>


<commit_before>// Copyright (c) 2010 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 <atlbase.h>
#include <vector>

#include "base/file_path.h"
#include "base/scoped_comptr_win.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_window.h"
#include "chrome/browser/renderer_host/render_widget_host_view_win.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/notification_type.h"
#include "chrome/test/in_process_browser_test.h"
#include "chrome/test/ui_test_utils.h"

namespace {

class AccessibilityWinBrowserTest : public InProcessBrowserTest {
 public:
  void SetUpCommandLine(CommandLine* command_line) {
    // Turns on the accessibility in the renderer. Off by default until
    // http://crbug.com/25564 is fixed.
    command_line->AppendSwitch(switches::kEnableRendererAccessibility);
  }

 protected:
  IAccessible* GetRenderWidgetHostViewClientAccessible();
};

class AccessibleChecker {
 public:
  AccessibleChecker(std::wstring expected_name, int32 expected_role);

  // Append an AccessibleChecker that verifies accessibility information for
  // a child IAccessible. Order is important.
  void AppendExpectedChild(AccessibleChecker* expected_child);

  // Check that the name and role of the given IAccessible instance and its
  // descendants match the expected names and roles that this object was
  // initialized with.
  void CheckAccessible(IAccessible* accessible);

  typedef std::vector<AccessibleChecker*> AccessibleCheckerVector;

 private:
  void CheckAccessibleName(IAccessible* accessible);
  void CheckAccessibleRole(IAccessible* accessible);
  void CheckAccessibleChildren(IAccessible* accessible);

 private:
  // Expected accessible name. Checked against IAccessible::get_accName.
  std::wstring name_;

  // Expected accessible role. Checked against IAccessible::get_accRole.
  int32 role_;

  // Expected accessible children. Checked using IAccessible::get_accChildCount
  // and ::AccessibleChildren.
  AccessibleCheckerVector children_;
};

VARIANT CreateI4Variant(LONG value) {
  VARIANT variant = {0};

  V_VT(&variant) = VT_I4;
  V_I4(&variant) = value;

  return variant;
}

IAccessible* GetAccessibleFromResultVariant(IAccessible* parent, VARIANT *var) {
  switch (V_VT(var)) {
    case VT_DISPATCH:
      return CComQIPtr<IAccessible>(V_DISPATCH(var)).Detach();
      break;

    case VT_I4: {
      CComPtr<IDispatch> dispatch;
      HRESULT hr = parent->get_accChild(CreateI4Variant(V_I4(var)), &dispatch);
      EXPECT_EQ(hr, S_OK);
      return CComQIPtr<IAccessible>(dispatch).Detach();
      break;
    }
  }

  return NULL;
}

// Retrieve the MSAA client accessibility object for the Render Widget Host View
// of the selected tab.
IAccessible*
AccessibilityWinBrowserTest::GetRenderWidgetHostViewClientAccessible() {
  HWND hwnd_render_widget_host_view =
      browser()->GetSelectedTabContents()->GetRenderWidgetHostView()->
          GetNativeView();

  IAccessible* accessible;
  HRESULT hr = AccessibleObjectFromWindow(
      hwnd_render_widget_host_view, OBJID_CLIENT,
      IID_IAccessible, reinterpret_cast<void**>(&accessible));
  EXPECT_EQ(S_OK, hr);
  EXPECT_NE(accessible, reinterpret_cast<IAccessible*>(NULL));

  return accessible;
}

AccessibleChecker::AccessibleChecker(
    std::wstring expected_name, int32 expected_role) :
    name_(expected_name),
    role_(expected_role) {
}

void AccessibleChecker::AppendExpectedChild(
    AccessibleChecker* expected_child) {
  children_.push_back(expected_child);
}

void AccessibleChecker::CheckAccessible(IAccessible* accessible) {
  CheckAccessibleName(accessible);
  CheckAccessibleRole(accessible);
  CheckAccessibleChildren(accessible);
}

void AccessibleChecker::CheckAccessibleName(IAccessible* accessible) {
  CComBSTR name;
  HRESULT hr =
      accessible->get_accName(CreateI4Variant(CHILDID_SELF), &name);

  if (name_.empty()) {
    // If the object doesn't have name S_FALSE should be returned.
    EXPECT_EQ(hr, S_FALSE);
  } else {
    // Test that the correct string was returned.
    EXPECT_EQ(hr, S_OK);
    EXPECT_EQ(CompareString(LOCALE_NEUTRAL, 0, name, SysStringLen(name),
                  name_.c_str(), name_.length()),
              CSTR_EQUAL);
  }
}

void AccessibleChecker::CheckAccessibleRole(IAccessible* accessible) {
  VARIANT var_role = {0};
  HRESULT hr =
      accessible->get_accRole(CreateI4Variant(CHILDID_SELF), &var_role);
  EXPECT_EQ(hr, S_OK);
  EXPECT_EQ(V_VT(&var_role), VT_I4);
  EXPECT_EQ(V_I4(&var_role), role_);
}

void AccessibleChecker::CheckAccessibleChildren(IAccessible* parent) {
  LONG child_count = 0;
  HRESULT hr = parent->get_accChildCount(&child_count);
  EXPECT_EQ(hr, S_OK);

  // TODO(dmazzoni): remove as soon as test passes on build bot
  printf("CheckAccessibleChildren: actual=%d expected=%d\n",
         static_cast<int>(child_count),
         static_cast<int>(children_.size()));

  ASSERT_EQ(child_count, children_.size());

  std::auto_ptr<VARIANT> child_array(new VARIANT[child_count]);
  LONG obtained_count = 0;
  hr = AccessibleChildren(parent, 0, child_count,
                          child_array.get(), &obtained_count);
  ASSERT_EQ(hr, S_OK);
  ASSERT_EQ(child_count, obtained_count);

  VARIANT* child = child_array.get();
  for (AccessibleCheckerVector::iterator child_checker = children_.begin();
       child_checker != children_.end();
       ++child_checker, ++child) {
    ScopedComPtr<IAccessible> child_accessible;
    child_accessible.Attach(GetAccessibleFromResultVariant(parent, child));
    (*child_checker)->CheckAccessible(child_accessible);
  }
}

// Flaky http://crbug.com/44546.
IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
                       FAILS_TestRendererAccessibilityTree) {
  GURL tree_url(
      "data:text/html,<title>Accessibility Win Test</title>"
      "<input type='button' value='push' /><input type='checkbox' />"
      "");
  browser()->OpenURL(tree_url, GURL(), CURRENT_TAB, PageTransition::TYPED);
  ui_test_utils::WaitForNotification(
      NotificationType::RENDER_VIEW_HOST_ACCESSIBILITY_TREE_UPDATED);

  ScopedComPtr<IAccessible> document_accessible(
      GetRenderWidgetHostViewClientAccessible());
  ASSERT_NE(document_accessible.get(), reinterpret_cast<IAccessible*>(NULL));

  AccessibleChecker button_checker(L"push", ROLE_SYSTEM_PUSHBUTTON);
  AccessibleChecker checkbox_checker(L"", ROLE_SYSTEM_CHECKBUTTON);

  AccessibleChecker grouping_checker(L"", ROLE_SYSTEM_GROUPING);
  grouping_checker.AppendExpectedChild(&button_checker);
  grouping_checker.AppendExpectedChild(&checkbox_checker);

  AccessibleChecker document_checker(L"", ROLE_SYSTEM_DOCUMENT);
  document_checker.AppendExpectedChild(&grouping_checker);

  // Check the accessible tree of the renderer.
  document_checker.CheckAccessible(document_accessible);

  // Check that document accessible has a parent accessible.
  ScopedComPtr<IDispatch> parent_dispatch;
  HRESULT hr = document_accessible->get_accParent(parent_dispatch.Receive());
  EXPECT_EQ(hr, S_OK);
  EXPECT_NE(parent_dispatch, reinterpret_cast<IDispatch*>(NULL));

  // Navigate to another page.
  GURL about_url("about:");
  ui_test_utils::NavigateToURL(browser(), about_url);

  // Verify that the IAccessible reference still points to a valid object and
  // that it calls to its methods fail since the tree is no longer valid after
  // the page navagation.
  // Todo(ctguil): Currently this is giving a false positive because E_FAIL is
  // returned when BrowserAccessibilityManager::RequestAccessibilityInfo fails
  // since the previous render view host connection is lost. Verify that
  // instances are actually marked as invalid once the browse side cache is
  // checked in.
  CComBSTR name;
  hr = document_accessible->get_accName(CreateI4Variant(CHILDID_SELF), &name);
  ASSERT_EQ(E_FAIL, hr);
}
}  // namespace.
<commit_msg>Fix TestRendererAccessibilityTree test.<commit_after>// Copyright (c) 2010 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 <atlbase.h>
#include <vector>

#include "base/file_path.h"
#include "base/scoped_comptr_win.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_window.h"
#include "chrome/browser/renderer_host/render_widget_host_view_win.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/notification_type.h"
#include "chrome/test/in_process_browser_test.h"
#include "chrome/test/ui_test_utils.h"

namespace {

class AccessibilityWinBrowserTest : public InProcessBrowserTest {
 public:
  void SetUpCommandLine(CommandLine* command_line) {
    // Turns on the accessibility in the renderer. Off by default until
    // http://crbug.com/25564 is fixed.
    command_line->AppendSwitch(switches::kEnableRendererAccessibility);
  }

 protected:
  IAccessible* GetRenderWidgetHostViewClientAccessible();
};

class AccessibleChecker {
 public:
  AccessibleChecker(std::wstring expected_name, int32 expected_role);
  AccessibleChecker(std::wstring expected_name, std::wstring expected_role);

  // Append an AccessibleChecker that verifies accessibility information for
  // a child IAccessible. Order is important.
  void AppendExpectedChild(AccessibleChecker* expected_child);

  // Check that the name and role of the given IAccessible instance and its
  // descendants match the expected names and roles that this object was
  // initialized with.
  void CheckAccessible(IAccessible* accessible);

  typedef std::vector<AccessibleChecker*> AccessibleCheckerVector;

 private:
  void CheckAccessibleName(IAccessible* accessible);
  void CheckAccessibleRole(IAccessible* accessible);
  void CheckAccessibleChildren(IAccessible* accessible);

 private:
  // Expected accessible name. Checked against IAccessible::get_accName.
  std::wstring name_;

  // Expected accessible role. Checked against IAccessible::get_accRole.
  CComVariant role_;

  // Expected accessible children. Checked using IAccessible::get_accChildCount
  // and ::AccessibleChildren.
  AccessibleCheckerVector children_;
};

VARIANT CreateI4Variant(LONG value) {
  VARIANT variant = {0};

  V_VT(&variant) = VT_I4;
  V_I4(&variant) = value;

  return variant;
}

IAccessible* GetAccessibleFromResultVariant(IAccessible* parent, VARIANT *var) {
  switch (V_VT(var)) {
    case VT_DISPATCH:
      return CComQIPtr<IAccessible>(V_DISPATCH(var)).Detach();
      break;

    case VT_I4: {
      CComPtr<IDispatch> dispatch;
      HRESULT hr = parent->get_accChild(CreateI4Variant(V_I4(var)), &dispatch);
      EXPECT_EQ(hr, S_OK);
      return CComQIPtr<IAccessible>(dispatch).Detach();
      break;
    }
  }

  return NULL;
}

// Retrieve the MSAA client accessibility object for the Render Widget Host View
// of the selected tab.
IAccessible*
AccessibilityWinBrowserTest::GetRenderWidgetHostViewClientAccessible() {
  HWND hwnd_render_widget_host_view =
      browser()->GetSelectedTabContents()->GetRenderWidgetHostView()->
          GetNativeView();

  IAccessible* accessible;
  HRESULT hr = AccessibleObjectFromWindow(
      hwnd_render_widget_host_view, OBJID_CLIENT,
      IID_IAccessible, reinterpret_cast<void**>(&accessible));
  EXPECT_EQ(S_OK, hr);
  EXPECT_NE(accessible, reinterpret_cast<IAccessible*>(NULL));

  return accessible;
}

AccessibleChecker::AccessibleChecker(
    std::wstring expected_name, int32 expected_role) :
    name_(expected_name),
    role_(expected_role) {
}

AccessibleChecker::AccessibleChecker(
    std::wstring expected_name, std::wstring expected_role) :
    name_(expected_name),
    role_(expected_role.c_str()) {
}

void AccessibleChecker::AppendExpectedChild(
    AccessibleChecker* expected_child) {
  children_.push_back(expected_child);
}

void AccessibleChecker::CheckAccessible(IAccessible* accessible) {
  CheckAccessibleName(accessible);
  CheckAccessibleRole(accessible);
  CheckAccessibleChildren(accessible);
}

void AccessibleChecker::CheckAccessibleName(IAccessible* accessible) {
  CComBSTR name;
  HRESULT hr =
      accessible->get_accName(CreateI4Variant(CHILDID_SELF), &name);

  if (name_.empty()) {
    // If the object doesn't have name S_FALSE should be returned.
    EXPECT_EQ(hr, S_FALSE);
  } else {
    // Test that the correct string was returned.
    EXPECT_EQ(hr, S_OK);
    EXPECT_EQ(CompareString(LOCALE_NEUTRAL, 0, name, SysStringLen(name),
                  name_.c_str(), name_.length()),
              CSTR_EQUAL);
  }
}

void AccessibleChecker::CheckAccessibleRole(IAccessible* accessible) {
  VARIANT var_role = {0};
  HRESULT hr =
      accessible->get_accRole(CreateI4Variant(CHILDID_SELF), &var_role);
  EXPECT_EQ(hr, S_OK);
  ASSERT_TRUE(role_ == var_role);
}

void AccessibleChecker::CheckAccessibleChildren(IAccessible* parent) {
  LONG child_count = 0;
  HRESULT hr = parent->get_accChildCount(&child_count);
  EXPECT_EQ(hr, S_OK);
  ASSERT_EQ(child_count, children_.size());

  std::auto_ptr<VARIANT> child_array(new VARIANT[child_count]);
  LONG obtained_count = 0;
  hr = AccessibleChildren(parent, 0, child_count,
                          child_array.get(), &obtained_count);
  ASSERT_EQ(hr, S_OK);
  ASSERT_EQ(child_count, obtained_count);

  VARIANT* child = child_array.get();
  for (AccessibleCheckerVector::iterator child_checker = children_.begin();
       child_checker != children_.end();
       ++child_checker, ++child) {
    ScopedComPtr<IAccessible> child_accessible;
    child_accessible.Attach(GetAccessibleFromResultVariant(parent, child));
    (*child_checker)->CheckAccessible(child_accessible);
  }
}

IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
                       TestRendererAccessibilityTree) {
  GURL tree_url(
      "data:text/html,<title>Accessibility Win Test</title>"
      "<input type='button' value='push' /><input type='checkbox' />"
      "");
  browser()->OpenURL(tree_url, GURL(), CURRENT_TAB, PageTransition::TYPED);
  ui_test_utils::WaitForNotification(
      NotificationType::RENDER_VIEW_HOST_ACCESSIBILITY_TREE_UPDATED);

  ScopedComPtr<IAccessible> document_accessible(
      GetRenderWidgetHostViewClientAccessible());
  ASSERT_NE(document_accessible.get(), reinterpret_cast<IAccessible*>(NULL));

  AccessibleChecker button_checker(L"push", ROLE_SYSTEM_PUSHBUTTON);
  AccessibleChecker checkbox_checker(L"", ROLE_SYSTEM_CHECKBUTTON);

  AccessibleChecker grouping_checker(L"", L"div");
  grouping_checker.AppendExpectedChild(&button_checker);
  grouping_checker.AppendExpectedChild(&checkbox_checker);

  AccessibleChecker document_checker(L"", ROLE_SYSTEM_DOCUMENT);
  document_checker.AppendExpectedChild(&grouping_checker);

  // Check the accessible tree of the renderer.
  document_checker.CheckAccessible(document_accessible);

  // Check that document accessible has a parent accessible.
  ScopedComPtr<IDispatch> parent_dispatch;
  HRESULT hr = document_accessible->get_accParent(parent_dispatch.Receive());
  EXPECT_EQ(hr, S_OK);
  EXPECT_NE(parent_dispatch, reinterpret_cast<IDispatch*>(NULL));

  // Navigate to another page.
  GURL about_url("about:");
  ui_test_utils::NavigateToURL(browser(), about_url);

  // Verify that the IAccessible reference still points to a valid object and
  // that it calls to its methods fail since the tree is no longer valid after
  // the page navagation.
  // Todo(ctguil): Currently this is giving a false positive because E_FAIL is
  // returned when BrowserAccessibilityManager::RequestAccessibilityInfo fails
  // since the previous render view host connection is lost. Verify that
  // instances are actually marked as invalid once the browse side cache is
  // checked in.
  CComBSTR name;
  hr = document_accessible->get_accName(CreateI4Variant(CHILDID_SELF), &name);
  ASSERT_EQ(E_FAIL, hr);
}
}  // namespace.
<|endoftext|>


<commit_before>/**
 Copyright 2017 Daniel Garcia Vaglio <degv364@gmail.com> Esteban Zamora Alvarado <estebanzacr.20@gmail.com>

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

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

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

 **/

#include "hi/tasks/lcd_draw_task.hh"
#include "hd/optimized_driver.hh"

LcdDrawTask::LcdDrawTask(void)
{
    Task::SetTaskName(LCD_DRAW);
    Task::SetTaskType(ONE_SHOT);
    m_u16SkyColor = (uint16_t)LCDColorTranslate(GRAPHICS_COLOR_DEEP_SKY_BLUE);
    m_u16GroundColor = (uint16_t) LCDColorTranslate(GRAPHICS_COLOR_BROWN);

    m_u16HorizonLevelY = 63;
    m_u16NextHorizonLevelY = 63;
}

return_e LcdDrawTask::setup(Heap* i_Heap)
{
    return_e rt;

    // Initializes display hardware
    Crystalfontz128x128_Init();
    // Set default screen orientation
    LCDSetOrientation();

    //Initializes tasks state booleans
    m_bIsFirstLcdDraw = true;
    m_bIsFirstIteration = true;

    //Tasks info setup
    Task::SetTaskExecutionCondition(false);
    Task::SetTaskTickInterval(0);

    //Messages memory allocation
    rt = i_Heap->Allocate(HEAP_MEM_SIZE, &m_pHeapMem);

    return (rt == RETURN_NO_SPACE) ? RETURN_FAIL : RETURN_OK;
}

return_e LcdDrawTask::run(void)
{
  // Use m_sContext->foreground
    return_e rt;
    message_t l_stInputMessage;
    bool l_bGotValidMessage = false;

    if (m_bIsFirstIteration) {

        //Receive message in first Draw Iteration

        rt = Task::Incoming.PopMessage(&l_stInputMessage);
        while (rt != RETURN_EMPTY) {
            if (l_stInputMessage.message_type == HORIZON_PARAMS
                        && l_stInputMessage.sender == LCD_ISSUE) {
                m_u16NextHorizonLevelY = (uint16_t) l_stInputMessage.data[0];
                l_bGotValidMessage = true;
            }
            rt = Task::Incoming.PopMessage(&l_stInputMessage);
        }

        if (!l_bGotValidMessage){
            return RETURN_OK;
        }

        if (m_bIsFirstLcdDraw) {
            m_u16NextHorizonLevelY -= m_u16NextHorizonLevelY % DRAW_CHUNK_LINES;
            m_u16NextHorizonLevelY = max(m_u16NextHorizonLevelY, 0);
            m_u16CurrentHorizonIterLevelY = 0;
            InitialDrawIteration(128 % DRAW_CHUNK_LINES);
        }
        else {
            m_u16CurrentHorizonIterLevelY = m_u16HorizonLevelY;
            UpdateDrawIteration((abs(m_u16NextHorizonLevelY-m_u16HorizonLevelY)) % DRAW_CHUNK_LINES);
        }

        m_bIsFirstIteration = false;
    }
    else {
        if (m_bIsFirstLcdDraw) {
            InitialDrawIteration(DRAW_CHUNK_LINES);
        }
        else {
            UpdateDrawIteration(DRAW_CHUNK_LINES);
        }
    }

    bool l_bFinishedIterations = m_bIsFirstLcdDraw ?
                                m_u16CurrentHorizonIterLevelY == 128 :
                                m_u16CurrentHorizonIterLevelY == m_u16NextHorizonLevelY;

    if (l_bFinishedIterations) {
        m_u16HorizonLevelY = m_u16NextHorizonLevelY;

	m_bIsFirstLcdDraw = false;

        m_bIsFirstIteration = true; //Prepare for next draw iteration chain
    }
    else {
        //Define Execute LCD_DRAW for Scheduler message (Auto-Trigger)
        m_pHeapMem[0] = (uint32_t) LCD_DRAW;
        message_t l_stTriggerDrawMessage = {LCD_ISSUE,
                                            SCHEDULER,
                                            ADD_TO_EXECUTION,
                                            1,
                                            m_pHeapMem};
        //Send message
        rt = Task::Outgoing.AddMessage(l_stTriggerDrawMessage);
    }

    return RETURN_OK;
}

void LcdDrawTask::InitialDrawIteration(uint16_t i_u16CurrentIterationDeltaY)
{
    uint16_t l_u16CurrentColor;
    int16_t l_u16NextHorizonIterLevelY = m_u16CurrentHorizonIterLevelY + i_u16CurrentIterationDeltaY;

    if (l_u16NextHorizonIterLevelY < m_u16NextHorizonLevelY) {
        l_u16CurrentColor = m_u16SkyColor;

    }
    else {
        l_u16CurrentColor = m_u16GroundColor;
    }
    LCDDrawCompleteHorizontalRect(m_u16CurrentHorizonIterLevelY,l_u16NextHorizonIterLevelY, l_u16CurrentColor);
    m_u16CurrentHorizonIterLevelY = l_u16NextHorizonIterLevelY;
}

void LcdDrawTask::UpdateDrawIteration(uint16_t i_u16CurrentIterationDeltaY)
{
    uint16_t l_u16NextHorizonIterLevelY;
    uint16_t l_u16CurrentColor;

    if ((int16_t)m_u16NextHorizonLevelY-(int16_t)m_u16HorizonLevelY >= 0) {
        l_u16NextHorizonIterLevelY = m_u16CurrentHorizonIterLevelY + i_u16CurrentIterationDeltaY;
	l_u16CurrentColor = m_u16SkyColor;
    }
    else {
        l_u16NextHorizonIterLevelY = m_u16CurrentHorizonIterLevelY - i_u16CurrentIterationDeltaY;
	l_u16CurrentColor = m_u16GroundColor;
    }

    LCDDrawCompleteHorizontalRect(m_u16CurrentHorizonIterLevelY,l_u16NextHorizonIterLevelY, l_u16CurrentColor);
    m_u16CurrentHorizonIterLevelY = l_u16NextHorizonIterLevelY;
}
<commit_msg>Fix order when calling draw rectangle<commit_after>/**
 Copyright 2017 Daniel Garcia Vaglio <degv364@gmail.com> Esteban Zamora Alvarado <estebanzacr.20@gmail.com>

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

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

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

 **/

#include "hi/tasks/lcd_draw_task.hh"
#include "hd/optimized_driver.hh"

LcdDrawTask::LcdDrawTask(void)
{
    Task::SetTaskName(LCD_DRAW);
    Task::SetTaskType(ONE_SHOT);
    m_u16SkyColor = (uint16_t)LCDColorTranslate(GRAPHICS_COLOR_DEEP_SKY_BLUE);
    m_u16GroundColor = (uint16_t) LCDColorTranslate(GRAPHICS_COLOR_BROWN);

    m_u16HorizonLevelY = 63;
    m_u16NextHorizonLevelY = 63;
}

return_e LcdDrawTask::setup(Heap* i_Heap)
{
    return_e rt;

    // Initializes display hardware
    Crystalfontz128x128_Init();
    // Set default screen orientation
    LCDSetOrientation();

    //Initializes tasks state booleans
    m_bIsFirstLcdDraw = true;
    m_bIsFirstIteration = true;

    //Tasks info setup
    Task::SetTaskExecutionCondition(false);
    Task::SetTaskTickInterval(0);

    //Messages memory allocation
    rt = i_Heap->Allocate(HEAP_MEM_SIZE, &m_pHeapMem);

    return (rt == RETURN_NO_SPACE) ? RETURN_FAIL : RETURN_OK;
}

return_e LcdDrawTask::run(void)
{
  // Use m_sContext->foreground
    return_e rt;
    message_t l_stInputMessage;
    bool l_bGotValidMessage = false;

    if (m_bIsFirstIteration) {

        //Receive message in first Draw Iteration

        rt = Task::Incoming.PopMessage(&l_stInputMessage);
        while (rt != RETURN_EMPTY) {
            if (l_stInputMessage.message_type == HORIZON_PARAMS
                        && l_stInputMessage.sender == LCD_ISSUE) {
                m_u16NextHorizonLevelY = (uint16_t) l_stInputMessage.data[0];
                l_bGotValidMessage = true;
            }
            rt = Task::Incoming.PopMessage(&l_stInputMessage);
        }

        if (!l_bGotValidMessage){
            return RETURN_OK;
        }

        if (m_bIsFirstLcdDraw) {
            m_u16NextHorizonLevelY -= m_u16NextHorizonLevelY % DRAW_CHUNK_LINES;
            m_u16NextHorizonLevelY = max(m_u16NextHorizonLevelY, 0);
            m_u16CurrentHorizonIterLevelY = 0;
            InitialDrawIteration(128 % DRAW_CHUNK_LINES);
        }
        else {
            m_u16CurrentHorizonIterLevelY = m_u16HorizonLevelY;
            UpdateDrawIteration((abs(m_u16NextHorizonLevelY-m_u16HorizonLevelY)) % DRAW_CHUNK_LINES);
        }

        m_bIsFirstIteration = false;
    }
    else {
        if (m_bIsFirstLcdDraw) {
            InitialDrawIteration(DRAW_CHUNK_LINES);
        }
        else {
            UpdateDrawIteration(DRAW_CHUNK_LINES);
        }
    }

    bool l_bFinishedIterations = m_bIsFirstLcdDraw ?
                                m_u16CurrentHorizonIterLevelY == 128 :
                                m_u16CurrentHorizonIterLevelY == m_u16NextHorizonLevelY;

    if (l_bFinishedIterations) {
        m_u16HorizonLevelY = m_u16NextHorizonLevelY;

	m_bIsFirstLcdDraw = false;

        m_bIsFirstIteration = true; //Prepare for next draw iteration chain
    }
    else {
        //Define Execute LCD_DRAW for Scheduler message (Auto-Trigger)
        m_pHeapMem[0] = (uint32_t) LCD_DRAW;
        message_t l_stTriggerDrawMessage = {LCD_ISSUE,
                                            SCHEDULER,
                                            ADD_TO_EXECUTION,
                                            1,
                                            m_pHeapMem};
        //Send message
        rt = Task::Outgoing.AddMessage(l_stTriggerDrawMessage);
    }

    return RETURN_OK;
}

void LcdDrawTask::InitialDrawIteration(uint16_t i_u16CurrentIterationDeltaY)
{
    uint16_t l_u16CurrentColor;
    uint16_t l_u16NextHorizonIterLevelY = m_u16CurrentHorizonIterLevelY + i_u16CurrentIterationDeltaY;
    uint16_t l_u16HorizonBottom;
    uint16_t l_u16HorizonTop;
    if(m_u16CurrentHorizonIterLevelY<l_u16NextHorizonIterLevelY){
      l_u16HorizonBottom = m_u16CurrentHorizonIterLevelY;
      l_u16HorizonTop = l_u16NextHorizonIterLevelY;
      l_u16CurrentColor = m_u16GroundColor;
    }
    else{
      l_u16HorizonBottom = l_u16NextHorizonIterLevelY;
      l_u16HorizonTop = m_u16CurrentHorizonIterLevelY;
      l_u16CurrentColor = m_u16SkyColor;
    }

    LCDDrawCompleteHorizontalRect(l_u16HorizonBottom,l_u16HorizonTop, l_u16CurrentColor);
    m_u16CurrentHorizonIterLevelY = l_u16NextHorizonIterLevelY;
}

void LcdDrawTask::UpdateDrawIteration(uint16_t i_u16CurrentIterationDeltaY)
{
    uint16_t l_u16NextHorizonIterLevelY;
    uint16_t l_u16CurrentColor;
    uint16_t l_u16HorizonBottom;
    uint16_t l_u16HorizonTop;

    if ((int16_t)m_u16NextHorizonLevelY-(int16_t)m_u16HorizonLevelY >= 0) {
        l_u16NextHorizonIterLevelY = m_u16CurrentHorizonIterLevelY + i_u16CurrentIterationDeltaY;
	l_u16HorizonBottom = l_u16NextHorizonIterLevelY;
	l_u16HorizonTop = m_u16CurrentHorizonIterLevelY;
	l_u16CurrentColor = m_u16GroundColor;
    }
    else {
        l_u16NextHorizonIterLevelY = m_u16CurrentHorizonIterLevelY - i_u16CurrentIterationDeltaY;
	l_u16HorizonBottom = m_u16CurrentHorizonIterLevelY;
	l_u16HorizonTop = l_u16NextHorizonIterLevelY;
	l_u16CurrentColor = m_u16SkyColor;
    }

    LCDDrawCompleteHorizontalRect(l_u16HorizonBottom,l_u16HorizonTop, l_u16CurrentColor);
    m_u16CurrentHorizonIterLevelY = l_u16NextHorizonIterLevelY;
}
<|endoftext|>


<commit_before>#ifndef ALEPH_MATH_SYMMETRIC_MATRIX_HH__
#define ALEPH_MATH_SYMMETRIC_MATRIX_HH__

#include <algorithm>
#include <stdexcept>

#include <cstddef>

namespace aleph
{

namespace math
{

/**
  @class SymmetricMatrix

  Describes a symmetric matrix of an arbitrary data type. The class is
  able to access to the data using an interface that pretends to model
  a regular matrix.

  Hence both types of queries will be valid:

      M(i,j)
      M(j,i)

  Other than that, this class aims to have a small footprint.

  @tparam T Data type stored in matrix, e.g. `double`
  @tparam I Index type for accessing the matrix. You may change this for
            small matrices in order to reduce their memory usage. Notice
            that the default values should be sufficient in most cases.
*/

template <class T, class I = std::size_t> class SymmetricMatrix
{
public:

  /** Creates an empty symmetric matrix */
  SymmetricMatrix()
  {
  }

  /** Creates symmetric matrix with a given number of rows and columns */
  SymmetricMatrix( I n )
    : _numRows( n )
    , _size( n * ( n + 1 ) / 2 )
    , _data( new T[ _size ] )
  {
    std::fill( _data, _data + _size, I(0) );
  }

  /**
    Creates a symmetric matrix as a copy of another symmetric matrix, by
    simply copying all data values. This function first allocates memory
    before clearing it, and finally fills it with a copy of the data the
    other matrix stores. Hence, this function is *not* highly-efficient.

    @param other Matrix from which to copy data
  */

  SymmetricMatrix( const SymmetricMatrix& other )
    : SymmetricMatrix( other._numRows )
  {
    std::copy( other._data, other._data + other._size, _data );
  }

  /** Destroys the symmetric matrix */
  ~SymmetricMatrix()
  {
    delete[] _data;
  }

  /** Swaps two matrices */
  void swap( SymmetricMatrix& other )
  {
    std::swap( _numRows, other._numRows );
    std::swap( _size   , other._size    );
    std::swap( _data   , other._data    );
  }

  /**
    Assigns a given symmetric matrix to the current symmetric matrix,
    taking care not to throw an error.
  */

  SymmetricMatrix& operator=( SymmetricMatrix other )
  {
    this->swap( other );
    return *this;
  }

  /**
    Provides element-wise access to the matrix and returns the element
    at the specified position. The function throws if an invalid index
    is encountered.

    @param row    Desired row for query
    @param column Desired column for query

    @returns Const reference to the desired value
  */

  const T& operator()( I row, I column ) const
  {
    if( row >= _numRows || column >= _numRows )
      throw std::out_of_range( "Index is out of range" );

    if( row > column )
      std::swap( row, column );

    auto index = row * _numRows - row * ( row + 1 ) / 2 + column;

    if( index >= _size )
      throw std::out_of_range( "Index is out of range" );
    else
      return _data[index];
  }

  T& operator()( I row, I column )
  {
    return const_cast<T&>( static_cast<const SymmetricMatrix&>( *this )( row, column ) );
  }

  /** Returns number of rows */
  I numRows() const noexcept
  {
    return _numRows;
  }

  /** Returns size of matrix */
  I size() const noexcept
  {
    return _size;
  }

  /** Checks whether the matrix is empty */
  bool empty() const noexcept
  {
    return _numRows == 0 && _size == 0 && _data == nullptr;
  }

private:

  /** Number of rows (and columns) */
  I _numRows = I(0);

  /** Total size of data storage */
  I _size = I(0);

  /** 1D data storage (for efficiency reasons) */
  T* _data = nullptr;

};

} // namespace math

} // namespace aleph

#endif
<commit_msg>Added output operator for symmetric matrices<commit_after>#ifndef ALEPH_MATH_SYMMETRIC_MATRIX_HH__
#define ALEPH_MATH_SYMMETRIC_MATRIX_HH__

#include <algorithm>
#include <iomanip>
#include <iosfwd>
#include <stdexcept>

#include <cstddef>

namespace aleph
{

namespace math
{

/**
  @class SymmetricMatrix

  Describes a symmetric matrix of an arbitrary data type. The class is
  able to access to the data using an interface that pretends to model
  a regular matrix.

  Hence both types of queries will be valid:

      M(i,j)
      M(j,i)

  Other than that, this class aims to have a small footprint.

  @tparam T Data type stored in matrix, e.g. `double`
  @tparam I Index type for accessing the matrix. You may change this for
            small matrices in order to reduce their memory usage. Notice
            that the default values should be sufficient in most cases.
*/

template <class T, class I = std::size_t> class SymmetricMatrix
{
public:

  /** Creates an empty symmetric matrix */
  SymmetricMatrix()
  {
  }

  /** Creates symmetric matrix with a given number of rows and columns */
  SymmetricMatrix( I n )
    : _numRows( n )
    , _size( n * ( n + 1 ) / 2 )
    , _data( new T[ _size ] )
  {
    std::fill( _data, _data + _size, I(0) );
  }

  /**
    Creates a symmetric matrix as a copy of another symmetric matrix, by
    simply copying all data values. This function first allocates memory
    before clearing it, and finally fills it with a copy of the data the
    other matrix stores. Hence, this function is *not* highly-efficient.

    @param other Matrix from which to copy data
  */

  SymmetricMatrix( const SymmetricMatrix& other )
    : SymmetricMatrix( other._numRows )
  {
    std::copy( other._data, other._data + other._size, _data );
  }

  /** Destroys the symmetric matrix */
  ~SymmetricMatrix()
  {
    delete[] _data;
  }

  /** Swaps two matrices */
  void swap( SymmetricMatrix& other )
  {
    std::swap( _numRows, other._numRows );
    std::swap( _size   , other._size    );
    std::swap( _data   , other._data    );
  }

  /**
    Assigns a given symmetric matrix to the current symmetric matrix,
    taking care not to throw an error.
  */

  SymmetricMatrix& operator=( SymmetricMatrix other )
  {
    this->swap( other );
    return *this;
  }

  /**
    Provides element-wise access to the matrix and returns the element
    at the specified position. The function throws if an invalid index
    is encountered.

    @param row    Desired row for query
    @param column Desired column for query

    @returns Const reference to the desired value
  */

  const T& operator()( I row, I column ) const
  {
    if( row >= _numRows || column >= _numRows )
      throw std::out_of_range( "Index is out of range" );

    if( row > column )
      std::swap( row, column );

    auto index = row * _numRows - row * ( row + 1 ) / 2 + column;

    if( index >= _size )
      throw std::out_of_range( "Index is out of range" );
    else
      return _data[index];
  }

  T& operator()( I row, I column )
  {
    return const_cast<T&>( static_cast<const SymmetricMatrix&>( *this )( row, column ) );
  }

  /** Returns number of rows */
  I numRows() const noexcept
  {
    return _numRows;
  }

  /** Returns size of matrix */
  I size() const noexcept
  {
    return _size;
  }

  /** Checks whether the matrix is empty */
  bool empty() const noexcept
  {
    return _numRows == 0 && _size == 0 && _data == nullptr;
  }

private:

  /** Number of rows (and columns) */
  I _numRows = I(0);

  /** Total size of data storage */
  I _size = I(0);

  /** 1D data storage (for efficiency reasons) */
  T* _data = nullptr;

};

} // namespace math

} // namespace aleph

/**
  Output operator for pretty-printing symmetric matrices. This is most
  useful for debugging. The function takes care of formatting but will
  not modify the flags of the output stream permanently.

  @param o Output stream
  @param M Input matrix

  @returns Modified output stream
*/

template <class T> std::ostream& operator<<( std::ostream& o, const aleph::math::SymmetricMatrix<T>& M )
{
  auto flags( o.flags() );

  auto n = M.numRows();

  o << std::setfill( ' ' );

  for( decltype(n) i = 0; i < n; i++ )
  {
    for( decltype(n) j = 0; j < n; j++ )
    {
      if( j != 0 )
        o << ", ";

      o << std::setw( 10 ) << std::right << M(i,j);
    }

    o << "\n";
  }

  o.flags( flags );
  return o;
}

#endif
<|endoftext|>


<commit_before>// Copyright (c) 2010 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 "base/basictypes.h"
#include "chrome/browser/autofill/autofill_common_unittest.h"
#include "chrome/browser/autofill/credit_card.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {

// Tests credit card summary string generation.  This test simulates a variety
// of different possible summary strings.  Variations occur based on the
// existence of credit card number, month, and year fields.
TEST(CreditCardTest, PreviewSummaryAndObfuscatedNumberStrings) {
  // Case 0: empty credit card.
  CreditCard credit_card0(string16(), 0);
  string16 summary0 = credit_card0.PreviewSummary();
  EXPECT_EQ(summary0, string16());
  string16 obfuscated0 = credit_card0.ObfuscatedNumber();
  EXPECT_EQ(obfuscated0, string16());

  // Case 00: Empty credit card with empty strings.
  CreditCard credit_card00(string16(), 0);
  autofill_unittest::SetCreditCardInfo(&credit_card00, "Corporate",
      "John Dillinger", "Visa", "", "", "", "Chicago");
  string16 summary00 = credit_card00.PreviewSummary();
  EXPECT_EQ(summary00, string16());
  string16 obfuscated00 = credit_card00.ObfuscatedNumber();
  EXPECT_EQ(obfuscated00, string16());

  // Case 1: No credit card number.
  CreditCard credit_card1(string16(), 0);
  autofill_unittest::SetCreditCardInfo(&credit_card1, "Corporate",
      "John Dillinger", "Visa", "", "01", "2010", "Chicago");
  string16 summary1 = credit_card1.PreviewSummary();
  EXPECT_EQ(summary1, string16());
  string16 obfuscated1 = credit_card1.ObfuscatedNumber();
  EXPECT_EQ(obfuscated1, string16());

  // Case 2: No month.
  CreditCard credit_card2(string16(), 0);
  autofill_unittest::SetCreditCardInfo(&credit_card2, "Corporate",
      "John Dillinger", "Visa", "123456789012", "", "2010", "Chicago");
  string16 summary2 = credit_card2.PreviewSummary();
  EXPECT_EQ(summary2, string16(ASCIIToUTF16("************9012")));
  string16 obfuscated2 = credit_card2.ObfuscatedNumber();
  EXPECT_EQ(obfuscated2, string16(ASCIIToUTF16("************9012")));

  // Case 3: No year.
  CreditCard credit_card3(string16(), 0);
  autofill_unittest::SetCreditCardInfo(&credit_card3, "Corporate",
      "John Dillinger", "Visa", "123456789012", "01", "", "Chicago");
  string16 summary3 = credit_card3.PreviewSummary();
  EXPECT_EQ(summary3, string16(ASCIIToUTF16("************9012")));
  string16 obfuscated3 = credit_card3.ObfuscatedNumber();
  EXPECT_EQ(obfuscated3, string16(ASCIIToUTF16("************9012")));

  // Case 4: Have everything.
  CreditCard credit_card4(string16(), 0);
  autofill_unittest::SetCreditCardInfo(&credit_card4, "Corporate",
      "John Dillinger", "Visa", "123456789012", "01", "2010", "Chicago");
  string16 summary4 = credit_card4.PreviewSummary();
  EXPECT_EQ(summary4, string16(ASCIIToUTF16("************9012, Exp: 01/2010")));
  string16 obfuscated4 = credit_card4.ObfuscatedNumber();
  EXPECT_EQ(obfuscated4, string16(ASCIIToUTF16("************9012")));
}

}  // namespace

<commit_msg>I reversed the order of the EXPECT_EQ tests so expected value is first, actual value is second.<commit_after>// Copyright (c) 2010 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 "base/basictypes.h"
#include "chrome/browser/autofill/autofill_common_unittest.h"
#include "chrome/browser/autofill/credit_card.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {

// Tests credit card summary string generation.  This test simulates a variety
// of different possible summary strings.  Variations occur based on the
// existence of credit card number, month, and year fields.
TEST(CreditCardTest, PreviewSummaryAndObfuscatedNumberStrings) {
  // Case 0: empty credit card.
  CreditCard credit_card0(string16(), 0);
  string16 summary0 = credit_card0.PreviewSummary();
  EXPECT_EQ(string16(), summary0);
  string16 obfuscated0 = credit_card0.ObfuscatedNumber();
  EXPECT_EQ(string16(), obfuscated0);

  // Case 00: Empty credit card with empty strings.
  CreditCard credit_card00(string16(), 0);
  autofill_unittest::SetCreditCardInfo(&credit_card00, "Corporate",
      "John Dillinger", "Visa", "", "", "", "Chicago");
  string16 summary00 = credit_card00.PreviewSummary();
  EXPECT_EQ(string16(), summary00);
  string16 obfuscated00 = credit_card00.ObfuscatedNumber();
  EXPECT_EQ(string16(), obfuscated00);

  // Case 1: No credit card number.
  CreditCard credit_card1(string16(), 0);
  autofill_unittest::SetCreditCardInfo(&credit_card1, "Corporate",
      "John Dillinger", "Visa", "", "01", "2010", "Chicago");
  string16 summary1 = credit_card1.PreviewSummary();
  EXPECT_EQ(string16(), summary1);
  string16 obfuscated1 = credit_card1.ObfuscatedNumber();
  EXPECT_EQ(string16(), obfuscated1);

  // Case 2: No month.
  CreditCard credit_card2(string16(), 0);
  autofill_unittest::SetCreditCardInfo(&credit_card2, "Corporate",
      "John Dillinger", "Visa", "123456789012", "", "2010", "Chicago");
  string16 summary2 = credit_card2.PreviewSummary();
  EXPECT_EQ(string16(ASCIIToUTF16("************9012")), summary2);
  string16 obfuscated2 = credit_card2.ObfuscatedNumber();
  EXPECT_EQ(string16(ASCIIToUTF16("************9012")), obfuscated2);

  // Case 3: No year.
  CreditCard credit_card3(string16(), 0);
  autofill_unittest::SetCreditCardInfo(&credit_card3, "Corporate",
      "John Dillinger", "Visa", "123456789012", "01", "", "Chicago");
  string16 summary3 = credit_card3.PreviewSummary();
  EXPECT_EQ(string16(ASCIIToUTF16("************9012")), summary3);
  string16 obfuscated3 = credit_card3.ObfuscatedNumber();
  EXPECT_EQ(string16(ASCIIToUTF16("************9012")), obfuscated3);

  // Case 4: Have everything.
  CreditCard credit_card4(string16(), 0);
  autofill_unittest::SetCreditCardInfo(&credit_card4, "Corporate",
      "John Dillinger", "Visa", "123456789012", "01", "2010", "Chicago");
  string16 summary4 = credit_card4.PreviewSummary();
  EXPECT_EQ(string16(ASCIIToUTF16("************9012, Exp: 01/2010")), summary4);
  string16 obfuscated4 = credit_card4.ObfuscatedNumber();
  EXPECT_EQ(string16(ASCIIToUTF16("************9012")), obfuscated4);
}

}  // namespace

<|endoftext|>