<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: regmerge.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 05:19:02 $
 *
 *  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
 *
 ************************************************************************/

#include <stdio.h>
#include <string.h>

#include "registry/registry.h"

#ifndef _RTL_USTRING_HXX_
#include    <rtl/ustring.hxx>
#endif

#ifndef _RTL_ALLOC_H_
#include    <rtl/alloc.h>
#endif

#ifndef _OSL_PROCESS_H_
#include <osl/process.h>
#endif
#ifndef _OSL_DIAGNOSE_H_
#include <osl/diagnose.h>
#endif
#ifndef _OSL_THREAD_H_
#include <osl/thread.h>
#endif
#ifndef _OSL_FILE_HXX_
#include <osl/file.hxx>
#endif

#ifdef SAL_UNX
#define SEPARATOR '/'
#else
#define SEPARATOR '\\'
#endif

using namespace ::rtl;
using namespace ::osl;

sal_Bool isFileUrl(const OString& fileName)
{
    if (fileName.indexOf("file://") == 0 )
        return sal_True;
    return sal_False;
}

OUString convertToFileUrl(const OString& fileName)
{
    if ( isFileUrl(fileName) )
    {
        return OStringToOUString(fileName, osl_getThreadTextEncoding());
    }

    OUString uUrlFileName;
    OUString uFileName(fileName.getStr(), fileName.getLength(), osl_getThreadTextEncoding());
    if ( fileName.indexOf('.') == 0 || fileName.indexOf(SEPARATOR) < 0 )
    {
        OUString uWorkingDir;
        OSL_VERIFY( osl_getProcessWorkingDir(&uWorkingDir.pData) == osl_Process_E_None );
        OSL_VERIFY( FileBase::getAbsoluteFileURL(uWorkingDir, uFileName, uUrlFileName) == FileBase::E_None );
    } else
    {
        OSL_VERIFY( FileBase::getFileURLFromSystemPath(uFileName, uUrlFileName) == FileBase::E_None );
    }

    return uUrlFileName;
}

int realargc;
char* realargv[2048];

static void dumpHelp()
{
    fprintf(stderr, "using: regmerge [-v|--verbose] mergefile mergeKeyName regfile_1 ... regfile_n\n");
    fprintf(stderr, "       regmerge @regcmds\nOptions:\n");
    fprintf(stderr, "  -v, --verbose : verbose output on stdout.\n");
    fprintf(stderr, "  mergefile     : specifies the merged registry file. If this file doesn't exists,\n");
    fprintf(stderr, "                  it is created.\n");
    fprintf(stderr, "  mergeKeyName  : specifies the merge key, everything is merged under this key.\n");
    fprintf(stderr, "                  If this key doesn't exists, it is created.\n");
    fprintf(stderr, "  regfile_1..n  : specifies one or more registry files which are merged.\n");
}

static bool checkCommandFile(char* cmdfile)
{
    FILE    *commandfile;
    char    option[256];
    bool    bVerbose = false;

    commandfile = fopen(cmdfile+1, "r");
    if( commandfile == NULL )
    {
        fprintf(stderr, "ERROR: Can't open command file \"%s\"\n", cmdfile);
    } else
    {
        while ( fscanf(commandfile, "%s", option) != EOF )
        {
            if (option[0]== '@')
            {
                bool bRet = checkCommandFile(option);
                // ensure that the option will not be overwritten
                if ( !bRet )
                    bVerbose = bRet;
            } else {
                if (option[0]== '-') {
                    if (strncmp(option, "-v", 2)  == 0 ||
                        strncmp(option, "--verbose", 9) == 0)
                    {
                        bVerbose = true;
                    } else {
                        fprintf(stderr, "ERROR: unknown option \"%s\"\n", option);
                        dumpHelp();
                        exit(-1);
                    }
                }else
                {
                    realargv[realargc]= strdup(option);
                    realargc++;
                }
            }
            if (realargc == 2047)
            {
                fprintf(stderr, "ERROR: more than 2048 arguments.\n");
                break;
            }
        }
        fclose(commandfile);
    }

    return bVerbose;
}

static bool checkCommandArgs(int argc, char **argv)
{
    bool bVerbose = false;

    realargc = 0;

    for (int i=0; i<argc; i++)
    {
        if (argv[i][0]== '@')
        {
            bool bRet = checkCommandFile(argv[i]);
            // ensure that the option will not be overwritten
            if ( !bRet )
                bVerbose = bRet;
        } else {
            if (argv[i][0]== '-') {
                if (strncmp(argv[i], "-v", 2)  == 0 ||
                    strncmp(argv[i], "--verbose", 9) == 0)
                {
                    bVerbose = true;
                } else {
                    fprintf(stderr, "ERROR: unknown option \"%s\"\n", argv[i]);
                    dumpHelp();
                    exit(-1);
                }
            } else
            {
                realargv[realargc]= strdup(argv[i]);
                realargc++;
            }
        }
    }

    return bVerbose;
}

static void cleanCommandArgs()
{
    for (int i=0; i<realargc; i++)
    {
        free(realargv[i]);
    }
}

#if (defined UNX) || (defined OS2)
int main( int argc, char * argv[] )
#else
int _cdecl main( int argc, char * argv[] )
#endif
{
    RegHandle       hReg;
    RegKeyHandle    hRootKey;
    bool            bVerbose = checkCommandArgs(argc, argv);

    if (realargc < 4)
    {
        dumpHelp();
        cleanCommandArgs();
        exit(1);
    }

    ::rtl::OUString regName( convertToFileUrl(realargv[1]) );
    if (reg_openRegistry(regName.pData, &hReg, REG_READWRITE))
    {
        if (reg_createRegistry(regName.pData, &hReg))
        {
            if (bVerbose)
                fprintf(stderr, "open registry \"%s\" failed\n", realargv[1]);
            cleanCommandArgs();
            exit(-1);
        }
    }

    if (!reg_openRootKey(hReg, &hRootKey))
    {
        ::rtl::OUString mergeKeyName( ::rtl::OUString::createFromAscii(realargv[2]) );
        ::rtl::OUString targetRegName;
        RegError _ret = REG_NO_ERROR;
        for (int i = 3; i < realargc; i++)
        {
            targetRegName = convertToFileUrl(realargv[i]);
            if (_ret = reg_mergeKey(hRootKey, mergeKeyName.pData, targetRegName.pData, sal_False, bVerbose))
            {
                if (_ret == REG_MERGE_CONFLICT)
                {
                    if (bVerbose)
                        fprintf(stderr, "merging registry \"%s\" under key \"%s\" in registry \"%s\".\n",
                                realargv[i], realargv[2], realargv[1]);
                } else
                {
                    if (bVerbose)
                        fprintf(stderr, "ERROR: merging registry \"%s\" under key \"%s\" in registry \"%s\" failed.\n",
                                realargv[i], realargv[2], realargv[1]);
                    exit(-2);
                }
            } else
            {
                if (bVerbose)
                    fprintf(stderr, "merging registry \"%s\" under key \"%s\" in registry \"%s\".\n",
                            realargv[i], realargv[2], realargv[1]);
            }
        }

        if (reg_closeKey(hRootKey))
        {
            if (bVerbose)
                fprintf(stderr, "closing root key of registry \"%s\" failed\n",
                        realargv[1]);
            exit(-3);
        }
    } else
    {
        if (bVerbose)
            fprintf(stderr, "open root key of registry \"%s\" failed\n",
                    realargv[1]);
        exit(-4);
    }

    if (reg_closeRegistry(hReg))
    {
        if (bVerbose)
            fprintf(stderr, "closing registry \"%s\" failed\n", realargv[1]);
        cleanCommandArgs();
        exit(-5);
    }

    cleanCommandArgs();
    return(0);
}

<commit_msg>INTEGRATION: CWS warnings01 (1.3.28); FILE MERGED 2005/11/21 13:37:39 sb 1.3.28.3: #i53898# Made code warning-free. 2005/09/22 22:06:30 sb 1.3.28.2: RESYNC: (1.3-1.4); FILE MERGED 2005/09/05 10:06:53 sb 1.3.28.1: #i53898# Made code warning-free.<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: regmerge.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-19 14:29:26 $
 *
 *  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
 *
 ************************************************************************/

#include <stdio.h>
#include <string.h>

#include "registry/registry.h"

#ifndef _RTL_USTRING_HXX_
#include    <rtl/ustring.hxx>
#endif

#ifndef _RTL_ALLOC_H_
#include    <rtl/alloc.h>
#endif

#ifndef _OSL_PROCESS_H_
#include <osl/process.h>
#endif
#ifndef _OSL_DIAGNOSE_H_
#include <osl/diagnose.h>
#endif
#ifndef _OSL_THREAD_H_
#include <osl/thread.h>
#endif
#ifndef _OSL_FILE_HXX_
#include <osl/file.hxx>
#endif

#ifdef SAL_UNX
#define SEPARATOR '/'
#else
#define SEPARATOR '\\'
#endif

using namespace ::rtl;
using namespace ::osl;

sal_Bool isFileUrl(const OString& fileName)
{
    if (fileName.indexOf("file://") == 0 )
        return sal_True;
    return sal_False;
}

OUString convertToFileUrl(const OString& fileName)
{
    if ( isFileUrl(fileName) )
    {
        return OStringToOUString(fileName, osl_getThreadTextEncoding());
    }

    OUString uUrlFileName;
    OUString uFileName(fileName.getStr(), fileName.getLength(), osl_getThreadTextEncoding());
    if ( fileName.indexOf('.') == 0 || fileName.indexOf(SEPARATOR) < 0 )
    {
        OUString uWorkingDir;
        if (osl_getProcessWorkingDir(&uWorkingDir.pData) != osl_Process_E_None)
        {
            OSL_ASSERT(false);
        }
        if (FileBase::getAbsoluteFileURL(uWorkingDir, uFileName, uUrlFileName)
            != FileBase::E_None)
        {
            OSL_ASSERT(false);
        }
    } else
    {
        if (FileBase::getFileURLFromSystemPath(uFileName, uUrlFileName)
            != FileBase::E_None)
        {
            OSL_ASSERT(false);
        }
    }

    return uUrlFileName;
}

int realargc;
char* realargv[2048];

static void dumpHelp()
{
    fprintf(stderr, "using: regmerge [-v|--verbose] mergefile mergeKeyName regfile_1 ... regfile_n\n");
    fprintf(stderr, "       regmerge @regcmds\nOptions:\n");
    fprintf(stderr, "  -v, --verbose : verbose output on stdout.\n");
    fprintf(stderr, "  mergefile     : specifies the merged registry file. If this file doesn't exists,\n");
    fprintf(stderr, "                  it is created.\n");
    fprintf(stderr, "  mergeKeyName  : specifies the merge key, everything is merged under this key.\n");
    fprintf(stderr, "                  If this key doesn't exists, it is created.\n");
    fprintf(stderr, "  regfile_1..n  : specifies one or more registry files which are merged.\n");
}

static bool checkCommandFile(char* cmdfile)
{
    FILE    *commandfile;
    char    option[256];
    bool    bVerbose = false;

    commandfile = fopen(cmdfile+1, "r");
    if( commandfile == NULL )
    {
        fprintf(stderr, "ERROR: Can't open command file \"%s\"\n", cmdfile);
    } else
    {
        while ( fscanf(commandfile, "%s", option) != EOF )
        {
            if (option[0]== '@')
            {
                bool bRet = checkCommandFile(option);
                // ensure that the option will not be overwritten
                if ( !bRet )
                    bVerbose = bRet;
            } else {
                if (option[0]== '-') {
                    if (strncmp(option, "-v", 2)  == 0 ||
                        strncmp(option, "--verbose", 9) == 0)
                    {
                        bVerbose = true;
                    } else {
                        fprintf(stderr, "ERROR: unknown option \"%s\"\n", option);
                        dumpHelp();
                        exit(-1);
                    }
                }else
                {
                    realargv[realargc]= strdup(option);
                    realargc++;
                }
            }
            if (realargc == 2047)
            {
                fprintf(stderr, "ERROR: more than 2048 arguments.\n");
                break;
            }
        }
        fclose(commandfile);
    }

    return bVerbose;
}

static bool checkCommandArgs(int argc, char **argv)
{
    bool bVerbose = false;

    realargc = 0;

    for (int i=0; i<argc; i++)
    {
        if (argv[i][0]== '@')
        {
            bool bRet = checkCommandFile(argv[i]);
            // ensure that the option will not be overwritten
            if ( !bRet )
                bVerbose = bRet;
        } else {
            if (argv[i][0]== '-') {
                if (strncmp(argv[i], "-v", 2)  == 0 ||
                    strncmp(argv[i], "--verbose", 9) == 0)
                {
                    bVerbose = true;
                } else {
                    fprintf(stderr, "ERROR: unknown option \"%s\"\n", argv[i]);
                    dumpHelp();
                    exit(-1);
                }
            } else
            {
                realargv[realargc]= strdup(argv[i]);
                realargc++;
            }
        }
    }

    return bVerbose;
}

static void cleanCommandArgs()
{
    for (int i=0; i<realargc; i++)
    {
        free(realargv[i]);
    }
}

#if (defined UNX) || (defined OS2)
int main( int argc, char * argv[] )
#else
int _cdecl main( int argc, char * argv[] )
#endif
{
    RegHandle       hReg;
    RegKeyHandle    hRootKey;
    bool            bVerbose = checkCommandArgs(argc, argv);

    if (realargc < 4)
    {
        dumpHelp();
        cleanCommandArgs();
        exit(1);
    }

    ::rtl::OUString regName( convertToFileUrl(realargv[1]) );
    if (reg_openRegistry(regName.pData, &hReg, REG_READWRITE))
    {
        if (reg_createRegistry(regName.pData, &hReg))
        {
            if (bVerbose)
                fprintf(stderr, "open registry \"%s\" failed\n", realargv[1]);
            cleanCommandArgs();
            exit(-1);
        }
    }

    if (!reg_openRootKey(hReg, &hRootKey))
    {
        ::rtl::OUString mergeKeyName( ::rtl::OUString::createFromAscii(realargv[2]) );
        ::rtl::OUString targetRegName;
        for (int i = 3; i < realargc; i++)
        {
            targetRegName = convertToFileUrl(realargv[i]);
            RegError _ret = reg_mergeKey(
                hRootKey, mergeKeyName.pData, targetRegName.pData, sal_False,
                bVerbose);
            if (_ret)
            {
                if (_ret == REG_MERGE_CONFLICT)
                {
                    if (bVerbose)
                        fprintf(stderr, "merging registry \"%s\" under key \"%s\" in registry \"%s\".\n",
                                realargv[i], realargv[2], realargv[1]);
                } else
                {
                    if (bVerbose)
                        fprintf(stderr, "ERROR: merging registry \"%s\" under key \"%s\" in registry \"%s\" failed.\n",
                                realargv[i], realargv[2], realargv[1]);
                    exit(-2);
                }
            } else
            {
                if (bVerbose)
                    fprintf(stderr, "merging registry \"%s\" under key \"%s\" in registry \"%s\".\n",
                            realargv[i], realargv[2], realargv[1]);
            }
        }

        if (reg_closeKey(hRootKey))
        {
            if (bVerbose)
                fprintf(stderr, "closing root key of registry \"%s\" failed\n",
                        realargv[1]);
            exit(-3);
        }
    } else
    {
        if (bVerbose)
            fprintf(stderr, "open root key of registry \"%s\" failed\n",
                    realargv[1]);
        exit(-4);
    }

    if (reg_closeRegistry(hReg))
    {
        if (bVerbose)
            fprintf(stderr, "closing registry \"%s\" failed\n", realargv[1]);
        cleanCommandArgs();
        exit(-5);
    }

    cleanCommandArgs();
    return(0);
}

<|endoftext|>


<commit_before>#include <iostream>
#include <cstring>

#include "fitness.h"

int FITNESS::setSolution(std::string solution)
{
  fitnessSolution = solution;

  return 0;
}

std::string FITNESS::getSolution()
{
  return fitnessSolution;
}

int FITNESS::getSolutionLength(std::string solution)
{
  return solution.length();
}

int FITNESS::getFitness(int *individual)
{
  int fitness = 0;

  // Solution string to array
  int solutionLength = getSolutionLength(getSolution());
  int solution_array[solutionLength];
  for (int i = 0; i < solutionLength; i++)
  {
    solution_array[i] = stoi(fitnessSolution.substr(i, 1), nullptr, 2);
  }

  for (int i = 0; i < solutionLength; i++)
  {
    if (individual[i] == solution_array[i])
    {
      fitness++;
    }
  }

  return fitness;
}

int FITNESS::getFittest(int **pop, int popSize)
{
  int fittestIndividual = 0;
  for (int i = 0; i < popSize; i++)
  {
    if (getFitness(pop[fittestIndividual]) <= getFitness(pop[i]))
      fittestIndividual = i;
  }

  return fittestIndividual;
}
<commit_msg>Changed argument of function 'getSolutionLength' and deleted parameters where the function is used.<commit_after>#include <iostream>
#include <cstring>

#include "fitness.h"

int FITNESS::setSolution(std::string solution)
{
  fitnessSolution = solution;

  return 0;
}

std::string FITNESS::getSolution()
{
  return fitnessSolution;
}

int FITNESS::getSolutionLength()
{
  return fitnessSolution.length();
}

int FITNESS::getFitness(int *individual)
{
  int fitness = 0;

  // Solution string to array
  int solutionLength = getSolutionLength();
  int solution_array[solutionLength];
  for (int i = 0; i < solutionLength; i++)
  {
    solution_array[i] = stoi(fitnessSolution.substr(i, 1), nullptr, 2);
  }

  for (int i = 0; i < solutionLength; i++)
  {
    if (individual[i] == solution_array[i])
    {
      fitness++;
    }
  }

  return fitness;
}

int FITNESS::getFittest(int **pop, int popSize)
{
  int fittestIndividual = 0;
  for (int i = 0; i < popSize; i++)
  {
    if (getFitness(pop[fittestIndividual]) <= getFitness(pop[i]))
      fittestIndividual = i;
  }

  return fittestIndividual;
}
<|endoftext|>


<commit_before>#include "../prep/random.h"

#include <iostream>
#include <unordered_set>
#include <vector>
#include <algorithm>
#include <iterator>

#include <cstdlib>
#include <cassert>

using namespace std;

template <typename iterator>
pair<iterator, iterator> find_2sum_sorted(typename iterator_traits<iterator>::value_type const &target, iterator begin, iterator end) {
	// ...
}

template <typename iterator>
pair<iterator, iterator> find_2sum(typename iterator_traits<iterator>::value_type const &target, iterator begin, iterator end) {
	sort(begin, end);

	return find_2sum_sorted(target, begin, end);
}

template <typename iterator>
pair<iterator, iterator> find_2sum_linear(typename iterator_traits<iterator>::value_type const &target, iterator begin, iterator end) {
	// ...
}

template <typename iterator>
pair<iterator, iterator> find_3sum(typename iterator_traits<iterator>::value_type const &target, iterator begin, iterator end) {
	sort(begin, end);

	// ...
}

template <typename iterator, typename method_type>
void test_2sum(typename iterator_traits<iterator>::value_type const &target, iterator begin, iterator end, method_type method) {
	auto result = method(target, begin, end);

	// ...
}

template <typename iterator>
void test_3sum(typename iterator_traits<iterator>::value_type const &target, iterator begin, iterator end) {
	auto result = find_3sum(target, begin, end);

	// ...
}

void stdin_test() {
	int target;
	if(!(cin >> target)) return;

	cout << "Target: " << target << endl;

	vector<int> v;
	cout << "Input:";
	for(int x; cin >> x; ) {
		v.push_back(x);
		cout << ' ' << x;
	}
	cout << endl;

	test_2sum(target, begin(v), end(v), find_2sum);
	test_2sum(target, begin(v), end(v), find_2sum_linear);
	test_3sum(target, begin(v), end(v));
}

void random_test(size_t n, int k) {
	assert(n > 0);

	cout << "n = " << n
		<< endl
		<< " k = " << k
		<< endl;

	auto 2sum_target = get_random(2 * k);
	cout << "2SUM target: " << target << endl;

	auto 3sum_target = get_random(3 * k);
	cout << "3SUM Target: " << target << endl;

	vector<unsigned> v(n);
	cout << "Input:";
	while(n--) {
		v[n] = get_random(k);
		cout << ' ' << v[n];
	}
	cout << endl;

	test_2sum(2sum_target, begin(v), end(v), find_2sum);
	test_2sum(2sum_target, begin(v), end(v), find_2sum_linear);
	test_3sum(3sum_target, begin(v), end(v));
}

int main(int argc, char **argv) {
	cout << "Seed: " << seed_random(argc > 3 ? atoi(argv[3]) : 0) << endl;

	random_test(
		argc > 1 ? atoi(argv[1]) : 20,
		argc > 2 ? atoi(argv[2]) : (sqrt(n) * 2)
	);

	cout << endl;

	stdin_test();
}
<commit_msg>further implementation of exercise 48<commit_after>#include "../prep/random.h"

#include <iostream>
#include <unordered_map>
#include <vector>
#include <algorithm>
#include <iterator>

#include <cstdlib>
#include <cassert>

using namespace std;

template <typename iterator>
pair<iterator, iterator> find_2sum_sorted(typename iterator_traits<iterator>::value_type const &target, iterator begin, iterator end) {
//* faster if the values are slow to sum/subtract
	if(begin == end || *begin > target) {
		return make_pair(end, end);
	}

	for(auto l = begin, r = end - 1; l != r; ) {
		auto seek = target - *l;

		while(*r > seek) {
			if(--r == l) {
				return make_pair(end, end);
			}
		}

		if(*r == seek) {
			return make_pair(l, r);
		}

		if(*++l > target) break;
	}
/*/ // less branches
	if(begin == end) {
		return make_pair(end, end);
	}

	for(auto l = begin, r = end - 1; l != r; ) {
		auto sum = *l + *r;

		if(sum > target) {
			--r;
		}
		else if(sum < target) {
			++l;
		}
		else {
			return make_pair(l, r);
		}
	}
//*/

	return make_pair(end, end);
}

template <typename iterator>
pair<iterator, iterator> find_2sum(typename iterator_traits<iterator>::value_type const &target, iterator begin, iterator end) {
	sort(begin, end);

	return find_2sum_sorted(target, begin, end);
}

template <typename iterator>
pair<iterator, iterator> find_2sum_linear(typename iterator_traits<iterator>::value_type const &target, iterator begin, iterator end) {
/* slightly more space efficient, at most n/2 space used
	auto half = target / 2;

	{
		size_t less = 0;
		size_t more = 0;

		for(auto i = begin; i != end; ++i) {
			if(*i > half) ++more;
			else ++less;
		}
	}

	auto chooser = more > less
		? [=](decltype(target) const &x){ return !(*i > half); }
		: [=](decltype(target) const &x){ return *i > half; };

	unordered_map<decltype(target), pair<iterator, bool>> table;

	for(auto i = begin; i != end; ++i) {
		if(!chooser(*i)) continue;

		auto j = table.find(*i);

		if(j == table.end()) {
			table[*i] = make_pair(i, false);
		}
		else {
			j->second.second = true;
		}
	}

	for(auto i = begin; i != end; ++i) {
		if(chooser(*i)) continue;

		auto complement = target - *i;
		auto j = table.find(complement);

		if(j != table.end() && (*i != complement || j->second)) {
			return make_pair(i, j->second.first);
		}
	}
/*/ //simpler
	unordered_map<decltype(target), pair<iterator, bool>> table;

	for(auto i = begin; i != end; ++i) {
		auto j = table.find(*i);

		if(j == table.end()) {
			table[*i] = make_pair(i, false);
		}
		else {
			j->second.second = true;
		}
	}

	for(auto i = begin; i != end; ++i) {
		auto complement = target - *i;
		auto j = table.find(complement);

		if(j != table.end() && (*i != complement || j->second)) {
			return make_pair(i, j->second.first);
		}
	}
//*/
}

template <typename iterator>
pair<iterator, iterator> find_3sum(typename iterator_traits<iterator>::value_type const &target, iterator begin, iterator end) {
	sort(begin, end);

	for(auto i = begin; i != end; ++i) {
		auto result = find_2sum_sorted(target - *i, i + 1, end);

		if(result.second != end && result.first != end) {
			return result;
		}
	}

	return make_pair(end, end);
}

template <typename iterator, typename method_type>
void test_2sum(typename iterator_traits<iterator>::value_type const &target, iterator begin, iterator end, method_type method) {
	auto result = method(target, begin, end);

	// ...
}

template <typename iterator>
void test_3sum(typename iterator_traits<iterator>::value_type const &target, iterator begin, iterator end) {
	auto result = find_3sum(target, begin, end);

	// ...
}

void stdin_test() {
	int target;
	if(!(cin >> target)) return;

	cout << "Target: " << target << endl;

	vector<int> v;
	cout << "Input:";
	for(int x; cin >> x; ) {
		v.push_back(x);
		cout << ' ' << x;
	}
	cout << endl;

	test_2sum(target, begin(v), end(v), find_2sum);
	test_2sum(target, begin(v), end(v), find_2sum_linear);
	test_3sum(target, begin(v), end(v));
}

void random_test(size_t n, int k) {
	assert(n > 0);

	cout << "n = " << n
		<< endl
		<< " k = " << k
		<< endl;

	auto 2sum_target = get_random(2 * k);
	cout << "2SUM target: " << target << endl;

	auto 3sum_target = get_random(3 * k);
	cout << "3SUM Target: " << target << endl;

	vector<unsigned> v(n);
	cout << "Input:";
	while(n--) {
		v[n] = get_random(k);
		cout << ' ' << v[n];
	}
	cout << endl;

	test_2sum(2sum_target, begin(v), end(v), find_2sum);
	test_2sum(2sum_target, begin(v), end(v), find_2sum_linear);
	test_3sum(3sum_target, begin(v), end(v));
}

int main(int argc, char **argv) {
	cout << "Seed: " << seed_random(argc > 3 ? atoi(argv[3]) : 0) << endl;

	random_test(
		argc > 1 ? atoi(argv[1]) : 20,
		argc > 2 ? atoi(argv[2]) : (sqrt(n) * 2)
	);

	cout << endl;

	stdin_test();
}
<|endoftext|>


<commit_before>#include <atlconv.h>
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <stdio.h>
#include <tchar.h>
#include <windows.h>

#include <boost/algorithm/string.hpp>
#include <boost/foreach.hpp>
#include <boost/program_options.hpp>

#include "VoiceroidFactory.h"
#include "Yukari.h"
#include "YukariEx.h"

#define DELIMITERS L".B"

using namespace boost::program_options;

// IvV\\
struct Options {
	// ǂݏグ VOICEROID(Yukari, YukariEx)
	std::string target_voiceroid_str;
	// o̓t@CpX
	std::string output_file;
	// ̓t@CpX
	std::string input_file;
	// ̓t@CR[h UTF8 Ƃď
	bool is_utf8;
	// [h(ĐEۑ܂őҋ@܂)
	bool is_sync_mode;
	// ǂݏグ(Ƃēnꂽꍇ)
	std::wstring echo_text;
	// ǂݏグ𕪊ڈ̃TCY
	size_t split_size;
} typedef Options;

// t@Ce擾
std::string getContents(std::string filepath);

// 񂪃f~^ǂ肷
bool is_delimiter(std::wstring str);

// wstring  string ɕϊ
std::string wstring2string(const std::wstring &src);

// string  wstring ɕϊ
std::wstring string2wstring(const std::string &src);

// UTF8  SJIS ɂĕԂ
std::string utf8toSjis(std::string srcUTF8);

// R}hC
Options parseArgs(int argc, _TCHAR* argv[]);

int _tmain(int argc, _TCHAR* argv[])
{
	setlocale(LC_CTYPE, "");
	std::ios::sync_with_stdio(true);

	// R}hC
	Options options = parseArgs(argc, argv);

	// w肳ꂽɉ
	// R}hCt@Cǂݏグ擾B
	std::string contents;
	if (options.input_file.compare("") == 0) {
		// t@Cw肪Ȃ΃R}hC擾
		contents = wstring2string(options.echo_text);
	} else {
		// t@Cw肪΃t@Ce擾
		contents = getContents(options.input_file);

		// t@CR[hɉĕϊ
		if (options.is_utf8) {
			// utf8
			contents = utf8toSjis(contents);
		}
	}

	// ɉĒNgp邩肷
	VoiceroidType voiceroidType;
	if (options.target_voiceroid_str.compare("Yukari") == 0) {
		voiceroidType = VoiceroidType::YUKARI;
	}
	else if (options.target_voiceroid_str.compare("YukariEx") == 0) {
		voiceroidType = VoiceroidType::YUKARI_EX;
	}

	// VOICEROID 쐬
	Voiceroid* voiceroid = VoiceroidFactory::create(voiceroidType);

	// ǂݏグ邩t@Cɕۑ邩
	if (options.output_file.length() == 0) {
		// w蕶𒴂Ȃ悤ɕȂǂݏグB
		std::wstring wcontents = string2wstring(contents);

		std::list<std::wstring> list_string;
		boost::split(list_string, wcontents, boost::is_any_of(DELIMITERS));

		size_t size = 0;
		std::wstringstream ss;

		BOOST_FOREACH(std::wstring s, list_string) {

			if (size == 0
				|| is_delimiter(s)) {
				// ŏw蕶Ă炱͂傤ȂB
				size += s.length();
				ss << s << L"B";
			} else if (size + s.length() > options.split_size) {
				// w蕶𒴂ꍇA
				// ܂łߍł̂ǂݏグB

				// ǂݏグ
				voiceroid->echo(wstring2string(ss.str()), options.is_sync_mode);

				// ss Zbg
				ss.str(L"");
				ss.clear();
				size = s.length();
				ss << s << L"B";
			} else {
				// w蕶𒴂ȂꍇA
				// TCY𑝂₵ĕ񌋍
				size += s.length();
				ss << s << L"B";
			}
		}

		// Ō̓ǂݏグ
		voiceroid->echo(wstring2string(ss.str()), options.is_sync_mode);

	} else {
		// t@Cɕۑ
		voiceroid->save(contents, options.output_file, options.is_sync_mode);
	}

	delete voiceroid;

	exit(0);
}

Options parseArgs(int argc, _TCHAR* argv[]) {
	options_description opt("IvV");
	// R}hC`
	opt.add_options()
		("help,h", "wv\")
		("voiceroid", value<std::string>()->default_value("YukariEx"), "ǂݏグ VOICEROID(Yukari, YukariEx)")
		("output-file,o", wvalue<std::wstring>(), "o̓t@CpX")
		("input-file,i", wvalue<std::wstring>(), "̓t@CpX")
		("utf8,u", "̓t@CR[h UTF8 Ƃď")
		("sync,s", "[h(ĐEۑ܂őҋ@܂)")
		("split-size", value<size_t>()->default_value(2000), "ǂݏグ𕪊ڈ̃TCY");

	// R}hC
	variables_map argmap;
	auto pr = parse_command_line(argc, argv, opt);
	store(pr, argmap);
	notify(argmap);

	// ͌ʎ擾
	Options options;
	options.target_voiceroid_str = argmap["voiceroid"].as<std::string>();

	// o̓t@CpX擾
	// (gpĂo[W boost_program_options ł́A
	//  std::wstring ɑ΂ default_value w肷ƃRpCG[ɂȂ邽߁A
	//  IvV̗L`FbNƑOŎ)
	std::wstring woutput_file;
	if (argmap.count("output-file")) {
		woutput_file = argmap["output-file"].as<std::wstring>();
	} else {
		woutput_file = L"";
	}

	// ̓t@CpX擾
	// (gpĂo[W boost_program_options ł́A
	//  std::wstring ɑ΂ default_value w肷ƃRpCG[ɂȂ邽߁A
	//  IvV̗L`FbNƑOŎ)
	std::wstring winput_file;
	if (argmap.count("input-file")) {
		winput_file = argmap["input-file"].as<std::wstring>();
	} else {
		winput_file = L"";
	}

	options.is_utf8 = argmap.count("utf8");
	options.is_sync_mode = !argmap["sync"].empty();
	options.echo_text = _T("");
	options.split_size = argmap["split-size"].as<size_t>();

	// wstring Ŏ󂯎 string ɕϊ
	options.output_file = wstring2string(woutput_file);
	options.input_file = wstring2string(winput_file);

	// IvVȊÕR}hC擾
	for (auto const& str : collect_unrecognized(pr.options, include_positional)) {
		options.echo_text.append(_T(" "));
		options.echo_text.append(str);
	}

	// wv\w肪邩A
	// echo_text, input_file Ƃ̏ꍇAwv\ďI
	if (argmap.count("help") ||
		(options.echo_text.compare(_T("")) == 0
			&& options.input_file.compare("") == 0)) {
		_TCHAR drive[_MAX_DRIVE];
		_TCHAR dir[_MAX_DIR];
		_TCHAR filename[_MAX_FNAME];
		_TCHAR ext[_MAX_EXT];
		_tsplitpath(argv[0], drive, dir, filename, ext);

		wprintf(L"Usage: %s%s [options] [text]\n", filename, ext);

		std::stringstream helpStream;
		helpStream << opt << std::endl;
		printf(helpStream.str().c_str());

		exit(1);
	}

	return options;
}

std::string wstring2string(const std::wstring &src) {
	char *mbs = new char[src.length() * MB_CUR_MAX + 1];
	wcstombs(mbs, src.c_str(), src.length() * MB_CUR_MAX + 1);

	std::string dest = mbs;
	delete[] mbs;

	return dest;
}

std::wstring string2wstring(const std::string &src) {
	wchar_t *wcs = new wchar_t[src.length() + 1];
	mbstowcs(wcs, src.c_str(), src.length() + 1);
	std::wstring dest = wcs;
	delete[] wcs;

	return dest;
}

std::string utf8toSjis(std::string srcUTF8) {
	//Unicode֕ϊ̕񒷂𓾂
	int lenghtUnicode = MultiByteToWideChar(CP_UTF8, 0, srcUTF8.c_str(), srcUTF8.size() + 1, NULL, 0);

	//KvȕUnicodẽobt@m
	wchar_t* bufUnicode = new wchar_t[lenghtUnicode];

	//UTF8Unicode֕ϊ
	MultiByteToWideChar(CP_UTF8, 0, srcUTF8.c_str(), srcUTF8.size() + 1, bufUnicode, lenghtUnicode);

	//ShiftJIS֕ϊ̕񒷂𓾂
	int lengthSJis = WideCharToMultiByte(CP_THREAD_ACP, 0, bufUnicode, -1, NULL, 0, NULL, NULL);

	//KvȕShiftJIS̃obt@m
	char* bufShiftJis = new char[lengthSJis];

	//UnicodeShiftJIS֕ϊ
	WideCharToMultiByte(CP_THREAD_ACP, 0, bufUnicode, lenghtUnicode + 1, bufShiftJis, lengthSJis, NULL, NULL);

	std::string strSJis(bufShiftJis);

	delete bufUnicode;
	delete bufShiftJis;

	return strSJis;
}

// t@Ce擾
std::string getContents(std::string filepath) {
	std::ifstream ifs (filepath);

	// t@CI[v۔
	if (ifs.fail())
	{
		std::cerr << "t@CI[vɎs܂B" << std::endl;
		return NULL;
	}

	// TODO: ꉽĂł[ˁH
	std::istreambuf_iterator<char> it(ifs);
	std::istreambuf_iterator<char> last;
	std::string str (it, last);

	return str;
}

bool is_delimiter(std::wstring str) {
	for (wchar_t* it = DELIMITERS; *it; ++it) {
		size_t index = str.find(*it);

		if (index != std::string::npos) {
			return TRUE;
		}
	}

	return FALSE;
}

<commit_msg>リファクタリング。<commit_after>#include <atlconv.h>
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <stdio.h>
#include <tchar.h>
#include <windows.h>

#include <boost/algorithm/string.hpp>
#include <boost/foreach.hpp>
#include <boost/program_options.hpp>

#include "VoiceroidFactory.h"
#include "Yukari.h"
#include "YukariEx.h"

#define DELIMITERS L".B"

using namespace boost::program_options;

// IvV\\
struct Options {
	// ǂݏグ VOICEROID(Yukari, YukariEx)
	std::string target_voiceroid_str;
	// o̓t@CpX
	std::string output_file;
	// ̓t@CpX
	std::string input_file;
	// ̓t@CR[h UTF8 Ƃď
	bool is_utf8;
	// [h(ĐEۑ܂őҋ@܂)
	bool is_sync_mode;
	// ǂݏグ(Ƃēnꂽꍇ)
	std::wstring echo_text;
	// ǂݏグ𕪊ڈ̃TCY
	size_t split_size;
} typedef Options;

// t@Ce擾
std::string getContents(std::string filepath);

// 񂪃f~^ǂ肷
bool is_delimiter(std::wstring str);

// wstring  string ɕϊ
std::string wstring2string(const std::wstring &src);

// string  wstring ɕϊ
std::wstring string2wstring(const std::string &src);

// UTF8  SJIS ɂĕԂ
std::string utf8toSjis(std::string srcUTF8);

// R}hC
Options parseArgs(int argc, _TCHAR* argv[]);

int _tmain(int argc, _TCHAR* argv[])
{
	setlocale(LC_CTYPE, "");
	std::ios::sync_with_stdio(true);

	// R}hC
	Options options = parseArgs(argc, argv);

	// w肳ꂽɉ
	// R}hCt@Cǂݏグ擾B
	std::string contents;
	if (options.input_file.compare("") == 0) {
		// t@Cw肪Ȃ΃R}hC擾
		contents = wstring2string(options.echo_text);
	} else {
		// t@Cw肪΃t@Ce擾
		contents = getContents(options.input_file);

		// t@CR[hɉĕϊ
		if (options.is_utf8) {
			// utf8
			contents = utf8toSjis(contents);
		}
	}

	// ɉĒNgp邩肷
	VoiceroidType voiceroidType;
	if (options.target_voiceroid_str.compare("Yukari") == 0) {
		voiceroidType = VoiceroidType::YUKARI;
	}
	else if (options.target_voiceroid_str.compare("YukariEx") == 0) {
		voiceroidType = VoiceroidType::YUKARI_EX;
	}

	// VOICEROID 쐬
	Voiceroid* voiceroid = VoiceroidFactory::create(voiceroidType);

	// ǂݏグ邩t@Cɕۑ邩
	if (options.output_file.length() == 0) {
		// w蕶𒴂Ȃ悤ɕȂǂݏグB
		std::wstring wcontents = string2wstring(contents);

		std::list<std::wstring> list_string;
		boost::split(list_string, wcontents, boost::is_any_of(DELIMITERS));

		size_t size = 0;
		std::wstringstream ss;

		BOOST_FOREACH(std::wstring s, list_string) {

			// w蕶𒴂ꍇA
			// ܂łߍł̂ǂݏグB
			// A񂩂璴Ăꍇ͂߂B
			if (size != 0 && size + s.length() > options.split_size) {

				// ǂݏグ
				voiceroid->echo(wstring2string(ss.str()), options.is_sync_mode);

				// ss Zbg
				ss.str(L"");
				ss.clear();
				size = 0;
			}

			// TCY𑝂₵ĕ񌋍
			size += s.length();
			ss << s << L"B";
		}

		// Ō̓ǂݏグ
		voiceroid->echo(wstring2string(ss.str()), options.is_sync_mode);

	} else {
		// t@Cɕۑ
		voiceroid->save(contents, options.output_file, options.is_sync_mode);
	}

	delete voiceroid;

	exit(0);
}

Options parseArgs(int argc, _TCHAR* argv[]) {
	options_description opt("IvV");
	// R}hC`
	opt.add_options()
		("help,h", "wv\")
		("voiceroid", value<std::string>()->default_value("YukariEx"), "ǂݏグ VOICEROID(Yukari, YukariEx)")
		("output-file,o", wvalue<std::wstring>(), "o̓t@CpX")
		("input-file,i", wvalue<std::wstring>(), "̓t@CpX")
		("utf8,u", "̓t@CR[h UTF8 Ƃď")
		("sync,s", "[h(ĐEۑ܂őҋ@܂)")
		("split-size", value<size_t>()->default_value(2000), "ǂݏグ𕪊ڈ̃TCY");

	// R}hC
	variables_map argmap;
	auto pr = parse_command_line(argc, argv, opt);
	store(pr, argmap);
	notify(argmap);

	// ͌ʎ擾
	Options options;
	options.target_voiceroid_str = argmap["voiceroid"].as<std::string>();

	// o̓t@CpX擾
	// (gpĂo[W boost_program_options ł́A
	//  std::wstring ɑ΂ default_value w肷ƃRpCG[ɂȂ邽߁A
	//  IvV̗L`FbNƑOŎ)
	std::wstring woutput_file;
	if (argmap.count("output-file")) {
		woutput_file = argmap["output-file"].as<std::wstring>();
	} else {
		woutput_file = L"";
	}

	// ̓t@CpX擾
	// (gpĂo[W boost_program_options ł́A
	//  std::wstring ɑ΂ default_value w肷ƃRpCG[ɂȂ邽߁A
	//  IvV̗L`FbNƑOŎ)
	std::wstring winput_file;
	if (argmap.count("input-file")) {
		winput_file = argmap["input-file"].as<std::wstring>();
	} else {
		winput_file = L"";
	}

	options.is_utf8 = argmap.count("utf8");
	options.is_sync_mode = !argmap["sync"].empty();
	options.echo_text = _T("");
	options.split_size = argmap["split-size"].as<size_t>();

	// wstring Ŏ󂯎 string ɕϊ
	options.output_file = wstring2string(woutput_file);
	options.input_file = wstring2string(winput_file);

	// IvVȊÕR}hC擾
	for (auto const& str : collect_unrecognized(pr.options, include_positional)) {
		options.echo_text.append(_T(" "));
		options.echo_text.append(str);
	}

	// wv\w肪邩A
	// echo_text, input_file Ƃ̏ꍇAwv\ďI
	if (argmap.count("help") ||
		(options.echo_text.compare(_T("")) == 0
			&& options.input_file.compare("") == 0)) {
		_TCHAR drive[_MAX_DRIVE];
		_TCHAR dir[_MAX_DIR];
		_TCHAR filename[_MAX_FNAME];
		_TCHAR ext[_MAX_EXT];
		_tsplitpath(argv[0], drive, dir, filename, ext);

		wprintf(L"Usage: %s%s [options] [text]\n", filename, ext);

		std::stringstream helpStream;
		helpStream << opt << std::endl;
		printf(helpStream.str().c_str());

		exit(1);
	}

	return options;
}

std::string wstring2string(const std::wstring &src) {
	char *mbs = new char[src.length() * MB_CUR_MAX + 1];
	wcstombs(mbs, src.c_str(), src.length() * MB_CUR_MAX + 1);

	std::string dest = mbs;
	delete[] mbs;

	return dest;
}

std::wstring string2wstring(const std::string &src) {
	wchar_t *wcs = new wchar_t[src.length() + 1];
	mbstowcs(wcs, src.c_str(), src.length() + 1);
	std::wstring dest = wcs;
	delete[] wcs;

	return dest;
}

std::string utf8toSjis(std::string srcUTF8) {
	//Unicode֕ϊ̕񒷂𓾂
	int lenghtUnicode = MultiByteToWideChar(CP_UTF8, 0, srcUTF8.c_str(), srcUTF8.size() + 1, NULL, 0);

	//KvȕUnicodẽobt@m
	wchar_t* bufUnicode = new wchar_t[lenghtUnicode];

	//UTF8Unicode֕ϊ
	MultiByteToWideChar(CP_UTF8, 0, srcUTF8.c_str(), srcUTF8.size() + 1, bufUnicode, lenghtUnicode);

	//ShiftJIS֕ϊ̕񒷂𓾂
	int lengthSJis = WideCharToMultiByte(CP_THREAD_ACP, 0, bufUnicode, -1, NULL, 0, NULL, NULL);

	//KvȕShiftJIS̃obt@m
	char* bufShiftJis = new char[lengthSJis];

	//UnicodeShiftJIS֕ϊ
	WideCharToMultiByte(CP_THREAD_ACP, 0, bufUnicode, lenghtUnicode + 1, bufShiftJis, lengthSJis, NULL, NULL);

	std::string strSJis(bufShiftJis);

	delete bufUnicode;
	delete bufShiftJis;

	return strSJis;
}

// t@Ce擾
std::string getContents(std::string filepath) {
	std::ifstream ifs (filepath);

	// t@CI[v۔
	if (ifs.fail())
	{
		std::cerr << "t@CI[vɎs܂B" << std::endl;
		return NULL;
	}

	// TODO: ꉽĂł[ˁH
	std::istreambuf_iterator<char> it(ifs);
	std::istreambuf_iterator<char> last;
	std::string str (it, last);

	return str;
}

bool is_delimiter(std::wstring str) {
	for (wchar_t* it = DELIMITERS; *it; ++it) {
		size_t index = str.find(*it);

		if (index != std::string::npos) {
			return TRUE;
		}
	}

	return FALSE;
}

<|endoftext|>


<commit_before>// Copyright (c) 2009-2020 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <core_io.h>

#include <primitives/block.h>
#include <primitives/transaction.h>
#include <script/script.h>
#include <script/sign.h>
#include <serialize.h>
#include <streams.h>
#include <univalue.h>
#include <util/strencodings.h>
#include <version.h>

#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/replace.hpp>
#include <boost/algorithm/string/split.hpp>

#include <algorithm>
#include <string>

CScript ParseScript(const std::string& s)
{
    CScript result;

    static std::map<std::string, opcodetype> mapOpNames;

    if (mapOpNames.empty())
    {
        for (unsigned int op = 0; op <= MAX_OPCODE; op++)
        {
            // Allow OP_RESERVED to get into mapOpNames
            if (op < OP_NOP && op != OP_RESERVED)
                continue;

            std::string strName = GetOpName(static_cast<opcodetype>(op));
            if (strName == "OP_UNKNOWN")
                continue;
            mapOpNames[strName] = static_cast<opcodetype>(op);
            // Convenience: OP_ADD and just ADD are both recognized:
            boost::algorithm::replace_first(strName, "OP_", "");
            mapOpNames[strName] = static_cast<opcodetype>(op);
        }
    }

    std::vector<std::string> words;
    boost::algorithm::split(words, s, boost::algorithm::is_any_of(" \t\n"), boost::algorithm::token_compress_on);

    for (std::vector<std::string>::const_iterator w = words.begin(); w != words.end(); ++w)
    {
        if (w->empty())
        {
            // Empty string, ignore. (boost::split given '' will return one word)
        }
        else if (std::all_of(w->begin(), w->end(), ::IsDigit) ||
            (w->front() == '-' && w->size() > 1 && std::all_of(w->begin()+1, w->end(), ::IsDigit)))
        {
            // Number
            int64_t n = atoi64(*w);

            //limit the range of numbers ParseScript accepts in decimal
            //since numbers outside -0xFFFFFFFF...0xFFFFFFFF are illegal in scripts
            if (n > int64_t{0xffffffff} || n < -1 * int64_t{0xffffffff}) {
                throw std::runtime_error("script parse error: decimal numeric value only allowed in the "
                                         "range -0xFFFFFFFF...0xFFFFFFFF");
            }

            result << n;
        }
        else if (w->substr(0,2) == "0x" && w->size() > 2 && IsHex(std::string(w->begin()+2, w->end())))
        {
            // Raw hex data, inserted NOT pushed onto stack:
            std::vector<unsigned char> raw = ParseHex(std::string(w->begin()+2, w->end()));
            result.insert(result.end(), raw.begin(), raw.end());
        }
        else if (w->size() >= 2 && w->front() == '\'' && w->back() == '\'')
        {
            // Single-quoted string, pushed as data. NOTE: this is poor-man's
            // parsing, spaces/tabs/newlines in single-quoted strings won't work.
            std::vector<unsigned char> value(w->begin()+1, w->end()-1);
            result << value;
        }
        else if (mapOpNames.count(*w))
        {
            // opcode, e.g. OP_ADD or ADD:
            result << mapOpNames[*w];
        }
        else
        {
            throw std::runtime_error("script parse error");
        }
    }

    return result;
}

// Check that all of the input and output scripts of a transaction contains valid opcodes
static bool CheckTxScriptsSanity(const CMutableTransaction& tx)
{
    // Check input scripts for non-coinbase txs
    if (!CTransaction(tx).IsCoinBase()) {
        for (unsigned int i = 0; i < tx.vin.size(); i++) {
            if (!tx.vin[i].scriptSig.HasValidOps() || tx.vin[i].scriptSig.size() > MAX_SCRIPT_SIZE) {
                return false;
            }
        }
    }
    // Check output scripts
    for (unsigned int i = 0; i < tx.vout.size(); i++) {
        if (!tx.vout[i].scriptPubKey.HasValidOps() || tx.vout[i].scriptPubKey.size() > MAX_SCRIPT_SIZE) {
            return false;
        }
    }

    return true;
}

static bool DecodeTx(CMutableTransaction& tx, const std::vector<unsigned char>& tx_data, bool try_no_witness, bool try_witness)
{
    if (try_witness) {
        CDataStream ssData(tx_data, SER_NETWORK, PROTOCOL_VERSION);
        try {
            ssData >> tx;
            // If transaction looks sane, we don't try other mode even if requested
            if (ssData.empty() && (!try_no_witness || CheckTxScriptsSanity(tx))) {
                return true;
            }
        } catch (const std::exception&) {
            // Fall through.
        }
    }

    if (try_no_witness) {
        CDataStream ssData(tx_data, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS);
        try {
            ssData >> tx;
            if (ssData.empty()) {
                return true;
            }
        } catch (const std::exception&) {
            // Fall through.
        }
    }

    return false;
}

bool DecodeHexTx(CMutableTransaction& tx, const std::string& hex_tx, bool try_no_witness, bool try_witness)
{
    if (!IsHex(hex_tx)) {
        return false;
    }

    std::vector<unsigned char> txData(ParseHex(hex_tx));
    return DecodeTx(tx, txData, try_no_witness, try_witness);
}

bool DecodeHexBlockHeader(CBlockHeader& header, const std::string& hex_header)
{
    if (!IsHex(hex_header)) return false;

    const std::vector<unsigned char> header_data{ParseHex(hex_header)};
    CDataStream ser_header(header_data, SER_NETWORK, PROTOCOL_VERSION);
    try {
        ser_header >> header;
    } catch (const std::exception&) {
        return false;
    }
    return true;
}

bool DecodeHexBlk(CBlock& block, const std::string& strHexBlk)
{
    if (!IsHex(strHexBlk))
        return false;

    std::vector<unsigned char> blockData(ParseHex(strHexBlk));
    CDataStream ssBlock(blockData, SER_NETWORK, PROTOCOL_VERSION);
    try {
        ssBlock >> block;
    }
    catch (const std::exception&) {
        return false;
    }

    return true;
}

bool ParseHashStr(const std::string& strHex, uint256& result)
{
    if ((strHex.size() != 64) || !IsHex(strHex))
        return false;

    result.SetHex(strHex);
    return true;
}

std::vector<unsigned char> ParseHexUV(const UniValue& v, const std::string& strName)
{
    std::string strHex;
    if (v.isStr())
        strHex = v.getValStr();
    if (!IsHex(strHex))
        throw std::runtime_error(strName + " must be hexadecimal string (not '" + strHex + "')");
    return ParseHex(strHex);
}

int ParseSighashString(const UniValue& sighash)
{
    int hash_type = SIGHASH_ALL;
    if (!sighash.isNull()) {
        static std::map<std::string, int> map_sighash_values = {
            {std::string("ALL"), int(SIGHASH_ALL)},
            {std::string("ALL|ANYONECANPAY"), int(SIGHASH_ALL|SIGHASH_ANYONECANPAY)},
            {std::string("NONE"), int(SIGHASH_NONE)},
            {std::string("NONE|ANYONECANPAY"), int(SIGHASH_NONE|SIGHASH_ANYONECANPAY)},
            {std::string("SINGLE"), int(SIGHASH_SINGLE)},
            {std::string("SINGLE|ANYONECANPAY"), int(SIGHASH_SINGLE|SIGHASH_ANYONECANPAY)},
        };
        std::string strHashType = sighash.get_str();
        const auto& it = map_sighash_values.find(strHashType);
        if (it != map_sighash_values.end()) {
            hash_type = it->second;
        } else {
            throw std::runtime_error(strHashType + " is not a valid sighash parameter.");
        }
    }
    return hash_type;
}
<commit_msg>Improve heuristic hex transaction decoding<commit_after>// Copyright (c) 2009-2020 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <core_io.h>

#include <primitives/block.h>
#include <primitives/transaction.h>
#include <script/script.h>
#include <script/sign.h>
#include <serialize.h>
#include <streams.h>
#include <univalue.h>
#include <util/strencodings.h>
#include <version.h>

#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/replace.hpp>
#include <boost/algorithm/string/split.hpp>

#include <algorithm>
#include <string>

CScript ParseScript(const std::string& s)
{
    CScript result;

    static std::map<std::string, opcodetype> mapOpNames;

    if (mapOpNames.empty())
    {
        for (unsigned int op = 0; op <= MAX_OPCODE; op++)
        {
            // Allow OP_RESERVED to get into mapOpNames
            if (op < OP_NOP && op != OP_RESERVED)
                continue;

            std::string strName = GetOpName(static_cast<opcodetype>(op));
            if (strName == "OP_UNKNOWN")
                continue;
            mapOpNames[strName] = static_cast<opcodetype>(op);
            // Convenience: OP_ADD and just ADD are both recognized:
            boost::algorithm::replace_first(strName, "OP_", "");
            mapOpNames[strName] = static_cast<opcodetype>(op);
        }
    }

    std::vector<std::string> words;
    boost::algorithm::split(words, s, boost::algorithm::is_any_of(" \t\n"), boost::algorithm::token_compress_on);

    for (std::vector<std::string>::const_iterator w = words.begin(); w != words.end(); ++w)
    {
        if (w->empty())
        {
            // Empty string, ignore. (boost::split given '' will return one word)
        }
        else if (std::all_of(w->begin(), w->end(), ::IsDigit) ||
            (w->front() == '-' && w->size() > 1 && std::all_of(w->begin()+1, w->end(), ::IsDigit)))
        {
            // Number
            int64_t n = atoi64(*w);

            //limit the range of numbers ParseScript accepts in decimal
            //since numbers outside -0xFFFFFFFF...0xFFFFFFFF are illegal in scripts
            if (n > int64_t{0xffffffff} || n < -1 * int64_t{0xffffffff}) {
                throw std::runtime_error("script parse error: decimal numeric value only allowed in the "
                                         "range -0xFFFFFFFF...0xFFFFFFFF");
            }

            result << n;
        }
        else if (w->substr(0,2) == "0x" && w->size() > 2 && IsHex(std::string(w->begin()+2, w->end())))
        {
            // Raw hex data, inserted NOT pushed onto stack:
            std::vector<unsigned char> raw = ParseHex(std::string(w->begin()+2, w->end()));
            result.insert(result.end(), raw.begin(), raw.end());
        }
        else if (w->size() >= 2 && w->front() == '\'' && w->back() == '\'')
        {
            // Single-quoted string, pushed as data. NOTE: this is poor-man's
            // parsing, spaces/tabs/newlines in single-quoted strings won't work.
            std::vector<unsigned char> value(w->begin()+1, w->end()-1);
            result << value;
        }
        else if (mapOpNames.count(*w))
        {
            // opcode, e.g. OP_ADD or ADD:
            result << mapOpNames[*w];
        }
        else
        {
            throw std::runtime_error("script parse error");
        }
    }

    return result;
}

// Check that all of the input and output scripts of a transaction contains valid opcodes
static bool CheckTxScriptsSanity(const CMutableTransaction& tx)
{
    // Check input scripts for non-coinbase txs
    if (!CTransaction(tx).IsCoinBase()) {
        for (unsigned int i = 0; i < tx.vin.size(); i++) {
            if (!tx.vin[i].scriptSig.HasValidOps() || tx.vin[i].scriptSig.size() > MAX_SCRIPT_SIZE) {
                return false;
            }
        }
    }
    // Check output scripts
    for (unsigned int i = 0; i < tx.vout.size(); i++) {
        if (!tx.vout[i].scriptPubKey.HasValidOps() || tx.vout[i].scriptPubKey.size() > MAX_SCRIPT_SIZE) {
            return false;
        }
    }

    return true;
}

static bool DecodeTx(CMutableTransaction& tx, const std::vector<unsigned char>& tx_data, bool try_no_witness, bool try_witness)
{
    // General strategy:
    // - Decode both with extended serialization (which interprets the 0x0001 tag as a marker for
    //   the presense of witnesses) and with legacy serialization (which interprets the tag as a
    //   0-input 1-output incomplete transaction).
    //   - Restricted by try_no_witness (which disables legacy if false) and try_witness (which
    //     disables extended if false).
    //   - Ignore serializations that do not fully consume the hex string.
    // - If neither succeeds, fail.
    // - If only one succeeds, return that one.
    // - If both decode attempts succeed:
    //   - If only one passes the CheckTxScriptsSanity check, return that one.
    //   - If neither or both pass CheckTxScriptsSanity, return the extended one.

    CMutableTransaction tx_extended, tx_legacy;
    bool ok_extended = false, ok_legacy = false;

    // Try decoding with extended serialization support, and remember if the result successfully
    // consumes the entire input.
    if (try_witness) {
        CDataStream ssData(tx_data, SER_NETWORK, PROTOCOL_VERSION);
        try {
            ssData >> tx_extended;
            if (ssData.empty()) ok_extended = true;
        } catch (const std::exception&) {
            // Fall through.
        }
    }

    // Optimization: if extended decoding succeeded and the result passes CheckTxScriptsSanity,
    // don't bother decoding the other way.
    if (ok_extended && CheckTxScriptsSanity(tx_extended)) {
        tx = std::move(tx_extended);
        return true;
    }

    // Try decoding with legacy serialization, and remember if the result successfully consumes the entire input.
    if (try_no_witness) {
        CDataStream ssData(tx_data, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS);
        try {
            ssData >> tx_legacy;
            if (ssData.empty()) ok_legacy = true;
        } catch (const std::exception&) {
            // Fall through.
        }
    }

    // If legacy decoding succeeded and passes CheckTxScriptsSanity, that's our answer, as we know
    // at this point that extended decoding either failed or doesn't pass the sanity check.
    if (ok_legacy && CheckTxScriptsSanity(tx_legacy)) {
        tx = std::move(tx_legacy);
        return true;
    }

    // If extended decoding succeeded, and neither decoding passes sanity, return the extended one.
    if (ok_extended) {
        tx = std::move(tx_extended);
        return true;
    }

    // If legacy decoding succeeded and extended didn't, return the legacy one.
    if (ok_legacy) {
        tx = std::move(tx_legacy);
        return true;
    }

    // If none succeeded, we failed.
    return false;
}

bool DecodeHexTx(CMutableTransaction& tx, const std::string& hex_tx, bool try_no_witness, bool try_witness)
{
    if (!IsHex(hex_tx)) {
        return false;
    }

    std::vector<unsigned char> txData(ParseHex(hex_tx));
    return DecodeTx(tx, txData, try_no_witness, try_witness);
}

bool DecodeHexBlockHeader(CBlockHeader& header, const std::string& hex_header)
{
    if (!IsHex(hex_header)) return false;

    const std::vector<unsigned char> header_data{ParseHex(hex_header)};
    CDataStream ser_header(header_data, SER_NETWORK, PROTOCOL_VERSION);
    try {
        ser_header >> header;
    } catch (const std::exception&) {
        return false;
    }
    return true;
}

bool DecodeHexBlk(CBlock& block, const std::string& strHexBlk)
{
    if (!IsHex(strHexBlk))
        return false;

    std::vector<unsigned char> blockData(ParseHex(strHexBlk));
    CDataStream ssBlock(blockData, SER_NETWORK, PROTOCOL_VERSION);
    try {
        ssBlock >> block;
    }
    catch (const std::exception&) {
        return false;
    }

    return true;
}

bool ParseHashStr(const std::string& strHex, uint256& result)
{
    if ((strHex.size() != 64) || !IsHex(strHex))
        return false;

    result.SetHex(strHex);
    return true;
}

std::vector<unsigned char> ParseHexUV(const UniValue& v, const std::string& strName)
{
    std::string strHex;
    if (v.isStr())
        strHex = v.getValStr();
    if (!IsHex(strHex))
        throw std::runtime_error(strName + " must be hexadecimal string (not '" + strHex + "')");
    return ParseHex(strHex);
}

int ParseSighashString(const UniValue& sighash)
{
    int hash_type = SIGHASH_ALL;
    if (!sighash.isNull()) {
        static std::map<std::string, int> map_sighash_values = {
            {std::string("ALL"), int(SIGHASH_ALL)},
            {std::string("ALL|ANYONECANPAY"), int(SIGHASH_ALL|SIGHASH_ANYONECANPAY)},
            {std::string("NONE"), int(SIGHASH_NONE)},
            {std::string("NONE|ANYONECANPAY"), int(SIGHASH_NONE|SIGHASH_ANYONECANPAY)},
            {std::string("SINGLE"), int(SIGHASH_SINGLE)},
            {std::string("SINGLE|ANYONECANPAY"), int(SIGHASH_SINGLE|SIGHASH_ANYONECANPAY)},
        };
        std::string strHashType = sighash.get_str();
        const auto& it = map_sighash_values.find(strHashType);
        if (it != map_sighash_values.end()) {
            hash_type = it->second;
        } else {
            throw std::runtime_error(strHashType + " is not a valid sighash parameter.");
        }
    }
    return hash_type;
}
<|endoftext|>


<commit_before>//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------

// RUN: mkdir -p %T/subdir && clang -DCLING_EXPORT=%dllexport -shared %S/call_lib.c -o %T/subdir/libtest%shlibext
// RUN: cat %s | %cling -I %S -DENVVAR_LIB="\"%/T/subdir\"" -DENVVAR_INC="\"%/p/subdir\"" -Xclang -verify 2>&1 | FileCheck %s

extern "C" int cling_testlibrary_function();

// For gcc setenv
#ifndef __THROW
 #define __THROW
#endif
extern "C" int setenv(const char *name, const char *value, int overwrite) __THROW;
extern "C" int _putenv_s(const char *name, const char *value);
static void setup() {
#ifdef _WIN32
 #define setenv(n, v, o) _putenv_s(n,v)
#endif
  ::setenv("ENVVAR_INC", ENVVAR_INC, 1);
  ::setenv("ENVVAR_LIB", ENVVAR_LIB, 1);
}
setup();

#pragma cling add_include_path("$ENVVAR_INC")
#include "Include_header.h"
include_test()
// CHECK: OK(int) 0

#pragma cling add_library_path("$ENVVAR_LIB")
#pragma cling load("libtest")
cling_testlibrary_function()
// CHECK: (int) 66

#pragma cling add_library_path("$NONEXISTINGVARNAME")
//expected-no-diagnostics
<commit_msg>Fix setenv declaration for gcc on OS X.<commit_after>//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------

// RUN: mkdir -p %T/subdir && clang -DCLING_EXPORT=%dllexport -shared %S/call_lib.c -o %T/subdir/libtest%shlibext
// RUN: cat %s | %cling -I %S -DENVVAR_LIB="\"%/T/subdir\"" -DENVVAR_INC="\"%/p/subdir\"" -Xclang -verify 2>&1 | FileCheck %s

extern "C" int cling_testlibrary_function();

#ifndef _WIN32
 #include <stdlib.h>
#else
 extern "C" int _putenv_s(const char *name, const char *value);
 #define setenv(n, v, o) _putenv_s(n,v)
#endif

::setenv("ENVVAR_INC", ENVVAR_INC, 1);
::setenv("ENVVAR_LIB", ENVVAR_LIB, 1);

#pragma cling add_include_path("$ENVVAR_INC")
#include "Include_header.h"
include_test()
// CHECK: OK(int) 0

#pragma cling add_library_path("$ENVVAR_LIB")
#pragma cling load("libtest")
cling_testlibrary_function()
// CHECK: (int) 66

#pragma cling add_library_path("$NONEXISTINGVARNAME")
//expected-no-diagnostics
<|endoftext|>


<commit_before>#include <FL/fl_draw.H>
#include <FL/x.H>
#include "settings.hpp"
#include "gpxlayer.hpp"
#include "wgt_eleprofile.hpp"

wgt_eleprofile::wgt_eleprofile(int x, int y, int w, int h, const char *label) :
    Fl_Widget(x, y, w, h, label),
    m_offscreen(w, h)
{
}

wgt_eleprofile::~wgt_eleprofile()
{
}

void wgt_eleprofile::trackpoints(const std::vector<gpxlayer::waypoint>& wpts)
{
    double dst = 0.0;
    m_elemin = 0.0;
    m_elemax = 0.0;

    m_wpts.clear();

    std::vector<gpxlayer::waypoint>::const_iterator it;
    for (it=wpts.begin();it!=wpts.end();++it)
    {
        point2d<double> ptmp;
        ptmp.y((*it).elevation());

        if (ptmp.y() < m_elemin)
            m_elemin = ptmp.y();
        if (ptmp.y() > m_elemax)
            m_elemax = ptmp.y();

        if (it != wpts.begin())
        {
            dst += utils::dist(
                point2d<double>((*it).lon(), (*it).lat()),
                point2d<double>((*(it-1)).lon(), (*(it-1)).lat()));
        }

        ptmp.x(dst);
        m_wpts.push_back(ptmp);
    }
}

void wgt_eleprofile::refresh()
{
    redraw();
}

int wgt_eleprofile::handle_move(int event)
{
    if (m_wpts.size() <= 1)
        return 0;

    int posx = Fl::event_x()-x();
    int posy = h() - (Fl::event_y()-y());

    double yscale = ((m_elemax-m_elemin) > 0.0) ? ((double)h())/(m_elemax-m_elemin) : 0.0;
    double xscale = ((*(m_wpts.end()-1)).x() > 0.0) ? ((double)w())/(*(m_wpts.end()-1)).x() : 0.0;

    double trip = (xscale > 0.0) ? posx/xscale : 0.0;
    double ele = (yscale > 0.0) ? posy/yscale : 0.0;

    notify_mouse(trip, ele);
    return 1;
}

int wgt_eleprofile::handle_enter(int event)
{
    fl_cursor(FL_CURSOR_CROSS);
    return 1;
}

int wgt_eleprofile::handle_leave(int event)
{
    fl_cursor(FL_CURSOR_DEFAULT);
    notify_mouse(0.0, 0.0);
    return 1;
}

int wgt_eleprofile::handle(int event)
{
    int ret = 0;

    switch (event) {
        case FL_MOVE:
            {
                ret = handle_move(event);
                break;
            }
        case FL_ENTER:
            {
                ret = handle_enter(event);
                break;
            }
        case FL_LEAVE:
            {
                ret = handle_leave(event);
                break;
            }
        case FL_PUSH:
            {
                //handle_push(event);

                // The push event always needs to return 1, otherwise dragging
                // will not work
                ret = 1;
                break;
            }
        case FL_RELEASE:
            {
                //ret = handle_release(event);
                break;
            }
        case FL_DRAG:
            {
                //ret = handle_drag(event);
                break;
            }
        case FL_MOUSEWHEEL:
            {
                //ret = handle_mousewheel(event);
                break;
            }
        case FL_FOCUS:
            {
                // Focus is accepted
                //ret = 1;
                break;
            }
        case FL_KEYBOARD:
            {
                //ret = handle_keyboard(event);
                break;
            }
    }

    return ret;
}

void wgt_eleprofile::notify_mouse(double trip, double ele)
{
    event_mouse e(trip, ele);
    fire(&e);
}

void wgt_eleprofile::draw()
{
    // Make sure redraw() has been called previously
    if ((damage() & FL_DAMAGE_ALL) == 0)
        return;

    // resize the offscreent o match the viewport
    m_offscreen.resize(w(), h());

    // Draw the profile
    draw_profile();

    fl_copy_offscreen(x(), y(), w(), h(), m_offscreen.buf(), 0, 0);
}

void wgt_eleprofile::draw_profile()
{
    m_offscreen.fgcolor(fgfx::color(0xff,0xff,0xff));
    m_offscreen.fillrect(0,0,w(),h());

    if (m_wpts.size() <= 1)
        return;

    double corr = (m_elemin < 0) ? -m_elemin : 0.0;
    double min = m_elemin + corr;
    double max = m_elemax + corr;

    double yscale = ((max-min) > 0.0) ? ((double)h())/(max-min) : 0.0;
    double xscale = ((*(m_wpts.end()-1)).x() > 0.0) ? ((double)w())/(*(m_wpts.end()-1)).x() : 0.0;

    m_offscreen.fgcolor(fgfx::color(0xff,0x00,0x00));

    double elast = 0.0;
    std::vector< point2d<double> >::iterator it;
    for (it=m_wpts.begin();it!=m_wpts.end();++it)
    {
        double ecurrent = (*it).y() + corr;

        if (it == m_wpts.begin())
        {
            elast = (*it).y() + corr;
            continue;
        }

        m_offscreen.line(
                (int)((*(it-1)).x()*xscale), h()-(int)(elast*yscale),
                (int)((*it).x()*xscale), h()-(int)(ecurrent*yscale),
                1);

        elast = ecurrent;
    }
}

<commit_msg>Bugfix for negative elevation values in the profile viewer.<commit_after>#include <FL/fl_draw.H>
#include <FL/x.H>
#include "settings.hpp"
#include "gpxlayer.hpp"
#include "wgt_eleprofile.hpp"

wgt_eleprofile::wgt_eleprofile(int x, int y, int w, int h, const char *label) :
    Fl_Widget(x, y, w, h, label),
    m_offscreen(w, h)
{
}

wgt_eleprofile::~wgt_eleprofile()
{
}

void wgt_eleprofile::trackpoints(const std::vector<gpxlayer::waypoint>& wpts)
{
    double dst = 0.0;
    m_elemin = 0.0;
    m_elemax = 0.0;

    m_wpts.clear();

    std::vector<gpxlayer::waypoint>::const_iterator it;
    for (it=wpts.begin();it!=wpts.end();++it)
    {
        point2d<double> ptmp;
        ptmp.y((*it).elevation());

        if (ptmp.y() < m_elemin)
            m_elemin = ptmp.y();
        if (ptmp.y() > m_elemax)
            m_elemax = ptmp.y();

        if (it != wpts.begin())
        {
            dst += utils::dist(
                point2d<double>((*it).lon(), (*it).lat()),
                point2d<double>((*(it-1)).lon(), (*(it-1)).lat()));
        }

        ptmp.x(dst);
        m_wpts.push_back(ptmp);
    }
}

void wgt_eleprofile::refresh()
{
    redraw();
}

int wgt_eleprofile::handle_move(int event)
{
    if (m_wpts.size() <= 1)
        return 0;

    int posx = Fl::event_x()-x();
    int posy = h() - (Fl::event_y()-y());

    double yscale = ((m_elemax-m_elemin) > 0.0) ? ((double)h())/(m_elemax-m_elemin) : 0.0;
    double xscale = ((*(m_wpts.end()-1)).x() > 0.0) ? ((double)w())/(*(m_wpts.end()-1)).x() : 0.0;

    double trip = (xscale > 0.0) ? posx/xscale : 0.0;
    double ele = (yscale > 0.0) ? posy/yscale : 0.0;

    if (m_elemin < 0)
        ele += m_elemin;

    notify_mouse(trip, ele);
    return 1;
}

int wgt_eleprofile::handle_enter(int event)
{
    fl_cursor(FL_CURSOR_CROSS);
    return 1;
}

int wgt_eleprofile::handle_leave(int event)
{
    fl_cursor(FL_CURSOR_DEFAULT);
    notify_mouse(0.0, 0.0);
    return 1;
}

int wgt_eleprofile::handle(int event)
{
    int ret = 0;

    switch (event) {
        case FL_MOVE:
            {
                ret = handle_move(event);
                break;
            }
        case FL_ENTER:
            {
                ret = handle_enter(event);
                break;
            }
        case FL_LEAVE:
            {
                ret = handle_leave(event);
                break;
            }
        case FL_PUSH:
            {
                //handle_push(event);

                // The push event always needs to return 1, otherwise dragging
                // will not work
                ret = 1;
                break;
            }
        case FL_RELEASE:
            {
                //ret = handle_release(event);
                break;
            }
        case FL_DRAG:
            {
                //ret = handle_drag(event);
                break;
            }
        case FL_MOUSEWHEEL:
            {
                //ret = handle_mousewheel(event);
                break;
            }
        case FL_FOCUS:
            {
                // Focus is accepted
                //ret = 1;
                break;
            }
        case FL_KEYBOARD:
            {
                //ret = handle_keyboard(event);
                break;
            }
    }

    return ret;
}

void wgt_eleprofile::notify_mouse(double trip, double ele)
{
    event_mouse e(trip, ele);
    fire(&e);
}

void wgt_eleprofile::draw()
{
    // Make sure redraw() has been called previously
    if ((damage() & FL_DAMAGE_ALL) == 0)
        return;

    // resize the offscreent o match the viewport
    m_offscreen.resize(w(), h());

    // Draw the profile
    draw_profile();

    fl_copy_offscreen(x(), y(), w(), h(), m_offscreen.buf(), 0, 0);
}

void wgt_eleprofile::draw_profile()
{
    m_offscreen.fgcolor(fgfx::color(0xff,0xff,0xff));
    m_offscreen.fillrect(0,0,w(),h());

    if (m_wpts.size() <= 1)
        return;

    double corr = (m_elemin < 0) ? -m_elemin : 0.0;
    double min = m_elemin + corr;
    double max = m_elemax + corr;

    double yscale = ((max-min) > 0.0) ? ((double)h())/(max-min) : 0.0;
    double xscale = ((*(m_wpts.end()-1)).x() > 0.0) ? ((double)w())/(*(m_wpts.end()-1)).x() : 0.0;

    m_offscreen.fgcolor(fgfx::color(0xff,0x00,0x00));

    double elast = 0.0;
    std::vector< point2d<double> >::iterator it;
    for (it=m_wpts.begin();it!=m_wpts.end();++it)
    {
        double ecurrent = (*it).y() + corr;

        if (it == m_wpts.begin())
        {
            elast = (*it).y() + corr;
            continue;
        }

        m_offscreen.line(
                (int)((*(it-1)).x()*xscale), h()-(int)(elast*yscale),
                (int)((*it).x()*xscale), h()-(int)(ecurrent*yscale),
                1);

        elast = ecurrent;
    }
}

<|endoftext|>


<commit_before>/*      _______   __   __   __   ______   __   __   _______   __   __
 *     / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___  /\ /  |\/ /\
 *    / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
 *   / / /__   / / // / // / // / /    / ___  / // ___  / // /| ' / /
 *  / /_// /\ / /_// / // / // /_/_   / / // / // /\_/ / // / |  / /
 * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
 * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
 *
 * Copyright (c) 2004, 2005, 2006 Olof Naessn and Per Larsson
 *
 *                                                         Js_./
 * Per Larsson a.k.a finalman                          _RqZ{a<^_aa
 * Olof Naessn a.k.a jansem/yakslem                _asww7!uY`>  )\a//
 *                                                 _Qhm`] _f "'c  1!5m
 * Visit: http://guichan.darkbits.org             )Qk<P ` _: :+' .'  "{[
 *                                               .)j(] .d_/ '-(  P .   S
 * License: (BSD)                                <Td/Z <fP"5(\"??"\a.  .L
 * Redistribution and use in source and          _dV>ws?a-?'      ._/L  #'
 * binary forms, with or without                 )4d[#7r, .   '     )d`)[
 * modification, are permitted provided         _Q-5'5W..j/?'   -?!\)cam'
 * that the following conditions are met:       j<<WP+k/);.        _W=j f
 * 1. Redistributions of source code must       .$%w\/]Q  . ."'  .  mj$
 *    retain the above copyright notice,        ]E.pYY(Q]>.   a     J@\
 *    this list of conditions and the           j(]1u<sE"L,. .   ./^ ]{a
 *    following disclaimer.                     4'_uomm\.  )L);-4     (3=
 * 2. Redistributions in binary form must        )_]X{Z('a_"a7'<a"a,  ]"[
 *    reproduce the above copyright notice,       #}<]m7`Za??4,P-"'7. ).m
 *    this list of conditions and the            ]d2e)Q(<Q(  ?94   b-  LQ/
 *    following disclaimer in the                <B!</]C)d_, '(<' .f. =C+m
 *    documentation and/or other materials      .Z!=J ]e []('-4f _ ) -.)m]'
 *    provided with the distribution.          .w[5]' _[ /.)_-"+?   _/ <W"
 * 3. Neither the name of Guichan nor the      :$we` _! + _/ .        j?
 *    names of its contributors may be used     =3)= _f  (_yQmWW$#(    "
 *    to endorse or promote products derived     -   W,  sQQQQmZQ#Wwa]..
 *    from this software without specific        (js, \[QQW$QWW#?!V"".
 *    prior written permission.                    ]y:.<\..          .
 *                                                 -]n w/ '         [.
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT       )/ )/           !
 * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY         <  (; sac    ,    '
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING,               ]^ .-  %
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF            c <   r
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR            aga<  <La
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE          5%  )P'-3L
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR        _bQf` y`..)a
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,          ,J?4P'.P"_(\?d'.,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES               _Pa,)!f/<[]/  ?"
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT      _2-..:. .r+_,.. .
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,     ?a.<%"'  " -'.a_ _,
 * 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.
 */

/*
 * For comments regarding functions please see the header file.
 */

#include "guichan/widgets/window.hpp"

#include "guichan/exception.hpp"
#include "guichan/font.hpp"
#include "guichan/graphics.hpp"
#include "guichan/mouseinput.hpp"

#include <iostream>

namespace gcn
{
    Window::Window()
            :mIsMoving(false)
    {
        setBorderSize(1);
        setPadding(2);
        setTitleBarHeight(16);
        setAlignment(Graphics::CENTER);
        addMouseListener(this);
        setMovable(true);
        setOpaque(true);
        setFocusable(true);
    }

    Window::Window(const std::string& caption)
            :mIsMoving(false)
    {
        setCaption(caption);
        setBorderSize(1);
        setPadding(2);
        setTitleBarHeight(16);
        setAlignment(Graphics::CENTER);
        addMouseListener(this);
        setMovable(true);
        setOpaque(true);
        setFocusable(true);
    }

    Window::~Window()
    {
    }

    void Window::setPadding(unsigned int padding)
    {
        mPadding = padding;
    }

    unsigned int Window::getPadding() const
    {
        return mPadding;
    }

    void Window::setTitleBarHeight(unsigned int height)
    {
        mTitleBarHeight = height;
    }

    unsigned int Window::getTitleBarHeight()
    {
        return mTitleBarHeight;
    }

    void Window::setCaption(const std::string& caption)
    {
        mCaption = caption;
    }

    const std::string& Window::getCaption() const
    {
        return mCaption;
    }

    void Window::setAlignment(unsigned int alignment)
    {
        mAlignment = alignment;
    }

    unsigned int Window::getAlignment() const
    {
        return mAlignment;
    }

    void Window::draw(Graphics* graphics)
    {
        Color faceColor = getBaseColor();
        Color highlightColor, shadowColor;
        int alpha = getBaseColor().a;
        int width = getWidth() + getBorderSize() * 2 - 1;
        int height = getHeight() + getBorderSize() * 2 - 1;
        highlightColor = faceColor + 0x303030;
        highlightColor.a = alpha;
        shadowColor = faceColor - 0x303030;
        shadowColor.a = alpha;

        Rectangle d = getChildrenArea();

        // Fill the background around the content
        graphics->setColor(faceColor);
        // Fill top
        graphics->fillRectangle(Rectangle(0,0,getWidth(),d.y - 1));
        // Fill left
        graphics->fillRectangle(Rectangle(0,d.y - 1, d.x - 1, getHeight() - d.y + 1));
        // Fill right
        graphics->fillRectangle(Rectangle(d.x + d.width + 1,
                                          d.y - 1,
                                          getWidth() - d.x - d.width - 1,
                                          getHeight() - d.y + 1));
        // Fill bottom
        graphics->fillRectangle(Rectangle(d.x - 1,
                                          d.y + d.height + 1,
                                          d.width + 2,
                                          getHeight() - d.height - d.y - 1));

        if (isOpaque())
        {
            graphics->fillRectangle(d);
        }

        // Construct a rectangle one pixel bigger than the content
        d.x -= 1;
        d.y -= 1;
        d.width += 2;
        d.height += 2;

        // Draw a border around the content
        graphics->setColor(shadowColor);
        // Top line
        graphics->drawLine(d.x,
                           d.y,
                           d.x + d.width - 2,
                           d.y);

        // Left line
        graphics->drawLine(d.x,
                           d.y + 1,
                           d.x,
                           d.y + d.height - 1);

        graphics->setColor(highlightColor);
        // Right line
        graphics->drawLine(d.x + d.width - 1,
                           d.y,
                           d.x + d.width - 1,
                           d.y + d.height - 2);
        // Bottom line
        graphics->drawLine(d.x + 1,
                           d.y + d.height - 1,
                           d.x + d.width - 1,
                           d.y + d.height - 1);

        drawChildren(graphics);

        int textX;
        int textY;

        textY = ((int)getTitleBarHeight() - getFont()->getHeight()) / 2;

        switch (getAlignment())
        {
          case Graphics::LEFT:
              textX = 4;
              break;
          case Graphics::CENTER:
              textX = getWidth() / 2;
              break;
          case Graphics::RIGHT:
              textX = getWidth() - 4;
              break;
          default:
              throw GCN_EXCEPTION("Unknown alignment.");
        }

        graphics->setColor(getForegroundColor());
        graphics->setFont(getFont());
        graphics->pushClipArea(Rectangle(0, 0, getWidth(), getTitleBarHeight() - 1));
        graphics->drawText(getCaption(), textX, textY, getAlignment());
        graphics->popClipArea();
    }

    void Window::drawBorder(Graphics* graphics)
    {
        Color faceColor = getBaseColor();
        Color highlightColor, shadowColor;
        int alpha = getBaseColor().a;
        int width = getWidth() + getBorderSize() * 2 - 1;
        int height = getHeight() + getBorderSize() * 2 - 1;
        highlightColor = faceColor + 0x303030;
        highlightColor.a = alpha;
        shadowColor = faceColor - 0x303030;
        shadowColor.a = alpha;

        unsigned int i;
        for (i = 0; i < getBorderSize(); ++i)
        {
            graphics->setColor(highlightColor);
            graphics->drawLine(i,i, width - i, i);
            graphics->drawLine(i,i + 1, i, height - i - 1);
            graphics->setColor(shadowColor);
            graphics->drawLine(width - i,i + 1, width - i, height - i);
            graphics->drawLine(i,height - i, width - i - 1, height - i);
        }
    }

    void Window::mousePressed(MouseEvent& mouseEvent)
    {
        if (getParent() != NULL)
        {
            getParent()->moveToTop(this);
        }

        mDragOffsetX = mouseEvent.getX();
        mDragOffsetY = mouseEvent.getY();

        mIsMoving = mouseEvent.getY() <= (int)mTitleBarHeight;

        std::cout << mouseEvent.getY() << " " << mTitleBarHeight << std::endl;
        mouseEvent.consume();
    }

    void Window::mouseDragged(MouseEvent& mouseEvent)
    {
        if (isMovable() && mIsMoving)
        {
            setPosition(mouseEvent.getX() - mDragOffsetX + getX(),
                        mouseEvent.getY() - mDragOffsetY + getY());
        }

        mouseEvent.consume();
    }

    Rectangle Window::getChildrenArea()
    {
        return Rectangle(getPadding(),
                         getTitleBarHeight(),
                         getWidth() - getPadding() * 2,
                         getHeight() - getPadding() - getTitleBarHeight());
    }

    void Window::setMovable(bool movable)
    {
        mMovable = movable;
    }

    bool Window::isMovable() const
    {
        return mMovable;
    }

    void Window::setOpaque(bool opaque)
    {
        mOpaque = opaque;
    }

    bool Window::isOpaque()
    {
        return mOpaque;
    }

    void Window::resizeToContent()
    {
        WidgetListIterator it;

        int w = 0, h = 0;
        for (it = mWidgets.begin(); it != mWidgets.end(); it++)
        {
            if ((*it)->getX() + (*it)->getWidth() > w)
            {
                w = (*it)->getX() + (*it)->getWidth();
            }

            if ((*it)->getY() + (*it)->getHeight() > h)
            {
                h = (*it)->getY() + (*it)->getHeight();
            }
        }

        setSize(w + 2* getPadding(), h + getPadding() + getTitleBarHeight());
    }
}
<commit_msg>Debug printing has been removed.<commit_after>/*      _______   __   __   __   ______   __   __   _______   __   __
 *     / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___  /\ /  |\/ /\
 *    / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
 *   / / /__   / / // / // / // / /    / ___  / // ___  / // /| ' / /
 *  / /_// /\ / /_// / // / // /_/_   / / // / // /\_/ / // / |  / /
 * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
 * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
 *
 * Copyright (c) 2004, 2005, 2006 Olof Naessn and Per Larsson
 *
 *                                                         Js_./
 * Per Larsson a.k.a finalman                          _RqZ{a<^_aa
 * Olof Naessn a.k.a jansem/yakslem                _asww7!uY`>  )\a//
 *                                                 _Qhm`] _f "'c  1!5m
 * Visit: http://guichan.darkbits.org             )Qk<P ` _: :+' .'  "{[
 *                                               .)j(] .d_/ '-(  P .   S
 * License: (BSD)                                <Td/Z <fP"5(\"??"\a.  .L
 * Redistribution and use in source and          _dV>ws?a-?'      ._/L  #'
 * binary forms, with or without                 )4d[#7r, .   '     )d`)[
 * modification, are permitted provided         _Q-5'5W..j/?'   -?!\)cam'
 * that the following conditions are met:       j<<WP+k/);.        _W=j f
 * 1. Redistributions of source code must       .$%w\/]Q  . ."'  .  mj$
 *    retain the above copyright notice,        ]E.pYY(Q]>.   a     J@\
 *    this list of conditions and the           j(]1u<sE"L,. .   ./^ ]{a
 *    following disclaimer.                     4'_uomm\.  )L);-4     (3=
 * 2. Redistributions in binary form must        )_]X{Z('a_"a7'<a"a,  ]"[
 *    reproduce the above copyright notice,       #}<]m7`Za??4,P-"'7. ).m
 *    this list of conditions and the            ]d2e)Q(<Q(  ?94   b-  LQ/
 *    following disclaimer in the                <B!</]C)d_, '(<' .f. =C+m
 *    documentation and/or other materials      .Z!=J ]e []('-4f _ ) -.)m]'
 *    provided with the distribution.          .w[5]' _[ /.)_-"+?   _/ <W"
 * 3. Neither the name of Guichan nor the      :$we` _! + _/ .        j?
 *    names of its contributors may be used     =3)= _f  (_yQmWW$#(    "
 *    to endorse or promote products derived     -   W,  sQQQQmZQ#Wwa]..
 *    from this software without specific        (js, \[QQW$QWW#?!V"".
 *    prior written permission.                    ]y:.<\..          .
 *                                                 -]n w/ '         [.
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT       )/ )/           !
 * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY         <  (; sac    ,    '
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING,               ]^ .-  %
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF            c <   r
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR            aga<  <La
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE          5%  )P'-3L
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR        _bQf` y`..)a
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,          ,J?4P'.P"_(\?d'.,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES               _Pa,)!f/<[]/  ?"
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT      _2-..:. .r+_,.. .
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,     ?a.<%"'  " -'.a_ _,
 * 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.
 */

/*
 * For comments regarding functions please see the header file.
 */

#include "guichan/widgets/window.hpp"

#include "guichan/exception.hpp"
#include "guichan/font.hpp"
#include "guichan/graphics.hpp"
#include "guichan/mouseinput.hpp"

namespace gcn
{
    Window::Window()
            :mIsMoving(false)
    {
        setBorderSize(1);
        setPadding(2);
        setTitleBarHeight(16);
        setAlignment(Graphics::CENTER);
        addMouseListener(this);
        setMovable(true);
        setOpaque(true);
        setFocusable(true);
    }

    Window::Window(const std::string& caption)
            :mIsMoving(false)
    {
        setCaption(caption);
        setBorderSize(1);
        setPadding(2);
        setTitleBarHeight(16);
        setAlignment(Graphics::CENTER);
        addMouseListener(this);
        setMovable(true);
        setOpaque(true);
        setFocusable(true);
    }

    Window::~Window()
    {
    }

    void Window::setPadding(unsigned int padding)
    {
        mPadding = padding;
    }

    unsigned int Window::getPadding() const
    {
        return mPadding;
    }

    void Window::setTitleBarHeight(unsigned int height)
    {
        mTitleBarHeight = height;
    }

    unsigned int Window::getTitleBarHeight()
    {
        return mTitleBarHeight;
    }

    void Window::setCaption(const std::string& caption)
    {
        mCaption = caption;
    }

    const std::string& Window::getCaption() const
    {
        return mCaption;
    }

    void Window::setAlignment(unsigned int alignment)
    {
        mAlignment = alignment;
    }

    unsigned int Window::getAlignment() const
    {
        return mAlignment;
    }

    void Window::draw(Graphics* graphics)
    {
        Color faceColor = getBaseColor();
        Color highlightColor, shadowColor;
        int alpha = getBaseColor().a;
        int width = getWidth() + getBorderSize() * 2 - 1;
        int height = getHeight() + getBorderSize() * 2 - 1;
        highlightColor = faceColor + 0x303030;
        highlightColor.a = alpha;
        shadowColor = faceColor - 0x303030;
        shadowColor.a = alpha;

        Rectangle d = getChildrenArea();

        // Fill the background around the content
        graphics->setColor(faceColor);
        // Fill top
        graphics->fillRectangle(Rectangle(0,0,getWidth(),d.y - 1));
        // Fill left
        graphics->fillRectangle(Rectangle(0,d.y - 1, d.x - 1, getHeight() - d.y + 1));
        // Fill right
        graphics->fillRectangle(Rectangle(d.x + d.width + 1,
                                          d.y - 1,
                                          getWidth() - d.x - d.width - 1,
                                          getHeight() - d.y + 1));
        // Fill bottom
        graphics->fillRectangle(Rectangle(d.x - 1,
                                          d.y + d.height + 1,
                                          d.width + 2,
                                          getHeight() - d.height - d.y - 1));

        if (isOpaque())
        {
            graphics->fillRectangle(d);
        }

        // Construct a rectangle one pixel bigger than the content
        d.x -= 1;
        d.y -= 1;
        d.width += 2;
        d.height += 2;

        // Draw a border around the content
        graphics->setColor(shadowColor);
        // Top line
        graphics->drawLine(d.x,
                           d.y,
                           d.x + d.width - 2,
                           d.y);

        // Left line
        graphics->drawLine(d.x,
                           d.y + 1,
                           d.x,
                           d.y + d.height - 1);

        graphics->setColor(highlightColor);
        // Right line
        graphics->drawLine(d.x + d.width - 1,
                           d.y,
                           d.x + d.width - 1,
                           d.y + d.height - 2);
        // Bottom line
        graphics->drawLine(d.x + 1,
                           d.y + d.height - 1,
                           d.x + d.width - 1,
                           d.y + d.height - 1);

        drawChildren(graphics);

        int textX;
        int textY;

        textY = ((int)getTitleBarHeight() - getFont()->getHeight()) / 2;

        switch (getAlignment())
        {
          case Graphics::LEFT:
              textX = 4;
              break;
          case Graphics::CENTER:
              textX = getWidth() / 2;
              break;
          case Graphics::RIGHT:
              textX = getWidth() - 4;
              break;
          default:
              throw GCN_EXCEPTION("Unknown alignment.");
        }

        graphics->setColor(getForegroundColor());
        graphics->setFont(getFont());
        graphics->pushClipArea(Rectangle(0, 0, getWidth(), getTitleBarHeight() - 1));
        graphics->drawText(getCaption(), textX, textY, getAlignment());
        graphics->popClipArea();
    }

    void Window::drawBorder(Graphics* graphics)
    {
        Color faceColor = getBaseColor();
        Color highlightColor, shadowColor;
        int alpha = getBaseColor().a;
        int width = getWidth() + getBorderSize() * 2 - 1;
        int height = getHeight() + getBorderSize() * 2 - 1;
        highlightColor = faceColor + 0x303030;
        highlightColor.a = alpha;
        shadowColor = faceColor - 0x303030;
        shadowColor.a = alpha;

        unsigned int i;
        for (i = 0; i < getBorderSize(); ++i)
        {
            graphics->setColor(highlightColor);
            graphics->drawLine(i,i, width - i, i);
            graphics->drawLine(i,i + 1, i, height - i - 1);
            graphics->setColor(shadowColor);
            graphics->drawLine(width - i,i + 1, width - i, height - i);
            graphics->drawLine(i,height - i, width - i - 1, height - i);
        }
    }

    void Window::mousePressed(MouseEvent& mouseEvent)
    {
        if (getParent() != NULL)
        {
            getParent()->moveToTop(this);
        }

        mDragOffsetX = mouseEvent.getX();
        mDragOffsetY = mouseEvent.getY();

        mIsMoving = mouseEvent.getY() <= (int)mTitleBarHeight;

        mouseEvent.consume();
    }

    void Window::mouseDragged(MouseEvent& mouseEvent)
    {
        if (isMovable() && mIsMoving)
        {
            setPosition(mouseEvent.getX() - mDragOffsetX + getX(),
                        mouseEvent.getY() - mDragOffsetY + getY());
        }

        mouseEvent.consume();
    }

    Rectangle Window::getChildrenArea()
    {
        return Rectangle(getPadding(),
                         getTitleBarHeight(),
                         getWidth() - getPadding() * 2,
                         getHeight() - getPadding() - getTitleBarHeight());
    }

    void Window::setMovable(bool movable)
    {
        mMovable = movable;
    }

    bool Window::isMovable() const
    {
        return mMovable;
    }

    void Window::setOpaque(bool opaque)
    {
        mOpaque = opaque;
    }

    bool Window::isOpaque()
    {
        return mOpaque;
    }

    void Window::resizeToContent()
    {
        WidgetListIterator it;

        int w = 0, h = 0;
        for (it = mWidgets.begin(); it != mWidgets.end(); it++)
        {
            if ((*it)->getX() + (*it)->getWidth() > w)
            {
                w = (*it)->getX() + (*it)->getWidth();
            }

            if ((*it)->getY() + (*it)->getHeight() > h)
            {
                h = (*it)->getY() + (*it)->getHeight();
            }
        }

        setSize(w + 2* getPadding(), h + getPadding() + getTitleBarHeight());
    }
}
<|endoftext|>