/*
* Copyright (C) 2010-2016 JPEXS, All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
*/
package com.jpexs.decompiler.flash.abc.avm2;
import com.jpexs.decompiler.flash.abc.ABCVersionRequirements;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instructions;
import com.jpexs.decompiler.flash.abc.types.Decimal;
import com.jpexs.decompiler.flash.abc.types.Float4;
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.decompiler.flash.ecma.Null;
import com.jpexs.decompiler.flash.ecma.Undefined;
import com.jpexs.decompiler.flash.types.annotations.Internal;
import com.jpexs.decompiler.flash.types.annotations.SWFField;
import com.jpexs.decompiler.flash.types.annotations.SWFVersion;
import com.jpexs.decompiler.graph.DottedChain;
import com.jpexs.helpers.HashArrayList;
import com.jpexs.helpers.utf8.Utf8PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* @author JPEXS
*/
public class AVM2ConstantPool implements Cloneable {
private static final Logger logger = Logger.getLogger(AVM2ConstantPool.class.getName());
@SWFField
private HashArrayList<Long> constant_int = new HashArrayList<>();
@SWFField
private HashArrayList<Long> constant_uint = new HashArrayList<>();
@SWFField
private HashArrayList<Double> constant_double = new HashArrayList<>();
@SWFField
@ABCVersionRequirements(exactMinor = 17)
private HashArrayList<Decimal> constant_decimal = new HashArrayList<>();
@SWFField
@SWFVersion(from = 16)
@ABCVersionRequirements(minMajor = 47, minMinor = 16)
private HashArrayList<Float> constant_float = new HashArrayList<>();
/* Only for some versions */
@SWFField
@SWFVersion(from = 16)
@ABCVersionRequirements(minMajor = 47, minMinor = 16)
private HashArrayList<Float4> constant_float4 = new HashArrayList<>();
@SWFField
private HashArrayList<String> constant_string = new HashArrayList<>();
@SWFField
private HashArrayList<Namespace> constant_namespace = new HashArrayList<>();
@SWFField
private HashArrayList<NamespaceSet> constant_namespace_set = new HashArrayList<>();
@SWFField
private HashArrayList<Multiname> constant_multiname = new HashArrayList<>();
public AVM2ConstantPool() {
}
@Internal
public Map<String, DottedChain> dottedChainCache = new HashMap<>();
private void ensureDefault(List<?> list) {
if (list.isEmpty()) {
list.add(null);
}
}
public void ensureIntCapacity(int capacity) {
constant_int.ensureCapacity(capacity);
if (capacity > 0) {
ensureDefault(constant_int);
}
}
public void ensureNamespaceCapacity(int capacity) {
constant_namespace.ensureCapacity(capacity);
if (capacity > 0) {
ensureDefault(constant_namespace);
}
}
public void ensureNamespaceSetCapacity(int capacity) {
constant_namespace_set.ensureCapacity(capacity);
if (capacity > 0) {
ensureDefault(constant_namespace_set);
}
}
public void ensureMultinameCapacity(int capacity) {
constant_multiname.ensureCapacity(capacity);
if (capacity > 0) {
ensureDefault(constant_multiname);
}
}
public void ensureUIntCapacity(int capacity) {
constant_uint.ensureCapacity(capacity);
if (capacity > 0) {
ensureDefault(constant_uint);
}
}
public void ensureDoubleCapacity(int capacity) {
constant_double.ensureCapacity(capacity);
if (capacity > 0) {
ensureDefault(constant_double);
}
}
public void ensureDecimalCapacity(int capacity) {
constant_decimal.ensureCapacity(capacity);
if (capacity > 0) {
ensureDefault(constant_decimal);
}
}
public void ensureFloatCapacity(int capacity) {
constant_float.ensureCapacity(capacity);
if (capacity > 0) {
ensureDefault(constant_float);
}
}
public void ensureFloat4Capacity(int capacity) {
constant_float4.ensureCapacity(capacity);
if (capacity > 0) {
ensureDefault(constant_float4);
}
}
public void ensureStringCapacity(int capacity) {
constant_string.ensureCapacity(capacity);
if (capacity > 0) {
ensureDefault(constant_string);
}
}
public synchronized int addInt(long value) {
ensureDefault(constant_int);
value = (int) value;
constant_int.add(value);
return constant_int.size() - 1;
}
public synchronized int addNamespace(Namespace ns) {
ensureDefault(constant_namespace);
constant_namespace.add(ns);
return constant_namespace.size() - 1;
}
public int addNamespace(int kind, int nameIndex) {
return addNamespace(new Namespace(kind, nameIndex));
}
public synchronized int addNamespaceSet(NamespaceSet nss) {
ensureDefault(constant_namespace_set);
constant_namespace_set.add(nss);
return constant_namespace_set.size() - 1;
}
public synchronized int addMultiname(Multiname m) {
ensureDefault(constant_multiname);
constant_multiname.add(m);
return constant_multiname.size() - 1;
}
public synchronized int addUInt(long value) {
ensureDefault(constant_uint);
value &= 0xffffffffl;
constant_uint.add(value);
return constant_uint.size() - 1;
}
public synchronized int addDouble(double value) {
ensureDefault(constant_double);
constant_double.add(value);
return constant_double.size() - 1;
}
public synchronized int addDecimal(Decimal value) {
ensureDefault(constant_decimal);
constant_decimal.add(value);
return constant_decimal.size() - 1;
}
public synchronized int addFloat(Float value) {
ensureDefault(constant_float);
constant_float.add(value);
return constant_float.size() - 1;
}
public synchronized int addFloat4(Float4 value) {
ensureDefault(constant_float4);
constant_float4.add(value);
return constant_float4.size() - 1;
}
public synchronized int addString(String value) {
ensureDefault(constant_string);
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 float setFloat(int index, float value) {
constant_float.set(index, value);
return value;
}
public Float4 setFloat4(int index, Float4 value) {
constant_float4.set(index, value);
return value;
}
public String setString(int index, String value) {
constant_string.set(index, value);
return value;
}
public long getInt(int index) {
try {
if (index == 0) {
return 0;
}
return constant_int.get(index);
} catch (IndexOutOfBoundsException ex) {
logger.log(Level.SEVERE, "Int not found. Index: " + index, ex);
}
return 0;
}
public Namespace getNamespace(int index) {
try {
return constant_namespace.get(index);
} catch (IndexOutOfBoundsException ex) {
logger.log(Level.SEVERE, "Namespace not found. Index: " + index, ex);
}
return null;
}
public NamespaceSet getNamespaceSet(int index) {
try {
return constant_namespace_set.get(index);
} catch (IndexOutOfBoundsException ex) {
logger.log(Level.SEVERE, "NamespaceSet not found. Index: " + index, ex);
}
return null;
}
/**
* Converts kind MULTINAME with one namespace to QNAME with that namespace
* (must exist in the abc). Ignores others.
*
* @param cpool
* @param index MULTINAME index
* @return
*/
public int convertToQname(AVM2ConstantPool cpool, int index) {
Multiname mx = cpool.getMultiname(index);
if (mx.isMULTINAMEwithOneNs(cpool)) {
Multiname mx2 = new Multiname();
mx2.kind = Multiname.QNAME;
mx2.name_index = mx.name_index;
mx2.namespace_index = mx.getSingleNamespaceIndex(cpool);
//and same QNAME exists within this ABC
int newMultinameIndex = cpool.getMultinameId(mx2, false);
if (newMultinameIndex > 0) {
index = newMultinameIndex; //use that QNAME
}
}
return index;
}
public Multiname getMultiname(int index) {
try {
return constant_multiname.get(index);
} catch (IndexOutOfBoundsException ex) {
logger.log(Level.SEVERE, "Multiname not found. Index: " + index, ex);
}
return null;
}
public long getUInt(int index) {
try {
if (index == 0) {
return 0;
}
return constant_uint.get(index);
} catch (IndexOutOfBoundsException ex) {
logger.log(Level.SEVERE, "UInt not found. Index: " + index, ex);
}
return 0;
}
public double getDouble(int index) {
try {
if (index == 0) {
return 0;
}
return constant_double.get(index);
} catch (IndexOutOfBoundsException ex) {
logger.log(Level.SEVERE, "Double not found. Index: " + index, ex);
}
return 0;
}
public Decimal getDecimal(int index) {
try {
return constant_decimal.get(index);
} catch (IndexOutOfBoundsException ex) {
logger.log(Level.SEVERE, "Decimal not found. Index: " + index, ex);
}
return null;
}
public int getDecimalId(Decimal val, boolean add) {
int id = getDecimalId(val);
if (add && id == -1) {
id = addDecimal(val);
}
return id;
}
public Float getFloat(int index) {
try {
return constant_float.get(index);
} catch (IndexOutOfBoundsException ex) {
logger.log(Level.SEVERE, "Float not found. Index: " + index, ex);
}
return null;
}
public Float4 getFloat4(int index) {
try {
return constant_float4.get(index);
} catch (IndexOutOfBoundsException ex) {
logger.log(Level.SEVERE, "Float4 not found. Index: " + index, ex);
}
return null;
}
public String getString(int index) {
try {
return constant_string.get(index);
} catch (IndexOutOfBoundsException ex) {
logger.log(Level.SEVERE, "String not found. Index: " + index, ex);
}
return null;
}
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 getFloatCount() {
return constant_float.size();
}
public int getFloat4Count() {
return constant_float4.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;
}
private int getNamespaceId(int kind, int nameIndex, int index) {
for (int n = 1; n < constant_namespace.size(); n++) {
Namespace ns = constant_namespace.get(n);
if (ns.name_index == nameIndex && (ns.kind == kind)) {
if (index == 0) {
return n;
}
index--;
}
}
return -1;
}
public int getNamespaceId(int kind, int nameIndex, int index, boolean add) {
int id = getNamespaceId(kind, nameIndex, index);
if (add && id == -1) {
id = addNamespace(kind, nameIndex);
}
return id;
}
public int getNamespaceId(int kind, String name, int index, boolean add) {
int nameIndex = getStringId(name, add);
if (nameIndex == -1) {
return -1;
}
return getNamespaceId(kind, nameIndex, index, add);
}
public int getNamespaceId(int kind, DottedChain name, int index, boolean add) {
int nameIndex = getStringId(name, add);
if (nameIndex == -1) {
return -1;
}
return getNamespaceId(kind, nameIndex, index, add);
}
private int getIntId(long value) {
return constant_int.indexOf(value);
}
private int getUIntId(long value) {
return constant_uint.indexOf(value);
}
private int getDoubleId(double value) {
return constant_double.indexOf(value);
}
private int getFloatId(float value) {
return constant_float.indexOf(value);
}
private int getFloat4Id(Float4 value) {
return constant_float4.indexOf(value);
}
private int getDecimalId(Decimal value) {
return constant_decimal.indexOf(value);
}
private int getStringId(String value) {
return constant_string.indexOf(value);
}
private int getMultinameId(Multiname value) {
return constant_multiname.indexOf(value);
}
public int getQnameId(String name, int namespaceKind, String namespaceName, boolean add) {
return getMultinameId(Multiname.createQName(false, getStringId(name, add), getNamespaceId(namespaceKind, namespaceName, 0, add)), 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 == -1) {
id = addMultiname(val);
}
return id;
}
/**
* Finds multiname index based on multiname in other constant pool
*
* @param val
* @param origConst
* @return
*/
public int getMultinameId(Multiname val, AVM2ConstantPool origConst) {
for (int i = 1; i < getMultinameCount(); i++) {
if (getMultiname(i).qnameEquals(this, val, origConst)) {
return i;
}
}
return -1;
}
public int getStringId(String val, boolean add) {
if (val == null) {
return 0;
}
int id = getStringId(val);
if (add && id == -1) {
id = addString(val);
}
return id;
}
public int getStringId(DottedChain val, boolean add) {
if (val == null) {
return 0;
}
return getStringId(val.toRawString(), add);
}
public int getIntId(long val, boolean add) {
int id = getIntId(val);
if (add && id == -1) {
id = addInt(val);
}
return id;
}
private int getNamespaceSetId(int[] namespaces) {
loopi:
for (int i = 1; i < constant_namespace_set.size(); i++) {
NamespaceSet ts = constant_namespace_set.get(i);
if (ts.namespaces.length != namespaces.length) {
continue;
}
for (int j = 0; j < namespaces.length; j++) {
boolean found = false;
for (int k = 0; k < namespaces.length; k++) {
if (ts.namespaces[j] == namespaces[k]) {
found = true;
break;
}
}
if (!found) {
continue loopi;
}
}
return i;
}
return -1;
}
public int getNamespaceSetId(int[] namespaces, boolean add) {
int id = getNamespaceSetId(namespaces);
if (add && id == -1) {
id = addNamespaceSet(new NamespaceSet(namespaces));
}
return id;
}
public int getUIntId(long val, boolean add) {
int id = getUIntId(val);
if (add && id == -1) {
id = addUInt(val);
}
return id;
}
public int getDoubleId(double val, boolean add) {
int id = getDoubleId(val);
if (add && id == -1) {
id = addDouble(val);
}
return id;
}
public int getFloatId(float val, boolean add) {
int id = getFloatId(val);
if (add && id == -1) {
id = addFloat(val);
}
return id;
}
public int getFloat4Id(Float4 val, boolean add) {
int id = getFloat4Id(val);
if (add && id == -1) {
id = addFloat4(val);
}
return id;
}
public DottedChain getDottedChain(int index) {
String str = getString(index);
DottedChain chain = dottedChainCache.get(str);
if (chain == null) {
chain = DottedChain.parseWithSuffix(str);
dottedChainCache.put(str, chain);
}
return chain;
}
public void dump(Utf8PrintWriter writer) {
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);
}
@Override
public AVM2ConstantPool clone() {
try {
AVM2ConstantPool ret = (AVM2ConstantPool) super.clone();
ret.constant_int = new HashArrayList<>(constant_int);
ret.constant_uint = new HashArrayList<>(constant_uint);
ret.constant_double = new HashArrayList<>(constant_double);
ret.constant_decimal = new HashArrayList<>(constant_decimal);
ret.constant_float = new HashArrayList<>(constant_float);
ret.constant_float4 = new HashArrayList<>(constant_float4);
ret.constant_string = new HashArrayList<>(constant_string);
ret.constant_namespace = new HashArrayList<>(constant_namespace);
ret.constant_namespace_set = new HashArrayList<>(constant_namespace_set);
ret.constant_multiname = new HashArrayList<>(constant_multiname);
ret.dottedChainCache = new HashMap<>();
return ret;
} catch (CloneNotSupportedException ex) {
throw new RuntimeException();
}
}
public AVM2Instruction makePush(Object ovalue) {
if (ovalue instanceof Long) {
long value = (Long) ovalue;
if (value >= -128 && value <= 127) {
return new AVM2Instruction(0, AVM2Instructions.PushByte, new int[]{(int) (long) value});
} else if (value >= -32768 && value <= 32767) {
return new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{((int) (long) value) & 0xffff});
} else {
return new AVM2Instruction(0, AVM2Instructions.PushInt, new int[]{getIntId(value, true)});
}
}
if (ovalue instanceof Double) {
return new AVM2Instruction(0, AVM2Instructions.PushDouble, new int[]{getDoubleId((Double) ovalue, true)});
}
if (ovalue instanceof String) {
return new AVM2Instruction(0, AVM2Instructions.PushString, new int[]{getStringId((String) ovalue, true)});
}
if (ovalue instanceof Boolean) {
if ((Boolean) ovalue) {
return new AVM2Instruction(0, AVM2Instructions.PushTrue, null);
}
return new AVM2Instruction(0, AVM2Instructions.PushFalse, null);
}
if (ovalue == Null.INSTANCE) {
return new AVM2Instruction(0, AVM2Instructions.PushNull, null);
}
if (ovalue == Undefined.INSTANCE) {
return new AVM2Instruction(0, AVM2Instructions.PushUndefined, null);
}
return null;
}
/**
* Merges second constantpool into this one
*
* @param secondPool
* @param stringMap
* @param intMap
* @param uintMap
* @param doubleMap
* @param floatMap
* @param float4Map
* @param decimalMap
* @param namespaceMap
* @param namespaceSetMap
* @param multinameMap
*/
public void merge(AVM2ConstantPool secondPool, Map<Integer, Integer> stringMap, Map<Integer, Integer> intMap, Map<Integer, Integer> uintMap, Map<Integer, Integer> doubleMap, Map<Integer, Integer> floatMap, Map<Integer, Integer> float4Map, Map<Integer, Integer> decimalMap, Map<Integer, Integer> namespaceMap, Map<Integer, Integer> namespaceSetMap, Map<Integer, Integer> multinameMap) {
stringMap.put(0, 0);
for (int i = 1; i < secondPool.constant_string.size(); i++) {
String val = secondPool.constant_string.get(i);
stringMap.put(i, getStringId(val, true));
}
intMap.put(0, 0);
for (int i = 1; i < secondPool.constant_int.size(); i++) {
Long val = secondPool.constant_int.get(i);
intMap.put(i, getIntId(val, true));
}
uintMap.put(0, 0);
for (int i = 1; i < secondPool.constant_uint.size(); i++) {
Long val = secondPool.constant_uint.get(i);
uintMap.put(i, getUIntId(val, true));
}
doubleMap.put(0, 0);
for (int i = 1; i < secondPool.constant_double.size(); i++) {
Double val = secondPool.constant_double.get(i);
doubleMap.put(i, getDoubleId(val, true));
}
floatMap.put(0, 0);
for (int i = 1; i < secondPool.constant_float.size(); i++) {
Float val = secondPool.constant_float.get(i);
floatMap.put(i, getFloatId(val, true));
}
float4Map.put(0, 0);
for (int i = 1; i < secondPool.constant_float4.size(); i++) {
Float4 val = secondPool.constant_float4.get(i);
float4Map.put(i, getFloat4Id(val, true));
}
decimalMap.put(0, 0);
for (int i = 1; i < secondPool.constant_decimal.size(); i++) {
Decimal val = secondPool.constant_decimal.get(i);
decimalMap.put(i, getDecimalId(val, true));
}
namespaceMap.put(0, 0);
for (int i = 1; i < secondPool.constant_namespace.size(); i++) {
Namespace secondNamespace = secondPool.constant_namespace.get(i);
int mappedId;
int newNameIndex = stringMap.get(secondNamespace.name_index);
if (secondNamespace.kind == Namespace.KIND_PRIVATE) {//always add, this does not exists in this ABC. Conflicting private namespaces can have same names.
mappedId = addNamespace(secondNamespace.kind, newNameIndex);
} else {
mappedId = getNamespaceId(secondNamespace.kind, newNameIndex, 0, true);
}
namespaceMap.put(i, mappedId);
}
namespaceSetMap.put(0, 0);
for (int i = 1; i < secondPool.constant_namespace_set.size(); i++) {
NamespaceSet secondNamespaceSet = secondPool.constant_namespace_set.get(i);
int mappedsNss[] = new int[secondNamespaceSet.namespaces.length];
for (int n = 0; n < secondNamespaceSet.namespaces.length; n++) {
mappedsNss[n] = namespaceMap.get(secondNamespaceSet.namespaces[n]);
}
int mappedId = getNamespaceSetId(mappedsNss, true);
namespaceSetMap.put(i, mappedId);
}
multinameMap.put(0, 0);
for (int i = 1; i < secondPool.constant_multiname.size(); i++) {
Multiname secondMultiname = secondPool.constant_multiname.get(i);
Multiname newMultiname = null;
int newNameIndex = secondMultiname.name_index <= 0 ? secondMultiname.name_index : stringMap.get(secondMultiname.name_index);
int newNsIndex = secondMultiname.namespace_index <= 0 ? secondMultiname.namespace_index : namespaceMap.get(secondMultiname.namespace_index);
int newNssIndex = secondMultiname.namespace_set_index <= 0 ? secondMultiname.namespace_set_index : namespaceSetMap.get(secondMultiname.namespace_set_index);
switch (secondMultiname.kind) {
case Multiname.MULTINAME:
newMultiname = Multiname.createMultiname(false, newNameIndex, newNssIndex);
break;
case Multiname.MULTINAMEA:
newMultiname = Multiname.createMultiname(true, newNameIndex, newNssIndex);
break;
case Multiname.MULTINAMEL:
newMultiname = Multiname.createMultinameL(false, newNssIndex);
break;
case Multiname.MULTINAMELA:
newMultiname = Multiname.createMultinameL(true, newNssIndex);
break;
case Multiname.QNAME:
newMultiname = Multiname.createQName(false, newNameIndex, newNsIndex);
break;
case Multiname.QNAMEA:
newMultiname = Multiname.createQName(true, newNameIndex, newNsIndex);
break;
case Multiname.RTQNAME:
newMultiname = Multiname.createRTQName(false, newNameIndex);
break;
case Multiname.RTQNAMEA:
newMultiname = Multiname.createRTQName(true, newNameIndex);
break;
case Multiname.RTQNAMEL:
newMultiname = Multiname.createRTQNameL(false);
break;
case Multiname.RTQNAMELA:
newMultiname = Multiname.createRTQNameL(true);
break;
case Multiname.TYPENAME:
int newQnameIndex = multinameMap.get(secondMultiname.qname_index);
int newParams[] = new int[secondMultiname.params.length];
for (int p = 0; p < secondMultiname.params.length; p++) {
newParams[p] = multinameMap.get(secondMultiname.params[p]);
}
newMultiname = Multiname.createTypeName(newQnameIndex, newParams);
break;
}
int mappedId = getMultinameId(newMultiname, true);
multinameMap.put(i, mappedId);
}
}
}