| 9 | namespace Star { |
| 10 | |
| 11 | void PackedAssetSource::build(DirectoryAssetSource& directorySource, String const& targetPackedFile, |
| 12 | StringList const& extensionSorting, BuildProgressCallback progressCallback) { |
| 13 | FilePtr file = File::open(targetPackedFile, IOMode::ReadWrite | IOMode::Truncate); |
| 14 | |
| 15 | DataStreamIODevice ds(file); |
| 16 | |
| 17 | ds.writeData("SBAsset6", 8); |
| 18 | // Skip 8 bytes, this will be a pointer to the index once we are done. |
| 19 | ds.seek(8, IOSeek::Relative); |
| 20 | |
| 21 | // Insert every found entry into the packed file, and also simultaneously |
| 22 | // compute the full index. |
| 23 | StringMap<pair<uint64_t, uint64_t>> index; |
| 24 | |
| 25 | OrderedHashSet<String> extensionOrdering; |
| 26 | for (auto const& str : extensionSorting) |
| 27 | extensionOrdering.add(str.toLower()); |
| 28 | |
| 29 | StringList assetPaths = directorySource.assetPaths(); |
| 30 | |
| 31 | // Returns a value for the asset that can be used to predictably sort assets |
| 32 | // by name and then by extension, where every extension listed in |
| 33 | // "extensionSorting" will come first, and then any extension not listed will |
| 34 | // come after. |
| 35 | auto getOrderingValue = [&extensionOrdering](String const& asset) -> pair<size_t, String> { |
| 36 | String extension; |
| 37 | auto lastDot = asset.findLast("."); |
| 38 | if (lastDot != NPos) |
| 39 | extension = asset.substr(lastDot + 1); |
| 40 | |
| 41 | if (auto i = extensionOrdering.indexOf(extension.toLower())) { |
| 42 | return {*i, asset.toLower()}; |
| 43 | } else { |
| 44 | return {extensionOrdering.size(), asset.toLower()}; |
| 45 | } |
| 46 | }; |
| 47 | |
| 48 | assetPaths.sort([&getOrderingValue](String const& a, String const& b) { |
| 49 | return getOrderingValue(a) < getOrderingValue(b); |
| 50 | }); |
| 51 | |
| 52 | for (size_t i = 0; i < assetPaths.size(); ++i) { |
| 53 | String const& assetPath = assetPaths[i]; |
| 54 | ByteArray contents = directorySource.read(assetPath); |
| 55 | |
| 56 | if (progressCallback) |
| 57 | progressCallback(i, assetPaths.size(), directorySource.toFilesystem(assetPath), assetPath); |
| 58 | index.add(assetPath, {ds.pos(), contents.size()}); |
| 59 | ds.writeBytes(contents); |
| 60 | } |
| 61 | |
| 62 | uint64_t indexStart = ds.pos(); |
| 63 | ds.writeData("INDEX", 5); |
| 64 | ds.write(directorySource.metadata()); |
| 65 | ds.write(index); |
| 66 | |
| 67 | ds.seek(8); |
| 68 | ds.write(indexStart); |
nothing calls this directly
no test coverage detected