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

#include <boost/assign/list_of.hpp> // for 'map_list_of()'
#include <boost/foreach.hpp>

#include "checkpoints.h"

#include "main.h"
#include "uint256.h"

namespace Checkpoints
{
    typedef std::map<int, uint256> MapCheckpoints;

    //
    // What makes a good checkpoint block?
    // + Is surrounded by blocks with reasonable timestamps
    //   (no blocks before with a timestamp after, none after with
    //    timestamp before)
    // + Contains no strange transactions
    //

	// no checkpoint now, can be added in later releases
    static MapCheckpoints mapCheckpoints =
            boost::assign::map_list_of
            (  0, hashGenesisBlockOfficial )
			(  10, uint256("0x37123389e62e569cb8c6ea11ab93e4be8382b82323cbc0f017af1b94216ef13e"))
			(  50, uint256("0x58854ad0d27533eb2691c6580971e6945e950a4419117bed750b68064bf4d9ed"))
			(  100, uint256("0x597f8bea37d5885c80c0e64b9a70ed58aa7acddf94940b205a2049098e9ec14b"))
			(  500, uint256("0xa48c1e8d7a57dff9872930e8bc729b86ed8ee0ddb8631b4e9e67112d0db57c88"))
			(  1000, uint256("0xd7340ba3046b16eacef10ceec5de73e8f3ff55c33e33fff6b6d4e8bc311b07fc"))
			(  2000, uint256("0x23881c119e17bece6815f4b675fb390e36ba01d6dc447b28dc5ee21e081b872b"))
			(  2500, uint256("0x51f13e1ba91021cc7e8c40850055c660edbfe9977cb45c78e73299c817ecb749"))
			(  3000, uint256("0xb799e01f438c33760ec227c1f76fadeaa4e95bf76fa80ebb1e6fb538c5736164"))
			(  5000, uint256("0xff23a10acfc927be366c9a7f41dd60b0a9e5123fe0296239b7b660e6557921d1"))
			(  5200, uint256("0xff53a9ca9d94ced77dd60f044e23b28eca04fcb63c3583dafa6a0f3169a15e06"))
			(  7000, uint256("0x90dc96799b1932e0ddbe3651c326008bcea1213ec5ec4f4d9d1f66dd9fdceac6"))
			;

    bool CheckBlock(int nHeight, const uint256& hash)
    {
        if (fTestNet) return true; // Testnet has no checkpoints

        MapCheckpoints::const_iterator i = mapCheckpoints.find(nHeight);
        if (i == mapCheckpoints.end()) return true;
        return hash == i->second;
		// return true;
    }

    int GetTotalBlocksEstimate()
    {
        if (fTestNet) return 0;

        return mapCheckpoints.rbegin()->first;
		// return 0;
    }

    CBlockIndex* GetLastCheckpoint(const std::map<uint256, CBlockIndex*>& mapBlockIndex)
    {
        if (fTestNet) return NULL;

        BOOST_REVERSE_FOREACH(const MapCheckpoints::value_type& i, mapCheckpoints)
        {
            const uint256& hash = i.second;
            std::map<uint256, CBlockIndex*>::const_iterator t = mapBlockIndex.find(hash);
            if (t != mapBlockIndex.end())
                return t->second;
				// return NULL;
        }
        return NULL;
    }
}
<commit_msg>update checkpoint<commit_after>// Copyright (c) 2009-2012 The Bitcoin developers
// Copyright (c) 2011-2012 Litecoin Developers
// Copyright (c) 2013 iCoin Developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <boost/assign/list_of.hpp> // for 'map_list_of()'
#include <boost/foreach.hpp>

#include "checkpoints.h"

#include "main.h"
#include "uint256.h"

namespace Checkpoints
{
    typedef std::map<int, uint256> MapCheckpoints;

    //
    // What makes a good checkpoint block?
    // + Is surrounded by blocks with reasonable timestamps
    //   (no blocks before with a timestamp after, none after with
    //    timestamp before)
    // + Contains no strange transactions
    //

	// no checkpoint now, can be added in later releases
    static MapCheckpoints mapCheckpoints =
            boost::assign::map_list_of
            (  0, hashGenesisBlockOfficial )
			(  10, uint256("0x37123389e62e569cb8c6ea11ab93e4be8382b82323cbc0f017af1b94216ef13e"))
			(  50, uint256("0x58854ad0d27533eb2691c6580971e6945e950a4419117bed750b68064bf4d9ed"))
			(  100, uint256("0x597f8bea37d5885c80c0e64b9a70ed58aa7acddf94940b205a2049098e9ec14b"))
			(  500, uint256("0xa48c1e8d7a57dff9872930e8bc729b86ed8ee0ddb8631b4e9e67112d0db57c88"))
			(  1000, uint256("0xd7340ba3046b16eacef10ceec5de73e8f3ff55c33e33fff6b6d4e8bc311b07fc"))
			(  2000, uint256("0x23881c119e17bece6815f4b675fb390e36ba01d6dc447b28dc5ee21e081b872b"))
			(  2500, uint256("0x51f13e1ba91021cc7e8c40850055c660edbfe9977cb45c78e73299c817ecb749"))
			(  3000, uint256("0xb799e01f438c33760ec227c1f76fadeaa4e95bf76fa80ebb1e6fb538c5736164"))
			(  5000, uint256("0xff23a10acfc927be366c9a7f41dd60b0a9e5123fe0296239b7b660e6557921d1"))
			(  5200, uint256("0xff53a9ca9d94ced77dd60f044e23b28eca04fcb63c3583dafa6a0f3169a15e06"))
			(  7000, uint256("0x90dc96799b1932e0ddbe3651c326008bcea1213ec5ec4f4d9d1f66dd9fdceac6"))
			(  10000, uint256("0xc6f81a9e8095276e97904299f54da9d33c470aed4ab2cfd1b5fc326658d47667"))
			(  15000, uint256("0xa0858cdc8c2742df69bf9b31143f83b1d9c833bf77a998624068fd11fd242658"))
			(  17500, uint256("0xdf7f7219cdb74f4909ad7ecb94a71cc0e3edd59ec3014f6b6dc8c97d6196fcc0"))
			;

    bool CheckBlock(int nHeight, const uint256& hash)
    {
        if (fTestNet) return true; // Testnet has no checkpoints

        MapCheckpoints::const_iterator i = mapCheckpoints.find(nHeight);
        if (i == mapCheckpoints.end()) return true;
        return hash == i->second;
		// return true;
    }

    int GetTotalBlocksEstimate()
    {
        if (fTestNet) return 0;

        return mapCheckpoints.rbegin()->first;
		// return 0;
    }

    CBlockIndex* GetLastCheckpoint(const std::map<uint256, CBlockIndex*>& mapBlockIndex)
    {
        if (fTestNet) return NULL;

        BOOST_REVERSE_FOREACH(const MapCheckpoints::value_type& i, mapCheckpoints)
        {
            const uint256& hash = i.second;
            std::map<uint256, CBlockIndex*>::const_iterator t = mapBlockIndex.find(hash);
            if (t != mapBlockIndex.end())
                return t->second;
				// return NULL;
        }
        return NULL;
    }
}
<|endoftext|>


<commit_before>/******************************************************************************
*       SOFA, Simulation Open-Framework Architecture, development version     *
*                (c) 2006-2016 INRIA, USTL, UJF, CNRS, MGH                    *
*                                                                             *
* 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.          *
*******************************************************************************
*                               SOFA :: Modules                               *
*                                                                             *
* This component is open-source                                               *
*                                                                             *
* Contributors:                                                               *
*    - damien.marchal@univ-lille1.fr                                          *
*                                                                             *
* Contact information: contact@sofa-framework.org                             *
******************************************************************************/
/*****************************************************************************
* User of this library should read the documentation
* in the messaging.h file.
******************************************************************************/

#include "RichConsoleStyleMessageFormatter.h"
#include "Message.h"

#include <sofa/helper/system/console.h>
#include <sofa/helper/fixed_array.h>

#include <boost/tokenizer.hpp>
#include <boost/token_functions.hpp>
#include <boost/token_iterator.hpp>

namespace sofa
{

namespace helper
{

namespace logging
{

namespace richconsolestylemessageformater
{
/////////////////////////////// STATIC ELEMENT SPECIFIC TO RichConsoleStyleMessage /////////////////
typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
helper::fixed_array<std::string,Message::TypeCount> s_messageTypePrefixes;
helper::fixed_array<Console::ColorType,Message::TypeCount> s_messageTypeColors;

int initColors(){
    s_messageTypePrefixes[Message::Advice]      = "[SUGGESTION] ";
    s_messageTypePrefixes[Message::Info]        = "[INFO]    ";
    s_messageTypePrefixes[Message::Deprecated]  = "[DEPRECATED] ";
    s_messageTypePrefixes[Message::Warning]     = "[WARNING] ";
    s_messageTypePrefixes[Message::Error]       = "[ERROR]   ";
    s_messageTypePrefixes[Message::Fatal]       = "[FATAL]   ";
    s_messageTypePrefixes[Message::TEmpty]      = "[EMPTY]   ";

    s_messageTypeColors[Message::Advice]       = Console::BRIGHT_GREEN;
    s_messageTypeColors[Message::Info]       = Console::BRIGHT_GREEN;
    s_messageTypeColors[Message::Deprecated] = Console::BRIGHT_YELLOW;
    s_messageTypeColors[Message::Warning]    = Console::BRIGHT_CYAN;
    s_messageTypeColors[Message::Error]      = Console::BRIGHT_RED;
    s_messageTypeColors[Message::Fatal]      = Console::BRIGHT_PURPLE;
    s_messageTypeColors[Message::TEmpty]     = Console::DEFAULT_COLOR;
    return 1;
}

int s_isInited = initColors();

///
/// \brief simpleFormat a text containing our markdown 'tags'
/// \param jsize size of the line prefix to fill with space (for left side alignment)
/// \param text  the text to format
/// \param line_length number of column to render to to
/// \param wrapped the destination stream where to write the formatted text.
///
void simpleFormat(int jsize, const std::string& text, size_t line_length,
                  std::ostream& wrapped)
{
    //TODO(dmarchal): All that code is a mess...need to be done for real.

    /// space and * are separator that are returned in the token flow
    /// while "\n" is a 'hidden' separator.
    static boost::char_separator<char> sep("\n", "* '");

    std::string emptyspace(jsize, ' ') ;

    tokenizer tokens(text, sep) ;

    int numspaces = 0 ;
    bool beginOfLine = false ;
    bool isInItalic = false ;

    size_t space_left = line_length;
    for (tokenizer::iterator tok_iter = tokens.begin();tok_iter != tokens.end(); ++tok_iter)
    {
        const std::string& word = *tok_iter;
        if(word=="'" || word=="*")
        {
            if(isInItalic)
            {
                isInItalic=false;
                wrapped << Console::DEFAULT_CODE ;
                wrapped << "'";
                continue;
            }
            else
            {
                isInItalic=true;

                if(numspaces==1){
                    if(!beginOfLine){
                        wrapped << " ";
                        numspaces = 0;
                        space_left--;
                    }else{
                        wrapped << emptyspace ;
                    }
                }

                wrapped << "'";
                wrapped << Console::ITALIC ;
                wrapped << Console::UNDERLINE ;
                continue;
            }
        }else if(word==" ")
        {
            if(numspaces==1)
            {
                wrapped << "\n"  ;
                numspaces=0;
                space_left = line_length;
                beginOfLine=true;
                continue;
            }else
            {
                numspaces=1;
                continue;
            }
        }else{
            if(numspaces==1){
                if(!beginOfLine){
                    wrapped << " ";
                    numspaces = 0;
                    space_left--;
                }else{
                    wrapped << emptyspace ;
                }
            }
        }

        if (space_left < word.length() + 1)
        {
            if(word.length()>line_length)
            {
                std::string first;
                size_t curidx=0;
                size_t endidx=std::min(word.length(), space_left);

                while(curidx < word.length())
                {
                    first=word.substr(curidx,endidx);

                    if(beginOfLine)
                        wrapped << emptyspace ;

                    beginOfLine=false;
                    wrapped << first ;

                    curidx+=endidx;
                    endidx=std::min(word.length()-curidx, line_length);

                    if(curidx < word.length())
                    {
                        wrapped << '\n' ;
                        beginOfLine=true;
                    }
                }
                space_left = line_length - first.length();
            }
            else
            {
                wrapped << "\n";
                wrapped << emptyspace ;
                wrapped << word ;
                space_left = line_length-word.length();
            }
        }
        else
        {
            if(beginOfLine)
                wrapped << emptyspace ;

            beginOfLine=false;
            wrapped << word;
            space_left -= word.length() ;
        }
    }
}

////////////////////////////// RichConsoleStyleMessageFormatter Implementation /////////////////////
RichConsoleStyleMessageFormatter::RichConsoleStyleMessageFormatter(){}

void RichConsoleStyleMessageFormatter::formatMessage(const Message& m, std::ostream& out)
{
    int psize = s_messageTypePrefixes[m.type()].size() ;

    out << s_messageTypeColors[m.type()] << s_messageTypePrefixes[m.type()];

    if (!m.sender().empty())
    {
        if( m.componentInfo() )
        {
            psize +=m.sender().size()+m.componentInfo()->m_name.size()+5 ;
            out << Console::BLUE << "[" << m.sender()<< "(" << m.componentInfo()->m_name << ")] ";
        }
        else
        {
            psize +=m.sender().size()+3 ;
            out << Console::BLUE << "[" << m.sender()<< "] ";
        }
    }
    out << Console::DEFAULT_COLOR;

    /// Format & align the text and write the result into 'out'.
    simpleFormat(psize , m.message().str(), Console::getColumnCount()-psize, out) ;

    std::stringstream buf;
    std::string emptyspace(psize, ' ') ;

    buf << "Emitted from '" << m.fileInfo().filename << "' line " << m.fileInfo().line ;
    out << "\n" << emptyspace ;
    simpleFormat(psize , buf.str(), Console::getColumnCount()-psize, out) ;

    ///Restore the console rendering attribute.
    out << Console::DEFAULT_COLOR;
    out << Console::DEFAULT_CODE;
    out << std::endl ;
}

} // richconsolestylmessageformatter
} // logging
} // helper
} // sofa

<commit_msg>[SofaKernel] FIX the rich style formatter that was not wrapping line correctly<commit_after>/******************************************************************************
*       SOFA, Simulation Open-Framework Architecture, development version     *
*                (c) 2006-2016 INRIA, USTL, UJF, CNRS, MGH                    *
*                                                                             *
* 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.          *
*******************************************************************************
*                               SOFA :: Modules                               *
*                                                                             *
* This component is open-source                                               *
*                                                                             *
* Contributors:                                                               *
*    - damien.marchal@univ-lille1.fr                                          *
*                                                                             *
* Contact information: contact@sofa-framework.org                             *
******************************************************************************/
/*****************************************************************************
* User of this library should read the documentation
* in the messaging.h file.
******************************************************************************/

#include "RichConsoleStyleMessageFormatter.h"
#include "Message.h"

#include <sofa/helper/system/console.h>
#include <sofa/helper/fixed_array.h>

#include <boost/tokenizer.hpp>
#include <boost/token_functions.hpp>
#include <boost/token_iterator.hpp>

namespace sofa
{

namespace helper
{

namespace logging
{

namespace richconsolestylemessageformater
{
/////////////////////////////// STATIC ELEMENT SPECIFIC TO RichConsoleStyleMessage /////////////////
typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
helper::fixed_array<std::string,Message::TypeCount> s_messageTypePrefixes;
helper::fixed_array<Console::ColorType,Message::TypeCount> s_messageTypeColors;

int initColors(){
    s_messageTypePrefixes[Message::Advice]      = "[SUGGESTION] ";
    s_messageTypePrefixes[Message::Info]        = "[INFO]    ";
    s_messageTypePrefixes[Message::Deprecated]  = "[DEPRECATED] ";
    s_messageTypePrefixes[Message::Warning]     = "[WARNING] ";
    s_messageTypePrefixes[Message::Error]       = "[ERROR]   ";
    s_messageTypePrefixes[Message::Fatal]       = "[FATAL]   ";
    s_messageTypePrefixes[Message::TEmpty]      = "[EMPTY]   ";

    s_messageTypeColors[Message::Advice]       = Console::BRIGHT_GREEN;
    s_messageTypeColors[Message::Info]       = Console::BRIGHT_GREEN;
    s_messageTypeColors[Message::Deprecated] = Console::BRIGHT_YELLOW;
    s_messageTypeColors[Message::Warning]    = Console::BRIGHT_CYAN;
    s_messageTypeColors[Message::Error]      = Console::BRIGHT_RED;
    s_messageTypeColors[Message::Fatal]      = Console::BRIGHT_PURPLE;
    s_messageTypeColors[Message::TEmpty]     = Console::DEFAULT_COLOR;
    return 1;
}

int s_isInited = initColors();

///
/// \brief simpleFormat a text containing our markdown 'tags'
/// \param jsize size of the line prefix to fill with space (for left side alignment)
/// \param text  the text to format
/// \param line_length number of column to render to to
/// \param wrapped the destination stream where to write the formatted text.
///
void simpleFormat(int jsize, const std::string& text, size_t line_length,
                  std::ostream& wrapped)
{
    //TODO(dmarchal): All that code is a mess...need to be done for real.

    /// space and * are separator that are returned in the token flow
    /// while "\n" is a 'hidden' separator.
    static boost::char_separator<char> sep("\n", "* '");

    std::string emptyspace(jsize, ' ') ;

    tokenizer tokens(text, sep) ;

    int numspaces = 0 ;
    bool beginOfLine = false ;
    bool isInItalic = false ;

    size_t space_left = line_length;
    for (tokenizer::iterator tok_iter = tokens.begin();tok_iter != tokens.end(); ++tok_iter)
    {
        const std::string& word = *tok_iter;
        if(word=="'" || word=="*")
        {
            if(isInItalic)
            {
                isInItalic=false;
                wrapped << Console::DEFAULT_CODE ;
                wrapped << "'";
                continue;
            }
            else
            {
                isInItalic=true;

                if(numspaces==1){
                    if(!beginOfLine){
                        wrapped << " ";
                        numspaces = 0;
                        space_left--;
                    }else{
                        wrapped << emptyspace ;
                    }
                }

                wrapped << "'";
                wrapped << Console::ITALIC ;
                wrapped << Console::UNDERLINE ;
                continue;
            }
        }else if(word==" ")
        {
            if(numspaces==1)
            {
                wrapped << "\n"  ;
                numspaces=0;
                space_left = line_length;
                beginOfLine=true;
                continue;
            }else
            {
                numspaces=1;
                continue;
            }
        }else{
            if(numspaces==1){
                if(!beginOfLine){
                    wrapped << " ";
                    numspaces = 0;
                    space_left--;
                }else{
                    wrapped << Console::DEFAULT_CODE;
                    wrapped << Console::DEFAULT_COLOR;
                    wrapped << emptyspace ;
                    if(isInItalic){
                        wrapped << Console::ITALIC;
                        wrapped << Console::UNDERLINE;
                    }
                }
            }
        }

        if (space_left < word.length() + 1)
        {
            if(word.length()>line_length)
            {
                std::string first;
                size_t curidx=0;
                size_t endidx=std::min(word.length(), space_left-1);

                while(curidx < word.length())
                {
                    first=word.substr(curidx,endidx);

                    if(beginOfLine){
                        wrapped << Console::DEFAULT_CODE;
                        wrapped << Console::DEFAULT_COLOR;
                        wrapped << emptyspace ;
                        if(isInItalic){
                            wrapped << Console::ITALIC;
                            wrapped << Console::UNDERLINE;
                        }
                    }
                    beginOfLine=false;
                    wrapped << first ;

                    curidx+=endidx;
                    endidx=std::min(word.length()-curidx, line_length-1);

                    if(curidx < word.length())
                    {
                        wrapped << "\n" ;
                        beginOfLine=true;
                    }
                }
                space_left = line_length - first.length();
            }
            else
            {
                wrapped << "\n";
                wrapped << Console::DEFAULT_CODE;
                wrapped << Console::DEFAULT_COLOR;
                wrapped << emptyspace ;
                if(isInItalic){
                    wrapped << Console::ITALIC;
                    wrapped << Console::UNDERLINE;
                }
                wrapped << word ;
                space_left = line_length-word.length();
            }
        }
        else
        {
            if(beginOfLine){
                wrapped << Console::DEFAULT_CODE;
                wrapped << Console::DEFAULT_COLOR;
                wrapped << emptyspace ;
                if(isInItalic){
                    wrapped << Console::ITALIC;
                    wrapped << Console::UNDERLINE;
                }
            }
            beginOfLine=false;
            wrapped << word;
            space_left -= word.length() ;
        }
    }
}

////////////////////////////// RichConsoleStyleMessageFormatter Implementation /////////////////////
RichConsoleStyleMessageFormatter::RichConsoleStyleMessageFormatter(){}

void RichConsoleStyleMessageFormatter::formatMessage(const Message& m, std::ostream& out)
{
    int psize = s_messageTypePrefixes[m.type()].size() ;

    out << s_messageTypeColors[m.type()] << s_messageTypePrefixes[m.type()];

    if (!m.sender().empty())
    {
        if( m.componentInfo() )
        {
            psize +=m.sender().size()+m.componentInfo()->m_name.size()+5 ;
            out << Console::BLUE << "[" << m.sender()<< "(" << m.componentInfo()->m_name << ")] ";
        }
        else
        {
            psize +=m.sender().size()+3 ;
            out << Console::BLUE << "[" << m.sender()<< "] ";
        }
    }
    out << Console::DEFAULT_COLOR;

    /// Format & align the text and write the result into 'out'.
    simpleFormat(psize , m.message().str(), Console::getColumnCount()-psize, out) ;

    std::stringstream buf;
    std::string emptyspace(psize, ' ') ;

    buf << "Emitted from '" << m.fileInfo().filename << "' line " << m.fileInfo().line ;
    out << "\n" << emptyspace ;
    simpleFormat(psize , buf.str(), Console::getColumnCount()-psize, out) ;

    ///Restore the console rendering attribute.
    out << Console::DEFAULT_COLOR;
    out << Console::DEFAULT_CODE;
    out << std::endl ;
}

} // richconsolestylmessageformatter
} // logging
} // helper
} // sofa

<|endoftext|>


<commit_before>// SPDX-License-Identifier: Apache-2.0
// ----------------------------------------------------------------------------
// Copyright 2021 Arm Limited
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy
// of the License at:
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.
// ----------------------------------------------------------------------------

/**
 * @brief Functions for the library entrypoint.
 */

#if defined(ASTCENC_DIAGNOSTICS)

#include <cassert>
#include <cstdarg>
#include <cstdio>
#include <string>

#include "astcenc_diagnostic_trace.h"

/** @brief The global trace logger. */
static TraceLog* g_TraceLog = nullptr;

/** @brief The JSON indentation level. */
static const int g_trace_indent = 2;

TraceLog::TraceLog(
	const char* file_name):
	m_file(file_name, std::ofstream::out | std::ofstream::binary)
{
	assert(!g_TraceLog);
	g_TraceLog = this;
	m_root = new TraceNode("root");
}

TraceNode* TraceLog::get_current_leaf()
{
	if (m_stack.size())
	{
		return m_stack.back();
	}

	return nullptr;
}

int TraceLog::get_depth()
{
	return m_stack.size();
}

TraceLog::~TraceLog()
{
	assert(g_TraceLog == this);
	delete m_root;
	g_TraceLog = nullptr;
}

TraceNode::TraceNode(
	const char* format,
	...
) {
	// Format the name string
	constexpr size_t bufsz = 256;
	char buffer[bufsz];

	va_list args;
	va_start (args, format);
	vsnprintf (buffer, bufsz, format, args);
	va_end (args);

	// Guarantee there is a nul termintor
	buffer[bufsz - 1] = 0;

	// Generate the node
	TraceNode* parent = g_TraceLog->get_current_leaf();
	int depth = g_TraceLog->get_depth();
	g_TraceLog->m_stack.push_back(this);

	bool comma = parent && parent->m_attrib_count;
	auto& out = g_TraceLog->m_file;

	if (parent)
	{
		parent->m_attrib_count++;
	}

	if (comma)
	{
		out << ',';
	}

	if (depth)
	{
		out << '\n';
	}

	int out_indent = (depth * 2) * g_trace_indent;
	int in_indent = (depth * 2 + 1) * g_trace_indent;

	std::string out_indents("");
	if (out_indent)
	{
		out_indents = std::string(out_indent, ' ');
	}

	std::string in_indents(in_indent, ' ');

	out << out_indents << "[ \"node\", \"" << buffer << "\",\n";
	out << in_indents << "[";
}

void TraceNode::add_attrib(
	std::string type,
	std::string key,
	std::string value
) {
	(void)type;

	int depth = g_TraceLog->get_depth();
	int indent = (depth * 2) * g_trace_indent;
	auto& out = g_TraceLog->m_file;
	bool comma = m_attrib_count;
	m_attrib_count++;

	if (comma)
	{
		out << ',';
	}

	out << '\n';
	out << std::string(indent, ' ') << "[ "
	                                << "\"" << key << "\", "
	                                << value << " ]";
}

TraceNode::~TraceNode()
{
	g_TraceLog->m_stack.pop_back();

	auto& out = g_TraceLog->m_file;
	int depth = g_TraceLog->get_depth();
	int out_indent = (depth * 2) * g_trace_indent;
	int in_indent = (depth * 2 + 1) * g_trace_indent;

	std::string out_indents("");
	if (out_indent)
	{
		out_indents = std::string(out_indent, ' ');
	}

	std::string in_indents(in_indent, ' ');

	if (m_attrib_count)
	{
		out << "\n" << in_indents;
	}
	out << "]\n";

	out << out_indents << "]";
}

void trace_add_data(
	const char* key,
	const char* format,
	...
) {
	constexpr size_t bufsz = 256;
	char buffer[bufsz];

	va_list args;
	va_start (args, format);
	vsnprintf (buffer, bufsz, format, args);
	va_end (args);

	// Guarantee there is a nul termintor
	buffer[bufsz - 1] = 0;

	std::string value = "\"" + std::string(buffer) + "\"";

	TraceNode* node = g_TraceLog->get_current_leaf();
	node->add_attrib("str", key, value);
}

void trace_add_data(
	const char* key,
	float value
) {
  	char buffer[256];
	sprintf(buffer, "%.20g", (double)value);
	TraceNode* node = g_TraceLog->get_current_leaf();
	node->add_attrib("float", key, buffer);
}

void trace_add_data(
	const char* key,
	int value
) {
	TraceNode* node = g_TraceLog->get_current_leaf();
	node->add_attrib("int", key, std::to_string(value));
}

void trace_add_data(
	const char* key,
	unsigned int value
) {
	TraceNode* node = g_TraceLog->get_current_leaf();
	node->add_attrib("int", key, std::to_string(value));
}

#endif
<commit_msg>Cleanup API for diagnostic_trace<commit_after>// SPDX-License-Identifier: Apache-2.0
// ----------------------------------------------------------------------------
// Copyright 2021 Arm Limited
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy
// of the License at:
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.
// ----------------------------------------------------------------------------

/**
 * @brief Functions for the library entrypoint.
 */

#if defined(ASTCENC_DIAGNOSTICS)

#include <cassert>
#include <cstdarg>
#include <cstdio>
#include <string>

#include "astcenc_diagnostic_trace.h"

/** @brief The global trace logger. */
static TraceLog* g_TraceLog = nullptr;

/** @brief The JSON indentation level. */
static const int g_trace_indent = 2;

TraceLog::TraceLog(
	const char* file_name):
	m_file(file_name, std::ofstream::out | std::ofstream::binary)
{
	assert(!g_TraceLog);
	g_TraceLog = this;
	m_root = new TraceNode("root");
}

/* See header for documentation. */
TraceNode* TraceLog::get_current_leaf()
{
	if (m_stack.size())
	{
		return m_stack.back();
	}

	return nullptr;
}

/* See header for documentation. */
int TraceLog::get_depth()
{
	return m_stack.size();
}

/* See header for documentation. */
TraceLog::~TraceLog()
{
	assert(g_TraceLog == this);
	delete m_root;
	g_TraceLog = nullptr;
}

/* See header for documentation. */
TraceNode::TraceNode(
	const char* format,
	...
) {
	// Format the name string
	constexpr size_t bufsz = 256;
	char buffer[bufsz];

	va_list args;
	va_start (args, format);
	vsnprintf (buffer, bufsz, format, args);
	va_end (args);

	// Guarantee there is a nul termintor
	buffer[bufsz - 1] = 0;

	// Generate the node
	TraceNode* parent = g_TraceLog->get_current_leaf();
	int depth = g_TraceLog->get_depth();
	g_TraceLog->m_stack.push_back(this);

	bool comma = parent && parent->m_attrib_count;
	auto& out = g_TraceLog->m_file;

	if (parent)
	{
		parent->m_attrib_count++;
	}

	if (comma)
	{
		out << ',';
	}

	if (depth)
	{
		out << '\n';
	}

	int out_indent = (depth * 2) * g_trace_indent;
	int in_indent = (depth * 2 + 1) * g_trace_indent;

	std::string out_indents("");
	if (out_indent)
	{
		out_indents = std::string(out_indent, ' ');
	}

	std::string in_indents(in_indent, ' ');

	out << out_indents << "[ \"node\", \"" << buffer << "\",\n";
	out << in_indents << "[";
}

/* See header for documentation. */
void TraceNode::add_attrib(
	std::string type,
	std::string key,
	std::string value
) {
	(void)type;

	int depth = g_TraceLog->get_depth();
	int indent = (depth * 2) * g_trace_indent;
	auto& out = g_TraceLog->m_file;
	bool comma = m_attrib_count;
	m_attrib_count++;

	if (comma)
	{
		out << ',';
	}

	out << '\n';
	out << std::string(indent, ' ') << "[ "
	                                << "\"" << key << "\", "
	                                << value << " ]";
}

/* See header for documentation. */
TraceNode::~TraceNode()
{
	g_TraceLog->m_stack.pop_back();

	auto& out = g_TraceLog->m_file;
	int depth = g_TraceLog->get_depth();
	int out_indent = (depth * 2) * g_trace_indent;
	int in_indent = (depth * 2 + 1) * g_trace_indent;

	std::string out_indents("");
	if (out_indent)
	{
		out_indents = std::string(out_indent, ' ');
	}

	std::string in_indents(in_indent, ' ');

	if (m_attrib_count)
	{
		out << "\n" << in_indents;
	}
	out << "]\n";

	out << out_indents << "]";
}

/* See header for documentation. */
void trace_add_data(
	const char* key,
	const char* format,
	...
) {
	constexpr size_t bufsz = 256;
	char buffer[bufsz];

	va_list args;
	va_start (args, format);
	vsnprintf (buffer, bufsz, format, args);
	va_end (args);

	// Guarantee there is a nul termintor
	buffer[bufsz - 1] = 0;

	std::string value = "\"" + std::string(buffer) + "\"";

	TraceNode* node = g_TraceLog->get_current_leaf();
	node->add_attrib("str", key, value);
}

/* See header for documentation. */
void trace_add_data(
	const char* key,
	float value
) {
  	char buffer[256];
	sprintf(buffer, "%.20g", (double)value);
	TraceNode* node = g_TraceLog->get_current_leaf();
	node->add_attrib("float", key, buffer);
}

/* See header for documentation. */
void trace_add_data(
	const char* key,
	int value
) {
	TraceNode* node = g_TraceLog->get_current_leaf();
	node->add_attrib("int", key, std::to_string(value));
}

/* See header for documentation. */
void trace_add_data(
	const char* key,
	unsigned int value
) {
	TraceNode* node = g_TraceLog->get_current_leaf();
	node->add_attrib("int", key, std::to_string(value));
}

#endif
<|endoftext|>


<commit_before>/*

Copyright (c) 2007, Un Shyam
All rights reserved.

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.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

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; 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.

*/

#include <algorithm>
#include <iostream>

#include "libtorrent/hasher.hpp"
#include "libtorrent/pe_crypto.hpp"
#include "libtorrent/session.hpp"

#include "setup_transfer.hpp"
#include "test.hpp"

#ifndef TORRENT_DISABLE_ENCRYPTION

char const* pe_policy(libtorrent::pe_settings::enc_policy policy)
{
	using namespace libtorrent;

	if (policy == pe_settings::disabled) return "disabled";
	else if (policy == pe_settings::enabled) return "enabled";
	else if (policy == pe_settings::forced) return "forced";
	return "unknown";
}

void display_pe_settings(libtorrent::pe_settings s)
{
	using namespace libtorrent;

	fprintf(stderr, "out_enc_policy - %s\tin_enc_policy - %s\n"
		, pe_policy(s.out_enc_policy), pe_policy(s.in_enc_policy));

	fprintf(stderr, "enc_level - %s\t\tprefer_rc4 - %s\n"
		, s.allowed_enc_level == pe_settings::plaintext ? "plaintext"
		: s.allowed_enc_level == pe_settings::rc4 ? "rc4"
		: s.allowed_enc_level == pe_settings::both ? "both" : "unknown"
		, s.prefer_rc4 ? "true": "false");
}

void test_transfer(libtorrent::pe_settings::enc_policy policy,
		   libtorrent::pe_settings::enc_level level = libtorrent::pe_settings::both,
		   bool pref_rc4 = false)
{
	using namespace libtorrent;

	// these are declared before the session objects
	// so that they are destructed last. This enables
	// the sessions to destruct in parallel
	session_proxy p1;
	session_proxy p2;

	session ses1(fingerprint("LT", 0, 1, 0, 0), std::make_pair(48800, 49000), "0.0.0.0", 0);
	session ses2(fingerprint("LT", 0, 1, 0, 0), std::make_pair(49800, 50000), "0.0.0.0", 0);
	pe_settings s;

	s.out_enc_policy = libtorrent::pe_settings::enabled;
	s.in_enc_policy = libtorrent::pe_settings::enabled;

	s.allowed_enc_level = pe_settings::both;
	ses2.set_pe_settings(s);

	s.out_enc_policy = policy;
	s.in_enc_policy = policy;
	s.allowed_enc_level = level;
	s.prefer_rc4 = pref_rc4;
	ses1.set_pe_settings(s);

	s = ses1.get_pe_settings();
	fprintf(stderr, " Session1 \n");
	display_pe_settings(s);
	s = ses2.get_pe_settings();
	fprintf(stderr, " Session2 \n");
	display_pe_settings(s);

	torrent_handle tor1;
	torrent_handle tor2;

	using boost::tuples::ignore;
	boost::tie(tor1, tor2, ignore) = setup_transfer(&ses1, &ses2, 0, true, false, true
		, "_pe", 16 * 1024, 0, false, 0, true);

	fprintf(stderr, "waiting for transfer to complete\n");

	for (int i = 0; i < 50; ++i)
	{
		torrent_status s = tor2.status();
		print_alerts(ses1, "ses1");
		print_alerts(ses2, "ses2");

		if (s.is_seeding) break;
		test_sleep(1000);
	}

	TEST_CHECK(tor2.status().is_seeding);
 	if (tor2.status().is_seeding) fprintf(stderr, "done\n");
	ses1.remove_torrent(tor1);
	ses2.remove_torrent(tor2);

	// this allows shutting down the sessions in parallel
	p1 = ses1.abort();
	p2 = ses2.abort();

	error_code ec;
	remove_all("tmp1_pe", ec);
	remove_all("tmp2_pe", ec);
	remove_all("tmp3_pe", ec);
}

void test_enc_handler(libtorrent::encryption_handler* a, libtorrent::encryption_handler* b)
{
	int repcount = 128;
	for (int rep = 0; rep < repcount; ++rep)
	{
		std::size_t buf_len = rand() % (512 * 1024);
		char* buf = new char[buf_len];
		char* cmp_buf = new char[buf_len];

		std::generate(buf, buf + buf_len, &std::rand);
		std::memcpy(cmp_buf, buf, buf_len);

		a->encrypt(buf, buf_len);
		TEST_CHECK(!std::equal(buf, buf + buf_len, cmp_buf));
		b->decrypt(buf, buf_len);
		TEST_CHECK(std::equal(buf, buf + buf_len, cmp_buf));

		b->encrypt(buf, buf_len);
		TEST_CHECK(!std::equal(buf, buf + buf_len, cmp_buf));
		a->decrypt(buf, buf_len);
		TEST_CHECK(std::equal(buf, buf + buf_len, cmp_buf));

		delete[] buf;
		delete[] cmp_buf;
	}
}

#endif

int test_main()
{
	using namespace libtorrent;

#ifndef TORRENT_DISABLE_ENCRYPTION
	int repcount = 128;

	for (int rep = 0; rep < repcount; ++rep)
	{
		dh_key_exchange DH1, DH2;

		DH1.compute_secret(DH2.get_local_key());
		DH2.compute_secret(DH1.get_local_key());

		TEST_CHECK(std::equal(DH1.get_secret(), DH1.get_secret() + 96, DH2.get_secret()));
	}

	dh_key_exchange DH1, DH2;
	DH1.compute_secret(DH2.get_local_key());
	DH2.compute_secret(DH1.get_local_key());

	TEST_CHECK(std::equal(DH1.get_secret(), DH1.get_secret() + 96, DH2.get_secret()));

	sha1_hash test1_key = hasher("test1_key",8).final();
	sha1_hash test2_key = hasher("test2_key",8).final();

	fprintf(stderr, "testing RC4 handler\n");
	rc4_handler rc41;
	rc41.set_incoming_key(&test2_key[0], 20);
	rc41.set_outgoing_key(&test1_key[0], 20);
	rc4_handler rc42;
	rc42.set_incoming_key(&test1_key[0], 20);
	rc42.set_outgoing_key(&test2_key[0], 20);
	test_enc_handler(&rc41, &rc42);

	test_transfer(pe_settings::disabled);

	test_transfer(pe_settings::forced, pe_settings::plaintext);
	test_transfer(pe_settings::forced, pe_settings::rc4);
	test_transfer(pe_settings::forced, pe_settings::both, false);
	test_transfer(pe_settings::forced, pe_settings::both, true);

	test_transfer(pe_settings::enabled, pe_settings::plaintext);
	test_transfer(pe_settings::enabled, pe_settings::rc4);
	test_transfer(pe_settings::enabled, pe_settings::both, false);
	test_transfer(pe_settings::enabled, pe_settings::both, true);
#else
	fprintf(stderr, "PE test not run because it's disabled\n");
#endif

	return 0;
}

<commit_msg>attempt to make test_pe_crypto pass under valgrind in reasonable time<commit_after>/*

Copyright (c) 2007, Un Shyam
All rights reserved.

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.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

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; 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.

*/

#include <algorithm>
#include <iostream>

#include "libtorrent/hasher.hpp"
#include "libtorrent/pe_crypto.hpp"
#include "libtorrent/session.hpp"

#include "setup_transfer.hpp"
#include "test.hpp"

#ifndef TORRENT_DISABLE_ENCRYPTION

char const* pe_policy(libtorrent::pe_settings::enc_policy policy)
{
	using namespace libtorrent;

	if (policy == pe_settings::disabled) return "disabled";
	else if (policy == pe_settings::enabled) return "enabled";
	else if (policy == pe_settings::forced) return "forced";
	return "unknown";
}

void display_pe_settings(libtorrent::pe_settings s)
{
	using namespace libtorrent;

	fprintf(stderr, "out_enc_policy - %s\tin_enc_policy - %s\n"
		, pe_policy(s.out_enc_policy), pe_policy(s.in_enc_policy));

	fprintf(stderr, "enc_level - %s\t\tprefer_rc4 - %s\n"
		, s.allowed_enc_level == pe_settings::plaintext ? "plaintext"
		: s.allowed_enc_level == pe_settings::rc4 ? "rc4"
		: s.allowed_enc_level == pe_settings::both ? "both" : "unknown"
		, s.prefer_rc4 ? "true": "false");
}

void test_transfer(libtorrent::pe_settings::enc_policy policy
	, int timeout
	, libtorrent::pe_settings::enc_level level = libtorrent::pe_settings::both
	, bool pref_rc4 = false)
{
	using namespace libtorrent;

	// these are declared before the session objects
	// so that they are destructed last. This enables
	// the sessions to destruct in parallel
	session_proxy p1;
	session_proxy p2;

	session ses1(fingerprint("LT", 0, 1, 0, 0), std::make_pair(48800, 49000), "0.0.0.0", 0);
	session ses2(fingerprint("LT", 0, 1, 0, 0), std::make_pair(49800, 50000), "0.0.0.0", 0);
	pe_settings s;

	s.out_enc_policy = libtorrent::pe_settings::enabled;
	s.in_enc_policy = libtorrent::pe_settings::enabled;

	s.allowed_enc_level = pe_settings::both;
	ses2.set_pe_settings(s);

	s.out_enc_policy = policy;
	s.in_enc_policy = policy;
	s.allowed_enc_level = level;
	s.prefer_rc4 = pref_rc4;
	ses1.set_pe_settings(s);

	s = ses1.get_pe_settings();
	fprintf(stderr, " Session1 \n");
	display_pe_settings(s);
	s = ses2.get_pe_settings();
	fprintf(stderr, " Session2 \n");
	display_pe_settings(s);

	torrent_handle tor1;
	torrent_handle tor2;

	using boost::tuples::ignore;
	boost::tie(tor1, tor2, ignore) = setup_transfer(&ses1, &ses2, 0, true, false, true
		, "_pe", 16 * 1024, 0, false, 0, true);

	fprintf(stderr, "waiting for transfer to complete\n");

	for (int i = 0; i < timeout * 10; ++i)
	{
		torrent_status s = tor2.status();
		print_alerts(ses1, "ses1");
		print_alerts(ses2, "ses2");

		if (s.is_seeding) break;
		test_sleep(100);
	}

	TEST_CHECK(tor2.status().is_seeding);
 	if (tor2.status().is_seeding) fprintf(stderr, "done\n");
	ses1.remove_torrent(tor1);
	ses2.remove_torrent(tor2);

	// this allows shutting down the sessions in parallel
	p1 = ses1.abort();
	p2 = ses2.abort();

	error_code ec;
	remove_all("tmp1_pe", ec);
	remove_all("tmp2_pe", ec);
	remove_all("tmp3_pe", ec);
}

void test_enc_handler(libtorrent::encryption_handler* a, libtorrent::encryption_handler* b)
{
#ifdef TORRENT_USE_VALGRIND
	const int repcount = 10;
#else
	const int repcount = 128;
#endif
	for (int rep = 0; rep < repcount; ++rep)
	{
		std::size_t buf_len = rand() % (512 * 1024);
		char* buf = new char[buf_len];
		char* cmp_buf = new char[buf_len];

		std::generate(buf, buf + buf_len, &std::rand);
		std::memcpy(cmp_buf, buf, buf_len);

		a->encrypt(buf, buf_len);
		TEST_CHECK(!std::equal(buf, buf + buf_len, cmp_buf));
		b->decrypt(buf, buf_len);
		TEST_CHECK(std::equal(buf, buf + buf_len, cmp_buf));

		b->encrypt(buf, buf_len);
		TEST_CHECK(!std::equal(buf, buf + buf_len, cmp_buf));
		a->decrypt(buf, buf_len);
		TEST_CHECK(std::equal(buf, buf + buf_len, cmp_buf));

		delete[] buf;
		delete[] cmp_buf;
	}
}

#endif

int test_main()
{
	using namespace libtorrent;

#ifndef TORRENT_DISABLE_ENCRYPTION

#ifdef TORRENT_USE_VALGRIND
	const int repcount = 10;
#else
	const int repcount = 128;
#endif

	for (int rep = 0; rep < repcount; ++rep)
	{
		dh_key_exchange DH1, DH2;

		DH1.compute_secret(DH2.get_local_key());
		DH2.compute_secret(DH1.get_local_key());

		TEST_CHECK(std::equal(DH1.get_secret(), DH1.get_secret() + 96, DH2.get_secret()));
	}

	dh_key_exchange DH1, DH2;
	DH1.compute_secret(DH2.get_local_key());
	DH2.compute_secret(DH1.get_local_key());

	TEST_CHECK(std::equal(DH1.get_secret(), DH1.get_secret() + 96, DH2.get_secret()));

	sha1_hash test1_key = hasher("test1_key",8).final();
	sha1_hash test2_key = hasher("test2_key",8).final();

	fprintf(stderr, "testing RC4 handler\n");
	rc4_handler rc41;
	rc41.set_incoming_key(&test2_key[0], 20);
	rc41.set_outgoing_key(&test1_key[0], 20);
	rc4_handler rc42;
	rc42.set_incoming_key(&test1_key[0], 20);
	rc42.set_outgoing_key(&test2_key[0], 20);
	test_enc_handler(&rc41, &rc42);

#ifdef TORRENT_USE_VALGRIND
	const int timeout = 10;
#else
	const int timeout = 5;
#endif

	test_transfer(pe_settings::disabled, timeout);

	test_transfer(pe_settings::forced, timeout, pe_settings::plaintext);
	test_transfer(pe_settings::forced, timeout, pe_settings::rc4);
	test_transfer(pe_settings::forced, timeout, pe_settings::both, false);
	test_transfer(pe_settings::forced, timeout, pe_settings::both, true);

	test_transfer(pe_settings::enabled, timeout, pe_settings::plaintext);
	test_transfer(pe_settings::enabled, timeout, pe_settings::rc4);
	test_transfer(pe_settings::enabled, timeout, pe_settings::both, false);
	test_transfer(pe_settings::enabled, timeout, pe_settings::both, true);
#else
	fprintf(stderr, "PE test not run because it's disabled\n");
#endif

	return 0;
}

<|endoftext|>


<commit_before>// Source : https://leetcode.com/problems/expression-add-operators/
// Author : Yijing Bai
// Date   : 2016-03-24

/**********************************************************************************
 *
 * Given a string that contains only digits 0-9 and a target value, return all
 * possibilities to add binary operators (not unary) +, -, or * between the digits so
 * they evaluate to the target value.
 *
 * Examples:
 * "123", 6 -> ["1+2+3", "1*2*3"]
 * "232", 8 -> ["2*3+2", "2+3*2"]
 * "105", 5 -> ["1*0+5","10-5"]
 * "00", 0 -> ["0+0", "0-0", "0*0"]
 * "3456237490", 9191 -> []
 *
 * Credits:Special thanks to @davidtan1890 for adding this problem and creating all
 * test cases.
 *
 *
 *
 *
 *
 *
 *
 **********************************************************************************/

<commit_msg>expression add operators<commit_after>// Source : https://leetcode.com/problems/expression-add-operators/
// Author : Yijing Bai
// Date   : 2016-03-24

/**********************************************************************************
 *
 * Given a string that contains only digits 0-9 and a target value, return all
 * possibilities to add binary operators (not unary) +, -, or * between the digits so
 * they evaluate to the target value.
 *
 * Examples:
 * "123", 6 -> ["1+2+3", "1*2*3"]
 * "232", 8 -> ["2*3+2", "2+3*2"]
 * "105", 5 -> ["1*0+5","10-5"]
 * "00", 0 -> ["0+0", "0-0", "0*0"]
 * "3456237490", 9191 -> []
 *
 * Credits:Special thanks to @davidtan1890 for adding this problem and creating all
 * test cases.
 *
 *
 *
 *
 *
 *
 *
 **********************************************************************************/

class Solution {
public:
    vector<string> addOperators(string num, int target) {
        vector<string> res;
        if (num.empty()) return res;
        for (int i=1; i<=num.size(); i++) {
            string s = num.substr(0, i);
            long cur = stol(s);
            if (to_string(cur).size() != s.size()) continue;
            dfs(res, num, target, s, i, cur, cur, '#');         // no operator defined.
        }

        return res;
    }
private:
    void dfs(vector<string>& res, const string& num,
             const int target, string cur, int pos, const long cv,
             const long pv, const char op) {
        if (pos == num.size() && cv == target) {
            res.push_back(cur);
        } else {
            for (int i = pos + 1; i <= num.size(); i++) {
                string t = num.substr(pos, i - pos);
                long now = stol(t);
                if (to_string(now).size() != t.size()) continue;
                dfs(res, num, target, cur+'+'+t, i, cv + now, now, '+');
                dfs(res, num, target, cur + '-' + t, i, cv - now, now, '-');
                dfs(res, num, target, cur+'*'+t, i, (op == '-') ? cv+pv - pv*now : ((op == '+') ? cv-pv + pv*now : pv*now), pv*now, op);
            }
        }
    }
};
<|endoftext|>


<commit_before>AliJetReader *CreateJetReader(Char_t *jr); // Common config
AliJetFinder *CreateJetFinder(Char_t *jf,Float_t radius = -1);

AliAnalysisTaskJets *AddTaskJets(Char_t *jr, Char_t *jf,Float_t radius = -1); // for the new AF

AliAnalysisTaskJets *AddTaskJets(){
  // fills the standard "jets" branch in the AOD
  // need the ESDFilter to run before, to access the AODtracks
  // Tracks selected by the first Filter (1<<0)
  // needs to be adapted for different cuts

  // UA1 as standard chosen, since it is the most robust and simple JF
  // R = 0.4 suffficient to provide accurate jet axis for correlation studies
  // energy resolution suffers a little
  // Acceptance of jets not limited by the Jet Finder but should be done
  // by user to abs(eta) < 0.5

  return AddTaskJets("AOD","UA1",0.4);

}

Int_t AddTaskJetsDelta(char *nonStdFile = ""){

  // Adds a whole set of jet finders  all to be written
  // to a delta AOD

  // this can in principle be done also with on the fly
  // if we have an ESD input jet fidner task does automatically fetch the ouput aod

   AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
   if (!mgr) {
      ::Error("AddTaskJetsDelta", "No analysis manager to connect to.");
      return 0;
   }

   // Check the analysis type using the event handlers connected to the analysis manager.
   //==============================================================================
   if (!mgr->GetInputEventHandler()) {
      ::Error("AddTaskJetsDelta", "This task requires an input event handler");
      return 0;
   }

  AliAODHandler *aodh = (AliAODHandler*)mgr->GetOutputEventHandler();
  if (!aodh) {
    ::Error("AddTaskJetsDelta", "This task needs an output event handler");
    return 0;
  }

  TString type = mgr->GetInputEventHandler()->GetDataType();

  AliAnalysisTaskJets *jetana = 0;
  Int_t iCount = 0;

  const char *cJF[7]        = {"UA1","UA1","UA1","CDF","DA","SISCONE","FASTJET"};
  const Float_t radius[7]   = {  0.4,  0.7,  1.0,  0.7, 0.7,      0.4,      0.4};
  const UInt_t  flag[7]     = {    6,    7,    7,    7,   7,        7,        7};
  // flag first bit AOD, second bit AODMC2 third bit AODMC2
  // i.e. 7 all, 6 only MC2 and MC
  // this stay at three
  const char *cReader[3] = {"AOD","AODMC","AODMC2"};

  for(int i = 0; i< 7;i++){
    for(int ib = 0;ib<3;ib++){
      if(flag[i]&(1<<ib)){
	jetana = AddTaskJets(cReader[ib],cJF[i],radius[i]);
	if(jetana){
	  char *cRadius = "";
	  if(radius[i]>0)cRadius = Form("%02d",(int)((radius[i]+0.01)*10.)); // add an offset beacuse of precision
	  Printf(cRadius);
	  jetana->SetNonStdBranch(Form("jets%s_%s%s",cReader[ib],cJF[i],cRadius));
	  iCount++;
	}
      }
    }
  }

  Printf("Added %d JetFinders",iCount);
}

AliAnalysisTaskJets *AddTaskJets(Char_t *jr, Char_t *jf, Float_t radius)
{
  // Creates a jet finder task, configures it and adds it to the analysis manager.

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

   // Check the analysis type using the event handlers connected to the analysis manager.
   //==============================================================================
   if (!mgr->GetInputEventHandler()) {
      ::Error("AddTaskJets", "This task requires an input event handler");
      return NULL;
   }

  AliAODHandler *aodh = (AliAODHandler*)mgr->GetOutputEventHandler();
  if (!aodh) {
    ::Error("AddTaskJets", "This task needs an output event handler");
    return NULL;
  }

   // Create the task and configure it.
   //===========================================================================
   AliAnalysisTaskJets *jetana;
   AliJetReader *er = CreateJetReader(jr);
    // Define jet header and jet finder
   AliJetFinder *jetFinder = CreateJetFinder(jf,radius);

   if (jetFinder){
       if (er) jetFinder->SetJetReader(er);
   }

   char *cRadius = "";
   if(radius>0)cRadius = Form("%02d",(int)((radius+0.01)*10.));

   jetana = new AliAnalysisTaskJets(Form("JetAnalysis%s_%s%s",jr,jf,cRadius));
   TString type = mgr->GetInputEventHandler()->GetDataType();
   if (type == "AOD") jetana->SetNonStdBranch(Form("jets%s",jf));

   TString c_jr(jr);
   c_jr.ToLower();
   TString c_jf(jf);
   c_jf.ToLower();

   AliAnalysisDataContainer *cout_jet = mgr->CreateContainer(Form("jethist_%s_%s%s",c_jr.Data(),c_jf.Data(),cRadius), TList::Class(),
							     AliAnalysisManager::kOutputContainer, Form("%s:PWG4_jethist_%s_%s%s",AliAnalysisManager::GetCommonFileName(),
													c_jr.Data(),c_jf.Data(),cRadius));
   // Connect jet finder to task.
   jetana->SetJetFinder(jetFinder);
   jetana->SetConfigFile("");
   jetana->SetDebugLevel(0);
   mgr->AddTask(jetana);

   // 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
   //==============================================================================
   mgr->ConnectInput  (jetana, 0, mgr->GetCommonInputContainer());
// AOD output slot will be used in a different way in future
   mgr->ConnectOutput (jetana, 0, mgr->GetCommonOutputContainer());
   mgr->ConnectOutput (jetana, 1, cout_jet);

   return jetana;
}

AliJetFinder *CreateJetFinder(Char_t *jf,Float_t radius){
  AliJetFinder *jetFinder = 0;

  switch (jf) {
  case "CDF":
    AliCdfJetHeader *jh = new AliCdfJetHeader();
    jh->SetRadius(0.7);
    if(radius>0)jh->SetRadius(radius);
    jetFinder = new AliCdfJetFinder();
    if (jh) jetFinder->SetJetHeader(jh);
    break;

  case "DA":
    AliDAJetHeader *jh=new AliDAJetHeader();
    jh->SetComment("DA jet code with default parameters");
    jh->SelectJets(kTRUE);
    jh->SetRadius(0.7);
    if(radius>0)jh->SetRadius(radius);
    jetFinder = new AliDAJetFinder();
    if (jh) jetFinder->SetJetHeader(jh);
    break;

  case "FASTJET":
    // DEFAULT is ANTI KT
    AliFastJetHeaderV1 *jh = new AliFastJetHeaderV1();
    jh->SetRparam(0.4); // setup parameters
    if(radius>0)jh->SetRparam(radius);
    jh->SetAlgorithm(2); // antikt from fastjet/JetDefinition.hh
    jetFinder = new AliFastJetFinder();
    if (jh) jetFinder->SetJetHeader(jh);
    break;

  case "FASTKT":
    AliFastJetHeaderV1 *jh = new AliFastJetHeaderV1();
    jh->SetRparam(0.4); // setup parameters
    if(radius>0)jh->SetRparam(radius);
    jh->SetAlgorithm(0); // kt from fastjet/JetDefinition.hh
    jetFinder = new AliFastJetFinder();
    if (jh) jetFinder->SetJetHeader(jh);
    break;

  case "SISCONE":
    AliSISConeJetHeader * jh = new AliSISConeJetHeader();

    jh->SetJetEtaMax(1.5);
    jh->SetJetEtaMin(-1.5);

    //siscone parameters
    jh->SetConeRadius(0.4);                   // default cone radius
    if(radius>0)jh->SetConeRadius(radius);   // cone radius

    jh->SetOverlapThreshold(0.75);            // overlap parameter, between 0 and 1 excluded!! 0.75 value is advised
    jh->SetPtProtojetMin(0);                  // pt min of protojets
    jh->SetMinJetPt(10);                      // Ptmin of jets (GeV)

    //do you want to subtract BG (0 = no, 1 = yes)
    jh->SetBGMode(0);

    //for background
    jh->SetRapRange( -0.9, 0.9);              // rapidity range for subtracting background must be < ghostmaxrap-0.95*R
    jh->SetPhiRange(0 , 2*TMath::Pi());       // phi range for subtracting background

    //to determine jets area
    jh->SetBGAlgorithm(1);                    // algorithm for rho calculation : 0 = kT, 1 = Cambridge
    jh->SetGhostEtaMax(4);                    // eta max where ghosts are generated
    jh->SetGhostArea(0.05);                   // area of a ghost
    jh->SetMeanGhostKt(1e-100);               // average transverse momentum of the ghosts.
    jh->SetAreaTypeNumber(4);                 // from 1 to 5 : 1 = active_area, 2 = active_area_explicit_ghosts, 3 = one_ghost_passive_area, 4 = passive_area, 5 = voronoi_area
    jetFinder = new AliSISConeJetFinder();
    if (jh) jetFinder->SetJetHeader(jh);
    break;

  case "UA1":
    AliUA1JetHeaderV1 *jh=new AliUA1JetHeaderV1();
    jh->SetComment("UA1 jet code with default parameters");
    jh->BackgMode(0);
    jh->SetRadius(0.4);
    if(radius>0)jh->SetRadius(radius);
    jh->SetEtSeed(4.);
    jh->SetEtSeed(4.);
    jh->SetNAcceptJets(6);
    jh->SetLegoNbinPhi(432);
    jh->SetLegoNbinEta(274);
    jh->SetLegoEtaMin(-2);
    jh->SetLegoEtaMax(+2);
    jh->SetMinJetEt(5.);
    jh->SetJetEtaMax(1.5);
    jh->SetJetEtaMin(-1.5);

    jetFinder = new AliUA1JetFinderV1();
    if (jh) jetFinder->SetJetHeader(jh);
    break;

  case "UA1MC":
    AliUA1JetHeaderV1 *jh=new AliUA1JetHeaderV1();
    jh->SetComment("UA1 jet code with default MC parameters");
    jh->BackgMode(0);
    jh->SetRadius(1.0);
    if(radius>0)jh->SetRadius(radius);
    jh->SetEtSeed(4.);
    jh->SetNAcceptJets(6);
    jh->SetLegoNbinPhi(432);
    jh->SetLegoNbinEta(274);
    jh->SetLegoEtaMin(-2);
    jh->SetLegoEtaMax(+2);
    jh->SetMinJetEt(5.);
    jh->SetJetEtaMax(1.5);
    jh->SetJetEtaMin(-1.5);
    jetFinder = new AliUA1JetFinderV1();
    if (jh) jetFinder->SetJetHeader(jh);
    break;
  default:
    Printf("\n >>>>>>> AddTaskJets Error Wrong jet finder selected\n");
    break;
  }

  return jetFinder;

}

AliJetReader *CreateJetReader(Char_t *jr){
  AliJetReader *er = 0;

  switch (jr) {
  case "MC":
    AliJetKineReaderHeader *jrh = new AliJetKineReaderHeader();
    jrh->SetComment("MC full Kinematics");
    jrh->SetFastSimTPC(kFALSE);
    jrh->SetFastSimEMCAL(kFALSE);
    jrh->SetPtCut(0.);
    jrh->SetFiducialEta(-2.1,2.1); // to take all MC particles default is 0 .9
    // Define reader and set its header
    er = new AliJetKineReader();
    er->SetReaderHeader(jrh);
    break;
  case "MC2":
    AliJetKineReaderHeader *jrh = new AliJetKineReaderHeader();
    jrh->SetComment("MC full Kinematics spearate config charged only");
    jrh->SetFastSimTPC(kFALSE);
    jrh->SetFastSimEMCAL(kFALSE);
    jrh->SetChargedOnly(kTRUE);
    jrh->SetPtCut(0.);
    jrh->SetFiducialEta(-2.1,2.1); // to take all MC particles default is 0 .9
    // Define reader and set its header
    er = new AliJetKineReader();
    er->SetReaderHeader(jrh);
    break;
  case "ESD":
    AliJetESDReaderHeader *jrh = new AliJetESDReaderHeader();
    jrh->SetComment("Testing");
    jrh->SetFirstEvent(0);
    jrh->SetLastEvent(1000);
    jrh->SetPtCut(0.);
    jrh->SetReadSignalOnly(kFALSE);
    // Define reader and set its header
    er = new AliJetESDReader();
    er->SetReaderHeader(jrh);
    break;

  case "AOD":
    AliJetAODReaderHeader *jrh = new AliJetAODReaderHeader();
    jrh->SetComment("AOD Reader");
    jrh->SetPtCut(0.);
    jrh->SetTestFilterMask(16); // Change this one for a different set of cuts
    // Define reader and set its header
    er = new AliJetAODReader();
    er->SetReaderHeader(jrh);
    break;
  case "AODMC":
    AliJetAODReaderHeader *jrh = new AliJetAODReaderHeader();
    jrh->SetComment("AOD MC Reader");
    jrh->SetPtCut(0.);
    jrh->SetFiducialEta(-2.1,2.1); // to take all MC particles default is 0.9
    jrh->SetReadAODMC(1);// 1 all primary MC , 2 all primary charged
    // Define reader and set its header
    er = new AliJetAODReader();
    er->SetReaderHeader(jrh);
    break;
  case "AODMC2":
    AliJetAODReaderHeader *jrh = new AliJetAODReaderHeader();
    jrh->SetComment("AOD MC Reader");
    jrh->SetPtCut(0.);
    jrh->SetFiducialEta(-2.1,2.1); // to take all MC particles default is 0.9
    jrh->SetReadAODMC(2);// 1 all primary MC , 2 all primary charged
    // Define reader and set its header
    er = new AliJetAODReader();
    er->SetReaderHeader(jrh);
    break;

  default:
    ::Error("AddTaskJets", "Wrong jet reader selected\n");
    return 0;
  }

  return er;

}
<commit_msg>setting the name for non-std file<commit_after>AliJetReader *CreateJetReader(Char_t *jr); // Common config
AliJetFinder *CreateJetFinder(Char_t *jf,Float_t radius = -1);

AliAnalysisTaskJets *AddTaskJets(Char_t *jr, Char_t *jf,Float_t radius = -1); // for the new AF

AliAnalysisTaskJets *AddTaskJets(){
  // fills the standard "jets" branch in the AOD
  // need the ESDFilter to run before, to access the AODtracks
  // Tracks selected by the first Filter (1<<0)
  // needs to be adapted for different cuts

  // UA1 as standard chosen, since it is the most robust and simple JF
  // R = 0.4 suffficient to provide accurate jet axis for correlation studies
  // energy resolution suffers a little
  // Acceptance of jets not limited by the Jet Finder but should be done
  // by user to abs(eta) < 0.5

  return AddTaskJets("AOD","UA1",0.4);

}

Int_t AddTaskJetsDelta(char *nonStdFile = ""){

  // Adds a whole set of jet finders  all to be written
  // to a delta AOD

  // this can in principle be done also with on the fly
  // if we have an ESD input jet fidner task does automatically fetch the ouput aod

   AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
   if (!mgr) {
      ::Error("AddTaskJetsDelta", "No analysis manager to connect to.");
      return 0;
   }

   // Check the analysis type using the event handlers connected to the analysis manager.
   //==============================================================================
   if (!mgr->GetInputEventHandler()) {
      ::Error("AddTaskJetsDelta", "This task requires an input event handler");
      return 0;
   }

  AliAODHandler *aodh = (AliAODHandler*)mgr->GetOutputEventHandler();
  if (!aodh) {
    ::Error("AddTaskJetsDelta", "This task needs an output event handler");
    return 0;
  }

  TString outFile(nonStdFile);

  TString type = mgr->GetInputEventHandler()->GetDataType();

  AliAnalysisTaskJets *jetana = 0;
  Int_t iCount = 0;

  const char *cJF[7]        = {"UA1","UA1","UA1","CDF","DA","SISCONE","FASTJET"};
  const Float_t radius[7]   = {  0.4,  0.7,  1.0,  0.7, 0.7,      0.4,      0.4};
  const UInt_t  flag[7]     = {    6,    7,    7,    7,   7,        7,        7};
  // flag first bit AOD, second bit AODMC2 third bit AODMC2
  // i.e. 7 all, 6 only MC2 and MC
  // this stay at three
  const char *cReader[3] = {"AOD","AODMC","AODMC2"};

  for(int i = 0; i< 7;i++){
    for(int ib = 0;ib<3;ib++){
      if(flag[i]&(1<<ib)){
	jetana = AddTaskJets(cReader[ib],cJF[i],radius[i]);
	if(jetana){
	  char *cRadius = "";
	  if(radius[i]>0)cRadius = Form("%02d",(int)((radius[i]+0.01)*10.)); // add an offset beacuse of precision
	  Printf(cRadius);
	  jetana->SetNonStdBranch(Form("jets%s_%s%s",cReader[ib],cJF[i],cRadius));
	  if(outFile.Length()>0)jetana->SetNonStdOutputFile(outFile.Data());
	  iCount++;
	}
      }
    }
  }

  Printf("Added %d JetFinders",iCount);
}

AliAnalysisTaskJets *AddTaskJets(Char_t *jr, Char_t *jf, Float_t radius)
{
  // Creates a jet finder task, configures it and adds it to the analysis manager.

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

   // Check the analysis type using the event handlers connected to the analysis manager.
   //==============================================================================
   if (!mgr->GetInputEventHandler()) {
      ::Error("AddTaskJets", "This task requires an input event handler");
      return NULL;
   }

  AliAODHandler *aodh = (AliAODHandler*)mgr->GetOutputEventHandler();
  if (!aodh) {
    ::Error("AddTaskJets", "This task needs an output event handler");
    return NULL;
  }

   // Create the task and configure it.
   //===========================================================================
   AliAnalysisTaskJets *jetana;
   AliJetReader *er = CreateJetReader(jr);
    // Define jet header and jet finder
   AliJetFinder *jetFinder = CreateJetFinder(jf,radius);

   if (jetFinder){
       if (er) jetFinder->SetJetReader(er);
   }

   char *cRadius = "";
   if(radius>0)cRadius = Form("%02d",(int)((radius+0.01)*10.));

   jetana = new AliAnalysisTaskJets(Form("JetAnalysis%s_%s%s",jr,jf,cRadius));
   TString type = mgr->GetInputEventHandler()->GetDataType();
   if (type == "AOD") jetana->SetNonStdBranch(Form("jets%s",jf));

   TString c_jr(jr);
   c_jr.ToLower();
   TString c_jf(jf);
   c_jf.ToLower();

   AliAnalysisDataContainer *cout_jet = mgr->CreateContainer(Form("jethist_%s_%s%s",c_jr.Data(),c_jf.Data(),cRadius), TList::Class(),
							     AliAnalysisManager::kOutputContainer, Form("%s:PWG4_jethist_%s_%s%s",AliAnalysisManager::GetCommonFileName(),
													c_jr.Data(),c_jf.Data(),cRadius));
   // Connect jet finder to task.
   jetana->SetJetFinder(jetFinder);
   jetana->SetConfigFile("");
   jetana->SetDebugLevel(0);
   mgr->AddTask(jetana);

   // 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
   //==============================================================================
   mgr->ConnectInput  (jetana, 0, mgr->GetCommonInputContainer());
// AOD output slot will be used in a different way in future
   mgr->ConnectOutput (jetana, 0, mgr->GetCommonOutputContainer());
   mgr->ConnectOutput (jetana, 1, cout_jet);

   return jetana;
}

AliJetFinder *CreateJetFinder(Char_t *jf,Float_t radius){
  AliJetFinder *jetFinder = 0;

  switch (jf) {
  case "CDF":
    AliCdfJetHeader *jh = new AliCdfJetHeader();
    jh->SetRadius(0.7);
    if(radius>0)jh->SetRadius(radius);
    jetFinder = new AliCdfJetFinder();
    if (jh) jetFinder->SetJetHeader(jh);
    break;

  case "DA":
    AliDAJetHeader *jh=new AliDAJetHeader();
    jh->SetComment("DA jet code with default parameters");
    jh->SelectJets(kTRUE);
    jh->SetRadius(0.7);
    if(radius>0)jh->SetRadius(radius);
    jetFinder = new AliDAJetFinder();
    if (jh) jetFinder->SetJetHeader(jh);
    break;

  case "FASTJET":
    // DEFAULT is ANTI KT
    AliFastJetHeaderV1 *jh = new AliFastJetHeaderV1();
    jh->SetRparam(0.4); // setup parameters
    if(radius>0)jh->SetRparam(radius);
    jh->SetAlgorithm(2); // antikt from fastjet/JetDefinition.hh
    jetFinder = new AliFastJetFinder();
    if (jh) jetFinder->SetJetHeader(jh);
    break;

  case "FASTKT":
    AliFastJetHeaderV1 *jh = new AliFastJetHeaderV1();
    jh->SetRparam(0.4); // setup parameters
    if(radius>0)jh->SetRparam(radius);
    jh->SetAlgorithm(0); // kt from fastjet/JetDefinition.hh
    jetFinder = new AliFastJetFinder();
    if (jh) jetFinder->SetJetHeader(jh);
    break;

  case "SISCONE":
    AliSISConeJetHeader * jh = new AliSISConeJetHeader();

    jh->SetJetEtaMax(1.5);
    jh->SetJetEtaMin(-1.5);

    //siscone parameters
    jh->SetConeRadius(0.4);                   // default cone radius
    if(radius>0)jh->SetConeRadius(radius);   // cone radius

    jh->SetOverlapThreshold(0.75);            // overlap parameter, between 0 and 1 excluded!! 0.75 value is advised
    jh->SetPtProtojetMin(0);                  // pt min of protojets
    jh->SetMinJetPt(10);                      // Ptmin of jets (GeV)

    //do you want to subtract BG (0 = no, 1 = yes)
    jh->SetBGMode(0);

    //for background
    jh->SetRapRange( -0.9, 0.9);              // rapidity range for subtracting background must be < ghostmaxrap-0.95*R
    jh->SetPhiRange(0 , 2*TMath::Pi());       // phi range for subtracting background

    //to determine jets area
    jh->SetBGAlgorithm(1);                    // algorithm for rho calculation : 0 = kT, 1 = Cambridge
    jh->SetGhostEtaMax(4);                    // eta max where ghosts are generated
    jh->SetGhostArea(0.05);                   // area of a ghost
    jh->SetMeanGhostKt(1e-100);               // average transverse momentum of the ghosts.
    jh->SetAreaTypeNumber(4);                 // from 1 to 5 : 1 = active_area, 2 = active_area_explicit_ghosts, 3 = one_ghost_passive_area, 4 = passive_area, 5 = voronoi_area
    jetFinder = new AliSISConeJetFinder();
    if (jh) jetFinder->SetJetHeader(jh);
    break;

  case "UA1":
    AliUA1JetHeaderV1 *jh=new AliUA1JetHeaderV1();
    jh->SetComment("UA1 jet code with default parameters");
    jh->BackgMode(0);
    jh->SetRadius(0.4);
    if(radius>0)jh->SetRadius(radius);
    jh->SetEtSeed(4.);
    jh->SetEtSeed(4.);
    jh->SetNAcceptJets(6);
    jh->SetLegoNbinPhi(432);
    jh->SetLegoNbinEta(274);
    jh->SetLegoEtaMin(-2);
    jh->SetLegoEtaMax(+2);
    jh->SetMinJetEt(5.);
    jh->SetJetEtaMax(1.5);
    jh->SetJetEtaMin(-1.5);

    jetFinder = new AliUA1JetFinderV1();
    if (jh) jetFinder->SetJetHeader(jh);
    break;

  case "UA1MC":
    AliUA1JetHeaderV1 *jh=new AliUA1JetHeaderV1();
    jh->SetComment("UA1 jet code with default MC parameters");
    jh->BackgMode(0);
    jh->SetRadius(1.0);
    if(radius>0)jh->SetRadius(radius);
    jh->SetEtSeed(4.);
    jh->SetNAcceptJets(6);
    jh->SetLegoNbinPhi(432);
    jh->SetLegoNbinEta(274);
    jh->SetLegoEtaMin(-2);
    jh->SetLegoEtaMax(+2);
    jh->SetMinJetEt(5.);
    jh->SetJetEtaMax(1.5);
    jh->SetJetEtaMin(-1.5);
    jetFinder = new AliUA1JetFinderV1();
    if (jh) jetFinder->SetJetHeader(jh);
    break;
  default:
    Printf("\n >>>>>>> AddTaskJets Error Wrong jet finder selected\n");
    break;
  }

  return jetFinder;

}

AliJetReader *CreateJetReader(Char_t *jr){
  AliJetReader *er = 0;

  switch (jr) {
  case "MC":
    AliJetKineReaderHeader *jrh = new AliJetKineReaderHeader();
    jrh->SetComment("MC full Kinematics");
    jrh->SetFastSimTPC(kFALSE);
    jrh->SetFastSimEMCAL(kFALSE);
    jrh->SetPtCut(0.);
    jrh->SetFiducialEta(-2.1,2.1); // to take all MC particles default is 0 .9
    // Define reader and set its header
    er = new AliJetKineReader();
    er->SetReaderHeader(jrh);
    break;
  case "MC2":
    AliJetKineReaderHeader *jrh = new AliJetKineReaderHeader();
    jrh->SetComment("MC full Kinematics spearate config charged only");
    jrh->SetFastSimTPC(kFALSE);
    jrh->SetFastSimEMCAL(kFALSE);
    jrh->SetChargedOnly(kTRUE);
    jrh->SetPtCut(0.);
    jrh->SetFiducialEta(-2.1,2.1); // to take all MC particles default is 0 .9
    // Define reader and set its header
    er = new AliJetKineReader();
    er->SetReaderHeader(jrh);
    break;
  case "ESD":
    AliJetESDReaderHeader *jrh = new AliJetESDReaderHeader();
    jrh->SetComment("Testing");
    jrh->SetFirstEvent(0);
    jrh->SetLastEvent(1000);
    jrh->SetPtCut(0.);
    jrh->SetReadSignalOnly(kFALSE);
    // Define reader and set its header
    er = new AliJetESDReader();
    er->SetReaderHeader(jrh);
    break;

  case "AOD":
    AliJetAODReaderHeader *jrh = new AliJetAODReaderHeader();
    jrh->SetComment("AOD Reader");
    jrh->SetPtCut(0.);
    jrh->SetTestFilterMask(16); // Change this one for a different set of cuts
    // Define reader and set its header
    er = new AliJetAODReader();
    er->SetReaderHeader(jrh);
    break;
  case "AODMC":
    AliJetAODReaderHeader *jrh = new AliJetAODReaderHeader();
    jrh->SetComment("AOD MC Reader");
    jrh->SetPtCut(0.);
    jrh->SetFiducialEta(-2.1,2.1); // to take all MC particles default is 0.9
    jrh->SetReadAODMC(1);// 1 all primary MC , 2 all primary charged
    // Define reader and set its header
    er = new AliJetAODReader();
    er->SetReaderHeader(jrh);
    break;
  case "AODMC2":
    AliJetAODReaderHeader *jrh = new AliJetAODReaderHeader();
    jrh->SetComment("AOD MC Reader");
    jrh->SetPtCut(0.);
    jrh->SetFiducialEta(-2.1,2.1); // to take all MC particles default is 0.9
    jrh->SetReadAODMC(2);// 1 all primary MC , 2 all primary charged
    // Define reader and set its header
    er = new AliJetAODReader();
    er->SetReaderHeader(jrh);
    break;

  default:
    ::Error("AddTaskJets", "Wrong jet reader selected\n");
    return 0;
  }

  return er;

}
<|endoftext|>


<commit_before>//
// Content3d.cpp
//
// 3D Content Management class.
//
// Copyright (c) 2003-2006 Virtual Terrain Project.
// Free for all uses, see license.txt for details.
//

#include "vtlib/vtlib.h"
#include "vtdata/FilePath.h"
#include "vtdata/vtLog.h"
#include "Content3d.h"

vtItem3d::vtItem3d()
{
	m_pNode = NULL;
}

vtItem3d::~vtItem3d()
{
	// Don't need to explicitly release the item's node here, because all nodes
	//  are released when the the manager's group is released.
	m_pNode = NULL;
}

/**
 * Load the model(s) associated with an item.  If there are several models,
 * generally these are different levels of detail (LOD) for the item.
 */
bool vtItem3d::LoadModels()
{
	VTLOG(" Loading models for item.\n");

	if (m_pNode)
		return true;	// already loaded

	int i, models = NumModels();

	// attempt to instantiate the item
	vtLOD *pLod=NULL;

	if (models > 1)
	{
		pLod = new vtLOD;
		m_pNode = pLod;
	}
	float ranges[20];
	ranges[0] = 0.0f;

	for (i = 0; i < models; i++)
	{
		vtModel *model = GetModel(i);
		vtNode *pNode = NULL;

		// perhaps it's directly resolvable
		pNode = vtNode::LoadModel(model->m_filename);

		// if there are some data path(s) to search, use them
		if (!pNode)
		{
			vtString fullpath = FindFileOnPaths(vtGetDataPath(), model->m_filename);
			if (fullpath != "")
				pNode = vtNode::LoadModel(fullpath);
		}

		if (pNode)
			VTLOG(" Loaded successfully.\n");
		else
		{
			VTLOG(" Couldn't load model from %hs\n",
				(const char *) model->m_filename);
			return false;
		}

		if (model->m_scale != 1.0f)
		{
			// Wrap in a transform node so that we can scale/rotate the node
			vtTransform *pTrans = new vtTransform();
			pTrans->SetName2("scaling xform");
			pTrans->AddChild(pNode);
			pTrans->Identity();
			pTrans->Scale3(model->m_scale, model->m_scale, model->m_scale);
			pNode = pTrans;
		}

		if (models > 1)
			pLod->AddChild(pNode);
		else
			m_pNode = pNode;

		if (models > 1)
			ranges[i+1] = model->m_distance;
	}
	if (models > 1)
		pLod->SetRanges(ranges, models+1);

	return true;
}

//
// An item can store some extents, which give a rough indication of
//  the 2D area taken up by the model, useful for drawing it in traditional
//  2D GIS environments like VTBuilder.
//
//  Whenever a model is added, or the scale factor changes, the extents
//   should be updated.
//
void vtItem3d::UpdateExtents()
{
	m_extents.Empty();

	if (m_pNode == NULL)
		return;

	// A good way to do it would be to try to get a tight bounding box,
	//  but that's non-trivial to compute with OSG.  For now, settle for
	//  making a rectangle from the loose bounding sphere.

	// Both the 3D model and the extents are in approximate meters and
	//  centered on the item's local origin.
	FSphere sph;
	m_pNode->GetBoundSphere(sph);
	m_extents.left = sph.center.x - sph.radius;
	m_extents.right = sph.center.x + sph.radius;

	// However, the XY extents of the extents have Y pointing up, whereas
	//  the world coords have Z pointing down.
	m_extents.top = -sph.center.z + sph.radius;
	m_extents.bottom = -sph.center.z - sph.radius;
}

///////////////////////////////////////////////////////////////////////

vtContentManager3d::vtContentManager3d()
{
	m_pGroup = NULL;
}

void vtContentManager3d::ReleaseContents()
{
	if (m_pGroup)
		m_pGroup->Release();
	m_pGroup = NULL;
}

vtContentManager3d::~vtContentManager3d()
{
	ReleaseContents();
}

vtNode *vtContentManager3d::CreateNodeFromItemname(const char *itemname)
{
	vtItem3d *pItem = (vtItem3d *) FindItemByName(itemname);
	if (!pItem)
		return NULL;

	if (!pItem->m_pNode)
	{
		if (!pItem->LoadModels())
			return NULL;

		if (!m_pGroup)
		{
			m_pGroup = new vtGroup();
			m_pGroup->SetName2("Content Manager Container Group");
		}

		// Add to content container: must keep a reference to each item's
		//  model node so it doesn't get deleted while the manager is alive.
		m_pGroup->AddChild(pItem->m_pNode);
	}
	return pItem->m_pNode;
}

<commit_msg>tweak<commit_after>//
// Content3d.cpp
//
// 3D Content Management class.
//
// Copyright (c) 2003-2007 Virtual Terrain Project.
// Free for all uses, see license.txt for details.
//

#include "vtlib/vtlib.h"
#include "vtdata/FilePath.h"
#include "vtdata/vtLog.h"
#include "Content3d.h"

vtItem3d::vtItem3d()
{
	m_pNode = NULL;
}

vtItem3d::~vtItem3d()
{
	// Don't need to explicitly release the item's node here, because all nodes
	//  are released when the the manager's group is released.
	m_pNode = NULL;
}

/**
 * Load the model(s) associated with an item.  If there are several models,
 * generally these are different levels of detail (LOD) for the item.
 */
bool vtItem3d::LoadModels()
{
	VTLOG(" Loading models for item.\n");

	if (m_pNode)
		return true;	// already loaded

	int i, models = NumModels();

	// attempt to instantiate the item
	vtLOD *pLod=NULL;

	if (models > 1)
	{
		pLod = new vtLOD;
		m_pNode = pLod;
	}
	float ranges[20];
	ranges[0] = 0.0f;

	for (i = 0; i < models; i++)
	{
		vtModel *model = GetModel(i);
		vtNode *pNode = NULL;

		// perhaps it's directly resolvable
		pNode = vtNode::LoadModel(model->m_filename);

		// if there are some data path(s) to search, use them
		if (!pNode)
		{
			vtString fullpath = FindFileOnPaths(vtGetDataPath(), model->m_filename);
			if (fullpath != "")
				pNode = vtNode::LoadModel(fullpath);
		}

		if (pNode)
			VTLOG(" Loaded successfully.\n");
		else
		{
			VTLOG(" Couldn't load model from %hs\n",
				(const char *) model->m_filename);
			return false;
		}

		if (model->m_scale != 1.0f)
		{
			// Wrap in a transform node so that we can scale/rotate the node
			vtTransform *pTrans = new vtTransform;
			pTrans->SetName2("scaling xform");
			pTrans->AddChild(pNode);
			pTrans->Identity();
			pTrans->Scale3(model->m_scale, model->m_scale, model->m_scale);
			pNode = pTrans;
		}

		if (models > 1)
			pLod->AddChild(pNode);
		else
			m_pNode = pNode;

		if (models > 1)
			ranges[i+1] = model->m_distance;
	}
	if (models > 1)
		pLod->SetRanges(ranges, models+1);

	return true;
}

//
// An item can store some extents, which give a rough indication of
//  the 2D area taken up by the model, useful for drawing it in traditional
//  2D GIS environments like VTBuilder.
//
//  Whenever a model is added, or the scale factor changes, the extents
//   should be updated.
//
void vtItem3d::UpdateExtents()
{
	m_extents.Empty();

	if (m_pNode == NULL)
		return;

	// A good way to do it would be to try to get a tight bounding box,
	//  but that's non-trivial to compute with OSG.  For now, settle for
	//  making a rectangle from the loose bounding sphere.

	// Both the 3D model and the extents are in approximate meters and
	//  centered on the item's local origin.
	FSphere sph;
	m_pNode->GetBoundSphere(sph);
	m_extents.left = sph.center.x - sph.radius;
	m_extents.right = sph.center.x + sph.radius;

	// However, the XY extents of the extents have Y pointing up, whereas
	//  the world coords have Z pointing down.
	m_extents.top = -sph.center.z + sph.radius;
	m_extents.bottom = -sph.center.z - sph.radius;
}

///////////////////////////////////////////////////////////////////////

vtContentManager3d::vtContentManager3d()
{
	m_pGroup = NULL;
}

void vtContentManager3d::ReleaseContents()
{
	if (m_pGroup)
		m_pGroup->Release();
	m_pGroup = NULL;
}

vtContentManager3d::~vtContentManager3d()
{
	ReleaseContents();
}

vtNode *vtContentManager3d::CreateNodeFromItemname(const char *itemname)
{
	vtItem3d *pItem = (vtItem3d *) FindItemByName(itemname);
	if (!pItem)
		return NULL;

	if (!pItem->m_pNode)
	{
		if (!pItem->LoadModels())
			return NULL;

		if (!m_pGroup)
		{
			m_pGroup = new vtGroup;
			m_pGroup->SetName2("Content Manager Container Group");
		}

		// Add to content container: must keep a reference to each item's
		//  model node so it doesn't get deleted while the manager is alive.
		m_pGroup->AddChild(pItem->m_pNode);
	}
	return pItem->m_pNode;
}

<|endoftext|>


<commit_before>/*=====================================================================

 QGroundControl Open Source Ground Control Station

 (c) 2009 - 2011 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>

 This file is part of the QGROUNDCONTROL project

 QGROUNDCONTROL is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.

 QGROUNDCONTROL 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 General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.

 ======================================================================*/

#include <QTimer>
#include <QList>
#include <QDebug>
#include <QMutexLocker>
#include <iostream>
#include "TCPLink.h"
#include "LinkManager.h"
#include "QGC.h"
#include <QHostInfo>
#include <QSignalSpy>

/// @file
///     @brief TCP link type for SITL support
///
///     @author Don Gagne <don@thegagnes.com>

TCPLink::TCPLink(QHostAddress hostAddress, quint16 socketPort) :
    _hostAddress(hostAddress),
    _port(socketPort),
    _socket(NULL),
    _socketIsConnected(false)
{
    // We're doing it wrong - because the Qt folks got the API wrong:
    // http://blog.qt.digia.com/blog/2010/06/17/youre-doing-it-wrong/
    moveToThread(this);

    _linkId = getNextLinkId();
    _resetName();

    qDebug() << "TCP Created " << _name;
}

TCPLink::~TCPLink()
{
    disconnect();

    // Tell the thread to exit
    quit();
    // Wait for it to exit
    wait();

	deleteLater();
}

void TCPLink::run()
{
    _hardwareConnect();

	exec();
}

void TCPLink::setHostAddress(QHostAddress hostAddress)
{
    bool reconnect = false;

	if (this->isConnected()) {
		disconnect();
		reconnect = true;
	}

	_hostAddress = hostAddress;
    _resetName();

	if (reconnect) {
		connect();
	}
}

void TCPLink::setHostAddress(const QString& hostAddress)
{
    setHostAddress(QHostAddress(hostAddress));
}

void TCPLink::setPort(int port)
{
    bool reconnect = false;

	if (this->isConnected()) {
		disconnect();
		reconnect = true;
	}

	_port = port;
    _resetName();

	if (reconnect) {
		connect();
	}
}

#ifdef TCPLINK_READWRITE_DEBUG
void TCPLink::_writeDebugBytes(const char *data, qint16 size)
{
    QString bytes;
    QString ascii;
    for (int i=0; i<size; i++)
    {
        unsigned char v = data[i];
        bytes.append(QString().sprintf("%02x ", v));
        if (data[i] > 31 && data[i] < 127)
        {
            ascii.append(data[i]);
        }
        else
        {
            ascii.append(219);
        }
    }
    qDebug() << "Sent" << size << "bytes to" << _hostAddress.toString() << ":" << _port << "data:";
    qDebug() << bytes;
    qDebug() << "ASCII:" << ascii;
}
#endif

void TCPLink::writeBytes(const char* data, qint64 size)
{
#ifdef TCPLINK_READWRITE_DEBUG
    _writeDebugBytes(data, size);
#endif
    _socket->write(data, size);

    // Log the amount and time written out for future data rate calculations.
    QMutexLocker dataRateLocker(&dataRateMutex);
    logDataRateToBuffer(outDataWriteAmounts, outDataWriteTimes, &outDataIndex, size, QDateTime::currentMSecsSinceEpoch());
}

/**
 * @brief Read a number of bytes from the interface.
 *
 * @param data Pointer to the data byte array to write the bytes to
 * @param maxLength The maximum number of bytes to write
 **/
void TCPLink::readBytes()
{
    qint64 byteCount = _socket->bytesAvailable();

    if (byteCount)
    {
        QByteArray buffer;
        buffer.resize(byteCount);

        _socket->read(buffer.data(), buffer.size());

        emit bytesReceived(this, buffer);

        // Log the amount and time received for future data rate calculations.
        QMutexLocker dataRateLocker(&dataRateMutex);
        logDataRateToBuffer(inDataWriteAmounts, inDataWriteTimes, &inDataIndex, byteCount, QDateTime::currentMSecsSinceEpoch());

#ifdef TCPLINK_READWRITE_DEBUG
        writeDebugBytes(buffer.data(), buffer.size());
#endif
    }
}

/**
 * @brief Get the number of bytes to read.
 *
 * @return The number of bytes to read
 **/
qint64 TCPLink::bytesAvailable()
{
    return _socket->bytesAvailable();
}

/**
 * @brief Disconnect the connection.
 *
 * @return True if connection has been disconnected, false if connection couldn't be disconnected.
 **/
bool TCPLink::disconnect()
{
	quit();
	wait();

    if (_socket)
	{
        _socketIsConnected = false;
		delete _socket;
		_socket = NULL;

        emit disconnected();
        emit connected(false);
	}

    return true;
}

/**
 * @brief Connect the connection.
 *
 * @return True if connection has been established, false if connection couldn't be established.
 **/
bool TCPLink::connect()
{
	if (isRunning())
	{
		quit();
		wait();
	}

    start(HighPriority);

    return true;
}

bool TCPLink::_hardwareConnect(void)
{
    Q_ASSERT(_socket == NULL);
	_socket = new QTcpSocket();

    QSignalSpy errorSpy(_socket, SIGNAL(error(QAbstractSocket::SocketError)));

    _socket->connectToHost(_hostAddress, _port);

    QObject::connect(_socket, SIGNAL(readyRead()), this, SLOT(readBytes()));
    QObject::connect(_socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(_socketError(QAbstractSocket::SocketError)));

    // Give the socket a second to connect to the other side otherwise error out
    if (!_socket->waitForConnected(1000))
    {
        // Whether a failed connection emits an error signal or not is platform specific.
        // So in cases where it is not emitted, we emit one ourselves.
        if (errorSpy.count() == 0) {
            emit communicationError(getName(), "Connection failed");
        }
        delete _socket;
        _socket = NULL;
        return false;
    }

    _socketIsConnected = true;
    emit connected(true);
    emit connected();

    return true;
}

void TCPLink::_socketError(QAbstractSocket::SocketError socketError)
{
    Q_UNUSED(socketError);
    emit communicationError(getName(), "Error on socket: " + _socket->errorString());
}

/**
 * @brief Check if connection is active.
 *
 * @return True if link is connected, false otherwise.
 **/
bool TCPLink::isConnected() const
{
    return _socketIsConnected;
}

int TCPLink::getId() const
{
    return _linkId;
}

QString TCPLink::getName() const
{
    return _name;
}

qint64 TCPLink::getConnectionSpeed() const
{
    return 54000000; // 54 Mbit
}

qint64 TCPLink::getCurrentInDataRate() const
{
    return 0;
}

qint64 TCPLink::getCurrentOutDataRate() const
{
    return 0;
}

void TCPLink::_resetName(void)
{
    _name = QString("TCP Link (host:%1 port:%2)").arg(_hostAddress.toString()).arg(_port);
    emit nameChanged(_name);
}

void TCPLink::waitForBytesWritten(int msecs)
{
    Q_ASSERT(_socket);
    _socket->waitForBytesWritten(msecs);
}

void TCPLink::waitForReadyRead(int msecs)
{
    Q_ASSERT(_socket);
    _socket->waitForReadyRead(msecs);
}
<commit_msg>deleteLater on _socket<commit_after>/*=====================================================================

 QGroundControl Open Source Ground Control Station

 (c) 2009 - 2011 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>

 This file is part of the QGROUNDCONTROL project

 QGROUNDCONTROL is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.

 QGROUNDCONTROL 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 General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.

 ======================================================================*/

#include <QTimer>
#include <QList>
#include <QDebug>
#include <QMutexLocker>
#include <iostream>
#include "TCPLink.h"
#include "LinkManager.h"
#include "QGC.h"
#include <QHostInfo>
#include <QSignalSpy>

/// @file
///     @brief TCP link type for SITL support
///
///     @author Don Gagne <don@thegagnes.com>

TCPLink::TCPLink(QHostAddress hostAddress, quint16 socketPort) :
    _hostAddress(hostAddress),
    _port(socketPort),
    _socket(NULL),
    _socketIsConnected(false)
{
    // We're doing it wrong - because the Qt folks got the API wrong:
    // http://blog.qt.digia.com/blog/2010/06/17/youre-doing-it-wrong/
    moveToThread(this);

    _linkId = getNextLinkId();
    _resetName();

    qDebug() << "TCP Created " << _name;
}

TCPLink::~TCPLink()
{
    disconnect();

    // Tell the thread to exit
    quit();
    // Wait for it to exit
    wait();

	deleteLater();
}

void TCPLink::run()
{
    _hardwareConnect();

	exec();
}

void TCPLink::setHostAddress(QHostAddress hostAddress)
{
    bool reconnect = false;

	if (this->isConnected()) {
		disconnect();
		reconnect = true;
	}

	_hostAddress = hostAddress;
    _resetName();

	if (reconnect) {
		connect();
	}
}

void TCPLink::setHostAddress(const QString& hostAddress)
{
    setHostAddress(QHostAddress(hostAddress));
}

void TCPLink::setPort(int port)
{
    bool reconnect = false;

	if (this->isConnected()) {
		disconnect();
		reconnect = true;
	}

	_port = port;
    _resetName();

	if (reconnect) {
		connect();
	}
}

#ifdef TCPLINK_READWRITE_DEBUG
void TCPLink::_writeDebugBytes(const char *data, qint16 size)
{
    QString bytes;
    QString ascii;
    for (int i=0; i<size; i++)
    {
        unsigned char v = data[i];
        bytes.append(QString().sprintf("%02x ", v));
        if (data[i] > 31 && data[i] < 127)
        {
            ascii.append(data[i]);
        }
        else
        {
            ascii.append(219);
        }
    }
    qDebug() << "Sent" << size << "bytes to" << _hostAddress.toString() << ":" << _port << "data:";
    qDebug() << bytes;
    qDebug() << "ASCII:" << ascii;
}
#endif

void TCPLink::writeBytes(const char* data, qint64 size)
{
#ifdef TCPLINK_READWRITE_DEBUG
    _writeDebugBytes(data, size);
#endif
    _socket->write(data, size);

    // Log the amount and time written out for future data rate calculations.
    QMutexLocker dataRateLocker(&dataRateMutex);
    logDataRateToBuffer(outDataWriteAmounts, outDataWriteTimes, &outDataIndex, size, QDateTime::currentMSecsSinceEpoch());
}

/**
 * @brief Read a number of bytes from the interface.
 *
 * @param data Pointer to the data byte array to write the bytes to
 * @param maxLength The maximum number of bytes to write
 **/
void TCPLink::readBytes()
{
    qint64 byteCount = _socket->bytesAvailable();

    if (byteCount)
    {
        QByteArray buffer;
        buffer.resize(byteCount);

        _socket->read(buffer.data(), buffer.size());

        emit bytesReceived(this, buffer);

        // Log the amount and time received for future data rate calculations.
        QMutexLocker dataRateLocker(&dataRateMutex);
        logDataRateToBuffer(inDataWriteAmounts, inDataWriteTimes, &inDataIndex, byteCount, QDateTime::currentMSecsSinceEpoch());

#ifdef TCPLINK_READWRITE_DEBUG
        writeDebugBytes(buffer.data(), buffer.size());
#endif
    }
}

/**
 * @brief Get the number of bytes to read.
 *
 * @return The number of bytes to read
 **/
qint64 TCPLink::bytesAvailable()
{
    return _socket->bytesAvailable();
}

/**
 * @brief Disconnect the connection.
 *
 * @return True if connection has been disconnected, false if connection couldn't be disconnected.
 **/
bool TCPLink::disconnect()
{
	quit();
	wait();

    if (_socket)
	{
        _socketIsConnected = false;
		_socket->deleteLater(); // Make sure delete happens on correct thread
		_socket = NULL;

        emit disconnected();
        emit connected(false);
	}

    return true;
}

/**
 * @brief Connect the connection.
 *
 * @return True if connection has been established, false if connection couldn't be established.
 **/
bool TCPLink::connect()
{
	if (isRunning())
	{
		quit();
		wait();
	}

    start(HighPriority);

    return true;
}

bool TCPLink::_hardwareConnect(void)
{
    Q_ASSERT(_socket == NULL);
	_socket = new QTcpSocket();

    QSignalSpy errorSpy(_socket, SIGNAL(error(QAbstractSocket::SocketError)));

    _socket->connectToHost(_hostAddress, _port);

    QObject::connect(_socket, SIGNAL(readyRead()), this, SLOT(readBytes()));
    QObject::connect(_socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(_socketError(QAbstractSocket::SocketError)));

    // Give the socket a second to connect to the other side otherwise error out
    if (!_socket->waitForConnected(1000))
    {
        // Whether a failed connection emits an error signal or not is platform specific.
        // So in cases where it is not emitted, we emit one ourselves.
        if (errorSpy.count() == 0) {
            emit communicationError(getName(), "Connection failed");
        }
        delete _socket;
        _socket = NULL;
        return false;
    }

    _socketIsConnected = true;
    emit connected(true);
    emit connected();

    return true;
}

void TCPLink::_socketError(QAbstractSocket::SocketError socketError)
{
    Q_UNUSED(socketError);
    emit communicationError(getName(), "Error on socket: " + _socket->errorString());
}

/**
 * @brief Check if connection is active.
 *
 * @return True if link is connected, false otherwise.
 **/
bool TCPLink::isConnected() const
{
    return _socketIsConnected;
}

int TCPLink::getId() const
{
    return _linkId;
}

QString TCPLink::getName() const
{
    return _name;
}

qint64 TCPLink::getConnectionSpeed() const
{
    return 54000000; // 54 Mbit
}

qint64 TCPLink::getCurrentInDataRate() const
{
    return 0;
}

qint64 TCPLink::getCurrentOutDataRate() const
{
    return 0;
}

void TCPLink::_resetName(void)
{
    _name = QString("TCP Link (host:%1 port:%2)").arg(_hostAddress.toString()).arg(_port);
    emit nameChanged(_name);
}

void TCPLink::waitForBytesWritten(int msecs)
{
    Q_ASSERT(_socket);
    _socket->waitForBytesWritten(msecs);
}

void TCPLink::waitForReadyRead(int msecs)
{
    Q_ASSERT(_socket);
    _socket->waitForReadyRead(msecs);
}
<|endoftext|>