summaryrefslogtreecommitdiff
path: root/indra/llcache/llvfile.cpp
diff options
context:
space:
mode:
authorCallum Prentice <callum@gmail.com>2020-09-16 18:53:24 -0700
committerCallum Prentice <callum@gmail.com>2020-09-16 18:53:24 -0700
commit3fc07dea01795b31c37dcd093ec73d190a1e188a (patch)
treeb000b56002957e5d0367aa87f0b03b8827181474 /indra/llcache/llvfile.cpp
parent060dd2aeab72df26d6375f2e0fad619113fe7e13 (diff)
First part of change to remove LLVFS from the Viewer. Consists of code changes to remove LLVFS and LLVFSThread classes along with the associated source files. The existing llvfs folder is renamed to llcache. Also includes changes to CMake script in many places to reflect changes. Eventually, llvfile source file and class will be renamed but that is not in this change.
Diffstat (limited to 'indra/llcache/llvfile.cpp')
-rw-r--r--indra/llcache/llvfile.cpp387
1 files changed, 387 insertions, 0 deletions
diff --git a/indra/llcache/llvfile.cpp b/indra/llcache/llvfile.cpp
new file mode 100644
index 0000000000..be753244c0
--- /dev/null
+++ b/indra/llcache/llvfile.cpp
@@ -0,0 +1,387 @@
+/**
+ * @file llvfile.cpp
+ * @brief Implementation of virtual file
+ *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "llvfile.h"
+
+#include "llerror.h"
+#include "llthread.h"
+#include "lltimer.h"
+#include "llfasttimer.h"
+#include "llmemory.h"
+
+#include <fstream>
+#include "lldir.h"
+
+const S32 LLVFile::READ = 0x00000001;
+const S32 LLVFile::WRITE = 0x00000002;
+const S32 LLVFile::READ_WRITE = 0x00000003; // LLVFile::READ & LLVFile::WRITE
+const S32 LLVFile::APPEND = 0x00000006; // 0x00000004 & LLVFile::WRITE
+
+static LLTrace::BlockTimerStatHandle FTM_VFILE_WAIT("VFile Wait");
+
+LLVFile::LLVFile(const LLUUID &file_id, const LLAssetType::EType file_type, S32 mode)
+{
+ mFileType = file_type;
+ mFileID = file_id;
+ mPosition = 0;
+ mBytesRead = 0;
+ mReadComplete = FALSE;
+ mMode = mode;
+}
+
+LLVFile::~LLVFile()
+{
+}
+
+const std::string assetTypeToString(LLAssetType::EType at)
+{
+ /**
+ * Make use of the C++17 (or is it 14) feature that allows
+ * for inline initialization of an std::map<>
+ */
+ typedef std::map<LLAssetType::EType, std::string> asset_type_to_name_t;
+ asset_type_to_name_t asset_type_to_name =
+ {
+ { LLAssetType::AT_TEXTURE, "TEXTURE" },
+ { LLAssetType::AT_SOUND, "SOUND" },
+ { LLAssetType::AT_CALLINGCARD, "CALLINGCARD" },
+ { LLAssetType::AT_LANDMARK, "LANDMARK" },
+ { LLAssetType::AT_SCRIPT, "SCRIPT" },
+ { LLAssetType::AT_CLOTHING, "CLOTHING" },
+ { LLAssetType::AT_OBJECT, "OBJECT" },
+ { LLAssetType::AT_NOTECARD, "NOTECARD" },
+ { LLAssetType::AT_CATEGORY, "CATEGORY" },
+ { LLAssetType::AT_LSL_TEXT, "LSL_TEXT" },
+ { LLAssetType::AT_LSL_BYTECODE, "LSL_BYTECODE" },
+ { LLAssetType::AT_TEXTURE_TGA, "TEXTURE_TGA" },
+ { LLAssetType::AT_BODYPART, "BODYPART" },
+ { LLAssetType::AT_SOUND_WAV, "SOUND_WAV" },
+ { LLAssetType::AT_IMAGE_TGA, "IMAGE_TGA" },
+ { LLAssetType::AT_IMAGE_JPEG, "IMAGE_JPEG" },
+ { LLAssetType::AT_ANIMATION, "ANIMATION" },
+ { LLAssetType::AT_GESTURE, "GESTURE" },
+ { LLAssetType::AT_SIMSTATE, "SIMSTATE" },
+ { LLAssetType::AT_LINK, "LINK" },
+ { LLAssetType::AT_LINK_FOLDER, "LINK_FOLDER" },
+ { LLAssetType::AT_MARKETPLACE_FOLDER, "MARKETPLACE_FOLDER" },
+ { LLAssetType::AT_WIDGET, "WIDGET" },
+ { LLAssetType::AT_PERSON, "PERSON" },
+ { LLAssetType::AT_MESH, "MESH" },
+ { LLAssetType::AT_SETTINGS, "SETTINGS" },
+ { LLAssetType::AT_UNKNOWN, "UNKNOWN" }
+ };
+
+ asset_type_to_name_t::iterator iter = asset_type_to_name.find(at);
+ if (iter != asset_type_to_name.end())
+ {
+ return iter->second;
+ }
+
+ return std::string("UNKNOWN");
+}
+
+const std::string idToFilepath(const std::string id, LLAssetType::EType at)
+{
+ /**
+ * For the moment this is just {UUID}_{ASSET_TYPE}.txt but of
+ * course, will be greatly expanded upon
+ */
+ std::ostringstream ss;
+ ss << "00cache_";
+ ss << id;
+ ss << "_";
+ ss << assetTypeToString(at);
+ ss << ".txt";
+
+ const std::string filepath = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ss.str());
+
+ return filepath;
+}
+
+// static
+bool LLVFile::getExists(const LLUUID &file_id, const LLAssetType::EType file_type)
+{
+ std::string id_str;
+ file_id.toString(id_str);
+ const std::string filename = idToFilepath(id_str, file_type);
+
+ std::ifstream file(filename, std::ios::binary);
+ if (file.is_open())
+ {
+ file.seekg(0, std::ios::end);
+ return file.tellg() > 0;
+ }
+ return false;
+}
+
+// static
+bool LLVFile::removeFile(const LLUUID &file_id, const LLAssetType::EType file_type)
+{
+ std::string id_str;
+ file_id.toString(id_str);
+ const std::string filename = idToFilepath(id_str, file_type);
+
+ std::remove(filename.c_str());
+
+ return true;
+}
+
+// static
+bool LLVFile::renameFile(const LLUUID &old_file_id, const LLAssetType::EType old_file_type,
+ const LLUUID &new_file_id, const LLAssetType::EType new_file_type)
+{
+ std::string old_id_str;
+ old_file_id.toString(old_id_str);
+ const std::string old_filename = idToFilepath(old_id_str, old_file_type);
+
+ std::string new_id_str;
+ new_file_id.toString(new_id_str);
+ const std::string new_filename = idToFilepath(new_id_str, new_file_type);
+
+ if (std::rename(old_filename.c_str(), new_filename.c_str()))
+ {
+ // We would like to return FALSE here indicating the operation
+ // failed but the original code does not and doing so seems to
+ // break a lot of things so we go with the flow...
+ //return FALSE;
+ }
+
+ return TRUE;
+}
+
+// static
+S32 LLVFile::getFileSize(const LLUUID &file_id, const LLAssetType::EType file_type)
+{
+ std::string id_str;
+ file_id.toString(id_str);
+ const std::string filename = idToFilepath(id_str, file_type);
+
+ S32 file_size = 0;
+ std::ifstream file(filename, std::ios::binary);
+ if (file.is_open())
+ {
+ file.seekg(0, std::ios::end);
+ file_size = file.tellg();
+ }
+
+ return file_size;
+}
+
+BOOL LLVFile::read(U8 *buffer, S32 bytes, BOOL async, F32 priority)
+{
+ BOOL success = TRUE;
+
+ mReadComplete = FALSE;
+
+ std::string id;
+ mFileID.toString(id);
+ const std::string filename = idToFilepath(id, mFileType);
+
+ std::ifstream file(filename, std::ios::binary);
+ if (file.is_open())
+ {
+ file.seekg(mPosition, std::ios::beg);
+
+ file.read((char*)buffer, bytes);
+
+ if (file)
+ {
+ mBytesRead = bytes;
+ }
+ else
+ {
+ mBytesRead = file.gcount();
+ }
+
+ file.close();
+
+ mPosition += mBytesRead;
+ if (!mBytesRead)
+ {
+ success = FALSE;
+ }
+
+ mReadComplete = TRUE;
+ }
+
+ return success;
+}
+
+BOOL LLVFile::isReadComplete()
+{
+ if (mReadComplete)
+ {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+S32 LLVFile::getLastBytesRead()
+{
+ return mBytesRead;
+}
+
+BOOL LLVFile::eof()
+{
+ return mPosition >= getSize();
+}
+
+BOOL LLVFile::write(const U8 *buffer, S32 bytes)
+{
+ std::string id_str;
+ mFileID.toString(id_str);
+ const std::string filename = idToFilepath(id_str, mFileType);
+
+ BOOL success = FALSE;
+
+ if (mMode == APPEND)
+ {
+ std::ofstream ofs(filename, std::ios::app | std::ios::binary);
+ if (ofs)
+ {
+ ofs.write((const char*)buffer, bytes);
+
+ success = TRUE;
+ }
+ }
+ else
+ {
+ std::ofstream ofs(filename, std::ios::binary);
+ if (ofs)
+ {
+ ofs.write((const char*)buffer, bytes);
+
+ mPosition += bytes;
+
+ success = TRUE;
+ }
+ }
+
+ return success;
+}
+
+//static
+BOOL LLVFile::writeFile(const U8 *buffer, S32 bytes, const LLUUID &uuid, LLAssetType::EType type)
+{
+ LLVFile file(uuid, type, LLVFile::WRITE);
+ file.setMaxSize(bytes);
+ return file.write(buffer, bytes);
+}
+
+BOOL LLVFile::seek(S32 offset, S32 origin)
+{
+ if (-1 == origin)
+ {
+ origin = mPosition;
+ }
+
+ S32 new_pos = origin + offset;
+
+ S32 size = getSize();
+
+ if (new_pos > size)
+ {
+ LL_WARNS() << "Attempt to seek past end of file" << LL_ENDL;
+
+ mPosition = size;
+ return FALSE;
+ }
+ else if (new_pos < 0)
+ {
+ LL_WARNS() << "Attempt to seek past beginning of file" << LL_ENDL;
+
+ mPosition = 0;
+ return FALSE;
+ }
+
+ mPosition = new_pos;
+ return TRUE;
+}
+
+S32 LLVFile::tell() const
+{
+ return mPosition;
+}
+
+S32 LLVFile::getSize()
+{
+ return LLVFile::getFileSize(mFileID, mFileType);
+}
+
+S32 LLVFile::getMaxSize()
+{
+ // offer up a huge size since we don't care what the max is
+ return INT_MAX;
+}
+
+BOOL LLVFile::setMaxSize(S32 size)
+{
+ // we don't care what the max size is so we do nothing
+ // and return true to indicate all was okay
+ return TRUE;
+}
+
+BOOL LLVFile::rename(const LLUUID &new_id, const LLAssetType::EType new_type)
+{
+ LLVFile::renameFile(mFileID, mFileType, new_id, new_type);
+
+ mFileID = new_id;
+ mFileType = new_type;
+
+ return TRUE;
+}
+
+BOOL LLVFile::remove()
+{
+ LLVFile::removeFile(mFileID, mFileType);
+
+ return TRUE;
+}
+
+// static
+void LLVFile::initClass()
+{
+}
+
+// static
+void LLVFile::cleanupClass()
+{
+}
+
+bool LLVFile::isLocked()
+{
+ // I don't think we care about this test since there is no locking
+ // TODO: remove this function and calling sites?
+ return FALSE;
+}
+
+void LLVFile::waitForLock()
+{
+ // TODO: remove this function and calling sites?
+}