/* Copyright (C) 2010 Mobile Sorcery AB This program is free software; you can redistribute it and/or modify it under the terms of the Eclipse Public License v1.0. This program 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 Eclipse Public License v1.0 for more details. You should have received a copy of the Eclipse Public License v1.0 along with this program. It is also available at http://www.eclipse.org/legal/epl-v10.html */ package com.mobilesorcery.sdk.profiling.internal; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; import com.mobilesorcery.sdk.core.ISLDInfo; import com.mobilesorcery.sdk.profiling.FunctionDesc; import com.mobilesorcery.sdk.profiling.Invocation; class ProfilingDataParserHandler extends DefaultHandler { final static String FUNC_TAG = "f"; final static String FUNC_ADDR_ATTR = "a"; final static String FUNC_NAME_ATTR = "n"; final static String AGG_TIME_ATTR = "t"; final static String SELF_TIME_ATTR = "lt"; final static String INVOCATION_COUNT_ATTR = "c"; private Invocation current; private ISLDInfo sld; public ProfilingDataParserHandler(Invocation root, ISLDInfo info) { this.current = root; this.sld = info; } public void startElement(String uri, String name, String qName, Attributes atts) { if (FUNC_TAG.equals(name)) { Invocation invocation = new Invocation(current); String functionName = atts.getValue(FUNC_NAME_ATTR); String functionAddrStr = atts.getValue(FUNC_ADDR_ATTR); String filename = null; int lineno = -1; int functionAddr = parseAddr(functionAddrStr); if (functionName == null && functionAddrStr != null) { functionName = sld.getFunction(functionAddr); } if (functionAddrStr != null) { filename = sld.getFileName(functionAddr); lineno = sld.getLine(functionAddr); } FunctionDesc fd = new FunctionDesc(functionAddr, functionName, filename, lineno); int count = parseInt(atts.getValue(INVOCATION_COUNT_ATTR), 0); float selfTime = parseFloat(atts.getValue(SELF_TIME_ATTR), 0); float aggTime = parseFloat(atts.getValue(AGG_TIME_ATTR), 0); invocation.setProfiledEntity(fd); invocation.setCount(count); invocation.setSelfTime(selfTime); invocation.setAggregateTime(aggTime); current.addInvocation(invocation); current = invocation; } } private float parseFloat(String value, float invalidValue) { if (value != null) { try { return Float.parseFloat(value); } catch (NumberFormatException e) { // Return default } } return invalidValue; } private int parseInt(String value, int invalidValue) { if (value != null) { try { return Integer.parseInt(value); } catch (NumberFormatException e) { // Return default } } return invalidValue; } private int parseAddr(String addrStr) { if (addrStr != null && addrStr.startsWith("0x")) { try { return Integer.parseInt(addrStr.substring(2), 16); } catch (NumberFormatException e) { // return no addr } } return FunctionDesc.NO_ADDR; } public void endElement(String uri, String name, String qName) throws SAXException { if (FUNC_TAG.equals(name)) { current = (Invocation) current.getCaller(); } } }