blob: 7e9b73f5ac87a6c15e8b10fb574eb0321da4a938 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2010 Nokia 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:
* Nokia - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.debug.edc.tcf.extension;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import org.eclipse.tm.tcf.services.IMemory.ErrorOffset;
/**
* This exception class provides the agent with a container that closely mirrors what will end up in a
* <code>org.eclipse.tm.internal.tcf.services.remote.MemoryProxy.MemoryErrorReport</code>
* containing a list of <code>MemoryProxy.Range</code> objects on the other side of a TCF channel.
* <p>
* To mimic <code>MemoryProxy.Range</code>, this object holds an <code>ArrayList</code>
* of {@link PartialMemoryBlock} objects.
* <p>
* An exception is used because the memory block decorated with multiple status
* values for internally segmented sections of the block is considered the exceptional
* case, and may need to be thrown up the chain to get around conventional parameter
* and return values.
*
* @author kirk.beitz@nokia.com
* @since 2.0
*/
public class MemoryBlockMultiStatusException extends AgentException {
private static final long serialVersionUID = -5403275982691807261L;
/**
* the list mirroring the list of
* <code>
* org.eclipse.tm.internal.tcf.services.remote.MemoryProxy.Range
* </code>
* objects on the other side of the TCF channel.
*/
private final ArrayList<PartialMemoryBlock> pbList;
/**
* the byte buffer of data representing the memory being decorated
* with multiple status values
*/
private final ByteBuffer buf;
/**
* version of constructor allowing an already partially filled
* buffer to append the <code>PartialMemoryBlock</code> list from
* another <code>MemoryBlockMultiStatusException</code>.
* <p>
* Primary use case is expected to be a low-level memory read that
* returned fewer bytes than expected, resulting in only exception
* status for the end portion of the block of memory being read.
*
* @param msg the original problem to associate with the whole exception
* @param block the block of memory to associate with the whole exception
* @param m exception from which to extract the additional PartialMemoryBlock list
*/
public MemoryBlockMultiStatusException(String msg,
ByteBuffer block, MemoryBlockMultiStatusException m) {
super(msg);
buf = block;
pbList = (m != null) ? m.getPartialBLocks() : null;
}
/**
* version of constructor combining the information from two other
* MemoryBlockMultiStatusException exceptions into a single exception.
* <p>
* primary use case is expected to be a low-level memory read that
* fails and splits the read into smaller chunks to determine if a
* different status should decorate segments within the full block
*
* @param msg the original problem to associate with thewhole exception
* @param fullBlock the block of memory to associate with the whole exception
* @param m1 the first of two exceptions to combine
* @param m2 the second of two exceptions to combine
*/
public MemoryBlockMultiStatusException(String msg, ByteBuffer fullBlock,
MemoryBlockMultiStatusException m1, MemoryBlockMultiStatusException m2) {
super(msg);
buf = fullBlock;
if (m1 != null) {
pbList = m1.getPartialBLocks();
if (m2 != null && m2.getPartialBLocks() != null) {
pbList.addAll(m2.getPartialBLocks());
}
} else if (m2 != null) {
pbList = m2.getPartialBLocks();
} else {
pbList = null;
}
}
/**
* seminal version of the constructor, containing a block of memory
* that could not be processed, and creating a single status to
* associate with the entire passed block.
* <p>
* primary use cases are expected to be a low-level memory read that
* fails in a way in which it is known that the entire block has a
* single status, often whereby the block is then to be combined with
* other <code>PartialMemoryBlocks</code> to create a
* <code>MemoryBlockMultiStatusException</code>
* that represents a bigger block containing the block passed to
* this constructor.
* @param block empty block (often expected to be a slice of a bigger block)
* @param addr target memory address location of the block
* @param size size of the block being described
*/
public MemoryBlockMultiStatusException(ByteBuffer block, int addr, int size) {
super((String)null);
buf = block;
buf.put((byte)0xBE);
pbList = new ArrayList<PartialMemoryBlock>(1);
pbList.add(new PartialMemoryBlock(addr, size, ErrorOffset.BYTE_INVALID));
}
/**
* access this exception's list of descriptors
* that mirrors the <code>MemoryProxy.Range</code> created in
* <code>
* org.eclipse.tm.internal.tcf.services.remote.MemoryProxy.MemoryErrorReport
* </code>
* from data returned from the TCF agent for a MemoryService#getMemory() call.
*
* @return the list of block descriptors
*/
public ArrayList<PartialMemoryBlock> getPartialBLocks() {
return pbList;
}
/**
* access this exception's buffer representing the memory data
* read (as well as sections that may contain unknown content
* for <code>PartialMemoryBlock</code> objects that have status
* but no associated memory data).
* @return the block of memory data held by this exception
*/
public ByteBuffer getBuf() {
return buf;
}
}