mirror of
https://github.com/plexusorg/Plex-FAWE.git
synced 2025-07-12 08:08:34 +00:00
Feature/propagate diff and object cleanup (#1190)
* Feature/main/propagate diff annotations (#1187) * 25% done * More work * More work * 50% * More work * 75% * 100% & cleanup * Update adapters * Squish squash, applesauce commit275ba9bd84
Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Sat Jul 17 01:10:20 2021 +0200 Update dependency com.comphenix.protocol:ProtocolLib to v4.7.0 (#1173) Co-authored-by: Renovate Bot <bot@renovateapp.com> commit9fd8984804
Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Sat Jul 17 01:09:29 2021 +0200 Update dependency org.checkerframework:checker-qual to v3.16.0 (#1184) Co-authored-by: Renovate Bot <bot@renovateapp.com> commit861fb45e5c
Author: dordsor21 <dordsor21@gmail.com> Date: Fri Jul 16 19:07:02 2021 +0100 Fix #1075 commit420c45a29a
Author: dordsor21 <dordsor21@gmail.com> Date: Fri Jul 16 18:48:21 2021 +0100 Entity removal should be on the main thread as we're just passing through rather than doing chunk operations - Fixes #1164 - Not working: butcher/remove history commit4d4db7dcd0
Author: SirYwell <hannesgreule@outlook.de> Date: Fri Jul 16 17:52:44 2021 +0200 Make sure leaves category is loaded for heightmaps (fixes #1176) commitc98f6e4f37
Author: dordsor21 <dordsor21@gmail.com> Date: Fri Jul 16 10:44:52 2021 +0100 Do not allow generation commands to generate outside selection commit2485f5eccc
Author: dordsor21 <dordsor21@gmail.com> Date: Fri Jul 16 10:43:15 2021 +0100 EditSession needs to override some Extent methods to ensure block changes are correctly set through the various extents Fixes #1152 commitd9418ec8ae
Author: dordsor21 <dordsor21@gmail.com> Date: Fri Jul 16 09:52:44 2021 +0100 Undo part of41073bb1a0
Fixes #1178 * Update Upstream fb1fb84 Fixed typo and grammar * We don't support custom heights yet * Casing inconsistency * Address a few comments * Address comments * Don't refactor to AP classpath * Document annotation style * Refactoring & shade cleanup * Address a few comments * More work * Resolve comments not being resolved yet * Feature/main/propagate diff annotations (#1187) (#1194) * Remove beta package, fix history packages, move classes out of object package * Resolve comments not being resolved yet * Remove beta package, fix history packages, move classes out of object package Co-authored-by: NotMyFault <mc.cache@web.de> * brushes should be under brush * More refactoring - Filters/processors should be in the same place and are related to extents - Transforms are in `extent.transform` in upstream * Move history classes under history * Update adapters Co-authored-by: dordsor21 <dordsor21@gmail.com>
This commit is contained in:
@ -0,0 +1,17 @@
|
||||
package com.fastasyncworldedit.core.internal.command;
|
||||
|
||||
import org.enginehub.piston.CommandParameters;
|
||||
import org.enginehub.piston.gen.CommandCallListener;
|
||||
import org.enginehub.piston.inject.InjectedValueStore;
|
||||
import org.enginehub.piston.inject.Key;
|
||||
import org.enginehub.piston.util.ValueProvider;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class MethodInjector implements CommandCallListener {
|
||||
@Override
|
||||
public void beforeCall(Method commandMethod, CommandParameters parameters) {
|
||||
InjectedValueStore store = parameters.injectedValue(Key.of(InjectedValueStore.class)).get();
|
||||
store.injectValue(Key.of(Method.class), ValueProvider.constant(commandMethod));
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package com.fastasyncworldedit.core.internal.exception;
|
||||
|
||||
import com.fastasyncworldedit.core.configuration.Caption;
|
||||
|
||||
public class FaweBlockBagException extends FaweException {
|
||||
public FaweBlockBagException() {
|
||||
super(Caption.of("fawe.error.worldedit.some.fails.blockbag"));
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package com.fastasyncworldedit.core.internal.exception;
|
||||
|
||||
import com.fastasyncworldedit.core.configuration.Caption;
|
||||
|
||||
public class FaweChunkLoadException extends FaweException {
|
||||
public FaweChunkLoadException() {
|
||||
super(Caption.of("fawe.cancel.worldedit.failed.load.chunk"));
|
||||
}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
package com.fastasyncworldedit.core.internal.exception;
|
||||
|
||||
import com.sk89q.worldedit.util.formatting.WorldEditText;
|
||||
import com.sk89q.worldedit.util.formatting.text.Component;
|
||||
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
public class FaweException extends RuntimeException {
|
||||
// DEBUG
|
||||
public static final FaweException _enableQueue = new FaweException("enableQueue");
|
||||
public static final FaweException _disableQueue = new FaweException("disableQueue");
|
||||
|
||||
private final Component message;
|
||||
|
||||
public FaweException(String reason) {
|
||||
this(TextComponent.of(reason));
|
||||
}
|
||||
|
||||
public FaweException(Component reason) {
|
||||
this.message = reason;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return WorldEditText.reduceToText(message, Locale.ROOT);
|
||||
}
|
||||
|
||||
public Component getComponent() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public static FaweException get(Throwable e) {
|
||||
if (e instanceof FaweException) {
|
||||
return (FaweException) e;
|
||||
}
|
||||
Throwable cause = e.getCause();
|
||||
if (cause == null) {
|
||||
return null;
|
||||
}
|
||||
return get(cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* Faster exception throwing/handling if you don't fill the stacktrace.
|
||||
*
|
||||
* @return a reference to this {@code Throwable} instance.
|
||||
*/
|
||||
@Override
|
||||
public Throwable fillInStackTrace() {
|
||||
return this;
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package com.fastasyncworldedit.core.internal.io;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public class AbstractDelegateOutputStream extends OutputStream {
|
||||
private final OutputStream parent;
|
||||
|
||||
@Override
|
||||
public void write(int b) throws IOException {
|
||||
parent.write(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(byte[] b) throws IOException {
|
||||
parent.write(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(byte[] b, int off, int len) throws IOException {
|
||||
parent.write(b, off, len);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() throws IOException {
|
||||
parent.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
parent.close();
|
||||
}
|
||||
|
||||
public AbstractDelegateOutputStream(OutputStream os) {
|
||||
this.parent = os;
|
||||
}
|
||||
}
|
@ -0,0 +1,226 @@
|
||||
package com.fastasyncworldedit.core.internal.io;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.io.Writer;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* A speedy implementation of ByteArrayOutputStream. It's not synchronized, and it
|
||||
* does not copy buffers when it's expanded. There's also no copying of the internal buffer
|
||||
* if it's contents is extracted with the writeTo(stream) method.
|
||||
*
|
||||
* @author Rickard ?berg
|
||||
* @author Brat Baker (Atlassian)
|
||||
* @author Alexey
|
||||
* @version $Date: 2008-01-19 10:09:56 +0800 (Sat, 19 Jan 2008) $ $Id: FastByteArrayOutputStream.java 3000 2008-01-19 02:09:56Z tm_jee $
|
||||
*/
|
||||
public class FastByteArrayOutputStream extends OutputStream {
|
||||
|
||||
private static final int DEFAULT_BLOCK_SIZE = 8192;
|
||||
|
||||
private final ArrayDeque<byte[]> buffers = new ArrayDeque<>();
|
||||
|
||||
private byte[] buffer;
|
||||
private final int blockSize;
|
||||
private int index;
|
||||
private int size;
|
||||
|
||||
|
||||
public FastByteArrayOutputStream() {
|
||||
this(DEFAULT_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
public FastByteArrayOutputStream(int aSize) {
|
||||
blockSize = aSize;
|
||||
buffer = new byte[blockSize];
|
||||
}
|
||||
|
||||
public FastByteArrayOutputStream(byte[] buffer) {
|
||||
blockSize = buffer.length;
|
||||
this.buffer = buffer;
|
||||
}
|
||||
|
||||
public int getSize() {
|
||||
return size + index;
|
||||
}
|
||||
|
||||
public byte[][] toByteArrays() {
|
||||
if (index > 0) {
|
||||
byte[] buf2 = new byte[index];
|
||||
System.arraycopy(buffer, 0, buf2, 0, index);
|
||||
buffers.addLast(buf2);
|
||||
size += index;
|
||||
index = 0;
|
||||
}
|
||||
byte[][] res = new byte[buffers.size()][];
|
||||
int i = 0;
|
||||
for (byte[] bytes : buffers) {
|
||||
res[i++] = bytes;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public byte[] toByteArray() {
|
||||
if (buffers.isEmpty()) {
|
||||
if (buffer.length == index) {
|
||||
return buffer;
|
||||
}
|
||||
buffer = Arrays.copyOfRange(buffer, 0, index);
|
||||
return buffer;
|
||||
}
|
||||
byte[] data = new byte[getSize()];
|
||||
|
||||
// Check if we have a list of buffers
|
||||
int pos = 0;
|
||||
|
||||
for (byte[] bytes : buffers) {
|
||||
System.arraycopy(bytes, 0, data, pos, bytes.length);
|
||||
pos += bytes.length;
|
||||
}
|
||||
|
||||
// write the internal buffer directly
|
||||
System.arraycopy(buffer, 0, data, pos, index);
|
||||
|
||||
this.index = size + index;
|
||||
this.buffer = data;
|
||||
this.buffers.clear();
|
||||
return this.buffer;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return new String(toByteArray());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(byte[] b) throws IOException {
|
||||
if (b.length > blockSize) {
|
||||
if (index > 0) {
|
||||
byte[] buf2 = new byte[index];
|
||||
System.arraycopy(buffer, 0, buf2, 0, index);
|
||||
buffer = buf2;
|
||||
addBuffer();
|
||||
}
|
||||
size += b.length;
|
||||
buffers.addLast(b);
|
||||
} else {
|
||||
write(b, 0, b.length);
|
||||
}
|
||||
}
|
||||
|
||||
public void write(int datum) {
|
||||
if (index == blockSize) {
|
||||
addBuffer();
|
||||
}
|
||||
// store the byte
|
||||
buffer[index++] = (byte) datum;
|
||||
}
|
||||
|
||||
public void write(byte[] data, int offset, int length) throws IOException {
|
||||
if ((offset < 0) || ((offset + length) > data.length) || (length < 0)) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
} else {
|
||||
if ((index + length) > blockSize) {
|
||||
int copyLength;
|
||||
|
||||
do {
|
||||
if (index == blockSize) {
|
||||
addBuffer();
|
||||
}
|
||||
|
||||
copyLength = blockSize - index;
|
||||
|
||||
if (length < copyLength) {
|
||||
copyLength = length;
|
||||
}
|
||||
|
||||
System.arraycopy(data, offset, buffer, index, copyLength);
|
||||
offset += copyLength;
|
||||
index += copyLength;
|
||||
length -= copyLength;
|
||||
} while (length > 0);
|
||||
} else {
|
||||
// Copy in the subarray
|
||||
System.arraycopy(data, offset, buffer, index, length);
|
||||
index += length;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void writeTo(OutputStream out) throws IOException {
|
||||
// Check if we have a list of buffers
|
||||
if (buffers != null) {
|
||||
|
||||
for (byte[] bytes : buffers) {
|
||||
out.write(bytes, 0, blockSize);
|
||||
}
|
||||
}
|
||||
|
||||
// write the internal buffer directly
|
||||
out.write(buffer, 0, index);
|
||||
}
|
||||
|
||||
public void writeTo(RandomAccessFile out) throws IOException {
|
||||
// Check if we have a list of buffers
|
||||
if (buffers != null) {
|
||||
|
||||
for (byte[] bytes : buffers) {
|
||||
out.write(bytes, 0, blockSize);
|
||||
}
|
||||
}
|
||||
|
||||
// write the internal buffer directly
|
||||
out.write(buffer, 0, index);
|
||||
}
|
||||
|
||||
public void writeTo(Writer out, String encoding) throws IOException {
|
||||
if (buffers != null) {
|
||||
writeToViaSmoosh(out, encoding);
|
||||
} else {
|
||||
writeToViaString(out, encoding);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeToViaString(Writer out, String encoding) throws IOException {
|
||||
byte[] bufferToWrite = buffer; // this is always the last buffer to write
|
||||
int bufferToWriteLen = index; // index points to our place in the last buffer
|
||||
writeToImpl(out, encoding, bufferToWrite, bufferToWriteLen);
|
||||
}
|
||||
|
||||
private void writeToViaSmoosh(Writer out, String encoding) throws IOException {
|
||||
byte[] bufferToWrite = toByteArray();
|
||||
int bufferToWriteLen = bufferToWrite.length;
|
||||
writeToImpl(out, encoding, bufferToWrite, bufferToWriteLen);
|
||||
}
|
||||
|
||||
private void writeToImpl(Writer out, String encoding, byte[] bufferToWrite, int bufferToWriteLen)
|
||||
throws IOException {
|
||||
String writeStr;
|
||||
if (encoding != null) {
|
||||
writeStr = new String(bufferToWrite, 0, bufferToWriteLen, encoding);
|
||||
} else {
|
||||
writeStr = new String(bufferToWrite, 0, bufferToWriteLen);
|
||||
}
|
||||
out.write(writeStr);
|
||||
}
|
||||
|
||||
private void addBuffer() {
|
||||
buffers.addLast(buffer);
|
||||
buffer = new byte[blockSize];
|
||||
size += index;
|
||||
index = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
Arrays.fill(buffer, (byte) 0);
|
||||
index = 0;
|
||||
size = 0;
|
||||
buffers.clear();
|
||||
}
|
||||
}
|
@ -0,0 +1,110 @@
|
||||
package com.fastasyncworldedit.core.internal.io;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
public class FastByteArraysInputStream extends InputStream {
|
||||
private final byte[][] buffers;
|
||||
private final int length;
|
||||
|
||||
private byte[] current;
|
||||
|
||||
private int layer;
|
||||
private int localIndex;
|
||||
private int globalIndex;
|
||||
private int curLen;
|
||||
|
||||
|
||||
public FastByteArraysInputStream(byte[][] buffers) {
|
||||
this.buffers = buffers;
|
||||
int size = 0;
|
||||
for (byte[] bytes : buffers) {
|
||||
size += bytes.length;
|
||||
}
|
||||
this.length = size;
|
||||
current = buffers.length == 0 ? new byte[layer++] : buffers[layer++];
|
||||
curLen = current.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean markSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mark(int dummy) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int available() {
|
||||
return this.length - this.globalIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long skip(long n) {
|
||||
if (n <= this.length - this.globalIndex) {
|
||||
this.globalIndex += (int) n;
|
||||
this.localIndex += (int) n;
|
||||
ensureBuffer();
|
||||
return n;
|
||||
}
|
||||
n = this.length - this.globalIndex;
|
||||
layer = buffers.length - 1;
|
||||
this.current = buffers[layer];
|
||||
this.curLen = current.length;
|
||||
this.localIndex = current.length;
|
||||
this.globalIndex = this.length;
|
||||
return n;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() {
|
||||
if (curLen != localIndex) {
|
||||
globalIndex++;
|
||||
return this.current[localIndex++] & 0xFF;
|
||||
} else if (length == globalIndex) {
|
||||
return -1;
|
||||
} else {
|
||||
localIndex = 0;
|
||||
current = buffers[layer++];
|
||||
curLen = current.length;
|
||||
globalIndex++;
|
||||
return this.current[localIndex++] & 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(byte[] b, int offset, int length) {
|
||||
if (this.length <= this.globalIndex) {
|
||||
return length == 0 ? 0 : -1;
|
||||
}
|
||||
int n = Math.min(length, this.length - this.globalIndex);
|
||||
int read = 0;
|
||||
int amount = Math.min(curLen - localIndex, n - read);
|
||||
System.arraycopy(this.current, localIndex, b, offset + read, amount);
|
||||
read += amount;
|
||||
localIndex += amount;
|
||||
globalIndex += amount;
|
||||
ensureBuffer();
|
||||
return read;
|
||||
}
|
||||
|
||||
public void ensureBuffer() {
|
||||
while (localIndex >= curLen && layer < buffers.length) {
|
||||
localIndex -= curLen;
|
||||
current = buffers[layer++];
|
||||
this.curLen = current.length;
|
||||
}
|
||||
}
|
||||
|
||||
public long length() {
|
||||
return this.length;
|
||||
}
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
package com.fastasyncworldedit.core.internal.io;
|
||||
|
||||
import com.fastasyncworldedit.core.util.IOUtil;
|
||||
import com.sk89q.jnbt.NBTInputStream;
|
||||
import com.sk89q.jnbt.NamedTag;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class FaweInputStream extends DataInputStream {
|
||||
|
||||
private final InputStream parent;
|
||||
|
||||
public FaweInputStream(InputStream parent) {
|
||||
super(parent);
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public InputStream getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
public int readMedium() throws IOException {
|
||||
return (read() << 16) + (read() << 8) + read();
|
||||
}
|
||||
|
||||
private NBTInputStream nbtIn;
|
||||
|
||||
public void skipFully(int num) throws IOException {
|
||||
long skipped = skip(num);
|
||||
while (skipped != num) {
|
||||
skipped += skip(num - skipped);
|
||||
}
|
||||
}
|
||||
|
||||
public NamedTag readNBT() throws IOException {
|
||||
if (nbtIn == null) {
|
||||
nbtIn = new NBTInputStream(parent);
|
||||
}
|
||||
return nbtIn.readNamedTag();
|
||||
}
|
||||
|
||||
public Object readPrimitive(Class<?> clazz) throws IOException {
|
||||
if (clazz == long.class || clazz == Long.class) {
|
||||
return readLong();
|
||||
} else if (clazz == double.class || clazz == Double.class) {
|
||||
return readDouble();
|
||||
} else if (clazz == float.class || clazz == Float.class) {
|
||||
return readFloat();
|
||||
} else if (clazz == int.class || clazz == Integer.class) {
|
||||
return readInt();
|
||||
} else if (clazz == short.class || clazz == Short.class) {
|
||||
return readShort();
|
||||
} else if (clazz == char.class || clazz == Character.class) {
|
||||
return readChar();
|
||||
} else if (clazz == byte.class || clazz == Byte.class) {
|
||||
return readByte();
|
||||
} else if (clazz == boolean.class || clazz == Boolean.class) {
|
||||
return readBoolean();
|
||||
} else {
|
||||
throw new UnsupportedOperationException("Unknown class " + clazz);
|
||||
}
|
||||
}
|
||||
|
||||
public final int readVarInt() throws IOException {
|
||||
return IOUtil.readVarInt(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
if (nbtIn != null) {
|
||||
nbtIn.close();
|
||||
}
|
||||
parent.close();
|
||||
}
|
||||
}
|
@ -0,0 +1,95 @@
|
||||
package com.fastasyncworldedit.core.internal.io;
|
||||
|
||||
import com.sk89q.jnbt.NBTOutputStream;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public class FaweOutputStream extends DataOutputStream {
|
||||
|
||||
private final OutputStream parent;
|
||||
|
||||
public FaweOutputStream(OutputStream parent) {
|
||||
super(parent);
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public OutputStream getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
public void write(int b, int amount) throws IOException {
|
||||
for (int i = 0; i < amount; i++) {
|
||||
write(b);
|
||||
}
|
||||
}
|
||||
|
||||
public void writeShort(short s) throws IOException {
|
||||
write((byte) (s >>> 8));
|
||||
write((byte) (s));
|
||||
}
|
||||
|
||||
public void writeMedium(int m) throws IOException {
|
||||
write((byte) (m >>> 16));
|
||||
write((byte) (m >>> 8));
|
||||
write((byte) (m));
|
||||
}
|
||||
|
||||
public void writeVarInt(int i) throws IOException {
|
||||
while ((i & -128) != 0) {
|
||||
this.writeByte(i & 127 | 128);
|
||||
i >>>= 7;
|
||||
}
|
||||
this.writeByte(i);
|
||||
}
|
||||
|
||||
public void write(long[] data) throws IOException {
|
||||
this.writeVarInt(data.length);
|
||||
|
||||
for (long datum : data) {
|
||||
this.writeLong(datum);
|
||||
}
|
||||
}
|
||||
|
||||
private NBTOutputStream nbtOut;
|
||||
|
||||
public void writeNBT(String name, Tag tag) throws IOException {
|
||||
if (nbtOut == null) {
|
||||
nbtOut = new NBTOutputStream(parent);
|
||||
}
|
||||
nbtOut.writeNamedTag(name, tag);
|
||||
}
|
||||
|
||||
public void writePrimitive(Object value) throws IOException {
|
||||
Class<? extends Object> clazz = value.getClass();
|
||||
if (clazz == long.class || clazz == Long.class) {
|
||||
writeLong((long) value);
|
||||
} else if (clazz == double.class || clazz == Double.class) {
|
||||
writeDouble((double) value);
|
||||
} else if (clazz == float.class || clazz == Float.class) {
|
||||
writeFloat((float) value);
|
||||
} else if (clazz == int.class || clazz == Integer.class) {
|
||||
writeInt((int) value);
|
||||
} else if (clazz == short.class || clazz == Short.class) {
|
||||
writeShort((short) value);
|
||||
} else if (clazz == char.class || clazz == Character.class) {
|
||||
writeChar((char) value);
|
||||
} else if (clazz == byte.class || clazz == Byte.class) {
|
||||
writeByte((byte) value);
|
||||
} else if (clazz == boolean.class || clazz == Boolean.class) {
|
||||
writeBoolean((boolean) value);
|
||||
} else {
|
||||
throw new UnsupportedOperationException("Unknown class " + clazz);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
if (nbtOut != null) {
|
||||
nbtOut.close();
|
||||
}
|
||||
parent.close();
|
||||
}
|
||||
}
|
@ -0,0 +1,303 @@
|
||||
package com.fastasyncworldedit.core.internal.io;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.DataOutput;
|
||||
import java.io.FilterOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.UTFDataFormatException;
|
||||
|
||||
public class LittleEndianOutputStream extends FilterOutputStream implements DataOutput {
|
||||
|
||||
/**
|
||||
* The number of bytes written so far to the little endian output stream.
|
||||
*/
|
||||
protected int written;
|
||||
|
||||
/**
|
||||
* Creates a new little endian output stream and chains it to the
|
||||
* output stream specified by the out argument.
|
||||
*
|
||||
* @param out the underlying output stream.
|
||||
* @see FilterOutputStream#out
|
||||
*/
|
||||
public LittleEndianOutputStream(OutputStream out) {
|
||||
super(out);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the specified byte value to the underlying output stream.
|
||||
*
|
||||
* @param b the {@code byte} value to be written.
|
||||
* @exception IOException if the underlying stream throws an IOException.
|
||||
*/
|
||||
@Override
|
||||
public synchronized void write(int b) throws IOException {
|
||||
out.write(b);
|
||||
written++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes {@code length} bytes from the specified byte array
|
||||
* starting at {@code offset} to the underlying output stream.
|
||||
*
|
||||
* @param data the data.
|
||||
* @param offset the start offset in the data.
|
||||
* @param length the number of bytes to write.
|
||||
* @exception IOException if the underlying stream throws an IOException.
|
||||
*/
|
||||
@Override
|
||||
public synchronized void write(@NotNull byte[] data, int offset, int length)
|
||||
throws IOException {
|
||||
out.write(data, offset, length);
|
||||
written += length;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Writes a {@code boolean} to the underlying output stream as
|
||||
* a single byte. If the argument is true, the byte value 1 is written.
|
||||
* If the argument is false, the byte value {@code 0} in written.
|
||||
*
|
||||
* @param b the {@code boolean} value to be written.
|
||||
* @exception IOException if the underlying stream throws an IOException.
|
||||
*/
|
||||
@Override
|
||||
public void writeBoolean(boolean b) throws IOException {
|
||||
|
||||
if (b) {
|
||||
this.write(1);
|
||||
} else {
|
||||
this.write(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes out a {@code byte} to the underlying output stream
|
||||
*
|
||||
* @param b the {@code byte} value to be written.
|
||||
* @exception IOException if the underlying stream throws an IOException.
|
||||
*/
|
||||
@Override
|
||||
public void writeByte(int b) throws IOException {
|
||||
out.write(b);
|
||||
written++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a two byte {@code short} to the underlying output stream in
|
||||
* little endian order, low byte first.
|
||||
*
|
||||
* @param s the {@code short} to be written.
|
||||
* @exception IOException if the underlying stream throws an IOException.
|
||||
*/
|
||||
@Override
|
||||
public void writeShort(int s) throws IOException {
|
||||
|
||||
out.write(s & 0xFF);
|
||||
out.write((s >>> 8) & 0xFF);
|
||||
written += 2;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a two byte {@code char} to the underlying output stream
|
||||
* in little endian order, low byte first.
|
||||
*
|
||||
* @param c the {@code char} value to be written.
|
||||
* @exception IOException if the underlying stream throws an IOException.
|
||||
*/
|
||||
@Override
|
||||
public void writeChar(int c) throws IOException {
|
||||
|
||||
out.write(c & 0xFF);
|
||||
out.write((c >>> 8) & 0xFF);
|
||||
written += 2;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a four-byte {@code int} to the underlying output stream
|
||||
* in little endian order, low byte first, high byte last
|
||||
*
|
||||
* @param i the {@code int} to be written.
|
||||
* @exception IOException if the underlying stream throws an IOException.
|
||||
*/
|
||||
@Override
|
||||
public void writeInt(int i) throws IOException {
|
||||
|
||||
out.write(i & 0xFF);
|
||||
out.write((i >>> 8) & 0xFF);
|
||||
out.write((i >>> 16) & 0xFF);
|
||||
out.write((i >>> 24) & 0xFF);
|
||||
written += 4;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes an eight-byte {@code long} to the underlying output stream
|
||||
* in little endian order, low byte first, high byte last
|
||||
*
|
||||
* @param l the {@code long} to be written.
|
||||
* @exception IOException if the underlying stream throws an IOException.
|
||||
*/
|
||||
@Override
|
||||
public void writeLong(long l) throws IOException {
|
||||
|
||||
out.write((int) l & 0xFF);
|
||||
out.write((int) (l >>> 8) & 0xFF);
|
||||
out.write((int) (l >>> 16) & 0xFF);
|
||||
out.write((int) (l >>> 24) & 0xFF);
|
||||
out.write((int) (l >>> 32) & 0xFF);
|
||||
out.write((int) (l >>> 40) & 0xFF);
|
||||
out.write((int) (l >>> 48) & 0xFF);
|
||||
out.write((int) (l >>> 56) & 0xFF);
|
||||
written += 8;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a 4 byte Java float to the underlying output stream in
|
||||
* little endian order.
|
||||
*
|
||||
* @param f the {@code float} value to be written.
|
||||
* @exception IOException if an I/O error occurs.
|
||||
*/
|
||||
@Override
|
||||
public final void writeFloat(float f) throws IOException {
|
||||
|
||||
this.writeInt(Float.floatToIntBits(f));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes an 8 byte Java double to the underlying output stream in
|
||||
* little endian order.
|
||||
*
|
||||
* @param d the {@code double} value to be written.
|
||||
* @exception IOException if an I/O error occurs.
|
||||
*/
|
||||
@Override
|
||||
public final void writeDouble(double d) throws IOException {
|
||||
|
||||
this.writeLong(Double.doubleToLongBits(d));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a string to the underlying output stream as a sequence of
|
||||
* bytes. Each character is written to the data output stream as
|
||||
* if by the {@code writeByte()} method.
|
||||
*
|
||||
* @param s the {@code String} value to be written.
|
||||
* @exception IOException if the underlying stream throws an IOException.
|
||||
* @see java.io.DataOutputStream#writeByte(int)
|
||||
* @see java.io.DataOutputStream#out
|
||||
*/
|
||||
@Override
|
||||
public void writeBytes(String s) throws IOException {
|
||||
|
||||
int length = s.length();
|
||||
for (int i = 0; i < length; i++) {
|
||||
out.write((byte) s.charAt(i));
|
||||
}
|
||||
written += length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a string to the underlying output stream as a sequence of
|
||||
* characters. Each character is written to the data output stream as
|
||||
* if by the {@code writeChar} method.
|
||||
*
|
||||
* @param s a {@code String} value to be written.
|
||||
* @exception IOException if the underlying stream throws an IOException.
|
||||
* @see java.io.DataOutputStream#writeChar(int)
|
||||
* @see java.io.DataOutputStream#out
|
||||
*/
|
||||
@Override
|
||||
public void writeChars(String s) throws IOException {
|
||||
|
||||
int length = s.length();
|
||||
for (int i = 0; i < length; i++) {
|
||||
int c = s.charAt(i);
|
||||
out.write(c & 0xFF);
|
||||
out.write((c >>> 8) & 0xFF);
|
||||
}
|
||||
written += length * 2;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a string of no more than 65,535 characters
|
||||
* to the underlying output stream using UTF-8
|
||||
* encoding. This method first writes a two byte short
|
||||
* in <b>big</b> endian order as required by the
|
||||
* UTF-8 specification. This gives the number of bytes in the
|
||||
* UTF-8 encoded version of the string, not the number of characters
|
||||
* in the string. Next each character of the string is written
|
||||
* using the UTF-8 encoding for the character.
|
||||
*
|
||||
* @param s the string to be written.
|
||||
* @exception UTFDataFormatException if the string is longer than
|
||||
* 65,535 characters.
|
||||
* @exception IOException if the underlying stream throws an IOException.
|
||||
*/
|
||||
@Override
|
||||
public void writeUTF(String s) throws IOException {
|
||||
|
||||
int numchars = s.length();
|
||||
int numbytes = 0;
|
||||
|
||||
for (int i = 0 ; i < numchars ; i++) {
|
||||
int c = s.charAt(i);
|
||||
if ((c >= 0x0001) && (c <= 0x007F)) {
|
||||
numbytes++;
|
||||
} else if (c > 0x07FF) {
|
||||
numbytes += 3;
|
||||
} else {
|
||||
numbytes += 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (numbytes > 65535) {
|
||||
throw new UTFDataFormatException();
|
||||
}
|
||||
|
||||
out.write((numbytes >>> 8) & 0xFF);
|
||||
out.write(numbytes & 0xFF);
|
||||
for (int i = 0 ; i < numchars ; i++) {
|
||||
int c = s.charAt(i);
|
||||
if ((c >= 0x0001) && (c <= 0x007F)) {
|
||||
out.write(c);
|
||||
}
|
||||
else if (c > 0x07FF) {
|
||||
out.write(0xE0 | ((c >> 12) & 0x0F));
|
||||
out.write(0x80 | ((c >> 6) & 0x3F));
|
||||
out.write(0x80 | (c & 0x3F));
|
||||
written += 2;
|
||||
}
|
||||
else {
|
||||
out.write(0xC0 | ((c >> 6) & 0x1F));
|
||||
out.write(0x80 | (c & 0x3F));
|
||||
written += 1;
|
||||
}
|
||||
}
|
||||
|
||||
written += numchars + 2;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of bytes written to this little endian output stream.
|
||||
* (This class is not thread-safe with respect to this method. It is
|
||||
* possible that this number is temporarily less than the actual
|
||||
* number of bytes written.)
|
||||
* @return the value of the {@code written} field.
|
||||
*/
|
||||
public int size() {
|
||||
return this.written;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
package com.fastasyncworldedit.core.internal.io;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class NonCloseableInputStream extends InputStream {
|
||||
|
||||
private final InputStream parent;
|
||||
|
||||
public NonCloseableInputStream(InputStream parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
return parent.read();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(byte[] b) throws IOException {
|
||||
return parent.read(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(byte[] b, int off, int len) throws IOException {
|
||||
return parent.read(b, off, len);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long skip(long n) throws IOException {
|
||||
return parent.skip(n);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int available() throws IOException {
|
||||
return parent.available();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mark(int readlimit) {
|
||||
parent.mark(readlimit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() throws IOException {
|
||||
parent.reset();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean markSupported() {
|
||||
return parent.markSupported();
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
package com.fastasyncworldedit.core.internal.io;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FilterInputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.channels.FileChannel;
|
||||
|
||||
public class ResettableFileInputStream extends FilterInputStream {
|
||||
private final FileChannel myFileChannel;
|
||||
private long mark = 0;
|
||||
|
||||
public ResettableFileInputStream(FileInputStream fis) {
|
||||
super(fis);
|
||||
myFileChannel = fis.getChannel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean markSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void mark(int readlimit) {
|
||||
try {
|
||||
mark = myFileChannel.position();
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
mark = -1;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void reset() throws IOException {
|
||||
if (mark == -1) {
|
||||
throw new IOException("not marked");
|
||||
}
|
||||
myFileChannel.position(mark);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user