incubator-kato-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From monte...@apache.org
Subject svn commit: r883384 [16/47] - in /incubator/kato/trunk/org.apache.kato: ./ kato.anttasks/src/main/java/org/apache/kato/anttasks/ kato.anttasks/src/main/java/org/apache/kato/anttasks/sitebuilder/ kato.anttasks/src/main/java/org/apache/kato/anttasks/tck/...
Date Mon, 23 Nov 2009 15:54:15 GMT
Modified: incubator/kato/trunk/org.apache.kato/kato.hprof.reader/src/main/java/org/apache/kato/hprof/datalayer/HProfFile.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/org.apache.kato/kato.hprof.reader/src/main/java/org/apache/kato/hprof/datalayer/HProfFile.java?rev=883384&r1=883383&r2=883384&view=diff
==============================================================================
--- incubator/kato/trunk/org.apache.kato/kato.hprof.reader/src/main/java/org/apache/kato/hprof/datalayer/HProfFile.java (original)
+++ incubator/kato/trunk/org.apache.kato/kato.hprof.reader/src/main/java/org/apache/kato/hprof/datalayer/HProfFile.java Mon Nov 23 15:53:48 2009
@@ -1,1428 +1,1428 @@
-/*******************************************************************************
- * Licensed 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 org.apache.kato.hprof.datalayer;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.util.List;
-
-import org.apache.kato.common.BitMaskMappingArray;
-import org.apache.kato.common.DataProviderBackedArrayProvider;
-import org.apache.kato.common.DataReader;
-import org.apache.kato.common.IArrayEntryProvider;
-import org.apache.kato.common.IDataProvider;
-import org.apache.kato.common.InvalidFileFormat;
-import org.apache.kato.common.SubsetDataProvider;
-import org.apache.kato.hprof.HProfRecordFormatter;
- 
-public class HProfFile {
-
-	class ControlSettingsHProfRecord extends HProfRecord implements
-			IControlSettingsHProfRecord {
-
-		public ControlSettingsHProfRecord(short tag, byte[] data) {
-			super(tag, data);
-
-		}
-
-		public short getStackTraceDepth() {
-			return readShort(4);
-		}
-
-		public boolean isAllocTrace() {
-			return (readInt(0) & 1) == 1;
-		}
-
-		public boolean isCpuSampling() {
-			return (readInt(0) & 2) == 2;
-		}
-	}
-
-	class EndThreadHProfRecord extends HProfRecord implements
-			IThreadEndingHProfRecord {
-
-		public EndThreadHProfRecord(short tag, byte[] data) {
-			super(tag, data);
-
-		}
-
-		public int getThreadSerialNumber() {
-			return readInt(0);
-		}
-	}
-
-	class FrameHProfRecord extends HProfRecord implements
-			IJavaStackFrameHProfRecord {
-
-		public FrameHProfRecord(short tag, byte[] data) {
-			super(tag, data);
-
-		}
-
-		public int getClassSerialNumber() {
-			return readInt(idSize * 4);
-		}
-
-		public int getLineNumber() {
-			return readInt((idSize * 4) + 4);
-		}
-
-		public long getMethodNameID() {
-			return readNumber(idSize, idSize);
-		}
-
-		public long getMethodSignatureID() {
-			return readNumber(idSize + idSize, idSize);
-		}
-
-		public long getSourceFileNameID() {
-			return readNumber(idSize + idSize + idSize, idSize);
-		}
-
-		public long getStackFrameID() {
-			return readNumber(0, idSize);
-		}
-
-		/**
-		 * Check equality based on stack frame ID.
-		 */
-		public boolean equals(Object obj) {
-			if ((obj == null) || !(obj instanceof FrameHProfRecord)) {
-				return false;
-			}
-			
-			FrameHProfRecord record = (FrameHProfRecord) obj;
-			
-			return record.getStackFrameID() == getStackFrameID();
-		}
-
-	}
-
-	class HeapDumpHProfRecord extends HProfRecord implements
-			IHeapDumpHProfRecord {
-
-		private BitMaskMappingArray subRecordArray = null;
-		private int subRecordCount = -1;
-		private long size = 0;
-		private IDataProvider myP = null;
-
-		public HeapDumpHProfRecord(short tag, IDataProvider dataProvider)
-				throws IOException {
-			super(tag, null);
-			size = dataProvider.getDataLength();
-			myP = dataProvider;
-			subRecordArray = new BitMaskMappingArray(1000, 25,
-					new HProfDumpRecordArrayProvider(dataProvider));
-		}
-
-		public IHProfRecord getSubRecord(int index) {
-
-			return (IHProfRecord) subRecordArray.get(index);
-		}
-
-		@Override
-		public int getSubRecordCount() {
-			if (subRecordCount == -1) {
-
-				subRecordCount = 0;
-				while (true) {
-					if (subRecordCount == 5) {
-						int a = 1;
-					}
-					Object o = subRecordArray.get(subRecordCount);
-					if (o == null)
-						break;
-					subRecordCount++;
-					if (o instanceof UnknownHProfRecord) {
-						break;
-					}
-				}
-
-			}
-			return subRecordCount;
-		}
-
-		@Override
-		public long getDataLength() {
-			return (int) size;
-		}
-
-		@Override
-		public byte[] getData() {
-			try {
-				return peek(myP, 20);
-			} catch (IOException e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
-			}
-			return null;
-		}
-
-		@Override
-		public long getSubRecordLocation(int index) {
-			return subRecordArray.getLocation(index);
-		}
-
-		@Override
-		/**
-		 * Return a record by its locations
-		 * 
-		 * @param location
-		 * @return IHProfRecord at given location
-		 */
-		public IHProfRecord getSubRecordByLocation(long location) {		
-			return (IHProfRecord) subRecordArray.getAtLocation(location);
-		}
-	}
-
-	private final class HProfDumpRecordArrayProvider extends
-			DataProviderBackedArrayProvider {
-		private HProfDumpRecordArrayProvider(IDataProvider provider) {
-			super(provider);
-		}
-
-		private IHProfRecord buildClassDumpRecord(int tag,
-				IDataProvider dumpRecordProvider) throws IOException {
-
-			long loc = dumpRecordProvider.getCurrentLocation();
-			dumpRecordProvider.moveBy((idSize * 7) + 8);
-			short elements = dumpRecordProvider.readU2(); // size of constant
-			// pool
-			int constantPoolIndex = (int)(dumpRecordProvider.getCurrentLocation()
-					- loc);
-			for (int i = 0; i < elements; i++) {
-				short cpIndex = dumpRecordProvider.readU2();
-				short type = dumpRecordProvider.readByte();
-				int arrayLength = sizes.getLengthFromType(type);
-				dumpRecordProvider.moveBy(arrayLength);
-			}
-
-			short staticFields = dumpRecordProvider.readU2();
-						
-			int staticFieldsIndex = (int)(dumpRecordProvider.getCurrentLocation()- loc);
-			for (int i = 0; i < staticFields; i++) {
-				long index = DataReader.readNumber(dumpRecordProvider, idSize);
-				short type = dumpRecordProvider.readByte();
-				int arrayLength = sizes.getLengthFromType(type);
-				dumpRecordProvider.moveBy(arrayLength);
-			}
-
-			short instFields = dumpRecordProvider.readU2();
-
-			int instFieldsIndex = (int) (dumpRecordProvider.getCurrentLocation()- loc);
-			for (int i = 0; i < instFields; i++) {
-				long index = DataReader.readNumber(dumpRecordProvider, idSize);
-				short type = dumpRecordProvider.readByte();
-			}
-
-			long datalength = dumpRecordProvider.getCurrentLocation() - loc;
-			SubsetDataProvider p = new SubsetDataProvider(dumpRecordProvider,
-					loc, datalength);
-
-			// Pass indices of static and instance fields - they are variable length.
-			return new GCClassHeapDumpRecord((byte) tag, p, staticFieldsIndex, instFieldsIndex );
-
-		}
-
-		@Override
-		public Object getCurrentElement() {
-			// read tag
-			try {
-				long l = getProvider().getCurrentLocation();
-
-				IDataProvider p = getProvider();
-				if (p.dataRemaining() < 1)
-					return null;
-				short tag = p.readByte();
-				int size = getRecordSize(tag);
-				byte[] data = null;
-				if (size >= 0) {
-					data = getProvider().readBytes(size);
-				}
-
-				switch (tag) {
-				case 0xFF: // unknown root
-					return new GCRootUnknownHeapRecord(tag, data);
-
-				case 0x01: // jni global root
-
-					return new GCRootJNIGlobalRefHeapRecord(tag, data);
-
-				case 0x02: // jni local
-					return new GCRootJNILocalHeapRecord(tag, data);
-
-				case 0x03: // java frame
-					return new GCRootJavaFrameHeapRecord(tag, data);
-
-				case 0x04: // native stack root
-					return new GCRootNativeStackHeapRecord(tag, data);
-
-				case 0x05: // stick class root
-					return new GCRootStickyClassHeapRecord(tag, data);
-
-				case 0x06: // thread block root
-					return new GCRoothreadBlockHeapRecord(tag, data);
-
-				case 0x07: // monitor used
-					return new GCRootMonitorUsedHeapRecord(tag, data);
-
-				case 0x08: // thread obj root
-					return new GCRootThreadObjHeapRecord(tag, data);
-
-				case 0x20: // class dump
-					return buildClassDumpRecord(tag, getProvider());
-				case 0x21: // instance
-					return buildInstanceDumpRecord(tag, getProvider());
-
-				case 0x22: // obj array
-					return buildObjArrayDumpRecord(tag, getProvider());
-				case 0x23: // primitive array
-					return buildPrimitiveArrayDumpRecord(tag, getProvider());
-
-				default:
-					// don't know what this is
-					return new UnknownHProfRecord(tag, null);
-
-				}
-
-			} catch (IOException e) {
-				e.printStackTrace();
-				return null;
-			}
-
-		}
-
-		private Object buildPrimitiveArrayDumpRecord(short tag,
-				IDataProvider arrayProvider) throws IOException {
-
-			long loc = arrayProvider.getCurrentLocation();
-			arrayProvider.moveBy(idSize + 4);
-			int elements = arrayProvider.readU4();
-			short elementType = arrayProvider.readByte();
-
-			int elementLength = sizes.getLengthFromType(elementType);
-			int datalength = idSize + 9 + (elementLength * elements);
-			arrayProvider.moveTo(loc);
-			SubsetDataProvider p = new SubsetDataProvider(arrayProvider,
-					datalength);
-			arrayProvider.moveTo(loc + datalength);
-			return new GCPrimitiveArrayHeapDumpRecord(tag, p);
-		}
-
-		/**
-		 * 
-		 * id array object ID u4 stack trace serial number u4 number of elements
-		 * id array class ID [id]* elements
-		 * 
-		 * @param tag
-		 * @param arrayProvider
-		 * @return
-		 * @throws IOException
-		 */
-		private Object buildObjArrayDumpRecord(short tag,
-				IDataProvider arrayProvider) throws IOException {
-
-			long loc = arrayProvider.getCurrentLocation();
-			arrayProvider.moveBy(idSize + 4);
-			int elements = arrayProvider.readU4();
-			int datalength = (idSize * 2) + 8 + (idSize * elements);
-			arrayProvider.moveTo(loc);
-			SubsetDataProvider p = new SubsetDataProvider(arrayProvider,
-					datalength);
-			arrayProvider.moveTo(loc + datalength);
-			return new GCObjectArrayHeapDumpRecord(tag, p);
-		}
-
-		/**
-		 * id object ID u4 stack trace serial number id class object ID u4
-		 * number of bytes that follow [vl]* instance field values (class,
-		 * followed by super, super's super ...)
-		 * 
-		 * @param tag
-		 * @param arrayProvider
-		 * @return
-		 * @throws IOException
-		 */
-		private Object buildInstanceDumpRecord(short tag,
-				IDataProvider arrayProvider) throws IOException {
-
-			long loc = arrayProvider.getCurrentLocation();
-			arrayProvider.moveBy((idSize * 2) + 4);
-			int byteCount = arrayProvider.readU4();
-			int datalength = (idSize * 2) + 8 + byteCount;
-			arrayProvider.moveTo(loc);
-			SubsetDataProvider p = new SubsetDataProvider(arrayProvider,
-					datalength);
-			arrayProvider.moveTo(loc + datalength);
-			return new GCInstanceHeapDumpRecord(tag, p);
-		}
-
-		/**
-		 * Returns record size for given tag.
-		 * 
-		 * @param tag -
-		 *            tag to size
-		 * @return record size or -1 if dynamic, -2 if unknown tag
-		 */
-		private int getRecordSize(int tag) {
-			int recordLength = 0;
-
-			switch (tag) {
-
-			case 0xFF: // unknown root
-
-				recordLength = idSize;
-				break;
-
-			case 0x01: // jni global root
-
-				recordLength = idSize * 2;
-				break;
-
-			case 0x02: // jni local
-				recordLength = idSize + 8;
-				break;
-
-			case 0x03: // java frame
-				recordLength = idSize + 8;
-				break;
-
-			case 0x04: // native stack root
-				recordLength = idSize + 4;
-				break;
-
-			case 0x05: // stick class root
-				recordLength = idSize;
-				break;
-
-			case 0x06: // thread block root
-				recordLength = idSize + 4;
-				break;
-
-			case 0x07: // monitor used
-				recordLength = idSize;
-				break;
-
-			case 0x08: // thread obj root
-				recordLength = idSize + 8;
-				break;
-
-			case 0x20: // class dump
-			case 0x21: // instance
-			case 0x22: // obj array
-			case 0x23: // primitive array
-				recordLength = -1;
-				break;
-			default:
-				// don't know what this is
-				recordLength = -2;
-
-			}
-			return recordLength;
-		}
-	}
-
-	private final class HPROFRecordProvider implements IArrayEntryProvider {
-
-		private IDataProvider recordProvider = null;
-
-		public HPROFRecordProvider(IDataProvider provider) {
-			this.recordProvider = provider;
-		}
-
-		@Override
-		public IHProfRecord getCurrentElement() {
-
-			// read tag
-			try {
-
-				short tag = recordProvider.readByte();
-				int ms = recordProvider.readU4();
-				int left = recordProvider.readU4();
-				byte[] data = null;
-
-				switch (tag) {
-				case 0x0c:
-					break;
-				default:
-
-					data = recordProvider.readBytes(left);
-
-				}
-
-				switch (tag) {
-
-				case 0x01:
-
-					return new UTF8HProfRecordImpl(tag, data);
-				case 0x02:
-					return new LoadClassHProfRecord(tag, data);
-				case 0x03:
-					return new UnloadClassHProfRecord(tag, data);
-				case 0x04:
-					return new FrameHProfRecord(tag, data);
-				case 0x05:
-					return new TraceHProfRecord(tag, data);
-				case 0x0e:
-					return new ControlSettingsHProfRecord(tag, data);
-
-				case 0x0a:
-					return new StartThreadHProfRecord(tag, data);
-				case 0x0b:
-					return new EndThreadHProfRecord(tag, data);
-
-				case 0x0c:
-					IHeapDumpHProfRecord rec = new HeapDumpHProfRecord(tag,
-							new SubsetDataProvider(recordProvider, left));
-					recordProvider.moveBy(left);
-					return rec;
-				default:
-					// don't know what the thing is - return an unknown
-					// type.
-
-					return new UnknownHProfRecord(tag, data);
-				}
-
-			} catch (IOException e) {
-				return null;
-			}
-
-		}
-
-		@Override
-		public long getCurrentLocation() {
-
-			try {
-				return recordProvider.getCurrentLocation();
-			} catch (IOException e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
-			}
-			return -1;
-		}
-
-		@Override
-		public void getState(List state) {
-
-			state.add("HProfRecordProvider");
-			recordProvider.addState(state);
-
-		}
-
-		@Override
-		public boolean moveRelativeElement(int seekNo) {
-
-			while (seekNo > 0) {
-				Object o = getCurrentElement();
-				if (o == null)
-					return false;
-				seekNo--;
-			}
-			return true;
-		}
-
-		@Override
-		public boolean moveToLocation(long l) {
-
-			try {
-				recordProvider.moveTo(l);
-				return true;
-			} catch (IOException e) {
-				return false;
-			}
-		}
-	}
-
-	class LoadClassHProfRecord extends HProfRecord implements
-			ILoadClassHProfRecord {
-
-		public LoadClassHProfRecord(short tag, byte[] data) {
-			super(tag, data);
-
-		}
-
-		public long getClassNameID() {
-			return readNumber(8 + idSize, idSize);
-		}
-
-		public long getClassObjectID() {
-			return readNumber(4, idSize);
-		}
-
-		public int getClassSerialNumber() {
-			return readInt(0);
-		}
-
-		public int getStackTraceSerialNumber() {
-			return readInt(4 + idSize);
-		}
-	}
-
-	class UnloadClassHProfRecord extends HProfRecord implements
-			IUnloadClassHProfRecord {
-
-		public UnloadClassHProfRecord(short tag, byte[] data) {
-			super(tag, data);
-
-		}
-
-		public int getClassSerialNumber() {
-			return readInt(0);
-		}
-	}
-
-	class StartThreadHProfRecord extends HProfRecord implements
-			IThreadActiveHProfRecord {
-
-		public StartThreadHProfRecord(short tag, byte[] data) {
-			super(tag, data);
-
-		}
-
-		public int getStackTraceSerialNumber() {
-			return readInt(idSize + 4);
-		}
-
-		public long getThreadGroupNameID() {
-			return readNumber(8 + (idSize * 2), idSize);
-
-		}
-
-		public long getThreadGroupParentNameID() {
-			return readNumber(8 + (idSize * 3), idSize);
-		}
-
-		public long getThreadNameID() {
-			return readNumber(8 + idSize, idSize);
-		}
-
-		public long getThreadObjectID() {
-			return readNumber(4, idSize);
-		}
-
-		public int getThreadSerialNumber() {
-			return readInt(0);
-		}
-	}
-
-	class TraceHProfRecord extends HProfRecord implements
-			IJavaStackTraceHProfRecord {
-
-		public TraceHProfRecord(short tag, byte[] data) {
-			super(tag, data);
-		}
-
-		public int getFrameCount() {
-			return readInt(8);
-		}
-
-		public int getSerialNumber() {
-			return readInt(0);
-		}
-
-		public long getStackFrameID(int elementNo) {
-			return readNumber((idSize * elementNo) + 12, idSize);
-		}
-
-		public int getThreadSerialNumber() {
-			return readInt(4);
-		}
-	}
-
-	class UnknownHProfRecord extends HProfRecord {
-
-		public UnknownHProfRecord(short tag, byte[] data) {
-			super(tag, data);
-
-		}
-
-	}
-
-	class UTF8HProfRecordImpl extends HProfRecord implements IUTF8HProfRecord {
-
-		public UTF8HProfRecordImpl(short tag, byte[] data) {
-			super(tag, data);
-
-		}
-
-		@Override
-		public String getAsString() {
-
-			try {
-				return new String(getCharacters(), "UTF-8");
-			} catch (UnsupportedEncodingException e) {
-
-				return null;
-			}
-		}
-
-		/*
-		 * (non-Javadoc)
-		 * 
-		 * @see org.apache.kato.hprof.IUTF8HProfRecord#getCharacters()
-		 */
-		public byte[] getCharacters() {
-
-			int length = ((int) getDataLength()) - idSize;
-			return readBytes(idSize, length);
-		}
-
-		/*
-		 * (non-Javadoc)
-		 * 
-		 * @see org.apache.kato.hprof.IUTF8HProfRecord#getNameID()
-		 */
-		public long getNameID() {
-			return readNumber(0, idSize);
-		}
-	}
-
-	private BitMaskMappingArray array = null;
-
-	private String header = null;
-
-	private Integer idSize = null;
-	private HProfDataTypeSizes sizes = null;
-
-	private IDataProvider mainProvider = null;
-
-	private int records = -1;
-	private long recordsOffset = 0;
-
-	private Long timeStamp = null;
-
-	private File source=null;
-	
-	public HProfFile(IDataProvider provider) {
-		this.mainProvider = provider;
-	}
-
-	public byte[] peek(IDataProvider dumpRecordProvider, int i)
-			throws IOException {
-		long loc = dumpRecordProvider.getCurrentLocation();
-		long bytesLeft = dumpRecordProvider.getDataLength()
-				- dumpRecordProvider.getCurrentLocation();
-		if (i > bytesLeft)
-			i = (int) bytesLeft;
-		byte[] b = dumpRecordProvider.readBytes(i);
-		dumpRecordProvider.moveTo(loc);
-		return b;
-	}
-
-	private void buildHeader() throws IOException {
-
-		try {
-			header = mainProvider.readCString();
-		} catch (IOException ioe) {
-			throw new InvalidFileFormat("File is not an HPROF file", ioe);
-		}
-		if (header.equals("JAVA PROFILE 1.0.1") == false
-				&& header.equals("JAVA PROFILE 1.0.2") == false) {
-			throw new InvalidFileFormat("File is not an HPROF file");
-		}
-		try {
-			idSize = mainProvider.readU4();
-			timeStamp = mainProvider.readU8();
-		} catch (IOException ioe) {
-			throw new InvalidFileFormat("HPROF file is truncated", ioe);
-		}
-		sizes = new HProfDataTypeSizes(idSize);
-
-		recordsOffset = mainProvider.getCurrentLocation();
-		long maxOffsetLength = mainProvider.getDataLength() - recordsOffset;
-		SubsetDataProvider subset = new SubsetDataProvider(mainProvider,
-				maxOffsetLength);
-		array = new BitMaskMappingArray(1000, 25, new HPROFRecordProvider(
-				subset));
-
-	}
-
-	public void close() throws IOException {
-		mainProvider.close();
-
-	}
-
-	public String getHeader() {
-
-		return header;
-	}
-
-	public Integer getIdentifierSize() {
-
-		return idSize;
-	}
-
-	public long getRecordLocation(int index) {
-		if (index < 0)
-			throw new IllegalArgumentException("record index [" + index
-					+ "] is less than zero");
-		return array.getLocation(index) + recordsOffset + 9; // add 9 for
-		// header bytes
-		// of heap dump
-		// record
-	}
-
-	public IHProfRecord getRecord(int index) {
-
-		if (index < 0)
-			throw new IllegalArgumentException("record index [" + index
-					+ "] is less than zero");
-		return (IHProfRecord) array.get(index);
-	}
-
-	public int getRecordCount() {
-
-		if (records < 0)
-			records = readRecords();
-		return records;
-	}
-
-	public Long getTimeStamp() {
-		return timeStamp;
-	}
-
-	public void open() throws IOException {
-		mainProvider.open();
-		buildHeader();
-	}
-
-	private int readRecords() {
-		int counter = 0;
-		IHProfRecord record = null;
-
-		while (true) {
-			record = getRecord(counter);
-			if (record == null)
-				break;
-			counter++;
-
-		}
-		return counter;
-	}
-
-	class GCRoothreadBlockHeapRecord extends HProfRecord {
-
-		public GCRoothreadBlockHeapRecord(short tag, byte[] data) {
-			super(tag, data);
-		}
-
-		public long getId() {
-			return readNumber(0, idSize);
-		}
-
-		public int getThreadSerialNumber() {
-			return readInt(idSize);
-		}
-
-	}
-
-	class GCRootJavaFrameHeapRecord extends HProfRecord {
-
-		public GCRootJavaFrameHeapRecord(short tag, byte[] data) {
-			super(tag, data);
-		}
-
-		public long getId() {
-			return readNumber(0, idSize);
-		}
-
-		public int getThreadSerialNumber() {
-			return readInt(idSize);
-		}
-
-		public int getStackFrameNumber() {
-			return readInt(idSize + 4);
-		}
-
-	}
-
-	class GCRootJNIGlobalRefHeapRecord extends HProfRecord {
-
-		public GCRootJNIGlobalRefHeapRecord(short tag, byte[] data) {
-			super(tag, data);
-		}
-
-		public long getObjid() {
-			return readNumber(0, idSize);
-		}
-
-		public long getJniid() {
-			return readNumber(idSize, idSize);
-		}
-
-	}
-
-	class GCRootJNILocalHeapRecord extends HProfRecord {
-
-		public GCRootJNILocalHeapRecord(short tag, byte[] data) {
-			super(tag, data);
-
-		}
-
-		public long getId() {
-			return readNumber(0, idSize);
-		}
-
-		public int getThreadSerialNumber() {
-			return readInt(idSize);
-		}
-
-		public int getStackFrameNumber() {
-			return readInt(idSize + 4);
-		}
-
-	}
-
-	public abstract class IDEntryHeapRecord extends HProfRecord {
-
-		public IDEntryHeapRecord(short tag, byte[] data) {
-			super(tag, data);
-
-		}
-
-		public long getID() {
-			return readNumber(0, idSize);
-		}
-	}
-
-	class GCRootMonitorUsedHeapRecord extends IDEntryHeapRecord {
-
-		public GCRootMonitorUsedHeapRecord(short tag, byte[] data) {
-			super(tag, data);
-
-		}
-
-	}
-
-	class GCRootStickyClassHeapRecord extends IDEntryHeapRecord {
-
-		public GCRootStickyClassHeapRecord(short tag, byte[] data) {
-			super(tag, data);
-
-		}
-
-	}
-
-	class GCRootUnknownHeapRecord extends HProfRecord {
-
-		public GCRootUnknownHeapRecord(short tag, byte[] data) {
-			super(tag, data);
-
-		}
-
-	}
-
-	class GCRootThreadObjHeapRecord extends HProfRecord {
-
-		public GCRootThreadObjHeapRecord(short tag, byte[] data) {
-			super(tag, data);
-
-		}
-
-		public long getId() {
-			return readNumber(0, idSize);
-		}
-
-		public int getThreadSequenceNumber() {
-			return readInt(idSize);
-		}
-
-		public int getStackTraceSequenceNumber() {
-			return readInt(idSize + 4);
-		}
-
-	}
-
-	class GCRootNativeStackHeapRecord extends HProfRecord {
-
-		public GCRootNativeStackHeapRecord(short tag, byte[] data) {
-			super(tag, data);
-
-		}
-
-		public long getId() {
-			return readNumber(0, idSize);
-		}
-
-		public int getThreadSequenceNumber() {
-			return readInt(idSize);
-		}
-
-	}
-
-	abstract class LightHeapEntryRecord implements IHProfRecord {
-
-		private IDataProvider lightProvider = null;
-		private short tag = 0;
-
-		public LightHeapEntryRecord(short tag, IDataProvider provider) {
-			this.tag = tag;
-			this.lightProvider = provider;
-		}
-
-		@Override
-		public byte[] getData() {
-			try {
-				return peek(lightProvider, (int)Math.min(200, this.getDataLength()));
-			} catch (IOException e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
-			}
-			return null;
-		}
-
-		public short getTag() {
-			return tag;
-		}
-
-		public long getDataLength() {
-
-			try {
-				return lightProvider.getDataLength();
-			} catch (IOException e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
-			}
-			return -1;
-		}
-
-		public IDataProvider getProvider() {
-			return lightProvider;
-		}
-
-		protected long readLong(int offset) {			
-			try {
-				lightProvider.moveTo(offset);
-				return lightProvider.readU8();
-			} catch (IOException e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
-			}
-			return -1;
-
-		}
-
-		protected int readInt(int offset) {
-			try {
-				lightProvider.moveTo(offset);
-				return lightProvider.readU4();
-			} catch (IOException e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
-			}
-			return -1;
-
-		}
-
-		protected short readByte(int offset) {
-			try {
-				lightProvider.moveTo(offset);
-				return lightProvider.readByte();
-			} catch (IOException e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
-			}
-			return -1;
-
-		}
-
-		protected char readChar(int offset) {
-			try {
-				lightProvider.moveTo(offset);
-				return (char)lightProvider.readU2();
-			} catch (IOException e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
-			}
-			return (char)-1;
-
-		}
-		
-		protected short readShort(int offset) {
-			try {
-				lightProvider.moveTo(offset);
-				return lightProvider.readU2();
-			} catch (IOException e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
-			}
-			return -1;
-		}
-
-		protected long readNumber(int offset, int length) {
-			try {
-				lightProvider.moveTo(offset);
-				return DataReader.readNumber(lightProvider, length);
-			} catch (IOException e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
-			}
-			return -1;
-
-		}
-
-		protected byte[] readBytes(int offset, int length) {
-			try {
-				lightProvider.moveTo(offset);
-				return lightProvider.readBytes(length);
-			} catch (IOException e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
-			}
-			return null;
-		}
-		
-		@Override
-		public String toString() {
-			StringBuffer output = new StringBuffer("LightHeapRecord: Tag: 0x");
-			output.append(Long.toHexString(getTag()));
-			output.append(", length:");
-			output.append(getDataLength());
-			output.append(", Data:");
-			for (int i=0; i < getDataLength(); i++) {
-				short val = (short) (((short)readByte(i))&0xff);
-				if (val <= 0xf) {
-					output.append('0');
-				}
-				output.append(Integer.toHexString(val));
-			}
-			
-			return output.toString();
-		}
-	}
-
-	class GCPrimitiveArrayHeapDumpRecord extends LightHeapEntryRecord  implements IGCPrimitiveArrayHeapDumpRecord {
-
-		public GCPrimitiveArrayHeapDumpRecord(short tag, IDataProvider provider) {
-			super(tag, provider);
-
-		}
-
-		@Override
-		public long getID() {
-			return readNumber(0, idSize);
-		}
-
-		@Override
-		public int getStackTraceNumber() {
-			return readInt(idSize);
-		}
-
-		@Override
-		public int getNumberOfElements() {
-			return readInt(idSize + 4);
-		}
-
-		@Override
-		public short getElementType() {
-			return readByte(idSize + 8);
-		}
-
-		@Override
-		public boolean getBooleanElement(int index) {
-			return getByteElement(index) == 0;
-		}
-		
-		@Override
-		public short getByteElement(int index) {
-			return readByte(idSize+9+index);
-		}
-		
-		@Override
-		public short getShortElement(int index) {
-			return readShort(idSize+ 9 + index * 2);
-		}
-		
-		@Override
-		public char getCharElement(int index) {
-			return readChar(idSize+ 9 + index * 2);
-		}
-		
-		@Override
-		public int getIntElement(int index) {
-			return readInt(idSize+ 9 + index * 4);
-		}
-		
-		@Override
-		public long getLongElement(int index) {
-			return readLong(idSize+ 9 + index * 8);
-		}
-		
-		@Override
-		public float getFloatElement(int index) {
-			return Float.intBitsToFloat(getIntElement(index));
-		}
-		
-		@Override
-		public double getDoubleElement(int index) {
-			return Double.longBitsToDouble(getLongElement(index));
-		}
-	}
-
-	/**
-	 * An array of references on the heap.
-	 * 
-	 */
-	class GCObjectArrayHeapDumpRecord extends LightHeapEntryRecord implements IGCObjectArrayHeapDumpRecord {
-
-		public GCObjectArrayHeapDumpRecord(short tag, IDataProvider provider) {
-			super(tag, provider);
-
-		}
-
-		@Override
-		public long getID() {
-			return readNumber(0, idSize);
-		}
-
-		@Override
-		public int getStackTraceNumber() {
-			return readInt(idSize);
-		}
-
-		@Override
-		public int getNumberOfElements() {
-			return readInt(idSize + 4);
-		}
-
-		@Override
-		public long getArrayClassObjectID() {
-			return readNumber(idSize + 8, idSize);
-		}
-		
-		@Override
-		public long getElement(int index) {
-			return readNumber(idSize*2+8 + index * idSize, idSize);
-		}
-
-
-		@Override
-		public String toString() {
-			StringBuffer output = new StringBuffer(super.toString()); 
-			output.append("\nReferences: ");
-			for (int i=0; i < getNumberOfElements(); i++) {
-				output.append("0x").append(Long.toHexString(getElement(i))).append(' ');
-			}
-			
-			return output.toString();
-		}
-	}
-
-	/**
-	 * An ordinary object instance on the heap.
-	 *
-	 */
-	class GCInstanceHeapDumpRecord extends LightHeapEntryRecord implements IGCInstanceHeapDumpRecord {
-
-		public GCInstanceHeapDumpRecord(short tag, IDataProvider provider) {
-			super(tag, provider);
-
-		}
-
-		public long getID() {
-			return readNumber(0, idSize);
-		}
-
-		public int getStackTraceNumber() {
-			return readInt(idSize);
-		}
-
-		public long getClassObjectID() {
-			return readNumber(idSize + 4, idSize);
-		}
-
-		public int getNumberOfValueBytes() {
-			return readInt((idSize * 2) + 4);
-		}
-
-		@Override
-		public byte getByteField(int offset) {
-			return (byte) readByte((idSize*2 + 8) + offset);
-		}
-
-		@Override
-		public char getCharField(int offset) {
-			return readChar((idSize*2 + 8) + offset);
-		}
-
-		@Override
-		public double getDoubleField(int offset) {
-			return Double.longBitsToDouble(readLong((idSize*2 + 8) + offset));
-		}
-
-		@Override
-		public float getFloatField(int offset) {
-			return Float.intBitsToFloat(readInt((idSize*2 + 8) + offset));
-		}
-
-		@Override
-		public long getIDField(int offset) {		
-			return readNumber((idSize*2 + 8) + offset,idSize);
-		}
-
-		@Override
-		public int getIntegerField(int offset) {
-			return readInt((idSize*2 + 8) + offset);
-		}
-
-		@Override
-		public long getLongField(int offset) {	
-			return readLong((idSize*2 + 8) + offset);
-		}
-
-		@Override
-		public short getShortField(int offset) {
-			return readShort((idSize*2 + 8) + offset);
-		}
-
-		@Override
-		public boolean getBooleanField(int offset) {
-			return !(getByteField(offset) == 0);
-		}
-
-	}
-
-	public class GCClassHeapDumpRecord extends LightHeapEntryRecord implements IGCClassHeapDumpRecord, IHeapObject {
-
-		private int staticFieldsOffset;
-		private int instFieldsOffset;
-
-		public GCClassHeapDumpRecord(byte tag, IDataProvider provider
-				, int staticFieldsOffset, int instFieldsOffset ) {
-			super(tag, provider);
-			
-			this.staticFieldsOffset = staticFieldsOffset;
-			this.instFieldsOffset = instFieldsOffset;
-		}
-
-		public long getID() {
-			return readNumber(0, idSize);
-		}
-
-		public int getStackTraceNumber() {
-			return readInt(idSize);
-		}
-
-		public long getSuperClassObjectID() {
-			return readNumber(idSize + 4, idSize);
-		}
-
-		public long getClassLoaderObjectID() {
-			return readNumber((idSize * 2) + 4, idSize);
-		}
-
-		public long getSignersObjectID() {
-			return readNumber((idSize * 3) + 4, idSize);
-		}
-
-		public long getProtectionDomainObjectID() {
-			return readNumber((idSize * 4) + 4, idSize);
-		}
-
-		public int getInstanceSize() {
-			return readInt((idSize * 7) + 4);
-		}
-
-		public int getConstantPoolSize() {
-			return readShort((idSize * 7) + 8);
-		}
-
-		public ConstantPoolEntry[] getConstantPool() {
-			return readConstantPool((idSize * 7) + 10);
-		}
-
-		private ConstantPoolEntry[] readConstantPool(int offset) {
-			int entries = getConstantPoolSize();
-			ConstantPoolEntry[] pool = new ConstantPoolEntry[entries];
-			for (int i = 0; i < entries; i++) {
-				ConstantPoolEntry cpe = new ConstantPoolEntry();
-				cpe.cpIndex = readShort(offset);
-				offset += 2;
-				cpe.type = readByte(offset);
-				offset++;
-				int valueLength = sizes.getLengthFromType(cpe.type);
-				cpe.data = readBytes(offset, valueLength);
-				offset += valueLength;
-				pool[i] = cpe;
-			}
-			return pool;
-		}
-
-		public StaticFieldEntry[] getStaticFields() {
-			return readStaticFields(staticFieldsOffset);			
-		}
-		
-		private StaticFieldEntry[] readStaticFields(int offset) {
-			short staticFields = readShort(offset-2);
-			
-			StaticFieldEntry[] fields = new StaticFieldEntry[staticFields];
-			for (int i = 0; i < staticFields; i++) {
-				long stringID = readNumber(offset,idSize);
-				offset += idSize;
-				short type = readByte(offset);
-				offset+=1;
-				int arrayLength = sizes.getLengthFromType(type);
-				long data = readNumber(offset, arrayLength);
-				offset += arrayLength;
-				
-				fields[i] = new StaticFieldEntry(stringID, type, data);
-			}
-			
-			return fields;
-		}
-		
-		public InstanceFieldEntry[] getInstanceFields() {
-			return readInstanceFields(instFieldsOffset);
-		}
-
-		private InstanceFieldEntry[] readInstanceFields(int offset) {
-			short instFields = readShort(offset-2);
-			int fieldOffset = 0;
-			InstanceFieldEntry[] fields = new InstanceFieldEntry[instFields];
-			
-			for (int i = 0; i < instFields; i++) {
-				long stringID = readNumber(offset,idSize);
-				offset += idSize;
-				
-				short type = readByte(offset);
-				offset+=1;
-								
-				fields[i] = new InstanceFieldEntry(stringID, type, fieldOffset);
-				fieldOffset += sizes.getLengthFromType(type);
-			}
-			offsetSize = fieldOffset;
-			return fields;
-		}
-
-		private int offsetSize=-1;
-		@Override
-		public int getOffsetSize() {
-			if(offsetSize == -1) {
-				getInstanceFields();
-			}
-			return offsetSize;
-		}
-		
-	}
-
-	public void setSource(File source) {
-		this.source=source;
-		
-	}
-
-	public File getSource() {
-		return source;
-	}
-}
+/*******************************************************************************
+ * Licensed 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 org.apache.kato.hprof.datalayer;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.util.List;
+
+import org.apache.kato.common.BitMaskMappingArray;
+import org.apache.kato.common.DataProviderBackedArrayProvider;
+import org.apache.kato.common.DataReader;
+import org.apache.kato.common.IArrayEntryProvider;
+import org.apache.kato.common.IDataProvider;
+import org.apache.kato.common.InvalidFileFormat;
+import org.apache.kato.common.SubsetDataProvider;
+import org.apache.kato.hprof.HProfRecordFormatter;
+ 
+public class HProfFile {
+
+	class ControlSettingsHProfRecord extends HProfRecord implements
+			IControlSettingsHProfRecord {
+
+		public ControlSettingsHProfRecord(short tag, byte[] data) {
+			super(tag, data);
+
+		}
+
+		public short getStackTraceDepth() {
+			return readShort(4);
+		}
+
+		public boolean isAllocTrace() {
+			return (readInt(0) & 1) == 1;
+		}
+
+		public boolean isCpuSampling() {
+			return (readInt(0) & 2) == 2;
+		}
+	}
+
+	class EndThreadHProfRecord extends HProfRecord implements
+			IThreadEndingHProfRecord {
+
+		public EndThreadHProfRecord(short tag, byte[] data) {
+			super(tag, data);
+
+		}
+
+		public int getThreadSerialNumber() {
+			return readInt(0);
+		}
+	}
+
+	class FrameHProfRecord extends HProfRecord implements
+			IJavaStackFrameHProfRecord {
+
+		public FrameHProfRecord(short tag, byte[] data) {
+			super(tag, data);
+
+		}
+
+		public int getClassSerialNumber() {
+			return readInt(idSize * 4);
+		}
+
+		public int getLineNumber() {
+			return readInt((idSize * 4) + 4);
+		}
+
+		public long getMethodNameID() {
+			return readNumber(idSize, idSize);
+		}
+
+		public long getMethodSignatureID() {
+			return readNumber(idSize + idSize, idSize);
+		}
+
+		public long getSourceFileNameID() {
+			return readNumber(idSize + idSize + idSize, idSize);
+		}
+
+		public long getStackFrameID() {
+			return readNumber(0, idSize);
+		}
+
+		/**
+		 * Check equality based on stack frame ID.
+		 */
+		public boolean equals(Object obj) {
+			if ((obj == null) || !(obj instanceof FrameHProfRecord)) {
+				return false;
+			}
+			
+			FrameHProfRecord record = (FrameHProfRecord) obj;
+			
+			return record.getStackFrameID() == getStackFrameID();
+		}
+
+	}
+
+	class HeapDumpHProfRecord extends HProfRecord implements
+			IHeapDumpHProfRecord {
+
+		private BitMaskMappingArray subRecordArray = null;
+		private int subRecordCount = -1;
+		private long size = 0;
+		private IDataProvider myP = null;
+
+		public HeapDumpHProfRecord(short tag, IDataProvider dataProvider)
+				throws IOException {
+			super(tag, null);
+			size = dataProvider.getDataLength();
+			myP = dataProvider;
+			subRecordArray = new BitMaskMappingArray(1000, 25,
+					new HProfDumpRecordArrayProvider(dataProvider));
+		}
+
+		public IHProfRecord getSubRecord(int index) {
+
+			return (IHProfRecord) subRecordArray.get(index);
+		}
+
+		@Override
+		public int getSubRecordCount() {
+			if (subRecordCount == -1) {
+
+				subRecordCount = 0;
+				while (true) {
+					if (subRecordCount == 5) {
+						int a = 1;
+					}
+					Object o = subRecordArray.get(subRecordCount);
+					if (o == null)
+						break;
+					subRecordCount++;
+					if (o instanceof UnknownHProfRecord) {
+						break;
+					}
+				}
+
+			}
+			return subRecordCount;
+		}
+
+		@Override
+		public long getDataLength() {
+			return (int) size;
+		}
+
+		@Override
+		public byte[] getData() {
+			try {
+				return peek(myP, 20);
+			} catch (IOException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+			return null;
+		}
+
+		@Override
+		public long getSubRecordLocation(int index) {
+			return subRecordArray.getLocation(index);
+		}
+
+		@Override
+		/**
+		 * Return a record by its locations
+		 * 
+		 * @param location
+		 * @return IHProfRecord at given location
+		 */
+		public IHProfRecord getSubRecordByLocation(long location) {		
+			return (IHProfRecord) subRecordArray.getAtLocation(location);
+		}
+	}
+
+	private final class HProfDumpRecordArrayProvider extends
+			DataProviderBackedArrayProvider {
+		private HProfDumpRecordArrayProvider(IDataProvider provider) {
+			super(provider);
+		}
+
+		private IHProfRecord buildClassDumpRecord(int tag,
+				IDataProvider dumpRecordProvider) throws IOException {
+
+			long loc = dumpRecordProvider.getCurrentLocation();
+			dumpRecordProvider.moveBy((idSize * 7) + 8);
+			short elements = dumpRecordProvider.readU2(); // size of constant
+			// pool
+			int constantPoolIndex = (int)(dumpRecordProvider.getCurrentLocation()
+					- loc);
+			for (int i = 0; i < elements; i++) {
+				short cpIndex = dumpRecordProvider.readU2();
+				short type = dumpRecordProvider.readByte();
+				int arrayLength = sizes.getLengthFromType(type);
+				dumpRecordProvider.moveBy(arrayLength);
+			}
+
+			short staticFields = dumpRecordProvider.readU2();
+						
+			int staticFieldsIndex = (int)(dumpRecordProvider.getCurrentLocation()- loc);
+			for (int i = 0; i < staticFields; i++) {
+				long index = DataReader.readNumber(dumpRecordProvider, idSize);
+				short type = dumpRecordProvider.readByte();
+				int arrayLength = sizes.getLengthFromType(type);
+				dumpRecordProvider.moveBy(arrayLength);
+			}
+
+			short instFields = dumpRecordProvider.readU2();
+
+			int instFieldsIndex = (int) (dumpRecordProvider.getCurrentLocation()- loc);
+			for (int i = 0; i < instFields; i++) {
+				long index = DataReader.readNumber(dumpRecordProvider, idSize);
+				short type = dumpRecordProvider.readByte();
+			}
+
+			long datalength = dumpRecordProvider.getCurrentLocation() - loc;
+			SubsetDataProvider p = new SubsetDataProvider(dumpRecordProvider,
+					loc, datalength);
+
+			// Pass indices of static and instance fields - they are variable length.
+			return new GCClassHeapDumpRecord((byte) tag, p, staticFieldsIndex, instFieldsIndex );
+
+		}
+
+		@Override
+		public Object getCurrentElement() {
+			// read tag
+			try {
+				long l = getProvider().getCurrentLocation();
+
+				IDataProvider p = getProvider();
+				if (p.dataRemaining() < 1)
+					return null;
+				short tag = p.readByte();
+				int size = getRecordSize(tag);
+				byte[] data = null;
+				if (size >= 0) {
+					data = getProvider().readBytes(size);
+				}
+
+				switch (tag) {
+				case 0xFF: // unknown root
+					return new GCRootUnknownHeapRecord(tag, data);
+
+				case 0x01: // jni global root
+
+					return new GCRootJNIGlobalRefHeapRecord(tag, data);
+
+				case 0x02: // jni local
+					return new GCRootJNILocalHeapRecord(tag, data);
+
+				case 0x03: // java frame
+					return new GCRootJavaFrameHeapRecord(tag, data);
+
+				case 0x04: // native stack root
+					return new GCRootNativeStackHeapRecord(tag, data);
+
+				case 0x05: // stick class root
+					return new GCRootStickyClassHeapRecord(tag, data);
+
+				case 0x06: // thread block root
+					return new GCRoothreadBlockHeapRecord(tag, data);
+
+				case 0x07: // monitor used
+					return new GCRootMonitorUsedHeapRecord(tag, data);
+
+				case 0x08: // thread obj root
+					return new GCRootThreadObjHeapRecord(tag, data);
+
+				case 0x20: // class dump
+					return buildClassDumpRecord(tag, getProvider());
+				case 0x21: // instance
+					return buildInstanceDumpRecord(tag, getProvider());
+
+				case 0x22: // obj array
+					return buildObjArrayDumpRecord(tag, getProvider());
+				case 0x23: // primitive array
+					return buildPrimitiveArrayDumpRecord(tag, getProvider());
+
+				default:
+					// don't know what this is
+					return new UnknownHProfRecord(tag, null);
+
+				}
+
+			} catch (IOException e) {
+				e.printStackTrace();
+				return null;
+			}
+
+		}
+
+		private Object buildPrimitiveArrayDumpRecord(short tag,
+				IDataProvider arrayProvider) throws IOException {
+
+			long loc = arrayProvider.getCurrentLocation();
+			arrayProvider.moveBy(idSize + 4);
+			int elements = arrayProvider.readU4();
+			short elementType = arrayProvider.readByte();
+
+			int elementLength = sizes.getLengthFromType(elementType);
+			int datalength = idSize + 9 + (elementLength * elements);
+			arrayProvider.moveTo(loc);
+			SubsetDataProvider p = new SubsetDataProvider(arrayProvider,
+					datalength);
+			arrayProvider.moveTo(loc + datalength);
+			return new GCPrimitiveArrayHeapDumpRecord(tag, p);
+		}
+
+		/**
+		 * 
+		 * id array object ID u4 stack trace serial number u4 number of elements
+		 * id array class ID [id]* elements
+		 * 
+		 * @param tag
+		 * @param arrayProvider
+		 * @return
+		 * @throws IOException
+		 */
+		private Object buildObjArrayDumpRecord(short tag,
+				IDataProvider arrayProvider) throws IOException {
+
+			long loc = arrayProvider.getCurrentLocation();
+			arrayProvider.moveBy(idSize + 4);
+			int elements = arrayProvider.readU4();
+			int datalength = (idSize * 2) + 8 + (idSize * elements);
+			arrayProvider.moveTo(loc);
+			SubsetDataProvider p = new SubsetDataProvider(arrayProvider,
+					datalength);
+			arrayProvider.moveTo(loc + datalength);
+			return new GCObjectArrayHeapDumpRecord(tag, p);
+		}
+
+		/**
+		 * id object ID u4 stack trace serial number id class object ID u4
+		 * number of bytes that follow [vl]* instance field values (class,
+		 * followed by super, super's super ...)
+		 * 
+		 * @param tag
+		 * @param arrayProvider
+		 * @return
+		 * @throws IOException
+		 */
+		private Object buildInstanceDumpRecord(short tag,
+				IDataProvider arrayProvider) throws IOException {
+
+			long loc = arrayProvider.getCurrentLocation();
+			arrayProvider.moveBy((idSize * 2) + 4);
+			int byteCount = arrayProvider.readU4();
+			int datalength = (idSize * 2) + 8 + byteCount;
+			arrayProvider.moveTo(loc);
+			SubsetDataProvider p = new SubsetDataProvider(arrayProvider,
+					datalength);
+			arrayProvider.moveTo(loc + datalength);
+			return new GCInstanceHeapDumpRecord(tag, p);
+		}
+
+		/**
+		 * Returns record size for given tag.
+		 * 
+		 * @param tag -
+		 *            tag to size
+		 * @return record size or -1 if dynamic, -2 if unknown tag
+		 */
+		private int getRecordSize(int tag) {
+			int recordLength = 0;
+
+			switch (tag) {
+
+			case 0xFF: // unknown root
+
+				recordLength = idSize;
+				break;
+
+			case 0x01: // jni global root
+
+				recordLength = idSize * 2;
+				break;
+
+			case 0x02: // jni local
+				recordLength = idSize + 8;
+				break;
+
+			case 0x03: // java frame
+				recordLength = idSize + 8;
+				break;
+
+			case 0x04: // native stack root
+				recordLength = idSize + 4;
+				break;
+
+			case 0x05: // stick class root
+				recordLength = idSize;
+				break;
+
+			case 0x06: // thread block root
+				recordLength = idSize + 4;
+				break;
+
+			case 0x07: // monitor used
+				recordLength = idSize;
+				break;
+
+			case 0x08: // thread obj root
+				recordLength = idSize + 8;
+				break;
+
+			case 0x20: // class dump
+			case 0x21: // instance
+			case 0x22: // obj array
+			case 0x23: // primitive array
+				recordLength = -1;
+				break;
+			default:
+				// don't know what this is
+				recordLength = -2;
+
+			}
+			return recordLength;
+		}
+	}
+
+	private final class HPROFRecordProvider implements IArrayEntryProvider {
+
+		private IDataProvider recordProvider = null;
+
+		public HPROFRecordProvider(IDataProvider provider) {
+			this.recordProvider = provider;
+		}
+
+		@Override
+		public IHProfRecord getCurrentElement() {
+
+			// read tag
+			try {
+
+				short tag = recordProvider.readByte();
+				int ms = recordProvider.readU4();
+				int left = recordProvider.readU4();
+				byte[] data = null;
+
+				switch (tag) {
+				case 0x0c:
+					break;
+				default:
+
+					data = recordProvider.readBytes(left);
+
+				}
+
+				switch (tag) {
+
+				case 0x01:
+
+					return new UTF8HProfRecordImpl(tag, data);
+				case 0x02:
+					return new LoadClassHProfRecord(tag, data);
+				case 0x03:
+					return new UnloadClassHProfRecord(tag, data);
+				case 0x04:
+					return new FrameHProfRecord(tag, data);
+				case 0x05:
+					return new TraceHProfRecord(tag, data);
+				case 0x0e:
+					return new ControlSettingsHProfRecord(tag, data);
+
+				case 0x0a:
+					return new StartThreadHProfRecord(tag, data);
+				case 0x0b:
+					return new EndThreadHProfRecord(tag, data);
+
+				case 0x0c:
+					IHeapDumpHProfRecord rec = new HeapDumpHProfRecord(tag,
+							new SubsetDataProvider(recordProvider, left));
+					recordProvider.moveBy(left);
+					return rec;
+				default:
+					// don't know what the thing is - return an unknown
+					// type.
+
+					return new UnknownHProfRecord(tag, data);
+				}
+
+			} catch (IOException e) {
+				return null;
+			}
+
+		}
+
+		@Override
+		public long getCurrentLocation() {
+
+			try {
+				return recordProvider.getCurrentLocation();
+			} catch (IOException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+			return -1;
+		}
+
+		@Override
+		public void getState(List state) {
+
+			state.add("HProfRecordProvider");
+			recordProvider.addState(state);
+
+		}
+
+		@Override
+		public boolean moveRelativeElement(int seekNo) {
+
+			while (seekNo > 0) {
+				Object o = getCurrentElement();
+				if (o == null)
+					return false;
+				seekNo--;
+			}
+			return true;
+		}
+
+		@Override
+		public boolean moveToLocation(long l) {
+
+			try {
+				recordProvider.moveTo(l);
+				return true;
+			} catch (IOException e) {
+				return false;
+			}
+		}
+	}
+
+	class LoadClassHProfRecord extends HProfRecord implements
+			ILoadClassHProfRecord {
+
+		public LoadClassHProfRecord(short tag, byte[] data) {
+			super(tag, data);
+
+		}
+
+		public long getClassNameID() {
+			return readNumber(8 + idSize, idSize);
+		}
+
+		public long getClassObjectID() {
+			return readNumber(4, idSize);
+		}
+
+		public int getClassSerialNumber() {
+			return readInt(0);
+		}
+
+		public int getStackTraceSerialNumber() {
+			return readInt(4 + idSize);
+		}
+	}
+
+	class UnloadClassHProfRecord extends HProfRecord implements
+			IUnloadClassHProfRecord {
+
+		public UnloadClassHProfRecord(short tag, byte[] data) {
+			super(tag, data);
+
+		}
+
+		public int getClassSerialNumber() {
+			return readInt(0);
+		}
+	}
+
+	class StartThreadHProfRecord extends HProfRecord implements
+			IThreadActiveHProfRecord {
+
+		public StartThreadHProfRecord(short tag, byte[] data) {
+			super(tag, data);
+
+		}
+
+		public int getStackTraceSerialNumber() {
+			return readInt(idSize + 4);
+		}
+
+		public long getThreadGroupNameID() {
+			return readNumber(8 + (idSize * 2), idSize);
+
+		}
+
+		public long getThreadGroupParentNameID() {
+			return readNumber(8 + (idSize * 3), idSize);
+		}
+
+		public long getThreadNameID() {
+			return readNumber(8 + idSize, idSize);
+		}
+
+		public long getThreadObjectID() {
+			return readNumber(4, idSize);
+		}
+
+		public int getThreadSerialNumber() {
+			return readInt(0);
+		}
+	}
+
+	class TraceHProfRecord extends HProfRecord implements
+			IJavaStackTraceHProfRecord {
+
+		public TraceHProfRecord(short tag, byte[] data) {
+			super(tag, data);
+		}
+
+		public int getFrameCount() {
+			return readInt(8);
+		}
+
+		public int getSerialNumber() {
+			return readInt(0);
+		}
+
+		public long getStackFrameID(int elementNo) {
+			return readNumber((idSize * elementNo) + 12, idSize);
+		}
+
+		public int getThreadSerialNumber() {
+			return readInt(4);
+		}
+	}
+
+	class UnknownHProfRecord extends HProfRecord {
+
+		public UnknownHProfRecord(short tag, byte[] data) {
+			super(tag, data);
+
+		}
+
+	}
+
+	class UTF8HProfRecordImpl extends HProfRecord implements IUTF8HProfRecord {
+
+		public UTF8HProfRecordImpl(short tag, byte[] data) {
+			super(tag, data);
+
+		}
+
+		@Override
+		public String getAsString() {
+
+			try {
+				return new String(getCharacters(), "UTF-8");
+			} catch (UnsupportedEncodingException e) {
+
+				return null;
+			}
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see org.apache.kato.hprof.IUTF8HProfRecord#getCharacters()
+		 */
+		public byte[] getCharacters() {
+
+			int length = ((int) getDataLength()) - idSize;
+			return readBytes(idSize, length);
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see org.apache.kato.hprof.IUTF8HProfRecord#getNameID()
+		 */
+		public long getNameID() {
+			return readNumber(0, idSize);
+		}
+	}
+
+	private BitMaskMappingArray array = null;
+
+	private String header = null;
+
+	private Integer idSize = null;
+	private HProfDataTypeSizes sizes = null;
+
+	private IDataProvider mainProvider = null;
+
+	private int records = -1;
+	private long recordsOffset = 0;
+
+	private Long timeStamp = null;
+
+	private File source=null;
+	
+	public HProfFile(IDataProvider provider) {
+		this.mainProvider = provider;
+	}
+
+	public byte[] peek(IDataProvider dumpRecordProvider, int i)
+			throws IOException {
+		long loc = dumpRecordProvider.getCurrentLocation();
+		long bytesLeft = dumpRecordProvider.getDataLength()
+				- dumpRecordProvider.getCurrentLocation();
+		if (i > bytesLeft)
+			i = (int) bytesLeft;
+		byte[] b = dumpRecordProvider.readBytes(i);
+		dumpRecordProvider.moveTo(loc);
+		return b;
+	}
+
+	private void buildHeader() throws IOException {
+
+		try {
+			header = mainProvider.readCString();
+		} catch (IOException ioe) {
+			throw new InvalidFileFormat("File is not an HPROF file", ioe);
+		}
+		if (header.equals("JAVA PROFILE 1.0.1") == false
+				&& header.equals("JAVA PROFILE 1.0.2") == false) {
+			throw new InvalidFileFormat("File is not an HPROF file");
+		}
+		try {
+			idSize = mainProvider.readU4();
+			timeStamp = mainProvider.readU8();
+		} catch (IOException ioe) {
+			throw new InvalidFileFormat("HPROF file is truncated", ioe);
+		}
+		sizes = new HProfDataTypeSizes(idSize);
+
+		recordsOffset = mainProvider.getCurrentLocation();
+		long maxOffsetLength = mainProvider.getDataLength() - recordsOffset;
+		SubsetDataProvider subset = new SubsetDataProvider(mainProvider,
+				maxOffsetLength);
+		array = new BitMaskMappingArray(1000, 25, new HPROFRecordProvider(
+				subset));
+
+	}
+
+	public void close() throws IOException {
+		mainProvider.close();
+
+	}
+
+	public String getHeader() {
+
+		return header;
+	}
+
+	public Integer getIdentifierSize() {
+
+		return idSize;
+	}
+
+	public long getRecordLocation(int index) {
+		if (index < 0)
+			throw new IllegalArgumentException("record index [" + index
+					+ "] is less than zero");
+		return array.getLocation(index) + recordsOffset + 9; // add 9 for
+		// header bytes
+		// of heap dump
+		// record
+	}
+
+	public IHProfRecord getRecord(int index) {
+
+		if (index < 0)
+			throw new IllegalArgumentException("record index [" + index
+					+ "] is less than zero");
+		return (IHProfRecord) array.get(index);
+	}
+
+	public int getRecordCount() {
+
+		if (records < 0)
+			records = readRecords();
+		return records;
+	}
+
+	public Long getTimeStamp() {
+		return timeStamp;
+	}
+
+	public void open() throws IOException {
+		mainProvider.open();
+		buildHeader();
+	}
+
+	private int readRecords() {
+		int counter = 0;
+		IHProfRecord record = null;
+
+		while (true) {
+			record = getRecord(counter);
+			if (record == null)
+				break;
+			counter++;
+
+		}
+		return counter;
+	}
+
+	class GCRoothreadBlockHeapRecord extends HProfRecord {
+
+		public GCRoothreadBlockHeapRecord(short tag, byte[] data) {
+			super(tag, data);
+		}
+
+		public long getId() {
+			return readNumber(0, idSize);
+		}
+
+		public int getThreadSerialNumber() {
+			return readInt(idSize);
+		}
+
+	}
+
+	class GCRootJavaFrameHeapRecord extends HProfRecord {
+
+		public GCRootJavaFrameHeapRecord(short tag, byte[] data) {
+			super(tag, data);
+		}
+
+		public long getId() {
+			return readNumber(0, idSize);
+		}
+
+		public int getThreadSerialNumber() {
+			return readInt(idSize);
+		}
+
+		public int getStackFrameNumber() {
+			return readInt(idSize + 4);
+		}
+
+	}
+
+	class GCRootJNIGlobalRefHeapRecord extends HProfRecord {
+
+		public GCRootJNIGlobalRefHeapRecord(short tag, byte[] data) {
+			super(tag, data);
+		}
+
+		public long getObjid() {
+			return readNumber(0, idSize);
+		}
+
+		public long getJniid() {
+			return readNumber(idSize, idSize);
+		}
+
+	}
+
+	class GCRootJNILocalHeapRecord extends HProfRecord {
+
+		public GCRootJNILocalHeapRecord(short tag, byte[] data) {
+			super(tag, data);
+
+		}
+
+		public long getId() {
+			return readNumber(0, idSize);
+		}
+
+		public int getThreadSerialNumber() {
+			return readInt(idSize);
+		}
+
+		public int getStackFrameNumber() {
+			return readInt(idSize + 4);
+		}
+
+	}
+
+	public abstract class IDEntryHeapRecord extends HProfRecord {
+
+		public IDEntryHeapRecord(short tag, byte[] data) {
+			super(tag, data);
+
+		}
+
+		public long getID() {
+			return readNumber(0, idSize);
+		}
+	}
+
+	class GCRootMonitorUsedHeapRecord extends IDEntryHeapRecord {
+
+		public GCRootMonitorUsedHeapRecord(short tag, byte[] data) {
+			super(tag, data);
+
+		}
+
+	}
+
+	class GCRootStickyClassHeapRecord extends IDEntryHeapRecord {
+
+		public GCRootStickyClassHeapRecord(short tag, byte[] data) {
+			super(tag, data);
+
+		}
+
+	}
+
+	class GCRootUnknownHeapRecord extends HProfRecord {
+
+		public GCRootUnknownHeapRecord(short tag, byte[] data) {
+			super(tag, data);
+
+		}
+
+	}
+
+	class GCRootThreadObjHeapRecord extends HProfRecord {
+
+		public GCRootThreadObjHeapRecord(short tag, byte[] data) {
+			super(tag, data);
+
+		}
+
+		public long getId() {
+			return readNumber(0, idSize);
+		}
+
+		public int getThreadSequenceNumber() {
+			return readInt(idSize);
+		}
+
+		public int getStackTraceSequenceNumber() {
+			return readInt(idSize + 4);
+		}
+
+	}
+
+	class GCRootNativeStackHeapRecord extends HProfRecord {
+
+		public GCRootNativeStackHeapRecord(short tag, byte[] data) {
+			super(tag, data);
+
+		}
+
+		public long getId() {
+			return readNumber(0, idSize);
+		}
+
+		public int getThreadSequenceNumber() {
+			return readInt(idSize);
+		}
+
+	}
+
+	abstract class LightHeapEntryRecord implements IHProfRecord {
+
+		private IDataProvider lightProvider = null;
+		private short tag = 0;
+
+		public LightHeapEntryRecord(short tag, IDataProvider provider) {
+			this.tag = tag;
+			this.lightProvider = provider;
+		}
+
+		@Override
+		public byte[] getData() {
+			try {
+				return peek(lightProvider, (int)Math.min(200, this.getDataLength()));
+			} catch (IOException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+			return null;
+		}
+
+		public short getTag() {
+			return tag;
+		}
+
+		public long getDataLength() {
+
+			try {
+				return lightProvider.getDataLength();
+			} catch (IOException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+			return -1;
+		}
+
+		public IDataProvider getProvider() {
+			return lightProvider;
+		}
+
+		protected long readLong(int offset) {			
+			try {
+				lightProvider.moveTo(offset);
+				return lightProvider.readU8();
+			} catch (IOException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+			return -1;
+
+		}
+
+		protected int readInt(int offset) {
+			try {
+				lightProvider.moveTo(offset);
+				return lightProvider.readU4();
+			} catch (IOException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+			return -1;
+
+		}
+
+		protected short readByte(int offset) {
+			try {
+				lightProvider.moveTo(offset);
+				return lightProvider.readByte();
+			} catch (IOException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+			return -1;
+
+		}
+
+		protected char readChar(int offset) {
+			try {
+				lightProvider.moveTo(offset);
+				return (char)lightProvider.readU2();
+			} catch (IOException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+			return (char)-1;
+
+		}
+		
+		protected short readShort(int offset) {
+			try {
+				lightProvider.moveTo(offset);
+				return lightProvider.readU2();
+			} catch (IOException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+			return -1;
+		}
+
+		protected long readNumber(int offset, int length) {
+			try {
+				lightProvider.moveTo(offset);
+				return DataReader.readNumber(lightProvider, length);
+			} catch (IOException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+			return -1;
+
+		}
+
+		protected byte[] readBytes(int offset, int length) {
+			try {
+				lightProvider.moveTo(offset);
+				return lightProvider.readBytes(length);
+			} catch (IOException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+			return null;
+		}
+		
+		@Override
+		public String toString() {
+			StringBuffer output = new StringBuffer("LightHeapRecord: Tag: 0x");
+			output.append(Long.toHexString(getTag()));
+			output.append(", length:");
+			output.append(getDataLength());
+			output.append(", Data:");
+			for (int i=0; i < getDataLength(); i++) {
+				short val = (short) (((short)readByte(i))&0xff);
+				if (val <= 0xf) {
+					output.append('0');
+				}
+				output.append(Integer.toHexString(val));
+			}
+			
+			return output.toString();
+		}
+	}
+
+	class GCPrimitiveArrayHeapDumpRecord extends LightHeapEntryRecord  implements IGCPrimitiveArrayHeapDumpRecord {
+
+		public GCPrimitiveArrayHeapDumpRecord(short tag, IDataProvider provider) {
+			super(tag, provider);
+
+		}
+
+		@Override
+		public long getID() {
+			return readNumber(0, idSize);
+		}
+
+		@Override
+		public int getStackTraceNumber() {
+			return readInt(idSize);
+		}
+
+		@Override
+		public int getNumberOfElements() {
+			return readInt(idSize + 4);
+		}
+
+		@Override
+		public short getElementType() {
+			return readByte(idSize + 8);
+		}
+
+		@Override
+		public boolean getBooleanElement(int index) {
+			return getByteElement(index) == 0;
+		}
+		
+		@Override
+		public short getByteElement(int index) {
+			return readByte(idSize+9+index);
+		}
+		
+		@Override
+		public short getShortElement(int index) {
+			return readShort(idSize+ 9 + index * 2);
+		}
+		
+		@Override
+		public char getCharElement(int index) {
+			return readChar(idSize+ 9 + index * 2);
+		}
+		
+		@Override
+		public int getIntElement(int index) {
+			return readInt(idSize+ 9 + index * 4);
+		}
+		
+		@Override
+		public long getLongElement(int index) {
+			return readLong(idSize+ 9 + index * 8);
+		}
+		
+		@Override
+		public float getFloatElement(int index) {
+			return Float.intBitsToFloat(getIntElement(index));
+		}
+		
+		@Override
+		public double getDoubleElement(int index) {
+			return Double.longBitsToDouble(getLongElement(index));
+		}
+	}
+
+	/**
+	 * An array of references on the heap.
+	 * 
+	 */
+	class GCObjectArrayHeapDumpRecord extends LightHeapEntryRecord implements IGCObjectArrayHeapDumpRecord {
+
+		public GCObjectArrayHeapDumpRecord(short tag, IDataProvider provider) {
+			super(tag, provider);
+
+		}
+
+		@Override
+		public long getID() {
+			return readNumber(0, idSize);
+		}
+
+		@Override
+		public int getStackTraceNumber() {
+			return readInt(idSize);
+		}
+
+		@Override
+		public int getNumberOfElements() {
+			return readInt(idSize + 4);
+		}
+
+		@Override
+		public long getArrayClassObjectID() {
+			return readNumber(idSize + 8, idSize);
+		}
+		
+		@Override
+		public long getElement(int index) {
+			return readNumber(idSize*2+8 + index * idSize, idSize);
+		}
+
+
+		@Override
+		public String toString() {
+			StringBuffer output = new StringBuffer(super.toString()); 
+			output.append("\nReferences: ");
+			for (int i=0; i < getNumberOfElements(); i++) {
+				output.append("0x").append(Long.toHexString(getElement(i))).append(' ');
+			}
+			
+			return output.toString();
+		}
+	}
+
+	/**
+	 * An ordinary object instance on the heap.
+	 *
+	 */
+	class GCInstanceHeapDumpRecord extends LightHeapEntryRecord implements IGCInstanceHeapDumpRecord {
+
+		public GCInstanceHeapDumpRecord(short tag, IDataProvider provider) {
+			super(tag, provider);
+
+		}
+
+		public long getID() {
+			return readNumber(0, idSize);
+		}
+
+		public int getStackTraceNumber() {
+			return readInt(idSize);
+		}
+
+		public long getClassObjectID() {
+			return readNumber(idSize + 4, idSize);
+		}
+
+		public int getNumberOfValueBytes() {
+			return readInt((idSize * 2) + 4);
+		}
+
+		@Override
+		public byte getByteField(int offset) {
+			return (byte) readByte((idSize*2 + 8) + offset);
+		}
+
+		@Override
+		public char getCharField(int offset) {
+			return readChar((idSize*2 + 8) + offset);
+		}
+
+		@Override
+		public double getDoubleField(int offset) {
+			return Double.longBitsToDouble(readLong((idSize*2 + 8) + offset));
+		}
+
+		@Override
+		public float getFloatField(int offset) {
+			return Float.intBitsToFloat(readInt((idSize*2 + 8) + offset));
+		}
+
+		@Override
+		public long getIDField(int offset) {		
+			return readNumber((idSize*2 + 8) + offset,idSize);
+		}
+
+		@Override
+		public int getIntegerField(int offset) {
+			return readInt((idSize*2 + 8) + offset);
+		}
+
+		@Override
+		public long getLongField(int offset) {	
+			return readLong((idSize*2 + 8) + offset);
+		}
+
+		@Override
+		public short getShortField(int offset) {
+			return readShort((idSize*2 + 8) + offset);
+		}
+
+		@Override
+		public boolean getBooleanField(int offset) {
+			return !(getByteField(offset) == 0);
+		}
+
+	}
+
+	public class GCClassHeapDumpRecord extends LightHeapEntryRecord implements IGCClassHeapDumpRecord, IHeapObject {
+
+		private int staticFieldsOffset;
+		private int instFieldsOffset;
+
+		public GCClassHeapDumpRecord(byte tag, IDataProvider provider
+				, int staticFieldsOffset, int instFieldsOffset ) {
+			super(tag, provider);
+			
+			this.staticFieldsOffset = staticFieldsOffset;
+			this.instFieldsOffset = instFieldsOffset;
+		}
+
+		public long getID() {
+			return readNumber(0, idSize);
+		}
+
+		public int getStackTraceNumber() {
+			return readInt(idSize);
+		}
+
+		public long getSuperClassObjectID() {
+			return readNumber(idSize + 4, idSize);
+		}
+
+		public long getClassLoaderObjectID() {
+			return readNumber((idSize * 2) + 4, idSize);
+		}
+
+		public long getSignersObjectID() {
+			return readNumber((idSize * 3) + 4, idSize);
+		}
+
+		public long getProtectionDomainObjectID() {
+			return readNumber((idSize * 4) + 4, idSize);
+		}
+
+		public int getInstanceSize() {
+			return readInt((idSize * 7) + 4);
+		}
+
+		public int getConstantPoolSize() {
+			return readShort((idSize * 7) + 8);
+		}
+
+		public ConstantPoolEntry[] getConstantPool() {
+			return readConstantPool((idSize * 7) + 10);
+		}
+
+		private ConstantPoolEntry[] readConstantPool(int offset) {
+			int entries = getConstantPoolSize();
+			ConstantPoolEntry[] pool = new ConstantPoolEntry[entries];
+			for (int i = 0; i < entries; i++) {
+				ConstantPoolEntry cpe = new ConstantPoolEntry();
+				cpe.cpIndex = readShort(offset);
+				offset += 2;
+				cpe.type = readByte(offset);
+				offset++;
+				int valueLength = sizes.getLengthFromType(cpe.type);
+				cpe.data = readBytes(offset, valueLength);
+				offset += valueLength;
+				pool[i] = cpe;
+			}
+			return pool;
+		}
+
+		public StaticFieldEntry[] getStaticFields() {
+			return readStaticFields(staticFieldsOffset);			
+		}
+		
+		private StaticFieldEntry[] readStaticFields(int offset) {
+			short staticFields = readShort(offset-2);
+			
+			StaticFieldEntry[] fields = new StaticFieldEntry[staticFields];
+			for (int i = 0; i < staticFields; i++) {
+				long stringID = readNumber(offset,idSize);
+				offset += idSize;
+				short type = readByte(offset);
+				offset+=1;
+				int arrayLength = sizes.getLengthFromType(type);
+				long data = readNumber(offset, arrayLength);
+				offset += arrayLength;
+				
+				fields[i] = new StaticFieldEntry(stringID, type, data);
+			}
+			
+			return fields;
+		}
+		
+		public InstanceFieldEntry[] getInstanceFields() {
+			return readInstanceFields(instFieldsOffset);
+		}
+
+		private InstanceFieldEntry[] readInstanceFields(int offset) {
+			short instFields = readShort(offset-2);
+			int fieldOffset = 0;
+			InstanceFieldEntry[] fields = new InstanceFieldEntry[instFields];
+			
+			for (int i = 0; i < instFields; i++) {
+				long stringID = readNumber(offset,idSize);
+				offset += idSize;
+				
+				short type = readByte(offset);
+				offset+=1;
+								
+				fields[i] = new InstanceFieldEntry(stringID, type, fieldOffset);
+				fieldOffset += sizes.getLengthFromType(type);
+			}
+			offsetSize = fieldOffset;
+			return fields;
+		}
+
+		private int offsetSize=-1;
+		@Override
+		public int getOffsetSize() {
+			if(offsetSize == -1) {
+				getInstanceFields();
+			}
+			return offsetSize;
+		}
+		
+	}
+
+	public void setSource(File source) {
+		this.source=source;
+		
+	}
+
+	public File getSource() {
+		return source;
+	}
+}

Propchange: incubator/kato/trunk/org.apache.kato/kato.hprof.reader/src/main/java/org/apache/kato/hprof/datalayer/HProfFile.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: incubator/kato/trunk/org.apache.kato/kato.hprof.reader/src/main/java/org/apache/kato/hprof/datalayer/HProfRecord.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/org.apache.kato/kato.hprof.reader/src/main/java/org/apache/kato/hprof/datalayer/HProfRecord.java?rev=883384&r1=883383&r2=883384&view=diff
==============================================================================
--- incubator/kato/trunk/org.apache.kato/kato.hprof.reader/src/main/java/org/apache/kato/hprof/datalayer/HProfRecord.java (original)
+++ incubator/kato/trunk/org.apache.kato/kato.hprof.reader/src/main/java/org/apache/kato/hprof/datalayer/HProfRecord.java Mon Nov 23 15:53:48 2009
@@ -1,64 +1,64 @@
-/*******************************************************************************
- * Licensed 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 org.apache.kato.hprof.datalayer;
-
-import org.apache.kato.common.DataReader;
-
-public abstract class HProfRecord implements IHProfRecord {
-
-	private short tag=0;
-	private byte[] data=null;
-	public HProfRecord(short tag,byte[] data) {
-		this.tag=tag;
-		this.data=data;
-	}
-
-	/* (non-Javadoc)
-	 * @see org.apache.kato.hprof.datalayer.IHProfRecord#getTag()
-	 */
-	public short getTag() {
-		return tag;
-	}
-
-	
-	protected int readInt(int offset) {
-		return DataReader.read4Bytes(data,offset);
-	}
-	protected short readShort(int offset) {
-		return DataReader.read2Bytes(data,offset);
-	}
-	
-	protected long readNumber(int offset, int length) {
-		return DataReader.readNumber(data,offset,length);
-		
-	}
-	protected byte[] readBytes(int offset,int length) {
-		return DataReader.readByteArray(data,offset,length);
-	}
-	
-	/* (non-Javadoc)
-	 * @see org.apache.kato.hprof.datalayer.IHProfRecord#getDataLength()
-	 */
-	public long getDataLength() {
-		if(data==null) return 0;
-		return data.length;
-	}
-
-	/* (non-Javadoc)
-	 * @see org.apache.kato.hprof.datalayer.IHProfRecord#getData()
-	 */
-	public byte[] getData() {
-		return data;
-	}
-}
+/*******************************************************************************
+ * Licensed 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 org.apache.kato.hprof.datalayer;
+
+import org.apache.kato.common.DataReader;
+
+public abstract class HProfRecord implements IHProfRecord {
+
+	private short tag=0;
+	private byte[] data=null;
+	public HProfRecord(short tag,byte[] data) {
+		this.tag=tag;
+		this.data=data;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.apache.kato.hprof.datalayer.IHProfRecord#getTag()
+	 */
+	public short getTag() {
+		return tag;
+	}
+
+	
+	protected int readInt(int offset) {
+		return DataReader.read4Bytes(data,offset);
+	}
+	protected short readShort(int offset) {
+		return DataReader.read2Bytes(data,offset);
+	}
+	
+	protected long readNumber(int offset, int length) {
+		return DataReader.readNumber(data,offset,length);
+		
+	}
+	protected byte[] readBytes(int offset,int length) {
+		return DataReader.readByteArray(data,offset,length);
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.apache.kato.hprof.datalayer.IHProfRecord#getDataLength()
+	 */
+	public long getDataLength() {
+		if(data==null) return 0;
+		return data.length;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.apache.kato.hprof.datalayer.IHProfRecord#getData()
+	 */
+	public byte[] getData() {
+		return data;
+	}
+}

Propchange: incubator/kato/trunk/org.apache.kato/kato.hprof.reader/src/main/java/org/apache/kato/hprof/datalayer/HProfRecord.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/kato/trunk/org.apache.kato/kato.hprof.reader/src/main/java/org/apache/kato/hprof/datalayer/HProfRecordTypes.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: incubator/kato/trunk/org.apache.kato/kato.hprof.reader/src/main/java/org/apache/kato/hprof/datalayer/IControlSettingsHProfRecord.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/org.apache.kato/kato.hprof.reader/src/main/java/org/apache/kato/hprof/datalayer/IControlSettingsHProfRecord.java?rev=883384&r1=883383&r2=883384&view=diff
==============================================================================
--- incubator/kato/trunk/org.apache.kato/kato.hprof.reader/src/main/java/org/apache/kato/hprof/datalayer/IControlSettingsHProfRecord.java (original)
+++ incubator/kato/trunk/org.apache.kato/kato.hprof.reader/src/main/java/org/apache/kato/hprof/datalayer/IControlSettingsHProfRecord.java Mon Nov 23 15:53:48 2009
@@ -1,24 +1,24 @@
-/*******************************************************************************
- * Licensed 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 org.apache.kato.hprof.datalayer;
-
-public interface IControlSettingsHProfRecord {
-
-	public abstract boolean isAllocTrace();
-
-	public abstract boolean isCpuSampling();
-
-	public abstract short getStackTraceDepth();
-
+/*******************************************************************************
+ * Licensed 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 org.apache.kato.hprof.datalayer;
+
+public interface IControlSettingsHProfRecord {
+
+	public abstract boolean isAllocTrace();
+
+	public abstract boolean isCpuSampling();
+
+	public abstract short getStackTraceDepth();
+
 }
\ No newline at end of file

Propchange: incubator/kato/trunk/org.apache.kato/kato.hprof.reader/src/main/java/org/apache/kato/hprof/datalayer/IControlSettingsHProfRecord.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: incubator/kato/trunk/org.apache.kato/kato.hprof.reader/src/main/java/org/apache/kato/hprof/datalayer/IGCClassHeapDumpRecord.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/org.apache.kato/kato.hprof.reader/src/main/java/org/apache/kato/hprof/datalayer/IGCClassHeapDumpRecord.java?rev=883384&r1=883383&r2=883384&view=diff
==============================================================================
--- incubator/kato/trunk/org.apache.kato/kato.hprof.reader/src/main/java/org/apache/kato/hprof/datalayer/IGCClassHeapDumpRecord.java (original)
+++ incubator/kato/trunk/org.apache.kato/kato.hprof.reader/src/main/java/org/apache/kato/hprof/datalayer/IGCClassHeapDumpRecord.java Mon Nov 23 15:53:48 2009
@@ -1,42 +1,42 @@
-/*******************************************************************************
- * Licensed 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 org.apache.kato.hprof.datalayer;
-
-
-public interface IGCClassHeapDumpRecord {
-	public long getID();
-	
-	public int getStackTraceNumber();
-
-	public long getSuperClassObjectID();
-
-	public long getClassLoaderObjectID();
-
-	public long getSignersObjectID();
-
-	public long getProtectionDomainObjectID();
-
-	public int getInstanceSize();
-
-	public int getConstantPoolSize();
-
-	public ConstantPoolEntry[] getConstantPool();
-
-	public InstanceFieldEntry[] getInstanceFields();
-	
-	public StaticFieldEntry[] getStaticFields();
-
-	public int getOffsetSize();	
-
-}
+/*******************************************************************************
+ * Licensed 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 org.apache.kato.hprof.datalayer;
+
+
+public interface IGCClassHeapDumpRecord {
+	public long getID();
+	
+	public int getStackTraceNumber();
+
+	public long getSuperClassObjectID();
+
+	public long getClassLoaderObjectID();
+
+	public long getSignersObjectID();
+
+	public long getProtectionDomainObjectID();
+
+	public int getInstanceSize();
+
+	public int getConstantPoolSize();
+
+	public ConstantPoolEntry[] getConstantPool();
+
+	public InstanceFieldEntry[] getInstanceFields();
+	
+	public StaticFieldEntry[] getStaticFields();
+
+	public int getOffsetSize();	
+
+}

Propchange: incubator/kato/trunk/org.apache.kato/kato.hprof.reader/src/main/java/org/apache/kato/hprof/datalayer/IGCClassHeapDumpRecord.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: incubator/kato/trunk/org.apache.kato/kato.hprof.reader/src/main/java/org/apache/kato/hprof/datalayer/IGCInstanceHeapDumpRecord.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/org.apache.kato/kato.hprof.reader/src/main/java/org/apache/kato/hprof/datalayer/IGCInstanceHeapDumpRecord.java?rev=883384&r1=883383&r2=883384&view=diff
==============================================================================
--- incubator/kato/trunk/org.apache.kato/kato.hprof.reader/src/main/java/org/apache/kato/hprof/datalayer/IGCInstanceHeapDumpRecord.java (original)
+++ incubator/kato/trunk/org.apache.kato/kato.hprof.reader/src/main/java/org/apache/kato/hprof/datalayer/IGCInstanceHeapDumpRecord.java Mon Nov 23 15:53:48 2009
@@ -1,104 +1,104 @@
-/*******************************************************************************
- * Licensed 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 org.apache.kato.hprof.datalayer;
-
-/**
- * Represents a GCInstanceHeapDumpRecord.
- * This is a plain object instance, i.e. it is not an array.
- * 
- * 
- */
-public interface IGCInstanceHeapDumpRecord extends IHeapObject {
-
-
-	/**
-	 * The object id of the class this object is an instance of.
-	 * 
-	 * @return long object id
-	 */
-	public abstract long getClassObjectID();
-
-
-	/**
-	 * Retrieve a boolean field from this object.
-	 * 
-	 * @param offset into instance values.
-	 * @return byte value
-	 */
-	public abstract boolean getBooleanField(int offset);
-	
-	/**
-	 * Retrieve a byte field from this object.
-	 * 
-	 * @param offset into instance values.
-	 * @return byte value
-	 */
-	public abstract byte getByteField(int offset);
-	
-	/**
-	 * Retrieve a char field from this object.
-	 * 
-	 * @param offset into instance values.
-	 * @return char value
-	 */
-	public abstract char getCharField(int offset);
-	
-	/**
-	 * Retrieve a short field from this object.
-	 * 
-	 * @param offset into instance values.
-	 * @return short value
-	 */
-	public abstract short getShortField(int offset);
-	
-	/**
-	 * Retrieve a int field from this object.
-	 * 
-	 * @param offset into instance values.
-	 * @return int value
-	 */
-	public abstract int getIntegerField(int offset);
-	
-	/**
-	 * Retrieve a long field from this object.
-	 * 
-	 * @param offset into instance values.
-	 * @return long value
-	 */
-	public abstract long getLongField(int offset);
-	
-	/**
-	 * Retrieve a float field from this object.
-	 * 
-	 * @param offset into instance values.
-	 * @return float value
-	 */
-	public abstract float getFloatField(int offset);
-	
-	/**
-	 * Retrieve a double field from this object.
-	 * 
-	 * @param offset into instance values.
-	 * @return double value
-	 */
-	public abstract double getDoubleField(int offset);
-	
-	/**
-	 * Retrieve an object ID field from this object.
-	 * 
-	 * @param offset into instance values.
-	 * @return long value - an object ID.
-	 */
-	public abstract long getIDField(int offset);
-}
+/*******************************************************************************
+ * Licensed 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 org.apache.kato.hprof.datalayer;
+
+/**
+ * Represents a GCInstanceHeapDumpRecord.
+ * This is a plain object instance, i.e. it is not an array.
+ * 
+ * 
+ */
+public interface IGCInstanceHeapDumpRecord extends IHeapObject {
+
+
+	/**
+	 * The object id of the class this object is an instance of.
+	 * 
+	 * @return long object id
+	 */
+	public abstract long getClassObjectID();
+
+
+	/**
+	 * Retrieve a boolean field from this object.
+	 * 
+	 * @param offset into instance values.
+	 * @return byte value
+	 */
+	public abstract boolean getBooleanField(int offset);
+	
+	/**
+	 * Retrieve a byte field from this object.
+	 * 
+	 * @param offset into instance values.
+	 * @return byte value
+	 */
+	public abstract byte getByteField(int offset);
+	
+	/**
+	 * Retrieve a char field from this object.
+	 * 
+	 * @param offset into instance values.
+	 * @return char value
+	 */
+	public abstract char getCharField(int offset);
+	
+	/**
+	 * Retrieve a short field from this object.
+	 * 
+	 * @param offset into instance values.
+	 * @return short value
+	 */
+	public abstract short getShortField(int offset);
+	
+	/**
+	 * Retrieve a int field from this object.
+	 * 
+	 * @param offset into instance values.
+	 * @return int value
+	 */
+	public abstract int getIntegerField(int offset);
+	
+	/**
+	 * Retrieve a long field from this object.
+	 * 
+	 * @param offset into instance values.
+	 * @return long value
+	 */
+	public abstract long getLongField(int offset);
+	
+	/**
+	 * Retrieve a float field from this object.
+	 * 
+	 * @param offset into instance values.
+	 * @return float value
+	 */
+	public abstract float getFloatField(int offset);
+	
+	/**
+	 * Retrieve a double field from this object.
+	 * 
+	 * @param offset into instance values.
+	 * @return double value
+	 */
+	public abstract double getDoubleField(int offset);
+	
+	/**
+	 * Retrieve an object ID field from this object.
+	 * 
+	 * @param offset into instance values.
+	 * @return long value - an object ID.
+	 */
+	public abstract long getIDField(int offset);
+}

Propchange: incubator/kato/trunk/org.apache.kato/kato.hprof.reader/src/main/java/org/apache/kato/hprof/datalayer/IGCInstanceHeapDumpRecord.java
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message