/* * 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 . */ package com.jpexs.asdec.abc; import com.jpexs.asdec.abc.types.Decimal; import com.jpexs.asdec.abc.types.InstanceInfo; import com.jpexs.asdec.abc.types.MethodInfo; import com.jpexs.asdec.abc.types.Multiname; import com.jpexs.asdec.abc.types.Namespace; 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); value = value >> 8; } 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 >>> 0); 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