<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * Version: MPL 1.1 / GPLv3+ / LGPLv3+
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (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.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Initial Developer of the Original Code is
 *       Novell Inc.
 * Portions created by the Initial Developer are Copyright (C) 2010 the
 * Initial Developer. All Rights Reserved.
 *
 * Contributor(s): Florian Reuter <freuter@novell.com>
 *                 Cedric Bosdonnat <cbosdonnat@novell.com>
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
 * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
 * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
 * instead of those above.
 */
#include "precompiled_sw.hxx"

#include "frame.hxx"
#include "txtfrm.hxx"
#include "porlin.hxx"
#include "porlay.hxx"
#include "portxt.hxx"
#include <libxml/xmlwriter.h>
#include <SwPortionHandler.hxx>

class XmlPortionDumper:public SwPortionHandler
{
  private:
    xmlTextWriterPtr writer;
    sal_uInt16 ofs;
  public:

    XmlPortionDumper( xmlTextWriterPtr some_writer ):writer( some_writer ), ofs( 0 )
    {
    }

    virtual ~ XmlPortionDumper(  )
    {
    }

    /**
        @param nLength
                length of this portion in the model string
        @param rText
                text which is painted on-screen
      */
    virtual void Text( sal_uInt16 nLength,
                       sal_uInt16 nType )
    {
        ofs += nLength;
        xmlTextWriterStartElement( writer, BAD_CAST( "Text" ) );
        xmlTextWriterWriteFormatAttribute( writer,
                                           BAD_CAST( "nLength" ),
                                           "%i", ( int ) nLength );
        xmlTextWriterWriteFormatAttribute( writer,
                                           BAD_CAST( "nType" ),
                                           "%i", ( int ) nType );
        xmlTextWriterEndElement( writer );
    }

    /**
        @param nLength
                length of this portion in the model string
        @param rText
                text which is painted on-screen
        @param nType
                type of this portion
      */
    virtual void Special( sal_uInt16 nLength,
                          const String & rText,
                          sal_uInt16 nType )
    {
        xmlTextWriterStartElement( writer, BAD_CAST( "Special" ) );
        xmlTextWriterWriteFormatAttribute( writer,
                                           BAD_CAST( "nLength" ),
                                           "%i", ( int ) nLength );
        xmlTextWriterWriteFormatAttribute( writer,
                                           BAD_CAST( "nType" ),
                                           "%i", ( int ) nType );
        rtl::OUString sText( rText );
        rtl::OString sText8 =::rtl::OUStringToOString( sText,
                                                       RTL_TEXTENCODING_UTF8 );
        xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "rText" ),
                                           "%s", sText8.getStr(  ) );

        xmlTextWriterEndElement( writer );
        ofs += nLength;
    }

    virtual void LineBreak(  )
    {
        xmlTextWriterStartElement( writer, BAD_CAST( "LineBreak" ) );
        xmlTextWriterEndElement( writer );
    }

    /**
      * @param nLength
      *         number of 'model string' characters to be skipped
      */
    virtual void Skip( sal_uInt16 nLength )
    {
        xmlTextWriterStartElement( writer, BAD_CAST( "Skip" ) );
        xmlTextWriterWriteFormatAttribute( writer,
                                           BAD_CAST( "nLength" ),
                                           "%i", ( int ) nLength );
        xmlTextWriterEndElement( writer );
        ofs += nLength;
    }

    virtual void Finish(  )
    {
        xmlTextWriterStartElement( writer, BAD_CAST( "Finish" ) );
        xmlTextWriterEndElement( writer );
    }

};

void SwTxtPortion::dumpPortionAsXml( xub_StrLen ofs, XubString & /*aText */,
                                     xmlTextWriterPtr writer )
{
    xmlTextWriterStartElement( writer, BAD_CAST( "SwTxtPortion" ) );
    xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "ofs" ), "%i", ofs );
    xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "len" ), "%i",
                                       ( int ) this->GetLen(  ) );

    xmlTextWriterEndElement( writer );
}

void SwLinePortion::dumpPortionAsXml( xub_StrLen ofs, XubString & /*aText */,
                                      xmlTextWriterPtr writer )
{
    xmlTextWriterStartElement( writer, BAD_CAST( "SwLinePortion" ) );
    xmlTextWriterWriteFormatAttribute( writer,
                                       BAD_CAST( "nWhichPor" ),
                                       "%04X",
                                       ( int ) this->GetWhichPor(  ) );
    xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "ofs" ), "%i", ofs );
    xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "len" ), "%i",
                                       ( int ) this->GetLen(  ) );
    xmlTextWriterEndElement( writer );
}

void SwLineLayout::dumpLineAsXml( xmlTextWriterPtr writer,
                                  xub_StrLen & ofs, XubString & aText )
{                               // not used any longer...
    xmlTextWriterStartElement( writer, BAD_CAST( "SwLineLayout" ) );
    SwLinePortion *portion = this;
    while ( portion != NULL )
    {
        portion->dumpPortionAsXml( ofs, aText, writer );
        ofs += portion->GetLen(  );
        portion = portion->GetPortion(  );
    }
    xmlTextWriterEndElement( writer );
}

void SwParaPortion::dumpAsXml( xmlTextWriterPtr writer, SwTxtFrm * pTxtFrm )
{
    xmlTextWriterStartElement( writer, BAD_CAST( "SwParaPortion" ) );
    SwParaPortion *pPara = this;

    if ( pPara && pTxtFrm )
    {
        xub_StrLen ofs = 0;
        XubString & aText = ( String & ) pTxtFrm->GetTxt(  );
        if ( pTxtFrm->IsFollow(  ) )
            ofs += pTxtFrm->GetOfst(  );

        SwLineLayout *pLine = pPara;
        while ( pLine )
        {
            xmlTextWriterStartElement( writer, BAD_CAST( "line" ) );
            SwLinePortion *pPor = pLine->GetFirstPortion(  );
            while ( pPor )
            {
                pPor->dumpPortionAsXml( ofs, aText, writer );
                ofs += pPor->GetLen(  );
                pPor = pPor->GetPortion(  );
            }

            xmlTextWriterEndElement( writer );  // line
            pLine = pLine->GetNext(  );
        }
    }
    xmlTextWriterEndElement( writer );
}

void SwFrm::dumpAsXml( xmlTextWriterPtr writer )
{
    const char *name = NULL;

    switch ( GetType(  ) )
    {
    case FRM_ROOT:
        name = "root";
        break;
    case FRM_PAGE:
        name = "page";
        break;
    case FRM_COLUMN:
        name = "column";
        break;
    case FRM_HEADER:
        name = "header";
        break;
    case FRM_FOOTER:
        name = "footer";
        break;
    case FRM_FTNCONT:
        name = "ftncont";
        break;
    case FRM_FTN:
        name = "ftn";
        break;
    case FRM_BODY:
        name = "body";
        break;
    case FRM_FLY:
        name = "fly";
        break;
    case FRM_SECTION:
        name = "section";
        break;
    case FRM_UNUSED:
        name = "unused";
        break;
    case FRM_TAB:
        name = "tab";
        break;
    case FRM_ROW:
        name = "row";
        break;
    case FRM_CELL:
        name = "cell";
        break;
    case FRM_TXT:
        name = "txt";
        break;
    case FRM_NOTXT:
        name = "txt";
        break;
    };

    if ( name != NULL )
    {
        xmlTextWriterStartElement( writer, ( const xmlChar * ) name );

        dumpAsXmlAttributes( writer );

        if ( IsTxtFrm(  ) )
        {
            SwTxtFrm *pTxtFrm = ( SwTxtFrm * ) this;
            rtl::OUString aTxt = pTxtFrm->GetTxt(  );
            for ( int i = 0; i < 32; i++ )
            {
                aTxt = aTxt.replace( i, '*' );
            }
            rtl::OString aTxt8 =::rtl::OUStringToOString( aTxt,
                                                          RTL_TEXTENCODING_UTF8 );
            xmlTextWriterWriteString( writer,
                                      ( const xmlChar * ) aTxt8.getStr(  ) );
            XmlPortionDumper pdumper( writer );
            pTxtFrm->VisitPortions( pdumper );

        }
        else
        {
            dumpChildrenAsXml( writer );
        }
        xmlTextWriterEndElement( writer );
    }
}

void SwFrm::dumpAsXmlAttributes( xmlTextWriterPtr writer )
{
    xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "ptr" ), "%p", this );
    xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "next" ), "%p", GetNext() );
    xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "prev" ), "%p", GetPrev() );
    xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "upper" ), "%p", this->GetUpper() );
    xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "lower" ), "%p", this->GetLower() );
}

void SwFrm::dumpChildrenAsXml( xmlTextWriterPtr writer )
{
    SwFrm *pFrm = GetLower(  );
    for ( ; pFrm != NULL; pFrm = pFrm->GetNext(  ) )
    {
        pFrm->dumpAsXml( writer );
    }
}

void SwTxtFrm::dumpAsXmlAttributes( xmlTextWriterPtr writer )
{
    SwFrm::dumpAsXmlAttributes( writer );
    if ( HasFollow() )
        xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "follow" ), "%p", GetFollow() );
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>Fix the build - methods in xmldump.cxx debug-only<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * Version: MPL 1.1 / GPLv3+ / LGPLv3+
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (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.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Initial Developer of the Original Code is
 *       Novell Inc.
 * Portions created by the Initial Developer are Copyright (C) 2010 the
 * Initial Developer. All Rights Reserved.
 *
 * Contributor(s): Florian Reuter <freuter@novell.com>
 *                 Cedric Bosdonnat <cbosdonnat@novell.com>
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
 * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
 * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
 * instead of those above.
 */
#include "precompiled_sw.hxx"

#include "frame.hxx"
#include "txtfrm.hxx"
#include "porlin.hxx"
#include "porlay.hxx"
#include "portxt.hxx"
#include <libxml/xmlwriter.h>
#include <SwPortionHandler.hxx>

class XmlPortionDumper:public SwPortionHandler
{
  private:
    xmlTextWriterPtr writer;
    sal_uInt16 ofs;
  public:

    XmlPortionDumper( xmlTextWriterPtr some_writer ):writer( some_writer ), ofs( 0 )
    {
    }

    virtual ~ XmlPortionDumper(  )
    {
    }

    /**
        @param nLength
                length of this portion in the model string
        @param rText
                text which is painted on-screen
      */
    virtual void Text( sal_uInt16 nLength,
                       sal_uInt16 nType )
    {
        ofs += nLength;
        xmlTextWriterStartElement( writer, BAD_CAST( "Text" ) );
        xmlTextWriterWriteFormatAttribute( writer,
                                           BAD_CAST( "nLength" ),
                                           "%i", ( int ) nLength );
        xmlTextWriterWriteFormatAttribute( writer,
                                           BAD_CAST( "nType" ),
                                           "%i", ( int ) nType );
        xmlTextWriterEndElement( writer );
    }

    /**
        @param nLength
                length of this portion in the model string
        @param rText
                text which is painted on-screen
        @param nType
                type of this portion
      */
    virtual void Special( sal_uInt16 nLength,
                          const String & rText,
                          sal_uInt16 nType )
    {
        xmlTextWriterStartElement( writer, BAD_CAST( "Special" ) );
        xmlTextWriterWriteFormatAttribute( writer,
                                           BAD_CAST( "nLength" ),
                                           "%i", ( int ) nLength );
        xmlTextWriterWriteFormatAttribute( writer,
                                           BAD_CAST( "nType" ),
                                           "%i", ( int ) nType );
        rtl::OUString sText( rText );
        rtl::OString sText8 =::rtl::OUStringToOString( sText,
                                                       RTL_TEXTENCODING_UTF8 );
        xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "rText" ),
                                           "%s", sText8.getStr(  ) );

        xmlTextWriterEndElement( writer );
        ofs += nLength;
    }

    virtual void LineBreak(  )
    {
        xmlTextWriterStartElement( writer, BAD_CAST( "LineBreak" ) );
        xmlTextWriterEndElement( writer );
    }

    /**
      * @param nLength
      *         number of 'model string' characters to be skipped
      */
    virtual void Skip( sal_uInt16 nLength )
    {
        xmlTextWriterStartElement( writer, BAD_CAST( "Skip" ) );
        xmlTextWriterWriteFormatAttribute( writer,
                                           BAD_CAST( "nLength" ),
                                           "%i", ( int ) nLength );
        xmlTextWriterEndElement( writer );
        ofs += nLength;
    }

    virtual void Finish(  )
    {
        xmlTextWriterStartElement( writer, BAD_CAST( "Finish" ) );
        xmlTextWriterEndElement( writer );
    }

};

#if OSL_DEBUG_LEVEL > 1

void SwTxtPortion::dumpPortionAsXml( xub_StrLen ofs, XubString & /*aText */,
                                     xmlTextWriterPtr writer )
{
    xmlTextWriterStartElement( writer, BAD_CAST( "SwTxtPortion" ) );
    xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "ofs" ), "%i", ofs );
    xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "len" ), "%i",
                                       ( int ) this->GetLen(  ) );

    xmlTextWriterEndElement( writer );
}

void SwLinePortion::dumpPortionAsXml( xub_StrLen ofs, XubString & /*aText */,
                                      xmlTextWriterPtr writer )
{
    xmlTextWriterStartElement( writer, BAD_CAST( "SwLinePortion" ) );
    xmlTextWriterWriteFormatAttribute( writer,
                                       BAD_CAST( "nWhichPor" ),
                                       "%04X",
                                       ( int ) this->GetWhichPor(  ) );
    xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "ofs" ), "%i", ofs );
    xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "len" ), "%i",
                                       ( int ) this->GetLen(  ) );
    xmlTextWriterEndElement( writer );
}

void SwLineLayout::dumpLineAsXml( xmlTextWriterPtr writer,
                                  xub_StrLen & ofs, XubString & aText )
{                               // not used any longer...
    xmlTextWriterStartElement( writer, BAD_CAST( "SwLineLayout" ) );
    SwLinePortion *portion = this;
    while ( portion != NULL )
    {
        portion->dumpPortionAsXml( ofs, aText, writer );
        ofs += portion->GetLen(  );
        portion = portion->GetPortion(  );
    }
    xmlTextWriterEndElement( writer );
}

void SwParaPortion::dumpAsXml( xmlTextWriterPtr writer, SwTxtFrm * pTxtFrm )
{
    xmlTextWriterStartElement( writer, BAD_CAST( "SwParaPortion" ) );
    SwParaPortion *pPara = this;

    if ( pPara && pTxtFrm )
    {
        xub_StrLen ofs = 0;
        XubString & aText = ( String & ) pTxtFrm->GetTxt(  );
        if ( pTxtFrm->IsFollow(  ) )
            ofs += pTxtFrm->GetOfst(  );

        SwLineLayout *pLine = pPara;
        while ( pLine )
        {
            xmlTextWriterStartElement( writer, BAD_CAST( "line" ) );
            SwLinePortion *pPor = pLine->GetFirstPortion(  );
            while ( pPor )
            {
                pPor->dumpPortionAsXml( ofs, aText, writer );
                ofs += pPor->GetLen(  );
                pPor = pPor->GetPortion(  );
            }

            xmlTextWriterEndElement( writer );  // line
            pLine = pLine->GetNext(  );
        }
    }
    xmlTextWriterEndElement( writer );
}

void SwFrm::dumpAsXml( xmlTextWriterPtr writer )
{
    const char *name = NULL;

    switch ( GetType(  ) )
    {
    case FRM_ROOT:
        name = "root";
        break;
    case FRM_PAGE:
        name = "page";
        break;
    case FRM_COLUMN:
        name = "column";
        break;
    case FRM_HEADER:
        name = "header";
        break;
    case FRM_FOOTER:
        name = "footer";
        break;
    case FRM_FTNCONT:
        name = "ftncont";
        break;
    case FRM_FTN:
        name = "ftn";
        break;
    case FRM_BODY:
        name = "body";
        break;
    case FRM_FLY:
        name = "fly";
        break;
    case FRM_SECTION:
        name = "section";
        break;
    case FRM_UNUSED:
        name = "unused";
        break;
    case FRM_TAB:
        name = "tab";
        break;
    case FRM_ROW:
        name = "row";
        break;
    case FRM_CELL:
        name = "cell";
        break;
    case FRM_TXT:
        name = "txt";
        break;
    case FRM_NOTXT:
        name = "txt";
        break;
    };

    if ( name != NULL )
    {
        xmlTextWriterStartElement( writer, ( const xmlChar * ) name );

        dumpAsXmlAttributes( writer );

        if ( IsTxtFrm(  ) )
        {
            SwTxtFrm *pTxtFrm = ( SwTxtFrm * ) this;
            rtl::OUString aTxt = pTxtFrm->GetTxt(  );
            for ( int i = 0; i < 32; i++ )
            {
                aTxt = aTxt.replace( i, '*' );
            }
            rtl::OString aTxt8 =::rtl::OUStringToOString( aTxt,
                                                          RTL_TEXTENCODING_UTF8 );
            xmlTextWriterWriteString( writer,
                                      ( const xmlChar * ) aTxt8.getStr(  ) );
            XmlPortionDumper pdumper( writer );
            pTxtFrm->VisitPortions( pdumper );

        }
        else
        {
            dumpChildrenAsXml( writer );
        }
        xmlTextWriterEndElement( writer );
    }
}

void SwFrm::dumpAsXmlAttributes( xmlTextWriterPtr writer )
{
    xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "ptr" ), "%p", this );
    xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "next" ), "%p", GetNext() );
    xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "prev" ), "%p", GetPrev() );
    xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "upper" ), "%p", this->GetUpper() );
    xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "lower" ), "%p", this->GetLower() );
}

void SwFrm::dumpChildrenAsXml( xmlTextWriterPtr writer )
{
    SwFrm *pFrm = GetLower(  );
    for ( ; pFrm != NULL; pFrm = pFrm->GetNext(  ) )
    {
        pFrm->dumpAsXml( writer );
    }
}

void SwTxtFrm::dumpAsXmlAttributes( xmlTextWriterPtr writer )
{
    SwFrm::dumpAsXmlAttributes( writer );
    if ( HasFollow() )
        xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "follow" ), "%p", GetFollow() );
}

#endif

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


<commit_before><commit_msg>Add pnorm&maxdist to benchmark html report tooltip<commit_after><|endoftext|>


<commit_before>#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#include <TCP.h>
#include <NetString.h>

#define BUFFER_LEN	( 80 )
#define BUFFER_STR	( "%79[0-9a-zA-Z.: ]s\n0" )

void CopyInputToBuffers( const char * const inputBuffer, char * const outIP, char * const outPort, char * const outCommand );

/*
====================
main

	Program entry point
====================
*/
int main( int argc, char ** argv ) {
	char buffer[BUFFER_LEN]; // buffer to store the send and receive packet
	bool isRunning = true; // Set the program to running
	bool tutorial = true; // Display the tutorial

	while ( isRunning ) {
		// While the socket is good and the program is running

		printf( "Enter IP address and port then command\n" );
		if ( tutorial ) {
			// Display the tutorial message
			printf( "Eg:\n192.168.0.2:27000 time\n\n" );

			tutorial = false; // Disable the tutorial message for future runs
		}
		printf( "> " ); // Show the text input indicator

		fseek( stdin, 0, SEEK_END ); // Clear the STDIN buffer
		scanf( BUFFER_STR, buffer ); // See BUFFER_STR above
		// BUFFER_STR is set to allow text, numbers, spaces and colons
		// Scanf will block while the user inputs text into buffer

		// Buffers for splitting the input string into
		char ipSection[16];
		char portSection[6];
		char command[8];

		// Split the input string into the buffers
		CopyInputToBuffers( buffer, &ipSection[0], &portSection[0], &command[0] );

		xiSocket::addressInfo_s destinationInfo; // We need to set where the packet is going

		// Convert the IP address string into a uint8_t[4] byte address for the destination
		NetString::ToV4Address( ipSection, 16, &destinationInfo.address.protocolV4[0], 4 );
		// Convert the port string to it's numeric value
		destinationInfo.port = atoi( portSection );

		xiTCP * const tcpSocket = xiTCP::ConnectTo( destinationInfo );
		if ( tcpSocket ) {
			tcpSocket->SetBlocking( true ); // Set the send to blocking, the program will halt until it is sent

			const byteLen_t sentBytes = tcpSocket->SendBuffer( command, 8 ); // command is 8 chars max, see it's declaration
			if ( sentBytes > 0 ) {
				// If we managed to send something

				if ( strcmp( command, "exit" ) == 0 ) {
					// If we sent the exit command

					isRunning = false; // Stop running on the next loop
				} else {
					bool didTimeOut = true; // Presume that we won't get a reply in time
					const clock_t timeOutStart = clock(); // Record when we started listening

					do {
						tcpSocket->SetBlocking( false ); // Set the socket to non-blocking so we can update the timer

						const byteLen_t receivedBytes = tcpSocket->ReadIntoBuffer( buffer, BUFFER_LEN ); // Listen to the socket into buffer
						if ( receivedBytes > 0 ) {
							// If we received something

							// Output who we sent the message to and what the reply we got was
							printf( "Reply from %s:%s \"%s\"\n", ipSection, portSection, buffer );

							didTimeOut = false; // We got a reply before the timeout
							break; // Break the listen loop
						}
					} while ( clock() < timeOutStart + 3000 ); // 3 second timeout

					if ( didTimeOut ) {
						// If we did infact timeout, notify the user
						printf( "Timed out\n" );
					}
				}
			}

			tcpSocket->Drop();
		} else {
			printf( "Connect failed\n" );
		}

		printf( "\n\n" ); // Add some padding between sessions
	}

	return 1;
}

/*
====================
CopyInputToBuffers

	Function that takes the input string and fills some char buffers with the data
	This is a dangerous function with a high chance of crashing with bad data!
	Expects the tokens: "X:P C" with X being the IP address, P the port and C the command
====================
*/
void CopyInputToBuffers( const char * const inputBuffer, char * const outIP, char * const outPort, char * const outCommand ) {
	// Copy in IP string
	const char * c = &inputBuffer[0];
	while ( *c != ':' ) {
		const size_t offset = c - &inputBuffer[0];
		outIP[offset] = *c;
		outIP[offset + 1] = 0;

		c++;
	}
	const size_t ipStrLen = strlen( outIP ) + 1;

	// Copy in port string
	c++;
	while ( *c != ' ' ) {
		const size_t offset = c - &inputBuffer[ipStrLen];
		outPort[offset] = *c;
		outPort[offset + 1] = 0;

		c++;
	}
	const size_t portStrLen = strlen( outPort ) + 1;

	const size_t ipPortLen = ( ipStrLen + portStrLen );

	// Copy in command string
	c++;
	while ( *c != 0 ) {
		const size_t offset = c - &inputBuffer[ipPortLen];
		outCommand[offset] = *c;
		outCommand[offset + 1] = 0;

		c++;
	}
}
<commit_msg>Increased the TCP timeout to 30 seconds<commit_after>#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#include <TCP.h>
#include <NetString.h>

#define BUFFER_LEN	( 80 )
#define BUFFER_STR	( "%79[0-9a-zA-Z.: ]s\n0" )

void CopyInputToBuffers( const char * const inputBuffer, char * const outIP, char * const outPort, char * const outCommand );

/*
====================
main

	Program entry point
====================
*/
int main( int argc, char ** argv ) {
	char buffer[BUFFER_LEN]; // buffer to store the send and receive packet
	bool isRunning = true; // Set the program to running
	bool tutorial = true; // Display the tutorial

	while ( isRunning ) {
		// While the socket is good and the program is running

		printf( "Enter IP address and port then command\n" );
		if ( tutorial ) {
			// Display the tutorial message
			printf( "Eg:\n192.168.0.2:27000 time\n\n" );

			tutorial = false; // Disable the tutorial message for future runs
		}
		printf( "> " ); // Show the text input indicator

		fseek( stdin, 0, SEEK_END ); // Clear the STDIN buffer
		scanf( BUFFER_STR, buffer ); // See BUFFER_STR above
		// BUFFER_STR is set to allow text, numbers, spaces and colons
		// Scanf will block while the user inputs text into buffer

		// Buffers for splitting the input string into
		char ipSection[16];
		char portSection[6];
		char command[8];

		// Split the input string into the buffers
		CopyInputToBuffers( buffer, &ipSection[0], &portSection[0], &command[0] );

		xiSocket::addressInfo_s destinationInfo; // We need to set where the packet is going

		// Convert the IP address string into a uint8_t[4] byte address for the destination
		NetString::ToV4Address( ipSection, 16, &destinationInfo.address.protocolV4[0], 4 );
		// Convert the port string to it's numeric value
		destinationInfo.port = atoi( portSection );

		xiTCP * const tcpSocket = xiTCP::ConnectTo( destinationInfo );
		if ( tcpSocket ) {
			tcpSocket->SetBlocking( true ); // Set the send to blocking, the program will halt until it is sent

			const byteLen_t sentBytes = tcpSocket->SendBuffer( command, 8 ); // command is 8 chars max, see it's declaration
			if ( sentBytes > 0 ) {
				// If we managed to send something

				if ( strcmp( command, "exit" ) == 0 ) {
					// If we sent the exit command

					isRunning = false; // Stop running on the next loop
				} else {
					bool didTimeOut = true; // Presume that we won't get a reply in time
					const clock_t timeOutStart = clock(); // Record when we started listening

					do {
						tcpSocket->SetBlocking( false ); // Set the socket to non-blocking so we can update the timer

						const byteLen_t receivedBytes = tcpSocket->ReadIntoBuffer( buffer, BUFFER_LEN ); // Listen to the socket into buffer
						if ( receivedBytes > 0 ) {
							// If we received something

							// Output who we sent the message to and what the reply we got was
							printf( "Reply from %s:%s \"%s\"\n", ipSection, portSection, buffer );

							didTimeOut = false; // We got a reply before the timeout
							break; // Break the listen loop
						}
					} while ( clock() < timeOutStart + 30000 ); // 30 second timeout

					if ( didTimeOut ) {
						// If we did infact timeout, notify the user
						printf( "Timed out\n" );
					}
				}
			}

			tcpSocket->Drop();
		} else {
			printf( "Connect failed\n" );
		}

		printf( "\n\n" ); // Add some padding between sessions
	}

	return 1;
}

/*
====================
CopyInputToBuffers

	Function that takes the input string and fills some char buffers with the data
	This is a dangerous function with a high chance of crashing with bad data!
	Expects the tokens: "X:P C" with X being the IP address, P the port and C the command
====================
*/
void CopyInputToBuffers( const char * const inputBuffer, char * const outIP, char * const outPort, char * const outCommand ) {
	// Copy in IP string
	const char * c = &inputBuffer[0];
	while ( *c != ':' ) {
		const size_t offset = c - &inputBuffer[0];
		outIP[offset] = *c;
		outIP[offset + 1] = 0;

		c++;
	}
	const size_t ipStrLen = strlen( outIP ) + 1;

	// Copy in port string
	c++;
	while ( *c != ' ' ) {
		const size_t offset = c - &inputBuffer[ipStrLen];
		outPort[offset] = *c;
		outPort[offset + 1] = 0;

		c++;
	}
	const size_t portStrLen = strlen( outPort ) + 1;

	const size_t ipPortLen = ( ipStrLen + portStrLen );

	// Copy in command string
	c++;
	while ( *c != 0 ) {
		const size_t offset = c - &inputBuffer[ipPortLen];
		outCommand[offset] = *c;
		outCommand[offset + 1] = 0;

		c++;
	}
}
<|endoftext|>


<commit_before>/* Symbol export for G+Smo shared object */

#define gsTensorBSplineBasis_EXPORT

#include <gsNurbs/gsTensorBSplineBasis.h>
#include <gsNurbs/gsTensorBSplineBasis.hpp>

namespace gismo
{

// CLASS_TEMPLATE_INST gsTensorBSplineBasis<2,real_t>;
// CLASS_TEMPLATE_INST gsTensorBSplineBasis<3,real_t>;
// CLASS_TEMPLATE_INST gsTensorBSplineBasis<4,real_t>;

CLASS_TEMPLATE_INST internal::gsXml< gsTensorBSplineBasis<2,real_t> >;
CLASS_TEMPLATE_INST internal::gsXml< gsTensorBSplineBasis<3,real_t> >;
CLASS_TEMPLATE_INST internal::gsXml< gsTensorBSplineBasis<4,real_t> >;

}
<commit_msg>small fix<commit_after>/* Symbol export for G+Smo shared object */

#define gsTensorBSplineBasis_EXPORT

#include <gsNurbs/gsTensorBSplineBasis.h>
#include <gsNurbs/gsTensorBSplineBasis.hpp>

namespace gismo
{

// CLASS_TEMPLATE_INST gsTensorBSplineBasis<2,real_t>;
// CLASS_TEMPLATE_INST gsTensorBSplineBasis<3,real_t>;
// CLASS_TEMPLATE_INST gsTensorBSplineBasis<4,real_t>;

CLASS_TEMPLATE_INST internal::gsXml< gsTensorBSplineBasis<1,real_t> >;
CLASS_TEMPLATE_INST internal::gsXml< gsTensorBSplineBasis<2,real_t> >;
CLASS_TEMPLATE_INST internal::gsXml< gsTensorBSplineBasis<3,real_t> >;
CLASS_TEMPLATE_INST internal::gsXml< gsTensorBSplineBasis<4,real_t> >;

}
<|endoftext|>


<commit_before>#include "JeuxState.h"
#include "PagedGeometry.h"
#include "GrassLoader.h"
#include "BatchPage.h"
#include "ImpostorPage.h"
#include "TreeLoader3D.h"

using namespace Ogre;
using namespace Forests;

JeuxState::JeuxState()
    :    m_Loader(0),
         m_TerrainImported(false),
         m_SceneFile(Ogre::StringUtil::BLANK)
{
    m_MoveSpeed			= 1.0f;
    m_RotateSpeed		= 0.3f;

    m_bQuit             = false;
    m_bLMouseDown = false;
    m_bRMouseDown = false;

    inputManager = InputManager::getSingletonPtr();

    mSkyX = 0;
    mBasicController = 0;
}

void JeuxState::enter()
{
    inputManager->addKeyListener(this,"Game1");
    inputManager->addMouseListener(this,"Game2");

    XsiliumFramework::getInstance()->m_pLog->logMessage("Entering JeuxState...");

    createScene();

    buildGUI();
}

bool JeuxState::pause()
{
    XsiliumFramework::getInstance()->m_pLog->logMessage("Pausing JeuxState...");

    return true;
}

void JeuxState::resume()
{
    XsiliumFramework::getInstance()->m_pLog->logMessage("Resuming JeuxState...");

    XsiliumFramework::getInstance()->m_pViewport->setCamera(m_pCamera);
    m_bQuit = false;
}

void JeuxState::exit()
{
    XsiliumFramework::getInstance()->m_pLog->logMessage("Leaving JeuxState...");

    m_pSceneMgr->destroyCamera(m_pCamera);
    if(m_pSceneMgr)
        XsiliumFramework::getInstance()->m_pRoot->destroySceneManager(m_pSceneMgr);

    CEGUI::WindowManager::getSingleton().destroyAllWindows();

    inputManager->removeKeyListener(this);
    inputManager->removeMouseListener(this);
}

void JeuxState::buildGUI()
{

	using namespace CEGUI;
    CEGUI::WindowManager& winMgr(CEGUI::WindowManager::getSingleton());

    CEGUI::Window* parent = winMgr.createWindow("DefaultWindow", "CEGUIApp/Console");

    CEGUI::Window* d_root = winMgr.loadLayoutFromFile("XsiliumConsole.layout");

    Console * d_console = new Console(d_root);

    // we will destroy the console box windows ourselves
    d_root->setDestroyedByParent(false);

        // Do events wire-up
    d_root->subscribeEvent(CEGUI::Window::EventKeyDown, Event::Subscriber(&Console::handleKeyDown, d_console));

    d_root->getChild("Console/Button")->
            subscribeEvent(PushButton::EventClicked, Event::Subscriber(&Console::handleSubmit, d_console));

    d_root->getChild("Console/Editbox")->
            subscribeEvent(Editbox::EventTextAccepted, Event::Subscriber(&Console::handleSubmit, d_console));

        // attach this window if parent is valid
    parent->addChild(d_root);

    CEGUI::System::getSingleton().getDefaultGUIContext().setRootWindow(d_root);
}

void JeuxState::createScene()
{
	m_pSceneMgr = XsiliumFramework::getInstance()->m_pRoot->createSceneManager(ST_GENERIC, "GameSceneMgr");

    m_Loader = new DotSceneLoader();
    m_Loader->parseDotScene("SampleDotScene.scene", "General", m_pSceneMgr);

    // Loop through all cameras and grab their name and set their debug representation
     Ogre::SceneManager::CameraIterator cameras = m_pSceneMgr->getCameraIterator();
     while (cameras.hasMoreElements())
     {
         Ogre::Camera* camera = cameras.getNext();
         mCamNames.push_back(camera->getName());
         Ogre::Entity* debugEnt = m_pSceneMgr->createEntity(camera->getName() + Ogre::String("_debug"), "scbCamera.mesh");

             Ogre::SceneNode* pNode = m_pSceneMgr->getRootSceneNode()->createChildSceneNode(camera->getName());
             pNode->setPosition(camera->getPosition());
             pNode->setOrientation(camera->getOrientation());

             pNode->attachObject(debugEnt);
             pNode->scale(0.5, 0.5, 0.5);
     }

     // Grab the first available camera, for now
     Ogre::String cameraName = mCamNames[0];
     try
     {
         m_pCamera = m_pSceneMgr->getCamera(cameraName);
         XsiliumFramework::getInstance()->m_pRenderWnd->getViewport(0)->setCamera(m_pCamera);
        // mCameraMan->setCamera(m_pCamera);
         m_pSceneMgr->getEntity(m_pCamera->getName() + Ogre::String("_debug"))->setVisible(false);

         for(unsigned int ij = 0;ij < m_Loader->mPGHandles.size();ij++)
         {
             m_Loader->mPGHandles[ij]->setCamera(m_pCamera);
         }

     }
     catch (Ogre::Exception& e)
     {
         Ogre::LogManager::getSingleton().logMessage("SampleApp::createScene : setting the active camera to (\"" +
             cameraName + ") failed: " + e.getFullDescription());
     }

	/*	mBasicController = new SkyX::BasicController();
		mSkyX = new SkyX::SkyX(m_pSceneMgr, mBasicController);
		mSkyX->create();

		mBasicController->setMoonPhase(0.75f);*/

	//	mSkyX->getCloudsManager()->add(SkyX::CloudLayer::Options(/* Default options */));

}

void JeuxState::update(double timeSinceLastFrame)
{
    m_FrameEvent.timeSinceLastFrame = timeSinceLastFrame;

    CEGUI::System& gui_system(CEGUI::System::getSingleton());

    gui_system.injectTimePulse(timeSinceLastFrame);
    gui_system.getDefaultGUIContext().injectTimePulse(timeSinceLastFrame);

    if(m_bQuit == true)
    {
        popGameState();
        return;
    }
    m_MoveScale = m_MoveSpeed   * timeSinceLastFrame;
    m_RotScale  = m_RotateSpeed * timeSinceLastFrame;

	m_TranslateVector = Ogre::Vector3::ZERO;

    getInput();
    m_pCamera->moveRelative(m_TranslateVector / 10);

   // mSkyX->update(timeSinceLastFrame);

}

void JeuxState::getInput()
{
        if(inputManager->getKeyboard()->isKeyDown(OIS::KC_A))
            m_TranslateVector.x = -m_MoveScale;

        if(inputManager->getKeyboard()->isKeyDown(OIS::KC_D))
            m_TranslateVector.x = m_MoveScale;

        if(inputManager->getKeyboard()->isKeyDown(OIS::KC_W))
            m_TranslateVector.z = -m_MoveScale;

        if(inputManager->getKeyboard()->isKeyDown(OIS::KC_S))
            m_TranslateVector.z = m_MoveScale;

}

bool JeuxState::keyPressed(const OIS::KeyEvent &keyEventRef)
{
	switch(keyEventRef.key)
	{
	case OIS::KC_ESCAPE:
		m_bQuit = true;
		break;
	case OIS::KC_LSHIFT:
			m_pCamera->moveRelative(m_TranslateVector);
		break;
	default:
		break;
	}
    return true;
}
bool JeuxState::keyReleased(const OIS::KeyEvent &keyEventRef)
{
	return true;
}

bool JeuxState::mouseMoved( const OIS::MouseEvent &event )
{
	if(m_bLMouseDown)
	{
		m_pCamera->yaw(Degree(event.state.X.rel * -0.1f));
	    m_pCamera->pitch(Degree(event.state.Y.rel * -0.1f));
	}
	return true;
}
bool JeuxState::mousePressed( const OIS::MouseEvent &event, OIS::MouseButtonID id )
{
    if(id == OIS::MB_Left)
    {
        m_bLMouseDown = true;
    }
    else if(id == OIS::MB_Right)
    {
        m_bRMouseDown = true;
    }

	return true;
}
bool JeuxState::mouseReleased( const OIS::MouseEvent &event, OIS::MouseButtonID id )
{
    if(id == OIS::MB_Left)
    {
        m_bLMouseDown = false;
    }
    else if(id == OIS::MB_Right)
    {
        m_bRMouseDown = false;
    }
	return true;
}

<commit_msg>Mise en place des input sur les cameras<commit_after>#include "JeuxState.h"
#include "PagedGeometry.h"
#include "GrassLoader.h"
#include "BatchPage.h"
#include "ImpostorPage.h"
#include "TreeLoader3D.h"

using namespace Ogre;
using namespace Forests;

JeuxState::JeuxState()
    :    m_Loader(0),
         m_TerrainImported(false),
         m_SceneFile(Ogre::StringUtil::BLANK)
{
    m_MoveSpeed			= 1.0f;
    m_RotateSpeed		= 0.3f;

    m_bQuit             = false;
    m_bLMouseDown = false;
    m_bRMouseDown = false;

    inputManager = InputManager::getSingletonPtr();

    mSkyX = 0;
    mBasicController = 0;
}

void JeuxState::enter()
{
    inputManager->addKeyListener(this,"Game1");
    inputManager->addMouseListener(this,"Game2");

    XsiliumFramework::getInstance()->m_pLog->logMessage("Entering JeuxState...");

    createScene();

    buildGUI();
}

bool JeuxState::pause()
{
    XsiliumFramework::getInstance()->m_pLog->logMessage("Pausing JeuxState...");

    return true;
}

void JeuxState::resume()
{
    XsiliumFramework::getInstance()->m_pLog->logMessage("Resuming JeuxState...");

    XsiliumFramework::getInstance()->m_pViewport->setCamera(m_pCamera);
    m_bQuit = false;
}

void JeuxState::exit()
{
    XsiliumFramework::getInstance()->m_pLog->logMessage("Leaving JeuxState...");

    m_pSceneMgr->destroyCamera(m_pCamera);
    if(m_pSceneMgr)
        XsiliumFramework::getInstance()->m_pRoot->destroySceneManager(m_pSceneMgr);

    CEGUI::WindowManager::getSingleton().destroyAllWindows();

    inputManager->removeKeyListener(this);
    inputManager->removeMouseListener(this);
}

void JeuxState::buildGUI()
{

	using namespace CEGUI;
    CEGUI::WindowManager& winMgr(CEGUI::WindowManager::getSingleton());

    CEGUI::Window* parent = winMgr.createWindow("DefaultWindow", "CEGUIApp/Console");

    CEGUI::Window* d_root = winMgr.loadLayoutFromFile("XsiliumConsole.layout");

    Console * d_console = new Console(d_root);

    // we will destroy the console box windows ourselves
    d_root->setDestroyedByParent(false);

        // Do events wire-up
    d_root->subscribeEvent(CEGUI::Window::EventKeyDown, Event::Subscriber(&Console::handleKeyDown, d_console));

    d_root->getChild("Console/Button")->
            subscribeEvent(PushButton::EventClicked, Event::Subscriber(&Console::handleSubmit, d_console));

    d_root->getChild("Console/Editbox")->
            subscribeEvent(Editbox::EventTextAccepted, Event::Subscriber(&Console::handleSubmit, d_console));

        // attach this window if parent is valid
    parent->addChild(d_root);

    CEGUI::System::getSingleton().getDefaultGUIContext().setRootWindow(d_root);
}

void JeuxState::createScene()
{
	m_pSceneMgr = XsiliumFramework::getInstance()->m_pRoot->createSceneManager(ST_GENERIC, "GameSceneMgr");

    m_Loader = new DotSceneLoader();
    m_Loader->parseDotScene("SampleDotScene.scene", "General", m_pSceneMgr);

    // Loop through all cameras and grab their name and set their debug representation
     Ogre::SceneManager::CameraIterator cameras = m_pSceneMgr->getCameraIterator();
     while (cameras.hasMoreElements())
     {
         Ogre::Camera* camera = cameras.getNext();
         mCamNames.push_back(camera->getName());
         Ogre::Entity* debugEnt = m_pSceneMgr->createEntity(camera->getName() + Ogre::String("_debug"), "scbCamera.mesh");

             Ogre::SceneNode* pNode = m_pSceneMgr->getRootSceneNode()->createChildSceneNode(camera->getName());
             pNode->setPosition(camera->getPosition());
             pNode->setOrientation(camera->getOrientation());

             pNode->attachObject(debugEnt);
             pNode->scale(0.5, 0.5, 0.5);
     }

     // Grab the first available camera, for now
     Ogre::String cameraName = mCamNames[0];
     try
     {
         m_pCamera = m_pSceneMgr->getCamera(cameraName);
         XsiliumFramework::getInstance()->m_pRenderWnd->getViewport(0)->setCamera(m_pCamera);
        // mCameraMan->setCamera(m_pCamera);
         m_pSceneMgr->getEntity(m_pCamera->getName() + Ogre::String("_debug"))->setVisible(false);

         for(unsigned int ij = 0;ij < m_Loader->mPGHandles.size();ij++)
         {
             m_Loader->mPGHandles[ij]->setCamera(m_pCamera);
         }

     }
     catch (Ogre::Exception& e)
     {
         Ogre::LogManager::getSingleton().logMessage("SampleApp::createScene : setting the active camera to (\"" +
             cameraName + ") failed: " + e.getFullDescription());
     }

	/*	mBasicController = new SkyX::BasicController();
		mSkyX = new SkyX::SkyX(m_pSceneMgr, mBasicController);
		mSkyX->create();

		mBasicController->setMoonPhase(0.75f);*/

	//	mSkyX->getCloudsManager()->add(SkyX::CloudLayer::Options(/* Default options */));

}

void JeuxState::update(double timeSinceLastFrame)
{
    m_FrameEvent.timeSinceLastFrame = timeSinceLastFrame;

    CEGUI::System& gui_system(CEGUI::System::getSingleton());

    gui_system.injectTimePulse(timeSinceLastFrame);
    gui_system.getDefaultGUIContext().injectTimePulse(timeSinceLastFrame);

    if(m_bQuit == true)
    {
        popGameState();
        return;
    }
    m_MoveScale = m_MoveSpeed   * timeSinceLastFrame;
    m_RotScale  = m_RotateSpeed * timeSinceLastFrame;

	m_TranslateVector = Ogre::Vector3::ZERO;

    getInput();
    m_pCamera->moveRelative(m_TranslateVector / 10);

   // mSkyX->update(timeSinceLastFrame);

}

void JeuxState::getInput()
{
        if(inputManager->getKeyboard()->isKeyDown(OIS::KC_A))
            m_TranslateVector.x = -m_MoveScale;

        if(inputManager->getKeyboard()->isKeyDown(OIS::KC_D))
            m_TranslateVector.x = m_MoveScale;

        if(inputManager->getKeyboard()->isKeyDown(OIS::KC_W))
            m_TranslateVector.z = -m_MoveScale;

        if(inputManager->getKeyboard()->isKeyDown(OIS::KC_S))
            m_TranslateVector.z = m_MoveScale;
        if(inputManager->getKeyboard()->isKeyDown(OIS::KC_0))
        {
        	m_pCamera = m_pSceneMgr->getCamera("Camera#0");
        	XsiliumFramework::getInstance()->m_pRenderWnd->getViewport(0)->setCamera(m_pCamera);
        }
        if(inputManager->getKeyboard()->isKeyDown(OIS::KC_1))
        {
        	m_pCamera = m_pSceneMgr->getCamera("Camera#1");
        	XsiliumFramework::getInstance()->m_pRenderWnd->getViewport(0)->setCamera(m_pCamera);
        }
        if(inputManager->getKeyboard()->isKeyDown(OIS::KC_2))
        {
        	m_pCamera = m_pSceneMgr->getCamera("Camera#2");
        	XsiliumFramework::getInstance()->m_pRenderWnd->getViewport(0)->setCamera(m_pCamera);
        }
}

bool JeuxState::keyPressed(const OIS::KeyEvent &keyEventRef)
{
	switch(keyEventRef.key)
	{
	case OIS::KC_ESCAPE:
		m_bQuit = true;
		break;
	case OIS::KC_LSHIFT:
			m_pCamera->moveRelative(m_TranslateVector);
		break;
	default:
		break;
	}
    return true;
}
bool JeuxState::keyReleased(const OIS::KeyEvent &keyEventRef)
{
	return true;
}

bool JeuxState::mouseMoved( const OIS::MouseEvent &event )
{
	if(m_bLMouseDown)
	{
		m_pCamera->yaw(Degree(event.state.X.rel * -0.1f));
	    m_pCamera->pitch(Degree(event.state.Y.rel * -0.1f));
	}
	return true;
}
bool JeuxState::mousePressed( const OIS::MouseEvent &event, OIS::MouseButtonID id )
{
    if(id == OIS::MB_Left)
    {
        m_bLMouseDown = true;
    }
    else if(id == OIS::MB_Right)
    {
        m_bRMouseDown = true;
    }

	return true;
}
bool JeuxState::mouseReleased( const OIS::MouseEvent &event, OIS::MouseButtonID id )
{
    if(id == OIS::MB_Left)
    {
        m_bLMouseDown = false;
    }
    else if(id == OIS::MB_Right)
    {
        m_bRMouseDown = false;
    }
	return true;
}

<|endoftext|>


<commit_before>//---------------------------------------------------------
// Copyright 2015 Ontario Institute for Cancer Research
// Written by Jared Simpson (jared.simpson@oicr.on.ca)
//---------------------------------------------------------
//
// nanopolish_pore_model_set -- A class that maintains
// a collection of pore models that SquiggleReads
// can load during initialization.
//
#include "nanopolish_pore_model_set.h"
#include "nanopolish_builtin_models.h"

//
PoreModelSet::PoreModelSet()
{
    // Copy the built-in models into the map
    for(auto p : builtin_models) {
        assert(!p.type.empty());
        assert(!p.metadata.get_short_name().empty());
        register_model(p);
    }
}

//
PoreModelSet::~PoreModelSet()
{

}

//
void PoreModelSet::initialize(const std::string& fofn_filename)
{
    // grab singleton instance
    PoreModelSet& model_set = getInstance();

    // open the fofn file reader
    std::ifstream fofn_reader(fofn_filename);
    if(!fofn_reader.is_open()) {
        fprintf(stderr, "Error: could not read %s\n", fofn_filename.c_str());
        exit(EXIT_FAILURE);
    }

    std::string model_filename;
    while(getline(fofn_reader, model_filename)) {

        // read the model
        PoreModel p(model_filename);
        assert(!p.name.empty());
        assert(!p.type.empty());
        model_set.register_model(p);
    }
}

void PoreModelSet::register_model(const PoreModel& p)
{
    // Check that this model doesn't exist already
    auto& type_set = model_type_sets[p.type];
    auto name_iter = type_set.find(p.metadata.get_short_name());
    if(name_iter != type_set.end()) {
        fprintf(stderr, "Warning: overwriting model %s-%s\n", p.metadata.get_short_name().c_str(), p.type.c_str());
    }
    type_set.insert(std::make_pair(p.metadata.get_short_name(), p));
    fprintf(stderr, "[pore model set] registered model %s-%s(alphabet: %s)\n", p.metadata.get_short_name().c_str(),
                                                                               p.type.c_str(),
                                                                               p.pmalphabet->get_name().c_str());
}

//
bool PoreModelSet::has_model(const std::string& type, const std::string& short_name)
{
    PoreModelSet& model_set = getInstance();

    auto iter_type = model_set.model_type_sets.find(type);
    if(iter_type == model_set.model_type_sets.end()) {
        return false;
    }

    auto iter_short_name = iter_type->second.find(short_name);
    return iter_short_name != iter_type->second.end();
}

//
const PoreModel& PoreModelSet::get_model(const std::string& type, const std::string& short_name)
{
    PoreModelSet& model_set = getInstance();

    auto iter_type = model_set.model_type_sets.find(type);
    if(iter_type == model_set.model_type_sets.end()) {
        fprintf(stderr, "Error: cannot find model type %s\n", type.c_str());
        exit(EXIT_FAILURE);
    }

    auto iter_short_name = iter_type->second.find(short_name);
    if(iter_short_name == iter_type->second.end()) {
        fprintf(stderr, "Error: cannot find model %s for type %s\n", short_name.c_str(), type.c_str());
        exit(EXIT_FAILURE);
    }

    return iter_short_name->second;
}

//
const PoreModelMap& PoreModelSet::get_models(const std::string& type)
{
    PoreModelSet& model_set = getInstance();

    auto iter_type = model_set.model_type_sets.find(type);
    if(iter_type == model_set.model_type_sets.end()) {
        fprintf(stderr, "Error: cannot find model type %s\n", type.c_str());
        exit(EXIT_FAILURE);
    }

    return iter_type->second;
}

void PoreModelSet::insert_model(const std::string& type, const PoreModel& model)
{
    #pragma omp critical
    {
        PoreModelSet& model_set = getInstance();
        std::string key = model.metadata.get_short_name();
        model_set.model_type_sets[type][key] = model;
    }
}
<commit_msg>models were not replaced when an external file was provided<commit_after>//---------------------------------------------------------
// Copyright 2015 Ontario Institute for Cancer Research
// Written by Jared Simpson (jared.simpson@oicr.on.ca)
//---------------------------------------------------------
//
// nanopolish_pore_model_set -- A class that maintains
// a collection of pore models that SquiggleReads
// can load during initialization.
//
#include "nanopolish_pore_model_set.h"
#include "nanopolish_builtin_models.h"

//
PoreModelSet::PoreModelSet()
{
    // Copy the built-in models into the map
    for(auto p : builtin_models) {
        assert(!p.type.empty());
        assert(!p.metadata.get_short_name().empty());
        register_model(p);
    }
}

//
PoreModelSet::~PoreModelSet()
{

}

//
void PoreModelSet::initialize(const std::string& fofn_filename)
{
    // grab singleton instance
    PoreModelSet& model_set = getInstance();

    // open the fofn file reader
    std::ifstream fofn_reader(fofn_filename);
    if(!fofn_reader.is_open()) {
        fprintf(stderr, "Error: could not read %s\n", fofn_filename.c_str());
        exit(EXIT_FAILURE);
    }

    std::string model_filename;
    while(getline(fofn_reader, model_filename)) {

        // read the model
        PoreModel p(model_filename);
        assert(!p.name.empty());
        assert(!p.type.empty());
        model_set.register_model(p);
    }
}

void PoreModelSet::register_model(const PoreModel& p)
{
    // Check that this model doesn't exist already
    auto& type_set = model_type_sets[p.type];
    auto name_iter = type_set.find(p.metadata.get_short_name());
    if(name_iter != type_set.end()) {
        fprintf(stderr, "Warning: overwriting model %s-%s\n", p.metadata.get_short_name().c_str(), p.type.c_str());
    }
    type_set[p.metadata.get_short_name()] = p;
    fprintf(stderr, "[pore model set] registered model %s-%s(alphabet: %s)\n", p.metadata.get_short_name().c_str(),
                                                                               p.type.c_str(),
                                                                               p.pmalphabet->get_name().c_str());
}

//
bool PoreModelSet::has_model(const std::string& type, const std::string& short_name)
{
    PoreModelSet& model_set = getInstance();

    auto iter_type = model_set.model_type_sets.find(type);
    if(iter_type == model_set.model_type_sets.end()) {
        return false;
    }

    auto iter_short_name = iter_type->second.find(short_name);
    return iter_short_name != iter_type->second.end();
}

//
const PoreModel& PoreModelSet::get_model(const std::string& type, const std::string& short_name)
{
    PoreModelSet& model_set = getInstance();

    auto iter_type = model_set.model_type_sets.find(type);
    if(iter_type == model_set.model_type_sets.end()) {
        fprintf(stderr, "Error: cannot find model type %s\n", type.c_str());
        exit(EXIT_FAILURE);
    }

    auto iter_short_name = iter_type->second.find(short_name);
    if(iter_short_name == iter_type->second.end()) {
        fprintf(stderr, "Error: cannot find model %s for type %s\n", short_name.c_str(), type.c_str());
        exit(EXIT_FAILURE);
    }

    return iter_short_name->second;
}

//
const PoreModelMap& PoreModelSet::get_models(const std::string& type)
{
    PoreModelSet& model_set = getInstance();

    auto iter_type = model_set.model_type_sets.find(type);
    if(iter_type == model_set.model_type_sets.end()) {
        fprintf(stderr, "Error: cannot find model type %s\n", type.c_str());
        exit(EXIT_FAILURE);
    }

    return iter_type->second;
}

void PoreModelSet::insert_model(const std::string& type, const PoreModel& model)
{
    #pragma omp critical
    {
        PoreModelSet& model_set = getInstance();
        std::string key = model.metadata.get_short_name();
        model_set.model_type_sets[type][key] = model;
    }
}
<|endoftext|>


<commit_before>/*
 * Copyright 2007-2017 Content Management AG
 * All rights reserved.
 *
 * author: Max Kellermann <mk@cm4all.com>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * - Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the
 * distribution.
 *
 * 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
 * FOUNDATION 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; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, 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.
 */

#ifndef BENG_PROXY_GROWING_BUFFER_HXX
#define BENG_PROXY_GROWING_BUFFER_HXX

#include "DefaultChunkAllocator.hxx"

#include "util/Compiler.h"

#include <utility>

#include <stddef.h>

template<typename T> struct ConstBuffer;
template<typename T> struct WritableBuffer;
class IstreamBucketList;

/**
 * An auto-growing buffer you can write to.
 */
class GrowingBuffer {
    friend class GrowingBufferReader;

    struct Buffer;

    struct BufferPtr {
        Buffer *buffer = nullptr;
        DefaultChunkAllocator allocator;

        BufferPtr() = default;

        BufferPtr(BufferPtr &&src) noexcept
            :buffer(src.buffer), allocator(std::move(src.allocator)) {
            src.buffer = nullptr;
        }

        ~BufferPtr() noexcept {
            if (buffer != nullptr)
                Free();
        }

        BufferPtr &operator=(BufferPtr &&src) noexcept {
            using std::swap;
            swap(buffer, src.buffer);
            swap(allocator, src.allocator);
            return *this;
        }

        operator bool() const noexcept {
            return buffer != nullptr;
        }

        Buffer &Allocate() noexcept;
        void Free() noexcept;

        void Pop() noexcept;

        const Buffer *get() const noexcept {
            return buffer;
        }

        Buffer *get() noexcept {
            return buffer;
        }

        const Buffer &operator*() const noexcept {
            return *buffer;
        }

        Buffer &operator*() noexcept {
            return *buffer;
        }

        const Buffer *operator->() const noexcept {
            return buffer;
        }

        Buffer *operator->() noexcept {
            return buffer;
        }
    };

    struct Buffer {
        BufferPtr next;

        const size_t size;
        size_t fill = 0;
        char data[sizeof(size_t)];

        explicit Buffer(size_t _size) noexcept
            :size(_size) {}

        bool IsFull() const noexcept {
            return fill == size;
        }

        WritableBuffer<void> Write() noexcept;
        size_t WriteSome(ConstBuffer<void> src) noexcept;
    };

    BufferPtr head;
    Buffer *tail = nullptr;

    size_t position = 0;

public:
    GrowingBuffer() = default;

    GrowingBuffer(GrowingBuffer &&src) noexcept
        :head(std::move(src.head)), tail(src.tail) {
        src.tail = nullptr;
    }

    bool IsEmpty() const noexcept {
        return tail == nullptr;
    }

    void Clear() noexcept {
        Release();
    }

    /**
     * Release the buffer list, which may now be owned by somebody
     * else.
     */
    void Release() noexcept {
        if (head)
            head.Free();
        tail = nullptr;
        position = 0;
    }

    void *Write(size_t length) noexcept;

    size_t WriteSome(const void *p, size_t length) noexcept;
    void Write(const void *p, size_t length) noexcept;

    void Write(const char *p) noexcept;

    void AppendMoveFrom(GrowingBuffer &&src) noexcept;

    /**
     * Returns the total size of the buffer.
     */
    gcc_pure
    size_t GetSize() const noexcept;

    /**
     * Duplicates the whole buffer (including all chunks) to one
     * contiguous buffer.
     */
    WritableBuffer<void> Dup(struct pool &pool) const noexcept;

    gcc_pure
    ConstBuffer<void> Read() const noexcept;

    /**
     * Skip an arbitrary number of data bytes, which may span over
     * multiple internal buffers.
     */
    void Skip(size_t length) noexcept;

    /**
     * Consume data returned by Read().
     */
    void Consume(size_t length) noexcept;

private:
    Buffer &AppendBuffer() noexcept;

    void CopyTo(void *dest) const noexcept;

    template<typename F>
    void ForEachBuffer(F &&f) const {
        const auto *i = head.get();
        if (i == nullptr)
            return;

        f({i->data + position, i->fill - position});

        while ((i = i->next.get()) != nullptr)
            f({i->data, i->fill});
    }
};

class GrowingBufferReader {
    GrowingBuffer::BufferPtr buffer;
    size_t position = 0;

public:
    explicit GrowingBufferReader(GrowingBuffer &&gb) noexcept;

    gcc_pure
    bool IsEOF() const noexcept;

    gcc_pure
    size_t Available() const noexcept;

    gcc_pure
    ConstBuffer<void> Read() const noexcept;

    /**
     * Consume data returned by Read().
     */
    void Consume(size_t length) noexcept;

    /**
     * Skip an arbitrary number of data bytes, which may span over
     * multiple internal buffers.
     */
    void Skip(size_t length) noexcept;

    void FillBucketList(IstreamBucketList &list) const noexcept;
    size_t ConsumeBucketList(size_t nbytes) noexcept;

private:
    template<typename F>
    void ForEachBuffer(F &&f) const {
        const auto *i = buffer.get();
        if (i == nullptr)
            return;

        f({i->data + position, i->fill - position});

        while ((i = i->next.get()) != nullptr)
            f({i->data, i->fill});
    }
};

#endif
<commit_msg>GrowingBuffer: use `uint8_t` instead of `char`<commit_after>/*
 * Copyright 2007-2017 Content Management AG
 * All rights reserved.
 *
 * author: Max Kellermann <mk@cm4all.com>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * - Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the
 * distribution.
 *
 * 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
 * FOUNDATION 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; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, 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.
 */

#ifndef BENG_PROXY_GROWING_BUFFER_HXX
#define BENG_PROXY_GROWING_BUFFER_HXX

#include "DefaultChunkAllocator.hxx"
#include "util/Compiler.h"

#include <utility>

#include <stddef.h>
#include <stdint.h>

template<typename T> struct ConstBuffer;
template<typename T> struct WritableBuffer;
class IstreamBucketList;

/**
 * An auto-growing buffer you can write to.
 */
class GrowingBuffer {
    friend class GrowingBufferReader;

    struct Buffer;

    struct BufferPtr {
        Buffer *buffer = nullptr;
        DefaultChunkAllocator allocator;

        BufferPtr() = default;

        BufferPtr(BufferPtr &&src) noexcept
            :buffer(src.buffer), allocator(std::move(src.allocator)) {
            src.buffer = nullptr;
        }

        ~BufferPtr() noexcept {
            if (buffer != nullptr)
                Free();
        }

        BufferPtr &operator=(BufferPtr &&src) noexcept {
            using std::swap;
            swap(buffer, src.buffer);
            swap(allocator, src.allocator);
            return *this;
        }

        operator bool() const noexcept {
            return buffer != nullptr;
        }

        Buffer &Allocate() noexcept;
        void Free() noexcept;

        void Pop() noexcept;

        const Buffer *get() const noexcept {
            return buffer;
        }

        Buffer *get() noexcept {
            return buffer;
        }

        const Buffer &operator*() const noexcept {
            return *buffer;
        }

        Buffer &operator*() noexcept {
            return *buffer;
        }

        const Buffer *operator->() const noexcept {
            return buffer;
        }

        Buffer *operator->() noexcept {
            return buffer;
        }
    };

    struct Buffer {
        BufferPtr next;

        const size_t size;
        size_t fill = 0;
        uint8_t data[sizeof(size_t)];

        explicit Buffer(size_t _size) noexcept
            :size(_size) {}

        bool IsFull() const noexcept {
            return fill == size;
        }

        WritableBuffer<void> Write() noexcept;
        size_t WriteSome(ConstBuffer<void> src) noexcept;
    };

    BufferPtr head;
    Buffer *tail = nullptr;

    size_t position = 0;

public:
    GrowingBuffer() = default;

    GrowingBuffer(GrowingBuffer &&src) noexcept
        :head(std::move(src.head)), tail(src.tail) {
        src.tail = nullptr;
    }

    bool IsEmpty() const noexcept {
        return tail == nullptr;
    }

    void Clear() noexcept {
        Release();
    }

    /**
     * Release the buffer list, which may now be owned by somebody
     * else.
     */
    void Release() noexcept {
        if (head)
            head.Free();
        tail = nullptr;
        position = 0;
    }

    void *Write(size_t length) noexcept;

    size_t WriteSome(const void *p, size_t length) noexcept;
    void Write(const void *p, size_t length) noexcept;

    void Write(const char *p) noexcept;

    void AppendMoveFrom(GrowingBuffer &&src) noexcept;

    /**
     * Returns the total size of the buffer.
     */
    gcc_pure
    size_t GetSize() const noexcept;

    /**
     * Duplicates the whole buffer (including all chunks) to one
     * contiguous buffer.
     */
    WritableBuffer<void> Dup(struct pool &pool) const noexcept;

    gcc_pure
    ConstBuffer<void> Read() const noexcept;

    /**
     * Skip an arbitrary number of data bytes, which may span over
     * multiple internal buffers.
     */
    void Skip(size_t length) noexcept;

    /**
     * Consume data returned by Read().
     */
    void Consume(size_t length) noexcept;

private:
    Buffer &AppendBuffer() noexcept;

    void CopyTo(void *dest) const noexcept;

    template<typename F>
    void ForEachBuffer(F &&f) const {
        const auto *i = head.get();
        if (i == nullptr)
            return;

        f({i->data + position, i->fill - position});

        while ((i = i->next.get()) != nullptr)
            f({i->data, i->fill});
    }
};

class GrowingBufferReader {
    GrowingBuffer::BufferPtr buffer;
    size_t position = 0;

public:
    explicit GrowingBufferReader(GrowingBuffer &&gb) noexcept;

    gcc_pure
    bool IsEOF() const noexcept;

    gcc_pure
    size_t Available() const noexcept;

    gcc_pure
    ConstBuffer<void> Read() const noexcept;

    /**
     * Consume data returned by Read().
     */
    void Consume(size_t length) noexcept;

    /**
     * Skip an arbitrary number of data bytes, which may span over
     * multiple internal buffers.
     */
    void Skip(size_t length) noexcept;

    void FillBucketList(IstreamBucketList &list) const noexcept;
    size_t ConsumeBucketList(size_t nbytes) noexcept;

private:
    template<typename F>
    void ForEachBuffer(F &&f) const {
        const auto *i = buffer.get();
        if (i == nullptr)
            return;

        f({i->data + position, i->fill - position});

        while ((i = i->next.get()) != nullptr)
            f({i->data, i->fill});
    }
};

#endif
<|endoftext|>


<commit_before><commit_msg>Lata bio<commit_after><|endoftext|>


<commit_before>/**
\file
\brief Defines the coral::bus::SlaveAgent class.
*/
#ifndef CORAL_BUS_SLAVE_AGENT_HPP
#define CORAL_BUS_SLAVE_AGENT_HPP

#include <chrono>
#include <exception>
#include <string>
#include <vector>

#include "boost/bimap.hpp"
#include "boost/bimap/multiset_of.hpp"
#include "zmq.hpp"

#include "coral/config.h"
#include "coral/bus/variable_io.hpp"
#include "coral/model.hpp"
#include "coral/net.hpp"
#include "coral/net/reactor.hpp"
#include "coral/net/zmqx.hpp"
#include "coral/slave/instance.hpp"
#include "execution.pb.h"

namespace coral
{
namespace bus
{

/**
\brief  A class which contains the state of the slave and takes care of
        responding to requests from the master node in an appropriate manner.
*/
class SlaveAgent
{
public:
    /**
    \brief  Constructs a new SlaveAgent.

    \param [in] reactor
        The Reactor which should be used to listen for incoming messages.
    \param [in] slaveInstance
        The slave itself.
    \param [in] controlEndpoint
        The endpoint to which the slave should bind to receive an incoming
        connection from a master.
    \param [in] dataPubEndpoint
        The endpoint to which the slave should bind and publish its output
        data.
    \param [in] commTimeout
        A time after which communication with the master is assumed to be
        broken.  When this happens, a coral::slave::TimeoutException will
        be thrown from the "incoming message" handler, and will propagate
        out through coral::net::Reactor::Run().
    */
    SlaveAgent(
        coral::net::Reactor& reactor,
        coral::slave::Instance& slaveInstance,
        const coral::net::Endpoint& controlEndpoint,
        const coral::net::Endpoint& dataPubEndpoint,
        std::chrono::milliseconds commTimeout);

    /**
    \brief  The endpoint on which the slave is listening for incoming messages
            from the master.

    This is useful if the `controlEndpoint` argument passed to the constructor
    contains a wildcard port number, in which case this function will return
    the actual port used.
    */
    coral::net::Endpoint BoundControlEndpoint() const;

    /**
    \brief  The endpoint to which the slave is publishing its output data.

    This is useful if the `dataPubEndpoint` argument passed to the constructor
    contains a wildcard port number, in which case this function will return
    the actual port used.
    */
    coral::net::Endpoint BoundDataPubEndpoint() const;

private:
    /*
    \brief  Responds to a message from the master.

    On input, `msg` must be the message received from master, and on output,
    it will contain the slave's reply.  Internally, the function forwards to
    the handler function that corresponds to the slave's current state.
    */
    void RequestReply(std::vector<zmq::message_t>& msg);

    // Each of these functions correspond to one of the slave's possible states.
    // On input, `msg` is a message from the master node, and when the function
    // returns, `msg` must contain the reply.  If the message triggers a state
    // change, the handler function must update m_stateHandler to point to the
    // function for the new state.
    void NotConnectedHandler(std::vector<zmq::message_t>& msg);
    void ConnectedHandler(std::vector<zmq::message_t>& msg);
    void ReadyHandler(std::vector<zmq::message_t>& msg);
    void PublishedHandler(std::vector<zmq::message_t>& msg);
    void StepFailedHandler(std::vector<zmq::message_t>& msg);

    // Performs the "describe" operation, including filling `msg` with a
    // reply message.
    void HandleDescribe(std::vector<zmq::message_t>& msg);

    // Performs the "set variables" operation for ReadyHandler(), including
    // filling `msg` with a reply message.
    void HandleSetVars(std::vector<zmq::message_t>& msg);

    // Performs the "set peers" operation for ReadyHandler(), including
    // filling `msg` with a reply message.
    void HandleSetPeers(std::vector<zmq::message_t>& msg);

    // Performs the time step for ReadyHandler()
    bool Step(const coralproto::execution::StepData& stepData);

    // Publishes all variable values (used by Step()).
    void PublishAll();

    // A pointer to the handler function for the current state.
    void (SlaveAgent::* m_stateHandler)(std::vector<zmq::message_t>&);

    // A less-than comparison functor for Variable objects, so we can put
    // them in a std::map.
    struct VariableLess
    {
        bool operator()(const coral::model::Variable& a, const coral::model::Variable& b) const
        {
            return ((a.Slave() << 16) + a.ID()) < ((b.Slave() << 16) + b.ID());
        }
    };

    // A class which keeps track of connections to our input variables and the
    // values we receive for them.
    class Connections
    {
    public:
        // Connects to the publisher endpoints
        void Connect(
            const coral::net::Endpoint* endpoints,
            std::size_t endpointsSize);

        // Establishes a connection between a remote output variable and one of
        // our input variables, breaking any existing connections to that input.
        void Couple(
            coral::model::Variable remoteOutput,
            coral::model::VariableID localInput);

        // Waits until all data has been received for the time step specified
        // by `stepID` and updates the slave instance with the new values.
        void Update(
            coral::slave::Instance& slaveInstance,
            coral::model::StepID stepID,
            std::chrono::milliseconds timeout);

    private:
        // Breaks a connection to a local input variable, if any.
        void Decouple(coral::model::VariableID localInput);

        // A bidirectional mapping between output variables and input variables.
        typedef boost::bimap<
            boost::bimaps::multiset_of<coral::model::Variable, VariableLess>,
            coral::model::VariableID>
            ConnectionBimap;

        ConnectionBimap m_connections;
        coral::bus::VariableSubscriber m_subscriber;
    };

    coral::slave::Instance& m_slaveInstance;
    std::chrono::milliseconds m_commTimeout;

    coral::net::zmqx::RepSocket m_control;
    coral::bus::VariablePublisher m_publisher;
    Connections m_connections;
    coral::model::SlaveID m_id; // The slave's ID number in the current execution

    coral::model::StepID m_currentStepID; // ID of ongoing or just completed step
};

/// Exception thrown when the slave receives a TERMINATE command.
class Shutdown : public std::exception
{
public:
    const char* what() const CORAL_NOEXCEPT override { return "Normal shutdown requested by master"; }
};

}}      // namespace
#endif  // header guard
<commit_msg>Explicitly disable move and copy for SlaveAgent<commit_after>/**
\file
\brief Defines the coral::bus::SlaveAgent class.
*/
#ifndef CORAL_BUS_SLAVE_AGENT_HPP
#define CORAL_BUS_SLAVE_AGENT_HPP

#include <chrono>
#include <exception>
#include <string>
#include <vector>

#include "boost/bimap.hpp"
#include "boost/bimap/multiset_of.hpp"
#include "zmq.hpp"

#include "coral/config.h"
#include "coral/bus/variable_io.hpp"
#include "coral/model.hpp"
#include "coral/net.hpp"
#include "coral/net/reactor.hpp"
#include "coral/net/zmqx.hpp"
#include "coral/slave/instance.hpp"
#include "execution.pb.h"

namespace coral
{
namespace bus
{

/**
\brief  A class which contains the state of the slave and takes care of
        responding to requests from the master node in an appropriate manner.
*/
class SlaveAgent
{
public:
    /**
    \brief  Constructs a new SlaveAgent.

    \param [in] reactor
        The Reactor which should be used to listen for incoming messages.
    \param [in] slaveInstance
        The slave itself.
    \param [in] controlEndpoint
        The endpoint to which the slave should bind to receive an incoming
        connection from a master.
    \param [in] dataPubEndpoint
        The endpoint to which the slave should bind and publish its output
        data.
    \param [in] commTimeout
        A time after which communication with the master is assumed to be
        broken.  When this happens, a coral::slave::TimeoutException will
        be thrown from the "incoming message" handler, and will propagate
        out through coral::net::Reactor::Run().
    */
    SlaveAgent(
        coral::net::Reactor& reactor,
        coral::slave::Instance& slaveInstance,
        const coral::net::Endpoint& controlEndpoint,
        const coral::net::Endpoint& dataPubEndpoint,
        std::chrono::milliseconds commTimeout);

    // Class can't be copied or moved because it leaks references to `this`
    // through Reactor event handlers.
    SlaveAgent(const SlaveAgent&) = delete;
    SlaveAgent& operator=(const SlaveAgent&) = delete;
    SlaveAgent(SlaveAgent&&) = delete;
    SlaveAgent& operator=(SlaveAgent&&) = delete;

    /**
    \brief  The endpoint on which the slave is listening for incoming messages
            from the master.

    This is useful if the `controlEndpoint` argument passed to the constructor
    contains a wildcard port number, in which case this function will return
    the actual port used.
    */
    coral::net::Endpoint BoundControlEndpoint() const;

    /**
    \brief  The endpoint to which the slave is publishing its output data.

    This is useful if the `dataPubEndpoint` argument passed to the constructor
    contains a wildcard port number, in which case this function will return
    the actual port used.
    */
    coral::net::Endpoint BoundDataPubEndpoint() const;

private:
    /*
    \brief  Responds to a message from the master.

    On input, `msg` must be the message received from master, and on output,
    it will contain the slave's reply.  Internally, the function forwards to
    the handler function that corresponds to the slave's current state.
    */
    void RequestReply(std::vector<zmq::message_t>& msg);

    // Each of these functions correspond to one of the slave's possible states.
    // On input, `msg` is a message from the master node, and when the function
    // returns, `msg` must contain the reply.  If the message triggers a state
    // change, the handler function must update m_stateHandler to point to the
    // function for the new state.
    void NotConnectedHandler(std::vector<zmq::message_t>& msg);
    void ConnectedHandler(std::vector<zmq::message_t>& msg);
    void ReadyHandler(std::vector<zmq::message_t>& msg);
    void PublishedHandler(std::vector<zmq::message_t>& msg);
    void StepFailedHandler(std::vector<zmq::message_t>& msg);

    // Performs the "describe" operation, including filling `msg` with a
    // reply message.
    void HandleDescribe(std::vector<zmq::message_t>& msg);

    // Performs the "set variables" operation for ReadyHandler(), including
    // filling `msg` with a reply message.
    void HandleSetVars(std::vector<zmq::message_t>& msg);

    // Performs the "set peers" operation for ReadyHandler(), including
    // filling `msg` with a reply message.
    void HandleSetPeers(std::vector<zmq::message_t>& msg);

    // Performs the time step for ReadyHandler()
    bool Step(const coralproto::execution::StepData& stepData);

    // Publishes all variable values (used by Step()).
    void PublishAll();

    // A pointer to the handler function for the current state.
    void (SlaveAgent::* m_stateHandler)(std::vector<zmq::message_t>&);

    // A less-than comparison functor for Variable objects, so we can put
    // them in a std::map.
    struct VariableLess
    {
        bool operator()(const coral::model::Variable& a, const coral::model::Variable& b) const
        {
            return ((a.Slave() << 16) + a.ID()) < ((b.Slave() << 16) + b.ID());
        }
    };

    // A class which keeps track of connections to our input variables and the
    // values we receive for them.
    class Connections
    {
    public:
        // Connects to the publisher endpoints
        void Connect(
            const coral::net::Endpoint* endpoints,
            std::size_t endpointsSize);

        // Establishes a connection between a remote output variable and one of
        // our input variables, breaking any existing connections to that input.
        void Couple(
            coral::model::Variable remoteOutput,
            coral::model::VariableID localInput);

        // Waits until all data has been received for the time step specified
        // by `stepID` and updates the slave instance with the new values.
        void Update(
            coral::slave::Instance& slaveInstance,
            coral::model::StepID stepID,
            std::chrono::milliseconds timeout);

    private:
        // Breaks a connection to a local input variable, if any.
        void Decouple(coral::model::VariableID localInput);

        // A bidirectional mapping between output variables and input variables.
        typedef boost::bimap<
            boost::bimaps::multiset_of<coral::model::Variable, VariableLess>,
            coral::model::VariableID>
            ConnectionBimap;

        ConnectionBimap m_connections;
        coral::bus::VariableSubscriber m_subscriber;
    };

    coral::slave::Instance& m_slaveInstance;
    std::chrono::milliseconds m_commTimeout;

    coral::net::zmqx::RepSocket m_control;
    coral::bus::VariablePublisher m_publisher;
    Connections m_connections;
    coral::model::SlaveID m_id; // The slave's ID number in the current execution

    coral::model::StepID m_currentStepID; // ID of ongoing or just completed step
};

/// Exception thrown when the slave receives a TERMINATE command.
class Shutdown : public std::exception
{
public:
    const char* what() const CORAL_NOEXCEPT override { return "Normal shutdown requested by master"; }
};

}}      // namespace
#endif  // header guard
<|endoftext|>