<commit_before>#include "GodotGlobal.hpp"

#include "String.hpp"

#include "Wrapped.hpp"

static GDCALLINGCONV void *wrapper_create(void *data, const void *type_tag, godot_object *instance) {
	godot::_Wrapped *wrapper_memory = (godot::_Wrapped *)godot::api->godot_alloc(sizeof(godot::_Wrapped));

	if (!wrapper_memory)
		return NULL;
	wrapper_memory->_owner = instance;
	wrapper_memory->_type_tag = (size_t)type_tag;

	return (void *)wrapper_memory;
}

static GDCALLINGCONV void wrapper_destroy(void *data, void *wrapper) {
	if (wrapper)
		godot::api->godot_free(wrapper);
}

namespace godot {

void *_RegisterState::nativescript_handle;
int _RegisterState::language_index;

const godot_gdnative_core_api_struct *api = nullptr;
const godot_gdnative_core_1_1_api_struct *core_1_1_api = nullptr;
const godot_gdnative_core_1_2_api_struct *core_1_2_api = nullptr;

const godot_gdnative_ext_nativescript_api_struct *nativescript_api = nullptr;
const godot_gdnative_ext_nativescript_1_1_api_struct *nativescript_1_1_api = nullptr;
const godot_gdnative_ext_pluginscript_api_struct *pluginscript_api = nullptr;
const godot_gdnative_ext_android_api_struct *android_api = nullptr;
const godot_gdnative_ext_arvr_api_struct *arvr_api = nullptr;
const godot_gdnative_ext_videodecoder_api_struct *videodecoder_api = nullptr;
const godot_gdnative_ext_net_api_struct *net_api = nullptr;
const godot_gdnative_ext_net_3_2_api_struct *net_3_2_api = nullptr;

const void *gdnlib = NULL;

void Godot::print(const String &message) {
	godot::api->godot_print((godot_string *)&message);
}

void Godot::print_warning(const String &description, const String &function, const String &file, int line) {
	int len;

	char *c_desc = description.alloc_c_string();
	char *c_func = function.alloc_c_string();
	char *c_file = file.alloc_c_string();

	if (c_desc != nullptr && c_func != nullptr && c_file != nullptr) {
		godot::api->godot_print_warning(c_desc, c_func, c_file, line);
	};

	if (c_desc != nullptr) godot::api->godot_free(c_desc);
	if (c_func != nullptr) godot::api->godot_free(c_func);
	if (c_file != nullptr) godot::api->godot_free(c_file);
}

void Godot::print_error(const String &description, const String &function, const String &file, int line) {
	int len;

	char *c_desc = description.alloc_c_string();
	char *c_func = function.alloc_c_string();
	char *c_file = file.alloc_c_string();

	if (c_desc != nullptr && c_func != nullptr && c_file != nullptr) {
		godot::api->godot_print_error(c_desc, c_func, c_file, line);
	};

	if (c_desc != nullptr) godot::api->godot_free(c_desc);
	if (c_func != nullptr) godot::api->godot_free(c_func);
	if (c_file != nullptr) godot::api->godot_free(c_file);
}

void ___register_types();
void ___init_method_bindings();

void Godot::gdnative_init(godot_gdnative_init_options *options) {
	godot::api = options->api_struct;
	godot::gdnlib = options->gd_native_library;

	const godot_gdnative_api_struct *core_extension = godot::api->next;

	while (core_extension) {
		if (core_extension->version.major == 1 && core_extension->version.minor == 1) {
			godot::core_1_1_api = (const godot_gdnative_core_1_1_api_struct *)core_extension;
		} else if (core_extension->version.major == 1 && core_extension->version.minor == 2) {
			godot::core_1_2_api = (const godot_gdnative_core_1_2_api_struct *)core_extension;
		}
		core_extension = core_extension->next;
	}

	// now find our extensions
	for (int i = 0; i < godot::api->num_extensions; i++) {
		switch (godot::api->extensions[i]->type) {
			case GDNATIVE_EXT_NATIVESCRIPT: {
				godot::nativescript_api = (const godot_gdnative_ext_nativescript_api_struct *)godot::api->extensions[i];

				const godot_gdnative_api_struct *extension = godot::nativescript_api->next;

				while (extension) {
					if (extension->version.major == 1 && extension->version.minor == 1) {
						godot::nativescript_1_1_api = (const godot_gdnative_ext_nativescript_1_1_api_struct *)extension;
					}

					extension = extension->next;
				}
			} break;
			case GDNATIVE_EXT_PLUGINSCRIPT: {
				godot::pluginscript_api = (const godot_gdnative_ext_pluginscript_api_struct *)godot::api->extensions[i];
			} break;
			case GDNATIVE_EXT_ANDROID: {
				godot::android_api = (const godot_gdnative_ext_android_api_struct *)godot::api->extensions[i];
			} break;
			case GDNATIVE_EXT_ARVR: {
				godot::arvr_api = (const godot_gdnative_ext_arvr_api_struct *)godot::api->extensions[i];
			} break;
			case GDNATIVE_EXT_VIDEODECODER: {
				godot::videodecoder_api = (const godot_gdnative_ext_videodecoder_api_struct *)godot::api->extensions[i];
			} break;
			case GDNATIVE_EXT_NET: {
				godot::net_api = (const godot_gdnative_ext_net_api_struct *)godot::api->extensions[i];

				const godot_gdnative_api_struct *extension = godot::net_api->next;

				while (extension) {
					if (extension->version.major == 3 && extension->version.minor == 2) {
						godot::net_3_2_api = (const godot_gdnative_ext_net_3_2_api_struct *)extension;
					}

					extension = extension->next;
				}
			} break;

			default: break;
		}
	}
}

void Godot::gdnative_terminate(godot_gdnative_terminate_options *options) {
	// reserved for future use.
}

void Godot::gdnative_profiling_add_data(const char *p_signature, uint64_t p_time) {
	godot::nativescript_1_1_api->godot_nativescript_profiling_add_data(p_signature, p_time);
}

void Godot::nativescript_init(void *handle) {
	godot::_RegisterState::nativescript_handle = handle;

	godot_instance_binding_functions binding_funcs = {};
	binding_funcs.alloc_instance_binding_data = wrapper_create;
	binding_funcs.free_instance_binding_data = wrapper_destroy;

	godot::_RegisterState::language_index = godot::nativescript_1_1_api->godot_nativescript_register_instance_binding_data_functions(binding_funcs);

	___register_types();
	___init_method_bindings();
}

void Godot::nativescript_terminate(void *handle) {
	godot::nativescript_1_1_api->godot_nativescript_unregister_instance_binding_data_functions(godot::_RegisterState::language_index);
}

} // namespace godot
<commit_msg>Call register types and init earlier<commit_after>#include "GodotGlobal.hpp"

#include "String.hpp"

#include "Wrapped.hpp"

static GDCALLINGCONV void *wrapper_create(void *data, const void *type_tag, godot_object *instance) {
	godot::_Wrapped *wrapper_memory = (godot::_Wrapped *)godot::api->godot_alloc(sizeof(godot::_Wrapped));

	if (!wrapper_memory)
		return NULL;
	wrapper_memory->_owner = instance;
	wrapper_memory->_type_tag = (size_t)type_tag;

	return (void *)wrapper_memory;
}

static GDCALLINGCONV void wrapper_destroy(void *data, void *wrapper) {
	if (wrapper)
		godot::api->godot_free(wrapper);
}

namespace godot {

void *_RegisterState::nativescript_handle;
int _RegisterState::language_index;

const godot_gdnative_core_api_struct *api = nullptr;
const godot_gdnative_core_1_1_api_struct *core_1_1_api = nullptr;
const godot_gdnative_core_1_2_api_struct *core_1_2_api = nullptr;

const godot_gdnative_ext_nativescript_api_struct *nativescript_api = nullptr;
const godot_gdnative_ext_nativescript_1_1_api_struct *nativescript_1_1_api = nullptr;
const godot_gdnative_ext_pluginscript_api_struct *pluginscript_api = nullptr;
const godot_gdnative_ext_android_api_struct *android_api = nullptr;
const godot_gdnative_ext_arvr_api_struct *arvr_api = nullptr;
const godot_gdnative_ext_videodecoder_api_struct *videodecoder_api = nullptr;
const godot_gdnative_ext_net_api_struct *net_api = nullptr;
const godot_gdnative_ext_net_3_2_api_struct *net_3_2_api = nullptr;

const void *gdnlib = NULL;

void Godot::print(const String &message) {
	godot::api->godot_print((godot_string *)&message);
}

void Godot::print_warning(const String &description, const String &function, const String &file, int line) {
	int len;

	char *c_desc = description.alloc_c_string();
	char *c_func = function.alloc_c_string();
	char *c_file = file.alloc_c_string();

	if (c_desc != nullptr && c_func != nullptr && c_file != nullptr) {
		godot::api->godot_print_warning(c_desc, c_func, c_file, line);
	};

	if (c_desc != nullptr) godot::api->godot_free(c_desc);
	if (c_func != nullptr) godot::api->godot_free(c_func);
	if (c_file != nullptr) godot::api->godot_free(c_file);
}

void Godot::print_error(const String &description, const String &function, const String &file, int line) {
	int len;

	char *c_desc = description.alloc_c_string();
	char *c_func = function.alloc_c_string();
	char *c_file = file.alloc_c_string();

	if (c_desc != nullptr && c_func != nullptr && c_file != nullptr) {
		godot::api->godot_print_error(c_desc, c_func, c_file, line);
	};

	if (c_desc != nullptr) godot::api->godot_free(c_desc);
	if (c_func != nullptr) godot::api->godot_free(c_func);
	if (c_file != nullptr) godot::api->godot_free(c_file);
}

void ___register_types();
void ___init_method_bindings();

void Godot::gdnative_init(godot_gdnative_init_options *options) {
	godot::api = options->api_struct;
	godot::gdnlib = options->gd_native_library;

	const godot_gdnative_api_struct *core_extension = godot::api->next;

	while (core_extension) {
		if (core_extension->version.major == 1 && core_extension->version.minor == 1) {
			godot::core_1_1_api = (const godot_gdnative_core_1_1_api_struct *)core_extension;
		} else if (core_extension->version.major == 1 && core_extension->version.minor == 2) {
			godot::core_1_2_api = (const godot_gdnative_core_1_2_api_struct *)core_extension;
		}
		core_extension = core_extension->next;
	}

	// now find our extensions
	for (int i = 0; i < godot::api->num_extensions; i++) {
		switch (godot::api->extensions[i]->type) {
			case GDNATIVE_EXT_NATIVESCRIPT: {
				godot::nativescript_api = (const godot_gdnative_ext_nativescript_api_struct *)godot::api->extensions[i];

				const godot_gdnative_api_struct *extension = godot::nativescript_api->next;

				while (extension) {
					if (extension->version.major == 1 && extension->version.minor == 1) {
						godot::nativescript_1_1_api = (const godot_gdnative_ext_nativescript_1_1_api_struct *)extension;
					}

					extension = extension->next;
				}
			} break;
			case GDNATIVE_EXT_PLUGINSCRIPT: {
				godot::pluginscript_api = (const godot_gdnative_ext_pluginscript_api_struct *)godot::api->extensions[i];
			} break;
			case GDNATIVE_EXT_ANDROID: {
				godot::android_api = (const godot_gdnative_ext_android_api_struct *)godot::api->extensions[i];
			} break;
			case GDNATIVE_EXT_ARVR: {
				godot::arvr_api = (const godot_gdnative_ext_arvr_api_struct *)godot::api->extensions[i];
			} break;
			case GDNATIVE_EXT_VIDEODECODER: {
				godot::videodecoder_api = (const godot_gdnative_ext_videodecoder_api_struct *)godot::api->extensions[i];
			} break;
			case GDNATIVE_EXT_NET: {
				godot::net_api = (const godot_gdnative_ext_net_api_struct *)godot::api->extensions[i];

				const godot_gdnative_api_struct *extension = godot::net_api->next;

				while (extension) {
					if (extension->version.major == 3 && extension->version.minor == 2) {
						godot::net_3_2_api = (const godot_gdnative_ext_net_3_2_api_struct *)extension;
					}

					extension = extension->next;
				}
			} break;

			default: break;
		}
	}

	// register these now
	___register_types();
	___init_method_bindings();
}

void Godot::gdnative_terminate(godot_gdnative_terminate_options *options) {
	// reserved for future use.
}

void Godot::gdnative_profiling_add_data(const char *p_signature, uint64_t p_time) {
	godot::nativescript_1_1_api->godot_nativescript_profiling_add_data(p_signature, p_time);
}

void Godot::nativescript_init(void *handle) {
	godot::_RegisterState::nativescript_handle = handle;

	godot_instance_binding_functions binding_funcs = {};
	binding_funcs.alloc_instance_binding_data = wrapper_create;
	binding_funcs.free_instance_binding_data = wrapper_destroy;

	godot::_RegisterState::language_index = godot::nativescript_1_1_api->godot_nativescript_register_instance_binding_data_functions(binding_funcs);
}

void Godot::nativescript_terminate(void *handle) {
	godot::nativescript_1_1_api->godot_nativescript_unregister_instance_binding_data_functions(godot::_RegisterState::language_index);
}

} // namespace godot
<|endoftext|>


<commit_before>/*
 * Copyright 2010 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkImageInfoPriv.h"
#include "SkSafeMath.h"
#include "SkReadBuffer.h"
#include "SkWriteBuffer.h"

int SkColorTypeBytesPerPixel(SkColorType ct) {
    switch (ct) {
        case kUnknown_SkColorType:      return 0;
        case kAlpha_8_SkColorType:      return 1;
        case kRGB_565_SkColorType:      return 2;
        case kARGB_4444_SkColorType:    return 2;
        case kRGBA_8888_SkColorType:    return 4;
        case kBGRA_8888_SkColorType:    return 4;
        case kRGB_888x_SkColorType:     return 4;
        case kRGBA_1010102_SkColorType: return 4;
        case kRGB_101010x_SkColorType:  return 4;
        case kGray_8_SkColorType:       return 1;
        case kRGBA_F16_SkColorType:     return 8;
    }
    return 0;
}

// These values must be constant over revisions, though they can be renamed to reflect if/when
// they are deprecated.
enum Stored_SkColorType {
    kUnknown_Stored_SkColorType             = 0,
    kAlpha_8_Stored_SkColorType             = 1,
    kRGB_565_Stored_SkColorType             = 2,
    kARGB_4444_Stored_SkColorType           = 3,
    kRGBA_8888_Stored_SkColorType           = 4,
    kBGRA_8888_Stored_SkColorType           = 5,
    kIndex_8_Stored_SkColorType_DEPRECATED  = 6,
    kGray_8_Stored_SkColorType              = 7,
    kRGBA_F16_Stored_SkColorType            = 8,
    kRGB_888x_Stored_SkColorType            = 9,
    kRGBA_1010102_Stored_SkColorType        = 10,
    kRGB_101010x_Stored_SkColorType         = 11,
};

bool SkColorTypeIsAlwaysOpaque(SkColorType ct) {
    return !(kAlpha_SkColorTypeComponentFlag & SkColorTypeComponentFlags(ct));
}

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

int SkImageInfo::bytesPerPixel() const { return SkColorTypeBytesPerPixel(fColorType); }

int SkImageInfo::shiftPerPixel() const { return SkColorTypeShiftPerPixel(fColorType); }

size_t SkImageInfo::computeOffset(int x, int y, size_t rowBytes) const {
    SkASSERT((unsigned)x < (unsigned)fWidth);
    SkASSERT((unsigned)y < (unsigned)fHeight);
    return SkColorTypeComputeOffset(fColorType, x, y, rowBytes);
}

size_t SkImageInfo::computeByteSize(size_t rowBytes) const {
    if (0 == fHeight) {
        return 0;
    }
    SkSafeMath safe;
    size_t bytes = safe.add(safe.mul(fHeight - 1, rowBytes),
                            safe.mul(fWidth, this->bytesPerPixel()));
    return safe ? bytes : SK_MaxSizeT;
}

SkImageInfo SkImageInfo::MakeS32(int width, int height, SkAlphaType at) {
    return SkImageInfo(width, height, kN32_SkColorType, at,
                       SkColorSpace::MakeSRGB());
}

bool SkColorTypeValidateAlphaType(SkColorType colorType, SkAlphaType alphaType,
                                  SkAlphaType* canonical) {
    switch (colorType) {
        case kUnknown_SkColorType:
            alphaType = kUnknown_SkAlphaType;
            break;
        case kAlpha_8_SkColorType:
            if (kUnpremul_SkAlphaType == alphaType) {
                alphaType = kPremul_SkAlphaType;
            }
            // fall-through
        case kARGB_4444_SkColorType:
        case kRGBA_8888_SkColorType:
        case kBGRA_8888_SkColorType:
        case kRGBA_1010102_SkColorType:
        case kRGBA_F16_SkColorType:
            if (kUnknown_SkAlphaType == alphaType) {
                return false;
            }
            break;
        case kGray_8_SkColorType:
        case kRGB_565_SkColorType:
        case kRGB_888x_SkColorType:
        case kRGB_101010x_SkColorType:
            alphaType = kOpaque_SkAlphaType;
            break;
        default:
            return false;
    }
    if (canonical) {
        *canonical = alphaType;
    }
    return true;
}

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

#include "SkReadPixelsRec.h"

bool SkReadPixelsRec::trim(int srcWidth, int srcHeight) {
    if (nullptr == fPixels || fRowBytes < fInfo.minRowBytes()) {
        return false;
    }
    if (0 >= fInfo.width() || 0 >= fInfo.height()) {
        return false;
    }

    int x = fX;
    int y = fY;
    SkIRect srcR = SkIRect::MakeXYWH(x, y, fInfo.width(), fInfo.height());
    if (!srcR.intersect(0, 0, srcWidth, srcHeight)) {
        return false;
    }

    // if x or y are negative, then we have to adjust pixels
    if (x > 0) {
        x = 0;
    }
    if (y > 0) {
        y = 0;
    }
    // here x,y are either 0 or negative
    // we negate and add them so UBSAN (pointer-overflow) doesn't get confused.
    fPixels = ((char*)fPixels + -y*fRowBytes + -x*fInfo.bytesPerPixel());
    // the intersect may have shrunk info's logical size
    fInfo = fInfo.makeWH(srcR.width(), srcR.height());
    fX = srcR.x();
    fY = srcR.y();

    return true;
}

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

#include "SkWritePixelsRec.h"

bool SkWritePixelsRec::trim(int dstWidth, int dstHeight) {
    if (nullptr == fPixels || fRowBytes < fInfo.minRowBytes()) {
        return false;
    }
    if (0 >= fInfo.width() || 0 >= fInfo.height()) {
        return false;
    }

    int x = fX;
    int y = fY;
    SkIRect dstR = SkIRect::MakeXYWH(x, y, fInfo.width(), fInfo.height());
    if (!dstR.intersect(0, 0, dstWidth, dstHeight)) {
        return false;
    }

    // if x or y are negative, then we have to adjust pixels
    if (x > 0) {
        x = 0;
    }
    if (y > 0) {
        y = 0;
    }
    // here x,y are either 0 or negative
    // we negate and add them so UBSAN (pointer-overflow) doesn't get confused.
    fPixels = ((const char*)fPixels + -y*fRowBytes + -x*fInfo.bytesPerPixel());
    // the intersect may have shrunk info's logical size
    fInfo = fInfo.makeWH(dstR.width(), dstR.height());
    fX = dstR.x();
    fY = dstR.y();

    return true;
}
<commit_msg>Fix SkImageInfo::computeByteSize underflow<commit_after>/*
 * Copyright 2010 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkImageInfoPriv.h"
#include "SkSafeMath.h"
#include "SkReadBuffer.h"
#include "SkWriteBuffer.h"

int SkColorTypeBytesPerPixel(SkColorType ct) {
    switch (ct) {
        case kUnknown_SkColorType:      return 0;
        case kAlpha_8_SkColorType:      return 1;
        case kRGB_565_SkColorType:      return 2;
        case kARGB_4444_SkColorType:    return 2;
        case kRGBA_8888_SkColorType:    return 4;
        case kBGRA_8888_SkColorType:    return 4;
        case kRGB_888x_SkColorType:     return 4;
        case kRGBA_1010102_SkColorType: return 4;
        case kRGB_101010x_SkColorType:  return 4;
        case kGray_8_SkColorType:       return 1;
        case kRGBA_F16_SkColorType:     return 8;
    }
    return 0;
}

// These values must be constant over revisions, though they can be renamed to reflect if/when
// they are deprecated.
enum Stored_SkColorType {
    kUnknown_Stored_SkColorType             = 0,
    kAlpha_8_Stored_SkColorType             = 1,
    kRGB_565_Stored_SkColorType             = 2,
    kARGB_4444_Stored_SkColorType           = 3,
    kRGBA_8888_Stored_SkColorType           = 4,
    kBGRA_8888_Stored_SkColorType           = 5,
    kIndex_8_Stored_SkColorType_DEPRECATED  = 6,
    kGray_8_Stored_SkColorType              = 7,
    kRGBA_F16_Stored_SkColorType            = 8,
    kRGB_888x_Stored_SkColorType            = 9,
    kRGBA_1010102_Stored_SkColorType        = 10,
    kRGB_101010x_Stored_SkColorType         = 11,
};

bool SkColorTypeIsAlwaysOpaque(SkColorType ct) {
    return !(kAlpha_SkColorTypeComponentFlag & SkColorTypeComponentFlags(ct));
}

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

int SkImageInfo::bytesPerPixel() const { return SkColorTypeBytesPerPixel(fColorType); }

int SkImageInfo::shiftPerPixel() const { return SkColorTypeShiftPerPixel(fColorType); }

size_t SkImageInfo::computeOffset(int x, int y, size_t rowBytes) const {
    SkASSERT((unsigned)x < (unsigned)fWidth);
    SkASSERT((unsigned)y < (unsigned)fHeight);
    return SkColorTypeComputeOffset(fColorType, x, y, rowBytes);
}

size_t SkImageInfo::computeByteSize(size_t rowBytes) const {
    if (0 == fHeight) {
        return 0;
    }
    SkSafeMath safe;
    size_t bytes = safe.add(safe.mul(safe.addInt(fHeight, -1), rowBytes),
                            safe.mul(fWidth, this->bytesPerPixel()));
    return safe ? bytes : SK_MaxSizeT;
}

SkImageInfo SkImageInfo::MakeS32(int width, int height, SkAlphaType at) {
    return SkImageInfo(width, height, kN32_SkColorType, at,
                       SkColorSpace::MakeSRGB());
}

bool SkColorTypeValidateAlphaType(SkColorType colorType, SkAlphaType alphaType,
                                  SkAlphaType* canonical) {
    switch (colorType) {
        case kUnknown_SkColorType:
            alphaType = kUnknown_SkAlphaType;
            break;
        case kAlpha_8_SkColorType:
            if (kUnpremul_SkAlphaType == alphaType) {
                alphaType = kPremul_SkAlphaType;
            }
            // fall-through
        case kARGB_4444_SkColorType:
        case kRGBA_8888_SkColorType:
        case kBGRA_8888_SkColorType:
        case kRGBA_1010102_SkColorType:
        case kRGBA_F16_SkColorType:
            if (kUnknown_SkAlphaType == alphaType) {
                return false;
            }
            break;
        case kGray_8_SkColorType:
        case kRGB_565_SkColorType:
        case kRGB_888x_SkColorType:
        case kRGB_101010x_SkColorType:
            alphaType = kOpaque_SkAlphaType;
            break;
        default:
            return false;
    }
    if (canonical) {
        *canonical = alphaType;
    }
    return true;
}

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

#include "SkReadPixelsRec.h"

bool SkReadPixelsRec::trim(int srcWidth, int srcHeight) {
    if (nullptr == fPixels || fRowBytes < fInfo.minRowBytes()) {
        return false;
    }
    if (0 >= fInfo.width() || 0 >= fInfo.height()) {
        return false;
    }

    int x = fX;
    int y = fY;
    SkIRect srcR = SkIRect::MakeXYWH(x, y, fInfo.width(), fInfo.height());
    if (!srcR.intersect(0, 0, srcWidth, srcHeight)) {
        return false;
    }

    // if x or y are negative, then we have to adjust pixels
    if (x > 0) {
        x = 0;
    }
    if (y > 0) {
        y = 0;
    }
    // here x,y are either 0 or negative
    // we negate and add them so UBSAN (pointer-overflow) doesn't get confused.
    fPixels = ((char*)fPixels + -y*fRowBytes + -x*fInfo.bytesPerPixel());
    // the intersect may have shrunk info's logical size
    fInfo = fInfo.makeWH(srcR.width(), srcR.height());
    fX = srcR.x();
    fY = srcR.y();

    return true;
}

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

#include "SkWritePixelsRec.h"

bool SkWritePixelsRec::trim(int dstWidth, int dstHeight) {
    if (nullptr == fPixels || fRowBytes < fInfo.minRowBytes()) {
        return false;
    }
    if (0 >= fInfo.width() || 0 >= fInfo.height()) {
        return false;
    }

    int x = fX;
    int y = fY;
    SkIRect dstR = SkIRect::MakeXYWH(x, y, fInfo.width(), fInfo.height());
    if (!dstR.intersect(0, 0, dstWidth, dstHeight)) {
        return false;
    }

    // if x or y are negative, then we have to adjust pixels
    if (x > 0) {
        x = 0;
    }
    if (y > 0) {
        y = 0;
    }
    // here x,y are either 0 or negative
    // we negate and add them so UBSAN (pointer-overflow) doesn't get confused.
    fPixels = ((const char*)fPixels + -y*fRowBytes + -x*fInfo.bytesPerPixel());
    // the intersect may have shrunk info's logical size
    fInfo = fInfo.makeWH(dstR.width(), dstR.height());
    fX = dstR.x();
    fY = dstR.y();

    return true;
}
<|endoftext|>


<commit_before>///////////////////////////////////////////////////////////////////////////////////
/// OpenGL Mathematics (glm.g-truc.net)
///
/// Copyright (c) 2005 - 2015 G-Truc Creation (www.g-truc.net)
/// Permission is hereby granted, free of charge, to any person obtaining a copy
/// of this software and associated documentation files (the "Software"), to deal
/// in the Software without restriction, including without limitation the rights
/// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
/// copies of the Software, and to permit persons to whom the Software is
/// furnished to do so, subject to the following conditions:
///
/// The above copyright notice and this permission notice shall be included in
/// all copies or substantial portions of the Software.
///
/// Restrictions:
///		By making use of the Software for military purposes, you choose to make
///		a Bunny unhappy.
///
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
/// THE SOFTWARE.
///
/// @ref gtx_matrix_decompose
/// @file glm/gtx/matrix_decompose.hpp
/// @date 2014-08-29 / 2014-08-29
/// @author Christophe Riccio
///
/// @see core (dependence)
///
/// @defgroup gtx_matrix_decompose GLM_GTX_matrix_decompose
/// @ingroup gtx
///
/// @brief Decomposes a model matrix to translations, rotation and scale components
///
/// <glm/gtx/decomposition.hpp> need to be included to use these functionalities.
///////////////////////////////////////////////////////////////////////////////////

#pragma once

// Dependencies
#include "../mat4x4.hpp"
#include "../vec3.hpp"
#include "../vec4.hpp"
#include "../gtc/quaternion.hpp"
#include "../gtc/matrix_transform.hpp"

#if(defined(GLM_MESSAGES) && !defined(GLM_EXT_INCLUDED))
#	pragma message("GLM: GLM_GTX_matrix_decompose extension included")
#endif

namespace glm
{
	/// @addtogroup gtx_matrix_decompose
	/// @{

	/// Decomposes a model matrix to translations, rotation and scale components
	/// @see gtx_matrix_decompose
	template <typename T, precision P>
	GLM_FUNC_DECL bool decompose(
		tmat4x4<T, P> const & modelMatrix,
		tvec3<T, P> & scale, tquat<T, P> & orientation, tvec3<T, P> & translation, tvec3<T, P> & skew, tvec4<T, P> & perspective);

	/// @}
}//namespace glm

#include "matrix_decompose.inl"
<commit_msg>Update matrix_decompose.hpp<commit_after>///////////////////////////////////////////////////////////////////////////////////
/// OpenGL Mathematics (glm.g-truc.net)
///
/// Copyright (c) 2005 - 2015 G-Truc Creation (www.g-truc.net)
/// Permission is hereby granted, free of charge, to any person obtaining a copy
/// of this software and associated documentation files (the "Software"), to deal
/// in the Software without restriction, including without limitation the rights
/// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
/// copies of the Software, and to permit persons to whom the Software is
/// furnished to do so, subject to the following conditions:
///
/// The above copyright notice and this permission notice shall be included in
/// all copies or substantial portions of the Software.
///
/// Restrictions:
///		By making use of the Software for military purposes, you choose to make
///		a Bunny unhappy.
///
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
/// THE SOFTWARE.
///
/// @ref gtx_matrix_decompose
/// @file glm/gtx/matrix_decompose.hpp
/// @date 2014-08-29 / 2014-08-29
/// @author Christophe Riccio
///
/// @see core (dependence)
///
/// @defgroup gtx_matrix_decompose GLM_GTX_matrix_decompose
/// @ingroup gtx
///
/// @brief Decomposes a model matrix to translations, rotation and scale components
///
/// <glm/gtx/matrix_decompose.hpp> need to be included to use these functionalities.
///////////////////////////////////////////////////////////////////////////////////

#pragma once

// Dependencies
#include "../mat4x4.hpp"
#include "../vec3.hpp"
#include "../vec4.hpp"
#include "../gtc/quaternion.hpp"
#include "../gtc/matrix_transform.hpp"

#if(defined(GLM_MESSAGES) && !defined(GLM_EXT_INCLUDED))
#	pragma message("GLM: GLM_GTX_matrix_decompose extension included")
#endif

namespace glm
{
	/// @addtogroup gtx_matrix_decompose
	/// @{

	/// Decomposes a model matrix to translations, rotation and scale components
	/// @see gtx_matrix_decompose
	template <typename T, precision P>
	GLM_FUNC_DECL bool decompose(
		tmat4x4<T, P> const & modelMatrix,
		tvec3<T, P> & scale, tquat<T, P> & orientation, tvec3<T, P> & translation, tvec3<T, P> & skew, tvec4<T, P> & perspective);

	/// @}
}//namespace glm

#include "matrix_decompose.inl"
<|endoftext|>


<commit_before>#include "nfa.hxx"
#include <iostream>

const char* state_not_found::what () const throw ()
{
    return "state not found in delta mapping";
}

std::string printNFA (const NFA& nfa)
{
    std::ostringstream ss;

    ss << "automaton " << nfa.name << std::endl;
    for (DeltaMappingT::const_iterator dmi = nfa.delta.begin();
	 dmi != nfa.delta.end();
	 ++dmi) {
	const StateT& st = dmi->first;
	if (st == nfa.initial)
	    ss << "initial ";
	if (nfa.final.find(st) != nfa.final.end())
	    ss << "final ";
	ss << "state " << st << " {" << std::endl;
	for (StateDeltaT::const_iterator sdi = dmi->second.begin();
	     sdi != dmi->second.end();
	     ++sdi) {
	    ss << sdi->first << " -> { ";
	    std::copy(sdi->second.begin(), sdi->second.end(),
		      std::ostream_iterator<StateT >(ss," "));
	    ss << "}" << std::endl;
	}
	ss << "}" << std::endl;
    }

    return ss.str();
}

std::string printNFA (const NFA_conv& nfa)
{
    std::ostringstream ss;

    ss << "automaton " << nfa.name << std::endl;
    for (std::map<SetOfStatesT, StateDeltaT >::const_iterator dmi
	     = nfa.delta.begin();
	 dmi != nfa.delta.end();
	 ++dmi) {
	const SetOfStatesT& st = dmi->first;
	if (st == nfa.initial)
	    ss << "initial ";
	if (nfa.final.find(st) != nfa.final.end())
	    ss << "final ";
	ss << "state " << join_seq(std::string("-"),st) << " {" << std::endl;
	for (StateDeltaT::const_iterator sdi = dmi->second.begin();
	     sdi != dmi->second.end();
	     ++sdi) {
	    ss << sdi->first << " -> { ";
	    std::copy(sdi->second.begin(), sdi->second.end(),
		      std::ostream_iterator<StateT >(ss," "));
	    ss << "}" << std::endl;
	}
	ss << "}" << std::endl;
    }

    return ss.str();
}

/* Get set of input alphabet T from automaton's delta mapping. */
std::set<LetterT > input_alphabet (const NFA& nfa)
{
    std::set<LetterT> alphabet;
    for (DeltaMappingT::const_iterator i = nfa.delta.begin();
	 i != nfa.delta.end();
	 ++i) {
	for (StateDeltaT::const_iterator k = i->second.begin();
	     k != i->second.end();
	     ++k) {
	    alphabet.insert(k->first);
	}
    }
    return alphabet;
}

NFA_conv convert_NFA2DFA (const NFA& nfa)
{
    NFA_conv nfa_conv;
    /* 1. The set Q' = {{q0}} will be defined, the state {q0} will be treated
       as unmarked. */
    std::set<LetterT > alphabet = input_alphabet(nfa);
    std::set<SetOfStatesT > Qnew, unmarked, marked;
    SetOfStatesT q0set;
    q0set.insert(nfa.initial);
    Qnew.insert(q0set);
    unmarked.insert(q0set);

    /* 2. If each state in Q' is marked, then continue with step (4). */
    while (! unmarked.empty()) {
	/* 3. An unmarked state q' will be chosen from Q' and th following
	   operations will be executed: */
	SetOfStatesT q_ = *unmarked.begin();
	/* (a) We will determine delta'(q',a) = union(delta(p,a)) for
	   p element q' and for all a element T. */
	StateDeltaT stdelta;
	int cnt = 0;
	for (std::set<LetterT >::const_iterator letter = alphabet.begin();
	     letter != alphabet.end();
	     ++letter) {
	    /* alokace promenne pro sjednoceni union(delta(p,a))
	       for p element q' */
	    SetOfStatesT* un = new SetOfStatesT;
	    int cnt2 = 0;
	    for (SetOfStatesT::const_iterator p = q_.begin();
		 p != q_.end();
		 ++p) {
		// najdi StateDeltaT pro stav
		DeltaMappingT::const_iterator dmi = nfa.delta.find(*p);
		// element nenalezen
		if (dmi == nfa.delta.end())
		    throw state_not_found();
		const StateDeltaT& sd = dmi->second;
		/* Najdi mnozinu cilovych stavu ze stavu *p pri
		   vstupnim pismenu *letter. */
		StateDeltaT::const_iterator sdi = sd.find(*letter);
		/* Element nenalezen, tzn. z tohodle stavu pri
		   vstupu *letter nevede zadna cesta. */
		if (sdi == sd.end())
		    continue;
		un->insert(sdi->second.begin(), sdi->second.end());
	    }
	    stdelta.insert(make_pair(*letter,*un));
	    /* (b) Q' = Q' union delta'(q',a) for all a element T. */
	    Qnew.insert(*un);
	    /* pokud stav jeste neni oznaceny */
	    if (marked.find(*un) == marked.end())
		/* pridame ho k neoznacenym */
		unmarked.insert(*un);

	}
	/* (c) The state q' element Q' will be marked. */
	unmarked.erase(q_);
	marked.insert(q_);
	/* (d) Continue with step (2). */
	nfa_conv.delta.insert(make_pair(q_,stdelta));
    }

    nfa_conv.name = nfa.name;
    /* 4. q0' = {q0}. */
    nfa_conv.initial = q0set;
    /* 5. F' = {q' : q' element Q', q' intersection F != 0}. */
    for (std::set<SetOfStatesT >::const_iterator q_ = Qnew.begin();
	 q_ != Qnew.end();
	 ++q_) {
	// promenna pro prunik
	SetOfStatesT inter;
	set_intersection(q_->begin(), q_->end(),
			 nfa.final.begin(), nfa.final.end(),
			 std::insert_iterator<SetOfStatesT >(inter,
							     inter.begin()));
	if (! inter.empty())
	    nfa_conv.final.insert(*q_);
    }

    return nfa_conv;
}

NFA fix_converted (const NFA_conv& nfa_conv, bool )
{

}
<commit_msg>convert_NFA2DFA(): Osetreni nepritomnosti prechodu pro dane vstupni convert_NFA2DFA(): Osetreni nepritomnosti prechodu pro dane vstupni pismeno,<commit_after>#include "nfa.hxx"
#include <iostream>

const char* state_not_found::what () const throw ()
{
    return "state not found in delta mapping";
}

std::string printNFA (const NFA& nfa)
{
    std::ostringstream ss;

    ss << "automaton " << nfa.name << std::endl;
    for (DeltaMappingT::const_iterator dmi = nfa.delta.begin();
	 dmi != nfa.delta.end();
	 ++dmi) {
	const StateT& st = dmi->first;
	if (st == nfa.initial)
	    ss << "initial ";
	if (nfa.final.find(st) != nfa.final.end())
	    ss << "final ";
	ss << "state " << st << " {" << std::endl;
	for (StateDeltaT::const_iterator sdi = dmi->second.begin();
	     sdi != dmi->second.end();
	     ++sdi) {
	    ss << sdi->first << " -> { ";
	    std::copy(sdi->second.begin(), sdi->second.end(),
		      std::ostream_iterator<StateT >(ss," "));
	    ss << "}" << std::endl;
	}
	ss << "}" << std::endl;
    }

    return ss.str();
}

std::string printNFA (const NFA_conv& nfa)
{
    std::ostringstream ss;

    ss << "automaton " << nfa.name << std::endl;
    for (std::map<SetOfStatesT, StateDeltaT >::const_iterator dmi
	     = nfa.delta.begin();
	 dmi != nfa.delta.end();
	 ++dmi) {
	const SetOfStatesT& st = dmi->first;
	if (st == nfa.initial)
	    ss << "initial ";
	if (nfa.final.find(st) != nfa.final.end())
	    ss << "final ";
	ss << "state " << join_seq(std::string("-"),st) << " {" << std::endl;
	for (StateDeltaT::const_iterator sdi = dmi->second.begin();
	     sdi != dmi->second.end();
	     ++sdi) {
	    ss << sdi->first << " -> { ";
	    std::copy(sdi->second.begin(), sdi->second.end(),
		      std::ostream_iterator<StateT >(ss," "));
	    ss << "}" << std::endl;
	}
	ss << "}" << std::endl;
    }

    return ss.str();
}

/* Get set of input alphabet T from automaton's delta mapping. */
std::set<LetterT > input_alphabet (const NFA& nfa)
{
    std::set<LetterT> alphabet;
    for (DeltaMappingT::const_iterator i = nfa.delta.begin();
	 i != nfa.delta.end();
	 ++i) {
	for (StateDeltaT::const_iterator k = i->second.begin();
	     k != i->second.end();
	     ++k) {
	    alphabet.insert(k->first);
	}
    }
    return alphabet;
}

NFA_conv convert_NFA2DFA (const NFA& nfa)
{
    NFA_conv nfa_conv;
    /* 1. The set Q' = {{q0}} will be defined, the state {q0} will be treated
       as unmarked. */
    std::set<LetterT > alphabet = input_alphabet(nfa);
    std::set<SetOfStatesT > Qnew, unmarked, marked;
    SetOfStatesT q0set;
    q0set.insert(nfa.initial);
    Qnew.insert(q0set);
    unmarked.insert(q0set);

    /* 2. If each state in Q' is marked, then continue with step (4). */
    while (! unmarked.empty()) {
	/* 3. An unmarked state q' will be chosen from Q' and th following
	   operations will be executed: */
	SetOfStatesT q_ = *unmarked.begin();
	/* (a) We will determine delta'(q',a) = union(delta(p,a)) for
	   p element q' and for all a element T. */
	StateDeltaT stdelta;
	int cnt = 0;
	for (std::set<LetterT >::const_iterator letter = alphabet.begin();
	     letter != alphabet.end();
	     ++letter) {
	    /* alokace promenne pro sjednoceni union(delta(p,a))
	       for p element q' */
	    SetOfStatesT* un = new SetOfStatesT;
	    int cnt2 = 0;
	    for (SetOfStatesT::const_iterator p = q_.begin();
		 p != q_.end();
		 ++p) {
		// najdi StateDeltaT pro stav
		DeltaMappingT::const_iterator dmi = nfa.delta.find(*p);
		// element nenalezen
		if (dmi == nfa.delta.end())
		    throw state_not_found();
		const StateDeltaT& sd = dmi->second;
		/* Najdi mnozinu cilovych stavu ze stavu *p pri
		   vstupnim pismenu *letter. */
		StateDeltaT::const_iterator sdi = sd.find(*letter);
		/* Element nenalezen, tzn. z tohodle stavu pri
		   vstupu *letter nevede zadna cesta. */
		if (sdi == sd.end())
		    continue;
		un->insert(sdi->second.begin(), sdi->second.end());
	    }
	    if (un->empty())
		continue;
	    stdelta.insert(make_pair(*letter,*un));
	    /* (b) Q' = Q' union delta'(q',a) for all a element T. */
	    Qnew.insert(*un);
	    /* pokud stav jeste neni oznaceny */
	    if (marked.find(*un) == marked.end())
		/* pridame ho k neoznacenym */
		unmarked.insert(*un);

	}
	/* (c) The state q' element Q' will be marked. */
	unmarked.erase(q_);
	marked.insert(q_);
	/* (d) Continue with step (2). */
	nfa_conv.delta.insert(make_pair(q_,stdelta));
    }

    nfa_conv.name = nfa.name;
    /* 4. q0' = {q0}. */
    nfa_conv.initial = q0set;
    /* 5. F' = {q' : q' element Q', q' intersection F != 0}. */
    for (std::set<SetOfStatesT >::const_iterator q_ = Qnew.begin();
	 q_ != Qnew.end();
	 ++q_) {
	// promenna pro prunik
	SetOfStatesT inter;
	set_intersection(q_->begin(), q_->end(),
			 nfa.final.begin(), nfa.final.end(),
			 std::insert_iterator<SetOfStatesT >(inter,
							     inter.begin()));
	if (! inter.empty())
	    nfa_conv.final.insert(*q_);
    }

    return nfa_conv;
}

NFA fix_converted (const NFA_conv& nfa_conv, bool )
{

}
<|endoftext|>


<commit_before>// Copyright 2006, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//

#include <stdio.h>
#include "gtest/gtest.h"

GTEST_API_ int main(int argc, char **argv) {
  printf("Running main() from gtest_main.cc\n");
  testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}
<commit_msg>small tweaks, OSS merge cl 206357486<commit_after>// Copyright 2006, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//

#include <stdio.h>
#include "gtest/gtest.h"

GTEST_API_ int main(int argc, char **argv) {
  printf("Running main() from %s\n", __FILE__);
  testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}
<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2006 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/
//$Id: datasource_cache.cpp 23 2005-03-22 22:16:34Z pavlenko $

// stl
#include <algorithm>
#include <stdexcept>
// boost
#include <boost/thread/mutex.hpp>
#include <boost/filesystem/operations.hpp>
// mapnik
#include <mapnik/datasource_cache.hpp>
// ltdl
#include <ltdl.h>

namespace mapnik
{
    using namespace std;
    using namespace boost;

    datasource_cache::datasource_cache()
    {
        if (lt_dlinit()) throw;
    }

    datasource_cache::~datasource_cache()
    {
        lt_dlexit();
    }

    std::map<string,boost::shared_ptr<PluginInfo> > datasource_cache::plugins_;
    bool datasource_cache::registered_=false;

    datasource_ptr datasource_cache::create(const parameters& params)
    {
        datasource_ptr ds;
        try
        {
           boost::optional<std::string> type = params.get<std::string>("type");
           if (type)
           {
              map<string,boost::shared_ptr<PluginInfo> >::iterator itr=plugins_.find(*type);
              if (itr!=plugins_.end())
              {
                 if (itr->second->handle())
                 {
                    create_ds* create_datasource =
                       (create_ds*) lt_dlsym(itr->second->handle(), "create");
                    if (!create_datasource)
                    {
                       std::clog << "Cannot load symbols: " << lt_dlerror() << std::endl;
                    }
                    else
                    {
                        ds=datasource_ptr(create_datasource(params), datasource_deleter());
                    }
                }
                else
                {
                    std::clog << "Cannot load library: " << lt_dlerror() << std::endl;
                }
              }
           }
#ifdef MAPNIK_DEBUG
            std::clog<<"datasource="<<ds<<" type="<<type<<std::endl;
#endif
        }
        catch (datasource_exception& ex)
        {
            std::clog << ex.what() << "\n";
        }
        catch (...)
        {
            std::clog << " exception caught\n";
        }
        return ds;
    }

    bool datasource_cache::insert(const std::string& type,const lt_dlhandle module)
    {
        return plugins_.insert(make_pair(type,boost::shared_ptr<PluginInfo>
                                         (new PluginInfo(type,module)))).second;
    }

    void datasource_cache::register_datasources(const std::string& str)
    {
        mutex::scoped_lock lock(mapnik::singleton<mapnik::datasource_cache,
                                mapnik::CreateStatic>::mutex_);
        filesystem::path path(str);
        filesystem::directory_iterator end_itr;
        if (exists(path) && is_directory(path))
        {
            for (filesystem::directory_iterator itr(path);itr!=end_itr;++itr )
            {
                if (!is_directory( *itr ) && itr->leaf()[0]!='.')
                {
                   try
                   {
                      lt_dlhandle module=lt_dlopen(itr->string().c_str());
                      if (module)
                      {
                         datasource_name* ds_name =
                            (datasource_name*) lt_dlsym(module, "datasource_name");
                         if (ds_name && insert(ds_name(),module))
                         {
#ifdef MAPNIK_DEBUG
                            std::clog<<"registered datasource : "<<ds_name()<<std::endl;
#endif
                            registered_=true;
                         }
                      }
                      else
                      {
                         std::clog << lt_dlerror() << "\n";
                      }
                   }
                   catch (...) {}
                }
            }
        }
    }
}
<commit_msg>check if file ends with '.input' before attempting to load it<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2006 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/
//$Id: datasource_cache.cpp 23 2005-03-22 22:16:34Z pavlenko $

// stl
#include <algorithm>
#include <stdexcept>
// boost
#include <boost/thread/mutex.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/algorithm/string.hpp>
// mapnik
#include <mapnik/datasource_cache.hpp>
// ltdl
#include <ltdl.h>

namespace mapnik
{
   using namespace std;
   using namespace boost;

   bool is_input_plugin (std::string const& filename)
   {
      return boost::algorithm::ends_with(filename,".input");
   }

   datasource_cache::datasource_cache()
   {
      if (lt_dlinit()) throw;
   }

   datasource_cache::~datasource_cache()
   {
      lt_dlexit();
   }

   std::map<string,boost::shared_ptr<PluginInfo> > datasource_cache::plugins_;
   bool datasource_cache::registered_=false;

   datasource_ptr datasource_cache::create(const parameters& params)
   {
      datasource_ptr ds;
      try
      {
         boost::optional<std::string> type = params.get<std::string>("type");
         if (type)
         {
            map<string,boost::shared_ptr<PluginInfo> >::iterator itr=plugins_.find(*type);
            if (itr!=plugins_.end())
            {
               if (itr->second->handle())
               {
                  create_ds* create_datasource =
                     (create_ds*) lt_dlsym(itr->second->handle(), "create");
                  if (!create_datasource)
                  {
                     std::clog << "Cannot load symbols: " << lt_dlerror() << std::endl;
                  }
                  else
                  {
                     ds=datasource_ptr(create_datasource(params), datasource_deleter());
                  }
               }
               else
               {
                  std::clog << "Cannot load library: " << lt_dlerror() << std::endl;
               }
            }
         }
#ifdef MAPNIK_DEBUG
         std::clog<<"datasource="<<ds<<" type="<<type<<std::endl;
#endif
      }
      catch (datasource_exception& ex)
      {
         std::clog << ex.what() << "\n";
      }
      catch (...)
      {
         std::clog << " exception caught\n";
      }
      return ds;
   }

   bool datasource_cache::insert(const std::string& type,const lt_dlhandle module)
   {
      return plugins_.insert(make_pair(type,boost::shared_ptr<PluginInfo>
                                       (new PluginInfo(type,module)))).second;
   }

   void datasource_cache::register_datasources(const std::string& str)
   {
      mutex::scoped_lock lock(mapnik::singleton<mapnik::datasource_cache,
                              mapnik::CreateStatic>::mutex_);
      filesystem::path path(str);
      filesystem::directory_iterator end_itr;
      if (exists(path) && is_directory(path))
      {
         for (filesystem::directory_iterator itr(path);itr!=end_itr;++itr )
         {
            if (!is_directory( *itr ) && is_input_plugin(itr->leaf()))
            {
               try
               {
                  lt_dlhandle module=lt_dlopen(itr->string().c_str());
                  if (module)
                  {
                     datasource_name* ds_name =
                        (datasource_name*) lt_dlsym(module, "datasource_name");
                     if (ds_name && insert(ds_name(),module))
                     {
#ifdef MAPNIK_DEBUG
                        std::clog<<"registered datasource : "<<ds_name()<<std::endl;
#endif
                        registered_=true;
                     }
                  }
                  else
                  {
                     std::clog << lt_dlerror() << "\n";
                  }
               }
               catch (...) {}
            }
         }
      }
   }
}
<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2011 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/
//$Id: datasource_cache.cpp 23 2005-03-22 22:16:34Z pavlenko $

// mapnik
#include <mapnik/datasource_cache.hpp>

#include <mapnik/config_error.hpp>

// boost
#include <boost/version.hpp>
#include <boost/make_shared.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/algorithm/string.hpp>

// ltdl
#include <ltdl.h>

// stl
#include <algorithm>
#include <iostream>
#include <stdexcept>

namespace mapnik
{

bool is_input_plugin (std::string const& filename)
{
    return boost::algorithm::ends_with(filename,std::string(".input"));
}

datasource_cache::datasource_cache()
{
    if (lt_dlinit()) throw std::runtime_error("lt_dlinit() failed");
}

datasource_cache::~datasource_cache()
{
    lt_dlexit();
}

std::map<std::string,boost::shared_ptr<PluginInfo> > datasource_cache::plugins_;
bool datasource_cache::registered_=false;
std::vector<std::string> datasource_cache::plugin_directories_;

datasource_ptr datasource_cache::create(const parameters& params, bool bind)
{
    boost::optional<std::string> type = params.get<std::string>("type");
    if ( ! type)
    {
        throw config_error(std::string("Could not create datasource. Required ") +
                           "parameter 'type' is missing");
    }

#ifdef MAPNIK_THREADSAFE
    mutex::scoped_lock lock(mutex_);
#endif
    datasource_ptr ds;
    std::map<std::string,boost::shared_ptr<PluginInfo> >::iterator itr=plugins_.find(*type);
    if ( itr == plugins_.end() )
    {
        throw config_error(std::string("Could not create datasource. No plugin ") +
                           "found for type '" + * type + "' (searched in: " + plugin_directories() + ")");
    }
    if ( ! itr->second->handle())
    {
        throw std::runtime_error(std::string("Cannot load library: ") +
                                 lt_dlerror());
    }
    // http://www.mr-edd.co.uk/blog/supressing_gcc_warnings
    #ifdef __GNUC__
    __extension__
    #endif
    create_ds* create_datasource =
        reinterpret_cast<create_ds*>(lt_dlsym(itr->second->handle(), "create"));

    if ( ! create_datasource)
    {
        throw std::runtime_error(std::string("Cannot load symbols: ") +
                                 lt_dlerror());
    }
#ifdef MAPNIK_DEBUG
    std::clog << "size = " << params.size() << "\n";
    parameters::const_iterator i = params.begin();
    for (;i!=params.end();++i)
    {
        std::clog << i->first << "=" << i->second << "\n";
    }
#endif
    ds=datasource_ptr(create_datasource(params, bind), datasource_deleter());

#ifdef MAPNIK_DEBUG
    std::clog<<"datasource="<<ds<<" type="<<type<<std::endl;
#endif
    return ds;
}

bool datasource_cache::insert(const std::string& type,const lt_dlhandle module)
{
    return plugins_.insert(make_pair(type,boost::make_shared<PluginInfo>
                                     (type,module))).second;
}

std::string datasource_cache::plugin_directories()
{
    return boost::algorithm::join(plugin_directories_,", ");
}

std::vector<std::string> datasource_cache::plugin_names ()
{
    std::vector<std::string> names;
    std::map<std::string,boost::shared_ptr<PluginInfo> >::const_iterator itr;
    for (itr = plugins_.begin();itr!=plugins_.end();++itr)
    {
        names.push_back(itr->first);
    }
    return names;
}

void datasource_cache::register_datasources(const std::string& str)
{
#ifdef MAPNIK_THREADSAFE
    mutex::scoped_lock lock(mapnik::singleton<mapnik::datasource_cache,
                            mapnik::CreateStatic>::mutex_);
#endif
    boost::filesystem::path path(str);
    plugin_directories_.push_back(str);
    boost::filesystem::directory_iterator end_itr;

    if (exists(path) && is_directory(path))
    {
        for (boost::filesystem::directory_iterator itr(path);itr!=end_itr;++itr )
        {

#if BOOST_VERSION < 103400
            if (!is_directory( *itr )  && is_input_plugin(itr->leaf()))
#else
#if (BOOST_FILESYSTEM_VERSION == 3)
            if (!is_directory( *itr )  && is_input_plugin(itr->path().filename().string()))
#else // v2
            if (!is_directory( *itr )  && is_input_plugin(itr->path().leaf()))
#endif
#endif
            {
                try
                {
#ifdef LIBTOOL_SUPPORTS_ADVISE
                    /* Note: the below was added as a workaround pre http://trac.mapnik.org/ticket/790
                       It could now be removed, but also is not doing any harm AFAICT.
                    */

                    // with ltdl >=2.2 we can actually pass RTDL_GLOBAL to dlopen via the
                    // ltdl advise trick which is required on linux unless plugins are directly
                    // linked to libmapnik (and deps) at build time. The only other approach is to
                    // set the dlopen flags in the calling process (like in the python bindings)

                    // clear errors
                    lt_dlerror();

                    lt_dlhandle module = 0;
                    lt_dladvise advise;
                    int ret;

                    ret = lt_dlinit();
                    if (ret != 0) {
                        std::clog << "Datasource loader: could not intialize dynamic loading: " << lt_dlerror() << "\n";
                    }

                    ret = lt_dladvise_init(&advise);
                    if (ret != 0) {
                        std::clog << "Datasource loader: could not intialize dynamic loading: " << lt_dlerror() << "\n";
                    }

                    ret = lt_dladvise_global(&advise);
                    if (ret != 0) {
                        std::clog << "Datasource loader: could not intialize dynamic loading of global symbols: " << lt_dlerror() << "\n";
                    }
#if (BOOST_FILESYSTEM_VERSION == 3)
                    module = lt_dlopenadvise (itr->path().string().c_str(), advise);
#else // v2
                    module = lt_dlopenadvise (itr->string().c_str(), advise);
#endif

                    lt_dladvise_destroy(&advise);
#else

#if (BOOST_FILESYSTEM_VERSION == 3)
                    lt_dlhandle module = lt_dlopen(itr->path().string().c_str());
#else // v2
                    lt_dlhandle module = lt_dlopen(itr->string().c_str());
#endif

#endif
                    if (module)
                    {
                        // http://www.mr-edd.co.uk/blog/supressing_gcc_warnings
                        #ifdef __GNUC__
                        __extension__
                        #endif
                        datasource_name* ds_name =
                            reinterpret_cast<datasource_name*>(lt_dlsym(module, "datasource_name"));
                        if (ds_name && insert(ds_name(),module))
                        {
#ifdef MAPNIK_DEBUG
                            std::clog << "Datasource loader: registered: " << ds_name() << std::endl;
#endif
                            registered_=true;
                        }
                    }
                    else
                    {
#if (BOOST_FILESYSTEM_VERSION == 3)
                        std::clog << "Problem loading plugin library: " << itr->path().string()
                                  << " (dlopen failed - plugin likely has an unsatisfied dependency or incompatible ABI)" << std::endl;
#else // v2
                        std::clog << "Problem loading plugin library: " << itr->string()
                                  << " (dlopen failed - plugin likely has an unsatisfied dependency or incompatible ABI)" << std::endl;
#endif
                    }
                }
                catch (...) {}
            }
        }
    }
}

}
<commit_msg>print warning if the plugin cannot be loaded as it is lacking an interface<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2011 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/
//$Id: datasource_cache.cpp 23 2005-03-22 22:16:34Z pavlenko $

// mapnik
#include <mapnik/datasource_cache.hpp>

#include <mapnik/config_error.hpp>

// boost
#include <boost/version.hpp>
#include <boost/make_shared.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/algorithm/string.hpp>

// ltdl
#include <ltdl.h>

// stl
#include <algorithm>
#include <iostream>
#include <stdexcept>

namespace mapnik
{

bool is_input_plugin (std::string const& filename)
{
    return boost::algorithm::ends_with(filename,std::string(".input"));
}

datasource_cache::datasource_cache()
{
    if (lt_dlinit()) throw std::runtime_error("lt_dlinit() failed");
}

datasource_cache::~datasource_cache()
{
    lt_dlexit();
}

std::map<std::string,boost::shared_ptr<PluginInfo> > datasource_cache::plugins_;
bool datasource_cache::registered_=false;
std::vector<std::string> datasource_cache::plugin_directories_;

datasource_ptr datasource_cache::create(const parameters& params, bool bind)
{
    boost::optional<std::string> type = params.get<std::string>("type");
    if ( ! type)
    {
        throw config_error(std::string("Could not create datasource. Required ") +
                           "parameter 'type' is missing");
    }

#ifdef MAPNIK_THREADSAFE
    mutex::scoped_lock lock(mutex_);
#endif
    datasource_ptr ds;
    std::map<std::string,boost::shared_ptr<PluginInfo> >::iterator itr=plugins_.find(*type);
    if ( itr == plugins_.end() )
    {
        throw config_error(std::string("Could not create datasource. No plugin ") +
                           "found for type '" + * type + "' (searched in: " + plugin_directories() + ")");
    }
    if ( ! itr->second->handle())
    {
        throw std::runtime_error(std::string("Cannot load library: ") +
                                 lt_dlerror());
    }
    // http://www.mr-edd.co.uk/blog/supressing_gcc_warnings
    #ifdef __GNUC__
    __extension__
    #endif
    create_ds* create_datasource =
        reinterpret_cast<create_ds*>(lt_dlsym(itr->second->handle(), "create"));

    if ( ! create_datasource)
    {
        throw std::runtime_error(std::string("Cannot load symbols: ") +
                                 lt_dlerror());
    }
#ifdef MAPNIK_DEBUG
    std::clog << "size = " << params.size() << "\n";
    parameters::const_iterator i = params.begin();
    for (;i!=params.end();++i)
    {
        std::clog << i->first << "=" << i->second << "\n";
    }
#endif
    ds=datasource_ptr(create_datasource(params, bind), datasource_deleter());

#ifdef MAPNIK_DEBUG
    std::clog<<"datasource="<<ds<<" type="<<type<<std::endl;
#endif
    return ds;
}

bool datasource_cache::insert(const std::string& type,const lt_dlhandle module)
{
    return plugins_.insert(make_pair(type,boost::make_shared<PluginInfo>
                                     (type,module))).second;
}

std::string datasource_cache::plugin_directories()
{
    return boost::algorithm::join(plugin_directories_,", ");
}

std::vector<std::string> datasource_cache::plugin_names ()
{
    std::vector<std::string> names;
    std::map<std::string,boost::shared_ptr<PluginInfo> >::const_iterator itr;
    for (itr = plugins_.begin();itr!=plugins_.end();++itr)
    {
        names.push_back(itr->first);
    }
    return names;
}

void datasource_cache::register_datasources(const std::string& str)
{
#ifdef MAPNIK_THREADSAFE
    mutex::scoped_lock lock(mapnik::singleton<mapnik::datasource_cache,
                            mapnik::CreateStatic>::mutex_);
#endif
    boost::filesystem::path path(str);
    plugin_directories_.push_back(str);
    boost::filesystem::directory_iterator end_itr;

    if (exists(path) && is_directory(path))
    {
        for (boost::filesystem::directory_iterator itr(path);itr!=end_itr;++itr )
        {

#if BOOST_VERSION < 103400
            if (!is_directory( *itr )  && is_input_plugin(itr->leaf()))
#else
#if (BOOST_FILESYSTEM_VERSION == 3)
            if (!is_directory( *itr )  && is_input_plugin(itr->path().filename().string()))
#else // v2
            if (!is_directory( *itr )  && is_input_plugin(itr->path().leaf()))
#endif
#endif
            {
                try
                {
#ifdef LIBTOOL_SUPPORTS_ADVISE
                    /* Note: the below was added as a workaround pre http://trac.mapnik.org/ticket/790
                       It could now be removed, but also is not doing any harm AFAICT.
                    */

                    // with ltdl >=2.2 we can actually pass RTDL_GLOBAL to dlopen via the
                    // ltdl advise trick which is required on linux unless plugins are directly
                    // linked to libmapnik (and deps) at build time. The only other approach is to
                    // set the dlopen flags in the calling process (like in the python bindings)

                    // clear errors
                    lt_dlerror();

                    lt_dlhandle module = 0;
                    lt_dladvise advise;
                    int ret;

                    ret = lt_dlinit();
                    if (ret != 0) {
                        std::clog << "Datasource loader: could not intialize dynamic loading: " << lt_dlerror() << "\n";
                    }

                    ret = lt_dladvise_init(&advise);
                    if (ret != 0) {
                        std::clog << "Datasource loader: could not intialize dynamic loading: " << lt_dlerror() << "\n";
                    }

                    ret = lt_dladvise_global(&advise);
                    if (ret != 0) {
                        std::clog << "Datasource loader: could not intialize dynamic loading of global symbols: " << lt_dlerror() << "\n";
                    }
#if (BOOST_FILESYSTEM_VERSION == 3)
                    module = lt_dlopenadvise (itr->path().string().c_str(), advise);
#else // v2
                    module = lt_dlopenadvise (itr->string().c_str(), advise);
#endif

                    lt_dladvise_destroy(&advise);
#else

#if (BOOST_FILESYSTEM_VERSION == 3)
                    lt_dlhandle module = lt_dlopen(itr->path().string().c_str());
#else // v2
                    lt_dlhandle module = lt_dlopen(itr->string().c_str());
#endif

#endif
                    if (module)
                    {
                        // http://www.mr-edd.co.uk/blog/supressing_gcc_warnings
                        #ifdef __GNUC__
                        __extension__
                        #endif
                        datasource_name* ds_name =
                            reinterpret_cast<datasource_name*>(lt_dlsym(module, "datasource_name"));
                        if (ds_name && insert(ds_name(),module))
                        {
#ifdef MAPNIK_DEBUG
                            std::clog << "Datasource loader: registered: " << ds_name() << std::endl;
#endif
                            registered_=true;
                        }
                        else
                        {
                            std::clog << "Problem loading plugin library '" << itr->path().string() << "' (plugin is lacking compatible interface" << std::endl;
                        }
                    }
                    else
                    {
#if (BOOST_FILESYSTEM_VERSION == 3)
                        std::clog << "Problem loading plugin library: " << itr->path().string()
                                  << " (dlopen failed - plugin likely has an unsatisfied dependency or incompatible ABI)" << std::endl;
#else // v2
                        std::clog << "Problem loading plugin library: " << itr->string()
                                  << " (dlopen failed - plugin likely has an unsatisfied dependency or incompatible ABI)" << std::endl;
#endif
                    }
                }
                catch (...) {}
            }
        }
    }
}

}
<|endoftext|>


<commit_before>// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2019 The Bitcoin Core developers
// Copyright (c) 2014-2019 The DigiByte Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <primitives/block.h>
#include <util/strencodings.h>
#include <crypto/common.h>
#include <crypto/groestl.h>
#include <crypto/qubit.h>
#include <crypto/scrypt.h>
#include <crypto/skein.h>
#include <consensus/consensus.h>
#include <chainparams.h>
#include <util/system.h>
#include <hash.h>
#include <tinyformat.h>
#include <crypto/common.h>
#include <arith_uint256.h>

uint256 CBlockHeader::GetHash() const
{
    return SerializeHash(*this);
}

int CBlockHeader::GetAlgo() const
{
    switch (nVersion & BLOCK_VERSION_ALGO)
    {
        case BLOCK_VERSION_SCRYPT:
            return ALGO_SCRYPT;
        case BLOCK_VERSION_SHA256D:
            return ALGO_SHA256D;
        case BLOCK_VERSION_GROESTL:
            return ALGO_GROESTL;
        case BLOCK_VERSION_SKEIN:
            return ALGO_SKEIN;
        case BLOCK_VERSION_QUBIT:
            return ALGO_QUBIT;
    }
    return ALGO_UNKNOWN;
}

uint256 CBlockHeader::GetPoWAlgoHash(const Consensus::Params& params) const
{
    switch (GetAlgo())
    {
        case ALGO_SHA256D:
            return GetHash();
        case ALGO_SCRYPT:
        {
            uint256 thash;
            scrypt_1024_1_1_256(BEGIN(nVersion), END(thash));
            return thash;
        }
        case ALGO_GROESTL:
        {
            uint256 thash;
            groestl(BEGIN(nVersion), BEGIN(thash));
            return thash;
        }
        case ALGO_SKEIN:
        {
            uint256 thash;
            skein(BEGIN(nVersion), BEGIN(thash));
            return thash;
        }
        case ALGO_QUBIT:
        {
            uint256 thash;
            thash = qubit(BEGIN(nVersion));
            return thash;
        }
        case ALGO_UNKNOWN:
            // This block will be rejected anyway, but returning an always-invalid
            // PoW hash will allow it to be rejected sooner.
            return ArithToUint256(~arith_uint256(0));
    }
    assert(false);
    return GetHash();
}

std::string CBlock::ToString(const Consensus::Params& params) const
{
    std::stringstream s;
    s << strprintf("CBlock(hash=%s, ver=0x%08x, pow_algo=%d, pow_hash=%s, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%u)\n",
        GetHash().ToString(),
        nVersion,
        GetAlgo(),
        GetPoWAlgoHash(params).ToString(),
        hashPrevBlock.ToString(),
        hashMerkleRoot.ToString(),
        nTime, nBits, nNonce,
        vtx.size());
    for (const auto& tx : vtx) {
        s << "  " << tx->ToString() << "\n";
    }
    return s.str();
}

std::string GetAlgoName(int Algo)
{
    switch (Algo)
    {
        case ALGO_SHA256D:
            return std::string("sha256d");
        case ALGO_SCRYPT:
            return std::string("scrypt");
        case ALGO_GROESTL:
            return std::string("groestl");
        case ALGO_SKEIN:
            return std::string("skein");
        case ALGO_QUBIT:
            return std::string("qubit");
    }
    return std::string("unknown");
}

int GetAlgoByName(std::string strAlgo, int fallback)
{
    transform(strAlgo.begin(),strAlgo.end(),strAlgo.begin(),::tolower);
    if (strAlgo == "sha" || strAlgo == "sha256" || strAlgo == "sha256d")
        return ALGO_SHA256D;
    else if (strAlgo == "scrypt")
        return ALGO_SCRYPT;
    else if (strAlgo == "groestl" || strAlgo == "groestlsha2")
        return ALGO_GROESTL;
    else if (strAlgo == "skein" || strAlgo == "skeinsha2")
        return ALGO_SKEIN;
    else if (strAlgo == "q2c" || strAlgo == "qubit")
        return ALGO_QUBIT;
    else
        return fallback;
}

int64_t GetBlockWeight(const CBlock& block)
{
    // This implements the weight = (stripped_size * 4) + witness_size formula,
    // using only serialization with and without witness data. As witness_size
    // is equal to total_size - stripped_size, this formula is identical to:
    // weight = (stripped_size * 3) + total_size.
    return ::GetSerializeSize(block, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR - 1) + ::GetSerializeSize(block, PROTOCOL_VERSION);
}
<commit_msg>Refactoring GetPoWAlgoHash.<commit_after>// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2019 The Bitcoin Core developers
// Copyright (c) 2014-2019 The DigiByte Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <primitives/block.h>
#include <util/strencodings.h>
#include <crypto/common.h>
#include <crypto/groestl.h>
#include <crypto/qubit.h>
#include <crypto/scrypt.h>
#include <crypto/skein.h>
#include <consensus/consensus.h>
#include <chainparams.h>
#include <util/system.h>
#include <hash.h>
#include <tinyformat.h>
#include <crypto/common.h>
#include <arith_uint256.h>

uint256 CBlockHeader::GetHash() const
{
    return SerializeHash(*this);
}

int CBlockHeader::GetAlgo() const
{
    switch (nVersion & BLOCK_VERSION_ALGO)
    {
        case BLOCK_VERSION_SCRYPT:
            return ALGO_SCRYPT;
        case BLOCK_VERSION_SHA256D:
            return ALGO_SHA256D;
        case BLOCK_VERSION_GROESTL:
            return ALGO_GROESTL;
        case BLOCK_VERSION_SKEIN:
            return ALGO_SKEIN;
        case BLOCK_VERSION_QUBIT:
            return ALGO_QUBIT;
    }
    return ALGO_UNKNOWN;
}

uint256 CBlockHeader::GetPoWAlgoHash(const Consensus::Params& params) const
{
    uint256 thash;

    switch (GetAlgo())
    {
        case ALGO_SHA256D:
        {
            return GetHash();
        }
        case ALGO_SCRYPT:
        {
            scrypt_1024_1_1_256(BEGIN(nVersion), END(thash));
            break;
        }
        case ALGO_GROESTL:
        {
            groestl(BEGIN(nVersion), BEGIN(thash));
            break;
        }
        case ALGO_SKEIN:
        {
            skein(BEGIN(nVersion), BEGIN(thash));
            break;
        }
        case ALGO_QUBIT:
        {
            thash = qubit(BEGIN(nVersion));
            break;
        }
        case ALGO_UNKNOWN:
            // This block will be rejected anyway, but returning an always-invalid
            // PoW hash will allow it to be rejected sooner.
            thash = ArithToUint256(~arith_uint256(0));
            break;
    }
    return thash;
}

std::string CBlock::ToString(const Consensus::Params& params) const
{
    std::stringstream s;
    s << strprintf("CBlock(hash=%s, ver=0x%08x, pow_algo=%d, pow_hash=%s, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%u)\n",
        GetHash().ToString(),
        nVersion,
        GetAlgo(),
        GetPoWAlgoHash(params).ToString(),
        hashPrevBlock.ToString(),
        hashMerkleRoot.ToString(),
        nTime, nBits, nNonce,
        vtx.size());
    for (const auto& tx : vtx) {
        s << "  " << tx->ToString() << "\n";
    }
    return s.str();
}

std::string GetAlgoName(int Algo)
{
    switch (Algo)
    {
        case ALGO_SHA256D:
            return std::string("sha256d");
        case ALGO_SCRYPT:
            return std::string("scrypt");
        case ALGO_GROESTL:
            return std::string("groestl");
        case ALGO_SKEIN:
            return std::string("skein");
        case ALGO_QUBIT:
            return std::string("qubit");
    }
    return std::string("unknown");
}

int GetAlgoByName(std::string strAlgo, int fallback)
{
    transform(strAlgo.begin(),strAlgo.end(),strAlgo.begin(),::tolower);
    if (strAlgo == "sha" || strAlgo == "sha256" || strAlgo == "sha256d")
        return ALGO_SHA256D;
    else if (strAlgo == "scrypt")
        return ALGO_SCRYPT;
    else if (strAlgo == "groestl" || strAlgo == "groestlsha2")
        return ALGO_GROESTL;
    else if (strAlgo == "skein" || strAlgo == "skeinsha2")
        return ALGO_SKEIN;
    else if (strAlgo == "q2c" || strAlgo == "qubit")
        return ALGO_QUBIT;
    else
        return fallback;
}

int64_t GetBlockWeight(const CBlock& block)
{
    // This implements the weight = (stripped_size * 4) + witness_size formula,
    // using only serialization with and without witness data. As witness_size
    // is equal to total_size - stripped_size, this formula is identical to:
    // weight = (stripped_size * 3) + total_size.
    return ::GetSerializeSize(block, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR - 1) + ::GetSerializeSize(block, PROTOCOL_VERSION);
}
<|endoftext|>


<commit_before>/*
    This code is released under the terms of the MIT license.
    See COPYING.txt for details.
*/

#include <QMessageBox>
#include <algorithm>
#include "propertieswindow.h"
#include "ui_propertieswindow.h"
#include "stuff.h"
#include "level.h"
#include "graphics.h"
#include "hexspinbox.h"
#include "tileset.h"

PropertiesWindow::PropertiesWindow(QWidget *parent) :
    QDialog(parent, Qt::CustomizeWindowHint
            | Qt::WindowTitleHint
            | Qt::WindowCloseButtonHint
            | Qt::MSWindowsFixedSizeDialogHint
           ),
    ui(new Ui::PropertiesWindow),
    tileBox(new HexSpinBox(this, 2)),
    tilePalBox(new HexSpinBox(this, 2)),
    spriteBox(new HexSpinBox(this, 2)),
    spritePalBox(new HexSpinBox(this, 2))
{
    ui->setupUi(this);

    // prevent window resizing
    this->layout()->setSizeConstraint(QLayout::SetFixedSize);

    // add spinboxes
    QGridLayout *layout = ui->gridLayout;
    layout->addWidget(tileBox,      2, 2, 1, 1);
    layout->addWidget(tilePalBox,   2, 5, 1, 1);
    layout->addWidget(spriteBox,    3, 2, 1, 1);
    layout->addWidget(spritePalBox, 3, 5, 1, 1);

    // add music names to other dropdown
    for (StringMap::const_iterator i = musicNames.begin(); i != musicNames.end(); i++) {
        ui->comboBox_Music->addItem(i->second, i->first);
    }

    // set up signals to automatically apply changes
    QObject::connect(ui->comboBox_TileGFX, SIGNAL(currentIndexChanged(int)),
                     this, SLOT(applyChange()));
    QObject::connect(this->tileBox, SIGNAL(valueChanged(int)),
                     this, SLOT(applyChange()));
    QObject::connect(this->tilePalBox, SIGNAL(valueChanged(int)),
                     this, SLOT(applyChange()));
    QObject::connect(this->spriteBox, SIGNAL(valueChanged(int)),
                     this, SLOT(applyChange()));
    QObject::connect(this->spritePalBox, SIGNAL(valueChanged(int)),
                     this, SLOT(applyChange()));
    QObject::connect(ui->slider_AnimSpeed, SIGNAL(valueChanged(int)),
                     this, SLOT(applySpeed(int)));
    QObject::connect(ui->spinBox_Length, SIGNAL(valueChanged(int)),
                     this, SLOT(applyChange()));
    QObject::connect(ui->spinBox_Width, SIGNAL(valueChanged(int)),
                     this, SLOT(applyChange()));

    // set up signals to handle width/length constraints
    QObject::connect(ui->spinBox_Length, SIGNAL(valueChanged(int)),
                     this, SLOT(setMaxLevelWidth(int)));
    QObject::connect(ui->spinBox_Width, SIGNAL(valueChanged(int)),
                     this, SLOT(setMaxLevelLength(int)));
}

PropertiesWindow::~PropertiesWindow()
{
    delete ui;
}

void PropertiesWindow::setMaxLevelWidth(int length) {
    ui->spinBox_Width->setMaximum(16 / length);
}

void PropertiesWindow::setMaxLevelLength(int width) {
    ui->spinBox_Length->setMaximum(16 / width);
}

void PropertiesWindow::startEdit(leveldata_t *level) {
    this->level = NULL;

    // add graphics indices to dropdown
    ui->comboBox_TileGFX->clear();
    for (int i = 0; i < 256; i++)
        ui->comboBox_TileGFX->addItem(QString::number(i, 16).rightJustified(2, QLatin1Char('0')).toUpper()
                                         + ": banks "
                                         + QString::number(bankTable[0][i], 16).rightJustified(2, QLatin1Char('0')).toUpper() + ", "
                                         + QString::number(bankTable[1][i], 16).rightJustified(2, QLatin1Char('0')).toUpper() + ", "
                                         + QString::number(bankTable[2][i], 16).rightJustified(2, QLatin1Char('0')).toUpper() + "-"
                                         + QString::number((bankTable[2][i] + 3) & 0xFF, 16).rightJustified(2, QLatin1Char('0')).toUpper());

    // set graphics values
    ui->comboBox_TileGFX->setCurrentIndex(level->header.tileIndex);
    this->tileBox       ->setValue(level->tileset);
    this->tileBox       ->setMaximum(NUM_TILESETS - 1);
    this->tilePalBox    ->setValue(level->header.tilePal);
    this->tilePalBox    ->setMaximum(255);
    this->spriteBox     ->setValue(level->header.sprIndex);
    this->spriteBox     ->setMaximum(255);
    this->spritePalBox  ->setValue(level->header.sprPal);
    this->spritePalBox  ->setMaximum(255);
    ui->slider_AnimSpeed->setValue(level->header.animSpeed);

    // set height and width values
    ui->spinBox_Length->setValue(level->header.screensV);
    setMaxLevelWidth(level->header.screensH);

    ui->spinBox_Width ->setValue(level->header.screensH);
    setMaxLevelLength(level->header.screensV);

    // set music value
    ui->comboBox_Music->setCurrentIndex(std::distance(musicNames.begin(),
                                                      musicNames.find(level->header.music)));

    // save pointer
    this->level = level;
    // and original data, in case user cancels
    this->header  = level->header;
    this->tileset = level->tileset;

    this->exec();
}

void PropertiesWindow::applySpeed(int speed) {
    if (speed)
        //ui->label_FrameLength->setText(QString("%1 msec").arg(speed * 16));
        ui->label_FrameLength->setText(QString("%1 frame%2").arg(speed)
                                       .arg(speed > 1 ? "s" : ""));
    else
        ui->label_FrameLength->setText("none");

    if (level) {
        level->header.animSpeed = speed;
        emit speedChanged(speed);
    }
}

void PropertiesWindow::applyChange() {
    if (!level) return;

    level->header.tileIndex = ui->comboBox_TileGFX->currentIndex();
    level->header.tilePal   = this->tilePalBox->value();
    level->tileset          = this->tileBox->value();
    level->header.sprIndex  = this->spriteBox->value();
    level->header.sprPal    = this->spritePalBox->value();

    // apply level size
    level->header.screensV = ui->spinBox_Length->value();
    level->header.screensH = ui->spinBox_Width ->value();

    // apply music setting
    level->header.music = ui->comboBox_Music->itemData(ui->comboBox_Music->currentIndex()).toUInt();

    emit changed();
}

void PropertiesWindow::accept() {
    level->modified = true;
    level->modifiedRecently = true;

    QDialog::accept();
}

// discard settings
void PropertiesWindow::reject() {
    // return to original settings
    level->header  = this->header;
    level->tileset = this->tileset;

    emit changed();
    QDialog::reject();
}
<commit_msg>whoops<commit_after>/*
    This code is released under the terms of the MIT license.
    See COPYING.txt for details.
*/

#include <QMessageBox>
#include <algorithm>
#include "propertieswindow.h"
#include "ui_propertieswindow.h"
#include "stuff.h"
#include "level.h"
#include "graphics.h"
#include "hexspinbox.h"
#include "tileset.h"

PropertiesWindow::PropertiesWindow(QWidget *parent) :
    QDialog(parent, Qt::CustomizeWindowHint
            | Qt::WindowTitleHint
            | Qt::WindowCloseButtonHint
            | Qt::MSWindowsFixedSizeDialogHint
           ),
    ui(new Ui::PropertiesWindow),
    tileBox(new HexSpinBox(this, 2)),
    tilePalBox(new HexSpinBox(this, 2)),
    spriteBox(new HexSpinBox(this, 2)),
    spritePalBox(new HexSpinBox(this, 2))
{
    ui->setupUi(this);

    // prevent window resizing
    this->layout()->setSizeConstraint(QLayout::SetFixedSize);

    // add spinboxes
    QGridLayout *layout = ui->gridLayout;
    layout->addWidget(tileBox,      2, 2, 1, 1);
    layout->addWidget(tilePalBox,   2, 5, 1, 1);
    layout->addWidget(spriteBox,    3, 2, 1, 1);
    layout->addWidget(spritePalBox, 3, 5, 1, 1);

    // add music names to other dropdown
    for (StringMap::const_iterator i = musicNames.begin(); i != musicNames.end(); i++) {
        ui->comboBox_Music->addItem(i->second, i->first);
    }

    // set up signals to automatically apply changes
    QObject::connect(ui->comboBox_TileGFX, SIGNAL(currentIndexChanged(int)),
                     this, SLOT(applyChange()));
    QObject::connect(this->tileBox, SIGNAL(valueChanged(int)),
                     this, SLOT(applyChange()));
    QObject::connect(this->tilePalBox, SIGNAL(valueChanged(int)),
                     this, SLOT(applyChange()));
    QObject::connect(this->spriteBox, SIGNAL(valueChanged(int)),
                     this, SLOT(applyChange()));
    QObject::connect(this->spritePalBox, SIGNAL(valueChanged(int)),
                     this, SLOT(applyChange()));
    QObject::connect(ui->slider_AnimSpeed, SIGNAL(valueChanged(int)),
                     this, SLOT(applySpeed(int)));
    QObject::connect(ui->spinBox_Length, SIGNAL(valueChanged(int)),
                     this, SLOT(applyChange()));
    QObject::connect(ui->spinBox_Width, SIGNAL(valueChanged(int)),
                     this, SLOT(applyChange()));

    // set up signals to handle width/length constraints
    QObject::connect(ui->spinBox_Length, SIGNAL(valueChanged(int)),
                     this, SLOT(setMaxLevelWidth(int)));
    QObject::connect(ui->spinBox_Width, SIGNAL(valueChanged(int)),
                     this, SLOT(setMaxLevelLength(int)));
}

PropertiesWindow::~PropertiesWindow()
{
    delete ui;
    delete tileBox;
    delete tilePalBox;
    delete spriteBox;
    delete spritePalBox;
}

void PropertiesWindow::setMaxLevelWidth(int length) {
    ui->spinBox_Width->setMaximum(16 / length);
}

void PropertiesWindow::setMaxLevelLength(int width) {
    ui->spinBox_Length->setMaximum(16 / width);
}

void PropertiesWindow::startEdit(leveldata_t *level) {
    this->level = NULL;

    // add graphics indices to dropdown
    ui->comboBox_TileGFX->clear();
    for (int i = 0; i < 256; i++)
        ui->comboBox_TileGFX->addItem(QString::number(i, 16).rightJustified(2, QLatin1Char('0')).toUpper()
                                         + ": banks "
                                         + QString::number(bankTable[0][i], 16).rightJustified(2, QLatin1Char('0')).toUpper() + ", "
                                         + QString::number(bankTable[1][i], 16).rightJustified(2, QLatin1Char('0')).toUpper() + ", "
                                         + QString::number(bankTable[2][i], 16).rightJustified(2, QLatin1Char('0')).toUpper() + "-"
                                         + QString::number((bankTable[2][i] + 3) & 0xFF, 16).rightJustified(2, QLatin1Char('0')).toUpper());

    // set graphics values
    ui->comboBox_TileGFX->setCurrentIndex(level->header.tileIndex);
    this->tileBox       ->setValue(level->tileset);
    this->tileBox       ->setMaximum(NUM_TILESETS - 1);
    this->tilePalBox    ->setValue(level->header.tilePal);
    this->tilePalBox    ->setMaximum(255);
    this->spriteBox     ->setValue(level->header.sprIndex);
    this->spriteBox     ->setMaximum(255);
    this->spritePalBox  ->setValue(level->header.sprPal);
    this->spritePalBox  ->setMaximum(255);
    ui->slider_AnimSpeed->setValue(level->header.animSpeed);

    // set height and width values
    ui->spinBox_Length->setValue(level->header.screensV);
    setMaxLevelWidth(level->header.screensH);

    ui->spinBox_Width ->setValue(level->header.screensH);
    setMaxLevelLength(level->header.screensV);

    // set music value
    ui->comboBox_Music->setCurrentIndex(std::distance(musicNames.begin(),
                                                      musicNames.find(level->header.music)));

    // save pointer
    this->level = level;
    // and original data, in case user cancels
    this->header  = level->header;
    this->tileset = level->tileset;

    this->exec();
}

void PropertiesWindow::applySpeed(int speed) {
    if (speed)
        //ui->label_FrameLength->setText(QString("%1 msec").arg(speed * 16));
        ui->label_FrameLength->setText(QString("%1 frame%2").arg(speed)
                                       .arg(speed > 1 ? "s" : ""));
    else
        ui->label_FrameLength->setText("none");

    if (level) {
        level->header.animSpeed = speed;
        emit speedChanged(speed);
    }
}

void PropertiesWindow::applyChange() {
    if (!level) return;

    level->header.tileIndex = ui->comboBox_TileGFX->currentIndex();
    level->header.tilePal   = this->tilePalBox->value();
    level->tileset          = this->tileBox->value();
    level->header.sprIndex  = this->spriteBox->value();
    level->header.sprPal    = this->spritePalBox->value();

    // apply level size
    level->header.screensV = ui->spinBox_Length->value();
    level->header.screensH = ui->spinBox_Width ->value();

    // apply music setting
    level->header.music = ui->comboBox_Music->itemData(ui->comboBox_Music->currentIndex()).toUInt();

    emit changed();
}

void PropertiesWindow::accept() {
    level->modified = true;
    level->modifiedRecently = true;

    QDialog::accept();
}

// discard settings
void PropertiesWindow::reject() {
    // return to original settings
    level->header  = this->header;
    level->tileset = this->tileset;

    emit changed();
    QDialog::reject();
}
<|endoftext|>