diff --git a/build-library.sh b/build-library.sh index 2f9925be8..4db0dbfb3 100755 --- a/build-library.sh +++ b/build-library.sh @@ -8,8 +8,8 @@ if [ "$#" -eq 0 ]; then echo " target: osx ios iossimulator ioscatalyst androidarm androidarm64 androidx86 androidx86_64" echo "To control iOS, macOS builds set environment variables:" echo " minimum deployment target" - echo " - MACOSX_DEPLOYMENT_TARGET=10.15" - echo " - IPHONEOS_DEPLOYMENT_TARGET=12.0" + echo " - MACOSX_DEPLOYMENT_TARGET=11.0" + echo " - IPHONEOS_DEPLOYMENT_TARGET=13.0" echo " archs to build on macOS/iOS" echo " - ARCHS=\"x86_64 arm64\" (macOS)" echo " - ARCHS=\"arm64\" (iOS)" @@ -73,7 +73,7 @@ case "$@" in ;; esac TARGET_PATH=/Library/libdigidocpp.${TARGET} - : ${IPHONEOS_DEPLOYMENT_TARGET:="12.0"} + : ${IPHONEOS_DEPLOYMENT_TARGET:="13.0"} export IPHONEOS_DEPLOYMENT_TARGET CMAKEARGS=" -DCMAKE_OSX_SYSROOT=${SYSROOT} \ diff --git a/prepare_osx_build_environment.sh b/prepare_osx_build_environment.sh index 042408048..a806855c5 100755 --- a/prepare_osx_build_environment.sh +++ b/prepare_osx_build_environment.sh @@ -67,7 +67,7 @@ case "$@" in CONFIGURE="--host=arm-apple-darwin --enable-static --disable-shared --disable-dependency-tracking" SYSROOT=$(xcrun -sdk iphonesimulator --show-sdk-path) : ${ARCHS:="x86_64"} - : ${IPHONEOS_DEPLOYMENT_TARGET:="12.0"} + : ${IPHONEOS_DEPLOYMENT_TARGET:="13.0"} export IPHONEOS_DEPLOYMENT_TARGET export CFLAGS="-arch ${ARCHS// / -arch } -isysroot ${SYSROOT}" ;; @@ -77,7 +77,7 @@ case "$@" in CONFIGURE="--host=x86_64-apple-darwin --enable-static --disable-shared --disable-dependency-tracking" SYSROOT=$(xcrun -sdk macosx --show-sdk-path) : ${ARCHS:="x86_64 arm64"} - : ${IPHONEOS_DEPLOYMENT_TARGET:="12.0"} + : ${IPHONEOS_DEPLOYMENT_TARGET:="13.0"} export IPHONEOS_DEPLOYMENT_TARGET export CFLAGS="-arch ${ARCHS// / -arch } -target x86_64-apple-ios-macabi -isysroot ${SYSROOT}" ;; @@ -87,7 +87,7 @@ case "$@" in CONFIGURE="--host=arm-apple-darwin --enable-static --disable-shared --disable-dependency-tracking" SYSROOT=$(xcrun -sdk iphoneos --show-sdk-path) : ${ARCHS:="arm64"} - : ${IPHONEOS_DEPLOYMENT_TARGET:="12.0"} + : ${IPHONEOS_DEPLOYMENT_TARGET:="13.0"} export IPHONEOS_DEPLOYMENT_TARGET export CFLAGS="-arch ${ARCHS// / -arch } -isysroot ${SYSROOT}" ;; @@ -97,7 +97,7 @@ case "$@" in CONFIGURE="--disable-static --enable-shared --disable-dependency-tracking" SYSROOT=$(xcrun -sdk macosx --show-sdk-path) : ${ARCHS:="x86_64 arm64"} - : ${MACOSX_DEPLOYMENT_TARGET:="10.15"} + : ${MACOSX_DEPLOYMENT_TARGET:="11.0"} export MACOSX_DEPLOYMENT_TARGET export CFLAGS="-arch ${ARCHS// / -arch } " ;; @@ -423,8 +423,8 @@ case "$@" in echo " tasks: xerces, xalan, openssl, xmlsec, xsd, all, help" echo "To control iOS, macOS builds set environment variables:" echo " minimum deployment target" - echo " - MACOSX_DEPLOYMENT_TARGET=10.15" - echo " - IPHONEOS_DEPLOYMENT_TARGET=12.0" + echo " - MACOSX_DEPLOYMENT_TARGET=11.0" + echo " - IPHONEOS_DEPLOYMENT_TARGET=13.0" echo " archs to build on macOS/iOS" echo " - ARCHS=\"x86_64 arm64\" (macOS)" echo " - ARCHS=\"arm64\" (iOS)" diff --git a/src/ASiContainer.cpp b/src/ASiContainer.cpp index f93feefa5..1855f28e0 100644 --- a/src/ASiContainer.cpp +++ b/src/ASiContainer.cpp @@ -154,7 +154,7 @@ unique_ptr ASiContainer::dataStream(const string &path, const ZipSeria { unique_ptr data; if(d->properties[path].size > MAX_MEM_FILE) - data = make_unique(File::encodeName(File::tempFileName()).c_str(), fstream::in|fstream::out|fstream::binary|fstream::trunc); + data = make_unique(File::tempFileName(), fstream::in|fstream::out|fstream::binary|fstream::trunc); else data = make_unique(); z.extract(path, *data); @@ -180,7 +180,7 @@ void ASiContainer::addDataFile(const string &path, const string &mediaType) ZipSerialize::Properties prop { appInfo(), File::modifiedTime(path), File::fileSize(path) }; bool useTempFile = prop.size > MAX_MEM_FILE; - zproperty(File::fileName(path), move(prop)); + zproperty(File::fileName(path), std::move(prop)); unique_ptr is; if(useTempFile) { @@ -193,7 +193,7 @@ void ASiContainer::addDataFile(const string &path, const string &mediaType) *data << file.rdbuf(); is.reset(data); } - addDataFilePrivate(move(is), fileName, mediaType); + addDataFilePrivate(std::move(is), fileName, mediaType); } void ASiContainer::addDataFile(unique_ptr is, const string &fileName, const string &mediaType) @@ -201,7 +201,7 @@ void ASiContainer::addDataFile(unique_ptr is, const string &fileName, c addDataFileChecks(fileName, mediaType); if(fileName.find_last_of("/\\") != string::npos) THROW("Document file '%s' cannot contain directory path.", fileName.c_str()); - addDataFilePrivate(move(is), fileName, mediaType); + addDataFilePrivate(std::move(is), fileName, mediaType); } void ASiContainer::addDataFileChecks(const string &fileName, const string &mediaType) @@ -218,7 +218,7 @@ void ASiContainer::addDataFileChecks(const string &fileName, const string &media void ASiContainer::addDataFilePrivate(unique_ptr is, const string &fileName, const string &mediaType) { - d->documents.push_back(new DataFilePrivate(move(is), fileName, mediaType)); + d->documents.push_back(new DataFilePrivate(std::move(is), fileName, mediaType)); } /** @@ -288,7 +288,7 @@ ZipSerialize::Properties ASiContainer::zproperty(const string &file) const void ASiContainer::zproperty(const string &file, ZipSerialize::Properties &&prop) { - d->properties[file] = move(prop); + d->properties[file] = std::move(prop); } /** diff --git a/src/util/File.cpp b/src/util/File.cpp index a9aecd2cc..363294af5 100644 --- a/src/util/File.cpp +++ b/src/util/File.cpp @@ -62,7 +62,7 @@ using f_statbuf = struct stat; using f_utimbuf = struct utimbuf; #endif -stack File::tempFiles; +stack File::tempFiles; string File::confPath() { @@ -73,63 +73,21 @@ string File::confPath() #elif defined(_WIN32) return dllPath("digidocpp.dll"); #else - return path(env("SNAP"), DIGIDOCPP_CONFIG_DIR "/"); + fs::path result; + if(char *var = getenv("SNAP")) + result = fs::path(var); + return (result / DIGIDOCPP_CONFIG_DIR "/").u8string(); #endif } -#ifndef _WIN32 -string File::env(string_view varname) -{ - if(char *var = getenv(varname.data())) - return decodeName(var); - return {}; -} -#endif - /** * Encodes path to compatible std lib * @param fileName path * @return encoded path */ -File::f_string File::encodeName(string_view fileName) -{ - if(fileName.empty()) - return {}; -#ifdef __APPLE__ - CFStringRef ref = CFStringCreateWithBytesNoCopy({}, (UInt8 *)fileName.data(), - CFIndex(fileName.size()), kCFStringEncodingUTF8, FALSE, kCFAllocatorNull); - string out(fileName.size() * 2, 0); - CFStringGetFileSystemRepresentation(ref, out.data(), CFIndex(out.size())); - CFRelease(ref); - out.resize(strlen(out.c_str())); -#else - f_string out = fs::u8path(fileName); -#endif - return out; -} - -/** - * Decodes path from std lib path - * @param localFileName path - * @return decoded path - */ -string File::decodeName(const f_string_view &localFileName) +fs::path File::encodeName(string_view fileName) { - if(localFileName.empty()) - return {}; -#ifdef __APPLE__ - CFMutableStringRef ref = CFStringCreateMutable(nullptr, 0); - CFStringAppendCString(ref, localFileName.data(), kCFStringEncodingUTF8); - CFStringNormalize(ref, kCFStringNormalizationFormC); - - string out(localFileName.size() * 2, 0); - CFStringGetCString(ref, out.data(), CFIndex(out.size()), kCFStringEncodingUTF8); - CFRelease(ref); - out.resize(strlen(out.c_str())); -#else - string out = fs::path(localFileName).u8string(); -#endif - return out; + return fs::u8path(fileName); } /** @@ -140,8 +98,7 @@ string File::decodeName(const f_string_view &localFileName) */ bool File::fileExists(const string& path) { - f_statbuf fileInfo; - return f_stat(encodeName(path).c_str(), &fileInfo) == 0 && (fileInfo.st_mode & S_IFMT) == S_IFREG; + return fs::is_regular_file(fs::u8path(path)); } #ifdef _WIN32 @@ -167,14 +124,13 @@ string File::dllPath(string_view dll) time_t File::modifiedTime(const string &path) { f_statbuf fileInfo; - return f_stat(encodeName(path).c_str(), &fileInfo) ? time(nullptr) : fileInfo.st_mtime; + return f_stat(fs::u8path(path).c_str(), &fileInfo) ? time(nullptr) : fileInfo.st_mtime; } void File::updateModifiedTime(const string &path, time_t time) { - f_string _path = encodeName(path); f_utimbuf u_time { time, time }; - if(f_utime(_path.c_str(), &u_time)) + if(f_utime(fs::u8path(path).c_str(), &u_time)) THROW("Failed to update file modified time."); } @@ -193,8 +149,7 @@ string File::fileExtension(const string &path) */ unsigned long File::fileSize(const string &path) { - f_statbuf fileInfo; - return f_stat(encodeName(path).c_str(), &fileInfo) ? 0 : (unsigned long)fileInfo.st_size; + return fs::file_size(fs::u8path(path)); } /** @@ -266,26 +221,22 @@ string File::path(string dir, string_view relativePath) /** * @return returns temporary filename. */ -string File::tempFileName() +fs::path File::tempFileName() { #ifdef _WIN32 // requires TMP environment variable to be set wchar_t *fileName = _wtempnam(nullptr, nullptr); // TODO: static buffer, not thread-safe if(!fileName) THROW("Failed to create a temporary file name."); - string path = fs::path(fileName).u8string(); + tempFiles.emplace(fileName); free(fileName); #else -#ifdef __APPLE__ - string path = File::path(env("TMPDIR"), "XXXXXX"); -#else - string path = "/tmp/XXXXXX"; -#endif - if(mkstemp(path.data()) == -1) + string tmp = "XXXXXX"; + if(mkstemp(tmp.data()) == -1) THROW("Failed to create a temporary file name."); + tempFiles.push(fs::temp_directory_path() / tmp); #endif - tempFiles.push(path); - return path; + return tempFiles.top(); } /** @@ -300,7 +251,7 @@ void File::createDirectory(string path) THROW("Can not create directory with no name."); if(path.back() == '/' || path.back() == '\\') path.pop_back(); - f_string _path = encodeName(path); + auto _path = fs::u8path(path); #ifdef _WIN32 int result = _wmkdir(_path.c_str()); #else @@ -327,7 +278,9 @@ string File::digidocppPath() CoTaskMemFree(knownFolder); return appData; #elif defined(ANDROID) - return path(env("HOME"), ".digidocpp"); + if(char *var = getenv("HOME")) + return (fs::path(var) / ".digidocpp").u8string(); + return {}; #else string buf(sysconf(_SC_GETPW_R_SIZE_MAX), 0); passwd pwbuf {}; @@ -363,21 +316,19 @@ string File::fullPathUrl(const string &path) */ void File::deleteTempFiles() { + error_code ec; while(!tempFiles.empty()) { - if(!removeFile(tempFiles.top())) - WARN( "Tried to remove the temporary file or directory '%s', but failed.", tempFiles.top().c_str() ); + if(!fs::remove(tempFiles.top(), ec) || ec) + WARN("Tried to remove the temporary file or directory '%s', but failed.", tempFiles.top().u8string().c_str()); tempFiles.pop(); } } bool File::removeFile(const string &path) { -#ifdef _WIN32 - return _wremove(fs::u8path(path).c_str()) == 0; -#else - return remove(encodeName(path).c_str()) == 0; -#endif + error_code ec; + return fs::remove(fs::u8path(path), ec); } /** diff --git a/src/util/File.h b/src/util/File.h index 65983e980..68a581843 100644 --- a/src/util/File.h +++ b/src/util/File.h @@ -23,6 +23,14 @@ #include +namespace std +{ + namespace filesystem + { + class path; + } +} + namespace digidoc { namespace util @@ -34,18 +42,9 @@ namespace digidoc class File { public: -#ifdef _WIN32 - using f_string = std::wstring; - using f_string_view = std::wstring_view; -#else - using f_string = std::string; - using f_string_view = std::string_view; -#endif static std::string confPath(); static std::string digidocppPath(); - static f_string encodeName(std::string_view fileName); - static std::string decodeName(const f_string_view &localFileName); - static bool isRelative(const std::string &path); + static std::filesystem::path encodeName(std::string_view fileName); static time_t modifiedTime(const std::string &path); static void updateModifiedTime(const std::string &path, time_t time); static bool fileExists(const std::string& path); @@ -55,7 +54,7 @@ namespace digidoc static std::string directory(const std::string& path); static std::string path(std::string dir, std::string_view relativePath); static std::string fullPathUrl(const std::string &path); - static std::string tempFileName(); + static std::filesystem::path tempFileName(); static void createDirectory(std::string path); static void deleteTempFiles(); static bool removeFile(const std::string &path); @@ -71,10 +70,7 @@ namespace digidoc #ifdef __APPLE__ static std::string frameworkResourcesPath(std::string_view name); #endif - static std::stack tempFiles; -#ifndef _WIN32 - static std::string env(std::string_view varname); -#endif + static std::stack tempFiles; }; } diff --git a/src/util/ZipSerialize.cpp b/src/util/ZipSerialize.cpp index 87bf9dbe3..3101270c7 100644 --- a/src/util/ZipSerialize.cpp +++ b/src/util/ZipSerialize.cpp @@ -20,7 +20,6 @@ #include "ZipSerialize.h" #include "DateTime.h" -#include "File.h" #include "log.h" #include @@ -30,6 +29,7 @@ #endif #include +#include #include using namespace digidoc; @@ -59,18 +59,18 @@ ZipSerialize::ZipSerialize(string path, bool create) #else fill_fopen_filefunc(&d->def); #endif - d->path = move(path); + d->path = std::move(path); if(create) { DEBUG("ZipSerialize::create(%s)", d->path.c_str()); - d->create = zipOpen2((const char*)util::File::encodeName(d->path).c_str(), APPEND_STATUS_CREATE, nullptr, &d->def); + d->create = zipOpen2((const char*)filesystem::u8path(d->path).c_str(), APPEND_STATUS_CREATE, nullptr, &d->def); if(!d->create) THROW("Failed to create ZIP file '%s'.", d->path.c_str()); } else { DEBUG("ZipSerialize::open(%s)", d->path.c_str()); - d->open = unzOpen2((const char*)util::File::encodeName(d->path).c_str(), &d->def); + d->open = unzOpen2((const char*)filesystem::u8path(d->path).c_str(), &d->def); if(!d->open) THROW("Failed to open ZIP file '%s'.", d->path.c_str()); } @@ -115,7 +115,7 @@ vector ZipSerialize::list() const if(unzResult != UNZ_OK) THROW("Failed to get filename of the current file inside ZIP container. ZLib error: %d", unzResult); - list.push_back(move(fileName)); + list.push_back(std::move(fileName)); } return list; diff --git a/src/xml/URIResolver.cpp b/src/xml/URIResolver.cpp index 514acef02..41a276bbd 100644 --- a/src/xml/URIResolver.cpp +++ b/src/xml/URIResolver.cpp @@ -74,24 +74,21 @@ BinInputStream* URIResolver::resolveURI(const XMLCh *uri) throw XSECException(XSECException::ErrorOpeningURI, "XSECURIResolverXerces - anonymous references not supported in default URI Resolvers"); -#ifdef _WIN32 - string _uri = File::decodeName(reinterpret_cast(uri)); -#else - string _uri = xsd::cxx::xml::transcode(uri); -#endif - if(strncmp(_uri.c_str(), "/", 1) == 0) _uri.erase(0, 1); + string _uri = File::fromUriPath(xsd::cxx::xml::transcode(uri)); + if(_uri.front() == '/') + _uri.erase(0); for(const DataFile *file: doc_->dataFiles()) { - if(file->fileName() == File::fromUriPath(_uri)) + if(file->fileName() == _uri) return new IStreamInputStream(static_cast(file)->m_is.get()); } if(doc_->mediaType() == ASiC_E::MIMETYPE_ADOC) { - ASiC_E *adoc = static_cast(doc_); + auto *adoc = static_cast(doc_); for(const DataFile *file: adoc->metaFiles()) { - if(file->fileName() == File::fromUriPath(_uri)) + if(file->fileName() == _uri) return new IStreamInputStream(static_cast(file)->m_is.get()); } }