diff --git a/memory/org.eclipse.cdt.debug.core.memory/src/org/eclipse/cdt/debug/core/memory/transport/ExportRequest.java b/memory/org.eclipse.cdt.debug.core.memory/src/org/eclipse/cdt/debug/core/memory/transport/ExportRequest.java new file mode 100644 index 00000000000..ff92e8c24c1 --- /dev/null +++ b/memory/org.eclipse.cdt.debug.core.memory/src/org/eclipse/cdt/debug/core/memory/transport/ExportRequest.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * 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 export configuration + * + * @since 0.1 + * + */ +public final class ExportRequest { + + private final BigInteger start; + private final BigInteger end; + private final BigInteger addressable; + private final ReadMemory read; + + public ExportRequest(BigInteger start, BigInteger end, BigInteger addressable, ReadMemory read) { + this.start = start; + this.end = end; + this.addressable = addressable; + this.read = read; + } + + /** + * + * @return starting offset + */ + public BigInteger start() { + return start; + } + + /** + * + * @return ending offset + */ + public BigInteger end() { + return end; + } + + /** + * + * @return addressable size + */ + public BigInteger addressable() { + return addressable; + } + + /** + * + * @return reader + */ + public ReadMemory read() { + return read; + } +} diff --git a/memory/org.eclipse.cdt.debug.core.memory/src/org/eclipse/cdt/debug/core/memory/transport/FileExport.java b/memory/org.eclipse.cdt.debug.core.memory/src/org/eclipse/cdt/debug/core/memory/transport/FileExport.java new file mode 100644 index 00000000000..564c2edc940 --- /dev/null +++ b/memory/org.eclipse.cdt.debug.core.memory/src/org/eclipse/cdt/debug/core/memory/transport/FileExport.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * 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.math.BigInteger; + +import org.eclipse.core.runtime.ICoreRunnable; + +/** + * Exports memory information to a given file + * + * @since 0.1 + */ +public abstract class FileExport implements ICoreRunnable { + + protected final BigInteger start; + protected final BigInteger end; + protected final BigInteger addressable; + protected final ReadMemory read; + + protected final File file; + + protected FileExport(File input, ExportRequest request) { + this.file = input; + this.start = request.start(); + this.end = request.end(); + this.addressable = request.addressable(); + this.read = request.read(); + } + +} diff --git a/memory/org.eclipse.cdt.debug.core.memory/src/org/eclipse/cdt/debug/core/memory/transport/ImportRequest.java b/memory/org.eclipse.cdt.debug.core.memory/src/org/eclipse/cdt/debug/core/memory/transport/ImportRequest.java index 2085e966040..ab981503f3b 100644 --- a/memory/org.eclipse.cdt.debug.core.memory/src/org/eclipse/cdt/debug/core/memory/transport/ImportRequest.java +++ b/memory/org.eclipse.cdt.debug.core.memory/src/org/eclipse/cdt/debug/core/memory/transport/ImportRequest.java @@ -22,7 +22,7 @@ import java.math.BigInteger; * @since 0.1 * */ -public class ImportRequest { +public final class ImportRequest { private final BigInteger base; private final BigInteger start; diff --git a/memory/org.eclipse.cdt.debug.core.memory/src/org/eclipse/cdt/debug/core/memory/transport/ReadMemory.java b/memory/org.eclipse.cdt.debug.core.memory/src/org/eclipse/cdt/debug/core/memory/transport/ReadMemory.java new file mode 100644 index 00000000000..f98cb00e166 --- /dev/null +++ b/memory/org.eclipse.cdt.debug.core.memory/src/org/eclipse/cdt/debug/core/memory/transport/ReadMemory.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * 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; + +import org.eclipse.debug.core.DebugException; + +/** + * Reads an array of bytes using the given offset + * + * @since 0.1 + */ +public interface ReadMemory { + + /** + * Reads an array of bytes from a memory starting from the given offset. + * + * @param offset + * @return the obtained data + * @throws DebugException + */ + byte[] from(BigInteger offset) throws DebugException; + +} diff --git a/memory/org.eclipse.cdt.debug.core.memory/src/org/eclipse/cdt/debug/internal/core/memory/transport/ReadMemoryBlock.java b/memory/org.eclipse.cdt.debug.core.memory/src/org/eclipse/cdt/debug/internal/core/memory/transport/ReadMemoryBlock.java new file mode 100644 index 00000000000..3ce1ec7006a --- /dev/null +++ b/memory/org.eclipse.cdt.debug.core.memory/src/org/eclipse/cdt/debug/internal/core/memory/transport/ReadMemoryBlock.java @@ -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.core.memory.transport; + +import java.math.BigInteger; + +import org.eclipse.cdt.debug.core.memory.transport.ReadMemory; +import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.model.IMemoryBlockExtension; +import org.eclipse.debug.core.model.MemoryByte; + +/** + * Reads memory from the given {@link IMemoryBlockExtension} + * + */ +public final class ReadMemoryBlock implements ReadMemory { + + private final IMemoryBlockExtension memory; + private final long unit; + + public ReadMemoryBlock(IMemoryBlockExtension memory) { + this.memory = memory; + this.unit = BigInteger.valueOf(1).longValue(); + } + + @Override + public byte[] from(BigInteger offset) throws DebugException { + MemoryByte[] received = memory.getBytesFromOffset(offset, unit); + byte[] bytes = new byte[received.length]; + for (int i = 0; i < received.length; i++) { + bytes[i] = received[i].getValue(); + } + return bytes; + } + +} diff --git a/memory/org.eclipse.cdt.debug.ui.memory.transport/src/org/eclipse/cdt/debug/internal/ui/memory/transport/AddressableSize.java b/memory/org.eclipse.cdt.debug.ui.memory.transport/src/org/eclipse/cdt/debug/internal/ui/memory/transport/AddressableSize.java new file mode 100644 index 00000000000..6c8f4e352d1 --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.transport/src/org/eclipse/cdt/debug/internal/ui/memory/transport/AddressableSize.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * 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.Supplier; + +import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.model.IMemoryBlockExtension; + +public class AddressableSize implements Supplier { + + private final IMemoryBlockExtension memory; + + public AddressableSize(IMemoryBlockExtension memory) { + this.memory = memory; + } + + @Override + public BigInteger get() { + try { + return BigInteger.valueOf(memory.getAddressableSize()); + } catch (DebugException e1) { + // sane value for most cases + return BigInteger.ONE; + } + } + +} diff --git a/memory/org.eclipse.cdt.debug.ui.memory.transport/src/org/eclipse/cdt/debug/ui/memory/transport/PlainTextExport.java b/memory/org.eclipse.cdt.debug.ui.memory.transport/src/org/eclipse/cdt/debug/ui/memory/transport/PlainTextExport.java new file mode 100644 index 00000000000..cc17b94f15c --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.transport/src/org/eclipse/cdt/debug/ui/memory/transport/PlainTextExport.java @@ -0,0 +1,111 @@ +/******************************************************************************* + * 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 { + + 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$ + } + } + +} \ No newline at end of file diff --git a/memory/org.eclipse.cdt.debug.ui.memory.transport/src/org/eclipse/cdt/debug/ui/memory/transport/PlainTextExporter.java b/memory/org.eclipse.cdt.debug.ui.memory.transport/src/org/eclipse/cdt/debug/ui/memory/transport/PlainTextExporter.java index d8bc66c642c..ebabeea4fbf 100644 --- a/memory/org.eclipse.cdt.debug.ui.memory.transport/src/org/eclipse/cdt/debug/ui/memory/transport/PlainTextExporter.java +++ b/memory/org.eclipse.cdt.debug.ui.memory.transport/src/org/eclipse/cdt/debug/ui/memory/transport/PlainTextExporter.java @@ -15,19 +15,16 @@ 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.ReadMemory; +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.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.debug.core.model.MemoryByte; import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.swt.SWT; import org.eclipse.swt.events.KeyEvent; @@ -453,110 +450,13 @@ public class PlainTextExporter implements IMemoryExporter { @Override public void exportMemory() { - Job job = new Job("Memory Export to Plain Text File") { //$NON-NLS-1$ - @Override - public IStatus run(IProgressMonitor monitor) { - try { - final BigInteger addressableSize = getAdressableSize(); - - // 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(addressableSize); - // deduce the number of data chunks to be output, per line - final BigInteger dataCellsPerLine = dataCellSize.multiply(numberOfColumns); - - BigInteger transferAddress = fStartAddress; - - FileWriter writer = new FileWriter(fOutputFile); - - BigInteger jobs = fEndAddress.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(fEndAddress) < 0 && !monitor.isCanceled()) { - BigInteger length = dataCellsPerLine; - 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))); - - StringBuilder buf = new StringBuilder(); - - for (int i = 0; i < length.divide(dataCellSize).intValue(); i++) { - if (i != 0) - buf.append(" "); //$NON-NLS-1$ - MemoryByte bytes[] = ((IMemoryBlockExtension) fMemoryBlock).getBytesFromAddress( - transferAddress.add(dataCellSize.multiply(BigInteger.valueOf(i))), - dataCellSize.longValue()); - for (int byteIndex = 0; byteIndex < bytes.length; byteIndex++) { - String bString = BigInteger.valueOf(0xFF & bytes[byteIndex].getValue()).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$ - 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; - } - }; + ReadMemory read = new ReadMemoryBlock((IMemoryBlockExtension) fMemoryBlock); + BigInteger addressable = new AddressableSize((IMemoryBlockExtension) fMemoryBlock).get(); + ExportRequest request = new ExportRequest(fStartAddress, fEndAddress, addressable, read); + PlainTextExport memoryExport = new PlainTextExport(fOutputFile, request); + TransportJob job = new TransportJob("Memory Export to Plain Text File", memoryExport); job.setUser(true); job.schedule(); } - private BigInteger getAdressableSize() { - BigInteger addressableSize; - try { - addressableSize = BigInteger.valueOf(((IMemoryBlockExtension) fMemoryBlock).getAddressableSize()); - } catch (DebugException e1) { - // sane value for most cases - addressableSize = BigInteger.ONE; - } - return addressableSize; - } - }