Use istringstream for deserializing config options in order to use the correct locale. #2187

This commit is contained in:
Alessandro Ranellucci 2014-08-04 11:34:53 +02:00
parent b10917806a
commit d9f6b0933b
2 changed files with 30 additions and 36 deletions

View File

@ -58,8 +58,8 @@ class ConfigOptionFloat : public ConfigOption
}; };
bool deserialize(std::string str) { bool deserialize(std::string str) {
this->value = ::atof(str.c_str()); std::istringstream iss(str);
return true; return iss >> this->value;
}; };
}; };
@ -81,7 +81,10 @@ class ConfigOptionFloats : public ConfigOption, public ConfigOptionVector<double
std::istringstream is(str); std::istringstream is(str);
std::string item_str; std::string item_str;
while (std::getline(is, item_str, ',')) { while (std::getline(is, item_str, ',')) {
this->values.push_back(::atof(item_str.c_str())); std::istringstream iss(item_str);
double value;
iss >> value;
this->values.push_back(value);
} }
return true; return true;
}; };
@ -104,8 +107,8 @@ class ConfigOptionInt : public ConfigOption
}; };
bool deserialize(std::string str) { bool deserialize(std::string str) {
this->value = ::atoi(str.c_str()); std::istringstream iss(str);
return true; return iss >> this->value;
}; };
}; };
@ -127,7 +130,10 @@ class ConfigOptionInts : public ConfigOption, public ConfigOptionVector<int>
std::istringstream is(str); std::istringstream is(str);
std::string item_str; std::string item_str;
while (std::getline(is, item_str, ',')) { while (std::getline(is, item_str, ',')) {
this->values.push_back(::atoi(item_str.c_str())); std::istringstream iss(item_str);
int value;
iss >> value;
this->values.push_back(value);
} }
return true; return true;
}; };
@ -212,8 +218,8 @@ class ConfigOptionPercent : public ConfigOption
bool deserialize(std::string str) { bool deserialize(std::string str) {
// don't try to parse the trailing % since it's optional // don't try to parse the trailing % since it's optional
int res = sscanf(str.c_str(), "%lf", &this->value); std::istringstream iss(str);
return res == 1; return iss >> this->value;
}; };
}; };
@ -241,15 +247,9 @@ class ConfigOptionFloatOrPercent : public ConfigOption
}; };
bool deserialize(std::string str) { bool deserialize(std::string str) {
if (str.find_first_of("%") != std::string::npos) { this->percent = str.find_first_of("%") != std::string::npos;
int res = sscanf(str.c_str(), "%lf%%", &this->value); std::istringstream iss(str);
if (res == 0) return false; return iss >> this->value;
this->percent = true;
} else {
this->value = ::atof(str.c_str());
this->percent = false;
}
return true;
}; };
}; };
@ -270,14 +270,12 @@ class ConfigOptionPoint : public ConfigOption
}; };
bool deserialize(std::string str) { bool deserialize(std::string str) {
if (strncmp(str.c_str(), "0x", 2) == 0) { std::istringstream iss(str);
this->point.x = 0; iss >> this->point.x;
int res = sscanf(str.c_str()+2, "%lf", &this->point.y); iss.ignore(std::numeric_limits<std::streamsize>::max(), ',');
return res == 1; iss.ignore(std::numeric_limits<std::streamsize>::max(), 'x');
} else { iss >> this->point.y;
int res = sscanf(str.c_str(), "%lf%*1[,x]%lf", &this->point.x, &this->point.y); return true;
return res == 2;
}
}; };
}; };
@ -302,16 +300,10 @@ class ConfigOptionPoints : public ConfigOption, public ConfigOptionVector<Pointf
std::string point_str; std::string point_str;
while (std::getline(is, point_str, ',')) { while (std::getline(is, point_str, ',')) {
Pointf point; Pointf point;
if (strncmp(point_str.c_str(), "0x", 2) == 0) { std::istringstream iss(point_str);
// if string starts with "0x", only apply sscanf() to the second coordinate iss >> point.x;
// otherwise it would parse the string as a hex number iss.ignore(std::numeric_limits<std::streamsize>::max(), 'x');
point.x = 0; iss >> point.y;
int res = sscanf(point_str.c_str()+2, "%lf", &point.y);
if (res != 1) return false;
} else {
int res = sscanf(point_str.c_str(), "%lfx%lf", &point.x, &point.y);
if (res != 2) return false;
}
values.push_back(point); values.push_back(point);
} }
this->values = values; this->values = values;

View File

@ -4,7 +4,7 @@ use strict;
use warnings; use warnings;
use Slic3r::XS; use Slic3r::XS;
use Test::More tests => 103; use Test::More tests => 105;
foreach my $config (Slic3r::Config->new, Slic3r::Config::Full->new) { foreach my $config (Slic3r::Config->new, Slic3r::Config::Full->new) {
$config->set('layer_height', 0.3); $config->set('layer_height', 0.3);
@ -63,6 +63,8 @@ foreach my $config (Slic3r::Config->new, Slic3r::Config::Full->new) {
is $config->serialize('extruder_offset'), '10x20,30x45', 'serialize points'; is $config->serialize('extruder_offset'), '10x20,30x45', 'serialize points';
$config->set_deserialize('extruder_offset', '20x10'); $config->set_deserialize('extruder_offset', '20x10');
is_deeply $config->get('extruder_offset'), [[20,10]], 'deserialize points'; is_deeply $config->get('extruder_offset'), [[20,10]], 'deserialize points';
$config->set_deserialize('extruder_offset', '0x0');
is_deeply $config->get('extruder_offset'), [[0,0]], 'deserialize points';
{ {
my @values = ([10,20]); my @values = ([10,20]);
$values[2] = [10,20]; # implicitely extend array; this is not the same as explicitely assigning undef to second item $values[2] = [10,20]; # implicitely extend array; this is not the same as explicitely assigning undef to second item