blob: c3e7a0a357e178289431bf9865473afb527b8637 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2008, 2012 SAP AG and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* SAP AG - initial API and implementation
* Stefan Eggerstorfer - JDK7u6 doesn't have count/offset fields
*******************************************************************************/
package org.eclipse.mat.snapshot.model;
import org.eclipse.mat.SnapshotException;
/**
* Utility class to extract String representations of heap dump objects.
*/
public final class PrettyPrinter
{
/**
* Convert a <code>java.lang.String</code> object into a String.
* @param stringObject the String object in the dump
* @param limit maximum number of characters to return
* @return the value of the string from the dump, as a String
* @throws SnapshotException
*/
public static String objectAsString(IObject stringObject, int limit) throws SnapshotException
{
Object valueObj = stringObject.resolveValue("value"); //$NON-NLS-1$
if (!(valueObj instanceof IPrimitiveArray))
return null;
IPrimitiveArray charArray = (IPrimitiveArray) valueObj;
Object countObj = stringObject.resolveValue("count"); //$NON-NLS-1$
// count and offset fields were removed with JDK7u6
if (countObj == null)
{
return arrayAsString(charArray, 0, charArray.getLength(), limit);
}
else
{
if (!(countObj instanceof Integer))
return null;
Integer count = (Integer) countObj;
if (count.intValue() == 0)
return ""; //$NON-NLS-1$
// IBM java.lang.String implementation may have count but not offset
Integer offset = 0;
Object offsetObj = stringObject.resolveValue("offset"); //$NON-NLS-1$
if ((offsetObj instanceof Integer)) {
offset = (Integer) offsetObj;
}
return arrayAsString(charArray, offset, count, limit);
}
}
/**
* Convert a <code>char[]</code> object into a String.
* Unprintable characters are returned as \\unnnn values
* @param charArray
* @param offset where to start
* @param count how many characters to read
* @param limit the maximum number of characters to read
* @return the characters as a string
*/
public static String arrayAsString(IPrimitiveArray charArray, int offset, int count, int limit)
{
if (charArray.getType() != IObject.Type.CHAR)
return null;
int length = charArray.getLength();
int contentToRead = count <= limit ? count : limit;
if (contentToRead > length - offset)
contentToRead = length - offset;
char[] value;
if (offset == 0 && length == contentToRead)
value = (char[]) charArray.getValueArray();
else
value = (char[]) charArray.getValueArray(offset, contentToRead);
if (value == null)
return null;
StringBuilder result = new StringBuilder(value.length);
for (int ii = 0; ii < value.length; ii++)
{
char val = value[ii];
if (val >= 32 && val < 127)
result.append(val);
else
result.append("\\u").append(String.format("%04x", 0xFFFF & val)); //$NON-NLS-1$//$NON-NLS-2$
}
if (limit < count)
result.append("..."); //$NON-NLS-1$
return result.toString();
}
private PrettyPrinter()
{}
}