Skip to content

Commit

Permalink
Merge a24c19b into 49c3f66
Browse files Browse the repository at this point in the history
  • Loading branch information
sjamesr committed Jan 1, 2020
2 parents 49c3f66 + a24c19b commit 43dc2dc
Show file tree
Hide file tree
Showing 14 changed files with 178 additions and 172 deletions.
48 changes: 48 additions & 0 deletions src/main/java/au/com/southsky/jfreesane/ByteStreams.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package au.com.southsky.jfreesane;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

final class ByteStreams {
private static int COPY_BUF_SIZE = 8192;

private ByteStreams() {}

/**
* A stand-in for {@code InputStream.readAllBytes} available in Java 9+. We currently support Java
* 8, so this is what we have to do.
*/
static int readAllBytes(InputStream in, byte[] dst) throws IOException {
int pos = 0;
while (pos < dst.length) {
int r = in.read(dst, pos, dst.length - pos);
if (r == -1) {
return pos;
}

pos += r;
}

return pos;
}

/**
* Copies up to maxBytes from src to dst, returning how many were copied.
*/
static int copy(InputStream src, OutputStream dst, int maxBytes) throws IOException {
byte[] buf = new byte[Math.min(maxBytes, COPY_BUF_SIZE)];
int total = 0;

while (total < maxBytes) {
int r = src.read(buf, 0, Math.min(maxBytes - total, COPY_BUF_SIZE));
if (r == -1) {
break;
}
dst.write(buf, 0, r);
total += r;
}

return total;
}
}
12 changes: 1 addition & 11 deletions src/main/java/au/com/southsky/jfreesane/FrameReader.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
import java.util.logging.Level;
import java.util.logging.Logger;

import com.google.common.base.MoreObjects;
import com.google.common.io.ByteStreams;
import com.google.common.primitives.UnsignedInteger;

/**
Expand Down Expand Up @@ -120,16 +118,8 @@ private int readRecord(OutputStream destination) throws IOException, SaneExcepti
throw new IllegalStateException("TODO: support massive records");
}

int bytesRead = (int) ByteStreams.copy(ByteStreams.limit(inputStream, length), destination);
int bytesRead = ByteStreams.copy(inputStream, destination, length);
log.log(Level.FINE, "Read a record of {0} bytes", bytesRead);
return bytesRead;
}

@Override
public String toString() {
return MoreObjects.toStringHelper(FrameReader.class)
.add("isBigEndian", bigEndian)
.add("parameters", parameters)
.toString();
}
}
4 changes: 1 addition & 3 deletions src/main/java/au/com/southsky/jfreesane/OptionGroup.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

import java.util.List;

import com.google.common.base.MoreObjects;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;

Expand Down Expand Up @@ -46,6 +44,6 @@ void addOption(SaneOption option) {

@Override
public String toString() {
return MoreObjects.toStringHelper(this).add("title", title).add("options", options).toString();
return "OptionGroup{" + "title='" + title + '\'' + ", options=" + options + '}';
}
}
43 changes: 43 additions & 0 deletions src/main/java/au/com/southsky/jfreesane/Preconditions.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package au.com.southsky.jfreesane;

final class Preconditions {
private Preconditions() {}

static void checkState(boolean state, String message, Object... args) {
if (!state) {
throw new IllegalStateException(String.format(message, args));
}
}

static void checkState(boolean state, String message) {
if (!state) {
throw new IllegalStateException(message);
}
}

static void checkState(boolean state) {
if (!state) {
throw new IllegalStateException();
}
}

static void checkArgument(boolean arg) {
if (!arg) {
throw new IllegalArgumentException();
}
}

static void checkArgument(boolean arg, String message, Object... args) {
if (!arg) {
throw new IllegalArgumentException(String.format(message, args));
}
}

static <T> T checkNotNull(T obj) {
if (obj == null) {
throw new NullPointerException();
}

return obj;
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
package au.com.southsky.jfreesane;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import com.google.common.collect.Maps;

/**
* A static factory of listeners that limit the rate at which they send
* {@link ScanListener#recordRead} notifications. The primary purpose of this class is to allow
Expand Down Expand Up @@ -48,7 +47,7 @@ public static ScanListener noMoreFrequentlyThan(
final ScanListener listener, final long time, final TimeUnit timeUnit) {
return new ScanListener() {
// Most users will only scan from one device at a time.
private Map<SaneDevice, Long> lastSentTime = Maps.newHashMapWithExpectedSize(1);
private Map<SaneDevice, Long> lastSentTime = new HashMap<>(1);

@Override
public void scanningStarted(SaneDevice device) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package au.com.southsky.jfreesane;

import com.google.common.base.Charsets;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.collect.HashBasedTable;
Expand All @@ -14,6 +13,7 @@
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
Expand Down Expand Up @@ -48,7 +48,7 @@ public SaneClientAuthentication(final String path) {
new CharSource() {
@Override
public Reader openStream() throws IOException {
return new InputStreamReader(new FileInputStream(path), Charsets.US_ASCII);
return new InputStreamReader(new FileInputStream(path), StandardCharsets.US_ASCII);
}
});
}
Expand Down
33 changes: 13 additions & 20 deletions src/main/java/au/com/southsky/jfreesane/SaneDevice.java
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
package au.com.southsky.jfreesane;

import com.google.common.base.Function;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

import java.awt.image.BufferedImage;
import java.io.Closeable;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
* Represents a SANE device within a session. SANE devices are obtained from a {@link SaneSession}.
Expand All @@ -31,7 +29,7 @@ public class SaneDevice implements Closeable {

private SaneDeviceHandle handle;

private Map<String, SaneOption> optionTitleMap = null;
private List<SaneOption> options = null;
private final List<OptionGroup> groups = Lists.newArrayList();

SaneDevice(SaneSession session, String name, String vendor, String model, String type) {
Expand Down Expand Up @@ -165,21 +163,12 @@ SaneDeviceHandle getHandle() {
* @throws IOException if a problem occurred talking to the SANE backend
*/
public List<SaneOption> listOptions() throws IOException {
if (optionTitleMap == null) {
if (options == null) {
groups.clear();
optionTitleMap =
Maps.uniqueIndex(
SaneOption.optionsFor(this),
new Function<SaneOption, String>() {
@Override
public String apply(SaneOption input) {
return input.getName();
}
});
options = SaneOption.optionsFor(this);
}

// Maps.uniqueIndex guarantees the order of optionTitleMap.values()
return ImmutableList.copyOf(optionTitleMap.values());
return new ArrayList<>(options);
}

void addOptionGroup(OptionGroup group) {
Expand All @@ -198,9 +187,13 @@ public List<OptionGroup> getOptionGroups() throws IOException {
* Returns the option with the given name for this device. If the option does not exist,
* {@code null} is returned. Name matching is case-sensitive.
*/
public SaneOption getOption(String title) throws IOException {
public SaneOption getOption(String optionName) throws IOException {
listOptions();
return optionTitleMap.get(title);
return options
.stream()
.filter(o -> Objects.equals(optionName, o.getName()))
.findFirst()
.orElse(null);
}

SaneSession getSession() {
Expand All @@ -212,6 +205,6 @@ SaneSession getSession() {
* options after an option was set).
*/
void invalidateOptions() {
optionTitleMap = null;
options = null;
}
}
37 changes: 9 additions & 28 deletions src/main/java/au/com/southsky/jfreesane/SaneEnums.java
Original file line number Diff line number Diff line change
@@ -1,21 +1,18 @@
package au.com.southsky.jfreesane;

import java.util.List;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;

/**
* Utilities for dealing with instances of {@link SaneEnum}.
*
* @author James Ring (sjr@jdns.org)
*/
final class SaneEnums {
private static Map<Class<?>, Map<Integer, ?>> cachedTypeMaps = Maps.newHashMap();
private static Map<Class<?>, Map<Integer, ?>> cachedTypeMaps = new HashMap<>();

// no public constructor
private SaneEnums() {}
Expand All @@ -27,14 +24,13 @@ private static synchronized <T extends Enum<T> & SaneEnum> Map<Integer, T> mapFo
return (Map<Integer, T>) cachedTypeMaps.get(enumType);
}

ImmutableMap.Builder<Integer, T> mapBuilder = ImmutableMap.builder();
Map<Integer, T> map = new HashMap<>();

for (T value : enumType.getEnumConstants()) {
mapBuilder.put(value.getWireValue(), value);
map.put(value.getWireValue(), value);
}

Map<Integer, T> result = mapBuilder.build();

Map<Integer, T> result = Collections.unmodifiableMap(map);
cachedTypeMaps.put(enumType, result);
return result;
}
Expand All @@ -44,30 +40,15 @@ private static synchronized <T extends Enum<T> & SaneEnum> Map<Integer, T> mapFo
* represent the wire values of the enum constants of the given {@code enumType}.
*/
public static <T extends Enum<T> & SaneEnum> Set<T> enumSet(Class<T> enumType, int wireValue) {
Set<T> result = EnumSet.noneOf(enumType);
T[] enumConstants = enumType.getEnumConstants();
List<T> values = Lists.newArrayListWithCapacity(enumConstants.length);

for (T value : enumConstants) {
if ((wireValue & value.getWireValue()) != 0) {
values.add(value);
result.add(value);
}
}

return Sets.immutableEnumSet(values);
}

/**
* Returns the result of bitwise-ORing the wire values of the given {@code SaneEnum} set. This
* method does not check to make sure the result is sensible: the caller must ensure that the set
* contains members whose wire values can be ORed together in a logically correct fashion.
*/
public static <T extends SaneEnum> int wireValue(Set<T> values) {
int result = 0;

for (T value : values) {
result |= value.getWireValue();
}

return result;
}

Expand Down
16 changes: 4 additions & 12 deletions src/main/java/au/com/southsky/jfreesane/SaneImage.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
package au.com.southsky.jfreesane;

import com.google.common.base.Function;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import com.google.common.collect.Ordering;
import com.google.common.collect.Sets;

import java.awt.Point;
import java.awt.Transparency;
Expand All @@ -18,6 +15,7 @@
import java.awt.image.IndexColorModel;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;
Expand All @@ -27,10 +25,10 @@
*/
final class SaneImage {
private static final Set<FrameType> singletonFrameTypes =
Sets.immutableEnumSet(FrameType.GRAY, FrameType.RGB);
Collections.unmodifiableSet(EnumSet.of(FrameType.GRAY, FrameType.RGB));

private static final Set<FrameType> redGreenBlueFrameTypes =
Sets.immutableEnumSet(FrameType.RED, FrameType.GREEN, FrameType.BLUE);
Collections.unmodifiableSet(EnumSet.of(FrameType.RED, FrameType.GREEN, FrameType.BLUE));

private final List<Frame> frames;
private final int depthPerPixel;
Expand All @@ -45,13 +43,7 @@ private SaneImage(
this.frames =
Ordering.explicit(
FrameType.RED, FrameType.GREEN, FrameType.BLUE, FrameType.RGB, FrameType.GRAY)
.onResultOf(
new Function<Frame, FrameType>() {
@Override
public FrameType apply(Frame input) {
return input.getType();
}
})
.onResultOf(Frame::getType)
.immutableSortedCopy(frames);
this.depthPerPixel = depthPerPixel;
this.width = width;
Expand Down

0 comments on commit 43dc2dc

Please sign in to comment.