();
+ for(String string : strings)
+ if(string != null)
+ nonNullStrings.addElement(string);
+ return (String[]) nonNullStrings.toArray(new String[0]);
+ }
+
+ private String getMemoryBlockBaseAddress()
+ {
+ BigInteger base = null;
+ try
+ {
+ base = fMemoryBlock.getBigBaseAddress();
+ }
+ catch(DebugException de)
+ {
+ // do nothing
+ }
+
+ if(base == null)
+ base = BigInteger.ZERO;
+
+ return "0x" + pad(getAddressSize() * 2, base.toString(16).toUpperCase()); //$NON-NLS-1$
+ }
+
+ private String getViewportStart()
+ {
+ ISelection selection = fMemoryView.getViewPane(IDebugUIConstants.ID_RENDERING_VIEW_PANE_1).getSelectionProvider().getSelection();
+ if(selection instanceof StructuredSelection)
+ {
+ if(((StructuredSelection) selection).getFirstElement() instanceof IRepositionableMemoryRendering)
+ {
+ ((IRepositionableMemoryRendering) ((StructuredSelection) selection).getFirstElement()).getSelectedAddress();
+ }
+ }
+ return null;
+ }
+
+ private String getStart()
+ {
+ BigInteger start = null;
+ try
+ {
+ start = fMemoryBlock.getMemoryBlockStartAddress();
+ }
+ catch(DebugException de)
+ {
+ // do nothing
+ }
+
+ if(start == null)
+ start = BigInteger.ZERO;
+
+ return "0x" + pad(getAddressSize() * 2, start.toString(16).toUpperCase()); //$NON-NLS-1$
+ }
+
+ private String getEnd()
+ {
+ BigInteger end = null;
+
+ try
+ {
+ end = fMemoryBlock.getMemoryBlockEndAddress();
+ }
+ catch(DebugException de)
+ {
+ // do nothing
+ }
+
+ if(end == null)
+ {
+ end = BigInteger.ZERO;
+
+ for(int i = getAddressSize(); i > 0; i--)
+ {
+ end = end.shiftLeft(8);
+ end = end.or(BigInteger.valueOf(255));
+ }
+ }
+
+ return "0x" + pad(getAddressSize() * 2, end.toString(16).toUpperCase()); //$NON-NLS-1$
+ }
+
+ private int getAddressSize()
+ {
+ int addressSize;
+ try
+ {
+ addressSize = fMemoryBlock.getAddressSize();
+ }
+ catch(DebugException de)
+ {
+ addressSize = 4; // default to 32bit?
+ }
+ return addressSize;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite)
+ */
+ protected Control createDialogArea(Composite parent) {
+
+ PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, MemorySearchPlugin.getUniqueIdentifier() + ".MemorySearchDialog_context"); //$NON-NLS-1$
+ Composite composite = new Composite(parent, SWT.NONE);
+ FormLayout formLayout = new FormLayout();
+ formLayout.spacing = 5;
+ formLayout.marginWidth = formLayout.marginHeight = 9;
+ composite.setLayout(formLayout);
+
+ // find
+
+ Label findLabel = new Label(composite, SWT.NONE);
+ Label replaceLabel = new Label(composite, SWT.NONE);
+ fReplaceText = new Text(composite, SWT.BORDER);
+
+ findLabel.setText(Messages.getString("FindReplaceDialog.LabelFind")); //$NON-NLS-1$
+
+ fFindText = new Text(composite, SWT.BORDER);
+ FormData data = new FormData();
+ data.left = new FormAttachment(fReplaceText, 0, SWT.LEFT);
+ data.width = 260;
+ fFindText.setLayoutData(data);
+ fFindText.setText(fProperties.getProperty(SEARCH_FIND, ""));
+
+ data = new FormData();
+ data.top = new FormAttachment(fFindText, 0, SWT.CENTER);
+ findLabel.setLayoutData(data);
+
+ // replace
+
+ replaceLabel.setText(Messages.getString("FindReplaceDialog.LabelReplaceWith")); //$NON-NLS-1$
+ data = new FormData();
+ data.top = new FormAttachment(fFindText);
+ replaceLabel.setLayoutData(data);
+
+ data = new FormData();
+ data.top = new FormAttachment(replaceLabel, 0, SWT.CENTER);
+ data.left = new FormAttachment(replaceLabel);
+ data.width = 260;
+ fReplaceText.setLayoutData(data);
+ fReplaceText.setText(fProperties.getProperty(SEARCH_REPLACE, ""));
+
+ // group direction
+
+ Group directionGroup = new Group(composite, SWT.NONE);
+ Group formatGroup = new Group(composite, SWT.NONE);
+ Group rangeGroup = new Group(composite, SWT.NONE);
+ directionGroup.setText(Messages.getString("FindReplaceDialog.LabelDirection")); //$NON-NLS-1$
+
+ GridLayout layout = new GridLayout();
+ layout.numColumns = 1;
+ directionGroup.setLayout(layout);
+
+ fForwardButton = new Button(directionGroup, SWT.RADIO);
+ fForwardButton.setText(Messages.getString("FindReplaceDialog.ButtonForward")); //$NON-NLS-1$
+ final Button backwardButton = new Button(directionGroup, SWT.RADIO);
+ backwardButton.setText(Messages.getString("FindReplaceDialog.ButtonBackward")); //$NON-NLS-1$
+ final boolean isForward = fProperties.getProperty(SEARCH_FORMAT_FORWARD, "true").equalsIgnoreCase("true");
+ fForwardButton.setSelection(isForward);
+ backwardButton.setSelection(!isForward);
+
+ data = new FormData();
+ data.top = new FormAttachment(fReplaceText);
+ data.right = new FormAttachment(formatGroup, 0, SWT.RIGHT);
+ data.left = new FormAttachment(formatGroup, 0, SWT.LEFT);
+ data.bottom = new FormAttachment(rangeGroup, 0, SWT.BOTTOM);
+ directionGroup.setLayoutData(data);
+
+ // group range
+
+ rangeGroup.setText(Messages.getString("FindReplaceDialog.LabelRange")); //$NON-NLS-1$
+
+ layout = new GridLayout();
+ layout.numColumns = 2;
+ layout.makeColumnsEqualWidth = false;
+ rangeGroup.setLayout(layout);
+
+ // group range - start address
+
+ Label startLabel = new Label(rangeGroup, SWT.NONE);
+ startLabel.setText(Messages.getString("FindReplaceDialog.LabelStartAddress")); //$NON-NLS-1$
+
+ fStartText = new Combo(rangeGroup, SWT.BORDER);
+ GridData gridData = new GridData();
+ gridData.widthHint = 200;
+ gridData.grabExcessHorizontalSpace = true;
+ fStartText.setLayoutData(gridData);
+
+ // group range - end address
+
+ Label endLabel = new Label(rangeGroup, SWT.NONE);
+ endLabel.setText(Messages.getString("FindReplaceDialog.LabelEndAddress")); //$NON-NLS-1$
+ fEndText = new Combo(rangeGroup, SWT.BORDER);
+ gridData = new GridData();
+ gridData.widthHint = 200;
+ gridData.grabExcessHorizontalSpace = true;
+ fEndText.setLayoutData(gridData);
+
+ data = new FormData();
+ data.left = new FormAttachment(directionGroup);
+ data.top = new FormAttachment(directionGroup, 0, SWT.TOP);
+ data.right = new FormAttachment(fFindText, 0, SWT.RIGHT);
+ rangeGroup.setLayoutData(data);
+
+ fStartText.setItems(removeNullElements(new String[] { getViewportStart(), getStart(), getEnd(), getMemoryBlockBaseAddress() }));
+ fEndText.setItems(removeNullElements(new String[] { getEnd(), getStart(), getMemoryBlockBaseAddress(), getViewportStart() }));
+ if(fProperties.getProperty(SEARCH_START) != null)
+ fStartText.add(fProperties.getProperty(SEARCH_START), 0);
+ if(fProperties.getProperty(SEARCH_END) != null)
+ fEndText.add(fProperties.getProperty(SEARCH_END), 0);
+ fStartText.select(0);
+ fEndText.select(0);
+
+ // format group
+
+ formatGroup.setText(Messages.getString("FindReplaceDialog.LabelFormat")); //$NON-NLS-1$
+ layout = new GridLayout();
+ layout.numColumns = 1;
+ formatGroup.setLayout(layout);
+
+ fFormatAsciiButton = new Button(formatGroup, SWT.RADIO);
+ fFormatAsciiButton.setText(Messages.getString("FindReplaceDialog.ButtonASCII")); //$NON-NLS-1$
+
+ fFormatHexButton = new Button(formatGroup, SWT.RADIO);
+ fFormatHexButton.setText(Messages.getString("FindReplaceDialog.ButtonHexadecimal")); //$NON-NLS-1$
+
+ fFormatOctalButton = new Button(formatGroup, SWT.RADIO);
+ fFormatOctalButton.setText(Messages.getString("FindReplaceDialog.ButtonOctal")); //$NON-NLS-1$
+
+ fFormatBinaryButton = new Button(formatGroup, SWT.RADIO);
+ fFormatBinaryButton.setText(Messages.getString("FindReplaceDialog.ButtonBinary")); //$NON-NLS-1$
+
+ fFormatDecimalButton = new Button(formatGroup, SWT.RADIO);
+ fFormatDecimalButton.setText(Messages.getString("FindReplaceDialog.ButtonDecimal")); //$NON-NLS-1$
+
+ fFormatByteSequenceButton = new Button(formatGroup, SWT.RADIO);
+ fFormatByteSequenceButton.setText(Messages.getString("FindReplaceDialog.ButtonByteSequence")); //$NON-NLS-1$
+
+ final String format = fProperties.getProperty(SEARCH_FORMAT, FindReplaceDialog.SEARCH_FORMAT_ASCII);
+
+ fFormatAsciiButton.setSelection(format.equals(SEARCH_FORMAT_ASCII));
+ fFormatOctalButton.setSelection(format.equals(SEARCH_FORMAT_OCTAL));
+ fFormatBinaryButton.setSelection(format.equals(SEARCH_FORMAT_BINARY));
+ fFormatDecimalButton.setSelection(format.equals(SEARCH_FORMAT_DECIMAL));
+ fFormatHexButton.setSelection(format.equals(SEARCH_FORMAT_HEX));
+ fFormatByteSequenceButton.setSelection(format.equals(SEARCH_FORMAT_BYTESEQUENCE));
+
+
+ data = new FormData();
+ data.top = new FormAttachment(rangeGroup);
+ formatGroup.setLayoutData(data);
+
+ // options group
+
+ Group optionsGroup = new Group(composite, SWT.NONE);
+ optionsGroup.setText(Messages.getString("FindReplaceDialog.LabelOptions")); //$NON-NLS-1$
+
+ data = new FormData();
+ data.left = new FormAttachment(formatGroup);
+ data.top = new FormAttachment(rangeGroup);
+ data.bottom = new FormAttachment(formatGroup, 0, SWT.BOTTOM);
+ data.right = new FormAttachment(rangeGroup, 0, SWT.RIGHT);
+ optionsGroup.setLayoutData(data);
+
+ layout = new GridLayout();
+ layout.numColumns = 1;
+ optionsGroup.setLayout(layout);
+
+
+ // wrap
+
+ fWrapCheckbox = new Button(optionsGroup, SWT.CHECK);
+ fWrapCheckbox.setText(Messages.getString("FindReplaceDialog.ButtonWrapSearch")); //$NON-NLS-1$
+ fWrapCheckbox.setEnabled(false); // TODO implement wrap
+
+ fCaseInSensitiveCheckbox = new Button(optionsGroup, SWT.CHECK);
+ fCaseInSensitiveCheckbox.setText(Messages.getString("FindReplaceDialog.ButtonCaseInsensitive")); //$NON-NLS-1$
+
+ fFormatAsciiButton.addSelectionListener(new SelectionListener()
+ {
+ public void widgetDefaultSelected(SelectionEvent e) { }
+
+ public void widgetSelected(SelectionEvent e) {
+ fCaseInSensitiveCheckbox.setEnabled(true);
+ }
+ });
+
+ SelectionListener nonAsciiListener = new SelectionListener()
+ {
+ public void widgetDefaultSelected(SelectionEvent e) { }
+
+ public void widgetSelected(SelectionEvent e) {
+ fCaseInSensitiveCheckbox.setEnabled(false);
+ validate();
+ }
+ };
+ fFormatHexButton.addSelectionListener(nonAsciiListener);
+ fFormatOctalButton.addSelectionListener(nonAsciiListener);
+ fFormatBinaryButton.addSelectionListener(nonAsciiListener);
+ fFormatDecimalButton.addSelectionListener(nonAsciiListener);
+ fFormatByteSequenceButton.addSelectionListener(nonAsciiListener);
+
+ fStartText.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ boolean valid = true;
+ try
+ {
+ getStartAddress();
+ }
+ catch(Exception ex)
+ {
+ valid = false;
+ }
+
+ fStartText.setForeground(valid ? Display.getDefault().getSystemColor(SWT.COLOR_BLACK) :
+ Display.getDefault().getSystemColor(SWT.COLOR_RED));
+
+ validate();
+ }
+
+ });
+
+ fEndText.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ try
+ {
+ getEndAddress();
+ fEndText.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_BLACK));
+ }
+ catch(Exception ex)
+ {
+ fEndText.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_RED));
+ }
+
+ validate();
+ }
+
+ });
+
+ fFindText.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e)
+ {
+ validate();
+ }
+ });
+
+ fReplaceText.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e)
+ {
+ validate();
+ }
+ });
+
+ composite.setTabList(new Control[] {
+ fFindText,
+ fReplaceText,
+ directionGroup,
+ rangeGroup,
+ formatGroup,
+ optionsGroup,
+ });
+
+ fFindText.setFocus();
+
+ return composite;
+ }
+
+
+ class FindReplaceMemoryCache
+ {
+ BigInteger memoryCacheStartAddress = BigInteger.ZERO;
+ MemoryByte memoryCacheData[] = new MemoryByte[0];
+ }
+
+ MemoryByte[] getBytesFromAddress(final BigInteger address, final int length, FindReplaceMemoryCache cache)
+ throws DebugException
+ {
+ if(! (address.compareTo(cache.memoryCacheStartAddress) >= 0
+ && address.add(BigInteger.valueOf(length)).compareTo(cache.memoryCacheStartAddress
+ .add(BigInteger.valueOf(cache.memoryCacheData.length))) < 0))
+ {
+ BigInteger fetchAddress = address.subtract(BigInteger.valueOf(preFetchSize));
+ if(fetchAddress.compareTo(BigInteger.ZERO) < 0) // TODO replace ZERO with address space start
+ fetchAddress = BigInteger.ZERO;
+
+ MemoryByte bytes[] = fMemoryBlock.getBytesFromAddress(fetchAddress, preFetchSize * 2);
+
+ cache.memoryCacheStartAddress = fetchAddress;
+ cache.memoryCacheData = bytes;
+ }
+
+ MemoryByte bytes[] = new MemoryByte[length];
+ System.arraycopy(cache.memoryCacheData, address.subtract(cache.memoryCacheStartAddress).intValue(),
+ bytes, 0, length);
+ return bytes;
+ }
+
+ private BigInteger parseHexBigInteger(String s)
+ {
+ if(s.toUpperCase().startsWith("0X"))
+ return new BigInteger(s.substring(2), 16);
+ else
+ return new BigInteger(s, 16);
+ }
+
+ protected void performFindNext()
+ {
+ try
+ {
+ BigInteger start = parseHexBigInteger(fProperties.getProperty(SEARCH_LAST_FOUND));
+ BigInteger end = parseHexBigInteger(fProperties.getProperty(SEARCH_END));
+ boolean searchForward = fProperties.getProperty(SEARCH_FORMAT_FORWARD, "false").equals("true");
+ boolean caseInSensitive = fProperties.getProperty(SEARCH_FORMAT_CASEINSENSTIVE, "false").equals("true");
+ if(searchForward)
+ start = start.add(BigInteger.ONE);
+ else
+ start = start.subtract(BigInteger.ONE);
+ SearchPhrase phrase = null;
+ String findText = fProperties.getProperty(SEARCH_FIND);
+
+ if(fProperties.getProperty(SEARCH_FORMAT).equals(SEARCH_FORMAT_ASCII))
+ phrase = new AsciiSearchPhrase(findText, caseInSensitive);
+ else if(fProperties.getProperty(SEARCH_FORMAT).equals(SEARCH_FORMAT_HEX))
+ phrase = new BigIntegerSearchPhrase(new BigInteger(findText.toUpperCase().startsWith("0X") //$NON-NLS-1$
+ ? findText.substring(2) : findText, 16), 16);
+ else if(fProperties.getProperty(SEARCH_FORMAT).equals(SEARCH_FORMAT_OCTAL))
+ phrase = new BigIntegerSearchPhrase(new BigInteger(findText.startsWith("0") //$NON-NLS-1$
+ ? findText.substring(1) : findText, 8), 8);
+ else if(fProperties.getProperty(SEARCH_FORMAT).equals(SEARCH_FORMAT_BINARY))
+ phrase = new BigIntegerSearchPhrase(new BigInteger(findText.toUpperCase().startsWith("0B") //$NON-NLS-1$
+ ? findText.substring(2) : findText, 2), 2);
+ else if(fProperties.getProperty(SEARCH_FORMAT).equals(SEARCH_FORMAT_DECIMAL))
+ phrase = new BigIntegerSearchPhrase(new BigInteger(findText, 10), 10);
+ else if(fProperties.getProperty(SEARCH_FORMAT).equals(SEARCH_FORMAT_BYTESEQUENCE))
+ phrase = new ByteSequenceSearchPhrase(findText);
+
+ performFind(start, end, phrase, searchForward, null, false, false);
+
+ }
+ catch(Exception e)
+ {
+ MemorySearchPlugin.logError(Messages.getString("FindReplaceDialog.MemorySearchFailure"), e);
+ }
+ }
+
+ private void performFind(final BigInteger start, final BigInteger end, final SearchPhrase searchPhrase,
+ final boolean searchForward, final byte[] replaceData, final boolean all, final boolean replaceThenFind)
+ {
+ final ISearchQuery query = new IMemorySearchQuery()
+ {
+ private ISearchResult fSearchResult = null;
+
+ public boolean canRerun() {
+ return false;
+ }
+
+ public boolean canRunInBackground() {
+ return true;
+ }
+
+ public String getLabel() {
+ return Messages.getString("FindReplaceDialog.SearchingMemoryFor") + searchPhrase; //$NON-NLS-1$
+ }
+
+ public ISearchResult getSearchResult() {
+ if(fSearchResult == null)
+ fSearchResult = new MemorySearchResult(this, Messages.getString("FindReplaceDialog.SearchingMemoryFor") + searchPhrase); //$NON-NLS-1$
+ return fSearchResult;
+ }
+
+ public IStatus run(IProgressMonitor monitor)
+ throws OperationCanceledException {
+
+ final BigInteger searchPhraseLength = BigInteger.valueOf(searchPhrase.getByteLength());
+ BigInteger range = start.subtract(end);
+ //BigInteger range = searchForward ? end.subtract(start) : start.subtract(end);
+ //BigInteger currentPosition = start;
+ BigInteger currentPosition = searchForward ? start : end.subtract(searchPhraseLength);
+
+ if ( range.compareTo(searchPhraseLength) >= 0 ) {
+ return Status.OK_STATUS;
+ }
+
+ boolean isReplace = replaceData != null;
+
+ BigInteger jobs = range;
+ BigInteger factor = BigInteger.ONE;
+ if(jobs.compareTo(BigInteger.valueOf(0x07FFFFFF)) > 0)
+ {
+ factor = jobs.divide(BigInteger.valueOf(0x07FFFFFF));
+ jobs = jobs.divide(factor);
+ }
+
+ BigInteger jobCount = BigInteger.ZERO;
+
+ BigInteger replaceCount = BigInteger.ZERO;
+
+ FindReplaceMemoryCache cache = new FindReplaceMemoryCache();
+
+ monitor.beginTask(Messages.getString("FindReplaceDialog.SearchingMemoryFor") + searchPhrase, jobs.intValue()); //$NON-NLS-1$
+
+ boolean matched = false;
+ while(((searchForward && currentPosition.compareTo(end.subtract(searchPhraseLength)) < 0)
+ || (!searchForward && currentPosition.compareTo(start) > 0)) && !monitor.isCanceled())
+ {
+ try
+ {
+ MemoryByte bytes[] = getBytesFromAddress(currentPosition, searchPhraseLength.intValue(), cache);
+ matched = searchPhrase.isMatch(bytes);
+ if(matched)
+ {
+ if(all && !isReplace)
+ ((MemorySearchResult) getSearchResult()).addMatch(new MemoryMatch(currentPosition, searchPhraseLength));
+
+ if(isReplace)
+ {
+ try
+ {
+ fMemoryBlock.setValue(currentPosition.subtract(fMemoryBlock.getBigBaseAddress()), replaceData);
+ }
+ catch(DebugException de)
+ {
+ MemorySearchPlugin.logError(Messages.getString("FindReplaceDialog.MemoryReadFailed"), de); //$NON-NLS-1$
+ }
+
+ replaceCount = replaceCount.add(BigInteger.ONE);
+ }
+
+ if(isReplace && replaceThenFind && replaceCount.compareTo(BigInteger.ONE) == 0)
+ {
+ isReplace = false;
+ matched = false;
+ }
+
+ if(matched && !all)
+ {
+ final BigInteger finalCurrentPosition = currentPosition;
+ Display.getDefault().asyncExec(new Runnable(){
+
+ public void run() {
+ IMemoryRenderingContainer containers[] = getMemoryView().getMemoryRenderingContainers();
+ for(int i = 0; i < containers.length; i++)
+ {
+ IMemoryRendering rendering = containers[i].getActiveRendering();
+ if(rendering instanceof IRepositionableMemoryRendering)
+ {
+ try {
+ ((IRepositionableMemoryRendering) rendering).goToAddress(finalCurrentPosition);
+ } catch (DebugException e) {
+ MemorySearchPlugin.logError(Messages.getString("FindReplaceDialog.RepositioningMemoryViewFailed"), e); //$NON-NLS-1$
+ }
+ }
+ if(rendering != null)
+ {
+ // Temporary, until platform accepts/adds new interface for setting the selection
+ try {
+ Method m = rendering.getClass().getMethod("setSelection", new Class[] { BigInteger.class, BigInteger.class } );
+ if(m != null)
+ m.invoke(rendering, finalCurrentPosition, finalCurrentPosition.add(searchPhraseLength));
+ } catch (Exception e) {
+ // do nothing
+ }
+ }
+ }
+ }
+
+ });
+
+ fProperties.setProperty(SEARCH_ENABLE_FIND_NEXT, "true");
+ fProperties.setProperty(SEARCH_LAST_FOUND, "0x" + finalCurrentPosition.toString(16));
+ return Status.OK_STATUS;
+ }
+ }
+
+ matched = false;
+
+ if(searchForward)
+ currentPosition = currentPosition.add(BigInteger.ONE);
+ else
+ currentPosition = currentPosition.subtract(BigInteger.ONE);
+
+ }
+ catch(DebugException e)
+ {
+ MemorySearchPlugin.logError(Messages.getString("FindReplaceDialog.MemorySearchFailure"), e); //$NON-NLS-1$
+ return Status.CANCEL_STATUS;
+ }
+
+ jobCount = jobCount.add(BigInteger.ONE);
+ if(jobCount.compareTo(factor) == 0)
+ {
+ jobCount = BigInteger.ZERO;
+ monitor.worked(1);
+ }
+ }
+
+ if(monitor.isCanceled())
+ return Status.CANCEL_STATUS;
+
+ return Status.OK_STATUS;
+ }
+
+ public MemoryView getMemoryView() {
+ return fMemoryView;
+ }
+ };
+
+ if(all && replaceData == null)
+ {
+ Display.getDefault().asyncExec(new Runnable() {
+ public void run()
+ {
+ NewSearchUI.activateSearchResultView();
+ NewSearchUI.runQueryInBackground(query);
+ }
+ });
+ }
+ else
+ {
+ Job job = new Job("Searching memory for " + searchPhrase){ //$NON-NLS-1$
+ public IStatus run(IProgressMonitor monitor) {
+ return query.run(monitor);
+ }
+ };
+ job.schedule();
+ }
+
+ }
+
+ interface SearchPhrase
+ {
+ boolean isMatch(MemoryByte[] bytes);
+ int getByteLength();
+ String toString();
+ }
+
+ class AsciiSearchPhrase implements SearchPhrase
+ {
+ private String fPhrase;
+ private boolean fIsCaseInsensitive;
+
+ public AsciiSearchPhrase(String phrase, boolean isCaseInsensitive)
+ {
+ fPhrase = phrase;
+ fIsCaseInsensitive = isCaseInsensitive;
+ }
+
+ public int getByteLength()
+ {
+ return fPhrase.length();
+ }
+
+ public String toString()
+ {
+ return fPhrase;
+ }
+
+ public boolean isMatch(MemoryByte[] bytes)
+ {
+ byte[] targetBytes = new byte[bytes.length];
+ for(int i = 0; i < bytes.length; i++)
+ targetBytes[i] = bytes[i].getValue();
+
+ String searchString = fPhrase;
+ String targetString = new String(targetBytes);
+
+ if(fIsCaseInsensitive)
+ {
+ searchString = searchString.toUpperCase();
+ targetString = targetString.toUpperCase();
+ }
+
+ return searchString.equals(targetString);
+ }
+ }
+
+ class ByteSequenceSearchPhrase implements SearchPhrase
+ {
+ private byte[] fBytes = null;
+
+ public ByteSequenceSearchPhrase(String phrase)
+ {
+ fBytes = parseByteSequence(phrase);
+ }
+
+ public int getByteLength()
+ {
+ if ( fBytes != null ) {
+ return fBytes.length;
+ }
+ else {
+ return 0;
+ }
+ }
+
+ public String toString()
+ {
+ if(fBytes == null)
+ return ""; //$NON-NLS-1$
+ StringBuffer buf = new StringBuffer();
+ for(int i = 0; i < fBytes.length; i++)
+ buf.append(BigInteger.valueOf(fBytes[i]).toString(16) + " "); //$NON-NLS-1$
+ return buf.toString();
+ }
+
+ public boolean isMatch(MemoryByte[] bytes)
+ {
+ if ( fBytes == null )
+ return false;
+ for(int i = 0; i < bytes.length; i++)
+ if(bytes[i].getValue() != fBytes[i])
+ return false;
+ return true;
+ }
+ }
+
+ class BigIntegerSearchPhrase implements SearchPhrase
+ {
+ private BigInteger fPhrase;
+ private int fRadix;
+
+ public BigIntegerSearchPhrase(BigInteger phrase, int radix)
+ {
+ fPhrase = phrase;
+ fRadix = radix;
+ }
+
+ public int getByteLength()
+ {
+ return removeZeroPrefixByte(fPhrase.toByteArray()).length;
+ }
+
+ public String toString()
+ {
+ return fPhrase.toString(fRadix);
+ }
+
+ public boolean isMatch(MemoryByte[] bytes)
+ {
+ byte[] targetBytes = new byte[bytes.length + 1];
+ targetBytes[0] = 0;
+ for(int i = 0; i < bytes.length; i++)
+ targetBytes[i + 1] = bytes[i].getValue();
+
+ // TODO endian?
+ BigInteger targetBigInteger = new BigInteger(targetBytes);
+
+ return fPhrase.equals(targetBigInteger);
+ }
+ }
+
+ private byte[] removeZeroPrefixByte(byte[] bytes)
+ {
+ if(bytes[0] != 0 || bytes.length == 1)
+ return bytes;
+
+ byte[] processedBytes = new byte[bytes.length - 1];
+ System.arraycopy(bytes, 1, processedBytes, 0, processedBytes.length);
+ return processedBytes;
+ }
+
+ interface IMemorySearchQuery extends ISearchQuery
+ {
+ public MemoryView getMemoryView();
+ };
+
+}
diff --git a/memory/org.eclipse.cdt.debug.ui.memory.search/src/org/eclipse/cdt/debug/ui/memory/search/MemoryMatch.java b/memory/org.eclipse.cdt.debug.ui.memory.search/src/org/eclipse/cdt/debug/ui/memory/search/MemoryMatch.java
new file mode 100644
index 00000000000..31ef6887ae9
--- /dev/null
+++ b/memory/org.eclipse.cdt.debug.ui.memory.search/src/org/eclipse/cdt/debug/ui/memory/search/MemoryMatch.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2008-2009 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Ted R Williams (Wind River Systems, Inc.) - initial implementation
+ *******************************************************************************/
+
+package org.eclipse.cdt.debug.ui.memory.search;
+
+import java.math.BigInteger;
+
+public class MemoryMatch
+{
+ BigInteger fStartAddress;
+
+ public BigInteger getStartAddress() {
+ return fStartAddress;
+ }
+
+ public void setStartAddress(BigInteger startAddress) {
+ fStartAddress = startAddress;
+ }
+
+ public BigInteger getLength() {
+ return fLength;
+ }
+
+ public void setLength(BigInteger length) {
+ fLength = length;
+ }
+
+ BigInteger fLength;
+
+ public MemoryMatch(BigInteger startAddress, BigInteger length)
+ {
+ fStartAddress = startAddress;
+ fLength = length;
+ }
+
+ public BigInteger getEndAddress()
+ {
+ return getStartAddress().add(getLength());
+ }
+}
diff --git a/memory/org.eclipse.cdt.debug.ui.memory.search/src/org/eclipse/cdt/debug/ui/memory/search/MemorySearchPlugin.java b/memory/org.eclipse.cdt.debug.ui.memory.search/src/org/eclipse/cdt/debug/ui/memory/search/MemorySearchPlugin.java
new file mode 100644
index 00000000000..be7a3f44aea
--- /dev/null
+++ b/memory/org.eclipse.cdt.debug.ui.memory.search/src/org/eclipse/cdt/debug/ui/memory/search/MemorySearchPlugin.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2007-2009 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Ted R Williams (Wind River Systems, Inc.) - initial implementation
+ *******************************************************************************/
+
+package org.eclipse.cdt.debug.ui.memory.search;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.internal.ui.DebugUIPlugin;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+
+public class MemorySearchPlugin extends AbstractUIPlugin
+{
+ private static final String PLUGIN_ID = "org.eclipse.cdt.debug.ui.memory.search"; //$NON-NLS-1$
+
+ private static MemorySearchPlugin plugin;
+
+ public MemorySearchPlugin()
+ {
+ super();
+ plugin = this;
+ }
+
+ /**
+ * Returns the shared instance.
+ */
+ public static MemorySearchPlugin getDefault() {
+ return plugin;
+ }
+
+ /**
+ * Returns the unique identifier for this plugin.
+ */
+ public static String getUniqueIdentifier() {
+ return PLUGIN_ID;
+ }
+
+ protected static void logError(String message, Exception e)
+ {
+ Status status = new Status(IStatus.ERROR, PLUGIN_ID,
+ DebugException.INTERNAL_ERROR, message, e);
+
+ getDefault().getLog().log(status);
+ }
+}
diff --git a/memory/org.eclipse.cdt.debug.ui.memory.search/src/org/eclipse/cdt/debug/ui/memory/search/MemorySearchResult.java b/memory/org.eclipse.cdt.debug.ui.memory.search/src/org/eclipse/cdt/debug/ui/memory/search/MemorySearchResult.java
new file mode 100644
index 00000000000..2f1f52e5abd
--- /dev/null
+++ b/memory/org.eclipse.cdt.debug.ui.memory.search/src/org/eclipse/cdt/debug/ui/memory/search/MemorySearchResult.java
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * Copyright (c) 2007-2009 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Ted R Williams (Wind River Systems, Inc.) - initial implementation
+ *******************************************************************************/
+
+package org.eclipse.cdt.debug.ui.memory.search;
+
+import java.util.Enumeration;
+import java.util.Vector;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.search.ui.ISearchQuery;
+import org.eclipse.search.ui.ISearchResult;
+import org.eclipse.search.ui.ISearchResultListener;
+import org.eclipse.search.ui.SearchResultEvent;
+
+public class MemorySearchResult implements ISearchResult
+{
+ private ISearchQuery fQuery;
+ private String fLabel;
+
+ private Vector listeners = new Vector();
+
+ private Vector fMatches = new Vector();
+
+ public MemorySearchResult(ISearchQuery query, String label)
+ {
+ fQuery = query;
+ fLabel = label;
+ }
+
+ public ImageDescriptor getImageDescriptor() {
+
+ return null;
+ }
+
+ public String getLabel() {
+ return fLabel;
+ }
+
+ public ISearchQuery getQuery() {
+ return fQuery;
+ }
+
+ public String getTooltip() {
+
+ return fLabel;
+ }
+
+ public MemoryMatch[] getMatches()
+ {
+ MemoryMatch matches[] = new MemoryMatch[fMatches.size()];
+ for(int i = 0; i < matches.length; i++)
+ matches[i] = (MemoryMatch) fMatches.elementAt(i);
+ return matches;
+ }
+
+ public void addMatch(MemoryMatch address)
+ {
+ fMatches.addElement(address);
+ fireChange();
+ }
+
+ private void fireChange()
+ {
+ Enumeration en = listeners.elements();
+ while(en.hasMoreElements())
+ ((ISearchResultListener) en.nextElement()).searchResultChanged(new SearchResultEvent(this) {} );
+ }
+
+ public void addListener(ISearchResultListener l) {
+ listeners.addElement(l);
+
+ }
+
+ public void removeListener(ISearchResultListener l) {
+ listeners.removeElement(l);
+ }
+
+}
diff --git a/memory/org.eclipse.cdt.debug.ui.memory.search/src/org/eclipse/cdt/debug/ui/memory/search/MemorySearchResultsPage.java b/memory/org.eclipse.cdt.debug.ui.memory.search/src/org/eclipse/cdt/debug/ui/memory/search/MemorySearchResultsPage.java
new file mode 100644
index 00000000000..14706c447b2
--- /dev/null
+++ b/memory/org.eclipse.cdt.debug.ui.memory.search/src/org/eclipse/cdt/debug/ui/memory/search/MemorySearchResultsPage.java
@@ -0,0 +1,302 @@
+/*******************************************************************************
+ * Copyright (c) 2007-2009 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Ted R Williams (Wind River Systems, Inc.) - initial implementation
+ *******************************************************************************/
+
+package org.eclipse.cdt.debug.ui.memory.search;
+
+import java.lang.reflect.Method;
+import java.math.BigInteger;
+
+import org.eclipse.cdt.debug.ui.memory.search.FindReplaceDialog.IMemorySearchQuery;
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.ui.memory.IMemoryRendering;
+import org.eclipse.debug.ui.memory.IMemoryRenderingContainer;
+import org.eclipse.debug.ui.memory.IRepositionableMemoryRendering;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.search.ui.IQueryListener;
+import org.eclipse.search.ui.ISearchQuery;
+import org.eclipse.search.ui.ISearchResult;
+import org.eclipse.search.ui.ISearchResultListener;
+import org.eclipse.search.ui.ISearchResultPage;
+import org.eclipse.search.ui.ISearchResultViewPart;
+import org.eclipse.search.ui.NewSearchUI;
+import org.eclipse.search.ui.SearchResultEvent;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IMemento;
+import org.eclipse.ui.part.Page;
+import org.eclipse.ui.part.PageBook;
+
+public class MemorySearchResultsPage extends Page implements ISearchResultPage, IQueryListener {
+
+ private TreeViewer fTreeViewer;
+ private PageBook fPagebook;
+ private Composite fViewerContainer;
+ private IQueryListener fQueryListener;
+
+ private ISearchResultViewPart fPart;
+
+ public void queryAdded(ISearchQuery query) {
+
+ }
+
+ public void queryFinished(ISearchQuery query) {
+
+ }
+
+ public void queryRemoved(ISearchQuery query) {
+
+ }
+
+ public void queryStarting(ISearchQuery query) {
+
+ }
+
+ public String getID() {
+
+ return MemorySearchPlugin.getUniqueIdentifier();
+ }
+
+ public String getLabel() {
+ if(fQuery == null)
+ return Messages.getString("MemorySearchResultsPage.LabelMemorySearch"); //$NON-NLS-1$
+ else
+ return fQuery.getLabel();
+ }
+
+ public Object getUIState() {
+
+ return fTreeViewer.getSelection();
+ }
+
+ public void restoreState(IMemento memento) {
+
+
+ }
+
+ public void saveState(IMemento memento) {
+
+
+ }
+
+ public void setID(String id) {
+
+
+ }
+
+ public void setInput(ISearchResult search, Object uiState) {
+ if(search instanceof MemorySearchResult)
+ ((MemorySearchResult) search).addListener(new ISearchResultListener()
+ {
+
+ public void searchResultChanged(SearchResultEvent e) {
+ Display.getDefault().asyncExec(new Runnable() {
+ public void run()
+ {
+ fTreeViewer.refresh();
+ }
+ });
+
+ }
+
+ });
+
+ }
+
+ public void setViewPart(ISearchResultViewPart part) {
+ fPart = part;
+ }
+
+ public void createControl(Composite parent) {
+ fViewerContainer = new Composite(parent, SWT.NULL);
+ fViewerContainer.setLayoutData(new GridData(GridData.FILL_BOTH));
+ fViewerContainer.setSize(100, 100);
+ fViewerContainer.setLayout(new FillLayout());
+
+ fTreeViewer = new TreeViewer(fViewerContainer, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
+
+ fTreeViewer.setContentProvider(new ITreeContentProvider() {
+
+ public void dispose() {
+
+
+ }
+
+ public void inputChanged(Viewer viewer, Object oldInput,
+ Object newInput) {
+ viewer.refresh();
+ }
+
+ public Object[] getChildren(Object parentElement) {
+ return new Object[0];
+ }
+
+ public Object getParent(Object element) {
+ return null;
+ }
+
+ public boolean hasChildren(Object element) {
+ return false;
+ }
+
+ public Object[] getElements(Object inputElement) {
+
+ if(fQuery == null)
+ return new Object[0];
+ else
+ {
+ return ((MemorySearchResult) fQuery.getSearchResult()).getMatches();
+ }
+ }
+
+ });
+
+ fTreeViewer.setInput(new Object());
+ fTreeViewer.addSelectionChangedListener(new ISelectionChangedListener(){
+
+ public void selectionChanged(final SelectionChangedEvent event) {
+ if( event.getSelection() instanceof StructuredSelection)
+ {
+ IMemoryRenderingContainer containers[] = ((IMemorySearchQuery) fQuery).getMemoryView().getMemoryRenderingContainers();
+ MemoryMatch match = (MemoryMatch) ((StructuredSelection) event.getSelection()).getFirstElement();
+ for(int i = 0; i < containers.length; i++)
+ {
+ IMemoryRendering rendering = containers[i].getActiveRendering();
+ if(rendering instanceof IRepositionableMemoryRendering)
+ {
+ try {
+ ((IRepositionableMemoryRendering) rendering).goToAddress(match.getStartAddress());
+ } catch (DebugException e) {
+ MemorySearchPlugin.logError(Messages.getString("MemorySearchResultsPage.RepositioningMemoryViewFailed"), e); //$NON-NLS-1$
+ }
+ }
+
+ if(rendering != null)
+ {
+ // Temporary, until platform accepts/adds new interface for setting the selection
+ try {
+ Method m = rendering.getClass().getMethod("setSelection", new Class[] { BigInteger.class, BigInteger.class } ); //$NON-NLS-1$
+ if(m != null)
+ m.invoke(rendering, match.getStartAddress(), match.getEndAddress());
+ } catch (Exception e) {
+ // do nothing
+ }
+ }
+ }
+ }
+ }
+
+ });
+ fTreeViewer.setLabelProvider(new ILabelProvider() {
+
+ public Image getImage(Object element) {
+
+ return null;
+ }
+
+ public String getText(Object element) {
+ if(element instanceof MemoryMatch)
+ return "0x" + ((MemoryMatch) element).getStartAddress().toString(16); //$NON-NLS-1$
+
+ return element.toString();
+ }
+
+ public void addListener(ILabelProviderListener listener) {
+
+
+ }
+
+ public void dispose() {
+
+
+ }
+
+ public boolean isLabelProperty(Object element, String property) {
+
+ return false;
+ }
+
+ public void removeListener(ILabelProviderListener listener) {
+
+
+ }
+
+ });
+
+ fQueryListener = createQueryListener();
+
+ NewSearchUI.addQueryListener(fQueryListener);
+ }
+
+ private ISearchQuery fQuery;
+
+ private IQueryListener createQueryListener() {
+ return new IQueryListener() {
+ public void queryAdded(ISearchQuery query) {
+ // ignore
+ }
+
+ public void queryRemoved(ISearchQuery query) {
+ queryStarting(query);
+ }
+
+ public void queryStarting(final ISearchQuery query) {
+ fQuery = query;
+
+ Display.getDefault().asyncExec(new Runnable() {
+ public void run()
+ {
+ fPart.updateLabel();
+
+ if(!fTreeViewer.getControl().isDisposed())
+ fTreeViewer.refresh();
+ }
+ });
+ }
+
+ public void queryFinished(final ISearchQuery query) {
+
+ }
+ };
+ }
+
+ public void dispose() {
+ fTreeViewer.getControl().dispose();
+ fViewerContainer.dispose();
+ }
+
+ public Control getControl() {
+ return fViewerContainer;
+ }
+
+ public void setActionBars(IActionBars actionBars) {
+
+
+ }
+
+ public void setFocus() {
+
+
+ }
+
+}
diff --git a/memory/org.eclipse.cdt.debug.ui.memory.search/src/org/eclipse/cdt/debug/ui/memory/search/Messages.java b/memory/org.eclipse.cdt.debug.ui.memory.search/src/org/eclipse/cdt/debug/ui/memory/search/Messages.java
new file mode 100644
index 00000000000..915c0905605
--- /dev/null
+++ b/memory/org.eclipse.cdt.debug.ui.memory.search/src/org/eclipse/cdt/debug/ui/memory/search/Messages.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2007-2009 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Ted R Williams (Wind River Systems, Inc.) - initial implementation
+ *******************************************************************************/
+
+package org.eclipse.cdt.debug.ui.memory.search;
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class Messages {
+ private static final String BUNDLE_NAME = "org.eclipse.cdt.debug.ui.memory.search.messages"; //$NON-NLS-1$
+
+ private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle
+ .getBundle(BUNDLE_NAME);
+
+ private Messages() {
+ }
+
+ public static String getString(String key) {
+ try {
+ return RESOURCE_BUNDLE.getString(key);
+ } catch (MissingResourceException e) {
+ return '!' + key + '!';
+ }
+ }
+}
diff --git a/memory/org.eclipse.cdt.debug.ui.memory.search/src/org/eclipse/cdt/debug/ui/memory/search/messages.properties b/memory/org.eclipse.cdt.debug.ui.memory.search/src/org/eclipse/cdt/debug/ui/memory/search/messages.properties
new file mode 100644
index 00000000000..e6a16833af8
--- /dev/null
+++ b/memory/org.eclipse.cdt.debug.ui.memory.search/src/org/eclipse/cdt/debug/ui/memory/search/messages.properties
@@ -0,0 +1,31 @@
+FindReplaceDialog.Title=Find / Replace Memory
+FindReplaceDialog.ButtonFind=Find
+FindReplaceDialog.ButtonFindAll=Find All
+FindReplaceDialog.ButtonReplaceFind=Replace/Find
+FindReplaceDialog.ButtonReplace=Replace
+FindReplaceDialog.ButtonReplaceAll=Replace All
+FindReplaceDialog.Close=Close
+FindReplaceDialog.LabelFind=Find:
+FindReplaceDialog.LabelReplaceWith=Replace With:
+FindReplaceDialog.LabelDirection=Direction
+FindReplaceDialog.ButtonForward=Forward
+FindReplaceDialog.ButtonBackward=Backward
+FindReplaceDialog.LabelRange=Range
+FindReplaceDialog.LabelStartAddress=Start address:
+FindReplaceDialog.LabelEndAddress=End address:
+FindReplaceDialog.LabelFormat=Format
+FindReplaceDialog.ButtonASCII=ASCII String
+FindReplaceDialog.ButtonHexadecimal=Hexadecimal
+FindReplaceDialog.ButtonOctal=Octal
+FindReplaceDialog.ButtonBinary=Binary
+FindReplaceDialog.ButtonDecimal=Decimal
+FindReplaceDialog.ButtonByteSequence=Byte Sequence
+FindReplaceDialog.LabelOptions=Options
+FindReplaceDialog.ButtonWrapSearch=Wrap Search
+FindReplaceDialog.ButtonCaseInsensitive=Case Insensitive
+FindReplaceDialog.MemoryReadFailed=Memory Read Failed
+FindReplaceDialog.MemorySearchFailure=Memory Search Failure
+FindReplaceDialog.RepositioningMemoryViewFailed=Repositioning Memory View Failed
+FindReplaceDialog.SearchingMemoryFor=Searching memory for
+MemorySearchResultsPage.LabelMemorySearch=Memory Search
+MemorySearchResultsPage.RepositioningMemoryViewFailed=Repositioning Memory View Failed
diff --git a/memory/org.eclipse.cdt.debug.ui.memory.traditional/.classpath b/memory/org.eclipse.cdt.debug.ui.memory.traditional/.classpath
new file mode 100644
index 00000000000..751c8f2e504
--- /dev/null
+++ b/memory/org.eclipse.cdt.debug.ui.memory.traditional/.classpath
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/memory/org.eclipse.cdt.debug.ui.memory.traditional/.project b/memory/org.eclipse.cdt.debug.ui.memory.traditional/.project
new file mode 100644
index 00000000000..5777fb24f47
--- /dev/null
+++ b/memory/org.eclipse.cdt.debug.ui.memory.traditional/.project
@@ -0,0 +1,28 @@
+
+
+ org.eclipse.cdt.debug.ui.memory.traditional
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.pde.ManifestBuilder
+
+
+
+
+ org.eclipse.pde.SchemaBuilder
+
+
+
+
+
+ org.eclipse.pde.PluginNature
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/memory/org.eclipse.cdt.debug.ui.memory.traditional/META-INF/MANIFEST.MF b/memory/org.eclipse.cdt.debug.ui.memory.traditional/META-INF/MANIFEST.MF
new file mode 100644
index 00000000000..efca372f9e2
--- /dev/null
+++ b/memory/org.eclipse.cdt.debug.ui.memory.traditional/META-INF/MANIFEST.MF
@@ -0,0 +1,16 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Traditional Memory Rendering
+Bundle-SymbolicName: org.eclipse.cdt.debug.ui.memory.traditional;singleton:=true
+Bundle-Version: 1.1.0.qualifier
+Bundle-Localization: plugin
+Require-Bundle: org.eclipse.debug.core,
+ org.eclipse.debug.ui,
+ org.eclipse.core.runtime,
+ org.eclipse.swt,
+ org.eclipse.jface,
+ org.eclipse.ui,
+ org.eclipse.search;bundle-version="3.4.0"
+Eclipse-LazyStart: true
+Bundle-Activator: org.eclipse.cdt.debug.ui.memory.traditional.TraditionalRenderingPlugin
+Bundle-Vendor: Eclipse.org
diff --git a/memory/org.eclipse.cdt.debug.ui.memory.traditional/about.html b/memory/org.eclipse.cdt.debug.ui.memory.traditional/about.html
new file mode 100644
index 00000000000..cb740ae8bc8
--- /dev/null
+++ b/memory/org.eclipse.cdt.debug.ui.memory.traditional/about.html
@@ -0,0 +1,24 @@
+
+
+
+
+About
+About This Content
+
+June 5, 2007
+License
+
+The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available
+at http://www.eclipse.org/legal/epl-v10.html.
+For purposes of the EPL, "Program" will mean the Content.
+
+If you did not receive this Content directly from the Eclipse Foundation, the Content is
+being redistributed by another party ("Redistributor") and different terms and conditions may
+apply to your use of any object code in the Content. Check the Redistributor's license that was
+provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at http://www.eclipse.org.
+
+
\ No newline at end of file
diff --git a/memory/org.eclipse.cdt.debug.ui.memory.traditional/build.properties b/memory/org.eclipse.cdt.debug.ui.memory.traditional/build.properties
new file mode 100644
index 00000000000..bbc45d3cdc8
--- /dev/null
+++ b/memory/org.eclipse.cdt.debug.ui.memory.traditional/build.properties
@@ -0,0 +1,9 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ plugin.properties,\
+ .,\
+ plugin.xml,\
+ about.html,\
+ icons/
+
diff --git a/memory/org.eclipse.cdt.debug.ui.memory.traditional/plugin.properties b/memory/org.eclipse.cdt.debug.ui.memory.traditional/plugin.properties
new file mode 100644
index 00000000000..3f960bac63c
--- /dev/null
+++ b/memory/org.eclipse.cdt.debug.ui.memory.traditional/plugin.properties
@@ -0,0 +1 @@
+TraditionalRenderingPreferenceActionName=Traditional Rendering Preferences...
\ No newline at end of file
diff --git a/memory/org.eclipse.cdt.debug.ui.memory.traditional/plugin.xml b/memory/org.eclipse.cdt.debug.ui.memory.traditional/plugin.xml
new file mode 100644
index 00000000000..9db0d7c8060
--- /dev/null
+++ b/memory/org.eclipse.cdt.debug.ui.memory.traditional/plugin.xml
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/AbstractPane.java b/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/AbstractPane.java
new file mode 100644
index 00000000000..59ee0cda2a4
--- /dev/null
+++ b/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/AbstractPane.java
@@ -0,0 +1,759 @@
+/*******************************************************************************
+ * Copyright (c) 2006-2009 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Ted R Williams (Wind River Systems, Inc.) - initial implementation
+ *******************************************************************************/
+
+package org.eclipse.cdt.debug.ui.memory.traditional;
+
+import java.math.BigInteger;
+
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.core.model.MemoryByte;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.dnd.DND;
+import org.eclipse.swt.events.FocusEvent;
+import org.eclipse.swt.events.FocusListener;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.events.MouseMoveListener;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.FontMetrics;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Canvas;
+import org.eclipse.swt.widgets.Caret;
+
+public abstract class AbstractPane extends Canvas
+{
+ protected Rendering fRendering;
+
+ // selection state
+ protected boolean fSelectionStarted = false;
+ protected boolean fSelectionInProgress = false;
+
+ protected BigInteger fSelectionStartAddress = null;
+
+ protected int fSelectionStartAddressSubPosition;
+
+ // caret
+ protected Caret fCaret = null;
+
+ // character may not fall on byte boundary
+ protected int fSubCellCaretPosition = 0;
+ protected int fOldSubCellCaretPosition = 0;
+
+ protected boolean fCaretEnabled = false;
+
+ protected BigInteger fCaretAddress = null;
+
+ // storage
+ protected int fRowCount = 0;
+
+ protected boolean fPaneVisible = true;
+
+ class AbstractPaneMouseListener implements MouseListener
+ {
+ public void mouseUp(MouseEvent me)
+ {
+ positionCaret(me.x, me.y);
+
+ fCaret.setVisible(true);
+
+ if(fSelectionInProgress && me.button == 1)
+ {
+ endSelection(me.x, me.y);
+ }
+
+ fSelectionInProgress = fSelectionStarted = false;
+ }
+
+ public void mouseDown(MouseEvent me)
+ {
+ AbstractPane.this.forceFocus();
+
+ positionCaret(me.x, me.y);
+
+ fCaret.setVisible(false);
+
+ if(me.button == 1)
+ {
+ // if shift is down and we have an existing start address,
+ // append selection
+ if((me.stateMask & SWT.SHIFT) != 0
+ && fRendering.getSelection().getStart() != null)
+ {
+
+ // if the pane doesn't have a selection start (the
+ // selection was created in a different pane)
+ // then initialize the pane's selection start to the
+ // rendering's selection start
+ if(AbstractPane.this.fSelectionStartAddress == null)
+ AbstractPane.this.fSelectionStartAddress = fRendering
+ .getSelection().getStart();
+
+ AbstractPane.this.fSelectionStarted = true;
+
+ AbstractPane.this.appendSelection(me.x, me.y);
+
+ }
+ else
+ {
+ // start a new selection
+
+ AbstractPane.this.startSelection(me.x, me.y);
+ }
+ }
+ }
+
+ public void mouseDoubleClick(MouseEvent me)
+ {
+ handleMouseDoubleClick(me);
+ }
+
+ }
+
+ class AbstractPaneMouseMoveListener implements MouseMoveListener
+ {
+ public void mouseMove(MouseEvent me)
+ {
+ if(fSelectionStarted)
+ {
+ fSelectionInProgress = true;
+ appendSelection(me.x, me.y);
+ }
+ }
+ }
+
+ class AbstractPaneKeyListener implements KeyListener
+ {
+ public void keyPressed(KeyEvent ke)
+ {
+ fOldSubCellCaretPosition = fSubCellCaretPosition;
+ if((ke.stateMask & SWT.SHIFT) != 0)
+ {
+ switch(ke.keyCode)
+ {
+ case SWT.ARROW_RIGHT:
+ case SWT.ARROW_LEFT:
+ case SWT.ARROW_UP:
+ case SWT.ARROW_DOWN:
+ case SWT.PAGE_DOWN:
+ case SWT.PAGE_UP:
+ if(fRendering.getSelection().getStart() == null)
+ {
+ fRendering.getSelection().setStart(fCaretAddress.add(BigInteger.valueOf(
+ fRendering.getAddressesPerColumn())), fCaretAddress);
+ }
+ break;
+ }
+ }
+
+ if(ke.keyCode == SWT.ARROW_RIGHT)
+ {
+ handleRightArrowKey();
+ }
+ else if(ke.keyCode == SWT.ARROW_LEFT || ke.keyCode == SWT.BS)
+ {
+ handleLeftArrowKey();
+ }
+ else if(ke.keyCode == SWT.ARROW_DOWN)
+ {
+ handleDownArrowKey();
+ }
+ else if(ke.keyCode == SWT.ARROW_UP)
+ {
+ handleUpArrowKey();
+ }
+ else if(ke.keyCode == SWT.PAGE_DOWN)
+ {
+ handlePageDownKey();
+ }
+ else if(ke.keyCode == SWT.PAGE_UP)
+ {
+ handlePageUpKey();
+ }
+ else if(ke.keyCode == SWT.ESC)
+ {
+ fRendering.getViewportCache().clearEditBuffer();
+ }
+ else if(ke.character == '\r')
+ {
+ fRendering.getViewportCache().writeEditBuffer();
+ }
+ else if(Rendering.isValidEditCharacter(ke.character))
+ {
+ if(fRendering.getSelection().hasSelection())
+ {
+ setCaretAddress(fRendering.getSelection().getLow());
+ fSubCellCaretPosition = 0;
+ }
+
+ editCell(fCaretAddress, fSubCellCaretPosition, ke.character);
+ }
+
+ if((ke.stateMask & SWT.SHIFT) != 0)
+ {
+ switch(ke.keyCode)
+ {
+ case SWT.ARROW_RIGHT:
+ case SWT.ARROW_LEFT:
+ case SWT.ARROW_UP:
+ case SWT.ARROW_DOWN:
+ case SWT.PAGE_DOWN:
+ case SWT.PAGE_UP:
+ fRendering.getSelection().setEnd(fCaretAddress.add(BigInteger.valueOf(
+ fRendering.getAddressesPerColumn())),
+ fCaretAddress);
+ break;
+ }
+ }
+ else if(ke.keyCode != SWT.SHIFT)
+ // if shift key, keep selection, we might add to it
+ {
+ fRendering.getSelection().clear();
+ }
+ }
+
+ public void keyReleased(KeyEvent ke)
+ {
+ // do nothing
+ }
+ }
+
+ class AbstractPanePaintListener implements PaintListener
+ {
+ public void paintControl(PaintEvent pe)
+ {
+ AbstractPane.this.paint(pe);
+ }
+ }
+
+ public AbstractPane(Rendering rendering)
+ {
+ super(rendering, SWT.DOUBLE_BUFFERED);
+
+ fRendering = rendering;
+
+ try
+ {
+ fCaretAddress = rendering.getBigBaseAddress();
+ }
+ catch(Exception e)
+ {
+ // do nothing
+ }
+
+ // pref
+
+ this.setFont(fRendering.getFont());
+
+ GC gc = new GC(this);
+ gc.setFont(this.getFont());
+ fCaret = new Caret(this, SWT.NONE);
+ fCaret.setSize(1, gc.stringExtent("|").y); //$NON-NLS-1$
+ gc.dispose();
+
+ this.addPaintListener(createPaintListener());
+
+ this.addMouseListener(createMouseListener());
+
+ this.addMouseMoveListener(createMouseMoveListener());
+
+ this.addKeyListener(createKeyListener());
+
+ this.addFocusListener(new FocusListener()
+ {
+ public void focusLost(FocusEvent fe)
+ {
+ IPreferenceStore store = TraditionalRenderingPlugin.getDefault().getPreferenceStore();
+ if(TraditionalRenderingPreferenceConstants.MEM_EDIT_BUFFER_SAVE_ON_ENTER_ONLY
+ .equals(store.getString(TraditionalRenderingPreferenceConstants.MEM_EDIT_BUFFER_SAVE)))
+ {
+ fRendering.getViewportCache().clearEditBuffer();
+ }
+ else
+ {
+ fRendering.getViewportCache().writeEditBuffer();
+ }
+
+ // clear the pane local selection start
+ AbstractPane.this.fSelectionStartAddress = null;
+ }
+
+ public void focusGained(FocusEvent fe)
+ {
+ }
+ });
+ }
+
+ protected MouseListener createMouseListener(){
+ return new AbstractPaneMouseListener();
+ }
+
+ protected MouseMoveListener createMouseMoveListener(){
+ return new AbstractPaneMouseMoveListener();
+ }
+
+ protected KeyListener createKeyListener(){
+ return new AbstractPaneKeyListener();
+ }
+
+ protected PaintListener createPaintListener(){
+ return new AbstractPanePaintListener();
+ }
+
+ protected void handleRightArrowKey()
+ {
+ fSubCellCaretPosition++;
+ if(fSubCellCaretPosition >= getCellCharacterCount())
+ {
+ fSubCellCaretPosition = 0;
+ // Ensure that caret is within the addressable range
+ BigInteger newCaretAddress = fCaretAddress.add(BigInteger
+ .valueOf(getNumberOfBytesRepresentedByColumn() / fRendering.getAddressableSize()));
+ if(newCaretAddress.compareTo(fRendering.getMemoryBlockEndAddress()) > 0)
+ {
+ fSubCellCaretPosition = getCellCharacterCount();
+ }
+ else
+ {
+ setCaretAddress(newCaretAddress);
+ }
+ }
+ updateCaret();
+ ensureCaretWithinViewport();
+ }
+
+ protected void handleLeftArrowKey()
+ {
+ fSubCellCaretPosition--;
+ if(fSubCellCaretPosition < 0)
+ {
+ fSubCellCaretPosition = getCellCharacterCount() - 1;
+ // Ensure that caret is within the addressable range
+ BigInteger newCaretAddress = fCaretAddress.subtract(BigInteger
+ .valueOf(getNumberOfBytesRepresentedByColumn() / fRendering.getAddressableSize()));
+ if(newCaretAddress.compareTo(fRendering.getMemoryBlockStartAddress()) < 0)
+ {
+ fSubCellCaretPosition = 0;
+ }
+ else
+ {
+ setCaretAddress(newCaretAddress);
+ }
+
+ }
+ updateCaret();
+ ensureCaretWithinViewport();
+ }
+
+ protected void handleDownArrowKey()
+ {
+ // Ensure that caret is within the addressable range
+ BigInteger newCaretAddress = fCaretAddress.add(BigInteger
+ .valueOf(fRendering.getAddressableCellsPerRow()));
+ setCaretAddress(newCaretAddress);
+
+ updateCaret();
+ ensureCaretWithinViewport();
+ }
+
+ protected void handleUpArrowKey()
+ {
+ // Ensure that caret is within the addressable range
+ BigInteger newCaretAddress = fCaretAddress.subtract(BigInteger
+ .valueOf(fRendering.getAddressableCellsPerRow()));
+ setCaretAddress(newCaretAddress);
+
+ updateCaret();
+ ensureCaretWithinViewport();
+ }
+
+ protected void handlePageDownKey()
+ {
+ // Ensure that caret is within the addressable range
+ BigInteger newCaretAddress = fCaretAddress.add(BigInteger
+ .valueOf(fRendering.getAddressableCellsPerRow()
+ * (fRendering.getRowCount() - 1)));
+
+ setCaretAddress(newCaretAddress);
+
+ updateCaret();
+ ensureCaretWithinViewport();
+ }
+
+ protected void handlePageUpKey()
+ {
+ // Ensure that caret is within the addressable range
+ BigInteger newCaretAddress = fCaretAddress.subtract(BigInteger
+ .valueOf(fRendering.getAddressableCellsPerRow()
+ * (fRendering.getRowCount() - 1)));
+ setCaretAddress(newCaretAddress);
+
+ updateCaret();
+ ensureCaretWithinViewport();
+ }
+
+ protected void handleMouseDoubleClick(MouseEvent me)
+ {
+ try
+ {
+ BigInteger address = getViewportAddress(me.x / getCellWidth(), me.y
+ / getCellHeight());
+
+ fRendering.getSelection().clear();
+ fRendering.getSelection().setStart(address.add(BigInteger
+ .valueOf(fRendering.getAddressesPerColumn())), address);
+ fRendering.getSelection().setEnd(address.add(BigInteger
+ .valueOf(fRendering.getAddressesPerColumn())), address);
+ }
+ catch(DebugException de)
+ {
+ // do nothing
+ }
+ }
+
+ protected boolean isPaneVisible()
+ {
+ return fPaneVisible;
+ }
+
+ protected void setPaneVisible(boolean visible)
+ {
+ fPaneVisible = visible;
+ this.setVisible(visible);
+ }
+
+ protected int getNumberOfBytesRepresentedByColumn()
+ {
+ return fRendering.getBytesPerColumn();
+ }
+
+ protected void editCell(BigInteger address, int subCellPosition,
+ char character)
+ {
+ // do nothing
+ }
+
+ // Set the caret address
+ protected void setCaretAddress(BigInteger caretAddress)
+ {
+ // Ensure that caret is within the addressable range
+ if((caretAddress.compareTo(fRendering.getMemoryBlockStartAddress()) >= 0) &&
+ (caretAddress.compareTo(fRendering.getMemoryBlockEndAddress()) <= 0))
+ {
+ fCaretAddress = caretAddress;
+ }
+ else if(caretAddress.compareTo(fRendering.getMemoryBlockStartAddress()) < 0)
+ {
+ // calculate offset from the beginning of the row
+ int cellOffset = fCaretAddress.subtract(fRendering.getViewportStartAddress()).intValue();
+ int row = cellOffset / (fRendering.getBytesPerRow() / fRendering.getBytesPerCharacter());
+
+ cellOffset -= row * fRendering.getBytesPerRow() / fRendering.getBytesPerCharacter();
+
+ fCaretAddress = fRendering.getMemoryBlockStartAddress().add(
+ BigInteger.valueOf(cellOffset / fRendering.getAddressableSize()));
+ }
+ else if(caretAddress.compareTo(fRendering.getMemoryBlockEndAddress()) > 0)
+ {
+ // calculate offset from the end of the row
+ int cellOffset = fCaretAddress.subtract(fRendering.getViewportEndAddress()).intValue() + 1;
+ int row = cellOffset / (fRendering.getBytesPerRow() / fRendering.getBytesPerCharacter());
+
+ cellOffset -= row * fRendering.getBytesPerRow()/ fRendering.getBytesPerCharacter();
+
+ fCaretAddress = fRendering.getMemoryBlockEndAddress().add(
+ BigInteger.valueOf(cellOffset / fRendering.getAddressableSize()));
+ }
+
+ fRendering.setCaretAddress(fCaretAddress);
+ }
+
+ protected boolean isOdd(int value)
+ {
+ return (value / 2) * 2 == value;
+ }
+
+ protected void updateCaret()
+ {
+ try
+ {
+ if(fCaretAddress != null)
+ {
+ Point cellPosition = getCellLocation(fCaretAddress);
+ if(cellPosition != null)
+ {
+ fCaret.setLocation(cellPosition.x + fSubCellCaretPosition
+ * getCellCharacterWidth(), cellPosition.y);
+ }
+ }
+ }
+ catch(Exception e)
+ {
+ fRendering
+ .logError(
+ TraditionalRenderingMessages
+ .getString("TraditionalRendering.FAILURE_POSITION_CURSOR"), e); //$NON-NLS-1$
+ }
+ }
+
+ protected void ensureCaretWithinViewport() // TODO getAddressableSize() > 1 ?
+ {
+ // determine if caret is before the viewport start
+ // if so, scroll viewport up by appropriate rows
+ if(fCaretAddress.compareTo(fRendering.getViewportStartAddress()) < 0)
+ {
+ BigInteger difference = fRendering.getViewportStartAddress()
+ .subtract(fCaretAddress);
+ BigInteger rows = difference.divide(BigInteger.valueOf(fRendering.getBytesPerRow()));
+ if(rows.multiply(
+ BigInteger.valueOf(fRendering.getBytesPerRow())).compareTo(difference) != 0)
+ rows = rows.add(BigInteger.valueOf(1));
+
+ fRendering.setViewportStartAddress(fRendering.getViewportStartAddress()
+ .subtract(rows.multiply(BigInteger.valueOf(fRendering.getBytesPerRow()))));
+ fRendering.ensureViewportAddressDisplayable();
+ fRendering.gotoAddress(fRendering.getViewportStartAddress());
+ }
+ // determine if caret is after the viewport end
+ // if so, scroll viewport down by appropriate rows
+ else if(fCaretAddress.compareTo(fRendering.getViewportEndAddress()) >= 0)
+ {
+ BigInteger difference = fCaretAddress.subtract(fRendering
+ .getViewportEndAddress().subtract(BigInteger.valueOf(1)));
+ BigInteger rows = difference.divide(BigInteger.valueOf(fRendering.getBytesPerRow()));
+ if(rows.multiply(
+ BigInteger.valueOf(fRendering.getBytesPerRow())).compareTo(difference) != 0)
+ rows = rows.add(BigInteger.valueOf(1));
+
+ fRendering.setViewportStartAddress(fRendering.getViewportStartAddress().add(
+ rows.multiply(BigInteger.valueOf(fRendering.getBytesPerRow()))));
+ fRendering.ensureViewportAddressDisplayable();
+ fRendering.gotoAddress(fRendering.getViewportStartAddress());
+ }
+
+ fRendering.setCaretAddress(fCaretAddress);
+ }
+
+ protected void advanceCursor()
+ {
+ fSubCellCaretPosition++;
+ if(fSubCellCaretPosition >= getCellCharacterCount())
+ {
+ fSubCellCaretPosition = 0;
+ fCaretAddress = fCaretAddress.add(BigInteger
+ .valueOf(getNumberOfBytesRepresentedByColumn() / fRendering.getAddressableSize()));
+
+ }
+ updateCaret();
+ ensureCaretWithinViewport();
+ }
+
+ protected void positionCaret(int x, int y)
+ {
+ // do nothing
+ }
+
+ protected int getRowCount()
+ {
+ return fRowCount;
+ }
+
+ protected void setRowCount()
+ {
+ fRowCount = getBounds().height / getCellHeight();
+ }
+
+ protected void settingsChanged()
+ {
+ fSubCellCaretPosition = 0;
+ }
+
+ protected void startSelection(int x, int y)
+ {
+ try
+ {
+ BigInteger address = getViewportAddress(x / getCellWidth(), y
+ / getCellHeight());
+
+ if(address != null)
+ {
+ this.fSelectionStartAddress = address;
+ Point cellPosition = getCellLocation(address);
+
+ if(cellPosition != null)
+ {
+ int offset = x - cellPosition.x;
+ fSelectionStartAddressSubPosition = offset
+ / getCellCharacterWidth();
+ }
+ fRendering.getSelection().clear();
+ fRendering.getSelection().setStart(address.add(BigInteger.valueOf(
+ fRendering.getBytesPerColumn() / fRendering.getAddressableSize())), address);
+
+ fSelectionStarted = true;
+
+ new CopyAction(fRendering, DND.SELECTION_CLIPBOARD).run();
+ }
+ }
+ catch(DebugException e)
+ {
+ fRendering
+ .logError(
+ TraditionalRenderingMessages
+ .getString("TraditionalRendering.FAILURE_START_SELECTION"), e); //$NON-NLS-1$
+ }
+ }
+
+ protected void endSelection(int x, int y)
+ {
+ appendSelection(x, y);
+
+ fSelectionInProgress = false;
+ }
+
+ protected void appendSelection(int x, int y)
+ {
+ try
+ {
+ if(this.fSelectionStartAddress == null)
+ return;
+
+ BigInteger address = getViewportAddress(x / getCellWidth(), y
+ / getCellHeight());
+
+ if(address.compareTo(this.fSelectionStartAddress) == 0)
+ {
+ // deal with sub cell selection
+ Point cellPosition = getCellLocation(address);
+ int offset = x - cellPosition.x;
+ int subCellCharacterPosition = offset / getCellCharacterWidth();
+
+ if(Math.abs(subCellCharacterPosition
+ - this.fSelectionStartAddressSubPosition) > this
+ .getCellCharacterCount() / 4)
+ {
+ fRendering.getSelection().setEnd(address.add(BigInteger
+ .valueOf(fRendering.getAddressesPerColumn())), address);
+ }
+ else
+ {
+ fRendering.getSelection().setEnd(null, null);
+ }
+ }
+ else
+ {
+ fRendering.getSelection().setEnd(address.add(BigInteger
+ .valueOf(fRendering.getAddressesPerColumn())), address);
+ }
+
+ if(fRendering.getSelection().getEnd() != null)
+ {
+ this.fCaretAddress = fRendering.getSelection().getEnd();
+ this.fSubCellCaretPosition = 0;
+ }
+
+ updateCaret();
+
+ new CopyAction(fRendering, DND.SELECTION_CLIPBOARD).run();
+ }
+ catch(DebugException e)
+ {
+ fRendering
+ .logError(
+ TraditionalRenderingMessages
+ .getString("TraditionalRendering.FAILURE_APPEND_SELECTION"), e); //$NON-NLS-1$
+ }
+ }
+
+ protected void paint(PaintEvent pe)
+ {
+ fRowCount = getBounds().height / getCellHeight();
+
+ if(fRendering.isDirty())
+ {
+ fRendering.setDirty(false);
+ fRendering.refresh();
+ }
+ }
+
+ abstract protected BigInteger getViewportAddress(int col, int row)
+ throws DebugException;
+
+ protected Point getCellLocation(BigInteger address)
+ {
+ return null;
+ }
+
+ protected String getCellText(MemoryByte bytes[])
+ {
+ return null;
+ }
+
+ abstract protected int getCellWidth();
+
+ abstract protected int getCellCharacterCount();
+
+ public void setFont(Font font)
+ {
+ super.setFont(font);
+ fCharacterWidth = -1;
+ fCellHeight = -1;
+ fTextHeight = -1;
+ }
+
+ private int fCellHeight = -1; // called often, cache
+
+ protected int getCellHeight()
+ {
+ if(fCellHeight == -1)
+ {
+ fCellHeight = getCellTextHeight()
+ + (fRendering.getCellPadding() * 2);
+ }
+
+ return fCellHeight;
+ }
+
+ private int fCharacterWidth = -1; // called often, cache
+
+ protected int getCellCharacterWidth()
+ {
+ if(fCharacterWidth == -1)
+ {
+ GC gc = new GC(this);
+ gc.setFont(fRendering.getFont());
+ fCharacterWidth = gc.getAdvanceWidth('F');
+ gc.dispose();
+ }
+
+ return fCharacterWidth;
+ }
+
+ private int fTextHeight = -1; // called often, cache
+
+ protected int getCellTextHeight()
+ {
+ if(fTextHeight == -1)
+ {
+ GC gc = new GC(this);
+ gc.setFont(fRendering.getFont());
+ FontMetrics fontMetrics = gc.getFontMetrics();
+ fTextHeight = fontMetrics.getHeight();
+ gc.dispose();
+ }
+ return fTextHeight;
+ }
+}
diff --git a/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/AddressPane.java b/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/AddressPane.java
new file mode 100644
index 00000000000..afb20eaa404
--- /dev/null
+++ b/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/AddressPane.java
@@ -0,0 +1,256 @@
+/*******************************************************************************
+ * Copyright (c) 2006-2009 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Ted R Williams (Wind River Systems, Inc.) - initial implementation
+ *******************************************************************************/
+
+package org.eclipse.cdt.debug.ui.memory.traditional;
+
+import java.math.BigInteger;
+
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.graphics.FontMetrics;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Point;
+
+public class AddressPane extends AbstractPane
+{
+ public AddressPane(Rendering parent)
+ {
+ super(parent);
+ }
+
+ protected BigInteger getViewportAddress(int col, int row)
+ throws DebugException
+ {
+ BigInteger address = fRendering.getViewportStartAddress();
+ address = address.add(BigInteger.valueOf((row
+ * fRendering.getColumnCount() + col)
+ * fRendering.getAddressesPerColumn()));
+
+ return address;
+ }
+
+ protected void appendSelection(int x, int y)
+ {
+ try
+ {
+ if(this.fSelectionStartAddress == null)
+ return;
+
+ BigInteger address = getViewportAddress(x / getCellWidth(), y
+ / getCellHeight());
+
+ if(address.compareTo(this.fSelectionStartAddress) == 0)
+ {
+ fRendering.getSelection().setEnd(null, null);
+ }
+ else
+ {
+ fRendering.getSelection().setEnd(address.add(BigInteger
+ .valueOf(fRendering.getAddressesPerColumn() * fRendering.getColumnCount())), address);
+ }
+ }
+ catch(DebugException e)
+ {
+ fRendering
+ .logError(
+ TraditionalRenderingMessages
+ .getString("TraditionalRendering.FAILURE_APPEND_SELECTION"), e); //$NON-NLS-1$
+ }
+ }
+
+ public Point computeSize(int wHint, int hHint)
+ {
+ return new Point(getCellWidth() + fRendering.getRenderSpacing(), 100);
+ }
+
+ protected int getCellCharacterCount()
+ {
+ // two characters per byte of hex address
+
+ return fRendering.getAddressBytes() * 2
+ + 2; // 0x
+ }
+
+ protected int getCellWidth()
+ {
+ GC gc = new GC(this);
+ StringBuffer buf = new StringBuffer();
+ for(int i = 0; i < getCellCharacterCount(); i++)
+ buf.append("0");
+ int width = gc.textExtent(buf.toString()).x;
+ gc.dispose();
+ return width;
+ }
+
+ private int getColumnCount()
+ {
+ return 0;
+ }
+
+ private BigInteger getCellAddressAt(int x, int y) throws DebugException
+ {
+ BigInteger address = fRendering.getViewportStartAddress();
+
+ int col = x / getCellWidth();
+ int row = y / getCellHeight();
+
+ if(col > getColumnCount())
+ return null;
+
+ address = address.add(BigInteger.valueOf(row
+ * fRendering.getColumnCount() * fRendering.getAddressesPerColumn()
+ / fRendering.getBytesPerCharacter()));
+
+ address = address.add(BigInteger.valueOf(col
+ * fRendering.getAddressesPerColumn()));
+
+ return address;
+ }
+
+ protected Point getCellLocation(BigInteger cellAddress)
+ {
+ try
+ {
+ BigInteger address = fRendering.getViewportStartAddress();
+
+ int cellOffset = cellAddress.subtract(address).intValue();
+
+ cellOffset *= fRendering.getAddressableSize();
+
+ if(fRendering.getColumnCount() == 0) // avoid divide by zero
+ return new Point(0,0);
+
+ int row = cellOffset
+ / (fRendering.getColumnCount() * fRendering.getBytesPerColumn() / fRendering
+ .getBytesPerCharacter());
+
+ cellOffset -= row * fRendering.getColumnCount()
+ * fRendering.getBytesPerColumn()
+ / fRendering.getBytesPerCharacter();
+
+ int col = cellOffset / fRendering.getBytesPerColumn()
+ / fRendering.getBytesPerCharacter();
+
+ int x = col * getCellWidth() + fRendering.getCellPadding();
+ int y = row * getCellHeight() + fRendering.getCellPadding();
+
+ return new Point(x, y);
+ }
+ catch(Exception e)
+ {
+ fRendering
+ .logError(
+ TraditionalRenderingMessages
+ .getString("TraditionalRendering.FAILURE_DETERMINE_CELL_LOCATION"), e); //$NON-NLS-1$
+ return null;
+ }
+ }
+
+ protected int getNumberOfBytesRepresentedByColumn()
+ {
+ return fRendering.getBytesPerRow();
+ }
+
+ protected void positionCaret(int x, int y)
+ {
+ try
+ {
+ BigInteger cellAddress = getCellAddressAt(x, y);
+ if(cellAddress != null)
+ {
+ Point cellPosition = getCellLocation(cellAddress);
+
+ int offset = x - cellPosition.x;
+ int x2 = offset / getCellCharacterWidth();
+
+ if(x2 >= this.getCellCharacterCount())
+ {
+ cellAddress = cellAddress.add(BigInteger.valueOf(this
+ .getNumberOfBytesRepresentedByColumn()));
+ x2 = 0;
+ cellPosition = getCellLocation(cellAddress);
+ }
+
+ fCaret.setLocation(cellPosition.x + x2
+ * getCellCharacterWidth(), cellPosition.y);
+
+ this.fCaretAddress = cellAddress;
+ this.fSubCellCaretPosition = x2;
+ setCaretAddress(fCaretAddress);
+ }
+ }
+ catch(Exception e)
+ {
+ fRendering
+ .logError(
+ TraditionalRenderingMessages
+ .getString("TraditionalRendering.FAILURE_POSITION_CURSOR"), e); //$NON-NLS-1$
+ }
+ }
+
+ protected void paint(PaintEvent pe)
+ {
+ super.paint(pe);
+
+ GC gc = pe.gc;
+
+ FontMetrics fontMetrics = gc.getFontMetrics();
+ int textHeight = fontMetrics.getHeight();
+ int cellHeight = textHeight + (fRendering.getCellPadding() * 2);
+
+ try
+ {
+ BigInteger start = fRendering.getViewportStartAddress();
+
+ for(int i = 0; i < this.getBounds().height / cellHeight; i++)
+ {
+ gc.setForeground(fRendering.getTraditionalRendering().getColorText());
+ BigInteger lineAddress = start.add(BigInteger.valueOf(i
+ * fRendering.getColumnCount()
+ * fRendering.getAddressesPerColumn()));
+
+ if(fRendering.getSelection().isSelected(lineAddress))
+ {
+ gc.setBackground(fRendering.getTraditionalRendering().getColorSelection());
+ gc.fillRectangle(fRendering.getCellPadding() * 2,
+ cellHeight * i, getCellWidth(), cellHeight);
+
+ gc.setForeground(fRendering.getTraditionalRendering().getColorBackground());
+ }
+ else
+ {
+ gc.setBackground(fRendering.getTraditionalRendering().getColorBackground());
+
+ gc.fillRectangle(fRendering.getCellPadding() * 2,
+ cellHeight * i, getCellWidth(), cellHeight);
+
+ // Allow subclass to override this method to do its own coloring
+ applyCustomColor(gc);
+ }
+
+ gc.drawText(fRendering.getAddressString(lineAddress),
+ fRendering.getCellPadding() * 2, cellHeight * i
+ + fRendering.getCellPadding());
+ }
+ }
+ catch(Exception e)
+ {
+ fRendering.logError(TraditionalRenderingMessages
+ .getString("TraditionalRendering.FAILURE_PAINT"), e); //$NON-NLS-1$
+ }
+ }
+
+ // Allow subclass to override this method to do its own coloring
+ protected void applyCustomColor(GC gc)
+ {
+ gc.setForeground(fRendering.getTraditionalRendering().getColorText());
+ }
+}
diff --git a/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/DataPane.java b/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/DataPane.java
new file mode 100644
index 00000000000..551cbc1522f
--- /dev/null
+++ b/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/DataPane.java
@@ -0,0 +1,381 @@
+/*******************************************************************************
+ * Copyright (c) 2006-2009 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Ted R Williams (Wind River Systems, Inc.) - initial implementation
+ *******************************************************************************/
+
+package org.eclipse.cdt.debug.ui.memory.traditional;
+
+import java.math.BigInteger;
+
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.core.model.MemoryByte;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Point;
+
+public class DataPane extends AbstractPane
+{
+ public DataPane(Rendering parent)
+ {
+ super(parent);
+ }
+
+ protected String getCellText(MemoryByte bytes[])
+ {
+ return fRendering.getRadixText(bytes, fRendering.getRadix(), fRendering
+ .isTargetLittleEndian());
+ }
+
+ protected void editCell(BigInteger address, int subCellPosition,
+ char character)
+ {
+ try
+ {
+ MemoryByte bytes[] = fRendering.getBytes(fCaretAddress, fRendering
+ .getBytesPerColumn());
+
+ String cellText = getCellText(bytes);
+ if(cellText == null)
+ return;
+
+ StringBuffer cellTextBuffer = new StringBuffer(cellText);
+ cellTextBuffer.setCharAt(subCellPosition, character);
+ BigInteger value = new BigInteger(cellTextBuffer.toString().trim(),
+ fRendering.getNumericRadix(fRendering.getRadix()));
+ final boolean isSignedType = fRendering.getRadix() == Rendering.RADIX_DECIMAL_SIGNED;
+ final boolean isSigned = isSignedType
+ && value.compareTo(BigInteger.valueOf(0)) < 0;
+
+ int bitCount = value.bitLength();
+ if(isSignedType)
+ bitCount++;
+ if(bitCount > fRendering.getBytesPerColumn() * 8)
+ return;
+
+ int byteLen = fRendering.getBytesPerColumn();
+ byte[] byteData = new byte[byteLen];
+ for(int i = 0; i < byteLen; i++)
+ {
+ int bits = 255;
+ if(isSignedType && i == byteLen - 1)
+ bits = 127;
+
+ byteData[i] = (byte) (value.and(BigInteger.valueOf(bits))
+ .intValue() & bits);
+ value = value.shiftRight(8);
+ }
+
+ if(isSigned)
+ byteData[byteLen - 1] |= 128;
+
+ if(!fRendering.isDisplayLittleEndian())
+ {
+ byte[] byteDataSwapped = new byte[byteData.length];
+ for(int i = 0; i < byteData.length; i++)
+ byteDataSwapped[i] = byteData[byteData.length - 1 - i];
+ byteData = byteDataSwapped;
+ }
+
+ if(byteData.length != bytes.length)
+ return;
+
+ TraditionalMemoryByte bytesToSet[] = new TraditionalMemoryByte[bytes.length];
+
+ for(int i = 0; i < byteData.length; i++)
+ {
+ bytesToSet[i] = new TraditionalMemoryByte(byteData[i]);
+ bytesToSet[i].setBigEndian(bytes[i].isBigEndian());
+
+ // for embedded, the user wants feedback that the change will be sent to the target,
+ // even if does not change the value. eventually, maybe we need another color to
+ // indicate change.
+ //if(bytes[i].getValue() != byteData[i])
+ {
+ bytesToSet[i].setEdited(true);
+ }
+ //else
+ {
+// if(bytes[i] instanceof TraditionalMemoryByte)
+// bytesToSet[i].setEdited(((TraditionalMemoryByte) bytes[i]).isEdited());
+ bytesToSet[i].setChanged(bytes[i].isChanged());
+ }
+ }
+
+ fRendering.getViewportCache().setEditedValue(address, bytesToSet);
+
+ advanceCursor();
+
+ redraw();
+ }
+ catch(Exception e)
+ {
+ // do nothing
+ }
+ }
+
+ protected int getCellWidth()
+ {
+ return getCellCharacterCount() * getCellCharacterWidth()
+ + (fRendering.getCellPadding() * 2);
+ }
+
+ protected int getCellCharacterCount()
+ {
+ return fRendering.getRadixCharacterCount(fRendering.getRadix(),
+ fRendering.getBytesPerColumn());
+ }
+
+ public Point computeSize(int wHint, int hHint)
+ {
+ return new Point(fRendering.getColumnCount() * getCellWidth()
+ + fRendering.getRenderSpacing(), 100);
+ }
+
+ private BigInteger getCellAddressAt(int x, int y) throws DebugException
+ {
+ BigInteger address = fRendering.getViewportStartAddress();
+
+ int col = x / getCellWidth();
+ int row = y / getCellHeight();
+
+ if(col >= fRendering.getColumnCount())
+ return null;
+
+ address = address.add(BigInteger.valueOf(row
+ * fRendering.getColumnCount() * fRendering.getAddressesPerColumn()));
+
+ address = address.add(BigInteger.valueOf(col
+ * fRendering.getAddressesPerColumn()));
+
+ return address;
+ }
+
+ protected Point getCellLocation(BigInteger cellAddress)
+ {
+ try
+ {
+ BigInteger address = fRendering.getViewportStartAddress();
+
+ int cellOffset = cellAddress.subtract(address).intValue();
+ cellOffset *= fRendering.getAddressableSize();
+
+ int row = cellOffset
+ / (fRendering.getColumnCount() * fRendering.getBytesPerColumn());
+ cellOffset -= row * fRendering.getColumnCount()
+ * fRendering.getBytesPerColumn();
+
+ int col = cellOffset / fRendering.getBytesPerColumn();
+
+ int x = col * getCellWidth() + fRendering.getCellPadding();
+ int y = row * getCellHeight() + fRendering.getCellPadding();
+
+ return new Point(x, y);
+ }
+ catch(Exception e)
+ {
+ fRendering
+ .logError(
+ TraditionalRenderingMessages
+ .getString("TraditionalRendering.FAILURE_DETERMINE_CELL_LOCATION"), e); //$NON-NLS-1$
+ return null;
+ }
+ }
+
+ protected void positionCaret(int x, int y)
+ {
+ try
+ {
+ BigInteger cellAddress = getCellAddressAt(x, y);
+ if(cellAddress != null)
+ {
+ Point cellPosition = getCellLocation(cellAddress);
+ int offset = x - cellPosition.x;
+ int subCellCharacterPosition = offset / getCellCharacterWidth();
+
+ if(subCellCharacterPosition == this.getCellCharacterCount())
+ {
+ cellAddress = cellAddress.add(BigInteger.valueOf(fRendering
+ .getAddressesPerColumn()));
+ subCellCharacterPosition = 0;
+ cellPosition = getCellLocation(cellAddress);
+ }
+
+ fCaret.setLocation(cellPosition.x + subCellCharacterPosition
+ * getCellCharacterWidth(), cellPosition.y);
+
+ this.fCaretAddress = cellAddress;
+ this.fSubCellCaretPosition = subCellCharacterPosition;
+ setCaretAddress(fCaretAddress);
+ }
+ }
+ catch(Exception e)
+ {
+ fRendering
+ .logError(
+ TraditionalRenderingMessages
+ .getString("TraditionalRendering.FAILURE_POSITION_CURSOR"), e); //$NON-NLS-1$
+ }
+ }
+
+ protected BigInteger getViewportAddress(int col, int row)
+ throws DebugException
+ {
+ BigInteger address = fRendering.getViewportStartAddress();
+ address = address.add(BigInteger.valueOf((row
+ * fRendering.getColumnCount() + col)
+ * fRendering.getAddressesPerColumn()));
+
+ return address;
+ }
+
+ protected void paint(PaintEvent pe)
+ {
+ super.paint(pe);
+
+ // Allow subclasses to override this method to do their own painting
+ doPaintData(pe);
+
+ }
+
+ // Allow subclasses to override this method to do their own painting
+ protected void doPaintData(PaintEvent pe)
+ {
+ GC gc = pe.gc;
+ gc.setFont(fRendering.getFont());
+
+ int cellHeight = getCellHeight();
+ int cellWidth = getCellWidth();
+
+ int columns = fRendering.getColumnCount();
+
+ try
+ {
+ BigInteger start = fRendering.getViewportStartAddress();
+
+ for(int i = 0; i < this.getBounds().height / cellHeight; i++)
+ {
+ for(int col = 0; col < columns; col++)
+ {
+ if(isOdd(col))
+ gc.setForeground(fRendering.getTraditionalRendering().getColorText());
+ else
+ gc.setForeground(fRendering.getTraditionalRendering().getColorTextAlternate());
+
+ BigInteger cellAddress = start.add(BigInteger.valueOf((i
+ * fRendering.getColumnCount() + col)
+ * fRendering.getAddressesPerColumn()));
+
+ TraditionalMemoryByte bytes[] = fRendering.getBytes(cellAddress,
+ fRendering.getBytesPerColumn());
+
+ if(fRendering.getSelection().isSelected(cellAddress))
+ {
+ gc.setBackground(fRendering.getTraditionalRendering().getColorSelection());
+ gc.fillRectangle(cellWidth * col
+ + fRendering.getCellPadding(), cellHeight * i,
+ cellWidth, cellHeight);
+
+ gc.setForeground(fRendering.getTraditionalRendering().getColorBackground());
+ }
+ else
+ {
+ gc.setBackground(fRendering.getTraditionalRendering().getColorBackground());
+ gc.fillRectangle(cellWidth * col
+ + fRendering.getCellPadding(), cellHeight * i,
+ cellWidth, cellHeight);
+
+ // Allow subclasses to override this method to do their own coloring
+ applyCustomColor(gc, bytes, col);
+ }
+
+ gc.drawText(getCellText(bytes), cellWidth * col
+ + fRendering.getCellPadding(), cellHeight * i
+ + fRendering.getCellPadding());
+
+ BigInteger cellEndAddress = cellAddress.add(BigInteger
+ .valueOf(fRendering.getAddressesPerColumn()));
+ cellEndAddress = cellEndAddress.subtract(BigInteger
+ .valueOf(1));
+
+ if(fCaretEnabled)
+ {
+ if(cellAddress.compareTo(fCaretAddress) <= 0
+ && cellEndAddress.compareTo(fCaretAddress) >= 0)
+ {
+ int x = cellWidth * col
+ + fRendering.getCellPadding()
+ + fSubCellCaretPosition
+ * this.getCellCharacterWidth();
+ int y = cellHeight * i
+ + fRendering.getCellPadding();
+ fCaret.setLocation(x, y);
+ }
+ }
+
+ if(fRendering.isDebug())
+ gc.drawRectangle(cellWidth * col
+ + fRendering.getCellPadding(), cellHeight * i
+ + fRendering.getCellPadding(), cellWidth,
+ cellHeight);
+ }
+ }
+ }
+ catch(Exception e)
+ {
+ fRendering.logError(TraditionalRenderingMessages
+ .getString("TraditionalRendering.FAILURE_PAINT"), e); //$NON-NLS-1$
+ }
+
+ }
+
+ // Allow subclasses to override this method to do their own coloring
+ protected void applyCustomColor(GC gc, TraditionalMemoryByte bytes[], int col)
+ {
+ // TODO consider adding finer granularity?
+ boolean anyByteEditing = false;
+ for(int n = 0; n < bytes.length && !anyByteEditing; n++)
+ if(bytes[n] instanceof TraditionalMemoryByte)
+ if(((TraditionalMemoryByte) bytes[n]).isEdited())
+ anyByteEditing = true;
+
+ if(isOdd(col))
+ gc.setForeground(fRendering.getTraditionalRendering().getColorText());
+ else
+ gc.setForeground(fRendering.getTraditionalRendering().getColorTextAlternate());
+ gc.setBackground(fRendering.getTraditionalRendering().getColorBackground());
+
+ if(anyByteEditing)
+ {
+ gc.setForeground(fRendering.getTraditionalRendering().getColorEdit());
+ }
+ else
+ {
+ boolean isColored = false;
+ for(int i = 0; i < fRendering.getHistoryDepth() && !isColored; i++)
+ {
+ // TODO consider adding finer granularity?
+ for(int n = 0; n < bytes.length; n++)
+ {
+ if(bytes[n].isChanged(i))
+ {
+ if(i == 0)
+ gc.setForeground(fRendering.getTraditionalRendering().getColorsChanged()[i]);
+ else
+ gc.setBackground(fRendering.getTraditionalRendering().getColorsChanged()[i]);
+ isColored = true;
+ break;
+ }
+ }
+ }
+ }
+
+ }
+
+}
diff --git a/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/IMemoryByte.java b/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/IMemoryByte.java
new file mode 100644
index 00000000000..650edbbca28
--- /dev/null
+++ b/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/IMemoryByte.java
@@ -0,0 +1,19 @@
+/*******************************************************************************
+ * Copyright (c) 2006-2009 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Ted R Williams (Wind River Systems, Inc.) - initial implementation
+ *******************************************************************************/
+
+package org.eclipse.cdt.debug.ui.memory.traditional;
+
+public interface IMemoryByte {
+
+ public boolean isEdited();
+
+ public void setEdited(boolean edited);
+}
diff --git a/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/IMemorySelection.java b/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/IMemorySelection.java
new file mode 100644
index 00000000000..ff1c104a8fa
--- /dev/null
+++ b/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/IMemorySelection.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2006-2009 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Ted R Williams (Wind River Systems, Inc.) - initial implementation
+ *******************************************************************************/
+
+package org.eclipse.cdt.debug.ui.memory.traditional;
+
+import java.math.BigInteger;
+
+public interface IMemorySelection
+{
+ public boolean hasSelection();
+
+ public boolean isSelected(BigInteger address);
+
+ public BigInteger getStart();
+
+ public BigInteger getEnd();
+
+ public BigInteger getStartLow();
+
+ public void setStart(BigInteger high, BigInteger low);
+
+ public void setEnd(BigInteger high, BigInteger low);
+
+ public BigInteger getHigh();
+
+ public BigInteger getLow();
+
+ public void clear();
+}
diff --git a/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/IViewportCache.java b/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/IViewportCache.java
new file mode 100644
index 00000000000..3c3973f19b1
--- /dev/null
+++ b/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/IViewportCache.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2006-2009 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Ted R Williams (Wind River Systems, Inc.) - initial implementation
+ *******************************************************************************/
+
+package org.eclipse.cdt.debug.ui.memory.traditional;
+
+import java.math.BigInteger;
+
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.core.model.MemoryByte;
+
+public interface IViewportCache {
+
+ public void dispose();
+ public void refresh();
+ public TraditionalMemoryByte[] getBytes(BigInteger address, int bytesRequested) throws DebugException;
+ public void archiveDeltas();
+ public void setEditedValue(BigInteger address, TraditionalMemoryByte[] bytes);
+ public void clearEditBuffer();
+ public void writeEditBuffer();
+ public boolean containsEditedCell(BigInteger address);
+ // private void queueRequest(BigInteger startAddress, BigInteger endAddress);
+}
diff --git a/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/Rendering.java b/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/Rendering.java
new file mode 100644
index 00000000000..72272adb37c
--- /dev/null
+++ b/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/Rendering.java
@@ -0,0 +1,2104 @@
+/*******************************************************************************
+ * Copyright (c) 2006-2009 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Ted R Williams (Wind River Systems, Inc.) - initial implementation
+ *******************************************************************************/
+
+package org.eclipse.cdt.debug.ui.memory.traditional;
+
+import java.math.BigInteger;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.Vector;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.debug.core.DebugEvent;
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.IDebugEventSetListener;
+import org.eclipse.debug.core.model.IDebugElement;
+import org.eclipse.debug.core.model.IMemoryBlock;
+import org.eclipse.debug.core.model.IMemoryBlockExtension;
+import org.eclipse.debug.core.model.MemoryByte;
+import org.eclipse.debug.internal.ui.DebugUIPlugin;
+import org.eclipse.debug.internal.ui.IInternalDebugUIConstants;
+import org.eclipse.debug.internal.ui.views.memory.MemoryViewUtil;
+import org.eclipse.debug.internal.ui.views.memory.renderings.GoToAddressComposite;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.dnd.TextTransfer;
+import org.eclipse.swt.dnd.Transfer;
+import org.eclipse.swt.events.ControlEvent;
+import org.eclipse.swt.events.ControlListener;
+import org.eclipse.swt.events.KeyAdapter;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Layout;
+import org.eclipse.swt.widgets.ScrollBar;
+import org.eclipse.swt.widgets.Text;
+
+public class Rendering extends Composite implements IDebugEventSetListener
+{
+ // the IMemoryRendering parent
+ private TraditionalRendering fParent;
+
+ // controls
+
+ protected AddressPane fAddressPane;
+
+ protected DataPane fBinaryPane;
+
+ protected TextPane fTextPane;
+
+ private GoToAddressComposite fAddressBar;
+
+ private Control fAddressBarControl; // FIXME why isn't there a getControl() ?
+
+ private Selection fSelection = new Selection();
+
+ // storage
+
+ BigInteger fViewportAddress = null; // default visibility for performance
+
+ BigInteger fMemoryBlockStartAddress = null;
+ BigInteger fMemoryBlockEndAddress = null;
+
+ protected BigInteger fBaseAddress = null; // remember the base address
+
+ private int fColumnCount = 0; // auto calculate can be disabled by user,
+ // making this user settable
+
+ private int fBytesPerRow = 0; // current number of bytes per row are displayed
+
+ private int fCurrentScrollSelection = 0; // current scroll selection;
+
+ private BigInteger fCaretAddress = BigInteger.valueOf(0); // -1 ?
+
+ // user settings
+
+ private int fTextMode = 1; // ASCII default, TODO make preference?
+
+ private int fBytesPerColumn = 4; // 4 byte cell width default
+
+ private int fRadix = RADIX_HEX;
+
+ private int fColumnsSetting = COLUMNS_AUTO_SIZE_TO_FIT;
+
+ private boolean fIsTargetLittleEndian = false;
+
+ private boolean fIsDisplayLittleEndian = false;
+
+ // constants used to identify radix
+ public final static int RADIX_HEX = 1;
+
+ public final static int RADIX_DECIMAL_SIGNED = 2;
+
+ public final static int RADIX_DECIMAL_UNSIGNED = 3;
+
+ public final static int RADIX_OCTAL = 4;
+
+ public final static int RADIX_BINARY = 5;
+
+ // constants used to identify panes
+ public final static int PANE_ADDRESS = 1;
+
+ public final static int PANE_BINARY = 2;
+
+ public final static int PANE_TEXT = 3;
+
+ // constants used to identify text, maybe java should be queried for all available sets
+ public final static int TEXT_ISO_8859_1 = 1;
+ public final static int TEXT_USASCII = 2;
+ public final static int TEXT_UTF8 = 3;
+ protected final static int TEXT_UTF16 = 4;
+
+ // internal constants
+ public final static int COLUMNS_AUTO_SIZE_TO_FIT = 0;
+
+ // view internal settings
+ private int fCellPadding = 2;
+
+ private int fPaneSpacing = 16;
+
+ private String fPaddingString = "?"; //$NON-NLS-1$
+
+ // flag whether the memory cache is dirty
+ private boolean fCacheDirty = false;
+
+ public Rendering(Composite parent, TraditionalRendering renderingParent)
+ {
+ super(parent, SWT.DOUBLE_BUFFERED | SWT.NO_BACKGROUND | SWT.H_SCROLL
+ | SWT.V_SCROLL);
+
+ this.setFont(JFaceResources
+ .getFont(IInternalDebugUIConstants.FONT_NAME)); // TODO internal?
+
+ this.fParent = renderingParent;
+
+ // initialize the viewport start
+ if(fParent.getMemoryBlock() != null)
+ {
+ fViewportAddress = fParent.getMemoryBlockStartAddress();
+
+ // this will be null if memory may be retrieved at any address less than
+ // this memory block's base. if so use the base address.
+ if (fViewportAddress == null)
+ fViewportAddress = fParent.getBigBaseAddress();
+ fBaseAddress = fViewportAddress;
+ }
+
+ // instantiate the panes, TODO default visibility from state or
+ // plugin.xml?
+ this.fAddressPane = createAddressPane();
+ this.fBinaryPane = createDataPane();
+ this.fTextPane = createTextPane();
+
+ fAddressBar = new GoToAddressComposite();
+ fAddressBarControl = fAddressBar.createControl(parent);
+ Button button = fAddressBar.getButton(IDialogConstants.OK_ID);
+ if (button != null)
+ {
+ button.addSelectionListener(new SelectionAdapter() {
+
+ public void widgetSelected(SelectionEvent e) {
+ doGoToAddress();
+ }
+ });
+
+ button = fAddressBar.getButton(IDialogConstants.CANCEL_ID);
+ if (button != null)
+ {
+ button.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ setVisibleAddressBar(false);
+ }});
+ }
+ }
+
+ fAddressBar.getExpressionWidget().addSelectionListener(new SelectionAdapter() {
+ public void widgetDefaultSelected(SelectionEvent e) {
+ doGoToAddress();
+ }});
+
+ fAddressBar.getExpressionWidget().addKeyListener(new KeyAdapter() {
+
+ public void keyPressed(KeyEvent e) {
+ if (e.keyCode == SWT.ESC)
+ setVisibleAddressBar(false);
+ super.keyPressed(e);
+ }
+ });
+
+ this.fAddressBarControl.setVisible(false);
+
+ getHorizontalBar().addSelectionListener(new SelectionListener()
+ {
+ public void widgetSelected(SelectionEvent se)
+ {
+ Rendering.this.layout();
+ }
+
+ public void widgetDefaultSelected(SelectionEvent se)
+ {
+ // do nothing
+ }
+ });
+
+ getVerticalBar().addSelectionListener(
+ new SelectionListener()
+ {
+ public void widgetSelected(SelectionEvent se)
+ {
+ int addressableSize = getAddressableSize();
+
+ switch(se.detail)
+ {
+ case SWT.ARROW_DOWN:
+ handleDownArrow();
+ break;
+ case SWT.PAGE_DOWN:
+ handlePageDown();
+ break;
+ case SWT.ARROW_UP:
+ handleUpArrow();
+ break;
+ case SWT.PAGE_UP:
+ handlePageUp();
+ break;
+ case SWT.SCROLL_LINE:
+ // See: BUG 203068 selection event details broken on GTK < 2.6
+ default:
+ if(getVerticalBar().getSelection() == getVerticalBar().getMinimum())
+ {
+ // Set view port start address to the start address of the Memory Block
+ fViewportAddress = Rendering.this.getMemoryBlockStartAddress();
+ }
+ else if(getVerticalBar().getSelection() == getVerticalBar().getMaximum())
+ {
+ // The view port end address should be less or equal to the the end address of the Memory Block
+ // Set view port address to be bigger than the end address of the Memory Block for now
+ // and let ensureViewportAddressDisplayable() to figure out the correct view port start address
+ fViewportAddress = Rendering.this.getMemoryBlockEndAddress();
+ }
+ else
+ {
+ // Figure out the delta
+ int delta = getVerticalBar().getSelection() - fCurrentScrollSelection;
+ fViewportAddress = fViewportAddress.add(BigInteger.valueOf(
+ getAddressableCellsPerRow() * delta));
+ }
+ ensureViewportAddressDisplayable();
+ // Update tooltip
+ // FIXME conversion from slider to scrollbar
+ // getVerticalBar().setToolTipText(Rendering.this.getAddressString(fViewportAddress));
+
+ // Update the addresses on the Address pane.
+ if(fAddressPane.isPaneVisible())
+ {
+ fAddressPane.redraw();
+ }
+ redrawPanes();
+ break;
+ }
+
+ }
+
+ public void widgetDefaultSelected(SelectionEvent se)
+ {
+ // do nothing
+ }
+ });
+
+ this.addPaintListener(new PaintListener()
+ {
+ public void paintControl(PaintEvent pe)
+ {
+ pe.gc.setBackground(Rendering.this.getTraditionalRendering().getColorBackground());
+ pe.gc.fillRectangle(0, 0, Rendering.this.getBounds().width,
+ Rendering.this.getBounds().height);
+ }
+ });
+
+ setLayout();
+
+ this.addControlListener(new ControlListener()
+ {
+ public void controlMoved(ControlEvent ce)
+ {
+ }
+
+ public void controlResized(ControlEvent ce)
+ {
+ packColumns();
+ }
+ });
+
+ DebugPlugin.getDefault().addDebugEventListener(this);
+ }
+
+ protected void setLayout()
+ {
+ this.setLayout(new Layout()
+ {
+ public void layout(Composite composite, boolean changed)
+ {
+ int xOffset = 0;
+ if(Rendering.this.getHorizontalBar().isVisible())
+ xOffset = Rendering.this.getHorizontalBar().getSelection();
+
+ int x = xOffset * -1;
+ int y = 0;
+
+ if(fAddressBarControl.isVisible())
+ {
+ fAddressBarControl.setBounds(0, 0,
+ Rendering.this.getBounds().width, fAddressBarControl
+ .computeSize(100, 30).y); // FIXME
+ //y = fAddressBarControl.getBounds().height;
+ }
+
+ if(fAddressPane.isPaneVisible())
+ {
+ fAddressPane.setBounds(x, y,
+ fAddressPane.computeSize(0, 0).x, Rendering.this
+ .getBounds().height
+ - y);
+ x = fAddressPane.getBounds().x
+ + fAddressPane.getBounds().width;
+ }
+
+ if(fBinaryPane.isPaneVisible())
+ {
+ fBinaryPane.setBounds(x, y,
+ fBinaryPane.computeSize(0, 0).x, Rendering.this
+ .getBounds().height
+ - y);
+ x = fBinaryPane.getBounds().x
+ + fBinaryPane.getBounds().width;
+ }
+
+ if(fTextPane.isPaneVisible())
+ {
+ fTextPane.setBounds(x, y,
+ Math.max(fTextPane.computeSize(0, 0).x, Rendering.this.getClientArea().width
+ - x - xOffset), Rendering.this.getBounds().height - y);
+ }
+
+ if(getClientArea().width >= fTextPane.getBounds().x + fTextPane.getBounds().width + xOffset)
+ {
+ Rendering.this.getHorizontalBar().setVisible(false);
+ }
+ else
+ {
+ ScrollBar horizontal = Rendering.this.getHorizontalBar();
+
+ horizontal.setVisible(true);
+ horizontal.setMinimum(0);
+ horizontal.setMaximum(fTextPane.getBounds().x
+ + fTextPane.getBounds().width + xOffset);
+ horizontal.setThumb(getClientArea().width);
+ horizontal.setPageIncrement(40); // TODO ?
+ horizontal.setIncrement(20); // TODO ?
+ }
+ }
+
+ protected Point computeSize(Composite composite, int wHint,
+ int hHint, boolean flushCache)
+ {
+ return new Point(100, 100); // dummy data
+ }
+ });
+ }
+
+ protected void handleDownArrow()
+ {
+ fViewportAddress = fViewportAddress.add(BigInteger
+ .valueOf(getAddressableCellsPerRow()));
+ ensureViewportAddressDisplayable();
+ redrawPanes();
+ }
+
+ protected void handleUpArrow()
+ {
+ fViewportAddress = fViewportAddress.subtract(BigInteger
+ .valueOf(getAddressableCellsPerRow()));
+ ensureViewportAddressDisplayable();
+ redrawPanes();
+ }
+
+ protected void handlePageDown()
+ {
+ fViewportAddress = fViewportAddress.add(BigInteger
+ .valueOf(getAddressableCellsPerRow()
+ * (Rendering.this.getRowCount() - 1)));
+ ensureViewportAddressDisplayable();
+ redrawPanes();
+ }
+
+ protected void handlePageUp()
+ {
+ fViewportAddress = fViewportAddress.subtract(BigInteger
+ .valueOf(getAddressableCellsPerRow()
+ * (Rendering.this.getRowCount() - 1)));
+ ensureViewportAddressDisplayable();
+ redrawPanes();
+ }
+
+ protected AddressPane createAddressPane()
+ {
+ return new AddressPane(this);
+ }
+
+ protected DataPane createDataPane()
+ {
+ return new DataPane(this);
+ }
+
+ protected TextPane createTextPane()
+ {
+ return new TextPane(this);
+ }
+
+ public TraditionalRendering getTraditionalRendering() // TODO rename
+ {
+ return fParent;
+ }
+
+ protected void setCaretAddress(BigInteger address)
+ {
+ fCaretAddress = address;
+ }
+
+ protected BigInteger getCaretAddress()
+ {
+ return fCaretAddress;
+ }
+
+ private void doGoToAddress() {
+ try {
+ BigInteger address = fAddressBar.getGoToAddress(this.getMemoryBlockStartAddress(), this.getCaretAddress());
+ getTraditionalRendering().gotoAddress(address);
+ setVisibleAddressBar(false);
+ } catch (NumberFormatException e1)
+ {
+ // FIXME log?
+ }
+ }
+
+ // Ensure that all addresses displayed are within the addressable range
+ protected void ensureViewportAddressDisplayable()
+ {
+ if(fViewportAddress.compareTo(Rendering.this.getMemoryBlockStartAddress()) < 0)
+ {
+ fViewportAddress = Rendering.this.getMemoryBlockStartAddress();
+ }
+ else if(getViewportEndAddress().compareTo(getMemoryBlockEndAddress().add(BigInteger.ONE)) > 0)
+ {
+ fViewportAddress = getMemoryBlockEndAddress().subtract(BigInteger.valueOf(getAddressableCellsPerRow()
+ * getRowCount() - 1));
+ }
+
+ setCurrentScrollSelection();
+ }
+
+ public IMemorySelection getSelection()
+ {
+ return fSelection;
+ }
+
+ protected int getHistoryDepth()
+ {
+ return fViewportCache.getHistoryDepth();
+ }
+
+ protected void setHistoryDepth(int depth)
+ {
+ fViewportCache.setHistoryDepth(depth);
+ }
+
+ public void logError(String message, Exception e)
+ {
+ Status status = new Status(IStatus.ERROR, fParent.getRenderingId(),
+ DebugException.INTERNAL_ERROR, message, e);
+
+ DebugUIPlugin.getDefault().getLog().log(status);
+ }
+
+ public void handleFontPreferenceChange(Font font)
+ {
+ setFont(font);
+
+ Control controls[] = this.getRenderingPanes();
+ for(int i = 0; i < controls.length; i++)
+ controls[i].setFont(font);
+
+ packColumns();
+ layout(true);
+ }
+
+ public void setPaddingString(String padding)
+ {
+ fPaddingString = padding;
+
+ refresh();
+ }
+
+ public char getPaddingCharacter()
+ {
+ return fPaddingString.charAt(0); // use only the first character
+ }
+
+ static int suspendCount = 0;
+
+ public void handleDebugEvents(DebugEvent[] events)
+ {
+ if(this.isDisposed())
+ return;
+
+ boolean isChangeOnly = false;
+ boolean isSuspend = false;
+
+ for(int i = 0; i < events.length; i++)
+ {
+ if(events[0].getSource() instanceof IDebugElement)
+ {
+ final int kind = events[i].getKind();
+ final int detail = events[i].getDetail();
+ final IDebugElement source = (IDebugElement) events[i]
+ .getSource();
+
+ if(source.getDebugTarget() == getMemoryBlock()
+ .getDebugTarget())
+ {
+ if(kind == DebugEvent.SUSPEND)
+ {
+ handleSuspendEvent(detail);
+ isSuspend = true;
+ }
+ else if(kind == DebugEvent.CHANGE)
+ {
+ handleChangeEvent();
+ isChangeOnly = true;
+ }
+ }
+ }
+ }
+
+ if(isSuspend)
+ handleSuspend();
+ else if(isChangeOnly)
+ handleChange();
+ }
+
+ protected void handleSuspend()
+ {
+ Display.getDefault().asyncExec(new Runnable()
+ {
+ public void run()
+ {
+ archiveDeltas();
+ refresh();
+ }
+ });
+ }
+
+ protected void handleChange()
+ {
+ Display.getDefault().asyncExec(new Runnable()
+ {
+ public void run()
+ {
+ refresh();
+ }
+ });
+ }
+
+ protected void handleSuspendEvent(int detail)
+ {
+ }
+
+ protected void handleChangeEvent()
+ {
+ }
+
+ // return true to enable development debug print statements
+ public boolean isDebug()
+ {
+ return false;
+ }
+
+ protected IMemoryBlockExtension getMemoryBlock()
+ {
+ IMemoryBlock block = fParent.getMemoryBlock();
+ if(block != null)
+ return (IMemoryBlockExtension) block
+ .getAdapter(IMemoryBlockExtension.class);
+
+ return null;
+ }
+
+ public BigInteger getBigBaseAddress()
+ {
+ return fParent.getBigBaseAddress();
+ }
+
+ public int getAddressableSize()
+ {
+ return fParent.getAddressableSize();
+ }
+
+ protected IViewportCache getViewportCache()
+ {
+ return fViewportCache;
+ }
+
+ public TraditionalMemoryByte[] getBytes(BigInteger address, int bytes)
+ throws DebugException
+ {
+ return getViewportCache().getBytes(address, bytes);
+ }
+
+ // default visibility for performance
+ ViewportCache fViewportCache = new ViewportCache();
+
+ private interface Request
+ {
+ }
+
+ class ViewportCache extends Thread implements IViewportCache
+ {
+ class ArchiveDeltas implements Request
+ {
+
+ }
+
+ class AddressPair implements Request
+ {
+ BigInteger startAddress;
+
+ BigInteger endAddress;
+
+ public AddressPair(BigInteger start, BigInteger end)
+ {
+ startAddress = start;
+ endAddress = end;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if(obj == null)
+ return false;
+ if(obj instanceof AddressPair)
+ {
+ return ((AddressPair) obj).startAddress.equals(startAddress)
+ && ((AddressPair) obj).endAddress.equals(endAddress);
+ }
+
+ return false;
+ }
+
+ }
+
+ class MemoryUnit
+ {
+ BigInteger start;
+
+ BigInteger end;
+
+ TraditionalMemoryByte[] bytes;
+
+ public MemoryUnit clone()
+ {
+ MemoryUnit b = new MemoryUnit();
+
+ b.start = this.start;
+ b.end = this.end;
+ b.bytes = new TraditionalMemoryByte[this.bytes.length];
+ for(int i = 0; i < this.bytes.length; i++)
+ b.bytes[i] = new TraditionalMemoryByte(this.bytes[i].getValue());
+
+ return b;
+ }
+
+ public boolean isValid()
+ {
+ return this.start != null && this.end != null
+ && this.bytes != null;
+ }
+ }
+
+ private HashMap fEditBuffer = new HashMap();
+
+ private boolean fDisposed = false;
+
+ private Object fLastQueued = null;
+
+ private Vector fQueue = new Vector();
+
+ protected MemoryUnit fCache = null;
+
+ protected MemoryUnit fHistoryCache[] = new MemoryUnit[0];
+
+ protected int fHistoryDepth = 0;
+
+ public ViewportCache()
+ {
+ start();
+ }
+
+ public void dispose()
+ {
+ fDisposed = true;
+ synchronized(this)
+ {
+ this.notify();
+ }
+ }
+
+ public int getHistoryDepth()
+ {
+ return fHistoryDepth;
+ }
+
+ public void setHistoryDepth(int depth)
+ {
+ fHistoryDepth = depth;
+ fHistoryCache = new MemoryUnit[fHistoryDepth];
+ }
+
+ public void refresh()
+ {
+ assert Thread.currentThread().equals(
+ Display.getDefault().getThread()) : TraditionalRenderingMessages
+ .getString("TraditionalRendering.CALLED_ON_NON_DISPATCH_THREAD"); //$NON-NLS-1$
+
+ if(fCache != null)
+ {
+ queueRequest(fViewportAddress, getViewportEndAddress());
+ }
+ }
+
+ public void archiveDeltas()
+ {
+ assert Thread.currentThread().equals(
+ Display.getDefault().getThread()) : TraditionalRenderingMessages
+ .getString("TraditionalRendering.CALLED_ON_NON_DISPATCH_THREAD"); //$NON-NLS-1$
+
+ if(fCache != null)
+ {
+ queueRequestArchiveDeltas();
+ }
+ }
+
+ private void queueRequest(BigInteger startAddress, BigInteger endAddress)
+ {
+ AddressPair pair = new AddressPair(startAddress, endAddress);
+ queue(pair);
+ }
+
+ private void queueRequestArchiveDeltas()
+ {
+ ArchiveDeltas archive = new ArchiveDeltas();
+ queue(archive);
+ }
+
+ private void queue(Object element)
+ {
+ synchronized(fQueue)
+ {
+ if(!(fQueue.size() > 0 && element.equals(fLastQueued)))
+ {
+ fQueue.addElement(element);
+ fLastQueued = element;
+ }
+ }
+ synchronized(this)
+ {
+ this.notify();
+ }
+ }
+
+ public void run()
+ {
+ while(!fDisposed)
+ {
+ AddressPair pair = null;
+ boolean archiveDeltas = false;
+ synchronized(fQueue)
+ {
+ if(fQueue.size() > 0)
+ {
+ Request request = (Request) fQueue.elementAt(0);
+ Class type = null;
+ if(request instanceof ArchiveDeltas)
+ {
+ archiveDeltas = true;
+ type = ArchiveDeltas.class;
+ }
+ else if(request instanceof AddressPair)
+ {
+ pair = (AddressPair) request;
+ type = AddressPair.class;
+ }
+
+ while(fQueue.size() > 0 && type.isInstance(fQueue.elementAt(0)))
+ fQueue.removeElementAt(0);
+ }
+ }
+ if(archiveDeltas)
+ {
+ for(int i = fViewportCache.getHistoryDepth() - 1; i > 0; i--)
+ fHistoryCache[i] = fHistoryCache[i - 1];
+
+ fHistoryCache[0] = fCache.clone();
+ }
+ else if(pair != null)
+ {
+ populateCache(pair.startAddress, pair.endAddress);
+ }
+ else
+ {
+ synchronized(this)
+ {
+ try
+ {
+ this.wait();
+ }
+ catch(Exception e)
+ {
+ // do nothing
+ }
+ }
+ }
+ }
+ }
+
+ // cache memory necessary to paint viewport
+ // TODO: user setting to buffer +/- x lines
+ // TODO: reuse existing cache? probably only a minor performance gain
+ private void populateCache(final BigInteger startAddress,
+ final BigInteger endAddress)
+ {
+ try
+ {
+ final IMemoryBlockExtension memoryBlock = getMemoryBlock();
+
+ final BigInteger lengthInBytes = endAddress.subtract(startAddress);
+ final BigInteger addressableSize = BigInteger.valueOf(getAddressableSize());
+
+ final long units = lengthInBytes.divide(addressableSize).add(
+ lengthInBytes.mod(addressableSize).compareTo(BigInteger.ZERO) > 0
+ ? BigInteger.ONE : BigInteger.ZERO).longValue();
+
+ // CDT (and maybe other backends) will call setValue() on these MemoryBlock objects.
+ // We don't want this to happen, because it interferes with this rendering's own
+ // change history. Ideally, we should strictly use the back end change notification
+ // and history, but it is only guaranteed to work for bytes within the address range
+ // of the MemoryBlock.
+ final MemoryByte readBytes[] = memoryBlock
+ .getBytesFromAddress(startAddress, units);
+
+ TraditionalMemoryByte cachedBytes[] = new TraditionalMemoryByte[readBytes.length];
+ for(int i = 0; i < readBytes.length; i++)
+ cachedBytes[i] = new TraditionalMemoryByte(readBytes[i].getValue(), readBytes[i].getFlags());
+
+ // derive the target endian from the read MemoryBytes.
+ if (cachedBytes.length > 0) {
+ if (cachedBytes[0].isEndianessKnown()) {
+ setTargetLittleEndian(!cachedBytes[0].isBigEndian());
+ }
+ }
+
+ // reorder bytes within unit to be a sequential byte stream if the endian is already little
+ if(isTargetLittleEndian())
+ {
+ // there isn't an order when the unit size is one, so skip for performance
+ if(addressableSize.compareTo(BigInteger.ONE) != 0)
+ {
+ int unitSize = addressableSize.intValue();
+ TraditionalMemoryByte cachedBytesAsByteSequence[] = new TraditionalMemoryByte[cachedBytes.length];
+ for(int unit = 0; unit < units; unit++)
+ {
+ for(int unitbyte = 0; unitbyte < unitSize; unitbyte++)
+ {
+ cachedBytesAsByteSequence[unit * unitSize + unitbyte] = cachedBytes[unit * unitSize + unitSize - unitbyte];
+ }
+ }
+ cachedBytes = cachedBytesAsByteSequence;
+ }
+ }
+
+ final TraditionalMemoryByte[] cachedBytesFinal = cachedBytes;
+ Display.getDefault().asyncExec(new Runnable()
+ {
+ public void run()
+ {
+ // generate deltas
+ for(int historyIndex = 0; historyIndex < getHistoryDepth(); historyIndex++)
+ {
+ if(fHistoryCache[historyIndex] != null && fHistoryCache[historyIndex].isValid())
+ {
+ BigInteger maxStart = startAddress
+ .max(fHistoryCache[historyIndex].start);
+ BigInteger minEnd = endAddress
+ .min(fHistoryCache[historyIndex].end).subtract(
+ BigInteger.valueOf(1));
+
+ BigInteger overlapLength = minEnd
+ .subtract(maxStart);
+ if(overlapLength.compareTo(BigInteger.valueOf(0)) > 0)
+ {
+ // there is overlap
+
+ int offsetIntoOld = maxStart.subtract(
+ fHistoryCache[historyIndex].start).intValue();
+ int offsetIntoNew = maxStart.subtract(
+ startAddress).intValue();
+
+ for(int i = overlapLength.intValue(); i >= 0; i--)
+ {
+ cachedBytesFinal[offsetIntoNew + i]
+ .setChanged(historyIndex, cachedBytesFinal[offsetIntoNew
+ + i].getValue() != fHistoryCache[historyIndex].bytes[offsetIntoOld
+ + i].getValue());
+ }
+ }
+ }
+ }
+
+ fCache = new MemoryUnit();
+ fCache.start = startAddress;
+ fCache.end = endAddress;
+ fCache.bytes = cachedBytesFinal;
+
+ // If the history does not exist, populate the history with the just populated cache. This solves the
+ // use case of 1) connect to target; 2) edit memory before the first suspend debug event; 3) paint
+ // differences in changed color.
+ if(fHistoryCache[0] == null)
+ fHistoryCache[0] = fCache.clone();
+
+ Rendering.this.redrawPanes();
+ }
+ });
+
+ }
+ catch(Exception e)
+ {
+ logError(
+ TraditionalRenderingMessages
+ .getString("TraditionalRendering.FAILURE_READ_MEMORY"), e); //$NON-NLS-1$
+ }
+ }
+
+ // bytes will be fetched from cache
+ public TraditionalMemoryByte[] getBytes(BigInteger address, int bytesRequested)
+ throws DebugException
+ {
+ assert Thread.currentThread().equals(
+ Display.getDefault().getThread()) : TraditionalRenderingMessages
+ .getString("TraditionalRendering.CALLED_ON_NON_DISPATCH_THREAD"); //$NON-NLS-1$
+
+ if(containsEditedCell(address)) // cell size cannot be switched during an edit
+ return getEditedMemory(address);
+
+ boolean contains = false;
+ if(fCache != null && fCache.start != null)
+ {
+ // see if all of the data requested is in the cache
+ BigInteger dataEnd = address.add(BigInteger.valueOf(bytesRequested));
+
+ if(fCache.start.compareTo(address) <= 0
+ && fCache.end.compareTo(dataEnd) >= 0
+ && fCache.bytes.length > 0)
+ contains = true;
+ }
+
+ if(contains)
+ {
+ int offset = address.subtract(fCache.start).intValue();
+ TraditionalMemoryByte bytes[] = new TraditionalMemoryByte[bytesRequested];
+ for(int i = 0; i < bytes.length; i++)
+ {
+ bytes[i] = fCache.bytes[offset + i];
+ }
+
+ return bytes;
+ }
+
+ TraditionalMemoryByte bytes[] = new TraditionalMemoryByte[bytesRequested];
+ for(int i = 0; i < bytes.length; i++)
+ {
+ bytes[i] = new TraditionalMemoryByte();
+ bytes[i].setReadable(false);
+ }
+
+ fViewportCache.queueRequest(fViewportAddress,
+ getViewportEndAddress());
+
+ return bytes;
+ }
+
+ public boolean containsEditedCell(BigInteger address)
+ {
+ assert Thread.currentThread().equals(
+ Display.getDefault().getThread()) : TraditionalRenderingMessages
+ .getString("TraditionalRendering.CALLED_ON_NON_DISPATCH_THREAD"); //$NON-NLS-1$
+
+ return fEditBuffer.containsKey(address);
+ }
+
+ private TraditionalMemoryByte[] getEditedMemory(BigInteger address)
+ {
+ assert Thread.currentThread().equals(
+ Display.getDefault().getThread()) : TraditionalRenderingMessages
+ .getString("TraditionalRendering.CALLED_ON_NON_DISPATCH_THREAD"); //$NON-NLS-1$
+
+ return (TraditionalMemoryByte[]) fEditBuffer.get(address);
+ }
+
+ public void clearEditBuffer()
+ {
+ assert Thread.currentThread().equals(
+ Display.getDefault().getThread()) : TraditionalRenderingMessages
+ .getString("TraditionalRendering.CALLED_ON_NON_DISPATCH_THREAD"); //$NON-NLS-1$
+
+ fEditBuffer.clear();
+ Rendering.this.redrawPanes();
+ }
+
+ public void writeEditBuffer()
+ {
+ assert Thread.currentThread().equals(
+ Display.getDefault().getThread()) : TraditionalRenderingMessages
+ .getString("TraditionalRendering.CALLED_ON_NON_DISPATCH_THREAD"); //$NON-NLS-1$
+
+ Set keySet = fEditBuffer.keySet();
+ Iterator iterator = keySet.iterator();
+
+ while(iterator.hasNext())
+ {
+ BigInteger address = (BigInteger) iterator.next();
+ TraditionalMemoryByte[] bytes = (TraditionalMemoryByte[]) fEditBuffer
+ .get(address);
+
+ byte byteValue[] = new byte[bytes.length];
+ for(int i = 0; i < bytes.length; i++)
+ byteValue[i] = bytes[i].getValue();
+
+ try
+ {
+ getMemoryBlock().setValue(address.subtract(fParent.getBigBaseAddress()), byteValue);
+ }
+ catch(Exception e)
+ {
+ MemoryViewUtil.openError(TraditionalRenderingMessages.getString("TraditionalRendering.FAILURE_WRITE_MEMORY"), "", e);
+
+ logError(
+ TraditionalRenderingMessages
+ .getString("TraditionalRendering.FAILURE_WRITE_MEMORY"), e); //$NON-NLS-1$
+ }
+ }
+
+ clearEditBuffer();
+ }
+
+ public void setEditedValue(BigInteger address, TraditionalMemoryByte[] bytes)
+ {
+ assert Thread.currentThread().equals(
+ Display.getDefault().getThread()) : TraditionalRenderingMessages
+ .getString("TraditionalRendering.CALLED_ON_NON_DISPATCH_THREAD"); //$NON-NLS-1$
+
+ fEditBuffer.put(address, bytes);
+ Rendering.this.redrawPanes();
+ }
+ }
+
+ public void setVisibleAddressBar(boolean visible)
+ {
+ fAddressBarControl.setVisible(visible);
+ if(visible)
+ {
+ String selectedStr = "0x" + getCaretAddress().toString(16);
+ Text text = fAddressBar.getExpressionWidget();
+ text.setText(selectedStr);
+ text.setSelection(0, text.getCharCount());
+ fAddressBar.getExpressionWidget().setFocus();
+ }
+
+ layout(true);
+ layoutPanes();
+ }
+
+ public void setDirty(boolean needRefresh)
+ {
+ fCacheDirty = needRefresh;
+ }
+
+ public boolean isDirty()
+ {
+ return fCacheDirty;
+ }
+
+ public void dispose()
+ {
+ DebugPlugin.getDefault().removeDebugEventListener(this);
+ if(fViewportCache != null)
+ {
+ fViewportCache.dispose();
+ fViewportCache = null;
+ }
+ super.dispose();
+ }
+
+ class Selection implements IMemorySelection
+ {
+ private BigInteger fStartHigh;
+ private BigInteger fStartLow;
+
+ private BigInteger fEndHigh;
+ private BigInteger fEndLow;
+
+ public void clear()
+ {
+ fEndHigh = fEndLow = fStartHigh = fStartLow = null;
+ redrawPanes();
+ }
+
+ public boolean hasSelection()
+ {
+ return fStartHigh != null && fStartLow != null
+ && fEndHigh != null && fEndLow != null;
+ }
+
+ public boolean isSelected(BigInteger address)
+ {
+ // do we have valid start and end addresses
+ if(getEnd() == null || getStart() == null)
+ return false;
+
+ // if end is greater than start
+ if(getEnd().compareTo(getStart()) >= 0)
+ {
+ if(address.compareTo(getStart()) >= 0
+ && address.compareTo(getEnd()) < 0)
+ return true;
+ }
+ // if start is greater than end
+ else if(getStart().compareTo(getEnd()) >= 0)
+ {
+ if(address.compareTo(getEnd()) >= 0
+ && address.compareTo(getStart()) < 0)
+ return true;
+ }
+
+ return false;
+ }
+
+ public void setStart(BigInteger high, BigInteger low)
+ {
+ if(high == null && low == null)
+ {
+ if(fStartHigh != null && fStartLow != null)
+ {
+ fStartHigh = null;
+ fStartLow = null;
+ redrawPanes();
+ }
+
+ return;
+ }
+
+ boolean changed = false;
+
+ if(fStartHigh == null || !high.equals(fStartHigh))
+ {
+ fStartHigh = high;
+ changed = true;
+ }
+
+ if(fStartLow == null || !low.equals(fStartLow))
+ {
+ fStartLow = low;
+ changed = true;
+ }
+
+ if(changed)
+ redrawPanes();
+ }
+
+ public void setEnd(BigInteger high, BigInteger low)
+ {
+ if(high == null && low == null)
+ {
+ if(fEndHigh != null && fEndLow != null)
+ {
+ fEndHigh = null;
+ fEndLow = null;
+ redrawPanes();
+ }
+
+ return;
+ }
+
+ boolean changed = false;
+
+ if(fEndHigh == null || !high.equals(fEndHigh))
+ {
+ fEndHigh = high;
+ changed = true;
+ }
+
+ if(fEndLow == null || !low.equals(fEndLow))
+ {
+ fEndLow = low;
+ changed = true;
+ }
+
+ if(changed)
+ redrawPanes();
+ }
+
+ public BigInteger getHigh()
+ {
+ if(!hasSelection())
+ return null;
+
+ return getStart().max(getEnd());
+ }
+
+ public BigInteger getLow()
+ {
+ if(!hasSelection())
+ return null;
+
+ return getStart().min(getEnd());
+ }
+
+ public BigInteger getStart()
+ {
+ // if there is no start, return null
+ if(fStartHigh == null)
+ return null;
+
+ // if there is no end, return the high address of the start
+ if(fEndHigh == null)
+ return fStartHigh;
+
+ // if Start High/Low equal End High/Low, return a low start and high end
+ if(fStartHigh.equals(fEndHigh)
+ && fStartLow.equals(fEndLow))
+ return fStartLow;
+
+ BigInteger differenceEndToStartHigh = fEndHigh.subtract(fStartHigh).abs();
+ BigInteger differenceEndToStartLow = fEndHigh.subtract(fStartLow).abs();
+
+ // return the start high or start low based on which creates a larger selection
+ if(differenceEndToStartHigh.compareTo(differenceEndToStartLow) > 0)
+ return fStartHigh;
+ else
+ return fStartLow;
+ }
+
+ public BigInteger getStartLow() {
+ return fStartLow;
+ }
+
+ public BigInteger getEnd()
+ {
+ // if there is no end, return null
+ if(fEndHigh == null)
+ return null;
+
+ // if Start High/Low equal End High/Low, return a low start and high end
+ if(fStartHigh.equals(fEndHigh)
+ && fStartLow.equals(fEndLow))
+ return fStartHigh;
+
+ BigInteger differenceStartToEndHigh = fStartHigh.subtract(fEndHigh).abs();
+ BigInteger differenceStartToEndLow = fStartHigh.subtract(fEndLow).abs();
+
+ // return the start high or start low based on which creates a larger selection
+ if(differenceStartToEndHigh.compareTo(differenceStartToEndLow) >= 0)
+ return fEndHigh;
+ else
+ return fEndLow;
+ }
+ }
+
+ public void setPaneVisible(int pane, boolean visible)
+ {
+ switch(pane)
+ {
+ case PANE_ADDRESS:
+ fAddressPane.setPaneVisible(visible);
+ break;
+ case PANE_BINARY:
+ fBinaryPane.setPaneVisible(visible);
+ break;
+ case PANE_TEXT:
+ fTextPane.setPaneVisible(visible);
+ break;
+ }
+
+ fireSettingsChanged();
+ layoutPanes();
+ }
+
+ public boolean getPaneVisible(int pane)
+ {
+ switch(pane)
+ {
+ case PANE_ADDRESS:
+ return fAddressPane.isPaneVisible();
+ case PANE_BINARY:
+ return fBinaryPane.isPaneVisible();
+ case PANE_TEXT:
+ return fTextPane.isPaneVisible();
+ default:
+ return false;
+ }
+ }
+
+ protected void packColumns()
+ {
+ int availableWidth = Rendering.this.getSize().x;
+
+ if(fAddressPane.isPaneVisible())
+ {
+ availableWidth -= fAddressPane.computeSize(0, 0).x;
+ availableWidth -= Rendering.this.getRenderSpacing() * 2;
+ }
+
+ int combinedWidth = 0;
+
+ if(fBinaryPane.isPaneVisible())
+ combinedWidth += fBinaryPane.getCellWidth();
+
+ if(fTextPane.isPaneVisible())
+ combinedWidth += fTextPane.getCellWidth();
+
+ if(getColumnsSetting() == Rendering.COLUMNS_AUTO_SIZE_TO_FIT)
+ {
+ if(combinedWidth == 0)
+ fColumnCount = 0;
+ else
+ {
+ fColumnCount = availableWidth / combinedWidth;
+ if(fColumnCount == 0)
+ fColumnCount = 1; // paint one column even if only part can show in view
+ }
+ }
+ else
+ {
+ fColumnCount = getColumnsSetting();
+ }
+
+ try
+ {
+ // Update the number of bytes per row;
+ // the max and min scroll range and the current thumb nail position.
+ fBytesPerRow = getBytesPerColumn() * getColumnCount();
+ BigInteger difference = getMemoryBlockEndAddress().subtract(getMemoryBlockStartAddress()).add(BigInteger.ONE);
+ BigInteger maxScrollRange = difference.divide(BigInteger.valueOf(getAddressableCellsPerRow()));
+ if(maxScrollRange.multiply(BigInteger.valueOf(getAddressableCellsPerRow())).compareTo(difference) != 0)
+ maxScrollRange = maxScrollRange.add(BigInteger.ONE);
+
+ // support targets with an addressable size greater than 1
+ maxScrollRange = maxScrollRange.divide(BigInteger.valueOf(getAddressableSize()));
+
+ getVerticalBar().setMinimum(1);
+ getVerticalBar().setMaximum(maxScrollRange.intValue());
+ getVerticalBar().setIncrement(1);
+ getVerticalBar().setPageIncrement(this.getRowCount() -1);
+ //TW FIXME conversion of slider to scrollbar
+ // fScrollBar.setToolTipText(Rendering.this.getAddressString(fViewportAddress));
+ setCurrentScrollSelection();
+ }
+ catch(Exception e)
+ {
+ // FIXME precautionary
+ }
+
+ Rendering.this.redraw();
+ Rendering.this.redrawPanes();
+ }
+
+ public AbstractPane[] getRenderingPanes()
+ {
+ return new AbstractPane[] { fAddressPane, fBinaryPane,
+ fTextPane };
+ }
+
+ public int getCellPadding()
+ {
+ return fCellPadding;
+ }
+
+ protected int getRenderSpacing()
+ {
+ return fPaneSpacing;
+ }
+
+ public void refresh()
+ {
+ if(!this.isDisposed())
+ {
+ if(this.isVisible() && getViewportCache() != null)
+ {
+ getViewportCache().refresh();
+ }
+ else
+ {
+ setDirty(true);
+ fParent.updateRenderingLabels();
+ }
+ }
+ }
+
+ protected void archiveDeltas()
+ {
+ this.getViewportCache().archiveDeltas();
+ }
+
+ public void gotoAddress(BigInteger address)
+ {
+ // Ensure that the GoTo address is within the addressable range
+ if((address.compareTo(this.getMemoryBlockStartAddress())< 0) ||
+ (address.compareTo(this.getMemoryBlockEndAddress()) > 0))
+ {
+ return;
+ }
+
+ fViewportAddress = address; // TODO update fCaretAddress
+ redrawPanes();
+ }
+
+ public void setViewportStartAddress(BigInteger newAddress)
+ {
+ fViewportAddress = newAddress;
+ }
+
+ public BigInteger getViewportStartAddress()
+ {
+ return fViewportAddress;
+ }
+
+ public BigInteger getViewportEndAddress()
+ {
+ return fViewportAddress.add(BigInteger.valueOf(this.getBytesPerRow() * getRowCount() / getAddressableSize()));
+ }
+
+ public String getAddressString(BigInteger address)
+ {
+ StringBuffer addressString = new StringBuffer(address.toString(16)
+ .toUpperCase());
+ for(int chars = getAddressBytes() * 2 - addressString.length(); chars > 0; chars--)
+ {
+ addressString.insert(0, '0');
+ }
+ addressString.insert(0, "0x"); //$NON-NLS-1$
+
+ return addressString.toString();
+ }
+
+ protected int getAddressBytes()
+ {
+ return fParent.getAddressSize();
+ }
+
+ public int getColumnCount()
+ {
+ return fColumnCount;
+ }
+
+ public int getColumnsSetting()
+ {
+ return fColumnsSetting;
+ }
+
+ public void setColumnsSetting(int columns)
+ {
+ if(fColumnsSetting != columns)
+ {
+ fColumnsSetting = columns;
+ fireSettingsChanged();
+ layoutPanes();
+ }
+ }
+
+ protected void ensureVisible(BigInteger address)
+ {
+ BigInteger viewportStart = this.getViewportStartAddress();
+ BigInteger viewportEnd = this.getViewportEndAddress();
+
+ boolean isAddressBeforeViewportStart = address.compareTo(viewportStart) < 0;
+ boolean isAddressAfterViewportEnd = address.compareTo(viewportEnd) > 0;
+
+ if(isAddressBeforeViewportStart || isAddressAfterViewportEnd)
+ gotoAddress(address);
+ }
+
+ protected int getRowCount()
+ {
+ int rowCount = 0;
+ Control panes[] = getRenderingPanes();
+ for(int i = 0; i < panes.length; i++)
+ {
+ if(panes[i] instanceof AbstractPane)
+ rowCount = Math.max(rowCount,
+ ((AbstractPane) panes[i]).getRowCount());
+ }
+
+ return rowCount;
+ }
+
+ public int getBytesPerColumn()
+ {
+ return fBytesPerColumn;
+ }
+
+ protected int getBytesPerRow()
+ {
+ return fBytesPerRow;
+ }
+
+ protected int getAddressableCellsPerRow()
+ {
+ return getBytesPerRow() / getAddressableSize();
+ }
+
+ public int getAddressesPerColumn()
+ {
+ return this.getBytesPerColumn() / getAddressableSize();
+ }
+
+ /**
+ * @return Set current scroll selection
+ */
+ protected void setCurrentScrollSelection()
+ {
+ BigInteger selection = getViewportStartAddress().divide(
+ BigInteger.valueOf(getAddressableCellsPerRow()).add(BigInteger.ONE));
+ getVerticalBar().setSelection(selection.intValue());
+ fCurrentScrollSelection = selection.intValue();
+ }
+
+ /**
+ * @return start address of the memory block
+ */
+ protected BigInteger getMemoryBlockStartAddress()
+ {
+ if(fMemoryBlockStartAddress == null)
+ fMemoryBlockStartAddress = fParent.getMemoryBlockStartAddress();
+ if(fMemoryBlockStartAddress == null)
+ fMemoryBlockStartAddress = BigInteger.ZERO;
+
+ return fMemoryBlockStartAddress;
+ }
+
+ /**
+ * @return end address of the memory block
+ */
+ protected BigInteger getMemoryBlockEndAddress()
+ {
+ if(fMemoryBlockEndAddress == null)
+ fMemoryBlockEndAddress = fParent.getMemoryBlockEndAddress();
+
+ return fMemoryBlockEndAddress;
+ }
+
+ public int getRadix()
+ {
+ return fRadix;
+ }
+
+ protected int getNumericRadix(int radix)
+ {
+ switch(radix)
+ {
+ case RADIX_BINARY:
+ return 2;
+ case RADIX_OCTAL:
+ return 8;
+ case RADIX_DECIMAL_SIGNED:
+ case RADIX_DECIMAL_UNSIGNED:
+ return 10;
+ case RADIX_HEX:
+ return 16;
+ }
+
+ return -1;
+ }
+
+ public void setRadix(int mode)
+ {
+ if(fRadix == mode)
+ return;
+
+ fRadix = mode;
+ fireSettingsChanged();
+ layoutPanes();
+ }
+
+ public void setTextMode(int mode)
+ {
+ fTextMode = mode;
+
+ fireSettingsChanged();
+ layoutPanes();
+ }
+
+ public int getTextMode()
+ {
+ return fTextMode;
+ }
+
+ protected String getCharacterSet(int mode)
+ {
+ switch(mode)
+ {
+ case Rendering.TEXT_UTF8:
+ return "UTF8";
+ case Rendering.TEXT_UTF16:
+ return "UTF16";
+ case Rendering.TEXT_USASCII:
+ return "US-ASCII";
+ case Rendering.TEXT_ISO_8859_1:
+ default:
+ return "ISO-8859-1";
+ }
+ }
+
+ public int getBytesPerCharacter()
+ {
+ if(fTextMode == Rendering.TEXT_UTF16)
+ return 2;
+
+ return 1;
+ }
+
+ public boolean isTargetLittleEndian()
+ {
+ return fIsTargetLittleEndian;
+ }
+
+ public void setTargetLittleEndian(boolean littleEndian)
+ {
+ if(fIsTargetLittleEndian == littleEndian)
+ return;
+
+ fParent.setTargetMemoryLittleEndian(littleEndian);
+ fIsTargetLittleEndian = littleEndian;
+ Display.getDefault().asyncExec(new Runnable() {
+ public void run()
+ {
+ fireSettingsChanged();
+ layoutPanes();
+ }
+ });
+ }
+
+ public boolean isDisplayLittleEndian()
+ {
+ return fIsDisplayLittleEndian;
+ }
+
+ public void setDisplayLittleEndian(boolean littleEndian)
+ {
+ if(fIsDisplayLittleEndian = littleEndian)
+ return;
+
+ fIsDisplayLittleEndian = littleEndian;
+
+ fireSettingsChanged();
+ Display.getDefault().asyncExec(new Runnable(){
+ public void run()
+ {
+ layoutPanes();
+ }
+ });
+ }
+
+ public void setBytesPerColumn(int byteCount)
+ {
+ if(fBytesPerColumn != byteCount)
+ {
+ fBytesPerColumn = byteCount;
+ fireSettingsChanged();
+ layoutPanes();
+ }
+ }
+
+ protected void redrawPane(int paneId)
+ {
+ if(!isDisposed() && this.isVisible())
+ {
+ AbstractPane pane = null;
+ if(paneId == Rendering.PANE_ADDRESS)
+ {
+ pane = fAddressPane;
+ }
+ else if(paneId == Rendering.PANE_BINARY)
+ {
+ pane = fBinaryPane;
+ }
+ if(paneId == Rendering.PANE_TEXT)
+ {
+ pane = fTextPane;
+ }
+ if(pane != null && pane.isPaneVisible())
+ {
+ pane.redraw();
+ pane.setRowCount();
+ if(pane.isFocusControl())
+ pane.updateCaret();
+ }
+
+ }
+
+ fParent.updateRenderingLabels();
+ }
+
+ protected void redrawPanes()
+ {
+ if(!isDisposed() && this.isVisible())
+ {
+ if(fAddressPane.isPaneVisible())
+ {
+ fAddressPane.redraw();
+ fAddressPane.setRowCount();
+ if(fAddressPane.isFocusControl())
+ fAddressPane.updateCaret();
+ }
+
+ if(fBinaryPane.isPaneVisible())
+ {
+ fBinaryPane.redraw();
+ fBinaryPane.setRowCount();
+ if(fBinaryPane.isFocusControl())
+ fBinaryPane.updateCaret();
+ }
+
+ if(fTextPane.isPaneVisible())
+ {
+ fTextPane.redraw();
+ fTextPane.setRowCount();
+ if(fTextPane.isFocusControl())
+ fTextPane.updateCaret();
+ }
+ }
+
+ fParent.updateRenderingLabels();
+ }
+
+ private void layoutPanes()
+ {
+ packColumns();
+ layout(true);
+
+ redraw();
+ redrawPanes();
+ }
+
+ private void fireSettingsChanged()
+ {
+ fAddressPane.settingsChanged();
+ fBinaryPane.settingsChanged();
+ fTextPane.settingsChanged();
+ }
+
+ protected void copyAddressToClipboard()
+ {
+ Clipboard clip = null;
+ try
+ {
+ clip = new Clipboard(getDisplay());
+
+ String addressString = "0x" + getCaretAddress().toString(16);
+
+ TextTransfer plainTextTransfer = TextTransfer.getInstance();
+ clip.setContents(new Object[] { addressString },
+ new Transfer[] { plainTextTransfer });
+ }
+ finally
+ {
+ if(clip != null)
+ {
+ clip.dispose();
+ }
+ }
+ }
+
+ static final char[] hexdigits = { '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
+
+ public String getRadixText(MemoryByte bytes[], int radix,
+ boolean isLittleEndian)
+ {
+ boolean readable = true;
+ for(int i = 0; i < bytes.length; i++)
+ if(!bytes[i].isReadable())
+ readable = false;
+
+ if(readable)
+ {
+ // bytes from the cache are stored as a sequential byte sequence regardless of target endian.
+ // the endian attribute tells us the recommended endian for display. the user may change this
+ // from the default. if the endian is little, we must swap the byte order.
+ boolean needsSwap = false;
+ if(isDisplayLittleEndian())
+ needsSwap = true;
+
+ switch(radix)
+ {
+ case Rendering.RADIX_HEX:
+ case Rendering.RADIX_OCTAL:
+ case Rendering.RADIX_BINARY:
+ {
+ long value = 0;
+ if(needsSwap)
+ {
+ for(int i = 0; i < bytes.length; i++)
+ {
+ value = value << 8;
+ value = value
+ | (bytes[bytes.length - 1 - i].getValue() & 0xFF);
+ }
+ }
+ else
+ {
+ for(int i = 0; i < bytes.length; i++)
+ {
+ value = value << 8;
+ value = value | (bytes[i].getValue() & 0xFF);
+ }
+ }
+
+ char buf[] = new char[getRadixCharacterCount(radix,
+ bytes.length)];
+
+ switch(radix)
+ {
+ case Rendering.RADIX_BINARY:
+ {
+ for(int i = buf.length - 1; i >= 0; i--)
+ {
+ buf[i] = hexdigits[(int) (value & 1)];
+ value = value >>> 1;
+ }
+ break;
+ }
+ case Rendering.RADIX_OCTAL:
+ {
+ for(int i = buf.length - 1; i >= 0; i--)
+ {
+ buf[i] = hexdigits[(int) (value & 7)];
+ value = value >>> 3;
+ }
+ break;
+ }
+ case Rendering.RADIX_HEX:
+ {
+ for(int i = buf.length - 1; i >= 0; i--)
+ {
+ buf[i] = hexdigits[(int) (value & 15)];
+ value = value >>> 4;
+ }
+ break;
+ }
+ }
+
+ return new String(buf);
+ }
+ case Rendering.RADIX_DECIMAL_UNSIGNED:
+ case Rendering.RADIX_DECIMAL_SIGNED:
+ {
+ boolean isSignedType = radix == Rendering.RADIX_DECIMAL_SIGNED ? true
+ : false;
+
+ int textWidth = getRadixCharacterCount(radix, bytes.length);
+
+ char buf[] = new char[textWidth];
+
+ byte[] value = new byte[bytes.length + 1];
+
+ if(needsSwap)
+ {
+ for(int i = 0; i < bytes.length; i++)
+ {
+ value[bytes.length - i] = bytes[i].getValue();
+ }
+ }
+ else
+ {
+ for(int i = 0; i < bytes.length; i++)
+ {
+ value[i + 1] = bytes[i].getValue();
+ }
+ }
+
+ BigInteger bigValue;
+ boolean isNegative = false;
+ if(isSignedType && (value[1] & 0x80) != 0)
+ {
+ value[0] = -1;
+ isNegative = true;
+ bigValue = new BigInteger(value).abs();
+ }
+ else
+ {
+ value[0] = 0;
+ bigValue = new BigInteger(value);
+ }
+
+ for(int i = 0; i < textWidth; i++)
+ {
+ BigInteger divideRemainder[] = bigValue.divideAndRemainder(
+ BigInteger.valueOf(10));
+ int remainder = divideRemainder[1].intValue();
+ buf[textWidth - 1 - i] = hexdigits[remainder % 10];
+ bigValue = divideRemainder[0];
+ }
+
+ if(isSignedType)
+ {
+ buf[0] = isNegative ? '-' : ' ';
+ }
+
+ return new String(buf);
+ }
+ }
+ }
+
+ StringBuffer errorText = new StringBuffer();
+ for(int i = getRadixCharacterCount(radix, bytes.length); i > 0; i--)
+ errorText.append(getPaddingCharacter());
+
+ return errorText.toString();
+ }
+
+ public int getRadixCharacterCount(int radix, int bytes)
+ {
+ switch(radix)
+ {
+ case Rendering.RADIX_HEX:
+ return bytes * 2;
+ case Rendering.RADIX_BINARY:
+ return bytes * 8;
+ case Rendering.RADIX_OCTAL:
+ {
+ switch(bytes)
+ {
+ case 1:
+ return 3;
+ case 2:
+ return 6;
+ case 4:
+ return 11;
+ case 8:
+ return 22;
+ }
+ }
+ case Rendering.RADIX_DECIMAL_UNSIGNED:
+ {
+ switch(bytes)
+ {
+ case 1:
+ return 3;
+ case 2:
+ return 5;
+ case 4:
+ return 10;
+ case 8:
+ return 20;
+ }
+ }
+ case Rendering.RADIX_DECIMAL_SIGNED:
+ {
+ switch(bytes)
+ {
+ case 1:
+ return 4;
+ case 2:
+ return 6;
+ case 4:
+ return 11;
+ case 8:
+ return 21;
+ }
+ }
+ }
+
+ return 0;
+ }
+
+ protected static boolean isValidEditCharacter(char character)
+ {
+ return (character >= '0' && character <= '9')
+ || (character >= 'a' && character <= 'z')
+ || (character >= 'A' && character <= 'Z') || character == '-'
+ || character == ' ';
+ }
+
+ public String formatText(MemoryByte[] memoryBytes,
+ boolean isLittleEndian, int textMode)
+ {
+ // check memory byte for unreadable bytes
+ boolean readable = true;
+ for(int i = 0; i < memoryBytes.length; i++)
+ if(!memoryBytes[i].isReadable())
+ readable = false;
+
+ // if any bytes are not readable, return ?'s
+ if(!readable)
+ {
+ StringBuffer errorText = new StringBuffer();
+ for(int i = memoryBytes.length; i > 0; i--)
+ errorText.append(getPaddingCharacter());
+ return errorText.toString();
+ }
+
+ // TODO
+ // does endian mean anything for text? ah, unicode?
+
+ // create byte array from MemoryByte array
+ byte bytes[] = new byte[memoryBytes.length];
+ for(int i = 0; i < bytes.length; i++)
+ {
+ bytes[i] = memoryBytes[i].getValue();
+ }
+
+ // replace invalid characters with '.'
+ // maybe there is a way to query the character set for
+ // valid characters?
+
+ // replace invalid US-ASCII with '.'
+ if(textMode == Rendering.TEXT_USASCII)
+ {
+ for(int i = 0; i < bytes.length; i++)
+ {
+ int byteValue = bytes[i];
+ if(byteValue < 0)
+ byteValue += 256;
+
+ if(byteValue < 0x20 || byteValue > 0x7e)
+ bytes[i] = '.';
+ }
+ }
+
+ // replace invalid ISO-8859-1 with '.'
+ if(textMode == Rendering.TEXT_ISO_8859_1)
+ {
+ for(int i = 0; i < bytes.length; i++)
+ {
+ int byteValue = bytes[i];
+ if(byteValue < 0)
+ byteValue += 256;
+
+ if(byteValue < 0x20 ||
+ (byteValue >= 0x7f && byteValue < 0x9f))
+ bytes[i] = '.';
+ }
+ }
+
+ try
+ {
+ // convert bytes to string using desired character set
+ StringBuffer buf = new StringBuffer(new String(bytes, this.getCharacterSet(textMode)));
+
+ // pad string to (byte count - string length) with spaces
+ for(int i = 0; i < memoryBytes.length - buf.length(); i++)
+ buf.append(' ');
+ return buf.toString();
+ }
+ catch(Exception e)
+ {
+ // return ?s the length of byte count
+ StringBuffer buf = new StringBuffer();
+ for(int i = 0; i < memoryBytes.length - buf.length(); i++)
+ buf.append(getPaddingCharacter());
+ return buf.toString();
+ }
+ }
+
+}
diff --git a/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/TextPane.java b/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/TextPane.java
new file mode 100644
index 00000000000..5b4bbe2253b
--- /dev/null
+++ b/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/TextPane.java
@@ -0,0 +1,326 @@
+/*******************************************************************************
+ * Copyright (c) 2006-2009 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Ted R Williams (Wind River Systems, Inc.) - initial implementation
+ *******************************************************************************/
+
+package org.eclipse.cdt.debug.ui.memory.traditional;
+
+import java.math.BigInteger;
+
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.core.model.MemoryByte;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Point;
+
+public class TextPane extends AbstractPane
+{
+ public TextPane(Rendering parent)
+ {
+ super(parent);
+ }
+
+ protected int getCellCharacterCount()
+ {
+ return fRendering.getBytesPerColumn()
+ / fRendering.getBytesPerCharacter();
+ }
+
+ protected String getCellText(MemoryByte bytes[])
+ {
+ return fRendering.formatText(bytes, fRendering
+ .isTargetLittleEndian(), fRendering.getTextMode());
+ }
+
+ protected void editCell(BigInteger address, int subCellPosition,
+ char character)
+ {
+ try
+ {
+ MemoryByte bytes[] = fRendering.getBytes(fCaretAddress, fRendering
+ .getBytesPerColumn());
+
+ String cellText = getCellText(bytes);
+ if(cellText == null)
+ return;
+
+ StringBuffer cellTextBuffer = new StringBuffer(cellText);
+ cellTextBuffer.setCharAt(subCellPosition, character);
+
+ byte byteData[] = cellTextBuffer.toString().getBytes(fRendering.getCharacterSet(fRendering.getTextMode()));
+ if(byteData.length != bytes.length)
+ return;
+
+ TraditionalMemoryByte bytesToSet[] = new TraditionalMemoryByte[bytes.length];
+
+ for(int i = 0; i < byteData.length; i++)
+ {
+ bytesToSet[i] = new TraditionalMemoryByte(byteData[i]);
+
+ if(bytes[i].getValue() != byteData[i])
+ {
+ bytesToSet[i].setEdited(true);
+ }
+ else
+ {
+ bytesToSet[i].setChanged(bytes[i].isChanged());
+ }
+ }
+
+ fRendering.getViewportCache().setEditedValue(address, bytesToSet);
+
+ advanceCursor();
+
+ redraw();
+ }
+ catch(Exception e)
+ {
+ // this is ok
+ }
+ }
+
+ protected int getCellWidth()
+ {
+ GC gc = new GC(this);
+ gc.setFont(fRendering.getFont());
+ int width = gc.getAdvanceWidth('F');
+ gc.dispose();
+
+ return fRendering.getBytesPerColumn()
+ / fRendering.getBytesPerCharacter() * width;
+ }
+
+ public Point computeSize(int wHint, int hHint)
+ {
+ return new Point(fRendering.getColumnCount() * getCellWidth()
+ + fRendering.getRenderSpacing(), 100);
+
+ }
+
+ protected Point getCellLocation(BigInteger cellAddress)
+ {
+ try
+ {
+ BigInteger address = fRendering.getViewportStartAddress();
+
+ int cellOffset = cellAddress.subtract(address).intValue();
+ cellOffset *= fRendering.getAddressableSize();
+
+ int row = cellOffset
+ / (fRendering.getColumnCount() * fRendering.getBytesPerColumn() / fRendering
+ .getBytesPerCharacter());
+ cellOffset -= row * fRendering.getColumnCount()
+ * fRendering.getBytesPerColumn()
+ / fRendering.getBytesPerCharacter();
+
+ int col = cellOffset / fRendering.getBytesPerColumn()
+ / fRendering.getBytesPerCharacter();
+
+ int x = col * getCellWidth() + fRendering.getCellPadding();
+ int y = row * getCellHeight() + fRendering.getCellPadding();
+
+ return new Point(x, y);
+ }
+ catch(Exception e)
+ {
+ fRendering
+ .logError(
+ TraditionalRenderingMessages
+ .getString("TraditionalRendering.FAILURE_DETERMINE_CELL_LOCATION"), e); //$NON-NLS-1$
+ return null;
+ }
+ }
+
+ private BigInteger getCellAddressAt(int x, int y) throws DebugException
+ {
+ BigInteger address = fRendering.getViewportStartAddress();
+
+ int col = x / getCellWidth();
+ int row = y / getCellHeight();
+
+ if(col >= fRendering.getColumnCount())
+ return null;
+
+ address = address.add(BigInteger.valueOf(row
+ * fRendering.getColumnCount() * fRendering.getAddressesPerColumn()
+ / fRendering.getBytesPerCharacter()));
+
+ address = address.add(BigInteger.valueOf(col
+ * fRendering.getAddressesPerColumn()));
+
+ return address;
+ }
+
+ protected void positionCaret(int x, int y)
+ {
+ try
+ {
+ BigInteger cellAddress = getCellAddressAt(x, y);
+
+ if(cellAddress != null)
+ {
+ Point cellPosition = getCellLocation(cellAddress);
+
+ int offset = x - cellPosition.x;
+ int x2 = offset / getCellCharacterWidth();
+
+ if(x2 == this.getCellCharacterCount())
+ {
+ cellAddress = cellAddress.add(BigInteger.valueOf(fRendering
+ .getAddressesPerColumn()));
+ x2 = 0;
+ cellPosition = getCellLocation(cellAddress);
+ }
+
+ fCaret.setLocation(cellPosition.x + x2
+ * getCellCharacterWidth(), cellPosition.y);
+
+ this.fCaretAddress = cellAddress;
+ this.fSubCellCaretPosition = x2;
+ setCaretAddress(fCaretAddress);
+ }
+ }
+ catch(Exception e)
+ {
+ fRendering
+ .logError(
+ TraditionalRenderingMessages
+ .getString("TraditionalRendering.FAILURE_POSITION_CURSOR"), e); //$NON-NLS-1$
+ }
+ }
+
+ protected BigInteger getViewportAddress(int col, int row)
+ throws DebugException
+ {
+ BigInteger address = fRendering.getViewportStartAddress();
+ address = address.add(BigInteger.valueOf((row
+ * fRendering.getColumnCount() + col)
+ * fRendering.getAddressesPerColumn()
+ / fRendering.getBytesPerCharacter()));
+
+ return address;
+ }
+
+ protected void paint(PaintEvent pe)
+ {
+ super.paint(pe);
+
+ GC gc = pe.gc;
+ gc.setFont(fRendering.getFont());
+
+ int cellHeight = getCellHeight();
+ int cellWidth = getCellWidth();
+
+ final int columns = fRendering.getColumnCount();
+
+ final boolean isLittleEndian = fRendering.isTargetLittleEndian();
+
+ gc.setForeground(fRendering.getTraditionalRendering().getColorBackground());
+ gc.fillRectangle(columns * cellWidth, 0, this.getBounds().width, this
+ .getBounds().height);
+
+ try
+ {
+ BigInteger start = fRendering.getViewportStartAddress();
+
+ for(int i = 0; i < this.getBounds().height / cellHeight; i++)
+ {
+ for(int col = 0; col < columns; col++)
+ {
+ if(isOdd(col))
+ gc.setForeground(fRendering.getTraditionalRendering().getColorText());
+ else
+ gc.setForeground(fRendering.getTraditionalRendering().getColorTextAlternate());
+
+ BigInteger cellAddress = start.add(BigInteger.valueOf((i
+ * columns + col)
+ * fRendering.getAddressesPerColumn()));
+
+ TraditionalMemoryByte bytes[] = fRendering.getBytes(cellAddress,
+ fRendering.getBytesPerColumn());
+
+ if(fRendering.getSelection().isSelected(cellAddress))
+ {
+ gc.setBackground(fRendering.getTraditionalRendering().getColorSelection());
+ gc.fillRectangle(cellWidth * col, cellHeight * i,
+ cellWidth, cellHeight);
+
+ gc.setForeground(fRendering.getTraditionalRendering().getColorBackground());
+ }
+ else
+ {
+ gc.setBackground(fRendering.getTraditionalRendering().getColorBackground());
+ gc.fillRectangle(cellWidth * col, cellHeight * i,
+ cellWidth, cellHeight);
+
+ applyCustomColor(gc, bytes, col);
+ }
+
+ gc.drawText(fRendering.formatText(bytes,
+ isLittleEndian, fRendering.getTextMode()), cellWidth * col, cellHeight * i
+ + fRendering.getCellPadding());
+
+ if(fRendering.isDebug())
+ gc.drawRectangle(cellWidth * col, cellHeight * i
+ + fRendering.getCellPadding(), cellWidth,
+ cellHeight);
+ }
+ }
+ }
+ catch(Exception e)
+ {
+ fRendering.logError(TraditionalRenderingMessages
+ .getString("TraditionalRendering.FAILURE_PAINT"), e); //$NON-NLS-1$
+ }
+
+ }
+
+ // Allow subclasses to override this method to do their own coloring
+ protected void applyCustomColor(GC gc, TraditionalMemoryByte bytes[], int col)
+ {
+ // TODO consider adding finer granularity?
+ boolean anyByteEditing = false;
+ for(int n = 0; n < bytes.length && !anyByteEditing; n++)
+ if(bytes[n] instanceof TraditionalMemoryByte)
+ if(((TraditionalMemoryByte) bytes[n]).isEdited())
+ anyByteEditing = true;
+
+ if(isOdd(col))
+ gc.setForeground(fRendering.getTraditionalRendering().getColorText());
+ else
+ gc.setForeground(fRendering.getTraditionalRendering().getColorTextAlternate());
+ gc.setBackground(fRendering.getTraditionalRendering().getColorBackground());
+
+ if(anyByteEditing)
+ {
+ gc.setForeground(fRendering.getTraditionalRendering().getColorEdit());
+ }
+ else
+ {
+ boolean isColored = false;
+ for(int i = 0; i < fRendering.getHistoryDepth() && !isColored; i++)
+ {
+ // TODO consider adding finer granularity?
+ for(int n = 0; n < bytes.length; n++)
+ {
+ if(bytes[n].isChanged(i))
+ {
+ if(i == 0)
+ gc.setForeground(fRendering.getTraditionalRendering().getColorsChanged()[i]);
+ else
+ gc.setBackground(fRendering.getTraditionalRendering().getColorsChanged()[i]);
+ isColored = true;
+ break;
+ }
+ }
+ }
+
+ }
+ }
+}
diff --git a/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/TraditionalGoToAddressRendering.java b/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/TraditionalGoToAddressRendering.java
new file mode 100644
index 00000000000..e9ef9bb4941
--- /dev/null
+++ b/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/TraditionalGoToAddressRendering.java
@@ -0,0 +1,269 @@
+/*******************************************************************************
+ * Copyright (c) 2006-2009 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Ted R Williams (Wind River Systems, Inc.) - initial implementation
+ *******************************************************************************/
+
+package org.eclipse.cdt.debug.ui.memory.traditional;
+
+import java.math.BigInteger;
+
+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.IMemoryBlockRetrievalExtension;
+import org.eclipse.debug.internal.ui.DebugUIMessages;
+import org.eclipse.debug.internal.ui.DebugUIPlugin;
+import org.eclipse.debug.internal.ui.views.memory.MemoryViewUtil;
+import org.eclipse.debug.internal.ui.views.memory.RenderingViewPane;
+import org.eclipse.debug.internal.ui.views.memory.renderings.CreateRendering;
+import org.eclipse.debug.ui.memory.AbstractMemoryRendering;
+import org.eclipse.debug.ui.memory.IMemoryRendering;
+import org.eclipse.debug.ui.memory.IMemoryRenderingContainer;
+import org.eclipse.debug.ui.memory.IMemoryRenderingSite;
+import org.eclipse.debug.ui.memory.IRepositionableMemoryRendering;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.KeyAdapter;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.PlatformUI;
+
+public class TraditionalGoToAddressRendering extends AbstractMemoryRendering {
+
+ private IMemoryRenderingSite fSite;
+ private IMemoryRenderingContainer fContainer;
+
+ @Override
+ public void init(IMemoryRenderingContainer container, IMemoryBlock block) {
+ super.init(container, block);
+ fSite = container.getMemoryRenderingSite();
+ fContainer = container;
+ }
+
+ public TraditionalGoToAddressRendering(String renderingId) {
+ super(renderingId);
+ }
+
+ private Control fControl;
+
+ public Control createControl(Composite parent) {
+
+ Composite fGotoAddressContainer = parent;
+
+ final GoToAddressWidget fGotoAddress = new GoToAddressWidget();
+ Control fGotoAddressControl = fGotoAddress.createControl(fGotoAddressContainer);
+
+ fControl = fGotoAddressControl;
+
+ final Runnable goHandler = new Runnable()
+ {
+ public void run()
+ {
+ go(fGotoAddress.getExpressionText(), false);
+ }
+ };
+
+ Button button = fGotoAddress.getButton(IDialogConstants.OK_ID);
+ if (button != null)
+ {
+ button.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ goHandler.run();
+ }
+ });
+ }
+
+ button = fGotoAddress.getButton(GoToAddressWidget.ID_GO_NEW_TAB);
+ if (button != null)
+ {
+ button.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ go(fGotoAddress.getExpressionText(), true);
+ }
+ });
+ }
+
+ fGotoAddress.getExpressionWidget().addKeyListener(new KeyAdapter() {
+ public void keyPressed(KeyEvent e) {
+ if (e.keyCode == SWT.CR)
+ goHandler.run();
+ super.keyPressed(e);
+ }
+ });
+
+
+ return fControl;
+ }
+
+ public Control getControl() {
+ return fControl;
+ }
+
+ private void go(final String expression, final boolean inNewTab)
+ {
+ IMemoryRenderingContainer containers[] = fSite.getMemoryRenderingContainers();
+ for(int i = 0; i < containers.length; i++)
+ {
+ if(containers[i] instanceof RenderingViewPane)
+ {
+ final IMemoryRenderingContainer container = containers[i];
+ if(containers[i] != null)
+ {
+ final IMemoryRendering activeRendering = containers[i].getActiveRendering();
+ if(activeRendering != null)
+ {
+ new Thread() {
+ public void run()
+ {
+ IMemoryBlock activeMemoryBlock = activeRendering.getMemoryBlock();
+ IMemoryBlockExtension blockExtension = (IMemoryBlockExtension) activeMemoryBlock.getAdapter(IMemoryBlockExtension.class);
+
+ if(inNewTab)
+ {
+ try {
+ final IMemoryRendering rendering = new CreateRendering(container);
+ IMemoryBlock newBlock = null;
+ if(activeMemoryBlock.getDebugTarget() instanceof IMemoryBlockRetrievalExtension)
+ {
+ newBlock = ((IMemoryBlockRetrievalExtension) activeMemoryBlock.getDebugTarget())
+ .getExtendedMemoryBlock(expression, activeMemoryBlock.getDebugTarget());
+
+ }
+ else
+ {
+ BigInteger newAddress;
+ if(expression.toUpperCase().startsWith("0X"))
+ newAddress = new BigInteger(expression.substring(2), 16);
+ else
+ newAddress = new BigInteger(expression, 16);
+
+ newBlock = activeMemoryBlock.getDebugTarget().getMemoryBlock(newAddress.longValue(),
+ activeMemoryBlock.getLength());
+ }
+
+ final IMemoryBlock finalNewBlock = newBlock;
+ Display.getDefault().asyncExec(new Runnable(){
+ public void run()
+ {
+ rendering.init(container, finalNewBlock);
+ container.addMemoryRendering(rendering);
+ }
+ });
+
+ } catch (DebugException e) {
+ MemoryViewUtil.openError(DebugUIMessages.GoToAddressAction_Go_to_address_failed,
+ DebugUIMessages.GoToAddressAction_Address_is_invalid, e);
+ }
+ }
+ else if(activeRendering instanceof IRepositionableMemoryRendering)
+ {
+ try
+ {
+ if(activeMemoryBlock.getDebugTarget() instanceof IMemoryBlockRetrievalExtension)
+ {
+ IMemoryBlockExtension resolveExpressionBlock = ((IMemoryBlockRetrievalExtension) activeMemoryBlock.getDebugTarget())
+ .getExtendedMemoryBlock(expression, activeMemoryBlock.getDebugTarget());
+ ((IRepositionableMemoryRendering) activeRendering).goToAddress(resolveExpressionBlock.getBigBaseAddress());
+ }
+ else
+ {
+ BigInteger newAddress;
+ if(expression.toUpperCase().startsWith("0X"))
+ newAddress = new BigInteger(expression.substring(2), 16);
+ else
+ newAddress = new BigInteger(expression, 16);
+
+ ((IRepositionableMemoryRendering) activeRendering).goToAddress(newAddress);
+ }
+ }
+ catch(DebugException de)
+ {
+ MemoryViewUtil.openError(DebugUIMessages.GoToAddressAction_Go_to_address_failed,
+ DebugUIMessages.GoToAddressAction_Address_is_invalid, de);
+ }
+ }
+
+ }
+ }.start();
+ }
+ }
+ }
+ }
+ }
+}
+
+class GoToAddressWidget {
+
+ private Text fExpression;
+ private Button fOKButton;
+ private Button fOKNewTabButton;
+ private Composite fComposite;
+
+ protected static int ID_GO_NEW_TAB = 2000;
+
+ /**
+ * @param parent
+ * @return
+ */
+ public Control createControl(Composite parent)
+ {
+ fComposite = new Composite(parent, SWT.NONE);
+ PlatformUI.getWorkbench().getHelpSystem().setHelp(fComposite, DebugUIPlugin.getUniqueIdentifier() + ".GoToAddressComposite_context"); //$NON-NLS-1$
+ GridLayout layout = new GridLayout();
+ layout.numColumns = 6;
+ layout.makeColumnsEqualWidth = false;
+ layout.marginHeight = 0;
+ layout.marginLeft = 0;
+ fComposite.setLayout(layout);
+
+ fExpression = new Text(fComposite, SWT.SINGLE | SWT.BORDER);
+ fExpression.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ fOKButton = new Button(fComposite, SWT.NONE);
+ fOKButton.setText("Go");
+
+// fOKNewTabButton = new Button(fComposite, SWT.NONE);
+// fOKNewTabButton.setText("New Tab");
+
+ return fComposite;
+ }
+
+ public int getHeight()
+ {
+ int height = fComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT).y;
+ return height;
+ }
+
+ public Button getButton(int id)
+ {
+ if (id == IDialogConstants.OK_ID)
+ return fOKButton;
+ if (id == ID_GO_NEW_TAB)
+ return fOKNewTabButton;
+ return null;
+ }
+
+ public String getExpressionText()
+ {
+ return fExpression.getText().trim();
+ }
+
+ public Text getExpressionWidget()
+ {
+ return fExpression;
+ }
+}
diff --git a/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/TraditionalGoToAddressRenderingTypeDelegate.java b/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/TraditionalGoToAddressRenderingTypeDelegate.java
new file mode 100644
index 00000000000..1e1bd4a2c87
--- /dev/null
+++ b/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/TraditionalGoToAddressRenderingTypeDelegate.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2006-2009 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Ted R Williams (Wind River Systems, Inc.) - initial implementation
+ *******************************************************************************/
+
+package org.eclipse.cdt.debug.ui.memory.traditional;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.ui.memory.IMemoryRendering;
+import org.eclipse.debug.ui.memory.IMemoryRenderingTypeDelegate;
+
+public class TraditionalGoToAddressRenderingTypeDelegate
+ implements IMemoryRenderingTypeDelegate
+{
+
+ public IMemoryRendering createRendering(String id) throws CoreException {
+ return new TraditionalGoToAddressRendering(id);
+ }
+
+
+}
diff --git a/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/TraditionalRendering.java b/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/TraditionalRendering.java
new file mode 100644
index 00000000000..f9c1b0d7071
--- /dev/null
+++ b/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/TraditionalRendering.java
@@ -0,0 +1,1494 @@
+/*******************************************************************************
+ * Copyright (c) 2006-2009 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Ted R Williams (Wind River Systems, Inc.) - initial implementation
+ *******************************************************************************/
+
+package org.eclipse.cdt.debug.ui.memory.traditional;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.math.BigInteger;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.Command;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+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.eclipse.debug.core.model.IMemoryBlock;
+import org.eclipse.debug.core.model.IMemoryBlockExtension;
+import org.eclipse.debug.core.model.IMemoryBlockRetrieval;
+import org.eclipse.debug.core.model.MemoryByte;
+import org.eclipse.debug.internal.ui.DebugPluginImages;
+import org.eclipse.debug.internal.ui.DebugUIMessages;
+import org.eclipse.debug.internal.ui.DebugUIPlugin;
+import org.eclipse.debug.internal.ui.IInternalDebugUIConstants;
+import org.eclipse.debug.internal.ui.memory.IMemoryBlockConnection;
+import org.eclipse.debug.internal.ui.views.memory.MemoryViewUtil;
+import org.eclipse.debug.internal.ui.views.memory.renderings.GoToAddressAction;
+import org.eclipse.debug.ui.IDebugUIConstants;
+import org.eclipse.debug.ui.memory.AbstractMemoryRendering;
+import org.eclipse.debug.ui.memory.AbstractTableRendering;
+import org.eclipse.debug.ui.memory.IMemoryRendering;
+import org.eclipse.debug.ui.memory.IMemoryRenderingContainer;
+import org.eclipse.debug.ui.memory.IRepositionableMemoryRendering;
+import org.eclipse.debug.ui.memory.IResettableMemoryRendering;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.dialogs.IInputValidator;
+import org.eclipse.jface.dialogs.InputDialog;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferenceConverter;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.jface.viewers.IBasicPropertyConstants;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.dnd.DND;
+import org.eclipse.swt.dnd.TextTransfer;
+import org.eclipse.swt.dnd.Transfer;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchActionConstants;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.commands.ICommandService;
+import org.eclipse.ui.model.IWorkbenchAdapter;
+import org.eclipse.ui.progress.UIJob;
+
+/**
+ * A memory rendering displaying memory in a traditional
+ * memory view look and feel, optimized for minimal IO traffic.
+ *
+ * requirements of the debug model implementation:
+ * - An IMemoryBlockExtension is required.
+ *
+ * Since it is not possible to size the memory block to match
+ * the size of the viewport, memory block change notification
+ * is not useful. Such events are ignored by this rendering.
+ */
+
+public class TraditionalRendering extends AbstractMemoryRendering implements IRepositionableMemoryRendering, IResettableMemoryRendering
+{
+ protected Rendering fRendering;
+ protected Action displayEndianBigAction;
+ protected Action displayEndianLittleAction;
+
+ private IWorkbenchAdapter fWorkbenchAdapter;
+ private IMemoryBlockConnection fConnection;
+
+ private final static int MAX_MENU_COLUMN_COUNT = 8;
+
+ public TraditionalRendering(String id)
+ {
+ super(id);
+
+ JFaceResources.getFontRegistry().addListener(
+ new IPropertyChangeListener()
+ {
+ public void propertyChange(PropertyChangeEvent event)
+ {
+ if(event.getProperty().equals(
+ IInternalDebugUIConstants.FONT_NAME))
+ {
+ TraditionalRendering.this.fRendering
+ .handleFontPreferenceChange(JFaceResources
+ .getFont(IInternalDebugUIConstants.FONT_NAME));
+ }
+ }
+ });
+
+ this.addPropertyChangeListener(new IPropertyChangeListener()
+ {
+ public void propertyChange(PropertyChangeEvent event)
+ {
+ IMemoryRendering sourceRendering = (IMemoryRendering) event
+ .getSource();
+ if(!sourceRendering.getMemoryBlock().equals(getMemoryBlock()))
+ return;
+
+ Object address = event.getNewValue();
+
+ if(event.getProperty().equals(
+ AbstractTableRendering.PROPERTY_SELECTED_ADDRESS)
+ && address instanceof BigInteger)
+ {
+ TraditionalRendering.this.fRendering
+ .ensureVisible((BigInteger) address);
+ }
+ }
+ });
+
+ TraditionalRenderingPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(
+ new IPropertyChangeListener()
+ {
+ public void propertyChange(PropertyChangeEvent event)
+ {
+ disposeColors();
+ allocateColors();
+ applyPreferences();
+ }
+ });
+
+
+ DebugUIPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(
+ new IPropertyChangeListener()
+ {
+ public void propertyChange(PropertyChangeEvent event)
+ {
+ if(event.getProperty().equals(IDebugUIConstants.PREF_PADDED_STR))
+ {
+ if(TraditionalRendering.this.fRendering != null)
+ {
+ setRenderingPadding((String) event.getNewValue());
+ TraditionalRendering.this.fRendering.redrawPanes();
+ }
+ }
+ }
+ });
+
+ }
+
+ private void setRenderingPadding(String padding)
+ {
+ if(padding == null || padding.length() == 0)
+ padding = "?";
+ TraditionalRendering.this.fRendering.setPaddingString(padding);
+ }
+
+ protected void logError(String message, Exception e)
+ {
+ Status status = new Status(IStatus.ERROR, getRenderingId(),
+ DebugException.INTERNAL_ERROR, message, e);
+
+ DebugUIPlugin.getDefault().getLog().log(status);
+ }
+
+ private BigInteger fBigBaseAddress;
+ private BigInteger fStartAddress;
+ private BigInteger fEndAddress;
+ private int fAddressableSize;
+ private int fAddressSize;
+
+ public void init(IMemoryRenderingContainer container, IMemoryBlock block)
+ {
+ super.init(container, block);
+
+ try
+ {
+ fBigBaseAddress = ((IMemoryBlockExtension) block).getBigBaseAddress();
+ }
+ catch(DebugException de)
+ {
+ logError(TraditionalRenderingMessages
+ .getString("TraditionalRendering.FAILURE_RETRIEVE_BASE_ADDRESS"), de); //$NON-NLS-1$ // FIXME
+ }
+
+ try
+ {
+ fAddressableSize = ((IMemoryBlockExtension) block).getAddressableSize();
+ }
+ catch(DebugException de)
+ {
+ fAddressableSize = 1;
+ }
+
+ try
+ {
+ fStartAddress = ((IMemoryBlockExtension)block).getMemoryBlockStartAddress();
+ }
+ catch (DebugException de) {
+ fStartAddress = null;
+ logError(TraditionalRenderingMessages
+ .getString("TraditionalRendering.FAILURE_RETRIEVE_START_ADDRESS"), de); //$NON-NLS-1$
+ }
+
+
+ try
+ {
+ fAddressSize = ((IMemoryBlockExtension) block).getAddressSize();
+ }
+ catch(DebugException e)
+ {
+ fAddressSize = 0;
+ }
+
+ BigInteger endAddress;
+ try
+ {
+ endAddress = ((IMemoryBlockExtension) block).getMemoryBlockEndAddress();
+ if (endAddress != null)
+ fEndAddress = endAddress;
+ }
+ catch (DebugException e)
+ {
+ fEndAddress = null;
+ }
+
+ if (fEndAddress == null)
+ {
+ int addressSize;
+ try {
+ addressSize = ((IMemoryBlockExtension) block).getAddressSize();
+ } catch (DebugException e) {
+ addressSize = 4;
+ }
+
+ endAddress = BigInteger.valueOf(2);
+ endAddress = endAddress.pow(addressSize*8);
+ endAddress = endAddress.subtract(BigInteger.valueOf(1));
+ fEndAddress = endAddress;
+ }
+
+ // default to MAX_VALUE if we have trouble getting the end address
+ if (fEndAddress == null)
+ fEndAddress = BigInteger.valueOf(Integer.MAX_VALUE);
+ }
+
+ public BigInteger getBigBaseAddress()
+ {
+ return fBigBaseAddress;
+ }
+
+ public BigInteger getMemoryBlockStartAddress()
+ {
+ return fStartAddress;
+ }
+
+ public BigInteger getMemoryBlockEndAddress()
+ {
+ return fEndAddress;
+ }
+
+ public int getAddressableSize()
+ {
+ return fAddressableSize;
+ }
+
+ public int getAddressSize()
+ {
+ return fAddressSize;
+ }
+
+ public Control createControl(Composite parent)
+ {
+ allocateColors();
+
+ this.fRendering = new Rendering(parent, this);
+
+ applyPreferences();
+
+ createMenus();
+
+ return this.fRendering;
+ }
+
+ // FIXME
+ private static final String ID_GO_TO_ADDRESS_COMMAND = "org.eclipse.debug.ui.command.gotoaddress"; //$NON-NLS-1$
+ private AbstractHandler fGoToAddressHandler;
+
+ public void activated()
+ {
+ super.activated();
+
+ IWorkbench workbench = PlatformUI.getWorkbench();
+ ICommandService commandSupport = (ICommandService)workbench.getAdapter(ICommandService.class);
+
+ if(commandSupport != null)
+ {
+ Command gotoCommand = commandSupport.getCommand(ID_GO_TO_ADDRESS_COMMAND);
+
+ if(fGoToAddressHandler == null)
+ {
+ fGoToAddressHandler = new AbstractHandler() {
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ // TODO
+ return null;
+ }
+ };
+ }
+ gotoCommand.setHandler(fGoToAddressHandler);
+ }
+
+ }
+
+ public void deactivated()
+ {
+ IWorkbench workbench = PlatformUI.getWorkbench();
+ ICommandService commandSupport = (ICommandService) workbench.getAdapter(ICommandService.class);
+
+ if(commandSupport != null)
+ {
+ // remove handler
+ Command command = commandSupport.getCommand(ID_GO_TO_ADDRESS_COMMAND);
+ command.setHandler(null);
+ }
+
+ super.deactivated();
+ }
+
+ public void setSelection(BigInteger start, BigInteger end)
+ {
+ fRendering.getSelection().setStart(start, start);
+ fRendering.getSelection().setEnd(end, end);
+ }
+
+ public void gotoAddress(final BigInteger address)
+ {
+ this.fRendering.gotoAddress(address);
+ }
+
+ public void updateRenderingLabels()
+ {
+ UIJob job = new UIJob("updateLabels"){ //$NON-NLS-1$
+ public IStatus runInUIThread(IProgressMonitor monitor) {
+
+ // update tab labels
+ String fLabel = getLabel();
+ firePropertyChangedEvent(new PropertyChangeEvent(TraditionalRendering.this,
+ IBasicPropertyConstants.P_TEXT, null, fLabel));
+
+ return Status.OK_STATUS;
+ }};
+ job.setSystem(true);
+ job.schedule();
+ }
+
+ private Color colorBackground;
+ private Color colorChanged;
+ private Color colorsChanged[] = null;
+ private Color colorEdit;
+ private Color colorSelection;
+ private Color colorText;
+ private Color colorTextAlternate;
+
+ public void allocateColors()
+ {
+ IPreferenceStore store = TraditionalRenderingPlugin.getDefault().getPreferenceStore();
+
+ colorBackground = new Color(Display.getDefault(), PreferenceConverter.getColor(store,
+ TraditionalRenderingPreferenceConstants.MEM_COLOR_BACKGROUND));
+
+ colorChanged = new Color(Display.getDefault(), PreferenceConverter.getColor(store,
+ TraditionalRenderingPreferenceConstants.MEM_COLOR_CHANGED));
+
+ colorEdit = new Color(Display.getDefault(), PreferenceConverter.getColor(store,
+ TraditionalRenderingPreferenceConstants.MEM_COLOR_EDIT));
+
+ colorSelection = new Color(Display.getDefault(), PreferenceConverter.getColor(store,
+ TraditionalRenderingPreferenceConstants.MEM_COLOR_SELECTION));
+
+ colorText = new Color(Display.getDefault(), PreferenceConverter.getColor(store,
+ TraditionalRenderingPreferenceConstants.MEM_COLOR_TEXT));
+
+ // alternate cell color
+ Color textColor = getColorText();
+ int red = textColor.getRed();
+ int green = textColor.getGreen();
+ int blue = textColor.getBlue();
+
+ float scale = (float) store.getInt(
+ TraditionalRenderingPreferenceConstants.MEM_LIGHTEN_DARKEN_ALTERNATE_CELLS);
+
+ red = (int) Math.min(red + ((255 - red) / 10) * scale, 255);
+ green = (int) Math.min(green + ((255 - green) / 10) * scale, 255);
+ blue = (int) Math.min(blue + ((255 - blue) / 10) * scale, 255);
+
+ colorTextAlternate = new Color(Display.getDefault(), new RGB(red, green, blue));
+ }
+
+ public void disposeColors()
+ {
+ if(colorBackground != null)
+ colorBackground.dispose();
+ colorBackground = null;
+
+ if(colorChanged != null)
+ colorChanged.dispose();
+ colorChanged = null;
+
+ if(colorEdit != null)
+ colorEdit.dispose();
+ colorEdit = null;
+
+ if(colorSelection != null)
+ colorSelection.dispose();
+ colorSelection = null;
+
+ if(colorText != null)
+ colorText.dispose();
+ colorText = null;
+
+ if(colorTextAlternate != null)
+ colorTextAlternate.dispose();
+ colorTextAlternate = null;
+
+ disposeChangedColors();
+ }
+
+ public void applyPreferences()
+ {
+ if(!fRendering.isDisposed())
+ {
+ IPreferenceStore store = TraditionalRenderingPlugin.getDefault().getPreferenceStore();
+
+ fRendering.setHistoryDepth(store.getInt(TraditionalRenderingPreferenceConstants.MEM_HISTORY_TRAILS_COUNT));
+
+ fRendering.setBackground(getColorBackground());
+
+ AbstractPane panes[] = fRendering.getRenderingPanes();
+ for(int i = 0; i < panes.length; i++)
+ panes[i].setBackground(getColorBackground());
+
+ setRenderingPadding(DebugUIPlugin.getDefault().getPreferenceStore().getString(IDebugUIConstants.PREF_PADDED_STR));
+
+ fRendering.redrawPanes();
+ }
+ }
+
+ public Color getColorBackground()
+ {
+ IPreferenceStore store = TraditionalRenderingPlugin.getDefault().getPreferenceStore();
+
+ if(store.getBoolean(TraditionalRenderingPreferenceConstants.MEM_USE_GLOBAL_BACKGROUND))
+ return Display.getDefault().getSystemColor(SWT.COLOR_LIST_BACKGROUND);
+ else
+ return colorBackground;
+ }
+
+ public Color getColorChanged()
+ {
+ return colorChanged;
+ }
+
+ private void disposeChangedColors()
+ {
+ if(colorsChanged != null)
+ for(int i = 0; i < colorsChanged.length; i++)
+ colorsChanged[i].dispose();
+ colorsChanged = null;
+ }
+
+ public Color[] getColorsChanged()
+ {
+ if(colorsChanged != null && colorsChanged.length != fRendering.getHistoryDepth())
+ {
+ disposeChangedColors();
+ }
+
+ if(colorsChanged == null)
+ {
+ colorsChanged = new Color[fRendering.getHistoryDepth()];
+ colorsChanged[0] = colorChanged;
+ int shades = fRendering.getHistoryDepth() + 4;
+ int red = (255 - colorChanged.getRed()) / shades;
+ int green = (255 - colorChanged.getGreen()) / shades;
+ int blue = (255 - colorChanged.getBlue()) / shades;
+ for(int i = 1; i < fRendering.getHistoryDepth(); i++)
+ {
+ colorsChanged[i] = new Color(colorChanged.getDevice(),
+ colorChanged.getRed() + ((shades - i) * red),
+ colorChanged.getGreen() + ((shades - i) * green),
+ colorChanged.getBlue() + ((shades - i) * blue));
+ }
+ }
+
+ return colorsChanged;
+ }
+
+ public Color getColorEdit()
+ {
+ return colorEdit;
+ }
+
+ public Color getColorSelection()
+ {
+ IPreferenceStore store = TraditionalRenderingPlugin.getDefault().getPreferenceStore();
+
+ if(store.getBoolean(TraditionalRenderingPreferenceConstants.MEM_USE_GLOBAL_SELECTION))
+ return Display.getDefault().getSystemColor(SWT.COLOR_LIST_SELECTION);
+ else
+ return colorSelection;
+ }
+
+ public Color getColorText()
+ {
+ IPreferenceStore store = TraditionalRenderingPlugin.getDefault().getPreferenceStore();
+
+ if(store.getBoolean(TraditionalRenderingPreferenceConstants.MEM_USE_GLOBAL_TEXT))
+ return Display.getDefault().getSystemColor(SWT.COLOR_LIST_FOREGROUND);
+ else
+ return colorText;
+ }
+
+ public Color getColorTextAlternate()
+ {
+ return colorTextAlternate;
+ }
+
+ public void createMenus()
+ {
+ // add the menu to each of the rendering panes
+ Control[] renderingControls = this.fRendering.getRenderingPanes();
+ for(int i = 0; i < renderingControls.length; i++)
+ super.createPopupMenu(renderingControls[i]);
+ super.createPopupMenu(this.fRendering);
+
+ // copy
+
+ final Action copyAction = new CopyAction(this.fRendering);
+
+ // copy address
+
+ final Action copyAddressAction = new Action(
+ TraditionalRenderingMessages
+ .getString("TraditionalRendering.COPY_ADDRESS")) //$NON-NLS-1$
+ {
+ public void run()
+ {
+ Display.getDefault().asyncExec(new Runnable()
+ {
+ public void run()
+ {
+ TraditionalRendering.this.fRendering.copyAddressToClipboard();
+ }
+ });
+ }
+ };
+
+ // go to address
+
+ final Action gotoAddressAction = new GoToAddressAction(TraditionalRendering.this)
+ {
+ public void run() {
+ TraditionalRendering.this.fRendering
+ .setVisibleAddressBar(true);
+ }
+ };
+
+ // reset to base address
+
+ final Action gotoBaseAddressAction = new Action(
+ TraditionalRenderingMessages
+ .getString("TraditionalRendering.RESET_TO_BASE_ADDRESS")) //$NON-NLS-1$
+ {
+ public void run()
+ {
+ Display.getDefault().asyncExec(new Runnable()
+ {
+ public void run()
+ {
+ TraditionalRendering.this.fRendering
+ .gotoAddress(TraditionalRendering.this.fRendering.fBaseAddress);
+ }
+ });
+ }
+ };
+
+
+ // refresh
+
+ final Action refreshAction = new Action(
+ TraditionalRenderingMessages
+ .getString("TraditionalRendering.REFRESH")) //$NON-NLS-1$
+ {
+ public void run()
+ {
+ Display.getDefault().asyncExec(new Runnable()
+ {
+ public void run()
+ {
+ // For compatibility with DSF update modes (hopefully this will either be replaced by an enhanced
+ // platform interface or the caching will move out of the data layer
+ try {
+ Method m = fRendering.getMemoryBlock().getClass().getMethod("clearCache", new Class[0]);
+ if(m != null)
+ m.invoke(fRendering.getMemoryBlock(), new Object[0]);
+ }
+ catch (Exception e)
+ {
+ }
+
+ TraditionalRendering.this.fRendering.refresh();
+ }
+ });
+ }
+ };
+
+ // display address
+
+ final Action displayAddressPaneAction = new Action(
+ TraditionalRenderingMessages
+ .getString("TraditionalRendering.ADDRESS"), //$NON-NLS-1$
+ IAction.AS_CHECK_BOX)
+ {
+ public void run()
+ {
+ TraditionalRendering.this.fRendering.setPaneVisible(
+ Rendering.PANE_ADDRESS, isChecked());
+ }
+ };
+ displayAddressPaneAction.setChecked(this.fRendering
+ .getPaneVisible(Rendering.PANE_ADDRESS));
+
+ // display hex
+
+ final Action displayBinaryPaneAction = new Action(
+ TraditionalRenderingMessages
+ .getString("TraditionalRendering.BINARY"), //$NON-NLS-1$
+ IAction.AS_CHECK_BOX)
+ {
+ public void run()
+ {
+ TraditionalRendering.this.fRendering.setPaneVisible(
+ Rendering.PANE_BINARY, isChecked());
+ }
+ };
+ displayBinaryPaneAction.setChecked(this.fRendering
+ .getPaneVisible(Rendering.PANE_BINARY));
+
+ // display text
+
+ final Action displayTextPaneAction = new Action(
+ TraditionalRenderingMessages
+ .getString("TraditionalRendering.TEXT"), //$NON-NLS-1$
+ IAction.AS_CHECK_BOX)
+ {
+ public void run()
+ {
+ TraditionalRendering.this.fRendering.setPaneVisible(
+ Rendering.PANE_TEXT, isChecked());
+ }
+ };
+ displayTextPaneAction.setChecked(this.fRendering
+ .getPaneVisible(Rendering.PANE_TEXT));
+
+ // display size
+
+ final Action displaySize1BytesAction = new Action(
+ TraditionalRenderingMessages
+ .getString("TraditionalRendering.1_BYTE"), //$NON-NLS-1$
+ IAction.AS_RADIO_BUTTON)
+ {
+ public void run()
+ {
+ TraditionalRendering.this.fRendering.setBytesPerColumn(1);
+ }
+ };
+ displaySize1BytesAction
+ .setChecked(this.fRendering.getBytesPerColumn() == 1);
+
+ final Action displaySize2BytesAction = new Action(
+ TraditionalRenderingMessages
+ .getString("TraditionalRendering.2_BYTES"), IAction.AS_RADIO_BUTTON) //$NON-NLS-1$
+ {
+ public void run()
+ {
+ TraditionalRendering.this.fRendering.setBytesPerColumn(2);
+ }
+ };
+ displaySize2BytesAction
+ .setChecked(this.fRendering.getBytesPerColumn() == 2);
+
+ final Action displaySize4BytesAction = new Action(
+ TraditionalRenderingMessages
+ .getString("TraditionalRendering.4_BYTES"), IAction.AS_RADIO_BUTTON) //$NON-NLS-1$
+ {
+ public void run()
+ {
+ TraditionalRendering.this.fRendering.setBytesPerColumn(4);
+ }
+ };
+ displaySize4BytesAction
+ .setChecked(this.fRendering.getBytesPerColumn() == 4);
+
+ final Action displaySize8BytesAction = new Action(
+ TraditionalRenderingMessages
+ .getString("TraditionalRendering.8_BYTES"), IAction.AS_RADIO_BUTTON) //$NON-NLS-1$
+ {
+ public void run()
+ {
+ TraditionalRendering.this.fRendering.setBytesPerColumn(8);
+ }
+ };
+ displaySize8BytesAction
+ .setChecked(this.fRendering.getBytesPerColumn() == 8);
+
+ // text / unicode ?
+
+ final Action displayCharactersISO8859Action = new Action(
+ TraditionalRenderingMessages
+ .getString("TraditionalRendering.ISO-8859-1"), //$NON-NLS-1$
+ IAction.AS_RADIO_BUTTON)
+ {
+ public void run()
+ {
+ TraditionalRendering.this.fRendering
+ .setTextMode(Rendering.TEXT_ISO_8859_1);
+ }
+ };
+ displayCharactersISO8859Action.setChecked(this.fRendering
+ .getTextMode() == Rendering.TEXT_ISO_8859_1);
+
+ final Action displayCharactersUSASCIIAction = new Action(
+ TraditionalRenderingMessages
+ .getString("TraditionalRendering.USASCII"), //$NON-NLS-1$
+ IAction.AS_RADIO_BUTTON)
+ {
+ public void run()
+ {
+ TraditionalRendering.this.fRendering
+ .setTextMode(Rendering.TEXT_USASCII);
+ }
+ };
+ displayCharactersUSASCIIAction.setChecked(this.fRendering
+ .getTextMode() == Rendering.TEXT_USASCII);
+
+ final Action displayCharactersUTF8Action = new Action(
+ TraditionalRenderingMessages
+ .getString("TraditionalRendering.UTF8"), IAction.AS_RADIO_BUTTON) //$NON-NLS-1$
+ {
+ public void run()
+ {
+ TraditionalRendering.this.fRendering
+ .setTextMode(Rendering.TEXT_UTF8);
+ }
+ };
+ displayCharactersUTF8Action.setChecked(this.fRendering
+ .getTextMode() == Rendering.TEXT_UTF8);
+
+// final Action displayCharactersUTF16Action = new Action(
+// TraditionalRenderingMessages
+// .getString("TraditionalRendering.UTF16"), IAction.AS_RADIO_BUTTON) //$NON-NLS-1$
+// {
+// @Override
+// public void run()
+// {
+// TraditionalRendering.this.fRendering
+// .setTextMode(Rendering.TEXT_UTF16);
+// }
+// };
+// displayCharactersUTF16Action.setChecked(this.fRendering
+// .getTextMode() == Rendering.TEXT_UTF16);
+
+ // endian
+
+ displayEndianBigAction = new Action(
+ TraditionalRenderingMessages
+ .getString("TraditionalRendering.BIG"), //$NON-NLS-1$
+ IAction.AS_RADIO_BUTTON)
+ {
+ public void run()
+ {
+ TraditionalRendering.this.fRendering
+ .setDisplayLittleEndian(false);
+ }
+ };
+ displayEndianBigAction.setChecked(!this.fRendering.isTargetLittleEndian());
+
+ displayEndianLittleAction = new Action(
+ TraditionalRenderingMessages
+ .getString("TraditionalRendering.LITTLE"), //$NON-NLS-1$
+ IAction.AS_RADIO_BUTTON)
+ {
+ public void run()
+ {
+ TraditionalRendering.this.fRendering
+ .setDisplayLittleEndian(true);
+ }
+ };
+ displayEndianLittleAction.setChecked(this.fRendering.isTargetLittleEndian());
+
+ // radix
+
+ final Action displayRadixHexAction = new Action(
+ TraditionalRenderingMessages
+ .getString("TraditionalRendering.HEX"), //$NON-NLS-1$
+ IAction.AS_RADIO_BUTTON)
+ {
+ public void run()
+ {
+ TraditionalRendering.this.fRendering
+ .setRadix(Rendering.RADIX_HEX);
+ }
+ };
+ displayRadixHexAction
+ .setChecked(this.fRendering.getRadix() == Rendering.RADIX_HEX);
+
+ final Action displayRadixDecSignedAction = new Action(
+ TraditionalRenderingMessages
+ .getString("TraditionalRendering.DECIMAL_SIGNED"), IAction.AS_RADIO_BUTTON) //$NON-NLS-1$
+ {
+ public void run()
+ {
+ TraditionalRendering.this.fRendering
+ .setRadix(Rendering.RADIX_DECIMAL_SIGNED);
+ }
+ };
+ displayRadixDecSignedAction
+ .setChecked(this.fRendering.getRadix() == Rendering.RADIX_DECIMAL_SIGNED);
+
+ final Action displayRadixDecUnsignedAction = new Action(
+ TraditionalRenderingMessages
+ .getString("TraditionalRendering.DECIMAL_UNSIGNED"), IAction.AS_RADIO_BUTTON) //$NON-NLS-1$
+ {
+ public void run()
+ {
+ TraditionalRendering.this.fRendering
+ .setRadix(Rendering.RADIX_DECIMAL_UNSIGNED);
+ }
+ };
+ displayRadixDecUnsignedAction
+ .setChecked(this.fRendering.getRadix() == Rendering.RADIX_DECIMAL_UNSIGNED);
+
+ final Action displayRadixOctAction = new Action(
+ TraditionalRenderingMessages
+ .getString("TraditionalRendering.OCTAL"), //$NON-NLS-1$
+ IAction.AS_RADIO_BUTTON)
+ {
+ public void run()
+ {
+ TraditionalRendering.this.fRendering
+ .setRadix(Rendering.RADIX_OCTAL);
+ }
+ };
+ displayRadixOctAction
+ .setChecked(this.fRendering.getRadix() == Rendering.RADIX_OCTAL);
+
+ final Action displayRadixBinAction = new Action(
+ TraditionalRenderingMessages
+ .getString("TraditionalRendering.BINARY"), //$NON-NLS-1$
+ IAction.AS_RADIO_BUTTON)
+ {
+ public void run()
+ {
+ TraditionalRendering.this.fRendering
+ .setRadix(Rendering.RADIX_BINARY);
+ }
+ };
+ displayRadixBinAction
+ .setChecked(this.fRendering.getRadix() == Rendering.RADIX_BINARY);
+
+ final Action displayColumnCountAuto = new Action(
+ TraditionalRenderingMessages
+ .getString("TraditionalRendering.COLUMN_COUNT_AUTO"), //$NON-NLS-1$
+ IAction.AS_RADIO_BUTTON)
+ {
+ public void run()
+ {
+ TraditionalRendering.this.fRendering.setColumnsSetting(Rendering.COLUMNS_AUTO_SIZE_TO_FIT);
+ }
+ };
+ displayColumnCountAuto.setChecked(fRendering.getColumnsSetting() == Rendering.COLUMNS_AUTO_SIZE_TO_FIT);
+
+ final Action[] displayColumnCounts = new Action[MAX_MENU_COLUMN_COUNT];
+ for(int i = 0, j = 1; i < MAX_MENU_COLUMN_COUNT; i++, j*=2)
+ {
+ final int finali = j;
+ displayColumnCounts[i] = new Action(
+ TraditionalRenderingMessages
+ .getString("TraditionalRendering.COLUMN_COUNT_" + finali), //$NON-NLS-1$
+ IAction.AS_RADIO_BUTTON)
+ {
+ public void run()
+ {
+ TraditionalRendering.this.fRendering.setColumnsSetting(finali);
+ }
+ };
+ displayColumnCounts[i].setChecked(fRendering.getColumnsSetting() == finali);
+ }
+
+ final Action displayColumnCountCustomValue = new Action("", IAction.AS_RADIO_BUTTON)
+ {
+ public void run()
+ {
+ }
+ };
+
+ final Action displayColumnCountCustom = new Action(
+ TraditionalRenderingMessages
+ .getString("TraditionalRendering.COLUMN_COUNT_CUSTOM"), //$NON-NLS-1$
+ IAction.AS_RADIO_BUTTON)
+ {
+ public void run()
+ {
+ InputDialog inputDialog = new InputDialog(
+ fRendering.getShell(),
+ "Set Column Count", //$NON-NLS-1$
+ "Please enter column count", //$NON-NLS-1$
+ "", //$NON-NLS-1$
+ new IInputValidator() {
+ public String isValid(String input) {
+ try {
+ int i= Integer.parseInt(input);
+ if (i <= 0)
+ return "Please enter a positive integer"; //$NON-NLS-1$
+ if (i > 200)
+ return "Please enter a positive integer not greater than 200"; //$NON-NLS-1$
+
+ } catch (NumberFormatException x) {
+ return "Please enter a positive integer"; //$NON-NLS-1$
+ }
+ return null;
+ }
+ }
+ );
+
+ if (inputDialog.open() != Window.OK)
+ {
+ this.setChecked(false);
+ int currentColumnSetting = TraditionalRendering.this.fRendering.getColumnsSetting();
+ if(currentColumnSetting == Rendering.COLUMNS_AUTO_SIZE_TO_FIT)
+ displayColumnCountAuto.setChecked(true);
+ else
+ {
+ boolean currentCountIsCustom = true;
+ for(int i = 0, j = 1; i < MAX_MENU_COLUMN_COUNT && currentCountIsCustom; i++, j*=2)
+ {
+ currentCountIsCustom = (j != fRendering.getColumnsSetting());
+ if(j == fRendering.getColumnsSetting())
+ displayColumnCounts[i].setChecked(true);
+ }
+ if(currentCountIsCustom)
+ displayColumnCountCustomValue.setChecked(true);
+ }
+
+ return;
+ }
+
+ int newColumnCount = -1;
+ try {
+ newColumnCount = Integer.parseInt(inputDialog.getValue());
+ } catch (NumberFormatException x) { assert false; }
+
+ boolean customIsOneOfStandardListChoices = false;
+
+ for(int i = 0, j = 1; i < MAX_MENU_COLUMN_COUNT; i++, j*=2) {
+ if ( newColumnCount == j ) {
+ customIsOneOfStandardListChoices = true;
+ TraditionalRendering.this.fRendering.setColumnsSetting(newColumnCount);
+ this.setChecked(false);
+ displayColumnCountCustomValue.setChecked(false);
+ displayColumnCounts[i].setChecked(true);
+ break;
+ }
+ }
+
+ if ( ! customIsOneOfStandardListChoices ) {
+ TraditionalRendering.this.fRendering.setColumnsSetting(newColumnCount);
+ this.setChecked(false);
+
+ displayColumnCountCustomValue.setChecked(true);
+ displayColumnCountCustomValue.setText(Integer.valueOf(
+ fRendering.getColumnsSetting()).toString());
+ }
+ }
+ };
+
+ getPopupMenuManager().addMenuListener(new IMenuListener()
+ {
+ public void menuAboutToShow(IMenuManager manager)
+ {
+ manager.add(new Separator());
+
+ MenuManager sub = new MenuManager(
+ TraditionalRenderingMessages
+ .getString("TraditionalRendering.PANES")); //$NON-NLS-1$
+ sub.add(displayAddressPaneAction);
+ sub.add(displayBinaryPaneAction);
+ sub.add(displayTextPaneAction);
+ manager.add(sub);
+
+ sub = new MenuManager(TraditionalRenderingMessages
+ .getString("TraditionalRendering.ENDIAN")); //$NON-NLS-1$
+ sub.add(displayEndianBigAction);
+ sub.add(displayEndianLittleAction);
+ manager.add(sub);
+
+ sub = new MenuManager(TraditionalRenderingMessages
+ .getString("TraditionalRendering.TEXT")); //$NON-NLS-1$
+ sub.add(displayCharactersISO8859Action);
+ sub.add(displayCharactersUSASCIIAction);
+ sub.add(displayCharactersUTF8Action);
+ //sub.add(displayCharactersUTF16Action);
+ manager.add(sub);
+
+ sub = new MenuManager(TraditionalRenderingMessages
+ .getString("TraditionalRendering.CELL_SIZE")); //$NON-NLS-1$
+ sub.add(displaySize1BytesAction);
+ sub.add(displaySize2BytesAction);
+ sub.add(displaySize4BytesAction);
+ sub.add(displaySize8BytesAction);
+ manager.add(sub);
+
+ sub = new MenuManager(TraditionalRenderingMessages
+ .getString("TraditionalRendering.RADIX")); //$NON-NLS-1$
+ sub.add(displayRadixHexAction);
+ sub.add(displayRadixDecSignedAction);
+ sub.add(displayRadixDecUnsignedAction);
+ sub.add(displayRadixOctAction);
+ sub.add(displayRadixBinAction);
+ manager.add(sub);
+
+ sub = new MenuManager(TraditionalRenderingMessages
+ .getString("TraditionalRendering.COLUMN_COUNT")); //$NON-NLS-1$
+ sub.add(displayColumnCountAuto);
+ for(int i = 0; i < displayColumnCounts.length; i++)
+ sub.add(displayColumnCounts[i]);
+
+ boolean currentCountIsCustom = fRendering.getColumnsSetting() != 0;
+ for(int i = 0, j = 1; i < MAX_MENU_COLUMN_COUNT && currentCountIsCustom; i++, j*=2)
+ currentCountIsCustom = (j != fRendering.getColumnsSetting());
+ if(currentCountIsCustom)
+ sub.add(displayColumnCountCustomValue);
+
+ sub.add(displayColumnCountCustom);
+ manager.add(sub);
+ manager.add(new Separator());
+
+ manager.add(copyAction);
+ manager.add(copyAddressAction);
+
+ // IMemoryGoToAddressProvider interface, called using reflection, waiting on platform acceptance of patch
+ final IMemoryBlockRetrieval retrieve = MemoryViewUtil.getMemoryBlockRetrieval(TraditionalRendering.this.getMemoryBlock());
+ if (retrieve != null)
+ {
+ try
+ {
+ Method m = retrieve.getClass().getMethod("getGoToAddressRenderingId", new Class[] {});
+ m.setAccessible(true);
+
+ if(m != null)
+ {
+ String id = (String) m.invoke(retrieve, new Object[] {});
+ if(id == null)
+ manager.add(gotoAddressAction);
+ }
+ }
+ catch(Exception e)
+ {
+ // do nothing
+ }
+ }
+
+ manager.add(gotoBaseAddressAction);
+ manager.add(refreshAction);
+ manager.add(new Separator());
+ manager.add(new Separator(
+ IWorkbenchActionConstants.MB_ADDITIONS));
+ }
+ });
+
+ }
+
+ public Control getControl()
+ {
+ return this.fRendering;
+ }
+
+
+ // selection is terminology for caret position
+ public BigInteger getSelectedAddress() {
+ IMemorySelection selection = fRendering.getSelection();
+ if (selection == null || selection.getStart() == null)
+ return fRendering.getCaretAddress();
+
+ return selection.getStartLow();
+ }
+
+ public MemoryByte[] getSelectedAsBytes() {
+ try
+ {
+ // default to the caret address and the cell count size
+ BigInteger startAddr = fRendering.getCaretAddress();
+ int byteCount = fRendering.getBytesPerColumn();
+
+ // Now see if there's a selection
+ IMemorySelection selection = fRendering.getSelection();
+ if (selection != null && selection.getStart() != null)
+ {
+ // The implementation is such that just having a caret somewhere
+ // (without multiple cells being selected) constitutes a selection,
+ // except for when the rendering is in its initial state. I.e.,
+ // just because we get here doesn't mean the user has selected more
+ // than one cell.
+
+ startAddr = getSelectedAddress();
+
+ if (selection.getHigh() != null)
+ {
+ byteCount = selection.getHigh().subtract(selection.getLow()).intValue() * fRendering.getAddressableSize();
+ }
+ }
+ return fRendering.getViewportCache().getBytes(startAddr, byteCount);
+
+ }
+ catch(DebugException de)
+ {
+ // FIXME log?
+ return null;
+ }
+ }
+
+ public void goToAddress(final BigInteger address) throws DebugException {
+ Display.getDefault().asyncExec(new Runnable(){
+ public void run()
+ {
+ fRendering.gotoAddress(address);
+ }
+ });
+ }
+
+ protected void setTargetMemoryLittleEndian(boolean littleEndian)
+ {
+ // once we actually read memory we can determine the
+ // endianess and need to set these actions accordingly.
+ displayEndianBigAction.setChecked(!littleEndian);
+ displayEndianLittleAction.setChecked(littleEndian);
+
+ // when target endian changes, force display endian to track.
+ // user can then change display endian if desired.
+ fRendering.setDisplayLittleEndian(littleEndian);
+ }
+
+ public void dispose()
+ {
+ if(this.fRendering != null)
+ this.fRendering.dispose();
+ disposeColors();
+ super.dispose();
+ }
+
+ public Object getAdapter(Class adapter)
+ {
+ if(adapter == IWorkbenchAdapter.class)
+ {
+ if(this.fWorkbenchAdapter == null)
+ {
+ this.fWorkbenchAdapter = new IWorkbenchAdapter()
+ {
+ public Object[] getChildren(Object o)
+ {
+ return new Object[0];
+ }
+
+ public ImageDescriptor getImageDescriptor(Object object)
+ {
+ return null;
+ }
+
+ public String getLabel(Object o)
+ {
+ return TraditionalRenderingMessages
+ .getString("TraditionalRendering.RENDERING_NAME"); //$NON-NLS-1$
+ }
+
+ public Object getParent(Object o)
+ {
+ return null;
+ }
+ };
+ }
+ return this.fWorkbenchAdapter;
+ }
+
+ if (adapter == IMemoryBlockConnection.class)
+ {
+ if (fConnection == null)
+ {
+ fConnection = new IMemoryBlockConnection()
+ {
+ public void update()
+ {
+ // update UI asynchronously
+ Display display = DebugUIPlugin.getDefault().getWorkbench().getDisplay();
+ display.asyncExec(new Runnable() {
+ public void run() {
+ try
+ {
+ if(fBigBaseAddress != TraditionalRendering.this.fRendering.getMemoryBlock().getBigBaseAddress())
+ {
+ fBigBaseAddress = TraditionalRendering.this.fRendering.getMemoryBlock().getBigBaseAddress();
+ TraditionalRendering.this.fRendering.gotoAddress(fBigBaseAddress);
+ }
+ TraditionalRendering.this.fRendering.refresh();
+ }
+ catch (DebugException e)
+ {
+ }
+ }
+ });
+ }
+ };
+ }
+ return fConnection;
+ }
+
+ return super.getAdapter(adapter);
+ }
+
+ public void resetRendering() throws DebugException {
+ fRendering.gotoAddress(fRendering.fBaseAddress);
+ }
+}
+
+
+class TraditionalMemoryByte extends MemoryByte implements IMemoryByte
+{
+ private boolean isEdited = false;
+
+ private boolean[] changeHistory = new boolean[0];
+
+ public TraditionalMemoryByte()
+ {
+ super();
+ }
+
+ public TraditionalMemoryByte(byte byteValue)
+ {
+ super(byteValue);
+ }
+
+ public TraditionalMemoryByte(byte byteValue, byte byteFlags)
+ {
+ super(byteValue, byteFlags);
+ }
+
+ public boolean isEdited()
+ {
+ return isEdited;
+ }
+
+ public void setEdited(boolean edited)
+ {
+ isEdited = edited;
+ }
+
+ public boolean isChanged(int historyDepth)
+ {
+ return changeHistory.length > historyDepth && changeHistory[historyDepth];
+ }
+
+ public void setChanged(int historyDepth, boolean changed)
+ {
+ if(historyDepth >= changeHistory.length)
+ {
+ boolean newChangeHistory[] = new boolean[historyDepth + 1];
+ System.arraycopy(changeHistory, 0, newChangeHistory, 0, changeHistory.length);
+ changeHistory = newChangeHistory;
+ }
+
+ changeHistory[historyDepth] = changed;
+
+ if(historyDepth == 0)
+ this.setChanged(changed);
+ }
+}
+
+class CopyAction extends Action
+{
+ // TODO for the sake of large copies, this action should probably read in
+ // blocks on a Job.
+
+ private Rendering fRendering;
+ private int fType = DND.CLIPBOARD;
+
+ public CopyAction(Rendering rendering)
+ {
+ this(rendering, DND.CLIPBOARD);
+ }
+
+ public CopyAction(Rendering rendering, int clipboardType)
+ {
+ super();
+ fType = clipboardType;
+ fRendering = rendering;
+ setText(DebugUIMessages.CopyViewToClipboardAction_title);
+ setToolTipText(DebugUIMessages.CopyViewToClipboardAction_tooltip);
+ setImageDescriptor(DebugPluginImages
+ .getImageDescriptor(IInternalDebugUIConstants.IMG_ELCL_COPY_VIEW_TO_CLIPBOARD));
+ setHoverImageDescriptor(DebugPluginImages
+ .getImageDescriptor(IInternalDebugUIConstants.IMG_LCL_COPY_VIEW_TO_CLIPBOARD));
+ setDisabledImageDescriptor(DebugPluginImages
+ .getImageDescriptor(IInternalDebugUIConstants.IMG_DLCL_COPY_VIEW_TO_CLIPBOARD));
+ }
+
+ public void run()
+ {
+ final String PANE_SPACING = " "; //$NON-NLS-1$
+
+ Clipboard clip = null;
+ try
+ {
+ clip = new Clipboard(fRendering.getDisplay());
+
+ BigInteger start = fRendering.getSelection().getStart();
+ BigInteger end = fRendering.getSelection().getEnd();
+ // end will be null when there is nothing selected
+ if (end == null)
+ return;
+
+ if(start.compareTo(end) > 0)
+ {
+ // swap start and end
+
+ BigInteger bigI = end;
+ end = start;
+ start = bigI;
+ }
+
+ final int radix = fRendering.getRadix();
+ final int bytesPerColumn = fRendering.getBytesPerColumn();
+ final boolean isLittleEndian = fRendering.isTargetLittleEndian();
+ final int bytesPerCharacter = fRendering.getBytesPerCharacter();
+
+ final int addressWidth = fRendering.getAddressString(start)
+ .length();
+
+ final int binaryCellWidth = fRendering.getRadixCharacterCount(
+ radix, bytesPerColumn) + 1;
+
+ final int asciiCellWidth = fRendering.getBytesPerColumn()
+ / fRendering.getBytesPerCharacter();
+
+ final int combindCellWidths = (fRendering
+ .getPaneVisible(Rendering.PANE_BINARY) ? binaryCellWidth : 0)
+ + (fRendering.getPaneVisible(Rendering.PANE_TEXT) ? asciiCellWidth
+ : 0);
+
+ final int columns = fRendering.getColumnCount();
+
+ BigInteger lengthToRead = end.subtract(start);
+
+ int rows = lengthToRead.divide(
+ BigInteger.valueOf(columns * bytesPerColumn)).intValue();
+
+ if(rows * columns * bytesPerColumn < lengthToRead.intValue())
+ rows++;
+
+ StringBuffer buffer = new StringBuffer();
+
+ for(int row = 0; row < rows; row++)
+ {
+ BigInteger rowAddress = start.add(BigInteger.valueOf(row
+ * columns * bytesPerColumn));
+
+ if(fRendering.getPaneVisible(Rendering.PANE_ADDRESS))
+ {
+ buffer.append(fRendering.getAddressString(rowAddress));
+ buffer.append(PANE_SPACING);
+ }
+
+ if(fRendering.getPaneVisible(Rendering.PANE_BINARY))
+ {
+ for(int col = 0; col < columns; col++)
+ {
+ BigInteger cellAddress = rowAddress.add(BigInteger
+ .valueOf(col * bytesPerColumn));
+
+ if(cellAddress.compareTo(end) < 0)
+ {
+ try
+ {
+ MemoryByte bytes[] = fRendering.getBytes(
+ cellAddress, bytesPerColumn);
+ buffer.append(fRendering.getRadixText(bytes,
+ radix, isLittleEndian));
+ }
+ catch(DebugException de)
+ {
+ fRendering
+ .logError(
+ TraditionalRenderingMessages
+ .getString("TraditionalRendering.FAILURE_COPY_OPERATION"), de); //$NON-NLS-1$
+ return;
+ }
+ }
+ else
+ {
+ for(int i = fRendering.getRadixCharacterCount(
+ radix, bytesPerColumn); i > 0; i--)
+ buffer.append(' ');
+ }
+
+ if(col != columns - 1)
+ buffer.append(' ');
+ }
+ }
+
+ if(fRendering.getPaneVisible(Rendering.PANE_BINARY)
+ && fRendering.getPaneVisible(Rendering.PANE_TEXT))
+ {
+ buffer.append(PANE_SPACING);
+ }
+
+ if(fRendering.getPaneVisible(Rendering.PANE_TEXT))
+ {
+ for(int col = 0; col < columns; col++)
+ {
+ BigInteger cellAddress = rowAddress.add(BigInteger
+ .valueOf(col * fRendering.getBytesPerColumn()));
+
+ if(cellAddress.compareTo(end) < 0)
+ {
+ try
+ {
+ MemoryByte bytes[] = fRendering
+ .getBytes(cellAddress, fRendering
+ .getBytesPerColumn());
+ buffer.append(fRendering.formatText(bytes,
+ isLittleEndian, fRendering.getTextMode()));
+ }
+ catch(DebugException de)
+ {
+ fRendering
+ .logError(
+ TraditionalRenderingMessages
+ .getString("TraditionalRendering.FAILURE_COPY_OPERATION"), de); //$NON-NLS-1$
+ return;
+ }
+ }
+ else
+ {
+
+ }
+ }
+ }
+
+ buffer.append("\n"); //$NON-NLS-1$
+ }
+
+ if(buffer.length() > 0)
+ {
+ TextTransfer plainTextTransfer = TextTransfer.getInstance();
+ clip.setContents(new Object[] { buffer.toString() },
+ new Transfer[] { plainTextTransfer }, fType);
+ }
+ }
+ finally
+ {
+ if(clip != null)
+ {
+ clip.dispose();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/TraditionalRenderingMessages.java b/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/TraditionalRenderingMessages.java
new file mode 100644
index 00000000000..d54f864851f
--- /dev/null
+++ b/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/TraditionalRenderingMessages.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2006-2009 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Ted R Williams (Wind River Systems, Inc.) - initial implementation
+ *******************************************************************************/
+
+package org.eclipse.cdt.debug.ui.memory.traditional;
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class TraditionalRenderingMessages
+{
+ private static final String BUNDLE_NAME = "org.eclipse.cdt.debug.ui.memory.traditional.TraditionalRendering_messages"; //$NON-NLS-1$
+
+ private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle
+ .getBundle(BUNDLE_NAME);
+
+ private TraditionalRenderingMessages()
+ {
+ }
+
+ public static String getString(String key)
+ {
+ // TODO Auto-generated method stub
+ try
+ {
+ return RESOURCE_BUNDLE.getString(key);
+ }
+ catch(MissingResourceException e)
+ {
+ return '!' + key + '!';
+ }
+ }
+}
diff --git a/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/TraditionalRenderingPlugin.java b/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/TraditionalRenderingPlugin.java
new file mode 100644
index 00000000000..0dbc658fd1a
--- /dev/null
+++ b/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/TraditionalRenderingPlugin.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2006-2009 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Ted R Williams (Wind River Systems, Inc.) - initial implementation
+ *******************************************************************************/
+
+package org.eclipse.cdt.debug.ui.memory.traditional;
+
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+
+public class TraditionalRenderingPlugin extends AbstractUIPlugin
+{
+ private static final String PLUGIN_ID = "org.eclipse.cdt.debug.ui.memory.traditional"; //$NON-NLS-1$
+
+ private static TraditionalRenderingPlugin plugin;
+
+ public TraditionalRenderingPlugin()
+ {
+ super();
+ plugin = this;
+ }
+
+ /**
+ * Returns the shared instance.
+ */
+ public static TraditionalRenderingPlugin getDefault() {
+ return plugin;
+ }
+
+ /**
+ * Returns the unique identifier for this plugin.
+ */
+ public static String getUniqueIdentifier() {
+ return PLUGIN_ID;
+ }
+}
diff --git a/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/TraditionalRenderingPreferenceAction.java b/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/TraditionalRenderingPreferenceAction.java
new file mode 100644
index 00000000000..5763d2ccdfb
--- /dev/null
+++ b/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/TraditionalRenderingPreferenceAction.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright (c) 2006-2009 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Ted R Williams (Wind River Systems, Inc.) - initial implementation
+ *******************************************************************************/
+
+package org.eclipse.cdt.debug.ui.memory.traditional;
+
+
+import org.eclipse.debug.internal.ui.DebugUIPlugin;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.preference.IPreferenceNode;
+import org.eclipse.jface.preference.IPreferencePage;
+import org.eclipse.jface.preference.PreferenceDialog;
+import org.eclipse.jface.preference.PreferenceManager;
+import org.eclipse.jface.preference.PreferenceNode;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.custom.BusyIndicator;
+import org.eclipse.ui.IViewActionDelegate;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.actions.ActionDelegate;
+
+public class TraditionalRenderingPreferenceAction extends ActionDelegate implements IViewActionDelegate {
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
+ */
+ public void run(IAction action) {
+ IPreferencePage page = new TraditionalRenderingPreferencePage();
+ showPreferencePage("org.eclipse.cdt.debug.ui.memory.traditional.TraditionalRenderingPreferencePage", page); //$NON-NLS-1$
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IViewActionDelegate#init(org.eclipse.ui.IViewPart)
+ */
+ public void init(IViewPart view) {
+ }
+
+ protected void showPreferencePage(String id, IPreferencePage page) {
+ final IPreferenceNode targetNode = new PreferenceNode(id, page);
+
+ PreferenceManager manager = new PreferenceManager();
+ manager.addToRoot(targetNode);
+ final PreferenceDialog dialog = new PreferenceDialog(DebugUIPlugin.getShell(), manager);
+ final boolean [] result = new boolean[] { false };
+ BusyIndicator.showWhile(DebugUIPlugin.getStandardDisplay(), new Runnable() {
+ public void run() {
+ dialog.create();
+ dialog.setMessage(targetNode.getLabelText());
+ result[0]= (dialog.open() == Window.OK);
+ }
+ });
+ }
+
+}
+
diff --git a/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/TraditionalRenderingPreferenceConstants.java b/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/TraditionalRenderingPreferenceConstants.java
new file mode 100644
index 00000000000..934e7c29876
--- /dev/null
+++ b/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/TraditionalRenderingPreferenceConstants.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2006-2009 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Ted R Williams (Wind River Systems, Inc.) - initial implementation
+ *******************************************************************************/
+
+package org.eclipse.cdt.debug.ui.memory.traditional;
+
+/**
+ * Constant definitions for plug-in preferences
+ */
+public class TraditionalRenderingPreferenceConstants {
+
+ public static final String MEM_COLOR_CHANGED = "memoryColorChanged";
+
+ public static final String MEM_USE_GLOBAL_BACKGROUND = "memUseGlobalBackground";
+
+ public static final String MEM_COLOR_BACKGROUND = "memoryColorBackground";
+
+ public static final String MEM_COLOR_EDIT = "memoryColorEdit";
+
+ public static final String MEM_COLOR_TEXT = "memoryColorText";
+
+ public static final String MEM_USE_GLOBAL_SELECTION = "memUseGlobalSelection";
+
+ public static final String MEM_COLOR_SELECTION = "memoryColorSelection";
+
+ public static final String MEM_USE_GLOBAL_TEXT = "memUseGlobalText";
+
+ public static final String MEM_LIGHTEN_DARKEN_ALTERNATE_CELLS = "memoryColorScaleTextAlternate";
+
+ public static final String MEM_EDIT_BUFFER_SAVE = "memoryEditBufferSave";
+
+ public static final String MEM_EDIT_BUFFER_SAVE_ON_ENTER_ONLY = "saveOnEnterCancelOnFocusLost";
+
+ public static final String MEM_EDIT_BUFFER_SAVE_ON_ENTER_OR_FOCUS_LOST = "saveOnEnterOrFocusLost";
+
+ public static final String MEM_HISTORY_TRAILS_COUNT = "memoryHistoryTrailsCount";
+
+}
diff --git a/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/TraditionalRenderingPreferenceInitializer.java b/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/TraditionalRenderingPreferenceInitializer.java
new file mode 100644
index 00000000000..3e097300be9
--- /dev/null
+++ b/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/TraditionalRenderingPreferenceInitializer.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2006-2009 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Ted R Williams (Wind River Systems, Inc.) - initial implementation
+ *******************************************************************************/
+
+
+package org.eclipse.cdt.debug.ui.memory.traditional;
+
+import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * Class used to initialize default preference values.
+ */
+public class TraditionalRenderingPreferenceInitializer extends AbstractPreferenceInitializer {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer#initializeDefaultPreferences()
+ */
+ public void initializeDefaultPreferences() {
+ IPreferenceStore store = TraditionalRenderingPlugin.getDefault()
+ .getPreferenceStore();
+
+ store.setDefault(TraditionalRenderingPreferenceConstants.MEM_USE_GLOBAL_TEXT, true);
+ store.setDefault(TraditionalRenderingPreferenceConstants.MEM_USE_GLOBAL_BACKGROUND, true);
+ store.setDefault(TraditionalRenderingPreferenceConstants.MEM_USE_GLOBAL_SELECTION, true);
+
+ store.setDefault(TraditionalRenderingPreferenceConstants.MEM_COLOR_CHANGED, "255,0,0");
+
+ Color systemSelection = Display.getDefault().getSystemColor(SWT.COLOR_LIST_SELECTION);
+ store.setDefault(TraditionalRenderingPreferenceConstants.MEM_COLOR_SELECTION, systemSelection.getRed()
+ + "," + systemSelection.getGreen() + "," + systemSelection.getBlue());
+
+ store.setDefault(TraditionalRenderingPreferenceConstants.MEM_LIGHTEN_DARKEN_ALTERNATE_CELLS, "5");
+
+ store.setDefault(TraditionalRenderingPreferenceConstants.MEM_COLOR_EDIT, "0,255,0");
+
+ Color systemText = Display.getDefault().getSystemColor(SWT.COLOR_LIST_FOREGROUND);
+ store.setDefault(TraditionalRenderingPreferenceConstants.MEM_COLOR_TEXT, systemText.getRed()
+ + "," + systemText.getGreen() + "," + systemText.getBlue());
+
+ Color systemBackground = Display.getDefault().getSystemColor(SWT.COLOR_LIST_BACKGROUND);
+ store.setDefault(TraditionalRenderingPreferenceConstants.MEM_COLOR_BACKGROUND, systemBackground.getRed()
+ + "," + systemBackground.getGreen() + "," + systemBackground.getBlue());
+
+ store.setDefault(TraditionalRenderingPreferenceConstants.MEM_EDIT_BUFFER_SAVE,
+ TraditionalRenderingPreferenceConstants.MEM_EDIT_BUFFER_SAVE_ON_ENTER_ONLY);
+
+ store.setDefault(TraditionalRenderingPreferenceConstants.MEM_HISTORY_TRAILS_COUNT, "1");
+ }
+
+}
diff --git a/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/TraditionalRenderingPreferencePage.java b/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/TraditionalRenderingPreferencePage.java
new file mode 100644
index 00000000000..ca15b61c765
--- /dev/null
+++ b/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/TraditionalRenderingPreferencePage.java
@@ -0,0 +1,104 @@
+/*******************************************************************************
+ * Copyright (c) 2006-2009 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Ted R Williams (Wind River Systems, Inc.) - initial implementation
+ *******************************************************************************/
+
+package org.eclipse.cdt.debug.ui.memory.traditional;
+
+import org.eclipse.jface.preference.BooleanFieldEditor;
+import org.eclipse.jface.preference.ColorFieldEditor;
+import org.eclipse.jface.preference.FieldEditorPreferencePage;
+import org.eclipse.jface.preference.RadioGroupFieldEditor;
+import org.eclipse.jface.preference.ScaleFieldEditor;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * This class represents a preference page that
+ * is contributed to the Preferences dialog. By
+ * subclassing FieldEditorPreferencePage, we
+ * can use the field support built into JFace that allows
+ * us to create a page that is small and knows how to
+ * save, restore and apply itself.
+ *
+ * This page is used to modify preferences only. They
+ * are stored in the preference store that belongs to
+ * the main plug-in class. That way, preferences can
+ * be accessed directly via the preference store.
+ */
+
+public class TraditionalRenderingPreferencePage
+ extends FieldEditorPreferencePage
+ implements IWorkbenchPreferencePage {
+
+ public TraditionalRenderingPreferencePage() {
+ super(GRID);
+ setPreferenceStore(TraditionalRenderingPlugin.getDefault().getPreferenceStore());
+ setDescription("Traditional Memory Rendering");
+ }
+
+
+ @Override
+ public void createControl(Composite parent) {
+ super.createControl(parent);
+ PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(), TraditionalRenderingPlugin.getUniqueIdentifier() + ".TraditionalRenderingPreferencePage_context");
+ }
+
+
+ /**
+ * Creates the field editors. Field editors are abstractions of
+ * the common GUI blocks needed to manipulate various types
+ * of preferences. Each field editor knows how to save and
+ * restore itself.
+ */
+ public void createFieldEditors() {
+ addField(new BooleanFieldEditor(TraditionalRenderingPreferenceConstants.MEM_USE_GLOBAL_TEXT,
+ "Use Global Te&xt Color", getFieldEditorParent()));
+
+ addField(new ColorFieldEditor(TraditionalRenderingPreferenceConstants.MEM_COLOR_TEXT,
+ "&Text Color:", getFieldEditorParent()));
+
+ addField(new ScaleFieldEditor(TraditionalRenderingPreferenceConstants.MEM_LIGHTEN_DARKEN_ALTERNATE_CELLS,
+ "Brighten Alternate Cells", getFieldEditorParent(), 0, 8, 1, 1));
+
+ addField(new BooleanFieldEditor(TraditionalRenderingPreferenceConstants.MEM_USE_GLOBAL_BACKGROUND,
+ "Use Global B&ackground Color", getFieldEditorParent()));
+
+ addField(new ColorFieldEditor(TraditionalRenderingPreferenceConstants.MEM_COLOR_BACKGROUND,
+ "&Background Color:", getFieldEditorParent()));
+
+ addField(new ColorFieldEditor(TraditionalRenderingPreferenceConstants.MEM_COLOR_CHANGED,
+ "&Changed Color:", getFieldEditorParent()));
+
+ addField(new ColorFieldEditor(TraditionalRenderingPreferenceConstants.MEM_COLOR_EDIT,
+ "&Edit Color:", getFieldEditorParent()));
+
+ addField(new BooleanFieldEditor(TraditionalRenderingPreferenceConstants.MEM_USE_GLOBAL_SELECTION,
+ "Use Global Se&lection Color", getFieldEditorParent()));
+
+ addField(new ColorFieldEditor(TraditionalRenderingPreferenceConstants.MEM_COLOR_SELECTION,
+ "&Selection Color:", getFieldEditorParent()));
+
+ addField(new RadioGroupFieldEditor(TraditionalRenderingPreferenceConstants.MEM_EDIT_BUFFER_SAVE,
+ "Edit Buffer", 1, new String[][] { { "Save on E&nter, Cancel on Focus Lost", "saveOnEnterCancelOnFocusLost" },
+ { "Save on Enter or Focus L&ost", "saveOnEnterOrFocusLost" } }, getFieldEditorParent()));
+
+ addField(new ScaleFieldEditor(TraditionalRenderingPreferenceConstants.MEM_HISTORY_TRAILS_COUNT,
+ "History &Trail Levels", getFieldEditorParent(), 1, 10, 1, 1));
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench)
+ */
+ public void init(IWorkbench workbench) {
+ }
+
+}
\ No newline at end of file
diff --git a/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/TraditionalRenderingTypeDelegate.java b/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/TraditionalRenderingTypeDelegate.java
new file mode 100644
index 00000000000..fdba6dbed01
--- /dev/null
+++ b/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/TraditionalRenderingTypeDelegate.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2006-2009 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Ted R Williams (Wind River Systems, Inc.) - initial implementation
+ *******************************************************************************/
+
+package org.eclipse.cdt.debug.ui.memory.traditional;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.ui.memory.IMemoryRendering;
+import org.eclipse.debug.ui.memory.IMemoryRenderingTypeDelegate;
+
+public class TraditionalRenderingTypeDelegate
+ implements IMemoryRenderingTypeDelegate
+{
+
+ public IMemoryRendering createRendering(String id) throws CoreException {
+ return new TraditionalRendering(id);
+ }
+
+
+}
diff --git a/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/TraditionalRendering_messages.properties b/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/TraditionalRendering_messages.properties
new file mode 100644
index 00000000000..041aa4d356f
--- /dev/null
+++ b/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/TraditionalRendering_messages.properties
@@ -0,0 +1,49 @@
+TraditionalRendering.GO_TO_ADDRESS=Go To Address
+TraditionalRendering.RESET_TO_BASE_ADDRESS=Reset To Base Address
+TraditionalRendering.REFRESH=Refresh
+TraditionalRendering.ADDRESS=Address
+TraditionalRendering.BINARY=Binary
+TraditionalRendering.TEXT=Text
+TraditionalRendering.1_BYTE=1 byte
+TraditionalRendering.2_BYTES=2 bytes
+TraditionalRendering.4_BYTES=4 bytes
+TraditionalRendering.8_BYTES=8 bytes
+TraditionalRendering.ISO-8859-1=ISO-8859-1
+TraditionalRendering.USASCII=US-ASCII
+TraditionalRendering.UTF8=UTF-8
+TraditionalRendering.UTF16=UTF-16
+TraditionalRendering.BIG=Big
+TraditionalRendering.LITTLE=Little
+TraditionalRendering.HEX=Hex
+TraditionalRendering.DECIMAL_SIGNED=Decimal Signed
+TraditionalRendering.DECIMAL_UNSIGNED=Decimal Unsigned
+TraditionalRendering.OCTAL=Octal
+TraditionalRendering.PANES=Panes
+TraditionalRendering.ENDIAN=Endian
+TraditionalRendering.CELL_SIZE=Cell Size
+TraditionalRendering.RADIX=Radix
+TraditionalRendering.RENDERING_NAME=Traditional
+TraditionalRendering.FAILURE_RETRIEVE_START_ADDRESS=Failure in retrieving start address.
+TraditionalRendering.FAILURE_RETRIEVE_BASE_ADDRESS=Failure in retrieving base address.
+TraditionalRendering.CALLED_ON_NON_DISPATCH_THREAD=Called on non-dispatch thread
+TraditionalRendering.FAILURE_READ_MEMORY=Failed reading memory.
+TraditionalRendering.FAILURE_WRITE_MEMORY=Error writing memory.
+TraditionalRendering.FAILURE_DETERMINE_ADDRESS_SIZE=Failed to determine address size.
+TraditionalRendering.FAILURE_POSITION_CURSOR=Failed to position cursor.
+TraditionalRendering.FAILURE_START_SELECTION=Failed to start selection.
+TraditionalRendering.FAILURE_APPEND_SELECTION=Failed to append selection.
+TraditionalRendering.FAILURE_DETERMINE_CELL_LOCATION=Failed to determine cell location.
+TraditionalRendering.FAILURE_PAINT=Failed to paint.
+TraditionalRendering.FAILURE_COPY_OPERATION=Failed copy operation.
+TraditionalRendering.COLUMN_COUNT=Columns
+TraditionalRendering.COLUMN_COUNT_AUTO=Auto Size to Fill
+TraditionalRendering.COLUMN_COUNT_1=1
+TraditionalRendering.COLUMN_COUNT_2=2
+TraditionalRendering.COLUMN_COUNT_4=4
+TraditionalRendering.COLUMN_COUNT_8=8
+TraditionalRendering.COLUMN_COUNT_16=16
+TraditionalRendering.COLUMN_COUNT_32=32
+TraditionalRendering.COLUMN_COUNT_64=64
+TraditionalRendering.COLUMN_COUNT_128=128
+TraditionalRendering.COLUMN_COUNT_CUSTOM=Custom...
+TraditionalRendering.COPY_ADDRESS=Copy Address
\ No newline at end of file
diff --git a/memory/org.eclipse.cdt.debug.ui.memory.transport/.classpath b/memory/org.eclipse.cdt.debug.ui.memory.transport/.classpath
new file mode 100644
index 00000000000..2fbb7a23e12
--- /dev/null
+++ b/memory/org.eclipse.cdt.debug.ui.memory.transport/.classpath
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/memory/org.eclipse.cdt.debug.ui.memory.transport/.project b/memory/org.eclipse.cdt.debug.ui.memory.transport/.project
new file mode 100644
index 00000000000..f011d2cff38
--- /dev/null
+++ b/memory/org.eclipse.cdt.debug.ui.memory.transport/.project
@@ -0,0 +1,28 @@
+
+
+ org.eclipse.cdt.debug.ui.memory.transport
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.pde.ManifestBuilder
+
+
+
+
+ org.eclipse.pde.SchemaBuilder
+
+
+
+
+
+ org.eclipse.pde.PluginNature
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/memory/org.eclipse.cdt.debug.ui.memory.transport/.settings/org.eclipse.jdt.core.prefs b/memory/org.eclipse.cdt.debug.ui.memory.transport/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 00000000000..b51d4342d8d
--- /dev/null
+++ b/memory/org.eclipse.cdt.debug.ui.memory.transport/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+#Fri May 09 21:44:48 PDT 2008
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.2
+org.eclipse.jdt.core.compiler.compliance=1.4
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=warning
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=warning
+org.eclipse.jdt.core.compiler.source=1.3
diff --git a/memory/org.eclipse.cdt.debug.ui.memory.transport/META-INF/MANIFEST.MF b/memory/org.eclipse.cdt.debug.ui.memory.transport/META-INF/MANIFEST.MF
new file mode 100644
index 00000000000..4486a9eb402
--- /dev/null
+++ b/memory/org.eclipse.cdt.debug.ui.memory.transport/META-INF/MANIFEST.MF
@@ -0,0 +1,16 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Memory Transport Plug-in
+Bundle-SymbolicName: org.eclipse.cdt.debug.ui.memory.transport;singleton:=true
+Bundle-Version: 1.1.0.qualifier
+Bundle-Localization: plugin
+Bundle-Vendor: Eclipse.org
+Require-Bundle: org.eclipse.debug.core,
+ org.eclipse.debug.ui,
+ org.eclipse.core.runtime,
+ org.eclipse.swt,
+ org.eclipse.jface,
+ org.eclipse.ui
+Bundle-RequiredExecutionEnvironment: J2SE-1.4
+Bundle-ActivationPolicy: lazy
+Bundle-Activator: org.eclipse.cdt.debug.ui.memory.transport.MemoryTransportPlugin
diff --git a/memory/org.eclipse.cdt.debug.ui.memory.transport/about.html b/memory/org.eclipse.cdt.debug.ui.memory.transport/about.html
new file mode 100644
index 00000000000..04492dd7e1b
--- /dev/null
+++ b/memory/org.eclipse.cdt.debug.ui.memory.transport/about.html
@@ -0,0 +1,24 @@
+
+
+
+
+About
+About This Content
+
+May 14, 2008
+License
+
+The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available
+at http://www.eclipse.org/legal/epl-v10.html.
+For purposes of the EPL, "Program" will mean the Content.
+
+If you did not receive this Content directly from the Eclipse Foundation, the Content is
+being redistributed by another party ("Redistributor") and different terms and conditions may
+apply to your use of any object code in the Content. Check the Redistributor's license that was
+provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at http://www.eclipse.org.
+
+
\ No newline at end of file
diff --git a/memory/org.eclipse.cdt.debug.ui.memory.transport/build.properties b/memory/org.eclipse.cdt.debug.ui.memory.transport/build.properties
new file mode 100644
index 00000000000..835e763df2c
--- /dev/null
+++ b/memory/org.eclipse.cdt.debug.ui.memory.transport/build.properties
@@ -0,0 +1,9 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ schema/,\
+ plugin.xml,\
+ build.properties,\
+ plugin.properties,\
+ icons/
diff --git a/memory/org.eclipse.cdt.debug.ui.memory.transport/icons/export.png b/memory/org.eclipse.cdt.debug.ui.memory.transport/icons/export.png
new file mode 100644
index 00000000000..91b2198825c
Binary files /dev/null and b/memory/org.eclipse.cdt.debug.ui.memory.transport/icons/export.png differ
diff --git a/memory/org.eclipse.cdt.debug.ui.memory.transport/icons/import.png b/memory/org.eclipse.cdt.debug.ui.memory.transport/icons/import.png
new file mode 100644
index 00000000000..fa02317c7fd
Binary files /dev/null and b/memory/org.eclipse.cdt.debug.ui.memory.transport/icons/import.png differ
diff --git a/memory/org.eclipse.cdt.debug.ui.memory.transport/plugin.properties b/memory/org.eclipse.cdt.debug.ui.memory.transport/plugin.properties
new file mode 100644
index 00000000000..1ce59a6a290
--- /dev/null
+++ b/memory/org.eclipse.cdt.debug.ui.memory.transport/plugin.properties
@@ -0,0 +1,2 @@
+ExportMemoryAction.label=Export
+ImportMemoryAction.label=Import
\ No newline at end of file
diff --git a/memory/org.eclipse.cdt.debug.ui.memory.transport/plugin.xml b/memory/org.eclipse.cdt.debug.ui.memory.transport/plugin.xml
new file mode 100644
index 00000000000..98cccbccfb7
--- /dev/null
+++ b/memory/org.eclipse.cdt.debug.ui.memory.transport/plugin.xml
@@ -0,0 +1,73 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/memory/org.eclipse.cdt.debug.ui.memory.transport/schema/MemoryTransport.exsd b/memory/org.eclipse.cdt.debug.ui.memory.transport/schema/MemoryTransport.exsd
new file mode 100644
index 00000000000..6efec619ca9
--- /dev/null
+++ b/memory/org.eclipse.cdt.debug.ui.memory.transport/schema/MemoryTransport.exsd
@@ -0,0 +1,141 @@
+
+
+
+
+
+
+
+
+ Allows plug-ins to contribute arbitrary memory importers and exporters.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1.0.0
+
+
+
+
+
+
+
+
+
+
+
+ /*******************************************************************************
+ * Copyright (c) 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Ted R Williams (Wind River Systems, Inc.) - initial implementation
+ *******************************************************************************/
+
+
+
+
diff --git a/memory/org.eclipse.cdt.debug.ui.memory.transport/src/org/eclipse/cdt/debug/ui/memory/transport/BufferedMemoryWriter.java b/memory/org.eclipse.cdt.debug.ui.memory.transport/src/org/eclipse/cdt/debug/ui/memory/transport/BufferedMemoryWriter.java
new file mode 100644
index 00000000000..d767bd86183
--- /dev/null
+++ b/memory/org.eclipse.cdt.debug.ui.memory.transport/src/org/eclipse/cdt/debug/ui/memory/transport/BufferedMemoryWriter.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Ted R Williams (Wind River Systems, Inc.) - initial implementation
+ *******************************************************************************/
+
+package org.eclipse.cdt.debug.ui.memory.transport;
+
+import java.math.BigInteger;
+
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.core.model.IMemoryBlockExtension;
+
+public class BufferedMemoryWriter
+{
+ private IMemoryBlockExtension fBlock;
+ private byte[] fBuffer;
+ private int fBufferPosition = 0;
+ private BigInteger fBufferStart = null;
+
+ public BufferedMemoryWriter(IMemoryBlockExtension block, int bufferLength)
+ {
+ fBlock = block;
+ fBuffer = new byte[bufferLength];
+ }
+
+ public void write(BigInteger address, byte[] data) throws DebugException
+ {
+ while(data.length > 0)
+ {
+ if(fBufferStart == null)
+ {
+ fBufferStart = address;
+ int length = data.length <= fBuffer.length ? data.length : fBuffer.length;
+ System.arraycopy(data, 0, fBuffer, 0, length);
+ fBufferPosition = length;
+ byte[] dataRemainder = new byte[data.length - length];
+ System.arraycopy(data, length, dataRemainder, 0, data.length - length);
+ data = dataRemainder;
+ address = fBufferStart.add(BigInteger.valueOf(length));
+ }
+ else if(fBufferStart.add(BigInteger.valueOf(fBufferPosition)).compareTo(address) != 0)
+ {
+ flush();
+ }
+ else
+ {
+ int availableBufferLength = fBuffer.length - fBufferPosition;
+ int length = data.length <= fBuffer.length - availableBufferLength
+ ? data.length : fBuffer.length - availableBufferLength;
+ System.arraycopy(data, 0, fBuffer, fBufferPosition, length);
+ fBufferPosition += length;
+
+ byte[] dataRemainder = new byte[data.length - length];
+ System.arraycopy(data, length, dataRemainder, 0, data.length - length);
+ data = dataRemainder;
+ address = fBufferStart.add(BigInteger.valueOf(length));
+ }
+
+ if(fBufferPosition == fBuffer.length)
+ flush();
+ }
+ }
+
+ public void flush() throws DebugException
+ {
+ if(fBufferStart != null)
+ {
+ byte data[] = new byte[fBufferPosition];
+ System.arraycopy(fBuffer, 0, data, 0, fBufferPosition);
+ fBlock.setValue(fBufferStart, data);
+ fBufferStart = null;
+ }
+ }
+
+}
+
+
diff --git a/memory/org.eclipse.cdt.debug.ui.memory.transport/src/org/eclipse/cdt/debug/ui/memory/transport/ExportMemoryDialog.java b/memory/org.eclipse.cdt.debug.ui.memory.transport/src/org/eclipse/cdt/debug/ui/memory/transport/ExportMemoryDialog.java
new file mode 100644
index 00000000000..0301c554a72
--- /dev/null
+++ b/memory/org.eclipse.cdt.debug.ui.memory.transport/src/org/eclipse/cdt/debug/ui/memory/transport/ExportMemoryDialog.java
@@ -0,0 +1,202 @@
+/*******************************************************************************
+ * Copyright (c) 2006-2009 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Ted R Williams (Wind River Systems, Inc.) - initial implementation
+ *******************************************************************************/
+
+package org.eclipse.cdt.debug.ui.memory.transport;
+
+import java.util.Properties;
+import java.util.Vector;
+
+import org.eclipse.cdt.debug.ui.memory.transport.model.IMemoryExporter;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IExtensionRegistry;
+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.eclipse.debug.core.model.IMemoryBlock;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.layout.FormLayout;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.dialogs.SelectionDialog;
+
+public class ExportMemoryDialog extends SelectionDialog
+{
+
+ private Combo fFormatCombo;
+
+ private IMemoryBlock fMemoryBlock;
+
+ private Control fCurrentControl = null;
+
+ private IMemoryExporter fFormatExporters[];
+ private String fFormatNames[];
+
+ private Properties fProperties = new Properties();
+
+ public ExportMemoryDialog(Shell parent, IMemoryBlock memoryBlock)
+ {
+ super(parent);
+ super.setTitle("Export Memory");
+ setShellStyle(getShellStyle() | SWT.RESIZE);
+
+ fMemoryBlock = memoryBlock;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.dialogs.Dialog#createButtonsForButtonBar(org.eclipse.swt.widgets.Composite)
+ */
+ protected void createButtonsForButtonBar(Composite parent) {
+ super.createButtonsForButtonBar(parent);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.dialogs.SelectionDialog#getResult()
+ */
+ public Object[] getResult() {
+
+ Object[] results = super.getResult();
+
+ if (results != null)
+ {
+ return results;
+ }
+ return new Object[0];
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.dialogs.Dialog#cancelPressed()
+ */
+ protected void cancelPressed() {
+
+ setResult(null);
+
+ super.cancelPressed();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.dialogs.Dialog#okPressed()
+ */
+ protected void okPressed() {
+ if(fCurrentControl != null)
+ fCurrentControl.dispose();
+ fFormatExporters[fFormatCombo.getSelectionIndex()].exportMemory();
+
+ super.okPressed();
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite)
+ */
+ protected Control createDialogArea(Composite parent) {
+
+ PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, MemoryTransportPlugin.getUniqueIdentifier() + ".ExportMemoryDialog_context"); //$NON-NLS-1$
+ Composite composite = new Composite(parent, SWT.NONE);
+ FormLayout formLayout = new FormLayout();
+ formLayout.spacing = 5;
+ formLayout.marginWidth = formLayout.marginHeight = 9;
+ composite.setLayout(formLayout);
+
+ // format
+
+ Label textLabel = new Label(composite, SWT.NONE);
+ textLabel.setText("Format: ");
+
+ fFormatCombo = new Combo(composite, SWT.BORDER | SWT.READ_ONLY);
+
+ FormData data = new FormData();
+ data.top = new FormAttachment(fFormatCombo, 0, SWT.CENTER);
+ textLabel.setLayoutData(data);
+
+ data = new FormData();
+ data.left = new FormAttachment(textLabel);
+ fFormatCombo.setLayoutData(data);
+
+ Vector exporters = new Vector();
+
+ IExtensionRegistry registry = Platform.getExtensionRegistry();
+ IExtensionPoint extensionPoint =
+ registry.getExtensionPoint("org.eclipse.cdt.debug.ui.memory.transport.memoryTransport");
+ IConfigurationElement points[] =
+ extensionPoint.getConfigurationElements();
+
+ for (int i = 0; i < points.length; i++)
+ {
+ IConfigurationElement element = points[i];
+ if("exporter".equals(element.getName()))
+ {
+ try
+ {
+ exporters.addElement((IMemoryExporter) element.createExecutableExtension("class"));
+ }
+ catch(Exception e) {
+ MemoryTransportPlugin.getDefault().getLog().log(new Status(IStatus.ERROR, MemoryTransportPlugin.getUniqueIdentifier(),
+ DebugException.INTERNAL_ERROR, "Failure", e));
+ }
+ }
+ }
+
+ fFormatExporters = new IMemoryExporter[exporters.size()];
+ fFormatNames = new String[exporters.size()];
+ for(int i = 0; i < fFormatExporters.length; i++)
+ {
+ fFormatExporters[i] = (IMemoryExporter) exporters.elementAt(i);
+ fFormatNames[i] = ((IMemoryExporter) exporters.elementAt(i)).getName();
+ }
+
+ final Composite container = new Composite(composite, SWT.NONE);
+ data = new FormData();
+ data.top = new FormAttachment(fFormatCombo);
+ data.left = new FormAttachment(0);
+ container.setLayoutData(data);
+
+ fFormatCombo.setItems(fFormatNames);
+
+ fFormatCombo.addSelectionListener(new SelectionListener(){
+
+ public void widgetDefaultSelected(SelectionEvent e) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void widgetSelected(SelectionEvent e) {
+ if(fCurrentControl != null)
+ fCurrentControl.dispose();
+ fCurrentControl = fFormatExporters[fFormatCombo.getSelectionIndex()].createControl(container,
+ fMemoryBlock, fProperties, ExportMemoryDialog.this);
+ }
+ });
+
+
+ fFormatCombo.select(0);
+ fCurrentControl = fFormatExporters[0].createControl(container,
+ fMemoryBlock, fProperties, ExportMemoryDialog.this);
+
+ return composite;
+ }
+
+ public void setValid(boolean isValid)
+ {
+ getButton(IDialogConstants.OK_ID).setEnabled(isValid);
+ }
+
+}
diff --git a/memory/org.eclipse.cdt.debug.ui.memory.transport/src/org/eclipse/cdt/debug/ui/memory/transport/ImportMemoryDialog.java b/memory/org.eclipse.cdt.debug.ui.memory.transport/src/org/eclipse/cdt/debug/ui/memory/transport/ImportMemoryDialog.java
new file mode 100644
index 00000000000..98574c8a504
--- /dev/null
+++ b/memory/org.eclipse.cdt.debug.ui.memory.transport/src/org/eclipse/cdt/debug/ui/memory/transport/ImportMemoryDialog.java
@@ -0,0 +1,245 @@
+/*******************************************************************************
+ * Copyright (c) 2006-2009 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Ted R Williams (Wind River Systems, Inc.) - initial implementation
+ *******************************************************************************/
+
+package org.eclipse.cdt.debug.ui.memory.transport;
+
+import java.math.BigInteger;
+import java.util.Properties;
+import java.util.Vector;
+
+import org.eclipse.cdt.debug.ui.memory.transport.model.IMemoryImporter;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IExtensionRegistry;
+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.eclipse.debug.core.model.IMemoryBlock;
+import org.eclipse.debug.internal.ui.views.memory.MemoryView;
+import org.eclipse.debug.internal.ui.views.memory.RenderingViewPane;
+import org.eclipse.debug.ui.memory.IMemoryRendering;
+import org.eclipse.debug.ui.memory.IMemoryRenderingContainer;
+import org.eclipse.debug.ui.memory.IRepositionableMemoryRendering;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.layout.FormLayout;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.dialogs.SelectionDialog;
+import org.eclipse.ui.progress.UIJob;
+
+public class ImportMemoryDialog extends SelectionDialog
+{
+
+ private Combo fFormatCombo;
+
+ private IMemoryBlock fMemoryBlock;
+
+ private Control fCurrentControl = null;
+
+ private IMemoryImporter fFormatImporters[];
+ private String fFormatNames[];
+
+ private Properties fProperties = new Properties();
+
+ private MemoryView fMemoryView;
+
+ public ImportMemoryDialog(Shell parent, IMemoryBlock memoryBlock, MemoryView view)
+ {
+ super(parent);
+ super.setTitle("Download to Memory");
+ setShellStyle(getShellStyle() | SWT.RESIZE);
+
+ fMemoryBlock = memoryBlock;
+ fMemoryView = view;
+ }
+
+ protected void scrollRenderings(final BigInteger address)
+ {
+ UIJob job = new UIJob("repositionRenderings"){ //$NON-NLS-1$
+ public IStatus runInUIThread(IProgressMonitor monitor) {
+ final IMemoryRenderingContainer containers[] = fMemoryView.getMemoryRenderingContainers();
+ for(int i = 0; i < containers.length; i++)
+ {
+ if(containers[i] instanceof RenderingViewPane)
+ {
+ IMemoryRendering rendering = containers[i].getActiveRendering();
+
+ if(rendering instanceof IRepositionableMemoryRendering)
+ {
+ try
+ {
+ ((IRepositionableMemoryRendering) rendering).goToAddress(address);
+ }
+ catch (DebugException e)
+ {
+ // do nothing
+ }
+ }
+ }
+ }
+
+ return Status.OK_STATUS;
+ }};
+ job.setSystem(true);
+ job.setThread(Display.getDefault().getThread());
+ job.schedule();
+
+
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.dialogs.Dialog#createButtonsForButtonBar(org.eclipse.swt.widgets.Composite)
+ */
+ protected void createButtonsForButtonBar(Composite parent) {
+ super.createButtonsForButtonBar(parent);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.dialogs.SelectionDialog#getResult()
+ */
+ public Object[] getResult() {
+
+ Object[] results = super.getResult();
+
+ if (results != null)
+ {
+ return results;
+ }
+ return new Object[0];
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.dialogs.Dialog#cancelPressed()
+ */
+ protected void cancelPressed() {
+
+ setResult(null);
+
+ super.cancelPressed();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.dialogs.Dialog#okPressed()
+ */
+ protected void okPressed() {
+ if(fCurrentControl != null)
+ fCurrentControl.dispose();
+ fFormatImporters[fFormatCombo.getSelectionIndex()].importMemory();
+
+ super.okPressed();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite)
+ */
+ protected Control createDialogArea(Composite parent) {
+
+ PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, MemoryTransportPlugin.getUniqueIdentifier() + ".ImportMemoryDialog_context"); //$NON-NLS-1$
+ Composite composite = new Composite(parent, SWT.NONE);
+ FormLayout formLayout = new FormLayout();
+ formLayout.spacing = 5;
+ formLayout.marginWidth = formLayout.marginHeight = 9;
+ composite.setLayout(formLayout);
+
+ // format
+
+ Label textLabel = new Label(composite, SWT.NONE);
+ textLabel.setText("Format: ");
+
+ fFormatCombo = new Combo(composite, SWT.BORDER | SWT.READ_ONLY);
+
+ FormData data = new FormData();
+ data.top = new FormAttachment(fFormatCombo, 0, SWT.CENTER);
+ textLabel.setLayoutData(data);
+
+ data = new FormData();
+ data.left = new FormAttachment(textLabel);
+ fFormatCombo.setLayoutData(data);
+
+ Vector importers = new Vector();
+
+ IExtensionRegistry registry = Platform.getExtensionRegistry();
+ IExtensionPoint extensionPoint =
+ registry.getExtensionPoint("org.eclipse.cdt.debug.ui.memory.transport.memoryTransport");
+ IConfigurationElement points[] =
+ extensionPoint.getConfigurationElements();
+
+ for (int i = 0; i < points.length; i++)
+ {
+ IConfigurationElement element = points[i];
+ if("importer".equals(element.getName()))
+ {
+ try
+ {
+ importers.addElement((IMemoryImporter) element.createExecutableExtension("class"));
+ }
+ catch(Exception e) {
+ MemoryTransportPlugin.getDefault().getLog().log(new Status(IStatus.ERROR, MemoryTransportPlugin.getUniqueIdentifier(),
+ DebugException.INTERNAL_ERROR, "Failure", e));
+ }
+ }
+ }
+
+ fFormatImporters = new IMemoryImporter[importers.size()];
+ fFormatNames = new String[importers.size()];
+ for(int i = 0; i < fFormatImporters.length; i++)
+ {
+ fFormatImporters[i] = (IMemoryImporter) importers.elementAt(i);
+ fFormatNames[i] = ((IMemoryImporter) importers.elementAt(i)).getName();
+ }
+
+ final Composite container = new Composite(composite, SWT.NONE);
+ data = new FormData();
+ data.top = new FormAttachment(fFormatCombo);
+ data.left = new FormAttachment(0);
+ container.setLayoutData(data);
+
+ fFormatCombo.setItems(fFormatNames);
+
+ fFormatCombo.addSelectionListener(new SelectionListener(){
+
+ public void widgetDefaultSelected(SelectionEvent e) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void widgetSelected(SelectionEvent e) {
+ if(fCurrentControl != null)
+ fCurrentControl.dispose();
+ fCurrentControl = fFormatImporters[fFormatCombo.getSelectionIndex()].createControl(container,
+ fMemoryBlock, fProperties, ImportMemoryDialog.this);
+ }
+ });
+
+ fFormatCombo.select(0);
+ fCurrentControl =
+ fFormatImporters[0].createControl(container,fMemoryBlock, fProperties, ImportMemoryDialog.this);
+
+ return composite;
+ }
+
+ public void setValid(boolean isValid)
+ {
+ getButton(IDialogConstants.OK_ID).setEnabled(isValid);
+ }
+}
diff --git a/memory/org.eclipse.cdt.debug.ui.memory.transport/src/org/eclipse/cdt/debug/ui/memory/transport/MemoryTransportPlugin.java b/memory/org.eclipse.cdt.debug.ui.memory.transport/src/org/eclipse/cdt/debug/ui/memory/transport/MemoryTransportPlugin.java
new file mode 100644
index 00000000000..4449a062dbf
--- /dev/null
+++ b/memory/org.eclipse.cdt.debug.ui.memory.transport/src/org/eclipse/cdt/debug/ui/memory/transport/MemoryTransportPlugin.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2006-2009 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Ted R Williams (Wind River Systems, Inc.) - initial implementation
+ *******************************************************************************/
+
+package org.eclipse.cdt.debug.ui.memory.transport;
+
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+
+public class MemoryTransportPlugin extends AbstractUIPlugin
+{
+ private static final String PLUGIN_ID = "org.eclipse.cdt.debug.ui.memory.transport"; //$NON-NLS-1$
+
+ private static MemoryTransportPlugin plugin;
+
+ public MemoryTransportPlugin()
+ {
+ super();
+ plugin = this;
+ }
+
+ /**
+ * Returns the shared instance.
+ */
+ public static MemoryTransportPlugin getDefault() {
+ return plugin;
+ }
+
+ /**
+ * Returns the unique identifier for this plugin.
+ */
+ public static String getUniqueIdentifier() {
+ return PLUGIN_ID;
+ }
+
+ /**
+ * Returns the currently active workbench window shell or null
+ * if none.
+ *
+ * @return the currently active workbench window shell or null
+ */
+ public static Shell getShell() {
+ IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+ if (window == null) {
+ IWorkbenchWindow[] windows = PlatformUI.getWorkbench().getWorkbenchWindows();
+ if (windows.length > 0) {
+ return windows[0].getShell();
+ }
+ }
+ else {
+ return window.getShell();
+ }
+ return null;
+ }
+}
diff --git a/memory/org.eclipse.cdt.debug.ui.memory.transport/src/org/eclipse/cdt/debug/ui/memory/transport/Messages.java b/memory/org.eclipse.cdt.debug.ui.memory.transport/src/org/eclipse/cdt/debug/ui/memory/transport/Messages.java
new file mode 100644
index 00000000000..e0d4fdc92a1
--- /dev/null
+++ b/memory/org.eclipse.cdt.debug.ui.memory.transport/src/org/eclipse/cdt/debug/ui/memory/transport/Messages.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2007-2009 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Ted R Williams (Wind River Systems, Inc.) - initial implementation
+ *******************************************************************************/
+
+package org.eclipse.cdt.debug.ui.memory.transport;
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class Messages {
+ private static final String BUNDLE_NAME = "org.eclipse.cdt.debug.ui.memory.transport.messages"; //$NON-NLS-1$
+
+ private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle
+ .getBundle(BUNDLE_NAME);
+
+ private Messages() {
+ }
+
+ public static String getString(String key) {
+ try {
+ return RESOURCE_BUNDLE.getString(key);
+ } catch (MissingResourceException e) {
+ return '!' + key + '!';
+ }
+ }
+}
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
new file mode 100644
index 00000000000..48d62a568d7
--- /dev/null
+++ b/memory/org.eclipse.cdt.debug.ui.memory.transport/src/org/eclipse/cdt/debug/ui/memory/transport/PlainTextExporter.java
@@ -0,0 +1,476 @@
+/*******************************************************************************
+ * Copyright (c) 2006-2009 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Ted R Williams (Wind River Systems, Inc.) - initial implementation
+ *******************************************************************************/
+
+package org.eclipse.cdt.debug.ui.memory.transport;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.math.BigInteger;
+import java.util.Properties;
+
+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.swt.SWT;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.layout.FormLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+
+public class PlainTextExporter implements IMemoryExporter {
+
+ File fOutputFile;
+ BigInteger fStartAddress;
+ BigInteger fEndAddress;
+
+ private Text fStartText;
+ private Text fEndText;
+ private Text fLengthText;
+ private Text fFileText;
+
+ private IMemoryBlock fMemoryBlock;
+
+ private ExportMemoryDialog fParentDialog;
+
+ private Properties fProperties;
+
+ public Control createControl(final Composite parent, IMemoryBlock memBlock, Properties properties, ExportMemoryDialog parentDialog)
+ {
+ fMemoryBlock = memBlock;
+ fParentDialog = parentDialog;
+ fProperties = properties;
+
+ Composite composite = new Composite(parent, SWT.NONE)
+ {
+ public void dispose()
+ {
+ fProperties.setProperty(TRANSFER_FILE, fFileText.getText());
+ fProperties.setProperty(TRANSFER_START, fStartText.getText());
+ fProperties.setProperty(TRANSFER_END, fEndText.getText());
+
+ fStartAddress = getStartAddress();
+ fEndAddress = getEndAddress();
+ fOutputFile = getFile();
+
+ super.dispose();
+ }
+ };
+
+ FormLayout formLayout = new FormLayout();
+ formLayout.spacing = 5;
+ formLayout.marginWidth = formLayout.marginHeight = 9;
+ composite.setLayout(formLayout);
+
+ // start address
+
+ Label startLabel = new Label(composite, SWT.NONE);
+ startLabel.setText("Start address: ");
+ FormData data = new FormData();
+ startLabel.setLayoutData(data);
+
+ fStartText = new Text(composite, SWT.NONE);
+ data = new FormData();
+ data.left = new FormAttachment(startLabel);
+ data.width = 100;
+ fStartText.setLayoutData(data);
+
+ // end address
+
+ Label endLabel = new Label(composite, SWT.NONE);
+ endLabel.setText("End address: ");
+ data = new FormData();
+ data.top = new FormAttachment(fStartText, 0, SWT.CENTER);
+ data.left = new FormAttachment(fStartText);
+ endLabel.setLayoutData(data);
+
+ fEndText = new Text(composite, SWT.NONE);
+ data = new FormData();
+ data.top = new FormAttachment(fStartText, 0, SWT.CENTER);
+ data.left = new FormAttachment(endLabel);
+ data.width = 100;
+ fEndText.setLayoutData(data);
+
+ // length
+
+ Label lengthLabel = new Label(composite, SWT.NONE);
+ lengthLabel.setText("Length: ");
+ data = new FormData();
+ data.top = new FormAttachment(fStartText, 0, SWT.CENTER);
+ data.left = new FormAttachment(fEndText);
+ lengthLabel.setLayoutData(data);
+
+ fLengthText = new Text(composite, SWT.NONE);
+ data = new FormData();
+ data.top = new FormAttachment(fStartText, 0, SWT.CENTER);
+ data.left = new FormAttachment(lengthLabel);
+ data.width = 100;
+ fLengthText.setLayoutData(data);
+
+ // file
+
+ Label fileLabel = new Label(composite, SWT.NONE);
+ fFileText = new Text(composite, SWT.NONE);
+ Button fileButton = new Button(composite, SWT.PUSH);
+
+ fileLabel.setText("File name: ");
+ data = new FormData();
+ data.top = new FormAttachment(fileButton, 0, SWT.CENTER);
+ fileLabel.setLayoutData(data);
+
+ data = new FormData();
+ data.top = new FormAttachment(fileButton, 0, SWT.CENTER);
+ data.left = new FormAttachment(fileLabel);
+ data.width = 300;
+ fFileText.setLayoutData(data);
+
+ fileButton.setText("Browse...");
+ data = new FormData();
+ data.top = new FormAttachment(fLengthText);
+ data.left = new FormAttachment(fFileText);
+ fileButton.setLayoutData(data);
+
+
+ fFileText.setText(properties.getProperty(TRANSFER_FILE, ""));
+ try
+ {
+ BigInteger startAddress = null;
+ if(fMemoryBlock instanceof IMemoryBlockExtension)
+ startAddress = ((IMemoryBlockExtension) fMemoryBlock)
+ .getBigBaseAddress(); // FIXME use selection/caret address?
+ else
+ startAddress = BigInteger.valueOf(fMemoryBlock.getStartAddress());
+
+ if(properties.getProperty(TRANSFER_START) != null)
+ fStartText.setText(properties.getProperty(TRANSFER_START));
+ else
+ fStartText.setText("0x" + startAddress.toString(16));
+
+ if(properties.getProperty(TRANSFER_END) != null)
+ fEndText.setText(properties.getProperty(TRANSFER_END));
+ else
+ fEndText.setText("0x" + startAddress.toString(16));
+
+ fLengthText.setText(getEndAddress().subtract(getStartAddress()).toString());
+ }
+ catch(Exception e)
+ {
+ MemoryTransportPlugin.getDefault().getLog().log(new Status(IStatus.ERROR, MemoryTransportPlugin.getUniqueIdentifier(),
+ DebugException.INTERNAL_ERROR, "Failure", e));
+ }
+
+ fileButton.addSelectionListener(new SelectionListener() {
+
+ public void widgetDefaultSelected(SelectionEvent e) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void widgetSelected(SelectionEvent e) {
+ FileDialog dialog = new FileDialog(parent.getShell(), SWT.SAVE);
+ dialog.setText("Choose memory export file");
+ dialog.setFilterExtensions(new String[] { "*.*;*" } );
+ dialog.setFilterNames(new String[] { "All Files" } );
+ dialog.setFileName(fFileText.getText());
+ dialog.open();
+
+ String filename = dialog.getFileName();
+ if(filename != null && filename.length() != 0 )
+ {
+ fFileText.setText(dialog.getFilterPath() + File.separator + filename);
+ }
+
+ validate();
+ }
+
+ });
+
+ fStartText.addKeyListener(new KeyListener() {
+ public void keyReleased(KeyEvent e) {
+ boolean valid = true;
+ try
+ {
+ getStartAddress();
+ }
+ catch(Exception ex)
+ {
+ valid = false;
+ }
+
+ fStartText.setForeground(valid ? Display.getDefault().getSystemColor(SWT.COLOR_BLACK) :
+ Display.getDefault().getSystemColor(SWT.COLOR_RED));
+
+ //
+
+ BigInteger endAddress = getEndAddress();
+ BigInteger startAddress = getStartAddress();
+
+ fLengthText.setText(endAddress.subtract(startAddress).toString());
+
+ validate();
+ }
+
+ public void keyPressed(KeyEvent e) {}
+ });
+
+ fEndText.addKeyListener(new KeyListener() {
+ public void keyReleased(KeyEvent e) {
+ try
+ {
+ getEndAddress();
+ fEndText.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_BLACK));
+
+ BigInteger endAddress = getEndAddress();
+ BigInteger startAddress = getStartAddress();
+
+ String lengthString = endAddress.subtract(startAddress).toString();
+
+ if(!fLengthText.getText().equals(lengthString))
+ fLengthText.setText(lengthString);
+ }
+ catch(Exception ex)
+ {
+ fEndText.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_RED));
+ }
+
+ validate();
+ }
+
+ public void keyPressed(KeyEvent e) {}
+
+ });
+
+ fLengthText.addKeyListener(new KeyListener() {
+ public void keyReleased(KeyEvent e) {
+ try
+ {
+ BigInteger length = getLength();
+ fLengthText.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_BLACK));
+ BigInteger startAddress = getStartAddress();
+ String endString = "0x" + startAddress.add(length).toString(16);
+ if(!fEndText.getText().equals(endString))
+ fEndText.setText(endString);
+ }
+ catch(Exception ex)
+ {
+ fLengthText.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_RED));
+ }
+
+ validate();
+ }
+
+
+
+ public void keyPressed(KeyEvent e) {
+
+ }
+ });
+
+ fFileText.addKeyListener(new KeyListener() {
+ public void keyReleased(KeyEvent e) {
+ validate();
+ }
+
+ public void keyPressed(KeyEvent e) {
+
+ }
+ });
+
+ composite.pack();
+
+ return composite;
+ }
+
+ public BigInteger getEndAddress()
+ {
+ String text = fEndText.getText();
+ boolean hex = text.startsWith("0x");
+ BigInteger endAddress = new BigInteger(hex ? text.substring(2) : text,
+ hex ? 16 : 10);
+
+ return endAddress;
+ }
+
+ public BigInteger getStartAddress()
+ {
+ String text = fStartText.getText();
+ boolean hex = text.startsWith("0x");
+ BigInteger startAddress = new BigInteger(hex ? text.substring(2) : text,
+ hex ? 16 : 10);
+
+ return startAddress;
+ }
+
+ public BigInteger getLength()
+ {
+ String text = fLengthText.getText();
+ boolean hex = text.startsWith("0x");
+ BigInteger lengthAddress = new BigInteger(hex ? text.substring(2) : text,
+ hex ? 16 : 10);
+
+ return lengthAddress;
+ }
+
+ public File getFile()
+ {
+ return new File(fFileText.getText());
+ }
+
+ private void validate()
+ {
+ boolean isValid = true;
+
+ try
+ {
+ getEndAddress();
+
+ getStartAddress();
+
+ BigInteger length = getLength();
+
+ if(length.compareTo(BigInteger.ZERO) <= 0)
+ isValid = false;
+
+ if(!getFile().getParentFile().exists())
+ isValid = false;
+ }
+ catch(Exception e)
+ {
+ isValid = false;
+ }
+
+ fParentDialog.setValid(isValid);
+
+ }
+
+ public String getId()
+ {
+ return "PlainTextExporter";
+ }
+
+ public String getName()
+ {
+ return "Plain Text";
+ }
+
+ public void exportMemory() {
+ Job job = new Job("Memory Export to Plain Text File"){ //$NON-NLS-1$
+ public IStatus run(IProgressMonitor monitor) {
+
+ try
+ {
+ try
+ {
+ // FIXME 4 byte default
+
+ BigInteger CELLSIZE = BigInteger.valueOf(4);
+
+ BigInteger COLUMNS = BigInteger.valueOf(5); // FIXME
+
+ BigInteger DATA_PER_LINE = CELLSIZE.multiply(COLUMNS);
+
+ BigInteger transferAddress = fStartAddress;
+
+ FileWriter writer = new FileWriter(fOutputFile);
+
+ BigInteger jobs = fEndAddress.subtract(transferAddress).divide(DATA_PER_LINE);
+ BigInteger factor = BigInteger.ONE;
+ if(jobs.compareTo(BigInteger.valueOf(0x7FFFFFFF)) > 0)
+ {
+ factor = jobs.divide(BigInteger.valueOf(0x7FFFFFFF));
+ jobs = jobs.divide(factor);
+ }
+
+ monitor.beginTask("Transferring Data", jobs.intValue());
+
+ BigInteger jobCount = BigInteger.ZERO;
+ while(transferAddress.compareTo(fEndAddress) < 0 && !monitor.isCanceled())
+ {
+ BigInteger length = DATA_PER_LINE;
+ if(fEndAddress.subtract(transferAddress).compareTo(length) < 0)
+ length = fEndAddress.subtract(transferAddress);
+
+ StringBuffer buf = new StringBuffer();
+
+// String transferAddressString = transferAddress.toString(16);
+
+ // future option
+// for(int i = 0; i < 8 - transferAddressString.length(); i++)
+// buf.append("0");
+// buf.append(transferAddressString);
+// buf.append(" "); // TODO tab?
+
+ // data
+
+ for(int i = 0; i < length.divide(CELLSIZE).intValue(); i++)
+ {
+ if(i != 0)
+ buf.append(" ");
+ MemoryByte bytes[] = ((IMemoryBlockExtension) fMemoryBlock).getBytesFromAddress(
+ transferAddress.add(CELLSIZE.multiply(BigInteger.valueOf(i))),
+ CELLSIZE.longValue() / ((IMemoryBlockExtension) fMemoryBlock).getAddressableSize());
+ 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");
+ buf.append(bString);
+ }
+ }
+
+ writer.write(buf.toString().toUpperCase());
+ writer.write("\n");
+
+ 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(Exception e)
+ {
+ MemoryTransportPlugin.getDefault().getLog().log(new Status(IStatus.ERROR, MemoryTransportPlugin.getUniqueIdentifier(),
+ DebugException.INTERNAL_ERROR, "Failure", e));
+ }
+ }
+ catch(Exception e)
+ {
+ MemoryTransportPlugin.getDefault().getLog().log(new Status(IStatus.ERROR, MemoryTransportPlugin.getUniqueIdentifier(),
+ DebugException.INTERNAL_ERROR, "Failure", e));
+ }
+ return Status.OK_STATUS;
+ }};
+ job.setUser(true);
+ job.schedule();
+ }
+}
diff --git a/memory/org.eclipse.cdt.debug.ui.memory.transport/src/org/eclipse/cdt/debug/ui/memory/transport/PlainTextImporter.java b/memory/org.eclipse.cdt.debug.ui.memory.transport/src/org/eclipse/cdt/debug/ui/memory/transport/PlainTextImporter.java
new file mode 100644
index 00000000000..2da8b589549
--- /dev/null
+++ b/memory/org.eclipse.cdt.debug.ui.memory.transport/src/org/eclipse/cdt/debug/ui/memory/transport/PlainTextImporter.java
@@ -0,0 +1,371 @@
+/*******************************************************************************
+ * Copyright (c) 2006-2009 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Ted R Williams (Wind River Systems, Inc.) - initial implementation
+ *******************************************************************************/
+
+package org.eclipse.cdt.debug.ui.memory.transport;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStreamReader;
+import java.math.BigInteger;
+import java.util.Properties;
+import java.util.StringTokenizer;
+
+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.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.layout.FormLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+
+public class PlainTextImporter implements IMemoryImporter {
+
+ File fInputFile;
+ BigInteger fStartAddress;
+ boolean fUseCustomAddress;
+ Boolean fScrollToStart;
+
+ private Text fStartText;
+ private Text fFileText;
+
+// private Button fComboRestoreToThisAddress;
+// private Button fComboRestoreToFileAddress;
+
+ private Button fScrollToBeginningOnImportComplete;
+
+ private IMemoryBlock fMemoryBlock;
+
+ private ImportMemoryDialog fParentDialog;
+
+ private Properties fProperties;
+
+ private static final int BUFFER_LENGTH = 64 * 1024;
+
+ public Control createControl(final Composite parent, IMemoryBlock memBlock, Properties properties, ImportMemoryDialog parentDialog)
+ {
+ fMemoryBlock = memBlock;
+ fParentDialog = parentDialog;
+ fProperties = properties;
+
+ fUseCustomAddress = true;
+
+ Composite composite = new Composite(parent, SWT.NONE)
+ {
+ public void dispose()
+ {
+ fProperties.setProperty(TRANSFER_FILE, fFileText.getText());
+ fProperties.setProperty(TRANSFER_START, fStartText.getText());
+ fProperties.setProperty(TRANSFER_SCROLL_TO_START, fScrollToStart.toString());
+
+ fStartAddress = getStartAddress();
+ fInputFile = getFile();
+
+ super.dispose();
+ }
+ };
+ FormLayout formLayout = new FormLayout();
+ formLayout.spacing = 5;
+ formLayout.marginWidth = formLayout.marginHeight = 9;
+ composite.setLayout(formLayout);
+
+// // restore to file address
+//
+// fComboRestoreToFileAddress = new Button(composite, SWT.RADIO);
+// fComboRestoreToFileAddress.setText("Restore to address specified in the file");
+// //comboRestoreToFileAddress.setLayoutData(data);
+//
+// // restore to this address
+//
+// fComboRestoreToThisAddress = new Button(composite, SWT.RADIO);
+// fComboRestoreToThisAddress.setText("Restore to this address: ");
+ FormData data = new FormData();
+// data.top = new FormAttachment(fComboRestoreToFileAddress);
+// fComboRestoreToThisAddress.setLayoutData(data);
+
+ Label labelStartText = new Label(composite, SWT.NONE);
+ labelStartText.setText("Restore to address: ");
+
+ fStartText = new Text(composite, SWT.NONE);
+ data = new FormData();
+// data.top = new FormAttachment(fComboRestoreToFileAddress);
+ data.left = new FormAttachment(labelStartText);
+ data.width = 100;
+ fStartText.setLayoutData(data);
+
+ // file
+
+ Label fileLabel = new Label(composite, SWT.NONE);
+ fFileText = new Text(composite, SWT.NONE);
+ Button fileButton = new Button(composite, SWT.PUSH);
+
+ fileLabel.setText("File name: ");
+ data = new FormData();
+ data.top = new FormAttachment(fileButton, 0, SWT.CENTER);
+ fileLabel.setLayoutData(data);
+
+ data = new FormData();
+ data.top = new FormAttachment(fileButton, 0, SWT.CENTER);
+ data.left = new FormAttachment(fileLabel);
+ data.width = 300;
+ fFileText.setLayoutData(data);
+
+ fileButton.setText("Browse...");
+ data = new FormData();
+ data.top = new FormAttachment(fStartText);
+ data.left = new FormAttachment(fFileText);
+ fileButton.setLayoutData(data);
+
+ fFileText.setText(properties.getProperty(TRANSFER_FILE, ""));
+ fScrollToStart = new Boolean(properties.getProperty(TRANSFER_SCROLL_TO_START, "true"));
+ try
+ {
+ BigInteger startAddress = null;
+ if(fMemoryBlock instanceof IMemoryBlockExtension)
+ startAddress = ((IMemoryBlockExtension) fMemoryBlock)
+ .getBigBaseAddress(); // FIXME use selection/caret address?
+ else
+ startAddress = BigInteger.valueOf(fMemoryBlock.getStartAddress());
+
+ if(properties.getProperty(TRANSFER_START) != null)
+ fStartText.setText(properties.getProperty(TRANSFER_START));
+ else
+ fStartText.setText("0x" + startAddress.toString(16));
+
+ }
+ catch(Exception e)
+ {
+ MemoryTransportPlugin.getDefault().getLog().log(new Status(IStatus.ERROR, MemoryTransportPlugin.getUniqueIdentifier(),
+ DebugException.INTERNAL_ERROR, "Failure", e));
+ }
+
+ fileButton.addSelectionListener(new SelectionListener() {
+
+ public void widgetDefaultSelected(SelectionEvent e) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void widgetSelected(SelectionEvent e) {
+ FileDialog dialog = new FileDialog(parent.getShell(), SWT.SAVE);
+ dialog.setText("Choose memory import file");
+ dialog.setFilterExtensions(new String[] { "*.*;*" } );
+ dialog.setFilterNames(new String[] { "All Files" } );
+ dialog.setFileName(fFileText.getText());
+ dialog.open();
+
+ String filename = dialog.getFileName();
+ if(filename != null && filename.length() != 0 )
+ {
+ fFileText.setText(dialog.getFilterPath() + File.separator + filename);
+ }
+
+ validate();
+ }
+
+ });
+
+ fStartText.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ boolean valid = true;
+ try
+ {
+ getStartAddress();
+ }
+ catch(Exception ex)
+ {
+ valid = false;
+ }
+
+ fStartText.setForeground(valid ? Display.getDefault().getSystemColor(SWT.COLOR_BLACK) :
+ Display.getDefault().getSystemColor(SWT.COLOR_RED));
+
+ //
+
+ validate();
+ }
+
+ });
+ fFileText.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ validate();
+ }
+ });
+
+ fScrollToBeginningOnImportComplete = new Button(composite, SWT.CHECK);
+ fScrollToBeginningOnImportComplete.setText("Scroll to File Start Address");
+ data = new FormData();
+ data.top = new FormAttachment(fileButton);
+ fScrollToBeginningOnImportComplete.setLayoutData(data);
+
+ composite.pack();
+ parent.pack();
+
+ Display.getDefault().asyncExec(new Runnable(){
+ public void run()
+ {
+ validate();
+ }
+ });
+
+ return composite;
+ }
+
+ private void validate()
+ {
+ boolean isValid = true;
+
+ try
+ {
+ getStartAddress();
+ if(!getFile().exists())
+ isValid = false;
+ }
+ catch(Exception e)
+ {
+ isValid = false;
+ }
+
+ fParentDialog.setValid(isValid);
+ }
+
+ public boolean getScrollToStart()
+ {
+ return fScrollToBeginningOnImportComplete.getSelection();
+ }
+
+ public BigInteger getStartAddress()
+ {
+ String text = fStartText.getText();
+ boolean hex = text.startsWith("0x");
+ BigInteger startAddress = new BigInteger(hex ? text.substring(2) : text,
+ hex ? 16 : 10);
+
+ return startAddress;
+ }
+
+ public File getFile()
+ {
+ return new File(fFileText.getText());
+ }
+
+ public String getId()
+ {
+ return "PlainTextImporter";
+ }
+
+ public String getName()
+ {
+ return "Plain Text";
+ }
+
+ public void importMemory() {
+ Job job = new Job("Memory Import from Plain Text File"){ //$NON-NLS-1$
+
+ public IStatus run(IProgressMonitor monitor) {
+
+ try
+ {
+ 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("Transferring Data", jobs.intValue()); //$NON-NLS-1$
+
+ BigInteger jobCount = BigInteger.ZERO;
+ BigInteger recordAddress = fStartAddress;
+ String line = reader.readLine();
+ while(line != null && !monitor.isCanceled())
+ {
+ StringTokenizer st = new StringTokenizer(line, " ");
+ 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++)
+ {
+ data[i] = new BigInteger(valueString.substring(position++, position++ + 1), 16).byteValue();
+ }
+
+ 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));
+
+ jobCount = jobCount.add(BigInteger.valueOf(bytesRead));
+ while(jobCount.compareTo(factor) >= 0)
+ {
+ jobCount = jobCount.subtract(factor);
+ monitor.worked(1);
+ }
+
+ line = reader.readLine();
+ }
+
+ memoryWriter.flush();
+ reader.close();
+ monitor.done();
+
+ if(fProperties.getProperty(TRANSFER_SCROLL_TO_START, "false").equals("true"))
+ fParentDialog.scrollRenderings(scrollToAddress);
+ }
+ catch(Exception e)
+ {
+ MemoryTransportPlugin.getDefault().getLog().log(new Status(IStatus.ERROR, MemoryTransportPlugin.getUniqueIdentifier(),
+ DebugException.INTERNAL_ERROR, "Failure", e));
+ }
+ }
+ catch(Exception e) {e.printStackTrace();}
+ return Status.OK_STATUS;
+ }};
+ job.setUser(true);
+ job.schedule();
+ }
+}
diff --git a/memory/org.eclipse.cdt.debug.ui.memory.transport/src/org/eclipse/cdt/debug/ui/memory/transport/RAWBinaryExporter.java b/memory/org.eclipse.cdt.debug.ui.memory.transport/src/org/eclipse/cdt/debug/ui/memory/transport/RAWBinaryExporter.java
new file mode 100644
index 00000000000..ca15bfdd2a8
--- /dev/null
+++ b/memory/org.eclipse.cdt.debug.ui.memory.transport/src/org/eclipse/cdt/debug/ui/memory/transport/RAWBinaryExporter.java
@@ -0,0 +1,465 @@
+/*******************************************************************************
+ * Copyright (c) 2006-2009 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Ted R Williams (Wind River Systems, Inc.) - initial implementation
+ *******************************************************************************/
+
+package org.eclipse.cdt.debug.ui.memory.transport;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.math.BigInteger;
+import java.util.Properties;
+
+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.swt.SWT;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.layout.FormLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+
+public class RAWBinaryExporter implements IMemoryExporter
+{
+ File fOutputFile;
+ BigInteger fStartAddress;
+ BigInteger fEndAddress;
+
+ private Text fStartText;
+ private Text fEndText;
+ private Text fLengthText;
+ private Text fFileText;
+
+ private IMemoryBlock fMemoryBlock;
+
+ private ExportMemoryDialog fParentDialog;
+
+ private Properties fProperties;
+
+ public Control createControl(final Composite parent, IMemoryBlock memBlock, Properties properties, ExportMemoryDialog parentDialog)
+ {
+ fMemoryBlock = memBlock;
+ fParentDialog = parentDialog;
+ fProperties = properties;
+
+ Composite composite = new Composite(parent, SWT.NONE)
+ {
+ public void dispose()
+ {
+ fProperties.setProperty(TRANSFER_FILE, fFileText.getText());
+ fProperties.setProperty(TRANSFER_START, fStartText.getText());
+ fProperties.setProperty(TRANSFER_END, fEndText.getText());
+
+ fStartAddress = getStartAddress();
+ fEndAddress = getEndAddress();
+ fOutputFile = getFile();
+
+ super.dispose();
+ }
+ };
+ FormLayout formLayout = new FormLayout();
+ formLayout.spacing = 5;
+ formLayout.marginWidth = formLayout.marginHeight = 9;
+ composite.setLayout(formLayout);
+
+ // start address
+
+ Label startLabel = new Label(composite, SWT.NONE);
+ startLabel.setText("Start address: ");
+ FormData data = new FormData();
+ startLabel.setLayoutData(data);
+
+ fStartText = new Text(composite, SWT.NONE);
+ data = new FormData();
+ data.left = new FormAttachment(startLabel);
+ data.width = 100;
+ fStartText.setLayoutData(data);
+
+ // end address
+
+ Label endLabel = new Label(composite, SWT.NONE);
+ endLabel.setText("End address: ");
+ data = new FormData();
+ data.top = new FormAttachment(fStartText, 0, SWT.CENTER);
+ data.left = new FormAttachment(fStartText);
+ endLabel.setLayoutData(data);
+
+ fEndText = new Text(composite, SWT.NONE);
+ data = new FormData();
+ data.top = new FormAttachment(fStartText, 0, SWT.CENTER);
+ data.left = new FormAttachment(endLabel);
+ data.width = 100;
+ fEndText.setLayoutData(data);
+
+ // length
+
+ Label lengthLabel = new Label(composite, SWT.NONE);
+ lengthLabel.setText("Length: ");
+ data = new FormData();
+ data.top = new FormAttachment(fStartText, 0, SWT.CENTER);
+ data.left = new FormAttachment(fEndText);
+ lengthLabel.setLayoutData(data);
+
+ fLengthText = new Text(composite, SWT.NONE);
+ data = new FormData();
+ data.top = new FormAttachment(fStartText, 0, SWT.CENTER);
+ data.left = new FormAttachment(lengthLabel);
+ data.width = 100;
+ fLengthText.setLayoutData(data);
+
+ // file
+
+ Label fileLabel = new Label(composite, SWT.NONE);
+ fFileText = new Text(composite, SWT.NONE);
+ Button fileButton = new Button(composite, SWT.PUSH);
+
+ fileLabel.setText("File name: ");
+ data = new FormData();
+ data.top = new FormAttachment(fileButton, 0, SWT.CENTER);
+ fileLabel.setLayoutData(data);
+
+ data = new FormData();
+ data.top = new FormAttachment(fileButton, 0, SWT.CENTER);
+ data.left = new FormAttachment(fileLabel);
+ data.width = 300;
+ fFileText.setLayoutData(data);
+
+ fileButton.setText("Browse...");
+ data = new FormData();
+ data.top = new FormAttachment(fLengthText);
+ data.left = new FormAttachment(fFileText);
+ fileButton.setLayoutData(data);
+
+ fFileText.setText(properties.getProperty(TRANSFER_FILE, ""));
+ try
+ {
+ BigInteger startAddress = null;
+ if(fMemoryBlock instanceof IMemoryBlockExtension)
+ startAddress = ((IMemoryBlockExtension) fMemoryBlock).getBigBaseAddress();
+ else
+ startAddress = BigInteger.valueOf(fMemoryBlock.getStartAddress());
+
+ if(properties.getProperty(TRANSFER_START) != null)
+ fStartText.setText(properties.getProperty(TRANSFER_START));
+ else
+ fStartText.setText("0x" + startAddress.toString(16));
+
+ if(properties.getProperty(TRANSFER_END) != null)
+ fEndText.setText(properties.getProperty(TRANSFER_END));
+ else
+ fEndText.setText("0x" + startAddress.toString(16));
+
+ fLengthText.setText(getEndAddress().subtract(getStartAddress()).toString());
+ }
+ catch(Exception e)
+ {
+ MemoryTransportPlugin.getDefault().getLog().log(new Status(IStatus.ERROR, MemoryTransportPlugin.getUniqueIdentifier(),
+ DebugException.INTERNAL_ERROR, "Failure", e));
+ }
+
+ fileButton.addSelectionListener(new SelectionListener() {
+
+ public void widgetDefaultSelected(SelectionEvent e) {
+ }
+
+ public void widgetSelected(SelectionEvent e) {
+ FileDialog dialog = new FileDialog(parent.getShell(), SWT.SAVE);
+ dialog.setText("Choose memory export file");
+ dialog.setFilterExtensions(new String[] { "*.*;*" } );
+ dialog.setFilterNames(new String[] { "All Files" } );
+ dialog.setFileName(fFileText.getText());
+ dialog.open();
+
+ String filename = dialog.getFileName();
+ if(filename != null && filename.length() != 0 )
+ {
+ fFileText.setText(dialog.getFilterPath() + File.separator + filename);
+ }
+
+ validate();
+ }
+
+ });
+
+ fStartText.addKeyListener(new KeyListener() {
+ public void keyReleased(KeyEvent e) {
+ boolean valid = true;
+ try
+ {
+ getStartAddress();
+ }
+ catch(Exception ex)
+ {
+ valid = false;
+ }
+
+ fStartText.setForeground(valid ? Display.getDefault().getSystemColor(SWT.COLOR_BLACK) :
+ Display.getDefault().getSystemColor(SWT.COLOR_RED));
+
+ //
+
+ BigInteger endAddress = getEndAddress();
+ BigInteger startAddress = getStartAddress();
+
+ fLengthText.setText(endAddress.subtract(startAddress).toString());
+
+ validate();
+ }
+
+ public void keyPressed(KeyEvent e) {}
+ });
+
+ fEndText.addKeyListener(new KeyListener() {
+ public void keyReleased(KeyEvent e) {
+ try
+ {
+ getEndAddress();
+ fEndText.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_BLACK));
+
+ BigInteger endAddress = getEndAddress();
+ BigInteger startAddress = getStartAddress();
+
+ String lengthString = endAddress.subtract(startAddress).toString();
+
+ if(!fLengthText.getText().equals(lengthString))
+ fLengthText.setText(lengthString);
+ }
+ catch(Exception ex)
+ {
+ fEndText.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_RED));
+ }
+
+ validate();
+ }
+
+ public void keyPressed(KeyEvent e) {}
+
+ });
+
+ fLengthText.addKeyListener(new KeyListener() {
+ public void keyReleased(KeyEvent e) {
+ try
+ {
+ BigInteger length = getLength();
+ fLengthText.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_BLACK));
+ BigInteger startAddress = getStartAddress();
+ String endString = "0x" + startAddress.add(length).toString(16);
+ if(!fEndText.getText().equals(endString))
+ fEndText.setText(endString);
+ }
+ catch(Exception ex)
+ {
+ fLengthText.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_RED));
+ }
+
+ validate();
+ }
+
+
+
+ public void keyPressed(KeyEvent e) {
+
+ }
+ });
+
+ fFileText.addKeyListener(new KeyListener() {
+ public void keyReleased(KeyEvent e) {
+ validate();
+ }
+
+ public void keyPressed(KeyEvent e) {
+
+ }
+ });
+
+ composite.pack();
+ parent.pack();
+
+ /*
+ * We need to perform a validation. If we do it immediately we will get an exception
+ * because things are not totally setup. So we schedule an immediate running of the
+ * validation. For a very brief time the view logically may show a state which does
+ * not reflect the true state of affairs. But the validate immediately corrects the
+ * info. In practice the user never sees the invalid state displayed, because of the
+ * speed of the draw of the dialog.
+ */
+ Display.getDefault().asyncExec(new Runnable(){
+ public void run()
+ {
+ validate();
+ }
+ });
+
+ return composite;
+ }
+
+ public BigInteger getEndAddress()
+ {
+ String text = fEndText.getText();
+ boolean hex = text.startsWith("0x");
+ BigInteger endAddress = new BigInteger(hex ? text.substring(2) : text,
+ hex ? 16 : 10);
+
+ return endAddress;
+ }
+
+ public BigInteger getStartAddress()
+ {
+ String text = fStartText.getText();
+ boolean hex = text.startsWith("0x");
+ BigInteger startAddress = new BigInteger(hex ? text.substring(2) : text,
+ hex ? 16 : 10);
+
+ return startAddress;
+ }
+
+ public BigInteger getLength()
+ {
+ String text = fLengthText.getText();
+ boolean hex = text.startsWith("0x");
+ BigInteger lengthAddress = new BigInteger(hex ? text.substring(2) : text,
+ hex ? 16 : 10);
+
+ return lengthAddress;
+ }
+
+ public File getFile()
+ {
+ return new File(fFileText.getText());
+ }
+
+ private void validate()
+ {
+ boolean isValid = true;
+
+ try
+ {
+ getEndAddress();
+
+ getStartAddress();
+
+ BigInteger length = getLength();
+
+ if(length.compareTo(BigInteger.ZERO) <= 0)
+ isValid = false;
+
+ if(!getFile().getParentFile().exists())
+ isValid = false;
+ }
+ catch(Exception e)
+ {
+ isValid = false;
+ }
+
+ fParentDialog.setValid(isValid);
+ }
+
+
+ public String getId()
+ {
+ return "rawbinary";
+ }
+
+ public String getName()
+ {
+ return "RAW Binary";
+ }
+
+ public void exportMemory()
+ {
+ Job job = new Job("Memory Export to RAW Binary File"){ //$NON-NLS-1$
+ public IStatus run(IProgressMonitor monitor) {
+
+ try
+ {
+ try
+ {
+ BigInteger DATA_PER_RECORD = BigInteger.valueOf(1024);
+
+ 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("Transferring Data", jobs.intValue());
+
+ 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);
+
+ // 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(Exception e)
+ {
+ MemoryTransportPlugin.getDefault().getLog().log(new Status(IStatus.ERROR, MemoryTransportPlugin.getUniqueIdentifier(),
+ DebugException.INTERNAL_ERROR, "Failure", e));
+ }
+ }
+ catch(Exception e)
+ {
+ MemoryTransportPlugin.getDefault().getLog().log(new Status(IStatus.ERROR, MemoryTransportPlugin.getUniqueIdentifier(),
+ DebugException.INTERNAL_ERROR, "Failure", e));
+ }
+ return Status.OK_STATUS;
+ }};
+ job.setUser(true);
+ job.schedule();
+ }
+
+}
diff --git a/memory/org.eclipse.cdt.debug.ui.memory.transport/src/org/eclipse/cdt/debug/ui/memory/transport/RAWBinaryImporter.java b/memory/org.eclipse.cdt.debug.ui.memory.transport/src/org/eclipse/cdt/debug/ui/memory/transport/RAWBinaryImporter.java
new file mode 100644
index 00000000000..d0270ae962e
--- /dev/null
+++ b/memory/org.eclipse.cdt.debug.ui.memory.transport/src/org/eclipse/cdt/debug/ui/memory/transport/RAWBinaryImporter.java
@@ -0,0 +1,344 @@
+/*******************************************************************************
+ * Copyright (c) 2006-2009 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Ted R Williams (Wind River Systems, Inc.) - initial implementation
+ *******************************************************************************/
+
+package org.eclipse.cdt.debug.ui.memory.transport;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.math.BigInteger;
+import java.util.Properties;
+
+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.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.layout.FormLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+
+public class RAWBinaryImporter implements IMemoryImporter {
+
+ File fInputFile;
+ BigInteger fStartAddress;
+ Boolean fScrollToStart;
+
+ private Text fStartText;
+ private Text fFileText;
+
+ private Button fScrollToBeginningOnImportComplete;
+
+ private IMemoryBlock fMemoryBlock;
+
+ private ImportMemoryDialog fParentDialog;
+
+ private Properties fProperties;
+
+ private static final int BUFFER_LENGTH = 64 * 1024;
+
+ public Control createControl(final Composite parent, IMemoryBlock memBlock, Properties properties, ImportMemoryDialog parentDialog)
+ {
+ fMemoryBlock = memBlock;
+ fParentDialog = parentDialog;
+ fProperties = properties;
+
+ Composite composite = new Composite(parent, SWT.NONE)
+ {
+ public void dispose()
+ {
+ fProperties.setProperty(TRANSFER_FILE, fFileText.getText());
+ fProperties.setProperty(TRANSFER_START, fStartText.getText());
+ fProperties.setProperty(TRANSFER_SCROLL_TO_START, fScrollToStart.toString());
+ fStartAddress = getStartAddress();
+ fInputFile = getFile();
+
+ super.dispose();
+ }
+ };
+ FormLayout formLayout = new FormLayout();
+ formLayout.spacing = 5;
+ formLayout.marginWidth = formLayout.marginHeight = 9;
+ composite.setLayout(formLayout);
+
+ // restore to this address
+
+ Label labelStartText = new Label(composite, SWT.NONE);
+ labelStartText.setText("Restore to address: ");
+
+ fStartText = new Text(composite, SWT.NONE);
+ FormData data = new FormData();
+ data.left = new FormAttachment(labelStartText);
+ data.width = 100;
+ fStartText.setLayoutData(data);
+
+ // file
+
+ Label fileLabel = new Label(composite, SWT.NONE);
+ fFileText = new Text(composite, SWT.NONE);
+ Button fileButton = new Button(composite, SWT.PUSH);
+
+ fileLabel.setText("File name: ");
+ data = new FormData();
+ data.top = new FormAttachment(fileButton, 0, SWT.CENTER);
+ fileLabel.setLayoutData(data);
+
+ data = new FormData();
+ data.top = new FormAttachment(fileButton, 0, SWT.CENTER);
+ data.left = new FormAttachment(fileLabel);
+ data.width = 300;
+ fFileText.setLayoutData(data);
+
+ fileButton.setText("Browse...");
+ data = new FormData();
+ data.top = new FormAttachment(fStartText);
+ data.left = new FormAttachment(fFileText);
+ fileButton.setLayoutData(data);
+
+ fFileText.setText(properties.getProperty(TRANSFER_FILE, ""));
+ fScrollToStart = new Boolean(properties.getProperty(TRANSFER_SCROLL_TO_START, "true"));
+ try
+ {
+ BigInteger startAddress = null;
+ if(fMemoryBlock instanceof IMemoryBlockExtension)
+ startAddress = ((IMemoryBlockExtension) fMemoryBlock).getBigBaseAddress();
+ else
+ startAddress = BigInteger.valueOf(fMemoryBlock.getStartAddress());
+
+ if(properties.getProperty(TRANSFER_START) != null)
+ fStartText.setText(properties.getProperty(TRANSFER_START));
+ else
+ fStartText.setText("0x" + startAddress.toString(16));
+
+ }
+ catch(Exception e)
+ {
+ MemoryTransportPlugin.getDefault().getLog().log(new Status(IStatus.ERROR, MemoryTransportPlugin.getUniqueIdentifier(),
+ DebugException.INTERNAL_ERROR, "Failure", e));
+ }
+
+ fileButton.addSelectionListener(new SelectionListener() {
+
+ public void widgetDefaultSelected(SelectionEvent e) {
+ }
+
+ public void widgetSelected(SelectionEvent e) {
+ FileDialog dialog = new FileDialog(parent.getShell(), SWT.SAVE);
+ dialog.setText("Choose memory import file");
+ dialog.setFilterExtensions(new String[] { "*.*;*" } );
+ dialog.setFilterNames(new String[] { "All Files" } );
+ dialog.setFileName(fFileText.getText());
+ dialog.open();
+
+ String filename = dialog.getFileName();
+ if(filename != null && filename.length() != 0 )
+ {
+ fFileText.setText(dialog.getFilterPath() + File.separator + filename);
+ }
+
+ validate();
+ }
+
+ });
+
+ fStartText.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ boolean valid = true;
+ try
+ {
+ getStartAddress();
+ }
+ catch(Exception ex)
+ {
+ valid = false;
+ }
+
+ fStartText.setForeground(valid ? Display.getDefault().getSystemColor(SWT.COLOR_BLACK) :
+ Display.getDefault().getSystemColor(SWT.COLOR_RED));
+
+ //
+
+ validate();
+ }
+
+ });
+ fFileText.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ validate();
+ }
+ });
+
+ fScrollToBeginningOnImportComplete = new Button(composite, SWT.CHECK);
+ fScrollToBeginningOnImportComplete.setText("Scroll to File Start Address");
+ data = new FormData();
+ data.top = new FormAttachment(fileButton);
+ fScrollToBeginningOnImportComplete.setLayoutData(data);
+
+ composite.pack();
+ parent.pack();
+
+ Display.getDefault().asyncExec(new Runnable(){
+ public void run()
+ {
+ validate();
+ }
+ });
+
+ return composite;
+ }
+
+ private void validate()
+ {
+ boolean isValid = true;
+
+ try
+ {
+ getStartAddress();
+ if(!getFile().exists())
+ isValid = false;
+ }
+ catch(Exception e)
+ {
+ isValid = false;
+ }
+
+ fParentDialog.setValid(isValid);
+ }
+
+ public boolean getScrollToStart()
+ {
+ return fScrollToBeginningOnImportComplete.getSelection();
+ }
+
+ public BigInteger getStartAddress()
+ {
+ String text = fStartText.getText();
+ boolean hex = text.startsWith("0x");
+ BigInteger startAddress = new BigInteger(hex ? text.substring(2) : text,
+ hex ? 16 : 10);
+
+ return startAddress;
+ }
+
+ public File getFile()
+ {
+ return new File(fFileText.getText());
+ }
+
+ public String getId()
+ {
+ return "rawbinary";
+ }
+
+ public String getName()
+ {
+ return "RAW Binary";
+ }
+
+ public void importMemory() {
+ Job job = new Job("Memory Import from RAW Binary File"){ //$NON-NLS-1$
+
+ public IStatus run(IProgressMonitor monitor) {
+
+ try
+ {
+ 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("Transferring Data", jobs.intValue()); //$NON-NLS-1$
+
+ BigInteger jobCount = BigInteger.ZERO;
+ 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);
+
+ jobCount = jobCount.add(BigInteger.valueOf(actualByteCount));
+ while(jobCount.compareTo(factor) >= 0)
+ {
+ jobCount = jobCount.subtract(factor);
+ monitor.worked(1);
+ }
+
+ recordAddress.add(BigInteger.valueOf(actualByteCount));
+ actualByteCount = reader.read(byteValues);
+ }
+
+ memoryWriter.flush();
+ reader.close();
+ monitor.done();
+
+ if(fProperties.getProperty(TRANSFER_SCROLL_TO_START, "false").equals("true"))
+ fParentDialog.scrollRenderings(scrollToAddress);
+ }
+ catch(Exception e)
+ {
+ MemoryTransportPlugin.getDefault().getLog().log(new Status(IStatus.ERROR, MemoryTransportPlugin.getUniqueIdentifier(),
+ DebugException.INTERNAL_ERROR, "Failure", e));
+ }
+ }
+ catch(Exception e)
+ {
+ MemoryTransportPlugin.getDefault().getLog().log(new Status(IStatus.ERROR, MemoryTransportPlugin.getUniqueIdentifier(),
+ DebugException.INTERNAL_ERROR, "Failure", e));
+ }
+ return Status.OK_STATUS;
+ }};
+ job.setUser(true);
+ job.schedule();
+ }
+}
diff --git a/memory/org.eclipse.cdt.debug.ui.memory.transport/src/org/eclipse/cdt/debug/ui/memory/transport/SRecordExporter.java b/memory/org.eclipse.cdt.debug.ui.memory.transport/src/org/eclipse/cdt/debug/ui/memory/transport/SRecordExporter.java
new file mode 100644
index 00000000000..8e6f61b7c9a
--- /dev/null
+++ b/memory/org.eclipse.cdt.debug.ui.memory.transport/src/org/eclipse/cdt/debug/ui/memory/transport/SRecordExporter.java
@@ -0,0 +1,508 @@
+/*******************************************************************************
+ * Copyright (c) 2006-2009 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Ted R Williams (Wind River Systems, Inc.) - initial implementation
+ *******************************************************************************/
+
+package org.eclipse.cdt.debug.ui.memory.transport;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.math.BigInteger;
+import java.util.Properties;
+
+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.swt.SWT;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.layout.FormLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+
+public class SRecordExporter implements IMemoryExporter
+{
+ File fOutputFile;
+ BigInteger fStartAddress;
+ BigInteger fEndAddress;
+
+ private Text fStartText;
+ private Text fEndText;
+ private Text fLengthText;
+ private Text fFileText;
+
+ private IMemoryBlock fMemoryBlock;
+
+ private ExportMemoryDialog fParentDialog;
+
+ private Properties fProperties;
+
+ public Control createControl(final Composite parent, IMemoryBlock memBlock, Properties properties, ExportMemoryDialog parentDialog)
+ {
+ fMemoryBlock = memBlock;
+ fParentDialog = parentDialog;
+ fProperties = properties;
+
+ Composite composite = new Composite(parent, SWT.NONE)
+ {
+ public void dispose()
+ {
+ fProperties.setProperty(TRANSFER_FILE, fFileText.getText());
+ fProperties.setProperty(TRANSFER_START, fStartText.getText());
+ fProperties.setProperty(TRANSFER_END, fEndText.getText());
+
+ fStartAddress = getStartAddress();
+ fEndAddress = getEndAddress();
+ fOutputFile = getFile();
+
+ super.dispose();
+ }
+ };
+ FormLayout formLayout = new FormLayout();
+ formLayout.spacing = 5;
+ formLayout.marginWidth = formLayout.marginHeight = 9;
+ composite.setLayout(formLayout);
+
+ // start address
+
+ Label startLabel = new Label(composite, SWT.NONE);
+ startLabel.setText("Start address: ");
+ FormData data = new FormData();
+ startLabel.setLayoutData(data);
+
+ fStartText = new Text(composite, SWT.NONE);
+ data = new FormData();
+ data.left = new FormAttachment(startLabel);
+ data.width = 100;
+ fStartText.setLayoutData(data);
+
+ // end address
+
+ Label endLabel = new Label(composite, SWT.NONE);
+ endLabel.setText("End address: ");
+ data = new FormData();
+ data.top = new FormAttachment(fStartText, 0, SWT.CENTER);
+ data.left = new FormAttachment(fStartText);
+ endLabel.setLayoutData(data);
+
+ fEndText = new Text(composite, SWT.NONE);
+ data = new FormData();
+ data.top = new FormAttachment(fStartText, 0, SWT.CENTER);
+ data.left = new FormAttachment(endLabel);
+ data.width = 100;
+ fEndText.setLayoutData(data);
+
+ // length
+
+ Label lengthLabel = new Label(composite, SWT.NONE);
+ lengthLabel.setText("Length: ");
+ data = new FormData();
+ data.top = new FormAttachment(fStartText, 0, SWT.CENTER);
+ data.left = new FormAttachment(fEndText);
+ lengthLabel.setLayoutData(data);
+
+ fLengthText = new Text(composite, SWT.NONE);
+ data = new FormData();
+ data.top = new FormAttachment(fStartText, 0, SWT.CENTER);
+ data.left = new FormAttachment(lengthLabel);
+ data.width = 100;
+ fLengthText.setLayoutData(data);
+
+ // file
+
+ Label fileLabel = new Label(composite, SWT.NONE);
+ fFileText = new Text(composite, SWT.NONE);
+ Button fileButton = new Button(composite, SWT.PUSH);
+
+ fileLabel.setText("File name: ");
+ data = new FormData();
+ data.top = new FormAttachment(fileButton, 0, SWT.CENTER);
+ fileLabel.setLayoutData(data);
+
+ data = new FormData();
+ data.top = new FormAttachment(fileButton, 0, SWT.CENTER);
+ data.left = new FormAttachment(fileLabel);
+ data.width = 300;
+ fFileText.setLayoutData(data);
+
+ fileButton.setText("Browse...");
+ data = new FormData();
+ data.top = new FormAttachment(fLengthText);
+ data.left = new FormAttachment(fFileText);
+ fileButton.setLayoutData(data);
+
+ fFileText.setText(properties.getProperty(TRANSFER_FILE, ""));
+ try
+ {
+ BigInteger startAddress = null;
+ if(fMemoryBlock instanceof IMemoryBlockExtension)
+ startAddress = ((IMemoryBlockExtension) fMemoryBlock)
+ .getBigBaseAddress(); // FIXME use selection/caret address?
+ else
+ startAddress = BigInteger.valueOf(fMemoryBlock.getStartAddress());
+
+ if(properties.getProperty(TRANSFER_START) != null)
+ fStartText.setText(properties.getProperty(TRANSFER_START));
+ else
+ fStartText.setText("0x" + startAddress.toString(16));
+
+ if(properties.getProperty(TRANSFER_END) != null)
+ fEndText.setText(properties.getProperty(TRANSFER_END));
+ else
+ fEndText.setText("0x" + startAddress.toString(16));
+
+ fLengthText.setText(getEndAddress().subtract(getStartAddress()).toString());
+ }
+ catch(Exception e)
+ {
+ MemoryTransportPlugin.getDefault().getLog().log(new Status(IStatus.ERROR, MemoryTransportPlugin.getUniqueIdentifier(),
+ DebugException.INTERNAL_ERROR, "Failure", e));
+ }
+
+ fileButton.addSelectionListener(new SelectionListener() {
+
+ public void widgetDefaultSelected(SelectionEvent e) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void widgetSelected(SelectionEvent e) {
+ FileDialog dialog = new FileDialog(parent.getShell(), SWT.SAVE);
+ dialog.setText("Choose memory export file");
+ dialog.setFilterExtensions(new String[] { "*.*;*" } );
+ dialog.setFilterNames(new String[] { "All Files" } );
+ dialog.setFileName(fFileText.getText());
+ dialog.open();
+
+ String filename = dialog.getFileName();
+ if(filename != null && filename.length() != 0 )
+ {
+ fFileText.setText(dialog.getFilterPath() + File.separator + filename);
+ }
+
+ validate();
+ }
+
+ });
+
+ fStartText.addKeyListener(new KeyListener() {
+ public void keyReleased(KeyEvent e) {
+ boolean valid = true;
+ try
+ {
+ getStartAddress();
+ }
+ catch(Exception ex)
+ {
+ valid = false;
+ }
+
+ fStartText.setForeground(valid ? Display.getDefault().getSystemColor(SWT.COLOR_BLACK) :
+ Display.getDefault().getSystemColor(SWT.COLOR_RED));
+
+ //
+
+ BigInteger endAddress = getEndAddress();
+ BigInteger startAddress = getStartAddress();
+
+ fLengthText.setText(endAddress.subtract(startAddress).toString());
+
+ validate();
+ }
+
+ public void keyPressed(KeyEvent e) {}
+ });
+
+ fEndText.addKeyListener(new KeyListener() {
+ public void keyReleased(KeyEvent e) {
+ try
+ {
+ getEndAddress();
+ fEndText.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_BLACK));
+
+ BigInteger endAddress = getEndAddress();
+ BigInteger startAddress = getStartAddress();
+
+ String lengthString = endAddress.subtract(startAddress).toString();
+
+ if(!fLengthText.getText().equals(lengthString))
+ fLengthText.setText(lengthString);
+ }
+ catch(Exception ex)
+ {
+ fEndText.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_RED));
+ }
+
+ validate();
+ }
+
+ public void keyPressed(KeyEvent e) {}
+
+ });
+
+ fLengthText.addKeyListener(new KeyListener() {
+ public void keyReleased(KeyEvent e) {
+ try
+ {
+ BigInteger length = getLength();
+ fLengthText.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_BLACK));
+ BigInteger startAddress = getStartAddress();
+ String endString = "0x" + startAddress.add(length).toString(16);
+ if(!fEndText.getText().equals(endString))
+ fEndText.setText(endString);
+ }
+ catch(Exception ex)
+ {
+ fLengthText.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_RED));
+ }
+
+ validate();
+ }
+
+
+
+ public void keyPressed(KeyEvent e) {
+
+ }
+ });
+
+ fFileText.addKeyListener(new KeyListener() {
+ public void keyReleased(KeyEvent e) {
+ validate();
+ }
+
+ public void keyPressed(KeyEvent e) {
+
+ }
+ });
+
+ composite.pack();
+ parent.pack();
+
+ /*
+ * We need to perform a validation. If we do it immediately we will get an exception
+ * because things are not totally setup. So we schedule an immediate running of the
+ * validation. For a very brief time the view logically may show a state which does
+ * not reflect the true state of affairs. But the validate immediately corrects the
+ * info. In practice the user never sees the invalid state displayed, because of the
+ * speed of the draw of the dialog.
+ */
+ Display.getDefault().asyncExec(new Runnable(){
+ public void run()
+ {
+ validate();
+ }
+ });
+
+ return composite;
+ }
+
+ public BigInteger getEndAddress()
+ {
+ String text = fEndText.getText();
+ boolean hex = text.startsWith("0x");
+ BigInteger endAddress = new BigInteger(hex ? text.substring(2) : text,
+ hex ? 16 : 10);
+
+ return endAddress;
+ }
+
+ public BigInteger getStartAddress()
+ {
+ String text = fStartText.getText();
+ boolean hex = text.startsWith("0x");
+ BigInteger startAddress = new BigInteger(hex ? text.substring(2) : text,
+ hex ? 16 : 10);
+
+ return startAddress;
+ }
+
+ public BigInteger getLength()
+ {
+ String text = fLengthText.getText();
+ boolean hex = text.startsWith("0x");
+ BigInteger lengthAddress = new BigInteger(hex ? text.substring(2) : text,
+ hex ? 16 : 10);
+
+ return lengthAddress;
+ }
+
+ public File getFile()
+ {
+ return new File(fFileText.getText());
+ }
+
+ private void validate()
+ {
+ boolean isValid = true;
+
+ try
+ {
+ getEndAddress();
+
+ getStartAddress();
+
+ BigInteger length = getLength();
+
+ if(length.compareTo(BigInteger.ZERO) <= 0)
+ isValid = false;
+
+ if(!getFile().getParentFile().exists())
+ isValid = false;
+ }
+ catch(Exception e)
+ {
+ isValid = false;
+ }
+
+ fParentDialog.setValid(isValid);
+ }
+
+
+ public String getId()
+ {
+ return "srecord";
+ }
+
+ public String getName()
+ {
+ return "SRecord";
+ }
+
+ public void exportMemory()
+ {
+ Job job = new Job("Memory Export to S-Record File"){ //$NON-NLS-1$
+ public IStatus run(IProgressMonitor monitor) {
+
+ try
+ {
+ try
+ {
+ // FIXME 4 byte default
+
+ BigInteger DATA_PER_RECORD = BigInteger.valueOf(16);
+
+ 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("Transferring Data", jobs.intValue());
+
+ 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);
+
+ writer.write("S3"); // FIXME 4 byte address
+
+ StringBuffer buf = new StringBuffer();
+
+ BigInteger sRecordLength = BigInteger.valueOf(4); // address size
+ sRecordLength = sRecordLength.add(length);
+ sRecordLength = sRecordLength.add(BigInteger.ONE); // checksum
+
+ String transferAddressString = transferAddress.toString(16);
+
+ String lengthString = sRecordLength.toString(16);
+ if(lengthString.length() == 1)
+ buf.append("0");
+ buf.append(lengthString);
+ for(int i = 0; i < 8 - transferAddressString.length(); i++)
+ buf.append("0");
+ buf.append(transferAddressString);
+
+ // data
+
+ MemoryByte bytes[] = ((IMemoryBlockExtension) fMemoryBlock).getBytesFromAddress(transferAddress,
+ length.longValue() / ((IMemoryBlockExtension) fMemoryBlock).getAddressableSize());
+ 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");
+ 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");
+ buf.append(bString);
+
+ writer.write(buf.toString().toUpperCase());
+ writer.write("\n");
+
+ 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(Exception e)
+ {
+ MemoryTransportPlugin.getDefault().getLog().log(new Status(IStatus.ERROR, MemoryTransportPlugin.getUniqueIdentifier(),
+ DebugException.INTERNAL_ERROR, "Failure", e));
+ }
+ }
+ catch(Exception e)
+ {
+ MemoryTransportPlugin.getDefault().getLog().log(new Status(IStatus.ERROR, MemoryTransportPlugin.getUniqueIdentifier(),
+ DebugException.INTERNAL_ERROR, "Failure", e));
+ }
+ return Status.OK_STATUS;
+ }};
+ job.setUser(true);
+ job.schedule();
+ }
+
+}
diff --git a/memory/org.eclipse.cdt.debug.ui.memory.transport/src/org/eclipse/cdt/debug/ui/memory/transport/SRecordImporter.java b/memory/org.eclipse.cdt.debug.ui.memory.transport/src/org/eclipse/cdt/debug/ui/memory/transport/SRecordImporter.java
new file mode 100644
index 00000000000..4a586c48d8d
--- /dev/null
+++ b/memory/org.eclipse.cdt.debug.ui.memory.transport/src/org/eclipse/cdt/debug/ui/memory/transport/SRecordImporter.java
@@ -0,0 +1,441 @@
+/*******************************************************************************
+ * Copyright (c) 2006-2009 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Ted R Williams (Wind River Systems, Inc.) - initial implementation
+ *******************************************************************************/
+
+package org.eclipse.cdt.debug.ui.memory.transport;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStreamReader;
+import java.math.BigInteger;
+import java.util.Properties;
+
+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.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.layout.FormLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+
+public class SRecordImporter implements IMemoryImporter {
+
+ File fInputFile;
+ BigInteger fStartAddress;
+ Boolean fScrollToStart;
+
+ private Text fStartText;
+ private Text fFileText;
+
+ private Button fComboRestoreToThisAddress;
+ private Button fComboRestoreToFileAddress;
+
+ private Button fScrollToBeginningOnImportComplete;
+
+ private IMemoryBlock fMemoryBlock;
+
+ private ImportMemoryDialog fParentDialog;
+
+ private Properties fProperties;
+
+ private static final int BUFFER_LENGTH = 64 * 1024;
+
+ public Control createControl(final Composite parent, IMemoryBlock memBlock, Properties properties, ImportMemoryDialog parentDialog)
+ {
+ fMemoryBlock = memBlock;
+ fParentDialog = parentDialog;
+ fProperties = properties;
+
+ Composite composite = new Composite(parent, SWT.NONE)
+ {
+ public void dispose()
+ {
+ fProperties.setProperty(TRANSFER_FILE, fFileText.getText());
+ fProperties.setProperty(TRANSFER_START, fStartText.getText());
+ fProperties.setProperty(TRANSFER_SCROLL_TO_START, fScrollToStart.toString());
+ fProperties.setProperty(TRANSFER_CUSTOM_START_ADDRESS, "" + fComboRestoreToThisAddress.getSelection());
+
+ fStartAddress = getStartAddress();
+ fInputFile = getFile();
+
+ super.dispose();
+ }
+ };
+ FormLayout formLayout = new FormLayout();
+ formLayout.spacing = 5;
+ formLayout.marginWidth = formLayout.marginHeight = 9;
+ composite.setLayout(formLayout);
+
+ // restore to file address
+
+ fComboRestoreToFileAddress = new Button(composite, SWT.RADIO);
+ fComboRestoreToFileAddress.setSelection(true);
+ fComboRestoreToFileAddress.setText("Restore to address specified in the file");
+ fComboRestoreToFileAddress.setSelection(!new Boolean(properties.getProperty(TRANSFER_CUSTOM_START_ADDRESS, "false")).booleanValue());
+ //comboRestoreToFileAddress.setLayoutData(data);
+
+ // restore to this address
+
+ fComboRestoreToThisAddress = new Button(composite, SWT.RADIO);
+ fComboRestoreToThisAddress.setText("Restore to this address: ");
+ fComboRestoreToThisAddress.setSelection(new Boolean(properties.getProperty(TRANSFER_CUSTOM_START_ADDRESS, "false")).booleanValue());
+ FormData data = new FormData();
+ data.top = new FormAttachment(fComboRestoreToFileAddress);
+ fComboRestoreToThisAddress.setLayoutData(data);
+
+ fStartText = new Text(composite, SWT.NONE);
+ data = new FormData();
+ data.top = new FormAttachment(fComboRestoreToFileAddress);
+ data.left = new FormAttachment(fComboRestoreToThisAddress);
+ data.width = 100;
+ fStartText.setLayoutData(data);
+
+ fComboRestoreToFileAddress.addSelectionListener(new SelectionListener() {
+
+ public void widgetDefaultSelected(SelectionEvent e) {}
+
+ public void widgetSelected(SelectionEvent e) {
+ validate();
+ }
+ });
+
+ fComboRestoreToThisAddress.addSelectionListener(new SelectionListener() {
+
+ public void widgetDefaultSelected(SelectionEvent e) {}
+
+ public void widgetSelected(SelectionEvent e) {
+ validate();
+ }
+ });
+
+ // file
+
+ Label fileLabel = new Label(composite, SWT.NONE);
+ fFileText = new Text(composite, SWT.NONE);
+ Button fileButton = new Button(composite, SWT.PUSH);
+
+ fileLabel.setText("File name: ");
+ data = new FormData();
+ data.top = new FormAttachment(fileButton, 0, SWT.CENTER);
+ fileLabel.setLayoutData(data);
+
+ data = new FormData();
+ data.top = new FormAttachment(fileButton, 0, SWT.CENTER);
+ data.left = new FormAttachment(fileLabel);
+ data.width = 300;
+ fFileText.setLayoutData(data);
+
+ fileButton.setText("Browse...");
+ data = new FormData();
+ data.top = new FormAttachment(fStartText);
+ data.left = new FormAttachment(fFileText);
+ fileButton.setLayoutData(data);
+
+ fFileText.setText(properties.getProperty(TRANSFER_FILE, ""));
+ fScrollToStart = new Boolean(properties.getProperty(TRANSFER_SCROLL_TO_START, "true"));
+ try
+ {
+ BigInteger startAddress = null;
+ if(fMemoryBlock instanceof IMemoryBlockExtension)
+ startAddress = ((IMemoryBlockExtension) fMemoryBlock)
+ .getBigBaseAddress(); // FIXME use selection/caret address?
+ else
+ startAddress = BigInteger.valueOf(fMemoryBlock.getStartAddress());
+
+ if(properties.getProperty(TRANSFER_START) != null)
+ fStartText.setText(properties.getProperty(TRANSFER_START));
+ else
+ fStartText.setText("0x" + startAddress.toString(16));
+
+ }
+ catch(Exception e)
+ {
+ MemoryTransportPlugin.getDefault().getLog().log(new Status(IStatus.ERROR, MemoryTransportPlugin.getUniqueIdentifier(),
+ DebugException.INTERNAL_ERROR, "Failure", e));
+ }
+
+ fileButton.addSelectionListener(new SelectionListener() {
+
+ public void widgetDefaultSelected(SelectionEvent e) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void widgetSelected(SelectionEvent e) {
+ FileDialog dialog = new FileDialog(parent.getShell(), SWT.SAVE);
+ dialog.setText("Choose memory import file");
+ dialog.setFilterExtensions(new String[] { "*.*;*" } );
+ dialog.setFilterNames(new String[] { "All Files" } );
+ dialog.setFileName(fFileText.getText());
+ dialog.open();
+
+ String filename = dialog.getFileName();
+ if(filename != null && filename.length() != 0 )
+ {
+ fFileText.setText(dialog.getFilterPath() + File.separator + filename);
+ }
+
+ validate();
+ }
+
+ });
+
+ fStartText.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ boolean valid = true;
+ try
+ {
+ getStartAddress();
+ }
+ catch(Exception ex)
+ {
+ valid = false;
+ }
+
+ fStartText.setForeground(valid ? Display.getDefault().getSystemColor(SWT.COLOR_BLACK) :
+ Display.getDefault().getSystemColor(SWT.COLOR_RED));
+
+ //
+
+ validate();
+ }
+
+ });
+ fFileText.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ validate();
+ }
+ });
+
+ fScrollToBeginningOnImportComplete = new Button(composite, SWT.CHECK);
+ fScrollToBeginningOnImportComplete.setText("Scroll to File Start Address");
+ data = new FormData();
+ data.top = new FormAttachment(fileButton);
+ fScrollToBeginningOnImportComplete.setLayoutData(data);
+
+ composite.pack();
+ parent.pack();
+
+ Display.getDefault().asyncExec(new Runnable(){
+ public void run()
+ {
+ validate();
+ }
+ });
+
+ return composite;
+ }
+
+ private void validate()
+ {
+ boolean isValid = true;
+
+ try
+ {
+ boolean restoreToAddress = fComboRestoreToThisAddress.getSelection();
+ if ( restoreToAddress ) {
+ getStartAddress();
+ }
+
+ boolean restoreToAddressFromFile = fComboRestoreToFileAddress.getSelection();
+ if ( restoreToAddressFromFile ) {
+ if(!getFile().exists()) {
+ isValid = false;
+ }
+ }
+ }
+ catch(Exception e)
+ {
+ isValid = false;
+ }
+
+ fParentDialog.setValid(isValid);
+ }
+
+ public boolean getScrollToStart()
+ {
+ return fScrollToBeginningOnImportComplete.getSelection();
+ }
+
+ public BigInteger getStartAddress()
+ {
+ String text = fStartText.getText();
+ boolean hex = text.startsWith("0x");
+ BigInteger startAddress = new BigInteger(hex ? text.substring(2) : text,
+ hex ? 16 : 10);
+
+ return startAddress;
+ }
+
+ public File getFile()
+ {
+ return new File(fFileText.getText());
+ }
+
+ public String getId()
+ {
+ return "srecord";
+ }
+
+ public String getName()
+ {
+ return "SRecord";
+ }
+
+ public void importMemory() {
+ Job job = new Job("Memory Import from S-Record File"){ //$NON-NLS-1$
+
+ public IStatus run(IProgressMonitor monitor) {
+
+ try
+ {
+ 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.getProperty(TRANSFER_CUSTOM_START_ADDRESS, "false").equals("true"))
+ 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("Transferring Data", jobs.intValue()); //$NON-NLS-1$
+
+ BigInteger jobCount = BigInteger.ZERO;
+ String line = reader.readLine();
+ while(line != null && !monitor.isCanceled())
+ {
+ String recordType = line.substring(0, 2);
+ int recordCount = Integer.parseInt(line.substring(2, 4), 16);
+ 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;
+
+ recordAddress = new BigInteger(line.substring(position, position + addressSize * 2), 16);
+ 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++)
+ {
+ data[i] = new BigInteger(line.substring(position++, position++ + 1), 16).byteValue();
+ }
+
+ /*
+ * 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.
+ */
+ StringBuffer buf = new StringBuffer(line.substring(2));
+ 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();
+ }
+
+ /*
+ * 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(), "Checksum failure of line = " + line); //$NON-NLS-1$
+ }
+
+ if(scrollToAddress == null)
+ scrollToAddress = recordAddress;
+
+ // FIXME error on incorrect checksum
+
+ memoryWriter.write(recordAddress.subtract(((IMemoryBlockExtension) fMemoryBlock).getBigBaseAddress()), data);
+
+ jobCount = jobCount.add(BigInteger.valueOf(bytesRead));
+ while(jobCount.compareTo(factor) >= 0)
+ {
+ jobCount = jobCount.subtract(factor);
+ monitor.worked(1);
+ }
+
+ line = reader.readLine();
+ }
+
+ memoryWriter.flush();
+ reader.close();
+ monitor.done();
+
+ if(fProperties.getProperty(TRANSFER_SCROLL_TO_START, "false").equals("true"))
+ fParentDialog.scrollRenderings(scrollToAddress);
+ }
+ catch(Exception e)
+ {
+ MemoryTransportPlugin.getDefault().getLog().log(new Status(IStatus.ERROR, MemoryTransportPlugin.getUniqueIdentifier(),
+ DebugException.INTERNAL_ERROR, "Failure", e));
+ }
+ }
+ catch(Exception e)
+ {
+ MemoryTransportPlugin.getDefault().getLog().log(new Status(IStatus.ERROR, MemoryTransportPlugin.getUniqueIdentifier(),
+ DebugException.INTERNAL_ERROR, "Failure", e));
+ }
+ return Status.OK_STATUS;
+ }};
+ job.setUser(true);
+ job.schedule();
+ }
+}
diff --git a/memory/org.eclipse.cdt.debug.ui.memory.transport/src/org/eclipse/cdt/debug/ui/memory/transport/actions/ExportMemoryAction.java b/memory/org.eclipse.cdt.debug.ui.memory.transport/src/org/eclipse/cdt/debug/ui/memory/transport/actions/ExportMemoryAction.java
new file mode 100644
index 00000000000..e722e9a906a
--- /dev/null
+++ b/memory/org.eclipse.cdt.debug.ui.memory.transport/src/org/eclipse/cdt/debug/ui/memory/transport/actions/ExportMemoryAction.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (c) 2006-2009 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Ted R Williams (Wind River Systems, Inc.) - initial implementation
+ *******************************************************************************/
+
+package org.eclipse.cdt.debug.ui.memory.transport.actions;
+
+import org.eclipse.cdt.debug.ui.memory.transport.ExportMemoryDialog;
+import org.eclipse.cdt.debug.ui.memory.transport.MemoryTransportPlugin;
+import org.eclipse.debug.core.model.IMemoryBlock;
+import org.eclipse.debug.internal.ui.views.memory.MemoryView;
+import org.eclipse.debug.ui.memory.IMemoryRendering;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.ui.IViewActionDelegate;
+import org.eclipse.ui.IViewPart;
+
+/**
+ * Action for exporting memory.
+ */
+public class ExportMemoryAction implements IViewActionDelegate {
+
+ private MemoryView fView;
+
+ public void init(IViewPart view) {
+ if (view instanceof MemoryView)
+ fView = (MemoryView) view;
+ }
+
+ private IMemoryBlock getMemoryBlock(ISelection selection)
+ {
+ IMemoryBlock memBlock = null;
+
+ if (selection instanceof IStructuredSelection) {
+ IStructuredSelection strucSel = (IStructuredSelection) selection;
+
+ // return if current selection is empty
+ if (strucSel.isEmpty())
+ return null;
+
+ Object obj = strucSel.getFirstElement();
+
+ if (obj == null)
+ return null;
+
+ if (obj instanceof IMemoryRendering) {
+ memBlock = ((IMemoryRendering) obj).getMemoryBlock();
+ } else if (obj instanceof IMemoryBlock) {
+ memBlock = (IMemoryBlock) obj;
+ }
+ }
+ return memBlock;
+ }
+
+ public void run(IAction action) {
+
+ ISelection selection = fView.getSite().getSelectionProvider()
+ .getSelection();
+ IMemoryBlock memBlock = getMemoryBlock(selection);
+ if(memBlock == null)
+ return;
+ ExportMemoryDialog dialog = new ExportMemoryDialog(MemoryTransportPlugin.getShell(), memBlock);
+ dialog.open();
+
+ dialog.getResult();
+ }
+
+ public void selectionChanged(IAction action, ISelection selection) {
+ action.setEnabled(getMemoryBlock(selection) != null);
+ }
+
+}
diff --git a/memory/org.eclipse.cdt.debug.ui.memory.transport/src/org/eclipse/cdt/debug/ui/memory/transport/actions/ImportMemoryAction.java b/memory/org.eclipse.cdt.debug.ui.memory.transport/src/org/eclipse/cdt/debug/ui/memory/transport/actions/ImportMemoryAction.java
new file mode 100644
index 00000000000..37f81921ae4
--- /dev/null
+++ b/memory/org.eclipse.cdt.debug.ui.memory.transport/src/org/eclipse/cdt/debug/ui/memory/transport/actions/ImportMemoryAction.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * Copyright (c) 2006-2009 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Ted R Williams (Wind River Systems, Inc.) - initial implementation
+ *******************************************************************************/
+
+package org.eclipse.cdt.debug.ui.memory.transport.actions;
+
+import org.eclipse.cdt.debug.ui.memory.transport.ImportMemoryDialog;
+import org.eclipse.cdt.debug.ui.memory.transport.MemoryTransportPlugin;
+import org.eclipse.debug.core.model.IMemoryBlock;
+import org.eclipse.debug.internal.ui.views.memory.MemoryView;
+import org.eclipse.debug.ui.memory.IMemoryRendering;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.ui.IViewActionDelegate;
+import org.eclipse.ui.IViewPart;
+
+/**
+ * Action for downloading memory.
+ */
+public class ImportMemoryAction implements IViewActionDelegate {
+
+
+ private MemoryView fView;
+
+ public void init(IViewPart view) {
+ if (view instanceof MemoryView)
+ fView = (MemoryView) view;
+
+// IDebugContextService debugContextService = DebugUITools.getDebugContextManager().getContextService(view.getSite().getWorkbenchWindow());
+// this.
+// debugContextService.getActiveContext();
+ }
+
+ private IMemoryBlock getMemoryBlock(ISelection selection)
+ {
+ IMemoryBlock memBlock = null;
+
+ if (selection instanceof IStructuredSelection) {
+ IStructuredSelection strucSel = (IStructuredSelection) selection;
+
+ // return if current selection is empty
+ if (strucSel.isEmpty())
+ return null;
+
+ Object obj = strucSel.getFirstElement();
+
+ if (obj == null)
+ return null;
+
+ if (obj instanceof IMemoryRendering) {
+ memBlock = ((IMemoryRendering) obj).getMemoryBlock();
+ } else if (obj instanceof IMemoryBlock) {
+ memBlock = (IMemoryBlock) obj;
+ }
+ }
+ return memBlock;
+ }
+
+ public void run(IAction action) {
+
+ ISelection selection = fView.getSite().getSelectionProvider()
+ .getSelection();
+ IMemoryBlock memBlock = getMemoryBlock(selection);
+ if(memBlock == null)
+ return;
+
+ ImportMemoryDialog dialog = new ImportMemoryDialog(MemoryTransportPlugin.getShell(), memBlock, fView);
+ dialog.open();
+
+ dialog.getResult();
+ }
+
+ public void selectionChanged(IAction action, ISelection selection) {
+ action.setEnabled(getMemoryBlock(selection) != null);
+ }
+
+}
diff --git a/memory/org.eclipse.cdt.debug.ui.memory.transport/src/org/eclipse/cdt/debug/ui/memory/transport/messages.properties b/memory/org.eclipse.cdt.debug.ui.memory.transport/src/org/eclipse/cdt/debug/ui/memory/transport/messages.properties
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/memory/org.eclipse.cdt.debug.ui.memory.transport/src/org/eclipse/cdt/debug/ui/memory/transport/model/IMemoryExporter.java b/memory/org.eclipse.cdt.debug.ui.memory.transport/src/org/eclipse/cdt/debug/ui/memory/transport/model/IMemoryExporter.java
new file mode 100644
index 00000000000..d90853b8fce
--- /dev/null
+++ b/memory/org.eclipse.cdt.debug.ui.memory.transport/src/org/eclipse/cdt/debug/ui/memory/transport/model/IMemoryExporter.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2006-2009 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Ted R Williams (Wind River Systems, Inc.) - initial implementation
+ *******************************************************************************/
+
+package org.eclipse.cdt.debug.ui.memory.transport.model;
+
+import java.util.Properties;
+
+import org.eclipse.cdt.debug.ui.memory.transport.ExportMemoryDialog;
+import org.eclipse.debug.core.model.IMemoryBlock;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+
+public interface IMemoryExporter
+{
+ public static final String TRANSFER_FILE = "File";
+ public static final String TRANSFER_START = "Start";
+ public static final String TRANSFER_END = "End";
+
+ public Control createControl(Composite parent, IMemoryBlock memBlock, Properties properties, ExportMemoryDialog parentDialog);
+
+ public void exportMemory();
+
+ public String getId();
+
+ public String getName();
+}
diff --git a/memory/org.eclipse.cdt.debug.ui.memory.transport/src/org/eclipse/cdt/debug/ui/memory/transport/model/IMemoryImporter.java b/memory/org.eclipse.cdt.debug.ui.memory.transport/src/org/eclipse/cdt/debug/ui/memory/transport/model/IMemoryImporter.java
new file mode 100644
index 00000000000..5defe42fc6e
--- /dev/null
+++ b/memory/org.eclipse.cdt.debug.ui.memory.transport/src/org/eclipse/cdt/debug/ui/memory/transport/model/IMemoryImporter.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2006-2009 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Ted R Williams (Wind River Systems, Inc.) - initial implementation
+ *******************************************************************************/
+
+package org.eclipse.cdt.debug.ui.memory.transport.model;
+
+import java.util.Properties;
+
+import org.eclipse.cdt.debug.ui.memory.transport.ImportMemoryDialog;
+import org.eclipse.debug.core.model.IMemoryBlock;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+
+public interface IMemoryImporter
+{
+ public static final String TRANSFER_FILE = "File";
+ public static final String TRANSFER_START = "Start";
+ public static final String TRANSFER_END = "End";
+ public static final String TRANSFER_CUSTOM_START_ADDRESS = "CustomStartAddress";
+ public static final String TRANSFER_SCROLL_TO_START = "ScrollToStart";
+
+ public Control createControl(Composite parent, IMemoryBlock memBlock, Properties properties, ImportMemoryDialog parentDialog);
+
+ public void importMemory();
+
+ public String getId();
+
+ public String getName();
+}