<commit_before>/***********************************************************************
 * This Source Code Form is subject to the terms of the Mozilla Public *
 * License, v. 2.0. If a copy of the MPL was not distributed with this *
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.            *
 ***********************************************************************/

#ifndef DUCK_HPP_INCLUDED
#define DUCK_HPP_INCLUDED

/**
 * @file Duck.hpp
 * @author Maxime PINARD
 * @version 0.0
 * @license Mozilla Public License, v. .2.0
 * @brief Defines the Duck Class
 */

#include <Ducky>

/**
 * @class Duck Duck.hpp
 * @brief Defines the Duck Class
 */
class Duck : public Duck{

	public:

		/**
		 * @brief Duck constructor with path to sprites and starting_coordinates
		 * @param game_window          Window of the game
		 * @param duck_textures        Textures of the duck. Order : Up, Down, Left, Right
		 * @param duckies_textures     Textures of the duckies. Order : Up, Down, Left, Right
		 * @param starting_coordinates Coordinates of the ducky spawn
		 */
		void Duck(sf::Window& game_window, sf::Texture duck_textures[4], sf::Texture duckies_textures[4], Coord starting_coordinates);

		/**
		 * @brief Default constructor
		 */
		Duck();

		/**
		 * @brief Default destructor
		 */
		~Duck();

		/**
		 * @brief Apply damages to the duck and respawn it
		 */
		void damaged();

		/**
		 * @brief Add a ducky to the duck familly
		 * @return [description]
		 */
		bool power_up();

		/**
		 * @brief Return the number of duckies
		 * @return The number of duckies
		 */
		unsigned char size();

	private:

		std::vector<Ducky> Duckies;
		char invulnerability;
};

#endif /*DUCK_HPP_INCLUDED*/<commit_msg>Duck.hpp correction<commit_after>/***********************************************************************
 * This Source Code Form is subject to the terms of the Mozilla Public *
 * License, v. 2.0. If a copy of the MPL was not distributed with this *
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.            *
 ***********************************************************************/

#ifndef DUCK_HPP_INCLUDED
#define DUCK_HPP_INCLUDED

/**
 * @file Duck.hpp
 * @author Maxime PINARD
 * @version 0.0
 * @license Mozilla Public License, v. .2.0
 * @brief Defines the Duck Class
 */

#include <Ducky>

/**
 * @class Duck Duck.hpp
 * @brief Defines the Duck Class
 */
class Duck : public Duck{

	public:

		/**
		 * @brief Duck constructor with path to sprites and starting_coordinates
		 * @param game_window          Window of the game
		 * @param duck_textures        Textures of the duck. Order : Up, Down, Left, Right
		 * @param duckies_textures     Textures of the duckies. Order : Up, Down, Left, Right
		 * @param starting_coordinates Coordinates of the ducky spawn
		 */
		Duck(sf::Window& game_window, sf::Texture duck_textures[4], sf::Texture duckies_textures[4], Coord starting_coordinates);

		/**
		 * @brief Default constructor
		 */
		Duck();

		/**
		 * @brief Default destructor
		 */
		~Duck();

		/**
		 * @brief Apply damages to the duck and respawn it
		 */
		void damaged();

		/**
		 * @brief Add a ducky to the duck familly
		 * @return [description]
		 */
		bool power_up();

		/**
		 * @brief Return the number of duckies
		 * @return The number of duckies
		 */
		unsigned char size();

	private:

		std::vector<Ducky> Duckies;
		char invulnerability;
};

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


<commit_before>/*
* Harp, an efficient IO library for chemistry file formats
* Copyright (C) 2014 Guillaume Fraux
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/
*/

/*! @file Harp.hpp
* Harp main C++ API header.
*
* This file contains all the function definitions for the C++ API of Harp, and
* should be self-documented enough.
*/

#ifndef HARP_H
#define HARP_H

#include "Logger.hpp"
#include "HarpFile.hpp"
#include "Error.hpp"

#endif
<commit_msg>Update the main header doc<commit_after>/*
* Harp, an efficient IO library for chemistry file formats
* Copyright (C) 2014 Guillaume Fraux
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/
*/

/*! @file Harp.hpp
* Harp main C++ API header.
*
* This file includes the public API headers for Harp, and should be the only one
* included by client applications.
*/

#ifndef HARP_HPP
#define HARP_HPP

#include "Logger.hpp"
#include "HarpFile.hpp"
#include "Error.hpp"

#endif
<|endoftext|>


<commit_before>// __BEGIN_LICENSE__
// Copyright (C) 2006-2010 United States Government as represented by
// the Administrator of the National Aeronautics and Space Administration.
// All Rights Reserved.
// __END_LICENSE__

#ifdef _MSC_VER
#pragma warning(disable:4244)
#pragma warning(disable:4267)
#pragma warning(disable:4996)
#endif

#ifdef NDEBUG
#undef NDEBUG
#endif

#include <cstdlib>

#include <boost/program_options.hpp>
namespace po = boost::program_options;

#include <vw/Core/Functors.h>
#include <vw/Image/Algorithms.h>
#include <vw/Image/ImageMath.h>
#include <vw/Image/ImageViewRef.h>
#include <vw/Image/PerPixelViews.h>
#include <vw/Image/PixelMask.h>
#include <vw/Image/MaskViews.h>
#include <vw/Image/PixelTypes.h>
#include <vw/Image/Statistics.h>
#include <vw/FileIO/DiskImageView.h>
#include <vw/Cartography/FileIO.h>
#include <vw/Cartography/GeoReference.h>

using namespace vw;

// Global variables
std::string input_file_name, output_file_name = "", shaded_relief_file_name;
float nodata_value;
float min_val = 0, max_val = 0;

// Useful functions

/// Erases a file suffix if one exists and returns the base string
static std::string prefix_from_filename(std::string const& filename) {
  std::string result = filename;
  int index = result.rfind(".");
  if (index != -1)
    result.erase(index, result.size());
  return result;
}

// Colormap function
class ColormapFunc : public ReturnFixedType<PixelMask<PixelRGB<float> > > {

public:
  ColormapFunc() {}

  template <class PixelT>
  PixelMask<PixelRGB<float> > operator() (PixelT const& pix) const {
    if (is_transparent(pix))
      return PixelMask<PixelRGB<float> >();

    float val = compound_select_channel<const float&>(pix,0);
    if (val > 1.0) val = 1.0;
    if (val < 0.0) val = 0.0;

    Vector2 red_range(3/8.0, 1.0);
    Vector2 green_range(2/8.0, 6/8.0);
    Vector2 blue_range(0.0, 5/8.0);

    float red_span = red_range[1] - red_range[0];
    float blue_span = blue_range[1] - blue_range[0];
    float green_span = green_range[1] - green_range[0];

    float red = 0;
    float green = 0;
    float blue = 0;

    // Red
    if (val >= red_range[0] && val <= red_range[0]+red_span/3)
      red = (val-red_range[0])/(red_span/3);
    if (val >= red_range[0]+red_span/3 && val <= red_range[0]+2*red_span/3)
      red = 1.0;
    if (val >= red_range[0]+2*red_span/3 && val <= red_range[1])
      red = 1-((val-(red_range[0]+2*red_span/3))/(red_span/3));

    // Blue
    if (val >= blue_range[0] && val <= blue_range[0]+blue_span/3)
      blue = (val-blue_range[0])/(blue_span/3);
    if (val >= blue_range[0]+blue_span/3 && val <= blue_range[0]+2*blue_span/3)
      blue = 1.0;
    if (val >= blue_range[0]+2*blue_span/3 && val <= blue_range[1])
      blue = 1-((val-(blue_range[0]+2*blue_span/3))/(blue_span/3));

     // Green
    if (val >= green_range[0] && val <= green_range[0]+green_span/3)
      green = (val-green_range[0])/(green_span/3);
    if (val >= green_range[0]+green_span/3 && val <= green_range[0]+2*green_span/3)
      green = 1.0;
    if (val >= green_range[0]+2*green_span/3 && val <= green_range[1])
      green = 1-((val-(green_range[0]+2*green_span/3))/(green_span/3));

    return PixelRGB<float> ( red, green, blue );
  }
};

template <class ViewT>
UnaryPerPixelView<ViewT, ColormapFunc> colormap(ImageViewBase<ViewT> const& view) {
  return UnaryPerPixelView<ViewT, ColormapFunc>(view.impl(), ColormapFunc());
}

// ---------------------------------------------------------------------------------------------------

template <class PixelT>
void do_colorized_dem(po::variables_map const& vm) {

  cartography::GeoReference georef;
  cartography::read_georeference(georef, input_file_name);

  DiskImageView<PixelT> disk_dem_file(input_file_name);
  ImageViewRef<PixelGray<float> > input_image = channel_cast<float>(disk_dem_file);

  vw_out() << "Creating colorized DEM.\n";
  if (min_val == 0 && max_val == 0) {
    min_max_channel_values( create_mask( input_image, nodata_value), min_val, max_val);
    vw_out() << "\t--> DEM color map range: [" << min_val << "  " << max_val << "]\n";
  } else {
    vw_out() << "\t--> Using user-specified color map range: [" << min_val << "  " << max_val << "]\n";
  }

  ImageViewRef<PixelMask<PixelGray<float> > > dem;
  DiskImageResource *disk_dem_rsrc = DiskImageResource::open(input_file_name);
  if (vm.count("nodata-value")) {
    vw_out() << "\t--> Masking nodata value: " << nodata_value << ".\n";
    dem = channel_cast<float>(create_mask(input_image, nodata_value));
  } else if ( disk_dem_rsrc->has_nodata_value() ) {
    nodata_value = disk_dem_rsrc->nodata_value();
    vw_out() << "\t--> Extracted nodata value from file: " << nodata_value << ".\n";
    dem = create_mask(input_image, nodata_value);
  } else {
    dem = pixel_cast<PixelMask<PixelGray<float> > >(input_image);
  }
  delete disk_dem_rsrc;

  ImageViewRef<PixelMask<PixelRGB<float> > > colorized_image = colormap(normalize(dem,min_val,max_val,0,1.0));

  if (shaded_relief_file_name != "") {
    vw_out() << "\t--> Incorporating hillshading from: " << shaded_relief_file_name << ".\n";
    DiskImageView<PixelMask<float> > shaded_relief_image(shaded_relief_file_name);
    ImageViewRef<PixelMask<PixelRGB<float> > > shaded_image = copy_mask(colorized_image*apply_mask(shaded_relief_image), shaded_relief_image);
    vw_out() << "Writing image color-mapped image: " << output_file_name << "\n";
    write_georeferenced_image(output_file_name, channel_cast_rescale<uint8>(shaded_image), georef,
                              TerminalProgressCallback( "tools.colormap", "Writing:"));
  } else {
    vw_out() << "Writing image color-mapped image: " << output_file_name << "\n";
    write_georeferenced_image(output_file_name, channel_cast_rescale<uint8>(colorized_image), georef,
                              TerminalProgressCallback( "tools.colormap", "Writing:"));
  }
}

void save_legend() {
  min_val = 0.0;
  max_val = 1.0;

  ImageView<PixelGray<float> > img(200, 500);
  for (int j = 0; j < img.rows(); ++j) {
    float val = float(j) / img.rows();
    for (int i = 0; i < img.cols(); ++i) {
      img(i,j) = val;
    }
  }

  ImageViewRef<PixelMask<PixelRGB<float> > > colorized_image = colormap(img);
  write_image("legend.png", channel_cast_rescale<uint8>(apply_mask(colorized_image)));
}

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

  set_debug_level(VerboseDebugMessage-1);

  po::options_description desc("Description: Produces a colorized image of a DEM \n\nUsage: colormap [options] <input file> \n\nOptions");
  desc.add_options()
    ("help,h", "Display this help message")
    ("input-file", po::value<std::string>(&input_file_name), "Explicitly specify the input file")
    ("shaded-relief-file,s", po::value<std::string>(&shaded_relief_file_name)->default_value(""), "Specify a shaded relief image (grayscale) to apply to the colorized image.")
    ("output-file,o", po::value<std::string>(&output_file_name), "Specify the output file")
    ("nodata-value", po::value<float>(&nodata_value), "Remap the DEM default value to the min altitude value.")
    ("min", po::value<float>(&min_val), "Minimum height of the color map.")
    ("max", po::value<float>(&max_val), "Maximum height of the color map.")
    ("moon", "Set the min and max values to [-8499 10208] meters, which is suitable for covering elevations on the Moon.")
    ("mars", "Set the min and max values to [-8208 21249] meters, which is suitable for covering elevations on Mars.")
    ("legend", "Generate the colormap legend.  This image is saved (without labels) as \'legend.png\'")
    ("verbose", "Verbose output");
  po::positional_options_description p;
  p.add("input-file", 1);

  po::variables_map vm;
  po::store( po::command_line_parser( argc, argv ).options(desc).positional(p).run(), vm );
  po::notify( vm );

  if( vm.count("help") ) {
    std::cout << desc << std::endl;
    return 1;
  }

  if( vm.count("legend") ) {
    std::cout << "\t--> Saving legend file to disk as \'legend.png\'\n";
    save_legend();
    exit(0);
  }

  // This is a reasonable range of elevation values to cover global
  // lunar topography.
  if( vm.count("moon") ) {
    min_val = -8499;
    max_val = 10208;
  }

  // This is a reasonable range of elevation values to cover global
  // mars topography.
  if( vm.count("mars") ) {
    min_val = -8208;
    max_val = 21249;
  }

  if( vm.count("input-file") != 1 ) {
    std::cout << "Error: Must specify exactly one input file!\n" << std::endl;
    std::cout << desc << std::endl;
    return 1;
  }

  if( output_file_name == "" ) {
    output_file_name = prefix_from_filename(input_file_name) + "_CMAP.tif";
  }

  if( vm.count("verbose") ) {
    set_debug_level(VerboseDebugMessage);
  }

  try {

    // Get the right pixel/channel type.
    DiskImageResource *rsrc = DiskImageResource::open(input_file_name);
    ChannelTypeEnum channel_type = rsrc->channel_type();
    PixelFormatEnum pixel_format = rsrc->pixel_format();
    delete rsrc;

    switch(pixel_format) {
    case VW_PIXEL_GRAY:
      switch(channel_type) {
      case VW_CHANNEL_UINT8:  do_colorized_dem<PixelGray<uint8>   >(vm); break;
      case VW_CHANNEL_INT16:  do_colorized_dem<PixelGray<int16>   >(vm); break;
      case VW_CHANNEL_UINT16: do_colorized_dem<PixelGray<uint16>  >(vm); break;
      default:                do_colorized_dem<PixelGray<float32> >(vm); break;
      }
      break;
    default:
      std::cout << "Error: Unsupported pixel format.  The DEM image must have only one channel.";
      exit(0);
    }
  }
  catch( Exception& e ) {
    std::cerr << "Error: " << e.what() << std::endl;
  }

  return 0;
}
<commit_msg>Nodata values were not detected prior to autoscaling in colormap.  Fixed this by shuffling things around.<commit_after>// __BEGIN_LICENSE__
// Copyright (C) 2006-2010 United States Government as represented by
// the Administrator of the National Aeronautics and Space Administration.
// All Rights Reserved.
// __END_LICENSE__

#ifdef _MSC_VER
#pragma warning(disable:4244)
#pragma warning(disable:4267)
#pragma warning(disable:4996)
#endif

#ifdef NDEBUG
#undef NDEBUG
#endif

#include <cstdlib>

#include <boost/program_options.hpp>
namespace po = boost::program_options;

#include <vw/Core/Functors.h>
#include <vw/Image/Algorithms.h>
#include <vw/Image/ImageMath.h>
#include <vw/Image/ImageViewRef.h>
#include <vw/Image/PerPixelViews.h>
#include <vw/Image/PixelMask.h>
#include <vw/Image/MaskViews.h>
#include <vw/Image/PixelTypes.h>
#include <vw/Image/Statistics.h>
#include <vw/FileIO/DiskImageView.h>
#include <vw/Cartography/FileIO.h>
#include <vw/Cartography/GeoReference.h>

using namespace vw;

// Global variables
std::string input_file_name, output_file_name = "", shaded_relief_file_name;
float nodata_value;
float min_val = 0, max_val = 0;

// Useful functions

/// Erases a file suffix if one exists and returns the base string
static std::string prefix_from_filename(std::string const& filename) {
  std::string result = filename;
  int index = result.rfind(".");
  if (index != -1)
    result.erase(index, result.size());
  return result;
}

// Colormap function
class ColormapFunc : public ReturnFixedType<PixelMask<PixelRGB<float> > > {

public:
  ColormapFunc() {}

  template <class PixelT>
  PixelMask<PixelRGB<float> > operator() (PixelT const& pix) const {
    if (is_transparent(pix))
      return PixelMask<PixelRGB<float> >();

    float val = compound_select_channel<const float&>(pix,0);
    if (val > 1.0) val = 1.0;
    if (val < 0.0) val = 0.0;

    Vector2 red_range(3/8.0, 1.0);
    Vector2 green_range(2/8.0, 6/8.0);
    Vector2 blue_range(0.0, 5/8.0);

    float red_span = red_range[1] - red_range[0];
    float blue_span = blue_range[1] - blue_range[0];
    float green_span = green_range[1] - green_range[0];

    float red = 0;
    float green = 0;
    float blue = 0;

    // Red
    if (val >= red_range[0] && val <= red_range[0]+red_span/3)
      red = (val-red_range[0])/(red_span/3);
    if (val >= red_range[0]+red_span/3 && val <= red_range[0]+2*red_span/3)
      red = 1.0;
    if (val >= red_range[0]+2*red_span/3 && val <= red_range[1])
      red = 1-((val-(red_range[0]+2*red_span/3))/(red_span/3));

    // Blue
    if (val >= blue_range[0] && val <= blue_range[0]+blue_span/3)
      blue = (val-blue_range[0])/(blue_span/3);
    if (val >= blue_range[0]+blue_span/3 && val <= blue_range[0]+2*blue_span/3)
      blue = 1.0;
    if (val >= blue_range[0]+2*blue_span/3 && val <= blue_range[1])
      blue = 1-((val-(blue_range[0]+2*blue_span/3))/(blue_span/3));

     // Green
    if (val >= green_range[0] && val <= green_range[0]+green_span/3)
      green = (val-green_range[0])/(green_span/3);
    if (val >= green_range[0]+green_span/3 && val <= green_range[0]+2*green_span/3)
      green = 1.0;
    if (val >= green_range[0]+2*green_span/3 && val <= green_range[1])
      green = 1-((val-(green_range[0]+2*green_span/3))/(green_span/3));

    return PixelRGB<float> ( red, green, blue );
  }
};

template <class ViewT>
UnaryPerPixelView<ViewT, ColormapFunc> colormap(ImageViewBase<ViewT> const& view) {
  return UnaryPerPixelView<ViewT, ColormapFunc>(view.impl(), ColormapFunc());
}

// ---------------------------------------------------------------------------------------------------

template <class PixelT>
void do_colorized_dem(po::variables_map const& vm) {
  vw_out() << "Creating colorized DEM.\n";

  cartography::GeoReference georef;
  cartography::read_georeference(georef, input_file_name);

  // Attempt to extract nodata value
  DiskImageResource *disk_dem_rsrc = DiskImageResource::open(input_file_name);
  if (vm.count("nodata-value")) {
    vw_out() << "\t--> Using user-supplied nodata value: " << nodata_value << ".\n";
  } else if ( disk_dem_rsrc->has_nodata_value() ) {
    nodata_value = disk_dem_rsrc->nodata_value();
    vw_out() << "\t--> Extracted nodata value from file: " << nodata_value << ".\n";
  }

  // Compute min/max
  DiskImageView<PixelT> disk_dem_file(input_file_name);
  ImageViewRef<PixelGray<float> > input_image = channel_cast<float>(disk_dem_file);
  if (min_val == 0 && max_val == 0) {
    min_max_channel_values( create_mask( input_image, nodata_value), min_val, max_val);
    vw_out() << "\t--> DEM color map range: [" << min_val << "  " << max_val << "]\n";
  } else {
    vw_out() << "\t--> Using user-specified color map range: [" << min_val << "  " << max_val << "]\n";
  }

  ImageViewRef<PixelMask<PixelGray<float> > > dem;
  if (vm.count("nodata-value")) {
    dem = channel_cast<float>(create_mask(input_image, nodata_value));
  } else if ( disk_dem_rsrc->has_nodata_value() ) {
    dem = create_mask(input_image, nodata_value);
  } else {
    dem = pixel_cast<PixelMask<PixelGray<float> > >(input_image);
  }
  delete disk_dem_rsrc;

  ImageViewRef<PixelMask<PixelRGB<float> > > colorized_image = colormap(normalize(dem,min_val,max_val,0,1.0));

  if (shaded_relief_file_name != "") {
    vw_out() << "\t--> Incorporating hillshading from: " << shaded_relief_file_name << ".\n";
    DiskImageView<PixelMask<float> > shaded_relief_image(shaded_relief_file_name);
    ImageViewRef<PixelMask<PixelRGB<float> > > shaded_image = copy_mask(colorized_image*apply_mask(shaded_relief_image), shaded_relief_image);
    vw_out() << "Writing image color-mapped image: " << output_file_name << "\n";
    write_georeferenced_image(output_file_name, channel_cast_rescale<uint8>(shaded_image), georef,
                              TerminalProgressCallback( "tools.colormap", "Writing:"));
  } else {
    vw_out() << "Writing image color-mapped image: " << output_file_name << "\n";
    write_georeferenced_image(output_file_name, channel_cast_rescale<uint8>(colorized_image), georef,
                              TerminalProgressCallback( "tools.colormap", "Writing:"));
  }
}

void save_legend() {
  min_val = 0.0;
  max_val = 1.0;

  ImageView<PixelGray<float> > img(200, 500);
  for (int j = 0; j < img.rows(); ++j) {
    float val = float(j) / img.rows();
    for (int i = 0; i < img.cols(); ++i) {
      img(i,j) = val;
    }
  }

  ImageViewRef<PixelMask<PixelRGB<float> > > colorized_image = colormap(img);
  write_image("legend.png", channel_cast_rescale<uint8>(apply_mask(colorized_image)));
}

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

  set_debug_level(VerboseDebugMessage-1);

  po::options_description desc("Description: Produces a colorized image of a DEM \n\nUsage: colormap [options] <input file> \n\nOptions");
  desc.add_options()
    ("help,h", "Display this help message")
    ("input-file", po::value<std::string>(&input_file_name), "Explicitly specify the input file")
    ("shaded-relief-file,s", po::value<std::string>(&shaded_relief_file_name)->default_value(""), "Specify a shaded relief image (grayscale) to apply to the colorized image.")
    ("output-file,o", po::value<std::string>(&output_file_name), "Specify the output file")
    ("nodata-value", po::value<float>(&nodata_value), "Remap the DEM default value to the min altitude value.")
    ("min", po::value<float>(&min_val), "Minimum height of the color map.")
    ("max", po::value<float>(&max_val), "Maximum height of the color map.")
    ("moon", "Set the min and max values to [-8499 10208] meters, which is suitable for covering elevations on the Moon.")
    ("mars", "Set the min and max values to [-8208 21249] meters, which is suitable for covering elevations on Mars.")
    ("legend", "Generate the colormap legend.  This image is saved (without labels) as \'legend.png\'")
    ("verbose", "Verbose output");
  po::positional_options_description p;
  p.add("input-file", 1);

  po::variables_map vm;
  po::store( po::command_line_parser( argc, argv ).options(desc).positional(p).run(), vm );
  po::notify( vm );

  if( vm.count("help") ) {
    std::cout << desc << std::endl;
    return 1;
  }

  if( vm.count("legend") ) {
    std::cout << "\t--> Saving legend file to disk as \'legend.png\'\n";
    save_legend();
    exit(0);
  }

  // This is a reasonable range of elevation values to cover global
  // lunar topography.
  if( vm.count("moon") ) {
    min_val = -8499;
    max_val = 10208;
  }

  // This is a reasonable range of elevation values to cover global
  // mars topography.
  if( vm.count("mars") ) {
    min_val = -8208;
    max_val = 21249;
  }

  if( vm.count("input-file") != 1 ) {
    std::cout << "Error: Must specify exactly one input file!\n" << std::endl;
    std::cout << desc << std::endl;
    return 1;
  }

  if( output_file_name == "" ) {
    output_file_name = prefix_from_filename(input_file_name) + "_CMAP.tif";
  }

  if( vm.count("verbose") ) {
    set_debug_level(VerboseDebugMessage);
  }

  try {

    // Get the right pixel/channel type.
    DiskImageResource *rsrc = DiskImageResource::open(input_file_name);
    ChannelTypeEnum channel_type = rsrc->channel_type();
    PixelFormatEnum pixel_format = rsrc->pixel_format();
    delete rsrc;

    switch(pixel_format) {
    case VW_PIXEL_GRAY:
      switch(channel_type) {
      case VW_CHANNEL_UINT8:  do_colorized_dem<PixelGray<uint8>   >(vm); break;
      case VW_CHANNEL_INT16:  do_colorized_dem<PixelGray<int16>   >(vm); break;
      case VW_CHANNEL_UINT16: do_colorized_dem<PixelGray<uint16>  >(vm); break;
      default:                do_colorized_dem<PixelGray<float32> >(vm); break;
      }
      break;
    default:
      std::cout << "Error: Unsupported pixel format.  The DEM image must have only one channel.";
      exit(0);
    }
  }
  catch( Exception& e ) {
    std::cerr << "Error: " << e.what() << std::endl;
  }

  return 0;
}
<|endoftext|>


<commit_before>#include <node_version.h>

#if NODE_VERSION_AT_LEAST(0, 11, 1) && !defined(_MSC_VER)
    #include <sys/types.h>
#endif
#include <v8.h>
#include <node.h>

#include <errno.h>

#include "nan.h"

#if defined(_MSC_VER)
    #include <time.h>
    #include <windows.h>

    // The closest thing to gettimeofday in Windows is GetSystemTimeAsFileTime
    // so stub out a gettimeofday() method that uses this
    // NOTE: When I tested on Windows XP, it only gave me about 10ms accuracy
    // (but at least it compiles)

    struct timezone {
        int  tz_minuteswest;
        int  tz_dsttime;
    };

    int gettimeofday(struct timeval *tv, struct timezone *tz) {
        FILETIME ft;
        GetSystemTimeAsFileTime(&ft);
        unsigned long long t = ft.dwHighDateTime;
        t <<= 32;
        t |= ft.dwLowDateTime;
        t /= 10;
        t -= 11644473600000000ULL;
        tv->tv_sec = (long) (t / 1000000UL);
        tv->tv_usec = (long) (t % 1000000UL);

        return 0;
    }
#else
    #include <sys/time.h>
#endif

static NAN_METHOD(Now) {
    NanScope();

    timeval t;
    int r = gettimeofday(&t, NULL);

    if (r < 0) {
        NanThrowError(node::ErrnoException(errno, "gettimeofday"));
        NanReturnUndefined();
    }

    NanReturnValue(NanNew<v8::Number>((t.tv_sec * 1000000.0) + t.tv_usec));
}

static NAN_METHOD(NowDouble) {
    NanScope();

    timeval t;
    int r = gettimeofday(&t, NULL);

    if (r < 0) {
        NanThrowError(node::ErrnoException(errno, "gettimeofday"));
        NanReturnUndefined();
    }

    NanReturnValue(NanNew<v8::Number>(t.tv_sec + (t.tv_usec * 0.000001)));
}

static NAN_METHOD(NowStruct) {
    NanScope();

    timeval t;
    int r = gettimeofday(&t, NULL);

    if (r < 0) {
        NanThrowError(node::ErrnoException(errno, "gettimeofday"));
        NanReturnUndefined();
    }

    v8::Local<v8::Array> array = NanNew<v8::Array>(2);
    array->Set(NanNew<v8::Integer>(0), NanNew<v8::Number>((double)t.tv_sec));
    array->Set(NanNew<v8::Integer>(1), NanNew<v8::Number>((double)t.tv_usec));

    NanReturnValue(array);
}

extern "C"
void init( v8::Handle<v8::Object> target ) {
    NanScope();

    NODE_SET_METHOD(target, "now", Now);
    NODE_SET_METHOD(target, "nowDouble", NowDouble);
    NODE_SET_METHOD(target, "nowStruct", NowStruct);
}
NODE_MODULE(microtime,init)
<commit_msg>cleanup<commit_after>#include <node_version.h>

#if NODE_VERSION_AT_LEAST(0, 11, 1) && !defined(_MSC_VER)
    #include <sys/types.h>
#endif
#include <v8.h>
#include <node.h>

#include <errno.h>

#include "nan.h"

#if defined(_MSC_VER)
    #include <time.h>
    #include <windows.h>

    // The closest thing to gettimeofday in Windows is GetSystemTimeAsFileTime
    // so stub out a gettimeofday() method that uses this
    // NOTE: When I tested on Windows XP, it only gave me about 10ms accuracy
    // (but at least it compiles)

    struct timezone {
        int  tz_minuteswest;
        int  tz_dsttime;
    };

    int gettimeofday(struct timeval *tv, struct timezone *tz) {
        FILETIME ft;
        GetSystemTimeAsFileTime(&ft);
        unsigned long long t = ft.dwHighDateTime;
        t <<= 32;
        t |= ft.dwLowDateTime;
        t /= 10;
        t -= 11644473600000000ULL;
        tv->tv_sec = (long) (t / 1000000UL);
        tv->tv_usec = (long) (t % 1000000UL);

        return 0;
    }
#else
    #include <sys/time.h>
#endif

static NAN_METHOD(Now) {
    NanScope();

    timeval t;
    int r = gettimeofday(&t, NULL);

    if (r < 0) {
        NanThrowError(node::ErrnoException(errno, "gettimeofday"));
        NanReturnUndefined();
    }

    NanReturnValue(NanNew<v8::Number>((t.tv_sec * 1000000.0) + t.tv_usec));
}

static NAN_METHOD(NowDouble) {
    NanScope();

    timeval t;
    int r = gettimeofday(&t, NULL);

    if (r < 0) {
        NanThrowError(node::ErrnoException(errno, "gettimeofday"));
        NanReturnUndefined();
    }

    NanReturnValue(NanNew<v8::Number>(t.tv_sec + (t.tv_usec * 0.000001)));
}

static NAN_METHOD(NowStruct) {
    NanScope();

    timeval t;
    int r = gettimeofday(&t, NULL);

    if (r < 0) {
        NanThrowError(node::ErrnoException(errno, "gettimeofday"));
        NanReturnUndefined();
    }

    v8::Local<v8::Array> array = NanNew<v8::Array>(2);
    array->Set(NanNew<v8::Integer>(0), NanNew<v8::Number>((double)t.tv_sec));
    array->Set(NanNew<v8::Integer>(1), NanNew<v8::Number>((double)t.tv_usec));

    NanReturnValue(array);
}

void init(v8::Handle<v8::Object> target) {
    NODE_SET_METHOD(target, "now", Now);
    NODE_SET_METHOD(target, "nowDouble", NowDouble);
    NODE_SET_METHOD(target, "nowStruct", NowStruct);
}
NODE_MODULE(microtime,init)
<|endoftext|>


<commit_before>//=======================================================================
// Copyright (c) 2013-2017 Baptiste Wicht.
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#ifndef DATA_H
#define DATA_H

#include "cpp_utils/assert.hpp"

#include "config.hpp"
#include "utils.hpp"
#include "server.hpp"
#include "api.hpp"

namespace budget {

template<typename T>
struct data_handler {
    size_t next_id;
    std::vector<T> data;

    data_handler(const char* module, const char* path) : module(module), path(path) {
        // Nothing else to init
    };

    //data_handler should never be copied
    data_handler(const data_handler& rhs) = delete;
    data_handler& operator=(const data_handler& rhs) = delete;

    bool is_changed() const {
        return changed;
    }

    void set_changed() {
        if (is_server_running()) {
            force_save();
        } else {
            changed = true;
        }
    }

    template<typename Functor>
    void parse_stream(std::istream& file, Functor f){
        next_id = 1;

        std::string line;
        while (file.good() && getline(file, line)) {
            if (line.empty()) {
                continue;
            }

            auto parts = split(line, ':');

            T entry;

            f(parts, entry);

            if (entry.id >= next_id) {
                next_id = entry.id + 1;
            }

            data.push_back(std::move(entry));
        }
    }

    template<typename Functor>
    void load(Functor f){
        //Make sure to clear the data first, as load_data can be called
        //several times
        data.clear();

        if(is_server_mode()){
            auto res = budget::api_get(std::string("/") + module + "/list/");

            if(res.success){
                std::stringstream ss(res.result);
                parse_stream(ss, f);
            }
        } else {
            auto file_path = path_to_budget_file(path);

            if (!file_exists(file_path)) {
                next_id = 1;
            } else {
                std::ifstream file(file_path);

                if (file.is_open()) {
                    if (file.good()) {
                        // We do not use the next_id saved anymore
                        // Simply consume it
                        size_t fake;
                        file >> fake;
                        file.get();

                        parse_stream(file, f);
                    }
                }
            }
        }
    }

    void load(){
        load([](std::vector<std::string>& parts, T& entry){ parts >> entry; });
    }

    void force_save() {
        if (budget::config_contains("random")) {
            std::cerr << "budget: error: Saving is disabled in random mode" << std::endl;
            return;
        }

        auto file_path = path_to_budget_file(path);

        std::ofstream file(file_path);

        // We still save the file ID so that it's still compatible with older versions for now
        file << next_id << std::endl;

        for (auto& entry : data) {
            file << entry << std::endl;
        }

        changed = false;
    }

    void save() {
        if (is_changed()) {
            force_save();
        }
    }

    size_t size() const {
        return data.size();
    }

    decltype(auto) begin() {
        return data.begin();
    }

    decltype(auto) begin() const {
        return data.begin();
    }

    decltype(auto) end() {
        return data.end();
    }

    decltype(auto) end() const {
        return data.end();
    }

    const char* get_module() const {
        return module;
    }

private:
    const char* module;
    const char* path;
    bool changed = false;
};

template<typename T>
bool exists(const data_handler<T>& data, size_t id){
    for(auto& entry : data.data){
        if(entry.id == id){
            return true;
        }
    }

    return false;
}

template<typename T>
void remove(data_handler<T>& data, size_t id){
    data.data.erase(std::remove_if(data.data.begin(), data.data.end(),
        [id](const T& entry){ return entry.id == id; }), data.data.end());

    data.set_changed();
}

template<typename T>
T& get(data_handler<T>& data, size_t id){
    for(auto& value : data.data){
        if(value.id == id){
            return value;
        }
    }

    cpp_unreachable("The data must exists");
}

template<typename T>
size_t add_data(data_handler<T>& data, T&& entry){
    if (is_server_mode()) {
        auto params = entry.get_params();

        auto res = budget::api_post(std::string("/") + data.get_module() + "/add/", params);

        if (!res.success) {
            std::cerr << "error: Failed to add expense" << std::endl;

            entry.id = 0;
        } else {
            entry.id = budget::to_number<size_t>(res.result);

            data.data.push_back(std::forward<T>(entry));
        }
    } else {
        entry.id = data.next_id++;

        data.data.push_back(std::forward<T>(entry));

        data.set_changed();
    }

    return entry.id;
}

} //end of namespace budget

#endif
<commit_msg>Cleanup mode handling in data<commit_after>//=======================================================================
// Copyright (c) 2013-2017 Baptiste Wicht.
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#ifndef DATA_H
#define DATA_H

#include "cpp_utils/assert.hpp"

#include "config.hpp"
#include "utils.hpp"
#include "server.hpp"
#include "api.hpp"

namespace budget {

template<typename T>
struct data_handler {
    size_t next_id;
    std::vector<T> data;

    data_handler(const char* module, const char* path) : module(module), path(path) {
        // Nothing else to init
    };

    //data_handler should never be copied
    data_handler(const data_handler& rhs) = delete;
    data_handler& operator=(const data_handler& rhs) = delete;

    bool is_changed() const {
        return changed;
    }

    void set_changed() {
        if (is_server_running()) {
            force_save();
        } else {
            changed = true;
        }
    }

    template<typename Functor>
    void parse_stream(std::istream& file, Functor f){
        next_id = 1;

        std::string line;
        while (file.good() && getline(file, line)) {
            if (line.empty()) {
                continue;
            }

            auto parts = split(line, ':');

            T entry;

            f(parts, entry);

            if (entry.id >= next_id) {
                next_id = entry.id + 1;
            }

            data.push_back(std::move(entry));
        }
    }

    template<typename Functor>
    void load(Functor f){
        //Make sure to clear the data first, as load_data can be called
        //several times
        data.clear();

        if(is_server_mode()){
            auto res = budget::api_get(std::string("/") + module + "/list/");

            if(res.success){
                std::stringstream ss(res.result);
                parse_stream(ss, f);
            }
        } else {
            auto file_path = path_to_budget_file(path);

            if (!file_exists(file_path)) {
                next_id = 1;
            } else {
                std::ifstream file(file_path);

                if (file.is_open()) {
                    if (file.good()) {
                        // We do not use the next_id saved anymore
                        // Simply consume it
                        size_t fake;
                        file >> fake;
                        file.get();

                        parse_stream(file, f);
                    }
                }
            }
        }
    }

    void load(){
        load([](std::vector<std::string>& parts, T& entry){ parts >> entry; });
    }

    void force_save() {
        cpp_assert(!is_server_mode(), "force_save() should never be called in server mode");

        if (budget::config_contains("random")) {
            std::cerr << "budget: error: Saving is disabled in random mode" << std::endl;
            return;
        }

        auto file_path = path_to_budget_file(path);

        std::ofstream file(file_path);

        // We still save the file ID so that it's still compatible with older versions for now
        file << next_id << std::endl;

        for (auto& entry : data) {
            file << entry << std::endl;
        }

        changed = false;
    }

    void save() {
        // In server mode, there is nothing to do
        if (is_server_mode()) {
            // It shoud not be changed
            cpp_assert(!is_changed(), "in server mode, is_changed() should never be true");

            return;
        }

        // In other modes, save if it's changed
        if (is_changed()) {
            force_save();
        }
    }

    size_t size() const {
        return data.size();
    }

    decltype(auto) begin() {
        return data.begin();
    }

    decltype(auto) begin() const {
        return data.begin();
    }

    decltype(auto) end() {
        return data.end();
    }

    decltype(auto) end() const {
        return data.end();
    }

    const char* get_module() const {
        return module;
    }

private:
    const char* module;
    const char* path;
    bool changed = false;
};

template<typename T>
bool exists(const data_handler<T>& data, size_t id){
    for(auto& entry : data.data){
        if(entry.id == id){
            return true;
        }
    }

    return false;
}

template<typename T>
void remove(data_handler<T>& data, size_t id){
    data.data.erase(std::remove_if(data.data.begin(), data.data.end(),
        [id](const T& entry){ return entry.id == id; }), data.data.end());

    data.set_changed();
}

template<typename T>
T& get(data_handler<T>& data, size_t id){
    for(auto& value : data.data){
        if(value.id == id){
            return value;
        }
    }

    cpp_unreachable("The data must exists");
}

template<typename T>
size_t add_data(data_handler<T>& data, T&& entry){
    if (is_server_mode()) {
        auto params = entry.get_params();

        auto res = budget::api_post(std::string("/") + data.get_module() + "/add/", params);

        if (!res.success) {
            std::cerr << "error: Failed to add expense" << std::endl;

            entry.id = 0;
        } else {
            entry.id = budget::to_number<size_t>(res.result);

            data.data.push_back(std::forward<T>(entry));
        }
    } else {
        entry.id = data.next_id++;

        data.data.push_back(std::forward<T>(entry));

        data.set_changed();
    }

    return entry.id;
}

} //end of namespace budget

#endif
<|endoftext|>


<commit_before>/* This file is part of Zanshin

   Copyright 2014 Kevin Ottens <ervin@kde.org>

   This program 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 2 of
   the License or (at your option) version 3 or any later version
   accepted by the membership of KDE e.V. (or its successor approved
   by the membership of KDE e.V.), which shall act as a proxy
   defined in Section 14 of version 3 of the license.

   This program 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 this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
   USA.
*/

#include "pageview.h"

#include <QAction>
#include <QHeaderView>
#include <QLineEdit>
#include <QTreeView>
#include <QVBoxLayout>
#include <QMessageBox>

#include "filterwidget.h"
#include "itemdelegate.h"

#include "presentation/artifactfilterproxymodel.h"
#include "presentation/metatypes.h"
#include "presentation/querytreemodelbase.h"

using namespace Widgets;

PageView::PageView(QWidget *parent)
    : QWidget(parent),
      m_filterWidget(new FilterWidget(this)),
      m_centralView(new QTreeView(this)),
      m_quickAddEdit(new QLineEdit(this))
{
    m_filterWidget->setObjectName("filterWidget");

    m_centralView->setObjectName("centralView");
    m_centralView->header()->hide();
    m_centralView->setAlternatingRowColors(true);
    m_centralView->setItemDelegate(new ItemDelegate(this));
    m_centralView->setDragDropMode(QTreeView::DragDrop);
    m_centralView->setSelectionMode(QAbstractItemView::ExtendedSelection);
    m_centralView->setModel(m_filterWidget->proxyModel());

    m_quickAddEdit->setObjectName("quickAddEdit");
    m_quickAddEdit->setPlaceholderText(tr("Type and press enter to add an action"));
    connect(m_quickAddEdit, SIGNAL(editingFinished()), this, SLOT(onEditingFinished()));

    auto layout = new QVBoxLayout;
    layout->addWidget(m_filterWidget);
    layout->addWidget(m_centralView);
    layout->addWidget(m_quickAddEdit);
    setLayout(layout);

    QAction *removeItemAction = new QAction(this);
    removeItemAction->setShortcut(Qt::Key_Delete);
    connect(removeItemAction, SIGNAL(triggered()), this, SLOT(onRemoveItemRequested()));
    addAction(removeItemAction);

    m_askConfirmationFunction = [] (const QString &text, QWidget *parent) -> int {
        QString title = tr("Delete Tasks");
        return QMessageBox::question(parent, title, text, QMessageBox::Yes | QMessageBox::No);
    };
}

QObject *PageView::model() const
{
    return m_model;
}

void PageView::setModel(QObject *model)
{
    if (model == m_model)
        return;

    if (m_centralView->selectionModel()) {
        disconnect(m_centralView->selectionModel(), 0, this, 0);
    }

    m_filterWidget->proxyModel()->setSourceModel(0);

    m_model = model;

    if (!m_model)
        return;

    QVariant modelProperty = m_model->property("centralListModel");
    if (modelProperty.canConvert<QAbstractItemModel*>())
        m_filterWidget->proxyModel()->setSourceModel(modelProperty.value<QAbstractItemModel*>());

    connect(m_centralView->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
            this, SLOT(onCurrentChanged(QModelIndex)));
}

PageView::AskConfirmationFunction PageView::askConfirmationFunction() const
{
    return m_askConfirmationFunction;
}

void PageView::setAskConfirmationFunction(const PageView::AskConfirmationFunction &askConfirmationFunction)
{
    m_askConfirmationFunction = askConfirmationFunction;
}

void PageView::onEditingFinished()
{
    if (m_quickAddEdit->text().isEmpty())
        return;

    QMetaObject::invokeMethod(m_model, "addTask", Q_ARG(QString, m_quickAddEdit->text()));
    m_quickAddEdit->clear();
}

void PageView::onRemoveItemRequested()
{
    const QModelIndexList &currentIndexes = m_centralView->selectionModel()->selectedIndexes();
    if (currentIndexes.isEmpty())
        return;

    QString text;
    if (currentIndexes.size() > 1) {
        bool hasDescendants = false;
        foreach (const QModelIndex &currentIndex, currentIndexes) {
            if (!currentIndex.isValid())
                continue;

            if (currentIndex.model()->rowCount(currentIndex) > 0) {
                hasDescendants = true;
                break;
            }
        }

        if (hasDescendants)
            text = tr("Do you really want to delete the selected items and their children?");
        else
            text = tr("Do you really want to delete the selected items?");

    } else {
        const QModelIndex &currentIndex = currentIndexes.first();
        if (!currentIndex.isValid())
            return;

        if (currentIndex.model()->rowCount(currentIndex) > 0)
            text = tr("Do you really want to delete the selected task and all its children?");
    }

    if (!text.isEmpty()) {
        int button = m_askConfirmationFunction(text, this);
        bool canRemove = (button == QMessageBox::Yes);

        if (!canRemove)
            return;
    }

    foreach (const QModelIndex &currentIndex, currentIndexes) {
        if (!currentIndex.isValid())
            continue;

        QMetaObject::invokeMethod(m_model, "removeItem", Q_ARG(QModelIndex, currentIndex));
    }
}

void PageView::onCurrentChanged(const QModelIndex &current)
{
    auto data = current.data(Presentation::QueryTreeModelBase::ObjectRole);
    if (!data.isValid())
        return;

    auto artifact = data.value<Domain::Artifact::Ptr>();
    if (!artifact)
        return;

    emit currentArtifactChanged(artifact);
}
<commit_msg>Fix uninitialized variable<commit_after>/* This file is part of Zanshin

   Copyright 2014 Kevin Ottens <ervin@kde.org>

   This program 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 2 of
   the License or (at your option) version 3 or any later version
   accepted by the membership of KDE e.V. (or its successor approved
   by the membership of KDE e.V.), which shall act as a proxy
   defined in Section 14 of version 3 of the license.

   This program 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 this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
   USA.
*/

#include "pageview.h"

#include <QAction>
#include <QHeaderView>
#include <QLineEdit>
#include <QTreeView>
#include <QVBoxLayout>
#include <QMessageBox>

#include "filterwidget.h"
#include "itemdelegate.h"

#include "presentation/artifactfilterproxymodel.h"
#include "presentation/metatypes.h"
#include "presentation/querytreemodelbase.h"

using namespace Widgets;

PageView::PageView(QWidget *parent)
    : QWidget(parent),
      m_model(0),
      m_filterWidget(new FilterWidget(this)),
      m_centralView(new QTreeView(this)),
      m_quickAddEdit(new QLineEdit(this))
{
    m_filterWidget->setObjectName("filterWidget");

    m_centralView->setObjectName("centralView");
    m_centralView->header()->hide();
    m_centralView->setAlternatingRowColors(true);
    m_centralView->setItemDelegate(new ItemDelegate(this));
    m_centralView->setDragDropMode(QTreeView::DragDrop);
    m_centralView->setSelectionMode(QAbstractItemView::ExtendedSelection);
    m_centralView->setModel(m_filterWidget->proxyModel());

    m_quickAddEdit->setObjectName("quickAddEdit");
    m_quickAddEdit->setPlaceholderText(tr("Type and press enter to add an action"));
    connect(m_quickAddEdit, SIGNAL(editingFinished()), this, SLOT(onEditingFinished()));

    auto layout = new QVBoxLayout;
    layout->addWidget(m_filterWidget);
    layout->addWidget(m_centralView);
    layout->addWidget(m_quickAddEdit);
    setLayout(layout);

    QAction *removeItemAction = new QAction(this);
    removeItemAction->setShortcut(Qt::Key_Delete);
    connect(removeItemAction, SIGNAL(triggered()), this, SLOT(onRemoveItemRequested()));
    addAction(removeItemAction);

    m_askConfirmationFunction = [] (const QString &text, QWidget *parent) -> int {
        QString title = tr("Delete Tasks");
        return QMessageBox::question(parent, title, text, QMessageBox::Yes | QMessageBox::No);
    };
}

QObject *PageView::model() const
{
    return m_model;
}

void PageView::setModel(QObject *model)
{
    if (model == m_model)
        return;

    if (m_centralView->selectionModel()) {
        disconnect(m_centralView->selectionModel(), 0, this, 0);
    }

    m_filterWidget->proxyModel()->setSourceModel(0);

    m_model = model;

    if (!m_model)
        return;

    QVariant modelProperty = m_model->property("centralListModel");
    if (modelProperty.canConvert<QAbstractItemModel*>())
        m_filterWidget->proxyModel()->setSourceModel(modelProperty.value<QAbstractItemModel*>());

    connect(m_centralView->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
            this, SLOT(onCurrentChanged(QModelIndex)));
}

PageView::AskConfirmationFunction PageView::askConfirmationFunction() const
{
    return m_askConfirmationFunction;
}

void PageView::setAskConfirmationFunction(const PageView::AskConfirmationFunction &askConfirmationFunction)
{
    m_askConfirmationFunction = askConfirmationFunction;
}

void PageView::onEditingFinished()
{
    if (m_quickAddEdit->text().isEmpty())
        return;

    QMetaObject::invokeMethod(m_model, "addTask", Q_ARG(QString, m_quickAddEdit->text()));
    m_quickAddEdit->clear();
}

void PageView::onRemoveItemRequested()
{
    const QModelIndexList &currentIndexes = m_centralView->selectionModel()->selectedIndexes();
    if (currentIndexes.isEmpty())
        return;

    QString text;
    if (currentIndexes.size() > 1) {
        bool hasDescendants = false;
        foreach (const QModelIndex &currentIndex, currentIndexes) {
            if (!currentIndex.isValid())
                continue;

            if (currentIndex.model()->rowCount(currentIndex) > 0) {
                hasDescendants = true;
                break;
            }
        }

        if (hasDescendants)
            text = tr("Do you really want to delete the selected items and their children?");
        else
            text = tr("Do you really want to delete the selected items?");

    } else {
        const QModelIndex &currentIndex = currentIndexes.first();
        if (!currentIndex.isValid())
            return;

        if (currentIndex.model()->rowCount(currentIndex) > 0)
            text = tr("Do you really want to delete the selected task and all its children?");
    }

    if (!text.isEmpty()) {
        int button = m_askConfirmationFunction(text, this);
        bool canRemove = (button == QMessageBox::Yes);

        if (!canRemove)
            return;
    }

    foreach (const QModelIndex &currentIndex, currentIndexes) {
        if (!currentIndex.isValid())
            continue;

        QMetaObject::invokeMethod(m_model, "removeItem", Q_ARG(QModelIndex, currentIndex));
    }
}

void PageView::onCurrentChanged(const QModelIndex &current)
{
    auto data = current.data(Presentation::QueryTreeModelBase::ObjectRole);
    if (!data.isValid())
        return;

    auto artifact = data.value<Domain::Artifact::Ptr>();
    if (!artifact)
        return;

    emit currentArtifactChanged(artifact);
}
<|endoftext|>


<commit_before>#include "momentum.h"
#include <boost/unordered_map.hpp>
#include <iostream>

namespace bts
{
#define MAX_MOMENTUM_NONCE  (1<<26)
#define SEARCH_SPACE_BITS 50
#define BIRTHDAYS_PER_HASH 8

// I'm a terrible person.
#define UPDATE_HASH(varname)                                                               \
    if (varname##_offset >= BIRTHDAYS_PER_HASH) {                                          \
        varname##_offset = varname##_offset % BIRTHDAYS_PER_HASH;                          \
        varname##_nonce = (varname##_minhash >> (64 - SEARCH_SPACE_BITS));                 \
                                                                                \
        *index = varname##_nonce;                                                          \
        SHA512((unsigned char *)hash_tmp, sizeof(hash_tmp), (unsigned char *)result_hash); \
                                                                                \
        varname##_minhash = result_hash[0];                                                \
        for (unsigned int sz = 0; sz < BIRTHDAYS_PER_HASH; ++sz) {                         \
            if (result_hash[sz] < varname##_minhash) {                                     \
                varname##_minhash = result_hash[sz];                                       \
            }                                                                              \
            varname##_hash[sz] = result_hash[sz];                                          \
        }                                                                                \
    }

std::vector< std::pair<uint32_t, uint32_t> > momentum_search(uint256 midHash)
{
    std::vector< std::pair<uint32_t, uint32_t> > results;

    char  hash_tmp[sizeof(midHash) + 4];
    memcpy((char *)&hash_tmp[4], (char *)&midHash, sizeof(midHash));
    uint32_t *index = (uint32_t *)hash_tmp;
    bool found_hit = false;
    uint32_t i = 0;

    while (true) {  // Stops after i = MAX_MOMENTUM_NONCE

        // X
        uint32_t turtle_nonce = i - (i % BIRTHDAYS_PER_HASH);
        uint32_t turtle_offset = (i % BIRTHDAYS_PER_HASH);
        uint64_t turtle_minhash = 0;
        uint64_t turtle_hash[8];

        // X'
        uint32_t hare_nonce = i - (i % BIRTHDAYS_PER_HASH);
        uint32_t hare_offset = (i % BIRTHDAYS_PER_HASH);
        uint64_t hare_minhash = 0;
        uint64_t hare_hash[8];

        // Defining X_0
        *index = i;
        uint64_t result_hash[8];
        SHA512((unsigned char *)hash_tmp, sizeof(hash_tmp), (unsigned char *)result_hash);
        turtle_minhash = result_hash[0];
        hare_minhash = result_hash[0];
        for (unsigned int sz = 0; sz < BIRTHDAYS_PER_HASH; ++sz) {
            turtle_hash[sz] = result_hash[sz];
            hare_hash[sz] = result_hash[sz];

            if (result_hash[sz] < turtle_minhash) {
                turtle_minhash = result_hash[sz];
                hare_minhash = result_hash[sz];
            }
        }

        // Step 1: dig for a hit
        // Not using 2^(SEARCH_SPACE_BITS/2)
        for(; i < MAX_MOMENTUM_NONCE; ++i) {

            // TURTLE
            // X = H(X)
            ++turtle_offset;
            UPDATE_HASH(turtle);

            // HARE
            // X' = H( H(X) )
            hare_offset += 2;
            UPDATE_HASH(hare);

            // Found a collision!
            if ((turtle_hash[turtle_offset] >> (64 - SEARCH_SPACE_BITS)) == (hare_hash[hare_offset] >> (64 - SEARCH_SPACE_BITS))) {

                // Are we stuck in a loop or find an actual collision?
                if (turtle_nonce != hare_nonce && turtle_offset != hare_offset) {
                    std::cerr << "Collision found!\n";
                    std::cerr << "   Iteration:     " << i << "\n";
                    std::cerr << "   Turtle Nonce:  " << turtle_nonce  << "\n";
                    std::cerr << "   Turtle Offset: " << turtle_offset << "\n";
                    std::cerr << "   Turtle Hash:   " << (turtle_hash[turtle_offset] >> (64 - SEARCH_SPACE_BITS)) << "\n";
                    std::cerr << "   Turtle Nonce Valid: " << (turtle_nonce < MAX_MOMENTUM_NONCE ? "YES" : "NO") << "\n";
                    std::cerr << "   Hare Nonce:    " << hare_nonce  << "\n";
                    std::cerr << "   Hare Offset:   " << hare_offset << "\n";
                    std::cerr << "   Hare Hash:     " << (hare_hash[hare_offset] >> (64 - SEARCH_SPACE_BITS)) << "\n";
                    std::cerr << "   Hare Nonce Valid:   " << (hare_nonce < MAX_MOMENTUM_NONCE ? "YES" : "NO") << "\n";

                    found_hit = true;
                    results.push_back( std::make_pair(turtle_nonce + turtle_offset, hare_nonce + hare_offset) );
                }

                // Either way, go get a new nonce
                break;
            }
        }

        // Keep scanning until we do MAX_MOMENTUM_NONCE checks
        if (i >= MAX_MOMENTUM_NONCE) {
            std::cerr << "Search complete.  Collisions found: " << results.size() << "\n";
            return results;
        }
    }

    return results;
}

uint64_t getBirthdayHash(const uint256 &midHash, uint32_t a)
{
    uint32_t index = a - (a % 8);
    char  hash_tmp[sizeof(midHash) + 4];

    memcpy(&hash_tmp[4], (char *)&midHash, sizeof(midHash));
    memcpy(&hash_tmp[0], (char *)&index, sizeof(index));

    uint64_t  result_hash[8];

    SHA512((unsigned char *)hash_tmp, sizeof(hash_tmp), (unsigned char *)&result_hash);

    uint64_t r = result_hash[a % BIRTHDAYS_PER_HASH] >> (64 - SEARCH_SPACE_BITS);

    return r;
}

bool momentum_verify(uint256 head, uint32_t a, uint32_t b)
{

    if(a == b) {
        return false;
    }

    if(a > MAX_MOMENTUM_NONCE) {
        return false;
    }

    if(b > MAX_MOMENTUM_NONCE) {
        return false;
    }

    bool r = (getBirthdayHash(head, a) == getBirthdayHash(head, b));
    return r;
}

}
<commit_msg>Complete rewrite using Floyd's Algorithm<commit_after>#include "momentum.h"
#include <boost/unordered_map.hpp>
#include <iostream>

namespace bts
{
uint64_t getBirthdayHash(const uint256 &midHash, uint32_t a);

#define MAX_MOMENTUM_NONCE ( 1<<26 )
#define SEARCH_SPACE_BITS  ( 50 )
#define BIRTHDAYS_PER_HASH ( 8 )

#define DEBUG_MODE ( 0 )

///// UTILITY FUNCTIONS /////

// Compresses "hash" to within MAX_MOMENTUM_NONCE space
#define COMPRESS_CHUNK(chunk) ( chunk % MAX_MOMENTUM_NONCE )
#define COMPRESS_HASH(hash)   ( COMPRESS_CHUNK(hash[0]) )

// HASH is a wrapper for SHA512
// It creates BIRTHDAYS_PER_HASH elements, each one
//   right shifted by (64 - SEARCH_SPACE_BITS)
#define HASH(input, temp, output)                                         \
{                                                                         \
    *hash_input = input;                                                  \
    SHA512((unsigned char *)temp, sizeof(temp), (unsigned char *)output); \
    output[0] >>= (64 - SEARCH_SPACE_BITS);                               \
    output[1] >>= (64 - SEARCH_SPACE_BITS);                               \
    output[2] >>= (64 - SEARCH_SPACE_BITS);                               \
    output[3] >>= (64 - SEARCH_SPACE_BITS);                               \
    output[4] >>= (64 - SEARCH_SPACE_BITS);                               \
    output[5] >>= (64 - SEARCH_SPACE_BITS);                               \
    output[6] >>= (64 - SEARCH_SPACE_BITS);                               \
    output[7] >>= (64 - SEARCH_SPACE_BITS);                               \
}

// Given a hash chunk "cur_hash", if it exists in
//   "hash_list", return the index, else -1.
#define CONTAINS_HASH(cur_chunk, hash_list) \
    (cur_chunk == hash_list[0] ? 0 :        \
     cur_chunk == hash_list[1] ? 1 :        \
     cur_chunk == hash_list[2] ? 2 :        \
     cur_chunk == hash_list[3] ? 3 :        \
     cur_chunk == hash_list[4] ? 4 :        \
     cur_chunk == hash_list[5] ? 5 :        \
     cur_chunk == hash_list[6] ? 6 :        \
     cur_chunk == hash_list[7] ? 7 :        \
     0xFF)

#define PRINT_HASH(hash)                         \
{                                                \
std::cerr << "         0: " << hash[0] << "\n"   \
          << "         1: " << hash[1] << "\n"   \
          << "         2: " << hash[2] << "\n"   \
          << "         3: " << hash[3] << "\n"   \
          << "         4: " << hash[4] << "\n"   \
          << "         5: " << hash[5] << "\n"   \
          << "         6: " << hash[6] << "\n"   \
          << "         7: " << hash[7] << "\n";  \
}

#define COPY_HASH(src, dst) \
{                           \
    dst[0] = src[0];        \
    dst[1] = src[1];        \
    dst[2] = src[2];        \
    dst[3] = src[3];        \
    dst[4] = src[4];        \
    dst[5] = src[5];        \
    dst[6] = src[6];        \
    dst[7] = src[7];        \
}

///// MAIN HASH /////

std::vector< std::pair<uint32_t, uint32_t> > momentum_search(uint256 midHash)
{
    std::vector< std::pair<uint32_t, uint32_t> > results;
    boost::unordered_map< uint64_t, uint32_t > rainbow( RAINBOW_ENTRIES );
    rainbow.rehash( RAINBOW_ENTRIES );

    char hash_temp[sizeof(uint256) + 4];
    memcpy((char *)&hash_temp[4], (char *)&midHash, sizeof(midHash));
    uint32_t *hash_input = (uint32_t *)hash_temp;
    uint64_t result_hash[8];

    // Floyd's cycle-finding algorithm
    uint32_t power = 1;
    uint32_t lam = 1;

    uint64_t turtle_hash[8];
    uint32_t turtle_nonce = 0;

    uint64_t hare_hash[8];
    uint32_t hare_nonce = 0;

    // Turtle = X_0
    HASH(0, hash_temp, turtle_hash);

    // Hare = F(X_0)
    hare_nonce = COMPRESS(result_hash);
    HASH(hare_nonce, hash_temp, hare_hash);

    while (power <= MAX_MOMENTUM_NONCE) {
        for (uint32_t chunk = 0; chunk < BIRTHDAYS_PER_HASH; ++chunk) {
            uint32_t offset = CONTAINS_HASH(hare[chunk], turtle_hash);

            if (offset != 0xFF) {
                if (DEBUG) {
                    std::cerr << "Found hit PART 1\n";
                    std::cerr << "Hare Nonce: " << hare_nonce << " + " << chunk << "\n";
                    PRINT_HASH(hare_hash);
                    std::cerr << "Trtl Nonce: " << turtle_nonce << " + " << offset << "\n";
                    PRITN_HASH(turtle_hash);
                }

                break;
            }
        }

        if (power == lam) {
            COPY_HASH(hare_hash, turtle_hash);
            turtle_nonce = hare_nonce;
            power <<= 1;
            lam = 0;
        }

        hare_nonce = COMPRESS(hare_hash);
        HASH(hare_nonce, hash_temp, hare_hash);
        ++lam;
    }

    // Nothing found, give up.
    if (power >= MAX_MOMENTUM_NONCE) { return results; }

    // Rewind to find first repetition of nonces
    turtle_nonce = 0;
    HASH(turtle_nonce, hash_temp, turtle_hash);
    hare_nonce = 0;
    HASH_COPY(turtle_hash, hare_hash);

    for (uint32_t fastforward = 0; fastforward < lam; ++fastforward) {
        hare_nonce = COMPRESS(hare_hash);
        HASH(hare_nonce, hash_temp, hare_hash);
    }

    while (true) {
        for (uint32_t chunk = 0; chunk < BIRTHDAYS_PER_HASH; ++chunk) {
            uint32_t offset = CONTAINS_HASH(hare[chunk], turtle_hash);

            if (offset != 0xFF) {
                if (DEBUG) {
                    std::cerr << "Found hit PART 2\n";
                    std::cerr << "Hare Nonce: " << hare_nonce << " + " << chunk << "\n";
                    PRINT_HASH(hare_hash);
                    std::cerr << "Trtl Nonce: " << turtle_nonce << " + " << offset << "\n";
                    PRITN_HASH(turtle_hash);
                }

                results.push_back( std::make_pair( hare_nonce + chunk, turtle_nonce + offset ) );
                return results;
            }
        }

        turtle_nonce = COMPRESS(turtle_hash);
        HASH(turtle_nonce, hash_temp, turtle_hash);

        hare_nonce = COMPRESS(hare_hash);
        HASH(hare_nonce, hash_temp, hare_hash);
    }

    std::cerr << "You should never be here!\n";

    return results;
}

uint64_t getBirthdayHash(const uint256 &midHash, uint32_t a)
{
    uint32_t index = a - (a % 8);
    char  hash_tmp[sizeof(midHash) + 4];

    memcpy(&hash_tmp[4], (char *)&midHash, sizeof(midHash));
    memcpy(&hash_tmp[0], (char *)&index, sizeof(index));

    uint64_t  result_hash[8];

    SHA512((unsigned char *)hash_tmp, sizeof(hash_tmp), (unsigned char *)&result_hash);

    uint64_t r = result_hash[a % BIRTHDAYS_PER_HASH] >> (64 - SEARCH_SPACE_BITS);

    return r;
}

bool momentum_verify(uint256 head, uint32_t a, uint32_t b)
{
    if(a == b) {
        return false;
    }

    if(a > MAX_MOMENTUM_NONCE) {
        return false;
    }

    if(b > MAX_MOMENTUM_NONCE) {
        return false;
    }

    bool r = (getBirthdayHash(head, a) == getBirthdayHash(head, b));
    return r;
}

}
<|endoftext|>


<commit_before>//------------------------------------------------------------------------------
//  Log.cc
//------------------------------------------------------------------------------
#include "Pre.h"
#include <cstdio>
#include "Core/Log.h"
#include "Core/Assert.h"
#include "Core/Logger.h"
#include "Core/Threading/RWLock.h"
#include "Core/Containers/Array.h"
#if ORYOL_WINDOWS
#include "Windows.h"
const Oryol::int32 LogBufSize = 2048;
#endif
#if ORYOL_ANDROID
#include <android/log.h>
#endif

namespace Oryol {
namespace Core {

using namespace std;

Log::Level curLogLevel = Log::Level::Dbg;
RWLock lock;
Array<Ptr<Logger>> loggers;

//------------------------------------------------------------------------------
void
Log::AddLogger(const Ptr<Logger>& l) {
    if (l) {
        lock.LockWrite();
        loggers.AddBack(l);
        lock.UnlockWrite();
    }
}

//------------------------------------------------------------------------------
int32
Log::GetNumLoggers() {
    return loggers.Size();
}

//------------------------------------------------------------------------------
Ptr<Logger>
Log::GetLogger(int32 index) {
    return loggers[index];
}

//------------------------------------------------------------------------------
void
Log::SetLogLevel(Level l) {
    curLogLevel = l;
}

//------------------------------------------------------------------------------
Log::Level
Log::GetLogLevel() {
    return curLogLevel;
}

//------------------------------------------------------------------------------
void
Log::Dbg(const char* msg, ...) {
    if (curLogLevel >= Level::Dbg) {
        va_list args;
        va_start(args, msg);
        Log::vprint(Level::Dbg, msg, args);
        va_end(args);
    }
}

//------------------------------------------------------------------------------
void
Log::Info(const char* msg, ...) {
    if (curLogLevel >= Level::Info) {
        va_list args;
        va_start(args, msg);
        Log::vprint(Level::Info, msg, args);
        va_end(args);
    }
}

//------------------------------------------------------------------------------
void
Log::Warn(const char* msg, ...) {
    if (curLogLevel >= Level::Warn) {
        va_list args;
        va_start(args, msg);
        Log::vprint(Level::Warn, msg, args);
        va_end(args);
    }
}

//------------------------------------------------------------------------------
void
Log::Error(const char* msg, ...) {
    if (curLogLevel >= Level::Error) {
        va_list args;
        va_start(args, msg);
        Log::vprint(Level::Error, msg, args);
        va_end(args);
    }
}

//------------------------------------------------------------------------------
void
Log::vprint(Level lvl, const char* msg, va_list args) {
    lock.LockRead();
    if (loggers.Empty()) {
        #if ORYOL_ANDROID
            android_LogPriority pri = ANDROID_LOG_DEFAULT;
            switch (lvl) {
                case Level::Error: pri = ANDROID_LOG_ERROR; break;
                case Level::Warn:  pri = ANDROID_LOG_WARN; break;
                case Level::Info:  pri = ANDROID_LOG_INFO; break;
                case Level::Dbg:   pri = ANDROID_LOG_DEBUG; break;
                default:           pri = ANDROID_LOG_DEFAULT; break;
            }
            __android_log_vprint(pri, "oryol", msg, args);
        #else
            std::vprintf(msg, args);
            #if ORYOL_WINDOWS
                char buf[LogBufSize];
                std::vsnprintf(buf, sizeof(buf), msg, args);
                buf[LogBufSize - 1] = 0;
                OutputDebugString(buf);
            #endif
        #endif
    }
    else {
        for (auto l : loggers) {
            l->VPrint(lvl, msg, args);
        }
    }
    lock.UnlockRead();
}

//------------------------------------------------------------------------------
void
Log::AssertMsg(const char* cond, const char* msg, const char* file, int32 line, const char* func) {
    lock.LockRead();
    if (loggers.Empty()) {
        #if ORYOL_ANDROID
            __android_log_print(ANDROID_LOG_FATAL, "oryol", "oryol assert: cond='%s'\nmsg='%s'\nfile='%s'\nline='%d'\nfunc='%s'\n",
                cond, msg ? msg : "none", file, line, func);
        #else
            std::printf("oryol assert: cond='%s'\nmsg='%s'\nfile='%s'\nline='%d'\nfunc='%s'\n",
                        cond, msg ? msg : "none", file, line, func);
            #if ORYOL_WINDOWS
                char buf[LogBufSize];
                _snprintf_s(buf, sizeof(buf), _TRUNCATE, "oryol assert: cond='%s'\nmsg='%s'\nfile='%s'\nline='%d'\nfunc='%s'\n",
                            cond, msg ? msg : "none", file, line, func);
                buf[LogBufSize - 1] = 0;
                OutputDebugString(buf);
            #endif
        #endif
    }
    else
    {
        for (const auto& l : loggers) {
            l->AssertMsg(cond, msg, file, line, func);
        }
    }
    lock.UnlockRead();
}

} // namespace Core
} // namespace Oryol
<commit_msg>Added logging support for pnacl, and fixed bug when reusing va_list<commit_after>//------------------------------------------------------------------------------
//  Log.cc
//------------------------------------------------------------------------------
#include "Pre.h"
#include <cstdio>
#include "Core/Log.h"
#include "Core/Assert.h"
#include "Core/Logger.h"
#include "Core/Threading/RWLock.h"
#include "Core/Containers/Array.h"
#if ORYOL_WINDOWS
#include "Windows.h"
#endif
#if ORYOL_ANDROID
#include <android/log.h>
#endif
#if ORYOL_PNACL
#include "Core/pnacl/pnaclInstance.h"
#endif

#if ORYOL_WINDOWS || ORYOL_PNACL
const Oryol::int32 LogBufSize = 2048;
#endif

namespace Oryol {
namespace Core {

using namespace std;

Log::Level curLogLevel = Log::Level::Dbg;
RWLock lock;
Array<Ptr<Logger>> loggers;

//------------------------------------------------------------------------------
void
Log::AddLogger(const Ptr<Logger>& l) {
    if (l) {
        lock.LockWrite();
        loggers.AddBack(l);
        lock.UnlockWrite();
    }
}

//------------------------------------------------------------------------------
int32
Log::GetNumLoggers() {
    return loggers.Size();
}

//------------------------------------------------------------------------------
Ptr<Logger>
Log::GetLogger(int32 index) {
    return loggers[index];
}

//------------------------------------------------------------------------------
void
Log::SetLogLevel(Level l) {
    curLogLevel = l;
}

//------------------------------------------------------------------------------
Log::Level
Log::GetLogLevel() {
    return curLogLevel;
}

//------------------------------------------------------------------------------
void
Log::Dbg(const char* msg, ...) {
    if (curLogLevel >= Level::Dbg) {
        va_list args;
        va_start(args, msg);
        Log::vprint(Level::Dbg, msg, args);
        va_end(args);
    }
}

//------------------------------------------------------------------------------
void
Log::Info(const char* msg, ...) {
    if (curLogLevel >= Level::Info) {
        va_list args;
        va_start(args, msg);
        Log::vprint(Level::Info, msg, args);
        va_end(args);
    }
}

//------------------------------------------------------------------------------
void
Log::Warn(const char* msg, ...) {
    if (curLogLevel >= Level::Warn) {
        va_list args;
        va_start(args, msg);
        Log::vprint(Level::Warn, msg, args);
        va_end(args);
    }
}

//------------------------------------------------------------------------------
void
Log::Error(const char* msg, ...) {
    if (curLogLevel >= Level::Error) {
        va_list args;
        va_start(args, msg);
        Log::vprint(Level::Error, msg, args);
        va_end(args);
    }
}

//------------------------------------------------------------------------------
void
Log::vprint(Level lvl, const char* msg, va_list args) {
    lock.LockRead();
    if (loggers.Empty()) {
        #if ORYOL_ANDROID
            android_LogPriority pri = ANDROID_LOG_DEFAULT;
            switch (lvl) {
                case Level::Error: pri = ANDROID_LOG_ERROR; break;
                case Level::Warn:  pri = ANDROID_LOG_WARN; break;
                case Level::Info:  pri = ANDROID_LOG_INFO; break;
                case Level::Dbg:   pri = ANDROID_LOG_DEBUG; break;
                default:           pri = ANDROID_LOG_DEFAULT; break;
            }
            __android_log_vprint(pri, "oryol", msg, args);
        #else
            #if ORYOL_WINDOWS || ORYOL_PNACL
            va_list argsCopy;
            va_copy(argsCopy, args);
            #endif

            // do the vprintf, this will destroy the original
            // va_list, so we made a copy before if necessary
            std::vprintf(msg, args);

            #if ORYOL_WINDOWS || ORYOL_PNACL
                char buf[LogBufSize];
                std::vsnprintf(buf, sizeof(buf), msg, argsCopy);
                buf[LogBufSize - 1] = 0;
                #if ORYOL_WINDOWS
                    OutputDebugString(buf);
                #elif ORYOL_PNACL
                    if (pnaclInstance::HasInstance()) {
                        pnaclInstance::Instance()->putMsg(buf);
                    }
                #endif
            #endif
        #endif
    }
    else {
        for (auto l : loggers) {
            l->VPrint(lvl, msg, args);
        }
    }
    lock.UnlockRead();
}

//------------------------------------------------------------------------------
void
Log::AssertMsg(const char* cond, const char* msg, const char* file, int32 line, const char* func) {
    lock.LockRead();
    if (loggers.Empty()) {
        #if ORYOL_ANDROID
            __android_log_print(ANDROID_LOG_FATAL, "oryol", "oryol assert: cond='%s'\nmsg='%s'\nfile='%s'\nline='%d'\nfunc='%s'\n",
                cond, msg ? msg : "none", file, line, func);
        #else
            std::printf("oryol assert: cond='%s'\nmsg='%s'\nfile='%s'\nline='%d'\nfunc='%s'\n",
                        cond, msg ? msg : "none", file, line, func);
            #if ORYOL_WINDOWS
                char buf[LogBufSize];
                _snprintf_s(buf, sizeof(buf), _TRUNCATE, "oryol assert: cond='%s'\nmsg='%s'\nfile='%s'\nline='%d'\nfunc='%s'\n",
                            cond, msg ? msg : "none", file, line, func);
                buf[LogBufSize - 1] = 0;
                OutputDebugString(buf);
            #elif ORYOL_PNACL
                if (pnaclInstance::HasInstance()) {
                    char buf[LogBufSize];
                    std::snprintf(buf, sizeof(buf), "oryol assert: cond='%s'\nmsg='%s'\nfile='%s'\nline='%d'\nfunc='%s'\n",
                                  cond, msg ? msg : "none", file, line, func);
                    buf[LogBufSize - 1] = 0;
                    pnaclInstance::Instance()->putMsg(buf);
                }
            #endif
        #endif
    }
    else
    {
        for (const auto& l : loggers) {
            l->AssertMsg(cond, msg, file, line, func);
        }
    }
    lock.UnlockRead();
}

} // namespace Core
} // namespace Oryol
<|endoftext|>


<commit_before>/*
	Copyright (C) 2003-2013 by Kristina Simpson <sweet.kristas@gmail.com>

	This software is provided 'as-is', without any express or implied
	warranty. In no event will the authors be held liable for any damages
	arising from the use of this software.

	Permission is granted to anyone to use this software for any purpose,
	including commercial applications, and to alter it and redistribute it
	freely, subject to the following restrictions:

	   1. The origin of this software must not be misrepresented; you must not
	   claim that you wrote the original software. If you use this software
	   in a product, an acknowledgment in the product documentation would be
	   appreciated but is not required.

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

	   3. This notice may not be removed or altered from any source
	   distribution.
*/

#include <sstream>

#include "asserts.hpp"
#include "css_parser.hpp"
#include "xhtml_text_node.hpp"

namespace xhtml
{
	namespace {
		struct DocumentImpl : public Document
		{
			DocumentImpl(css::StyleSheetPtr ss) : Document(ss) {}
		};

		struct DocumentFragmentImpl : public DocumentFragment
		{
			DocumentFragmentImpl(WeakDocumentPtr owner) : DocumentFragment(owner) {}
		};

		struct AttributeImpl : public Attribute
		{
			AttributeImpl(const std::string& name, const std::string& value, WeakDocumentPtr owner) : Attribute(name, value, owner) {}
		};
	}

	Node::Node(NodeId id, WeakDocumentPtr owner)
		: id_(id),
		  children_(),
		  attributes_(),
		  left_(),
		  right_(),
		  parent_(),
		  owner_document_(owner),
		  properties_()
	{
	}

	Node::~Node()
	{
	}

	void Node::addChild(NodePtr child)
	{
		if(child->id() == NodeId::DOCUMENT_FRAGMENT) {
			// we add the children of a document fragment rather than the node itself.
			if(children_.empty()) {
				children_ = child->children_;
				for(auto& c : children_) {
					c->setParent(shared_from_this());
				}
			} else {
				if(!child->children_.empty()) {
					children_.back()->right_ = child->children_.front();
					child->children_.front()->left_ = children_.back();
					for(auto& c : child->children_) {
						c->setParent(shared_from_this());
					}
					children_.insert(children_.end(), child->children_.begin(), child->children_.end());
				}
			}
		} else {
			child->left_ = child->right_ = std::weak_ptr<Node>();
			if(!children_.empty()) {
				children_.back()->right_ = child;
				child->left_ = children_.back();
			}
			children_.emplace_back(child);
			child->setParent(shared_from_this());
		}
	}

	void Node::addAttribute(AttributePtr a)
	{
		a->setParent(shared_from_this());
		attributes_[a->getName()] = a;
	}

	void Node::preOrderTraversal(std::function<bool(NodePtr)> fn)
	{
		// Visit node, visit children.
		if(!fn(shared_from_this())) {
			return;
		}
		for(auto& c : children_) {
			c->preOrderTraversal(fn);
		}
	}

	void Node::postOrderTraversal(std::function<bool(NodePtr)> fn)
	{
		// Visit children, then this process node.
		for(auto& c : children_) {
			c->preOrderTraversal(fn);
		}
		if(!fn(shared_from_this())) {
			return;
		}
	}

	AttributePtr Node::getAttribute(const std::string& name)
	{
		auto it = attributes_.find(name);
		return it != attributes_.end() ? it->second : nullptr;
	}

	std::string Node::nodeToString() const
	{
		std::ostringstream ss;
		for(auto& a : getAttributes()) {
			ss << "{" << a.second->toString() << "}";
		}
		return ss.str();
	}

	const std::string& Node::getValue() const
	{
		static std::string null_str;
		return null_str;
	}

	void Node::normalize()
	{
		std::vector<NodePtr> new_child_list;
		TextPtr new_text_node;
		for(auto& c : children_) {
			if(c->id() == NodeId::TEXT) {
				if(!c->getValue().empty()) {
					if(new_text_node) {
						new_text_node->addText(c->getValue());
					} else {
						new_text_node = Text::create(c->getValue(), owner_document_);
					}
				}
			} else {
				if(new_text_node) {
					new_child_list.emplace_back(new_text_node);
					new_text_node.reset();
				}
				new_child_list.emplace_back(c);
			}
		}
		if(new_text_node != nullptr) {
			new_child_list.emplace_back(new_text_node);
		}
		children_ = new_child_list;
		for(auto& c : children_) {
			c->normalize();
		}
	}

	void Node::processWhitespace()
	{
		css::CssWhitespace ws = getStyle("whitespace").getValue<css::CssWhitespace>();
		// XXX
	}

	// Documents do not have an owner document.
	Document::Document(css::StyleSheetPtr ss)
		: Node(NodeId::DOCUMENT, WeakDocumentPtr()),
		  style_sheet_(ss == nullptr ? std::make_shared<css::StyleSheet>() : ss)
	{
	}

	void Document::processStyles()
	{
		// parse all the style nodes into the style sheet.
		auto ss = style_sheet_;
		preOrderTraversal([&ss](NodePtr n) {
			if(n->hasTag(ElementId::STYLE)) {
				for(auto& child : n->getChildren()) {
					if(child->id() == NodeId::TEXT) {
						css::Parser::parse(ss, child->getValue());
					}
				}
			}
			return true;
		});

		preOrderTraversal([&ss](NodePtr n) {
			ss->applyRulesToElement(n);
			return true;
		});

		// XXX Parse and apply specific element style rules from attributes here.
		preOrderTraversal([](NodePtr n) {
			if(n->id() == NodeId::ELEMENT) {
				auto attr = n->getAttribute("style");
				if(attr) {
					auto plist = css::Parser::parseDeclarationList(attr->getValue());
					n->mergeProperties(plist);
				}
			}
			return true;
		});

		LOG_DEBUG("STYLESHEET: " << ss->toString());
	}

	Object Node::getStyle(const std::string& name) const
	{
		auto o = properties_.getProperty(name);
		if(o.shouldInherit()) {
			auto p = getParent();
			ASSERT_LOG(p != nullptr, "css property(" << name << ") is set to inherit but the node has no parent.");
			return p->getStyle(name);
		}
		if(o.empty()) {
			ASSERT_LOG(false, "Unimplemented style was asked for '" << name <<"'");
		}
		return o;
	}

	void Node::mergeProperties(const css::PropertyList& plist)
	{
		properties_.merge(plist);
	}

	std::string Document::toString() const
	{
		std::ostringstream ss;
		ss << "Document(" << nodeToString() << ")";
		return ss.str();
	}

	DocumentPtr Document::create(css::StyleSheetPtr ss)
	{
		return std::make_shared<DocumentImpl>(ss);
	}

	DocumentFragment::DocumentFragment(WeakDocumentPtr owner)
		: Node(NodeId::DOCUMENT_FRAGMENT, owner)
	{
	}

	DocumentFragmentPtr DocumentFragment::create(WeakDocumentPtr owner)
	{
		return std::make_shared<DocumentFragmentImpl>(owner);
	}

	std::string DocumentFragment::toString() const
	{
		std::ostringstream ss;
		ss << "DocumentFragment(" << nodeToString() << ")";
		return ss.str();
	}

	Attribute::Attribute(const std::string& name, const std::string& value, WeakDocumentPtr owner)
		: Node(NodeId::ATTRIBUTE, owner),
		  name_(name),
		  value_(value)
	{
	}

	AttributePtr Attribute::create(const std::string& name, const std::string& value, WeakDocumentPtr owner)
	{
		return std::make_shared<AttributeImpl>(name, value, owner);
	}

	std::string Attribute::toString() const
	{
		std::ostringstream ss;
		ss << "Attribute('" << name_ << ":" << value_ << "'" << nodeToString() << ")";
		return ss.str();
	}
}
<commit_msg>Added handling for css from link elements.<commit_after>/*
	Copyright (C) 2003-2013 by Kristina Simpson <sweet.kristas@gmail.com>

	This software is provided 'as-is', without any express or implied
	warranty. In no event will the authors be held liable for any damages
	arising from the use of this software.

	Permission is granted to anyone to use this software for any purpose,
	including commercial applications, and to alter it and redistribute it
	freely, subject to the following restrictions:

	   1. The origin of this software must not be misrepresented; you must not
	   claim that you wrote the original software. If you use this software
	   in a product, an acknowledgment in the product documentation would be
	   appreciated but is not required.

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

	   3. This notice may not be removed or altered from any source
	   distribution.
*/

#include <sstream>

#include "asserts.hpp"
#include "css_parser.hpp"
#include "xhtml_text_node.hpp"

#include "filesystem.hpp"

namespace xhtml
{
	namespace {
		struct DocumentImpl : public Document
		{
			DocumentImpl(css::StyleSheetPtr ss) : Document(ss) {}
		};

		struct DocumentFragmentImpl : public DocumentFragment
		{
			DocumentFragmentImpl(WeakDocumentPtr owner) : DocumentFragment(owner) {}
		};

		struct AttributeImpl : public Attribute
		{
			AttributeImpl(const std::string& name, const std::string& value, WeakDocumentPtr owner) : Attribute(name, value, owner) {}
		};
	}

	Node::Node(NodeId id, WeakDocumentPtr owner)
		: id_(id),
		  children_(),
		  attributes_(),
		  left_(),
		  right_(),
		  parent_(),
		  owner_document_(owner),
		  properties_()
	{
	}

	Node::~Node()
	{
	}

	void Node::addChild(NodePtr child)
	{
		if(child->id() == NodeId::DOCUMENT_FRAGMENT) {
			// we add the children of a document fragment rather than the node itself.
			if(children_.empty()) {
				children_ = child->children_;
				for(auto& c : children_) {
					c->setParent(shared_from_this());
				}
			} else {
				if(!child->children_.empty()) {
					children_.back()->right_ = child->children_.front();
					child->children_.front()->left_ = children_.back();
					for(auto& c : child->children_) {
						c->setParent(shared_from_this());
					}
					children_.insert(children_.end(), child->children_.begin(), child->children_.end());
				}
			}
		} else {
			child->left_ = child->right_ = std::weak_ptr<Node>();
			if(!children_.empty()) {
				children_.back()->right_ = child;
				child->left_ = children_.back();
			}
			children_.emplace_back(child);
			child->setParent(shared_from_this());
		}
	}

	void Node::addAttribute(AttributePtr a)
	{
		a->setParent(shared_from_this());
		attributes_[a->getName()] = a;
	}

	void Node::preOrderTraversal(std::function<bool(NodePtr)> fn)
	{
		// Visit node, visit children.
		if(!fn(shared_from_this())) {
			return;
		}
		for(auto& c : children_) {
			c->preOrderTraversal(fn);
		}
	}

	void Node::postOrderTraversal(std::function<bool(NodePtr)> fn)
	{
		// Visit children, then this process node.
		for(auto& c : children_) {
			c->preOrderTraversal(fn);
		}
		if(!fn(shared_from_this())) {
			return;
		}
	}

	AttributePtr Node::getAttribute(const std::string& name)
	{
		auto it = attributes_.find(name);
		return it != attributes_.end() ? it->second : nullptr;
	}

	std::string Node::nodeToString() const
	{
		std::ostringstream ss;
		for(auto& a : getAttributes()) {
			ss << "{" << a.second->toString() << "}";
		}
		return ss.str();
	}

	const std::string& Node::getValue() const
	{
		static std::string null_str;
		return null_str;
	}

	void Node::normalize()
	{
		std::vector<NodePtr> new_child_list;
		TextPtr new_text_node;
		for(auto& c : children_) {
			if(c->id() == NodeId::TEXT) {
				if(!c->getValue().empty()) {
					if(new_text_node) {
						new_text_node->addText(c->getValue());
					} else {
						new_text_node = Text::create(c->getValue(), owner_document_);
					}
				}
			} else {
				if(new_text_node) {
					new_child_list.emplace_back(new_text_node);
					new_text_node.reset();
				}
				new_child_list.emplace_back(c);
			}
		}
		if(new_text_node != nullptr) {
			new_child_list.emplace_back(new_text_node);
		}
		children_ = new_child_list;
		for(auto& c : children_) {
			c->normalize();
		}
	}

	void Node::processWhitespace()
	{
		css::CssWhitespace ws = getStyle("whitespace").getValue<css::CssWhitespace>();
		// XXX
	}

	// Documents do not have an owner document.
	Document::Document(css::StyleSheetPtr ss)
		: Node(NodeId::DOCUMENT, WeakDocumentPtr()),
		  style_sheet_(ss == nullptr ? std::make_shared<css::StyleSheet>() : ss)
	{
	}

	void Document::processStyles()
	{
		// parse all the style nodes into the style sheet.
		auto ss = style_sheet_;
		preOrderTraversal([&ss](NodePtr n) {
			if(n->hasTag(ElementId::STYLE)) {
				for(auto& child : n->getChildren()) {
					if(child->id() == NodeId::TEXT) {
						css::Parser::parse(ss, child->getValue());
					}
				}
			}
			if(n->hasTag(ElementId::LINK)) {
				auto rel = n->getAttribute("rel");
				auto href = n->getAttribute("href");
				auto type = n->getAttribute("type");		// expect "type/css"
				//auto media = n->getAttribute("media");	// expect "display" or nullptr
				if(rel && rel->getValue() == "stylesheet") {
					if(href == nullptr) {
						LOG_ERROR("There was no 'href' in the LINK element.");
					} else {
						//auto css_file = get_uri(href->getValue);
						auto css_file = sys::read_file("../data/" + href->getValue());
						css::Parser::parse(ss, css_file);
					}
				}
			}
			return true;
		});

		preOrderTraversal([&ss](NodePtr n) {
			ss->applyRulesToElement(n);
			return true;
		});

		// XXX Parse and apply specific element style rules from attributes here.
		preOrderTraversal([](NodePtr n) {
			if(n->id() == NodeId::ELEMENT) {
				auto attr = n->getAttribute("style");
				if(attr) {
					auto plist = css::Parser::parseDeclarationList(attr->getValue());
					n->mergeProperties(plist);
				}
			}
			return true;
		});

		LOG_DEBUG("STYLESHEET: " << ss->toString());
	}

	Object Node::getStyle(const std::string& name) const
	{
		auto o = properties_.getProperty(name);
		if(o.shouldInherit()) {
			auto p = getParent();
			ASSERT_LOG(p != nullptr, "css property(" << name << ") is set to inherit but the node has no parent.");
			return p->getStyle(name);
		}
		if(o.empty()) {
			ASSERT_LOG(false, "Unimplemented style was asked for '" << name <<"'");
		}
		return o;
	}

	void Node::mergeProperties(const css::PropertyList& plist)
	{
		properties_.merge(plist);
	}

	std::string Document::toString() const
	{
		std::ostringstream ss;
		ss << "Document(" << nodeToString() << ")";
		return ss.str();
	}

	DocumentPtr Document::create(css::StyleSheetPtr ss)
	{
		return std::make_shared<DocumentImpl>(ss);
	}

	DocumentFragment::DocumentFragment(WeakDocumentPtr owner)
		: Node(NodeId::DOCUMENT_FRAGMENT, owner)
	{
	}

	DocumentFragmentPtr DocumentFragment::create(WeakDocumentPtr owner)
	{
		return std::make_shared<DocumentFragmentImpl>(owner);
	}

	std::string DocumentFragment::toString() const
	{
		std::ostringstream ss;
		ss << "DocumentFragment(" << nodeToString() << ")";
		return ss.str();
	}

	Attribute::Attribute(const std::string& name, const std::string& value, WeakDocumentPtr owner)
		: Node(NodeId::ATTRIBUTE, owner),
		  name_(name),
		  value_(value)
	{
	}

	AttributePtr Attribute::create(const std::string& name, const std::string& value, WeakDocumentPtr owner)
	{
		return std::make_shared<AttributeImpl>(name, value, owner);
	}

	std::string Attribute::toString() const
	{
		std::ostringstream ss;
		ss << "Attribute('" << name_ << ":" << value_ << "'" << nodeToString() << ")";
		return ss.str();
	}
}
<|endoftext|>