<commit_before>/*
 * Copyright 2019 ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * See the LICENSE.PROPRIETARY file in the top-level directory for licensing information.
 */

#include "base64.hh"
#include "log.hh"
#include "serialization.hh"
#include "error.hh"
#include "rapidjson/writer.h"

static logging::logger slogger("alternator-serialization");

namespace alternator {

type_info type_info_from_string(std::string type) {
    static thread_local const std::unordered_map<std::string, type_info> type_infos = {
        {"S", {alternator_type::S, utf8_type}},
        {"B", {alternator_type::B, bytes_type}},
        {"BOOL", {alternator_type::BOOL, boolean_type}},
        {"N", {alternator_type::N, decimal_type}}, //FIXME: Replace with custom Alternator type when implemented
    };
    auto it = type_infos.find(type);
    if (it == type_infos.end()) {
        return {alternator_type::NOT_SUPPORTED_YET, utf8_type};
    }
    return it->second;
}

type_representation represent_type(alternator_type atype) {
    static thread_local const std::unordered_map<alternator_type, type_representation> type_representations = {
        {alternator_type::S, {"S", utf8_type}},
        {alternator_type::B, {"B", bytes_type}},
        {alternator_type::BOOL, {"BOOL", boolean_type}},
        {alternator_type::N, {"N", decimal_type}}, //FIXME: Replace with custom Alternator type when implemented
    };
    auto it = type_representations.find(atype);
    if (it == type_representations.end()) {
        throw std::runtime_error(format("Unknown alternator type {}", int8_t(atype)));
    }
    return it->second;
}

bytes serialize_item(const rjson::value& item) {
    if (item.IsNull() || item.MemberCount() != 1) {
        throw api_error("ValidationException", format("An item can contain only one attribute definition: {}", item));
    }
    auto it = item.MemberBegin();
    type_info type_info = type_info_from_string(it->name.GetString()); // JSON keys are guaranteed to be strings

    if (type_info.atype == alternator_type::NOT_SUPPORTED_YET) {
        slogger.trace("Non-optimal serialization of type {}", it->name.GetString());
        return bytes{int8_t(type_info.atype)} + to_bytes(rjson::print(item));
    }

    bytes serialized;
    // Alternator bytes representation does not start with "0x" followed by hex digits as Scylla-JSON does,
    // but instead uses base64.

    if (type_info.dtype == bytes_type) {
        std::string raw_value = it->value.GetString();
        serialized = base64_decode(std::string_view(raw_value));
    } else if (type_info.dtype == decimal_type) {
        serialized = type_info.dtype->from_string(it->value.GetString());
    } else if (type_info.dtype == boolean_type) {
        serialized = type_info.dtype->from_json_object(Json::Value(it->value.GetBool()), cql_serialization_format::internal());
    } else {
    	//FIXME(sarna): Once we have type visitors, this double conversion hack should be replaced with parsing straight from rapidjson
        serialized = type_info.dtype->from_json_object(Json::Value(rjson::print(it->value)), cql_serialization_format::internal());
    }

    //NOTICE: redundant copy here, from_json_object should accept bytes' output iterator too.
    // Or, we could append type info to the end, but that's unorthodox.
    return bytes{int8_t(type_info.atype)} + std::move(serialized);
}

rjson::value deserialize_item(bytes_view bv) {
    rjson::value deserialized(rapidjson::kObjectType);
    if (bv.empty()) {
        throw api_error("ValidationException", "Serialized value empty");
    }

    alternator_type atype = alternator_type(bv[0]);
    bv.remove_prefix(1);

    if (atype == alternator_type::NOT_SUPPORTED_YET) {
        slogger.trace("Non-optimal deserialization of alternator type {}", int8_t(atype));
        return rjson::parse_raw(reinterpret_cast<const char *>(bv.data()), bv.size());
    }

    type_representation type_representation = represent_type(atype);
    if (type_representation.dtype == bytes_type) {
        std::string b64 = base64_encode(bv);
        rjson::set_with_string_name(deserialized, type_representation.ident, rjson::from_string(b64));
    } else if (type_representation.dtype == decimal_type) {
        auto s = decimal_type->to_json_string(bytes(bv)); //FIXME(sarna): unnecessary copy
        rjson::set_with_string_name(deserialized, type_representation.ident, rjson::from_string(s));
    } else {
        rjson::set_with_string_name(deserialized, type_representation.ident, rjson::parse(type_representation.dtype->to_string(bytes(bv))));
    }

    return deserialized;
}

std::string type_to_string(data_type type) {
    static thread_local std::unordered_map<data_type, std::string> types = {
        {utf8_type, "S"},
        {bytes_type, "B"},
        {boolean_type, "BOOL"},
        {decimal_type, "N"}, // FIXME: use a specialized Alternator number type instead of the general decimal_type
    };
    auto it = types.find(type);
    if (it == types.end()) {
        throw std::runtime_error(format("Unknown type {}", type->name()));
    }
    return it->second;
}

bytes get_key_column_value(const rjson::value& item, const column_definition& column) {
    std::string column_name = column.name_as_text();
    std::string expected_type = type_to_string(column.type);

    const rjson::value& key_typed_value = rjson::get(item, rjson::value::StringRefType(column_name.c_str()));
    if (!key_typed_value.IsObject() || key_typed_value.MemberCount() != 1) {
        throw api_error("ValidationException",
                format("Missing or invalid value object for key column {}: {}", column_name, item));
    }
    return get_key_from_typed_value(key_typed_value, column, expected_type);
}

bytes get_key_from_typed_value(const rjson::value& key_typed_value, const column_definition& column, const std::string& expected_type) {
    auto it = key_typed_value.MemberBegin();
    if (it->name.GetString() != expected_type) {
        throw api_error("ValidationException",
                format("Expected type {} for key column {}, got type {}",
                        expected_type, column.name_as_text(), it->name.GetString()));
    }
    if (column.type == bytes_type) {
        return base64_decode(it->value.GetString());
    } else {
        return column.type->from_string(it->value.GetString());
    }

}

rjson::value json_key_column_value(bytes_view cell, const column_definition& column) {
    if (column.type == bytes_type) {
        std::string b64 = base64_encode(cell);
        return rjson::from_string(b64);
    } if (column.type == utf8_type) {
        return rjson::from_string(std::string(reinterpret_cast<const char*>(cell.data()), cell.size()));
    } else if (column.type == decimal_type) {
        // FIXME: use specialized Alternator number type, not the more
        // general "decimal_type". A dedicated type can be more efficient
        // in storage space and in parsing speed.
        auto s = decimal_type->to_json_string(bytes(cell));
        return rjson::from_string(s);
    } else {
        // We shouldn't get here, we shouldn't see such key columns.
        throw std::runtime_error(format("Unexpected key type: {}", column.type->name()));
    }
}

partition_key pk_from_json(const rjson::value& item, schema_ptr schema) {
    std::vector<bytes> raw_pk;
    // FIXME: this is a loop, but we really allow only one partition key column.
    for (const column_definition& cdef : schema->partition_key_columns()) {
        bytes raw_value = get_key_column_value(item, cdef);
        raw_pk.push_back(std::move(raw_value));
    }
   return partition_key::from_exploded(raw_pk);
}

clustering_key ck_from_json(const rjson::value& item, schema_ptr schema) {
    if (schema->clustering_key_size() == 0) {
        return clustering_key::make_empty();
    }
    std::vector<bytes> raw_ck;
    // FIXME: this is a loop, but we really allow only one clustering key column.
    for (const column_definition& cdef : schema->clustering_key_columns()) {
        bytes raw_value = get_key_column_value(item,  cdef);
        raw_ck.push_back(std::move(raw_value));
    }

    return clustering_key::from_exploded(raw_ck);
}

}
<commit_msg>alternator: migrate to visitor pattern in serialization<commit_after>/*
 * Copyright 2019 ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * See the LICENSE.PROPRIETARY file in the top-level directory for licensing information.
 */

#include "base64.hh"
#include "log.hh"
#include "serialization.hh"
#include "error.hh"
#include "rapidjson/writer.h"
#include "concrete_types.hh"

static logging::logger slogger("alternator-serialization");

namespace alternator {

type_info type_info_from_string(std::string type) {
    static thread_local const std::unordered_map<std::string, type_info> type_infos = {
        {"S", {alternator_type::S, utf8_type}},
        {"B", {alternator_type::B, bytes_type}},
        {"BOOL", {alternator_type::BOOL, boolean_type}},
        {"N", {alternator_type::N, decimal_type}}, //FIXME: Replace with custom Alternator type when implemented
    };
    auto it = type_infos.find(type);
    if (it == type_infos.end()) {
        return {alternator_type::NOT_SUPPORTED_YET, utf8_type};
    }
    return it->second;
}

type_representation represent_type(alternator_type atype) {
    static thread_local const std::unordered_map<alternator_type, type_representation> type_representations = {
        {alternator_type::S, {"S", utf8_type}},
        {alternator_type::B, {"B", bytes_type}},
        {alternator_type::BOOL, {"BOOL", boolean_type}},
        {alternator_type::N, {"N", decimal_type}}, //FIXME: Replace with custom Alternator type when implemented
    };
    auto it = type_representations.find(atype);
    if (it == type_representations.end()) {
        throw std::runtime_error(format("Unknown alternator type {}", int8_t(atype)));
    }
    return it->second;
}

struct from_json_visitor {
    const rjson::value& v;
    bytes_ostream& bo;

    void operator()(const reversed_type_impl& t) const { visit(*t.underlying_type(), from_json_visitor{v, bo}); };
    void operator()(const string_type_impl& t) {
        bo.write(t.from_string(v.GetString()));
    }
    void operator()(const bytes_type_impl& t) const {
        std::string raw_value = v.GetString();
        bo.write(base64_decode(std::string_view(raw_value)));
    }
    void operator()(const boolean_type_impl& t) const {
        bo.write(boolean_type->decompose(v.GetBool()));
    }
    void operator()(const decimal_type_impl& t) const {
        bo.write(t.from_string(v.GetString()));
    }
    // default
    void operator()(const abstract_type& t) const {
        bo.write(t.from_json_object(Json::Value(rjson::print(v)), cql_serialization_format::internal()));
    }
};

bytes serialize_item(const rjson::value& item) {
    if (item.IsNull() || item.MemberCount() != 1) {
        throw api_error("ValidationException", format("An item can contain only one attribute definition: {}", item));
    }
    auto it = item.MemberBegin();
    type_info type_info = type_info_from_string(it->name.GetString()); // JSON keys are guaranteed to be strings

    if (type_info.atype == alternator_type::NOT_SUPPORTED_YET) {
        slogger.trace("Non-optimal serialization of type {}", it->name.GetString());
        return bytes{int8_t(type_info.atype)} + to_bytes(rjson::print(item));
    }

    bytes_ostream bo;
    bo.write(bytes{int8_t(type_info.atype)});
    visit(*type_info.dtype, from_json_visitor{it->value, bo});

    return bytes(bo.linearize());
}

struct to_json_visitor {
    rjson::value& deserialized;
    const std::string& type_ident;
    bytes_view bv;

    void operator()(const reversed_type_impl& t) const { visit(*t.underlying_type(), to_json_visitor{deserialized, type_ident, bv}); };
    void operator()(const decimal_type_impl& t) const {
        auto s = decimal_type->to_json_string(bytes(bv));
        //FIXME(sarna): unnecessary copy
        rjson::set_with_string_name(deserialized, type_ident, rjson::from_string(s));
    }
    void operator()(const string_type_impl& t) {
        rjson::set_with_string_name(deserialized, type_ident, rjson::from_string(reinterpret_cast<const char *>(bv.data()), bv.size()));
    }
    void operator()(const bytes_type_impl& t) const {
        std::string b64 = base64_encode(bv);
        rjson::set_with_string_name(deserialized, type_ident, rjson::from_string(b64));
    }
    // default
    void operator()(const abstract_type& t) const {
        rjson::set_with_string_name(deserialized, type_ident, rjson::parse(t.to_string(bytes(bv))));
    }
};

rjson::value deserialize_item(bytes_view bv) {
    rjson::value deserialized(rapidjson::kObjectType);
    if (bv.empty()) {
        throw api_error("ValidationException", "Serialized value empty");
    }

    alternator_type atype = alternator_type(bv[0]);
    bv.remove_prefix(1);

    if (atype == alternator_type::NOT_SUPPORTED_YET) {
        slogger.trace("Non-optimal deserialization of alternator type {}", int8_t(atype));
        return rjson::parse_raw(reinterpret_cast<const char *>(bv.data()), bv.size());
    }
    type_representation type_representation = represent_type(atype);
    visit(*type_representation.dtype, to_json_visitor{deserialized, type_representation.ident, bv});

    return deserialized;
}

std::string type_to_string(data_type type) {
    static thread_local std::unordered_map<data_type, std::string> types = {
        {utf8_type, "S"},
        {bytes_type, "B"},
        {boolean_type, "BOOL"},
        {decimal_type, "N"}, // FIXME: use a specialized Alternator number type instead of the general decimal_type
    };
    auto it = types.find(type);
    if (it == types.end()) {
        throw std::runtime_error(format("Unknown type {}", type->name()));
    }
    return it->second;
}

bytes get_key_column_value(const rjson::value& item, const column_definition& column) {
    std::string column_name = column.name_as_text();
    std::string expected_type = type_to_string(column.type);

    const rjson::value& key_typed_value = rjson::get(item, rjson::value::StringRefType(column_name.c_str()));
    if (!key_typed_value.IsObject() || key_typed_value.MemberCount() != 1) {
        throw api_error("ValidationException",
                format("Missing or invalid value object for key column {}: {}", column_name, item));
    }
    return get_key_from_typed_value(key_typed_value, column, expected_type);
}

bytes get_key_from_typed_value(const rjson::value& key_typed_value, const column_definition& column, const std::string& expected_type) {
    auto it = key_typed_value.MemberBegin();
    if (it->name.GetString() != expected_type) {
        throw api_error("ValidationException",
                format("Expected type {} for key column {}, got type {}",
                        expected_type, column.name_as_text(), it->name.GetString()));
    }
    if (column.type == bytes_type) {
        return base64_decode(it->value.GetString());
    } else {
        return column.type->from_string(it->value.GetString());
    }

}

rjson::value json_key_column_value(bytes_view cell, const column_definition& column) {
    if (column.type == bytes_type) {
        std::string b64 = base64_encode(cell);
        return rjson::from_string(b64);
    } if (column.type == utf8_type) {
        return rjson::from_string(std::string(reinterpret_cast<const char*>(cell.data()), cell.size()));
    } else if (column.type == decimal_type) {
        // FIXME: use specialized Alternator number type, not the more
        // general "decimal_type". A dedicated type can be more efficient
        // in storage space and in parsing speed.
        auto s = decimal_type->to_json_string(bytes(cell));
        return rjson::from_string(s);
    } else {
        // We shouldn't get here, we shouldn't see such key columns.
        throw std::runtime_error(format("Unexpected key type: {}", column.type->name()));
    }
}

partition_key pk_from_json(const rjson::value& item, schema_ptr schema) {
    std::vector<bytes> raw_pk;
    // FIXME: this is a loop, but we really allow only one partition key column.
    for (const column_definition& cdef : schema->partition_key_columns()) {
        bytes raw_value = get_key_column_value(item, cdef);
        raw_pk.push_back(std::move(raw_value));
    }
   return partition_key::from_exploded(raw_pk);
}

clustering_key ck_from_json(const rjson::value& item, schema_ptr schema) {
    if (schema->clustering_key_size() == 0) {
        return clustering_key::make_empty();
    }
    std::vector<bytes> raw_ck;
    // FIXME: this is a loop, but we really allow only one clustering key column.
    for (const column_definition& cdef : schema->clustering_key_columns()) {
        bytes raw_value = get_key_column_value(item,  cdef);
        raw_ck.push_back(std::move(raw_value));
    }

    return clustering_key::from_exploded(raw_ck);
}

}
<|endoftext|>


<commit_before>#include "FSELightWorld.h"
#include "../Application.h"

#include <rttr/registration>

#include <SFML/Graphics.hpp>

namespace fse
{
	FSELightWorld::FSELightWorld(Scene* scene) : FSELightWorld(scene, sf::Vector2f(0, 0))
	{

	}

	FSELightWorld::FSELightWorld(Scene* scene, const sf::Vector2f& spawnPos) : FSEObject(scene, spawnPos)
	{
		setZOrder(255);
		light_system_ = std::make_unique<ltbl::LightSystem>(normal_texture_, specular_texture_, true);
		bloom_texture_.create(1, 1);
		bloom_shader_.loadFromMemory(bloom_shader_str_, sf::Shader::Fragment);
		gauss_blur_shader_.loadFromMemory(gauss_blur_shader_str_, sf::Shader::Fragment);
	}

	FSELightWorld::~FSELightWorld()
	{
		if (sun_ != nullptr)
			light_system_->removeLight(sun_);
	}

	void FSELightWorld::update(float deltaTime)
	{

	}

	void FSELightWorld::draw(sf::RenderTarget& target)
	{
		if (lighting_)
		{
			normal_texture_.display();
			specular_texture_.display();
			light_system_->render(target);

			if (bloom_)
			{
				if (sf::RenderTexture* r_texture = dynamic_cast<sf::RenderTexture*>(&target))
				{
					//r_texture->display();
					sf::Sprite sprite = sf::Sprite(bloom_texture_.getTexture());
					auto view = target.getView();

					bloom_shader_.setUniform("currTex", r_texture->getTexture());
					bloom_shader_.setUniform("lightCompTex", light_system_->getLightCompTexture().getTexture());
					bloom_shader_.setUniform("specCompTex", light_system_->getSpecCompTexture().getTexture());

					bloom_texture_.draw(sprite, &bloom_shader_);

					gauss_blur_shader_.setUniform("currTex", bloom_texture_.getTexture());
					gauss_blur_shader_.setUniform("texSize", sf::Vector2f(target.getSize().x, target.getSize().y));
					bool horizontal = false;
					for (int i = 0; i < 4; i++)
					{
						horizontal = !horizontal;
						gauss_blur_shader_.setUniform("horizontal", horizontal);
						bloom_texture_.draw(sf::Sprite(bloom_texture_.getTexture()), &gauss_blur_shader_);
					}

					bloom_texture_.display();

					sprite.setPosition(view.getCenter() - view.getSize() / 2.f);
					target.draw(sprite, sf::BlendAdd);

				}
			}
		}
	}

	void FSELightWorld::spawned()
	{
	}

	bool FSELightWorld::destroy()
	{
		return false;
	}

	void FSELightWorld::init(sf::RenderTarget* target) const
	{
		light_system_->create({ -1000.f, -1000.f, 1000.f, 1000.f }, target->getSize());
		//sun_ = light_system_->createLightDirectionEmission();
		//sun_->setColor(sf::Color::Black);
	}

	bool FSELightWorld::getLighting() const
	{
		return lighting_;
	}

	void FSELightWorld::setLighting(bool lighting)
	{
		lighting_ = lighting;
	}

	bool FSELightWorld::getBloom() const
	{
		return bloom_;
	}

	void FSELightWorld::setBloom(bool bloom)
	{
		if (sf::RenderTexture* rTexture = dynamic_cast<sf::RenderTexture*>(scene_->getRenderTarget()))
		{
			bloom_ = bloom;
		}
		else
		{
			std::cout << "Cannot use bloom directly on Window!\n";
			bloom_ = false;
		}
	}

	void FSELightWorld::updateView()
	{
		if (lighting_)
		{
			if (bloom_texture_.getSize() != scene_->getRenderTarget()->getSize())
			{
				bloom_texture_.create(scene_->getRenderTarget()->getSize().x, scene_->getRenderTarget()->getSize().y);
			}

			sf::View view = scene_->getRenderTarget()->getView();
			normal_texture_.setView(view);
			specular_texture_.setView(view);
			normal_texture_.clear(sf::Color(128u, 128u, 255u));
			specular_texture_.clear(sf::Color::Black);
		}
	}

	sf::Color FSELightWorld::getAmbientColor() const
	{
		return light_system_->getAmbientColor();
	}

	void FSELightWorld::setAmbientColor(const sf::Color color) const
	{
		light_system_->setAmbientColor(color);
	}

	ltbl::LightDirectionEmission* FSELightWorld::getSun()
	{
		if (sun_ == nullptr)
			sun_ = light_system_->createLightDirectionEmission();
		return sun_;
	}

	ltbl::LightSystem* FSELightWorld::getLightSystem() const
	{
		return light_system_.get();
	}

	sf::RenderTarget* FSELightWorld::getNormalTarget()
	{
		return &normal_texture_;
	}

	sf::RenderTarget* FSELightWorld::getSpecularTarget()
	{
		return &specular_texture_;
	}
}

RTTR_REGISTRATION
{
	using namespace rttr;
	using namespace fse;

	registration::class_<FSELightWorld>("fse::FSELightWorld")
	(
		metadata("SERIALIZE_NO_RECRATE", true)
	)
	.property("lighting_", &FSELightWorld::lighting_)
	.property("bloom_", &FSELightWorld::getBloom, &FSELightWorld::setBloom)
	.property("ambient_color_", &FSELightWorld::getAmbientColor, &FSELightWorld::setAmbientColor)
	;
}
<commit_msg>Lights: Fix bloom when view is zoomed.<commit_after>#include "FSELightWorld.h"
#include "../Application.h"

#include <rttr/registration>

#include <SFML/Graphics.hpp>

namespace fse
{
	FSELightWorld::FSELightWorld(Scene* scene) : FSELightWorld(scene, sf::Vector2f(0, 0))
	{

	}

	FSELightWorld::FSELightWorld(Scene* scene, const sf::Vector2f& spawnPos) : FSEObject(scene, spawnPos)
	{
		setZOrder(255);
		light_system_ = std::make_unique<ltbl::LightSystem>(normal_texture_, specular_texture_, true);
		bloom_texture_.create(1, 1);
		bloom_shader_.loadFromMemory(bloom_shader_str_, sf::Shader::Fragment);
		gauss_blur_shader_.loadFromMemory(gauss_blur_shader_str_, sf::Shader::Fragment);
	}

	FSELightWorld::~FSELightWorld()
	{
		if (sun_ != nullptr)
			light_system_->removeLight(sun_);
	}

	void FSELightWorld::update(float deltaTime)
	{

	}

	void FSELightWorld::draw(sf::RenderTarget& target)
	{
		if (lighting_)
		{
			normal_texture_.display();
			specular_texture_.display();
			light_system_->render(target);

			if (bloom_)
			{
				if (sf::RenderTexture* r_texture = dynamic_cast<sf::RenderTexture*>(&target))
				{
					//r_texture->display();
					sf::Sprite sprite = sf::Sprite(bloom_texture_.getTexture());
					auto view = target.getView();

					bloom_shader_.setUniform("currTex", r_texture->getTexture());
					bloom_shader_.setUniform("lightCompTex", light_system_->getLightCompTexture().getTexture());
					bloom_shader_.setUniform("specCompTex", light_system_->getSpecCompTexture().getTexture());

					bloom_texture_.draw(sprite, &bloom_shader_);

					gauss_blur_shader_.setUniform("currTex", bloom_texture_.getTexture());
					gauss_blur_shader_.setUniform("texSize", sf::Vector2f(target.getSize().x, target.getSize().y));
					bool horizontal = false;
					for (int i = 0; i < 4; i++)
					{
						horizontal = !horizontal;
						gauss_blur_shader_.setUniform("horizontal", horizontal);
						bloom_texture_.draw(sf::Sprite(bloom_texture_.getTexture()), &gauss_blur_shader_);
					}

					bloom_texture_.display();

					auto sz = view.getSize();
					sprite.setPosition(view.getCenter() - view.getSize() / 2.f);
					sprite.setScale(sz.x / target.getSize().x, sz.y / target.getSize().y);
					target.draw(sprite, sf::BlendAdd);

				}
			}
		}
	}

	void FSELightWorld::spawned()
	{
	}

	bool FSELightWorld::destroy()
	{
		return false;
	}

	void FSELightWorld::init(sf::RenderTarget* target) const
	{
		light_system_->create({ -1000.f, -1000.f, 1000.f, 1000.f }, target->getSize());
		//sun_ = light_system_->createLightDirectionEmission();
		//sun_->setColor(sf::Color::Black);
	}

	bool FSELightWorld::getLighting() const
	{
		return lighting_;
	}

	void FSELightWorld::setLighting(bool lighting)
	{
		lighting_ = lighting;
	}

	bool FSELightWorld::getBloom() const
	{
		return bloom_;
	}

	void FSELightWorld::setBloom(bool bloom)
	{
		if (sf::RenderTexture* rTexture = dynamic_cast<sf::RenderTexture*>(scene_->getRenderTarget()))
		{
			bloom_ = bloom;
		}
		else
		{
			std::cout << "Cannot use bloom directly on Window!\n";
			bloom_ = false;
		}
	}

	void FSELightWorld::updateView()
	{
		if (lighting_)
		{
			if (bloom_texture_.getSize() != scene_->getRenderTarget()->getSize())
			{
				bloom_texture_.create(scene_->getRenderTarget()->getSize().x, scene_->getRenderTarget()->getSize().y);
			}

			sf::View view = scene_->getRenderTarget()->getView();
			normal_texture_.setView(view);
			specular_texture_.setView(view);
			normal_texture_.clear(sf::Color(128u, 128u, 255u));
			specular_texture_.clear(sf::Color::Black);
		}
	}

	sf::Color FSELightWorld::getAmbientColor() const
	{
		return light_system_->getAmbientColor();
	}

	void FSELightWorld::setAmbientColor(const sf::Color color) const
	{
		light_system_->setAmbientColor(color);
	}

	ltbl::LightDirectionEmission* FSELightWorld::getSun()
	{
		if (sun_ == nullptr)
			sun_ = light_system_->createLightDirectionEmission();
		return sun_;
	}

	ltbl::LightSystem* FSELightWorld::getLightSystem() const
	{
		return light_system_.get();
	}

	sf::RenderTarget* FSELightWorld::getNormalTarget()
	{
		return &normal_texture_;
	}

	sf::RenderTarget* FSELightWorld::getSpecularTarget()
	{
		return &specular_texture_;
	}
}

RTTR_REGISTRATION
{
	using namespace rttr;
	using namespace fse;

	registration::class_<FSELightWorld>("fse::FSELightWorld")
	(
		metadata("SERIALIZE_NO_RECRATE", true)
	)
	.property("lighting_", &FSELightWorld::lighting_)
	.property("bloom_", &FSELightWorld::getBloom, &FSELightWorld::setBloom)
	.property("ambient_color_", &FSELightWorld::getAmbientColor, &FSELightWorld::setAmbientColor)
	;
}
<|endoftext|>


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

#include "chrome/browser/bookmarks/chrome_bookmark_client.h"

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/logging.h"
#include "base/values.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/favicon/favicon_changed_details.h"
#include "chrome/browser/favicon/favicon_service.h"
#include "chrome/browser/favicon/favicon_service_factory.h"
#include "chrome/browser/history/history_service.h"
#include "chrome/browser/history/history_service_factory.h"
#include "chrome/browser/history/url_database.h"
#include "chrome/browser/policy/profile_policy_connector.h"
#include "chrome/browser/policy/profile_policy_connector_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/startup_task_runner_service.h"
#include "chrome/browser/profiles/startup_task_runner_service_factory.h"
#include "components/bookmarks/browser/bookmark_model.h"
#include "components/bookmarks/browser/bookmark_node.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/user_metrics.h"
#include "grit/components_strings.h"
#include "policy/policy_constants.h"
#include "ui/base/l10n/l10n_util.h"

namespace {

void NotifyHistoryOfRemovedURLs(Profile* profile,
                                const std::set<GURL>& removed_urls) {
  HistoryService* history_service =
      HistoryServiceFactory::GetForProfile(profile, Profile::EXPLICIT_ACCESS);
  if (history_service)
    history_service->URLsNoLongerBookmarked(removed_urls);
}

}  // namespace

ChromeBookmarkClient::ChromeBookmarkClient(Profile* profile)
    : profile_(profile), model_(NULL) {
}

ChromeBookmarkClient::~ChromeBookmarkClient() {
}

void ChromeBookmarkClient::Init(BookmarkModel* model) {
  DCHECK(model);
  DCHECK(!model_);
  model_ = model;
  model_->AddObserver(this);

  managed_bookmarks_tracker_.reset(new policy::ManagedBookmarksTracker(
      model_,
      profile_->GetPrefs(),
      base::Bind(&ChromeBookmarkClient::GetManagedBookmarksDomain,
                 base::Unretained(this))));

  // Listen for changes to favicons so that we can update the favicon of the
  // node appropriately.
  registrar_.Add(this,
                 chrome::NOTIFICATION_FAVICON_CHANGED,
                 content::Source<Profile>(profile_));
}

void ChromeBookmarkClient::Shutdown() {
  if (model_) {
    registrar_.RemoveAll();

    model_->RemoveObserver(this);
    model_ = NULL;
  }
  BookmarkClient::Shutdown();
}

bool ChromeBookmarkClient::IsDescendantOfManagedNode(const BookmarkNode* node) {
  return node && node->HasAncestor(managed_node_);
}

bool ChromeBookmarkClient::HasDescendantsOfManagedNode(
    const std::vector<const BookmarkNode*>& list) {
  for (size_t i = 0; i < list.size(); ++i) {
    if (IsDescendantOfManagedNode(list[i]))
      return true;
  }
  return false;
}

bool ChromeBookmarkClient::PreferTouchIcon() {
#if !defined(OS_IOS)
  return false;
#else
  return true;
#endif
}

base::CancelableTaskTracker::TaskId ChromeBookmarkClient::GetFaviconImageForURL(
    const GURL& page_url,
    int icon_types,
    int desired_size_in_dip,
    const favicon_base::FaviconImageCallback& callback,
    base::CancelableTaskTracker* tracker) {
  FaviconService* favicon_service =
      FaviconServiceFactory::GetForProfile(profile_, Profile::EXPLICIT_ACCESS);
  if (!favicon_service)
    return base::CancelableTaskTracker::kBadTaskId;
  return favicon_service->GetFaviconImageForPageURL(
      FaviconService::FaviconForPageURLParams(
          page_url, icon_types, desired_size_in_dip),
      callback,
      tracker);
}

bool ChromeBookmarkClient::SupportsTypedCountForNodes() {
  return true;
}

void ChromeBookmarkClient::GetTypedCountForNodes(
    const NodeSet& nodes,
    NodeTypedCountPairs* node_typed_count_pairs) {
  HistoryService* history_service =
      HistoryServiceFactory::GetForProfile(profile_, Profile::EXPLICIT_ACCESS);
  history::URLDatabase* url_db =
      history_service ? history_service->InMemoryDatabase() : NULL;
  for (NodeSet::const_iterator i = nodes.begin(); i != nodes.end(); ++i) {
    int typed_count = 0;

    // If |url_db| is the InMemoryDatabase, it might not cache all URLRows, but
    // it guarantees to contain those with |typed_count| > 0. Thus, if we cannot
    // fetch the URLRow, it is safe to assume that its |typed_count| is 0.
    history::URLRow url;
    if (url_db && url_db->GetRowForURL((*i)->url(), &url))
      typed_count = url.typed_count();

    NodeTypedCountPair pair(*i, typed_count);
    node_typed_count_pairs->push_back(pair);
  }
}

bool ChromeBookmarkClient::IsPermanentNodeVisible(
    const BookmarkPermanentNode* node) {
  DCHECK(node->type() == BookmarkNode::BOOKMARK_BAR ||
         node->type() == BookmarkNode::OTHER_NODE ||
         node->type() == BookmarkNode::MOBILE ||
         node == managed_node_);
  if (node == managed_node_)
    return false;
#if !defined(OS_IOS)
  return node->type() != BookmarkNode::MOBILE;
#else
  return node->type() == BookmarkNode::MOBILE;
#endif
}

void ChromeBookmarkClient::RecordAction(const base::UserMetricsAction& action) {
  content::RecordAction(action);
}

bookmarks::LoadExtraCallback ChromeBookmarkClient::GetLoadExtraNodesCallback() {
  // Create the managed_node now; it will be populated in the LoadExtraNodes
  // callback.
  managed_node_ = new BookmarkPermanentNode(0);
  return base::Bind(
      &ChromeBookmarkClient::LoadExtraNodes,
      StartupTaskRunnerServiceFactory::GetForProfile(profile_)
          ->GetBookmarkTaskRunner(),
      managed_node_,
      base::Passed(managed_bookmarks_tracker_->GetInitialManagedBookmarks()));
}

bool ChromeBookmarkClient::CanSetPermanentNodeTitle(
    const BookmarkNode* permanent_node) {
  // The |managed_node_| can have its title updated if the user signs in or
  // out.
  return !IsDescendantOfManagedNode(permanent_node) ||
         permanent_node == managed_node_;
}

bool ChromeBookmarkClient::CanSyncNode(const BookmarkNode* node) {
  return !IsDescendantOfManagedNode(node);
}

bool ChromeBookmarkClient::CanBeEditedByUser(const BookmarkNode* node) {
  return !IsDescendantOfManagedNode(node);
}

void ChromeBookmarkClient::Observe(
    int type,
    const content::NotificationSource& source,
    const content::NotificationDetails& details) {
  switch (type) {
    case chrome::NOTIFICATION_FAVICON_CHANGED: {
      content::Details<FaviconChangedDetails> favicon_details(details);
      model_->OnFaviconChanged(favicon_details->urls);
      break;
    }

    default:
      NOTREACHED();
      break;
  }
}

void ChromeBookmarkClient::BookmarkModelChanged() {
}

void ChromeBookmarkClient::BookmarkNodeRemoved(
    BookmarkModel* model,
    const BookmarkNode* parent,
    int old_index,
    const BookmarkNode* node,
    const std::set<GURL>& removed_urls) {
  NotifyHistoryOfRemovedURLs(profile_, removed_urls);
}

void ChromeBookmarkClient::BookmarkAllUserNodesRemoved(
    BookmarkModel* model,
    const std::set<GURL>& removed_urls) {
  NotifyHistoryOfRemovedURLs(profile_, removed_urls);
}

void ChromeBookmarkClient::BookmarkModelLoaded(BookmarkModel* model,
                                               bool ids_reassigned) {
  // Start tracking the managed bookmarks. This will detect any changes that
  // may have occurred while the initial managed bookmarks were being loaded
  // on the background.
  managed_bookmarks_tracker_->Init(managed_node_);
}

// static
bookmarks::BookmarkPermanentNodeList ChromeBookmarkClient::LoadExtraNodes(
    const scoped_refptr<base::DeferredSequencedTaskRunner>& profile_io_runner,
    BookmarkPermanentNode* managed_node,
    scoped_ptr<base::ListValue> initial_managed_bookmarks,
    int64* next_node_id) {
  DCHECK(profile_io_runner->RunsTasksOnCurrentThread());
  // Load the initial contents of the |managed_node| now, and assign it an
  // unused ID.
  int64 managed_id = *next_node_id;
  managed_node->set_id(managed_id);
  *next_node_id = policy::ManagedBookmarksTracker::LoadInitial(
      managed_node, initial_managed_bookmarks.get(), managed_id + 1);
  managed_node->set_visible(!managed_node->empty());
  managed_node->SetTitle(
      l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_MANAGED_FOLDER_DEFAULT_NAME));

  bookmarks::BookmarkPermanentNodeList extra_nodes;
  extra_nodes.push_back(managed_node);
  return extra_nodes.Pass();
}

std::string ChromeBookmarkClient::GetManagedBookmarksDomain() {
  policy::ProfilePolicyConnector* connector =
      policy::ProfilePolicyConnectorFactory::GetForProfile(profile_);
  if (connector->IsPolicyFromCloudPolicy(policy::key::kManagedBookmarks))
    return connector->GetManagementDomain();
  return std::string();
}
<commit_msg>Fixed uninitialized read in ChromeBookmarkClient.<commit_after>// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/bookmarks/chrome_bookmark_client.h"

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/logging.h"
#include "base/values.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/favicon/favicon_changed_details.h"
#include "chrome/browser/favicon/favicon_service.h"
#include "chrome/browser/favicon/favicon_service_factory.h"
#include "chrome/browser/history/history_service.h"
#include "chrome/browser/history/history_service_factory.h"
#include "chrome/browser/history/url_database.h"
#include "chrome/browser/policy/profile_policy_connector.h"
#include "chrome/browser/policy/profile_policy_connector_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/startup_task_runner_service.h"
#include "chrome/browser/profiles/startup_task_runner_service_factory.h"
#include "components/bookmarks/browser/bookmark_model.h"
#include "components/bookmarks/browser/bookmark_node.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/user_metrics.h"
#include "grit/components_strings.h"
#include "policy/policy_constants.h"
#include "ui/base/l10n/l10n_util.h"

namespace {

void NotifyHistoryOfRemovedURLs(Profile* profile,
                                const std::set<GURL>& removed_urls) {
  HistoryService* history_service =
      HistoryServiceFactory::GetForProfile(profile, Profile::EXPLICIT_ACCESS);
  if (history_service)
    history_service->URLsNoLongerBookmarked(removed_urls);
}

}  // namespace

ChromeBookmarkClient::ChromeBookmarkClient(Profile* profile)
    : profile_(profile), model_(NULL), managed_node_(NULL) {
}

ChromeBookmarkClient::~ChromeBookmarkClient() {
}

void ChromeBookmarkClient::Init(BookmarkModel* model) {
  DCHECK(model);
  DCHECK(!model_);
  model_ = model;
  model_->AddObserver(this);

  managed_bookmarks_tracker_.reset(new policy::ManagedBookmarksTracker(
      model_,
      profile_->GetPrefs(),
      base::Bind(&ChromeBookmarkClient::GetManagedBookmarksDomain,
                 base::Unretained(this))));

  // Listen for changes to favicons so that we can update the favicon of the
  // node appropriately.
  registrar_.Add(this,
                 chrome::NOTIFICATION_FAVICON_CHANGED,
                 content::Source<Profile>(profile_));
}

void ChromeBookmarkClient::Shutdown() {
  if (model_) {
    registrar_.RemoveAll();

    model_->RemoveObserver(this);
    model_ = NULL;
  }
  BookmarkClient::Shutdown();
}

bool ChromeBookmarkClient::IsDescendantOfManagedNode(const BookmarkNode* node) {
  return node && node->HasAncestor(managed_node_);
}

bool ChromeBookmarkClient::HasDescendantsOfManagedNode(
    const std::vector<const BookmarkNode*>& list) {
  for (size_t i = 0; i < list.size(); ++i) {
    if (IsDescendantOfManagedNode(list[i]))
      return true;
  }
  return false;
}

bool ChromeBookmarkClient::PreferTouchIcon() {
#if !defined(OS_IOS)
  return false;
#else
  return true;
#endif
}

base::CancelableTaskTracker::TaskId ChromeBookmarkClient::GetFaviconImageForURL(
    const GURL& page_url,
    int icon_types,
    int desired_size_in_dip,
    const favicon_base::FaviconImageCallback& callback,
    base::CancelableTaskTracker* tracker) {
  FaviconService* favicon_service =
      FaviconServiceFactory::GetForProfile(profile_, Profile::EXPLICIT_ACCESS);
  if (!favicon_service)
    return base::CancelableTaskTracker::kBadTaskId;
  return favicon_service->GetFaviconImageForPageURL(
      FaviconService::FaviconForPageURLParams(
          page_url, icon_types, desired_size_in_dip),
      callback,
      tracker);
}

bool ChromeBookmarkClient::SupportsTypedCountForNodes() {
  return true;
}

void ChromeBookmarkClient::GetTypedCountForNodes(
    const NodeSet& nodes,
    NodeTypedCountPairs* node_typed_count_pairs) {
  HistoryService* history_service =
      HistoryServiceFactory::GetForProfile(profile_, Profile::EXPLICIT_ACCESS);
  history::URLDatabase* url_db =
      history_service ? history_service->InMemoryDatabase() : NULL;
  for (NodeSet::const_iterator i = nodes.begin(); i != nodes.end(); ++i) {
    int typed_count = 0;

    // If |url_db| is the InMemoryDatabase, it might not cache all URLRows, but
    // it guarantees to contain those with |typed_count| > 0. Thus, if we cannot
    // fetch the URLRow, it is safe to assume that its |typed_count| is 0.
    history::URLRow url;
    if (url_db && url_db->GetRowForURL((*i)->url(), &url))
      typed_count = url.typed_count();

    NodeTypedCountPair pair(*i, typed_count);
    node_typed_count_pairs->push_back(pair);
  }
}

bool ChromeBookmarkClient::IsPermanentNodeVisible(
    const BookmarkPermanentNode* node) {
  DCHECK(node->type() == BookmarkNode::BOOKMARK_BAR ||
         node->type() == BookmarkNode::OTHER_NODE ||
         node->type() == BookmarkNode::MOBILE ||
         node == managed_node_);
  if (node == managed_node_)
    return false;
#if !defined(OS_IOS)
  return node->type() != BookmarkNode::MOBILE;
#else
  return node->type() == BookmarkNode::MOBILE;
#endif
}

void ChromeBookmarkClient::RecordAction(const base::UserMetricsAction& action) {
  content::RecordAction(action);
}

bookmarks::LoadExtraCallback ChromeBookmarkClient::GetLoadExtraNodesCallback() {
  // Create the managed_node now; it will be populated in the LoadExtraNodes
  // callback.
  managed_node_ = new BookmarkPermanentNode(0);
  return base::Bind(
      &ChromeBookmarkClient::LoadExtraNodes,
      StartupTaskRunnerServiceFactory::GetForProfile(profile_)
          ->GetBookmarkTaskRunner(),
      managed_node_,
      base::Passed(managed_bookmarks_tracker_->GetInitialManagedBookmarks()));
}

bool ChromeBookmarkClient::CanSetPermanentNodeTitle(
    const BookmarkNode* permanent_node) {
  // The |managed_node_| can have its title updated if the user signs in or
  // out.
  return !IsDescendantOfManagedNode(permanent_node) ||
         permanent_node == managed_node_;
}

bool ChromeBookmarkClient::CanSyncNode(const BookmarkNode* node) {
  return !IsDescendantOfManagedNode(node);
}

bool ChromeBookmarkClient::CanBeEditedByUser(const BookmarkNode* node) {
  return !IsDescendantOfManagedNode(node);
}

void ChromeBookmarkClient::Observe(
    int type,
    const content::NotificationSource& source,
    const content::NotificationDetails& details) {
  switch (type) {
    case chrome::NOTIFICATION_FAVICON_CHANGED: {
      content::Details<FaviconChangedDetails> favicon_details(details);
      model_->OnFaviconChanged(favicon_details->urls);
      break;
    }

    default:
      NOTREACHED();
      break;
  }
}

void ChromeBookmarkClient::BookmarkModelChanged() {
}

void ChromeBookmarkClient::BookmarkNodeRemoved(
    BookmarkModel* model,
    const BookmarkNode* parent,
    int old_index,
    const BookmarkNode* node,
    const std::set<GURL>& removed_urls) {
  NotifyHistoryOfRemovedURLs(profile_, removed_urls);
}

void ChromeBookmarkClient::BookmarkAllUserNodesRemoved(
    BookmarkModel* model,
    const std::set<GURL>& removed_urls) {
  NotifyHistoryOfRemovedURLs(profile_, removed_urls);
}

void ChromeBookmarkClient::BookmarkModelLoaded(BookmarkModel* model,
                                               bool ids_reassigned) {
  // Start tracking the managed bookmarks. This will detect any changes that
  // may have occurred while the initial managed bookmarks were being loaded
  // on the background.
  managed_bookmarks_tracker_->Init(managed_node_);
}

// static
bookmarks::BookmarkPermanentNodeList ChromeBookmarkClient::LoadExtraNodes(
    const scoped_refptr<base::DeferredSequencedTaskRunner>& profile_io_runner,
    BookmarkPermanentNode* managed_node,
    scoped_ptr<base::ListValue> initial_managed_bookmarks,
    int64* next_node_id) {
  DCHECK(profile_io_runner->RunsTasksOnCurrentThread());
  // Load the initial contents of the |managed_node| now, and assign it an
  // unused ID.
  int64 managed_id = *next_node_id;
  managed_node->set_id(managed_id);
  *next_node_id = policy::ManagedBookmarksTracker::LoadInitial(
      managed_node, initial_managed_bookmarks.get(), managed_id + 1);
  managed_node->set_visible(!managed_node->empty());
  managed_node->SetTitle(
      l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_MANAGED_FOLDER_DEFAULT_NAME));

  bookmarks::BookmarkPermanentNodeList extra_nodes;
  extra_nodes.push_back(managed_node);
  return extra_nodes.Pass();
}

std::string ChromeBookmarkClient::GetManagedBookmarksDomain() {
  policy::ProfilePolicyConnector* connector =
      policy::ProfilePolicyConnectorFactory::GetForProfile(profile_);
  if (connector->IsPolicyFromCloudPolicy(policy::key::kManagedBookmarks))
    return connector->GetManagementDomain();
  return std::string();
}
<|endoftext|>


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

#include "chrome/browser/first_run/try_chrome_dialog_view.h"

#include <shellapi.h>

#include "base/logging.h"
#include "base/message_loop.h"
#include "base/string16.h"
#include "chrome/browser/process_singleton.h"
#include "chrome/installer/util/browser_distribution.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
#include "grit/theme_resources_standard.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "views/controls/button/image_button.h"
#include "views/controls/button/radio_button.h"
#include "views/controls/image_view.h"
#include "views/controls/link.h"
#include "views/layout/grid_layout.h"
#include "views/layout/layout_constants.h"
#include "views/widget/root_view.h"
#include "views/widget/widget.h"

namespace {

const wchar_t kHelpCenterUrl[] =
    L"https://www.google.com/support/chrome/bin/answer.py?answer=150752";

}  // namespace

// static
TryChromeDialogView::Result TryChromeDialogView::Show(
    size_t version,
    ProcessSingleton* process_singleton) {
  if (version > 10000) {
    // This is a test value. We want to make sure we exercise
    // returning this early. See EarlyReturnTest test harness.
    return NOT_NOW;
  }
  TryChromeDialogView dialog(version);
  return dialog.ShowModal(process_singleton);
}

TryChromeDialogView::TryChromeDialogView(size_t version)
    : version_(version),
      popup_(NULL),
      try_chrome_(NULL),
      kill_chrome_(NULL),
      result_(COUNT) {
}

TryChromeDialogView::~TryChromeDialogView() {
}

TryChromeDialogView::Result TryChromeDialogView::ShowModal(
    ProcessSingleton* process_singleton) {
  ResourceBundle& rb = ResourceBundle::GetSharedInstance();

  views::ImageView* icon = new views::ImageView();
  icon->SetImage(*rb.GetBitmapNamed(IDR_PRODUCT_ICON_32));
  gfx::Size icon_size = icon->GetPreferredSize();

  // An approximate window size. After Layout() we'll get better bounds.
  popup_ = new views::Widget;
  if (!popup_) {
    NOTREACHED();
    return DIALOG_ERROR;
  }

  views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP);
  params.can_activate = true;
  params.bounds = gfx::Rect(310, 160);
  popup_->Init(params);

  views::RootView* root_view = popup_->GetRootView();
  // The window color is a tiny bit off-white.
  root_view->set_background(
      views::Background::CreateSolidBackground(0xfc, 0xfc, 0xfc));

  views::GridLayout* layout = views::GridLayout::CreatePanel(root_view);
  if (!layout) {
    NOTREACHED();
    return DIALOG_ERROR;
  }
  root_view->SetLayoutManager(layout);

  views::ColumnSet* columns;
  // First row: [icon][pad][text][button].
  columns = layout->AddColumnSet(0);
  columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::LEADING, 0,
                     views::GridLayout::FIXED, icon_size.width(),
                     icon_size.height());
  columns->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing);
  columns->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1,
                     views::GridLayout::USE_PREF, 0, 0);
  columns->AddColumn(views::GridLayout::TRAILING, views::GridLayout::FILL, 1,
                     views::GridLayout::USE_PREF, 0, 0);
  // Second row: [pad][pad][radio 1].
  columns = layout->AddColumnSet(1);
  columns->AddPaddingColumn(0, icon_size.width());
  columns->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing);
  columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::FILL, 1,
                     views::GridLayout::USE_PREF, 0, 0);
  // Third row: [pad][pad][radio 2].
  columns = layout->AddColumnSet(2);
  columns->AddPaddingColumn(0, icon_size.width());
  columns->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing);
  columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::FILL, 1,
                     views::GridLayout::USE_PREF, 0, 0);
  // Fourth row: [pad][pad][button][pad][button].
  columns = layout->AddColumnSet(3);
  columns->AddPaddingColumn(0, icon_size.width());
  columns->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing);
  columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::FILL, 0,
                     views::GridLayout::USE_PREF, 0, 0);
  columns->AddPaddingColumn(0, views::kRelatedButtonHSpacing);
  columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::FILL, 0,
                     views::GridLayout::USE_PREF, 0, 0);
  // Fifth row: [pad][pad][link].
  columns = layout->AddColumnSet(4);
  columns->AddPaddingColumn(0, icon_size.width());
  columns->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing);
  columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::FILL, 1,
                     views::GridLayout::USE_PREF, 0, 0);
  // First row views.
  layout->StartRow(0, 0);
  layout->AddView(icon);

  // Find out what experiment we are conducting.
  BrowserDistribution* dist = BrowserDistribution::GetDistribution();
  if (!dist) {
    NOTREACHED() << "Cannot determine browser distribution";
    return DIALOG_ERROR;
  }
  BrowserDistribution::UserExperiment experiment;
  if (!dist->GetExperimentDetails(&experiment, version_) ||
      !experiment.heading) {
    NOTREACHED() << "Cannot determine which headline to show.";
    return DIALOG_ERROR;
  }
  string16 heading = l10n_util::GetStringUTF16(experiment.heading);
  views::Label* label = new views::Label(heading);
  label->SetFont(rb.GetFont(ResourceBundle::MediumBoldFont));
  label->SetMultiLine(true);
  label->SizeToFit(200);
  label->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
  layout->AddView(label);
  // The close button is custom.
  views::ImageButton* close_button = new views::ImageButton(this);
  close_button->SetImage(views::CustomButton::BS_NORMAL,
                        rb.GetBitmapNamed(IDR_CLOSE_BAR));
  close_button->SetImage(views::CustomButton::BS_HOT,
                        rb.GetBitmapNamed(IDR_CLOSE_BAR_H));
  close_button->SetImage(views::CustomButton::BS_PUSHED,
                        rb.GetBitmapNamed(IDR_CLOSE_BAR_P));
  close_button->set_tag(BT_CLOSE_BUTTON);
  layout->AddView(close_button);

  // Second row views.
  const string16 try_it(l10n_util::GetStringUTF16(IDS_TRY_TOAST_TRY_OPT));
  layout->StartRowWithPadding(0, 1, 0, 10);
  try_chrome_ = new views::RadioButton(try_it, 1);
  layout->AddView(try_chrome_);
  try_chrome_->SetChecked(true);

  // Third row views.
  const string16 kill_it(l10n_util::GetStringUTF16(IDS_UNINSTALL_CHROME));
  layout->StartRow(0, 2);
  kill_chrome_ = new views::RadioButton(kill_it, 1);
  layout->AddView(kill_chrome_);

  // Fourth row views.
  const string16 ok_it(l10n_util::GetStringUTF16(IDS_OK));
  const string16 cancel_it(l10n_util::GetStringUTF16(IDS_TRY_TOAST_CANCEL));
  const string16 why_this(l10n_util::GetStringUTF16(IDS_TRY_TOAST_WHY));
  layout->StartRowWithPadding(0, 3, 0, 10);
  views::Button* accept_button = new views::NativeButton(this, ok_it);
  accept_button->set_tag(BT_OK_BUTTON);
  layout->AddView(accept_button);
  views::Button* cancel_button = new views::NativeButton(this, cancel_it);
  cancel_button->set_tag(BT_CLOSE_BUTTON);
  layout->AddView(cancel_button);
  // Fifth row views.
  layout->StartRowWithPadding(0, 4, 0, 10);
  views::Link* link = new views::Link(why_this);
  link->set_listener(this);
  layout->AddView(link);

  // We resize the window according to the layout manager. This takes into
  // account the differences between XP and Vista fonts and buttons.
  layout->Layout(root_view);
  gfx::Size preferred = layout->GetPreferredSize(root_view);
  gfx::Rect pos = ComputeWindowPosition(preferred.width(), preferred.height(),
                                        base::i18n::IsRTL());
  popup_->SetBounds(pos);

  // Carve the toast shape into the window.
  SetToastRegion(popup_->GetNativeView(),
                 preferred.width(), preferred.height());

  // Time to show the window in a modal loop. We don't want this chrome
  // instance trying to serve WM_COPYDATA requests, as we'll surely crash.
  process_singleton->Lock(popup_->GetNativeView());
  popup_->Show();
  MessageLoop::current()->Run();
  process_singleton->Unlock();
  return result_;
}

gfx::Rect TryChromeDialogView::ComputeWindowPosition(int width,
                                                     int height,
                                                     bool is_RTL) {
  // The 'Shell_TrayWnd' is the taskbar. We like to show our window in that
  // monitor if we can. This code works even if such window is not found.
  HWND taskbar = ::FindWindowW(L"Shell_TrayWnd", NULL);
  HMONITOR monitor = ::MonitorFromWindow(taskbar, MONITOR_DEFAULTTOPRIMARY);
  MONITORINFO info = {sizeof(info)};
  if (!GetMonitorInfoW(monitor, &info)) {
    // Quite unexpected. Do a best guess at a visible rectangle.
    return gfx::Rect(20, 20, width + 20, height + 20);
  }
  // The |rcWork| is the work area. It should account for the taskbars that
  // are in the screen when we called the function.
  int left = is_RTL ? info.rcWork.left : info.rcWork.right - width;
  int top = info.rcWork.bottom - height;
  return gfx::Rect(left, top, width, height);
}

void TryChromeDialogView::SetToastRegion(HWND window, int w, int h) {
  static const POINT polygon[] = {
    {0,   4}, {1,   2}, {2,   1}, {4, 0},   // Left side.
    {w-4, 0}, {w-2, 1}, {w-1, 2}, {w, 4},   // Right side.
    {w, h}, {0, h}
  };
  HRGN region = ::CreatePolygonRgn(polygon, arraysize(polygon), WINDING);
  ::SetWindowRgn(window, region, FALSE);
}

void TryChromeDialogView::ButtonPressed(views::Button* sender,
                                        const views::Event& event) {
  if (sender->tag() == BT_CLOSE_BUTTON) {
    // The user pressed cancel or the [x] button.
    result_ = NOT_NOW;
  } else if (!try_chrome_) {
    // We don't have radio buttons, the user pressed ok.
    result_ = TRY_CHROME;
  } else {
    // The outcome is according to the selected ratio button.
    result_ = try_chrome_->checked() ? TRY_CHROME : UNINSTALL_CHROME;
  }
  popup_->Close();
  MessageLoop::current()->Quit();
}

void TryChromeDialogView::LinkClicked(views::Link* source, int event_flags) {
  ::ShellExecuteW(NULL, L"open", kHelpCenterUrl, NULL, NULL, SW_SHOW);
}
<commit_msg>first_run: Call ResourceBundle::GetNativeImageNamed() instead of GetBitmapNamed().<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/first_run/try_chrome_dialog_view.h"

#include <shellapi.h>

#include "base/logging.h"
#include "base/message_loop.h"
#include "base/string16.h"
#include "chrome/browser/process_singleton.h"
#include "chrome/installer/util/browser_distribution.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
#include "grit/theme_resources_standard.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/image.h"
#include "views/controls/button/image_button.h"
#include "views/controls/button/radio_button.h"
#include "views/controls/image_view.h"
#include "views/controls/link.h"
#include "views/layout/grid_layout.h"
#include "views/layout/layout_constants.h"
#include "views/widget/root_view.h"
#include "views/widget/widget.h"

namespace {

const wchar_t kHelpCenterUrl[] =
    L"https://www.google.com/support/chrome/bin/answer.py?answer=150752";

}  // namespace

// static
TryChromeDialogView::Result TryChromeDialogView::Show(
    size_t version,
    ProcessSingleton* process_singleton) {
  if (version > 10000) {
    // This is a test value. We want to make sure we exercise
    // returning this early. See EarlyReturnTest test harness.
    return NOT_NOW;
  }
  TryChromeDialogView dialog(version);
  return dialog.ShowModal(process_singleton);
}

TryChromeDialogView::TryChromeDialogView(size_t version)
    : version_(version),
      popup_(NULL),
      try_chrome_(NULL),
      kill_chrome_(NULL),
      result_(COUNT) {
}

TryChromeDialogView::~TryChromeDialogView() {
}

TryChromeDialogView::Result TryChromeDialogView::ShowModal(
    ProcessSingleton* process_singleton) {
  ResourceBundle& rb = ResourceBundle::GetSharedInstance();

  views::ImageView* icon = new views::ImageView();
  icon->SetImage(*rb.GetNativeImageNamed(IDR_PRODUCT_ICON_32));
  gfx::Size icon_size = icon->GetPreferredSize();

  // An approximate window size. After Layout() we'll get better bounds.
  popup_ = new views::Widget;
  if (!popup_) {
    NOTREACHED();
    return DIALOG_ERROR;
  }

  views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP);
  params.can_activate = true;
  params.bounds = gfx::Rect(310, 160);
  popup_->Init(params);

  views::RootView* root_view = popup_->GetRootView();
  // The window color is a tiny bit off-white.
  root_view->set_background(
      views::Background::CreateSolidBackground(0xfc, 0xfc, 0xfc));

  views::GridLayout* layout = views::GridLayout::CreatePanel(root_view);
  if (!layout) {
    NOTREACHED();
    return DIALOG_ERROR;
  }
  root_view->SetLayoutManager(layout);

  views::ColumnSet* columns;
  // First row: [icon][pad][text][button].
  columns = layout->AddColumnSet(0);
  columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::LEADING, 0,
                     views::GridLayout::FIXED, icon_size.width(),
                     icon_size.height());
  columns->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing);
  columns->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1,
                     views::GridLayout::USE_PREF, 0, 0);
  columns->AddColumn(views::GridLayout::TRAILING, views::GridLayout::FILL, 1,
                     views::GridLayout::USE_PREF, 0, 0);
  // Second row: [pad][pad][radio 1].
  columns = layout->AddColumnSet(1);
  columns->AddPaddingColumn(0, icon_size.width());
  columns->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing);
  columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::FILL, 1,
                     views::GridLayout::USE_PREF, 0, 0);
  // Third row: [pad][pad][radio 2].
  columns = layout->AddColumnSet(2);
  columns->AddPaddingColumn(0, icon_size.width());
  columns->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing);
  columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::FILL, 1,
                     views::GridLayout::USE_PREF, 0, 0);
  // Fourth row: [pad][pad][button][pad][button].
  columns = layout->AddColumnSet(3);
  columns->AddPaddingColumn(0, icon_size.width());
  columns->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing);
  columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::FILL, 0,
                     views::GridLayout::USE_PREF, 0, 0);
  columns->AddPaddingColumn(0, views::kRelatedButtonHSpacing);
  columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::FILL, 0,
                     views::GridLayout::USE_PREF, 0, 0);
  // Fifth row: [pad][pad][link].
  columns = layout->AddColumnSet(4);
  columns->AddPaddingColumn(0, icon_size.width());
  columns->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing);
  columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::FILL, 1,
                     views::GridLayout::USE_PREF, 0, 0);
  // First row views.
  layout->StartRow(0, 0);
  layout->AddView(icon);

  // Find out what experiment we are conducting.
  BrowserDistribution* dist = BrowserDistribution::GetDistribution();
  if (!dist) {
    NOTREACHED() << "Cannot determine browser distribution";
    return DIALOG_ERROR;
  }
  BrowserDistribution::UserExperiment experiment;
  if (!dist->GetExperimentDetails(&experiment, version_) ||
      !experiment.heading) {
    NOTREACHED() << "Cannot determine which headline to show.";
    return DIALOG_ERROR;
  }
  string16 heading = l10n_util::GetStringUTF16(experiment.heading);
  views::Label* label = new views::Label(heading);
  label->SetFont(rb.GetFont(ResourceBundle::MediumBoldFont));
  label->SetMultiLine(true);
  label->SizeToFit(200);
  label->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
  layout->AddView(label);
  // The close button is custom.
  views::ImageButton* close_button = new views::ImageButton(this);
  close_button->SetImage(views::CustomButton::BS_NORMAL,
                         rb.GetNativeImageNamed(IDR_CLOSE_BAR));
  close_button->SetImage(views::CustomButton::BS_HOT,
                         rb.GetNativeImageNamed(IDR_CLOSE_BAR_H));
  close_button->SetImage(views::CustomButton::BS_PUSHED,
                         rb.GetNativeImageNamed(IDR_CLOSE_BAR_P));
  close_button->set_tag(BT_CLOSE_BUTTON);
  layout->AddView(close_button);

  // Second row views.
  const string16 try_it(l10n_util::GetStringUTF16(IDS_TRY_TOAST_TRY_OPT));
  layout->StartRowWithPadding(0, 1, 0, 10);
  try_chrome_ = new views::RadioButton(try_it, 1);
  layout->AddView(try_chrome_);
  try_chrome_->SetChecked(true);

  // Third row views.
  const string16 kill_it(l10n_util::GetStringUTF16(IDS_UNINSTALL_CHROME));
  layout->StartRow(0, 2);
  kill_chrome_ = new views::RadioButton(kill_it, 1);
  layout->AddView(kill_chrome_);

  // Fourth row views.
  const string16 ok_it(l10n_util::GetStringUTF16(IDS_OK));
  const string16 cancel_it(l10n_util::GetStringUTF16(IDS_TRY_TOAST_CANCEL));
  const string16 why_this(l10n_util::GetStringUTF16(IDS_TRY_TOAST_WHY));
  layout->StartRowWithPadding(0, 3, 0, 10);
  views::Button* accept_button = new views::NativeButton(this, ok_it);
  accept_button->set_tag(BT_OK_BUTTON);
  layout->AddView(accept_button);
  views::Button* cancel_button = new views::NativeButton(this, cancel_it);
  cancel_button->set_tag(BT_CLOSE_BUTTON);
  layout->AddView(cancel_button);
  // Fifth row views.
  layout->StartRowWithPadding(0, 4, 0, 10);
  views::Link* link = new views::Link(why_this);
  link->set_listener(this);
  layout->AddView(link);

  // We resize the window according to the layout manager. This takes into
  // account the differences between XP and Vista fonts and buttons.
  layout->Layout(root_view);
  gfx::Size preferred = layout->GetPreferredSize(root_view);
  gfx::Rect pos = ComputeWindowPosition(preferred.width(), preferred.height(),
                                        base::i18n::IsRTL());
  popup_->SetBounds(pos);

  // Carve the toast shape into the window.
  SetToastRegion(popup_->GetNativeView(),
                 preferred.width(), preferred.height());

  // Time to show the window in a modal loop. We don't want this chrome
  // instance trying to serve WM_COPYDATA requests, as we'll surely crash.
  process_singleton->Lock(popup_->GetNativeView());
  popup_->Show();
  MessageLoop::current()->Run();
  process_singleton->Unlock();
  return result_;
}

gfx::Rect TryChromeDialogView::ComputeWindowPosition(int width,
                                                     int height,
                                                     bool is_RTL) {
  // The 'Shell_TrayWnd' is the taskbar. We like to show our window in that
  // monitor if we can. This code works even if such window is not found.
  HWND taskbar = ::FindWindowW(L"Shell_TrayWnd", NULL);
  HMONITOR monitor = ::MonitorFromWindow(taskbar, MONITOR_DEFAULTTOPRIMARY);
  MONITORINFO info = {sizeof(info)};
  if (!GetMonitorInfoW(monitor, &info)) {
    // Quite unexpected. Do a best guess at a visible rectangle.
    return gfx::Rect(20, 20, width + 20, height + 20);
  }
  // The |rcWork| is the work area. It should account for the taskbars that
  // are in the screen when we called the function.
  int left = is_RTL ? info.rcWork.left : info.rcWork.right - width;
  int top = info.rcWork.bottom - height;
  return gfx::Rect(left, top, width, height);
}

void TryChromeDialogView::SetToastRegion(HWND window, int w, int h) {
  static const POINT polygon[] = {
    {0,   4}, {1,   2}, {2,   1}, {4, 0},   // Left side.
    {w-4, 0}, {w-2, 1}, {w-1, 2}, {w, 4},   // Right side.
    {w, h}, {0, h}
  };
  HRGN region = ::CreatePolygonRgn(polygon, arraysize(polygon), WINDING);
  ::SetWindowRgn(window, region, FALSE);
}

void TryChromeDialogView::ButtonPressed(views::Button* sender,
                                        const views::Event& event) {
  if (sender->tag() == BT_CLOSE_BUTTON) {
    // The user pressed cancel or the [x] button.
    result_ = NOT_NOW;
  } else if (!try_chrome_) {
    // We don't have radio buttons, the user pressed ok.
    result_ = TRY_CHROME;
  } else {
    // The outcome is according to the selected ratio button.
    result_ = try_chrome_->checked() ? TRY_CHROME : UNINSTALL_CHROME;
  }
  popup_->Close();
  MessageLoop::current()->Quit();
}

void TryChromeDialogView::LinkClicked(views::Link* source, int event_flags) {
  ::ShellExecuteW(NULL, L"open", kHelpCenterUrl, NULL, NULL, SW_SHOW);
}
<|endoftext|>


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

#include "chrome/browser/in_process_webkit/webkit_context.h"

#include "base/command_line.h"
#include "chrome/browser/browser_thread.h"
#include "chrome/browser/profile.h"
#include "chrome/common/chrome_switches.h"

WebKitContext::WebKitContext(Profile* profile)
    : data_path_(profile->IsOffTheRecord() ? FilePath() : profile->GetPath()),
      is_incognito_(profile->IsOffTheRecord()),
      ALLOW_THIS_IN_INITIALIZER_LIST(
          dom_storage_context_(new DOMStorageContext(this))),
      ALLOW_THIS_IN_INITIALIZER_LIST(
          indexed_db_context_(new IndexedDBContext(this))) {
}

WebKitContext::~WebKitContext() {
  // If the WebKit thread was ever spun up, delete the object there.  The task
  // will just get deleted if the WebKit thread isn't created (which only
  // happens during testing).
  DOMStorageContext* dom_storage_context = dom_storage_context_.release();
  if (!BrowserThread::DeleteSoon(
          BrowserThread::WEBKIT, FROM_HERE, dom_storage_context)) {
    // The WebKit thread wasn't created, and the task got deleted without
    // freeing the DOMStorageContext, so delete it manually.
    delete dom_storage_context;
  }

  IndexedDBContext* indexed_db_context = indexed_db_context_.release();
  if (!BrowserThread::DeleteSoon(
          BrowserThread::WEBKIT, FROM_HERE, indexed_db_context)) {
    delete indexed_db_context;
  }
}

void WebKitContext::PurgeMemory() {
  if (!BrowserThread::CurrentlyOn(BrowserThread::WEBKIT)) {
    bool result = BrowserThread::PostTask(
        BrowserThread::WEBKIT, FROM_HERE,
        NewRunnableMethod(this, &WebKitContext::PurgeMemory));
    DCHECK(result);
    return;
  }

  dom_storage_context_->PurgeMemory();
}

void WebKitContext::DeleteDataModifiedSince(
    const base::Time& cutoff,
    const char* url_scheme_to_be_skipped,
    const std::vector<string16>& protected_origins) {
  if (!BrowserThread::CurrentlyOn(BrowserThread::WEBKIT)) {
    bool result = BrowserThread::PostTask(
        BrowserThread::WEBKIT, FROM_HERE,
        NewRunnableMethod(this, &WebKitContext::DeleteDataModifiedSince,
                          cutoff, url_scheme_to_be_skipped, protected_origins));
    DCHECK(result);
    return;
  }

  dom_storage_context_->DeleteDataModifiedSince(
      cutoff, url_scheme_to_be_skipped, protected_origins);
}

void WebKitContext::DeleteSessionStorageNamespace(
    int64 session_storage_namespace_id) {
  if (!BrowserThread::CurrentlyOn(BrowserThread::WEBKIT)) {
    BrowserThread::PostTask(
        BrowserThread::WEBKIT, FROM_HERE,
        NewRunnableMethod(this, &WebKitContext::DeleteSessionStorageNamespace,
                          session_storage_namespace_id));
    return;
  }

  dom_storage_context_->DeleteSessionStorageNamespace(
      session_storage_namespace_id);
}
<commit_msg>Don't assert  if PostTask fails for WEBKIT thread, since it doesn't exist on single-process mode.  This asserts when the cache is cleared. Review URL: http://codereview.chromium.org/4165007<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/in_process_webkit/webkit_context.h"

#include "base/command_line.h"
#include "chrome/browser/browser_thread.h"
#include "chrome/browser/profile.h"
#include "chrome/common/chrome_switches.h"

WebKitContext::WebKitContext(Profile* profile)
    : data_path_(profile->IsOffTheRecord() ? FilePath() : profile->GetPath()),
      is_incognito_(profile->IsOffTheRecord()),
      ALLOW_THIS_IN_INITIALIZER_LIST(
          dom_storage_context_(new DOMStorageContext(this))),
      ALLOW_THIS_IN_INITIALIZER_LIST(
          indexed_db_context_(new IndexedDBContext(this))) {
}

WebKitContext::~WebKitContext() {
  // If the WebKit thread was ever spun up, delete the object there.  The task
  // will just get deleted if the WebKit thread isn't created (which only
  // happens during testing).
  DOMStorageContext* dom_storage_context = dom_storage_context_.release();
  if (!BrowserThread::DeleteSoon(
          BrowserThread::WEBKIT, FROM_HERE, dom_storage_context)) {
    // The WebKit thread wasn't created, and the task got deleted without
    // freeing the DOMStorageContext, so delete it manually.
    delete dom_storage_context;
  }

  IndexedDBContext* indexed_db_context = indexed_db_context_.release();
  if (!BrowserThread::DeleteSoon(
          BrowserThread::WEBKIT, FROM_HERE, indexed_db_context)) {
    delete indexed_db_context;
  }
}

void WebKitContext::PurgeMemory() {
  if (!BrowserThread::CurrentlyOn(BrowserThread::WEBKIT)) {
    BrowserThread::PostTask(
        BrowserThread::WEBKIT, FROM_HERE,
        NewRunnableMethod(this, &WebKitContext::PurgeMemory));
    return;
  }

  dom_storage_context_->PurgeMemory();
}

void WebKitContext::DeleteDataModifiedSince(
    const base::Time& cutoff,
    const char* url_scheme_to_be_skipped,
    const std::vector<string16>& protected_origins) {
  if (!BrowserThread::CurrentlyOn(BrowserThread::WEBKIT)) {
    BrowserThread::PostTask(
        BrowserThread::WEBKIT, FROM_HERE,
        NewRunnableMethod(this, &WebKitContext::DeleteDataModifiedSince,
                          cutoff, url_scheme_to_be_skipped, protected_origins));
    return;
  }

  dom_storage_context_->DeleteDataModifiedSince(
      cutoff, url_scheme_to_be_skipped, protected_origins);
}

void WebKitContext::DeleteSessionStorageNamespace(
    int64 session_storage_namespace_id) {
  if (!BrowserThread::CurrentlyOn(BrowserThread::WEBKIT)) {
    BrowserThread::PostTask(
        BrowserThread::WEBKIT, FROM_HERE,
        NewRunnableMethod(this, &WebKitContext::DeleteSessionStorageNamespace,
                          session_storage_namespace_id));
    return;
  }

  dom_storage_context_->DeleteSessionStorageNamespace(
      session_storage_namespace_id);
}
<|endoftext|>


<commit_before>#include <zmq.hpp>
#include <string>
#include <iostream>
#ifndef _WIN32
#include <unistd.h>
#else
#include <windows.h>

//#define sleep(n)    Sleep(n)
#endif

int main(int argc, char *argv[]) {
	//  Prepare our context and socket
	zmq::context_t context(1);
	zmq::socket_t socket(context, ZMQ_REP);
	socket.bind("tcp://*:5577");

	while (true) {
		zmq::message_t request;

		//  Wait for next request from client
		socket.recv(&request);
		std::cout << "Received: " << (char *)request.data() << std::endl;

		//  Do some 'work'
		// sleep(1);

		//  Send reply back to client
		zmq::message_t reply(5);
		memcpy(reply.data(), "DONE", 5);
		socket.send(reply);
	}
	return 0;
}
<commit_msg>Enable IPV6<commit_after>#include <zmq.hpp>
#include <string>
#include <iostream>
#ifndef _WIN32
#include <unistd.h>
#else
#include <windows.h>

//#define sleep(n)    Sleep(n)
#endif

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

	//  Prepare our context and socket
	zmq::context_t context(1);
	zmq::socket_t socket(context, ZMQ_REP);

	int opt = 1;
	socket.setsockopt(ZMQ_IPV6, &opt, sizeof(int));
	socket.bind("tcp://*:5577");

	while (true) {
		zmq::message_t request;

		//  Wait for next request from client
		socket.recv(&request);
		std::cout << "Received: " << (char *)request.data() << std::endl;

		//  Do some 'work'
		// sleep(1);

		//  Send reply back to client
		zmq::message_t reply(5);
		memcpy(reply.data(), "DONE", 5);
		socket.send(reply);
	}
	return 0;
}
<|endoftext|>


<commit_before>#include <iostream>
#include <string>
#include <set>
#include <queue>
#include <map>
#include <sstream>
#include <string>
#include <fstream>

#include "Graph.h"

using namespace std;

class VertexEntry
{
  public:

  Vertex* v;
  //static int idc;

  VertexEntry(const Vertex* pV)
  {
    v = (Vertex*) &(*pV);
  }
/*
  VertexEntry& operator=(const VertexEntry & rhs)
  {
    if(this != &rhs)
    {
      if(rhs.v){ v = new Vertex(*rhs.v); }
      //v = (Vertex*) &(*rhs.v);
    }
    return *this;
  }
*/
  bool operator==(const VertexEntry & rhs)
  {
    return *v == *(rhs.v);
  }

  bool operator<(const VertexEntry & rhs)
  {
    return v->d < rhs.v->d;
  }

  bool operator>(const VertexEntry & rhs)
  {
    //return !(*this < rhs);
    return v->d > rhs.v->d;
  }

};

//int VertexEntry::idc = 0;
bool operator==(VertexEntry lhs, VertexEntry rhs) { return *lhs.v == *rhs.v;    };
bool operator>(VertexEntry lhs, VertexEntry rhs)  { return lhs.v->d > rhs.v->d; };
bool operator<(VertexEntry lhs, VertexEntry rhs)  { return lhs.v->d < rhs.v->d; };

/*
void set_input()
{
  src = 0; tgt = 5;
  cout << "Input source city index: " << src << endl;
  cout << "Input destination city index: " << tgt << endl;
  cout << "Computing shortest path from: " << src << " to "
       << tgt << endl;
}
*/

string srcstr, tgtstr;
Graph g(false, true);
map<int, Point> cities;
int NV, NE;

/**
 *
 */
void get_input()
{
  cout << "Input source city index: ";
  cin >> srcstr;
  cout << "Input destination city index: ";
  cin >> tgtstr;
  cout << "Computing shortest path from: " << srcstr << " to "
       << tgtstr << endl;
}

/**
 *
 */
bool make_graph(string input = "./doc/sample.txt")
{
  int          i  = 0;
  bool         ok = true;
  Point        p;
  string       s;
  stringstream ss;
  Vertex       *u,
               *v;

  cout << "Generating graph from file:  " << input << endl;

  ifstream in(input.c_str(), ios::in);

  if(in.is_open())
  {
    in >> NV >> NE;

    cout << "Map contains " << NV << " verticies (cities) and "
         << NE << " edges" << endl
         << "Generating city coordinates..." << endl;

    for( ; i < NV; ++i)
    {
      Vertex vtx;

      in >> vtx.p.idx;
      in >> vtx.p.x;
      in >> vtx.p.y;

      ss << vtx.p.idx;
      vtx.id = ss.str();
      ss.str(""); ss.clear();

      g.add_vertex(vtx);
    }

    cout << "Generated " << cities.size() << " city coordinates" << endl
         << "Connecting edges between cities in graph..." << endl;

    for(i = 0; i < NE && ok; ++i)
    {
      in >> s;
      u = g.get_vertex(s);
      in >> s;
      v = g.get_vertex(s);

      if(u && v)
      {
        cout << u->id << "->" << v->id << " | " << u->distance(*v)
             << endl;
        g.add_edge(u, v, u->distance(*v));
      }
      else
      {
        cerr << "Error: Could not locate verticies exiting..." << endl;
        ok = false;
      }
    }

    if (ok) cout << "Connected " << g.esize() << " edges" << endl;

    in.close();
  }
  else cerr << "Could not open: " << input << " for reading" << endl;

  return ok;
}

#define extract_min(q, u) { u = q.top().v; q.pop(); }

/**
 *
 */
void print_q(priority_queue<VertexEntry, vector<VertexEntry>, std::greater<VertexEntry> >& pq)
{
  cout << "Rendering Priority Queue..." << endl;
  priority_queue<VertexEntry, vector<VertexEntry>, std::greater<VertexEntry> > c;
  c = pq;
  while(!c.empty())
  {
    VertexEntry* ve = (VertexEntry*) &c.top();
    Vertex* u = ve->v;
    cout << "extract-min: " << "u[" << u->id << "]: " << u->d << endl;
    c.pop();
  }
}

/**
 *
 */
map< pair<string, string>, double> DIJKSTRA(Graph & g, Vertex* & src, Vertex* & tgt, map< pair<string, string>, double> pd)
{
  Vertex *v, *u;
  Edge* e;
  set<VertexEntry> s;
  float w;

  g.init_single_src(src);
  priority_queue<VertexEntry, vector<VertexEntry>, std::greater<VertexEntry> > pq;

  cout << "Dijkstra Initialized Using Min Priority Queue..." << endl;

  for(VertexMapIt i = g.VE.begin(); i != g.VE.end(); ++i)
  {
    v = (Vertex*) &i->first;
    VertexEntry ve(v);
    pq.push(ve);
  }

  print_q(pq);

  while(!pq.empty())
  {
    //extract_min(pq, u);
    //s.insert(VertexEntry(u));
    VertexEntry* ve = (VertexEntry*) &pq.top();
    u = ve->v;
    s.insert(*ve);
    pq.pop();
    cout << "extract-min: " << u->id << " : " << u->d << endl;
    AdjListIt ait = u->adj->begin();
    for( ; ait != u->adj->end(); ++ait)
    {
      v = *ait;
      w = g.get_edge(u, v)->cap;
      cout << "ud[" << u->id << "]: " << u->d << " vd[" << v->id << "]: "
           << v->d << " w: " << w << endl;
      g.relax(u, v, w);/*
      if(g.relax(*u, *v, e->cap))
      {
        pair<string, string> k = make_pair(u->id, v->id);
        pd[k] = v->d;
      }*/
    }
    cout << "Vertex[" << u->id << "] processed" << endl;
  }

  cout << "All pairs shortest path" << endl;

  for(set<VertexEntry>::iterator vei = s.begin(); vei != s.end(); ++vei)
  {
    VertexEntry ve = *vei;
    cout << "v[" << ve.v->id << "]: " << ve.v->d << endl;
  }

  cout << "All pairs shortest path complete...rendering path" << endl;

  Vertex* vtgt = g.get_vertex(*tgt);

  if(vtgt)
  {
    cout << vtgt->id << " -> ";
    Vertex* rent = vtgt->pi;
    while(rent)
    {
      cout << rent->id ;
      rent = rent->pi;
      if(rent) cout << " -> ";
    }
    cout << endl;

    VertexEntry ve(tgt);
    set<VertexEntry>::iterator sit = s.find(ve);
    if(sit != s.end())
    {
      VertexEntry ve = *sit;
      cout << "Total Distance: " << ve.v->d << endl;
    }
  }

  return pd;
}
/**
 *
 */
void PRINT_APSP(map< pair<string, string>, double> & apsp)
{
  cout << "Rendering APSP...\n";

  if(apsp.size() < 1)
  {
    cout << "None\n";
  }
  else
  {
    map< pair<string, string>, double>::iterator i = apsp.begin(),
                                        e = apsp.end();

    while(i != e)
    {
      cout << i->first.first << " -> " << i->first.second << " "
           << i->second << endl;
      ++i;
    }
  }
}

/**
 *
 */
int main(int argc, char* argv[])
{
  string mapfile;
  bool ok = true;

  if(argc == 2)
  {
   stringstream s;

    s << argv[1];
    s >> mapfile;
    ok = make_graph(mapfile);
  }
  else
  {
    ok = make_graph();
  }
  if(ok)
  {
    get_input();
/*
  Graph g(false, true);
  g.add_edge("0", "1", 4);
  g.add_edge("0", "7", 8);
  g.add_edge("1", "2", 8);
  g.add_edge("1", "7", 11);
  g.add_edge("2", "3", 7);
  g.add_edge("2", "8", 2);
  g.add_edge("2", "5", 4);
  g.add_edge("3", "4", 9);
  g.add_edge("3", "5", 14);
  g.add_edge("4", "5", 10);
  g.add_edge("5", "6", 2);
  g.add_edge("6", "7", 1);
  g.add_edge("6", "8", 6);
  g.add_edge("7", "8", 7);
*/
  //cout << g << endl;
    Vertex *src = g.get_vertex(srcstr),
           *tgt = g.get_vertex(tgtstr);
    if(!src)
      cout << "Error: Could not retrive source city " << srcstr << endl;
    else if(!src)
      cout << "Error: Could not retrive destination city " << tgtstr << endl;
    else
    {
      map< pair<string, string>, double> r;
      DIJKSTRA(g, src, tgt, r);
    }
  }

  return 0;
}
<commit_msg>Fixed opposite dir issue using make_heap to extract-min properly<commit_after>#include <iostream>
#include <string>
#include <set>
#include <queue>
#include <map>
#include <sstream>
#include <string>
#include <fstream>
#include <algorithm> //heapify

#include "Graph.h"

using namespace std;

class VertexEntry
{
  public:

  Vertex* v;
  //static int idc;

  VertexEntry()
  {
    v = 0;
  }

  VertexEntry(const Vertex* pV)
  {
    v = (Vertex*) &(*pV);
  }
/*
  VertexEntry& operator=(const VertexEntry & rhs)
  {
    if(this != &rhs)
    {
      if(rhs.v){ v = new Vertex(*rhs.v); }
      //v = (Vertex*) &(*rhs.v);
    }
    return *this;
  }
*/
  bool operator==(const VertexEntry & rhs)
  {
    return *v == *(rhs.v);
  }

  bool operator<(const VertexEntry & rhs)
  {
    return v->d < rhs.v->d;
  }

  bool operator>(const VertexEntry & rhs)
  {
    //return !(*this < rhs);
    return v->d > rhs.v->d;
  }

};

//int VertexEntry::idc = 0;
bool operator==(VertexEntry lhs, VertexEntry rhs) { return *lhs.v == *rhs.v;    };
bool operator>(VertexEntry lhs, VertexEntry rhs)  { return lhs.v->d > rhs.v->d; };
bool operator<(VertexEntry lhs, VertexEntry rhs)  { return lhs.v->d < rhs.v->d; };

bool mcomp(VertexEntry lhs, VertexEntry rhs)  { return lhs.v->d > rhs.v->d; };
/*
void set_input()
{
  src = 0; tgt = 5;
  cout << "Input source city index: " << src << endl;
  cout << "Input destination city index: " << tgt << endl;
  cout << "Computing shortest path from: " << src << " to "
       << tgt << endl;
}
*/

string srcstr, tgtstr;
Graph g(false, true);
map<int, Point> cities;
int NV, NE;

/**
 *
 */
void get_input()
{
  cout << "Input source city index: ";
  cin >> srcstr;
  cout << "Input destination city index: ";
  cin >> tgtstr;
  cout << "Computing shortest path from: " << srcstr << " to "
       << tgtstr << endl;
}

/**
 *
 */
bool make_graph(string input = "./doc/sample.txt")
{
  int          i  = 0;
  bool         ok = true;
  Point        p;
  string       s;
  stringstream ss;
  Vertex       *u,
               *v;

  cout << "Generating graph from file:  " << input << endl;

  ifstream in(input.c_str(), ios::in);

  if(in.is_open())
  {
    in >> NV >> NE;

    cout << "Map contains " << NV << " verticies (cities) and "
         << NE << " edges" << endl
         << "Generating city coordinates..." << endl;

    for( ; i < NV; ++i)
    {
      Vertex vtx;

      in >> vtx.p.idx;
      in >> vtx.p.x;
      in >> vtx.p.y;

      ss << vtx.p.idx;
      vtx.id = ss.str();
      ss.str(""); ss.clear();

      g.add_vertex(vtx);
    }

    cout << "Generated " << cities.size() << " city coordinates" << endl
         << "Connecting edges between cities in graph..." << endl;

    for(i = 0; i < NE && ok; ++i)
    {
      in >> s;
      u = g.get_vertex(s);
      in >> s;
      v = g.get_vertex(s);

      if(u && v)
      {
        cout << u->id << "->" << v->id << " | " << u->distance(*v)
             << endl;
        g.add_edge(u, v, u->distance(*v));
      }
      else
      {
        cerr << "Error: Could not locate verticies exiting..." << endl;
        ok = false;
      }
    }

    if (ok) cout << "Connected " << g.esize() << " edges" << endl;

    in.close();
    cout << g << endl;
  }
  else cerr << "Could not open: " << input << " for reading" << endl;

  return ok;
}

#define extract_min(q, u) { u = q.top().v; q.pop(); }

/**
 *
 */
void print_q(priority_queue<VertexEntry, vector<VertexEntry>, std::greater<VertexEntry> >& pq)
{
  cout << "Rendering Priority Queue..." << endl;
  priority_queue<VertexEntry, vector<VertexEntry>, std::greater<VertexEntry> > c;
  c = pq;
  while(!c.empty())
  {
    VertexEntry* ve = (VertexEntry*) &c.top();
    Vertex* u = ve->v;
    cout << "extract-min: " << "u[" << u->id << "]: " << u->d << endl;
    c.pop();
  }
}

/**
 *
 */
map< pair<string, string>, double> DIJKSTRA(Graph & g, Vertex* & src, Vertex* & tgt, map< pair<string, string>, double> pd)
{
  Vertex *v, *u;
  Edge* e;
  set<VertexEntry> s;
  float w;

  g.init_single_src(src);
  priority_queue<VertexEntry, vector<VertexEntry>, greater<VertexEntry> > pq;

  cout << "Dijkstra Initialized Using Min Priority Queue..." << endl;

  for(VertexMapIt i = g.VE.begin(); i != g.VE.end(); ++i)
  {
    v = (Vertex*) &i->first;
    VertexEntry ve(v);
    pq.push(ve);
  }

  while(!pq.empty())
  {
    //extract_min(pq, u);
    //s.insert(VertexEntry(u));
    print_q(pq);
    VertexEntry* ve = (VertexEntry*) &pq.top();
    u = ve->v;
    s.insert(*ve);
    pq.pop();
    cout << "extract-min: " << u->id << " : " << u->d << endl;
    AdjListIt ait = u->adj->begin();
    for( ; ait != u->adj->end(); ++ait)
    {
      v = *ait;
      w = g.get_edge(u, v)->cap;
      cout << "ud[" << u->id << "]: " << u->d << " vd[" << v->id << "]: "
           << v->d << " w: " << w << endl;
      if(g.relax(u, v, w))
      {
        cout << "-------RELAX-------" << endl;
        cout << "ud[" << u->id << "]: " << u->d << " vd[" << v->id << "]: "
             << v->d << " w: " << w << endl;
        cout << "-------RELAX-------" << endl;
      }/*
      if(g.relax(*u, *v, e->cap))
      {
        pair<string, string> k = make_pair(u->id, v->id);
        pd[k] = v->d;
      }*/
    }
    cout << "Vertex[" << u->id << "] processed" << endl;
    make_heap(const_cast<VertexEntry*>(&pq.top()), const_cast<VertexEntry*>(&pq.top()) + pq.size(), mcomp);
  }

  cout << "All pairs shortest path" << endl;

  for(set<VertexEntry>::iterator vei = s.begin(); vei != s.end(); ++vei)
  {
    VertexEntry ve = *vei;
    cout << "v[" << ve.v->id << "]: " << ve.v->d << endl;
  }

  cout << "All pairs shortest path complete...rendering path" << endl;

  Vertex* vtgt = g.get_vertex(*tgt);

  if(vtgt)
  {
    cout << vtgt->id << " -> ";
    Vertex* rent = vtgt->pi;
    while(rent)
    {
      cout << rent->id ;
      rent = rent->pi;
      if(rent) cout << " -> ";
    }
    cout << endl;

    VertexEntry ve(tgt);
    set<VertexEntry>::iterator sit = s.find(ve);
    if(sit != s.end())
    {
      VertexEntry ve = *sit;
      cout << "Total Distance: " << ve.v->d << endl;
    }
  }

  return pd;
}
/**
 *
 */
void PRINT_APSP(map< pair<string, string>, double> & apsp)
{
  cout << "Rendering APSP...\n";

  if(apsp.size() < 1)
  {
    cout << "None\n";
  }
  else
  {
    map< pair<string, string>, double>::iterator i = apsp.begin(),
                                        e = apsp.end();

    while(i != e)
    {
      cout << i->first.first << " -> " << i->first.second << " "
           << i->second << endl;
      ++i;
    }
  }
}

/**
 *
 */
int main(int argc, char* argv[])
{
  string mapfile;
  bool ok = true;

  if(argc == 2)
  {
   stringstream s;

    s << argv[1];
    s >> mapfile;
    ok = make_graph(mapfile);
  }
  else
  {
    ok = make_graph();
  }
  if(ok)
  {
    get_input();
/*
  Graph g(false, true);
  g.add_edge("0", "1", 4);
  g.add_edge("0", "7", 8);
  g.add_edge("1", "2", 8);
  g.add_edge("1", "7", 11);
  g.add_edge("2", "3", 7);
  g.add_edge("2", "8", 2);
  g.add_edge("2", "5", 4);
  g.add_edge("3", "4", 9);
  g.add_edge("3", "5", 14);
  g.add_edge("4", "5", 10);
  g.add_edge("5", "6", 2);
  g.add_edge("6", "7", 1);
  g.add_edge("6", "8", 6);
  g.add_edge("7", "8", 7);
*/
  //cout << g << endl;
    Vertex *src = g.get_vertex(srcstr),
           *tgt = g.get_vertex(tgtstr);
    if(!src)
      cout << "Error: Could not retrive source city " << srcstr << endl;
    else if(!src)
      cout << "Error: Could not retrive destination city " << tgtstr << endl;
    else
    {
      map< pair<string, string>, double> r;
      DIJKSTRA(g, src, tgt, r);
    }
  }

  return 0;
}
<|endoftext|>


<commit_before>#ifndef BULL_CORE_FILESYSTEM_FILE_HPP
#define BULL_CORE_FILESYSTEM_FILE_HPP

#include <memory>

#include <Bull/Core/FileSystem/FileOpeningMode.hpp>
#include <Bull/Core/FileSystem/Path.hpp>
#include <Bull/Core/IO/CursorAwareInStream.hpp>
#include <Bull/Core/IO/OutStream.hpp>
#include <Bull/Core/Pattern/NonCopyable.hpp>
#include <Bull/Core/Time/DateTime.hpp>

namespace Bull
{
    namespace prv
    {
        class FileImpl;
    }

    class BULL_CORE_API File : public NonCopyable, public CursorAwareInStream, public OutStream
    {
    private:

        #if defined BULL_OS_WINDOWS
            static constexpr const char* EndOfLine = "\r\n";
        #else
            static constexpr char EndOfLine = '\n';
        #endif

    public:

        /*! \brief Create a File
         *
         * \param path The Path of the file to create
         *
         */
        static void create(const Path& path);

        /*! \brief Tell whether a File exists
         *
         * \param path The Path of the File
         *
         * \return True if the file exists
         *
         */
        static bool exists(const Path& path);

        /*! \brief Copy a File
         *
         * \param path    The Path of the file to copy
         * \param newPath The new Path copied File
         *
         */
        static void copy(const Path& path, const Path& newPath);

        /*! \brief Rename a File
         *
         * \param path    The Path of the File to rename
         * \param newPath The new Path of the File
         *
         */
        static void rename(const Path& path, const Path& newPath);

        /*! \brief Delete a File
         *
         * \param path The Path of the File to delete
         *
         */
        static void remove(const Path& path);

    public:

        /*! \brief Default constructor
         *
         */
        File();

        /*! \brief Constructor
         *
         * \param path The Path of the file to open
         * \param mode The opening mode of the file (read, write or both)
         *
         */
        explicit File(const Path& path, Uint32 mode = FileOpeningMode_Read | FileOpeningMode_Write);

        /*! \brief Constructor by movement
         *
         * \param file The File to move
         *
         */
        File(File&& file) noexcept = default;

        /*! \brief Destructor
         *
         */
        ~File();

        /*! \brief Basic assignment operator by movement
         *
         * \param File The File to move
         *
         * \return This
         *
         */
        File& operator=(File&& file) noexcept = default;

        /*! \brief Open the File
         *
         * \param path The path of the file to open
         * \param mode The opening mode of the file (read, write or both)
         *
         */
        void open(const Path& path, Uint32 mode);

        /*! \brief Read bytes from the File
         *
         * \param length The length of data to read
         *
         * \return Read bytes
         *
         */
        ByteArray read(std::size_t length) override;

        /*! \brief Write data into the File
         *
         * \param bytes Bytes to write
         *
         * \return Return the number of bytes written
         *
         */
        std::size_t write(const ByteArray& bytes) override;

        /*! \brief Flush the File
         *
         */
        void flush() override;

        /*! \brief Get the date of the creation of the file
         *
         * \return Return the date of the creation of the file
         *
         */
        DateTime getCreationDate() const;

        /*! \brief Get the date of the creation of the file
         *
         * \return Return the date of the last access of the file
         *
         */
        DateTime getLastAccessDate() const;

        /*! \brief Get the date of the creation of the file
         *
         * \return Return the date of the last write of the file
         *
         */
        DateTime getLastWriteDate() const;

        /*! \brief Get the position of the cursor in the file
         *
         * \return Return the position of the cursor in the file
         *
         */
        std::size_t getCursor() const override;

        /*! \brief Move the reading position in the file
         *
         * \param offset The offset to move the cursor
         *
         * \return Return the actual position of the cursor
         *
         */
        std::size_t moveCursor(Int64 offset);

        /*! \brief Set the reading position in the file
         *
         * \param position The position to seek to
         *
         * \return Return the actual position of the cursor
         *
         */
        std::size_t setCursor(std::size_t position) override;

        /*! \brief Get the path of the file
         *
         * \return Return the path of the file
         *
         */
        inline const Path& getPath() const
        {
            return m_path;
        }

        /*! \brief Get the size of the file
         *
         * \return Return the size of the file
         *
         */
        std::size_t getSize() const override;

    private:

        Path                           m_path;
        Uint32                         m_mode;
        std::unique_ptr<prv::FileImpl> m_impl;
    };
}

#endif // BULL_CORE_FILESYSTEM_FILE_HPP
<commit_msg>[Core/File] Add a default opening mode on method open<commit_after>#ifndef BULL_CORE_FILESYSTEM_FILE_HPP
#define BULL_CORE_FILESYSTEM_FILE_HPP

#include <memory>

#include <Bull/Core/FileSystem/FileOpeningMode.hpp>
#include <Bull/Core/FileSystem/Path.hpp>
#include <Bull/Core/IO/CursorAwareInStream.hpp>
#include <Bull/Core/IO/OutStream.hpp>
#include <Bull/Core/Pattern/NonCopyable.hpp>
#include <Bull/Core/Time/DateTime.hpp>

namespace Bull
{
    namespace prv
    {
        class FileImpl;
    }

    class BULL_CORE_API File : public NonCopyable, public CursorAwareInStream, public OutStream
    {
    private:

        #if defined BULL_OS_WINDOWS
            static constexpr const char* EndOfLine = "\r\n";
        #else
            static constexpr char EndOfLine = '\n';
        #endif

    public:

        /*! \brief Create a File
         *
         * \param path The Path of the file to create
         *
         */
        static void create(const Path& path);

        /*! \brief Tell whether a File exists
         *
         * \param path The Path of the File
         *
         * \return True if the file exists
         *
         */
        static bool exists(const Path& path);

        /*! \brief Copy a File
         *
         * \param path    The Path of the file to copy
         * \param newPath The new Path copied File
         *
         */
        static void copy(const Path& path, const Path& newPath);

        /*! \brief Rename a File
         *
         * \param path    The Path of the File to rename
         * \param newPath The new Path of the File
         *
         */
        static void rename(const Path& path, const Path& newPath);

        /*! \brief Delete a File
         *
         * \param path The Path of the File to delete
         *
         */
        static void remove(const Path& path);

    public:

        /*! \brief Default constructor
         *
         */
        File();

        /*! \brief Constructor
         *
         * \param path The Path of the file to open
         * \param mode The opening mode of the file (read, write or both)
         *
         */
        explicit File(const Path& path, Uint32 mode = FileOpeningMode_Read | FileOpeningMode_Write);

        /*! \brief Constructor by movement
         *
         * \param file The File to move
         *
         */
        File(File&& file) noexcept = default;

        /*! \brief Destructor
         *
         */
        ~File();

        /*! \brief Basic assignment operator by movement
         *
         * \param File The File to move
         *
         * \return This
         *
         */
        File& operator=(File&& file) noexcept = default;

        /*! \brief Open the File
         *
         * \param path The path of the file to open
         * \param mode The opening mode of the file
         *
         */
        void open(const Path& path, Uint32 mode = FileOpeningMode_Read | FileOpeningMode_Write);

        /*! \brief Read bytes from the File
         *
         * \param length The length of data to read
         *
         * \return Read bytes
         *
         */
        ByteArray read(std::size_t length) override;

        /*! \brief Write data into the File
         *
         * \param bytes Bytes to write
         *
         * \return Return the number of bytes written
         *
         */
        std::size_t write(const ByteArray& bytes) override;

        /*! \brief Flush the File
         *
         */
        void flush() override;

        /*! \brief Get the date of the creation of the file
         *
         * \return Return the date of the creation of the file
         *
         */
        DateTime getCreationDate() const;

        /*! \brief Get the date of the creation of the file
         *
         * \return Return the date of the last access of the file
         *
         */
        DateTime getLastAccessDate() const;

        /*! \brief Get the date of the creation of the file
         *
         * \return Return the date of the last write of the file
         *
         */
        DateTime getLastWriteDate() const;

        /*! \brief Get the position of the cursor in the file
         *
         * \return Return the position of the cursor in the file
         *
         */
        std::size_t getCursor() const override;

        /*! \brief Move the reading position in the file
         *
         * \param offset The offset to move the cursor
         *
         * \return Return the actual position of the cursor
         *
         */
        std::size_t moveCursor(Int64 offset);

        /*! \brief Set the reading position in the file
         *
         * \param position The position to seek to
         *
         * \return Return the actual position of the cursor
         *
         */
        std::size_t setCursor(std::size_t position) override;

        /*! \brief Get the path of the file
         *
         * \return Return the path of the file
         *
         */
        inline const Path& getPath() const
        {
            return m_path;
        }

        /*! \brief Get the size of the file
         *
         * \return Return the size of the file
         *
         */
        std::size_t getSize() const override;

    private:

        Path                           m_path;
        Uint32                         m_mode;
        std::unique_ptr<prv::FileImpl> m_impl;
    };
}

#endif // BULL_CORE_FILESYSTEM_FILE_HPP
<|endoftext|>