mirror of
https://github.com/AppleCommander/AppleCommander.git
synced 2026-10-24 23:02:27 +00:00
Giving FileStore a 'flush' method to push out changes. (The alternative was some sort of provider that Source utilized, but that seems overly complicated.) This added a 'Source#replaceAllBytes'.
This commit is contained in:
1 parent
d32c27bde9
commit
58fe61d324
13 files changed
+124
-6
No files matched your search
@@ -34,7 +34,7 @@ import java.util.stream.Collectors;
|
||||
|
||||
public class FileEntrySource implements Source {
|
||||
private final FileEntry fileEntry;
|
||||
private final DataBuffer buffer;
|
||||
private DataBuffer buffer;
|
||||
private boolean changed;
|
||||
private final Set<Hint> hints;
|
||||
|
||||
@@ -98,6 +98,12 @@ public class FileEntrySource implements Source {
|
||||
changed = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void replaceAllBytes(DataBuffer data) {
|
||||
buffer = data;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasChanged() {
|
||||
return changed;
|
||||
|
||||
@@ -31,7 +31,6 @@ import org.applecommander.util.FileMagic;
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.nio.file.attribute.FileTime;
|
||||
import java.util.Date;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.zip.ZipEntry;
|
||||
@@ -83,6 +82,10 @@ public class ZipFileEntry implements FileEntry {
|
||||
return entry.getLastModifiedTime();
|
||||
}
|
||||
|
||||
public FileTime getLastAccessTime() {
|
||||
return entry.getLastAccessTime();
|
||||
}
|
||||
|
||||
public long getCrc() {
|
||||
return entry.getCrc();
|
||||
}
|
||||
@@ -91,6 +94,10 @@ public class ZipFileEntry implements FileEntry {
|
||||
return entry.getCompressedSize();
|
||||
}
|
||||
|
||||
public String getComment() {
|
||||
return entry.getComment();
|
||||
}
|
||||
|
||||
public int getMethod() {
|
||||
return entry.getMethod();
|
||||
}
|
||||
@@ -130,8 +137,8 @@ public class ZipFileEntry implements FileEntry {
|
||||
.unlocked()
|
||||
.size(getSize())
|
||||
.BIN(0x0000)
|
||||
.creation(new Date(getCreationTime().toMillis()))
|
||||
.modification(new Date(getLastModifiedTime().toMillis()))
|
||||
.creation(getCreationTime())
|
||||
.modification(getLastModifiedTime())
|
||||
.get();
|
||||
}
|
||||
|
||||
|
||||
@@ -26,9 +26,11 @@ import org.applecommander.filestore.FileEntry;
|
||||
import org.applecommander.filestore.FileStore;
|
||||
import org.applecommander.source.Source;
|
||||
import org.applecommander.util.Container;
|
||||
import org.applecommander.util.DataBuffer;
|
||||
import org.applecommander.util.InformationGroup;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.nio.file.Files;
|
||||
@@ -39,6 +41,9 @@ import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
import static org.applecommander.util.Shorthand.copy;
|
||||
|
||||
public class ZipFileStore implements FileStore {
|
||||
private final Source source;
|
||||
@@ -93,12 +98,33 @@ public class ZipFileStore implements FileStore {
|
||||
.addLongField("Size", ZipFileEntry::getCompressedSize, Mode.DETAIL)
|
||||
.addPercentField("Ratio", ZipFileEntry::getCompressedSize, ZipFileEntry::getSize, "%2.0f%%", Mode.DETAIL)
|
||||
.addFileTimeField("Creation", ZipFileEntry::getCreationTime)
|
||||
.addFileTimeField("Last Access", ZipFileEntry::getLastAccessTime, Mode.DETAIL)
|
||||
.addFileTimeField("Last Modified", ZipFileEntry::getLastModifiedTime)
|
||||
.addLongField("CRC-32", ZipFileEntry::getCrc, "%08x", Mode.DETAIL)
|
||||
.addStringField("Name", FileEntry::getName)
|
||||
.toList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
try (ZipOutputStream zip = new ZipOutputStream(baos)) {
|
||||
for (FileEntry fileEntry : entries) {
|
||||
ZipFileEntry zipFileEntry = (ZipFileEntry) fileEntry;
|
||||
ZipEntry zipEntry = new ZipEntry(zipFileEntry.getName());
|
||||
copy(zipFileEntry::getCreationTime, zipEntry::setCreationTime);
|
||||
copy(zipFileEntry::getLastAccessTime, zipEntry::setLastAccessTime);
|
||||
copy(zipFileEntry::getLastModifiedTime, zipEntry::setLastModifiedTime);
|
||||
copy(zipFileEntry::getComment, zipEntry::setComment);
|
||||
zip.putNextEntry(zipEntry);
|
||||
zip.write(fileEntry.getDataFork().asBytes());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
source.replaceAllBytes(DataBuffer.wrap(baos.toByteArray()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean can(Capability capability) {
|
||||
return false;
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
package org.applecommander.archive.zip;
|
||||
|
||||
import org.applecommander.filestore.FileStoreFactory;
|
||||
import org.applecommander.source.Source;
|
||||
import org.applecommander.util.DataBuffer;
|
||||
|
||||
public class ZipFileStoreFactory implements FileStoreFactory {
|
||||
@@ -32,4 +33,8 @@ public class ZipFileStoreFactory implements FileStoreFactory {
|
||||
ctx.fileStores.add(new ZipFileStore(ctx.source));
|
||||
}
|
||||
}
|
||||
|
||||
public static ZipFileStore create(Source source) {
|
||||
return new ZipFileStore(source);
|
||||
}
|
||||
}
|
||||
@@ -42,4 +42,20 @@ public interface FileStore extends CapabilityProvider, Container, InformationPro
|
||||
|
||||
/// Yields a list of columns to be used in this display mode.
|
||||
List<DisplayColumn> getDisplayColumns();
|
||||
|
||||
/// Flush any pending writes back to the source. This is intended to handle archives
|
||||
/// as they do not have a fixed structure to write changes. `flush` should be invoked
|
||||
/// before a save.
|
||||
///
|
||||
/// Example usage:
|
||||
///
|
||||
/// ```java
|
||||
/// FileStore fileStore = fileStoreSelection.getSelectedItem();
|
||||
/// fileStore.flush();
|
||||
/// Source source = fileStore.get(Source.class).orElseThrow();
|
||||
/// source.save();
|
||||
/// ```
|
||||
default void flush() {
|
||||
// Do Nothing
|
||||
}
|
||||
}
|
||||
@@ -125,6 +125,11 @@ public class DiskCopyImage implements Source {
|
||||
this.source.writeBytes(HEADER_SIZE+offset, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void replaceAllBytes(DataBuffer data) {
|
||||
this.source.replaceAllBytes(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasChanged() {
|
||||
return source.hasChanged();
|
||||
|
||||
@@ -126,6 +126,11 @@ public class UniversalDiskImage implements Source {
|
||||
source.writeBytes(this.info.dataOffset + offset, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void replaceAllBytes(DataBuffer data) {
|
||||
source.replaceAllBytes(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasChanged() {
|
||||
return source.hasChanged();
|
||||
|
||||
@@ -31,7 +31,7 @@ import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
public class DataBufferSource implements Source {
|
||||
private final DataBuffer dataBuffer;
|
||||
private DataBuffer dataBuffer;
|
||||
private final String name;
|
||||
private final Set<Capability> capabilities;
|
||||
private final Set<Hint> hints;
|
||||
@@ -74,6 +74,12 @@ public class DataBufferSource implements Source {
|
||||
changed = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void replaceAllBytes(DataBuffer data) {
|
||||
dataBuffer = data;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasChanged() {
|
||||
return changed;
|
||||
|
||||
@@ -33,7 +33,7 @@ import java.util.stream.Collectors;
|
||||
|
||||
public class FileEntrySource implements Source {
|
||||
private final FileEntry fileEntry;
|
||||
private final DataBuffer buffer;
|
||||
private DataBuffer buffer;
|
||||
private boolean changed;
|
||||
private final Set<Hint> hints;
|
||||
|
||||
@@ -85,6 +85,12 @@ public class FileEntrySource implements Source {
|
||||
changed = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void replaceAllBytes(DataBuffer data) {
|
||||
buffer = data;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasChanged() {
|
||||
return changed;
|
||||
|
||||
@@ -111,6 +111,12 @@ public class FileSource implements Source {
|
||||
changed = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void replaceAllBytes(DataBuffer data) {
|
||||
buffer = data;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasChanged() {
|
||||
return changed;
|
||||
|
||||
@@ -74,6 +74,9 @@ public interface Source extends CapabilityProvider, HintProvider, Container, Inf
|
||||
/// Write bytes to this source. Updates the changed status.
|
||||
void writeBytes(int offset, DataBuffer data);
|
||||
|
||||
/// Replace ALL bytes in this Source.
|
||||
void replaceAllBytes(DataBuffer data);
|
||||
|
||||
/// Indicates if this source has changed.
|
||||
boolean hasChanged();
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ package org.applecommander.transfer;
|
||||
import org.applecommander.util.DataBuffer;
|
||||
import org.applecommander.util.FileMagic;
|
||||
|
||||
import java.nio.file.attribute.FileTime;
|
||||
import java.util.Date;
|
||||
import java.util.Optional;
|
||||
|
||||
@@ -102,10 +103,22 @@ public record ProdosAttributes(String name, int access, int fileType, int auxTyp
|
||||
this.size = size;
|
||||
return this;
|
||||
}
|
||||
public Builder creation(FileTime creation) {
|
||||
if (creation != null) {
|
||||
this.creation = new Date(creation.toMillis());
|
||||
}
|
||||
return this;
|
||||
}
|
||||
public Builder creation(Date creation) {
|
||||
this.creation = creation;
|
||||
return this;
|
||||
}
|
||||
public Builder modification(FileTime modified) {
|
||||
if (modified != null) {
|
||||
this.modified = new Date(modified.toMillis());
|
||||
}
|
||||
return this;
|
||||
}
|
||||
public Builder modification(Date modified) {
|
||||
this.modified = modified;
|
||||
return this;
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package org.applecommander.util;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public abstract class Shorthand {
|
||||
/// This is a shorthand method to only set non-null values.
|
||||
public static <T> void copy(Supplier<T> supplier, Consumer<T> consumer) {
|
||||
T value = supplier.get();
|
||||
if (value != null) {
|
||||
consumer.accept(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user