/* Copyright (C) 2009 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.internal; import java.io.File; import java.io.IOException; import java.io.Writer; import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.TreeMap; import java.util.Map.Entry; import com.mobilesorcery.sdk.core.ISLDInfo; public class SLDInfoImpl implements ISLDInfo { private TreeMap<Integer, String> fileTable = new TreeMap<Integer, String>(); private TreeMap<Integer, Integer> addrToFile = new TreeMap<Integer, Integer>(); private TreeMap<Integer, Integer> addrToLine = new TreeMap<Integer, Integer>(); public TreeMap<AddressRange, String> startAddrForFunc = new TreeMap<AddressRange, String>(AddressRange.START_COMPARATOR); private File file; SLDInfoImpl(File sldFile) { this.file = sldFile; } void addFile(int id, String name) { fileTable.put(id, name); } void addLocationForAddress(int addr, int lineInFile, int fileId) { addrToLine.put(addr, lineInFile); addrToFile.put(addr, fileId); } void addRangeForFunction(String functionName, AddressRange addrRange) { if (addrRange != null) { startAddrForFunc.put(addrRange, functionName); } } /* (non-Javadoc) * @see com.mobilesorcery.sdk.core.ISLDInfo#getFileName(int) */ public String getFileName(int addr) { if (addrToFile.isEmpty()) { return null; } Entry<Integer, Integer> entry = addrToFile.floorEntry(addr); if (entry != null) { Integer fileId = entry.getValue(); if (fileId != null) { return fileTable.get(fileId); } } return null; } /* (non-Javadoc) * @see com.mobilesorcery.sdk.core.ISLDInfo#getLine(int) */ public int getLine(int addr) { if (addrToLine.isEmpty()) { return UNKNOWN_LINE; } Entry<Integer, Integer> entry = addrToLine.floorEntry(addr - 1); if (entry != null) { Integer line = entry.getValue(); if (line != null) { return line; } } return UNKNOWN_LINE; } public String getFunction(int addr) { AddressRange key = new AddressRange(addr, addr); Entry<AddressRange, String> closestEntry = startAddrForFunc.floorEntry(key); AddressRange closestAddressRange = closestEntry.getKey(); return closestAddressRange != null && closestAddressRange.inRange(addr) ? closestEntry.getValue() : null; } /* (non-Javadoc) * @see com.mobilesorcery.sdk.core.ISLDInfo#write(java.io.Writer) */ public void write(Writer writer) throws IOException { writer.write(SLDParser.FILE_MARKER); writer.write('\n'); for (Iterator<Integer> files = fileTable.keySet().iterator(); files.hasNext();) { Integer fileId = files.next(); String filename = fileTable.get(fileId); writer.write(fileId + ":" + filename); writer.write('\n'); } writer.write(SLDParser.SLD_MARKER); writer.write('\n'); for (Iterator<Integer> addrs = addrToFile.keySet().iterator(); addrs.hasNext();) { Integer addr = addrs.next(); int line = addrToLine.get(addr); int file = addrToFile.get(addr); writer.write(Integer.toHexString(addr) + ":" + line + ":" + file); writer.write("\n"); } } /* (non-Javadoc) * @see com.mobilesorcery.sdk.core.ISLDInfo#getSLDFile() */ public File getSLDFile() { return file; } public Collection<String> getAllFilenames() { return Collections.unmodifiableCollection(fileTable.values()); } public Collection<String> getAllFunctions() { return Collections.unmodifiableCollection(startAddrForFunc.values()); } }