<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * 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.
 *
 ************************************************************************/

// autogenerated file with codegen.pl

#include <testshl/simpleheader.hxx>

#include <rtl/ref.hxx>
#include <osl/file.hxx>
#include <osl/process.h>
#include <comphelper/seqstream.hxx>
#include <comphelper/sequence.hxx>
#include <cppuhelper/compbase1.hxx>
#include <cppuhelper/bootstrap.hxx>
#include <cppuhelper/basemutex.hxx>

#include <com/sun/star/xml/sax/FastToken.hpp>
#include <com/sun/star/xml/sax/XSAXSerializable.hpp>
#include <com/sun/star/xml/sax/XFastSAXSerializable.hpp>

#include "../source/dom/documentbuilder.hxx"

using namespace ::DOM;
using namespace ::comphelper;
using namespace ::com::sun::star;

namespace
{

// valid xml
static const char validTestFile[] =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?> \
 <office:document-content \
   xmlns:office=\"urn:oasis:names:tc:opendocument:xmlns:office:1.0\" \
   xmlns:xlink=\"http://www.w3.org/1999/xlink\" \
   office:version=\"1.0\"> \
   <office:scripts/> \
   <xlink:test/> \
   <office:automatic-styles teststyle=\"test\"/> \
   <moretest/> \
    some text öäü \
 </office:document-content> \
";

// generates a warning: unsupported xml version, unknown xml:space
// value
static const char warningTestFile[] =
"<?xml version=\"47-11.0\" encoding=\"UTF-8\"?> \
 <office:document-content \
   xmlns:office=\"urn:oasis:names:tc:opendocument:xmlns:office:1.0\" \
   xml:space=\"blafasl\" \
   office:version=\"1.0\"> \
   <office:scripts/> \
   <office:automatic-styles/> \
 </office:document-content> \
";

// <?xml not at start of file
static const char errorTestFile[] =
" <?xml version=\"1.0\" encoding=\"UTF-8\"?> \
 <office:document-content \
   xmlns:office=\"urn:oasis:names:tc:opendocument:xmlns:office:1.0\" \
   office:version=\"1.0\"> \
   <office:scripts/> \
   <office:automatic-styles/> \
 </office:document-content> \
";

// plain empty
static const char fatalTestFile[] = "";

struct ErrorHandler
    : public ::cppu::WeakImplHelper1< xml::sax::XErrorHandler >
{
    sal_uInt32 mnErrCount;
    sal_uInt32 mnFatalCount;
    sal_uInt32 mnWarnCount;

    bool noErrors() const { return !mnErrCount && !mnFatalCount && !mnWarnCount; }

    ErrorHandler() : mnErrCount(0), mnFatalCount(0), mnWarnCount(0)
    {}

    virtual void SAL_CALL error( const uno::Any& ) throw (xml::sax::SAXException, uno::RuntimeException)
    {
        ++mnErrCount;
    }

    virtual void SAL_CALL fatalError( const uno::Any& ) throw (xml::sax::SAXException, uno::RuntimeException)
    {
        ++mnFatalCount;
    }

    virtual void SAL_CALL warning( const uno::Any& ) throw (xml::sax::SAXException, uno::RuntimeException)
    {
        ++mnWarnCount;
    }
};

struct DocumentHandler
    : public ::cppu::WeakImplHelper1< xml::sax::XFastDocumentHandler >
{
    // XFastContextHandler
    virtual void SAL_CALL startFastElement( ::sal_Int32 Element, const uno::Reference< xml::sax::XFastAttributeList >& Attribs ) throw (xml::sax::SAXException, uno::RuntimeException)
    {
        OSL_TRACE("Seen element: %c with namespace 0x%x",
                  Element & 0xFFFF, Element & 0xFFFF0000);
    }

    virtual void SAL_CALL startUnknownElement( const ::rtl::OUString& Namespace, const ::rtl::OUString& Name, const uno::Reference< xml::sax::XFastAttributeList >& Attribs ) throw (xml::sax::SAXException, uno::RuntimeException)
    {
    }

    virtual void SAL_CALL endFastElement( ::sal_Int32 Element ) throw (xml::sax::SAXException, uno::RuntimeException)
    {
    }

    virtual void SAL_CALL endUnknownElement( const ::rtl::OUString& Namespace, const ::rtl::OUString& Name ) throw (xml::sax::SAXException, uno::RuntimeException)
    {
    }

    virtual uno::Reference< xml::sax::XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 Element, const uno::Reference< xml::sax::XFastAttributeList >& Attribs ) throw (xml::sax::SAXException, uno::RuntimeException)
    {
        return this;
    }

    virtual uno::Reference< xml::sax::XFastContextHandler > SAL_CALL createUnknownChildContext( const ::rtl::OUString& Namespace, const ::rtl::OUString& Name, const uno::Reference< xml::sax::XFastAttributeList >& Attribs ) throw (xml::sax::SAXException, uno::RuntimeException)
    {
        return this;
    }

    virtual void SAL_CALL characters( const ::rtl::OUString& aChars ) throw (xml::sax::SAXException, uno::RuntimeException)
    {
    }

    // XFastDocumentHandler
    virtual void SAL_CALL startDocument(  ) throw (xml::sax::SAXException, uno::RuntimeException)
    {
    }

    virtual void SAL_CALL endDocument(  ) throw (xml::sax::SAXException, uno::RuntimeException)
    {
    }

    virtual void SAL_CALL setDocumentLocator( const uno::Reference< xml::sax::XLocator >& xLocator ) throw (xml::sax::SAXException, uno::RuntimeException)
    {
    }
};

struct TokenHandler
    : public ::cppu::WeakImplHelper1< xml::sax::XFastTokenHandler >
{
    virtual ::sal_Int32 SAL_CALL getToken( const ::rtl::OUString& Identifier ) throw (uno::RuntimeException)
    {
        CPPUNIT_ASSERT_MESSAGE( "TokenHandler::getToken() unexpected call",
                                false );
        return -1;
    }

    virtual ::rtl::OUString SAL_CALL getIdentifier( ::sal_Int32 Token ) throw (uno::RuntimeException)
    {
        CPPUNIT_ASSERT_MESSAGE( "TokenHandler::getIdentifier() unexpected call",
                                false );
        return rtl::OUString();
    }

    virtual ::sal_Int32 SAL_CALL getTokenFromUTF8( const uno::Sequence< ::sal_Int8 >& Identifier ) throw (uno::RuntimeException)
    {
        OSL_TRACE("getTokenFromUTF8() %s", (const char*)Identifier.getConstArray());
        return Identifier.getLength() ? Identifier[0] : 0;
    }

    virtual uno::Sequence< ::sal_Int8 > SAL_CALL getUTF8Identifier( ::sal_Int32 Token ) throw (uno::RuntimeException)
    {
        CPPUNIT_ASSERT_MESSAGE( "TokenHandler::getUTF8Identifier() unexpected call",
                                false );
        return uno::Sequence<sal_Int8>();
    }
};

struct BasicTest : public CppUnit::TestFixture
{
    rtl::Reference<CDocumentBuilder>    mxDomBuilder;
    rtl::Reference<ErrorHandler>        mxErrHandler;
    rtl::Reference<SequenceInputStream> mxValidInStream;
    rtl::Reference<SequenceInputStream> mxWarningInStream;
    rtl::Reference<SequenceInputStream> mxErrorInStream;
    rtl::Reference<SequenceInputStream> mxFatalInStream;

    void setUp()
    {
        // luckily, DOM builder doesn't use service fac, so we need
        // not bootstrap uno here
        mxErrHandler.set( new ErrorHandler() );
        mxDomBuilder.set( new CDocumentBuilder(Reference< XMultiServiceFactory >() ));
        mxValidInStream.set( new SequenceInputStream(ByteSequence((sal_Int8*)validTestFile,
                                                                  SAL_N_ELEMENTS(validTestFile))) );
        mxWarningInStream.set( new SequenceInputStream(ByteSequence((sal_Int8*)warningTestFile,
                                                                    SAL_N_ELEMENTS(warningTestFile))) );
        mxErrorInStream.set( new SequenceInputStream(ByteSequence((sal_Int8*)errorTestFile,
                                                                  SAL_N_ELEMENTS(errorTestFile))) );
        mxFatalInStream.set( new SequenceInputStream(ByteSequence((sal_Int8*)fatalTestFile,
                                                                  SAL_N_ELEMENTS(fatalTestFile))) );
        mxDomBuilder->setErrorHandler(mxErrHandler.get());
    }

    void validInputTest()
    {
        CPPUNIT_ASSERT_MESSAGE( "Valid input file did not result in XDocument #1",
                                mxDomBuilder->parse(
                                    uno::Reference<io::XInputStream>(
                                        mxValidInStream.get())).is() );
        CPPUNIT_ASSERT_MESSAGE( "Valid input file resulted in parse errors",
                                mxErrHandler->noErrors() );
    }

    void warningInputTest()
    {
        CPPUNIT_ASSERT_MESSAGE( "Valid input file did not result in XDocument #2",
                                mxDomBuilder->parse(
                                    uno::Reference<io::XInputStream>(
                                        mxWarningInStream.get())).is() );
        CPPUNIT_ASSERT_MESSAGE( "No parse warnings in unclean input file",
                                mxErrHandler->mnWarnCount && !mxErrHandler->mnErrCount && !mxErrHandler->mnFatalCount );
    }

    void errorInputTest()
    {
        CPPUNIT_ASSERT_MESSAGE( "Valid input file did not result in XDocument #3",
                                mxDomBuilder->parse(
                                    uno::Reference<io::XInputStream>(
                                        mxErrorInStream.get())).is() );
        CPPUNIT_ASSERT_MESSAGE( "No parse errors in unclean input file",
                                !mxErrHandler->mnWarnCount && mxErrHandler->mnErrCount && !mxErrHandler->mnFatalCount );
    }

    void fatalInputTest()
    {
        CPPUNIT_ASSERT_MESSAGE( "Broken input file resulted in XDocument",
                                !mxDomBuilder->parse(
                                    uno::Reference<io::XInputStream>(
                                        mxFatalInStream.get())).is() );
        CPPUNIT_ASSERT_MESSAGE( "No fatal parse errors in unclean input file",
                                !mxErrHandler->mnWarnCount && !mxErrHandler->mnErrCount && mxErrHandler->mnFatalCount );
    };

    // Change the following lines only, if you add, remove or rename
    // member functions of the current class,
    // because these macros are need by auto register mechanism.
    CPPUNIT_TEST_SUITE(BasicTest);
    CPPUNIT_TEST(validInputTest);
    CPPUNIT_TEST(warningInputTest);
    CPPUNIT_TEST(errorInputTest);
    CPPUNIT_TEST(fatalInputTest);
    CPPUNIT_TEST_SUITE_END();
};

struct SerializerTest : public CppUnit::TestFixture
{
    SerializerTest() : mbUnoInitialized(false) {}

    uno::Reference<uno::XComponentContext>                   mxCtx;
    rtl::Reference<CDocumentBuilder>                         mxDomBuilder;
    rtl::Reference<ErrorHandler>                             mxErrHandler;
    rtl::Reference<SequenceInputStream>                      mxInStream;
    rtl::Reference<DocumentHandler>                          mxHandler;
    rtl::Reference<TokenHandler>                             mxTokHandler;
    uno::Sequence< beans::Pair< rtl::OUString, sal_Int32 > > maRegisteredNamespaces;
    bool                                                     mbUnoInitialized;

    void setUp()
    {
        // need working typelib, bootstrap UNO now
        if( !mbUnoInitialized )
        {
            const char* pArgs( getForwardString() );
            CPPUNIT_ASSERT_MESSAGE("Test file parameter", pArgs);

            const rtl::OUString sBaseDir=rtl::OUString::createFromAscii(pArgs);

            // bootstrap UNO
            try
            {
                ::rtl::OUString aIniUrl;
                CPPUNIT_ASSERT_MESSAGE(
                    "Converting ini file to URL",
                    osl_getFileURLFromSystemPath(
                        (sBaseDir+rtl::"unoxml_unittest_test.ini").pData,
                        &aIniUrl.pData ) == osl_File_E_None );

                mxCtx = ::cppu::defaultBootstrap_InitialComponentContext(aIniUrl);
                CPPUNIT_ASSERT_MESSAGE("Getting component context", mxCtx.is());
            }
            catch( uno::Exception& )
            {
                CPPUNIT_ASSERT_MESSAGE("Bootstrapping UNO", false);
            }

            mbUnoInitialized = true;
        }

        mxErrHandler.set( new ErrorHandler() );
        mxDomBuilder.set( new CDocumentBuilder(
                              uno::Reference< lang::XMultiServiceFactory >(
                                  mxCtx->getServiceManager(),
                                  uno::UNO_QUERY )));
        mxInStream.set( new SequenceInputStream(ByteSequence((sal_Int8*)validTestFile,
                                                             SAL_N_ELEMENTS(validTestFile))) );
        mxDomBuilder->setErrorHandler(mxErrHandler.get());

        mxHandler.set( new DocumentHandler() );
        mxTokHandler.set( new TokenHandler() );

        maRegisteredNamespaces.realloc(2);
        maRegisteredNamespaces[0] = beans::make_Pair(
            rtl::OUString(
                RTL_CONSTASCII_USTRINGPARAM(
                    "urn:oasis:names:tc:opendocument:xmlns:office:1.0") ),
            xml::sax::FastToken::NAMESPACE);
        maRegisteredNamespaces[1] = beans::make_Pair(
            rtl::OUString(
                RTL_CONSTASCII_USTRINGPARAM(
                    "http://www.w3.org/1999/xlink") ),
            2*xml::sax::FastToken::NAMESPACE);
    }

    void serializerTest ()
    {
        uno::Reference< xml::dom::XDocument > xDoc=
            mxDomBuilder->parse(
                uno::Reference<io::XInputStream>(
                    mxInStream.get()));
        CPPUNIT_ASSERT_MESSAGE( "Valid input file did not result in XDocument",
                                xDoc.is() );
        CPPUNIT_ASSERT_MESSAGE( "Valid input file resulted in parse errors",
                                mxErrHandler->noErrors() );

        uno::Reference< xml::sax::XSAXSerializable > xSaxSerializer(
            xDoc, uno::UNO_QUERY);
        CPPUNIT_ASSERT_MESSAGE( "XSAXSerializable not supported",
                                xSaxSerializer.is() );

        uno::Reference< xml::sax::XFastSAXSerializable > xFastSaxSerializer(
            xDoc, uno::UNO_QUERY);
        CPPUNIT_ASSERT_MESSAGE( "XFastSAXSerializable not supported",
                                xSaxSerializer.is() );

        xFastSaxSerializer->fastSerialize( mxHandler.get(),
                                           mxTokHandler.get(),
                                           uno::Sequence< beans::StringPair >(),
                                           maRegisteredNamespaces );
    }

    // Change the following lines only, if you add, remove or rename
    // member functions of the current class,
    // because these macros are need by auto register mechanism.

    CPPUNIT_TEST_SUITE(SerializerTest);
    CPPUNIT_TEST(serializerTest);
    CPPUNIT_TEST_SUITE_END();
};

// -----------------------------------------------------------------------------
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(BasicTest, "BasicTest");
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(SerializerTest, "SerializerTest");
}

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

// this macro creates an empty function, which will called by the RegisterAllFunctions()
// to let the user the possibility to also register some functions by hand.
NOADDITIONAL;

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>targeted string re-work<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * 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.
 *
 ************************************************************************/

// autogenerated file with codegen.pl

#include <testshl/simpleheader.hxx>

#include <rtl/ref.hxx>
#include <osl/file.hxx>
#include <osl/process.h>
#include <comphelper/seqstream.hxx>
#include <comphelper/sequence.hxx>
#include <cppuhelper/compbase1.hxx>
#include <cppuhelper/bootstrap.hxx>
#include <cppuhelper/basemutex.hxx>

#include <com/sun/star/xml/sax/FastToken.hpp>
#include <com/sun/star/xml/sax/XSAXSerializable.hpp>
#include <com/sun/star/xml/sax/XFastSAXSerializable.hpp>

#include "../source/dom/documentbuilder.hxx"

using namespace ::DOM;
using namespace ::comphelper;
using namespace ::com::sun::star;

namespace
{

// valid xml
static const char validTestFile[] =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?> \
 <office:document-content \
   xmlns:office=\"urn:oasis:names:tc:opendocument:xmlns:office:1.0\" \
   xmlns:xlink=\"http://www.w3.org/1999/xlink\" \
   office:version=\"1.0\"> \
   <office:scripts/> \
   <xlink:test/> \
   <office:automatic-styles teststyle=\"test\"/> \
   <moretest/> \
    some text öäü \
 </office:document-content> \
";

// generates a warning: unsupported xml version, unknown xml:space
// value
static const char warningTestFile[] =
"<?xml version=\"47-11.0\" encoding=\"UTF-8\"?> \
 <office:document-content \
   xmlns:office=\"urn:oasis:names:tc:opendocument:xmlns:office:1.0\" \
   xml:space=\"blafasl\" \
   office:version=\"1.0\"> \
   <office:scripts/> \
   <office:automatic-styles/> \
 </office:document-content> \
";

// <?xml not at start of file
static const char errorTestFile[] =
" <?xml version=\"1.0\" encoding=\"UTF-8\"?> \
 <office:document-content \
   xmlns:office=\"urn:oasis:names:tc:opendocument:xmlns:office:1.0\" \
   office:version=\"1.0\"> \
   <office:scripts/> \
   <office:automatic-styles/> \
 </office:document-content> \
";

// plain empty
static const char fatalTestFile[] = "";

struct ErrorHandler
    : public ::cppu::WeakImplHelper1< xml::sax::XErrorHandler >
{
    sal_uInt32 mnErrCount;
    sal_uInt32 mnFatalCount;
    sal_uInt32 mnWarnCount;

    bool noErrors() const { return !mnErrCount && !mnFatalCount && !mnWarnCount; }

    ErrorHandler() : mnErrCount(0), mnFatalCount(0), mnWarnCount(0)
    {}

    virtual void SAL_CALL error( const uno::Any& ) throw (xml::sax::SAXException, uno::RuntimeException)
    {
        ++mnErrCount;
    }

    virtual void SAL_CALL fatalError( const uno::Any& ) throw (xml::sax::SAXException, uno::RuntimeException)
    {
        ++mnFatalCount;
    }

    virtual void SAL_CALL warning( const uno::Any& ) throw (xml::sax::SAXException, uno::RuntimeException)
    {
        ++mnWarnCount;
    }
};

struct DocumentHandler
    : public ::cppu::WeakImplHelper1< xml::sax::XFastDocumentHandler >
{
    // XFastContextHandler
    virtual void SAL_CALL startFastElement( ::sal_Int32 Element, const uno::Reference< xml::sax::XFastAttributeList >& Attribs ) throw (xml::sax::SAXException, uno::RuntimeException)
    {
        OSL_TRACE("Seen element: %c with namespace 0x%x",
                  Element & 0xFFFF, Element & 0xFFFF0000);
    }

    virtual void SAL_CALL startUnknownElement( const ::rtl::OUString& Namespace, const ::rtl::OUString& Name, const uno::Reference< xml::sax::XFastAttributeList >& Attribs ) throw (xml::sax::SAXException, uno::RuntimeException)
    {
    }

    virtual void SAL_CALL endFastElement( ::sal_Int32 Element ) throw (xml::sax::SAXException, uno::RuntimeException)
    {
    }

    virtual void SAL_CALL endUnknownElement( const ::rtl::OUString& Namespace, const ::rtl::OUString& Name ) throw (xml::sax::SAXException, uno::RuntimeException)
    {
    }

    virtual uno::Reference< xml::sax::XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 Element, const uno::Reference< xml::sax::XFastAttributeList >& Attribs ) throw (xml::sax::SAXException, uno::RuntimeException)
    {
        return this;
    }

    virtual uno::Reference< xml::sax::XFastContextHandler > SAL_CALL createUnknownChildContext( const ::rtl::OUString& Namespace, const ::rtl::OUString& Name, const uno::Reference< xml::sax::XFastAttributeList >& Attribs ) throw (xml::sax::SAXException, uno::RuntimeException)
    {
        return this;
    }

    virtual void SAL_CALL characters( const ::rtl::OUString& aChars ) throw (xml::sax::SAXException, uno::RuntimeException)
    {
    }

    // XFastDocumentHandler
    virtual void SAL_CALL startDocument(  ) throw (xml::sax::SAXException, uno::RuntimeException)
    {
    }

    virtual void SAL_CALL endDocument(  ) throw (xml::sax::SAXException, uno::RuntimeException)
    {
    }

    virtual void SAL_CALL setDocumentLocator( const uno::Reference< xml::sax::XLocator >& xLocator ) throw (xml::sax::SAXException, uno::RuntimeException)
    {
    }
};

struct TokenHandler
    : public ::cppu::WeakImplHelper1< xml::sax::XFastTokenHandler >
{
    virtual ::sal_Int32 SAL_CALL getToken( const ::rtl::OUString& Identifier ) throw (uno::RuntimeException)
    {
        CPPUNIT_ASSERT_MESSAGE( "TokenHandler::getToken() unexpected call",
                                false );
        return -1;
    }

    virtual ::rtl::OUString SAL_CALL getIdentifier( ::sal_Int32 Token ) throw (uno::RuntimeException)
    {
        CPPUNIT_ASSERT_MESSAGE( "TokenHandler::getIdentifier() unexpected call",
                                false );
        return rtl::OUString();
    }

    virtual ::sal_Int32 SAL_CALL getTokenFromUTF8( const uno::Sequence< ::sal_Int8 >& Identifier ) throw (uno::RuntimeException)
    {
        OSL_TRACE("getTokenFromUTF8() %s", (const char*)Identifier.getConstArray());
        return Identifier.getLength() ? Identifier[0] : 0;
    }

    virtual uno::Sequence< ::sal_Int8 > SAL_CALL getUTF8Identifier( ::sal_Int32 Token ) throw (uno::RuntimeException)
    {
        CPPUNIT_ASSERT_MESSAGE( "TokenHandler::getUTF8Identifier() unexpected call",
                                false );
        return uno::Sequence<sal_Int8>();
    }
};

struct BasicTest : public CppUnit::TestFixture
{
    rtl::Reference<CDocumentBuilder>    mxDomBuilder;
    rtl::Reference<ErrorHandler>        mxErrHandler;
    rtl::Reference<SequenceInputStream> mxValidInStream;
    rtl::Reference<SequenceInputStream> mxWarningInStream;
    rtl::Reference<SequenceInputStream> mxErrorInStream;
    rtl::Reference<SequenceInputStream> mxFatalInStream;

    void setUp()
    {
        // luckily, DOM builder doesn't use service fac, so we need
        // not bootstrap uno here
        mxErrHandler.set( new ErrorHandler() );
        mxDomBuilder.set( new CDocumentBuilder(Reference< XMultiServiceFactory >() ));
        mxValidInStream.set( new SequenceInputStream(ByteSequence((sal_Int8*)validTestFile,
                                                                  SAL_N_ELEMENTS(validTestFile))) );
        mxWarningInStream.set( new SequenceInputStream(ByteSequence((sal_Int8*)warningTestFile,
                                                                    SAL_N_ELEMENTS(warningTestFile))) );
        mxErrorInStream.set( new SequenceInputStream(ByteSequence((sal_Int8*)errorTestFile,
                                                                  SAL_N_ELEMENTS(errorTestFile))) );
        mxFatalInStream.set( new SequenceInputStream(ByteSequence((sal_Int8*)fatalTestFile,
                                                                  SAL_N_ELEMENTS(fatalTestFile))) );
        mxDomBuilder->setErrorHandler(mxErrHandler.get());
    }

    void validInputTest()
    {
        CPPUNIT_ASSERT_MESSAGE( "Valid input file did not result in XDocument #1",
                                mxDomBuilder->parse(
                                    uno::Reference<io::XInputStream>(
                                        mxValidInStream.get())).is() );
        CPPUNIT_ASSERT_MESSAGE( "Valid input file resulted in parse errors",
                                mxErrHandler->noErrors() );
    }

    void warningInputTest()
    {
        CPPUNIT_ASSERT_MESSAGE( "Valid input file did not result in XDocument #2",
                                mxDomBuilder->parse(
                                    uno::Reference<io::XInputStream>(
                                        mxWarningInStream.get())).is() );
        CPPUNIT_ASSERT_MESSAGE( "No parse warnings in unclean input file",
                                mxErrHandler->mnWarnCount && !mxErrHandler->mnErrCount && !mxErrHandler->mnFatalCount );
    }

    void errorInputTest()
    {
        CPPUNIT_ASSERT_MESSAGE( "Valid input file did not result in XDocument #3",
                                mxDomBuilder->parse(
                                    uno::Reference<io::XInputStream>(
                                        mxErrorInStream.get())).is() );
        CPPUNIT_ASSERT_MESSAGE( "No parse errors in unclean input file",
                                !mxErrHandler->mnWarnCount && mxErrHandler->mnErrCount && !mxErrHandler->mnFatalCount );
    }

    void fatalInputTest()
    {
        CPPUNIT_ASSERT_MESSAGE( "Broken input file resulted in XDocument",
                                !mxDomBuilder->parse(
                                    uno::Reference<io::XInputStream>(
                                        mxFatalInStream.get())).is() );
        CPPUNIT_ASSERT_MESSAGE( "No fatal parse errors in unclean input file",
                                !mxErrHandler->mnWarnCount && !mxErrHandler->mnErrCount && mxErrHandler->mnFatalCount );
    };

    // Change the following lines only, if you add, remove or rename
    // member functions of the current class,
    // because these macros are need by auto register mechanism.
    CPPUNIT_TEST_SUITE(BasicTest);
    CPPUNIT_TEST(validInputTest);
    CPPUNIT_TEST(warningInputTest);
    CPPUNIT_TEST(errorInputTest);
    CPPUNIT_TEST(fatalInputTest);
    CPPUNIT_TEST_SUITE_END();
};

struct SerializerTest : public CppUnit::TestFixture
{
    SerializerTest() : mbUnoInitialized(false) {}

    uno::Reference<uno::XComponentContext>                   mxCtx;
    rtl::Reference<CDocumentBuilder>                         mxDomBuilder;
    rtl::Reference<ErrorHandler>                             mxErrHandler;
    rtl::Reference<SequenceInputStream>                      mxInStream;
    rtl::Reference<DocumentHandler>                          mxHandler;
    rtl::Reference<TokenHandler>                             mxTokHandler;
    uno::Sequence< beans::Pair< rtl::OUString, sal_Int32 > > maRegisteredNamespaces;
    bool                                                     mbUnoInitialized;

    void setUp()
    {
        // need working typelib, bootstrap UNO now
        if( !mbUnoInitialized )
        {
            const char* pArgs( getForwardString() );
            CPPUNIT_ASSERT_MESSAGE("Test file parameter", pArgs);

            const rtl::OUString sBaseDir=rtl::OUString::createFromAscii(pArgs);

            // bootstrap UNO
            try
            {
                ::rtl::OUString aIniUrl;
                CPPUNIT_ASSERT_MESSAGE(
                    "Converting ini file to URL",
                    osl_getFileURLFromSystemPath(
                        (sBaseDir+rtl::"unoxml_unittest_test.ini").pData,
                        &aIniUrl.pData ) == osl_File_E_None );

                mxCtx = ::cppu::defaultBootstrap_InitialComponentContext(aIniUrl);
                CPPUNIT_ASSERT_MESSAGE("Getting component context", mxCtx.is());
            }
            catch( uno::Exception& )
            {
                CPPUNIT_ASSERT_MESSAGE("Bootstrapping UNO", false);
            }

            mbUnoInitialized = true;
        }

        mxErrHandler.set( new ErrorHandler() );
        mxDomBuilder.set( new CDocumentBuilder(
                              uno::Reference< lang::XMultiServiceFactory >(
                                  mxCtx->getServiceManager(),
                                  uno::UNO_QUERY )));
        mxInStream.set( new SequenceInputStream(ByteSequence((sal_Int8*)validTestFile,
                                                             SAL_N_ELEMENTS(validTestFile))) );
        mxDomBuilder->setErrorHandler(mxErrHandler.get());

        mxHandler.set( new DocumentHandler() );
        mxTokHandler.set( new TokenHandler() );

        maRegisteredNamespaces.realloc(2);
        maRegisteredNamespaces[0] = beans::make_Pair(
            rtl::OUString( "urn:oasis:names:tc:opendocument:xmlns:office:1.0" ),
            xml::sax::FastToken::NAMESPACE);
        maRegisteredNamespaces[1] = beans::make_Pair(
            rtl::OUString( "http://www.w3.org/1999/xlink" ),
            2*xml::sax::FastToken::NAMESPACE);
    }

    void serializerTest ()
    {
        uno::Reference< xml::dom::XDocument > xDoc=
            mxDomBuilder->parse(
                uno::Reference<io::XInputStream>(
                    mxInStream.get()));
        CPPUNIT_ASSERT_MESSAGE( "Valid input file did not result in XDocument",
                                xDoc.is() );
        CPPUNIT_ASSERT_MESSAGE( "Valid input file resulted in parse errors",
                                mxErrHandler->noErrors() );

        uno::Reference< xml::sax::XSAXSerializable > xSaxSerializer(
            xDoc, uno::UNO_QUERY);
        CPPUNIT_ASSERT_MESSAGE( "XSAXSerializable not supported",
                                xSaxSerializer.is() );

        uno::Reference< xml::sax::XFastSAXSerializable > xFastSaxSerializer(
            xDoc, uno::UNO_QUERY);
        CPPUNIT_ASSERT_MESSAGE( "XFastSAXSerializable not supported",
                                xSaxSerializer.is() );

        xFastSaxSerializer->fastSerialize( mxHandler.get(),
                                           mxTokHandler.get(),
                                           uno::Sequence< beans::StringPair >(),
                                           maRegisteredNamespaces );
    }

    // Change the following lines only, if you add, remove or rename
    // member functions of the current class,
    // because these macros are need by auto register mechanism.

    CPPUNIT_TEST_SUITE(SerializerTest);
    CPPUNIT_TEST(serializerTest);
    CPPUNIT_TEST_SUITE_END();
};

// -----------------------------------------------------------------------------
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(BasicTest, "BasicTest");
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(SerializerTest, "SerializerTest");
}

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

// this macro creates an empty function, which will called by the RegisterAllFunctions()
// to let the user the possibility to also register some functions by hand.
NOADDITIONAL;

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>/*
 * Unit tests for the Raft library.
 *
 * Copyright (C) 2017 Nextworks
 * Author: Vincenzo Maffione <v.maffione@gmail.com>
 *
 * This file is part of rlite.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
 */

#include <iostream>
#include <list>
#include <string>
#include <cstdint>
#include <cassert>
#include <cstring>
#include <functional>
#include <queue>
#include <random>
#include <ctime>

#include "rlite/raft.hpp"

using namespace std;

struct TestLogEntry : public RaftLogEntry {
    uint32_t command;

    void serialize(char *serbuf) const override
    {
        memcpy(serbuf, reinterpret_cast<const char *>(&term), sizeof(term));
        memcpy(serbuf, reinterpret_cast<const char *>(&command),
               sizeof(command));
    }

    static size_t size() { return sizeof(Term) + sizeof(uint32_t); }
};

static string
logfile(const string &replica)
{
    return string("/tmp/raft_test_") + replica + "_log";
}

struct TestReplica {
    RaftSM *sm = nullptr;

    TestReplica() = default;
    TestReplica(RaftSM *_sm) : sm(_sm) {}
    ~TestReplica()
    {
        if (sm) {
            delete sm;
        }
    }
};

struct TestEvent {
    unsigned int abstime = 0;
    RaftSM *sm           = nullptr;
    RaftTimerType ttype  = RaftTimerType::Invalid;

    TestEvent(unsigned int t, RaftSM *_sm, RaftTimerType ty)
        : abstime(t), sm(_sm), ttype(ty)
    {
    }

    bool operator<(const TestEvent &o) const { /* Inverted logic. */
                                               return abstime >= o.abstime; }
    bool operator>=(const TestEvent &o) const { return !(*this < o); }
};

int
main()
{
    list<string> names = {"r1", "r2", "r3", "r4", "r5"};
    map<string, TestReplica *> replicas;
    priority_queue<TestEvent> events;
    unsigned int t = 0; /* time */
    RaftSMOutput output;

    srand(time(0));

    /* Clean up leftover logfiles, if any. */
    for (const auto &local : names) {
        remove(logfile(local).c_str());
    }

    for (const auto &local : names) {
        string logfilename = logfile(local);
        list<string> peers;
        RaftSM *sm;

        for (const auto &peer : names) {
            if (peer != local) {
                peers.push_back(peer);
            }
        }

        sm = new RaftSM(local + "-sm", local, logfilename, TestLogEntry::size(),
                        std::cerr, std::cout);
        if (sm->init(peers, &output)) {
            goto out;
        }
        replicas[local] = new TestReplica(sm);
    }

    for (;;) {
        /* Process timer commands. */
        for (const RaftTimerCmd &cmd : output.timer_commands) {
            if (cmd.action == RaftTimerAction::Set) {
                events.push(TestEvent(t + cmd.milliseconds, cmd.sm, cmd.type));
            }
        }

        /* Process output messages. */
        for (const auto &p : output.output_messages) {
            auto *rv  = dynamic_cast<RaftRequestVote *>(p.second);
            auto *rvr = dynamic_cast<RaftRequestVoteResp *>(p.second);
            auto *ae  = dynamic_cast<RaftAppendEntries *>(p.second);
            auto *aer = dynamic_cast<RaftAppendEntriesResp *>(p.second);

            assert(replicas.count(p.first));
            if (rv) {
                replicas[p.first]->sm->request_vote_input(*rv, &output);
            } else if (rvr) {
                replicas[p.first]->sm->request_vote_resp_input(*rvr, &output);
            } else if (ae) {
                replicas[p.first]->sm->append_entries_input(*ae, &output);
            } else if (aer) {
                replicas[p.first]->sm->append_entries_resp_input(*aer, &output);
            } else {
                assert(false);
            }

            delete p.second;
        }

        /* Extract next expired timer and update the associated
         * Raft state machine. */
        const TestEvent &next = events.top();
        t                     = next.abstime;
        cout << "| t = " << t << " |" << endl;
        next.sm->timer_expired(next.ttype, &output);
        events.pop();

        {
            string input;
            cin >> input;
        }
    }

out:
    for (const auto &kv : replicas) {
        kv.second->sm->shutdown();
        delete kv.second;
    }

    return 0;
}
<commit_msg>lib: raft: add missing cleanup of RaftSMOutput object<commit_after>/*
 * Unit tests for the Raft library.
 *
 * Copyright (C) 2017 Nextworks
 * Author: Vincenzo Maffione <v.maffione@gmail.com>
 *
 * This file is part of rlite.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
 */

#include <iostream>
#include <list>
#include <string>
#include <cstdint>
#include <cassert>
#include <cstring>
#include <functional>
#include <queue>
#include <random>
#include <ctime>

#include "rlite/raft.hpp"

using namespace std;

struct TestLogEntry : public RaftLogEntry {
    uint32_t command;

    void serialize(char *serbuf) const override
    {
        memcpy(serbuf, reinterpret_cast<const char *>(&term), sizeof(term));
        memcpy(serbuf, reinterpret_cast<const char *>(&command),
               sizeof(command));
    }

    static size_t size() { return sizeof(Term) + sizeof(uint32_t); }
};

static string
logfile(const string &replica)
{
    return string("/tmp/raft_test_") + replica + "_log";
}

struct TestReplica {
    RaftSM *sm = nullptr;

    TestReplica() = default;
    TestReplica(RaftSM *_sm) : sm(_sm) {}
    ~TestReplica()
    {
        if (sm) {
            delete sm;
        }
    }
};

struct TestEvent {
    unsigned int abstime = 0;
    RaftSM *sm           = nullptr;
    RaftTimerType ttype  = RaftTimerType::Invalid;

    TestEvent(unsigned int t, RaftSM *_sm, RaftTimerType ty)
        : abstime(t), sm(_sm), ttype(ty)
    {
    }

    bool operator<(const TestEvent &o) const { /* Inverted logic. */
                                               return abstime >= o.abstime; }
    bool operator>=(const TestEvent &o) const { return !(*this < o); }
};

int
main()
{
    list<string> names = {"r1", "r2", "r3", "r4", "r5"};
    map<string, TestReplica *> replicas;
    priority_queue<TestEvent> events;
    unsigned int t = 0; /* time */
    RaftSMOutput output;

    srand(time(0));

    /* Clean up leftover logfiles, if any. */
    for (const auto &local : names) {
        remove(logfile(local).c_str());
    }

    for (const auto &local : names) {
        string logfilename = logfile(local);
        list<string> peers;
        RaftSM *sm;

        for (const auto &peer : names) {
            if (peer != local) {
                peers.push_back(peer);
            }
        }

        sm = new RaftSM(local + "-sm", local, logfilename, TestLogEntry::size(),
                        std::cerr, std::cout);
        if (sm->init(peers, &output)) {
            goto out;
        }
        replicas[local] = new TestReplica(sm);
    }

    for (;;) {
        /* Process timer commands. */
        for (const RaftTimerCmd &cmd : output.timer_commands) {
            if (cmd.action == RaftTimerAction::Set) {
                events.push(TestEvent(t + cmd.milliseconds, cmd.sm, cmd.type));
            }
        }
        output.timer_commands.clear();

        /* Process output messages. */
        for (const auto &p : output.output_messages) {
            auto *rv  = dynamic_cast<RaftRequestVote *>(p.second);
            auto *rvr = dynamic_cast<RaftRequestVoteResp *>(p.second);
            auto *ae  = dynamic_cast<RaftAppendEntries *>(p.second);
            auto *aer = dynamic_cast<RaftAppendEntriesResp *>(p.second);

            assert(replicas.count(p.first));
            if (rv) {
                replicas[p.first]->sm->request_vote_input(*rv, &output);
            } else if (rvr) {
                replicas[p.first]->sm->request_vote_resp_input(*rvr, &output);
            } else if (ae) {
                replicas[p.first]->sm->append_entries_input(*ae, &output);
            } else if (aer) {
                replicas[p.first]->sm->append_entries_resp_input(*aer, &output);
            } else {
                assert(false);
            }

            delete p.second;
        }
        output.output_messages.clear();

        /* Extract next expired timer and update the associated
         * Raft state machine. */
        const TestEvent &next = events.top();
        t                     = next.abstime;
        cout << "| t = " << t << " |" << endl;
        next.sm->timer_expired(next.ttype, &output);
        events.pop();

        {
            string input;
            cin >> input;
        }
    }

out:
    for (const auto &kv : replicas) {
        kv.second->sm->shutdown();
        delete kv.second;
    }

    return 0;
}
<|endoftext|>


<commit_before>          // can be just the necessary schema
  class {{tupletypename}} {
    // Invariant: data stored in _fields is always in the representation
    // specified by _scheme.

    public:
    {% for ft in fieldtypes %}
        {{ft}} f{{loop.index - 1}};
    {% endfor %}

    static constexpr int numFields() {
      return {{numfields}};
    }

    // size of all fields in struct removing only end padding
    static size_t fieldsSize() {
        const {{tupletypename}} _t;
        return

        {% if numfields == 1 %}
            sizeof(_t.f0);
         {% else %}
            ((char*)&_t.f{{numfields-1}}) + sizeof(_t.f{{numfields-1}}) - ((char*)&_t);
         {% endif %}
    }

    {{tupletypename}} () {
      // no-op
    }

    //template <typename OT>
    //{{tupletypename}} (const OT& other) {
    //  std::memcpy(this, &other, sizeof({{tupletypename}}));
    //}
    {{tupletypename}} ({% for ft in fieldtypes %}
                               const {{ft}}& a{{loop.index-1}}
                               {% if not loop.last %},{% endif %}
                       {% endfor %}
                       ) {
        {% for i in range(numfields) %}
            f{{i}} = a{{i}};
        {% endfor %}
    }

    {# list of types comma separated #}
    {# TODO: uncomment when jinja 2.8 is released with support for set blocks
    {% set types_comma %}
        {% for ft in fieldtypes %}
        {{ft}}
        {% if not loop.last %},{% endif %}
        {% endfor %}
    {% endset %}
    #}

    {{tupletypename}}(const std::tuple<
        {% for ft in fieldtypes %}
        {{ft}}
        {% if not loop.last %},{% endif %}
        {% endfor %}
            >& o) {
        {% for i in range(numfields) %}
            f{{i}} = std::get<{{i}}>(o);
        {% endfor %}
     }

     std::tuple<
        {% for ft in fieldtypes %}
        {{ft}}
        {% if not loop.last %},{% endif %}
        {% endfor %}
     > to_tuple() {

        std::tuple<
        {% for ft in fieldtypes %}
        {{ft}}
        {% if not loop.last %},{% endif %}
        {% endfor %}
        > r;
        {% for i in range(numfields) %}
            std::get<{{i}}>(r) = f{{i}};
        {% endfor %}
        return r;
     }

    // shamelessly terrible disambiguation: one solution is named factory methods
    //{{tupletypename}} (std::vector<int64_t> vals, bool ignore1, bool ignore2) {
    //    {% for i in range(numfields) %}
    //        f{{i}} = vals[{{i}}];
    //    {% endfor %}
    //}

    // use the tuple schema to interpret the input stream
    static {{tupletypename}} fromIStream(std::istream& ss, char delim=' ') {
        {{tupletypename}} _ret;

        {% for i in range(numfields) %}
            {% if fieldtypes[i] == string_type_name %}
               {
               std::string _temp;
               std::getline(ss, _temp, delim);
               _ret.f{{i}} = to_array<MAX_STR_LEN, std::string>(_temp);
               }
            {% else %}
               {
               // use operator>> to parse into proper numeric type
               ss >> _ret.f{{i}};
               //throw away the next delimiter
               std::string _temp;
               std::getline(ss, _temp, delim);
               }
            {% endif %}
        {% endfor %}

        return _ret;
    }

    void toOStream(std::ostream& os) const {
       {% for i in range(numfields) %}
         {% if fieldtypes[i] == string_type_name %}
            os.write(f{{i}}.data(), (size_t)MAX_STR_LEN * sizeof(char));
            os.seekp(std::max(MAX_STR_LEN-f{{i}}.size(), (size_t)0), std::ios_base::cur);
         {% else %}
            os.write((char*)&f{{i}}, sizeof({{fieldtypes[i]}}));
         {% endif %}
       {% endfor %}
    }

    void toOStreamAscii(std::ostream& os) const {
        os
        {% for i in range(numfields-1) %}
        << f{{i}} << " "
        {% endfor %}
        << f{{numfields-1}} << std::endl;
    }

    //template <typename Tuple, typename T>
    //{{tupletypename}} (const Tuple& v0, const T& from) {
    //    constexpr size_t v0_size = std::tuple_size<Tuple>::value;
    //    constexpr int from_size = T::numFields();
    //    static_assert({{tupletypename}}::numFields() == (v0_size + from_size), "constructor only works on same number of total fields");
    //    TupleUtils::assign<0, decltype(_scheme)>(_fields, v0);
    //    std::memcpy(((char*)&_fields)+v0_size*sizeof(int64_t), &(from._fields), from_size*sizeof(int64_t));
    //}

    //template <typename Tuple>
    //{{tupletypename}} (const Tuple& v0) {
    //    static_assert({{tupletypename}}::numFields() == (std::tuple_size<Tuple>::value), "constructor only works on same number of total fields");
    //    TupleUtils::assign<0, decltype(_scheme)>(_fields, v0);
    //}

    std::ostream& dump(std::ostream& o) const {
      o << "Materialized(";

      {% for i in range(numfields) %}
        o << f{{i}} << ",";
      {% endfor %}

      o << ")";
      return o;
    }

    {{additional_code}}
  } {{after_def_code}};

  std::ostream& operator<< (std::ostream& o, const {{tupletypename}}& t) {
    return t.dump(o);
  }

<commit_msg>writing must also change<commit_after>          // can be just the necessary schema
  class {{tupletypename}} {
    // Invariant: data stored in _fields is always in the representation
    // specified by _scheme.

    public:
    {% for ft in fieldtypes %}
        {{ft}} f{{loop.index - 1}};
    {% endfor %}

    static constexpr int numFields() {
      return {{numfields}};
    }

    // size of all fields in struct removing only end padding
    static size_t fieldsSize() {
        const {{tupletypename}} _t;
        return

        {% if numfields == 1 %}
            sizeof(_t.f0);
         {% else %}
            ((char*)&_t.f{{numfields-1}}) + sizeof(_t.f{{numfields-1}}) - ((char*)&_t);
         {% endif %}
    }

    {{tupletypename}} () {
      // no-op
    }

    //template <typename OT>
    //{{tupletypename}} (const OT& other) {
    //  std::memcpy(this, &other, sizeof({{tupletypename}}));
    //}
    {{tupletypename}} ({% for ft in fieldtypes %}
                               const {{ft}}& a{{loop.index-1}}
                               {% if not loop.last %},{% endif %}
                       {% endfor %}
                       ) {
        {% for i in range(numfields) %}
            f{{i}} = a{{i}};
        {% endfor %}
    }

    {# list of types comma separated #}
    {# TODO: uncomment when jinja 2.8 is released with support for set blocks
    {% set types_comma %}
        {% for ft in fieldtypes %}
        {{ft}}
        {% if not loop.last %},{% endif %}
        {% endfor %}
    {% endset %}
    #}

    {{tupletypename}}(const std::tuple<
        {% for ft in fieldtypes %}
        {{ft}}
        {% if not loop.last %},{% endif %}
        {% endfor %}
            >& o) {
        {% for i in range(numfields) %}
            f{{i}} = std::get<{{i}}>(o);
        {% endfor %}
     }

     std::tuple<
        {% for ft in fieldtypes %}
        {{ft}}
        {% if not loop.last %},{% endif %}
        {% endfor %}
     > to_tuple() {

        std::tuple<
        {% for ft in fieldtypes %}
        {{ft}}
        {% if not loop.last %},{% endif %}
        {% endfor %}
        > r;
        {% for i in range(numfields) %}
            std::get<{{i}}>(r) = f{{i}};
        {% endfor %}
        return r;
     }

    // shamelessly terrible disambiguation: one solution is named factory methods
    //{{tupletypename}} (std::vector<int64_t> vals, bool ignore1, bool ignore2) {
    //    {% for i in range(numfields) %}
    //        f{{i}} = vals[{{i}}];
    //    {% endfor %}
    //}

    // use the tuple schema to interpret the input stream
    static {{tupletypename}} fromIStream(std::istream& ss, char delim=' ') {
        {{tupletypename}} _ret;

        {% for i in range(numfields) %}
            {% if fieldtypes[i] == string_type_name %}
               {
               std::string _temp;
               std::getline(ss, _temp, delim);
               _ret.f{{i}} = to_array<MAX_STR_LEN, std::string>(_temp);
               }
            {% else %}
               {
               // use operator>> to parse into proper numeric type
               ss >> _ret.f{{i}};
               //throw away the next delimiter
               std::string _temp;
               std::getline(ss, _temp, delim);
               }
            {% endif %}
        {% endfor %}

        return _ret;
    }

    void toOStream(std::ostream& os) const {
        os.write((char*)this, this->fieldsSize());
    }

    void toOStreamAscii(std::ostream& os) const {
        os
        {% for i in range(numfields-1) %}
        << f{{i}} << " "
        {% endfor %}
        << f{{numfields-1}} << std::endl;
    }

    //template <typename Tuple, typename T>
    //{{tupletypename}} (const Tuple& v0, const T& from) {
    //    constexpr size_t v0_size = std::tuple_size<Tuple>::value;
    //    constexpr int from_size = T::numFields();
    //    static_assert({{tupletypename}}::numFields() == (v0_size + from_size), "constructor only works on same number of total fields");
    //    TupleUtils::assign<0, decltype(_scheme)>(_fields, v0);
    //    std::memcpy(((char*)&_fields)+v0_size*sizeof(int64_t), &(from._fields), from_size*sizeof(int64_t));
    //}

    //template <typename Tuple>
    //{{tupletypename}} (const Tuple& v0) {
    //    static_assert({{tupletypename}}::numFields() == (std::tuple_size<Tuple>::value), "constructor only works on same number of total fields");
    //    TupleUtils::assign<0, decltype(_scheme)>(_fields, v0);
    //}

    std::ostream& dump(std::ostream& o) const {
      o << "Materialized(";

      {% for i in range(numfields) %}
        o << f{{i}} << ",";
      {% endfor %}

      o << ")";
      return o;
    }

    {{additional_code}}
  } {{after_def_code}};

  std::ostream& operator<< (std::ostream& o, const {{tupletypename}}& t) {
    return t.dump(o);
  }

<|endoftext|>


<commit_before>#ifndef __MESSAGES_HPP_INCLUDED__
#define __MESSAGES_HPP_INCLUDED__

#include <decree.hpp>
#include <replicaset.hpp>

enum class MessageType
{
    RequestMessage,
    PrepareMessage,
    PromiseMessage,
    AcceptMessage,
    AcceptedMessage,
    UpdateMessage,
    UpdatedMessage
};

struct MessageTypeHash
{
    template <typename T>
    std::size_t operator()(T t) const
    {
        return static_cast<std::size_t>(t);
    }
};

struct Message
{
    Decree decree;
    Replica from;
    Replica to;
    MessageType type;

    Message()
        : decree(), from(), to(), type()
    {
    }

    Message(Decree d, Replica f, Replica t, MessageType mtype)
        : decree(d), from(f), to(t), type(mtype)
    {
    }
};

Message Response(Message message, MessageType type);

#endif
<commit_msg>Add comments to message types<commit_after>#ifndef __MESSAGES_HPP_INCLUDED__
#define __MESSAGES_HPP_INCLUDED__

#include <decree.hpp>
#include <replicaset.hpp>

enum class MessageType
{
    //
    // RequestMessage sent when there is a new proposal.
    //
    RequestMessage,

    //
    // PrepareMessage sent to signal beginning of a round of paxos.
    //
    PrepareMessage,

    //
    // PromiseMessage sent to acknowledge a prepare.
    //
    PromiseMessage,

    //
    // AcceptMessage sent if quorum has elected a leader.
    //
    AcceptMessage,

    //
    // AcceptedMessage sent to prepare for a new round of paxos.
    //
    AcceptedMessage,

    //
    // UpdateMessage sent when replica realizes it is behind.
    //
    UpdateMessage,

    //
    // UpdatedMessage sent to update a replica that has fallen behind.
    //
    UpdatedMessage
};

struct MessageTypeHash
{
    template <typename T>
    std::size_t operator()(T t) const
    {
        return static_cast<std::size_t>(t);
    }
};

struct Message
{
    Decree decree;
    Replica from;
    Replica to;
    MessageType type;

    Message()
        : decree(), from(), to(), type()
    {
    }

    Message(Decree d, Replica f, Replica t, MessageType mtype)
        : decree(d), from(f), to(t), type(mtype)
    {
    }
};

Message Response(Message message, MessageType type);

#endif
<|endoftext|>


<commit_before>/* AssemblySolver.cpp
* Author: Ajay Seth
* Copyright (c)  2006 Stanford University
* Use of the OpenSim software in source form is permitted provided that the following
* conditions are met:
* 	1. The software is used only for non-commercial research and education. It may not
*     be used in relation to any commercial activity.
* 	2. The software is not distributed or redistributed.  Software distribution is allowed
*     only through https://simtk.org/home/opensim.
* 	3. Use of the OpenSim software or derivatives must be acknowledged in all publications,
*      presentations, or documents describing work in which OpenSim or derivatives are used.
* 	4. Credits to developers may not be removed from executables
*     created from modifications of the source.
* 	5. Modifications of source code must retain the above copyright notice, this list of
*     conditions and the following disclaimer.
*
*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
*  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
*  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
*  SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
*  TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
*  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
*  OR BUSINESS INTERRUPTION) OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
*  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "AssemblySolver.h"
#include "Model/Model.h"
#include "CoordinateReference.h"
#include <OpenSim/Common/Constant.h>

using namespace std;
using namespace SimTK;

namespace OpenSim {

//______________________________________________________________________________
/**
 * An implementation of the AssemblySolver
 *
 * @param model to assemble
 */
AssemblySolver::AssemblySolver
   (const Model &model, SimTK::Array_<CoordinateReference> &coordinateReferences,
	double constraintWeight) : Solver(model),
    _coordinateReferencesp(&coordinateReferences)
{
	_assembler = NULL;

	_constraintWeight = constraintWeight;

	// default accuracy
	_accuracy = 1e-4;

	// Get model coordinates
	const CoordinateSet &modelCoordSet = getModel().getCoordinateSet();

	SimTK::Array_<CoordinateReference>::iterator p;

	// Cycle through coordinate references
	for(p = _coordinateReferencesp->begin();
        p != _coordinateReferencesp->end(); p++)
    {
		if(p){
			//Find if any references that are empty and throw them away
			if(p->getName() == "" || p->getName() == "unknown"){
				//Get rid of the corresponding reference too
				p = _coordinateReferencesp->erase(p);
			}
			// Otherwise an error if the coordinate does not exist for this model
			else if ( !modelCoordSet.contains(p->getName())){
				throw(Exception("AssemblySolver: Model does not contain coordinate "+p->getName()+"."));
			}
		}
	}
}

AssemblySolver::~AssemblySolver()
{
	SimTK::Array_<CoordinateReference>::iterator p;
	for(p = _coordinateReferencesp->begin();
        p != _coordinateReferencesp->end(); p++)
	{
		p = _coordinateReferencesp->erase(p);
		--p;
	}

	delete _assembler;
}

/** Internal method to convert the CoordinateReferences into goals of the
		assembly solver. Subclasses, override and call base to include other goals
		such as point of interest matching (Marker tracking). This method is
		automatically called by assemble. */
void AssemblySolver::setupGoals(SimTK::State &s)
{
	// wipe-out the previous SimTK::Assembler
	delete _assembler;
	_assembler = new SimTK::Assembler(getModel().getMultibodySystem());
	_assembler->setAccuracy(_accuracy);

	// Define weights on constraints. Note can be spefified SimTK::Infinity to strictly enforce constraint
	// otherwise the weighted constraint error becomes a goal.
	_assembler->setSystemConstraintsWeight(_constraintWeight);

	// clear any old coordinate goals
	_coordinateAssemblyConditions.clear();

	// Get model coordinates
	const CoordinateSet &modelCoordSet = getModel().getCoordinateSet();

	SimTK::Array_<CoordinateReference>::iterator p;

	// Cycle through coordinate references
	for(p = _coordinateReferencesp->begin();
        p != _coordinateReferencesp->end(); p++) {
		if(p){
			CoordinateReference *coordRef = p;
			const Coordinate &coord = modelCoordSet.get(coordRef->getName());
			if(coord.getLocked(s)){
				//cout << "AssemblySolver: coordinate " << coord.getName() << " is locked/prescribed and will be excluded." << endl;
				_assembler->lockQ(coord.getBodyIndex(), SimTK::MobilizerQIndex(coord.getMobilityIndex()));
				//No longer need the lock on
				coord.setLocked(s, false);

				//Get rid of the corresponding reference too
				_coordinateReferencesp->erase(p);
				p--; //decrement since erase automatically points to next in the list
			}
			else{
				// Make this reference and its current value a goal of the Assembler
				SimTK::QValue *coordGoal = new SimTK::QValue(coord.getBodyIndex(), SimTK::MobilizerQIndex(coord.getMobilityIndex()),
														 coordRef->getValue(s) );
				// keep a handle to the goal so we can update
				_coordinateAssemblyConditions.push_back(coordGoal);
				// Add coordinate matching goal to the ik objective
				SimTK::AssemblyConditionIndex acIx = _assembler->adoptAssemblyGoal(coordGoal, coordRef->getWeight(s));
			}
		}
	}

	unsigned int nqrefs  = _coordinateReferencesp->size(),
                 nqgoals = _coordinateAssemblyConditions.size();
	//Should have a one-to-one matched arrays
	if(nqrefs != nqgoals)
		throw Exception("AsemblySolver::setupGoals() has a mismatch between number of references and goals.");
}

/** Once a set of coordinates has been specified its target value can
    be updated directly */
void AssemblySolver::updateCoordinateReference(const std::string &coordName, double value, double weight)
{
	SimTK::Array_<CoordinateReference>::iterator p;

	// Cycle through coordinate references
	for(p = _coordinateReferencesp->begin();
        p != _coordinateReferencesp->end(); p++) {
		if(p->getName() == coordName){
			p->setValueFunction(*new Constant(value));
			p->setWeight(weight);
			return;
		}
	}
}

/** Internal method to update the time, reference values and/or their
		weights that define the goals, based on the passed in state. */
void AssemblySolver::updateGoals(const SimTK::State &s)
{
	unsigned int nqrefs = _coordinateReferencesp->size();
	for(unsigned int i=0; i<nqrefs; i++){
		//update goal values from reference.
		_coordinateAssemblyConditions[i]->setValue
           ((*_coordinateReferencesp)[i].getValue(s));
		//_assembler->setAssemblyConditionWeight(_coordinateAssemblyConditions[i]->
	}
}

//______________________________________________________________________________
/**
 * Assemble the model such that it satisfies configuration goals and constraints
 * The input state is used to initialize the assembly and then is updated to
 * return the resulting assembled configuration.
 */
void AssemblySolver::assemble(SimTK::State &state)
{
	// Make a working copy of the state that will be used to set the internal state of the solver
	// This is necessary because we may wish to disable redundant constraints, but do not want this
	// to effect the state of constraints the user expects
	SimTK::State s = state;

	// Make sure goals are up-to-date.
	setupGoals(s);

	// Let assembler perform some internal setup
	_assembler->initialize(s);

	/*
	printf("UNASSEMBLED CONFIGURATION (err=%g, cost=%g, qerr=%g)\n",
        _assembler->calcCurrentErrorNorm(), _assembler->calcCurrentGoal(), max(abs(_assembler->getInternalState().getQErr())));
	cout << "Model numQs: " << _model.getNumCoordinates() << " Assembler num freeQs: " << _assembler->getNumFreeQs() << endl;
	*/

	try{
		// Now do the assembly and return the updated state.
		_assembler->assemble();
		// Update the q's in the state passed in
		_assembler->updateFromInternalState(s);
		state.updQ() = s.getQ();
		state.updU() = s.getU();

		// Get model coordinates
		const CoordinateSet &modelCoordSet = getModel().getCoordinateSet();
		// Make sure the locks in orignal state are restored
		for(int i=0; i< modelCoordSet.getSize(); ++i){
			bool isLocked = modelCoordSet[i].getLocked(state);
			if(isLocked)
				modelCoordSet[i].setLocked(state, isLocked);
		}

		/*
		printf("ASSEMBLED CONFIGURATION (acc=%g tol=%g err=%g, cost=%g, qerr=%g)\n",
			_assembler->getAccuracyInUse(), _assembler->getErrorToleranceInUse(),
			_assembler->calcCurrentErrorNorm(), _assembler->calcCurrentGoal(),
			max(abs(_assembler->getInternalState().getQErr())));
		printf("# initializations=%d\n", _assembler->getNumInitializations());
		printf("# assembly steps: %d\n", _assembler->getNumAssemblySteps());
		printf(" evals: goal=%d grad=%d error=%d jac=%d\n",
			_assembler->getNumGoalEvals(), _assembler->getNumGoalGradientEvals(),
			_assembler->getNumErrorEvals(), _assembler->getNumErrorJacobianEvals());
		*/
	}
	catch (std::exception ex)
    {
		std::string msg = "AssemblySolver::assemble() Failed: ";
		msg += ex.what();
		throw Exception(msg);
    }
}

/** Obtain a model configuration that meets the assembly conditions
    (desired values and constraints) given a state that satisfies or
	is close to satisfying the constraints. Note there can be no change
	in the number of constrainst or desired coordinates. Desired
	coordinate values can and should be updated between repeated calls
	to track a desired trajectory of coordinate values. */
void AssemblySolver::track(SimTK::State &s)
{

	// move the target locations or angles, etc... just do not change number of goals
	// and their type (constrained vs. weighted)

	if(_assembler && _assembler->isInitialized()){
		updateGoals(s);
	}
	else{
		throw Exception("AssemblySolver::track() failed: assemble() must be called first.");
	}

	try{
		// Now do the assembly and return the updated state.
		_assembler->track(s.getTime());

		// update the state from the result of the assembler
		_assembler->updateFromInternalState(s);

		/*
		printf("Tracking: t= %f (acc=%g tol=%g err=%g, cost=%g, qerr=%g)\n", s.getTime(),
			_assembler->getAccuracyInUse(), _assembler->getErrorToleranceInUse(),
			_assembler->calcCurrentErrorNorm(), _assembler->calcCurrentGoal(),
			max(abs(_assembler->getInternalState().getQErr())));
		*/
	}
	catch (SimTK::Exception::Base ex)
    {
		std::cout << "AssemblySolver::track() attempt Failed: " << ex.what() << std::endl;
		throw Exception("AssemblySolver::track() attempt failed.");
    }
}

} // end of namespace OpenSim<commit_msg>Fix exception message reporting in assembly solver -- should always catch a *reference* to an std::exception, not a *copy* or you lose the virtual what() that reports the message.<commit_after>/* AssemblySolver.cpp
* Author: Ajay Seth
* Copyright (c)  2006 Stanford University
* Use of the OpenSim software in source form is permitted provided that the following
* conditions are met:
* 	1. The software is used only for non-commercial research and education. It may not
*     be used in relation to any commercial activity.
* 	2. The software is not distributed or redistributed.  Software distribution is allowed
*     only through https://simtk.org/home/opensim.
* 	3. Use of the OpenSim software or derivatives must be acknowledged in all publications,
*      presentations, or documents describing work in which OpenSim or derivatives are used.
* 	4. Credits to developers may not be removed from executables
*     created from modifications of the source.
* 	5. Modifications of source code must retain the above copyright notice, this list of
*     conditions and the following disclaimer.
*
*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
*  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
*  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
*  SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
*  TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
*  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
*  OR BUSINESS INTERRUPTION) OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
*  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "AssemblySolver.h"
#include "Model/Model.h"
#include "CoordinateReference.h"
#include <OpenSim/Common/Constant.h>

using namespace std;
using namespace SimTK;

namespace OpenSim {

//______________________________________________________________________________
/**
 * An implementation of the AssemblySolver
 *
 * @param model to assemble
 */
AssemblySolver::AssemblySolver
   (const Model &model, SimTK::Array_<CoordinateReference> &coordinateReferences,
	double constraintWeight) : Solver(model),
    _coordinateReferencesp(&coordinateReferences)
{
	_assembler = NULL;

	_constraintWeight = constraintWeight;

	// default accuracy
	_accuracy = 1e-4;

	// Get model coordinates
	const CoordinateSet &modelCoordSet = getModel().getCoordinateSet();

	SimTK::Array_<CoordinateReference>::iterator p;

	// Cycle through coordinate references
	for(p = _coordinateReferencesp->begin();
        p != _coordinateReferencesp->end(); p++)
    {
		if(p){
			//Find if any references that are empty and throw them away
			if(p->getName() == "" || p->getName() == "unknown"){
				//Get rid of the corresponding reference too
				p = _coordinateReferencesp->erase(p);
			}
			// Otherwise an error if the coordinate does not exist for this model
			else if ( !modelCoordSet.contains(p->getName())){
				throw(Exception("AssemblySolver: Model does not contain coordinate "+p->getName()+"."));
			}
		}
	}
}

AssemblySolver::~AssemblySolver()
{
	SimTK::Array_<CoordinateReference>::iterator p;
	for(p = _coordinateReferencesp->begin();
        p != _coordinateReferencesp->end(); p++)
	{
		p = _coordinateReferencesp->erase(p);
		--p;
	}

	delete _assembler;
}

/** Internal method to convert the CoordinateReferences into goals of the
		assembly solver. Subclasses, override and call base to include other goals
		such as point of interest matching (Marker tracking). This method is
		automatically called by assemble. */
void AssemblySolver::setupGoals(SimTK::State &s)
{
	// wipe-out the previous SimTK::Assembler
	delete _assembler;
	_assembler = new SimTK::Assembler(getModel().getMultibodySystem());
	_assembler->setAccuracy(_accuracy);

	// Define weights on constraints. Note can be spefified SimTK::Infinity to strictly enforce constraint
	// otherwise the weighted constraint error becomes a goal.
	_assembler->setSystemConstraintsWeight(_constraintWeight);

	// clear any old coordinate goals
	_coordinateAssemblyConditions.clear();

	// Get model coordinates
	const CoordinateSet &modelCoordSet = getModel().getCoordinateSet();

	SimTK::Array_<CoordinateReference>::iterator p;

	// Cycle through coordinate references
	for(p = _coordinateReferencesp->begin();
        p != _coordinateReferencesp->end(); p++) {
		if(p){
			CoordinateReference *coordRef = p;
			const Coordinate &coord = modelCoordSet.get(coordRef->getName());
			if(coord.getLocked(s)){
				//cout << "AssemblySolver: coordinate " << coord.getName() << " is locked/prescribed and will be excluded." << endl;
				_assembler->lockQ(coord.getBodyIndex(), SimTK::MobilizerQIndex(coord.getMobilityIndex()));
				//No longer need the lock on
				coord.setLocked(s, false);

				//Get rid of the corresponding reference too
				_coordinateReferencesp->erase(p);
				p--; //decrement since erase automatically points to next in the list
			}
			else{
				// Make this reference and its current value a goal of the Assembler
				SimTK::QValue *coordGoal = new SimTK::QValue(coord.getBodyIndex(), SimTK::MobilizerQIndex(coord.getMobilityIndex()),
														 coordRef->getValue(s) );
				// keep a handle to the goal so we can update
				_coordinateAssemblyConditions.push_back(coordGoal);
				// Add coordinate matching goal to the ik objective
				SimTK::AssemblyConditionIndex acIx = _assembler->adoptAssemblyGoal(coordGoal, coordRef->getWeight(s));
			}
		}
	}

	unsigned int nqrefs  = _coordinateReferencesp->size(),
                 nqgoals = _coordinateAssemblyConditions.size();
	//Should have a one-to-one matched arrays
	if(nqrefs != nqgoals)
		throw Exception("AsemblySolver::setupGoals() has a mismatch between number of references and goals.");
}

/** Once a set of coordinates has been specified its target value can
    be updated directly */
void AssemblySolver::updateCoordinateReference(const std::string &coordName, double value, double weight)
{
	SimTK::Array_<CoordinateReference>::iterator p;

	// Cycle through coordinate references
	for(p = _coordinateReferencesp->begin();
        p != _coordinateReferencesp->end(); p++) {
		if(p->getName() == coordName){
			p->setValueFunction(*new Constant(value));
			p->setWeight(weight);
			return;
		}
	}
}

/** Internal method to update the time, reference values and/or their
		weights that define the goals, based on the passed in state. */
void AssemblySolver::updateGoals(const SimTK::State &s)
{
	unsigned int nqrefs = _coordinateReferencesp->size();
	for(unsigned int i=0; i<nqrefs; i++){
		//update goal values from reference.
		_coordinateAssemblyConditions[i]->setValue
           ((*_coordinateReferencesp)[i].getValue(s));
		//_assembler->setAssemblyConditionWeight(_coordinateAssemblyConditions[i]->
	}
}

//______________________________________________________________________________
/**
 * Assemble the model such that it satisfies configuration goals and constraints
 * The input state is used to initialize the assembly and then is updated to
 * return the resulting assembled configuration.
 */
void AssemblySolver::assemble(SimTK::State &state)
{
	// Make a working copy of the state that will be used to set the internal state of the solver
	// This is necessary because we may wish to disable redundant constraints, but do not want this
	// to effect the state of constraints the user expects
	SimTK::State s = state;

	// Make sure goals are up-to-date.
	setupGoals(s);

	// Let assembler perform some internal setup
	_assembler->initialize(s);

	/*
	printf("UNASSEMBLED CONFIGURATION (err=%g, cost=%g, qerr=%g)\n",
        _assembler->calcCurrentErrorNorm(), _assembler->calcCurrentGoal(), max(abs(_assembler->getInternalState().getQErr())));
	cout << "Model numQs: " << _model.getNumCoordinates() << " Assembler num freeQs: " << _assembler->getNumFreeQs() << endl;
	*/

	try{
		// Now do the assembly and return the updated state.
		_assembler->assemble();
		// Update the q's in the state passed in
		_assembler->updateFromInternalState(s);
		state.updQ() = s.getQ();
		state.updU() = s.getU();

		// Get model coordinates
		const CoordinateSet &modelCoordSet = getModel().getCoordinateSet();
		// Make sure the locks in orignal state are restored
		for(int i=0; i< modelCoordSet.getSize(); ++i){
			bool isLocked = modelCoordSet[i].getLocked(state);
			if(isLocked)
				modelCoordSet[i].setLocked(state, isLocked);
		}

		/*
		printf("ASSEMBLED CONFIGURATION (acc=%g tol=%g err=%g, cost=%g, qerr=%g)\n",
			_assembler->getAccuracyInUse(), _assembler->getErrorToleranceInUse(),
			_assembler->calcCurrentErrorNorm(), _assembler->calcCurrentGoal(),
			max(abs(_assembler->getInternalState().getQErr())));
		printf("# initializations=%d\n", _assembler->getNumInitializations());
		printf("# assembly steps: %d\n", _assembler->getNumAssemblySteps());
		printf(" evals: goal=%d grad=%d error=%d jac=%d\n",
			_assembler->getNumGoalEvals(), _assembler->getNumGoalGradientEvals(),
			_assembler->getNumErrorEvals(), _assembler->getNumErrorJacobianEvals());
		*/
	}
	catch (const std::exception& ex)
    {
		std::string msg = "AssemblySolver::assemble() Failed: ";
		msg += ex.what();
		throw Exception(msg);
    }
}

/** Obtain a model configuration that meets the assembly conditions
    (desired values and constraints) given a state that satisfies or
	is close to satisfying the constraints. Note there can be no change
	in the number of constrainst or desired coordinates. Desired
	coordinate values can and should be updated between repeated calls
	to track a desired trajectory of coordinate values. */
void AssemblySolver::track(SimTK::State &s)
{

	// move the target locations or angles, etc... just do not change number of goals
	// and their type (constrained vs. weighted)

	if(_assembler && _assembler->isInitialized()){
		updateGoals(s);
	}
	else{
		throw Exception("AssemblySolver::track() failed: assemble() must be called first.");
	}

	try{
		// Now do the assembly and return the updated state.
		_assembler->track(s.getTime());

		// update the state from the result of the assembler
		_assembler->updateFromInternalState(s);

		/*
		printf("Tracking: t= %f (acc=%g tol=%g err=%g, cost=%g, qerr=%g)\n", s.getTime(),
			_assembler->getAccuracyInUse(), _assembler->getErrorToleranceInUse(),
			_assembler->calcCurrentErrorNorm(), _assembler->calcCurrentGoal(),
			max(abs(_assembler->getInternalState().getQErr())));
		*/
	}
	catch (const std::exception& ex)
    {
		std::cout << "AssemblySolver::track() attempt Failed: " << ex.what() << std::endl;
		throw Exception("AssemblySolver::track() attempt failed.");
    }
}

} // end of namespace OpenSim<|endoftext|>


<commit_before>//=============================================================================
//
// *** AddTaskSPDdNdEta.C ***
//
// This macro initialize a complete AnalysisTask object for SPD dNdEta analysis.
//
//=============================================================================

AliAnalysisTaskSPDdNdEta *AddTaskSPDdNdEta()
{
// Creates an analysis task and adds it to the analysis manager.

  // A. Get the pointer to the existing analysis manager via the static access method.
  //==============================================================================
  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
  if (!mgr) {
    Error("AddTaskSPDdNdEta", "No analysis manager to connect to.");
    return NULL;
  }

  // B. Check the analysis type using the event handlers connected to the analysis
  //    manager. The availability of MC handler cann also be checked here.
  //==============================================================================
  if (!mgr->GetInputEventHandler()) {
    ::Error("AddTaskSPDdNdEta", "This task requires an input event handler");
    return NULL;
  }
  TString type = mgr->GetInputEventHandler()->GetDataType(); // can be "ESD" or "AOD"

  // C. Create the task, add it to manager.
  //==============================================================================

  AliAnalysisTaskSPDdNdEta *taskSPDdNdEta = new AliAnalysisTaskSPDdNdEta("TaskSPDdNdEta");
  mgr->AddTask(taskSPDdNdEta);

  // D. Configure the analysis task. Extra parameters can be used via optional
  // arguments of the AddTaskXXX() function.
  //===========================================================================
  taskSPDdNdEta->SetReadMC(kTRUE); // MC
  taskSPDdNdEta->SetppAnalysis(kTRUE); //pp analysis
  taskSPDdNdEta->SetTrigger(0);  //no trigger

  // E. Create ONLY the output containers for the data produced by the task.
  // Get and connect other common input/output containers via the manager as below
  //==============================================================================

  AliAnalysisDataContainer *cout_SPDdNdEta= mgr->CreateContainer("cOutput", TList::Class(), AliAnalysisManager::kOutputContainer, "SPDdNdEtaData.root");

   mgr->ConnectInput(taskSPDdNdEta, 0, mgr->GetCommonInputContainer());
   mgr->ConnectOutput(taskSPDdNdEta, 0, cout_SPDdNdEta);

   // Return task pointer at the end
   return taskSPDdNdEta;
}
<commit_msg>Update in the task setting (Mariella)<commit_after>//=============================================================================
//
// *** AddTaskSPDdNdEta.C ***
//
// This macro initialize a complete AnalysisTask object for SPD dNdEta analysis.
//
//=============================================================================

AliAnalysisTaskSPDdNdEta *AddTaskSPDdNdEta()
{
// Creates an analysis task and adds it to the analysis manager.

  // A. Get the pointer to the existing analysis manager via the static access method.
  //==============================================================================
  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
  if (!mgr) {
    Error("AddTaskSPDdNdEta", "No analysis manager to connect to.");
    return NULL;
  }

  // B. Check the analysis type using the event handlers connected to the analysis
  //    manager. The availability of MC handler cann also be checked here.
  //==============================================================================
  if (!mgr->GetInputEventHandler()) {
    ::Error("AddTaskSPDdNdEta", "This task requires an input event handler");
    return NULL;
  }
  TString type = mgr->GetInputEventHandler()->GetDataType(); // can be "ESD" or "AOD"

  // C. Create the task, add it to manager.
  //==============================================================================

  AliAnalysisTaskSPDdNdEta *taskSPDdNdEta = new AliAnalysisTaskSPDdNdEta("TaskSPDdNdEta");
  mgr->AddTask(taskSPDdNdEta);

  // D. Configure the analysis task. Extra parameters can be used via optional
  // arguments of the AddTaskXXX() function.
  //===========================================================================
  taskSPDdNdEta->SetReadMC(kTRUE); // MC
//  taskSPDdNdEta->SetppAnalysis(kTRUE); //pp analysis
  taskSPDdNdEta->SetTrigger(1);  //no trigger
  taskSPDdNdEta->SetEvtGen(kTRUE);  //to read Pythia data (kFALSE for Phojet)

  // E. Create ONLY the output containers for the data produced by the task.
  // Get and connect other common input/output containers via the manager as below
  //==============================================================================

  AliAnalysisDataContainer *cout_SPDdNdEta= mgr->CreateContainer("cOutput", TList::Class(), AliAnalysisManager::kOutputContainer, "SPDdNdEtaData.root");

   mgr->ConnectInput(taskSPDdNdEta, 0, mgr->GetCommonInputContainer());
   mgr->ConnectOutput(taskSPDdNdEta, 0, cout_SPDdNdEta);

   // Return task pointer at the end
   return taskSPDdNdEta;
}
<|endoftext|>


<commit_before>#include <distributions/models/gp.hpp>
#include <distributions/vector_math.hpp>

namespace distributions
{

void GammaPoisson::classifier_score (
        const Classifier & classifier,
        const Value & value,
        float * scores_accum,
        rng_t &) const
{
    const size_t size = classifier.groups.size();
    const float value_noalias = value;
    float * __restrict__ scores_accum_noalias = scores_accum;
    const float * __restrict__ score = classifier.score.data();
    const float * __restrict__ post_alpha = classifier.post_alpha.data();
    const float * __restrict__ score_coeff = classifier.score_coeff.data();
    float * __restrict__ temp = classifier.temp.data();

    const float log_factorial_value = fast_log_factorial(value);
    for (size_t i = 0; i < size; ++i) {
        temp[i] = fast_lgamma(post_alpha[i] + value_noalias);
    }
    for (size_t i = 0; i < size; ++i) {
        scores_accum[i] += score[i]
            + temp[i]
            - log_factorial_value
            + score_coeff[i] * value_noalias;
    }
}

} // namespace distributions
<commit_msg>Fix typo in gp.cc<commit_after>#include <distributions/models/gp.hpp>
#include <distributions/vector_math.hpp>

namespace distributions
{

void GammaPoisson::classifier_score (
        const Classifier & classifier,
        const Value & value,
        float * scores_accum,
        rng_t &) const
{
    const size_t size = classifier.groups.size();
    const float value_noalias = value;
    float * __restrict__ scores_accum_noalias = scores_accum;
    const float * __restrict__ score = classifier.score.data();
    const float * __restrict__ post_alpha = classifier.post_alpha.data();
    const float * __restrict__ score_coeff = classifier.score_coeff.data();
    float * __restrict__ temp = classifier.temp.data();

    const float log_factorial_value = fast_log_factorial(value);
    for (size_t i = 0; i < size; ++i) {
        temp[i] = fast_lgamma(post_alpha[i] + value_noalias);
    }
    for (size_t i = 0; i < size; ++i) {
        scores_accum_noalias[i] += score[i]
            + temp[i]
            - log_factorial_value
            + score_coeff[i] * value_noalias;
    }
}

} // namespace distributions
<|endoftext|>