/******************************************************************************* * Copyright (c) 2011, 2014 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: * Wind River Systems - initial API and implementation *******************************************************************************/ package org.eclipse.tcf.internal.services.remote; import java.util.Collection; import java.util.HashMap; import java.util.Map; import org.eclipse.tcf.core.Command; import org.eclipse.tcf.protocol.IChannel; import org.eclipse.tcf.protocol.IToken; import org.eclipse.tcf.protocol.JSON; import org.eclipse.tcf.services.ISymbols; public class SymbolsProxy implements ISymbols { private final IChannel channel; private class Context implements Symbol { private final byte[] value; private final Map<String,Object> props; Context(Map<String,Object> props) { this.props = props; value = JSON.toByteArray(props.get(PROP_VALUE)); } public String getOwnerID() { return (String)props.get(PROP_OWNER_ID); } public int getUpdatePolicy() { Number n = (Number)props.get(PROP_UPDATE_POLICY); if (n == null) return 0; return n.intValue(); } public Number getAddress() { return (Number)props.get(PROP_ADDRESS); } public String getBaseTypeID() { return (String)props.get(PROP_BASE_TYPE_ID); } public String getID() { return (String)props.get(PROP_ID); } public String getIndexTypeID() { return (String)props.get(PROP_INDEX_TYPE_ID); } public String getContainerID() { return (String)props.get(PROP_CONTAINER_ID); } public int getLength() { Number n = (Number)props.get(PROP_LENGTH); if (n == null) return 0; return n.intValue(); } public Number getLowerBound() { return (Number)props.get(PROP_LOWER_BOUND); } public Number getUpperBound() { return (Number)props.get(PROP_UPPER_BOUND); } public Number getBitStride() { return (Number)props.get(PROP_BIT_STRIDE); } public String getName() { return (String)props.get(PROP_NAME); } public int getOffset() { Number n = (Number)props.get(PROP_OFFSET); if (n == null) return 0; return n.intValue(); } public Map<String,Object> getProperties() { return props; } public int getSize() { Number n = (Number)props.get(PROP_SIZE); if (n == null) return 0; return n.intValue(); } public SymbolClass getSymbolClass() { Number n = (Number)props.get(PROP_SYMBOL_CLASS); if (n != null) { switch (n.intValue()) { case 1: return SymbolClass.value; case 2: return SymbolClass.reference; case 3: return SymbolClass.function; case 4: return SymbolClass.type; case 5: return SymbolClass.comp_unit; case 6: return SymbolClass.block; case 7: return SymbolClass.namespace; case 8: return SymbolClass.variant_part; case 9: return SymbolClass.variant; } } return SymbolClass.unknown; } public TypeClass getTypeClass() { Number n = (Number)props.get(PROP_TYPE_CLASS); if (n != null) { switch (n.intValue()) { case 1: return TypeClass.cardinal; case 2: return TypeClass.integer; case 3: return TypeClass.real; case 4: return TypeClass.pointer; case 5: return TypeClass.array; case 6: return TypeClass.composite; case 7: return TypeClass.enumeration; case 8: return TypeClass.function; case 9: return TypeClass.member_pointer; case 10: return TypeClass.complex; } } return TypeClass.unknown; } public String getTypeID() { return (String)props.get(PROP_TYPE_ID); } public byte[] getValue() { return value; } public boolean isBigEndian() { Boolean b = (Boolean)props.get(PROP_BIG_ENDIAN); return b != null && b.booleanValue(); } public String getRegisterID() { return (String)props.get(PROP_REGISTER); } public int getFlags() { Number n = (Number)props.get(PROP_FLAGS); if (n == null) return 0; return n.intValue(); } public boolean getFlag(int flag) { Number n = (Number)props.get(PROP_FLAGS); if (n == null) return false; return (n.intValue() & flag) != 0; } } public SymbolsProxy(IChannel channel) { this.channel = channel; } public String getName() { return NAME; } public IToken getContext(String id, final DoneGetContext done) { return new Command(channel, this, "getContext", new Object[]{ id }) { @SuppressWarnings("unchecked") @Override public void done(Exception error, Object[] args) { Context ctx = null; if (error == null) { assert args.length == 2; error = toError(args[0]); if (args[1] != null) ctx = new Context((Map<String,Object>)args[1]); } done.doneGetContext(token, error, ctx); } }.token; } public IToken getChildren(String parent_context_id, final DoneGetChildren done) { return new Command(channel, this, "getChildren", new Object[]{ parent_context_id }) { @Override public void done(Exception error, Object[] args) { String[] lst = null; if (error == null) { assert args.length == 2; error = toError(args[0]); lst = toStringArray(args[1]); } done.doneGetChildren(token, error, lst); } }.token; } public IToken find(String context_id, Number ip, String name, final DoneFind done) { return new Command(channel, this, "find", new Object[]{ context_id, ip, name }) { @Override public void done(Exception error, Object[] args) { String id = null; if (error == null) { assert args.length == 2; error = toError(args[0]); id = (String)args[1]; } done.doneFind(token, error, id); } }.token; } public IToken findByName(String context_id, Number ip, String name, final DoneFindAll done) { return new Command(channel, this, "findByName", new Object[]{ context_id, ip, name }) { @Override public void done(Exception error, Object[] args) { String[] ids = null; if (error == null) { assert args.length == 2; error = toError(args[0]); ids = toStringArray(args[1]); } done.doneFind(token, error, ids); } }.token; } public IToken findInScope(String context_id, Number ip, String scope_id, String name, final DoneFindAll done) { return new Command(channel, this, "findInScope", new Object[]{ context_id, ip, scope_id, name }) { @Override public void done(Exception error, Object[] args) { String[] ids = null; if (error == null) { assert args.length == 2; error = toError(args[0]); ids = toStringArray(args[1]); } done.doneFind(token, error, ids); } }.token; } public IToken findByAddr(String context_id, Number addr, final DoneFind done) { return new Command(channel, this, "findByAddr", new Object[]{ context_id, addr }) { @SuppressWarnings("rawtypes") @Override public void done(Exception error, Object[] args) { String id = null; if (error == null) { assert args.length == 2; error = toError(args[0]); if (args[1] instanceof Collection) id = (String)((Collection) args[1]).iterator().next(); else id = (String)args[1]; } done.doneFind(token, error, id); } }.token; } public IToken findByAddr(String context_id, Number addr, final DoneFindAll done) { return new Command(channel, this, "findByAddr", new Object[]{ context_id, addr }) { @Override public void done(Exception error, Object[] args) { String[] ids = null; if (error == null) { assert args.length == 2; error = toError(args[0]); ids = toStringArray(args[1]); } done.doneFind(token, error, ids); } }.token; } public IToken list(String context_id, final DoneList done) { return new Command(channel, this, "list", new Object[]{ context_id }) { @Override public void done(Exception error, Object[] args) { String[] lst = null; if (error == null) { assert args.length == 2; error = toError(args[0]); lst = toStringArray(args[1]); } done.doneList(token, error, lst); } }.token; } public IToken getLocationInfo(String symbol_id, final DoneGetLocationInfo done) { return new Command(channel, this, "getLocationInfo", new Object[]{ symbol_id }) { @Override @SuppressWarnings("unchecked") public void done(Exception error, Object[] args) { Map<String,Object> props = null; if (error == null) { assert args.length == 2; error = toError(args[0]); props = (Map<String,Object>)args[1]; } done.doneGetLocationInfo(token, error, props); } }.token; } public IToken findFrameInfo(String context_id, Number address, final DoneFindFrameInfo done) { return new Command(channel, this, "findFrameInfo", new Object[]{ context_id, address }) { @Override public void done(Exception error, Object[] args) { Number address = null; Number size = null; Object[] fp_cmds = null; Map<String,Object[]> reg_cmds = null; if (error == null) { assert args.length == 5; error = toError(args[0]); address = (Number)args[1]; size = (Number)args[2]; fp_cmds = toObjectArray(args[3]); reg_cmds = toStringMap(args[4]); } done.doneFindFrameInfo(token, error, address, size, fp_cmds, reg_cmds); } }.token; } public IToken getSymFileInfo(String context_id, Number address, final DoneGetSymFileInfo done) { return new Command(channel, this, "getSymFileInfo", new Object[]{ context_id, address }) { @SuppressWarnings("unchecked") @Override public void done(Exception error, Object[] args) { Map<String,Object> props = null; if (error == null) { assert args.length == 2; error = toError(args[0]); props = (Map<String,Object>)args[1]; } done.doneGetSymFileInfo(token, error, props); } }.token; } @SuppressWarnings("unchecked") private String[] toStringArray(Object o) { if (o == null) return null; if (o instanceof String) return new String[]{ (String)o }; Collection<String> c = (Collection<String>)o; return (String[])c.toArray(new String[c.size()]); } @SuppressWarnings("unchecked") private Object[] toObjectArray(Object o) { if (o == null) return null; Collection<Object> c = (Collection<Object>)o; return (Object[])c.toArray(new Object[c.size()]); } @SuppressWarnings("unchecked") private Map<String,Object[]> toStringMap(Object o) { if (o == null) return null; Map<String,Object> c = (Map<String,Object>)o; HashMap<String,Object[]> m = new HashMap<String,Object[]>(); for (Map.Entry<String,Object> e : c.entrySet()) { m.put(e.getKey(), toObjectArray(e.getValue())); } return m; } }