ObjectTreeNodeAdapter.java 7.2 KB
Newer Older
D
duke 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216
/*
 * Copyright 2001 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 *
 */

package sun.jvm.hotspot.bugspot.tree;

import java.io.*;
import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.debugger.cdbg.*;
import sun.jvm.hotspot.ui.tree.SimpleTreeNode;

/** An adapter class which allows C/C++ objects to be displayed in a
    tree via the SimpleTreeNode interface. */

public class ObjectTreeNodeAdapter extends FieldTreeNodeAdapter {
  // Address of object
  private Address addr;

  /** The address may be null (for object fields of objcets which are
      null). The FieldIdentifier should not be null. treeTableMode
      defaults to false. */
  public ObjectTreeNodeAdapter(Address addr, FieldIdentifier id) {
    this(addr, id, false);
  }

  /** The address may be null (for object fields of objcets which are
      null). The FieldIdentifier should not be null. */
  public ObjectTreeNodeAdapter(Address addr, FieldIdentifier id, boolean treeTableMode) {
    super(id, treeTableMode);
    this.addr = addr;
  }

  public int getChildCount() {
    if (addr == null) {
      return 0;
    }

    Counter c = new Counter();
    getType().iterateObject(addr, c);
    return c.getNumFields();
  }

  public SimpleTreeNode getChild(int index) {
    if (addr == null) {
      return null;
    }

    Fetcher f = new Fetcher(index);
    getType().iterateObject(addr, f);
    return f.getChild();
  }

  public boolean isLeaf() {
    return (addr == null);
  }

  public int getIndexOfChild(SimpleTreeNode child) {
    FieldIdentifier id = ((FieldTreeNodeAdapter) child).getID();
    Finder f = new Finder(id);
    getType().iterateObject(addr, f);
    return f.getIndex();
  }

  public String getValue() {
    if (addr != null) {
      return addr.toString();
    }
    return "NULL";
  }

  /** Should be used only once, then have the number of fields
      fetched. */
  static class Counter extends DefaultObjectVisitor {
    private int numFields;

    public int getNumFields() {
      return numFields;
    }

    public void doBit(FieldIdentifier f, long val)                   { ++numFields; }
    public void doInt(FieldIdentifier f, long val)                   { ++numFields; }
    public void doEnum(FieldIdentifier f, long val, String enumName) { ++numFields; }
    public void doFloat(FieldIdentifier f, float val)                { ++numFields; }
    public void doDouble(FieldIdentifier f, double val)              { ++numFields; }
    public void doPointer(FieldIdentifier f, Address val)            { ++numFields; }
    public void doArray(FieldIdentifier f, Address val)              { ++numFields; }
    public void doRef(FieldIdentifier f, Address val)                { ++numFields; }
    public void doCompound(FieldIdentifier f, Address addr)          { ++numFields; }
  }

  /** Creates a new SimpleTreeNode for the given field. */
  class Fetcher extends DefaultObjectVisitor {
    private int index;
    private int curField;
    private SimpleTreeNode child;

    public Fetcher(int index) {
      this.index = index;
    }

    public SimpleTreeNode getChild() {
      return child;
    }

    public void doBit(FieldIdentifier f, long val) {
      if (curField == index) {
        child = new LongTreeNodeAdapter(val, f, getTreeTableMode());
      }
      ++curField;
    }

    public void doInt(FieldIdentifier f, long val) {
      if (curField == index) {
        child = new LongTreeNodeAdapter(val, f, getTreeTableMode());
      }
      ++curField;
    }

    public void doEnum(FieldIdentifier f, long val, String enumName) {
      if (curField == index) {
        child = new EnumTreeNodeAdapter(enumName, val, f, getTreeTableMode());
      }
      ++curField;
    }

    public void doFloat(FieldIdentifier f, float val) {
      if (curField == index) {
        child = new FloatTreeNodeAdapter(val, f, getTreeTableMode());
      }
      ++curField;
    }

    public void doDouble(FieldIdentifier f, double val) {
      if (curField == index) {
        child = new DoubleTreeNodeAdapter(val, f, getTreeTableMode());
      }
      ++curField;
    }

    public void doPointer(FieldIdentifier f, Address val) {
      if (curField == index) {
        child = new AddressTreeNodeAdapter(val, f, getTreeTableMode());
      }
      ++curField;
    }

    public void doArray(FieldIdentifier f, Address val) {
      if (curField == index) {
        child = new AddressTreeNodeAdapter(val, f, getTreeTableMode());
      }
      ++curField;
    }

    public void doRef(FieldIdentifier f, Address val) {
      if (curField == index) {
        child = new AddressTreeNodeAdapter(val, f, getTreeTableMode());
      }
      ++curField;
    }

    public void doCompound(FieldIdentifier f, Address val) {
      if (curField == index) {
        child = new ObjectTreeNodeAdapter(val, f, getTreeTableMode());
      }
      ++curField;
    }
  }

  /** Finds the index of the given FieldIdentifier. */
  static class Finder extends DefaultObjectVisitor {
    private FieldIdentifier id;
    private int curField;
    private int index = -1;

    public Finder(FieldIdentifier id) {
      this.id = id;
    }

    /** Returns -1 if not found */
    public int getIndex() {
      return index;
    }

    public void doBit(FieldIdentifier f, long val)        { if (f.equals(id)) { index = curField; } ++curField; }
    public void doInt(FieldIdentifier f, long val)        { if (f.equals(id)) { index = curField; } ++curField; }
    public void doEnum(FieldIdentifier f, long val,
                       String enumName)                   { if (f.equals(id)) { index = curField; } ++curField; }
    public void doFloat(FieldIdentifier f, float val)     { if (f.equals(id)) { index = curField; } ++curField; }
    public void doDouble(FieldIdentifier f, double val)   { if (f.equals(id)) { index = curField; } ++curField; }
    public void doPointer(FieldIdentifier f, Address val) { if (f.equals(id)) { index = curField; } ++curField; }
    public void doArray(FieldIdentifier f, Address val)   { if (f.equals(id)) { index = curField; } ++curField; }
    public void doRef(FieldIdentifier f, Address val)     { if (f.equals(id)) { index = curField; } ++curField; }
    public void doCompound(FieldIdentifier f,
                           Address val)                   { if (f.equals(id)) { index = curField; } ++curField; }
  }
}