Line data Source code
1 : /** 2 : Copyright (c) 2023 Stappler LLC <admin@stappler.dev> 3 : 4 : Permission is hereby granted, free of charge, to any person obtaining a copy 5 : of this software and associated documentation files (the "Software"), to deal 6 : in the Software without restriction, including without limitation the rights 7 : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 : copies of the Software, and to permit persons to whom the Software is 9 : furnished to do so, subject to the following conditions: 10 : 11 : The above copyright notice and this permission notice shall be included in 12 : all copies or substantial portions of the Software. 13 : 14 : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 : THE SOFTWARE. 21 : **/ 22 : 23 : #ifndef XENOLITH_RESOURCES_ASSETS_XLASSET_H_ 24 : #define XENOLITH_RESOURCES_ASSETS_XLASSET_H_ 25 : 26 : #include "XLNetworkRequest.h" 27 : #include "XLStorageServer.h" 28 : #include "SPSubscription.h" 29 : 30 : namespace STAPPLER_VERSIONIZED stappler::xenolith::storage { 31 : 32 : class Asset; 33 : class AssetLibrary; 34 : struct AssetDownloadData; 35 : 36 : struct AssetVersionData { 37 : bool complete = false; 38 : bool download = false; // is download active for file 39 : uint32_t locked = 0; 40 : int64_t id = 0; 41 : Time ctime; // creation time 42 : Time mtime; // last modification time 43 : size_t size = 0; // file size 44 : float progress = 0.0f; // download progress 45 : 46 : String path; 47 : String contentType; 48 : String etag; 49 : }; 50 : 51 : class AssetLock : public Ref { 52 : public: 53 : virtual ~AssetLock(); 54 : 55 : int64_t getId() const { return _lockedVersion.id; } 56 : Time getCTime() const { return _lockedVersion.ctime; } 57 : Time getMTime() const { return _lockedVersion.mtime; } 58 : size_t getSize() const { return _lockedVersion.size; } 59 : 60 : StringView getPath() const { return _lockedVersion.path; } 61 : StringView getContentType() const { return _lockedVersion.contentType; } 62 : StringView getEtag() const { return _lockedVersion.etag; } 63 : StringView getCachePath() const; 64 : 65 : const Rc<Asset> &getAsset() const { return _asset; } 66 : 67 : Ref *getOwner() const { return _owner; } 68 : 69 : protected: 70 : friend class Asset; 71 : 72 : AssetLock(Rc<Asset> &&, const AssetVersionData &, Function<void(const AssetVersionData &)> &&, Ref *owner); 73 : 74 : AssetVersionData _lockedVersion; 75 : Function<void(const AssetVersionData &)> _releaseFunction; 76 : Rc<Asset> _asset; 77 : Rc<Ref> _owner; 78 : }; 79 : 80 : class Asset : public Subscription { 81 : public: 82 : using VersionData = AssetVersionData; 83 : 84 : enum Update : uint8_t { 85 : CacheDataUpdated = 1 << 1, 86 : DownloadStarted = 1 << 2, 87 : DownloadProgress = 1 << 3, 88 : DownloadCompleted = 1 << 4, 89 : DownloadSuccessful = 1 << 5, 90 : DownloadFailed = 1 << 6, 91 : }; 92 : 93 : Asset(AssetLibrary *, const db::Value &); 94 : virtual ~Asset(); 95 : 96 : Rc<AssetLock> lockVersion(int64_t, Ref *owner = nullptr); 97 : Rc<AssetLock> lockReadableVersion(Ref *owner = nullptr); 98 : 99 42 : int64_t getId() const { return _id; } 100 63 : StringView getUrl() const { return _url; } 101 0 : StringView getCachePath() const { return _cache; } 102 0 : Time getTouch() const { return _touch; } 103 : TimeInterval getTtl() const { return _ttl; } 104 : 105 : StringView getContentType() const; 106 : 107 : bool download(); 108 : void touch(Time t = Time::now()); 109 : void clear(); 110 : 111 : bool isDownloadAvailable() const; 112 : bool isDownloadInProgress() const; 113 : float getProgress() const; 114 : 115 : // or 0 if none 116 : int64_t getReadableVersionId() const; 117 : 118 0 : bool isStorageDirty() const { return _dirty; } 119 0 : void setStorageDirty(bool value) { _dirty = value; } 120 : 121 : void setData(const Value &d); 122 : void setData(Value &&d); 123 : const Value &getData() const { return _data; } 124 : 125 : Value encode() const; 126 : 127 : protected: 128 : friend class AssetLibrary; 129 : 130 : const VersionData *getReadableVersion() const; 131 : 132 : void parseVersions(const db::Value &); 133 : bool startNewDownload(Time ctime, StringView etag); 134 : bool resumeDownload(VersionData &); 135 : 136 : void setDownloadProgress(int64_t, float progress); 137 : void setDownloadComplete(VersionData &, bool success); 138 : void setFileValidated(bool success); 139 : void replaceVersion(VersionData &); 140 : 141 : // called from network thread 142 : void addVersion(AssetDownloadData *); 143 : void dropVersion(const VersionData &); 144 : 145 : void releaseLock(const VersionData &); 146 : 147 : String _path; 148 : String _cache; 149 : String _url; 150 : TimeInterval _ttl; 151 : Time _touch; 152 : Time _mtime; 153 : int64_t _id = 0; 154 : int64_t _downloadId = 0; 155 : 156 : Vector<VersionData> _versions; 157 : 158 : Value _data; 159 : AssetLibrary *_library = nullptr; 160 : bool _download = false; 161 : bool _dirty = true; 162 : 163 : mutable Mutex _mutex; 164 : }; 165 : 166 : } 167 : 168 : #endif /* XENOLITH_RESOURCES_ASSETS_XLASSET_H_ */