diff --git a/src/xvaga/agasys.cpp b/src/xvaga/agasys.cpp index 0828b5af5..4cca169bd 100755 --- a/src/xvaga/agasys.cpp +++ b/src/xvaga/agasys.cpp @@ -3,12 +3,14 @@ #include "agasys.h" #include "xvt.h" +#include "guid.hpp" /////////////////////////////////////////////////////////// // Unzip support /////////////////////////////////////////////////////////// #include +#include #include #include @@ -49,10 +51,10 @@ bool aga_unzip(const char* zipfile, const char* destdir) wxFFileInputStream file(zipfile); wxZipInputStream fin(file); - wxZipEntry* entry = NULL; + wxZipEntry* entry = nullptr; do entry = fin.GetNextEntry(); while (entry && entry->GetInternalName() != strFileName); - if (entry == NULL || !fin.OpenEntry(*entry)) + if (entry == nullptr || !fin.OpenEntry(*entry)) continue; wxString strOutFile = destdir; @@ -61,7 +63,7 @@ bool aga_unzip(const char* zipfile, const char* destdir) strOutFile += strFileName; wxString strPath; - ::wxSplitPath(strOutFile, &strPath, NULL, NULL); + ::wxSplitPath(strOutFile, &strPath, nullptr, nullptr); xvt_fsys_mkdir(strPath); wxFileOutputStream fout(strOutFile); @@ -154,7 +156,7 @@ bool aga_zip_filelist(const char* filelist, const char* zipfile) #include #define wxAgaClient wxDDEClient -static wxAgaClient* _net_client = NULL; +static wxAgaClient* _net_client = nullptr; static unsigned long _net_conns = 0; class wxAgaConnection : public wxDDEConnection @@ -169,21 +171,21 @@ bool wxAgaConnection::ExecuteAsync(const wxChar *data, int size, wxIPCFormat WXU if (size < 0) size = (wxStrlen(data) + 1) * sizeof(wxChar); // includes final NUL - bool ok = DdeClientTransaction((LPBYTE)data, size, (HCONV)m_hConv, NULL, + bool ok = DdeClientTransaction((LPBYTE)data, size, (HCONV)m_hConv, nullptr, 0, XTYP_EXECUTE, TIMEOUT_ASYNC, &result) != 0; return ok; } unsigned long aga_dde_connect(const char* host, const char* service, const char* topic) { - if (_net_client == NULL) + if (_net_client == nullptr) { _net_client = new wxAgaClient; _net_conns = 0; } wxConnectionBase* conn = _net_client->MakeConnection(host, service, topic); - if (conn != NULL) + if (conn != nullptr) _net_conns++; return (unsigned long)conn; @@ -235,7 +237,7 @@ bool aga_dde_execute_async(unsigned long connection, const char* msg) bool aga_dde_terminate(unsigned long connection) { bool ok = false; - if (connection != 0 && _net_client != NULL) + if (connection != 0 && _net_client != nullptr) { wxAgaConnection* conn = (wxAgaConnection*)connection; ok = conn->Disconnect(); @@ -245,7 +247,7 @@ bool aga_dde_terminate(unsigned long connection) if (_net_conns == 0) { delete _net_client; - _net_client = NULL; + _net_client = nullptr; } } } @@ -256,21 +258,20 @@ bool aga_dde_terminate(unsigned long connection) // Multi file operations /////////////////////////////////////////////////////////// -/* Solo da Vista in poi... +//Solo da Vista in poi... #include #include static IFileOperation* CreatePFO() { - return NULL; - HRESULT hr = ::CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); + HRESULT hr = ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); if (!SUCCEEDED(hr)) - return NULL; + return nullptr; - IFileOperation *pfo = NULL; - hr = ::CoCreateInstance(CLSID_FileOperation, NULL, CLSCTX_ALL, IID_PPV_ARGS(&pfo)); + IFileOperation *pfo = nullptr; + hr = ::CoCreateInstance(CLSID_FileOperation, nullptr, CLSCTX_ALL, IID_PPV_ARGS(&pfo)); if (!SUCCEEDED(hr)) - return NULL; + return nullptr; pfo->SetOperationFlags(FOF_NOCONFIRMATION); @@ -282,14 +283,13 @@ static void DeleteIUnknown(IUnknown* iu) if (iu) { iu->Release(); - iu = NULL; + iu = nullptr; } } -*/ + int xvt_fsys_files_remove(const char* src, SLIST names) { -/* int nDone = 0; IFileOperation *pfo = CreatePFO(); if (!pfo) @@ -301,12 +301,12 @@ int xvt_fsys_files_remove(const char* src, SLIST names) { wxString n = src; wxWritableWCharBuffer wcb = n.wchar_str(); - IShellItem* psiFolder = NULL; - hr = ::SHCreateItemFromParsingName(wcb, NULL, IID_PPV_ARGS(&psiFolder)); + IShellItem * psiFolder = nullptr; + hr = ::SHCreateItemFromParsingName(wcb, nullptr, IID_PPV_ARGS(&psiFolder)); if (SUCCEEDED(hr)) { - IEnumShellItems* pEnum = NULL; - hr = psiFolder->BindToHandler(NULL, BHID_EnumItems, IID_IEnumShellItems, (void**)&pEnum); + IEnumShellItems * pEnum = nullptr; + hr = psiFolder->BindToHandler(nullptr, BHID_EnumItems, IID_IEnumShellItems, (void**)&pEnum); if (SUCCEEDED(hr)) { hr = pfo->DeleteItems(pEnum); @@ -321,37 +321,187 @@ int xvt_fsys_files_remove(const char* src, SLIST names) { for (SLIST_ELT e = xvt_slist_get_first(names); e; e = xvt_slist_get_next(names, e)) { - wxFileName n = xvt_slist_get(names, e, NULL); + wxFileName n = xvt_slist_get(names, e, nullptr); if (!n.IsAbsolute()) n.PrependDir(src); wxWritableWCharBuffer wcb = n.GetFullPath().wchar_str(); - IShellItem* psiItem = NULL; - hr = ::SHCreateItemFromParsingName(wcb, NULL, IID_PPV_ARGS(&psiItem)); + IShellItem* psiItem = nullptr; + + hr = ::SHCreateItemFromParsingName(wcb, nullptr, IID_PPV_ARGS(&psiItem)); if (SUCCEEDED(hr)) { - hr = pfo->DeleteItem(psiItem, NULL); + hr = pfo->DeleteItem(psiItem, nullptr); if (SUCCEEDED(hr)) nDone++; DeleteIUnknown(psiItem); } } } - hr = pfo->PerformOperations(); DeleteIUnknown(pfo); return SUCCEEDED(hr) ? nDone : -1; - */ - return -1; // Not implemented yet } int xvt_fsys_files_copy(const char* src, SLIST names, const char* dst) { - return -1; + int nDone = 0; + IFileOperation *pfo = CreatePFO(); + if (!pfo) + return -1; + wxString d = dst; + wxWritableWCharBuffer wcbd = d.wchar_str(); + HRESULT hrd = 0; + IShellItem * pdiFolder = nullptr; + + hrd = ::SHCreateItemFromParsingName(wcbd, nullptr, IID_PPV_ARGS(&pdiFolder)); + if (!SUCCEEDED(hrd)) + return -1; + + HRESULT hr = 0; + + if (xvt_slist_count(names) == 0) + { + wxString n = src; + wxWritableWCharBuffer wcb = n.wchar_str(); + IShellItem * psiFolder = nullptr; + hr = ::SHCreateItemFromParsingName(wcb, nullptr, IID_PPV_ARGS(&psiFolder)); + if (SUCCEEDED(hr)) + { + IEnumShellItems * pEnum = nullptr; + hr = psiFolder->BindToHandler(nullptr, BHID_EnumItems, IID_IEnumShellItems, (void**)&pEnum); + if (SUCCEEDED(hr)) + { + hr = pfo->CopyItems(pEnum, pdiFolder); + if (SUCCEEDED(hr)) + nDone++; + DeleteIUnknown(pEnum); + } + DeleteIUnknown(psiFolder); + } + } + else + { + for (SLIST_ELT e = xvt_slist_get_first(names); e; e = xvt_slist_get_next(names, e)) + { + wxFileName n = xvt_slist_get(names, e, nullptr); + if (!n.IsAbsolute()) + n.PrependDir(src); + wxWritableWCharBuffer wcb = n.GetFullPath().wchar_str(); + IShellItem* psiItem = nullptr; + hr = ::SHCreateItemFromParsingName(wcb, nullptr, IID_PPV_ARGS(&psiItem)); + if (SUCCEEDED(hr)) + { + hr = pfo->CopyItem(psiItem, pdiFolder, nullptr, nullptr); + if (SUCCEEDED(hr)) + nDone++; + DeleteIUnknown(psiItem); + } + } + } + hr = pfo->PerformOperations(); + DeleteIUnknown(pdiFolder); + DeleteIUnknown(pfo); + return SUCCEEDED(hr) ? nDone : -1; } int xvt_fsys_files_move(const char* src, SLIST names, const char* dst) { - return -1; + int nDone = 0; + IFileOperation *pfo = CreatePFO(); + if (!pfo) + return -1; + + wxString d = dst; + wxWritableWCharBuffer wcbd = d.wchar_str(); + HRESULT hrd = 0; + IShellItem * pdiFolder = nullptr; + + hrd = ::SHCreateItemFromParsingName(wcbd, nullptr, IID_PPV_ARGS(&pdiFolder)); + if (!SUCCEEDED(hrd)) + return -1; + + HRESULT hr = 0; + + if (xvt_slist_count(names) == 0) + { + wxString n = src; + wxWritableWCharBuffer wcb = n.wchar_str(); + IShellItem * psiFolder = nullptr; + hr = ::SHCreateItemFromParsingName(wcb, nullptr, IID_PPV_ARGS(&psiFolder)); + if (SUCCEEDED(hr)) + { + IEnumShellItems * pEnum = nullptr; + hr = psiFolder->BindToHandler(nullptr, BHID_EnumItems, IID_IEnumShellItems, (void**)&pEnum); + if (SUCCEEDED(hr)) + { + hr = pfo->MoveItems(pEnum, pdiFolder); + if (SUCCEEDED(hr)) + nDone++; + DeleteIUnknown(pEnum); + } + DeleteIUnknown(psiFolder); + } + } + else + { + for (SLIST_ELT e = xvt_slist_get_first(names); e; e = xvt_slist_get_next(names, e)) + { + wxFileName n = xvt_slist_get(names, e, nullptr); + if (!n.IsAbsolute()) + n.PrependDir(src); + wxWritableWCharBuffer wcb = n.GetFullPath().wchar_str(); + IShellItem* psiItem = nullptr; + hr = ::SHCreateItemFromParsingName(wcb, nullptr, IID_PPV_ARGS(&psiItem)); + if (SUCCEEDED(hr)) + { + hr = pfo->MoveItem(psiItem, pdiFolder, nullptr, nullptr); + if (SUCCEEDED(hr)) + nDone++; + DeleteIUnknown(psiItem); + } + } + } + hr = pfo->PerformOperations(); + DeleteIUnknown(pfo); + DeleteIUnknown(pdiFolder); + return SUCCEEDED(hr) ? nDone : -1; +} + +void xvt_fsys_get_sys_dir(int what_dir, char * dir) +{ + wxFileName d; + wxString out; + + switch (what_dir) + { + case XVT_DESKTOP_DIR: + { + d = wxStandardPaths::Get().GetDocumentsDir(); + + d.SetName(wxString("Desktop")); + out = d.GetFullPath(); + } + break; + case XVT_DOCUMENTS_DIR: + d = wxStandardPaths::Get().GetDocumentsDir(); + out = d.GetFullPath(); + break; + case XVT_EXEC_DIR: + d = wxFileName::DirName(wxStandardPaths::Get().GetExecutablePath()); + out = d.GetFullPath(); + break; + case XVT_INSTALL_DIR: + d = wxStandardPaths::Get().GetDocumentsDir(); + out = d.GetVolume(); out << wxFileName::GetVolumeSeparator().c_str() << "\\"; + break; + case XVT_TEMP_DIR: + d = wxStandardPaths::Get().GetTempDir(); + out = d.GetFullPath(); + break; + default: + break; + } + wxStrncpy(dir, out, MAX_PATH); } /////////////////////////////////////////////////////////// @@ -477,7 +627,7 @@ void TProgressIndicator::Init(wxString msg, int nGauges, bool bCancellable) m_pEstimated = new wxStaticText(this, 1103, wxT("00:00:00")); pEstimated->Add(m_pEstimated, 0, wxALL|wxALIGN_CENTER, 0); - wxButton* pCancel = NULL; + wxButton* pCancel = nullptr; if (bCancellable) { pCancel = new wxButton(this, wxID_CANCEL, _("Cancel")); @@ -497,14 +647,14 @@ void TProgressIndicator::Init(wxString msg, int nGauges, bool bCancellable) } TProgressIndicator::TProgressIndicator(size_t nRange, wxString msg, bool bCancellable) - : wxDialog(NULL, wxID_ANY, msg) + : wxDialog(nullptr, wxID_ANY, msg) { Init(msg, 1, bCancellable); SetRange(nRange, 0); } TProgressIndicator::TProgressIndicator(wxString msg, bool bCancellable, int nGauges) - : wxDialog(NULL, wxID_ANY, msg) + : wxDialog(nullptr, wxID_ANY, msg) { Init(msg, nGauges, bCancellable); } @@ -536,7 +686,7 @@ public: wxThread::ExitCode TWorker::Entry() { ExitCode ec = 0; - if (m_pi != NULL) + if (m_pi != nullptr) { m_pi->SetRange(m_nLast-m_nFirst, m_nGauge); for (int i = m_nFirst; i < m_nLast && ec == 0; i++) @@ -581,7 +731,7 @@ BOOLEAN xvt_sys_multithread(XVT_MULTITHREAD_CALLBACK pFunc, void* pCaller, void* int ret = 0; if (nWorkers > 1) { - TProgressIndicator* pi = NULL; + TProgressIndicator* pi = nullptr; if (msg && *msg) pi = new TProgressIndicator(msg, tot > nWorkers, nWorkers); @@ -598,7 +748,7 @@ BOOLEAN xvt_sys_multithread(XVT_MULTITHREAD_CALLBACK pFunc, void* pCaller, void* for (w = 0; w < nWorkers; w++) worker[w]->Run(); - if (pi != NULL) + if (pi != nullptr) pi->Refresh(); for (w = 0; w < nWorkers; w++) @@ -607,10 +757,10 @@ BOOLEAN xvt_sys_multithread(XVT_MULTITHREAD_CALLBACK pFunc, void* pCaller, void* if (ret == 0 && r != 0) ret = int(r); delete worker[w]; - worker[w] = NULL; + worker[w] = nullptr; } - if (pi != NULL) + if (pi != nullptr) delete pi; } else @@ -634,3 +784,11 @@ BOOLEAN xvt_sys_multithread(XVT_MULTITHREAD_CALLBACK pFunc, void* pCaller, void* return ret; } + +XVTDLL char * xvt_GUID() +{ + strstream strguid; + + strguid << xg::newGuid() << '\0'; + return strguid.str(); +} \ No newline at end of file diff --git a/src/xvaga/guid.cpp b/src/xvaga/guid.cpp new file mode 100644 index 000000000..d53d12737 --- /dev/null +++ b/src/xvaga/guid.cpp @@ -0,0 +1,407 @@ +/* +The MIT License (MIT) + +Copyright (c) 2014 Graeme Hill (http://graemehill.ca) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + + +#include +#include "guid.hpp" + +#ifdef GUID_LIBUUID +#include +#endif + +#ifdef GUID_CFUUID +#include +#endif + +#ifdef GUID_WINDOWS +#include +#endif + +#ifdef GUID_ANDROID +#include +#include +#endif + +BEGIN_XG_NAMESPACE + +#ifdef GUID_ANDROID +AndroidGuidInfo androidInfo; + +AndroidGuidInfo AndroidGuidInfo::fromJniEnv(JNIEnv *env) +{ + AndroidGuidInfo info; + info.env = env; + auto localUuidClass = env->FindClass("java/util/UUID"); + info.uuidClass = (jclass)env->NewGlobalRef(localUuidClass); + env->DeleteLocalRef(localUuidClass); + info.newGuidMethod = env->GetStaticMethodID( + info.uuidClass, "randomUUID", "()Ljava/util/UUID;"); + info.mostSignificantBitsMethod = env->GetMethodID( + info.uuidClass, "getMostSignificantBits", "()J"); + info.leastSignificantBitsMethod = env->GetMethodID( + info.uuidClass, "getLeastSignificantBits", "()J"); + info.initThreadId = std::this_thread::get_id(); + return info; +} + +void initJni(JNIEnv *env) +{ + androidInfo = AndroidGuidInfo::fromJniEnv(env); +} +#endif + +// overload << so that it's easy to convert to a string +std::ostream &operator<<(std::ostream &s, const Guid &guid) +{ + std::ios_base::fmtflags f(s.flags()); // politely don't leave the ostream in hex mode + s << std::hex << std::setfill('0') + << std::setw(2) << (int)guid._bytes[0] + << std::setw(2) << (int)guid._bytes[1] + << std::setw(2) << (int)guid._bytes[2] + << std::setw(2) << (int)guid._bytes[3] + << "-" + << std::setw(2) << (int)guid._bytes[4] + << std::setw(2) << (int)guid._bytes[5] + << "-" + << std::setw(2) << (int)guid._bytes[6] + << std::setw(2) << (int)guid._bytes[7] + << "-" + << std::setw(2) << (int)guid._bytes[8] + << std::setw(2) << (int)guid._bytes[9] + << "-" + << std::setw(2) << (int)guid._bytes[10] + << std::setw(2) << (int)guid._bytes[11] + << std::setw(2) << (int)guid._bytes[12] + << std::setw(2) << (int)guid._bytes[13] + << std::setw(2) << (int)guid._bytes[14] + << std::setw(2) << (int)guid._bytes[15]; + s.flags(f); + return s; +} + +bool operator<(const xg::Guid &lhs, const xg::Guid &rhs) +{ + return lhs.bytes() < rhs.bytes(); +} + +bool Guid::isValid() const +{ + xg::Guid empty; + return *this != empty; +} + +// convert to string using std::snprintf() and std::string +std::string Guid::str() const +{ + char one[10], two[6], three[6], four[6], five[14]; + + snprintf(one, 10, "%02x%02x%02x%02x", + _bytes[0], _bytes[1], _bytes[2], _bytes[3]); + snprintf(two, 6, "%02x%02x", + _bytes[4], _bytes[5]); + snprintf(three, 6, "%02x%02x", + _bytes[6], _bytes[7]); + snprintf(four, 6, "%02x%02x", + _bytes[8], _bytes[9]); + snprintf(five, 14, "%02x%02x%02x%02x%02x%02x", + _bytes[10], _bytes[11], _bytes[12], _bytes[13], _bytes[14], _bytes[15]); + const std::string sep("-"); + std::string out(one); + + out += sep + two; + out += sep + three; + out += sep + four; + out += sep + five; + + return out; +} + +// conversion operator for std::string +Guid::operator std::string() const +{ + return str(); +} + +// Access underlying bytes +const std::array& Guid::bytes() const +{ + return _bytes; +} + +// create a guid from vector of bytes +Guid::Guid(const std::array &bytes) : _bytes(bytes) +{ } + +// create a guid from vector of bytes +Guid::Guid(std::array &&bytes) : _bytes(std::move(bytes)) +{ } + +// converts a single hex char to a number (0 - 15) +unsigned char hexDigitToChar(char ch) +{ + // 0-9 + if (ch > 47 && ch < 58) + return ch - 48; + + // a-f + if (ch > 96 && ch < 103) + return ch - 87; + + // A-F + if (ch > 64 && ch < 71) + return ch - 55; + + return 0; +} + +bool isValidHexChar(char ch) +{ + // 0-9 + if (ch > 47 && ch < 58) + return true; + + // a-f + if (ch > 96 && ch < 103) + return true; + + // A-F + if (ch > 64 && ch < 71) + return true; + + return false; +} + +// converts the two hexadecimal characters to an unsigned char (a byte) +unsigned char hexPairToChar(char a, char b) +{ + return hexDigitToChar(a) * 16 + hexDigitToChar(b); +} + +// create a guid from string +/* +Guid::Guid(std::string_view fromString) +{ + char charOne = '\0'; + char charTwo = '\0'; + bool lookingForFirstChar = true; + unsigned nextByte = 0; + + for (const char &ch : fromString) + { + if (ch == '-') + continue; + + if (nextByte >= 16 || !isValidHexChar(ch)) + { + // Invalid string so bail + zeroify(); + return; + } + + if (lookingForFirstChar) + { + charOne = ch; + lookingForFirstChar = false; + } + else + { + charTwo = ch; + auto byte = hexPairToChar(charOne, charTwo); + _bytes[nextByte++] = byte; + lookingForFirstChar = true; + } + } + + + // if there were fewer than 16 bytes in the string then guid is bad + if (nextByte < 16) + { + zeroify(); + return; + } +} +*/ + +// create empty guid +Guid::Guid() : _bytes{ {0} } +{ } + +// set all bytes to zero +void Guid::zeroify() +{ + std::fill(_bytes.begin(), _bytes.end(), static_cast(0)); +} + +// overload equality operator +bool Guid::operator==(const Guid &other) const +{ + return _bytes == other._bytes; +} + +// overload inequality operator +bool Guid::operator!=(const Guid &other) const +{ + return !((*this) == other); +} + +// member swap function +void Guid::swap(Guid &other) +{ + _bytes.swap(other._bytes); +} + +// This is the linux friendly implementation, but it could work on other +// systems that have libuuid available +#ifdef GUID_LIBUUID +Guid newGuid() +{ + std::array data; + static_assert(std::is_same::value, "Wrong type!"); + uuid_generate(data.data()); + return Guid{std::move(data)}; +} +#endif + +// this is the mac and ios version +#ifdef GUID_CFUUID +Guid newGuid() +{ + auto newId = CFUUIDCreate(NULL); + auto bytes = CFUUIDGetUUIDBytes(newId); + CFRelease(newId); + + std::array byteArray = + {{ + bytes.byte0, + bytes.byte1, + bytes.byte2, + bytes.byte3, + bytes.byte4, + bytes.byte5, + bytes.byte6, + bytes.byte7, + bytes.byte8, + bytes.byte9, + bytes.byte10, + bytes.byte11, + bytes.byte12, + bytes.byte13, + bytes.byte14, + bytes.byte15 + }}; + return Guid{std::move(byteArray)}; +} +#endif + +// obviously this is the windows version +#ifdef GUID_WINDOWS +Guid newGuid() +{ + GUID newId; + CoCreateGuid(&newId); + + std::array bytes = + { + (unsigned char)((newId.Data1 >> 24) & 0xFF), + (unsigned char)((newId.Data1 >> 16) & 0xFF), + (unsigned char)((newId.Data1 >> 8) & 0xFF), + (unsigned char)((newId.Data1) & 0xff), + + (unsigned char)((newId.Data2 >> 8) & 0xFF), + (unsigned char)((newId.Data2) & 0xff), + + (unsigned char)((newId.Data3 >> 8) & 0xFF), + (unsigned char)((newId.Data3) & 0xFF), + + (unsigned char)newId.Data4[0], + (unsigned char)newId.Data4[1], + (unsigned char)newId.Data4[2], + (unsigned char)newId.Data4[3], + (unsigned char)newId.Data4[4], + (unsigned char)newId.Data4[5], + (unsigned char)newId.Data4[6], + (unsigned char)newId.Data4[7] + }; + + return Guid{std::move(bytes)}; +} +#endif + +// android version that uses a call to a java api +#ifdef GUID_ANDROID +Guid newGuid(JNIEnv *env) +{ + assert(env != androidInfo.env || std::this_thread::get_id() == androidInfo.initThreadId); + + jobject javaUuid = env->CallStaticObjectMethod( + androidInfo.uuidClass, androidInfo.newGuidMethod); + jlong mostSignificant = env->CallLongMethod(javaUuid, + androidInfo.mostSignificantBitsMethod); + jlong leastSignificant = env->CallLongMethod(javaUuid, + androidInfo.leastSignificantBitsMethod); + + std::array bytes = + { + (unsigned char)((mostSignificant >> 56) & 0xFF), + (unsigned char)((mostSignificant >> 48) & 0xFF), + (unsigned char)((mostSignificant >> 40) & 0xFF), + (unsigned char)((mostSignificant >> 32) & 0xFF), + (unsigned char)((mostSignificant >> 24) & 0xFF), + (unsigned char)((mostSignificant >> 16) & 0xFF), + (unsigned char)((mostSignificant >> 8) & 0xFF), + (unsigned char)((mostSignificant) & 0xFF), + (unsigned char)((leastSignificant >> 56) & 0xFF), + (unsigned char)((leastSignificant >> 48) & 0xFF), + (unsigned char)((leastSignificant >> 40) & 0xFF), + (unsigned char)((leastSignificant >> 32) & 0xFF), + (unsigned char)((leastSignificant >> 24) & 0xFF), + (unsigned char)((leastSignificant >> 16) & 0xFF), + (unsigned char)((leastSignificant >> 8) & 0xFF), + (unsigned char)((leastSignificant) & 0xFF) + }; + + env->DeleteLocalRef(javaUuid); + + return Guid{std::move(bytes)}; +} + +Guid newGuid() +{ + return newGuid(androidInfo.env); +} +#endif + + +END_XG_NAMESPACE + +// Specialization for std::swap() -- +// call member swap function of lhs, passing rhs +namespace std +{ + template <> + void swap(xg::Guid &lhs, xg::Guid &rhs) noexcept + { + lhs.swap(rhs); + } +} diff --git a/src/xvaga/guid.hpp b/src/xvaga/guid.hpp new file mode 100644 index 000000000..5d8a96dc5 --- /dev/null +++ b/src/xvaga/guid.hpp @@ -0,0 +1,150 @@ +/* +The MIT License (MIT) + +Copyright (c) 2014 Graeme Hill (http://graemehill.ca) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#pragma once +#define GUID_WINDOWS + +#ifdef GUID_ANDROID +#include +#include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#define BEGIN_XG_NAMESPACE namespace xg { +#define END_XG_NAMESPACE } + +BEGIN_XG_NAMESPACE + +// Class to represent a GUID/UUID. Each instance acts as a wrapper around a +// 16 byte value that can be passed around by value. It also supports +// conversion to string (via the stream operator <<) and conversion from a +// string via constructor. +class Guid +{ +public: + explicit Guid(const std::array &bytes); + explicit Guid(std::array &&bytes); + +// explicit Guid(std::string_view fromString); + Guid(); + + Guid(const Guid &other) = default; + Guid &operator=(const Guid &other) = default; + Guid(Guid &&other) = default; + Guid &operator=(Guid &&other) = default; + + bool operator==(const Guid &other) const; + bool operator!=(const Guid &other) const; + + std::string str() const; + operator std::string() const; + const std::array& bytes() const; + void swap(Guid &other); + bool isValid() const; + +private: + void zeroify(); + + // actual data + std::array _bytes; + + // make the << operator a friend so it can access _bytes + friend std::ostream &operator<<(std::ostream &s, const Guid &guid); + friend bool operator<(const Guid &lhs, const Guid &rhs); +}; + +Guid newGuid(); + +#ifdef GUID_ANDROID +struct AndroidGuidInfo +{ + static AndroidGuidInfo fromJniEnv(JNIEnv *env); + + JNIEnv *env; + jclass uuidClass; + jmethodID newGuidMethod; + jmethodID mostSignificantBitsMethod; + jmethodID leastSignificantBitsMethod; + std::thread::id initThreadId; +}; + +extern AndroidGuidInfo androidInfo; + +void initJni(JNIEnv *env); + +// overloading for multi-threaded calls +Guid newGuid(JNIEnv *env); +#endif + +namespace details +{ + template struct hash; + + template + struct hash : public std::hash + { + using std::hash::hash; + }; + + + template + struct hash + { + inline std::size_t operator()(const T& v, const Rest&... rest) { + std::size_t seed = hash{}(rest...); + seed ^= hash{}(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2); + return seed; + } + }; +} + +END_XG_NAMESPACE + +namespace std +{ + // Template specialization for std::swap() -- + // See guid.cpp for the function definition + template <> + void swap(xg::Guid &guid0, xg::Guid &guid1) noexcept; + + // Specialization for std::hash -- this implementation + // uses std::hash on the stringification of the guid + // to calculate the hash + template <> + struct hash + { + std::size_t operator()(xg::Guid const &guid) const + { + const uint64_t* p = reinterpret_cast(guid.bytes().data()); + return xg::details::hash{}(p[0], p[1]); + } + }; +} diff --git a/src/xvaga/xvaga.cpp b/src/xvaga/xvaga.cpp index bfd8e8378..eb308bb86 100755 --- a/src/xvaga/xvaga.cpp +++ b/src/xvaga/xvaga.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include diff --git a/src/xvaga/xvt.h b/src/xvaga/xvt.h index 10ee5d588..938a894c9 100755 --- a/src/xvaga/xvt.h +++ b/src/xvaga/xvt.h @@ -41,6 +41,12 @@ extern "C" { #endif +#define XVT_DESKTOP_DIR 0 +#define XVT_DOCUMENTS_DIR 1 +#define XVT_EXEC_DIR 2 +#define XVT_INSTALL_DIR 3 +#define XVT_TEMP_DIR 4 + XVTDLL void xvt_app_allow_quit(void); XVTDLL void xvt_app_pre_create(void); XVTDLL void xvt_app_create(int argc, char **argv, unsigned long flags, EVENT_HANDLER eh, XVT_CONFIG *config); @@ -207,6 +213,7 @@ XVTDLL BOOLEAN xvt_fsys_file_md5(const char* path, char* outstr32); XVTDLL int xvt_fsys_files_copy (const char* src, SLIST names, const char* dst); XVTDLL int xvt_fsys_files_move (const char* src, SLIST names, const char* dst); XVTDLL int xvt_fsys_files_remove(const char* src, SLIST names); +XVTDLL void xvt_fsys_get_sys_dir(int what_dir, char * dir); XVTDLL void xvt_help_close_helpfile(XVT_HELP_INFO hi); XVTDLL XVT_HELP_INFO xvt_help_open_helpfile(FILE_SPEC *fs, unsigned long flags); @@ -272,6 +279,8 @@ XVTDLL void xvt_notebk_set_page_title(WINDOW notebk, short page_no, const char XVTDLL void xvt_notebk_rem_page(WINDOW notebk, short page_no); XVTDLL void xvt_notebk_rem_tab(WINDOW notebk, short tab_no); +XVTDLL char * xvt_GUID(); + // Added by Guy typedef const char* TRANSLATE_CALLBACK(const char* ita); XVTDLL void xvt_menu_translate_tree(WINDOW win, TRANSLATE_CALLBACK tc);