<commit_before>#include <routingkit/osm_profile.h>

namespace RoutingKit{

namespace{
	bool str_eq(const char*l, const char*r){
		return !strcmp(l, r);
	}

	bool str_wild_char_eq(const char*l, const char*r){
		while(*l != '\0' && *r != '\0'){
			if(*l != '?' && *r != '?' && *l != *r)
				return false;
			++l;
			++r;
		}
		return *l == '\0' && *r == '\0';
	}

	bool starts_with(const char*prefix, const char*str){
		while(*prefix != '\0' && *str == *prefix){
			++prefix;
			++str;
		}
		return *prefix == '\0';
	}

	void copy_str_and_make_lower_case(const char*in, char*out, unsigned out_size){
		char*out_end = out + out_size-1;
		while(*in && out != out_end){
			if('A' <= *in && *in <= 'Z')
				*out = *in - 'A' + 'a';
			else
				*out = *in;
			++in;
			++out;
		}
		*out = '\0';
	}

	// Splits the string at some separators such as ; and calls f(str) for each part.
	// The ; is replaced by a '\0'. Leading spaces are removed
	template<class F>
	void split_str_at_osm_value_separators(char*in, const F&f){
		while(*in == ' ')
			++in;
		const char*value_begin = in;
		for(;;){
			while(*in != '\0' && *in != ';')
				++in;
			if(*in == '\0'){
				f(value_begin);
				return;
			}else{
				*in = '\0';
				f(value_begin);
				++in;
				while(*in == ' ')
					++in;
				value_begin = in;
			}
		}
	}
}

bool is_osm_way_used_by_cars(uint64_t osm_way_id, const TagMap&tags, std::function<void(const std::string&)>log_message){
	const char* junction = tags["junction"];
	if(junction != nullptr)
		return true;

	const char* highway = tags["highway"];
	if(highway == nullptr)
		return false;

	const char*motor_vehicle = tags["motor_vehicle"];
	if(motor_vehicle && str_eq(motor_vehicle, "no"))
		return false;

	const char*access = tags["access"];
	if(access){
		if(!(str_eq(access, "yes") || str_eq(access, "permissive") || str_eq(access, "delivery")|| str_eq(access, "designated") || str_eq(access, "destination")))
			return false;
	}

	if(
		str_eq(highway, "motorway") ||
		str_eq(highway, "trunk") ||
		str_eq(highway, "primary") ||
		str_eq(highway, "secondary") ||
		str_eq(highway, "tertiary") ||
		str_eq(highway, "unclassified") ||
		str_eq(highway, "residential") ||
		str_eq(highway, "service") ||
		str_eq(highway, "motorway_link") ||
		str_eq(highway, "trunk_link") ||
		str_eq(highway, "primary_link") ||
		str_eq(highway, "secondary_link") ||
		str_eq(highway, "motorway_junction") ||
		str_eq(highway, "living_street") ||
		str_eq(highway, "residential") ||
		str_eq(highway, "ferry")
	)
		return true;

	if(str_eq(highway, "bicycle_road")){
		auto motorcar = tags["motorcar"];
		if(motorcar != nullptr)
			if(str_eq(motorcar, "yes"))
				return true;
		return false;
	}

	if(
		str_eq(highway, "construction") ||
		str_eq(highway, "path") ||
		str_eq(highway, "footway") ||
		str_eq(highway, "cycleway") ||
		str_eq(highway, "bridleway") ||
		str_eq(highway, "pedestrian") ||
		str_eq(highway, "bus_guideway") ||
		str_eq(highway, "raceway") ||
		str_eq(highway, "escape") ||
		str_eq(highway, "steps") ||
		str_eq(highway, "conveying")
	)
		return false;

	const char* oneway = tags["oneway"];
	if(oneway != nullptr){
		if(str_eq(oneway, "reversible")) {
			return false;
		}
	}

	const char* maxspeed = tags["maxspeed"];
	if(maxspeed != nullptr)
		return true;

	return false;
}

OSMWayDirectionCategory get_osm_car_direction_category(uint64_t osm_way_id, const TagMap&tags, std::function<void(const std::string&)>log_message){
	const char
		*oneway = tags["oneway"],
		*junction = tags["junction"],
		*highway = tags["highway"]
	;
	if(oneway != nullptr){
		if(str_eq(oneway, "-1") || str_eq(oneway, "reverse") || str_eq(oneway, "backward")) {
			return OSMWayDirectionCategory::only_open_backwards;
		} else if(str_eq(oneway, "yes") || str_eq(oneway, "true") || str_eq(oneway, "1")) {
			return OSMWayDirectionCategory::only_open_forwards;
		} else if(str_eq(oneway, "no") || str_eq(oneway, "false") || str_eq(oneway, "0")) {
			return OSMWayDirectionCategory::open_in_both;
		} else if(str_eq(oneway, "reversible")) {
			return OSMWayDirectionCategory::closed;
		} else {
			log_message("Warning: OSM way "+std::to_string(osm_way_id)+" has unknown oneway tag value \""+oneway+"\" for \"oneway\". Way is closed.");
		}
	} else if(junction != nullptr && str_eq(junction, "roundabout")) {
		return OSMWayDirectionCategory::only_open_forwards;
	} else if(highway != nullptr && (str_eq(highway, "motorway") || str_eq(highway, "motorway_link"))) {
		return OSMWayDirectionCategory::only_open_forwards;
	}
	return OSMWayDirectionCategory::open_in_both;
}

namespace{
	unsigned parse_maxspeed_value(uint64_t osm_way_id, const char*maxspeed, std::function<void(const std::string&)>log_message){
		if(str_eq(maxspeed, "signals") || str_eq(maxspeed, "variable"))
			return inf_weight;

		if(str_eq(maxspeed, "none") || str_eq(maxspeed, "unlimited"))
			return 130;

		if(str_eq(maxspeed, "walk") || str_eq(maxspeed, "foot") || str_wild_char_eq(maxspeed, "??:walk"))
			return 5;

		if(str_wild_char_eq(maxspeed, "??:urban") || str_eq(maxspeed, "urban"))
			return 40;

		if(str_wild_char_eq(maxspeed, "??:living_street") || str_eq(maxspeed, "living_street"))
			return 10;

		if(str_eq(maxspeed, "de:rural") || str_eq(maxspeed, "at:rural") || str_eq(maxspeed, "ro:rural") || str_eq(maxspeed, "rural"))
			return 100;
		if(str_eq(maxspeed, "ru:rural") || str_eq(maxspeed, "fr:rural"))
			return 90;

		if(str_eq(maxspeed, "ru:motorway"))
			return 110;
		if(str_eq(maxspeed, "at:motorway") || str_eq(maxspeed, "ro:motorway"))
			return 130;

		if(str_eq(maxspeed, "national"))
			return 100;

		if(str_eq(maxspeed, "ro:trunk"))
			return 100;
		if(str_eq(maxspeed, "dk:rural"))
			return 80;
		if(str_eq(maxspeed, "it:rural") || str_eq(maxspeed, "hu:rural"))
			return 90;

		if('0' <= *maxspeed && *maxspeed <= '9'){
			unsigned speed = 0;
			while('0' <= *maxspeed && *maxspeed <= '9'){
				speed *= 10;
				speed += *maxspeed - '0';
				++maxspeed;
			}
			while(*maxspeed == ' ')
				++maxspeed;
			if(*maxspeed == '\0' || str_eq(maxspeed, "km/h") || str_eq(maxspeed, "kmh") || str_eq(maxspeed, "kph")){
				return speed;
			}else if(str_eq(maxspeed, "mph")){
				return speed * 1609 / 1000;
			}else if(str_eq(maxspeed, "knots")){
				return speed * 1852 / 1000;
			}else{
				log_message("Warning: OSM way "+std::to_string(osm_way_id) +" has an unknown unit \""+maxspeed+"\" for its \"maxspeed\" tag -> assuming \"km/h\".");
				return speed;
			}
		}else{
			log_message("Warning: OSM way "+std::to_string(osm_way_id) +" has an unrecognized value of \""+maxspeed+"\" for its \"maxspeed\" tag.");
		}

		return inf_weight;
	}
}

unsigned get_osm_way_speed(uint64_t osm_way_id, const TagMap&tags, std::function<void(const std::string&)>log_message){
	auto maxspeed = tags["maxspeed"];
	if(maxspeed != nullptr){
		char lower_case_maxspeed[1024];
		copy_str_and_make_lower_case(maxspeed, lower_case_maxspeed, sizeof(lower_case_maxspeed)-1);

		unsigned speed = inf_weight;

		split_str_at_osm_value_separators(
			lower_case_maxspeed,
			 [&](const char*maxspeed){
				min_to(speed, parse_maxspeed_value(osm_way_id, maxspeed, log_message));
			}
		);

		if(speed != inf_weight)
			return speed;

	}

	auto junction = tags["junction"];
	if(junction){
		return 20;
	}

	auto highway = tags["highway"];
	if(highway){
		if(str_eq(highway, "motorway"))
			return 90;
		if(str_eq(highway, "motorway_link"))
			return 45;
		if(str_eq(highway, "trunk"))
			return 85;
		if(str_eq(highway, "trunk_link"))
			return 40;
		if(str_eq(highway, "primary"))
			return 65;
		if(str_eq(highway, "primary_link"))
			return 30;
		if(str_eq(highway, "secondary"))
			return 55;
		if(str_eq(highway, "secondary_link"))
			return 25;
		if(str_eq(highway, "tertiary"))
			return 40;
		if(str_eq(highway, "tertiary_link"))
			return 20;
		if(str_eq(highway, "unclassified"))
			return 25;
		if(str_eq(highway, "residential"))
			return 25;
		if(str_eq(highway, "living_street"))
			return 10;
		if(str_eq(highway, "service"))
			return 1;
		if(str_eq(highway, "ferry"))
			return 5;
	}

	if(maxspeed && highway)
		log_message("Warning: OSM way "+std::to_string(osm_way_id) +" has an unrecognized \"maxspeed\" tag of \""+maxspeed+"\" and an unrecognized \"highway\" tag of \""+highway+"\" and an no junction tag -> assuming 50km/h.");
	if(!maxspeed && highway)
		log_message("Warning: OSM way "+std::to_string(osm_way_id) +" has no \"maxspeed\" and an unrecognized \"highway\" tag of \""+highway+"\" and an no junction tag -> assuming 50km/h.");
	if(!maxspeed && !highway)
		log_message("Warning: OSM way "+std::to_string(osm_way_id) +" has no \"maxspeed\" and no \"highway\" tag of \""+highway+"\" and an no junction tag -> assuming 50km/h.");
	if(maxspeed && !highway)
		log_message("Warning: OSM way "+std::to_string(osm_way_id) +" has an unrecognized \"maxspeed\" tag of \""+maxspeed+"\" and no \"highway\" tag and an no junction tag -> assuming 50km/h.");
	return 50;
}

std::string get_osm_way_name(uint64_t osm_way_id, const TagMap&tags, std::function<void(const std::string&)>log_message){
	auto
		name = tags["name"],
		ref = tags["ref"];

	if(name != nullptr && ref != nullptr)
		return std::string(name) + ";"+ref;
	else if(name != nullptr)
		return std::string(name);
	else if(ref != nullptr)
		return std::string(ref);
	else
		return std::string();
}

} // RoutingKit
<commit_msg>patch to make sure that get_osm_way_speed never returns 0<commit_after>#include <routingkit/osm_profile.h>

namespace RoutingKit{

namespace{
	bool str_eq(const char*l, const char*r){
		return !strcmp(l, r);
	}

	bool str_wild_char_eq(const char*l, const char*r){
		while(*l != '\0' && *r != '\0'){
			if(*l != '?' && *r != '?' && *l != *r)
				return false;
			++l;
			++r;
		}
		return *l == '\0' && *r == '\0';
	}

	bool starts_with(const char*prefix, const char*str){
		while(*prefix != '\0' && *str == *prefix){
			++prefix;
			++str;
		}
		return *prefix == '\0';
	}

	void copy_str_and_make_lower_case(const char*in, char*out, unsigned out_size){
		char*out_end = out + out_size-1;
		while(*in && out != out_end){
			if('A' <= *in && *in <= 'Z')
				*out = *in - 'A' + 'a';
			else
				*out = *in;
			++in;
			++out;
		}
		*out = '\0';
	}

	// Splits the string at some separators such as ; and calls f(str) for each part.
	// The ; is replaced by a '\0'. Leading spaces are removed
	template<class F>
	void split_str_at_osm_value_separators(char*in, const F&f){
		while(*in == ' ')
			++in;
		const char*value_begin = in;
		for(;;){
			while(*in != '\0' && *in != ';')
				++in;
			if(*in == '\0'){
				f(value_begin);
				return;
			}else{
				*in = '\0';
				f(value_begin);
				++in;
				while(*in == ' ')
					++in;
				value_begin = in;
			}
		}
	}
}

bool is_osm_way_used_by_cars(uint64_t osm_way_id, const TagMap&tags, std::function<void(const std::string&)>log_message){
	const char* junction = tags["junction"];
	if(junction != nullptr)
		return true;

	const char* highway = tags["highway"];
	if(highway == nullptr)
		return false;

	const char*motor_vehicle = tags["motor_vehicle"];
	if(motor_vehicle && str_eq(motor_vehicle, "no"))
		return false;

	const char*access = tags["access"];
	if(access){
		if(!(str_eq(access, "yes") || str_eq(access, "permissive") || str_eq(access, "delivery")|| str_eq(access, "designated") || str_eq(access, "destination")))
			return false;
	}

	if(
		str_eq(highway, "motorway") ||
		str_eq(highway, "trunk") ||
		str_eq(highway, "primary") ||
		str_eq(highway, "secondary") ||
		str_eq(highway, "tertiary") ||
		str_eq(highway, "unclassified") ||
		str_eq(highway, "residential") ||
		str_eq(highway, "service") ||
		str_eq(highway, "motorway_link") ||
		str_eq(highway, "trunk_link") ||
		str_eq(highway, "primary_link") ||
		str_eq(highway, "secondary_link") ||
		str_eq(highway, "motorway_junction") ||
		str_eq(highway, "living_street") ||
		str_eq(highway, "residential") ||
		str_eq(highway, "ferry")
	)
		return true;

	if(str_eq(highway, "bicycle_road")){
		auto motorcar = tags["motorcar"];
		if(motorcar != nullptr)
			if(str_eq(motorcar, "yes"))
				return true;
		return false;
	}

	if(
		str_eq(highway, "construction") ||
		str_eq(highway, "path") ||
		str_eq(highway, "footway") ||
		str_eq(highway, "cycleway") ||
		str_eq(highway, "bridleway") ||
		str_eq(highway, "pedestrian") ||
		str_eq(highway, "bus_guideway") ||
		str_eq(highway, "raceway") ||
		str_eq(highway, "escape") ||
		str_eq(highway, "steps") ||
		str_eq(highway, "conveying")
	)
		return false;

	const char* oneway = tags["oneway"];
	if(oneway != nullptr){
		if(str_eq(oneway, "reversible")) {
			return false;
		}
	}

	const char* maxspeed = tags["maxspeed"];
	if(maxspeed != nullptr)
		return true;

	return false;
}

OSMWayDirectionCategory get_osm_car_direction_category(uint64_t osm_way_id, const TagMap&tags, std::function<void(const std::string&)>log_message){
	const char
		*oneway = tags["oneway"],
		*junction = tags["junction"],
		*highway = tags["highway"]
	;
	if(oneway != nullptr){
		if(str_eq(oneway, "-1") || str_eq(oneway, "reverse") || str_eq(oneway, "backward")) {
			return OSMWayDirectionCategory::only_open_backwards;
		} else if(str_eq(oneway, "yes") || str_eq(oneway, "true") || str_eq(oneway, "1")) {
			return OSMWayDirectionCategory::only_open_forwards;
		} else if(str_eq(oneway, "no") || str_eq(oneway, "false") || str_eq(oneway, "0")) {
			return OSMWayDirectionCategory::open_in_both;
		} else if(str_eq(oneway, "reversible")) {
			return OSMWayDirectionCategory::closed;
		} else {
			log_message("Warning: OSM way "+std::to_string(osm_way_id)+" has unknown oneway tag value \""+oneway+"\" for \"oneway\". Way is closed.");
		}
	} else if(junction != nullptr && str_eq(junction, "roundabout")) {
		return OSMWayDirectionCategory::only_open_forwards;
	} else if(highway != nullptr && (str_eq(highway, "motorway") || str_eq(highway, "motorway_link"))) {
		return OSMWayDirectionCategory::only_open_forwards;
	}
	return OSMWayDirectionCategory::open_in_both;
}

namespace{
	unsigned parse_maxspeed_value(uint64_t osm_way_id, const char*maxspeed, std::function<void(const std::string&)>log_message){
		if(str_eq(maxspeed, "signals") || str_eq(maxspeed, "variable"))
			return inf_weight;

		if(str_eq(maxspeed, "none") || str_eq(maxspeed, "unlimited"))
			return 130;

		if(str_eq(maxspeed, "walk") || str_eq(maxspeed, "foot") || str_wild_char_eq(maxspeed, "??:walk"))
			return 5;

		if(str_wild_char_eq(maxspeed, "??:urban") || str_eq(maxspeed, "urban"))
			return 40;

		if(str_wild_char_eq(maxspeed, "??:living_street") || str_eq(maxspeed, "living_street"))
			return 10;

		if(str_eq(maxspeed, "de:rural") || str_eq(maxspeed, "at:rural") || str_eq(maxspeed, "ro:rural") || str_eq(maxspeed, "rural"))
			return 100;
		if(str_eq(maxspeed, "ru:rural") || str_eq(maxspeed, "fr:rural"))
			return 90;

		if(str_eq(maxspeed, "ru:motorway"))
			return 110;
		if(str_eq(maxspeed, "at:motorway") || str_eq(maxspeed, "ro:motorway"))
			return 130;

		if(str_eq(maxspeed, "national"))
			return 100;

		if(str_eq(maxspeed, "ro:trunk"))
			return 100;
		if(str_eq(maxspeed, "dk:rural"))
			return 80;
		if(str_eq(maxspeed, "it:rural") || str_eq(maxspeed, "hu:rural"))
			return 90;

		if('0' <= *maxspeed && *maxspeed <= '9'){
			unsigned speed = 0;
			while('0' <= *maxspeed && *maxspeed <= '9'){
				speed *= 10;
				speed += *maxspeed - '0';
				++maxspeed;
			}
			while(*maxspeed == ' ')
				++maxspeed;
			if(*maxspeed == '\0' || str_eq(maxspeed, "km/h") || str_eq(maxspeed, "kmh") || str_eq(maxspeed, "kph")){
				return speed;
			}else if(str_eq(maxspeed, "mph")){
				return speed * 1609 / 1000;
			}else if(str_eq(maxspeed, "knots")){
				return speed * 1852 / 1000;
			}else{
				log_message("Warning: OSM way "+std::to_string(osm_way_id) +" has an unknown unit \""+maxspeed+"\" for its \"maxspeed\" tag -> assuming \"km/h\".");
				return speed;
			}
		}else{
			log_message("Warning: OSM way "+std::to_string(osm_way_id) +" has an unrecognized value of \""+maxspeed+"\" for its \"maxspeed\" tag.");
		}

		return inf_weight;
	}
}

unsigned get_osm_way_speed(uint64_t osm_way_id, const TagMap&tags, std::function<void(const std::string&)>log_message){
	auto maxspeed = tags["maxspeed"];
	if(maxspeed != nullptr){
		char lower_case_maxspeed[1024];
		copy_str_and_make_lower_case(maxspeed, lower_case_maxspeed, sizeof(lower_case_maxspeed)-1);

		unsigned speed = inf_weight;

		split_str_at_osm_value_separators(
			lower_case_maxspeed,
			 [&](const char*maxspeed){
				min_to(speed, parse_maxspeed_value(osm_way_id, maxspeed, log_message));
			}
		);

		if(speed == 0){
			speed = 1;
			log_message("Warning: OSM way "+std::to_string(osm_way_id)+" has speed 0 km/h, setting it to 1 km/h");
		}

		if(speed != inf_weight)
			return speed;

	}

	auto junction = tags["junction"];
	if(junction){
		return 20;
	}

	auto highway = tags["highway"];
	if(highway){
		if(str_eq(highway, "motorway"))
			return 90;
		if(str_eq(highway, "motorway_link"))
			return 45;
		if(str_eq(highway, "trunk"))
			return 85;
		if(str_eq(highway, "trunk_link"))
			return 40;
		if(str_eq(highway, "primary"))
			return 65;
		if(str_eq(highway, "primary_link"))
			return 30;
		if(str_eq(highway, "secondary"))
			return 55;
		if(str_eq(highway, "secondary_link"))
			return 25;
		if(str_eq(highway, "tertiary"))
			return 40;
		if(str_eq(highway, "tertiary_link"))
			return 20;
		if(str_eq(highway, "unclassified"))
			return 25;
		if(str_eq(highway, "residential"))
			return 25;
		if(str_eq(highway, "living_street"))
			return 10;
		if(str_eq(highway, "service"))
			return 1;
		if(str_eq(highway, "ferry"))
			return 5;
	}

	if(maxspeed && highway)
		log_message("Warning: OSM way "+std::to_string(osm_way_id) +" has an unrecognized \"maxspeed\" tag of \""+maxspeed+"\" and an unrecognized \"highway\" tag of \""+highway+"\" and an no junction tag -> assuming 50km/h.");
	if(!maxspeed && highway)
		log_message("Warning: OSM way "+std::to_string(osm_way_id) +" has no \"maxspeed\" and an unrecognized \"highway\" tag of \""+highway+"\" and an no junction tag -> assuming 50km/h.");
	if(!maxspeed && !highway)
		log_message("Warning: OSM way "+std::to_string(osm_way_id) +" has no \"maxspeed\" and no \"highway\" tag of \""+highway+"\" and an no junction tag -> assuming 50km/h.");
	if(maxspeed && !highway)
		log_message("Warning: OSM way "+std::to_string(osm_way_id) +" has an unrecognized \"maxspeed\" tag of \""+maxspeed+"\" and no \"highway\" tag and an no junction tag -> assuming 50km/h.");
	return 50;
}

std::string get_osm_way_name(uint64_t osm_way_id, const TagMap&tags, std::function<void(const std::string&)>log_message){
	auto
		name = tags["name"],
		ref = tags["ref"];

	if(name != nullptr && ref != nullptr)
		return std::string(name) + ";"+ref;
	else if(name != nullptr)
		return std::string(name);
	else if(ref != nullptr)
		return std::string(ref);
	else
		return std::string();
}

} // RoutingKit
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: soerr.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 13:55:44 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef _SOERR_HXX
#define _SOERR_HXX

#ifndef _ERRCODE_HXX //autogen
#include <tools/errcode.hxx>
#endif

// Fehler Codes
#define RID_SO_ERROR_HANDLER    32000

#define SO_ERR() (ERRCODE_AREA_SO | ERRCODE_CLASS_SO)
#define SO_WRN() (ERRCODE_AREA_SO | ERRCODE_CLASS_SO | ERRCODE_WARNING_MASK)

#define ERRCODE_SO_GENERALERROR             (SO_ERR() | 1)
#define ERRCODE_SO_CANT_BINDTOSOURCE        (SO_ERR() | 2)
#define ERRCODE_SO_NOCACHE_UPDATED          (SO_ERR() | 3)
#define ERRCODE_SO_SOMECACHES_NOTUPDATED    (SO_WRN() | 4)
#define ERRCODE_SO_MK_UNAVAILABLE           (SO_ERR() | 5)
#define ERRCODE_SO_E_CLASSDIFF              (SO_ERR() | 6)
#define ERRCODE_SO_MK_NO_OBJECT             (SO_ERR() | 7)
#define ERRCODE_SO_MK_EXCEEDED_DEADLINE     (SO_ERR() | 8)
#define ERRCODE_SO_MK_CONNECT_MANUALLY      (SO_ERR() | 9)
#define ERRCODE_SO_MK_INTERMEDIATE_INTERFACE_NOT_SUPPORTED  (SO_ERR() | 10)
#define ERRCODE_SO_NO_INTERFACE             (SO_ERR() | 11)
#define ERRCODE_SO_OUT_OF_MEMORY            (SO_ERR() | 12)
#define ERRCODE_SO_MK_SYNTAX                (SO_ERR() | 13)
#define ERRCODE_SO_MK_REDUCED_TO_SELF       (SO_WRN() | 14)
#define ERRCODE_SO_MK_NO_INVERSE            (SO_ERR() | 15)
#define ERRCODE_SO_MK_NO_PREFIX             (SO_ERR() | 16)
#define ERRCODE_SO_MK_HIM                   (SO_WRN() | 17)
#define ERRCODE_SO_MK_US                    (SO_WRN() | 18)
#define ERRCODE_SO_MK_ME                    (SO_WRN() | 19)
#define ERRCODE_SO_MK_NOT_BINDABLE          (SO_ERR() | 20)
#define ERRCODE_SO_NOT_IMPLEMENTED          (SO_ERR() | 21)
#define ERRCODE_SO_MK_NO_STORAGE            (SO_ERR() | 22)
#define ERRCODE_SO_FALSE                    (SO_WRN() | 23)
#define ERRCODE_SO_MK_NEED_GENERIC          (SO_ERR() | 24)
#define ERRCODE_SO_PENDING                  (SO_ERR() | 25)
#define ERRCODE_SO_NOT_INPLACEACTIVE        (SO_ERR() | 26)
#define ERRCODE_SO_LINDEX                   (SO_ERR() | 27)
#define ERRCODE_SO_CANNOT_DOVERB_NOW        (SO_WRN() | 28)
#define ERRCODE_SO_OLEOBJ_INVALIDHWND       (SO_WRN() | 29)
#define ERRCODE_SO_NOVERBS                  (SO_ERR() | 30)
#define ERRCODE_SO_INVALIDVERB              (SO_WRN() | 31)
#define ERRCODE_SO_MK_CONNECT               (SO_ERR() | 32)
#define ERRCODE_SO_NOTIMPL                  (SO_ERR() | 33)
#define ERRCODE_SO_MK_CANTOPENFILE          (SO_ERR() | 34)

// Fehler Contexte
#define RID_SO_ERRCTX           32001

#define ERRCTX_SO_DOVERB        1

#endif

<commit_msg>INTEGRATION: CWS changefileheader (1.3.774); FILE MERGED 2008/04/01 15:44:23 thb 1.3.774.2: #i85898# Stripping all external header guards 2008/03/31 13:00:56 rt 1.3.774.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: soerr.hxx,v $
 * $Revision: 1.4 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/
#ifndef _SOERR_HXX
#define _SOERR_HXX

#include <tools/errcode.hxx>

// Fehler Codes
#define RID_SO_ERROR_HANDLER    32000

#define SO_ERR() (ERRCODE_AREA_SO | ERRCODE_CLASS_SO)
#define SO_WRN() (ERRCODE_AREA_SO | ERRCODE_CLASS_SO | ERRCODE_WARNING_MASK)

#define ERRCODE_SO_GENERALERROR             (SO_ERR() | 1)
#define ERRCODE_SO_CANT_BINDTOSOURCE        (SO_ERR() | 2)
#define ERRCODE_SO_NOCACHE_UPDATED          (SO_ERR() | 3)
#define ERRCODE_SO_SOMECACHES_NOTUPDATED    (SO_WRN() | 4)
#define ERRCODE_SO_MK_UNAVAILABLE           (SO_ERR() | 5)
#define ERRCODE_SO_E_CLASSDIFF              (SO_ERR() | 6)
#define ERRCODE_SO_MK_NO_OBJECT             (SO_ERR() | 7)
#define ERRCODE_SO_MK_EXCEEDED_DEADLINE     (SO_ERR() | 8)
#define ERRCODE_SO_MK_CONNECT_MANUALLY      (SO_ERR() | 9)
#define ERRCODE_SO_MK_INTERMEDIATE_INTERFACE_NOT_SUPPORTED  (SO_ERR() | 10)
#define ERRCODE_SO_NO_INTERFACE             (SO_ERR() | 11)
#define ERRCODE_SO_OUT_OF_MEMORY            (SO_ERR() | 12)
#define ERRCODE_SO_MK_SYNTAX                (SO_ERR() | 13)
#define ERRCODE_SO_MK_REDUCED_TO_SELF       (SO_WRN() | 14)
#define ERRCODE_SO_MK_NO_INVERSE            (SO_ERR() | 15)
#define ERRCODE_SO_MK_NO_PREFIX             (SO_ERR() | 16)
#define ERRCODE_SO_MK_HIM                   (SO_WRN() | 17)
#define ERRCODE_SO_MK_US                    (SO_WRN() | 18)
#define ERRCODE_SO_MK_ME                    (SO_WRN() | 19)
#define ERRCODE_SO_MK_NOT_BINDABLE          (SO_ERR() | 20)
#define ERRCODE_SO_NOT_IMPLEMENTED          (SO_ERR() | 21)
#define ERRCODE_SO_MK_NO_STORAGE            (SO_ERR() | 22)
#define ERRCODE_SO_FALSE                    (SO_WRN() | 23)
#define ERRCODE_SO_MK_NEED_GENERIC          (SO_ERR() | 24)
#define ERRCODE_SO_PENDING                  (SO_ERR() | 25)
#define ERRCODE_SO_NOT_INPLACEACTIVE        (SO_ERR() | 26)
#define ERRCODE_SO_LINDEX                   (SO_ERR() | 27)
#define ERRCODE_SO_CANNOT_DOVERB_NOW        (SO_WRN() | 28)
#define ERRCODE_SO_OLEOBJ_INVALIDHWND       (SO_WRN() | 29)
#define ERRCODE_SO_NOVERBS                  (SO_ERR() | 30)
#define ERRCODE_SO_INVALIDVERB              (SO_WRN() | 31)
#define ERRCODE_SO_MK_CONNECT               (SO_ERR() | 32)
#define ERRCODE_SO_NOTIMPL                  (SO_ERR() | 33)
#define ERRCODE_SO_MK_CANTOPENFILE          (SO_ERR() | 34)

// Fehler Contexte
#define RID_SO_ERRCTX           32001

#define ERRCTX_SO_DOVERB        1

#endif

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: wrapfield.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: kz $ $Date: 2005-01-21 15:55:26 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  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., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef SVX_WRAPFIELD_HXX
#define SVX_WRAPFIELD_HXX

#ifndef _SV_FIELD_HXX
#include <vcl/field.hxx>
#endif

#ifndef INCLUDED_SVXDLLAPI_H
#include "svx/svxdllapi.h"
#endif

namespace svx {

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

/** A numeric spin field that wraps around the value on limits.
    @descr  Note: Use type "NumericField" in resources. */
class SVX_DLLPUBLIC WrapField : public NumericField
{
public:
    explicit            WrapField( Window* pParent, WinBits nWinStyle );
    explicit            WrapField( Window* pParent, const ResId& rResId );

protected:
    /** Up event with wrap-around functionality. */
    virtual void        Up();
    /** Down event with wrap-around functionality. */
    virtual void        Down();
};

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

} // namespace svx

#endif

<commit_msg>INTEGRATION: CWS ooo19126 (1.3.430); FILE MERGED 2005/09/05 14:17:04 rt 1.3.430.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: wrapfield.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 19:33:40 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef SVX_WRAPFIELD_HXX
#define SVX_WRAPFIELD_HXX

#ifndef _SV_FIELD_HXX
#include <vcl/field.hxx>
#endif

#ifndef INCLUDED_SVXDLLAPI_H
#include "svx/svxdllapi.h"
#endif

namespace svx {

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

/** A numeric spin field that wraps around the value on limits.
    @descr  Note: Use type "NumericField" in resources. */
class SVX_DLLPUBLIC WrapField : public NumericField
{
public:
    explicit            WrapField( Window* pParent, WinBits nWinStyle );
    explicit            WrapField( Window* pParent, const ResId& rResId );

protected:
    /** Up event with wrap-around functionality. */
    virtual void        Up();
    /** Down event with wrap-around functionality. */
    virtual void        Down();
};

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

} // namespace svx

#endif

<|endoftext|>


<commit_before>#include <boost/thread.hpp>
#include <sys/resource.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <assert.h>
#include <signal.h>
#include "coroutine.h"

static const char* g_ip = "127.0.0.1";
static const uint16_t g_port = 43333;
int thread_count = 4;
int qdata = 4;
std::atomic<int> session_count{0};

void echo_server()
{
    int ret;
    int accept_fd = socket(AF_INET, SOCK_STREAM, 0);
    assert(accept_fd >= 0);

    int v = 1;
    ret = setsockopt(accept_fd, SOL_SOCKET, SO_REUSEPORT, &v, sizeof(v));
    assert(ret == 0);

    sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(g_port);
    addr.sin_addr.s_addr = inet_addr(g_ip);
    ret = bind(accept_fd, (sockaddr*)&addr, sizeof(addr));
    assert(ret == 0);

    ret = listen(accept_fd, 100);
    assert(ret == 0);

    printf("Coroutine server startup, thread:%d, qdata:%d, listen %s:%d\n",
            thread_count, qdata, g_ip, g_port);
    for (;;) {
        socklen_t addr_len = sizeof(addr);
        int sock_fd = accept(accept_fd, (sockaddr*)&addr, &addr_len);
        if (sock_fd < 0) {
            perror("accept error:");
            continue;
        }

        go [sock_fd]{
            ++session_count;
            printf("connected(%d). socket=%d\n", (int)session_count, sock_fd);
            co_chan<bool> err;

            go [err, sock_fd] {
                int buflen = 4096;
                char *buf = new char[buflen];
                std::unique_ptr<char[]> _ep(buf);

                int noyield_for_c = 0;
                for (;;++noyield_for_c) {
retry_read:
                    auto n = read(sock_fd, buf, buflen);
                    if (n <= 0) {
                        if (errno == EINTR) {
                            printf("trigger EINTR. socket=%d\n", sock_fd);
                            goto retry_read;
                        }
                        break;
                    }

                    size_t begin = 0;
goon_write:
                    ssize_t rn = write(sock_fd, buf + begin, std::min<int>(n, qdata));
                    if (rn <= 0) {
                        if (errno == EINTR) {
                            printf("trigger EINTR. socket=%d\n", sock_fd);
                            goto goon_write;
                        }
                        break;
                    }
                    n -= rn;
                    begin += rn;
                    if ((noyield_for_c & 0xff) == 0)
                        co_yield;

                    if (n > 0) {
                        ++noyield_for_c;
                        goto goon_write;
                    }
                }
                printf("error trigger, socket=%d. errinfo:%s\n", sock_fd, strerror(errno));
                err << true;
            };

            err >> nullptr;
            --session_count;
            printf("disconnected(%d).\n", (int)session_count);
        };
    }
}

int main(int argc, char **argv)
{
    sigignore(SIGPIPE);

    if (argc > 1)
        if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0) {
            printf("\n    Usage: %s [ThreadCount] [QueryDataLength]\n", argv[0]);
            printf("\n    Default: %s 4 4\n", argv[0]);
            printf("\n    For example:\n         %s 2 32\n", argv[0]);
            printf("\n    That's means: start server with 2 threads, and per data-package is 32 bytes.\n\n");
            exit(1);
        }

//    co_sched.GetOptions().debug = co::dbg_ioblock;

    if (argc > 1)
        thread_count = atoi(argv[1]);
    if (argc > 2)
        qdata = atoi(argv[2]);

    rlimit of = {65536, 65536};
    if (-1 == setrlimit(RLIMIT_NOFILE, &of)) {
        perror("setrlimit");
        exit(1);
    }

    go echo_server;

    boost::thread_group tg;
    for (int i = 0; i < thread_count; ++i)
        tg.create_thread([] { g_Scheduler.RunUntilNoTask(); });
    tg.join_all();
    return 0;
}

<commit_msg>调整测试代码<commit_after>#include <boost/thread.hpp>
#include <sys/resource.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <assert.h>
#include <signal.h>
#include "coroutine.h"

static const char* g_ip = "127.0.0.1";
static const uint16_t g_port = 43333;
int thread_count = 4;
int qdata = 4;
std::atomic<int> session_count{0};

void echo_server()
{
    int ret;
    int accept_fd = socket(AF_INET, SOCK_STREAM, 0);
    assert(accept_fd >= 0);

    int v = 1;
    ret = setsockopt(accept_fd, SOL_SOCKET, SO_REUSEPORT, &v, sizeof(v));
    assert(ret == 0);

    sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(g_port);
    addr.sin_addr.s_addr = inet_addr(g_ip);
    ret = bind(accept_fd, (sockaddr*)&addr, sizeof(addr));
    assert(ret == 0);

    ret = listen(accept_fd, 100);
    assert(ret == 0);

    printf("Coroutine server startup, thread:%d, qdata:%d, listen %s:%d\n",
            thread_count, qdata, g_ip, g_port);
    for (;;) {
        socklen_t addr_len = sizeof(addr);
        int sock_fd = accept(accept_fd, (sockaddr*)&addr, &addr_len);
        if (sock_fd < 0) {
            perror("accept error:");
            continue;
        }

        go [sock_fd]{
            ++session_count;
            printf("connected(%d). socket=%d\n", (int)session_count, sock_fd);
            co_chan<bool> err;

            go [err, sock_fd] {
                char *buf = new char[qdata];
                std::unique_ptr<char[]> _ep(buf);

                int noyield_for_c = 0;
                for (;;++noyield_for_c) {
retry_read:
                    auto n = read(sock_fd, buf, qdata);
                    if (n <= 0) {
                        if (errno == EINTR) {
                            printf("trigger EINTR. socket=%d\n", sock_fd);
                            goto retry_read;
                        }
                        break;
                    }

                    size_t begin = 0;
goon_write:
                    ssize_t rn = write(sock_fd, buf + begin, std::min<int>(n, qdata));
                    if (rn <= 0) {
                        if (errno == EINTR) {
                            printf("trigger EINTR. socket=%d\n", sock_fd);
                            goto goon_write;
                        }
                        break;
                    }
                    n -= rn;
                    begin += rn;
                    if ((noyield_for_c & 0xff) == 0)
                        co_yield;

                    if (n > 0) {
                        ++noyield_for_c;
                        goto goon_write;
                    }
                }
                printf("error trigger, socket=%d. errinfo:%s\n", sock_fd, strerror(errno));
                err << true;
            };

            err >> nullptr;
            --session_count;
            printf("disconnected(%d).\n", (int)session_count);
        };
    }
}

int main(int argc, char **argv)
{
    sigignore(SIGPIPE);

    if (argc > 1)
        if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0) {
            printf("\n    Usage: %s [ThreadCount] [QueryDataLength]\n", argv[0]);
            printf("\n    Default: %s 4 4\n", argv[0]);
            printf("\n    For example:\n         %s 2 32\n", argv[0]);
            printf("\n    That's means: start server with 2 threads, and per data-package is 32 bytes.\n\n");
            exit(1);
        }

//    co_sched.GetOptions().debug = co::dbg_ioblock;

    if (argc > 1)
        thread_count = atoi(argv[1]);
    if (argc > 2)
        qdata = atoi(argv[2]);

    rlimit of = {65536, 65536};
    if (-1 == setrlimit(RLIMIT_NOFILE, &of)) {
        perror("setrlimit");
        exit(1);
    }

    go echo_server;

    boost::thread_group tg;
    for (int i = 0; i < thread_count; ++i)
        tg.create_thread([] { g_Scheduler.RunUntilNoTask(); });
    tg.join_all();
    return 0;
}

<|endoftext|>


<commit_before><commit_msg>Avoid warning from clang analyze due to potential NULL pointer by asserting pointer is not NULL.<commit_after><|endoftext|>


<commit_before>/***************************************************************************
    copyright            : (C) 2004 by Allan Sandfeld Jensen
    email                : kde@carewolf.com
 ***************************************************************************/

/***************************************************************************
 *   This library is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU Lesser General Public License version   *
 *   2.1 as published by the Free Software Foundation.                     *
 *                                                                         *
 *   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 Street, Fifth Floor, Boston, MA         *
 *   02110-1301  USA                                                       *
 *                                                                         *
 *   Alternatively, this file is available under the Mozilla Public        *
 *   License Version 1.1.  You may obtain a copy of the License at         *
 *   http://www.mozilla.org/MPL/                                           *
 ***************************************************************************/

#ifdef __SUNPRO_CC
// Sun Studio finds multiple specializations of Map because
// it considers specializations with and without class types
// to be different; this define forces Map to use only the
// specialization with the class keyword.
#define WANT_CLASS_INSTANTIATION_OF_MAP (1)
#endif

#include <tfile.h>
#include <tstring.h>
#include <tmap.h>
#include <tpropertymap.h>

#include "apetag.h"
#include "apefooter.h"
#include "apeitem.h"

using namespace TagLib;
using namespace APE;

class APE::Tag::TagPrivate
{
public:
  TagPrivate() : file(0), footerLocation(-1), tagLength(0) {}

  TagLib::File *file;
  long footerLocation;
  long tagLength;

  Footer footer;

  ItemListMap itemListMap;
};

////////////////////////////////////////////////////////////////////////////////
// public methods
////////////////////////////////////////////////////////////////////////////////

APE::Tag::Tag() : TagLib::Tag()
{
  d = new TagPrivate;
}

APE::Tag::Tag(TagLib::File *file, long footerLocation) : TagLib::Tag()
{
  d = new TagPrivate;
  d->file = file;
  d->footerLocation = footerLocation;

  read();
}

APE::Tag::~Tag()
{
  delete d;
}

ByteVector APE::Tag::fileIdentifier()
{
  return ByteVector::fromCString("APETAGEX");
}

String APE::Tag::title() const
{
  if(d->itemListMap["TITLE"].isEmpty())
    return String::null;
  return d->itemListMap["TITLE"].values().toString();
}

String APE::Tag::artist() const
{
  if(d->itemListMap["ARTIST"].isEmpty())
    return String::null;
  return d->itemListMap["ARTIST"].values().toString();
}

String APE::Tag::album() const
{
  if(d->itemListMap["ALBUM"].isEmpty())
    return String::null;
  return d->itemListMap["ALBUM"].values().toString();
}

String APE::Tag::comment() const
{
  if(d->itemListMap["COMMENT"].isEmpty())
    return String::null;
  return d->itemListMap["COMMENT"].values().toString();
}

String APE::Tag::genre() const
{
  if(d->itemListMap["GENRE"].isEmpty())
    return String::null;
  return d->itemListMap["GENRE"].values().toString();
}

TagLib::uint APE::Tag::year() const
{
  if(d->itemListMap["YEAR"].isEmpty())
    return 0;
  return d->itemListMap["YEAR"].toString().toInt();
}

TagLib::uint APE::Tag::track() const
{
  if(d->itemListMap["TRACK"].isEmpty())
    return 0;
  return d->itemListMap["TRACK"].toString().toInt();
}

void APE::Tag::setTitle(const String &s)
{
  addValue("TITLE", s, true);
}

void APE::Tag::setArtist(const String &s)
{
  addValue("ARTIST", s, true);
}

void APE::Tag::setAlbum(const String &s)
{
  addValue("ALBUM", s, true);
}

void APE::Tag::setComment(const String &s)
{
  addValue("COMMENT", s, true);
}

void APE::Tag::setGenre(const String &s)
{
  addValue("GENRE", s, true);
}

void APE::Tag::setYear(uint i)
{
  if(i <= 0)
    removeItem("YEAR");
  else
    addValue("YEAR", String::number(i), true);
}

void APE::Tag::setTrack(uint i)
{
  if(i <= 0)
    removeItem("TRACK");
  else
    addValue("TRACK", String::number(i), true);
}

// conversions of tag keys between what we use in PropertyMap and what's usual
// for APE tags
static const TagLib::uint keyConversionsSize = 5; //usual,         APE
static const char *keyConversions[][2] =  {{"TRACKNUMBER", "TRACK"       },
                                           {"DATE",        "YEAR"        },
                                           {"ALBUMARTIST", "ALBUM ARTIST"},
                                           {"DISCNUMBER",  "DISC"        },
                                           {"REMIXER",     "MIXARTIST"   }};

PropertyMap APE::Tag::properties() const
{
  PropertyMap properties;
  ItemListMap::ConstIterator it = itemListMap().begin();
  for(; it != itemListMap().end(); ++it) {
    String tagName = it->first.upper();
    // if the item is Binary or Locator, or if the key is an invalid string,
    // add to unsupportedData
    if(it->second.type() != Item::Text || tagName.isNull())
      properties.unsupportedData().append(it->first);
    else {
      // Some tags need to be handled specially
      for(uint i = 0; i < keyConversionsSize; ++i)
        if(tagName == keyConversions[i][1])
          tagName = keyConversions[i][0];
        properties[tagName].append(it->second.toStringList());
    }
  }
  return properties;
}

void APE::Tag::removeUnsupportedProperties(const StringList &properties)
{
  StringList::ConstIterator it = properties.begin();
  for(; it != properties.end(); ++it)
    removeItem(*it);
}

PropertyMap APE::Tag::setProperties(const PropertyMap &origProps)
{
  PropertyMap properties(origProps); // make a local copy that can be modified

  // see comment in properties()
  for(uint i = 0; i < keyConversionsSize; ++i)
    if(properties.contains(keyConversions[i][0])) {
      properties.insert(keyConversions[i][1], properties[keyConversions[i][0]]);
      properties.erase(keyConversions[i][0]);
    }

  // first check if tags need to be removed completely
  StringList toRemove;
  ItemListMap::ConstIterator remIt = itemListMap().begin();
  for(; remIt != itemListMap().end(); ++remIt) {
    String key = remIt->first.upper();
    // only remove if a) key is valid, b) type is text, c) key not contained in new properties
    if(!key.isNull() && remIt->second.type() == APE::Item::Text && !properties.contains(key))
      toRemove.append(remIt->first);
  }

  for(StringList::ConstIterator removeIt = toRemove.begin(); removeIt != toRemove.end(); removeIt++)
    removeItem(*removeIt);

  // now sync in the "forward direction"
  PropertyMap::ConstIterator it = properties.begin();
  PropertyMap invalid;
  for(; it != properties.end(); ++it) {
    const String &tagName = it->first;
    if(!checkKey(tagName))
      invalid.insert(it->first, it->second);
    else if(!(itemListMap().contains(tagName)) || !(itemListMap()[tagName].values() == it->second)) {
      if(it->second.size() == 0)
        removeItem(tagName);
      else {
        StringList::ConstIterator valueIt = it->second.begin();
        addValue(tagName, *valueIt, true);
        ++valueIt;
        for(; valueIt != it->second.end(); ++valueIt)
          addValue(tagName, *valueIt, false);
      }
    }
  }
  return invalid;
}

bool APE::Tag::checkKey(const String &key)
{
  if(key.size() < 2 || key.size() > 16)
      return false;
    for(String::ConstIterator it = key.begin(); it != key.end(); it++)
        // only allow printable ASCII including space (32..127)
        if (*it < 32 || *it >= 128)
          return false;
    String upperKey = key.upper();
    if (upperKey=="ID3" || upperKey=="TAG" || upperKey=="OGGS" || upperKey=="MP+")
      return false;
    return true;
}

APE::Footer *APE::Tag::footer() const
{
  return &d->footer;
}

const APE::ItemListMap& APE::Tag::itemListMap() const
{
  return d->itemListMap;
}

void APE::Tag::removeItem(const String &key)
{
  Map<const String, Item>::Iterator it = d->itemListMap.find(key.upper());
  if(it != d->itemListMap.end())
    d->itemListMap.erase(it);
}

void APE::Tag::addValue(const String &key, const String &value, bool replace)
{
  if(replace)
    removeItem(key);
  if(!key.isEmpty() && !value.isEmpty()) {
    if(!replace && d->itemListMap.contains(key)) {
      // Text items may contain more than one value
      if(APE::Item::Text == d->itemListMap.begin()->second.type())
        d->itemListMap[key.upper()].appendValue(value);
      // Binary or locator items may have only one value
      else
        setItem(key, Item(key, value));
    }
    else
      setItem(key, Item(key, value));
  }
}

void APE::Tag::setData(const String &key, const ByteVector &value)
{
  removeItem(key);
  if(!key.isEmpty() && !value.isEmpty())
    setItem(key, Item(key, value, true));
}

void APE::Tag::setItem(const String &key, const Item &item)
{
  if(!key.isEmpty())
    d->itemListMap.insert(key.upper(), item);
}

bool APE::Tag::isEmpty() const
{
  return d->itemListMap.isEmpty();
}

////////////////////////////////////////////////////////////////////////////////
// protected methods
////////////////////////////////////////////////////////////////////////////////

void APE::Tag::read()
{
  if(d->file && d->file->isValid()) {

    d->file->seek(d->footerLocation);
    d->footer.setData(d->file->readBlock(Footer::size()));

    if(d->footer.tagSize() <= Footer::size() ||
       d->footer.tagSize() > uint(d->file->length()))
      return;

    d->file->seek(d->footerLocation + Footer::size() - d->footer.tagSize());
    parse(d->file->readBlock(d->footer.tagSize() - Footer::size()));
  }
}

ByteVector APE::Tag::render() const
{
  ByteVector data;
  uint itemCount = 0;

  {
    for(Map<const String, Item>::ConstIterator it = d->itemListMap.begin();
        it != d->itemListMap.end(); ++it)
    {
      data.append(it->second.render());
      itemCount++;
    }
  }

  d->footer.setItemCount(itemCount);
  d->footer.setTagSize(data.size() + Footer::size());
  d->footer.setHeaderPresent(true);

  return d->footer.renderHeader() + data + d->footer.renderFooter();
}

void APE::Tag::parse(const ByteVector &data)
{
  uint pos = 0;

  // 11 bytes is the minimum size for an APE item

  for(uint i = 0; i < d->footer.itemCount() && pos <= data.size() - 11; i++) {
    APE::Item item;
    item.parse(data.mid(pos));

    d->itemListMap.insert(item.key().upper(), item);

    pos += item.size();
  }
}
<commit_msg>Fix an excessive loop when parsing an APE file.<commit_after>/***************************************************************************
    copyright            : (C) 2004 by Allan Sandfeld Jensen
    email                : kde@carewolf.com
 ***************************************************************************/

/***************************************************************************
 *   This library is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU Lesser General Public License version   *
 *   2.1 as published by the Free Software Foundation.                     *
 *                                                                         *
 *   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 Street, Fifth Floor, Boston, MA         *
 *   02110-1301  USA                                                       *
 *                                                                         *
 *   Alternatively, this file is available under the Mozilla Public        *
 *   License Version 1.1.  You may obtain a copy of the License at         *
 *   http://www.mozilla.org/MPL/                                           *
 ***************************************************************************/

#ifdef __SUNPRO_CC
// Sun Studio finds multiple specializations of Map because
// it considers specializations with and without class types
// to be different; this define forces Map to use only the
// specialization with the class keyword.
#define WANT_CLASS_INSTANTIATION_OF_MAP (1)
#endif

#include <tfile.h>
#include <tstring.h>
#include <tmap.h>
#include <tpropertymap.h>

#include "apetag.h"
#include "apefooter.h"
#include "apeitem.h"

using namespace TagLib;
using namespace APE;

class APE::Tag::TagPrivate
{
public:
  TagPrivate() : file(0), footerLocation(-1), tagLength(0) {}

  TagLib::File *file;
  long footerLocation;
  long tagLength;

  Footer footer;

  ItemListMap itemListMap;
};

////////////////////////////////////////////////////////////////////////////////
// public methods
////////////////////////////////////////////////////////////////////////////////

APE::Tag::Tag() : TagLib::Tag()
{
  d = new TagPrivate;
}

APE::Tag::Tag(TagLib::File *file, long footerLocation) : TagLib::Tag()
{
  d = new TagPrivate;
  d->file = file;
  d->footerLocation = footerLocation;

  read();
}

APE::Tag::~Tag()
{
  delete d;
}

ByteVector APE::Tag::fileIdentifier()
{
  return ByteVector::fromCString("APETAGEX");
}

String APE::Tag::title() const
{
  if(d->itemListMap["TITLE"].isEmpty())
    return String::null;
  return d->itemListMap["TITLE"].values().toString();
}

String APE::Tag::artist() const
{
  if(d->itemListMap["ARTIST"].isEmpty())
    return String::null;
  return d->itemListMap["ARTIST"].values().toString();
}

String APE::Tag::album() const
{
  if(d->itemListMap["ALBUM"].isEmpty())
    return String::null;
  return d->itemListMap["ALBUM"].values().toString();
}

String APE::Tag::comment() const
{
  if(d->itemListMap["COMMENT"].isEmpty())
    return String::null;
  return d->itemListMap["COMMENT"].values().toString();
}

String APE::Tag::genre() const
{
  if(d->itemListMap["GENRE"].isEmpty())
    return String::null;
  return d->itemListMap["GENRE"].values().toString();
}

TagLib::uint APE::Tag::year() const
{
  if(d->itemListMap["YEAR"].isEmpty())
    return 0;
  return d->itemListMap["YEAR"].toString().toInt();
}

TagLib::uint APE::Tag::track() const
{
  if(d->itemListMap["TRACK"].isEmpty())
    return 0;
  return d->itemListMap["TRACK"].toString().toInt();
}

void APE::Tag::setTitle(const String &s)
{
  addValue("TITLE", s, true);
}

void APE::Tag::setArtist(const String &s)
{
  addValue("ARTIST", s, true);
}

void APE::Tag::setAlbum(const String &s)
{
  addValue("ALBUM", s, true);
}

void APE::Tag::setComment(const String &s)
{
  addValue("COMMENT", s, true);
}

void APE::Tag::setGenre(const String &s)
{
  addValue("GENRE", s, true);
}

void APE::Tag::setYear(uint i)
{
  if(i <= 0)
    removeItem("YEAR");
  else
    addValue("YEAR", String::number(i), true);
}

void APE::Tag::setTrack(uint i)
{
  if(i <= 0)
    removeItem("TRACK");
  else
    addValue("TRACK", String::number(i), true);
}

// conversions of tag keys between what we use in PropertyMap and what's usual
// for APE tags
static const TagLib::uint keyConversionsSize = 5; //usual,         APE
static const char *keyConversions[][2] =  {{"TRACKNUMBER", "TRACK"       },
                                           {"DATE",        "YEAR"        },
                                           {"ALBUMARTIST", "ALBUM ARTIST"},
                                           {"DISCNUMBER",  "DISC"        },
                                           {"REMIXER",     "MIXARTIST"   }};

PropertyMap APE::Tag::properties() const
{
  PropertyMap properties;
  ItemListMap::ConstIterator it = itemListMap().begin();
  for(; it != itemListMap().end(); ++it) {
    String tagName = it->first.upper();
    // if the item is Binary or Locator, or if the key is an invalid string,
    // add to unsupportedData
    if(it->second.type() != Item::Text || tagName.isNull())
      properties.unsupportedData().append(it->first);
    else {
      // Some tags need to be handled specially
      for(uint i = 0; i < keyConversionsSize; ++i)
        if(tagName == keyConversions[i][1])
          tagName = keyConversions[i][0];
        properties[tagName].append(it->second.toStringList());
    }
  }
  return properties;
}

void APE::Tag::removeUnsupportedProperties(const StringList &properties)
{
  StringList::ConstIterator it = properties.begin();
  for(; it != properties.end(); ++it)
    removeItem(*it);
}

PropertyMap APE::Tag::setProperties(const PropertyMap &origProps)
{
  PropertyMap properties(origProps); // make a local copy that can be modified

  // see comment in properties()
  for(uint i = 0; i < keyConversionsSize; ++i)
    if(properties.contains(keyConversions[i][0])) {
      properties.insert(keyConversions[i][1], properties[keyConversions[i][0]]);
      properties.erase(keyConversions[i][0]);
    }

  // first check if tags need to be removed completely
  StringList toRemove;
  ItemListMap::ConstIterator remIt = itemListMap().begin();
  for(; remIt != itemListMap().end(); ++remIt) {
    String key = remIt->first.upper();
    // only remove if a) key is valid, b) type is text, c) key not contained in new properties
    if(!key.isNull() && remIt->second.type() == APE::Item::Text && !properties.contains(key))
      toRemove.append(remIt->first);
  }

  for(StringList::ConstIterator removeIt = toRemove.begin(); removeIt != toRemove.end(); removeIt++)
    removeItem(*removeIt);

  // now sync in the "forward direction"
  PropertyMap::ConstIterator it = properties.begin();
  PropertyMap invalid;
  for(; it != properties.end(); ++it) {
    const String &tagName = it->first;
    if(!checkKey(tagName))
      invalid.insert(it->first, it->second);
    else if(!(itemListMap().contains(tagName)) || !(itemListMap()[tagName].values() == it->second)) {
      if(it->second.size() == 0)
        removeItem(tagName);
      else {
        StringList::ConstIterator valueIt = it->second.begin();
        addValue(tagName, *valueIt, true);
        ++valueIt;
        for(; valueIt != it->second.end(); ++valueIt)
          addValue(tagName, *valueIt, false);
      }
    }
  }
  return invalid;
}

bool APE::Tag::checkKey(const String &key)
{
  if(key.size() < 2 || key.size() > 16)
      return false;
    for(String::ConstIterator it = key.begin(); it != key.end(); it++)
        // only allow printable ASCII including space (32..127)
        if (*it < 32 || *it >= 128)
          return false;
    String upperKey = key.upper();
    if (upperKey=="ID3" || upperKey=="TAG" || upperKey=="OGGS" || upperKey=="MP+")
      return false;
    return true;
}

APE::Footer *APE::Tag::footer() const
{
  return &d->footer;
}

const APE::ItemListMap& APE::Tag::itemListMap() const
{
  return d->itemListMap;
}

void APE::Tag::removeItem(const String &key)
{
  Map<const String, Item>::Iterator it = d->itemListMap.find(key.upper());
  if(it != d->itemListMap.end())
    d->itemListMap.erase(it);
}

void APE::Tag::addValue(const String &key, const String &value, bool replace)
{
  if(replace)
    removeItem(key);
  if(!key.isEmpty() && !value.isEmpty()) {
    if(!replace && d->itemListMap.contains(key)) {
      // Text items may contain more than one value
      if(APE::Item::Text == d->itemListMap.begin()->second.type())
        d->itemListMap[key.upper()].appendValue(value);
      // Binary or locator items may have only one value
      else
        setItem(key, Item(key, value));
    }
    else
      setItem(key, Item(key, value));
  }
}

void APE::Tag::setData(const String &key, const ByteVector &value)
{
  removeItem(key);
  if(!key.isEmpty() && !value.isEmpty())
    setItem(key, Item(key, value, true));
}

void APE::Tag::setItem(const String &key, const Item &item)
{
  if(!key.isEmpty())
    d->itemListMap.insert(key.upper(), item);
}

bool APE::Tag::isEmpty() const
{
  return d->itemListMap.isEmpty();
}

////////////////////////////////////////////////////////////////////////////////
// protected methods
////////////////////////////////////////////////////////////////////////////////

void APE::Tag::read()
{
  if(d->file && d->file->isValid()) {

    d->file->seek(d->footerLocation);
    d->footer.setData(d->file->readBlock(Footer::size()));

    if(d->footer.tagSize() <= Footer::size() ||
       d->footer.tagSize() > uint(d->file->length()))
      return;

    d->file->seek(d->footerLocation + Footer::size() - d->footer.tagSize());
    parse(d->file->readBlock(d->footer.tagSize() - Footer::size()));
  }
}

ByteVector APE::Tag::render() const
{
  ByteVector data;
  uint itemCount = 0;

  {
    for(Map<const String, Item>::ConstIterator it = d->itemListMap.begin();
        it != d->itemListMap.end(); ++it)
    {
      data.append(it->second.render());
      itemCount++;
    }
  }

  d->footer.setItemCount(itemCount);
  d->footer.setTagSize(data.size() + Footer::size());
  d->footer.setHeaderPresent(true);

  return d->footer.renderHeader() + data + d->footer.renderFooter();
}

void APE::Tag::parse(const ByteVector &data)
{
  // 11 bytes is the minimum size for an APE item

  if(data.size() < 11)
    return;

  uint pos = 0;

  for(uint i = 0; i < d->footer.itemCount() && pos <= data.size() - 11; i++) {
    APE::Item item;
    item.parse(data.mid(pos));

    d->itemListMap.insert(item.key().upper(), item);

    pos += item.size();
  }
}
<|endoftext|>


<commit_before>#include "AnimusKeyboard.h"

#define HID_CUSTOM_LAYOUT
#define LAYOUT_HID_SCANCODE
#include "HID.h"
#include "HID-Project.h"
// this is for the modified arduino HID
IKeyboard::IKeyboard(void)
{
  //nothing
}

void IKeyboard::Begin(void)
{
  BootKeyboard.begin();
  NKROKeyboard.begin();
}
void IKeyboard::End(void)
{
  BootKeyboard.end();
  NKROKeyboard.end();
}
void IKeyboard::Press(byte k)
{
  if (Global.NKROMode == 0)
  {
    BootKeyboard.press(k);
  }
  else
  {
    NKROKeyboard.press(k);
  }
  KeyState[k] = true;
}
void IKeyboard::Release(byte k)
{
  if (Global.NKROMode == 0)
  {
    BootKeyboard.release(k);
  }
  else
  {
    NKROKeyboard.release(k);
  }
  KeyState[k] = true;

}
void IKeyboard::Write(byte k)
{
  if (Global.NKROMode == 0)
  {
    BootKeyboard.press(k);
    BootKeyboard.release(k);
  }
  else
  {
    NKROKeyboard.press(k);
    NKROKeyboard.release(k);
  }
}
void IKeyboard::ReleaseAll(void)
{
  BootKeyboard.releaseAll();
  NKROKeyboard.releaseAll();
  for (short i = 0; i < 256; i++)
  {
    KeyState[i] = false;
  }
}

IKeyboard AnimusKeyboard;
<commit_msg>change: used better way to send scancodes<commit_after>#include "AnimusKeyboard.h"

#include "HID-Project.h"
// this is for the modified arduino HID
IKeyboard::IKeyboard(void)
{
  //nothing
}

void IKeyboard::Begin(void)
{
  BootKeyboard.begin();
  NKROKeyboard.begin();
}
void IKeyboard::End(void)
{
  BootKeyboard.end();
  NKROKeyboard.end();
}
void IKeyboard::Press(byte k)
{
  if (Global.NKROMode == 0)
  {
    BootKeyboard.press((KeyboardKeycode)k);
  }
  else
  {
    NKROKeyboard.press((KeyboardKeycode)k);
  }
  KeyState[k] = true;
}
void IKeyboard::Release(byte k)
{
  if (Global.NKROMode == 0)
  {
    BootKeyboard.release((KeyboardKeycode)k);
  }
  else
  {
    NKROKeyboard.release((KeyboardKeycode)k);
  }
  KeyState[k] = true;

}
void IKeyboard::Write(byte k)
{
  if (Global.NKROMode == 0)
  {
    BootKeyboard.press((KeyboardKeycode)k);
    BootKeyboard.release((KeyboardKeycode)k);
  }
  else
  {
    NKROKeyboard.press((KeyboardKeycode)k);
    NKROKeyboard.release((KeyboardKeycode)k);
  }
}
void IKeyboard::ReleaseAll(void)
{
  BootKeyboard.releaseAll();
  NKROKeyboard.releaseAll();
  for (short i = 0; i < 256; i++)
  {
    KeyState[i] = false;
  }
}

IKeyboard AnimusKeyboard;
<|endoftext|>


<commit_before><commit_msg>add aes ecb<commit_after><|endoftext|>


<commit_before>// The MIT License (MIT)

// Copyright (c) 2015 Skorezore

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

#include "settings.hpp"
#include "cpponfig/configuration.hpp"

using namespace std;
using namespace std::chrono;
using namespace cpponfiguration;

const gaem_settings & settings() {
	static configuration cfg("assets/gaem.cfg");
	static gaem_settings setts = [&]() {
		gaem_settings tmp;
		cfg.load();

		cfg.sof_comments = {"This is Gaem's configuration file.", "Modify those values at will, but", "if you break anything, it's your fault."};
		tmp.graphics.between_frames = milliseconds(cfg.get("graphics:time_between_frames", property("75", "In milliseconds")).integer());

		return tmp;
	}();
	static struct save_on_exit_t {
		~save_on_exit_t() {
			cfg.save();
		}
	} save_on_exit;

	return setts;
}
<commit_msg>Update Cpponfiguration. Remove explicit (and now superfluous) save-on-destruction for configuration<commit_after>// The MIT License (MIT)

// Copyright (c) 2015 Skorezore

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

#include "settings.hpp"
#include "cpponfig/configuration.hpp"

using namespace std;
using namespace std::chrono;
using namespace cpponfiguration;

const gaem_settings & settings() {
	static configuration cfg("assets/gaem.cfg");
	static gaem_settings setts = [&]() {
		gaem_settings tmp;
		cfg.load();

		cfg.sof_comments = {"This is Gaem's configuration file.", "Modify those values at will, but", "if you break anything, it's your fault."};
		tmp.graphics.between_frames = milliseconds(cfg.get("graphics:time_between_frames", property("75", "In milliseconds")).integer());

		return tmp;
	}();

	return setts;
}
<|endoftext|>


<commit_before>/*
-----------------------------------------------------------------------------
This source file is part of OGRE
    (Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org/

Copyright (c) 2000-2013 Torus Knot Software Ltd

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-----------------------------------------------------------------------------
*/
#include "OgreStableHeaders.h"
#include "OgreTextureManager.h"
#include "OgreException.h"
#include "OgrePixelFormat.h"
#include "OgreRoot.h"
#include "OgreRenderSystem.h"

namespace Ogre {
    //-----------------------------------------------------------------------
    template<> TextureManager* Singleton<TextureManager>::msSingleton = 0;
    TextureManager* TextureManager::getSingletonPtr(void)
    {
        return msSingleton;
    }
    TextureManager& TextureManager::getSingleton(void)
    {
        assert( msSingleton );  return ( *msSingleton );
    }
    //-----------------------------------------------------------------------
    TextureManager::TextureManager(void)
         : mPreferredIntegerBitDepth(0)
         , mPreferredFloatBitDepth(0)
         , mDefaultNumMipmaps(MIP_UNLIMITED)
    {
        mResourceType = "Texture";
        mLoadOrder = 75.0f;

        // Subclasses should register (when this is fully constructed)
    }
    //-----------------------------------------------------------------------
    TextureManager::~TextureManager()
    {
        // subclasses should unregister with resource group manager

    }
    //-----------------------------------------------------------------------
    TextureManager::ResourceCreateOrRetrieveResult TextureManager::createOrRetrieve(
            const String &name, const String& group, bool isManual, ManualResourceLoader* loader,
            const NameValuePairList* createParams, TextureType texType, int numMipmaps, Real gamma,
            bool isAlpha, PixelFormat desiredFormat, bool hwGamma)
    {
		ResourceCreateOrRetrieveResult res =
            Ogre::ResourceManager::createOrRetrieve(name, group, isManual, loader, createParams);
		// Was it created?
		if(res.second)
        {
            TexturePtr tex = res.first;
            tex->setTextureType(texType);
            tex->setNumMipmaps((numMipmaps == MIP_DEFAULT)? mDefaultNumMipmaps :
				static_cast<size_t>(numMipmaps));
            tex->setGamma(gamma);
            tex->setTreatLuminanceAsAlpha(isAlpha);
            tex->setFormat(desiredFormat);
			tex->setHardwareGammaEnabled(hwGamma);
        }
        return res;
    }
    //-----------------------------------------------------------------------
    TexturePtr TextureManager::prepare(const String &name, const String& group, TextureType texType,
                                       int numMipmaps, Real gamma, bool isAlpha,
                                       PixelFormat desiredFormat, bool hwGamma)
    {
		ResourceCreateOrRetrieveResult res =
            createOrRetrieve(name,group,false,0,0,texType,numMipmaps,gamma,isAlpha,desiredFormat,hwGamma);
        TexturePtr tex = res.first;
		tex->prepare();
        return tex;
    }
    //-----------------------------------------------------------------------
    TexturePtr TextureManager::load(const String &name, const String& group, TextureType texType,
                                    int numMipmaps, Real gamma, bool isAlpha, PixelFormat desiredFormat,
                                    bool hwGamma)
    {
		ResourceCreateOrRetrieveResult res =
            createOrRetrieve(name,group,false,0,0,texType,numMipmaps,gamma,isAlpha,desiredFormat,hwGamma);
        TexturePtr tex = res.first;
		tex->load();
        return tex;
    }

    //-----------------------------------------------------------------------
    TexturePtr TextureManager::loadImage( const String &name, const String& group,
        const Image &img, TextureType texType, int numMipmaps, Real gamma, bool isAlpha,
		PixelFormat desiredFormat, bool hwGamma)
    {
        TexturePtr tex = create(name, group, true);

        tex->setTextureType(texType);
        tex->setNumMipmaps((numMipmaps == MIP_DEFAULT)? mDefaultNumMipmaps :
			static_cast<size_t>(numMipmaps));
        tex->setGamma(gamma);
        tex->setTreatLuminanceAsAlpha(isAlpha);
        tex->setFormat(desiredFormat);
		tex->setHardwareGammaEnabled(hwGamma);
        tex->loadImage(img);

        return tex;
    }
    //-----------------------------------------------------------------------
    TexturePtr TextureManager::loadRawData(const String &name, const String& group,
        DataStreamPtr& stream, ushort uWidth, ushort uHeight,
        PixelFormat format, TextureType texType,
        int numMipmaps, Real gamma, bool hwGamma)
	{
        TexturePtr tex = create(name, group, true);

        tex->setTextureType(texType);
        tex->setNumMipmaps((numMipmaps == MIP_DEFAULT)? mDefaultNumMipmaps :
			static_cast<size_t>(numMipmaps));
        tex->setGamma(gamma);
		tex->setHardwareGammaEnabled(hwGamma);
		tex->loadRawData(stream, uWidth, uHeight, format);

        return tex;
	}
    //-----------------------------------------------------------------------
    TexturePtr TextureManager::createManual(const String & name, const String& group,
        TextureType texType, uint width, uint height, uint depth, int numMipmaps,
        PixelFormat format, int usage, ManualResourceLoader* loader, bool hwGamma,
		uint fsaa, const String& fsaaHint)
    {
        if (((usage & (int)TU_STATIC) != 0) && (!Root::getSingleton().getRenderSystem()->isStaticBufferLockable()))
        {
            usage = (usage & ~(int)TU_STATIC) | (int)TU_DYNAMIC;
        }
        TexturePtr ret = create(name, group, true, loader);
        ret->setTextureType(texType);
        ret->setWidth(width);
        ret->setHeight(height);
		ret->setDepth(depth);
        ret->setNumMipmaps((numMipmaps == MIP_DEFAULT)? mDefaultNumMipmaps :
			static_cast<size_t>(numMipmaps));
        ret->setFormat(format);
        ret->setUsage(usage);
		ret->setHardwareGammaEnabled(hwGamma);
		ret->setFSAA(fsaa, fsaaHint);
		ret->createInternalResources();
		return ret;
    }
    //-----------------------------------------------------------------------
    void TextureManager::setPreferredIntegerBitDepth(ushort bits, bool reloadTextures)
    {
        mPreferredIntegerBitDepth = bits;

        if (reloadTextures)
        {
            // Iterate through all textures
            for (ResourceMap::iterator it = mResources.begin(); it != mResources.end(); ++it)
            {
                Texture* texture = static_cast<Texture*>(it->second.get());
                // Reload loaded and reloadable texture only
                if (texture->isLoaded() && texture->isReloadable())
                {
                    texture->unload();
                    texture->setDesiredIntegerBitDepth(bits);
                    texture->load();
                }
                else
                {
                    texture->setDesiredIntegerBitDepth(bits);
                }
            }
        }
    }
    //-----------------------------------------------------------------------
    ushort TextureManager::getPreferredIntegerBitDepth(void) const
    {
        return mPreferredIntegerBitDepth;
    }
    //-----------------------------------------------------------------------
    void TextureManager::setPreferredFloatBitDepth(ushort bits, bool reloadTextures)
    {
        mPreferredFloatBitDepth = bits;

        if (reloadTextures)
        {
            // Iterate through all textures
            for (ResourceMap::iterator it = mResources.begin(); it != mResources.end(); ++it)
            {
                Texture* texture = static_cast<Texture*>(it->second.get());
                // Reload loaded and reloadable texture only
                if (texture->isLoaded() && texture->isReloadable())
                {
                    texture->unload();
                    texture->setDesiredFloatBitDepth(bits);
                    texture->load();
                }
                else
                {
                    texture->setDesiredFloatBitDepth(bits);
                }
            }
        }
    }
    //-----------------------------------------------------------------------
    ushort TextureManager::getPreferredFloatBitDepth(void) const
    {
        return mPreferredFloatBitDepth;
    }
    //-----------------------------------------------------------------------
    void TextureManager::setPreferredBitDepths(ushort integerBits, ushort floatBits, bool reloadTextures)
    {
        mPreferredIntegerBitDepth = integerBits;
        mPreferredFloatBitDepth = floatBits;

        if (reloadTextures)
        {
            // Iterate through all textures
            for (ResourceMap::iterator it = mResources.begin(); it != mResources.end(); ++it)
            {
                Texture* texture = static_cast<Texture*>(it->second.get());
                // Reload loaded and reloadable texture only
                if (texture->isLoaded() && texture->isReloadable())
                {
                    texture->unload();
                    texture->setDesiredBitDepths(integerBits, floatBits);
                    texture->load();
                }
                else
                {
                    texture->setDesiredBitDepths(integerBits, floatBits);
                }
            }
        }
    }
    //-----------------------------------------------------------------------
    void TextureManager::setDefaultNumMipmaps( size_t num )
    {
        mDefaultNumMipmaps = num;
    }
    //-----------------------------------------------------------------------
	bool TextureManager::isFormatSupported(TextureType ttype, PixelFormat format, int usage)
	{
		return getNativeFormat(ttype, format, usage) == format;
	}
    //-----------------------------------------------------------------------
	bool TextureManager::isEquivalentFormatSupported(TextureType ttype, PixelFormat format, int usage)
	{
		PixelFormat supportedFormat = getNativeFormat(ttype, format, usage);

		// Assume that same or greater number of bits means quality not degraded
		return PixelUtil::getNumElemBits(supportedFormat) >= PixelUtil::getNumElemBits(format);

	}
}
<commit_msg>Perform a check for 3D texture support on texture creation. Return a null TexturePtr if unsupported.<commit_after>/*
-----------------------------------------------------------------------------
This source file is part of OGRE
    (Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org/

Copyright (c) 2000-2013 Torus Knot Software Ltd

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-----------------------------------------------------------------------------
*/
#include "OgreStableHeaders.h"
#include "OgreTextureManager.h"
#include "OgreException.h"
#include "OgrePixelFormat.h"
#include "OgreRoot.h"
#include "OgreRenderSystem.h"

namespace Ogre {
    //-----------------------------------------------------------------------
    template<> TextureManager* Singleton<TextureManager>::msSingleton = 0;
    TextureManager* TextureManager::getSingletonPtr(void)
    {
        return msSingleton;
    }
    TextureManager& TextureManager::getSingleton(void)
    {
        assert( msSingleton );  return ( *msSingleton );
    }
    //-----------------------------------------------------------------------
    TextureManager::TextureManager(void)
         : mPreferredIntegerBitDepth(0)
         , mPreferredFloatBitDepth(0)
         , mDefaultNumMipmaps(MIP_UNLIMITED)
    {
        mResourceType = "Texture";
        mLoadOrder = 75.0f;

        // Subclasses should register (when this is fully constructed)
    }
    //-----------------------------------------------------------------------
    TextureManager::~TextureManager()
    {
        // subclasses should unregister with resource group manager

    }
    //-----------------------------------------------------------------------
    TextureManager::ResourceCreateOrRetrieveResult TextureManager::createOrRetrieve(
            const String &name, const String& group, bool isManual, ManualResourceLoader* loader,
            const NameValuePairList* createParams, TextureType texType, int numMipmaps, Real gamma,
            bool isAlpha, PixelFormat desiredFormat, bool hwGamma)
    {
		ResourceCreateOrRetrieveResult res =
            Ogre::ResourceManager::createOrRetrieve(name, group, isManual, loader, createParams);
		// Was it created?
		if(res.second)
        {
            TexturePtr tex = res.first;
            tex->setTextureType(texType);
            tex->setNumMipmaps((numMipmaps == MIP_DEFAULT)? mDefaultNumMipmaps :
				static_cast<size_t>(numMipmaps));
            tex->setGamma(gamma);
            tex->setTreatLuminanceAsAlpha(isAlpha);
            tex->setFormat(desiredFormat);
			tex->setHardwareGammaEnabled(hwGamma);
        }
        return res;
    }
    //-----------------------------------------------------------------------
    TexturePtr TextureManager::prepare(const String &name, const String& group, TextureType texType,
                                       int numMipmaps, Real gamma, bool isAlpha,
                                       PixelFormat desiredFormat, bool hwGamma)
    {
		ResourceCreateOrRetrieveResult res =
            createOrRetrieve(name,group,false,0,0,texType,numMipmaps,gamma,isAlpha,desiredFormat,hwGamma);
        TexturePtr tex = res.first;
		tex->prepare();
        return tex;
    }
    //-----------------------------------------------------------------------
    TexturePtr TextureManager::load(const String &name, const String& group, TextureType texType,
                                    int numMipmaps, Real gamma, bool isAlpha, PixelFormat desiredFormat,
                                    bool hwGamma)
    {
		ResourceCreateOrRetrieveResult res =
            createOrRetrieve(name,group,false,0,0,texType,numMipmaps,gamma,isAlpha,desiredFormat,hwGamma);
        TexturePtr tex = res.first;
		tex->load();
        return tex;
    }

    //-----------------------------------------------------------------------
    TexturePtr TextureManager::loadImage( const String &name, const String& group,
        const Image &img, TextureType texType, int numMipmaps, Real gamma, bool isAlpha,
		PixelFormat desiredFormat, bool hwGamma)
    {
        TexturePtr tex = create(name, group, true);

        tex->setTextureType(texType);
        tex->setNumMipmaps((numMipmaps == MIP_DEFAULT)? mDefaultNumMipmaps :
			static_cast<size_t>(numMipmaps));
        tex->setGamma(gamma);
        tex->setTreatLuminanceAsAlpha(isAlpha);
        tex->setFormat(desiredFormat);
		tex->setHardwareGammaEnabled(hwGamma);
        tex->loadImage(img);

        return tex;
    }
    //-----------------------------------------------------------------------
    TexturePtr TextureManager::loadRawData(const String &name, const String& group,
        DataStreamPtr& stream, ushort uWidth, ushort uHeight,
        PixelFormat format, TextureType texType,
        int numMipmaps, Real gamma, bool hwGamma)
	{
        TexturePtr tex = create(name, group, true);

        tex->setTextureType(texType);
        tex->setNumMipmaps((numMipmaps == MIP_DEFAULT)? mDefaultNumMipmaps :
			static_cast<size_t>(numMipmaps));
        tex->setGamma(gamma);
		tex->setHardwareGammaEnabled(hwGamma);
		tex->loadRawData(stream, uWidth, uHeight, format);

        return tex;
	}
    //-----------------------------------------------------------------------
    TexturePtr TextureManager::createManual(const String & name, const String& group,
        TextureType texType, uint width, uint height, uint depth, int numMipmaps,
        PixelFormat format, int usage, ManualResourceLoader* loader, bool hwGamma,
		uint fsaa, const String& fsaaHint)
    {
        TexturePtr ret;
        ret.setNull();

        // Check for 3D texture support
		const RenderSystemCapabilities* caps =
            Root::getSingleton().getRenderSystem()->getCapabilities();
        if (((texType == TEX_TYPE_3D) || (texType == TEX_TYPE_2D_ARRAY)) &&
            !caps->hasCapability(RSC_TEXTURE_3D))
            return ret;

        if (((usage & (int)TU_STATIC) != 0) && (!Root::getSingleton().getRenderSystem()->isStaticBufferLockable()))
        {
            usage = (usage & ~(int)TU_STATIC) | (int)TU_DYNAMIC;
        }
        ret = create(name, group, true, loader);
        ret->setTextureType(texType);
        ret->setWidth(width);
        ret->setHeight(height);
		ret->setDepth(depth);
        ret->setNumMipmaps((numMipmaps == MIP_DEFAULT)? mDefaultNumMipmaps :
			static_cast<size_t>(numMipmaps));
        ret->setFormat(format);
        ret->setUsage(usage);
		ret->setHardwareGammaEnabled(hwGamma);
		ret->setFSAA(fsaa, fsaaHint);
		ret->createInternalResources();
		return ret;
    }
    //-----------------------------------------------------------------------
    void TextureManager::setPreferredIntegerBitDepth(ushort bits, bool reloadTextures)
    {
        mPreferredIntegerBitDepth = bits;

        if (reloadTextures)
        {
            // Iterate through all textures
            for (ResourceMap::iterator it = mResources.begin(); it != mResources.end(); ++it)
            {
                Texture* texture = static_cast<Texture*>(it->second.get());
                // Reload loaded and reloadable texture only
                if (texture->isLoaded() && texture->isReloadable())
                {
                    texture->unload();
                    texture->setDesiredIntegerBitDepth(bits);
                    texture->load();
                }
                else
                {
                    texture->setDesiredIntegerBitDepth(bits);
                }
            }
        }
    }
    //-----------------------------------------------------------------------
    ushort TextureManager::getPreferredIntegerBitDepth(void) const
    {
        return mPreferredIntegerBitDepth;
    }
    //-----------------------------------------------------------------------
    void TextureManager::setPreferredFloatBitDepth(ushort bits, bool reloadTextures)
    {
        mPreferredFloatBitDepth = bits;

        if (reloadTextures)
        {
            // Iterate through all textures
            for (ResourceMap::iterator it = mResources.begin(); it != mResources.end(); ++it)
            {
                Texture* texture = static_cast<Texture*>(it->second.get());
                // Reload loaded and reloadable texture only
                if (texture->isLoaded() && texture->isReloadable())
                {
                    texture->unload();
                    texture->setDesiredFloatBitDepth(bits);
                    texture->load();
                }
                else
                {
                    texture->setDesiredFloatBitDepth(bits);
                }
            }
        }
    }
    //-----------------------------------------------------------------------
    ushort TextureManager::getPreferredFloatBitDepth(void) const
    {
        return mPreferredFloatBitDepth;
    }
    //-----------------------------------------------------------------------
    void TextureManager::setPreferredBitDepths(ushort integerBits, ushort floatBits, bool reloadTextures)
    {
        mPreferredIntegerBitDepth = integerBits;
        mPreferredFloatBitDepth = floatBits;

        if (reloadTextures)
        {
            // Iterate through all textures
            for (ResourceMap::iterator it = mResources.begin(); it != mResources.end(); ++it)
            {
                Texture* texture = static_cast<Texture*>(it->second.get());
                // Reload loaded and reloadable texture only
                if (texture->isLoaded() && texture->isReloadable())
                {
                    texture->unload();
                    texture->setDesiredBitDepths(integerBits, floatBits);
                    texture->load();
                }
                else
                {
                    texture->setDesiredBitDepths(integerBits, floatBits);
                }
            }
        }
    }
    //-----------------------------------------------------------------------
    void TextureManager::setDefaultNumMipmaps( size_t num )
    {
        mDefaultNumMipmaps = num;
    }
    //-----------------------------------------------------------------------
	bool TextureManager::isFormatSupported(TextureType ttype, PixelFormat format, int usage)
	{
		return getNativeFormat(ttype, format, usage) == format;
	}
    //-----------------------------------------------------------------------
	bool TextureManager::isEquivalentFormatSupported(TextureType ttype, PixelFormat format, int usage)
	{
		PixelFormat supportedFormat = getNativeFormat(ttype, format, usage);

		// Assume that same or greater number of bits means quality not degraded
		return PixelUtil::getNumElemBits(supportedFormat) >= PixelUtil::getNumElemBits(format);

	}
}
<|endoftext|>