mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-16 05:25:21 +02:00
Bug 562164 - Add JUnit tests for IMemoryImporter implementations
The following changes are done to make the implementation headless and testable: * Reworked FileImport to implement base flow * Added ImportRequest to aggregate operation configuration * Extracted PlainTextImport extends FileImport * Extracted RawBinaryImport extends FileImport * Extracted SRecordImport extends FileImport * Extracted FileImportJob * Added ScrollMemory to interact with UI * Added WriteMemoryBlock to isolate from UI class BufferedMemoryWriter * Reworked related i18n Change-Id: Ibd68c0e345e9455f5f8a2e1be673ddac5eb9a9b1 Signed-off-by: Alexander Fedorov <alexander.fedorov@arsysop.ru>
This commit is contained in:
parent
d4082abb67
commit
a92105a031
18 changed files with 767 additions and 407 deletions
|
@ -210,6 +210,7 @@ Java and all Java-based trademarks are trademarks of Oracle Corporation in the U
|
|||
<plugin id="org.eclipse.cdt.debug.application"/>
|
||||
<plugin id="org.eclipse.cdt.debug.application.doc"/>
|
||||
<plugin id="org.eclipse.cdt.debug.core"/>
|
||||
<plugin id="org.eclipse.cdt.debug.core.memory"/>
|
||||
<plugin id="org.eclipse.cdt.debug.ui"/>
|
||||
<plugin id="org.eclipse.cdt.debug.ui.memory.floatingpoint"/>
|
||||
<plugin id="org.eclipse.cdt.debug.ui.memory.memorybrowser"/>
|
||||
|
|
|
@ -6,6 +6,8 @@ Bundle-Version: 0.1.0.qualifier
|
|||
Bundle-Name: %Bundle-Name
|
||||
Bundle-Vendor: %Bundle-Vendor
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
|
||||
Require-Bundle: org.eclipse.cdt.debug.core;bundle-version="8.4.100",
|
||||
org.eclipse.core.runtime;bundle-version="3.17.200"
|
||||
Export-Package: org.eclipse.cdt.debug.core.memory.transport;x-friends:="org.eclipse.cdt.debug.ui.memory.transport"
|
||||
Require-Bundle: org.eclipse.core.runtime;bundle-version="3.17.0",
|
||||
org.eclipse.debug.core;bundle-version="3.15.0",
|
||||
org.eclipse.equinox.common;bundle-version="3.11.0"
|
||||
Export-Package: org.eclipse.cdt.debug.core.memory.transport;x-friends:="org.eclipse.cdt.debug.ui.memory.transport",
|
||||
org.eclipse.cdt.debug.internal.core.memory.transport;x-friends:="org.eclipse.cdt.debug.ui.memory.transport"
|
||||
|
|
|
@ -0,0 +1,108 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2020 ArSysOp 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:
|
||||
* Alexander Fedorov (ArSysOp) - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.debug.core.memory.transport;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
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.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;
|
||||
|
||||
/**
|
||||
* Imports memory information from a given file
|
||||
*
|
||||
* @since 0.1
|
||||
*/
|
||||
public abstract class FileImport<I extends AutoCloseable> implements ICoreRunnable {
|
||||
|
||||
protected final BigInteger base;
|
||||
protected final BigInteger start;
|
||||
protected final WriteMemory write;
|
||||
protected final Consumer<BigInteger> scroll;
|
||||
|
||||
private final File inputFile;
|
||||
|
||||
protected FileImport(File input, ImportRequest request, Consumer<BigInteger> scroll) {
|
||||
this.inputFile = input;
|
||||
this.base = request.base();
|
||||
this.start = request.start();
|
||||
this.write = request.write();
|
||||
this.scroll = scroll;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(IProgressMonitor monitor) throws CoreException {
|
||||
try (I reader = input(inputFile)) {
|
||||
BigInteger jobs = BigInteger.valueOf(inputFile.length());
|
||||
BigInteger factor = BigInteger.ONE;
|
||||
if (jobs.compareTo(BigInteger.valueOf(0x7FFFFFFF)) > 0) {
|
||||
factor = jobs.divide(BigInteger.valueOf(0x7FFFFFFF));
|
||||
jobs = jobs.divide(factor);
|
||||
}
|
||||
monitor.beginTask(Messages.FileImport_task_transferring, jobs.intValue());
|
||||
transfer(monitor, reader, factor);
|
||||
if (!monitor.isCanceled()) {
|
||||
write.flush();
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
requestFailed(Messages.FileImport_e_read_from_file, ex);
|
||||
} catch (DebugException ex) {
|
||||
requestFailed(Messages.FileImport_e_write_to_target, ex);
|
||||
} catch (CoreException ex) {
|
||||
failed(ex);
|
||||
} catch (Exception ex) {
|
||||
internalError(Messages.FileImport_e_import_from_file, ex);
|
||||
} finally {
|
||||
monitor.done();
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract I input(File file) throws FileNotFoundException;
|
||||
|
||||
protected abstract void transfer(IProgressMonitor monitor, I input, BigInteger factor)
|
||||
throws IOException, CoreException, DebugException;
|
||||
|
||||
protected void requestFailed(String message, Throwable exception) throws CoreException {
|
||||
failed(DebugException.REQUEST_FAILED, message, exception);
|
||||
}
|
||||
|
||||
protected void internalError(String message, Throwable exception) throws CoreException {
|
||||
failed(DebugException.INTERNAL_ERROR, message, exception);
|
||||
}
|
||||
|
||||
protected void failed(int code, String message, Throwable exception) throws CoreException {
|
||||
Status status = new Status(//
|
||||
IStatus.ERROR, //
|
||||
FrameworkUtil.getBundle(getClass()).getSymbolicName(), //
|
||||
code, //
|
||||
message, //
|
||||
exception);
|
||||
failed(new CoreException(status));
|
||||
}
|
||||
|
||||
protected void failed(CoreException exception) throws CoreException {
|
||||
Platform.getLog(FrameworkUtil.getBundle(getClass())).log(exception.getStatus());
|
||||
throw exception;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2020 ArSysOp 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:
|
||||
* Alexander Fedorov (ArSysOp) - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.debug.core.memory.transport;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
/**
|
||||
*
|
||||
* Aggregates memory import configuration
|
||||
*
|
||||
* @since 0.1
|
||||
*
|
||||
*/
|
||||
public class ImportRequest {
|
||||
|
||||
private final BigInteger base;
|
||||
private final BigInteger start;
|
||||
private final WriteMemory write;
|
||||
|
||||
public ImportRequest(BigInteger base, BigInteger start, WriteMemory write) {
|
||||
this.base = base;
|
||||
this.start = start;
|
||||
this.write = write;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return base memory address
|
||||
*/
|
||||
public BigInteger base() {
|
||||
return base;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return starting offset
|
||||
*/
|
||||
public BigInteger start() {
|
||||
return start;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return writer
|
||||
*/
|
||||
public WriteMemory write() {
|
||||
return write;
|
||||
}
|
||||
}
|
|
@ -13,15 +13,30 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.cdt.debug.core.memory.transport;
|
||||
|
||||
import org.eclipse.core.runtime.ICoreRunnable;
|
||||
import java.math.BigInteger;
|
||||
|
||||
import org.eclipse.debug.core.DebugException;
|
||||
|
||||
/**
|
||||
* Imports memory information from a given source
|
||||
* Writes an array of bytes using the given offset
|
||||
*
|
||||
* @since 0.1
|
||||
*/
|
||||
public abstract class MemoryImport implements ICoreRunnable {
|
||||
/* WIP: here we will place basic logic to read the data and notify consumer interactively
|
||||
private final Consumer<BigInteger> scroll;
|
||||
*/
|
||||
public interface WriteMemory {
|
||||
|
||||
/**
|
||||
* Writes the given data to a memory starting from the given offset. Actual write may be delayed until the nearest {@link WriteMemory#flush()} call
|
||||
*
|
||||
* @param offset
|
||||
* @param data
|
||||
* @throws DebugException
|
||||
*/
|
||||
void to(BigInteger offset, byte[] data) throws DebugException;
|
||||
|
||||
/**
|
||||
* Forces data write to a memory.
|
||||
*
|
||||
* @throws DebugException
|
||||
*/
|
||||
void flush() throws DebugException;
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2020 ArSysOp 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:
|
||||
* Alexander Fedorov (ArSysOp) - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.debug.internal.core.memory.transport;
|
||||
|
||||
import org.eclipse.cdt.debug.core.memory.transport.FileImport;
|
||||
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.core.runtime.jobs.Job;
|
||||
|
||||
/**
|
||||
* Runs {@link FileImport} operation as a {@link Job}
|
||||
*
|
||||
*/
|
||||
public final class FileImportJob extends Job {
|
||||
|
||||
private final FileImport<?> fileImport;
|
||||
|
||||
public FileImportJob(String name, FileImport<?> fileImport) {
|
||||
super(name);
|
||||
this.fileImport = fileImport;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IStatus run(IProgressMonitor monitor) {
|
||||
try {
|
||||
fileImport.run(monitor);
|
||||
} catch (CoreException e) {
|
||||
return e.getStatus();
|
||||
}
|
||||
return Status.OK_STATUS;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2020 ArSysOp 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:
|
||||
* Alexander Fedorov (ArSysOp) - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.debug.internal.core.memory.transport;
|
||||
|
||||
import org.eclipse.osgi.util.NLS;
|
||||
|
||||
public class Messages extends NLS {
|
||||
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 FileImport_e_read_from_file;
|
||||
public static String FileImport_e_write_to_target;
|
||||
public static String FileImport_task_transferring;
|
||||
public static String PlainTextImport_e_invalid_format;
|
||||
public static String SRecordImport_e_checksum_failure;
|
||||
public static String SRecordImport_e_invalid_address;
|
||||
public static String SRecordImport_e_invalid_checksum_format;
|
||||
public static String SRecordImport_e_invalid_data;
|
||||
public static String SRecordImport_e_invalid_line_length;
|
||||
static {
|
||||
// initialize resource bundle
|
||||
NLS.initializeMessages(BUNDLE_NAME, Messages.class);
|
||||
}
|
||||
|
||||
private Messages() {
|
||||
}
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
/*******************************************************************************
|
||||
* 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.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.math.BigInteger;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.eclipse.cdt.debug.core.memory.transport.FileImport;
|
||||
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.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.debug.core.DebugException;
|
||||
import org.osgi.framework.FrameworkUtil;
|
||||
|
||||
public final class PlainTextImport extends FileImport<BufferedReader> {
|
||||
|
||||
public PlainTextImport(File input, ImportRequest request, Consumer<BigInteger> scroll) {
|
||||
super(input, request, scroll);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BufferedReader input(File file) throws FileNotFoundException {
|
||||
return new BufferedReader(new InputStreamReader(new FileInputStream(file)));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void transfer(IProgressMonitor monitor, BufferedReader reader, BigInteger factor)
|
||||
throws IOException, CoreException, DebugException {
|
||||
BigInteger recordAddress = start;
|
||||
String line = reader.readLine();
|
||||
int lineNo = 1; // line error reporting
|
||||
while (line != null && !monitor.isCanceled()) {
|
||||
StringTokenizer st = new StringTokenizer(line, " "); //$NON-NLS-1$
|
||||
int bytesRead = 0;
|
||||
while (st.hasMoreElements()) {
|
||||
String valueString = (String) st.nextElement();
|
||||
int position = 0;
|
||||
byte data[] = new byte[valueString.length() / 2];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
try {
|
||||
data[i] = new BigInteger(valueString.substring(position++, position++ + 1), 16).byteValue();
|
||||
} catch (NumberFormatException ex) {
|
||||
throw new CoreException(new Status(IStatus.ERROR,
|
||||
FrameworkUtil.getBundle(getClass()).getSymbolicName(), DebugException.REQUEST_FAILED,
|
||||
String.format(Messages.PlainTextImport_e_invalid_format, lineNo), ex));
|
||||
}
|
||||
}
|
||||
BigInteger writeAddress = recordAddress.subtract(base).add(BigInteger.valueOf(bytesRead));
|
||||
write.to(writeAddress, data);
|
||||
bytesRead += data.length;
|
||||
}
|
||||
recordAddress = recordAddress.add(BigInteger.valueOf(bytesRead));
|
||||
scroll.accept(recordAddress);
|
||||
BigInteger jobCount = BigInteger.valueOf(bytesRead).divide(factor);
|
||||
monitor.worked(jobCount.intValue());
|
||||
line = reader.readLine();
|
||||
lineNo++;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
/*******************************************************************************
|
||||
* 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.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.eclipse.cdt.debug.core.memory.transport.FileImport;
|
||||
import org.eclipse.cdt.debug.core.memory.transport.ImportRequest;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.debug.core.DebugException;
|
||||
|
||||
public final class RAWBinaryImport extends FileImport<FileInputStream> {
|
||||
|
||||
public RAWBinaryImport(File input, ImportRequest request, Consumer<BigInteger> scroll) {
|
||||
super(input, request, scroll);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected FileInputStream input(File file) throws FileNotFoundException {
|
||||
return new FileInputStream(file);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void transfer(IProgressMonitor monitor, FileInputStream input, BigInteger factor)
|
||||
throws IOException, CoreException, DebugException {
|
||||
byte[] byteValues = new byte[1024];
|
||||
int actualByteCount = input.read(byteValues);
|
||||
BigInteger recordAddress = start;
|
||||
while (actualByteCount != -1 && !monitor.isCanceled()) {
|
||||
byte data[] = new byte[actualByteCount];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
data[i] = byteValues[i];
|
||||
}
|
||||
write.to(recordAddress.subtract(base), data);
|
||||
BigInteger jobCount = BigInteger.valueOf(actualByteCount).divide(factor);
|
||||
monitor.worked(jobCount.intValue());
|
||||
recordAddress = recordAddress.add(BigInteger.valueOf(actualByteCount));
|
||||
scroll.accept(recordAddress);
|
||||
actualByteCount = input.read(byteValues);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,148 @@
|
|||
/*******************************************************************************
|
||||
* 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.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.math.BigInteger;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.eclipse.cdt.debug.core.memory.transport.FileImport;
|
||||
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.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.debug.core.DebugException;
|
||||
import org.osgi.framework.FrameworkUtil;
|
||||
|
||||
public class SRecordImport extends FileImport<BufferedReader> {
|
||||
|
||||
private final boolean transfer;
|
||||
|
||||
public SRecordImport(File input, ImportRequest request, Consumer<BigInteger> scroll, boolean transfer) {
|
||||
super(input, request, scroll);
|
||||
this.transfer = transfer;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BufferedReader input(File file) throws FileNotFoundException {
|
||||
return new BufferedReader(new InputStreamReader(new FileInputStream(file)));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void transfer(IProgressMonitor monitor, BufferedReader reader, BigInteger factor)
|
||||
throws IOException, CoreException, DebugException {
|
||||
// FIXME 4 byte default
|
||||
final int CHECKSUM_LENGTH = 1;
|
||||
BigInteger offset = null;
|
||||
if (!transfer) {
|
||||
offset = BigInteger.ZERO;
|
||||
}
|
||||
String line = reader.readLine();
|
||||
int lineNo = 1; // line error reporting
|
||||
while (line != null && !monitor.isCanceled()) {
|
||||
String recordType = line.substring(0, 2);
|
||||
int recordCount = 0;
|
||||
try {
|
||||
recordCount = Integer.parseInt(line.substring(2, 4), 16);
|
||||
} catch (NumberFormatException ex) {
|
||||
throw new CoreException(new Status(IStatus.ERROR, FrameworkUtil.getBundle(getClass()).getSymbolicName(),
|
||||
DebugException.REQUEST_FAILED,
|
||||
String.format(Messages.SRecordImport_e_invalid_line_length, lineNo), ex));
|
||||
}
|
||||
int bytesRead = 4 + recordCount;
|
||||
int position = 4;
|
||||
int addressSize = 0;
|
||||
BigInteger recordAddress = null;
|
||||
if ("S3".equals(recordType)) //$NON-NLS-1$
|
||||
addressSize = 4;
|
||||
else if ("S1".equals(recordType)) //$NON-NLS-1$
|
||||
addressSize = 2;
|
||||
else if ("S2".equals(recordType)) //$NON-NLS-1$
|
||||
addressSize = 3;
|
||||
else if ("S0".equals(recordType) || "S5".equals(recordType) || "S7".equals(recordType) //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||
|| "S8".equals(recordType) || "S9".equals(recordType)) //$NON-NLS-1$ //$NON-NLS-2$
|
||||
{ // ignore S0, S5, S7, S8 and S9 records
|
||||
line = reader.readLine();
|
||||
lineNo++;
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
recordAddress = new BigInteger(line.substring(position, position + addressSize * 2), 16);
|
||||
} catch (NumberFormatException ex) {
|
||||
throw new CoreException(new Status(IStatus.ERROR, FrameworkUtil.getBundle(getClass()).getSymbolicName(),
|
||||
DebugException.REQUEST_FAILED, String.format(Messages.SRecordImport_e_invalid_address, lineNo),
|
||||
ex));
|
||||
}
|
||||
recordCount -= addressSize;
|
||||
position += addressSize * 2;
|
||||
if (offset == null) {
|
||||
offset = start.subtract(recordAddress);
|
||||
}
|
||||
recordAddress = recordAddress.add(offset);
|
||||
byte data[] = new byte[recordCount - CHECKSUM_LENGTH];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
try {
|
||||
data[i] = new BigInteger(line.substring(position++, position++ + 1), 16).byteValue();
|
||||
} catch (NumberFormatException ex) {
|
||||
throw new CoreException(new Status(IStatus.ERROR,
|
||||
FrameworkUtil.getBundle(getClass()).getSymbolicName(), DebugException.REQUEST_FAILED,
|
||||
String.format(Messages.SRecordImport_e_invalid_data, lineNo), ex));
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
StringBuilder buf = new StringBuilder(line.substring(2));
|
||||
byte checksum = 0;
|
||||
for (int i = 0; i < buf.length(); i += 2) {
|
||||
BigInteger value = null;
|
||||
try {
|
||||
value = new BigInteger(buf.substring(i, i + 2), 16);
|
||||
} catch (NumberFormatException ex) {
|
||||
throw new CoreException(new Status(IStatus.ERROR,
|
||||
FrameworkUtil.getBundle(getClass()).getSymbolicName(), DebugException.REQUEST_FAILED,
|
||||
String.format(Messages.SRecordImport_e_invalid_checksum_format, lineNo), ex));
|
||||
}
|
||||
checksum += value.byteValue();
|
||||
}
|
||||
/*
|
||||
* Since we included the checksum in the checksum calculation the checksum
|
||||
* ( if correct ) will always be 0xFF which is -1 using the signed byte size
|
||||
* calculation here.
|
||||
*/
|
||||
if (checksum != (byte) -1) {
|
||||
monitor.done();
|
||||
throw new CoreException(new Status(IStatus.ERROR, FrameworkUtil.getBundle(getClass()).getSymbolicName(),
|
||||
String.format(Messages.SRecordImport_e_checksum_failure, line)));
|
||||
}
|
||||
scroll.accept(recordAddress);
|
||||
// FIXME error on incorrect checksum
|
||||
write.to(recordAddress.subtract(base), data);
|
||||
BigInteger jobCount = BigInteger.valueOf(bytesRead).divide(factor);
|
||||
monitor.worked(jobCount.intValue());
|
||||
line = reader.readLine();
|
||||
lineNo++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
###############################################################################
|
||||
# Copyright (c) 2020 ArSysOp 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:
|
||||
# Alexander Fedorov (ArSysOp) - initial API and implementation
|
||||
###############################################################################
|
||||
|
||||
FileImport_e_import_from_file=Failure importing from file
|
||||
FileImport_e_read_from_file=Could not read from file.
|
||||
FileImport_e_write_to_target=Could not write to target.
|
||||
FileImport_task_transferring=Transferring Data
|
||||
PlainTextImport_e_invalid_format=Invalid file format. Expected integer at line %d
|
||||
SRecordImport_e_checksum_failure=Checksum failure of line = %d
|
||||
SRecordImport_e_invalid_address=Invalid file format. Invalid address at line %d
|
||||
SRecordImport_e_invalid_checksum_format=Invalid file format. Invalid checksum format at line %d
|
||||
SRecordImport_e_invalid_data=Invalid file format. Invalid data at line %d
|
||||
SRecordImport_e_invalid_line_length=Invalid file format. Invalid line length at line %d
|
|
@ -5,7 +5,8 @@ Bundle-SymbolicName: org.eclipse.cdt.debug.ui.memory.transport;singleton:=true
|
|||
Bundle-Version: 2.1.200.qualifier
|
||||
Bundle-Localization: plugin
|
||||
Bundle-Vendor: %providerName
|
||||
Require-Bundle: org.eclipse.debug.core,
|
||||
Require-Bundle: org.eclipse.cdt.debug.core.memory;bundle-version="0.1.0",
|
||||
org.eclipse.debug.core,
|
||||
org.eclipse.debug.ui,
|
||||
org.eclipse.core.runtime,
|
||||
org.eclipse.swt,
|
||||
|
@ -14,7 +15,8 @@ Require-Bundle: org.eclipse.debug.core,
|
|||
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Bundle-Activator: org.eclipse.cdt.debug.ui.memory.transport.MemoryTransportPlugin
|
||||
Export-Package: org.eclipse.cdt.debug.ui.memory.transport,
|
||||
Export-Package: org.eclipse.cdt.debug.internal.ui.memory.transport;x-internal:=true,
|
||||
org.eclipse.cdt.debug.ui.memory.transport,
|
||||
org.eclipse.cdt.debug.ui.memory.transport.actions,
|
||||
org.eclipse.cdt.debug.ui.memory.transport.model
|
||||
Automatic-Module-Name: org.eclipse.cdt.debug.ui.memory.transport
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2020 ArSysOp 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:
|
||||
* Alexander Fedorov (ArSysOp) - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.debug.internal.ui.memory.transport;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.eclipse.cdt.debug.ui.memory.transport.ImportMemoryDialog;
|
||||
|
||||
public final class ScrollMemory implements Consumer<BigInteger> {
|
||||
|
||||
private final ImportMemoryDialog dialog;
|
||||
|
||||
public ScrollMemory(ImportMemoryDialog dialog) {
|
||||
this.dialog = dialog;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(BigInteger address) {
|
||||
dialog.scrollRenderings(address);
|
||||
}
|
||||
|
||||
public static class Ignore implements Consumer<BigInteger> {
|
||||
|
||||
@Override
|
||||
public void accept(BigInteger t) {
|
||||
//ignore
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2020 ArSysOp 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:
|
||||
* Alexander Fedorov (ArSysOp) - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.debug.internal.ui.memory.transport;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
import org.eclipse.cdt.debug.core.memory.transport.WriteMemory;
|
||||
import org.eclipse.cdt.debug.ui.memory.transport.BufferedMemoryWriter;
|
||||
import org.eclipse.debug.core.DebugException;
|
||||
import org.eclipse.debug.core.model.IMemoryBlockExtension;
|
||||
|
||||
/**
|
||||
* Writes to a given {@link IMemoryBlockExtension} using {@link BufferedMemoryWriter}
|
||||
*
|
||||
*
|
||||
*/
|
||||
public final class WriteMemoryBlock implements WriteMemory {
|
||||
|
||||
private final BufferedMemoryWriter writer;
|
||||
private final int capacity = 64 * 1024;
|
||||
|
||||
public WriteMemoryBlock(IMemoryBlockExtension block) {
|
||||
this.writer = new BufferedMemoryWriter(block, capacity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void to(BigInteger offset, byte[] data) throws DebugException {
|
||||
writer.write(offset, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() throws DebugException {
|
||||
writer.flush();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006, 2013 Wind River Systems, Inc. and others.
|
||||
* 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
|
||||
|
@ -10,26 +10,25 @@
|
|||
*
|
||||
* 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.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.math.BigInteger;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.eclipse.cdt.debug.core.memory.transport.ImportRequest;
|
||||
import org.eclipse.cdt.debug.internal.core.memory.transport.FileImportJob;
|
||||
import org.eclipse.cdt.debug.internal.core.memory.transport.PlainTextImport;
|
||||
import org.eclipse.cdt.debug.internal.ui.memory.transport.ScrollMemory;
|
||||
import org.eclipse.cdt.debug.internal.ui.memory.transport.WriteMemoryBlock;
|
||||
import org.eclipse.cdt.debug.ui.memory.transport.model.IMemoryImporter;
|
||||
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.IMemoryBlockExtension;
|
||||
import org.eclipse.jface.dialogs.ErrorDialog;
|
||||
import org.eclipse.jface.dialogs.IDialogSettings;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.events.ModifyEvent;
|
||||
|
@ -64,8 +63,6 @@ public class PlainTextImporter implements IMemoryImporter {
|
|||
|
||||
private IDialogSettings fProperties;
|
||||
|
||||
private static final int BUFFER_LENGTH = 64 * 1024;
|
||||
|
||||
@Override
|
||||
public Control createControl(final Composite parent, IMemoryBlock memBlock, IDialogSettings properties,
|
||||
ImportMemoryDialog parentDialog) {
|
||||
|
@ -267,104 +264,22 @@ public class PlainTextImporter implements IMemoryImporter {
|
|||
|
||||
@Override
|
||||
public void importMemory() {
|
||||
Job job = new Job("Memory Import from Plain Text File") { //$NON-NLS-1$
|
||||
|
||||
@Override
|
||||
public IStatus run(IProgressMonitor monitor) {
|
||||
try {
|
||||
BufferedMemoryWriter memoryWriter = new BufferedMemoryWriter((IMemoryBlockExtension) fMemoryBlock,
|
||||
BUFFER_LENGTH);
|
||||
|
||||
BigInteger scrollToAddress = null;
|
||||
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(fInputFile)));
|
||||
|
||||
BigInteger jobs = BigInteger.valueOf(fInputFile.length());
|
||||
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("Importer.ProgressTitle"), jobs.intValue()); //$NON-NLS-1$
|
||||
|
||||
BigInteger recordAddress = fStartAddress;
|
||||
String line = reader.readLine();
|
||||
int lineNo = 1; // line error reporting
|
||||
while (line != null && !monitor.isCanceled()) {
|
||||
StringTokenizer st = new StringTokenizer(line, " "); //$NON-NLS-1$
|
||||
int bytesRead = 0;
|
||||
while (st.hasMoreElements()) {
|
||||
String valueString = (String) st.nextElement();
|
||||
int position = 0;
|
||||
byte data[] = new byte[valueString.length() / 2];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
try {
|
||||
data[i] = new BigInteger(valueString.substring(position++, position++ + 1), 16)
|
||||
.byteValue();
|
||||
} catch (NumberFormatException ex) {
|
||||
return new Status(IStatus.ERROR, MemoryTransportPlugin.getUniqueIdentifier(),
|
||||
DebugException.REQUEST_FAILED,
|
||||
String.format(Messages.getString("PlainTextImporter.ErrInvalidFormat"), //$NON-NLS-1$
|
||||
lineNo),
|
||||
ex);
|
||||
}
|
||||
}
|
||||
|
||||
if (scrollToAddress == null)
|
||||
scrollToAddress = recordAddress;
|
||||
|
||||
BigInteger writeAddress =
|
||||
|
||||
recordAddress.subtract(((IMemoryBlockExtension) fMemoryBlock).getBigBaseAddress())
|
||||
.add(BigInteger.valueOf(bytesRead));
|
||||
|
||||
memoryWriter.write(writeAddress, data);
|
||||
|
||||
bytesRead += data.length;
|
||||
}
|
||||
|
||||
recordAddress = recordAddress.add(BigInteger.valueOf(bytesRead));
|
||||
|
||||
BigInteger jobCount = BigInteger.valueOf(bytesRead).divide(factor);
|
||||
monitor.worked(jobCount.intValue());
|
||||
|
||||
line = reader.readLine();
|
||||
lineNo++;
|
||||
}
|
||||
|
||||
if (!monitor.isCanceled())
|
||||
memoryWriter.flush();
|
||||
|
||||
reader.close();
|
||||
monitor.done();
|
||||
|
||||
if (fScrollToStart)
|
||||
fParentDialog.scrollRenderings(scrollToAddress);
|
||||
} catch (IOException ex) {
|
||||
MemoryTransportPlugin.getDefault().getLog()
|
||||
.log(new Status(IStatus.ERROR, MemoryTransportPlugin.getUniqueIdentifier(),
|
||||
DebugException.REQUEST_FAILED, Messages.getString("Importer.ErrReadFile"), ex)); //$NON-NLS-1$
|
||||
return new Status(IStatus.ERROR, MemoryTransportPlugin.getUniqueIdentifier(),
|
||||
DebugException.REQUEST_FAILED, Messages.getString("Importer.ErrReadFile"), ex); //$NON-NLS-1$
|
||||
|
||||
} catch (DebugException ex) {
|
||||
MemoryTransportPlugin.getDefault().getLog()
|
||||
.log(new Status(IStatus.ERROR, MemoryTransportPlugin.getUniqueIdentifier(),
|
||||
DebugException.REQUEST_FAILED, Messages.getString("Importer.ErrWriteTarget"), ex)); //$NON-NLS-1$
|
||||
return new Status(IStatus.ERROR, MemoryTransportPlugin.getUniqueIdentifier(),
|
||||
DebugException.REQUEST_FAILED, Messages.getString("Importer.ErrWriteTarget"), ex); //$NON-NLS-1$
|
||||
} catch (Exception ex) {
|
||||
MemoryTransportPlugin.getDefault().getLog()
|
||||
.log(new Status(IStatus.ERROR, MemoryTransportPlugin.getUniqueIdentifier(),
|
||||
DebugException.INTERNAL_ERROR, Messages.getString("Importer.FalureImporting"), ex)); //$NON-NLS-1$
|
||||
return new Status(IStatus.ERROR, MemoryTransportPlugin.getUniqueIdentifier(),
|
||||
DebugException.INTERNAL_ERROR, Messages.getString("Importer.FalureImporting"), ex); //$NON-NLS-1$
|
||||
}
|
||||
return Status.OK_STATUS;
|
||||
}
|
||||
};
|
||||
job.setUser(true);
|
||||
job.schedule();
|
||||
try {
|
||||
Consumer<BigInteger> scroll = fScrollToStart ? new ScrollMemory(fParentDialog) : new ScrollMemory.Ignore();
|
||||
IMemoryBlockExtension block = (IMemoryBlockExtension) fMemoryBlock;
|
||||
ImportRequest request = new ImportRequest(block.getBigBaseAddress(), fStartAddress,
|
||||
new WriteMemoryBlock(block));
|
||||
PlainTextImport memoryImport = new PlainTextImport(fInputFile, request, scroll);
|
||||
FileImportJob job = new FileImportJob(//
|
||||
"Memory Import from Plain Text File", memoryImport);
|
||||
job.setUser(true);
|
||||
job.schedule();
|
||||
} catch (DebugException e) {
|
||||
//FIXME: unreachable with current implementation, to be i18n after UI rework
|
||||
ErrorDialog.openError(fParentDialog.getShell(), //
|
||||
"Import Failure", //
|
||||
"Failed to retrieve base memory address", //
|
||||
e.getStatus());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006, 2013 Wind River Systems, Inc. and others.
|
||||
* 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
|
||||
|
@ -10,23 +10,25 @@
|
|||
*
|
||||
* 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.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.eclipse.cdt.debug.core.memory.transport.ImportRequest;
|
||||
import org.eclipse.cdt.debug.internal.core.memory.transport.FileImportJob;
|
||||
import org.eclipse.cdt.debug.internal.core.memory.transport.RAWBinaryImport;
|
||||
import org.eclipse.cdt.debug.internal.ui.memory.transport.ScrollMemory;
|
||||
import org.eclipse.cdt.debug.internal.ui.memory.transport.WriteMemoryBlock;
|
||||
import org.eclipse.cdt.debug.ui.memory.transport.model.IMemoryImporter;
|
||||
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.IMemoryBlockExtension;
|
||||
import org.eclipse.jface.dialogs.ErrorDialog;
|
||||
import org.eclipse.jface.dialogs.IDialogSettings;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.events.ModifyEvent;
|
||||
|
@ -61,8 +63,6 @@ public class RAWBinaryImporter implements IMemoryImporter {
|
|||
|
||||
private IDialogSettings fProperties;
|
||||
|
||||
private static final int BUFFER_LENGTH = 64 * 1024;
|
||||
|
||||
@Override
|
||||
public Control createControl(final Composite parent, IMemoryBlock memBlock, IDialogSettings properties,
|
||||
ImportMemoryDialog parentDialog) {
|
||||
|
@ -247,89 +247,23 @@ public class RAWBinaryImporter implements IMemoryImporter {
|
|||
|
||||
@Override
|
||||
public void importMemory() {
|
||||
Job job = new Job("Memory Import from RAW Binary File") { //$NON-NLS-1$
|
||||
|
||||
@Override
|
||||
public IStatus run(IProgressMonitor monitor) {
|
||||
try {
|
||||
BufferedMemoryWriter memoryWriter = new BufferedMemoryWriter((IMemoryBlockExtension) fMemoryBlock,
|
||||
BUFFER_LENGTH);
|
||||
|
||||
BigInteger scrollToAddress = null;
|
||||
|
||||
FileInputStream reader = new FileInputStream(fInputFile);
|
||||
|
||||
BigInteger jobs = BigInteger.valueOf(fInputFile.length());
|
||||
BigInteger factor = BigInteger.ONE;
|
||||
if (jobs.compareTo(BigInteger.valueOf(0x7FFFFFFF)) > 0) {
|
||||
factor = jobs.divide(BigInteger.valueOf(0x7FFFFFFF));
|
||||
jobs = jobs.divide(factor);
|
||||
}
|
||||
|
||||
byte[] byteValues = new byte[1024];
|
||||
|
||||
monitor.beginTask(Messages.getString("Importer.ProgressTitle"), jobs.intValue()); //$NON-NLS-1$
|
||||
|
||||
int actualByteCount = reader.read(byteValues);
|
||||
BigInteger recordAddress = fStartAddress;
|
||||
|
||||
while (actualByteCount != -1 && !monitor.isCanceled()) {
|
||||
byte data[] = new byte[actualByteCount];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
data[i] = byteValues[i];
|
||||
}
|
||||
|
||||
if (scrollToAddress == null)
|
||||
scrollToAddress = recordAddress;
|
||||
|
||||
BigInteger baseAddress = null;
|
||||
if (fMemoryBlock instanceof IMemoryBlockExtension)
|
||||
baseAddress = ((IMemoryBlockExtension) fMemoryBlock).getBigBaseAddress();
|
||||
else
|
||||
baseAddress = BigInteger.valueOf(fMemoryBlock.getStartAddress());
|
||||
|
||||
memoryWriter.write(recordAddress.subtract(baseAddress), data);
|
||||
|
||||
BigInteger jobCount = BigInteger.valueOf(actualByteCount).divide(factor);
|
||||
monitor.worked(jobCount.intValue());
|
||||
|
||||
recordAddress = recordAddress.add(BigInteger.valueOf(actualByteCount));
|
||||
actualByteCount = reader.read(byteValues);
|
||||
}
|
||||
|
||||
if (!monitor.isCanceled())
|
||||
memoryWriter.flush();
|
||||
|
||||
reader.close();
|
||||
monitor.done();
|
||||
|
||||
if (fScrollToStart)
|
||||
fParentDialog.scrollRenderings(scrollToAddress);
|
||||
|
||||
} catch (IOException ex) {
|
||||
MemoryTransportPlugin.getDefault().getLog()
|
||||
.log(new Status(IStatus.ERROR, MemoryTransportPlugin.getUniqueIdentifier(),
|
||||
DebugException.REQUEST_FAILED, Messages.getString("Importer.ErrReadFile"), ex)); //$NON-NLS-1$
|
||||
return new Status(IStatus.ERROR, MemoryTransportPlugin.getUniqueIdentifier(),
|
||||
DebugException.REQUEST_FAILED, Messages.getString("Importer.ErrReadFile"), ex); //$NON-NLS-1$
|
||||
|
||||
} catch (DebugException ex) {
|
||||
MemoryTransportPlugin.getDefault().getLog()
|
||||
.log(new Status(IStatus.ERROR, MemoryTransportPlugin.getUniqueIdentifier(),
|
||||
DebugException.REQUEST_FAILED, Messages.getString("Importer.ErrWriteTarget"), ex)); //$NON-NLS-1$
|
||||
return new Status(IStatus.ERROR, MemoryTransportPlugin.getUniqueIdentifier(),
|
||||
DebugException.REQUEST_FAILED, Messages.getString("Importer.ErrWriteTarget"), ex); //$NON-NLS-1$
|
||||
} catch (Exception ex) {
|
||||
MemoryTransportPlugin.getDefault().getLog()
|
||||
.log(new Status(IStatus.ERROR, MemoryTransportPlugin.getUniqueIdentifier(),
|
||||
DebugException.INTERNAL_ERROR, Messages.getString("Importer.FalureImporting"), ex)); //$NON-NLS-1$
|
||||
return new Status(IStatus.ERROR, MemoryTransportPlugin.getUniqueIdentifier(),
|
||||
DebugException.INTERNAL_ERROR, Messages.getString("Importer.FalureImporting"), ex); //$NON-NLS-1$
|
||||
}
|
||||
return Status.OK_STATUS;
|
||||
}
|
||||
};
|
||||
job.setUser(true);
|
||||
job.schedule();
|
||||
try {
|
||||
Consumer<BigInteger> scroll = fScrollToStart ? new ScrollMemory(fParentDialog) : new ScrollMemory.Ignore();
|
||||
IMemoryBlockExtension block = (IMemoryBlockExtension) fMemoryBlock;
|
||||
ImportRequest request = new ImportRequest(block.getBigBaseAddress(), fStartAddress,
|
||||
new WriteMemoryBlock(block));
|
||||
RAWBinaryImport memoryImport = new RAWBinaryImport(fInputFile, request, scroll);
|
||||
FileImportJob job = new FileImportJob(//
|
||||
"Memory Import from RAW Binary File", memoryImport);
|
||||
job.setUser(true);
|
||||
job.schedule();
|
||||
} catch (DebugException e) {
|
||||
//FIXME: unreachable with current implementation, to be i18n after UI rework
|
||||
ErrorDialog.openError(fParentDialog.getShell(), //
|
||||
"Import Failure", //
|
||||
"Failed to retrieve base memory address", //
|
||||
e.getStatus());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006, 2016 Wind River Systems, Inc. and others.
|
||||
* 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
|
||||
|
@ -10,25 +10,25 @@
|
|||
*
|
||||
* 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.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.math.BigInteger;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.eclipse.cdt.debug.core.memory.transport.ImportRequest;
|
||||
import org.eclipse.cdt.debug.internal.core.memory.transport.FileImportJob;
|
||||
import org.eclipse.cdt.debug.internal.core.memory.transport.SRecordImport;
|
||||
import org.eclipse.cdt.debug.internal.ui.memory.transport.ScrollMemory;
|
||||
import org.eclipse.cdt.debug.internal.ui.memory.transport.WriteMemoryBlock;
|
||||
import org.eclipse.cdt.debug.ui.memory.transport.model.IMemoryImporter;
|
||||
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.IMemoryBlockExtension;
|
||||
import org.eclipse.jface.dialogs.ErrorDialog;
|
||||
import org.eclipse.jface.dialogs.IDialogSettings;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.events.KeyEvent;
|
||||
|
@ -68,8 +68,6 @@ public class SRecordImporter implements IMemoryImporter {
|
|||
|
||||
private IDialogSettings fProperties;
|
||||
|
||||
private static final int BUFFER_LENGTH = 64 * 1024;
|
||||
|
||||
@Override
|
||||
public Control createControl(final Composite parent, IMemoryBlock memBlock, IDialogSettings properties,
|
||||
ImportMemoryDialog parentDialog) {
|
||||
|
@ -337,176 +335,23 @@ public class SRecordImporter implements IMemoryImporter {
|
|||
|
||||
@Override
|
||||
public void importMemory() {
|
||||
Job job = new Job("Memory Import from S-Record File") { //$NON-NLS-1$
|
||||
|
||||
@Override
|
||||
public IStatus run(IProgressMonitor monitor) {
|
||||
|
||||
try {
|
||||
BufferedMemoryWriter memoryWriter = new BufferedMemoryWriter((IMemoryBlockExtension) fMemoryBlock,
|
||||
BUFFER_LENGTH);
|
||||
|
||||
// FIXME 4 byte default
|
||||
|
||||
final int CHECKSUM_LENGTH = 1;
|
||||
|
||||
BigInteger scrollToAddress = null;
|
||||
|
||||
BigInteger offset = null;
|
||||
if (!fProperties.getBoolean(TRANSFER_CUSTOM_START_ADDRESS))
|
||||
offset = BigInteger.ZERO;
|
||||
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(fInputFile)));
|
||||
|
||||
BigInteger jobs = BigInteger.valueOf(fInputFile.length());
|
||||
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("Importer.ProgressTitle"), jobs.intValue()); //$NON-NLS-1$
|
||||
|
||||
String line = reader.readLine();
|
||||
int lineNo = 1; // line error reporting
|
||||
while (line != null && !monitor.isCanceled()) {
|
||||
String recordType = line.substring(0, 2);
|
||||
int recordCount = 0;
|
||||
try {
|
||||
recordCount = Integer.parseInt(line.substring(2, 4), 16);
|
||||
} catch (NumberFormatException ex) {
|
||||
return new Status(IStatus.ERROR, MemoryTransportPlugin.getUniqueIdentifier(),
|
||||
DebugException.REQUEST_FAILED,
|
||||
String.format(Messages.getString("SRecordImporter.InvalidLineLength"), lineNo), ex); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
int bytesRead = 4 + recordCount;
|
||||
int position = 4;
|
||||
int addressSize = 0;
|
||||
|
||||
BigInteger recordAddress = null;
|
||||
|
||||
if ("S3".equals(recordType)) //$NON-NLS-1$
|
||||
addressSize = 4;
|
||||
else if ("S1".equals(recordType)) //$NON-NLS-1$
|
||||
addressSize = 2;
|
||||
else if ("S2".equals(recordType)) //$NON-NLS-1$
|
||||
addressSize = 3;
|
||||
else if ("S0".equals(recordType) || "S5".equals(recordType) || "S7".equals(recordType)
|
||||
|| "S8".equals(recordType) || "S9".equals(recordType)) //$NON-NLS-1$
|
||||
{ // ignore S0, S5, S7, S8 and S9 records
|
||||
line = reader.readLine();
|
||||
lineNo++;
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
recordAddress = new BigInteger(line.substring(position, position + addressSize * 2), 16);
|
||||
} catch (NumberFormatException ex) {
|
||||
return new Status(IStatus.ERROR, MemoryTransportPlugin.getUniqueIdentifier(),
|
||||
DebugException.REQUEST_FAILED,
|
||||
String.format(Messages.getString("SRecordImporter.InvalidAddress"), lineNo), ex); //$NON-NLS-1$
|
||||
}
|
||||
recordCount -= addressSize;
|
||||
position += addressSize * 2;
|
||||
|
||||
if (offset == null)
|
||||
offset = fStartAddress.subtract(recordAddress);
|
||||
|
||||
recordAddress = recordAddress.add(offset);
|
||||
|
||||
byte data[] = new byte[recordCount - CHECKSUM_LENGTH];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
try {
|
||||
data[i] = new BigInteger(line.substring(position++, position++ + 1), 16).byteValue();
|
||||
} catch (NumberFormatException ex) {
|
||||
return new Status(IStatus.ERROR, MemoryTransportPlugin.getUniqueIdentifier(),
|
||||
DebugException.REQUEST_FAILED,
|
||||
String.format(Messages.getString("SRecordImporter.InvalidData"), lineNo), ex); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
StringBuilder buf = new StringBuilder(line.substring(2));
|
||||
byte checksum = 0;
|
||||
|
||||
for (int i = 0; i < buf.length(); i += 2) {
|
||||
BigInteger value = null;
|
||||
try {
|
||||
value = new BigInteger(buf.substring(i, i + 2), 16);
|
||||
} catch (NumberFormatException ex) {
|
||||
return new Status(IStatus.ERROR, MemoryTransportPlugin.getUniqueIdentifier(),
|
||||
DebugException.REQUEST_FAILED,
|
||||
String.format(Messages.getString("SRecordImporter.InvalidChecksum"), lineNo), //$NON-NLS-1$
|
||||
ex);
|
||||
}
|
||||
checksum += value.byteValue();
|
||||
}
|
||||
|
||||
/*
|
||||
* Since we included the checksum in the checksum calculation the checksum
|
||||
* ( if correct ) will always be 0xFF which is -1 using the signed byte size
|
||||
* calculation here.
|
||||
*/
|
||||
if (checksum != (byte) -1) {
|
||||
reader.close();
|
||||
monitor.done();
|
||||
return new Status(IStatus.ERROR, MemoryTransportPlugin.getUniqueIdentifier(),
|
||||
Messages.getString("SRecordImporter.ChecksumFalure") + line); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
if (scrollToAddress == null)
|
||||
scrollToAddress = recordAddress;
|
||||
|
||||
// FIXME error on incorrect checksum
|
||||
|
||||
memoryWriter.write(
|
||||
recordAddress.subtract(((IMemoryBlockExtension) fMemoryBlock).getBigBaseAddress()),
|
||||
data);
|
||||
|
||||
BigInteger jobCount = BigInteger.valueOf(bytesRead).divide(factor);
|
||||
monitor.worked(jobCount.intValue());
|
||||
|
||||
line = reader.readLine();
|
||||
lineNo++;
|
||||
}
|
||||
|
||||
if (!monitor.isCanceled())
|
||||
memoryWriter.flush();
|
||||
|
||||
reader.close();
|
||||
monitor.done();
|
||||
|
||||
if (fScrollToStart)
|
||||
fParentDialog.scrollRenderings(scrollToAddress);
|
||||
|
||||
} catch (IOException ex) {
|
||||
MemoryTransportPlugin.getDefault().getLog()
|
||||
.log(new Status(IStatus.ERROR, MemoryTransportPlugin.getUniqueIdentifier(),
|
||||
DebugException.REQUEST_FAILED, Messages.getString("Importer.ErrReadFile"), ex)); //$NON-NLS-1$
|
||||
return new Status(IStatus.ERROR, MemoryTransportPlugin.getUniqueIdentifier(),
|
||||
DebugException.REQUEST_FAILED, Messages.getString("Importer.ErrReadFile"), ex); //$NON-NLS-1$
|
||||
|
||||
} catch (DebugException ex) {
|
||||
MemoryTransportPlugin.getDefault().getLog()
|
||||
.log(new Status(IStatus.ERROR, MemoryTransportPlugin.getUniqueIdentifier(),
|
||||
DebugException.REQUEST_FAILED, Messages.getString("Importer.ErrWriteTarget"), ex)); //$NON-NLS-1$
|
||||
return new Status(IStatus.ERROR, MemoryTransportPlugin.getUniqueIdentifier(),
|
||||
DebugException.REQUEST_FAILED, Messages.getString("Importer.ErrWriteTarget"), ex); //$NON-NLS-1$
|
||||
} catch (Exception ex) {
|
||||
MemoryTransportPlugin.getDefault().getLog()
|
||||
.log(new Status(IStatus.ERROR, MemoryTransportPlugin.getUniqueIdentifier(),
|
||||
DebugException.INTERNAL_ERROR, Messages.getString("Importer.FalureImporting"), ex)); //$NON-NLS-1$
|
||||
return new Status(IStatus.ERROR, MemoryTransportPlugin.getUniqueIdentifier(),
|
||||
DebugException.INTERNAL_ERROR, Messages.getString("Importer.FalureImporting"), ex); //$NON-NLS-1$
|
||||
}
|
||||
return Status.OK_STATUS;
|
||||
}
|
||||
};
|
||||
job.setUser(true);
|
||||
job.schedule();
|
||||
try {
|
||||
Consumer<BigInteger> scroll = fScrollToStart ? new ScrollMemory(fParentDialog) : new ScrollMemory.Ignore();
|
||||
IMemoryBlockExtension block = (IMemoryBlockExtension) fMemoryBlock;
|
||||
ImportRequest request = new ImportRequest(block.getBigBaseAddress(), fStartAddress,
|
||||
new WriteMemoryBlock(block));
|
||||
SRecordImport memoryImport = new SRecordImport(fInputFile, request, scroll,
|
||||
fProperties.getBoolean(TRANSFER_CUSTOM_START_ADDRESS));
|
||||
FileImportJob job = new FileImportJob(//
|
||||
"Memory Import from S-Record File", memoryImport);
|
||||
job.setUser(true);
|
||||
job.schedule();
|
||||
} catch (DebugException e) {
|
||||
//FIXME: unreachable with current implementation, to be i18n after UI rework
|
||||
ErrorDialog.openError(fParentDialog.getShell(), //
|
||||
"Import Failure", //
|
||||
"Failed to retrieve base memory address", //
|
||||
e.getStatus());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
###############################################################################
|
||||
# Copyright (c) 2009, 2010 Wind River Systems and others.
|
||||
# Copyright (c) 2009, 2020 Wind River Systems and others.
|
||||
#
|
||||
# This program and the accompanying materials
|
||||
# are made available under the terms of the Eclipse Public License 2.0
|
||||
|
@ -11,6 +11,7 @@
|
|||
# Contributors:
|
||||
# Ted R Williams (Wind River) - initial API and implementation
|
||||
# Teodor Madan (Freescale) -
|
||||
# Alexander Fedorov (ArSysOp) - headless part extraction
|
||||
###############################################################################
|
||||
|
||||
ExportMemoryDialog.Format=Format:\u0020
|
||||
|
@ -31,11 +32,8 @@ Exporter.ProgressTitle=Transferring Data
|
|||
|
||||
Importer.AllFiles=All Files
|
||||
Importer.Browse=Browse...
|
||||
Importer.ErrReadFile=Could not read from file.
|
||||
Importer.ErrWriteTarget=Could not write to target.
|
||||
Importer.FalureImporting=Failure importing from file
|
||||
Importer.File=File name:\u0020
|
||||
Importer.ProgressTitle=Transferring Data
|
||||
|
||||
PlainTextExporter.ChooseFile=Choose memory export file
|
||||
PlainTextExporter.EndAddress=End address:\u0020
|
||||
|
@ -44,7 +42,6 @@ PlainTextExporter.Name=Plain Text
|
|||
PlainTextExporter.StartAddress=Start address:\u0020
|
||||
|
||||
PlainTextImporter.ChooseFile=Choose memory import file
|
||||
PlainTextImporter.ErrInvalidFormat=Invalid file format. Expected integer at line %d
|
||||
PlainTextImporter.Name=Plain Text
|
||||
PlainTextImporter.RestoreAddress=Restore to address:\u0020
|
||||
PlainTextImporter.ScrollToStart=Scroll to restore address
|
||||
|
@ -56,14 +53,9 @@ SRecordExporter.Name=SRecord
|
|||
SRecordExporter.StartAddress=Start address:\u0020
|
||||
SRecordExporter.32BitLimitationMessage=SRecord format only supports 32-bit address spaces.
|
||||
|
||||
SRecordImporter.ChecksumFalure=Checksum failure of line =\u0020
|
||||
SRecordImporter.ChooseFile=Choose memory import file
|
||||
SRecordImporter.CustomAddressRestore=Restore to this address:\u0020
|
||||
SRecordImporter.FileAddressRestore=Restore to address specified in the file
|
||||
SRecordImporter.InvalidAddress=Invalid file format. Invalid address at line %d
|
||||
SRecordImporter.InvalidChecksum=Invalid file format. Invalid checksum format at line %d
|
||||
SRecordImporter.InvalidData=Invalid file format. Invalid data at line %d
|
||||
SRecordImporter.InvalidLineLength=Invalid file format. Invalid line length at line %d
|
||||
SRecordImporter.Name=SRecord
|
||||
SRecordImporter.ScrollToStart=Scroll to restore address
|
||||
SRecordImporter.32BitLimitationMessage=SRecord format only supports 32-bit address spaces.
|
||||
|
|
Loading…
Add table
Reference in a new issue