mirror of
https://github.com/AppleCommander/AppleCommander.git
synced 2024-06-12 17:32:20 +00:00
Adding DiskDiff and enhancing the basic disk comparison capabilities.
This commit is contained in:
parent
be12ac4c52
commit
087df7535e
|
@ -24,6 +24,7 @@ import java.util.logging.Level;
|
||||||
import java.util.logging.LogManager;
|
import java.util.logging.LogManager;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import io.github.applecommander.acx.command.CompareCommand;
|
||||||
import io.github.applecommander.acx.command.ConvertCommand;
|
import io.github.applecommander.acx.command.ConvertCommand;
|
||||||
import io.github.applecommander.acx.command.CopyFileCommand;
|
import io.github.applecommander.acx.command.CopyFileCommand;
|
||||||
import io.github.applecommander.acx.command.CreateDiskCommand;
|
import io.github.applecommander.acx.command.CreateDiskCommand;
|
||||||
|
@ -53,6 +54,7 @@ import picocli.CommandLine.Option;
|
||||||
optionListHeading = "%nOptions:%n",
|
optionListHeading = "%nOptions:%n",
|
||||||
description = "'acx' experimental utility",
|
description = "'acx' experimental utility",
|
||||||
subcommands = {
|
subcommands = {
|
||||||
|
CompareCommand.class,
|
||||||
ConvertCommand.class,
|
ConvertCommand.class,
|
||||||
CopyFileCommand.class,
|
CopyFileCommand.class,
|
||||||
CreateDiskCommand.class,
|
CreateDiskCommand.class,
|
||||||
|
|
|
@ -0,0 +1,87 @@
|
||||||
|
/*
|
||||||
|
* AppleCommander - An Apple ][ image utility.
|
||||||
|
* Copyright (C) 2019-2022 by Robert Greene and others
|
||||||
|
* robgreene at users.sourceforge.net
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
package io.github.applecommander.acx.command;
|
||||||
|
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
import com.webcodepro.applecommander.storage.Disk;
|
||||||
|
import com.webcodepro.applecommander.storage.compare.ComparisonResult;
|
||||||
|
import com.webcodepro.applecommander.storage.compare.DiskDiff;
|
||||||
|
|
||||||
|
import io.github.applecommander.acx.base.ReadOnlyDiskImageCommandOptions;
|
||||||
|
import io.github.applecommander.acx.converter.DiskConverter;
|
||||||
|
import picocli.CommandLine.ArgGroup;
|
||||||
|
import picocli.CommandLine.Command;
|
||||||
|
import picocli.CommandLine.Option;
|
||||||
|
import picocli.CommandLine.Parameters;
|
||||||
|
|
||||||
|
@Command(name = "compare", description = "Compare two disk images.")
|
||||||
|
public class CompareCommand extends ReadOnlyDiskImageCommandOptions {
|
||||||
|
@Parameters(arity = "1", converter = DiskConverter.class, description = "Second image to compare to.")
|
||||||
|
private Disk disk2;
|
||||||
|
|
||||||
|
@ArgGroup(heading = "%nComparison Strategy Selection:%n")
|
||||||
|
private StrategySelection strategySelection = new StrategySelection();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int handleCommand() throws Exception {
|
||||||
|
DiskDiff.Builder builder = DiskDiff.create(disk, disk2);
|
||||||
|
strategySelection.strategy.accept(builder);
|
||||||
|
ComparisonResult result = builder.compare();
|
||||||
|
|
||||||
|
if (result.getDifferenceCount() == 0) {
|
||||||
|
System.out.println("The disks match.");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
System.out.println("The disks do not match.");
|
||||||
|
result.getErrors().forEach(System.out::println);
|
||||||
|
result.getWarnings().forEach(System.out::println);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class StrategySelection {
|
||||||
|
private Consumer<DiskDiff.Builder> strategy = this::nativeGeometry;
|
||||||
|
|
||||||
|
@Option(names = "--native", description = "Compare by native geometry.")
|
||||||
|
private void selectNativeGeometry(boolean flag) {
|
||||||
|
strategy = this::nativeGeometry;
|
||||||
|
}
|
||||||
|
@Option(names = "--block", description = "Compare by block geometry.")
|
||||||
|
private void selectBlockGeometry(boolean flag) {
|
||||||
|
strategy = this::blockGeometry;
|
||||||
|
}
|
||||||
|
@Option(names = { "--track-sector", "--ts" }, description = "Compare by track/sector geometry.")
|
||||||
|
private void selectTrackSectorGeometry(boolean flag) {
|
||||||
|
strategy = this::trackSectorGeometry;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void nativeGeometry(DiskDiff.Builder builder) {
|
||||||
|
builder.selectCompareByNativeGeometry();
|
||||||
|
}
|
||||||
|
private void blockGeometry(DiskDiff.Builder builder) {
|
||||||
|
builder.selectCompareByBlockGeometry();
|
||||||
|
}
|
||||||
|
private void trackSectorGeometry(DiskDiff.Builder builder) {
|
||||||
|
builder.selectCompareByTrackSectorGeometry();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
* AppleCommander - An Apple ][ image utility.
|
||||||
|
* Copyright (C) 2021-2022 by Robert Greene and others
|
||||||
|
* robgreene at users.sourceforge.net
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
package com.webcodepro.applecommander.storage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates the broad disk geometry - track/sector or block.
|
||||||
|
* Note that BLOCK is meant to include only ProDOS/Pascal 512-byte
|
||||||
|
* blocks and not the RDOS 256 "blocks" (RDOS should remain under
|
||||||
|
* the track/sector geometry.)
|
||||||
|
*/
|
||||||
|
public enum DiskGeometry {
|
||||||
|
TRACK_SECTOR(256, "Track/Sector"),
|
||||||
|
BLOCK(512, "Block");
|
||||||
|
|
||||||
|
public int size;
|
||||||
|
public String text;
|
||||||
|
|
||||||
|
private DiskGeometry(int size, String text) {
|
||||||
|
this.size = size;
|
||||||
|
this.text = text;
|
||||||
|
}
|
||||||
|
}
|
|
@ -399,4 +399,9 @@ public abstract class FormattedDisk extends Disk implements DirectoryEntry {
|
||||||
* Typically, the FileEntry.setFileData method should be used.
|
* Typically, the FileEntry.setFileData method should be used.
|
||||||
*/
|
*/
|
||||||
public abstract void setFileData(FileEntry fileEntry, byte[] fileData) throws DiskFullException;
|
public abstract void setFileData(FileEntry fileEntry, byte[] fileData) throws DiskFullException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gives an indication on how this disk's geometry should be handled.
|
||||||
|
*/
|
||||||
|
public abstract DiskGeometry getDiskGeometry();
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
* AppleCommander - An Apple ][ image utility.
|
||||||
|
* Copyright (C) 2021-2022 by Robert Greene and others
|
||||||
|
* robgreene at users.sourceforge.net
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
package com.webcodepro.applecommander.storage.compare;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ComparisonResult {
|
||||||
|
private List<String> errors = new ArrayList<>();
|
||||||
|
private List<String> warnings = new ArrayList<>();
|
||||||
|
|
||||||
|
public boolean hasErrors() {
|
||||||
|
return !errors.isEmpty();
|
||||||
|
}
|
||||||
|
public int getDifferenceCount() {
|
||||||
|
return errors.size() + warnings.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addError(Exception ex) {
|
||||||
|
errors.add(ex.getMessage());
|
||||||
|
}
|
||||||
|
public void addError(String fmt, Object... args) {
|
||||||
|
errors.add(String.format(fmt, args));
|
||||||
|
}
|
||||||
|
public void addWarning(String fmt, Object... args) {
|
||||||
|
warnings.add(String.format(fmt, args));
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getErrors() {
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
public List<String> getWarnings() {
|
||||||
|
return warnings;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,189 @@
|
||||||
|
/*
|
||||||
|
* AppleCommander - An Apple ][ image utility.
|
||||||
|
* Copyright (C) 2021-2022 by Robert Greene and others
|
||||||
|
* robgreene at users.sourceforge.net
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
package com.webcodepro.applecommander.storage.compare;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.function.BiConsumer;
|
||||||
|
|
||||||
|
import com.webcodepro.applecommander.storage.Disk;
|
||||||
|
import com.webcodepro.applecommander.storage.DiskGeometry;
|
||||||
|
import com.webcodepro.applecommander.storage.DiskUnrecognizedException;
|
||||||
|
import com.webcodepro.applecommander.storage.FormattedDisk;
|
||||||
|
import com.webcodepro.applecommander.storage.physical.ImageOrder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform a disk comparison based on selected strategy.
|
||||||
|
*/
|
||||||
|
public class DiskDiff {
|
||||||
|
public static ComparisonResult compare(Disk diskA, Disk diskB) {
|
||||||
|
return new DiskDiff(diskA, diskB).compare();
|
||||||
|
}
|
||||||
|
public static Builder create(Disk diskA, Disk diskB) {
|
||||||
|
return new Builder(diskA, diskB);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Disk diskA;
|
||||||
|
private Disk diskB;
|
||||||
|
private ComparisonResult results = new ComparisonResult();
|
||||||
|
|
||||||
|
private BiConsumer<FormattedDisk,FormattedDisk> diskComparisonStrategy = this::compareByNativeGeometry;
|
||||||
|
|
||||||
|
private DiskDiff(Disk diskA, Disk diskB) {
|
||||||
|
Objects.requireNonNull(diskA);
|
||||||
|
Objects.requireNonNull(diskB);
|
||||||
|
this.diskA = diskA;
|
||||||
|
this.diskB = diskB;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ComparisonResult compare() {
|
||||||
|
FormattedDisk[] formattedDisksA = null;
|
||||||
|
try {
|
||||||
|
formattedDisksA = diskA.getFormattedDisks();
|
||||||
|
} catch (DiskUnrecognizedException e) {
|
||||||
|
results.addError(e);
|
||||||
|
}
|
||||||
|
FormattedDisk[] formattedDisksB = null;
|
||||||
|
try {
|
||||||
|
formattedDisksB = diskB.getFormattedDisks();
|
||||||
|
} catch (DiskUnrecognizedException e) {
|
||||||
|
results.addError(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!results.hasErrors()) {
|
||||||
|
compareAll(formattedDisksA, formattedDisksB);
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void compareAll(FormattedDisk[] formattedDisksA, FormattedDisk[] formattedDisksB) {
|
||||||
|
Objects.requireNonNull(formattedDisksA);
|
||||||
|
Objects.requireNonNull(formattedDisksB);
|
||||||
|
|
||||||
|
if (formattedDisksA.length != formattedDisksB.length) {
|
||||||
|
results.addWarning("Cannot compare all disks; %s has %d while %s has %d.",
|
||||||
|
diskA.getFilename(), formattedDisksA.length,
|
||||||
|
diskB.getFilename(), formattedDisksB.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
int min = Math.min(formattedDisksA.length, formattedDisksB.length);
|
||||||
|
for (int i=0; i<min; i++) {
|
||||||
|
this.diskComparisonStrategy.accept(formattedDisksA[i], formattedDisksB[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Compare disks by whatever native geometry the disks have. Fails if geometries do not match. */
|
||||||
|
public void compareByNativeGeometry(FormattedDisk formattedDiskA, FormattedDisk formattedDiskB) {
|
||||||
|
DiskGeometry geometryA = formattedDiskA.getDiskGeometry();
|
||||||
|
DiskGeometry geometryB = formattedDiskB.getDiskGeometry();
|
||||||
|
|
||||||
|
if (geometryA != geometryB) {
|
||||||
|
results.addError("Disks are different geometry (block versus track/sector)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (geometryA) {
|
||||||
|
case BLOCK:
|
||||||
|
compareByBlockGeometry(formattedDiskA, formattedDiskB);
|
||||||
|
break;
|
||||||
|
case TRACK_SECTOR:
|
||||||
|
compareByTrackSectorGeometry(formattedDiskA, formattedDiskB);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
results.addError("Unknown geometry: %s", geometryA);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Compare disks by 512-byte ProDOS/Pascal blocks. */
|
||||||
|
public void compareByBlockGeometry(FormattedDisk formattedDiskA, FormattedDisk formattedDiskB) {
|
||||||
|
ImageOrder orderA = formattedDiskA.getImageOrder();
|
||||||
|
ImageOrder orderB = formattedDiskB.getImageOrder();
|
||||||
|
|
||||||
|
if (orderA.getBlocksOnDevice() != orderB.getBlocksOnDevice()) {
|
||||||
|
results.addError("Different sized disks do not equal. (Blocks: %d <> %d)",
|
||||||
|
orderA.getBlocksOnDevice(), orderB.getBlocksOnDevice());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int block=0; block<orderA.getBlocksOnDevice(); block++) {
|
||||||
|
byte[] blockA = orderA.readBlock(block);
|
||||||
|
byte[] blockB = orderB.readBlock(block);
|
||||||
|
if (!Arrays.equals(blockA, blockB)) {
|
||||||
|
results.addError("Block #%d does not match.", block);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Compare disks by 256-byte DOS sectors. */
|
||||||
|
public void compareByTrackSectorGeometry(FormattedDisk formattedDiskA, FormattedDisk formattedDiskB) {
|
||||||
|
ImageOrder orderA = formattedDiskA.getImageOrder();
|
||||||
|
ImageOrder orderB = formattedDiskB.getImageOrder();
|
||||||
|
|
||||||
|
if (orderA.getSectorsPerDisk() != orderB.getSectorsPerDisk()) {
|
||||||
|
results.addError("Different sized disks do not equal. (Sectors: %d <> %d)",
|
||||||
|
orderA.getSectorsPerDisk(), orderB.getSectorsPerDisk());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int track=0; track<orderA.getTracksPerDisk(); track++) {
|
||||||
|
List<String> unequalSectors = new ArrayList<>();
|
||||||
|
for (int sector=0; sector<orderA.getSectorsPerTrack(); sector++) {
|
||||||
|
byte[] sectorA = orderA.readSector(track, sector);
|
||||||
|
byte[] sectorB = orderB.readSector(track, sector);
|
||||||
|
if (!Arrays.equals(sectorA, sectorB)) {
|
||||||
|
unequalSectors.add(Integer.toString(sector));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!unequalSectors.isEmpty()) {
|
||||||
|
results.addError("Track %d does not match on sectors %s", track,
|
||||||
|
String.join(",", unequalSectors));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Builder {
|
||||||
|
private DiskDiff diff;
|
||||||
|
|
||||||
|
public Builder(Disk diskA, Disk diskB) {
|
||||||
|
diff = new DiskDiff(diskA, diskB);
|
||||||
|
}
|
||||||
|
/** Compare disks by whatever native geometry the disks have. Fails if geometries do not match. */
|
||||||
|
public Builder selectCompareByNativeGeometry() {
|
||||||
|
diff.diskComparisonStrategy = diff::compareByNativeGeometry;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
/** Compare disks by 256-byte DOS sectors. */
|
||||||
|
public Builder selectCompareByTrackSectorGeometry() {
|
||||||
|
diff.diskComparisonStrategy = diff::compareByTrackSectorGeometry;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
/** Compare disks by 512-byte ProDOS/Pascal blocks. */
|
||||||
|
public Builder selectCompareByBlockGeometry() {
|
||||||
|
diff.diskComparisonStrategy = diff::compareByBlockGeometry;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ComparisonResult compare() {
|
||||||
|
return diff.compare();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -27,6 +27,7 @@ import java.util.StringTokenizer;
|
||||||
|
|
||||||
import com.webcodepro.applecommander.storage.DirectoryEntry;
|
import com.webcodepro.applecommander.storage.DirectoryEntry;
|
||||||
import com.webcodepro.applecommander.storage.DiskFullException;
|
import com.webcodepro.applecommander.storage.DiskFullException;
|
||||||
|
import com.webcodepro.applecommander.storage.DiskGeometry;
|
||||||
import com.webcodepro.applecommander.storage.FileEntry;
|
import com.webcodepro.applecommander.storage.FileEntry;
|
||||||
import com.webcodepro.applecommander.storage.FormattedDisk;
|
import com.webcodepro.applecommander.storage.FormattedDisk;
|
||||||
import com.webcodepro.applecommander.storage.StorageBundle;
|
import com.webcodepro.applecommander.storage.StorageBundle;
|
||||||
|
@ -557,4 +558,11 @@ public class CpmFormatDisk extends FormattedDisk {
|
||||||
public DirectoryEntry createDirectory(String name) throws DiskFullException {
|
public DirectoryEntry createDirectory(String name) throws DiskFullException {
|
||||||
throw new UnsupportedOperationException(textBundle.get("DirectoryCreationNotSupported")); //$NON-NLS-1$
|
throw new UnsupportedOperationException(textBundle.get("DirectoryCreationNotSupported")); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gives an indication on how this disk's geometry should be handled.
|
||||||
|
*/
|
||||||
|
public DiskGeometry getDiskGeometry() {
|
||||||
|
return DiskGeometry.TRACK_SECTOR;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ import com.webcodepro.applecommander.storage.DirectoryEntry;
|
||||||
import com.webcodepro.applecommander.storage.DiskException;
|
import com.webcodepro.applecommander.storage.DiskException;
|
||||||
import com.webcodepro.applecommander.storage.DiskCorruptException;
|
import com.webcodepro.applecommander.storage.DiskCorruptException;
|
||||||
import com.webcodepro.applecommander.storage.DiskFullException;
|
import com.webcodepro.applecommander.storage.DiskFullException;
|
||||||
|
import com.webcodepro.applecommander.storage.DiskGeometry;
|
||||||
import com.webcodepro.applecommander.storage.FileEntry;
|
import com.webcodepro.applecommander.storage.FileEntry;
|
||||||
import com.webcodepro.applecommander.storage.FormattedDisk;
|
import com.webcodepro.applecommander.storage.FormattedDisk;
|
||||||
import com.webcodepro.applecommander.storage.StorageBundle;
|
import com.webcodepro.applecommander.storage.StorageBundle;
|
||||||
|
@ -773,4 +774,11 @@ public class DosFormatDisk extends FormattedDisk {
|
||||||
public DirectoryEntry createDirectory(String name) throws DiskFullException {
|
public DirectoryEntry createDirectory(String name) throws DiskFullException {
|
||||||
throw new UnsupportedOperationException(textBundle.get("DirectoryCreationNotSupported")); //$NON-NLS-1$
|
throw new UnsupportedOperationException(textBundle.get("DirectoryCreationNotSupported")); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gives an indication on how this disk's geometry should be handled.
|
||||||
|
*/
|
||||||
|
public DiskGeometry getDiskGeometry() {
|
||||||
|
return DiskGeometry.TRACK_SECTOR;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ import java.util.List;
|
||||||
|
|
||||||
import com.webcodepro.applecommander.storage.DirectoryEntry;
|
import com.webcodepro.applecommander.storage.DirectoryEntry;
|
||||||
import com.webcodepro.applecommander.storage.DiskFullException;
|
import com.webcodepro.applecommander.storage.DiskFullException;
|
||||||
|
import com.webcodepro.applecommander.storage.DiskGeometry;
|
||||||
import com.webcodepro.applecommander.storage.FileEntry;
|
import com.webcodepro.applecommander.storage.FileEntry;
|
||||||
import com.webcodepro.applecommander.storage.FormattedDisk;
|
import com.webcodepro.applecommander.storage.FormattedDisk;
|
||||||
import com.webcodepro.applecommander.storage.StorageBundle;
|
import com.webcodepro.applecommander.storage.StorageBundle;
|
||||||
|
@ -699,4 +700,11 @@ public class GutenbergFormatDisk extends FormattedDisk {
|
||||||
public DirectoryEntry createDirectory(String name) throws DiskFullException {
|
public DirectoryEntry createDirectory(String name) throws DiskFullException {
|
||||||
throw new UnsupportedOperationException(textBundle.get("DirectoryCreationNotSupported")); //$NON-NLS-1$
|
throw new UnsupportedOperationException(textBundle.get("DirectoryCreationNotSupported")); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gives an indication on how this disk's geometry should be handled.
|
||||||
|
*/
|
||||||
|
public DiskGeometry getDiskGeometry() {
|
||||||
|
return DiskGeometry.TRACK_SECTOR;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ import java.util.List;
|
||||||
|
|
||||||
import com.webcodepro.applecommander.storage.DirectoryEntry;
|
import com.webcodepro.applecommander.storage.DirectoryEntry;
|
||||||
import com.webcodepro.applecommander.storage.DiskFullException;
|
import com.webcodepro.applecommander.storage.DiskFullException;
|
||||||
|
import com.webcodepro.applecommander.storage.DiskGeometry;
|
||||||
import com.webcodepro.applecommander.storage.FileEntry;
|
import com.webcodepro.applecommander.storage.FileEntry;
|
||||||
import com.webcodepro.applecommander.storage.FormattedDisk;
|
import com.webcodepro.applecommander.storage.FormattedDisk;
|
||||||
import com.webcodepro.applecommander.storage.StorageBundle;
|
import com.webcodepro.applecommander.storage.StorageBundle;
|
||||||
|
@ -537,4 +538,11 @@ public class NakedosFormatDisk extends FormattedDisk {
|
||||||
public DirectoryEntry createDirectory(String name) throws DiskFullException {
|
public DirectoryEntry createDirectory(String name) throws DiskFullException {
|
||||||
throw new UnsupportedOperationException(textBundle.get("DirectoryCreationNotSupported")); //$NON-NLS-1$
|
throw new UnsupportedOperationException(textBundle.get("DirectoryCreationNotSupported")); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gives an indication on how this disk's geometry should be handled.
|
||||||
|
*/
|
||||||
|
public DiskGeometry getDiskGeometry() {
|
||||||
|
return DiskGeometry.TRACK_SECTOR;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ import java.util.List;
|
||||||
|
|
||||||
import com.webcodepro.applecommander.storage.DirectoryEntry;
|
import com.webcodepro.applecommander.storage.DirectoryEntry;
|
||||||
import com.webcodepro.applecommander.storage.DiskFullException;
|
import com.webcodepro.applecommander.storage.DiskFullException;
|
||||||
|
import com.webcodepro.applecommander.storage.DiskGeometry;
|
||||||
import com.webcodepro.applecommander.storage.FileEntry;
|
import com.webcodepro.applecommander.storage.FileEntry;
|
||||||
import com.webcodepro.applecommander.storage.FormattedDisk;
|
import com.webcodepro.applecommander.storage.FormattedDisk;
|
||||||
import com.webcodepro.applecommander.storage.StorageBundle;
|
import com.webcodepro.applecommander.storage.StorageBundle;
|
||||||
|
@ -667,4 +668,11 @@ public class PascalFormatDisk extends FormattedDisk {
|
||||||
public DirectoryEntry createDirectory(String name) throws DiskFullException {
|
public DirectoryEntry createDirectory(String name) throws DiskFullException {
|
||||||
throw new UnsupportedOperationException(textBundle.get("DirectoryCreationNotSupported")); //$NON-NLS-1$
|
throw new UnsupportedOperationException(textBundle.get("DirectoryCreationNotSupported")); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gives an indication on how this disk's geometry should be handled.
|
||||||
|
*/
|
||||||
|
public DiskGeometry getDiskGeometry() {
|
||||||
|
return DiskGeometry.BLOCK;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@ import com.webcodepro.applecommander.storage.DirectoryEntry;
|
||||||
import com.webcodepro.applecommander.storage.DiskException;
|
import com.webcodepro.applecommander.storage.DiskException;
|
||||||
import com.webcodepro.applecommander.storage.DiskCorruptException;
|
import com.webcodepro.applecommander.storage.DiskCorruptException;
|
||||||
import com.webcodepro.applecommander.storage.DiskFullException;
|
import com.webcodepro.applecommander.storage.DiskFullException;
|
||||||
|
import com.webcodepro.applecommander.storage.DiskGeometry;
|
||||||
import com.webcodepro.applecommander.storage.FileEntry;
|
import com.webcodepro.applecommander.storage.FileEntry;
|
||||||
import com.webcodepro.applecommander.storage.FormattedDisk;
|
import com.webcodepro.applecommander.storage.FormattedDisk;
|
||||||
import com.webcodepro.applecommander.storage.StorageBundle;
|
import com.webcodepro.applecommander.storage.StorageBundle;
|
||||||
|
@ -1450,4 +1451,11 @@ public class ProdosFormatDisk extends FormattedDisk {
|
||||||
throw new DiskFullException(textBundle.get("ProdosFormatDisk.UnableToAllocateFileEntry"), this.getFilename());
|
throw new DiskFullException(textBundle.get("ProdosFormatDisk.UnableToAllocateFileEntry"), this.getFilename());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gives an indication on how this disk's geometry should be handled.
|
||||||
|
*/
|
||||||
|
public DiskGeometry getDiskGeometry() {
|
||||||
|
return DiskGeometry.BLOCK;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ import java.util.List;
|
||||||
|
|
||||||
import com.webcodepro.applecommander.storage.DirectoryEntry;
|
import com.webcodepro.applecommander.storage.DirectoryEntry;
|
||||||
import com.webcodepro.applecommander.storage.DiskFullException;
|
import com.webcodepro.applecommander.storage.DiskFullException;
|
||||||
|
import com.webcodepro.applecommander.storage.DiskGeometry;
|
||||||
import com.webcodepro.applecommander.storage.FileEntry;
|
import com.webcodepro.applecommander.storage.FileEntry;
|
||||||
import com.webcodepro.applecommander.storage.FormattedDisk;
|
import com.webcodepro.applecommander.storage.FormattedDisk;
|
||||||
import com.webcodepro.applecommander.storage.StorageBundle;
|
import com.webcodepro.applecommander.storage.StorageBundle;
|
||||||
|
@ -518,4 +519,11 @@ public class RdosFormatDisk extends FormattedDisk {
|
||||||
public DirectoryEntry createDirectory(String name) throws DiskFullException {
|
public DirectoryEntry createDirectory(String name) throws DiskFullException {
|
||||||
throw new UnsupportedOperationException(textBundle.get("DirectoryCreationNotSupported")); //$NON-NLS-1$
|
throw new UnsupportedOperationException(textBundle.get("DirectoryCreationNotSupported")); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gives an indication on how this disk's geometry should be handled.
|
||||||
|
*/
|
||||||
|
public DiskGeometry getDiskGeometry() {
|
||||||
|
return DiskGeometry.TRACK_SECTOR;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,12 +22,10 @@ package com.webcodepro.applecommander.util;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.GregorianCalendar;
|
import java.util.GregorianCalendar;
|
||||||
|
|
||||||
import com.webcodepro.applecommander.storage.FormattedDisk;
|
|
||||||
import com.webcodepro.applecommander.storage.physical.ImageOrder;
|
import com.webcodepro.applecommander.storage.physical.ImageOrder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -616,28 +614,6 @@ public class AppleUtil {
|
||||||
return sourceOrder.getSectorsPerDisk() == targetOrder.getSectorsPerDisk();
|
return sourceOrder.getSectorsPerDisk() == targetOrder.getSectorsPerDisk();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Compare two disks by track and sector.
|
|
||||||
*/
|
|
||||||
public static boolean disksEqualByTrackAndSector(FormattedDisk sourceDisk, FormattedDisk targetDisk) {
|
|
||||||
ImageOrder sourceOrder = sourceDisk.getImageOrder();
|
|
||||||
ImageOrder targetOrder = targetDisk.getImageOrder();
|
|
||||||
if (!sameSectorsPerDisk(sourceOrder, targetOrder)) {
|
|
||||||
throw new IllegalArgumentException(textBundle.
|
|
||||||
get("AppleUtil.CannotCompareDisks")); //$NON-NLS-1$
|
|
||||||
}
|
|
||||||
for (int track = 0; track < sourceOrder.getTracksPerDisk(); track++) {
|
|
||||||
for (int sector = 0; sector < sourceOrder.getSectorsPerTrack(); sector++) {
|
|
||||||
byte[] sourceData = sourceOrder.readSector(track, sector);
|
|
||||||
byte[] targetData = targetOrder.readSector(track, sector);
|
|
||||||
if (!Arrays.equals(sourceData, targetData)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Change ImageOrder from source order to target order by copying block by block.
|
* Change ImageOrder from source order to target order by copying block by block.
|
||||||
*/
|
*/
|
||||||
|
@ -658,24 +634,4 @@ public class AppleUtil {
|
||||||
protected static boolean sameBlocksPerDisk(ImageOrder sourceOrder, ImageOrder targetOrder) {
|
protected static boolean sameBlocksPerDisk(ImageOrder sourceOrder, ImageOrder targetOrder) {
|
||||||
return sourceOrder.getBlocksOnDevice() == targetOrder.getBlocksOnDevice();
|
return sourceOrder.getBlocksOnDevice() == targetOrder.getBlocksOnDevice();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Compare two disks block by block.
|
|
||||||
*/
|
|
||||||
public static boolean disksEqualByBlock(FormattedDisk sourceDisk, FormattedDisk targetDisk) {
|
|
||||||
ImageOrder sourceOrder = sourceDisk.getImageOrder();
|
|
||||||
ImageOrder targetOrder = targetDisk.getImageOrder();
|
|
||||||
if (!sameBlocksPerDisk(sourceOrder, targetOrder)) {
|
|
||||||
throw new IllegalArgumentException(textBundle.
|
|
||||||
get("AppleUtil.CannotCompareDisks")); //$NON-NLS-1$
|
|
||||||
}
|
|
||||||
for (int block = 0; block < sourceOrder.getBlocksOnDevice(); block++) {
|
|
||||||
byte[] sourceData = sourceOrder.readBlock(block);
|
|
||||||
byte[] targetData = targetOrder.readBlock(block);
|
|
||||||
if (!Arrays.equals(sourceData, targetData)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -289,10 +289,10 @@ CompareDisksStartPane.DiskNLabel=Please select disk image \#{0}:
|
||||||
|
|
||||||
# CompareDisksResultsPane
|
# CompareDisksResultsPane
|
||||||
CompareDisksResultsPane.RestartText=If you wish to compare more disks, click back and start again.
|
CompareDisksResultsPane.RestartText=If you wish to compare more disks, click back and start again.
|
||||||
CompareDisksResultsPane.UnableToLoadDiskN=Unable to load disk \#{0}: {1}\n
|
CompareDisksResultsPane.UnableToLoadDiskN=Unable to load disk \#{0}: {1}
|
||||||
CompareDisksResultsPane.DifferentSizeError=The two disks are of differing formats - unable to compare.\n
|
CompareDisksResultsPane.DifferentSizeError=The two disks are of differing formats - unable to compare.
|
||||||
CompareDisksResultsPane.DataDiffersMessage=The two disks do not contain the same data.\n
|
CompareDisksResultsPane.DataDiffersMessage=The two disks do not contain the same data.
|
||||||
CompareDisksResultsPane.DifferentDataFormatError=The two disks are not the same data format.\n
|
CompareDisksResultsPane.DifferentDataFormatError=The two disks are not the same data format.
|
||||||
CompareDisksResultsPane.DisksMatch=The disk images match.
|
CompareDisksResultsPane.DisksMatch=The disk images match.
|
||||||
|
|
||||||
# GraphicsFilterAdapter
|
# GraphicsFilterAdapter
|
||||||
|
|
|
@ -28,6 +28,8 @@ import org.junit.Test;
|
||||||
import com.webcodepro.applecommander.storage.Disk;
|
import com.webcodepro.applecommander.storage.Disk;
|
||||||
import com.webcodepro.applecommander.storage.DiskFullException;
|
import com.webcodepro.applecommander.storage.DiskFullException;
|
||||||
import com.webcodepro.applecommander.storage.FileEntry;
|
import com.webcodepro.applecommander.storage.FileEntry;
|
||||||
|
import com.webcodepro.applecommander.storage.compare.ComparisonResult;
|
||||||
|
import com.webcodepro.applecommander.storage.compare.DiskDiff;
|
||||||
import com.webcodepro.applecommander.storage.os.dos33.DosFormatDisk;
|
import com.webcodepro.applecommander.storage.os.dos33.DosFormatDisk;
|
||||||
import com.webcodepro.applecommander.storage.os.prodos.ProdosFormatDisk;
|
import com.webcodepro.applecommander.storage.os.prodos.ProdosFormatDisk;
|
||||||
import com.webcodepro.applecommander.storage.physical.ByteArrayImageLayout;
|
import com.webcodepro.applecommander.storage.physical.ByteArrayImageLayout;
|
||||||
|
@ -92,7 +94,9 @@ public class AppleUtilTest {
|
||||||
AppleUtil.changeImageOrderByTrackAndSector(dosDiskDosOrder.getImageOrder(),
|
AppleUtil.changeImageOrderByTrackAndSector(dosDiskDosOrder.getImageOrder(),
|
||||||
dosDiskNibbleOrder.getImageOrder());
|
dosDiskNibbleOrder.getImageOrder());
|
||||||
// Confirm that these disks are identical:
|
// Confirm that these disks are identical:
|
||||||
assertTrue(AppleUtil.disksEqualByTrackAndSector(dosDiskDosOrder, dosDiskNibbleOrder));
|
ComparisonResult result = DiskDiff.create(dosDiskDosOrder, dosDiskDosOrder)
|
||||||
|
.selectCompareByTrackSectorGeometry().compare();
|
||||||
|
assertEquals("Expected disks to have no differences", 0, result.getDifferenceCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -112,7 +116,9 @@ public class AppleUtilTest {
|
||||||
AppleUtil.changeImageOrderByBlock(prodosDiskDosOrder.getImageOrder(),
|
AppleUtil.changeImageOrderByBlock(prodosDiskDosOrder.getImageOrder(),
|
||||||
prodosDiskNibbleOrder.getImageOrder());
|
prodosDiskNibbleOrder.getImageOrder());
|
||||||
// Confirm that these disks are identical:
|
// Confirm that these disks are identical:
|
||||||
assertTrue(AppleUtil.disksEqualByBlock(prodosDiskDosOrder, prodosDiskNibbleOrder));
|
ComparisonResult result = DiskDiff.create(prodosDiskDosOrder, prodosDiskNibbleOrder)
|
||||||
|
.selectCompareByBlockGeometry().compare();
|
||||||
|
assertEquals("Expected disks to have no differences", 0, result.getDifferenceCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -19,16 +19,19 @@
|
||||||
*/
|
*/
|
||||||
package com.webcodepro.applecommander.ui.swt.wizard.comparedisks;
|
package com.webcodepro.applecommander.ui.swt.wizard.comparedisks;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.eclipse.swt.SWT;
|
import org.eclipse.swt.SWT;
|
||||||
import org.eclipse.swt.layout.RowLayout;
|
import org.eclipse.swt.layout.RowLayout;
|
||||||
import org.eclipse.swt.widgets.Composite;
|
import org.eclipse.swt.widgets.Composite;
|
||||||
import org.eclipse.swt.widgets.Label;
|
import org.eclipse.swt.widgets.Label;
|
||||||
|
|
||||||
import com.webcodepro.applecommander.storage.Disk;
|
import com.webcodepro.applecommander.storage.Disk;
|
||||||
import com.webcodepro.applecommander.storage.FormattedDisk;
|
import com.webcodepro.applecommander.storage.compare.ComparisonResult;
|
||||||
|
import com.webcodepro.applecommander.storage.compare.DiskDiff;
|
||||||
import com.webcodepro.applecommander.ui.UiBundle;
|
import com.webcodepro.applecommander.ui.UiBundle;
|
||||||
import com.webcodepro.applecommander.ui.swt.wizard.WizardPane;
|
import com.webcodepro.applecommander.ui.swt.wizard.WizardPane;
|
||||||
import com.webcodepro.applecommander.util.AppleUtil;
|
|
||||||
import com.webcodepro.applecommander.util.TextBundle;
|
import com.webcodepro.applecommander.util.TextBundle;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -75,6 +78,8 @@ public class CompareDisksResultsPane extends WizardPane {
|
||||||
|
|
||||||
label = new Label(control, SWT.WRAP);
|
label = new Label(control, SWT.WRAP);
|
||||||
label.setText(textBundle.get("CompareDisksResultsPane.RestartText")); //$NON-NLS-1$
|
label.setText(textBundle.get("CompareDisksResultsPane.RestartText")); //$NON-NLS-1$
|
||||||
|
|
||||||
|
parent.pack();
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Get the next pane. A null return indicates the end of the wizard.
|
* Get the next pane. A null return indicates the end of the wizard.
|
||||||
|
@ -93,49 +98,31 @@ public class CompareDisksResultsPane extends WizardPane {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String compareDisks() {
|
protected String compareDisks() {
|
||||||
StringBuffer errorMessages = new StringBuffer();
|
List<String> errorMessages = new ArrayList<>();
|
||||||
FormattedDisk[] disk1 = null;
|
Disk disk1 = null;
|
||||||
try {
|
try {
|
||||||
disk1 = new Disk(wizard.getDiskname1()).getFormattedDisks();
|
disk1 = new Disk(wizard.getDiskname1());
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
errorMessages.append(textBundle.
|
errorMessages.add(textBundle.
|
||||||
format("CompareDisksResultsPane.UnableToLoadDiskN", //$NON-NLS-1$
|
format("CompareDisksResultsPane.UnableToLoadDiskN", //$NON-NLS-1$
|
||||||
1, t.getLocalizedMessage()));
|
1, t.getLocalizedMessage()));
|
||||||
}
|
}
|
||||||
FormattedDisk[] disk2 = null;
|
Disk disk2 = null;
|
||||||
try {
|
try {
|
||||||
disk2 = new Disk(wizard.getDiskname2()).getFormattedDisks();
|
disk2 = new Disk(wizard.getDiskname2());
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
errorMessages.append(textBundle.
|
errorMessages.add(textBundle.
|
||||||
format("CompareDisksResultsPane.UnableToLoadDiskN", //$NON-NLS-1$
|
format("CompareDisksResultsPane.UnableToLoadDiskN", //$NON-NLS-1$
|
||||||
2, t.getLocalizedMessage()));
|
2, t.getLocalizedMessage()));
|
||||||
}
|
}
|
||||||
if (disk1 != null && disk2 != null) {
|
if (disk1 != null && disk2 != null) {
|
||||||
if (disk1.length != disk2.length) {
|
ComparisonResult result = DiskDiff.compare(disk1, disk2);
|
||||||
errorMessages.append(textBundle.get(
|
errorMessages.addAll(result.getErrors());
|
||||||
"CompareDisksResultsPane.DifferentSizeError")); //$NON-NLS-1$
|
errorMessages.addAll(result.getWarnings());
|
||||||
} else {
|
|
||||||
boolean disk1TSformat = disk1[0].isCpmFormat() || disk1[0].isDosFormat() || disk1[0].isRdosFormat();
|
|
||||||
boolean disk2TSformat = disk2[0].isCpmFormat() || disk2[0].isDosFormat() || disk2[0].isRdosFormat();
|
|
||||||
if (disk1TSformat && disk2TSformat) {
|
|
||||||
if (!AppleUtil.disksEqualByTrackAndSector(disk1[0], disk2[0])) {
|
|
||||||
errorMessages.append(textBundle.get(
|
|
||||||
"CompareDisksResultsPane.DataDiffersMessage")); //$NON-NLS-1$
|
|
||||||
}
|
}
|
||||||
} else if (!disk1TSformat && !disk2TSformat) {
|
if (errorMessages.size() == 0) {
|
||||||
if (!AppleUtil.disksEqualByBlock(disk1[0], disk2[0])) {
|
|
||||||
errorMessages.append(textBundle.get(
|
|
||||||
"CompareDisksResultsPane.DataDiffersMessage")); //$NON-NLS-1$
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
errorMessages.append(textBundle.get(
|
|
||||||
"CompareDisksResultsPane.DifferentDataFormatError")); //$NON-NLS-1$
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (errorMessages.length() == 0) {
|
|
||||||
return textBundle.get("CompareDisksResultsPane.DisksMatch"); //$NON-NLS-1$
|
return textBundle.get("CompareDisksResultsPane.DisksMatch"); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
return errorMessages.toString();
|
return String.join("\n", errorMessages);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user