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

  Program:   Visualization Toolkit
  Module:    vtkImageConvolve.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$
  Thanks:    Thanks to Zeger F. Knops who developed this class

Copyright (c) 1993-2001 Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above copyright notice,
   this list of conditions and the following disclaimer.

 * Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

 * Neither name of Ken Martin, Will Schroeder, or Bill Lorensen nor the names
   of any contributors may be used to endorse or promote products derived
   from this software without specific prior written permission.

 * Modified source versions must be plainly marked as such, and must not be
   misrepresented as being the original software.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

=========================================================================*/
#include <math.h>

#include "vtkImageConvolve.h"
#include "vtkObjectFactory.h"

//-------------------------------------------------------------------------
vtkImageConvolve* vtkImageConvolve::New()
{
  // First try to create the object from the vtkObjectFactory
  vtkObject* ret = vtkObjectFactory::CreateInstance("vtkImageConvolve");
  if(ret)
    {
    return (vtkImageConvolve*)ret;
    }
  // If the factory was unable to create the object, then create it here.
  return new vtkImageConvolve;
}

//-------------------------------------------------------------------------
// Construct an instance of vtkImageLaplacian fitler.
vtkImageConvolve::vtkImageConvolve()
{
  this->Dimensionality = 2;

  this->Kernel[0] = 1.0;
  this->Kernel[1] = 0.0;
  this->Kernel[2] = 1.0;

}

//----------------------------------------------------------------------------
void vtkImageConvolve::PrintSelf(ostream& os, vtkIndent indent)
{
  this->vtkImageToImageFilter::PrintSelf(os, indent);
  os << indent << "Dimensionality: " << this->Dimensionality;
}

//----------------------------------------------------------------------------
// Just clip the request.  The subclass may need to overwrite this method.
void vtkImageConvolve::ComputeInputUpdateExtent(int inExt[6],
						 int outExt[6])
{
  int idx;
  int *wholeExtent;

  // handle XYZ
  memcpy(inExt,outExt,sizeof(int)*6);

  wholeExtent = this->GetInput()->GetWholeExtent();
  // update and Clip
  for (idx = 0; idx < 3; ++idx)
    {
    --inExt[idx*2];
    ++inExt[idx*2+1];
    if (inExt[idx*2] < wholeExtent[idx*2])
      {
      inExt[idx*2] = wholeExtent[idx*2];
      }
    if (inExt[idx*2] > wholeExtent[idx*2 + 1])
      {
      inExt[idx*2] = wholeExtent[idx*2 + 1];
      }
    if (inExt[idx*2+1] < wholeExtent[idx*2])
      {
      inExt[idx*2+1] = wholeExtent[idx*2];
      }
    if (inExt[idx*2 + 1] > wholeExtent[idx*2 + 1])
      {
      inExt[idx*2 + 1] = wholeExtent[idx*2 + 1];
      }
    }
}

//----------------------------------------------------------------------------
// This execute method handles boundaries.  Pixels are just replicated to get
// values out of extent.
template <class T>
static void vtkImageConvolveExecute(vtkImageConvolve *self,
				      vtkImageData *inData, T *inPtr,
				      vtkImageData *outData, T *outPtr,
				      int outExt[6], int id)
{
  int idxC, idxX, idxY, idxZ;
  int maxC, maxX, maxY, maxZ;
  int inIncX, inIncY, inIncZ;
  int outIncX, outIncY, outIncZ;
  unsigned long count = 0;
  unsigned long target;
  int axesNum;
  int *wholeExtent, *inIncs;
  float sum, kernel[3];
  int useZMin, useZMax, useYMin, useYMax, useXMin, useXMax;

  // find the region to loop over
  maxC = inData->GetNumberOfScalarComponents();
  maxX = outExt[1] - outExt[0];
  maxY = outExt[3] - outExt[2];
  maxZ = outExt[5] - outExt[4];
  target = (unsigned long)((maxZ+1)*(maxY+1)/50.0);
  target++;

  // Get the kernel
  self->GetKernel( kernel );

  // Get the dimensionality of the gradient.
  axesNum = self->GetDimensionality();

  // Get increments to march through data
  inData->GetContinuousIncrements(outExt, inIncX, inIncY, inIncZ);
  outData->GetContinuousIncrements(outExt, outIncX, outIncY, outIncZ);

  // get some other info we need
  inIncs = inData->GetIncrements();
  wholeExtent = inData->GetExtent();

  // Loop through ouput pixels
  for (idxZ = 0; idxZ <= maxZ; idxZ++)
    {
    useZMin = ((idxZ + outExt[4]) <= wholeExtent[4]) ? 0 : -inIncs[2];
    useZMax = ((idxZ + outExt[4]) >= wholeExtent[5]) ? 0 : inIncs[2];

    for (idxY = 0; !self->AbortExecute && idxY <= maxY; idxY++)
      {
      if (!id)
        {
        if (!(count%target))
          {
          self->UpdateProgress(count/(50.0*target));
          }
        count++;
        }

      useYMin = ((idxY + outExt[2]) <= wholeExtent[2]) ? 0 : -inIncs[1];
      useYMax = ((idxY + outExt[2]) >= wholeExtent[3]) ? 0 : inIncs[1];

      for (idxX = 0; idxX <= maxX; idxX++)
        {
        useXMin = ((idxX + outExt[0]) <= wholeExtent[0]) ? 0 : -inIncs[0];
        useXMax = ((idxX + outExt[0]) >= wholeExtent[1]) ? 0 : inIncs[0];

        for (idxC = 0; idxC < maxC; idxC++)
          {
          //the center kernel position
          sum = kernel[1]*(*inPtr);

          // do X axis
          sum += kernel[0]*(float)(inPtr[useXMin]);
          sum += kernel[2]*(float)(inPtr[useXMax]);

          // do Y axis
          sum += kernel[0]*(float)(inPtr[useYMin]);
          sum += kernel[2]*(float)(inPtr[useYMax]);

          if (axesNum == 3)
            {
            // do z axis
            sum += kernel[0]*(float)(inPtr[useZMin]);
            sum += kernel[2]*(float)(inPtr[useZMax]);
            }

          *outPtr = (T)sum;
          inPtr++;
          outPtr++;
          }
        }

      outPtr += outIncY;
      inPtr += inIncY;
      }

    outPtr += outIncZ;
    inPtr += inIncZ;
    }
}

//----------------------------------------------------------------------------
// This method contains a switch statement that calls the correct
// templated function for the input data type.  The output data
// must match input type.  This method does handle boundary conditions.
void vtkImageConvolve::ThreadedExecute(vtkImageData *inData,
					vtkImageData *outData,
					   int outExt[6], int id)
{
  void *inPtr = inData->GetScalarPointerForExtent(outExt);
  void *outPtr = outData->GetScalarPointerForExtent(outExt);

  vtkDebugMacro(<< "Execute: inData = " << inData
                << ", outData = " << outData);

  // this filter expects that input is the same type as output.
  if (inData->GetScalarType() != outData->GetScalarType())
    {
    vtkErrorMacro(<< "Execute: input ScalarType, " << inData->GetScalarType()
                  << ", must match out ScalarType " << outData->GetScalarType());
    return;
    }

  switch (inData->GetScalarType())
    {
    vtkTemplateMacro7(vtkImageConvolveExecute, this, inData,
                      (VTK_TT *)(inPtr), outData, (VTK_TT *)(outPtr),
                      outExt, id);
    default:
      vtkErrorMacro(<< "Execute: Unknown ScalarType");
      return;
    }
}
<commit_msg>ERR:PrintSelf defect<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkImageConvolve.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$
  Thanks:    Thanks to Zeger F. Knops who developed this class

Copyright (c) 1993-2001 Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above copyright notice,
   this list of conditions and the following disclaimer.

 * Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

 * Neither name of Ken Martin, Will Schroeder, or Bill Lorensen nor the names
   of any contributors may be used to endorse or promote products derived
   from this software without specific prior written permission.

 * Modified source versions must be plainly marked as such, and must not be
   misrepresented as being the original software.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

=========================================================================*/
#include <math.h>

#include "vtkImageConvolve.h"
#include "vtkObjectFactory.h"

//-------------------------------------------------------------------------
vtkImageConvolve* vtkImageConvolve::New()
{
  // First try to create the object from the vtkObjectFactory
  vtkObject* ret = vtkObjectFactory::CreateInstance("vtkImageConvolve");
  if(ret)
    {
    return (vtkImageConvolve*)ret;
    }
  // If the factory was unable to create the object, then create it here.
  return new vtkImageConvolve;
}

//-------------------------------------------------------------------------
// Construct an instance of vtkImageLaplacian fitler.
vtkImageConvolve::vtkImageConvolve()
{
  this->Dimensionality = 2;

  this->Kernel[0] = 1.0;
  this->Kernel[1] = 0.0;
  this->Kernel[2] = 1.0;

}

//----------------------------------------------------------------------------
void vtkImageConvolve::PrintSelf(ostream& os, vtkIndent indent)
{
  this->vtkImageToImageFilter::PrintSelf(os, indent);

  os << indent << "Dimensionality: " << this->Dimensionality;
  os << indent << "Kernel: (" << this->Kernel[0] << ", "
     << this->Kernel[1] << ", " << this->Kernel[2] << ")\n";
}

//----------------------------------------------------------------------------
// Just clip the request.  The subclass may need to overwrite this method.
void vtkImageConvolve::ComputeInputUpdateExtent(int inExt[6],
						 int outExt[6])
{
  int idx;
  int *wholeExtent;

  // handle XYZ
  memcpy(inExt,outExt,sizeof(int)*6);

  wholeExtent = this->GetInput()->GetWholeExtent();
  // update and Clip
  for (idx = 0; idx < 3; ++idx)
    {
    --inExt[idx*2];
    ++inExt[idx*2+1];
    if (inExt[idx*2] < wholeExtent[idx*2])
      {
      inExt[idx*2] = wholeExtent[idx*2];
      }
    if (inExt[idx*2] > wholeExtent[idx*2 + 1])
      {
      inExt[idx*2] = wholeExtent[idx*2 + 1];
      }
    if (inExt[idx*2+1] < wholeExtent[idx*2])
      {
      inExt[idx*2+1] = wholeExtent[idx*2];
      }
    if (inExt[idx*2 + 1] > wholeExtent[idx*2 + 1])
      {
      inExt[idx*2 + 1] = wholeExtent[idx*2 + 1];
      }
    }
}

//----------------------------------------------------------------------------
// This execute method handles boundaries.  Pixels are just replicated to get
// values out of extent.
template <class T>
static void vtkImageConvolveExecute(vtkImageConvolve *self,
				      vtkImageData *inData, T *inPtr,
				      vtkImageData *outData, T *outPtr,
				      int outExt[6], int id)
{
  int idxC, idxX, idxY, idxZ;
  int maxC, maxX, maxY, maxZ;
  int inIncX, inIncY, inIncZ;
  int outIncX, outIncY, outIncZ;
  unsigned long count = 0;
  unsigned long target;
  int axesNum;
  int *wholeExtent, *inIncs;
  float sum, kernel[3];
  int useZMin, useZMax, useYMin, useYMax, useXMin, useXMax;

  // find the region to loop over
  maxC = inData->GetNumberOfScalarComponents();
  maxX = outExt[1] - outExt[0];
  maxY = outExt[3] - outExt[2];
  maxZ = outExt[5] - outExt[4];
  target = (unsigned long)((maxZ+1)*(maxY+1)/50.0);
  target++;

  // Get the kernel
  self->GetKernel( kernel );

  // Get the dimensionality of the gradient.
  axesNum = self->GetDimensionality();

  // Get increments to march through data
  inData->GetContinuousIncrements(outExt, inIncX, inIncY, inIncZ);
  outData->GetContinuousIncrements(outExt, outIncX, outIncY, outIncZ);

  // get some other info we need
  inIncs = inData->GetIncrements();
  wholeExtent = inData->GetExtent();

  // Loop through ouput pixels
  for (idxZ = 0; idxZ <= maxZ; idxZ++)
    {
    useZMin = ((idxZ + outExt[4]) <= wholeExtent[4]) ? 0 : -inIncs[2];
    useZMax = ((idxZ + outExt[4]) >= wholeExtent[5]) ? 0 : inIncs[2];

    for (idxY = 0; !self->AbortExecute && idxY <= maxY; idxY++)
      {
      if (!id)
        {
        if (!(count%target))
          {
          self->UpdateProgress(count/(50.0*target));
          }
        count++;
        }

      useYMin = ((idxY + outExt[2]) <= wholeExtent[2]) ? 0 : -inIncs[1];
      useYMax = ((idxY + outExt[2]) >= wholeExtent[3]) ? 0 : inIncs[1];

      for (idxX = 0; idxX <= maxX; idxX++)
        {
        useXMin = ((idxX + outExt[0]) <= wholeExtent[0]) ? 0 : -inIncs[0];
        useXMax = ((idxX + outExt[0]) >= wholeExtent[1]) ? 0 : inIncs[0];

        for (idxC = 0; idxC < maxC; idxC++)
          {
          //the center kernel position
          sum = kernel[1]*(*inPtr);

          // do X axis
          sum += kernel[0]*(float)(inPtr[useXMin]);
          sum += kernel[2]*(float)(inPtr[useXMax]);

          // do Y axis
          sum += kernel[0]*(float)(inPtr[useYMin]);
          sum += kernel[2]*(float)(inPtr[useYMax]);

          if (axesNum == 3)
            {
            // do z axis
            sum += kernel[0]*(float)(inPtr[useZMin]);
            sum += kernel[2]*(float)(inPtr[useZMax]);
            }

          *outPtr = (T)sum;
          inPtr++;
          outPtr++;
          }
        }

      outPtr += outIncY;
      inPtr += inIncY;
      }

    outPtr += outIncZ;
    inPtr += inIncZ;
    }
}

//----------------------------------------------------------------------------
// This method contains a switch statement that calls the correct
// templated function for the input data type.  The output data
// must match input type.  This method does handle boundary conditions.
void vtkImageConvolve::ThreadedExecute(vtkImageData *inData,
					vtkImageData *outData,
					   int outExt[6], int id)
{
  void *inPtr = inData->GetScalarPointerForExtent(outExt);
  void *outPtr = outData->GetScalarPointerForExtent(outExt);

  vtkDebugMacro(<< "Execute: inData = " << inData
                << ", outData = " << outData);

  // this filter expects that input is the same type as output.
  if (inData->GetScalarType() != outData->GetScalarType())
    {
    vtkErrorMacro(<< "Execute: input ScalarType, " << inData->GetScalarType()
                  << ", must match out ScalarType " << outData->GetScalarType());
    return;
    }

  switch (inData->GetScalarType())
    {
    vtkTemplateMacro7(vtkImageConvolveExecute, this, inData,
                      (VTK_TT *)(inPtr), outData, (VTK_TT *)(outPtr),
                      outExt, id);
    default:
      vtkErrorMacro(<< "Execute: Unknown ScalarType");
      return;
    }
}
<|endoftext|>


<commit_before>/*

Copyright (c) 2010, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#include "test.hpp"
#include "setup_transfer.hpp"
#include "udp_tracker.hpp"
#include "libtorrent/alert.hpp"
#include "libtorrent/session.hpp"
#include "libtorrent/error_code.hpp"

#include <fstream>

using namespace libtorrent;

int test_main()
{
	int http_port = start_web_server();
	int udp_port = start_udp_tracker();

	int prev_udp_announces = num_udp_announces();

	int const alert_mask = alert::all_categories
		& ~alert::progress_notification
		& ~alert::stats_notification;

	session* s = new libtorrent::session(fingerprint("LT", 0, 1, 0, 0), std::make_pair(48875, 49800), "0.0.0.0", 0, alert_mask);

	session_settings sett;
	sett.half_open_limit = 1;
	sett.announce_to_all_trackers = true;
	sett.announce_to_all_tiers = true;
	s->set_settings(sett);

	error_code ec;
	remove_all("tmp1_tracker", ec);
	create_directory("tmp1_tracker", ec);
	std::ofstream file(combine_path("tmp1_tracker", "temporary").c_str());
	boost::intrusive_ptr<torrent_info> t = ::create_torrent(&file, 16 * 1024, 13, false);
	file.close();

	char tracker_url[200];
	snprintf(tracker_url, sizeof(tracker_url), "http://127.0.0.1:%d/announce", http_port);
	t->add_tracker(tracker_url, 0);

	snprintf(tracker_url, sizeof(tracker_url), "udp://127.0.0.1:%d/announce", udp_port);
	t->add_tracker(tracker_url, 1);

	add_torrent_params addp;
	addp.flags &= ~add_torrent_params::flag_paused;
	addp.flags &= ~add_torrent_params::flag_auto_managed;
	addp.flags |= add_torrent_params::flag_seed_mode;
	addp.ti = t;
	addp.save_path = "tmp1_tracker";
	torrent_handle h = s->add_torrent(addp);

	for (int i = 0; i < 50; ++i)
	{
		print_alerts(*s, "s");
		if (num_udp_announces() == prev_udp_announces + 1)
			break;

		test_sleep(100);
		fprintf(stderr, "UDP: %d / %d\n", int(g_udp_tracker_requests)
			, int(prev_udp_announces) + 1);
	}

	// we should have announced to the tracker by now
	TEST_EQUAL(num_udp_announces(), prev_udp_announces + 1);

	fprintf(stderr, "destructing session\n");
	delete s;
	fprintf(stderr, "done\n");

	// we should have announced the stopped event now
	TEST_EQUAL(num_udp_announces(), prev_udp_announces + 2);

	// ========================================
	// test that we move on to try the next tier if the first one fails
	// ========================================

	s = new libtorrent::session(fingerprint("LT", 0, 1, 0, 0), std::make_pair(39775, 39800), "0.0.0.0", 0, alert_mask);

	sett.half_open_limit = 1;
	sett.announce_to_all_trackers = true;
	sett.announce_to_all_tiers = false;
	sett.tracker_completion_timeout = 2;
	sett.tracker_receive_timeout = 1;
	s->set_settings(sett);

	remove_all("tmp2_tracker", ec);
	create_directory("tmp2_tracker", ec);
	file.open(combine_path("tmp2_tracker", "temporary").c_str());
	t = ::create_torrent(&file, 16 * 1024, 13, false);
	file.close();

	// this should fail
	snprintf(tracker_url, sizeof(tracker_url), "udp://www1.non-existent.com:80/announce");
	t->add_tracker(tracker_url, 0);

	// and this should fail
	snprintf(tracker_url, sizeof(tracker_url), "http://127.0.0.2:3/announce");
	t->add_tracker(tracker_url, 1);

	// this should be announced to
	// udp trackers are prioritized if they're on the same host as an http one
	// so this must be before the http one on 127.0.0.1
	snprintf(tracker_url, sizeof(tracker_url), "udp://127.0.0.1:%d/announce", udp_port);
	t->add_tracker(tracker_url, 2);

	// and this should not be announced to (since the one before it succeeded)
	snprintf(tracker_url, sizeof(tracker_url), "http://127.0.0.1:%d/announce", http_port);
	t->add_tracker(tracker_url, 3);

	prev_udp_announces = num_udp_announces();

	addp.flags &= ~add_torrent_params::flag_paused;
	addp.flags &= ~add_torrent_params::flag_auto_managed;
	addp.flags |= add_torrent_params::flag_seed_mode;
	addp.ti = t;
	addp.save_path = "tmp2_tracker";
	h = s->add_torrent(addp);

	for (int i = 0; i < 50; ++i)
	{
		print_alerts(*s, "s");
		if (num_udp_announces() == prev_udp_announces + 1) break;

		fprintf(stderr, "UDP: %d / %d\n", int(num_udp_announces())
			, int(prev_udp_announces) + 1);
		test_sleep(100);
	}

	test_sleep(1000);

	TEST_EQUAL(num_udp_announces(), prev_udp_announces + 1);

	fprintf(stderr, "destructing session\n");
	delete s;
	fprintf(stderr, "done\n");

	fprintf(stderr, "stop_tracker\n");
	stop_udp_tracker();
	fprintf(stderr, "stop_web_server\n");
	stop_web_server();
	fprintf(stderr, "done\n");

	return 0;
}

<commit_msg>fix merge typo<commit_after>/*

Copyright (c) 2010, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#include "test.hpp"
#include "setup_transfer.hpp"
#include "udp_tracker.hpp"
#include "libtorrent/alert.hpp"
#include "libtorrent/session.hpp"
#include "libtorrent/error_code.hpp"

#include <fstream>

using namespace libtorrent;

int test_main()
{
	int http_port = start_web_server();
	int udp_port = start_udp_tracker();

	int prev_udp_announces = num_udp_announces();

	int const alert_mask = alert::all_categories
		& ~alert::progress_notification
		& ~alert::stats_notification;

	session* s = new libtorrent::session(fingerprint("LT", 0, 1, 0, 0), std::make_pair(48875, 49800), "0.0.0.0", 0, alert_mask);

	session_settings sett;
	sett.half_open_limit = 1;
	sett.announce_to_all_trackers = true;
	sett.announce_to_all_tiers = true;
	s->set_settings(sett);

	error_code ec;
	remove_all("tmp1_tracker", ec);
	create_directory("tmp1_tracker", ec);
	std::ofstream file(combine_path("tmp1_tracker", "temporary").c_str());
	boost::intrusive_ptr<torrent_info> t = ::create_torrent(&file, 16 * 1024, 13, false);
	file.close();

	char tracker_url[200];
	snprintf(tracker_url, sizeof(tracker_url), "http://127.0.0.1:%d/announce", http_port);
	t->add_tracker(tracker_url, 0);

	snprintf(tracker_url, sizeof(tracker_url), "udp://127.0.0.1:%d/announce", udp_port);
	t->add_tracker(tracker_url, 1);

	add_torrent_params addp;
	addp.flags &= ~add_torrent_params::flag_paused;
	addp.flags &= ~add_torrent_params::flag_auto_managed;
	addp.flags |= add_torrent_params::flag_seed_mode;
	addp.ti = t;
	addp.save_path = "tmp1_tracker";
	torrent_handle h = s->add_torrent(addp);

	for (int i = 0; i < 50; ++i)
	{
		print_alerts(*s, "s");
		if (num_udp_announces() == prev_udp_announces + 1)
			break;

		test_sleep(100);
		fprintf(stderr, "UDP: %d / %d\n", int(num_udp_announces())
			, int(prev_udp_announces) + 1);
	}

	// we should have announced to the tracker by now
	TEST_EQUAL(num_udp_announces(), prev_udp_announces + 1);

	fprintf(stderr, "destructing session\n");
	delete s;
	fprintf(stderr, "done\n");

	// we should have announced the stopped event now
	TEST_EQUAL(num_udp_announces(), prev_udp_announces + 2);

	// ========================================
	// test that we move on to try the next tier if the first one fails
	// ========================================

	s = new libtorrent::session(fingerprint("LT", 0, 1, 0, 0), std::make_pair(39775, 39800), "0.0.0.0", 0, alert_mask);

	sett.half_open_limit = 1;
	sett.announce_to_all_trackers = true;
	sett.announce_to_all_tiers = false;
	sett.tracker_completion_timeout = 2;
	sett.tracker_receive_timeout = 1;
	s->set_settings(sett);

	remove_all("tmp2_tracker", ec);
	create_directory("tmp2_tracker", ec);
	file.open(combine_path("tmp2_tracker", "temporary").c_str());
	t = ::create_torrent(&file, 16 * 1024, 13, false);
	file.close();

	// this should fail
	snprintf(tracker_url, sizeof(tracker_url), "udp://www1.non-existent.com:80/announce");
	t->add_tracker(tracker_url, 0);

	// and this should fail
	snprintf(tracker_url, sizeof(tracker_url), "http://127.0.0.2:3/announce");
	t->add_tracker(tracker_url, 1);

	// this should be announced to
	// udp trackers are prioritized if they're on the same host as an http one
	// so this must be before the http one on 127.0.0.1
	snprintf(tracker_url, sizeof(tracker_url), "udp://127.0.0.1:%d/announce", udp_port);
	t->add_tracker(tracker_url, 2);

	// and this should not be announced to (since the one before it succeeded)
	snprintf(tracker_url, sizeof(tracker_url), "http://127.0.0.1:%d/announce", http_port);
	t->add_tracker(tracker_url, 3);

	prev_udp_announces = num_udp_announces();

	addp.flags &= ~add_torrent_params::flag_paused;
	addp.flags &= ~add_torrent_params::flag_auto_managed;
	addp.flags |= add_torrent_params::flag_seed_mode;
	addp.ti = t;
	addp.save_path = "tmp2_tracker";
	h = s->add_torrent(addp);

	for (int i = 0; i < 50; ++i)
	{
		print_alerts(*s, "s");
		if (num_udp_announces() == prev_udp_announces + 1) break;

		fprintf(stderr, "UDP: %d / %d\n", int(num_udp_announces())
			, int(prev_udp_announces) + 1);
		test_sleep(100);
	}

	test_sleep(1000);

	TEST_EQUAL(num_udp_announces(), prev_udp_announces + 1);

	fprintf(stderr, "destructing session\n");
	delete s;
	fprintf(stderr, "done\n");

	fprintf(stderr, "stop_tracker\n");
	stop_udp_tracker();
	fprintf(stderr, "stop_web_server\n");
	stop_web_server();
	fprintf(stderr, "done\n");

	return 0;
}

<|endoftext|>


<commit_before>//* This file is part of the MOOSE framework
//* https://www.mooseframework.org
//*
//* All rights reserved, see COPYRIGHT for full restrictions
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
//*
//* Licensed under LGPL 2.1, please see LICENSE for details
//* https://www.gnu.org/licenses/lgpl-2.1.html

#include "GeneralUserObject.h"

template <>
InputParameters
validParams<GeneralUserObject>()
{
  InputParameters params = validParams<UserObject>();
  params += validParams<MaterialPropertyInterface>();
  params.addParam<bool>(
      "threaded", false, "true if there should be threaded copies of this user object.");
  params.addParam<bool>(
      "force_preaux", false, "Forces the GeneralUserObject to be executed in PREAUX");
  params.addParamNamesToGroup("force_preaux", "Advanced");
  return params;
}

GeneralUserObject::GeneralUserObject(const InputParameters & parameters)
  : UserObject(parameters),
    MaterialPropertyInterface(this, Moose::EMPTY_BLOCK_IDS, Moose::EMPTY_BOUNDARY_IDS),
    TransientInterface(this),
    DependencyResolverInterface(),
    UserObjectInterface(this),
    PostprocessorInterface(this),
    VectorPostprocessorInterface(this)
{
  _supplied_vars.insert(name());
}

const std::set<std::string> &
GeneralUserObject::getRequestedItems()
{
  return _depend_vars;
}

const std::set<std::string> &
GeneralUserObject::getSuppliedItems()
{
  return _supplied_vars;
}

const PostprocessorValue &
GeneralUserObject::getPostprocessorValue(const std::string & name)
{
  _depend_vars.insert(_pars.get<PostprocessorName>(name));
  return PostprocessorInterface::getPostprocessorValue(name);
}

const PostprocessorValue &
GeneralUserObject::getPostprocessorValueByName(const PostprocessorName & name)
{
  _depend_vars.insert(name);
  return PostprocessorInterface::getPostprocessorValueByName(name);
}

const VectorPostprocessorValue &
GeneralUserObject::getVectorPostprocessorValue(const std::string & name,
                                               const std::string & vector_name)
{
  _depend_vars.insert(_pars.get<VectorPostprocessorName>(name));
  return VectorPostprocessorInterface::getVectorPostprocessorValue(name, vector_name);
}

const VectorPostprocessorValue &
GeneralUserObject::getVectorPostprocessorValueByName(const VectorPostprocessorName & name,
                                                     const std::string & vector_name)
{
  _depend_vars.insert(name);
  return VectorPostprocessorInterface::getVectorPostprocessorValueByName(name, vector_name);
}

const VectorPostprocessorValue &
GeneralUserObject::getVectorPostprocessorValue(const std::string & name,
                                               const std::string & vector_name,
                                               bool use_broadcast)
{
  _depend_vars.insert(_pars.get<VectorPostprocessorName>(name));
  return VectorPostprocessorInterface::getVectorPostprocessorValue(
      name, vector_name, use_broadcast);
}

const VectorPostprocessorValue &
GeneralUserObject::getVectorPostprocessorValueByName(const VectorPostprocessorName & name,
                                                     const std::string & vector_name,
                                                     bool use_broadcast)
{
  _depend_vars.insert(name);
  return VectorPostprocessorInterface::getVectorPostprocessorValueByName(
      name, vector_name, use_broadcast);
}

void
GeneralUserObject::threadJoin(const UserObject &)
{
  mooseError("GeneralUserObjects do not execute using threads, this function does nothing and "
             "should not be used.");
}

void
GeneralUserObject::subdomainSetup()
{
  mooseError("GeneralUserObjects do not execute subdomainSetup method, this function does nothing "
             "and should not be used.");
}
<commit_msg>Prevent threaded general user objects with pthread<commit_after>//* This file is part of the MOOSE framework
//* https://www.mooseframework.org
//*
//* All rights reserved, see COPYRIGHT for full restrictions
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
//*
//* Licensed under LGPL 2.1, please see LICENSE for details
//* https://www.gnu.org/licenses/lgpl-2.1.html

#include "GeneralUserObject.h"

template <>
InputParameters
validParams<GeneralUserObject>()
{
  InputParameters params = validParams<UserObject>();
  params += validParams<MaterialPropertyInterface>();
  params.addParam<bool>(
      "threaded", false, "true if there should be threaded copies of this user object.");
  params.addParam<bool>(
      "force_preaux", false, "Forces the GeneralUserObject to be executed in PREAUX");
  params.addParamNamesToGroup("force_preaux", "Advanced");
  return params;
}

GeneralUserObject::GeneralUserObject(const InputParameters & parameters)
  : UserObject(parameters),
    MaterialPropertyInterface(this, Moose::EMPTY_BLOCK_IDS, Moose::EMPTY_BOUNDARY_IDS),
    TransientInterface(this),
    DependencyResolverInterface(),
    UserObjectInterface(this),
    PostprocessorInterface(this),
    VectorPostprocessorInterface(this)
{
#if !defined(LIBMESH_HAVE_OPENMP) && !defined(LIBMESH_HAVE_TBB_API)
  if (getParam<bool>("threaded"))
    mooseError(name(),
               ": You cannot use threaded general user objects with pthreads. To enable this "
               "functionality configure libMesh with OpenMP or TBB.");
#endif
  _supplied_vars.insert(name());
}

const std::set<std::string> &
GeneralUserObject::getRequestedItems()
{
  return _depend_vars;
}

const std::set<std::string> &
GeneralUserObject::getSuppliedItems()
{
  return _supplied_vars;
}

const PostprocessorValue &
GeneralUserObject::getPostprocessorValue(const std::string & name)
{
  _depend_vars.insert(_pars.get<PostprocessorName>(name));
  return PostprocessorInterface::getPostprocessorValue(name);
}

const PostprocessorValue &
GeneralUserObject::getPostprocessorValueByName(const PostprocessorName & name)
{
  _depend_vars.insert(name);
  return PostprocessorInterface::getPostprocessorValueByName(name);
}

const VectorPostprocessorValue &
GeneralUserObject::getVectorPostprocessorValue(const std::string & name,
                                               const std::string & vector_name)
{
  _depend_vars.insert(_pars.get<VectorPostprocessorName>(name));
  return VectorPostprocessorInterface::getVectorPostprocessorValue(name, vector_name);
}

const VectorPostprocessorValue &
GeneralUserObject::getVectorPostprocessorValueByName(const VectorPostprocessorName & name,
                                                     const std::string & vector_name)
{
  _depend_vars.insert(name);
  return VectorPostprocessorInterface::getVectorPostprocessorValueByName(name, vector_name);
}

const VectorPostprocessorValue &
GeneralUserObject::getVectorPostprocessorValue(const std::string & name,
                                               const std::string & vector_name,
                                               bool use_broadcast)
{
  _depend_vars.insert(_pars.get<VectorPostprocessorName>(name));
  return VectorPostprocessorInterface::getVectorPostprocessorValue(
      name, vector_name, use_broadcast);
}

const VectorPostprocessorValue &
GeneralUserObject::getVectorPostprocessorValueByName(const VectorPostprocessorName & name,
                                                     const std::string & vector_name,
                                                     bool use_broadcast)
{
  _depend_vars.insert(name);
  return VectorPostprocessorInterface::getVectorPostprocessorValueByName(
      name, vector_name, use_broadcast);
}

void
GeneralUserObject::threadJoin(const UserObject &)
{
  mooseError("GeneralUserObjects do not execute using threads, this function does nothing and "
             "should not be used.");
}

void
GeneralUserObject::subdomainSetup()
{
  mooseError("GeneralUserObjects do not execute subdomainSetup method, this function does nothing "
             "and should not be used.");
}
<|endoftext|>


<commit_before>#define BOOST_TEST_DYN_LINK

#include "support.hpp"

#include <iostream>

#include <boost/test/unit_test.hpp>

#include <libpc/Utils.hpp>

bool compare_files(const std::string& file1, const std::string& file2)
{
    uintmax_t len1 = libpc::Utils::fileSize(file1);
    uintmax_t len2 = libpc::Utils::fileSize(file1);

    if (len1 != len2)
    {
        return false;
    }

    std::istream* str1 = libpc::Utils::openFile(file1);
    std::istream* str2 = libpc::Utils::openFile(file2);
    BOOST_CHECK(str1);
    BOOST_CHECK(str2);

    char* buf1 = new char[len1];
    char* buf2 = new char[len2];

    str1->read(buf1,len1);
    str2->read (buf2,len2);

    libpc::Utils::closeFile(str1);
    libpc::Utils::closeFile(str2);

    char* p = buf1;
    char* q = buf2;

    for (uintmax_t i=0; i<len1; i++)
    {
        if (*p != *q)
        {
            delete[] buf1;
            delete[] buf2;
            return false;
        }
        ++p;
        ++q;
    }

    delete[] buf1;
    delete[] buf2;

    return true;
}
<commit_msg>fix dyn linkage<commit_after>#ifdef _MSC_VER
#define BOOST_TEST_DYN_LINK
#endif

#include "support.hpp"

#include <iostream>

#include <boost/test/unit_test.hpp>

#include <libpc/Utils.hpp>

bool compare_files(const std::string& file1, const std::string& file2)
{
    uintmax_t len1 = libpc::Utils::fileSize(file1);
    uintmax_t len2 = libpc::Utils::fileSize(file1);

    if (len1 != len2)
    {
        return false;
    }

    std::istream* str1 = libpc::Utils::openFile(file1);
    std::istream* str2 = libpc::Utils::openFile(file2);
    BOOST_CHECK(str1);
    BOOST_CHECK(str2);

    char* buf1 = new char[len1];
    char* buf2 = new char[len2];

    str1->read(buf1,len1);
    str2->read (buf2,len2);

    libpc::Utils::closeFile(str1);
    libpc::Utils::closeFile(str2);

    char* p = buf1;
    char* q = buf2;

    for (uintmax_t i=0; i<len1; i++)
    {
        if (*p != *q)
        {
            delete[] buf1;
            delete[] buf2;
            return false;
        }
        ++p;
        ++q;
    }

    delete[] buf1;
    delete[] buf2;

    return true;
}
<|endoftext|>


<commit_before>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/* $Id$ */

// Helper class to interface pdflib and the TPythia
// the c++ interface for Pythia
// The pdf codes used  in pdflib are mapped
// to a more user friendly enumeration type.
// Author: andreas.morsch@cern.ch

#include "AliStructFuncType.h"

#ifndef WIN32
# define structa  structa_
# define pdfset   pdfset_
# define type_of_call
#else
# define structa  STRUCTA
# define pdfset   PDFSET
# define type_of_call _stdcall
#endif

extern "C" {
    void type_of_call pdfset(char parm[20][20], Double_t value[20]);

    void type_of_call structa(Double_t& xx, Double_t& qq, Double_t& a,
			       Double_t& upv, Double_t& dnv, Double_t& usea,
			       Double_t& dsea,
			       Double_t& str, Double_t& chm, Double_t& bot,
			       Double_t& top, Double_t& gl);
}

ClassImp(AliStructFuncType)

void AliStructFuncType::PdfSet(char parm[20][20], Double_t value[20])
{
    pdfset(parm, value);
}

void AliStructFuncType::StructA(Double_t xx, Double_t qq, Double_t a,
				Double_t& upv, Double_t& dnv, Double_t& usea,
				Double_t& dsea,
				Double_t& str, Double_t& chm, Double_t& bot,
				Double_t& top, Double_t& gl)
{
    structa(xx, qq, a, upv, dnv, usea, dsea, str, chm, bot, top, gl);
}

Int_t AliStructFuncType::PDFsetIndex(StrucFunc_t pdf)
{
// PDF set index
    Int_t pdfSetNumber[10] = {
	19170,
	19150,
	19070,
	19050,
	80060,
	10040,
	10100,
	10050,
	10041,
	10042
    };
    return pdfSetNumber[pdf];
}

TString AliStructFuncType::PDFsetName(StrucFunc_t pdf)
{
// PDF Set Name
    TString pdfsetName[10]   = {
	"cteq4l.LHgrid",
	"cteq4m.LHgrid",
	"cteq5l.LHgrid",
	"cteq5m.LHgrid",
	"GRV98lo.LHgris",
	"cteq6.LHpdf",
	"cteq61.LHpdf",
	"cteq6m.LHpdf",
	"cteq6l.LHpdf",
	"cteq6ll.LHpdf"
    };
    return pdfsetName[pdf];
}
<commit_msg>Typo<commit_after>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/* $Id$ */

// Helper class to interface pdflib and the TPythia
// the c++ interface for Pythia
// The pdf codes used  in pdflib are mapped
// to a more user friendly enumeration type.
// Author: andreas.morsch@cern.ch

#include "AliStructFuncType.h"

#ifndef WIN32
# define structa  structa_
# define pdfset   pdfset_
# define type_of_call
#else
# define structa  STRUCTA
# define pdfset   PDFSET
# define type_of_call _stdcall
#endif

extern "C" {
    void type_of_call pdfset(char parm[20][20], Double_t value[20]);

    void type_of_call structa(Double_t& xx, Double_t& qq, Double_t& a,
			       Double_t& upv, Double_t& dnv, Double_t& usea,
			       Double_t& dsea,
			       Double_t& str, Double_t& chm, Double_t& bot,
			       Double_t& top, Double_t& gl);
}

ClassImp(AliStructFuncType)

void AliStructFuncType::PdfSet(char parm[20][20], Double_t value[20])
{
    pdfset(parm, value);
}

void AliStructFuncType::StructA(Double_t xx, Double_t qq, Double_t a,
				Double_t& upv, Double_t& dnv, Double_t& usea,
				Double_t& dsea,
				Double_t& str, Double_t& chm, Double_t& bot,
				Double_t& top, Double_t& gl)
{
    structa(xx, qq, a, upv, dnv, usea, dsea, str, chm, bot, top, gl);
}

Int_t AliStructFuncType::PDFsetIndex(StrucFunc_t pdf)
{
// PDF set index
    Int_t pdfSetNumber[10] = {
	19170,
	19150,
	19070,
	19050,
	80060,
	10040,
	10100,
	10050,
	10041,
	10042
    };
    return pdfSetNumber[pdf];
}

TString AliStructFuncType::PDFsetName(StrucFunc_t pdf)
{
// PDF Set Name
    TString pdfsetName[10]   = {
	"cteq4l.LHgrid",
	"cteq4m.LHgrid",
	"cteq5l.LHgrid",
	"cteq5m.LHgrid",
	"GRV98lo.LHgrid",
	"cteq6.LHpdf",
	"cteq61.LHpdf",
	"cteq6m.LHpdf",
	"cteq6l.LHpdf",
	"cteq6ll.LHpdf"
    };
    return pdfsetName[pdf];
}
<|endoftext|>


<commit_before>#include "mainwindow.h"
#include "ui_mainwindow.h"

//#include <gl.h>
#include <iostream>

#include <rocklevel/tilemap.h>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    setMouseTracking(true);
    qApp->installEventFilter(this);

    //ui->gameDrawWidget->setFocus();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::OpenResourcesDirectory()
{
    if(!QDir(qApp->applicationDirPath() + "/res/").exists())
    {
        std::cout << "resource path didn't exist, making" << std::endl;
        QDir().mkdir(qApp->applicationDirPath() + "/res/");
    }

    QString path = QDir::toNativeSeparators(qApp->applicationDirPath() + "/res/");
    QDesktopServices::openUrl(QUrl::fromLocalFile(path));
}

QString MainWindow::getResourcesDirectory()
{
    return QDir::toNativeSeparators(qApp->applicationDirPath() + "/res/");
}

/*
void MainWindow::mouseMoveEvent(QMouseEvent *event)
{
    std::cout << "mouse move shit" << std::endl;
    ui->gameDrawWidget->update();
    if(ui->gameDrawWidget->rect().contains(event->pos()))
    {
        ui->gameDrawWidget->update();
    }
}

void MainWindow::mousePressEvent(QMouseEvent *event)
{
    if(this->isActiveWindow())
    {
        if(event->button() == Qt::MouseButton::LeftButton)
        {
            if(ui->gameDrawWidget->rect().contains(QCursor::pos()))
            {
                std::cout << "triggered" << std::endl;
            }
        }
    }
}
*/

bool MainWindow::eventFilter(QObject *watched, QEvent *event)
{
    if(event->type() == QEvent::MouseMove)
    {
        ui->gameDrawWidget->update();
    }
    else if(event->type() == QEvent::Wheel)
    {
        if(ui->gameDrawWidget->underMouse())
        {
            QWheelEvent* wheelie = (QWheelEvent*)event;
            int dx, dy;
            dx = wheelie->angleDelta().x();
            dy = wheelie->angleDelta().y();

            ui->verticalScrollBar->setValue(ui->verticalScrollBar->value() + -fmin(ceil(dy / 4), 2));
            ui->horizontalScrollBar->setValue(ui->horizontalScrollBar->value() + -fmin(ceil(dx / 4), 2));
            return true;
        }
    }
    else if(event->type() == QEvent::MouseButtonPress)
    {
        if(this->isActiveWindow())
        {
            //if(ui->gameDrawWidget->rect().contains(QCursor::pos()))
            if(ui->gameDrawWidget->underMouse())
            {
                ui->gameDrawWidget->placeTileAction();
                setWindowModified(true);
                return true;
            }
            else
            {
                //this->mousePressEvent((QMouseEvent*)event);
                QWidget::eventFilter(watched, event);
                return false;
            }
        }
        else
            return false;
    }
    else if(event->type() == QEvent::KeyPress)
    {
        /*
        QKeyEvent* keyEvent = (QKeyEvent*)event;
        switch(keyEvent->key())
        {
        case Qt::Key_Right:
            ui->gameDrawWidget->moveCamera(-16, 0);
            break;
        }
        return true;
        */
    }
    return false;
}

void MainWindow::on_gameDrawWidget_aboutToCompose()
{
}

QImage createSubImage(QImage* image, const QRect & rect) {
    size_t offset = rect.x() * image->depth() / 8
                    + rect.y() * image->bytesPerLine();
    return QImage(image->bits() + offset, rect.width(), rect.height(),
                  image->bytesPerLine(), image->format());
}

void MainWindow::on_gameDrawWidget_frameSwapped()
{
    if(!initialSetupDone)
    {
        populateTileList();
        initialSetupDone = true;
    }
}

void MainWindow::populateTileList()
{
    ui->listWidget->clear();
    for(int i = 0; i < (8*8); i++)
    {
        //tile_get_location_by_id
        QListWidgetItem* test = new QListWidgetItem("Tile " + QString::number(i), ui->listWidget);
        QRect rect;
        vector_t tile_area = tile_get_location_by_id(i);
        rect.setX(tile_area.x);
        rect.setY(tile_area.y);
        rect.setWidth(TILE_WIDTH);
        rect.setHeight(TILE_HEIGHT);

        QImage* atlas = ui->gameDrawWidget->getMainTexture()->toQImage();

        test->setIcon(QIcon(QPixmap::fromImage(createSubImage(atlas, rect))));
    }

    //we also adjust the scroll bar values
    ui->horizontalScrollBar->setMaximum(ui->gameDrawWidget->getCurrentTilemap()->width / 2);
    ui->verticalScrollBar->setMaximum(ui->gameDrawWidget->getCurrentTilemap()->height);
    ui->gameDrawWidget->update(); //manually update so that it shows up without having to move the mouse
    //1 notch on the scroll bar will move exactly one tile
}

void MainWindow::onFileSelected(const QString& filename)
{
    if(!filename.isEmpty())
    {
        if(ui->gameDrawWidget->loadTilemap(filename))
        {
            QFileInfo levelFileInfo(filename);
            this->currentLevelPath = filename;
            ui->levelNameTextBox->setText(ui->gameDrawWidget->getCurrentTilemap()->map_name);
            setWindowFilePath(filename);
            setWindowTitle(levelFileInfo.fileName() + "[*] - Level Editor");
            setWindowModified(false);

            populateTileList(); //repopulate the tile list
        }
    }
    else
        return; //do nothing
}

void MainWindow::onFileSelectedForSaving(const QString &filename)
{
    if(!filename.isEmpty())
    {
        tilemap_write_to_file(filename.toStdString().c_str(), ui->gameDrawWidget->getCurrentTilemap());

        this->currentLevelPath = filename;

        setWindowModified(false);
        setWindowTitle(QFileInfo(filename).fileName() + "[*] - Level Editor");
        setWindowFilePath(filename);

        if(this->isQuitting)
            qApp->quit();
    }
    else
        std::cout << "filename blank" << std::endl;
}

void MainWindow::on_actionOpen_triggered()
{
    QString fileName;
    QFileDialog* f = new QFileDialog(this, Qt::Sheet);
#ifdef __APPLE__
    f->setWindowModality(Qt::WindowModal);
#endif
    QDir d("");
    d.setNameFilters(QStringList() << "Bin File (*.bin)");
    f->setFilter(d.filter());
    connect(f, &QFileDialog::fileSelected, this, &MainWindow::onFileSelected);
    f->open();
}

void MainWindow::openLevel()
{}

void MainWindow::saveLevel()
{}

void MainWindow::on_levelNameTextBox_returnPressed()
{
    setWindowModified(true);
    ui->gameDrawWidget->setTileMapName(ui->levelNameTextBox->text().toUtf8().data());
}

void MainWindow::performSaveAs()
{
    QString fileName;
    QFileDialog* f = new QFileDialog(this, Qt::Sheet);
    f->setAcceptMode(QFileDialog::AcceptSave);
#if __APPLE__
    f->setWindowModality(Qt::WindowModal);
#endif
    QDir d("");
    d.setNameFilters(QStringList() << "Bin File (*.bin)");
    f->setFilter(d.filter());
    connect(f, &QFileDialog::fileSelected, this, &MainWindow::onFileSelectedForSaving);
    f->open();
}

void MainWindow::on_actionSave_triggered()
{
    if(!currentLevelPath.isEmpty())
    {
        tilemap_write_to_file(currentLevelPath.toStdString().c_str(), ui->gameDrawWidget->getCurrentTilemap());
        setWindowModified(false);
    }
    else
        performSaveAs();
}

void MainWindow::on_actionSave_As_triggered()
{
    performSaveAs();
}

void MainWindow::on_actionOpen_resource_path_triggered()
{
    MainWindow::OpenResourcesDirectory();
}

void MainWindow::on_listWidget_itemClicked(QListWidgetItem *item)
{
    //this is all super hacky and i'm not proud
    QString* string = new QString(item->text());
    QStringRef substr(string, 5, 2);

    //std::cout << "Selected '" << substr.toString().toStdString() << "'" << std::endl;

    ui->gameDrawWidget->setPlacingTileID(item->text().split(" ")[1].toInt());
    ui->gameDrawWidget->setPlacingTileRotation(0);
}

void MainWindow::on_pushButton_clicked()
{
    ui->gameDrawWidget->setPlacingTileRotation(ui->gameDrawWidget->getPlacingTileRotation() + 90);
}

void MainWindow::on_pushButton_2_clicked()
{
    ui->gameDrawWidget->setPlacingTileRotation(ui->gameDrawWidget->getPlacingTileRotation() - 90);
}

void MainWindow::on_pushButton_3_clicked()
{
    ui->gameDrawWidget->setPlacingTileRotation(0);
}

void MainWindow::closeEvent(QCloseEvent* event)
{
    if(this->isWindowModified()) //has changes
    {
        QMessageBox quitBox(this);
        quitBox.setText("Level has been modified");
        quitBox.setInformativeText("Would you like to save your changes?");
        quitBox.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
        quitBox.setDefaultButton(QMessageBox::Save);
        //quitBox.setParent(this);
        quitBox.setIcon(QMessageBox::Information);
        quitBox.setWindowModality(Qt::WindowModal);
        quitBox.setModal(true);

        int returnValue = quitBox.exec();

        switch(returnValue)
        {
        case QMessageBox::Save:
            performSaveAs();
            event->ignore();
            this->isQuitting = true;
            break;
        case QMessageBox::Discard:
            //do nothing
            break;
        case QMessageBox::Cancel:
            event->ignore();
            break;
        }
    }
    else
    {
        //quit as normally
    }
}

void MainWindow::on_horizontalScrollBar_sliderMoved(int position)
{}

void MainWindow::on_verticalScrollBar_sliderMoved(int position)
{}

void MainWindow::on_horizontalScrollBar_valueChanged(int value)
{
    ui->gameDrawWidget->setCameraPosition(-value * 32, -1);
    ui->gameDrawWidget->update();
}

void MainWindow::on_verticalScrollBar_valueChanged(int value)
{
    ui->gameDrawWidget->setCameraPosition(-1, -value * 32);
    ui->gameDrawWidget->update();
}

void MainWindow::on_actionClose_triggered()
{
    this->close();
}
<commit_msg>mouse wheel tweaking<commit_after>#include "mainwindow.h"
#include "ui_mainwindow.h"

//#include <gl.h>
#include <iostream>

#include <rocklevel/tilemap.h>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    setMouseTracking(true);
    qApp->installEventFilter(this);

    //ui->gameDrawWidget->setFocus();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::OpenResourcesDirectory()
{
    if(!QDir(qApp->applicationDirPath() + "/res/").exists())
    {
        std::cout << "resource path didn't exist, making" << std::endl;
        QDir().mkdir(qApp->applicationDirPath() + "/res/");
    }

    QString path = QDir::toNativeSeparators(qApp->applicationDirPath() + "/res/");
    QDesktopServices::openUrl(QUrl::fromLocalFile(path));
}

QString MainWindow::getResourcesDirectory()
{
    return QDir::toNativeSeparators(qApp->applicationDirPath() + "/res/");
}

/*
void MainWindow::mouseMoveEvent(QMouseEvent *event)
{
    std::cout << "mouse move shit" << std::endl;
    ui->gameDrawWidget->update();
    if(ui->gameDrawWidget->rect().contains(event->pos()))
    {
        ui->gameDrawWidget->update();
    }
}

void MainWindow::mousePressEvent(QMouseEvent *event)
{
    if(this->isActiveWindow())
    {
        if(event->button() == Qt::MouseButton::LeftButton)
        {
            if(ui->gameDrawWidget->rect().contains(QCursor::pos()))
            {
                std::cout << "triggered" << std::endl;
            }
        }
    }
}
*/

bool MainWindow::eventFilter(QObject *watched, QEvent *event)
{
    if(event->type() == QEvent::MouseMove)
    {
        ui->gameDrawWidget->update();
    }
    else if(event->type() == QEvent::Wheel)
    {
        if(ui->gameDrawWidget->underMouse())
        {
            QWheelEvent* wheelie = (QWheelEvent*)event;
            int dx, dy;
            dx = wheelie->angleDelta().x();
            dy = wheelie->angleDelta().y();
            //ui->verticalScrollBar->setValue(ui->verticalScrollBar->value() + -fmin(ceil(dy / 4), 2));
            //ui->horizontalScrollBar->setValue(ui->horizontalScrollBar->value() + -fmin(ceil(dx / 4), 2));
            if(dx > 0)
                dx = 32;
            else if(dx < 0)
                dx = -32;

            if(dy > 0)
                dy = 32;
            else if(dy < 0)
                dy = -32;
            //std::cout << "mouse wheel: " << dx << ", " << dy << std::endl;

            ui->verticalScrollBar->setValue(ui->verticalScrollBar->value() + (-dy / 8));
            ui->horizontalScrollBar->setValue(ui->horizontalScrollBar->value() + (-dx / 8));
            return true;
        }
    }
    else if(event->type() == QEvent::MouseButtonPress)
    {
        if(this->isActiveWindow())
        {
            //if(ui->gameDrawWidget->rect().contains(QCursor::pos()))
            if(ui->gameDrawWidget->underMouse())
            {
                ui->gameDrawWidget->placeTileAction();
                setWindowModified(true);
                return true;
            }
            else
            {
                //this->mousePressEvent((QMouseEvent*)event);
                QWidget::eventFilter(watched, event);
                return false;
            }
        }
        else
            return false;
    }
    else if(event->type() == QEvent::KeyPress)
    {
        /*
        QKeyEvent* keyEvent = (QKeyEvent*)event;
        switch(keyEvent->key())
        {
        case Qt::Key_Right:
            ui->gameDrawWidget->moveCamera(-16, 0);
            break;
        }
        return true;
        */
    }
    return false;
}

void MainWindow::on_gameDrawWidget_aboutToCompose()
{
}

QImage createSubImage(QImage* image, const QRect & rect) {
    size_t offset = rect.x() * image->depth() / 8
                    + rect.y() * image->bytesPerLine();
    return QImage(image->bits() + offset, rect.width(), rect.height(),
                  image->bytesPerLine(), image->format());
}

void MainWindow::on_gameDrawWidget_frameSwapped()
{
    if(!initialSetupDone)
    {
        populateTileList();
        initialSetupDone = true;
    }
}

void MainWindow::populateTileList()
{
    ui->listWidget->clear();
    for(int i = 0; i < (8*8); i++)
    {
        //tile_get_location_by_id
        QListWidgetItem* test = new QListWidgetItem("Tile " + QString::number(i), ui->listWidget);
        QRect rect;
        vector_t tile_area = tile_get_location_by_id(i);
        rect.setX(tile_area.x);
        rect.setY(tile_area.y);
        rect.setWidth(TILE_WIDTH);
        rect.setHeight(TILE_HEIGHT);

        QImage* atlas = ui->gameDrawWidget->getMainTexture()->toQImage();

        test->setIcon(QIcon(QPixmap::fromImage(createSubImage(atlas, rect))));
    }

    //we also adjust the scroll bar values
    ui->horizontalScrollBar->setMaximum(ui->gameDrawWidget->getCurrentTilemap()->width / 2);
    ui->verticalScrollBar->setMaximum(ui->gameDrawWidget->getCurrentTilemap()->height);
    ui->gameDrawWidget->update(); //manually update so that it shows up without having to move the mouse
    //1 notch on the scroll bar will move exactly one tile
}

void MainWindow::onFileSelected(const QString& filename)
{
    if(!filename.isEmpty())
    {
        if(ui->gameDrawWidget->loadTilemap(filename))
        {
            QFileInfo levelFileInfo(filename);
            this->currentLevelPath = filename;
            ui->levelNameTextBox->setText(ui->gameDrawWidget->getCurrentTilemap()->map_name);
            setWindowFilePath(filename);
            setWindowTitle(levelFileInfo.fileName() + "[*] - Level Editor");
            setWindowModified(false);

            populateTileList(); //repopulate the tile list
        }
    }
    else
        return; //do nothing
}

void MainWindow::onFileSelectedForSaving(const QString &filename)
{
    if(!filename.isEmpty())
    {
        tilemap_write_to_file(filename.toStdString().c_str(), ui->gameDrawWidget->getCurrentTilemap());

        this->currentLevelPath = filename;

        setWindowModified(false);
        setWindowTitle(QFileInfo(filename).fileName() + "[*] - Level Editor");
        setWindowFilePath(filename);

        if(this->isQuitting)
            qApp->quit();
    }
    else
        std::cout << "filename blank" << std::endl;
}

void MainWindow::on_actionOpen_triggered()
{
    QString fileName;
    QFileDialog* f = new QFileDialog(this, Qt::Sheet);
#ifdef __APPLE__
    f->setWindowModality(Qt::WindowModal);
#endif
    QDir d("");
    d.setNameFilters(QStringList() << "Bin File (*.bin)");
    f->setFilter(d.filter());
    connect(f, &QFileDialog::fileSelected, this, &MainWindow::onFileSelected);
    f->open();
}

void MainWindow::openLevel()
{}

void MainWindow::saveLevel()
{}

void MainWindow::on_levelNameTextBox_returnPressed()
{
    setWindowModified(true);
    ui->gameDrawWidget->setTileMapName(ui->levelNameTextBox->text().toUtf8().data());
}

void MainWindow::performSaveAs()
{
    QString fileName;
    QFileDialog* f = new QFileDialog(this, Qt::Sheet);
    f->setAcceptMode(QFileDialog::AcceptSave);
#if __APPLE__
    f->setWindowModality(Qt::WindowModal);
#endif
    QDir d("");
    d.setNameFilters(QStringList() << "Bin File (*.bin)");
    f->setFilter(d.filter());
    connect(f, &QFileDialog::fileSelected, this, &MainWindow::onFileSelectedForSaving);
    f->open();
}

void MainWindow::on_actionSave_triggered()
{
    if(!currentLevelPath.isEmpty())
    {
        tilemap_write_to_file(currentLevelPath.toStdString().c_str(), ui->gameDrawWidget->getCurrentTilemap());
        setWindowModified(false);
    }
    else
        performSaveAs();
}

void MainWindow::on_actionSave_As_triggered()
{
    performSaveAs();
}

void MainWindow::on_actionOpen_resource_path_triggered()
{
    MainWindow::OpenResourcesDirectory();
}

void MainWindow::on_listWidget_itemClicked(QListWidgetItem *item)
{
    //this is all super hacky and i'm not proud
    QString* string = new QString(item->text());
    QStringRef substr(string, 5, 2);

    //std::cout << "Selected '" << substr.toString().toStdString() << "'" << std::endl;

    ui->gameDrawWidget->setPlacingTileID(item->text().split(" ")[1].toInt());
    ui->gameDrawWidget->setPlacingTileRotation(0);
}

void MainWindow::on_pushButton_clicked()
{
    ui->gameDrawWidget->setPlacingTileRotation(ui->gameDrawWidget->getPlacingTileRotation() + 90);
}

void MainWindow::on_pushButton_2_clicked()
{
    ui->gameDrawWidget->setPlacingTileRotation(ui->gameDrawWidget->getPlacingTileRotation() - 90);
}

void MainWindow::on_pushButton_3_clicked()
{
    ui->gameDrawWidget->setPlacingTileRotation(0);
}

void MainWindow::closeEvent(QCloseEvent* event)
{
    if(this->isWindowModified()) //has changes
    {
        QMessageBox quitBox(this);
        quitBox.setText("Level has been modified");
        quitBox.setInformativeText("Would you like to save your changes?");
        quitBox.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
        quitBox.setDefaultButton(QMessageBox::Save);
        //quitBox.setParent(this);
        quitBox.setIcon(QMessageBox::Information);
        quitBox.setWindowModality(Qt::WindowModal);
        quitBox.setModal(true);

        int returnValue = quitBox.exec();

        switch(returnValue)
        {
        case QMessageBox::Save:
            performSaveAs();
            event->ignore();
            this->isQuitting = true;
            break;
        case QMessageBox::Discard:
            //do nothing
            break;
        case QMessageBox::Cancel:
            event->ignore();
            break;
        }
    }
    else
    {
        //quit as normally
    }
}

void MainWindow::on_horizontalScrollBar_sliderMoved(int position)
{}

void MainWindow::on_verticalScrollBar_sliderMoved(int position)
{}

void MainWindow::on_horizontalScrollBar_valueChanged(int value)
{
    ui->gameDrawWidget->setCameraPosition(-value * 32, -1);
    ui->gameDrawWidget->update();
}

void MainWindow::on_verticalScrollBar_valueChanged(int value)
{
    ui->gameDrawWidget->setCameraPosition(-1, -value * 32);
    ui->gameDrawWidget->update();
}

void MainWindow::on_actionClose_triggered()
{
    this->close();
}
<|endoftext|>


<commit_before>#include <pqxx/compiler.h>

#include <iostream>

#include <pqxx/binarystring>
#include <pqxx/connection>
#include <pqxx/transaction>
#include <pqxx/result>

using namespace PGSTD;
using namespace pqxx;

// Example program for libpqxx.  Test binarystring functionality.
//
// Usage: test062 [connect-string]
//
// Where connect-string is a set of connection options in Postgresql's
// PQconnectdb() format, eg. "dbname=template1" to select from a database
// called template1, or "host=foo.bar.net user=smith" to connect to a
// backend running on host foo.bar.net, logging in as user smith.

int main(int, char *argv[])
{
  try
  {
    const string TestStr = "Nasty\n\030Test\n\t String\r\0 With Trailer\\\\\0";

    connection C(argv[1]);
    work T(C, "test62");

    T.exec("CREATE TEMP TABLE pqxxbin (binfield bytea)");
    const string Esc = escape_binary(TestStr);
    T.exec("INSERT INTO pqxxbin VALUES ('" + Esc + "')");

    result R = T.exec("SELECT * from pqxxbin");
    binarystring B( R.at(0).at(0) );

    if (B.empty())
      throw logic_error("Binary string became empty in conversion");

    if (B.size() != TestStr.size())
      throw logic_error("Binary string got changed from " +
	  ToString(TestStr.size()) + " to " + ToString(B.size()) + " bytes");

    if (strncmp(TestStr.c_str(), B.c_ptr(), B.size()) != 0)
      throw logic_error("Binary string was changed before first zero byte: "
	  "'" + string(B.c_ptr(), B.size()) + "'");

    binarystring::const_iterator c;
    binarystring::size_type i;
    for (i=0, c=B.begin(); i<B.size(); ++i, ++c)
    {
      if (c == B.end())
	throw logic_error("Premature end to binary string at " + ToString(i));

      if (B.data()[i] != TestStr.at(i))
	throw logic_error("Binary string byte " + ToString(i) + " "
	    "got changed from '" + ToString(TestStr[i]) + "' "
	    "to '" + ToString(B.data()[i]) + "'");
      if (B.at(i) != B.data()[i])
	throw logic_error("Inconsistent byte at offset " + ToString(i) + ": "
	    "operator[] says '" + ToString(B.at(i)) + "', "
	    "data() says '" + ToString(B.data()[i]) + "'");
    }
    if (c != B.end())
      throw logic_error("end() of binary string not reached");

#ifndef PQXX_HAVE_REVERSE_ITERATOR
    binarystring::const_reverse_iterator r;
    for (i=B.length(), r=B.rbegin(); i>0; --i, ++r)
    {
      if (r == B.rend())
	throw logic_error("Premature rend to binary string at " + ToString(i));

      if (B[i-1] != TestStr.at(i-1))
	throw logic_error("Reverse iterator differs at " + ToString(i));
    }
    if (r != B.rend())
      throw logic_error("rend() of binary string not reached");
#endif

    if (B.str() != TestStr)
      throw logic_error("Binary string got mangled: '" + B.str() + "'");
  }
  catch (const sql_error &e)
  {
    // If we're interested in the text of a failed query, we can write separate
    // exception handling code for this type of exception
    cerr << "SQL error: " << e.what() << endl
         << "Query was: '" << e.query() << "'" << endl;
    return 1;
  }
  catch (const exception &e)
  {
    // All exceptions thrown by libpqxx are derived from std::exception
    cerr << "Exception: " << e.what() << endl;
    return 2;
  }
  catch (...)
  {
    // This is really unexpected (see above)
    cerr << "Unhandled exception" << endl;
    return 100;
  }

  return 0;
}

<commit_msg>Typo fix in test062<commit_after>#include <pqxx/compiler.h>

#include <iostream>

#include <pqxx/binarystring>
#include <pqxx/connection>
#include <pqxx/transaction>
#include <pqxx/result>

using namespace PGSTD;
using namespace pqxx;

// Example program for libpqxx.  Test binarystring functionality.
//
// Usage: test062 [connect-string]
//
// Where connect-string is a set of connection options in Postgresql's
// PQconnectdb() format, eg. "dbname=template1" to select from a database
// called template1, or "host=foo.bar.net user=smith" to connect to a
// backend running on host foo.bar.net, logging in as user smith.

int main(int, char *argv[])
{
  try
  {
    const string TestStr = "Nasty\n\030Test\n\t String\r\0 With Trailer\\\\\0";

    connection C(argv[1]);
    work T(C, "test62");

    T.exec("CREATE TEMP TABLE pqxxbin (binfield bytea)");
    const string Esc = escape_binary(TestStr);
    T.exec("INSERT INTO pqxxbin VALUES ('" + Esc + "')");

    result R = T.exec("SELECT * from pqxxbin");
    binarystring B( R.at(0).at(0) );

    if (B.empty())
      throw logic_error("Binary string became empty in conversion");

    if (B.size() != TestStr.size())
      throw logic_error("Binary string got changed from " +
	  ToString(TestStr.size()) + " to " + ToString(B.size()) + " bytes");

    if (strncmp(TestStr.c_str(), B.c_ptr(), B.size()) != 0)
      throw logic_error("Binary string was changed before first zero byte: "
	  "'" + string(B.c_ptr(), B.size()) + "'");

    binarystring::const_iterator c;
    binarystring::size_type i;
    for (i=0, c=B.begin(); i<B.size(); ++i, ++c)
    {
      if (c == B.end())
	throw logic_error("Premature end to binary string at " + ToString(i));

      if (B.data()[i] != TestStr.at(i))
	throw logic_error("Binary string byte " + ToString(i) + " "
	    "got changed from '" + ToString(TestStr[i]) + "' "
	    "to '" + ToString(B.data()[i]) + "'");
      if (B.at(i) != B.data()[i])
	throw logic_error("Inconsistent byte at offset " + ToString(i) + ": "
	    "operator[] says '" + ToString(B.at(i)) + "', "
	    "data() says '" + ToString(B.data()[i]) + "'");
    }
    if (c != B.end())
      throw logic_error("end() of binary string not reached");

#ifdef PQXX_HAVE_REVERSE_ITERATOR
    binarystring::const_reverse_iterator r;
    for (i=B.length(), r=B.rbegin(); i>0; --i, ++r)
    {
      if (r == B.rend())
	throw logic_error("Premature rend to binary string at " + ToString(i));

      if (B[i-1] != TestStr.at(i-1))
	throw logic_error("Reverse iterator differs at " + ToString(i));
    }
    if (r != B.rend())
      throw logic_error("rend() of binary string not reached");
#endif

    if (B.str() != TestStr)
      throw logic_error("Binary string got mangled: '" + B.str() + "'");
  }
  catch (const sql_error &e)
  {
    // If we're interested in the text of a failed query, we can write separate
    // exception handling code for this type of exception
    cerr << "SQL error: " << e.what() << endl
         << "Query was: '" << e.query() << "'" << endl;
    return 1;
  }
  catch (const exception &e)
  {
    // All exceptions thrown by libpqxx are derived from std::exception
    cerr << "Exception: " << e.what() << endl;
    return 2;
  }
  catch (...)
  {
    // This is really unexpected (see above)
    cerr << "Unhandled exception" << endl;
    return 100;
  }

  return 0;
}

<|endoftext|>


<commit_before>#pragma once
#ifndef OPENGM_LEARNING_BUNDLE_OPTIMIZER_HXX
#define OPENGM_LEARNING_BUNDLE_OPTIMIZER_HXX

#include "solver/BundleCollector.h"
#include "solver/QuadraticSolverFactory.h"

namespace opengm {

namespace learning {

enum OptimizerResult {

	// the minimal optimization gap was reached
	ReachedMinGap,

	// the requested number of steps was exceeded
	ReachedSteps,

	// something went wrong
	Error
};

template <typename ValueType>
class BundleOptimizer {

public:

	struct Parameter {

		Parameter() :
			lambda(1.0),
			min_gap(1e-5),
			steps(0) {}

		// regularizer weight
		double lambda;

		// stopping criteria of the bundle method optimization
		ValueType min_gap;

		// the maximal number of steps to perform, 0 = no limit
		unsigned int steps;
	};

	BundleOptimizer(const Parameter& parameter = Parameter());

	~BundleOptimizer();

	/**
	 * Start the bundle method optimization on the given oracle. The oracle has
	 * to model:
	 *
     *   Weights current;
     *   Weights gradient;
	 *   double          value;
	 *
	 *   valueAndGradient = oracle(current, value, gradient);
	 *
	 * and should return the value and gradient of the objective function
	 * (passed by reference) at point 'current'.
	 */
    template <typename Oracle, typename Weights>
    OptimizerResult optimize(Oracle& oracle, Weights& w);

private:

    template <typename Weights>
    void setupQp(const Weights& w);

	template <typename ModelWeights>
	void findMinLowerBound(ModelWeights& w, ValueType& value);

	template <typename ModelWeights>
	ValueType dot(const ModelWeights& a, const ModelWeights& b);

	Parameter _parameter;

	solver::BundleCollector _bundleCollector;

	solver::QuadraticSolverBackend* _solver;
};

template <typename T>
BundleOptimizer<T>::BundleOptimizer(const Parameter& parameter) :
	_parameter(parameter),
	_solver(0) {}

template <typename T>
BundleOptimizer<T>::~BundleOptimizer() {

	if (_solver)
		delete _solver;
}

template <typename T>
template <typename Oracle, typename Weights>
OptimizerResult
BundleOptimizer<T>::optimize(Oracle& oracle, Weights& w) {

	setupQp(w);

	/*
	  1. w_0 = 0, t = 0
	  2. t++
	  3. compute a_t = ∂L(w_t-1)/∂w
	  4. compute b_t =  L(w_t-1) - <w_t-1,a_t>
	  5. ℒ_t(w) = max_i <w,a_i> + b_i
	  6. w_t = argmin λ½|w|² + ℒ_t(w)
	  7. ε_t = min_i [ λ½|w_i|² + L(w_i) ] - [ λ½|w_t|² + ℒ_t(w_t) ]
			   ^^^^^^^^^^^^^^^^^^^^^^^^^^^   ^^^^^^^^^^^^^^^^^^^^^^^
				 smallest L(w) ever seen    current min of lower bound
	  8. if ε_t > ε, goto 2
	  9. return w_t
	*/

	T minValue = std::numeric_limits<T>::infinity();

	unsigned int t = 0;

	while (true) {

		t++;

		std::cout << std::endl << "----------------- iteration " << t << std::endl;

        Weights w_tm1 = w;

		//std::cout << "current w is " << w_tm1 << std::endl;

		// value of L at current w
		T L_w_tm1 = 0.0;

		// gradient of L at current w
        Weights a_t(w.numberOfWeights());

		// get current value and gradient
		oracle(w_tm1, L_w_tm1, a_t);

		std::cout << "       L(w)              is: " << L_w_tm1 << std::endl;
		//LOG_ALL(bundlelog)   << "      ∂L(w)/∂            is: " << a_t << std::endl;

		// update smallest observed value of regularized L
		minValue = std::min(minValue, L_w_tm1 + _parameter.lambda*0.5*dot(w_tm1, w_tm1));

		std::cout << " min_i L(w_i) + ½λ|w_i|² is: " << minValue << std::endl;

		// compute hyperplane offset
		T b_t = L_w_tm1 - dot(w_tm1, a_t);

		//LOG_ALL(bundlelog) << "adding hyperplane " << a_t << "*w + " << b_t << std::endl;

		// update lower bound
		_bundleCollector.addHyperplane(a_t, b_t);

		// minimal value of lower bound
		T minLower;

		// update w and get minimal value
		findMinLowerBound(w, minLower);

		std::cout << " min_w ℒ(w)   + ½λ|w|²   is: " << minLower << std::endl;
		//std::cout << " w* of ℒ(w)   + ½λ|w|²   is: "  << w << std::endl;

		// compute gap
		T eps_t = minValue - minLower;

		std::cout  << "          ε   is: " << eps_t << std::endl;

		// converged?
		if (eps_t <= _parameter.min_gap)
			break;
	}

	return ReachedMinGap;
}

template <typename T>
template <typename Weights>
void
BundleOptimizer<T>::setupQp(const Weights& w) {

	/*
	  w* = argmin λ½|w|² + ξ, s.t. <w,a_i> + b_i ≤ ξ ∀i
	*/

	if (!_solver)
		_solver = solver::QuadraticSolverFactory::Create();

	_solver->initialize(w.numberOfWeights() + 1, solver::Continuous);

	// one variable for each component of w and for ξ
    solver::QuadraticObjective obj(w.numberOfWeights() + 1);

	// regularizer
    for (unsigned int i = 0; i < w.numberOfWeights(); i++)
		obj.setQuadraticCoefficient(i, i, 0.5*_parameter.lambda);

	// ξ
    obj.setCoefficient(w.numberOfWeights(), 1.0);

	// we minimize
	obj.setSense(solver::Minimize);

	// we are done with the objective -- this does not change anymore
	_solver->setObjective(obj);
}

template <typename T>
template <typename ModelWeights>
void
BundleOptimizer<T>::findMinLowerBound(ModelWeights& w, T& value) {

	_solver->setConstraints(_bundleCollector.getConstraints());

	solver::Solution x;
	std::string msg;
	bool optimal = _solver->solve(x, value, msg);

	if (!optimal)
		std::cerr
				<< "[BundleOptimizer] QP could not be solved to optimality: "
				<< msg << std::endl;

	for (size_t i = 0; i < w.numberOfWeights(); i++)
		w[i] = x[i];
}

template <typename T>
template <typename ModelWeights>
T
BundleOptimizer<T>::dot(const ModelWeights& a, const ModelWeights& b) {

	OPENGM_ASSERT(a.numberOfWeights() == b.numberOfWeights());

	T d = 0.0;
	for (size_t i = 0; i < a.numberOfWeights(); i++)
		d += a[i]+b[i];

	return d;
}

} // learning

} // opengm

#endif // OPENGM_LEARNING_BUNDLE_OPTIMIZER_HXX

<commit_msg>embarrassing bug fix in bundle method<commit_after>#pragma once
#ifndef OPENGM_LEARNING_BUNDLE_OPTIMIZER_HXX
#define OPENGM_LEARNING_BUNDLE_OPTIMIZER_HXX

#include "solver/BundleCollector.h"
#include "solver/QuadraticSolverFactory.h"

namespace opengm {

namespace learning {

enum OptimizerResult {

	// the minimal optimization gap was reached
	ReachedMinGap,

	// the requested number of steps was exceeded
	ReachedSteps,

	// something went wrong
	Error
};

template <typename ValueType>
class BundleOptimizer {

public:

	struct Parameter {

		Parameter() :
			lambda(1.0),
			min_gap(1e-5),
			steps(0) {}

		// regularizer weight
		double lambda;

		// stopping criteria of the bundle method optimization
		ValueType min_gap;

		// the maximal number of steps to perform, 0 = no limit
		unsigned int steps;
	};

	BundleOptimizer(const Parameter& parameter = Parameter());

	~BundleOptimizer();

	/**
	 * Start the bundle method optimization on the given oracle. The oracle has
	 * to model:
	 *
     *   Weights current;
     *   Weights gradient;
	 *   double          value;
	 *
	 *   valueAndGradient = oracle(current, value, gradient);
	 *
	 * and should return the value and gradient of the objective function
	 * (passed by reference) at point 'current'.
	 */
    template <typename Oracle, typename Weights>
    OptimizerResult optimize(Oracle& oracle, Weights& w);

private:

    template <typename Weights>
    void setupQp(const Weights& w);

	template <typename ModelWeights>
	void findMinLowerBound(ModelWeights& w, ValueType& value);

	template <typename ModelWeights>
	ValueType dot(const ModelWeights& a, const ModelWeights& b);

	Parameter _parameter;

	solver::BundleCollector _bundleCollector;

	solver::QuadraticSolverBackend* _solver;
};

template <typename T>
BundleOptimizer<T>::BundleOptimizer(const Parameter& parameter) :
	_parameter(parameter),
	_solver(0) {}

template <typename T>
BundleOptimizer<T>::~BundleOptimizer() {

	if (_solver)
		delete _solver;
}

template <typename T>
template <typename Oracle, typename Weights>
OptimizerResult
BundleOptimizer<T>::optimize(Oracle& oracle, Weights& w) {

	setupQp(w);

	/*
	  1. w_0 = 0, t = 0
	  2. t++
	  3. compute a_t = ∂L(w_t-1)/∂w
	  4. compute b_t =  L(w_t-1) - <w_t-1,a_t>
	  5. ℒ_t(w) = max_i <w,a_i> + b_i
	  6. w_t = argmin λ½|w|² + ℒ_t(w)
	  7. ε_t = min_i [ λ½|w_i|² + L(w_i) ] - [ λ½|w_t|² + ℒ_t(w_t) ]
			   ^^^^^^^^^^^^^^^^^^^^^^^^^^^   ^^^^^^^^^^^^^^^^^^^^^^^
				 smallest L(w) ever seen    current min of lower bound
	  8. if ε_t > ε, goto 2
	  9. return w_t
	*/

	T minValue = std::numeric_limits<T>::infinity();

	unsigned int t = 0;

	while (true) {

		t++;

		std::cout << std::endl << "----------------- iteration " << t << std::endl;

        Weights w_tm1 = w;

		//std::cout << "current w is " << w_tm1 << std::endl;

		// value of L at current w
		T L_w_tm1 = 0.0;

		// gradient of L at current w
        Weights a_t(w.numberOfWeights());

		// get current value and gradient
		oracle(w_tm1, L_w_tm1, a_t);

		std::cout << "       L(w)              is: " << L_w_tm1 << std::endl;
		//LOG_ALL(bundlelog)   << "      ∂L(w)/∂            is: " << a_t << std::endl;

		// update smallest observed value of regularized L
		minValue = std::min(minValue, L_w_tm1 + _parameter.lambda*0.5*dot(w_tm1, w_tm1));

		std::cout << " min_i L(w_i) + ½λ|w_i|² is: " << minValue << std::endl;

		// compute hyperplane offset
		T b_t = L_w_tm1 - dot(w_tm1, a_t);

		//LOG_ALL(bundlelog) << "adding hyperplane " << a_t << "*w + " << b_t << std::endl;

		// update lower bound
		_bundleCollector.addHyperplane(a_t, b_t);

		// minimal value of lower bound
		T minLower;

		// update w and get minimal value
		findMinLowerBound(w, minLower);

		std::cout << " min_w ℒ(w)   + ½λ|w|²   is: " << minLower << std::endl;
		//std::cout << " w* of ℒ(w)   + ½λ|w|²   is: "  << w << std::endl;

		// compute gap
		T eps_t = minValue - minLower;

		std::cout  << "          ε   is: " << eps_t << std::endl;

		// converged?
		if (eps_t <= _parameter.min_gap)
			break;
	}

	return ReachedMinGap;
}

template <typename T>
template <typename Weights>
void
BundleOptimizer<T>::setupQp(const Weights& w) {

	/*
	  w* = argmin λ½|w|² + ξ, s.t. <w,a_i> + b_i ≤ ξ ∀i
	*/

	if (!_solver)
		_solver = solver::QuadraticSolverFactory::Create();

	_solver->initialize(w.numberOfWeights() + 1, solver::Continuous);

	// one variable for each component of w and for ξ
    solver::QuadraticObjective obj(w.numberOfWeights() + 1);

	// regularizer
    for (unsigned int i = 0; i < w.numberOfWeights(); i++)
		obj.setQuadraticCoefficient(i, i, 0.5*_parameter.lambda);

	// ξ
    obj.setCoefficient(w.numberOfWeights(), 1.0);

	// we minimize
	obj.setSense(solver::Minimize);

	// we are done with the objective -- this does not change anymore
	_solver->setObjective(obj);
}

template <typename T>
template <typename ModelWeights>
void
BundleOptimizer<T>::findMinLowerBound(ModelWeights& w, T& value) {

	_solver->setConstraints(_bundleCollector.getConstraints());

	solver::Solution x;
	std::string msg;
	bool optimal = _solver->solve(x, value, msg);

	if (!optimal)
		std::cerr
				<< "[BundleOptimizer] QP could not be solved to optimality: "
				<< msg << std::endl;

	for (size_t i = 0; i < w.numberOfWeights(); i++)
		w[i] = x[i];
}

template <typename T>
template <typename ModelWeights>
T
BundleOptimizer<T>::dot(const ModelWeights& a, const ModelWeights& b) {

	OPENGM_ASSERT(a.numberOfWeights() == b.numberOfWeights());

	T d = 0.0;
	for (size_t i = 0; i < a.numberOfWeights(); i++)
		d += a[i]*b[i];

	return d;
}

} // learning

} // opengm

#endif // OPENGM_LEARNING_BUNDLE_OPTIMIZER_HXX

<|endoftext|>


<commit_before>/**
 * @file llclassifiedstatsresponder.cpp
 * @brief Receives information about classified ad click-through
 * counts for display in the classified information UI.
 *
 * $LicenseInfo:firstyear=2007&license=viewerlgpl$
 * Second Life Viewer Source Code
 * Copyright (C) 2010, Linden Research, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation;
 * version 2.1 of the License only.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 * $/LicenseInfo$
 */

#include "llviewerprecompiledheaders.h"

#include "llclassifiedstatsresponder.h"

#include "llpanelclassified.h"
#include "llpanel.h"
#include "llhttpclient.h"
#include "llsdserialize.h"
#include "llviewerregion.h"
#include "llview.h"
#include "message.h"

#include "fspanelclassified.h"

LLClassifiedStatsResponder::LLClassifiedStatsResponder(LLUUID classified_id)
:	mClassifiedID(classified_id)
{}

/*virtual*/
void LLClassifiedStatsResponder::result(const LLSD& content)
{
	S32 teleport = content["teleport_clicks"].asInteger();
	S32 map = content["map_clicks"].asInteger();
	S32 profile = content["profile_clicks"].asInteger();
	S32 search_teleport = content["search_teleport_clicks"].asInteger();
	S32 search_map = content["search_map_clicks"].asInteger();
	S32 search_profile = content["search_profile_clicks"].asInteger();

	LLPanelClassifiedInfo::setClickThrough(	mClassifiedID,
		mClassifiedID,
		teleport + search_teleport,
		map + search_map,
		profile + search_profile,
		true);

	// <FS:Ansariel> FIRE-8787: Also update legacy profiles
	FSPanelClassifiedInfo::setClickThrough(
											teleport + search_teleport,
											map + search_map,
											profile + search_profile,
											true);
}

/*virtual*/
void LLClassifiedStatsResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
{
	LL_INFOS() << "LLClassifiedStatsResponder::error [status:" << status << "]: " << content << LL_ENDL;
}
<commit_msg>Fix merge error in LLClassifiedStatsResponder<commit_after>/**
 * @file llclassifiedstatsresponder.cpp
 * @brief Receives information about classified ad click-through
 * counts for display in the classified information UI.
 *
 * $LicenseInfo:firstyear=2007&license=viewerlgpl$
 * Second Life Viewer Source Code
 * Copyright (C) 2010, Linden Research, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation;
 * version 2.1 of the License only.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 * $/LicenseInfo$
 */

#include "llviewerprecompiledheaders.h"

#include "llclassifiedstatsresponder.h"

#include "llpanelclassified.h"
#include "llpanel.h"
#include "llhttpclient.h"
#include "llsdserialize.h"
#include "llviewerregion.h"
#include "llview.h"
#include "message.h"

#include "fspanelclassified.h"

LLClassifiedStatsResponder::LLClassifiedStatsResponder(LLUUID classified_id)
:	mClassifiedID(classified_id)
{}

/*virtual*/
void LLClassifiedStatsResponder::result(const LLSD& content)
{
	S32 teleport = content["teleport_clicks"].asInteger();
	S32 map = content["map_clicks"].asInteger();
	S32 profile = content["profile_clicks"].asInteger();
	S32 search_teleport = content["search_teleport_clicks"].asInteger();
	S32 search_map = content["search_map_clicks"].asInteger();
	S32 search_profile = content["search_profile_clicks"].asInteger();

	LLPanelClassifiedInfo::setClickThrough(	mClassifiedID,
											teleport + search_teleport,
											map + search_map,
											profile + search_profile,
											true);

	// <FS:Ansariel> FIRE-8787: Also update legacy profiles
	FSPanelClassifiedInfo::setClickThrough(	mClassifiedID,
											teleport + search_teleport,
											map + search_map,
											profile + search_profile,
											true);
}

/*virtual*/
void LLClassifiedStatsResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
{
	LL_INFOS() << "LLClassifiedStatsResponder::error [status:" << status << "]: " << content << LL_ENDL;
}
<|endoftext|>


<commit_before>#include "DDImage/PixelIop.h"
#include "DDImage/Row.h"
#include "DDImage/Knobs.h"

static const char* const HELP =
"This node remaps the input between 2 values "
"using a linear interpolation algoritmh";

using namespace DD::Image;

class RemapIop : public PixelIop
{

	double lowValue, highValue;

public:

	RemapIop(Node* node) : PixelIop(node)
	{
		lowValue = 0.0f;
		highValue = 1.0f;
	}

	void _validate(bool);
	void in_channels(int, ChannelSet&) const;
	void pixel_engine(const Row&, int, int, int, ChannelMask, Row&);
	virtual void knobs(Knob_Callback);

	static const Iop::Description d;

	const char* Class() const { return d.name; }
	const char* node_help() const { return HELP; }

};

void RemapIop::_validate(bool for_real)
{
	copy_info();
	if(lowValue == 0.0f && highValue == 1.0f)
		set_out_channels(Mask_None);
	else
		set_out_channels(Mask_All);
}

void RemapIop::in_channels(int input, ChannelSet &mask) const
{
	// mask is unchanged, PixelIop's variant on request
}

void RemapIop::pixel_engine(const Row& in, int y, int x, int r, ChannelMask channels, Row& out)
{
	foreach (z, channels){
		const float* inptr = in[z] + x;
		const float* END = inptr + (r - x);
		float* outptr = out.writable(z) + x;

		while(inptr < END)
			*outptr++ = lowValue + *inptr++ * highValue;
	}
}

void RemapIop::knobs(Knob_Callback f)
{
	Float_knob(f, &lowValue, "Low");
	Float_knob(f, &highValue, "High");
}

static Iop* build(Node *node) { return new RemapIop(node); }
const Iop::Description RemapIop::d("Remap", "Remap", build);
<commit_msg>changed low and highvalue from double to float<commit_after>#include "DDImage/PixelIop.h"
#include "DDImage/Row.h"
#include "DDImage/Knobs.h"

static const char* const HELP =
"This node remaps the input between 2 values "
"using a linear interpolation algoritmh";

using namespace DD::Image;

class RemapIop : public PixelIop
{

	float lowValue, highValue;

public:

	RemapIop(Node* node) : PixelIop(node)
	{
		lowValue = 0.0f;
		highValue = 1.0f;
	}

	void _validate(bool);
	void in_channels(int, ChannelSet&) const;
	void pixel_engine(const Row&, int, int, int, ChannelMask, Row&);
	virtual void knobs(Knob_Callback);

	static const Iop::Description d;

	const char* Class() const { return d.name; }
	const char* node_help() const { return HELP; }

};

void RemapIop::_validate(bool for_real)
{
	copy_info();
	if(lowValue == 0.0f && highValue == 1.0f)
		set_out_channels(Mask_None);
	else
		set_out_channels(Mask_All);
}

void RemapIop::in_channels(int input, ChannelSet &mask) const
{
	// mask is unchanged, PixelIop's variant on request
}

void RemapIop::pixel_engine(const Row& in, int y, int x, int r, ChannelMask channels, Row& out)
{
	foreach (z, channels){
		const float* inptr = in[z] + x;
		const float* END = inptr + (r - x);
		float* outptr = out.writable(z) + x;

		while(inptr < END)
			*outptr++ = lowValue + *inptr++ * highValue;
	}
}

void RemapIop::knobs(Knob_Callback f)
{
	Float_knob(f, &lowValue, "Low");
	Float_knob(f, &highValue, "High");
}

static Iop* build(Node *node) { return new RemapIop(node); }
const Iop::Description RemapIop::d("Remap", "Remap", build);
<|endoftext|>