Fixed many invalid uses of StringView::GetText(), where a null-terminated string was required.
Renamed GetText() to GetNonTerminatedText() to reduce chance of same bugs appearing in the future.
This commit is contained in:
@@ -816,6 +816,6 @@ bool EditorUtilities::ReplaceInFile(const StringView& file, const StringView& fi
|
||||
String text;
|
||||
if (File::ReadAllText(file, text))
|
||||
return true;
|
||||
text.Replace(findWhat.GetText(), replaceWith.GetText());
|
||||
text.Replace(findWhat.Get(), findWhat.Length(), replaceWith.Get(), replaceWith.Length());
|
||||
return File::WriteAllText(file, text, Encoding::ANSI);
|
||||
}
|
||||
|
||||
@@ -384,12 +384,12 @@ Asset* Content::LoadAsyncInternal(const StringView& internalPath, MClass* type)
|
||||
CHECK_RETURN(type, nullptr);
|
||||
const auto scriptingType = Scripting::FindScriptingType(type->GetFullName());
|
||||
if (scriptingType)
|
||||
return LoadAsyncInternal(internalPath.GetText(), scriptingType);
|
||||
return LoadAsyncInternal(internalPath, scriptingType);
|
||||
LOG(Error, "Failed to find asset type '{0}'.", String(type->GetFullName()));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Asset* Content::LoadAsyncInternal(const Char* internalPath, const ScriptingTypeHandle& type)
|
||||
Asset* Content::LoadAsyncInternal(const StringView& internalPath, const ScriptingTypeHandle& type)
|
||||
{
|
||||
#if USE_EDITOR
|
||||
const String path = Globals::EngineContentFolder / internalPath + ASSET_FILES_EXTENSION_WITH_DOT;
|
||||
@@ -411,6 +411,11 @@ Asset* Content::LoadAsyncInternal(const Char* internalPath, const ScriptingTypeH
|
||||
return asset;
|
||||
}
|
||||
|
||||
Asset* Content::LoadAsyncInternal(const Char* internalPath, const ScriptingTypeHandle& type)
|
||||
{
|
||||
return LoadAsyncInternal(StringView(internalPath), type);
|
||||
}
|
||||
|
||||
FLAXENGINE_API Asset* LoadAsset(const Guid& id, const ScriptingTypeHandle& type)
|
||||
{
|
||||
return Content::LoadAsync(id, type);
|
||||
|
||||
@@ -187,6 +187,14 @@ public:
|
||||
/// <returns>The loaded asset or null if failed.</returns>
|
||||
API_FUNCTION(Attributes="HideInEditor") static Asset* LoadAsyncInternal(const StringView& internalPath, MClass* type);
|
||||
|
||||
/// <summary>
|
||||
/// Loads internal engine asset and holds it until it won't be referenced by any object. Returns null if asset is missing. Actual asset data loading is performed on a other thread in async.
|
||||
/// </summary>
|
||||
/// <param name="internalPath">The path of the asset relative to the engine internal content (excluding the extension).</param>
|
||||
/// <param name="type">The asset type. If loaded object has different type (excluding types derived from the given) the loading fails.</param>
|
||||
/// <returns>The loaded asset or null if failed.</returns>
|
||||
static Asset* LoadAsyncInternal(const StringView& internalPath, const ScriptingTypeHandle& type);
|
||||
|
||||
/// <summary>
|
||||
/// Loads internal engine asset and holds it until it won't be referenced by any object. Returns null if asset is missing. Actual asset data loading is performed on a other thread in async.
|
||||
/// </summary>
|
||||
|
||||
@@ -413,67 +413,97 @@ public:
|
||||
return replacedChars;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Replaces all occurences of searchText within current string with replacementText.
|
||||
/// </summary>
|
||||
/// <param name="searchText">String to search for. If empty or null no replacements are done.</param>
|
||||
/// <param name="replacementText">String to replace with. Null is treated as empty string.</param>
|
||||
/// <returns>Number of replacements made. (In case-sensitive mode if search text and replacement text are equal no replacements are done, and zero is returned.)</returns>
|
||||
int32 Replace(const T* searchText, const T* replacementText, StringSearchCase searchCase = StringSearchCase::CaseSensitive)
|
||||
{
|
||||
int32 replacedCount = 0;
|
||||
if (HasChars() && searchText && *searchText && replacementText && (searchCase == StringSearchCase::IgnoreCase || StringUtils::Compare(searchText, replacementText) != 0))
|
||||
const int32 searchTextLength = StringUtils::Length(searchText);
|
||||
const int32 replacementTextLength = StringUtils::Length(replacementText);
|
||||
return Replace(searchText, searchTextLength, replacementText, replacementTextLength, searchCase);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Replaces all occurences of searchText within current string with replacementText.
|
||||
/// </summary>
|
||||
/// <param name="searchText">String to search for. If empty or null no replacements are done.</param>
|
||||
/// <param name="searchTextLength">Length of searchText.</param>
|
||||
/// <param name="replacementText">String to replace with. Null is treated as empty string.</param>
|
||||
/// <param name="replacementTextLength">Length of replacementText.</param>
|
||||
/// <returns>Number of replacements made. (In case-sensitive mode if search text and replacement text are equal no replacements are done, and zero is returned.)</returns>
|
||||
int32 Replace(const T* searchText, int32 searchTextLength, const T* replacementText, int32 replacementTextLength, StringSearchCase searchCase = StringSearchCase::CaseSensitive)
|
||||
{
|
||||
if (!HasChars())
|
||||
return 0;
|
||||
|
||||
if (searchTextLength == 0)
|
||||
return 0;
|
||||
|
||||
// If we are doing case sensitive search and replacement text is equal to search text, we do nothing.
|
||||
if ((searchCase == StringSearchCase::CaseSensitive) && (searchTextLength == replacementTextLength) && (StringUtils::Compare(searchText, replacementText) == 0))
|
||||
{
|
||||
const int32 searchTextLength = StringUtils::Length(searchText);
|
||||
const int32 replacementTextLength = StringUtils::Length(replacementText);
|
||||
if (searchTextLength == replacementTextLength)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 replacedCount = 0;
|
||||
|
||||
if (searchTextLength == replacementTextLength)
|
||||
{
|
||||
T* pos = (T*)(searchCase == StringSearchCase::IgnoreCase ? StringUtils::FindIgnoreCase(_data, searchText) : StringUtils::Find(_data, searchText));
|
||||
while (pos != nullptr)
|
||||
{
|
||||
T* pos = (T*)(searchCase == StringSearchCase::IgnoreCase ? StringUtils::FindIgnoreCase(_data, searchText) : StringUtils::Find(_data, searchText));
|
||||
while (pos != nullptr)
|
||||
{
|
||||
replacedCount++;
|
||||
replacedCount++;
|
||||
|
||||
for (int32 i = 0; i < replacementTextLength; i++)
|
||||
pos[i] = replacementText[i];
|
||||
for (int32 i = 0; i < replacementTextLength; i++)
|
||||
pos[i] = replacementText[i];
|
||||
|
||||
if (pos + searchTextLength - **this < Length())
|
||||
pos = (T*)(searchCase == StringSearchCase::IgnoreCase ? StringUtils::FindIgnoreCase(pos + searchTextLength, searchText) : StringUtils::Find(pos + searchTextLength, searchText));
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (pos + searchTextLength - **this < Length())
|
||||
pos = (T*)(searchCase == StringSearchCase::IgnoreCase ? StringUtils::FindIgnoreCase(pos + searchTextLength, searchText) : StringUtils::Find(pos + searchTextLength, searchText));
|
||||
else
|
||||
break;
|
||||
}
|
||||
else if (Contains(searchText, searchCase))
|
||||
}
|
||||
else if (Contains(searchText, searchCase))
|
||||
{
|
||||
T* readPosition = _data;
|
||||
T* searchPosition = (T*)(searchCase == StringSearchCase::IgnoreCase ? StringUtils::FindIgnoreCase(readPosition, searchText) : StringUtils::Find(readPosition, searchText));
|
||||
while (searchPosition != nullptr)
|
||||
{
|
||||
T* readPosition = _data;
|
||||
T* searchPosition = (T*)(searchCase == StringSearchCase::IgnoreCase ? StringUtils::FindIgnoreCase(readPosition, searchText) : StringUtils::Find(readPosition, searchText));
|
||||
while (searchPosition != nullptr)
|
||||
{
|
||||
replacedCount++;
|
||||
readPosition = searchPosition + searchTextLength;
|
||||
searchPosition = (T*)(searchCase == StringSearchCase::IgnoreCase ? StringUtils::FindIgnoreCase(readPosition, searchText) : StringUtils::Find(readPosition, searchText));
|
||||
}
|
||||
|
||||
const auto oldLength = _length;
|
||||
const auto oldData = _data;
|
||||
_length += replacedCount * (replacementTextLength - searchTextLength);
|
||||
_data = (T*)Platform::Allocate((_length + 1) * sizeof(T), 16);
|
||||
|
||||
T* writePosition = _data;
|
||||
readPosition = oldData;
|
||||
replacedCount++;
|
||||
readPosition = searchPosition + searchTextLength;
|
||||
searchPosition = (T*)(searchCase == StringSearchCase::IgnoreCase ? StringUtils::FindIgnoreCase(readPosition, searchText) : StringUtils::Find(readPosition, searchText));
|
||||
while (searchPosition != nullptr)
|
||||
{
|
||||
const int32 writeOffset = (int32)(searchPosition - readPosition);
|
||||
Platform::MemoryCopy(writePosition, readPosition, writeOffset * sizeof(T));
|
||||
writePosition += writeOffset;
|
||||
|
||||
Platform::MemoryCopy(writePosition, replacementText, replacementTextLength * sizeof(T));
|
||||
writePosition += replacementTextLength;
|
||||
|
||||
readPosition = searchPosition + searchTextLength;
|
||||
searchPosition = (T*)(searchCase == StringSearchCase::IgnoreCase ? StringUtils::FindIgnoreCase(readPosition, searchText) : StringUtils::Find(readPosition, searchText));
|
||||
}
|
||||
|
||||
const int32 writeOffset = (int32)(oldData - readPosition) + oldLength;
|
||||
Platform::MemoryCopy(writePosition, readPosition, writeOffset * sizeof(T));
|
||||
|
||||
_data[_length] = 0;
|
||||
Platform::Free(oldData);
|
||||
}
|
||||
|
||||
const auto oldLength = _length;
|
||||
const auto oldData = _data;
|
||||
_length += replacedCount * (replacementTextLength - searchTextLength);
|
||||
_data = (T*)Platform::Allocate((_length + 1) * sizeof(T), 16);
|
||||
|
||||
T* writePosition = _data;
|
||||
readPosition = oldData;
|
||||
searchPosition = (T*)(searchCase == StringSearchCase::IgnoreCase ? StringUtils::FindIgnoreCase(readPosition, searchText) : StringUtils::Find(readPosition, searchText));
|
||||
while (searchPosition != nullptr)
|
||||
{
|
||||
const int32 writeOffset = (int32)(searchPosition - readPosition);
|
||||
Platform::MemoryCopy(writePosition, readPosition, writeOffset * sizeof(T));
|
||||
writePosition += writeOffset;
|
||||
|
||||
if (replacementTextLength > 0)
|
||||
Platform::MemoryCopy(writePosition, replacementText, replacementTextLength * sizeof(T));
|
||||
writePosition += replacementTextLength;
|
||||
|
||||
readPosition = searchPosition + searchTextLength;
|
||||
searchPosition = (T*)(searchCase == StringSearchCase::IgnoreCase ? StringUtils::FindIgnoreCase(readPosition, searchText) : StringUtils::Find(readPosition, searchText));
|
||||
}
|
||||
|
||||
const int32 writeOffset = (int32)(oldData - readPosition) + oldLength;
|
||||
Platform::MemoryCopy(writePosition, readPosition, writeOffset * sizeof(T));
|
||||
|
||||
_data[_length] = 0;
|
||||
Platform::Free(oldData);
|
||||
}
|
||||
|
||||
return replacedCount;
|
||||
|
||||
@@ -18,12 +18,12 @@ StringView::StringView(const String& str)
|
||||
|
||||
bool StringView::operator==(const String& other) const
|
||||
{
|
||||
return StringUtils::Compare(this->GetText(), *other) == 0;
|
||||
return this->Compare(StringView(other)) == 0;
|
||||
}
|
||||
|
||||
bool StringView::operator!=(const String& other) const
|
||||
{
|
||||
return StringUtils::Compare(this->GetText(), *other) != 0;
|
||||
return this->Compare(StringView(other)) != 0;
|
||||
}
|
||||
|
||||
StringView StringView::Left(int32 count) const
|
||||
@@ -62,12 +62,12 @@ StringAnsi StringView::ToStringAnsi() const
|
||||
|
||||
bool operator==(const String& a, const StringView& b)
|
||||
{
|
||||
return a.Length() == b.Length() && StringUtils::Compare(a.GetText(), b.GetText(), b.Length()) == 0;
|
||||
return a.Length() == b.Length() && StringUtils::Compare(a.GetText(), b.GetNonTerminatedText(), b.Length()) == 0;
|
||||
}
|
||||
|
||||
bool operator!=(const String& a, const StringView& b)
|
||||
{
|
||||
return a.Length() != b.Length() || StringUtils::Compare(a.GetText(), b.GetText(), b.Length()) != 0;
|
||||
return a.Length() != b.Length() || StringUtils::Compare(a.GetText(), b.GetNonTerminatedText(), b.Length()) != 0;
|
||||
}
|
||||
|
||||
StringAnsiView StringAnsiView::Empty;
|
||||
@@ -79,12 +79,12 @@ StringAnsiView::StringAnsiView(const StringAnsi& str)
|
||||
|
||||
bool StringAnsiView::operator==(const StringAnsi& other) const
|
||||
{
|
||||
return StringUtils::Compare(this->GetText(), *other) == 0;
|
||||
return this->Compare(StringAnsiView(other)) == 0;
|
||||
}
|
||||
|
||||
bool StringAnsiView::operator!=(const StringAnsi& other) const
|
||||
{
|
||||
return StringUtils::Compare(this->GetText(), *other) != 0;
|
||||
return this->Compare(StringAnsiView(other)) != 0;
|
||||
}
|
||||
|
||||
StringAnsi StringAnsiView::Substring(int32 startIndex) const
|
||||
@@ -111,10 +111,10 @@ StringAnsi StringAnsiView::ToStringAnsi() const
|
||||
|
||||
bool operator==(const StringAnsi& a, const StringAnsiView& b)
|
||||
{
|
||||
return a.Length() == b.Length() && StringUtils::Compare(a.GetText(), b.GetText(), b.Length()) == 0;
|
||||
return a.Length() == b.Length() && StringUtils::Compare(a.GetText(), b.GetNonTerminatedText(), b.Length()) == 0;
|
||||
}
|
||||
|
||||
bool operator!=(const StringAnsi& a, const StringAnsiView& b)
|
||||
{
|
||||
return a.Length() != b.Length() || StringUtils::Compare(a.GetText(), b.GetText(), b.Length()) != 0;
|
||||
return a.Length() != b.Length() || StringUtils::Compare(a.GetText(), b.GetNonTerminatedText(), b.Length()) != 0;
|
||||
}
|
||||
|
||||
@@ -63,9 +63,12 @@ public:
|
||||
const int32 lengthDiff = Length() - str.Length();
|
||||
if (lengthDiff != 0)
|
||||
return lengthDiff;
|
||||
if (Length() == 0)
|
||||
return 0;
|
||||
// We know here that both this StringView and str are not empty, and therefore Get() below are valid.
|
||||
if (searchCase == StringSearchCase::CaseSensitive)
|
||||
return StringUtils::Compare(this->GetText(), str.GetText(), Length());
|
||||
return StringUtils::CompareIgnoreCase(this->GetText(), str.GetText(), Length());
|
||||
return StringUtils::Compare(this->Get(), str.Get(), Length());
|
||||
return StringUtils::CompareIgnoreCase(this->Get(), str.Get(), Length());
|
||||
}
|
||||
|
||||
public:
|
||||
@@ -95,7 +98,7 @@ public:
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the pointer to the string.
|
||||
/// Gets the pointer to the string. Pointer can be null, and won't be null-terminated.
|
||||
/// </summary>
|
||||
FORCE_INLINE constexpr const T* operator*() const
|
||||
{
|
||||
@@ -103,7 +106,7 @@ public:
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the pointer to the string.
|
||||
/// Gets the pointer to the string. Pointer can be null, and won't be null-terminated.
|
||||
/// </summary>
|
||||
FORCE_INLINE constexpr const T* Get() const
|
||||
{
|
||||
@@ -111,9 +114,9 @@ public:
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the pointer to the string or to the static empty text if string is null. Returned pointer is always valid (read-only).
|
||||
/// Gets the pointer to the string or to the static empty text if string is null. Returned pointer is always non-null, but is not null-terminated.
|
||||
/// </summary>
|
||||
FORCE_INLINE const T* GetText() const
|
||||
FORCE_INLINE const T* GetNonTerminatedText() const
|
||||
{
|
||||
return _data ? _data : (const T*)TEXT("");
|
||||
}
|
||||
@@ -177,15 +180,17 @@ public:
|
||||
{
|
||||
if (prefix.IsEmpty() || Length() < prefix.Length())
|
||||
return false;
|
||||
// We know that this StringView is not empty, and therefore Get() below is valid.
|
||||
if (searchCase == StringSearchCase::IgnoreCase)
|
||||
return StringUtils::CompareIgnoreCase(this->GetText(), *prefix, prefix.Length()) == 0;
|
||||
return StringUtils::Compare(this->GetText(), *prefix, prefix.Length()) == 0;
|
||||
return StringUtils::CompareIgnoreCase(this->Get(), *prefix, prefix.Length()) == 0;
|
||||
return StringUtils::Compare(this->Get(), *prefix, prefix.Length()) == 0;
|
||||
}
|
||||
|
||||
bool EndsWith(const StringViewBase& suffix, StringSearchCase searchCase = StringSearchCase::IgnoreCase) const
|
||||
{
|
||||
if (suffix.IsEmpty() || Length() < suffix.Length())
|
||||
return false;
|
||||
// We know that this StringView is not empty, and therefore accessing data below is valid.
|
||||
if (searchCase == StringSearchCase::IgnoreCase)
|
||||
return StringUtils::CompareIgnoreCase(&(*this)[Length() - suffix.Length()], *suffix) == 0;
|
||||
return StringUtils::Compare(&(*this)[Length() - suffix.Length()], *suffix) == 0;
|
||||
@@ -232,7 +237,7 @@ public:
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="StringView"/> class.
|
||||
/// </summary>
|
||||
/// <param name="str">The characters sequence.</param>
|
||||
/// <param name="str">The characters sequence. If null, constructed StringView will be empty.</param>
|
||||
StringView(const Char* str)
|
||||
{
|
||||
_data = str;
|
||||
@@ -242,7 +247,7 @@ public:
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="StringView"/> class.
|
||||
/// </summary>
|
||||
/// <param name="str">The characters sequence.</param>
|
||||
/// <param name="str">The characters sequence. Can be null if length is zero.</param>
|
||||
/// <param name="length">The characters sequence length (excluding null-terminator character).</param>
|
||||
constexpr StringView(const Char* str, int32 length)
|
||||
: StringViewBase<Char>(str, length)
|
||||
@@ -270,7 +275,7 @@ public:
|
||||
/// <returns>True if this string is lexicographically equivalent to the other, otherwise false.</returns>
|
||||
FORCE_INLINE bool operator==(const StringView& other) const
|
||||
{
|
||||
return StringUtils::Compare(this->GetText(), other.GetText()) == 0;
|
||||
return this->Compare(other) == 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -280,7 +285,7 @@ public:
|
||||
/// <returns>True if this string is lexicographically is not equivalent to the other, otherwise false.</returns>
|
||||
FORCE_INLINE bool operator!=(const StringView& other) const
|
||||
{
|
||||
return StringUtils::Compare(this->GetText(), other.GetText()) != 0;
|
||||
return this->Compare(other) != 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -290,7 +295,7 @@ public:
|
||||
/// <returns>True if this string is lexicographically equivalent to the other, otherwise false.</returns>
|
||||
FORCE_INLINE bool operator==(const Char* other) const
|
||||
{
|
||||
return StringUtils::Compare(this->GetText(), other ? other : TEXT("")) == 0;
|
||||
return this->Compare(StringView(other)) == 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -300,7 +305,7 @@ public:
|
||||
/// <returns>True if this string is lexicographically is not equivalent to the other, otherwise false.</returns>
|
||||
FORCE_INLINE bool operator!=(const Char* other) const
|
||||
{
|
||||
return StringUtils::Compare(this->GetText(), other ? other : TEXT("")) != 0;
|
||||
return this->Compare(StringView(other)) != 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -459,7 +464,7 @@ public:
|
||||
/// <returns>True if this string is lexicographically equivalent to the other, otherwise false.</returns>
|
||||
FORCE_INLINE bool operator==(const StringAnsiView& other) const
|
||||
{
|
||||
return StringUtils::Compare(this->GetText(), other.GetText()) == 0;
|
||||
return this->Compare(other) == 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -469,7 +474,7 @@ public:
|
||||
/// <returns>True if this string is lexicographically is not equivalent to the other, otherwise false.</returns>
|
||||
FORCE_INLINE bool operator!=(const StringAnsiView& other) const
|
||||
{
|
||||
return StringUtils::Compare(this->GetText(), other.GetText()) != 0;
|
||||
return this->Compare(other) != 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -479,7 +484,7 @@ public:
|
||||
/// <returns>True if this string is lexicographically equivalent to the other, otherwise false.</returns>
|
||||
FORCE_INLINE bool operator==(const char* other) const
|
||||
{
|
||||
return StringUtils::Compare(this->GetText(), other ? other : "") == 0;
|
||||
return this->Compare(StringAnsiView(other)) == 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -489,7 +494,7 @@ public:
|
||||
/// <returns>True if this string is lexicographically is not equivalent to the other, otherwise false.</returns>
|
||||
FORCE_INLINE bool operator!=(const char* other) const
|
||||
{
|
||||
return StringUtils::Compare(this->GetText(), other ? other : "") != 0;
|
||||
return this->Compare(StringAnsiView(other)) != 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -278,18 +278,18 @@ String Localization::GetPluralString(const String& id, int32 n, const String& fa
|
||||
{
|
||||
CHECK_RETURN(n >= 1, fallback);
|
||||
n--;
|
||||
StringView result;
|
||||
const String* result = nullptr;
|
||||
for (auto& e : Instance.LocalizedStringTables)
|
||||
{
|
||||
const auto table = e.Get();
|
||||
const auto messages = table ? table->Entries.TryGet(id) : nullptr;
|
||||
if (messages && messages->Count() > n)
|
||||
{
|
||||
result = messages->At(n);
|
||||
result = &messages->At(n);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (result.IsEmpty())
|
||||
result = fallback;
|
||||
return String::Format(result.GetText(), n);
|
||||
if (!result)
|
||||
result = &fallback;
|
||||
return String::Format(result->GetText(), n);
|
||||
}
|
||||
|
||||
@@ -169,8 +169,8 @@ public:
|
||||
/// <summary>
|
||||
/// Copy memory region
|
||||
/// </summary>
|
||||
/// <param name="dst">Destination memory address</param>
|
||||
/// <param name="src">Source memory address</param>
|
||||
/// <param name="dst">Destination memory address. Must not be null, even if size is zero.</param>
|
||||
/// <param name="src">Source memory address. Must not be null, even if size is zero.</param>
|
||||
/// <param name="size">Size of the memory to copy in bytes</param>
|
||||
FORCE_INLINE static void MemoryCopy(void* dst, const void* src, uint64 size)
|
||||
{
|
||||
@@ -180,7 +180,7 @@ public:
|
||||
/// <summary>
|
||||
/// Set memory region with given value
|
||||
/// </summary>
|
||||
/// <param name="dst">Destination memory address</param>
|
||||
/// <param name="dst">Destination memory address. Must not be null, even if size is zero.</param>
|
||||
/// <param name="size">Size of the memory to set in bytes</param>
|
||||
/// <param name="value">Value to set</param>
|
||||
FORCE_INLINE static void MemorySet(void* dst, uint64 size, int32 value)
|
||||
@@ -191,7 +191,7 @@ public:
|
||||
/// <summary>
|
||||
/// Clear memory region with zeros
|
||||
/// </summary>
|
||||
/// <param name="dst">Destination memory address</param>
|
||||
/// <param name="dst">Destination memory address. Must not be null, even if size is zero.</param>
|
||||
/// <param name="size">Size of the memory to clear in bytes</param>
|
||||
FORCE_INLINE static void MemoryClear(void* dst, uint64 size)
|
||||
{
|
||||
@@ -201,8 +201,8 @@ public:
|
||||
/// <summary>
|
||||
/// Compare two blocks of the memory.
|
||||
/// </summary>
|
||||
/// <param name="buf1">The first buffer address.</param>
|
||||
/// <param name="buf2">The second buffer address.</param>
|
||||
/// <param name="buf1">The first buffer address. Must not be null, even if size is zero.</param>
|
||||
/// <param name="buf2">The second buffer address. Must not be null, even if size is zero.</param>
|
||||
/// <param name="size">Size of the memory to compare in bytes.</param>
|
||||
FORCE_INLINE static int32 MemoryCompare(const void* buf1, const void* buf2, uint64 size)
|
||||
{
|
||||
|
||||
@@ -1659,7 +1659,7 @@ void LinuxClipboard::SetText(const StringView& text)
|
||||
return;
|
||||
X11::Window window = (X11::Window)mainWindow->GetNativePtr();
|
||||
|
||||
Impl::ClipboardText.Set(text.GetText(), text.Length());
|
||||
Impl::ClipboardText.Set(text.Get(), text.Length());
|
||||
X11::XSetSelectionOwner(xDisplay, xAtomClipboard, window, CurrentTime); // CLIPBOARD
|
||||
X11::XSetSelectionOwner(xDisplay, (X11::Atom)1, window, CurrentTime); // XA_PRIMARY
|
||||
}
|
||||
|
||||
@@ -120,36 +120,36 @@ public:
|
||||
|
||||
public:
|
||||
|
||||
// Compare two strings with case sensitive
|
||||
// Compare two strings with case sensitive. Strings must not be null.
|
||||
static int32 Compare(const Char* str1, const Char* str2);
|
||||
|
||||
// Compare two strings without case sensitive
|
||||
// Compare two strings without case sensitive. Strings must not be null.
|
||||
static int32 Compare(const Char* str1, const Char* str2, int32 maxCount);
|
||||
|
||||
// Compare two strings without case sensitive
|
||||
// Compare two strings without case sensitive. Strings must not be null.
|
||||
static int32 CompareIgnoreCase(const Char* str1, const Char* str2);
|
||||
|
||||
// Compare two strings without case sensitive
|
||||
// Compare two strings without case sensitive. Strings must not be null.
|
||||
static int32 CompareIgnoreCase(const Char* str1, const Char* str2, int32 maxCount);
|
||||
|
||||
// Compare two strings with case sensitive
|
||||
// Compare two strings with case sensitive. Strings must not be null.
|
||||
static int32 Compare(const char* str1, const char* str2);
|
||||
|
||||
// Compare two strings without case sensitive
|
||||
// Compare two strings without case sensitive. Strings must not be null.
|
||||
static int32 Compare(const char* str1, const char* str2, int32 maxCount);
|
||||
|
||||
// Compare two strings without case sensitive
|
||||
// Compare two strings without case sensitive. Strings must not be null.
|
||||
static int32 CompareIgnoreCase(const char* str1, const char* str2);
|
||||
|
||||
// Compare two strings without case sensitive
|
||||
// Compare two strings without case sensitive. Strings must not be null.
|
||||
static int32 CompareIgnoreCase(const char* str1, const char* str2, int32 maxCount);
|
||||
|
||||
public:
|
||||
|
||||
// Get string length
|
||||
// Get string length. Returns 0 if str is null.
|
||||
static int32 Length(const Char* str);
|
||||
|
||||
// Get string length
|
||||
// Get string length. Returns 0 if str is null.
|
||||
static int32 Length(const char* str);
|
||||
|
||||
// Copy string
|
||||
|
||||
@@ -35,7 +35,7 @@ void RunUWP()
|
||||
|
||||
DialogResult MessageBox::Show(Window* parent, const StringView& text, const StringView& caption, MessageBoxButtons buttons, MessageBoxIcon icon)
|
||||
{
|
||||
return (DialogResult)CUWPPlatform->ShowMessageDialog(parent ? parent->GetImpl() : nullptr, text.GetText(), caption.GetText(), (UWPPlatformImpl::MessageBoxButtons)buttons, (UWPPlatformImpl::MessageBoxIcon)icon);
|
||||
return (DialogResult)CUWPPlatform->ShowMessageDialog(parent ? parent->GetImpl() : nullptr, String(text).GetText(), String(caption).GetText(), (UWPPlatformImpl::MessageBoxButtons)buttons, (UWPPlatformImpl::MessageBoxIcon)icon);
|
||||
}
|
||||
|
||||
bool UWPPlatform::Init()
|
||||
|
||||
@@ -25,7 +25,7 @@ void WindowsClipboard::SetText(const StringView& text)
|
||||
{
|
||||
const int32 size = (text.Length() + 1) * sizeof(Char);
|
||||
const HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, size);
|
||||
Platform::MemoryCopy(GlobalLock(hMem), text.GetText(), size);
|
||||
Platform::MemoryCopy(GlobalLock(hMem), String(text).GetText(), size);
|
||||
GlobalUnlock(hMem);
|
||||
|
||||
OpenClipboard(nullptr);
|
||||
|
||||
@@ -435,7 +435,7 @@ DialogResult MessageBox::Show(Window* parent, const StringView& text, const Stri
|
||||
}
|
||||
|
||||
// Show dialog
|
||||
int result = MessageBoxW(parent ? static_cast<HWND>(parent->GetNativePtr()) : nullptr, text.GetText(), caption.GetText(), flags);
|
||||
int result = MessageBoxW(parent ? static_cast<HWND>(parent->GetNativePtr()) : nullptr, String(text).GetText(), String(caption).GetText(), flags);
|
||||
|
||||
// Translate result to dialog result
|
||||
DialogResult dialogResult;
|
||||
@@ -948,10 +948,12 @@ int32 WindowsPlatform::StartProcess(const StringView& filename, const StringView
|
||||
LOG(Info, "Working directory: {0}", workingDir);
|
||||
}
|
||||
|
||||
String filenameString(filename);
|
||||
|
||||
SHELLEXECUTEINFOW shExecInfo = { 0 };
|
||||
shExecInfo.cbSize = sizeof(SHELLEXECUTEINFOW);
|
||||
shExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
|
||||
shExecInfo.lpFile = filename.GetText();
|
||||
shExecInfo.lpFile = filenameString.GetText();
|
||||
shExecInfo.lpParameters = args.HasChars() ? args.Get() : nullptr;
|
||||
shExecInfo.lpDirectory = workingDir.HasChars() ? workingDir.Get() : nullptr;
|
||||
shExecInfo.nShow = hiddenWindow ? SW_HIDE : SW_SHOW;
|
||||
@@ -1109,7 +1111,7 @@ int32 WindowsPlatform::RunProcess(const StringView& cmdLine, const StringView& w
|
||||
|
||||
// Create the process
|
||||
PROCESS_INFORMATION procInfo;
|
||||
if (!CreateProcessW(nullptr, const_cast<LPWSTR>(cmdLine.GetText()), nullptr, nullptr, TRUE, dwCreationFlags, (LPVOID)environmentStr, workingDir.HasChars() ? workingDir.Get() : nullptr, &startupInfoEx.StartupInfo, &procInfo))
|
||||
if (!CreateProcessW(nullptr, const_cast<LPWSTR>(String(cmdLine).GetText()), nullptr, nullptr, TRUE, dwCreationFlags, (LPVOID)environmentStr, String(workingDir).GetText(), &startupInfoEx.StartupInfo, &procInfo))
|
||||
{
|
||||
LOG(Warning, "Cannot start process '{0}'. Error code: 0x{1:x}", cmdLine, static_cast<int64>(GetLastError()));
|
||||
goto ERROR_EXIT;
|
||||
|
||||
@@ -166,7 +166,7 @@ namespace Flax.Build.Bindings
|
||||
if (typeInfo.Type == "String")
|
||||
return $"(StringView){value}";
|
||||
if (typeInfo.IsPtr && typeInfo.IsConst && typeInfo.Type == "Char")
|
||||
return $"((StringView){value}).GetText()";
|
||||
return $"((StringView){value}).GetNonTerminatedText()"; // This is a bug, as we need a null-terminated strig here. Any idea how to fix it?
|
||||
if (typeInfo.Type == "AssetReference" || typeInfo.Type == "WeakAssetReference")
|
||||
return $"ScriptingObject::Cast<{typeInfo.GenericArgs[0].Type}>((Asset*){value})";
|
||||
if (typeInfo.Type == "ScriptingObjectReference" || typeInfo.Type == "SoftObjectReference")
|
||||
|
||||
Reference in New Issue
Block a user