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

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkVoronoiSegmentationImageFilterTest.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 2001 Insight Consortium
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.

 * The name of the Insight Consortium, nor the names of any consortium members,
   nor 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 HOLDER 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 "itkVoronoiSegmentationImageFilter.h"
#include "itkImageRegionIteratorWithIndex.h"
#include "itkImage.h"
#include "vnl/vnl_sample.h"
#include <stdio.h>

const int WIDTH = 256;
const int HEIGHT = 256;

typedef itk::Image<unsigned short,2> UShortImage;
typedef itk::VoronoiSegmentationImageFilter<UShortImage, UShortImage> VorSeg;

int main(void){
  VorSeg::Pointer testVorseg(VorSeg::New());
  UShortImage::Pointer inputIMG = UShortImage::New();
  UShortImage::SizeType size={{WIDTH,HEIGHT}};
  UShortImage::IndexType index=UShortImage::IndexType::ZeroIndex;
  UShortImage::RegionType region;

  region.SetSize(size);
  region.SetIndex(index);

  inputIMG->SetLargestPossibleRegion( region );
  inputIMG->SetBufferedRegion( region );
  inputIMG->SetRequestedRegion( region );
  inputIMG->Allocate();

  itk::ImageRegionIteratorWithIndex <UShortImage> it(inputIMG, region);

  // background: random field with mean: 500, std: 50
  while( !it.IsAtEnd()) {
    it.Set((unsigned short)(vnl_sample_uniform(450,550)) );
    ++it;
  }

  //object (2): random field with mean: 520, std: 20;
  unsigned int i;
  unsigned int j;
  for(i = 30; i < 94; i++){
    index[0] = i;
    for (j = 30; j< 94; j++){
      index[1] = j;
      inputIMG->SetPixel(index, (unsigned short)(vnl_sample_uniform(500,540)) );
    }
  }

  for(i = 150; i < 214; i++){
    index[0] = i;
    for (j = 150; j< 214; j++){
      index[1] = j;
      inputIMG->SetPixel(index, (unsigned short)(vnl_sample_uniform(500,540)) );
    }
  }

  int k;
  unsigned short TestImg[65536];

  testVorseg->SetInput(inputIMG);
  testVorseg->SetMean(520);
  testVorseg->SetVar(20);
  testVorseg->SetMeanTolerance(10);
  testVorseg->SetVarTolerance(20);
  testVorseg->SetNumberOfSeeds(400);
  testVorseg->SetSteps(5);

  testVorseg->Update();

  itk::ImageRegionIteratorWithIndex <UShortImage> ot(testVorseg->GetOutput(), region);

  k=0;
  while( !ot.IsAtEnd()){
    TestImg[k]=ot.Get();
    k++;
    ++ot;
  }

  /* Test Ok on local machine.
  FILE *imgfile = fopen("output.raw","wb");
  fwrite(TestImg,2,65536,imgfile);
  fclose(imgfile);

  imgfile = fopen("input.raw","wb");
  it.GoToBegin();
  k=0;
  while( !it.IsAtEnd()){
    TestImg[k]=it.Get();
    k++;
    ++it;
  }
  fwrite(TestImg,2,65536,imgfile);
  fclose(imgfile);
*/
  std::cout<<"Test Succeed!"<<std::endl;
  return 0;
}

<commit_msg>ERR: need initialization before generateData<commit_after>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkVoronoiSegmentationImageFilterTest.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 2001 Insight Consortium
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.

 * The name of the Insight Consortium, nor the names of any consortium members,
   nor 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 HOLDER 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 "itkVoronoiSegmentationImageFilter.h"
#include "itkImageRegionIteratorWithIndex.h"
#include "itkImage.h"
#include "vnl/vnl_sample.h"
#include <stdio.h>

const int WIDTH = 256;
const int HEIGHT = 256;

typedef itk::Image<unsigned short,2> UShortImage;
typedef itk::VoronoiSegmentationImageFilter<UShortImage, UShortImage> VorSeg;

int main(void){
  VorSeg::Pointer testVorseg(VorSeg::New());
  UShortImage::Pointer inputIMG = UShortImage::New();
  UShortImage::SizeType size={{WIDTH,HEIGHT}};
  UShortImage::IndexType index=UShortImage::IndexType::ZeroIndex;
  UShortImage::RegionType region;

  region.SetSize(size);
  region.SetIndex(index);

  inputIMG->SetLargestPossibleRegion( region );
  inputIMG->SetBufferedRegion( region );
  inputIMG->SetRequestedRegion( region );
  inputIMG->Allocate();

  itk::ImageRegionIteratorWithIndex <UShortImage> it(inputIMG, region);

  // background: random field with mean: 500, std: 50
  while( !it.IsAtEnd()) {
    it.Set((unsigned short)(vnl_sample_uniform(450,550)) );
    ++it;
  }

  //object (2): random field with mean: 520, std: 20;
  unsigned int i;
  unsigned int j;
  for(i = 30; i < 94; i++){
    index[0] = i;
    for (j = 30; j< 94; j++){
      index[1] = j;
      inputIMG->SetPixel(index, (unsigned short)(vnl_sample_uniform(500,540)) );
    }
  }

  for(i = 150; i < 214; i++){
    index[0] = i;
    for (j = 150; j< 214; j++){
      index[1] = j;
      inputIMG->SetPixel(index, (unsigned short)(vnl_sample_uniform(500,540)) );
    }
  }

  int k;
  unsigned short TestImg[65536];

  testVorseg->SetInput(inputIMG);
  testVorseg->SetMean(520);
  testVorseg->SetVar(20);
  testVorseg->SetMeanTolerance(10);
  testVorseg->SetVarTolerance(20);
  testVorseg->SetNumberOfSeeds(400);
  testVorseg->SetSteps(5);

  testVorseg->InitializeSegment();
  testVorseg->Update();

  itk::ImageRegionIteratorWithIndex <UShortImage> ot(testVorseg->GetOutput(), region);

  k=0;
  while( !ot.IsAtEnd()){
    TestImg[k]=ot.Get();
    k++;
    ++ot;
  }

  /* Test Ok on local machine.
  FILE *imgfile = fopen("output.raw","wb");
  fwrite(TestImg,2,65536,imgfile);
  fclose(imgfile);

  imgfile = fopen("input.raw","wb");
  it.GoToBegin();
  k=0;
  while( !it.IsAtEnd()){
    TestImg[k]=it.Get();
    k++;
    ++it;
  }
  fwrite(TestImg,2,65536,imgfile);
  fclose(imgfile);
*/
  std::cout<<"Test Succeed!"<<std::endl;
  return 0;
}

<|endoftext|>


<commit_before>#include "symbol_table_class.hpp"

namespace assembler
{

bool symbol_table::sym_name_has_dot_f( const string_view& name ) const
{
	if ( name.size() >= 2 )
	{
		return ( ( *( name.cend() - 2 ) == '.' )
			&& ( *( name.cend() - 1 ) == 'f' ) );
	}

	return false;
}

string_view symbol_table::get_name( std::string&& name_as_str )
{
	//auto maybe_ret = str_set().find(name_as_str);
	//
	//if ( maybe_ret != str_set().end() )
	//{
	//	return string_view(*maybe_ret);
	//}
	//
	//return string_view();

	return string_view(*str_set().insert(std::move(name_as_str)).first);
}

symbol& symbol_table::enter( std::string&& name_as_str, tok typ,
	int val, size_t instr_grp )
{
	string_view name = get_name(std::move(name_as_str));

	return table().insert( { name,
		symbol( name, typ, val, instr_grp, sym_name_has_dot_f(name) ) } )
		.first->second;
}

}
<commit_msg>stuffs<commit_after>#include "symbol_table_class.hpp"

namespace assembler
{

bool symbol_table::sym_name_has_dot_f( const string_view& name ) const
{
	if ( name.size() >= 2 )
	{
		return ( ( *( name.cend() - 2 ) == '.' )
			&& ( *( name.cend() - 1 ) == 'f' ) );
	}

	return false;
}

string_view symbol_table::get_name( std::string&& name_as_str )
{
	return string_view(*str_set().insert(std::move(name_as_str)).first);
}

symbol& symbol_table::enter( std::string&& name_as_str, tok typ,
	int val, size_t instr_grp )
{
	string_view name = get_name(std::move(name_as_str));

	return table().insert( { name,
		symbol( name, typ, val, instr_grp, sym_name_has_dot_f(name) ) } )
		.first->second;
}

}
<|endoftext|>


<commit_before>// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ui/gl/vsync_provider.h"

#include <math.h>

#include "base/logging.h"
#include "base/time.h"

namespace {

// These constants define a reasonable range for a calculated refresh interval.
// Calculating refreshes out of this range will be considered a fatal error.
const int64 kMinVsyncIntervalUs = base::Time::kMicrosecondsPerSecond / 400;
const int64 kMaxVsyncIntervalUs = base::Time::kMicrosecondsPerSecond / 10;

// How much noise we'll tolerate between successive computed intervals before
// we think the latest computed interval is invalid (noisey due to
// monitor configuration change, moving a window between monitors, etc.).
const double kRelativeIntervalDifferenceThreshold = 0.05;

}  // namespace

namespace gfx {

VSyncProvider::VSyncProvider() {
}

VSyncProvider::~VSyncProvider() {
}

SyncControlVSyncProvider::SyncControlVSyncProvider()
    : VSyncProvider(),
      last_media_stream_counter_(0) {
  // On platforms where we can't get an accurate reading on the refresh
  // rate we fall back to the assumption that we're displaying 60 frames
  // per second.
  last_good_interval_ = base::TimeDelta::FromSeconds(1) / 60;
}

SyncControlVSyncProvider::~SyncControlVSyncProvider() {
}

void SyncControlVSyncProvider::GetVSyncParameters(
    const UpdateVSyncCallback& callback) {
#if defined(OS_LINUX)
  base::TimeTicks timebase;

  // The actual clock used for the system time returned by glXGetSyncValuesOML
  // is unspecified. In practice, the clock used is likely to be either
  // CLOCK_REALTIME or CLOCK_MONOTONIC, so we compare the returned time to the
  // current time according to both clocks, and assume that the returned time
  // was produced by the clock whose current time is closest to it, subject
  // to the restriction that the returned time must not be in the future
  // (since it is the time of a vblank that has already occurred).
  int64 system_time;
  int64 media_stream_counter;
  int64 swap_buffer_counter;
  if (!GetSyncValues(&system_time,
                     &media_stream_counter,
                     &swap_buffer_counter))
    return;

  // Both Intel and Mali drivers will return TRUE for GetSyncValues
  // but a value of 0 for MSC if they cannot access the CRTC data structure
  // associated with the surfrace.
  if (media_stream_counter == 0)
    return;

  struct timespec real_time;
  struct timespec monotonic_time;
  clock_gettime(CLOCK_REALTIME, &real_time);
  clock_gettime(CLOCK_MONOTONIC, &monotonic_time);

  int64 real_time_in_microseconds =
    real_time.tv_sec * base::Time::kMicrosecondsPerSecond +
    real_time.tv_nsec / base::Time::kNanosecondsPerMicrosecond;
  int64 monotonic_time_in_microseconds =
    monotonic_time.tv_sec * base::Time::kMicrosecondsPerSecond +
    monotonic_time.tv_nsec / base::Time::kNanosecondsPerMicrosecond;

  // We need the time according to CLOCK_MONOTONIC, so if we've been given
  // a time from CLOCK_REALTIME, we need to convert.
  bool time_conversion_needed =
      llabs(system_time - real_time_in_microseconds) <
      llabs(system_time - monotonic_time_in_microseconds);

  if (time_conversion_needed)
    system_time += monotonic_time_in_microseconds - real_time_in_microseconds;

  // Return if |system_time| is more than 1 frames in the future.
  int64 interval_in_microseconds = last_good_interval_.InMicroseconds();
  if (system_time > monotonic_time_in_microseconds + interval_in_microseconds)
    return;

  // If |system_time| is slightly in the future, adjust it to the previous
  // frame and use the last frame counter to prevent issues in the callback.
  if (system_time > monotonic_time_in_microseconds) {
    system_time -= interval_in_microseconds;
    media_stream_counter--;
  }
  if (monotonic_time_in_microseconds - system_time >
      base::Time::kMicrosecondsPerSecond)
    return;

  timebase = base::TimeTicks::FromInternalValue(system_time);

  // Only need the previous calculated interval for our filtering.
  while (last_computed_intervals_.size() > 1)
    last_computed_intervals_.pop();

  int32 numerator, denominator;
  if (GetMscRate(&numerator, &denominator)) {
    last_computed_intervals_.push(
        base::TimeDelta::FromSeconds(denominator) / numerator);
  } else if (!last_timebase_.is_null()) {
    base::TimeDelta timebase_diff = timebase - last_timebase_;
    uint64 counter_diff = media_stream_counter -
        last_media_stream_counter_;
    if (counter_diff > 0 && timebase > last_timebase_)
      last_computed_intervals_.push(timebase_diff / counter_diff);
  }

  if (last_computed_intervals_.size() == 2) {
    const base::TimeDelta& old_interval = last_computed_intervals_.front();
    const base::TimeDelta& new_interval = last_computed_intervals_.back();

    double relative_change =
        fabs(old_interval.InMillisecondsF() - new_interval.InMillisecondsF()) /
        new_interval.InMillisecondsF();
    if (relative_change < kRelativeIntervalDifferenceThreshold) {
      if (new_interval.InMicroseconds() < kMinVsyncIntervalUs ||
          new_interval.InMicroseconds() > kMaxVsyncIntervalUs) {
        LOG(FATAL) << "Calculated bogus refresh interval of "
                   << new_interval.InMicroseconds() << " us. "
                   << "Last time base of "
                   << last_timebase_.ToInternalValue() << " us. "
                   << "Current time base of "
                   << timebase.ToInternalValue() << " us. "
                   << "Last media stream count of "
                   << last_media_stream_counter_ << ". "
                   << "Current media stream count of "
                   << media_stream_counter << ".";
      } else {
        last_good_interval_ = new_interval;
      }
    }
  }

  last_timebase_ = timebase;
  last_media_stream_counter_ = media_stream_counter;
  callback.Run(timebase, last_good_interval_);
#endif  // defined(OS_LINUX)
}

}  // namespace gfx
<commit_msg>CrOS: Keep the sign on the media stream counter diff.<commit_after>// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ui/gl/vsync_provider.h"

#include <math.h>

#include "base/logging.h"
#include "base/time.h"

namespace {

// These constants define a reasonable range for a calculated refresh interval.
// Calculating refreshes out of this range will be considered a fatal error.
const int64 kMinVsyncIntervalUs = base::Time::kMicrosecondsPerSecond / 400;
const int64 kMaxVsyncIntervalUs = base::Time::kMicrosecondsPerSecond / 10;

// How much noise we'll tolerate between successive computed intervals before
// we think the latest computed interval is invalid (noisey due to
// monitor configuration change, moving a window between monitors, etc.).
const double kRelativeIntervalDifferenceThreshold = 0.05;

}  // namespace

namespace gfx {

VSyncProvider::VSyncProvider() {
}

VSyncProvider::~VSyncProvider() {
}

SyncControlVSyncProvider::SyncControlVSyncProvider()
    : VSyncProvider(),
      last_media_stream_counter_(0) {
  // On platforms where we can't get an accurate reading on the refresh
  // rate we fall back to the assumption that we're displaying 60 frames
  // per second.
  last_good_interval_ = base::TimeDelta::FromSeconds(1) / 60;
}

SyncControlVSyncProvider::~SyncControlVSyncProvider() {
}

void SyncControlVSyncProvider::GetVSyncParameters(
    const UpdateVSyncCallback& callback) {
#if defined(OS_LINUX)
  base::TimeTicks timebase;

  // The actual clock used for the system time returned by glXGetSyncValuesOML
  // is unspecified. In practice, the clock used is likely to be either
  // CLOCK_REALTIME or CLOCK_MONOTONIC, so we compare the returned time to the
  // current time according to both clocks, and assume that the returned time
  // was produced by the clock whose current time is closest to it, subject
  // to the restriction that the returned time must not be in the future
  // (since it is the time of a vblank that has already occurred).
  int64 system_time;
  int64 media_stream_counter;
  int64 swap_buffer_counter;
  if (!GetSyncValues(&system_time,
                     &media_stream_counter,
                     &swap_buffer_counter))
    return;

  // Both Intel and Mali drivers will return TRUE for GetSyncValues
  // but a value of 0 for MSC if they cannot access the CRTC data structure
  // associated with the surfrace.
  if (media_stream_counter == 0)
    return;

  struct timespec real_time;
  struct timespec monotonic_time;
  clock_gettime(CLOCK_REALTIME, &real_time);
  clock_gettime(CLOCK_MONOTONIC, &monotonic_time);

  int64 real_time_in_microseconds =
    real_time.tv_sec * base::Time::kMicrosecondsPerSecond +
    real_time.tv_nsec / base::Time::kNanosecondsPerMicrosecond;
  int64 monotonic_time_in_microseconds =
    monotonic_time.tv_sec * base::Time::kMicrosecondsPerSecond +
    monotonic_time.tv_nsec / base::Time::kNanosecondsPerMicrosecond;

  // We need the time according to CLOCK_MONOTONIC, so if we've been given
  // a time from CLOCK_REALTIME, we need to convert.
  bool time_conversion_needed =
      llabs(system_time - real_time_in_microseconds) <
      llabs(system_time - monotonic_time_in_microseconds);

  if (time_conversion_needed)
    system_time += monotonic_time_in_microseconds - real_time_in_microseconds;

  // Return if |system_time| is more than 1 frames in the future.
  int64 interval_in_microseconds = last_good_interval_.InMicroseconds();
  if (system_time > monotonic_time_in_microseconds + interval_in_microseconds)
    return;

  // If |system_time| is slightly in the future, adjust it to the previous
  // frame and use the last frame counter to prevent issues in the callback.
  if (system_time > monotonic_time_in_microseconds) {
    system_time -= interval_in_microseconds;
    media_stream_counter--;
  }
  if (monotonic_time_in_microseconds - system_time >
      base::Time::kMicrosecondsPerSecond)
    return;

  timebase = base::TimeTicks::FromInternalValue(system_time);

  // Only need the previous calculated interval for our filtering.
  while (last_computed_intervals_.size() > 1)
    last_computed_intervals_.pop();

  int32 numerator, denominator;
  if (GetMscRate(&numerator, &denominator)) {
    last_computed_intervals_.push(
        base::TimeDelta::FromSeconds(denominator) / numerator);
  } else if (!last_timebase_.is_null()) {
    base::TimeDelta timebase_diff = timebase - last_timebase_;
    int64 counter_diff = media_stream_counter -
        last_media_stream_counter_;
    if (counter_diff > 0 && timebase > last_timebase_)
      last_computed_intervals_.push(timebase_diff / counter_diff);
  }

  if (last_computed_intervals_.size() == 2) {
    const base::TimeDelta& old_interval = last_computed_intervals_.front();
    const base::TimeDelta& new_interval = last_computed_intervals_.back();

    double relative_change =
        fabs(old_interval.InMillisecondsF() - new_interval.InMillisecondsF()) /
        new_interval.InMillisecondsF();
    if (relative_change < kRelativeIntervalDifferenceThreshold) {
      if (new_interval.InMicroseconds() < kMinVsyncIntervalUs ||
          new_interval.InMicroseconds() > kMaxVsyncIntervalUs) {
        LOG(FATAL) << "Calculated bogus refresh interval of "
                   << new_interval.InMicroseconds() << " us. "
                   << "Last time base of "
                   << last_timebase_.ToInternalValue() << " us. "
                   << "Current time base of "
                   << timebase.ToInternalValue() << " us. "
                   << "Last media stream count of "
                   << last_media_stream_counter_ << ". "
                   << "Current media stream count of "
                   << media_stream_counter << ".";
      } else {
        last_good_interval_ = new_interval;
      }
    }
  }

  last_timebase_ = timebase;
  last_media_stream_counter_ = media_stream_counter;
  callback.Run(timebase, last_good_interval_);
#endif  // defined(OS_LINUX)
}

}  // namespace gfx
<|endoftext|>


<commit_before>//------------------------------------------------------------------------------
//  stringAtomTable.cc
//------------------------------------------------------------------------------
#include "Pre.h"
#include <cstring>
#include "stringAtomTable.h"
#if ORYOL_USE_VLD
#include "vld.h"
#endif

namespace Oryol {

ORYOL_THREADLOCAL_PTR(stringAtomTable) stringAtomTable::ptr = nullptr;

//------------------------------------------------------------------------------
stringAtomTable*
stringAtomTable::threadLocalPtr() {
    // NOTE: this object can never be released, even if a thread is left
    // since StringAtom object can move to other threads, thus memory
    // leak detectors will complain about these allocations on program
    // exit
    if (!ptr) {
        #if ORYOL_USE_VLD
        VLDDisable();
        #endif
        ptr = Memory::New<stringAtomTable>();
        #if ORYOL_USE_VLD
        VLDEnable();
        #endif
    }
    return ptr;
}

//------------------------------------------------------------------------------
const stringAtomBuffer::Header*
stringAtomTable::Find(int32_t hash, const char* str) const {

    // need to create a temp object for searching in the set
    stringAtomBuffer::Header dummyHead(this, hash, 0, str);
    Entry dummyEntry(&dummyHead);
    auto ptr = this->table.Find(dummyEntry);
    if (nullptr == ptr) {
        return nullptr;
    }
    else {
        o_assert(nullptr != ptr->header);
        return ptr->header;
    }
}

//------------------------------------------------------------------------------
const stringAtomBuffer::Header*
stringAtomTable::Add(int32_t hash, const char* str) {

    #if ORYOL_DEBUG
    o_assert(nullptr == this->Find(hash, str));
    #endif
    #if ORYOL_USE_VLD
    VLDDisable();
    #endif

    // add new string to the string buffer
    const stringAtomBuffer::Header* newHeader = this->buffer.AddString(this, hash, str);
    o_assert(nullptr != newHeader);

    // add new entry to our lookup table
    this->table.Add(Entry(newHeader));

    #if ORYOL_USE_VLD
    VLDEnable();
    #endif
    return newHeader;
}

//------------------------------------------------------------------------------
int32_t
stringAtomTable::HashForString(const char* str) {

    // see here: http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx
    const char* p = str;
    int32_t h = 0;
    char c;
    while (0 != (c = *p++))
    {
        h += c;
        h += (h << 10);
        h ^= (h >> 6);
    }
    h += (h << 3);
    h ^= (h >> 11);
    h += (h << 15);
    return h;
}

//------------------------------------------------------------------------------
bool
stringAtomTable::Entry::operator==(const Entry& rhs) const {

    #if ORYOL_DEBUG
    o_assert(this->header != 0 && rhs.header != 0);
    o_assert(this->header->hash != 0 && rhs.header->hash != 0);
    o_assert(this->header->str != 0 && rhs.header->str != 0);
    #endif

    if (this->header->hash != rhs.header->hash) {
        // if hashes differ, the entries are definitely not equal
        return false;
    }
    else {
        // if hashes are identical, need to do a strcmp
        return (0 == std::strcmp(this->header->str, rhs.header->str));
    }
}

//------------------------------------------------------------------------------
bool
stringAtomTable::Entry::operator<(const Entry& rhs) const {

    #if ORYOL_DEBUG
    o_assert(this->header != 0 && rhs.header != 0);
    o_assert(this->header->hash != 0 && rhs.header->hash != 0);
    o_assert(this->header->str != 0 && rhs.header->str != 0);
    #endif
    return std::strcmp(this->header->str, rhs.header->str) < 0;
}

} // namespace Oryol

<commit_msg>stringAtomTable.cc: fix an UB bug (shift of signed integer), found by clang's UB sanitizer<commit_after>//------------------------------------------------------------------------------
//  stringAtomTable.cc
//------------------------------------------------------------------------------
#include "Pre.h"
#include <cstring>
#include "stringAtomTable.h"
#if ORYOL_USE_VLD
#include "vld.h"
#endif

namespace Oryol {

ORYOL_THREADLOCAL_PTR(stringAtomTable) stringAtomTable::ptr = nullptr;

//------------------------------------------------------------------------------
stringAtomTable*
stringAtomTable::threadLocalPtr() {
    // NOTE: this object can never be released, even if a thread is left
    // since StringAtom object can move to other threads, thus memory
    // leak detectors will complain about these allocations on program
    // exit
    if (!ptr) {
        #if ORYOL_USE_VLD
        VLDDisable();
        #endif
        ptr = Memory::New<stringAtomTable>();
        #if ORYOL_USE_VLD
        VLDEnable();
        #endif
    }
    return ptr;
}

//------------------------------------------------------------------------------
const stringAtomBuffer::Header*
stringAtomTable::Find(int32_t hash, const char* str) const {

    // need to create a temp object for searching in the set
    stringAtomBuffer::Header dummyHead(this, hash, 0, str);
    Entry dummyEntry(&dummyHead);
    auto ptr = this->table.Find(dummyEntry);
    if (nullptr == ptr) {
        return nullptr;
    }
    else {
        o_assert(nullptr != ptr->header);
        return ptr->header;
    }
}

//------------------------------------------------------------------------------
const stringAtomBuffer::Header*
stringAtomTable::Add(int32_t hash, const char* str) {

    #if ORYOL_DEBUG
    o_assert(nullptr == this->Find(hash, str));
    #endif
    #if ORYOL_USE_VLD
    VLDDisable();
    #endif

    // add new string to the string buffer
    const stringAtomBuffer::Header* newHeader = this->buffer.AddString(this, hash, str);
    o_assert(nullptr != newHeader);

    // add new entry to our lookup table
    this->table.Add(Entry(newHeader));

    #if ORYOL_USE_VLD
    VLDEnable();
    #endif
    return newHeader;
}

//------------------------------------------------------------------------------
int32_t
stringAtomTable::HashForString(const char* str) {

    // see here: http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx
    const char* p = str;
    uint32_t h = 0;
    char c;
    while (0 != (c = *p++))
    {
        h += c;
        h += (h << 10);
        h ^= (h >> 6);
    }
    h += (h << 3);
    h ^= (h >> 11);
    h += (h << 15);
    return h;
}

//------------------------------------------------------------------------------
bool
stringAtomTable::Entry::operator==(const Entry& rhs) const {

    #if ORYOL_DEBUG
    o_assert(this->header != 0 && rhs.header != 0);
    o_assert(this->header->hash != 0 && rhs.header->hash != 0);
    o_assert(this->header->str != 0 && rhs.header->str != 0);
    #endif

    if (this->header->hash != rhs.header->hash) {
        // if hashes differ, the entries are definitely not equal
        return false;
    }
    else {
        // if hashes are identical, need to do a strcmp
        return (0 == std::strcmp(this->header->str, rhs.header->str));
    }
}

//------------------------------------------------------------------------------
bool
stringAtomTable::Entry::operator<(const Entry& rhs) const {

    #if ORYOL_DEBUG
    o_assert(this->header != 0 && rhs.header != 0);
    o_assert(this->header->hash != 0 && rhs.header->hash != 0);
    o_assert(this->header->str != 0 && rhs.header->str != 0);
    #endif
    return std::strcmp(this->header->str, rhs.header->str) < 0;
}

} // namespace Oryol

<|endoftext|>


<commit_before>//
//  TilesRenderParameters.hpp
//  G3MiOSSDK
//
//  Created by Diego Gomez Deck on 08/08/12.
//
//

#ifndef G3MiOSSDK_TilesRenderParameters_hpp
#define G3MiOSSDK_TilesRenderParameters_hpp

//#include "Sector.hpp"
//#include "Vector2I.hpp"
#include "URL.hpp"

class TilesRenderParameters {
public:
  const bool _renderDebug;
  const bool _useTilesSplitBudget;
  const bool _forceFirstLevelTilesRenderOnStart;
  const bool _incrementalTileQuality;
  const bool _renderIncompletePlanet;
  const URL  _incompletePlanetTexureURL;

  TilesRenderParameters(const bool renderDebug,
                        const bool useTilesSplitBudget,
                        const bool forceFirstLevelTilesRenderOnStart,
                        const bool incrementalTileQuality,
                        const bool renderIncompletePlanet,
                        const URL& incompletePlanetTexureURL) :
  _renderDebug(renderDebug),
  _useTilesSplitBudget(useTilesSplitBudget),
  _forceFirstLevelTilesRenderOnStart(forceFirstLevelTilesRenderOnStart),
  _incrementalTileQuality(incrementalTileQuality),
  _renderIncompletePlanet(renderIncompletePlanet),
  _incompletePlanetTexureURL(incompletePlanetTexureURL)
  {

  }

  ~TilesRenderParameters() {
  }

};

#endif
<commit_msg>New renderIncompletePlanet mode in TileRenderer<commit_after>//
//  TilesRenderParameters.hpp
//  G3MiOSSDK
//
//  Created by Diego Gomez Deck on 08/08/12.
//
//

#ifndef G3MiOSSDK_TilesRenderParameters_hpp
#define G3MiOSSDK_TilesRenderParameters_hpp

//#include "Sector.hpp"
//#include "Vector2I.hpp"
#include "URL.hpp"

class TilesRenderParameters {
public:
  const bool _renderDebug;
  const bool _useTilesSplitBudget;
  const bool _forceFirstLevelTilesRenderOnStart;
  const bool _incrementalTileQuality;
  const bool _renderIncompletePlanet;
#ifdef C_CODE
  const URL  _incompletePlanetTexureURL;
#endif
#ifdef JAVA_CODE
  public final URL _incompletePlanetTexureURL;
#endif

  TilesRenderParameters(const bool renderDebug,
                        const bool useTilesSplitBudget,
                        const bool forceFirstLevelTilesRenderOnStart,
                        const bool incrementalTileQuality,
                        const bool renderIncompletePlanet,
                        const URL& incompletePlanetTexureURL) :
  _renderDebug(renderDebug),
  _useTilesSplitBudget(useTilesSplitBudget),
  _forceFirstLevelTilesRenderOnStart(forceFirstLevelTilesRenderOnStart),
  _incrementalTileQuality(incrementalTileQuality),
  _renderIncompletePlanet(renderIncompletePlanet),
  _incompletePlanetTexureURL(incompletePlanetTexureURL)
  {

  }

  ~TilesRenderParameters() {
  }

};

#endif
<|endoftext|>


<commit_before>#include <math.h>
#include <stdio.h>
#include <sstream>

#include "position.h"

namespace cyclus {
namespace toolkit {

Position::Position() : latitude_(0), longitude_(0) {}

Position::Position(double decimal_lat, double decimal_lon) {
  LatCheck(decimal_lat);
  LonCheck(decimal_lon);
  latitude_ = SetPrecision(decimal_lat * CYCLUS_DECIMAL_SECOND_MULTIPLIER, 1);
  longitude_ = SetPrecision(decimal_lon * CYCLUS_DECIMAL_SECOND_MULTIPLIER, 1);
}

Position::~Position() {}

double Position::latitude() const {
  return SetPrecision(latitude_ / CYCLUS_DECIMAL_SECOND_MULTIPLIER, 6);
}

double Position::longitude() const {
  return SetPrecision(longitude_ / CYCLUS_DECIMAL_SECOND_MULTIPLIER, 6);
}

void Position::latitude(double lat) {
  LatCheck(lat);
  latitude_ = SetPrecision(lat * CYCLUS_DECIMAL_SECOND_MULTIPLIER, 1);
}

void Position::longitude(double lon) {
  LonCheck(lon);
  longitude_ = SetPrecision(lon * CYCLUS_DECIMAL_SECOND_MULTIPLIER, 1);
}

void Position::set_position(double lat, double lon) {
  LatCheck(lat);
  LonCheck(lon);
  latitude_ = SetPrecision(lat * CYCLUS_DECIMAL_SECOND_MULTIPLIER, 1);
  longitude_ = SetPrecision(lon * CYCLUS_DECIMAL_SECOND_MULTIPLIER, 1);
}

void Position::LatCheck(double lat) {
  if (lat > 90 || lat < -90){
    std::stringstream msg;
    msg << "The provided latitude (" << lat
        << ") is outside the acceptable range.";
    throw ValueError(msg.str());
  }
}

void Position::LonCheck(double lon) {
  if (lon > 180 || lon < -180){
    std::stringstream msg;
    msg << "The provided longitude (" << lon
        << ") is outside the acceptable range.";
    throw ValueError(msg.str());
  }
}

double Position::Distance(Position target) const {
  double earth_radius = 6372.8;  // in kilometers (KM)
  double curr_longitude = this->longitude() * M_PI / 180;
  double curr_latitude = this->latitude() * M_PI / 180;
  double tarlongitude = target.longitude() * M_PI / 180;
  double tarlatitude = target.latitude() * M_PI / 180;
  double dlong = tarlongitude - curr_longitude;
  double dlat = tarlatitude - curr_latitude;

  double half_chord_length_sq =
      pow(sin(dlat / 2), 2) +
      pow(sin(dlong / 2), 2) * cos(curr_latitude) * cos(tarlatitude);

  double angular_distance =
      2 * atan2(sqrt(half_chord_length_sq), sqrt(1 - half_chord_length_sq));
  return earth_radius * angular_distance;
}

std::string Position::ToString(Position::StringFormat format) const {
  std::stringstream lat_string;
  std::stringstream lon_string;
  double lat = this->latitude();
  double lon = this->longitude();
  switch (format) {
    case StringFormat::DEGREES:
      lat_string << ToStringHelperLat(format, lat);
      lon_string << ToStringHelperLon(format, lon);
      break;
    case StringFormat::DEGREES_MINUTES:
      lat_string << ToStringHelperLat(format, lat);
      lon_string << ToStringHelperLon(format, lon);
      break;
    case StringFormat::DEGREES_MINUTES_SECONDS:
      lat_string << ToStringHelperLat(format, lat);
      lon_string << ToStringHelperLon(format, lon);
      break;
  }
  return lat_string.str() + lon_string.str() + "/";
}

double Position::SetPrecision(double value, double precision) const {
  if (precision == 0) {
    return floor(value);
  }
  return (floor((value * pow(10, precision) + 0.5)) / pow(10, precision));
}

std::string Position::ToStringHelperLat(int mode, double lat) const {
  std::stringstream lat_string;
  double lat_int;
  lat_string << ToStringHelper(lat);

  lat = modf(lat, &lat_int);
  if (((int)lat_int) / 10 == 0) {
    lat_string << "0";
  }
  switch (mode) {
    case StringFormat::DEGREES:
      lat_string << std::setprecision(7) << fabs(lat_int + lat);
      break;
    case StringFormat::DEGREES_MINUTES:
      lat_string << abs((int)lat_int) << ToStringHelperDM(lat);
      break;
    case StringFormat::DEGREES_MINUTES_SECONDS:
      lat_string << abs((int)lat_int) << ToStringHelperDMS(lat);
      break;
  }
  return lat_string.str();
}

std::string Position::ToStringHelperLon(int mode, double lon) const {
  std::stringstream lon_string;
  double lon_int;
  lon_string << ToStringHelper(lon);
  lon = modf(lon, &lon_int);
  if (((int)lon_int) / 100 == 0) {
    if (((int)lon_int) / 10 == 0) {
      lon_string << "0";
    }
    lon_string << "0";
  }
  switch (mode) {
    case StringFormat::DEGREES:
      lon_string << std::setprecision(7) << fabs(lon_int + lon);
      break;
    case StringFormat::DEGREES_MINUTES:
      lon_string << abs((int)lon_int) << ToStringHelperDM(lon);
      break;
    case StringFormat::DEGREES_MINUTES_SECONDS:
      lon_string << abs((int)lon_int) << ToStringHelperDMS(lon);
      break;
  }
  return lon_string.str();
}

std::string Position::ToStringHelper(double value) const {
  std::stringstream temp;
  if (value > 0) {
    temp << "+";
  } else {
    temp << "-";
  }
  return temp.str();
}

std::string Position::ToStringHelperDM(double value) const {
  std::stringstream temp;
  value = fabs(value) * 60;
  if (((int)fabs(value)) / 10 == 0) {
    temp << "0";
  }
  temp << std::setprecision(5) << value;

  return temp.str();
}

std::string Position::ToStringHelperDMS(double value) const {
  std::stringstream temp;
  double value_int;
  value = fabs(value) * 60;
  value = modf(value, &value_int);
  if (((int)value_int) / 10 == 0) {
    temp << "0";
  }
  temp << fabs(value_int);
  value = value * 60;
  if ((int)fabs(value) / 10 == 0) {
    temp << "0";
  }
  temp << std::setprecision(1) << std::fixed << value;

  return temp.str();
}

}  // namespace toolkit
}  // namespace cyclus
<commit_msg>Added Acceptable range for Lon and Lat<commit_after>#include <math.h>
#include <stdio.h>
#include <sstream>

#include "position.h"

namespace cyclus {
namespace toolkit {

Position::Position() : latitude_(0), longitude_(0) {}

Position::Position(double decimal_lat, double decimal_lon) {
  LatCheck(decimal_lat);
  LonCheck(decimal_lon);
  latitude_ = SetPrecision(decimal_lat * CYCLUS_DECIMAL_SECOND_MULTIPLIER, 1);
  longitude_ = SetPrecision(decimal_lon * CYCLUS_DECIMAL_SECOND_MULTIPLIER, 1);
}

Position::~Position() {}

double Position::latitude() const {
  return SetPrecision(latitude_ / CYCLUS_DECIMAL_SECOND_MULTIPLIER, 6);
}

double Position::longitude() const {
  return SetPrecision(longitude_ / CYCLUS_DECIMAL_SECOND_MULTIPLIER, 6);
}

void Position::latitude(double lat) {
  LatCheck(lat);
  latitude_ = SetPrecision(lat * CYCLUS_DECIMAL_SECOND_MULTIPLIER, 1);
}

void Position::longitude(double lon) {
  LonCheck(lon);
  longitude_ = SetPrecision(lon * CYCLUS_DECIMAL_SECOND_MULTIPLIER, 1);
}

void Position::set_position(double lat, double lon) {
  LatCheck(lat);
  LonCheck(lon);
  latitude_ = SetPrecision(lat * CYCLUS_DECIMAL_SECOND_MULTIPLIER, 1);
  longitude_ = SetPrecision(lon * CYCLUS_DECIMAL_SECOND_MULTIPLIER, 1);
}

void Position::LatCheck(double lat) {
  if (lat > 90 || lat < -90){
    std::stringstream msg;
    msg << "The provided latitude (" << lat
        << ") is outside the acceptable range. "
        << "[-90, 90]";
    throw ValueError(msg.str());
  }
}

void Position::LonCheck(double lon) {
  if (lon > 180 || lon < -180){
    std::stringstream msg;
    msg << "The provided longitude (" << lon
        << ") is outside the acceptable range."
        << "[-180, 180]";
    throw ValueError(msg.str());
  }
}

double Position::Distance(Position target) const {
  double earth_radius = 6372.8;  // in kilometers (KM)
  double curr_longitude = this->longitude() * M_PI / 180;
  double curr_latitude = this->latitude() * M_PI / 180;
  double tarlongitude = target.longitude() * M_PI / 180;
  double tarlatitude = target.latitude() * M_PI / 180;
  double dlong = tarlongitude - curr_longitude;
  double dlat = tarlatitude - curr_latitude;

  double half_chord_length_sq =
      pow(sin(dlat / 2), 2) +
      pow(sin(dlong / 2), 2) * cos(curr_latitude) * cos(tarlatitude);

  double angular_distance =
      2 * atan2(sqrt(half_chord_length_sq), sqrt(1 - half_chord_length_sq));
  return earth_radius * angular_distance;
}

std::string Position::ToString(Position::StringFormat format) const {
  std::stringstream lat_string;
  std::stringstream lon_string;
  double lat = this->latitude();
  double lon = this->longitude();
  switch (format) {
    case StringFormat::DEGREES:
      lat_string << ToStringHelperLat(format, lat);
      lon_string << ToStringHelperLon(format, lon);
      break;
    case StringFormat::DEGREES_MINUTES:
      lat_string << ToStringHelperLat(format, lat);
      lon_string << ToStringHelperLon(format, lon);
      break;
    case StringFormat::DEGREES_MINUTES_SECONDS:
      lat_string << ToStringHelperLat(format, lat);
      lon_string << ToStringHelperLon(format, lon);
      break;
  }
  return lat_string.str() + lon_string.str() + "/";
}

double Position::SetPrecision(double value, double precision) const {
  if (precision == 0) {
    return floor(value);
  }
  return (floor((value * pow(10, precision) + 0.5)) / pow(10, precision));
}

std::string Position::ToStringHelperLat(int mode, double lat) const {
  std::stringstream lat_string;
  double lat_int;
  lat_string << ToStringHelper(lat);

  lat = modf(lat, &lat_int);
  if (((int)lat_int) / 10 == 0) {
    lat_string << "0";
  }
  switch (mode) {
    case StringFormat::DEGREES:
      lat_string << std::setprecision(7) << fabs(lat_int + lat);
      break;
    case StringFormat::DEGREES_MINUTES:
      lat_string << abs((int)lat_int) << ToStringHelperDM(lat);
      break;
    case StringFormat::DEGREES_MINUTES_SECONDS:
      lat_string << abs((int)lat_int) << ToStringHelperDMS(lat);
      break;
  }
  return lat_string.str();
}

std::string Position::ToStringHelperLon(int mode, double lon) const {
  std::stringstream lon_string;
  double lon_int;
  lon_string << ToStringHelper(lon);
  lon = modf(lon, &lon_int);
  if (((int)lon_int) / 100 == 0) {
    if (((int)lon_int) / 10 == 0) {
      lon_string << "0";
    }
    lon_string << "0";
  }
  switch (mode) {
    case StringFormat::DEGREES:
      lon_string << std::setprecision(7) << fabs(lon_int + lon);
      break;
    case StringFormat::DEGREES_MINUTES:
      lon_string << abs((int)lon_int) << ToStringHelperDM(lon);
      break;
    case StringFormat::DEGREES_MINUTES_SECONDS:
      lon_string << abs((int)lon_int) << ToStringHelperDMS(lon);
      break;
  }
  return lon_string.str();
}

std::string Position::ToStringHelper(double value) const {
  std::stringstream temp;
  if (value > 0) {
    temp << "+";
  } else {
    temp << "-";
  }
  return temp.str();
}

std::string Position::ToStringHelperDM(double value) const {
  std::stringstream temp;
  value = fabs(value) * 60;
  if (((int)fabs(value)) / 10 == 0) {
    temp << "0";
  }
  temp << std::setprecision(5) << value;

  return temp.str();
}

std::string Position::ToStringHelperDMS(double value) const {
  std::stringstream temp;
  double value_int;
  value = fabs(value) * 60;
  value = modf(value, &value_int);
  if (((int)value_int) / 10 == 0) {
    temp << "0";
  }
  temp << fabs(value_int);
  value = value * 60;
  if ((int)fabs(value) / 10 == 0) {
    temp << "0";
  }
  temp << std::setprecision(1) << std::fixed << value;

  return temp.str();
}

}  // namespace toolkit
}  // namespace cyclus
<|endoftext|>


<commit_before>
#include <stdio.h>
#include <iostream>
#include "argstream.h"

#include "SRSConfig.h"
#include "HierarchicalSRSImageToImageFilter.h"
#include "Graph.h"
#include "Graph-ITKStyle.h"
#include "WeightingGraph.h"
#include "SubsamplingGraph.h"
#include "FastRegistrationGraph.h"
#include "BaseLabel.h"
#include "Potential-Registration-Unary.h"
#include "Potential-Registration-Pairwise.h"
#include "Potential-Segmentation-Unary.h"
#include "Potential-Segmentation-Pairwise.h"
#include "Potential-SegmentationRegistration-Pairwise.h"
#include "MRF-TRW-S.h"

using namespace std;
using namespace itk;

int main(int argc, char ** argv)
{

	feenableexcept(FE_INVALID|FE_DIVBYZERO|FE_OVERFLOW);

	SRSConfig filterConfig;
	filterConfig.parseParams(argc,argv);
	//define types.
	typedef unsigned char PixelType;
	const unsigned int D=2;
	typedef Image<PixelType,D> ImageType;
    typedef Image<PixelType,D> InternalImageType;
    typedef itk::Vector<float,D> BaseLabelType;
    typedef DenseRegistrationLabelMapper<ImageType,BaseLabelType> LabelMapperType;
    //typedef SparseRegistrationLabelMapper<ImageType,BaseLabelType> LabelMapperType;
    //    typedef UnaryPotentialSegmentationArtificial2< ImageType > SegmentationUnaryPotentialType;
    //typedef SegmentationClassifierGradient<ImageType> ClassifierType;
    typedef HandcraftedBoneSegmentationClassifierGradient<InternalImageType> ClassifierType;
    //typedef SegmentationGaussianClassifierGradient<ImageType> ClassifierType;
    //typedef SegmentationClassifier<ImageType> ClassifierType;
    typedef UnaryPotentialSegmentationClassifier< InternalImageType, ClassifierType > SegmentationUnaryPotentialType;
    //typedef UnaryPotentialSegmentationUnsignedBone< ImageType > SegmentationUnaryPotentialType;

    //typedef SmoothnessClassifierGradient<ImageType> SegmentationSmoothnessClassifierType;
    typedef SmoothnessClassifierGradientContrast<InternalImageType> SegmentationSmoothnessClassifierType;
    typedef PairwisePotentialSegmentationClassifier<InternalImageType,SegmentationSmoothnessClassifierType> SegmentationPairwisePotentialType;

    //typedef UnaryPotentialRegistrationSAD< LabelMapperType, ImageType > RegistrationUnaryPotentialType;
    //typedef UnaryPotentialRegistrationNCC< LabelMapperType, ImageType > RegistrationUnaryPotentialType;
    //typedef FastUnaryPotentialRegistrationNCC< LabelMapperType, ImageType > RegistrationUnaryPotentialType;
    //typedef UnaryPotentialRegistrationNCCWithBonePrior< LabelMapperType, ImageType > RegistrationUnaryPotentialType;
    typedef UnaryPotentialRegistrationNCCWithDistanceBonePrior< LabelMapperType, ImageType > RegistrationUnaryPotentialType;
    typedef PairwisePotentialRegistration< LabelMapperType, ImageType > RegistrationPairwisePotentialType;
    //typedef PairwisePotentialRegistrationSigmoid< LabelMapperType, ImageType > RegistrationPairwisePotentialType;
    typedef PairwisePotentialSegmentationRegistration<  ImageType > SegmentationRegistrationPairwisePotentialType;
    //typedef FastRegistrationGraphModel<
    typedef GraphModel<
    // // //typedef ITKGraphModel<
    //typedef SortedSubsamplingGraphModel<
    //typedef SortedCumSumSubsamplingGraphModel<
    //typedef WeightedGraphModel<
         InternalImageType,
        RegistrationUnaryPotentialType,
        RegistrationPairwisePotentialType,
        SegmentationUnaryPotentialType,
        SegmentationPairwisePotentialType,
        SegmentationRegistrationPairwisePotentialType,
        LabelMapperType>        GraphType;

	typedef HierarchicalSRSImageToImageFilter<GraphType>        FilterType;

	//create filter
    FilterType::Pointer filter=FilterType::New();
    filter->setConfig(filterConfig);
    filter->setFixedImage(FilterUtils<ImageType,InternalImageType>::cast(ImageUtils<ImageType>::readImage(filterConfig.targetFilename)));
    filter->setMovingImage(FilterUtils<ImageType,InternalImageType>::cast(ImageUtils<ImageType>::readImage(filterConfig.movingFilename)));
    filter->setMovingSegmentation(FilterUtils<ImageType,InternalImageType>::cast(ImageUtils<ImageType>::readImage(filterConfig.movingSegmentationFilename)));
    filter->setFixedGradientImage(FilterUtils<ImageType,InternalImageType>::cast(ImageUtils<ImageType>::readImage(filterConfig.fixedGradientFilename)));

	clock_t FULLstart = clock();
	//DO IT!
	filter->Update();
	clock_t FULLend = clock();
	float t = (float) ((double)(FULLend - FULLstart) / CLOCKS_PER_SEC);
	std::cout<<"Finished computation after "<<t<<" seconds"<<std::endl;
	std::cout<<"RegUnaries: "<<tUnary<<" Optimization: "<<tOpt<<std::endl;
    std::cout<<"RegPairwise: "<<tPairwise<<std::endl;
	return 1;
}
<commit_msg>sortedSubsampling enabled. still full potential normalisation. const penalty for zero-overlap displacements<commit_after>
#include <stdio.h>
#include <iostream>
#include "argstream.h"

#include "SRSConfig.h"
#include "HierarchicalSRSImageToImageFilter.h"
#include "Graph.h"
#include "Graph-ITKStyle.h"
#include "WeightingGraph.h"
#include "SubsamplingGraph.h"
#include "FastRegistrationGraph.h"
#include "BaseLabel.h"
#include "Potential-Registration-Unary.h"
#include "Potential-Registration-Pairwise.h"
#include "Potential-Segmentation-Unary.h"
#include "Potential-Segmentation-Pairwise.h"
#include "Potential-SegmentationRegistration-Pairwise.h"
#include "MRF-TRW-S.h"

using namespace std;
using namespace itk;

int main(int argc, char ** argv)
{

	feenableexcept(FE_INVALID|FE_DIVBYZERO|FE_OVERFLOW);

	SRSConfig filterConfig;
	filterConfig.parseParams(argc,argv);
	//define types.
	typedef unsigned char PixelType;
	const unsigned int D=2;
	typedef Image<PixelType,D> ImageType;
    typedef Image<PixelType,D> InternalImageType;
    typedef itk::Vector<float,D> BaseLabelType;
    typedef DenseRegistrationLabelMapper<ImageType,BaseLabelType> LabelMapperType;
    //typedef SparseRegistrationLabelMapper<ImageType,BaseLabelType> LabelMapperType;
    //    typedef UnaryPotentialSegmentationArtificial2< ImageType > SegmentationUnaryPotentialType;
    //typedef SegmentationClassifierGradient<ImageType> ClassifierType;
    typedef HandcraftedBoneSegmentationClassifierGradient<InternalImageType> ClassifierType;
    //typedef SegmentationGaussianClassifierGradient<ImageType> ClassifierType;
    //typedef SegmentationClassifier<ImageType> ClassifierType;
    typedef UnaryPotentialSegmentationClassifier< InternalImageType, ClassifierType > SegmentationUnaryPotentialType;
    //typedef UnaryPotentialSegmentationUnsignedBone< ImageType > SegmentationUnaryPotentialType;

    //typedef SmoothnessClassifierGradient<ImageType> SegmentationSmoothnessClassifierType;
    typedef SmoothnessClassifierGradientContrast<InternalImageType> SegmentationSmoothnessClassifierType;
    typedef PairwisePotentialSegmentationClassifier<InternalImageType,SegmentationSmoothnessClassifierType> SegmentationPairwisePotentialType;

    //typedef UnaryPotentialRegistrationSAD< LabelMapperType, ImageType > RegistrationUnaryPotentialType;
    //typedef UnaryPotentialRegistrationNCC< LabelMapperType, ImageType > RegistrationUnaryPotentialType;
    //typedef FastUnaryPotentialRegistrationNCC< LabelMapperType, ImageType > RegistrationUnaryPotentialType;
    //typedef UnaryPotentialRegistrationNCCWithBonePrior< LabelMapperType, ImageType > RegistrationUnaryPotentialType;
    typedef UnaryPotentialRegistrationNCCWithDistanceBonePrior< LabelMapperType, ImageType > RegistrationUnaryPotentialType;
    typedef PairwisePotentialRegistration< LabelMapperType, ImageType > RegistrationPairwisePotentialType;
    //typedef PairwisePotentialRegistrationSigmoid< LabelMapperType, ImageType > RegistrationPairwisePotentialType;
    typedef PairwisePotentialSegmentationRegistration<  ImageType > SegmentationRegistrationPairwisePotentialType;
    //typedef FastRegistrationGraphModel<
    //typedef GraphModel<
    // // //typedef ITKGraphModel<
    typedef SortedSubsamplingGraphModel<
    //typedef SortedCumSumSubsamplingGraphModel<
    //typedef WeightedGraphModel<
         InternalImageType,
        RegistrationUnaryPotentialType,
        RegistrationPairwisePotentialType,
        SegmentationUnaryPotentialType,
        SegmentationPairwisePotentialType,
        SegmentationRegistrationPairwisePotentialType,
        LabelMapperType>        GraphType;

	typedef HierarchicalSRSImageToImageFilter<GraphType>        FilterType;

	//create filter
    FilterType::Pointer filter=FilterType::New();
    filter->setConfig(filterConfig);
    filter->setFixedImage(FilterUtils<ImageType,InternalImageType>::cast(ImageUtils<ImageType>::readImage(filterConfig.targetFilename)));
    filter->setMovingImage(FilterUtils<ImageType,InternalImageType>::cast(ImageUtils<ImageType>::readImage(filterConfig.movingFilename)));
    filter->setMovingSegmentation(FilterUtils<ImageType,InternalImageType>::cast(ImageUtils<ImageType>::readImage(filterConfig.movingSegmentationFilename)));
    filter->setFixedGradientImage(FilterUtils<ImageType,InternalImageType>::cast(ImageUtils<ImageType>::readImage(filterConfig.fixedGradientFilename)));

	clock_t FULLstart = clock();
	//DO IT!
	filter->Update();
	clock_t FULLend = clock();
	float t = (float) ((double)(FULLend - FULLstart) / CLOCKS_PER_SEC);
	std::cout<<"Finished computation after "<<t<<" seconds"<<std::endl;
	std::cout<<"RegUnaries: "<<tUnary<<" Optimization: "<<tOpt<<std::endl;
    std::cout<<"RegPairwise: "<<tPairwise<<std::endl;
	return 1;
}
<|endoftext|>


<commit_before>//!
//! @file   HydraulicAckumulator.hpp
//! @author Robert Braun <robert.braun@liu.se>
//! @date   2010-01-12
//!
//! @brief Contains a Hydraulic Ackumulator component with constant bulk modulus
//!
//$Id$

#ifndef HYDRAULICCHECKACKUMULATOR_HPP_INCLUDED
#define HYDRAULICCHECKACKUMULATOR_HPP_INCLUDED

#include <iostream>
#include "HopsanCore.h"
#include "math.h"

class HydraulicAckumulator : public ComponentQ
{
private:
    double mPmin, mVtot, mVoil, mVgas, mBetae, mKappa, mKce, mStartPressure, mStartFlow;
    Delay mDelayedP2, mDelayedC1, mDelayedZc1, mDelayedQ2;
    enum {P1, P2};

public:
    static Component *Creator()
    {
        std::cout << "running checkvalve creator" << std::endl;
        return new HydraulicAckumulator("DefaultCheckValveName");
    }

    HydraulicAckumulator(const string name,
                                const double pmin       = 1000000.0,
                                const double vtot       = 0.005,
                                const double voil       = 0.0,
                                const double betae      = 1000000000.0,
                                const double kappa      = 1.4,
                                const double kce        = 0.0000000001,
                                const double startpressure = 1000000.0,         //Start pressure, must beequal to or higher than pmin
                                const double startflow = 0.0,                   //Initial flow into the accumulator
                                const double timestep   = 0.001)
        : ComponentQ(name, timestep)
    {
        mPmin                   = pmin;
        mVtot                   = vtot;
        mVoil                   = voil;
        mVgas                   = vtot-voil;
        mBetae                  = betae;
        mKappa                  = kappa;
        mKce                    = kce;
        mStartPressure          = startpressure;
        mStartFlow              = startflow;

        addPowerPort("P1", "NodeHydraulic", P1);     //External port
        addPowerPort("P2", "NodeHydraulic", P2);     //Internal "port"

        registerParameter("Pmin", "Minimum Internal Pressure", "Pa", mPmin);
        registerParameter("Vtot", "Total Volume", "m^3", mVtot);
        registerParameter("Voil", "Oil Volume", "m^3", mVoil);
        registerParameter("Betae", "Effective Bulk Modulus", "Pa", mBetae);
        registerParameter("Kappa", "Polytropic Exponent", "-", mKappa);
        registerParameter("Kce", "Flow-Pressure Coefficient", "(m^3/s)/Pa", mKce);
        registerParameter("StartPressure", "Initial Internal Pressure", "Pa", mStartPressure);
        registerParameter("StartFlow", "Initial Flow Into Ackumulator", "m^3/s", mStartFlow);
    }

    void initialize()
    {
        cout << "Begin Initialize" << endl;
        double p1 = mPortPtrs[P1]->readNode(NodeHydraulic::PRESSURE);
        double c1 = mPortPtrs[P1]->readNode(NodeHydraulic::WAVEVARIABLE);
        double Zc1 = mPortPtrs[P1]->readNode(NodeHydraulic::CHARIMP);

        if (mStartPressure < mPmin)         //User has selected an initial pressure lower than the minimum pressure, so use minimum pressure instead
        {
            mStartPressure = mPmin;
            if (mStartPressure < 0)         //User has selected a minimum pressure lower than zero, put it to zero
            {
                mStartPressure = 0;
            }
            mVgas = mVtot;                  //Pressure is minimum, so ackumulator is empty
            mVoil = 0;
            mDelayedQ2.initializeValues(mStartFlow);        //"Previous" value for q2 first step
        }
        else
        {
            if (p1 < 0.0)                               //Neighbour component has provided a presssure lower than zero, so put it so zero
            {
                p1 = 0.0;
            }
            mDelayedQ2.initializeValues(mKce*(p1-mStartPressure));              //"Previous" value for q2 first step, calculated with orifice equation
            mVgas = pow(mPmin*pow(mVtot, mKappa)/mStartPressure, 1/mKappa);     //Initial gas volume, calculated from initial pressure
            mVoil = mVtot - mVgas;
        }
        mDelayedP2.initializeValues(mStartPressure);
        mDelayedC1.initializeValues(c1);
        mDelayedZc1.initializeValues(Zc1);
        cout << "End Initialize" << endl;
    }

    void simulateOneTimestep()
    {
        cout << "Begin Step" << endl;
        //Get variable values from nodes
        double c1 = mPortPtrs[P1]->readNode(NodeHydraulic::WAVEVARIABLE);
        double Zc1 = mPortPtrs[P1]->readNode(NodeHydraulic::CHARIMP);

        //Ackumulator equations
        cout << "Declare Variables" << endl;

        double e0, ct;
        double p1,q1,q2;
        double p2 = mDelayedP2.value();

        cout << "Begin Equations" << endl;

        e0 = mPmin * pow(mVtot, mKappa);
        ct = mVgas / (p2*mKappa) + (mVtot-mVgas) / mBetae;
        q2 = (mDelayedQ2.value() * (2*ct*(mKce*mDelayedZc1.value()+1) - mKce*mTimestep) +
              2*ct*mKce*(c1-mDelayedC1.value())) / (2*ct*(mKce*Zc1+1) + mKce*mTimestep);
        p1 = c1 - Zc1*q2;
        p2 = p1 - q2/mKce;

        cout << "Begin Cavitation Check" << endl;

        if (p1 < 0.0)       //Cavitation!
        {
            c1 = 0.0;
            Zc1 = 0.0;
            q2 = (mDelayedQ2.value() * (2*ct*(mKce*mDelayedZc1.value()+1) - mKce*mTimestep) +
                  2*ct*mKce*(c1-mDelayedC1.value())) / (2*ct*(mKce*Zc1+1) + mKce*mTimestep);
            p1 = 0.0;
            p2 = -q2/mKce;
        }

        if (p2 < mPmin)     //Too low pressure (ack cannot be less than empty)
        {
            mVgas = mVtot;
            q2 = 0.0;
            p1 = c1;
            p2 = mPmin;
        }

        mVgas = pow(e0/p2, 1/mKappa);
        mVoil = mVtot - mVgas;
        q1 = -q2;

        cout << "Equations Done" << endl;

        mDelayedQ2.update(q2);
        mDelayedC1.update(c1);
        mDelayedZc1.update(Zc1);

        cout << "Delay Updated" << endl << "p1 = " << p1 << ", q1 = " << q1 << ", p2 = " << p2 << ", q2 = " << q2 << endl;

        //Write new values to nodes
        mPortPtrs[P1]->writeNode(NodeHydraulic::PRESSURE, p1);
        mPortPtrs[P1]->writeNode(NodeHydraulic::MASSFLOW, q1);

        cout << "Port 1 writen" << endl;

        mPortPtrs[P2]->writeNode(NodeHydraulic::PRESSURE, p2);
        mPortPtrs[P2]->writeNode(NodeHydraulic::MASSFLOW, q2);

        cout << "End Step" << endl;
    }
};

#endif // HYDRAULICACKUMULATOR_HPP_INCLUDED
<commit_msg>Ackumulator now appear to be working correctly. Added a signal port for accessing the oil volume.<commit_after>//!
//! @file   HydraulicAckumulator.hpp
//! @author Robert Braun <robert.braun@liu.se>
//! @date   2010-01-12
//!
//! @brief Contains a Hydraulic Ackumulator component with constant bulk modulus
//!
//$Id$

#ifndef HYDRAULICCHECKACKUMULATOR_HPP_INCLUDED
#define HYDRAULICCHECKACKUMULATOR_HPP_INCLUDED

#include <iostream>
#include "HopsanCore.h"
#include "math.h"

class HydraulicAckumulator : public ComponentQ
{
private:
    double mPmin, mVtot, mVoil, mVgas, mBetae, mKappa, mKce, mStartPressure, mStartFlow;
    Delay mDelayedP2, mDelayedC1, mDelayedZc1, mDelayedQ2;
    enum {P1, out};

public:
    static Component *Creator()
    {
        std::cout << "running checkvalve creator" << std::endl;
        return new HydraulicAckumulator("DefaultCheckValveName");
    }

    HydraulicAckumulator(const string name,
                                const double pmin       = 1000000.0,
                                const double vtot       = 0.005,
                                const double voil       = 0.0,
                                const double betae      = 1000000000.0,
                                const double kappa      = 1.4,
                                const double kce        = 0.0000000001,
                                const double startpressure = 1000000.0,         //Start pressure, must beequal to or higher than pmin
                                const double startflow = 0.0,                   //Initial flow into the accumulator
                                const double timestep   = 0.001)
        : ComponentQ(name, timestep)
    {
        mPmin                   = pmin;
        mVtot                   = vtot;
        mVoil                   = voil;
        mVgas                   = vtot-voil;
        mBetae                  = betae;
        mKappa                  = kappa;
        mKce                    = kce;
        mStartPressure          = startpressure;
        mStartFlow              = startflow;

        addPowerPort("P1", "NodeHydraulic", P1);     //External port
        addWritePort("out", "NodeSignal", out);     //Internal pressure output

        registerParameter("Pmin", "Minimum Internal Pressure", "Pa", mPmin);
        registerParameter("Vtot", "Total Volume", "m^3", mVtot);
        registerParameter("Voil", "Oil Volume", "m^3", mVoil);
        registerParameter("Betae", "Effective Bulk Modulus", "Pa", mBetae);
        registerParameter("Kappa", "Polytropic Exponent", "-", mKappa);
        registerParameter("Kce", "Flow-Pressure Coefficient", "(m^3/s)/Pa", mKce);
        registerParameter("StartPressure", "Initial Internal Pressure", "Pa", mStartPressure);
        registerParameter("StartFlow", "Initial Flow Into Ackumulator", "m^3/s", mStartFlow);
    }

    void initialize()
    {
        double p1 = mPortPtrs[P1]->readNode(NodeHydraulic::PRESSURE);
        double c1 = mPortPtrs[P1]->readNode(NodeHydraulic::WAVEVARIABLE);
        double Zc1 = mPortPtrs[P1]->readNode(NodeHydraulic::CHARIMP);

        if (mStartPressure < mPmin)         //User has selected an initial pressure lower than the minimum pressure, so use minimum pressure instead
        {
            mStartPressure = mPmin;
            if (mStartPressure < 0)         //User has selected a minimum pressure lower than zero, put it to zero
            {
                mStartPressure = 0;
            }
            mVgas = mVtot;                  //Pressure is minimum, so ackumulator is empty
            mVoil = 0;
            mDelayedQ2.initializeValues(mStartFlow);        //"Previous" value for q2 first step
        }
        else
        {
            if (p1 < 0.0)                               //Neighbour component has provided a presssure lower than zero, so put it so zero
            {
                p1 = 0.0;
            }
            mDelayedQ2.initializeValues(mKce*(p1-mStartPressure));              //"Previous" value for q2 first step, calculated with orifice equation
            mVgas = pow(mPmin*pow(mVtot, mKappa)/mStartPressure, 1/mKappa);     //Initial gas volume, calculated from initial pressure
            mVoil = mVtot - mVgas;
        }
        mDelayedP2.initializeValues(mStartPressure);
        mDelayedC1.initializeValues(c1);
        mDelayedZc1.initializeValues(Zc1);

        mDelayedP2.setStepDelay(1);
        mDelayedC1.setStepDelay(1);
        mDelayedZc1.setStepDelay(1);
        mDelayedQ2.setStepDelay(1);

        cout << "Start Pressure: " << mStartPressure << endl;;
    }

    void simulateOneTimestep()
    {
        //Get variable values from nodes
        double c1 = mPortPtrs[P1]->readNode(NodeHydraulic::WAVEVARIABLE);
        double Zc1 = mPortPtrs[P1]->readNode(NodeHydraulic::CHARIMP);

        //Ackumulator equations
        double e0, ct;
        double p1,q1,q2;
        double p2 = mDelayedP2.value();

        e0 = mPmin * pow(mVtot, mKappa);
        ct = mVgas / (p2*mKappa) + (mVtot-mVgas) / mBetae;
        q2 = (mDelayedQ2.value() * (2*ct*(mKce*mDelayedZc1.value()+1) - mKce*mTimestep) +
              2*ct*mKce*(c1-mDelayedC1.value())) / (2*ct*(mKce*Zc1+1) + mKce*mTimestep);
        p1 = c1 - Zc1*q2;
        p2 = p1 - q2/mKce;

        if (mTime < 0.05)
        {
                cout << "p1 = " << p1 << ", p2 = " << p2 << ", q = " << q2 << ", ct = " << ct << endl;
        }

        if (p1 < 0.0)       //Cavitation!
        {
            c1 = 0.0;
            Zc1 = 0.0;
            q2 = (mDelayedQ2.value() * (2*ct*(mKce*mDelayedZc1.value()+1) - mKce*mTimestep) +
                  2*ct*mKce*(c1-mDelayedC1.value())) / (2*ct*(mKce*Zc1+1) + mKce*mTimestep);
            p1 = 0.0;
            p2 = -q2/mKce;
        }

        if (p2 < mPmin)     //Too low pressure (ack cannot be less than empty)
        {
            cout << "Empty!" << endl;
            mVgas = mVtot;
            q2 = 0.0;
            p1 = c1;
            p2 = mPmin;
        }

        mVgas = pow(e0/p2, 1/mKappa);
        mVoil = mVtot - mVgas;
        q1 = -q2;

        if (mTime < 0.05)
        {
                cout << "Voil = " << mVoil << endl;
        }

        mDelayedP2.update(p2);
        mDelayedQ2.update(q2);
        mDelayedC1.update(c1);
        mDelayedZc1.update(Zc1);

        //Write new values to nodes
        mPortPtrs[P1]->writeNode(NodeHydraulic::PRESSURE, p1);
        mPortPtrs[P1]->writeNode(NodeHydraulic::MASSFLOW, q1);
        if (mPortPtrs[out]->isConnected())
        {
            mPortPtrs[out]->writeNode(NodeSignal::VALUE, mVoil);
        }

    }
};

#endif // HYDRAULICACKUMULATOR_HPP_INCLUDED
<|endoftext|>


<commit_before>/**
 * This file is part of the "libfnord" project
 *   Copyright (c) 2015 Paul Asmuth
 *
 * FnordMetric is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License v3.0. You should have received a
 * copy of the GNU General Public License along with this program. If not, see
 * <http://www.gnu.org/licenses/>.
 */
#include "fnord/util/binarymessagewriter.h"
#include "tsdb/TSDBServlet.h"
#include "tsdb/RecordEnvelope.pb.h"
#include "fnord/json/json.h"
#include <fnord/wallclock.h>
#include <fnord/thread/wakeup.h>
#include "fnord/protobuf/MessageEncoder.h"
#include "fnord/protobuf/MessagePrinter.h"
#include "fnord/protobuf/msg.h"
#include <fnord/util/Base64.h>
#include <fnord/fnv.h>
#include <sstable/sstablereader.h>
#include <chartsql/runtime/ASCIITableFormat.h>

using namespace fnord;

namespace tsdb {

TSDBServlet::TSDBServlet(TSDBNode* node) : node_(node) {}

void TSDBServlet::handleHTTPRequest(
    RefPtr<http::HTTPRequestStream> req_stream,
    RefPtr<http::HTTPResponseStream> res_stream) {
  req_stream->readBody();
  const auto& req = req_stream->request();
  URI uri(req.uri());

  http::HTTPResponse res;
  res.populateFromRequest(req);
  res.addHeader("Access-Control-Allow-Origin", "*");

  try {
    if (uri.path() == "/tsdb/insert") {
      insertRecords(&req, &res, &uri);
      res_stream->writeResponse(res);
      return;
    }

    if (uri.path() == "/tsdb/stream") {
      streamPartition(&req, &res, res_stream, &uri);
      return;
    }

    if (uri.path() == "/tsdb/partition_info") {
      fetchPartitionInfo(&req, &res, &uri);
      res_stream->writeResponse(res);
      return;
    }

    if (uri.path() == "/tsdb/sql") {
      executeSQL(&req, &res, res_stream, &uri);
      return;
    }

    res.setStatus(fnord::http::kStatusNotFound);
    res.addBody("not found");
    res_stream->writeResponse(res);
  } catch (const Exception& e) {
    fnord::logError("tsdb", e, "error while processing HTTP request");

    res.setStatus(http::kStatusInternalServerError);
    res.addBody(StringUtil::format("error: $0: $1", e.getTypeName(), e.getMessage()));
    res_stream->writeResponse(res);
  }

  res_stream->finishResponse();
}

void TSDBServlet::insertRecords(
    const http::HTTPRequest* req,
    http::HTTPResponse* res,
    URI* uri) {
  auto record_list = msg::decode<RecordEnvelopeList>(req->body());

  Vector<RefPtr<Partition>> partition_refs;
  HashMap<Partition*, Vector<RecordRef>> grouped;
  for (const auto& record : record_list.records()) {
    auto partition = node_->findOrCreatePartition(
        record.tsdb_namespace(),
        record.stream_key(),
        SHA1Hash::fromHexString(record.partition_key()));

    auto record_data = record.record_data().data();
    auto record_size = record.record_data().size();

    if (grouped.count(partition.get()) == 0) {
      partition_refs.emplace_back(partition);
    }

    grouped[partition.get()].emplace_back(
        SHA1Hash::fromHexString(record.record_id()),
        Buffer(record_data, record_size));
  }

  for (const auto& group : grouped) {
    group.first->insertRecords(group.second);
  }

  res->setStatus(http::kStatusCreated);
}

void TSDBServlet::streamPartition(
    const http::HTTPRequest* req,
    http::HTTPResponse* res,
    RefPtr<http::HTTPResponseStream> res_stream,
    URI* uri) {
  const auto& params = uri->queryParams();

  String tsdb_namespace;
  if (!URI::getParam(params, "namespace", &tsdb_namespace)) {
    res->setStatus(fnord::http::kStatusBadRequest);
    res->addBody("missing ?namespace=... parameter");
    return;
  }

  String stream_key;
  if (!URI::getParam(params, "stream", &stream_key)) {
    res->setStatus(fnord::http::kStatusBadRequest);
    res->addBody("missing ?stream=... parameter");
    return;
  }

  String partition_key;
  if (!URI::getParam(params, "partition", &partition_key)) {
    res->setStatus(fnord::http::kStatusBadRequest);
    res->addBody("missing ?partition=... parameter");
    return;
  }

  size_t sample_mod = 0;
  size_t sample_idx = 0;
  String sample_str;
  if (URI::getParam(params, "sample", &sample_str)) {
    auto parts = StringUtil::split(sample_str, ":");

    if (parts.size() != 2) {
      res->setStatus(fnord::http::kStatusBadRequest);
      res->addBody("invalid ?sample=... parameter, format is <mod>:<idx>");
      res_stream->writeResponse(*res);
    }

    sample_mod = std::stoull(parts[0]);
    sample_idx = std::stoull(parts[1]);
  }

  res->setStatus(http::kStatusOK);
  res->addHeader("Content-Type", "application/octet-stream");
  res->addHeader("Connection", "close");
  res_stream->startResponse(*res);

  auto partition = node_->findPartition(
      tsdb_namespace,
      stream_key,
      SHA1Hash::fromHexString(partition_key));

  if (!partition.isEmpty()) {
    FNV<uint64_t> fnv;
    auto files = partition.get()->listFiles();

    for (const auto& f : files) {
      auto fpath = FileUtil::joinPaths(node_->dbPath(), f);
      sstable::SSTableReader reader(fpath);
      auto cursor = reader.getCursor();

      while (cursor->valid()) {
        uint64_t* key;
        size_t key_size;
        cursor->getKey((void**) &key, &key_size);
        if (key_size != SHA1Hash::kSize) {
          RAISE(kRuntimeError, "invalid row");
        }

        if (sample_mod == 0 ||
            (fnv.hash(key, key_size) % sample_mod == sample_idx)) {
          void* data;
          size_t data_size;
          cursor->getData(&data, &data_size);

          util::BinaryMessageWriter buf;
          if (data_size > 0) {
            buf.appendUInt64(data_size);
            buf.append(data, data_size);
            res_stream->writeBodyChunk(Buffer(buf.data(), buf.size()));
          }
          res_stream->waitForReader();
        }

        if (!cursor->next()) {
          break;
        }
      }
    }
  }

  util::BinaryMessageWriter buf;
  buf.appendUInt64(0);
  res_stream->writeBodyChunk(Buffer(buf.data(), buf.size()));

  res_stream->finishResponse();
}

void TSDBServlet::fetchPartitionInfo(
    const http::HTTPRequest* req,
    http::HTTPResponse* res,
    URI* uri) {
  const auto& params = uri->queryParams();

  String tsdb_namespace;
  if (!URI::getParam(params, "namespace", &tsdb_namespace)) {
    res->setStatus(fnord::http::kStatusBadRequest);
    res->addBody("missing ?namespace=... parameter");
    return;
  }

  String stream_key;
  if (!URI::getParam(params, "stream", &stream_key)) {
    res->setStatus(fnord::http::kStatusBadRequest);
    res->addBody("missing ?stream=... parameter");
    return;
  }

  String partition_key;
  if (!URI::getParam(params, "partition", &partition_key)) {
    res->setStatus(fnord::http::kStatusBadRequest);
    res->addBody("missing ?partition=... parameter");
    return;
  }

  auto partition = node_->findPartition(
      tsdb_namespace,
      stream_key,
      SHA1Hash::fromHexString(partition_key));

  PartitionInfo pinfo;
  pinfo.set_partition_key(partition_key);
  if (!partition.isEmpty()) {
    pinfo = partition.get()->partitionInfo();
  }

  res->setStatus(http::kStatusOK);
  res->addHeader("Content-Type", "application/x-protobuf");
  res->addBody(*msg::encode(pinfo));
}

void TSDBServlet::executeSQL(
    const http::HTTPRequest* req,
    http::HTTPResponse* res,
    RefPtr<http::HTTPResponseStream> res_stream,
    URI* uri) {
  if (!req->hasHeader("X-TSDB-Namespace")) {
    http::HTTPResponse res;
    res.populateFromRequest(*req);
    res.setStatus(fnord::http::kStatusBadRequest);
    res.addBody("missing X-TSDB-Namespace header");
    res_stream->writeResponse(res);
    return;
  }

  auto tsdb_ns = req->getHeader("X-TSDB-Namespace");

  auto query = req->body().toString();
  auto qplan = node_->sqlEngine()->parseAndBuildQueryPlan(
      tsdb_ns,
      query);

  Buffer result;
  csql::ASCIITableFormat format;
  format.formatResults(qplan, BufferOutputStream::fromBuffer(&result));

  res->setStatus(http::kStatusOK);
  res->addHeader("Access-Control-Allow-Origin", "*");
  res->addHeader("Content-Type", "text/plain");
  res->addHeader("Connection", "close");
  res_stream->startResponse(*res);
  res_stream->writeBodyChunk(result);
  res_stream->finishResponse();
}

}

<commit_msg>response headers<commit_after>/**
 * This file is part of the "libfnord" project
 *   Copyright (c) 2015 Paul Asmuth
 *
 * FnordMetric is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License v3.0. You should have received a
 * copy of the GNU General Public License along with this program. If not, see
 * <http://www.gnu.org/licenses/>.
 */
#include "fnord/util/binarymessagewriter.h"
#include "tsdb/TSDBServlet.h"
#include "tsdb/RecordEnvelope.pb.h"
#include "fnord/json/json.h"
#include <fnord/wallclock.h>
#include <fnord/thread/wakeup.h>
#include "fnord/protobuf/MessageEncoder.h"
#include "fnord/protobuf/MessagePrinter.h"
#include "fnord/protobuf/msg.h"
#include <fnord/util/Base64.h>
#include <fnord/fnv.h>
#include <sstable/sstablereader.h>
#include <chartsql/runtime/ASCIITableFormat.h>

using namespace fnord;

namespace tsdb {

TSDBServlet::TSDBServlet(TSDBNode* node) : node_(node) {}

void TSDBServlet::handleHTTPRequest(
    RefPtr<http::HTTPRequestStream> req_stream,
    RefPtr<http::HTTPResponseStream> res_stream) {
  req_stream->readBody();
  const auto& req = req_stream->request();
  URI uri(req.uri());

  http::HTTPResponse res;
  res.populateFromRequest(req);
  res.addHeader("Access-Control-Allow-Origin", "*");

  try {
    if (uri.path() == "/tsdb/insert") {
      insertRecords(&req, &res, &uri);
      res_stream->writeResponse(res);
      return;
    }

    if (uri.path() == "/tsdb/stream") {
      streamPartition(&req, &res, res_stream, &uri);
      return;
    }

    if (uri.path() == "/tsdb/partition_info") {
      fetchPartitionInfo(&req, &res, &uri);
      res_stream->writeResponse(res);
      return;
    }

    if (uri.path() == "/tsdb/sql") {
      executeSQL(&req, &res, res_stream, &uri);
      return;
    }

    res.setStatus(fnord::http::kStatusNotFound);
    res.addBody("not found");
    res_stream->writeResponse(res);
  } catch (const Exception& e) {
    fnord::logError("tsdb", e, "error while processing HTTP request");

    res.setStatus(http::kStatusInternalServerError);
    res.addBody(StringUtil::format("error: $0: $1", e.getTypeName(), e.getMessage()));
    res_stream->writeResponse(res);
  }

  res_stream->finishResponse();
}

void TSDBServlet::insertRecords(
    const http::HTTPRequest* req,
    http::HTTPResponse* res,
    URI* uri) {
  auto record_list = msg::decode<RecordEnvelopeList>(req->body());

  Vector<RefPtr<Partition>> partition_refs;
  HashMap<Partition*, Vector<RecordRef>> grouped;
  for (const auto& record : record_list.records()) {
    auto partition = node_->findOrCreatePartition(
        record.tsdb_namespace(),
        record.stream_key(),
        SHA1Hash::fromHexString(record.partition_key()));

    auto record_data = record.record_data().data();
    auto record_size = record.record_data().size();

    if (grouped.count(partition.get()) == 0) {
      partition_refs.emplace_back(partition);
    }

    grouped[partition.get()].emplace_back(
        SHA1Hash::fromHexString(record.record_id()),
        Buffer(record_data, record_size));
  }

  for (const auto& group : grouped) {
    group.first->insertRecords(group.second);
  }

  res->setStatus(http::kStatusCreated);
}

void TSDBServlet::streamPartition(
    const http::HTTPRequest* req,
    http::HTTPResponse* res,
    RefPtr<http::HTTPResponseStream> res_stream,
    URI* uri) {
  const auto& params = uri->queryParams();

  String tsdb_namespace;
  if (!URI::getParam(params, "namespace", &tsdb_namespace)) {
    res->setStatus(fnord::http::kStatusBadRequest);
    res->addBody("missing ?namespace=... parameter");
    return;
  }

  String stream_key;
  if (!URI::getParam(params, "stream", &stream_key)) {
    res->setStatus(fnord::http::kStatusBadRequest);
    res->addBody("missing ?stream=... parameter");
    return;
  }

  String partition_key;
  if (!URI::getParam(params, "partition", &partition_key)) {
    res->setStatus(fnord::http::kStatusBadRequest);
    res->addBody("missing ?partition=... parameter");
    return;
  }

  size_t sample_mod = 0;
  size_t sample_idx = 0;
  String sample_str;
  if (URI::getParam(params, "sample", &sample_str)) {
    auto parts = StringUtil::split(sample_str, ":");

    if (parts.size() != 2) {
      res->setStatus(fnord::http::kStatusBadRequest);
      res->addBody("invalid ?sample=... parameter, format is <mod>:<idx>");
      res_stream->writeResponse(*res);
    }

    sample_mod = std::stoull(parts[0]);
    sample_idx = std::stoull(parts[1]);
  }

  res->setStatus(http::kStatusOK);
  res->addHeader("Content-Type", "application/octet-stream");
  res->addHeader("Connection", "close");
  res_stream->startResponse(*res);

  auto partition = node_->findPartition(
      tsdb_namespace,
      stream_key,
      SHA1Hash::fromHexString(partition_key));

  if (!partition.isEmpty()) {
    FNV<uint64_t> fnv;
    auto files = partition.get()->listFiles();

    for (const auto& f : files) {
      auto fpath = FileUtil::joinPaths(node_->dbPath(), f);
      sstable::SSTableReader reader(fpath);
      auto cursor = reader.getCursor();

      while (cursor->valid()) {
        uint64_t* key;
        size_t key_size;
        cursor->getKey((void**) &key, &key_size);
        if (key_size != SHA1Hash::kSize) {
          RAISE(kRuntimeError, "invalid row");
        }

        if (sample_mod == 0 ||
            (fnv.hash(key, key_size) % sample_mod == sample_idx)) {
          void* data;
          size_t data_size;
          cursor->getData(&data, &data_size);

          util::BinaryMessageWriter buf;
          if (data_size > 0) {
            buf.appendUInt64(data_size);
            buf.append(data, data_size);
            res_stream->writeBodyChunk(Buffer(buf.data(), buf.size()));
          }
          res_stream->waitForReader();
        }

        if (!cursor->next()) {
          break;
        }
      }
    }
  }

  util::BinaryMessageWriter buf;
  buf.appendUInt64(0);
  res_stream->writeBodyChunk(Buffer(buf.data(), buf.size()));

  res_stream->finishResponse();
}

void TSDBServlet::fetchPartitionInfo(
    const http::HTTPRequest* req,
    http::HTTPResponse* res,
    URI* uri) {
  const auto& params = uri->queryParams();

  String tsdb_namespace;
  if (!URI::getParam(params, "namespace", &tsdb_namespace)) {
    res->setStatus(fnord::http::kStatusBadRequest);
    res->addBody("missing ?namespace=... parameter");
    return;
  }

  String stream_key;
  if (!URI::getParam(params, "stream", &stream_key)) {
    res->setStatus(fnord::http::kStatusBadRequest);
    res->addBody("missing ?stream=... parameter");
    return;
  }

  String partition_key;
  if (!URI::getParam(params, "partition", &partition_key)) {
    res->setStatus(fnord::http::kStatusBadRequest);
    res->addBody("missing ?partition=... parameter");
    return;
  }

  auto partition = node_->findPartition(
      tsdb_namespace,
      stream_key,
      SHA1Hash::fromHexString(partition_key));

  PartitionInfo pinfo;
  pinfo.set_partition_key(partition_key);
  if (!partition.isEmpty()) {
    pinfo = partition.get()->partitionInfo();
  }

  res->setStatus(http::kStatusOK);
  res->addHeader("Content-Type", "application/x-protobuf");
  res->addBody(*msg::encode(pinfo));
}

void TSDBServlet::executeSQL(
    const http::HTTPRequest* req,
    http::HTTPResponse* res,
    RefPtr<http::HTTPResponseStream> res_stream,
    URI* uri) {
  if (!req->hasHeader("X-TSDB-Namespace")) {
    res->setStatus(fnord::http::kStatusBadRequest);
    res->addBody("missing X-TSDB-Namespace header");
    res_stream->writeResponse(res);
    return;
  }

  auto tsdb_ns = req->getHeader("X-TSDB-Namespace");

  auto query = req->body().toString();
  auto qplan = node_->sqlEngine()->parseAndBuildQueryPlan(
      tsdb_ns,
      query);

  Buffer result;
  csql::ASCIITableFormat format;
  format.formatResults(qplan, BufferOutputStream::fromBuffer(&result));

  res->setStatus(http::kStatusOK);
  res->addHeader("Content-Type", "text/plain");
  res->addHeader("Connection", "close");
  res_stream->startResponse(*res);
  res_stream->writeBodyChunk(result);
  res_stream->finishResponse();
}

}

<|endoftext|>


<commit_before>/* -*- coding: utf-8; mode: c++; tab-width: 3 -*-

Copyright 2011, 2012, 2013
Raffaello D. Di Napoli

This file is part of Application-Building Components (henceforth referred to as ABC).

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

ABC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.

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

#include <abc/testing/unit.hxx>
#include <abc/testing/mock/iostream.hxx>
#include <abc/trace.hxx>

////////////////////////////////////////////////////////////////////////////////////////////////////
// abc::test::ostream_print_no_replacements

namespace abc {

namespace test {

class ostream_print_no_replacements :
	public testing::unit {
public:

	/** See testing::unit::title().
	*/
	virtual istr title() {
		return istr(SL("ostream_print - no replacements"));
	}

	/** See testing::unit::run().
	*/
	virtual void run() {
		ABC_TRACE_FN((this));

		testing::mock::ostream mos;

		// Syntax errors.
		mos.reset();
		ABC_TESTING_EXPECT_EXCEPTION(syntax_error, mos.print(SL("{")));
		mos.reset();
		ABC_TESTING_EXPECT_EXCEPTION(syntax_error, mos.print(SL("{{{")));
		mos.reset();
		ABC_TESTING_EXPECT_EXCEPTION(syntax_error, mos.print(SL("}")));
		mos.reset();
		ABC_TESTING_EXPECT_EXCEPTION(syntax_error, mos.print(SL("}}}")));

		// No replacements.
		mos.reset();
		ABC_TESTING_EXPECT((mos.print(SL("")), mos.contents_equal(SL(""))));
		mos.reset();
		ABC_TESTING_EXPECT((mos.print(SL("x")), mos.contents_equal(SL("x"))));
		mos.reset();
		ABC_TESTING_EXPECT((mos.print(SL("x"), SL("a")), mos.contents_equal(SL("x"))));
		mos.reset();
		ABC_TESTING_EXPECT((mos.print(SL("{{")), mos.contents_equal(SL("{"))));
		mos.reset();
		ABC_TESTING_EXPECT((mos.print(SL("}}")), mos.contents_equal(SL("}"))));
		mos.reset();
		ABC_TESTING_EXPECT((mos.print(SL("{{}}")), mos.contents_equal(SL("{}"))));
	}
};

} //namespace test

} //namespace abc

ABC_TESTING_UNIT_REGISTER(abc::test::ostream_print_no_replacements)

////////////////////////////////////////////////////////////////////////////////////////////////////
// abc::test::ostream_print_one_replacement

namespace abc {

namespace test {

class ostream_print_one_replacement :
	public testing::unit {
public:

	/** See testing::unit::title().
	*/
	virtual istr title() {
		return istr(SL("ostream_print - one replacement"));
	}

	/** See testing::unit::run().
	*/
	virtual void run() {
		ABC_TRACE_FN((this));

		testing::mock::ostream mos;

		// Single string replacement, deduced argument index.
		mos.reset();
		ABC_TESTING_EXPECT((mos.print(SL("{}"), SL("a")), mos.contents_equal(SL("a"))));
		mos.reset();
		ABC_TESTING_EXPECT((mos.print(SL("x{}"), SL("a")), mos.contents_equal(SL("xa"))));
		mos.reset();
		ABC_TESTING_EXPECT((mos.print(SL("{}x"), SL("a")), mos.contents_equal(SL("ax"))));
		mos.reset();
		ABC_TESTING_EXPECT((mos.print(SL("x{}x"), SL("a")), mos.contents_equal(SL("xax"))));
		mos.reset();
		ABC_TESTING_EXPECT((mos.print(SL("{{{}}}"), SL("a")), mos.contents_equal(SL("{a}"))));

		// Single string replacement, explicit index.
		mos.reset();
		ABC_TESTING_EXPECT((mos.print(SL("{0}"), SL("a")), mos.contents_equal(SL("a"))));
		mos.reset();
		ABC_TESTING_EXPECT((mos.print(SL("x{0}"), SL("a")), mos.contents_equal(SL("xa"))));
		mos.reset();
		ABC_TESTING_EXPECT((mos.print(SL("{0}x"), SL("a")), mos.contents_equal(SL("ax"))));
		mos.reset();
		ABC_TESTING_EXPECT((mos.print(SL("x{0}x"), SL("a")), mos.contents_equal(SL("xax"))));

		// Single integer replacement, various ways of reference, various format options.
		mos.reset();
		ABC_TESTING_EXPECT((mos.print(SL("{}"), 34), mos.contents_equal(SL("34"))));
		mos.reset();
		ABC_TESTING_EXPECT((mos.print(SL("{:x}"), 34), mos.contents_equal(SL("22"))));
		mos.reset();
		ABC_TESTING_EXPECT((mos.print(SL("{:#x}"), 34), mos.contents_equal(SL("0x22"))));
	}
};

} //namespace test

} //namespace abc

ABC_TESTING_UNIT_REGISTER(abc::test::ostream_print_one_replacement)

////////////////////////////////////////////////////////////////////////////////////////////////////
// abc::test::ostream_print_two_replacements

namespace abc {

namespace test {

class ostream_print_two_replacements :
	public testing::unit {
public:

	/** See testing::unit::title().
	*/
	virtual istr title() {
		return istr(SL("ostream_print - two replacements"));
	}

	/** See testing::unit::run().
	*/
	virtual void run() {
		ABC_TRACE_FN((this));

		testing::mock::ostream mos;

		// Single string replacement, referenced twice.
		mos.reset();
		ABC_TESTING_EXPECT((mos.print(SL("{0}{0}"), SL("a")), mos.contents_equal(SL("aa"))));
		mos.reset();
		ABC_TESTING_EXPECT((mos.print(SL("{0}x{0}"), SL("a")), mos.contents_equal(SL("axa"))));
		mos.reset();
		ABC_TESTING_EXPECT((mos.print(SL("x{0}x{0}"), SL("a")), mos.contents_equal(SL("xaxa"))));
		mos.reset();
		ABC_TESTING_EXPECT((mos.print(SL("{0}x{0}x"), SL("a")), mos.contents_equal(SL("axax"))));
		mos.reset();
		ABC_TESTING_EXPECT((mos.print(SL("x{0}x{0}x"), SL("a")), mos.contents_equal(SL("xaxax"))));

		// Two string replacements, various ways of reference.
		mos.reset();
		ABC_TESTING_EXPECT((mos.print(SL("{}{}"), SL("a"), SL("b")), mos.contents_equal(SL("ab"))));
		mos.reset();
		ABC_TESTING_EXPECT((mos.print(SL("{0}{1}"), SL("a"), SL("b")), mos.contents_equal(SL("ab"))));
		mos.reset();
		ABC_TESTING_EXPECT((mos.print(SL("{1}{0}"), SL("a"), SL("b")), mos.contents_equal(SL("ba"))));
		mos.reset();
		ABC_TESTING_EXPECT((mos.print(SL("{1}{1}"), SL("a"), SL("b")), mos.contents_equal(SL("bb"))));
	}
};

} //namespace test

} //namespace abc

ABC_TESTING_UNIT_REGISTER(abc::test::ostream_print_two_replacements)

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

<commit_msg>Improve title of tests in ostream-print.cxx<commit_after>/* -*- coding: utf-8; mode: c++; tab-width: 3 -*-

Copyright 2011, 2012, 2013
Raffaello D. Di Napoli

This file is part of Application-Building Components (henceforth referred to as ABC).

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

ABC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.

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

#include <abc/testing/unit.hxx>
#include <abc/testing/mock/iostream.hxx>
#include <abc/trace.hxx>

////////////////////////////////////////////////////////////////////////////////////////////////////
// abc::test::ostream_print_no_replacements

namespace abc {

namespace test {

class ostream_print_no_replacements :
	public testing::unit {
public:

	/** See testing::unit::title().
	*/
	virtual istr title() {
		return istr(SL("abc::ostream::print() - no replacements"));
	}

	/** See testing::unit::run().
	*/
	virtual void run() {
		ABC_TRACE_FN((this));

		testing::mock::ostream mos;

		// Syntax errors.
		mos.reset();
		ABC_TESTING_EXPECT_EXCEPTION(syntax_error, mos.print(SL("{")));
		mos.reset();
		ABC_TESTING_EXPECT_EXCEPTION(syntax_error, mos.print(SL("{{{")));
		mos.reset();
		ABC_TESTING_EXPECT_EXCEPTION(syntax_error, mos.print(SL("}")));
		mos.reset();
		ABC_TESTING_EXPECT_EXCEPTION(syntax_error, mos.print(SL("}}}")));

		// No replacements.
		mos.reset();
		ABC_TESTING_EXPECT((mos.print(SL("")), mos.contents_equal(SL(""))));
		mos.reset();
		ABC_TESTING_EXPECT((mos.print(SL("x")), mos.contents_equal(SL("x"))));
		mos.reset();
		ABC_TESTING_EXPECT((mos.print(SL("x"), SL("a")), mos.contents_equal(SL("x"))));
		mos.reset();
		ABC_TESTING_EXPECT((mos.print(SL("{{")), mos.contents_equal(SL("{"))));
		mos.reset();
		ABC_TESTING_EXPECT((mos.print(SL("}}")), mos.contents_equal(SL("}"))));
		mos.reset();
		ABC_TESTING_EXPECT((mos.print(SL("{{}}")), mos.contents_equal(SL("{}"))));
	}
};

} //namespace test

} //namespace abc

ABC_TESTING_UNIT_REGISTER(abc::test::ostream_print_no_replacements)

////////////////////////////////////////////////////////////////////////////////////////////////////
// abc::test::ostream_print_one_replacement

namespace abc {

namespace test {

class ostream_print_one_replacement :
	public testing::unit {
public:

	/** See testing::unit::title().
	*/
	virtual istr title() {
		return istr(SL("abc::ostream::print() - one replacement"));
	}

	/** See testing::unit::run().
	*/
	virtual void run() {
		ABC_TRACE_FN((this));

		testing::mock::ostream mos;

		// Single string replacement, deduced argument index.
		mos.reset();
		ABC_TESTING_EXPECT((mos.print(SL("{}"), SL("a")), mos.contents_equal(SL("a"))));
		mos.reset();
		ABC_TESTING_EXPECT((mos.print(SL("x{}"), SL("a")), mos.contents_equal(SL("xa"))));
		mos.reset();
		ABC_TESTING_EXPECT((mos.print(SL("{}x"), SL("a")), mos.contents_equal(SL("ax"))));
		mos.reset();
		ABC_TESTING_EXPECT((mos.print(SL("x{}x"), SL("a")), mos.contents_equal(SL("xax"))));
		mos.reset();
		ABC_TESTING_EXPECT((mos.print(SL("{{{}}}"), SL("a")), mos.contents_equal(SL("{a}"))));

		// Single string replacement, explicit index.
		mos.reset();
		ABC_TESTING_EXPECT((mos.print(SL("{0}"), SL("a")), mos.contents_equal(SL("a"))));
		mos.reset();
		ABC_TESTING_EXPECT((mos.print(SL("x{0}"), SL("a")), mos.contents_equal(SL("xa"))));
		mos.reset();
		ABC_TESTING_EXPECT((mos.print(SL("{0}x"), SL("a")), mos.contents_equal(SL("ax"))));
		mos.reset();
		ABC_TESTING_EXPECT((mos.print(SL("x{0}x"), SL("a")), mos.contents_equal(SL("xax"))));

		// Single integer replacement, various ways of reference, various format options.
		mos.reset();
		ABC_TESTING_EXPECT((mos.print(SL("{}"), 34), mos.contents_equal(SL("34"))));
		mos.reset();
		ABC_TESTING_EXPECT((mos.print(SL("{:x}"), 34), mos.contents_equal(SL("22"))));
		mos.reset();
		ABC_TESTING_EXPECT((mos.print(SL("{:#x}"), 34), mos.contents_equal(SL("0x22"))));
	}
};

} //namespace test

} //namespace abc

ABC_TESTING_UNIT_REGISTER(abc::test::ostream_print_one_replacement)

////////////////////////////////////////////////////////////////////////////////////////////////////
// abc::test::ostream_print_two_replacements

namespace abc {

namespace test {

class ostream_print_two_replacements :
	public testing::unit {
public:

	/** See testing::unit::title().
	*/
	virtual istr title() {
		return istr(SL("abc::ostream::print() - two replacements"));
	}

	/** See testing::unit::run().
	*/
	virtual void run() {
		ABC_TRACE_FN((this));

		testing::mock::ostream mos;

		// Single string replacement, referenced twice.
		mos.reset();
		ABC_TESTING_EXPECT((mos.print(SL("{0}{0}"), SL("a")), mos.contents_equal(SL("aa"))));
		mos.reset();
		ABC_TESTING_EXPECT((mos.print(SL("{0}x{0}"), SL("a")), mos.contents_equal(SL("axa"))));
		mos.reset();
		ABC_TESTING_EXPECT((mos.print(SL("x{0}x{0}"), SL("a")), mos.contents_equal(SL("xaxa"))));
		mos.reset();
		ABC_TESTING_EXPECT((mos.print(SL("{0}x{0}x"), SL("a")), mos.contents_equal(SL("axax"))));
		mos.reset();
		ABC_TESTING_EXPECT((mos.print(SL("x{0}x{0}x"), SL("a")), mos.contents_equal(SL("xaxax"))));

		// Two string replacements, various ways of reference.
		mos.reset();
		ABC_TESTING_EXPECT((mos.print(SL("{}{}"), SL("a"), SL("b")), mos.contents_equal(SL("ab"))));
		mos.reset();
		ABC_TESTING_EXPECT((mos.print(SL("{0}{1}"), SL("a"), SL("b")), mos.contents_equal(SL("ab"))));
		mos.reset();
		ABC_TESTING_EXPECT((mos.print(SL("{1}{0}"), SL("a"), SL("b")), mos.contents_equal(SL("ba"))));
		mos.reset();
		ABC_TESTING_EXPECT((mos.print(SL("{1}{1}"), SL("a"), SL("b")), mos.contents_equal(SL("bb"))));
	}
};

} //namespace test

} //namespace abc

ABC_TESTING_UNIT_REGISTER(abc::test::ostream_print_two_replacements)

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

<|endoftext|>