Skip to content

Commit

Permalink
Always return entire file with fileGetContents
Browse files Browse the repository at this point in the history
  • Loading branch information
botder committed Aug 7, 2023
1 parent b98f887 commit 1c0c978
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 11 deletions.
30 changes: 30 additions & 0 deletions Client/mods/deathmatch/logic/CScriptFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,36 @@ long CScriptFile::Write(unsigned long ulSize, const char* pData)
return m_pFile->FWrite(pData, ulSize);
}

long CScriptFile::GetContents(std::string& buffer)
{
if (!m_pFile)
return -1;

// Store the current position to restore it later.
const int currentPos = m_pFile->FTell();

// Move to the end of the file to determine the size.
m_pFile->FSeek(0, SEEK_END);
const int fileSize = m_pFile->FTell();

try
{
buffer.resize(fileSize);
}
catch (const std::bad_alloc&)
{
m_pFile->FSeek(currentPos, SEEK_SET);
return -2;
}

// Move to the start of the file to read the entire file.
m_pFile->FSeek(0, SEEK_SET);
const int bytesRead = m_pFile->FRead(buffer.data(), fileSize);
m_pFile->FSeek(currentPos, SEEK_SET);
buffer.resize(bytesRead);
return bytesRead;
}

// If file was downloaded with a resource, validate checksum
void CScriptFile::DoResourceFileCheck()
{
Expand Down
2 changes: 2 additions & 0 deletions Client/mods/deathmatch/logic/CScriptFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ class CScriptFile final : public CClientEntity
long Read(unsigned long ulSize, SString& outBuffer);
long Write(unsigned long ulSize, const char* pData);

long GetContents(std::string& buffer);

// Debug info for garbage collected files
const SLuaDebugInfo& GetLuaDebugInfo() { return m_LuaDebugInfo; };
void SetLuaDebugInfo(const SLuaDebugInfo& luaDebugInfo) { m_LuaDebugInfo = luaDebugInfo; };
Expand Down
30 changes: 30 additions & 0 deletions Server/mods/deathmatch/logic/CScriptFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,36 @@ long CScriptFile::Write(unsigned long ulSize, const char* pData)
return fwrite(pData, 1, ulSize, m_pFile);
}

long CScriptFile::GetContents(std::string& buffer)
{
if (!m_pFile)
return -1;

// Store the current position to restore it later.
const long currentPos = ftell(m_pFile);

// Move to the end of the file to determine the size.
fseek(m_pFile, 0, SEEK_END);
const long fileSize = ftell(m_pFile);

try
{
buffer.resize(fileSize);
}
catch (const std::bad_alloc&)
{
fseek(m_pFile, currentPos, SEEK_SET);
return -2;
}

// Move to the start of the file to read the entire file.
fseek(m_pFile, 0, SEEK_SET);
const long bytesRead = fread(buffer.data(), 1, fileSize, m_pFile);
fseek(m_pFile, currentPos, SEEK_SET);
buffer.resize(bytesRead);
return bytesRead;
}

CResource* CScriptFile::GetResource()
{
return m_pResource;
Expand Down
2 changes: 2 additions & 0 deletions Server/mods/deathmatch/logic/CScriptFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ class CScriptFile final : public CElement
long Read(unsigned long ulSize, SString& outBuffer);
long Write(unsigned long ulSize, const char* pData);

long GetContents(std::string& buffer);

// Debug info for garbage collected files
const SLuaDebugInfo& GetLuaDebugInfo() { return m_LuaDebugInfo; };
void SetLuaDebugInfo(const SLuaDebugInfo& luaDebugInfo) { m_LuaDebugInfo = luaDebugInfo; };
Expand Down
14 changes: 4 additions & 10 deletions Shared/mods/deathmatch/logic/luadefs/CLuaFileDefs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -799,14 +799,12 @@ int CLuaFileDefs::fileWrite(lua_State* luaVM)
return 1;
}

std::optional<SString> CLuaFileDefs::fileGetContents(lua_State* L, CScriptFile* scriptFile, std::optional<bool> maybeVerifyContents)
std::optional<std::string> CLuaFileDefs::fileGetContents(lua_State* L, CScriptFile* scriptFile, std::optional<bool> maybeVerifyContents)
{
// bool fileGetContents ( file target [, bool verifyContents = true ] )
// string fileGetContents ( file target [, bool verifyContents = true ] )

SString buffer;

// We abuse the logic of CScriptFile::Read to determine size of file and to resize the buffer accordingly, to avoid doing that work twice.
const long bytesRead = scriptFile->Read(std::numeric_limits<long>::max(), buffer);
std::string buffer;
const long bytesRead = scriptFile->GetContents(buffer);

if (bytesRead == -2)
{
Expand All @@ -819,10 +817,6 @@ std::optional<SString> CLuaFileDefs::fileGetContents(lua_State* L, CScriptFile*
return {};
}

// Remove EOF byte at the end of the buffer (which breaks checksum if we have to compute it below).
if (!buffer.empty())
buffer.resize(buffer.size() - 1);

if (maybeVerifyContents.value_or(true) == false)
return buffer;

Expand Down
2 changes: 1 addition & 1 deletion Shared/mods/deathmatch/logic/luadefs/CLuaFileDefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class CLuaFileDefs : public CLuaDefs
LUA_DECLARE(fileFlush);
LUA_DECLARE(fileRead);
LUA_DECLARE(fileWrite);
static std::optional<SString> fileGetContents(lua_State* L, CScriptFile* scriptFile, std::optional<bool> maybeVerifyContents);
static std::optional<std::string> fileGetContents(lua_State* L, CScriptFile* scriptFile, std::optional<bool> maybeVerifyContents);

LUA_DECLARE(fileGetPos);
LUA_DECLARE(fileGetSize);
Expand Down

0 comments on commit 1c0c978

Please sign in to comment.