summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRye <rye@alchemyviewer.org>2025-12-30 11:39:16 -0500
committerAndrey Kleshchev <117672381+akleshchev@users.noreply.github.com>2026-01-07 02:15:43 +0200
commit25dc8660efedecfd9f021142ac1e4ff3639e80d4 (patch)
tree3751a0f21917bbe3d460ae2b613c7e5070d55dae
parentb74a3c25d16685b8dfad8880e20ac99c5769d2e4 (diff)
Clean up LLFile and LLFilesystem operations to reduce temporaries allocations and utf8->utf16 conversions
Fix LLFile::tmpdir failing when temp directory is located in a unicode path on windows Add Tracy profiler tagging to LLFile that's disabled by default Replace LLFile::utf8StringToWstring with our fsyspath std::filesystem::path adapter Introduce std::filesystem::path to llifstream/llofstream wrappers Add move operators to fsyspath to match copy operator Restore LLUniqueFile RAII class for direct c file io wrapping and reducing merge conflicts with downstream code that may depend upon it Signed-off-by: Rye <rye@alchemyviewer.org>
-rw-r--r--indra/llappearance/llpolymesh.cpp2
-rw-r--r--indra/llcommon/fsyspath.h4
-rw-r--r--indra/llcommon/llcrc.cpp2
-rw-r--r--indra/llcommon/llcrc.h2
-rwxr-xr-xindra/llcommon/llfile.cpp290
-rwxr-xr-xindra/llcommon/llfile.h465
-rw-r--r--indra/llcommon/llprocessor.cpp4
-rw-r--r--indra/llcommon/llprofilercategories.h9
-rw-r--r--indra/llcommon/llsys.cpp6
-rw-r--r--indra/llcommon/tests/llfile_test.cpp115
-rwxr-xr-xindra/llfilesystem/lldir.cpp15
-rw-r--r--indra/llfilesystem/lldir.h2
-rw-r--r--indra/llfilesystem/lldir_linux.cpp18
-rw-r--r--indra/llfilesystem/lldir_linux.h1
-rw-r--r--indra/llfilesystem/lldir_mac.cpp8
-rw-r--r--indra/llfilesystem/lldir_mac.h1
-rw-r--r--indra/llfilesystem/lldir_win32.cpp7
-rw-r--r--indra/llfilesystem/lldir_win32.h1
-rwxr-xr-xindra/llfilesystem/llfilesystem.cpp81
-rw-r--r--indra/llfilesystem/llfilesystem.h5
-rw-r--r--indra/llfilesystem/tests/lldir_test.cpp2
-rw-r--r--indra/llimage/llimagedimensionsinfo.cpp2
-rw-r--r--indra/llimage/llimagetga.cpp2
-rw-r--r--indra/llmessage/llassetstorage.cpp2
-rw-r--r--indra/llmessage/lltransfersourcefile.cpp2
-rw-r--r--indra/llmessage/lltransfertargetfile.cpp2
-rw-r--r--indra/llmessage/llxfer_file.cpp16
-rw-r--r--indra/llmessage/message.cpp4
-rw-r--r--indra/llmessage/tests/lldatapacker_test.cpp4
-rw-r--r--indra/llrender/llshadermgr.cpp4
-rw-r--r--indra/llui/lluicolortable.cpp2
-rw-r--r--indra/llui/llxuiparser.cpp6
-rw-r--r--indra/llxml/llcontrol.cpp2
-rw-r--r--indra/llxml/llxmlparser.cpp4
-rw-r--r--indra/newview/llconversationlog.cpp4
-rw-r--r--indra/newview/lldrawpoolbump.cpp2
-rwxr-xr-xindra/newview/llfloaterpreference.cpp10
-rwxr-xr-xindra/newview/llfloateruipreview.cpp2
-rw-r--r--indra/newview/llinventorymodel.cpp4
-rw-r--r--indra/newview/llkeyconflict.cpp2
-rw-r--r--indra/newview/lllogchat.cpp12
-rw-r--r--indra/newview/llmutelist.cpp8
-rw-r--r--indra/newview/llpreviewnotecard.cpp4
-rw-r--r--indra/newview/llpreviewscript.cpp4
-rw-r--r--indra/newview/llstartup.cpp6
-rw-r--r--indra/newview/lltoolbarview.cpp2
-rw-r--r--indra/newview/llviewerassetstorage.cpp4
-rw-r--r--indra/newview/llviewerinput.cpp2
-rw-r--r--indra/newview/llviewermenufile.cpp2
-rw-r--r--indra/newview/llviewerstatsrecorder.cpp2
50 files changed, 678 insertions, 484 deletions
diff --git a/indra/llappearance/llpolymesh.cpp b/indra/llappearance/llpolymesh.cpp
index d5323e0b84..b579dc007b 100644
--- a/indra/llappearance/llpolymesh.cpp
+++ b/indra/llappearance/llpolymesh.cpp
@@ -280,7 +280,7 @@ bool LLPolyMeshSharedData::loadMesh( const std::string& fileName )
LL_ERRS() << "Filename is Empty!" << LL_ENDL;
return false;
}
- LLFILE* fp = LLFile::fopen(fileName, "rb"); /*Flawfinder: ignore*/
+ LLFILE* fp = LLFile::fopen(fileName, TEXT("rb")); /*Flawfinder: ignore*/
if (!fp)
{
LLError::LLUserWarningMsg::showMissingFiles();
diff --git a/indra/llcommon/fsyspath.h b/indra/llcommon/fsyspath.h
index 2c900c02a7..237d99ae86 100644
--- a/indra/llcommon/fsyspath.h
+++ b/indra/llcommon/fsyspath.h
@@ -57,7 +57,7 @@ class fsyspath: public std::filesystem::path
public:
// default
- fsyspath() {}
+ fsyspath() = default;
// construct from UTF-8 encoded string
fsyspath(const std::string& path): fsyspath(std::string_view(path)) {}
fsyspath(const char* path): fsyspath(std::string_view(path)) {}
@@ -66,8 +66,10 @@ public:
{}
// construct from existing path
fsyspath(const super& path): super(path) {}
+ fsyspath(super&& path) : super(std::move(path)) {}
fsyspath& operator=(const super& p) { super::operator=(p); return *this; }
+ fsyspath& operator=(super&& p) { super::operator=(std::move(p)); return *this; }
fsyspath& operator=(const std::string& p) { return (*this) = std::string_view(p); }
fsyspath& operator=(const char* p) { return (*this) = std::string_view(p); }
fsyspath& operator=(std::string_view p)
diff --git a/indra/llcommon/llcrc.cpp b/indra/llcommon/llcrc.cpp
index d79d06e2a2..f836a12c35 100644
--- a/indra/llcommon/llcrc.cpp
+++ b/indra/llcommon/llcrc.cpp
@@ -166,7 +166,7 @@ void LLCRC::update(const std::string& filename)
return;
}
- FILE* fp = LLFile::fopen(filename, "rb"); /* Flawfinder: ignore */
+ FILE* fp = LLFile::fopen(filename, TEXT("rb")); /* Flawfinder: ignore */
if (fp)
{
diff --git a/indra/llcommon/llcrc.h b/indra/llcommon/llcrc.h
index a3bde47780..cbf4cf4e75 100644
--- a/indra/llcommon/llcrc.h
+++ b/indra/llcommon/llcrc.h
@@ -36,7 +36,7 @@
// example (don't try this at work kids):
//
// LLCRC crc;
-// FILE* fp = LLFile::fopen(filename,"rb");
+// FILE* fp = LLFile::fopen(filename,TEXT("rb"));
// while(!feof(fp)) {
// crc.update(fgetc(fp));
// }
diff --git a/indra/llcommon/llfile.cpp b/indra/llcommon/llfile.cpp
index 0ceb2eb03b..114df29f6e 100755
--- a/indra/llcommon/llfile.cpp
+++ b/indra/llcommon/llfile.cpp
@@ -226,7 +226,7 @@ static void find_locking_process(const std::string& filename)
}
#endif // LL_WINDOWS hack to identify processes holding file open
-static int warnif(std::string_view desc, const std::string& filename, int rc, int suppress_warning = 0)
+static int warnif(std::string_view desc, const std::filesystem::path& filename, int rc, int suppress_warning = 0)
{
if (rc < 0)
{
@@ -252,7 +252,7 @@ static int warnif(std::string_view desc, const std::string& filename, int rc, in
return rc;
}
-static int warnif(std::string_view desc, const std::string& filename, const std::error_code& ec, int suppress_warning = 0)
+static int warnif(std::string_view desc, const std::filesystem::path& filename, const std::error_code& ec, int suppress_warning = 0)
{
if (ec)
{
@@ -506,8 +506,9 @@ inline bool are_open_mode_flags_invalid(std::ios_base::openmode omode)
//----------------------------------------------------------------------------------------
// class member functions
//----------------------------------------------------------------------------------------
-int LLFile::open(const std::string& filename, std::ios_base::openmode omode, std::error_code& ec, int perm)
+int LLFile::open(const std::filesystem::path& file_path, std::ios_base::openmode omode, std::error_code& ec, int perm)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_FILE;
close(ec);
if (are_open_mode_flags_invalid(omode))
{
@@ -519,14 +520,13 @@ int LLFile::open(const std::string& filename, std::ios_base::openmode omode, std
create = decode_open_create_flags(omode),
attributes = decode_attributes(omode, perm);
- std::wstring file_path = utf8StringToWstring(filename);
- mHandle = CreateFileW(file_path.c_str(), access, share, nullptr, create, attributes, nullptr);
+ mHandle = CreateFileW(file_path.native().c_str(), access, share, nullptr, create, attributes, nullptr);
// The dwShareMode = share parameter takes care of locking the file for other processes if indicated,
// no need to do anything else for file locking here
#else
int oflags = decode_open_mode(omode);
int lmode = omode & LLFile::lock_mask;
- mHandle = ::open(filename.c_str(), oflags, perm);
+ mHandle = ::open(file_path.native().c_str(), oflags, perm);
if (mHandle != InvalidHandle && lmode && lock(lmode | LLFile::noblock, ec) != 0)
{
close();
@@ -549,6 +549,7 @@ int LLFile::open(const std::string& filename, std::ios_base::openmode omode, std
S64 LLFile::size(std::error_code& ec)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_FILE;
#if LL_WINDOWS
LARGE_INTEGER value = { 0 };
if (GetFileSizeEx(mHandle, &value))
@@ -570,6 +571,7 @@ S64 LLFile::size(std::error_code& ec)
S64 LLFile::tell(std::error_code& ec)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_FILE;
#if LL_WINDOWS
LARGE_INTEGER value = { 0 };
if (SetFilePointerEx(mHandle, value, &value, FILE_CURRENT))
@@ -595,6 +597,7 @@ int LLFile::seek(S64 pos, std::error_code& ec)
int LLFile::seek(S64 offset, std::ios_base::seekdir dir, std::error_code& ec)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_FILE;
S64 newOffset = 0;
#if LL_WINDOWS
DWORD seekdir = seek_mode_from_dir(dir);
@@ -620,6 +623,7 @@ inline DWORD next_buffer_size(S64 nbytes)
S64 LLFile::read(void* buffer, S64 nbytes, std::error_code& ec)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_FILE;
if (nbytes == 0)
{
// Nothing to do
@@ -660,6 +664,7 @@ S64 LLFile::read(void* buffer, S64 nbytes, std::error_code& ec)
S64 LLFile::write(const void* buffer, S64 nbytes, std::error_code& ec)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_FILE;
if (nbytes == 0)
{
// Nothing to do here
@@ -705,6 +710,7 @@ S64 LLFile::write(const void* buffer, S64 nbytes, std::error_code& ec)
S64 LLFile::printf(const char* fmt, ...)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_FILE;
va_list args1;
va_start(args1, fmt);
va_list args2;
@@ -732,6 +738,7 @@ S64 LLFile::printf(const char* fmt, ...)
int LLFile::lock(int mode, std::error_code& ec)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_FILE;
#if LL_WINDOWS
if (!(mode & LLFile::lock_mask))
{
@@ -765,6 +772,7 @@ int LLFile::lock(int mode, std::error_code& ec)
int LLFile::close(std::error_code& ec)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_FILE;
if (mHandle != InvalidHandle)
{
llfile_handle_t handle = InvalidHandle;
@@ -792,8 +800,9 @@ int LLFile::close()
//----------------------------------------------------------------------------------------
// static
-LLFILE* LLFile::fopen(const std::string& filename, const char* mode, int lmode)
+LLFILE* LLFile::fopen(const std::filesystem::path& file_path, const fopen_flags_t* mode, int lmode)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_FILE;
LLFILE* file;
#if LL_WINDOWS
int shflag = _SH_DENYNO;
@@ -806,11 +815,9 @@ LLFILE* LLFile::fopen(const std::string& filename, const char* mode, int lmode)
shflag = _SH_DENYWR;
break;
}
- std::wstring file_path = utf8StringToWstring(filename);
- std::wstring utf16mode = ll_convert<std::wstring>(std::string(mode));
- file = _wfsopen(file_path.c_str(), utf16mode.c_str(), shflag);
+ file = _wfsopen(file_path.native().c_str(), mode, shflag);
#else
- file = ::fopen(filename.c_str(), mode);
+ file = ::fopen(file_path.native().c_str(), mode);
if (file && (lmode & (LLFile::lock_mask)))
{
// Rather fail on a sharing conflict than block
@@ -827,6 +834,7 @@ LLFILE* LLFile::fopen(const std::string& filename, const char* mode, int lmode)
// static
int LLFile::close(LLFILE* file)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_FILE;
int ret_value = 0;
if (file)
{
@@ -836,17 +844,11 @@ int LLFile::close(LLFILE* file)
}
// static
-std::string LLFile::getContents(const std::string& filename)
-{
- std::error_code ec;
- return getContents(filename, ec);
-}
-
-// static
-std::string LLFile::getContents(const std::string& filename, std::error_code& ec)
+std::string LLFile::getContents(const std::filesystem::path& file_path, std::error_code& ec)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_FILE;
std::string buffer;
- LLFile file(filename, LLFile::in | LLFile::binary, ec);
+ LLFile file(file_path, LLFile::in | LLFile::binary, ec);
if (file)
{
S64 length = file.size(ec);
@@ -864,48 +866,41 @@ std::string LLFile::getContents(const std::string& filename, std::error_code& ec
}
// static
-int LLFile::mkdir(const std::string& dirname)
+int LLFile::mkdir(const std::filesystem::path& file_path)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_FILE;
std::error_code ec;
- std::filesystem::path file_path = utf8StringToPath(dirname);
// We often use mkdir() to ensure the existence of a directory that might
// already exist. There is no known case in which we want to call out as
// an error the requested directory already existing.
std::filesystem::create_directory(file_path, ec);
// The return value is only true if the directory was actually created.
// But if it already existed, ec still indicates success.
- return warnif("mkdir", dirname, ec);
+ return warnif("mkdir", file_path, ec);
}
// static
-int LLFile::remove(const std::string& filename, int suppress_warning)
+int LLFile::remove(const std::filesystem::path& file_path, int suppress_warning)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_FILE;
std::error_code ec;
- std::filesystem::path file_path = utf8StringToPath(filename);
std::filesystem::remove(file_path, ec);
- return warnif("remove", filename, ec, suppress_warning);
+ return warnif("remove", file_path, ec, suppress_warning);
}
// static
-int LLFile::rename(const std::string& filename, const std::string& newname, int suppress_warning)
+int LLFile::rename(const std::filesystem::path& file_path, const std::filesystem::path& new_path, int suppress_warning)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_FILE;
std::error_code ec;
- std::filesystem::path file_path = utf8StringToPath(filename);
- std::filesystem::path new_path = utf8StringToPath(newname);
std::filesystem::rename(file_path, new_path, ec);
- return warnif(STRINGIZE("rename to '" << newname << "' from"), filename, ec, suppress_warning);
-}
-
-// static
-S64 LLFile::read(const std::string& filename, void* buf, S64 offset, S64 nbytes)
-{
- std::error_code ec;
- return read(filename, buf, offset, nbytes, ec);
+ return warnif("rename", file_path, ec, suppress_warning);
}
// static
-S64 LLFile::read(const std::string& filename, void* buf, S64 offset, S64 nbytes, std::error_code& ec)
+S64 LLFile::read(const std::filesystem::path& file_path, void* buf, S64 offset, S64 nbytes, std::error_code& ec)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_FILE;
// if number of bytes is 0 or less there is nothing to do here
if (nbytes <= 0)
{
@@ -921,7 +916,7 @@ S64 LLFile::read(const std::string& filename, void* buf, S64 offset, S64 nbytes,
{
std::ios_base::openmode omode = LLFile::in | LLFile::binary;
- LLFile file(filename, omode, ec);
+ LLFile file(file_path, omode, ec);
if (!ec && (bool)file)
{
if (offset > 0)
@@ -939,19 +934,13 @@ S64 LLFile::read(const std::string& filename, void* buf, S64 offset, S64 nbytes,
}
}
}
- return warnif("read from file failed", filename, ec);
+ return warnif("read from file failed", file_path, ec);
}
// static
-S64 LLFile::write(const std::string& filename, const void* buf, S64 offset, S64 nbytes)
-{
- std::error_code ec;
- return write(filename, buf, offset, nbytes, ec);
-}
-
-// static
-S64 LLFile::write(const std::string& filename, const void* buf, S64 offset, S64 nbytes, std::error_code& ec)
+S64 LLFile::write(const std::filesystem::path& file_path, const void* buf, S64 offset, S64 nbytes, std::error_code& ec)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_FILE;
// if number of bytes is 0 or less there is nothing to do here
if (nbytes <= 0)
{
@@ -971,7 +960,7 @@ S64 LLFile::write(const std::string& filename, const void* buf, S64 offset, S64
omode |= LLFile::app;
}
- LLFile file(filename, omode, ec);
+ LLFile file(file_path, omode, ec);
if (!ec && (bool)file)
{
if (offset > 0)
@@ -989,99 +978,52 @@ S64 LLFile::write(const std::string& filename, const void* buf, S64 offset, S64
}
}
}
- return warnif("write to file failed", filename, ec);
+ return warnif("write to file failed", file_path, ec);
}
// static
-bool LLFile::copy(const std::string& source, const std::string& target)
+bool LLFile::copy(const std::filesystem::path& source_path, const std::filesystem::path& target_path, std::filesystem::copy_options options, std::error_code& ec)
{
- std::error_code ec;
- return copy(source, target, std::filesystem::copy_options::overwrite_existing, ec);
-}
-
-// static
-bool LLFile::copy(const std::string& source, const std::string& target, std::filesystem::copy_options options, std::error_code& ec)
-{
- std::filesystem::path source_path = utf8StringToPath(source);
- std::filesystem::path target_path = utf8StringToPath(target);
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_FILE;
bool copied = std::filesystem::copy_file(source_path, target_path, options, ec);
if (!copied)
{
- warnif(STRINGIZE("copy failed, to '" << target << "' from"), source, ec);
+ warnif(STRINGIZE("copy failed, to '" << target_path << "' from"), source_path, ec);
}
return copied;
}
// static
-int LLFile::stat(const std::string& filename, llstat* filestatus, const char *fname, int suppress_warning)
+int LLFile::stat(const std::filesystem::path& file_path, llstat* filestatus, const char *fname, int suppress_warning)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_FILE;
#if LL_WINDOWS
- std::wstring file_path = utf8StringToWstring(filename);
- int rc = _wstat64(file_path.c_str(), filestatus);
+ int rc = _wstat64(file_path.native().c_str(), filestatus);
#else
- int rc = ::stat(filename.c_str(), filestatus);
+ int rc = ::stat(file_path.native().c_str(), filestatus);
#endif
- return warnif(fname ? fname : "stat", filename, rc, suppress_warning);
+ return warnif(fname ? fname : "stat", file_path, rc, suppress_warning);
}
// static
-std::time_t LLFile::getCreationTime(const std::string& filename, int suppress_warning)
-{
- // As of C++20 there is no functionality in std::filesystem to retrieve this information
- llstat filestat;
- int rc = stat(filename, &filestat, "getCreationTime", suppress_warning);
- if (rc == 0)
- {
-#if LL_DARWIN
- return filestat.st_birthtime;
-#else
- // Linux stat() doesn't have a creation/birth time (st_ctime really is the last status
- // change or inode attributes change) unless we would use statx() instead. But that is
- // a major effort, which would require Linux specific changes to LLFile::stat() above
- // and possibly adaptions for other platforms that we leave for a later exercise if it
- // is ever desired.
- return filestat.st_ctime;
-#endif
- }
- return 0;
-}
-
-// static
-std::time_t LLFile::getModificationTime(const std::string& filename, int suppress_warning)
-{
- // tried to use std::filesystem::last_write_time() but the whole std::chrono infrastructure is as of
- // C++20 still not fully implemented on all platforms. Specifically MacOS C++20 seems lacking here,
- // and Windows requires a roundabout through std::chrono::utc_clock to then get a
- // std::chrono::system_clock that can return a more useful time_t.
- // So we take the easy way out in a similar way as with getCreationTime().
- llstat filestat;
- int rc = stat(filename, &filestat, "getModificationTime", suppress_warning);
- if (rc == 0)
- {
- return filestat.st_mtime;
- }
- return 0;
-}
-
-// static
-S64 LLFile::size(const std::string& filename, int suppress_warning)
+S64 LLFile::size(const std::filesystem::path& file_path, int suppress_warning)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_FILE;
std::error_code ec;
- std::filesystem::path file_path = utf8StringToPath(filename);
std::intmax_t size = static_cast<std::intmax_t>(std::filesystem::file_size(file_path, ec));
if (ec)
{
- warnif("size", filename, ec, suppress_warning);
+ warnif("size", file_path, ec, suppress_warning);
return 0;
}
return size;
}
// static
-std::filesystem::file_status LLFile::getStatus(const std::string& filename, bool dontFollowSymLink, int suppress_warning)
+std::filesystem::file_status LLFile::getStatus(const std::filesystem::path& file_path, bool dontFollowSymLink, int suppress_warning)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_FILE;
std::error_code ec;
- std::filesystem::path file_path = utf8StringToPath(filename);
std::filesystem::file_status status;
if (dontFollowSymLink)
{
@@ -1091,100 +1033,43 @@ std::filesystem::file_status LLFile::getStatus(const std::string& filename, bool
{
status = std::filesystem::status(file_path, ec);
}
- warnif("getStatus()", filename, ec, suppress_warning);
+ warnif("getStatus()", file_path, ec, suppress_warning);
return status;
}
// static
-bool LLFile::exists(const std::string& filename)
-{
- std::filesystem::file_status status = getStatus(filename);
- return std::filesystem::exists(status);
-}
-
-// static
-bool LLFile::isdir(const std::string& filename)
-{
- std::filesystem::file_status status = getStatus(filename);
- return std::filesystem::is_directory(status);
-}
-
-// static
-bool LLFile::isfile(const std::string& filename)
-{
- std::filesystem::file_status status = getStatus(filename);
- return std::filesystem::is_regular_file(status);
-}
-
-// static
-bool LLFile::islink(const std::string& filename)
-{
- std::filesystem::file_status status = getStatus(filename, true);
- return std::filesystem::is_symlink(status);
-}
-
-// static
const std::string& LLFile::tmpdir()
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_FILE;
static std::string temppath;
if (temppath.empty())
{
- temppath = std::filesystem::temp_directory_path().string();
- }
-
#if LL_WINDOWS
- char sep = '\\';
+ temppath = ll_convert<std::string>(std::filesystem::temp_directory_path().native());
+ char sep = '\\';
#else
- char sep = '/';
+ temppath = std::filesystem::temp_directory_path().string();
+ char sep = '/';
#endif
- if (temppath[temppath.size() - 1] != sep)
- {
- temppath += sep;
+ if (temppath[temppath.size() - 1] != sep)
+ {
+ temppath += sep;
+ }
}
+
return temppath;
}
-// static
-std::filesystem::path LLFile::utf8StringToPath(const std::string& pathname)
-{
#if LL_WINDOWS
- return ll_convert<std::wstring>(pathname);
-#else
- return pathname;
-#endif
-}
-#if LL_WINDOWS
+/************** input file stream ********************************/
-// static
-std::wstring LLFile::utf8StringToWstring(const std::string& pathname)
+// explicit
+llifstream::llifstream(const char* _Filename, ios_base::openmode _Mode) :
+ std::ifstream(ll_convert<std::wstring>(_Filename).c_str(), _Mode | ios_base::in)
{
- std::wstring utf16string(ll_convert<std::wstring>(pathname));
- if (utf16string.size() >= MAX_PATH)
- {
- // By going through std::filesystem::path we get a lot of path sanitation done for us that
- // is needed when passing a path with a kernel object space prefix to Windows API functions
- // since this prefix disables the kernel32 path normalization
- std::filesystem::path utf16path(utf16string);
-
- // By prepending "\\?\" to a path, Windows widechar file APIs will not fail on long path names
- utf16string.assign(L"\\\\?\\").append(utf16path);
-
- /* remove trailing spaces and dots (yes, Windows really does that) */
- size_t last_valid = utf16string.find_last_not_of(L" \t.");
- if (last_valid == std::wstring::npos)
- {
- return std::wstring();
- }
- return utf16string.substr(0, last_valid + 1);
- }
- return utf16string;
}
-/************** input file stream ********************************/
-
-llifstream::llifstream() {}
-
// explicit
llifstream::llifstream(const std::string& _Filename, ios_base::openmode _Mode):
std::ifstream(ll_convert<std::wstring>( _Filename ).c_str(),
@@ -1192,15 +1077,37 @@ llifstream::llifstream(const std::string& _Filename, ios_base::openmode _Mode):
{
}
+// explicit
+llifstream::llifstream(const std::filesystem::path& _Filepath, ios_base::openmode _Mode) :
+ std::ifstream(_Filepath, _Mode | ios_base::in)
+{
+}
+
+void llifstream::open(const char* _Filename, ios_base::openmode _Mode)
+{
+ std::ifstream::open(ll_convert<std::wstring>(_Filename).c_str(),
+ _Mode | ios_base::in);
+}
+
void llifstream::open(const std::string& _Filename, ios_base::openmode _Mode)
{
std::ifstream::open(ll_convert<std::wstring>(_Filename).c_str(),
_Mode | ios_base::in);
}
+void llifstream::open(const std::filesystem::path& _Filepath, ios_base::openmode _Mode)
+{
+ std::ifstream::open(_Filepath,
+ _Mode | ios_base::in);
+}
+
/************** output file stream ********************************/
-llofstream::llofstream() {}
+// explicit
+llofstream::llofstream(const char* _Filename, ios_base::openmode _Mode) :
+ std::ofstream(ll_convert<std::wstring>(_Filename).c_str(), _Mode | ios_base::out)
+{
+}
// explicit
llofstream::llofstream(const std::string& _Filename, ios_base::openmode _Mode):
@@ -1209,10 +1116,27 @@ llofstream::llofstream(const std::string& _Filename, ios_base::openmode _Mode):
{
}
+// explicit
+llofstream::llofstream(const std::filesystem::path& _Filepath, ios_base::openmode _Mode) :
+ std::ofstream(_Filepath, _Mode | ios_base::out)
+{
+}
+
+void llofstream::open(const char* _Filename, ios_base::openmode _Mode)
+{
+ std::ofstream::open(ll_convert<std::wstring>(_Filename).c_str(), _Mode | ios_base::out);
+}
+
void llofstream::open(const std::string& _Filename, ios_base::openmode _Mode)
{
std::ofstream::open(ll_convert<std::wstring>( _Filename ).c_str(),
_Mode | ios_base::out);
}
+void llofstream::open(const std::filesystem::path& _Filepath, ios_base::openmode _Mode)
+{
+ std::ofstream::open(_Filepath,
+ _Mode | ios_base::out);
+}
+
#endif // LL_WINDOWS
diff --git a/indra/llcommon/llfile.h b/indra/llcommon/llfile.h
index dcd561ce7f..7e8e114098 100755
--- a/indra/llcommon/llfile.h
+++ b/indra/llcommon/llfile.h
@@ -35,6 +35,8 @@
* Attempts to mostly mirror the POSIX style IO functions.
*/
+#include "stdtypes.h"
+
#include <fstream>
#include <filesystem>
#include <sys/stat.h>
@@ -51,15 +53,24 @@ typedef struct stat llstat;
typedef FILE LLFILE;
+#include "fsyspath.h"
#include "llstring.h" // safe char* -> std::string conversion
+#ifndef TEXT
+#if LL_WINDOWS
+#define TEXT(flags) L##flags
+#else
+#define TEXT(flags) flags
+#endif
+#endif
+
/// This class provides a selection of functions to operate on files through names and
/// a class implementation to represent a file for reading and writing to it
/// All the functions with a path string input take UTF8 path/filenames
///
/// @nosubgrouping
///
-class LL_COMMON_API LLFile
+class LLFile
{
public:
// ================================================================================
@@ -157,12 +168,24 @@ public:
}
/// constructor opening the file
- LLFile(const std::string& filename, std::ios_base::openmode omode, std::error_code& ec, int perm = 0666) :
+ explicit LLFile(const char* filename, std::ios_base::openmode omode, std::error_code& ec, int perm = 0666) :
+ mHandle(InvalidHandle)
+ {
+ open(filename, omode, ec, perm);
+ }
+
+ explicit LLFile(const std::string& filename, std::ios_base::openmode omode, std::error_code& ec, int perm = 0666) :
mHandle(InvalidHandle)
{
open(filename, omode, ec, perm);
}
+ explicit LLFile(const std::filesystem::path& file_path, std::ios_base::openmode omode, std::error_code& ec, int perm = 0666) :
+ mHandle(InvalidHandle)
+ {
+ open(file_path, omode, ec, perm);
+ }
+
/// destructor always attempts to close the file
~LLFile() { close(); }
///@}
@@ -198,7 +221,17 @@ public:
///@{
/// Open a file with the specific open mode flags
- int open(const std::string& filename, std::ios_base::openmode omode, std::error_code& ec, int perm = 0666);
+ inline int open(const char* filename, std::ios_base::openmode omode, std::error_code& ec, int perm = 0666)
+ {
+ std::filesystem::path file_path = fsyspath(filename);
+ return open(file_path, omode, ec, perm);
+ }
+ inline int open(const std::string& filename, std::ios_base::openmode omode, std::error_code& ec, int perm = 0666)
+ {
+ std::filesystem::path file_path = fsyspath(filename);
+ return open(file_path, omode, ec, perm);
+ }
+ int open(const std::filesystem::path& filename, std::ios_base::openmode omode, std::error_code& ec, int perm = 0666);
///< @returns 0 on success, -1 on failure
/// Determine the size of the opened file
@@ -257,7 +290,23 @@ public:
///
///@{
/// open a file with the specified access mode
- static LLFILE* fopen(const std::string& filename, const char* accessmode, int lmode = 0);
+ ///
+#if LL_WINDOWS
+ using fopen_flags_t = wchar_t;
+#else
+ using fopen_flags_t = char;
+#endif
+ inline static LLFILE* fopen(const char* filename, const fopen_flags_t* accessmode, int lmode = 0)
+ {
+ std::filesystem::path file_path = fsyspath(filename);
+ return LLFile::fopen(file_path, accessmode, lmode);
+ }
+ inline static LLFILE* fopen(const std::string& filename, const fopen_flags_t* accessmode, int lmode = 0)
+ {
+ std::filesystem::path file_path = fsyspath(filename);
+ return LLFile::fopen(file_path, accessmode, lmode);
+ }
+ static LLFILE* fopen(const std::filesystem::path& file_path, const fopen_flags_t* accessmode, int lmode = 0);
///< 'accessmode' follows the rules of the Posix fopen() mode parameter
/// "r" open the file for reading only and positions the stream at the beginning
/// "r+" open the file for reading and writing and positions the stream at the beginning
@@ -291,19 +340,63 @@ public:
///< @returns 0 on success and -1 on failure.
/// create a directory
- static int mkdir(const std::string& filename);
+ inline static int mkdir(const char* dirname)
+ {
+ std::filesystem::path dir_path = fsyspath(dirname);
+ return mkdir(dir_path);
+ }
+ inline static int mkdir(const std::string& dirname)
+ {
+ std::filesystem::path dir_path = fsyspath(dirname);
+ return mkdir(dir_path);
+ }
+ static int mkdir(const std::filesystem::path& dirname);
///< mkdir() considers "directory already exists" to be not an error.
/// @returns 0 on success and -1 on failure.
/// remove a file or directory
- static int remove(const std::string& filename, int suppress_warning = 0);
+ inline static int remove(const char* filename, int suppress_warning = 0)
+ {
+ std::filesystem::path file_path = fsyspath(filename);
+ return remove(file_path, suppress_warning);
+ }
+ inline static int remove(const std::string& filename, int suppress_warning = 0)
+ {
+ std::filesystem::path file_path = fsyspath(filename);
+ return remove(file_path, suppress_warning);
+ }
+ static int remove(const std::filesystem::path& file_path, int suppress_warning = 0);
///< pass an errno value (e.g., ENOENT) in the optional 'suppress_warning' parameter if you want to
/// suppress a warning in the log when the failure matches that errno (e.g., suppress warning if
/// the file or directory does not exist)
/// @returns 0 on success and -1 on failure.
/// rename a file
- static int rename(const std::string& filename, const std::string& newname, int suppress_warning = 0);
+ inline static int rename(const char* filename, const char* newname, int suppress_warning = 0)
+ {
+ std::filesystem::path file_path = fsyspath(filename);
+ std::filesystem::path new_path = fsyspath(newname);
+ return rename(file_path, new_path, suppress_warning);
+ }
+ inline static int rename(const std::string& filename, const char* newname, int suppress_warning = 0)
+ {
+ std::filesystem::path file_path = fsyspath(filename);
+ std::filesystem::path new_path = fsyspath(newname);
+ return rename(file_path, new_path, suppress_warning);
+ }
+ inline static int rename(const char* filename, const std::string& newname, int suppress_warning = 0)
+ {
+ std::filesystem::path file_path = fsyspath(filename);
+ std::filesystem::path new_path = fsyspath(newname);
+ return rename(file_path, new_path, suppress_warning);
+ }
+ inline static int rename(const std::string& filename, const std::string& newname, int suppress_warning = 0)
+ {
+ std::filesystem::path file_path = fsyspath(filename);
+ std::filesystem::path new_path = fsyspath(newname);
+ return rename(file_path, new_path, suppress_warning);
+ }
+ static int rename(const std::filesystem::path& file_path, const std::filesystem::path& new_path, int suppress_warning = 0);
///< it will silently overwrite newname if it exists without returning an error
/// Posix guarantees that if newname already exists, then there will be no moment
/// in which for other processes newname does not exist. There is no such guarantee
@@ -312,7 +405,31 @@ public:
/// @returns 0 on success and -1 on failure.
/// copy the contents of the file from 'source' to 'target'
- static bool copy(const std::string& source, const std::string& target);
+ inline static bool copy(const char* source, const char* target)
+ {
+ std::error_code ec;
+ return copy(source, target, std::filesystem::copy_options::overwrite_existing, ec);
+ }
+ inline static bool copy(const char* source, const std::string& target)
+ {
+ std::error_code ec;
+ return copy(source, target, std::filesystem::copy_options::overwrite_existing, ec);
+ }
+ inline static bool copy(const std::string& source, char* target)
+ {
+ std::error_code ec;
+ return copy(source, target, std::filesystem::copy_options::overwrite_existing, ec);
+ }
+ inline static bool copy(const std::string& source, const std::string& target)
+ {
+ std::error_code ec;
+ return copy(source, target, std::filesystem::copy_options::overwrite_existing, ec);
+ }
+ inline static bool copy(const std::filesystem::path& source_path, const std::filesystem::path& target_path)
+ {
+ std::error_code ec;
+ return copy(source_path, target_path, std::filesystem::copy_options::overwrite_existing, ec);
+ }
///< Copies the contents of the file 'source' to the file 'target', overwriting 'target' if it already
/// existed.
/// This is a convenience function that implements the previous behavior of silently overwriting an
@@ -321,7 +438,31 @@ public:
/// @returns true on success and false on failure.
/// copy the contents of the file from 'from' to 'to'
- static bool copy(const std::string& source, const std::string& target, std::filesystem::copy_options options, std::error_code& ec);
+ inline static bool copy(const char* source, const char* target, std::filesystem::copy_options options, std::error_code& ec)
+ {
+ std::filesystem::path source_path = fsyspath(source);
+ std::filesystem::path target_path = fsyspath(target);
+ return copy(source_path, target_path, options, ec);
+ }
+ inline static bool copy(const char* source, const std::string& target, std::filesystem::copy_options options, std::error_code& ec)
+ {
+ std::filesystem::path source_path = fsyspath(source);
+ std::filesystem::path target_path = fsyspath(target);
+ return copy(source_path, target_path, options, ec);
+ }
+ inline static bool copy(const std::string& source, const char* target, std::filesystem::copy_options options, std::error_code& ec)
+ {
+ std::filesystem::path source_path = fsyspath(source);
+ std::filesystem::path target_path = fsyspath(target);
+ return copy(source_path, target_path, options, ec);
+ }
+ inline static bool copy(const std::string& source, const std::string& target, std::filesystem::copy_options options, std::error_code& ec)
+ {
+ std::filesystem::path source_path = fsyspath(source);
+ std::filesystem::path target_path = fsyspath(target);
+ return copy(source_path, target_path, options, ec);
+ }
+ static bool copy(const std::filesystem::path& source_path, const std::filesystem::path& target_path, std::filesystem::copy_options options, std::error_code& ec);
///< Copies the contents of the file 'source' to the file 'target'. The options parameter allows to
/// specify what should happen if the "target" file already exists:
/// std::filesystem::copy_options::none - return an error in ec and fail
@@ -331,48 +472,115 @@ public:
/// @returns true on success and false on failure.
/// retrieve the content of a file into a string
- static std::string getContents(const std::string& filename);
- static std::string getContents(const std::string& filename, std::error_code& ec);
+ inline static std::string getContents(const char* filename)
+ {
+ std::error_code ec;
+ return getContents(filename, ec);
+ }
+ inline static std::string getContents(const std::string& filename)
+ {
+ std::error_code ec;
+ return getContents(filename, ec);
+ }
+ inline static std::string getContents(const std::filesystem::path& file_path)
+ {
+ std::error_code ec;
+ return getContents(file_path, ec);
+ }
+ inline static std::string getContents(const char* filename, std::error_code& ec)
+ {
+ std::filesystem::path file_path = fsyspath(filename);
+ return getContents(file_path, ec);
+ }
+ inline static std::string getContents(const std::string& filename, std::error_code& ec)
+ {
+ std::filesystem::path file_path = fsyspath(filename);
+ return getContents(file_path, ec);
+ }
+ static std::string getContents(const std::filesystem::path& file_path, std::error_code& ec);
///< @returns the entire content of the file as std::string or an empty string on failure
/// read nBytes from the file into the buffer, starting at offset in the file
- static S64 read(const std::string& filename, void* buf, S64 offset, S64 nbytes);
- static S64 read(const std::string& filename, void* buf, S64 offset, S64 nbytes, std::error_code& ec);
+ inline static S64 read(const char* filename, void* buf, S64 offset, S64 nbytes)
+ {
+ std::error_code ec;
+ return read(filename, buf, offset, nbytes, ec);
+ }
+ inline static S64 read(const std::string& filename, void* buf, S64 offset, S64 nbytes)
+ {
+ std::error_code ec;
+ return read(filename, buf, offset, nbytes, ec);
+ }
+ inline static S64 read(const std::filesystem::path& file_path, void* buf, S64 offset, S64 nbytes)
+ {
+ std::error_code ec;
+ return read(file_path, buf, offset, nbytes, ec);
+ }
+ inline static S64 read(const char* filename, void* buf, S64 offset, S64 nbytes, std::error_code& ec)
+ {
+ std::filesystem::path file_path = fsyspath(filename);
+ return read(file_path, buf, offset, nbytes, ec);
+ }
+ inline static S64 read(const std::string& filename, void* buf, S64 offset, S64 nbytes, std::error_code& ec)
+ {
+ std::filesystem::path file_path = fsyspath(filename);
+ return read(file_path, buf, offset, nbytes, ec);
+ }
+ static S64 read(const std::filesystem::path& filename, void* buf, S64 offset, S64 nbytes, std::error_code& ec);
///< @returns bytes read on success, or -1 on failure
/// write nBytes from the buffer into the file, starting at offset in the file
- static S64 write(const std::string& filename, const void* buf, S64 offset, S64 nbytes);
- static S64 write(const std::string& filename, const void* buf, S64 offset, S64 nbytes, std::error_code& ec);
+ inline static S64 write(const std::string& filename, const void* buf, S64 offset, S64 nbytes)
+ {
+ std::error_code ec;
+ std::filesystem::path file_path = fsyspath(filename);
+ return write(file_path, buf, offset, nbytes, ec);
+ }
+ inline static S64 write(const std::filesystem::path& filename, const void* buf, S64 offset, S64 nbytes)
+ {
+ std::error_code ec;
+ std::filesystem::path file_path = fsyspath(filename);
+ return write(file_path, buf, offset, nbytes, ec);
+ }
+ inline static S64 write(const std::string& filename, const void* buf, S64 offset, S64 nbytes, std::error_code& ec)
+ {
+ std::filesystem::path file_path = fsyspath(filename);
+ return write(file_path, buf, offset, nbytes, ec);
+ }
+ static S64 write(const std::filesystem::path& filename, const void* buf, S64 offset, S64 nbytes, std::error_code& ec);
///< If a negative offset is provided, the file is opened in append mode and the
/// write will be appended to the end of the file.
/// @returns bytes written on success, or -1 on failure
/// return the file stat structure for filename
- static int stat(const std::string& filename, llstat* file_status, const char *operation = nullptr, int suppress_warning = ENOENT);
+ inline static int stat(const char* filename, llstat* file_status, const char* operation = nullptr, int suppress_warning = ENOENT)
+ {
+ std::filesystem::path file_path = fsyspath(filename);
+ return stat(file_path, file_status, operation, suppress_warning);
+ }
+ inline static int stat(const std::string& filename, llstat* file_status, const char* operation = nullptr, int suppress_warning = ENOENT)
+ {
+ std::filesystem::path file_path = fsyspath(filename);
+ return stat(file_path, file_status, operation, suppress_warning);
+ }
+ static int stat(const std::filesystem::path& file_path, llstat* file_status, const char *operation = nullptr, int suppress_warning = ENOENT);
///< for compatibility with existing uses of LL_File::stat() we use ENOENT as default in the
/// optional 'suppress_warning' parameter to avoid spamming the log with warnings when the API
/// is used to detect if a file exists
/// @returns 0 on success and -1 on failure.
- /// get the creation data and time of a file
- static std::time_t getCreationTime(const std::string& filename, int suppress_warning = 0);
- ///< Different systems have different support for this. Under Windows this is supposedly
- /// the actual time the file was created, on the Mac this is the actual birth date of
- /// the file which is in fact the creation time. The according ctime entry in the stat
- /// structure under Linux (and any other *nix really) is however contrary to what one
- /// might expect based on the c in ctime not the creation time but the time the last
- /// change to the inode entry was made. Changing access rights to a file will update
- /// this value too. In order to have a true creation time under Linux, we would have
- /// to use the statx() call which is available since kernel 4.19, but that will require
- /// considerable changes to the implementation of above stat() function.
- /// @returns the creation time (last status change under Linux) of the file or 0 on error
-
- /// get the last modification data and time of a file
- static std::time_t getModificationTime(const std::string& filename, int suppress_warning = 0);
- ///< @returns the modification time of the file or 0 on error
-
/// get the std::filesystem::file_status for filename
- static std::filesystem::file_status getStatus(const std::string& filename, bool dontFollowSymLink = false, int suppress_warning = ENOENT);
+ inline static std::filesystem::file_status getStatus(const char* filename, bool dontFollowSymLink = false, int suppress_warning = ENOENT)
+ {
+ std::filesystem::path file_path = fsyspath(filename);
+ return getStatus(file_path, dontFollowSymLink, suppress_warning);
+ }
+ inline static std::filesystem::file_status getStatus(const std::string& filename, bool dontFollowSymLink = false, int suppress_warning = ENOENT)
+ {
+ std::filesystem::path file_path = fsyspath(filename);
+ return getStatus(file_path, dontFollowSymLink, suppress_warning);
+ }
+ static std::filesystem::file_status getStatus(const std::filesystem::path& file_path, bool dontFollowSymLink = false, int suppress_warning = ENOENT);
///< dontFollowSymLinks set to true returns the std::filesystem::file_status of the symlink if it
/// is one, rather than resolving it. We pass by default ENOENT in the optional 'suppress_warning'
/// parameter to not spam the log with warnings when the file or directory does not exist
@@ -380,66 +588,108 @@ public:
/// and other APIs accepting a file_status.
/// get the size of a file in bytes
- static S64 size(const std::string& filename, int suppress_warning = ENOENT);
+ inline static S64 size(const char* filename, int suppress_warning = ENOENT)
+ {
+ std::filesystem::path file_path = fsyspath(filename);
+ return size(file_path, suppress_warning);
+ }
+ inline static S64 size(const std::string& filename, int suppress_warning = ENOENT)
+ {
+ std::filesystem::path file_path = fsyspath(filename);
+ return size(file_path, suppress_warning);
+ }
+ static S64 size(const std::filesystem::path& file_path, int suppress_warning = ENOENT);
///< we pass by default ENOENT in the optional 'suppress_warning' parameter to not spam
/// the log with warnings when the file does not exist
/// @returns the file size on success or 0 on failure.
/// check if filename is an existing file or directory
- static bool exists(const std::string& filename);
+ inline static bool exists(const char* filename)
+ {
+ std::filesystem::file_status status = getStatus(filename);
+ return std::filesystem::exists(status);
+ }
+ inline static bool exists(const std::string& filename)
+ {
+ std::filesystem::file_status status = getStatus(filename);
+ return std::filesystem::exists(status);
+ }
+ inline static bool exists(const std::filesystem::path& file_path)
+ {
+ std::filesystem::file_status status = getStatus(file_path);
+ return std::filesystem::exists(status);
+ }
///< @returns true if the path is for an existing file or directory
/// check if filename is an existing directory
- static bool isdir(const std::string& filename);
+ inline static bool isdir(const char* filename)
+ {
+ std::filesystem::file_status status = getStatus(filename);
+ return std::filesystem::is_directory(status);
+ }
+ inline static bool isdir(const std::string& filename)
+ {
+ std::filesystem::file_status status = getStatus(filename);
+ return std::filesystem::is_directory(status);
+ }
+ inline static bool isdir(const std::filesystem::path& file_path)
+ {
+ std::filesystem::file_status status = getStatus(file_path);
+ return std::filesystem::is_directory(status);
+ }
///< @returns true if the path is for an existing directory
/// check if filename is an existing file
- static bool isfile(const std::string& filename);
+ inline static bool isfile(const char* filename)
+ {
+ std::filesystem::file_status status = getStatus(filename);
+ return std::filesystem::is_regular_file(status);
+ }
+ inline static bool isfile(const std::string& filename)
+ {
+ std::filesystem::file_status status = getStatus(filename);
+ return std::filesystem::is_regular_file(status);
+ }
+ inline static bool isfile(const std::filesystem::path& file_path)
+ {
+ std::filesystem::file_status status = getStatus(file_path);
+ return std::filesystem::is_regular_file(status);
+ }
///< @returns true if the path is for an existing file
/// check if filename is a symlink
- static bool islink(const std::string& filename);
+ inline static bool islink(const char* filename)
+ {
+ std::filesystem::file_status status = getStatus(filename, true);
+ return std::filesystem::is_symlink(status);
+ }
+ inline static bool islink(const std::string& filename)
+ {
+ std::filesystem::file_status status = getStatus(filename, true);
+ return std::filesystem::is_symlink(status);
+ }
+ inline static bool islink(const std::filesystem::path& file_path)
+ {
+ std::filesystem::file_status status = getStatus(file_path, true);
+ return std::filesystem::is_symlink(status);
+ }
///< @returns true if the path is pointing at a symlink
/// return a path to the temporary directory on the system
static const std::string& tmpdir();
- /// converts a string containing a path in utf8 encoding into an explicit filesystem path
- static std::filesystem::path utf8StringToPath(const std::string& pathname);
- ///< @returns the path as a std::filesystem::path
- ///@}
-
private:
#if LL_WINDOWS
typedef HANDLE llfile_handle_t;
const llfile_handle_t InvalidHandle = INVALID_HANDLE_VALUE;
+ llfile_handle_t mHandle = INVALID_HANDLE_VALUE; // The file handle/descriptor
#else
typedef int llfile_handle_t;
const llfile_handle_t InvalidHandle = -1;
+ llfile_handle_t mHandle = -1;; // The file handle/descriptor
#endif
- /// ================================================================================
- /// @name private static member functions
- ///
-#if LL_WINDOWS
- /// convert a string containing a path in utf8 encoding into a Windows format std::wstring
- static std::wstring utf8StringToWstring(const std::string& pathname);
- ///< this will prepend the path with the Windows kernel object space prefix when the path is
- /// equal or longer than MAX_PATH characters and do some sanitation on the path.
- /// This allows the underlaying Windows APIs to process long path names. Do not pass such a path
- /// to std::filesystem functions. These functions are not guaranteed to handle such paths properly.
- /// It's only useful to pass the resulting string buffer to Microsoft Windows widechar APIs or
- /// the Microsoft C runtime widechar file functions.
- ///
- /// Example:
- ///
- /// std::wstring file_path = utf8StringToWstring(filename);
- /// HANDLE CreateFileW(file_path.c_str(), ......);
- ///
- /// @returns the path as a std::wstring path
-#endif
- llfile_handle_t mHandle; // The file handle/descriptor
- std::ios_base::openmode mOpen; // Used to emulate std::ios_base::app under Windows
+ std::ios_base::openmode mOpen{}; // Used to emulate std::ios_base::app under Windows
};
#if LL_WINDOWS
@@ -451,7 +701,7 @@ private:
* Does The Right Thing when passed a non-ASCII pathname. Sadly, that isn't
* true of Microsoft's std::ifstream.
*/
-class LL_COMMON_API llifstream : public std::ifstream
+class llifstream : public std::ifstream
{
// input stream associated with a C stream
public:
@@ -463,7 +713,7 @@ class LL_COMMON_API llifstream : public std::ifstream
* @c &sb to the base class initializer. Does not open any files
* (you haven't given it a filename to open).
*/
- llifstream();
+ llifstream() = default;
/**
* @brief Create an input file stream.
@@ -472,8 +722,12 @@ class LL_COMMON_API llifstream : public std::ifstream
*
* @c ios_base::in is automatically included in @a mode.
*/
+ explicit llifstream(const char* _Filename,
+ ios_base::openmode _Mode = ios_base::in);
explicit llifstream(const std::string& _Filename,
ios_base::openmode _Mode = ios_base::in);
+ explicit llifstream(const std::filesystem::path& _Filepath,
+ ios_base::openmode _Mode = ios_base::in);
/**
* @brief Opens an external file.
@@ -483,10 +737,73 @@ class LL_COMMON_API llifstream : public std::ifstream
* Calls @c llstdio_filebuf::open(s,mode|in). If that function
* fails, @c failbit is set in the stream's error state.
*/
+ void open(const char* _Filename,
+ ios_base::openmode _Mode = ios_base::in);
void open(const std::string& _Filename,
ios_base::openmode _Mode = ios_base::in);
+ void open(const std::filesystem::path& _Filepath,
+ ios_base::openmode _Mode = ios_base::in);
};
+/// RAII class
+class LLUniqueFile
+{
+public:
+ // empty
+ LLUniqueFile() = default;
+ // wrap (e.g.) result of LLFile::fopen()
+ LLUniqueFile(LLFILE* f) : mFileHandle(f) {}
+ // no copy
+ LLUniqueFile(const LLUniqueFile&) = delete;
+ // move construction
+ LLUniqueFile(LLUniqueFile&& other) noexcept
+ {
+ mFileHandle = other.mFileHandle;
+ other.mFileHandle = nullptr;
+ }
+ // The point of LLUniqueFile is to close on destruction.
+ ~LLUniqueFile() { close(); }
+
+ // simple assignment
+ LLUniqueFile& operator=(LLFILE* f)
+ {
+ close();
+ mFileHandle = f;
+ return *this;
+ }
+ // copy assignment deleted
+ LLUniqueFile& operator=(const LLUniqueFile&) = delete;
+ // move assignment
+ LLUniqueFile& operator=(LLUniqueFile&& other) noexcept
+ {
+ close();
+ std::swap(mFileHandle, other.mFileHandle);
+ return *this;
+ }
+
+ // explicit close operation
+ void close()
+ {
+ if (mFileHandle)
+ {
+ // in case close() throws, set mFileHandle null FIRST
+ LLFILE* h{ nullptr };
+ std::swap(h, mFileHandle);
+ LLFile::close(h);
+ }
+ }
+
+ // detect whether the wrapped LLFILE is open or not
+ explicit operator bool() const { return bool(mFileHandle); }
+ bool operator!() { return !mFileHandle; }
+
+ // LLUniqueFile should be usable for any operation that accepts LLFILE*
+ // (or FILE* for that matter)
+ operator LLFILE*() const { return mFileHandle; }
+
+private:
+ LLFILE* mFileHandle = nullptr;
+};
/**
* @brief Controlling output for files.
@@ -496,7 +813,7 @@ class LL_COMMON_API llifstream : public std::ifstream
* Right Thing when passed a non-ASCII pathname. Sadly, that isn't true of
* Microsoft's std::ofstream.
*/
-class LL_COMMON_API llofstream : public std::ofstream
+class llofstream : public std::ofstream
{
public:
// Constructors:
@@ -507,7 +824,7 @@ class LL_COMMON_API llofstream : public std::ofstream
* @c &sb to the base class initializer. Does not open any files
* (you haven't given it a filename to open).
*/
- llofstream();
+ llofstream() = default;
/**
* @brief Create an output file stream.
@@ -516,8 +833,12 @@ class LL_COMMON_API llofstream : public std::ofstream
*
* @c ios_base::out is automatically included in @a mode.
*/
+ explicit llofstream(const char* _Filename,
+ ios_base::openmode _Mode = ios_base::out|ios_base::trunc);
explicit llofstream(const std::string& _Filename,
ios_base::openmode _Mode = ios_base::out|ios_base::trunc);
+ explicit llofstream(const std::filesystem::path& _Filepath,
+ ios_base::openmode _Mode = ios_base::out|ios_base::trunc);
/**
* @brief Opens an external file.
@@ -526,8 +847,12 @@ class LL_COMMON_API llofstream : public std::ofstream
*
* @c ios_base::out is automatically included in @a mode.
*/
+ void open(const char* _Filename,
+ ios_base::openmode _Mode = ios_base::out|ios_base::trunc);
void open(const std::string& _Filename,
ios_base::openmode _Mode = ios_base::out|ios_base::trunc);
+ void open(const std::filesystem::path& _Filepath,
+ ios_base::openmode _Mode = ios_base::out|ios_base::trunc);
};
#else // ! LL_WINDOWS
diff --git a/indra/llcommon/llprocessor.cpp b/indra/llcommon/llprocessor.cpp
index 37d1c60f91..7656986fe2 100644
--- a/indra/llcommon/llprocessor.cpp
+++ b/indra/llcommon/llprocessor.cpp
@@ -837,7 +837,7 @@ private:
void get_proc_cpuinfo()
{
std::map< std::string, std::string > cpuinfo;
- LLFILE* cpuinfo_fp = LLFile::fopen(CPUINFO_FILE, "rb");
+ LLFILE* cpuinfo_fp = LLFile::fopen(CPUINFO_FILE, TEXT("rb"));
if(cpuinfo_fp)
{
char line[MAX_STRING];
@@ -954,7 +954,7 @@ private:
std::ostringstream s;
// *NOTE:Mani - This is for linux only.
- LLFILE* cpuinfo = LLFile::fopen(CPUINFO_FILE, "rb");
+ LLFILE* cpuinfo = LLFile::fopen(CPUINFO_FILE, TEXT("rb"));
if(cpuinfo)
{
char line[MAX_STRING];
diff --git a/indra/llcommon/llprofilercategories.h b/indra/llcommon/llprofilercategories.h
index 1c4f0f5624..261fdf14b7 100644
--- a/indra/llcommon/llprofilercategories.h
+++ b/indra/llcommon/llprofilercategories.h
@@ -48,6 +48,7 @@
#define LL_PROFILER_CATEGORY_ENABLE_DRAWPOOL 1
#define LL_PROFILER_CATEGORY_ENABLE_ENVIRONMENT 1
#define LL_PROFILER_CATEGORY_ENABLE_FACE 1
+//#define LL_PROFILER_CATEGORY_ENABLE_FILE 1
#define LL_PROFILER_CATEGORY_ENABLE_LLSD 1
#define LL_PROFILER_CATEGORY_ENABLE_LOGGING 1
#define LL_PROFILER_CATEGORY_ENABLE_MATERIAL 1
@@ -126,6 +127,14 @@
#define LL_PROFILE_ZONE_SCOPED_CATEGORY_FACE
#endif
+#if LL_PROFILER_CATEGORY_ENABLE_FILE
+#define LL_PROFILE_ZONE_NAMED_CATEGORY_FILE LL_PROFILE_ZONE_NAMED
+#define LL_PROFILE_ZONE_SCOPED_CATEGORY_FILE LL_PROFILE_ZONE_SCOPED
+#else
+#define LL_PROFILE_ZONE_NAMED_CATEGORY_FILE(name)
+#define LL_PROFILE_ZONE_SCOPED_CATEGORY_FILE
+#endif
+
#if LL_PROFILER_CATEGORY_ENABLE_LLSD
#define LL_PROFILE_ZONE_NAMED_CATEGORY_LLSD LL_PROFILE_ZONE_NAMED
#define LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD LL_PROFILE_ZONE_SCOPED
diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp
index 9b5dd2df39..499de996e2 100644
--- a/indra/llcommon/llsys.cpp
+++ b/indra/llcommon/llsys.cpp
@@ -514,7 +514,7 @@ namespace {
#if LL_LINUX
constexpr U32 STATUS_SIZE = 2048;
- LLFILE* status_filep = LLFile::fopen("/proc/self/status", "rb");
+ LLFILE* status_filep = LLFile::fopen("/proc/self/status", TEXT("rb"));
if (status_filep)
{
char buff[STATUS_SIZE]; /* Flawfinder: ignore */
@@ -1273,7 +1273,7 @@ bool gunzip_file(const std::string& srcfile, const std::string& dstfile)
src = gzopen(srcfile.c_str(), "rb");
#endif
if (! src) goto err;
- dst = LLFile::fopen(tmpfile, "wb"); /* Flawfinder: ignore */
+ dst = LLFile::fopen(tmpfile, TEXT("wb")); /* Flawfinder: ignore */
if (! dst) goto err;
do
{
@@ -1314,7 +1314,7 @@ bool gzip_file(const std::string& srcfile, const std::string& dstfile)
#endif
if (! dst) goto err;
- src = LLFile::fopen(srcfile, "rb"); /* Flawfinder: ignore */
+ src = LLFile::fopen(srcfile, TEXT("rb")); /* Flawfinder: ignore */
if (! src) goto err;
while ((bytes = (S32)fread(buffer, sizeof(U8), COMPRESS_BUFFER_SIZE, src)) > 0)
diff --git a/indra/llcommon/tests/llfile_test.cpp b/indra/llcommon/tests/llfile_test.cpp
index f1cee06856..ab4616cfb2 100644
--- a/indra/llcommon/tests/llfile_test.cpp
+++ b/indra/llcommon/tests/llfile_test.cpp
@@ -33,14 +33,13 @@
namespace tut
{
- static void clear_entire_dir(const std::string &dir)
+ static void clear_entire_dir(const std::filesystem::path& dir_path)
{
std::error_code ec;
- std::filesystem::path dir_path = LLFile::utf8StringToPath(dir);
std::filesystem::remove_all(dir_path, ec);
}
- static std::filesystem::path append_filename(const std::filesystem::path& dir, const std::string& element)
+ static std::filesystem::path append_filename(const std::filesystem::path& dir, const std::u8string& element)
{
std::filesystem::path path = dir;
return path.append(element);
@@ -48,13 +47,13 @@ namespace tut
static std::filesystem::path get_testdir(const std::filesystem::path& tempdir)
{
- return append_filename(tempdir, std::string("test_dir"));
+ return append_filename(tempdir, std::u8string(u8"test_dir"));
}
static std::filesystem::path get_testdir_unicode(const std::filesystem::path& tempdir)
{
// Example Unicode directory name: "test_ユニコード_dir"
- return append_filename(tempdir, std::string("test_\xE3\x83\xA6\xE3\x83\x8B\xE3\x82\xB3\xE3\x83\xBC\xE3\x83\x89_dir"));
+ return append_filename(tempdir, std::u8string(u8"test_\xE3\x83\xA6\xE3\x83\x8B\xE3\x82\xB3\xE3\x83\xBC\xE3\x83\x89_dir"));
}
struct llfile_test
@@ -72,46 +71,46 @@ namespace tut
// Test creating directories and files and deleting them and checking if the
// relevant status functions work as expected
ensure("LLFile::tmpdir() empty", !tempdir.empty());
- ensure("LLFile::tmpdir() doesn't exist", LLFile::exists(tempdir.string()));
- ensure("LLFile::tmpdir() is not a directory", LLFile::isdir(tempdir.string()));
- ensure("LLFile::tmpdir() should not be a file", !LLFile::isfile(tempdir.string()));
+ ensure("LLFile::tmpdir() doesn't exist", LLFile::exists(tempdir));
+ ensure("LLFile::tmpdir() is not a directory", LLFile::isdir(tempdir));
+ ensure("LLFile::tmpdir() should not be a file", !LLFile::isfile(tempdir));
// Make sure there is nothing left from a previous test run
- clear_entire_dir(testdir.string());
- ensure("llfile_test should not exist anymore", !LLFile::exists(testdir.string()));
+ clear_entire_dir(testdir);
+ ensure("llfile_test should not exist anymore", !LLFile::exists(testdir));
- int rc = LLFile::mkdir(testdir.string());
+ int rc = LLFile::mkdir(testdir);
ensure("LLFile::mkdir() failed", rc == 0);
- ensure("llfile_test should be a directory", LLFile::isdir(testdir.string()));
- rc = LLFile::mkdir(testdir.string());
+ ensure("llfile_test should be a directory", LLFile::isdir(testdir));
+ rc = LLFile::mkdir(testdir);
ensure("LLFile::mkdir() should not fail when the directory already exists", rc == 0);
std::filesystem::path testfile1 = testdir;
testfile1.append("llfile_test.dat");
- ensure("llfile_test1.dat should not yet exist", !LLFile::exists(testfile1.string()));
+ ensure("llfile_test1.dat should not yet exist", !LLFile::exists(testfile1));
const char* testdata = "testdata";
- S64 bytes = LLFile::write(testfile1.string(), testdata, 0, sizeof(testdata));
+ S64 bytes = LLFile::write(testfile1, testdata, 0, sizeof(testdata));
ensure("LLFile::write() did not write correctly", bytes == sizeof(testdata));
- rc = LLFile::remove(testfile1.string());
+ rc = LLFile::remove(testfile1);
ensure("LLFile::remove() for file test_file.dat", rc == 0);
- ensure("llfile_test.dat should not exist anymore", !LLFile::exists(testfile1.string()));
- ensure("llfile_test.dat should not be a file", !LLFile::isfile(testfile1.string()));
- ensure("llfile_test.dat should not be a directory", !LLFile::isdir(testfile1.string()));
- ensure("llfile_test.dat should not be a symlink", !LLFile::islink(testfile1.string()));
+ ensure("llfile_test.dat should not exist anymore", !LLFile::exists(testfile1));
+ ensure("llfile_test.dat should not be a file", !LLFile::isfile(testfile1));
+ ensure("llfile_test.dat should not be a directory", !LLFile::isdir(testfile1));
+ ensure("llfile_test.dat should not be a symlink", !LLFile::islink(testfile1));
- rc = LLFile::remove(testdir.string());
+ rc = LLFile::remove(testdir);
ensure("LLFile::remove() for directory llfile_test failed", rc == 0);
- ensure("llfile_test should not exist anymore", !LLFile::exists(testdir.string()));
+ ensure("llfile_test should not exist anymore", !LLFile::exists(testdir));
}
template<> template<>
void llfile_test_object_t::test<2>()
{
// High level static file IO functions to read and write data files
- LLFile::mkdir(testdir.string());
- ensure("llfile_test should exist", LLFile::isdir(testdir.string()));
+ LLFile::mkdir(testdir);
+ ensure("llfile_test should exist", LLFile::isdir(testdir));
std::filesystem::path testfile1 = testdir;
testfile1.append("llfile_test.dat");
@@ -119,42 +118,36 @@ namespace tut
std::string testdata1("testdata");
std::string testdata2("datateststuff");
std::time_t current = time(nullptr);
- S64 bytes = LLFile::write(testfile1.string(), testdata1.c_str(), 0, testdata1.length());
+ S64 bytes = LLFile::write(testfile1, testdata1.c_str(), 0, testdata1.length());
ensure("LLFile::write() did not write correctly", bytes == testdata1.length());
- ensure("llfile_test.dat should exist", LLFile::exists(testfile1.string()));
- ensure("llfile_test.dat should be a file", LLFile::isfile(testfile1.string()));
- ensure("llfile_test.dat should not be a directory", !LLFile::isdir(testfile1.string()));
+ ensure("llfile_test.dat should exist", LLFile::exists(testfile1));
+ ensure("llfile_test.dat should be a file", LLFile::isfile(testfile1));
+ ensure("llfile_test.dat should not be a directory", !LLFile::isdir(testfile1));
- bytes = LLFile::size(testfile1.string());
+ bytes = LLFile::size(testfile1);
ensure("LLFile::size() did not return the correct size", bytes == testdata1.length());
- std::string data = LLFile::getContents(testfile1.string());
+ std::string data = LLFile::getContents(testfile1);
ensure("LLFile::getContents() did not return the correct size data", data.length() == testdata1.length());
ensure_memory_matches("LLFile::getContents() did not read correct data", testdata1.c_str(), (U32)testdata1.length(), data.c_str(), (U32)data.length());
- std::time_t ctime = LLFile::getCreationTime(testfile1.string());
- ensure_approximately_equals_range("LLFile::getCreationTime() did not return correct time", (F32)(ctime - current), 0.f, 1);
-
- std::time_t mtime = LLFile::getModificationTime(testfile1.string());
- ensure_approximately_equals_range("LLFile::getModificationTime() did not return correct time", (F32)(mtime - current), 0.f, 1);
-
char buffer[1024];
- bytes = LLFile::read(testfile1.string(), buffer, 0, testdata1.length());
+ bytes = LLFile::read(testfile1, buffer, 0, testdata1.length());
ensure("LLFile:read() did not return the correct size", bytes == testdata1.length());
ensure_memory_matches("LLFile::read() did not read correct data", testdata1.c_str(), (U32)bytes, buffer, (U32)bytes);
// What if we try to read more data than there is in the file?
- bytes = LLFile::read(testfile1.string(), buffer, 0, bytes + 10);
+ bytes = LLFile::read(testfile1, buffer, 0, bytes + 10);
ensure("LLFile:read() did not correctly stop on eof", bytes == testdata1.length());
ensure_memory_matches("LLFile::read() did not read correct data", testdata1.c_str(), (U32)bytes, buffer, (U32)bytes);
// Let's append more data
- bytes = LLFile::write(testfile1.string(), testdata2.c_str(), -1, testdata2.length());
+ bytes = LLFile::write(testfile1, testdata2.c_str(), -1, testdata2.length());
ensure("LLFile::write() did not write correctly", bytes == testdata2.length());
- bytes = LLFile::size(testfile1.string());
+ bytes = LLFile::size(testfile1);
ensure("LLFile::size() did not return the correct size", bytes == testdata1.length() + testdata2.length());
- bytes = LLFile::read(testfile1.string(), buffer, 0, bytes);
+ bytes = LLFile::read(testfile1, buffer, 0, bytes);
ensure("LLFile:read() did not read correct number of bytes", bytes == testdata1.length() + testdata2.length());
ensure_memory_matches("LLFile:read() did not read correct testdata1", testdata1.c_str(), (U32)testdata1.length(), buffer, (U32)testdata1.length());
ensure_memory_matches("LLFile:read() did not read correct testdata2", testdata2.c_str(), (U32)testdata2.length(), buffer + testdata1.length(), (U32)testdata2.length());
@@ -176,7 +169,7 @@ namespace tut
}
std::error_code ec;
- LLFile fileout(testfile.string(), LLFile::out, ec);
+ LLFile fileout(testfile, LLFile::out, ec);
ensure("LLFile constructor did not open correctly", (bool)fileout);
ensure("error_code from LLFile constructor should not indicate an error", !ec);
if (fileout)
@@ -196,7 +189,7 @@ namespace tut
fileout.close();
}
- LLFile filein(testfile.string(), LLFile::in, ec);
+ LLFile filein(testfile, LLFile::in, ec);
ensure("LLFile constructor did not open correctly", (bool)filein);
ensure("error_code from LLFile constructor should not indicate an error", !ec);
if (filein)
@@ -236,16 +229,16 @@ namespace tut
testfile.append("llfile_test.bin");
std::error_code ec;
- LLFile file(testfile.string(), LLFile::out | LLFile::noreplace, ec);
+ LLFile file(testfile, LLFile::out | LLFile::noreplace, ec);
ensure("LLFile constructor should not have opened the already existing file", !file);
ensure("error_code from LLFile constructor should indicate an error", (bool)ec);
- LLFile::remove(testfile.string());
- file = LLFile(testfile.string(), LLFile::out | LLFile::app | LLFile::trunc, ec);
+ LLFile::remove(testfile);
+ file = LLFile(testfile, LLFile::out | LLFile::app | LLFile::trunc, ec);
ensure("LLFile constructor should not have opened the file with conflicting flags", !file);
ensure("error_code from LLFile constructor should indicate an error", (bool)ec);
- file = LLFile(testfile.string(), LLFile::out | LLFile::app | LLFile::noreplace, ec);
+ file = LLFile(testfile, LLFile::out | LLFile::app | LLFile::noreplace, ec);
ensure("LLFile constructor should not have opened the file with conflicting flags", !file);
ensure("error_code from LLFile constructor should indicate an error", (bool)ec);
@@ -253,7 +246,7 @@ namespace tut
testfile.append("llfile_test");
testfile.append("llfile_test.bin");
- file = LLFile(testfile.string(), LLFile::in, ec);
+ file = LLFile(testfile, LLFile::in, ec);
ensure("LLFile constructor should not have been able to open the file in the non-existing directory", !file);
ensure("error_code from LLFile constructor should indicate an error", (bool)ec);
}
@@ -270,37 +263,37 @@ namespace tut
testfile_unicode.append(unicode_filename);
// Clean up any previous test artifacts
- clear_entire_dir(testdir_unicode.string());
- ensure("Unicode test directory should not exist", !LLFile::exists(testdir_unicode.string()));
+ clear_entire_dir(testdir_unicode);
+ ensure("Unicode test directory should not exist", !LLFile::exists(testdir_unicode));
// Create the Unicode directory
- int rc = LLFile::mkdir(testdir_unicode.string());
+ int rc = LLFile::mkdir(testdir_unicode);
ensure("LLFile::mkdir() failed for Unicode directory", rc == 0);
- ensure("Unicode test directory should exist", LLFile::isdir(testdir_unicode.string()));
+ ensure("Unicode test directory should exist", LLFile::isdir(testdir_unicode));
- ensure("Unicode test file should not exist", !LLFile::exists(testfile_unicode.string()));
+ ensure("Unicode test file should not exist", !LLFile::exists(testfile_unicode));
// Write to the Unicode file
const char* testdata = "unicode_testdata";
- S64 bytes = LLFile::write(testfile_unicode.string(), testdata, 0, strlen(testdata));
- ensure("Unicode test file should exist", LLFile::exists(testfile_unicode.string()));
- ensure("Unicode test file should be a file", LLFile::isfile(testfile_unicode.string()));
+ S64 bytes = LLFile::write(testfile_unicode, testdata, 0, strlen(testdata));
+ ensure("Unicode test file should exist", LLFile::exists(testfile_unicode));
+ ensure("Unicode test file should be a file", LLFile::isfile(testfile_unicode));
ensure("LLFile::write() did not write correctly to Unicode file", bytes == (S64)strlen(testdata));
// Read back the data
char buffer[64] = {};
- bytes = LLFile::read(testfile_unicode.string(), buffer, 0, sizeof(buffer));
+ bytes = LLFile::read(testfile_unicode, buffer, 0, sizeof(buffer));
ensure("LLFile::read() did not read correctly from Unicode file", bytes == (S64)strlen(testdata));
ensure_memory_matches("LLFile::read() did not read correct Unicode data", testdata, (U32)bytes, buffer, (U32)bytes);
// Remove the file and directory
- rc = LLFile::remove(testfile_unicode.string());
+ rc = LLFile::remove(testfile_unicode);
ensure("LLFile::remove() failed for Unicode file", rc == 0);
- ensure("Unicode test file should not exist after removal", !LLFile::exists(testfile_unicode.string()));
+ ensure("Unicode test file should not exist after removal", !LLFile::exists(testfile_unicode));
- rc = LLFile::remove(testdir_unicode.string());
+ rc = LLFile::remove(testdir_unicode);
ensure("LLFile::remove() failed for Unicode directory", rc == 0);
- ensure("Unicode test directory should not exist after removal", !LLFile::exists(testdir_unicode.string()));
+ ensure("Unicode test directory should not exist after removal", !LLFile::exists(testdir_unicode));
}
} // namespace tut
diff --git a/indra/llfilesystem/lldir.cpp b/indra/llfilesystem/lldir.cpp
index eb3c2d9909..3ec8983e8a 100755
--- a/indra/llfilesystem/lldir.cpp
+++ b/indra/llfilesystem/lldir.cpp
@@ -91,13 +91,13 @@ LLDir::~LLDir()
std::vector<std::string> LLDir::getFilesInDir(const std::string &dirname)
{
// Returns a vector of filenames in the directory.
- std::filesystem::path p = LLFile::utf8StringToPath(dirname);
+ fsyspath dir_path(dirname);
std::vector<std::string> v;
std::error_code ec;
- if (std::filesystem::is_directory(p, ec))
+ if (std::filesystem::is_directory(dir_path, ec))
{
std::filesystem::directory_iterator end_iter;
- for (std::filesystem::directory_iterator dir_itr(p);
+ for (std::filesystem::directory_iterator dir_itr(dir_path);
dir_itr != end_iter;
++dir_itr)
{
@@ -173,10 +173,10 @@ U32 LLDir::deleteDirAndContents(const std::string& dir_name)
//Removes the directory and its contents. Returns number of files deleted.
U32 num_deleted = 0;
- std::filesystem::path dir_path = LLFile::utf8StringToPath(dir_name);
try
{
+ fsyspath dir_path(dir_name);
if (std::filesystem::is_directory(dir_path))
{
if (!std::filesystem::is_empty(dir_path))
@@ -196,6 +196,11 @@ U32 LLDir::deleteDirAndContents(const std::string& dir_name)
return num_deleted;
}
+bool LLDir::fileExists(const std::string& filename) const
+{
+ return LLFile::exists(filename);
+}
+
const std::string LLDir::findFile(const std::string &filename,
const std::string& searchPath1,
const std::string& searchPath2,
@@ -1005,7 +1010,7 @@ bool LLDir::setCacheDir(const std::string &path)
{
LLFile::mkdir(path);
std::string tempname = add(path, "temp");
- LLFILE* file = LLFile::fopen(tempname,"wt");
+ LLFILE* file = LLFile::fopen(tempname, TEXT("wt"));
if (file)
{
fclose(file);
diff --git a/indra/llfilesystem/lldir.h b/indra/llfilesystem/lldir.h
index b0d2b6aada..8388816059 100644
--- a/indra/llfilesystem/lldir.h
+++ b/indra/llfilesystem/lldir.h
@@ -71,7 +71,7 @@ class LLDir
std::vector<std::string> getFilesInDir(const std::string &dirname);
// pure virtual functions
virtual std::string getCurPath() = 0;
- virtual bool fileExists(const std::string &filename) const = 0;
+ virtual bool fileExists(const std::string &filename) const;
const std::string findFile(const std::string& filename, const std::vector<std::string> filenames) const;
const std::string findFile(const std::string& filename, const std::string& searchPath1 = "", const std::string& searchPath2 = "", const std::string& searchPath3 = "") const;
diff --git a/indra/llfilesystem/lldir_linux.cpp b/indra/llfilesystem/lldir_linux.cpp
index b13b42c954..0ebaab1114 100644
--- a/indra/llfilesystem/lldir_linux.cpp
+++ b/indra/llfilesystem/lldir_linux.cpp
@@ -238,24 +238,6 @@ std::string LLDir_Linux::getCurPath()
return tmp_str;
}
-
-bool LLDir_Linux::fileExists(const std::string &filename) const
-{
- struct stat stat_data;
- // Check the age of the file
- // Now, we see if the files we've gathered are recent...
- int res = stat(filename.c_str(), &stat_data);
- if (!res)
- {
- return true;
- }
- else
- {
- return false;
- }
-}
-
-
/*virtual*/ std::string LLDir_Linux::getLLPluginLauncher()
{
return gDirUtilp->getExecutableDir() + gDirUtilp->getDirDelimiter() +
diff --git a/indra/llfilesystem/lldir_linux.h b/indra/llfilesystem/lldir_linux.h
index bd031bd7bb..ad9cd76554 100644
--- a/indra/llfilesystem/lldir_linux.h
+++ b/indra/llfilesystem/lldir_linux.h
@@ -47,7 +47,6 @@ public:
virtual std::string getCurPath();
virtual U32 countFilesInDir(const std::string &dirname, const std::string &mask);
- /*virtual*/ bool fileExists(const std::string &filename) const;
/*virtual*/ std::string getLLPluginLauncher();
/*virtual*/ std::string getLLPluginFilename(std::string base_name);
diff --git a/indra/llfilesystem/lldir_mac.cpp b/indra/llfilesystem/lldir_mac.cpp
index 2db1b6ec5d..7bddee0f75 100644
--- a/indra/llfilesystem/lldir_mac.cpp
+++ b/indra/llfilesystem/lldir_mac.cpp
@@ -177,14 +177,6 @@ std::string LLDir_Mac::getCurPath()
return boost::filesystem::path( boost::filesystem::current_path() ).string();
}
-
-
-bool LLDir_Mac::fileExists(const std::string &filename) const
-{
- return boost::filesystem::exists(filename);
-}
-
-
/*virtual*/ std::string LLDir_Mac::getLLPluginLauncher()
{
return gDirUtilp->getAppRODataDir() + gDirUtilp->getDirDelimiter() +
diff --git a/indra/llfilesystem/lldir_mac.h b/indra/llfilesystem/lldir_mac.h
index f812ee810b..54dc2eb237 100644
--- a/indra/llfilesystem/lldir_mac.h
+++ b/indra/llfilesystem/lldir_mac.h
@@ -45,7 +45,6 @@ public:
const std::string& app_read_only_data_dir);
virtual std::string getCurPath();
- virtual bool fileExists(const std::string &filename) const;
/*virtual*/ std::string getLLPluginLauncher();
/*virtual*/ std::string getLLPluginFilename(std::string base_name);
diff --git a/indra/llfilesystem/lldir_win32.cpp b/indra/llfilesystem/lldir_win32.cpp
index 1cfa157634..912a2963c6 100644
--- a/indra/llfilesystem/lldir_win32.cpp
+++ b/indra/llfilesystem/lldir_win32.cpp
@@ -373,13 +373,6 @@ std::string LLDir_Win32::getCurPath()
return ll_convert<std::string>(std::wstring(w_str));
}
-
-bool LLDir_Win32::fileExists(const std::string &filename) const
-{
- return LLFile::exists(filename);
-}
-
-
/*virtual*/ std::string LLDir_Win32::getLLPluginLauncher()
{
return gDirUtilp->getExecutableDir() + gDirUtilp->getDirDelimiter() +
diff --git a/indra/llfilesystem/lldir_win32.h b/indra/llfilesystem/lldir_win32.h
index 21a3f1213b..c3a41d3e33 100644
--- a/indra/llfilesystem/lldir_win32.h
+++ b/indra/llfilesystem/lldir_win32.h
@@ -44,7 +44,6 @@ public:
/*virtual*/ std::string getCurPath();
/*virtual*/ U32 countFilesInDir(const std::string &dirname, const std::string &mask);
- /*virtual*/ bool fileExists(const std::string &filename) const;
/*virtual*/ std::string getLLPluginLauncher();
/*virtual*/ std::string getLLPluginFilename(std::string base_name);
diff --git a/indra/llfilesystem/llfilesystem.cpp b/indra/llfilesystem/llfilesystem.cpp
index 0c220fe7cf..388cbc280f 100755
--- a/indra/llfilesystem/llfilesystem.cpp
+++ b/indra/llfilesystem/llfilesystem.cpp
@@ -34,8 +34,6 @@
#include "llfasttimer.h"
#include "lldiskcache.h"
-#include "boost/filesystem.hpp"
-
constexpr S32 LLFileSystem::READ = 0x00000001;
constexpr S32 LLFileSystem::WRITE = 0x00000002;
constexpr S32 LLFileSystem::READ_WRITE = 0x00000003; // LLFileSystem::READ & LLFileSystem::WRITE
@@ -51,22 +49,21 @@ LLFileSystem::LLFileSystem(const LLUUID& file_id, const LLAssetType::EType file_
mBytesRead = 0;
mMode = mode;
+ // build the filepath
+ mPath = fsyspath(LLDiskCache::metaDataToFilepath(mFileID, mFileType));
+
// This block of code was originally called in the read() method but after comments here:
// https://bitbucket.org/lindenlab/viewer/commits/e28c1b46e9944f0215a13cab8ee7dded88d7fc90#comment-10537114
// we decided to follow Henri's suggestion and move the code to update the last access time here.
if (mode == LLFileSystem::READ)
{
- // build the filename (TODO: we do this in a few places - perhaps we should factor into a single function)
- const std::string filename = LLDiskCache::metaDataToFilepath(mFileID, mFileType);
-
// update the last access time for the file if it exists - this is required
// even though we are reading and not writing because this is the
// way the cache works - it relies on a valid "last accessed time" for
// each file so it knows how to remove the oldest, unused files
- bool exists = gDirUtilp->fileExists(filename);
- if (exists)
+ if (LLFile::exists(mPath))
{
- updateFileAccessTime(filename);
+ updateFileAccessTime();
}
}
}
@@ -111,20 +108,11 @@ bool LLFileSystem::renameFile(const LLUUID& old_file_id, const LLAssetType::ETyp
return true;
}
-// static
-S64 LLFileSystem::getFileSize(const LLUUID& file_id, const LLAssetType::EType file_type)
-{
- const std::string filename = LLDiskCache::metaDataToFilepath(file_id, file_type);
- return LLFile::size(filename);
-}
-
bool LLFileSystem::read(U8* buffer, S32 bytes)
{
bool success = false;
- const std::string filename = LLDiskCache::metaDataToFilepath(mFileID, mFileType);
-
- llifstream file(filename, std::ios::binary);
+ llifstream file(mPath, std::ios::binary);
if (file.is_open())
{
file.seekg(mPosition, std::ios::beg);
@@ -164,13 +152,11 @@ bool LLFileSystem::eof() const
bool LLFileSystem::write(const U8* buffer, S32 bytes)
{
- const std::string filename = LLDiskCache::metaDataToFilepath(mFileID, mFileType);
-
bool success = false;
if (mMode == APPEND)
{
- llofstream ofs(filename, std::ios::app | std::ios::binary);
+ llofstream ofs(mPath, std::ios::app | std::ios::binary);
if (ofs)
{
ofs.write((const char*)buffer, bytes);
@@ -183,7 +169,7 @@ bool LLFileSystem::write(const U8* buffer, S32 bytes)
else if (mMode == READ_WRITE)
{
// Don't truncate if file already exists
- llofstream ofs(filename, std::ios::in | std::ios::binary);
+ llofstream ofs(mPath, std::ios::in | std::ios::binary);
if (ofs)
{
ofs.seekp(mPosition, std::ios::beg);
@@ -194,7 +180,7 @@ bool LLFileSystem::write(const U8* buffer, S32 bytes)
else
{
// File doesn't exist - open in write mode
- ofs.open(filename, std::ios::binary);
+ ofs.open(mPath, std::ios::binary);
if (ofs.is_open())
{
ofs.write((const char*)buffer, bytes);
@@ -205,7 +191,7 @@ bool LLFileSystem::write(const U8* buffer, S32 bytes)
}
else
{
- llofstream ofs(filename, std::ios::binary);
+ llofstream ofs(mPath, std::ios::binary);
if (ofs)
{
ofs.write((const char*)buffer, bytes);
@@ -256,7 +242,7 @@ S32 LLFileSystem::tell() const
S32 LLFileSystem::getSize() const
{
- return (S32)LLFileSystem::getFileSize(mFileID, mFileType);
+ return narrow(LLFile::size(mPath));
}
S32 LLFileSystem::getMaxSize() const
@@ -271,17 +257,18 @@ bool LLFileSystem::rename(const LLUUID& new_id, const LLAssetType::EType new_typ
mFileID = new_id;
mFileType = new_type;
+ mPath = fsyspath(LLDiskCache::metaDataToFilepath(mFileID, mFileType));
return true;
}
bool LLFileSystem::remove() const
{
- LLFileSystem::removeFile(mFileID, mFileType);
+ LLFile::remove(mPath);
return true;
}
-void LLFileSystem::updateFileAccessTime(const std::string& file_path)
+void LLFileSystem::updateFileAccessTime()
{
/**
* Threshold in time_t units that is used to decide if the last access time
@@ -292,52 +279,32 @@ void LLFileSystem::updateFileAccessTime(const std::string& file_path)
*
* Let's start with 1 hour in time_t units and see how that unfolds
*/
- constexpr std::time_t time_threshold = 1 * 60 * 60;
+ constexpr std::chrono::hours time_threshold(1);
// current time
- const std::time_t cur_time = std::time(nullptr);
-
- boost::system::error_code ec;
-#if LL_WINDOWS
- // file last write time
- const std::time_t last_write_time = boost::filesystem::last_write_time(ll_convert<std::wstring>(file_path), ec);
- if (ec.failed())
- {
- LL_WARNS() << "Failed to read last write time for cache file " << file_path << ": " << ec.message() << LL_ENDL;
- return;
- }
-
- // delta between cur time and last time the file was written
- const std::time_t delta_time = cur_time - last_write_time;
+ const std::filesystem::file_time_type cur_time = std::chrono::file_clock::now();
- // we only write the new value if the time in time_threshold has elapsed
- // before the last one
- if (delta_time > time_threshold)
- {
- boost::filesystem::last_write_time(ll_convert<std::wstring>(file_path), cur_time, ec);
- }
-#else
+ std::error_code ec;
// file last write time
- const std::time_t last_write_time = boost::filesystem::last_write_time(file_path, ec);
- if (ec.failed())
+ const std::filesystem::file_time_type last_write_time = std::filesystem::last_write_time(mPath, ec);
+ if (ec)
{
- LL_WARNS() << "Failed to read last write time for cache file " << file_path << ": " << ec.message() << LL_ENDL;
+ LL_WARNS() << "Failed to read last write time for cache file " << mPath << ": " << ec.message() << LL_ENDL;
return;
}
// delta between cur time and last time the file was written
- const std::time_t delta_time = cur_time - last_write_time;
+ const auto delta_time = cur_time - last_write_time;
// we only write the new value if the time in time_threshold has elapsed
// before the last one
if (delta_time > time_threshold)
{
- boost::filesystem::last_write_time(file_path, cur_time, ec);
+ std::filesystem::last_write_time(mPath, cur_time, ec);
}
-#endif
- if (ec.failed())
+ if (ec)
{
- LL_WARNS() << "Failed to update last write time for cache file " << file_path << ": " << ec.message() << LL_ENDL;
+ LL_WARNS() << "Failed to update last write time for cache file " << mPath << ": " << ec.message() << LL_ENDL;
}
}
diff --git a/indra/llfilesystem/llfilesystem.h b/indra/llfilesystem/llfilesystem.h
index 7188683e7f..bc8b9216bd 100644
--- a/indra/llfilesystem/llfilesystem.h
+++ b/indra/llfilesystem/llfilesystem.h
@@ -33,6 +33,7 @@
#include "lluuid.h"
#include "llassettype.h"
#include "lldiskcache.h"
+#include <filesystem>
class LLFileSystem
{
@@ -58,13 +59,12 @@ class LLFileSystem
* file in the cache is read (not written) so that the last time the file was
* accessed is up to date (This is used in the mechanism for purging the cache)
*/
- void updateFileAccessTime(const std::string& file_path);
+ void updateFileAccessTime();
static bool getExists(const LLUUID& file_id, const LLAssetType::EType file_type);
static bool removeFile(const LLUUID& file_id, const LLAssetType::EType file_type, int suppress_warning = 0);
static bool renameFile(const LLUUID& old_file_id, const LLAssetType::EType old_file_type,
const LLUUID& new_file_id, const LLAssetType::EType new_file_type);
- static S64 getFileSize(const LLUUID& file_id, const LLAssetType::EType file_type);
public:
static const S32 READ;
@@ -73,6 +73,7 @@ class LLFileSystem
static const S32 APPEND;
protected:
+ std::filesystem::path mPath;
LLAssetType::EType mFileType;
LLUUID mFileID;
S32 mPosition;
diff --git a/indra/llfilesystem/tests/lldir_test.cpp b/indra/llfilesystem/tests/lldir_test.cpp
index 8b86da40b3..b879fef48a 100644
--- a/indra/llfilesystem/tests/lldir_test.cpp
+++ b/indra/llfilesystem/tests/lldir_test.cpp
@@ -405,7 +405,7 @@ namespace tut
std::string makeTestFile( const std::string& dir, const std::string& file )
{
std::string path = dir + file;
- LLFILE* handle = LLFile::fopen( path, "w" );
+ LLFILE* handle = LLFile::fopen(path, TEXT("w"));
ensure("failed to open test file '"+path+"'", handle != NULL );
// Harbison & Steele, 4th ed., p. 366: "If an error occurs, fputs
// returns EOF; otherwise, it returns some other, nonnegative value."
diff --git a/indra/llimage/llimagedimensionsinfo.cpp b/indra/llimage/llimagedimensionsinfo.cpp
index c896d60c85..1d93014e1b 100644
--- a/indra/llimage/llimagedimensionsinfo.cpp
+++ b/indra/llimage/llimagedimensionsinfo.cpp
@@ -166,7 +166,7 @@ bool LLImageDimensionsInfo::getImageDimensionsJpeg()
{
sJpegErrorEncountered = false;
clean();
- FILE* fp = LLFile::fopen(mSrcFilename, "rb");
+ FILE* fp = LLFile::fopen(mSrcFilename, TEXT("rb"));
if (!fp)
{
setLastError("Unable to open file for reading", mSrcFilename);
diff --git a/indra/llimage/llimagetga.cpp b/indra/llimage/llimagetga.cpp
index 25232b77aa..7c6686db95 100644
--- a/indra/llimage/llimagetga.cpp
+++ b/indra/llimage/llimagetga.cpp
@@ -1191,7 +1191,7 @@ bool LLImageTGA::loadFile( const std::string& path )
return false;
}
- LLFILE* file = LLFile::fopen(path, "rb"); /* Flawfinder: ignore */
+ LLFILE* file = LLFile::fopen(path, TEXT("rb")); /* Flawfinder: ignore */
if( !file )
{
LL_WARNS() << "Couldn't open file " << path << LL_ENDL;
diff --git a/indra/llmessage/llassetstorage.cpp b/indra/llmessage/llassetstorage.cpp
index 34eeacb273..13be0161b4 100644
--- a/indra/llmessage/llassetstorage.cpp
+++ b/indra/llmessage/llassetstorage.cpp
@@ -1402,7 +1402,7 @@ void LLAssetStorage::legacyGetDataCallback(const LLUUID &uuid,
uuid.toString(uuid_str);
filename = llformat("%s.%s",gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_str).c_str(),LLAssetType::lookup(type));
- LLFILE* fp = LLFile::fopen(filename, "wb"); /* Flawfinder: ignore */
+ LLFILE* fp = LLFile::fopen(filename, TEXT("wb")); /* Flawfinder: ignore */
if (fp)
{
const S32 buf_size = 65536;
diff --git a/indra/llmessage/lltransfersourcefile.cpp b/indra/llmessage/lltransfersourcefile.cpp
index 77a6c466c7..c2bf5c2afa 100644
--- a/indra/llmessage/lltransfersourcefile.cpp
+++ b/indra/llmessage/lltransfersourcefile.cpp
@@ -62,7 +62,7 @@ void LLTransferSourceFile::initTransfer()
return;
}
// Look for the file.
- mFP = LLFile::fopen(mParams.getFilename(), "rb"); /* Flawfinder: ignore */
+ mFP = LLFile::fopen(mParams.getFilename(), TEXT("rb")); /* Flawfinder: ignore */
if (!mFP)
{
sendTransferStatus(LLTS_ERROR);
diff --git a/indra/llmessage/lltransfertargetfile.cpp b/indra/llmessage/lltransfertargetfile.cpp
index 6d8b69fa6f..cc66befcae 100644
--- a/indra/llmessage/lltransfertargetfile.cpp
+++ b/indra/llmessage/lltransfertargetfile.cpp
@@ -75,7 +75,7 @@ LLTSCode LLTransferTargetFile::dataCallback(const S32 packet_id, U8 *in_datap, c
if (!mFP)
{
- mFP = LLFile::fopen(mParams.mFilename, "wb"); /* Flawfinder: ignore */
+ mFP = LLFile::fopen(mParams.mFilename, TEXT("wb")); /* Flawfinder: ignore */
if (!mFP)
{
diff --git a/indra/llmessage/llxfer_file.cpp b/indra/llmessage/llxfer_file.cpp
index 71b910297b..f0310c6297 100644
--- a/indra/llmessage/llxfer_file.cpp
+++ b/indra/llmessage/llxfer_file.cpp
@@ -161,7 +161,7 @@ S32 LLXfer_File::initializeRequest(U64 xfer_id,
S32 LLXfer_File::startDownload()
{
S32 retval = 0; // presume success
- mFp = LLFile::fopen(mTempFilename,"w+b"); /* Flawfinder : ignore */
+ mFp = LLFile::fopen(mTempFilename,TEXT("w+b")); /* Flawfinder : ignore */
if (mFp)
{
fclose(mFp);
@@ -209,7 +209,7 @@ S32 LLXfer_File::startSend (U64 xfer_id, const LLHost &remote_host)
mBufferStartOffset = 0;
// We leave the file open, assuming we'll start reading and sending soon
- mFp = LLFile::fopen(mLocalFilename,"rb"); /* Flawfinder : ignore */
+ mFp = LLFile::fopen(mLocalFilename,TEXT("rb")); /* Flawfinder : ignore */
if (mFp)
{
fseek(mFp,0,SEEK_END);
@@ -252,7 +252,7 @@ S32 LLXfer_File::reopenFileHandle()
if (mFp == NULL)
{
- mFp = LLFile::fopen(mLocalFilename,"rb"); /* Flawfinder : ignore */
+ mFp = LLFile::fopen(mLocalFilename,TEXT("rb")); /* Flawfinder : ignore */
if (mFp == NULL)
{
LL_INFOS("Xfer") << "Warning: " << mLocalFilename << " not found when re-opening file" << LL_ENDL;
@@ -313,7 +313,7 @@ S32 LLXfer_File::flush()
{
LL_ERRS("Xfer") << "Overwriting open file pointer!" << LL_ENDL;
}
- mFp = LLFile::fopen(mTempFilename,"a+b"); /* Flawfinder : ignore */
+ mFp = LLFile::fopen(mTempFilename,TEXT("a+b")); /* Flawfinder : ignore */
if (mFp)
{
@@ -381,11 +381,11 @@ S32 LLXfer_File::processEOF()
}
else
{
- //LLFILE* fp = LLFile::fopen(mTempFilename, "r");
+ //LLFILE* fp = LLFile::fopen(mTempFilename, TEXT("r"));
//LL_WARNS() << "File " << mTempFilename << " does "
// << (!fp ? "not" : "" ) << " exit." << LL_ENDL;
//if(fp) fclose(fp);
- //fp = LLFile::fopen(mLocalFilename, "r");
+ //fp = LLFile::fopen(mLocalFilename, TEXT("r"));
//LL_WARNS() << "File " << mLocalFilename << " does "
// << (!fp ? "not" : "" ) << " exit." << LL_ENDL;
//if(fp) fclose(fp);
@@ -452,8 +452,8 @@ U32 LLXfer_File::getXferTypeTag()
S32 copy_file(const std::string& from, const std::string& to)
{
S32 rv = 0;
- LLFILE* in = LLFile::fopen(from, "rb"); /*Flawfinder: ignore*/
- LLFILE* out = LLFile::fopen(to, "wb"); /*Flawfinder: ignore*/
+ LLFILE* in = LLFile::fopen(from, TEXT("rb")); /*Flawfinder: ignore*/
+ LLFILE* out = LLFile::fopen(to, TEXT("wb")); /*Flawfinder: ignore*/
if(in && out)
{
S32 read = 0;
diff --git a/indra/llmessage/message.cpp b/indra/llmessage/message.cpp
index e2937490ba..5b3b57f11e 100644
--- a/indra/llmessage/message.cpp
+++ b/indra/llmessage/message.cpp
@@ -2376,7 +2376,7 @@ void dump_prehash_files()
{
U32 i;
std::string filename("../../indra/llmessage/message_prehash.h");
- LLFILE* fp = LLFile::fopen(filename, "w"); /* Flawfinder: ignore */
+ LLFILE* fp = LLFile::fopen(filename, TEXT("w")); /* Flawfinder: ignore */
if (fp)
{
fprintf(
@@ -2407,7 +2407,7 @@ void dump_prehash_files()
fclose(fp);
}
filename = std::string("../../indra/llmessage/message_prehash.cpp");
- fp = LLFile::fopen(filename, "w"); /* Flawfinder: ignore */
+ fp = LLFile::fopen(filename, TEXT("w")); /* Flawfinder: ignore */
if (fp)
{
fprintf(
diff --git a/indra/llmessage/tests/lldatapacker_test.cpp b/indra/llmessage/tests/lldatapacker_test.cpp
index 746817936d..92a2c31ca8 100644
--- a/indra/llmessage/tests/lldatapacker_test.cpp
+++ b/indra/llmessage/tests/lldatapacker_test.cpp
@@ -348,7 +348,7 @@ namespace tut
{
F32 f_val = 44.44f, f_unpkval;
- LLFILE* fp = LLFile::fopen(TEST_FILE_NAME, "w+");
+ LLFILE* fp = LLFile::fopen(TEST_FILE_NAME, TEXT("w+"));
if(!fp)
{
LL_ERRS() << "File couldnt be open" << LL_ENDL;
@@ -403,7 +403,7 @@ namespace tut
LLVector4 unpkllvec4;
LLUUID unpkuuid;
- LLFILE* fp = LLFile::fopen(TEST_FILE_NAME,"w+");
+ LLFILE* fp = LLFile::fopen(TEST_FILE_NAME,TEXT("w+"));
if(!fp)
{
LL_ERRS() << "File couldnt be open" << LL_ENDL;
diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index 7e8d31232b..0ed98f2e7e 100644
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -501,7 +501,7 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev
open_file_name = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "shaders/errorF.glsl");
}
- file = LLFile::fopen(open_file_name, "r");
+ file = LLFile::fopen(open_file_name, TEXT("r"));
}
else
#endif
@@ -529,7 +529,7 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev
*/
LL_DEBUGS("ShaderLoading") << "Looking in " << open_file_name << LL_ENDL;
- file = LLFile::fopen(open_file_name, "r"); /* Flawfinder: ignore */
+ file = LLFile::fopen(open_file_name, TEXT("r")); /* Flawfinder: ignore */
if (file)
{
LL_DEBUGS("ShaderLoading") << "Loading file: " << open_file_name << " (Want class " << gpu_class << ")" << LL_ENDL;
diff --git a/indra/llui/lluicolortable.cpp b/indra/llui/lluicolortable.cpp
index a792cb8103..206d02b366 100644
--- a/indra/llui/lluicolortable.cpp
+++ b/indra/llui/lluicolortable.cpp
@@ -298,7 +298,7 @@ void LLUIColorTable::saveUserSettings() const
if(!output_node->isNull())
{
const std::string& filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "colors.xml");
- LLFILE *fp = LLFile::fopen(filename, "w");
+ LLFILE *fp = LLFile::fopen(filename, TEXT("w"));
if(fp != NULL)
{
diff --git a/indra/llui/llxuiparser.cpp b/indra/llui/llxuiparser.cpp
index 8fd85a89a1..e3d806bdd0 100644
--- a/indra/llui/llxuiparser.cpp
+++ b/indra/llui/llxuiparser.cpp
@@ -637,7 +637,7 @@ void LLXUIXSDWriter::writeXSD(const std::string& type_name, const std::string& p
}
}
- LLFILE* xsd_file = LLFile::fopen(file_name.c_str(), "w");
+ LLFILE* xsd_file = LLFile::fopen(file_name.c_str(), TEXT("w"));
LLXMLNode::writeHeaderToFile(xsd_file);
root_nodep->writeToFile(xsd_file);
fclose(xsd_file);
@@ -1326,7 +1326,7 @@ void LLXUIParser::parserError(const std::string& message)
struct ScopedFile
{
- ScopedFile( const std::string& filename, const char* accessmode )
+ ScopedFile( const std::string& filename, const LLFile::fopen_flags_t* accessmode )
{
mFile = LLFile::fopen(filename, accessmode);
}
@@ -1397,7 +1397,7 @@ bool LLSimpleXUIParser::readXUI(const std::string& filename, LLInitParam::BaseBl
mCurReadDepth = 0;
setParseSilently(silent);
- ScopedFile file(filename, "rb");
+ ScopedFile file(filename, TEXT("rb"));
if( !file.isOpen() )
{
LL_WARNS("ReadXUI") << "Unable to open file " << filename << LL_ENDL;
diff --git a/indra/llxml/llcontrol.cpp b/indra/llxml/llcontrol.cpp
index 562a30e8d1..a8e44f7bdd 100644
--- a/indra/llxml/llcontrol.cpp
+++ b/indra/llxml/llcontrol.cpp
@@ -399,7 +399,7 @@ void LLControlGroup::cleanup()
if(mSettingsProfile && getCount.size() != 0)
{
std::string file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, SETTINGS_PROFILE);
- LLFILE* out = LLFile::fopen(file, "w"); /* Flawfinder: ignore */
+ LLFILE* out = LLFile::fopen(file, TEXT("w")); /* Flawfinder: ignore */
if(!out)
{
LL_WARNS("SettingsProfile") << "Error opening " << SETTINGS_PROFILE << LL_ENDL;
diff --git a/indra/llxml/llxmlparser.cpp b/indra/llxml/llxmlparser.cpp
index e2c7d17e2a..5aac9100dd 100644
--- a/indra/llxml/llxmlparser.cpp
+++ b/indra/llxml/llxmlparser.cpp
@@ -72,7 +72,7 @@ bool LLXmlParser::parseFile(const std::string &path)
bool success = true;
- LLFILE* file = LLFile::fopen(path, "rb"); /* Flawfinder: ignore */
+ LLFILE* file = LLFile::fopen(path, TEXT("rb")); /* Flawfinder: ignore */
if( !file )
{
mAuxErrorString = llformat( "Couldn't open file %s", path.c_str());
@@ -388,7 +388,7 @@ int main()
{
char buf[1024];
- LLFILE* file = LLFile::fopen("test.xml", "rb");
+ LLFILE* file = LLFile::fopen("test.xml", TEXT("rb"));
if( !file )
{
return 1;
diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp
index 4a4985d8ac..63a3743ef7 100644
--- a/indra/newview/llconversationlog.cpp
+++ b/indra/newview/llconversationlog.cpp
@@ -512,7 +512,7 @@ bool LLConversationLog::saveToFile(const std::string& filename)
return false;
}
- LLFILE* fp = LLFile::fopen(filename, "wb");
+ LLFILE* fp = LLFile::fopen(filename, TEXT("wb"));
if (!fp)
{
LL_WARNS() << "Couldn't open call log list" << filename << LL_ENDL;
@@ -556,7 +556,7 @@ bool LLConversationLog::loadFromFile(const std::string& filename)
return false;
}
- LLFILE* fp = LLFile::fopen(filename, "rb");
+ LLFILE* fp = LLFile::fopen(filename, TEXT("rb"));
if (!fp)
{
LL_WARNS() << "Couldn't open call log list" << filename << LL_ENDL;
diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp
index 6c151351ff..200fce7b5b 100644
--- a/indra/newview/lldrawpoolbump.cpp
+++ b/indra/newview/lldrawpoolbump.cpp
@@ -114,7 +114,7 @@ void LLStandardBumpmap::addstandard()
gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount++] = LLStandardBumpmap("Darkness"); // BE_DARKNESS
std::string file_name = gDirUtilp->getExpandedFilename( LL_PATH_APP_SETTINGS, "std_bump.ini" );
- LLFILE* file = LLFile::fopen( file_name, "rt" ); /*Flawfinder: ignore*/
+ LLFILE* file = LLFile::fopen( file_name, TEXT("rt") ); /*Flawfinder: ignore*/
if( !file )
{
LL_WARNS() << "Could not open std_bump <" << file_name << ">" << LL_ENDL;
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 4fa14a199d..989dbc0c29 100755
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -2037,9 +2037,13 @@ void LLFloaterPreference::changed()
{
// onClearLog clears list, then notifies changed() and only then clears file,
// so check presence of conversations before checking file, file will cleared later.
- bool has_logs = LLConversationLog::instance().getConversations().size() > 0
- && LLFile::isfile(LLConversationLog::instance().getFileName())
- && LLFile::size(LLConversationLog::instance().getFileName()) > 0;
+ bool has_logs = false;
+ if (LLConversationLog::instance().getConversations().size() > 0)
+ {
+ std::filesystem::path file_path = fsyspath(LLConversationLog::instance().getFileName());
+ has_logs = LLFile::isfile(file_path)
+ && LLFile::size(file_path) > 0;
+ }
getChild<LLButton>("clear_log")->setEnabled(has_logs);
}
diff --git a/indra/newview/llfloateruipreview.cpp b/indra/newview/llfloateruipreview.cpp
index 0bf0946c42..cf710d45dd 100755
--- a/indra/newview/llfloateruipreview.cpp
+++ b/indra/newview/llfloateruipreview.cpp
@@ -574,7 +574,7 @@ void LLFloaterUIPreview::onClickExportSchema()
// std::string file_name(template_path + gDirUtilp->getDirDelimiter() + widget_name + ".rng");
- // LLFILE* rng_file = LLFile::fopen(file_name.c_str(), "w");
+ // LLFILE* rng_file = LLFile::fopen(file_name.c_str(), TEXT("w"));
// {
// LLXMLNode::writeHeaderToFile(rng_file);
// const bool use_type_decorations = false;
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index 043fd7003d..9491c9d610 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -2745,7 +2745,7 @@ bool LLInventoryModel::loadSkeleton(
const S32 NO_VERSION = LLViewerInventoryCategory::VERSION_UNKNOWN;
std::string gzip_filename(inventory_filename);
gzip_filename.append(".gz");
- LLFILE* fp = LLFile::fopen(gzip_filename, "rb");
+ LLFILE* fp = LLFile::fopen(gzip_filename, TEXT("rb"));
bool remove_inventory_file = false;
if (LLAppViewer::instance()->isSecondInstance())
{
@@ -4908,7 +4908,7 @@ bool decompress_file(const char* src_filename, const char* dst_filename)
// open the files
src = gzopen(src_filename, "rb");
if(!src) goto err_decompress;
- dst = LLFile::fopen(dst_filename, "wb");
+ dst = LLFile::fopen(dst_filename, TEXT("wb"));
if(!dst) goto err_decompress;
// decompress.
diff --git a/indra/newview/llkeyconflict.cpp b/indra/newview/llkeyconflict.cpp
index 666ab4f5d0..458d5225e1 100644
--- a/indra/newview/llkeyconflict.cpp
+++ b/indra/newview/llkeyconflict.cpp
@@ -575,7 +575,7 @@ void LLKeyConflictHandler::saveToSettings(bool temporary)
// Write the resulting XML to file
if (!output_node->isNull())
{
- LLFILE *fp = LLFile::fopen(filename, "w");
+ LLFILE *fp = LLFile::fopen(filename, TEXT("w"));
if (fp != NULL)
{
LLXMLNode::writeHeaderToFile(fp);
diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp
index 30ea255e24..405530f5bd 100644
--- a/indra/newview/lllogchat.cpp
+++ b/indra/newview/lllogchat.cpp
@@ -453,7 +453,7 @@ void LLLogChat::loadChatHistory(const std::string& file_name, std::list<LLSD>& m
// If we got here, we managed to stat the file.
// Open the file to read in binary mode to prevent interpreting other characters as EOF
- LLFILE* fptr = LLFile::fopen(log_file_name, "rb"); /*Flawfinder: ignore*/
+ LLFILE* fptr = LLFile::fopen(log_file_name, TEXT("rb")); /*Flawfinder: ignore*/
if (!fptr)
{ // Ok, this is strange but not really tragic in the big picture of things
LL_WARNS("ChatHistory") << "Unable to read file " << log_file_name << " after stat was successful" << LL_ENDL;
@@ -890,7 +890,7 @@ bool LLLogChat::isAdHocTranscriptExist(std::string file_name)
bool LLLogChat::isTranscriptFileFound(std::string fullname)
{
bool result = false;
- LLFILE * filep = LLFile::fopen(fullname, "rb");
+ LLFILE * filep = LLFile::fopen(fullname, TEXT("rb"));
if (NULL != filep)
{
if (makeLogFileName("chat") == fullname)
@@ -1183,7 +1183,7 @@ void LLLoadHistoryThread::loadHistory(const std::string& file_name, std::list<LL
}
bool load_all_history = load_params.has("load_all_history") ? load_params["load_all_history"].asBoolean() : false;
- LLFILE* fptr = LLFile::fopen(LLLogChat::makeLogFileName(file_name), "rb");/*Flawfinder: ignore*/
+ LLFILE* fptr = LLFile::fopen(LLLogChat::makeLogFileName(file_name), TEXT("rb"));/*Flawfinder: ignore*/
if (!fptr)
{
@@ -1192,17 +1192,17 @@ void LLLoadHistoryThread::loadHistory(const std::string& file_name, std::list<LL
{
std::string old_name(file_name);
old_name.erase(old_name.size() - GROUP_CHAT_SUFFIX.size());
- fptr = LLFile::fopen(LLLogChat::makeLogFileName(old_name), "rb");
+ fptr = LLFile::fopen(LLLogChat::makeLogFileName(old_name), TEXT("rb"));
if (fptr)
{
fclose(fptr);
LLFile::copy(LLLogChat::makeLogFileName(old_name), LLLogChat::makeLogFileName(file_name));
}
- fptr = LLFile::fopen(LLLogChat::makeLogFileName(file_name), "rb");
+ fptr = LLFile::fopen(LLLogChat::makeLogFileName(file_name), TEXT("rb"));
}
if (!fptr)
{
- fptr = LLFile::fopen(LLLogChat::oldLogFileName(file_name), "rb");/*Flawfinder: ignore*/
+ fptr = LLFile::fopen(LLLogChat::oldLogFileName(file_name), TEXT("rb"));/*Flawfinder: ignore*/
if (!fptr)
{
mNewLoad = false;
diff --git a/indra/newview/llmutelist.cpp b/indra/newview/llmutelist.cpp
index 9157e34833..0e9fe5eb52 100644
--- a/indra/newview/llmutelist.cpp
+++ b/indra/newview/llmutelist.cpp
@@ -589,7 +589,7 @@ bool LLMuteList::loadFromFile(const std::string& filename)
return false;
}
- LLFILE* fp = LLFile::fopen(filename, "rb"); /*Flawfinder: ignore*/
+ LLFILE* fp = LLFile::fopen(filename, TEXT("rb")); /*Flawfinder: ignore*/
if (!fp)
{
LL_WARNS() << "Couldn't open mute list " << filename << LL_ENDL;
@@ -653,7 +653,7 @@ bool LLMuteList::saveToFile(const std::string& filename)
return false;
}
- LLFILE* fp = LLFile::fopen(filename, "wb"); /*Flawfinder: ignore*/
+ LLFILE* fp = LLFile::fopen(filename, TEXT("wb")); /*Flawfinder: ignore*/
if (!fp)
{
LL_WARNS() << "Couldn't open mute list " << filename << LL_ENDL;
@@ -940,7 +940,7 @@ LLRenderMuteList::LLRenderMuteList()
bool LLRenderMuteList::saveToFile()
{
std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "render_mute_settings.txt");
- LLFILE* fp = LLFile::fopen(filename, "wb");
+ LLFILE* fp = LLFile::fopen(filename, TEXT("wb"));
if (!fp)
{
LL_WARNS() << "Couldn't open render mute list file: " << filename << LL_ENDL;
@@ -963,7 +963,7 @@ bool LLRenderMuteList::saveToFile()
bool LLRenderMuteList::loadFromFile()
{
std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "render_mute_settings.txt");
- LLFILE* fp = LLFile::fopen(filename, "rb");
+ LLFILE* fp = LLFile::fopen(filename, TEXT("rb"));
if (!fp)
{
LL_WARNS() << "Couldn't open render mute list file: " << filename << LL_ENDL;
diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp
index 4fe661b055..6928d7e6c3 100644
--- a/indra/newview/llpreviewnotecard.cpp
+++ b/indra/newview/llpreviewnotecard.cpp
@@ -801,7 +801,7 @@ bool LLPreviewNotecard::loadNotecardText(const std::string& filename)
return false;
}
- LLFILE* file = LLFile::fopen(filename, "rb"); /*Flawfinder: ignore*/
+ LLFILE* file = LLFile::fopen(filename, TEXT("rb")); /*Flawfinder: ignore*/
if (!file)
{
LL_WARNS() << "Error opening " << filename << LL_ENDL;
@@ -832,7 +832,7 @@ bool LLPreviewNotecard::loadNotecardText(const std::string& filename)
bool LLPreviewNotecard::writeToFile(const std::string& filename)
{
- LLFILE* fp = LLFile::fopen(filename, "wb");
+ LLFILE* fp = LLFile::fopen(filename, TEXT("wb"));
if (!fp)
{
LL_WARNS() << "Unable to write to " << filename << LL_ENDL;
diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp
index 2c436198e3..c73976e540 100644
--- a/indra/newview/llpreviewscript.cpp
+++ b/indra/newview/llpreviewscript.cpp
@@ -632,7 +632,7 @@ bool LLScriptEdCore::loadScriptText(const std::string& filename)
return false;
}
- LLFILE* file = LLFile::fopen(filename, "rb"); /*Flawfinder: ignore*/
+ LLFILE* file = LLFile::fopen(filename, TEXT("rb")); /*Flawfinder: ignore*/
if (!file)
{
LL_WARNS() << "Error opening " << filename << LL_ENDL;
@@ -663,7 +663,7 @@ bool LLScriptEdCore::loadScriptText(const std::string& filename)
bool LLScriptEdCore::writeToFile(const std::string& filename)
{
- LLFILE* fp = LLFile::fopen(filename, "wb");
+ LLFILE* fp = LLFile::fopen(filename, TEXT("wb"));
if (!fp)
{
LL_WARNS() << "Unable to write to " << filename << LL_ENDL;
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 3ce9526488..37609f74ed 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -587,7 +587,7 @@ bool idle_startup()
std::string message_template_path = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,"message_template.msg");
LLFILE* found_template = NULL;
- found_template = LLFile::fopen(message_template_path, "r"); /* Flawfinder: ignore */
+ found_template = LLFile::fopen(message_template_path, TEXT("r")); /* Flawfinder: ignore */
#if LL_WINDOWS
// On the windows dev builds, unpackaged, the message_template.msg
@@ -596,7 +596,7 @@ bool idle_startup()
if (!found_template)
{
message_template_path = gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "app_settings", "message_template.msg");
- found_template = LLFile::fopen(message_template_path.c_str(), "r"); /* Flawfinder: ignore */
+ found_template = LLFile::fopen(message_template_path.c_str(), TEXT("r")); /* Flawfinder: ignore */
}
#elif LL_DARWIN
// On Mac dev builds, message_template.msg lives in:
@@ -606,7 +606,7 @@ bool idle_startup()
message_template_path =
gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,
"message_template.msg");
- found_template = LLFile::fopen(message_template_path.c_str(), "r"); /* Flawfinder: ignore */
+ found_template = LLFile::fopen(message_template_path.c_str(), TEXT("r")); /* Flawfinder: ignore */
}
#endif
diff --git a/indra/newview/lltoolbarview.cpp b/indra/newview/lltoolbarview.cpp
index c1ec5fa183..d1e36676af 100644
--- a/indra/newview/lltoolbarview.cpp
+++ b/indra/newview/lltoolbarview.cpp
@@ -420,7 +420,7 @@ void LLToolBarView::saveToolbars() const
if(!output_node->isNull())
{
const std::string& filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "toolbars.xml");
- LLFILE *fp = LLFile::fopen(filename, "w");
+ LLFILE *fp = LLFile::fopen(filename, TEXT("w"));
if (fp != NULL)
{
LLXMLNode::writeHeaderToFile(fp);
diff --git a/indra/newview/llviewerassetstorage.cpp b/indra/newview/llviewerassetstorage.cpp
index e76d340eda..c28f3dc73a 100644
--- a/indra/newview/llviewerassetstorage.cpp
+++ b/indra/newview/llviewerassetstorage.cpp
@@ -182,7 +182,7 @@ void LLViewerAssetStorage::storeAssetData(
else
{
// LLAssetStorage metric: Successful Request
- S32 size = (S32)LLFileSystem::getFileSize(asset_id, asset_type);
+ S32 size = vfile.getSize();
const char *message = "Added to upload queue";
reportMetric( asset_id, asset_type, LLStringUtil::null, LLUUID::null, size, MR_OKAY, __FILE__, __LINE__, message );
@@ -279,7 +279,7 @@ void LLViewerAssetStorage::storeAssetData(
LL_DEBUGS("AssetStorage") << "ASSET_ID: " << asset_id << LL_ENDL;
S32 size = 0;
- LLFILE* fp = LLFile::fopen(filename, "rb");
+ LLFILE* fp = LLFile::fopen(filename, TEXT("rb"));
if (fp)
{
fseek(fp, 0, SEEK_END);
diff --git a/indra/newview/llviewerinput.cpp b/indra/newview/llviewerinput.cpp
index 3c79f0b21c..9b39f7b0e9 100644
--- a/indra/newview/llviewerinput.cpp
+++ b/indra/newview/llviewerinput.cpp
@@ -1430,7 +1430,7 @@ S32 LLViewerInput::loadBindingsXML(const std::string& filename)
// file in app_settings is supposed to be up to date
// this is only for the file from user_settings
LL_INFOS("ViewerInput") << "Updating file " << filename << " to a newer version" << LL_ENDL;
- LLFILE *fp = LLFile::fopen(filename, "w");
+ LLFILE *fp = LLFile::fopen(filename, TEXT("w"));
if (fp != NULL)
{
LLXMLNode::writeHeaderToFile(fp);
diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp
index 0e9bfb102f..a8ed2da9e0 100644
--- a/indra/newview/llviewermenufile.cpp
+++ b/indra/newview/llviewermenufile.cpp
@@ -1161,7 +1161,7 @@ void handle_compress_image()
// so doing dirty, but OS independent fopen and fseek
size_t get_file_size(std::string &filename)
{
- LLFILE* file = LLFile::fopen(filename, "rb"); /*Flawfinder: ignore*/
+ LLFILE* file = LLFile::fopen(filename, TEXT("rb")); /*Flawfinder: ignore*/
if (!file)
{
LL_WARNS() << "Error opening " << filename << LL_ENDL;
diff --git a/indra/newview/llviewerstatsrecorder.cpp b/indra/newview/llviewerstatsrecorder.cpp
index 58065ecce5..a2141f4eed 100644
--- a/indra/newview/llviewerstatsrecorder.cpp
+++ b/indra/newview/llviewerstatsrecorder.cpp
@@ -194,7 +194,7 @@ void LLViewerStatsRecorder::writeToLog( F32 interval )
// Open the data file
makeStatsFileName();
- mStatsFile = LLFile::fopen(mStatsFileName, "wb");
+ mStatsFile = LLFile::fopen(mStatsFileName, TEXT("wb"));
if (mStatsFile)
{