// Near Infinity - An Infinity Engine Browser and Editor
// Copyright (C) 2001 - 2005 Jon Olav Hauglid
// See LICENSE.txt for license information
package org.infinity.search;
import java.awt.Component;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.infinity.datatype.StringRef;
import org.infinity.resource.AbstractStruct;
import org.infinity.resource.Resource;
import org.infinity.resource.ResourceFactory;
import org.infinity.resource.StructEntry;
import org.infinity.resource.bcs.BcsResource;
import org.infinity.resource.bcs.Compiler;
import org.infinity.resource.bcs.Decompiler;
import org.infinity.resource.dlg.AbstractCode;
import org.infinity.resource.dlg.Action;
import org.infinity.resource.dlg.DlgResource;
import org.infinity.resource.key.ResourceEntry;
import org.infinity.resource.sav.SavResource;
import org.infinity.resource.text.PlainTextResource;
public final class StringReferenceSearcher extends AbstractReferenceSearcher
{
private static final Pattern NUMBERPATTERN = Pattern.compile("\\d+", Pattern.DOTALL);
private final int searchvalue;
public StringReferenceSearcher(int searchvalue, Component parent)
{
super(null, new String[]{"2DA", "ARE", "BCS", "CHR", "CHU", "CRE", "DLG", "EFF", "GAM", "INI",
"ITM", "SPL", "SRC", "STO", "TOH", "WMP"}, parent);
this.searchvalue = searchvalue;
}
@Override
protected void search(ResourceEntry entry, Resource resource)
{
if (resource instanceof BcsResource)
searchScript(entry, (BcsResource)resource);
else if (resource instanceof DlgResource)
searchDialog(entry, (AbstractStruct)resource);
else if (resource instanceof SavResource)
searchSave(entry, (SavResource)resource);
else if (resource instanceof PlainTextResource)
searchText(entry, (PlainTextResource)resource);
else
searchStruct(entry, (AbstractStruct)resource);
}
private void searchDialog(ResourceEntry entry, AbstractStruct dialog)
{
for (int i = 0; i < dialog.getFieldCount(); i++) {
StructEntry o = dialog.getField(i);
if (o instanceof StringRef && ((StringRef)o).getValue() == searchvalue)
addHit(entry, entry.getSearchString(), o);
else if (o instanceof AbstractCode) {
AbstractCode sourceCode = (AbstractCode)o;
try {
Compiler compiler = new Compiler(sourceCode.toString(),
(sourceCode instanceof Action) ? Compiler.ScriptType.ACTION :
Compiler.ScriptType.TRIGGER);
String code = compiler.getCode();
if (compiler.getErrors().size() == 0) {
Decompiler decompiler = new Decompiler(code, true);
if (o instanceof Action) {
decompiler.setScriptType(Decompiler.ScriptType.ACTION);
} else {
decompiler.setScriptType(Decompiler.ScriptType.TRIGGER);
}
decompiler.decompile();
for (final Integer stringRef : decompiler.getStringRefsUsed()) {
if (stringRef.intValue() == searchvalue)
addHit(entry, entry.getSearchString(), sourceCode);
}
}
} catch (Exception e) {
System.out.println("Exception in " + dialog.getName() + " - " + sourceCode.getName());
e.printStackTrace();
}
}
else if (o instanceof AbstractStruct)
searchDialog(entry, (AbstractStruct)o);
}
}
private void searchSavStruct(ResourceEntry entry, ResourceEntry saventry, AbstractStruct struct)
{
for (int i = 0; i < struct.getFieldCount(); i++) {
StructEntry o = struct.getField(i);
if (o instanceof StringRef && ((StringRef)o).getValue() == searchvalue)
addHit(entry, saventry.toString(), o);
else if (o instanceof AbstractStruct)
searchSavStruct(entry, saventry, (AbstractStruct)o);
}
}
private void searchSave(ResourceEntry entry, SavResource savfile)
{
List<? extends ResourceEntry> entries = savfile.getFileHandler().getFileEntries();
for (int i = 0; i < entries.size(); i++) {
ResourceEntry saventry = (ResourceEntry)entries.get(i);
Resource resource = ResourceFactory.getResource(saventry);
if (resource instanceof AbstractStruct)
searchSavStruct(entry, saventry, (AbstractStruct)resource);
}
}
private void searchScript(ResourceEntry entry, BcsResource bcsfile)
{
Decompiler decompiler = new Decompiler(bcsfile.getCode(), true);
decompiler.decompile();
for (final Integer stringRef : decompiler.getStringRefsUsed()) {
if (stringRef.intValue() == searchvalue)
addHit(entry, null, null);
}
}
private void searchStruct(ResourceEntry entry, AbstractStruct struct)
{
for (int i = 0; i < struct.getFieldCount(); i++) {
StructEntry o = struct.getField(i);
if (o instanceof StringRef && ((StringRef)o).getValue() == searchvalue)
addHit(entry, entry.getSearchString(), o);
else if (o instanceof AbstractStruct)
searchStruct(entry, (AbstractStruct)o);
}
}
private void searchText(ResourceEntry entry, PlainTextResource text)
{
Matcher m = NUMBERPATTERN.matcher(text.getText());
while (m.find()) {
long nr = Long.parseLong(text.getText().substring(m.start(), m.end()));
if (nr == searchvalue)
addHit(entry, null, null);
}
}
}