mirror of
https://github.com/rwengine/openrw.git
synced 2024-11-22 10:22:52 +01:00
Merge pull request #547 from ShFil119/safe_convertion
Safer convertion strings to numbers
This commit is contained in:
commit
1586a90401
@ -13,6 +13,7 @@
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
|
||||
#include <data/Clump.hpp>
|
||||
#include <rw/casts.hpp>
|
||||
#include <rw/debug.hpp>
|
||||
#include <rw/types.hpp>
|
||||
|
||||
@ -105,7 +106,7 @@ void GameData::loadLevelFile(const std::string& path) {
|
||||
} else if (cmd == "SPLASH") {
|
||||
splash = line.substr(space + 1);
|
||||
} else if (cmd == "COLFILE") {
|
||||
int zone = atoi(line.substr(space + 1, 1).c_str());
|
||||
int zone = lexical_cast<int>(line.substr(space + 1, 1));
|
||||
auto path = line.substr(space + 3);
|
||||
loadCOL(zone, path);
|
||||
} else if (cmd == "IPL") {
|
||||
@ -252,7 +253,9 @@ void GameData::loadCarcols(const std::string& path) {
|
||||
if (std::getline(ss, r, ',') && std::getline(ss, g, ',') &&
|
||||
std::getline(ss, b)) {
|
||||
vehicleColours.emplace_back(
|
||||
atoi(r.c_str()), atoi(g.c_str()), atoi(b.c_str()));
|
||||
lexical_cast<int>(r),
|
||||
lexical_cast<int>(g),
|
||||
lexical_cast<int>(b));
|
||||
}
|
||||
} else if (currentSection == CAR) {
|
||||
std::string vehicle, p, s;
|
||||
@ -262,7 +265,8 @@ void GameData::loadCarcols(const std::string& path) {
|
||||
std::vector<std::pair<size_t, size_t>> colours;
|
||||
|
||||
while (std::getline(ss, p, ',') && std::getline(ss, s, ',')) {
|
||||
colours.emplace_back(atoi(p.c_str()), atoi(s.c_str()));
|
||||
colours.emplace_back(lexical_cast<int>(p),
|
||||
lexical_cast<int>(s));
|
||||
}
|
||||
|
||||
vehiclePalettes.insert({vehicle, colours});
|
||||
@ -336,11 +340,11 @@ void GameData::loadWater(const std::string& path) {
|
||||
std::getline(ss, e, ',')) {
|
||||
|
||||
waterBlocks.emplace_back(
|
||||
atof(a.c_str()),
|
||||
atof(b.c_str()),
|
||||
atof(c.c_str()),
|
||||
atof(d.c_str()),
|
||||
atof(e.c_str()));
|
||||
lexical_cast<float>(a),
|
||||
lexical_cast<float>(b),
|
||||
lexical_cast<float>(c),
|
||||
lexical_cast<float>(d),
|
||||
lexical_cast<float>(e));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -386,7 +390,7 @@ TextureArchive GameData::loadTextureArchive(const std::string& name) {
|
||||
void GameData::getNameAndLod(std::string& name, int& lod) {
|
||||
auto lodpos = name.rfind("_l");
|
||||
if (lodpos != std::string::npos) {
|
||||
lod = std::atoi(name.substr(lodpos + 2).c_str());
|
||||
lod = lexical_cast<int>(name.substr(lodpos + 2));
|
||||
name = name.substr(0, lodpos);
|
||||
}
|
||||
}
|
||||
@ -464,7 +468,7 @@ bool GameData::loadModel(ModelID model) {
|
||||
static const std::string specialPrefix("special");
|
||||
if (!name.compare(0, specialPrefix.size(), specialPrefix)) {
|
||||
auto sid = name.substr(specialPrefix.size());
|
||||
unsigned short specialID = std::atoi(sid.c_str());
|
||||
unsigned short specialID = lexical_cast<int>(sid);
|
||||
name = engine->state->specialCharacters[specialID];
|
||||
slotname = name;
|
||||
break;
|
||||
|
@ -11,6 +11,8 @@
|
||||
|
||||
#include "data/PathData.hpp"
|
||||
|
||||
#include <rw/casts.hpp>
|
||||
|
||||
bool LoaderIDE::load(const std::string &filename, const PedStatsList &stats) {
|
||||
std::ifstream str(filename);
|
||||
|
||||
@ -71,30 +73,30 @@ bool LoaderIDE::load(const std::string &filename, const PedStatsList &stats) {
|
||||
auto objs = std::make_unique<SimpleModelInfo>();
|
||||
|
||||
getline(strstream, buff, ',');
|
||||
objs->setModelID(atoi(buff.c_str()));
|
||||
objs->setModelID(lexical_cast<int>(buff));
|
||||
|
||||
getline(strstream, objs->name, ',');
|
||||
getline(strstream, objs->textureslot, ',');
|
||||
|
||||
getline(strstream, buff, ',');
|
||||
objs->setNumAtomics(atoi(buff.c_str()));
|
||||
objs->setNumAtomics(lexical_cast<int>(buff));
|
||||
|
||||
for (int i = 0; i < objs->getNumAtomics(); i++) {
|
||||
getline(strstream, buff, ',');
|
||||
objs->setLodDistance(i, atof(buff.c_str()));
|
||||
objs->setLodDistance(i, lexical_cast<float>(buff));
|
||||
}
|
||||
|
||||
objs->determineFurthest();
|
||||
|
||||
getline(strstream, buff, ',');
|
||||
objs->flags = atoi(buff.c_str());
|
||||
objs->flags = lexical_cast<int>(buff);
|
||||
|
||||
// Keep reading TOBJ data
|
||||
if (section == LoaderIDE::TOBJ) {
|
||||
getline(strstream, buff, ',');
|
||||
objs->timeOn = atoi(buff.c_str());
|
||||
objs->timeOn = lexical_cast<int>(buff);
|
||||
getline(strstream, buff, ',');
|
||||
objs->timeOff = atoi(buff.c_str());
|
||||
objs->timeOff = lexical_cast<int>(buff);
|
||||
} else {
|
||||
objs->timeOn = 0;
|
||||
objs->timeOff = 24;
|
||||
@ -107,7 +109,7 @@ bool LoaderIDE::load(const std::string &filename, const PedStatsList &stats) {
|
||||
auto cars = std::make_unique<VehicleModelInfo>();
|
||||
|
||||
getline(strstream, buff, ',');
|
||||
cars->setModelID(std::atoi(buff.c_str()));
|
||||
cars->setModelID(lexical_cast<int>(buff));
|
||||
|
||||
getline(strstream, cars->name, ',');
|
||||
getline(strstream, cars->textureslot, ',');
|
||||
@ -123,10 +125,10 @@ bool LoaderIDE::load(const std::string &filename, const PedStatsList &stats) {
|
||||
VehicleModelInfo::findVehicleClass(buff);
|
||||
|
||||
getline(strstream, buff, ',');
|
||||
cars->frequency_ = std::atoi(buff.c_str());
|
||||
cars->frequency_ = lexical_cast<int>(buff);
|
||||
|
||||
getline(strstream, buff, ',');
|
||||
cars->level_ = std::atoi(buff.c_str());
|
||||
cars->level_ = lexical_cast<int>(buff);
|
||||
|
||||
getline(strstream, buff, ',');
|
||||
cars->componentrules_ = std::stoul(buff, nullptr, 16);
|
||||
@ -134,14 +136,14 @@ bool LoaderIDE::load(const std::string &filename, const PedStatsList &stats) {
|
||||
switch (cars->vehicletype_) {
|
||||
case VehicleModelInfo::CAR:
|
||||
getline(strstream, buff, ',');
|
||||
cars->wheelmodel_ = std::atoi(buff.c_str());
|
||||
cars->wheelmodel_ = lexical_cast<int>(buff);
|
||||
getline(strstream, buff, ',');
|
||||
cars->wheelscale_ = std::atof(buff.c_str());
|
||||
cars->wheelscale_ = lexical_cast<float>(buff);
|
||||
break;
|
||||
case VehicleModelInfo::PLANE:
|
||||
/// @todo load LOD
|
||||
getline(strstream, buff, ',');
|
||||
// cars->planeLOD_ = std::atoi(buff.c_str());
|
||||
// cars->planeLOD_ = lexical_cast<int>(buff);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -154,7 +156,7 @@ bool LoaderIDE::load(const std::string &filename, const PedStatsList &stats) {
|
||||
auto peds = std::make_unique<PedModelInfo>();
|
||||
|
||||
getline(strstream, buff, ',');
|
||||
peds->setModelID(std::atoi(buff.c_str()));
|
||||
peds->setModelID(lexical_cast<int>(buff));
|
||||
|
||||
getline(strstream, peds->name, ',');
|
||||
getline(strstream, peds->textureslot, ',');
|
||||
@ -168,7 +170,7 @@ bool LoaderIDE::load(const std::string &filename, const PedStatsList &stats) {
|
||||
getline(strstream, peds->animgroup_, ',');
|
||||
|
||||
getline(strstream, buff, ',');
|
||||
peds->carsmask_ = std::atoi(buff.c_str());
|
||||
peds->carsmask_ = lexical_cast<int>(buff);
|
||||
|
||||
objects.emplace(peds->id(), std::move(peds));
|
||||
break;
|
||||
@ -186,7 +188,7 @@ bool LoaderIDE::load(const std::string &filename, const PedStatsList &stats) {
|
||||
|
||||
std::string id;
|
||||
getline(strstream, id, ',');
|
||||
path.ID = atoi(id.c_str());
|
||||
path.ID = lexical_cast<int>(id);
|
||||
|
||||
getline(strstream, path.modelName);
|
||||
|
||||
@ -198,7 +200,7 @@ bool LoaderIDE::load(const std::string &filename, const PedStatsList &stats) {
|
||||
std::stringstream buffstream(linebuff);
|
||||
|
||||
getline(buffstream, buff, ',');
|
||||
switch (atoi(buff.c_str())) {
|
||||
switch (lexical_cast<int>(buff)) {
|
||||
case 0:
|
||||
node.type = PathNode::EMPTY;
|
||||
break;
|
||||
@ -215,27 +217,27 @@ bool LoaderIDE::load(const std::string &filename, const PedStatsList &stats) {
|
||||
}
|
||||
|
||||
getline(buffstream, buff, ',');
|
||||
node.next = atoi(buff.c_str());
|
||||
node.next = lexical_cast<int>(buff);
|
||||
|
||||
getline(buffstream, buff, ','); // "Always 0"
|
||||
|
||||
getline(buffstream, buff, ',');
|
||||
node.position.x = strtof(buff.c_str(), nullptr) / 16.f;
|
||||
node.position.x = lexical_cast<float>(buff) / 16.f;
|
||||
|
||||
getline(buffstream, buff, ',');
|
||||
node.position.y = strtof(buff.c_str(), nullptr) / 16.f;
|
||||
node.position.y = lexical_cast<float>(buff) / 16.f;
|
||||
|
||||
getline(buffstream, buff, ',');
|
||||
node.position.z = strtof(buff.c_str(), nullptr) / 16.f;
|
||||
node.position.z = lexical_cast<float>(buff) / 16.f;
|
||||
|
||||
getline(buffstream, buff, ',');
|
||||
node.size = strtof(buff.c_str(), nullptr) / 16.f;
|
||||
node.size = lexical_cast<float>(buff) / 16.f;
|
||||
|
||||
getline(buffstream, buff, ',');
|
||||
node.leftLanes = atoi(buff.c_str());
|
||||
node.leftLanes = lexical_cast<int>(buff);
|
||||
|
||||
getline(buffstream, buff, ',');
|
||||
node.rightLanes = atoi(buff.c_str());
|
||||
node.rightLanes = lexical_cast<int>(buff);
|
||||
|
||||
path.nodes.push_back(node);
|
||||
}
|
||||
@ -250,7 +252,7 @@ bool LoaderIDE::load(const std::string &filename, const PedStatsList &stats) {
|
||||
auto hier = std::make_unique<ClumpModelInfo>();
|
||||
|
||||
getline(strstream, buff, ',');
|
||||
hier->setModelID(std::atoi(buff.c_str()));
|
||||
hier->setModelID(lexical_cast<int>(buff));
|
||||
|
||||
getline(strstream, hier->name, ',');
|
||||
getline(strstream, hier->textureslot, ',');
|
||||
|
@ -14,6 +14,8 @@
|
||||
#include "data/InstanceData.hpp"
|
||||
#include "data/ZoneData.hpp"
|
||||
|
||||
#include <rw/casts.hpp>
|
||||
|
||||
enum SectionTypes { INST, PICK, CULL, ZONE, NONE };
|
||||
|
||||
/// Load the IPL data into memory
|
||||
@ -76,15 +78,15 @@ bool LoaderIPL::load(const std::string& filename) {
|
||||
getline(strstream, rotW, ',');
|
||||
|
||||
auto instance = std::make_shared<InstanceData>(
|
||||
atoi(id.c_str()), // ID
|
||||
lexical_cast<int>(id), // ID
|
||||
model.substr(1, model.size() - 1),
|
||||
glm::vec3(atof(posX.c_str()), atof(posY.c_str()),
|
||||
atof(posZ.c_str())),
|
||||
glm::vec3(atof(scaleX.c_str()), atof(scaleY.c_str()),
|
||||
atof(scaleZ.c_str())),
|
||||
glm::vec3(lexical_cast<float>(posX), lexical_cast<float>(posY),
|
||||
lexical_cast<float>(posZ)),
|
||||
glm::vec3(lexical_cast<float>(scaleX), lexical_cast<float>(scaleY),
|
||||
lexical_cast<float>(scaleZ)),
|
||||
glm::normalize(
|
||||
glm::quat(-atof(rotW.c_str()), atof(rotX.c_str()),
|
||||
atof(rotY.c_str()), atof(rotZ.c_str()))));
|
||||
glm::quat(-lexical_cast<float>(rotW), lexical_cast<float>(rotX),
|
||||
lexical_cast<float>(rotY), lexical_cast<float>(rotZ))));
|
||||
|
||||
m_instances.push_back(instance);
|
||||
} else if (section == ZONE) {
|
||||
@ -98,24 +100,24 @@ bool LoaderIPL::load(const std::string& filename) {
|
||||
zone.name = value;
|
||||
|
||||
getline(strstream, value, ',');
|
||||
zone.type = atoi(value.c_str());
|
||||
zone.type = lexical_cast<int>(value);
|
||||
|
||||
getline(strstream, value, ',');
|
||||
zone.min.x = atof(value.c_str());
|
||||
zone.min.x = lexical_cast<float>(value);
|
||||
getline(strstream, value, ',');
|
||||
zone.min.y = atof(value.c_str());
|
||||
zone.min.y = lexical_cast<float>(value);
|
||||
getline(strstream, value, ',');
|
||||
zone.min.z = atof(value.c_str());
|
||||
zone.min.z = lexical_cast<float>(value);
|
||||
|
||||
getline(strstream, value, ',');
|
||||
zone.max.x = atof(value.c_str());
|
||||
zone.max.x = lexical_cast<float>(value);
|
||||
getline(strstream, value, ',');
|
||||
zone.max.y = atof(value.c_str());
|
||||
zone.max.y = lexical_cast<float>(value);
|
||||
getline(strstream, value, ',');
|
||||
zone.max.z = atof(value.c_str());
|
||||
zone.max.z = lexical_cast<float>(value);
|
||||
|
||||
getline(strstream, value, ',');
|
||||
zone.island = atoi(value.c_str());
|
||||
zone.island = lexical_cast<int>(value);
|
||||
|
||||
for (int i = 0; i < ZONE_GANG_COUNT; i++) {
|
||||
zone.gangCarDensityDay[i] = zone.gangCarDensityNight[i] =
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
#include "script/ScriptTypes.hpp"
|
||||
|
||||
#include <rw/bit_cast.hpp>
|
||||
#include <rw/casts.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
@ -14,7 +14,7 @@ SET(RWLIB_SOURCES
|
||||
source/gl/TextureData.cpp
|
||||
|
||||
source/rw/abort.cpp
|
||||
source/rw/bit_cast.hpp
|
||||
source/rw/casts.hpp
|
||||
source/rw/filesystem.hpp
|
||||
source/rw/forward.hpp
|
||||
source/rw/types.hpp
|
||||
|
@ -7,7 +7,7 @@
|
||||
#include <cstddef>
|
||||
|
||||
#include "rw/debug.hpp"
|
||||
#include "rw/bit_cast.hpp"
|
||||
#include "rw/casts.hpp"
|
||||
|
||||
/**
|
||||
* @brief Class for working with RenderWare binary streams.
|
||||
|
@ -1,15 +0,0 @@
|
||||
#ifndef _LIBRW_BIT_CAST_HPP_
|
||||
#define _LIBRW_BIT_CAST_HPP_
|
||||
|
||||
//Based on https://gist.github.com/socantre/3472964
|
||||
#include <cstring> // memcpy
|
||||
#include <type_traits> // is_trivially_copyable
|
||||
|
||||
template <class Dest, class Source>
|
||||
inline Dest bit_cast(Source const &source) {
|
||||
Dest dest = Dest{};
|
||||
std::memcpy(&dest, &source, sizeof(Dest));
|
||||
return dest;
|
||||
}
|
||||
|
||||
#endif
|
35
rwlib/source/rw/casts.hpp
Normal file
35
rwlib/source/rw/casts.hpp
Normal file
@ -0,0 +1,35 @@
|
||||
#ifndef _LIBRW_CASTS_HPP_
|
||||
#define _LIBRW_CASTS_HPP_
|
||||
|
||||
#include <cstring> // memcpy
|
||||
|
||||
#include "rw/debug.hpp"
|
||||
|
||||
//Based on https://gist.github.com/socantre/3472964
|
||||
template <class Dest, class Source>
|
||||
inline Dest bit_cast(Source const &source) {
|
||||
Dest dest = Dest{};
|
||||
std::memcpy(&dest, &source, sizeof(Dest));
|
||||
return dest;
|
||||
}
|
||||
|
||||
template <class T, class S>
|
||||
inline T lexical_cast(const S& s);
|
||||
|
||||
template <>
|
||||
inline int lexical_cast(const std::string& source) {
|
||||
char* end = nullptr; //for errors handling
|
||||
int result = std::strtol(source.c_str(), &end, 10);
|
||||
RW_CHECK(end != source.c_str(), "Problem with conversion " << *end << " to int");
|
||||
return result;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline float lexical_cast(const std::string& source) {
|
||||
char* end = nullptr; //for errors handling
|
||||
float result = std::strtof(source.c_str(), &end);
|
||||
RW_CHECK(end != source.c_str(), "Problem with conversion " << *end << " to float");
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user