diff --git a/libaegisub/common/charset_conv.cpp b/libaegisub/common/charset_conv.cpp index 3cdca0e958..b0825e0194 100644 --- a/libaegisub/common/charset_conv.cpp +++ b/libaegisub/common/charset_conv.cpp @@ -12,21 +12,18 @@ // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -/// @file charset_conv.cpp -/// @brief Wrapper for libiconv to present a more C++-friendly API -/// @ingroup libaegisub +#include -#include -#include +#include +#include "charset_6937.h" -#include +#include #include - -#include +#include +#include +#include #include -#include "charset_6937.h" - // Check if we can use advanced fallback capabilities added in GNU's iconv // implementation #if !defined(_LIBICONV_VERSION) || _LIBICONV_VERSION < 0x010A || defined(LIBICONV_PLUG) @@ -267,7 +264,7 @@ Iconv::Iconv(const char *source, const char *dest) : cd(iconv_open(dest, source)) { if (cd == iconv_invalid) - throw UnsupportedConversion(std::string("Cannot convert from ") + source + " to " + dest); + throw UnsupportedConversion(agi::Str("Cannot convert from ", source, " to ", dest)); } Iconv::~Iconv() { diff --git a/libaegisub/include/libaegisub/string.h b/libaegisub/include/libaegisub/string.h new file mode 100644 index 0000000000..4af862610c --- /dev/null +++ b/libaegisub/include/libaegisub/string.h @@ -0,0 +1,61 @@ +// Copyright (c) 2022, Thomas Goyne +// +// Permission to use, copy, modify, and distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +#include + +namespace agi { +namespace detail { +inline void AppendStr(std::string& target, std::initializer_list strs) { + size_t size = 0; + for (auto str : strs) + size += str.size(); + target.reserve(target.size() + size); + for (auto str : strs) + target.append(str); +} +} + +template +void AppendJoin(std::string& str, std::string_view sep, Range const& range) +{ + auto begin = std::begin(range); + auto end = std::end(range); + if (begin == end) return; + + str += *begin++; + while (begin != end) { + str += sep; + str += *begin++; + } +} + +template +std::string Join(std::string_view sep, Range const& range) { + std::string str; + AppendJoin(str, sep, range); + return str; +} + +template +std::string Str(Args&&... args) { + std::string str; + detail::AppendStr(str, {args...}); + return str; +} + +template +void AppendStr(std::string& str, Args&&... args) { + detail::AppendStr(str, {args...}); +} +} // namespace agi diff --git a/src/ass_attachment.cpp b/src/ass_attachment.cpp index 1de9896e2d..d198039517 100644 --- a/src/ass_attachment.cpp +++ b/src/ass_attachment.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include @@ -43,8 +44,8 @@ AssAttachment::AssAttachment(std::filesystem::path const& name, AssEntryGroup gr agi::read_file_mapping file(name); auto buff = file.read(); - entry_data = (group == AssEntryGroup::FONT ? "fontname: " : "filename: ") + filename.get() + "\r\n"; - entry_data = entry_data.get() + agi::ass::UUEncode(buff, buff + file.size()); + entry_data = agi::Str(group == AssEntryGroup::FONT ? "fontname: " : "filename: ", filename.get(), "\r\n", + agi::ass::UUEncode(buff, buff + file.size())); } size_t AssAttachment::GetSize() const { diff --git a/src/ass_dialogue.cpp b/src/ass_dialogue.cpp index 95073111ce..50c618d933 100644 --- a/src/ass_dialogue.cpp +++ b/src/ass_dialogue.cpp @@ -27,19 +27,15 @@ // // Aegisub Project http://www.aegisub.org/ -/// @file ass_dialogue.cpp -/// @brief Class for dialogue lines in subtitles -/// @ingroup subs_storage - #include "ass_dialogue.h" #include "subtitle_format.h" #include "utils.h" #include #include +#include #include -#include #include #include #include @@ -79,7 +75,7 @@ class tokenizer { std::string_view next_tok() { if (pos.eof()) - throw SubtitleFormatParseError("Failed parsing line: " + std::string(str)); + throw SubtitleFormatParseError(agi::Str("Failed parsing line: ", str)); return *pos++; } @@ -269,7 +265,7 @@ void AssDialogue::StripTags() { static std::string get_text(std::unique_ptr &d) { return d->GetText(); } void AssDialogue::UpdateText(std::vector>& blocks) { if (blocks.empty()) return; - Text = join(blocks | transformed(get_text), ""); + Text = agi::Join("", blocks | transformed(get_text)); } bool AssDialogue::CollidesWith(const AssDialogue *target) const { @@ -280,5 +276,5 @@ bool AssDialogue::CollidesWith(const AssDialogue *target) const { static std::string get_text_p(AssDialogueBlock *d) { return d->GetText(); } std::string AssDialogue::GetStrippedText() const { auto blocks = ParseTags(); - return join(blocks | agi::of_type() | transformed(get_text_p), ""); + return agi::Join("", blocks | agi::of_type() | transformed(get_text_p)); } diff --git a/src/ass_file.cpp b/src/ass_file.cpp index 50a082a7b3..eb46454946 100644 --- a/src/ass_file.cpp +++ b/src/ass_file.cpp @@ -107,7 +107,7 @@ void AssFile::InsertAttachment(std::filesystem::path const& filename) { Attachments.emplace_back(filename, group); } -std::string AssFile::GetScriptInfo(std::string const& key) const { +std::string_view AssFile::GetScriptInfo(std::string_view key) const { for (auto const& info : Info) { if (boost::iequals(key, info.Key())) return info.Value(); @@ -116,11 +116,11 @@ std::string AssFile::GetScriptInfo(std::string const& key) const { return ""; } -int AssFile::GetScriptInfoAsInt(std::string const& key) const { - return atoi(GetScriptInfo(key).c_str()); +int AssFile::GetScriptInfoAsInt(std::string_view key) const { + return atoi(GetScriptInfo(key).data()); } -void AssFile::SetScriptInfo(std::string const& key, std::string const& value) { +void AssFile::SetScriptInfo(std::string_view key, std::string_view value) { for (auto it = Info.begin(); it != Info.end(); ++it) { if (boost::iequals(key, it->Key())) { if (value.empty()) @@ -226,14 +226,14 @@ void AssFile::Sort(EntryList &lst, CompFunc comp, std::set GetExtradata(std::vector const& id_list) const; /// Remove unreferenced extradata entries diff --git a/src/ass_info.h b/src/ass_info.h index af6463d78a..8ca22273bb 100644 --- a/src/ass_info.h +++ b/src/ass_info.h @@ -22,12 +22,12 @@ class AssInfo final : public AssEntry { public: AssInfo(AssInfo const& o) = default; - AssInfo(std::string key, std::string value) : key(std::move(key)), value(std::move(value)) { } + AssInfo(std::string_view key, std::string_view value) : key(key), value(value) { } AssEntryGroup Group() const override { return AssEntryGroup::INFO; } std::string GetEntryData() const { return key + ": " + value; } - std::string Key() const { return key; } - std::string Value() const { return value; } - void SetValue(std::string const& new_value) { value = new_value; } + std::string_view Key() const { return key; } + std::string_view Value() const { return value; } + void SetValue(std::string_view new_value) { value = new_value; } }; diff --git a/src/ass_override.cpp b/src/ass_override.cpp index 035662c6df..9fec83f4f1 100644 --- a/src/ass_override.cpp +++ b/src/ass_override.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -411,7 +412,7 @@ void AssDialogueBlockOverride::AddTag(std::string const& tag) { static std::string tag_str(AssOverrideTag const& t) { return t; } std::string AssDialogueBlockOverride::GetText() { - text = "{" + join(Tags | transformed(tag_str), std::string()) + "}"; + text = agi::Str("{", agi::Join("", Tags | transformed(tag_str)), "}"); return text; } diff --git a/src/ass_style_storage.cpp b/src/ass_style_storage.cpp index fdfe75ee89..0cdcea462d 100644 --- a/src/ass_style_storage.cpp +++ b/src/ass_style_storage.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #include @@ -50,10 +51,10 @@ void AssStyleStorage::Save() const { agi::fs::CreateDirectory(file.parent_path()); agi::io::Save out(file); - out.Get() << "\xEF\xBB\xBF"; + out.Get() << "\xEF\xBB\xBF"; // UTF-8 BOM for (auto const& cur : style) - out.Get() << cur->GetEntryData() << std::endl; + out.Get() << cur->GetEntryData() << "\n"; } void AssStyleStorage::Load(std::filesystem::path const& filename) { @@ -75,9 +76,8 @@ void AssStyleStorage::Load(std::filesystem::path const& filename) { } } -void AssStyleStorage::LoadCatalog(std::string const& catalogname) { - auto filename = config::path->Decode("?user/catalog/" + catalogname + ".sty"); - Load(filename); +void AssStyleStorage::LoadCatalog(std::string_view catalogname) { + Load(config::path->Decode(agi::Str("?user/catalog/", catalogname, ".sty"))); } void AssStyleStorage::Delete(int idx) { @@ -91,7 +91,7 @@ std::vector AssStyleStorage::GetNames() { return names; } -AssStyle *AssStyleStorage::GetStyle(std::string const& name) { +AssStyle *AssStyleStorage::GetStyle(std::string_view name) { for (auto& cur : style) { if (boost::iequals(cur->name, name)) return cur.get(); @@ -106,9 +106,9 @@ std::vector AssStyleStorage::GetCatalogs() { return catalogs; } -bool AssStyleStorage::CatalogExists(std::string const& catalogname) { +bool AssStyleStorage::CatalogExists(std::string_view catalogname) { if (catalogname.empty()) return false; - auto filename = config::path->Decode("?user/catalog/" + catalogname + ".sty"); + auto filename = config::path->Decode(agi::Str("?user/catalog/", catalogname, ".sty")); return agi::fs::FileExists(filename); } diff --git a/src/ass_style_storage.h b/src/ass_style_storage.h index 994ec33669..6b1f7cb8e1 100644 --- a/src/ass_style_storage.h +++ b/src/ass_style_storage.h @@ -63,7 +63,7 @@ class AssStyleStorage { /// Get the style with the given name /// @param name Case-insensitive style name /// @return Style or nullptr if the requested style is not found - AssStyle *GetStyle(std::string const& name); + AssStyle *GetStyle(std::string_view name); /// Save stored styles to a file void Save() const; @@ -74,14 +74,14 @@ class AssStyleStorage { /// Load stored styles from a file in the default location /// @param catalogname Basename for the catalog file. Does not have to exist. - void LoadCatalog(std::string const& catalogname); + void LoadCatalog(std::string_view catalogname); /// Make a list of all existing style catalogs in the default location static std::vector GetCatalogs(); /// Check whether the name catalog exists in the default location /// @param catalogname Basename for the catalog file to check for. - static bool CatalogExists(std::string const& catalogname); + static bool CatalogExists(std::string_view catalogname); /// Insert all styles into a file, replacing existing styles with the same names /// @param file File to replace styles in diff --git a/src/async_video_provider.cpp b/src/async_video_provider.cpp index 431c2112f1..2deb5972ee 100644 --- a/src/async_video_provider.cpp +++ b/src/async_video_provider.cpp @@ -91,7 +91,7 @@ static std::unique_ptr get_subs_provider(wxEvtHandler *evt_ha } } -AsyncVideoProvider::AsyncVideoProvider(std::filesystem::path const& video_filename, std::string const& colormatrix, wxEvtHandler *parent, agi::BackgroundRunner *br) +AsyncVideoProvider::AsyncVideoProvider(std::filesystem::path const& video_filename, std::string_view colormatrix, wxEvtHandler *parent, agi::BackgroundRunner *br) : worker(agi::dispatch::Create()) , subs_provider(get_subs_provider(parent, br)) , source_provider(VideoProviderFactory::GetProvider(video_filename, colormatrix, br)) @@ -208,8 +208,10 @@ std::shared_ptr AsyncVideoProvider::GetFrame(int frame, double time, return ret; } -void AsyncVideoProvider::SetColorSpace(std::string const& matrix) { - worker->Async([=] { source_provider->SetColorSpace(matrix); }); +void AsyncVideoProvider::SetColorSpace(std::string_view matrix) { + worker->Async([this, matrix = std::string(matrix)]() { + source_provider->SetColorSpace(matrix); + }); } wxDEFINE_EVENT(EVT_FRAME_READY, FrameReadyEvent); diff --git a/src/async_video_provider.h b/src/async_video_provider.h index 119fc8bc70..8d06f26dd0 100644 --- a/src/async_video_provider.h +++ b/src/async_video_provider.h @@ -109,7 +109,7 @@ class AsyncVideoProvider { std::shared_ptr GetFrame(int frame, double time, bool raw = false); /// Ask the video provider to change YCbCr matricies - void SetColorSpace(std::string const& matrix); + void SetColorSpace(std::string_view matrix); int GetFrameCount() const { return source_provider->GetFrameCount(); } int GetWidth() const { return source_provider->GetWidth(); } @@ -127,7 +127,7 @@ class AsyncVideoProvider { /// @brief Constructor /// @param videoFileName File to open /// @param parent Event handler to send FrameReady events to - AsyncVideoProvider(std::filesystem::path const& filename, std::string const& colormatrix, wxEvtHandler *parent, agi::BackgroundRunner *br); + AsyncVideoProvider(std::filesystem::path const& filename, std::string_view colormatrix, wxEvtHandler *parent, agi::BackgroundRunner *br); ~AsyncVideoProvider(); }; diff --git a/src/audio_colorscheme.cpp b/src/audio_colorscheme.cpp index c918ffb973..1b19efb34e 100644 --- a/src/audio_colorscheme.cpp +++ b/src/audio_colorscheme.cpp @@ -34,12 +34,13 @@ #include "options.h" #include +#include AudioColorScheme::AudioColorScheme(int prec, std::string const& scheme_name, int audio_rendering_style) : palette((3<(audio_rendering_style)) { case AudioStyle_Normal: opt_base += "Normal/"; break; diff --git a/src/audio_player.cpp b/src/audio_player.cpp index fb0a974cf8..68dac2149a 100644 --- a/src/audio_player.cpp +++ b/src/audio_player.cpp @@ -27,17 +27,14 @@ // // Aegisub Project http://www.aegisub.org/ -/// @file audio_player.cpp -/// @brief Baseclass for audio players -/// @ingroup audio_output -/// - #include "include/aegisub/audio_player.h" #include "audio_controller.h" #include "factory_manager.h" #include "options.h" +#include + std::unique_ptr CreateAlsaPlayer(agi::AudioProvider *providers, wxWindow *window); std::unique_ptr CreateDirectSoundPlayer(agi::AudioProvider *providers, wxWindow *window); std::unique_ptr CreateDirectSound2Player(agi::AudioProvider *providers, wxWindow *window); @@ -93,7 +90,7 @@ std::unique_ptr AudioPlayerFactory::GetAudioPlayer(agi::AudioProvid return factory->create(provider, window); } catch (AudioPlayerOpenError const& err) { - error += std::string(factory->name) + " factory: " + err.GetMessage() + "\n"; + agi::AppendStr(error, factory->name, " factory: ", err.GetMessage(), "\n"); } } throw AudioPlayerOpenError(error); diff --git a/src/audio_provider_factory.cpp b/src/audio_provider_factory.cpp index 1a3e4f16bf..d849f019b9 100644 --- a/src/audio_provider_factory.cpp +++ b/src/audio_provider_factory.cpp @@ -24,6 +24,7 @@ #include #include #include +#include using namespace agi; @@ -74,18 +75,18 @@ std::unique_ptr GetAudioProvider(fs::path const& filename, } catch (fs::FileNotFound const& err) { LOG_D("audio_provider") << err.GetMessage(); - msg_all += std::string(factory->name) + ": " + err.GetMessage() + " not found.\n"; + agi::AppendStr(msg_all, factory->name, ": ", err.GetMessage(), " not found.\n"); } catch (AudioDataNotFound const& err) { LOG_D("audio_provider") << err.GetMessage(); found_file = true; - msg_all += std::string(factory->name) + ": " + err.GetMessage() + "\n"; + agi::AppendStr(msg_all, factory->name, ": ", err.GetMessage(), "\n"); } catch (AudioProviderError const& err) { LOG_D("audio_provider") << err.GetMessage(); found_audio = true; found_file = true; - std::string thismsg = std::string(factory->name) + ": " + err.GetMessage() + "\n"; + std::string thismsg = agi::Str(factory->name, ": ", err.GetMessage(), "\n"); msg_all += thismsg; msg_partial += thismsg; } diff --git a/src/auto4_base.cpp b/src/auto4_base.cpp index c3e98a1d24..b4ec51c2d6 100644 --- a/src/auto4_base.cpp +++ b/src/auto4_base.cpp @@ -43,6 +43,7 @@ #include #include #include +#include #include #include @@ -494,7 +495,7 @@ namespace Automation4 { catchall.pop_back(); if (Factories().size() > 1) - fnfilter = from_wx(_("All Supported Formats")) + "|" + catchall + "|" + fnfilter; + fnfilter = agi::Str(from_wx(_("All Supported Formats")), "|", catchall, "|", fnfilter); return fnfilter; } diff --git a/src/auto4_lua_assfile.cpp b/src/auto4_lua_assfile.cpp index 886adec36b..76ca93a1ed 100644 --- a/src/auto4_lua_assfile.cpp +++ b/src/auto4_lua_assfile.cpp @@ -45,6 +45,7 @@ #include #include #include +#include #include #include @@ -58,7 +59,7 @@ namespace { [[noreturn]] BadField bad_field(const char *expected_type, const char *name, const char *line_clasee) { - throw BadField(std::string("Invalid or missing field '") + name + "' in '" + line_clasee + "' class subtitle line (expected " + expected_type + ")"); + throw BadField(agi::Str("Invalid or missing field '", name, "' in '", line_clasee, "' class subtitle line (expected ", expected_type, ")")); } void get_field(lua_State *L, const char *name, const char *line_class, int (*p)(lua_State *, int)) diff --git a/src/auto4_lua_dialog.cpp b/src/auto4_lua_dialog.cpp index c860778b2c..af27ff1b0d 100644 --- a/src/auto4_lua_dialog.cpp +++ b/src/auto4_lua_dialog.cpp @@ -42,6 +42,7 @@ #include #include #include +#include #include #include @@ -526,7 +527,7 @@ namespace Automation4 { if (control->CanSerialiseValue()) { if (!res.empty()) res += "|"; - res += inline_string_encode(control->name) + ":" + control->SerialiseValue(); + agi::AppendStr(res, inline_string_encode(control->name), ":", control->SerialiseValue()); } } @@ -535,16 +536,15 @@ namespace Automation4 { void LuaDialog::Unserialise(const std::string &serialised) { for (auto tok : agi::Split(serialised, '|')) { - auto pos = std::find(begin(tok), end(tok), ':'); - if (pos == end(tok)) continue; + auto pos = tok.find(':'); + if (pos == tok.npos) continue; - std::string name = inline_string_decode(std::string(begin(tok), pos)); - std::string value(pos + 1, end(tok)); + std::string name = inline_string_decode(tok.substr(0, pos)); // Hand value to all controls matching name for (auto& control : controls) { if (control->name == name && control->CanSerialiseValue()) - control->UnserialiseValue(value); + control->UnserialiseValue(tok.substr(pos + 1)); } } } diff --git a/src/command/edit.cpp b/src/command/edit.cpp index 51f2ea5bc6..1d2881ccc4 100644 --- a/src/command/edit.cpp +++ b/src/command/edit.cpp @@ -53,6 +53,7 @@ #include #include #include +#include #include #include @@ -242,7 +243,8 @@ struct parsed_line { std::string insert(tag + value); int shift = insert.size(); if (plain || blockn < 0) { - line->Text = line->Text.get().substr(0, orig_pos) + "{" + insert + "}" + line->Text.get().substr(orig_pos); + std::string_view text = line->Text.get(); + line->Text = agi::Str(text.substr(0, orig_pos), "{", insert, "}", text.substr(orig_pos)); shift += 2; blocks = line->ParseTags(); } @@ -769,14 +771,14 @@ static void combine_lines(agi::Context *c, void (*combiner)(AssDialogue *, AssDi static void combine_karaoke(AssDialogue *first, AssDialogue *second) { if (second) - first->Text = first->Text.get() + "{\\k" + std::to_string((second->End - second->Start) / 10) + "}" + second->Text.get(); + first->Text = agi::Str(first->Text.get(), "{\\k", std::to_string((second->End - second->Start) / 10), "}", second->Text.get()); else - first->Text = "{\\k" + std::to_string((first->End - first->Start) / 10) + "}" + first->Text.get(); + first->Text = agi::Str("{\\k", std::to_string((first->End - first->Start) / 10), "}", first->Text.get()); } static void combine_concat(AssDialogue *first, AssDialogue *second) { if (second) - first->Text = first->Text.get() + " " + second->Text.get(); + first->Text = agi::Str(first->Text.get(), " ", second->Text.get()); } static void combine_drop(AssDialogue *, AssDialogue *) { } diff --git a/src/dialog_kara_timing_copy.cpp b/src/dialog_kara_timing_copy.cpp index e1966a7cf3..b7cd4ce8d9 100644 --- a/src/dialog_kara_timing_copy.cpp +++ b/src/dialog_kara_timing_copy.cpp @@ -304,11 +304,6 @@ void KaraokeLineMatchDisplay::SetInputData(AssDialogue *src, AssDialogue *dst) matcher.SetInputData(ParseKaraokeSyllables(src), dst->GetStrippedText()); } -std::string KaraokeLineMatchDisplay::GetOutputLine() const -{ - return matcher.GetOutputLine(); -} - void KaraokeLineMatchDisplay::IncreaseSourceMatch() { if (matcher.IncreaseSourceMatch()) Refresh(true); diff --git a/src/dialog_properties.cpp b/src/dialog_properties.cpp index 76d7477cd0..7887cff9b7 100644 --- a/src/dialog_properties.cpp +++ b/src/dialog_properties.cpp @@ -70,13 +70,13 @@ class DialogProperties { /// @param key Name of field /// @param value New value /// @return Did the value actually need to be changed? - int SetInfoIfDifferent(std::string const& key, std::string const& value); + int SetInfoIfDifferent(std::string_view key, std::string_view value); /// Add a property with label and text box for updating the property /// @param sizer Sizer to add the label and control to /// @param label Label text to use /// @param property Script info property name - void AddProperty(wxSizer *sizer, wxString const& label, std::string const& property); + void AddProperty(wxSizer *sizer, wxString const& label, std::string_view property); public: /// Constructor @@ -175,11 +175,11 @@ DialogProperties::DialogProperties(agi::Context *c) d.CenterOnParent(); } -void DialogProperties::AddProperty(wxSizer *sizer, wxString const& label, std::string const& property) { +void DialogProperties::AddProperty(wxSizer *sizer, wxString const& label, std::string_view property) { wxTextCtrl *ctrl = new wxTextCtrl(&d, -1, to_wx(c->ass->GetScriptInfo(property)), wxDefaultPosition, wxSize(200, -1)); sizer->Add(new wxStaticText(&d, -1, label), wxSizerFlags().Center().Left()); sizer->Add(ctrl, wxSizerFlags(1).Expand()); - properties.push_back({property, ctrl}); + properties.emplace_back(property, ctrl); } void DialogProperties::OnOK(wxCommandEvent &) { @@ -198,7 +198,7 @@ void DialogProperties::OnOK(wxCommandEvent &) { d.EndModal(!!count); } -int DialogProperties::SetInfoIfDifferent(std::string const& key, std::string const&value) { +int DialogProperties::SetInfoIfDifferent(std::string_view key, std::string_view value) { if (c->ass->GetScriptInfo(key) != value) { c->ass->SetScriptInfo(key, value); return 1; diff --git a/src/ffmpegsource_common.cpp b/src/ffmpegsource_common.cpp index 371ac74bb2..fa3f49e2fe 100644 --- a/src/ffmpegsource_common.cpp +++ b/src/ffmpegsource_common.cpp @@ -43,6 +43,7 @@ #include #include #include +#include #include #include @@ -186,7 +187,7 @@ std::filesystem::path FFmpegSourceProvider::GetCacheFilename(std::filesystem::pa hash.process_bytes(filename.string().c_str(), filename.string().size()); // Generate the filename - auto result = config::path->Decode("?local/ffms2cache/" + std::to_string(hash.checksum()) + "_" + std::to_string(len) + "_" + std::to_string(agi::fs::ModifiedTime(filename)) + ".ffindex"); + auto result = config::path->Decode(agi::Str("?local/ffms2cache/", std::to_string(hash.checksum()), "_", std::to_string(len), "_", std::to_string(agi::fs::ModifiedTime(filename)), ".ffindex"); // Ensure that folder exists agi::fs::CreateDirectory(result.parent_path()); diff --git a/src/include/aegisub/audio_player.h b/src/include/aegisub/audio_player.h index 8e29e16281..ab8e906c81 100644 --- a/src/include/aegisub/audio_player.h +++ b/src/include/aegisub/audio_player.h @@ -27,11 +27,6 @@ // // Aegisub Project http://www.aegisub.org/ -/// @file audio_player.h -/// @brief Declaration of base-class for audio players -/// @ingroup main_headers audio_output -/// - #pragma once #include diff --git a/src/resolution_resampler.cpp b/src/resolution_resampler.cpp index 0c834853e0..b71f3a6575 100644 --- a/src/resolution_resampler.cpp +++ b/src/resolution_resampler.cpp @@ -39,7 +39,7 @@ enum { BOTTOM = 3 }; -static const std::string names[] = { +static const constexpr std::string_view names[] = { "None", "TV.601", "PC.601", "TV.709", "PC.709", @@ -47,7 +47,7 @@ static const std::string names[] = { "TV.240M", "PC.240M" }; -YCbCrMatrix MatrixFromString(std::string const& str) { +YCbCrMatrix MatrixFromString(std::string_view str) { if (str.empty()) return YCbCrMatrix::tv_709; auto pos = std::find(std::begin(names), std::end(names), str); if (pos == std::end(names)) @@ -55,7 +55,7 @@ YCbCrMatrix MatrixFromString(std::string const& str) { return static_cast(std::distance(std::begin(names), pos)); } -std::string MatrixToString(YCbCrMatrix mat) { +std::string_view MatrixToString(YCbCrMatrix mat) { return names[static_cast(mat)]; } diff --git a/src/resolution_resampler.h b/src/resolution_resampler.h index f2975e87a4..6faba2b845 100644 --- a/src/resolution_resampler.h +++ b/src/resolution_resampler.h @@ -38,8 +38,8 @@ enum class YCbCrMatrix : int { pc_240m }; -YCbCrMatrix MatrixFromString(std::string const& str); -std::string MatrixToString(YCbCrMatrix mat); +YCbCrMatrix MatrixFromString(std::string_view str); +std::string_view MatrixToString(YCbCrMatrix mat); std::vector MatrixNames(); /// Configuration parameters for a resample diff --git a/src/subtitle_format.cpp b/src/subtitle_format.cpp index 04e2ef6807..70bc06a23c 100644 --- a/src/subtitle_format.cpp +++ b/src/subtitle_format.cpp @@ -51,10 +51,10 @@ #include #include +#include #include #include -#include #include #include @@ -165,7 +165,7 @@ void SubtitleFormat::ConvertNewlines(AssFile &file, std::string_view newline, bo boost::replace_all(repl, "\\h", " "); boost::ireplace_all(repl, "\\n", newline); if (mergeLineBreaks) { - std::string dbl(newline + newline); + auto dbl = agi::Str(newline, newline); size_t pos = 0; while ((pos = repl.find(dbl, pos)) != std::string::npos) boost::replace_all(repl, dbl, newline); @@ -309,13 +309,11 @@ std::string SubtitleFormat::GetWildcards(int mode) { for (auto& str : cur) str.insert(0, "*."); all.insert(all.end(), begin(cur), end(cur)); - final += "|"; - final += format->GetName(); - final += " {"; - final += boost::join(cur, ","); + agi::AppendStr(final, "|", format->GetName(), " {"); + agi::AppendJoin(final, ",", cur); final += ")|"; - final += boost::join(cur, ";"); + agi::AppendJoin(final, ";", cur); } - return from_wx(_("All Supported Formats")) + " (" + boost::join(all, ",") + ")|" + boost::join(all, ";") + final; + return agi::Str(from_wx(_("All Supported Formats")), " (", agi::Join(",", all), ")|", agi::Join(";", all), final); } diff --git a/src/subtitle_format_ebu3264.cpp b/src/subtitle_format_ebu3264.cpp index 83923720a7..43d4812f62 100644 --- a/src/subtitle_format_ebu3264.cpp +++ b/src/subtitle_format_ebu3264.cpp @@ -538,9 +538,9 @@ namespace BlockGSI create_header(AssFile const& copy, EbuExportSettings const& export_settings) { - std::string scriptinfo_title = copy.GetScriptInfo("Title"); - std::string scriptinfo_translation = copy.GetScriptInfo("Original Translation"); - std::string scriptinfo_editing = copy.GetScriptInfo("Original Editing"); + std::string_view scriptinfo_title = copy.GetScriptInfo("Title"); + std::string_view scriptinfo_translation = copy.GetScriptInfo("Original Translation"); + std::string_view scriptinfo_editing = copy.GetScriptInfo("Original Editing"); agi::charset::IconvWrapper gsi_encoder("UTF-8", "CP850"); diff --git a/src/toolbar.cpp b/src/toolbar.cpp index 40c0a77697..e4293b5015 100644 --- a/src/toolbar.cpp +++ b/src/toolbar.cpp @@ -29,8 +29,8 @@ #include #include #include +#include -#include #include #include @@ -162,7 +162,7 @@ namespace { std::vector hotkeys = hotkey::get_hotkey_strs(ht_context, command->name()); if (!hotkeys.empty()) - ret += to_wx(" (" + boost::join(hotkeys, "/") + ")"); + ret += to_wx(" (" + agi::Join("/", hotkeys) + ")"); return ret; } diff --git a/src/video_provider_dummy.cpp b/src/video_provider_dummy.cpp index 0ee4ad8811..30220f8a07 100644 --- a/src/video_provider_dummy.cpp +++ b/src/video_provider_dummy.cpp @@ -102,7 +102,7 @@ void DummyVideoProvider::GetFrame(int, VideoFrame &frame) { } namespace agi { class BackgroundRunner; } -std::unique_ptr CreateDummyVideoProvider(std::filesystem::path const& filename, std::string const&, agi::BackgroundRunner *) { +std::unique_ptr CreateDummyVideoProvider(std::filesystem::path const& filename, std::string_view, agi::BackgroundRunner *) { if (!boost::starts_with(filename.string(), "?dummy")) return {}; diff --git a/src/video_provider_manager.cpp b/src/video_provider_manager.cpp index abf6b427db..2d9c5cfba6 100644 --- a/src/video_provider_manager.cpp +++ b/src/video_provider_manager.cpp @@ -22,18 +22,19 @@ #include #include +#include -std::unique_ptr CreateDummyVideoProvider(std::filesystem::path const&, std::string const&, agi::BackgroundRunner *); -std::unique_ptr CreateYUV4MPEGVideoProvider(std::filesystem::path const&, std::string const&, agi::BackgroundRunner *); -std::unique_ptr CreateFFmpegSourceVideoProvider(std::filesystem::path const&, std::string const&, agi::BackgroundRunner *); -std::unique_ptr CreateAvisynthVideoProvider(std::filesystem::path const&, std::string const&, agi::BackgroundRunner *); +std::unique_ptr CreateDummyVideoProvider(std::filesystem::path const&, std::string_view, agi::BackgroundRunner *); +std::unique_ptr CreateYUV4MPEGVideoProvider(std::filesystem::path const&, std::string_view, agi::BackgroundRunner *); +std::unique_ptr CreateFFmpegSourceVideoProvider(std::filesystem::path const&, std::string_view, agi::BackgroundRunner *); +std::unique_ptr CreateAvisynthVideoProvider(std::filesystem::path const&, std::string_view, agi::BackgroundRunner *); std::unique_ptr CreateCacheVideoProvider(std::unique_ptr); namespace { struct factory { const char *name; - std::unique_ptr (*create)(std::filesystem::path const&, std::string const&, agi::BackgroundRunner *); + std::unique_ptr (*create)(std::filesystem::path const&, std::string_view, agi::BackgroundRunner *); bool hidden; }; @@ -53,7 +54,7 @@ std::vector VideoProviderFactory::GetClasses() { return ::GetClasses(providers); } -std::unique_ptr VideoProviderFactory::GetProvider(std::filesystem::path const& filename, std::string const& colormatrix, agi::BackgroundRunner *br) { +std::unique_ptr VideoProviderFactory::GetProvider(std::filesystem::path const& filename, std::string_view colormatrix, agi::BackgroundRunner *br) { auto preferred = OPT_GET("Video/Provider")->GetString(); auto sorted = GetSorted(providers, preferred); @@ -88,7 +89,7 @@ std::unique_ptr VideoProviderFactory::GetProvider(std::filesystem err = ex.GetMessage(); } - errors += std::string(factory->name) + ": " + err + "\n"; + agi::AppendStr(errors, factory->name, ": ", err, "\n"); LOG_D("manager/video/provider") << factory->name << ": " << err; } diff --git a/src/video_provider_manager.h b/src/video_provider_manager.h index 1c4b6da32d..c03c61556e 100644 --- a/src/video_provider_manager.h +++ b/src/video_provider_manager.h @@ -24,5 +24,5 @@ namespace agi { class BackgroundRunner; } struct VideoProviderFactory { static std::vector GetClasses(); - static std::unique_ptr GetProvider(std::filesystem::path const& video_file, std::string const& colormatrix, agi::BackgroundRunner *br); + static std::unique_ptr GetProvider(std::filesystem::path const& video_file, std::string_view colormatrix, agi::BackgroundRunner *br); }; diff --git a/src/video_provider_yuv4mpeg.cpp b/src/video_provider_yuv4mpeg.cpp index 63b670c479..300346699d 100644 --- a/src/video_provider_yuv4mpeg.cpp +++ b/src/video_provider_yuv4mpeg.cpp @@ -426,6 +426,6 @@ void YUV4MPEGVideoProvider::GetFrame(int n, VideoFrame &frame) { } namespace agi { class BackgroundRunner; } -std::unique_ptr CreateYUV4MPEGVideoProvider(std::filesystem::path const& path, std::string const&, agi::BackgroundRunner *) { +std::unique_ptr CreateYUV4MPEGVideoProvider(std::filesystem::path const& path, std::string_view, agi::BackgroundRunner *) { return std::make_unique(path); } diff --git a/src/visual_tool.cpp b/src/visual_tool.cpp index 61d3207226..03a35b5949 100644 --- a/src/visual_tool.cpp +++ b/src/visual_tool.cpp @@ -14,10 +14,6 @@ // // Aegisub Project http://www.aegisub.org/ -/// @file visual_tool.cpp -/// @brief Base class for visual typesetting functions -/// @ingroup visual_ts - #include "visual_tool.h" #include "ass_dialogue.h" @@ -36,6 +32,7 @@ #include #include #include +#include #include @@ -553,7 +550,7 @@ void VisualToolBase::SetOverride(AssDialogue* line, std::string const& tag, std: line->UpdateText(blocks); } else - line->Text = "{" + tag + value + "}" + line->Text.get(); + line->Text = agi::Str("{", tag, value, "}", line->Text.get()); } // If only export worked diff --git a/src/visual_tool.h b/src/visual_tool.h index 72eec42249..bd15c03d06 100644 --- a/src/visual_tool.h +++ b/src/visual_tool.h @@ -14,10 +14,6 @@ // // Aegisub Project http://www.aegisub.org/ -/// @file visual_tool.h -/// @see visual_tool.cpp -/// @ingroup visual_ts - #pragma once #include "gl_wrap.h" diff --git a/tests/tests/hotkey.cpp b/tests/tests/hotkey.cpp index 91c7bafb64..c5ee60578c 100644 --- a/tests/tests/hotkey.cpp +++ b/tests/tests/hotkey.cpp @@ -45,79 +45,79 @@ TEST(lagi_hotkey, empty_default) { TEST(lagi_hotkey, scan) { Hotkey h("", simple_valid); - EXPECT_STREQ("cmd1", h.Scan("Always", "Ctrl-C", false).c_str()); - EXPECT_STREQ("cmd2", h.Scan("Default", "Ctrl-C", false).c_str()); - EXPECT_STREQ("cmd2", h.Scan("Other", "Ctrl-C", false).c_str()); - EXPECT_STREQ("cmd2", h.Scan("Nonexistent", "Ctrl-C", false).c_str()); - - EXPECT_STREQ("cmd1", h.Scan("Always", "Ctrl-C", true).c_str()); - EXPECT_STREQ("cmd1", h.Scan("Default", "Ctrl-C", true).c_str()); - EXPECT_STREQ("cmd1", h.Scan("Other", "Ctrl-C", true).c_str()); - EXPECT_STREQ("cmd1", h.Scan("Nonexistent", "Ctrl-C", true).c_str()); - - EXPECT_STREQ("cmd1", h.Scan("Always", "Alt-C", false).c_str()); - EXPECT_STREQ("cmd1", h.Scan("Default", "Alt-C", false).c_str()); - EXPECT_STREQ("cmd1", h.Scan("Other", "Alt-C", false).c_str()); - EXPECT_STREQ("cmd1", h.Scan("Nonexistent", "Alt-C", false).c_str()); - - EXPECT_STREQ("cmd1", h.Scan("Always", "Alt-C", true).c_str()); - EXPECT_STREQ("cmd1", h.Scan("Default", "Alt-C", true).c_str()); - EXPECT_STREQ("cmd1", h.Scan("Other", "Alt-C", true).c_str()); - EXPECT_STREQ("cmd1", h.Scan("Nonexistent", "Alt-C", true).c_str()); - - EXPECT_STREQ("", h.Scan("Always", "Shift-C", false).c_str()); - EXPECT_STREQ("", h.Scan("Default", "Shift-C", false).c_str()); - EXPECT_STREQ("cmd1", h.Scan("Other", "Shift-C", false).c_str()); - EXPECT_STREQ("", h.Scan("Nonexistent", "Shift-C", false).c_str()); - - EXPECT_STREQ("", h.Scan("Always", "Shift-C", true).c_str()); - EXPECT_STREQ("", h.Scan("Default", "Shift-C", true).c_str()); - EXPECT_STREQ("cmd1", h.Scan("Other", "Shift-C", true).c_str()); - EXPECT_STREQ("", h.Scan("Nonexistent", "Shift-C", true).c_str()); - - EXPECT_STREQ("", h.Scan("Always", "Q", false).c_str()); - EXPECT_STREQ("", h.Scan("Default", "Q", false).c_str()); - EXPECT_STREQ("cmd3", h.Scan("Other", "Q", false).c_str()); - EXPECT_STREQ("", h.Scan("Nonexistent", "Q", false).c_str()); - - EXPECT_STREQ("", h.Scan("Always", "Q", true).c_str()); - EXPECT_STREQ("", h.Scan("Default", "Q", true).c_str()); - EXPECT_STREQ("cmd3", h.Scan("Other", "Q", true).c_str()); - EXPECT_STREQ("", h.Scan("Nonexistent", "Q", true).c_str()); - - EXPECT_STREQ("", h.Scan("Always", "C", false).c_str()); - EXPECT_STREQ("", h.Scan("Default", "C", false).c_str()); - EXPECT_STREQ("", h.Scan("Other", "C", false).c_str()); - EXPECT_STREQ("", h.Scan("Nonexistent", "C", false).c_str()); - - EXPECT_STREQ("", h.Scan("Always", "C", true).c_str()); - EXPECT_STREQ("", h.Scan("Default", "C", true).c_str()); - EXPECT_STREQ("", h.Scan("Other", "C", true).c_str()); - EXPECT_STREQ("", h.Scan("Nonexistent", "C", true).c_str()); + EXPECT_EQ("cmd1", h.Scan("Always", "Ctrl-C", false)); + EXPECT_EQ("cmd2", h.Scan("Default", "Ctrl-C", false)); + EXPECT_EQ("cmd2", h.Scan("Other", "Ctrl-C", false)); + EXPECT_EQ("cmd2", h.Scan("Nonexistent", "Ctrl-C", false)); + + EXPECT_EQ("cmd1", h.Scan("Always", "Ctrl-C", true)); + EXPECT_EQ("cmd1", h.Scan("Default", "Ctrl-C", true)); + EXPECT_EQ("cmd1", h.Scan("Other", "Ctrl-C", true)); + EXPECT_EQ("cmd1", h.Scan("Nonexistent", "Ctrl-C", true)); + + EXPECT_EQ("cmd1", h.Scan("Always", "Alt-C", false)); + EXPECT_EQ("cmd1", h.Scan("Default", "Alt-C", false)); + EXPECT_EQ("cmd1", h.Scan("Other", "Alt-C", false)); + EXPECT_EQ("cmd1", h.Scan("Nonexistent", "Alt-C", false)); + + EXPECT_EQ("cmd1", h.Scan("Always", "Alt-C", true)); + EXPECT_EQ("cmd1", h.Scan("Default", "Alt-C", true)); + EXPECT_EQ("cmd1", h.Scan("Other", "Alt-C", true)); + EXPECT_EQ("cmd1", h.Scan("Nonexistent", "Alt-C", true)); + + EXPECT_EQ("", h.Scan("Always", "Shift-C", false)); + EXPECT_EQ("", h.Scan("Default", "Shift-C", false)); + EXPECT_EQ("cmd1", h.Scan("Other", "Shift-C", false)); + EXPECT_EQ("", h.Scan("Nonexistent", "Shift-C", false)); + + EXPECT_EQ("", h.Scan("Always", "Shift-C", true)); + EXPECT_EQ("", h.Scan("Default", "Shift-C", true)); + EXPECT_EQ("cmd1", h.Scan("Other", "Shift-C", true)); + EXPECT_EQ("", h.Scan("Nonexistent", "Shift-C", true)); + + EXPECT_EQ("", h.Scan("Always", "Q", false)); + EXPECT_EQ("", h.Scan("Default", "Q", false)); + EXPECT_EQ("cmd3", h.Scan("Other", "Q", false)); + EXPECT_EQ("", h.Scan("Nonexistent", "Q", false)); + + EXPECT_EQ("", h.Scan("Always", "Q", true)); + EXPECT_EQ("", h.Scan("Default", "Q", true)); + EXPECT_EQ("cmd3", h.Scan("Other", "Q", true)); + EXPECT_EQ("", h.Scan("Nonexistent", "Q", true)); + + EXPECT_EQ("", h.Scan("Always", "C", false)); + EXPECT_EQ("", h.Scan("Default", "C", false)); + EXPECT_EQ("", h.Scan("Other", "C", false)); + EXPECT_EQ("", h.Scan("Nonexistent", "C", false)); + + EXPECT_EQ("", h.Scan("Always", "C", true)); + EXPECT_EQ("", h.Scan("Default", "C", true)); + EXPECT_EQ("", h.Scan("Other", "C", true)); + EXPECT_EQ("", h.Scan("Nonexistent", "C", true)); } TEST(lagi_hotkey, get_hotkey) { Hotkey h("", simple_valid); - EXPECT_STREQ("Ctrl-C", h.GetHotkey("Always", "cmd1").c_str()); - EXPECT_STREQ("Alt-C", h.GetHotkey("Default", "cmd1").c_str()); - EXPECT_STREQ("Shift-C", h.GetHotkey("Other", "cmd1").c_str()); - EXPECT_STREQ("Alt-C", h.GetHotkey("Nonexistent", "cmd1").c_str()); - - EXPECT_STREQ("Ctrl-C", h.GetHotkey("Always", "cmd2").c_str()); - EXPECT_STREQ("Ctrl-C", h.GetHotkey("Default", "cmd2").c_str()); - EXPECT_STREQ("Ctrl-C", h.GetHotkey("Other", "cmd2").c_str()); - EXPECT_STREQ("Ctrl-C", h.GetHotkey("Nonexistent", "cmd2").c_str()); - - EXPECT_STREQ("", h.GetHotkey("Always", "cmd3").c_str()); - EXPECT_STREQ("", h.GetHotkey("Default", "cmd3").c_str()); - EXPECT_STREQ("Q", h.GetHotkey("Other", "cmd3").c_str()); - EXPECT_STREQ("", h.GetHotkey("Nonexistent", "cmd3").c_str()); - - EXPECT_STREQ("", h.GetHotkey("Always", "cmd4").c_str()); - EXPECT_STREQ("", h.GetHotkey("Default", "cmd4").c_str()); - EXPECT_STREQ("", h.GetHotkey("Other", "cmd4").c_str()); - EXPECT_STREQ("", h.GetHotkey("Nonexistent", "cmd4").c_str()); + EXPECT_EQ("Ctrl-C", h.GetHotkey("Always", "cmd1")); + EXPECT_EQ("Alt-C", h.GetHotkey("Default", "cmd1")); + EXPECT_EQ("Shift-C", h.GetHotkey("Other", "cmd1")); + EXPECT_EQ("Alt-C", h.GetHotkey("Nonexistent", "cmd1")); + + EXPECT_EQ("Ctrl-C", h.GetHotkey("Always", "cmd2")); + EXPECT_EQ("Ctrl-C", h.GetHotkey("Default", "cmd2")); + EXPECT_EQ("Ctrl-C", h.GetHotkey("Other", "cmd2")); + EXPECT_EQ("Ctrl-C", h.GetHotkey("Nonexistent", "cmd2")); + + EXPECT_EQ("", h.GetHotkey("Always", "cmd3")); + EXPECT_EQ("", h.GetHotkey("Default", "cmd3")); + EXPECT_EQ("Q", h.GetHotkey("Other", "cmd3")); + EXPECT_EQ("", h.GetHotkey("Nonexistent", "cmd3")); + + EXPECT_EQ("", h.GetHotkey("Always", "cmd4")); + EXPECT_EQ("", h.GetHotkey("Default", "cmd4")); + EXPECT_EQ("", h.GetHotkey("Other", "cmd4")); + EXPECT_EQ("", h.GetHotkey("Nonexistent", "cmd4")); } TEST(lagi_hotkey, get_hotkeys) { @@ -176,8 +176,8 @@ TEST(lagi_hotkey, set_hotkey_map) { h.SetHotkeyMap(hm); EXPECT_TRUE(listener_called); - EXPECT_STREQ("cmd1", h.Scan("Always", "C", false).c_str()); - EXPECT_STREQ("cmd2", h.Scan("Default", "Shift-C", false).c_str()); + EXPECT_EQ("cmd1", h.Scan("Always", "C", false)); + EXPECT_EQ("cmd2", h.Scan("Default", "Shift-C", false)); } EXPECT_EQ(2, Hotkey("data/hotkey_tmp", "{}").GetHotkeyMap().size()); @@ -194,9 +194,9 @@ TEST(lagi_hotkey, combo_stuff) { ASSERT_EQ(1, std::distance(it, end)); Combo c = it->second; - EXPECT_STREQ("Ctrl-C", c.Str().c_str()); - EXPECT_STREQ("cmd2", c.CmdName().c_str()); - EXPECT_STREQ("Default", c.Context().c_str()); + EXPECT_EQ("Ctrl-C", c.Str()); + EXPECT_EQ("cmd2", c.CmdName()); + EXPECT_EQ("Default", c.Context()); } TEST(lagi_hotkey, old_format_is_backed_up_before_migrating) { diff --git a/tests/tests/iconv.cpp b/tests/tests/iconv.cpp index 91d512b1b3..050e50be5f 100644 --- a/tests/tests/iconv.cpp +++ b/tests/tests/iconv.cpp @@ -31,31 +31,6 @@ TEST(lagi_iconv, InvalidConversions) { EXPECT_THROW(IconvWrapper("nonexistent charset", "nonexistent charset"), UnsupportedConversion); } -TEST(lagi_iconv, StrLen1) { - IconvWrapper conv("UTF-8", "UTF-8", false); - for (int i = 0; i < 10; i++) { - std::string str(i, ' '); - ASSERT_EQ(i, conv.SrcStrLen(str.c_str())); - ASSERT_EQ(i, conv.DstStrLen(str.c_str())); - } -} -TEST(lagi_iconv, StrLen2) { - IconvWrapper conv("UTF-16LE", "UTF-16LE", false); - for (int i = 0; i < 10; i++) { - std::basic_string str(i, ' '); - ASSERT_EQ(2*i, conv.SrcStrLen((const char *)str.c_str())); - ASSERT_EQ(2*i, conv.DstStrLen((const char *)str.c_str())); - } -} -TEST(lagi_iconv, StrLen4) { - IconvWrapper conv("UTF-32LE", "UTF-32LE", false); - for (int i = 0; i < 10; i++) { - std::basic_string str(i, ' '); - ASSERT_EQ(4*i, conv.SrcStrLen((const char *)str.c_str())); - ASSERT_EQ(4*i, conv.DstStrLen((const char *)str.c_str())); - } -} - #ifdef _LIBICONV_VERSION TEST(lagi_iconv, Fallbacks) { IconvWrapper nofallback("UTF-8", "Shift-JIS", false); @@ -111,14 +86,16 @@ TEST(lagi_iconv, Conversions) { // Basic overflow tests TEST(lagi_iconv, Buffer) { IconvWrapper conv("UTF-8", "UTF-16LE", false); - char buff[32]; - memset(buff, 0xFF, sizeof(buff)); + std::array buff; + buff.fill(0xFF); + std::span sbuff(buff); + std::string_view src("", 1); - EXPECT_THROW(conv.Convert("", 1, buff, 0), BufferTooSmall); + EXPECT_THROW(conv.Convert(src, sbuff.first(0)), BufferTooSmall); EXPECT_EQ('\xFF', buff[0]); - EXPECT_THROW(conv.Convert("", 1, buff, 1), BufferTooSmall); + EXPECT_THROW(conv.Convert(src, sbuff.first(1)), BufferTooSmall); EXPECT_EQ('\xFF', buff[0]); - EXPECT_NO_THROW(conv.Convert("", 1, buff, 2)); + EXPECT_NO_THROW(conv.Convert(src, sbuff.first(2))); EXPECT_EQ('\0', buff[0]); EXPECT_EQ('\0', buff[1]); EXPECT_EQ('\xFF', buff[2]);