mirror of
https://onedev.site.tesses.net/tesses-framework
synced 2026-02-08 07:45: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/NullFilesystem.cpp
|
||||
src/Filesystem/MountableFilesystem.cpp
|
||||
src/Filesystem/FSHelpers.cpp
|
||||
src/Filesystem/TempFS.cpp
|
||||
src/Crypto/ClientTLSStream.cpp
|
||||
src/Crypto/MbedHelpers.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)")
|
||||
|
||||
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 second=0;
|
||||
bool isLocal=false;
|
||||
int64_t ToEpochNoConvert();
|
||||
int64_t ToEpochNoConvert() const;
|
||||
void FromEpochNoConvert(int64_t gmt);
|
||||
public:
|
||||
DateTime();
|
||||
DateTime(int year, int month, int day, int hour, int minute, int seconds, bool isLocal=true);
|
||||
DateTime(int64_t epoch);
|
||||
int Year();
|
||||
int Month();
|
||||
int Day();
|
||||
int Hour();
|
||||
int Minute();
|
||||
int Second();
|
||||
int DayOfWeek();
|
||||
bool IsLocal();
|
||||
int64_t ToEpoch();
|
||||
DateTime ToLocal();
|
||||
DateTime ToUTC();
|
||||
int Year() const;
|
||||
int Month() const;
|
||||
int Day() const;
|
||||
int Hour() const;
|
||||
int Minute() const;
|
||||
int Second() const;
|
||||
int DayOfWeek() const;
|
||||
bool IsLocal() const;
|
||||
int64_t ToEpoch() const;
|
||||
DateTime ToLocal() const;
|
||||
DateTime ToUTC() const;
|
||||
void SetToLocal();
|
||||
void SetToUTC();
|
||||
void SetYear(int y);
|
||||
@@ -52,15 +52,105 @@ namespace Tesses::Framework::Date
|
||||
static DateTime Now();
|
||||
static DateTime NowUTC();
|
||||
|
||||
std::string ToString();
|
||||
std::string ToString(std::string fmt);
|
||||
std::string ToString() const;
|
||||
std::string ToString(std::string fmt) const;
|
||||
|
||||
|
||||
std::string ToHttpDate();
|
||||
std::string ToHttpDate() const;
|
||||
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);
|
||||
std::vector<std::string> path;
|
||||
VFSPath();
|
||||
VFSPath(const char* path) : VFSPath((std::string)path)
|
||||
{}
|
||||
VFSPath(std::vector<std::string> path);
|
||||
VFSPath(std::string path);
|
||||
VFSPath(VFSPath p, std::string subent);
|
||||
@@ -36,22 +38,27 @@ namespace Tesses::Framework::Filesystem
|
||||
|
||||
|
||||
|
||||
VFSPath GetParent();
|
||||
VFSPath CollapseRelativeParents();
|
||||
std::string GetFileName();
|
||||
bool HasExtension();
|
||||
std::string GetExtension();
|
||||
VFSPath GetParent() const;
|
||||
VFSPath CollapseRelativeParents() const;
|
||||
std::string GetFileName() const;
|
||||
bool HasExtension() const;
|
||||
std::string GetExtension() const;
|
||||
void ChangeExtension(std::string ext);
|
||||
void RemoveExtension();
|
||||
std::string ToString();
|
||||
std::string ToString() const;
|
||||
|
||||
operator std::string() const
|
||||
{
|
||||
return ToString();
|
||||
}
|
||||
|
||||
static VFSPath GetAbsoluteCurrentDirectory();
|
||||
static void SetAbsoluteCurrentDirectory(VFSPath path);
|
||||
VFSPath MakeAbsolute();
|
||||
VFSPath MakeAbsolute() const;
|
||||
|
||||
VFSPath MakeAbsolute(VFSPath curDir);
|
||||
VFSPath MakeRelative();
|
||||
VFSPath MakeRelative(VFSPath toMakeRelativeTo);
|
||||
VFSPath MakeAbsolute(VFSPath curDir) const;
|
||||
VFSPath MakeRelative() const;
|
||||
VFSPath MakeRelative(VFSPath toMakeRelativeTo) const;
|
||||
};
|
||||
VFSPath operator/(VFSPath p, VFSPath p2);
|
||||
VFSPath operator/(VFSPath p, std::string p2);
|
||||
|
||||
@@ -9,6 +9,7 @@ namespace Tesses::Framework::Platform::Environment
|
||||
|
||||
|
||||
namespace SpecialFolders {
|
||||
Tesses::Framework::Filesystem::VFSPath GetTemp();
|
||||
Tesses::Framework::Filesystem::VFSPath GetHomeFolder();
|
||||
Tesses::Framework::Filesystem::VFSPath GetDownloads();
|
||||
Tesses::Framework::Filesystem::VFSPath GetMusic();
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "Filesystem/NullFilesystem.hpp"
|
||||
#include "Filesystem/MountableFilesystem.hpp"
|
||||
#include "Filesystem/MemoryFilesystem.hpp"
|
||||
#include "Filesystem/FSHelpers.hpp"
|
||||
#include "Crypto/ClientTLSStream.hpp"
|
||||
#include "Crypto/MbedHelpers.hpp"
|
||||
#include "Lazy.hpp"
|
||||
|
||||
@@ -11,6 +11,7 @@ namespace Tesses::Framework::TextStreams
|
||||
int32_t ReadChar();
|
||||
std::string ReadLine();
|
||||
bool ReadLine(std::string& str);
|
||||
void ReadAllLines(std::vector<std::string>& lines);
|
||||
std::string ReadToEnd();
|
||||
void ReadToEnd(std::string& str);
|
||||
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->isLocal = isLocal;
|
||||
}
|
||||
int DateTime::Year()
|
||||
int DateTime::Year() const
|
||||
{
|
||||
return this->year;
|
||||
}
|
||||
int DateTime::Month()
|
||||
int DateTime::Month() const
|
||||
{
|
||||
return this->month;
|
||||
}
|
||||
int DateTime::Day()
|
||||
int DateTime::Day() const
|
||||
{
|
||||
return this->day;
|
||||
}
|
||||
int DateTime::Hour()
|
||||
int DateTime::Hour() const
|
||||
{
|
||||
return this->hour;
|
||||
}
|
||||
int DateTime::Minute()
|
||||
int DateTime::Minute() const
|
||||
{
|
||||
return this->minute;
|
||||
}
|
||||
int DateTime::Second()
|
||||
int DateTime::Second() const
|
||||
{
|
||||
return this->second;
|
||||
}
|
||||
bool DateTime::IsLocal()
|
||||
bool DateTime::IsLocal() const
|
||||
{
|
||||
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::sys_days d = ymd;
|
||||
@@ -214,7 +214,7 @@ namespace Tesses::Framework::Date
|
||||
this->isLocal=true;
|
||||
this->FromEpochNoConvert(local);
|
||||
}
|
||||
DateTime DateTime::ToLocal()
|
||||
DateTime DateTime::ToLocal() const
|
||||
{
|
||||
DateTime dt = *this;
|
||||
dt.SetToLocal();
|
||||
@@ -294,13 +294,13 @@ namespace Tesses::Framework::Date
|
||||
this->FromEpochNoConvert(local);
|
||||
|
||||
}
|
||||
DateTime DateTime::ToUTC()
|
||||
DateTime DateTime::ToUTC() const
|
||||
{
|
||||
DateTime dt = *this;
|
||||
dt.SetToUTC();
|
||||
return dt;
|
||||
}
|
||||
int64_t DateTime::ToEpoch()
|
||||
int64_t DateTime::ToEpoch() const
|
||||
{
|
||||
if(this->isLocal)
|
||||
{
|
||||
@@ -309,7 +309,7 @@ namespace Tesses::Framework::Date
|
||||
}
|
||||
return this->ToEpochNoConvert();
|
||||
}
|
||||
int64_t DateTime::ToEpochNoConvert()
|
||||
int64_t DateTime::ToEpochNoConvert() const
|
||||
{
|
||||
date::year y = (date::year)year;
|
||||
date::month m = (date::month)month;
|
||||
@@ -551,7 +551,7 @@ namespace Tesses::Framework::Date
|
||||
dt.second = second;
|
||||
return true;
|
||||
}
|
||||
std::string DateTime::ToHttpDate()
|
||||
std::string DateTime::ToHttpDate() const
|
||||
{
|
||||
auto utc=this->ToUTC();
|
||||
std::string weekday=weekday_short[utc.DayOfWeek()];
|
||||
@@ -567,12 +567,12 @@ namespace Tesses::Framework::Date
|
||||
return strm.str();
|
||||
|
||||
}
|
||||
std::string DateTime::ToString()
|
||||
std::string DateTime::ToString() const
|
||||
{
|
||||
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();
|
||||
|
||||
@@ -732,4 +732,211 @@ namespace Tesses::Framework::Date
|
||||
}
|
||||
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::current_path(mpath);
|
||||
}
|
||||
VFSPath VFSPath::MakeAbsolute()
|
||||
VFSPath VFSPath::MakeAbsolute() const
|
||||
{
|
||||
return MakeAbsolute(GetAbsoluteCurrentDirectory());
|
||||
}
|
||||
VFSPath VFSPath::MakeAbsolute(VFSPath curDir)
|
||||
VFSPath VFSPath::MakeAbsolute(VFSPath curDir) const
|
||||
{
|
||||
if (!this->relative) return *this;
|
||||
VFSPath p2 = curDir / *this;
|
||||
return p2.CollapseRelativeParents();
|
||||
}
|
||||
VFSPath VFSPath::MakeRelative()
|
||||
VFSPath VFSPath::MakeRelative() const
|
||||
{
|
||||
return MakeRelative(GetAbsoluteCurrentDirectory());
|
||||
}
|
||||
VFSPath VFSPath::MakeRelative(VFSPath toMakeRelativeTo)
|
||||
VFSPath VFSPath::MakeRelative(VFSPath toMakeRelativeTo) const
|
||||
{
|
||||
|
||||
if(this->relative) return *this;
|
||||
@@ -250,7 +250,7 @@ namespace Tesses::Framework::Filesystem
|
||||
p2.relative = true;
|
||||
return p2;
|
||||
}
|
||||
VFSPath VFSPath::CollapseRelativeParents()
|
||||
VFSPath VFSPath::CollapseRelativeParents() const
|
||||
{
|
||||
std::vector<std::string> parts;
|
||||
|
||||
@@ -330,7 +330,7 @@ namespace Tesses::Framework::Filesystem
|
||||
this->path = p;
|
||||
}
|
||||
|
||||
bool VFSPath::HasExtension()
|
||||
bool VFSPath::HasExtension() const
|
||||
{
|
||||
if(this->path.empty()) return false;
|
||||
auto& str = this->path.back();
|
||||
@@ -338,7 +338,7 @@ namespace Tesses::Framework::Filesystem
|
||||
if(index == std::string::npos) return false;
|
||||
return true;
|
||||
}
|
||||
std::string VFSPath::GetExtension()
|
||||
std::string VFSPath::GetExtension() const
|
||||
{
|
||||
if(this->path.empty()) return {};
|
||||
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;
|
||||
if(this->path.empty()) return VFSPath();
|
||||
@@ -407,13 +407,13 @@ namespace Tesses::Framework::Filesystem
|
||||
return res;
|
||||
}
|
||||
|
||||
std::string VFSPath::GetFileName()
|
||||
std::string VFSPath::GetFileName() const
|
||||
{
|
||||
if(this->path.empty()) return "";
|
||||
return this->path.back();
|
||||
}
|
||||
|
||||
std::string VFSPath::ToString()
|
||||
std::string VFSPath::ToString() const
|
||||
{
|
||||
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] + "/";
|
||||
|
||||
@@ -25,13 +25,18 @@ namespace Tesses::Framework::Platform::Environment
|
||||
|
||||
namespace SpecialFolders
|
||||
{
|
||||
|
||||
VFSPath GetTemp()
|
||||
{
|
||||
return std::filesystem::temp_directory_path().string();
|
||||
}
|
||||
VFSPath GetHomeFolder()
|
||||
{
|
||||
#if defined(TESSESFRAMEWORK_ENABLE_PLATFORMFOLDERS) && !defined(SAGO_DISABLE)
|
||||
return sago::getHomeDir();
|
||||
#elif defined(__EMSCRIPTEN__)
|
||||
return (std::string)"/home/web_user";
|
||||
#elif defined(__ANDROID__)
|
||||
return (std::string)"/sdcard/TF_User";
|
||||
#else
|
||||
return (std::string)"/TF_User";
|
||||
#endif
|
||||
@@ -40,6 +45,8 @@ namespace Tesses::Framework::Platform::Environment
|
||||
{
|
||||
#if defined(TESSESFRAMEWORK_ENABLE_PLATFORMFOLDERS) && !defined(SAGO_DISABLE)
|
||||
return sago::getDownloadFolder();
|
||||
#elif defined(__ANDROID__)
|
||||
return (std::string)"/sdcard/Download";
|
||||
#else
|
||||
return GetHomeFolder() / "Downloads";
|
||||
#endif
|
||||
@@ -48,6 +55,8 @@ namespace Tesses::Framework::Platform::Environment
|
||||
{
|
||||
#if defined(TESSESFRAMEWORK_ENABLE_PLATFORMFOLDERS) && !defined(SAGO_DISABLE)
|
||||
return sago::getMusicFolder();
|
||||
#elif defined(__ANDROID__)
|
||||
return (std::string)"/sdcard/Music";
|
||||
#else
|
||||
return GetHomeFolder() / "Music";
|
||||
#endif
|
||||
@@ -56,6 +65,8 @@ namespace Tesses::Framework::Platform::Environment
|
||||
{
|
||||
#if defined(TESSESFRAMEWORK_ENABLE_PLATFORMFOLDERS) && !defined(SAGO_DISABLE)
|
||||
return sago::getPicturesFolder();
|
||||
#elif defined(__ANDROID__)
|
||||
return (std::string)"/sdcard/Pictures";
|
||||
#else
|
||||
return GetHomeFolder() / "Pictures";
|
||||
#endif
|
||||
@@ -64,6 +75,8 @@ namespace Tesses::Framework::Platform::Environment
|
||||
{
|
||||
#if defined(TESSESFRAMEWORK_ENABLE_PLATFORMFOLDERS) && !defined(SAGO_DISABLE)
|
||||
return sago::getVideoFolder();
|
||||
#elif defined(__ANDROID__)
|
||||
return (std::string)"/sdcard/Movies";
|
||||
#else
|
||||
return GetHomeFolder() / "Videos";
|
||||
#endif
|
||||
@@ -72,6 +85,8 @@ namespace Tesses::Framework::Platform::Environment
|
||||
{
|
||||
#if defined(TESSESFRAMEWORK_ENABLE_PLATFORMFOLDERS) && !defined(SAGO_DISABLE)
|
||||
return sago::getDocumentsFolder();
|
||||
#elif defined(__ANDROID__)
|
||||
return (std::string)"/sdcard/Documents";
|
||||
#else
|
||||
return GetHomeFolder() / "Documents";
|
||||
#endif
|
||||
@@ -237,6 +252,9 @@ namespace Tesses::Framework::Platform::Environment
|
||||
}
|
||||
std::string GetPlatform()
|
||||
{
|
||||
#if defined(__ANDROID__)
|
||||
return "Android";
|
||||
#endif
|
||||
#if defined(__SWITCH__)
|
||||
return "Nintendo Switch";
|
||||
#endif
|
||||
|
||||
@@ -37,7 +37,7 @@ I modified it to return home directory and conditionally compile for systems tha
|
||||
#ifndef 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
|
||||
#endif
|
||||
|
||||
|
||||
@@ -33,6 +33,23 @@ namespace Tesses::Framework::TextStreams
|
||||
} while(r != -1);
|
||||
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()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user