mirror of
https://github.com/AppleCommander/AppleCommander.git
synced 2026-10-24 23:02:27 +00:00
Updates sources to support 'can(Capability.SAVE_SOURCE)' as appropriate and added/implemented 'save()'.
This commit is contained in:
1 parent
18c16a856c
commit
f6d083d6bf
6 files changed
+117
-38
No files matched your search
+14
-1
@@ -26,6 +26,7 @@ import org.applecommander.util.Container;
|
||||
import org.applecommander.util.DataBuffer;
|
||||
import org.applecommander.util.InformationGroup;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
@@ -45,7 +46,9 @@ public class FileEntrySource implements Source {
|
||||
|
||||
@Override
|
||||
public boolean can(Capability capability) {
|
||||
// TODO?
|
||||
if (fileEntry.getFormattedDisk().canWriteFileData()) {
|
||||
return capability == Capability.SAVE_SOURCE;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -69,6 +72,16 @@ public class FileEntrySource implements Source {
|
||||
return fileEntry.getFilename();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save() throws IOException {
|
||||
try {
|
||||
fileEntry.setFileData(buffer.asBytes());
|
||||
changed = false;
|
||||
} catch (DiskException ex) {
|
||||
throw new IOException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataBuffer readAllBytes() {
|
||||
return buffer;
|
||||
|
||||
@@ -37,6 +37,7 @@ import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
public class ShrinkitFileStore implements FileStore {
|
||||
@@ -45,6 +46,7 @@ public class ShrinkitFileStore implements FileStore {
|
||||
private final List<FileEntry> files = new ArrayList<>();
|
||||
|
||||
public ShrinkitFileStore(Source source) {
|
||||
Objects.requireNonNull(source);
|
||||
this.source = source;
|
||||
try {
|
||||
this.archive = new NuFileArchive(new ByteArrayInputStream(source.readAllBytes().asBytes()));
|
||||
|
||||
@@ -26,6 +26,7 @@ import org.applecommander.util.Container;
|
||||
import org.applecommander.util.DataBuffer;
|
||||
import org.applecommander.util.InformationGroup;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
@@ -82,8 +83,7 @@ public class DiskCopyImage implements Source {
|
||||
|
||||
@Override
|
||||
public boolean can(Capability capability) {
|
||||
// TODO - not definted yet
|
||||
return false;
|
||||
return source.can(capability);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -135,6 +135,11 @@ public class DiskCopyImage implements Source {
|
||||
source.clearChanges();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save() throws IOException {
|
||||
source.save();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<InformationGroup> information() {
|
||||
BiFunction<Integer,Integer,String> cksumFn = (a, e) -> {
|
||||
|
||||
@@ -26,6 +26,7 @@ import org.applecommander.util.Container;
|
||||
import org.applecommander.util.DataBuffer;
|
||||
import org.applecommander.util.InformationGroup;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
@@ -87,8 +88,7 @@ public class UniversalDiskImage implements Source {
|
||||
|
||||
@Override
|
||||
public boolean can(Capability capability) {
|
||||
// TODO we haven't defined any yet
|
||||
return false;
|
||||
return source.can(capability);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -136,6 +136,11 @@ public class UniversalDiskImage implements Source {
|
||||
source.clearChanges();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save() throws IOException {
|
||||
source.save();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<InformationGroup> information() {
|
||||
Info info = getInfo();
|
||||
|
||||
@@ -28,6 +28,7 @@ import org.applecommander.util.InformationGroup;
|
||||
import java.io.*;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
@@ -67,7 +68,9 @@ public class FileSource implements Source {
|
||||
|
||||
@Override
|
||||
public boolean can(Capability capability) {
|
||||
// TODO - we haven't actually identified save yet!
|
||||
if (path.toFile().canWrite()) {
|
||||
return capability == Capability.SAVE_SOURCE;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -118,6 +121,12 @@ public class FileSource implements Source {
|
||||
changed = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save() throws IOException {
|
||||
Files.write(path, buffer.asBytes(), StandardOpenOption.TRUNCATE_EXISTING);
|
||||
changed = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<InformationGroup> information() {
|
||||
InformationGroup.Builder builder = InformationGroup.builder("File Source")
|
||||
|
||||
@@ -25,53 +25,100 @@ import org.applecommander.util.Container;
|
||||
import org.applecommander.util.DataBuffer;
|
||||
import org.applecommander.util.InformationProvider;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Source and Factory for an archive or disk in AppleCommander.
|
||||
* <p/>
|
||||
* Typical usage:
|
||||
* {@snippet lang = java:
|
||||
* import com.webcodepro.applecommander.storage.Sources;Optional<Source> sourceOpt = Sources.create(Path.of(filename));
|
||||
* if (sourceOpt.isPresent()) {
|
||||
* // do something with sourceOpt.get()
|
||||
* System.out.println(sourceOpt.get().getSize());
|
||||
* }
|
||||
* // Only happens if the initiating object is not understood
|
||||
* throw new RuntimeException("Unable to create image source");
|
||||
*}
|
||||
*/
|
||||
/// Source and Factory for an archive or disk in AppleCommander.
|
||||
///
|
||||
/// Typical usage:
|
||||
///
|
||||
/// ```java
|
||||
/// import com.webcodepro.applecommander.storage.Sources;
|
||||
/// import java.util.Optional;
|
||||
/// Optional<source> sourceOpt = Sources.create(Path.of(filename));
|
||||
/// if (sourceOpt.isPresent()) {
|
||||
/// // do something with the Source
|
||||
/// Source source = sourceOpt.get();
|
||||
/// System.out.println(source.getSize());
|
||||
/// }
|
||||
/// else {
|
||||
/// // Only happens if the initiating object is not understood
|
||||
/// throw new RuntimeException("Unable to create image source");
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Optionally, you can use the Optional's more _fluent_ API and write
|
||||
/// code like this:
|
||||
///
|
||||
/// ```java
|
||||
/// import com.webcodepro.applecommander.storage.Sources;
|
||||
/// Sources.create(Path.of(filename)).ifPresent(source -> {
|
||||
/// // do something with the Source
|
||||
/// System.out.println(source.getSize());
|
||||
/// });
|
||||
/// ```
|
||||
public interface Source extends CapabilityProvider, HintProvider, Container, InformationProvider {
|
||||
/// Indicates the physical size of this image on disk.
|
||||
int getSize();
|
||||
|
||||
/// The name of the source. It likely will be used in user interfaces. It could represent a file
|
||||
/// from the computer or even a file from a file store.
|
||||
String getName();
|
||||
|
||||
/// Read all bytes from this source.
|
||||
DataBuffer readAllBytes();
|
||||
|
||||
/// Read a range of bytes from this source.
|
||||
DataBuffer readBytes(int offset, int length);
|
||||
|
||||
/// Write bytes to this source. Updates the changed status.
|
||||
void writeBytes(int offset, DataBuffer data);
|
||||
|
||||
/// Indicates if this source has changed.
|
||||
boolean hasChanged();
|
||||
|
||||
/// Clears the changed indicator.
|
||||
void clearChanges();
|
||||
|
||||
/**
|
||||
* Indicates if the source image is approximately equal to this size
|
||||
* (less any image over-read).
|
||||
* Currently, hardcoded to allow up to 255 extra bytes at the end of a
|
||||
* disk image. Must be at least the requested size!
|
||||
*/
|
||||
/// Save the image back to the origin. Note that this could conceivably save back to the
|
||||
/// OS file system, or back to a file store. Use the `CapabilityProvider#can` to see if
|
||||
/// a save is possible. The save operation should clear the change indicator.
|
||||
///
|
||||
/// For example:
|
||||
///
|
||||
/// ```java
|
||||
/// if (source.can(Capability.SAVE_SOURCE)) {
|
||||
/// source.save();
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Note that the capability can be used to enable appropriate options. If source _cannot_
|
||||
/// be saved, a "Save As" type operation can be applied and the source switched for the
|
||||
/// `FileStore` in question.
|
||||
///
|
||||
/// @throws IOException if an error occurs while saving the source.
|
||||
/// @throws UnsupportedOperationException if the source does not support the save operation.
|
||||
default void save() throws IOException {
|
||||
throw new UnsupportedOperationException("save operation not supported");
|
||||
}
|
||||
|
||||
/// Indicates if the source image is approximately equal to this size
|
||||
/// (less any image over-read).
|
||||
/// Currently, hardcoded to allow up to 255 extra bytes at the end of a
|
||||
/// disk image. Must be at least the requested size!
|
||||
default boolean isApproxEQ(int value) {
|
||||
return getSize() >= value && getSize() <= value + 255;
|
||||
}
|
||||
/**
|
||||
* Indicates if the source image is "approximately" between
|
||||
* these two values (less any image over-read).
|
||||
* Currently, hardcoded to allow up to 255 extra bytes at the end of a
|
||||
* disk image. Must be at least the requested size!
|
||||
*/
|
||||
|
||||
/// Indicates if the source image is "approximately" between
|
||||
/// these two values (less any image over-read).
|
||||
/// Currently, hardcoded to allow up to 255 extra bytes at the end of a
|
||||
/// disk image. Must be at least the requested size!
|
||||
default boolean isApproxBetween(int value1, int value2) {
|
||||
return getSize() >= value1 && getSize() <= value2 + 255;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if this name has a given file extension.
|
||||
*/
|
||||
/// Test if this name has a given file extension.
|
||||
default boolean extensionLike(String extension) {
|
||||
String name = getName().toLowerCase();
|
||||
String ext1 = String.format(".%s", extension.toLowerCase());
|
||||
@@ -79,9 +126,7 @@ public interface Source extends CapabilityProvider, HintProvider, Container, Inf
|
||||
return name.endsWith(ext1) || name.endsWith(ext2);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the Source creation factory interface.
|
||||
*/
|
||||
/// This is the Source creation factory interface.
|
||||
interface Factory {
|
||||
Optional<Source> fromObject(Object object);
|
||||
Optional<Source> fromSource(Source source);
|
||||
|
||||
Reference in new issue
Block a user