mirror of
https://onedev.site.tesses.net/tesses-framework
synced 2026-02-09 00:05:46 +00:00
Add fshelpers and temp
This commit is contained in:
@@ -49,6 +49,8 @@ src/Filesystem/MemoryFilesystem.cpp
|
|||||||
src/Filesystem/SubdirFilesystem.cpp
|
src/Filesystem/SubdirFilesystem.cpp
|
||||||
src/Filesystem/NullFilesystem.cpp
|
src/Filesystem/NullFilesystem.cpp
|
||||||
src/Filesystem/MountableFilesystem.cpp
|
src/Filesystem/MountableFilesystem.cpp
|
||||||
|
src/Filesystem/FSHelpers.cpp
|
||||||
|
src/Filesystem/TempFS.cpp
|
||||||
src/Crypto/ClientTLSStream.cpp
|
src/Crypto/ClientTLSStream.cpp
|
||||||
src/Crypto/MbedHelpers.cpp
|
src/Crypto/MbedHelpers.cpp
|
||||||
src/Args.cpp
|
src/Args.cpp
|
||||||
@@ -379,3 +381,4 @@ set(CPACK_PACKAGE_VERSION_MINOR "${TessesFramework_VERSION_MINOR}")
|
|||||||
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libmbedtls-dev (>= 2.28.8)")
|
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libmbedtls-dev (>= 2.28.8)")
|
||||||
|
|
||||||
include(CPack)
|
include(CPack)
|
||||||
|
add_subdirectory(pkgconfig)
|
||||||
@@ -1 +1,2 @@
|
|||||||
export DEB_VERSION=1.0.0
|
export BUILD=$(($BUILD_NO-163))
|
||||||
|
export DEB_VERSION=1.0.0-$BUILD
|
||||||
@@ -16,23 +16,23 @@ namespace Tesses::Framework::Date
|
|||||||
int minute=0;
|
int minute=0;
|
||||||
int second=0;
|
int second=0;
|
||||||
bool isLocal=false;
|
bool isLocal=false;
|
||||||
int64_t ToEpochNoConvert();
|
int64_t ToEpochNoConvert() const;
|
||||||
void FromEpochNoConvert(int64_t gmt);
|
void FromEpochNoConvert(int64_t gmt);
|
||||||
public:
|
public:
|
||||||
DateTime();
|
DateTime();
|
||||||
DateTime(int year, int month, int day, int hour, int minute, int seconds, bool isLocal=true);
|
DateTime(int year, int month, int day, int hour, int minute, int seconds, bool isLocal=true);
|
||||||
DateTime(int64_t epoch);
|
DateTime(int64_t epoch);
|
||||||
int Year();
|
int Year() const;
|
||||||
int Month();
|
int Month() const;
|
||||||
int Day();
|
int Day() const;
|
||||||
int Hour();
|
int Hour() const;
|
||||||
int Minute();
|
int Minute() const;
|
||||||
int Second();
|
int Second() const;
|
||||||
int DayOfWeek();
|
int DayOfWeek() const;
|
||||||
bool IsLocal();
|
bool IsLocal() const;
|
||||||
int64_t ToEpoch();
|
int64_t ToEpoch() const;
|
||||||
DateTime ToLocal();
|
DateTime ToLocal() const;
|
||||||
DateTime ToUTC();
|
DateTime ToUTC() const;
|
||||||
void SetToLocal();
|
void SetToLocal();
|
||||||
void SetToUTC();
|
void SetToUTC();
|
||||||
void SetYear(int y);
|
void SetYear(int y);
|
||||||
@@ -52,15 +52,105 @@ namespace Tesses::Framework::Date
|
|||||||
static DateTime Now();
|
static DateTime Now();
|
||||||
static DateTime NowUTC();
|
static DateTime NowUTC();
|
||||||
|
|
||||||
std::string ToString();
|
std::string ToString() const;
|
||||||
std::string ToString(std::string fmt);
|
std::string ToString(std::string fmt) const;
|
||||||
|
|
||||||
|
|
||||||
std::string ToHttpDate();
|
std::string ToHttpDate() const;
|
||||||
static bool TryParseHttpDate(std::string txt, DateTime& dt);
|
static bool TryParseHttpDate(std::string txt, DateTime& dt);
|
||||||
|
|
||||||
|
operator std::string() const
|
||||||
|
{
|
||||||
|
return ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
operator int64_t() const
|
||||||
|
{
|
||||||
|
return ToEpoch();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
class TimeSpan {
|
||||||
|
int64_t totalSeconds;
|
||||||
|
public:
|
||||||
|
TimeSpan();
|
||||||
|
TimeSpan(int64_t totalSeconds);
|
||||||
|
TimeSpan(int hours, int minutes, int seconds);
|
||||||
|
TimeSpan(int days,int hours, int minutes, int seconds);
|
||||||
|
|
||||||
|
|
||||||
|
void Set(int days, int hours, int minutes, int seconds);
|
||||||
|
void Set(int hours, int minutes, int seconds);
|
||||||
|
|
||||||
|
void SetDays(int d);
|
||||||
|
void SetHours(int h);
|
||||||
|
void SetMinutes(int m);
|
||||||
|
void SetSeconds(int s);
|
||||||
|
|
||||||
|
|
||||||
|
int Days() const;
|
||||||
|
int Hours() const;
|
||||||
|
int Minutes() const;
|
||||||
|
int Seconds() const;
|
||||||
|
|
||||||
|
|
||||||
|
int64_t TotalSeconds() const;
|
||||||
|
int64_t TotalMinutes() const;
|
||||||
|
int64_t TotalHours() const;
|
||||||
|
|
||||||
|
|
||||||
|
void SetTotalSeconds(int64_t totalSeconds);
|
||||||
|
void SetTotalMinutes(int64_t totalMinutes);
|
||||||
|
void SetTotalHours(int64_t totalHours);
|
||||||
|
|
||||||
|
void AddSeconds(int64_t seconds);
|
||||||
|
void AddMinutes(int64_t minutes);
|
||||||
|
void AddHours(int64_t hours);
|
||||||
|
void AddDays(int64_t days);
|
||||||
|
|
||||||
|
std::string ToString(bool slim=true) const;
|
||||||
|
|
||||||
|
static bool TryParse(std::string text, TimeSpan& span);
|
||||||
|
|
||||||
|
operator int64_t() const
|
||||||
|
{
|
||||||
|
return TotalSeconds();
|
||||||
|
}
|
||||||
|
|
||||||
|
operator std::string()
|
||||||
|
{
|
||||||
|
return ToString();
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
DateTime operator+(const DateTime& dt, const TimeSpan& ts)
|
||||||
|
{
|
||||||
|
DateTime dt2(dt.ToEpoch() + ts.TotalSeconds());
|
||||||
|
if(dt.IsLocal())
|
||||||
|
dt2.SetToLocal();
|
||||||
|
return dt2;
|
||||||
|
}
|
||||||
|
DateTime operator+(const TimeSpan& ts,const DateTime& dt)
|
||||||
|
{
|
||||||
|
DateTime dt2(dt.ToEpoch() + ts.TotalSeconds());
|
||||||
|
if(dt.IsLocal())
|
||||||
|
dt2.SetToLocal();
|
||||||
|
return dt2;
|
||||||
|
}
|
||||||
|
TimeSpan operator+(const TimeSpan& ts, const TimeSpan& ts2)
|
||||||
|
{
|
||||||
|
return (int64_t)ts + (int64_t)ts2;
|
||||||
|
}
|
||||||
|
DateTime operator-(const DateTime& dt, const TimeSpan& ts)
|
||||||
|
{
|
||||||
|
DateTime dt2(dt.ToEpoch() - ts.TotalSeconds());
|
||||||
|
if(dt.IsLocal())
|
||||||
|
dt2.SetToLocal();
|
||||||
|
return dt2;
|
||||||
|
}
|
||||||
|
TimeSpan operator-(const DateTime& dt, const DateTime& dt2)
|
||||||
|
{
|
||||||
|
return (int64_t)dt - (int64_t)dt2;
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
33
include/TessesFramework/Filesystem/FSHelpers.hpp
Normal file
33
include/TessesFramework/Filesystem/FSHelpers.hpp
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "TempFS.hpp"
|
||||||
|
#include "VFSFix.hpp"
|
||||||
|
|
||||||
|
namespace Tesses::Framework::Filesystem::Helpers
|
||||||
|
{
|
||||||
|
void ReadAllText(std::shared_ptr<VFS> vfs, VFSPath path, std::string& text);
|
||||||
|
void ReadAllLines(std::shared_ptr<VFS> vfs, VFSPath path, std::vector<std::string>& lines);
|
||||||
|
void ReadAllBytes(std::shared_ptr<VFS> vfs, VFSPath path, std::vector<uint8_t>& array);
|
||||||
|
std::string ReadAllText(std::shared_ptr<VFS> vfs, VFSPath path);
|
||||||
|
std::vector<std::string> ReadAllLines(std::shared_ptr<VFS> vfs, VFSPath path);
|
||||||
|
std::vector<uint8_t> ReadAllBytes(std::shared_ptr<VFS> vfs, VFSPath path);
|
||||||
|
void WriteAllText(std::shared_ptr<VFS> vfs, VFSPath path, const std::string& text);
|
||||||
|
void WriteAllLines(std::shared_ptr<VFS> vfs, VFSPath path, const std::vector<std::string>& parts);
|
||||||
|
void WriteAllBytes(std::shared_ptr<VFS> vfs, VFSPath path, const std::vector<uint8_t>& bytes);
|
||||||
|
|
||||||
|
void CopyStreamProgress(std::shared_ptr<Streams::Stream> src,std::shared_ptr<Streams::Stream> dest, std::function<void(int64_t offset, int64_t length)> progress);
|
||||||
|
|
||||||
|
void CopyFile(std::shared_ptr<VFS> vfsSrc, VFSPath pathSrc, std::shared_ptr<VFS> vfsDest, VFSPath pathDest, bool overwrite=true);
|
||||||
|
void CopyFile(std::shared_ptr<VFS> vfsSrc, VFSPath pathSrc, std::shared_ptr<VFS> vfsDest, VFSPath pathDest, std::function<void(int64_t offset, int64_t length)> progress, bool overwrite=true);
|
||||||
|
void CopyDirectory(std::shared_ptr<VFS> vfsSrc, VFSPath pathSrc, std::shared_ptr<VFS> vfsDest, VFSPath pathDest, bool overwrite=true);
|
||||||
|
void CopyDirectory(std::shared_ptr<VFS> vfsSrc, VFSPath pathSrc, std::shared_ptr<VFS> vfsDest, VFSPath pathDest, std::function<void(int64_t offset, int64_t length, VFSPath currentFile)> progress, bool overwrite=true);
|
||||||
|
|
||||||
|
inline std::shared_ptr<TempFS> CreateTempFS(bool deleteOnDestroy=true)
|
||||||
|
{
|
||||||
|
return std::make_shared<TempFS>(deleteOnDestroy);
|
||||||
|
}
|
||||||
|
inline std::shared_ptr<TempFS> CreateTempFS(std::shared_ptr<VFS> vfs,bool deleteOnDestroy=true)
|
||||||
|
{
|
||||||
|
return std::make_shared<TempFS>(vfs,deleteOnDestroy);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
51
include/TessesFramework/Filesystem/TempFS.hpp
Normal file
51
include/TessesFramework/Filesystem/TempFS.hpp
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "../Common.hpp"
|
||||||
|
#include "VFS.hpp"
|
||||||
|
#include "VFSFix.hpp"
|
||||||
|
namespace Tesses::Framework::Filesystem
|
||||||
|
{
|
||||||
|
void UniqueString(std::string& text);
|
||||||
|
|
||||||
|
class TempFS : public VFS
|
||||||
|
{
|
||||||
|
std::shared_ptr<VFS> vfs;
|
||||||
|
bool deleteOnDestroy;
|
||||||
|
std::shared_ptr<VFS> parent;
|
||||||
|
std::string tmp_str;
|
||||||
|
public:
|
||||||
|
std::string TempDirectoryName();
|
||||||
|
TempFS(bool deleteOnDestroy=true);
|
||||||
|
TempFS(std::shared_ptr<VFS> vfs,bool deleteOnDestroy=true);
|
||||||
|
|
||||||
|
std::shared_ptr<Tesses::Framework::Streams::Stream> OpenFile(VFSPath path, std::string mode);
|
||||||
|
void CreateDirectory(VFSPath path);
|
||||||
|
void DeleteDirectory(VFSPath path);
|
||||||
|
bool SpecialFileExists(VFSPath path);
|
||||||
|
bool FileExists(VFSPath path);
|
||||||
|
bool RegularFileExists(VFSPath path);
|
||||||
|
bool SymlinkExists(VFSPath path);
|
||||||
|
bool CharacterDeviceExists(VFSPath path);
|
||||||
|
bool BlockDeviceExists(VFSPath path);
|
||||||
|
bool SocketFileExists(VFSPath path);
|
||||||
|
bool FIFOFileExists(VFSPath path);
|
||||||
|
bool DirectoryExists(VFSPath path);
|
||||||
|
void DeleteFile(VFSPath path);
|
||||||
|
void CreateSymlink(VFSPath existingFile, VFSPath symlinkFile);
|
||||||
|
VFSPathEnumerator EnumeratePaths(VFSPath path);
|
||||||
|
void CreateHardlink(VFSPath existingFile, VFSPath newName);
|
||||||
|
void MoveFile(VFSPath src, VFSPath dest);
|
||||||
|
void MoveDirectory(VFSPath src, VFSPath dest);
|
||||||
|
void DeleteDirectoryRecurse(VFSPath path);
|
||||||
|
VFSPath ReadLink(VFSPath path);
|
||||||
|
std::string VFSPathToSystem(VFSPath path);
|
||||||
|
VFSPath SystemToVFSPath(std::string path);
|
||||||
|
|
||||||
|
void GetDate(VFSPath path, Date::DateTime& lastWrite, Date::DateTime& lastAccess);
|
||||||
|
void SetDate(VFSPath path, Date::DateTime lastWrite, Date::DateTime lastAccess);
|
||||||
|
bool StatVFS(VFSPath path, StatVFSData& vfsData);
|
||||||
|
|
||||||
|
void Chmod(VFSPath path, uint32_t mode);
|
||||||
|
void Close();
|
||||||
|
~TempFS();
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -29,6 +29,8 @@ namespace Tesses::Framework::Filesystem
|
|||||||
static std::vector<std::string> SplitPath(std::string path);
|
static std::vector<std::string> SplitPath(std::string path);
|
||||||
std::vector<std::string> path;
|
std::vector<std::string> path;
|
||||||
VFSPath();
|
VFSPath();
|
||||||
|
VFSPath(const char* path) : VFSPath((std::string)path)
|
||||||
|
{}
|
||||||
VFSPath(std::vector<std::string> path);
|
VFSPath(std::vector<std::string> path);
|
||||||
VFSPath(std::string path);
|
VFSPath(std::string path);
|
||||||
VFSPath(VFSPath p, std::string subent);
|
VFSPath(VFSPath p, std::string subent);
|
||||||
@@ -36,22 +38,27 @@ namespace Tesses::Framework::Filesystem
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
VFSPath GetParent();
|
VFSPath GetParent() const;
|
||||||
VFSPath CollapseRelativeParents();
|
VFSPath CollapseRelativeParents() const;
|
||||||
std::string GetFileName();
|
std::string GetFileName() const;
|
||||||
bool HasExtension();
|
bool HasExtension() const;
|
||||||
std::string GetExtension();
|
std::string GetExtension() const;
|
||||||
void ChangeExtension(std::string ext);
|
void ChangeExtension(std::string ext);
|
||||||
void RemoveExtension();
|
void RemoveExtension();
|
||||||
std::string ToString();
|
std::string ToString() const;
|
||||||
|
|
||||||
|
operator std::string() const
|
||||||
|
{
|
||||||
|
return ToString();
|
||||||
|
}
|
||||||
|
|
||||||
static VFSPath GetAbsoluteCurrentDirectory();
|
static VFSPath GetAbsoluteCurrentDirectory();
|
||||||
static void SetAbsoluteCurrentDirectory(VFSPath path);
|
static void SetAbsoluteCurrentDirectory(VFSPath path);
|
||||||
VFSPath MakeAbsolute();
|
VFSPath MakeAbsolute() const;
|
||||||
|
|
||||||
VFSPath MakeAbsolute(VFSPath curDir);
|
VFSPath MakeAbsolute(VFSPath curDir) const;
|
||||||
VFSPath MakeRelative();
|
VFSPath MakeRelative() const;
|
||||||
VFSPath MakeRelative(VFSPath toMakeRelativeTo);
|
VFSPath MakeRelative(VFSPath toMakeRelativeTo) const;
|
||||||
};
|
};
|
||||||
VFSPath operator/(VFSPath p, VFSPath p2);
|
VFSPath operator/(VFSPath p, VFSPath p2);
|
||||||
VFSPath operator/(VFSPath p, std::string p2);
|
VFSPath operator/(VFSPath p, std::string p2);
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ namespace Tesses::Framework::Platform::Environment
|
|||||||
|
|
||||||
|
|
||||||
namespace SpecialFolders {
|
namespace SpecialFolders {
|
||||||
|
Tesses::Framework::Filesystem::VFSPath GetTemp();
|
||||||
Tesses::Framework::Filesystem::VFSPath GetHomeFolder();
|
Tesses::Framework::Filesystem::VFSPath GetHomeFolder();
|
||||||
Tesses::Framework::Filesystem::VFSPath GetDownloads();
|
Tesses::Framework::Filesystem::VFSPath GetDownloads();
|
||||||
Tesses::Framework::Filesystem::VFSPath GetMusic();
|
Tesses::Framework::Filesystem::VFSPath GetMusic();
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
#include "Filesystem/NullFilesystem.hpp"
|
#include "Filesystem/NullFilesystem.hpp"
|
||||||
#include "Filesystem/MountableFilesystem.hpp"
|
#include "Filesystem/MountableFilesystem.hpp"
|
||||||
#include "Filesystem/MemoryFilesystem.hpp"
|
#include "Filesystem/MemoryFilesystem.hpp"
|
||||||
|
#include "Filesystem/FSHelpers.hpp"
|
||||||
#include "Crypto/ClientTLSStream.hpp"
|
#include "Crypto/ClientTLSStream.hpp"
|
||||||
#include "Crypto/MbedHelpers.hpp"
|
#include "Crypto/MbedHelpers.hpp"
|
||||||
#include "Lazy.hpp"
|
#include "Lazy.hpp"
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ namespace Tesses::Framework::TextStreams
|
|||||||
int32_t ReadChar();
|
int32_t ReadChar();
|
||||||
std::string ReadLine();
|
std::string ReadLine();
|
||||||
bool ReadLine(std::string& str);
|
bool ReadLine(std::string& str);
|
||||||
|
void ReadAllLines(std::vector<std::string>& lines);
|
||||||
std::string ReadToEnd();
|
std::string ReadToEnd();
|
||||||
void ReadToEnd(std::string& str);
|
void ReadToEnd(std::string& str);
|
||||||
void CopyTo(TextWriter& writer, size_t bufSz=1024);
|
void CopyTo(TextWriter& writer, size_t bufSz=1024);
|
||||||
|
|||||||
21
pkgconfig/CMakeLists.txt
Normal file
21
pkgconfig/CMakeLists.txt
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
set(PKGCONFIG_INCLUDEDIR "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}")
|
||||||
|
set(PKGCONFIG_LIBDIR "\${prefix}/${CMAKE_INSTALL_LIBDIR}")
|
||||||
|
|
||||||
|
set(PKGCONFIG_PROJECT_DESCRIPTION "A cross platform wrapper library")
|
||||||
|
set(PKGCONFIG_PROJECT_HOMEPAGE_URL "https://onedev.site.tesses.net/tesses-framework")
|
||||||
|
|
||||||
|
if(TESSESFRAMEWORK_ENABLE_MBED)
|
||||||
|
set(PKGCONFIG_DEPS "Requires: mbedtls")
|
||||||
|
else()
|
||||||
|
set(PKGCONFIG_DEPS "")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
configure_file(tessesframework_static.pc.in tessesframework_static.pc @ONLY)
|
||||||
|
install(FILES
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/tessesframework_static.pc
|
||||||
|
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
|
||||||
|
|
||||||
|
configure_file(tessesframework.pc.in tessesframework.pc @ONLY)
|
||||||
|
install(FILES
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/tessesframework.pc
|
||||||
|
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
|
||||||
13
pkgconfig/tessesframework.pc.in
Normal file
13
pkgconfig/tessesframework.pc.in
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
prefix=@CMAKE_INSTALL_PREFIX@
|
||||||
|
includedir=@PKGCONFIG_INCLUDEDIR@
|
||||||
|
libdir=@PKGCONFIG_LIBDIR@
|
||||||
|
|
||||||
|
Name: @PROJECT_NAME@
|
||||||
|
Description: @PKGCONFIG_PROJECT_DESCRIPTION@
|
||||||
|
URL: @PKGCONFIG_PROJECT_HOMEPAGE_URL@
|
||||||
|
Version: @PROJECT_VERSION@
|
||||||
|
|
||||||
|
@PKGCONFIG_DEPS@
|
||||||
|
|
||||||
|
Cflags: -I"${includedir}"
|
||||||
|
Libs: -L"${libdir}" -ltessesframework_shared
|
||||||
13
pkgconfig/tessesframework_static.pc.in
Normal file
13
pkgconfig/tessesframework_static.pc.in
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
prefix=@CMAKE_INSTALL_PREFIX@
|
||||||
|
includedir=@PKGCONFIG_INCLUDEDIR@
|
||||||
|
libdir=@PKGCONFIG_LIBDIR@
|
||||||
|
|
||||||
|
Name: @PROJECT_NAME@
|
||||||
|
Description: @PKGCONFIG_PROJECT_DESCRIPTION@
|
||||||
|
URL: @PKGCONFIG_PROJECT_HOMEPAGE_URL@
|
||||||
|
Version: @PROJECT_VERSION@
|
||||||
|
|
||||||
|
@PKGCONFIG_DEPS@
|
||||||
|
|
||||||
|
Cflags: -I"${includedir}"
|
||||||
|
Libs: -L"${libdir}" -ltessesframework
|
||||||
@@ -105,35 +105,35 @@ namespace Tesses::Framework::Date
|
|||||||
this->second = seconds;
|
this->second = seconds;
|
||||||
this->isLocal = isLocal;
|
this->isLocal = isLocal;
|
||||||
}
|
}
|
||||||
int DateTime::Year()
|
int DateTime::Year() const
|
||||||
{
|
{
|
||||||
return this->year;
|
return this->year;
|
||||||
}
|
}
|
||||||
int DateTime::Month()
|
int DateTime::Month() const
|
||||||
{
|
{
|
||||||
return this->month;
|
return this->month;
|
||||||
}
|
}
|
||||||
int DateTime::Day()
|
int DateTime::Day() const
|
||||||
{
|
{
|
||||||
return this->day;
|
return this->day;
|
||||||
}
|
}
|
||||||
int DateTime::Hour()
|
int DateTime::Hour() const
|
||||||
{
|
{
|
||||||
return this->hour;
|
return this->hour;
|
||||||
}
|
}
|
||||||
int DateTime::Minute()
|
int DateTime::Minute() const
|
||||||
{
|
{
|
||||||
return this->minute;
|
return this->minute;
|
||||||
}
|
}
|
||||||
int DateTime::Second()
|
int DateTime::Second() const
|
||||||
{
|
{
|
||||||
return this->second;
|
return this->second;
|
||||||
}
|
}
|
||||||
bool DateTime::IsLocal()
|
bool DateTime::IsLocal() const
|
||||||
{
|
{
|
||||||
return this->isLocal;
|
return this->isLocal;
|
||||||
}
|
}
|
||||||
int DateTime::DayOfWeek()
|
int DateTime::DayOfWeek() const
|
||||||
{
|
{
|
||||||
date::year_month_day ymd(date::year(year),date::month((uint32_t)month),date::day((uint32_t)day));
|
date::year_month_day ymd(date::year(year),date::month((uint32_t)month),date::day((uint32_t)day));
|
||||||
date::sys_days d = ymd;
|
date::sys_days d = ymd;
|
||||||
@@ -214,7 +214,7 @@ namespace Tesses::Framework::Date
|
|||||||
this->isLocal=true;
|
this->isLocal=true;
|
||||||
this->FromEpochNoConvert(local);
|
this->FromEpochNoConvert(local);
|
||||||
}
|
}
|
||||||
DateTime DateTime::ToLocal()
|
DateTime DateTime::ToLocal() const
|
||||||
{
|
{
|
||||||
DateTime dt = *this;
|
DateTime dt = *this;
|
||||||
dt.SetToLocal();
|
dt.SetToLocal();
|
||||||
@@ -294,13 +294,13 @@ namespace Tesses::Framework::Date
|
|||||||
this->FromEpochNoConvert(local);
|
this->FromEpochNoConvert(local);
|
||||||
|
|
||||||
}
|
}
|
||||||
DateTime DateTime::ToUTC()
|
DateTime DateTime::ToUTC() const
|
||||||
{
|
{
|
||||||
DateTime dt = *this;
|
DateTime dt = *this;
|
||||||
dt.SetToUTC();
|
dt.SetToUTC();
|
||||||
return dt;
|
return dt;
|
||||||
}
|
}
|
||||||
int64_t DateTime::ToEpoch()
|
int64_t DateTime::ToEpoch() const
|
||||||
{
|
{
|
||||||
if(this->isLocal)
|
if(this->isLocal)
|
||||||
{
|
{
|
||||||
@@ -309,7 +309,7 @@ namespace Tesses::Framework::Date
|
|||||||
}
|
}
|
||||||
return this->ToEpochNoConvert();
|
return this->ToEpochNoConvert();
|
||||||
}
|
}
|
||||||
int64_t DateTime::ToEpochNoConvert()
|
int64_t DateTime::ToEpochNoConvert() const
|
||||||
{
|
{
|
||||||
date::year y = (date::year)year;
|
date::year y = (date::year)year;
|
||||||
date::month m = (date::month)month;
|
date::month m = (date::month)month;
|
||||||
@@ -551,7 +551,7 @@ namespace Tesses::Framework::Date
|
|||||||
dt.second = second;
|
dt.second = second;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
std::string DateTime::ToHttpDate()
|
std::string DateTime::ToHttpDate() const
|
||||||
{
|
{
|
||||||
auto utc=this->ToUTC();
|
auto utc=this->ToUTC();
|
||||||
std::string weekday=weekday_short[utc.DayOfWeek()];
|
std::string weekday=weekday_short[utc.DayOfWeek()];
|
||||||
@@ -567,12 +567,12 @@ namespace Tesses::Framework::Date
|
|||||||
return strm.str();
|
return strm.str();
|
||||||
|
|
||||||
}
|
}
|
||||||
std::string DateTime::ToString()
|
std::string DateTime::ToString() const
|
||||||
{
|
{
|
||||||
return ToString("%Y/%m/%d %H:%M:%S");
|
return ToString("%Y/%m/%d %H:%M:%S");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string DateTime::ToString(std::string fmt)
|
std::string DateTime::ToString(std::string fmt) const
|
||||||
{
|
{
|
||||||
auto weekday = this->DayOfWeek();
|
auto weekday = this->DayOfWeek();
|
||||||
|
|
||||||
@@ -732,4 +732,211 @@ namespace Tesses::Framework::Date
|
|||||||
}
|
}
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
TimeSpan::TimeSpan()
|
||||||
|
{
|
||||||
|
this->totalSeconds = 0;
|
||||||
|
}
|
||||||
|
TimeSpan::TimeSpan(int64_t totalSeconds)
|
||||||
|
{
|
||||||
|
this->totalSeconds = totalSeconds;
|
||||||
|
|
||||||
|
}
|
||||||
|
TimeSpan::TimeSpan(int hours, int minutes, int seconds) : TimeSpan(0,hours,minutes,seconds)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
TimeSpan::TimeSpan(int days,int hours, int minutes, int seconds)
|
||||||
|
{
|
||||||
|
this->totalSeconds = (int64_t)days * 86400;
|
||||||
|
this->totalSeconds += (int64_t)hours * 3600;
|
||||||
|
this->totalSeconds += (int64_t)minutes * 60;
|
||||||
|
this->totalSeconds += (int64_t)seconds;
|
||||||
|
}
|
||||||
|
void TimeSpan::Set(int days, int hours, int minutes, int seconds)
|
||||||
|
{
|
||||||
|
this->totalSeconds = (int64_t)days * 86400;
|
||||||
|
this->totalSeconds += (int64_t)hours * 3600;
|
||||||
|
this->totalSeconds += (int64_t)minutes * 60;
|
||||||
|
this->totalSeconds += (int64_t)seconds;
|
||||||
|
}
|
||||||
|
void TimeSpan::Set(int hours, int minutes, int seconds)
|
||||||
|
{
|
||||||
|
this->totalSeconds = (int64_t)hours * 3600;
|
||||||
|
this->totalSeconds += (int64_t)minutes * 60;
|
||||||
|
this->totalSeconds += (int64_t)seconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimeSpan::SetDays(int d)
|
||||||
|
{
|
||||||
|
Set(d,this->Hours(),this->Minutes(),this->Seconds());
|
||||||
|
}
|
||||||
|
void TimeSpan::SetHours(int h)
|
||||||
|
{
|
||||||
|
Set(this->Days(),h,this->Minutes(), this->Seconds());
|
||||||
|
}
|
||||||
|
void TimeSpan::SetMinutes(int m)
|
||||||
|
{
|
||||||
|
Set(this->Days(),this->Hours(),m,this->Seconds());
|
||||||
|
}
|
||||||
|
void TimeSpan::SetSeconds(int s)
|
||||||
|
{
|
||||||
|
Set(this->Days(),this->Hours(),this->Minutes(),s);
|
||||||
|
}
|
||||||
|
|
||||||
|
int TimeSpan::Days() const
|
||||||
|
{
|
||||||
|
|
||||||
|
return (int)(this->totalSeconds / 86400);
|
||||||
|
}
|
||||||
|
int TimeSpan::Hours() const
|
||||||
|
{
|
||||||
|
|
||||||
|
return (int)((this->totalSeconds / 3600) % 24);
|
||||||
|
}
|
||||||
|
int TimeSpan::Minutes() const
|
||||||
|
{
|
||||||
|
return (int)((this->totalSeconds / 60) % 60);
|
||||||
|
}
|
||||||
|
int TimeSpan::Seconds() const
|
||||||
|
{
|
||||||
|
return (int)(this->totalSeconds % 60);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int64_t TimeSpan::TotalSeconds() const
|
||||||
|
{
|
||||||
|
return this->totalSeconds;
|
||||||
|
}
|
||||||
|
int64_t TimeSpan::TotalMinutes() const
|
||||||
|
{
|
||||||
|
return this->totalSeconds / 60;
|
||||||
|
}
|
||||||
|
int64_t TimeSpan::TotalHours() const
|
||||||
|
{
|
||||||
|
return this->totalSeconds / 3600;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimeSpan::AddSeconds(int64_t seconds)
|
||||||
|
{
|
||||||
|
this->totalSeconds += seconds;
|
||||||
|
}
|
||||||
|
void TimeSpan::AddMinutes(int64_t minutes)
|
||||||
|
{
|
||||||
|
this->totalSeconds += minutes * 60;
|
||||||
|
}
|
||||||
|
void TimeSpan::AddHours(int64_t hours)
|
||||||
|
{
|
||||||
|
this->totalSeconds += hours * 3600;
|
||||||
|
}
|
||||||
|
void TimeSpan::AddDays(int64_t days)
|
||||||
|
{
|
||||||
|
this->totalSeconds += days * 86400;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimeSpan::SetTotalSeconds(int64_t totalSeconds)
|
||||||
|
{
|
||||||
|
this->totalSeconds = totalSeconds;
|
||||||
|
}
|
||||||
|
void TimeSpan::SetTotalMinutes(int64_t totalMinutes)
|
||||||
|
{
|
||||||
|
this->totalSeconds = totalMinutes * 60;
|
||||||
|
}
|
||||||
|
void TimeSpan::SetTotalHours(int64_t totalHours)
|
||||||
|
{
|
||||||
|
this->totalSeconds = totalHours * 3600;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string TimeSpan::ToString(bool slim) const
|
||||||
|
{
|
||||||
|
std::string str={};
|
||||||
|
if(this->totalSeconds < 0)
|
||||||
|
str += "-";
|
||||||
|
if(slim && this->totalSeconds > -36000 && this->totalSeconds < 36000)
|
||||||
|
{
|
||||||
|
//0:00
|
||||||
|
//00:00
|
||||||
|
//0:00:00
|
||||||
|
if(this->totalSeconds <= -3600 || this->totalSeconds >= 3600)
|
||||||
|
{
|
||||||
|
//hours must force multi digit minutes
|
||||||
|
str += std::to_string(this->Hours());
|
||||||
|
str += ":";
|
||||||
|
str += Http::HttpUtils::LeftPad(std::to_string(this->Minutes()),2,' ');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
str += std::to_string(this->Minutes());
|
||||||
|
}
|
||||||
|
|
||||||
|
str += ":";
|
||||||
|
str += Http::HttpUtils::LeftPad(std::to_string(this->Seconds()),2,' ');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//00:00:00
|
||||||
|
//0.00:00:00
|
||||||
|
|
||||||
|
if(this->totalSeconds <= -86400 || this->totalSeconds >= 86400)
|
||||||
|
{
|
||||||
|
str += std::to_string(this->Days());
|
||||||
|
str += ".";
|
||||||
|
}
|
||||||
|
|
||||||
|
str += Http::HttpUtils::LeftPad(std::to_string(this->Hours()),2,' ');
|
||||||
|
str += ":";
|
||||||
|
str += Http::HttpUtils::LeftPad(std::to_string(this->Minutes()),2,' ');
|
||||||
|
str += ":";
|
||||||
|
str += Http::HttpUtils::LeftPad(std::to_string(this->Seconds()),2,' ');
|
||||||
|
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TimeSpan::TryParse(std::string text, TimeSpan& span)
|
||||||
|
{
|
||||||
|
if(text.empty()) return false;
|
||||||
|
bool negative = text[0] == '-';
|
||||||
|
int64_t totalSeconds = 0;
|
||||||
|
|
||||||
|
|
||||||
|
try{
|
||||||
|
|
||||||
|
|
||||||
|
std::string colonPart = text.substr(negative ? 1 : 0);
|
||||||
|
auto res = Http::HttpUtils::SplitString(colonPart,":");
|
||||||
|
|
||||||
|
if(res.size() < 2 || res.size() > 3) return false;
|
||||||
|
std::string hour = res[0];
|
||||||
|
size_t index=hour.find('.');
|
||||||
|
if(index != std::string::npos)
|
||||||
|
{
|
||||||
|
totalSeconds += std::stoll(hour.substr(0,index)) * 86400;
|
||||||
|
hour = hour.substr(index+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(res.size() == 2)
|
||||||
|
{
|
||||||
|
//mm:ss
|
||||||
|
|
||||||
|
|
||||||
|
totalSeconds += std::stoll(hour) * 60;
|
||||||
|
totalSeconds += std::stoll(res[1]);
|
||||||
|
}
|
||||||
|
else if(res.size() == 3)
|
||||||
|
{
|
||||||
|
totalSeconds += std::stoll(hour) * 3600;
|
||||||
|
totalSeconds += std::stoll(res[1]) * 60;
|
||||||
|
totalSeconds += std::stoll(res[2]);
|
||||||
|
}
|
||||||
|
else return false;
|
||||||
|
|
||||||
|
}catch(...) {return false;}
|
||||||
|
|
||||||
|
if(negative) totalSeconds = -totalSeconds;
|
||||||
|
|
||||||
|
span.SetTotalSeconds(totalSeconds);
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
184
src/Filesystem/FSHelpers.cpp
Normal file
184
src/Filesystem/FSHelpers.cpp
Normal file
@@ -0,0 +1,184 @@
|
|||||||
|
#include "TessesFramework/Filesystem/FSHelpers.hpp"
|
||||||
|
#include "TessesFramework/TextStreams/StreamReader.hpp"
|
||||||
|
#include "TessesFramework/TextStreams/StreamWriter.hpp"
|
||||||
|
|
||||||
|
namespace Tesses::Framework::Filesystem::Helpers
|
||||||
|
{
|
||||||
|
void ReadAllText(std::shared_ptr<VFS> vfs, VFSPath path, std::string& text)
|
||||||
|
{
|
||||||
|
auto file = vfs->OpenFile(path,"rb");
|
||||||
|
if(file->CanRead())
|
||||||
|
{
|
||||||
|
TextStreams::StreamReader reader(file);
|
||||||
|
reader.ReadToEnd(text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void ReadAllLines(std::shared_ptr<VFS> vfs, VFSPath path, std::vector<std::string>& lines)
|
||||||
|
{
|
||||||
|
auto file = vfs->OpenFile(path,"rb");
|
||||||
|
if(file->CanRead())
|
||||||
|
{
|
||||||
|
TextStreams::StreamReader reader(file);
|
||||||
|
reader.ReadAllLines(lines);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void ReadAllBytes(std::shared_ptr<VFS> vfs, VFSPath path, std::vector<uint8_t>& array)
|
||||||
|
{
|
||||||
|
auto file = vfs->OpenFile(path,"rb");
|
||||||
|
if(file->CanRead())
|
||||||
|
{
|
||||||
|
if(file->CanSeek())
|
||||||
|
{
|
||||||
|
size_t length = (size_t)file->GetLength();
|
||||||
|
array.resize(length);
|
||||||
|
file->ReadBlock(array.data(), array.size());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
size_t totalSize = 0;
|
||||||
|
size_t read = 0;
|
||||||
|
do {
|
||||||
|
array.resize(totalSize+1024);
|
||||||
|
read = file->ReadBlock(array.data()+totalSize,1024);
|
||||||
|
totalSize += read;
|
||||||
|
} while(read != 0);
|
||||||
|
|
||||||
|
array.resize(totalSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::string ReadAllText(std::shared_ptr<VFS> vfs, VFSPath path)
|
||||||
|
{
|
||||||
|
std::string text;
|
||||||
|
ReadAllText(vfs,path,text);
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
std::vector<std::string> ReadAllLines(std::shared_ptr<VFS> vfs, VFSPath path)
|
||||||
|
{
|
||||||
|
std::vector<std::string> lines;
|
||||||
|
ReadAllLines(vfs,path,lines);
|
||||||
|
return lines;
|
||||||
|
}
|
||||||
|
std::vector<uint8_t> ReadAllBytes(std::shared_ptr<VFS> vfs, VFSPath path)
|
||||||
|
{
|
||||||
|
std::vector<uint8_t> bytes;
|
||||||
|
ReadAllBytes(vfs,path,bytes);
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
void WriteAllText(std::shared_ptr<VFS> vfs, VFSPath path, const std::string& text)
|
||||||
|
{
|
||||||
|
auto file = vfs->OpenFile(path,"wb");
|
||||||
|
if(file->CanWrite())
|
||||||
|
{
|
||||||
|
TextStreams::StreamWriter writer(file);
|
||||||
|
writer.Write(text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void WriteAllLines(std::shared_ptr<VFS> vfs, VFSPath path, const std::vector<std::string>& parts)
|
||||||
|
{
|
||||||
|
auto file = vfs->OpenFile(path,"wb");
|
||||||
|
if(file->CanWrite())
|
||||||
|
{
|
||||||
|
TextStreams::StreamWriter writer(file);
|
||||||
|
for(auto& line : parts)
|
||||||
|
{
|
||||||
|
writer.WriteLine(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void WriteAllBytes(std::shared_ptr<VFS> vfs, VFSPath path, const std::vector<uint8_t>& bytes)
|
||||||
|
{
|
||||||
|
auto file = vfs->OpenFile(path,"wb");
|
||||||
|
if(file->CanWrite())
|
||||||
|
{
|
||||||
|
file->WriteBlock(bytes.data(),bytes.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CopyFile(std::shared_ptr<VFS> vfsSrc, VFSPath pathSrc, std::shared_ptr<VFS> vfsDest, VFSPath pathDest, bool overwrite)
|
||||||
|
{
|
||||||
|
if(!overwrite && vfsDest->FileExists(pathDest)) return;
|
||||||
|
if(!vfsSrc->FileExists(pathSrc)) return;
|
||||||
|
auto src=vfsSrc->OpenFile(pathSrc,"wb");
|
||||||
|
auto dest = vfsDest->OpenFile(pathDest,"wb");
|
||||||
|
if(src->CanRead() && dest->CanWrite())
|
||||||
|
src->CopyTo(dest);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CopyStreamProgress(std::shared_ptr<Streams::Stream> src,std::shared_ptr<Streams::Stream> dest, std::function<void(int64_t offset, int64_t length)> progress)
|
||||||
|
{
|
||||||
|
int64_t length=0;
|
||||||
|
try {
|
||||||
|
length = src->GetLength();
|
||||||
|
} catch(...) {
|
||||||
|
length=0;
|
||||||
|
}
|
||||||
|
if(length == 0) length = (int64_t)1<<62; // a big number so its always 0% if the stream does not have a length
|
||||||
|
|
||||||
|
int64_t offset = 0;
|
||||||
|
size_t read = 0;
|
||||||
|
std::vector<uint8_t> data(4096);
|
||||||
|
|
||||||
|
|
||||||
|
do {
|
||||||
|
read = src->ReadBlock(data.data(),data.size());
|
||||||
|
dest->WriteBlock(data.data(),read);
|
||||||
|
offset += (int64_t)read;
|
||||||
|
if(read != 0)
|
||||||
|
progress(offset,length);
|
||||||
|
} while(read != 0);
|
||||||
|
|
||||||
|
if(offset > 0)
|
||||||
|
progress(offset,offset);
|
||||||
|
}
|
||||||
|
void CopyFile(std::shared_ptr<VFS> vfsSrc, VFSPath pathSrc, std::shared_ptr<VFS> vfsDest, VFSPath pathDest, std::function<void(int64_t offset, int64_t length)> progress, bool overwrite)
|
||||||
|
{
|
||||||
|
if(!overwrite && vfsDest->FileExists(pathDest)) return;
|
||||||
|
if(!vfsSrc->FileExists(pathSrc)) return;
|
||||||
|
auto src=vfsSrc->OpenFile(pathSrc,"wb");
|
||||||
|
auto dest = vfsDest->OpenFile(pathDest,"wb");
|
||||||
|
if(src->CanRead() && dest->CanWrite())
|
||||||
|
CopyStreamProgress(src,dest,progress);
|
||||||
|
}
|
||||||
|
void CopyDirectory(std::shared_ptr<VFS> vfsSrc, VFSPath pathSrc, std::shared_ptr<VFS> vfsDest, VFSPath pathDest,bool overwrite)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
if(vfsSrc->DirectoryExists(pathSrc))
|
||||||
|
{
|
||||||
|
vfsDest->CreateDirectory(pathDest);
|
||||||
|
for(auto& srcPath : vfsSrc->EnumeratePaths(pathSrc))
|
||||||
|
{
|
||||||
|
if(vfsSrc->DirectoryExists(srcPath))
|
||||||
|
{
|
||||||
|
CopyDirectory(vfsSrc,srcPath,vfsDest,pathDest / srcPath.GetFileName());
|
||||||
|
}
|
||||||
|
if(vfsSrc->FileExists(srcPath))
|
||||||
|
{
|
||||||
|
CopyFile(vfsSrc,srcPath,vfsDest,pathDest / srcPath.GetFileName(),overwrite);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void CopyDirectory(std::shared_ptr<VFS> vfsSrc, VFSPath pathSrc, std::shared_ptr<VFS> vfsDest, VFSPath pathDest, std::function<void(int64_t offset, int64_t length, VFSPath currentFile)> progress, bool overwrite)
|
||||||
|
{
|
||||||
|
if(vfsSrc->DirectoryExists(pathSrc))
|
||||||
|
{
|
||||||
|
vfsDest->CreateDirectory(pathDest);
|
||||||
|
for(auto& srcPath : vfsSrc->EnumeratePaths(pathSrc))
|
||||||
|
{
|
||||||
|
if(vfsSrc->DirectoryExists(srcPath))
|
||||||
|
{
|
||||||
|
CopyDirectory(vfsSrc,srcPath,vfsDest,pathDest / srcPath.GetFileName(),progress,overwrite);
|
||||||
|
}
|
||||||
|
if(vfsSrc->FileExists(srcPath))
|
||||||
|
{
|
||||||
|
CopyFile(vfsSrc,srcPath,vfsDest,pathDest / srcPath.GetFileName(),[progress,srcPath](int64_t offset, int64_t length)->void {
|
||||||
|
progress(offset,length,srcPath);
|
||||||
|
},overwrite);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
205
src/Filesystem/TempFS.cpp
Normal file
205
src/Filesystem/TempFS.cpp
Normal file
@@ -0,0 +1,205 @@
|
|||||||
|
#include "TessesFramework/Threading/Mutex.hpp"
|
||||||
|
#include "TessesFramework/Filesystem/TempFS.hpp"
|
||||||
|
#include "TessesFramework/Filesystem/LocalFS.hpp"
|
||||||
|
#include "TessesFramework/Filesystem/SubdirFilesystem.hpp"
|
||||||
|
#include "TessesFramework/Platform/Environment.hpp"
|
||||||
|
namespace Tesses::Framework::Filesystem {
|
||||||
|
Tesses::Framework::Threading::Mutex umtx;
|
||||||
|
int64_t uidx=0;
|
||||||
|
void UniqueString(std::string& text)
|
||||||
|
{
|
||||||
|
umtx.Lock();
|
||||||
|
text += std::to_string((int64_t)time(NULL));
|
||||||
|
text += "_";
|
||||||
|
text += std::to_string(uidx);
|
||||||
|
|
||||||
|
uidx++;
|
||||||
|
|
||||||
|
umtx.Unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
TempFS::TempFS(bool deleteOnDestroy) : TempFS(std::make_shared<SubdirFilesystem>(LocalFS, Platform::Environment::SpecialFolders::GetTemp()), deleteOnDestroy)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
TempFS::TempFS(std::shared_ptr<VFS> vfs,bool deleteOnDestroy)
|
||||||
|
{
|
||||||
|
this->parent = vfs;
|
||||||
|
this->deleteOnDestroy=deleteOnDestroy;
|
||||||
|
this->tmp_str = "tf_tmp_";
|
||||||
|
UniqueString(this->tmp_str);
|
||||||
|
VFSPath p;
|
||||||
|
p.relative = false;
|
||||||
|
p.path.push_back(this->tmp_str);
|
||||||
|
this->parent->CreateDirectory(p);
|
||||||
|
this->vfs = std::make_shared<SubdirFilesystem>(this->parent,p);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string TempFS::TempDirectoryName()
|
||||||
|
{
|
||||||
|
return this->tmp_str;
|
||||||
|
}
|
||||||
|
std::shared_ptr<Tesses::Framework::Streams::Stream> TempFS::OpenFile(VFSPath path, std::string mode)
|
||||||
|
{
|
||||||
|
if(this->vfs == nullptr) return nullptr;
|
||||||
|
return this->vfs->OpenFile(path,mode);
|
||||||
|
}
|
||||||
|
void TempFS::CreateDirectory(VFSPath path)
|
||||||
|
{
|
||||||
|
if(this->vfs == nullptr) return;
|
||||||
|
this->vfs->CreateDirectory(path);
|
||||||
|
}
|
||||||
|
void TempFS::DeleteDirectory(VFSPath path)
|
||||||
|
{
|
||||||
|
if(this->vfs == nullptr) return;
|
||||||
|
this->vfs->DeleteDirectory(path);
|
||||||
|
}
|
||||||
|
bool TempFS::SpecialFileExists(VFSPath path)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(this->vfs == nullptr) return false;
|
||||||
|
return this->vfs->SpecialFileExists(path);
|
||||||
|
}
|
||||||
|
bool TempFS::FileExists(VFSPath path)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(this->vfs == nullptr) return false;
|
||||||
|
return this->vfs->FileExists(path);
|
||||||
|
}
|
||||||
|
bool TempFS::RegularFileExists(VFSPath path)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(this->vfs == nullptr) return false;
|
||||||
|
return this->vfs->RegularFileExists(path);
|
||||||
|
}
|
||||||
|
bool TempFS::SymlinkExists(VFSPath path)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(this->vfs == nullptr) return false;
|
||||||
|
return this->vfs->SymlinkExists(path);
|
||||||
|
}
|
||||||
|
bool TempFS::CharacterDeviceExists(VFSPath path)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(this->vfs == nullptr) return false;
|
||||||
|
return this->vfs->CharacterDeviceExists(path);
|
||||||
|
}
|
||||||
|
bool TempFS::BlockDeviceExists(VFSPath path)
|
||||||
|
{
|
||||||
|
if(this->vfs == nullptr) return false;
|
||||||
|
return this->vfs->BlockDeviceExists(path);
|
||||||
|
}
|
||||||
|
bool TempFS::SocketFileExists(VFSPath path)
|
||||||
|
{
|
||||||
|
if(this->vfs == nullptr) return false;
|
||||||
|
return this->vfs->SocketFileExists(path);
|
||||||
|
}
|
||||||
|
bool TempFS::FIFOFileExists(VFSPath path)
|
||||||
|
{
|
||||||
|
if(this->vfs == nullptr) return false;
|
||||||
|
return this->vfs->FIFOFileExists(path);
|
||||||
|
}
|
||||||
|
bool TempFS::DirectoryExists(VFSPath path)
|
||||||
|
{
|
||||||
|
if(this->vfs == nullptr) return false;
|
||||||
|
return this->vfs->DirectoryExists(path);
|
||||||
|
}
|
||||||
|
void TempFS::DeleteFile(VFSPath path)
|
||||||
|
{
|
||||||
|
if(this->vfs == nullptr) return;
|
||||||
|
this->vfs->DeleteFile(path);
|
||||||
|
}
|
||||||
|
void TempFS::CreateSymlink(VFSPath existingFile, VFSPath symlinkFile)
|
||||||
|
{
|
||||||
|
if(this->vfs == nullptr) return;
|
||||||
|
this->vfs->CreateSymlink(existingFile, symlinkFile);
|
||||||
|
}
|
||||||
|
VFSPathEnumerator TempFS::EnumeratePaths(VFSPath path)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(this->vfs == nullptr) return VFSPathEnumerator();
|
||||||
|
|
||||||
|
return this->vfs->EnumeratePaths(path);
|
||||||
|
}
|
||||||
|
void TempFS::CreateHardlink(VFSPath existingFile, VFSPath newName)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(this->vfs == nullptr) return;
|
||||||
|
this->vfs->CreateHardlink(existingFile,newName);
|
||||||
|
}
|
||||||
|
void TempFS::MoveFile(VFSPath src, VFSPath dest)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(this->vfs == nullptr) return;
|
||||||
|
this->vfs->MoveFile(src,dest);
|
||||||
|
}
|
||||||
|
void TempFS::MoveDirectory(VFSPath src, VFSPath dest)
|
||||||
|
{
|
||||||
|
if(this->vfs == nullptr) return;
|
||||||
|
this->vfs->MoveDirectory(src,dest);
|
||||||
|
}
|
||||||
|
void TempFS::DeleteDirectoryRecurse(VFSPath path)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(this->vfs == nullptr) return;
|
||||||
|
this->vfs->DeleteDirectoryRecurse(path);
|
||||||
|
}
|
||||||
|
VFSPath TempFS::ReadLink(VFSPath path)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(this->vfs == nullptr) return VFSPath();
|
||||||
|
return this->vfs->ReadLink(path);
|
||||||
|
}
|
||||||
|
std::string TempFS::VFSPathToSystem(VFSPath path)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(this->vfs == nullptr) return "";
|
||||||
|
return this->vfs->VFSPathToSystem(path);
|
||||||
|
}
|
||||||
|
VFSPath TempFS::SystemToVFSPath(std::string path)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(this->vfs == nullptr) return VFSPath();
|
||||||
|
return this->vfs->SystemToVFSPath(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TempFS::GetDate(VFSPath path, Date::DateTime& lastWrite, Date::DateTime& lastAccess)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(this->vfs == nullptr) return;
|
||||||
|
this->vfs->GetDate(path,lastWrite,lastAccess);
|
||||||
|
}
|
||||||
|
void TempFS::SetDate(VFSPath path, Date::DateTime lastWrite, Date::DateTime lastAccess)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(this->vfs == nullptr) return;
|
||||||
|
this->vfs->SetDate(path,lastWrite,lastAccess);
|
||||||
|
}
|
||||||
|
bool TempFS::StatVFS(VFSPath path, StatVFSData& vfsData)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(this->vfs == nullptr) return false;
|
||||||
|
return this->vfs->StatVFS(path, vfsData);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TempFS::Chmod(VFSPath path, uint32_t mode)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(this->vfs == nullptr) return;
|
||||||
|
this->vfs->Chmod(path,mode);
|
||||||
|
}
|
||||||
|
void TempFS::Close()
|
||||||
|
{
|
||||||
|
|
||||||
|
VFSPath p;
|
||||||
|
p.relative = false;
|
||||||
|
p.path.push_back(this->tmp_str);
|
||||||
|
this->vfs = nullptr;
|
||||||
|
if(this->deleteOnDestroy && this->parent->DirectoryExists(p))
|
||||||
|
this->parent->DeleteDirectoryRecurse(p);
|
||||||
|
}
|
||||||
|
TempFS::~TempFS()
|
||||||
|
{
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -202,21 +202,21 @@ namespace Tesses::Framework::Filesystem
|
|||||||
std::filesystem::path mpath=res;
|
std::filesystem::path mpath=res;
|
||||||
std::filesystem::current_path(mpath);
|
std::filesystem::current_path(mpath);
|
||||||
}
|
}
|
||||||
VFSPath VFSPath::MakeAbsolute()
|
VFSPath VFSPath::MakeAbsolute() const
|
||||||
{
|
{
|
||||||
return MakeAbsolute(GetAbsoluteCurrentDirectory());
|
return MakeAbsolute(GetAbsoluteCurrentDirectory());
|
||||||
}
|
}
|
||||||
VFSPath VFSPath::MakeAbsolute(VFSPath curDir)
|
VFSPath VFSPath::MakeAbsolute(VFSPath curDir) const
|
||||||
{
|
{
|
||||||
if (!this->relative) return *this;
|
if (!this->relative) return *this;
|
||||||
VFSPath p2 = curDir / *this;
|
VFSPath p2 = curDir / *this;
|
||||||
return p2.CollapseRelativeParents();
|
return p2.CollapseRelativeParents();
|
||||||
}
|
}
|
||||||
VFSPath VFSPath::MakeRelative()
|
VFSPath VFSPath::MakeRelative() const
|
||||||
{
|
{
|
||||||
return MakeRelative(GetAbsoluteCurrentDirectory());
|
return MakeRelative(GetAbsoluteCurrentDirectory());
|
||||||
}
|
}
|
||||||
VFSPath VFSPath::MakeRelative(VFSPath toMakeRelativeTo)
|
VFSPath VFSPath::MakeRelative(VFSPath toMakeRelativeTo) const
|
||||||
{
|
{
|
||||||
|
|
||||||
if(this->relative) return *this;
|
if(this->relative) return *this;
|
||||||
@@ -250,7 +250,7 @@ namespace Tesses::Framework::Filesystem
|
|||||||
p2.relative = true;
|
p2.relative = true;
|
||||||
return p2;
|
return p2;
|
||||||
}
|
}
|
||||||
VFSPath VFSPath::CollapseRelativeParents()
|
VFSPath VFSPath::CollapseRelativeParents() const
|
||||||
{
|
{
|
||||||
std::vector<std::string> parts;
|
std::vector<std::string> parts;
|
||||||
|
|
||||||
@@ -330,7 +330,7 @@ namespace Tesses::Framework::Filesystem
|
|||||||
this->path = p;
|
this->path = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VFSPath::HasExtension()
|
bool VFSPath::HasExtension() const
|
||||||
{
|
{
|
||||||
if(this->path.empty()) return false;
|
if(this->path.empty()) return false;
|
||||||
auto& str = this->path.back();
|
auto& str = this->path.back();
|
||||||
@@ -338,7 +338,7 @@ namespace Tesses::Framework::Filesystem
|
|||||||
if(index == std::string::npos) return false;
|
if(index == std::string::npos) return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
std::string VFSPath::GetExtension()
|
std::string VFSPath::GetExtension() const
|
||||||
{
|
{
|
||||||
if(this->path.empty()) return {};
|
if(this->path.empty()) return {};
|
||||||
auto& str = this->path.back();
|
auto& str = this->path.back();
|
||||||
@@ -395,7 +395,7 @@ namespace Tesses::Framework::Filesystem
|
|||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
VFSPath VFSPath::GetParent()
|
VFSPath VFSPath::GetParent() const
|
||||||
{
|
{
|
||||||
std::vector<std::string> paths;
|
std::vector<std::string> paths;
|
||||||
if(this->path.empty()) return VFSPath();
|
if(this->path.empty()) return VFSPath();
|
||||||
@@ -407,13 +407,13 @@ namespace Tesses::Framework::Filesystem
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string VFSPath::GetFileName()
|
std::string VFSPath::GetFileName() const
|
||||||
{
|
{
|
||||||
if(this->path.empty()) return "";
|
if(this->path.empty()) return "";
|
||||||
return this->path.back();
|
return this->path.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string VFSPath::ToString()
|
std::string VFSPath::ToString() const
|
||||||
{
|
{
|
||||||
if(this->path.empty() && !this->relative) return "/";
|
if(this->path.empty() && !this->relative) return "/";
|
||||||
if(!this->relative && this->path.size() == 1 && !this->path[0].empty() && this->path[0].back() == ':') return this->path[0] + "/";
|
if(!this->relative && this->path.size() == 1 && !this->path[0].empty() && this->path[0].back() == ':') return this->path[0] + "/";
|
||||||
|
|||||||
@@ -25,13 +25,18 @@ namespace Tesses::Framework::Platform::Environment
|
|||||||
|
|
||||||
namespace SpecialFolders
|
namespace SpecialFolders
|
||||||
{
|
{
|
||||||
|
VFSPath GetTemp()
|
||||||
|
{
|
||||||
|
return std::filesystem::temp_directory_path().string();
|
||||||
|
}
|
||||||
VFSPath GetHomeFolder()
|
VFSPath GetHomeFolder()
|
||||||
{
|
{
|
||||||
#if defined(TESSESFRAMEWORK_ENABLE_PLATFORMFOLDERS) && !defined(SAGO_DISABLE)
|
#if defined(TESSESFRAMEWORK_ENABLE_PLATFORMFOLDERS) && !defined(SAGO_DISABLE)
|
||||||
return sago::getHomeDir();
|
return sago::getHomeDir();
|
||||||
#elif defined(__EMSCRIPTEN__)
|
#elif defined(__EMSCRIPTEN__)
|
||||||
return (std::string)"/home/web_user";
|
return (std::string)"/home/web_user";
|
||||||
|
#elif defined(__ANDROID__)
|
||||||
|
return (std::string)"/sdcard/TF_User";
|
||||||
#else
|
#else
|
||||||
return (std::string)"/TF_User";
|
return (std::string)"/TF_User";
|
||||||
#endif
|
#endif
|
||||||
@@ -40,6 +45,8 @@ namespace Tesses::Framework::Platform::Environment
|
|||||||
{
|
{
|
||||||
#if defined(TESSESFRAMEWORK_ENABLE_PLATFORMFOLDERS) && !defined(SAGO_DISABLE)
|
#if defined(TESSESFRAMEWORK_ENABLE_PLATFORMFOLDERS) && !defined(SAGO_DISABLE)
|
||||||
return sago::getDownloadFolder();
|
return sago::getDownloadFolder();
|
||||||
|
#elif defined(__ANDROID__)
|
||||||
|
return (std::string)"/sdcard/Download";
|
||||||
#else
|
#else
|
||||||
return GetHomeFolder() / "Downloads";
|
return GetHomeFolder() / "Downloads";
|
||||||
#endif
|
#endif
|
||||||
@@ -48,6 +55,8 @@ namespace Tesses::Framework::Platform::Environment
|
|||||||
{
|
{
|
||||||
#if defined(TESSESFRAMEWORK_ENABLE_PLATFORMFOLDERS) && !defined(SAGO_DISABLE)
|
#if defined(TESSESFRAMEWORK_ENABLE_PLATFORMFOLDERS) && !defined(SAGO_DISABLE)
|
||||||
return sago::getMusicFolder();
|
return sago::getMusicFolder();
|
||||||
|
#elif defined(__ANDROID__)
|
||||||
|
return (std::string)"/sdcard/Music";
|
||||||
#else
|
#else
|
||||||
return GetHomeFolder() / "Music";
|
return GetHomeFolder() / "Music";
|
||||||
#endif
|
#endif
|
||||||
@@ -56,6 +65,8 @@ namespace Tesses::Framework::Platform::Environment
|
|||||||
{
|
{
|
||||||
#if defined(TESSESFRAMEWORK_ENABLE_PLATFORMFOLDERS) && !defined(SAGO_DISABLE)
|
#if defined(TESSESFRAMEWORK_ENABLE_PLATFORMFOLDERS) && !defined(SAGO_DISABLE)
|
||||||
return sago::getPicturesFolder();
|
return sago::getPicturesFolder();
|
||||||
|
#elif defined(__ANDROID__)
|
||||||
|
return (std::string)"/sdcard/Pictures";
|
||||||
#else
|
#else
|
||||||
return GetHomeFolder() / "Pictures";
|
return GetHomeFolder() / "Pictures";
|
||||||
#endif
|
#endif
|
||||||
@@ -64,6 +75,8 @@ namespace Tesses::Framework::Platform::Environment
|
|||||||
{
|
{
|
||||||
#if defined(TESSESFRAMEWORK_ENABLE_PLATFORMFOLDERS) && !defined(SAGO_DISABLE)
|
#if defined(TESSESFRAMEWORK_ENABLE_PLATFORMFOLDERS) && !defined(SAGO_DISABLE)
|
||||||
return sago::getVideoFolder();
|
return sago::getVideoFolder();
|
||||||
|
#elif defined(__ANDROID__)
|
||||||
|
return (std::string)"/sdcard/Movies";
|
||||||
#else
|
#else
|
||||||
return GetHomeFolder() / "Videos";
|
return GetHomeFolder() / "Videos";
|
||||||
#endif
|
#endif
|
||||||
@@ -72,6 +85,8 @@ namespace Tesses::Framework::Platform::Environment
|
|||||||
{
|
{
|
||||||
#if defined(TESSESFRAMEWORK_ENABLE_PLATFORMFOLDERS) && !defined(SAGO_DISABLE)
|
#if defined(TESSESFRAMEWORK_ENABLE_PLATFORMFOLDERS) && !defined(SAGO_DISABLE)
|
||||||
return sago::getDocumentsFolder();
|
return sago::getDocumentsFolder();
|
||||||
|
#elif defined(__ANDROID__)
|
||||||
|
return (std::string)"/sdcard/Documents";
|
||||||
#else
|
#else
|
||||||
return GetHomeFolder() / "Documents";
|
return GetHomeFolder() / "Documents";
|
||||||
#endif
|
#endif
|
||||||
@@ -237,6 +252,9 @@ namespace Tesses::Framework::Platform::Environment
|
|||||||
}
|
}
|
||||||
std::string GetPlatform()
|
std::string GetPlatform()
|
||||||
{
|
{
|
||||||
|
#if defined(__ANDROID__)
|
||||||
|
return "Android";
|
||||||
|
#endif
|
||||||
#if defined(__SWITCH__)
|
#if defined(__SWITCH__)
|
||||||
return "Nintendo Switch";
|
return "Nintendo Switch";
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ I modified it to return home directory and conditionally compile for systems tha
|
|||||||
#ifndef SAGO_PLATFORM_FOLDERS_H
|
#ifndef SAGO_PLATFORM_FOLDERS_H
|
||||||
#define SAGO_PLATFORM_FOLDERS_H
|
#define SAGO_PLATFORM_FOLDERS_H
|
||||||
|
|
||||||
#if defined(GEKKO) || defined(__SWITCH__) || defined(__EMSCRIPTEN__) || defined(__PS2__)
|
#if defined(GEKKO) || defined(__SWITCH__) || defined(__EMSCRIPTEN__) || defined(__PS2__) || defined(__ANDROID__)
|
||||||
#define SAGO_DISABLE
|
#define SAGO_DISABLE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -33,6 +33,23 @@ namespace Tesses::Framework::TextStreams
|
|||||||
} while(r != -1);
|
} while(r != -1);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
void TextReader::ReadAllLines(std::vector<std::string>& lines)
|
||||||
|
{
|
||||||
|
int32_t r = -1;
|
||||||
|
std::string builder;
|
||||||
|
do {
|
||||||
|
r = ReadChar();
|
||||||
|
if(r == -1) break;
|
||||||
|
if(r == '\r') continue;
|
||||||
|
if(r == '\n') {
|
||||||
|
lines.push_back(builder);
|
||||||
|
builder.clear();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
builder += (char)r;
|
||||||
|
|
||||||
|
} while(r != -1);
|
||||||
|
}
|
||||||
|
|
||||||
std::string TextReader::ReadToEnd()
|
std::string TextReader::ReadToEnd()
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user