<commit_before>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef _DOCUMENT_HXX
#define _DOCUMENT_HXX

#include <list>
#include <set>
#include <sal/types.h>
#include <cppuhelper/implbase6.hxx>
#include <com/sun/star/uno/Reference.h>
#include <com/sun/star/uno/Exception.hpp>
#include <com/sun/star/beans/StringPair.hpp>
#include <com/sun/star/xml/dom/XNode.hpp>
#include <com/sun/star/xml/dom/XAttr.hpp>
#include <com/sun/star/xml/dom/XElement.hpp>
#include <com/sun/star/xml/dom/XDOMImplementation.hpp>
#include <com/sun/star/xml/dom/events/XDocumentEvent.hpp>
#include <com/sun/star/xml/dom/events/XEvent.hpp>
#include <com/sun/star/xml/sax/XSAXSerializable.hpp>
#include <com/sun/star/xml/sax/XFastSAXSerializable.hpp>
#include <com/sun/star/xml/sax/XDocumentHandler.hpp>
#include <com/sun/star/xml/sax/XFastDocumentHandler.hpp>
#include <com/sun/star/io/XActiveDataSource.hpp>
#include <com/sun/star/io/XActiveDataControl.hpp>
#include <com/sun/star/io/XOutputStream.hpp>
#include <com/sun/star/io/XStreamListener.hpp>

#include "node.hxx"

#include <libxml/tree.h>

using namespace std;
using ::rtl::OUString;
using namespace com::sun::star;
using namespace com::sun::star::uno;
using namespace com::sun::star::lang;
using namespace com::sun::star::xml::sax;
using namespace com::sun::star::io;
using namespace com::sun::star::xml::dom;
using namespace com::sun::star::xml::dom::events;

namespace DOM
{

    class CDocument : public cppu::ImplInheritanceHelper6<
        CNode, XDocument, XDocumentEvent,
        XActiveDataControl, XActiveDataSource, XSAXSerializable, XFastSAXSerializable>
    {
        friend class CNode;
        typedef std::list< Reference< XNode >* > nodereflist_t;
        typedef set< Reference< XStreamListener > > listenerlist_t;
    private:

        xmlDocPtr m_aDocPtr;

        // datacontrol/source state
        listenerlist_t m_streamListeners;
        Reference< XOutputStream > m_rOutputStream;

    protected:
        CDocument(xmlDocPtr aDocPtr);

    public:

        virtual ~CDocument();

        virtual void SAL_CALL saxify(
            const Reference< XDocumentHandler >& i_xHandler);

        virtual void SAL_CALL fastSaxify( Context& rContext );

        /**
        Creates an Attr of the given name.
        */
        virtual Reference< XAttr > SAL_CALL createAttribute(const OUString& name)
            throw (RuntimeException, DOMException);

        /**
        Creates an attribute of the given qualified name and namespace URI.
        */
        virtual Reference< XAttr > SAL_CALL createAttributeNS(const OUString& namespaceURI, const OUString& qualifiedName)
            throw (RuntimeException, DOMException);

        /**
        Creates a CDATASection node whose value is the specified string.
        */
        virtual Reference< XCDATASection > SAL_CALL createCDATASection(const OUString& data)
            throw (RuntimeException);

        /**
        Creates a Comment node given the specified string.
        */
        virtual Reference< XComment > SAL_CALL createComment(const OUString& data)
            throw (RuntimeException);

        /**
        Creates an empty DocumentFragment object.
        */
        virtual Reference< XDocumentFragment > SAL_CALL createDocumentFragment()
            throw (RuntimeException);

        /**
        Creates an element of the type specified.
        */
        virtual Reference< XElement > SAL_CALL createElement(const OUString& tagName)
            throw (RuntimeException, DOMException);

        /**
        Creates an element of the given qualified name and namespace URI.
        */
        virtual Reference< XElement > SAL_CALL createElementNS(const OUString& namespaceURI, const OUString& qualifiedName)
            throw (RuntimeException, DOMException);

        /**
        Creates an EntityReference object.
        */
        virtual Reference< XEntityReference > SAL_CALL createEntityReference(const OUString& name)
            throw (RuntimeException, DOMException);

        /**
        Creates a ProcessingInstruction node given the specified name and
        data strings.
        */
        virtual Reference< XProcessingInstruction > SAL_CALL createProcessingInstruction(
                const OUString& target, const OUString& data)
            throw (RuntimeException, DOMException);

        /**
        Creates a Text node given the specified string.
        */
        virtual Reference< XText > SAL_CALL createTextNode(const OUString& data)
            throw (RuntimeException);

        /**
        The Document Type Declaration (see DocumentType) associated with this
        document.
        */
        virtual Reference< XDocumentType > SAL_CALL getDoctype()
            throw (RuntimeException);

        /**
        This is a convenience attribute that allows direct access to the child
        node that is the root element of the document.
        */
        virtual Reference< XElement > SAL_CALL getDocumentElement()
            throw (RuntimeException);

        /**
        Returns the Element whose ID is given by elementId.
        */
        virtual Reference< XElement > SAL_CALL getElementById(const OUString& elementId)
            throw (RuntimeException);

        /**
        Returns a NodeList of all the Elements with a given tag name in the
        order in which they are encountered in a preorder traversal of the
        Document tree.
        */
        virtual Reference< XNodeList > SAL_CALL getElementsByTagName(const OUString& tagname)
            throw (RuntimeException);

        /**
        Returns a NodeList of all the Elements with a given local name and
        namespace URI in the order in which they are encountered in a preorder
        traversal of the Document tree.
        */
        virtual Reference< XNodeList > SAL_CALL getElementsByTagNameNS(const OUString& namespaceURI, const OUString& localName)
            throw (RuntimeException);

        /**
        The DOMImplementation object that handles this document.
        */
        virtual Reference< XDOMImplementation > SAL_CALL getImplementation()
            throw (RuntimeException);

        /**
        Imports a node from another document to this document.
        */
        virtual Reference< XNode > SAL_CALL importNode(const Reference< XNode >& importedNode, sal_Bool deep)
            throw (RuntimeException, DOMException);

        // XDocumentEvent
        virtual Reference< XEvent > SAL_CALL createEvent(const OUString& eventType) throw (RuntimeException);

        // XActiveDataControl,
        // see http://api.openoffice.org/docs/common/ref/com/sun/star/io/XActiveDataControl.html
        virtual void SAL_CALL addListener(const Reference< XStreamListener >& aListener )  throw (RuntimeException);
        virtual void SAL_CALL removeListener(const Reference< XStreamListener >& aListener ) throw (RuntimeException);
        virtual void SAL_CALL start() throw (RuntimeException);
        virtual void SAL_CALL terminate() throw (RuntimeException);

        // XActiveDataSource
        // see http://api.openoffice.org/docs/common/ref/com/sun/star/io/XActiveDataSource.html
        virtual void SAL_CALL setOutputStream(  const Reference< XOutputStream >& aStream ) throw (RuntimeException);
        virtual Reference< XOutputStream > SAL_CALL getOutputStream() throw (RuntimeException);

        // ---- resolve uno inheritance problems...
        // overrides for XNode base
        virtual OUString SAL_CALL getNodeName()
            throw (RuntimeException);
        virtual OUString SAL_CALL getNodeValue()
            throw (RuntimeException);
        // --- delegation for XNde base.
        virtual Reference< XNode > SAL_CALL appendChild(const Reference< XNode >& newChild)
            throw (RuntimeException, DOMException)
        {
            return CNode::appendChild(newChild);
        }
        virtual Reference< XNode > SAL_CALL cloneNode(sal_Bool deep)
            throw (RuntimeException)
        {
            return CNode::cloneNode(deep);
        }
        virtual Reference< XNamedNodeMap > SAL_CALL getAttributes()
            throw (RuntimeException)
        {
            return CNode::getAttributes();
        }
        virtual Reference< XNodeList > SAL_CALL getChildNodes()
            throw (RuntimeException)
        {
            return CNode::getChildNodes();
        }
        virtual Reference< XNode > SAL_CALL getFirstChild()
            throw (RuntimeException)
        {
            return CNode::getFirstChild();
        }
        virtual Reference< XNode > SAL_CALL getLastChild()
            throw (RuntimeException)
        {
            return CNode::getLastChild();
        }
        virtual OUString SAL_CALL getLocalName()
            throw (RuntimeException)
        {
            return CNode::getLocalName();
        }
        virtual OUString SAL_CALL getNamespaceURI()
            throw (RuntimeException)
        {
            return CNode::getNamespaceURI();
        }
        virtual Reference< XNode > SAL_CALL getNextSibling()
            throw (RuntimeException)
        {
            return CNode::getNextSibling();
        }
        virtual NodeType SAL_CALL getNodeType()
            throw (RuntimeException)
        {
            return CNode::getNodeType();
        }
        virtual Reference< XDocument > SAL_CALL getOwnerDocument()
            throw (RuntimeException)
        {
            return CNode::getOwnerDocument();
        }
        virtual Reference< XNode > SAL_CALL getParentNode()
            throw (RuntimeException)
        {
            return CNode::getParentNode();
        }
        virtual OUString SAL_CALL getPrefix()
            throw (RuntimeException)
        {
           return CNode::getPrefix();
        }
        virtual Reference< XNode > SAL_CALL getPreviousSibling()
            throw (RuntimeException)
        {
            return CNode::getPreviousSibling();
        }
        virtual sal_Bool SAL_CALL hasAttributes()
            throw (RuntimeException)
        {
            return CNode::hasAttributes();
        }
        virtual sal_Bool SAL_CALL hasChildNodes()
            throw (RuntimeException)
        {
            return CNode::hasChildNodes();
        }
        virtual Reference< XNode > SAL_CALL insertBefore(
                const Reference< XNode >& newChild, const Reference< XNode >& refChild)
            throw (DOMException)
        {
            return CNode::insertBefore(newChild, refChild);
        }
        virtual sal_Bool SAL_CALL isSupported(const OUString& feature, const OUString& ver)
            throw (RuntimeException)
        {
            return CNode::isSupported(feature, ver);
        }
        virtual void SAL_CALL normalize()
            throw (RuntimeException)
        {
            CNode::normalize();
        }
        virtual Reference< XNode > SAL_CALL removeChild(const Reference< XNode >& oldChild)
            throw (RuntimeException, DOMException)
        {
            return CNode::removeChild(oldChild);
        }
        virtual Reference< XNode > SAL_CALL replaceChild(
                const Reference< XNode >& newChild, const Reference< XNode >& oldChild)
            throw (RuntimeException, DOMException)
        {
            return CNode::replaceChild(newChild, oldChild);
        }
        virtual void SAL_CALL setNodeValue(const OUString& nodeValue)
            throw (RuntimeException, DOMException)
        {
            return CNode::setNodeValue(nodeValue);
        }
        virtual void SAL_CALL setPrefix(const OUString& prefix)
            throw (RuntimeException, DOMException)
        {
            return CNode::setPrefix(prefix);
        }

        // ::com::sun::star::xml::sax::XSAXSerializable
        virtual void SAL_CALL serialize(
            const Reference< XDocumentHandler >& i_xHandler,
            const Sequence< beans::StringPair >& i_rNamespaces)
            throw (RuntimeException, SAXException);

        // ::com::sun::star::xml::sax::XFastSAXSerializable
        virtual void SAL_CALL fastSerialize( const Reference< XFastDocumentHandler >& handler,
                                             const Reference< XFastTokenHandler >& tokenHandler,
                                             const Sequence< beans::StringPair >& i_rNamespaces,
                                             const Sequence< beans::Pair< rtl::OUString, sal_Int32 > >& namespaces )
            throw (SAXException, RuntimeException);
    };
}

#endif
<commit_msg>sw34bf01: #i112783#: unoxml: remove DOM::CDocument::nodereflist_t<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef _DOCUMENT_HXX
#define _DOCUMENT_HXX

#include <list>
#include <set>
#include <sal/types.h>
#include <cppuhelper/implbase6.hxx>
#include <com/sun/star/uno/Reference.h>
#include <com/sun/star/uno/Exception.hpp>
#include <com/sun/star/beans/StringPair.hpp>
#include <com/sun/star/xml/dom/XNode.hpp>
#include <com/sun/star/xml/dom/XAttr.hpp>
#include <com/sun/star/xml/dom/XElement.hpp>
#include <com/sun/star/xml/dom/XDOMImplementation.hpp>
#include <com/sun/star/xml/dom/events/XDocumentEvent.hpp>
#include <com/sun/star/xml/dom/events/XEvent.hpp>
#include <com/sun/star/xml/sax/XSAXSerializable.hpp>
#include <com/sun/star/xml/sax/XFastSAXSerializable.hpp>
#include <com/sun/star/xml/sax/XDocumentHandler.hpp>
#include <com/sun/star/xml/sax/XFastDocumentHandler.hpp>
#include <com/sun/star/io/XActiveDataSource.hpp>
#include <com/sun/star/io/XActiveDataControl.hpp>
#include <com/sun/star/io/XOutputStream.hpp>
#include <com/sun/star/io/XStreamListener.hpp>

#include "node.hxx"

#include <libxml/tree.h>

using namespace std;
using ::rtl::OUString;
using namespace com::sun::star;
using namespace com::sun::star::uno;
using namespace com::sun::star::lang;
using namespace com::sun::star::xml::sax;
using namespace com::sun::star::io;
using namespace com::sun::star::xml::dom;
using namespace com::sun::star::xml::dom::events;

namespace DOM
{

    class CDocument : public cppu::ImplInheritanceHelper6<
        CNode, XDocument, XDocumentEvent,
        XActiveDataControl, XActiveDataSource, XSAXSerializable, XFastSAXSerializable>
    {
        friend class CNode;
        typedef set< Reference< XStreamListener > > listenerlist_t;
    private:

        xmlDocPtr m_aDocPtr;

        // datacontrol/source state
        listenerlist_t m_streamListeners;
        Reference< XOutputStream > m_rOutputStream;

    protected:
        CDocument(xmlDocPtr aDocPtr);

    public:

        virtual ~CDocument();

        virtual void SAL_CALL saxify(
            const Reference< XDocumentHandler >& i_xHandler);

        virtual void SAL_CALL fastSaxify( Context& rContext );

        /**
        Creates an Attr of the given name.
        */
        virtual Reference< XAttr > SAL_CALL createAttribute(const OUString& name)
            throw (RuntimeException, DOMException);

        /**
        Creates an attribute of the given qualified name and namespace URI.
        */
        virtual Reference< XAttr > SAL_CALL createAttributeNS(const OUString& namespaceURI, const OUString& qualifiedName)
            throw (RuntimeException, DOMException);

        /**
        Creates a CDATASection node whose value is the specified string.
        */
        virtual Reference< XCDATASection > SAL_CALL createCDATASection(const OUString& data)
            throw (RuntimeException);

        /**
        Creates a Comment node given the specified string.
        */
        virtual Reference< XComment > SAL_CALL createComment(const OUString& data)
            throw (RuntimeException);

        /**
        Creates an empty DocumentFragment object.
        */
        virtual Reference< XDocumentFragment > SAL_CALL createDocumentFragment()
            throw (RuntimeException);

        /**
        Creates an element of the type specified.
        */
        virtual Reference< XElement > SAL_CALL createElement(const OUString& tagName)
            throw (RuntimeException, DOMException);

        /**
        Creates an element of the given qualified name and namespace URI.
        */
        virtual Reference< XElement > SAL_CALL createElementNS(const OUString& namespaceURI, const OUString& qualifiedName)
            throw (RuntimeException, DOMException);

        /**
        Creates an EntityReference object.
        */
        virtual Reference< XEntityReference > SAL_CALL createEntityReference(const OUString& name)
            throw (RuntimeException, DOMException);

        /**
        Creates a ProcessingInstruction node given the specified name and
        data strings.
        */
        virtual Reference< XProcessingInstruction > SAL_CALL createProcessingInstruction(
                const OUString& target, const OUString& data)
            throw (RuntimeException, DOMException);

        /**
        Creates a Text node given the specified string.
        */
        virtual Reference< XText > SAL_CALL createTextNode(const OUString& data)
            throw (RuntimeException);

        /**
        The Document Type Declaration (see DocumentType) associated with this
        document.
        */
        virtual Reference< XDocumentType > SAL_CALL getDoctype()
            throw (RuntimeException);

        /**
        This is a convenience attribute that allows direct access to the child
        node that is the root element of the document.
        */
        virtual Reference< XElement > SAL_CALL getDocumentElement()
            throw (RuntimeException);

        /**
        Returns the Element whose ID is given by elementId.
        */
        virtual Reference< XElement > SAL_CALL getElementById(const OUString& elementId)
            throw (RuntimeException);

        /**
        Returns a NodeList of all the Elements with a given tag name in the
        order in which they are encountered in a preorder traversal of the
        Document tree.
        */
        virtual Reference< XNodeList > SAL_CALL getElementsByTagName(const OUString& tagname)
            throw (RuntimeException);

        /**
        Returns a NodeList of all the Elements with a given local name and
        namespace URI in the order in which they are encountered in a preorder
        traversal of the Document tree.
        */
        virtual Reference< XNodeList > SAL_CALL getElementsByTagNameNS(const OUString& namespaceURI, const OUString& localName)
            throw (RuntimeException);

        /**
        The DOMImplementation object that handles this document.
        */
        virtual Reference< XDOMImplementation > SAL_CALL getImplementation()
            throw (RuntimeException);

        /**
        Imports a node from another document to this document.
        */
        virtual Reference< XNode > SAL_CALL importNode(const Reference< XNode >& importedNode, sal_Bool deep)
            throw (RuntimeException, DOMException);

        // XDocumentEvent
        virtual Reference< XEvent > SAL_CALL createEvent(const OUString& eventType) throw (RuntimeException);

        // XActiveDataControl,
        // see http://api.openoffice.org/docs/common/ref/com/sun/star/io/XActiveDataControl.html
        virtual void SAL_CALL addListener(const Reference< XStreamListener >& aListener )  throw (RuntimeException);
        virtual void SAL_CALL removeListener(const Reference< XStreamListener >& aListener ) throw (RuntimeException);
        virtual void SAL_CALL start() throw (RuntimeException);
        virtual void SAL_CALL terminate() throw (RuntimeException);

        // XActiveDataSource
        // see http://api.openoffice.org/docs/common/ref/com/sun/star/io/XActiveDataSource.html
        virtual void SAL_CALL setOutputStream(  const Reference< XOutputStream >& aStream ) throw (RuntimeException);
        virtual Reference< XOutputStream > SAL_CALL getOutputStream() throw (RuntimeException);

        // ---- resolve uno inheritance problems...
        // overrides for XNode base
        virtual OUString SAL_CALL getNodeName()
            throw (RuntimeException);
        virtual OUString SAL_CALL getNodeValue()
            throw (RuntimeException);
        // --- delegation for XNde base.
        virtual Reference< XNode > SAL_CALL appendChild(const Reference< XNode >& newChild)
            throw (RuntimeException, DOMException)
        {
            return CNode::appendChild(newChild);
        }
        virtual Reference< XNode > SAL_CALL cloneNode(sal_Bool deep)
            throw (RuntimeException)
        {
            return CNode::cloneNode(deep);
        }
        virtual Reference< XNamedNodeMap > SAL_CALL getAttributes()
            throw (RuntimeException)
        {
            return CNode::getAttributes();
        }
        virtual Reference< XNodeList > SAL_CALL getChildNodes()
            throw (RuntimeException)
        {
            return CNode::getChildNodes();
        }
        virtual Reference< XNode > SAL_CALL getFirstChild()
            throw (RuntimeException)
        {
            return CNode::getFirstChild();
        }
        virtual Reference< XNode > SAL_CALL getLastChild()
            throw (RuntimeException)
        {
            return CNode::getLastChild();
        }
        virtual OUString SAL_CALL getLocalName()
            throw (RuntimeException)
        {
            return CNode::getLocalName();
        }
        virtual OUString SAL_CALL getNamespaceURI()
            throw (RuntimeException)
        {
            return CNode::getNamespaceURI();
        }
        virtual Reference< XNode > SAL_CALL getNextSibling()
            throw (RuntimeException)
        {
            return CNode::getNextSibling();
        }
        virtual NodeType SAL_CALL getNodeType()
            throw (RuntimeException)
        {
            return CNode::getNodeType();
        }
        virtual Reference< XDocument > SAL_CALL getOwnerDocument()
            throw (RuntimeException)
        {
            return CNode::getOwnerDocument();
        }
        virtual Reference< XNode > SAL_CALL getParentNode()
            throw (RuntimeException)
        {
            return CNode::getParentNode();
        }
        virtual OUString SAL_CALL getPrefix()
            throw (RuntimeException)
        {
           return CNode::getPrefix();
        }
        virtual Reference< XNode > SAL_CALL getPreviousSibling()
            throw (RuntimeException)
        {
            return CNode::getPreviousSibling();
        }
        virtual sal_Bool SAL_CALL hasAttributes()
            throw (RuntimeException)
        {
            return CNode::hasAttributes();
        }
        virtual sal_Bool SAL_CALL hasChildNodes()
            throw (RuntimeException)
        {
            return CNode::hasChildNodes();
        }
        virtual Reference< XNode > SAL_CALL insertBefore(
                const Reference< XNode >& newChild, const Reference< XNode >& refChild)
            throw (DOMException)
        {
            return CNode::insertBefore(newChild, refChild);
        }
        virtual sal_Bool SAL_CALL isSupported(const OUString& feature, const OUString& ver)
            throw (RuntimeException)
        {
            return CNode::isSupported(feature, ver);
        }
        virtual void SAL_CALL normalize()
            throw (RuntimeException)
        {
            CNode::normalize();
        }
        virtual Reference< XNode > SAL_CALL removeChild(const Reference< XNode >& oldChild)
            throw (RuntimeException, DOMException)
        {
            return CNode::removeChild(oldChild);
        }
        virtual Reference< XNode > SAL_CALL replaceChild(
                const Reference< XNode >& newChild, const Reference< XNode >& oldChild)
            throw (RuntimeException, DOMException)
        {
            return CNode::replaceChild(newChild, oldChild);
        }
        virtual void SAL_CALL setNodeValue(const OUString& nodeValue)
            throw (RuntimeException, DOMException)
        {
            return CNode::setNodeValue(nodeValue);
        }
        virtual void SAL_CALL setPrefix(const OUString& prefix)
            throw (RuntimeException, DOMException)
        {
            return CNode::setPrefix(prefix);
        }

        // ::com::sun::star::xml::sax::XSAXSerializable
        virtual void SAL_CALL serialize(
            const Reference< XDocumentHandler >& i_xHandler,
            const Sequence< beans::StringPair >& i_rNamespaces)
            throw (RuntimeException, SAXException);

        // ::com::sun::star::xml::sax::XFastSAXSerializable
        virtual void SAL_CALL fastSerialize( const Reference< XFastDocumentHandler >& handler,
                                             const Reference< XFastTokenHandler >& tokenHandler,
                                             const Sequence< beans::StringPair >& i_rNamespaces,
                                             const Sequence< beans::Pair< rtl::OUString, sal_Int32 > >& namespaces )
            throw (SAXException, RuntimeException);
    };
}

#endif
<|endoftext|>


<commit_before>#include <sys/socket.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <netdb.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <termios.h>
#include <fcntl.h>
#include <errno.h>

#include <iostream>
using namespace std;

#define BAUDRATE B9600

size_t sendcommand(int fd, const char * buf, const size_t len, char * recv_buf, const size_t recv_len)
{
	const size_t write_result = write(fd, buf, len);
	if(write_result < 0)
	{
		fprintf(stderr, "%s: write(2) failed %d %s\n",  __PRETTY_FUNCTION__, errno, strerror(errno));
		return 0;
	}
	sleep(1);
	const size_t read_result = read(fd, recv_buf, recv_len);
	return read_result;
}

int main(int argc, char ** argv)
{
	char * monitor_command = NULL;
	char * init_command = NULL;
	const char * delim = ",";
	struct termios m_oldtio,m_newtio;

	if(argc < 3)
	{
		fprintf(stderr, "Usage: %s device baudrate measure_string init_string\n", argv[0]);
		fprintf(stderr, "Usage: %s device baudrate measure_string\n", argv[0]);
		fprintf(stderr, "Usage: %s device baudrate\n", argv[0]);
		return -1;
	}

	if(argc > 3)	monitor_command = argv[3];
	if(argc > 4)	init_command = argv[4];
	//const size_t monitor_command_length 	= (monitor_command == NULL ? 0 : strlen(monitor_command));
	//const size_t init_command_length 	= (init_command == NULL ? 0 : strlen(init_command));

	const size_t line_buffer_length = 256;
	int serial_port = open(argv[1], O_RDWR | O_NOCTTY);
	if(serial_port == -1)
	{
		fprintf(stderr, "%s: error in open(2): %d %s\n", __PRETTY_FUNCTION__, errno, strerror(errno));
		return -1;
	}

	tcgetattr(serial_port, &m_oldtio);
        bzero(&m_newtio, sizeof(m_newtio));
        m_newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;
        m_newtio.c_iflag = IGNPAR;
        m_newtio.c_oflag = 0;
        m_newtio.c_lflag = 0;
        m_newtio.c_cc[VTIME] = 0;
        m_newtio.c_cc[VMIN] = 1;

	tcflush(serial_port, TCIFLUSH);
	const int tcset_result = tcsetattr(serial_port, TCSANOW, &m_newtio);
	if(tcset_result < 0)
	{
		fprintf(stderr, "%s: error in tcsetattr(3): %d %s\n", __PRETTY_FUNCTION__, errno, strerror(errno));
		return -1;
	}

//	sendcommand(serial_port, init_command, init_command_length);
/*
	cout << "time_before.tv_sec" << delim << "time_before.tv_nsec" << delim << "time_after.tv_sec" << delim << "time_after.tv_nsec" << delim;
	cout << "stage1_voltage" << delim << "stage2_voltage" << delim << "stage3_voltage" << delim;
	cout << "stage1_length" << delim << "stage2_length" << delim;
	cout << "discharge_threshold_low" << delim << "discharge_threshold_high" << delim;
	cout << "year" << delim << "month" << delim << "dom" << delim << "hour" << delim << "minute" << delim << "sec" << delim;
	cout << "ah100" << delim << "ah" << delim;
	cout << "kwh100" << delim << "kwh" << endl << flush;
*/
//	while(true)
	{
		const char * command = "pc.solar.getparams";
		const size_t command_length = strlen(command);

		const char * expected_response = "solar.pc.sendparams.";
		const size_t expected_response_length = strlen(expected_response);

		const size_t response_length = 1024; //18+27;
		char response[response_length];

		struct timespec time_before, time_after;
		clock_gettime(CLOCK_REALTIME, &time_before);

		const size_t command_result = sendcommand(serial_port, command, command_length, response, response_length);

		const char * response_values = &response[expected_response_length];
		const unsigned int stage1_voltage 	= response_values[0] + 79;
		const unsigned int stage2_voltage 	= response_values[1] + 79;
		const unsigned int stage3_voltage 	= response_values[2] + 79;
		const unsigned int stage1_length	= response_values[3] - 1;
		const unsigned int stage2_length 	= response_values[4] - 1;
		const unsigned int dis_lo_thres	= response_values[5] + 79;
		const unsigned int dis_hi_thres	= response_values[6] + 79;

		const unsigned int year		= ((unsigned int)response_values[14]) + 1999;
		const unsigned int month	= ((unsigned int)response_values[15]) + 1;
		const unsigned int dom		= ((unsigned int)response_values[16]) + 1;
		const unsigned int hour		= ((unsigned int)response_values[17]) + 1;
		const unsigned int min		= ((unsigned int)response_values[18]) + 1;
		const unsigned int sec		= ((unsigned int)response_values[19]) + 1;

		const unsigned ah100		= ((unsigned int)response_values[20])-1;
		const unsigned ah		= ((unsigned int)response_values[21])-1;

		const unsigned kwh100		= ((unsigned int)response_values[22])-1;
		const unsigned kwh		= ((unsigned int)response_values[23])-1;

		const char * command_getdata = "pc.solar.getdata";
		const size_t command_getdata_length = strlen(command_getdata);

		clock_gettime(CLOCK_REALTIME, &time_after);
//		printf("%d,%d,%d,%d,%s\n", time_before.tv_sec, time_before.tv_nsec, time_after.tv_sec, time_after.tv_nsec, line_buffer);
		cout << time_before.tv_sec << delim << time_before.tv_nsec << delim << time_after.tv_sec << delim << time_after.tv_nsec << delim;
		cout << stage1_voltage << delim << stage2_voltage << delim << stage3_voltage << delim;
		cout << stage1_length << delim << stage2_length << delim;
		cout << dis_lo_thres << delim << dis_hi_thres << delim;
		cout << year << delim << month << delim << dom << delim << hour << delim << min << delim << sec << delim;
		cout << ah100 << delim << ah << delim;
		cout << kwh100 << delim << kwh;

		const char * command_getdata_expected_response = "solar.pc.senddata";
		const size_t command_getdata_expected_response_length = strlen(command_getdata_expected_response);

		const size_t command_getdata_result = sendcommand(serial_port, command_getdata, command_getdata_length, response, response_length);

		for(size_t i=command_getdata_expected_response_length; i<command_getdata_result; i++)
			cout << ((unsigned int)response[i]) << ",";

		cout << endl << flush;
//		fflush(stdout);
	}

	return 0;
};
<commit_msg>Several small fixes.<commit_after>#include <sys/socket.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <netdb.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <termios.h>
#include <fcntl.h>
#include <errno.h>

#include <iostream>
using namespace std;

#define BAUDRATE B9600

size_t sendcommand(int fd, const char * buf, const size_t len, char * recv_buf, const size_t recv_len)
{
	const size_t write_result = write(fd, buf, len);
	if(write_result < 0)
	{
		fprintf(stderr, "%s: write(2) failed %d %s\n",  __PRETTY_FUNCTION__, errno, strerror(errno));
		return 0;
	}
	sleep(1);
	const size_t read_result = read(fd, recv_buf, recv_len);
	return read_result;
}

int main(int argc, char ** argv)
{
	const char * delim = ",";
	struct termios m_oldtio,m_newtio;

	if(argc < 3)
	{
		fprintf(stderr, "Usage: %s device baudrate\n", argv[0]);
		return -1;
	}

	const int serial_port = open(argv[1], O_RDWR | O_NOCTTY);
	if(serial_port == -1)
	{
		fprintf(stderr, "%s: error in open(2): %d %s\n", __PRETTY_FUNCTION__, errno, strerror(errno));
		return -1;
	}

	tcgetattr(serial_port, &m_oldtio);
        bzero(&m_newtio, sizeof(m_newtio));
        m_newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;
        m_newtio.c_iflag = IGNPAR;
        m_newtio.c_oflag = 0;
        m_newtio.c_lflag = 0;
        m_newtio.c_cc[VTIME] = 0;
        m_newtio.c_cc[VMIN] = 1;

	tcflush(serial_port, TCIFLUSH);
	const int tcset_result = tcsetattr(serial_port, TCSANOW, &m_newtio);
	if(tcset_result < 0)
	{
		fprintf(stderr, "%s: error in tcsetattr(3): %d %s\n", __PRETTY_FUNCTION__, errno, strerror(errno));
		return -1;
	}

//	sendcommand(serial_port, init_command, init_command_length);
/*
	cout << "time_before.tv_sec" << delim << "time_before.tv_nsec" << delim << "time_after.tv_sec" << delim << "time_after.tv_nsec" << delim;
	cout << "stage1_voltage" << delim << "stage2_voltage" << delim << "stage3_voltage" << delim;
	cout << "stage1_length" << delim << "stage2_length" << delim;
	cout << "discharge_threshold_low" << delim << "discharge_threshold_high" << delim;
	cout << "year" << delim << "month" << delim << "dom" << delim << "hour" << delim << "minute" << delim << "sec" << delim;
	cout << "ah100" << delim << "ah" << delim;
	cout << "kwh100" << delim << "kwh" << endl << flush;
*/
//	while(true)
	{
		const char * command = "pc.solar.getparams";
		const size_t command_length = strlen(command);

		const char * expected_response = "solar.pc.sendparams.";
		const size_t expected_response_length = strlen(expected_response);

		const size_t response_length = 1024; //18+27;
		char response[response_length];

		struct timespec time_before, time_after;
		clock_gettime(CLOCK_REALTIME, &time_before);

		const size_t command_result = sendcommand(serial_port, command, command_length, response, response_length);
		if(command_result < 1)
			return -1;

		const char * response_values = &response[expected_response_length];
		const unsigned int stage1_voltage 	= response_values[0] + 79;
		const unsigned int stage2_voltage 	= response_values[1] + 79;
		const unsigned int stage3_voltage 	= response_values[2] + 79;
		const unsigned int stage1_length	= response_values[3] - 1;
		const unsigned int stage2_length 	= response_values[4] - 1;
		const unsigned int dis_lo_thres	= response_values[5] + 79;
		const unsigned int dis_hi_thres	= response_values[6] + 79;

		const unsigned int year		= ((unsigned int)response_values[14]) + 1999;
		const unsigned int month	= ((unsigned int)response_values[15]) + 1;
		const unsigned int dom		= ((unsigned int)response_values[16]) + 1;
		const unsigned int hour		= ((unsigned int)response_values[17]) + 1;
		const unsigned int min		= ((unsigned int)response_values[18]) + 1;
		const unsigned int sec		= ((unsigned int)response_values[19]) + 1;

		const unsigned ah100		= ((unsigned int)response_values[20])-1;
		const unsigned ah		= ((unsigned int)response_values[21])-1;

		const unsigned kwh100		= ((unsigned int)response_values[22])-1;
		const unsigned kwh		= ((unsigned int)response_values[23])-1;

		const char * command_getdata = "pc.solar.getdata";
		const size_t command_getdata_length = strlen(command_getdata);

		clock_gettime(CLOCK_REALTIME, &time_after);
//		printf("%d,%d,%d,%d,%s\n", time_before.tv_sec, time_before.tv_nsec, time_after.tv_sec, time_after.tv_nsec, line_buffer);
		cout << time_before.tv_sec << delim << time_before.tv_nsec << delim << time_after.tv_sec << delim << time_after.tv_nsec << delim;
		cout << stage1_voltage << delim << stage2_voltage << delim << stage3_voltage << delim;
		cout << stage1_length << delim << stage2_length << delim;
		cout << dis_lo_thres << delim << dis_hi_thres << delim;
		cout << year << delim << month << delim << dom << delim << hour << delim << min << delim << sec << delim;
		cout << ah100 << delim << ah << delim;
		cout << kwh100 << delim << kwh;

		const char * command_getdata_expected_response = "solar.pc.senddata";
		const size_t command_getdata_expected_response_length = strlen(command_getdata_expected_response);

		const size_t command_getdata_result = sendcommand(serial_port, command_getdata, command_getdata_length, response, response_length);
		if(command_getdata_result > 0)
		{
			for(size_t i=command_getdata_expected_response_length; i<command_getdata_result; i++)
				cout << ((unsigned int)response[i]) << ",";
		}

		cout << endl << flush;
//		fflush(stdout);
	}

	return 0;
};
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/memory/p9_mss_eff_config_thermal.C $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

///
/// @file p9_mss_eff_config_thermal.C
/// @brief Perform thermal calculations as part of the effective configuration
///
// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
// *HWP HWP Backup: Brian Silver <bsilver@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 1
// *HWP Consumed by: FSP:HB

#include <fapi2.H>
#include "p9_mss_eff_config_thermal.H"

///
/// @brief Perform thermal calculations as part of the effective configuration
/// @param[in] i_target the controller (e.g., MCS)
/// @return FAPI2_RC_SUCCESS iff ok
///
fapi2::ReturnCode p9_mss_eff_config_thermal( const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target )
{
    FAPI_INF("Start effective config thermal");
    FAPI_INF("End effective config thermal");
    return fapi2::FAPI2_RC_SUCCESS;
}
<commit_msg>Change procedure include paths<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/memory/p9_mss_eff_config_thermal.C $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

///
/// @file p9_mss_eff_config_thermal.C
/// @brief Perform thermal calculations as part of the effective configuration
///
// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
// *HWP HWP Backup: Brian Silver <bsilver@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 1
// *HWP Consumed by: FSP:HB

#include <fapi2.H>
#include <p9_mss_eff_config_thermal.H>

///
/// @brief Perform thermal calculations as part of the effective configuration
/// @param[in] i_target the controller (e.g., MCS)
/// @return FAPI2_RC_SUCCESS iff ok
///
fapi2::ReturnCode p9_mss_eff_config_thermal( const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target )
{
    FAPI_INF("Start effective config thermal");
    FAPI_INF("End effective config thermal");
    return fapi2::FAPI2_RC_SUCCESS;
}
<|endoftext|>


<commit_before>/*
 * rngs
 * ECE 541 Project 2
 * Kashev Dalmia - dalmia3
 * David Huang   - huang157
 */

#include "stl_rng.h"

namespace rng
{
    StlRng::StlRng() {
    }

    void StlRng::seed(int seed_num) {
        gen = std::mt19937(seed_num);
    }

    double StlRng::operator()() {
        return dist(gen);
    }
}<commit_msg>adding semantically correct constructor thing<commit_after>/*
 * rngs
 * ECE 541 Project 2
 * Kashev Dalmia - dalmia3
 * David Huang   - huang157
 */

#include "stl_rng.h"

namespace rng
{
    StlRng::StlRng() :
        RandomNumberGenerator()
    {}

    void StlRng::seed(int seed_num) {
        gen = std::mt19937(seed_num);
    }

    double StlRng::operator()() {
        return dist(gen);
    }

}<|endoftext|>


<commit_before>/** \file    TextUtil.h
 *  \brief   Declarations of text related utility functions.
 *  \author  Dr. Johannes Ruscheinski
 *  \author  Jiangtao Hu
 */

/*
 *  Copyright 2003-2009 Project iVia.
 *  Copyright 2003-2009 The Regents of The University of California.
 *  Copyright 2015 Universitätsbibliothek Tübingen.
 *
 *  This file is part of the libiViaCore package.
 *
 *  The libiViaCore package is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public License as published
 *  by the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  libiViaCore 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 libiViaCore; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "TextUtil.h"
#include <algorithm>
#include <exception>
#include <cstdio>
#include <cwctype>
#include "Compiler.h"
#include "Locale.h"
#include "HtmlParser.h"
#include "RegexMatcher.h"
#include "StringUtil.h"

namespace {

class TextExtractor: public HtmlParser {
    std::string &extracted_text_;
public:
    TextExtractor(const std::string &html, std::string * const extracted_text)
        : HtmlParser(html, HtmlParser::TEXT), extracted_text_(*extracted_text) { }
    virtual void notify(const HtmlParser::Chunk &chunk);
};

void TextExtractor::notify(const HtmlParser::Chunk &chunk) {
    if (chunk.type_ == HtmlParser::TEXT)
        extracted_text_ += chunk.text_;
}

} // unnamned namespace

namespace TextUtil {

std::string ExtractText(const std::string &html) {
    std::string extracted_text;
    TextExtractor extractor(html, &extracted_text);
    extractor.parse();

    return extracted_text;
}

bool IsRomanNumeral(const std::string &s) {
    if (s.empty())
        return false;

    std::string err_msg;
    static RegexMatcher *matcher(nullptr);
    if (unlikely(matcher == nullptr)) {
        const std::string pattern("^M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$");
        matcher = RegexMatcher::RegexMatcherFactory(pattern, &err_msg);
        if (unlikely(matcher == nullptr))
            throw std::runtime_error("Failed to construct a RegexMatcher for \"" + pattern
                                     + "\" in TextUtil::IsRomanNumeral: " + err_msg);
    }

    const bool retcode(matcher->matched(s, &err_msg));
    if (unlikely(not err_msg.empty()))
        throw std::runtime_error("Failed to match \"" + s + "\" against pattern \"" + matcher->getPattern()
                                 + "\" in TextUtil::IsRomanNumeral: " + err_msg);

    return retcode;
}

bool IsUnsignedInteger(const std::string &s) {
    std::string err_msg;
    static RegexMatcher *matcher(nullptr);
    if (unlikely(matcher == nullptr)) {
        const std::string pattern("^[0-9]+$");
        matcher = RegexMatcher::RegexMatcherFactory(pattern, &err_msg);
        if (unlikely(matcher == nullptr))
            throw std::runtime_error("Failed to construct a RegexMatcher for \"" + pattern
                                     + "\" in TextUtil::IsUnsignedInteger: " + err_msg);
    }

    const bool retcode(matcher->matched(s, &err_msg));
    if (unlikely(not err_msg.empty()))
        throw std::runtime_error("Failed to match \"" + s + "\" against pattern \"" + matcher->getPattern()
                                 + "\" in TextUtil::IsUnsignedInteger: " + err_msg);

    return retcode;
}

bool UTF8toWCharString(const std::string &utf8_string, std::wstring * wchar_string) {
    wchar_string->clear();

    const char *cp(utf8_string.c_str());
    size_t remainder(utf8_string.size());
    std::mbstate_t state = std::mbstate_t();
    for (;;) {
        wchar_t wch;
        const size_t retcode(std::mbrtowc(&wch, cp, remainder, &state));
        if (retcode == static_cast<size_t>(-1) or retcode == static_cast<size_t>(-2))
            return false;
        if (retcode == 0)
            return true;
        *wchar_string += wch;
        cp += retcode;
        remainder -= retcode;
    }
}

bool WCharToUTF8String(const std::wstring &wchar_string, std::string * utf8_string) {
    utf8_string->clear();

    char buf[6];
    std::mbstate_t state = std::mbstate_t();
    for (const auto wch : wchar_string) {
        const size_t retcode(std::wcrtomb(buf, wch, &state));
        if (retcode == static_cast<size_t>(-1))
            return false;
        utf8_string->append(buf, retcode);
    }

    return true;
}

bool WCharToUTF8String(const wchar_t wchar, std::string * utf8_string) {
    utf8_string->clear();

    char buf[6];
    std::mbstate_t state = std::mbstate_t();
    const size_t retcode(std::wcrtomb(buf, wchar, &state));
    if (retcode == static_cast<size_t>(-1))
        return false;
    utf8_string->append(buf, retcode);
    return true;
}

bool UTF8ToLower(const std::string &utf8_string, std::string * const lowercase_utf8_string) {
    std::wstring wchar_string;
    if (not UTF8toWCharString(utf8_string, &wchar_string))
        return false;

    // Lowercase the wide character string:
    std::wstring lowercase_wide_string;
    for (const auto wide_ch : wchar_string)
        lowercase_wide_string += std::towlower(static_cast<wint_t>(wide_ch));

    return WCharToUTF8String(lowercase_wide_string, lowercase_utf8_string);
}

namespace {

/** \return True if "number_candidate" is non-empty and consists only of characters belonging
 *          to the wide-character class "digit"
 */
bool IsNumber(const std::wstring &number_candidate) {
    if (number_candidate.empty())
        return false;

    for (const wchar_t ch : number_candidate) {
        if (not std::iswdigit(ch))
            return false;
    }

    return true;
}

template<typename ContainerType> bool ChopIntoWords(const std::string &text, ContainerType * const words,
                                                    const unsigned min_word_length)
{
    words->clear();

    std::wstring wide_text;
    if (unlikely(not UTF8toWCharString(text, &wide_text)))
        return false;

    std::wstring word;
    std::string utf8_word;
    bool leading(true);
    for (const wchar_t ch : wide_text) {
        if (leading and (ch == L'-' or ch == L'\''))
            ; // Do nothing!
        else if (iswalnum(ch) or ch == L'-' or ch == L'\'') {
            word += ch;
            leading = false;
        } else if (ch == L'.' and IsNumber(word)) {
            word += ch;
            if (word.length() >= min_word_length) {
                if (unlikely(not WCharToUTF8String(word, &utf8_word)))
                    return false;
                words->insert(words->end(), utf8_word);
            }
            word.clear();
            leading = true;
        } else {
            // Remove trailing and leading hyphens and quotes:
            while (word.length() > 0 and (word[word.length() - 1] == L'-' or word[word.length() - 1] == L'\''))
                word.resize(word.length() - 1);
            if (word.length() >= min_word_length) {
                if (unlikely(not WCharToUTF8String(word, &utf8_word)))
                    return false;
                words->insert(words->end(), utf8_word);
            }
            word.clear();
            leading = true;
        }
    }

    // Remove trailing and leading hyphens and quotes:
    while (word.length() > 0 and word[word.length() - 1] == '-')
        word.resize(word.length() - 1);
    if (word.length() >= min_word_length) {
        if (unlikely(not WCharToUTF8String(word, &utf8_word)))
            return false;
        words->insert(words->end(), utf8_word);
    }

    return true;
}

} // unnamed namespace

bool ChopIntoWords(const std::string &text, std::unordered_set<std::string> * const words,
                   const unsigned min_word_length)
{
    return ChopIntoWords<std::unordered_set<std::string>> (text, words, min_word_length);
}

bool ChopIntoWords(const std::string &text, std::vector<std::string> * const words,
                   const unsigned min_word_length)
{
    return ChopIntoWords<std::vector<std::string>> (text, words, min_word_length);
}

std::vector<std::string>::const_iterator FindSubstring(const std::vector<std::string> &haystack,
                                                       const std::vector<std::string> &needle)
{
    if (needle.empty())
        return haystack.cbegin();

    std::vector<std::string>::const_iterator search_start(haystack.cbegin());
    while (search_start != haystack.cend()) {
        const std::vector<std::string>::const_iterator haystack_start(
            std::find(search_start, haystack.cend(), needle[0]));
        if ((haystack.cend() - haystack_start) < static_cast<ssize_t>(needle.size()))
            return haystack.cend();

        std::vector<std::string>::const_iterator needle_word(needle.cbegin());
        std::vector<std::string>::const_iterator haystack_word(haystack_start);
        for (;;) {
            ++needle_word;
            if (needle_word == needle.cend())
                return haystack_start;
            ++haystack_word;
            if (haystack_word == haystack.cend())
                return haystack.cend();
            else if (*haystack_word != *needle_word) {
                search_start = haystack_start + 1;
                break;
            }
        }
    }

    return haystack.cend();
}

std::string Base64Encode(const std::string &s, const char symbol63, const char symbol64) {
    static char symbols[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\0\0";
    symbols[62] = symbol63;
    symbols[63] = symbol64;

    std::string encoded_chars;
    std::string::const_iterator ch(s.begin());
    while (ch != s.end()) {
        // Collect groups of 3 characters:
        unsigned buf(static_cast<unsigned char>(*ch));
        buf <<= 8u;
        ++ch;
        unsigned ignore_count(0);
        if (ch != s.end()) {
            buf |= static_cast<unsigned char>(*ch);
            ++ch;
        } else
            ++ignore_count;
        buf <<= 8u;
        if (ch != s.end()) {
            buf |= static_cast<unsigned char>(*ch);
            ++ch;
        }
        else
            ++ignore_count;

        // Now grab 6 bits at a time and encode them starting with the 4th character:
        char next4[4];
        for (unsigned char_no(0); char_no < 4; ++char_no) {
            next4[4 - 1 - char_no] = symbols[buf & 0x3Fu];
            buf >>= 6u;
        }

        for (unsigned char_no(0); char_no < 4 - ignore_count; ++char_no)
            encoded_chars += next4[char_no];
    }

    return encoded_chars;
}

inline bool IsWhiteSpace(const char ch) {
    return ch == ' ' or ch == '\t' or ch == '\n' or ch == '\v' or ch == '\xA0';
}

inline std::string OctalEscape(const char ch) {
    char buf[1 + 3 + 1];
    std::sprintf(buf, "\\%03o", static_cast<unsigned>(ch));
    return buf;
}

std::string EscapeString(const std::string &original_string, const bool also_escape_whitespace) {
    std::string escaped_string;
    escaped_string.reserve(original_string.size() * 2);

    for (char ch : original_string) {
        if (std::iscntrl(ch) or (not also_escape_whitespace or IsWhiteSpace(ch)))
            escaped_string += OctalEscape(ch);
        else
            escaped_string += ch;
    }

    return escaped_string;
}

} // namespace TextUtil
<commit_msg>Final version for formatting hopefully.<commit_after>/** \file    TextUtil.h
 *  \brief   Declarations of text related utility functions.
 *  \author  Dr. Johannes Ruscheinski
 *  \author  Jiangtao Hu
 */

/*
 *  Copyright 2003-2009 Project iVia.
 *  Copyright 2003-2009 The Regents of The University of California.
 *  Copyright 2015 Universitätsbibliothek Tübingen.
 *
 *  This file is part of the libiViaCore package.
 *
 *  The libiViaCore package is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public License as published
 *  by the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  libiViaCore 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 libiViaCore; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "TextUtil.h"
#include <algorithm>
#include <exception>
#include <cstdio>
#include <cwctype>
#include "Compiler.h"
#include "Locale.h"
#include "HtmlParser.h"
#include "RegexMatcher.h"
#include "StringUtil.h"

namespace {

class TextExtractor: public HtmlParser {
    std::string &extracted_text_;
public:
    TextExtractor(const std::string &html, std::string * const extracted_text)
        : HtmlParser(html, HtmlParser::TEXT), extracted_text_(*extracted_text) { }
    virtual void notify(const HtmlParser::Chunk &chunk);
};

void TextExtractor::notify(const HtmlParser::Chunk &chunk) {
    if (chunk.type_ == HtmlParser::TEXT)
        extracted_text_ += chunk.text_;
}

} // unnamned namespace

namespace TextUtil {

std::string ExtractText(const std::string &html) {
    std::string extracted_text;
    TextExtractor extractor(html, &extracted_text);
    extractor.parse();

    return extracted_text;
}

bool IsRomanNumeral(const std::string &s) {
    if (s.empty())
        return false;

    std::string err_msg;
    static RegexMatcher *matcher(nullptr);
    if (unlikely(matcher == nullptr)) {
        const std::string pattern("^M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$");
        matcher = RegexMatcher::RegexMatcherFactory(pattern, &err_msg);
        if (unlikely(matcher == nullptr))
            throw std::runtime_error("Failed to construct a RegexMatcher for \"" + pattern
                                     + "\" in TextUtil::IsRomanNumeral: " + err_msg);
    }

    const bool retcode(matcher->matched(s, &err_msg));
    if (unlikely(not err_msg.empty()))
        throw std::runtime_error("Failed to match \"" + s + "\" against pattern \"" + matcher->getPattern()
                                 + "\" in TextUtil::IsRomanNumeral: " + err_msg);

    return retcode;
}

bool IsUnsignedInteger(const std::string &s) {
    std::string err_msg;
    static RegexMatcher *matcher(nullptr);
    if (unlikely(matcher == nullptr)) {
        const std::string pattern("^[0-9]+$");
        matcher = RegexMatcher::RegexMatcherFactory(pattern, &err_msg);
        if (unlikely(matcher == nullptr))
            throw std::runtime_error("Failed to construct a RegexMatcher for \"" + pattern
                                     + "\" in TextUtil::IsUnsignedInteger: " + err_msg);
    }

    const bool retcode(matcher->matched(s, &err_msg));
    if (unlikely(not err_msg.empty()))
        throw std::runtime_error("Failed to match \"" + s + "\" against pattern \"" + matcher->getPattern()
                                 + "\" in TextUtil::IsUnsignedInteger: " + err_msg);

    return retcode;
}

bool UTF8toWCharString(const std::string &utf8_string, std::wstring * wchar_string) {
    wchar_string->clear();

    const char *cp(utf8_string.c_str());
    size_t remainder(utf8_string.size());
    std::mbstate_t state = std::mbstate_t();
    for (;;) {
        wchar_t wch;
        const size_t retcode(std::mbrtowc(&wch, cp, remainder, &state));
        if (retcode == static_cast<size_t>(-1) or retcode == static_cast<size_t>(-2))
            return false;
        if (retcode == 0)
            return true;
        *wchar_string += wch;
        cp += retcode;
        remainder -= retcode;
    }
}

bool WCharToUTF8String(const std::wstring &wchar_string, std::string * utf8_string) {
    utf8_string->clear();

    char buf[6];
    std::mbstate_t state = std::mbstate_t();
    for (const auto wch : wchar_string) {
        const size_t retcode(std::wcrtomb(buf, wch, &state));
        if (retcode == static_cast<size_t>(-1))
            return false;
        utf8_string->append(buf, retcode);
    }

    return true;
}

bool WCharToUTF8String(const wchar_t wchar, std::string * utf8_string) {
    utf8_string->clear();

    char buf[6];
    std::mbstate_t state = std::mbstate_t();
    const size_t retcode(std::wcrtomb(buf, wchar, &state));
    if (retcode == static_cast<size_t>(-1))
        return false;
    utf8_string->append(buf, retcode);
    return true;
}

bool UTF8ToLower(const std::string &utf8_string, std::string * const lowercase_utf8_string) {
    std::wstring wchar_string;
    if (not UTF8toWCharString(utf8_string, &wchar_string))
        return false;

    // Lowercase the wide character string:
    std::wstring lowercase_wide_string;
    for (const auto wide_ch : wchar_string)
        lowercase_wide_string += std::towlower(static_cast<wint_t>(wide_ch));

    return WCharToUTF8String(lowercase_wide_string, lowercase_utf8_string);
}

namespace {

/** \return True if "number_candidate" is non-empty and consists only of characters belonging
 *          to the wide-character class "digit"
 */
bool IsNumber(const std::wstring &number_candidate) {
    if (number_candidate.empty())
        return false;

    for (const wchar_t ch : number_candidate) {
        if (not std::iswdigit(ch))
            return false;
    }

    return true;
}

template<typename ContainerType> bool ChopIntoWords(const std::string &text, ContainerType * const words,
                                                    const unsigned min_word_length)
{
    words->clear();

    std::wstring wide_text;
    if (unlikely(not UTF8toWCharString(text, &wide_text)))
        return false;

    std::wstring word;
    std::string utf8_word;
    bool leading(true);
    for (const wchar_t ch : wide_text) {
        if (leading and (ch == L'-' or ch == L'\''))
            ; // Do nothing!
        else if (iswalnum(ch) or ch == L'-' or ch == L'\'') {
            word += ch;
            leading = false;
        } else if (ch == L'.' and IsNumber(word)) {
            word += ch;
            if (word.length() >= min_word_length) {
                if (unlikely(not WCharToUTF8String(word, &utf8_word)))
                    return false;
                words->insert(words->end(), utf8_word);
            }
            word.clear();
            leading = true;
        } else {
            // Remove trailing and leading hyphens and quotes:
            while (word.length() > 0 and (word[word.length() - 1] == L'-' or word[word.length() - 1] == L'\''))
                word.resize(word.length() - 1);
            if (word.length() >= min_word_length) {
                if (unlikely(not WCharToUTF8String(word, &utf8_word)))
                    return false;
                words->insert(words->end(), utf8_word);
            }
            word.clear();
            leading = true;
        }
    }

    // Remove trailing and leading hyphens and quotes:
    while (word.length() > 0 and word[word.length() - 1] == '-')
        word.resize(word.length() - 1);
    if (word.length() >= min_word_length) {
        if (unlikely(not WCharToUTF8String(word, &utf8_word)))
            return false;
        words->insert(words->end(), utf8_word);
    }

    return true;
}

} // unnamed namespace

bool ChopIntoWords(const std::string &text, std::unordered_set<std::string> * const words,
                   const unsigned min_word_length)
{
    return ChopIntoWords<std::unordered_set<std::string>> (text, words, min_word_length);
}

bool ChopIntoWords(const std::string &text, std::vector<std::string> * const words,
                   const unsigned min_word_length)
{
    return ChopIntoWords<std::vector<std::string>> (text, words, min_word_length);
}

std::vector<std::string>::const_iterator FindSubstring(const std::vector<std::string> &haystack,
                                                       const std::vector<std::string> &needle)
{
    if (needle.empty())
        return haystack.cbegin();

    std::vector<std::string>::const_iterator search_start(haystack.cbegin());
    while (search_start != haystack.cend()) {
        const std::vector<std::string>::const_iterator haystack_start(
            std::find(search_start, haystack.cend(), needle[0]));
        if ((haystack.cend() - haystack_start) < static_cast<ssize_t>(needle.size()))
            return haystack.cend();

        std::vector<std::string>::const_iterator needle_word(needle.cbegin());
        std::vector<std::string>::const_iterator haystack_word(haystack_start);
        for (;;) {
            ++needle_word;
            if (needle_word == needle.cend())
                return haystack_start;
            ++haystack_word;
            if (haystack_word == haystack.cend())
                return haystack.cend();
            else if (*haystack_word != *needle_word) {
                search_start = haystack_start + 1;
                break;
            }
        }
    }

    return haystack.cend();
}

std::string Base64Encode(const std::string &s, const char symbol63, const char symbol64) {
    static char symbols[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\0\0";
    symbols[62] = symbol63;
    symbols[63] = symbol64;

    std::string encoded_chars;
    std::string::const_iterator ch(s.begin());
    while (ch != s.end()) {
        // Collect groups of 3 characters:
        unsigned buf(static_cast<unsigned char>(*ch));
        buf <<= 8u;
        ++ch;
        unsigned ignore_count(0);
        if (ch != s.end()) {
            buf |= static_cast<unsigned char>(*ch);
            ++ch;
        } else
            ++ignore_count;
        buf <<= 8u;
        if (ch != s.end()) {
            buf |= static_cast<unsigned char>(*ch);
            ++ch;
        }
        else
            ++ignore_count;

        // Now grab 6 bits at a time and encode them starting with the 4th character:
        char next4[4];
        for (unsigned char_no(0); char_no < 4; ++char_no) {
            next4[4 - 1 - char_no] = symbols[buf & 0x3Fu];
            buf >>= 6u;
        }

        for (unsigned char_no(0); char_no < 4 - ignore_count; ++char_no)
            encoded_chars += next4[char_no];
    }

    return encoded_chars;
}

inline bool IsWhiteSpace(const char ch) {
    return ch == ' ' or ch == '\t' or ch == '\n' or ch == '\v' or ch == '\xA0';
}

inline std::string OctalEscape(const char ch) {
    char buf[1 + 3 + 1];
    std::sprintf(buf, "\\%03o", ch);
    return buf;
}

std::string EscapeString(const std::string &original_string, const bool also_escape_whitespace) {
    std::string escaped_string;
    escaped_string.reserve(original_string.size() * 2);

    for (char ch : original_string) {
        if (std::iscntrl(ch) or (not also_escape_whitespace or IsWhiteSpace(ch)))
            escaped_string += OctalEscape(ch);
        else
            escaped_string += ch;
    }

    return escaped_string;
}

} // namespace TextUtil
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2007-2010 Digital Bazaar, Inc. All rights reserved.
 */
#define __STDC_CONSTANT_MACROS

#include "monarch/net/SocketTools.h"

#include "monarch/net/WindowsSupport.h"
#include "monarch/rt/Thread.h"
#include "monarch/rt/System.h"

#include <limits.h>

using namespace monarch::net;
using namespace monarch::rt;

#ifndef HOST_NAME_MAX
#define HOST_NAME_MAX 255
#endif

int SocketTools::select(bool read, int fd, int64_t timeout)
{
   int rval = 0;

   // create a file descriptor set to read on
   fd_set rfds;
   FD_ZERO(&rfds);

   // create a file descriptor set to write on
   fd_set wfds;
   FD_ZERO(&wfds);

   // create a file descriptor set to check for exceptions on
   fd_set exfds;
   FD_ZERO(&exfds);

   // add file descriptor to sets
   FD_SET(fd, &rfds);
   FD_SET(fd, &wfds);
   FD_SET(fd, &exfds);

   // "n" parameter is the highest numbered descriptor plus 1
   int n = fd + 1;

   // set 20 millisecond interrupt check timeout (necessary because
   // windows lacks SIGNAL support to do interruptions properly)
   int64_t intck = INT64_C(20);

   // keep selecting (polling) until timeout is reached
   int64_t remaining = (timeout <= 0) ? intck : timeout;

   struct timeval to;
   if(timeout < 0)
   {
      // create instant timeout (polling)
      to.tv_sec = 0;
      to.tv_usec = 0;
   }
   else
   {
      // create intck millisecond timeout (1 millisecond is 1000 microseconds)
      to.tv_sec = 0;
      to.tv_usec = (remaining < intck ? remaining : intck) * INT64_C(1000);
   }

   uint64_t start = System::getCurrentMilliseconds();
   uint64_t end;

   Thread* t = Thread::currentThread();
   while(remaining > 0 && rval == 0 && !t->isInterrupted())
   {
      // wait for file descriptors to be updated
      if(read)
      {
         // wait for readability
         rval = ::select(n, &rfds, NULL, &exfds, &to);
      }
      else
      {
         // wait for readability and writability
         //
         // Note: We must test to see if the pipe is broken by
         // testing for readability -- as it will occur if the
         // connection closes due to TCP sending an RST to the
         // socket which causes recv() to return 0
         rval = ::select(n, &rfds, &wfds, &exfds, &to);
         if(rval > 0 && !FD_ISSET(fd, &wfds) && FD_ISSET(fd, &rfds))
         {
            // check to see if the connection has been shutdown, by seeing
            // if recv() will return 0 (do a peek so as not to disturb data)
            char buf;
            int flags = MSG_PEEK;
#ifdef MSG_DONTWAIT
            flags |= MSG_DONTWAIT;
#endif
            if(SOCKET_MACRO_recv(fd, &buf, 1, flags) <= 0)
            {
               // connection closed, or error
               rval = -1;
               errno = EBADF;
            }
            else
            {
               // connection not closed, but write timed out/not detected
               rval = 0;
            }
         }
      }

      if(rval < 0 && (errno == 0 || errno == EINPROGRESS || errno == EINTR))
      {
         // no error, just timed out, operation in progress,
         // or syscall interrupted
         rval = 0;

         // Note: handling EINTR could be changed to interrupt the current
         // thread if appropriate
      }

      // select() implementation may alter sets or timeout, so reset them
      // if calling select() again (not interrupted and timeout >= 0)
      if(rval == 0 && timeout >= 0)
      {
         // clear sets and re-add file descriptor
         FD_ZERO(&rfds);
         FD_ZERO(&wfds);
         FD_ZERO(&exfds);
         FD_SET(fd, &rfds);
         FD_SET(fd, &wfds);
         FD_SET(fd, &exfds);

         // reset timeout
         to.tv_sec = 0;
         to.tv_usec = intck * INT64_C(1000);
      }

      if(timeout != 0)
      {
         // decrement remaining time
         end = System::getCurrentMilliseconds();
         remaining -= (end - start);
         start = end;
         to.tv_usec = (remaining < intck ? remaining : intck) * INT64_C(1000);
      }
   }

   if(t->isInterrupted())
   {
      rval = -1;
      errno = EINTR;

      // set interrupted exception
      ExceptionRef e = t->createInterruptedException();
      Exception::set(e);
   }
   else if(rval > 0 && FD_ISSET(fd, &exfds) != 0)
   {
      // an exception occurred with the file descriptor
      rval = -1;
      errno = EBADF;
   }

   return rval;
}

int SocketTools::select(
   int nfds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds,
   int64_t timeout, const sigset_t* sigmask)
{
   int rval = 0;

// Note: disabled due to a lack of support in windows
//   // create timeout
//   struct timeval* tv = NULL;
//   struct timeval to;
//   if(timeout > 0)
//   {
//      // set timeout (1 millisecond is 1000 microseconds)
//      to.tv_sec = timeout / INT64_C(1000);
//      to.tv_usec = (timeout % INT64_C(1000)) * INT64_C(1000);
//      tv = &to;
//   }
//
//   // FIXME: signals supposedly don't make select() return in windows
//   // this needs to be tested and potentially remedied somehow
//
//   // FIXME: furthermore, even if we block SIGINT (interruption signal) up
//   // until we reach the select call -- and then unblock right before it
//   // the signal could still sneak in right before select() is called and
//   // control is transferred to the kernel, and therefore we'd handle the
//   // SIGINT before the select() call and select() wouldn't get interrupted
//   // (there is pselect() for doing that unblocking atomically, but
//   // it's UNIX only) -- this may be solved by writing to another file
//   // descriptor when we receive SIGINTs and checking that file descriptor
//   // as well as the one we are waiting on -- but this might not be a
//   // viable solution for windows
//
//   // block SIGINTs
//   blockSignal(SIGINT);
//
//   Thread* t = Thread::currentThread();
//   if(!t->isInterrupted())
//   {
//      // FIXME: pselect() required here to do atomic unblocking & selecting
//
//      // wait for file descriptors to be updated
//      unblockSignal(SIGINT);
//      rval = ::select(nfds, readfds, writefds, exceptfds, timeout);
//      if(rval < 0)
//      {
//         if(errno == EINTR)
//         {
//            // interrupt thread
//            t->interrupt();
//         }
//      }
//   }
//   else
//   {
//      rval = -1;
//      errno = EINTR;
//   }

   // clone file descriptor sets
   fd_set readfds2;
   fd_set writefds2;
   fd_set exceptfds2;

   if(readfds != NULL)
   {
      readfds2 = *readfds;
   }

   if(writefds != NULL)
   {
      writefds2 = *writefds;
   }

   if(exceptfds != NULL)
   {
      exceptfds2 = *exceptfds;
   }

   // set 20 millisecond interrupt check timeout (necessary because
   // windows lacks SIGNAL support to do interruptions properly)
   int64_t intck = INT64_C(20);

   // keep selecting (polling) until timeout is reached
   int64_t remaining = (timeout <= 0) ? intck : timeout;

   struct timeval to;
   if(timeout < 0)
   {
      // create instant timeout (polling)
      to.tv_sec = 0;
      to.tv_usec = 0;
   }
   else
   {
      // create 20 millisecond timeout (1 millisecond is 1000 microseconds)
      to.tv_sec = 0;
      to.tv_usec = (remaining < intck ? remaining : intck) * INT64_C(1000);
   }

   uint64_t start = System::getCurrentMilliseconds();
   uint64_t end;

   Thread* t = Thread::currentThread();
   while(remaining > 0 && rval == 0 && !t->isInterrupted())
   {
      // wait for file descriptors to be updated
      rval = ::select(nfds, readfds, writefds, exceptfds, &to);

      if(rval < 0 && (errno == 0 || errno == EINPROGRESS || errno == EINTR))
      {
         // no error, just timed out, operation in progress,
         // or syscall interrupted
         rval = 0;

         // Note: handling EINTR could be changed to interrupt the current
         // thread if appropriate
      }

      // select() implementation may alter sets or timeout, so reset them
      // if calling select() again (not interrupted and timeout >= 0)
      if(rval == 0 && timeout >= 0)
      {
         // reset file descriptor sets
         if(readfds != NULL)
         {
            *readfds = readfds2;
         }

         if(writefds != NULL)
         {
            *writefds = writefds2;
         }

         if(exceptfds != NULL)
         {
            *exceptfds = exceptfds2;
         }

         // reset timeout
         to.tv_sec = 0;
         to.tv_usec = intck * INT64_C(1000);
      }

      if(timeout != 0)
      {
         // decrement remaining time
         end = System::getCurrentMilliseconds();
         remaining -= (end - start);
         start = end;
         to.tv_usec = (remaining < intck ? remaining : intck) * INT64_C(1000);
      }
   }

   if(t->isInterrupted())
   {
      rval = -1;
      errno = EINTR;

      // set interrupted exception
      ExceptionRef e = t->createInterruptedException();
      Exception::set(e);
   }

   return rval;
}

std::string SocketTools::getHostname()
{
   char tmp[HOST_NAME_MAX + 1];
   memset(tmp, 0, HOST_NAME_MAX + 1);
   gethostname(tmp, HOST_NAME_MAX);
   return tmp;
}
<commit_msg>Made sure to reset FD sets on any error (including EINPROGRESS,etc).<commit_after>/*
 * Copyright (c) 2007-2010 Digital Bazaar, Inc. All rights reserved.
 */
#define __STDC_CONSTANT_MACROS

#include "monarch/net/SocketTools.h"

#include "monarch/net/WindowsSupport.h"
#include "monarch/rt/Thread.h"
#include "monarch/rt/System.h"

#include <limits.h>

using namespace monarch::net;
using namespace monarch::rt;

#ifndef HOST_NAME_MAX
#define HOST_NAME_MAX 255
#endif
#include <cstdio>
int SocketTools::select(bool read, int fd, int64_t timeout)
{
   int rval = 0;

   // create a file descriptor set to read on
   fd_set rfds;
   FD_ZERO(&rfds);

   // create a file descriptor set to write on
   fd_set wfds;
   FD_ZERO(&wfds);

   // create a file descriptor set to check for exceptions on
   fd_set exfds;
   FD_ZERO(&exfds);

   // add file descriptor to sets
   FD_SET(fd, &rfds);
   FD_SET(fd, &wfds);
   FD_SET(fd, &exfds);

   // "n" parameter is the highest numbered descriptor plus 1
   int n = fd + 1;

   // set 20 millisecond interrupt check timeout (necessary because
   // windows lacks SIGNAL support to do interruptions properly)
   int64_t intck = INT64_C(20);

   // keep selecting (polling) until timeout is reached
   int64_t remaining = (timeout <= 0) ? intck : timeout;

   struct timeval to;
   if(timeout < 0)
   {
      // create instant timeout (polling)
      to.tv_sec = 0;
      to.tv_usec = 0;
   }
   else
   {
      // create intck millisecond timeout (1 millisecond is 1000 microseconds)
      to.tv_sec = 0;
      to.tv_usec = (remaining < intck ? remaining : intck) * INT64_C(1000);
   }

   uint64_t start = System::getCurrentMilliseconds();
   uint64_t end;

   Thread* t = Thread::currentThread();
   while(remaining > 0 && rval == 0 && !t->isInterrupted())
   {
      // wait for file descriptors to be updated
      if(read)
      {
         // wait for readability
         rval = ::select(n, &rfds, NULL, &exfds, &to);
      }
      else
      {
         // wait for readability and writability
         //
         // Note: We must test to see if the pipe is broken by
         // testing for readability -- as it will occur if the
         // connection closes due to TCP sending an RST to the
         // socket which causes recv() to return 0
         rval = ::select(n, &rfds, &wfds, &exfds, &to);
         if(rval > 0 && !FD_ISSET(fd, &wfds) && FD_ISSET(fd, &rfds))
         {
            // check to see if the connection has been shutdown, by seeing
            // if recv() will return 0 (do a peek so as not to disturb data)
            char buf;
            int flags = MSG_PEEK;
#ifdef MSG_DONTWAIT
            flags |= MSG_DONTWAIT;
#endif
            if(SOCKET_MACRO_recv(fd, &buf, 1, flags) <= 0)
            {
               // connection closed, or error
               rval = -1;
               errno = EBADF;
            }
            else
            {
               // connection not closed, but write timed out/not detected
               rval = 0;
            }
         }
      }

      if(rval < 0 && (errno == 0 || errno == EINPROGRESS || errno == EINTR))
      {
         // no error, just timed out, operation in progress,
         // or syscall interrupted
         rval = 0;

         // Note: handling EINTR could be changed to interrupt the current
         // thread if appropriate
      }

      // select() implementation may alter sets or timeout, so reset them
      // if calling select() again (not interrupted and timeout >= 0)
      if(rval == 0)
      {
         // clear sets and re-add file descriptor
         FD_ZERO(&rfds);
         FD_ZERO(&wfds);
         FD_ZERO(&exfds);
         FD_SET(fd, &rfds);
         FD_SET(fd, &wfds);
         FD_SET(fd, &exfds);

         // reset timeout
         to.tv_sec = 0;
         if(timeout < 0)
         {
            to.tv_usec = 0;
         }
         else
         {
            to.tv_usec = intck * INT64_C(1000);
         }
      }

      if(timeout != 0)
      {
         // decrement remaining time
         end = System::getCurrentMilliseconds();
         remaining -= (end - start);
         start = end;
         to.tv_usec = (remaining < intck ? remaining : intck) * INT64_C(1000);
      }
   }

   if(t->isInterrupted())
   {
      rval = -1;
      errno = EINTR;

      // set interrupted exception
      ExceptionRef e = t->createInterruptedException();
      Exception::set(e);
   }
   else if(rval > 0 && FD_ISSET(fd, &exfds) != 0)
   {
      // an exception occurred with the file descriptor
      rval = -1;
      errno = EBADF;
   }

   return rval;
}

int SocketTools::select(
   int nfds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds,
   int64_t timeout, const sigset_t* sigmask)
{
   int rval = 0;

// Note: disabled due to a lack of support in windows
//   // create timeout
//   struct timeval* tv = NULL;
//   struct timeval to;
//   if(timeout > 0)
//   {
//      // set timeout (1 millisecond is 1000 microseconds)
//      to.tv_sec = timeout / INT64_C(1000);
//      to.tv_usec = (timeout % INT64_C(1000)) * INT64_C(1000);
//      tv = &to;
//   }
//
//   // FIXME: signals supposedly don't make select() return in windows
//   // this needs to be tested and potentially remedied somehow
//
//   // FIXME: furthermore, even if we block SIGINT (interruption signal) up
//   // until we reach the select call -- and then unblock right before it
//   // the signal could still sneak in right before select() is called and
//   // control is transferred to the kernel, and therefore we'd handle the
//   // SIGINT before the select() call and select() wouldn't get interrupted
//   // (there is pselect() for doing that unblocking atomically, but
//   // it's UNIX only) -- this may be solved by writing to another file
//   // descriptor when we receive SIGINTs and checking that file descriptor
//   // as well as the one we are waiting on -- but this might not be a
//   // viable solution for windows
//
//   // block SIGINTs
//   blockSignal(SIGINT);
//
//   Thread* t = Thread::currentThread();
//   if(!t->isInterrupted())
//   {
//      // FIXME: pselect() required here to do atomic unblocking & selecting
//
//      // wait for file descriptors to be updated
//      unblockSignal(SIGINT);
//      rval = ::select(nfds, readfds, writefds, exceptfds, timeout);
//      if(rval < 0)
//      {
//         if(errno == EINTR)
//         {
//            // interrupt thread
//            t->interrupt();
//         }
//      }
//   }
//   else
//   {
//      rval = -1;
//      errno = EINTR;
//   }

   // clone file descriptor sets
   fd_set readfds2;
   fd_set writefds2;
   fd_set exceptfds2;

   if(readfds != NULL)
   {
      readfds2 = *readfds;
   }

   if(writefds != NULL)
   {
      writefds2 = *writefds;
   }

   if(exceptfds != NULL)
   {
      exceptfds2 = *exceptfds;
   }

   // set 20 millisecond interrupt check timeout (necessary because
   // windows lacks SIGNAL support to do interruptions properly)
   int64_t intck = INT64_C(20);

   // keep selecting (polling) until timeout is reached
   int64_t remaining = (timeout <= 0) ? intck : timeout;

   struct timeval to;
   if(timeout < 0)
   {
      // create instant timeout (polling)
      to.tv_sec = 0;
      to.tv_usec = 0;
   }
   else
   {
      // create 20 millisecond timeout (1 millisecond is 1000 microseconds)
      to.tv_sec = 0;
      to.tv_usec = (remaining < intck ? remaining : intck) * INT64_C(1000);
   }

   uint64_t start = System::getCurrentMilliseconds();
   uint64_t end;

   Thread* t = Thread::currentThread();
   while(remaining > 0 && rval == 0 && !t->isInterrupted())
   {
      // wait for file descriptors to be updated
      rval = ::select(nfds, readfds, writefds, exceptfds, &to);

      if(rval < 0 && (errno == 0 || errno == EINPROGRESS || errno == EINTR))
      {
         // no error, just timed out, operation in progress,
         // or syscall interrupted
         rval = 0;

         // Note: handling EINTR could be changed to interrupt the current
         // thread if appropriate
      }

      // select() implementation may alter sets or timeout, so reset them
      // if calling select() again (not interrupted and timeout >= 0)
      if(rval == 0 && timeout >= 0)
      {
         // reset file descriptor sets
         if(readfds != NULL)
         {
            *readfds = readfds2;
         }

         if(writefds != NULL)
         {
            *writefds = writefds2;
         }

         if(exceptfds != NULL)
         {
            *exceptfds = exceptfds2;
         }

         // reset timeout
         to.tv_sec = 0;
         to.tv_usec = intck * INT64_C(1000);
      }

      if(timeout != 0)
      {
         // decrement remaining time
         end = System::getCurrentMilliseconds();
         remaining -= (end - start);
         start = end;
         to.tv_usec = (remaining < intck ? remaining : intck) * INT64_C(1000);
      }
   }

   if(t->isInterrupted())
   {
      rval = -1;
      errno = EINTR;

      // set interrupted exception
      ExceptionRef e = t->createInterruptedException();
      Exception::set(e);
   }

   return rval;
}

std::string SocketTools::getHostname()
{
   char tmp[HOST_NAME_MAX + 1];
   memset(tmp, 0, HOST_NAME_MAX + 1);
   gethostname(tmp, HOST_NAME_MAX);
   return tmp;
}
<|endoftext|>


<commit_before>#include <iostream>
#include <Eigen/Core>

#include "genrp/solvers/direct.h"
#include "genrp/solvers/band.h"

#define DO_TEST(NAME, VAR1, VAR2)                            \
{                                                            \
  double base, comp, delta;                                  \
  base = VAR1;                                               \
  comp = VAR2;                                               \
  delta = std::abs(base - comp);                             \
  if (delta > 1e-10) {                                       \
    std::cerr << "Test failed: '" << #NAME << "' - error: " << delta << std::endl; \
    return 1;                                                \
  } else                                                     \
    std::cerr << "Test passed: '" << #NAME << "' - error: " << delta << std::endl; \
}

int main (int argc, char* argv[])
{
  srand(42);

  size_t nterms = 3;
  if (argc >= 2) nterms = atoi(argv[1]);
  size_t N = 1024;
  if (argc >= 3) N = atoi(argv[2]);
  size_t niter = 10;
  if (argc >= 4) niter = atoi(argv[3]);

  // Set up the coefficients.
  Eigen::VectorXd alpha_real = Eigen::VectorXd::Random(nterms + 1),
                  alpha_complex_real = Eigen::VectorXd::Random(nterms),
                  alpha_complex_imag = Eigen::VectorXd::Random(nterms),
                  beta_real = Eigen::VectorXd::Random(nterms + 1),
                  beta_complex_real = Eigen::VectorXd::Random(nterms),
                  beta_complex_imag = Eigen::VectorXd::Random(nterms);
  alpha_real.array() += 1.0;
  alpha_complex_real.array() += 1.0;
  alpha_complex_imag.array() += 1.0;
  alpha_complex_imag.array() *= 0.5;
  beta_real.array() += 1.0;
  beta_complex_real.array() += 1.0;
  beta_complex_imag.array() += 1.0;

  // Generate some fake data.
  Eigen::VectorXd x = Eigen::VectorXd::Random(N),
                  yerr2 = Eigen::VectorXd::Random(N),
                  y;

  // Set the scale of the uncertainties.
  yerr2.array() *= 0.1;
  yerr2.array() += 0.3;

  // The times need to be sorted.
  std::sort(x.data(), x.data() + x.size());

  // Compute the y values.
  y = sin(x.array());

  genrp::DirectSolver<double> direct;
  genrp::BandSolver<double> band;

  direct.compute(alpha_real, beta_real, x, yerr2);
  band.compute(alpha_real, beta_real, x, yerr2);
  DO_TEST(band_real_log_det, direct.log_determinant(), band.log_determinant())
  DO_TEST(band_real_dot_solve, direct.dot_solve(y), band.dot_solve(y))

  band.compute(alpha_complex_real, alpha_complex_imag, beta_complex_real, beta_complex_imag, x, yerr2);
  direct.compute(alpha_complex_real, alpha_complex_imag, beta_complex_real, beta_complex_imag, x, yerr2);
  DO_TEST(band_complex_dot_solve, direct.dot_solve(y), band.dot_solve(y))
  DO_TEST(band_complex_log_det, direct.log_determinant(), band.log_determinant())

  band.compute(alpha_real, beta_real, alpha_complex_real, alpha_complex_imag, beta_complex_real, beta_complex_imag, x, yerr2);
  direct.compute(alpha_real, beta_real, alpha_complex_real, alpha_complex_imag, beta_complex_real, beta_complex_imag, x, yerr2);
  DO_TEST(band_mixed_dot_solve, direct.dot_solve(y), band.dot_solve(y))
  DO_TEST(band_mixed_log_det, direct.log_determinant(), band.log_determinant())

  return 0;
}
<commit_msg>tests?<commit_after>#include <iostream>
#include <Eigen/Core>

#include "genrp/solvers/direct.h"
#include "genrp/solvers/band.h"

#define DO_TEST(NAME, VAR1, VAR2)                            \
{                                                            \
  double base, comp, delta;                                  \
  base = VAR1;                                               \
  comp = VAR2;                                               \
  delta = std::abs(base - comp);                             \
  if (delta > 1e-10) {                                       \
    std::cerr << "Test failed: '" << #NAME << "' - error: " << delta << std::endl; \
    return 1;                                                \
  } else                                                     \
    std::cerr << "Test passed: '" << #NAME << "' - error: " << delta << std::endl; \
}

int main (int argc, char* argv[])
{
  srand(42);

  size_t nterms = 3;
  if (argc >= 2) nterms = atoi(argv[1]);
  size_t N = 1024;
  if (argc >= 3) N = atoi(argv[2]);
  size_t niter = 10;
  if (argc >= 4) niter = atoi(argv[3]);

  // Set up the coefficients.
  Eigen::VectorXd alpha_real = Eigen::VectorXd::Random(nterms + 1),
                  alpha_complex_real = Eigen::VectorXd::Random(nterms),
                  alpha_complex_imag = Eigen::VectorXd::Random(nterms),
                  beta_real = Eigen::VectorXd::Random(nterms + 1),
                  beta_complex_real = Eigen::VectorXd::Random(nterms),
                  beta_complex_imag = Eigen::VectorXd::Random(nterms);
  alpha_real.array() += 1.0;
  alpha_complex_real.array() += 1.0;
  alpha_complex_imag.array() += 1.0;
  alpha_complex_imag.array() *= 0.1;
  beta_real.array() += 1.0;
  beta_complex_real.array() += 1.0;
  beta_complex_imag.array() += 1.0;

  // Generate some fake data.
  Eigen::VectorXd x = Eigen::VectorXd::Random(N),
                  yerr2 = Eigen::VectorXd::Random(N),
                  y;

  // Set the scale of the uncertainties.
  yerr2.array() *= 0.1;
  yerr2.array() += 0.3;

  // The times need to be sorted.
  std::sort(x.data(), x.data() + x.size());

  // Compute the y values.
  y = sin(x.array());

  genrp::DirectSolver<double> direct;
  genrp::BandSolver<double> band;

  direct.compute(alpha_real, beta_real, x, yerr2);
  band.compute(alpha_real, beta_real, x, yerr2);
  DO_TEST(band_real_log_det, direct.log_determinant(), band.log_determinant())
  DO_TEST(band_real_dot_solve, direct.dot_solve(y), band.dot_solve(y))

  band.compute(alpha_complex_real, alpha_complex_imag, beta_complex_real, beta_complex_imag, x, yerr2);
  direct.compute(alpha_complex_real, alpha_complex_imag, beta_complex_real, beta_complex_imag, x, yerr2);
  DO_TEST(band_complex_dot_solve, direct.dot_solve(y), band.dot_solve(y))
  DO_TEST(band_complex_log_det, direct.log_determinant(), band.log_determinant())

  band.compute(alpha_real, beta_real, alpha_complex_real, alpha_complex_imag, beta_complex_real, beta_complex_imag, x, yerr2);
  direct.compute(alpha_real, beta_real, alpha_complex_real, alpha_complex_imag, beta_complex_real, beta_complex_imag, x, yerr2);
  DO_TEST(band_mixed_dot_solve, direct.dot_solve(y), band.dot_solve(y))
  DO_TEST(band_mixed_log_det, direct.log_determinant(), band.log_determinant())

  return 0;
}
<|endoftext|>