update code style

This commit is contained in:
huangyuhui
2016-01-01 11:03:09 +08:00
parent 1f7eb04215
commit b82243a9c0
298 changed files with 3902 additions and 3998 deletions

View File

@@ -151,7 +151,7 @@ public final class Launcher {
int flag = 0;
try {
minecraftMain.invoke(null, new Object[]{(String[]) cmdList.toArray(new String[cmdList.size()])});
minecraftMain.invoke(null, new Object[] { (String[]) cmdList.toArray(new String[cmdList.size()]) });
} catch (Throwable throwable) {
String trace = StrUtils.getStackTrace(throwable);
final String advice = MinecraftCrashAdvicer.getAdvice(trace);
@@ -174,15 +174,16 @@ public final class Launcher {
}
}
/*
static Object getShutdownHaltLock() {
try {
Class z = Class.forName("java.lang.Shutdown");
Field haltLock = z.getDeclaredField("haltLock");
haltLock.setAccessible(true);
return haltLock.get(null);
} catch (Throwable ex) {
ex.printStackTrace();
return new Object();
}
}*/
* static Object getShutdownHaltLock() {
* try {
* Class z = Class.forName("java.lang.Shutdown");
* Field haltLock = z.getDeclaredField("haltLock");
* haltLock.setAccessible(true);
* return haltLock.get(null);
* } catch (Throwable ex) {
* ex.printStackTrace();
* return new Object();
* }
* }
*/
}

View File

@@ -76,7 +76,7 @@ public final class Main implements Runnable {
try {
sslContext = SSLContext.getInstance("TLS");
X509TrustManager[] xtmArray = new X509TrustManager[]{XTM};
X509TrustManager[] xtmArray = new X509TrustManager[] { XTM };
sslContext.init(null, xtmArray, new java.security.SecureRandom());
} catch (GeneralSecurityException gse) {
}
@@ -112,7 +112,7 @@ public final class Main implements Runnable {
public static final Main INSTANCE = new Main();
public static HelloMinecraftLookAndFeel LOOK_AND_FEEL;
@SuppressWarnings({"CallToPrintStackTrace", "UseSpecificCatch"})
@SuppressWarnings({ "CallToPrintStackTrace", "UseSpecificCatch" })
public static void main(String[] args) {
{
//PluginManager.getServerPlugin();

View File

@@ -34,6 +34,7 @@ public interface IPlugin {
* You can modify the application actions by this method.
*
* @param profile info to the Minecraft Loader
*
* @return For example, you can implement IMinecraftProvider to support
* MultiMC
*/

View File

@@ -18,7 +18,6 @@
package org.jackhuang.hellominecraft.launcher.launch;
import java.io.IOException;
import javax.swing.SwingUtilities;
import org.jackhuang.hellominecraft.C;
import org.jackhuang.hellominecraft.HMCLog;
import org.jackhuang.hellominecraft.launcher.launch.GameLauncher.DownloadLibraryJob;

View File

@@ -111,7 +111,7 @@ public class GameLauncher {
return null;
}
List<String> lst = null;
List<String> lst;
try {
lst = loader.makeLaunchingCommand();
} catch (Exception e) {

View File

@@ -39,8 +39,6 @@ public abstract class IMinecraftDownloadService extends IMinecraftService {
public abstract boolean downloadMinecraftVersionJson(String id);
/**
* Get the libraries that need to download.
*

View File

@@ -74,6 +74,7 @@ public abstract class IMinecraftProvider {
/**
*
* @param v should be resolved
*
* @return libraries of resolved minecraft version v.
*/
public abstract GameLauncher.DecompressLibraryJob getDecompressLibraries(MinecraftVersion v);

View File

@@ -24,6 +24,7 @@ import org.jackhuang.hellominecraft.launcher.settings.Profile;
* @author huangyuhui
*/
public abstract class IMinecraftService {
public Profile profile;
public IMinecraftService(Profile profile) {

View File

@@ -17,7 +17,6 @@
*/
package org.jackhuang.hellominecraft.launcher.utils.assets;
/**
*
* @author huangyuhui

View File

@@ -46,6 +46,7 @@ public abstract class IAuthenticator {
* @param info username & password
*
* @return login result
*
* @throws
* org.jackhuang.hellominecraft.launcher.utils.auth.AuthenticationException
*/

View File

@@ -27,7 +27,7 @@ import org.jackhuang.hellominecraft.launcher.utils.installers.InstallerVersionLi
public abstract class IDownloadProvider {
public InstallerVersionList getInstallerByType(InstallerType type) {
switch(type) {
switch (type) {
case Forge:
return getForgeInstaller();
case LiteLoader:

View File

@@ -44,7 +44,7 @@ public final class InstallerService {
}
public Task download(InstallerVersion v, InstallerType type) {
switch(type) {
switch (type) {
case Forge:
return downloadForge(v);
case Optifine:

View File

@@ -30,7 +30,6 @@ public enum InstallerType {
this.id = id;
}
public String getLocalizedName() {
return this.name();
}

View File

@@ -48,6 +48,7 @@ public abstract class InstallerVersionList implements Consumer<String[]> {
* Get installers you want.
*
* @param mcVersion the installers to this Minecraft version.
*
* @return cached result.
*/
protected abstract List<InstallerVersion> getVersionsImpl(String mcVersion);
@@ -56,6 +57,7 @@ public abstract class InstallerVersionList implements Consumer<String[]> {
* Get installers you want, please cache this method's result to save time.
*
* @param mcVersion the installers to this Minecraft version.
*
* @return a copy of the cached data to prevent
* ConcurrentModificationException.
*/

View File

@@ -76,9 +76,11 @@ public class ForgeInstaller extends Task {
FileUtils.copyFile(new File(from, profile.install.minecraft + ".jar"),
new File(to, profile.install.target + ".jar"));
HMCLog.log("Creating new version profile..." + profile.install.target + ".json");
/*for (MinecraftLibrary library : profile.versionInfo.libraries)
if (library.name.startsWith("net.minecraftforge:forge:"))
library.url = installerVersion.universal;*/
/*
* for (MinecraftLibrary library : profile.versionInfo.libraries)
* if (library.name.startsWith("net.minecraftforge:forge:"))
* library.url = installerVersion.universal;
*/
FileUtils.write(new File(to, profile.install.target + ".json"), C.gsonPrettyPrinting.toJson(profile.versionInfo));
HMCLog.log("Extracting universal forge pack..." + profile.install.filePath);

View File

@@ -74,9 +74,9 @@ public class AppDataUpgrader extends IUpgrader {
if (mainClass != null) {
ArrayList<String> al = new ArrayList<>(Arrays.asList(args));
al.add("notfound");
new URLClassLoader(new URL[] {jar.toURI().toURL()},
new URLClassLoader(new URL[] { jar.toURI().toURL() },
URLClassLoader.getSystemClassLoader().getParent()).loadClass(mainClass)
.getMethod("main", String[].class).invoke(null, new Object[] {al.toArray(new String[0])});
.getMethod("main", String[].class).invoke(null, new Object[] { al.toArray(new String[0]) });
return true;
}
}
@@ -95,7 +95,7 @@ public class AppDataUpgrader extends IUpgrader {
if (map != null && map.containsKey("pack"))
try {
if (TaskWindow.getInstance().addTask(new AppDataUpgraderTask(map.get("pack"), number.version)).start()) {
new ProcessBuilder(new String[] {IOUtils.getJavaDir(), "-jar", AppDataUpgraderTask.getSelf(number.version).getAbsolutePath()}).directory(new File(".")).start();
new ProcessBuilder(new String[] { IOUtils.getJavaDir(), "-jar", AppDataUpgraderTask.getSelf(number.version).getAbsolutePath() }).directory(new File(".")).start();
System.exit(0);
}
} catch (IOException ex) {

View File

@@ -35,6 +35,7 @@ public abstract class IUpgrader implements Event<VersionNumber> {
*
* @param nowVersion now launcher version
* @param args Application CommandLine Arguments
*
* @return true if it is needed to break the main thread to shutdown this
* application.
*/
@@ -45,6 +46,7 @@ public abstract class IUpgrader implements Event<VersionNumber> {
*
* @param sender Should be VersionChecker
* @param number the newest version
*
* @return should return true
*/
@Override

View File

@@ -52,7 +52,7 @@ public class NewFileUpgrader extends IUpgrader {
File newf = new File(FileUtils.getName(str));
if (TaskWindow.getInstance().addTask(new FileDownloadTask(str, newf)).start()) {
try {
new ProcessBuilder(new String[] {IOUtils.tryGetCanonicalFilePath(newf), "--removeOldLauncher", IOUtils.getRealPath()}).directory(new File(".")).start();
new ProcessBuilder(new String[] { IOUtils.tryGetCanonicalFilePath(newf), "--removeOldLauncher", IOUtils.getRealPath() }).directory(new File(".")).start();
} catch (IOException ex) {
HMCLog.err("Failed to start new app", ex);
}

View File

@@ -40,6 +40,7 @@ import rx.Observable;
* @author huangyuhui
*/
public class MinecraftDownloadService extends IMinecraftDownloadService {
MinecraftVersionManager mgr;
public MinecraftDownloadService(Profile p, MinecraftVersionManager mgr) {

View File

@@ -273,10 +273,10 @@ public class MinecraftVersionManager extends IMinecraftProvider {
for (MinecraftVersion s : getVersions()) {
FileUtils.deleteDirectoryQuietly(new File(profile.getGameDirFile(), "versions" + File.separator + s.id + File.separator + s.id + "-natives"));
File f = getRunDirectory(s.id);
String[] dir = {"logs", "asm", "NVIDIA", "crash-reports", "server-resource-packs", "natives", "native"};
String[] dir = { "logs", "asm", "NVIDIA", "crash-reports", "server-resource-packs", "natives", "native" };
for (String str : dir)
FileUtils.deleteDirectoryQuietly(new File(f, str));
String[] files = {"output-client.log", "usercache.json", "usernamecache.json", "hmclmc.log"};
String[] files = { "output-client.log", "usercache.json", "usernamecache.json", "hmclmc.log" };
for (String str : files)
new File(f, str).delete();
}

View File

@@ -42,10 +42,9 @@ public class GameDownloadPanel extends AnimatedPanel implements Selectable {
}
/**
* This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
@@ -110,8 +109,8 @@ public class GameDownloadPanel extends AnimatedPanel implements Selectable {
DefaultTableModel model = SwingUtils.clearDefaultTable(lstDownloads);
gsp.getProfile().getMinecraftProvider().getDownloadService().getRemoteVersions()
.observeOn(Schedulers.eventQueue()).subscribeOn(Schedulers.newThread())
.subscribe((ver) -> model.addRow(new Object[] {ver.id, ver.time,
StrUtils.equalsOne(ver.type, "old_beta", "old_alpha", "release", "snapshot") ? C.i18n("versions." + ver.type) : ver.type}),
.subscribe((ver) -> model.addRow(new Object[] { ver.id, ver.time,
StrUtils.equalsOne(ver.type, "old_beta", "old_alpha", "release", "snapshot") ? C.i18n("versions." + ver.type) : ver.type }),
(e) -> {
MessageBox.Show("Failed to refresh download: " + e.getLocalizedMessage());
HMCLog.err("Failed to refresh download.", e);

View File

@@ -1251,7 +1251,7 @@ public final class GameSettingsPanel extends AnimatedPanel implements DropTarget
.subscribeOn(Schedulers.newThread()).observeOn(Schedulers.eventQueue())
.subscribe(t -> {
for (ModInfo x : t)
model.addRow(new Object[]{x.isActive(), x, x.version});
model.addRow(new Object[] { x.isActive(), x, x.version });
reloadingMods = false;
});
}

View File

@@ -30,7 +30,7 @@ import javax.swing.JLabel;
* @author huangyuhui
*/
public class HeaderTab extends JLabel
implements MouseListener {
implements MouseListener {
private boolean isActive;
private final DefaultButtonModel model;

View File

@@ -124,7 +124,7 @@ public class InstallerPanel extends AnimatedPanel implements Selectable {
void refreshVersions() {
if (TaskWindow.getInstance().addTask(new TaskRunnableArg1<>(C.i18n("install." + id.id + ".get_list"), list)
.registerPreviousResult(new DefaultPreviousResult<>(new String[]{gsp.getMinecraftVersionFormatted()})))
.registerPreviousResult(new DefaultPreviousResult<>(new String[] { gsp.getMinecraftVersionFormatted() })))
.start())
loadVersions();
}
@@ -152,7 +152,7 @@ public class InstallerPanel extends AnimatedPanel implements Selectable {
if (versions != null)
for (InstallerVersionList.InstallerVersion v : versions)
if (v != null)
model.addRow(new Object[]{v.selfVersion == null ? "null" : v.selfVersion, v.mcVersion == null ? "null" : v.mcVersion});
model.addRow(new Object[] { v.selfVersion == null ? "null" : v.selfVersion, v.mcVersion == null ? "null" : v.mcVersion });
}
});
}

View File

@@ -39,10 +39,9 @@ public class ServerListCellRenderer extends javax.swing.JPanel implements ListCe
}
/**
* This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents

View File

@@ -57,10 +57,9 @@ public class ServerListView extends javax.swing.JDialog {
public static final int FAILED_TO_SELECT = -1;
/**
* This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents

View File

@@ -22,7 +22,7 @@ package org.jackhuang.hellominecraft.logging.message;
* @author huangyuhui
*/
public abstract class AbstractMessageFactory
implements IMessageFactory {
implements IMessageFactory {
@Override
public IMessage newMessage(Object message) {

View File

@@ -18,7 +18,7 @@
package org.jackhuang.hellominecraft.logging.message;
public class ObjectMessage
implements IMessage {
implements IMessage {
private static final long serialVersionUID = -5903272448334166185L;
private final transient Object obj;
@@ -41,7 +41,7 @@ implements IMessage {
@Override
public Object[] getParameters() {
return new Object[] {this.obj};
return new Object[] { this.obj };
}
@Override

View File

@@ -68,11 +68,11 @@ public class ParameterizedMessage
}
public ParameterizedMessage(String messagePattern, Object arg) {
this(messagePattern, new Object[] {arg});
this(messagePattern, new Object[] { arg });
}
public ParameterizedMessage(String messagePattern, Object arg1, Object arg2) {
this(messagePattern, new Object[] {arg1, arg2});
this(messagePattern, new Object[] { arg1, arg2 });
}
private String[] parseArguments(Object[] arguments) {

View File

@@ -22,7 +22,7 @@ package org.jackhuang.hellominecraft.logging.message;
* @author huangyuhui
*/
public class SimpleMessage
implements IMessage {
implements IMessage {
private static final long serialVersionUID = -8398002534962715992L;
private final String message;

View File

@@ -21,7 +21,7 @@ import java.util.Arrays;
import java.util.IllegalFormatException;
public class StringFormattedMessage
implements IMessage {
implements IMessage {
private static final long serialVersionUID = -665975803997290697L;
private final String messagePattern;

View File

@@ -32,7 +32,8 @@ public class DoubleTask extends Task {
@Override
public void executeTask() throws Throwable {
a.executeTask(); b.executeTask();
a.executeTask();
b.executeTask();
}
@Override

View File

@@ -113,7 +113,7 @@ public abstract class Task {
public void run() {
try {
executeTask();
} catch(Throwable t) {
} catch (Throwable t) {
HMCLog.err("Failed to execute task", t);
}
}

View File

@@ -38,7 +38,8 @@ public class TaskObservable<T> extends TaskInfo {
@Override
public void executeTask() {
r.subscribe(t->{});
r.subscribe(t -> {
});
}
}

View File

@@ -113,15 +113,13 @@ public class FileDownloadTask extends Task implements PreviousResult<File>, Prev
connection.connect();
// Make sure response code is in the 200 range.
if (connection.getResponseCode() / 100 != 2) {
if (connection.getResponseCode() / 100 != 2)
throw new NetException(C.i18n("download.not_200") + " " + connection.getResponseCode());
}
// Check for valid content length.
int contentLength = connection.getContentLength();
if (contentLength < 1) {
if (contentLength < 1)
throw new NetException("The content length is invalid.");
}
filePath.getParentFile().mkdirs();
@@ -179,7 +177,8 @@ public class FileDownloadTask extends Task implements PreviousResult<File>, Prev
closeFiles();
}
}
if (failReason != null) throw failReason;
if (failReason != null)
throw failReason;
}
public static void download(String url, String file, DownloadListener dl) throws Throwable {

View File

@@ -76,7 +76,8 @@ public class HTTPGetTask extends TaskInfo implements PreviousResult<String> {
t = new NetException("Failed to get " + url, ex);
}
}
if (t != null) throw t;
if (t != null)
throw t;
}
@Override

View File

@@ -32,22 +32,29 @@ public interface IUpdateChecker {
void checkOutdate();
/**
* Get the <b>cached</b> newest version number, use "process" method to download!
* Get the <b>cached</b> newest version number, use "process" method to
* download!
*
* @return the newest version number
*
* @see process
*/
VersionNumber getNewVersion();
/**
* Download the version number synchronously.
* When you execute this method first, should leave "showMessage" false.
* @param showMessage If it is requested to warn the user that there is a new version.
* Download the version number synchronously. When you execute this method
* first, should leave "showMessage" false.
*
* @param showMessage If it is requested to warn the user that there is a
* new version.
*
* @return the process observable.
*/
Observable process(boolean showMessage);
/**
* Get the download links.
*
* @return a JSON, which contains the server response.
*/
Observable<Map<String, String>> requestDownloadLink();

View File

@@ -53,7 +53,8 @@ public final class NetUtils {
public static String getStreamContent(InputStream is, String encoding)
throws IOException {
if (is == null) return null;
if (is == null)
return null;
StringBuilder sb = new StringBuilder();
try (InputStreamReader br = new InputStreamReader(is, encoding)) {
int len;
@@ -162,7 +163,7 @@ public final class NetUtils {
return Observable.createWithEmptySubscription(t1 -> {
try {
t1.onNext(get(url));
} catch(Exception e) {
} catch (Exception e) {
t1.onError(e);
}
});

View File

@@ -54,10 +54,14 @@ public final class StrUtils {
cmdbuf.append("\\");
cmdbuf.append('"');
} else if (s.endsWith("\""))
/* The argument has already been quoted. */
/*
* The argument has already been quoted.
*/
cmdbuf.append(s);
else
/* Unmatched quote for the argument. */
/*
* Unmatched quote for the argument.
*/
throw new IllegalArgumentException();
else
cmdbuf.append(s);

View File

@@ -23,9 +23,9 @@ public class Hex {
public static final Charset DEFAULT_CHARSET = Charsets.UTF_8;
public static final String DEFAULT_CHARSET_NAME = "UTF-8";
private static final char[] DIGITS_LOWER = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
private static final char[] DIGITS_LOWER = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
private static final char[] DIGITS_UPPER = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
private static final char[] DIGITS_UPPER = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
private final Charset charset;
public static byte[] decodeHex(char[] data) throws Exception {

View File

@@ -72,9 +72,9 @@ public class Java {
}
/*
-----------------------------------
MAC OS X
-----------------------------------
* -----------------------------------
* MAC OS X
* -----------------------------------
*/
public static List<Java> queryAllJDKInMac() {
List<Java> ans = new ArrayList<>();
@@ -88,9 +88,9 @@ public class Java {
}
/*
-----------------------------------
WINDOWS
-----------------------------------
* -----------------------------------
* WINDOWS
* -----------------------------------
*/
public static List<Java> queryAllJavaHomeInWindowsByReg() {
List<Java> ans = new ArrayList<>();
@@ -126,7 +126,7 @@ public class Java {
}
private static List<String> queryRegSubFolders(String location) throws IOException, InterruptedException {
String[] cmd = new String[] {"cmd", "/c", "reg", "query", location};
String[] cmd = new String[] { "cmd", "/c", "reg", "query", location };
List<String> l = IOUtils.readProcessByInputStream(cmd);
List<String> ans = new ArrayList<>();
for (String line : l)
@@ -136,7 +136,7 @@ public class Java {
}
private static String queryRegValue(String location, String name) throws IOException, InterruptedException {
String[] cmd = new String[] {"cmd", "/c", "reg", "query", location, "/v", name};
String[] cmd = new String[] { "cmd", "/c", "reg", "query", location, "/v", name };
List<String> l = IOUtils.readProcessByInputStream(cmd);
boolean last = false;
for (String s : l) {

View File

@@ -166,7 +166,7 @@ public final class JdkVersion {
private static final Pattern p = Pattern.compile("java version \"[1-9]*\\.[1-9]*\\.[0-9]*(.*?)\"");
public static JdkVersion getJavaVersionFromExecutable(String file) throws IOException {
String[] str = new String[] {file, "-version"};
String[] str = new String[] { file, "-version" };
Platform platform = Platform.BIT_32;
String ver = null;
try {

View File

@@ -28,7 +28,7 @@ import java.awt.image.Raster;
import java.awt.image.WritableRaster;
public abstract class AbstractFilter
implements BufferedImageOp {
implements BufferedImageOp {
@Override
public abstract BufferedImage filter(BufferedImage paramBufferedImage1, BufferedImage paramBufferedImage2);

View File

@@ -33,31 +33,32 @@ public class LogWindowOutputStream extends OutputStream {
private final LogWindow txt;
private final Level sas;
/*
private final CacheTask t = new CacheTask();
private class CacheTask extends TimerTask {
private final Object lock = new Object();
private StringBuilder cachedString = new StringBuilder();
@Override
public void run() {
synchronized(lock) {
SwingUtilities.invokeLater(() -> {
String t = txt.getText() + cachedString.toString().replace("\t", " ");
txt.setText(t);
txt.setCaretPosition(t.length());
cachedString = new StringBuilder();
});
}
}
void cache(String s) {
synchronized(lock) {
cachedString.append(s);
}
}
}*/
* private final CacheTask t = new CacheTask();
* private class CacheTask extends TimerTask {
* private final Object lock = new Object();
* private StringBuilder cachedString = new StringBuilder();
*
* @Override
* public void run() {
* synchronized(lock) {
* SwingUtilities.invokeLater(() -> {
* String t = txt.getText() + cachedString.toString().replace("\t", " ");
* txt.setText(t);
* txt.setCaretPosition(t.length());
* cachedString = new StringBuilder();
* });
* }
* }
*
* void cache(String s) {
* synchronized(lock) {
* cachedString.append(s);
* }
* }
* }
*/
public LogWindowOutputStream(LogWindow logWindow, Level l) {
txt = logWindow;
this.sas = l;
@@ -85,7 +86,7 @@ public class LogWindowOutputStream extends OutputStream {
@Override
public final void write(int paramInt) {
append(new String(new byte[] {(byte) paramInt}));
append(new String(new byte[] { (byte) paramInt }));
}
public static void dispose() {

View File

@@ -58,7 +58,7 @@ public class SwingUtils {
*/
public static DefaultTableModel makeDefaultTableModel(String[] titleA, final Class[] typesA, final boolean[] canEditA) {
return new DefaultTableModel(
new Object[][]{},
new Object[][] {},
titleA) {
Class[] types = typesA;
boolean[] canEdit = canEditA;
@@ -81,7 +81,7 @@ public class SwingUtils {
switch (OS.os()) {
case OSX:
try {
Runtime.getRuntime().exec(new String[]{"/usr/bin/open", path});
Runtime.getRuntime().exec(new String[] { "/usr/bin/open", path });
} catch (IOException ex) {
HMCLog.err("Failed to open " + path + " through /usr/bin/open", ex);
}
@@ -108,7 +108,7 @@ public class SwingUtils {
} catch (Throwable e) {
if (OS.os() == OS.OSX)
try {
Runtime.getRuntime().exec(new String[]{"/usr/bin/open", link});
Runtime.getRuntime().exec(new String[] { "/usr/bin/open", link });
} catch (IOException ex) {
HMCLog.warn("Failed to open link: " + link, ex);
}

View File

@@ -21,14 +21,17 @@ abstract class BCJCoder implements FilterCoder {
return filterID >= 0x04 && filterID <= 0x09;
}
@Override
public boolean changesSize() {
return false;
}
@Override
public boolean nonLastOK() {
return true;
}
@Override
public boolean lastOK() {
return false;
}

View File

@@ -21,23 +21,28 @@ class BCJDecoder extends BCJCoder implements FilterDecoder {
assert isBCJFilterID(filterID);
this.filterID = filterID;
if (props.length == 0)
switch (props.length) {
case 0:
startOffset = 0;
else if (props.length == 4) {
break;
case 4:
int n = 0;
for (int i = 0; i < 4; ++i)
n |= (props[i] & 0xFF) << (i * 8);
startOffset = n;
} else
break;
default:
throw new UnsupportedOptionsException(
"Unsupported BCJ filter properties");
}
}
@Override
public int getMemoryUsage() {
return SimpleInputStream.getMemoryUsage();
}
@Override
public InputStream getInputStream(InputStream in) {
SimpleFilter simpleFilter = null;

View File

@@ -18,9 +18,9 @@ abstract class BCJOptions extends FilterOptions {
}
/**
* Sets the start offset for the address conversions.
* Normally this is useless so you shouldn't use this function.
* The default value is <code>0</code>.
* Sets the start offset for the address conversions. Normally this is
* useless so you shouldn't use this function. The default value is
* <code>0</code>.
*/
public void setStartOffset(int startOffset)
throws UnsupportedOptionsException {

View File

@@ -9,25 +9,25 @@
package org.tukaani.xz;
/**
* Thrown when the compressed input data is corrupt.
* However, it is possible that some or all of the data
* already read from the input stream was corrupt too.
* Thrown when the compressed input data is corrupt. However, it is possible
* that some or all of the data already read from the input stream was corrupt
* too.
*/
public class CorruptedInputException extends XZIOException {
private static final long serialVersionUID = 3L;
/**
* Creates a new CorruptedInputException with
* the default error detail message.
* Creates a new CorruptedInputException with the default error detail
* message.
*/
public CorruptedInputException() {
super("Compressed data is corrupt");
}
/**
* Creates a new CorruptedInputException with
* the specified error detail message.
* Creates a new CorruptedInputException with the specified error detail
* message.
*
* @param s error detail message
*/

View File

@@ -22,10 +22,12 @@ class DeltaDecoder extends DeltaCoder implements FilterDecoder {
distance = (props[0] & 0xFF) + 1;
}
@Override
public int getMemoryUsage() {
return 1;
}
@Override
public InputStream getInputStream(InputStream in) {
return new DeltaInputStream(in, distance);
}

View File

@@ -15,9 +15,9 @@ import org.tukaani.xz.delta.DeltaDecoder;
/**
* Decodes raw Delta-filtered data (no XZ headers).
* <p>
* The delta filter doesn't change the size of the data and thus it
* cannot have an end-of-payload marker. It will simply decode until
* its input stream indicates end of input.
* The delta filter doesn't change the size of the data and thus it cannot have
* an end-of-payload marker. It will simply decode until its input stream
* indicates end of input.
*/
public class DeltaInputStream extends InputStream {
@@ -41,12 +41,10 @@ public class DeltaInputStream extends InputStream {
/**
* Creates a new Delta decoder with the given delta calculation distance.
*
* @param in input stream from which Delta filtered data
* is read
* @param in input stream from which Delta filtered data is read
*
* @param distance delta calculation distance, must be in the
* range [<code>DISTANCE_MIN</code>,
* <code>DISTANCE_MAX</code>]
* @param distance delta calculation distance, must be in the range
* [<code>DISTANCE_MIN</code>, <code>DISTANCE_MAX</code>]
*/
public DeltaInputStream(InputStream in, int distance) {
// Check for null because otherwise null isn't detect
@@ -61,11 +59,12 @@ public class DeltaInputStream extends InputStream {
/**
* Decode the next byte from this input stream.
*
* @return the next decoded byte, or <code>-1</code> to indicate
* the end of input on the input stream <code>in</code>
* @return the next decoded byte, or <code>-1</code> to indicate the end of
* input on the input stream <code>in</code>
*
* @throws IOException may be thrown by <code>in</code>
*/
@Override
public int read() throws IOException {
return read(tempBuf, 0, 1) == -1 ? -1 : (tempBuf[0] & 0xFF);
}
@@ -73,21 +72,22 @@ public class DeltaInputStream extends InputStream {
/**
* Decode into an array of bytes.
* <p>
* This calls <code>in.read(buf, off, len)</code> and defilters the
* returned data.
* This calls <code>in.read(buf, off, len)</code> and defilters the returned
* data.
*
* @param buf target buffer for decoded data
* @param off start offset in <code>buf</code>
* @param len maximum number of bytes to read
*
* @return number of bytes read, or <code>-1</code> to indicate
* the end of the input stream <code>in</code>
* @return number of bytes read, or <code>-1</code> to indicate the end of
* the input stream <code>in</code>
*
* @throws XZIOException if the stream has been closed
*
* @throws IOException may be thrown by underlaying input
* stream <code>in</code>
* @throws IOException may be thrown by underlaying input stream
* <code>in</code>
*/
@Override
public int read(byte[] buf, int off, int len) throws IOException {
if (len == 0)
return 0;
@@ -118,6 +118,7 @@ public class DeltaInputStream extends InputStream {
*
* @return the value returned by <code>in.available()</code>
*/
@Override
public int available() throws IOException {
if (in == null)
throw new XZIOException("Stream closed");
@@ -129,11 +130,12 @@ public class DeltaInputStream extends InputStream {
}
/**
* Closes the stream and calls <code>in.close()</code>.
* If the stream was already closed, this does nothing.
* Closes the stream and calls <code>in.close()</code>. If the stream was
* already closed, this does nothing.
*
* @throws IOException if thrown by <code>in.close()</code>
*/
@Override
public void close() throws IOException {
if (in != null)
try {

View File

@@ -11,19 +11,19 @@ package org.tukaani.xz;
import java.io.InputStream;
/**
* Delta filter options. The Delta filter can be used only as a non-last
* filter in the chain, for example Delta + LZMA2.
* Delta filter options. The Delta filter can be used only as a non-last filter
* in the chain, for example Delta + LZMA2.
* <p>
* Currently only simple byte-wise delta is supported. The only option
* is the delta distance, which you should set to match your data.
* It's not possible to provide a generic default value for it.
* Currently only simple byte-wise delta is supported. The only option is the
* delta distance, which you should set to match your data. It's not possible to
* provide a generic default value for it.
* <p>
* For example, with distance = 2 and eight-byte input
* A1 B1 A2 B3 A3 B5 A4 B7, the output will be A1 B1 01 02 01 02 01 02.
* For example, with distance = 2 and eight-byte input A1 B1 A2 B3 A3 B5 A4 B7,
* the output will be A1 B1 01 02 01 02 01 02.
* <p>
* The Delta filter can be good with uncompressed bitmap images. It can
* also help with PCM audio, although special-purpose compressors like
* FLAC will give much smaller result at much better compression speed.
* The Delta filter can be good with uncompressed bitmap images. It can also
* help with PCM audio, although special-purpose compressors like FLAC will give
* much smaller result at much better compression speed.
*/
public class DeltaOptions extends FilterOptions {
@@ -53,8 +53,8 @@ public class DeltaOptions extends FilterOptions {
}
/**
* Sets the delta distance in bytes. The new distance must be in
* the range [DISTANCE_MIN, DISTANCE_MAX].
* Sets the delta distance in bytes. The new distance must be in the range
* [DISTANCE_MIN, DISTANCE_MAX].
*/
public void setDistance(int distance) throws UnsupportedOptionsException {
if (distance < DISTANCE_MIN || distance > DISTANCE_MAX)
@@ -72,26 +72,32 @@ public class DeltaOptions extends FilterOptions {
return distance;
}
@Override
public int getEncoderMemoryUsage() {
return DeltaOutputStream.getMemoryUsage();
}
@Override
public FinishableOutputStream getOutputStream(FinishableOutputStream out) {
return new DeltaOutputStream(out, this);
}
@Override
public int getDecoderMemoryUsage() {
return 1;
}
@Override
public InputStream getInputStream(InputStream in) {
return new DeltaInputStream(in, distance);
}
@Override
FilterEncoder getFilterEncoder() {
return new DeltaEncoder(this);
}
@Override
public Object clone() {
try {
return super.clone();

View File

@@ -18,10 +18,9 @@ import java.io.IOException;
public abstract class FilterOptions implements Cloneable {
/**
* Gets how much memory the encoder will need with
* the given filter chain. This function simply calls
* <code>getEncoderMemoryUsage()</code> for every filter
* in the array and returns the sum of the returned values.
* Gets how much memory the encoder will need with the given filter chain.
* This function simply calls <code>getEncoderMemoryUsage()</code> for every
* filter in the array and returns the sum of the returned values.
*/
public static int getEncoderMemoryUsage(FilterOptions[] options) {
int m = 0;
@@ -33,10 +32,9 @@ public abstract class FilterOptions implements Cloneable {
}
/**
* Gets how much memory the decoder will need with
* the given filter chain. This function simply calls
* <code>getDecoderMemoryUsage()</code> for every filter
* in the array and returns the sum of the returned values.
* Gets how much memory the decoder will need with the given filter chain.
* This function simply calls <code>getDecoderMemoryUsage()</code> for every
* filter in the array and returns the sum of the returned values.
*/
public static int getDecoderMemoryUsage(FilterOptions[] options) {
int m = 0;
@@ -53,18 +51,18 @@ public abstract class FilterOptions implements Cloneable {
public abstract int getEncoderMemoryUsage();
/**
* Gets a raw (no XZ headers) encoder output stream using these options.
* Raw streams are an advanced feature. In most cases you want to store
* the compressed data in the .xz container format instead of using
* a raw stream. To use this filter in a .xz file, pass this object
* to XZOutputStream.
* Gets a raw (no XZ headers) encoder output stream using these options. Raw
* streams are an advanced feature. In most cases you want to store the
* compressed data in the .xz container format instead of using a raw
* stream. To use this filter in a .xz file, pass this object to
* XZOutputStream.
*/
public abstract FinishableOutputStream getOutputStream(
FinishableOutputStream out);
/**
* Gets how much memory the decoder will need to decompress the data
* that was encoded with these options.
* Gets how much memory the decoder will need to decompress the data that
* was encoded with these options.
*/
public abstract int getDecoderMemoryUsage();

View File

@@ -35,6 +35,7 @@ public class FinishableWrapperOutputStream extends FinishableOutputStream {
/**
* Calls {@link java.io.OutputStream#write(int) out.write(b)}.
*/
@Override
public void write(int b) throws IOException {
out.write(b);
}
@@ -42,6 +43,7 @@ public class FinishableWrapperOutputStream extends FinishableOutputStream {
/**
* Calls {@link java.io.OutputStream#write(byte[]) out.write(buf)}.
*/
@Override
public void write(byte[] buf) throws IOException {
out.write(buf);
}
@@ -50,6 +52,7 @@ public class FinishableWrapperOutputStream extends FinishableOutputStream {
* Calls {@link java.io.OutputStream#write(byte[],int,int)
* out.write(buf, off, len)}.
*/
@Override
public void write(byte[] buf, int off, int len) throws IOException {
out.write(buf, off, len);
}
@@ -57,6 +60,7 @@ public class FinishableWrapperOutputStream extends FinishableOutputStream {
/**
* Calls {@link java.io.OutputStream#flush() out.flush()}.
*/
@Override
public void flush() throws IOException {
out.flush();
}
@@ -64,6 +68,7 @@ public class FinishableWrapperOutputStream extends FinishableOutputStream {
/**
* Calls {@link java.io.OutputStream#close() out.close()}.
*/
@Override
public void close() throws IOException {
out.close();
}

View File

@@ -25,10 +25,12 @@ class LZMA2Decoder extends LZMA2Coder implements FilterDecoder {
dictSize <<= (props[0] >>> 1) + 11;
}
@Override
public int getMemoryUsage() {
return LZMA2InputStream.getMemoryUsage(dictSize);
}
@Override
public InputStream getInputStream(InputStream in) {
return new LZMA2InputStream(in, dictSize);
}

View File

@@ -32,18 +32,22 @@ class LZMA2Encoder extends LZMA2Coder implements FilterEncoder {
this.options = (LZMA2Options) options.clone();
}
@Override
public long getFilterID() {
return FILTER_ID;
}
@Override
public byte[] getFilterProps() {
return props;
}
@Override
public boolean supportsFlushing() {
return true;
}
@Override
public FinishableOutputStream getOutputStream(FinishableOutputStream out) {
return options.getOutputStream(out);
}

View File

@@ -24,8 +24,8 @@ public class LZMA2InputStream extends InputStream {
/**
* Smallest valid LZMA2 dictionary size.
* <p>
* Very tiny dictionaries would be a performance problem, so
* the minimum is 4 KiB.
* Very tiny dictionaries would be a performance problem, so the minimum is
* 4 KiB.
*/
public static final int DICT_SIZE_MIN = 4096;
@@ -33,11 +33,11 @@ public class LZMA2InputStream extends InputStream {
* Largest dictionary size supported by this implementation.
* <p>
* The LZMA2 algorithm allows dictionaries up to one byte less than 4 GiB.
* This implementation supports only 16 bytes less than 2 GiB for raw
* LZMA2 streams, and for .xz files the maximum is 1.5 GiB. This
* limitation is due to Java using signed 32-bit integers for array
* indexing. The limitation shouldn't matter much in practice since so
* huge dictionaries are not normally used.
* This implementation supports only 16 bytes less than 2 GiB for raw LZMA2
* streams, and for .xz files the maximum is 1.5 GiB. This limitation is due
* to Java using signed 32-bit integers for array indexing. The limitation
* shouldn't matter much in practice since so huge dictionaries are not
* normally used.
*/
public static final int DICT_SIZE_MAX = Integer.MAX_VALUE & ~15;
@@ -62,12 +62,11 @@ public class LZMA2InputStream extends InputStream {
private final byte[] tempBuf = new byte[1];
/**
* Gets approximate decompressor memory requirements as kibibytes for
* the given dictionary size.
* Gets approximate decompressor memory requirements as kibibytes for the
* given dictionary size.
*
* @param dictSize LZMA2 dictionary size as bytes, must be
* in the range [<code>DICT_SIZE_MIN</code>,
* <code>DICT_SIZE_MAX</code>]
* @param dictSize LZMA2 dictionary size as bytes, must be in the range
* [<code>DICT_SIZE_MIN</code>, <code>DICT_SIZE_MAX</code>]
*
* @return approximate memory requirements as kibibytes (KiB)
*/
@@ -91,27 +90,25 @@ public class LZMA2InputStream extends InputStream {
}
/**
* Creates a new input stream that decompresses raw LZMA2 data
* from <code>in</code>.
* Creates a new input stream that decompresses raw LZMA2 data from
* <code>in</code>.
* <p>
* The caller needs to know the dictionary size used when compressing;
* the dictionary size isn't stored as part of a raw LZMA2 stream.
* The caller needs to know the dictionary size used when compressing; the
* dictionary size isn't stored as part of a raw LZMA2 stream.
* <p>
* Specifying a too small dictionary size will prevent decompressing
* the stream. Specifying a too big dictionary is waste of memory but
* Specifying a too small dictionary size will prevent decompressing the
* stream. Specifying a too big dictionary is waste of memory but
* decompression will work.
* <p>
* There is no need to specify a dictionary bigger than
* the uncompressed size of the data even if a bigger dictionary
* was used when compressing. If you know the uncompressed size
* of the data, this might allow saving some memory.
* There is no need to specify a dictionary bigger than the uncompressed
* size of the data even if a bigger dictionary was used when compressing.
* If you know the uncompressed size of the data, this might allow saving
* some memory.
*
* @param in input stream from which LZMA2-compressed
* data is read
* @param in input stream from which LZMA2-compressed data is read
*
* @param dictSize LZMA2 dictionary size as bytes, must be
* in the range [<code>DICT_SIZE_MIN</code>,
* <code>DICT_SIZE_MAX</code>]
* @param dictSize LZMA2 dictionary size as bytes, must be in the range
* [<code>DICT_SIZE_MIN</code>, <code>DICT_SIZE_MAX</code>]
*/
public LZMA2InputStream(InputStream in, int dictSize) {
this(in, dictSize, null);
@@ -120,20 +117,18 @@ public class LZMA2InputStream extends InputStream {
/**
* Creates a new LZMA2 decompressor using a preset dictionary.
* <p>
* This is like <code>LZMA2InputStream(InputStream, int)</code> except
* that the dictionary may be initialized using a preset dictionary.
* If a preset dictionary was used when compressing the data, the
* same preset dictionary must be provided when decompressing.
* This is like <code>LZMA2InputStream(InputStream, int)</code> except that
* the dictionary may be initialized using a preset dictionary. If a preset
* dictionary was used when compressing the data, the same preset dictionary
* must be provided when decompressing.
*
* @param in input stream from which LZMA2-compressed
* data is read
* @param in input stream from which LZMA2-compressed data is read
*
* @param dictSize LZMA2 dictionary size as bytes, must be
* in the range [<code>DICT_SIZE_MIN</code>,
* <code>DICT_SIZE_MAX</code>]
* @param dictSize LZMA2 dictionary size as bytes, must be in the range
* [<code>DICT_SIZE_MIN</code>, <code>DICT_SIZE_MAX</code>]
*
* @param presetDict preset dictionary or <code>null</code>
* to use no preset dictionary
* @param presetDict preset dictionary or <code>null</code> to use no preset
* dictionary
*/
public LZMA2InputStream(InputStream in, int dictSize, byte[] presetDict) {
// Check for null because otherwise null isn't detect
@@ -151,19 +146,18 @@ public class LZMA2InputStream extends InputStream {
/**
* Decompresses the next byte from this input stream.
* <p>
* Reading lots of data with <code>read()</code> from this input stream
* may be inefficient. Wrap it in <code>java.io.BufferedInputStream</code>
* if you need to read lots of data one byte at a time.
* Reading lots of data with <code>read()</code> from this input stream may
* be inefficient. Wrap it in <code>java.io.BufferedInputStream</code> if
* you need to read lots of data one byte at a time.
*
* @return the next decompressed byte, or <code>-1</code>
* to indicate the end of the compressed stream
* @return the next decompressed byte, or <code>-1</code> to indicate the
* end of the compressed stream
*
* @throws CorruptedInputException
*
* @throws XZIOException if the stream has been closed
*
* @throws EOFException
* compressed input is truncated or corrupt
* @throws EOFException compressed input is truncated or corrupt
*
* @throws IOException may be thrown by <code>in</code>
*/
@@ -174,24 +168,23 @@ public class LZMA2InputStream extends InputStream {
/**
* Decompresses into an array of bytes.
* <p>
* If <code>len</code> is zero, no bytes are read and <code>0</code>
* is returned. Otherwise this will block until <code>len</code>
* bytes have been decompressed, the end of the LZMA2 stream is reached,
* or an exception is thrown.
* If <code>len</code> is zero, no bytes are read and <code>0</code> is
* returned. Otherwise this will block until <code>len</code> bytes have
* been decompressed, the end of the LZMA2 stream is reached, or an
* exception is thrown.
*
* @param buf target buffer for uncompressed data
* @param off start offset in <code>buf</code>
* @param len maximum number of uncompressed bytes to read
*
* @return number of bytes read, or <code>-1</code> to indicate
* the end of the compressed stream
* @return number of bytes read, or <code>-1</code> to indicate the end of
* the compressed stream
*
* @throws CorruptedInputException
*
* @throws XZIOException if the stream has been closed
*
* @throws EOFException
* compressed input is truncated or corrupt
* @throws EOFException compressed input is truncated or corrupt
*
* @throws IOException may be thrown by <code>in</code>
*/
@@ -311,20 +304,18 @@ public class LZMA2InputStream extends InputStream {
}
/**
* Returns the number of uncompressed bytes that can be read
* without blocking. The value is returned with an assumption
* that the compressed input data will be valid. If the compressed
* data is corrupt, <code>CorruptedInputException</code> may get
* thrown before the number of bytes claimed to be available have
* been read from this input stream.
* Returns the number of uncompressed bytes that can be read without
* blocking. The value is returned with an assumption that the compressed
* input data will be valid. If the compressed data is corrupt,
* <code>CorruptedInputException</code> may get thrown before the number of
* bytes claimed to be available have been read from this input stream.
* <p>
* In LZMA2InputStream, the return value will be non-zero when the
* decompressor is in the middle of an LZMA2 chunk. The return value
* will then be the number of uncompressed bytes remaining from that
* chunk.
* decompressor is in the middle of an LZMA2 chunk. The return value will
* then be the number of uncompressed bytes remaining from that chunk.
*
* @return the number of uncompressed bytes that can be read
* without blocking
* @return the number of uncompressed bytes that can be read without
* blocking
*/
public int available() throws IOException {
if (in == null)
@@ -337,8 +328,8 @@ public class LZMA2InputStream extends InputStream {
}
/**
* Closes the stream and calls <code>in.close()</code>.
* If the stream was already closed, this does nothing.
* Closes the stream and calls <code>in.close()</code>. If the stream was
* already closed, this does nothing.
*
* @throws IOException if thrown by <code>in.close()</code>
*/

View File

@@ -16,9 +16,8 @@ import org.tukaani.xz.lzma.LZMAEncoder;
/**
* LZMA2 compression options.
* <p>
* While this allows setting the LZMA2 compression options in detail,
* often you only need <code>LZMA2Options()</code> or
* <code>LZMA2Options(int)</code>.
* While this allows setting the LZMA2 compression options in detail, often you
* only need <code>LZMA2Options()</code> or <code>LZMA2Options(int)</code>.
*/
public class LZMA2Options extends FilterOptions {
@@ -45,13 +44,13 @@ public class LZMA2Options extends FilterOptions {
/**
* Maximum dictionary size for compression is 768 MiB.
* <p>
* The decompressor supports bigger dictionaries, up to almost 2 GiB.
* With HC4 the encoder would support dictionaries bigger than 768 MiB.
* The 768 MiB limit comes from the current implementation of BT4 where
* we would otherwise hit the limits of signed ints in array indexing.
* The decompressor supports bigger dictionaries, up to almost 2 GiB. With
* HC4 the encoder would support dictionaries bigger than 768 MiB. The 768
* MiB limit comes from the current implementation of BT4 where we would
* otherwise hit the limits of signed ints in array indexing.
* <p>
* If you really need bigger dictionary for decompression,
* use {@link LZMA2InputStream} directly.
* If you really need bigger dictionary for decompression, use
* {@link LZMA2InputStream} directly.
*/
public static final int DICT_SIZE_MAX = 768 << 20;
@@ -86,20 +85,20 @@ public class LZMA2Options extends FilterOptions {
public static final int PB_DEFAULT = 2;
/**
* Compression mode: uncompressed.
* The data is wrapped into a LZMA2 stream without compression.
* Compression mode: uncompressed. The data is wrapped into a LZMA2 stream
* without compression.
*/
public static final int MODE_UNCOMPRESSED = 0;
/**
* Compression mode: fast.
* This is usually combined with a hash chain match finder.
* Compression mode: fast. This is usually combined with a hash chain match
* finder.
*/
public static final int MODE_FAST = LZMAEncoder.MODE_FAST;
/**
* Compression mode: normal.
* This is usually combined with a binary tree match finder.
* Compression mode: normal. This is usually combined with a binary tree
* match finder.
*/
public static final int MODE_NORMAL = LZMAEncoder.MODE_NORMAL;
@@ -125,9 +124,9 @@ public class LZMA2Options extends FilterOptions {
private static final int[] presetToDictSize = {
1 << 18, 1 << 20, 1 << 21, 1 << 22, 1 << 22,
1 << 23, 1 << 23, 1 << 24, 1 << 25, 1 << 26};
1 << 23, 1 << 23, 1 << 24, 1 << 25, 1 << 26 };
private static final int[] presetToDepthLimit = {4, 8, 24, 48};
private static final int[] presetToDepthLimit = { 4, 8, 24, 48 };
private int dictSize;
private byte[] presetDict = null;
@@ -140,8 +139,8 @@ public class LZMA2Options extends FilterOptions {
private int depthLimit;
/**
* Creates new LZMA2 options and sets them to the default values.
* This is equivalent to <code>LZMA2Options(PRESET_DEFAULT)</code>.
* Creates new LZMA2 options and sets them to the default values. This is
* equivalent to <code>LZMA2Options(PRESET_DEFAULT)</code>.
*/
public LZMA2Options() {
try {
@@ -155,8 +154,7 @@ public class LZMA2Options extends FilterOptions {
/**
* Creates new LZMA2 options and sets them to the given preset.
*
* @throws UnsupportedOptionsException
* <code>preset</code> is not supported
* @throws UnsupportedOptionsException <code>preset</code> is not supported
*/
public LZMA2Options(int preset) throws UnsupportedOptionsException {
setPreset(preset);
@@ -165,8 +163,7 @@ public class LZMA2Options extends FilterOptions {
/**
* Creates new LZMA2 options and sets them to the given custom values.
*
* @throws UnsupportedOptionsException
* unsupported options were specified
* @throws UnsupportedOptionsException unsupported options were specified
*/
public LZMA2Options(int dictSize, int lc, int lp, int pb, int mode,
int niceLen, int mf, int depthLimit)
@@ -183,18 +180,17 @@ public class LZMA2Options extends FilterOptions {
/**
* Sets the compression options to the given preset.
* <p>
* The presets 0-3 are fast presets with medium compression.
* The presets 4-6 are fairly slow presets with high compression.
* The default preset (<code>PRESET_DEFAULT</code>) is 6.
* The presets 0-3 are fast presets with medium compression. The presets 4-6
* are fairly slow presets with high compression. The default preset
* (<code>PRESET_DEFAULT</code>) is 6.
* <p>
* The presets 7-9 are like the preset 6 but use bigger dictionaries
* and have higher compressor and decompressor memory requirements.
* Unless the uncompressed size of the file exceeds 8&nbsp;MiB,
* 16&nbsp;MiB, or 32&nbsp;MiB, it is waste of memory to use the
* presets 7, 8, or 9, respectively.
* The presets 7-9 are like the preset 6 but use bigger dictionaries and
* have higher compressor and decompressor memory requirements. Unless the
* uncompressed size of the file exceeds 8&nbsp;MiB, 16&nbsp;MiB, or
* 32&nbsp;MiB, it is waste of memory to use the presets 7, 8, or 9,
* respectively.
*
* @throws UnsupportedOptionsException
* <code>preset</code> is not supported
* @throws UnsupportedOptionsException <code>preset</code> is not supported
*/
public void setPreset(int preset) throws UnsupportedOptionsException {
if (preset < 0 || preset > 9)
@@ -227,12 +223,11 @@ public class LZMA2Options extends FilterOptions {
* However, using a dictioanary bigger than the size of the uncompressed
* data is waste of memory.
* <p>
* Any value in the range [DICT_SIZE_MIN, DICT_SIZE_MAX] is valid,
* but sizes of 2^n and 2^n&nbsp;+&nbsp;2^(n-1) bytes are somewhat
* recommended.
* Any value in the range [DICT_SIZE_MIN, DICT_SIZE_MAX] is valid, but sizes
* of 2^n and 2^n&nbsp;+&nbsp;2^(n-1) bytes are somewhat recommended.
*
* @throws UnsupportedOptionsException
* <code>dictSize</code> is not supported
* @throws UnsupportedOptionsException <code>dictSize</code> is not
* supported
*/
public void setDictSize(int dictSize) throws UnsupportedOptionsException {
if (dictSize < DICT_SIZE_MIN)
@@ -256,18 +251,18 @@ public class LZMA2Options extends FilterOptions {
}
/**
* Sets a preset dictionary. Use null to disable the use of
* a preset dictionary. By default there is no preset dictionary.
* Sets a preset dictionary. Use null to disable the use of a preset
* dictionary. By default there is no preset dictionary.
* <p>
* <b>The .xz format doesn't support a preset dictionary for now.
* Do not set a preset dictionary unless you use raw LZMA2.</b>
* <b>The .xz format doesn't support a preset dictionary for now. Do not set
* a preset dictionary unless you use raw LZMA2.</b>
* <p>
* Preset dictionary can be useful when compressing many similar,
* relatively small chunks of data independently from each other.
* A preset dictionary should contain typical strings that occur in
* the files being compressed. The most probable strings should be
* near the end of the preset dictionary. The preset dictionary used
* for compression is also needed for decompression.
* Preset dictionary can be useful when compressing many similar, relatively
* small chunks of data independently from each other. A preset dictionary
* should contain typical strings that occur in the files being compressed.
* The most probable strings should be near the end of the preset
* dictionary. The preset dictionary used for compression is also needed for
* decompression.
*/
public void setPresetDict(byte[] presetDict) {
this.presetDict = presetDict;
@@ -283,12 +278,11 @@ public class LZMA2Options extends FilterOptions {
/**
* Sets the number of literal context bits and literal position bits.
* <p>
* The sum of <code>lc</code> and <code>lp</code> is limited to 4.
* Trying to exceed it will throw an exception. This function lets
* you change both at the same time.
* The sum of <code>lc</code> and <code>lp</code> is limited to 4. Trying to
* exceed it will throw an exception. This function lets you change both at
* the same time.
*
* @throws UnsupportedOptionsException
* <code>lc</code> and <code>lp</code>
* @throws UnsupportedOptionsException <code>lc</code> and <code>lp</code>
* are invalid
*/
public void setLcLp(int lc, int lp) throws UnsupportedOptionsException {
@@ -305,28 +299,25 @@ public class LZMA2Options extends FilterOptions {
/**
* Sets the number of literal context bits.
* <p>
* All bytes that cannot be encoded as matches are encoded as literals.
* That is, literals are simply 8-bit bytes that are encoded one at
* a time.
* All bytes that cannot be encoded as matches are encoded as literals. That
* is, literals are simply 8-bit bytes that are encoded one at a time.
* <p>
* The literal coding makes an assumption that the highest <code>lc</code>
* bits of the previous uncompressed byte correlate with the next byte.
* For example, in typical English text, an upper-case letter is often
* followed by a lower-case letter, and a lower-case letter is usually
* followed by another lower-case letter. In the US-ASCII character set,
* the highest three bits are 010 for upper-case letters and 011 for
* lower-case letters. When <code>lc</code> is at least 3, the literal
* coding can take advantage of this property in the uncompressed data.
* bits of the previous uncompressed byte correlate with the next byte. For
* example, in typical English text, an upper-case letter is often followed
* by a lower-case letter, and a lower-case letter is usually followed by
* another lower-case letter. In the US-ASCII character set, the highest
* three bits are 010 for upper-case letters and 011 for lower-case letters.
* When <code>lc</code> is at least 3, the literal coding can take advantage
* of this property in the uncompressed data.
* <p>
* The default value (3) is usually good. If you want maximum compression,
* try <code>setLc(4)</code>. Sometimes it helps a little, and sometimes it
* makes compression worse. If it makes it worse, test for example
* <code>setLc(2)</code> too.
*
* @throws UnsupportedOptionsException
* <code>lc</code> is invalid, or the sum
* of <code>lc</code> and <code>lp</code>
* exceed LC_LP_MAX
* @throws UnsupportedOptionsException <code>lc</code> is invalid, or the
* sum of <code>lc</code> and <code>lp</code> exceed LC_LP_MAX
*/
public void setLc(int lc) throws UnsupportedOptionsException {
setLcLp(lc, lp);
@@ -335,14 +326,12 @@ public class LZMA2Options extends FilterOptions {
/**
* Sets the number of literal position bits.
* <p>
* This affets what kind of alignment in the uncompressed data is
* assumed when encoding literals. See {@link #setPb(int) setPb} for
* more information about alignment.
* This affets what kind of alignment in the uncompressed data is assumed
* when encoding literals. See {@link #setPb(int) setPb} for more
* information about alignment.
*
* @throws UnsupportedOptionsException
* <code>lp</code> is invalid, or the sum
* of <code>lc</code> and <code>lp</code>
* exceed LC_LP_MAX
* @throws UnsupportedOptionsException <code>lp</code> is invalid, or the
* sum of <code>lc</code> and <code>lp</code> exceed LC_LP_MAX
*/
public void setLp(int lp) throws UnsupportedOptionsException {
setLcLp(lc, lp);
@@ -365,26 +354,23 @@ public class LZMA2Options extends FilterOptions {
/**
* Sets the number of position bits.
* <p>
* This affects what kind of alignment in the uncompressed data is
* assumed in general. The default (2) means four-byte alignment
* (2^<code>pb</code> = 2^2 = 4), which is often a good choice when
* there's no better guess.
* This affects what kind of alignment in the uncompressed data is assumed
* in general. The default (2) means four-byte alignment (2^<code>pb</code>
* = 2^2 = 4), which is often a good choice when there's no better guess.
* <p>
* When the alignment is known, setting the number of position bits
* accordingly may reduce the file size a little. For example with text
* files having one-byte alignment (US-ASCII, ISO-8859-*, UTF-8), using
* <code>setPb(0)</code> can improve compression slightly. For UTF-16
* text, <code>setPb(1)</code> is a good choice. If the alignment is
* an odd number like 3 bytes, <code>setPb(0)</code> might be the best
* choice.
* <code>setPb(0)</code> can improve compression slightly. For UTF-16 text,
* <code>setPb(1)</code> is a good choice. If the alignment is an odd number
* like 3 bytes, <code>setPb(0)</code> might be the best choice.
* <p>
* Even though the assumed alignment can be adjusted with
* <code>setPb</code> and <code>setLp</code>, LZMA2 still slightly favors
* 16-byte alignment. It might be worth taking into account when designing
* file formats that are likely to be often compressed with LZMA2.
* Even though the assumed alignment can be adjusted with <code>setPb</code>
* and <code>setLp</code>, LZMA2 still slightly favors 16-byte alignment. It
* might be worth taking into account when designing file formats that are
* likely to be often compressed with LZMA2.
*
* @throws UnsupportedOptionsException
* <code>pb</code> is invalid
* @throws UnsupportedOptionsException <code>pb</code> is invalid
*/
public void setPb(int pb) throws UnsupportedOptionsException {
if (pb < 0 || pb > PB_MAX)
@@ -404,20 +390,19 @@ public class LZMA2Options extends FilterOptions {
/**
* Sets the compression mode.
* <p>
* This specifies the method to analyze the data produced by
* a match finder. The default is <code>MODE_FAST</code> for presets
* 0-3 and <code>MODE_NORMAL</code> for presets 4-9.
* This specifies the method to analyze the data produced by a match finder.
* The default is <code>MODE_FAST</code> for presets 0-3 and
* <code>MODE_NORMAL</code> for presets 4-9.
* <p>
* Usually <code>MODE_FAST</code> is used with Hash Chain match finders
* and <code>MODE_NORMAL</code> with Binary Tree match finders. This is
* also what the presets do.
* Usually <code>MODE_FAST</code> is used with Hash Chain match finders and
* <code>MODE_NORMAL</code> with Binary Tree match finders. This is also
* what the presets do.
* <p>
* The special mode <code>MODE_UNCOMPRESSED</code> doesn't try to
* compress the data at all (and doesn't use a match finder) and will
* simply wrap it in uncompressed LZMA2 chunks.
* The special mode <code>MODE_UNCOMPRESSED</code> doesn't try to compress
* the data at all (and doesn't use a match finder) and will simply wrap it
* in uncompressed LZMA2 chunks.
*
* @throws UnsupportedOptionsException
* <code>mode</code> is not supported
* @throws UnsupportedOptionsException <code>mode</code> is not supported
*/
public void setMode(int mode) throws UnsupportedOptionsException {
if (mode < MODE_UNCOMPRESSED || mode > MODE_NORMAL)
@@ -435,14 +420,12 @@ public class LZMA2Options extends FilterOptions {
}
/**
* Sets the nice length of matches.
* Once a match of at least <code>niceLen</code> bytes is found,
* the algorithm stops looking for better matches. Higher values tend
* to give better compression at the expense of speed. The default
* depends on the preset.
* Sets the nice length of matches. Once a match of at least
* <code>niceLen</code> bytes is found, the algorithm stops looking for
* better matches. Higher values tend to give better compression at the
* expense of speed. The default depends on the preset.
*
* @throws UnsupportedOptionsException
* <code>niceLen</code> is invalid
* @throws UnsupportedOptionsException <code>niceLen</code> is invalid
*/
public void setNiceLen(int niceLen) throws UnsupportedOptionsException {
if (niceLen < NICE_LEN_MIN)
@@ -468,13 +451,12 @@ public class LZMA2Options extends FilterOptions {
/**
* Sets the match finder type.
* <p>
* Match finder has a major effect on compression speed, memory usage,
* and compression ratio. Usually Hash Chain match finders are faster
* than Binary Tree match finders. The default depends on the preset:
* 0-3 use <code>MF_HC4</code> and 4-9 use <code>MF_BT4</code>.
* Match finder has a major effect on compression speed, memory usage, and
* compression ratio. Usually Hash Chain match finders are faster than
* Binary Tree match finders. The default depends on the preset: 0-3 use
* <code>MF_HC4</code> and 4-9 use <code>MF_BT4</code>.
*
* @throws UnsupportedOptionsException
* <code>mf</code> is not supported
* @throws UnsupportedOptionsException <code>mf</code> is not supported
*/
public void setMatchFinder(int mf) throws UnsupportedOptionsException {
if (mf != MF_HC4 && mf != MF_BT4)
@@ -494,18 +476,17 @@ public class LZMA2Options extends FilterOptions {
/**
* Sets the match finder search depth limit.
* <p>
* The default is a special value of <code>0</code> which indicates that
* the depth limit should be automatically calculated by the selected
* match finder from the nice length of matches.
* The default is a special value of <code>0</code> which indicates that the
* depth limit should be automatically calculated by the selected match
* finder from the nice length of matches.
* <p>
* Reasonable depth limit for Hash Chain match finders is 4-100 and
* 16-1000 for Binary Tree match finders. Using very high values can
* make the compressor extremely slow with some files. Avoid settings
* higher than 1000 unless you are prepared to interrupt the compression
* in case it is taking far too long.
* Reasonable depth limit for Hash Chain match finders is 4-100 and 16-1000
* for Binary Tree match finders. Using very high values can make the
* compressor extremely slow with some files. Avoid settings higher than
* 1000 unless you are prepared to interrupt the compression in case it is
* taking far too long.
*
* @throws UnsupportedOptionsException
* <code>depthLimit</code> is invalid
* @throws UnsupportedOptionsException <code>depthLimit</code> is invalid
*/
public void setDepthLimit(int depthLimit)
throws UnsupportedOptionsException {
@@ -540,12 +521,12 @@ public class LZMA2Options extends FilterOptions {
* Gets how much memory the LZMA2 decoder will need to decompress the data
* that was encoded with these options and stored in a .xz file.
* <p>
* The returned value may bigger than the value returned by a direct call
* to {@link LZMA2InputStream#getMemoryUsage(int)} if the dictionary size
* is not 2^n or 2^n&nbsp;+&nbsp;2^(n-1) bytes. This is because the .xz
* headers store the dictionary size in such a format and other values
* are rounded up to the next such value. Such rounding is harmess except
* it might waste some memory if an unsual dictionary size is used.
* The returned value may bigger than the value returned by a direct call to
* {@link LZMA2InputStream#getMemoryUsage(int)} if the dictionary size is
* not 2^n or 2^n&nbsp;+&nbsp;2^(n-1) bytes. This is because the .xz headers
* store the dictionary size in such a format and other values are rounded
* up to the next such value. Such rounding is harmess except it might waste
* some memory if an unsual dictionary size is used.
* <p>
* If you use raw LZMA2 streams and unusual dictioanary size, call
* {@link LZMA2InputStream#getMemoryUsage} directly to get raw decoder

View File

@@ -20,16 +20,16 @@ import org.tukaani.xz.lzma.LZMADecoder;
* Decompresses legacy .lzma files and raw LZMA streams (no .lzma header).
* <p>
* <b>IMPORTANT:</b> In contrast to other classes in this package, this class
* reads data from its input stream one byte at a time. If the input stream
* is for example {@link java.io.FileInputStream}, wrapping it into
* {@link java.io.BufferedInputStream} tends to improve performance a lot.
* This is not automatically done by this class because there may be use
* cases where it is desired that this class won't read any bytes past
* the end of the LZMA stream.
* reads data from its input stream one byte at a time. If the input stream is
* for example {@link java.io.FileInputStream}, wrapping it into
* {@link java.io.BufferedInputStream} tends to improve performance a lot. This
* is not automatically done by this class because there may be use cases where
* it is desired that this class won't read any bytes past the end of the LZMA
* stream.
* <p>
* Even when using <code>BufferedInputStream</code>, the performance tends
* to be worse (maybe 10-20&nbsp;% slower) than with {@link LZMA2InputStream}
* or {@link XZInputStream} (when the .xz file contains LZMA2-compressed data).
* Even when using <code>BufferedInputStream</code>, the performance tends to be
* worse (maybe 10-20&nbsp;% slower) than with {@link LZMA2InputStream} or
* {@link XZInputStream} (when the .xz file contains LZMA2-compressed data).
*
* @since 1.4
*/
@@ -39,10 +39,10 @@ public class LZMAInputStream extends InputStream {
* Largest dictionary size supported by this implementation.
* <p>
* LZMA allows dictionaries up to one byte less than 4 GiB. This
* implementation supports only 16 bytes less than 2 GiB. This
* limitation is due to Java using signed 32-bit integers for array
* indexing. The limitation shouldn't matter much in practice since so
* huge dictionaries are not normally used.
* implementation supports only 16 bytes less than 2 GiB. This limitation is
* due to Java using signed 32-bit integers for array indexing. The
* limitation shouldn't matter much in practice since so huge dictionaries
* are not normally used.
*/
public static final int DICT_SIZE_MAX = Integer.MAX_VALUE & ~15;
@@ -56,33 +56,29 @@ public class LZMAInputStream extends InputStream {
private final byte[] tempBuf = new byte[1];
/**
* Number of uncompressed bytes left to be decompressed, or -1 if
* the end marker is used.
* Number of uncompressed bytes left to be decompressed, or -1 if the end
* marker is used.
*/
private long remainingSize;
private IOException exception = null;
/**
* Gets approximate decompressor memory requirements as kibibytes for
* the given dictionary size and LZMA properties byte (lc, lp, and pb).
* Gets approximate decompressor memory requirements as kibibytes for the
* given dictionary size and LZMA properties byte (lc, lp, and pb).
*
* @param dictSize LZMA dictionary size as bytes, should be
* in the range [<code>0</code>,
* <code>DICT_SIZE_MAX</code>]
* @param dictSize LZMA dictionary size as bytes, should be in the range
* [<code>0</code>, <code>DICT_SIZE_MAX</code>]
*
* @param propsByte LZMA properties byte that encodes the values
* of lc, lp, and pb
* @param propsByte LZMA properties byte that encodes the values of lc, lp,
* and pb
*
* @return approximate memory requirements as kibibytes (KiB)
*
* @throws UnsupportedOptionsException
* if <code>dictSize</code> is outside
* the range [<code>0</code>,
* <code>DICT_SIZE_MAX</code>]
* @throws UnsupportedOptionsException if <code>dictSize</code> is outside
* the range [<code>0</code>, <code>DICT_SIZE_MAX</code>]
*
* @throws CorruptedInputException
* if <code>propsByte</code> is invalid
* @throws CorruptedInputException if <code>propsByte</code> is invalid
*/
public static int getMemoryUsage(int dictSize, byte propsByte)
throws UnsupportedOptionsException, CorruptedInputException {
@@ -102,18 +98,17 @@ public class LZMAInputStream extends InputStream {
}
/**
* Gets approximate decompressor memory requirements as kibibytes for
* the given dictionary size, lc, and lp. Note that pb isn't needed.
* Gets approximate decompressor memory requirements as kibibytes for the
* given dictionary size, lc, and lp. Note that pb isn't needed.
*
* @param dictSize LZMA dictionary size as bytes, must be
* in the range [<code>0</code>,
* <code>DICT_SIZE_MAX</code>]
* @param dictSize LZMA dictionary size as bytes, must be in the range
* [<code>0</code>, <code>DICT_SIZE_MAX</code>]
*
* @param lc number of literal context bits, must be
* in the range [0, 8]
* @param lc number of literal context bits, must be in the range [0,
* 8]
*
* @param lp number of literal position bits, must be
* in the range [0, 4]
* @param lp number of literal position bits, must be in the range [0,
* 4]
*
* @return approximate memory requirements as kibibytes (KiB)
*/
@@ -156,25 +151,22 @@ public class LZMAInputStream extends InputStream {
}
/**
* Creates a new .lzma file format decompressor without
* a memory usage limit.
* Creates a new .lzma file format decompressor without a memory usage
* limit.
*
* @param in input stream from which .lzma data is read;
* it might be a good idea to wrap it in
* <code>BufferedInputStream</code>, see the
* note at the top of this page
* @param in input stream from which .lzma data is read; it might be a good
* idea to wrap it in <code>BufferedInputStream</code>, see the note at the
* top of this page
*
* @throws CorruptedInputException
* file is corrupt or perhaps not in
* the .lzma format at all
* @throws CorruptedInputException file is corrupt or perhaps not in the
* .lzma format at all
*
* @throws UnsupportedOptionsException
* dictionary size or uncompressed size is too
* big for this implementation
* @throws UnsupportedOptionsException dictionary size or uncompressed size
* is too big for this implementation
*
* @throws EOFException
* file is truncated or perhaps not in
* the .lzma format at all
* @throws EOFException file is truncated or perhaps not in
* the .lzma format
* at all
*
* @throws IOException may be thrown by <code>in</code>
*/
@@ -183,32 +175,28 @@ public class LZMAInputStream extends InputStream {
}
/**
* Creates a new .lzma file format decompressor with an optional
* memory usage limit.
* Creates a new .lzma file format decompressor with an optional memory
* usage limit.
*
* @param in input stream from which .lzma data is read;
* it might be a good idea to wrap it in
* <code>BufferedInputStream</code>, see the
* note at the top of this page
* @param in input stream from which .lzma data is read; it might
* be a good
* idea to wrap it in <code>BufferedInputStream</code>, see the note at the
* top of this page
*
* @param memoryLimit memory usage limit in kibibytes (KiB)
* or <code>-1</code> to impose no
* memory usage limit
* @param memoryLimit memory usage limit in kibibytes (KiB) or
* <code>-1</code> to impose no memory usage limit
*
* @throws CorruptedInputException
* file is corrupt or perhaps not in
* the .lzma format at all
* @throws CorruptedInputException file is corrupt or perhaps not in the
* .lzma format at all
*
* @throws UnsupportedOptionsException
* dictionary size or uncompressed size is too
* big for this implementation
* @throws UnsupportedOptionsException dictionary size or uncompressed size
* is too big for this implementation
*
* @throws MemoryLimitException
* memory usage limit was exceeded
* @throws MemoryLimitException memory usage limit was exceeded
*
* @throws EOFException
* file is truncated or perhaps not in
* the .lzma format at all
* @throws EOFException file is truncated or perhaps not in
* the .lzma format
* at all
*
* @throws IOException may be thrown by <code>in</code>
*/
@@ -244,45 +232,43 @@ public class LZMAInputStream extends InputStream {
* Creates a new input stream that decompresses raw LZMA data (no .lzma
* header) from <code>in</code>.
* <p>
* The caller needs to know if the "end of payload marker (EOPM)" alias
* "end of stream marker (EOS marker)" alias "end marker" present.
* If the end marker isn't used, the caller must know the exact
* uncompressed size of the stream.
* The caller needs to know if the "end of payload marker (EOPM)" alias "end
* of stream marker (EOS marker)" alias "end marker" present. If the end
* marker isn't used, the caller must know the exact uncompressed size of
* the stream.
* <p>
* The caller also needs to provide the LZMA properties byte that encodes
* the number of literal context bits (lc), literal position bits (lp),
* and position bits (pb).
* the number of literal context bits (lc), literal position bits (lp), and
* position bits (pb).
* <p>
* The dictionary size used when compressing is also needed. Specifying
* a too small dictionary size will prevent decompressing the stream.
* Specifying a too big dictionary is waste of memory but decompression
* will work.
* The dictionary size used when compressing is also needed. Specifying a
* too small dictionary size will prevent decompressing the stream.
* Specifying a too big dictionary is waste of memory but decompression will
* work.
* <p>
* There is no need to specify a dictionary bigger than
* the uncompressed size of the data even if a bigger dictionary
* was used when compressing. If you know the uncompressed size
* of the data, this might allow saving some memory.
* There is no need to specify a dictionary bigger than the uncompressed
* size of the data even if a bigger dictionary was used when compressing.
* If you know the uncompressed size of the data, this might allow saving
* some memory.
*
* @param in input stream from which compressed
* data is read
* @param in input stream from which compressed data is read
*
* @param uncompSize uncompressed size of the LZMA stream or -1
* if the end marker is used in the LZMA stream
* @param uncompSize uncompressed size of the LZMA stream or -1 if the end
* marker is used in the LZMA stream
*
* @param propsByte LZMA properties byte that has the encoded
* values for literal context bits (lc), literal
* position bits (lp), and position bits (pb)
* @param propsByte LZMA properties byte that has the encoded values for
* literal context bits (lc), literal position bits (lp), and position bits
* (pb)
*
* @param dictSize dictionary size as bytes, must be in the range
* [<code>0</code>, <code>DICT_SIZE_MAX</code>]
*
* @throws CorruptedInputException
* if <code>propsByte</code> is invalid or
* @throws CorruptedInputException if <code>propsByte</code> is invalid
* or
* the first input byte is not 0x00
*
* @throws UnsupportedOptionsException
* dictionary size or uncompressed size is too
* big for this implementation
* @throws UnsupportedOptionsException dictionary size or uncompressed size
* is too big for this implementation
*
*
*/
@@ -295,29 +281,27 @@ public class LZMAInputStream extends InputStream {
* Creates a new input stream that decompresses raw LZMA data (no .lzma
* header) from <code>in</code> optionally with a preset dictionary.
*
* @param in input stream from which LZMA-compressed
* data is read
* @param in input stream from which LZMA-compressed data is read
*
* @param uncompSize uncompressed size of the LZMA stream or -1
* if the end marker is used in the LZMA stream
* @param uncompSize uncompressed size of the LZMA stream or -1 if the end
* marker is used in the LZMA stream
*
* @param propsByte LZMA properties byte that has the encoded
* values for literal context bits (lc), literal
* position bits (lp), and position bits (pb)
* @param propsByte LZMA properties byte that has the encoded values for
* literal context bits (lc), literal position bits (lp), and position bits
* (pb)
*
* @param dictSize dictionary size as bytes, must be in the range
* [<code>0</code>, <code>DICT_SIZE_MAX</code>]
*
* @param presetDict preset dictionary or <code>null</code>
* to use no preset dictionary
* @param presetDict preset dictionary or <code>null</code> to use no preset
* dictionary
*
* @throws CorruptedInputException
* if <code>propsByte</code> is invalid or
* @throws CorruptedInputException if <code>propsByte</code> is invalid
* or
* the first input byte is not 0x00
*
* @throws UnsupportedOptionsException
* dictionary size or uncompressed size is too
* big for this implementation
* @throws UnsupportedOptionsException dictionary size or uncompressed size
* is too big for this implementation
*
* @throws EOFException file is truncated or corrupt
*
@@ -333,29 +317,26 @@ public class LZMAInputStream extends InputStream {
* Creates a new input stream that decompresses raw LZMA data (no .lzma
* header) from <code>in</code> optionally with a preset dictionary.
*
* @param in input stream from which LZMA-compressed
* data is read
* @param in input stream from which LZMA-compressed data is read
*
* @param uncompSize uncompressed size of the LZMA stream or -1
* if the end marker is used in the LZMA stream
* @param uncompSize uncompressed size of the LZMA stream or -1 if the end
* marker is used in the LZMA stream
*
* @param lc number of literal context bits, must be
* in the range [0, 8]
* @param lc number of literal context bits, must be in the range
* [0, 8]
*
* @param lp number of literal position bits, must be
* in the range [0, 4]
* @param lp number of literal position bits, must be in the range
* [0, 4]
*
* @param pb number position bits, must be
* in the range [0, 4]
* @param pb number position bits, must be in the range [0, 4]
*
* @param dictSize dictionary size as bytes, must be in the range
* [<code>0</code>, <code>DICT_SIZE_MAX</code>]
*
* @param presetDict preset dictionary or <code>null</code>
* to use no preset dictionary
* @param presetDict preset dictionary or <code>null</code> to use no preset
* dictionary
*
* @throws CorruptedInputException
* if the first input byte is not 0x00
* @throws CorruptedInputException if the first input byte is not 0x00
*
* @throws EOFException file is truncated or corrupt
*
@@ -424,19 +405,18 @@ public class LZMAInputStream extends InputStream {
/**
* Decompresses the next byte from this input stream.
* <p>
* Reading lots of data with <code>read()</code> from this input stream
* may be inefficient. Wrap it in <code>java.io.BufferedInputStream</code>
* if you need to read lots of data one byte at a time.
* Reading lots of data with <code>read()</code> from this input stream may
* be inefficient. Wrap it in <code>java.io.BufferedInputStream</code> if
* you need to read lots of data one byte at a time.
*
* @return the next decompressed byte, or <code>-1</code>
* to indicate the end of the compressed stream
* @return the next decompressed byte, or <code>-1</code> to indicate the
* end of the compressed stream
*
* @throws CorruptedInputException
*
* @throws XZIOException if the stream has been closed
*
* @throws EOFException
* compressed input is truncated or corrupt
* @throws EOFException compressed input is truncated or corrupt
*
* @throws IOException may be thrown by <code>in</code>
*/
@@ -447,17 +427,17 @@ public class LZMAInputStream extends InputStream {
/**
* Decompresses into an array of bytes.
* <p>
* If <code>len</code> is zero, no bytes are read and <code>0</code>
* is returned. Otherwise this will block until <code>len</code>
* bytes have been decompressed, the end of the LZMA stream is reached,
* or an exception is thrown.
* If <code>len</code> is zero, no bytes are read and <code>0</code> is
* returned. Otherwise this will block until <code>len</code> bytes have
* been decompressed, the end of the LZMA stream is reached, or an exception
* is thrown.
*
* @param buf target buffer for uncompressed data
* @param off start offset in <code>buf</code>
* @param len maximum number of uncompressed bytes to read
*
* @return number of bytes read, or <code>-1</code> to indicate
* the end of the compressed stream
* @return number of bytes read, or <code>-1</code> to indicate the end of
* the compressed stream
*
* @throws CorruptedInputException
*
@@ -552,8 +532,8 @@ public class LZMAInputStream extends InputStream {
}
/**
* Closes the stream and calls <code>in.close()</code>.
* If the stream was already closed, this does nothing.
* Closes the stream and calls <code>in.close()</code>. If the stream was
* already closed, this does nothing.
*
* @throws IOException if thrown by <code>in.close()</code>
*/

View File

@@ -9,11 +9,11 @@
package org.tukaani.xz;
/**
* Thrown when the memory usage limit given to the XZ decompressor
* would be exceeded.
* Thrown when the memory usage limit given to the XZ decompressor would be
* exceeded.
* <p>
* The amount of memory required and the memory usage limit are
* included in the error detail message in human readable format.
* The amount of memory required and the memory usage limit are included in the
* error detail message in human readable format.
*/
public class MemoryLimitException extends XZIOException {
@@ -25,8 +25,8 @@ public class MemoryLimitException extends XZIOException {
/**
* Creates a new MemoryLimitException.
* <p>
* The amount of memory needed and the memory usage limit are
* included in the error detail message.
* The amount of memory needed and the memory usage limit are included in
* the error detail message.
*
* @param memoryNeeded amount of memory needed as kibibytes (KiB)
* @param memoryLimit specified memory usage limit as kibibytes (KiB)
@@ -49,8 +49,8 @@ public class MemoryLimitException extends XZIOException {
}
/**
* Gets what the memory usage limit was at the time the exception
* was created.
* Gets what the memory usage limit was at the time the exception was
* created.
*
* @return memory usage limit as kibibytes (KiB)
*/

View File

@@ -14,14 +14,14 @@ import java.io.IOException;
import java.io.FileNotFoundException;
/**
* Wraps a {@link java.io.RandomAccessFile RandomAccessFile}
* in a SeekableInputStream.
* Wraps a {@link java.io.RandomAccessFile RandomAccessFile} in a
* SeekableInputStream.
*/
public class SeekableFileInputStream extends SeekableInputStream {
/**
* The RandomAccessFile that has been wrapped
* into a SeekableFileInputStream.
* The RandomAccessFile that has been wrapped into a
* SeekableFileInputStream.
*/
protected RandomAccessFile randomAccessFile;
@@ -33,8 +33,8 @@ public class SeekableFileInputStream extends SeekableInputStream {
}
/**
* Creates a new seekable input stream that reads from a file with
* the specified name.
* Creates a new seekable input stream that reads from a file with the
* specified name.
*/
public SeekableFileInputStream(String name) throws FileNotFoundException {
randomAccessFile = new RandomAccessFile(name, "r");
@@ -63,8 +63,7 @@ public class SeekableFileInputStream extends SeekableInputStream {
}
/**
* Calls
* {@link RandomAccessFile#read(byte[],int,int)
* Calls null null null null null null null null null null null {@link RandomAccessFile#read(byte[],int,int)
* randomAccessFile.read(buf, off, len)}.
*/
public int read(byte[] buf, int off, int len) throws IOException {

View File

@@ -19,22 +19,21 @@ public abstract class SeekableInputStream extends InputStream {
/**
* Seeks <code>n</code> bytes forward in this stream.
* <p>
* This will not seek past the end of the file. If the current position
* is already at or past the end of the file, this doesn't seek at all
* and returns <code>0</code>. Otherwise, if skipping <code>n</code> bytes
* would cause the position to exceed the stream size, this will do
* equivalent of <code>seek(length())</code> and the return value will
* be adjusted accordingly.
* This will not seek past the end of the file. If the current position is
* already at or past the end of the file, this doesn't seek at all and
* returns <code>0</code>. Otherwise, if skipping <code>n</code> bytes would
* cause the position to exceed the stream size, this will do equivalent of
* <code>seek(length())</code> and the return value will be adjusted
* accordingly.
* <p>
* If <code>n</code> is negative, the position isn't changed and
* the return value is <code>0</code>. It doesn't seek backward
* because it would conflict with the specification of
* If <code>n</code> is negative, the position isn't changed and the return
* value is <code>0</code>. It doesn't seek backward because it would
* conflict with the specification of
* {@link java.io.InputStream#skip(long) InputStream.skip}.
*
* @return <code>0</code> if <code>n</code> is negative,
* less than <code>n</code> if skipping <code>n</code>
* bytes would seek past the end of the file,
* <code>n</code> otherwise
* @return <code>0</code> if <code>n</code> is negative, less than
* <code>n</code> if skipping <code>n</code> bytes would seek past the end
* of the file, <code>n</code> otherwise
*
* @throws IOException might be thrown by {@link #seek(long)}
*/
@@ -68,14 +67,14 @@ public abstract class SeekableInputStream extends InputStream {
* Seeks to the specified absolute position in the stream.
* <p>
* Seeking past the end of the file should be supported by the subclasses
* unless there is a good reason to do otherwise. If one has seeked
* past the end of the stream, <code>read</code> will return
* <code>-1</code> to indicate end of stream.
* unless there is a good reason to do otherwise. If one has seeked past the
* end of the stream, <code>read</code> will return <code>-1</code> to
* indicate end of stream.
*
* @param pos new read position in the stream
*
* @throws IOException if <code>pos</code> is negative or if
* a stream-specific I/O error occurs
* @throws IOException if <code>pos</code> is negative or if a
* stream-specific I/O error occurs
*/
public abstract void seek(long pos) throws IOException;
}

View File

@@ -20,53 +20,52 @@ import org.tukaani.xz.index.IndexDecoder;
import org.tukaani.xz.index.BlockInfo;
/**
* Decompresses a .xz file in random access mode.
* This supports decompressing concatenated .xz files.
* Decompresses a .xz file in random access mode. This supports decompressing
* concatenated .xz files.
* <p>
* Each .xz file consist of one or more Streams. Each Stream consist of zero
* or more Blocks. Each Stream contains an Index of Streams' Blocks.
* The Indexes from all Streams are loaded in RAM by a constructor of this
* class. A typical .xz file has only one Stream, and parsing its Index will
* need only three or four seeks.
* Each .xz file consist of one or more Streams. Each Stream consist of zero or
* more Blocks. Each Stream contains an Index of Streams' Blocks. The Indexes
* from all Streams are loaded in RAM by a constructor of this class. A typical
* .xz file has only one Stream, and parsing its Index will need only three or
* four seeks.
* <p>
* To make random access possible, the data in a .xz file must be splitted
* into multiple Blocks of reasonable size. Decompression can only start at
* a Block boundary. When seeking to an uncompressed position that is not at
* a Block boundary, decompression starts at the beginning of the Block and
* throws away data until the target position is reached. Thus, smaller Blocks
* mean faster seeks to arbitrary uncompressed positions. On the other hand,
* smaller Blocks mean worse compression. So one has to make a compromise
* between random access speed and compression ratio.
* To make random access possible, the data in a .xz file must be splitted into
* multiple Blocks of reasonable size. Decompression can only start at a Block
* boundary. When seeking to an uncompressed position that is not at a Block
* boundary, decompression starts at the beginning of the Block and throws away
* data until the target position is reached. Thus, smaller Blocks mean faster
* seeks to arbitrary uncompressed positions. On the other hand, smaller Blocks
* mean worse compression. So one has to make a compromise between random access
* speed and compression ratio.
* <p>
* Implementation note: This class uses linear search to locate the correct
* Stream from the data structures in RAM. It was the simplest to implement
* and should be fine as long as there aren't too many Streams. The correct
* Block inside a Stream is located using binary search and thus is fast
* even with a huge number of Blocks.
* Stream from the data structures in RAM. It was the simplest to implement and
* should be fine as long as there aren't too many Streams. The correct Block
* inside a Stream is located using binary search and thus is fast even with a
* huge number of Blocks.
*
* <h4>Memory usage</h4>
* <p>
* The amount of memory needed for the Indexes is taken into account when
* checking the memory usage limit. Each Stream is calculated to need at
* least 1&nbsp;KiB of memory and each Block 16 bytes of memory, rounded up
* to the next kibibyte. So unless the file has a huge number of Streams or
* Blocks, these don't take significant amount of memory.
* checking the memory usage limit. Each Stream is calculated to need at least
* 1&nbsp;KiB of memory and each Block 16 bytes of memory, rounded up to the
* next kibibyte. So unless the file has a huge number of Streams or Blocks,
* these don't take significant amount of memory.
*
* <h4>Creating random-accessible .xz files</h4>
* <p>
* When using {@link XZOutputStream}, a new Block can be started by calling
* its {@link XZOutputStream#endBlock() endBlock} method. If you know
* that the decompressor will only need to seek to certain uncompressed
* positions, it can be a good idea to start a new Block at (some of) these
* positions (and only at these positions to get better compression ratio).
* When using {@link XZOutputStream}, a new Block can be started by calling its
* {@link XZOutputStream#endBlock() endBlock} method. If you know that the
* decompressor will only need to seek to certain uncompressed positions, it can
* be a good idea to start a new Block at (some of) these positions (and only at
* these positions to get better compression ratio).
* <p>
* liblzma in XZ Utils supports starting a new Block with
* <code>LZMA_FULL_FLUSH</code>. XZ Utils 5.1.1alpha added threaded
* compression which creates multi-Block .xz files. XZ Utils 5.1.1alpha
* also added the option <code>--block-size=SIZE</code> to the xz command
* line tool. XZ Utils 5.1.2alpha added a partial implementation of
* <code>--block-list=SIZES</code> which allows specifying sizes of
* individual Blocks.
* <code>LZMA_FULL_FLUSH</code>. XZ Utils 5.1.1alpha added threaded compression
* which creates multi-Block .xz files. XZ Utils 5.1.1alpha also added the
* option <code>--block-size=SIZE</code> to the xz command line tool. XZ Utils
* 5.1.2alpha added a partial implementation of <code>--block-list=SIZES</code>
* which allows specifying sizes of individual Blocks.
*
* @see SeekableFileInputStream
* @see XZInputStream
@@ -80,22 +79,21 @@ public class SeekableXZInputStream extends SeekableInputStream {
private SeekableInputStream in;
/**
* Memory usage limit after the memory usage of the IndexDecoders have
* been substracted.
* Memory usage limit after the memory usage of the IndexDecoders have been
* substracted.
*/
private final int memoryLimit;
/**
* Memory usage of the IndexDecoders.
* <code>memoryLimit + indexMemoryUsage</code> equals the original
* memory usage limit that was passed to the constructor.
* <code>memoryLimit + indexMemoryUsage</code> equals the original memory
* usage limit that was passed to the constructor.
*/
private int indexMemoryUsage = 0;
/**
* List of IndexDecoders, one for each Stream in the file.
* The list is in reverse order: The first element is
* the last Stream in the file.
* List of IndexDecoders, one for each Stream in the file. The list is in
* reverse order: The first element is the last Stream in the file.
*/
private final ArrayList streams = new ArrayList();
@@ -120,20 +118,20 @@ public class SeekableXZInputStream extends SeekableInputStream {
private int blockCount = 0;
/**
* Size and position information about the current Block.
* If there are no Blocks, all values will be <code>-1</code>.
* Size and position information about the current Block. If there are no
* Blocks, all values will be <code>-1</code>.
*/
private final BlockInfo curBlockInfo;
/**
* Temporary (and cached) information about the Block whose information
* is queried via <code>getBlockPos</code> and related functions.
* Temporary (and cached) information about the Block whose information is
* queried via <code>getBlockPos</code> and related functions.
*/
private final BlockInfo queriedBlockInfo;
/**
* Integrity Check in the current XZ Stream. The constructor leaves
* this to point to the Check of the first Stream.
* Integrity Check in the current XZ Stream. The constructor leaves this to
* point to the Check of the first Stream.
*/
private Check check;
@@ -153,14 +151,14 @@ public class SeekableXZInputStream extends SeekableInputStream {
private long seekPos;
/**
* True when <code>seek(long)</code> has been called but the actual
* seeking hasn't been done yet.
* True when <code>seek(long)</code> has been called but the actual seeking
* hasn't been done yet.
*/
private boolean seekNeeded = false;
/**
* True when end of the file was reached. This can be cleared by
* calling <code>seek(long)</code>.
* True when end of the file was reached. This can be cleared by calling
* <code>seek(long)</code>.
*/
private boolean endReached = false;
@@ -170,32 +168,28 @@ public class SeekableXZInputStream extends SeekableInputStream {
private IOException exception = null;
/**
* Temporary buffer for read(). This avoids reallocating memory
* on every read() call.
* Temporary buffer for read(). This avoids reallocating memory on every
* read() call.
*/
private final byte[] tempBuf = new byte[1];
/**
* Creates a new seekable XZ decompressor without a memory usage limit.
*
* @param in seekable input stream containing one or more
* XZ Streams; the whole input stream is used
* @param in seekable input stream containing one or more XZ Streams; the
* whole input stream is used
*
* @throws XZFormatException
* input is not in the XZ format
* @throws XZFormatException input is not in the XZ format
*
* @throws CorruptedInputException
* XZ data is corrupt or truncated
* @throws CorruptedInputException XZ data is corrupt or truncated
*
* @throws UnsupportedOptionsException
* XZ headers seem valid but they specify
* options not supported by this implementation
* @throws UnsupportedOptionsException XZ headers seem valid but they
* specify options not supported by this implementation
*
* @throws EOFException
* less than 6 bytes of input was available
* from <code>in</code>, or (unlikely) the size
* of the underlying stream got smaller while
* this was reading from it
* @throws EOFException less than 6 bytes of input was
* available from
* <code>in</code>, or (unlikely) the size of the underlying stream got
* smaller while this was reading from it
*
* @throws IOException may be thrown by <code>in</code>
*/
@@ -205,35 +199,31 @@ public class SeekableXZInputStream extends SeekableInputStream {
}
/**
* Creates a new seekable XZ decomporessor with an optional
* memory usage limit.
* Creates a new seekable XZ decomporessor with an optional memory usage
* limit.
*
* @param in seekable input stream containing one or more
* XZ Streams; the whole input stream is used
* @param in seekable input stream containing one or more XZ
* Streams; the
* whole input stream is used
*
* @param memoryLimit memory usage limit in kibibytes (KiB)
* or <code>-1</code> to impose no
* memory usage limit
* @param memoryLimit memory usage limit in kibibytes (KiB) or
* <code>-1</code> to impose no memory usage limit
*
* @throws XZFormatException
* input is not in the XZ format
* @throws XZFormatException input is not in the XZ format
*
* @throws CorruptedInputException
* XZ data is corrupt or truncated
* @throws CorruptedInputException XZ data is corrupt or truncated
*
* @throws UnsupportedOptionsException
* XZ headers seem valid but they specify
* options not supported by this implementation
* @throws UnsupportedOptionsException XZ headers seem valid but they
* specify options not supported by this implementation
*
* @throws MemoryLimitException
* decoded XZ Indexes would need more memory
* @throws MemoryLimitException decoded XZ Indexes would need more
* memory
* than allowed by the memory usage limit
*
* @throws EOFException
* less than 6 bytes of input was available
* from <code>in</code>, or (unlikely) the size
* of the underlying stream got smaller while
* this was reading from it
* @throws EOFException less than 6 bytes of input was
* available from
* <code>in</code>, or (unlikely) the size of the underlying stream got
* smaller while this was reading from it
*
* @throws IOException may be thrown by <code>in</code>
*/
@@ -391,13 +381,11 @@ public class SeekableXZInputStream extends SeekableInputStream {
}
/**
* Gets the types of integrity checks used in the .xz file.
* Multiple checks are possible only if there are multiple
* concatenated XZ Streams.
* Gets the types of integrity checks used in the .xz file. Multiple checks
* are possible only if there are multiple concatenated XZ Streams.
* <p>
* The returned value has a bit set for every check type that is present.
* For example, if CRC64 and SHA-256 were used, the return value is
* <code>(1&nbsp;&lt;&lt;&nbsp;XZ.CHECK_CRC64)
* For example, if CRC64 and SHA-256 were used, the return value is <code>(1&nbsp;&lt;&lt;&nbsp;XZ.CHECK_CRC64)
* | (1&nbsp;&lt;&lt;&nbsp;XZ.CHECK_SHA256)</code>.
*/
public int getCheckTypes() {
@@ -405,22 +393,21 @@ public class SeekableXZInputStream extends SeekableInputStream {
}
/**
* Gets the amount of memory in kibibytes (KiB) used by
* the data structures needed to locate the XZ Blocks.
* This is usually useless information but since it is calculated
* for memory usage limit anyway, it is nice to make it available to too.
* Gets the amount of memory in kibibytes (KiB) used by the data structures
* needed to locate the XZ Blocks. This is usually useless information but
* since it is calculated for memory usage limit anyway, it is nice to make
* it available to too.
*/
public int getIndexMemoryUsage() {
return indexMemoryUsage;
}
/**
* Gets the uncompressed size of the largest XZ Block in bytes.
* This can be useful if you want to check that the file doesn't
* have huge XZ Blocks which could make seeking to arbitrary offsets
* very slow. Note that huge Blocks don't automatically mean that
* seeking would be slow, for example, seeking to the beginning of
* any Block is always fast.
* Gets the uncompressed size of the largest XZ Block in bytes. This can be
* useful if you want to check that the file doesn't have huge XZ Blocks
* which could make seeking to arbitrary offsets very slow. Note that huge
* Blocks don't automatically mean that seeking would be slow, for example,
* seeking to the beginning of any Block is always fast.
*/
public long getLargestBlockSize() {
return largestBlockSize;
@@ -473,9 +460,9 @@ public class SeekableXZInputStream extends SeekableInputStream {
}
/**
* Gets the position where the given compressed Block starts in
* the underlying .xz file.
* This information is rarely useful to the users of this class.
* Gets the position where the given compressed Block starts in the
* underlying .xz file. This information is rarely useful to the users of
* this class.
*
* @throws IndexOutOfBoundsException if
* <code>blockNumber&nbsp;&lt;&nbsp;0</code> or
@@ -489,9 +476,9 @@ public class SeekableXZInputStream extends SeekableInputStream {
}
/**
* Gets the compressed size of the given Block.
* This together with the uncompressed size can be used to calculate
* the compression ratio of the specific Block.
* Gets the compressed size of the given Block. This together with the
* uncompressed size can be used to calculate the compression ratio of the
* specific Block.
*
* @throws IndexOutOfBoundsException if
* <code>blockNumber&nbsp;&lt;&nbsp;0</code> or
@@ -524,8 +511,7 @@ public class SeekableXZInputStream extends SeekableInputStream {
* Gets the number of the Block that contains the byte at the given
* uncompressed position.
*
* @throws IndexOutOfBoundsException if
* <code>pos&nbsp;&lt;&nbsp;0</code> or
* @throws IndexOutOfBoundsException if <code>pos&nbsp;&lt;&nbsp;0</code> or
* <code>pos&nbsp;&gt;=&nbsp;length()</code>.
*
* @since 1.3
@@ -538,8 +524,8 @@ public class SeekableXZInputStream extends SeekableInputStream {
/**
* Decompresses the next byte from this input stream.
*
* @return the next decompressed byte, or <code>-1</code>
* to indicate the end of the compressed stream
* @return the next decompressed byte, or <code>-1</code> to indicate the
* end of the compressed stream
*
* @throws CorruptedInputException
* @throws UnsupportedOptionsException
@@ -556,16 +542,16 @@ public class SeekableXZInputStream extends SeekableInputStream {
/**
* Decompresses into an array of bytes.
* <p>
* If <code>len</code> is zero, no bytes are read and <code>0</code>
* is returned. Otherwise this will try to decompress <code>len</code>
* bytes of uncompressed data. Less than <code>len</code> bytes may
* be read only in the following situations:
* If <code>len</code> is zero, no bytes are read and <code>0</code> is
* returned. Otherwise this will try to decompress <code>len</code> bytes of
* uncompressed data. Less than <code>len</code> bytes may be read only in
* the following situations:
* <ul>
* <li>The end of the compressed data was reached successfully.</li>
* <li>An error is detected after at least one but less than
* <code>len</code> bytes have already been successfully
* decompressed. The next call with non-zero <code>len</code>
* will immediately throw the pending exception.</li>
* <code>len</code> bytes have already been successfully decompressed. The
* next call with non-zero <code>len</code> will immediately throw the
* pending exception.</li>
* <li>An exception is thrown.</li>
* </ul>
*
@@ -573,8 +559,8 @@ public class SeekableXZInputStream extends SeekableInputStream {
* @param off start offset in <code>buf</code>
* @param len maximum number of uncompressed bytes to read
*
* @return number of bytes read, or <code>-1</code> to indicate
* the end of the compressed stream
* @return number of bytes read, or <code>-1</code> to indicate the end of
* the compressed stream
*
* @throws CorruptedInputException
* @throws UnsupportedOptionsException
@@ -639,15 +625,14 @@ public class SeekableXZInputStream extends SeekableInputStream {
}
/**
* Returns the number of uncompressed bytes that can be read
* without blocking. The value is returned with an assumption
* that the compressed input data will be valid. If the compressed
* data is corrupt, <code>CorruptedInputException</code> may get
* thrown before the number of bytes claimed to be available have
* been read from this input stream.
* Returns the number of uncompressed bytes that can be read without
* blocking. The value is returned with an assumption that the compressed
* input data will be valid. If the compressed data is corrupt,
* <code>CorruptedInputException</code> may get thrown before the number of
* bytes claimed to be available have been read from this input stream.
*
* @return the number of uncompressed bytes that can be read
* without blocking
* @return the number of uncompressed bytes that can be read without
* blocking
*/
public int available() throws IOException {
if (in == null)
@@ -663,8 +648,8 @@ public class SeekableXZInputStream extends SeekableInputStream {
}
/**
* Closes the stream and calls <code>in.close()</code>.
* If the stream was already closed, this does nothing.
* Closes the stream and calls <code>in.close()</code>. If the stream was
* already closed, this does nothing.
*
* @throws IOException if thrown by <code>in.close()</code>
*/
@@ -678,8 +663,8 @@ public class SeekableXZInputStream extends SeekableInputStream {
}
/**
* Gets the uncompressed size of this input stream. If there are multiple
* XZ Streams, the total uncompressed size of all XZ Streams is returned.
* Gets the uncompressed size of this input stream. If there are multiple XZ
* Streams, the total uncompressed size of all XZ Streams is returned.
*/
public long length() {
return uncompressedSize;
@@ -698,20 +683,19 @@ public class SeekableXZInputStream extends SeekableInputStream {
}
/**
* Seeks to the specified absolute uncompressed position in the stream.
* This only stores the new position, so this function itself is always
* very fast. The actual seek is done when <code>read</code> is called
* to read at least one byte.
* Seeks to the specified absolute uncompressed position in the stream. This
* only stores the new position, so this function itself is always very
* fast. The actual seek is done when <code>read</code> is called to read at
* least one byte.
* <p>
* Seeking past the end of the stream is possible. In that case
* <code>read</code> will return <code>-1</code> to indicate
* the end of the stream.
* <code>read</code> will return <code>-1</code> to indicate the end of the
* stream.
*
* @param pos new uncompressed read position
*
* @throws XZIOException
* if <code>pos</code> is negative, or
* if stream has been closed
* @throws XZIOException if <code>pos</code> is negative, or if stream has
* been closed
*/
public void seek(long pos) throws IOException {
if (in == null)
@@ -727,10 +711,9 @@ public class SeekableXZInputStream extends SeekableInputStream {
/**
* Seeks to the beginning of the given XZ Block.
*
* @throws XZIOException
* if <code>blockNumber&nbsp;&lt;&nbsp;0</code> or
* <code>blockNumber&nbsp;&gt;=&nbsp;getBlockCount()</code>,
* or if stream has been closed
* @throws XZIOException if <code>blockNumber&nbsp;&lt;&nbsp;0</code> or
* <code>blockNumber&nbsp;&gt;=&nbsp;getBlockCount()</code>, or if stream
* has been closed
*
* @since 1.3
*/
@@ -749,8 +732,8 @@ public class SeekableXZInputStream extends SeekableInputStream {
}
/**
* Does the actual seeking. This is also called when <code>read</code>
* needs a new Block to decode.
* Does the actual seeking. This is also called when <code>read</code> needs
* a new Block to decode.
*/
private void seek() throws IOException {
// If seek(long) wasn't called, we simply need to get the next Block
@@ -844,8 +827,8 @@ public class SeekableXZInputStream extends SeekableInputStream {
}
/**
* Locates the given Block and stores information about it
* to <code>info</code>.
* Locates the given Block and stores information about it to
* <code>info</code>.
*/
private void locateBlockByNumber(BlockInfo info, int blockNumber) {
// Validate.

View File

@@ -18,11 +18,11 @@ import org.tukaani.xz.index.IndexHash;
import org.tukaani.xz.check.Check;
/**
* Decompresses exactly one XZ Stream in streamed mode (no seeking).
* The decompression stops after the first XZ Stream has been decompressed,
* and the read position in the input stream is left at the first byte
* after the end of the XZ Stream. This can be useful when XZ data has
* been stored inside some other file format or protocol.
* Decompresses exactly one XZ Stream in streamed mode (no seeking). The
* decompression stops after the first XZ Stream has been decompressed, and the
* read position in the input stream is left at the first byte after the end of
* the XZ Stream. This can be useful when XZ data has been stored inside some
* other file format or protocol.
* <p>
* Unless you know what you are doing, don't use this class to decompress
* standalone .xz files. For that purpose, use <code>XZInputStream</code>.
@@ -30,11 +30,11 @@ import org.tukaani.xz.check.Check;
* <h4>When uncompressed size is known beforehand</h4>
* <p>
* If you are decompressing complete XZ streams and your application knows
* exactly how much uncompressed data there should be, it is good to try
* reading one more byte by calling <code>read()</code> and checking
* that it returns <code>-1</code>. This way the decompressor will parse the
* file footers and verify the integrity checks, giving the caller more
* confidence that the uncompressed data is valid.
* exactly how much uncompressed data there should be, it is good to try reading
* one more byte by calling <code>read()</code> and checking that it returns
* <code>-1</code>. This way the decompressor will parse the file footers and
* verify the integrity checks, giving the caller more confidence that the
* uncompressed data is valid.
*
* @see XZInputStream
*/
@@ -52,29 +52,25 @@ public class SingleXZInputStream extends InputStream {
private final byte[] tempBuf = new byte[1];
/**
* Creates a new XZ decompressor that decompresses exactly one
* XZ Stream from <code>in</code> without a memory usage limit.
* Creates a new XZ decompressor that decompresses exactly one XZ Stream
* from <code>in</code> without a memory usage limit.
* <p>
* This constructor reads and parses the XZ Stream Header (12 bytes)
* from <code>in</code>. The header of the first Block is not read
* until <code>read</code> is called.
* This constructor reads and parses the XZ Stream Header (12 bytes) from
* <code>in</code>. The header of the first Block is not read until
* <code>read</code> is called.
*
* @param in input stream from which XZ-compressed
* data is read
* @param in input stream from which XZ-compressed data is read
*
* @throws XZFormatException
* input is not in the XZ format
* @throws XZFormatException input is not in the XZ format
*
* @throws CorruptedInputException
* XZ header CRC32 doesn't match
* @throws CorruptedInputException XZ header CRC32 doesn't match
*
* @throws UnsupportedOptionsException
* XZ header is valid but specifies options
* not supported by this implementation
* @throws UnsupportedOptionsException XZ header is valid but specifies
* options not supported by this implementation
*
* @throws EOFException
* less than 12 bytes of input was available
* from <code>in</code>
* @throws EOFException less than 12 bytes of input was
* available from
* <code>in</code>
*
* @throws IOException may be thrown by <code>in</code>
*/
@@ -83,32 +79,27 @@ public class SingleXZInputStream extends InputStream {
}
/**
* Creates a new XZ decompressor that decompresses exactly one
* XZ Stream from <code>in</code> with an optional memory usage limit.
* Creates a new XZ decompressor that decompresses exactly one XZ Stream
* from <code>in</code> with an optional memory usage limit.
* <p>
* This is identical to <code>SingleXZInputStream(InputStream)</code>
* except that this takes also the <code>memoryLimit</code> argument.
* This is identical to <code>SingleXZInputStream(InputStream)</code> except
* that this takes also the <code>memoryLimit</code> argument.
*
* @param in input stream from which XZ-compressed
* data is read
* @param in input stream from which XZ-compressed data is read
*
* @param memoryLimit memory usage limit in kibibytes (KiB)
* or <code>-1</code> to impose no
* memory usage limit
* @param memoryLimit memory usage limit in kibibytes (KiB) or
* <code>-1</code> to impose no memory usage limit
*
* @throws XZFormatException
* input is not in the XZ format
* @throws XZFormatException input is not in the XZ format
*
* @throws CorruptedInputException
* XZ header CRC32 doesn't match
* @throws CorruptedInputException XZ header CRC32 doesn't match
*
* @throws UnsupportedOptionsException
* XZ header is valid but specifies options
* not supported by this implementation
* @throws UnsupportedOptionsException XZ header is valid but specifies
* options not supported by this implementation
*
* @throws EOFException
* less than 12 bytes of input was available
* from <code>in</code>
* @throws EOFException less than 12 bytes of input was
* available from
* <code>in</code>
*
* @throws IOException may be thrown by <code>in</code>
*/
@@ -158,12 +149,12 @@ public class SingleXZInputStream extends InputStream {
/**
* Decompresses the next byte from this input stream.
* <p>
* Reading lots of data with <code>read()</code> from this input stream
* may be inefficient. Wrap it in {@link java.io.BufferedInputStream}
* if you need to read lots of data one byte at a time.
* Reading lots of data with <code>read()</code> from this input stream may
* be inefficient. Wrap it in {@link java.io.BufferedInputStream} if you
* need to read lots of data one byte at a time.
*
* @return the next decompressed byte, or <code>-1</code>
* to indicate the end of the compressed stream
* @return the next decompressed byte, or <code>-1</code> to indicate the
* end of the compressed stream
*
* @throws CorruptedInputException
* @throws UnsupportedOptionsException
@@ -171,8 +162,8 @@ public class SingleXZInputStream extends InputStream {
*
* @throws XZIOException if the stream has been closed
*
* @throws EOFException
* compressed input is truncated or corrupt
* @throws EOFException compressed input is truncated or
* corrupt
*
* @throws IOException may be thrown by <code>in</code>
*/
@@ -183,16 +174,16 @@ public class SingleXZInputStream extends InputStream {
/**
* Decompresses into an array of bytes.
* <p>
* If <code>len</code> is zero, no bytes are read and <code>0</code>
* is returned. Otherwise this will try to decompress <code>len</code>
* bytes of uncompressed data. Less than <code>len</code> bytes may
* be read only in the following situations:
* If <code>len</code> is zero, no bytes are read and <code>0</code> is
* returned. Otherwise this will try to decompress <code>len</code> bytes of
* uncompressed data. Less than <code>len</code> bytes may be read only in
* the following situations:
* <ul>
* <li>The end of the compressed data was reached successfully.</li>
* <li>An error is detected after at least one but less <code>len</code>
* bytes have already been successfully decompressed.
* The next call with non-zero <code>len</code> will immediately
* throw the pending exception.</li>
* bytes have already been successfully decompressed. The next call with
* non-zero <code>len</code> will immediately throw the pending
* exception.</li>
* <li>An exception is thrown.</li>
* </ul>
*
@@ -200,8 +191,8 @@ public class SingleXZInputStream extends InputStream {
* @param off start offset in <code>buf</code>
* @param len maximum number of uncompressed bytes to read
*
* @return number of bytes read, or <code>-1</code> to indicate
* the end of the compressed stream
* @return number of bytes read, or <code>-1</code> to indicate the end of
* the compressed stream
*
* @throws CorruptedInputException
* @throws UnsupportedOptionsException
@@ -209,8 +200,8 @@ public class SingleXZInputStream extends InputStream {
*
* @throws XZIOException if the stream has been closed
*
* @throws EOFException
* compressed input is truncated or corrupt
* @throws EOFException compressed input is truncated or
* corrupt
*
* @throws IOException may be thrown by <code>in</code>
*/
@@ -279,15 +270,14 @@ public class SingleXZInputStream extends InputStream {
}
/**
* Returns the number of uncompressed bytes that can be read
* without blocking. The value is returned with an assumption
* that the compressed input data will be valid. If the compressed
* data is corrupt, <code>CorruptedInputException</code> may get
* thrown before the number of bytes claimed to be available have
* been read from this input stream.
* Returns the number of uncompressed bytes that can be read without
* blocking. The value is returned with an assumption that the compressed
* input data will be valid. If the compressed data is corrupt,
* <code>CorruptedInputException</code> may get thrown before the number of
* bytes claimed to be available have been read from this input stream.
*
* @return the number of uncompressed bytes that can be read
* without blocking
* @return the number of uncompressed bytes that can be read without
* blocking
*/
public int available() throws IOException {
if (in == null)
@@ -300,8 +290,8 @@ public class SingleXZInputStream extends InputStream {
}
/**
* Closes the stream and calls <code>in.close()</code>.
* If the stream was already closed, this does nothing.
* Closes the stream and calls <code>in.close()</code>. If the stream was
* already closed, this does nothing.
*
* @throws IOException if thrown by <code>in.close()</code>
*/

View File

@@ -9,23 +9,23 @@
package org.tukaani.xz;
/**
* Thrown when compression options not supported by this implementation
* are detected. Some other implementation might support those options.
* Thrown when compression options not supported by this implementation are
* detected. Some other implementation might support those options.
*/
public class UnsupportedOptionsException extends XZIOException {
private static final long serialVersionUID = 3L;
/**
* Creates a new UnsupportedOptionsException with null
* as its error detail message.
* Creates a new UnsupportedOptionsException with null as its error detail
* message.
*/
public UnsupportedOptionsException() {
}
/**
* Creates a new UnsupportedOptionsException with the given
* error detail message.
* Creates a new UnsupportedOptionsException with the given error detail
* message.
*
* @param s error detail message
*/

View File

@@ -14,23 +14,23 @@ package org.tukaani.xz;
public class XZ {
/**
* XZ Header Magic Bytes begin a XZ file.
* This can be useful to detect XZ compressed data.
* XZ Header Magic Bytes begin a XZ file. This can be useful to detect XZ
* compressed data.
*/
public static final byte[] HEADER_MAGIC = {
(byte) 0xFD, '7', 'z', 'X', 'Z', '\0'};
(byte) 0xFD, '7', 'z', 'X', 'Z', '\0' };
/**
* XZ Footer Magic Bytes are the last bytes of a XZ Stream.
*/
public static final byte[] FOOTER_MAGIC = {'Y', 'Z'};
public static final byte[] FOOTER_MAGIC = { 'Y', 'Z' };
/**
* Integrity check ID indicating that no integrity check is calculated.
* <p>
* Omitting the integrity check is strongly discouraged except when
* the integrity of the data will be verified by other means anyway,
* and calculating the check twice would be useless.
* Omitting the integrity check is strongly discouraged except when the
* integrity of the data will be verified by other means anyway, and
* calculating the check twice would be useless.
*/
public static final int CHECK_NONE = 0;

View File

@@ -9,9 +9,8 @@
package org.tukaani.xz;
/**
* Generic {@link java.io.IOException IOException} specific to this package.
* The other IOExceptions in this package extend
* from <code>XZIOException</code>.
* Generic {@link java.io.IOException IOException} specific to this package. The
* other IOExceptions in this package extend from <code>XZIOException</code>.
*/
public class XZIOException extends java.io.IOException {

View File

@@ -17,9 +17,9 @@ import org.tukaani.xz.common.DecoderUtil;
/**
* Decompresses a .xz file in streamed mode (no seeking).
* <p>
* Use this to decompress regular standalone .xz files. This reads from
* its input stream until the end of the input or until an error occurs.
* This supports decompressing concatenated .xz files.
* Use this to decompress regular standalone .xz files. This reads from its
* input stream until the end of the input or until an error occurs. This
* supports decompressing concatenated .xz files.
*
* <h4>Typical use cases</h4>
* <p>
@@ -30,18 +30,18 @@ import org.tukaani.xz.common.DecoderUtil;
* XZInputStream inxz = new XZInputStream(infile);
* </pre></blockquote>
* <p>
* It's important to keep in mind that decompressor memory usage depends
* on the settings used to compress the file. The worst-case memory usage
* of XZInputStream is currently 1.5&nbsp;GiB. Still, very few files will
* require more than about 65&nbsp;MiB because that's how much decompressing
* a file created with the highest preset level will need, and only a few
* people use settings other than the predefined presets.
* It's important to keep in mind that decompressor memory usage depends on the
* settings used to compress the file. The worst-case memory usage of
* XZInputStream is currently 1.5&nbsp;GiB. Still, very few files will require
* more than about 65&nbsp;MiB because that's how much decompressing a file
* created with the highest preset level will need, and only a few people use
* settings other than the predefined presets.
* <p>
* It is possible to specify a memory usage limit for
* <code>XZInputStream</code>. If decompression requires more memory than
* the specified limit, MemoryLimitException will be thrown when reading
* from the stream. For example, the following sets the memory usage limit
* to 100&nbsp;MiB:
* <code>XZInputStream</code>. If decompression requires more memory than the
* specified limit, MemoryLimitException will be thrown when reading from the
* stream. For example, the following sets the memory usage limit to
* 100&nbsp;MiB:
* <p>
* <blockquote><pre>
* InputStream infile = new FileInputStream("foo.xz");
@@ -50,13 +50,12 @@ import org.tukaani.xz.common.DecoderUtil;
*
* <h4>When uncompressed size is known beforehand</h4>
* <p>
* If you are decompressing complete files and your application knows
* exactly how much uncompressed data there should be, it is good to try
* reading one more byte by calling <code>read()</code> and checking
* that it returns <code>-1</code>. This way the decompressor will parse the
* file footers and verify the integrity checks, giving the caller more
* confidence that the uncompressed data is valid. (This advice seems to
* apply to
* If you are decompressing complete files and your application knows exactly
* how much uncompressed data there should be, it is good to try reading one
* more byte by calling <code>read()</code> and checking that it returns
* <code>-1</code>. This way the decompressor will parse the file footers and
* verify the integrity checks, giving the caller more confidence that the
* uncompressed data is valid. (This advice seems to apply to
* {@link java.util.zip.GZIPInputStream java.util.zip.GZIPInputStream} too.)
*
* @see SingleXZInputStream
@@ -74,26 +73,22 @@ public class XZInputStream extends InputStream {
/**
* Creates a new XZ decompressor without a memory usage limit.
* <p>
* This constructor reads and parses the XZ Stream Header (12 bytes)
* from <code>in</code>. The header of the first Block is not read
* until <code>read</code> is called.
* This constructor reads and parses the XZ Stream Header (12 bytes) from
* <code>in</code>. The header of the first Block is not read until
* <code>read</code> is called.
*
* @param in input stream from which XZ-compressed
* data is read
* @param in input stream from which XZ-compressed data is read
*
* @throws XZFormatException
* input is not in the XZ format
* @throws XZFormatException input is not in the XZ format
*
* @throws CorruptedInputException
* XZ header CRC32 doesn't match
* @throws CorruptedInputException XZ header CRC32 doesn't match
*
* @throws UnsupportedOptionsException
* XZ header is valid but specifies options
* not supported by this implementation
* @throws UnsupportedOptionsException XZ header is valid but specifies
* options not supported by this implementation
*
* @throws EOFException
* less than 12 bytes of input was available
* from <code>in</code>
* @throws EOFException less than 12 bytes of input was
* available from
* <code>in</code>
*
* @throws IOException may be thrown by <code>in</code>
*/
@@ -104,29 +99,24 @@ public class XZInputStream extends InputStream {
/**
* Creates a new XZ decompressor with an optional memory usage limit.
* <p>
* This is identical to <code>XZInputStream(InputStream)</code> except
* that this takes also the <code>memoryLimit</code> argument.
* This is identical to <code>XZInputStream(InputStream)</code> except that
* this takes also the <code>memoryLimit</code> argument.
*
* @param in input stream from which XZ-compressed
* data is read
* @param in input stream from which XZ-compressed data is read
*
* @param memoryLimit memory usage limit in kibibytes (KiB)
* or <code>-1</code> to impose no
* memory usage limit
* @param memoryLimit memory usage limit in kibibytes (KiB) or
* <code>-1</code> to impose no memory usage limit
*
* @throws XZFormatException
* input is not in the XZ format
* @throws XZFormatException input is not in the XZ format
*
* @throws CorruptedInputException
* XZ header CRC32 doesn't match
* @throws CorruptedInputException XZ header CRC32 doesn't match
*
* @throws UnsupportedOptionsException
* XZ header is valid but specifies options
* not supported by this implementation
* @throws UnsupportedOptionsException XZ header is valid but specifies
* options not supported by this implementation
*
* @throws EOFException
* less than 12 bytes of input was available
* from <code>in</code>
* @throws EOFException less than 12 bytes of input was
* available from
* <code>in</code>
*
* @throws IOException may be thrown by <code>in</code>
*/
@@ -139,12 +129,12 @@ public class XZInputStream extends InputStream {
/**
* Decompresses the next byte from this input stream.
* <p>
* Reading lots of data with <code>read()</code> from this input stream
* may be inefficient. Wrap it in {@link java.io.BufferedInputStream}
* if you need to read lots of data one byte at a time.
* Reading lots of data with <code>read()</code> from this input stream may
* be inefficient. Wrap it in {@link java.io.BufferedInputStream} if you
* need to read lots of data one byte at a time.
*
* @return the next decompressed byte, or <code>-1</code>
* to indicate the end of the compressed stream
* @return the next decompressed byte, or <code>-1</code> to indicate the
* end of the compressed stream
*
* @throws CorruptedInputException
* @throws UnsupportedOptionsException
@@ -152,8 +142,8 @@ public class XZInputStream extends InputStream {
*
* @throws XZIOException if the stream has been closed
*
* @throws EOFException
* compressed input is truncated or corrupt
* @throws EOFException compressed input is truncated or
* corrupt
*
* @throws IOException may be thrown by <code>in</code>
*/
@@ -164,16 +154,16 @@ public class XZInputStream extends InputStream {
/**
* Decompresses into an array of bytes.
* <p>
* If <code>len</code> is zero, no bytes are read and <code>0</code>
* is returned. Otherwise this will try to decompress <code>len</code>
* bytes of uncompressed data. Less than <code>len</code> bytes may
* be read only in the following situations:
* If <code>len</code> is zero, no bytes are read and <code>0</code> is
* returned. Otherwise this will try to decompress <code>len</code> bytes of
* uncompressed data. Less than <code>len</code> bytes may be read only in
* the following situations:
* <ul>
* <li>The end of the compressed data was reached successfully.</li>
* <li>An error is detected after at least one but less <code>len</code>
* bytes have already been successfully decompressed.
* The next call with non-zero <code>len</code> will immediately
* throw the pending exception.</li>
* bytes have already been successfully decompressed. The next call with
* non-zero <code>len</code> will immediately throw the pending
* exception.</li>
* <li>An exception is thrown.</li>
* </ul>
*
@@ -181,8 +171,8 @@ public class XZInputStream extends InputStream {
* @param off start offset in <code>buf</code>
* @param len maximum number of uncompressed bytes to read
*
* @return number of bytes read, or <code>-1</code> to indicate
* the end of the compressed stream
* @return number of bytes read, or <code>-1</code> to indicate the end of
* the compressed stream
*
* @throws CorruptedInputException
* @throws UnsupportedOptionsException
@@ -190,8 +180,8 @@ public class XZInputStream extends InputStream {
*
* @throws XZIOException if the stream has been closed
*
* @throws EOFException
* compressed input is truncated or corrupt
* @throws EOFException compressed input is truncated or
* corrupt
*
* @throws IOException may be thrown by <code>in</code>
*/
@@ -276,15 +266,14 @@ public class XZInputStream extends InputStream {
}
/**
* Returns the number of uncompressed bytes that can be read
* without blocking. The value is returned with an assumption
* that the compressed input data will be valid. If the compressed
* data is corrupt, <code>CorruptedInputException</code> may get
* thrown before the number of bytes claimed to be available have
* been read from this input stream.
* Returns the number of uncompressed bytes that can be read without
* blocking. The value is returned with an assumption that the compressed
* input data will be valid. If the compressed data is corrupt,
* <code>CorruptedInputException</code> may get thrown before the number of
* bytes claimed to be available have been read from this input stream.
*
* @return the number of uncompressed bytes that can be read
* without blocking
* @return the number of uncompressed bytes that can be read without
* blocking
*/
public int available() throws IOException {
if (in == null)
@@ -297,8 +286,8 @@ public class XZInputStream extends InputStream {
}
/**
* Closes the stream and calls <code>in.close()</code>.
* If the stream was already closed, this does nothing.
* Closes the stream and calls <code>in.close()</code>. If the stream was
* already closed, this does nothing.
*
* @throws IOException if thrown by <code>in.close()</code>
*/

View File

@@ -20,25 +20,24 @@ import org.tukaani.xz.index.IndexEncoder;
*
* <h4>Examples</h4>
* <p>
* Getting an output stream to compress with LZMA2 using the default
* settings and the default integrity check type (CRC64):
* Getting an output stream to compress with LZMA2 using the default settings
* and the default integrity check type (CRC64):
* <p>
* <blockquote><pre>
* FileOutputStream outfile = new FileOutputStream("foo.xz");
* XZOutputStream outxz = new XZOutputStream(outfile, new LZMA2Options());
* </pre></blockquote>
* <p>
* Using the preset level <code>8</code> for LZMA2 (the default
* is <code>6</code>) and SHA-256 instead of CRC64 for integrity checking:
* Using the preset level <code>8</code> for LZMA2 (the default is
* <code>6</code>) and SHA-256 instead of CRC64 for integrity checking:
* <p>
* <blockquote><pre>
* XZOutputStream outxz = new XZOutputStream(outfile, new LZMA2Options(8),
* XZ.CHECK_SHA256);
* </pre></blockquote>
* <p>
* Using the x86 BCJ filter together with LZMA2 to compress x86 executables
* and printing the memory usage information before creating the
* XZOutputStream:
* Using the x86 BCJ filter together with LZMA2 to compress x86 executables and
* printing the memory usage information before creating the XZOutputStream:
* <p>
* <blockquote><pre>
* X86Options x86 = new X86Options();
@@ -64,9 +63,9 @@ public class XZOutputStream extends FinishableOutputStream {
private FilterEncoder[] filters;
/**
* True if the current filter chain supports flushing.
* If it doesn't support flushing, <code>flush()</code>
* will use <code>endBlock()</code> as a fallback.
* True if the current filter chain supports flushing. If it doesn't support
* flushing, <code>flush()</code> will use <code>endBlock()</code> as a
* fallback.
*/
private boolean filtersSupportFlushing;
@@ -76,19 +75,17 @@ public class XZOutputStream extends FinishableOutputStream {
private final byte[] tempBuf = new byte[1];
/**
* Creates a new XZ compressor using one filter and CRC64 as
* the integrity check. This constructor is equivalent to passing
* a single-member FilterOptions array to
* Creates a new XZ compressor using one filter and CRC64 as the integrity
* check. This constructor is equivalent to passing a single-member
* FilterOptions array to
* <code>XZOutputStream(OutputStream, FilterOptions[])</code>.
*
* @param out output stream to which the compressed data
* will be written
* @param out output stream to which the compressed data will be
* written
*
* @param filterOptions
* filter options to use
* @param filterOptions filter options to use
*
* @throws UnsupportedOptionsException
* invalid filter chain
* @throws UnsupportedOptionsException invalid filter chain
*
* @throws IOException may be thrown from <code>out</code>
*/
@@ -98,43 +95,39 @@ public class XZOutputStream extends FinishableOutputStream {
}
/**
* Creates a new XZ compressor using one filter and the specified
* integrity check type. This constructor is equivalent to
* passing a single-member FilterOptions array to
* Creates a new XZ compressor using one filter and the specified integrity
* check type. This constructor is equivalent to passing a single-member
* FilterOptions array to
* <code>XZOutputStream(OutputStream, FilterOptions[], int)</code>.
*
* @param out output stream to which the compressed data
* will be written
* @param out output stream to which the compressed data will be
* written
*
* @param filterOptions
* filter options to use
* @param filterOptions filter options to use
*
* @param checkType type of the integrity check,
* for example XZ.CHECK_CRC32
* @param checkType type of the integrity check, for example
* XZ.CHECK_CRC32
*
* @throws UnsupportedOptionsException
* invalid filter chain
* @throws UnsupportedOptionsException invalid filter chain
*
* @throws IOException may be thrown from <code>out</code>
*/
public XZOutputStream(OutputStream out, FilterOptions filterOptions,
int checkType) throws IOException {
this(out, new FilterOptions[] {filterOptions}, checkType);
this(out, new FilterOptions[] { filterOptions }, checkType);
}
/**
* Creates a new XZ compressor using 1-4 filters and CRC64 as
* the integrity check. This constructor is equivalent
* Creates a new XZ compressor using 1-4 filters and CRC64 as the integrity
* check. This constructor is equivalent
* <code>XZOutputStream(out, filterOptions, XZ.CHECK_CRC64)</code>.
*
* @param out output stream to which the compressed data
* will be written
* @param out output stream to which the compressed data will be
* written
*
* @param filterOptions
* array of filter options to use
* @param filterOptions array of filter options to use
*
* @throws UnsupportedOptionsException
* invalid filter chain
* @throws UnsupportedOptionsException invalid filter chain
*
* @throws IOException may be thrown from <code>out</code>
*/
@@ -144,20 +137,18 @@ public class XZOutputStream extends FinishableOutputStream {
}
/**
* Creates a new XZ compressor using 1-4 filters and the specified
* integrity check type.
* Creates a new XZ compressor using 1-4 filters and the specified integrity
* check type.
*
* @param out output stream to which the compressed data
* will be written
* @param out output stream to which the compressed data will be
* written
*
* @param filterOptions
* array of filter options to use
* @param filterOptions array of filter options to use
*
* @param checkType type of the integrity check,
* for example XZ.CHECK_CRC32
* @param checkType type of the integrity check, for example
* XZ.CHECK_CRC32
*
* @throws UnsupportedOptionsException
* invalid filter chain
* @throws UnsupportedOptionsException invalid filter chain
*
* @throws IOException may be thrown from <code>out</code>
*/
@@ -173,16 +164,14 @@ public class XZOutputStream extends FinishableOutputStream {
}
/**
* Updates the filter chain with a single filter.
* This is equivalent to passing a single-member FilterOptions array
* to <code>updateFilters(FilterOptions[])</code>.
* Updates the filter chain with a single filter. This is equivalent to
* passing a single-member FilterOptions array to
* <code>updateFilters(FilterOptions[])</code>.
*
* @param filterOptions
* new filter to use
* @param filterOptions new filter to use
*
* @throws UnsupportedOptionsException
* unsupported filter chain, or trying to change
* the filter chain in the middle of a Block
* @throws UnsupportedOptionsException unsupported filter chain, or trying
* to change the filter chain in the middle of a Block
*/
public void updateFilters(FilterOptions filterOptions)
throws XZIOException {
@@ -194,17 +183,15 @@ public class XZOutputStream extends FinishableOutputStream {
/**
* Updates the filter chain with 1-4 filters.
* <p>
* Currently this cannot be used to update e.g. LZMA2 options in the
* middle of a XZ Block. Use <code>endBlock()</code> to finish the
* current XZ Block before calling this function. The new filter chain
* will then be used for the next XZ Block.
* Currently this cannot be used to update e.g. LZMA2 options in the middle
* of a XZ Block. Use <code>endBlock()</code> to finish the current XZ Block
* before calling this function. The new filter chain will then be used for
* the next XZ Block.
*
* @param filterOptions
* new filter chain to use
* @param filterOptions new filter chain to use
*
* @throws UnsupportedOptionsException
* unsupported filter chain, or trying to change
* the filter chain in the middle of a Block
* @throws UnsupportedOptionsException unsupported filter chain, or trying
* to change the filter chain in the middle of a Block
*/
public void updateFilters(FilterOptions[] filterOptions)
throws XZIOException {
@@ -230,12 +217,10 @@ public class XZOutputStream extends FinishableOutputStream {
/**
* Writes one byte to be compressed.
*
* @throws XZIOException
* XZ Stream has grown too big
* @throws XZIOException XZ Stream has grown too big
*
* @throws XZIOException
* <code>finish()</code> or <code>close()</code>
* was already called
* @throws XZIOException <code>finish()</code> or <code>close()</code> was
* already called
*
* @throws IOException may be thrown by the underlying output stream
*/
@@ -245,26 +230,22 @@ public class XZOutputStream extends FinishableOutputStream {
}
/**
* Writes an array of bytes to be compressed.
* The compressors tend to do internal buffering and thus the written
* data won't be readable from the compressed output immediately.
* Use <code>flush()</code> to force everything written so far to
* be written to the underlaying output stream, but be aware that
* flushing reduces compression ratio.
* Writes an array of bytes to be compressed. The compressors tend to do
* internal buffering and thus the written data won't be readable from the
* compressed output immediately. Use <code>flush()</code> to force
* everything written so far to be written to the underlaying output stream,
* but be aware that flushing reduces compression ratio.
*
* @param buf buffer of bytes to be written
* @param off start offset in <code>buf</code>
* @param len number of bytes to write
*
* @throws XZIOException
* XZ Stream has grown too big: total file size
* about 8&nbsp;EiB or the Index field exceeds
* 16&nbsp;GiB; you shouldn't reach these sizes
* in practice
* @throws XZIOException XZ Stream has grown too big: total file size about
* 8&nbsp;EiB or the Index field exceeds 16&nbsp;GiB; you shouldn't reach
* these sizes in practice
*
* @throws XZIOException
* <code>finish()</code> or <code>close()</code>
* was already called and len &gt; 0
* @throws XZIOException <code>finish()</code> or <code>close()</code> was
* already called and len &gt; 0
*
* @throws IOException may be thrown by the underlying output stream
*/
@@ -290,27 +271,25 @@ public class XZOutputStream extends FinishableOutputStream {
}
/**
* Finishes the current XZ Block (but not the whole XZ Stream).
* This doesn't flush the stream so it's possible that not all data will
* be decompressible from the output stream when this function returns.
* Call also <code>flush()</code> if flushing is wanted in addition to
* finishing the current XZ Block.
* Finishes the current XZ Block (but not the whole XZ Stream). This doesn't
* flush the stream so it's possible that not all data will be
* decompressible from the output stream when this function returns. Call
* also <code>flush()</code> if flushing is wanted in addition to finishing
* the current XZ Block.
* <p>
* If there is no unfinished Block open, this function will do nothing.
* (No empty XZ Block will be created.)
* If there is no unfinished Block open, this function will do nothing. (No
* empty XZ Block will be created.)
* <p>
* This function can be useful, for example, to create
* random-accessible .xz files.
* This function can be useful, for example, to create random-accessible .xz
* files.
* <p>
* Starting a new XZ Block means that the encoder state is reset.
* Doing this very often will increase the size of the compressed
* file a lot (more than plain <code>flush()</code> would do).
* Starting a new XZ Block means that the encoder state is reset. Doing this
* very often will increase the size of the compressed file a lot (more than
* plain <code>flush()</code> would do).
*
* @throws XZIOException
* XZ Stream has grown too big
* @throws XZIOException XZ Stream has grown too big
*
* @throws XZIOException
* stream finished or closed
* @throws XZIOException stream finished or closed
*
* @throws IOException may be thrown by the underlying output stream
*/
@@ -337,24 +316,21 @@ public class XZOutputStream extends FinishableOutputStream {
}
/**
* Flushes the encoder and calls <code>out.flush()</code>.
* All buffered pending data will then be decompressible from
* the output stream.
* Flushes the encoder and calls <code>out.flush()</code>. All buffered
* pending data will then be decompressible from the output stream.
* <p>
* Calling this function very often may increase the compressed
* file size a lot. The filter chain options may affect the size
* increase too. For example, with LZMA2 the HC4 match finder has
* smaller penalty with flushing than BT4.
* Calling this function very often may increase the compressed file size a
* lot. The filter chain options may affect the size increase too. For
* example, with LZMA2 the HC4 match finder has smaller penalty with
* flushing than BT4.
* <p>
* Some filters don't support flushing. If the filter chain has
* such a filter, <code>flush()</code> will call <code>endBlock()</code>
* before flushing.
* Some filters don't support flushing. If the filter chain has such a
* filter, <code>flush()</code> will call <code>endBlock()</code> before
* flushing.
*
* @throws XZIOException
* XZ Stream has grown too big
* @throws XZIOException XZ Stream has grown too big
*
* @throws XZIOException
* stream finished or closed
* @throws XZIOException stream finished or closed
*
* @throws IOException may be thrown by the underlying output stream
*/
@@ -384,20 +360,19 @@ public class XZOutputStream extends FinishableOutputStream {
}
/**
* Finishes compression without closing the underlying stream.
* No more data can be written to this stream after finishing
* (calling <code>write</code> with an empty buffer is OK).
* Finishes compression without closing the underlying stream. No more data
* can be written to this stream after finishing (calling <code>write</code>
* with an empty buffer is OK).
* <p>
* Repeated calls to <code>finish()</code> do nothing unless
* an exception was thrown by this stream earlier. In that case
* the same exception is thrown again.
* Repeated calls to <code>finish()</code> do nothing unless an exception
* was thrown by this stream earlier. In that case the same exception is
* thrown again.
* <p>
* After finishing, the stream may be closed normally with
* <code>close()</code>. If the stream will be closed anyway, there
* usually is no need to call <code>finish()</code> separately.
* <code>close()</code>. If the stream will be closed anyway, there usually
* is no need to call <code>finish()</code> separately.
*
* @throws XZIOException
* XZ Stream has grown too big
* @throws XZIOException XZ Stream has grown too big
*
* @throws IOException may be thrown by the underlying output stream
*/
@@ -423,14 +398,13 @@ public class XZOutputStream extends FinishableOutputStream {
}
/**
* Finishes compression and closes the underlying stream.
* The underlying stream <code>out</code> is closed even if finishing
* fails. If both finishing and closing fail, the exception thrown
* by <code>finish()</code> is thrown and the exception from the failed
* <code>out.close()</code> is lost.
* Finishes compression and closes the underlying stream. The underlying
* stream <code>out</code> is closed even if finishing fails. If both
* finishing and closing fail, the exception thrown by <code>finish()</code>
* is thrown and the exception from the failed <code>out.close()</code> is
* lost.
*
* @throws XZIOException
* XZ Stream has grown too big
* @throws XZIOException XZ Stream has grown too big
*
* @throws IOException may be thrown by the underlying output stream
*/

View File

@@ -23,10 +23,10 @@ public class CRC32 extends Check {
public byte[] finish() {
long value = state.getValue();
byte[] buf = {(byte) (value),
byte[] buf = { (byte) (value),
(byte) (value >>> 8),
(byte) (value >>> 16),
(byte) (value >>> 24)};
(byte) (value >>> 24) };
state.reset();
return buf;
}

View File

@@ -28,8 +28,8 @@ final class HC4 extends LZEncoder {
}
/**
* Creates a new LZEncoder with the HC4 match finder.
* See <code>LZEncoder.getInstance</code> for parameter descriptions.
* Creates a new LZEncoder with the HC4 match finder. See
* <code>LZEncoder.getInstance</code> for parameter descriptions.
*/
HC4(int dictSize, int beforeSizeMin, int readAheadMax,
int niceLen, int matchLenMax, int depthLimit) {
@@ -54,8 +54,8 @@ final class HC4 extends LZEncoder {
}
/**
* Moves to the next byte, checks that there is enough available space,
* and possibly normalizes the hash tables and the hash chain.
* Moves to the next byte, checks that there is enough available space, and
* possibly normalizes the hash tables and the hash chain.
*
* @return number of bytes available, including the current byte
*/

View File

@@ -18,16 +18,16 @@ public abstract class LZEncoder {
public static final int MF_BT4 = 0x14;
/**
* Number of bytes to keep available before the current byte
* when moving the LZ window.
* Number of bytes to keep available before the current byte when moving the
* LZ window.
*/
private final int keepSizeBefore;
/**
* Number of bytes that must be available, the current byte included,
* to make hasEnoughData return true. Flushing and finishing are
* naturally exceptions to this since there cannot be any data after
* the end of the uncompressed input.
* Number of bytes that must be available, the current byte included, to
* make hasEnoughData return true. Flushing and finishing are naturally
* exceptions to this since there cannot be any data after the end of the
* uncompressed input.
*/
private final int keepSizeAfter;
@@ -63,8 +63,8 @@ public abstract class LZEncoder {
}
/**
* Gets approximate memory usage of the LZEncoder base structure and
* the match finder as kibibytes.
* Gets approximate memory usage of the LZEncoder base structure and the
* match finder as kibibytes.
*/
public static int getMemoryUsage(
int dictSize, int extraSizeBefore, int extraSizeAfter,
@@ -94,17 +94,15 @@ public abstract class LZEncoder {
* <p>
* @param dictSize dictionary size
*
* @param extraSizeBefore
* number of bytes to keep available in the
* history in addition to dictSize
* @param extraSizeBefore number of bytes to keep available in the history
* in addition to dictSize
*
* @param extraSizeAfter
* number of bytes that must be available
* after current position + matchLenMax
* @param extraSizeAfter number of bytes that must be available after
* current position + matchLenMax
*
* @param niceLen if a match of at least <code>niceLen</code>
* bytes is found, be happy with it and don't
* stop looking for longer matches
* @param niceLen if a match of at least <code>niceLen</code> bytes
* is
* found, be happy with it and don't stop looking for longer matches
*
* @param matchLenMax don't test for matches longer than
* <code>matchLenMax</code> bytes
@@ -145,9 +143,9 @@ public abstract class LZEncoder {
}
/**
* Sets a preset dictionary. If a preset dictionary is wanted, this
* function must be called immediately after creating the LZEncoder
* before any data has been encoded.
* Sets a preset dictionary. If a preset dictionary is wanted, this function
* must be called immediately after creating the LZEncoder before any data
* has been encoded.
*/
public void setPresetDict(int dictSize, byte[] presetDict) {
assert !isStarted();
@@ -165,8 +163,8 @@ public abstract class LZEncoder {
}
/**
* Moves data from the end of the buffer to the beginning, discarding
* old data and making space for new input.
* Moves data from the end of the buffer to the beginning, discarding old
* data and making space for new input.
*/
private void moveWindow() {
// Align the move to a multiple of 16 bytes. LZMA2 needs this
@@ -212,8 +210,8 @@ public abstract class LZEncoder {
}
/**
* Process pending bytes remaining from preset dictionary initialization
* or encoder flush operation.
* Process pending bytes remaining from preset dictionary initialization or
* encoder flush operation.
*/
private void processPendingBytes() {
// After flushing or setting a preset dictionary there will be
@@ -234,16 +232,16 @@ public abstract class LZEncoder {
}
/**
* Returns true if at least one byte has already been run through
* the match finder.
* Returns true if at least one byte has already been run through the match
* finder.
*/
public boolean isStarted() {
return readPos != -1;
}
/**
* Marks that all the input needs to be made available in
* the encoded output.
* Marks that all the input needs to be made available in the encoded
* output.
*/
public void setFlushing() {
readLimit = writePos - 1;
@@ -251,8 +249,8 @@ public abstract class LZEncoder {
}
/**
* Marks that there is no more input remaining. The read position
* can be advanced until the end of the data.
* Marks that there is no more input remaining. The read position can be
* advanced until the end of the data.
*/
public void setFinishing() {
readLimit = writePos - 1;
@@ -261,8 +259,8 @@ public abstract class LZEncoder {
}
/**
* Tests if there is enough input available to let the caller encode
* at least one more byte.
* Tests if there is enough input available to let the caller encode at
* least one more byte.
*/
public boolean hasEnoughData(int alreadyReadLen) {
return readPos - alreadyReadLen < readLimit;
@@ -277,8 +275,8 @@ public abstract class LZEncoder {
* Get the number of bytes available, including the current byte.
* <p>
* Note that the result is undefined if <code>getMatches</code> or
* <code>skip</code> hasn't been called yet and no preset dictionary
* is being used.
* <code>skip</code> hasn't been called yet and no preset dictionary is
* being used.
*/
public int getAvail() {
assert isStarted();
@@ -296,9 +294,8 @@ public abstract class LZEncoder {
/**
* Gets the byte from the given backward offset.
* <p>
* The current byte is at <code>0</code>, the previous byte
* at <code>1</code> etc. To get a byte at zero-based distance,
* use <code>getByte(dist + 1)<code>.
* The current byte is at <code>0</code>, the previous byte at
* <code>1</code> etc. To get a byte at zero-based distance, use <code>getByte(dist + 1)<code>.
* <p>
* This function is equivalent to <code>getByte(0, backward)</code>.
*/
@@ -307,9 +304,9 @@ public abstract class LZEncoder {
}
/**
* Gets the byte from the given forward minus backward offset.
* The forward offset is added to the current position. This lets
* one read bytes ahead of the current byte.
* Gets the byte from the given forward minus backward offset. The forward
* offset is added to the current position. This lets one read bytes ahead
* of the current byte.
*/
public int getByte(int forward, int backward) {
return buf[readPos + forward - backward] & 0xFF;
@@ -354,10 +351,10 @@ public abstract class LZEncoder {
}
/**
* Verifies that the matches returned by the match finder are valid.
* This is meant to be used in an assert statement. This is totally
* useless for actual encoding since match finder's results should
* naturally always be valid if it isn't broken.
* Verifies that the matches returned by the match finder are valid. This is
* meant to be used in an assert statement. This is totally useless for
* actual encoding since match finder's results should naturally always be
* valid if it isn't broken.
*
* @param matches return value from <code>getMatches</code>
*
@@ -374,21 +371,17 @@ public abstract class LZEncoder {
}
/**
* Moves to the next byte, checks if there is enough input available,
* and returns the amount of input available.
* Moves to the next byte, checks if there is enough input available, and
* returns the amount of input available.
*
* @param requiredForFlushing
* minimum number of available bytes when
* flushing; encoding may be continued with
* new input after flushing
* @param requiredForFinishing
* minimum number of available bytes when
* finishing; encoding must not be continued
* after finishing or the match finder state
* may be corrupt
* @param requiredForFlushing minimum number of available bytes when
* flushing; encoding may be continued with new input after flushing
* @param requiredForFinishing minimum number of available bytes when
* finishing; encoding must not be continued after finishing or the match
* finder state may be corrupt
*
* @return the number of bytes available or zero if there
* is not enough input available
* @return the number of bytes available or zero if there is not enough
* input available
*/
int movePos(int requiredForFlushing, int requiredForFinishing) {
assert requiredForFlushing >= requiredForFinishing;

View File

@@ -44,11 +44,11 @@ abstract class LZMACoder {
final short[] isRep2 = new short[State.STATES];
final short[][] isRep0Long = new short[State.STATES][POS_STATES_MAX];
final short[][] distSlots = new short[DIST_STATES][DIST_SLOTS];
final short[][] distSpecial = {new short[2], new short[2],
final short[][] distSpecial = { new short[2], new short[2],
new short[4], new short[4],
new short[8], new short[8],
new short[16], new short[16],
new short[32], new short[32]};
new short[32], new short[32] };
final short[] distAlign = new short[ALIGN_SIZE];
static final int getDistState(int len) {

View File

@@ -37,10 +37,10 @@ public final class LZMADecoder extends LZMACoder {
}
/**
* Returns true if LZMA end marker was detected. It is encoded as
* the maximum match distance which with signed ints becomes -1. This
* function is needed only for LZMA1. LZMA2 doesn't use the end marker
* in the LZMA layer.
* Returns true if LZMA end marker was detected. It is encoded as the
* maximum match distance which with signed ints becomes -1. This function
* is needed only for LZMA1. LZMA2 doesn't use the end marker in the LZMA
* layer.
*/
public boolean endMarkerDetected() {
return reps[0] == -1;

View File

@@ -22,10 +22,10 @@ public abstract class LZMAEncoder extends LZMACoder {
* LZMA2 chunk is considered full when its uncompressed size exceeds
* <code>LZMA2_UNCOMPRESSED_LIMIT</code>.
* <p>
* A compressed LZMA2 chunk can hold 2 MiB of uncompressed data.
* A single LZMA symbol may indicate up to MATCH_LEN_MAX bytes
* of data, so the LZMA2 chunk is considered full when there is
* less space than MATCH_LEN_MAX bytes.
* A compressed LZMA2 chunk can hold 2 MiB of uncompressed data. A single
* LZMA symbol may indicate up to MATCH_LEN_MAX bytes of data, so the LZMA2
* chunk is considered full when there is less space than MATCH_LEN_MAX
* bytes.
*/
private static final int LZMA2_UNCOMPRESSED_LIMIT
= (2 << 20) - MATCH_LEN_MAX;
@@ -34,11 +34,11 @@ public abstract class LZMAEncoder extends LZMACoder {
* LZMA2 chunk is considered full when its compressed size exceeds
* <code>LZMA2_COMPRESSED_LIMIT</code>.
* <p>
* The maximum compressed size of a LZMA2 chunk is 64 KiB.
* A single LZMA symbol might use 20 bytes of space even though
* it usually takes just one byte or so. Two more bytes are needed
* for LZMA2 uncompressed chunks (see LZMA2OutputStream.writeChunk).
* Leave a little safety margin and use 26 bytes.
* The maximum compressed size of a LZMA2 chunk is 64 KiB. A single LZMA
* symbol might use 20 bytes of space even though it usually takes just one
* byte or so. Two more bytes are needed for LZMA2 uncompressed chunks (see
* LZMA2OutputStream.writeChunk). Leave a little safety margin and use 26
* bytes.
*/
private static final int LZMA2_COMPRESSED_LIMIT = (64 << 10) - 26;
@@ -107,9 +107,9 @@ public abstract class LZMAEncoder extends LZMACoder {
}
/**
* Gets an integer [0, 63] matching the highest two bits of an integer.
* This is like bit scan reverse (BSR) on x86 except that this also
* cares about the second highest bit.
* Gets an integer [0, 63] matching the highest two bits of an integer. This
* is like bit scan reverse (BSR) on x86 except that this also cares about
* the second highest bit.
*/
public static int getDistSlot(int dist) {
if (dist <= DIST_MODEL_START)
@@ -147,19 +147,18 @@ public abstract class LZMAEncoder extends LZMACoder {
/**
* Gets the next LZMA symbol.
* <p>
* There are three types of symbols: literal (a single byte),
* repeated match, and normal match. The symbol is indicated
* by the return value and by the variable <code>back</code>.
* There are three types of symbols: literal (a single byte), repeated
* match, and normal match. The symbol is indicated by the return value and
* by the variable <code>back</code>.
* <p>
* Literal: <code>back == -1</code> and return value is <code>1</code>.
* The literal itself needs to be read from <code>lz</code> separately.
* Literal: <code>back == -1</code> and return value is <code>1</code>. The
* literal itself needs to be read from <code>lz</code> separately.
* <p>
* Repeated match: <code>back</code> is in the range [0, 3] and
* the return value is the length of the repeated match.
* Repeated match: <code>back</code> is in the range [0, 3] and the return
* value is the length of the repeated match.
* <p>
* Normal match: <code>back - REPS<code> (<code>back - 4</code>)
* is the distance of the match and the return value is the length
* of the match.
* Normal match: <code>back - REPS<code> (<code>back - 4</code>) is the
* distance of the match and the return value is the length of the match.
*/
abstract int getNextSymbol();
@@ -477,9 +476,9 @@ public abstract class LZMAEncoder extends LZMACoder {
}
/**
* Updates the lookup tables used for calculating match distance
* and length prices. The updating is skipped for performance reasons
* if the tables haven't changed much since the previous update.
* Updates the lookup tables used for calculating match distance and length
* prices. The updating is skipped for performance reasons if the tables
* haven't changed much since the previous update.
*/
void updatePrices() {
if (distPriceCount <= 0)
@@ -621,8 +620,8 @@ public abstract class LZMAEncoder extends LZMACoder {
/**
* The prices are updated after at least
* <code>PRICE_UPDATE_INTERVAL</code> many lengths
* have been encoded with the same posState.
* <code>PRICE_UPDATE_INTERVAL</code> many lengths have been encoded
* with the same posState.
*/
private static final int PRICE_UPDATE_INTERVAL = 32; // FIXME?

View File

@@ -60,9 +60,9 @@ final class LZMAEncoderNormal extends LZMAEncoder {
}
/**
* Converts the opts array from backward indexes to forward indexes.
* Then it will be simple to get the next symbol from the array
* in later calls to <code>getNextSymbol()</code>.
* Converts the opts array from backward indexes to forward indexes. Then it
* will be simple to get the next symbol from the array in later calls to
* <code>getNextSymbol()</code>.
*/
private int convertOpts() {
optEnd = optCur;

View File

@@ -58,8 +58,7 @@ final class Optimum {
}
/**
* Sets to indicate three LZMA symbols of which the second one
* is a literal.
* Sets to indicate three LZMA symbols of which the second one is a literal.
*/
void set3(int newPrice, int optCur, int back2, int len2, int back) {
price = newPrice;

View File

@@ -3,14 +3,14 @@
*
* <h4>Introduction</h4>
* <p>
* This aims to be a complete implementation of XZ data compression
* in pure Java. Features:
* This aims to be a complete implementation of XZ data compression in pure
* Java. Features:
* <ul>
* <li>Full support for the .xz file format specification version 1.0.4</li>
* <li>Single-threaded streamed compression and decompression</li>
* <li>Single-threaded decompression with limited random access support</li>
* <li>Raw streams (no .xz headers) for advanced users, including LZMA2
* with preset dictionary</li>
* <li>Raw streams (no .xz headers) for advanced users, including LZMA2 with
* preset dictionary</li>
* </ul>
* <p>
* Threading is planned but it is unknown when it will be implemented.
@@ -21,15 +21,14 @@
* <h4>Getting started</h4>
* <p>
* Start by reading the documentation of {@link org.tukaani.xz.XZOutputStream}
* and {@link org.tukaani.xz.XZInputStream}.
* If you use XZ inside another file format or protocol,
* see also {@link org.tukaani.xz.SingleXZInputStream}.
* and {@link org.tukaani.xz.XZInputStream}. If you use XZ inside another file
* format or protocol, see also {@link org.tukaani.xz.SingleXZInputStream}.
*
* <h4>Licensing</h4>
* <p>
* XZ for Java has been put into the public domain, thus you can do
* whatever you want with it. All the files in the package have been
* written by Lasse Collin and/or Igor Pavlov.
* XZ for Java has been put into the public domain, thus you can do whatever you
* want with it. All the files in the package have been written by Lasse Collin
* and/or Igor Pavlov.
* <p>
* This software is provided "as is", without any warranty.
*/

View File

@@ -15,7 +15,7 @@ public final class IA64 implements SimpleFilter {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
4, 4, 6, 6, 0, 0, 7, 7,
4, 4, 0, 0, 4, 4, 0, 0};
4, 4, 0, 0, 4, 4, 0, 0 };
private final boolean isEncoder;
private int pos;

View File

@@ -12,9 +12,9 @@ package org.tukaani.xz.simple;
public final class X86 implements SimpleFilter {
private static final boolean[] MASK_TO_ALLOWED_STATUS
= {true, true, true, false, true, false, false, false};
= { true, true, true, false, true, false, false, false };
private static final int[] MASK_TO_BIT_NUMBER = {0, 1, 2, 2, 3, 3, 3, 3};
private static final int[] MASK_TO_BIT_NUMBER = { 0, 1, 2, 2, 3, 3, 3, 3 };
private final boolean isEncoder;
private int pos;

File diff suppressed because it is too large Load Diff

View File

@@ -18,27 +18,35 @@ package rx;
/**
* Provides a mechanism for receiving push-based notifications.
* <p>
* After an Observer calls an {@link Observable}'s <code>Observable.subscribe</code> method, the {@link Observable} calls the Observer's <code>onNext</code> method to provide notifications. A
* well-behaved {@link Observable} will
* call an Observer's <code>onCompleted</code> closure exactly once or the Observer's <code>onError</code> closure exactly once.
* After an Observer calls an {@link Observable}'s
* <code>Observable.subscribe</code> method, the {@link Observable} calls the
* Observer's <code>onNext</code> method to provide notifications. A
* well-behaved {@link Observable} will call an Observer's
* <code>onCompleted</code> closure exactly once or the Observer's
* <code>onError</code> closure exactly once.
* <p>
* For more information see the <a href="https://github.com/Netflix/RxJava/wiki/Observable">RxJava Wiki</a>
* For more information see the
* <a href="https://github.com/Netflix/RxJava/wiki/Observable">RxJava Wiki</a>
*
* @param <T>
*/
public interface Observer<T> {
/**
* Notifies the Observer that the {@link Observable} has finished sending push-based notifications.
* Notifies the Observer that the {@link Observable} has finished sending
* push-based notifications.
* <p>
* The {@link Observable} will not call this closure if it calls <code>onError</code>.
* The {@link Observable} will not call this closure if it calls
* <code>onError</code>.
*/
public void onCompleted();
/**
* Notifies the Observer that the {@link Observable} has experienced an error condition.
* Notifies the Observer that the {@link Observable} has experienced an
* error condition.
* <p>
* If the {@link Observable} calls this closure, it will not thereafter call <code>onNext</code> or <code>onCompleted</code>.
* If the {@link Observable} calls this closure, it will not thereafter call
* <code>onNext</code> or <code>onCompleted</code>.
*
* @param e
*/
@@ -47,9 +55,12 @@ public interface Observer<T> {
/**
* Provides the Observer with new data.
* <p>
* The {@link Observable} calls this closure 1 or more times, unless it calls <code>onError</code> in which case this closure may never be called.
* The {@link Observable} calls this closure 1 or more times, unless it
* calls <code>onError</code> in which case this closure may never be
* called.
* <p>
* The {@link Observable} will not call this closure again after it calls either <code>onCompleted</code> or <code>onError</code>.
* The {@link Observable} will not call this closure again after it calls
* either <code>onCompleted</code> or <code>onError</code>.
*
* @param args
*/

View File

@@ -28,8 +28,8 @@ public interface Scheduler {
/**
* Schedules a cancelable action to be executed.
*
* @param action
* action
* @param action action
*
* @return a subscription to be able to unsubscribe from action.
*/
Subscription schedule(Func0<Subscription> action);
@@ -37,8 +37,8 @@ public interface Scheduler {
/**
* Schedules an action to be executed.
*
* @param action
* action
* @param action action
*
* @return a subscription to be able to unsubscribe from action.
*/
Subscription schedule(Action0 action);
@@ -46,8 +46,8 @@ public interface Scheduler {
/**
* Schedules an action to be executed in dueTime.
*
* @param action
* action
* @param action action
*
* @return a subscription to be able to unsubscribe from action.
*/
Subscription schedule(Action0 action, long dueTime, TimeUnit unit);
@@ -55,8 +55,8 @@ public interface Scheduler {
/**
* Schedules a cancelable action to be executed in dueTime.
*
* @param action
* action
* @param action action
*
* @return a subscription to be able to unsubscribe from action.
*/
Subscription schedule(Func0<Subscription> action, long dueTime, TimeUnit unit);

View File

@@ -18,16 +18,20 @@ package rx;
import rx.subscriptions.Subscriptions;
/**
* Subscription returns from {@link Observable#subscribe(Observer)} to allow unsubscribing.
* Subscription returns from {@link Observable#subscribe(Observer)} to allow
* unsubscribing.
* <p>
* See utilities in {@link Subscriptions} and implementations in the {@link rx.subscriptions} package.
* See utilities in {@link Subscriptions} and implementations in the
* {@link rx.subscriptions} package.
*/
public interface Subscription {
/**
* Stop receiving notifications on the {@link Observer} that was registered when this Subscription was received.
* Stop receiving notifications on the {@link Observer} that was registered
* when this Subscription was received.
* <p>
* This allows unregistering an {@link Observer} before it has finished receiving all events (ie. before onCompleted is called).
* This allows unregistering an {@link Observer} before it has finished
* receiving all events (ie. before onCompleted is called).
*/
public void unsubscribe();

View File

@@ -23,7 +23,9 @@ import rx.subscriptions.Subscriptions;
import rx.util.functions.Action0;
import rx.util.functions.Func0;
/* package */
/*
* package
*/
abstract class AbstractScheduler implements Scheduler {
@Override

View File

@@ -23,9 +23,11 @@ import rx.Subscription;
import rx.util.functions.Func0;
/**
* Schedules work on the current thread but does not execute immediately. Work is put in a queue and executed after the current unit of work is completed.
* Schedules work on the current thread but does not execute immediately. Work
* is put in a queue and executed after the current unit of work is completed.
*/
public class CurrentThreadScheduler extends AbstractScheduler {
private static final CurrentThreadScheduler INSTANCE = new CurrentThreadScheduler();
public static CurrentThreadScheduler getInstance() {
@@ -61,9 +63,8 @@ public class CurrentThreadScheduler extends AbstractScheduler {
queue.add(action);
if (exec) {
while (!queue.isEmpty()) {
while (!queue.isEmpty())
queue.poll().call();
}
QUEUE.set(null);
}

View File

@@ -22,9 +22,15 @@ import rx.util.AtomicObservableSubscription;
import rx.util.functions.Func0;
/**
* Combines standard {@link Subscription#unsubscribe()} functionality with ability to skip execution if an unsubscribe occurs before the {@link #call()} method is invoked.
* Combines standard {@link Subscription#unsubscribe()} functionality with
* ability to skip execution if an unsubscribe occurs before the {@link #call()}
* method is invoked.
*/
/* package */class DiscardableAction implements Func0<Subscription>, Subscription {
/*
* package
*/
class DiscardableAction implements Func0<Subscription>, Subscription {
private final Func0<Subscription> underlying;
private final AtomicObservableSubscription wrapper = new AtomicObservableSubscription();

View File

@@ -27,6 +27,7 @@ import rx.util.functions.Func0;
* @author huangyuhui
*/
public class EventQueueScheduler extends AbstractScheduler {
private static final EventQueueScheduler INSTANCE = new EventQueueScheduler();
public static EventQueueScheduler getInstance() {

View File

@@ -24,6 +24,7 @@ import rx.util.functions.Func0;
* Executes work immediately on the current thread.
*/
public final class ImmediateScheduler extends AbstractScheduler {
private static final ImmediateScheduler INSTANCE = new ImmediateScheduler();
public static ImmediateScheduler getInstance() {

View File

@@ -24,6 +24,7 @@ import rx.util.functions.Func0;
* Schedules work on a new thread.
*/
public class NewThreadScheduler extends AbstractScheduler {
private static final NewThreadScheduler INSTANCE = new NewThreadScheduler();
public static NewThreadScheduler getInstance() {

View File

@@ -28,6 +28,7 @@ import rx.Scheduler;
* Static factory methods for creating Schedulers.
*/
public class Schedulers {
private static final ScheduledExecutorService COMPUTATION_EXECUTOR = createComputationExecutor();
private static final Executor IO_EXECUTOR = createIOExecutor();
@@ -45,7 +46,8 @@ public class Schedulers {
}
/**
* {@link Scheduler} that queues work on the current thread to be executed after the current work completes.
* {@link Scheduler} that queues work on the current thread to be executed
* after the current work completes.
*
* @return {@link CurrentThreadScheduler} instance
*/
@@ -54,7 +56,8 @@ public class Schedulers {
}
/**
* {@link Scheduler} that creates a new {@link Thread} for each unit of work.
* {@link Scheduler} that creates a new {@link Thread} for each unit of
* work.
*
* @return {@link NewThreadScheduler} instance
*/
@@ -63,7 +66,8 @@ public class Schedulers {
}
/**
* {@link Scheduler} that queues work on the EventQueue thread to be executed on the Swing UI Thread.
* {@link Scheduler} that queues work on the EventQueue thread to be
* executed on the Swing UI Thread.
*
* @return {@link NewThreadScheduler} instance
*/
@@ -83,7 +87,8 @@ public class Schedulers {
}
/**
* {@link Scheduler} that queues work on an {@link ScheduledExecutorService}.
* {@link Scheduler} that queues work on an
* {@link ScheduledExecutorService}.
*
* @return {@link ExecutorScheduler} instance
*/
@@ -94,11 +99,14 @@ public class Schedulers {
/**
* {@link Scheduler} intended for computational work.
* <p>
* The implementation is backed by a {@link ScheduledExecutorService} thread-pool sized to the number of CPU cores.
* The implementation is backed by a {@link ScheduledExecutorService}
* thread-pool sized to the number of CPU cores.
* <p>
* This can be used for event-loops, processing callbacks and other computational work.
* This can be used for event-loops, processing callbacks and other
* computational work.
* <p>
* Do not perform IO-bound work on this scheduler. Use {@link #threadPoolForComputation()} instead.
* Do not perform IO-bound work on this scheduler. Use
* {@link #threadPoolForComputation()} instead.
*
* @return {@link ExecutorScheduler} for computation-bound work.
*/
@@ -109,11 +117,13 @@ public class Schedulers {
/**
* {@link Scheduler} intended for IO-bound work.
* <p>
* The implementation is backed by an {@link Executor} thread-pool that will grow as needed.
* The implementation is backed by an {@link Executor} thread-pool that will
* grow as needed.
* <p>
* This can be used for asynchronously performing blocking IO.
* <p>
* Do not perform computational work on this scheduler. Use {@link #threadPoolForComputation()} instead.
* Do not perform computational work on this scheduler. Use
* {@link #threadPoolForComputation()} instead.
*
* @return {@link ExecutorScheduler} for IO-bound work.
*/

View File

@@ -21,7 +21,11 @@ import rx.Scheduler;
import rx.Subscription;
import rx.util.functions.Func0;
/* package */class SleepingAction implements Func0<Subscription> {
/*
* package
*/
class SleepingAction implements Func0<Subscription> {
private final Func0<Subscription> underlying;
private final Scheduler scheduler;
private final long execTime;
@@ -34,14 +38,13 @@ import rx.util.functions.Func0;
@Override
public Subscription call() {
if (execTime < scheduler.now()) {
if (execTime < scheduler.now())
try {
Thread.sleep(scheduler.now() - execTime);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException(e);
}
}
return underlying.call();

View File

@@ -21,7 +21,9 @@ import rx.Subscription;
import rx.util.functions.Func1;
/**
* An {@link Observable} that has been grouped by a key whose value can be obtained using {@link #getKey()} <p>
* An {@link Observable} that has been grouped by a key whose value can be
* obtained using {@link #getKey()}
* <p>
*
* @see {@link Observable#groupBy(Observable, Func1)}
*
@@ -29,6 +31,7 @@ import rx.util.functions.Func1;
* @param <T>
*/
public class GroupedObservable<K, T> extends Observable<T> {
private final K key;
public GroupedObservable(K key, Func1<Observer<T>, Subscription> onSubscribe) {

View File

@@ -15,19 +15,18 @@ public class OperationAll {
}
private static class AllObservable<T> implements Func1<Observer<Boolean>, Subscription> {
private final Observable<T> sequence;
private final Func1<T, Boolean> predicate;
private final AtomicBoolean status = new AtomicBoolean(true);
private final AtomicObservableSubscription subscription = new AtomicObservableSubscription();
private AllObservable(Observable<T> sequence, Func1<T, Boolean> predicate) {
this.sequence = sequence;
this.predicate = predicate;
}
@Override
public Subscription call(final Observer<Boolean> observer) {
return subscription.wrap(sequence.subscribe(new Observer<T>() {

View File

@@ -36,12 +36,18 @@ import rx.util.functions.Functions;
public class OperationCombineLatest {
/**
* Combines the two given observables, emitting an event containing an aggregation of the latest values of each of the source observables
* each time an event is received from one of the source observables, where the aggregation is defined by the given function.
* Combines the two given observables, emitting an event containing an
* aggregation of the latest values of each of the source observables each
* time an event is received from one of the source observables, where the
* aggregation is defined by the given function.
*
* @param w0 The first source observable.
* @param w1 The second source observable.
* @param combineLatestFunction The aggregation function used to combine the source observable values.
* @return A function from an observer to a subscription. This can be used to create an observable from.
* @param combineLatestFunction The aggregation function used to combine the
* source observable values.
*
* @return A function from an observer to a subscription. This can be used
* to create an observable from.
*/
public static <T0, T1, R> Func1<Observer<R>, Subscription> combineLatest(Observable<T0> w0, Observable<T1> w1, Func2<T0, T1, R> combineLatestFunction) {
Aggregator<R> a = new Aggregator<>(Functions.fromFunc(combineLatestFunction));
@@ -51,7 +57,8 @@ public class OperationCombineLatest {
}
/**
* @see #combineLatest(Observable w0, Observable w1, Func2 combineLatestFunction)
* @see #combineLatest(Observable w0, Observable w1, Func2
* combineLatestFunction)
*/
public static <T0, T1, T2, R> Func1<Observer<R>, Subscription> combineLatest(Observable<T0> w0, Observable<T1> w1, Observable<T2> w2, Func3<T0, T1, T2, R> combineLatestFunction) {
Aggregator<R> a = new Aggregator<>(Functions.fromFunc(combineLatestFunction));
@@ -62,7 +69,8 @@ public class OperationCombineLatest {
}
/**
* @see #combineLatest(Observable w0, Observable w1, Func2 combineLatestFunction)
* @see #combineLatest(Observable w0, Observable w1, Func2
* combineLatestFunction)
*/
public static <T0, T1, T2, T3, R> Func1<Observer<R>, Subscription> combineLatest(Observable<T0> w0, Observable<T1> w1, Observable<T2> w2, Observable<T3> w3, Func4<T0, T1, T2, T3, R> combineLatestFunction) {
Aggregator<R> a = new Aggregator<>(Functions.fromFunc(combineLatestFunction));
@@ -74,6 +82,7 @@ public class OperationCombineLatest {
}
private static class CombineObserver<R, T> implements Observer<T> {
final Observable<T> w;
final Aggregator<R> a;
private Subscription subscription;
@@ -84,9 +93,8 @@ public class OperationCombineLatest {
}
public synchronized void startWatching() {
if (subscription != null) {
if (subscription != null)
throw new RuntimeException("This should only be called once.");
}
subscription = w.subscribe(this);
}
@@ -107,9 +115,10 @@ public class OperationCombineLatest {
}
/**
* Receive notifications from each of the observables we are reducing and execute the combineLatestFunction
* whenever we have received an event from one of the observables, as soon as each Observable has received
* at least one event.
* Receive notifications from each of the observables we are reducing and
* execute the combineLatestFunction whenever we have received an event from
* one of the observables, as soon as each Observable has received at least
* one event.
*/
private static class Aggregator<R> implements Func1<Observer<R>, Subscription> {
@@ -124,27 +133,33 @@ public class OperationCombineLatest {
/**
* Store when an observer completes.
* <p>
* Note that access to this set MUST BE SYNCHRONIZED via 'lockObject' above.
* */
* Note that access to this set MUST BE SYNCHRONIZED via 'lockObject'
* above.
*
*/
private final Set<CombineObserver<R, ?>> completed = new HashSet<>();
/**
* The latest value from each observer
* <p>
* Note that access to this set MUST BE SYNCHRONIZED via 'lockObject' above.
* */
* Note that access to this set MUST BE SYNCHRONIZED via 'lockObject'
* above.
*
*/
private final Map<CombineObserver<R, ?>, Object> latestValue = new HashMap<>();
/**
* Whether each observer has a latest value at all.
* <p>
* Note that access to this set MUST BE SYNCHRONIZED via 'lockObject' above.
* */
* Note that access to this set MUST BE SYNCHRONIZED via 'lockObject'
* above.
*
*/
private final Set<CombineObserver<R, ?>> hasLatestValue = new HashSet<>();
/**
* Ordered list of observers to combine.
* No synchronization is necessary as these can not be added or changed asynchronously.
* Ordered list of observers to combine. No synchronization is necessary
* as these can not be added or changed asynchronously.
*/
private final List<CombineObserver<R, ?>> observers = new LinkedList<>();
@@ -153,7 +168,8 @@ public class OperationCombineLatest {
}
/**
* Receive notification of a Observer starting (meaning we should require it for aggregation)
* Receive notification of a Observer starting (meaning we should
* require it for aggregation)
*
* @param w The observer to add.
*/
@@ -167,11 +183,11 @@ public class OperationCombineLatest {
* @param w The observer that has completed.
*/
<T> void complete(CombineObserver<R, T> w) {
synchronized(lockObject) {
synchronized (lockObject) {
// store that this CombineLatestObserver is completed
completed.add(w);
// if all CombineObservers are completed, we mark the whole thing as completed
if (completed.size() == observers.size()) {
if (completed.size() == observers.size())
if (running.get()) {
// mark ourselves as done
observer.onCompleted();
@@ -180,34 +196,39 @@ public class OperationCombineLatest {
}
}
}
}
/**
* Receive error for a Observer. Throw the error up the chain and stop processing.
* Receive error for a Observer. Throw the error up the chain and stop
* processing.
*/
void error(Exception e) {
observer.onError(e);
/* tell all observers to unsubscribe since we had an error */
/*
* tell all observers to unsubscribe since we had an error
*/
stop();
}
/**
* Receive the next value from an observer.
* <p>
* If we have received values from all observers, trigger the combineLatest function, otherwise store the value and keep waiting.
* If we have received values from all observers, trigger the
* combineLatest function, otherwise store the value and keep waiting.
*
* @param w
* @param arg
*/
<T> void next(CombineObserver<R, T> w, T arg) {
if (observer == null) {
if (observer == null)
throw new RuntimeException("This shouldn't be running if an Observer isn't registered");
}
/* if we've been 'unsubscribed' don't process anything further even if the things we're watching keep sending (likely because they are not responding to the unsubscribe call) */
if (!running.get()) {
/*
* if we've been 'unsubscribed' don't process anything further even
* if the things we're watching keep sending (likely because they
* are not responding to the unsubscribe call)
*/
if (!running.get())
return;
}
// define here so the variable is out of the synchronized scope
Object[] argsToCombineLatest = new Object[observers.size()];
@@ -221,18 +242,15 @@ public class OperationCombineLatest {
hasLatestValue.add(w);
// if all observers in the 'observers' list have a value, invoke the combineLatestFunction
for (CombineObserver<R, ?> rw : observers) {
if (!hasLatestValue.contains(rw)) {
for (CombineObserver<R, ?> rw : observers)
if (!hasLatestValue.contains(rw))
// we don't have a value yet for each observer to combine, so we don't have a combined value yet either
return;
}
}
// if we get to here this means all the queues have data
int i = 0;
for (CombineObserver<R, ?> _w : observers) {
for (CombineObserver<R, ?> _w : observers)
argsToCombineLatest[i++] = latestValue.get(_w);
}
}
// if we did not return above from the synchronized block we can now invoke the combineLatestFunction with all of the args
// we do this outside the synchronized block as it is now safe to call this concurrently and don't need to block other threads from calling
// this 'next' method while another thread finishes calling this combineLatestFunction
@@ -241,15 +259,15 @@ public class OperationCombineLatest {
@Override
public Subscription call(Observer<R> observer) {
if (this.observer != null) {
if (this.observer != null)
throw new IllegalStateException("Only one Observer can subscribe to this Observable.");
}
this.observer = observer;
/* start the observers */
for (CombineObserver<R, ?> rw : observers) {
/*
* start the observers
*/
for (CombineObserver<R, ?> rw : observers)
rw.startWatching();
}
return new Subscription() {
@Override
@@ -260,14 +278,16 @@ public class OperationCombineLatest {
}
private void stop() {
/* tell ourselves to stop processing onNext events */
/*
* tell ourselves to stop processing onNext events
*/
running.set(false);
/* propogate to all observers to unsubscribe */
for (CombineObserver<R, ?> rw : observers) {
if (rw.subscription != null) {
/*
* propogate to all observers to unsubscribe
*/
for (CombineObserver<R, ?> rw : observers)
if (rw.subscription != null)
rw.subscription.unsubscribe();
}
}
}
}
}

View File

@@ -30,11 +30,13 @@ import rx.util.functions.Func1;
public final class OperationConcat {
/**
* Combine the observable sequences from the list of Observables into one observable sequence without any transformation.
* Combine the observable sequences from the list of Observables into one
* observable sequence without any transformation.
*
* @param sequences
* An observable sequence of elements to project.
* @return An observable sequence whose elements are the result of combining the output from the list of Observables.
* @param sequences An observable sequence of elements to project.
*
* @return An observable sequence whose elements are the result of combining
* the output from the list of Observables.
*/
public static <T> Func1<Observer<T>, Subscription> concat(final Observable<T>... sequences) {
return new Func1<Observer<T>, Subscription>() {
@@ -66,6 +68,7 @@ public final class OperationConcat {
}
private static class Concat<T> implements Func1<Observer<T>, Subscription> {
private final Observable<T>[] sequences;
private int num = 0;
private int count = 0;
@@ -94,6 +97,7 @@ public final class OperationConcat {
}
private class ConcatObserver implements Observer<T> {
private final Observer<T> observer;
ConcatObserver(Observer<T> observer) {

View File

@@ -22,17 +22,23 @@ import rx.Subscription;
import rx.util.functions.Func1;
/**
* Dematerializes the explicit notification values of an observable sequence as implicit notifications.
* See http://msdn.microsoft.com/en-us/library/hh229047(v=vs.103).aspx for the Microsoft Rx equivalent.
* Dematerializes the explicit notification values of an observable sequence as
* implicit notifications. See
* http://msdn.microsoft.com/en-us/library/hh229047(v=vs.103).aspx for the
* Microsoft Rx equivalent.
*/
public final class OperationDematerialize {
/**
* Dematerializes the explicit notification values of an observable sequence as implicit notifications.
* Dematerializes the explicit notification values of an observable sequence
* as implicit notifications.
*
* @param sequence An observable sequence containing explicit notification
* values which have to be turned into implicit notifications.
*
* @return An observable sequence exhibiting the behavior corresponding to
* the source sequence's notification values.
*
* @param sequence
* An observable sequence containing explicit notification values which have to be turned into implicit notifications.
* @return An observable sequence exhibiting the behavior corresponding to the source sequence's notification values.
* @see http://msdn.microsoft.com/en-us/library/hh229047(v=vs.103).aspx
*/
public static <T> Func1<Observer<T>, Subscription> dematerialize(final Observable<Notification<T>> sequence) {

View File

@@ -44,9 +44,8 @@ public final class OperationFilter<T> {
@Override
public void onNext(T value) {
try {
if (predicate.call(value)) {
if (predicate.call(value))
observer.onNext(value);
}
} catch (Exception ex) {
observer.onError(ex);
// this will work if the sequence is asynchronous, it will have no effect on a synchronous observable

View File

@@ -32,18 +32,24 @@ public final class OperationFinally {
* so we use "finallyDo".
*
* @param sequence An observable sequence of elements
* @param action An action to be taken when the sequence is complete or throws an exception
* @return An observable sequence with the same elements as the input.
* After the last element is consumed (and {@link Observer#onCompleted} has been called),
* or after an exception is thrown (and {@link Observer#onError} has been called),
* the given action will be called.
* @see <a href="http://msdn.microsoft.com/en-us/library/hh212133(v=vs.103).aspx">MSDN Observable.Finally method</a>
* @param action An action to be taken when the sequence is complete or
* throws an exception
*
* @return An observable sequence with the same elements as the input. After
* the last element is consumed (and {@link Observer#onCompleted} has been
* called), or after an exception is thrown (and {@link Observer#onError}
* has been called), the given action will be called.
*
* @see
* <a href="http://msdn.microsoft.com/en-us/library/hh212133(v=vs.103).aspx">MSDN
* Observable.Finally method</a>
*/
public static <T> Func1<Observer<T>, Subscription> finallyDo(final Observable<T> sequence, final Action0 action) {
return new Finally<>(sequence, action)::call;
}
private static class Finally<T> implements Func1<Observer<T>, Subscription> {
private final Observable<T> sequence;
private final Action0 finalAction;
@@ -58,6 +64,7 @@ public final class OperationFinally {
}
private class FinallyObserver implements Observer<T> {
private final Observer<T> observer;
FinallyObserver(Observer<T> observer) {

View File

@@ -23,52 +23,51 @@ import rx.util.functions.Func1;
public final class OperationMap {
/**
* Accepts a sequence and a transformation function. Returns a sequence that is the result of
* applying the transformation function to each item in the sequence.
* Accepts a sequence and a transformation function. Returns a sequence that
* is the result of applying the transformation function to each item in the
* sequence.
*
* @param sequence
* the input sequence.
* @param func
* a function to apply to each item in the sequence.
* @param <T>
* the type of the input sequence.
* @param <R>
* the type of the output sequence.
* @return a sequence that is the result of applying the transformation function to each item in the input sequence.
* @param sequence the input sequence.
* @param func a function to apply to each item in the sequence.
* @param <T> the type of the input sequence.
* @param <R> the type of the output sequence.
*
* @return a sequence that is the result of applying the transformation
* function to each item in the input sequence.
*/
public static <T, R> Func1<Observer<R>, Subscription> map(Observable<T> sequence, Func1<T, R> func) {
return new MapObservable<>(sequence, func);
}
/**
* Accepts a sequence of observable sequences and a transformation function. Returns a flattened sequence that is the result of
* applying the transformation function to each item in the sequence of each observable sequence.
* Accepts a sequence of observable sequences and a transformation function.
* Returns a flattened sequence that is the result of applying the
* transformation function to each item in the sequence of each observable
* sequence.
* <p>
* The closure should return an Observable which will then be merged.
*
* @param sequence
* the input sequence.
* @param func
* a function to apply to each item in the sequence.
* @param <T>
* the type of the input sequence.
* @param <R>
* the type of the output sequence.
* @return a sequence that is the result of applying the transformation function to each item in the input sequence.
* @param sequence the input sequence.
* @param func a function to apply to each item in the sequence.
* @param <T> the type of the input sequence.
* @param <R> the type of the output sequence.
*
* @return a sequence that is the result of applying the transformation
* function to each item in the input sequence.
*/
public static <T, R> Func1<Observer<R>, Subscription> mapMany(Observable<T> sequence, Func1<T, Observable<R>> func) {
return OperationMerge.merge(Observable.create(map(sequence, func)));
}
/**
* An observable sequence that is the result of applying a transformation to each item in an input sequence.
* An observable sequence that is the result of applying a transformation to
* each item in an input sequence.
*
* @param <T>
* the type of the input sequence.
* @param <R>
* the type of the output sequence.
* @param <T> the type of the input sequence.
* @param <R> the type of the output sequence.
*/
private static class MapObservable<T, R> implements Func1<Observer<R>, Subscription> {
public MapObservable(Observable<T> sequence, Func1<T, R> func) {
this.sequence = sequence;
this.func = func;
@@ -85,14 +84,14 @@ public final class OperationMap {
}
/**
* An observer that applies a transformation function to each item and forwards the result to an inner observer.
* An observer that applies a transformation function to each item and
* forwards the result to an inner observer.
*
* @param <T>
* the type of the observer items.
* @param <R>
* the type of the inner observer items.
* @param <T> the type of the observer items.
* @param <R> the type of the inner observer items.
*/
private static class MapObserver<T, R> implements Observer<T> {
public MapObserver(Observer<R> observer, Func1<T, R> func) {
this.observer = observer;
this.func = func;

Some files were not shown because too many files have changed in this diff Show More