/*******************************************************************************
* Copyright (c) 2000, 2006 QNX Software Systems 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:
* QNX Software Systems - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.debug.mi.core.cdi;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import org.eclipse.cdt.debug.core.cdi.CDIException;
import org.eclipse.cdt.debug.core.cdi.model.ICDISignal;
import org.eclipse.cdt.debug.mi.core.MIException;
import org.eclipse.cdt.debug.mi.core.MISession;
import org.eclipse.cdt.debug.mi.core.RxThread;
import org.eclipse.cdt.debug.mi.core.cdi.model.Signal;
import org.eclipse.cdt.debug.mi.core.cdi.model.Target;
import org.eclipse.cdt.debug.mi.core.command.CommandFactory;
import org.eclipse.cdt.debug.mi.core.command.CLIHandle;
import org.eclipse.cdt.debug.mi.core.command.CLIInfoSignals;
import org.eclipse.cdt.debug.mi.core.event.MIEvent;
import org.eclipse.cdt.debug.mi.core.event.MISignalChangedEvent;
import org.eclipse.cdt.debug.mi.core.output.CLIInfoSignalsInfo;
import org.eclipse.cdt.debug.mi.core.output.MISigHandle;
/**
*/
public class SignalManager extends Manager {
ICDISignal[] EMPTY_SIGNALS = {};
MISigHandle[] noSigs = new MISigHandle[0];
Map signalsMap;
public SignalManager(Session session) {
super(session, false);
signalsMap = new Hashtable();
}
synchronized List getSignalsList(Target target) {
List signalsList = (List)signalsMap.get(target);
if (signalsList == null) {
signalsList = Collections.synchronizedList(new ArrayList());
signalsMap.put(target, signalsList);
}
return signalsList;
}
MISigHandle[] getMISignals(MISession miSession) throws CDIException {
MISigHandle[] miSigs;
CommandFactory factory = miSession.getCommandFactory();
CLIInfoSignals sigs = factory.createCLIInfoSignals();
try {
RxThread rxThread = miSession.getRxThread();
rxThread.setEnableConsole(false);
miSession.postCommand(sigs);
CLIInfoSignalsInfo info = sigs.getMIInfoSignalsInfo();
if (info == null) {
throw new CDIException(CdiResources.getString("cdi.Common.No_answer")); //$NON-NLS-1$
}
miSigs = info.getMISignals();
} catch (MIException e) {
throw new MI2CDIException(e);
} finally {
RxThread rxThread = miSession.getRxThread();
rxThread.setEnableConsole(true);
}
return miSigs;
}
MISigHandle getMISignal(MISession miSession, String name) throws CDIException {
MISigHandle sig = null;
CommandFactory factory = miSession.getCommandFactory();
CLIInfoSignals sigs = factory.createCLIInfoSignals(name);
try {
RxThread rxThread = miSession.getRxThread();
rxThread.setEnableConsole(false);
miSession.postCommand(sigs);
CLIInfoSignalsInfo info = sigs.getMIInfoSignalsInfo();
if (info == null) {
throw new CDIException(CdiResources.getString("cdi.Common.No_answer")); //$NON-NLS-1$
}
MISigHandle[] miSigs = info.getMISignals();
if (miSigs.length > 0) {
sig = miSigs[0];
}
} catch (MIException e) {
throw new MI2CDIException(e);
} finally {
RxThread rxThread = miSession.getRxThread();
rxThread.setEnableConsole(true);
}
return sig;
}
/**
* Method hasSignalChanged.
* @param sig
* @param mISignal
* @return boolean
*/
private boolean hasSignalChanged(ICDISignal sig, MISigHandle miSignal) {
return !sig.getName().equals(miSignal.getName()) ||
sig.isStopSet() != miSignal.isStop() ||
sig.isIgnore() != !miSignal.isPass();
}
protected ICDISignal findSignal(Target target, String name) {
ICDISignal sig = null;
List signalsList = (List) signalsMap.get(target);
if (signalsList != null) {
ICDISignal[] sigs = (ICDISignal[])signalsList.toArray(new ICDISignal[0]);
for (int i = 0; i < sigs.length; i++) {
if (sigs[i].getName().equals(name)) {
sig = sigs[i];
break;
}
}
}
return sig;
}
public ICDISignal getSignal(MISession miSession, String name) {
Session session = (Session)getSession();
Target target = session.getTarget(miSession);
return getSignal(target, name);
}
public ICDISignal getSignal(Target target, String name) {
ICDISignal sig = findSignal(target, name);
if (sig == null) {
MISigHandle miSig = null;
try {
miSig = getMISignal(target.getMISession(), name);
sig = new Signal(target, miSig);
List signalsList = getSignalsList(target);
signalsList.add(sig);
} catch (CDIException e) {
// The session maybe terminated because of the signal.
miSig = new MISigHandle(name, false, false, false, name);
sig = new Signal(target, miSig);
}
}
return sig;
}
public void handle(Signal sig, boolean isIgnore, boolean isStop) throws CDIException {
Target target = (Target)sig.getTarget();
MISession miSession = target.getMISession();
CommandFactory factory = miSession.getCommandFactory();
StringBuffer buffer = new StringBuffer(sig.getName());
buffer.append(" "); //$NON-NLS-1$
if (isIgnore) {
buffer.append("ignore"); //$NON-NLS-1$
} else {
buffer.append("noignore"); //$NON-NLS-1$
}
buffer.append(" "); //$NON-NLS-1$
if (isStop) {
buffer.append("stop"); //$NON-NLS-1$
} else {
buffer.append("nostop"); //$NON-NLS-1$
}
CLIHandle handle = factory.createCLIHandle(buffer.toString());
try {
miSession.postCommand(handle);
handle.getMIInfo();
} catch (MIException e) {
throw new MI2CDIException(e);
}
sig.getMISignal().handle(isIgnore, isStop);
miSession.fireEvent(new MISignalChangedEvent(miSession, sig.getName()));
}
public ICDISignal[] getSignals(Target target) throws CDIException {
List signalsList = (List)signalsMap.get(target);
if (signalsList == null) {
update(target);
}
signalsList = (List)signalsMap.get(target);
if (signalsList != null) {
return (ICDISignal[])signalsList.toArray(new ICDISignal[0]);
}
return EMPTY_SIGNALS;
}
public void update(Target target) throws CDIException {
MISession miSession = target.getMISession();
MISigHandle[] miSigs = getMISignals(miSession);
List eventList = new ArrayList(miSigs.length);
List signalsList = getSignalsList(target);
for (int i = 0; i < miSigs.length; i++) {
ICDISignal sig = findSignal(target, miSigs[i].getName());
if (sig != null) {
if (hasSignalChanged(sig, miSigs[i])) {
// Fire ChangedEvent
((Signal)sig).setMISignal(miSigs[i]);
eventList.add(new MISignalChangedEvent(miSession, miSigs[i].getName()));
}
} else {
// add the new breakpoint and fire CreatedEvent
signalsList.add(new Signal(target, miSigs[i]));
//eventList.add(new MISignCreatedEvent(miSession, miSigs[i].getName()));
}
}
MIEvent[] events = (MIEvent[])eventList.toArray(new MIEvent[0]);
miSession.fireEvents(events);
}
}