1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-13 03:05:39 +02:00

Bug 562164 - Add JUnit tests for IMemoryExporter implementations

The following changes are done to make the implementation headless and
testable:
* Reworked FileExport to implement base flow
* Extracted PlainTextExport extends FileExport
* Extracted RawBinaryExport extends FileExport
* Extracted SRecordExport extends FileExport
* Reworked related i18n

Change-Id: Ica1057e0b628c2f17b5e588cd9b0524b5b7a400d
Signed-off-by: Alexander Fedorov <alexander.fedorov@arsysop.ru>
This commit is contained in:
Alexander Fedorov 2020-04-27 13:51:08 +03:00
parent 6491efc5e9
commit 7f7c2a0c24
15 changed files with 427 additions and 372 deletions

View file

@ -14,9 +14,18 @@
package org.eclipse.cdt.debug.core.memory.transport; package org.eclipse.cdt.debug.core.memory.transport;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.math.BigInteger; import java.math.BigInteger;
import org.eclipse.cdt.debug.internal.core.memory.transport.Messages;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.ICoreRunnable; import org.eclipse.core.runtime.ICoreRunnable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugException;
import org.osgi.framework.FrameworkUtil;
/** /**
* Exports memory information to a given file * Exports memory information to a given file
@ -30,7 +39,7 @@ public abstract class FileExport<O extends AutoCloseable> implements ICoreRunnab
protected final BigInteger addressable; protected final BigInteger addressable;
protected final ReadMemory read; protected final ReadMemory read;
protected final File file; private final File file;
protected FileExport(File input, ExportRequest request) { protected FileExport(File input, ExportRequest request) {
this.file = input; this.file = input;
@ -40,4 +49,72 @@ public abstract class FileExport<O extends AutoCloseable> implements ICoreRunnab
this.read = request.read(); this.read = request.read();
} }
@Override
public void run(IProgressMonitor monitor) throws CoreException {
try (O writer = output(file)) {
BigInteger jobs = end.subtract(start).divide(chunkSize());
BigInteger factor = BigInteger.ONE;
if (jobs.compareTo(BigInteger.valueOf(0x7FFFFFFF)) > 0) {
factor = jobs.divide(BigInteger.valueOf(0x7FFFFFFF));
jobs = jobs.divide(factor);
}
monitor.beginTask(Messages.FileExport_task_transferring, jobs.intValue());
transfer(writer, factor, monitor);
} catch (IOException ex) {
requestFailed(Messages.FileExport_e_write_file, ex);
} catch (DebugException ex) {
requestFailed(Messages.FileExport_e_read_target, ex);
} catch (Exception ex) {
internalError(Messages.FileExport_e_export_memory, ex);
} finally {
monitor.done();
}
}
/**
* Creates the writer for the given file
*
* @param file to export to
* @return writer instance
* @throws IOException
*/
protected abstract O output(File file) throws IOException;
/**
* Determines the data chunk to use for export
*
* @return the size of data chunk
*/
protected abstract BigInteger chunkSize();
protected abstract void transfer(O output, BigInteger factor, IProgressMonitor monitor)
throws IOException, DebugException;
protected String transferring(BigInteger length, BigInteger address) {
return String.format(Messages.FileExport_sub_transferring, length.toString(10), address.toString(16));
}
protected void requestFailed(String message, Throwable exception) throws DebugException {
failed(DebugException.REQUEST_FAILED, message, exception);
}
protected void internalError(String message, Throwable exception) throws DebugException {
failed(DebugException.INTERNAL_ERROR, message, exception);
}
protected void failed(int code, String message, Throwable exception) throws DebugException {
Status status = new Status(//
IStatus.ERROR, //
FrameworkUtil.getBundle(getClass()).getSymbolicName(), //
code, //
message, //
exception);
failed(new DebugException(status));
}
protected void failed(DebugException exception) throws DebugException {
Platform.getLog(FrameworkUtil.getBundle(getClass())).log(exception.getStatus());
throw exception;
}
} }

View file

@ -61,47 +61,52 @@ public abstract class FileImport<I extends AutoCloseable> implements ICoreRunnab
jobs = jobs.divide(factor); jobs = jobs.divide(factor);
} }
monitor.beginTask(Messages.FileImport_task_transferring, jobs.intValue()); monitor.beginTask(Messages.FileImport_task_transferring, jobs.intValue());
transfer(monitor, reader, factor); transfer(reader, factor, monitor);
if (!monitor.isCanceled()) { if (!monitor.isCanceled()) {
write.flush(); write.flush();
} }
} catch (IOException ex) { } catch (IOException ex) {
requestFailed(Messages.FileImport_e_read_from_file, ex); requestFailed(Messages.FileImport_e_read_file, ex);
} catch (DebugException ex) { } catch (DebugException ex) {
requestFailed(Messages.FileImport_e_write_to_target, ex); requestFailed(Messages.FileImport_e_write_target, ex);
} catch (CoreException ex) {
failed(ex);
} catch (Exception ex) { } catch (Exception ex) {
internalError(Messages.FileImport_e_import_from_file, ex); internalError(Messages.FileImport_e_import_file, ex);
} finally { } finally {
monitor.done(); monitor.done();
} }
} }
/**
* Creates the reader for the given file
*
* @param file to import from
* @return reader instance
* @throws IOException
*/
protected abstract I input(File file) throws FileNotFoundException; protected abstract I input(File file) throws FileNotFoundException;
protected abstract void transfer(IProgressMonitor monitor, I input, BigInteger factor) protected abstract void transfer(I input, BigInteger factor, IProgressMonitor monitor)
throws IOException, CoreException, DebugException; throws IOException, DebugException;
protected void requestFailed(String message, Throwable exception) throws CoreException { protected void requestFailed(String message, Throwable exception) throws DebugException {
failed(DebugException.REQUEST_FAILED, message, exception); failed(DebugException.REQUEST_FAILED, message, exception);
} }
protected void internalError(String message, Throwable exception) throws CoreException { protected void internalError(String message, Throwable exception) throws DebugException {
failed(DebugException.INTERNAL_ERROR, message, exception); failed(DebugException.INTERNAL_ERROR, message, exception);
} }
protected void failed(int code, String message, Throwable exception) throws CoreException { protected void failed(int code, String message, Throwable exception) throws DebugException {
Status status = new Status(// Status status = new Status(//
IStatus.ERROR, // IStatus.ERROR, //
FrameworkUtil.getBundle(getClass()).getSymbolicName(), // FrameworkUtil.getBundle(getClass()).getSymbolicName(), //
code, // code, //
message, // message, //
exception); exception);
failed(new CoreException(status)); failed(new DebugException(status));
} }
protected void failed(CoreException exception) throws CoreException { protected void failed(DebugException exception) throws DebugException {
Platform.getLog(FrameworkUtil.getBundle(getClass())).log(exception.getStatus()); Platform.getLog(FrameworkUtil.getBundle(getClass())).log(exception.getStatus());
throw exception; throw exception;
} }

View file

@ -17,9 +17,14 @@ import org.eclipse.osgi.util.NLS;
public class Messages extends NLS { public class Messages extends NLS {
private static final String BUNDLE_NAME = "org.eclipse.cdt.debug.internal.core.memory.transport.messages"; //$NON-NLS-1$ private static final String BUNDLE_NAME = "org.eclipse.cdt.debug.internal.core.memory.transport.messages"; //$NON-NLS-1$
public static String FileImport_e_import_from_file; public static String FileExport_e_export_memory;
public static String FileImport_e_read_from_file; public static String FileExport_e_read_target;
public static String FileImport_e_write_to_target; public static String FileExport_e_write_file;
public static String FileExport_sub_transferring;
public static String FileExport_task_transferring;
public static String FileImport_e_import_file;
public static String FileImport_e_read_file;
public static String FileImport_e_write_target;
public static String FileImport_task_transferring; public static String FileImport_task_transferring;
public static String PlainTextImport_e_invalid_format; public static String PlainTextImport_e_invalid_format;
public static String SRecordImport_e_checksum_failure; public static String SRecordImport_e_checksum_failure;

View file

@ -0,0 +1,91 @@
/*******************************************************************************
* Copyright (c) 2006, 2020 Wind River Systems, Inc. and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Ted R Williams (Wind River Systems, Inc.) - initial implementation
* Alexander Fedorov (ArSysOp) - headless part extraction
*******************************************************************************/
package org.eclipse.cdt.debug.internal.core.memory.transport;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.math.BigInteger;
import org.eclipse.cdt.debug.core.memory.transport.ExportRequest;
import org.eclipse.cdt.debug.core.memory.transport.FileExport;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.debug.core.DebugException;
public final class PlainTextExport extends FileExport<FileWriter> {
public PlainTextExport(File output, ExportRequest request) {
super(output, request);
}
@Override
protected FileWriter output(File file) throws IOException {
return new FileWriter(file);
}
@Override
protected BigInteger chunkSize() {
// These variables control how the output will be formatted
// The output data is split by chunks of 1 addressable unit size.
BigInteger dataCellSize = BigInteger.valueOf(1);
// show 32 bytes of data per line, total. Adjust number of columns to compensate
// for longer addressable unit size
BigInteger numberOfColumns = BigInteger.valueOf(32).divide(addressable);
// deduce the number of data chunks to be output, per line
return dataCellSize.multiply(numberOfColumns);
}
@Override
protected void transfer(FileWriter output, BigInteger factor, IProgressMonitor monitor)
throws IOException, DebugException {
// These variables control how the output will be formatted
// The output data is split by chunks of 1 addressable unit size.
final BigInteger dataCellSize = BigInteger.valueOf(1);
BigInteger transferAddress = start;
BigInteger jobCount = BigInteger.ZERO;
BigInteger dataCellsPerLine = chunkSize();
while (transferAddress.compareTo(end) < 0 && !monitor.isCanceled()) {
BigInteger length = dataCellsPerLine;
if (end.subtract(transferAddress).compareTo(length) < 0) {
length = end.subtract(transferAddress);
}
monitor.subTask(transferring(length, transferAddress));
StringBuilder buf = new StringBuilder();
for (int i = 0; i < length.divide(dataCellSize).intValue(); i++) {
if (i != 0) {
buf.append(" "); //$NON-NLS-1$
}
BigInteger from = transferAddress.add(dataCellSize.multiply(BigInteger.valueOf(i)));
byte[] bytes = read.from(from);
for (int byteIndex = 0; byteIndex < bytes.length; byteIndex++) {
String bString = BigInteger.valueOf(0xFF & bytes[byteIndex]).toString(16);
if (bString.length() == 1) {
buf.append("0"); //$NON-NLS-1$
}
buf.append(bString);
}
}
output.write(buf.toString().toUpperCase());
output.write("\n"); //$NON-NLS-1$
transferAddress = transferAddress.add(length);
jobCount = jobCount.add(BigInteger.ONE);
if (jobCount.compareTo(factor) == 0) {
jobCount = BigInteger.ZERO;
monitor.worked(1);
}
}
}
}

View file

@ -26,7 +26,6 @@ import java.util.function.Consumer;
import org.eclipse.cdt.debug.core.memory.transport.FileImport; import org.eclipse.cdt.debug.core.memory.transport.FileImport;
import org.eclipse.cdt.debug.core.memory.transport.ImportRequest; import org.eclipse.cdt.debug.core.memory.transport.ImportRequest;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.Status;
@ -45,8 +44,8 @@ public final class PlainTextImport extends FileImport<BufferedReader> {
} }
@Override @Override
protected void transfer(IProgressMonitor monitor, BufferedReader reader, BigInteger factor) protected void transfer(BufferedReader reader, BigInteger factor, IProgressMonitor monitor)
throws IOException, CoreException, DebugException { throws IOException, DebugException {
BigInteger recordAddress = start; BigInteger recordAddress = start;
String line = reader.readLine(); String line = reader.readLine();
int lineNo = 1; // line error reporting int lineNo = 1; // line error reporting
@ -61,7 +60,7 @@ public final class PlainTextImport extends FileImport<BufferedReader> {
try { try {
data[i] = new BigInteger(valueString.substring(position++, position++ + 1), 16).byteValue(); data[i] = new BigInteger(valueString.substring(position++, position++ + 1), 16).byteValue();
} catch (NumberFormatException ex) { } catch (NumberFormatException ex) {
throw new CoreException(new Status(IStatus.ERROR, throw new DebugException(new Status(IStatus.ERROR,
FrameworkUtil.getBundle(getClass()).getSymbolicName(), DebugException.REQUEST_FAILED, FrameworkUtil.getBundle(getClass()).getSymbolicName(), DebugException.REQUEST_FAILED,
String.format(Messages.PlainTextImport_e_invalid_format, lineNo), ex)); String.format(Messages.PlainTextImport_e_invalid_format, lineNo), ex));
} }

View file

@ -0,0 +1,66 @@
/*******************************************************************************
* Copyright (c) 2006, 2020 Wind River Systems, Inc. and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Ted R Williams (Wind River Systems, Inc.) - initial implementation
* Alexander Fedorov (ArSysOp) - headless part extraction
*******************************************************************************/
package org.eclipse.cdt.debug.internal.core.memory.transport;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import org.eclipse.cdt.debug.core.memory.transport.ExportRequest;
import org.eclipse.cdt.debug.core.memory.transport.FileExport;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.debug.core.DebugException;
public final class RAWBinaryExport extends FileExport<FileOutputStream> {
public RAWBinaryExport(File input, ExportRequest request) {
super(input, request);
}
@Override
protected FileOutputStream output(File file) throws IOException {
return new FileOutputStream(file);
}
@Override
protected BigInteger chunkSize() {
return BigInteger.valueOf(1024);
}
@Override
protected void transfer(FileOutputStream output, BigInteger factor, IProgressMonitor monitor)
throws IOException, DebugException {
BigInteger transferAddress = start;
BigInteger jobCount = BigInteger.ZERO;
BigInteger chunkSize = chunkSize();
while (transferAddress.compareTo(end) < 0 && !monitor.isCanceled()) {
BigInteger length = chunkSize;
if (end.subtract(transferAddress).compareTo(length) < 0) {
length = end.subtract(transferAddress);
}
monitor.subTask(transferring(length, transferAddress));
byte[] byteValues = read.from(transferAddress);
output.write(byteValues);
transferAddress = transferAddress.add(length);
jobCount = jobCount.add(BigInteger.ONE);
if (jobCount.compareTo(factor) == 0) {
jobCount = BigInteger.ZERO;
monitor.worked(1);
}
}
}
}

View file

@ -23,7 +23,6 @@ import java.util.function.Consumer;
import org.eclipse.cdt.debug.core.memory.transport.FileImport; import org.eclipse.cdt.debug.core.memory.transport.FileImport;
import org.eclipse.cdt.debug.core.memory.transport.ImportRequest; import org.eclipse.cdt.debug.core.memory.transport.ImportRequest;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.DebugException;
@ -39,8 +38,8 @@ public final class RAWBinaryImport extends FileImport<FileInputStream> {
} }
@Override @Override
protected void transfer(IProgressMonitor monitor, FileInputStream input, BigInteger factor) protected void transfer(FileInputStream input, BigInteger factor, IProgressMonitor monitor)
throws IOException, CoreException, DebugException { throws IOException, DebugException {
byte[] byteValues = new byte[1024]; byte[] byteValues = new byte[1024];
int actualByteCount = input.read(byteValues); int actualByteCount = input.read(byteValues);
BigInteger recordAddress = start; BigInteger recordAddress = start;

View file

@ -0,0 +1,118 @@
/*******************************************************************************
* Copyright (c) 2006, 2020 Wind River Systems, Inc. and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Ted R Williams (Wind River Systems, Inc.) - initial implementation
* Alexander Fedorov (ArSysOp) - headless part extraction
*******************************************************************************/
package org.eclipse.cdt.debug.internal.core.memory.transport;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.math.BigInteger;
import org.eclipse.cdt.debug.core.memory.transport.ExportRequest;
import org.eclipse.cdt.debug.core.memory.transport.FileExport;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.debug.core.DebugException;
public final class SRecordExport extends FileExport<FileWriter> {
public SRecordExport(File input, ExportRequest request) {
super(input, request);
}
@Override
protected FileWriter output(File file) throws IOException {
return new FileWriter(file);
}
@Override
protected BigInteger chunkSize() {
// FIXME 4 byte default
return BigInteger.valueOf(16);
}
@Override
protected void transfer(FileWriter output, BigInteger factor, IProgressMonitor monitor)
throws IOException, DebugException {
final BigInteger DATA_PER_RECORD = chunkSize();
final BigInteger DATA_PER_TRANSFER = BigInteger.valueOf(4096).multiply(DATA_PER_RECORD);
BigInteger jobCount = BigInteger.ZERO;
BigInteger transferAddress = start;
while (transferAddress.compareTo(end) < 0 && !monitor.isCanceled()) {
BigInteger length = DATA_PER_TRANSFER;
if (end.subtract(transferAddress).compareTo(length) < 0) {
length = end.subtract(transferAddress);
}
monitor.subTask(transferring(length, transferAddress));
byte[] bytes = read.from(transferAddress);
BigInteger sRecordAddress = transferAddress;
BigInteger sRecordEndAddress = transferAddress.add(length);
while (sRecordAddress.compareTo(sRecordEndAddress) < 0 && !monitor.isCanceled()) {
BigInteger sRecordDataLength = DATA_PER_RECORD;
if (sRecordEndAddress.subtract(sRecordAddress).compareTo(sRecordDataLength) < 0) {
sRecordDataLength = end.subtract(sRecordAddress);
}
output.write("S3"); // FIXME 4 byte address //$NON-NLS-1$
StringBuilder buf = new StringBuilder();
BigInteger sRecordLength = BigInteger.valueOf(4); // address size
sRecordLength = sRecordLength.add(sRecordDataLength);
sRecordLength = sRecordLength.add(BigInteger.ONE); // checksum
String transferAddressString = sRecordAddress.toString(16);
String lengthString = sRecordLength.toString(16);
if (lengthString.length() == 1) {
buf.append("0"); //$NON-NLS-1$
}
buf.append(lengthString);
for (int i = 0; i < 8 - transferAddressString.length(); i++) {
buf.append("0"); //$NON-NLS-1$
}
buf.append(transferAddressString);
final int byteOffset = sRecordAddress.subtract(transferAddress).intValue();
final int byteLength = byteOffset + sRecordDataLength.intValue();
for (int byteIndex = byteOffset; byteIndex < byteLength; byteIndex++) {
String bString = BigInteger.valueOf(0xFF & bytes[byteIndex]).toString(16);
if (bString.length() == 1) {
buf.append("0"); //$NON-NLS-1$
}
buf.append(bString);
}
/*
* The least significant byte of the one's complement of the sum of the values
* represented by the pairs of characters making up the records length, address,
* and the code/data fields.
*/
byte checksum = 0;
for (int i = 0; i < buf.length(); i += 2) {
BigInteger value = new BigInteger(buf.substring(i, i + 2), 16);
checksum += value.byteValue();
}
String bString = BigInteger.valueOf(0xFF - checksum).and(BigInteger.valueOf(0xFF)).toString(16);
if (bString.length() == 1) {
buf.append("0"); //$NON-NLS-1$
}
buf.append(bString);
output.write(buf.toString().toUpperCase());
output.write("\n"); //$NON-NLS-1$
sRecordAddress = sRecordAddress.add(sRecordDataLength);
jobCount = jobCount.add(BigInteger.ONE);
if (jobCount.compareTo(factor) == 0) {
jobCount = BigInteger.ZERO;
monitor.worked(1);
}
}
transferAddress = transferAddress.add(length);
}
}
}

View file

@ -25,7 +25,6 @@ import java.util.function.Consumer;
import org.eclipse.cdt.debug.core.memory.transport.FileImport; import org.eclipse.cdt.debug.core.memory.transport.FileImport;
import org.eclipse.cdt.debug.core.memory.transport.ImportRequest; import org.eclipse.cdt.debug.core.memory.transport.ImportRequest;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.Status;
@ -47,8 +46,8 @@ public class SRecordImport extends FileImport<BufferedReader> {
} }
@Override @Override
protected void transfer(IProgressMonitor monitor, BufferedReader reader, BigInteger factor) protected void transfer(BufferedReader reader, BigInteger factor, IProgressMonitor monitor)
throws IOException, CoreException, DebugException { throws IOException, DebugException {
// FIXME 4 byte default // FIXME 4 byte default
final int CHECKSUM_LENGTH = 1; final int CHECKSUM_LENGTH = 1;
BigInteger offset = null; BigInteger offset = null;
@ -63,8 +62,8 @@ public class SRecordImport extends FileImport<BufferedReader> {
try { try {
recordCount = Integer.parseInt(line.substring(2, 4), 16); recordCount = Integer.parseInt(line.substring(2, 4), 16);
} catch (NumberFormatException ex) { } catch (NumberFormatException ex) {
throw new CoreException(new Status(IStatus.ERROR, FrameworkUtil.getBundle(getClass()).getSymbolicName(), throw new DebugException(new Status(IStatus.ERROR,
DebugException.REQUEST_FAILED, FrameworkUtil.getBundle(getClass()).getSymbolicName(), DebugException.REQUEST_FAILED,
String.format(Messages.SRecordImport_e_invalid_line_length, lineNo), ex)); String.format(Messages.SRecordImport_e_invalid_line_length, lineNo), ex));
} }
int bytesRead = 4 + recordCount; int bytesRead = 4 + recordCount;
@ -87,9 +86,9 @@ public class SRecordImport extends FileImport<BufferedReader> {
try { try {
recordAddress = new BigInteger(line.substring(position, position + addressSize * 2), 16); recordAddress = new BigInteger(line.substring(position, position + addressSize * 2), 16);
} catch (NumberFormatException ex) { } catch (NumberFormatException ex) {
throw new CoreException(new Status(IStatus.ERROR, FrameworkUtil.getBundle(getClass()).getSymbolicName(), throw new DebugException(new Status(IStatus.ERROR,
DebugException.REQUEST_FAILED, String.format(Messages.SRecordImport_e_invalid_address, lineNo), FrameworkUtil.getBundle(getClass()).getSymbolicName(), DebugException.REQUEST_FAILED,
ex)); String.format(Messages.SRecordImport_e_invalid_address, lineNo), ex));
} }
recordCount -= addressSize; recordCount -= addressSize;
position += addressSize * 2; position += addressSize * 2;
@ -102,7 +101,7 @@ public class SRecordImport extends FileImport<BufferedReader> {
try { try {
data[i] = new BigInteger(line.substring(position++, position++ + 1), 16).byteValue(); data[i] = new BigInteger(line.substring(position++, position++ + 1), 16).byteValue();
} catch (NumberFormatException ex) { } catch (NumberFormatException ex) {
throw new CoreException(new Status(IStatus.ERROR, throw new DebugException(new Status(IStatus.ERROR,
FrameworkUtil.getBundle(getClass()).getSymbolicName(), DebugException.REQUEST_FAILED, FrameworkUtil.getBundle(getClass()).getSymbolicName(), DebugException.REQUEST_FAILED,
String.format(Messages.SRecordImport_e_invalid_data, lineNo), ex)); String.format(Messages.SRecordImport_e_invalid_data, lineNo), ex));
} }
@ -119,7 +118,7 @@ public class SRecordImport extends FileImport<BufferedReader> {
try { try {
value = new BigInteger(buf.substring(i, i + 2), 16); value = new BigInteger(buf.substring(i, i + 2), 16);
} catch (NumberFormatException ex) { } catch (NumberFormatException ex) {
throw new CoreException(new Status(IStatus.ERROR, throw new DebugException(new Status(IStatus.ERROR,
FrameworkUtil.getBundle(getClass()).getSymbolicName(), DebugException.REQUEST_FAILED, FrameworkUtil.getBundle(getClass()).getSymbolicName(), DebugException.REQUEST_FAILED,
String.format(Messages.SRecordImport_e_invalid_checksum_format, lineNo), ex)); String.format(Messages.SRecordImport_e_invalid_checksum_format, lineNo), ex));
} }
@ -132,8 +131,9 @@ public class SRecordImport extends FileImport<BufferedReader> {
*/ */
if (checksum != (byte) -1) { if (checksum != (byte) -1) {
monitor.done(); monitor.done();
throw new CoreException(new Status(IStatus.ERROR, FrameworkUtil.getBundle(getClass()).getSymbolicName(), throw new DebugException(
String.format(Messages.SRecordImport_e_checksum_failure, line))); new Status(IStatus.ERROR, FrameworkUtil.getBundle(getClass()).getSymbolicName(),
String.format(Messages.SRecordImport_e_checksum_failure, line)));
} }
scroll.accept(recordAddress); scroll.accept(recordAddress);
// FIXME error on incorrect checksum // FIXME error on incorrect checksum

View file

@ -12,9 +12,14 @@
# Alexander Fedorov (ArSysOp) - initial API and implementation # Alexander Fedorov (ArSysOp) - initial API and implementation
############################################################################### ###############################################################################
FileImport_e_import_from_file=Failure importing from file FileExport_e_export_memory=Failure exporting memory
FileImport_e_read_from_file=Could not read from file. FileExport_e_read_target=Could not read from target.
FileImport_e_write_to_target=Could not write to target. FileExport_e_write_file=Could not write to file.
FileExport_sub_transferring=Transferring %s bytes at address 0x%s
FileExport_task_transferring=Transferring Data
FileImport_e_import_file=Failure importing from file
FileImport_e_read_file=Could not read from file.
FileImport_e_write_target=Could not write to target.
FileImport_task_transferring=Transferring Data FileImport_task_transferring=Transferring Data
PlainTextImport_e_invalid_format=Invalid file format. Expected integer at line %d PlainTextImport_e_invalid_format=Invalid file format. Expected integer at line %d
SRecordImport_e_checksum_failure=Checksum failure of line = %d SRecordImport_e_checksum_failure=Checksum failure of line = %d

View file

@ -1,111 +0,0 @@
/*******************************************************************************
* Copyright (c) 2006, 2020 Wind River Systems, Inc. and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Ted R Williams (Wind River Systems, Inc.) - initial implementation
* Alexander Fedorov (ArSysOp) - headless part extraction
*******************************************************************************/
package org.eclipse.cdt.debug.ui.memory.transport;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.math.BigInteger;
import org.eclipse.cdt.debug.core.memory.transport.ExportRequest;
import org.eclipse.cdt.debug.core.memory.transport.FileExport;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugException;
final class PlainTextExport extends FileExport<FileWriter> {
protected PlainTextExport(File output, ExportRequest request) {
super(output, request);
}
@Override
public void run(IProgressMonitor monitor) throws CoreException {
try {
// These variables control how the output will be formatted
// The output data is split by chunks of 1 addressable unit size.
final BigInteger dataCellSize = BigInteger.valueOf(1);
// show 32 bytes of data per line, total. Adjust number of columns to compensate
// for longer addressable unit size
final BigInteger numberOfColumns = BigInteger.valueOf(32).divide(addressable);
// deduce the number of data chunks to be output, per line
final BigInteger dataCellsPerLine = dataCellSize.multiply(numberOfColumns);
BigInteger transferAddress = start;
FileWriter writer = new FileWriter(file);
BigInteger jobs = end.subtract(transferAddress).divide(dataCellsPerLine);
BigInteger factor = BigInteger.ONE;
if (jobs.compareTo(BigInteger.valueOf(0x7FFFFFFF)) > 0) {
factor = jobs.divide(BigInteger.valueOf(0x7FFFFFFF));
jobs = jobs.divide(factor);
}
monitor.beginTask(Messages.getString("Exporter.ProgressTitle"), jobs.intValue()); //$NON-NLS-1$
BigInteger jobCount = BigInteger.ZERO;
while (transferAddress.compareTo(end) < 0 && !monitor.isCanceled()) {
BigInteger length = dataCellsPerLine;
if (end.subtract(transferAddress).compareTo(length) < 0)
length = end.subtract(transferAddress);
monitor.subTask(String.format(Messages.getString("Exporter.Progress"), length.toString(10), //$NON-NLS-1$
transferAddress.toString(16)));
StringBuilder buf = new StringBuilder();
for (int i = 0; i < length.divide(dataCellSize).intValue(); i++) {
if (i != 0) {
buf.append(" "); //$NON-NLS-1$
}
BigInteger from = transferAddress.add(dataCellSize.multiply(BigInteger.valueOf(i)));
byte[] bytes = read.from(from);
for (int byteIndex = 0; byteIndex < bytes.length; byteIndex++) {
String bString = BigInteger.valueOf(0xFF & bytes[byteIndex]).toString(16);
if (bString.length() == 1) {
buf.append("0"); //$NON-NLS-1$
}
buf.append(bString);
}
}
writer.write(buf.toString().toUpperCase());
writer.write("\n"); //$NON-NLS-1$
transferAddress = transferAddress.add(length);
jobCount = jobCount.add(BigInteger.ONE);
if (jobCount.compareTo(factor) == 0) {
jobCount = BigInteger.ZERO;
monitor.worked(1);
}
}
writer.close();
monitor.done();
} catch (IOException ex) {
MemoryTransportPlugin.getDefault().getLog()
.log(new Status(IStatus.ERROR, MemoryTransportPlugin.getUniqueIdentifier(),
DebugException.REQUEST_FAILED, Messages.getString("Exporter.ErrFile"), ex)); //$NON-NLS-1$
throw new CoreException(new Status(IStatus.ERROR, MemoryTransportPlugin.getUniqueIdentifier(),
DebugException.REQUEST_FAILED, Messages.getString("Exporter.ErrFile"), ex)); //$NON-NLS-1$
} catch (DebugException ex) {
MemoryTransportPlugin.getDefault().getLog()
.log(new Status(IStatus.ERROR, MemoryTransportPlugin.getUniqueIdentifier(),
DebugException.REQUEST_FAILED, Messages.getString("Exporter.ErrReadTarget"), ex)); //$NON-NLS-1$
throw new CoreException(new Status(IStatus.ERROR, MemoryTransportPlugin.getUniqueIdentifier(),
DebugException.REQUEST_FAILED, Messages.getString("Exporter.ErrReadTarget"), ex)); //$NON-NLS-1$
} catch (Exception ex) {
MemoryTransportPlugin.getDefault().getLog()
.log(new Status(IStatus.ERROR, MemoryTransportPlugin.getUniqueIdentifier(),
DebugException.INTERNAL_ERROR, Messages.getString("Exporter.Falure"), ex)); //$NON-NLS-1$
throw new CoreException(new Status(IStatus.ERROR, MemoryTransportPlugin.getUniqueIdentifier(),
DebugException.INTERNAL_ERROR, Messages.getString("Exporter.Falure"), ex)); //$NON-NLS-1$
}
}
}

View file

@ -19,6 +19,7 @@ import java.math.BigInteger;
import org.eclipse.cdt.debug.core.memory.transport.ExportRequest; import org.eclipse.cdt.debug.core.memory.transport.ExportRequest;
import org.eclipse.cdt.debug.core.memory.transport.ReadMemory; import org.eclipse.cdt.debug.core.memory.transport.ReadMemory;
import org.eclipse.cdt.debug.internal.core.memory.transport.PlainTextExport;
import org.eclipse.cdt.debug.internal.core.memory.transport.ReadMemoryBlock; import org.eclipse.cdt.debug.internal.core.memory.transport.ReadMemoryBlock;
import org.eclipse.cdt.debug.internal.core.memory.transport.TransportJob; import org.eclipse.cdt.debug.internal.core.memory.transport.TransportJob;
import org.eclipse.cdt.debug.internal.ui.memory.transport.AddressableSize; import org.eclipse.cdt.debug.internal.ui.memory.transport.AddressableSize;

View file

@ -15,19 +15,17 @@
package org.eclipse.cdt.debug.ui.memory.transport; package org.eclipse.cdt.debug.ui.memory.transport;
import java.io.File; import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigInteger; import java.math.BigInteger;
import org.eclipse.cdt.debug.core.memory.transport.ExportRequest;
import org.eclipse.cdt.debug.core.memory.transport.ReadMemory;
import org.eclipse.cdt.debug.internal.core.memory.transport.RAWBinaryExport;
import org.eclipse.cdt.debug.internal.core.memory.transport.ReadMemoryBlock;
import org.eclipse.cdt.debug.internal.core.memory.transport.TransportJob;
import org.eclipse.cdt.debug.internal.ui.memory.transport.AddressableSize;
import org.eclipse.cdt.debug.ui.memory.transport.model.IMemoryExporter; import org.eclipse.cdt.debug.ui.memory.transport.model.IMemoryExporter;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.model.IMemoryBlock; import org.eclipse.debug.core.model.IMemoryBlock;
import org.eclipse.debug.core.model.IMemoryBlockExtension; import org.eclipse.debug.core.model.IMemoryBlockExtension;
import org.eclipse.debug.core.model.MemoryByte;
import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.swt.SWT; import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.events.KeyEvent;
@ -456,79 +454,11 @@ public class RAWBinaryExporter implements IMemoryExporter {
@Override @Override
public void exportMemory() { public void exportMemory() {
Job job = new Job("Memory Export to RAW Binary File") { //$NON-NLS-1$ ReadMemory read = new ReadMemoryBlock((IMemoryBlockExtension) fMemoryBlock);
@Override BigInteger addressable = new AddressableSize((IMemoryBlockExtension) fMemoryBlock).get();
public IStatus run(IProgressMonitor monitor) { ExportRequest request = new ExportRequest(fStartAddress, fEndAddress, addressable, read);
try { RAWBinaryExport memoryExport = new RAWBinaryExport(fOutputFile, request);
BigInteger DATA_PER_RECORD = BigInteger.valueOf(1024); TransportJob job = new TransportJob("Memory Export to RAW Binary File", memoryExport);
BigInteger transferAddress = fStartAddress;
FileOutputStream writer = new FileOutputStream(fOutputFile);
BigInteger jobs = fEndAddress.subtract(transferAddress).divide(DATA_PER_RECORD);
BigInteger factor = BigInteger.ONE;
if (jobs.compareTo(BigInteger.valueOf(0x7FFFFFFF)) > 0) {
factor = jobs.divide(BigInteger.valueOf(0x7FFFFFFF));
jobs = jobs.divide(factor);
}
monitor.beginTask(Messages.getString("Exporter.ProgressTitle"), jobs.intValue()); //$NON-NLS-1$
BigInteger jobCount = BigInteger.ZERO;
while (transferAddress.compareTo(fEndAddress) < 0 && !monitor.isCanceled()) {
BigInteger length = DATA_PER_RECORD;
if (fEndAddress.subtract(transferAddress).compareTo(length) < 0)
length = fEndAddress.subtract(transferAddress);
monitor.subTask(String.format(Messages.getString("Exporter.Progress"), length.toString(10), //$NON-NLS-1$
transferAddress.toString(16)));
// data
byte[] byteValues = new byte[length.intValue()];
MemoryByte bytes[] = ((IMemoryBlockExtension) fMemoryBlock).getBytesFromAddress(transferAddress,
length.longValue() / ((IMemoryBlockExtension) fMemoryBlock).getAddressableSize());
for (int byteIndex = 0; byteIndex < bytes.length; byteIndex++) {
byteValues[byteIndex] = bytes[byteIndex].getValue();
}
writer.write(byteValues);
transferAddress = transferAddress.add(length);
jobCount = jobCount.add(BigInteger.ONE);
if (jobCount.compareTo(factor) == 0) {
jobCount = BigInteger.ZERO;
monitor.worked(1);
}
}
writer.close();
monitor.done();
} catch (IOException ex) {
MemoryTransportPlugin.getDefault().getLog()
.log(new Status(IStatus.ERROR, MemoryTransportPlugin.getUniqueIdentifier(),
DebugException.REQUEST_FAILED, Messages.getString("Exporter.ErrFile"), ex)); //$NON-NLS-1$
return new Status(IStatus.ERROR, MemoryTransportPlugin.getUniqueIdentifier(),
DebugException.REQUEST_FAILED, Messages.getString("Exporter.ErrFile"), ex); //$NON-NLS-1$
} catch (DebugException ex) {
MemoryTransportPlugin.getDefault().getLog()
.log(new Status(IStatus.ERROR, MemoryTransportPlugin.getUniqueIdentifier(),
DebugException.REQUEST_FAILED, Messages.getString("Exporter.ErrReadTarget"), ex)); //$NON-NLS-1$
return new Status(IStatus.ERROR, MemoryTransportPlugin.getUniqueIdentifier(),
DebugException.REQUEST_FAILED, Messages.getString("Exporter.ErrReadTarget"), ex); //$NON-NLS-1$
} catch (Exception ex) {
MemoryTransportPlugin.getDefault().getLog()
.log(new Status(IStatus.ERROR, MemoryTransportPlugin.getUniqueIdentifier(),
DebugException.INTERNAL_ERROR, Messages.getString("Exporter.Falure"), ex)); //$NON-NLS-1$
return new Status(IStatus.ERROR, MemoryTransportPlugin.getUniqueIdentifier(),
DebugException.INTERNAL_ERROR, Messages.getString("Exporter.Falure"), ex); //$NON-NLS-1$
}
return Status.OK_STATUS;
}
};
job.setUser(true); job.setUser(true);
job.schedule(); job.schedule();
} }

View file

@ -16,19 +16,17 @@
package org.eclipse.cdt.debug.ui.memory.transport; package org.eclipse.cdt.debug.ui.memory.transport;
import java.io.File; import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.math.BigInteger; import java.math.BigInteger;
import org.eclipse.cdt.debug.core.memory.transport.ExportRequest;
import org.eclipse.cdt.debug.core.memory.transport.ReadMemory;
import org.eclipse.cdt.debug.internal.core.memory.transport.ReadMemoryBlock;
import org.eclipse.cdt.debug.internal.core.memory.transport.SRecordExport;
import org.eclipse.cdt.debug.internal.core.memory.transport.TransportJob;
import org.eclipse.cdt.debug.internal.ui.memory.transport.AddressableSize;
import org.eclipse.cdt.debug.ui.memory.transport.model.IMemoryExporter; import org.eclipse.cdt.debug.ui.memory.transport.model.IMemoryExporter;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.model.IMemoryBlock; import org.eclipse.debug.core.model.IMemoryBlock;
import org.eclipse.debug.core.model.IMemoryBlockExtension; import org.eclipse.debug.core.model.IMemoryBlockExtension;
import org.eclipse.debug.core.model.MemoryByte;
import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.swt.SWT; import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.events.KeyEvent;
@ -491,133 +489,11 @@ public class SRecordExporter implements IMemoryExporter {
@Override @Override
public void exportMemory() { public void exportMemory() {
Job job = new Job("Memory Export to S-Record File") { //$NON-NLS-1$ ReadMemory read = new ReadMemoryBlock((IMemoryBlockExtension) fMemoryBlock);
@Override BigInteger addressable = new AddressableSize((IMemoryBlockExtension) fMemoryBlock).get();
public IStatus run(IProgressMonitor monitor) { ExportRequest request = new ExportRequest(fStartAddress, fEndAddress, addressable, read);
try { SRecordExport memoryExport = new SRecordExport(fOutputFile, request);
// FIXME 4 byte default TransportJob job = new TransportJob("Memory Export to S-Record File", memoryExport);
BigInteger DATA_PER_RECORD = BigInteger.valueOf(16);
BigInteger DATA_PER_TRANSFER = BigInteger.valueOf(4096).multiply(DATA_PER_RECORD);
BigInteger transferAddress = fStartAddress;
FileWriter writer = new FileWriter(fOutputFile);
BigInteger jobs = fEndAddress.subtract(transferAddress).divide(DATA_PER_RECORD);
BigInteger factor = BigInteger.ONE;
if (jobs.compareTo(BigInteger.valueOf(0x7FFFFFFF)) > 0) {
factor = jobs.divide(BigInteger.valueOf(0x7FFFFFFF));
jobs = jobs.divide(factor);
}
monitor.beginTask(Messages.getString("Exporter.ProgressTitle"), jobs.intValue()); //$NON-NLS-1$
BigInteger jobCount = BigInteger.ZERO;
while (transferAddress.compareTo(fEndAddress) < 0 && !monitor.isCanceled()) {
BigInteger length = DATA_PER_TRANSFER;
if (fEndAddress.subtract(transferAddress).compareTo(length) < 0)
length = fEndAddress.subtract(transferAddress);
monitor.subTask(String.format(Messages.getString("Exporter.Progress"), length.toString(10), //$NON-NLS-1$
transferAddress.toString(16)));
MemoryByte bytes[] = ((IMemoryBlockExtension) fMemoryBlock).getBytesFromAddress(transferAddress,
length.longValue() / ((IMemoryBlockExtension) fMemoryBlock).getAddressableSize());
BigInteger sRecordAddress = transferAddress;
BigInteger sRecordEndAddress = transferAddress.add(length);
while (sRecordAddress.compareTo(sRecordEndAddress) < 0 && !monitor.isCanceled()) {
BigInteger sRecordDataLength = DATA_PER_RECORD;
if (sRecordEndAddress.subtract(sRecordAddress).compareTo(sRecordDataLength) < 0) {
sRecordDataLength = fEndAddress.subtract(sRecordAddress);
}
writer.write("S3"); // FIXME 4 byte address //$NON-NLS-1$
StringBuilder buf = new StringBuilder();
BigInteger sRecordLength = BigInteger.valueOf(4); // address size
sRecordLength = sRecordLength.add(sRecordDataLength);
sRecordLength = sRecordLength.add(BigInteger.ONE); // checksum
String transferAddressString = sRecordAddress.toString(16);
String lengthString = sRecordLength.toString(16);
if (lengthString.length() == 1)
buf.append("0"); //$NON-NLS-1$
buf.append(lengthString);
for (int i = 0; i < 8 - transferAddressString.length(); i++)
buf.append("0"); //$NON-NLS-1$
buf.append(transferAddressString);
final int byteOffset = sRecordAddress.subtract(transferAddress).intValue();
final int byteLength = byteOffset + sRecordDataLength.intValue();
for (int byteIndex = byteOffset; byteIndex < byteLength; byteIndex++) {
String bString = BigInteger.valueOf(0xFF & bytes[byteIndex].getValue()).toString(16);
if (bString.length() == 1)
buf.append("0"); //$NON-NLS-1$
buf.append(bString);
}
/*
* The least significant byte of the one's complement of the sum of the values
* represented by the pairs of characters making up the records length, address,
* and the code/data fields.
*/
byte checksum = 0;
for (int i = 0; i < buf.length(); i += 2) {
BigInteger value = new BigInteger(buf.substring(i, i + 2), 16);
checksum += value.byteValue();
}
String bString = BigInteger.valueOf(0xFF - checksum).and(BigInteger.valueOf(0xFF))
.toString(16);
if (bString.length() == 1)
buf.append("0"); //$NON-NLS-1$
buf.append(bString);
writer.write(buf.toString().toUpperCase());
writer.write("\n"); //$NON-NLS-1$
sRecordAddress = sRecordAddress.add(sRecordDataLength);
jobCount = jobCount.add(BigInteger.ONE);
if (jobCount.compareTo(factor) == 0) {
jobCount = BigInteger.ZERO;
monitor.worked(1);
}
}
transferAddress = transferAddress.add(length);
}
writer.close();
monitor.done();
} catch (IOException ex) {
MemoryTransportPlugin.getDefault().getLog()
.log(new Status(IStatus.ERROR, MemoryTransportPlugin.getUniqueIdentifier(),
DebugException.REQUEST_FAILED, Messages.getString("Exporter.ErrFile"), ex)); //$NON-NLS-1$
return new Status(IStatus.ERROR, MemoryTransportPlugin.getUniqueIdentifier(),
DebugException.REQUEST_FAILED, Messages.getString("Exporter.ErrFile"), ex); //$NON-NLS-1$
} catch (DebugException ex) {
MemoryTransportPlugin.getDefault().getLog()
.log(new Status(IStatus.ERROR, MemoryTransportPlugin.getUniqueIdentifier(),
DebugException.REQUEST_FAILED, Messages.getString("Exporter.ErrReadTarget"), ex)); //$NON-NLS-1$
return new Status(IStatus.ERROR, MemoryTransportPlugin.getUniqueIdentifier(),
DebugException.REQUEST_FAILED, Messages.getString("Exporter.ErrReadTarget"), ex); //$NON-NLS-1$
} catch (Exception ex) {
MemoryTransportPlugin.getDefault().getLog()
.log(new Status(IStatus.ERROR, MemoryTransportPlugin.getUniqueIdentifier(),
DebugException.INTERNAL_ERROR, Messages.getString("Exporter.Falure"), ex)); //$NON-NLS-1$
return new Status(IStatus.ERROR, MemoryTransportPlugin.getUniqueIdentifier(),
DebugException.INTERNAL_ERROR, Messages.getString("Exporter.Falure"), ex); //$NON-NLS-1$
}
return Status.OK_STATUS;
}
};
job.setUser(true); job.setUser(true);
job.schedule(); job.schedule();
} }

View file

@ -23,16 +23,10 @@ ImportMemoryDialog.Title=Import Memory
Exporter.AllFiles=All Files Exporter.AllFiles=All Files
Exporter.Browse=Browse... Exporter.Browse=Browse...
Exporter.ErrFile=Could not write to file.
Exporter.ErrReadTarget=Could not read from target.
Exporter.Falure=Failure exporting memory
Exporter.FileName=File name:\u0020 Exporter.FileName=File name:\u0020
Exporter.Progress=Transferring %s bytes at address 0x%s
Exporter.ProgressTitle=Transferring Data
Importer.AllFiles=All Files Importer.AllFiles=All Files
Importer.Browse=Browse... Importer.Browse=Browse...
Importer.FalureImporting=Failure importing from file
Importer.File=File name:\u0020 Importer.File=File name:\u0020
PlainTextExporter.ChooseFile=Choose memory export file PlainTextExporter.ChooseFile=Choose memory export file