/* * Copyright (C) 2010-2013 JPEXS * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * 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 * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package com.jpexs.decompiler.flash.abc.avm2; import com.jpexs.decompiler.flash.abc.types.Decimal; import com.jpexs.decompiler.flash.abc.types.Multiname; import com.jpexs.decompiler.flash.abc.types.Namespace; import com.jpexs.decompiler.flash.abc.types.NamespaceSet; import java.io.OutputStream; import java.io.PrintStream; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.Arrays; import java.util.logging.Level; import java.util.logging.Logger; public class ConstantPool { public long[] constant_int; public long[] constant_uint; public double[] constant_double; /* Only for some minor versions */ public Decimal[] constant_decimal; public String[] constant_string; public Namespace[] constant_namespace; public NamespaceSet[] constant_namespace_set; public Multiname[] constant_multiname; public int addInt(long value) { constant_int = Arrays.copyOf(constant_int, constant_int.length + 1); constant_int[constant_int.length - 1] = value; return constant_int.length - 1; } public int addNamespace(Namespace ns) { constant_namespace = Arrays.copyOf(constant_namespace, constant_namespace.length + 1); constant_namespace[constant_namespace.length - 1] = ns; return constant_namespace.length - 1; } public int addNamespaceSet(NamespaceSet nss) { constant_namespace_set = Arrays.copyOf(constant_namespace_set, constant_namespace_set.length + 1); constant_namespace_set[constant_namespace_set.length - 1] = nss; return constant_namespace_set.length - 1; } public int addMultiname(Multiname m) { constant_multiname = Arrays.copyOf(constant_multiname, constant_multiname.length + 1); constant_multiname[constant_multiname.length - 1] = m; return constant_multiname.length - 1; } public int addUInt(long value) { constant_uint = Arrays.copyOf(constant_uint, constant_uint.length + 1); constant_uint[constant_uint.length - 1] = value; return constant_uint.length - 1; } public int addDouble(double value) { constant_double = Arrays.copyOf(constant_double, constant_double.length + 1); constant_double[constant_double.length - 1] = value; return constant_double.length - 1; } public int addString(String value) { constant_string = Arrays.copyOf(constant_string, constant_string.length + 1); constant_string[constant_string.length - 1] = value; return constant_string.length - 1; } public int getNamespaceId(Namespace val, int index) { for (int n = 1; n < constant_namespace.length; n++) { Namespace ns = constant_namespace[n]; if (ns.name_index == val.name_index && (ns.kind == val.kind)) { if (index == 0) { return n; } index--; } } return 0; } public int getIntId(long value) { for (int i = 1; i < constant_int.length; i++) { if (constant_int[i] == value) { return i; } } return 0; } public int getUIntId(long value) { for (int i = 1; i < constant_uint.length; i++) { if (constant_uint[i] == value) { return i; } } return 0; } public int getDoubleId(double value) { for (int i = 1; i < constant_double.length; i++) { if (Double.compare(constant_double[i], value) == 0) { return i; } } return 0; } public int getStringId(String val) { for (int i = 1; i < constant_string.length; i++) { if (constant_string[i].equals(val)) { return i; } } return 0; } public int getMultinameId(Multiname val) { loopm: for (int m = 1; m < constant_multiname.length; m++) { Multiname mul = constant_multiname[m]; if (mul.kind == val.kind && mul.name_index == val.name_index && mul.namespace_index == val.namespace_index && mul.namespace_set_index == val.namespace_set_index && mul.qname_index == val.qname_index && mul.params.size() == val.params.size()) { for (int p = 0; p < mul.params.size(); p++) { if (mul.params.get(p) != val.params.get(p)) { continue loopm; } } return m; } } return 0; } public int getQnameId(String name, int namespaceKind, String namespaceName, boolean add) { return getMultinameId(new Multiname(Multiname.QNAME, getStringId(name, add), getNamespaceId(new Namespace(namespaceKind, getStringId(namespaceName, add)), 0, add), -1, -1, new ArrayList()), add); } public int getPublicQnameId(String name, boolean add) { return getQnameId(name, Namespace.KIND_PACKAGE, "", add); } public int getMultinameId(Multiname val, boolean add) { int id = getMultinameId(val); if (add && id == 0) { id = addMultiname(val); } return id; } public int getStringId(String val, boolean add) { int id = getStringId(val); if (add && id == 0) { id = addString(val); } return id; } public int getIntId(long val, boolean add) { int id = getIntId(val); if (add && id == 0) { id = addInt(val); } return id; } public int getNamespaceId(Namespace val, int index, boolean add) { int id = getNamespaceId(val, index); if (add && id == 0) { id = addNamespace(val); } return id; } public int getUIntId(long val, boolean add) { int id = getUIntId(val); if (add && id == 0) { id = addUInt(val); } return id; } public int getDoubleId(double val, boolean add) { int id = getDoubleId(val); if (add && id == 0) { id = addDouble(val); } return id; } public void dump(OutputStream os) { PrintStream output; try { output = new PrintStream(os, false, "utf-8"); } catch (UnsupportedEncodingException ex) { Logger.getLogger(ConstantPool.class.getName()).log(Level.SEVERE, null, ex); return; } String s = ""; for (int i = 1; i < constant_int.length; i++) { output.println("INT[" + i + "]=" + constant_int[i]); } for (int i = 1; i < constant_uint.length; i++) { output.println("UINT[" + i + "]=" + constant_uint[i]); } for (int i = 1; i < constant_double.length; i++) { output.println("Double[" + i + "]=" + constant_double[i]); } for (int i = 1; i < constant_string.length; i++) { output.println("String[" + i + "]=" + constant_string[i]); } for (int i = 1; i < constant_namespace.length; i++) { output.println("Namespace[" + i + "]=" + constant_namespace[i].toString(this)); } for (int i = 1; i < constant_namespace_set.length; i++) { output.println("NamespaceSet[" + i + "]=" + constant_namespace_set[i].toString(this)); } for (int i = 1; i < constant_multiname.length; i++) { output.println("Multiname[" + i + "]=" + constant_multiname[i].toString(this, new ArrayList())); } } public String multinameToString(int index) { if (index == 0) { return "null"; } return constant_multiname[index].toString(this, new ArrayList()); } public String namespaceToString(int index) { if (index == 0) { return "null"; } return constant_namespace[index].toString(this); } public String namespaceSetToString(int index) { if (index == 0) { return "null"; } return constant_namespace_set[index].toString(this); } }