/*
* Copyright (C) 2010-2014 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 com.jpexs.helpers.utf8.Utf8PrintWriter;
import java.util.ArrayList;
import java.util.List;
public class ConstantPool {
public List constant_int = new ArrayList<>();
public List constant_uint = new ArrayList<>();
public List constant_double = new ArrayList<>();
/* Only for some minor versions */
public List constant_decimal = new ArrayList<>();
public List constant_string = new ArrayList<>();
public List constant_namespace = new ArrayList<>();
public List constant_namespace_set = new ArrayList<>();
public List constant_multiname = new ArrayList<>();
public synchronized int addInt(long value) {
constant_int.add(value);
return constant_int.size() - 1;
}
public synchronized int addNamespace(Namespace ns) {
constant_namespace.add(ns);
return constant_namespace.size() - 1;
}
public synchronized int addNamespaceSet(NamespaceSet nss) {
constant_namespace_set.add(nss);
return constant_namespace_set.size() - 1;
}
public synchronized int addMultiname(Multiname m) {
constant_multiname.add(m);
return constant_multiname.size() - 1;
}
public synchronized int addUInt(long value) {
constant_uint.add(value);
return constant_uint.size() - 1;
}
public synchronized int addDouble(double value) {
constant_double.add(value);
return constant_double.size() - 1;
}
public synchronized int addDecimal(Decimal value) {
constant_decimal.add(value);
return constant_decimal.size() - 1;
}
public synchronized int addString(String value) {
constant_string.add(value);
return constant_string.size() - 1;
}
public long setInt(int index, long value) {
constant_int.set(index, value);
return value;
}
public Namespace setNamespace(int index, Namespace ns) {
constant_namespace.set(index, ns);
return ns;
}
public NamespaceSet setNamespaceSet(int index, NamespaceSet nss) {
constant_namespace_set.set(index, nss);
return nss;
}
public Multiname setMultiname(int index, Multiname m) {
constant_multiname.set(index, m);
return m;
}
public long setUInt(int index, long value) {
constant_uint.set(index, value);
return value;
}
public double setDouble(int index, double value) {
constant_double.set(index, value);
return value;
}
public Decimal setDecimal(int index, Decimal value) {
constant_decimal.set(index, value);
return value;
}
public String setString(int index, String value) {
constant_string.set(index, value);
return value;
}
public long getInt(int index) {
return constant_int.get(index);
}
public Namespace getNamespace(int index) {
return constant_namespace.get(index);
}
public NamespaceSet getNamespaceSet(int index) {
return constant_namespace_set.get(index);
}
public Multiname getMultiname(int index) {
return constant_multiname.get(index);
}
public long getUInt(int index) {
return constant_uint.get(index);
}
public double getDouble(int index) {
return constant_double.get(index);
}
public Decimal getDecimal(int index) {
return constant_decimal.get(index);
}
public String getString(int index) {
return constant_string.get(index);
}
public int getIntCount() {
return constant_int.size();
}
public int getNamespaceCount() {
return constant_namespace.size();
}
public int getNamespaceSetCount() {
return constant_namespace_set.size();
}
public int getMultinameCount() {
return constant_multiname.size();
}
public int getUIntCount() {
return constant_uint.size();
}
public int getDoubleCount() {
return constant_double.size();
}
public int getDecimalCount() {
return constant_decimal.size();
}
public int getStringCount() {
return constant_string.size();
}
public int getNamespaceSubIndex(int namespaceId){
Namespace ns = constant_namespace.get(namespaceId);
int index=0;
for (int n = 1; n < namespaceId; n++) {
if(constant_namespace.get(n).name_index == ns.name_index && constant_namespace.get(n).kind == ns.kind){
index++;
}
}
return index;
}
public int getNamespaceId(Namespace val, int index) {
for (int n = 1; n < constant_namespace.size(); n++) {
Namespace ns = constant_namespace.get(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.size(); i++) {
if (constant_int.get(i) == value) {
return i;
}
}
return 0;
}
public int getUIntId(long value) {
for (int i = 1; i < constant_uint.size(); i++) {
if (constant_uint.get(i) == value) {
return i;
}
}
return 0;
}
public int getDoubleId(double value) {
for (int i = 1; i < constant_double.size(); i++) {
if(Double.isNaN(value) && Double.isNaN(constant_double.get(i))){
return i;
}
if (Double.compare(constant_double.get(i), value) == 0) {
return i;
}
}
return 0;
}
public int getStringId(String val) {
if (val == null) {
return 0;
}
for (int i = 1; i < constant_string.size(); i++) {
if (constant_string.get(i).equals(val)) {
return i;
}
}
return 0;
}
public int getMultinameId(Multiname val) {
loopm:
for (int m = 1; m < constant_multiname.size(); m++) {
Multiname mul = constant_multiname.get(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) {
if (val == null) {
return 0;
}
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 getNamespaceSetId(NamespaceSet val) {
loopi:
for (int i = 1; i < constant_namespace_set.size(); i++) {
NamespaceSet ts = constant_namespace_set.get(i);
if (ts.namespaces.length != val.namespaces.length) {
continue;
}
for (int j = 0; j < val.namespaces.length; j++) {
boolean found = false;
for (int k = 0; k < val.namespaces.length; k++) {
if (ts.namespaces[j] == val.namespaces[k]) {
found = true;
break;
}
}
if (!found) {
continue loopi;
}
}
return i;
}
return 0;
}
public int getNamespaceSetId(NamespaceSet val, boolean add) {
int id = getNamespaceSetId(val);
if (add && id == 0) {
id = addNamespaceSet(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(Utf8PrintWriter writer) {
String s = "";
for (int i = 1; i < constant_int.size(); i++) {
writer.println("INT[" + i + "]=" + constant_int.get(i));
}
for (int i = 1; i < constant_uint.size(); i++) {
writer.println("UINT[" + i + "]=" + constant_uint.get(i));
}
for (int i = 1; i < constant_double.size(); i++) {
writer.println("Double[" + i + "]=" + constant_double.get(i));
}
for (int i = 1; i < constant_string.size(); i++) {
writer.println("String[" + i + "]=" + constant_string.get(i));
}
for (int i = 1; i < constant_namespace.size(); i++) {
writer.println("Namespace[" + i + "]=" + constant_namespace.get(i).toString(this));
}
for (int i = 1; i < constant_namespace_set.size(); i++) {
writer.println("NamespaceSet[" + i + "]=" + constant_namespace_set.get(i).toString(this));
}
for (int i = 1; i < constant_multiname.size(); i++) {
writer.println("Multiname[" + i + "]=" + constant_multiname.get(i).toString(this, new ArrayList()));
}
}
public String multinameToString(int index) {
if (index == 0) {
return "null";
}
return constant_multiname.get(index).toString(this, new ArrayList());
}
public String namespaceToString(int index) {
if (index == 0) {
return "null";
}
return constant_namespace.get(index).toString(this);
}
public String namespaceSetToString(int index) {
if (index == 0) {
return "null";
}
return constant_namespace_set.get(index).toString(this);
}
}