package com.jpexs.decompiler.flash.iggy.streams;
import java.io.ByteArrayOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
/**
*
* @author JPEXS
*/
public abstract class AbstractDataStream implements DataStreamInterface {
/**
* Available bytes
*
* @return null if unknown, long value otherwise
*/
@Override
public abstract Long available();
@Override
public abstract long position();
@Override
public long readUI64() throws IOException {
long lsb = readUI32();
long msb = readUI32();
long result = msb << 32 | lsb;
return result & 0xffffffffffffffffL;
}
@Override
public long readSI64() throws IOException {
long lsb = readUI32();
long msb = readUI32();
return msb << 32 | lsb;
}
@Override
public boolean writeUI64(long val) throws IOException {
write((int) (val & 0xff));
write((int) ((val >> 8) & 0xff));
write((int) ((val >> 16) & 0xff));
write((int) ((val >> 24) & 0xff));
write((int) ((val >> 32) & 0xff));
write((int) ((val >> 40) & 0xff));
write((int) ((val >> 48) & 0xff));
write((int) ((val >> 56) & 0xff));
return true;
}
@Override
public boolean writeSI64(long val) throws IOException {
write((int) (val & 0xff));
write((int) ((val >> 8) & 0xff));
write((int) ((val >> 16) & 0xff));
write((int) ((val >> 24) & 0xff));
write((int) ((val >> 32) & 0xff));
write((int) ((val >> 40) & 0xff));
write((int) ((val >> 48) & 0xff));
write((int) ((val >> 56) & 0xff));
return true;
}
@Override
public long readUI32() throws IOException {
try {
return (readUI8() | (readUI8() << 8) | (readUI8() << 16) | (readUI8() << 24));
} catch (EOFException ex) {
return -1;
}
}
@Override
public boolean writeUI32(long val) throws IOException {
write((int) (val & 0xff));
write((int) ((val >> 8) & 0xff));
write((int) ((val >> 16) & 0xff));
write((int) ((val >> 24) & 0xff));
return true;
}
@Override
public int readUI16() throws IOException {
try {
return (readUI8() | (readUI8() << 8)) & 0xffff;
} catch (EOFException ex) {
return -1;
}
}
@Override
public boolean writeUI16(int val) throws IOException {
write(val & 0xff);
write((val >> 8) & 0xff);
return true;
}
@Override
public int readUI8() throws IOException {
try {
return read() & 0xff;
} catch (EOFException ex) {
return -1;
}
}
@Override
public boolean writeUI8(int val) throws IOException {
write(val);
return true;
}
@Override
public float readFloat() throws IOException {
return Float.intBitsToFloat((int) readUI32());
}
@Override
public boolean writeFloat(float val) throws IOException {
return writeUI32(Float.floatToIntBits(val));
}
@Override
public byte[] readBytes(int numBytes) throws IOException {
byte[] ret = new byte[numBytes];
for (int i = 0; i < numBytes; i++) {
ret[i] = (byte) read();
}
return ret;
}
public byte[] getAllBytes() throws IOException {
long oldPos = position();
seek(0, SeekMode.SET);
byte[] ret = readBytes((int) (long) available());
seek(oldPos, SeekMode.SET);
return ret;
}
@Override
public void writeBytes(byte[] data) throws IOException {
for (int i = 0; i < data.length; i++) {
write(data[i] & 0xff);
}
}
@Override
public abstract int read() throws IOException;
@Override
public abstract void seek(long pos, SeekMode mode) throws IOException;
@Override
public void write(int val) throws IOException {
//nothing
}
@Override
public void close() {
//nothing
}
@Override
public int readUI8(long addr) throws IOException {
long curPos = position();
seek(addr, SeekMode.SET);
int val = readUI8();
seek(curPos, SeekMode.SET);
return val;
}
@Override
public boolean writeWChar(String name) throws IOException {
for (int i = 0; i < name.length(); i++) {
writeUI16(name.charAt(i));
}
writeUI16(0);
return true;
}
@Override
public String readWChar() throws IOException {
StringBuilder strBuilder = new StringBuilder();
do {
char c = (char) readUI16();
if (c == '\0') {
break;
}
strBuilder.append(c);
} while (true);
return strBuilder.toString();
}
@Override
public void pad8bytes() throws IOException {
int pad8 = (int) (position() % 8);
switch (pad8) {
case 1:
write(0);
case 2:
write(0);
case 3:
write(0);
case 4:
write(0);
case 5:
write(0);
case 6:
write(0);
case 7:
write(0);
}
}
@Override
public void setOlderOffsetToThisPos(long savedPos) throws IOException {
long curPos = position();
long actual = curPos - savedPos;
seek(savedPos, SeekMode.SET);
writeUI64(actual);
seek(curPos, SeekMode.SET);
}
public void setOlderOffsetToThisPosCheck(long savedPos, long expected) throws IOException {
if (expected == 1) {
return;
}
long curPos = position();
long actual = curPos - savedPos;
if (actual != expected) {
throw new RuntimeException("Expected " + expected + " but found actual " + actual + ". Diff:" + ((actual - expected) > 0 ? "+" : "") + (actual - expected));
}
}
}