| 1 | package com.rox.save; | |
| 2 | ||
| 3 | import java.io.IOException; | |
| 4 | import java.nio.file.FileAlreadyExistsException; | |
| 5 | import java.nio.file.Files; | |
| 6 | import java.nio.file.Path; | |
| 7 | import java.time.LocalDateTime; | |
| 8 | import java.time.format.DateTimeFormatter; | |
| 9 | ||
| 10 | /** | |
| 11 | * Where a ROM's save files live: a directory named after the ROM (its filename without extension), | |
| 12 | * alongside the ROM file itself - not a hardcoded project path, since a ROM can be loaded from | |
| 13 | * anywhere. | |
| 14 | */ | |
| 15 | public final class SavePaths { | |
| 16 | private static final String BATTERY_SAVE_FILE_NAME = "battery.sav"; | |
| 17 | private static final String LIVE_SAVE_FILE_NAME = "latest.sav"; | |
| 18 | private static final String LABELS_FILE_NAME = "labels.txt"; | |
| 19 | private static final String DEBUG_SNAPSHOT_PREFIX = "debug-snapshot-"; | |
| 20 | private static final DateTimeFormatter DEBUG_SNAPSHOT_TIMESTAMP = DateTimeFormatter.ofPattern("yyyyMMdd-HHmmss"); | |
| 21 | ||
| 22 | private SavePaths(){ | |
| 23 | } | |
| 24 | ||
| 25 | public static Path saveDirectory(final Path romPath){ | |
| 26 | final Path absoluteRomPath = romPath.toAbsolutePath(); | |
| 27 | final String fileName = absoluteRomPath.getFileName().toString(); | |
| 28 | final int extensionIndex = fileName.lastIndexOf('.'); | |
| 29 |
2
1. saveDirectory : changed conditional boundary → KILLED 2. saveDirectory : negated conditional → KILLED |
final String baseName = extensionIndex > 0 ? fileName.substring(0, extensionIndex) : fileName; |
| 30 |
1
1. saveDirectory : replaced return value with null for com/rox/save/SavePaths::saveDirectory → KILLED |
return absoluteRomPath.getParent().resolve(baseName); |
| 31 | } | |
| 32 | ||
| 33 | public static Path batterySaveFile(final Path romPath){ | |
| 34 |
1
1. batterySaveFile : replaced return value with null for com/rox/save/SavePaths::batterySaveFile → KILLED |
return saveDirectory(romPath).resolve(BATTERY_SAVE_FILE_NAME); |
| 35 | } | |
| 36 | ||
| 37 | public static Path liveSaveFile(final Path romPath){ | |
| 38 |
1
1. liveSaveFile : replaced return value with null for com/rox/save/SavePaths::liveSaveFile → KILLED |
return saveDirectory(romPath).resolve(LIVE_SAVE_FILE_NAME); |
| 39 | } | |
| 40 | ||
| 41 | /** The ROM's memory labels - see {@code com.rox.debug.labels.LabelFile}. */ | |
| 42 | public static Path labelsFile(final Path romPath){ | |
| 43 |
1
1. labelsFile : replaced return value with null for com/rox/save/SavePaths::labelsFile → KILLED |
return saveDirectory(romPath).resolve(LABELS_FILE_NAME); |
| 44 | } | |
| 45 | ||
| 46 | /** {@code debug-snapshot-<yyyyMMdd-HHmmss>} - names both a flagged issue's folder and the {@code .sav} inside it. */ | |
| 47 | public static String debugSnapshotName(final LocalDateTime capturedAt){ | |
| 48 |
1
1. debugSnapshotName : replaced return value with "" for com/rox/save/SavePaths::debugSnapshotName → KILLED |
return DEBUG_SNAPSHOT_PREFIX + DEBUG_SNAPSHOT_TIMESTAMP.format(capturedAt); |
| 49 | } | |
| 50 | ||
| 51 | /** Where a flagged issue's files go: a {@link #debugSnapshotName} folder in the ROM's save directory. */ | |
| 52 | public static Path debugSnapshotDirectory(final Path romPath, final LocalDateTime capturedAt){ | |
| 53 |
1
1. debugSnapshotDirectory : replaced return value with null for com/rox/save/SavePaths::debugSnapshotDirectory → KILLED |
return saveDirectory(romPath).resolve(debugSnapshotName(capturedAt)); |
| 54 | } | |
| 55 | ||
| 56 | /** | |
| 57 | * Creates and returns a fresh folder for a flagged issue: {@link #debugSnapshotDirectory} itself, or | |
| 58 | * that name plus {@code -2}, {@code -3}... if a capture in the same second already took it. Creating | |
| 59 | * the folder is the claim - {@link Files#createDirectory} fails if it exists - so two captures can't | |
| 60 | * both end up writing into the same one. | |
| 61 | */ | |
| 62 | public static Path reserveDebugSnapshotDirectory(final Path romPath, final LocalDateTime capturedAt) throws IOException { | |
| 63 | final Path base = debugSnapshotDirectory(romPath, capturedAt); | |
| 64 | Files.createDirectories(base.getParent()); | |
| 65 | Path candidate = base; | |
| 66 |
1
1. reserveDebugSnapshotDirectory : Changed increment from 1 to -1 → KILLED |
for (int suffix = 2; ; suffix++){ |
| 67 | try { | |
| 68 |
1
1. reserveDebugSnapshotDirectory : replaced return value with null for com/rox/save/SavePaths::reserveDebugSnapshotDirectory → KILLED |
return Files.createDirectory(candidate); |
| 69 | } catch (FileAlreadyExistsException e){ | |
| 70 | candidate = base.resolveSibling(base.getFileName() + "-" + suffix); | |
| 71 | } | |
| 72 | } | |
| 73 | } | |
| 74 | } | |
Mutations | ||
| 29 |
1.1 2.2 |
|
| 30 |
1.1 |
|
| 34 |
1.1 |
|
| 38 |
1.1 |
|
| 43 |
1.1 |
|
| 48 |
1.1 |
|
| 53 |
1.1 |
|
| 66 |
1.1 |
|
| 68 |
1.1 |