mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-05-31 11:44:36 +00:00
272 lines
7.9 KiB
Java
272 lines
7.9 KiB
Java
/*
|
|
* Copyright (C) 2010-2011 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.asdec.abc;
|
|
|
|
import com.jpexs.asdec.abc.types.*;
|
|
import com.jpexs.asdec.abc.types.traits.*;
|
|
import java.io.IOException;
|
|
import java.io.OutputStream;
|
|
|
|
public class ABCOutputStream extends OutputStream {
|
|
|
|
private OutputStream os;
|
|
|
|
public ABCOutputStream(OutputStream os) {
|
|
this.os = os;
|
|
}
|
|
|
|
@Override
|
|
public void write(int b) throws IOException {
|
|
os.write(b);
|
|
}
|
|
|
|
public void writeU30(long value) throws IOException {
|
|
writeS32(value);
|
|
/*boolean loop = true;
|
|
boolean underZero=value<0;
|
|
|
|
if(underZero){
|
|
value = value & 0xFFFFFFFF;
|
|
}else{
|
|
value = value & 0x7FFFFFFF;
|
|
}
|
|
do {
|
|
int ret = (int) (value & 0x7F);
|
|
if (value < 0x80) {
|
|
loop = false;
|
|
}
|
|
if (value > 0x7F) {
|
|
ret += 0x80;
|
|
}
|
|
write(ret);
|
|
value = value >> 7;
|
|
} while (loop);
|
|
*/
|
|
}
|
|
|
|
public void writeU32(long value) throws IOException {
|
|
boolean loop = true;
|
|
value = value & 0xFFFFFFFF;
|
|
do {
|
|
int ret = (int) (value & 0x7F);
|
|
if (value < 0x80) {
|
|
loop = false;
|
|
}
|
|
if (value > 0x7F) {
|
|
ret += 0x80;
|
|
}
|
|
write(ret);
|
|
value = value >> 7;
|
|
} while (loop);
|
|
}
|
|
|
|
public void writeS24(long value) throws IOException {
|
|
int ret = (int) (value & 0xff);
|
|
write(ret);
|
|
value = value >> 8;
|
|
ret = (int) (value & 0xff);
|
|
write(ret);
|
|
value = value >> 8;
|
|
ret = (int) (value & 0xff);
|
|
write(ret);
|
|
}
|
|
|
|
public void writeS32(long value) throws IOException {
|
|
boolean belowZero = value < 0;
|
|
/*if (belowZero) {
|
|
value = -value;
|
|
}*/
|
|
int bitcount = 0;
|
|
boolean loop = true;
|
|
//value = value & 0xFFFFFFFF;
|
|
do {
|
|
bitcount += 7;
|
|
int ret = (int) (value & 0x7F);
|
|
if (value < 0x80) {
|
|
if (belowZero) { //&& bitcount < 35
|
|
ret += 0x80;
|
|
} else {
|
|
loop = false;
|
|
}
|
|
} else {
|
|
ret += 0x80;
|
|
}
|
|
|
|
if (bitcount == 35) {
|
|
ret = ret & 0xf;
|
|
}
|
|
write(ret);
|
|
if (bitcount == 35) {
|
|
break;
|
|
}
|
|
value = value >> 7;
|
|
} while (loop);
|
|
}
|
|
|
|
public void writeLong(long value) throws IOException {
|
|
byte writeBuffer[] = new byte[8];
|
|
writeBuffer[7] = (byte) (value >>> 56);
|
|
writeBuffer[6] = (byte) (value >>> 48);
|
|
writeBuffer[5] = (byte) (value >>> 40);
|
|
writeBuffer[4] = (byte) (value >>> 32);
|
|
writeBuffer[3] = (byte) (value >>> 24);
|
|
writeBuffer[2] = (byte) (value >>> 16);
|
|
writeBuffer[1] = (byte) (value >>> 8);
|
|
writeBuffer[0] = (byte) (value);
|
|
write(writeBuffer);
|
|
}
|
|
|
|
public void writeDouble(double value) throws IOException {
|
|
writeLong(Double.doubleToLongBits(value));
|
|
}
|
|
|
|
public void writeU8(int value) throws IOException {
|
|
write(value);
|
|
}
|
|
|
|
public void writeU16(int value) throws IOException {
|
|
write(value & 0xff);
|
|
write((value >> 8) & 0xff);
|
|
}
|
|
|
|
public void writeString(String s) throws IOException {
|
|
byte sbytes[] = s.getBytes("utf8");
|
|
writeU30(sbytes.length);
|
|
write(sbytes);
|
|
}
|
|
|
|
public void writeNamespace(Namespace ns) throws IOException {
|
|
write(ns.kind);
|
|
for (int k = 0; k < Namespace.nameSpaceKinds.length; k++) {
|
|
if (Namespace.nameSpaceKinds[k] == ns.kind) {
|
|
writeU30(ns.name_index);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void writeMultiname(Multiname m) throws IOException {
|
|
writeU8(m.kind);
|
|
if ((m.kind == 7) || (m.kind == 0xd)) { // CONSTANT_QName and CONSTANT_QNameA.
|
|
writeU30(m.namespace_index);
|
|
writeU30(m.name_index);
|
|
}
|
|
if ((m.kind == 9) || (m.kind == 0xe)) { // CONSTANT_Multiname and CONSTANT_MultinameA.
|
|
writeU30(m.name_index);
|
|
writeU30(m.namespace_set_index);
|
|
}
|
|
if ((m.kind == 0xf) || (m.kind == 0x10)) { //CONSTANT_RTQName and CONSTANT_RTQNameA
|
|
writeU30(m.name_index);
|
|
}
|
|
if ((m.kind == 0x1B) || (m.kind == 0x1C)) { //CONSTANT_MultinameL and CONSTANT_MultinameLA
|
|
writeU30(m.namespace_set_index);
|
|
}
|
|
if (m.kind == 0x1D) {
|
|
writeU30(m.qname_index);
|
|
writeU30(m.params.size());
|
|
for (int i = 0; i < m.params.size(); i++) {
|
|
writeU30(m.params.get(i));
|
|
}
|
|
}
|
|
//kind==0x11,0x12 nothing CONSTANT_RTQNameL and CONSTANT_RTQNameLA.
|
|
}
|
|
|
|
public void writeMethodInfo(MethodInfo mi) throws IOException {
|
|
writeU30(mi.param_types.length);
|
|
writeU30(mi.ret_type);
|
|
for (int i = 0; i < mi.param_types.length; i++) {
|
|
writeU30(mi.param_types[i]);
|
|
}
|
|
writeU30(mi.name_index);
|
|
write(mi.flags);
|
|
if ((mi.flags & 8) == 8) {
|
|
writeU30(mi.optional.length);
|
|
for (int i = 0; i < mi.optional.length; i++) {
|
|
writeU30(mi.optional[i].value_index);
|
|
write(mi.optional[i].value_kind);
|
|
}
|
|
}
|
|
|
|
if ((mi.flags & 128) == 128) { //if has_paramnames
|
|
for (int i = 0; i < mi.paramNames.length; i++) {
|
|
writeU30(mi.paramNames[i]);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void writeTrait(Trait t) throws IOException {
|
|
writeU30(t.name_index);
|
|
write((t.kindFlags << 4) + t.kindType);
|
|
if (t instanceof TraitSlotConst) {
|
|
TraitSlotConst t1 = (TraitSlotConst) t;
|
|
writeU30(t1.slot_id);
|
|
writeU30(t1.type_index);
|
|
writeU30(t1.value_index);
|
|
if (t1.value_index != 0) {
|
|
write(t1.value_kind);
|
|
}
|
|
}
|
|
if (t instanceof TraitMethodGetterSetter) {
|
|
TraitMethodGetterSetter t2 = (TraitMethodGetterSetter) t;
|
|
writeU30(t2.disp_id);
|
|
writeU30(t2.method_info);
|
|
}
|
|
if (t instanceof TraitClass) {
|
|
TraitClass t3 = (TraitClass) t;
|
|
writeU30(t3.slot_id);
|
|
writeU30(t3.class_info);
|
|
}
|
|
if (t instanceof TraitFunction) {
|
|
TraitFunction t4 = (TraitFunction) t;
|
|
writeU30(t4.slot_index);
|
|
writeU30(t4.method_info);
|
|
}
|
|
if ((t.kindFlags & 4) == 4) {
|
|
writeU30(t.metadata.length);
|
|
for (int i = 0; i < t.metadata.length; i++) {
|
|
writeU30(t.metadata[i]);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void writeTraits(Traits t) throws IOException {
|
|
writeU30(t.traits.length);
|
|
for (int i = 0; i < t.traits.length; i++) {
|
|
writeTrait(t.traits[i]);
|
|
}
|
|
}
|
|
|
|
public void writeInstanceInfo(InstanceInfo ii) throws IOException {
|
|
writeU30(ii.name_index);
|
|
writeU30(ii.super_index);
|
|
write(ii.flags);
|
|
if ((ii.flags & 8) == 8) {
|
|
writeU30(ii.protectedNS);
|
|
}
|
|
writeU30(ii.interfaces.length);
|
|
for (int i = 0; i < ii.interfaces.length; i++) {
|
|
writeU30(ii.interfaces[i]);
|
|
}
|
|
writeU30(ii.iinit_index);
|
|
writeTraits(ii.instance_traits);
|
|
}
|
|
|
|
public void writeDecimal(Decimal value) throws IOException {
|
|
write(value.data);
|
|
}
|
|
}
|