1 11 12 package org.eclipse.debug.internal.ui.views.memory.renderings; 13 14 import java.math.BigInteger ; 15 16 import org.eclipse.core.runtime.IProgressMonitor; 17 import org.eclipse.core.runtime.IStatus; 18 import org.eclipse.core.runtime.Status; 19 import org.eclipse.core.runtime.jobs.Job; 20 import org.eclipse.debug.core.DebugException; 21 import org.eclipse.debug.core.model.IMemoryBlock; 22 import org.eclipse.debug.core.model.IMemoryBlockExtension; 23 import org.eclipse.debug.core.model.MemoryByte; 24 import org.eclipse.debug.internal.ui.DebugUIMessages; 25 import org.eclipse.debug.internal.ui.DebugUIPlugin; 26 import org.eclipse.debug.internal.ui.memory.provisional.AbstractAsyncTableRendering; 27 import org.eclipse.debug.internal.ui.views.memory.MemoryViewUtil; 28 import org.eclipse.debug.ui.memory.MemoryRenderingElement; 29 import org.eclipse.jface.viewers.ICellModifier; 30 import org.eclipse.swt.widgets.TableItem; 31 32 36 public class AsyncTableRenderingCellModifier implements ICellModifier { 39 40 private AbstractAsyncTableRendering fRendering; 41 private boolean fMBSupportsValueModification = false; 42 43 private ICellModifier fCustomModifier; 44 45 public AsyncTableRenderingCellModifier(AbstractAsyncTableRendering rendering, ICellModifier customModifier) { 46 fRendering = rendering; 47 fCustomModifier = customModifier; 48 49 Job job = new Job("AsyncTableRenderingCellModifier"){ 51 protected IStatus run(IProgressMonitor monitor) { 52 fMBSupportsValueModification = fRendering.getMemoryBlock().supportsValueModification(); 53 return Status.OK_STATUS; 54 }}; 55 job.setSystem(true); 56 job.schedule(); 57 } 58 59 65 public boolean canModify(Object element, String property) { 66 boolean canModify = true; 67 try { 68 if (!(element instanceof MemorySegment)) 69 return false; 70 71 if (!isValueModificationSupported()) { 72 return false; 73 } 74 75 MemorySegment line = (MemorySegment) element; 76 if (TableRenderingLine.P_ADDRESS.equals(property)) { 77 return false; 78 } 79 80 int addressableSize = getAddressableSize(); 85 86 int offset = Integer.valueOf(property, 16).intValue() * addressableSize; 87 88 MemoryByte[] bytes = line.getBytes(offset, fRendering.getBytesPerColumn()); 89 90 if (fCustomModifier != null) 91 { 92 BigInteger address = line.getAddress().add(BigInteger.valueOf(offset)); 93 MemoryRenderingElement mElement = new MemoryRenderingElement(fRendering, address, bytes); 94 return fCustomModifier.canModify(mElement, null); 95 } 96 97 for (int i = 0; i < bytes.length; i++) { 98 if (!bytes[i].isWritable()) { 99 canModify = false; 100 } 101 } 102 return canModify; 103 } catch (NumberFormatException e) { 104 canModify = false; 105 return canModify; 106 } 107 } 108 109 112 private int getAddressableSize() { 113 int addressableSize = fRendering.getAddressableSize(); 114 if (addressableSize < 1) 115 addressableSize = 1; 116 return addressableSize; 117 } 118 119 125 public Object getValue(Object element, String property) { 126 127 129 if (!(element instanceof MemorySegment)) 130 return null; 131 132 MemorySegment line = (MemorySegment) element; 133 try { 134 if (TableRenderingLine.P_ADDRESS.equals(property)) 135 return line.getAddress(); 136 137 int offsetToLineBuffer = Integer.valueOf(property, 16).intValue() * getAddressableSize(); 138 MemoryByte[] memory = line.getBytes(offsetToLineBuffer, fRendering.getBytesPerColumn()); 139 140 int offsetFromLineAddress = Integer.valueOf(property, 16).intValue(); 141 BigInteger address = line.getAddress().add(BigInteger.valueOf(offsetFromLineAddress)); 142 143 if (fCustomModifier != null) 144 { 145 MemoryRenderingElement mElement = new MemoryRenderingElement(fRendering, address, memory); 146 return fCustomModifier.getValue(mElement, null); 147 } 148 149 return fRendering.getString(fRendering.getRenderingId(), address, memory); 151 152 } catch (NumberFormatException e) { 153 return "00"; } 155 } 156 157 163 public void modify(Object element, final String property, final Object value) { 164 165 MemorySegment segment = null; 166 if (element instanceof TableItem) { 167 Object data = ((TableItem)element).getData(); 168 if (data != null && data instanceof MemorySegment) 169 segment = (MemorySegment)data; 170 171 } else if (element instanceof MemorySegment){ 172 segment = (MemorySegment) element; 173 } 174 175 if (segment == null) 176 return; 177 178 final MemorySegment line = segment; 179 180 Job job = new Job("Set Values"){ 182 protected IStatus run(IProgressMonitor monitor) { 183 try { 184 final IMemoryBlock memoryBlk = fRendering.getMemoryBlock(); 186 187 int offsetFromLineAddress = Integer.valueOf(property, 16).intValue(); 189 190 final BigInteger offsetFromMBBase = getOffset(memoryBlk, line.getAddress(), offsetFromLineAddress); 192 193 int offsetToLineBuffer = Integer.valueOf(property, 16).intValue() * getAddressableSize(); 197 198 MemoryByte[] oldArray = line.getBytes(offsetToLineBuffer, fRendering.getBytesPerColumn()); 199 200 BigInteger address = line.getAddress(); 202 address = address.add(BigInteger.valueOf(offsetFromLineAddress)); 203 204 if (fCustomModifier != null) { 205 MemoryRenderingElement mElement = new MemoryRenderingElement(fRendering, address, oldArray); 206 fCustomModifier.modify(mElement, null, value); 207 return Status.OK_STATUS; 208 } 209 210 if (!(value instanceof String )) 211 { 212 DebugUIPlugin.logErrorMessage("Cell modifier cannot handle non-string values."); return Status.OK_STATUS; 214 } 215 216 byte[] bytes = null; 217 String oldValue = (String ) getValue(line, property); 218 if (!oldValue.equals(value)) { 219 bytes = fRendering.getBytes(fRendering.getRenderingId(), address, oldArray, (String ) value); 220 221 if (bytes == null) 222 return Status.OK_STATUS; 223 224 if (bytes.length == 0) 225 return Status.OK_STATUS; 226 227 if (bytes.length <= oldArray.length) { 228 boolean changed = false; 229 for (int i = 0; i < bytes.length; i++) { 231 if (bytes[i] != oldArray[i].getValue()) { 232 changed = true; 233 break; 234 } 235 } 236 if (!changed) 237 return Status.OK_STATUS; 238 } 239 } else { 240 return Status.OK_STATUS; 242 } 243 244 final byte[] newByteValues = bytes; 245 246 if (memoryBlk instanceof IMemoryBlockExtension) 247 ((IMemoryBlockExtension) memoryBlk).setValue(offsetFromMBBase, newByteValues); 248 else 249 memoryBlk.setValue(offsetFromMBBase.longValue(), newByteValues); 250 } catch (DebugException e) { 251 MemoryViewUtil.openError(DebugUIMessages.MemoryViewCellModifier_failure_title, DebugUIMessages.MemoryViewCellModifier_failed, e); 252 } catch (NumberFormatException e) { 253 MemoryViewUtil.openError(DebugUIMessages.MemoryViewCellModifier_failure_title, DebugUIMessages.MemoryViewCellModifier_failed + "\n" + DebugUIMessages.MemoryViewCellModifier_data_is_invalid, null); } 255 return Status.OK_STATUS; 256 }}; 257 258 job.setSystem(true); 259 job.schedule(); 260 } 261 262 private BigInteger getOffset(IMemoryBlock memory, BigInteger lineAddress, int lineOffset) throws DebugException { 263 264 BigInteger memoryAddr; 265 266 if (memory instanceof IMemoryBlockExtension) { 267 memoryAddr = ((IMemoryBlockExtension) memory).getBigBaseAddress(); 268 } else { 269 memoryAddr = BigInteger.valueOf(memory.getStartAddress()); 270 } 271 272 if (memoryAddr == null) 273 memoryAddr = new BigInteger ("0"); 275 return lineAddress.subtract(memoryAddr).add(BigInteger.valueOf(lineOffset)); 276 } 277 278 private boolean isValueModificationSupported() 279 { 280 return fMBSupportsValueModification; 281 } 282 283 } 284 | Popular Tags |