mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-07-19 00:09:00 +00:00
get needed characters refactored, get rid of innertags in showframe (using Timelined instead), last frame bug fixed (when there is no ShowFrame tag after the last placeobject tags), remove characters from tags (without removing the whole tag) + organize imports, code formatting
This commit is contained in:
@@ -1,391 +1,391 @@
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.types.Decimal;
|
||||
import com.jpexs.decompiler.flash.abc.types.InstanceInfo;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import com.jpexs.decompiler.flash.abc.types.Multiname;
|
||||
import com.jpexs.decompiler.flash.abc.types.Namespace;
|
||||
import com.jpexs.decompiler.flash.abc.types.ValueKind;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.Trait;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.TraitClass;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.TraitFunction;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.TraitMethodGetterSetter;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.TraitSlotConst;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.Traits;
|
||||
import com.jpexs.helpers.utf8.Utf8Helper;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ABCInputStream extends InputStream {
|
||||
|
||||
private static final int CLASS_PROTECTED_NS = 8;
|
||||
private static final int ATTR_METADATA = 4;
|
||||
private final InputStream is;
|
||||
private long bytesRead = 0;
|
||||
private ByteArrayOutputStream bufferOs = null;
|
||||
public static final boolean DEBUG_READ = false;
|
||||
|
||||
public void startBuffer() {
|
||||
if (bufferOs == null) {
|
||||
bufferOs = new ByteArrayOutputStream();
|
||||
} else {
|
||||
bufferOs.reset();
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] stopBuffer() {
|
||||
if (bufferOs == null) {
|
||||
return new byte[0];
|
||||
}
|
||||
byte[] ret = bufferOs.toByteArray();
|
||||
bufferOs.reset();
|
||||
return ret;
|
||||
}
|
||||
|
||||
public ABCInputStream(InputStream is) {
|
||||
this.is = is;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
bytesRead++;
|
||||
int i = is.read();
|
||||
if (DEBUG_READ) {
|
||||
System.out.println("Read:0x" + Integer.toHexString(i));
|
||||
}
|
||||
if (bufferOs != null) {
|
||||
if (i != -1) {
|
||||
bufferOs.write(i);
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(byte[] b) throws IOException {
|
||||
int currBytesRead = is.read(b);
|
||||
bytesRead += currBytesRead;
|
||||
if (DEBUG_READ) {
|
||||
StringBuilder sb = new StringBuilder("Read[");
|
||||
sb.append(currBytesRead);
|
||||
sb.append('/');
|
||||
sb.append(b.length);
|
||||
sb.append("]: ");
|
||||
for (int jj = 0; jj < currBytesRead; jj++) {
|
||||
sb.append("0x");
|
||||
sb.append(Integer.toHexString(b[jj]));
|
||||
sb.append(' ');
|
||||
}
|
||||
System.out.println(sb.toString());
|
||||
}
|
||||
if (bufferOs != null) {
|
||||
if (currBytesRead > 0) {
|
||||
bufferOs.write(b, 0, currBytesRead);
|
||||
}
|
||||
}
|
||||
return currBytesRead;
|
||||
}
|
||||
|
||||
;
|
||||
|
||||
public int readU8() throws IOException {
|
||||
return read();
|
||||
}
|
||||
|
||||
public long readU32() throws IOException {
|
||||
int i;
|
||||
long ret = 0;
|
||||
int bytePos = 0;
|
||||
int byteCount = 0;
|
||||
boolean nextByte;
|
||||
do {
|
||||
i = read();
|
||||
nextByte = (i >> 7) == 1;
|
||||
i &= 0x7f;
|
||||
ret += (((long) i) << bytePos);
|
||||
byteCount++;
|
||||
bytePos += 7;
|
||||
} while (nextByte);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public int readU30() throws IOException {
|
||||
return (int) readU32();
|
||||
}
|
||||
|
||||
public int readS24() throws IOException {
|
||||
int ret = (read()) + (read() << 8) + (read() << 16);
|
||||
|
||||
if ((ret >> 23) == 1) {
|
||||
ret |= 0xff000000;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public int readU16() throws IOException {
|
||||
return (read()) + (read() << 8);
|
||||
}
|
||||
|
||||
public long readS32() throws IOException {
|
||||
int i;
|
||||
long ret = 0;
|
||||
int bytePos = 0;
|
||||
int byteCount = 0;
|
||||
boolean nextByte;
|
||||
do {
|
||||
i = read();
|
||||
nextByte = (i >> 7) == 1;
|
||||
i &= 0x7f;
|
||||
ret += (i << bytePos);
|
||||
byteCount++;
|
||||
bytePos += 7;
|
||||
if (bytePos == 35) {
|
||||
if ((ret >> 31) == 1) {
|
||||
ret = -(ret & 0x7fffffff);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} while (nextByte);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int available() throws IOException {
|
||||
return is.available();
|
||||
}
|
||||
|
||||
public final long readLong() throws IOException {
|
||||
byte[] readBuffer = safeRead(8);
|
||||
return (((long) readBuffer[7] << 56)
|
||||
+ ((long) (readBuffer[6] & 255) << 48)
|
||||
+ ((long) (readBuffer[5] & 255) << 40)
|
||||
+ ((long) (readBuffer[4] & 255) << 32)
|
||||
+ ((long) (readBuffer[3] & 255) << 24)
|
||||
+ ((readBuffer[2] & 255) << 16)
|
||||
+ ((readBuffer[1] & 255) << 8)
|
||||
+ ((readBuffer[0] & 255)));
|
||||
}
|
||||
|
||||
public double readDouble() throws IOException {
|
||||
long el = readLong();
|
||||
double ret = Double.longBitsToDouble(el);
|
||||
return ret;
|
||||
}
|
||||
|
||||
private byte[] safeRead(int count) throws IOException {
|
||||
byte[] ret = new byte[count];
|
||||
for (int i = 0; i < count; i++) {
|
||||
ret[i] = (byte) read();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public Namespace readNamespace() throws IOException {
|
||||
int kind = read();
|
||||
int name_index = 0;
|
||||
for (int k = 0; k < Namespace.nameSpaceKinds.length; k++) {
|
||||
if (Namespace.nameSpaceKinds[k] == kind) {
|
||||
name_index = readU30();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return new Namespace(kind, name_index);
|
||||
}
|
||||
|
||||
public Multiname readMultiname() throws IOException {
|
||||
int kind = readU8();
|
||||
int namespace_index = 0;
|
||||
int name_index = 0;
|
||||
int namespace_set_index = 0;
|
||||
int qname_index = 0;
|
||||
List<Integer> params = new ArrayList<>();
|
||||
|
||||
if ((kind == Multiname.QNAME) || (kind == Multiname.QNAMEA)) {
|
||||
namespace_index = readU30();
|
||||
name_index = readU30();
|
||||
} else if ((kind == Multiname.RTQNAME) || (kind == Multiname.RTQNAMEA)) {
|
||||
name_index = readU30();
|
||||
} else if ((kind == Multiname.RTQNAMEL) || (kind == Multiname.RTQNAMELA)) {
|
||||
|
||||
} else if ((kind == Multiname.MULTINAME) || (kind == Multiname.MULTINAMEA)) {
|
||||
name_index = readU30();
|
||||
namespace_set_index = readU30();
|
||||
} else if ((kind == Multiname.MULTINAMEL) || (kind == Multiname.MULTINAMELA)) {
|
||||
namespace_set_index = readU30();
|
||||
} else if (kind == Multiname.TYPENAME) {
|
||||
qname_index = readU30(); //Multiname index!!!
|
||||
int paramsLength = readU30();
|
||||
for (int i = 0; i < paramsLength; i++) {
|
||||
params.add(readU30()); //multiname indices!
|
||||
}
|
||||
} else {
|
||||
throw new IOException("Unknown kind of Multiname:0x" + Integer.toHexString(kind));
|
||||
}
|
||||
|
||||
return new Multiname(kind, name_index, namespace_index, namespace_set_index, qname_index, params);
|
||||
}
|
||||
|
||||
public MethodInfo readMethodInfo() throws IOException {
|
||||
int param_count = readU30();
|
||||
int ret_type = readU30();
|
||||
int[] param_types = new int[param_count];
|
||||
for (int i = 0; i < param_count; i++) {
|
||||
param_types[i] = readU30();
|
||||
}
|
||||
int name_index = readU30();
|
||||
int flags = read();
|
||||
|
||||
//// 1=need_arguments, 2=need_activation, 4=need_rest 8=has_optional (16=ignore_rest, 32=explicit,) 64=setsdxns, 128=has_paramnames
|
||||
ValueKind[] optional = new ValueKind[0];
|
||||
if ((flags & 8) == 8) { //if has_optional
|
||||
int optional_count = readU30();
|
||||
optional = new ValueKind[optional_count];
|
||||
for (int i = 0; i < optional_count; i++) {
|
||||
optional[i] = new ValueKind(readU30(), read());
|
||||
}
|
||||
}
|
||||
|
||||
int[] param_names = new int[param_count];
|
||||
if ((flags & 128) == 128) { //if has_paramnames
|
||||
for (int i = 0; i < param_count; i++) {
|
||||
param_names[i] = readU30();
|
||||
}
|
||||
}
|
||||
return new MethodInfo(param_types, ret_type, name_index, flags, optional, param_names);
|
||||
}
|
||||
|
||||
public Trait readTrait() throws IOException {
|
||||
long pos = getPosition();
|
||||
startBuffer();
|
||||
int name_index = readU30();
|
||||
int kind = read();
|
||||
int kindType = 0xf & kind;
|
||||
int kindFlags = kind >> 4;
|
||||
Trait trait;
|
||||
|
||||
switch (kindType) {
|
||||
case 0: //slot
|
||||
case 6: //const
|
||||
TraitSlotConst t1 = new TraitSlotConst();
|
||||
t1.slot_id = readU30();
|
||||
t1.type_index = readU30();
|
||||
t1.value_index = readU30();
|
||||
if (t1.value_index != 0) {
|
||||
t1.value_kind = read();
|
||||
}
|
||||
trait = t1;
|
||||
break;
|
||||
case 1: //method
|
||||
case 2: //getter
|
||||
case 3: //setter
|
||||
TraitMethodGetterSetter t2 = new TraitMethodGetterSetter();
|
||||
t2.disp_id = readU30();
|
||||
t2.method_info = readU30();
|
||||
trait = t2;
|
||||
break;
|
||||
case 4: //class
|
||||
TraitClass t3 = new TraitClass();
|
||||
t3.slot_id = readU30();
|
||||
t3.class_info = readU30();
|
||||
trait = t3;
|
||||
break;
|
||||
case 5: //function
|
||||
TraitFunction t4 = new TraitFunction();
|
||||
t4.slot_id = readU30();
|
||||
t4.method_info = readU30();
|
||||
trait = t4;
|
||||
break;
|
||||
default:
|
||||
throw new IOException("Unknown trait kind:" + kind);
|
||||
}
|
||||
trait.fileOffset = pos;
|
||||
trait.kindType = kindType;
|
||||
trait.kindFlags = kindFlags;
|
||||
trait.name_index = name_index;
|
||||
if ((kindFlags & ATTR_METADATA) != 0) {
|
||||
int metadata_count = readU30();
|
||||
trait.metadata = new int[metadata_count];
|
||||
for (int i = 0; i < metadata_count; i++) {
|
||||
trait.metadata[i] = readU30();
|
||||
}
|
||||
}
|
||||
trait.bytes = stopBuffer();
|
||||
return trait;
|
||||
}
|
||||
|
||||
public Traits readTraits() throws IOException {
|
||||
int count = readU30();
|
||||
Traits traits = new Traits();
|
||||
traits.traits = new ArrayList<>();
|
||||
for (int i = 0; i < count; i++) {
|
||||
traits.traits.add(readTrait());
|
||||
}
|
||||
return traits;
|
||||
}
|
||||
|
||||
public byte[] readBytes(int count) throws IOException {
|
||||
byte[] ret = new byte[count];
|
||||
for (int i = 0; i < count; i++) {
|
||||
ret[i] = (byte) read();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public Decimal readDecimal() throws IOException {
|
||||
byte[] data = readBytes(16);
|
||||
return new Decimal(data);
|
||||
}
|
||||
|
||||
public InstanceInfo readInstanceInfo() throws IOException {
|
||||
InstanceInfo ret = new InstanceInfo();
|
||||
ret.name_index = readU30();
|
||||
ret.super_index = readU30();
|
||||
ret.flags = read();
|
||||
if ((ret.flags & CLASS_PROTECTED_NS) != 0) {
|
||||
ret.protectedNS = readU30();
|
||||
}
|
||||
int interfaces_count = readU30();
|
||||
ret.interfaces = new int[interfaces_count];
|
||||
for (int i = 0; i < interfaces_count; i++) {
|
||||
ret.interfaces[i] = readU30();
|
||||
}
|
||||
ret.iinit_index = readU30();
|
||||
ret.instance_traits = readTraits();
|
||||
return ret;
|
||||
}
|
||||
|
||||
public String readString() throws IOException {
|
||||
int length = readU30();
|
||||
byte[] b = safeRead(length);
|
||||
String r = new String(b, Utf8Helper.charset);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
/*public void markStart(){
|
||||
bytesRead=0;
|
||||
}*/
|
||||
public long getPosition() {
|
||||
return bytesRead;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.types.Decimal;
|
||||
import com.jpexs.decompiler.flash.abc.types.InstanceInfo;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import com.jpexs.decompiler.flash.abc.types.Multiname;
|
||||
import com.jpexs.decompiler.flash.abc.types.Namespace;
|
||||
import com.jpexs.decompiler.flash.abc.types.ValueKind;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.Trait;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.TraitClass;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.TraitFunction;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.TraitMethodGetterSetter;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.TraitSlotConst;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.Traits;
|
||||
import com.jpexs.helpers.utf8.Utf8Helper;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ABCInputStream extends InputStream {
|
||||
|
||||
private static final int CLASS_PROTECTED_NS = 8;
|
||||
private static final int ATTR_METADATA = 4;
|
||||
private final InputStream is;
|
||||
private long bytesRead = 0;
|
||||
private ByteArrayOutputStream bufferOs = null;
|
||||
public static final boolean DEBUG_READ = false;
|
||||
|
||||
public void startBuffer() {
|
||||
if (bufferOs == null) {
|
||||
bufferOs = new ByteArrayOutputStream();
|
||||
} else {
|
||||
bufferOs.reset();
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] stopBuffer() {
|
||||
if (bufferOs == null) {
|
||||
return new byte[0];
|
||||
}
|
||||
byte[] ret = bufferOs.toByteArray();
|
||||
bufferOs.reset();
|
||||
return ret;
|
||||
}
|
||||
|
||||
public ABCInputStream(InputStream is) {
|
||||
this.is = is;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
bytesRead++;
|
||||
int i = is.read();
|
||||
if (DEBUG_READ) {
|
||||
System.out.println("Read:0x" + Integer.toHexString(i));
|
||||
}
|
||||
if (bufferOs != null) {
|
||||
if (i != -1) {
|
||||
bufferOs.write(i);
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(byte[] b) throws IOException {
|
||||
int currBytesRead = is.read(b);
|
||||
bytesRead += currBytesRead;
|
||||
if (DEBUG_READ) {
|
||||
StringBuilder sb = new StringBuilder("Read[");
|
||||
sb.append(currBytesRead);
|
||||
sb.append('/');
|
||||
sb.append(b.length);
|
||||
sb.append("]: ");
|
||||
for (int jj = 0; jj < currBytesRead; jj++) {
|
||||
sb.append("0x");
|
||||
sb.append(Integer.toHexString(b[jj]));
|
||||
sb.append(' ');
|
||||
}
|
||||
System.out.println(sb.toString());
|
||||
}
|
||||
if (bufferOs != null) {
|
||||
if (currBytesRead > 0) {
|
||||
bufferOs.write(b, 0, currBytesRead);
|
||||
}
|
||||
}
|
||||
return currBytesRead;
|
||||
}
|
||||
|
||||
;
|
||||
|
||||
public int readU8() throws IOException {
|
||||
return read();
|
||||
}
|
||||
|
||||
public long readU32() throws IOException {
|
||||
int i;
|
||||
long ret = 0;
|
||||
int bytePos = 0;
|
||||
int byteCount = 0;
|
||||
boolean nextByte;
|
||||
do {
|
||||
i = read();
|
||||
nextByte = (i >> 7) == 1;
|
||||
i &= 0x7f;
|
||||
ret += (((long) i) << bytePos);
|
||||
byteCount++;
|
||||
bytePos += 7;
|
||||
} while (nextByte);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public int readU30() throws IOException {
|
||||
return (int) readU32();
|
||||
}
|
||||
|
||||
public int readS24() throws IOException {
|
||||
int ret = (read()) + (read() << 8) + (read() << 16);
|
||||
|
||||
if ((ret >> 23) == 1) {
|
||||
ret |= 0xff000000;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public int readU16() throws IOException {
|
||||
return (read()) + (read() << 8);
|
||||
}
|
||||
|
||||
public long readS32() throws IOException {
|
||||
int i;
|
||||
long ret = 0;
|
||||
int bytePos = 0;
|
||||
int byteCount = 0;
|
||||
boolean nextByte;
|
||||
do {
|
||||
i = read();
|
||||
nextByte = (i >> 7) == 1;
|
||||
i &= 0x7f;
|
||||
ret += (i << bytePos);
|
||||
byteCount++;
|
||||
bytePos += 7;
|
||||
if (bytePos == 35) {
|
||||
if ((ret >> 31) == 1) {
|
||||
ret = -(ret & 0x7fffffff);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} while (nextByte);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int available() throws IOException {
|
||||
return is.available();
|
||||
}
|
||||
|
||||
public final long readLong() throws IOException {
|
||||
byte[] readBuffer = safeRead(8);
|
||||
return (((long) readBuffer[7] << 56)
|
||||
+ ((long) (readBuffer[6] & 255) << 48)
|
||||
+ ((long) (readBuffer[5] & 255) << 40)
|
||||
+ ((long) (readBuffer[4] & 255) << 32)
|
||||
+ ((long) (readBuffer[3] & 255) << 24)
|
||||
+ ((readBuffer[2] & 255) << 16)
|
||||
+ ((readBuffer[1] & 255) << 8)
|
||||
+ ((readBuffer[0] & 255)));
|
||||
}
|
||||
|
||||
public double readDouble() throws IOException {
|
||||
long el = readLong();
|
||||
double ret = Double.longBitsToDouble(el);
|
||||
return ret;
|
||||
}
|
||||
|
||||
private byte[] safeRead(int count) throws IOException {
|
||||
byte[] ret = new byte[count];
|
||||
for (int i = 0; i < count; i++) {
|
||||
ret[i] = (byte) read();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public Namespace readNamespace() throws IOException {
|
||||
int kind = read();
|
||||
int name_index = 0;
|
||||
for (int k = 0; k < Namespace.nameSpaceKinds.length; k++) {
|
||||
if (Namespace.nameSpaceKinds[k] == kind) {
|
||||
name_index = readU30();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return new Namespace(kind, name_index);
|
||||
}
|
||||
|
||||
public Multiname readMultiname() throws IOException {
|
||||
int kind = readU8();
|
||||
int namespace_index = 0;
|
||||
int name_index = 0;
|
||||
int namespace_set_index = 0;
|
||||
int qname_index = 0;
|
||||
List<Integer> params = new ArrayList<>();
|
||||
|
||||
if ((kind == Multiname.QNAME) || (kind == Multiname.QNAMEA)) {
|
||||
namespace_index = readU30();
|
||||
name_index = readU30();
|
||||
} else if ((kind == Multiname.RTQNAME) || (kind == Multiname.RTQNAMEA)) {
|
||||
name_index = readU30();
|
||||
} else if ((kind == Multiname.RTQNAMEL) || (kind == Multiname.RTQNAMELA)) {
|
||||
|
||||
} else if ((kind == Multiname.MULTINAME) || (kind == Multiname.MULTINAMEA)) {
|
||||
name_index = readU30();
|
||||
namespace_set_index = readU30();
|
||||
} else if ((kind == Multiname.MULTINAMEL) || (kind == Multiname.MULTINAMELA)) {
|
||||
namespace_set_index = readU30();
|
||||
} else if (kind == Multiname.TYPENAME) {
|
||||
qname_index = readU30(); //Multiname index!!!
|
||||
int paramsLength = readU30();
|
||||
for (int i = 0; i < paramsLength; i++) {
|
||||
params.add(readU30()); //multiname indices!
|
||||
}
|
||||
} else {
|
||||
throw new IOException("Unknown kind of Multiname:0x" + Integer.toHexString(kind));
|
||||
}
|
||||
|
||||
return new Multiname(kind, name_index, namespace_index, namespace_set_index, qname_index, params);
|
||||
}
|
||||
|
||||
public MethodInfo readMethodInfo() throws IOException {
|
||||
int param_count = readU30();
|
||||
int ret_type = readU30();
|
||||
int[] param_types = new int[param_count];
|
||||
for (int i = 0; i < param_count; i++) {
|
||||
param_types[i] = readU30();
|
||||
}
|
||||
int name_index = readU30();
|
||||
int flags = read();
|
||||
|
||||
//// 1=need_arguments, 2=need_activation, 4=need_rest 8=has_optional (16=ignore_rest, 32=explicit,) 64=setsdxns, 128=has_paramnames
|
||||
ValueKind[] optional = new ValueKind[0];
|
||||
if ((flags & 8) == 8) { //if has_optional
|
||||
int optional_count = readU30();
|
||||
optional = new ValueKind[optional_count];
|
||||
for (int i = 0; i < optional_count; i++) {
|
||||
optional[i] = new ValueKind(readU30(), read());
|
||||
}
|
||||
}
|
||||
|
||||
int[] param_names = new int[param_count];
|
||||
if ((flags & 128) == 128) { //if has_paramnames
|
||||
for (int i = 0; i < param_count; i++) {
|
||||
param_names[i] = readU30();
|
||||
}
|
||||
}
|
||||
return new MethodInfo(param_types, ret_type, name_index, flags, optional, param_names);
|
||||
}
|
||||
|
||||
public Trait readTrait() throws IOException {
|
||||
long pos = getPosition();
|
||||
startBuffer();
|
||||
int name_index = readU30();
|
||||
int kind = read();
|
||||
int kindType = 0xf & kind;
|
||||
int kindFlags = kind >> 4;
|
||||
Trait trait;
|
||||
|
||||
switch (kindType) {
|
||||
case 0: //slot
|
||||
case 6: //const
|
||||
TraitSlotConst t1 = new TraitSlotConst();
|
||||
t1.slot_id = readU30();
|
||||
t1.type_index = readU30();
|
||||
t1.value_index = readU30();
|
||||
if (t1.value_index != 0) {
|
||||
t1.value_kind = read();
|
||||
}
|
||||
trait = t1;
|
||||
break;
|
||||
case 1: //method
|
||||
case 2: //getter
|
||||
case 3: //setter
|
||||
TraitMethodGetterSetter t2 = new TraitMethodGetterSetter();
|
||||
t2.disp_id = readU30();
|
||||
t2.method_info = readU30();
|
||||
trait = t2;
|
||||
break;
|
||||
case 4: //class
|
||||
TraitClass t3 = new TraitClass();
|
||||
t3.slot_id = readU30();
|
||||
t3.class_info = readU30();
|
||||
trait = t3;
|
||||
break;
|
||||
case 5: //function
|
||||
TraitFunction t4 = new TraitFunction();
|
||||
t4.slot_id = readU30();
|
||||
t4.method_info = readU30();
|
||||
trait = t4;
|
||||
break;
|
||||
default:
|
||||
throw new IOException("Unknown trait kind:" + kind);
|
||||
}
|
||||
trait.fileOffset = pos;
|
||||
trait.kindType = kindType;
|
||||
trait.kindFlags = kindFlags;
|
||||
trait.name_index = name_index;
|
||||
if ((kindFlags & ATTR_METADATA) != 0) {
|
||||
int metadata_count = readU30();
|
||||
trait.metadata = new int[metadata_count];
|
||||
for (int i = 0; i < metadata_count; i++) {
|
||||
trait.metadata[i] = readU30();
|
||||
}
|
||||
}
|
||||
trait.bytes = stopBuffer();
|
||||
return trait;
|
||||
}
|
||||
|
||||
public Traits readTraits() throws IOException {
|
||||
int count = readU30();
|
||||
Traits traits = new Traits();
|
||||
traits.traits = new ArrayList<>();
|
||||
for (int i = 0; i < count; i++) {
|
||||
traits.traits.add(readTrait());
|
||||
}
|
||||
return traits;
|
||||
}
|
||||
|
||||
public byte[] readBytes(int count) throws IOException {
|
||||
byte[] ret = new byte[count];
|
||||
for (int i = 0; i < count; i++) {
|
||||
ret[i] = (byte) read();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public Decimal readDecimal() throws IOException {
|
||||
byte[] data = readBytes(16);
|
||||
return new Decimal(data);
|
||||
}
|
||||
|
||||
public InstanceInfo readInstanceInfo() throws IOException {
|
||||
InstanceInfo ret = new InstanceInfo();
|
||||
ret.name_index = readU30();
|
||||
ret.super_index = readU30();
|
||||
ret.flags = read();
|
||||
if ((ret.flags & CLASS_PROTECTED_NS) != 0) {
|
||||
ret.protectedNS = readU30();
|
||||
}
|
||||
int interfaces_count = readU30();
|
||||
ret.interfaces = new int[interfaces_count];
|
||||
for (int i = 0; i < interfaces_count; i++) {
|
||||
ret.interfaces[i] = readU30();
|
||||
}
|
||||
ret.iinit_index = readU30();
|
||||
ret.instance_traits = readTraits();
|
||||
return ret;
|
||||
}
|
||||
|
||||
public String readString() throws IOException {
|
||||
int length = readU30();
|
||||
byte[] b = safeRead(length);
|
||||
String r = new String(b, Utf8Helper.charset);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
/*public void markStart(){
|
||||
bytesRead=0;
|
||||
}*/
|
||||
public long getPosition() {
|
||||
return bytesRead;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user