package app.create.rpg.rgssad;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
public class RgssOutputStream extends OutputStream {
RgssEntry mEntry = null;
long mOffset = 0, mTotal = 0;
int mMagic;
OutputStream mStream;
public static byte[] MAGIC = new byte[] {0x52, 0x47, 0x53, 0x53, 0x41, 0x44, 0x00, 0x01};
public RgssOutputStream(OutputStream os, int magic) throws IOException {
mStream = os;
mMagic = magic;
os.write(MAGIC);
}
public synchronized void write_dword (int val) throws IOException {
val ^= mMagic;
mMagic = mMagic * 7 + 3;
mStream.write(new byte[]{(byte) val, (byte) (val >>> 8), (byte) (val >>> 16), (byte) (val >>> 24)});
}
public synchronized void write_byte (byte val) throws IOException {
val ^= (byte) mMagic;
mMagic = mMagic * 7 + 3;
mStream.write(val);
}
public synchronized void closeEntry() throws IOException {
if (mEntry == null) return;
if (mEntry.getOffset() != mOffset)
throw new IOException ("Not fully written or overwritten");
mMagic = (int) mEntry.getMagicKey();
mEntry = null;
mOffset = 0;
}
public synchronized void putNextEntry(RgssEntry entry) throws IOException {
try {
closeEntry();
mMagic = entry.mMagic; // restore magic
byte[] bytes = entry.getName().getBytes("UTF-8");
write_dword(bytes.length);
for (byte b : bytes)
write_byte(b);
write_dword((int) entry.getSize());
entry.mMagic = mMagic;
entry.mOffset = mTotal;
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
@Override
public void close() throws IOException {
closeEntry();
mStream.close();
}
@Override
public void flush() throws IOException {
mStream.flush();
}
@Override
public void write(int oneByte) throws IOException {
if (mOffset + 1 >= mEntry.getSize())
throw new IOException ("Out of size");
mStream.write(oneByte ^ (mMagic >>> ((mOffset & 3) << 3)));
if ((mOffset++ & 3) == 3)
mMagic = mMagic * 7 + 3;
}
}