From 093fea5fa377450eb2df6cdb9ae00a67797d25a1 Mon Sep 17 00:00:00 2001 From: None Date: Wed, 30 Apr 2025 20:27:52 +0200 Subject: [PATCH] Update bundled ZenLib to 0.4.41 Signed-off-by: Maxime Gervais --- Source/ZenLib/BitStream.h | 42 +- Source/ZenLib/BitStream_Fast.h | 29 +- Source/ZenLib/BitStream_LE.h | 17 +- Source/ZenLib/Conf.h | 17 +- Source/ZenLib/Dir.cpp | 268 +++++++-- Source/ZenLib/Dir.h | 4 +- Source/ZenLib/File.cpp | 960 +++++++++++++++++++++++------- Source/ZenLib/File.h | 1 + Source/ZenLib/FileName.cpp | 14 +- Source/ZenLib/HTTP_Client.cpp | 8 +- Source/ZenLib/InfoMap.cpp | 10 +- Source/ZenLib/OS_Utils.cpp | 193 +++++- Source/ZenLib/OS_Utils.h | 43 ++ Source/ZenLib/Thread.cpp | 48 +- Source/ZenLib/Translation.cpp | 2 +- Source/ZenLib/Utils.cpp | 28 +- Source/ZenLib/Utils.h | 6 - Source/ZenLib/Ztring.cpp | 185 +++--- Source/ZenLib/Ztring.h | 2 +- Source/ZenLib/ZtringList.cpp | 21 +- Source/ZenLib/ZtringListList.cpp | 9 +- Source/ZenLib/ZtringListListF.cpp | 6 +- Source/ZenLib/int128s.cpp | 108 ++-- Source/ZenLib/int128s.h | 156 +++-- Source/ZenLib/int128u.cpp | 108 ++-- Source/ZenLib/int128u.h | 156 +++-- 26 files changed, 1731 insertions(+), 710 deletions(-) diff --git a/Source/ZenLib/BitStream.h b/Source/ZenLib/BitStream.h index f00e04a0..e23b8485 100644 --- a/Source/ZenLib/BitStream.h +++ b/Source/ZenLib/BitStream.h @@ -30,16 +30,32 @@ namespace ZenLib class BitStream { public: - BitStream () {Buffer=NULL; - Buffer_Size=Buffer_Size_Init=Buffer_Size_BeforeLastCall=0; - LastByte_Size=0; - BufferUnderRun=true; - BookMark=false;} - BitStream (const int8u* Buffer_, size_t Size_) {Buffer=Buffer_; - Buffer_Size=Buffer_Size_Init=Buffer_Size_BeforeLastCall=Size_*8; //Size is in bits - LastByte_Size=0; - BufferUnderRun=Buffer_Size?false:true; - BookMark=false;} + BitStream () { Buffer = NULL; + Buffer_Size = 0; + Buffer_Size_Init = 0; + Buffer_Size_BeforeLastCall = 0; + LastByte = 0; + LastByte_Size = 0; + BufferUnderRun = true; + BookMark = false; + Buffer_BookMark = 0; + Buffer_Size_BookMark = 0; + LastByte_BookMark = 0; + LastByte_Size_BookMark = 0; + BufferUnderRun_BookMark = false; } + BitStream (const int8u* Buffer_, size_t Size_) { Buffer = Buffer_; + Buffer_Size = Size_ * 8; //Size is in bits + Buffer_Size_Init = Size_ * 8; //Size is in bits + Buffer_Size_BeforeLastCall = Size_ * 8; //Size is in bits + LastByte = 0; + LastByte_Size = 0; + BufferUnderRun = (Buffer_Size ? false : true); + BookMark = false; + Buffer_BookMark = 0; + Buffer_Size_BookMark = 0; + LastByte_BookMark = 0; + LastByte_Size_BookMark = 0; + BufferUnderRun_BookMark = false; } virtual ~BitStream () {}; virtual void Attach(const int8u* Buffer_, size_t Size_) @@ -98,14 +114,17 @@ class BitStream ToReturn |= ((size_t)*Buffer) << NewBits; Buffer++; Buffer_Size-=8; + [[fallthrough]]; case 2 : NewBits-=8; ToReturn |= ((size_t)*Buffer) << NewBits; Buffer++; Buffer_Size-=8; + [[fallthrough]]; case 1 : NewBits-=8; ToReturn |= ((size_t)*Buffer) << NewBits; Buffer++; Buffer_Size-=8; + [[fallthrough]]; case 0 : LastByte=*Buffer; Buffer++; @@ -191,12 +210,15 @@ class BitStream case 3 : NewBits-=8; Buffer++; Buffer_Size-=8; + [[fallthrough]]; case 2 : NewBits-=8; Buffer++; Buffer_Size-=8; + [[fallthrough]]; case 1 : NewBits-=8; Buffer++; Buffer_Size-=8; + [[fallthrough]]; case 0 : LastByte=*Buffer; Buffer++; diff --git a/Source/ZenLib/BitStream_Fast.h b/Source/ZenLib/BitStream_Fast.h index 8f579f3c..97063333 100644 --- a/Source/ZenLib/BitStream_Fast.h +++ b/Source/ZenLib/BitStream_Fast.h @@ -30,12 +30,16 @@ namespace ZenLib class BitStream_Fast { public: - BitStream_Fast () {Buffer=NULL; - Buffer_Size=Buffer_Size_Init=0; - BufferUnderRun=false;} - BitStream_Fast (const int8u* Buffer_, size_t Size_) {Buffer=Buffer_; - Buffer_Size=Buffer_Size_Init=Size_*8; //Size is in bits - BufferUnderRun=false;} + BitStream_Fast () { Buffer = NULL; + Buffer_Size = 0; + Buffer_Size_Init = 0; + LastByte = 0; + BufferUnderRun = false; } + BitStream_Fast (const int8u* Buffer_, size_t Size_) { Buffer = Buffer_; + Buffer_Size = Size_ * 8; //Size is in bits + Buffer_Size_Init = Size_ * 8; //Size is in bits + LastByte = 0; + BufferUnderRun = false; } ~BitStream_Fast () {} void Attach(const int8u* Buffer_, size_t Size_) @@ -182,11 +186,12 @@ class BitStream_Fast { case 3 : NewBits-=8; ToReturn|=*(Buffer++)<>((Buffer_Size-HowMany)%8))&Mask[NewBits]; @@ -403,6 +409,13 @@ class BitStream_Fast return Buffer_Size%8; } + inline void Resize(size_t Size_) //Size_ is the new count of remaining bits, must have the same alignment as Remain() + { + if (BufferUnderRun && Size_>Buffer_Size) + BufferUnderRun=false; + Buffer_Size=Size_; + } + private : const int8u* Buffer; size_t Buffer_Size; diff --git a/Source/ZenLib/BitStream_LE.h b/Source/ZenLib/BitStream_LE.h index 362427fb..20147c07 100644 --- a/Source/ZenLib/BitStream_LE.h +++ b/Source/ZenLib/BitStream_LE.h @@ -26,8 +26,19 @@ namespace ZenLib class BitStream_LE : public BitStream { public: - BitStream_LE () :BitStream() {}; - BitStream_LE (const int8u* Buffer_, size_t Size_) :BitStream(Buffer_, Size_) {}; + BitStream_LE() : BitStream(), + endbyte(0), + endbit(0), + buffer(NULL), + ptr(NULL), + ptr_BeforeLastCall(NULL), + storage(0) { + }; + + BitStream_LE (const int8u* Buffer_, size_t Size_) : BitStream(Buffer_, Size_), + ptr_BeforeLastCall(NULL) { + Attach(Buffer_, Size_); + }; void Attach(const int8u* Buffer_, size_t Size_) { @@ -102,6 +113,8 @@ class BitStream_LE : public BitStream void Byte_Align() { + if (endbit) + Get(endbit); }; size_t Offset_Get() diff --git a/Source/ZenLib/Conf.h b/Source/ZenLib/Conf.h index c4172fca..735aa330 100644 --- a/Source/ZenLib/Conf.h +++ b/Source/ZenLib/Conf.h @@ -55,6 +55,21 @@ #endif #endif +//--------------------------------------------------------------------------- +//Windows UWP +#if defined(WIN32) || defined(WIN64) + #if defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_APP) + #ifndef WINDOWS_UWP + #define WINDOWS_UWP + #endif + #endif + #if defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_GAMES) + #ifndef WINDOWS_GAMES + #define WINDOWS_GAMES + #endif + #endif +#endif + //--------------------------------------------------------------------------- //Unix (Linux, HP, Sun, BeOS...) #if defined(UNIX) || defined(_UNIX) || defined(__UNIX__) \ @@ -193,7 +208,7 @@ //--------------------------------------------------------------------------- //(-1) is known to be the MAX of an unsigned int but GCC complains about it #ifdef __cplusplus - #include //for size_t + #include //for size_t #else /* __cplusplus */ #include //for size_t #endif /* __cplusplus */ diff --git a/Source/ZenLib/Dir.cpp b/Source/ZenLib/Dir.cpp index e84e4a2b..032a9dff 100644 --- a/Source/ZenLib/Dir.cpp +++ b/Source/ZenLib/Dir.cpp @@ -28,6 +28,17 @@ #ifdef WINDOWS #undef __TEXT #include + #ifdef WINDOWS_UWP + #include + #include + #include + #include + using namespace Microsoft::WRL; + using namespace Microsoft::WRL::Wrappers; + using namespace ABI::Windows::Foundation; + using namespace ABI::Windows::Foundation::Collections; + using namespace ABI::Windows::Storage; + #endif #else #include #include @@ -187,67 +198,127 @@ ZtringList Dir::GetAllFileNames(const Ztring &Dir_Name_, dirlist_t Options) ToReturn.push_back(Liste[Pos].c_str()); #else //ZENLIB_USEWX #ifdef WINDOWS - //Is a dir? - if (Exists(Dir_Name)) - Dir_Name+=__T("\\*"); + #ifdef WINDOWS_UWP + //Ensure all slashs are converted to backslashs (WinRT file API don't like slashs) + Dir_Name.FindAndReplace(__T("/"), __T("\\")); + + ComPtr Folder; + if (FAILED(Get_Folder(HStringReference(Dir_Name.c_str(), (unsigned int)Dir_Name.size()), Folder))) + return ToReturn; + + ComPtr* > > Async_GetItems; + ComPtr > Items; + if (FAILED(Folder->GetItemsAsyncOverloadDefaultStartAndCount(&Async_GetItems)) || + FAILED(Await(Async_GetItems)) || + FAILED(Async_GetItems->GetResults(&Items)) || + !Items) + return ToReturn; + + unsigned int Size; + if (FAILED(Items->get_Size(&Size))) + return ToReturn; + + for (unsigned int Pos=0; Pos Item; + if (FAILED(Items->GetAt(Pos, &Item)) || !Item) + continue; - //Path - Ztring Path=FileName::Path_Get(Dir_Name); - if (Path.empty()) - { - DWORD Path_Size=GetFullPathName(Dir_Name.c_str(), 0, NULL, NULL); - Char* PathTemp=new Char[Path_Size+1]; - if (GetFullPathName(Dir_Name.c_str(), Path_Size+1, PathTemp, NULL)) - Path=FileName::Path_Get(PathTemp); - delete [] PathTemp; - } + HString File_Name_HString; + if (FAILED(Item->get_Name(File_Name_HString.GetAddressOf()))) + continue; - #ifdef UNICODE - WIN32_FIND_DATAW FindFileDataW; - HANDLE hFind=FindFirstFileW(Dir_Name.c_str(), &FindFileDataW); - #else - WIN32_FIND_DATA FindFileData; - HANDLE hFind=FindFirstFile(Dir_Name.c_str(), &FindFileData); - #endif //UNICODE + Ztring File_Name(WindowsGetStringRawBuffer(File_Name_HString.Get(), NULL)); - if (hFind==INVALID_HANDLE_VALUE) - { - ZENLIB_DEBUG2( "Dir GetAllFileNames", - Debug+=", returns with files count="; Debug +=Ztring::ToZtring(ToReturn.size()).To_UTF8()) + if (File_Name.empty() || (!(Options&Include_Hidden) && File_Name[0]==__T('.'))) + continue; - return ZtringList(); - } + tstring File_Name_Complete = Dir_Name + __T("\\") + File_Name; + + boolean IsFile = FALSE; + boolean IsFolder = FALSE; + Item->IsOfType(StorageItemTypes_File, &IsFile); + Item->IsOfType(StorageItemTypes_Folder, &IsFolder); + + if ((Options&Include_Files) && IsFile && ((Options&Include_Hidden) || File_Name[0] != __T('.'))) + { + Add_Item_To_FUA(HStringReference(File_Name_Complete.c_str(), (unsigned int)File_Name_Complete.length()), Item); + ToReturn.push_back(File_Name_Complete); + } + else if ((Options&Include_Dirs) && IsFolder) + { + Add_Item_To_FUA(HStringReference(File_Name_Complete.c_str(), (unsigned int)File_Name_Complete.length()), Item); + ToReturn.push_back(File_Name_Complete); + } + + if (IsFolder && Options&Parse_SubDirs) + ToReturn+=GetAllFileNames(File_Name_Complete, Options); + } + + return ToReturn; + #else + //Is a dir? + if (Exists(Dir_Name)) + Dir_Name+=__T("\\*"); + + //Path + Ztring Path=FileName::Path_Get(Dir_Name); + if (Path.empty()) + { + DWORD Path_Size=GetFullPathName(Dir_Name.c_str(), 0, NULL, NULL); + Char* PathTemp=new Char[Path_Size+1]; + if (GetFullPathName(Dir_Name.c_str(), Path_Size+1, PathTemp, NULL)) + Path=FileName::Path_Get(PathTemp); + delete [] PathTemp; + } - BOOL ReturnValue; - do - { #ifdef UNICODE - Ztring File_Name(FindFileDataW.cFileName); + WIN32_FIND_DATAW FindFileDataW; + HANDLE hFind=FindFirstFileW(Dir_Name.c_str(), &FindFileDataW); #else - Ztring File_Name(FindFileData.cFileName); + WIN32_FIND_DATA FindFileData; + HANDLE hFind=FindFirstFile(Dir_Name.c_str(), &FindFileData); #endif //UNICODE - if (File_Name!=__T(".") && File_Name!=__T("..")) //Avoid . an .. + + if (hFind==INVALID_HANDLE_VALUE) { - Ztring File_Name_Complete=Path+__T("\\")+File_Name; - if (Exists(File_Name_Complete)) + ZENLIB_DEBUG2( "Dir GetAllFileNames", + Debug+=", returns with files count="; Debug +=Ztring::ToZtring(ToReturn.size()).To_UTF8()) + + return ZtringList(); + } + + BOOL ReturnValue; + do + { + #ifdef UNICODE + Ztring File_Name(FindFileDataW.cFileName); + #else + Ztring File_Name(FindFileData.cFileName); + #endif //UNICODE + if (File_Name!=__T(".") && File_Name!=__T("..")) //Avoid . an .. { - if (Options&Include_Dirs) - ToReturn.push_back(File_Name_Complete); //A dir - if (Options&Parse_SubDirs) - ToReturn+=GetAllFileNames(File_Name_Complete, Options); //A SubDir + Ztring File_Name_Complete=Path+__T("\\")+File_Name; + if (Exists(File_Name_Complete)) + { + if (Options&Include_Dirs) + ToReturn.push_back(File_Name_Complete); //A dir + if (Options&Parse_SubDirs) + ToReturn+=GetAllFileNames(File_Name_Complete, Options); //A SubDir + } + else if ((Options&Include_Files) && ((Options&Include_Hidden) || (!File_Name.empty() && File_Name[0]!=__T('.')))) + ToReturn.push_back(File_Name_Complete); //A file } - else if ((Options&Include_Files) && ((Options&Include_Hidden) || (!File_Name.empty() && File_Name[0]!=__T('.')))) - ToReturn.push_back(File_Name_Complete); //A file + #ifdef UNICODE + ReturnValue=FindNextFileW(hFind, &FindFileDataW); + #else + ReturnValue=FindNextFile(hFind, &FindFileData); + #endif //UNICODE } - #ifdef UNICODE - ReturnValue=FindNextFileW(hFind, &FindFileDataW); - #else - ReturnValue=FindNextFile(hFind, &FindFileData); - #endif //UNICODE - } - while (ReturnValue); + while (ReturnValue); - FindClose(hFind); + FindClose(hFind); + #endif #else //WINDOWS //A file? if (File::Exists(Dir_Name)) @@ -297,6 +368,7 @@ ZtringList Dir::GetAllFileNames(const Ztring &Dir_Name_, dirlist_t Options) //Close it closedir(Dir); } + #if !defined(__ANDROID_API__) || __ANDROID_API__ >= 28 else { glob_t globbuf; @@ -306,6 +378,7 @@ ZtringList Dir::GetAllFileNames(const Ztring &Dir_Name_, dirlist_t Options) ToReturn.push_back(Ztring().From_Local(globbuf.gl_pathv[Pos])); } } + #endif #endif #endif //ZENLIB_USEWX @@ -330,16 +403,52 @@ bool Dir::Exists(const Ztring &File_Name) return FN.DirExists(); #else //ZENLIB_USEWX #ifdef WINDOWS - #ifdef UNICODE - DWORD FileAttributes=GetFileAttributesW(File_Name.c_str()); + #ifdef WINDOWS_UWP + //Ensure all slashs are converted to backslashs (WinRT file API don't like slashs) + Ztring File_Name_=File_Name; + File_Name_.FindAndReplace(__T("/"), __T("\\")); + + //Try to access folder directly + ComPtr Folder; + if (SUCCEEDED(Get_Folder(HStringReference(File_Name_.c_str(), (unsigned int)File_Name_.size()), Folder))) + return true; + + //Try directory access methods + tstring Parent=FileName::Path_Get(File_Name_); + tstring Dir=FileName::Name_Get(File_Name_); + + ComPtr Parent_Folder; + if (FAILED(Get_Folder(HStringReference(Parent.c_str(), (unsigned int)Parent.size()), Parent_Folder))) + return false; + + //IStorageFolder don't provide TryGetItemAsync + ComPtr Parent_Folder2; + if (FAILED(Parent_Folder->QueryInterface(IID_PPV_ARGS(&Parent_Folder2))) || !Parent_Folder2) + return false; + + ComPtr > Async_GetItem; + ComPtr Item; + ComPtr Child; + if (SUCCEEDED(Parent_Folder2->TryGetItemAsync(HStringReference(Dir.c_str(), (unsigned int)Dir.size()).Get(), &Async_GetItem)) && + SUCCEEDED(Await(Async_GetItem)) && + SUCCEEDED(Async_GetItem->GetResults(&Item)) && + Item && + SUCCEEDED(Item.As(&Child))) + return true; + + return false; #else - DWORD FileAttributes=GetFileAttributes(File_Name.c_str()); - #endif //UNICODE + #ifdef UNICODE + DWORD FileAttributes=GetFileAttributesW(File_Name.c_str()); + #else + DWORD FileAttributes=GetFileAttributes(File_Name.c_str()); + #endif //UNICODE - ZENLIB_DEBUG2( "Dir Exists", - Debug+=", returns "; Debug +=Ztring::ToZtring(((FileAttributes!=INVALID_FILE_ATTRIBUTES) && (FileAttributes&FILE_ATTRIBUTE_DIRECTORY))?1:0).To_UTF8()) + ZENLIB_DEBUG2( "Dir Exists", + Debug+=", returns "; Debug +=Ztring::ToZtring(((FileAttributes!=INVALID_FILE_ATTRIBUTES) && (FileAttributes&FILE_ATTRIBUTE_DIRECTORY))?1:0).To_UTF8()) - return ((FileAttributes!=INVALID_FILE_ATTRIBUTES) && (FileAttributes&FILE_ATTRIBUTE_DIRECTORY)); + return ((FileAttributes!=INVALID_FILE_ATTRIBUTES) && (FileAttributes&FILE_ATTRIBUTE_DIRECTORY)); + #endif #else //WINDOWS struct stat buffer; int status; @@ -364,15 +473,44 @@ bool Dir::Create(const Ztring &File_Name) return false; } - #ifdef ZENLIB_USEWX + #ifdef ZENLIB_USEWX return wxFileName::Mkdir(File_Name.c_str()); #else //ZENLIB_USEWX #ifdef WINDOWS - #ifdef UNICODE - return CreateDirectoryW(File_Name.c_str(), NULL)!=0; + #ifdef WINDOWS_UWP + CreationCollisionOption Collision_Option=CreationCollisionOption_FailIfExists; + + //Ensure all slashs are converted to backslashs (WinRT file API don't like slashs) + Parent.FindAndReplace(__T("/"), __T("\\")); + + //Split folder and parent + Ztring Dir=FileName::Name_Get(File_Name); + + //Split folder and parent + size_t Last_Separator=File_Name.rfind(__T("\\")); + + //Open parent folder + ComPtr Folder; + if (FAILED(Get_Folder(HStringReference(Parent.c_str(), (unsigned int)Parent.size()), Folder))) + return false; + + //Create folder + ComPtr > Async_Create; + ComPtr New; + if (FAILED(Folder->CreateFolderAsync(HStringReference(Dir.c_str(), (unsigned int)Dir.size()).Get(), Collision_Option, &Async_Create)) || + FAILED(Await(Async_Create)) || + FAILED(Async_Create->GetResults(&New)) || + !New) + return false; + + return true; #else - return CreateDirectory(File_Name.c_str(), NULL)!=0; - #endif //UNICODE + #ifdef UNICODE + return CreateDirectoryW(File_Name.c_str(), NULL)!=0; + #else + return CreateDirectory(File_Name.c_str(), NULL)!=0; + #endif //UNICODE + #endif #else //WINDOWS return mkdir(File_Name.To_Local().c_str(), 0700)==0; #endif //WINDOWS @@ -383,7 +521,7 @@ bool Dir::Create(const Ztring &File_Name) // GetAllFileNames //*************************************************************************** -#ifdef WINDOWS +#if defined WINDOWS && !defined WINDOWS_UWP class GetAllFileNames_Private { public: @@ -392,13 +530,13 @@ class GetAllFileNames_Private Dir::dirlist_t Options; HANDLE hFind; #ifdef UNICODE - WIN32_FIND_DATAW FindFileDataW; + WIN32_FIND_DATAW FindFileDataW{}; #else - WIN32_FIND_DATA FindFileData; + WIN32_FIND_DATA FindFileData{}; #endif //UNICODE GetAllFileNames_Private() - : hFind(INVALID_HANDLE_VALUE) + : Options(), hFind(INVALID_HANDLE_VALUE) { } }; @@ -532,7 +670,7 @@ void GetAllFileNames::Close () ZENLIB_DEBUG2( "GetAllFileNames Close", ) } -#endif //WINDOWS +#endif //WINDOWS && !WINDOWS_UWP //*************************************************************************** // diff --git a/Source/ZenLib/Dir.h b/Source/ZenLib/Dir.h index d01d37c3..4755a625 100644 --- a/Source/ZenLib/Dir.h +++ b/Source/ZenLib/Dir.h @@ -50,7 +50,7 @@ public : static bool Create(const Ztring &Dir_Name); }; -#ifdef WINDOWS +#if defined WINDOWS && !defined WINDOWS_UWP class GetAllFileNames_Private; class GetAllFileNames { @@ -67,7 +67,7 @@ class GetAllFileNames private: GetAllFileNames_Private* p; }; -#endif //WINDOWS +#endif //WINDOWS && !WINDOWS_UWP } //NameSpace diff --git a/Source/ZenLib/File.cpp b/Source/ZenLib/File.cpp index daad46e2..f84b58cd 100644 --- a/Source/ZenLib/File.cpp +++ b/Source/ZenLib/File.cpp @@ -15,6 +15,7 @@ #include "ZenLib/Conf_Internal.h" //--------------------------------------------------------------------------- +#include "ZenLib/FileName.h" //--------------------------------------------------------------------------- #ifdef ZENLIB_USEWX #include @@ -30,9 +31,17 @@ #if !defined(WINDOWS) #include #if defined(LINUX) - #include - #include - #include + #include + #if defined(__GLIBC__) && defined(__GLIBC_PREREQ) + #if __GLIBC_PREREQ(2, 28) + #ifndef LINUX_STATX + #define LINUX_STATX 1 + #endif + #include + #include + #include + #endif + #endif #endif #endif //!defined(WINDOWS) #include @@ -46,12 +55,34 @@ #elif defined WINDOWS #undef __TEXT #include + #ifdef WINDOWS_UWP + #include + #include + #include + #include + using namespace Microsoft::WRL; + using namespace Microsoft::WRL::Wrappers; + using namespace ABI::Windows::Foundation; + using namespace ABI::Windows::Foundation::Collections; + using namespace ABI::Windows::Storage; + using namespace ABI::Windows::Storage::Streams; + using namespace ABI::Windows::Storage::FileProperties; + #endif #endif #endif //ZENLIB_USEWX -#include "ZenLib/File.h" #include "ZenLib/OS_Utils.h" +#include "ZenLib/File.h" + //--------------------------------------------------------------------------- +#ifdef WINDOWS_UWP +struct WrtFile +{ + ComPtr File; + ComPtr Buffer; +}; +#endif +//--------------------------------------------------------------------------- namespace ZenLib { @@ -159,7 +190,11 @@ File::File() #ifdef ZENLIB_STANDARD File_Handle=NULL; #elif defined WINDOWS - File_Handle=INVALID_HANDLE_VALUE; + #ifdef WINDOWS_UWP + File_Handle=NULL; + #else + File_Handle=INVALID_HANDLE_VALUE; + #endif #endif #endif //ZENLIB_USEWX Position=(int64u)-1; @@ -174,7 +209,11 @@ File::File(Ztring File_Name, access_t Access) #ifdef ZENLIB_STANDARD File_Handle=NULL; #elif defined WINDOWS - File_Handle=INVALID_HANDLE_VALUE; + #ifdef WINDOWS_UWP + File_Handle=NULL; + #else + File_Handle=INVALID_HANDLE_VALUE; + #endif #endif #endif //ZENLIB_USEWX Position=(int64u)-1; @@ -223,7 +262,7 @@ bool File::Open (const tstring &File_Name_, access_t Access) case Access_Write : access=O_BINARY|O_WRONLY|O_CREAT|O_TRUNC ; break; case Access_Read_Write : access=O_BINARY|O_RDWR |O_CREAT ; break; case Access_Write_Append : access=O_BINARY|O_WRONLY|O_CREAT|O_APPEND ; break; - default : access=0 ; break; + default : access=0 ; } #ifdef UNICODE File_Handle=open(File_Name.To_Local().c_str(), access); @@ -235,7 +274,6 @@ bool File::Open (const tstring &File_Name_, access_t Access) ios_base::openmode mode; switch (Access) { - case Access_Read : mode=ios_base::binary|ios_base::in; break; case Access_Write : mode=ios_base::binary|ios_base::in|ios_base::out; break; case Access_Read_Write : mode=ios_base::binary|ios_base::in|ios_base::out; break; case Access_Write_Append : if (!Exists(File_Name)) @@ -243,7 +281,7 @@ bool File::Open (const tstring &File_Name_, access_t Access) else mode=ios_base::binary|ios_base::out|ios_base::app; break; - default : ; + default : mode = ios_base::binary | ios_base::in; } #ifdef UNICODE File_Handle=new fstream(File_Name.To_Local().c_str(), mode); @@ -257,64 +295,138 @@ bool File::Open (const tstring &File_Name_, access_t Access) } return true; #elif defined WINDOWS - DWORD dwDesiredAccess, dwShareMode, dwCreationDisposition; - switch (Access) - { - case Access_Read : dwDesiredAccess=FILE_READ_DATA; dwShareMode=FILE_SHARE_READ|FILE_SHARE_WRITE; dwCreationDisposition=OPEN_EXISTING; break; - case Access_Write : dwDesiredAccess=GENERIC_WRITE; dwShareMode=FILE_SHARE_READ|FILE_SHARE_WRITE; dwCreationDisposition=OPEN_ALWAYS; break; - case Access_Read_Write : dwDesiredAccess=FILE_READ_DATA|GENERIC_WRITE; dwShareMode=FILE_SHARE_READ|FILE_SHARE_WRITE; dwCreationDisposition=OPEN_ALWAYS; break; - case Access_Write_Append : dwDesiredAccess = FILE_APPEND_DATA; dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; dwCreationDisposition = OPEN_ALWAYS; break; - default : dwDesiredAccess=0; dwShareMode=0; dwCreationDisposition=0; break; - } + #ifdef WINDOWS_UWP + File_Handle=new WrtFile(); - #ifdef UNICODE - File_Handle=CreateFileW(File_Name.c_str(), dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, 0, NULL); + FileAccessMode Desired_Mode; + StorageOpenOptions Share_Mode; + switch (Access) + { + case Access_Read: Desired_Mode=FileAccessMode_Read; Share_Mode=StorageOpenOptions_AllowReadersAndWriters; break; + case Access_Write: + case Access_Read_Write: + case Access_Write_Append: Desired_Mode=FileAccessMode_ReadWrite; Share_Mode=StorageOpenOptions_AllowReadersAndWriters; break; + default: Desired_Mode=FileAccessMode_Read; Share_Mode=StorageOpenOptions_None; + } + + // Ensure all slashs are converted to backslashs (WinRT file API don't like slashs) + File_Name.FindAndReplace(__T("/"), __T("\\")); + + if (FAILED(Get_File(HStringReference(File_Name.c_str(), (unsigned int)File_Name.size()), ((WrtFile*)File_Handle)->File))) + { + if (Access==Access_Write || Access==Access_Read_Write || Access==Access_Write_Append) + { + if (!Create(File_Name, false)) + { + ZENLIB_DEBUG2("File Open", Debug += ", returns 0";) + return false; + } + + if (Access==Access_Write_Append) + { + Size_Get(); + if (FAILED(((WrtFile*)File_Handle)->Buffer->Seek(Size))) + { + ZENLIB_DEBUG2("File Open", Debug += ", returns 0";) + return false; + } + } + + return true; + } + + ZENLIB_DEBUG2("File Open", Debug += ", returns 0";) + return false; + } + + //IStorageFile don't provide OpenWithOptionsAsync + ComPtr File2; + if (FAILED(((WrtFile*)File_Handle)->File->QueryInterface(IID_PPV_ARGS(&File2))) || !File2) + { + ZENLIB_DEBUG2("File Open", Debug += ", returns 0";) + return false; + } + + ComPtr > Async_Open; + if (FAILED(File2->OpenWithOptionsAsync(Desired_Mode, Share_Mode, &Async_Open)) || + FAILED(Await(Async_Open)) || + FAILED(Async_Open->GetResults(&((WrtFile*)File_Handle)->Buffer)) + || !((WrtFile*)File_Handle)->Buffer) + { + ZENLIB_DEBUG2("File Open", Debug += ", returns 0";) + return false; + } + + if (Access==Access_Write_Append) + { + Size_Get(); + if (FAILED(((WrtFile*)File_Handle)->Buffer->Seek(Size))) + { + ZENLIB_DEBUG2("File Open", Debug += ", returns 0";) + return false; + } + } + else + Position=0; #else - File_Handle=CreateFile(File_Name.c_str(), dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, 0, NULL); - #endif //UNICODE - #if 0 //Disabled - if (File_Handle==INVALID_HANDLE_VALUE) - { - //Sometimes the file is locked for few milliseconds, we try again later - DWORD dw = GetLastError(); - if (dw!=ERROR_FILE_NOT_FOUND) + DWORD dwDesiredAccess, dwShareMode, dwCreationDisposition; + switch (Access) { - /* - char lpMsgBuf[1000]; - FormatMessageA( - FORMAT_MESSAGE_FROM_SYSTEM, - NULL, - dw, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - lpMsgBuf, - 1000, NULL ); - */ - Sleep(1000); - #ifdef UNICODE - File_Handle=CreateFileW(File_Name.c_str(), dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, 0, NULL); - #else - File_Handle=CreateFile(File_Name.c_str(), dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, 0, NULL); - #endif //UNICODE + case Access_Read : dwDesiredAccess=FILE_READ_DATA; dwShareMode=FILE_SHARE_READ|FILE_SHARE_WRITE; dwCreationDisposition=OPEN_EXISTING; break; + case Access_Write : dwDesiredAccess=GENERIC_WRITE; dwShareMode=FILE_SHARE_READ|FILE_SHARE_WRITE; dwCreationDisposition=OPEN_ALWAYS; break; + case Access_Read_Write : dwDesiredAccess=FILE_READ_DATA|GENERIC_WRITE; dwShareMode=FILE_SHARE_READ|FILE_SHARE_WRITE; dwCreationDisposition=OPEN_ALWAYS; break; + case Access_Write_Append : dwDesiredAccess = FILE_APPEND_DATA; dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; dwCreationDisposition = OPEN_ALWAYS; break; + default : dwDesiredAccess=0; dwShareMode=0; dwCreationDisposition=0; break; } - } - #endif //0 - if (File_Handle==INVALID_HANDLE_VALUE) - { - ZENLIB_DEBUG2( "File Open", - Debug+=", returns 0";) - //File is not openable - return false; - } + #ifdef UNICODE + File_Handle=CreateFileW(File_Name.c_str(), dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, 0, NULL); + #else + File_Handle=CreateFile(File_Name.c_str(), dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, 0, NULL); + #endif //UNICODE + #if 0 //Disabled + if (File_Handle==INVALID_HANDLE_VALUE) + { + //Sometimes the file is locked for few milliseconds, we try again later + DWORD dw = GetLastError(); + if (dw!=ERROR_FILE_NOT_FOUND) + { + /* + char lpMsgBuf[1000]; + FormatMessageA( + FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + dw, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + lpMsgBuf, + 1000, NULL ); + */ + Sleep(1000); + #ifdef UNICODE + File_Handle=CreateFileW(File_Name.c_str(), dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, 0, NULL); + #else + File_Handle=CreateFile(File_Name.c_str(), dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, 0, NULL); + #endif //UNICODE + } + } + #endif //0 + if (File_Handle==INVALID_HANDLE_VALUE) + { + ZENLIB_DEBUG2( "File Open", + Debug+=", returns 0";) - ZENLIB_DEBUG2( "File Open", - Debug+=", returns 1";) + //File is not openable + return false; + } - if (Access==Access_Write_Append) - Size_Get(); - else - Position=0; + ZENLIB_DEBUG2( "File Open", + Debug+=", returns 1";) + if (Access == Access_Write_Append) + Size_Get(); + else + Position = 0; + #endif return true; #endif #endif //ZENLIB_USEWX @@ -378,45 +490,89 @@ bool File::Create (const Ztring &File_Name_, bool OverWrite) #endif //UNICODE return ((fstream*)File_Handle)->is_open(); #elif defined WINDOWS - DWORD dwDesiredAccess, dwShareMode, dwCreationDisposition; - if (OverWrite) { - dwDesiredAccess=GENERIC_WRITE; - dwCreationDisposition=CREATE_ALWAYS; - } else { - dwDesiredAccess=GENERIC_WRITE; - dwCreationDisposition=CREATE_NEW; - } - dwShareMode=0; + #ifdef WINDOWS_UWP + File_Handle=new WrtFile(); - #ifdef UNICODE - File_Handle=CreateFileW(File_Name.c_str(), dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, 0, NULL); + FileAccessMode Desired_Mode=FileAccessMode_ReadWrite; + StorageOpenOptions Share_Mode=StorageOpenOptions_AllowReadersAndWriters; + CreationCollisionOption Collision_Option=CreationCollisionOption_FailIfExists; + if (OverWrite) + Collision_Option=CreationCollisionOption_ReplaceExisting; + + //Ensure all slashs are converted to backslashs (WinRT file API don't like slashs) + File_Name.FindAndReplace(__T("/"), __T("\\")); + + //Split file and folder + tstring Destination_Dir=FileName::Path_Get(File_Name); + tstring Destination_File=FileName::Name_Get(File_Name); + + //Open dst folder + ComPtr Folder; + if (FAILED(Get_Folder(HStringReference(Destination_Dir.c_str(), (unsigned int)Destination_Dir.size()), Folder))) + return false; + + //Create file + ComPtr > Async_Create; + ComPtr File; + if (FAILED(Folder->CreateFileAsync(HStringReference(Destination_File.c_str(), (unsigned int)Destination_File.size()).Get(), Collision_Option, &Async_Create)) || + FAILED(Await(Async_Create)) || + FAILED(Async_Create->GetResults(&((WrtFile*)File_Handle)->File)) || + !((WrtFile*)File_Handle)->File) + return false; + + //IStorageFile don't provide OpenWithOptionsAsync + ComPtr File2; + if (FAILED(((WrtFile*)File_Handle)->File->QueryInterface(IID_PPV_ARGS(&File2))) || !File2) + return false; + + ComPtr > Async_Open_File; + if (FAILED(File2->OpenWithOptionsAsync(Desired_Mode, Share_Mode, &Async_Open_File)) || + FAILED(Await(Async_Open_File)) || + FAILED(Async_Open_File->GetResults(&((WrtFile*)File_Handle)->Buffer)) || + !((WrtFile*)File_Handle)->Buffer) + return false; + + return true; #else - File_Handle=CreateFile(File_Name.c_str(), dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, 0, NULL); - #endif //UNICODE - #if 0 //Disabled - if (File_Handle==INVALID_HANDLE_VALUE) - { - //Sometime the file is locked for few milliseconds, we try again later - Sleep(3000); + DWORD dwDesiredAccess, dwShareMode, dwCreationDisposition; + if (OverWrite) { + dwDesiredAccess=GENERIC_WRITE; + dwCreationDisposition=CREATE_ALWAYS; + } else { + dwDesiredAccess=GENERIC_WRITE; + dwCreationDisposition=CREATE_NEW; + } + dwShareMode=0; + #ifdef UNICODE File_Handle=CreateFileW(File_Name.c_str(), dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, 0, NULL); #else File_Handle=CreateFile(File_Name.c_str(), dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, 0, NULL); #endif //UNICODE - } - #endif //0 - if (File_Handle==INVALID_HANDLE_VALUE) - { - ZENLIB_DEBUG2( "File Create", - Debug+=", returns 0";) - - //File is not openable - return false; - } + #if 0 //Disabled + if (File_Handle==INVALID_HANDLE_VALUE) + { + //Sometime the file is locked for few milliseconds, we try again later + Sleep(3000); + #ifdef UNICODE + File_Handle=CreateFileW(File_Name.c_str(), dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, 0, NULL); + #else + File_Handle=CreateFile(File_Name.c_str(), dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, 0, NULL); + #endif //UNICODE + } + #endif //0 + if (File_Handle==INVALID_HANDLE_VALUE) + { + ZENLIB_DEBUG2( "File Create", + Debug+=", returns 0";) - ZENLIB_DEBUG2( "File Create", - Debug+=", returns 1";) + //File is not openable + return false; + } + ZENLIB_DEBUG2( "File Create", + Debug+=", returns 1";) + #endif return true; #endif #endif //ZENLIB_USEWX @@ -433,7 +589,11 @@ void File::Close () #ifdef ZENLIB_STANDARD if (File_Handle!=NULL) #elif defined WINDOWS - if (File_Handle!=INVALID_HANDLE_VALUE) + #ifdef WINDOWS_UWP + if (File_Handle) + #else + if (File_Handle!=INVALID_HANDLE_VALUE) + #endif #endif #endif //ZENLIB_USEWX { @@ -450,7 +610,11 @@ void File::Close () //close(File_Handle); File_Handle=-1; delete (fstream*)File_Handle; File_Handle=NULL; #elif defined WINDOWS - CloseHandle(File_Handle); File_Handle=INVALID_HANDLE_VALUE; + #ifdef WINDOWS_UWP + delete(WrtFile*)File_Handle; File_Handle=NULL; + #else + CloseHandle(File_Handle); File_Handle=INVALID_HANDLE_VALUE; + #endif #endif #endif //ZENLIB_USEWX Position=(int64u)-1; @@ -472,16 +636,21 @@ void File::Close () //--------------------------------------------------------------------------- size_t File::Read (int8u* Buffer, size_t Buffer_Size_Max) { - ZENLIB_DEBUG1( "File Read", - Debug+=", File_Name="; Debug+=Ztring(File_Name).To_UTF8(); Debug+=", MaxSize="; Debug +=Ztring::ToZtring(Buffer_Size_Max).To_UTF8()) + ZENLIB_DEBUG1("File Read", + Debug += ", File_Name="; Debug += Ztring(File_Name).To_UTF8(); Debug += ", MaxSize="; Debug += Ztring::ToZtring(Buffer_Size_Max).To_UTF8()) - #ifdef ZENLIB_USEWX - if (File_Handle==NULL) - #else //ZENLIB_USEWX - #ifdef ZENLIB_STANDARD - if (File_Handle==NULL) +#ifdef ZENLIB_USEWX + if (File_Handle == NULL) +#else //ZENLIB_USEWX + #ifdef ZENLIB_STANDARD + if (File_Handle == NULL) #elif defined WINDOWS - if (File_Handle==INVALID_HANDLE_VALUE) + #ifdef WINDOWS_UWP + boolean Can_Read=FALSE; + if (!File_Handle || !((WrtFile*)File_Handle)->Buffer || FAILED(((WrtFile*)File_Handle)->Buffer->get_CanRead(&Can_Read)) || !Can_Read) + #else + if (File_Handle == INVALID_HANDLE_VALUE) + #endif #endif #endif //ZENLIB_USEWX return 0; @@ -504,22 +673,51 @@ size_t File::Read (int8u* Buffer, size_t Buffer_Size_Max) Position+=ByteRead; return ByteRead; #elif defined WINDOWS - DWORD Buffer_Size; - if (ReadFile(File_Handle, Buffer, (DWORD)Buffer_Size_Max, &Buffer_Size, NULL)) - { - Position+=Buffer_Size; + #ifdef WINDOWS_UWP + ComPtr Stream; + if (FAILED(((WrtFile*)File_Handle)->Buffer->QueryInterface(IID_PPV_ARGS(&Stream))) || !Stream) + return 0; - ZENLIB_DEBUG2( "File Read", - Debug+=", new position ";Debug+=Ztring::ToZtring(Position).To_UTF8();;Debug+=", returns ";Debug+=Ztring::ToZtring((int64u)Buffer_Size).To_UTF8();) + ComPtr Reader_Factory; + if (FAILED(GetActivationFactory(HStringReference(RuntimeClass_Windows_Storage_Streams_DataReader).Get(), &Reader_Factory)) || !Reader_Factory) + return 0; - return Buffer_Size; - } - else - { - ZENLIB_DEBUG2( "File Read", - Debug+=", returns 0";) - return 0; - } + ComPtr Reader; + if (FAILED(Reader_Factory->CreateDataReader(*Stream.GetAddressOf(), &Reader)) || !Reader) + return 0; + + UINT32 Readed=0; + ComPtr > Async_Read; + if (FAILED(Reader->LoadAsync((UINT32)Buffer_Size_Max, &Async_Read)) || + FAILED(Await(Async_Read)) || + FAILED(Async_Read->GetResults(&Readed))) + return 0; + + if (FAILED(Reader->ReadBytes((UINT32)Buffer_Size_Max, (BYTE*)Buffer))) + return 0; + + Reader->DetachStream(&Stream); + + return (size_t)Readed; + #else + DWORD Buffer_Size; + if (ReadFile(File_Handle, Buffer, (DWORD)Buffer_Size_Max, &Buffer_Size, NULL)) + { + if (Position!=(int64u)-1) + Position+=Buffer_Size; + + ZENLIB_DEBUG2( "File Read", + Debug+=", new position ";Debug+=Ztring::ToZtring(Position).To_UTF8();;Debug+=", returns ";Debug+=Ztring::ToZtring((int64u)Buffer_Size).To_UTF8();) + + return Buffer_Size; + } + else + { + ZENLIB_DEBUG2( "File Read", + Debug+=", returns 0";) + return 0; + } + #endif #endif #endif //ZENLIB_USEWX } @@ -533,7 +731,12 @@ size_t File::Write (const int8u* Buffer, size_t Buffer_Size) #ifdef ZENLIB_STANDARD if (File_Handle==NULL) #elif defined WINDOWS - if (File_Handle==INVALID_HANDLE_VALUE) + #ifdef WINDOWS_UWP + boolean Can_Write=FALSE; + if (!File_Handle || !((WrtFile*)File_Handle)->Buffer || FAILED(((WrtFile*)File_Handle)->Buffer->get_CanWrite(&Can_Write)) || !Can_Write) + #else + if (File_Handle==INVALID_HANDLE_VALUE) + #endif #endif #endif //ZENLIB_USEWX return 0; @@ -556,18 +759,46 @@ size_t File::Write (const int8u* Buffer, size_t Buffer_Size) return Buffer_Size; } #elif defined WINDOWS - DWORD Buffer_Size_Written; - if (WriteFile(File_Handle, Buffer, (DWORD)Buffer_Size, &Buffer_Size_Written, NULL)) - { - if (Position!=(int64u)-1) - Position+=Buffer_Size_Written; - return Buffer_Size_Written; - } - else - { - Position=(int64u)-1; - return 0; - } + #ifdef WINDOWS_UWP + ComPtr Stream; + if (FAILED(((WrtFile*)File_Handle)->Buffer->QueryInterface(IID_PPV_ARGS(&Stream))) || !Stream) + return 0; + + ComPtr Writer_Factory; + if (FAILED(GetActivationFactory(HStringReference(RuntimeClass_Windows_Storage_Streams_DataWriter).Get(), &Writer_Factory)) || !Writer_Factory) + return 0; + + ComPtr Writer; + if (FAILED(Writer_Factory->CreateDataWriter(*Stream.GetAddressOf(), &Writer)) || !Writer) + return 0; + + if (FAILED(Writer->WriteBytes((UINT32)Buffer_Size, (BYTE*)Buffer))) + return 0; + + UINT32 Written=0; + ComPtr > Async_Write; + if (FAILED(Writer->StoreAsync(&Async_Write)) || + FAILED(Await(Async_Write)) || + FAILED(Async_Write->GetResults(&Written))) + return 0; + + Writer->DetachStream(&Stream); + + return (size_t)Written; + #else + DWORD Buffer_Size_Written; + if (WriteFile(File_Handle, Buffer, (DWORD)Buffer_Size, &Buffer_Size_Written, NULL)) + { + if (Position!=(int64u)-1) + Position+=Buffer_Size_Written; + return Buffer_Size_Written; + } + else + { + Position=(int64u)-1; + return 0; + } + #endif #endif #endif //ZENLIB_USEWX } @@ -586,22 +817,50 @@ bool File::Truncate (int64u Offset) return false; //Not supported #else //defined(WINDOWS) //Need to close the file, use truncate, reopen it + #if !defined(__ANDROID_API__) || __ANDROID_API__ >= 21 if (Offset==(int64u)-1) Offset=Position_Get(); Ztring File_Name_Sav=File_Name; Close(); - truncate(File_Name_Sav.To_Local().c_str(), Offset); + if (truncate(File_Name_Sav.To_Local().c_str(), Offset)) + return false; if (!Open(File_Name_Sav, Access_Read_Write)) return false; GoTo(0, FromEnd); return true; + #else + return false; //Not supported + #endif #endif //!defined(WINDOWS) #elif defined WINDOWS - if(Offset!=(int64u)-1 && Offset!=Position_Get()) - if (!GoTo(Offset)) + #ifdef WINDOWS_UWP + boolean Can_Write=FALSE; + if (!((WrtFile*)File_Handle)->Buffer || FAILED(((WrtFile*)File_Handle)->Buffer->get_CanWrite(&Can_Write)) || !Can_Write) return false; - SetEndOfFile(File_Handle); - return true; + + ComPtr Stream; + if (FAILED(((WrtFile*)File_Handle)->Buffer->QueryInterface(IID_PPV_ARGS(&Stream))) || !Stream) + return false; + + if (Offset==(int64u)-1) + { + if (FAILED(((WrtFile*)File_Handle)->Buffer->put_Size((UINT64)Position_Get()))) + return false; + } + else + { + if (FAILED(((WrtFile*)File_Handle)->Buffer->put_Size((UINT64)Offset))) + return false; + } + + return true; + #else + if(Offset!=(int64u)-1 && Offset!=Position_Get()) + if (!GoTo(Offset)) + return false; + SetEndOfFile(File_Handle); + return true; + #endif #endif #endif //ZENLIB_USEWX } @@ -629,7 +888,11 @@ bool File::GoTo (int64s Position_ToMove, move_t MoveMethod) #ifdef ZENLIB_STANDARD if (File_Handle==NULL) #elif defined WINDOWS - if (File_Handle==INVALID_HANDLE_VALUE) + #ifdef WINDOWS_UWP + if (!File_Handle || !((WrtFile*)File_Handle)->File || !((WrtFile*)File_Handle)->Buffer) + #else + if (File_Handle==INVALID_HANDLE_VALUE) + #endif #endif #endif //ZENLIB_USEWX return false; @@ -661,18 +924,34 @@ bool File::GoTo (int64s Position_ToMove, move_t MoveMethod) ((fstream*)File_Handle)->seekg((streamoff)Position_ToMove, dir); return !((fstream*)File_Handle)->fail(); #elif defined WINDOWS - LARGE_INTEGER GoTo; - GoTo.QuadPart=Position_ToMove; - BOOL i=SetFilePointerEx(File_Handle, GoTo, NULL, MoveMethod); + #ifdef WINDOWS_UWP + UINT64 New_Position=0; + switch (MoveMethod) + { + case FromBegin : New_Position=Position_ToMove; break; + case FromCurrent : New_Position=Position_Get()+Position_ToMove; break; + case FromEnd : New_Position=Size_Get()-Position_ToMove; break; + default : New_Position=Position_ToMove; + } - #ifdef ZENLIB_DEBUG - LARGE_INTEGER Temp; Temp.QuadPart=0; - SetFilePointerEx(File_Handle, Temp, &Temp, FILE_CURRENT); - ZENLIB_DEBUG2( "File GoTo", - Debug+=", new position ";Debug+=Ztring::ToZtring(Temp.QuadPart).To_UTF8();Debug+=", returns ";Debug+=i?'1':'0';) - #endif //ZENLIB_DEBUG + if (FAILED(((WrtFile*)File_Handle)->Buffer->Seek(New_Position))) + return false; - return i?true:false; + return true; + #else + LARGE_INTEGER GoTo; + GoTo.QuadPart=Position_ToMove; + BOOL i=SetFilePointerEx(File_Handle, GoTo, NULL, MoveMethod); + + #ifdef ZENLIB_DEBUG + LARGE_INTEGER Temp; Temp.QuadPart=0; + SetFilePointerEx(File_Handle, Temp, &Temp, FILE_CURRENT); + ZENLIB_DEBUG2( "File GoTo", + Debug+=", new position ";Debug+=Ztring::ToZtring(Temp.QuadPart).To_UTF8();Debug+=", returns ";Debug+=i?'1':'0';) + #endif //ZENLIB_DEBUG + + return i?true:false; + #endif #endif #endif //ZENLIB_USEWX } @@ -692,7 +971,11 @@ int64u File::Position_Get () #ifdef ZENLIB_STANDARD if (File_Handle==NULL) #elif defined WINDOWS - if (File_Handle==INVALID_HANDLE_VALUE) + #ifdef WINDOWS_UWP + if (!File_Handle || !((WrtFile*)File_Handle)->File || !((WrtFile*)File_Handle)->Buffer) + #else + if (File_Handle == INVALID_HANDLE_VALUE) + #endif #endif #endif //ZENLIB_USEWX return (int64u)-1; @@ -704,13 +987,17 @@ int64u File::Position_Get () Position=((fstream*)File_Handle)->tellg(); return Position; #elif defined WINDOWS - LARGE_INTEGER GoTo; GoTo.QuadPart=0; - GoTo.LowPart=SetFilePointer(File_Handle, GoTo.LowPart, &GoTo.HighPart, FILE_CURRENT); - Position=GoTo.QuadPart; - - ZENLIB_DEBUG2( "File GoTo", - Debug+=", new position ";Debug+=Ztring::ToZtring(GoTo.QuadPart).To_UTF8();Debug+=", returns 1";) + #ifdef WINDOWS_UWP + if (FAILED(((WrtFile*)File_Handle)->Buffer->get_Position((UINT64*)&Position))) + return (int64u)-1; + #else + LARGE_INTEGER GoTo; GoTo.QuadPart=0; + GoTo.LowPart=SetFilePointer(File_Handle, GoTo.LowPart, &GoTo.HighPart, FILE_CURRENT); + Position=GoTo.QuadPart; + ZENLIB_DEBUG2( "File GoTo", + Debug+=", new position ";Debug+=Ztring::ToZtring(GoTo.QuadPart).To_UTF8();Debug+=", returns 1";) + #endif return Position; #endif #endif //ZENLIB_USEWX @@ -729,7 +1016,11 @@ int64u File::Size_Get() #ifdef ZENLIB_STANDARD if (File_Handle==NULL) #elif defined WINDOWS - if (File_Handle==INVALID_HANDLE_VALUE) + #ifdef WINDOWS_UWP + if (!File_Handle || !((WrtFile*)File_Handle)->File) + #else + if (File_Handle==INVALID_HANDLE_VALUE) + #endif #endif #endif //ZENLIB_USEWX return 0; @@ -754,13 +1045,30 @@ int64u File::Size_Get() else Size=(int64u)-1; #elif defined WINDOWS + #ifdef WINDOWS_UWP + ComPtr Item; + if (FAILED(((WrtFile*)File_Handle)->File->QueryInterface(IID_PPV_ARGS(&Item))) || !Item) + return (int64u)-1; + + ComPtr > Async_Properties; + ComPtr Properties; + if (FAILED(Item->GetBasicPropertiesAsync(&Async_Properties)) || + FAILED(Await(Async_Properties)) || + FAILED(Async_Properties->GetResults(&Properties)) || + !Properties) + return (int64u)-1; + + if (FAILED(Properties->get_Size(&Size))) + return (int64u)-1; + #else LARGE_INTEGER x = {0}; BOOL bRet = ::GetFileSizeEx(File_Handle, &x); if (bRet == FALSE) return (int64u)-1; Size=x.QuadPart; + #endif #endif - return Size; + return Size; #endif //ZENLIB_USEWX } @@ -773,7 +1081,11 @@ Ztring File::Created_Get() #ifdef ZENLIB_STANDARD if (File_Handle==NULL) #elif defined WINDOWS - if (File_Handle==INVALID_HANDLE_VALUE) + #ifdef WINDOWS_UWP + if (!File_Handle || !((WrtFile*)File_Handle)->File) + #else + if (File_Handle==INVALID_HANDLE_VALUE) + #endif #endif #endif //ZENLIB_USEWX return Ztring(); @@ -782,7 +1094,7 @@ Ztring File::Created_Get() return __T(""); //Not implemented #else //ZENLIB_USEWX #ifdef ZENLIB_STANDARD - #if defined LINUX && defined STATX_BTIME + #if defined(LINUX) && defined(LINUX_STATX) struct statx Stat; int Result=statx(AT_FDCWD, File_Name.To_Local().c_str(), AT_STATX_SYNC_AS_STAT, STATX_BTIME, &Stat); if (Result<0) @@ -798,17 +1110,29 @@ Ztring File::Created_Get() return Time; #else return __T(""); //Not implemented - #endif //defined LINUX && defined STATX_BTIME + #endif //defined(LINUX) && defined(LINUX_STATX) #elif defined WINDOWS - FILETIME TimeFT; - if (GetFileTime(File_Handle, &TimeFT, NULL, NULL)) - { - int64u Time64=0x100000000ULL*TimeFT.dwHighDateTime+TimeFT.dwLowDateTime; - Ztring Time; Time.Date_From_Milliseconds_1601(Time64/10000); - return Time; - } - else - return __T(""); //There was a problem + #ifdef WINDOWS_UWP + ComPtr Item; + if (FAILED(((WrtFile*)File_Handle)->File->QueryInterface(IID_PPV_ARGS(&Item))) || !Item) + return __T(""); + + DateTime Time; + if (FAILED(Item->get_DateCreated(&Time))) + return __T(""); + + return Ztring().Date_From_Milliseconds_1601((int64u)(Time.UniversalTime/10000)); + #else + FILETIME TimeFT; + if (GetFileTime(File_Handle, &TimeFT, NULL, NULL)) + { + int64u Time64=0x100000000ULL*TimeFT.dwHighDateTime+TimeFT.dwLowDateTime; + Ztring Time; Time.Date_From_Milliseconds_1601(Time64/10000); + return Time; + } + else + return __T(""); //There was a problem + #endif #endif #endif //ZENLIB_USEWX } @@ -842,7 +1166,11 @@ Ztring File::Created_Local_Get() #ifdef ZENLIB_STANDARD if (File_Handle==NULL) #elif defined WINDOWS - if (File_Handle==INVALID_HANDLE_VALUE) + #ifdef WINDOWS_UWP + if (!File_Handle || !((WrtFile*)File_Handle)->File) + #else + if (File_Handle==INVALID_HANDLE_VALUE) + #endif #endif #endif //ZENLIB_USEWX return Ztring(); @@ -850,8 +1178,8 @@ Ztring File::Created_Local_Get() #ifdef ZENLIB_USEWX return __T(""); //Not implemented #else //ZENLIB_USEWX - #if defined ZENLIB_STANDARD - #if defined LINUX && defined STATX_BTIME + #ifdef ZENLIB_STANDARD + #if defined(LINUX) && defined(LINUX_STATX) struct statx Stat; int Result=statx(AT_FDCWD, File_Name.To_Local().c_str(), AT_STATX_SYNC_AS_STAT, STATX_BTIME, &Stat); if (Result<0) @@ -867,15 +1195,33 @@ Ztring File::Created_Local_Get() return Time; #else return __T(""); //Not implemented - #endif //defined LINUX && defined STATX_BTIME + #endif //defined(LINUX) && defined(LINUX_STATX) #elif defined WINDOWS - FILETIME TimeFT; - if (GetFileTime(File_Handle, &TimeFT, NULL, NULL)) - { - return Calc_Time(TimeFT); - } - else - return __T(""); //There was a problem + #ifdef WINDOWS_UWP + ComPtr Item; + if (FAILED(((WrtFile*)File_Handle)->File->QueryInterface(IID_PPV_ARGS(&Item))) || !Item) + return __T(""); + + DateTime Time; + if (FAILED(Item->get_DateCreated(&Time))) + return __T(""); + + FILETIME File_Time; + ULARGE_INTEGER Time_Union; + Time_Union.QuadPart=(ULONGLONG)Time.UniversalTime; + File_Time.dwHighDateTime=Time_Union.HighPart; + File_Time.dwLowDateTime=Time_Union.LowPart; + + return Calc_Time(File_Time); + #else + FILETIME TimeFT; + if (GetFileTime(File_Handle, &TimeFT, NULL, NULL)) + { + return Calc_Time(TimeFT); + } + else + return __T(""); //There was a problem + #endif #endif #endif //ZENLIB_USEWX } @@ -889,7 +1235,11 @@ Ztring File::Modified_Get() #ifdef ZENLIB_STANDARD if (File_Handle==NULL) #elif defined WINDOWS - if (File_Handle==INVALID_HANDLE_VALUE) + #ifdef WINDOWS_UWP + if (!File_Handle || !((WrtFile*)File_Handle)->File) + #else + if (File_Handle==INVALID_HANDLE_VALUE) + #endif #endif #endif //ZENLIB_USEWX return Ztring(); @@ -905,15 +1255,35 @@ Ztring File::Modified_Get() Ztring Time; Time.Date_From_Seconds_1970((int64s)Stat.st_mtime); return Time; #elif defined WINDOWS - FILETIME TimeFT; - if (GetFileTime(File_Handle, NULL, NULL, &TimeFT)) - { - int64u Time64=0x100000000ULL*TimeFT.dwHighDateTime+TimeFT.dwLowDateTime; - Ztring Time; Time.Date_From_Milliseconds_1601(Time64/10000); - return Time; - } - else - return __T(""); //There was a problem + #ifdef WINDOWS_UWP + ComPtr Item; + if (FAILED(((WrtFile*)File_Handle)->File->QueryInterface(IID_PPV_ARGS(&Item))) || !Item) + return __T(""); + + ComPtr > Async_Properties; + ComPtr Properties; + if (FAILED(Item->GetBasicPropertiesAsync(&Async_Properties)) || + FAILED(Await(Async_Properties)) || + FAILED(Async_Properties->GetResults(&Properties)) || + !Properties) + return __T(""); + + DateTime Time; + if (FAILED(Properties->get_DateModified(&Time)) || Time.UniversalTime==0) + return __T(""); + + return Ztring().Date_From_Milliseconds_1601((int64u)(Time.UniversalTime/10000)); + #else + FILETIME TimeFT; + if (GetFileTime(File_Handle, NULL, NULL, &TimeFT)) + { + int64u Time64=0x100000000ULL*TimeFT.dwHighDateTime+TimeFT.dwLowDateTime; + Ztring Time; Time.Date_From_Milliseconds_1601(Time64/10000); + return Time; + } + else + return __T(""); //There was a problem + #endif #endif #endif //ZENLIB_USEWX } @@ -927,7 +1297,11 @@ Ztring File::Modified_Local_Get() #ifdef ZENLIB_STANDARD if (File_Handle==NULL) #elif defined WINDOWS - if (File_Handle==INVALID_HANDLE_VALUE) + #ifdef WINDOWS_UWP + if (!File_Handle || !((WrtFile*)File_Handle)->File) + #else + if (File_Handle==INVALID_HANDLE_VALUE) + #endif #endif #endif //ZENLIB_USEWX return Ztring(); @@ -943,13 +1317,39 @@ Ztring File::Modified_Local_Get() Ztring Time; Time.Date_From_Seconds_1970_Local(Stat.st_mtime); return Time; #elif defined WINDOWS - FILETIME TimeFT; - if (GetFileTime(File_Handle, NULL, NULL, &TimeFT)) - { - return Calc_Time(TimeFT); - } - else - return __T(""); //There was a problem + #ifdef WINDOWS_UWP + ComPtr Item; + if (FAILED(((WrtFile*)File_Handle)->File->QueryInterface(IID_PPV_ARGS(&Item))) || !Item) + return __T(""); + + ComPtr > Async_Properties; + ComPtr Properties; + if (FAILED(Item->GetBasicPropertiesAsync(&Async_Properties)) || + FAILED(Await(Async_Properties)) || + FAILED(Async_Properties->GetResults(&Properties)) || + !Properties) + return __T(""); + + DateTime Time; + if (FAILED(Properties->get_DateModified(&Time)) || Time.UniversalTime==0) + return __T(""); + + FILETIME File_Time; + ULARGE_INTEGER Time_Union; + Time_Union.QuadPart=(ULONGLONG)Time.UniversalTime; + File_Time.dwHighDateTime=Time_Union.HighPart; + File_Time.dwLowDateTime=Time_Union.LowPart; + + return Calc_Time(File_Time); + #else + FILETIME TimeFT; + if (GetFileTime(File_Handle, NULL, NULL, &TimeFT)) + { + return Calc_Time(TimeFT); + } + else + return __T(""); //There was a problem + #endif #endif #endif //ZENLIB_USEWX } @@ -964,7 +1364,11 @@ bool File::Opened_Get() //return File_Handle!=-1; return File_Handle!=NULL && ((fstream*)File_Handle)->is_open(); #elif defined WINDOWS - return File_Handle!=INVALID_HANDLE_VALUE; + #ifdef WINDOWS_UWP + return File_Handle && ((WrtFile*)File_Handle)->File && ((WrtFile*)File_Handle)->Buffer; + #else + return File_Handle!=INVALID_HANDLE_VALUE; + #endif #endif #endif //ZENLIB_USEWX } @@ -1020,16 +1424,52 @@ bool File::Exists(const Ztring &File_Name) #elif defined WINDOWS if (File_Name.find(__T('*'))!=std::string::npos || (File_Name.find(__T("\\\\?\\"))!=0 && File_Name.find(__T('?'))!=std::string::npos) || (File_Name.find(__T("\\\\?\\"))==0 && File_Name.find(__T('?'), 4)!=std::string::npos)) return false; - #ifdef UNICODE - DWORD FileAttributes=GetFileAttributesW(File_Name.c_str()); + #ifdef WINDOWS_UWP + //Ensure all slashs are converted to backslashs (WinRT file API don't like slashs) + Ztring File_Name_=File_Name; + File_Name_.FindAndReplace(__T("/"), __T("\\")); + + //Try to access file directly + ComPtr File; + if (SUCCEEDED(Get_File(HStringReference(File_Name_.c_str(), (unsigned int)File_Name_.size()), File))) + return true; + + //Try directory access methods + tstring Dir_=FileName::Path_Get(File_Name_); + tstring File_=FileName::Name_Get(File_Name_); + + ComPtr Folder; + if (FAILED(Get_Folder(HStringReference(Dir_.c_str(), (unsigned int)Dir_.size()), Folder))) + return false; + + //IStorageFolder don't provide TryGetItemAsync + ComPtr Folder2; + if (FAILED(Folder->QueryInterface(IID_PPV_ARGS(&Folder2))) || !Folder2) + return false; + + ComPtr > Async_GetItem; + ComPtr Item; + ComPtr AsFile; + if (SUCCEEDED(Folder2->TryGetItemAsync(HStringReference(File_.c_str(), (unsigned int)File_.size()).Get(), &Async_GetItem)) && + SUCCEEDED(Await(Async_GetItem)) && + SUCCEEDED(Async_GetItem->GetResults(&Item)) && + Item && + SUCCEEDED(Item.As(&AsFile))) + return true; + + return false; #else - DWORD FileAttributes=GetFileAttributes(File_Name.c_str()); - #endif //UNICODE + #ifdef UNICODE + DWORD FileAttributes=GetFileAttributesW(File_Name.c_str()); + #else + DWORD FileAttributes=GetFileAttributes(File_Name.c_str()); + #endif //UNICODE - ZENLIB_DEBUG2( "File Exists", - Debug+=", File_Name="; Debug+=Ztring::ToZtring(((FileAttributes!=INVALID_FILE_ATTRIBUTES) && !(FileAttributes&FILE_ATTRIBUTE_DIRECTORY))?1:0).To_UTF8()) + ZENLIB_DEBUG2( "File Exists", + Debug+=", File_Name="; Debug+=Ztring::ToZtring(((FileAttributes!=INVALID_FILE_ATTRIBUTES) && !(FileAttributes&FILE_ATTRIBUTE_DIRECTORY))?1:0).To_UTF8()) - return ((FileAttributes!=INVALID_FILE_ATTRIBUTES) && !(FileAttributes&FILE_ATTRIBUTE_DIRECTORY)); + return ((FileAttributes!=INVALID_FILE_ATTRIBUTES) && !(FileAttributes&FILE_ATTRIBUTE_DIRECTORY)); + #endif #endif #endif //ZENLIB_USEWX } @@ -1043,11 +1483,49 @@ bool File::Copy(const Ztring &Source, const Ztring &Destination, bool OverWrite) #ifdef ZENLIB_STANDARD return false; #elif defined WINDOWS - #ifdef UNICODE - return CopyFileW(Source.c_str(), Destination.c_str(), !OverWrite)!=0; + #ifdef WINDOWS_UWP + NameCollisionOption Collision_Option=NameCollisionOption_FailIfExists; + if (OverWrite) + Collision_Option=NameCollisionOption_ReplaceExisting; + + //Ensure all slashs are converted to backslashs (WinRT file API don't like slashs) + Ztring Source_=Source; + Source_.FindAndReplace(__T("/"), __T("\\")); + + Ztring Destination_=Destination; + Destination_.FindAndReplace(__T("/"), __T("\\")); + + //Split destination file and folder + tstring Destination_Dir=FileName::Path_Get(Destination_); + tstring Destination_File=FileName::Name_Get(Destination_); + + //Open src file + ComPtr File; + if (FAILED(Get_File(HStringReference(Source_.c_str(), (unsigned int)Source_.size()), File))) + return false; + + //Open dst folder + ComPtr Folder; + if (FAILED(Get_Folder(HStringReference(Destination_Dir.c_str(), (unsigned int)Destination_Dir.size()), Folder))) + return false; + + //Copy file + ComPtr > Async_Copy; + ComPtr New_File; + if (FAILED(File->CopyOverload(*Folder.GetAddressOf(), HStringReference(Destination_File.c_str(), (unsigned int)Destination_File.size()).Get(), Collision_Option, &Async_Copy)) || + FAILED(Await(Async_Copy)) || + FAILED(Async_Copy->GetResults(&New_File)) || + !New_File) + return false; + + return true; #else - return CopyFile(Source.c_str(), Destination.c_str(), !OverWrite)!=0; - #endif //UNICODE + #ifdef UNICODE + return CopyFileW(Source.c_str(), Destination.c_str(), !OverWrite)!=0; + #else + return CopyFile(Source.c_str(), Destination.c_str(), !OverWrite)!=0; + #endif //UNICODE + #endif #endif #endif //ZENLIB_USEWX } @@ -1065,11 +1543,47 @@ bool File::Move(const Ztring &Source, const Ztring &Destination, bool OverWrite) #ifdef ZENLIB_STANDARD return !std::rename(Source.To_Local().c_str(), Destination.To_Local().c_str()); #elif defined WINDOWS - #ifdef UNICODE - return MoveFileW(Source.c_str(), Destination.c_str())!=0; + #ifdef WINDOWS_UWP + NameCollisionOption Collision_Option=NameCollisionOption_FailIfExists; + if (OverWrite) + Collision_Option=NameCollisionOption_ReplaceExisting; + + //Ensure all slashs are converted to backslashs (WinRT file API don't like slashs) + Ztring Source_=Source; + Source_.FindAndReplace(__T("/"), __T("\\")); + + Ztring Destination_=Destination; + Destination_.FindAndReplace(__T("/"), __T("\\")); + + //Split destination file and folder + tstring Destination_Dir=FileName::Path_Get(Destination_); + tstring Destination_File=FileName::Name_Get(Destination_); + + //Open src file + ComPtr File; + if (FAILED(Get_File(HStringReference(Source_.c_str(), (unsigned int)Source_.size()), File))) + return false; + + //Open dst folder + ComPtr Folder; + if (FAILED(Get_Folder(HStringReference(Destination_Dir.c_str(), (unsigned int)Destination_Dir.size()), Folder))) + return false; + + //Move file + ComPtr Async_Move; + if (FAILED(File->MoveOverload(*Folder.GetAddressOf(), HStringReference(Destination_File.c_str(), (unsigned int)Destination_File.size()).Get(), Collision_Option, &Async_Move)) || + FAILED(Await(Async_Move)) || + FAILED(Async_Move->GetResults())) + return false; + + return true; #else - return MoveFile(Source.c_str(), Destination.c_str())!=0; - #endif //UNICODE + #ifdef UNICODE + return MoveFileExW(Source.c_str(), Destination.c_str(), 0)!=0; + #else + return MoveFileEx(Source.c_str(), Destination.c_str(), 0)!=0; + #endif //UNICODE + #endif #endif #endif //ZENLIB_USEWX } @@ -1087,11 +1601,33 @@ bool File::Delete(const Ztring &File_Name) return unlink(File_Name.c_str())==0; #endif //UNICODE #elif defined WINDOWS - #ifdef UNICODE - return DeleteFileW(File_Name.c_str())!=0; + #ifdef WINDOWS_UWP + //Ensure all slashs are converted to backslashs (WinRT file API don't like slashs) + Ztring File_Name_=File_Name; + File_Name_.FindAndReplace(__T("/"), __T("\\")); + + ComPtr File_; + if (FAILED(Get_File(HStringReference(File_Name_.c_str(), (unsigned int)File_Name_.size()), File_))) + return false; + + ComPtr Item; + if (FAILED(File_->QueryInterface(IID_PPV_ARGS(&Item))) || !Item) + return false; + + ComPtr Async_Delete; + if (FAILED(Item->DeleteAsync(StorageDeleteOption_Default, &Async_Delete)) || + FAILED(Await(Async_Delete)) || + FAILED(Async_Delete->GetResults())) + return false; + + return true; #else - return DeleteFile(File_Name.c_str())!=0; - #endif //UNICODE + #ifdef UNICODE + return DeleteFileW(File_Name.c_str())!=0; + #else + return DeleteFile(File_Name.c_str())!=0; + #endif //UNICODE + #endif #endif #endif //ZENLIB_USEWX } diff --git a/Source/ZenLib/File.h b/Source/ZenLib/File.h index 392e4af0..48be7a1e 100644 --- a/Source/ZenLib/File.h +++ b/Source/ZenLib/File.h @@ -17,6 +17,7 @@ //--------------------------------------------------------------------------- #include "ZenLib/Ztring.h" + //--------------------------------------------------------------------------- namespace ZenLib diff --git a/Source/ZenLib/FileName.cpp b/Source/ZenLib/FileName.cpp index d26784ca..2f48d6ac 100644 --- a/Source/ZenLib/FileName.cpp +++ b/Source/ZenLib/FileName.cpp @@ -190,11 +190,15 @@ Ztring FileName::TempFileName_Create(const Ztring &Prefix) if (!GetTempPath(MAX_PATH, Path)) return Ztring(); //Problem while getting a temp path - Char FileName[MAX_PATH+1]; - if (!GetTempFileName(Path, Prefix.c_str(), 0, FileName)) - return Ztring(); //Problem while getting a file name - - return Ztring(FileName); + #ifndef WINDOWS_GAMES + Char FileName[MAX_PATH+1]; + if (!GetTempFileName(Path, Prefix.c_str(), 0, FileName)) + return Ztring(); //Problem while getting a file name + + return Ztring(FileName); + #else // #ifdef WINDOWS_GAMES + return __T("D:\\xxx.txt"); + #endif // #ifdef WINDOWS_GAMES #else return __T("C:\\xxx.txt"); #endif diff --git a/Source/ZenLib/HTTP_Client.cpp b/Source/ZenLib/HTTP_Client.cpp index 2dabfe8a..1665e7eb 100644 --- a/Source/ZenLib/HTTP_Client.cpp +++ b/Source/ZenLib/HTTP_Client.cpp @@ -45,6 +45,8 @@ HTTP_Client::HTTP_Client () //--------------------------------------------------------------------------- HTTP_Client::~HTTP_Client () { + if (Handle) + Close(); #ifdef WINDOWS WSACleanup(); #endif @@ -115,7 +117,11 @@ Ztring HTTP_Client::Read () return Ztring(); } - Ztring ToReturn; ToReturn.From_Local(Buffer, Size); + Ztring ToReturn; + ToReturn.From_UTF8(Buffer, Size); + if (ToReturn.empty()) + ToReturn.From_Local(Buffer, Size); + delete[] Buffer; return ToReturn; } diff --git a/Source/ZenLib/InfoMap.cpp b/Source/ZenLib/InfoMap.cpp index 063ce53b..d091b2f3 100644 --- a/Source/ZenLib/InfoMap.cpp +++ b/Source/ZenLib/InfoMap.cpp @@ -38,14 +38,14 @@ const Ztring InfoMap_EmptyZtring_Const; //Use it when we can't return a referenc //--------------------------------------------------------------------------- // Constructors InfoMap::InfoMap() -: std::multimap () +: std::multimap (), Max() { Separator[0]=EOL; Separator[1]=__T(";"); } InfoMap::InfoMap(const Ztring &Source) -: std::multimap () +: std::multimap (), Max() { Separator[0]=EOL; Separator[1]=__T(";"); @@ -53,7 +53,7 @@ InfoMap::InfoMap(const Ztring &Source) } InfoMap::InfoMap(const Char *Source) -: std::multimap () +: std::multimap (), Max() { Separator[0]=EOL; Separator[1]=__T(";"); @@ -62,7 +62,7 @@ InfoMap::InfoMap(const Char *Source) #ifdef _UNICODE InfoMap::InfoMap (const char* S) -: std::multimap () +: std::multimap (), Max() { Separator[0]=EOL; Separator[1]=__T(";"); @@ -99,7 +99,7 @@ const Ztring &InfoMap::Get (const Ztring &Value, size_t Pos, const Ztring &WithV else { ++List; //The second one, this is a stupid hack for a 2 value, should be changed later... - if (Possecond.size()) + if (List!=end() && Possecond.size()) { if (List->second[WithValue_Pos]==WithValue) return List->second[Pos]; diff --git a/Source/ZenLib/OS_Utils.cpp b/Source/ZenLib/OS_Utils.cpp index 70598734..6aadf436 100644 --- a/Source/ZenLib/OS_Utils.cpp +++ b/Source/ZenLib/OS_Utils.cpp @@ -21,7 +21,27 @@ #ifdef WINDOWS #undef __TEXT #include - #include + #ifdef WINDOWS_UWP + #include + #include + #include + #include + #include + #include + #include + using namespace Microsoft::WRL; + using namespace Microsoft::WRL::Wrappers; + using namespace ABI::Windows::Foundation; + using namespace ABI::Windows::Foundation::Collections; + using namespace ABI::Windows::Storage; + using namespace ABI::Windows::Storage::AccessCache; + using namespace ABI::Windows::Storage::Streams; + using namespace ABI::Windows::Security::Cryptography; + using namespace ABI::Windows::Security::Cryptography::Core; + #else + #include + #include + #endif #endif #endif //ZENLIB_USEWX #include "ZenLib/OS_Utils.h" @@ -40,6 +60,173 @@ bool IsWin9X () return false; //Hardcoded value because we don't support Win9x anymore } +//*************************************************************************** +// WinRT Helpers +//*************************************************************************** + +#if defined(WINDOWS) && defined(WINDOWS_UWP) +//--------------------------------------------------------------------------- +HRESULT Add_Item_To_FUA(HStringReference Path, ComPtr &Item) +{ + ComPtr Path_Buffer; + ComPtr Hash_Buffer; + ComPtr Cryptographic_Buffer_Statics; + ComPtr Hash_Provider_Statics; + ComPtr Hash_Provider; + UINT32 Buffer_Lenght = 0; + UINT32 Hash_Lenght = 0; + HString Path_Hash; + + if (SUCCEEDED(GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Security_Cryptography_CryptographicBuffer).Get(), &Cryptographic_Buffer_Statics)) && + Cryptographic_Buffer_Statics && + SUCCEEDED(Cryptographic_Buffer_Statics->ConvertStringToBinary(Path.Get(), BinaryStringEncoding_Utf16LE, &Path_Buffer)) && + Path_Buffer && + SUCCEEDED(GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Security_Cryptography_Core_HashAlgorithmProvider).Get(), &Hash_Provider_Statics)) && + Hash_Provider_Statics && + SUCCEEDED(Hash_Provider_Statics->OpenAlgorithm(HString::MakeReference(L"SHA256").Get(), &Hash_Provider)) && + Hash_Provider && + SUCCEEDED(Hash_Provider->HashData(*Path_Buffer.GetAddressOf(), &Hash_Buffer)) && + Hash_Buffer && + SUCCEEDED(Hash_Buffer->get_Length(&Buffer_Lenght)) && + Buffer_Lenght && + SUCCEEDED(Hash_Provider->get_HashLength(&Hash_Lenght)) && + Hash_Lenght && + Buffer_Lenght == Hash_Lenght && + SUCCEEDED(Cryptographic_Buffer_Statics->EncodeToBase64String(*Hash_Buffer.GetAddressOf(), Path_Hash.GetAddressOf()))) + { + ComPtr Permissions_Manager; + ComPtr FutureAccess_List; + if (SUCCEEDED(GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Storage_AccessCache_StorageApplicationPermissions).Get(), &Permissions_Manager)) && + Permissions_Manager && + SUCCEEDED(Permissions_Manager->get_FutureAccessList(&FutureAccess_List)) && + FutureAccess_List) + return FutureAccess_List->AddOrReplace(Path_Hash.Get(), *Item.GetAddressOf(), HString::MakeReference(L"").Get()); + } + + return E_FAIL; +} + +//--------------------------------------------------------------------------- +HRESULT Get_File(HStringReference File_Name, ComPtr &File) +{ + //Try to access file directly + ComPtr Storage; + if (SUCCEEDED(GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Storage_StorageFile).Get(), &Storage)) && Storage) + { + ComPtr > Async_GetFile; + if (SUCCEEDED(Storage->GetFileFromPathAsync(File_Name.Get(), &Async_GetFile)) && + SUCCEEDED(Await(Async_GetFile)) && + SUCCEEDED(Async_GetFile->GetResults(&File)) && + File) + return S_OK; + } + + //Try to access file by sha256 hashed path in future access list + ComPtr Path_Buffer; + ComPtr Hash_Buffer; + ComPtr Cryptographic_Buffer_Statics; + ComPtr Hash_Provider_Statics; + ComPtr Hash_Provider; + UINT32 Buffer_Lenght=0; + UINT32 Hash_Lenght=0; + HString Path_Hash; + + if (SUCCEEDED(GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Security_Cryptography_CryptographicBuffer).Get(), &Cryptographic_Buffer_Statics)) && + Cryptographic_Buffer_Statics && + SUCCEEDED(Cryptographic_Buffer_Statics->ConvertStringToBinary(File_Name.Get(), BinaryStringEncoding_Utf16LE, &Path_Buffer)) && + Path_Buffer && + SUCCEEDED(GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Security_Cryptography_Core_HashAlgorithmProvider).Get(), &Hash_Provider_Statics)) && + Hash_Provider_Statics && + SUCCEEDED(Hash_Provider_Statics->OpenAlgorithm(HString::MakeReference(L"SHA256").Get(), &Hash_Provider)) && + Hash_Provider && + SUCCEEDED(Hash_Provider->HashData(*Path_Buffer.GetAddressOf(), &Hash_Buffer)) && + Hash_Buffer && + SUCCEEDED(Hash_Buffer->get_Length(&Buffer_Lenght)) && + Buffer_Lenght && + SUCCEEDED(Hash_Provider->get_HashLength(&Hash_Lenght)) && + Hash_Lenght && + Buffer_Lenght == Hash_Lenght && + SUCCEEDED(Cryptographic_Buffer_Statics->EncodeToBase64String(*Hash_Buffer.GetAddressOf(), Path_Hash.GetAddressOf()))) + { + ComPtr Permissions_Manager; + if (SUCCEEDED(GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Storage_AccessCache_StorageApplicationPermissions).Get(), &Permissions_Manager)) && Permissions_Manager) + { + ComPtr FutureAccess_List; + ComPtr > Async_GetFile_FutureAccess; + if (SUCCEEDED(Permissions_Manager->get_FutureAccessList(&FutureAccess_List)) && + FutureAccess_List && + SUCCEEDED(FutureAccess_List->GetFileAsync(Path_Hash.Get(), &Async_GetFile_FutureAccess)) && + Await(Async_GetFile_FutureAccess) && + SUCCEEDED(Async_GetFile_FutureAccess->GetResults(&File)) && + File) + return S_OK; + } + } + + return E_FAIL; +} + +//--------------------------------------------------------------------------- +HRESULT Get_Folder(HStringReference Folder_Name, ComPtr &Folder) +{ + //Try to access folder directly + ComPtr Storage; + if (SUCCEEDED(GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Storage_StorageFolder).Get(), &Storage)) && Storage) + { + ComPtr > Async_GetFolder; + if (SUCCEEDED(Storage->GetFolderFromPathAsync(Folder_Name.Get(), &Async_GetFolder)) && + SUCCEEDED(Await(Async_GetFolder)) && + SUCCEEDED(Async_GetFolder->GetResults(&Folder)) && + Folder) + return S_OK; + } + + //Try to access folder by sha256 hashed path in future access list + ComPtr Path_Buffer; + ComPtr Hash_Buffer; + ComPtr Cryptographic_Buffer_Statics; + ComPtr Hash_Provider_Statics; + ComPtr Hash_Provider; + UINT32 Buffer_Lenght = 0; + UINT32 Hash_Lenght = 0; + HString Path_Hash; + + if (SUCCEEDED(GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Security_Cryptography_CryptographicBuffer).Get(), &Cryptographic_Buffer_Statics)) && + Cryptographic_Buffer_Statics && + SUCCEEDED(Cryptographic_Buffer_Statics->ConvertStringToBinary(Folder_Name.Get(), BinaryStringEncoding_Utf16LE, &Path_Buffer)) && + Path_Buffer && + SUCCEEDED(GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Security_Cryptography_Core_HashAlgorithmProvider).Get(), &Hash_Provider_Statics)) && + Hash_Provider_Statics && + SUCCEEDED(Hash_Provider_Statics->OpenAlgorithm(HString::MakeReference(L"SHA256").Get(), &Hash_Provider)) && + Hash_Provider && + SUCCEEDED(Hash_Provider->HashData(*Path_Buffer.GetAddressOf(), &Hash_Buffer)) && + Hash_Buffer && + SUCCEEDED(Hash_Buffer->get_Length(&Buffer_Lenght)) && + Buffer_Lenght && + SUCCEEDED(Hash_Provider->get_HashLength(&Hash_Lenght)) && + Hash_Lenght && + Buffer_Lenght == Hash_Lenght && + SUCCEEDED(Cryptographic_Buffer_Statics->EncodeToBase64String(*Hash_Buffer.GetAddressOf(), Path_Hash.GetAddressOf()))) + { + ComPtr Permissions_Manager; + if (SUCCEEDED(GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Storage_AccessCache_StorageApplicationPermissions).Get(), &Permissions_Manager)) && Permissions_Manager) + { + ComPtr FutureAccess_List; + ComPtr > Async_GetFolder_FutureAccess; + if (SUCCEEDED(Permissions_Manager->get_FutureAccessList(&FutureAccess_List)) && + FutureAccess_List && + SUCCEEDED(FutureAccess_List->GetFolderAsync(Folder_Name.Get(), &Async_GetFolder_FutureAccess)) && + Await(Async_GetFolder_FutureAccess) && + SUCCEEDED(Async_GetFolder_FutureAccess->GetResults(&Folder)) && + Folder) + return S_OK; + } + } + + return E_FAIL; +} +#endif + //*************************************************************************** // Shell //*************************************************************************** @@ -48,7 +235,7 @@ void Shell_Execute(const Ztring &ToExecute) { #ifdef ZENLIB_USEWX #else //ZENLIB_USEWX - #ifdef WINDOWS + #if defined(WINDOWS) && !defined(WINDOWS_UWP) && !defined(WINDOWS_GAMES) ShellExecute(NULL, __T("open"), ToExecute.c_str(), NULL, NULL, 0); #else //Not supported @@ -66,7 +253,7 @@ void Shell_Execute(const Ztring &ToExecute) Ztring Directory_Select_Caption; -#ifdef WINDOWS +#if defined(WINDOWS) && !defined(WINDOWS_UWP) && !defined(WINDOWS_GAMES) #ifdef UNICODE char InitDirA[MAX_PATH]; wchar_t InitDir [MAX_PATH]; diff --git a/Source/ZenLib/OS_Utils.h b/Source/ZenLib/OS_Utils.h index 3c261440..d5fe564a 100644 --- a/Source/ZenLib/OS_Utils.h +++ b/Source/ZenLib/OS_Utils.h @@ -13,6 +13,14 @@ #include "ZenLib/Ztring.h" //--------------------------------------------------------------------------- +//--------------------------------------------------------------------------- +#ifdef WINDOWS_UWP +#include +#include +#include +#endif +//--------------------------------------------------------------------------- + namespace ZenLib { @@ -33,5 +41,40 @@ void Shell_Execute(const Ztring &ToExecute); Ztring OpenFolder_Show(void* Handle, const Ztring &Title, const Ztring &Caption); +//*************************************************************************** +// WinRT Helpers +//*************************************************************************** +#ifdef WINDOWS_UWP +template +inline HRESULT Await(const Microsoft::WRL::ComPtr &Operation) +{ + if (!Operation) + return E_POINTER; + + Microsoft::WRL::ComPtr Info; + HRESULT Result=Operation.As(&Info); + if (FAILED(Result)) + return Result; + + ABI::Windows::Foundation::AsyncStatus Status; + while (SUCCEEDED(Result=Info->get_Status(&Status)) && Status==Started) + Sleep(0); //Yield + + if (FAILED(Result) || Status!=Completed) { + HRESULT Error_Code; + Result=Info->get_ErrorCode(&Error_Code); + if (FAILED(Result)) + return Result; + return Error_Code; + } + + return Result; +} + +HRESULT Add_Item_To_FUA(Microsoft::WRL::Wrappers::HStringReference Path, Microsoft::WRL::ComPtr &Item); +HRESULT Get_File(Microsoft::WRL::Wrappers::HStringReference File_Name, Microsoft::WRL::ComPtr &File); +HRESULT Get_Folder(Microsoft::WRL::Wrappers::HStringReference Folder_Name, Microsoft::WRL::ComPtr &Folder); +#endif + } //namespace ZenLib #endif diff --git a/Source/ZenLib/Thread.cpp b/Source/ZenLib/Thread.cpp index adfa45ce..fd183033 100644 --- a/Source/ZenLib/Thread.cpp +++ b/Source/ZenLib/Thread.cpp @@ -298,15 +298,21 @@ Thread::returnvalue Thread::RequestTerminate() //--------------------------------------------------------------------------- Thread::returnvalue Thread::ForceTerminate() { - CriticalSectionLocker CSL(C); + #ifdef WINDOWS_UWP + return Incoherent; + #else + CriticalSectionLocker CSL(C); - //Terminating (not clean) - TerminateThread((HANDLE)ThreadPointer, 1); ThreadPointer=NULL; + //Terminating (not clean) + #pragma warning ( suppress : 6258 ) //C6258: Using TerminateThread does not allow proper thread clean up. + TerminateThread((HANDLE)ThreadPointer, 1); + ThreadPointer=NULL; - //Configuring - State=State_Terminated; + //Configuring + State=State_Terminated; - return Ok; + return Ok; + #endif } //*************************************************************************** @@ -315,25 +321,19 @@ Thread::returnvalue Thread::ForceTerminate() bool Thread::IsRunning() { - CriticalSectionLocker CSL(C); - const bool ToReturn=State==State_Running || State==State_Terminating; - return ToReturn; + return State==State_Running; } //--------------------------------------------------------------------------- bool Thread::IsTerminating() { - CriticalSectionLocker CSL(C); - const bool ToReturn=State==State_Terminating; - return ToReturn; + return State==State_Terminating; } //--------------------------------------------------------------------------- bool Thread::IsExited() { - CriticalSectionLocker CSL(C); - const bool ToReturn=State==State_New || State==State_Terminated; - return ToReturn; + return State==State_Terminated; } //*************************************************************************** @@ -519,6 +519,9 @@ Thread::returnvalue Thread::RequestTerminate() Thread::returnvalue Thread::ForceTerminate() { //Terminating (not clean) + #if !defined(__ANDROID_API__) + pthread_cancel((pthread_t)ThreadPointer); + #endif //Configuring State=State_Terminated; @@ -533,33 +536,28 @@ Thread::returnvalue Thread::ForceTerminate() //--------------------------------------------------------------------------- bool Thread::IsRunning() { - CriticalSectionLocker CSL(C); - const bool ToReturn=State==State_Running; - return ToReturn; + return State==State_Running; } //--------------------------------------------------------------------------- bool Thread::IsTerminating() { - CriticalSectionLocker CSL(C); - const bool ToReturn=State==State_Terminating; - return ToReturn; + return State==State_Terminating; } //--------------------------------------------------------------------------- bool Thread::IsExited() { - CriticalSectionLocker CSL(C); - const bool ToReturn=State==State_New || State==State_Terminating; - return ToReturn; + return State==State_Terminated; } //*************************************************************************** // Communicating //*************************************************************************** -void Thread::Sleep(size_t) +void Thread::Sleep(size_t Millisecond) { + usleep(Millisecond*1000); } void Thread::Yield() diff --git a/Source/ZenLib/Translation.cpp b/Source/ZenLib/Translation.cpp index a58a012a..af628cd8 100644 --- a/Source/ZenLib/Translation.cpp +++ b/Source/ZenLib/Translation.cpp @@ -34,7 +34,7 @@ namespace ZenLib //--------------------------------------------------------------------------- // Constructors Translation::Translation() -: std::map () +: std::map (), Max() { Separator[0]=EOL; Separator[1]=__T(";"); diff --git a/Source/ZenLib/Utils.cpp b/Source/ZenLib/Utils.cpp index e272ead3..7f6daf43 100644 --- a/Source/ZenLib/Utils.cpp +++ b/Source/ZenLib/Utils.cpp @@ -971,12 +971,18 @@ void int64u_int32u (int64u BigInt, int32u &High, int32u &Low) // Floats and ints int32s float32_int32s (float32 F, bool Rounded) { + //Out of boundaries + if (F>=(int32s)0x7FFFFFFF) + return (int32s)0x7FFFFFFF; + if (F<=(int32s)0x80000000) + return (int32s)0x80000000; + //Not rounded if (!Rounded) return (int32s)F; //Rounded int I1=(int)F; - if (F-I1>=0.5) + if (F-I1>=0.5f) return I1+1; else return I1; @@ -984,12 +990,18 @@ int32s float32_int32s (float32 F, bool Rounded) int64s float32_int64s (float32 F, bool Rounded) { + //Out of boundaries + if (F>=(int64s)0x7FFFFFFFFFFFFFFFLL) + return (int64s)0x7FFFFFFFFFFFFFFFLL; + if (F<=(int64s)0x8000000000000000LL) + return (int64s)0x8000000000000000LL; + //Not rounded if (!Rounded) return (int64s)F; //Rounded int I1=(int)F; - if (F-I1>=0.5) + if (F-I1>=0.5f) return I1+1; else return I1; @@ -997,6 +1009,12 @@ int64s float32_int64s (float32 F, bool Rounded) int32s float64_int32s (float64 F, bool Rounded) { + //Out of boundaries + if (F>=(int32s)0x7FFFFFFF) + return (int32s)0x7FFFFFFF; + if (F<=(int32s)0x80000000) + return (int32s)0x80000000; + //Not rounded if (!Rounded) return (int32s)F; @@ -1010,6 +1028,12 @@ int32s float64_int32s (float64 F, bool Rounded) int64s float64_int64s (float64 F, bool Rounded) { + //Out of boundaries + if (F>=(int64s)0x7FFFFFFFFFFFFFFFLL) + return (int64s)0x7FFFFFFFFFFFFFFFLL; + if (F<=(int64s)0x8000000000000000LL) + return (int64s)0x8000000000000000LL; + //Not rounded if (!Rounded) return (int64s)F; diff --git a/Source/ZenLib/Utils.h b/Source/ZenLib/Utils.h index 8845d78d..921c8b58 100644 --- a/Source/ZenLib/Utils.h +++ b/Source/ZenLib/Utils.h @@ -76,7 +76,6 @@ void float322LittleEndian (char* List, float32 Value); void float642LittleEndian (char* List, float64 Value); void float802LittleEndian (char* List, float80 Value); -#ifndef __BORLANDC__ inline int8s LittleEndian2int8s (const int8u* List) {return LittleEndian2int8s ((const char*)List);} inline int8u LittleEndian2int8u (const int8u* List) {return LittleEndian2int8u ((const char*)List);} inline int16s LittleEndian2int16s (const int8u* List) {return LittleEndian2int16s ((const char*)List);} @@ -124,7 +123,6 @@ inline void float162LittleEndian (int8u* List, float32 Value) {return float1 inline void float322LittleEndian (int8u* List, float32 Value) {return float322LittleEndian ((char*)List, Value);} inline void float642LittleEndian (int8u* List, float64 Value) {return float642LittleEndian ((char*)List, Value);} inline void float802LittleEndian (int8u* List, float80 Value) {return float802LittleEndian ((char*)List, Value);} -#endif //__BORLANDC__ //--------------------------------------------------------------------------- //Big Endians @@ -176,7 +174,6 @@ void float322BigEndian (char* List, float32 Value); void float642BigEndian (char* List, float64 Value); void float802BigEndian (char* List, float80 Value); -#ifndef __BORLANDC__ inline int8s BigEndian2int8s (const int8u* List) {return BigEndian2int8s ((const char*)List);} inline int8u BigEndian2int8u (const int8u* List) {return BigEndian2int8u ((const char*)List);} inline int16s BigEndian2int16s (const int8u* List) {return BigEndian2int16s ((const char*)List);} @@ -224,7 +221,6 @@ inline void float162BigEndian (int8u* List, float32 Value) {return float162B inline void float322BigEndian (int8u* List, float32 Value) {return float322BigEndian ((char*)List, Value);} inline void float642BigEndian (int8u* List, float64 Value) {return float642BigEndian ((char*)List, Value);} inline void float802BigEndian (int8u* List, float80 Value) {return float802BigEndian ((char*)List, Value);} -#endif //__BORLANDC__ //--------------------------------------------------------------------------- // int32 - int64 @@ -261,7 +257,6 @@ inline int32u CC4(const char* C) {return BigEndian2int32u(C);} inline int32u CC3(const char* C) {return BigEndian2int24u(C);} inline int16u CC2(const char* C) {return BigEndian2int16u(C);} inline int8u CC1(const char* C) {return BigEndian2int8u (C);} -#ifndef __BORLANDC__ inline int64u CC8(const int8u* C) {return BigEndian2int64u(C);} inline int64u CC7(const int8u* C) {return BigEndian2int56u(C);} inline int64u CC6(const int8u* C) {return BigEndian2int48u(C);} @@ -270,7 +265,6 @@ inline int32u CC4(const int8u* C) {return BigEndian2int32u(C);} inline int32u CC3(const int8u* C) {return BigEndian2int24u(C);} inline int16u CC2(const int8u* C) {return BigEndian2int16u(C);} inline int8u CC1(const int8u* C) {return BigEndian2int8u (C);} -#endif // __BORLANDC__ //--------------------------------------------------------------------------- // turn a numeric literal into a hex constant diff --git a/Source/ZenLib/Ztring.cpp b/Source/ZenLib/Ztring.cpp index d2497719..22a39bbd 100644 --- a/Source/ZenLib/Ztring.cpp +++ b/Source/ZenLib/Ztring.cpp @@ -32,7 +32,9 @@ #ifdef WINDOWS #undef __TEXT #include - #include + #ifndef WINDOWS_GAMES + #include + #endif #endif #endif //ZENLIB_USEWX #ifdef __MINGW32__ @@ -266,7 +268,7 @@ Ztring& Ztring::From_Unicode (const wchar_t* S) if (Size!=0 && Size!=(size_t)-1) { char* AnsiString=new char[Size+1]; - Size=wcstombs(AnsiString, S, wcslen(S)); + Size=wcstombs(AnsiString, S, Size+1); AnsiString[Size]='\0'; assign (AnsiString); delete[] AnsiString; @@ -589,11 +591,11 @@ Ztring& Ztring::From_Local (const char* S) else clear(); #else //WINDOWS - size_t Size=mbstowcs(NULL, S, 0); + size_t Size=mbsrtowcs(NULL, &S, 0, NULL); if (Size!=0 && Size!=(size_t)-1) { wchar_t* WideString=new wchar_t[Size+1]; - Size=mbstowcs(WideString, S, Size); + Size=mbsrtowcs(WideString, &S, Size, NULL); WideString[Size]=L'\0'; assign (WideString); delete[] WideString; //WideString=NULL; @@ -649,17 +651,13 @@ Ztring& Ztring::From_ISO_8859_1(const char* S, size_type Start, size_type Length if (Length==Error) Length=strlen(S+Start); - #ifdef _UNICODE - char* Temp = new char[Length+1]; - strncpy(Temp, S +Start, Length); - Temp[Length] = '\0'; - From_ISO_8859_1(Temp); - delete[] Temp; - #else - assign(S +Start, Length); - if (find(__T('\0')) != std::string::npos) - resize(find(__T('\0'))); - #endif + + char* Temp = new char[Length+1]; + strncpy(Temp, S +Start, Length); + Temp[Length] = '\0'; + From_ISO_8859_1(Temp); + delete[] Temp; + return *this; } @@ -688,17 +686,13 @@ Ztring& Ztring::From_ISO_8859_2(const char* S, size_type Start, size_type Length if (Length==Error) Length=strlen(S+Start); - #ifdef _UNICODE - char* Temp = new char[Length+1]; - strncpy(Temp, S +Start, Length); - Temp[Length] = '\0'; - From_ISO_8859_2(Temp); - delete[] Temp; - #else - assign(S +Start, Length); - if (find(__T('\0')) != std::string::npos) - resize(find(__T('\0'))); - #endif + + char* Temp = new char[Length+1]; + strncpy(Temp, S +Start, Length); + Temp[Length] = '\0'; + From_ISO_8859_2(Temp); + delete[] Temp; + return *this; } @@ -738,43 +732,50 @@ Ztring& Ztring::From_UUID (const int128u S) Ztring& Ztring::From_CC4 (const int32u S) { - std::string S1; - S1.append(1, (char)((S&0xFF000000)>>24)); - S1.append(1, (char)((S&0x00FF0000)>>16)); - S1.append(1, (char)((S&0x0000FF00)>> 8)); - S1.append(1, (char)((S&0x000000FF) )); - From_Local(S1.c_str()); - - // Validity Test - if ( size()==4 - || (size()==3 && (S&0x000000FF)==0x00000000 && at(0)>=0x20 && at(1)>=0x20 && at(2)>=0x20) - || (size()==2 && (S&0x0000FFFF)==0x00000000 && at(0)>=0x20 && at(1)>=0x20) - || (size()==1 && (S&0x00FFFFFF)==0x00000000 && at(0)>=0x20)) - return *this; - - // Not valid, using 0x as fallback clear(); - append(__T("0x")); - append(Ztring().From_CC1((int8u)((S&0xFF000000)>>24))); - append(Ztring().From_CC1((int8u)((S&0x00FF0000)>>16))); - append(Ztring().From_CC1((int8u)((S&0x0000FF00)>> 8))); - append(Ztring().From_CC1((int8u)((S&0x000000FF) ))); + for (int8s i=(4-1)*8; i>=0; i-=8) + { + int32u Value=(S&(0xFF<>i; + if (Value<0x20) + { + if (!i || (i!=24 && !(S&(0xFFFFFFFF>>(32-i))))) + return *this; // Trailing 0 are fine + // Not valid, using 0x as fallback + clear(); + append(__T("0x")); + append(Ztring().From_CC1((int8u)((S&0xFF000000)>>24))); + append(Ztring().From_CC1((int8u)((S&0x00FF0000)>>16))); + append(Ztring().From_CC1((int8u)((S&0x0000FF00)>> 8))); + append(Ztring().From_CC1((int8u)((S&0x000000FF) ))); + return *this; + } + append(1, (Char)(Value)); + } return *this; } Ztring& Ztring::From_CC3 (const int32u S) { - std::string S1; - S1.append(1, (char)((S&0x00FF0000)>>16)); - S1.append(1, (char)((S&0x0000FF00)>> 8)); - S1.append(1, (char)((S&0x000000FF)>> 0)); - From_Local(S1.c_str()); - - //Test - if (empty()) - assign(__T("(empty)")); + clear(); + for (int8s i=(3-1)*8; i>=0; i-=8) + { + int32u Value=(S&(0xFF<>i; + if (Value<0x20) + { + if (!i || (i!=16 && !(S&(0xFFFFFF>>(24-i))))) + return *this; // Trailing 0 are fine + // Not valid, using 0x as fallback + clear(); + append(__T("0x")); + append(Ztring().From_CC1((int8u)((S&0x00FF0000)>>16))); + append(Ztring().From_CC1((int8u)((S&0x0000FF00)>> 8))); + append(Ztring().From_CC1((int8u)((S&0x000000FF) ))); + return *this; + } + append(1, (Char)(Value)); + } return *this; } @@ -1305,7 +1306,19 @@ Ztring& Ztring::Date_From_Seconds_1970 (const int32s Value) Ztring& Ztring::Date_From_Seconds_1970 (const int64s Value) { time_t Time=(time_t)Value; + #if defined(HAVE_GMTIME_R) + struct tm Gmt_Temp; + struct tm *Gmt=gmtime_r(&Time, &Gmt_Temp); + #elif defined(_MSC_VER) + struct tm Gmt_Temp; + errno_t gmtime_s_Result=gmtime_s(&Gmt_Temp , &Time); + struct tm* Gmt=gmtime_s_Result?NULL:&Gmt_Temp; + #else + #ifdef __GNUC__ + #warning "This version of ZenLib is not thread safe" + #endif struct tm *Gmt=gmtime(&Time); + #endif if (!Gmt) { clear(); @@ -1336,9 +1349,23 @@ Ztring& Ztring::Date_From_Seconds_1970 (const int64s Value) Ztring& Ztring::Date_From_Seconds_1970_Local (const int32u Value) { time_t Time=(time_t)Value; + #if defined(HAVE_LOCALTIME_R) + struct tm Gmt_Temp; + struct tm *Gmt=localtime_r(&Time, &Gmt_Temp); + #elif defined(_MSC_VER) + struct tm Gmt_Temp; + errno_t localtime_s_Result=localtime_s(&Gmt_Temp , &Time); + struct tm* Gmt=localtime_s_Result?NULL:&Gmt_Temp; + #else + #ifdef __GNUC__ + #warning "This version of ZenLib is not thread safe" + #endif struct tm *Gmt=localtime(&Time); + #endif Ztring DateT; Ztring Date; + if (Gmt) + { Date+=Ztring::ToZtring((Gmt->tm_year+1900)); Date+=__T("-"); DateT.From_Number(Gmt->tm_mon+1); if (DateT.size()<2){DateT=Ztring(__T("0"))+Ztring::ToZtring(Gmt->tm_mon+1);} @@ -1356,6 +1383,7 @@ Ztring& Ztring::Date_From_Seconds_1970_Local (const int32u Value) DateT.From_Number(Gmt->tm_sec); if (DateT.size()<2){DateT=Ztring(__T("0"))+Ztring::ToZtring(Gmt->tm_sec);} Date+=DateT; assign (Date.c_str()); + } return *this; } @@ -1364,7 +1392,7 @@ Ztring& Ztring::Date_From_String (const char* Value, size_t Value_Size) //Only the year if (Value_Size<10) { - From_Local(Value, 0, Value_Size); + From_UTF8(Value, 0, Value_Size); return *this; } @@ -1401,7 +1429,7 @@ Ztring& Ztring::Date_From_String (const char* Value, size_t Value_Size) assign (ToReturn.c_str()); #else //ZENLIB_USEWX - Ztring DateS; DateS.From_Local(Value, 0, Value_Size); + Ztring DateS; DateS.From_UTF8(Value, 0, Value_Size); //Unix style formating : exactly 24 bytes (or 25 with 0x0A at the end) and Year is at the end if ((DateS.size()==24 || (DateS.size()==25 && DateS[24]==__T('\n'))) && DateS[23]>=__T('0') && DateS[23]<=__T('9') && DateS[21]>=__T('0') && DateS[21]<=__T('9') && DateS[19]==__T(' ')) { @@ -1503,7 +1531,7 @@ Ztring& Ztring::Date_From_String (const char* Value, size_t Value_Size) append(DateS); } else - From_Local(Value, 0, Value_Size); //Not implemented + From_UTF8(Value, 0, Value_Size); //Not implemented #endif //ZENLIB_USEWX return *this; } @@ -1618,18 +1646,23 @@ std::string Ztring::To_UTF8 () const case 6: utf8chars[5] = 0x80 | (wc & 0x3f); wc = (wc >> 6) | 0x4000000; + [[fallthrough]]; case 5: utf8chars[4] = 0x80 | (wc & 0x3f); wc = (wc >> 6) | 0x200000; + [[fallthrough]]; case 4: utf8chars[3] = 0x80 | (wc & 0x3f); wc = (wc >> 6) | 0x10000; + [[fallthrough]]; case 3: utf8chars[2] = 0x80 | (wc & 0x3f); wc = (wc >> 6) | 0x800; + [[fallthrough]]; case 2: utf8chars[1] = 0x80 | (wc & 0x3f); wc = (wc >> 6) | 0xc0; + [[fallthrough]]; case 1: utf8chars[0] = (char) wc; } @@ -1698,8 +1731,8 @@ std::string Ztring::To_Local () const std::string AnsiString; for (size_t Pos=0; Pos=0) + size_t Result_Size=wcrtomb(Result, operator[](Pos), 0); + if (Result_Size && Result_Size!=(size_t)-1) AnsiString.append(Result, Result_Size); else AnsiString+='?'; @@ -1826,11 +1859,11 @@ int8s Ztring::To_int8s (int8u Radix, ztring_t Options) const #endif //Rounded - if (Options==Ztring_Rounded && find(__T('.'))!=Error) + if (Options&Ztring_Rounded && find(__T('.'))!=Error) { float80 F=To_float80(); F-=I; - if (F>=0.5) + if (F>=0.5f) return (int8s)I+1; } @@ -1864,11 +1897,11 @@ int8u Ztring::To_int8u (int8u Radix, ztring_t Options) const #endif //Rounded - if (Options==Ztring_Rounded && find(__T('.'))!=std::string::npos) + if (Options&Ztring_Rounded && find(__T('.'))!=std::string::npos) { float32 F=To_float32(); F-=I; - if (F>=0.5) + if (F>=0.5f) return (int8u)I+1; } @@ -1902,11 +1935,11 @@ int16s Ztring::To_int16s (int8u Radix, ztring_t Options) const #endif //Rounded - if (Options==Ztring_Rounded && find(__T('.'))!=Error) + if (Options&Ztring_Rounded && find(__T('.'))!=Error) { float80 F=To_float80(); F-=I; - if (F>=0.5) + if (F>=0.5f) return (int16s)I+1; } @@ -1940,11 +1973,11 @@ int16u Ztring::To_int16u (int8u Radix, ztring_t Options) const #endif //Rounded - if (Options==Ztring_Rounded && find(__T('.'))!=std::string::npos) + if (Options&Ztring_Rounded && find(__T('.'))!=std::string::npos) { float32 F=To_float32(); F-=I; - if (F>=0.5) + if (F>=0.5f) return (int16u)I+1; } @@ -1978,11 +2011,11 @@ int32s Ztring::To_int32s (int8u Radix, ztring_t Options) const #endif //Rounded - if (Options==Ztring_Rounded && find(__T('.'))!=Error) + if (Options&Ztring_Rounded && find(__T('.'))!=Error) { float80 F=To_float80(); F-=I; - if (F>=0.5) + if (F>=0.5f) return I+1; } @@ -2016,11 +2049,11 @@ int32u Ztring::To_int32u (int8u Radix, ztring_t Options) const #endif //Rounded - if (Options==Ztring_Rounded && find(__T('.'))!=std::string::npos) + if (Options&Ztring_Rounded && find(__T('.'))!=std::string::npos) { float32 F=To_float32(); F-=I; - if (F>=0.5) + if (F>=0.5f) return I+1; } @@ -2054,11 +2087,11 @@ int64s Ztring::To_int64s (int8u Radix, ztring_t Options) const #endif //Rounded - if (Options==Ztring_Rounded && find(__T('.'))!=std::string::npos) + if (Options&Ztring_Rounded && find(__T('.'))!=std::string::npos) { float32 F=To_float32(); F-=I; - if (F>0.5) + if (F>0.5f) return I+1; } @@ -2092,11 +2125,11 @@ int64u Ztring::To_int64u (int8u Radix, ztring_t Options) const #endif //Rounded - if (Options==Ztring_Rounded && find(__T('.'))!=std::string::npos) + if (Options&Ztring_Rounded && find(__T('.'))!=std::string::npos) { float32 F=To_float32(); F-=I; - if (F>=0.5) + if (F>=0.5f) return I+1; } diff --git a/Source/ZenLib/Ztring.h b/Source/ZenLib/Ztring.h index 55ccb703..5d26cfae 100644 --- a/Source/ZenLib/Ztring.h +++ b/Source/ZenLib/Ztring.h @@ -342,7 +342,7 @@ public : Ztring SubString (const tstring &Begin, const tstring &End, size_type Pos=0, ztring_t Options=Ztring_Nothing) const; /// @brief replace a string by another one /// @param ToFind string to find - /// @param ToReplace string wich replace the string found + /// @param ReplaceBy string wich replace the string found /// @param Pos Position to begin to scan string /// @param Options Options for searching \n /// Available : Ztring_CaseSensitive, Ztring_Recursive diff --git a/Source/ZenLib/ZtringList.cpp b/Source/ZenLib/ZtringList.cpp index e9a3a733..0e2b5162 100644 --- a/Source/ZenLib/ZtringList.cpp +++ b/Source/ZenLib/ZtringList.cpp @@ -39,7 +39,7 @@ extern Ztring EmptyZtring; //--------------------------------------------------------------------------- // Constructors ZtringList::ZtringList () -: std::vector > () +: std::vector > (), Max() { Separator[0]=__T(";"); Quote=__T("\""); @@ -47,7 +47,7 @@ ZtringList::ZtringList () } ZtringList::ZtringList(const ZtringList &Source) -: std::vector > () +: std::vector > (), Max() { Separator[0]=Source.Separator[0]; Quote=Source.Quote; @@ -154,19 +154,19 @@ Ztring ZtringList::Read () const return Ztring(); Ztring Retour; - Ztring ToFind=Separator[0]+Quote[0]+__T("\r\n"); + Ztring ToFind=Separator[0]+Quote+__T("\r\n"); for (size_type Pos=0; Pos=ToWrite.size()) @@ -334,7 +335,9 @@ Ztring::size_type ZtringList::MaxStringLength_Get () // Separator void ZtringList::Separator_Set (size_type Level, const Ztring &NewSeparator) { - if (Level>0) + if (NewSeparator.empty() || Level>0) + return; + if (Separator[Level]==NewSeparator) return; Separator[Level]=NewSeparator; } @@ -343,6 +346,8 @@ void ZtringList::Separator_Set (size_type Level, const Ztring &NewSeparator) // Quote void ZtringList::Quote_Set (const Ztring &NewQuote) { + if (Quote==NewQuote) + return; Quote=NewQuote; } diff --git a/Source/ZenLib/ZtringListList.cpp b/Source/ZenLib/ZtringListList.cpp index 54c6a945..d4cb853b 100644 --- a/Source/ZenLib/ZtringListList.cpp +++ b/Source/ZenLib/ZtringListList.cpp @@ -323,7 +323,7 @@ void ZtringListList::Write(const Ztring &ToWrite) while (i=size()) { - size_t PreviousSize=size(); resize(y+1); for (size_t j=0; j<=y; j++) + { operator[](j).Separator_Set(0, Separator[1]); + operator[](j).Quote_Set(Quote); + operator[](j).Max_Set(0, Max[1]); + } } ZtringList& Line=operator[](y); if (x>=Line.size()) @@ -600,7 +603,7 @@ ZtringListList ZtringListList::SubSheet (const Ztring &ToFind, size_type Pos1, s // Separator void ZtringListList::Separator_Set (size_type Level, const Ztring &NewSeparator) { - if (Level>1) + if (NewSeparator.empty() || Level>1) return; Separator[Level]=NewSeparator; diff --git a/Source/ZenLib/ZtringListListF.cpp b/Source/ZenLib/ZtringListListF.cpp index c1ea781d..eee10ba0 100644 --- a/Source/ZenLib/ZtringListListF.cpp +++ b/Source/ZenLib/ZtringListListF.cpp @@ -29,8 +29,6 @@ namespace ZenLib { -//--------------------------------------------------------------------------- -#define READ_SIZE 512*1024 //--------------------------------------------------------------------------- //*************************************************************************** @@ -266,7 +264,7 @@ bool ZtringListListF::CSV_Sauvegarder () //Sauvegarde File F; if (!F.Create(Name, true)) - return Error; + return false; if (Separator[0]==__T("(Default)")) Separator[0]=EOL; @@ -282,7 +280,7 @@ bool ZtringListListF::CFG_Sauvegarder () { File F; if (!F.Create(Name, true)) - return Error; + return false; Ztring ToWrite; Ztring Propriete, Valeur, Commentaire; diff --git a/Source/ZenLib/int128s.cpp b/Source/ZenLib/int128s.cpp index 881e43c9..a5470d12 100644 --- a/Source/ZenLib/int128s.cpp +++ b/Source/ZenLib/int128s.cpp @@ -55,7 +55,7 @@ namespace ZenLib // IMPLEMENTATION -const char * int128::toString (unsigned int radix) const throw () { +const char * int128::toString (unsigned int radix) const noexcept { if (!*this) return "0"; if (radix < 2 || radix > 37) return "(invalid radix)"; @@ -75,9 +75,9 @@ const char * int128::toString (unsigned int radix) const throw () { sz [--i] = '-'; return &sz [i]; -}; +} -int128::int128 (const char * sz) throw () +int128::int128 (const char * sz) noexcept : lo (0u), hi (0) { if (!sz) return; @@ -120,55 +120,55 @@ int128::int128 (const char * sz) throw () *this = 0 - *this; return; -}; +} -int128::int128 (const float a) throw () +int128::int128 (const float a) noexcept #if defined (__mips__) || defined (__mipsel__) : lo ((int64u) fmodf ((const double)a, 18446744073709551616.0)), #else : lo ((int64u) fmodf (a, 18446744073709551616.0f)), #endif - hi ((int64s) (a / 18446744073709551616.0f)) {}; + hi ((int64s) (a / 18446744073709551616.0f)) {} -int128::int128 (const double & a) throw () +int128::int128 (const double & a) noexcept : lo ((int64u) fmod (a, 18446744073709551616.0)), - hi ((int64s) (a / 18446744073709551616.0)) {}; + hi ((int64s) (a / 18446744073709551616.0)) {} -int128::int128 (const long double & a) throw () +int128::int128 (const long double & a) noexcept #if defined (__mips__) || defined (__mipsel__) : lo ((int64u) fmod ((const double)a, 18446744073709551616.0)), #else : lo ((int64u) fmodl (a, 18446744073709551616.0l)), #endif - hi ((int64s) (a / 18446744073709551616.0l)) {}; + hi ((int64s) (a / 18446744073709551616.0l)) {} -float int128::toFloat () const throw () { +float int128::toFloat () const noexcept { return (float) this->hi * 18446744073709551616.0f + (float) this->lo; -}; +} -double int128::toDouble () const throw () { +double int128::toDouble () const noexcept { return (double) this->hi * 18446744073709551616.0 + (double) this->lo; -}; +} -long double int128::toLongDouble () const throw () { +long double int128::toLongDouble () const noexcept { return (long double) this->hi * 18446744073709551616.0l + (long double) this->lo; -}; +} -int128 int128::operator - () const throw () { +int128 int128::operator - () const noexcept { if (!this->hi && !this->lo) // number is 0, just return 0 return *this; else // non 0 number return int128 (0-this->lo, ~this->hi); -}; +} -int128 int128::operator ~ () const throw () { +int128 int128::operator ~ () const noexcept { return int128 (~this->lo, ~this->hi); -}; +} int128 & int128::operator ++ () { ++this->lo; @@ -176,7 +176,7 @@ int128 & int128::operator ++ () { ++this->hi; return *this; -}; +} int128 & int128::operator -- () { if (!this->lo) @@ -184,32 +184,32 @@ int128 & int128::operator -- () { --this->lo; return *this; -}; +} int128 int128::operator ++ (int) { int128 b = *this; ++ *this; return b; -}; +} int128 int128::operator -- (int) { int128 b = *this; -- *this; return b; -}; +} -int128 & int128::operator += (const int128 & b) throw () { +int128 & int128::operator += (const int128 & b) noexcept { int64u old_lo = this->lo; this->lo += b.lo; this->hi += b.hi + (this->lo < old_lo); return *this; -}; +} -int128 & int128::operator *= (const int128 & b) throw () { +int128 & int128::operator *= (const int128 & b) noexcept { if (!b) return *this = 0u; if (b == 1u) @@ -229,10 +229,10 @@ int128 & int128::operator *= (const int128 & b) throw () { }; return *this; -}; +} -int128 int128::div (const int128 & divisor, int128 & remainder) const throw () { +int128 int128::div (const int128 & divisor, int128 & remainder) const noexcept { if (!divisor) return 1u / (unsigned int) divisor.lo; // or RaiseException (EXCEPTION_INT_DIVIDE_BY_ZERO, @@ -278,18 +278,18 @@ int128 int128::div (const int128 & divisor, int128 & remainder) const throw () { remainder = r; return q; -}; +} -bool int128::bit (unsigned int n) const throw () { +bool int128::bit (unsigned int n) const noexcept { n &= 0x7F; if (n < 64) return (this->lo & (1ull << n))?true:false; else return (this->hi & (1ull << (n - 64)))?true:false; -}; +} -void int128::bit (unsigned int n, bool val) throw () { +void int128::bit (unsigned int n, bool val) noexcept { n &= 0x7F; if (val) { @@ -299,10 +299,10 @@ void int128::bit (unsigned int n, bool val) throw () { if (n < 64) this->lo &= ~(1ull << n); else this->hi &= ~(1ull << (n - 64)); }; -}; +} -int128 & int128::operator >>= (unsigned int n) throw () { +int128 & int128::operator >>= (unsigned int n) noexcept { n &= 0x7F; if (n > 63) { @@ -329,9 +329,9 @@ int128 & int128::operator >>= (unsigned int n) throw () { }; return *this; -}; +} -int128 & int128::operator <<= (unsigned int n) throw () { +int128 & int128::operator <<= (unsigned int n) noexcept { n &= 0x7F; if (n > 63) { @@ -356,34 +356,34 @@ int128 & int128::operator <<= (unsigned int n) throw () { }; return *this; -}; +} -bool int128::operator ! () const throw () { +bool int128::operator ! () const noexcept { return !(this->hi || this->lo); -}; +} -int128 & int128::operator |= (const int128 & b) throw () { +int128 & int128::operator |= (const int128 & b) noexcept { this->hi |= b.hi; this->lo |= b.lo; return *this; -}; +} -int128 & int128::operator &= (const int128 & b) throw () { +int128 & int128::operator &= (const int128 & b) noexcept { this->hi &= b.hi; this->lo &= b.lo; return *this; -}; +} -int128 & int128::operator ^= (const int128 & b) throw () { +int128 & int128::operator ^= (const int128 & b) noexcept { this->hi ^= b.hi; this->lo ^= b.lo; return *this; -}; +} -bool operator < (const int128 & a, const int128 & b) throw () { +bool operator < (const int128 & a, const int128 & b) noexcept { if (a.hi == b.hi) { if (a.hi < 0) return (int64s) a.lo < (int64s) b.lo; @@ -391,16 +391,16 @@ bool operator < (const int128 & a, const int128 & b) throw () { return a.lo < b.lo; } else return a.hi < b.hi; -}; +} -bool operator == (const int128 & a, const int128 & b) throw () { +bool operator == (const int128 & a, const int128 & b) noexcept { return a.hi == b.hi && a.lo == b.lo; -}; -bool operator && (const int128 & a, const int128 & b) throw () { +} +bool operator && (const int128 & a, const int128 & b) noexcept { return (a.hi || a.lo) && (b.hi || b.lo); -}; -bool operator || (const int128 & a, const int128 & b) throw () { +} +bool operator || (const int128 & a, const int128 & b) noexcept { return (a.hi || a.lo) || (b.hi || b.lo); -}; +} } //NameSpace diff --git a/Source/ZenLib/int128s.h b/Source/ZenLib/int128s.h index c179838d..41e58935 100644 --- a/Source/ZenLib/int128s.h +++ b/Source/ZenLib/int128s.h @@ -25,14 +25,6 @@ Version: 1.1 */ -#include -#include -#include -#ifdef __cplusplus - #include //for size_t -#else /* __cplusplus */ - #include //for size_t -#endif /* __cplusplus */ #include "ZenLib/Conf.h" namespace ZenLib @@ -48,96 +40,96 @@ class int128 { protected: // Some global operator functions must be friends - friend bool operator < (const int128 &, const int128 &) throw (); - friend bool operator == (const int128 &, const int128 &) throw (); - friend bool operator || (const int128 &, const int128 &) throw (); - friend bool operator && (const int128 &, const int128 &) throw (); + friend bool operator < (const int128 &, const int128 &) noexcept; + friend bool operator == (const int128 &, const int128 &) noexcept; + friend bool operator || (const int128 &, const int128 &) noexcept; + friend bool operator && (const int128 &, const int128 &) noexcept; public: // Constructors - inline int128 () throw () : lo(0), hi(0) {}; - inline int128 (const int128 & a) throw () : lo (a.lo), hi (a.hi) {}; + inline int128 () noexcept : lo(0), hi(0) {}; + inline int128 (const int128 & a) noexcept : lo (a.lo), hi (a.hi) {}; - inline int128 (const unsigned int & a) throw () : lo (a), hi (0ll) {}; - inline int128 (const signed int & a) throw () : lo (a), hi (0ll) { + inline int128 (const unsigned int & a) noexcept : lo (a), hi (0ll) {}; + inline int128 (const signed int & a) noexcept : lo (a), hi (0ll) { if (a < 0) this->hi = -1ll; }; - inline int128 (const int64u & a) throw () : lo (a), hi (0ll) {}; - inline int128 (const int64s & a) throw () : lo (a), hi (0ll) { + inline int128 (const int64u & a) noexcept : lo (a), hi (0ll) {}; + inline int128 (const int64s & a) noexcept : lo (a), hi (0ll) { if (a < 0) this->hi = -1ll; }; - int128 (const float a) throw (); - int128 (const double & a) throw (); - int128 (const long double & a) throw (); + int128 (const float a) noexcept; + int128 (const double & a) noexcept; + int128 (const long double & a) noexcept; - int128 (const char * sz) throw (); + int128 (const char * sz) noexcept; // TODO: Consider creation of operator= to eliminate // the need of intermediate objects during assignments. private: // Special internal constructors - int128 (const int64u & a, const int64s & b) throw () + int128 (const int64u & a, const int64s & b) noexcept : lo (a), hi (b) {}; public: // Operators - bool operator ! () const throw (); + bool operator ! () const noexcept; - int128 operator - () const throw (); - int128 operator ~ () const throw (); + int128 operator - () const noexcept; + int128 operator ~ () const noexcept; int128 & operator ++ (); int128 & operator -- (); int128 operator ++ (int); int128 operator -- (int); - int128 & operator += (const int128 & b) throw (); - int128 & operator *= (const int128 & b) throw (); + int128 & operator += (const int128 & b) noexcept; + int128 & operator *= (const int128 & b) noexcept; - int128 & operator >>= (unsigned int n) throw (); - int128 & operator <<= (unsigned int n) throw (); + int128 & operator >>= (unsigned int n) noexcept; + int128 & operator <<= (unsigned int n) noexcept; - int128 & operator |= (const int128 & b) throw (); - int128 & operator &= (const int128 & b) throw (); - int128 & operator ^= (const int128 & b) throw (); + int128 & operator |= (const int128 & b) noexcept; + int128 & operator &= (const int128 & b) noexcept; + int128 & operator ^= (const int128 & b) noexcept; // Inline simple operators - inline const int128 & operator + () const throw () { return *this; }; + inline const int128 & operator + () const noexcept { return *this; }; // Rest of inline operators - inline int128 & operator -= (const int128 & b) throw () { + inline int128 & operator -= (const int128 & b) noexcept { return *this += (-b); }; - inline int128 & operator /= (const int128 & b) throw () { + inline int128 & operator /= (const int128 & b) noexcept { int128 dummy; *this = this->div (b, dummy); return *this; }; - inline int128 & operator %= (const int128 & b) throw () { + inline int128 & operator %= (const int128 & b) noexcept { this->div (b, *this); return *this; }; // Common methods - int toInt () const throw () { return (int) this->lo; }; - int64s toInt64 () const throw () { return (int64s) this->lo; }; + int toInt () const noexcept { return (int) this->lo; }; + int64s toInt64 () const noexcept { return (int64s) this->lo; }; - const char * toString (unsigned int radix = 10) const throw (); - float toFloat () const throw (); - double toDouble () const throw (); - long double toLongDouble () const throw (); + const char * toString (unsigned int radix = 10) const noexcept; + float toFloat () const noexcept; + double toDouble () const noexcept; + long double toLongDouble () const noexcept; // Arithmetic methods - int128 div (const int128 &, int128 &) const throw (); + int128 div (const int128 &, int128 &) const noexcept; // Bit operations - bool bit (unsigned int n) const throw (); - void bit (unsigned int n, bool val) throw (); + bool bit (unsigned int n) const noexcept; + void bit (unsigned int n, bool val) noexcept; } -#ifdef __GNUC__ +#if defined(__GNUC__) && !defined(__ANDROID_API__) __attribute__ ((__aligned__ (16), __packed__)) #endif ; @@ -145,44 +137,44 @@ class int128 { // GLOBAL OPERATORS -bool operator < (const int128 & a, const int128 & b) throw (); -bool operator == (const int128 & a, const int128 & b) throw (); -bool operator || (const int128 & a, const int128 & b) throw (); -bool operator && (const int128 & a, const int128 & b) throw (); +bool operator < (const int128 & a, const int128 & b) noexcept; +bool operator == (const int128 & a, const int128 & b) noexcept; +bool operator || (const int128 & a, const int128 & b) noexcept; +bool operator && (const int128 & a, const int128 & b) noexcept; // GLOBAL OPERATOR INLINES -inline int128 operator + (const int128 & a, const int128 & b) throw () { - return int128 (a) += b; }; -inline int128 operator - (const int128 & a, const int128 & b) throw () { - return int128 (a) -= b; }; -inline int128 operator * (const int128 & a, const int128 & b) throw () { - return int128 (a) *= b; }; -inline int128 operator / (const int128 & a, const int128 & b) throw () { - return int128 (a) /= b; }; -inline int128 operator % (const int128 & a, const int128 & b) throw () { - return int128 (a) %= b; }; - -inline int128 operator >> (const int128 & a, unsigned int n) throw () { - return int128 (a) >>= n; }; -inline int128 operator << (const int128 & a, unsigned int n) throw () { - return int128 (a) <<= n; }; - -inline int128 operator & (const int128 & a, const int128 & b) throw () { - return int128 (a) &= b; }; -inline int128 operator | (const int128 & a, const int128 & b) throw () { - return int128 (a) |= b; }; -inline int128 operator ^ (const int128 & a, const int128 & b) throw () { - return int128 (a) ^= b; }; - -inline bool operator > (const int128 & a, const int128 & b) throw () { - return b < a; }; -inline bool operator <= (const int128 & a, const int128 & b) throw () { - return !(b < a); }; -inline bool operator >= (const int128 & a, const int128 & b) throw () { - return !(a < b); }; -inline bool operator != (const int128 & a, const int128 & b) throw () { - return !(a == b); }; +inline int128 operator + (const int128 & a, const int128 & b) noexcept { + return int128 (a) += b; } +inline int128 operator - (const int128 & a, const int128 & b) noexcept { + return int128 (a) -= b; } +inline int128 operator * (const int128 & a, const int128 & b) noexcept { + return int128 (a) *= b; } +inline int128 operator / (const int128 & a, const int128 & b) noexcept { + return int128 (a) /= b; } +inline int128 operator % (const int128 & a, const int128 & b) noexcept { + return int128 (a) %= b; } + +inline int128 operator >> (const int128 & a, unsigned int n) noexcept { + return int128 (a) >>= n; } +inline int128 operator << (const int128 & a, unsigned int n) noexcept { + return int128 (a) <<= n; } + +inline int128 operator & (const int128 & a, const int128 & b) noexcept { + return int128 (a) &= b; } +inline int128 operator | (const int128 & a, const int128 & b) noexcept { + return int128 (a) |= b; } +inline int128 operator ^ (const int128 & a, const int128 & b) noexcept { + return int128 (a) ^= b; } + +inline bool operator > (const int128 & a, const int128 & b) noexcept { + return b < a; } +inline bool operator <= (const int128 & a, const int128 & b) noexcept { + return !(b < a); } +inline bool operator >= (const int128 & a, const int128 & b) noexcept { + return !(a < b); } +inline bool operator != (const int128 & a, const int128 & b) noexcept { + return !(a == b); } // MISC diff --git a/Source/ZenLib/int128u.cpp b/Source/ZenLib/int128u.cpp index 476f0c75..90497f5a 100644 --- a/Source/ZenLib/int128u.cpp +++ b/Source/ZenLib/int128u.cpp @@ -55,7 +55,7 @@ namespace ZenLib // IMPLEMENTATION -const char * uint128::toString (unsigned int radix) const throw () { +const char * uint128::toString (unsigned int radix) const noexcept { if (!*this) return "0"; if (radix < 2 || radix > 37) return "(invalid radix)"; @@ -72,9 +72,9 @@ const char * uint128::toString (unsigned int radix) const throw () { }; return &sz [i]; -}; +} -uint128::uint128 (const char * sz) throw () +uint128::uint128 (const char * sz) noexcept : lo (0u), hi (0u) { if (!sz) return; @@ -117,55 +117,55 @@ uint128::uint128 (const char * sz) throw () *this = 0u - *this; return; -}; +} -uint128::uint128 (const float a) throw () +uint128::uint128 (const float a) noexcept #if defined (__mips__) || defined (__mipsel__) : lo ((int64u) fmod ((const double)a, 18446744073709551616.0)), #else : lo ((int64u) fmodf (a, 18446744073709551616.0f)), #endif - hi ((int64u) (a / 18446744073709551616.0f)) {}; + hi ((int64u) (a / 18446744073709551616.0f)) {} -uint128::uint128 (const double & a) throw () +uint128::uint128 (const double & a) noexcept : lo ((int64u) fmod (a, 18446744073709551616.0)), - hi ((int64u) (a / 18446744073709551616.0)) {}; + hi ((int64u) (a / 18446744073709551616.0)) {} -uint128::uint128 (const long double & a) throw () +uint128::uint128 (const long double & a) noexcept #if defined (__mips__) || defined (__mipsel__) : lo ((int64u) fmod ((const double)a, 18446744073709551616.0)), #else : lo ((int64u) fmodl (a, 18446744073709551616.0l)), #endif - hi ((int64u) (a / 18446744073709551616.0l)) {}; + hi ((int64u) (a / 18446744073709551616.0l)) {} -float uint128::toFloat () const throw () { +float uint128::toFloat () const noexcept { return (float) this->hi * 18446744073709551616.0f + (float) this->lo; -}; +} -double uint128::toDouble () const throw () { +double uint128::toDouble () const noexcept { return (double) this->hi * 18446744073709551616.0 + (double) this->lo; -}; +} -long double uint128::toLongDouble () const throw () { +long double uint128::toLongDouble () const noexcept { return (long double) this->hi * 18446744073709551616.0l + (long double) this->lo; -}; +} -uint128 uint128::operator - () const throw () { +uint128 uint128::operator - () const noexcept { if (!this->hi && !this->lo) // number is 0, just return 0 return *this; else // non 0 number return uint128 (0-this->lo, ~this->hi); -}; +} -uint128 uint128::operator ~ () const throw () { +uint128 uint128::operator ~ () const noexcept { return uint128 (~this->lo, ~this->hi); -}; +} uint128 & uint128::operator ++ () { ++this->lo; @@ -173,7 +173,7 @@ uint128 & uint128::operator ++ () { ++this->hi; return *this; -}; +} uint128 & uint128::operator -- () { if (!this->lo) @@ -181,32 +181,32 @@ uint128 & uint128::operator -- () { --this->lo; return *this; -}; +} uint128 uint128::operator ++ (int) { uint128 b = *this; ++ *this; return b; -}; +} uint128 uint128::operator -- (int) { uint128 b = *this; -- *this; return b; -}; +} -uint128 & uint128::operator += (const uint128 & b) throw () { +uint128 & uint128::operator += (const uint128 & b) noexcept { int64u old_lo = this->lo; this->lo += b.lo; this->hi += b.hi + (this->lo < old_lo); return *this; -}; +} -uint128 & uint128::operator *= (const uint128 & b) throw () { +uint128 & uint128::operator *= (const uint128 & b) noexcept { if (!b) return *this = 0u; if (b == 1u) @@ -226,10 +226,10 @@ uint128 & uint128::operator *= (const uint128 & b) throw () { }; return *this; -}; +} -uint128 uint128::div (const uint128 & ds, uint128 & remainder) const throw () { +uint128 uint128::div (const uint128 & ds, uint128 & remainder) const noexcept { if (!ds) return 1u / (unsigned int) ds.lo; @@ -268,18 +268,18 @@ uint128 uint128::div (const uint128 & ds, uint128 & remainder) const throw () { remainder = r; return q; -}; +} -bool uint128::bit (unsigned int n) const throw () { +bool uint128::bit (unsigned int n) const noexcept { n &= 0x7F; if (n < 64) return (this->lo & (1ull << n))?true:false; else return (this->hi & (1ull << (n - 64)))?true:false; -}; +} -void uint128::bit (unsigned int n, bool val) throw () { +void uint128::bit (unsigned int n, bool val) noexcept { n &= 0x7F; if (val) { @@ -289,10 +289,10 @@ void uint128::bit (unsigned int n, bool val) throw () { if (n < 64) this->lo &= ~(1ull << n); else this->hi &= ~(1ull << (n - 64)); }; -}; +} -uint128 & uint128::operator >>= (unsigned int n) throw () { +uint128 & uint128::operator >>= (unsigned int n) noexcept { n &= 0x7F; if (n > 63) { @@ -317,9 +317,9 @@ uint128 & uint128::operator >>= (unsigned int n) throw () { }; return *this; -}; +} -uint128 & uint128::operator <<= (unsigned int n) throw () { +uint128 & uint128::operator <<= (unsigned int n) noexcept { n &= 0x7F; if (n > 63) { @@ -344,45 +344,45 @@ uint128 & uint128::operator <<= (unsigned int n) throw () { }; return *this; -}; +} -bool uint128::operator ! () const throw () { +bool uint128::operator ! () const noexcept { return !(this->hi || this->lo); -}; +} -uint128 & uint128::operator |= (const uint128 & b) throw () { +uint128 & uint128::operator |= (const uint128 & b) noexcept { this->hi |= b.hi; this->lo |= b.lo; return *this; -}; +} -uint128 & uint128::operator &= (const uint128 & b) throw () { +uint128 & uint128::operator &= (const uint128 & b) noexcept { this->hi &= b.hi; this->lo &= b.lo; return *this; -}; +} -uint128 & uint128::operator ^= (const uint128 & b) throw () { +uint128 & uint128::operator ^= (const uint128 & b) noexcept { this->hi ^= b.hi; this->lo ^= b.lo; return *this; -}; +} -bool operator < (const uint128 & a, const uint128 & b) throw () { +bool operator < (const uint128 & a, const uint128 & b) noexcept { return (a.hi == b.hi) ? (a.lo < b.lo) : (a.hi < b.hi); -}; +} -bool operator == (const uint128 & a, const uint128 & b) throw () { +bool operator == (const uint128 & a, const uint128 & b) noexcept { return a.hi == b.hi && a.lo == b.lo; -}; -bool operator && (const uint128 & a, const uint128 & b) throw () { +} +bool operator && (const uint128 & a, const uint128 & b) noexcept { return (a.hi || a.lo) && (b.hi || b.lo); -}; -bool operator || (const uint128 & a, const uint128 & b) throw () { +} +bool operator || (const uint128 & a, const uint128 & b) noexcept { return (a.hi || a.lo) || (b.hi || b.lo); -}; +} } //NameSpace diff --git a/Source/ZenLib/int128u.h b/Source/ZenLib/int128u.h index e2a422df..3a77a364 100644 --- a/Source/ZenLib/int128u.h +++ b/Source/ZenLib/int128u.h @@ -25,10 +25,6 @@ Version: 1.1 */ - -#include -#include -#include #include "ZenLib/Conf.h" // CLASS @@ -44,136 +40,136 @@ class uint128 { protected: // Some global operator functions must be friends - friend bool operator < (const uint128 &, const uint128 &) throw (); - friend bool operator == (const uint128 &, const uint128 &) throw (); - friend bool operator || (const uint128 &, const uint128 &) throw (); - friend bool operator && (const uint128 &, const uint128 &) throw (); + friend bool operator < (const uint128 &, const uint128 &) noexcept; + friend bool operator == (const uint128 &, const uint128 &) noexcept; + friend bool operator || (const uint128 &, const uint128 &) noexcept; + friend bool operator && (const uint128 &, const uint128 &) noexcept; public: // Constructors - inline uint128 () throw () : lo(0), hi(0) {}; - inline uint128 (const uint128 & a) throw () : lo (a.lo), hi (a.hi) {}; + inline uint128 () noexcept : lo(0), hi(0) {}; + inline uint128 (const uint128 & a) noexcept : lo (a.lo), hi (a.hi) {}; - inline uint128 (const int & a) throw () : lo (a), hi (0ull) {}; - inline uint128 (const unsigned int & a) throw () : lo (a), hi (0ull) {}; - inline uint128 (const int64u & a) throw () : lo (a), hi (0ull) {}; + inline uint128 (const int & a) noexcept : lo (a), hi (0ull) {}; + inline uint128 (const unsigned int & a) noexcept : lo (a), hi (0ull) {}; + inline uint128 (const int64u & a) noexcept : lo (a), hi (0ull) {}; - uint128 (const float a) throw (); - uint128 (const double & a) throw (); - uint128 (const long double & a) throw (); + uint128 (const float a) noexcept; + uint128 (const double & a) noexcept; + uint128 (const long double & a) noexcept; - uint128 (const char * sz) throw (); + uint128 (const char * sz) noexcept; // TODO: Consider creation of operator= to eliminate // the need of intermediate objects during assignments. private: // Special internal constructors - uint128 (const int64u & a, const int64u & b) throw () + uint128 (const int64u & a, const int64u & b) noexcept : lo (a), hi (b) {}; public: // Operators - bool operator ! () const throw (); + bool operator ! () const noexcept; - uint128 operator - () const throw (); - uint128 operator ~ () const throw (); + uint128 operator - () const noexcept; + uint128 operator ~ () const noexcept; uint128 & operator ++ (); uint128 & operator -- (); uint128 operator ++ (int); uint128 operator -- (int); - uint128 & operator += (const uint128 & b) throw (); - uint128 & operator *= (const uint128 & b) throw (); + uint128 & operator += (const uint128 & b) noexcept; + uint128 & operator *= (const uint128 & b) noexcept; - uint128 & operator >>= (unsigned int n) throw (); - uint128 & operator <<= (unsigned int n) throw (); + uint128 & operator >>= (unsigned int n) noexcept; + uint128 & operator <<= (unsigned int n) noexcept; - uint128 & operator |= (const uint128 & b) throw (); - uint128 & operator &= (const uint128 & b) throw (); - uint128 & operator ^= (const uint128 & b) throw (); + uint128 & operator |= (const uint128 & b) noexcept; + uint128 & operator &= (const uint128 & b) noexcept; + uint128 & operator ^= (const uint128 & b) noexcept; // Inline simple operators - inline const uint128 & operator + () const throw () { return *this; }; + inline const uint128 & operator + () const noexcept { return *this; } // Rest of inline operators - inline uint128 & operator -= (const uint128 & b) throw () { + inline uint128 & operator -= (const uint128 & b) noexcept { return *this += (-b); }; - inline uint128 & operator /= (const uint128 & b) throw () { + inline uint128 & operator /= (const uint128 & b) noexcept { uint128 dummy; *this = this->div (b, dummy); return *this; }; - inline uint128 & operator %= (const uint128 & b) throw () { + inline uint128 & operator %= (const uint128 & b) noexcept { this->div (b, *this); return *this; }; // Common methods - unsigned int toUint () const throw () { - return (unsigned int) this->lo; }; - int64u toUint64 () const throw () { - return (int64u) this->lo; }; - const char * toString (unsigned int radix = 10) const throw (); - float toFloat () const throw (); - double toDouble () const throw (); - long double toLongDouble () const throw (); + unsigned int toUint () const noexcept { + return (unsigned int) this->lo; } + int64u toUint64 () const noexcept { + return (int64u) this->lo; } + const char * toString (unsigned int radix = 10) const noexcept; + float toFloat () const noexcept; + double toDouble () const noexcept; + long double toLongDouble () const noexcept; // Arithmetic methods - uint128 div (const uint128 &, uint128 &) const throw (); + uint128 div (const uint128 &, uint128 &) const noexcept; // Bit operations - bool bit (unsigned int n) const throw (); - void bit (unsigned int n, bool val) throw (); + bool bit (unsigned int n) const noexcept; + void bit (unsigned int n, bool val) noexcept; } -#ifdef __GNUC__ - __attribute__ ((__aligned__ (16), __packed__)) +#if defined(__GNUC__) && !defined(__ANDROID_API__) + __attribute__ ((__aligned__ (16), __packed__)) #endif ; // GLOBAL OPERATORS -bool operator < (const uint128 & a, const uint128 & b) throw (); -bool operator == (const uint128 & a, const uint128 & b) throw (); -bool operator || (const uint128 & a, const uint128 & b) throw (); -bool operator && (const uint128 & a, const uint128 & b) throw (); +bool operator < (const uint128 & a, const uint128 & b) noexcept; +bool operator == (const uint128 & a, const uint128 & b) noexcept; +bool operator || (const uint128 & a, const uint128 & b) noexcept; +bool operator && (const uint128 & a, const uint128 & b) noexcept; // GLOBAL OPERATOR INLINES -inline uint128 operator + (const uint128 & a, const uint128 & b) throw () { - return uint128 (a) += b; }; -inline uint128 operator - (const uint128 & a, const uint128 & b) throw () { - return uint128 (a) -= b; }; -inline uint128 operator * (const uint128 & a, const uint128 & b) throw () { - return uint128 (a) *= b; }; -inline uint128 operator / (const uint128 & a, const uint128 & b) throw () { - return uint128 (a) /= b; }; -inline uint128 operator % (const uint128 & a, const uint128 & b) throw () { - return uint128 (a) %= b; }; - -inline uint128 operator >> (const uint128 & a, unsigned int n) throw () { - return uint128 (a) >>= n; }; -inline uint128 operator << (const uint128 & a, unsigned int n) throw () { - return uint128 (a) <<= n; }; - -inline uint128 operator & (const uint128 & a, const uint128 & b) throw () { - return uint128 (a) &= b; }; -inline uint128 operator | (const uint128 & a, const uint128 & b) throw () { - return uint128 (a) |= b; }; -inline uint128 operator ^ (const uint128 & a, const uint128 & b) throw () { - return uint128 (a) ^= b; }; - -inline bool operator > (const uint128 & a, const uint128 & b) throw () { - return b < a; }; -inline bool operator <= (const uint128 & a, const uint128 & b) throw () { - return !(b < a); }; -inline bool operator >= (const uint128 & a, const uint128 & b) throw () { - return !(a < b); }; -inline bool operator != (const uint128 & a, const uint128 & b) throw () { - return !(a == b); }; +inline uint128 operator + (const uint128 & a, const uint128 & b) noexcept { + return uint128 (a) += b; } +inline uint128 operator - (const uint128 & a, const uint128 & b) noexcept { + return uint128 (a) -= b; } +inline uint128 operator * (const uint128 & a, const uint128 & b) noexcept { + return uint128 (a) *= b; } +inline uint128 operator / (const uint128 & a, const uint128 & b) noexcept { + return uint128 (a) /= b; } +inline uint128 operator % (const uint128 & a, const uint128 & b) noexcept { + return uint128 (a) %= b; } + +inline uint128 operator >> (const uint128 & a, unsigned int n) noexcept { + return uint128 (a) >>= n; } +inline uint128 operator << (const uint128 & a, unsigned int n) noexcept { + return uint128 (a) <<= n; } + +inline uint128 operator & (const uint128 & a, const uint128 & b) noexcept { + return uint128 (a) &= b; } +inline uint128 operator | (const uint128 & a, const uint128 & b) noexcept { + return uint128 (a) |= b; } +inline uint128 operator ^ (const uint128 & a, const uint128 & b) noexcept { + return uint128 (a) ^= b; } + +inline bool operator > (const uint128 & a, const uint128 & b) noexcept { + return b < a; } +inline bool operator <= (const uint128 & a, const uint128 & b) noexcept { + return !(b < a); } +inline bool operator >= (const uint128 & a, const uint128 & b) noexcept { + return !(a < b); } +inline bool operator != (const uint128 & a, const uint128 & b) noexcept { + return !(a == b); } // MISC