diff --git a/resources/to-array.py b/resources/to-array.py index e1a56cfc7..ef89f9ecb 100644 --- a/resources/to-array.py +++ b/resources/to-array.py @@ -20,15 +20,30 @@ bytes_str = ', '.join([ str(ch) for ch in data ]) with open(output_cpp_path, 'w') as output_cpp_f: output_cpp_f.write(f''' #include "{output_h_path}" -const unsigned char {symbol_name}[] = {{ {bytes_str} }}; -const unsigned int {symbol_name}_size = {data_size}; + +const struct {symbol_name}Resource {symbol_name} = {{{{{{ {bytes_str} }}}}}}; ''') with open(output_h_path, 'w') as output_h_f: output_h_f.write(f''' #pragma once -extern const unsigned char {symbol_name}[]; -extern const unsigned int {symbol_name}_size; +#include +#include + +extern const struct {symbol_name}Resource +{{ + std::array data; + + std::span AsCharSpan() const + {{ + return std::span(reinterpret_cast(data.data()), data.size()); + }} + + std::span AsUcharSpan() const + {{ + return std::span(data.data(), data.size()); + }} +}} {symbol_name}; ''') def dep_escape(s): diff --git a/src/Format.cpp b/src/Format.cpp index 121c2872b..fd0d320c1 100644 --- a/src/Format.cpp +++ b/src/Format.cpp @@ -123,7 +123,7 @@ std::vector format::PixelsToPPM(PlaneAdapter> const &in } static std::unique_ptr>> readPNG( - std::vector const &data, + std::span data, // If omitted, // RGB data is returned with A=0xFF // RGBA data is returned as itself @@ -218,12 +218,12 @@ static std::unique_ptr>> readPNG( return output; } -std::unique_ptr>> format::PixelsFromPNG(std::vector const &data) +std::unique_ptr>> format::PixelsFromPNG(std::span data) { return readPNG(data, std::nullopt); } -std::unique_ptr>> format::PixelsFromPNG(std::vector const &data, RGB background) +std::unique_ptr>> format::PixelsFromPNG(std::span data, RGB background) { return readPNG(data, background); } diff --git a/src/Format.h b/src/Format.h index b406d13fb..bfdf3e542 100644 --- a/src/Format.h +++ b/src/Format.h @@ -1,5 +1,6 @@ #pragma once #include +#include #include #include "common/String.h" #include "common/Plane.h" @@ -16,8 +17,8 @@ namespace format String CleanString(String dirtyString, bool ascii, bool color, bool newlines, bool numeric = false); std::vector PixelsToPPM(PlaneAdapter> const &); std::unique_ptr> PixelsToPNG(PlaneAdapter> const &); - std::unique_ptr>> PixelsFromPNG(std::vector const &); - std::unique_ptr>> PixelsFromPNG(std::vector const &, RGB background); + std::unique_ptr>> PixelsFromPNG(std::span data); + std::unique_ptr>> PixelsFromPNG(std::span data, RGB background); void RenderTemperature(StringBuilder &sb, float temp, int scale); float StringToTemperature(String str, int defaultScale); } diff --git a/src/PowderToy.cpp b/src/PowderToy.cpp index 6de44ea8e..c6e94cd9b 100644 --- a/src/PowderToy.cpp +++ b/src/PowderToy.cpp @@ -137,7 +137,7 @@ static void BlueScreen(String detailMessage, std::optional> auto crashLogData = errorText.ToUtf8(); std::cerr << crashLogData << std::endl; - Platform::WriteFile(std::vector(crashLogData.begin(), crashLogData.end()), crashLogPath); + Platform::WriteFile(crashLogData, crashLogPath); //Death loop SDL_Event event; diff --git a/src/WindowIcon.cpp b/src/WindowIcon.cpp index 99c7c76a5..0088e433b 100644 --- a/src/WindowIcon.cpp +++ b/src/WindowIcon.cpp @@ -6,7 +6,7 @@ void WindowIcon(SDL_Window *window) { - if (auto image = format::PixelsFromPNG(std::vector(icon_exe_png, icon_exe_png + icon_exe_png_size))) + if (auto image = format::PixelsFromPNG(icon_exe_png.AsCharSpan())) { SDL_Surface *icon = SDL_CreateRGBSurfaceFrom(image->data(), image->Size().X, image->Size().Y, 32, image->Size().Y * sizeof(pixel), 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000); SDL_SetWindowIcon(window, icon); diff --git a/src/bzip2/bz2wrap.cpp b/src/bzip2/bz2wrap.cpp index 8bf119f29..b86fecf40 100644 --- a/src/bzip2/bz2wrap.cpp +++ b/src/bzip2/bz2wrap.cpp @@ -7,7 +7,7 @@ static size_t outputSizeIncrement = 0x100000U; -BZ2WCompressResult BZ2WCompress(std::vector &dest, const char *srcData, size_t srcSize, size_t maxSize) +BZ2WCompressResult BZ2WCompress(std::vector &dest, std::span srcData, size_t maxSize) { bz_stream stream; stream.bzalloc = NULL; @@ -18,8 +18,8 @@ BZ2WCompressResult BZ2WCompress(std::vector &dest, const char *srcData, si return BZ2WCompressNomem; } std::unique_ptr> bz2Data(&stream, BZ2_bzCompressEnd); - stream.next_in = const_cast(srcData); // I hope bz2 doesn't actually write anything here... - stream.avail_in = srcSize; + stream.next_in = const_cast(srcData.data()); // I hope bz2 doesn't actually write anything here... + stream.avail_in = srcData.size(); dest.resize(0); bool done = false; while (!done) @@ -53,7 +53,7 @@ BZ2WCompressResult BZ2WCompress(std::vector &dest, const char *srcData, si return BZ2WCompressOk; } -BZ2WDecompressResult BZ2WDecompress(std::vector &dest, const char *srcData, size_t srcSize, size_t maxSize) +BZ2WDecompressResult BZ2WDecompress(std::vector &dest, std::span srcData, size_t maxSize) { bz_stream stream; stream.bzalloc = NULL; @@ -64,8 +64,8 @@ BZ2WDecompressResult BZ2WDecompress(std::vector &dest, const char *srcData return BZ2WDecompressNomem; } std::unique_ptr> bz2Data(&stream, BZ2_bzDecompressEnd); - stream.next_in = const_cast(srcData); // I hope bz2 doesn't actually write anything here... - stream.avail_in = srcSize; + stream.next_in = const_cast(srcData.data()); // I hope bz2 doesn't actually write anything here... + stream.avail_in = srcData.size(); dest.resize(0); bool done = false; while (!done) diff --git a/src/bzip2/bz2wrap.h b/src/bzip2/bz2wrap.h index 3404c0a31..faaf668fc 100644 --- a/src/bzip2/bz2wrap.h +++ b/src/bzip2/bz2wrap.h @@ -1,5 +1,6 @@ #pragma once #include +#include #include enum BZ2WCompressResult @@ -8,7 +9,7 @@ enum BZ2WCompressResult BZ2WCompressNomem, BZ2WCompressLimit, }; -BZ2WCompressResult BZ2WCompress(std::vector &dest, const char *srcData, size_t srcSize, size_t maxSize = 0); +BZ2WCompressResult BZ2WCompress(std::vector &dest, std::span srcData, size_t maxSize = 0); enum BZ2WDecompressResult { @@ -19,4 +20,4 @@ enum BZ2WDecompressResult BZ2WDecompressBad, BZ2WDecompressEof, }; -BZ2WDecompressResult BZ2WDecompress(std::vector &dest, const char *srcData, size_t srcSize, size_t maxSize = 0); +BZ2WDecompressResult BZ2WDecompress(std::vector &dest, std::span srcData, size_t maxSize = 0); diff --git a/src/client/GameSave.cpp b/src/client/GameSave.cpp index 880d859d8..be3a6a575 100644 --- a/src/client/GameSave.cpp +++ b/src/client/GameSave.cpp @@ -500,7 +500,7 @@ void GameSave::readOPS(const std::vector &data) { std::vector bsonData; - switch (auto status = BZ2WDecompress(bsonData, (char *)(inputData + 12), inputDataLen - 12, toAlloc)) + switch (auto status = BZ2WDecompress(bsonData, std::span(reinterpret_cast(inputData + 12), inputDataLen - 12), toAlloc)) { case BZ2WDecompressOk: break; case BZ2WDecompressNomem: throw ParseException(ParseException::Corrupt, "Cannot allocate memory"); @@ -1393,7 +1393,7 @@ void GameSave::readPSv(const std::vector &dataVec) throw ParseException(ParseException::InvalidDimensions, "Save data too large"); std::vector bsonData; - switch (auto status = BZ2WDecompress(bsonData, (char *)(saveData + 12), dataLength - 12, size)) + switch (auto status = BZ2WDecompress(bsonData, std::span(reinterpret_cast(saveData + 12), dataLength - 12), size)) { case BZ2WDecompressOk: break; case BZ2WDecompressNomem: throw ParseException(ParseException::Corrupt, "Cannot allocate memory"); @@ -2632,7 +2632,7 @@ std::pair> GameSave::serialiseOPS() const std::vector outputData; - switch (auto status = BZ2WCompress(outputData, (char *)finalData, finalDataLen)) + switch (auto status = BZ2WCompress(outputData, std::span(reinterpret_cast(finalData), finalDataLen))) { case BZ2WCompressOk: break; case BZ2WCompressNomem: throw BuildException(String::Build("Save error, out of memory")); diff --git a/src/client/http/ImageRequest.cpp b/src/client/http/ImageRequest.cpp index fe1379057..07332b767 100644 --- a/src/client/http/ImageRequest.cpp +++ b/src/client/http/ImageRequest.cpp @@ -13,7 +13,7 @@ namespace http { auto [ status, data ] = Request::Finish(); ParseResponse(data, status, responseData); - auto vb = VideoBuffer::FromPNG(std::vector(data.begin(), data.end())); + auto vb = VideoBuffer::FromPNG(data); if (vb) { vb->Resize(requestedSize, true); diff --git a/src/common/platform/Common.cpp b/src/common/platform/Common.cpp index 8d665ff60..0d0ee6ded 100644 --- a/src/common/platform/Common.cpp +++ b/src/common/platform/Common.cpp @@ -67,7 +67,7 @@ bool ReadFile(std::vector &fileData, ByteString filename) return true; } -bool WriteFile(const std::vector &fileData, ByteString filename) +bool WriteFile(std::span fileData, ByteString filename) { auto replace = FileExists(filename); auto writeFileName = filename; diff --git a/src/common/platform/Emscripten.cpp b/src/common/platform/Emscripten.cpp index 7b379bf0e..cb282ac37 100644 --- a/src/common/platform/Emscripten.cpp +++ b/src/common/platform/Emscripten.cpp @@ -106,7 +106,7 @@ ByteString ExecutableName() return DefaultDdir() + "/" + ExecutableNameFirstApprox(); // bogus } -bool UpdateStart(const std::vector &data) +bool UpdateStart(std::span data) { return false; } diff --git a/src/common/platform/Linux.cpp b/src/common/platform/Linux.cpp index ae13a051a..13570988a 100644 --- a/src/common/platform/Linux.cpp +++ b/src/common/platform/Linux.cpp @@ -92,13 +92,14 @@ bool Install() if (ok) { - ByteString desktopData(powder_desktop, powder_desktop + powder_desktop_size); + auto data = powder_desktop.AsCharSpan(); + ByteString desktopData(data.begin(), data.end()); auto exe = Platform::ExecutableName(); auto path = exe.SplitFromEndBy('/').Before(); desktopData = desktopData.Substitute("Exec=" + ByteString(APPEXE), "Exec=" + desktopEscapeString(desktopEscapeExec(exe))); desktopData += ByteString::Build("Path=", desktopEscapeString(path), "\n"); ByteString file = ByteString::Build(APPVENDOR, "-", APPID, ".desktop"); - ok = ok && Platform::WriteFile(std::vector(desktopData.begin(), desktopData.end()), file); + ok = ok && Platform::WriteFile(desktopData, file); ok = ok && !system(ByteString::Build("xdg-desktop-menu install ", file).c_str()); ok = ok && !system(ByteString::Build("xdg-mime default ", file, " application/vnd.powdertoy.save").c_str()); ok = ok && !system(ByteString::Build("xdg-mime default ", file, " x-scheme-handler/ptsave").c_str()); @@ -107,21 +108,21 @@ bool Install() if (ok) { ByteString file = ByteString(APPVENDOR) + "-save.xml"; - ok = ok && Platform::WriteFile(std::vector(save_xml, save_xml + save_xml_size), file); + ok = ok && Platform::WriteFile(save_xml.AsCharSpan(), file); ok = ok && !system(ByteString::Build("xdg-mime install ", file).c_str()); Platform::RemoveFile(file); } if (ok) { ByteString file = ByteString(APPVENDOR) + "-cps.png"; - ok = ok && Platform::WriteFile(std::vector(icon_cps_png, icon_cps_png + icon_cps_png_size), file); + ok = ok && Platform::WriteFile(icon_cps_png.AsCharSpan(), file); ok = ok && !system(ByteString::Build("xdg-icon-resource install --noupdate --context mimetypes --size 64 ", file, " application-vnd.powdertoy.save").c_str()); Platform::RemoveFile(file); } if (ok) { ByteString file = ByteString(APPVENDOR) + "-exe.png"; - ok = ok && Platform::WriteFile(std::vector(icon_exe_png, icon_exe_png + icon_exe_png_size), file); + ok = ok && Platform::WriteFile(icon_exe_png.AsCharSpan(), file); ok = ok && !system(ByteString::Build("xdg-icon-resource install --noupdate --size 64 ", file, " ", APPVENDOR, "-", APPEXE).c_str()); Platform::RemoveFile(file); } diff --git a/src/common/platform/Platform.h b/src/common/platform/Platform.h index 9e5475d66..b3f2a92d3 100644 --- a/src/common/platform/Platform.h +++ b/src/common/platform/Platform.h @@ -1,6 +1,7 @@ #pragma once #include "common/String.h" #include +#include #include #include #include @@ -40,7 +41,7 @@ namespace Platform std::vector DirectorySearch(ByteString directory, ByteString search, std::vector extensions); bool ReadFile(std::vector &fileData, ByteString filename); - bool WriteFile(const std::vector &fileData, ByteString filename); + bool WriteFile(std::span fileData, ByteString filename); // TODO: Remove these and switch to *A Win32 API variants when we stop fully supporting windows // versions older than win10 1903, for example when win10 reaches EOL, see 18084d5aa0e5. @@ -56,7 +57,7 @@ namespace Platform bool ChangeDir(ByteString toDir); - bool UpdateStart(const std::vector &data); + bool UpdateStart(std::span data); bool UpdateFinish(); void UpdateCleanup(); diff --git a/src/common/platform/PosixProc.cpp b/src/common/platform/PosixProc.cpp index e8792e9e2..9fa43eb1e 100644 --- a/src/common/platform/PosixProc.cpp +++ b/src/common/platform/PosixProc.cpp @@ -37,7 +37,7 @@ ByteString ExecutableName() return rp.get(); } -bool UpdateStart(const std::vector &data) +bool UpdateStart(std::span data) { ByteString exeName = Platform::ExecutableName(); diff --git a/src/common/platform/Windows.cpp b/src/common/platform/Windows.cpp index d563dccf9..d11270416 100644 --- a/src/common/platform/Windows.cpp +++ b/src/common/platform/Windows.cpp @@ -309,7 +309,7 @@ bool Install() return ok; } -bool UpdateStart(const std::vector &data) +bool UpdateStart(std::span data) { ByteString exeName = Platform::ExecutableName(), updName; diff --git a/src/graphics/FontReader.cpp b/src/graphics/FontReader.cpp index ae13ebee1..bdce98ac3 100644 --- a/src/graphics/FontReader.cpp +++ b/src/graphics/FontReader.cpp @@ -23,7 +23,7 @@ static bool InitFontData() static std::vector fontDataBuf; static std::vector fontPtrsBuf; static std::vector< std::array > fontRangesBuf; - if (BZ2WDecompress(fontDataBuf, reinterpret_cast(compressed_font_data), compressed_font_data_size) != BZ2WDecompressOk) + if (BZ2WDecompress(fontDataBuf, compressed_font_data.AsCharSpan()) != BZ2WDecompressOk) { return false; } diff --git a/src/graphics/Graphics.cpp b/src/graphics/Graphics.cpp index aa8ff287f..986035039 100644 --- a/src/graphics/Graphics.cpp +++ b/src/graphics/Graphics.cpp @@ -142,7 +142,7 @@ void VideoBuffer::ResizeToFit(Vec2 bound, bool resample) Resize(size, resample); } -std::unique_ptr VideoBuffer::FromPNG(std::vector const &data) +std::unique_ptr VideoBuffer::FromPNG(std::span data) { auto video = format::PixelsFromPNG(data, 0x000000_rgb); if (video) diff --git a/src/graphics/VideoBuffer.h b/src/graphics/VideoBuffer.h index 83634bf19..9f0c0802f 100644 --- a/src/graphics/VideoBuffer.h +++ b/src/graphics/VideoBuffer.h @@ -1,6 +1,7 @@ #pragma once #include #include +#include #include #include "common/Plane.h" #include "common/String.h" @@ -53,7 +54,7 @@ public: // Automatically choose a size to fit within the given box, keeping aspect ratio void ResizeToFit(Vec2 bound, bool resample = false); - static std::unique_ptr FromPNG(std::vector const &); + static std::unique_ptr FromPNG(std::span data); std::unique_ptr> ToPNG() const; std::vector ToPPM() const; }; diff --git a/src/gui/font/FontEditor.cpp b/src/gui/font/FontEditor.cpp index a55807703..52922ff3d 100644 --- a/src/gui/font/FontEditor.cpp +++ b/src/gui/font/FontEditor.cpp @@ -34,7 +34,7 @@ void FontEditor::ReadDataFile(ByteString dataFile) std::vector fontDataBuf; std::vector fontPtrsBuf; std::vector< std::array > fontRangesBuf; - if (BZ2WDecompress(fontDataBuf, fileData.data(), fileData.size()) != BZ2WDecompressOk) + if (BZ2WDecompress(fontDataBuf, fileData) != BZ2WDecompressOk) { throw std::runtime_error("Could not decompress font data"); } @@ -131,7 +131,7 @@ void FontEditor::WriteDataFile(ByteString dataFile, std::vector c } std::vector compressed; - if (BZ2WCompress(compressed, uncompressed.data(), uncompressed.size()) != BZ2WCompressOk) + if (BZ2WCompress(compressed, uncompressed) != BZ2WCompressOk) { throw std::runtime_error("Could not compress font data"); } diff --git a/src/gui/save/LocalSaveActivity.h b/src/gui/save/LocalSaveActivity.h index 8c8b06f65..8081d75d5 100644 --- a/src/gui/save/LocalSaveActivity.h +++ b/src/gui/save/LocalSaveActivity.h @@ -23,9 +23,7 @@ class ThumbnailRendererTask; class LocalSaveActivity: public WindowActivity { using OnSaved = std::function)>; - std::unique_ptr>> saveToDiskImage = format::PixelsFromPNG( - std::vector(save_local_png, save_local_png + save_local_png_size) - ); + std::unique_ptr>> saveToDiskImage = format::PixelsFromPNG(save_local_png.AsCharSpan()); std::unique_ptr save; ThumbnailRendererTask *thumbnailRenderer; diff --git a/src/gui/save/ServerSaveActivity.h b/src/gui/save/ServerSaveActivity.h index 8b64faaf2..d9f1e8257 100644 --- a/src/gui/save/ServerSaveActivity.h +++ b/src/gui/save/ServerSaveActivity.h @@ -33,9 +33,7 @@ class ServerSaveActivity: public WindowActivity, public TaskListener std::unique_ptr uploadSaveRequest; using OnUploaded = std::function)>; - std::unique_ptr>> saveToServerImage = format::PixelsFromPNG( - std::vector(save_online_png, save_online_png + save_online_png_size) - ); + std::unique_ptr>> saveToServerImage = format::PixelsFromPNG(save_online_png.AsCharSpan()); public: ServerSaveActivity(std::unique_ptr newSave, OnUploaded onUploaded); diff --git a/src/lua/LuaBz2.cpp b/src/lua/LuaBz2.cpp index 5d6e35508..c0dd330f6 100644 --- a/src/lua/LuaBz2.cpp +++ b/src/lua/LuaBz2.cpp @@ -6,7 +6,7 @@ static int compress(lua_State *L) auto src = tpt_lua_checkByteString(L, 1); auto maxSize = size_t(luaL_optinteger(L, 2, 0)); std::vector dest; - auto result = BZ2WCompress(dest, src.data(), src.size(), maxSize); + auto result = BZ2WCompress(dest, src, maxSize); #define RETURN_ERR(str) lua_pushnil(L); lua_pushinteger(L, int(result)); lua_pushliteral(L, str); return 3 switch (result) { @@ -24,7 +24,7 @@ static int decompress(lua_State *L) auto src = tpt_lua_checkByteString(L, 1); auto maxSize = size_t(luaL_optinteger(L, 2, 0)); std::vector dest; - auto result = BZ2WDecompress(dest, src.data(), src.size(), maxSize); + auto result = BZ2WDecompress(dest, src, maxSize); #define RETURN_ERR(str) lua_pushnil(L); lua_pushinteger(L, int(result)); lua_pushliteral(L, str); return 3 switch (result) { diff --git a/src/lua/LuaMisc.cpp b/src/lua/LuaMisc.cpp index 31db21703..a2daeda8f 100644 --- a/src/lua/LuaMisc.cpp +++ b/src/lua/LuaMisc.cpp @@ -96,7 +96,7 @@ void LuaMisc::Tick(lua_State *L) return; } ByteString filename = "autorun.lua"; - if (!Platform::WriteFile(std::vector(scriptData.begin(), scriptData.end()), filename)) + if (!Platform::WriteFile(scriptData, filename)) { complete({ Status::GetFailed{ String::Build("Unable to write to ", filename.FromUtf8()) } }); return; @@ -177,7 +177,8 @@ static int record(lua_State *L) static int compatChunk(lua_State *L) { - lua_pushlstring(L, reinterpret_cast(compat_lua), compat_lua_size); + auto data = compat_lua.AsCharSpan(); + lua_pushlstring(L, data.data(), data.size()); return 1; } static int debug(lua_State *L) diff --git a/src/lua/LuaScriptInterface.cpp b/src/lua/LuaScriptInterface.cpp index 22b6b4e0c..1597b6d8a 100644 --- a/src/lua/LuaScriptInterface.cpp +++ b/src/lua/LuaScriptInterface.cpp @@ -176,7 +176,8 @@ LuaScriptInterface::LuaScriptInterface(GameController *newGameController, GameMo ref.Assign(L, -1); lua_pop(L, 1); } - if (luaL_loadbuffer(L, (const char *)compat_lua, compat_lua_size, "@[built-in compat.lua]") || tpt_lua_pcall(L, 0, 0, 0, eventTraitNone)) + auto compatSpan = compat_lua.AsCharSpan(); + if (luaL_loadbuffer(L, compatSpan.data(), compatSpan.size(), "@[built-in compat.lua]") || tpt_lua_pcall(L, 0, 0, 0, eventTraitNone)) { throw std::runtime_error(ByteString("failed to load built-in compat: ") + tpt_lua_toByteString(L, -1)); } diff --git a/src/prefs/Prefs.cpp b/src/prefs/Prefs.cpp index ddbcb5d32..94c1a51af 100644 --- a/src/prefs/Prefs.cpp +++ b/src/prefs/Prefs.cpp @@ -53,7 +53,7 @@ void Prefs::Write() Json::StreamWriterBuilder wbuilder; wbuilder["indentation"] = "\t"; ByteString data = Json::writeString(wbuilder, root); - if (!Platform::WriteFile(std::vector(data.begin(), data.end()), path)) + if (!Platform::WriteFile(data, path)) { return; }