forked from Mirrorlandia_minetest/minetest
Introduce std::string_view
into wider use (#14368)
This commit is contained in:
parent
fa47af737f
commit
6ca214fefc
@ -5459,7 +5459,7 @@ Utilities
|
||||
You can use `colorspec_to_bytes` to generate raw RGBA values.
|
||||
Palettes are not supported at the moment.
|
||||
You may use this to procedurally generate textures during server init.
|
||||
* `minetest.urlencode(str)`: Encodes non-unreserved URI characters by a
|
||||
* `minetest.urlencode(str)`: Encodes reserved URI characters by a
|
||||
percent sign followed by two hex digits. See
|
||||
[RFC 3986, section 2.3](https://datatracker.ietf.org/doc/html/rfc3986#section-2.3).
|
||||
|
||||
|
@ -133,6 +133,12 @@ local function test_compress()
|
||||
end
|
||||
unittests.register("test_compress", test_compress)
|
||||
|
||||
local function test_urlencode()
|
||||
-- checks that API code handles null bytes
|
||||
assert(core.urlencode("foo\000bar!") == "foo%00bar%21")
|
||||
end
|
||||
unittests.register("test_urlencode", test_urlencode)
|
||||
|
||||
local function test_game_info()
|
||||
local info = minetest.get_game_info()
|
||||
local game_conf = Settings(info.path .. "/game.conf")
|
||||
|
@ -46,7 +46,7 @@ enum ActiveObjectType {
|
||||
|
||||
struct ActiveObjectMessage
|
||||
{
|
||||
ActiveObjectMessage(u16 id_, bool reliable_=true, const std::string &data_ = "") :
|
||||
ActiveObjectMessage(u16 id_, bool reliable_=true, std::string_view data_ = "") :
|
||||
id(id_),
|
||||
reliable(reliable_),
|
||||
datastring(data_)
|
||||
|
@ -577,6 +577,7 @@ void ChatPrompt::historyNext()
|
||||
|
||||
void ChatPrompt::nickCompletion(const std::set<std::string> &names, bool backwards)
|
||||
{
|
||||
const std::wstring_view line(getLineRef());
|
||||
// Two cases:
|
||||
// (a) m_nick_completion_start == m_nick_completion_end == 0
|
||||
// Then no previous nick completion is active.
|
||||
@ -586,7 +587,6 @@ void ChatPrompt::nickCompletion(const std::set<std::string> &names, bool backwar
|
||||
// m_nick_completion_start..m_nick_completion_end are the
|
||||
// interval where the originally used prefix was. Cycle
|
||||
// through the list of completions of that prefix.
|
||||
const std::wstring &line = getLineRef();
|
||||
u32 prefix_start = m_nick_completion_start;
|
||||
u32 prefix_end = m_nick_completion_end;
|
||||
bool initial = (prefix_end == 0);
|
||||
@ -601,7 +601,7 @@ void ChatPrompt::nickCompletion(const std::set<std::string> &names, bool backwar
|
||||
if (prefix_start == prefix_end)
|
||||
return;
|
||||
}
|
||||
std::wstring prefix = line.substr(prefix_start, prefix_end - prefix_start);
|
||||
auto prefix = line.substr(prefix_start, prefix_end - prefix_start);
|
||||
|
||||
// find all names that start with the selected prefix
|
||||
std::vector<std::wstring> completions;
|
||||
@ -624,7 +624,7 @@ void ChatPrompt::nickCompletion(const std::set<std::string> &names, bool backwar
|
||||
{
|
||||
while (word_end < line.size() && !iswspace(line[word_end]))
|
||||
++word_end;
|
||||
std::wstring word = line.substr(prefix_start, word_end - prefix_start);
|
||||
auto word = line.substr(prefix_start, word_end - prefix_start);
|
||||
|
||||
// cycle through completions
|
||||
for (u32 i = 0; i < completions.size(); ++i)
|
||||
@ -640,7 +640,7 @@ void ChatPrompt::nickCompletion(const std::set<std::string> &names, bool backwar
|
||||
}
|
||||
}
|
||||
}
|
||||
std::wstring replacement = completions[replacement_index];
|
||||
const auto &replacement = completions[replacement_index];
|
||||
if (word_end < line.size() && iswspace(line[word_end]))
|
||||
++word_end;
|
||||
|
||||
|
@ -541,11 +541,9 @@ bool IClientMediaDownloader::checkAndLoad(
|
||||
// Compute actual checksum of data
|
||||
std::string data_sha1;
|
||||
{
|
||||
SHA1 data_sha1_calculator;
|
||||
data_sha1_calculator.addBytes(data.c_str(), data.size());
|
||||
unsigned char *data_tmpdigest = data_sha1_calculator.getDigest();
|
||||
data_sha1.assign((char*) data_tmpdigest, 20);
|
||||
free(data_tmpdigest);
|
||||
SHA1 ctx;
|
||||
ctx.addBytes(data);
|
||||
data_sha1 = ctx.getDigest();
|
||||
}
|
||||
|
||||
// Check that received file matches announced checksum
|
||||
|
@ -67,7 +67,7 @@ bool FileCache::loadByPath(const std::string &path, std::ostream &os)
|
||||
return !bad;
|
||||
}
|
||||
|
||||
bool FileCache::updateByPath(const std::string &path, const std::string &data)
|
||||
bool FileCache::updateByPath(const std::string &path, std::string_view data)
|
||||
{
|
||||
createDir();
|
||||
std::ofstream file(path.c_str(), std::ios_base::binary |
|
||||
@ -80,13 +80,13 @@ bool FileCache::updateByPath(const std::string &path, const std::string &data)
|
||||
return false;
|
||||
}
|
||||
|
||||
file.write(data.c_str(), data.length());
|
||||
file << data;
|
||||
file.close();
|
||||
|
||||
return !file.fail();
|
||||
}
|
||||
|
||||
bool FileCache::update(const std::string &name, const std::string &data)
|
||||
bool FileCache::update(const std::string &name, std::string_view data)
|
||||
{
|
||||
std::string path = m_dir + DIR_DELIM + name;
|
||||
return updateByPath(path, data);
|
||||
|
@ -22,6 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
class FileCache
|
||||
{
|
||||
@ -31,7 +32,7 @@ public:
|
||||
*/
|
||||
FileCache(const std::string &dir) : m_dir(dir) {}
|
||||
|
||||
bool update(const std::string &name, const std::string &data);
|
||||
bool update(const std::string &name, std::string_view data);
|
||||
bool load(const std::string &name, std::ostream &os);
|
||||
bool exists(const std::string &name);
|
||||
|
||||
@ -43,5 +44,5 @@ private:
|
||||
|
||||
void createDir();
|
||||
bool loadByPath(const std::string &path, std::ostream &os);
|
||||
bool updateByPath(const std::string &path, const std::string &data);
|
||||
bool updateByPath(const std::string &path, std::string_view data);
|
||||
};
|
||||
|
@ -804,7 +804,7 @@ ShaderInfo ShaderSource::generateShader(const std::string &name,
|
||||
}
|
||||
|
||||
void dumpShaderProgram(std::ostream &output_stream,
|
||||
const std::string &program_type, const std::string &program)
|
||||
const std::string &program_type, std::string_view program)
|
||||
{
|
||||
output_stream << program_type << " shader program:" << std::endl <<
|
||||
"----------------------------------" << std::endl;
|
||||
|
@ -192,4 +192,4 @@ public:
|
||||
IWritableShaderSource *createShaderSource();
|
||||
|
||||
void dumpShaderProgram(std::ostream &output_stream,
|
||||
const std::string &program_type, const std::string &program);
|
||||
const std::string &program_type, std::string_view program);
|
||||
|
@ -404,7 +404,7 @@ private:
|
||||
// Generate image based on a string like "stone.png" or "[crack:1:0".
|
||||
// if baseimg is NULL, it is created. Otherwise stuff is made on it.
|
||||
// source_image_names is important to determine when to flush the image from a cache (dynamic media)
|
||||
bool generateImagePart(std::string part_of_name, video::IImage *& baseimg, std::set<std::string> &source_image_names);
|
||||
bool generateImagePart(std::string_view part_of_name, video::IImage *& baseimg, std::set<std::string> &source_image_names);
|
||||
|
||||
/*! Generates an image from a full string like
|
||||
* "stone.png^mineral_coal.png^[crack:1:0".
|
||||
@ -412,7 +412,7 @@ private:
|
||||
* The returned Image should be dropped.
|
||||
* source_image_names is important to determine when to flush the image from a cache (dynamic media)
|
||||
*/
|
||||
video::IImage* generateImage(const std::string &name, std::set<std::string> &source_image_names);
|
||||
video::IImage* generateImage(std::string_view name, std::set<std::string> &source_image_names);
|
||||
|
||||
// Thread-safe cache of what source images are known (true = known)
|
||||
MutexedMap<std::string, bool> m_source_image_existence;
|
||||
@ -593,7 +593,7 @@ static void draw_crack(video::IImage *crack, video::IImage *dst,
|
||||
// Brighten image
|
||||
void brighten(video::IImage *image);
|
||||
// Parse a transform name
|
||||
u32 parseImageTransform(const std::string& s);
|
||||
u32 parseImageTransform(std::string_view s);
|
||||
// Apply transform to image dimension
|
||||
core::dimension2d<u32> imageTransformDimension(u32 transform, core::dimension2d<u32> dim);
|
||||
// Apply transform to image data
|
||||
@ -963,7 +963,8 @@ static video::IImage *createInventoryCubeImage(
|
||||
return result;
|
||||
}
|
||||
|
||||
video::IImage* TextureSource::generateImage(const std::string &name, std::set<std::string> &source_image_names)
|
||||
video::IImage* TextureSource::generateImage(std::string_view name,
|
||||
std::set<std::string> &source_image_names)
|
||||
{
|
||||
// Get the base image
|
||||
|
||||
@ -1024,15 +1025,15 @@ video::IImage* TextureSource::generateImage(const std::string &name, std::set<st
|
||||
according to it
|
||||
*/
|
||||
|
||||
std::string last_part_of_name = name.substr(last_separator_pos + 1);
|
||||
auto last_part_of_name = name.substr(last_separator_pos + 1);
|
||||
|
||||
/*
|
||||
If this name is enclosed in parentheses, generate it
|
||||
and blit it onto the base image
|
||||
*/
|
||||
if (last_part_of_name[0] == paren_open
|
||||
&& last_part_of_name[last_part_of_name.size() - 1] == paren_close) {
|
||||
std::string name2 = last_part_of_name.substr(1,
|
||||
&& last_part_of_name.back() == paren_close) {
|
||||
auto name2 = last_part_of_name.substr(1,
|
||||
last_part_of_name.size() - 2);
|
||||
video::IImage *tmp = generateImage(name2, source_image_names);
|
||||
if (!tmp) {
|
||||
@ -1199,7 +1200,7 @@ void blitBaseImage(video::IImage* &src, video::IImage* &dst)
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
bool TextureSource::generateImagePart(std::string part_of_name,
|
||||
bool TextureSource::generateImagePart(std::string_view part_of_name,
|
||||
video::IImage *& baseimg, std::set<std::string> &source_image_names)
|
||||
{
|
||||
const char escape = '\\'; // same as in generateImage()
|
||||
@ -1216,8 +1217,9 @@ bool TextureSource::generateImagePart(std::string part_of_name,
|
||||
|
||||
// Stuff starting with [ are special commands
|
||||
if (part_of_name.empty() || part_of_name[0] != '[') {
|
||||
source_image_names.insert(part_of_name);
|
||||
video::IImage *image = m_sourcecache.getOrLoad(part_of_name);
|
||||
std::string part_s(part_of_name);
|
||||
source_image_names.insert(part_s);
|
||||
video::IImage *image = m_sourcecache.getOrLoad(part_s);
|
||||
if (!image) {
|
||||
// Do not create the dummy texture
|
||||
if (part_of_name.empty())
|
||||
@ -1516,8 +1518,10 @@ bool TextureSource::generateImagePart(std::string part_of_name,
|
||||
return false;
|
||||
}
|
||||
|
||||
str_replace(part_of_name, '&', '^');
|
||||
Strfnd sf(part_of_name);
|
||||
std::string part_s(part_of_name);
|
||||
str_replace(part_s, '&', '^');
|
||||
|
||||
Strfnd sf(part_s);
|
||||
sf.next("{");
|
||||
std::string imagename_top = sf.next("{");
|
||||
std::string imagename_left = sf.next("{");
|
||||
@ -1873,7 +1877,7 @@ bool TextureSource::generateImagePart(std::string part_of_name,
|
||||
else if (str_starts_with(part_of_name, "[png:")) {
|
||||
std::string png;
|
||||
{
|
||||
std::string blob = part_of_name.substr(5);
|
||||
auto blob = part_of_name.substr(5);
|
||||
if (!base64_is_valid(blob)) {
|
||||
errorstream << "generateImagePart(): "
|
||||
<< "malformed base64 in [png" << std::endl;
|
||||
@ -2433,7 +2437,7 @@ void brighten(video::IImage *image)
|
||||
}
|
||||
}
|
||||
|
||||
u32 parseImageTransform(const std::string& s)
|
||||
u32 parseImageTransform(std::string_view s)
|
||||
{
|
||||
int total_transform = 0;
|
||||
|
||||
|
@ -22,6 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "settings.h"
|
||||
#include "filesys.h"
|
||||
#include "gettext.h"
|
||||
#include "exceptions.h"
|
||||
|
||||
|
||||
std::string ModConfiguration::getUnsatisfiedModsError() const
|
||||
|
@ -228,7 +228,7 @@ bool ModStorage::contains(const std::string &name) const
|
||||
return m_database->hasModEntry(m_mod_name, name);
|
||||
}
|
||||
|
||||
bool ModStorage::setString(const std::string &name, const std::string &var)
|
||||
bool ModStorage::setString(const std::string &name, std::string_view var)
|
||||
{
|
||||
if (var.empty())
|
||||
return m_database->removeModEntry(m_mod_name, name);
|
||||
|
@ -123,7 +123,7 @@ public:
|
||||
|
||||
bool contains(const std::string &name) const override;
|
||||
|
||||
bool setString(const std::string &name, const std::string &var) override;
|
||||
bool setString(const std::string &name, std::string_view var) override;
|
||||
|
||||
const StringMap &getStrings(StringMap *place) const override;
|
||||
|
||||
|
@ -239,9 +239,9 @@ std::set<std::string> getAvailableGameIds()
|
||||
|
||||
// Add it to result
|
||||
const char *ends[] = {"_game", NULL};
|
||||
std::string shorter = removeStringEnd(dln.name, ends);
|
||||
auto shorter = removeStringEnd(dln.name, ends);
|
||||
if (!shorter.empty())
|
||||
gameids.insert(shorter);
|
||||
gameids.emplace(shorter);
|
||||
else
|
||||
gameids.insert(dln.name);
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
|
||||
inline bool isGroupRecipeStr(const std::string &rec_name)
|
||||
{
|
||||
return str_starts_with(rec_name, std::string("group:"));
|
||||
return str_starts_with(rec_name, "group:");
|
||||
}
|
||||
|
||||
static bool hasGroupItem(const std::vector<std::string> &recipe)
|
||||
|
@ -25,7 +25,7 @@ Dummy database class
|
||||
#include "remoteplayer.h"
|
||||
|
||||
|
||||
bool Database_Dummy::saveBlock(const v3s16 &pos, const std::string &data)
|
||||
bool Database_Dummy::saveBlock(const v3s16 &pos, std::string_view data)
|
||||
{
|
||||
m_database[getBlockAsInteger(pos)] = data;
|
||||
return true;
|
||||
@ -128,11 +128,12 @@ bool Database_Dummy::hasModEntry(const std::string &modname, const std::string &
|
||||
}
|
||||
|
||||
bool Database_Dummy::setModEntry(const std::string &modname,
|
||||
const std::string &key, const std::string &value)
|
||||
const std::string &key, std::string_view value)
|
||||
{
|
||||
auto mod_pair = m_mod_storage_database.find(modname);
|
||||
if (mod_pair == m_mod_storage_database.end()) {
|
||||
m_mod_storage_database[modname] = StringMap({{key, value}});
|
||||
auto &map = m_mod_storage_database[modname];
|
||||
map[key] = value;
|
||||
} else {
|
||||
mod_pair->second[key] = value;
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include "database.h"
|
||||
#include "irrlichttypes.h"
|
||||
@ -27,7 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
class Database_Dummy : public MapDatabase, public PlayerDatabase, public ModStorageDatabase
|
||||
{
|
||||
public:
|
||||
bool saveBlock(const v3s16 &pos, const std::string &data);
|
||||
bool saveBlock(const v3s16 &pos, std::string_view data);
|
||||
void loadBlock(const v3s16 &pos, std::string *block);
|
||||
bool deleteBlock(const v3s16 &pos);
|
||||
void listAllLoadableBlocks(std::vector<v3s16> &dst);
|
||||
@ -43,7 +44,7 @@ public:
|
||||
const std::string &key, std::string *value);
|
||||
bool hasModEntry(const std::string &modname, const std::string &key);
|
||||
bool setModEntry(const std::string &modname,
|
||||
const std::string &key, const std::string &value);
|
||||
const std::string &key,std::string_view value);
|
||||
bool removeModEntry(const std::string &modname, const std::string &key);
|
||||
bool removeModEntries(const std::string &modname);
|
||||
void listMods(std::vector<std::string> *res);
|
||||
|
@ -428,13 +428,14 @@ bool ModStorageDatabaseFiles::hasModEntry(const std::string &modname, const std:
|
||||
}
|
||||
|
||||
bool ModStorageDatabaseFiles::setModEntry(const std::string &modname,
|
||||
const std::string &key, const std::string &value)
|
||||
const std::string &key, std::string_view value)
|
||||
{
|
||||
Json::Value *meta = getOrCreateJson(modname);
|
||||
if (!meta)
|
||||
return false;
|
||||
|
||||
(*meta)[key] = Json::Value(value);
|
||||
Json::Value value_v(value.data(), value.data() + value.size());
|
||||
(*meta)[key] = std::move(value_v);
|
||||
m_modified.insert(modname);
|
||||
|
||||
return true;
|
||||
|
@ -84,7 +84,7 @@ public:
|
||||
const std::string &key, std::string *value);
|
||||
virtual bool hasModEntry(const std::string &modname, const std::string &key);
|
||||
virtual bool setModEntry(const std::string &modname,
|
||||
const std::string &key, const std::string &value);
|
||||
const std::string &key, std::string_view value);
|
||||
virtual bool removeModEntry(const std::string &modname, const std::string &key);
|
||||
virtual bool removeModEntries(const std::string &modname);
|
||||
virtual void listMods(std::vector<std::string> *res);
|
||||
|
@ -53,10 +53,11 @@ Database_LevelDB::Database_LevelDB(const std::string &savedir)
|
||||
m_database.reset(db);
|
||||
}
|
||||
|
||||
bool Database_LevelDB::saveBlock(const v3s16 &pos, const std::string &data)
|
||||
bool Database_LevelDB::saveBlock(const v3s16 &pos, std::string_view data)
|
||||
{
|
||||
leveldb::Slice data_s(data.data(), data.size());
|
||||
leveldb::Status status = m_database->Put(leveldb::WriteOptions(),
|
||||
i64tos(getBlockAsInteger(pos)), data);
|
||||
i64tos(getBlockAsInteger(pos)), data_s);
|
||||
if (!status.ok()) {
|
||||
warningstream << "saveBlock: LevelDB error saving block "
|
||||
<< pos << ": " << status.ToString() << std::endl;
|
||||
|
@ -34,7 +34,7 @@ public:
|
||||
Database_LevelDB(const std::string &savedir);
|
||||
~Database_LevelDB() = default;
|
||||
|
||||
bool saveBlock(const v3s16 &pos, const std::string &data);
|
||||
bool saveBlock(const v3s16 &pos, std::string_view data);
|
||||
void loadBlock(const v3s16 &pos, std::string *block);
|
||||
bool deleteBlock(const v3s16 &pos);
|
||||
void listAllLoadableBlocks(std::vector<v3s16> &dst);
|
||||
|
@ -223,7 +223,7 @@ void MapDatabasePostgreSQL::initStatements()
|
||||
"SELECT posX, posY, posZ FROM blocks");
|
||||
}
|
||||
|
||||
bool MapDatabasePostgreSQL::saveBlock(const v3s16 &pos, const std::string &data)
|
||||
bool MapDatabasePostgreSQL::saveBlock(const v3s16 &pos, std::string_view data)
|
||||
{
|
||||
// Verify if we don't overflow the platform integer with the mapblock size
|
||||
if (data.size() > INT_MAX) {
|
||||
@ -240,7 +240,7 @@ bool MapDatabasePostgreSQL::saveBlock(const v3s16 &pos, const std::string &data)
|
||||
y = htonl(pos.Y);
|
||||
z = htonl(pos.Z);
|
||||
|
||||
const void *args[] = { &x, &y, &z, data.c_str() };
|
||||
const void *args[] = { &x, &y, &z, data.data() };
|
||||
const int argLen[] = {
|
||||
sizeof(x), sizeof(y), sizeof(z), (int)data.size()
|
||||
};
|
||||
@ -940,11 +940,11 @@ bool ModStorageDatabasePostgreSQL::hasModEntry(const std::string &modname,
|
||||
}
|
||||
|
||||
bool ModStorageDatabasePostgreSQL::setModEntry(const std::string &modname,
|
||||
const std::string &key, const std::string &value)
|
||||
const std::string &key, std::string_view value)
|
||||
{
|
||||
verifyDatabase();
|
||||
|
||||
const void *args[] = { modname.c_str(), key.c_str(), value.c_str() };
|
||||
const void *args[] = { modname.c_str(), key.c_str(), value.data() };
|
||||
const int argLen[] = {
|
||||
-1,
|
||||
(int)MYMIN(key.size(), INT_MAX),
|
||||
|
@ -120,7 +120,7 @@ public:
|
||||
MapDatabasePostgreSQL(const std::string &connect_string);
|
||||
virtual ~MapDatabasePostgreSQL() = default;
|
||||
|
||||
bool saveBlock(const v3s16 &pos, const std::string &data);
|
||||
bool saveBlock(const v3s16 &pos, std::string_view data);
|
||||
void loadBlock(const v3s16 &pos, std::string *block);
|
||||
bool deleteBlock(const v3s16 &pos);
|
||||
void listAllLoadableBlocks(std::vector<v3s16> &dst);
|
||||
@ -186,7 +186,7 @@ public:
|
||||
bool getModEntry(const std::string &modname, const std::string &key, std::string *value);
|
||||
bool hasModEntry(const std::string &modname, const std::string &key);
|
||||
bool setModEntry(const std::string &modname,
|
||||
const std::string &key, const std::string &value);
|
||||
const std::string &key, std::string_view value);
|
||||
bool removeModEntry(const std::string &modname, const std::string &key);
|
||||
bool removeModEntries(const std::string &modname);
|
||||
void listMods(std::vector<std::string> *res);
|
||||
|
@ -91,12 +91,12 @@ void Database_Redis::endSave() {
|
||||
freeReplyObject(reply);
|
||||
}
|
||||
|
||||
bool Database_Redis::saveBlock(const v3s16 &pos, const std::string &data)
|
||||
bool Database_Redis::saveBlock(const v3s16 &pos, std::string_view data)
|
||||
{
|
||||
std::string tmp = i64tos(getBlockAsInteger(pos));
|
||||
|
||||
redisReply *reply = static_cast<redisReply *>(redisCommand(ctx, "HSET %s %s %b",
|
||||
hash.c_str(), tmp.c_str(), data.c_str(), data.size()));
|
||||
hash.c_str(), tmp.c_str(), data.data(), data.size()));
|
||||
if (!reply) {
|
||||
warningstream << "saveBlock: redis command 'HSET' failed on "
|
||||
"block " << pos << ": " << ctx->errstr << std::endl;
|
||||
|
@ -38,7 +38,7 @@ public:
|
||||
void beginSave();
|
||||
void endSave();
|
||||
|
||||
bool saveBlock(const v3s16 &pos, const std::string &data);
|
||||
bool saveBlock(const v3s16 &pos, std::string_view data);
|
||||
void loadBlock(const v3s16 &pos, std::string *block);
|
||||
bool deleteBlock(const v3s16 &pos);
|
||||
void listAllLoadableBlocks(std::vector<v3s16> &dst);
|
||||
|
@ -258,7 +258,7 @@ bool MapDatabaseSQLite3::deleteBlock(const v3s16 &pos)
|
||||
return good;
|
||||
}
|
||||
|
||||
bool MapDatabaseSQLite3::saveBlock(const v3s16 &pos, const std::string &data)
|
||||
bool MapDatabaseSQLite3::saveBlock(const v3s16 &pos, std::string_view data)
|
||||
{
|
||||
verifyDatabase();
|
||||
|
||||
@ -283,13 +283,8 @@ void MapDatabaseSQLite3::loadBlock(const v3s16 &pos, std::string *block)
|
||||
return;
|
||||
}
|
||||
|
||||
const char *data = (const char *) sqlite3_column_blob(m_stmt_read, 0);
|
||||
size_t len = sqlite3_column_bytes(m_stmt_read, 0);
|
||||
|
||||
if (data)
|
||||
block->assign(data, len);
|
||||
else
|
||||
block->clear();
|
||||
auto data = sqlite_to_blob(m_stmt_read, 0);
|
||||
block->assign(data);
|
||||
|
||||
sqlite3_step(m_stmt_read);
|
||||
// We should never get more than 1 row, so ok to reset
|
||||
@ -553,7 +548,7 @@ bool PlayerDatabaseSQLite3::loadPlayer(RemotePlayer *player, PlayerSAO *sao)
|
||||
int_to_sqlite(m_stmt_player_load_inventory_items, 2, invId);
|
||||
while (sqlite3_step(m_stmt_player_load_inventory_items) == SQLITE_ROW) {
|
||||
const std::string itemStr = sqlite_to_string(m_stmt_player_load_inventory_items, 1);
|
||||
if (itemStr.length() > 0) {
|
||||
if (!itemStr.empty()) {
|
||||
ItemStack stack;
|
||||
stack.deSerialize(itemStr);
|
||||
invList->changeItem(sqlite_to_uint(m_stmt_player_load_inventory_items, 0), stack);
|
||||
@ -567,7 +562,7 @@ bool PlayerDatabaseSQLite3::loadPlayer(RemotePlayer *player, PlayerSAO *sao)
|
||||
str_to_sqlite(m_stmt_player_metadata_load, 1, sao->getPlayer()->getName());
|
||||
while (sqlite3_step(m_stmt_player_metadata_load) == SQLITE_ROW) {
|
||||
std::string attr = sqlite_to_string(m_stmt_player_metadata_load, 0);
|
||||
std::string value = sqlite_to_string(m_stmt_player_metadata_load, 1);
|
||||
auto value = sqlite_to_string_view(m_stmt_player_metadata_load, 1);
|
||||
|
||||
sao->getMeta().setString(attr, value);
|
||||
}
|
||||
@ -592,7 +587,7 @@ void PlayerDatabaseSQLite3::listPlayers(std::vector<std::string> &res)
|
||||
verifyDatabase();
|
||||
|
||||
while (sqlite3_step(m_stmt_player_list) == SQLITE_ROW)
|
||||
res.push_back(sqlite_to_string(m_stmt_player_list, 0));
|
||||
res.emplace_back(sqlite_to_string_view(m_stmt_player_list, 0));
|
||||
|
||||
sqlite3_reset(m_stmt_player_list);
|
||||
}
|
||||
@ -669,14 +664,14 @@ bool AuthDatabaseSQLite3::getAuth(const std::string &name, AuthEntry &res)
|
||||
return false;
|
||||
}
|
||||
res.id = sqlite_to_uint(m_stmt_read, 0);
|
||||
res.name = sqlite_to_string(m_stmt_read, 1);
|
||||
res.password = sqlite_to_string(m_stmt_read, 2);
|
||||
res.name = sqlite_to_string_view(m_stmt_read, 1);
|
||||
res.password = sqlite_to_string_view(m_stmt_read, 2);
|
||||
res.last_login = sqlite_to_int64(m_stmt_read, 3);
|
||||
sqlite3_reset(m_stmt_read);
|
||||
|
||||
int64_to_sqlite(m_stmt_read_privs, 1, res.id);
|
||||
while (sqlite3_step(m_stmt_read_privs) == SQLITE_ROW) {
|
||||
res.privileges.emplace_back(sqlite_to_string(m_stmt_read_privs, 0));
|
||||
res.privileges.emplace_back(sqlite_to_string_view(m_stmt_read_privs, 0));
|
||||
}
|
||||
sqlite3_reset(m_stmt_read_privs);
|
||||
|
||||
@ -741,7 +736,7 @@ void AuthDatabaseSQLite3::listNames(std::vector<std::string> &res)
|
||||
verifyDatabase();
|
||||
|
||||
while (sqlite3_step(m_stmt_list_names) == SQLITE_ROW) {
|
||||
res.push_back(sqlite_to_string(m_stmt_list_names, 0));
|
||||
res.emplace_back(sqlite_to_string_view(m_stmt_list_names, 0));
|
||||
}
|
||||
sqlite3_reset(m_stmt_list_names);
|
||||
}
|
||||
@ -815,11 +810,9 @@ void ModStorageDatabaseSQLite3::getModEntries(const std::string &modname, String
|
||||
|
||||
str_to_sqlite(m_stmt_get_all, 1, modname);
|
||||
while (sqlite3_step(m_stmt_get_all) == SQLITE_ROW) {
|
||||
const char *key_data = (const char *) sqlite3_column_blob(m_stmt_get_all, 0);
|
||||
size_t key_len = sqlite3_column_bytes(m_stmt_get_all, 0);
|
||||
const char *value_data = (const char *) sqlite3_column_blob(m_stmt_get_all, 1);
|
||||
size_t value_len = sqlite3_column_bytes(m_stmt_get_all, 1);
|
||||
(*storage)[std::string(key_data, key_len)] = std::string(value_data, value_len);
|
||||
auto key = sqlite_to_blob(m_stmt_get_all, 0);
|
||||
auto value = sqlite_to_blob(m_stmt_get_all, 1);
|
||||
(*storage)[std::string(key)].assign(value);
|
||||
}
|
||||
sqlite3_vrfy(sqlite3_errcode(m_database), SQLITE_DONE);
|
||||
|
||||
@ -833,9 +826,8 @@ void ModStorageDatabaseSQLite3::getModKeys(const std::string &modname,
|
||||
|
||||
str_to_sqlite(m_stmt_get_keys, 1, modname);
|
||||
while (sqlite3_step(m_stmt_get_keys) == SQLITE_ROW) {
|
||||
const char *key_data = (const char *) sqlite3_column_blob(m_stmt_get_keys, 0);
|
||||
size_t key_len = sqlite3_column_bytes(m_stmt_get_keys, 0);
|
||||
storage->emplace_back(key_data, key_len);
|
||||
auto key = sqlite_to_blob(m_stmt_get_keys, 0);
|
||||
storage->emplace_back(key);
|
||||
}
|
||||
sqlite3_vrfy(sqlite3_errcode(m_database), SQLITE_DONE);
|
||||
|
||||
@ -852,9 +844,8 @@ bool ModStorageDatabaseSQLite3::getModEntry(const std::string &modname,
|
||||
"Internal error: failed to bind query at " __FILE__ ":" TOSTRING(__LINE__));
|
||||
bool found = sqlite3_step(m_stmt_get) == SQLITE_ROW;
|
||||
if (found) {
|
||||
const char *value_data = (const char *) sqlite3_column_blob(m_stmt_get, 0);
|
||||
size_t value_len = sqlite3_column_bytes(m_stmt_get, 0);
|
||||
value->assign(value_data, value_len);
|
||||
auto sv = sqlite_to_blob(m_stmt_get, 0);
|
||||
value->assign(sv);
|
||||
sqlite3_step(m_stmt_get);
|
||||
}
|
||||
|
||||
@ -881,7 +872,7 @@ bool ModStorageDatabaseSQLite3::hasModEntry(const std::string &modname,
|
||||
}
|
||||
|
||||
bool ModStorageDatabaseSQLite3::setModEntry(const std::string &modname,
|
||||
const std::string &key, const std::string &value)
|
||||
const std::string &key, std::string_view value)
|
||||
{
|
||||
verifyDatabase();
|
||||
|
||||
|
@ -44,14 +44,9 @@ protected:
|
||||
void verifyDatabase();
|
||||
|
||||
// Convertors
|
||||
inline void str_to_sqlite(sqlite3_stmt *s, int iCol, const std::string &str) const
|
||||
inline void str_to_sqlite(sqlite3_stmt *s, int iCol, std::string_view str) const
|
||||
{
|
||||
sqlite3_vrfy(sqlite3_bind_text(s, iCol, str.c_str(), str.size(), NULL));
|
||||
}
|
||||
|
||||
inline void str_to_sqlite(sqlite3_stmt *s, int iCol, const char *str) const
|
||||
{
|
||||
sqlite3_vrfy(sqlite3_bind_text(s, iCol, str, strlen(str), NULL));
|
||||
sqlite3_vrfy(sqlite3_bind_text(s, iCol, str.data(), str.size(), NULL));
|
||||
}
|
||||
|
||||
inline void int_to_sqlite(sqlite3_stmt *s, int iCol, int val) const
|
||||
@ -69,10 +64,28 @@ protected:
|
||||
sqlite3_vrfy(sqlite3_bind_double(s, iCol, val));
|
||||
}
|
||||
|
||||
inline std::string sqlite_to_string(sqlite3_stmt *s, int iCol)
|
||||
// Note that the return value is only valid until the statement is stepped or reset.
|
||||
inline std::string_view sqlite_to_string_view(sqlite3_stmt *s, int iCol)
|
||||
{
|
||||
const char* text = reinterpret_cast<const char*>(sqlite3_column_text(s, iCol));
|
||||
return std::string(text ? text : "");
|
||||
return text ? std::string_view(text) : std::string_view();
|
||||
}
|
||||
|
||||
// Avoid using this in favor of `sqlite_to_string_view`.
|
||||
inline std::string sqlite_to_string(sqlite3_stmt *s, int iCol)
|
||||
{
|
||||
return std::string(sqlite_to_string_view(s, iCol));
|
||||
}
|
||||
|
||||
// Converts a BLOB-type column into a string_view (null byte safe).
|
||||
// Note that the return value is only valid until the statement is stepped or reset.
|
||||
inline std::string_view sqlite_to_blob(sqlite3_stmt *s, int iCol)
|
||||
{
|
||||
const char *data = reinterpret_cast<const char*>(sqlite3_column_blob(s, iCol));
|
||||
if (!data)
|
||||
return std::string_view();
|
||||
size_t len = sqlite3_column_bytes(s, iCol);
|
||||
return std::string_view(data, len);
|
||||
}
|
||||
|
||||
inline s32 sqlite_to_int(sqlite3_stmt *s, int iCol)
|
||||
@ -107,13 +120,16 @@ protected:
|
||||
}
|
||||
|
||||
// Query verifiers helpers
|
||||
inline void sqlite3_vrfy(int s, const std::string &m = "", int r = SQLITE_OK) const
|
||||
inline void sqlite3_vrfy(int s, std::string_view m = "", int r = SQLITE_OK) const
|
||||
{
|
||||
if (s != r)
|
||||
throw DatabaseException(m + ": " + sqlite3_errmsg(m_database));
|
||||
if (s != r) {
|
||||
std::string msg(m);
|
||||
msg.append(": ").append(sqlite3_errmsg(m_database));
|
||||
throw DatabaseException(msg);
|
||||
}
|
||||
}
|
||||
|
||||
inline void sqlite3_vrfy(const int s, const int r, const std::string &m = "") const
|
||||
inline void sqlite3_vrfy(const int s, const int r, std::string_view m = "") const
|
||||
{
|
||||
sqlite3_vrfy(s, m, r);
|
||||
}
|
||||
@ -146,7 +162,7 @@ public:
|
||||
MapDatabaseSQLite3(const std::string &savedir);
|
||||
virtual ~MapDatabaseSQLite3();
|
||||
|
||||
bool saveBlock(const v3s16 &pos, const std::string &data);
|
||||
bool saveBlock(const v3s16 &pos, std::string_view data);
|
||||
void loadBlock(const v3s16 &pos, std::string *block);
|
||||
bool deleteBlock(const v3s16 &pos);
|
||||
void listAllLoadableBlocks(std::vector<v3s16> &dst);
|
||||
@ -245,7 +261,7 @@ public:
|
||||
const std::string &key, std::string *value);
|
||||
virtual bool hasModEntry(const std::string &modname, const std::string &key);
|
||||
virtual bool setModEntry(const std::string &modname,
|
||||
const std::string &key, const std::string &value);
|
||||
const std::string &key,std::string_view value);
|
||||
virtual bool removeModEntry(const std::string &modname, const std::string &key);
|
||||
virtual bool removeModEntries(const std::string &modname);
|
||||
virtual void listMods(std::vector<std::string> *res);
|
||||
|
@ -19,12 +19,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
#include "irr_v3d.h"
|
||||
#include "irrlichttypes.h"
|
||||
#include "util/basic_macros.h"
|
||||
#include "util/string.h"
|
||||
|
||||
class Database
|
||||
@ -40,7 +39,7 @@ class MapDatabase : public Database
|
||||
public:
|
||||
virtual ~MapDatabase() = default;
|
||||
|
||||
virtual bool saveBlock(const v3s16 &pos, const std::string &data) = 0;
|
||||
virtual bool saveBlock(const v3s16 &pos, std::string_view data) = 0;
|
||||
virtual void loadBlock(const v3s16 &pos, std::string *block) = 0;
|
||||
virtual bool deleteBlock(const v3s16 &pos) = 0;
|
||||
|
||||
@ -97,7 +96,7 @@ public:
|
||||
virtual bool getModEntry(const std::string &modname,
|
||||
const std::string &key, std::string *value) = 0;
|
||||
virtual bool setModEntry(const std::string &modname,
|
||||
const std::string &key, const std::string &value) = 0;
|
||||
const std::string &key, std::string_view value) = 0;
|
||||
virtual bool removeModEntry(const std::string &modname, const std::string &key) = 0;
|
||||
virtual bool removeModEntries(const std::string &modname) = 0;
|
||||
virtual void listMods(std::vector<std::string> *res) = 0;
|
||||
|
@ -828,7 +828,7 @@ const char *GetFilenameFromPath(const char *path)
|
||||
return filename ? filename + 1 : path;
|
||||
}
|
||||
|
||||
bool safeWriteToFile(const std::string &path, const std::string &content)
|
||||
bool safeWriteToFile(const std::string &path, std::string_view content)
|
||||
{
|
||||
std::string tmp_file = path + ".~mt";
|
||||
|
||||
@ -844,7 +844,7 @@ bool safeWriteToFile(const std::string &path, const std::string &content)
|
||||
return false;
|
||||
}
|
||||
DWORD bytes_written;
|
||||
tmp_success = (WriteFile(tmp_handle, content.c_str(), content.size(), &bytes_written, nullptr) &&
|
||||
tmp_success = (WriteFile(tmp_handle, content.data(), content.size(), &bytes_written, nullptr) &&
|
||||
FlushFileBuffers(tmp_handle));
|
||||
CloseHandle(tmp_handle);
|
||||
#else
|
||||
|
@ -21,8 +21,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
#include "exceptions.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#define DIR_DELIM "\\"
|
||||
@ -142,7 +142,7 @@ std::string AbsolutePath(const std::string &path);
|
||||
// delimiter is found.
|
||||
const char *GetFilenameFromPath(const char *path);
|
||||
|
||||
bool safeWriteToFile(const std::string &path, const std::string &content);
|
||||
bool safeWriteToFile(const std::string &path, std::string_view content);
|
||||
|
||||
#ifndef SERVER
|
||||
bool extractZipFile(irr::io::IFileSystem *fs, const char *filename, const std::string &destination);
|
||||
|
@ -755,7 +755,7 @@ void GUIFormSpecMenu::parseScrollBarOptions(parserData* data, const std::string
|
||||
data->scrollbar_options.thumb_size = value <= 0 ? 1 : value;
|
||||
continue;
|
||||
} else if (options[0] == "arrows") {
|
||||
std::string value = trim(options[1]);
|
||||
auto value = trim(options[1]);
|
||||
if (value == "hide")
|
||||
data->scrollbar_options.arrow_visiblity = GUIScrollBar::HIDE;
|
||||
else if (value == "show")
|
||||
@ -2449,8 +2449,8 @@ bool GUIFormSpecMenu::parseSizeDirect(parserData* data, const std::string &eleme
|
||||
if (parts.size() < 2)
|
||||
return false;
|
||||
|
||||
std::string type = trim(parts[0]);
|
||||
std::string description = trim(parts[1]);
|
||||
auto type = trim(parts[0]);
|
||||
std::string description(trim(parts[1]));
|
||||
|
||||
if (type != "size" && type != "invsize")
|
||||
return false;
|
||||
@ -2473,8 +2473,8 @@ bool GUIFormSpecMenu::parsePositionDirect(parserData *data, const std::string &e
|
||||
if (parts.size() != 2)
|
||||
return false;
|
||||
|
||||
std::string type = trim(parts[0]);
|
||||
std::string description = trim(parts[1]);
|
||||
auto type = trim(parts[0]);
|
||||
std::string description(trim(parts[1]));
|
||||
|
||||
if (type != "position")
|
||||
return false;
|
||||
@ -2512,8 +2512,8 @@ bool GUIFormSpecMenu::parseAnchorDirect(parserData *data, const std::string &ele
|
||||
if (parts.size() != 2)
|
||||
return false;
|
||||
|
||||
std::string type = trim(parts[0]);
|
||||
std::string description = trim(parts[1]);
|
||||
auto type = trim(parts[0]);
|
||||
std::string description(trim(parts[1]));
|
||||
|
||||
if (type != "anchor")
|
||||
return false;
|
||||
@ -2552,8 +2552,8 @@ bool GUIFormSpecMenu::parsePaddingDirect(parserData *data, const std::string &el
|
||||
if (parts.size() != 2)
|
||||
return false;
|
||||
|
||||
std::string type = trim(parts[0]);
|
||||
std::string description = trim(parts[1]);
|
||||
auto type = trim(parts[0]);
|
||||
std::string description(trim(parts[1]));
|
||||
|
||||
if (type != "padding")
|
||||
return false;
|
||||
@ -2624,7 +2624,7 @@ bool GUIFormSpecMenu::parseStyle(parserData *data, const std::string &element, b
|
||||
|
||||
std::vector<std::string> selectors = split(parts[0], ',');
|
||||
for (size_t sel = 0; sel < selectors.size(); sel++) {
|
||||
std::string selector = trim(selectors[sel]);
|
||||
std::string selector(trim(selectors[sel]));
|
||||
|
||||
// Copy the style properties to a new StyleSpec
|
||||
// This allows a separate state mask per-selector
|
||||
@ -3216,7 +3216,7 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
|
||||
mydata.real_coordinates = m_formspec_version >= 2;
|
||||
for (; i < elements.size(); i++) {
|
||||
std::vector<std::string> parts = split(elements[i], '[');
|
||||
std::string name = trim(parts[0]);
|
||||
auto name = trim(parts[0]);
|
||||
if (name != "real_coordinates" || parts.size() != 2)
|
||||
break; // Invalid format
|
||||
|
||||
|
@ -49,10 +49,10 @@ static void sanitize_string(std::string &str)
|
||||
str.erase(std::remove(str.begin(), str.end(), DESERIALIZE_PAIR_DELIM), str.end());
|
||||
}
|
||||
|
||||
bool ItemStackMetadata::setString(const std::string &name, const std::string &var)
|
||||
bool ItemStackMetadata::setString(const std::string &name, std::string_view var)
|
||||
{
|
||||
std::string clean_name = name;
|
||||
std::string clean_var = var;
|
||||
std::string clean_var(var);
|
||||
sanitize_string(clean_name);
|
||||
sanitize_string(clean_var);
|
||||
|
||||
|
@ -36,7 +36,7 @@ public:
|
||||
|
||||
// Overrides
|
||||
void clear() override;
|
||||
bool setString(const std::string &name, const std::string &var) override;
|
||||
bool setString(const std::string &name, std::string_view var) override;
|
||||
|
||||
void serialize(std::ostream &os) const;
|
||||
void deSerialize(std::istream &is);
|
||||
|
@ -1798,6 +1798,7 @@ bool ServerMap::saveBlock(MapBlock *block, MapDatabase *db, int compression_leve
|
||||
o.write((char*) &version, 1);
|
||||
block->serialize(o, version, true, compression_level);
|
||||
|
||||
// FIXME: zero copy possible in c++20 or with custom rdbuf
|
||||
bool ret = db->saveBlock(p3d, o.str());
|
||||
if (ret) {
|
||||
// We just wrote it to the disk so clear modified flag
|
||||
|
@ -382,7 +382,7 @@ void MapBlock::serialize(std::ostream &os_compressed, u8 version, bool disk, int
|
||||
Bulk node data
|
||||
*/
|
||||
NameIdMapping nimap;
|
||||
SharedBuffer<u8> buf;
|
||||
Buffer<u8> buf;
|
||||
const u8 content_width = 2;
|
||||
const u8 params_width = 2;
|
||||
if(disk)
|
||||
@ -653,7 +653,7 @@ void MapBlock::deSerialize_pre22(std::istream &is, u8 version, bool disk)
|
||||
|
||||
// Make a temporary buffer
|
||||
u32 ser_length = MapNode::serializedLength(version);
|
||||
SharedBuffer<u8> databuf_nodelist(nodecount * ser_length);
|
||||
Buffer<u8> databuf_nodelist(nodecount * ser_length);
|
||||
|
||||
// These have no compression
|
||||
if (version <= 3 || version == 5 || version == 6) {
|
||||
|
@ -384,7 +384,7 @@ bool Schematic::serializeToMts(std::ostream *os) const
|
||||
}
|
||||
|
||||
// compressed bulk node data
|
||||
SharedBuffer<u8> buf = MapNode::serializeBulk(MTSCHEM_MAPNODE_SER_FMT_VER,
|
||||
auto buf = MapNode::serializeBulk(MTSCHEM_MAPNODE_SER_FMT_VER,
|
||||
schemdata, size.X * size.Y * size.Z, 2, 2);
|
||||
compress(buf, ss, MTSCHEM_MAPNODE_SER_FMT_VER);
|
||||
|
||||
|
@ -690,7 +690,7 @@ void MapNode::deSerialize(u8 *source, u8 version)
|
||||
}
|
||||
}
|
||||
|
||||
SharedBuffer<u8> MapNode::serializeBulk(int version,
|
||||
Buffer<u8> MapNode::serializeBulk(int version,
|
||||
const MapNode *nodes, u32 nodecount,
|
||||
u8 content_width, u8 params_width)
|
||||
{
|
||||
@ -706,7 +706,7 @@ SharedBuffer<u8> MapNode::serializeBulk(int version,
|
||||
throw SerializationError("MapNode::serializeBulk: serialization to "
|
||||
"version < 24 not possible");
|
||||
|
||||
SharedBuffer<u8> databuf(nodecount * (content_width + params_width));
|
||||
Buffer<u8> databuf(nodecount * (content_width + params_width));
|
||||
|
||||
u32 start1 = content_width * nodecount;
|
||||
u32 start2 = (content_width + 1) * nodecount;
|
||||
|
@ -316,7 +316,7 @@ struct alignas(u32) MapNode
|
||||
// content_width = the number of bytes of content per node
|
||||
// params_width = the number of bytes of params per node
|
||||
// compressed = true to zlib-compress output
|
||||
static SharedBuffer<u8> serializeBulk(int version,
|
||||
static Buffer<u8> serializeBulk(int version,
|
||||
const MapNode *nodes, u32 nodecount,
|
||||
u8 content_width, u8 params_width);
|
||||
static void deSerializeBulk(std::istream &is, int version,
|
||||
|
@ -70,7 +70,7 @@ bool IMetadata::getStringToRef(const std::string &name,
|
||||
const std::string &IMetadata::resolveString(const std::string &str, std::string *place,
|
||||
u16 recursion, bool deprecated) const
|
||||
{
|
||||
if (recursion <= 1 && str.substr(0, 2) == "${" && str[str.length() - 1] == '}') {
|
||||
if (recursion <= 1 && str_starts_with(str, "${") && str.back() == '}') {
|
||||
if (deprecated) {
|
||||
warningstream << "Deprecated use of recursive resolution syntax in metadata: ";
|
||||
safe_print_string(warningstream, str);
|
||||
@ -128,7 +128,7 @@ const std::string *SimpleMetadata::getStringRaw(const std::string &name, std::st
|
||||
return found != m_stringvars.cend() ? &found->second : nullptr;
|
||||
}
|
||||
|
||||
bool SimpleMetadata::setString(const std::string &name, const std::string &var)
|
||||
bool SimpleMetadata::setString(const std::string &name, std::string_view var)
|
||||
{
|
||||
if (var.empty()) {
|
||||
if (m_stringvars.erase(name) == 0)
|
||||
@ -137,7 +137,7 @@ bool SimpleMetadata::setString(const std::string &name, const std::string &var)
|
||||
StringMap::iterator it = m_stringvars.find(name);
|
||||
if (it != m_stringvars.end() && it->second == var)
|
||||
return false;
|
||||
m_stringvars[name] = var;
|
||||
m_stringvars[name].assign(var);
|
||||
}
|
||||
m_modified = true;
|
||||
return true;
|
||||
|
@ -53,7 +53,7 @@ public:
|
||||
bool getStringToRef(const std::string &name, std::string &str, u16 recursion = 0) const;
|
||||
|
||||
// Returns whether the metadata was (potentially) changed.
|
||||
virtual bool setString(const std::string &name, const std::string &var) = 0;
|
||||
virtual bool setString(const std::string &name, std::string_view var) = 0;
|
||||
|
||||
inline bool removeString(const std::string &name) { return setString(name, ""); }
|
||||
|
||||
@ -89,7 +89,7 @@ public:
|
||||
|
||||
size_t size() const;
|
||||
bool contains(const std::string &name) const override;
|
||||
virtual bool setString(const std::string &name, const std::string &var) override;
|
||||
virtual bool setString(const std::string &name, std::string_view var) override;
|
||||
const StringMap &getStrings(StringMap *) const override final;
|
||||
const std::vector<std::string> &getKeys(std::vector<std::string> *place)
|
||||
const override final;
|
||||
|
@ -1651,10 +1651,8 @@ void Client::handleCommand_MediaPush(NetworkPacket *pkt)
|
||||
std::string computed_hash;
|
||||
{
|
||||
SHA1 ctx;
|
||||
ctx.addBytes(filedata.c_str(), filedata.size());
|
||||
unsigned char *buf = ctx.getDigest();
|
||||
computed_hash.assign((char*) buf, 20);
|
||||
free(buf);
|
||||
ctx.addBytes(filedata);
|
||||
computed_hash = ctx.getDigest();
|
||||
}
|
||||
if (raw_hash != computed_hash) {
|
||||
verbosestream << "Hash of file data mismatches, ignoring." << std::endl;
|
||||
|
@ -99,7 +99,7 @@ NetworkPacket& NetworkPacket::operator>>(std::string& dst)
|
||||
return *this;
|
||||
}
|
||||
|
||||
NetworkPacket& NetworkPacket::operator<<(const std::string &src)
|
||||
NetworkPacket& NetworkPacket::operator<<(std::string_view src)
|
||||
{
|
||||
if (src.size() > STRING_MAX_LEN) {
|
||||
throw PacketError("String too long");
|
||||
@ -109,12 +109,12 @@ NetworkPacket& NetworkPacket::operator<<(const std::string &src)
|
||||
|
||||
*this << msgsize;
|
||||
|
||||
putRawString(src.c_str(), (u32)msgsize);
|
||||
putRawString(src.data(), (u32)msgsize);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void NetworkPacket::putLongString(const std::string &src)
|
||||
void NetworkPacket::putLongString(std::string_view src)
|
||||
{
|
||||
if (src.size() > LONG_STRING_MAX_LEN) {
|
||||
throw PacketError("String too long");
|
||||
@ -124,7 +124,7 @@ void NetworkPacket::putLongString(const std::string &src)
|
||||
|
||||
*this << msgsize;
|
||||
|
||||
putRawString(src.c_str(), msgsize);
|
||||
putRawString(src.data(), msgsize);
|
||||
}
|
||||
|
||||
static constexpr bool NEED_SURROGATE_CODING = sizeof(wchar_t) > 2;
|
||||
@ -160,7 +160,7 @@ NetworkPacket& NetworkPacket::operator>>(std::wstring& dst)
|
||||
return *this;
|
||||
}
|
||||
|
||||
NetworkPacket& NetworkPacket::operator<<(const std::wstring &src)
|
||||
NetworkPacket& NetworkPacket::operator<<(std::wstring_view src)
|
||||
{
|
||||
if (src.size() > WIDE_STRING_MAX_LEN) {
|
||||
throw PacketError("String too long");
|
||||
|
@ -55,18 +55,18 @@ public:
|
||||
const char *getString(u32 from_offset) const;
|
||||
// major difference to putCString(): doesn't write len into the buffer
|
||||
void putRawString(const char *src, u32 len);
|
||||
void putRawString(const std::string &src)
|
||||
void putRawString(std::string_view src)
|
||||
{
|
||||
putRawString(src.c_str(), src.size());
|
||||
putRawString(src.data(), src.size());
|
||||
}
|
||||
|
||||
NetworkPacket &operator>>(std::string &dst);
|
||||
NetworkPacket &operator<<(const std::string &src);
|
||||
NetworkPacket &operator<<(std::string_view src);
|
||||
|
||||
void putLongString(const std::string &src);
|
||||
void putLongString(std::string_view src);
|
||||
|
||||
NetworkPacket &operator>>(std::wstring &dst);
|
||||
NetworkPacket &operator<<(const std::wstring &src);
|
||||
NetworkPacket &operator<<(std::wstring_view src);
|
||||
|
||||
std::string readLongString();
|
||||
|
||||
|
@ -1142,17 +1142,16 @@ bool NodeDefManager::getIds(const std::string &name,
|
||||
std::vector<content_t> &result) const
|
||||
{
|
||||
//TimeTaker t("getIds", NULL, PRECISION_MICRO);
|
||||
if (name.substr(0,6) != "group:") {
|
||||
if (!str_starts_with(name, "group:")) {
|
||||
content_t id = CONTENT_IGNORE;
|
||||
bool exists = getId(name, id);
|
||||
if (exists)
|
||||
result.push_back(id);
|
||||
return exists;
|
||||
}
|
||||
std::string group = name.substr(6);
|
||||
|
||||
std::unordered_map<std::string, std::vector<content_t>>::const_iterator
|
||||
i = m_group_to_items.find(group);
|
||||
std::string group = name.substr(6);
|
||||
auto i = m_group_to_items.find(group);
|
||||
if (i == m_group_to_items.end())
|
||||
return true;
|
||||
|
||||
@ -1847,7 +1846,7 @@ bool NodeResolver::getIdsFromNrBacklog(std::vector<content_t> *result_out,
|
||||
content_t c;
|
||||
std::string &name = m_nodenames[m_nodenames_idx++];
|
||||
|
||||
if (name.substr(0,6) != "group:") {
|
||||
if (!str_starts_with(name, "group:")) {
|
||||
if (m_ndef->getId(name, c)) {
|
||||
result_out->push_back(c);
|
||||
} else if (all_required) {
|
||||
|
@ -20,6 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#pragma once
|
||||
|
||||
#include <unordered_set>
|
||||
#include <map>
|
||||
#include "metadata.h"
|
||||
|
||||
/*
|
||||
|
@ -832,7 +832,7 @@ static bool open_uri(const std::string &uri)
|
||||
|
||||
bool open_url(const std::string &url)
|
||||
{
|
||||
if (url.substr(0, 7) != "http://" && url.substr(0, 8) != "https://") {
|
||||
if (!str_starts_with(url, "http://") && !str_starts_with(url, "https://")) {
|
||||
errorstream << "Unable to open browser as URL is missing schema: " << url << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
@ -1664,7 +1664,7 @@ Pointabilities read_pointabilities(lua_State *L, int index)
|
||||
std::string name = luaL_checkstring(L, -2);
|
||||
|
||||
// handle groups
|
||||
if(std::string_view(name).substr(0,6)=="group:") {
|
||||
if (str_starts_with(name, "group:")) {
|
||||
pointabilities.node_groups[name.substr(6)] = read_pointability_type(L, -1);
|
||||
} else {
|
||||
pointabilities.nodes[name] = read_pointability_type(L, -1);
|
||||
@ -1685,7 +1685,7 @@ Pointabilities read_pointabilities(lua_State *L, int index)
|
||||
std::string name = luaL_checkstring(L, -2);
|
||||
|
||||
// handle groups
|
||||
if(std::string_view(name).substr(0,6)=="group:") {
|
||||
if (str_starts_with(name, "group:")) {
|
||||
pointabilities.object_groups[name.substr(6)] = read_pointability_type(L, -1);
|
||||
} else {
|
||||
pointabilities.objects[name] = read_pointability_type(L, -1);
|
||||
|
@ -25,6 +25,7 @@ extern "C" {
|
||||
#include <cmath>
|
||||
#include <irr_v2d.h>
|
||||
#include <irr_v3d.h>
|
||||
#include <string_view>
|
||||
#include "c_converter.h"
|
||||
#include "c_types.h"
|
||||
|
||||
@ -78,11 +79,16 @@ v3f LuaHelper::readParam(lua_State *L, int index)
|
||||
}
|
||||
|
||||
template <>
|
||||
std::string LuaHelper::readParam(lua_State *L, int index)
|
||||
std::string_view LuaHelper::readParam(lua_State *L, int index)
|
||||
{
|
||||
size_t length;
|
||||
std::string result;
|
||||
const char *str = luaL_checklstring(L, index, &length);
|
||||
result.assign(str, length);
|
||||
return result;
|
||||
return std::string_view(str, length);
|
||||
}
|
||||
|
||||
template <>
|
||||
std::string LuaHelper::readParam(lua_State *L, int index)
|
||||
{
|
||||
auto sv = readParam<std::string_view>(L, index);
|
||||
return std::string(sv); // a copy
|
||||
}
|
||||
|
@ -19,6 +19,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string_view>
|
||||
|
||||
extern "C" {
|
||||
#include <lua.h>
|
||||
}
|
||||
@ -27,23 +29,22 @@ class LuaHelper
|
||||
{
|
||||
protected:
|
||||
/**
|
||||
* Read a value using a template type T from Lua State L and index
|
||||
*
|
||||
* Read a value using a template type T from Lua state L at index
|
||||
*
|
||||
* @tparam T type to read from Lua
|
||||
* @param L Lua state
|
||||
* @param index Lua Index to read
|
||||
* @param index Lua index to read
|
||||
* @return read value from Lua
|
||||
*/
|
||||
template <typename T>
|
||||
static T readParam(lua_State *L, int index);
|
||||
|
||||
/**
|
||||
* Read a value using a template type T from Lua State L and index
|
||||
* Read a value using a template type T from Lua state L at index
|
||||
*
|
||||
* @tparam T type to read from Lua
|
||||
* @param L Lua state
|
||||
* @param index Lua Index to read
|
||||
* @param index Lua index to read
|
||||
* @param default_value default value to apply if nil
|
||||
* @return read value from Lua or default value if nil
|
||||
*/
|
||||
@ -53,3 +54,18 @@ protected:
|
||||
return lua_isnoneornil(L, index) ? default_value : readParam<T>(L, index);
|
||||
}
|
||||
};
|
||||
|
||||
// (only declared for documentation purposes:)
|
||||
|
||||
/**
|
||||
* Read a string from Lua state L at index without copying it.
|
||||
*
|
||||
* Note that the returned string view is only valid as long as the value is on
|
||||
* the stack and has not been modified. Be careful.
|
||||
*
|
||||
* @param L Lua state
|
||||
* @param index Lua index to read
|
||||
* @return string view
|
||||
*/
|
||||
template <>
|
||||
std::string_view LuaHelper::readParam(lua_State *L, int index);
|
||||
|
@ -163,6 +163,9 @@ int LuaItemStack::l_get_metadata(lua_State *L)
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
LuaItemStack *o = checkObject<LuaItemStack>(L, 1);
|
||||
ItemStack &item = o->m_stack;
|
||||
|
||||
log_deprecated(L, "ItemStack:get_metadata is deprecated", 1, true);
|
||||
|
||||
const std::string &value = item.metadata.getString("");
|
||||
lua_pushlstring(L, value.c_str(), value.size());
|
||||
return 1;
|
||||
@ -176,6 +179,8 @@ int LuaItemStack::l_set_metadata(lua_State *L)
|
||||
LuaItemStack *o = checkObject<LuaItemStack>(L, 1);
|
||||
ItemStack &item = o->m_stack;
|
||||
|
||||
log_deprecated(L, "ItemStack:set_metadata is deprecated", 1, true);
|
||||
|
||||
size_t len = 0;
|
||||
const char *ptr = luaL_checklstring(L, 2, &len);
|
||||
item.metadata.setString("", std::string(ptr, len));
|
||||
|
@ -115,9 +115,7 @@ int MetaDataRef::l_set_string(lua_State *L)
|
||||
|
||||
MetaDataRef *ref = checkAnyMetadata(L, 1);
|
||||
std::string name = luaL_checkstring(L, 2);
|
||||
size_t len = 0;
|
||||
const char *s = lua_tolstring(L, 3, &len);
|
||||
std::string str(s, len);
|
||||
auto str = readParam<std::string_view>(L, 3);
|
||||
|
||||
IMetadata *meta = ref->getmeta(!str.empty());
|
||||
if (meta != NULL && meta->setString(name, str))
|
||||
@ -300,9 +298,8 @@ bool MetaDataRef::handleFromTable(lua_State *L, int table, IMetadata *meta)
|
||||
while (lua_next(L, fieldstable) != 0) {
|
||||
// key at index -2 and value at index -1
|
||||
std::string name = readParam<std::string>(L, -2);
|
||||
size_t cl;
|
||||
const char *cs = lua_tolstring(L, -1, &cl);
|
||||
meta->setString(name, std::string(cs, cl));
|
||||
auto value = readParam<std::string_view>(L, -1);
|
||||
meta->setString(name, value);
|
||||
lua_pop(L, 1); // Remove value, keep key for next iteration
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
|
@ -318,8 +318,7 @@ int ModApiUtil::l_compress(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
|
||||
size_t size;
|
||||
const char *data = luaL_checklstring(L, 1, &size);
|
||||
auto data = readParam<std::string_view>(L, 1);
|
||||
|
||||
LuaCompressMethod method = get_compress_method(L, 2);
|
||||
|
||||
@ -330,13 +329,13 @@ int ModApiUtil::l_compress(lua_State *L)
|
||||
if (!lua_isnoneornil(L, 3))
|
||||
level = readParam<int>(L, 3);
|
||||
|
||||
compressZlib(reinterpret_cast<const u8 *>(data), size, os, level);
|
||||
compressZlib(data, os, level);
|
||||
} else if (method == LUA_COMPRESS_METHOD_ZSTD) {
|
||||
int level = ZSTD_CLEVEL_DEFAULT;
|
||||
if (!lua_isnoneornil(L, 3))
|
||||
level = readParam<int>(L, 3);
|
||||
|
||||
compressZstd(reinterpret_cast<const u8 *>(data), size, os, level);
|
||||
compressZstd(data, os, level);
|
||||
}
|
||||
|
||||
std::string out = os.str();
|
||||
@ -350,12 +349,12 @@ int ModApiUtil::l_decompress(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
|
||||
size_t size;
|
||||
const char *data = luaL_checklstring(L, 1, &size);
|
||||
auto data = readParam<std::string_view>(L, 1);
|
||||
|
||||
LuaCompressMethod method = get_compress_method(L, 2);
|
||||
|
||||
std::istringstream is(std::string(data, size), std::ios_base::binary);
|
||||
// FIXME: zero copy possible in c++26 or with custom rdbuf
|
||||
std::istringstream is(std::string(data), std::ios_base::binary);
|
||||
std::ostringstream os(std::ios_base::binary);
|
||||
|
||||
if (method == LUA_COMPRESS_METHOD_DEFLATE) {
|
||||
@ -375,10 +374,9 @@ int ModApiUtil::l_encode_base64(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
|
||||
size_t size;
|
||||
const char *data = luaL_checklstring(L, 1, &size);
|
||||
auto data = readParam<std::string_view>(L, 1);
|
||||
|
||||
std::string out = base64_encode((const unsigned char *)(data), size);
|
||||
std::string out = base64_encode(data);
|
||||
|
||||
lua_pushlstring(L, out.data(), out.size());
|
||||
return 1;
|
||||
@ -389,9 +387,7 @@ int ModApiUtil::l_decode_base64(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
|
||||
size_t size;
|
||||
const char *d = luaL_checklstring(L, 1, &size);
|
||||
const std::string data = std::string(d, size);
|
||||
auto data = readParam<std::string_view>(L, 1);
|
||||
|
||||
if (!base64_is_valid(data)) {
|
||||
lua_pushnil(L);
|
||||
@ -487,12 +483,11 @@ int ModApiUtil::l_safe_file_write(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
const char *path = luaL_checkstring(L, 1);
|
||||
size_t size;
|
||||
const char *content = luaL_checklstring(L, 2, &size);
|
||||
auto content = readParam<std::string_view>(L, 2);
|
||||
|
||||
CHECK_SECURE_PATH(L, path, true);
|
||||
|
||||
bool ret = fs::safeWriteToFile(path, std::string(content, size));
|
||||
bool ret = fs::safeWriteToFile(path, content);
|
||||
lua_pushboolean(L, ret);
|
||||
|
||||
return 1;
|
||||
@ -549,18 +544,16 @@ int ModApiUtil::l_get_version(lua_State *L)
|
||||
int ModApiUtil::l_sha1(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
size_t size;
|
||||
const char *data = luaL_checklstring(L, 1, &size);
|
||||
|
||||
auto data = readParam<std::string_view>(L, 1);
|
||||
bool hex = !lua_isboolean(L, 2) || !readParam<bool>(L, 2);
|
||||
|
||||
// Compute actual checksum of data
|
||||
std::string data_sha1;
|
||||
{
|
||||
SHA1 ctx;
|
||||
ctx.addBytes(data, size);
|
||||
unsigned char *data_tmpdigest = ctx.getDigest();
|
||||
data_sha1.assign((char*) data_tmpdigest, 20);
|
||||
free(data_tmpdigest);
|
||||
ctx.addBytes(data);
|
||||
data_sha1 = ctx.getDigest();
|
||||
}
|
||||
|
||||
if (hex) {
|
||||
@ -654,8 +647,8 @@ int ModApiUtil::l_urlencode(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
|
||||
const char *value = luaL_checkstring(L, 1);
|
||||
lua_pushstring(L, urlencode(value).c_str());
|
||||
auto s = readParam<std::string_view>(L, 1);
|
||||
lua_pushstring(L, urlencode(s).c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -106,11 +106,6 @@ void compressZlib(const u8 *data, size_t data_size, std::ostream &os, int level)
|
||||
}
|
||||
}
|
||||
|
||||
void compressZlib(const std::string &data, std::ostream &os, int level)
|
||||
{
|
||||
compressZlib((u8*)data.c_str(), data.size(), os, level);
|
||||
}
|
||||
|
||||
void decompressZlib(std::istream &is, std::ostream &os, size_t limit)
|
||||
{
|
||||
z_stream z;
|
||||
@ -211,7 +206,6 @@ void compressZstd(const u8 *data, size_t data_size, std::ostream &os, int level)
|
||||
// it will be destroyed when the thread ends
|
||||
thread_local std::unique_ptr<ZSTD_CStream, ZSTD_Deleter> stream(ZSTD_createCStream());
|
||||
|
||||
|
||||
ZSTD_initCStream(stream.get(), level);
|
||||
|
||||
const size_t bufsize = 16384;
|
||||
@ -247,11 +241,6 @@ void compressZstd(const u8 *data, size_t data_size, std::ostream &os, int level)
|
||||
|
||||
}
|
||||
|
||||
void compressZstd(const std::string &data, std::ostream &os, int level)
|
||||
{
|
||||
compressZstd((u8*)data.c_str(), data.size(), os, level);
|
||||
}
|
||||
|
||||
void decompressZstd(std::istream &is, std::ostream &os)
|
||||
{
|
||||
// reusing the context is recommended for performance
|
||||
@ -295,7 +284,7 @@ void decompressZstd(std::istream &is, std::ostream &os)
|
||||
}
|
||||
}
|
||||
|
||||
void compress(u8 *data, u32 size, std::ostream &os, u8 version, int level)
|
||||
void compress(const u8 *data, u32 size, std::ostream &os, u8 version, int level)
|
||||
{
|
||||
if(version >= 29)
|
||||
{
|
||||
@ -345,16 +334,6 @@ void compress(u8 *data, u32 size, std::ostream &os, u8 version, int level)
|
||||
os.write((char*)¤t_byte, 1);
|
||||
}
|
||||
|
||||
void compress(const SharedBuffer<u8> &data, std::ostream &os, u8 version, int level)
|
||||
{
|
||||
compress(*data, data.getSize(), os, version, level);
|
||||
}
|
||||
|
||||
void compress(const std::string &data, std::ostream &os, u8 version, int level)
|
||||
{
|
||||
compress((u8*)data.c_str(), data.size(), os, version, level);
|
||||
}
|
||||
|
||||
void decompress(std::istream &is, std::ostream &os, u8 version)
|
||||
{
|
||||
if(version >= 29)
|
||||
|
@ -22,7 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "irrlichttypes.h"
|
||||
#include "exceptions.h"
|
||||
#include <iostream>
|
||||
#include "util/pointer.h"
|
||||
#include <string_view>
|
||||
|
||||
/*
|
||||
Map format serialization version
|
||||
@ -83,19 +83,27 @@ inline bool ser_ver_supported(s32 v) {
|
||||
}
|
||||
|
||||
/*
|
||||
Misc. serialization functions
|
||||
Compression functions
|
||||
*/
|
||||
|
||||
void compressZlib(const u8 *data, size_t data_size, std::ostream &os, int level = -1);
|
||||
void compressZlib(const std::string &data, std::ostream &os, int level = -1);
|
||||
inline void compressZlib(std::string_view data, std::ostream &os, int level = -1)
|
||||
{
|
||||
compressZlib(reinterpret_cast<const u8*>(data.data()), data.size(), os, level);
|
||||
}
|
||||
void decompressZlib(std::istream &is, std::ostream &os, size_t limit = 0);
|
||||
|
||||
void compressZstd(const u8 *data, size_t data_size, std::ostream &os, int level = 0);
|
||||
void compressZstd(const std::string &data, std::ostream &os, int level = 0);
|
||||
inline void compressZstd(std::string_view data, std::ostream &os, int level = 0)
|
||||
{
|
||||
compressZstd(reinterpret_cast<const u8*>(data.data()), data.size(), os, level);
|
||||
}
|
||||
void decompressZstd(std::istream &is, std::ostream &os);
|
||||
|
||||
// These choose between zlib and a self-made one according to version
|
||||
void compress(const SharedBuffer<u8> &data, std::ostream &os, u8 version, int level = -1);
|
||||
void compress(const std::string &data, std::ostream &os, u8 version, int level = -1);
|
||||
void compress(u8 *data, u32 size, std::ostream &os, u8 version, int level = -1);
|
||||
// These choose between zstd, zlib and a self-made one according to version
|
||||
void compress(const u8 *data, u32 size, std::ostream &os, u8 version, int level = -1);
|
||||
inline void compress(std::string_view data, std::ostream &os, u8 version, int level = -1)
|
||||
{
|
||||
compress(reinterpret_cast<const u8*>(data.data()), data.size(), os, version, level);
|
||||
}
|
||||
void decompress(std::istream &is, std::ostream &os, u8 version);
|
||||
|
@ -2534,14 +2534,13 @@ bool Server::addMediaFile(const std::string &filename,
|
||||
}
|
||||
|
||||
SHA1 sha1;
|
||||
sha1.addBytes(filedata.c_str(), filedata.length());
|
||||
sha1.addBytes(filedata);
|
||||
|
||||
unsigned char *digest = sha1.getDigest();
|
||||
std::string sha1_base64 = base64_encode(digest, 20);
|
||||
std::string sha1_hex = hex_encode((char*) digest, 20);
|
||||
std::string digest = sha1.getDigest();
|
||||
std::string sha1_base64 = base64_encode(digest);
|
||||
std::string sha1_hex = hex_encode(digest);
|
||||
if (digest_to)
|
||||
*digest_to = std::string((char*) digest, 20);
|
||||
free(digest);
|
||||
*digest_to = digest;
|
||||
|
||||
// Put in list
|
||||
m_media[filename] = MediaInfo(filepath, sha1_base64);
|
||||
|
@ -93,8 +93,8 @@ struct MediaInfo
|
||||
// does what it says. used by some cases of dynamic media.
|
||||
bool delete_at_shutdown;
|
||||
|
||||
MediaInfo(const std::string &path_="",
|
||||
const std::string &sha1_digest_=""):
|
||||
MediaInfo(std::string_view path_ = "",
|
||||
std::string_view sha1_digest_ = ""):
|
||||
path(path_),
|
||||
sha1_digest(sha1_digest_),
|
||||
no_announce(false),
|
||||
|
@ -97,7 +97,7 @@ void SettingsHierarchy::onLayerRemoved(int layer)
|
||||
|
||||
/* Settings implementation */
|
||||
|
||||
Settings *Settings::createLayer(SettingsLayer sl, const std::string &end_tag)
|
||||
Settings *Settings::createLayer(SettingsLayer sl, std::string_view end_tag)
|
||||
{
|
||||
return new Settings(end_tag, &g_hierarchy, (int)sl);
|
||||
}
|
||||
@ -109,7 +109,7 @@ Settings *Settings::getLayer(SettingsLayer sl)
|
||||
}
|
||||
|
||||
|
||||
Settings::Settings(const std::string &end_tag, SettingsHierarchy *h,
|
||||
Settings::Settings(std::string_view end_tag, SettingsHierarchy *h,
|
||||
int settings_layer) :
|
||||
m_end_tag(end_tag),
|
||||
m_hierarchy(h),
|
||||
@ -131,7 +131,7 @@ Settings::~Settings()
|
||||
}
|
||||
|
||||
|
||||
Settings & Settings::operator = (const Settings &other)
|
||||
Settings & Settings::operator=(const Settings &other)
|
||||
{
|
||||
if (&other == this)
|
||||
return *this;
|
||||
@ -151,7 +151,7 @@ Settings & Settings::operator = (const Settings &other)
|
||||
}
|
||||
|
||||
|
||||
bool Settings::checkNameValid(const std::string &name)
|
||||
bool Settings::checkNameValid(std::string_view name)
|
||||
{
|
||||
bool valid = name.find_first_of("=\"{}#") == std::string::npos;
|
||||
if (valid)
|
||||
@ -166,7 +166,7 @@ bool Settings::checkNameValid(const std::string &name)
|
||||
}
|
||||
|
||||
|
||||
bool Settings::checkValueValid(const std::string &value)
|
||||
bool Settings::checkValueValid(std::string_view value)
|
||||
{
|
||||
if (value.substr(0, 3) == "\"\"\"" ||
|
||||
value.find("\n\"\"\"") != std::string::npos) {
|
||||
@ -407,13 +407,13 @@ bool Settings::parseCommandLine(int argc, char *argv[],
|
||||
{
|
||||
int nonopt_index = 0;
|
||||
for (int i = 1; i < argc; i++) {
|
||||
std::string arg_name = argv[i];
|
||||
std::string_view arg_name(argv[i]);
|
||||
if (arg_name.substr(0, 2) != "--") {
|
||||
// If option doesn't start with -, read it in as nonoptX
|
||||
if (arg_name[0] != '-'){
|
||||
if (arg_name[0] != '-') {
|
||||
std::string name = "nonopt";
|
||||
name += itos(nonopt_index);
|
||||
set(name, arg_name);
|
||||
set(name, std::string(arg_name));
|
||||
nonopt_index++;
|
||||
continue;
|
||||
}
|
||||
@ -422,7 +422,7 @@ bool Settings::parseCommandLine(int argc, char *argv[],
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string name = arg_name.substr(2);
|
||||
std::string name(arg_name.substr(2));
|
||||
|
||||
auto n = allowed_options.find(name);
|
||||
if (n == allowed_options.end()) {
|
||||
@ -997,7 +997,7 @@ bool Settings::remove(const std::string &name)
|
||||
SettingsParseEvent Settings::parseConfigObject(const std::string &line,
|
||||
std::string &name, std::string &value)
|
||||
{
|
||||
std::string trimmed_line = trim(line);
|
||||
auto trimmed_line = trim(line);
|
||||
|
||||
if (trimmed_line.empty())
|
||||
return SPE_NONE;
|
||||
|
@ -23,8 +23,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "util/string.h"
|
||||
#include "util/basic_macros.h"
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
|
||||
class Settings;
|
||||
@ -124,18 +124,17 @@ typedef std::unordered_map<std::string, SettingsEntry> SettingEntries;
|
||||
class Settings {
|
||||
public:
|
||||
/* These functions operate on the global hierarchy! */
|
||||
static Settings *createLayer(SettingsLayer sl, const std::string &end_tag = "");
|
||||
static Settings *createLayer(SettingsLayer sl, std::string_view end_tag = "");
|
||||
static Settings *getLayer(SettingsLayer sl);
|
||||
/**/
|
||||
|
||||
Settings(const std::string &end_tag = "") :
|
||||
Settings(std::string_view end_tag = "") :
|
||||
m_end_tag(end_tag)
|
||||
{}
|
||||
Settings(const std::string &end_tag, SettingsHierarchy *h, int settings_layer);
|
||||
Settings(std::string_view end_tag, SettingsHierarchy *h, int settings_layer);
|
||||
~Settings();
|
||||
|
||||
Settings & operator += (const Settings &other);
|
||||
Settings & operator = (const Settings &other);
|
||||
Settings & operator=(const Settings &other);
|
||||
|
||||
/***********************
|
||||
* Reading and writing *
|
||||
@ -258,8 +257,8 @@ private:
|
||||
bool updateConfigObject(std::istream &is, std::ostream &os,
|
||||
u32 tab_depth=0);
|
||||
|
||||
static bool checkNameValid(const std::string &name);
|
||||
static bool checkValueValid(const std::string &value);
|
||||
static bool checkNameValid(std::string_view name);
|
||||
static bool checkValueValid(std::string_view value);
|
||||
static std::string getMultiline(std::istream &is, size_t *num_lines=NULL);
|
||||
static void printEntry(std::ostream &os, const std::string &name,
|
||||
const SettingsEntry &entry, u32 tab_depth=0);
|
||||
@ -276,9 +275,7 @@ private:
|
||||
// For sane mutex locking when iterating
|
||||
friend class LuaSettings;
|
||||
|
||||
void updateNoLock(const Settings &other);
|
||||
void clearNoLock();
|
||||
void clearDefaultsNoLock();
|
||||
|
||||
void doCallbacks(const std::string &name) const;
|
||||
|
||||
|
@ -33,7 +33,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
*/
|
||||
struct SoundSpec
|
||||
{
|
||||
SoundSpec(const std::string &name = "", float gain = 1.0f,
|
||||
SoundSpec(std::string_view name = "", float gain = 1.0f,
|
||||
bool loop = false, float fade = 0.0f, float pitch = 1.0f,
|
||||
float start_time = 0.0f) :
|
||||
name(name), gain(gain), fade(fade), pitch(pitch), start_time(start_time),
|
||||
|
@ -57,7 +57,7 @@ void TestCompression::runTests(IGameDef *gamedef)
|
||||
|
||||
void TestCompression::testRLECompression()
|
||||
{
|
||||
SharedBuffer<u8> fromdata(4);
|
||||
Buffer<u8> fromdata(4);
|
||||
fromdata[0]=1;
|
||||
fromdata[1]=5;
|
||||
fromdata[2]=5;
|
||||
@ -106,7 +106,7 @@ void TestCompression::testRLECompression()
|
||||
|
||||
void TestCompression::testZlibCompression()
|
||||
{
|
||||
SharedBuffer<u8> fromdata(4);
|
||||
Buffer<u8> fromdata(4);
|
||||
fromdata[0]=1;
|
||||
fromdata[1]=5;
|
||||
fromdata[2]=5;
|
||||
|
@ -189,10 +189,9 @@ void TestMapSettingsManager::testMapSettingsManager()
|
||||
SHA1 ctx;
|
||||
std::string metafile_contents;
|
||||
UASSERT(fs::ReadFile(test_mapmeta_path, metafile_contents));
|
||||
ctx.addBytes(&metafile_contents[0], metafile_contents.size());
|
||||
unsigned char *sha1_result = ctx.getDigest();
|
||||
int resultdiff = memcmp(sha1_result, expected_contents_hash, 20);
|
||||
free(sha1_result);
|
||||
ctx.addBytes(metafile_contents);
|
||||
std::string sha1_result = ctx.getDigest();
|
||||
int resultdiff = memcmp(sha1_result.data(), expected_contents_hash, 20);
|
||||
|
||||
UASSERT(!resultdiff);
|
||||
#endif
|
||||
|
@ -240,20 +240,26 @@ void TestUtilities::testPadString()
|
||||
|
||||
void TestUtilities::testStartsWith()
|
||||
{
|
||||
UASSERT(str_starts_with(std::string(), std::string()) == true);
|
||||
std::string the("the");
|
||||
UASSERT(str_starts_with(std::string(), "") == true);
|
||||
UASSERT(str_starts_with(std::string("the sharp pickaxe"),
|
||||
std::string()) == true);
|
||||
UASSERT(str_starts_with(std::string("the sharp pickaxe"),
|
||||
std::string("the")) == true);
|
||||
std::string_view(the)) == true);
|
||||
UASSERT(str_starts_with(std::string("the sharp pickaxe"),
|
||||
std::string("The")) == false);
|
||||
UASSERT(str_starts_with(std::string("the sharp pickaxe"),
|
||||
std::string("The"), true) == true);
|
||||
UASSERT(str_starts_with(std::string("T"), std::string("The")) == false);
|
||||
UASSERT(str_starts_with(std::string("T"), "The") == false);
|
||||
}
|
||||
|
||||
void TestUtilities::testStrEqual()
|
||||
{
|
||||
std::string foo("foo");
|
||||
UASSERT(str_equal(foo, std::string_view(foo)));
|
||||
UASSERT(!str_equal(foo, std::string("bar")));
|
||||
UASSERT(str_equal(std::string_view(foo), std::string_view(foo)));
|
||||
UASSERT(str_equal(std::wstring(L"FOO"), std::wstring(L"foo"), true));
|
||||
UASSERT(str_equal(utf8_to_wide("abc"), utf8_to_wide("abc")));
|
||||
UASSERT(str_equal(utf8_to_wide("ABC"), utf8_to_wide("abc"), true));
|
||||
}
|
||||
@ -629,14 +635,14 @@ void TestUtilities::testBase64()
|
||||
|
||||
void TestUtilities::testSanitizeDirName()
|
||||
{
|
||||
UASSERT(sanitizeDirName("a", "~") == "a");
|
||||
UASSERT(sanitizeDirName(" ", "~") == "__");
|
||||
UASSERT(sanitizeDirName(" a ", "~") == "_a_");
|
||||
UASSERT(sanitizeDirName("COM1", "~") == "~COM1");
|
||||
UASSERT(sanitizeDirName("COM1", ":") == "_COM1");
|
||||
UASSERT(sanitizeDirName("cOm\u00B2", "~") == "~cOm\u00B2");
|
||||
UASSERT(sanitizeDirName("cOnIn$", "~") == "~cOnIn$");
|
||||
UASSERT(sanitizeDirName(" cOnIn$ ", "~") == "_cOnIn$_");
|
||||
UASSERTEQ(auto, sanitizeDirName("a", "~"), "a");
|
||||
UASSERTEQ(auto, sanitizeDirName(" ", "~"), "__");
|
||||
UASSERTEQ(auto, sanitizeDirName(" a ", "~"), "_a_");
|
||||
UASSERTEQ(auto, sanitizeDirName("COM1", "~"), "~COM1");
|
||||
UASSERTEQ(auto, sanitizeDirName("COM1", ":"), "_COM1");
|
||||
UASSERTEQ(auto, sanitizeDirName("cOm\u00B2", "~"), "~cOm\u00B2");
|
||||
UASSERTEQ(auto, sanitizeDirName("cOnIn$", "~"), "~cOnIn$");
|
||||
UASSERTEQ(auto, sanitizeDirName(" cOnIn$ ", "~"), "_cOnIn$_");
|
||||
}
|
||||
|
||||
template <typename F, typename C>
|
||||
|
@ -39,10 +39,9 @@ std::string translate_password(const std::string &name,
|
||||
|
||||
std::string slt = name + password;
|
||||
SHA1 sha1;
|
||||
sha1.addBytes(slt.c_str(), slt.length());
|
||||
unsigned char *digest = sha1.getDigest();
|
||||
std::string pwd = base64_encode(digest, 20);
|
||||
free(digest);
|
||||
sha1.addBytes(slt);
|
||||
std::string digest = sha1.getDigest();
|
||||
std::string pwd = base64_encode(digest);
|
||||
return pwd;
|
||||
}
|
||||
|
||||
@ -112,8 +111,8 @@ std::string encode_srp_verifier(const std::string &verifier,
|
||||
{
|
||||
std::ostringstream ret_str;
|
||||
ret_str << "#1#"
|
||||
<< base64_encode((unsigned char *)salt.c_str(), salt.size()) << "#"
|
||||
<< base64_encode((unsigned char *)verifier.c_str(), verifier.size());
|
||||
<< base64_encode(salt) << "#"
|
||||
<< base64_encode(verifier);
|
||||
return ret_str.str();
|
||||
}
|
||||
|
||||
|
@ -45,15 +45,15 @@ static inline bool is_base64(unsigned char c)
|
||||
|| c == '+' || c == '/';
|
||||
}
|
||||
|
||||
bool base64_is_valid(std::string const& s)
|
||||
bool base64_is_valid(std::string_view s)
|
||||
{
|
||||
size_t i = 0;
|
||||
for (; i < s.size(); ++i)
|
||||
if (!is_base64(s[i]))
|
||||
break;
|
||||
unsigned char padding = 3 - ((i + 3) % 4);
|
||||
if ((padding == 1 && base64_chars_padding_1.find(s[i - 1]) == std::string::npos)
|
||||
|| (padding == 2 && base64_chars_padding_2.find(s[i - 1]) == std::string::npos)
|
||||
if ((padding == 1 && base64_chars_padding_1.find(s[i - 1]) == s.npos)
|
||||
|| (padding == 2 && base64_chars_padding_2.find(s[i - 1]) == s.npos)
|
||||
|| padding == 3)
|
||||
return false;
|
||||
int actual_padding = s.size() - i;
|
||||
@ -69,8 +69,14 @@ bool base64_is_valid(std::string const& s)
|
||||
return padding == actual_padding;
|
||||
}
|
||||
|
||||
std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) {
|
||||
std::string base64_encode(std::string_view s)
|
||||
{
|
||||
const unsigned char *bytes_to_encode = reinterpret_cast<const unsigned char*>(s.data());
|
||||
size_t in_len = s.size();
|
||||
|
||||
std::string ret;
|
||||
ret.reserve(in_len + in_len / 3);
|
||||
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
unsigned char char_array_3[3];
|
||||
@ -110,16 +116,17 @@ std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
std::string base64_decode(std::string const& encoded_string) {
|
||||
std::string base64_decode(std::string_view encoded_string)
|
||||
{
|
||||
int in_len = encoded_string.size();
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
int in_ = 0;
|
||||
unsigned char char_array_4[4], char_array_3[3];
|
||||
std::string ret;
|
||||
ret.reserve(in_len / 4 * 3);
|
||||
|
||||
while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
|
||||
char_array_4[i++] = encoded_string[in_]; in_++;
|
||||
|
@ -29,7 +29,8 @@ René Nyffenegger rene.nyffenegger@adp-gmbh.ch
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
bool base64_is_valid(std::string const& s);
|
||||
std::string base64_encode(unsigned char const* , unsigned int len);
|
||||
std::string base64_decode(std::string const& s);
|
||||
bool base64_is_valid(std::string_view s);
|
||||
std::string base64_encode(std::string_view s);
|
||||
std::string base64_decode(std::string_view s);
|
||||
|
@ -20,6 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
static const char hex_chars[] = "0123456789abcdef";
|
||||
|
||||
@ -41,9 +42,9 @@ static inline std::string hex_encode(const char *data, unsigned int data_size)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline std::string hex_encode(const std::string &data)
|
||||
static inline std::string hex_encode(std::string_view data)
|
||||
{
|
||||
return hex_encode(data.c_str(), data.size());
|
||||
return hex_encode(data.data(), data.size());
|
||||
}
|
||||
|
||||
static inline bool hex_digit_decode(char hexdigit, unsigned char &value)
|
||||
|
@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "debug.h" // For assert()
|
||||
#include <cstring>
|
||||
#include <memory> // std::shared_ptr
|
||||
#include <string_view>
|
||||
|
||||
|
||||
template<typename T> class ConstSharedPtr {
|
||||
@ -133,6 +134,13 @@ public:
|
||||
return m_size;
|
||||
}
|
||||
|
||||
operator std::string_view() const
|
||||
{
|
||||
if (!data)
|
||||
return std::string_view();
|
||||
return std::string_view(reinterpret_cast<char*>(data), m_size);
|
||||
}
|
||||
|
||||
private:
|
||||
void drop()
|
||||
{
|
||||
|
@ -34,7 +34,7 @@ FloatType g_serialize_f32_type = FLOATTYPE_UNKNOWN;
|
||||
//// String
|
||||
////
|
||||
|
||||
std::string serializeString16(const std::string &plain)
|
||||
std::string serializeString16(std::string_view plain)
|
||||
{
|
||||
std::string s;
|
||||
char buf[2];
|
||||
@ -76,7 +76,7 @@ std::string deSerializeString16(std::istream &is)
|
||||
//// Long String
|
||||
////
|
||||
|
||||
std::string serializeString32(const std::string &plain)
|
||||
std::string serializeString32(std::string_view plain)
|
||||
{
|
||||
std::string s;
|
||||
char buf[4];
|
||||
@ -122,7 +122,7 @@ std::string deSerializeString32(std::istream &is)
|
||||
//// JSON-like strings
|
||||
////
|
||||
|
||||
std::string serializeJsonString(const std::string &plain)
|
||||
std::string serializeJsonString(std::string_view plain)
|
||||
{
|
||||
std::string tmp;
|
||||
|
||||
@ -263,13 +263,13 @@ std::string deSerializeJsonString(std::istream &is)
|
||||
return tmp;
|
||||
}
|
||||
|
||||
std::string serializeJsonStringIfNeeded(const std::string &s)
|
||||
std::string serializeJsonStringIfNeeded(std::string_view s)
|
||||
{
|
||||
for (size_t i = 0; i < s.size(); ++i) {
|
||||
if (s[i] <= 0x1f || s[i] >= 0x7f || s[i] == ' ' || s[i] == '\"')
|
||||
return serializeJsonString(s);
|
||||
}
|
||||
return s;
|
||||
return std::string(s);
|
||||
}
|
||||
|
||||
std::string deSerializeJsonStringIfNeeded(std::istream &is)
|
||||
|
@ -41,7 +41,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include <cstring> // for memcpy
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <string_view>
|
||||
|
||||
#define FIXEDPOINT_FACTOR 1000.0f
|
||||
|
||||
@ -450,26 +450,26 @@ inline v3f clampToF1000(v3f v)
|
||||
}
|
||||
|
||||
// Creates a string with the length as the first two bytes
|
||||
std::string serializeString16(const std::string &plain);
|
||||
std::string serializeString16(std::string_view plain);
|
||||
|
||||
// Reads a string with the length as the first two bytes
|
||||
std::string deSerializeString16(std::istream &is);
|
||||
|
||||
// Creates a string with the length as the first four bytes
|
||||
std::string serializeString32(const std::string &plain);
|
||||
std::string serializeString32(std::string_view plain);
|
||||
|
||||
// Reads a string with the length as the first four bytes
|
||||
std::string deSerializeString32(std::istream &is);
|
||||
|
||||
// Creates a string encoded in JSON format (almost equivalent to a C string literal)
|
||||
std::string serializeJsonString(const std::string &plain);
|
||||
std::string serializeJsonString(std::string_view plain);
|
||||
|
||||
// Reads a string encoded in JSON format
|
||||
std::string deSerializeJsonString(std::istream &is);
|
||||
|
||||
// If the string contains spaces, quotes or control characters, encodes as JSON.
|
||||
// Else returns the string unmodified.
|
||||
std::string serializeJsonStringIfNeeded(const std::string &s);
|
||||
std::string serializeJsonStringIfNeeded(std::string_view s);
|
||||
|
||||
// Parses a string serialized by serializeJsonStringIfNeeded.
|
||||
std::string deSerializeJsonStringIfNeeded(std::istream &is);
|
||||
|
@ -65,7 +65,7 @@ void SHA1::storeBigEndianUint32( unsigned char* byte, Uint32 num )
|
||||
SHA1::SHA1()
|
||||
{
|
||||
// make sure that the data type is the right size
|
||||
assert( sizeof( Uint32 ) * 5 == 20 );
|
||||
static_assert( sizeof( Uint32 ) * 5 == 20 );
|
||||
}
|
||||
|
||||
// Destructor ********************************************************
|
||||
@ -134,20 +134,19 @@ void SHA1::process()
|
||||
}
|
||||
|
||||
// addBytes **********************************************************
|
||||
void SHA1::addBytes( const char* data, int num )
|
||||
void SHA1::addBytes( const char* data, Uint32 num )
|
||||
{
|
||||
assert( data );
|
||||
assert( num >= 0 );
|
||||
// add these bytes to the running total
|
||||
size += num;
|
||||
// repeat until all data is processed
|
||||
while( num > 0 )
|
||||
{
|
||||
// number of bytes required to complete block
|
||||
int needed = 64 - unprocessedBytes;
|
||||
assert( needed > 0 );
|
||||
Uint32 needed = 64 - unprocessedBytes;
|
||||
assert( needed <= 64 );
|
||||
// number of bytes to copy (use smaller of two)
|
||||
int toCopy = (num < needed) ? num : needed;
|
||||
Uint32 toCopy = (num < needed) ? num : needed;
|
||||
// Copy the bytes
|
||||
memcpy( bytes + unprocessedBytes, data, toCopy );
|
||||
// Bytes have been copied
|
||||
@ -161,7 +160,7 @@ void SHA1::addBytes( const char* data, int num )
|
||||
}
|
||||
|
||||
// digest ************************************************************
|
||||
unsigned char* SHA1::getDigest()
|
||||
void SHA1::getDigest(unsigned char *digest)
|
||||
{
|
||||
// save the message size
|
||||
Uint32 totalBitsL = size << 3;
|
||||
@ -179,20 +178,16 @@ unsigned char* SHA1::getDigest()
|
||||
addBytes( (char*)footer, 64 - unprocessedBytes);
|
||||
assert( unprocessedBytes <= 56 );
|
||||
// how many zeros do we need
|
||||
int neededZeros = 56 - unprocessedBytes;
|
||||
Uint32 neededZeros = 56 - unprocessedBytes;
|
||||
// store file size (in bits) in big-endian format
|
||||
storeBigEndianUint32( footer + neededZeros , totalBitsH );
|
||||
storeBigEndianUint32( footer + neededZeros + 4, totalBitsL );
|
||||
// finish the final block
|
||||
addBytes( (char*)footer, neededZeros + 8 );
|
||||
// allocate memory for the digest bytes
|
||||
unsigned char* digest = (unsigned char*)malloc( 20 );
|
||||
// copy the digest bytes
|
||||
storeBigEndianUint32( digest, H0 );
|
||||
storeBigEndianUint32( digest + 4, H1 );
|
||||
storeBigEndianUint32( digest + 8, H2 );
|
||||
storeBigEndianUint32( digest + 12, H3 );
|
||||
storeBigEndianUint32( digest + 16, H4 );
|
||||
// return the digest
|
||||
return digest;
|
||||
}
|
||||
|
@ -26,7 +26,11 @@ SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
|
||||
typedef unsigned int Uint32;
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
typedef uint32_t Uint32;
|
||||
|
||||
class SHA1
|
||||
{
|
||||
@ -38,15 +42,24 @@ private:
|
||||
Uint32 H3 = 0x10325476;
|
||||
Uint32 H4 = 0xc3d2e1f0;
|
||||
unsigned char bytes[64];
|
||||
int unprocessedBytes = 0;
|
||||
Uint32 unprocessedBytes = 0;
|
||||
Uint32 size = 0;
|
||||
void process();
|
||||
|
||||
public:
|
||||
SHA1();
|
||||
~SHA1();
|
||||
void addBytes(const char *data, int num);
|
||||
unsigned char *getDigest();
|
||||
void addBytes(const char *data, Uint32 num);
|
||||
inline void addBytes(std::string_view data) {
|
||||
addBytes(data.data(), data.size());
|
||||
}
|
||||
void getDigest(unsigned char *to);
|
||||
inline std::string getDigest() {
|
||||
std::string ret(20, '\000');
|
||||
getDigest(reinterpret_cast<unsigned char*>(ret.data()));
|
||||
return ret;
|
||||
}
|
||||
|
||||
// utility methods
|
||||
static Uint32 lrot(Uint32 x, int bits);
|
||||
static void storeBigEndianUint32(unsigned char *byte, Uint32 num);
|
||||
|
@ -20,14 +20,19 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
// FIXME: convert this class to string_view
|
||||
template <typename T>
|
||||
class BasicStrfnd {
|
||||
typedef std::basic_string<T> String;
|
||||
String str;
|
||||
size_t pos;
|
||||
public:
|
||||
BasicStrfnd(const String &s) : str(s), pos(0) {}
|
||||
BasicStrfnd(const String &s) { start(s); }
|
||||
BasicStrfnd(const T *ptr) { str = ptr; pos = 0; }
|
||||
BasicStrfnd(std::basic_string_view<T> sv) { str = sv; pos = 0; }
|
||||
|
||||
void start(const String &s) { str = s; pos = 0; }
|
||||
size_t where() { return pos; }
|
||||
void to(size_t i) { pos = i; }
|
||||
|
@ -82,14 +82,14 @@ const char *DEFAULT_ENCODING = "UTF-32LE";
|
||||
const char *DEFAULT_ENCODING = "WCHAR_T";
|
||||
#endif
|
||||
|
||||
std::wstring utf8_to_wide(const std::string &input)
|
||||
std::wstring utf8_to_wide(std::string_view input)
|
||||
{
|
||||
const size_t inbuf_size = input.length();
|
||||
// maximum possible size, every character is sizeof(wchar_t) bytes
|
||||
size_t outbuf_size = input.length() * sizeof(wchar_t);
|
||||
|
||||
char *inbuf = new char[inbuf_size]; // intentionally NOT null-terminated
|
||||
memcpy(inbuf, input.c_str(), inbuf_size);
|
||||
memcpy(inbuf, input.data(), inbuf_size);
|
||||
std::wstring out;
|
||||
out.resize(outbuf_size / sizeof(wchar_t));
|
||||
|
||||
@ -110,14 +110,14 @@ std::wstring utf8_to_wide(const std::string &input)
|
||||
return out;
|
||||
}
|
||||
|
||||
std::string wide_to_utf8(const std::wstring &input)
|
||||
std::string wide_to_utf8(std::wstring_view input)
|
||||
{
|
||||
const size_t inbuf_size = input.length() * sizeof(wchar_t);
|
||||
// maximum possible size: utf-8 encodes codepoints using 1 up to 4 bytes
|
||||
size_t outbuf_size = input.length() * 4;
|
||||
|
||||
char *inbuf = new char[inbuf_size]; // intentionally NOT null-terminated
|
||||
memcpy(inbuf, input.c_str(), inbuf_size);
|
||||
memcpy(inbuf, input.data(), inbuf_size);
|
||||
std::string out;
|
||||
out.resize(outbuf_size);
|
||||
|
||||
@ -135,24 +135,24 @@ std::string wide_to_utf8(const std::wstring &input)
|
||||
|
||||
#else // _WIN32
|
||||
|
||||
std::wstring utf8_to_wide(const std::string &input)
|
||||
std::wstring utf8_to_wide(std::string_view input)
|
||||
{
|
||||
size_t outbuf_size = input.size() + 1;
|
||||
wchar_t *outbuf = new wchar_t[outbuf_size];
|
||||
memset(outbuf, 0, outbuf_size * sizeof(wchar_t));
|
||||
MultiByteToWideChar(CP_UTF8, 0, input.c_str(), input.size(),
|
||||
MultiByteToWideChar(CP_UTF8, 0, input.data(), input.size(),
|
||||
outbuf, outbuf_size);
|
||||
std::wstring out(outbuf);
|
||||
delete[] outbuf;
|
||||
return out;
|
||||
}
|
||||
|
||||
std::string wide_to_utf8(const std::wstring &input)
|
||||
std::string wide_to_utf8(std::wstring_view input)
|
||||
{
|
||||
size_t outbuf_size = (input.size() + 1) * 6;
|
||||
char *outbuf = new char[outbuf_size];
|
||||
memset(outbuf, 0, outbuf_size);
|
||||
WideCharToMultiByte(CP_UTF8, 0, input.c_str(), input.size(),
|
||||
WideCharToMultiByte(CP_UTF8, 0, input.data(), input.size(),
|
||||
outbuf, outbuf_size, NULL, NULL);
|
||||
std::string out(outbuf);
|
||||
delete[] outbuf;
|
||||
@ -162,9 +162,9 @@ std::string wide_to_utf8(const std::wstring &input)
|
||||
#endif // _WIN32
|
||||
|
||||
|
||||
std::string urlencode(const std::string &str)
|
||||
std::string urlencode(std::string_view str)
|
||||
{
|
||||
// Encodes non-unreserved URI characters by a percent sign
|
||||
// Encodes reserved URI characters by a percent sign
|
||||
// followed by two hex digits. See RFC 3986, section 2.3.
|
||||
static const char url_hex_chars[] = "0123456789ABCDEF";
|
||||
std::ostringstream oss(std::ios::binary);
|
||||
@ -180,7 +180,7 @@ std::string urlencode(const std::string &str)
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string urldecode(const std::string &str)
|
||||
std::string urldecode(std::string_view str)
|
||||
{
|
||||
// Inverse of urlencode
|
||||
std::ostringstream oss(std::ios::binary);
|
||||
@ -615,10 +615,10 @@ void str_replace(std::string &str, char from, char to)
|
||||
* before filling it again.
|
||||
*/
|
||||
|
||||
void translate_all(const std::wstring &s, size_t &i,
|
||||
static void translate_all(const std::wstring &s, size_t &i,
|
||||
Translations *translations, std::wstring &res);
|
||||
|
||||
void translate_string(const std::wstring &s, Translations *translations,
|
||||
static void translate_string(const std::wstring &s, Translations *translations,
|
||||
const std::wstring &textdomain, size_t &i, std::wstring &res)
|
||||
{
|
||||
std::wostringstream output;
|
||||
@ -732,14 +732,15 @@ void translate_string(const std::wstring &s, Translations *translations,
|
||||
res = result.str();
|
||||
}
|
||||
|
||||
void translate_all(const std::wstring &s, size_t &i,
|
||||
static void translate_all(const std::wstring &s, size_t &i,
|
||||
Translations *translations, std::wstring &res)
|
||||
{
|
||||
std::wostringstream output;
|
||||
res.clear();
|
||||
res.reserve(s.length());
|
||||
while (i < s.length()) {
|
||||
// Not an escape sequence: just add the character.
|
||||
if (s[i] != '\x1b') {
|
||||
output.put(s[i]);
|
||||
res.append(1, s[i]);
|
||||
++i;
|
||||
continue;
|
||||
}
|
||||
@ -747,7 +748,7 @@ void translate_all(const std::wstring &s, size_t &i,
|
||||
// We have an escape sequence: locate it and its data
|
||||
// It is either a single character, or it begins with '('
|
||||
// and extends up to the following ')', with '\' as an escape character.
|
||||
size_t escape_start = i;
|
||||
const size_t escape_start = i;
|
||||
++i;
|
||||
size_t start_index = i;
|
||||
size_t length;
|
||||
@ -784,14 +785,12 @@ void translate_all(const std::wstring &s, size_t &i,
|
||||
textdomain = parts[1];
|
||||
std::wstring translated;
|
||||
translate_string(s, translations, textdomain, i, translated);
|
||||
output << translated;
|
||||
res.append(translated);
|
||||
} else {
|
||||
// Another escape sequence, such as colors. Preserve it.
|
||||
output << std::wstring(s, escape_start, i - escape_start);
|
||||
res.append(&s[escape_start], i - escape_start);
|
||||
}
|
||||
}
|
||||
|
||||
res = output.str();
|
||||
}
|
||||
|
||||
// Translate string server side
|
||||
@ -813,7 +812,7 @@ std::wstring translate_string(const std::wstring &s)
|
||||
#endif
|
||||
}
|
||||
|
||||
static const std::array<std::wstring, 30> disallowed_dir_names = {
|
||||
static const std::array<std::wstring_view, 30> disallowed_dir_names = {
|
||||
// Problematic filenames from here:
|
||||
// https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file#file-and-directory-names
|
||||
// Plus undocumented values from here:
|
||||
@ -853,10 +852,10 @@ static const std::array<std::wstring, 30> disallowed_dir_names = {
|
||||
/**
|
||||
* List of characters that are blacklisted from created directories
|
||||
*/
|
||||
static const std::wstring disallowed_path_chars = L"<>:\"/\\|?*.";
|
||||
static const std::wstring_view disallowed_path_chars = L"<>:\"/\\|?*.";
|
||||
|
||||
|
||||
std::string sanitizeDirName(const std::string &str, const std::string &optional_prefix)
|
||||
std::string sanitizeDirName(std::string_view str, std::string_view optional_prefix)
|
||||
{
|
||||
std::wstring safe_name = utf8_to_wide(str);
|
||||
|
||||
@ -897,7 +896,7 @@ std::string sanitizeDirName(const std::string &str, const std::string &optional_
|
||||
}
|
||||
|
||||
|
||||
void safe_print_string(std::ostream &os, const std::string &str)
|
||||
void safe_print_string(std::ostream &os, std::string_view str)
|
||||
{
|
||||
std::ostream::fmtflags flags = os.flags();
|
||||
os << std::hex;
|
||||
@ -913,7 +912,7 @@ void safe_print_string(std::ostream &os, const std::string &str)
|
||||
}
|
||||
|
||||
|
||||
v3f str_to_v3f(const std::string &str)
|
||||
v3f str_to_v3f(std::string_view str)
|
||||
{
|
||||
v3f value;
|
||||
Strfnd f(str);
|
||||
|
@ -23,10 +23,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "irrString.h"
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
#include <limits>
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <cctype>
|
||||
@ -76,15 +76,18 @@ struct FlagDesc {
|
||||
|
||||
// Try to avoid converting between wide and UTF-8 unless you need to
|
||||
// input/output stuff via Irrlicht
|
||||
std::wstring utf8_to_wide(const std::string &input);
|
||||
std::string wide_to_utf8(const std::wstring &input);
|
||||
std::wstring utf8_to_wide(std::string_view input);
|
||||
std::string wide_to_utf8(std::wstring_view input);
|
||||
|
||||
std::string urlencode(std::string_view str);
|
||||
std::string urldecode(std::string_view str);
|
||||
|
||||
std::string urlencode(const std::string &str);
|
||||
std::string urldecode(const std::string &str);
|
||||
u32 readFlagString(std::string str, const FlagDesc *flagdesc, u32 *flagmask);
|
||||
std::string writeFlagString(u32 flags, const FlagDesc *flagdesc, u32 flagmask);
|
||||
|
||||
size_t mystrlcpy(char *dst, const char *src, size_t size) noexcept;
|
||||
char *mystrtok_r(char *s, const char *sep, char **lasts) noexcept;
|
||||
|
||||
u64 read_seed(const char *str);
|
||||
bool parseColorString(const std::string &value, video::SColor &color, bool quiet,
|
||||
unsigned char default_alpha = 0xff);
|
||||
@ -115,23 +118,32 @@ inline std::string padStringRight(std::string str, size_t len)
|
||||
*
|
||||
* @return If no end could be removed then "" is returned.
|
||||
*/
|
||||
inline std::string removeStringEnd(const std::string &str,
|
||||
inline std::string_view removeStringEnd(std::string_view str,
|
||||
const char *ends[])
|
||||
{
|
||||
const char **p = ends;
|
||||
|
||||
for (; *p && (*p)[0] != '\0'; p++) {
|
||||
std::string end = *p;
|
||||
std::string_view end(*p);
|
||||
if (str.size() < end.size())
|
||||
continue;
|
||||
if (str.compare(str.size() - end.size(), end.size(), end) == 0)
|
||||
return str.substr(0, str.size() - end.size());
|
||||
}
|
||||
|
||||
return "";
|
||||
return std::string_view();
|
||||
}
|
||||
|
||||
|
||||
#define MAKE_VARIANT(_name, _t0, _t1) \
|
||||
template <typename T, typename... Args> \
|
||||
inline auto _name(_t0 arg1, _t1 arg2, Args&&... args) \
|
||||
{ \
|
||||
return (_name)(std::basic_string_view<T>(arg1), std::basic_string_view<T>(arg2), \
|
||||
std::forward<Args>(args)...); \
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check two strings for equivalence. If \p case_insensitive is true
|
||||
* then the case of the strings is ignored (default is false).
|
||||
@ -142,8 +154,8 @@ inline std::string removeStringEnd(const std::string &str,
|
||||
* @return true if the strings match
|
||||
*/
|
||||
template <typename T>
|
||||
inline bool str_equal(const std::basic_string<T> &s1,
|
||||
const std::basic_string<T> &s2,
|
||||
inline bool str_equal(std::basic_string_view<T> s1,
|
||||
std::basic_string_view<T> s2,
|
||||
bool case_insensitive = false)
|
||||
{
|
||||
if (!case_insensitive)
|
||||
@ -159,6 +171,16 @@ inline bool str_equal(const std::basic_string<T> &s1,
|
||||
return true;
|
||||
}
|
||||
|
||||
// For some reason an std::string will not implicitly get converted
|
||||
// to an std::basic_string_view<char> in the template case above, so we need
|
||||
// these three wrappers. It works if you take out the template parameters.
|
||||
// see also <https://stackoverflow.com/questions/68380141/>
|
||||
MAKE_VARIANT(str_equal, const std::basic_string<T> &, const std::basic_string<T> &)
|
||||
|
||||
MAKE_VARIANT(str_equal, std::basic_string_view<T>, const std::basic_string<T> &)
|
||||
|
||||
MAKE_VARIANT(str_equal, const std::basic_string<T> &, std::basic_string_view<T>)
|
||||
|
||||
|
||||
/**
|
||||
* Check whether \p str begins with the string prefix. If \p case_insensitive
|
||||
@ -171,8 +193,8 @@ inline bool str_equal(const std::basic_string<T> &s1,
|
||||
* @return true if the str begins with prefix
|
||||
*/
|
||||
template <typename T>
|
||||
inline bool str_starts_with(const std::basic_string<T> &str,
|
||||
const std::basic_string<T> &prefix,
|
||||
inline bool str_starts_with(std::basic_string_view<T> str,
|
||||
std::basic_string_view<T> prefix,
|
||||
bool case_insensitive = false)
|
||||
{
|
||||
if (str.size() < prefix.size())
|
||||
@ -187,24 +209,17 @@ inline bool str_starts_with(const std::basic_string<T> &str,
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether \p str begins with the string prefix. If \p case_insensitive
|
||||
* is true then the check is case insensitve (default is false; i.e. case is
|
||||
* significant).
|
||||
*
|
||||
* @param str
|
||||
* @param prefix
|
||||
* @param case_insensitive
|
||||
* @return true if the str begins with prefix
|
||||
*/
|
||||
template <typename T>
|
||||
inline bool str_starts_with(const std::basic_string<T> &str,
|
||||
const T *prefix,
|
||||
bool case_insensitive = false)
|
||||
{
|
||||
return str_starts_with(str, std::basic_string<T>(prefix),
|
||||
case_insensitive);
|
||||
}
|
||||
// (same conversion issue here)
|
||||
MAKE_VARIANT(str_starts_with, const std::basic_string<T> &, const std::basic_string<T> &)
|
||||
|
||||
MAKE_VARIANT(str_starts_with, std::basic_string_view<T>, const std::basic_string<T> &)
|
||||
|
||||
MAKE_VARIANT(str_starts_with, const std::basic_string<T> &, std::basic_string_view<T>)
|
||||
|
||||
// (the same but with char pointers, only for the prefix argument)
|
||||
MAKE_VARIANT(str_starts_with, const std::basic_string<T> &, const T*)
|
||||
|
||||
MAKE_VARIANT(str_starts_with, std::basic_string_view<T>, const T*)
|
||||
|
||||
|
||||
/**
|
||||
@ -218,8 +233,8 @@ inline bool str_starts_with(const std::basic_string<T> &str,
|
||||
* @return true if the str begins with suffix
|
||||
*/
|
||||
template <typename T>
|
||||
inline bool str_ends_with(const std::basic_string<T> &str,
|
||||
const std::basic_string<T> &suffix,
|
||||
inline bool str_ends_with(std::basic_string_view<T> str,
|
||||
std::basic_string_view<T> suffix,
|
||||
bool case_insensitive = false)
|
||||
{
|
||||
if (str.size() < suffix.size())
|
||||
@ -235,25 +250,20 @@ inline bool str_ends_with(const std::basic_string<T> &str,
|
||||
return true;
|
||||
}
|
||||
|
||||
// (same conversion issue here)
|
||||
MAKE_VARIANT(str_ends_with, const std::basic_string<T> &, const std::basic_string<T> &)
|
||||
|
||||
/**
|
||||
* Check whether \p str ends with the string suffix. If \p case_insensitive
|
||||
* is true then the check is case insensitve (default is false; i.e. case is
|
||||
* significant).
|
||||
*
|
||||
* @param str
|
||||
* @param suffix
|
||||
* @param case_insensitive
|
||||
* @return true if the str begins with suffix
|
||||
*/
|
||||
template <typename T>
|
||||
inline bool str_ends_with(const std::basic_string<T> &str,
|
||||
const T *suffix,
|
||||
bool case_insensitive = false)
|
||||
{
|
||||
return str_ends_with(str, std::basic_string<T>(suffix),
|
||||
case_insensitive);
|
||||
}
|
||||
MAKE_VARIANT(str_ends_with, std::basic_string_view<T>, const std::basic_string<T> &)
|
||||
|
||||
MAKE_VARIANT(str_ends_with, const std::basic_string<T> &, std::basic_string_view<T>)
|
||||
|
||||
// (the same but with char pointers, only for the suffix argument)
|
||||
MAKE_VARIANT(str_ends_with, const std::basic_string<T> &, const T*)
|
||||
|
||||
MAKE_VARIANT(str_ends_with, std::basic_string_view<T>, const T*)
|
||||
|
||||
|
||||
#undef MAKE_VARIANT
|
||||
|
||||
|
||||
/**
|
||||
@ -282,24 +292,21 @@ inline std::vector<std::basic_string<T> > str_split(
|
||||
* @param str
|
||||
* @return A copy of \p str converted to all lowercase characters.
|
||||
*/
|
||||
inline std::string lowercase(const std::string &str)
|
||||
inline std::string lowercase(std::string_view str)
|
||||
{
|
||||
std::string s2;
|
||||
|
||||
s2.reserve(str.size());
|
||||
|
||||
for (char i : str)
|
||||
s2 += tolower(i);
|
||||
|
||||
s2.resize(str.size());
|
||||
for (size_t i = 0; i < str.size(); i++)
|
||||
s2[i] = tolower(str[i]);
|
||||
return s2;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param str
|
||||
* @return A copy of \p str with leading and trailing whitespace removed.
|
||||
* @return A view of \p str with leading and trailing whitespace removed.
|
||||
*/
|
||||
inline std::string trim(const std::string &str)
|
||||
inline std::string_view trim(std::string_view str)
|
||||
{
|
||||
size_t front = 0;
|
||||
size_t back = str.size();
|
||||
@ -313,6 +320,26 @@ inline std::string trim(const std::string &str)
|
||||
return str.substr(front, back - front);
|
||||
}
|
||||
|
||||
// If input was a temporary string keep it one to make sure patterns like
|
||||
// trim(func_that_returns_str()) are predictable regarding memory allocation
|
||||
// and don't lead to UAF. ↓ ↓ ↓
|
||||
|
||||
/**
|
||||
* @param str
|
||||
* @return A copy of \p str with leading and trailing whitespace removed.
|
||||
*/
|
||||
inline std::string trim(std::string &&str)
|
||||
{
|
||||
std::string ret(trim(std::string_view(str)));
|
||||
return ret;
|
||||
}
|
||||
|
||||
// The above declaration causes ambiguity with char pointers so we have to fix that:
|
||||
inline std::string_view trim(const char *str)
|
||||
{
|
||||
return trim(std::string_view(str));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns whether \p str should be regarded as (bool) true. Case and leading
|
||||
@ -320,7 +347,7 @@ inline std::string trim(const std::string &str)
|
||||
* true are "y", "yes", "true" and any number that is not 0.
|
||||
* @param str
|
||||
*/
|
||||
inline bool is_yes(const std::string &str)
|
||||
inline bool is_yes(std::string_view str)
|
||||
{
|
||||
std::string s2 = lowercase(trim(str));
|
||||
|
||||
@ -377,7 +404,7 @@ inline float mystof(const std::string &str)
|
||||
template <typename T>
|
||||
inline T from_string(const std::string &str)
|
||||
{
|
||||
std::stringstream tmp(str);
|
||||
std::istringstream tmp(str);
|
||||
T t;
|
||||
tmp >> t;
|
||||
return t;
|
||||
@ -386,42 +413,6 @@ inline T from_string(const std::string &str)
|
||||
/// Returns a 64-bit signed value represented by the string \p str (decimal).
|
||||
inline s64 stoi64(const std::string &str) { return from_string<s64>(str); }
|
||||
|
||||
#if __cplusplus < 201103L
|
||||
namespace std {
|
||||
|
||||
/// Returns a string representing the value \p val.
|
||||
template <typename T>
|
||||
inline string to_string(T val)
|
||||
{
|
||||
ostringstream oss;
|
||||
oss << val;
|
||||
return oss.str();
|
||||
}
|
||||
#define DEFINE_STD_TOSTRING_FLOATINGPOINT(T) \
|
||||
template <> \
|
||||
inline string to_string<T>(T val) \
|
||||
{ \
|
||||
ostringstream oss; \
|
||||
oss << std::fixed \
|
||||
<< std::setprecision(6) \
|
||||
<< val; \
|
||||
return oss.str(); \
|
||||
}
|
||||
DEFINE_STD_TOSTRING_FLOATINGPOINT(float)
|
||||
DEFINE_STD_TOSTRING_FLOATINGPOINT(double)
|
||||
DEFINE_STD_TOSTRING_FLOATINGPOINT(long double)
|
||||
|
||||
#undef DEFINE_STD_TOSTRING_FLOATINGPOINT
|
||||
|
||||
/// Returns a wide string representing the value \p val
|
||||
template <typename T>
|
||||
inline wstring to_wstring(T val)
|
||||
{
|
||||
return utf8_to_wide(to_string(val));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/// Returns a string representing the decimal value of the 32-bit value \p i.
|
||||
inline std::string itos(s32 i) { return std::to_string(i); }
|
||||
/// Returns a string representing the decimal value of the 64-bit value \p i.
|
||||
@ -443,8 +434,8 @@ inline std::string ftos(float f)
|
||||
* @param pattern The pattern to replace.
|
||||
* @param replacement What to replace the pattern with.
|
||||
*/
|
||||
inline void str_replace(std::string &str, const std::string &pattern,
|
||||
const std::string &replacement)
|
||||
inline void str_replace(std::string &str, std::string_view pattern,
|
||||
std::string_view replacement)
|
||||
{
|
||||
std::string::size_type start = str.find(pattern, 0);
|
||||
while (start != str.npos) {
|
||||
@ -454,7 +445,7 @@ inline void str_replace(std::string &str, const std::string &pattern,
|
||||
}
|
||||
|
||||
/**
|
||||
* Escapes characters [ ] \ , ; that cannot be used in formspecs
|
||||
* Escapes characters that cannot be used in formspecs
|
||||
*/
|
||||
inline void str_formspec_escape(std::string &str)
|
||||
{
|
||||
@ -486,7 +477,7 @@ void str_replace(std::string &str, char from, char to);
|
||||
*
|
||||
* @see string_allowed_blacklist()
|
||||
*/
|
||||
inline bool string_allowed(const std::string &str, const std::string &allowed_chars)
|
||||
inline bool string_allowed(std::string_view str, std::string_view allowed_chars)
|
||||
{
|
||||
return str.find_first_not_of(allowed_chars) == str.npos;
|
||||
}
|
||||
@ -502,8 +493,8 @@ inline bool string_allowed(const std::string &str, const std::string &allowed_ch
|
||||
|
||||
* @see string_allowed()
|
||||
*/
|
||||
inline bool string_allowed_blacklist(const std::string &str,
|
||||
const std::string &blacklisted_chars)
|
||||
inline bool string_allowed_blacklist(std::string_view str,
|
||||
std::string_view blacklisted_chars)
|
||||
{
|
||||
return str.find_first_of(blacklisted_chars) == str.npos;
|
||||
}
|
||||
@ -524,12 +515,12 @@ inline bool string_allowed_blacklist(const std::string &str,
|
||||
* @param row_len The row length (in characters).
|
||||
* @return A new string with the wrapping applied.
|
||||
*/
|
||||
inline std::string wrap_rows(const std::string &from,
|
||||
unsigned row_len)
|
||||
inline std::string wrap_rows(std::string_view from, unsigned row_len)
|
||||
{
|
||||
std::string to;
|
||||
to.reserve(from.size());
|
||||
|
||||
size_t character_idx = 0;
|
||||
unsigned character_idx = 0;
|
||||
for (size_t i = 0; i < from.size(); i++) {
|
||||
if (!IS_UTF8_MULTB_INNER(from[i])) {
|
||||
// Wrap string after last inner byte of char
|
||||
@ -551,6 +542,7 @@ template <typename T>
|
||||
inline std::basic_string<T> unescape_string(const std::basic_string<T> &s)
|
||||
{
|
||||
std::basic_string<T> res;
|
||||
res.reserve(s.size());
|
||||
|
||||
for (size_t i = 0; i < s.length(); i++) {
|
||||
if (s[i] == '\\') {
|
||||
@ -574,6 +566,7 @@ template <typename T>
|
||||
std::basic_string<T> unescape_enriched(const std::basic_string<T> &s)
|
||||
{
|
||||
std::basic_string<T> output;
|
||||
output.reserve(s.size());
|
||||
size_t i = 0;
|
||||
while (i < s.length()) {
|
||||
if (s[i] == '\x1b') {
|
||||
@ -646,7 +639,7 @@ inline std::wstring unescape_translate(const std::wstring &s) {
|
||||
* @return true if to_check is not empty and all characters in to_check are
|
||||
* decimal digits, otherwise false
|
||||
*/
|
||||
inline bool is_number(const std::string &to_check)
|
||||
inline bool is_number(std::string_view to_check)
|
||||
{
|
||||
for (char i : to_check)
|
||||
if (!std::isdigit(i))
|
||||
@ -720,7 +713,7 @@ inline const std::string duration_to_string(int sec)
|
||||
* @return A std::string
|
||||
*/
|
||||
inline std::string str_join(const std::vector<std::string> &list,
|
||||
const std::string &delimiter)
|
||||
std::string_view delimiter)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
bool first = true;
|
||||
@ -738,17 +731,17 @@ inline std::string str_join(const std::vector<std::string> &list,
|
||||
*/
|
||||
inline std::string stringw_to_utf8(const irr::core::stringw &input)
|
||||
{
|
||||
std::wstring str(input.c_str());
|
||||
return wide_to_utf8(str);
|
||||
std::wstring_view sv(input.c_str(), input.size());
|
||||
return wide_to_utf8(sv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an irr::core:stringw from a UTF8 std::string.
|
||||
*/
|
||||
inline irr::core::stringw utf8_to_stringw(const std::string &input)
|
||||
inline irr::core::stringw utf8_to_stringw(std::string_view input)
|
||||
{
|
||||
std::wstring str = utf8_to_wide(input);
|
||||
return irr::core::stringw(str.c_str());
|
||||
return irr::core::stringw(str.c_str(), str.size());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -757,7 +750,7 @@ inline irr::core::stringw utf8_to_stringw(const std::string &input)
|
||||
* and add a prefix to them
|
||||
* 2. Remove 'unsafe' characters from the name by replacing them with '_'
|
||||
*/
|
||||
std::string sanitizeDirName(const std::string &str, const std::string &optional_prefix);
|
||||
std::string sanitizeDirName(std::string_view str, std::string_view optional_prefix);
|
||||
|
||||
/**
|
||||
* Prints a sanitized version of a string without control characters.
|
||||
@ -765,12 +758,12 @@ std::string sanitizeDirName(const std::string &str, const std::string &optional_
|
||||
* ASCII control characters are replaced with their hex encoding in angle
|
||||
* brackets (e.g. "a\x1eb" -> "a<1e>b").
|
||||
*/
|
||||
void safe_print_string(std::ostream &os, const std::string &str);
|
||||
void safe_print_string(std::ostream &os, std::string_view str);
|
||||
|
||||
/**
|
||||
* Parses a string of form `(1, 2, 3)` to a v3f
|
||||
*
|
||||
* @param str String
|
||||
* @return
|
||||
* @param str string
|
||||
* @return float vector
|
||||
*/
|
||||
v3f str_to_v3f(const std::string &str);
|
||||
v3f str_to_v3f(std::string_view str);
|
||||
|
Loading…
Reference in New Issue
Block a user