<commit_before>#ifndef ___INANITY_SCRIPT_V8_VALUES_IPP___
#define ___INANITY_SCRIPT_V8_VALUES_IPP___

#include "values.hpp"
#include "../../String.hpp"
#include "../../Exception.hpp"

BEGIN_INANITY_V8

template <>
struct Value<bool>
{
	typedef bool ValueType;

	static inline bool From(v8::Local<v8::Value> value)
	{
		return value->BooleanValue();
	}

	static inline v8::Local<v8::Value> To(bool value)
	{
		return v8::BooleanObject::New(value);
	}
};

template <>
struct Value<int>
{
	typedef int ValueType;

	static inline int From(v8::Local<v8::Value> value)
	{
		return value->Int32Value();
	}

	static inline v8::Local<v8::Value> To(int value)
	{
		return v8::NumberObject::New((double)value);
	}
};

template <>
struct Value<double>
{
	typedef double ValueType;

	static inline double From(v8::Local<v8::Value> value)
	{
		return value->NumberValue();
	}

	static inline v8::Local<v8::Value> To(double value)
	{
		return v8::NumberObject::New(value);
	}
};

template <>
struct Value<float>
{
	typedef float ValueType;

	static inline float From(v8::Local<v8::Value> value)
	{
		return (float)value->NumberValue();
	}

	static inline v8::Local<v8::Value> To(float value)
	{
		return v8::NumberObject::New((double)value);
	}
};

template <>
struct Value<unsigned int>
{
	typedef unsigned int ValueType;

	static inline unsigned int From(v8::Local<v8::Value> value)
	{
		return value->Uint32Value();
	}

	static inline v8::Local<v8::Value> To(unsigned int value)
	{
		return v8::NumberObject::New((double)value);
	}
};

template <>
struct Value<long long>
{
	typedef long long ValueType;

	static inline long long From(v8::Local<v8::Value> value)
	{
		return value->IntegerValue();
	}

	static inline v8::Local<v8::Value> To(long long value)
	{
		return v8::NumberObject::New((double)value);
	}
};

template <>
struct Value<unsigned long long>
{
	typedef unsigned long long ValueType;

	static inline unsigned long long From(v8::Local<v8::Value> value)
	{
		return value->IntegerValue();
	}

	static inline v8::Local<v8::Value> To(unsigned long long value)
	{
		return v8::NumberObject::New((double)value);
	}
};

template <>
struct Value<const char*>
{
	typedef String ValueType;

	static inline String From(v8::Local<v8::Value> value)
	{
		v8::String::Utf8Value s(value);
		return String(*s, s.length());
	}

	static inline v8::Local<v8::Value> To(const char* value)
	{
		return v8::String::New(value);
	}
};

template <>
struct Value<String>
{
	typedef String ValueType;

	static inline String From(v8::Local<v8::Value> value)
	{
		v8::String::Utf8Value s(value);
		return String(*s, s.length());
	}

	static inline v8::Local<v8::Value> To(const String& value)
	{
		return v8::String::New(value.c_str(), (int)value.length());
	}
};

template <>
struct Value<const String&>
{
	typedef String ValueType;

	static inline String From(v8::Local<v8::Value> value)
	{
		v8::String::Utf8Value s(value);
		return String(*s, s.length());
	}
};

/*
ptr<RefCounted> is represented as an External, or as null (zero pointer).
External of corrent object contains non-null pointer.
External with null pointer is a wiped object, i.e. object which was
reclamed from script by C++ code.
Other values are not accepted (i.e. zero, undefined).
*/
template <typename ObjectType>
struct Value<ptr<ObjectType> >
{
	typedef ptr<ObjectType> ValueType;

	static inline ptr<ObjectType> From(v8::Local<v8::Value> value)
	{
		// get internal field of an object
		v8::Local<v8::Value> thisValue = value->ToObject()->GetInternalField(0);

		// if it's null object
		if(thisValue->IsNull())
			return 0;

		// otherwise it should be an external
		if(!thisValue->IsExternal())
		{
			v8::String::Utf8Value s(thisValue);
			const char* classFullName = Meta::MetaOf<MetaProvider, ObjectType>()->GetFullName();
			THROW(classFullName + String(" instance can't be obtained from ") + *s);
		}

		// get the value
		void* externalValue = v8::External::Cast(*thisValue)->Value();

		// if the value is null, the object was reclaimed
		if(!externalValue)
		{
			const char* classFullName = Meta::MetaOf<MetaProvider, ObjectType>()->GetFullName();
			THROW(classFullName + String(" instance was reclaimed"));
		}

		ObjectType* object = fast_cast<ObjectType*>((RefCounted*)externalValue);

		return object;
	}

	static inline v8::Local<v8::Value> To(ptr<ObjectType> value)
	{
		if(value)
			return State::GetCurrent()->ConvertObject(Meta::MetaOf<MetaProvider, ObjectType>(), static_cast<RefCounted*>(&*value));
		else
			return v8::Null();
	}
};

template <typename T>
struct Value
{
	typedef T ValueType;

	static inline T From(v8::Local<v8::Value> value)
	{
		return Meta::ConverterFromScript<MetaProvider, T>::Convert(MetaProvider::Any(value));
	}
};

template <typename T>
struct Value<const T&>
{
	typedef T ValueType;

	static inline T From(v8::Local<v8::Value> value)
	{
		return Meta::ConverterFromScript<MetaProvider, T>::Convert(MetaProvider::Any(value));
	}
};

END_INANITY_V8

#endif
<commit_msg>add missing include<commit_after>#ifndef ___INANITY_SCRIPT_V8_VALUES_IPP___
#define ___INANITY_SCRIPT_V8_VALUES_IPP___

#include "values.hpp"
#include "State.hpp"
#include "../../String.hpp"
#include "../../Exception.hpp"

BEGIN_INANITY_V8

template <>
struct Value<bool>
{
	typedef bool ValueType;

	static inline bool From(v8::Local<v8::Value> value)
	{
		return value->BooleanValue();
	}

	static inline v8::Local<v8::Value> To(bool value)
	{
		return v8::BooleanObject::New(value);
	}
};

template <>
struct Value<int>
{
	typedef int ValueType;

	static inline int From(v8::Local<v8::Value> value)
	{
		return value->Int32Value();
	}

	static inline v8::Local<v8::Value> To(int value)
	{
		return v8::NumberObject::New((double)value);
	}
};

template <>
struct Value<double>
{
	typedef double ValueType;

	static inline double From(v8::Local<v8::Value> value)
	{
		return value->NumberValue();
	}

	static inline v8::Local<v8::Value> To(double value)
	{
		return v8::NumberObject::New(value);
	}
};

template <>
struct Value<float>
{
	typedef float ValueType;

	static inline float From(v8::Local<v8::Value> value)
	{
		return (float)value->NumberValue();
	}

	static inline v8::Local<v8::Value> To(float value)
	{
		return v8::NumberObject::New((double)value);
	}
};

template <>
struct Value<unsigned int>
{
	typedef unsigned int ValueType;

	static inline unsigned int From(v8::Local<v8::Value> value)
	{
		return value->Uint32Value();
	}

	static inline v8::Local<v8::Value> To(unsigned int value)
	{
		return v8::NumberObject::New((double)value);
	}
};

template <>
struct Value<long long>
{
	typedef long long ValueType;

	static inline long long From(v8::Local<v8::Value> value)
	{
		return value->IntegerValue();
	}

	static inline v8::Local<v8::Value> To(long long value)
	{
		return v8::NumberObject::New((double)value);
	}
};

template <>
struct Value<unsigned long long>
{
	typedef unsigned long long ValueType;

	static inline unsigned long long From(v8::Local<v8::Value> value)
	{
		return value->IntegerValue();
	}

	static inline v8::Local<v8::Value> To(unsigned long long value)
	{
		return v8::NumberObject::New((double)value);
	}
};

template <>
struct Value<const char*>
{
	typedef String ValueType;

	static inline String From(v8::Local<v8::Value> value)
	{
		v8::String::Utf8Value s(value);
		return String(*s, s.length());
	}

	static inline v8::Local<v8::Value> To(const char* value)
	{
		return v8::String::New(value);
	}
};

template <>
struct Value<String>
{
	typedef String ValueType;

	static inline String From(v8::Local<v8::Value> value)
	{
		v8::String::Utf8Value s(value);
		return String(*s, s.length());
	}

	static inline v8::Local<v8::Value> To(const String& value)
	{
		return v8::String::New(value.c_str(), (int)value.length());
	}
};

template <>
struct Value<const String&>
{
	typedef String ValueType;

	static inline String From(v8::Local<v8::Value> value)
	{
		v8::String::Utf8Value s(value);
		return String(*s, s.length());
	}
};

/*
ptr<RefCounted> is represented as an External, or as null (zero pointer).
External of corrent object contains non-null pointer.
External with null pointer is a wiped object, i.e. object which was
reclamed from script by C++ code.
Other values are not accepted (i.e. zero, undefined).
*/
template <typename ObjectType>
struct Value<ptr<ObjectType> >
{
	typedef ptr<ObjectType> ValueType;

	static inline ptr<ObjectType> From(v8::Local<v8::Value> value)
	{
		// get internal field of an object
		v8::Local<v8::Value> thisValue = value->ToObject()->GetInternalField(0);

		// if it's null object
		if(thisValue->IsNull())
			return 0;

		// otherwise it should be an external
		if(!thisValue->IsExternal())
		{
			v8::String::Utf8Value s(thisValue);
			const char* classFullName = Meta::MetaOf<MetaProvider, ObjectType>()->GetFullName();
			THROW(classFullName + String(" instance can't be obtained from ") + *s);
		}

		// get the value
		void* externalValue = v8::External::Cast(*thisValue)->Value();

		// if the value is null, the object was reclaimed
		if(!externalValue)
		{
			const char* classFullName = Meta::MetaOf<MetaProvider, ObjectType>()->GetFullName();
			THROW(classFullName + String(" instance was reclaimed"));
		}

		ObjectType* object = fast_cast<ObjectType*>((RefCounted*)externalValue);

		return object;
	}

	static inline v8::Local<v8::Value> To(ptr<ObjectType> value)
	{
		if(value)
			return State::GetCurrent()->ConvertObject(Meta::MetaOf<MetaProvider, ObjectType>(), static_cast<RefCounted*>(&*value));
		else
			return v8::Null();
	}
};

template <typename T>
struct Value
{
	typedef T ValueType;

	static inline T From(v8::Local<v8::Value> value)
	{
		return Meta::ConverterFromScript<MetaProvider, T>::Convert(MetaProvider::Any(value));
	}
};

template <typename T>
struct Value<const T&>
{
	typedef T ValueType;

	static inline T From(v8::Local<v8::Value> value)
	{
		return Meta::ConverterFromScript<MetaProvider, T>::Convert(MetaProvider::Any(value));
	}
};

END_INANITY_V8

#endif
<|endoftext|>


<commit_before>/*
 * An implementation of a string range match counting algorithm in O(n+m) time
 * and O(log(m)) extra space based on an exact string matching algorithm by
 * Galil and Seiferas. Originally published in:
 *
 * J. Kärkkäinen, D. Kempa, S. Puglisi: String Range Matching.
 * Proceedings of the 25th Symposium on Combinatorial Pattern
 * Matching (CPM), pp. 232-241, 2014.
 * http://dx.doi.org/10.1007/978-3-319-07566-2_24
 *
 * Copyright (c) 2015 Jarno Leppänen
 */

#ifndef GS_COUNT_HPP
#define GS_COUNT_HPP

#include "gs_count_detail.hpp"

namespace rmatch {
namespace detail {

/* Find O(log(m)) scopes of the k-hrps of a string. This is the
   'PreCompute'-algorithm listed in Fig. 2 of the original paper. */
template <typename string_type, typename index_type>
s_t<index_type> gs_precompute(string_type y, index_type m, index_type k)
{
    using namespace std;
    s_t<index_type> s;
    add(s.n,index_type(1),index_type(0));
    index_type i = 1, last = 1, l = 0, count = 0;
    while (i < m) { // Invariant: count = |y_[0..i) ∩ [ɛ,y)|
        while (i+l < m && y[i+l] == y[l]) ++l;
        index_type b, e, c;
        contains(s.p,l,b,e,c);
        if (k*i <= i+l && b == 0) {
            b = 2*i; e = i+l+1; c = count;
            add(s.p,b,e,c); // y[0..i) is a new k-hrp
        }
        if (2*last <= i) {
            add(s.n,i,count);
            last = i;
        }
        if (i+l == m || y[i+l] < y[l]) ++count;
        if (b != 0) {
            count += c;
            i += b/2;
            l -= b/2;
        } else {
            pred(s.n,l/k+1,b,c);
            count += c;
            i += b;
            l = 0;
        }
    }
    return s;
}

} // detail

/**
 * Calculate the number of suffixes in a text that are lexicographically smaller
 * than a given pattern in linear time and O(log(m)) extra space.
 *
 * @param x Input text. (random access iterator)
 * @param n Length of the input text.
 * @param y Input pattern. (random access iterator)
 * @param m Length of the input pattern.
 * @param k Constant k used in calculating the k-hrps of the pattern. This
 * should be larger or equal to 3.
 * @return Number of matching suffixes in the text.
 */
template <typename string_type, typename index_type>
index_type gs_count_less(
        string_type x, index_type n,
        string_type y, index_type m,
        index_type k)
{
    using namespace std;
    using namespace rmatch::detail;
    s_t<index_type> s = gs_precompute(y,m,k);
    index_type count = 0, i = 0, l = 0;
    while (i < n) { // Invariant: count = |x_[0..i) ∩ [ɛ,y)|
        while (i+l < n && l < m && x[i+l] == y[l]) ++l;
        index_type b, e, c;
        contains(s.p,l,b,e,c);
        if (l < m && (i+l == n || x[i+l] < y[l])) ++count;
        if (b != 0) { // per(y[0..l)) = b/2
            // c = |Y_[1..b/2) ∩ [ɛ,y)| = |x_[i+1..i+b/2) ∩ [ɛ,y)|
            count += c;
            i += b/2;
            l -= b/2;
        } else { // per(y[0..l)) > l/k
            pred(s.n,l/k+1,b,c); // (⌊l/k⌋+1)/4 < b
            // c = |Y_[1..b) ∩ [ɛ,y)| = |x_[i+1..i+b) ∩ [ɛ,y)|
            count += c;
            i += b;
            l = 0;
        }
    }
    return count;
}

/**
 * Calculate the number of suffixes in a text x that are lexicographically
 * larger or equal to pattern b and smaller than pattern e; i.e. b <= x < e.
 *
 * @param x Input text. (random access iterator)
 * @param n Size of the input text.
 * @param b Lower bound pattern. (random access iterator)
 * @param m1 Size of the lower bound pattern.
 * @param e Upper bound pattern. (random access iterator)
 * @param m2 Size of the upper bound pattern.
 * @param k Constant k used in calculating the k-hrps of the patterns. This
 * should be larger or equal to 3.
 * @return Number of matching suffixes in the text.
 */
template <typename string_type, typename index_type>
index_type gs_count_range(
        string_type x, index_type n,
        string_type b, index_type m1,
        string_type e, index_type m2,
        index_type k)
{
    return
        gs_count_less(x,n,e,m2,k)-
        gs_count_less(x,n,b,m1,k);
}

/**
 * Calculate the number of suffixes in a text x that are lexicographically
 * larger or equal to pattern b and smaller than pattern e; i.e. b <= x < e.
 *
 * @param x Input text. (random access container)
 * @param b The lower bound pattern. (random access container)
 * @param e The upper bound pattern. (random access container)
 * @param k Constant k used in calculating the k-hrps of the patterns. This
 * should be larger or equal to 3.
 * @return Number of matching suffixes in the text.
 */
template <typename string_type>
typename string_type::size_type gs_count_range(
        const string_type& x,
        const string_type& b,
        const string_type& e,
        typename string_type::size_type k)
{
    return gs_count_range(
            x.begin(),x.size(),
            b.begin(),b.size(),
            e.begin(),e.size(),
            k);
}

} // rmatch

#endif // GS_COUNT_HPP
<commit_msg>Fix u < l for gs_count<commit_after>/*
 * An implementation of a string range match counting algorithm in O(n+m) time
 * and O(log(m)) extra space based on an exact string matching algorithm by
 * Galil and Seiferas. Originally published in:
 *
 * J. Kärkkäinen, D. Kempa, S. Puglisi: String Range Matching.
 * Proceedings of the 25th Symposium on Combinatorial Pattern
 * Matching (CPM), pp. 232-241, 2014.
 * http://dx.doi.org/10.1007/978-3-319-07566-2_24
 *
 * Copyright (c) 2015 Jarno Leppänen
 */

#ifndef GS_COUNT_HPP
#define GS_COUNT_HPP

#include "gs_count_detail.hpp"

namespace rmatch {
namespace detail {

/* Find O(log(m)) scopes of the k-hrps of a string. This is the
   'PreCompute'-algorithm listed in Fig. 2 of the original paper. */
template <typename string_type, typename index_type>
s_t<index_type> gs_precompute(string_type y, index_type m, index_type k)
{
    using namespace std;
    s_t<index_type> s;
    add(s.n,index_type(1),index_type(0));
    index_type i = 1, last = 1, l = 0, count = 0;
    while (i < m) { // Invariant: count = |y_[0..i) ∩ [ɛ,y)|
        while (i+l < m && y[i+l] == y[l]) ++l;
        index_type b, e, c;
        contains(s.p,l,b,e,c);
        if (k*i <= i+l && b == 0) {
            b = 2*i; e = i+l+1; c = count;
            add(s.p,b,e,c); // y[0..i) is a new k-hrp
        }
        if (2*last <= i) {
            add(s.n,i,count);
            last = i;
        }
        if (i+l == m || y[i+l] < y[l]) ++count;
        if (b != 0) {
            count += c;
            i += b/2;
            l -= b/2;
        } else {
            pred(s.n,l/k+1,b,c);
            count += c;
            i += b;
            l = 0;
        }
    }
    return s;
}

} // detail

/**
 * Calculate the number of suffixes in a text that are lexicographically smaller
 * than a given pattern in linear time and O(log(m)) extra space.
 *
 * @param x Input text. (random access iterator)
 * @param n Length of the input text.
 * @param y Input pattern. (random access iterator)
 * @param m Length of the input pattern.
 * @param k Constant k used in calculating the k-hrps of the pattern. This
 * should be larger or equal to 3.
 * @return Number of matching suffixes in the text.
 */
template <typename string_type, typename index_type>
index_type gs_count_less(
        string_type x, index_type n,
        string_type y, index_type m,
        index_type k)
{
    using namespace std;
    using namespace rmatch::detail;
    s_t<index_type> s = gs_precompute(y,m,k);
    index_type count = 0, i = 0, l = 0;
    while (i < n) { // Invariant: count = |x_[0..i) ∩ [ɛ,y)|
        while (i+l < n && l < m && x[i+l] == y[l]) ++l;
        index_type b, e, c;
        contains(s.p,l,b,e,c);
        if (l < m && (i+l == n || x[i+l] < y[l])) ++count;
        if (b != 0) { // per(y[0..l)) = b/2
            // c = |Y_[1..b/2) ∩ [ɛ,y)| = |x_[i+1..i+b/2) ∩ [ɛ,y)|
            count += c;
            i += b/2;
            l -= b/2;
        } else { // per(y[0..l)) > l/k
            pred(s.n,l/k+1,b,c); // (⌊l/k⌋+1)/4 < b
            // c = |Y_[1..b) ∩ [ɛ,y)| = |x_[i+1..i+b) ∩ [ɛ,y)|
            count += c;
            i += b;
            l = 0;
        }
    }
    return count;
}

/**
 * Calculate the number of suffixes in a text x that are lexicographically
 * larger or equal to pattern b and smaller than pattern e; i.e. b <= x < e.
 *
 * @param x Input text. (random access iterator)
 * @param n Size of the input text.
 * @param b Lower bound pattern. (random access iterator)
 * @param m1 Size of the lower bound pattern.
 * @param e Upper bound pattern. (random access iterator)
 * @param m2 Size of the upper bound pattern.
 * @param k Constant k used in calculating the k-hrps of the patterns. This
 * should be larger or equal to 3.
 * @return Number of matching suffixes in the text.
 */
template <typename string_type, typename index_type>
index_type gs_count_range(
        string_type x, index_type n,
        string_type b, index_type m1,
        string_type e, index_type m2,
        index_type k)
{
    index_type l = gs_count_less(x,n,b,m1,k);
    index_type u = gs_count_less(x,n,e,m2,k);
    return u < l ? 0 : u - l;
}

/**
 * Calculate the number of suffixes in a text x that are lexicographically
 * larger or equal to pattern b and smaller than pattern e; i.e. b <= x < e.
 *
 * @param x Input text. (random access container)
 * @param b The lower bound pattern. (random access container)
 * @param e The upper bound pattern. (random access container)
 * @param k Constant k used in calculating the k-hrps of the patterns. This
 * should be larger or equal to 3.
 * @return Number of matching suffixes in the text.
 */
template <typename string_type>
typename string_type::size_type gs_count_range(
        const string_type& x,
        const string_type& b,
        const string_type& e,
        typename string_type::size_type k)
{
    return gs_count_range(
            x.begin(),x.size(),
            b.begin(),b.size(),
            e.begin(),e.size(),
            k);
}

} // rmatch

#endif // GS_COUNT_HPP
<|endoftext|>


<commit_before>#include "Image.h"

using namespace iml;

bool Image::loadpng(const std::string &filename) {
  // Open the file. libpng expects C file handle.
  FILE *fp = fopen(filename.c_str(), "rb");
  if (!fp) {
    std::cerr << "Couldn't open image file." << std::endl;
    return false;
  }

  // Handles for settings for reading
  png_structp pngp =
      png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
  if (!pngp) {
    std::cerr << "Couldn't create png struct" << std::endl;
    fclose(fp);
    return false;
  }

  png_infop pngi = png_create_info_struct(pngp);
  if (!pngi) {
    std::cerr << "Couldn't create png/info struct" << std::endl;
    png_destroy_read_struct(&pngp, (png_infopp)0, (png_infopp)0);
    fclose(fp);
    return false;
  }

  png_infop pngend = png_create_info_struct(pngp);
  if (!pngp || !pngi) {
    std::cerr << "Couldn't create png/info struct" << std::endl;
    png_destroy_read_struct(&pngp, &pngi, (png_infopp)0);
    fclose(fp);
    return false;
  }

  if (setjmp(png_jmpbuf(pngp))) {
    png_destroy_read_struct(&pngp, &pngi, &pngend);
    fclose(fp);
    return false;
  }

  // Associate with the file
  png_init_io(pngp, fp);

  // Start reading the info at the start of the file (height, width, etc)
  png_read_info(pngp, pngi);

  // Get the info we need
  _height = png_get_image_height(pngp, pngi);
  _width = png_get_image_width(pngp, pngi);
  if (_height <= 0 || _width <= 0) {
    std::cerr << "Found no image data, zero dimension" << std::endl;
    png_destroy_read_struct(&pngp, &pngi, &pngend);
    fclose(fp);
    return false;
  }

  // Try to expand to rgba.
  int bit_depth = png_get_bit_depth(pngp, pngi);
  int color_type = png_get_color_type(pngp, pngi);
  int channels = png_get_channels(pngp, pngi);
  if (color_type == PNG_COLOR_TYPE_PALETTE) {
    png_set_palette_to_rgb(pngp);
  }
  if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) {
    png_set_expand_gray_1_2_4_to_8(pngp);
  }
  if (png_get_valid(pngp, pngi, PNG_INFO_tRNS)) {
    png_set_tRNS_to_alpha(pngp);
  }
  if (color_type == PNG_COLOR_TYPE_RGB) {
    png_set_filler(pngp, 255, PNG_FILLER_BEFORE);
  }
  if (bit_depth == 16) {
    png_set_strip_16(pngp);
  }

  // Get length of row for allocation, allocate
  int rowbytes = png_get_rowbytes(pngp, pngi);
  unsigned char **row_pointers = new unsigned char *[_height];
  data = new unsigned char[rowbytes * _height];

  // Have row_pointers point into data sequentially, read into data
  for (size_t i = 0; i < _height; ++i) {
    row_pointers[i] = data + i * rowbytes;
  }
  png_read_image(pngp, row_pointers);
  delete[] row_pointers;

  png_read_end(pngp, pngend);

  // Cleanup
  png_destroy_read_struct(&pngp, &pngi, &pngend);
  fclose(fp);

  // Try again to get 8bit RGBA if we were unsuccessful.
  // Should now atleast be 8bit each, not palette.
  if (channels == 1 || channels == 3) {
    unsigned char *tmp = data;
    data = new unsigned char[_width * _height * 4];
    if (channels == 1) {
      std::cerr << "G -> RGBA performed" << std::endl;
      for (size_t i = 0; i < _width * _height; ++i) {
        data[i * 4 + 0] = tmp[i];
        data[i * 4 + 1] = tmp[i];
        data[i * 4 + 2] = tmp[i];
        data[i * 4 + 3] = 255;
      }
    } else if (channels == 3) {
      std::cerr << "RGB -> RGBA performed" << std::endl;
      auto *in = tmp;
      auto *out = data;
      while (in != tmp + _height * _width * 3) {
        out[0] = in[0];
        out[1] = in[1];
        out[2] = in[2];
        out[3] = 255;
        in += 3;
        out += 4;
      }
    }
    delete tmp;
  }

  return true;
}

Image::Image(const std::string &filename) {
  auto pos = filename.rfind(".png");
  if (pos == filename.length() - 4) {
    ok = loadpng(filename);
    return;
  }
}

Image::Image(size_t width, size_t height) : _width(width), _height(height) {
  data = new unsigned char[width * height * 4];
}

bool iml::writepng(const std::string &filename, Image *img) {
  return writepng(filename, img->width(), img->height(), img->data);
}

bool iml::writepng(const std::string &filename, size_t width, size_t height,
                   unsigned char *data) {
  FILE *fp = fopen(filename.c_str(), "wb");
  if (!fp) {
    return false;
  }

  png_structp pngp =
      png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
  if (!pngp) {
    return false;
  }
  png_infop pngi = png_create_info_struct(pngp);
  if (!pngi) {
    png_destroy_write_struct(&pngp, (png_infopp)NULL);
    return false;
  }

  png_init_io(pngp, fp);

  png_set_IHDR(pngp, pngi, width, height, 8, PNG_COLOR_TYPE_RGB_ALPHA,
               PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE,
               PNG_FILTER_TYPE_BASE);

  png_write_info(pngp, pngi);

  // Have row_pointers point into data sequentially, write to file
  unsigned char **row_pointers = new unsigned char *[height];
  for (size_t i = 0; i < height; ++i) {
    row_pointers[i] = data + i * width * 4;
  }
  png_write_image(pngp, row_pointers);
  delete[] row_pointers;

  png_write_end(pngp, pngi);

  // Cleanup
  png_destroy_write_struct(&pngp, &pngi);

  return true;
}

Image::~Image() { delete[] data; }
<commit_msg>Solves image loading SIGSEGVs<commit_after>#include "Image.h"

using namespace iml;

bool Image::loadpng(const std::string &filename) {
  // Open the file. libpng expects C file handle.
  FILE *fp = fopen(filename.c_str(), "rb");
  if (!fp) {
    std::cerr << "Couldn't open image file." << std::endl;
    return false;
  }

  // Handles for settings for reading
  png_structp pngp =
      png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
  if (!pngp) {
    std::cerr << "Couldn't create png struct" << std::endl;
    fclose(fp);
    return false;
  }

  png_infop pngi = png_create_info_struct(pngp);
  if (!pngi) {
    std::cerr << "Couldn't create png/info struct" << std::endl;
    png_destroy_read_struct(&pngp, (png_infopp)0, (png_infopp)0);
    fclose(fp);
    return false;
  }

  png_infop pngend = png_create_info_struct(pngp);
  if (!pngp || !pngi) {
    std::cerr << "Couldn't create png/info struct" << std::endl;
    png_destroy_read_struct(&pngp, &pngi, (png_infopp)0);
    fclose(fp);
    return false;
  }

  if (setjmp(png_jmpbuf(pngp))) {
    png_destroy_read_struct(&pngp, &pngi, &pngend);
    fclose(fp);
    return false;
  }

  // Associate with the file
  png_init_io(pngp, fp);

  // Start reading the info at the start of the file (height, width, etc)
  png_read_info(pngp, pngi);

  // Get the info we need
  _height = png_get_image_height(pngp, pngi);
  _width = png_get_image_width(pngp, pngi);
  if (_height <= 0 || _width <= 0) {
    std::cerr << "Found no image data, zero dimension" << std::endl;
    png_destroy_read_struct(&pngp, &pngi, &pngend);
    fclose(fp);
    return false;
  }

  // Try to expand to rgba.
  int bit_depth = png_get_bit_depth(pngp, pngi);
  int color_type = png_get_color_type(pngp, pngi);
  int channels = png_get_channels(pngp, pngi);
  if (color_type == PNG_COLOR_TYPE_PALETTE) {
    png_set_palette_to_rgb(pngp);
  }
  if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) {
    png_set_expand_gray_1_2_4_to_8(pngp);
  }
  if (png_get_valid(pngp, pngi, PNG_INFO_tRNS)) {
    png_set_tRNS_to_alpha(pngp);
  }
  if (color_type == PNG_COLOR_TYPE_RGB) {
    png_set_filler(pngp, 255, PNG_FILLER_BEFORE);
  }
  if (bit_depth == 16) {
    png_set_strip_16(pngp);
  }

  // Update rowbytes and such with new information from transforms.
  png_read_update_info(pngp, pngi);
  channels = png_get_channels(pngp, pngi);

  // Get length of row for allocation, allocate
  int rowbytes = png_get_rowbytes(pngp, pngi);
  unsigned char **row_pointers = new unsigned char *[_height];
  data = new unsigned char[rowbytes * _height];

  // Have row_pointers point into data sequentially, read into data
  for (size_t i = 0; i < _height; ++i) {
    row_pointers[i] = data + i * rowbytes;
  }
  png_read_image(pngp, row_pointers);
  delete[] row_pointers;

  png_read_end(pngp, pngend);

  // Cleanup
  png_destroy_read_struct(&pngp, &pngi, &pngend);
  fclose(fp);

  // Try again to get 8bit RGBA if we were unsuccessful.
  // Should now atleast be 8bit each, not palette.
  if (channels == 1 || channels == 3) {
    unsigned char *tmp = data;
    data = new unsigned char[_width * _height * 4];
    if (channels == 1) {
      std::cerr << "G -> RGBA performed" << std::endl;
      for (size_t i = 0; i < _width * _height; ++i) {
        data[i * 4 + 0] = tmp[i];
        data[i * 4 + 1] = tmp[i];
        data[i * 4 + 2] = tmp[i];
        data[i * 4 + 3] = 255;
      }
    } else if (channels == 3) {
      std::cerr << "RGB -> RGBA performed" << std::endl;
      auto *in = tmp;
      auto *out = data;
      while (in != tmp + _height * _width * 3) {
        out[0] = in[0];
        out[1] = in[1];
        out[2] = in[2];
        out[3] = 255;
        in += 3;
        out += 4;
      }
    }
    delete tmp;
  }

  return true;
}

Image::Image(const std::string &filename) {
  auto pos = filename.rfind(".png");
  if (pos == filename.length() - 4) {
    ok = loadpng(filename);
    return;
  }
}

Image::Image(size_t width, size_t height) : _width(width), _height(height) {
  data = new unsigned char[width * height * 4];
}

bool iml::writepng(const std::string &filename, Image *img) {
  return writepng(filename, img->width(), img->height(), img->data);
}

bool iml::writepng(const std::string &filename, size_t width, size_t height,
                   unsigned char *data) {
  FILE *fp = fopen(filename.c_str(), "wb");
  if (!fp) {
    return false;
  }

  png_structp pngp =
      png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
  if (!pngp) {
    return false;
  }
  png_infop pngi = png_create_info_struct(pngp);
  if (!pngi) {
    png_destroy_write_struct(&pngp, (png_infopp)NULL);
    return false;
  }

  png_init_io(pngp, fp);

  png_set_IHDR(pngp, pngi, width, height, 8, PNG_COLOR_TYPE_RGB_ALPHA,
               PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE,
               PNG_FILTER_TYPE_BASE);

  png_write_info(pngp, pngi);

  // Have row_pointers point into data sequentially, write to file
  unsigned char **row_pointers = new unsigned char *[height];
  for (size_t i = 0; i < height; ++i) {
    row_pointers[i] = data + i * width * 4;
  }
  png_write_image(pngp, row_pointers);
  delete[] row_pointers;

  png_write_end(pngp, pngi);

  // Cleanup
  png_destroy_write_struct(&pngp, &pngi);

  return true;
}

Image::~Image() { delete[] data; }
<|endoftext|>


<commit_before><commit_msg>Port++<commit_after><|endoftext|>


<commit_before>#ifndef ENTT_CORE_TYPE_TRAITS_HPP
#define ENTT_CORE_TYPE_TRAITS_HPP

#include <type_traits>
#include "../core/hashed_string.hpp"

namespace entt {

/*! @brief A class to use to push around lists of types, nothing more. */
template<typename...>
struct type_list {};

/**
 * @brief Concatenates multiple type lists into one.
 * @tparam Type List of types.
 * @return The given type list.
 */
template<typename... Type>
constexpr auto type_list_cat(type_list<Type...> = type_list<>{}) {
    return type_list<Type...>{};
}

/**
 * @brief Concatenates multiple type lists into one.
 * @tparam Type List of types.
 * @tparam Other List of types.
 * @tparam List Type list instances.
 * @return A type list that is the concatenation of the given type lists.
 */
template<typename... Type, typename... Other, typename... List>
constexpr auto type_list_cat(type_list<Type...>, type_list<Other...>, List...) {
    return type_list_cat(type_list<Type..., Other...>{}, List{}...);
}

/*! @brief Traits class used mainly to push things across boundaries. */
template<typename>
struct shared_traits;

/**
 * @brief Specialization used to get rid of constness.
 * @tparam Type Shared type.
 */
template<typename Type>
struct shared_traits<const Type>
        : shared_traits<Type>
{};

/**
 * @brief Provides the member constant `value` to true if a given type is
 * shared. In all other cases, `value` is false.
 */
template<typename, typename = std::void_t<>>
struct is_shared: std::false_type {};

/**
 * @brief Provides the member constant `value` to true if a given type is
 * shared. In all other cases, `value` is false.
 * @tparam Type Potentially shared type.
 */
template<typename Type>
struct is_shared<Type, std::void_t<typename shared_traits<std::decay_t<Type>>::type>>: std::true_type {};

/**
 * @brief Helper variable template.
 *
 * True if a given type is shared, false otherwise.
 *
 * @tparam Type Potentially shared type.
 */
template<class Type>
constexpr auto is_shared_v = is_shared<Type>::value;

}

/**
 * @brief Makes an already existing type a shared type.
 * @param type Type to make shareable.
 */
#define ENTT_SHARED_TYPE(type)\
    template<>\
    struct entt::shared_traits<type>\
        : std::integral_constant<typename entt::hashed_string::hash_type, entt::hashed_string::to_value(#type)>\
    {}

/**
 * @brief Defines a type as shareable (to use for structs).
 * @param clazz Name of the type to make shareable.
 */
#define ENTT_SHARED_STRUCT(clazz)\
    struct clazz;\
    ENTT_SHARED_TYPE(clazz)\
    struct clazz

/**
 * @brief Defines a type as shareable (to use for classes).
 * @param clazz Name of the type to make shareable.
 */
#define ENTT_SHARED_CLASS(clazz)\
    class clazz;\
    ENTT_SHARED_TYPE(clazz)\
    class clazz

#endif // ENTT_CORE_TYPE_TRAITS_HPP
<commit_msg>minor changes<commit_after>#ifndef ENTT_CORE_TYPE_TRAITS_HPP
#define ENTT_CORE_TYPE_TRAITS_HPP

#include <type_traits>
#include "../core/hashed_string.hpp"

namespace entt {

/*! @brief A class to use to push around lists of types, nothing more. */
template<typename...>
struct type_list {};

/**
 * @brief Concatenates multiple type lists into one.
 * @tparam Type List of types.
 * @return The given type list.
 */
template<typename... Type>
constexpr auto type_list_cat(type_list<Type...> = type_list<>{}) {
    return type_list<Type...>{};
}

/**
 * @brief Concatenates multiple type lists into one.
 * @tparam Type List of types.
 * @tparam Other List of types.
 * @tparam List Type list instances.
 * @return A type list that is the concatenation of the given type lists.
 */
template<typename... Type, typename... Other, typename... List>
constexpr auto type_list_cat(type_list<Type...>, type_list<Other...>, List...) {
    return type_list_cat(type_list<Type..., Other...>{}, List{}...);
}

/*! @brief Traits class used mainly to push things across boundaries. */
template<typename>
struct shared_traits;

/**
 * @brief Specialization used to get rid of constness.
 * @tparam Type Shared type.
 */
template<typename Type>
struct shared_traits<const Type>
        : shared_traits<Type>
{};

/**
 * @brief Helper type.
 * @tparam Type Potentially shared type.
 */
template<typename Type>
using shared_traits_t = typename shared_traits<Type>::type;

/**
 * @brief Provides the member constant `value` to true if a given type is
 * shared. In all other cases, `value` is false.
 */
template<typename, typename = std::void_t<>>
struct is_shared: std::false_type {};

/**
 * @brief Provides the member constant `value` to true if a given type is
 * shared. In all other cases, `value` is false.
 * @tparam Type Potentially shared type.
 */
template<typename Type>
struct is_shared<Type, std::void_t<shared_traits_t<std::decay_t<Type>>>>: std::true_type {};

/**
 * @brief Helper variable template.
 *
 * True if a given type is shared, false otherwise.
 *
 * @tparam Type Potentially shared type.
 */
template<class Type>
constexpr auto is_shared_v = is_shared<Type>::value;

}

/**
 * @brief Makes an already existing type a shared type.
 * @param type Type to make shareable.
 */
#define ENTT_SHARED_TYPE(type)\
    template<>\
    struct entt::shared_traits<type>\
        : std::integral_constant<typename entt::hashed_string::hash_type, entt::hashed_string::to_value(#type)>\
    {}

/**
 * @brief Defines a type as shareable (to use for structs).
 * @param clazz Name of the type to make shareable.
 */
#define ENTT_SHARED_STRUCT(clazz)\
    struct clazz;\
    ENTT_SHARED_TYPE(clazz)\
    struct clazz

/**
 * @brief Defines a type as shareable (to use for classes).
 * @param clazz Name of the type to make shareable.
 */
#define ENTT_SHARED_CLASS(clazz)\
    class clazz;\
    ENTT_SHARED_TYPE(clazz)\
    class clazz

#endif // ENTT_CORE_TYPE_TRAITS_HPP
<|endoftext|>


<commit_before>
// (c) COPYRIGHT URI/MIT 1994-1996
// Please read the full copyright statement in the file COPYRIGH.
//
// Authors:
//      jhrg,jimg       James Gallagher (jgallagher@gso.uri.edu)

// Implementation for Int32.
//
// jhrg 9/7/94

// $Log: Int32.cc,v $
// Revision 1.28  1996/06/04 21:33:34  jimg
// Multiple connections are now possible. It is now possible to open several
// URLs at the same time and read from them in a round-robin fashion. To do
// this I added data source and sink parameters to the serialize and
// deserialize mfuncs. Connect was also modified so that it manages the data
// source `object' (which is just an XDR pointer).
//
// Revision 1.27  1996/05/31 23:29:50  jimg
// Updated copyright notice.
//
// Revision 1.26  1996/05/29 22:08:40  jimg
// Made changes necessary to support CEs that return the value of a function
// instead of the value of a variable. This was done so that it would be
// possible to translate Sequences into Arrays without first reading the
// entire sequence over the network.
//
// Revision 1.25  1996/05/16 22:49:49  jimg
// Dan's changes for version 2.0. Added a parameter to read that returns
// an error code so that EOF can be distinguished from an actual error when
// reading sequences. This *may* be replaced by an error member function
// in the future.
//
// Revision 1.24  1996/05/14 15:38:28  jimg
// These changes have already been checked in once before. However, I
// corrupted the source repository and restored it from a 5/9/96 backup
// tape. The previous version's log entry should cover the changes.
//
// Revision 1.23  1996/05/06 18:34:19  jimg
// Replaced calls to atof and atoi with calls to strtol and strtod.
//
// Revision 1.22  1996/04/05 00:21:35  jimg
// Compiled with g++ -Wall and fixed various warnings.
//
// Revision 1.21  1996/04/04 18:25:08  jimg
// Merged changes from version 1.1.1.
//
// Revision 1.20  1996/03/05 18:08:32  jimg
// Added ce_eval to serailize member function.
// Added the ops member function and int_ops function.
//
// Revision 1.19  1996/02/02 00:31:08  jimg
// Merge changes for DODS-1.1.0 into DODS-2.x
//
// Revision 1.18  1995/12/09  01:06:49  jimg
// Added changes so that relational operators will work properly for all the
// datatypes (including Sequences). The relational ops are evaluated in
// DDS::eval_constraint() after being parsed by DDS::parse_constraint().
//
// Revision 1.17  1995/12/06  21:35:16  jimg
// Changed read() from three to two parameters.
// Removed store_val() and read_val() (use buf2val() and val2buf()).
//
// Revision 1.16  1995/08/26  00:31:36  jimg
// Removed code enclosed in #ifdef NEVER #endif.
//
// Revision 1.15  1995/08/22  23:57:51  jimg
// Removed deprecated member functions.
// Changed read_val/Store_val to buf2val/val2buf.
//
// Revision 1.14.2.1  1995/07/11 18:16:22  jimg
// Changed instances of xdr_long to XDR_INT32.
//
// Revision 1.14  1995/07/09  21:29:00  jimg
// Added copyright notice.
//
// Revision 1.13  1995/05/10  15:34:02  jimg
// Failed to change `config.h' to `config_dap.h' in these files.
//
// Revision 1.12  1995/05/10  13:45:21  jimg
// Changed the name of the configuration header file from `config.h' to
// `config_dap.h' so that other libraries could have header files which were
// installed in the DODS include directory without overwriting this one. Each
// config header should follow the convention config_<name>.h.
//
// Revision 1.11  1995/03/16  17:26:40  jimg
// Moved include of config_dap.h to top of includes.
// Added TRACE_NEW switched dbnew debugging includes.
//
// Revision 1.10  1995/03/04  14:34:46  jimg
// Major modifications to the transmission and representation of values:
// Added card() virtual function which is true for classes that
// contain cardinal types (byte, int float, string).
// Changed the representation of Str from the C rep to a C++
// class represenation.
// Chnaged read_val and store_val so that they take and return
// types that are stored by the object (e.g., inthe case of Str
// an URL, read_val returns a C++ String object).
// Modified Array representations so that arrays of card()
// objects are just that - no more storing strings, ... as
// C would store them.
// Arrays of non cardinal types are arrays of the DODS objects (e.g.,
// an array of a structure is represented as an array of Structure
// objects).
//
// Revision 1.9  1995/02/10  02:22:45  jimg
// Added DBMALLOC includes and switch to code which uses malloc/free.
// Private and protected symbols now start with `_'.
// Added new accessors for name and type fields of BaseType; the old ones
// will be removed in a future release.
// Added the store_val() mfunc. It stores the given value in the object's
// internal buffer.
// Made both List and Str handle their values via pointers to memory.
// Fixed read_val().
// Made serialize/deserialize handle all malloc/free calls (even in those
// cases where xdr initiates the allocation).
// Fixed print_val().
//
// Revision 1.8  1995/01/19  20:05:17  jimg
// ptr_duplicate() mfunc is now abstract virtual.
// Array, ... Grid duplicate mfuncs were modified to take pointers, not
// referenves.
//
// Revision 1.7  1995/01/11  15:54:29  jimg
// Added modifications necessary for BaseType's static XDR pointers. This
// was mostly a name change from xdrin/out to _xdrin/out.
// Removed the two FILE pointers from ctors, since those are now set with
// functions which are friends of BaseType.
//
// Revision 1.6  1994/12/09  21:35:59  jimg
// Used the XDR_INT32 and XDR_FLOAT64 symbols defined in config.h.
//
// Revision 1.5  1994/12/07  21:23:18  jimg
// Changed from xdr_long to XDR_INT32 (defined in config.h by configure)
//
// Revision 1.4  1994/11/29  20:10:36  jimg
// Added functions for data transmission.
// Added boolean parameter to serialize which, when true, causes the output
// buffer to be flushed. The default value is false.
// Added FILE *in and *out parameters to the ctor. The default values are
// stdin/out.
// Removed the `type' parameter from the ctor.
//
// Revision 1.3  1994/09/23  14:36:08  jimg
// Fixed errors in comments.
//
// Revision 1.2  1994/09/15  21:08:44  jimg
// Added many classes to the BaseType hierarchy - the complete set of types
// described in the DODS API design documet is now represented.
// The parser can parse DDS files.
// Fixed many small problems with BaseType.
// Added CtorType.
//
// Revision 1.1  1994/09/09  15:38:45  jimg
// Child class of BaseType -- used in the future to hold specific serialization
// information for integers. Should this be a class that uses BaseType?
//

#ifdef __GNUG__
#pragma implementation
#endif

#include "config_dap.h"

#include <stdlib.h>
#include <assert.h>

#include "Int32.h"
#include "DDS.h"
#include "dods-limits.h"
#include "parser.h"
#include "expr.h"
#include "expr.tab.h"
#include "debug.h"

#ifdef TRACE_NEW
#include "trace_new.h"
#endif

Int32::Int32(const String &n) : BaseType(n, dods_int32_c, (xdrproc_t)XDR_INT32)
{
}

unsigned int
Int32::width()
{
    return sizeof(dods_int32);
}

bool
Int32::serialize(const String &dataset, DDS &dds, XDR *sink,
		 bool ce_eval = true)
{
    int error;

    if (!read_p() && !read(dataset, error))
	return false;

    if (ce_eval && !dds.eval_selection(dataset))
	return true;

    if (!XDR_INT32(sink, &_buf))
	return false;

    return true;
}

bool
Int32::deserialize(XDR *source, bool)
{
    unsigned int num = XDR_INT32(source, &_buf);

    return (num > 0);		/* make the return value a boolean */
}

unsigned int
Int32::val2buf(void *val, bool)
{
    assert(val);

    _buf = *(dods_int32 *)val;

    return width();
}

unsigned int
Int32::buf2val(void **val)
{
    assert(_buf && val);

    if (!*val)
	*val = new dods_int32;

    *(dods_int32 *)*val =_buf;

    return width();
}

// Print BUF to stdout with its declaration. Intended mostly for debugging.

void
Int32::print_val(ostream &os, String space, bool print_decl_p)
{
    if (print_decl_p) {
	print_decl(os, space, false);
	os << " = " << _buf << ";" << endl;
    }
    else
	os << _buf;
}

static bool
int_ops(int i1, int i2, int op)
{
    switch (op) {
      case EQUAL:
	return i1 == i2;
      case NOT_EQUAL:
	return i1 != i2;
      case GREATER:
	return i1 > i2;
      case GREATER_EQL:
	return i1 >= i2;
      case LESS:
	return i1 < i2;
      case LESS_EQL:
	return i1 <= i2;
      case REGEXP:
	cerr << "Regexp not valid for byte values" << endl;
	return false;
      default:
	cerr << "Unknown operator" << endl;
	return false;
    }
}

bool
Int32::ops(BaseType &b, int op)
{
    dods_int32 a1, a2;

    if (!read_p()) {
	cerr << "This value not yet read!" << endl;
	return false;
    }
    else {
	dods_int32 *a1p = &a1;
	buf2val((void **)&a1p);
    }

    if (!b.read_p()) {
	cerr << "Arg value not yet read!" << endl;
	return false;
    }
    else switch (b.type()) {
      case dods_byte_c:
      case dods_int32_c: {
	dods_int32 *a2p = &a2;
	b.buf2val((void **)&a2p);
	break;
      }
      case dods_float64_c: {
	double d;
	double *dp = &d;
	b.buf2val((void **)&dp);
	a2 = (dods_int32)d;
	break;
      }
      case dods_str_c: {
	String s;
	String *sp = &s;
	b.buf2val((void **)&sp);

	char *ptr;
	const char *cp = (const char *)s;
	long v = strtol(cp, &ptr, 0);

	if (v == 0 && cp == ptr) {
	    cerr << "`" << s << "' is not an integer value" << endl;
	    return false;
	}
	if (v > DODS_INT_MAX || v < DODS_INT_MIN) {
	    cerr << "`" << v << "' is not a integer value" << endl;
	    return false;
	}

	a2 = v;
	break;
      }
      default:
	return false;
	break;
    }

    return int_ops(a1, a2, op);
}
<commit_msg>Moved int32_ops to util.cc Added __unused__ to char rcsid[] definition. Removed system includes.<commit_after>
// (c) COPYRIGHT URI/MIT 1994-1996
// Please read the full copyright statement in the file COPYRIGH.
//
// Authors:
//      jhrg,jimg       James Gallagher (jgallagher@gso.uri.edu)

// Implementation for Int32.
//
// jhrg 9/7/94

// $Log: Int32.cc,v $
// Revision 1.29  1996/08/13 18:31:16  jimg
// Moved int32_ops to util.cc
// Added __unused__ to char rcsid[] definition.
// Removed system includes.
//
// Revision 1.28  1996/06/04 21:33:34  jimg
// Multiple connections are now possible. It is now possible to open several
// URLs at the same time and read from them in a round-robin fashion. To do
// this I added data source and sink parameters to the serialize and
// deserialize mfuncs. Connect was also modified so that it manages the data
// source `object' (which is just an XDR pointer).
//
// Revision 1.27  1996/05/31 23:29:50  jimg
// Updated copyright notice.
//
// Revision 1.26  1996/05/29 22:08:40  jimg
// Made changes necessary to support CEs that return the value of a function
// instead of the value of a variable. This was done so that it would be
// possible to translate Sequences into Arrays without first reading the
// entire sequence over the network.
//
// Revision 1.25  1996/05/16 22:49:49  jimg
// Dan's changes for version 2.0. Added a parameter to read that returns
// an error code so that EOF can be distinguished from an actual error when
// reading sequences. This *may* be replaced by an error member function
// in the future.
//
// Revision 1.24  1996/05/14 15:38:28  jimg
// These changes have already been checked in once before. However, I
// corrupted the source repository and restored it from a 5/9/96 backup
// tape. The previous version's log entry should cover the changes.
//
// Revision 1.23  1996/05/06 18:34:19  jimg
// Replaced calls to atof and atoi with calls to strtol and strtod.
//
// Revision 1.22  1996/04/05 00:21:35  jimg
// Compiled with g++ -Wall and fixed various warnings.
//
// Revision 1.21  1996/04/04 18:25:08  jimg
// Merged changes from version 1.1.1.
//
// Revision 1.20  1996/03/05 18:08:32  jimg
// Added ce_eval to serailize member function.
// Added the ops member function and int_ops function.
//
// Revision 1.19  1996/02/02 00:31:08  jimg
// Merge changes for DODS-1.1.0 into DODS-2.x
//
// Revision 1.18  1995/12/09  01:06:49  jimg
// Added changes so that relational operators will work properly for all the
// datatypes (including Sequences). The relational ops are evaluated in
// DDS::eval_constraint() after being parsed by DDS::parse_constraint().
//
// Revision 1.17  1995/12/06  21:35:16  jimg
// Changed read() from three to two parameters.
// Removed store_val() and read_val() (use buf2val() and val2buf()).
//
// Revision 1.16  1995/08/26  00:31:36  jimg
// Removed code enclosed in #ifdef NEVER #endif.
//
// Revision 1.15  1995/08/22  23:57:51  jimg
// Removed deprecated member functions.
// Changed read_val/Store_val to buf2val/val2buf.
//
// Revision 1.14.2.1  1995/07/11 18:16:22  jimg
// Changed instances of xdr_long to XDR_INT32.
//
// Revision 1.14  1995/07/09  21:29:00  jimg
// Added copyright notice.
//
// Revision 1.13  1995/05/10  15:34:02  jimg
// Failed to change `config.h' to `config_dap.h' in these files.
//
// Revision 1.12  1995/05/10  13:45:21  jimg
// Changed the name of the configuration header file from `config.h' to
// `config_dap.h' so that other libraries could have header files which were
// installed in the DODS include directory without overwriting this one. Each
// config header should follow the convention config_<name>.h.
//
// Revision 1.11  1995/03/16  17:26:40  jimg
// Moved include of config_dap.h to top of includes.
// Added TRACE_NEW switched dbnew debugging includes.
//
// Revision 1.10  1995/03/04  14:34:46  jimg
// Major modifications to the transmission and representation of values:
// Added card() virtual function which is true for classes that
// contain cardinal types (byte, int float, string).
// Changed the representation of Str from the C rep to a C++
// class represenation.
// Chnaged read_val and store_val so that they take and return
// types that are stored by the object (e.g., inthe case of Str
// an URL, read_val returns a C++ String object).
// Modified Array representations so that arrays of card()
// objects are just that - no more storing strings, ... as
// C would store them.
// Arrays of non cardinal types are arrays of the DODS objects (e.g.,
// an array of a structure is represented as an array of Structure
// objects).
//
// Revision 1.9  1995/02/10  02:22:45  jimg
// Added DBMALLOC includes and switch to code which uses malloc/free.
// Private and protected symbols now start with `_'.
// Added new accessors for name and type fields of BaseType; the old ones
// will be removed in a future release.
// Added the store_val() mfunc. It stores the given value in the object's
// internal buffer.
// Made both List and Str handle their values via pointers to memory.
// Fixed read_val().
// Made serialize/deserialize handle all malloc/free calls (even in those
// cases where xdr initiates the allocation).
// Fixed print_val().
//
// Revision 1.8  1995/01/19  20:05:17  jimg
// ptr_duplicate() mfunc is now abstract virtual.
// Array, ... Grid duplicate mfuncs were modified to take pointers, not
// referenves.
//
// Revision 1.7  1995/01/11  15:54:29  jimg
// Added modifications necessary for BaseType's static XDR pointers. This
// was mostly a name change from xdrin/out to _xdrin/out.
// Removed the two FILE pointers from ctors, since those are now set with
// functions which are friends of BaseType.
//
// Revision 1.6  1994/12/09  21:35:59  jimg
// Used the XDR_INT32 and XDR_FLOAT64 symbols defined in config.h.
//
// Revision 1.5  1994/12/07  21:23:18  jimg
// Changed from xdr_long to XDR_INT32 (defined in config.h by configure)
//
// Revision 1.4  1994/11/29  20:10:36  jimg
// Added functions for data transmission.
// Added boolean parameter to serialize which, when true, causes the output
// buffer to be flushed. The default value is false.
// Added FILE *in and *out parameters to the ctor. The default values are
// stdin/out.
// Removed the `type' parameter from the ctor.
//
// Revision 1.3  1994/09/23  14:36:08  jimg
// Fixed errors in comments.
//
// Revision 1.2  1994/09/15  21:08:44  jimg
// Added many classes to the BaseType hierarchy - the complete set of types
// described in the DODS API design documet is now represented.
// The parser can parse DDS files.
// Fixed many small problems with BaseType.
// Added CtorType.
//
// Revision 1.1  1994/09/09  15:38:45  jimg
// Child class of BaseType -- used in the future to hold specific serialization
// information for integers. Should this be a class that uses BaseType?
//

#ifdef __GNUG__
#pragma implementation
#endif

#include "config_dap.h"

static char rcsid[] __unused__ = {"$Id: Int32.cc,v 1.29 1996/08/13 18:31:16 jimg Exp $"};

#include <stdlib.h>
#include <assert.h>

#include "Int32.h"
#include "DDS.h"
#include "util.h"
#include "dods-limits.h"
#if 0
#include "parser.h"
#include "expr.h"
#include "expr.tab.h"
#endif
#include "debug.h"

#ifdef TRACE_NEW
#include "trace_new.h"
#endif

Int32::Int32(const String &n) : BaseType(n, dods_int32_c, (xdrproc_t)XDR_INT32)
{
}

unsigned int
Int32::width()
{
    return sizeof(dods_int32);
}

bool
Int32::serialize(const String &dataset, DDS &dds, XDR *sink,
		 bool ce_eval = true)
{
    int error;

    if (!read_p() && !read(dataset, error))
	return false;

    if (ce_eval && !dds.eval_selection(dataset))
	return true;

    if (!XDR_INT32(sink, &_buf))
	return false;

    return true;
}

bool
Int32::deserialize(XDR *source, bool)
{
    unsigned int num = XDR_INT32(source, &_buf);

    return (num > 0);		/* make the return value a boolean */
}

unsigned int
Int32::val2buf(void *val, bool)
{
    assert(val);

    _buf = *(dods_int32 *)val;

    return width();
}

unsigned int
Int32::buf2val(void **val)
{
    assert(_buf && val);

    if (!*val)
	*val = new dods_int32;

    *(dods_int32 *)*val =_buf;

    return width();
}

// Print BUF to stdout with its declaration. Intended mostly for debugging.

void
Int32::print_val(ostream &os, String space, bool print_decl_p)
{
    if (print_decl_p) {
	print_decl(os, space, false);
	os << " = " << _buf << ";" << endl;
    }
    else
	os << _buf;
}

bool
Int32::ops(BaseType &b, int op)
{
    dods_int32 a1, a2;

    if (!read_p()) {
	cerr << "This value not yet read!" << endl;
	return false;
    }
    else {
	dods_int32 *a1p = &a1;
	buf2val((void **)&a1p);
    }

    if (!b.read_p()) {
	cerr << "Arg value not yet read!" << endl;
	return false;
    }
    else switch (b.type()) {
      case dods_byte_c:
      case dods_int32_c: {
	dods_int32 *a2p = &a2;
	b.buf2val((void **)&a2p);
	break;
      }
      case dods_float64_c: {
	double d;
	double *dp = &d;
	b.buf2val((void **)&dp);
	a2 = (dods_int32)d;
	break;
      }
      case dods_str_c: {
	String s;
	String *sp = &s;
	b.buf2val((void **)&sp);

	char *ptr;
	const char *cp = (const char *)s;
	long v = strtol(cp, &ptr, 0);

	if (v == 0 && cp == ptr) {
	    cerr << "`" << s << "' is not an integer value" << endl;
	    return false;
	}
	if (v > DODS_INT_MAX || v < DODS_INT_MIN) {
	    cerr << "`" << v << "' is not a integer value" << endl;
	    return false;
	}

	a2 = v;
	break;
      }
      default:
	return false;
	break;
    }

    return int_ops(a1, a2, op);
}
<|endoftext|>


<commit_before>#include <iostream>
#include <sstream>
#include <string>
#include <cstdlib>
#include <unistd.h>
#include <iostream>
#include "document.hpp"
#include "eval_apply.hpp"
#include "error.hpp"
#include "sass_interface.h"

extern "C" {
  using namespace std;

  sass_context* sass_new_context()
  { return (sass_context*) calloc(1, sizeof(sass_context)); }

  void sass_free_context(sass_context* ctx)
  {
    if (ctx->output_string) free(ctx->output_string);
    if (ctx->error_message) free(ctx->error_message);

    free(ctx);
  }

  sass_file_context* sass_new_file_context()
  { return (sass_file_context*) calloc(1, sizeof(sass_file_context)); }

  void sass_free_file_context(sass_file_context* ctx)
  {
    if (ctx->output_string) free(ctx->output_string);
    if (ctx->error_message) free(ctx->error_message);

    free(ctx);
  }

  sass_folder_context* sass_new_folder_context()
    { return (sass_folder_context*) calloc(1, sizeof(sass_folder_context)); }

  void sass_free_folder_context(sass_folder_context* ctx)
  {
    if (ctx->output_path) free(ctx->output_path);
    if (ctx->error_message) free(ctx->error_message);

    free(ctx);
  }

  static char* process_document(Sass::Document& doc, int style)
  {
    using namespace Sass;
    doc.parse_scss();
    eval(doc.root,
         doc.context.new_Node(Node::none, doc.path, doc.line, 0),
         doc.context.global_env,
         doc.context.function_env,
         doc.context.new_Node,
         doc.context);
    extend_selectors(doc.context.pending_extensions, doc.context.extensions, doc.context.new_Node);
    string output(doc.emit_css(static_cast<Document::CSS_Style>(style)));
    char* c_output = (char*) malloc(output.size() + 1);
    strcpy(c_output, output.c_str());
    return c_output;
  }

  int sass_compile(sass_context* c_ctx)
  {
    using namespace Sass;
    try {
      Context cpp_ctx(c_ctx->options.include_paths, c_ctx->options.image_path);
      // cpp_ctx.image_path = c_ctx->options.image_path;
      // Document doc(0, c_ctx->input_string, cpp_ctx);
      Document doc(Document::make_from_source_chars(cpp_ctx, c_ctx->source_string));
      c_ctx->output_string = process_document(doc, c_ctx->options.output_style);
      c_ctx->error_message = 0;
      c_ctx->error_status = 0;
    }
    catch (Error& e) {
      stringstream msg_stream;
      msg_stream << "ERROR -- " << e.path << ", line " << e.line << ": " << e.message << endl;
      string msg(msg_stream.str());
      char* msg_str = (char*) malloc(msg.size() + 1);
      strcpy(msg_str, msg.c_str());
      c_ctx->error_status = 1;
      c_ctx->output_string = 0;
      c_ctx->error_message = msg_str;
    }
    catch(bad_alloc& ba) {
      stringstream msg_stream;
      msg_stream << "ERROR -- unable to allocate memory: " << ba.what() << endl;
      string msg(msg_stream.str());
      char* msg_str = (char*) malloc(msg.size() + 1);
      strcpy(msg_str, msg.c_str());
      c_ctx->error_status = 1;
      c_ctx->output_string = 0;
      c_ctx->error_message = msg_str;
    }
    // TO DO: CATCH EVERYTHING ELSE
    return 0;
  }

  int sass_compile_file(sass_file_context* c_ctx)
  {
    using namespace Sass;
    try {
      Context cpp_ctx(c_ctx->options.include_paths, c_ctx->options.image_path);
      // Document doc(c_ctx->input_path, 0, cpp_ctx);
      // string path_string(c_ctx->options.image_path);
      // path_string = "'" + path_string + "/";
      // cpp_ctx.image_path = c_ctx->options.image_path;
      Document doc(Document::make_from_file(cpp_ctx, string(c_ctx->input_path)));
      // cerr << "MADE A DOC AND CONTEXT OBJ" << endl;
      // cerr << "REGISTRY: " << doc.context.registry.size() << endl;
      c_ctx->output_string = process_document(doc, c_ctx->options.output_style);
      c_ctx->error_message = 0;
      c_ctx->error_status = 0;
    }
    catch (Error& e) {
      stringstream msg_stream;
      msg_stream << "ERROR -- " << e.path << ", line " << e.line << ": " << e.message << endl;
      string msg(msg_stream.str());
      char* msg_str = (char*) malloc(msg.size() + 1);
      strcpy(msg_str, msg.c_str());
      c_ctx->error_status = 1;
      c_ctx->output_string = 0;
      c_ctx->error_message = msg_str;
    }
    catch(bad_alloc& ba) {
      stringstream msg_stream;
      msg_stream << "ERROR -- unable to allocate memory: " << ba.what() << endl;
      string msg(msg_stream.str());
      char* msg_str = (char*) malloc(msg.size() + 1);
      strcpy(msg_str, msg.c_str());
      c_ctx->error_status = 1;
      c_ctx->output_string = 0;
      c_ctx->error_message = msg_str;
    }
    // TO DO: CATCH EVERYTHING ELSE
    return 0;
  }

  int sass_compile_folder(sass_folder_context* c_ctx)
  {
    return 1;
  }

}
<commit_msg>Don't free output_path<commit_after>#include <iostream>
#include <sstream>
#include <string>
#include <cstdlib>
#include <unistd.h>
#include <iostream>
#include "document.hpp"
#include "eval_apply.hpp"
#include "error.hpp"
#include "sass_interface.h"

extern "C" {
  using namespace std;

  sass_context* sass_new_context()
  { return (sass_context*) calloc(1, sizeof(sass_context)); }

  void sass_free_context(sass_context* ctx)
  {
    if (ctx->output_string) free(ctx->output_string);
    if (ctx->error_message) free(ctx->error_message);

    free(ctx);
  }

  sass_file_context* sass_new_file_context()
  { return (sass_file_context*) calloc(1, sizeof(sass_file_context)); }

  void sass_free_file_context(sass_file_context* ctx)
  {
    if (ctx->output_string) free(ctx->output_string);
    if (ctx->error_message) free(ctx->error_message);

    free(ctx);
  }

  sass_folder_context* sass_new_folder_context()
    { return (sass_folder_context*) calloc(1, sizeof(sass_folder_context)); }

  void sass_free_folder_context(sass_folder_context* ctx)
  {
    if (ctx->error_message) free(ctx->error_message);

    free(ctx);
  }

  static char* process_document(Sass::Document& doc, int style)
  {
    using namespace Sass;
    doc.parse_scss();
    eval(doc.root,
         doc.context.new_Node(Node::none, doc.path, doc.line, 0),
         doc.context.global_env,
         doc.context.function_env,
         doc.context.new_Node,
         doc.context);
    extend_selectors(doc.context.pending_extensions, doc.context.extensions, doc.context.new_Node);
    string output(doc.emit_css(static_cast<Document::CSS_Style>(style)));
    char* c_output = (char*) malloc(output.size() + 1);
    strcpy(c_output, output.c_str());
    return c_output;
  }

  int sass_compile(sass_context* c_ctx)
  {
    using namespace Sass;
    try {
      Context cpp_ctx(c_ctx->options.include_paths, c_ctx->options.image_path);
      // cpp_ctx.image_path = c_ctx->options.image_path;
      // Document doc(0, c_ctx->input_string, cpp_ctx);
      Document doc(Document::make_from_source_chars(cpp_ctx, c_ctx->source_string));
      c_ctx->output_string = process_document(doc, c_ctx->options.output_style);
      c_ctx->error_message = 0;
      c_ctx->error_status = 0;
    }
    catch (Error& e) {
      stringstream msg_stream;
      msg_stream << "ERROR -- " << e.path << ", line " << e.line << ": " << e.message << endl;
      string msg(msg_stream.str());
      char* msg_str = (char*) malloc(msg.size() + 1);
      strcpy(msg_str, msg.c_str());
      c_ctx->error_status = 1;
      c_ctx->output_string = 0;
      c_ctx->error_message = msg_str;
    }
    catch(bad_alloc& ba) {
      stringstream msg_stream;
      msg_stream << "ERROR -- unable to allocate memory: " << ba.what() << endl;
      string msg(msg_stream.str());
      char* msg_str = (char*) malloc(msg.size() + 1);
      strcpy(msg_str, msg.c_str());
      c_ctx->error_status = 1;
      c_ctx->output_string = 0;
      c_ctx->error_message = msg_str;
    }
    // TO DO: CATCH EVERYTHING ELSE
    return 0;
  }

  int sass_compile_file(sass_file_context* c_ctx)
  {
    using namespace Sass;
    try {
      Context cpp_ctx(c_ctx->options.include_paths, c_ctx->options.image_path);
      // Document doc(c_ctx->input_path, 0, cpp_ctx);
      // string path_string(c_ctx->options.image_path);
      // path_string = "'" + path_string + "/";
      // cpp_ctx.image_path = c_ctx->options.image_path;
      Document doc(Document::make_from_file(cpp_ctx, string(c_ctx->input_path)));
      // cerr << "MADE A DOC AND CONTEXT OBJ" << endl;
      // cerr << "REGISTRY: " << doc.context.registry.size() << endl;
      c_ctx->output_string = process_document(doc, c_ctx->options.output_style);
      c_ctx->error_message = 0;
      c_ctx->error_status = 0;
    }
    catch (Error& e) {
      stringstream msg_stream;
      msg_stream << "ERROR -- " << e.path << ", line " << e.line << ": " << e.message << endl;
      string msg(msg_stream.str());
      char* msg_str = (char*) malloc(msg.size() + 1);
      strcpy(msg_str, msg.c_str());
      c_ctx->error_status = 1;
      c_ctx->output_string = 0;
      c_ctx->error_message = msg_str;
    }
    catch(bad_alloc& ba) {
      stringstream msg_stream;
      msg_stream << "ERROR -- unable to allocate memory: " << ba.what() << endl;
      string msg(msg_stream.str());
      char* msg_str = (char*) malloc(msg.size() + 1);
      strcpy(msg_str, msg.c_str());
      c_ctx->error_status = 1;
      c_ctx->output_string = 0;
      c_ctx->error_message = msg_str;
    }
    // TO DO: CATCH EVERYTHING ELSE
    return 0;
  }

  int sass_compile_folder(sass_folder_context* c_ctx)
  {
    return 1;
  }

}
<|endoftext|>


<commit_before>/*
 * File:   Debug.h
 * Author: edmmhka
 *
 * Created on August 17, 2012, 1:39 PM
 */

#ifndef DEBUG_H
#define	DEBUG_H

#define KASSERT(x) if (!(x)) { Debug::panic("Assertion (" #x ") failed at " __FILE__ ":%d\n", __LINE__); }

class Debug {
private:
   Debug() = delete;
   Debug(const Debug& orig) = delete;
   ~Debug() = delete;

public:
   static void panic [[noreturn]] (const char*, ...);

   static void verbose(const char*, ...);
   static void info(const char*, ...);
   static void warning(const char*, ...);
   static void error(const char*, ...);

   enum class DebugLevel
   {
      Silent,
      Error,
      Warning,
      Info,
      Verbose
   };

private:
   static void printTimeStamp();

   static DebugLevel debugLevel;
};

#endif	/* DEBUG_H */
<commit_msg>use compiler specific annotaion instead of c++11, because some tools just plain suck<commit_after>/*
 * File:   Debug.h
 * Author: edmmhka
 *
 * Created on August 17, 2012, 1:39 PM
 */

#ifndef DEBUG_H
#define	DEBUG_H

#define KASSERT(x) if (!(x)) { Debug::panic("Assertion (" #x ") failed at " __FILE__ ":%d\n", __LINE__); }

class Debug {
private:
   Debug() = delete;
   Debug(const Debug& orig) = delete;
   ~Debug() = delete;

public:
   static void panic (const char*, ...) __attribute__((noreturn));

   static void verbose(const char*, ...);
   static void info(const char*, ...);
   static void warning(const char*, ...);
   static void error(const char*, ...);

   enum class DebugLevel
   {
      Silent,
      Error,
      Warning,
      Info,
      Verbose
   };

private:
   static void printTimeStamp();

   static DebugLevel debugLevel;
};

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


<commit_before>// Copyright 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "iree/hal/vulkan/debug_reporter.h"

#include "iree/base/tracing.h"
#include "iree/hal/vulkan/status_util.h"

namespace iree {
namespace hal {
namespace vulkan {

namespace {

// NOTE: |user_data| may be nullptr if we are being called during instance
// creation. Otherwise it is a pointer to the DebugReporter instance.

// NOTE: this callback must be thread safe and must be careful not to reach too
// far outside of the call - it is called in-context from arbitrary threads with
// some amount of Vulkan state on the stack. Assume that creating or deleting
// Vulkan objects, issuing most Vulkan commands, etc are off-limits.

VKAPI_ATTR VkBool32 VKAPI_CALL DebugUtilsMessageCallback(
    VkDebugUtilsMessageSeverityFlagBitsEXT message_severity,
    VkDebugUtilsMessageTypeFlagsEXT message_type,
    const VkDebugUtilsMessengerCallbackDataEXT* callback_data,
    void* user_data) {
  // TODO(benvanik): better logging once we have switched logging APIs.
  LOG(ERROR) << callback_data->pMessage;

  return VK_FALSE;  // VK_TRUE is reserved for future use.
}

VKAPI_ATTR VkBool32 VKAPI_CALL DebugReportCallback(
    VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT object_type,
    uint64_t object, size_t location, int32_t message_code,
    const char* layer_prefix, const char* message, void* user_data) {
  // TODO(benvanik): better logging once we have switched logging APIs.
  LOG(ERROR) << message;

  return VK_FALSE;  // VK_TRUE is reserved for future use.
}

}  // namespace

// static
void DebugReporter::PopulateStaticCreateInfo(
    VkDebugUtilsMessengerCreateInfoEXT* create_info) {
  create_info->sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
  create_info->pNext = nullptr;
  create_info->flags = 0;

  // TODO(benvanik): only enable the severities that logging has enabled.
  create_info->messageSeverity =
      VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT |
      VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT |
      VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT |
      VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;

  // TODO(benvanik): allow filtering by category as a flag.
  create_info->messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT |
                             VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT |
                             VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT;

  create_info->pfnUserCallback = DebugUtilsMessageCallback;
  create_info->pUserData = nullptr;
}

// static
void DebugReporter::PopulateStaticCreateInfo(
    VkDebugReportCallbackCreateInfoEXT* create_info) {
  create_info->sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT;
  create_info->pNext = nullptr;
  create_info->flags = 0;

  // TODO(benvanik): only enable the severities that logging has enabled.
  create_info->flags |=
      VK_DEBUG_REPORT_INFORMATION_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT |
      VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT |
      VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_DEBUG_BIT_EXT;

  create_info->pfnCallback = DebugReportCallback;
  create_info->pUserData = nullptr;
}

// static
StatusOr<std::unique_ptr<DebugReporter>>
DebugReporter::CreateDebugUtilsMessenger(
    VkInstance instance, const ref_ptr<DynamicSymbols>& syms,
    const VkAllocationCallbacks* allocation_callbacks) {
  IREE_TRACE_SCOPE0("DebugReporter::CreateDebugUtilsMessenger");

  auto debug_reporter =
      absl::WrapUnique(new DebugReporter(instance, syms, allocation_callbacks));

  VkDebugUtilsMessengerCreateInfoEXT create_info;
  PopulateStaticCreateInfo(&create_info);
  create_info.pUserData = debug_reporter.get();

  VK_RETURN_IF_ERROR(syms->vkCreateDebugUtilsMessengerEXT(
      instance, &create_info, allocation_callbacks,
      &debug_reporter->messenger_));

  return debug_reporter;
}

// static
StatusOr<std::unique_ptr<DebugReporter>>
DebugReporter::CreateDebugReportCallback(
    VkInstance instance, const ref_ptr<DynamicSymbols>& syms,
    const VkAllocationCallbacks* allocation_callbacks) {
  IREE_TRACE_SCOPE0("DebugReporter::CreateDebugReportCallback");

  auto debug_reporter =
      absl::WrapUnique(new DebugReporter(instance, syms, allocation_callbacks));

  VkDebugReportCallbackCreateInfoEXT create_info;
  PopulateStaticCreateInfo(&create_info);
  create_info.pUserData = debug_reporter.get();

  VK_RETURN_IF_ERROR(syms->vkCreateDebugReportCallbackEXT(
      instance, &create_info, allocation_callbacks,
      &debug_reporter->callback_));

  return debug_reporter;
}

DebugReporter::DebugReporter(VkInstance instance,
                             const ref_ptr<DynamicSymbols>& syms,
                             const VkAllocationCallbacks* allocation_callbacks)
    : instance_(instance),
      syms_(add_ref(syms)),
      allocation_callbacks_(allocation_callbacks) {}

DebugReporter::~DebugReporter() {
  IREE_TRACE_SCOPE0("DebugReporter::dtor");
  if (messenger_ != VK_NULL_HANDLE) {
    syms_->vkDestroyDebugUtilsMessengerEXT(instance_, messenger_,
                                           allocation_callbacks_);
  }
  if (callback_ != VK_NULL_HANDLE) {
    syms_->vkDestroyDebugReportCallbackEXT(instance_, callback_,
                                           allocation_callbacks_);
  }
}

}  // namespace vulkan
}  // namespace hal
}  // namespace iree
<commit_msg>Turn down verbosity of debug_reporter messages.<commit_after>// Copyright 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "iree/hal/vulkan/debug_reporter.h"

#include "iree/base/tracing.h"
#include "iree/hal/vulkan/status_util.h"

namespace iree {
namespace hal {
namespace vulkan {

namespace {

// NOTE: |user_data| may be nullptr if we are being called during instance
// creation. Otherwise it is a pointer to the DebugReporter instance.

// NOTE: this callback must be thread safe and must be careful not to reach too
// far outside of the call - it is called in-context from arbitrary threads with
// some amount of Vulkan state on the stack. Assume that creating or deleting
// Vulkan objects, issuing most Vulkan commands, etc are off-limits.

VKAPI_ATTR VkBool32 VKAPI_CALL DebugUtilsMessageCallback(
    VkDebugUtilsMessageSeverityFlagBitsEXT message_severity,
    VkDebugUtilsMessageTypeFlagsEXT message_type,
    const VkDebugUtilsMessengerCallbackDataEXT* callback_data,
    void* user_data) {
  if (message_severity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) {
    LOG(ERROR) << callback_data->pMessage;
  } else {
    VLOG(1) << callback_data->pMessage;
  }

  return VK_FALSE;  // VK_TRUE is reserved for future use.
}

VKAPI_ATTR VkBool32 VKAPI_CALL DebugReportCallback(
    VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT object_type,
    uint64_t object, size_t location, int32_t message_code,
    const char* layer_prefix, const char* message, void* user_data) {
  VLOG(1) << message;

  return VK_FALSE;  // VK_TRUE is reserved for future use.
}

}  // namespace

// static
void DebugReporter::PopulateStaticCreateInfo(
    VkDebugUtilsMessengerCreateInfoEXT* create_info) {
  create_info->sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
  create_info->pNext = nullptr;
  create_info->flags = 0;

  // TODO(benvanik): only enable the severities that logging has enabled.
  create_info->messageSeverity =
      VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT |
      VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT |
      VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT |
      VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;

  // TODO(benvanik): allow filtering by category as a flag.
  create_info->messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT |
                             VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT |
                             VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT;

  create_info->pfnUserCallback = DebugUtilsMessageCallback;
  create_info->pUserData = nullptr;
}

// static
void DebugReporter::PopulateStaticCreateInfo(
    VkDebugReportCallbackCreateInfoEXT* create_info) {
  create_info->sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT;
  create_info->pNext = nullptr;
  create_info->flags = 0;

  // TODO(benvanik): only enable the severities that logging has enabled.
  create_info->flags |=
      VK_DEBUG_REPORT_INFORMATION_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT |
      VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT |
      VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_DEBUG_BIT_EXT;

  create_info->pfnCallback = DebugReportCallback;
  create_info->pUserData = nullptr;
}

// static
StatusOr<std::unique_ptr<DebugReporter>>
DebugReporter::CreateDebugUtilsMessenger(
    VkInstance instance, const ref_ptr<DynamicSymbols>& syms,
    const VkAllocationCallbacks* allocation_callbacks) {
  IREE_TRACE_SCOPE0("DebugReporter::CreateDebugUtilsMessenger");

  auto debug_reporter =
      absl::WrapUnique(new DebugReporter(instance, syms, allocation_callbacks));

  VkDebugUtilsMessengerCreateInfoEXT create_info;
  PopulateStaticCreateInfo(&create_info);
  create_info.pUserData = debug_reporter.get();

  VK_RETURN_IF_ERROR(syms->vkCreateDebugUtilsMessengerEXT(
      instance, &create_info, allocation_callbacks,
      &debug_reporter->messenger_));

  return debug_reporter;
}

// static
StatusOr<std::unique_ptr<DebugReporter>>
DebugReporter::CreateDebugReportCallback(
    VkInstance instance, const ref_ptr<DynamicSymbols>& syms,
    const VkAllocationCallbacks* allocation_callbacks) {
  IREE_TRACE_SCOPE0("DebugReporter::CreateDebugReportCallback");

  auto debug_reporter =
      absl::WrapUnique(new DebugReporter(instance, syms, allocation_callbacks));

  VkDebugReportCallbackCreateInfoEXT create_info;
  PopulateStaticCreateInfo(&create_info);
  create_info.pUserData = debug_reporter.get();

  VK_RETURN_IF_ERROR(syms->vkCreateDebugReportCallbackEXT(
      instance, &create_info, allocation_callbacks,
      &debug_reporter->callback_));

  return debug_reporter;
}

DebugReporter::DebugReporter(VkInstance instance,
                             const ref_ptr<DynamicSymbols>& syms,
                             const VkAllocationCallbacks* allocation_callbacks)
    : instance_(instance),
      syms_(add_ref(syms)),
      allocation_callbacks_(allocation_callbacks) {}

DebugReporter::~DebugReporter() {
  IREE_TRACE_SCOPE0("DebugReporter::dtor");
  if (messenger_ != VK_NULL_HANDLE) {
    syms_->vkDestroyDebugUtilsMessengerEXT(instance_, messenger_,
                                           allocation_callbacks_);
  }
  if (callback_ != VK_NULL_HANDLE) {
    syms_->vkDestroyDebugReportCallbackEXT(instance_, callback_,
                                           allocation_callbacks_);
  }
}

}  // namespace vulkan
}  // namespace hal
}  // namespace iree
<|endoftext|>


<commit_before>//
// Copyright (c) 2012 Daniel Lundin
//

#include "medida/reporting/json_reporter.h"

#include <chrono>
#include <ctime>
#include <mutex>
#include <sstream>
#ifdef _MSC_VER
#include <Winsock2.h>
#else
#include <sys/utsname.h>
#endif

#include "medida/reporting/util.h"

namespace medida {
namespace reporting {

class JsonReporter::Impl {
 public:
  Impl(JsonReporter& self, MetricsRegistry &registry);
  ~Impl();
  void Process(Counter& counter);
  void Process(Meter& meter);
  void Process(Histogram& histogram);
  void Process(Timer& timer);
  std::string Report();
 private:
  JsonReporter& self_;
  medida::MetricsRegistry& registry_;
  mutable std::mutex mutex_;
  std::stringstream out_;
  std::string uname_;
};

JsonReporter::JsonReporter(MetricsRegistry &registry)
    : impl_ {new JsonReporter::Impl {*this, registry}} {
}

JsonReporter::~JsonReporter() {
}

std::string JsonReporter::Report() {
  return impl_->Report();
}

void JsonReporter::Process(Counter& counter) {
  impl_->Process(counter);
}

void JsonReporter::Process(Meter& meter) {
  impl_->Process(meter);
}

void JsonReporter::Process(Histogram& histogram) {
  impl_->Process(histogram);
}

void JsonReporter::Process(Timer& timer) {
  impl_->Process(timer);
}

// === Implementation ===

JsonReporter::Impl::Impl(JsonReporter& self, MetricsRegistry &registry)
    : self_     (self),
      registry_ (registry) {
#ifdef _MSC_VER
	char nameBuf[128];
	if (gethostname(nameBuf, sizeof(nameBuf)) == 0)
	{
		uname_ = std::string(nameBuf);
	}
	else
	{
		uname_ = std::string("localhost");
	}
#else
  utsname name;
  uname_ = {uname(&name) ? "localhost" : name.nodename};
#endif
}

JsonReporter::Impl::~Impl() {
}

std::string JsonReporter::Impl::Report() {
  auto t = std::time(NULL);
  char mbstr[32] = "";

  std::tm tm;
#ifdef _WIN32
    // On Win32 this is returns a thread-local and there's no _r variant.
    std::tm *tmPtr = gmtime(&t);
    tm = *tmPtr;
#else
    // On unix the _r variant uses a local output, so is threadsafe.
    gmtime_r(&t, &tm);
#endif

  std::strftime(mbstr, 32, "%FT%TZ", &tm);
  std::lock_guard<std::mutex> lock {mutex_};
  out_.str("");
  out_.clear();
  out_ << "{" << std::endl
       << "\"ts\":\"" << mbstr << "\"," << std::endl
       << "\"uname\":\"" << uname_ << "\"," << std::endl
       << "\"metrics\":{" << std::endl;
  auto first = true;
  for (auto& kv : registry_.GetAllMetrics()) {
    auto name = kv.first;
    auto metric = kv.second;
    if (first) {
      first = false;
    } else {
      out_ << ",";
    }
    out_ << "\"" << name.ToString() << "\":{" << std::endl;
    metric->Process(self_);
    out_ << "}" << std::endl;
  }
  out_ << "}"    // metrics
       << "}";  // top
  return out_.str();
}

void JsonReporter::Impl::Process(Counter& counter) {
  out_ << "\"type\":\"counter\"," << std::endl;
  out_ << "\"count\":" << counter.count() << std::endl;
}

void JsonReporter::Impl::Process(Meter& meter) {
  auto event_type = meter.event_type();
  auto unit = FormatRateUnit(meter.rate_unit());
  out_ << "\"type\":\"meter\"," << std::endl
       << "\"count\":" << meter.count() << "," << std::endl
       << "\"event_type\":\"" << event_type << "\"," << std::endl
       << "\"rate_unit\":\"" << unit << "\"," << std::endl
       << "\"mean_rate\":" << meter.mean_rate() << "," << std::endl
       << "\"1_min_rate\":" << meter.one_minute_rate() << "," << std::endl
       << "\"5_min_rate\":" << meter.five_minute_rate() << "," << std::endl
       << "\"15_min_rate\":" << meter.fifteen_minute_rate() << std::endl;
}

void JsonReporter::Impl::Process(Histogram& histogram) {
  auto snapshot = histogram.GetSnapshot();
#ifdef _MSC_VER
#undef min
#undef max
#endif
  out_ << "\"type\":\"histogram\"," << std::endl
       << "\"min\":" << histogram.min() << "," << std::endl
       << "\"max\":" << histogram.max() << "," << std::endl
       << "\"mean\":" << histogram.mean() << "," << std::endl
       << "\"stddev\":" << histogram.std_dev() << "," << std::endl
       << "\"median\":" << snapshot.getMedian() << "," << std::endl
       << "\"75%\":" << snapshot.get75thPercentile() << "," << std::endl
       << "\"95%\":" << snapshot.get95thPercentile() << "," << std::endl
       << "\"98%\":" << snapshot.get98thPercentile() << "," << std::endl
       << "\"99%\":" << snapshot.get99thPercentile() << "," << std::endl
       << "\"99.9%\":" << snapshot.get999thPercentile() << std::endl;
}

void JsonReporter::Impl::Process(Timer& timer) {
  auto snapshot = timer.GetSnapshot();
  auto rate_unit = FormatRateUnit(timer.rate_unit());
  auto duration_unit = FormatRateUnit(timer.duration_unit());
  out_ << "\"type\":\"timer\"," << std::endl
       << "\"count\":" << timer.count() << "," << std::endl
       << "\"event_type\":\"" << timer.event_type() << "\"," << std::endl
       << "\"rate_unit\":\"" << rate_unit << "\"," << std::endl
       << "\"mean_rate\":" << timer.mean_rate() << "," << std::endl
       << "\"1_min_rate\":" << timer.one_minute_rate() << "," << std::endl
       << "\"5_min_rate\":" << timer.five_minute_rate() << "," << std::endl
       << "\"15_min_rate\":" << timer.fifteen_minute_rate() << "," << std::endl
       << "\"duration_unit\":\"" << duration_unit << "\"," << std::endl
       << "\"min\":" << timer.min() << "," << std::endl
       << "\"max\":" << timer.max() << "," << std::endl
       << "\"mean\":" << timer.mean() << "," << std::endl
       << "\"stddev\":" << timer.std_dev() << "," << std::endl
       << "\"median\":" << snapshot.getMedian() << "," << std::endl
       << "\"75%\":" << snapshot.get75thPercentile() << "," << std::endl
       << "\"95%\":" << snapshot.get95thPercentile() << "," << std::endl
       << "\"98%\":" << snapshot.get98thPercentile() << "," << std::endl
       << "\"99%\":" << snapshot.get99thPercentile() << "," << std::endl
       << "\"99.9%\":" << snapshot.get999thPercentile() << std::endl;
}

} // namespace reporting
} // namespace medida
<commit_msg>fix for mingw<commit_after>//
// Copyright (c) 2012 Daniel Lundin
//

#include "medida/reporting/json_reporter.h"

#include <chrono>
#include <ctime>
#include <mutex>
#include <sstream>
#ifdef _WIN32
#include <Winsock2.h>
#else
#include <sys/utsname.h>
#endif

#include "medida/reporting/util.h"

namespace medida {
namespace reporting {

class JsonReporter::Impl {
 public:
  Impl(JsonReporter& self, MetricsRegistry &registry);
  ~Impl();
  void Process(Counter& counter);
  void Process(Meter& meter);
  void Process(Histogram& histogram);
  void Process(Timer& timer);
  std::string Report();
 private:
  JsonReporter& self_;
  medida::MetricsRegistry& registry_;
  mutable std::mutex mutex_;
  std::stringstream out_;
  std::string uname_;
};

JsonReporter::JsonReporter(MetricsRegistry &registry)
    : impl_ {new JsonReporter::Impl {*this, registry}} {
}

JsonReporter::~JsonReporter() {
}

std::string JsonReporter::Report() {
  return impl_->Report();
}

void JsonReporter::Process(Counter& counter) {
  impl_->Process(counter);
}

void JsonReporter::Process(Meter& meter) {
  impl_->Process(meter);
}

void JsonReporter::Process(Histogram& histogram) {
  impl_->Process(histogram);
}

void JsonReporter::Process(Timer& timer) {
  impl_->Process(timer);
}

// === Implementation ===

JsonReporter::Impl::Impl(JsonReporter& self, MetricsRegistry &registry)
    : self_     (self),
      registry_ (registry) {
#ifdef _WIN32
	char nameBuf[128];
	if (gethostname(nameBuf, sizeof(nameBuf)) == 0)
	{
		uname_ = std::string(nameBuf);
	}
	else
	{
		uname_ = std::string("localhost");
	}
#else
  utsname name;
  uname_ = {uname(&name) ? "localhost" : name.nodename};
#endif
}

JsonReporter::Impl::~Impl() {
}

std::string JsonReporter::Impl::Report() {
  auto t = std::time(NULL);
  char mbstr[32] = "";

  std::tm tm;
#ifdef _WIN32
    // On Win32 this is returns a thread-local and there's no _r variant.
    std::tm *tmPtr = gmtime(&t);
    tm = *tmPtr;
#else
    // On unix the _r variant uses a local output, so is threadsafe.
    gmtime_r(&t, &tm);
#endif

  std::strftime(mbstr, 32, "%FT%TZ", &tm);
  std::lock_guard<std::mutex> lock {mutex_};
  out_.str("");
  out_.clear();
  out_ << "{" << std::endl
       << "\"ts\":\"" << mbstr << "\"," << std::endl
       << "\"uname\":\"" << uname_ << "\"," << std::endl
       << "\"metrics\":{" << std::endl;
  auto first = true;
  for (auto& kv : registry_.GetAllMetrics()) {
    auto name = kv.first;
    auto metric = kv.second;
    if (first) {
      first = false;
    } else {
      out_ << ",";
    }
    out_ << "\"" << name.ToString() << "\":{" << std::endl;
    metric->Process(self_);
    out_ << "}" << std::endl;
  }
  out_ << "}"    // metrics
       << "}";  // top
  return out_.str();
}

void JsonReporter::Impl::Process(Counter& counter) {
  out_ << "\"type\":\"counter\"," << std::endl;
  out_ << "\"count\":" << counter.count() << std::endl;
}

void JsonReporter::Impl::Process(Meter& meter) {
  auto event_type = meter.event_type();
  auto unit = FormatRateUnit(meter.rate_unit());
  out_ << "\"type\":\"meter\"," << std::endl
       << "\"count\":" << meter.count() << "," << std::endl
       << "\"event_type\":\"" << event_type << "\"," << std::endl
       << "\"rate_unit\":\"" << unit << "\"," << std::endl
       << "\"mean_rate\":" << meter.mean_rate() << "," << std::endl
       << "\"1_min_rate\":" << meter.one_minute_rate() << "," << std::endl
       << "\"5_min_rate\":" << meter.five_minute_rate() << "," << std::endl
       << "\"15_min_rate\":" << meter.fifteen_minute_rate() << std::endl;
}

void JsonReporter::Impl::Process(Histogram& histogram) {
  auto snapshot = histogram.GetSnapshot();
#ifdef _WIN32
#undef min
#undef max
#endif
  out_ << "\"type\":\"histogram\"," << std::endl
       << "\"min\":" << histogram.min() << "," << std::endl
       << "\"max\":" << histogram.max() << "," << std::endl
       << "\"mean\":" << histogram.mean() << "," << std::endl
       << "\"stddev\":" << histogram.std_dev() << "," << std::endl
       << "\"median\":" << snapshot.getMedian() << "," << std::endl
       << "\"75%\":" << snapshot.get75thPercentile() << "," << std::endl
       << "\"95%\":" << snapshot.get95thPercentile() << "," << std::endl
       << "\"98%\":" << snapshot.get98thPercentile() << "," << std::endl
       << "\"99%\":" << snapshot.get99thPercentile() << "," << std::endl
       << "\"99.9%\":" << snapshot.get999thPercentile() << std::endl;
}

void JsonReporter::Impl::Process(Timer& timer) {
  auto snapshot = timer.GetSnapshot();
  auto rate_unit = FormatRateUnit(timer.rate_unit());
  auto duration_unit = FormatRateUnit(timer.duration_unit());
  out_ << "\"type\":\"timer\"," << std::endl
       << "\"count\":" << timer.count() << "," << std::endl
       << "\"event_type\":\"" << timer.event_type() << "\"," << std::endl
       << "\"rate_unit\":\"" << rate_unit << "\"," << std::endl
       << "\"mean_rate\":" << timer.mean_rate() << "," << std::endl
       << "\"1_min_rate\":" << timer.one_minute_rate() << "," << std::endl
       << "\"5_min_rate\":" << timer.five_minute_rate() << "," << std::endl
       << "\"15_min_rate\":" << timer.fifteen_minute_rate() << "," << std::endl
       << "\"duration_unit\":\"" << duration_unit << "\"," << std::endl
       << "\"min\":" << timer.min() << "," << std::endl
       << "\"max\":" << timer.max() << "," << std::endl
       << "\"mean\":" << timer.mean() << "," << std::endl
       << "\"stddev\":" << timer.std_dev() << "," << std::endl
       << "\"median\":" << snapshot.getMedian() << "," << std::endl
       << "\"75%\":" << snapshot.get75thPercentile() << "," << std::endl
       << "\"95%\":" << snapshot.get95thPercentile() << "," << std::endl
       << "\"98%\":" << snapshot.get98thPercentile() << "," << std::endl
       << "\"99%\":" << snapshot.get99thPercentile() << "," << std::endl
       << "\"99.9%\":" << snapshot.get999thPercentile() << std::endl;
}

} // namespace reporting
} // namespace medida
<|endoftext|>