<commit_before>#include "aa_controller.h"
#include "animation.h"
#include "p_rect.h"
//#include "stack_cutter.h"
#include <iostream>
#include <string>

std::array<int,3> aa_controller::prompt_for_quadratic_coeffs(bool allow_negatives) {
	std::array<int,3> out{};
	std::string vars[] = {"a","b","c"};
	for (int i = 0; i < 3; ++i) {
		std::cout << vars[i] << " = " << std::endl;
		std::cin >> out[i];
		while (!allow_negatives && out[i] < 0) {
			std::cout << "Non-negative values are not permitted." << std::endl;
			std::cout << vars[i] << " = " << std::endl;
			std::cin >> out[i];
		}
	}
	return out;
}

void aa_controller::animate_quadratic_factorization(std::array<int,3> coeffs) {
	int a = std::get<0>(coeffs);
	int b = std::get<1>(coeffs);
	int c = std::get<2>(coeffs);
	animate_quadratic_factorization(a,b,c);
}

void aa_controller::animate_quadratic_factorization(const int a, const int b, const int c) {
	// factors ax^2 + bx + c into (a0x + b0)(a1x + b1)
	std::tuple<bool,int,int,int,int> f = algebra::quad_factor(a,b,c);

	bool is_factorable = std::get<0>(f);
	if (!is_factorable) {
		std::cout << "not factorable." << std::endl;
		return;
	}
	int a0 = std::get<1>(f);
	int b0 = std::get<2>(f);
	int a1 = std::get<3>(f);
	int b1 = std::get<4>(f);

	// set up scene
	// 3 p_rects to start
	// 1st column: 1x by a x's
	// 2nd column: 1x by b 1's
	// 3rd column: 1 by c 1's

	// first split second column into two sub-columns
	// col 2a:  1x wide by a0*b1 1's high
	// col 2b:  1x wide by a1*b0 1's high

	// split first column into a0 columns, each of which is 1x wide and a1 x's high (group 1)
	// split subcolumns 2a and 2b into two groups of columns:
	// group 2a: a0 columns, each of which is 1x wide and b1 1's high
	// group 2b: a1 columns, each of which is 1x wide and b0 1's high
	// split 3rd column into b0 columns, each of which is 1 wide and b1 1's high (group 3)

	// lock the groups together
	// move group 2a on top of group 1
	// rotate group 2b
	// move group 3 on top of group 2b

	/*
	ascii_viewer vwr{};
	auto s = std::make_shared<scene>();
	auto root = std::make_shared<node>();
	s->set_root(root);
	view v{};
	ascii_renderer r{};
	v.rectangle = located<rect,2>(rect(STD_VIEW_WIDTH,STD_VIEW_HEIGHT),point<2>(0,0));
	v.scn = std::weak_ptr<scene>(s);
	auto animation_ = std::make_shared<animation<wchar_t>>();
	animation_->set_animation_speed(3);

	length one{"1",1};
	length x{"x",2};
	std::shared_ptr<p_rect> group1, group2, group3;
	group1 = std::make_shared<p_rect>(std::vector<length>(1,x),std::vector<length>(a,x));
	group2 = std::make_shared<p_rect>(std::vector<length>(1,x),std::vector<length>(b,one));
	group3 = std::make_shared<p_rect>(std::vector<length>(1,one),std::vector<length>(c,one));

	root->add_child(group1);
	root->add_child(group2);
	root->add_child(group3);
	group1->set_location(0,0,0);
	group2->set_location(group1->width() + p_rect::unit_size,0,0);
	group3->set_location(group2->get_location() + point<3>(group2->width() + p_rect::unit_size,0,0));

	animation_->append_frame(v.render(r));

	stack_cutter sc{v,animation_};
	auto group3_p = sc.cut_and_stack(group3,b0);
	group3_p->shift(group2->width() + p_rect::unit_size,0,0);
	auto group2_p = sc.cut_and_stack(group2,std::set<int>({static_cast<int>(a0 * b1)}));
	auto group2_a = group2_p->get_children()[0];
	auto group2_b = group2_p->get_children()[1];
	group2_a->set_parent(root,true);
	group2_b->set_parent(root,true);

	vwr.present(*animation_);
	*/
}<commit_msg>remove obsolete animation code.  add user interface code.<commit_after>#include "aa_controller.h"
#include "animation.h"
#include "p_rect.h"
#include "quad_factor_animator.h"
#include "viewer.h"
#include <iostream>
#include <string>

std::array<int,3> aa_controller::prompt_for_quadratic_coeffs(bool allow_negatives) {
	std::array<int,3> out{};
	std::string vars[] = {"a","b","c"};

	std::cout << "Enter coefficients : ax^2 + bx + c" << std::endl;
	for (int i = 0; i < 3; ++i) {
		std::cout << vars[i] << " = " << std::endl;
		std::cin >> out[i];
		while (!allow_negatives && out[i] < 0) {
			std::cout << "Non-negative values are not permitted." << std::endl;
			std::cout << vars[i] << " = " << std::endl;
			std::cin >> out[i];
		}
	}
	return out;
}

void aa_controller::animate_quadratic_factorization(std::array<int,3> coeffs) {
	int a = std::get<0>(coeffs);
	int b = std::get<1>(coeffs);
	int c = std::get<2>(coeffs);
	animate_quadratic_factorization(a,b,c);
}

void aa_controller::animate_quadratic_factorization(int a, int b, int c) {
	auto qfa = quad_factor_animator(a,b,c);
	ascii_viewer vwr{};
	vwr.present(*qfa.animate());
}<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: documentacceleratorconfiguration.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2004-12-08 08:32:53 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  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., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef __FRAMEWORK_ACCELERATORS_DOCUMENTACCELERATORCONFIGURATION_HXX_
#define __FRAMEWORK_ACCELERATORS_DOCUMENTACCELERATORCONFIGURATION_HXX_

//__________________________________________
// own includes

#ifndef __FRAMEWORK_ACCELERATORS_ACCELERATORCONFIGURATION_HXX_
#include <accelerators/acceleratorconfiguration.hxx>
#endif

#ifndef __FRAMEWORK_ACCELERATORS_PRESETHANDLER_HXX_
#include <accelerators/presethandler.hxx>
#endif

#ifndef __FRAMEWORK_MACROS_XINTERFACE_HXX_
#include <macros/interface.hxx>
#endif

#ifndef __FRAMEWORK_MACROS_XTYPEPROVIDER_HXX_
#include <macros/xtypeprovider.hxx>
#endif

#ifndef __FRAMEWORK_MACROS_XSERVICEINFO_HXX_
#include <macros/xserviceinfo.hxx>
#endif

//__________________________________________
// interface includes

#ifndef _COM_SUN_STAR_LANG_XINITIALIZATION_HPP_
#include <com/sun/star/lang/XInitialization.hpp>
#endif

#ifndef _DRAFTS_COM_SUN_STAR_UI_XUICONFIGURATIONSTORAGE_HPP_
#include <drafts/com/sun/star/ui/XUIConfigurationStorage.hpp>
#endif

//__________________________________________
// other includes

//__________________________________________
// definition

namespace framework
{

//__________________________________________
/**
    implements a read/write access to a document
    based accelerator configuration.
 */
class DocumentAcceleratorConfiguration : public AcceleratorConfiguration
                                       , public css::lang::XServiceInfo
                                       , public css::lang::XInitialization
//                                       , public dcss::ui::XUIConfigurationStorage
{
    //______________________________________
    // member

    private:

        //----------------------------------
        /** points to the root storage of the outside document,
            where we can read/save our configuration data. */
        css::uno::Reference< css::embed::XStorage > m_xDocumentRoot;

    //______________________________________
    // interface

    public:

        //----------------------------------
        /** initialize this instance and fill the internal cache.

            @param  xSMGR
                    reference to an uno service manager, which is used internaly.
         */
        DocumentAcceleratorConfiguration(const css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR);
        virtual ~DocumentAcceleratorConfiguration();

        // XInterface, XTypeProvider, XServiceInfo
        DECLARE_XINTERFACE
        DECLARE_XTYPEPROVIDER
        DECLARE_XSERVICEINFO

        // XInitialization
        virtual void SAL_CALL initialize(const css::uno::Sequence< css::uno::Any >& lArguments)
            throw(css::uno::Exception       ,
                  css::uno::RuntimeException);

        // XUIConfigurationStorage
        virtual void SAL_CALL setStorage(const css::uno::Reference< css::embed::XStorage >& xStorage)
            throw(css::uno::RuntimeException);

        virtual sal_Bool SAL_CALL hasStorage()
            throw(css::uno::RuntimeException);

    //______________________________________
    // helper

    private:

        //----------------------------------
        /** read all data into the cache. */
        void impl_ts_fillCache();

        //----------------------------------
        /** forget all currently cached data AND(!)
            forget all currently used storages. */
        void impl_ts_clearCache();
};

} // namespace framework

#endif // __FRAMEWORK_ACCELERATORS_DOCUMENTACCELERATORCONFIGURATION_HXX_
<commit_msg>INTEGRATION: CWS removedrafts (1.4.58); FILE MERGED 2005/02/17 12:47:41 cd 1.4.58.1: #i42557# move UNOIDL types from drafts to com<commit_after>/*************************************************************************
 *
 *  $RCSfile: documentacceleratorconfiguration.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: kz $ $Date: 2005-03-01 19:37:35 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  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., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef __FRAMEWORK_ACCELERATORS_DOCUMENTACCELERATORCONFIGURATION_HXX_
#define __FRAMEWORK_ACCELERATORS_DOCUMENTACCELERATORCONFIGURATION_HXX_

//__________________________________________
// own includes

#ifndef __FRAMEWORK_ACCELERATORS_ACCELERATORCONFIGURATION_HXX_
#include <accelerators/acceleratorconfiguration.hxx>
#endif

#ifndef __FRAMEWORK_ACCELERATORS_PRESETHANDLER_HXX_
#include <accelerators/presethandler.hxx>
#endif

#ifndef __FRAMEWORK_MACROS_XINTERFACE_HXX_
#include <macros/interface.hxx>
#endif

#ifndef __FRAMEWORK_MACROS_XTYPEPROVIDER_HXX_
#include <macros/xtypeprovider.hxx>
#endif

#ifndef __FRAMEWORK_MACROS_XSERVICEINFO_HXX_
#include <macros/xserviceinfo.hxx>
#endif

//__________________________________________
// interface includes

#ifndef _COM_SUN_STAR_LANG_XINITIALIZATION_HPP_
#include <com/sun/star/lang/XInitialization.hpp>
#endif

#ifndef _COM_SUN_STAR_UI_XUICONFIGURATIONSTORAGE_HPP_
#include <com/sun/star/ui/XUIConfigurationStorage.hpp>
#endif

//__________________________________________
// other includes

//__________________________________________
// definition

namespace framework
{

//__________________________________________
/**
    implements a read/write access to a document
    based accelerator configuration.
 */
class DocumentAcceleratorConfiguration : public AcceleratorConfiguration
                                       , public css::lang::XServiceInfo
                                       , public css::lang::XInitialization
//                                       , public css::ui::XUIConfigurationStorage
{
    //______________________________________
    // member

    private:

        //----------------------------------
        /** points to the root storage of the outside document,
            where we can read/save our configuration data. */
        css::uno::Reference< css::embed::XStorage > m_xDocumentRoot;

    //______________________________________
    // interface

    public:

        //----------------------------------
        /** initialize this instance and fill the internal cache.

            @param  xSMGR
                    reference to an uno service manager, which is used internaly.
         */
        DocumentAcceleratorConfiguration(const css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR);
        virtual ~DocumentAcceleratorConfiguration();

        // XInterface, XTypeProvider, XServiceInfo
        DECLARE_XINTERFACE
        DECLARE_XTYPEPROVIDER
        DECLARE_XSERVICEINFO

        // XInitialization
        virtual void SAL_CALL initialize(const css::uno::Sequence< css::uno::Any >& lArguments)
            throw(css::uno::Exception       ,
                  css::uno::RuntimeException);

        // XUIConfigurationStorage
        virtual void SAL_CALL setStorage(const css::uno::Reference< css::embed::XStorage >& xStorage)
            throw(css::uno::RuntimeException);

        virtual sal_Bool SAL_CALL hasStorage()
            throw(css::uno::RuntimeException);

    //______________________________________
    // helper

    private:

        //----------------------------------
        /** read all data into the cache. */
        void impl_ts_fillCache();

        //----------------------------------
        /** forget all currently cached data AND(!)
            forget all currently used storages. */
        void impl_ts_clearCache();
};

} // namespace framework

#endif // __FRAMEWORK_ACCELERATORS_DOCUMENTACCELERATORCONFIGURATION_HXX_
<|endoftext|>


<commit_before>// Maintainer: Jan Kristian Sto. Domingo [jstod001@ucr.edu]
// exec.cpp for rshell

#include <iostream>
#include <cstring>
#include <string>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

using namespace std;

//Notes on function formats:
//execvp(const char *file, char *const argv[])

// tokenCounter function used to determine size of dynamically
// allocated array for use in the execvp function
unsigned tokenCounter(char* a)
{
    unsigned count = 0;
    char* token;

    token = strtok(a, " ;");

    while(token != NULL)
    {
        token = strtok(NULL, " ;");
        count++;
    }

    return count;
}

int main()
{
    int PID = fork();
    if(PID == 0)
    {
        //cout << "child process" << endl;

        // command prompt
        char* username = getlogin();
        char hostname[20];
        gethostname(hostname, 20);
        cout << username << "@" << hostname << "$ ";

        string str_input;
        getline(cin, str_input);

        // output message for test purposes
        // cout << "Original string: " << str_input << endl << endl;

        char* c_input = new char[str_input.length() + 1];
        strcpy(c_input, str_input.c_str());

        // output message for test purposes
        // cout << "Converted to cstring: " << c_input << endl << endl;

        // new cstring now has to be tokenized and placed into a char**
        // for the exec vp function

        char* tmp = new char[str_input.length() + 1];
        strcpy(tmp, c_input);
        // tmp protects the original cstring input
        // tmp will be used for the tokenCounter function

        unsigned token_count = 0;
        token_count = tokenCounter(tmp);

        char** arg;
        arg = new char* [token_count];

        // output message for test purposes
        // cout << "c_input after tokenCounter: " << c_input << endl;

        // the following chunk of code will take each token
        // and place it into arg which will then be used as
        // a parameter in execvp
        unsigned i = 0;
        char* ptr;
        ptr = strtok(c_input, " ;");
        while(ptr != NULL)
        {
            arg[i] = ptr;
            // cout message for test purposes
            cout << "arg[" << i << "] = " << arg[i] << endl;
            ptr = strtok(NULL, " ;");
            i++;
        }

        //cout << arg[0] << endl;
        char exit_key[5] = "exit";
        //cout << "arg[0]: " << arg[0] << endl;
        //cout << "exit_key: " << exit_key << endl;
        //cout << strcmp(arg[0], exit_key) << endl;
        if(*arg[0] == *exit_key)
        {
            //cout << "executing exit(0)" << endl;
            exit(0);
        }
        else
        {
            execvp(arg[0], arg);
            perror(arg[0]);
        }
    }
    else
    {
        if(PID == -1)
        {
            perror("fork");
        }
        int w = wait(0);
        if(w == -1)
        {
            perror("wait");
        }
        //cout << "parent process" << endl;
    }

    return 0;
}

<commit_msg>fixed bug where program will exit if executable entered exists and is four characters in length<commit_after>// Maintainer: Jan Kristian Sto. Domingo [jstod001@ucr.edu]
// exec.cpp for rshell

#include <iostream>
#include <cstring>
#include <string>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

using namespace std;

//Notes on function formats:
//execvp(const char *file, char *const argv[])

// tokenCounter function used to determine size of dynamically
// allocated array for use in the execvp function
unsigned tokenCounter(char* a)
{
    unsigned count = 0;
    char* token;

    token = strtok(a, " ;");

    while(token != NULL)
    {
        token = strtok(NULL, " ;");
        count++;
    }

    return count;
}

int main()
{
    int PID = fork();
    if(PID == 0)
    {
        //cout << "child process" << endl;

        // command prompt
        char* username = getlogin();
        char hostname[20];
        gethostname(hostname, 20);
        cout << username << "@" << hostname << "$ ";

        string str_input;
        getline(cin, str_input);

        // output message for test purposes
        // cout << "Original string: " << str_input << endl << endl;

        char* c_input = new char[str_input.length() + 1];
        strcpy(c_input, str_input.c_str());

        // output message for test purposes
        // cout << "Converted to cstring: " << c_input << endl << endl;

        // new cstring now has to be tokenized and placed into a char**
        // for the exec vp function

        char* tmp = new char[str_input.length() + 1];
        strcpy(tmp, c_input);
        // tmp protects the original cstring input
        // tmp will be used for the tokenCounter function

        unsigned token_count = 0;
        token_count = tokenCounter(tmp);

        char** arg;
        arg = new char* [token_count];

        // output message for test purposes
        // cout << "c_input after tokenCounter: " << c_input << endl;

        // the following chunk of code will take each token
        // and place it into arg which will then be used as
        // a parameter in execvp
        unsigned i = 0;
        char* ptr;
        ptr = strtok(c_input, " ;");
        while(ptr != NULL)
        {
            arg[i] = ptr;
            // cout message for test purposes
            cout << "arg[" << i << "] = " << arg[i] << endl;
            ptr = strtok(NULL, " ;");
            i++;
        }

        //cout << arg[0] << endl;
        if(string(arg[0]) == "exit")
        {
            cout << "executing exit(0)" << endl;
            exit(0);
        }
        else
        {
            cout << "in execvp" << endl;
            execvp(arg[0], arg);
            perror(arg[0]);
        }
    }
    else
    {
        if(PID == -1)
        {
            perror("fork");
        }
        int w = wait(0);
        if(w == -1)
        {
            perror("wait");
        }
        //cout << "parent process" << endl;
    }

    return 0;
}

<|endoftext|>


<commit_before>#include "L3G.h"
#include <stdexcept>

#define L3G4200D_ADDRESS_SA0_LOW  (0xD0 >> 1)
#define L3G4200D_ADDRESS_SA0_HIGH (0xD2 >> 1)
#define L3GD20_ADDRESS_SA0_LOW    (0xD4 >> 1)
#define L3GD20_ADDRESS_SA0_HIGH   (0xD6 >> 1)

L3G::L3G(const char * i2cDeviceName) : i2c(i2cDeviceName)
{
    // Auto-detect address
    // try each possible address and stop if reading WHO_AM_I returns the expected response

    detectAddress();
}

void L3G::detectAddress()
{
    i2c.addressSet(L3G4200D_ADDRESS_SA0_LOW);
    if (i2c.tryReadByte(L3G_WHO_AM_I) == 0xD3) return;
    i2c.addressSet(L3G4200D_ADDRESS_SA0_HIGH);
    if (i2c.tryReadByte(L3G_WHO_AM_I) == 0xD3) return;
    i2c.addressSet(L3GD20_ADDRESS_SA0_LOW);
    if (i2c.tryReadByte(L3G_WHO_AM_I) == 0xD4) return;
    i2c.addressSet(L3GD20_ADDRESS_SA0_HIGH);
    if (i2c.tryReadByte(L3G_WHO_AM_I) == 0xD4) return;

    throw std::runtime_error("Could not detect gyro.");
}

// Turns on the gyro and places it in normal mode.
void L3G::enableDefault()
{
    // Normal power mode, all axes enabled
    writeReg(L3G_CTRL_REG1, 0b00001111);
}

void L3G::writeReg(uint8_t reg, uint8_t value)
{
    i2c.writeByte(reg, value);
}

uint8_t L3G::readReg(uint8_t reg)
{
    return i2c.readByte(reg);
}

void L3G::read()
{
    uint8_t block[6];
    i2c.readBlock(0x80 | L3G_OUT_X_L, sizeof(block), block);

    g[0] = (int16_t)(block[1] << 8 | block[0]);
    g[1] = (int16_t)(block[3] << 8 | block[2]);
    g[2] = (int16_t)(block[5] << 8 | block[4]);
}
<commit_msg>Removed some comments.<commit_after>#include "L3G.h"
#include <stdexcept>

#define L3G4200D_ADDRESS_SA0_LOW  (0xD0 >> 1)
#define L3G4200D_ADDRESS_SA0_HIGH (0xD2 >> 1)
#define L3GD20_ADDRESS_SA0_LOW    (0xD4 >> 1)
#define L3GD20_ADDRESS_SA0_HIGH   (0xD6 >> 1)

L3G::L3G(const char * i2cDeviceName) : i2c(i2cDeviceName)
{
    detectAddress();
}

void L3G::detectAddress()
{
    i2c.addressSet(L3G4200D_ADDRESS_SA0_LOW);
    if (i2c.tryReadByte(L3G_WHO_AM_I) == 0xD3) return;
    i2c.addressSet(L3G4200D_ADDRESS_SA0_HIGH);
    if (i2c.tryReadByte(L3G_WHO_AM_I) == 0xD3) return;
    i2c.addressSet(L3GD20_ADDRESS_SA0_LOW);
    if (i2c.tryReadByte(L3G_WHO_AM_I) == 0xD4) return;
    i2c.addressSet(L3GD20_ADDRESS_SA0_HIGH);
    if (i2c.tryReadByte(L3G_WHO_AM_I) == 0xD4) return;

    throw std::runtime_error("Could not detect gyro.");
}

// Turns on the gyro and places it in normal mode.
void L3G::enableDefault()
{
    // Normal power mode, all axes enabled
    writeReg(L3G_CTRL_REG1, 0b00001111);
}

void L3G::writeReg(uint8_t reg, uint8_t value)
{
    i2c.writeByte(reg, value);
}

uint8_t L3G::readReg(uint8_t reg)
{
    return i2c.readByte(reg);
}

void L3G::read()
{
    uint8_t block[6];
    i2c.readBlock(0x80 | L3G_OUT_X_L, sizeof(block), block);

    g[0] = (int16_t)(block[1] << 8 | block[0]);
    g[1] = (int16_t)(block[3] << 8 | block[2]);
    g[2] = (int16_t)(block[5] << 8 | block[4]);
}
<|endoftext|>


<commit_before>/*

Copyright (c) 2003, Arvid Norberg
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 "libtorrent/pch.hpp"

#ifdef _WIN32
// windows part
#include "libtorrent/utf8.hpp"

#include <io.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>

#ifndef _MODE_T_
typedef int mode_t;
#endif

#ifdef UNICODE
#include "libtorrent/storage.hpp"
#endif

#else
// unix part
#define _FILE_OFFSET_BITS 64
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>

#include <boost/static_assert.hpp>
// make sure the _FILE_OFFSET_BITS define worked
// on this platform
BOOST_STATIC_ASSERT(sizeof(lseek(0, 0, 0)) >= 8);

#endif

#include <boost/filesystem/operations.hpp>
#include "libtorrent/file.hpp"
#include <sstream>

#ifndef O_BINARY
#define O_BINARY 0
#endif

#ifndef O_RANDOM
#define O_RANDOM 0
#endif

#ifdef UNICODE
#include "libtorrent/storage.hpp"
#endif

namespace fs = boost::filesystem;

namespace
{
	enum { mode_in = 1, mode_out = 2 };

	mode_t map_open_mode(int m)
	{
		if (m == (mode_in | mode_out)) return O_RDWR | O_CREAT | O_BINARY | O_RANDOM;
		if (m == mode_out) return O_WRONLY | O_CREAT | O_BINARY | O_RANDOM;
		if (m == mode_in) return O_RDONLY | O_BINARY | O_RANDOM;
		assert(false);
		return 0;
	}

#ifdef WIN32
	std::string utf8_native(std::string const& s)
	{
		try
		{
			std::wstring ws;
			libtorrent::utf8_wchar(s, ws);
			std::size_t size = wcstombs(0, ws.c_str(), 0);
			if (size == std::size_t(-1)) return s;
			std::string ret;
			ret.resize(size);
			size = wcstombs(&ret[0], ws.c_str(), size + 1);
			if (size == wchar_t(-1)) return s;
			ret.resize(size);
			return ret;
		}
		catch(std::exception)
		{
			return s;
		}
	}
#else
	std::string utf8_native(std::string const& s)
	{
		return s;
	}
#endif

}

namespace libtorrent
{

	const file::open_mode file::in(mode_in);
	const file::open_mode file::out(mode_out);

	const file::seek_mode file::begin(1);
	const file::seek_mode file::end(2);

	struct file::impl
	{
		impl()
			: m_fd(-1)
			, m_open_mode(0)
		{}

		impl(fs::path const& path, int mode)
			: m_fd(-1)
			, m_open_mode(0)
		{
			open(path, mode);
		}

		~impl()
		{
			close();
		}

		void open(fs::path const& path, int mode)
		{
			assert(path.is_complete());
			close();
#if defined(_WIN32) && defined(UNICODE)
			std::wstring wpath(safe_convert(path.native_file_string()));
			m_fd = ::_wopen(
				wpath.c_str()
				, map_open_mode(mode)
				, S_IREAD | S_IWRITE);
#else
#ifdef _WIN32
			m_fd = ::_open(
#else
			m_fd = ::open(
#endif
				utf8_native(path.native_file_string()).c_str()
				, map_open_mode(mode)
#ifdef _WIN32
				, S_IREAD | S_IWRITE);
#else
				, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
#endif
#endif
			if (m_fd == -1)
			{
				std::stringstream msg;
				msg << "open failed: '" << path.native_file_string() << "'. "
					<< strerror(errno);
				throw file_error(msg.str());
			}
			m_open_mode = mode;
		}

		void close()
		{
			if (m_fd == -1) return;

#ifdef _WIN32
			::_close(m_fd);
#else
			::close(m_fd);
#endif
			m_fd = -1;
			m_open_mode = 0;
		}

		size_type read(char* buf, size_type num_bytes)
		{
			assert(num_bytes > 0);
			assert(m_open_mode & mode_in);
			assert(m_fd != -1);

#ifdef _WIN32
			size_type ret = ::_read(m_fd, buf, num_bytes);
#else
			size_type ret = ::read(m_fd, buf, num_bytes);
#endif
			if (ret == -1 || ret == 0)
			{
				std::stringstream msg;
				msg << "read failed: " << strerror(errno);
				throw file_error(msg.str());
			}
			return ret;
		}

		size_type write(const char* buf, size_type num_bytes)
		{
			assert(m_open_mode & mode_out);
			assert(m_fd != -1);

			// TODO: Test this a bit more, what happens with random failures in
			// the files?
//			if ((rand() % 100) > 80)
//				throw file_error("debug");

#ifdef _WIN32
			size_type ret = ::_write(m_fd, buf, num_bytes);
#else
			size_type ret = ::write(m_fd, buf, num_bytes);
#endif
			if (ret == -1)
			{
				std::stringstream msg;
				msg << "write failed: " << strerror(errno);
				throw file_error(msg.str());
			}
			return ret;
		}

		size_type seek(size_type offset, int m)
		{
			assert(m_open_mode);
			assert(m_fd != -1);

			int seekdir = (m == 1)?SEEK_SET:SEEK_END;
#ifdef _WIN32
			size_type ret = _lseeki64(m_fd, offset, seekdir);
#else
			size_type ret = lseek(m_fd, offset, seekdir);
#endif

			// For some strange reason this fails
			// on win32. Use windows specific file
			// wrapper instead.
			if (ret == -1)
			{
				std::stringstream msg;
				msg << "seek failed: '" << strerror(errno)
					<< "' fd: " << m_fd
					<< " offset: " << offset
					<< " seekdir: " << seekdir;
				throw file_error(msg.str());
			}
			return ret;
		}

		size_type tell()
		{
			assert(m_open_mode);
			assert(m_fd != -1);

#ifdef _WIN32
			return _telli64(m_fd);
#else
			return lseek(m_fd, 0, SEEK_CUR);
#endif
		}

		int m_fd;
		int m_open_mode;
	};

	// pimpl forwardings

	file::file() : m_impl(new impl()) {}

	file::file(boost::filesystem::path const& p, file::open_mode m)
		: m_impl(new impl(p, m.m_mask))
	{}

	file::~file() {}

	void file::open(boost::filesystem::path const& p, file::open_mode m)
	{
		m_impl->open(p, m.m_mask);
	}

	void file::close()
	{
		m_impl->close();
	}

	size_type file::write(const char* buf, size_type num_bytes)
	{
		return m_impl->write(buf, num_bytes);
	}

	size_type file::read(char* buf, size_type num_bytes)
	{
		return m_impl->read(buf, num_bytes);
	}

	size_type file::seek(size_type pos, file::seek_mode m)
	{
		return m_impl->seek(pos, m.m_val);
	}

	size_type file::tell()
	{
		return m_impl->tell();
	}

}
<commit_msg>reverted last check-in<commit_after>/*

Copyright (c) 2003, Arvid Norberg
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 "libtorrent/pch.hpp"

#ifdef _WIN32
// windows part
#include "libtorrent/utf8.hpp"

#include <io.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>

#ifndef _MODE_T_
typedef int mode_t;
#endif

#ifdef UNICODE
#include "libtorrent/storage.hpp"
#endif

#else
// unix part
#define _FILE_OFFSET_BITS 64
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>

#include <boost/static_assert.hpp>
// make sure the _FILE_OFFSET_BITS define worked
// on this platform
BOOST_STATIC_ASSERT(sizeof(lseek(0, 0, 0)) >= 8);

#endif

#include <boost/filesystem/operations.hpp>
#include "libtorrent/file.hpp"
#include <sstream>

#ifndef O_BINARY
#define O_BINARY 0
#endif

#ifndef O_RANDOM
#define O_RANDOM 0
#endif

#ifdef UNICODE
#include "libtorrent/storage.hpp"
#endif

namespace fs = boost::filesystem;

namespace
{
	enum { mode_in = 1, mode_out = 2 };

	mode_t map_open_mode(int m)
	{
		if (m == (mode_in | mode_out)) return O_RDWR | O_CREAT | O_BINARY | O_RANDOM;
		if (m == mode_out) return O_WRONLY | O_CREAT | O_BINARY | O_RANDOM;
		if (m == mode_in) return O_RDONLY | O_BINARY | O_RANDOM;
		assert(false);
		return 0;
	}

#ifdef WIN32
	std::string utf8_native(std::string const& s)
	{
		try
		{
			std::wstring ws;
			libtorrent::utf8_wchar(s, ws);
			std::size_t size = wcstombs(0, ws.c_str(), 0);
			if (size == std::size_t(-1)) return s;
			std::string ret;
			ret.resize(size);
			size = wcstombs(&ret[0], ws.c_str(), size + 1);
			if (size == wchar_t(-1)) return s;
			ret.resize(size);
			return ret;
		}
		catch(std::exception)
		{
			return s;
		}
	}
#else
	std::string utf8_native(std::string const& s)
	{
		return s;
	}
#endif

}

namespace libtorrent
{

	const file::open_mode file::in(mode_in);
	const file::open_mode file::out(mode_out);

	const file::seek_mode file::begin(1);
	const file::seek_mode file::end(2);

	struct file::impl
	{
		impl()
			: m_fd(-1)
			, m_open_mode(0)
		{}

		impl(fs::path const& path, int mode)
			: m_fd(-1)
			, m_open_mode(0)
		{
			open(path, mode);
		}

		~impl()
		{
			close();
		}

		void open(fs::path const& path, int mode)
		{
			assert(path.is_complete());
			close();
#if defined(_WIN32) && defined(UNICODE)
			std::wstring wpath(safe_convert(path.native_file_string()));
			m_fd = ::_wopen(
				wpath.c_str()
				, map_open_mode(mode)
				, S_IREAD | S_IWRITE);
#else
#ifdef _WIN32
			m_fd = ::_open(
#else
			m_fd = ::open(
#endif
				utf8_native(path.native_file_string()).c_str()
				, map_open_mode(mode)
#ifdef _WIN32
				, S_IREAD | S_IWRITE);
#else
				, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
#endif
#endif
			if (m_fd == -1)
			{
				std::stringstream msg;
				msg << "open failed: '" << path.native_file_string() << "'. "
					<< strerror(errno);
				throw file_error(msg.str());
			}
			m_open_mode = mode;
		}

		void close()
		{
			if (m_fd == -1) return;

#ifdef _WIN32
			::_close(m_fd);
#else
			::close(m_fd);
#endif
			m_fd = -1;
			m_open_mode = 0;
		}

		size_type read(char* buf, size_type num_bytes)
		{
			assert(m_open_mode & mode_in);
			assert(m_fd != -1);

#ifdef _WIN32
			size_type ret = ::_read(m_fd, buf, num_bytes);
#else
			size_type ret = ::read(m_fd, buf, num_bytes);
#endif
			if (ret == -1)
			{
				std::stringstream msg;
				msg << "read failed: " << strerror(errno);
				throw file_error(msg.str());
			}
			return ret;
		}

		size_type write(const char* buf, size_type num_bytes)
		{
			assert(m_open_mode & mode_out);
			assert(m_fd != -1);

			// TODO: Test this a bit more, what happens with random failures in
			// the files?
//			if ((rand() % 100) > 80)
//				throw file_error("debug");

#ifdef _WIN32
			size_type ret = ::_write(m_fd, buf, num_bytes);
#else
			size_type ret = ::write(m_fd, buf, num_bytes);
#endif
			if (ret == -1)
			{
				std::stringstream msg;
				msg << "write failed: " << strerror(errno);
				throw file_error(msg.str());
			}
			return ret;
		}

		size_type seek(size_type offset, int m)
		{
			assert(m_open_mode);
			assert(m_fd != -1);

			int seekdir = (m == 1)?SEEK_SET:SEEK_END;
#ifdef _WIN32
			size_type ret = _lseeki64(m_fd, offset, seekdir);
#else
			size_type ret = lseek(m_fd, offset, seekdir);
#endif

			// For some strange reason this fails
			// on win32. Use windows specific file
			// wrapper instead.
			if (ret == -1)
			{
				std::stringstream msg;
				msg << "seek failed: '" << strerror(errno)
					<< "' fd: " << m_fd
					<< " offset: " << offset
					<< " seekdir: " << seekdir;
				throw file_error(msg.str());
			}
			return ret;
		}

		size_type tell()
		{
			assert(m_open_mode);
			assert(m_fd != -1);

#ifdef _WIN32
			return _telli64(m_fd);
#else
			return lseek(m_fd, 0, SEEK_CUR);
#endif
		}

		int m_fd;
		int m_open_mode;
	};

	// pimpl forwardings

	file::file() : m_impl(new impl()) {}

	file::file(boost::filesystem::path const& p, file::open_mode m)
		: m_impl(new impl(p, m.m_mask))
	{}

	file::~file() {}

	void file::open(boost::filesystem::path const& p, file::open_mode m)
	{
		m_impl->open(p, m.m_mask);
	}

	void file::close()
	{
		m_impl->close();
	}

	size_type file::write(const char* buf, size_type num_bytes)
	{
		return m_impl->write(buf, num_bytes);
	}

	size_type file::read(char* buf, size_type num_bytes)
	{
		return m_impl->read(buf, num_bytes);
	}

	size_type file::seek(size_type pos, file::seek_mode m)
	{
		return m_impl->seek(pos, m.m_val);
	}

	size_type file::tell()
	{
		return m_impl->tell();
	}

}
<|endoftext|>


<commit_before>/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * 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.
 */

#include <signal.h>

#include <iostream>

#include <folly/Random.h>
#include <folly/String.h>
#include <folly/init/Init.h>
#include <folly/ssl/Init.h>

#include <thrift/lib/cpp2/server/ThriftServer.h>
#include <thrift/perf/cpp/AsyncLoadHandler2.h>

using std::cout;
using namespace apache::thrift;

DEFINE_int32(port, 1234, "server port");
DEFINE_int64(num_threads, 4, "number of worker threads");
DEFINE_int64(num_queue_threads, 4, "number of task queue threads");
DEFINE_int32(max_conn_pool_size, 0, "maximum size of idle connection pool");
DEFINE_int32(idle_timeout, 0, "idle timeout (in milliseconds)");
DEFINE_int32(task_timeout, 0, "task timeout (in milliseconds)");
DEFINE_int32(
    handshake_timeout,
    0,
    "SSL handshake timeout (in milliseconds). "
    "Default is 0, which is to not set a granular timeout for SSL handshakes. "
    "Connections that stall during handshakes may still be timed out "
    "with --idle_timeout");
DEFINE_int32(max_connections, 0, "DEPRECATED (REMOVE ME)");
DEFINE_int32(max_requests, 0, "max active requests");
DEFINE_string(cert, "", "server SSL certificate file");
DEFINE_string(key, "", "server SSL private key file");
DEFINE_string(client_ca_list, "", "file pointing to a client CA or list");
DEFINE_string(ticket_seeds, "", "server Ticket seeds file");
DEFINE_string(
    ecc_curve, "prime256v1", "The ECC curve to use for EC handshakes");
DEFINE_bool(enable_tfo, true, "Enable TFO");
DEFINE_int32(tfo_queue_size, 1000, "TFO queue size");

void setTunables(ThriftServer* server) {
  if (FLAGS_idle_timeout > 0) {
    server->setIdleTimeout(std::chrono::milliseconds(FLAGS_idle_timeout));
  }
  if (FLAGS_task_timeout > 0) {
    server->setTaskExpireTime(std::chrono::milliseconds(FLAGS_task_timeout));
  }
  if (FLAGS_handshake_timeout > 0) {
    server->setSSLHandshakeTimeout(
        std::chrono::milliseconds(FLAGS_handshake_timeout));
  }
}

ThriftServer* g_server = nullptr;

[[noreturn]] void sigHandler(int /* signo */) {
  g_server->stop();
  exit(0);
}

int main(int argc, char* argv[]) {
  folly::init(&argc, &argv);

  if (argc != 1) {
    fprintf(stderr, "error: unhandled arguments:");
    for (int n = 1; n < argc; ++n) {
      fprintf(stderr, " %s", argv[n]);
    }
    fprintf(stderr, "\n");
    return 1;
  }

  auto handler = std::make_shared<AsyncLoadHandler2>();

  std::shared_ptr<ThriftServer> server;
  server.reset(new ThriftServer());
  server->setInterface(handler);
  server->setPort(FLAGS_port);
  server->setNumIOWorkerThreads(FLAGS_num_threads);
  server->setNumCPUWorkerThreads(FLAGS_num_queue_threads);
  server->setMaxRequests(FLAGS_max_requests);
  server->setFastOpenOptions(FLAGS_enable_tfo, FLAGS_tfo_queue_size);

  if (FLAGS_cert.length() > 0 && FLAGS_key.length() > 0) {
    auto sslContext = std::make_shared<wangle::SSLContextConfig>();
    sslContext->setCertificate(FLAGS_cert, FLAGS_key, "");
    sslContext->clientCAFile = FLAGS_client_ca_list;
    sslContext->eccCurveName = FLAGS_ecc_curve;
    server->setSSLConfig(sslContext);
  }
  if (!FLAGS_ticket_seeds.empty()) {
    server->watchTicketPathForChanges(FLAGS_ticket_seeds);
  } else {
    // Generate random seeds to use for all workers.  If no seeds are set, then
    // each worker gets its own random seeds, so session resumptions fail across
    // workers.
    wangle::TLSTicketKeySeeds seeds;
    for (auto* seed : {&seeds.oldSeeds, &seeds.currentSeeds, &seeds.newSeeds}) {
      auto randomData = folly::Random::secureRandom<uint64_t>();
      auto asHex = folly::hexlify(folly::ByteRange(
          (const unsigned char*)&randomData, sizeof(uint64_t)));
      seed->push_back(std::move(asHex));
    }
    server->setTicketSeeds(std::move(seeds));
  }

  // Set tunable server parameters
  setTunables(server.get());

  g_server = server.get();
  signal(SIGINT, sigHandler);

  cout << "Serving requests on port " << FLAGS_port << "...\n";
  server->serve();

  cout << "Exiting normally" << std::endl;

  return 0;
}
<commit_msg>Support disabling active requests counter<commit_after>/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * 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.
 */

#include <signal.h>

#include <iostream>

#include <folly/Random.h>
#include <folly/String.h>
#include <folly/init/Init.h>
#include <folly/ssl/Init.h>

#include <thrift/lib/cpp2/server/ThriftServer.h>
#include <thrift/perf/cpp/AsyncLoadHandler2.h>

using std::cout;
using namespace apache::thrift;

DEFINE_int32(port, 1234, "server port");
DEFINE_int64(num_threads, 4, "number of worker threads");
DEFINE_int64(num_queue_threads, 4, "number of task queue threads");
DEFINE_int32(max_conn_pool_size, 0, "maximum size of idle connection pool");
DEFINE_int32(idle_timeout, 0, "idle timeout (in milliseconds)");
DEFINE_int32(task_timeout, 0, "task timeout (in milliseconds)");
DEFINE_int32(
    handshake_timeout,
    0,
    "SSL handshake timeout (in milliseconds). "
    "Default is 0, which is to not set a granular timeout for SSL handshakes. "
    "Connections that stall during handshakes may still be timed out "
    "with --idle_timeout");
DEFINE_int32(max_connections, 0, "DEPRECATED (REMOVE ME)");
DEFINE_int32(
    max_requests,
    0,
    "max active requests, ignored if disable_active_requests_tracking is true");
DEFINE_bool(
    disable_active_requests_tracking,
    false,
    "Disable active request tracking to improve performance");
DEFINE_string(cert, "", "server SSL certificate file");
DEFINE_string(key, "", "server SSL private key file");
DEFINE_string(client_ca_list, "", "file pointing to a client CA or list");
DEFINE_string(ticket_seeds, "", "server Ticket seeds file");
DEFINE_string(
    ecc_curve, "prime256v1", "The ECC curve to use for EC handshakes");
DEFINE_bool(enable_tfo, true, "Enable TFO");
DEFINE_int32(tfo_queue_size, 1000, "TFO queue size");

void setTunables(ThriftServer* server) {
  if (FLAGS_idle_timeout > 0) {
    server->setIdleTimeout(std::chrono::milliseconds(FLAGS_idle_timeout));
  }
  if (FLAGS_task_timeout > 0) {
    server->setTaskExpireTime(std::chrono::milliseconds(FLAGS_task_timeout));
  }
  if (FLAGS_handshake_timeout > 0) {
    server->setSSLHandshakeTimeout(
        std::chrono::milliseconds(FLAGS_handshake_timeout));
  }
  if (FLAGS_disable_active_requests_tracking) {
    server->disableActiveRequestsTracking();
  }
}

ThriftServer* g_server = nullptr;

[[noreturn]] void sigHandler(int /* signo */) {
  g_server->stop();
  exit(0);
}

int main(int argc, char* argv[]) {
  folly::init(&argc, &argv);

  if (argc != 1) {
    fprintf(stderr, "error: unhandled arguments:");
    for (int n = 1; n < argc; ++n) {
      fprintf(stderr, " %s", argv[n]);
    }
    fprintf(stderr, "\n");
    return 1;
  }

  auto handler = std::make_shared<AsyncLoadHandler2>();

  std::shared_ptr<ThriftServer> server;
  server.reset(new ThriftServer());
  server->setInterface(handler);
  server->setPort(FLAGS_port);
  server->setNumIOWorkerThreads(FLAGS_num_threads);
  server->setNumCPUWorkerThreads(FLAGS_num_queue_threads);
  server->setMaxRequests(FLAGS_max_requests);
  server->setFastOpenOptions(FLAGS_enable_tfo, FLAGS_tfo_queue_size);

  if (FLAGS_cert.length() > 0 && FLAGS_key.length() > 0) {
    auto sslContext = std::make_shared<wangle::SSLContextConfig>();
    sslContext->setCertificate(FLAGS_cert, FLAGS_key, "");
    sslContext->clientCAFile = FLAGS_client_ca_list;
    sslContext->eccCurveName = FLAGS_ecc_curve;
    server->setSSLConfig(sslContext);
  }
  if (!FLAGS_ticket_seeds.empty()) {
    server->watchTicketPathForChanges(FLAGS_ticket_seeds);
  } else {
    // Generate random seeds to use for all workers.  If no seeds are set, then
    // each worker gets its own random seeds, so session resumptions fail across
    // workers.
    wangle::TLSTicketKeySeeds seeds;
    for (auto* seed : {&seeds.oldSeeds, &seeds.currentSeeds, &seeds.newSeeds}) {
      auto randomData = folly::Random::secureRandom<uint64_t>();
      auto asHex = folly::hexlify(folly::ByteRange(
          (const unsigned char*)&randomData, sizeof(uint64_t)));
      seed->push_back(std::move(asHex));
    }
    server->setTicketSeeds(std::move(seeds));
  }

  // Set tunable server parameters
  setTunables(server.get());

  g_server = server.get();
  signal(SIGINT, sigHandler);

  cout << "Serving requests on port " << FLAGS_port << "...\n";
  server->serve();

  cout << "Exiting normally" << std::endl;

  return 0;
}
<|endoftext|>


<commit_before>/*
* Copyright (c) 2013-2016, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
* See full license text in LICENSE file at top of project tree
*/

#include "Log.h"

namespace i2p {
namespace log {
	static Log logger;
	/**
	 * @brief Maps our loglevel to their symbolic name
	 */
	static const char * g_LogLevelStr[eNumLogLevels] =
	{
		"error", // eLogError
		"warn",  // eLogWarn
		"info",  // eLogInfo
		"debug"	 // eLogDebug
	};

	/**
	 * @brief Colorize log output -- array of terminal control sequences
	 * @note Using ISO 6429 (ANSI) color sequences
	 */
#ifdef _WIN32
	static const char *LogMsgColors[] = { "", "", "", "", "" };
#else /* UNIX */
	static const char *LogMsgColors[] = {
		[eLogError]     = "\033[1;31m", /* red */
		[eLogWarning]   = "\033[1;33m", /* yellow */
		[eLogInfo]      = "\033[1;36m", /* cyan */
		[eLogDebug]     = "\033[1;34m", /* blue */
		[eNumLogLevels] = "\033[0m",    /* reset */
	};
#endif

#ifndef _WIN32
	/**
	 * @brief  Maps our log levels to syslog one
	 * @return syslog priority LOG_*, as defined in syslog.h
	 */
	static inline int GetSyslogPrio (enum LogLevel l) {
		int priority = LOG_DEBUG;
		switch (l) {
			case eLogError   : priority = LOG_ERR;     break;
			case eLogWarning : priority = LOG_WARNING; break;
			case eLogInfo    : priority = LOG_INFO;    break;
			case eLogDebug   : priority = LOG_DEBUG;   break;
			default          : priority = LOG_DEBUG;   break;
		}
		return priority;
	}
#endif

	Log::Log():
	m_Destination(eLogStdout), m_MinLevel(eLogInfo),
	m_LogStream (nullptr), m_Logfile(""), m_HasColors(true),
	m_IsRunning (false), m_Thread (nullptr)
	{
	}

	Log::~Log ()
	{
		delete m_Thread;
	}

	void Log::Start ()
	{
		if (!m_IsRunning)
		{
			m_IsRunning = true;
			m_Thread = new std::thread (std::bind (&Log::Run, this));
		}
	}

	void Log::Stop ()
	{
		switch (m_Destination)
		{
#ifndef _WIN32
			case eLogSyslog :
				closelog();
				break;
#endif
			case eLogFile:
			case eLogStream:
					if (m_LogStream) m_LogStream->flush();
				break;
			default:
				/* do nothing */
				break;
		}
		m_IsRunning = false;
		m_Queue.WakeUp ();
		if (m_Thread)
		{
			m_Thread->join ();
			delete m_Thread;
			m_Thread = nullptr;
		}
	}

	void Log::SetLogLevel (const std::string& level) {
		if      (level == "error") { m_MinLevel = eLogError; }
		else if (level == "warn")  { m_MinLevel = eLogWarning; }
		else if (level == "info")  { m_MinLevel = eLogInfo;  }
		else if (level == "debug") { m_MinLevel = eLogDebug; }
		else {
			LogPrint(eLogError, "Log: unknown loglevel: ", level);
			return;
		}
		LogPrint(eLogInfo, "Log: min messages level set to ", level);
	}

	const char * Log::TimeAsString(std::time_t t) {
		if (t != m_LastTimestamp) {
			strftime(m_LastDateTime, sizeof(m_LastDateTime), "%H:%M:%S", localtime(&t));
			m_LastTimestamp = t;
		}
		return m_LastDateTime;
	}

	/**
	 * @note This function better to be run in separate thread due to disk i/o.
	 * Unfortunately, with current startup process with late fork() this
	 * will give us nothing but pain. Maybe later. See in NetDb as example.
	 */
	void Log::Process(std::shared_ptr<LogMsg> msg)
	{
		if (!msg) return;
		std::hash<std::thread::id> hasher;
		unsigned short short_tid;
		short_tid = (short) (hasher(msg->tid) % 1000);
		switch (m_Destination) {
#ifndef _WIN32
			case eLogSyslog:
				syslog(GetSyslogPrio(msg->level), "[%03u] %s", short_tid, msg->text.c_str());
				break;
#endif
			case eLogFile:
			case eLogStream:
				if (m_LogStream)
					*m_LogStream << TimeAsString(msg->timestamp)
						<< "@" << short_tid
						<< "/" << g_LogLevelStr[msg->level]
						<< " - " << msg->text << std::endl;
				break;
			case eLogStdout:
			default:
				std::cout    << TimeAsString(msg->timestamp)
					<< "@" << short_tid
					<< "/" << LogMsgColors[msg->level] << g_LogLevelStr[msg->level] << LogMsgColors[eNumLogLevels]
					<< " - " << msg->text << std::endl;
				break;
		} // switch
	}

	void Log::Run ()
	{
		while (m_IsRunning)
		{
			std::shared_ptr<LogMsg> msg;
			while (msg = m_Queue.Get ())
				Process (msg);
			if (m_LogStream) m_LogStream->flush();
			if (m_IsRunning)
				m_Queue.Wait ();
		}
	}

	void Log::Append(std::shared_ptr<i2p::log::LogMsg> & msg)
	{
		m_Queue.Put(msg);
	}

	void Log::SendTo (const std::string& path)
	{
		if (m_LogStream) m_LogStream = nullptr; // close previous
		auto flags = std::ofstream::out | std::ofstream::app;
		auto os = std::make_shared<std::ofstream> (path, flags);
		if (os->is_open ())
		{
			m_HasColors = false;
			m_Logfile = path;
			m_Destination = eLogFile;
			m_LogStream = os;
			return;
		}
		LogPrint(eLogError, "Log: can't open file ", path);
	}

	void Log::SendTo (std::shared_ptr<std::ostream> os) {
		m_HasColors = false;
		m_Destination = eLogStream;
		m_LogStream = os;
	}

#ifndef _WIN32
	void Log::SendTo(const char *name, int facility) {
		m_HasColors = false;
		m_Destination = eLogSyslog;
		m_LogStream = nullptr;
		openlog(name, LOG_CONS | LOG_PID, facility);
	}
#endif

	void Log::Reopen() {
		if (m_Destination == eLogFile)
			SendTo(m_Logfile);
	}

	Log & Logger() {
		return logger;
	}
} // log
} // i2p
<commit_msg>reopen log upon daemon start<commit_after>/*
* Copyright (c) 2013-2016, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
* See full license text in LICENSE file at top of project tree
*/

#include "Log.h"

namespace i2p {
namespace log {
	static Log logger;
	/**
	 * @brief Maps our loglevel to their symbolic name
	 */
	static const char * g_LogLevelStr[eNumLogLevels] =
	{
		"error", // eLogError
		"warn",  // eLogWarn
		"info",  // eLogInfo
		"debug"	 // eLogDebug
	};

	/**
	 * @brief Colorize log output -- array of terminal control sequences
	 * @note Using ISO 6429 (ANSI) color sequences
	 */
#ifdef _WIN32
	static const char *LogMsgColors[] = { "", "", "", "", "" };
#else /* UNIX */
	static const char *LogMsgColors[] = {
		[eLogError]     = "\033[1;31m", /* red */
		[eLogWarning]   = "\033[1;33m", /* yellow */
		[eLogInfo]      = "\033[1;36m", /* cyan */
		[eLogDebug]     = "\033[1;34m", /* blue */
		[eNumLogLevels] = "\033[0m",    /* reset */
	};
#endif

#ifndef _WIN32
	/**
	 * @brief  Maps our log levels to syslog one
	 * @return syslog priority LOG_*, as defined in syslog.h
	 */
	static inline int GetSyslogPrio (enum LogLevel l) {
		int priority = LOG_DEBUG;
		switch (l) {
			case eLogError   : priority = LOG_ERR;     break;
			case eLogWarning : priority = LOG_WARNING; break;
			case eLogInfo    : priority = LOG_INFO;    break;
			case eLogDebug   : priority = LOG_DEBUG;   break;
			default          : priority = LOG_DEBUG;   break;
		}
		return priority;
	}
#endif

	Log::Log():
	m_Destination(eLogStdout), m_MinLevel(eLogInfo),
	m_LogStream (nullptr), m_Logfile(""), m_HasColors(true),
	m_IsRunning (false), m_Thread (nullptr)
	{
	}

	Log::~Log ()
	{
		delete m_Thread;
	}

	void Log::Start ()
	{
		if (!m_IsRunning)
		{
			Reopen ();
			m_IsRunning = true;
			m_Thread = new std::thread (std::bind (&Log::Run, this));
		}
	}

	void Log::Stop ()
	{
		switch (m_Destination)
		{
#ifndef _WIN32
			case eLogSyslog :
				closelog();
				break;
#endif
			case eLogFile:
			case eLogStream:
					if (m_LogStream) m_LogStream->flush();
				break;
			default:
				/* do nothing */
				break;
		}
		m_IsRunning = false;
		m_Queue.WakeUp ();
		if (m_Thread)
		{
			m_Thread->join ();
			delete m_Thread;
			m_Thread = nullptr;
		}
	}

	void Log::SetLogLevel (const std::string& level) {
		if      (level == "error") { m_MinLevel = eLogError; }
		else if (level == "warn")  { m_MinLevel = eLogWarning; }
		else if (level == "info")  { m_MinLevel = eLogInfo;  }
		else if (level == "debug") { m_MinLevel = eLogDebug; }
		else {
			LogPrint(eLogError, "Log: unknown loglevel: ", level);
			return;
		}
		LogPrint(eLogInfo, "Log: min messages level set to ", level);
	}

	const char * Log::TimeAsString(std::time_t t) {
		if (t != m_LastTimestamp) {
			strftime(m_LastDateTime, sizeof(m_LastDateTime), "%H:%M:%S", localtime(&t));
			m_LastTimestamp = t;
		}
		return m_LastDateTime;
	}

	/**
	 * @note This function better to be run in separate thread due to disk i/o.
	 * Unfortunately, with current startup process with late fork() this
	 * will give us nothing but pain. Maybe later. See in NetDb as example.
	 */
	void Log::Process(std::shared_ptr<LogMsg> msg)
	{
		if (!msg) return;
		std::hash<std::thread::id> hasher;
		unsigned short short_tid;
		short_tid = (short) (hasher(msg->tid) % 1000);
		switch (m_Destination) {
#ifndef _WIN32
			case eLogSyslog:
				syslog(GetSyslogPrio(msg->level), "[%03u] %s", short_tid, msg->text.c_str());
				break;
#endif
			case eLogFile:
			case eLogStream:
				if (m_LogStream)
					*m_LogStream << TimeAsString(msg->timestamp)
						<< "@" << short_tid
						<< "/" << g_LogLevelStr[msg->level]
						<< " - " << msg->text << std::endl;
				break;
			case eLogStdout:
			default:
				std::cout    << TimeAsString(msg->timestamp)
					<< "@" << short_tid
					<< "/" << LogMsgColors[msg->level] << g_LogLevelStr[msg->level] << LogMsgColors[eNumLogLevels]
					<< " - " << msg->text << std::endl;
				break;
		} // switch
	}

	void Log::Run ()
	{
		while (m_IsRunning)
		{
			std::shared_ptr<LogMsg> msg;
			while (msg = m_Queue.Get ())
				Process (msg);
			if (m_LogStream) m_LogStream->flush();
			if (m_IsRunning)
				m_Queue.Wait ();
		}
	}

	void Log::Append(std::shared_ptr<i2p::log::LogMsg> & msg)
	{
		m_Queue.Put(msg);
	}

	void Log::SendTo (const std::string& path)
	{
		if (m_LogStream) m_LogStream = nullptr; // close previous
		auto flags = std::ofstream::out | std::ofstream::app;
		auto os = std::make_shared<std::ofstream> (path, flags);
		if (os->is_open ())
		{
			m_HasColors = false;
			m_Logfile = path;
			m_Destination = eLogFile;
			m_LogStream = os;
			return;
		}
		LogPrint(eLogError, "Log: can't open file ", path);
	}

	void Log::SendTo (std::shared_ptr<std::ostream> os) {
		m_HasColors = false;
		m_Destination = eLogStream;
		m_LogStream = os;
	}

#ifndef _WIN32
	void Log::SendTo(const char *name, int facility) {
		m_HasColors = false;
		m_Destination = eLogSyslog;
		m_LogStream = nullptr;
		openlog(name, LOG_CONS | LOG_PID, facility);
	}
#endif

	void Log::Reopen() {
		if (m_Destination == eLogFile)
			SendTo(m_Logfile);
	}

	Log & Logger() {
		return logger;
	}
} // log
} // i2p
<|endoftext|>


<commit_before>#include <iostream>
#include <fstream>
#include <algorithm>
#include <cstdio>
#include <cstring>

using namespace std;

// Maximum number of numbers in files.
const int MAX_SIZE = 1024;
// Total quantity of numbers
int N;
// File counter for heap. Initially equals fileNumber and decreases when all number in a file used.
int fileCtr = 0;
// Number of files
int fileNumber;
// Heap for sorting numbers from main file part by part.
double *dmHeap;

/*
 * Struct to be used in main heap.
 * Moves like a cursor on a specific file.
 */
struct numbFiles{
	// Current number in its file.
	double x;
	// Remaining number in its file.
	int counter;
	// Index for its file in filesH[]
	int No;
};

// Ordering rule for the heap while merging
struct greater1{
	bool operator()(const numbFiles& a, numbFiles& b) const{
		return a.x > b.x;
	}
};

// Ordering rule for the heap while separating
struct greater2{
	bool operator()(const double& a, double& b) const{
		return a > b;
	}
};

double heap_pop(int& array_size){
	array_size--;
	double value = dmHeap[array_size];
	dmHeap[array_size] = 0;
	return value;
}

/*
 * Reads the numbers to dmHeap[] from the given file part by part.
 * Each file has MAX_SIZE numbers (last file has <= MAX_SIZE).
 * Writes the sorted version of the heap to a specific file.
 * File name is "/tmp/F_"+fileCtr+".txt".
 * For example, 3. part will be written in "F_3.txt".
 */
void readnSeparate(string fname){
	ifstream finn (fname);
	int i, j;
	dmHeap = new double[MAX_SIZE];

	finn >> N;

	while(!finn.eof()){
		fileCtr++;
		double x;

		for(i = 0 ; i < MAX_SIZE ; i++){
			finn >> x;
			if(finn.eof()){
				if(x != dmHeap[i-1]){
					dmHeap[i] = x;
					i++;
				}
				break;
			}
			dmHeap[i] = x;
		}

		make_heap(&dmHeap[0],&dmHeap[i],greater2());

		string fpath = "";
		fpath += "/tmp/F_";
		fpath += to_string(fileCtr);
		fpath += ".txt";
		ofstream fout(fpath);
		fout << fixed;
		fout.precision(6);
		while(i){
			pop_heap (&dmHeap[0],&dmHeap[i],greater2());
			double x = heap_pop(i);
			fout << x <<endl;
		}
	}

	delete[] dmHeap;
}

// Deletes the created files in /tmp directory.
void deleteFiles(){
	int i, j;
	for(i = 1 ; i <= fileNumber ; i++){
		string fpath = "";
		fpath += "/tmp/F_";
		fpath += to_string(i);
		fpath += ".txt";
		char f_name[fpath.length()];
		for(j = 0 ; j < fpath.length() ; j++)
			f_name[j] = fpath[j];
		const char* file_name = f_name;
		remove(file_name);
	}
}

int main(int argc, char *argv[]){
	int i, j;

	readnSeparate(argv[1]);

	fileNumber = fileCtr;

	numbFiles heapX[fileCtr];

	// Cursor for each file. Starts from index 1.
	// filesH[i] shows "/tmp/F_"+i+".txt".
	ifstream filesH[fileCtr+1];

	// Initialization of heapX[]
	for(i = 0 ; i < fileCtr ; i++){
		heapX[i].No = i+1;
		string fpath = "";
		fpath += "/tmp/F_";
		fpath += to_string(i+1);
		fpath += ".txt";
		filesH[i+1].open(fpath);
		filesH[i+1] >> heapX[i].x;
		heapX[i].counter = MAX_SIZE;
	}

	heapX[fileCtr-1].counter =  N - (fileCtr-1)*MAX_SIZE;

	make_heap(&heapX[0],&heapX[fileCtr],greater1());

	ofstream fout(argv[2]);
	fout << fixed;
	fout.precision(6);
	/*
	 * Like in our final exam question there are fileNumber files with MAX_SIZE number of double numbers in them.
	 * The code puts every file's first number into the heap.
	 * Then pop the min number and write it on the output file.
	 * If there is still numbers in the poped number's file, then the new number pushed into the heap.
	 * If there is no number remains in the poped number's file, then the heap's size decreases
	 * and this procedure continues until there is only one file remains.
	 * When one file remains, the code attach the remaining numbers on this file to the output file.
	 *
	 */
	for(i = 0 ; i < N ; i++){
		if(fileCtr == 1){
			fout << heapX[0].x <<endl;
			filesH[ heapX[0].No ] >> heapX[0].x;
		}
		else{
			pop_heap (&heapX[0],&heapX[fileCtr],greater1());
			fout << heapX[fileCtr-1].x<<endl;
			heapX[fileCtr-1].counter--;
			if(heapX[fileCtr-1].counter > 0){
				filesH[ heapX[fileCtr-1].No ] >> heapX[fileCtr-1].x;
				push_heap(&heapX[0],&heapX[fileCtr],greater1());
			}
			else
				fileCtr--;
		}
	}
	fileCtr--;

	deleteFiles();

	return (0-0);
}

<commit_msg>Delete Main.cc<commit_after><|endoftext|>


<commit_before>#ifndef __STOUT_MULTIHASHMAP_HPP__
#define __STOUT_MULTIHASHMAP_HPP__

#include <utility>

#include <boost/unordered_map.hpp>

#include "hashset.hpp"

// Implementation of a hash multimap via Boost's
// 'unordered_multimap'. The rationale for creating this is that the
// std::multimap implementation is painful to use (requires lots of
// iterator garbage, as well as the use of 'equal_range' which makes
// for cluttered code).
template <typename K, typename V>
class multihashmap : public boost::unordered_multimap<K, V>
{
public:
  void put(const K& key, const V& value);
  hashset<V> get(const K& key) const;
  bool remove(const K& key);
  bool remove(const K& key, const V& value);
  bool contains(const K& key) const;
  bool contains(const K& key, const V& value) const;
};

template <typename K, typename V>
void multihashmap<K, V>::put(const K& key, const V& value)
{
  insert(std::pair<K, V>(key, value));
}

template <typename K, typename V>
hashset<V> multihashmap<K, V>::get(const K& key) const
{
  hashset<V> values; // Values to return.

  std::pair<typename boost::unordered_multimap<K, V>::const_iterator,
    typename boost::unordered_multimap<K, V>::const_iterator> range;

  range = equal_range(key);

  typename boost::unordered_multimap<K, V>::const_iterator i;
  for (i = range.first; i != range.second; ++i) {
    values.insert((*i).second);
  }

  return values;
}

template <typename K, typename V>
bool multihashmap<K, V>::remove(const K& key)
{
  return erase(key) > 0;
}

template <typename K, typename V>
bool multihashmap<K, V>::remove(const K& key, const V& value)
{
  typename boost::unordered_multimap<K, V>::iterator i;
  for (i = find(key); i != boost::unordered_multimap<K, V>::end(); ++i) {
    if ((*i).second == value) {
      erase(i);
      return true;
    }
  }

  return false;
}

template <typename K, typename V>
bool multihashmap<K, V>::contains(const K& key) const
{
  return count(key) > 0;
}

template <typename K, typename V>
bool multihashmap<K, V>::contains(const K& key, const V& value) const
{
  typename boost::unordered_multimap<K, V>::const_iterator i;
  for (i = find(key); i != boost::unordered_multimap<K, V>::end(); ++i) {
    if ((*i).second == value) {
      return true;
    }
  }

  return false;
}

#endif // __STOUT_MULTIHASHMAP_HPP__
<commit_msg>Updated multihashmap to compile with GCC 4.7<commit_after>#ifndef __STOUT_MULTIHASHMAP_HPP__
#define __STOUT_MULTIHASHMAP_HPP__

#include <utility>

#include <boost/unordered_map.hpp>

#include "hashset.hpp"

// Implementation of a hash multimap via Boost's
// 'unordered_multimap'. The rationale for creating this is that the
// std::multimap implementation is painful to use (requires lots of
// iterator garbage, as well as the use of 'equal_range' which makes
// for cluttered code).
template <typename K, typename V>
class multihashmap : public boost::unordered_multimap<K, V>
{
public:
  void put(const K& key, const V& value);
  hashset<V> get(const K& key) const;
  bool remove(const K& key);
  bool remove(const K& key, const V& value);
  bool contains(const K& key) const;
  bool contains(const K& key, const V& value) const;
};

template <typename K, typename V>
void multihashmap<K, V>::put(const K& key, const V& value)
{
  boost::unordered_multimap<K, V>::insert(std::pair<K, V>(key, value));
}

template <typename K, typename V>
hashset<V> multihashmap<K, V>::get(const K& key) const
{
  hashset<V> values; // Values to return.

  std::pair<typename boost::unordered_multimap<K, V>::const_iterator,
    typename boost::unordered_multimap<K, V>::const_iterator> range;

  range = boost::unordered_multimap<K, V>::equal_range(key);

  typename boost::unordered_multimap<K, V>::const_iterator i;
  for (i = range.first; i != range.second; ++i) {
    values.insert((*i).second);
  }

  return values;
}

template <typename K, typename V>
bool multihashmap<K, V>::remove(const K& key)
{
  return boost::unordered_multimap<K, V>::erase(key) > 0;
}

template <typename K, typename V>
bool multihashmap<K, V>::remove(const K& key, const V& value)
{
  typename boost::unordered_multimap<K, V>::iterator i;
  for (i = boost::unordered_multimap<K, V>::find(key);
       i != boost::unordered_multimap<K, V>::end();
       ++i) {
    if ((*i).second == value) {
      boost::unordered_multimap<K, V>::erase(i);
      return true;
    }
  }

  return false;
}

template <typename K, typename V>
bool multihashmap<K, V>::contains(const K& key) const
{
  return count(key) > 0;
}

template <typename K, typename V>
bool multihashmap<K, V>::contains(const K& key, const V& value) const
{
  typename boost::unordered_multimap<K, V>::const_iterator i;
  for (i = boost::unordered_multimap<K, V>::find(key);
       i != boost::unordered_multimap<K, V>::end();
       ++i) {
    if ((*i).second == value) {
      return true;
    }
  }

  return false;
}

#endif // __STOUT_MULTIHASHMAP_HPP__
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: b2ituple.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-07 20:36:32 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _BGFX_TUPLE_B2ITUPLE_HXX
#define _BGFX_TUPLE_B2ITUPLE_HXX

#ifndef _SAL_TYPES_H_
#include <sal/types.h>
#endif

namespace basegfx
{
    /** Base class for all Points/Vectors with two sal_Int32 values

        This class provides all methods common to Point
        avd Vector classes which are derived from here.

        @derive Use this class to implement Points or Vectors
        which are based on two sal_Int32 values
    */
    class B2ITuple
    {
    protected:
        sal_Int32                                       mnX;
        sal_Int32                                       mnY;

    public:
        /** Create a 2D Tuple

            The tuple is initialized to (0, 0)
        */
        B2ITuple()
        :   mnX(0),
            mnY(0)
        {}

        /** Create a 2D Tuple

            @param fX
            This parameter is used to initialize the X-coordinate
            of the 2D Tuple.

            @param fY
            This parameter is used to initialize the Y-coordinate
            of the 2D Tuple.
        */
        B2ITuple(sal_Int32 fX, sal_Int32 fY)
        :   mnX( fX ),
            mnY( fY )
        {}

        /** Create a copy of a 2D Tuple

            @param rTup
            The 2D Tuple which will be copied.
        */
        B2ITuple(const B2ITuple& rTup)
        :   mnX( rTup.mnX ),
            mnY( rTup.mnY )
        {}

        ~B2ITuple()
        {}

        /// Get X-Coordinate of 2D Tuple
        sal_Int32 getX() const
        {
            return mnX;
        }

        /// Get Y-Coordinate of 2D Tuple
        sal_Int32 getY() const
        {
            return mnY;
        }

        /// Set X-Coordinate of 2D Tuple
        void setX(sal_Int32 fX)
        {
            mnX = fX;
        }

        /// Set Y-Coordinate of 2D Tuple
        void setY(sal_Int32 fY)
        {
            mnY = fY;
        }

        /// Array-access to 2D Tuple
        const sal_Int32& operator[] (int nPos) const
        {
            // Here, normally one if(...) should be used. In the assumption that
            // both sal_Int32 members can be accessed as an array a shortcut is used here.
            // if(0 == nPos) return mnX; return mnY;
            return *((&mnX) + nPos);
        }

        /// Array-access to 2D Tuple
        sal_Int32& operator[] (int nPos)
        {
            // Here, normally one if(...) should be used. In the assumption that
            // both sal_Int32 members can be accessed as an array a shortcut is used here.
            // if(0 == nPos) return mnX; return mnY;
            return *((&mnX) + nPos);
        }

        // operators
        //////////////////////////////////////////////////////////////////////

        B2ITuple& operator+=( const B2ITuple& rTup )
        {
            mnX += rTup.mnX;
            mnY += rTup.mnY;
            return *this;
        }

        B2ITuple& operator-=( const B2ITuple& rTup )
        {
            mnX -= rTup.mnX;
            mnY -= rTup.mnY;
            return *this;
        }

        B2ITuple& operator/=( const B2ITuple& rTup )
        {
            mnX /= rTup.mnX;
            mnY /= rTup.mnY;
            return *this;
        }

        B2ITuple& operator*=( const B2ITuple& rTup )
        {
            mnX *= rTup.mnX;
            mnY *= rTup.mnY;
            return *this;
        }

        B2ITuple& operator*=(sal_Int32 t)
        {
            mnX *= t;
            mnY *= t;
            return *this;
        }

        B2ITuple& operator/=(sal_Int32 t)
        {
            mnX /= t;
            mnY /= t;
            return *this;
        }

        B2ITuple operator-(void) const
        {
            return B2ITuple(-mnX, -mnY);
        }

        bool equalZero() const { return mnX == 0 && mnY == 0; }

        bool operator==( const B2ITuple& rTup ) const
        {
            return rTup.mnX == mnX && rTup.mnY == mnY;
        }

        bool operator!=( const B2ITuple& rTup ) const
        {
            return !(*this == rTup);
        }

        B2ITuple& operator=( const B2ITuple& rTup )
        {
            mnX = rTup.mnX;
            mnY = rTup.mnY;
            return *this;
        }

        static const B2ITuple& getEmptyTuple();
    };

    // external operators
    //////////////////////////////////////////////////////////////////////////

    class B2DTuple;

    B2ITuple minimum(const B2ITuple& rTupA, const B2ITuple& rTupB);

    B2ITuple maximum(const B2ITuple& rTupA, const B2ITuple& rTupB);

    B2ITuple absolute(const B2ITuple& rTup);

    B2DTuple interpolate(const B2ITuple& rOld1, const B2ITuple& rOld2, double t);

    B2DTuple average(const B2ITuple& rOld1, const B2ITuple& rOld2);

    B2DTuple average(const B2ITuple& rOld1, const B2ITuple& rOld2, const B2ITuple& rOld3);

    B2ITuple operator+(const B2ITuple& rTupA, const B2ITuple& rTupB);

    B2ITuple operator-(const B2ITuple& rTupA, const B2ITuple& rTupB);

    B2ITuple operator/(const B2ITuple& rTupA, const B2ITuple& rTupB);

    B2ITuple operator*(const B2ITuple& rTupA, const B2ITuple& rTupB);

    B2ITuple operator*(const B2ITuple& rTup, sal_Int32 t);

    B2ITuple operator*(sal_Int32 t, const B2ITuple& rTup);

    B2ITuple operator/(const B2ITuple& rTup, sal_Int32 t);

    B2ITuple operator/(sal_Int32 t, const B2ITuple& rTup);

} // end of namespace basegfx

#endif /* _BGFX_TUPLE_B2ITUPLE_HXX */
<commit_msg>INTEGRATION: CWS changefileheader (1.5.88); FILE MERGED 2008/04/01 15:01:11 thb 1.5.88.2: #i85898# Stripping all external header guards 2008/03/28 16:05:46 rt 1.5.88.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: b2ituple.hxx,v $
 * $Revision: 1.6 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef _BGFX_TUPLE_B2ITUPLE_HXX
#define _BGFX_TUPLE_B2ITUPLE_HXX

#include <sal/types.h>

namespace basegfx
{
    /** Base class for all Points/Vectors with two sal_Int32 values

        This class provides all methods common to Point
        avd Vector classes which are derived from here.

        @derive Use this class to implement Points or Vectors
        which are based on two sal_Int32 values
    */
    class B2ITuple
    {
    protected:
        sal_Int32                                       mnX;
        sal_Int32                                       mnY;

    public:
        /** Create a 2D Tuple

            The tuple is initialized to (0, 0)
        */
        B2ITuple()
        :   mnX(0),
            mnY(0)
        {}

        /** Create a 2D Tuple

            @param fX
            This parameter is used to initialize the X-coordinate
            of the 2D Tuple.

            @param fY
            This parameter is used to initialize the Y-coordinate
            of the 2D Tuple.
        */
        B2ITuple(sal_Int32 fX, sal_Int32 fY)
        :   mnX( fX ),
            mnY( fY )
        {}

        /** Create a copy of a 2D Tuple

            @param rTup
            The 2D Tuple which will be copied.
        */
        B2ITuple(const B2ITuple& rTup)
        :   mnX( rTup.mnX ),
            mnY( rTup.mnY )
        {}

        ~B2ITuple()
        {}

        /// Get X-Coordinate of 2D Tuple
        sal_Int32 getX() const
        {
            return mnX;
        }

        /// Get Y-Coordinate of 2D Tuple
        sal_Int32 getY() const
        {
            return mnY;
        }

        /// Set X-Coordinate of 2D Tuple
        void setX(sal_Int32 fX)
        {
            mnX = fX;
        }

        /// Set Y-Coordinate of 2D Tuple
        void setY(sal_Int32 fY)
        {
            mnY = fY;
        }

        /// Array-access to 2D Tuple
        const sal_Int32& operator[] (int nPos) const
        {
            // Here, normally one if(...) should be used. In the assumption that
            // both sal_Int32 members can be accessed as an array a shortcut is used here.
            // if(0 == nPos) return mnX; return mnY;
            return *((&mnX) + nPos);
        }

        /// Array-access to 2D Tuple
        sal_Int32& operator[] (int nPos)
        {
            // Here, normally one if(...) should be used. In the assumption that
            // both sal_Int32 members can be accessed as an array a shortcut is used here.
            // if(0 == nPos) return mnX; return mnY;
            return *((&mnX) + nPos);
        }

        // operators
        //////////////////////////////////////////////////////////////////////

        B2ITuple& operator+=( const B2ITuple& rTup )
        {
            mnX += rTup.mnX;
            mnY += rTup.mnY;
            return *this;
        }

        B2ITuple& operator-=( const B2ITuple& rTup )
        {
            mnX -= rTup.mnX;
            mnY -= rTup.mnY;
            return *this;
        }

        B2ITuple& operator/=( const B2ITuple& rTup )
        {
            mnX /= rTup.mnX;
            mnY /= rTup.mnY;
            return *this;
        }

        B2ITuple& operator*=( const B2ITuple& rTup )
        {
            mnX *= rTup.mnX;
            mnY *= rTup.mnY;
            return *this;
        }

        B2ITuple& operator*=(sal_Int32 t)
        {
            mnX *= t;
            mnY *= t;
            return *this;
        }

        B2ITuple& operator/=(sal_Int32 t)
        {
            mnX /= t;
            mnY /= t;
            return *this;
        }

        B2ITuple operator-(void) const
        {
            return B2ITuple(-mnX, -mnY);
        }

        bool equalZero() const { return mnX == 0 && mnY == 0; }

        bool operator==( const B2ITuple& rTup ) const
        {
            return rTup.mnX == mnX && rTup.mnY == mnY;
        }

        bool operator!=( const B2ITuple& rTup ) const
        {
            return !(*this == rTup);
        }

        B2ITuple& operator=( const B2ITuple& rTup )
        {
            mnX = rTup.mnX;
            mnY = rTup.mnY;
            return *this;
        }

        static const B2ITuple& getEmptyTuple();
    };

    // external operators
    //////////////////////////////////////////////////////////////////////////

    class B2DTuple;

    B2ITuple minimum(const B2ITuple& rTupA, const B2ITuple& rTupB);

    B2ITuple maximum(const B2ITuple& rTupA, const B2ITuple& rTupB);

    B2ITuple absolute(const B2ITuple& rTup);

    B2DTuple interpolate(const B2ITuple& rOld1, const B2ITuple& rOld2, double t);

    B2DTuple average(const B2ITuple& rOld1, const B2ITuple& rOld2);

    B2DTuple average(const B2ITuple& rOld1, const B2ITuple& rOld2, const B2ITuple& rOld3);

    B2ITuple operator+(const B2ITuple& rTupA, const B2ITuple& rTupB);

    B2ITuple operator-(const B2ITuple& rTupA, const B2ITuple& rTupB);

    B2ITuple operator/(const B2ITuple& rTupA, const B2ITuple& rTupB);

    B2ITuple operator*(const B2ITuple& rTupA, const B2ITuple& rTupB);

    B2ITuple operator*(const B2ITuple& rTup, sal_Int32 t);

    B2ITuple operator*(sal_Int32 t, const B2ITuple& rTup);

    B2ITuple operator/(const B2ITuple& rTup, sal_Int32 t);

    B2ITuple operator/(sal_Int32 t, const B2ITuple& rTup);

} // end of namespace basegfx

#endif /* _BGFX_TUPLE_B2ITUPLE_HXX */
<|endoftext|>


<commit_before>
#include <iostream>
#include <iomanip>
#include <cmath>
#include <string>
#include <exception>

#include <botan/filters.h>
using Botan::byte;
using Botan::u64bit;

#include "common.h"
#include "timer.h"
#include "bench.h"

/* Discard output to reduce overhead */
struct BitBucket : public Botan::Filter
   {
   void write(const byte[], u32bit) {}
   };

Botan::Filter* lookup(const std::string&,
                      const std::vector<std::string>&,
                      const std::string& = "All");

namespace {

double bench_filter(std::string name, Botan::Filter* filter,
                    Botan::RandomNumberGenerator& rng,
                    bool html, double seconds)
   {
   Botan::Pipe pipe(filter, new BitBucket);

   pipe.start_msg();

   byte buf[32 * 1024];
   Timer timer(name, sizeof(buf));

   rng.randomize(buf, sizeof(buf));

   while(timer.seconds() < seconds)
      {
      timer.start();
      pipe.write(buf, sizeof(buf));
      timer.stop();
      }

   pipe.end_msg();

   double bytes_per_sec = timer.events() / timer.seconds();
   double mbytes_per_sec = bytes_per_sec / (1024.0 * 1024.0);

   std::cout.setf(std::ios::fixed, std::ios::floatfield);
   std::cout.precision(2);
   if(html)
      {
      if(name.find("<") != std::string::npos)
         name.replace(name.find("<"), 1, "<");
      if(name.find(">") != std::string::npos)
         name.replace(name.find(">"), 1, ">");
      std::cout << "
" << name
                << std::string(25 - name.length(), ' ') << "   ";
      std::cout.width(6);
      std::cout << mbytes_per_sec << std::endl;
      }
   else
      {
      std::cout << name << ": " << std::string(25 - name.length(), ' ');
      std::cout.width(6);
      std::cout << mbytes_per_sec << " Mbytes/sec" << std::endl;
      }
   return (mbytes_per_sec);
   }

double bench(const std::string& name, const std::string& filtername, bool html,
             double seconds, u32bit keylen, u32bit ivlen,
             Botan::RandomNumberGenerator& rng)
   {
   std::vector<std::string> params;

   Botan::SecureVector<byte> key(keylen);
   rng.randomize(key, key.size());
   params.push_back(hex_encode(key, key.size()));

   //params.push_back(std::string(int(2*keylen), 'A'));
   params.push_back(std::string(int(2* ivlen), 'A'));

   Botan::Filter* filter = lookup(filtername, params);

   if(filter)
      return bench_filter(name, filter, rng, html, seconds);
   return 0;
   }

}

void benchmark(const std::string& what,
               Botan::RandomNumberGenerator& rng,
               bool html, double seconds)
   {
   try {
      if(html)
         {
         std::cout << "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD "
                   << "HTML 4.0 Transitional//EN\">\n"
                   << "\n\n"
                   << "<TITLE>Botan Benchmarks</TITLE>\n\n"
                   << "\n\n"
                   << "

\n"
                   << "
\n"
                   << "
Algorithm                      "
                   << "Mbytes / second\n"
                   << "
\n";
         }

      double sum = 0;
      u32bit how_many = 0;

      std::vector<algorithm> algos = get_algos();

      for(u32bit j = 0; j != algos.size(); j++)
         if(what == "All" || what == algos[j].type)
            {
            double speed = bench(algos[j].name, algos[j].filtername,
                                 html, seconds, algos[j].keylen,
                                 algos[j].ivlen, rng);
            if(speed > .00001) /* log(0) == -inf -> messed up average */
               sum += std::log(speed);
            how_many++;
            }

      if(html)
         std::cout << "
\n\n";

      double average = std::exp(sum / static_cast<double>(how_many));

      if(what == "All" && html)
         std::cout << "\n
Overall speed average: " << average
                   << "\n\n";
      else if(what == "All")
          std::cout << "\nOverall speed average: " << average
                    << std::endl;

      if(html) std::cout << "\n";
      }
   catch(Botan::Exception& e)
      {
      std::cout << "Botan exception caught: " << e.what() << std::endl;
      return;
      }
   catch(std::exception& e)
      {
      std::cout << "Standard library exception caught: " << e.what()
                << std::endl;
      return;
      }
   catch(...)
      {
      std::cout << "Unknown exception caught." << std::endl;
      return;
      }
   }

u32bit bench_algo(const std::string& name,
                  Botan::RandomNumberGenerator& rng,
                  double seconds)
   {
   try {
      std::vector<algorithm> algos = get_algos();

      for(u32bit j = 0; j != algos.size(); j++)
         {
         if(algos[j].name == name)
            {
            bench(algos[j].name, algos[j].filtername, false, seconds,
                  algos[j].keylen, algos[j].ivlen, rng);
            return 1;
            }
         }
      return 0;
      }
   catch(Botan::Exception& e)
      {
      std::cout << "Botan exception caught: " << e.what() << std::endl;
      return 0;
      }
   catch(std::exception& e)
      {
      std::cout << "Standard library exception caught: " << e.what()
                << std::endl;
      return 0;
      }
   catch(...)
      {
      std::cout << "Unknown exception caught." << std::endl;
      return 0;
      }
   }
<commit_msg>s/Mbyte/MiB/ to be precise about meaning (2^20 bytes/second)<commit_after>
#include <iostream>
#include <iomanip>
#include <cmath>
#include <string>
#include <exception>

#include <botan/filters.h>
using Botan::byte;
using Botan::u64bit;

#include "common.h"
#include "timer.h"
#include "bench.h"

/* Discard output to reduce overhead */
struct BitBucket : public Botan::Filter
   {
   void write(const byte[], u32bit) {}
   };

Botan::Filter* lookup(const std::string&,
                      const std::vector<std::string>&,
                      const std::string& = "All");

namespace {

double bench_filter(std::string name, Botan::Filter* filter,
                    Botan::RandomNumberGenerator& rng,
                    bool html, double seconds)
   {
   Botan::Pipe pipe(filter, new BitBucket);

   pipe.start_msg();

   byte buf[32 * 1024];
   Timer timer(name, sizeof(buf));

   rng.randomize(buf, sizeof(buf));

   while(timer.seconds() < seconds)
      {
      timer.start();
      pipe.write(buf, sizeof(buf));
      timer.stop();
      }

   pipe.end_msg();

   double bytes_per_sec = timer.events() / timer.seconds();
   double mbytes_per_sec = bytes_per_sec / (1024.0 * 1024.0);

   std::cout.setf(std::ios::fixed, std::ios::floatfield);
   std::cout.precision(2);
   if(html)
      {
      if(name.find("<") != std::string::npos)
         name.replace(name.find("<"), 1, "<");
      if(name.find(">") != std::string::npos)
         name.replace(name.find(">"), 1, ">");
      std::cout << "
" << name
                << std::string(25 - name.length(), ' ') << "   ";
      std::cout.width(6);
      std::cout << mbytes_per_sec << std::endl;
      }
   else
      {
      std::cout << name << ": " << std::string(25 - name.length(), ' ');
      std::cout.width(6);
      std::cout << mbytes_per_sec << " MiB/sec" << std::endl;
      }
   return (mbytes_per_sec);
   }

double bench(const std::string& name, const std::string& filtername, bool html,
             double seconds, u32bit keylen, u32bit ivlen,
             Botan::RandomNumberGenerator& rng)
   {
   std::vector<std::string> params;

   Botan::SecureVector<byte> key(keylen);
   rng.randomize(key, key.size());
   params.push_back(hex_encode(key, key.size()));

   //params.push_back(std::string(int(2*keylen), 'A'));
   params.push_back(std::string(int(2* ivlen), 'A'));

   Botan::Filter* filter = lookup(filtername, params);

   if(filter)
      return bench_filter(name, filter, rng, html, seconds);
   return 0;
   }

}

void benchmark(const std::string& what,
               Botan::RandomNumberGenerator& rng,
               bool html, double seconds)
   {
   try {
      if(html)
         {
         std::cout << "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD "
                   << "HTML 4.0 Transitional//EN\">\n"
                   << "\n\n"
                   << "<TITLE>Botan Benchmarks</TITLE>\n\n"
                   << "\n\n"
                   << "

\n"
                   << "
\n"
                   << "
Algorithm                      "
                   << "Mib / second\n"
                   << "
\n";
         }

      double sum = 0;
      u32bit how_many = 0;

      std::vector<algorithm> algos = get_algos();

      for(u32bit j = 0; j != algos.size(); j++)
         if(what == "All" || what == algos[j].type)
            {
            double speed = bench(algos[j].name, algos[j].filtername,
                                 html, seconds, algos[j].keylen,
                                 algos[j].ivlen, rng);
            if(speed > .00001) /* log(0) == -inf -> messed up average */
               sum += std::log(speed);
            how_many++;
            }

      if(html)
         std::cout << "
\n\n";

      double average = std::exp(sum / static_cast<double>(how_many));

      if(what == "All" && html)
         std::cout << "\n
Overall speed average: " << average
                   << "\n\n";
      else if(what == "All")
          std::cout << "\nOverall speed average: " << average
                    << std::endl;

      if(html) std::cout << "\n";
      }
   catch(Botan::Exception& e)
      {
      std::cout << "Botan exception caught: " << e.what() << std::endl;
      return;
      }
   catch(std::exception& e)
      {
      std::cout << "Standard library exception caught: " << e.what()
                << std::endl;
      return;
      }
   catch(...)
      {
      std::cout << "Unknown exception caught." << std::endl;
      return;
      }
   }

u32bit bench_algo(const std::string& name,
                  Botan::RandomNumberGenerator& rng,
                  double seconds)
   {
   try {
      std::vector<algorithm> algos = get_algos();

      for(u32bit j = 0; j != algos.size(); j++)
         {
         if(algos[j].name == name)
            {
            bench(algos[j].name, algos[j].filtername, false, seconds,
                  algos[j].keylen, algos[j].ivlen, rng);
            return 1;
            }
         }
      return 0;
      }
   catch(Botan::Exception& e)
      {
      std::cout << "Botan exception caught: " << e.what() << std::endl;
      return 0;
      }
   catch(std::exception& e)
      {
      std::cout << "Standard library exception caught: " << e.what()
                << std::endl;
      return 0;
      }
   catch(...)
      {
      std::cout << "Unknown exception caught." << std::endl;
      return 0;
      }
   }
<|endoftext|>