Package flash.tools.debugger.concrete

Source Code of flash.tools.debugger.concrete.DSwfInfo

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License.  You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package flash.tools.debugger.concrete;

import java.util.Map;

import flash.swf.debug.DebugModule;
import flash.swf.debug.LineRecord;
import flash.tools.ActionLocation;
import flash.tools.debugger.InProgressException;
import flash.tools.debugger.Isolate;
import flash.tools.debugger.NoResponseException;
import flash.tools.debugger.Session;
import flash.tools.debugger.SourceFile;
import flash.tools.debugger.SwfInfo;
import flash.tools.debugger.events.FunctionMetaDataAvailableEvent;
import flash.util.IntMap;

public class DSwfInfo implements SwfInfo
{
  private int      m_index;
  private long    m_id;
  private IntMap    m_source;
  private String    m_path;
  private String    m_url;
  private String    m_host;
  private int      m_port;
  private boolean    m_swdLoading;
  private int      m_swfSize;
  private int      m_swdSize;
  private int      m_bpCount;
  private int      m_offsetCount;
  private int      m_scriptsExpected;
  private int      m_minId;    // first script id in the swf
  private int      m_maxId;    // last script id in this swf
  private byte[]    m_swf;      // actual swf contents
  private byte[]    m_swd;      // actual swd contents
  private boolean    m_unloaded;    // set if the player has unloaded this swf
  private Map<Long,Integer> m_local2Global; // local script id to global script id mapping table
  private int      m_numRefreshes; // number of refreshes we have taken
  private int         m_vmVersion;    // version of the vm

  private boolean            m_populated;  // set if we have already tried to load swf/swd for this info
  private LineFunctionContainer    m_container;  // used for pulling out detailed info about the swf

  private final static String UNKNOWN = PlayerSessionManager.getLocalizationManager().getLocalizedTextString("unknown"); //$NON-NLS-1$

  public DSwfInfo(int index, int isolateId
  { 
    // defaults values of zero
    m_id = 0;
    m_index = index;
    m_source = new IntMap();
    m_path = UNKNOWN;
    m_url = UNKNOWN;
    m_host = UNKNOWN;
    m_port = 0;
    m_swdLoading = true;
    m_scriptsExpected = -1// means not yet set by anyone!
    m_isolateId = isolateId;
    // rest default to null, 0 or false
  }

  /** SwfInfo interface */
  public String    getPath()                        { return m_path; }
  public String    getUrl()                        { return m_url; }
  public int      getSwfSize()                      { return m_swfSize; }
  public int      getSwdSize(Session s) throws InProgressException    { swdLoaded(s); return m_swdSize; }
  public boolean    isUnloaded()                      { return m_unloaded; }
  public boolean    isProcessingComplete()                  { return isPopulated(); }
  public boolean    containsSource(SourceFile f)              { return m_source.contains(f.getId()); }

  /* getters */
  public long      getId()          { return m_id; }
  public String    getHost()        { return m_host; }
  public int      getPort()        { return m_port; }
  public int      getSwdSize()       { return m_swdSize; }
  public int      getRefreshCount()    { return m_numRefreshes; }
  public boolean    isSwdLoading()      { return m_swdLoading; }
  public boolean    isPopulated()      { return m_populated; }
  public byte[]    getSwf()        { return m_swf; }
  public byte[]    getSwd()        { return m_swd; }
  public int      getSourceExpectedCount()  { return m_scriptsExpected; }
    public int          getVmVersion()          { return m_vmVersion;  }

//  public int      getBreakpointCount() throws InProgressException  { swdLoading(); return m_bpCount; }
//  public int      getOffsetCount()     { swdLoading(); return m_offsetCount; }
  public int      getSourceCount()   { return m_source.size(); }
  public int      getFirstSourceId()   { return m_minId; }
  public int      getLastSourceId()   { return m_maxId; }

    public void         setVmVersion(int vmVersion) { m_vmVersion = vmVersion;  }
  public void      setUnloaded()      { m_unloaded = true; }
  public void      setSwf(byte[] swf)    { m_swf = swf; }
  public void      setSwd(byte[] swd)    { m_swd = swd; }
  public void      setPopulated()      { m_swdLoading = false; m_populated = true; // no more waiting for swd, we're done
  public void      setSourceExpectedCount(int c) { m_scriptsExpected = c; }

  public void      addSource(int i, DModule m) { m_source.put(i, m); }

  /**
   * Return the number of sources that we have
   */
  public int getSourceCount(Session s) throws InProgressException 
  {
    // only if we don't have it all yet
    // then try to force a load
    if (!hasAllSource())
      swdLoaded(s);

    return getSourceCount();
  }

  /**
   * Return a list of our sources
   */
  public SourceFile[] getSourceList(Session s) throws InProgressException   
  {
    // only if we don't have it all yet
    // then try to force a load
    if (!hasAllSource())
      swdLoaded(s);

    return (SourceFile[])m_source.valuesToArray( new SourceFile[m_source.size()] );
  }

  /**
   * Make sure that the player has loaded our swd.  If not
   * we continue InProgressException to query the player for when its complete.
   * At some point we give up and finally admit that
   * we don't have a swd associated with this swf.
   */
  void swdLoaded(Session s) throws InProgressException
  {
    if (isSwdLoading() && !isUnloaded())
    {
      // make the request
//      System.out.println("Swdloaded " + m_isolateId);
      try { ((PlayerSession)s).requestSwfInfo(m_index, m_isolateId); } catch(NoResponseException nre) {}

      // I should now be complete
      if (!m_swdLoading)
        // done!
      else if (getSourceExpectedCount() > -1 && m_numRefreshes > 10)
        setPopulated()// tried too many times, so bail big time, no swd available (only if we already have our expected count)
      else
        throw new InProgressException(); // still loading!!!
    }
  }

  /**
   * This method returns true once we have all the scripts
   * that we expect to ever have.  We can get the information about
   * how many scripts we should get from two sources, 1) we may
   * get an InSwfInfo message from the player which contains
   * this value and 2) we may get a InNumScript message which
   * contains a script count.  A small caveat of course, is that
   * in case 1. we may also not get the a value if the swd has
   * not been fully processed by the player yet.
   */
  public boolean hasAllSource()
  {
    boolean yes = false;
    int expect = getSourceExpectedCount();
    int have = getSourceCount();

    // if they are equal we are done, unless
    // our expectation has not been set and have not yet loaded our swd
    if (expect == -1 && isSwdLoading())
      yes = false;
    else if (expect == have)
      yes = true;
    else
      yes = false;

    return yes;
  }

  public void freshen(long id, String path, String url, String host, long port, boolean swdLoading, long swfSize, long swdSize, long bpCount, long offsetCount, long scriptCount, Map<Long,Integer> map, int minId, int maxId)
  {
    m_id = (int)id;
    m_path = path;
    m_url = url;
    m_host = host;
    m_port = (int)port;
    m_swfSize = (int)swfSize;
    m_swdSize = (int)swdSize;
    m_bpCount = (int)bpCount;
    m_offsetCount = (int)offsetCount;
    m_local2Global = map;
    m_minId = (swdSize > 0) ? minId : 0;
    m_maxId = (swdSize > 0) ? maxId : 0;
    m_swdLoading = swdLoading;
    m_numRefreshes++;

    // only touch expected count if swd already loaded
    if (!swdLoading)
      m_scriptsExpected = (int)scriptCount;
  }

  /**
   * Locate the given offset within the swf
   */
  public ActionLocation locate(int offset)
  {
    return m_container.locationLessOrEqualTo(offset);
  }

  /**
   * Ask the container to locate the next line
   * record following the location specified in the
   * location, without spilling over into the next
   * action list
   */
  public ActionLocation locateSourceLineEnd(ActionLocation l)
  {
    return locateSourceLineEnd(l, -1);
  }

  public ActionLocation locateSourceLineEnd(ActionLocation l, int stopAt)
  {
    ActionLocation end = m_container.endOfSourceLine(l);
    if (stopAt > -1 && end.at > stopAt)
      end.at = stopAt;
    return end;
  }

  /**
   * Use the local2global script id map that was provided by the
   * Player, so that we can take the local id contained in the swd
   * and convert it to a global one that the player has annointed
   * to this script.
   */
  int local2Global(long id)
  {
    Integer g = m_local2Global.get(id);
    if (g != null)
      id = g.intValue();

    return (int) id;
  }

  /**
   * Freshen the contents of this object with the given swf info
   * The items that we touch are all swd related, as everything else
   * has arrriave
   */

  // temporary while we parse
  DManager m_manager;
  private int m_isolateId = Isolate.DEFAULT_ID;

  /**
   * Extracts information out of the SWF/SWD in order to populate
   * function line number tables in SourceFile variabels.
   */
  public void parseSwfSwd(DManager manager)
  {
    m_manager = manager;

    // suck in the swf/swd into action lists and then walk the lists
    // looking for LineRecords
    m_container = new LineFunctionContainer(m_swf, m_swd);
    m_container.combForLineRecords(this);

    // we are done, sucess or no
    setPopulated();

    // log event that we have complete done
    manager.addEvent(new FunctionMetaDataAvailableEvent());
    m_manager = null;
  }

  /**
   * This is a callback function from LineFunctionContainer.combForLineRecords()
   * We extract what we want and then update the associated module
   */
  public void processLineRecord(ActionLocation where, LineRecord r)
  {
    int line = r.lineno;
    String func = (where.function == null) ? null : where.function.name;
    DebugModule dm = r.module;

    // locate the source file
    int id = -1;
    DModule module;

    if (dm == null || where.at == -1)
      ;
    else if ( (id = local2Global(dm.id)) < 0 )
      ;
    else if ( (module = m_manager.getSource(id, Isolate.DEFAULT_ID)) == null )
      ;
    else
      module.addLineFunctionInfo(where.actions.getOffset(where.at), line, func);
  }

  /* for debugging */
  @Override
  public String toString() {
    return m_path;
  }

  @Override
  public int getIsolateId() {
    return m_isolateId;
  }
}
TOP

Related Classes of flash.tools.debugger.concrete.DSwfInfo

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.