<commit_before>#ifndef STAN_MATH_REV_SCAL_FUNCTOR_REDUCE_SUM_HPP
#define STAN_MATH_REV_SCAL_FUNCTOR_REDUCE_SUM_HPP

#include <stan/math/prim/meta.hpp>
#include <stan/math/rev/fun/typedefs.hpp>

#include <tbb/task_arena.h>
#include <tbb/parallel_reduce.h>
#include <tbb/blocked_range.h>

#include <iostream>
#include <iterator>
#include <vector>

namespace stan {
namespace math {
namespace internal {

template <typename ReduceFunction, typename ReturnType, typename M,
          typename... Args>
struct reduce_sum_impl<ReduceFunction, require_var_t<ReturnType>, ReturnType, M,
                       Args...> {
  struct recursive_reducer {
    size_t num_terms_;
    const std::vector<M>& vmapped_;
    std::tuple<const Args&...> args_tuple_;

    double sum_;
    Eigen::VectorXd args_adjoints_;

    recursive_reducer(size_t num_terms, const std::vector<M>& vmapped,
                      const Args&... args)
        : num_terms_(num_terms),
          vmapped_(vmapped),
          args_tuple_(args...),
          sum_(0.0),
          args_adjoints_(Eigen::VectorXd::Zero(num_terms)) {}

    recursive_reducer(recursive_reducer& other, tbb::split)
        : num_terms_(other.num_terms_),
          vmapped_(other.vmapped_),
          args_tuple_(other.args_tuple_),
          sum_(other.sum_),
          args_adjoints_(other.args_adjoints_) {}

    template <typename T>
    T& deep_copy(T& arg) {
      return arg;
    }

    var deep_copy(const var& arg) { return var(arg.val()); }

    std::vector<var> deep_copy(const std::vector<var>& arg) {
      std::vector<var> copy(arg.size());
      for (size_t i = 0; i < arg.size(); ++i) {
        copy[i] = arg[i].val();
      }
      return copy;
    }

    template <int RowType, int ColType>
    Eigen::Matrix<var, RowType, ColType> deep_copy(
        const Eigen::Matrix<var, RowType, ColType>& arg) {
      Eigen::Matrix<var, RowType, ColType> copy(arg.size());
      for (size_t i = 0; i < arg.size(); ++i) {
        copy(i) = arg(i).val();
      }
      return copy;
    }

    template <typename... Pargs>
    void accumulate_adjoints(double* dest, const var& x, const Pargs&... args) {
      *dest += x.adj();
      accumulate_adjoints(dest + 1, args...);
    }

    // Works with anything that has operator[Integral] defined
    template <typename... Pargs, typename Vec, require_vector_like_vt<is_var, Vec>...>
    void accumulate_adjoints(double* dest, const Vec& x,
                             const Pargs&... args) {
      for (size_t i = 0; i < x.size(); ++i) {
        dest[i] += x[i].adj();
      }
      accumulate_adjoints(dest + x.size(), args...);
    }
    // Fails to compile if type T does not have member operator(Integral)
    template <typename T>
    using operator_paren_access_t = decltype(std::declval<T>()(int{}));

    // Works on anything with a operator()
    template <typename... Pargs, typename Mat, require_t<is_detected<Mat, operator_paren_access_t>>...,
    require_t<is_var<value_type_t<Mat>>>...>
    void accumulate_adjoints(double* dest,
                             const Mat& x,
                             const Pargs&... args) {
      for (size_t i = 0; i < x.size(); ++i) {
        dest[i] += x(i).adj();
      }
      accumulate_adjoints(dest + x.size(), args...);
    }

    // Anything with a scalar type of Arithmetic gets tossed
    template <typename Arith, require_arithmetic_t<scalar_type_t<Arith>>..., typename... Pargs>
    void accumulate_adjoints(double* dest, Arith&& x, const Pargs&... args) {
      accumulate_adjoints(dest, args...);
    }

    void accumulate_adjoints(double*) {}

    void operator()(const tbb::blocked_range<size_t>& r) {
      if (r.empty())
        return;

      auto start = vmapped_.begin();
      std::advance(start, r.begin());
      auto end = vmapped_.begin();
      std::advance(end, r.end());

      const std::vector<M> sub_slice(start, end);

      try {
        start_nested();

        // create a deep copy of all var's so that these are not
        // linked to any outer AD tree
        auto args_tuple_local_copy = apply(
            [&](auto&&... args) { return std::make_tuple(deep_copy(args)...); },
            args_tuple_);

        var sub_sum_v = apply(
            [&](auto&&... args) {
              return ReduceFunction()(r.begin(), r.end() - 1, sub_slice,
                                      args...);
            },
            args_tuple_local_copy);

        sub_sum_v.grad();

        sum_ += sub_sum_v.val();

        // This should accumulate the adjoints from args_tuple_local_copy into
        //  the memory of args_adjoints_
        apply(
            [&](auto&&... args) {
              accumulate_adjoints(args_adjoints_.data(), args...);
            },
            args_tuple_local_copy);
      } catch (const std::exception& e) {
        recover_memory_nested();
        throw;
      }
      recover_memory_nested();
    }

    void join(const recursive_reducer& rhs) {
      sum_ += rhs.sum_;
      args_adjoints_ += rhs.args_adjoints_;
    }
  };

  // Fails to compile if type T does not have callable member size()
  template <typename T>
  using member_size_t = decltype(std::declval<T>().size());

  // TODO(Steve): add requires for generic containers
  template <typename Container,
            require_t<is_detected<Container, member_size_t>>...,
            require_t<is_var<value_type_t<Container>>>..., typename... Pargs>
  size_t count_var_impl(size_t count, const Container& x,
                        const Pargs&... args) const {
    return count_var_impl(count + x.size(), args...);
  }

  template <typename Container,
            require_t<is_detected<Container, member_size_t>>...,
            require_t<std::is_arithmetic<value_type_t<Container>>>...,
            typename... Pargs>
  size_t count_var_impl(size_t count, const Container& x,
                        const Pargs&... args) const {
    return count_var_impl(count, args...);
  }

  template <typename... Pargs>
  size_t count_var_impl(size_t count, const var& x,
                        const Pargs&... args) const {
    return count_var_impl(count + 1, args...);
  }

  template <typename... Pargs, typename Arith, require_arithmetic_t<scalar_type_t<Arith>>...>
  size_t count_var_impl(size_t count, Arith& x, const Pargs&... args) const {
    return count_var_impl(count, args...);
  }

  size_t count_var_impl(size_t count) const { return count; }

  /**
   * Count the number of scalars of type T in the input argument list
   *
   * @tparam Pargs Types of input arguments
   * @return Number of scalars of type T in input
   */
  template <typename... Pargs>
  size_t count_var(const Pargs&... args) const {
    return count_var_impl(0, args...);
  }

  template <typename... Pargs>
  void save_varis(vari** dest, const var& x, const Pargs&... args) const {
    *dest = x.vi_;
    save_varis(dest + 1, args...);
  }

  template <typename... Pargs>
  void save_varis(vari** dest, const std::vector<var>& x,
                  const Pargs&... args) const {
    for (size_t i = 0; i < x.size(); ++i) {
      dest[i] = x[i].vi_;
    }
    save_varis(dest + x.size(), args...);
  }

  template <typename... Pargs, int RowType, int ColType>
  void save_varis(vari** dest, const Eigen::Matrix<var, RowType, ColType>& x,
                  const Pargs&... args) const {
    for (size_t i = 0; i < x.size(); ++i) {
      dest[i] = x(i).vi_;
    }
    save_varis(dest + x.size(), args...);
  }

  template <typename R, typename... Pargs>
  void save_varis(vari** dest, const R& x, const Pargs&... args) const {
    save_varis(dest, args...);
  }

  void save_varis(vari**) const {}

  var operator()(const std::vector<M>& vmapped, std::size_t grainsize,
                 const Args&... args) const {
    const std::size_t num_jobs = vmapped.size();

    if (num_jobs == 0)
      return var(0.0);

    const std::size_t num_terms = count_var(args...);

    recursive_reducer worker(num_terms, vmapped, args...);

#ifdef STAN_DETERMINISTIC
    tbb::static_partitioner partitioner;
    tbb::parallel_deterministic_reduce(
        tbb::blocked_range<std::size_t>(0, num_jobs, grainsize), worker,
        partitioner);
#else
    tbb::parallel_reduce(
        tbb::blocked_range<std::size_t>(0, num_jobs, grainsize), worker);
#endif

    vari** varis
        = ChainableStack::instance_->memalloc_.alloc_array<vari*>(num_terms);
    double* partials
        = ChainableStack::instance_->memalloc_.alloc_array<double>(num_terms);

    save_varis(varis, args...);

    for (size_t i = 0; i < num_terms; ++i) {
      partials[i] = worker.args_adjoints_(i);
    }

    return var(new precomputed_gradients_vari(worker.sum_, num_terms, varis,
                                              partials));
  }
};
}  // namespace internal

}  // namespace math
}  // namespace stan

#endif
<commit_msg>move operator_paren checker out one scope<commit_after>#ifndef STAN_MATH_REV_SCAL_FUNCTOR_REDUCE_SUM_HPP
#define STAN_MATH_REV_SCAL_FUNCTOR_REDUCE_SUM_HPP

#include <stan/math/prim/meta.hpp>
#include <stan/math/rev/fun/typedefs.hpp>

#include <tbb/task_arena.h>
#include <tbb/parallel_reduce.h>
#include <tbb/blocked_range.h>

#include <iostream>
#include <iterator>
#include <vector>

namespace stan {
namespace math {
namespace internal {

template <typename ReduceFunction, typename ReturnType, typename M,
          typename... Args>
struct reduce_sum_impl<ReduceFunction, require_var_t<ReturnType>, ReturnType, M,
                       Args...> {
   // TODO(Steve): Move this somewhere smarter
   // Fails to compile if type T does not have member operator(Integral)
   template <typename T>
   using operator_paren_access_t = decltype(std::declval<T>()(int{}));

  struct recursive_reducer {
    size_t num_terms_;
    const std::vector<M>& vmapped_;
    std::tuple<const Args&...> args_tuple_;

    double sum_;
    Eigen::VectorXd args_adjoints_;

    recursive_reducer(size_t num_terms, const std::vector<M>& vmapped,
                      const Args&... args)
        : num_terms_(num_terms),
          vmapped_(vmapped),
          args_tuple_(args...),
          sum_(0.0),
          args_adjoints_(Eigen::VectorXd::Zero(num_terms)) {}

    recursive_reducer(recursive_reducer& other, tbb::split)
        : num_terms_(other.num_terms_),
          vmapped_(other.vmapped_),
          args_tuple_(other.args_tuple_),
          sum_(other.sum_),
          args_adjoints_(other.args_adjoints_) {}

    template <typename T>
    T& deep_copy(T& arg) {
      return arg;
    }

    var deep_copy(const var& arg) { return var(arg.val()); }

    std::vector<var> deep_copy(const std::vector<var>& arg) {
      std::vector<var> copy(arg.size());
      for (size_t i = 0; i < arg.size(); ++i) {
        copy[i] = arg[i].val();
      }
      return copy;
    }

    template <int RowType, int ColType>
    Eigen::Matrix<var, RowType, ColType> deep_copy(
        const Eigen::Matrix<var, RowType, ColType>& arg) {
      Eigen::Matrix<var, RowType, ColType> copy(arg.size());
      for (size_t i = 0; i < arg.size(); ++i) {
        copy(i) = arg(i).val();
      }
      return copy;
    }

    template <typename... Pargs>
    void accumulate_adjoints(double* dest, const var& x, const Pargs&... args) {
      *dest += x.adj();
      accumulate_adjoints(dest + 1, args...);
    }

    // Works with anything that has operator[Integral] defined
    template <typename... Pargs, typename Vec, require_vector_like_vt<is_var, Vec>...>
    void accumulate_adjoints(double* dest, const Vec& x,
                             const Pargs&... args) {
      for (size_t i = 0; i < x.size(); ++i) {
        dest[i] += x[i].adj();
      }
      accumulate_adjoints(dest + x.size(), args...);
    }

    // Works on anything with a operator()
    template <typename... Pargs, typename Mat, require_t<is_detected<Mat, operator_paren_access_t>>...,
    require_t<is_var<value_type_t<Mat>>>...>
    void accumulate_adjoints(double* dest,
                             const Mat& x,
                             const Pargs&... args) {
      for (size_t i = 0; i < x.size(); ++i) {
        dest[i] += x(i).adj();
      }
      accumulate_adjoints(dest + x.size(), args...);
    }

    // Anything with a scalar type of Arithmetic gets tossed
    template <typename Arith, require_arithmetic_t<scalar_type_t<Arith>>..., typename... Pargs>
    void accumulate_adjoints(double* dest, Arith&& x, const Pargs&... args) {
      accumulate_adjoints(dest, args...);
    }

    void accumulate_adjoints(double*) {}

    void operator()(const tbb::blocked_range<size_t>& r) {
      if (r.empty())
        return;

      auto start = vmapped_.begin();
      std::advance(start, r.begin());
      auto end = vmapped_.begin();
      std::advance(end, r.end());

      const std::vector<M> sub_slice(start, end);

      try {
        start_nested();

        // create a deep copy of all var's so that these are not
        // linked to any outer AD tree
        auto args_tuple_local_copy = apply(
            [&](auto&&... args) { return std::make_tuple(deep_copy(args)...); },
            args_tuple_);

        var sub_sum_v = apply(
            [&](auto&&... args) {
              return ReduceFunction()(r.begin(), r.end() - 1, sub_slice,
                                      args...);
            },
            args_tuple_local_copy);

        sub_sum_v.grad();

        sum_ += sub_sum_v.val();

        // This should accumulate the adjoints from args_tuple_local_copy into
        //  the memory of args_adjoints_
        apply(
            [&](auto&&... args) {
              accumulate_adjoints(args_adjoints_.data(), args...);
            },
            args_tuple_local_copy);
      } catch (const std::exception& e) {
        recover_memory_nested();
        throw;
      }
      recover_memory_nested();
    }

    void join(const recursive_reducer& rhs) {
      sum_ += rhs.sum_;
      args_adjoints_ += rhs.args_adjoints_;
    }
  };

  // Fails to compile if type T does not have callable member size()
  template <typename T>
  using member_size_t = decltype(std::declval<T>().size());

  // TODO(Steve): add requires for generic containers
  template <typename Container,
            require_t<is_detected<Container, member_size_t>>...,
            require_t<is_var<value_type_t<Container>>>..., typename... Pargs>
  size_t count_var_impl(size_t count, const Container& x,
                        const Pargs&... args) const {
    return count_var_impl(count + x.size(), args...);
  }

  template <typename Container,
            require_t<is_detected<Container, member_size_t>>...,
            require_t<std::is_arithmetic<value_type_t<Container>>>...,
            typename... Pargs>
  size_t count_var_impl(size_t count, const Container& x,
                        const Pargs&... args) const {
    return count_var_impl(count, args...);
  }

  template <typename... Pargs>
  size_t count_var_impl(size_t count, const var& x,
                        const Pargs&... args) const {
    return count_var_impl(count + 1, args...);
  }

  template <typename... Pargs, typename Arith, require_arithmetic_t<scalar_type_t<Arith>>...>
  size_t count_var_impl(size_t count, Arith& x, const Pargs&... args) const {
    return count_var_impl(count, args...);
  }

  size_t count_var_impl(size_t count) const { return count; }

  /**
   * Count the number of scalars of type T in the input argument list
   *
   * @tparam Pargs Types of input arguments
   * @return Number of scalars of type T in input
   */
  template <typename... Pargs>
  size_t count_var(const Pargs&... args) const {
    return count_var_impl(0, args...);
  }

  template <typename... Pargs>
  void save_varis(vari** dest, const var& x, const Pargs&... args) const {
    *dest = x.vi_;
    save_varis(dest + 1, args...);
  }

  template <typename... Pargs, typename Vec, require_vector_like_vt<is_var, Vec>...>
  void save_varis(vari** dest, const Vec& x,
                  const Pargs&... args) const {
    for (size_t i = 0; i < x.size(); ++i) {
      dest[i] = x[i].vi_;
    }
    save_varis(dest + x.size(), args...);
  }

  template <typename... Pargs, typename Mat, require_t<is_detected<Mat, operator_paren_access_t>>...,
  require_t<is_var<value_type_t<Mat>>>...>
  void save_varis(vari** dest, const Mat& x,
                  const Pargs&... args) const {
    for (size_t i = 0; i < x.size(); ++i) {
      dest[i] = x(i).vi_;
    }
    save_varis(dest + x.size(), args...);
  }

  template <typename R, typename... Pargs>
  void save_varis(vari** dest, const R& x, const Pargs&... args) const {
    save_varis(dest, args...);
  }

  void save_varis(vari**) const {}

  var operator()(const std::vector<M>& vmapped, std::size_t grainsize,
                 const Args&... args) const {
    const std::size_t num_jobs = vmapped.size();

    if (num_jobs == 0)
      return var(0.0);

    const std::size_t num_terms = count_var(args...);

    recursive_reducer worker(num_terms, vmapped, args...);

#ifdef STAN_DETERMINISTIC
    tbb::static_partitioner partitioner;
    tbb::parallel_deterministic_reduce(
        tbb::blocked_range<std::size_t>(0, num_jobs, grainsize), worker,
        partitioner);
#else
    tbb::parallel_reduce(
        tbb::blocked_range<std::size_t>(0, num_jobs, grainsize), worker);
#endif

    vari** varis
        = ChainableStack::instance_->memalloc_.alloc_array<vari*>(num_terms);
    double* partials
        = ChainableStack::instance_->memalloc_.alloc_array<double>(num_terms);

    save_varis(varis, args...);

    for (size_t i = 0; i < num_terms; ++i) {
      partials[i] = worker.args_adjoints_(i);
    }

    return var(new precomputed_gradients_vari(worker.sum_, num_terms, varis,
                                              partials));
  }
};
}  // namespace internal

}  // namespace math
}  // namespace stan

#endif
<|endoftext|>


<commit_before>/*******************************
Copyright (C) 2013-2015 gregoire ANGERAND

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 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
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, see <http://www.gnu.org/licenses/>.
**********************************/

#include "ToneMapRenderer.h"
#include "ShaderCombinaison.h"
#include "VertexArrayObject.h"
#include <n/utils.h>

namespace n {
namespace graphics {

const Material &getMaterial() {
	static Material mat;
	if(mat.isNull()) {
		MaterialData i;
		i.depth = MaterialData::Always;
		mat = Material(i);
	}
	return mat;
}

ShaderCombinaison *getToneShader(bool debug = false) {
	static ShaderCombinaison *shaders[2] = {0, 0};
	if(!shaders[debug]) {
		static core::String deb[2] = {"", "\n#define DEBUG\n"};
		shaders[debug] = new ShaderCombinaison(new Shader<FragmentShader>(
			deb[debug] +
			"uniform sampler2D n_0;"
			"uniform sampler2D n_1;"

			"uniform float logMin;"
			"uniform float logMax;"
			"uniform float exposure;"
			"uniform float white;"

			"in vec2 n_TexCoord;"

			"out vec4 n_Out;"

			"float rgbLum(vec3 rgb) {"
				"return dot(vec3(0.299, 0.587, 0.114), rgb);"
			"}"

			"float clampLum(float l) {"
				"return clamp(l, logMin, logMax);"
			"}"

			"vec3 reinhard(vec3 col, float exp, float key, float w) {"
				"float cL = rgbLum(col);"
				"float lum = cL * exp / key;"
				"float W = 1 + lum / sqr(w);"
				"lum *= W / (lum + 1);"
				"return col * lum / cL;"
			"}"

			"vec3 gamma(vec3 col) {"
				"return pow(col, vec3(1.0 / 2.2));"
			"}"

			"void main() {"
				"vec2 offset = 0.5 / textureSize(n_1, 0);"
				"vec4 avgLum4 = textureGather(n_1, offset, 0);"
				"float avgLum = exp(clampLum((avgLum4.x + avgLum4.y + avgLum4.z + avgLum4.w) * 0.25));"

				"vec4 color = texture(n_0, n_TexCoord);"
				"vec3 rein = reinhard(color.rgb, exposure, avgLum, white);"
				"n_Out = vec4(rein, color.a);"
				"\n#ifdef DEBUG\n"
				"if(color.x > 1 || color.y > 1 || color.z > 1) { n_Out = vec4(1, 0, 0, 1); }"
				"if(n_TexCoord.x < 0.1 && n_TexCoord.y > 0.9) { n_Out = vec4(avgLum); }"
				"if(n_TexCoord.x > 0.5) { n_Out = color; }"
				"\n#endif\n"
			"}"), ShaderProgram::NoProjectionShader);
	}
	return shaders[debug];
}

ShaderCombinaison *getLogShader() {
	static ShaderCombinaison *shader = 0;
	if(!shader) {
		shader = new ShaderCombinaison(new Shader<FragmentShader>(
			"uniform sampler2D n_0;"
			"in vec2 n_TexCoord;"
			"out float n_Out;"

			"float rgbLum(vec3 rgb) {"
				"return dot(vec3(0.299, 0.587, 0.114), rgb);"
			"}"

			"const float epsilon = 0.0001;"

			"void main() {"
				"vec4 color = texture(n_0, n_TexCoord);"
				"float lum = rgbLum(color.rgb);"
				"n_Out = log(epsilon + lum);"
			"}"), ShaderProgram::NoProjectionShader);
	}
	return shader;
}

ShaderCombinaison *getDSShader() {
	static ShaderCombinaison *shader = 0;
	if(!shader) {
		shader = new ShaderCombinaison(new Shader<FragmentShader>(
			"uniform sampler2D n_0;"
			"in vec2 n_TexCoord;"
			"out float n_Out;"
			"uniform float scale;"

			"vec2 rescale(vec2 tex) {"
				"tex *= scale;"
				"vec2 h = vec2(0);  (0.5 / textureSize(n_0, 0));"
				"return tex * (1.0 - 2 * h) + h;"
			"}"

			"void main() {"
				"vec4 avgLum = textureGather(n_0, rescale(n_TexCoord), 0);"
				//"vec4 maxLum = textureGather(n_0, rescale(n_TexCoord), 1);"
				"n_Out.x = (avgLum.x + avgLum.y + avgLum.z + avgLum.w) * 0.25;"
				//"n_Out.y = max(max(maxLum.x, maxLum.y), max(maxLum.z, maxLum.w));"
			"}"), new Shader<VertexShader>(
			"layout(location = 0) in vec3 n_VertexPosition;"
			"layout(location = 3) in vec2 n_VertexCoord;"

			"uniform float scale;"

			"out vec2 n_TexCoord;"

			"void main() {"
				"vec3 vp = n_VertexPosition * 0.5 + 0.5;"
				"vp *= 0.5 * scale;"
				"vp = vp * 2.0 - 1.0;"
				"gl_Position = vec4(vp, 1.0);"
				"n_TexCoord = n_VertexCoord;"
			"}"));
	}
	return shader;
}

Texture computeLum(const Texture &in, FrameBuffer *buffers[]) {
	ShaderCombinaison *sh = getLogShader();
	sh->bind();
	sh->setValue("n_0", in);

	buffers[0]->bind();
	GLContext::getContext()->getScreen().draw(Material());

	sh = getDSShader();
	sh->bind();

	float scale = 1.0;
	bool last = false;
	uint baseSize = buffers[0]->getSize().x();
	while(baseSize != 2) {
		sh->setValue("n_0", buffers[last]->getAttachement(0));
		sh->setValue("scale", scale);
		buffers[!last]->bind();
		last = !last;
		scale *= 0.5;
		baseSize /= 2;
		GLContext::getContext()->getScreen().draw(Material());
	}
	return buffers[last]->getAttachement(0);
}

ToneMapRenderer::ToneMapRenderer(BufferedRenderer *c, uint s) : BufferableRenderer(), child(c), slot(s), exposure(0.35), white(1.5), range(0.055, 10000), debug(false) {
}

ToneMapRenderer::~ToneMapRenderer() {
}

void *ToneMapRenderer::prepare() {
	return child->prepare();
}

void ToneMapRenderer::render(void *ptr) {
	const FrameBuffer *fb = GLContext::getContext()->getFrameBuffer();
	child->render(ptr);

	uint ls = core::log2ui(child->getFrameBuffer().getSize().min());
	math::Vec2ui size = math::Vec2ui(1 << ls);
	FrameBuffer *buffers[] = {GLContext::getContext()->getFrameBufferPool().get(size, false, ImageFormat::R32F),
							  GLContext::getContext()->getFrameBufferPool().get(size, false, ImageFormat::R32F)};

	Texture lum = computeLum(child->getFrameBuffer().getAttachement(slot), buffers);

	if(fb) {
		fb->bind();
	} else {
		FrameBuffer::unbind();
	}

	ShaderCombinaison *sh = getToneShader(debug);
	sh->bind();
	sh->setValue("logMin", log(range.x()));
	sh->setValue("logMax", log(range.y()));
	sh->setValue("exposure", exposure);
	sh->setValue("white", white);

	sh->setValue("n_0", child->getFrameBuffer().getAttachement(slot));
	sh->setValue("n_1", lum);
	/*float lums[2] = { -1, -1 };
	gl::glGetTextureSubImage(lum.getHandle(), 0, 0, 0, 0, 1, 1, 1, GL_RG, GL_FLOAT, 2 * sizeof(float), lums);
	std::cout<<lum.getHandle()<<"  max = "<<lums[1]<<", avg = "<<exp(lums[0])<<std::endl;*/

	GLContext::getContext()->getScreen().draw(getMaterial(), VertexAttribs(), RenderFlag::NoShader);

	GLContext::getContext()->getFrameBufferPool().add(buffers[0]);
	GLContext::getContext()->getFrameBufferPool().add(buffers[1]);
}

}
}
<commit_msg>Fixed tone-mapper broken by the new material pipeline.<commit_after>/*******************************
Copyright (C) 2013-2015 gregoire ANGERAND

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 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
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, see <http://www.gnu.org/licenses/>.
**********************************/

#include "ToneMapRenderer.h"
#include "ShaderCombinaison.h"
#include "VertexArrayObject.h"
#include <n/utils.h>

namespace n {
namespace graphics {

const Material &getMaterial() {
	static Material mat;
	if(mat.isNull()) {
		MaterialData i;
		i.depth = MaterialData::Always;
		mat = Material(i);
	}
	return mat;
}

ShaderCombinaison *getToneShader(bool debug = false) {
	static ShaderCombinaison *shaders[2] = {0, 0};
	if(!shaders[debug]) {
		static core::String deb[2] = {"", "\n#define DEBUG\n"};
		shaders[debug] = new ShaderCombinaison(new Shader<FragmentShader>(
			deb[debug] +
			"uniform sampler2D n_0;"
			"uniform sampler2D n_1;"

			"uniform float logMin;"
			"uniform float logMax;"
			"uniform float exposure;"
			"uniform float white;"

			"in vec2 n_TexCoord;"

			"out vec4 n_Out;"

			"float rgbLum(vec3 rgb) {"
				"return dot(vec3(0.299, 0.587, 0.114), rgb);"
			"}"

			"float clampLum(float l) {"
				"return clamp(l, logMin, logMax);"
			"}"

			"vec3 reinhard(vec3 col, float exp, float key, float w) {"
				"float cL = rgbLum(col);"
				"float lum = cL * exp / key;"
				"float W = 1 + lum / sqr(w);"
				"lum *= W / (lum + 1);"
				"return col * lum / cL;"
			"}"

			"vec3 gamma(vec3 col) {"
				"return pow(col, vec3(1.0 / 2.2));"
			"}"

			"void main() {"
				"vec2 offset = 0.5 / textureSize(n_1, 0);"
				"vec4 avgLum4 = textureGather(n_1, offset, 0);"
				"float avgLum = exp(clampLum((avgLum4.x + avgLum4.y + avgLum4.z + avgLum4.w) * 0.25));"

				"vec4 color = texture(n_0, n_TexCoord);"
				"vec3 rein = reinhard(color.rgb, exposure, avgLum, white);"
				"n_Out = vec4(rein, color.a);"
				"\n#ifdef DEBUG\n"
				"if(color.x > 1 || color.y > 1 || color.z > 1) { n_Out = vec4(1, 0, 0, 1); }"
				"if(n_TexCoord.x < 0.1 && n_TexCoord.y > 0.9) { n_Out = vec4(log(avgLum)); }"
				"if(n_TexCoord.x > 0.5) { n_Out = color; }"
				"\n#endif\n"
			"}"), ShaderProgram::NoProjectionShader);
	}
	return shaders[debug];
}

ShaderCombinaison *getLogShader() {
	static ShaderCombinaison *shader = 0;
	if(!shader) {
		shader = new ShaderCombinaison(new Shader<FragmentShader>(
			"uniform sampler2D n_0;"
			"in vec2 n_TexCoord;"
			"out float n_Out;"

			"float rgbLum(vec3 rgb) {"
				"return dot(vec3(0.299, 0.587, 0.114), rgb);"
			"}"

			"const float epsilon = 0.0001;"

			"void main() {"
				"vec4 color = texture(n_0, n_TexCoord);"
				"float lum = rgbLum(color.rgb);"
				"n_Out = log(epsilon + lum);"
			"}"), ShaderProgram::NoProjectionShader);
	}
	return shader;
}

ShaderCombinaison *getDSShader() {
	static ShaderCombinaison *shader = 0;
	if(!shader) {
		shader = new ShaderCombinaison(new Shader<FragmentShader>(
			"uniform sampler2D n_0;"
			"in vec2 n_TexCoord;"
			"out float n_Out;"
			"uniform float scale;"

			"vec2 rescale(vec2 tex) {"
				"tex *= scale;"
				"vec2 h = vec2(0);  (0.5 / textureSize(n_0, 0));"
				"return tex * (1.0 - 2 * h) + h;"
			"}"

			"void main() {"
				"vec4 avgLum = textureGather(n_0, rescale(n_TexCoord), 0);"
				//"vec4 maxLum = textureGather(n_0, rescale(n_TexCoord), 1);"
				"n_Out.x = (avgLum.x + avgLum.y + avgLum.z + avgLum.w) * 0.25;"
				//"n_Out.y = max(max(maxLum.x, maxLum.y), max(maxLum.z, maxLum.w));"
			"}"), new Shader<VertexShader>(
			"layout(location = 0) in vec3 n_VertexPosition;"
			"layout(location = 3) in vec2 n_VertexCoord;"

			"uniform float scale;"

			"out vec2 n_TexCoord;"

			"void main() {"
				"vec3 vp = n_VertexPosition * 0.5 + 0.5;"
				"vp *= 0.5 * scale;"
				"vp = vp * 2.0 - 1.0;"
				"gl_Position = vec4(vp, 1.0);"
				"n_TexCoord = n_VertexCoord;"
			"}"));
	}
	return shader;
}

Texture computeLum(const Texture &in, FrameBuffer *buffers[]) {
	ShaderCombinaison *sh = getLogShader();
	sh->bind();
	sh->setValue("n_0", in);

	buffers[0]->bind();
	GLContext::getContext()->getScreen().draw(getMaterial(), VertexAttribs(), RenderFlag::NoShader);

	sh = getDSShader();
	sh->bind();

	float scale = 1.0;
	bool last = false;
	uint baseSize = buffers[0]->getSize().x();
	while(baseSize != 2) {
		sh->setValue("n_0", buffers[last]->getAttachement(0));
		sh->setValue("scale", scale);
		buffers[!last]->bind();
		last = !last;
		scale *= 0.5;
		baseSize /= 2;
		GLContext::getContext()->getScreen().draw(getMaterial(), VertexAttribs(), RenderFlag::NoShader);
	}
	return buffers[last]->getAttachement(0);
}

ToneMapRenderer::ToneMapRenderer(BufferedRenderer *c, uint s) : BufferableRenderer(), child(c), slot(s), exposure(0.1), white(1.5), range(0.055, 10000), debug(false) {
}

ToneMapRenderer::~ToneMapRenderer() {
}

void *ToneMapRenderer::prepare() {
	return child->prepare();
}

void ToneMapRenderer::render(void *ptr) {
	const FrameBuffer *fb = GLContext::getContext()->getFrameBuffer();
	child->render(ptr);

	uint ls = core::log2ui(child->getSize().min());
	math::Vec2ui size = math::Vec2ui(1 << ls);
	FrameBuffer *buffers[] = {GLContext::getContext()->getFrameBufferPool().get(size, false, ImageFormat::R32F),
							  GLContext::getContext()->getFrameBufferPool().get(size, false, ImageFormat::R32F)};

	Texture lum = computeLum(child->getFrameBuffer().getAttachement(slot), buffers);

	if(fb) {
		fb->bind();
	} else {
		FrameBuffer::unbind();
	}

	ShaderCombinaison *sh = getToneShader(debug);
	sh->bind();
	sh->setValue("logMin", log(range.x()));
	sh->setValue("logMax", log(range.y()));
	sh->setValue("exposure", exposure);
	sh->setValue("white", white);

	sh->setValue("n_0", child->getFrameBuffer().getAttachement(slot));
	sh->setValue("n_1", lum);
	/*float lums[2] = { -1, -1 };
	gl::glGetTextureSubImage(lum.getHandle(), 0, 0, 0, 0, 1, 1, 1, GL_RG, GL_FLOAT, 2 * sizeof(float), lums);
	std::cout<<lum.getHandle()<<"  max = "<<lums[1]<<", avg = "<<exp(lums[0])<<std::endl;*/

	GLContext::getContext()->getScreen().draw(getMaterial(), VertexAttribs(), RenderFlag::NoShader);

	GLContext::getContext()->getFrameBufferPool().add(buffers[0]);
	GLContext::getContext()->getFrameBufferPool().add(buffers[1]);
}

}
}
<|endoftext|>


<commit_before>/*------------------------------------------------------------------------
* (The MIT License)
*
* Copyright (c) 2008-2011 Rhomobile, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* http://rhomobile.com
*------------------------------------------------------------------------*/

#include "net/AsyncHttp.h"
#include "common/StringConverter.h"
#include "net/URI.h"
#include "common/RhodesApp.h"
#include "common/RhoAppAdapter.h"

namespace rho
{
using namespace rho::common;
namespace net
{

IMPLEMENT_LOGCLASS(CAsyncHttp, "AsyncHttp");
CAsyncHttp* CAsyncHttp::m_pInstance = 0;

/*static*/ CAsyncHttp* CAsyncHttp::Create()
{
    if ( m_pInstance )
        return m_pInstance;

    m_pInstance = new CAsyncHttp( );
    return m_pInstance;
}

/*static*/void CAsyncHttp::Destroy()
{
    if ( m_pInstance )
        delete m_pInstance;

    m_pInstance = 0;
}

CAsyncHttp::CAsyncHttp() : CThreadQueue()
{
	CThreadQueue::setLogCategory(getLogCategory());

    setPollInterval(QUEUE_POLL_INTERVAL_INFINITE);
}

CAsyncHttp::~CAsyncHttp(void)
{
    stop(-1);
    LOG(INFO) + "Thread shutdown";
}

unsigned long CAsyncHttp::addHttpCommand(IQueueCommand* pCmd)
{
	if (((CHttpCommand*)pCmd)->m_strCallback.length()==0)
    {
        processCommandBase(pCmd);
        unsigned long ret = ((CHttpCommand*)pCmd)->getRetValue();
        delete pCmd;
        return ret;
    }

	CThreadQueue::addQueueCommand(pCmd);

	start(epLow);

    return ((CHttpCommand*)pCmd)->getRetValue();
}

void CAsyncHttp::cancelRequest(const char* szCallback)
{
    if (!szCallback || !*szCallback )
    {
        LOG(INFO) + "Cancel callback should not be empty. Use * for cancel all";
        return;
    }

    synchronized(getCommandLock());
    CHttpCommand* pCmd = (CHttpCommand*)getCurCommand();

    if ( pCmd != null && ( *szCallback == '*' || pCmd->m_strCallback.compare(szCallback) == 0) )
        pCmd->cancel();

    if ( *szCallback == '*' )
        getCommands().clear();
    else
    {
        for (int i = getCommands().size()-1; i >= 0; i--)
        {
            CHttpCommand* pCmd1 = (CHttpCommand*)getCommands().get(i);

            if ( pCmd1 != null && pCmd1->m_strCallback.compare(szCallback) == 0 )
                getCommands().remove(i);
        }

    }
}

void CAsyncHttp::processCommand(IQueueCommand* pCmd)
{
    ((CHttpCommand*)pCmd)->execute();
}

extern "C" void header_iter(const char* szName, const char* szValue, void* pHash)
{
    ((Hashtable<String,String>*)pHash)->put(szName, szValue);
}

CAsyncHttp::CHttpCommand::CHttpCommand(String strCmd, rho_param *p) : m_params(p)
{
    m_eCmd = translateCommand(strCmd);
    m_strCallback = m_params.getString("callback");
    m_strCallbackParams = m_params.getString("callback_param");

    m_params.getHash("headers", m_mapHeaders);

    if(m_params.has("ssl_verify_peer"))
        m_NetRequest.setSslVerifyPeer(m_params.getBool("ssl_verify_peer"));
}

void CAsyncHttp::CHttpCommand::execute()
{
    NetResponse resp;
    switch( m_eCmd )
    {
    case hcGet:
        resp = getNet().doRequest( m_params.getString("http_command", "GET").c_str(),
            m_params.getString("url"), m_params.getString("body"), null, &m_mapHeaders);
        break;
	case hcPost:
        resp = getNet().doRequest(m_params.getString("http_command", "POST").c_str(),
			m_params.getString("url"), m_params.getString("body"), null, &m_mapHeaders);
        break;

    case hcDownload:
        resp = getNet().pullFile(m_params.getString("url"), m_params.getString("filename"), null, &m_mapHeaders);
        break;

    case hcUpload:
        {
            VectorPtr<net::CMultipartItem*> arMultipartItems;

            CRhoParamArray arParams( m_params, "multipart");
            if ( arParams.size() > 0 )
            {
                for( int i = 0; i < arParams.size(); i++)
                {
                    CRhoParams oItem = arParams.getItem(i);

                    net::CMultipartItem* pItem = new net::CMultipartItem();
                    String strFilePath = oItem.getString("filename");
                    if ( strFilePath.length() == 0 )
                    {
                        pItem->m_strBody = oItem.getString("body");
                        pItem->m_strContentType = oItem.getString("content_type", "");
                    }
                    else
                    {
                        pItem->m_strFilePath = strFilePath;
                        pItem->m_strContentType = oItem.getString("content_type", "application/octet-stream");
                    }

                    pItem->m_strName = oItem.getString("name");
                    pItem->m_strFileName = oItem.getString("filename_base");
                    arMultipartItems.addElement(pItem);
                }
            }else
            {
                net::CMultipartItem* pItem = new net::CMultipartItem();
                pItem->m_strFilePath = m_params.getString("filename");
                pItem->m_strContentType = m_params.getString("file_content_type", "application/octet-stream");
                pItem->m_strName = m_params.getString("name");
                pItem->m_strFileName = m_params.getString("filename_base");
                arMultipartItems.addElement(pItem);

                String strBody = m_params.getString("body");
                if ( strBody.length() > 0 )
                {
                    net::CMultipartItem* pItem2 = new net::CMultipartItem();
                    pItem2->m_strBody = strBody;
                    pItem2->m_strContentType = m_mapHeaders.get("content-type");
                    arMultipartItems.addElement(pItem2);
                }
            }

            resp = getNet().pushMultipartData( m_params.getString("url"), arMultipartItems, null, &m_mapHeaders );
            break;
        }
    default: ;
    }

    if ( !m_NetRequest.isCancelled())
        callNotify(resp,0);

    m_params.free_params();
}

unsigned long CAsyncHttp::CHttpCommand::getRetValue()
{
	if ( m_strCallback.length() == 0 )
	{
		if(getLogCategory().getName() == "NO_LOGGING")
			return atoi(m_strResBody.c_str());
		else
			return rho_ruby_create_string(m_strResBody.c_str());
	}

    return rho_ruby_get_NIL();
}

String CAsyncHttp::CHttpCommand::makeHeadersString()
{
    String strRes = "";

    for ( Hashtable<String,String>::iterator it = m_mapHeaders.begin();  it != m_mapHeaders.end(); ++it )
    {
        if ( strRes.length() > 0)
            strRes += "&";

        strRes += "headers[";
        URI::urlEncode(it->first,strRes);
        strRes += "]=";
        URI::urlEncode(it->second,strRes);
    }

    return strRes;
}

void CAsyncHttp::CHttpCommand::callNotify(NetResponse& resp, int nError )
{
	m_strResBody = "rho_callback=1";
    m_strResBody += "&status=";
    if ( nError > 0 )
    {
    	m_strResBody += "error&error_code=" + nError;
    }else
    {
        if ( resp.isSuccess() )
        {
    	    m_strResBody += "ok";
            if ( resp.isResponseRecieved())
	            m_strResBody += "&http_error=" + convertToStringA(resp.getRespCode());
        }
        else
        {
    	    m_strResBody += "error&error_code=";
            m_strResBody += convertToStringA(RhoAppAdapter.getErrorFromResponse(resp));
            if ( resp.isResponseRecieved())
	            m_strResBody += "&http_error=" + convertToStringA(resp.getRespCode());
        }

        String cookies = resp.getCookies();
        if (cookies.length()>0)
            m_strResBody += "&cookies=" + URI::urlEncode(cookies);

        String strHeaders = makeHeadersString();
        if (strHeaders.length() > 0 )
            m_strResBody += "&" + strHeaders;

        m_strResBody += "&" + RHODESAPP().addCallbackObject(
            new CAsyncHttpResponse(resp, m_mapHeaders.get("content-type"), m_mapHeaders.get("content-encoding")), "body");
    }

    if ( m_strCallbackParams.length() > 0 )
        m_strResBody += "&" + m_strCallbackParams;

    if ( m_strCallback.length() > 0 )
    {
        String strFullUrl = m_NetRequest.resolveUrl(m_strCallback);
        LOG(TRACE) + "Callback:" + m_strCallback + "Result body: " + m_strResBody;
        getNet().pushData( strFullUrl, m_strResBody, null );
    }
}

CAsyncHttp::CAsyncHttpResponse::~CAsyncHttpResponse(){}

extern "C" VALUE rjson_tokener_parse(const char *str, char** pszError );
unsigned long CAsyncHttp::CAsyncHttpResponse::getObjectValue()
{
    if (m_NetResponse.isSuccess())
    {
        if ( m_strContentType.find("application/json") != String::npos && m_strContentEncoding.find("gzip") == String::npos)
        {
            char* szError = 0;
            unsigned long valBody = rjson_tokener_parse(m_NetResponse.getCharData(), &szError);
            if ( valBody != 0 )
                return valBody;

            LOG(ERROR) + "Incorrect json body.Error:" + (szError ? szError : "");
            if ( szError )
                free(szError);
        }
    }

    return rho_ruby_create_string_withlen2(m_NetResponse.getCharData(), m_NetResponse.getDataSize() );
}

} // namespace net
} // namespace rho

extern "C" {

using namespace rho::net;

void rho_asynchttp_cancel(const char* cancel_callback)
{
    if ( CAsyncHttp::getInstance() != null )
        CAsyncHttp::getInstance()->cancelRequest(cancel_callback);
}

unsigned long rho_asynchttp_request(const char* command, rho_param *p)
{
    CAsyncHttp::Create();

    return CAsyncHttp::getInstance()->addHttpCommand(new CAsyncHttp::CHttpCommand( command, p ));
}

}
<commit_msg>asynchttp: remove check for gzip<commit_after>/*------------------------------------------------------------------------
* (The MIT License)
*
* Copyright (c) 2008-2011 Rhomobile, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* http://rhomobile.com
*------------------------------------------------------------------------*/

#include "net/AsyncHttp.h"
#include "common/StringConverter.h"
#include "net/URI.h"
#include "common/RhodesApp.h"
#include "common/RhoAppAdapter.h"

namespace rho
{
using namespace rho::common;
namespace net
{

IMPLEMENT_LOGCLASS(CAsyncHttp, "AsyncHttp");
CAsyncHttp* CAsyncHttp::m_pInstance = 0;

/*static*/ CAsyncHttp* CAsyncHttp::Create()
{
    if ( m_pInstance )
        return m_pInstance;

    m_pInstance = new CAsyncHttp( );
    return m_pInstance;
}

/*static*/void CAsyncHttp::Destroy()
{
    if ( m_pInstance )
        delete m_pInstance;

    m_pInstance = 0;
}

CAsyncHttp::CAsyncHttp() : CThreadQueue()
{
	CThreadQueue::setLogCategory(getLogCategory());

    setPollInterval(QUEUE_POLL_INTERVAL_INFINITE);
}

CAsyncHttp::~CAsyncHttp(void)
{
    stop(-1);
    LOG(INFO) + "Thread shutdown";
}

unsigned long CAsyncHttp::addHttpCommand(IQueueCommand* pCmd)
{
	if (((CHttpCommand*)pCmd)->m_strCallback.length()==0)
    {
        processCommandBase(pCmd);
        unsigned long ret = ((CHttpCommand*)pCmd)->getRetValue();
        delete pCmd;
        return ret;
    }

	CThreadQueue::addQueueCommand(pCmd);

	start(epLow);

    return ((CHttpCommand*)pCmd)->getRetValue();
}

void CAsyncHttp::cancelRequest(const char* szCallback)
{
    if (!szCallback || !*szCallback )
    {
        LOG(INFO) + "Cancel callback should not be empty. Use * for cancel all";
        return;
    }

    synchronized(getCommandLock());
    CHttpCommand* pCmd = (CHttpCommand*)getCurCommand();

    if ( pCmd != null && ( *szCallback == '*' || pCmd->m_strCallback.compare(szCallback) == 0) )
        pCmd->cancel();

    if ( *szCallback == '*' )
        getCommands().clear();
    else
    {
        for (int i = getCommands().size()-1; i >= 0; i--)
        {
            CHttpCommand* pCmd1 = (CHttpCommand*)getCommands().get(i);

            if ( pCmd1 != null && pCmd1->m_strCallback.compare(szCallback) == 0 )
                getCommands().remove(i);
        }

    }
}

void CAsyncHttp::processCommand(IQueueCommand* pCmd)
{
    ((CHttpCommand*)pCmd)->execute();
}

extern "C" void header_iter(const char* szName, const char* szValue, void* pHash)
{
    ((Hashtable<String,String>*)pHash)->put(szName, szValue);
}

CAsyncHttp::CHttpCommand::CHttpCommand(String strCmd, rho_param *p) : m_params(p)
{
    m_eCmd = translateCommand(strCmd);
    m_strCallback = m_params.getString("callback");
    m_strCallbackParams = m_params.getString("callback_param");

    m_params.getHash("headers", m_mapHeaders);

    if(m_params.has("ssl_verify_peer"))
        m_NetRequest.setSslVerifyPeer(m_params.getBool("ssl_verify_peer"));
}

void CAsyncHttp::CHttpCommand::execute()
{
    NetResponse resp;
    switch( m_eCmd )
    {
    case hcGet:
        resp = getNet().doRequest( m_params.getString("http_command", "GET").c_str(),
            m_params.getString("url"), m_params.getString("body"), null, &m_mapHeaders);
        break;
	case hcPost:
        resp = getNet().doRequest(m_params.getString("http_command", "POST").c_str(),
			m_params.getString("url"), m_params.getString("body"), null, &m_mapHeaders);
        break;

    case hcDownload:
        resp = getNet().pullFile(m_params.getString("url"), m_params.getString("filename"), null, &m_mapHeaders);
        break;

    case hcUpload:
        {
            VectorPtr<net::CMultipartItem*> arMultipartItems;

            CRhoParamArray arParams( m_params, "multipart");
            if ( arParams.size() > 0 )
            {
                for( int i = 0; i < arParams.size(); i++)
                {
                    CRhoParams oItem = arParams.getItem(i);

                    net::CMultipartItem* pItem = new net::CMultipartItem();
                    String strFilePath = oItem.getString("filename");
                    if ( strFilePath.length() == 0 )
                    {
                        pItem->m_strBody = oItem.getString("body");
                        pItem->m_strContentType = oItem.getString("content_type", "");
                    }
                    else
                    {
                        pItem->m_strFilePath = strFilePath;
                        pItem->m_strContentType = oItem.getString("content_type", "application/octet-stream");
                    }

                    pItem->m_strName = oItem.getString("name");
                    pItem->m_strFileName = oItem.getString("filename_base");
                    arMultipartItems.addElement(pItem);
                }
            }else
            {
                net::CMultipartItem* pItem = new net::CMultipartItem();
                pItem->m_strFilePath = m_params.getString("filename");
                pItem->m_strContentType = m_params.getString("file_content_type", "application/octet-stream");
                pItem->m_strName = m_params.getString("name");
                pItem->m_strFileName = m_params.getString("filename_base");
                arMultipartItems.addElement(pItem);

                String strBody = m_params.getString("body");
                if ( strBody.length() > 0 )
                {
                    net::CMultipartItem* pItem2 = new net::CMultipartItem();
                    pItem2->m_strBody = strBody;
                    pItem2->m_strContentType = m_mapHeaders.get("content-type");
                    arMultipartItems.addElement(pItem2);
                }
            }

            resp = getNet().pushMultipartData( m_params.getString("url"), arMultipartItems, null, &m_mapHeaders );
            break;
        }
    default: ;
    }

    if ( !m_NetRequest.isCancelled())
        callNotify(resp,0);

    m_params.free_params();
}

unsigned long CAsyncHttp::CHttpCommand::getRetValue()
{
	if ( m_strCallback.length() == 0 )
	{
		if(getLogCategory().getName() == "NO_LOGGING")
			return atoi(m_strResBody.c_str());
		else
			return rho_ruby_create_string(m_strResBody.c_str());
	}

    return rho_ruby_get_NIL();
}

String CAsyncHttp::CHttpCommand::makeHeadersString()
{
    String strRes = "";

    for ( Hashtable<String,String>::iterator it = m_mapHeaders.begin();  it != m_mapHeaders.end(); ++it )
    {
        if ( strRes.length() > 0)
            strRes += "&";

        strRes += "headers[";
        URI::urlEncode(it->first,strRes);
        strRes += "]=";
        URI::urlEncode(it->second,strRes);
    }

    return strRes;
}

void CAsyncHttp::CHttpCommand::callNotify(NetResponse& resp, int nError )
{
	m_strResBody = "rho_callback=1";
    m_strResBody += "&status=";
    if ( nError > 0 )
    {
    	m_strResBody += "error&error_code=" + nError;
    }else
    {
        if ( resp.isSuccess() )
        {
    	    m_strResBody += "ok";
            if ( resp.isResponseRecieved())
	            m_strResBody += "&http_error=" + convertToStringA(resp.getRespCode());
        }
        else
        {
    	    m_strResBody += "error&error_code=";
            m_strResBody += convertToStringA(RhoAppAdapter.getErrorFromResponse(resp));
            if ( resp.isResponseRecieved())
	            m_strResBody += "&http_error=" + convertToStringA(resp.getRespCode());
        }

        String cookies = resp.getCookies();
        if (cookies.length()>0)
            m_strResBody += "&cookies=" + URI::urlEncode(cookies);

        String strHeaders = makeHeadersString();
        if (strHeaders.length() > 0 )
            m_strResBody += "&" + strHeaders;

        m_strResBody += "&" + RHODESAPP().addCallbackObject(
            new CAsyncHttpResponse(resp, m_mapHeaders.get("content-type"), m_mapHeaders.get("content-encoding")), "body");
    }

    if ( m_strCallbackParams.length() > 0 )
        m_strResBody += "&" + m_strCallbackParams;

    if ( m_strCallback.length() > 0 )
    {
        String strFullUrl = m_NetRequest.resolveUrl(m_strCallback);
        LOG(TRACE) + "Callback:" + m_strCallback + "Result body: " + m_strResBody;
        getNet().pushData( strFullUrl, m_strResBody, null );
    }
}

CAsyncHttp::CAsyncHttpResponse::~CAsyncHttpResponse(){}

extern "C" VALUE rjson_tokener_parse(const char *str, char** pszError );
unsigned long CAsyncHttp::CAsyncHttpResponse::getObjectValue()
{
    if (m_NetResponse.isSuccess())
    {
        if ( m_strContentType.find("application/json") != String::npos/* && m_strContentEncoding.find("gzip") == String::npos*/ )
        {
            char* szError = 0;
            unsigned long valBody = rjson_tokener_parse(m_NetResponse.getCharData(), &szError);
            if ( valBody != 0 )
                return valBody;

            LOG(ERROR) + "Incorrect json body.Error:" + (szError ? szError : "");
            if ( szError )
                free(szError);
        }
    }

    return rho_ruby_create_string_withlen2(m_NetResponse.getCharData(), m_NetResponse.getDataSize() );
}

} // namespace net
} // namespace rho

extern "C" {

using namespace rho::net;

void rho_asynchttp_cancel(const char* cancel_callback)
{
    if ( CAsyncHttp::getInstance() != null )
        CAsyncHttp::getInstance()->cancelRequest(cancel_callback);
}

unsigned long rho_asynchttp_request(const char* command, rho_param *p)
{
    CAsyncHttp::Create();

    return CAsyncHttp::getInstance()->addHttpCommand(new CAsyncHttp::CHttpCommand( command, p ));
}

}
<|endoftext|>


<commit_before>/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

#include "DexStructure.h"

#include <boost/algorithm/string/predicate.hpp>
#include <vector>

#include "DexClass.h"
#include "Util.h"

namespace {

struct PenaltyPattern {
  const char* suffix;
  unsigned penalty;

  PenaltyPattern(const char* str, unsigned penalty)
      : suffix(str), penalty(penalty) {}
};

const PenaltyPattern PENALTY_PATTERNS[] = {
    {"Layout;", 1500},
    {"View;", 1500},
    {"ViewGroup;", 1800},
    {"Activity;", 1500},
};

constexpr unsigned VTABLE_SLOT_SIZE = 4;
constexpr unsigned OBJECT_VTABLE = 48;
constexpr unsigned METHOD_SIZE = 52;
constexpr unsigned INSTANCE_FIELD_SIZE = 16;
constexpr unsigned MAX_METHOD_REFS = (1 << 16) - 1;
constexpr unsigned MAX_FIELD_REFS = (1 << 16) - 1;

bool matches_penalty(const char* str, unsigned* penalty) {
  for (auto const& pattern : PENALTY_PATTERNS) {
    if (boost::algorithm::ends_with(str, pattern.suffix)) {
      *penalty = pattern.penalty;
      return true;
    }
  }
  return false;
}

/**
 * Estimates the linear alloc space consumed by the class at runtime.
 */
unsigned estimate_linear_alloc(const DexClass* clazz) {
  unsigned lasize = 0;
  // VTable guesstimate. Technically we could do better here, but only so much.
  // Try to stay bug-compatible with DalvikStatsTool.
  if (!is_interface(clazz)) {
    unsigned vtablePenalty = OBJECT_VTABLE;
    if (!matches_penalty(clazz->get_type()->get_name()->c_str(),
                         &vtablePenalty) &&
        clazz->get_super_class() != nullptr) {

      // TODO: we could be redexing object some day... :)
      matches_penalty(clazz->get_super_class()->get_name()->c_str(),
                      &vtablePenalty);
    }
    lasize += vtablePenalty;
    lasize += clazz->get_vmethods().size() * VTABLE_SLOT_SIZE;
  }

  lasize += clazz->get_dmethods().size() * METHOD_SIZE;
  lasize += clazz->get_vmethods().size() * METHOD_SIZE;
  lasize += clazz->get_ifields().size() * INSTANCE_FIELD_SIZE;

  return lasize;
}

/**
 * Removes the elements of b from a. Runs in O(size(a)), so it works best if
 * size(a) << size(b).
 */
template <typename T>
std::unordered_set<T> set_difference(const std::unordered_set<T>& a,
                                     const std::unordered_set<T>& b) {
  std::unordered_set<T> result;
  for (auto& v : a) {
    if (!b.count(v)) {
      result.emplace(v);
    }
  }
  return result;
}

} // namespace

namespace interdex {

bool DexesStructure::add_class_to_current_dex(const MethodRefs& clazz_mrefs,
                                              const FieldRefs& clazz_frefs,
                                              DexClass* clazz) {
  always_assert_log(m_classes.count(clazz) == 0,
                    "Can't emit the same class twice!\n", SHOW(clazz));

  if (m_current_dex.add_class_if_fits(clazz_mrefs, clazz_frefs,
                                      m_linear_alloc_limit, clazz)) {
    update_stats(clazz_mrefs, clazz_frefs, clazz);
    m_classes.emplace(clazz);
    return true;
  }

  return false;
}

void DexesStructure::add_class_no_checks(const MethodRefs& clazz_mrefs,
                                         const FieldRefs& clazz_frefs,
                                         DexClass* clazz) {
  always_assert_log(m_classes.count(clazz) == 0,
                    "Can't emit the same class twice!\n", SHOW(clazz));

  auto laclazz = estimate_linear_alloc(clazz);
  m_current_dex.add_class_no_checks(clazz_mrefs, clazz_frefs, laclazz, clazz);
  m_classes.emplace(clazz);
  update_stats(clazz_mrefs, clazz_frefs, clazz);
}

DexClasses DexesStructure::end_dex(DexInfo dex_info) {
  m_info.num_dexes++;

  if (!dex_info.primary) {
    m_info.num_secondary_dexes++;
  }

  if (dex_info.coldstart) {
    m_info.num_coldstart_dexes++;
  }

  if (dex_info.extended) {
    m_info.num_extended_set_dexes++;
  }

  if (dex_info.mixed_mode) {
    m_info.num_mixed_mode_dexes++;
  }

  if (dex_info.scroll) {
    m_info.num_scroll_dexes++;
  }

  m_current_dex.check_refs_count();

  DexClasses all_classes = std::move(m_current_dex.take_all_classes());

  m_current_dex = DexStructure();
  return all_classes;
}

void DexesStructure::update_stats(const MethodRefs& clazz_mrefs,
                                  const FieldRefs& clazz_frefs,
                                  DexClass* clazz) {
  for (DexMethod* method : clazz->get_dmethods()) {
    if (is_static(method)) {
      m_stats.num_static_meths++;
    }
  }
  m_stats.num_dmethods += clazz->get_dmethods().size();
  m_stats.num_vmethods += clazz->get_vmethods().size();
  m_stats.num_mrefs += clazz_mrefs.size();
  m_stats.num_frefs += clazz_frefs.size();
}

bool DexStructure::add_class_if_fits(const MethodRefs& clazz_mrefs,
                                     const FieldRefs& clazz_frefs,
                                     size_t linear_alloc_limit,
                                     DexClass* clazz) {

  unsigned laclazz = estimate_linear_alloc(clazz);
  if (m_linear_alloc_size + laclazz > linear_alloc_limit) {
    TRACE(IDEX, 6,
          "[warning]: Class won't fit current dex since it will go "
          "over the linear alloc limit: %s\n",
          SHOW(clazz));
    return false;
  }

  auto extra_mrefs = set_difference(clazz_mrefs, m_mrefs);
  auto extra_frefs = set_difference(clazz_frefs, m_frefs);

  if (m_mrefs.size() + extra_mrefs.size() >= MAX_METHOD_REFS ||
      m_frefs.size() + extra_frefs.size() >= MAX_FIELD_REFS) {
    TRACE(IDEX, 6,
          "[warning]: Class won't fit current dex since it will go "
          "over the method or field refs limit: %d / %d : %s\n",
          m_mrefs.size() + extra_mrefs.size(),
          m_frefs.size() + extra_frefs.size(), SHOW(clazz));
    return false;
  }

  add_class_no_checks(clazz_mrefs, clazz_frefs, laclazz, clazz);
  return true;
}

void DexStructure::add_class_no_checks(const MethodRefs& clazz_mrefs,
                                       const FieldRefs& clazz_frefs,
                                       unsigned laclazz,
                                       DexClass* clazz) {
  TRACE(IDEX, 7, "Adding class: %s\n", SHOW(clazz));
  m_mrefs.insert(clazz_mrefs.begin(), clazz_mrefs.end());
  m_frefs.insert(clazz_frefs.begin(), clazz_frefs.end());
  m_linear_alloc_size += laclazz;
  m_classes.push_back(clazz);
}

/*
 * Sanity check: did gather_refs return all the refs that ultimately ended up
 * in the dex?
 */
void DexStructure::check_refs_count() {
  std::vector<DexMethodRef*> mrefs;
  for (DexClass* cls : m_classes) {
    cls->gather_methods(mrefs);
  }
  std::unordered_set<DexMethodRef*> mrefs_set(mrefs.begin(), mrefs.end());
  if (mrefs_set.size() > m_mrefs.size()) {
    for (DexMethodRef* mr : mrefs_set) {
      if (!m_mrefs.count(mr)) {
        TRACE(IDEX, 4, "WARNING: Could not find %s in predicted mrefs set\n",
              SHOW(mr));
      }
    }
  }

  std::vector<DexFieldRef*> frefs;
  for (DexClass* cls : m_classes) {
    cls->gather_fields(frefs);
  }
  std::unordered_set<DexFieldRef*> frefs_set(frefs.begin(), frefs.end());
  if (frefs_set.size() > m_frefs.size()) {
    for (auto* fr : frefs_set) {
      if (!m_frefs.count(fr)) {
        TRACE(IDEX, 4, "WARNING: Could not find %s in predicted frefs set\n",
              SHOW(fr));
      }
    }
  }

  // TODO: do we need to re-check linear_alloc_limit?
}

} // namespace interdex
<commit_msg>Emit class when duplicated<commit_after>/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

#include "DexStructure.h"

#include <boost/algorithm/string/predicate.hpp>
#include <vector>

#include "DexClass.h"
#include "Util.h"

namespace {

struct PenaltyPattern {
  const char* suffix;
  unsigned penalty;

  PenaltyPattern(const char* str, unsigned penalty)
      : suffix(str), penalty(penalty) {}
};

const PenaltyPattern PENALTY_PATTERNS[] = {
    {"Layout;", 1500},
    {"View;", 1500},
    {"ViewGroup;", 1800},
    {"Activity;", 1500},
};

constexpr unsigned VTABLE_SLOT_SIZE = 4;
constexpr unsigned OBJECT_VTABLE = 48;
constexpr unsigned METHOD_SIZE = 52;
constexpr unsigned INSTANCE_FIELD_SIZE = 16;
constexpr unsigned MAX_METHOD_REFS = (1 << 16) - 1;
constexpr unsigned MAX_FIELD_REFS = (1 << 16) - 1;

bool matches_penalty(const char* str, unsigned* penalty) {
  for (auto const& pattern : PENALTY_PATTERNS) {
    if (boost::algorithm::ends_with(str, pattern.suffix)) {
      *penalty = pattern.penalty;
      return true;
    }
  }
  return false;
}

/**
 * Estimates the linear alloc space consumed by the class at runtime.
 */
unsigned estimate_linear_alloc(const DexClass* clazz) {
  unsigned lasize = 0;
  // VTable guesstimate. Technically we could do better here, but only so much.
  // Try to stay bug-compatible with DalvikStatsTool.
  if (!is_interface(clazz)) {
    unsigned vtablePenalty = OBJECT_VTABLE;
    if (!matches_penalty(clazz->get_type()->get_name()->c_str(),
                         &vtablePenalty) &&
        clazz->get_super_class() != nullptr) {

      // TODO: we could be redexing object some day... :)
      matches_penalty(clazz->get_super_class()->get_name()->c_str(),
                      &vtablePenalty);
    }
    lasize += vtablePenalty;
    lasize += clazz->get_vmethods().size() * VTABLE_SLOT_SIZE;
  }

  lasize += clazz->get_dmethods().size() * METHOD_SIZE;
  lasize += clazz->get_vmethods().size() * METHOD_SIZE;
  lasize += clazz->get_ifields().size() * INSTANCE_FIELD_SIZE;

  return lasize;
}

/**
 * Removes the elements of b from a. Runs in O(size(a)), so it works best if
 * size(a) << size(b).
 */
template <typename T>
std::unordered_set<T> set_difference(const std::unordered_set<T>& a,
                                     const std::unordered_set<T>& b) {
  std::unordered_set<T> result;
  for (auto& v : a) {
    if (!b.count(v)) {
      result.emplace(v);
    }
  }
  return result;
}

} // namespace

namespace interdex {

bool DexesStructure::add_class_to_current_dex(const MethodRefs& clazz_mrefs,
                                              const FieldRefs& clazz_frefs,
                                              DexClass* clazz) {
  always_assert_log(m_classes.count(clazz) == 0,
                    "Can't emit the same class twice!\n", SHOW(clazz));

  if (m_current_dex.add_class_if_fits(clazz_mrefs, clazz_frefs,
                                      m_linear_alloc_limit, clazz)) {
    update_stats(clazz_mrefs, clazz_frefs, clazz);
    m_classes.emplace(clazz);
    return true;
  }

  return false;
}

void DexesStructure::add_class_no_checks(const MethodRefs& clazz_mrefs,
                                         const FieldRefs& clazz_frefs,
                                         DexClass* clazz) {
  always_assert_log(m_classes.count(clazz) == 0,
                    "Can't emit the same class twice: %s!\n", SHOW(clazz));

  auto laclazz = estimate_linear_alloc(clazz);
  m_current_dex.add_class_no_checks(clazz_mrefs, clazz_frefs, laclazz, clazz);
  m_classes.emplace(clazz);
  update_stats(clazz_mrefs, clazz_frefs, clazz);
}

DexClasses DexesStructure::end_dex(DexInfo dex_info) {
  m_info.num_dexes++;

  if (!dex_info.primary) {
    m_info.num_secondary_dexes++;
  }

  if (dex_info.coldstart) {
    m_info.num_coldstart_dexes++;
  }

  if (dex_info.extended) {
    m_info.num_extended_set_dexes++;
  }

  if (dex_info.mixed_mode) {
    m_info.num_mixed_mode_dexes++;
  }

  if (dex_info.scroll) {
    m_info.num_scroll_dexes++;
  }

  m_current_dex.check_refs_count();

  DexClasses all_classes = std::move(m_current_dex.take_all_classes());

  m_current_dex = DexStructure();
  return all_classes;
}

void DexesStructure::update_stats(const MethodRefs& clazz_mrefs,
                                  const FieldRefs& clazz_frefs,
                                  DexClass* clazz) {
  for (DexMethod* method : clazz->get_dmethods()) {
    if (is_static(method)) {
      m_stats.num_static_meths++;
    }
  }
  m_stats.num_dmethods += clazz->get_dmethods().size();
  m_stats.num_vmethods += clazz->get_vmethods().size();
  m_stats.num_mrefs += clazz_mrefs.size();
  m_stats.num_frefs += clazz_frefs.size();
}

bool DexStructure::add_class_if_fits(const MethodRefs& clazz_mrefs,
                                     const FieldRefs& clazz_frefs,
                                     size_t linear_alloc_limit,
                                     DexClass* clazz) {

  unsigned laclazz = estimate_linear_alloc(clazz);
  if (m_linear_alloc_size + laclazz > linear_alloc_limit) {
    TRACE(IDEX, 6,
          "[warning]: Class won't fit current dex since it will go "
          "over the linear alloc limit: %s\n",
          SHOW(clazz));
    return false;
  }

  auto extra_mrefs = set_difference(clazz_mrefs, m_mrefs);
  auto extra_frefs = set_difference(clazz_frefs, m_frefs);

  if (m_mrefs.size() + extra_mrefs.size() >= MAX_METHOD_REFS ||
      m_frefs.size() + extra_frefs.size() >= MAX_FIELD_REFS) {
    TRACE(IDEX, 6,
          "[warning]: Class won't fit current dex since it will go "
          "over the method or field refs limit: %d / %d : %s\n",
          m_mrefs.size() + extra_mrefs.size(),
          m_frefs.size() + extra_frefs.size(), SHOW(clazz));
    return false;
  }

  add_class_no_checks(clazz_mrefs, clazz_frefs, laclazz, clazz);
  return true;
}

void DexStructure::add_class_no_checks(const MethodRefs& clazz_mrefs,
                                       const FieldRefs& clazz_frefs,
                                       unsigned laclazz,
                                       DexClass* clazz) {
  TRACE(IDEX, 7, "Adding class: %s\n", SHOW(clazz));
  m_mrefs.insert(clazz_mrefs.begin(), clazz_mrefs.end());
  m_frefs.insert(clazz_frefs.begin(), clazz_frefs.end());
  m_linear_alloc_size += laclazz;
  m_classes.push_back(clazz);
}

/*
 * Sanity check: did gather_refs return all the refs that ultimately ended up
 * in the dex?
 */
void DexStructure::check_refs_count() {
  std::vector<DexMethodRef*> mrefs;
  for (DexClass* cls : m_classes) {
    cls->gather_methods(mrefs);
  }
  std::unordered_set<DexMethodRef*> mrefs_set(mrefs.begin(), mrefs.end());
  if (mrefs_set.size() > m_mrefs.size()) {
    for (DexMethodRef* mr : mrefs_set) {
      if (!m_mrefs.count(mr)) {
        TRACE(IDEX, 4, "WARNING: Could not find %s in predicted mrefs set\n",
              SHOW(mr));
      }
    }
  }

  std::vector<DexFieldRef*> frefs;
  for (DexClass* cls : m_classes) {
    cls->gather_fields(frefs);
  }
  std::unordered_set<DexFieldRef*> frefs_set(frefs.begin(), frefs.end());
  if (frefs_set.size() > m_frefs.size()) {
    for (auto* fr : frefs_set) {
      if (!m_frefs.count(fr)) {
        TRACE(IDEX, 4, "WARNING: Could not find %s in predicted frefs set\n",
              SHOW(fr));
      }
    }
  }

  // TODO: do we need to re-check linear_alloc_limit?
}

} // namespace interdex
<|endoftext|>


<commit_before>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: doctemplateslocal.cxx,v $
 * $Revision: 1.4 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sfx2.hxx"

#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_
#include <com/sun/star/beans/StringPair.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#endif
#ifndef _COM_SUN_STAR_IO_XACTIVEDATASOURCE_HPP
#include <com/sun/star/io/XActiveDataSource.hpp>
#endif
#ifndef _COM_SUN_STAR_XML_SAX_XPARSER_HPP
#include <com/sun/star/xml/sax/XParser.hpp>
#endif
#ifndef _COM_SUN_STAR_XML_SAX_XDOCUMENTHANDLER_HPP
#include <com/sun/star/xml/sax/XDocumentHandler.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_ILLEGALARGUMENTEXCEPTION_HPP
#include <com/sun/star/lang/IllegalArgumentException.hpp>
#endif

#include "doctemplateslocal.hxx"
#include "attributelist.hxx"

using namespace ::com::sun::star;

// -----------------------------------
uno::Sequence< beans::StringPair > DocTemplLocaleHelper::ReadGroupLocalizationSequence( const uno::Reference< io::XInputStream >& xInStream, const uno::Reference< lang::XMultiServiceFactory > xFactory )
    throw( uno::Exception )
{
    ::rtl::OUString aStringID = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "groupuinames.xml" ) );
    return ReadLocalizationSequence_Impl( xInStream, aStringID, xFactory );
}

// -----------------------------------
void SAL_CALL DocTemplLocaleHelper::WriteGroupLocalizationSequence( const uno::Reference< io::XOutputStream >& xOutStream, const uno::Sequence< beans::StringPair >& aSequence, const uno::Reference< lang::XMultiServiceFactory > xFactory )
    throw( uno::Exception )
{
    if ( !xOutStream.is() )
        throw uno::RuntimeException();

    uno::Reference< io::XActiveDataSource > xWriterSource(
        xFactory->createInstance(
            ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.xml.sax.Writer" ) ) ),
        uno::UNO_QUERY_THROW );
    uno::Reference< xml::sax::XDocumentHandler > xWriterHandler( xWriterSource, uno::UNO_QUERY_THROW );

    xWriterSource->setOutputStream( xOutStream );

    ::rtl::OUString aGroupListElement( RTL_CONSTASCII_USTRINGPARAM( "groupuinames:template-group-list" ) );
    ::rtl::OUString aGroupElement( RTL_CONSTASCII_USTRINGPARAM( "groupuinames:template-group" ) );
    ::rtl::OUString aNameAttr( RTL_CONSTASCII_USTRINGPARAM( "groupuinames:name" ) );
    ::rtl::OUString aUINameAttr( RTL_CONSTASCII_USTRINGPARAM( "groupuinames:default-ui-name" ) );
    ::rtl::OUString aCDATAString( RTL_CONSTASCII_USTRINGPARAM ( "CDATA" ) );
    ::rtl::OUString aWhiteSpace( RTL_CONSTASCII_USTRINGPARAM ( " " ) );

    // write the namespace
    AttributeList* pRootAttrList = new AttributeList;
    uno::Reference< xml::sax::XAttributeList > xRootAttrList( pRootAttrList );
    pRootAttrList->AddAttribute(
        ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "xmlns" ) ),
        aCDATAString,
        ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "http://openoffice.org/2006/groupuinames" ) ) );

    xWriterHandler->startDocument();
    xWriterHandler->startElement( aGroupListElement, xRootAttrList );

    for ( sal_Int32 nInd = 0; nInd < aSequence.getLength(); nInd++ )
    {
        AttributeList *pAttrList = new AttributeList;
        uno::Reference< xml::sax::XAttributeList > xAttrList( pAttrList );
        pAttrList->AddAttribute( aNameAttr, aCDATAString, aSequence[nInd].First );
        pAttrList->AddAttribute( aUINameAttr, aCDATAString, aSequence[nInd].Second );

        xWriterHandler->startElement( aGroupElement, xAttrList );
        xWriterHandler->ignorableWhitespace( aWhiteSpace );
        xWriterHandler->endElement( aGroupElement );
    }

    xWriterHandler->ignorableWhitespace( aWhiteSpace );
    xWriterHandler->endElement( aGroupListElement );
    xWriterHandler->endDocument();
}

// ==================================================================================

// -----------------------------------
uno::Sequence< beans::StringPair > SAL_CALL DocTemplLocaleHelper::ReadLocalizationSequence_Impl( const uno::Reference< io::XInputStream >& xInStream, const ::rtl::OUString& aStringID, const uno::Reference< lang::XMultiServiceFactory > xFactory )
    throw( uno::Exception )
{
    if ( !xFactory.is() || !xInStream.is() )
        throw uno::RuntimeException();

    uno::Sequence< beans::StringPair > aResult;

    uno::Reference< xml::sax::XParser > xParser( xFactory->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.xml.sax.Parser" ) ) ), uno::UNO_QUERY_THROW );

    DocTemplLocaleHelper* pHelper = new DocTemplLocaleHelper();
    uno::Reference< xml::sax::XDocumentHandler > xHelper( static_cast< xml::sax::XDocumentHandler* >( pHelper ) );
    xml::sax::InputSource aParserInput;
    aParserInput.aInputStream = xInStream;
    aParserInput.sSystemId = aStringID;
    xParser->setDocumentHandler( xHelper );
    xParser->parseStream( aParserInput );
    xParser->setDocumentHandler( uno::Reference < xml::sax::XDocumentHandler > () );

    return pHelper->GetParsingResult();
}

// -----------------------------------
DocTemplLocaleHelper::DocTemplLocaleHelper()
: m_aGroupListElement( RTL_CONSTASCII_USTRINGPARAM( "groupuinames:template-group-list" ) )
, m_aGroupElement( RTL_CONSTASCII_USTRINGPARAM( "groupuinames:template-group" ) )
, m_aNameAttr( RTL_CONSTASCII_USTRINGPARAM( "groupuinames:name" ) )
, m_aUINameAttr( RTL_CONSTASCII_USTRINGPARAM( "groupuinames:default-ui-name" ) )
{
}

// -----------------------------------
DocTemplLocaleHelper::~DocTemplLocaleHelper()
{
}

// -----------------------------------
uno::Sequence< beans::StringPair > DocTemplLocaleHelper::GetParsingResult()
{
    if ( m_aElementsSeq.getLength() )
        throw uno::RuntimeException(); // the parsing has still not finished!

    return m_aResultSeq;
}

// -----------------------------------
void SAL_CALL DocTemplLocaleHelper::startDocument()
        throw(xml::sax::SAXException, uno::RuntimeException)
{
}

// -----------------------------------
void SAL_CALL DocTemplLocaleHelper::endDocument()
        throw(xml::sax::SAXException, uno::RuntimeException)
{
}

// -----------------------------------
void SAL_CALL DocTemplLocaleHelper::startElement( const ::rtl::OUString& aName, const uno::Reference< xml::sax::XAttributeList >& xAttribs )
        throw( xml::sax::SAXException, uno::RuntimeException )
{
    if ( aName == m_aGroupListElement )
    {
        sal_Int32 nNewLength = m_aElementsSeq.getLength() + 1;

        if ( nNewLength != 1 )
            throw xml::sax::SAXException(); // TODO: this element must be the first level element

        m_aElementsSeq.realloc( nNewLength );
        m_aElementsSeq[nNewLength-1] = aName;

        return; // nothing to do
    }
    else if ( aName == m_aGroupElement )
    {
        sal_Int32 nNewLength = m_aElementsSeq.getLength() + 1;
        if ( nNewLength != 2 )
            throw xml::sax::SAXException(); // TODO: this element must be the second level element

        m_aElementsSeq.realloc( nNewLength );
        m_aElementsSeq[nNewLength-1] = aName;

        sal_Int32 nNewEntryNum = m_aResultSeq.getLength() + 1;
        m_aResultSeq.realloc( nNewEntryNum );

        ::rtl::OUString aNameValue = xAttribs->getValueByName( m_aNameAttr );
        if ( !aNameValue.getLength() )
            throw xml::sax::SAXException(); // TODO: the ID value must present

        ::rtl::OUString aUINameValue = xAttribs->getValueByName( m_aUINameAttr );
        if ( !aUINameValue.getLength() )
            throw xml::sax::SAXException(); // TODO: the ID value must present

        m_aResultSeq[nNewEntryNum-1].First = aNameValue;
        m_aResultSeq[nNewEntryNum-1].Second = aUINameValue;
    }
    else
    {
        // accept future extensions
        sal_Int32 nNewLength = m_aElementsSeq.getLength() + 1;

        if ( !nNewLength )
            throw xml::sax::SAXException(); // TODO: the extension element must not be the first level element

        m_aElementsSeq.realloc( nNewLength );
        m_aElementsSeq[nNewLength-1] = aName;
    }
}

// -----------------------------------
void SAL_CALL DocTemplLocaleHelper::endElement( const ::rtl::OUString& aName )
    throw( xml::sax::SAXException, uno::RuntimeException )
{
    sal_Int32 nLength = m_aElementsSeq.getLength();
    if ( nLength <= 0 )
        throw xml::sax::SAXException(); // TODO: no other end elements expected!

    if ( !m_aElementsSeq[nLength-1].equals( aName ) )
        throw xml::sax::SAXException(); // TODO: unexpected element ended

    m_aElementsSeq.realloc( nLength - 1 );
}

// -----------------------------------
void SAL_CALL DocTemplLocaleHelper::characters( const ::rtl::OUString& /*aChars*/ )
        throw(xml::sax::SAXException, uno::RuntimeException)
{
}

// -----------------------------------
void SAL_CALL DocTemplLocaleHelper::ignorableWhitespace( const ::rtl::OUString& /*aWhitespaces*/ )
        throw(xml::sax::SAXException, uno::RuntimeException)
{
}

// -----------------------------------
void SAL_CALL DocTemplLocaleHelper::processingInstruction( const ::rtl::OUString& /*aTarget*/, const ::rtl::OUString& /*aData*/ )
        throw(xml::sax::SAXException, uno::RuntimeException)
{
}

// -----------------------------------
void SAL_CALL DocTemplLocaleHelper::setDocumentLocator( const uno::Reference< xml::sax::XLocator >& /*xLocator*/ )
        throw(xml::sax::SAXException, uno::RuntimeException)
{
}

<commit_msg>INTEGRATION: CWS xmlfix2 (1.3.428); FILE MERGED 2008/05/15 17:28:01 mst 1.3.428.2: RESYNC: (1.3-1.4); FILE MERGED 2008/03/31 15:14:12 mst 1.3.428.1: remove duplicated XAttributeList implementations - sfx2/source/doc/attributelist.{hxx,cxx}:   + removed - sfx2/source/doc/makefile.mk:   + remove attributelist.cxx - sfx2/source/doc/doctemplateslocal.cxx:   + use comphelper/attributelist.hxx<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: doctemplateslocal.cxx,v $
 * $Revision: 1.5 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sfx2.hxx"

#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_
#include <com/sun/star/beans/StringPair.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#endif
#ifndef _COM_SUN_STAR_IO_XACTIVEDATASOURCE_HPP
#include <com/sun/star/io/XActiveDataSource.hpp>
#endif
#ifndef _COM_SUN_STAR_XML_SAX_XPARSER_HPP
#include <com/sun/star/xml/sax/XParser.hpp>
#endif
#ifndef _COM_SUN_STAR_XML_SAX_XDOCUMENTHANDLER_HPP
#include <com/sun/star/xml/sax/XDocumentHandler.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_ILLEGALARGUMENTEXCEPTION_HPP
#include <com/sun/star/lang/IllegalArgumentException.hpp>
#endif

#include <comphelper/attributelist.hxx>

#include "doctemplateslocal.hxx"

using namespace ::com::sun::star;

// -----------------------------------
uno::Sequence< beans::StringPair > DocTemplLocaleHelper::ReadGroupLocalizationSequence( const uno::Reference< io::XInputStream >& xInStream, const uno::Reference< lang::XMultiServiceFactory > xFactory )
    throw( uno::Exception )
{
    ::rtl::OUString aStringID = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "groupuinames.xml" ) );
    return ReadLocalizationSequence_Impl( xInStream, aStringID, xFactory );
}

// -----------------------------------
void SAL_CALL DocTemplLocaleHelper::WriteGroupLocalizationSequence( const uno::Reference< io::XOutputStream >& xOutStream, const uno::Sequence< beans::StringPair >& aSequence, const uno::Reference< lang::XMultiServiceFactory > xFactory )
    throw( uno::Exception )
{
    if ( !xOutStream.is() )
        throw uno::RuntimeException();

    uno::Reference< io::XActiveDataSource > xWriterSource(
        xFactory->createInstance(
            ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.xml.sax.Writer" ) ) ),
        uno::UNO_QUERY_THROW );
    uno::Reference< xml::sax::XDocumentHandler > xWriterHandler( xWriterSource, uno::UNO_QUERY_THROW );

    xWriterSource->setOutputStream( xOutStream );

    ::rtl::OUString aGroupListElement( RTL_CONSTASCII_USTRINGPARAM( "groupuinames:template-group-list" ) );
    ::rtl::OUString aGroupElement( RTL_CONSTASCII_USTRINGPARAM( "groupuinames:template-group" ) );
    ::rtl::OUString aNameAttr( RTL_CONSTASCII_USTRINGPARAM( "groupuinames:name" ) );
    ::rtl::OUString aUINameAttr( RTL_CONSTASCII_USTRINGPARAM( "groupuinames:default-ui-name" ) );
    ::rtl::OUString aCDATAString( RTL_CONSTASCII_USTRINGPARAM ( "CDATA" ) );
    ::rtl::OUString aWhiteSpace( RTL_CONSTASCII_USTRINGPARAM ( " " ) );

    // write the namespace
    ::comphelper::AttributeList* pRootAttrList = new ::comphelper::AttributeList;
    uno::Reference< xml::sax::XAttributeList > xRootAttrList( pRootAttrList );
    pRootAttrList->AddAttribute(
        ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "xmlns" ) ),
        aCDATAString,
        ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "http://openoffice.org/2006/groupuinames" ) ) );

    xWriterHandler->startDocument();
    xWriterHandler->startElement( aGroupListElement, xRootAttrList );

    for ( sal_Int32 nInd = 0; nInd < aSequence.getLength(); nInd++ )
    {
        ::comphelper::AttributeList *pAttrList = new ::comphelper::AttributeList;
        uno::Reference< xml::sax::XAttributeList > xAttrList( pAttrList );
        pAttrList->AddAttribute( aNameAttr, aCDATAString, aSequence[nInd].First );
        pAttrList->AddAttribute( aUINameAttr, aCDATAString, aSequence[nInd].Second );

        xWriterHandler->startElement( aGroupElement, xAttrList );
        xWriterHandler->ignorableWhitespace( aWhiteSpace );
        xWriterHandler->endElement( aGroupElement );
    }

    xWriterHandler->ignorableWhitespace( aWhiteSpace );
    xWriterHandler->endElement( aGroupListElement );
    xWriterHandler->endDocument();
}

// ==================================================================================

// -----------------------------------
uno::Sequence< beans::StringPair > SAL_CALL DocTemplLocaleHelper::ReadLocalizationSequence_Impl( const uno::Reference< io::XInputStream >& xInStream, const ::rtl::OUString& aStringID, const uno::Reference< lang::XMultiServiceFactory > xFactory )
    throw( uno::Exception )
{
    if ( !xFactory.is() || !xInStream.is() )
        throw uno::RuntimeException();

    uno::Sequence< beans::StringPair > aResult;

    uno::Reference< xml::sax::XParser > xParser( xFactory->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.xml.sax.Parser" ) ) ), uno::UNO_QUERY_THROW );

    DocTemplLocaleHelper* pHelper = new DocTemplLocaleHelper();
    uno::Reference< xml::sax::XDocumentHandler > xHelper( static_cast< xml::sax::XDocumentHandler* >( pHelper ) );
    xml::sax::InputSource aParserInput;
    aParserInput.aInputStream = xInStream;
    aParserInput.sSystemId = aStringID;
    xParser->setDocumentHandler( xHelper );
    xParser->parseStream( aParserInput );
    xParser->setDocumentHandler( uno::Reference < xml::sax::XDocumentHandler > () );

    return pHelper->GetParsingResult();
}

// -----------------------------------
DocTemplLocaleHelper::DocTemplLocaleHelper()
: m_aGroupListElement( RTL_CONSTASCII_USTRINGPARAM( "groupuinames:template-group-list" ) )
, m_aGroupElement( RTL_CONSTASCII_USTRINGPARAM( "groupuinames:template-group" ) )
, m_aNameAttr( RTL_CONSTASCII_USTRINGPARAM( "groupuinames:name" ) )
, m_aUINameAttr( RTL_CONSTASCII_USTRINGPARAM( "groupuinames:default-ui-name" ) )
{
}

// -----------------------------------
DocTemplLocaleHelper::~DocTemplLocaleHelper()
{
}

// -----------------------------------
uno::Sequence< beans::StringPair > DocTemplLocaleHelper::GetParsingResult()
{
    if ( m_aElementsSeq.getLength() )
        throw uno::RuntimeException(); // the parsing has still not finished!

    return m_aResultSeq;
}

// -----------------------------------
void SAL_CALL DocTemplLocaleHelper::startDocument()
        throw(xml::sax::SAXException, uno::RuntimeException)
{
}

// -----------------------------------
void SAL_CALL DocTemplLocaleHelper::endDocument()
        throw(xml::sax::SAXException, uno::RuntimeException)
{
}

// -----------------------------------
void SAL_CALL DocTemplLocaleHelper::startElement( const ::rtl::OUString& aName, const uno::Reference< xml::sax::XAttributeList >& xAttribs )
        throw( xml::sax::SAXException, uno::RuntimeException )
{
    if ( aName == m_aGroupListElement )
    {
        sal_Int32 nNewLength = m_aElementsSeq.getLength() + 1;

        if ( nNewLength != 1 )
            throw xml::sax::SAXException(); // TODO: this element must be the first level element

        m_aElementsSeq.realloc( nNewLength );
        m_aElementsSeq[nNewLength-1] = aName;

        return; // nothing to do
    }
    else if ( aName == m_aGroupElement )
    {
        sal_Int32 nNewLength = m_aElementsSeq.getLength() + 1;
        if ( nNewLength != 2 )
            throw xml::sax::SAXException(); // TODO: this element must be the second level element

        m_aElementsSeq.realloc( nNewLength );
        m_aElementsSeq[nNewLength-1] = aName;

        sal_Int32 nNewEntryNum = m_aResultSeq.getLength() + 1;
        m_aResultSeq.realloc( nNewEntryNum );

        ::rtl::OUString aNameValue = xAttribs->getValueByName( m_aNameAttr );
        if ( !aNameValue.getLength() )
            throw xml::sax::SAXException(); // TODO: the ID value must present

        ::rtl::OUString aUINameValue = xAttribs->getValueByName( m_aUINameAttr );
        if ( !aUINameValue.getLength() )
            throw xml::sax::SAXException(); // TODO: the ID value must present

        m_aResultSeq[nNewEntryNum-1].First = aNameValue;
        m_aResultSeq[nNewEntryNum-1].Second = aUINameValue;
    }
    else
    {
        // accept future extensions
        sal_Int32 nNewLength = m_aElementsSeq.getLength() + 1;

        if ( !nNewLength )
            throw xml::sax::SAXException(); // TODO: the extension element must not be the first level element

        m_aElementsSeq.realloc( nNewLength );
        m_aElementsSeq[nNewLength-1] = aName;
    }
}

// -----------------------------------
void SAL_CALL DocTemplLocaleHelper::endElement( const ::rtl::OUString& aName )
    throw( xml::sax::SAXException, uno::RuntimeException )
{
    sal_Int32 nLength = m_aElementsSeq.getLength();
    if ( nLength <= 0 )
        throw xml::sax::SAXException(); // TODO: no other end elements expected!

    if ( !m_aElementsSeq[nLength-1].equals( aName ) )
        throw xml::sax::SAXException(); // TODO: unexpected element ended

    m_aElementsSeq.realloc( nLength - 1 );
}

// -----------------------------------
void SAL_CALL DocTemplLocaleHelper::characters( const ::rtl::OUString& /*aChars*/ )
        throw(xml::sax::SAXException, uno::RuntimeException)
{
}

// -----------------------------------
void SAL_CALL DocTemplLocaleHelper::ignorableWhitespace( const ::rtl::OUString& /*aWhitespaces*/ )
        throw(xml::sax::SAXException, uno::RuntimeException)
{
}

// -----------------------------------
void SAL_CALL DocTemplLocaleHelper::processingInstruction( const ::rtl::OUString& /*aTarget*/, const ::rtl::OUString& /*aData*/ )
        throw(xml::sax::SAXException, uno::RuntimeException)
{
}

// -----------------------------------
void SAL_CALL DocTemplLocaleHelper::setDocumentLocator( const uno::Reference< xml::sax::XLocator >& /*xLocator*/ )
        throw(xml::sax::SAXException, uno::RuntimeException)
{
}

<|endoftext|>


<commit_before>#include <iostream>
#include "DDImage/ddImageVersionNumbers.h"
int main(int, char*[])
{
  std::cout << kDDImageVersion;
  return 0;
}
<commit_msg>Build Nuke stuff into lib/nuke${MAJOR}.${MINOR} (e.g lib/nuke6.2)<commit_after>#include <iostream>
#include "DDImage/ddImageVersionNumbers.h"
int main(int, char*[])
{
    // Print a Nuke API identifier number, used to make the
    // lib/nuke${API_NUMBER} directory

    // Nuke aims to maintain API compatibilty between "v" releases, so
    // compiling for 6.1v1 will work with 6.1v2 etc (but not
    // 6.2v1). Only exception has been 5.1v5 and 5.1v6 (because it was
    // supposed to be 5.2v1)
    std::cout << kDDImageVersionMajorNum << "." << kDDImageVersionMinorNum;
    return 0;
}
<|endoftext|>


<commit_before>#include "ARVersion.h"
#if !defined(__CINT__) || defined(__MAKECINT__)
#include "AliCDBManager.h"
#include "AliCDBStorage.h"
#include "AliCDBId.h"
#include "AliCDBMetaData.h"
#include "AliGeomManager.h"
#include <TROOT.h>
#include "AliRun.h"
#include <TGeoManager.h>
#include <TString.h>
#endif

void UpdateCDBIdealGeom(const char* cdbUri, const char* cfgFile){
  // Produce the ideal geometry and store it in the specified CDB
  // The second argument allows to specify the config file to be used
  // in particular for giving the choice to generate either a full or
  // a partial geometry.
  //

  AliCDBManager* cdb = AliCDBManager::Instance();
  // we set the default storage to the repository because some dets require
  // already at the time of geometry creation to find calibration objects in the cdb
  AliCDBStorage* storage = 0;
  if(!cdb->IsDefaultStorageSet()) cdb->SetDefaultStorage("local://$ALICE_ROOT");
  storage = cdb->GetStorage(cdbUri);
  if(!storage)
  {
    Printf("unable to create valid storage from: %s", cdbUri);
    return;
  }
  cdb->SetRun(0);
  AliCDBId id("GRP/Geometry/Data",0,AliCDBRunRange::Infinity());
  AliCDBMetaData *md= new AliCDBMetaData();

  // Get root and AliRoot versions
  const char* rootv = gROOT->GetVersion();
  TString av(ALIROOT_SVN_BRANCH);
  Int_t revnum = ALIROOT_SVN_REVISION;

  Printf("root version: %s.  AliRoot %s, revision number %d",rootv,av.Data(),revnum);

  md->SetAliRootVersion(av.Data());
  md->SetComment(Form("Geometry produced with root version %s and AliRoot %s, revision number %d",rootv,av.Data(),revnum));

  gAlice->Init(cfgFile);

  if(!gGeoManager){
    Printf("Unable to produce a valid geometry to be put in the CDB!");
    return;
  }

  Printf("Storing in CDB geometry produced with root version %s and AliRoot version %s",rootv,av.Data());
  storage->Put(gGeoManager,id,md);
  // This is to allow macros lauched after this one in the same session to find the
  // newly produced geometry.
  storage->QueryCDB(cdb->GetRun());

}

<commit_msg>Setting default colours for the geometry (suggested by Mateusz)<commit_after>#include "ARVersion.h"
#if !defined(__CINT__) || defined(__MAKECINT__)
#include "AliCDBManager.h"
#include "AliCDBStorage.h"
#include "AliCDBId.h"
#include "AliCDBMetaData.h"
#include "AliGeomManager.h"
#include <TROOT.h>
#include "AliRun.h"
#include <TGeoManager.h>
#include <TString.h>
#endif

void UpdateCDBIdealGeom(const char* cdbUri, const char* cfgFile){
  // Produce the ideal geometry and store it in the specified CDB
  // The second argument allows to specify the config file to be used
  // in particular for giving the choice to generate either a full or
  // a partial geometry.
  //

  AliCDBManager* cdb = AliCDBManager::Instance();
  // we set the default storage to the repository because some dets require
  // already at the time of geometry creation to find calibration objects in the cdb
  AliCDBStorage* storage = 0;
  if(!cdb->IsDefaultStorageSet()) cdb->SetDefaultStorage("local://$ALICE_ROOT");
  storage = cdb->GetStorage(cdbUri);
  if(!storage)
  {
    Printf("unable to create valid storage from: %s", cdbUri);
    return;
  }
  cdb->SetRun(0);
  AliCDBId id("GRP/Geometry/Data",0,AliCDBRunRange::Infinity());
  AliCDBMetaData *md= new AliCDBMetaData();

  // Get root and AliRoot versions
  const char* rootv = gROOT->GetVersion();
  TString av(ALIROOT_SVN_BRANCH);
  Int_t revnum = ALIROOT_SVN_REVISION;

  Printf("root version: %s.  AliRoot %s, revision number %d",rootv,av.Data(),revnum);

  md->SetAliRootVersion(av.Data());
  md->SetComment(Form("Geometry produced with root version %s and AliRoot %s, revision number %d",rootv,av.Data(),revnum));

  gAlice->Init(cfgFile);

  if(!gGeoManager){
    Printf("Unable to produce a valid geometry to be put in the CDB!");
    return;
  }
  gGeoManager->DefaultColors(); // assign default colors according to Z of material
  // (many colors turned into dark gray nuances some time ago, when the root palette was changed)

  Printf("Storing in CDB geometry produced with root version %s and AliRoot version %s",rootv,av.Data());
  storage->Put(gGeoManager,id,md);
  // This is to allow macros lauched after this one in the same session to find the
  // newly produced geometry.
  storage->QueryCDB(cdb->GetRun());

}

<|endoftext|>