Skip to content

Commit

Permalink
Allow finding schematic format by InputStream (#2249)
Browse files Browse the repository at this point in the history
* Allow finding schematic format by InputStream

* .

* Don't auto-close the stream

* Fix up based on feedback

* checkstyle
  • Loading branch information
me4502 committed Apr 2, 2023
1 parent df3f7b2 commit c7d559b
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 17 deletions.
18 changes: 18 additions & 0 deletions verification/src/changes/accepted-core-public-api-changes.json
Original file line number Diff line number Diff line change
Expand Up @@ -192,5 +192,23 @@
"FIELD_NOW_FINAL"
]
}
],
"This now delegates to the InputStream method if not implemented": [
{
"type": "com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat",
"member": "Method com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat.isFormat(java.io.File)",
"changes": [
"METHOD_ABSTRACT_NOW_DEFAULT"
]
}
],
"New method added with default implementation": [
{
"type": "com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat",
"member": "Method com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat.isFormat(java.io.InputStream)",
"changes": [
"METHOD_NEW_DEFAULT"
]
}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,6 @@ default boolean clearContainerBlockContents(World world, BlockVector3 pt) {
}

/**
<<<<<<< HEAD
* Checks if this adapter supports custom biomes.
* @return if custom biomes are supported
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@
package com.sk89q.worldedit.extent.clipboard.io;

import com.google.common.collect.ImmutableSet;
import com.sk89q.jnbt.NBTInputStream;
import com.sk89q.jnbt.NBTOutputStream;
import com.sk89q.worldedit.extent.clipboard.io.sponge.SpongeSchematicV1Reader;
import com.sk89q.worldedit.extent.clipboard.io.sponge.SpongeSchematicV2Reader;
import com.sk89q.worldedit.extent.clipboard.io.sponge.SpongeSchematicV2Writer;
Expand All @@ -35,8 +33,6 @@

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
Expand Down Expand Up @@ -72,9 +68,12 @@ public ClipboardWriter getWriter(OutputStream outputStream) throws IOException {
}

@Override
public boolean isFormat(File file) {
public boolean isFormat(InputStream inputStream) {
LinRootEntry rootEntry;
try (var stream = new DataInputStream(new GZIPInputStream(new FileInputStream(file)))) {
try {
DataInputStream stream = inputStream instanceof DataInputStream dataInputStream
? dataInputStream
: new DataInputStream(inputStream);
rootEntry = LinBinaryIO.readUsing(stream, LinRootEntry::readFrom);
} catch (Exception e) {
return false;
Expand Down Expand Up @@ -105,8 +104,8 @@ public ClipboardWriter getWriter(OutputStream outputStream) throws IOException {
}

@Override
public boolean isFormat(File file) {
return detectOldSpongeSchematic(file, 1);
public boolean isFormat(InputStream inputStream) {
return detectOldSpongeSchematic(inputStream, 1);
}
},
SPONGE_V2_SCHEMATIC("sponge.2") {
Expand All @@ -129,8 +128,8 @@ public ClipboardWriter getWriter(OutputStream outputStream) throws IOException {
}

@Override
public boolean isFormat(File file) {
return detectOldSpongeSchematic(file, 2);
public boolean isFormat(InputStream inputStream) {
return detectOldSpongeSchematic(inputStream, 2);
}
},
SPONGE_V3_SCHEMATIC("sponge.3", "sponge", "schem") {
Expand All @@ -153,9 +152,12 @@ public ClipboardWriter getWriter(OutputStream outputStream) throws IOException {
}

@Override
public boolean isFormat(File file) {
public boolean isFormat(InputStream inputStream) {
LinCompoundTag root;
try (var stream = new DataInputStream(new GZIPInputStream(new FileInputStream(file)))) {
try {
DataInputStream stream = inputStream instanceof DataInputStream dataInputStream
? dataInputStream
: new DataInputStream(inputStream);
root = LinBinaryIO.readUsing(stream, LinRootEntry::readFrom).value();
} catch (Exception e) {
return false;
Expand All @@ -173,9 +175,12 @@ public boolean isFormat(File file) {
},
;

private static boolean detectOldSpongeSchematic(File file, int version) {
private static boolean detectOldSpongeSchematic(InputStream inputStream, int version) {
LinRootEntry rootEntry;
try (var stream = new DataInputStream(new GZIPInputStream(new FileInputStream(file)))) {
try {
DataInputStream stream = inputStream instanceof DataInputStream dataInputStream
? dataInputStream
: new DataInputStream(inputStream);
rootEntry = LinBinaryIO.readUsing(stream, LinRootEntry::readFrom);
} catch (Exception e) {
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.util.Set;
import java.util.zip.GZIPInputStream;

/**
* A collection of supported clipboard formats.
Expand Down Expand Up @@ -68,7 +70,29 @@ public interface ClipboardFormat {
* @param file the file
* @return true if the given file is of this format
*/
boolean isFormat(File file);
default boolean isFormat(File file) {
try (InputStream stream = new GZIPInputStream(Files.newInputStream(file.toPath()))) {
return isFormat(stream);
} catch (IOException e) {
return false;
}
}

/**
* Return whether the given stream is of this format.
*
* @apiNote The caller is responsible for the following:
* <ul>
* <li>Closing the input stream</li>
* <li>Ensuring the data is directly readable, such as not being in GZip format</li>
* </ul>
*
* @param inputStream The stream
* @return true if the given stream is of this format
*/
default boolean isFormat(InputStream inputStream) {
return false;
}

/**
* Get the file extension this format primarily uses.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,16 @@
import com.sk89q.worldedit.WorldEdit;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.function.Supplier;
import javax.annotation.Nullable;

import static com.google.common.base.Preconditions.checkNotNull;
Expand Down Expand Up @@ -80,7 +83,7 @@ public static ClipboardFormat findByAlias(String alias) {
}

/**
* Detect the format of given a file.
* Detect the format of a given file.
*
* @param file
* the file
Expand All @@ -99,6 +102,29 @@ public static ClipboardFormat findByFile(File file) {
return null;
}

/**
* Detect the format of a given input stream.
*
* @apiNote The caller is responsible for ensuring the stream is in a readable format, such as removing GZip compression.
*
* @param inputStreamSupplier The input stream supplier
* @return the format, otherwise null if one cannot be detected
*/
@Nullable
public static ClipboardFormat findByInputStream(Supplier<InputStream> inputStreamSupplier) {
checkNotNull(inputStreamSupplier);

for (ClipboardFormat format : registeredFormats) {
try (var stream = inputStreamSupplier.get()) {
if (format.isFormat(stream)) {
return format;
}
} catch (IOException ignored) { }
}

return null;
}

/**
* A mapping from extensions to formats.
*
Expand Down

0 comments on commit c7d559b

Please sign in to comment.