This commit is contained in:
李建国 2024-02-28 10:53:50 +08:00
commit 9a63237f32
54 changed files with 6007 additions and 0 deletions

39
.gitignore vendored Normal file
View File

@ -0,0 +1,39 @@
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### IntelliJ IDEA ###
.idea/modules.xml
.idea/jarRepositories.xml
.idea/compiler.xml
.idea/libraries/
*.iws
*.iml
*.ipr
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store
/.idea/

3
buildNumber.properties Normal file
View File

@ -0,0 +1,3 @@
#maven.buildNumber.plugin properties file
#Wed Feb 21 16:14:03 CST 2024
buildNumber=1

170
pom.xml Normal file
View File

@ -0,0 +1,170 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.aohe</groupId>
<artifactId>twain-service</artifactId>
<version>0.1.1</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.java-websocket</groupId>
<artifactId>Java-WebSocket</artifactId>
<version>1.5.3</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version>
<optional>true</optional>
</dependency>
<!--这个依赖直接包含了 logback-core 以及 slf4j-api 的依赖-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.25</version>
</dependency>
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>2.0.43</version>
</dependency>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>4.5.1</version>
</dependency>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna-platform</artifactId>
<version>4.5.1</version>
</dependency>
</dependencies>
<!-- <build>-->
<!-- <plugins>-->
<!-- <plugin>-->
<!-- <groupId>org.apache.maven.plugins</groupId>-->
<!-- <artifactId>maven-assembly-plugin</artifactId>-->
<!-- <version>2.3</version>-->
<!-- <configuration>-->
<!-- &lt;!&ndash;如果不想在打包的后缀加上 assembly.xml 中设置的 id可以加上下面的配置&ndash;&gt;-->
<!-- <appendAssemblyId>false</appendAssemblyId>-->
<!-- <descriptorRefs>-->
<!-- <descriptorRef>jar-with-dependencies</descriptorRef>-->
<!-- </descriptorRefs>-->
<!-- <archive>-->
<!-- <manifest>-->
<!-- &lt;!&ndash; 是否绑定依赖,将外部 jar 包依赖加入到 classPath 中 &ndash;&gt;-->
<!-- <addClasspath>true</addClasspath>-->
<!-- &lt;!&ndash; 依赖前缀,与之前设置的文件夹路径要匹配 &ndash;&gt;-->
<!-- <classpathPrefix>lib/</classpathPrefix>-->
<!-- &lt;!&ndash; 执行的主程序入口 &ndash;&gt;-->
<!-- <mainClass>org.aohe.Main</mainClass>-->
<!-- </manifest>-->
<!-- </archive>-->
<!-- </configuration>-->
<!-- <executions>-->
<!-- <execution>-->
<!-- <id>make-assembly</id>-->
<!-- &lt;!&ndash;绑定的 maven 操作&ndash;&gt;-->
<!-- <phase>package</phase>-->
<!-- <goals>-->
<!-- <goal>assembly</goal>-->
<!-- </goals>-->
<!-- </execution>-->
<!-- </executions>-->
<!-- </plugin>-->
<!-- <plugin>-->
<!-- <groupId>org.graalvm.nativeimage</groupId>-->
<!-- <artifactId>native-image-maven-plugin</artifactId>-->
<!-- <version>21.2.0</version>-->
<!-- <executions>-->
<!-- <execution>-->
<!-- <goals>-->
<!-- <goal>native-image</goal>-->
<!-- </goals>-->
<!-- <phase>package</phase>-->
<!-- </execution>-->
<!-- </executions>-->
<!-- <configuration>-->
<!-- <skip>false</skip>-->
<!-- <imageName>twain-service</imageName>-->
<!-- <mainClass>org.aohe.Main</mainClass>-->
<!-- <buildArgs>-->
<!-- &#45;&#45;no-fallback-->
<!-- </buildArgs>-->
<!-- </configuration>-->
<!-- </plugin>-->
<!-- </plugins>-->
<!-- </build>-->
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4.1</version>
<configuration>
<!--打包时,包含所有依赖的 jar 包-->
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
<!--生成 javadoc 文件-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<encoding>UTF-8</encoding>
<charset>UTF-8</charset>
<docencoding>UTF-8</docencoding>
<doclint>none</doclint>
</configuration>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<!--生成 source 文件-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,29 @@
//package org.aohe;
//
//import lombok.extern.slf4j.Slf4j;
//import org.aohe.web.SocketServer;
//
//import java.io.BufferedReader;
//import java.io.IOException;
//import java.io.InputStreamReader;
//
//@Slf4j
//public class Main {
// public static void main(String[] args) throws IOException, InterruptedException {
// int port = 8997; // 843 flash policy port
//
// SocketServer s = new SocketServer(port);
// s.start();
// System.out.println("ChatServer started on port: " + s.getPort());
//
// BufferedReader sysin = new BufferedReader(new InputStreamReader(System.in));
// while (true) {
// String in = sysin.readLine();
// s.broadcast(in);
// if (in.equals("exit")) {
// s.stop(1000);
// break;
// }
// }
// }
//}

View File

@ -0,0 +1,242 @@
//package org.aohe.control;
//
//import cn.hutool.core.codec.Base64;
//import cn.hutool.core.lang.Console;
//import cn.hutool.log.Log;
//import cn.hutool.log.LogFactory;
//import cn.hutool.log.StaticLog;
//import com.alibaba.fastjson2.JSONObject;
//import org.aohe.core.twain.*;
//import org.aohe.exceptions.TwainException;
//import org.aohe.result.R;
//import org.aohe.scan.Source;
//import org.aohe.scan.SourceManager;
//
//import java.io.File;
//import java.util.*;
//
//public class Operational {
//
// private static final Log log = LogFactory.get();
//
// private static TwainScanner scanner = null;
//
// public static String selectOperational(String path) {
// JSONObject json = JSONObject.parse(path);
//
// //操作符
// String function = json.getString("function");
//
// //参数符
// JSONObject param = json.getJSONObject("params");
//
// R r = R.ok();
// try {
// if("001001".equals(function)){
// //获取扫描仪列表
// r = getDevices();
// } else if ("001002".equals(function)) {
// //选择扫描仪
// r = setScanner(param.getString("scannerId"));
// }else if ("001003".equals(function)){
// //获取扫描仪操作符列表
// r = getDeviceOperations();
// }else if ("001004".equals(function)){
// //r = setDeviceOperations();
// }else if ("001007".equals(function)){
// r = setDeviceOperations(param);
// }else if ("001008".equals(function)){
// r = startScan(param.getString("scannerId"));
// }else if ("001012".equals(function)){
// closeTwSource();
// }else if ("001013".equals(function)){
// closeTwSource();
// }else if ("001015".equals(function)){
// r = startScan(param.getString("scannerId"),true);
// }else if ("001016".equals(function)){
// r = startScan(param.getString("scannerId"),true);
// }
// } catch (TwainException e) {
// StaticLog.error("获取驱动列表失败");
// StaticLog.error(e);
// throw new RuntimeException(e);
// } catch (InterruptedException e) {
// StaticLog.error("选择驱动失败");
// StaticLog.error(e);
// throw new RuntimeException(e);
// }
//
// return r.toJsonStr();
// }
//
// /**
// * 001001
// * 获取连接到当前终端的所有扫描仪并返回设备的SN号
// *
// * @return R<list>
// */
// public static R getDevices () throws TwainException {
// return R.ok(TwainSource.getProductNamesToList());
// }
//
// /**
// * 001002
// * 选中某一获取到的扫描仪
// * @return R<boolean> -> success
// */
// public static R setScanner(String name) throws TwainException, InterruptedException {
// if(name == null || name.isEmpty()){
// return R.fail("扫描仪名字为空");
// }
//
// TwainScanner.getScanner().select(name);
// Twain.getSourceManager().selectSource(name);
//
// return R.ok();
// }
//
// public static void main(String[] args) throws TwainException {
// System.out.println(TwainScanner.getScanner().getDeviceNames());
// }
//
// /**
// * 001003
// * 获取当前选中扫描仪可配置的项
// * @return
// */
// public static R getDeviceOperations() throws TwainException {
//
// try{
// TwainSource twainSource = openTwSource();
// TwainCapability[] capabilities = twainSource.getCapabilities();
//
//
// Map<String, List<String>> map = new HashMap<>();
// for (TwainCapability cap : capabilities){
// List<String> list = new ArrayList<>();
//
// String key = Twain.getMapCapCodeToName().get(cap.cap);
// String formatKey = String.format("0x%04x", cap.cap);
//
// list.add(key);
// list.add(formatKey);
//
// map.put(key,list);
// }
// return R.ok(map);
// }finally {
// closeTwSource();
// }
//
//
//
//
//
// }
//
// /**
// * 001004
// * 设置或修改当前选中扫描仪某一配置项的能力值
// * DPI --> double
// * 色彩模式 color 0,1,2 -> 黑白灰度彩色
// * 进纸模式 paper true,false -> 自动手动
// * @param map 参数和值
// * @return R
// */
// public static R setDeviceOperations(JSONObject map){
// try {
// TwainSource twainSource = Twain.getSourceManager().getSource();
// // 先约定为三种参数 DPI,色彩模式,进纸模式
// if(map.get("dpi") !=null){
// twainSource.setResolution(map.getDouble("dpi"));
// }
// if(map.get("color") !=null){
// twainSource.setCapability(Twain.ICAP_PIXELTYPE, map.getInteger("color"));
// }
// if(map.get("paper") !=null){
// twainSource.setCapability(Twain.CAP_FEEDERENABLED, map.getBooleanValue("paper"));
// }
// } catch (TwainException e) {
// throw new RuntimeException(e);
// }
// return R.ok();
// }
//
// /**
// * 001008
// * 当前扫描仪启动扫描
// * @param name 扫描仪名称
// * @return R
// * @throws TwainException default error
// */
// public static R startScan(String name) throws TwainException {
// return startScan(name, false);
// }
//
// /**
// * 001008
// * 当前扫描仪启动扫描
// * @param name 扫描仪名称
// * @param systemUI 是否使用打印机自带UI
// * @return R
// * @throws TwainException default error
// */
// public static R startScan(String name, boolean systemUI ) throws TwainException {
// Source source = new Source();
// source.setName(name);
// source.setSystemUI(systemUI);
// List<File> fileList = source.scan();
// List<String> base64Files = new ArrayList<>();
// for (File file : fileList){
// base64Files.add(Base64.encode(file));
// }
// return R.ok(base64Files);
// }
//
//// public static void main(String[] args) throws TwainException, InterruptedException {
//// List<String> list = (List<String>) getDevices().getData();
//// System.out.println(list.get(0));
//// R r = setScanner(list.get(0));
//// //System.out.println(getDeviceOperations());
//// System.out.println(startScan(list.get(0), false));
//// ;
//// }
//
//
// /**
// * 打开接口
// * @return twSource
// * @throws TwainException 默认错误
// */
// public static TwainSource openTwSource() throws TwainException {
// TwainSource twainSource = Twain.getSourceManager().getSource();
//
// if(twainSource.getState() != 4){
// //打开接口
// Twain.getSourceManager().openSource();
// }
// return twainSource;
// }
//
// /**
// * 关闭接口
// * @throws TwainException 默认错误
// */
// public static void closeTwSource() throws TwainException {
// TwainSource twainSource = Twain.getSourceManager().getSource();
// twainSource.close();
// }
//
// public void getSetting(Integer i) throws TwainException {
//
// try{
// TwainSource twainSource = openTwSource();
// TwainCapability tc = twainSource.getCapability(i);
// Console.log(tc.getItems());
// } catch (TwainException e) {
// throw new RuntimeException(e);
// } finally {
// closeTwSource();
// }
// }
//}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,41 @@
/*
* Copyright 2018 lucifer.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.aohe.core.twain;
import com.sun.jna.Pointer;
import com.sun.jna.win32.StdCallLibrary;
import org.aohe.libs.Win32Twain;
public class TwainCallback implements StdCallLibrary.StdCallCallback {
public int callback(Win32Twain.TW_IDENTITY orign, Win32Twain.TW_IDENTITY dest, int dg, short dat, short msg, Pointer data) {
// System.out.println("MSG!!!!!!!!!!!!!!!!!!!!!!!!!!!" + msg);
try {
TwainIdentity orig = new TwainIdentity(Twain.sourceManager, orign);
TwainSource source = Twain.sourceManager.getSource();
if (orig.getId() != source.getId()) {
return Twain.TWRC_FAILURE;
}
System.out.println(String.format("CALLBACK ----------------------> DG:%d, DAT:%d, MSG:%d", dg, dat, msg));
return source.callback(dg, dat, msg, data);
} catch (Throwable e) {
Twain.signalException(e.getMessage());
e.printStackTrace();
return Twain.TWRC_FAILURE;
}
}
}

View File

@ -0,0 +1,280 @@
package org.aohe.core.twain;
import com.sun.jna.Pointer;
import org.aohe.exceptions.TwainCheckStatusException;
import org.aohe.exceptions.TwainException;
import org.aohe.libs.Win32Twain;
import org.aohe.utils.TwainUtils;
import org.aohe.variable.*;
import java.util.ArrayList;
import java.util.List;
public class TwainCapability {
protected TwainSource source;
public int cap;
protected byte[] capability = new byte[16];
protected TwainContainer container;
public TwainCapability(TwainSource source, int cap) throws TwainException {
this.source = source;
this.cap = cap;
this.container = get();
}
public TwainCapability(TwainSource source, int cap, int mode) throws TwainException {
this.source = source;
this.cap = cap;
switch (mode) {
case Twain.MSG_GETCURRENT:
container = getCurrent();
break;
case Twain.MSG_GETDEFAULT:
container = getDefault();
break;
case Twain.MSG_GET:
default:
container = get();
break;
}
}
/**
* 根据消息和容器类型获取TwainContainer对象
* @param msg 消息类型
* @param contype 容器类型
* @return TwainContainer对象
* @throws TwainException Twain异常
*/
private TwainContainer get(int msg, int contype) throws TwainException {
Win32Twain.TW_CAPABILITY cp = new Win32Twain.TW_CAPABILITY();
cp.Cap = (short) cap;
cp.ConType = (short) contype;
cp.Container = 0l;
TwainUtils.setINT16(capability, 0, cap);
TwainUtils.setINT16(capability, 2, contype);
TwainUtils.setINT64(capability, 4, 0);
System.out.print("TWAIN GET: ");
dumpHex(capability);
System.out.print(",");
source.call(Twain.DG_CONTROL, Twain.DAT_CAPABILITY, (short) msg, capability);
int containerType = TwainUtils.getINT16(capability, 2);
Pointer containerPtr = new Pointer(TwainUtils.getINT64(capability, 4));
dumpHex(capability);
System.out.print(",");
byte[] container = Twain.getContainer(containerType, containerPtr);
dumpHex(container);
System.out.println();
switch (containerType) {
case Twain.TWON_ARRAY:
return new TwainArray(cap, container);
case Twain.TWON_ENUMERATION:
return new TwainEnumeration(cap, container);
case Twain.TWON_ONEVALUE:
return new TwainOneValue(cap, container);
case Twain.TWON_RANGE:
return new TwainRange(cap, container);
default:
throw new TwainException("Unknown container type " + containerType);
}
}
private TwainContainer get(int msg) throws TwainException {
return get(msg, -1);
}
public TwainContainer get() throws TwainException {
return container = get(Twain.MSG_GET);
}
public TwainContainer getCurrent() throws TwainException {
return get(Twain.MSG_GETCURRENT);
}
public TwainContainer getDefault() throws TwainException {
return get(Twain.MSG_GETDEFAULT);
}
public int querySupport() throws TwainException {
return get(Twain.MSG_QUERYSUPPORT, Twain.TWON_ONEVALUE).intValue();
}
public boolean querySupport(int flagMask) {
try {
int flags = querySupport();
return (flags & flagMask) != 0;
} catch (TwainException e) {
return false;
}
}
public TwainContainer reset() throws TwainException {
return container = get(Twain.MSG_RESET);
}
public TwainContainer set() throws TwainException {
return container = set(container);
}
public static void dumpHex(byte[] bytes) {
for (int i = 0; i < bytes.length; i++) {
System.out.print(String.format("%02x", bytes[i]));
}
}
public TwainContainer set(TwainContainer container) throws TwainException {
int containerType = container.getType();
byte[] containerBytes = container.getBytes();
Pointer containerHandle = Twain.setContainer(containerType, containerBytes);
try {
TwainUtils.setINT16(capability, 0, cap);
TwainUtils.setINT16(capability, 2, containerType);
TwainUtils.setINT64(capability, 4, Pointer.nativeValue(containerHandle));
System.out.print("TWAIN SET: ");
dumpHex(capability);
System.out.print(",");
dumpHex(containerBytes);
System.out.println();
source.call(Twain.DG_CONTROL, Twain.DAT_CAPABILITY, Twain.MSG_SET, capability);
} catch (TwainCheckStatusException e) {
e.printStackTrace();
container = get();
} finally {
Twain.free(containerHandle);
}
return container;
}
public <T> T[] getItems() {
return container.getItems();
}
public boolean booleanValue() throws TwainException {
return getCurrent().booleanValue();
}
public int intValue() throws TwainException {
return getCurrent().intValue();
}
public double doubleValue() throws TwainException {
return getCurrent().doubleValue();
}
public void setCurrentValue(boolean v) throws TwainException {
setCurrentValue(new Boolean(v));
}
public void setCurrentValue(int v) throws TwainException {
setCurrentValue(new Integer(v));
}
public void setCurrentValue(double v) throws TwainException {
setCurrentValue(new Double(v));
}
public void setCurrentValue(Object val) throws TwainException {
container.setCurrentValue(val);
set();
}
public boolean booleanDefaultValue() throws TwainException {
return getDefault().booleanDefaultValue();
}
public int intDefaultValue() throws TwainException {
return getDefault().intDefaultValue();
}
public double doubleDefaultValue() throws TwainException {
return getDefault().doubleDefaultValue();
}
public void setDefaultValue(boolean v) throws TwainException {
setDefaultValue(new Boolean(v));
}
public void setDefaultValue(int v) throws TwainException {
setDefaultValue(new Integer(v));
}
public void setDefaultValue(double v) throws TwainException {
setDefaultValue(new Double(v));
}
public void setDefaultValue(Object val) throws TwainException {
container.setDefaultValue(val);
set();
}
public static TwainCapability[] getCapabilities(TwainSource source) throws TwainException {
TwainCapability tc = source.getCapability(Twain.CAP_SUPPORTEDCAPS);
Object[] items = tc.getItems();
List<TwainCapability> caps = new ArrayList<>();
for (int i = 0; i < items.length; i++) {
int capid = ((Number) items[i]).intValue();
try {
switch (capid) {
case Twain.ICAP_COMPRESSION:
caps.add(new Compression(source));
break;
case Twain.ICAP_XFERMECH:
caps.add(new XferMech(source));
break;
case Twain.ICAP_IMAGEFILEFORMAT:
caps.add(new ImageFileFormat(source));
break;
default:
caps.add(new TwainCapability(source, capid));
break;
}
} catch (TwainException e) {
}
}
return (TwainCapability[]) caps.toArray(new TwainCapability[0]);
}
static public class ImageFileFormat extends TwainCapability {
ImageFileFormat(TwainSource source) throws TwainException {
super(source, Twain.ICAP_IMAGEFILEFORMAT);
}
}
static public class Compression extends TwainCapability {
Compression(TwainSource source) throws TwainException {
super(source, Twain.ICAP_COMPRESSION);
}
}
static public class XferMech extends TwainCapability {
XferMech(TwainSource source) throws TwainException {
super(source, Twain.ICAP_XFERMECH);
}
@Override
public int intValue() {
try {
return super.intValue();
} catch (Exception e) {
return Twain.TWSX_NATIVE;
}
}
}
}

View File

@ -0,0 +1,29 @@
package org.aohe.core.twain;
import org.aohe.transfer.TwainFileTransfer;
import org.aohe.transfer.TwainMemoryTransfer;
import org.aohe.transfer.TwainNativeTransfer;
import org.aohe.transfer.TwainTransfer;
public class TwainDefaultTransferFactory implements TwainTransferFactory {
public TwainDefaultTransferFactory() {
}
@Override
public TwainTransfer createMemoryTransfer(TwainSource source) {
return new TwainMemoryTransfer(source);
}
@Override
public TwainTransfer createNativeTransfer(TwainSource source) {
return new TwainNativeTransfer(source);
}
@Override
public TwainTransfer createFileTransfer(TwainSource source) {
return new TwainFileTransfer(source);
}
}

View File

@ -0,0 +1,140 @@
package org.aohe.core.twain;
import org.aohe.transfer.TwainMemoryTransfer;
import java.awt.image.BufferedImage;
import java.io.File;
public class TwainIOMetadata {
static public Type INFO = new Type("INFO");
static public Type EXCEPTION = new Type("EXCEPTION");
static public Type SELECTED = new Type("SELECTED");
static public Type ACQUIRED = new Type("ACQUIRED");
static public Type FILE = new Type("FILE");
static public Type MEMORY = new Type("MEMORY");
static public Type NEGOTIATE = new Type("NEGOTIATE");
static public Type STATECHANGE = new Type("STATECHANGE");
private int laststate = 0, state = 0;
private boolean cancel = false;
private BufferedImage image = null;
private File file = null;
private String info = "";
private Exception exception = null;
public void setState(int s) {
laststate = state;
state = s;
}
public int getLastState() {
return laststate;
}
public int getState() {
return state;
}
public boolean isState(int state) {
return this.state == state;
}
public void setImage(BufferedImage image) {
this.image = image;
this.file = null;
}
public BufferedImage getImage() {
return image;
}
public void setFile(File file) {
this.image = null;
this.file = file;
}
public File getFile() {
return file;
}
public void setInfo(String info) {
this.info = info;
}
public String getInfo() {
return info;
}
public void setException(Exception ex) {
this.exception = ex;
}
public Exception getException() {
return exception;
}
public boolean getCancel() {
return cancel;
}
public void setCancel(boolean cancel) {
this.cancel = cancel;
}
static public final String[] TWAIN_STATE = {
"",
"Pre-Session",
"Source Manager Loaded",
"Source Manager Open",
"Source Open",
"Source Enabled",
"Transfer Ready",
"Transferring Data",};
public String getStateStr() {
return TWAIN_STATE[getState()];
}
private TwainSource source = null;
void setSource(TwainSource source) {
this.source = source;
}
public TwainSource getSource() {
return source;
}
public TwainSource getDevice() {
return source;
}
private TwainMemoryTransfer.Info memory = null;
public void setMemory(TwainMemoryTransfer.Info info) {
memory = info;
}
public TwainMemoryTransfer.Info getMemory() {
return memory;
}
public boolean isFinished() {
return (getState() == 3) && (getLastState() == 4);
}
static public class Type {
String type;
public Type(String type) {
this.type = type;
}
@Override
public String toString() {
return type;
}
}
}

View File

@ -0,0 +1,179 @@
package org.aohe.core.twain;
import org.aohe.exceptions.TwainException;
import org.aohe.libs.Win32Twain;
import java.util.ArrayList;
import java.util.List;
public class TwainIdentity {
private TwainSourceManager manager;
protected Win32Twain.TW_IDENTITY identity;
public TwainIdentity(TwainSourceManager manager) {
this.manager = manager;
this.identity = new Win32Twain.TW_IDENTITY();
}
TwainIdentity(TwainSourceManager sourceManager, Win32Twain.TW_IDENTITY orign) {
this.manager = manager;
this.identity = orign;
}
protected void getDefault() {
try {
manager.call(Twain.DG_CONTROL, Twain.DAT_IDENTITY, Twain.MSG_GETDEFAULT, identity);
} catch (TwainException e) {
}
}
void userSelect() throws TwainException {
manager.call(Twain.DG_CONTROL, Twain.DAT_IDENTITY, Twain.MSG_USERSELECT, identity);
}
public void open() throws TwainException {
manager.call(Twain.DG_CONTROL, Twain.DAT_IDENTITY, Twain.MSG_OPENDS, identity);
}
public void close() throws TwainException {
manager.call(Twain.DG_CONTROL, Twain.DAT_IDENTITY, Twain.MSG_CLOSEDS, identity);
}
void getFirst() throws TwainException {
manager.call(Twain.DG_CONTROL, Twain.DAT_IDENTITY, Twain.MSG_GETFIRST, identity);
}
void getNext() throws TwainException {
manager.call(Twain.DG_CONTROL, Twain.DAT_IDENTITY, Twain.MSG_GETNEXT, identity);
}
public int getId() {
return identity.Id;
}
public int getMajorNum() {
return identity.Version.MajorNum;
}
public int getMinorNum() {
return identity.Version.MinorNum;
}
public int getLanguage() {
return identity.Version.Language;
}
public int getCountry() {
return identity.Version.Country;
}
public int getProtocolMajor() {
return identity.ProtocolMajor;
}
public int getProtocolMinor() {
return identity.ProtocolMinor;
}
public int getSupportedGroups() {
return identity.SupportedGroups;
}
public String getManufacturer() {
return identity.getManufacturer();
}
public String getProductFamily() {
return identity.getProductFamily();
}
public String getProductName() {
return identity.getProductName();
}
public static TwainIdentity[] getIdentities() throws TwainException {
TwainSourceManager manager = Twain.getSourceManager();
List<TwainIdentity> identities = new ArrayList<>();
try {
TwainIdentity identity = new TwainIdentity(manager);
identity.getFirst();
identities.add(identity);
while (true) {
identity = new TwainIdentity(manager);
identity.getNext();
identities.add(identity);
}
} catch (TwainException e) {
}
return identities.toArray(new TwainIdentity[0]);
}
/**
* 获取产品名称数组
* @return 产品名称数组
* @throws TwainException 如果获取产品名称时发生错误
*/
public static String[] getProductNames() throws TwainException {
TwainSourceManager manager = Twain.getSourceManager();
List<String> identities = new ArrayList<>();
try {
TwainIdentity identity = new TwainIdentity(manager);
identity.getFirst();
identities.add(identity.getProductName());
while (true) {
identity = new TwainIdentity(manager);
identity.getNext();
identities.add(identity.getProductName());
}
} catch (TwainException e) {
// 处理TwainException
//查询完成抛出错误
}
return identities.toArray(new String[0]);
}
/**
* 获取产品名称List
* @return 产品名称数组
* @throws TwainException 如果获取产品名称时发生错误
*/
public static List<String> getProductNamesToList() throws TwainException {
TwainSourceManager manager = Twain.getSourceManager();
List<String> identities = new ArrayList<>();
try {
TwainIdentity identity = new TwainIdentity(manager);
identity.getFirst();
identities.add(identity.getProductName());
while (true) {
identity = new TwainIdentity(manager);
identity.getNext();
identities.add(identity.getProductName());
}
} catch (TwainException e) {
// 处理TwainException
//查询完成抛出错误
}
return identities;
}
public String toString() {
String s = "TwainIdentity\n";
s += "\tid = 0x" + Integer.toHexString(getId()) + "\n";
s += "\tmajorNum = 0x" + Integer.toHexString(getMajorNum()) + "\n";
s += "\tminorNum = 0x" + Integer.toHexString(getMinorNum()) + "\n";
s += "\tlanguage = 0x" + Integer.toHexString(getLanguage()) + "\n";
s += "\tcountry = 0x" + Integer.toHexString(getCountry()) + "\n";
s += "\tprotocol major = 0x" + Integer.toHexString(getProtocolMajor()) + "\n";
s += "\tprotocol minor = 0x" + Integer.toHexString(getProtocolMinor()) + "\n";
s += "\tsupported groups = 0x" + Integer.toHexString(getSupportedGroups()) + "\n";
s += "\tmanufacturer = " + getManufacturer() + "\n";
s += "\tproduct family = " + getProductFamily() + "\n";
s += "\tproduct name = " + getProductName() + "\n";
return s;
}
}

View File

@ -0,0 +1,90 @@
package org.aohe.core.twain;
import org.aohe.exceptions.TwainException;
import org.aohe.utils.TwainUtils;
import static org.aohe.core.twain.Twain.*;
public class TwainImageLayout {
TwainSource source;
byte[] buf = new byte[28];
public TwainImageLayout(TwainSource source) {
this.source = source;
}
public void get() throws TwainException {
source.call(DG_IMAGE, DAT_IMAGELAYOUT, MSG_GET, buf);
}
public void getDefault() throws TwainException {
source.call(DG_IMAGE, DAT_IMAGELAYOUT, MSG_GETDEFAULT, buf);
}
public void set() throws TwainException {
source.call(DG_IMAGE, DAT_IMAGELAYOUT, MSG_SET, buf);
}
public void reset() throws TwainException {
source.call(DG_IMAGE, DAT_IMAGELAYOUT, MSG_RESET, buf);
}
public double getLeft() {
return TwainUtils.getFIX32(buf, 0);
}
public void setLeft(double v) {
TwainUtils.setFIX32(buf, 0, v);
}
public double getTop() {
return TwainUtils.getFIX32(buf, 4);
}
public void setTop(double v) {
TwainUtils.setFIX32(buf, 4, v);
}
public double getRight() {
return TwainUtils.getFIX32(buf, 8);
}
public void setRight(double v) {
TwainUtils.setFIX32(buf, 8, v);
}
public double getBottom() {
return TwainUtils.getFIX32(buf, 12);
}
public void setBottom(double v) {
TwainUtils.setFIX32(buf, 12, v);
}
public int getDocumentNumber() {
return TwainUtils.getINT32(buf, 16);
}
public void setDocumentNumber(int v) {
TwainUtils.setINT32(buf, 16, v);
}
public int getPageNumber() {
return TwainUtils.getINT32(buf, 20);
}
public void setPageNumber(int v) {
TwainUtils.setINT32(buf, 20, v);
}
public int getFrameNumber() {
return TwainUtils.getINT32(buf, 24);
}
public void setFrameNumber(int v) {
TwainUtils.setINT32(buf, 24, v);
}
}

View File

@ -0,0 +1,8 @@
package org.aohe.core.twain;
public interface TwainListener {
public void update(TwainIOMetadata.Type type, TwainIOMetadata metadata);
}

View File

@ -0,0 +1,159 @@
package org.aohe.core.twain;
import org.aohe.exceptions.TwainException;
import org.aohe.transfer.TwainMemoryTransfer;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class TwainScanner {
private TwainIOMetadata metadata;
private List<TwainListener> listeners = new ArrayList<>();
public TwainScanner() {
metadata = new TwainIOMetadata();
Twain.setScanner(this);
}
public void select() throws TwainException {
Twain.select(this);
}
public TwainIdentity[] getIdentities() {
List<TwainIdentity> identities = new ArrayList<>();
try {
Twain.getIdentities(this, identities);
} catch (Exception e) {
metadata.setException(e);
fireListenerUpdate(metadata.EXCEPTION);
}
return (TwainIdentity[]) identities.toArray(new TwainIdentity[identities.size()]);
}
public String[] getDeviceNames() throws TwainException {
List<TwainIdentity> identities = new ArrayList<>();
Twain.getIdentities(this, identities);
String[] names = new String[identities.size()];
Iterator<TwainIdentity> ids = identities.iterator();
for (int i = 0; ids.hasNext(); i++) {
TwainIdentity id = (TwainIdentity) ids.next();
names[i] = id.getProductName();
}
return names;
}
public void select(String name) throws TwainException {
Twain.select(this, name);
}
public void selectNow() throws TwainException {
Twain.selectNow();
}
public void acquire() throws TwainException {
Twain.acquire(this);
}
public void setCancel(boolean c) throws TwainException {
Twain.setCancel(this, c);
}
void setImage(BufferedImage image) {
try {
metadata.setImage(image);
fireListenerUpdate(metadata.ACQUIRED);
} catch (Exception e) {
metadata.setException(e);
fireListenerUpdate(metadata.EXCEPTION);
}
}
void setImage(File file) {
try {
metadata.setFile(file);
fireListenerUpdate(metadata.FILE);
} catch (Exception e) {
metadata.setException(e);
fireListenerUpdate(metadata.EXCEPTION);
}
}
void setImageBuffer(TwainMemoryTransfer.Info info) {
try {
((TwainIOMetadata) metadata).setMemory(info);
fireListenerUpdate(metadata.MEMORY);
} catch (Exception e) {
metadata.setException(e);
fireListenerUpdate(metadata.EXCEPTION);
}
}
protected void negotiateCapabilities(TwainSource source) {
((TwainIOMetadata) metadata).setSource(source);
fireListenerUpdate(metadata.NEGOTIATE);
if (metadata.getCancel()) {
try {
source.close();
} catch (Exception e) {
metadata.setException(e);
fireListenerUpdate(metadata.EXCEPTION);
}
}
}
void setState(TwainSource source) {
metadata.setState(source.getState());
((TwainIOMetadata) metadata).setSource(source);
fireListenerUpdate(metadata.STATECHANGE);
}
void signalInfo(String msg, int val) {
metadata.setInfo(msg + " [0x" + Integer.toHexString(val) + "]");
fireListenerUpdate(metadata.INFO);
}
void signalException(String msg) {
Exception e = new TwainException(getClass().getName() + ".setException:\n " + msg);
metadata.setException(e);
fireListenerUpdate(metadata.EXCEPTION);
}
public TwainIOMetadata getMetadata() {
return metadata;
}
public void setMetadata(TwainIOMetadata metadata) {
this.metadata = metadata;
}
public void addListener(TwainListener listener) {
listeners.add(listener);
}
public void removeListener(TwainListener listener) {
listeners.remove(listener);
}
public void fireExceptionUpdate(Exception e) {
metadata.setException(e);
fireListenerUpdate(metadata.EXCEPTION);
}
public void fireListenerUpdate(TwainIOMetadata.Type type) {
for (Iterator<TwainListener> e = new ArrayList<>(listeners).iterator(); e.hasNext();) {
TwainListener listener = (TwainListener) e.next();
listener.update(type, metadata);
}
}
public static TwainScanner getScanner() {
return new TwainScanner();
}
}

View File

@ -0,0 +1,559 @@
package org.aohe.core.twain;
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.WinDef;
import org.aohe.exceptions.*;
import org.aohe.libs.Win32Twain;
import org.aohe.transfer.TwainTransfer;
import org.aohe.utils.TwainUtils;
import java.util.concurrent.Semaphore;
public class TwainSource extends TwainIdentity {
private boolean busy;
private int state;
private WinDef.HWND hwnd;
private int showUI = 1;
private int modalUI = 0;
private int iff = Twain.TWFF_BMP;
private boolean userCancelled;
private TwainTransferFactory transferFactory;
private Semaphore twSemaphore = null;
private boolean twHaveImage = false;
short callback(int dg, short dat, short msg, Pointer data) {
switch (msg) {
case Twain.MSG_XFERREADY:
// twHaveImage = true;
// twSemaphore.release();
try {
transferImage();
} catch (Exception e) {
return Twain.TWRC_FAILURE;
}
break;
case Twain.MSG_CLOSEDSOK:
case Twain.MSG_CLOSEDSREQ:
// twHaveImage = false;
// twSemaphore.release();
try {
disable();
close();
} catch (Exception e) {
return Twain.TWRC_FAILURE;
}
break;
case Twain.MSG_DEVICEEVENT:
case Twain.MSG_NULL:
break;
default:
System.out.println("Unknown message");
return Twain.TWRC_FAILURE;
}
return Twain.TWRC_SUCCESS;
}
public TwainSource(TwainSourceManager manager, WinDef.HWND hwnd, boolean busy) {
super(manager);
this.busy = busy;
this.state = 3;
this.hwnd = hwnd;
this.userCancelled = false;
this.transferFactory = new TwainDefaultTransferFactory();
}
public Win32Twain.TW_IDENTITY getIdentity() {
return identity;
}
public boolean isBusy() {
return busy;
}
protected void setBusy(boolean b) {
busy = b;
Twain.signalStateChange(this);
}
public int getState() {
return state;
}
public void setState(int s) {
state = s;
Twain.signalStateChange(this);
}
public boolean getCancel() {
return userCancelled;
}
public void setCancel(boolean c) {
userCancelled = c;
}
protected void checkState(int state) throws TwainException {
if (this.state == state) {
return;
}
throw new TwainException(getClass().getName() + ".checkState: Source not in state " + state + " but in state " + this.state + ".");
}
private boolean isTwain20() {
return false;
// return (identity.SupportedGroups & 0x40000000) != 0;
}
@Override
public void open() throws TwainException {
super.open();
if (isTwain20()) {
Win32Twain.TW_CALLBACK cb = new Win32Twain.TW_CALLBACK();
cb.Message = 0;
cb.Proc = new TwainCallback();
call(Twain.DG_CONTROL, (short) 0x12, (short) 0x902, cb);
}
}
protected int getConditionCode() throws TwainException {
Win32Twain.TW_FIX32 status = new Win32Twain.TW_FIX32();
int rc = Twain.callSource(identity, Twain.DG_CONTROL, Twain.DAT_STATUS, Twain.MSG_GET, status);
if (rc != Twain.TWRC_SUCCESS) {
throw new TwainException("Cannot retrive twain source's status. RC = " + rc);
}
// System.out.println(status.Whole + " " + status.Frac);
return status.Whole;
}
public void call(short dg, short dat, short msg, Object data) throws TwainCheckStatusException, TwainCancelException, TwainNotDSException, TwainTransferDoneException, TwainException {
int rc = Twain.callSource(identity, dg, dat, msg, data);
switch (rc) {
case Twain.TWRC_SUCCESS:
return;
case Twain.TWRC_FAILURE:
int cc = getConditionCode();
if (cc == 4) {
} else {
throw new TwainException(getClass().getName() + ".call error: " + TwainSourceManager.INFO[cc]);
}
case Twain.TWRC_CHECKSTATUS:
throw new TwainCheckStatusException();
case Twain.TWRC_CANCEL:
throw new TwainCancelException();
case Twain.TWRC_DSEVENT:
return;
case Twain.TWRC_NOTDSEVENT:
throw new TwainNotDSException();
case Twain.TWRC_XFERDONE:
throw new TwainTransferDoneException();
case Twain.TWRC_ENDOFLIST:
throw new TwainEndOfListException();
case Twain.TWRC_INFONOTSUPPORTED:
throw new TwainInfNotSupportedException();
case Twain.TWRC_DATANOTAVAILABLE:
throw new TwainDataNotAvailableException();
default:
throw new TwainException("Failed to call source. RC = " + rc);
}
}
public TwainCapability[] getCapabilities() throws TwainException {
return TwainCapability.getCapabilities(this);
}
public TwainCapability getCapability(int cap) throws TwainException { // use only in state 4
return new TwainCapability(this, cap);
}
public TwainCapability getCapability(int cap, int mode) throws TwainException {
return new TwainCapability(this, cap, mode);
}
public TwainTransferFactory getTransferFactory() {
return transferFactory;
}
public void setTransferFactory(TwainTransferFactory transferFactory) {
if (transferFactory == null) {
throw new IllegalArgumentException(getClass().getName() + ".setTransferFactory\n\tTwain transfer factory cannot be null.");
}
this.transferFactory = transferFactory;
}
public void setShowUI(boolean enable) {
showUI = (enable) ? 1 : 0;
}
public boolean isModalUI() {
return (modalUI == 1);
}
public void setCapability(int cap, boolean v) throws TwainException {
TwainCapability tc = getCapability(cap, Twain.MSG_GETCURRENT);
if (tc.booleanValue() != v) {
tc.setCurrentValue(v);
if (getCapability(cap).booleanValue() != v) {
throw new TwainException(getClass().getName() + ".setCapability:\n\tCannot set capability " + cap + " to " + v);
}
}
}
public void setCapability(int cap, int v) throws TwainException {
TwainCapability tc = getCapability(cap, Twain.MSG_GETCURRENT);
if (tc.intValue() != v) {
tc.setCurrentValue(v);
if (getCapability(cap).intValue() != v) {
throw new TwainException(getClass().getName() + ".setCapability:\n\tCannot set capability " + cap + " to " + v);
}
}
}
public void setCapability(int cap, double v) throws TwainException {
TwainCapability tc = getCapability(cap, Twain.MSG_GETCURRENT);
if (tc.doubleValue() != v) {
tc.setCurrentValue(v);
if (getCapability(cap).doubleValue() != v) {
throw new TwainException(getClass().getName() + ".setCapability:\n\tCannot set capability " + cap + " to " + v);
}
}
}
public boolean isUIControllable() {
try {
return getCapability(Twain.CAP_UICONTROLLABLE).booleanValue();
} catch (Exception e) {
Twain.signalException(getClass().getName() + ".isUIControllable:\n\t" + e);
return false;
}
}
public boolean isDeviceOnline() {
try {
return getCapability(Twain.CAP_DEVICEONLINE).booleanValue();
} catch (Exception e) {
Twain.signalException(getClass().getName() + ".isOnline:\n\t" + e);
return true;
}
}
public void setShowUserInterface(boolean show) throws TwainException {
setShowUI(show);
}
public void setShowProgressBar(boolean show) throws TwainException {
setCapability(Twain.CAP_INDICATORS, show);
}
public void setResolution(double dpi) throws TwainException {
setCapability(Twain.ICAP_UNITS, Twain.TWUN_INCHES);
setCapability(Twain.ICAP_XRESOLUTION, dpi);
setCapability(Twain.ICAP_YRESOLUTION, dpi);
}
public void setRegionOfInterest(int x, int y, int w, int h) throws TwainException {
if ((x == -1) && (y == -1) && (w == -1) && (h == -1)) {
new TwainImageLayout(this).reset();
} else {
setCapability(Twain.ICAP_UNITS, Twain.TWUN_PIXELS);
TwainImageLayout til = new TwainImageLayout(this);
til.get();
til.setLeft(x);
til.setTop(y);
til.setRight(x + w);
til.setBottom(y + h);
til.set();
}
}
public void setRegionOfInterest(double x, double y, double w, double h) throws TwainException {
if ((x == -1) && (y == -1) && (w == -1) && (h == -1)) {
new TwainImageLayout(this).reset();
} else {
setCapability(Twain.ICAP_UNITS, Twain.TWUN_CENTIMETERS);
TwainImageLayout til = new TwainImageLayout(this);
til.get();
til.setLeft(x / 10.0);
til.setTop(y / 10.0);
til.setRight((x + w) / 10.0);
til.setBottom((y + h) / 10.0);
til.set();
}
}
public void select(String name) throws TwainException {
checkState(3);
TwainSourceManager manager = Twain.getSourceManager();
try {
TwainIdentity device = new TwainIdentity(manager);
device.getFirst();
while (true) {
if (device.getProductName().equals(name)) {
device.identity.copyTo(identity);
break;
}
device.getNext();
}
} catch (TwainEndOfListException treeol) {
throw new TwainException(getClass().getName() + ".select(String name)\n\tCannot find twain data source: '" + name + "'");
}
}
void enable() throws TwainException {
checkState(4);
Twain.negotiateCapabilities(this);
if (getState() < 4) {
return;
}
int xfer = new TwainCapability.XferMech(this).intValue();
if (xfer == Twain.TWSX_NATIVE) {
} else if (xfer == Twain.TWSX_FILE) {
try {
iff = getCapability(Twain.ICAP_IMAGEFILEFORMAT).intValue();
} catch (Exception e) {
iff = Twain.TWFF_BMP;
}
}
// if (isTwain20()) {
// twSemaphore = new Semaphore(0, true);
// twHaveImage = false;
// }
modalUI = 0;
Win32Twain.TW_USERINTERFACE ui = new Win32Twain.TW_USERINTERFACE();
ui.ShowUI = showUI != 0;
ui.hParent = hwnd;
try {
call(Twain.DG_CONTROL, Twain.DAT_USERINTERFACE, Twain.MSG_ENABLEDS, ui);
modalUI = ui.ModalUI ? 1 : 0;
setState(5);
} catch (TwainCheckStatusException trecs) {
setState(5);
} catch (TwainCancelException trec) {
disable();
close();
}
// if (isTwain20()) {
// try {
//
// new Thread(new Runnable() {
// @Override
// public void run() {
// try {
// twSemaphore.tryAcquire(5, TimeUnit.MINUTES);
// twSemaphore.release();
//
// if (twHaveImage) {
// transferImage();
// } else {
//// throw new TwainException("Scan timeout");
// }
//
//
// } catch (Exception e) {
// e.printStackTrace();
// }
// }
// }).start();
//
// } catch (Exception e) {
// e.printStackTrace();
// throw new TwainException(e);
// }
// }
}
private void transfer(TwainTransfer tt) throws TwainException {
try {
byte[] pendingXfers = new byte[6];
do {
setState(6);
TwainUtils.setINT16(pendingXfers, 0, 0);
try {
tt.setCancel(userCancelled);
tt.initiate();
} catch (TwainTransferDoneException tretd) {
setState(7);
tt.finish();
call(Twain.DG_CONTROL, Twain.DAT_PENDINGXFERS, Twain.MSG_ENDXFER, pendingXfers);
if (TwainUtils.getINT16(pendingXfers, 0) == 0) {
setState(5);
}
} catch (TwainUserCancelException tuce) {
call(Twain.DG_CONTROL, Twain.DAT_PENDINGXFERS, Twain.MSG_RESET, pendingXfers);
setState(5);
} catch (TwainCancelException trec) {
tt.cancel();
call(Twain.DG_CONTROL, Twain.DAT_PENDINGXFERS, Twain.MSG_ENDXFER, pendingXfers);
if (TwainUtils.getINT16(pendingXfers, 0) > 0) {
call(Twain.DG_CONTROL, Twain.DAT_PENDINGXFERS, Twain.MSG_RESET, pendingXfers);
}
setState(5);
} catch (TwainException tfe) {
Twain.signalException(getClass().getName() + ".transfer:\n\t" + tfe);
call(Twain.DG_CONTROL, Twain.DAT_PENDINGXFERS, Twain.MSG_ENDXFER, pendingXfers);
if (TwainUtils.getINT16(pendingXfers, 0) > 0) {
call(Twain.DG_CONTROL, Twain.DAT_PENDINGXFERS, Twain.MSG_RESET, pendingXfers);
}
setState(5);
} finally {
tt.cleanup();
}
} while (TwainUtils.getINT16(pendingXfers, 0) != 0);
} finally {
if (userCancelled || (showUI == 0)) {
userCancelled = false;
disable();
close();
}
}
}
void transferImage() throws TwainException {
switch (getXferMech()) {
case Twain.TWSX_NATIVE:
transfer(transferFactory.createNativeTransfer(this));
break;
case Twain.TWSX_FILE:
transfer(transferFactory.createFileTransfer(this));
break;
case Twain.TWSX_MEMORY:
transfer(transferFactory.createMemoryTransfer(this));
break;
default:
break;
}
}
void disable() throws TwainException {
if (state < 5) {
return;
}
byte[] gui = new byte[8];
TwainUtils.setINT16(gui, 0, -1);
TwainUtils.setINT16(gui, 2, 0);
TwainUtils.setINT32(gui, 4, (int) Pointer.nativeValue(hwnd.getPointer()));
call(Twain.DG_CONTROL, Twain.DAT_USERINTERFACE, Twain.MSG_DISABLEDS, gui);
setState(4);
}
@Override
public void close() throws TwainException {
if (state != 4) {
return;
}
// if (isTwain20()) {
// Win32Twain.TW_CALLBACK cb = new Win32Twain.TW_CALLBACK();
// cb.Message = 0;
// cb.Proc = null;//new TwainCallback();
//
// call(Twain.DG_CONTROL, (short) 0x12, (short) 0x902, cb);
// }
super.close();
busy = false;
setState(3);
}
int handleGetMessage(Pointer msgPtr) throws TwainException {
if (state < 5) {
return Twain.TWRC_NOTDSEVENT;
}
try {
Win32Twain.TW_EVENT event = new Win32Twain.TW_EVENT();
event.pEvent = msgPtr;
event.TWMessage = 0;
call(Twain.DG_CONTROL, Twain.DAT_EVENT, Twain.MSG_PROCESSEVENT, event);
int message = event.TWMessage;
switch (message) {
case Twain.MSG_XFERREADY:
transferImage();
break;
case Twain.MSG_CLOSEDSOK:
case Twain.MSG_CLOSEDSREQ:
disable();
close();
break;
case Twain.MSG_DEVICEEVENT:
case Twain.MSG_NULL:
default:
break;
}
return Twain.TWRC_DSEVENT;
} catch (TwainNotDSException trendse) {
return Twain.TWRC_NOTDSEVENT;
}
}
public int getXferMech() throws TwainException {
return new TwainCapability.XferMech(this).intValue();
}
public void setXferMech(int mech) {
try {
switch (mech) {
case Twain.TWSX_NATIVE:
case Twain.TWSX_FILE:
case Twain.TWSX_MEMORY:
break;
default:
mech = Twain.TWSX_NATIVE;
break;
}
TwainCapability tc;
tc = getCapability(Twain.ICAP_XFERMECH, Twain.MSG_GETCURRENT);
if (tc.intValue() != mech) {
tc.setCurrentValue(mech);
if (getCapability(Twain.ICAP_XFERMECH).intValue() != mech) {
Twain.signalException(getClass().getName() + ".setXferMech:\n\tCannot change transfer mechanism to mode=" + mech);
}
}
} catch (TwainException e) {
Twain.signalException(getClass().getName() + ".setXferMech:\n\t" + e);
}
}
public int getImageFileFormat() {
return iff;
}
public void setImageFileFormat(int iff) {
try {
TwainCapability tc;
switch (iff) {
case Twain.TWFF_TIFF:
case Twain.TWFF_BMP:
case Twain.TWFF_JFIF:
case Twain.TWFF_TIFFMULTI:
case Twain.TWFF_PNG:
break;
default:
iff = Twain.TWFF_BMP;
break;
}
tc = getCapability(Twain.ICAP_IMAGEFILEFORMAT, Twain.MSG_GETCURRENT);
if (tc.intValue() != iff) {
tc.setCurrentValue(iff);
if (getCapability(Twain.ICAP_IMAGEFILEFORMAT).intValue() != iff) {
Twain.signalException(getClass().getName() + ".setImageFileFormat:\n\tCannot change file format to format=" + iff);
}
}
} catch (Exception e) {
Twain.signalException(getClass().getName() + ".setImageFileFormat:\n\t" + e);
}
}
}

View File

@ -0,0 +1,173 @@
package org.aohe.core.twain;
import com.sun.jna.platform.win32.WinDef;
import org.aohe.exceptions.TwainEndOfListException;
import org.aohe.exceptions.TwainException;
import org.aohe.exceptions.TwainResultException;
import org.aohe.exceptions.TwainTransferDoneException;
import org.aohe.utils.TwainUtils;
import org.aohe.exceptions.TwainCheckStatusException;
import org.aohe.exceptions.TwainDSException;
import org.aohe.exceptions.TwainNotDSException;
import org.aohe.exceptions.TwainCancelException;
import java.util.List;
public class TwainSourceManager {
public static final String[] INFO = {
"Success",
"Failure due to unknown causes",
"Not enough memory to perform operation",
"No Data Source",
"DS is connected to max possible applications",
"DS or DSM reported internal error",
"Unknown capability",
"",
"",
"Unrecognized MSG DG DAT combination",
"Data parameter out of range",
"DG DAT MSG out of expected sequence",
"Unknown destination Application/Source in DSM_Entry",
"Capability not supported by source",
"Operation not supported by capability",
"Capability has dependancy on other capability",
"File System operation is denied (file is protected)",
"Operation failed because file already exists.",
"File not found",
"Operation failed because directory is not empty",
"The feeder is jammed",
"The feeder detected multiple pages",
"Error writing the file (i.e. disk full conditions)",
"The device went offline prior to or during this operation"
};
private TwainSource source;
public TwainSourceManager(WinDef.HWND hwnd) {
source = new TwainSource(this, hwnd, false);
source.getDefault();
}
String getConditionCodeStr() throws TwainException {
return INFO[getConditionCode()];
}
int getConditionCode() throws TwainException {
byte[] status = new byte[4];
int rc = Twain.callSourceManager(Twain.DG_CONTROL, Twain.DAT_STATUS, Twain.MSG_GET, status);
if (rc != Twain.TWRC_SUCCESS) {
throw new TwainResultException("Cannot retrieve twain source manager's status. RC = " + rc);
}
return TwainUtils.getINT16(status, 0);
}
void call(int dg, int id, int msg, Object obj) throws TwainException {
int rc = Twain.callSourceManager(dg, id, msg, obj);
switch (rc) {
case Twain.TWRC_SUCCESS:
return;
case Twain.TWRC_FAILURE:
throw new TwainException(getClass().getName() + ".call error: " + getConditionCodeStr());
case Twain.TWRC_CHECKSTATUS:
throw new TwainCheckStatusException();
case Twain.TWRC_CANCEL:
throw new TwainCancelException();
case Twain.TWRC_DSEVENT:
throw new TwainDSException();
case Twain.TWRC_NOTDSEVENT:
throw new TwainNotDSException();
case Twain.TWRC_XFERDONE:
throw new TwainTransferDoneException();
case Twain.TWRC_ENDOFLIST:
throw new TwainEndOfListException();
default:
throw new TwainException("Failed to call source. RC = " + rc);
}
}
public TwainSource getSource() {
return source;
}
TwainSource selectSource() throws TwainException {
source.checkState(3);
source.setBusy(true);
try {
source.userSelect();
return source;
} catch (TwainException trec) {
return source;
} finally {
source.setBusy(false);
}
}
void getIdentities(List<TwainIdentity> identities) throws TwainException {
source.checkState(3);
source.setBusy(true);
try {
TwainIdentity identity = new TwainIdentity(this);
identity.getFirst();
identities.add(identity);
while (true) {
identity = new TwainIdentity(this);
identity.getNext();
identities.add(identity);
}
} catch (TwainEndOfListException treeol) {
} catch (TwainException tioe) {
} finally {
source.setBusy(false);
}
}
public TwainSource selectSource(String name) throws TwainException {
source.checkState(3);
source.setBusy(true);
try {
source.select(name);
return source;
} finally {
source.setBusy(false);
}
}
public TwainSource openSource() throws TwainException {
source.checkState(3);
source.setBusy(true);
try {
source.open();
if (!source.isDeviceOnline()) {
source.close();
throw new TwainException("Selected twain source is not online.");
}
source.setState(4);
return source;
} catch (TwainCancelException trec) {
source.setBusy(false);
return source;
} catch (TwainException tioe) {
source.setBusy(false);
throw tioe;
}
}
public void closeSource() throws TwainException {
source.checkState(4);
source.setBusy(true);
try {
source.close();
} catch (TwainCancelException trec) {
source.setBusy(false);
} catch (TwainException tioe) {
source.setBusy(false);
throw tioe;
}
}
}

View File

@ -0,0 +1,14 @@
package org.aohe.core.twain;
import org.aohe.transfer.TwainTransfer;
public interface TwainTransferFactory {
TwainTransfer createNativeTransfer(TwainSource source);
TwainTransfer createFileTransfer(TwainSource source);
TwainTransfer createMemoryTransfer(TwainSource source);
}

View File

@ -0,0 +1,49 @@
package org.aohe.core.twain;
import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinDef;
import com.sun.jna.platform.win32.WinUser;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import static org.aohe.core.twain.Twain.callMapper;
import static org.aohe.core.twain.Twain.execute;
public class TwainWndProc implements WinUser.WindowProc {
private ExecutorService exec = Executors.newCachedThreadPool();
@Override
public WinDef.LRESULT callback(WinDef.HWND hwnd, int uMsg, final WinDef.WPARAM wParam, WinDef.LPARAM lParam) {
switch (uMsg) {
case WinUser.WM_CLOSE:
case WinUser.WM_DESTROY:
if (hwnd.equals(Twain.hwnd)) {
User32.INSTANCE.DestroyWindow(hwnd);
hwnd = null;
Twain.g_AppID = null;
Twain.done();
}
break;
case WinUser.WM_USER: {
final Object o = callMapper.get(lParam.intValue());
if (o != null) {
// exec.submit(new Runnable() {
// @Override
// public void run() {
execute(o, wParam.intValue());
// }
// });
}
}
break;
default:
return User32.INSTANCE.DefWindowProc(hwnd, uMsg, wParam, lParam);
}
return new WinDef.LRESULT(0);
}
}

View File

@ -0,0 +1,10 @@
package org.aohe.exceptions;
public class TwainCancelException extends TwainResultException {
public TwainCancelException() {
super("User cancelled twain operation.");
}
}

View File

@ -0,0 +1,10 @@
package org.aohe.exceptions;
public class TwainCheckStatusException extends TwainResultException {
public TwainCheckStatusException() {
super("\"Source could not fulfill request.");
}
}

View File

@ -0,0 +1,9 @@
package org.aohe.exceptions;
public class TwainDSException extends TwainResultException {
public TwainDSException() {
super("Data source event.");
}
}

View File

@ -0,0 +1,9 @@
package org.aohe.exceptions;
public class TwainDataNotAvailableException extends TwainResultException {
public TwainDataNotAvailableException() {
super("TwainDataNotAvailableException");
}
}

View File

@ -0,0 +1,10 @@
package org.aohe.exceptions;
public class TwainEndOfListException extends TwainResultException {
public TwainEndOfListException() {
super("End of List.");
}
}

View File

@ -0,0 +1,25 @@
package org.aohe.exceptions;
public class TwainException extends Exception {
public TwainException() {
}
public TwainException(String message) {
super(message);
}
public TwainException(String message, Throwable cause) {
super(message, cause);
}
public TwainException(Throwable cause) {
super(cause);
}
public TwainException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}

View File

@ -0,0 +1,10 @@
package org.aohe.exceptions;
public class TwainInfNotSupportedException extends TwainResultException {
public TwainInfNotSupportedException() {
super("InfNotSupported.");
}
}

View File

@ -0,0 +1,10 @@
package org.aohe.exceptions;
public class TwainNotDSException extends TwainResultException {
public TwainNotDSException() {
super("No data source event.");
}
}

View File

@ -0,0 +1,24 @@
package org.aohe.exceptions;
public class TwainResultException extends TwainException {
public TwainResultException() {
}
public TwainResultException(String message) {
super(message);
}
public TwainResultException(String message, Throwable cause) {
super(message, cause);
}
public TwainResultException(Throwable cause) {
super(cause);
}
public TwainResultException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}

View File

@ -0,0 +1,10 @@
package org.aohe.exceptions;
public class TwainTransferDoneException extends TwainResultException {
public TwainTransferDoneException() {
super("Image transfer done.");
}
}

View File

@ -0,0 +1,9 @@
package org.aohe.exceptions;
public class TwainUserCancelException extends TwainResultException {
public TwainUserCancelException() {
super("User cancelled twain operation.");
}
}

View File

@ -0,0 +1,140 @@
package org.aohe.libs;
import com.sun.jna.Library;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import com.sun.jna.ptr.IntByReference;
import java.util.Arrays;
import java.util.List;
public interface Kernel32 extends Library {
boolean Beep(int freq, int duration);
int GetCurrentDirectoryA(int bufLen, byte buffer[]);
boolean SetCurrentDirectoryA(String dir);
int GetLastError();
int GetCurrentProcess();
int GetCurrentProcessId();
int GetTickCount();
int LoadLibraryA(String lib);
Pointer GlobalLock(Pointer hdl);
boolean GlobalUnlock(Pointer hdl);
Pointer GlobalLock(int hdl);
boolean GlobalUnlock(int hdl);
Pointer GlobalAlloc(int flags, int size);
int GlobalFree(Pointer hdl);
int GlobalFree(int hdl);
int GetLogicalDrives();
int GetLogicalDriveStringsA(int bufLen, byte buf[]);
boolean GetVolumeInformationA(String lpRootPathName, byte lpVolumeNameBuffer[], int nVolumeNameSize, int lpVolumeSerialNumber[], int lpMaximumComponentLength[], int lpFileSystemFlags[], byte lpFileSystemNameBuffer[], int nFileSystemNameSize);
int GetDriveTypeA(String drive);
void GetSystemTime(SYSTEMTIME st);
void GetLocalTime(SYSTEMTIME st);
void GetComputerName();
boolean GetProcessTimes(int processHdl, FILETIME creation, FILETIME exit, FILETIME kernel, FILETIME user);
boolean GetSystemTimes(FILETIME idle, FILETIME kernel, FILETIME user);
int CreateFileA(String file, int access, int mode, SECURITY_ATTRIBUTES secAttrs, int disposition, int flagsAndAttribs, int hdlTemplate);
boolean DeviceIoControl(int hdl, int opCode, byte inBuf[], int inBufSize, byte outBuf[], int outBufSize, int bytesReturned[], OVERLAPPED ol);
boolean GetSystemPowerStatus(SYSTEM_POWER_STATUS sps);
boolean GetDiskFreeSpaceA(String s, IntByReference r1, IntByReference r2, IntByReference r3, IntByReference r4);
boolean GetDiskFreeSpaceEx(String s, IntByReference r1, IntByReference r2, IntByReference r3);
public static class SYSTEMTIME extends Structure {
public short wYear;
public short wMonth;
public short wDayOfWeek;
public short wDay;
public short wHour;
public short wMinute;
public short wSecond;
public short wMilliseconds;
@Override
protected List<String> getFieldOrder() {
return Arrays.asList(new String[]{"wYear", "wMonth", "wDayOfWeek", "wDay", "wHour", "wMinute", "wSecond", "wMilliseconds"});
}
}
public static class SYSTEM_POWER_STATUS extends Structure {
public byte ACLineStatus;
public byte BatteryFlag;
public byte BatteryLifePercent;
public byte Reserved1;
public int BatteryLifeTime;
public int BatteryFullLifeTime;
@Override
protected List<String> getFieldOrder() {
return Arrays.asList(new String[]{"ACLineStatus", "BatteryFlag", "BatteryLifePercent", "Reserved1", "BatteryLifeTime", "BatteryFullLifeTime"});
}
}
public static class OVERLAPPED extends Structure {
int Internal;
int InternalHigh;
int Offset;
int OffsetHigh;
int hEvent;
@Override
protected List<String> getFieldOrder() {
return Arrays.asList(new String[]{"Internal", "InternalHigh", "Offset", "OffsetHigh", "hEvent"});
}
}
public static class SECURITY_ATTRIBUTES extends Structure {
int nLength;
Pointer lpSecurityDescriptor;
boolean bInheritHandle;
@Override
protected List<String> getFieldOrder() {
return Arrays.asList(new String[]{"nLength", "lpSecurityDescriptor", "bInheritHandle"});
}
}
public static class FILETIME extends Structure {
public int dwLowDateTime;
public int dwHighDateTime;
@Override
protected List<String> getFieldOrder() {
return Arrays.asList(new String[]{"dwLowDateTime", "dwHighDateTime"});
}
}
}

View File

@ -0,0 +1,94 @@
package org.aohe.libs;
import com.sun.jna.*;
import com.sun.jna.platform.win32.WinDef;
import com.sun.jna.platform.win32.WinUser;
import java.util.Arrays;
import java.util.List;
public interface User32 extends Library {
boolean MessageBeep(int uType);
WinDef.HWND CreateWindowExA(int styleEx, String className, String windowName, int style, int x, int y, int width, int height, int hndParent, int hndMenu, int hndInst, Object parm);
boolean SetWindowPos(WinDef.HWND hWnd, int hWndInsAfter, int x, int y, int cx, int cy, short uFlgs);
boolean SetWindowPos(WinDef.HWND hWnd, WinDef.HWND hWndInsertAfter, int X, int Y, int cx, int cy, int uFlags);
WinDef.ATOM RegisterClassEx(WinUser.WNDCLASSEX lpwcx);
int DestroyWindow(int hdl);
int DestroyWindow(WinDef.HWND hdl);
boolean GetMessageA(MSG lpMsg, int hWnd, int wMsgFilterMin, int wMsgFilterMax);
boolean TranslateMessage(MSG lpMsg);
int DispatchMessageA(MSG lpMsg);
void PostMessage(WinDef.HWND hWnd, int msg, WinDef.WPARAM wParam, WinDef.LPARAM lParam);
public static class POINT extends Structure {
public int x;
public int y;
@Override
protected List<String> getFieldOrder() {
return Arrays.asList(new String[]{"x", "y"});
}
}
public static class MSG extends Structure {
public int hwnd;
public int message;
public short wParm;
public int lParm;
public int time;
public POINT pt;
@Override
protected List<String> getFieldOrder() {
return Arrays.asList(new String[]{"hwnd", "message", "wParm", "lParm", "time", "pt"});
}
}
public static HANDLE INVALID_HANDLE_VALUE = new HANDLE(Pointer.createConstant(Pointer.SIZE == 8 ? -1 : 0xFFFFFFFFL));
public static class HANDLE extends PointerType {
private boolean immutable;
public HANDLE() {
}
public HANDLE(Pointer p) {
setPointer(p);
immutable = true;
}
@Override
public Object fromNative(Object nativeValue, FromNativeContext context) {
Object o = super.fromNative(nativeValue, context);
if (INVALID_HANDLE_VALUE.equals(o)) {
return INVALID_HANDLE_VALUE;
}
return o;
}
@Override
public void setPointer(Pointer p) {
if (immutable) {
throw new UnsupportedOperationException("immutable reference");
}
super.setPointer(p);
}
}
}

View File

@ -0,0 +1,280 @@
package org.aohe.libs;
import com.sun.jna.Callback;
import com.sun.jna.Library;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import com.sun.jna.platform.win32.WinDef;
import java.util.Arrays;
import java.util.List;
public interface Win32Twain extends Library {
public short DSM_Entry(TW_IDENTITY origin, TW_IDENTITY destination, int dg, short dat, short msg, Object p);
public Pointer DSM_Alloc(int len);
public void DSM_Free(Pointer handle);
public Pointer DSM_Lock(Pointer handle);
public boolean DSM_Unlock(Pointer handle);
public static class TW_CALLBACK extends Structure {
public Callback Proc;
public int RefCon;
public short Message;
@Override
protected List<String> getFieldOrder() {
return Arrays.asList(new String[]{"Proc", "RefCon", "Message"});
}
}
public static class TW_STATUS extends Structure {
public short ConditionCode;
public short Reserved;
@Override
protected List<String> getFieldOrder() {
return Arrays.asList(new String[]{"ConditionCode", "Reserved"});
}
}
public static class TW_CAPABILITY extends Structure {
public short Cap;
public short ConType;
public Long Container;
public int reserved;
@Override
protected List<String> getFieldOrder() {
return Arrays.asList(new String[]{"Cap", "ConType", "Container", "reserved"});
}
}
public static class TW_VERSION extends Structure implements Structure.ByValue {
public short MajorNum;
public short MinorNum;
public short Language;
public short Country;
public byte Info[] = new byte[34];
public TW_VERSION(int align) {
super();
setAlignType(align);
}
public TW_VERSION() {
super();
setAlignType(Structure.ALIGN_NONE);
}
@Override
protected List<String> getFieldOrder() {
return Arrays.asList(new String[]{"MajorNum", "MinorNum", "Language", "Country", "Info"});
}
public void setInfo(String m) {
byte[] mb = m.getBytes();
for (int i = 0; i < Math.min(32, mb.length); ++i) {
Info[i] = mb[i];
}
}
public String getInfo() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 32; ++i) {
if (Info[i] == 0) {
break;
}
sb.append((char) Info[i]);
}
return sb.toString();
}
}
public static class TW_IDENTITY extends Structure {
public int Id;
public TW_VERSION Version = new TW_VERSION();
public short ProtocolMajor;
public short ProtocolMinor;
public int SupportedGroups;
public byte Manufacturer[] = new byte[34];
public byte ProductFamily[] = new byte[34];
public byte ProductName[] = new byte[34];
public TW_IDENTITY(int align) {
super();
setAlignType(align);
}
public TW_IDENTITY() {
super();
setAlignType(Structure.ALIGN_NONE);
}
@Override
protected List<String> getFieldOrder() {
return Arrays.asList(new String[]{"Id", "Version", "ProtocolMajor", "ProtocolMinor", "SupportedGroups", "Manufacturer", "ProductFamily", "ProductName"});
}
public void setManufacturer(String m) {
byte mb[] = m.getBytes();
for (int i = 0; i < Math.min(32, mb.length); ++i) {
Manufacturer[i] = mb[i];
}
}
public String getManufacturer() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 32; ++i) {
if (Manufacturer[i] == 0) {
break;
}
sb.append((char) Manufacturer[i]);
}
return sb.toString();
}
public void setProductFamily(String m) {
byte mb[] = m.getBytes();
for (int i = 0; i < Math.min(32, mb.length); ++i) {
ProductFamily[i] = mb[i];
}
}
public String getProductFamily() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 32; ++i) {
if (ProductFamily[i] == 0) {
break;
}
sb.append((char) ProductFamily[i]);
}
return sb.toString();
}
public void setProductName(String m) {
byte mb[] = m.getBytes();
for (int i = 0; i < Math.min(32, mb.length); ++i) {
ProductName[i] = mb[i];
}
}
public String getProductName() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 32; ++i) {
if (ProductName[i] == 0) {
break;
}
sb.append((char) ProductName[i]);
}
return sb.toString();
}
public void copyTo(TW_IDENTITY identity) {
identity.Id = Id;
System.arraycopy(Manufacturer, 0, identity.Manufacturer, 0, Manufacturer.length);
System.arraycopy(ProductFamily, 0, identity.ProductFamily, 0, ProductFamily.length);
System.arraycopy(ProductName, 0, identity.ProductName, 0, ProductName.length);
System.arraycopy(Version.Info, 0, identity.Version.Info, 0, Version.Info.length);
identity.Version.Country = Version.Country;
identity.Version.Language = Version.Language;
identity.Version.MajorNum = Version.MajorNum;
identity.Version.MinorNum = Version.MinorNum;
identity.ProtocolMajor = ProtocolMajor;
identity.ProtocolMinor = ProtocolMinor;
identity.SupportedGroups = SupportedGroups;
}
}
public static class TW_FIX32 extends Structure {
public short Whole;
public short Frac;
@Override
protected List<String> getFieldOrder() {
return Arrays.asList(new String[]{"Whole", "Frac"});
}
}
public static class TW_USERINTERFACE extends Structure {
public boolean ShowUI;
public boolean ModalUI;
public WinDef.HWND hParent;
@Override
protected List<String> getFieldOrder() {
return Arrays.asList(new String[]{"ShowUI", "ModalUI", "hParent"});
}
}
public static class TW_PENDINGXFERS extends Structure {
public int EOJ;
public int Reserved;
@Override
protected List<String> getFieldOrder() {
return Arrays.asList(new String[]{"EOJ", "Reserved"});
}
}
public static class TW_EVENT extends Structure {
public Pointer pEvent;
public short TWMessage;
@Override
protected List<String> getFieldOrder() {
return Arrays.asList(new String[]{"pEvent", "TWMessage"});
}
}
public static class TW_MEMORY extends Structure {
public int Flags;
public int Length;
public Pointer TheMem;
@Override
protected List<String> getFieldOrder() {
return Arrays.asList(new String[]{"Flags", "Length", "TheMem"});
}
}
public static class TW_IMAGEMEMXFER extends Structure implements Structure.ByValue {
public short Compression;
public int BytesPerRow;
public int Columns;
public int Rows;
public int XOffset;
public int YOffset;
public int BytesWritten;
public TW_MEMORY Memory;
@Override
protected List<String> getFieldOrder() {
return Arrays.asList(new String[]{"Compression", "BytesPerRow", "Columns", "Rows", "XOffset", "YOffset", "BytesWritten", "Memory"});
}
}
}

View File

@ -0,0 +1,39 @@
package org.aohe.result;
import cn.hutool.json.JSONUtil;
import lombok.Data;
@Data
public class R<T> {
private String code;
private String msg;
private T data;
private boolean success;
public R (String code, String msg, T data, boolean success) {
this.code = code;
this.msg = msg;
this.data = data;
this.success = success;
}
public static R ok(Object data) {
return new R<>("200", "ok", data, true);
}
public static R ok() {
return new R<>("200", "ok", null, true);
}
public static R fail(String msg) {
return new R<>("500", msg, null, false);
}
public String toJsonStr() {
return JSONUtil.toJsonStr(this);
}
}

View File

@ -0,0 +1,189 @@
package org.aohe.scan;
import org.aohe.core.twain.*;
import org.aohe.exceptions.TwainException;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class Source implements TwainListener {
private double dpi = 300.0;
private ColorMode color = ColorMode.GRAYSCALE;
private boolean autoDocumentFeeder = true;
private boolean systemUI = true;
private String name;
private final Object syncObject = new Object();
private ExecutorService exec;
private List<File> fileList = new ArrayList<>();
public Source() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getDpi() {
return dpi;
}
public void setDpi(double dpi) {
this.dpi = dpi;
}
public ColorMode getColor() {
return color;
}
public void setColor(ColorMode color) {
this.color = color;
}
public boolean isAutoDocumentFeeder() {
return autoDocumentFeeder;
}
public void setAutoDocumentFeeder(boolean autoDocumentFeeder) {
this.autoDocumentFeeder = autoDocumentFeeder;
}
public boolean isSystemUI() {
return systemUI;
}
public void setSystemUI(boolean systemUI) {
this.systemUI = systemUI;
}
@Override
public void update(TwainIOMetadata.Type type, TwainIOMetadata metadata) {
// System.out.println(type + " -> " + metadata.getState() + ": " + metadata.getStateStr());
if (type == TwainIOMetadata.NEGOTIATE && metadata.getState() == 4) {
setupSource(metadata.getSource());
} else if (type == TwainIOMetadata.ACQUIRED && metadata.getState() == 7) {
pushImage(metadata.getImage());
metadata.setImage(null);
} else if (type == TwainIOMetadata.STATECHANGE && metadata.getState() == 3 && metadata.getLastState() == 4) {
jobDone();
}
}
private void setupSource(TwainSource source) {
try {
//source.setShowProgressBar(true);
source.setShowUI(systemUI);
source.setImageFileFormat(7);
if (!systemUI) {
// source.setShowUI(false);
source.setResolution(dpi);
TwainCapability pt = source.getCapability(Twain.ICAP_PIXELTYPE);
switch (color) {
case BW:
pt.setCurrentValue(0);
break;
case GRAYSCALE:
pt.setCurrentValue(1);
break;
case COLOR:
pt.setCurrentValue(2);
break;
}
source.setCapability(Twain.CAP_FEEDERENABLED, autoDocumentFeeder ? 1 : 0);
}
} catch (TwainException e) {
e.printStackTrace();
}
}
private void pushImage(final BufferedImage image) {
exec.submit(() -> {
try {
File f = File.createTempFile("img", ".jpg");
ImageIO.write(image, "JPG", f);
fileList.add(f);
} catch (IOException ignored) {
}
});
}
private void jobDone() {
exec.shutdown();
try {
while (!exec.awaitTermination(100, TimeUnit.MILLISECONDS)) {
}
} catch (InterruptedException ex) {
}
synchronized (syncObject) {
syncObject.notifyAll();
}
exec = null;
}
public List<File> scan() {
exec = Executors.newFixedThreadPool(1);
TwainScanner scanner = TwainScanner.getScanner();
try {
scanner.select(name);//
scanner.addListener(this);
scanner.acquire();
synchronized (syncObject) {
syncObject.wait();
}
} catch (TwainException | InterruptedException e) {
}
return fileList;
}
public List<File> scan(TwainScanner scanner) {
exec = Executors.newFixedThreadPool(1);
try {
systemUI = false;
scanner.addListener(this);
scanner.acquire();
synchronized (syncObject) {
syncObject.wait();
}
} catch (TwainException | InterruptedException e) {
}
return fileList;
}
public static enum ColorMode {
BW,
GRAYSCALE,
COLOR
}
}

View File

@ -0,0 +1,39 @@
package org.aohe.scan;
import org.aohe.core.twain.Twain;
import org.aohe.core.twain.TwainScanner;
import org.aohe.exceptions.TwainException;
import java.util.ArrayList;
import java.util.List;
public class SourceManager {
private static SourceManager instance;
public static SourceManager instance() {
if (instance == null) {
instance = new SourceManager();
}
return instance;
}
public List<Source> getSources() throws TwainException {
List<Source> ret = new ArrayList<>();
for (String s : TwainScanner.getScanner().getDeviceNames()) {
Source source = new Source();
source.setName(s);
ret.add(source);
}
return ret;
}
public void freeResources() {
Twain.done();
}
}

View File

@ -0,0 +1,76 @@
package org.aohe.transfer;
import org.aohe.core.twain.Twain;
import org.aohe.core.twain.TwainSource;
import org.aohe.exceptions.TwainException;
import org.aohe.utils.TwainUtils;
import java.io.File;
public class TwainFileTransfer extends TwainTransfer {
protected File file;
public TwainFileTransfer(TwainSource source) {
super(source);
file = null;
}
protected int getImageFileFormat() {
return source.getImageFileFormat();
}
public void setFile(File f) {
file = f;
}
public File getFile() {
if (file == null) {
String ext = Twain.ImageFileFormatExts[getImageFileFormat()];
try {
File dir = new File(System.getProperty("user.home"), "mmsc/tmp");
dir.mkdirs();
file = File.createTempFile("mmsctwain", ext, dir);
} catch (Exception e) {
file = new File("c:\\mmsctwain." + ext);
}
}
return file;
}
@Override
public void initiate() throws TwainException {
super.initiate();
String file = getFile().getPath();
int iff = getImageFileFormat();
byte[] setup = new byte[260];
TwainUtils.setString(setup, 0, file);
TwainUtils.setINT16(setup, 256, iff);
TwainUtils.setINT16(setup, 258, 0);
source.call(Twain.DG_CONTROL, Twain.DAT_SETUPFILEXFER, Twain.MSG_SET, setup);
source.call(Twain.DG_IMAGE, Twain.DAT_IMAGEFILEXFER, Twain.MSG_GET, null);
}
@Override
public void finish() throws TwainException {
Twain.transferFileImage(file);
}
@Override
public void cancel() throws TwainException {
if ((file != null) && file.exists()) {
file.delete();
}
}
@Override
public void cleanup() throws TwainException {
setFile(null);
}
}

View File

@ -0,0 +1,107 @@
package org.aohe.transfer;
import org.aohe.core.twain.Twain;
import org.aohe.core.twain.TwainSource;
import org.aohe.exceptions.TwainException;
import org.aohe.utils.TwainUtils;
public class TwainMemoryTransfer extends TwainTransfer {
private final byte[] imx = new byte[48];
private Info info;
protected int minBufSize = -1;
protected int maxBufSize = -1;
protected int preferredSize = -1;
public TwainMemoryTransfer(TwainSource source) {
super(source);
}
protected void retrieveBufferSizes() throws TwainException {
byte[] setup = new byte[12];
TwainUtils.setINT32(setup, 0, minBufSize);
TwainUtils.setINT32(setup, 4, maxBufSize);
TwainUtils.setINT32(setup, 8, preferredSize);
source.call(Twain.DG_CONTROL, Twain.DAT_SETUPMEMXFER, Twain.MSG_GET, setup);
minBufSize = TwainUtils.getINT32(setup, 0);
maxBufSize = TwainUtils.getINT32(setup, 4);
preferredSize = TwainUtils.getINT32(setup, 8);
}
@Override
public void initiate() throws TwainException {
super.initiate();
retrieveBufferSizes();
Twain.nnew(imx, preferredSize);
byte[] buf = new byte[preferredSize];
info = new Info(imx, buf);
while (true) {
source.call(Twain.DG_IMAGE, Twain.DAT_IMAGEMEMXFER, Twain.MSG_GET, imx);
int bytesWritten = TwainUtils.getINT32(imx, 22);
int bytesCopied = Twain.ncopy(buf, imx, bytesWritten);
if (bytesCopied == bytesWritten) {
Twain.transferMemoryBuffer(info);
}
}
}
@Override
public void finish() throws TwainException {
int bytesWritten = TwainUtils.getINT32(imx, 22);
int bytesCopied = Twain.ncopy(info.getBuffer(), imx, bytesWritten);
Twain.transferMemoryBuffer(info);
}
@Override
public void cleanup() throws TwainException {
Twain.ndelete(imx);
}
public static class Info {
private byte[] imx;
private byte[] buf;
private int len;
Info(byte[] imx, byte[] buf) {
this.imx = imx;
this.buf = buf;
}
public byte[] getBuffer() {
return buf;
}
public int getCompression() {
return TwainUtils.getINT16(imx, 0);
}
public int getBytesPerRow() {
return TwainUtils.getINT32(imx, 2);
}
public int getWidth() {
return TwainUtils.getINT32(imx, 6);
}
public int getHeight() {
return TwainUtils.getINT32(imx, 10);
}
public int getTop() {
return TwainUtils.getINT32(imx, 14);
}
public int getLeft() {
return TwainUtils.getINT32(imx, 18);
}
public int getLength() {
return TwainUtils.getINT32(imx, 22);
}
}
}

View File

@ -0,0 +1,33 @@
package org.aohe.transfer;
import org.aohe.core.twain.Twain;
import org.aohe.core.twain.TwainSource;
import org.aohe.exceptions.TwainException;
import org.aohe.utils.TwainUtils;
/**
*
* @author lucifer
*/
public class TwainNativeTransfer extends TwainTransfer {
private final byte[] imageHandle = new byte[8];
public TwainNativeTransfer(TwainSource source) {
super(source);
}
@Override
public void initiate() throws TwainException {
super.initiate();
source.call(Twain.DG_IMAGE, Twain.DAT_IMAGENATIVEXFER, Twain.MSG_GET, imageHandle);
}
@Override
public void finish() throws TwainException {
int handle = TwainUtils.getINT32(imageHandle, 0);
Twain.transferNativeImage(handle);
}
}

View File

@ -0,0 +1,42 @@
package org.aohe.transfer;
import org.aohe.core.twain.Twain;
import org.aohe.core.twain.TwainSource;
import org.aohe.exceptions.TwainException;
import org.aohe.exceptions.TwainUserCancelException;
public class TwainTransfer {
protected TwainSource source;
protected boolean isCancelled;
public TwainTransfer(TwainSource source) {
this.source = source;
isCancelled = false;
}
public void initiate() throws TwainException {
commitCancel();
}
public void setCancel(boolean isCancelled) {
this.isCancelled = isCancelled;
}
protected void commitCancel() throws TwainException {
if (isCancelled && (source.getState() == Twain.STATE_TRANSFERREADY)) {
throw new TwainUserCancelException();
}
}
public void finish() throws TwainException {
}
public void cancel() throws TwainException {
}
public void cleanup() throws TwainException {
}
}

View File

@ -0,0 +1,64 @@
package org.aohe.utils;
import org.aohe.core.twain.Twain;
import org.aohe.core.twain.TwainScanner;
import org.aohe.core.twain.TwainSource;
import org.aohe.exceptions.TwainException;
public class TwainUtils {
public static int getINT16(byte[] buf, int off) {
return (buf[off++] & 0x00FF) | (buf[off] << 8);
}
public static void setINT16(byte[] buf, int off, int i) {
buf[off++] = (byte) i;
buf[off++] = (byte) (i >> 8);
}
public static int getINT32(byte[] buf, int off) {
return (buf[off++] & 0x00FF) | ((buf[off++] & 0x00FF) << 8) | ((buf[off++] & 0x00FF) << 16) | (buf[off] << 24);
}
public static void setINT32(byte[] buf, int off, int i) {
buf[off++] = (byte) i;
buf[off++] = (byte) (i >> 8);
buf[off++] = (byte) (i >> 16);
buf[off++] = (byte) (i >> 24);
}
public static long getINT64(byte[] buf, int off) {
return (buf[off++] & 0x00FF) | ((buf[off++] & 0x00FF) << 8) | ((buf[off++] & 0x00FF) << 16) | ((buf[off++] & 0x00FF) << 24)
| ((buf[off++] & 0x00FF) << 32) | ((buf[off++] & 0x00FF) << 40) | ((buf[off++] & 0x00FF) << 48) | (buf[off] << 56);
}
public static void setINT64(byte[] buf, int off, long i) {
buf[off++] = (byte) i;
buf[off++] = (byte) (i >> 8);
buf[off++] = (byte) (i >> 16);
buf[off++] = (byte) (i >> 24);
buf[off++] = (byte) (i >> 32);
buf[off++] = (byte) (i >> 40);
buf[off++] = (byte) (i >> 48);
buf[off++] = (byte) (i >> 56);
}
public static double getFIX32(byte[] buf, int off) {
int whole = ((buf[off++] & 0x00FF) | (buf[off++] << 8));
int frac = ((buf[off++] & 0x00FF) | ((buf[off] & 0x00FF) << 8));
return ((double) whole) + ((double) frac) / 65536.0;
}
public static void setFIX32(byte[] buf, int off, double d) {
int value = (int) (d * 65536.0 + ((d < 0) ? (-0.5) : 0.5));
setINT16(buf, off, value >> 16);
setINT16(buf, off + 2, value & 0x0000FFFF);
}
public static void setString(byte[] buf, int off, String s) {
System.arraycopy(s.getBytes(), 0, buf, 0, s.length());
}
}

View File

@ -0,0 +1,70 @@
package org.aohe.variable;
import java.util.ArrayList;
import java.util.List;
import org.aohe.core.twain.Twain;
import org.aohe.exceptions.TwainException;
import org.aohe.utils.TwainUtils;
public class TwainArray extends TwainContainer {
int count;
List<Object> items = new ArrayList<>();
public TwainArray(int cap, byte[] container) {
super(cap, container);
count = TwainUtils.getINT32(container, 2);
for (int i = 0, off = 6; i < count; i++) {
items.add(getObjectAt(container, off));
off += TYPE_SIZES[type];
}
}
@Override
public int getType() {
return Twain.TWON_ARRAY;
}
@Override
public byte[] getBytes() {
int count = items.size();
int len = 6 + count * TYPE_SIZES[type];
byte[] container = new byte[len];
TwainUtils.setINT16(container, 0, type);
TwainUtils.setINT32(container, 2, count);
for (int i = 0, off = 6; i < count; i++) {
setObjectAt(container, off, items.get(i));
off += TYPE_SIZES[type];
}
return container;
}
@Override
public Object getCurrentValue() throws TwainException {
throw new TwainException(getClass().getName() + ".getCurrentValue:\n\tnot applicable");
}
@Override
public void setCurrentValue(Object obj) throws TwainException {
throw new TwainException(getClass().getName() + ".setCurrentValue:\n\tnot applicable");
}
@Override
public Object getDefaultValue() throws TwainException {
throw new TwainException(getClass().getName() + ".getDefaultValue:\n\tnot applicable");
}
@Override
public void setDefaultValue(Object obj) throws TwainException {
throw new TwainException(getClass().getName() + ".setDefaultValue:\n\tnot applicable");
}
@Override
public <T> T[] getItems() {
return (T[]) items.toArray();
}
}

View File

@ -0,0 +1,295 @@
/*
* Copyright 2018 (c) Denis Andreev (lucifer).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.aohe.variable;
import org.aohe.core.twain.Twain;
import org.aohe.exceptions.TwainException;
import org.aohe.utils.TwainUtils;
import java.awt.geom.Rectangle2D;
public abstract class TwainContainer {
public static final int[] TYPE_SIZES = {
1, 2, 4,
1, 2, 4,
2, 4, 16,
34, 66, 130, 256,
1026, 1024
};
protected int cap;
protected int type;
TwainContainer(int cap, byte[] container) {
this.cap = cap;
this.type = TwainUtils.getINT16(container, 0);
}
TwainContainer(int cap, int type) {
this.cap = cap;
this.type = type;
}
public int getCapabilityId() {
return cap;
}
public abstract int getType();
public abstract byte[] getBytes();
public int getItemType() {
return type;
}
abstract public <T> T[] getItems();
private boolean booleanValue(Object obj) throws TwainException {
if (obj instanceof Number) {
return (((Number) obj).intValue() != 0);
} else if (obj instanceof Boolean) {
return ((Boolean) obj).booleanValue();
} else if (obj instanceof String) {
return Boolean.valueOf((String) obj).booleanValue();
}
throw new TwainException(getClass().getName() + ".booleanValue:\n\tUnsupported data type: " + obj.getClass().getName());
}
private int intValue(Object obj) throws TwainException {
if (obj instanceof Number) {
return ((Number) obj).intValue();
} else if (obj instanceof Boolean) {
return ((((Boolean) obj).booleanValue()) ? 1 : 0);
} else if (obj instanceof String) {
String s = (String) obj;
try {
return Integer.parseInt(s);
} catch (Exception e) {
throw new TwainException(getClass().getName() + ".intValue:\n\tCannot convert string [\"" + s + "\"] to int.");
}
}
throw new TwainException(getClass().getName() + ".intValue:\n\tUnsupported data type: " + obj.getClass().getName());
}
private double doubleValue(Object obj) throws TwainException {
if (obj instanceof Number) {
return ((Number) obj).doubleValue();
} else if (obj instanceof Boolean) {
return ((((Boolean) obj).booleanValue()) ? 1 : 0);
} else if (obj instanceof String) {
String s = (String) obj;
try {
return Double.parseDouble(s);
} catch (Exception e) {
throw new TwainException(getClass().getName() + ".doubleValue:\n\tCannot convert string [\"" + s + "\"] to double.");
}
}
throw new TwainException(getClass().getName() + ".doubleValue:\n\tUnsupported data type: " + obj.getClass().getName());
}
abstract public Object getCurrentValue() throws TwainException;
public boolean booleanValue() throws TwainException {
return booleanValue(getCurrentValue());
}
public int intValue() throws TwainException {
return intValue(getCurrentValue());
}
public double doubleValue() throws TwainException {
return doubleValue(getCurrentValue());
}
abstract public void setCurrentValue(Object v) throws TwainException;
public void setCurrentValue(boolean v) throws TwainException {
setCurrentValue(new Boolean(v));
}
public void setCurrentValue(int v) throws TwainException {
setCurrentValue(new Integer(v));
}
public void setCurrentValue(double v) throws TwainException {
setCurrentValue(new Double(v));
}
abstract public Object getDefaultValue() throws TwainException;
public boolean booleanDefaultValue() throws TwainException {
return booleanValue(getDefaultValue());
}
public int intDefaultValue() throws TwainException {
return intValue(getDefaultValue());
}
public double doubleDefaultValue() throws TwainException {
return doubleValue(getDefaultValue());
}
abstract public void setDefaultValue(Object v) throws TwainException;
public void setDefaultValue(boolean v) throws TwainException {
setDefaultValue(new Boolean(v));
}
public void setDefaultValue(int v) throws TwainException {
setDefaultValue(new Integer(v));
}
public void setDefaultValue(double v) throws TwainException {
setDefaultValue(new Double(v));
}
protected Object get32BitObjectAt(byte[] container, int index) {
switch (type) {
case Twain.TWTY_INT8:
case Twain.TWTY_INT16:
case Twain.TWTY_INT32:
return TwainUtils.getINT32(container, index);
case Twain.TWTY_UINT8:
return TwainUtils.getINT32(container, index) & 0x000000FF;
case Twain.TWTY_UINT16:
return TwainUtils.getINT32(container, index) & 0x0000FFFF;
case Twain.TWTY_UINT32:
return ((long) TwainUtils.getINT32(container, index)) & 0x00000000FFFFFFFFL;
case Twain.TWTY_BOOL:
return (TwainUtils.getINT32(container, index) != 0);
case Twain.TWTY_FIX32:
return TwainUtils.getFIX32(container, index);
case Twain.TWTY_FRAME:
case Twain.TWTY_STR32:
case Twain.TWTY_STR64:
case Twain.TWTY_STR128:
case Twain.TWTY_STR255:
case Twain.TWTY_STR1024:
case Twain.TWTY_UNI512:
return TwainUtils.getINT32(container, index);
default:
}
return null;
}
protected void set32BitObjectAt(byte[] container, int index, Object item) {
if (item instanceof Integer) {
int v = ((Integer) item);
switch (type) {
case Twain.TWTY_FIX32:
TwainUtils.setFIX32(container, index, v);
break;
case Twain.TWTY_BOOL:
TwainUtils.setINT32(container, index, (v == 0) ? 0 : 1);
break;
default:
TwainUtils.setINT32(container, index, v);
break;
}
} else if (item instanceof Double) {
double v = ((Double) item);
switch (type) {
case Twain.TWTY_FIX32:
TwainUtils.setFIX32(container, index, v);
break;
case Twain.TWTY_BOOL:
TwainUtils.setINT32(container, index, (v == 0) ? 0 : 1);
break;
default:
TwainUtils.setINT32(container, index, (int) v);
break;
}
} else if (item instanceof Boolean) {
int v = (((Boolean) item)) ? 1 : 0;
if (type == Twain.TWTY_FIX32) {
TwainUtils.setFIX32(container, index, v);
} else {
TwainUtils.setINT32(container, index, v);
}
} else if (item instanceof String) {
if (type == Twain.TWTY_FIX32) {
this.set32BitObjectAt(container, index, new Double((String) item));
} else {
this.set32BitObjectAt(container, index, new Integer((String) item));
}
}
}
protected Object getObjectAt(byte[] container, int index) {
switch (type) {
case Twain.TWTY_INT8:
return new Integer(container[index]);
case Twain.TWTY_INT16:
return TwainUtils.getINT16(container, index);
case Twain.TWTY_INT32:
return TwainUtils.getINT32(container, index);
case Twain.TWTY_UINT8:
return container[index] & 0x000000FF;
case Twain.TWTY_UINT16:
return TwainUtils.getINT16(container, index) & 0x0000FFFF;
case Twain.TWTY_UINT32:
return ((long) TwainUtils.getINT32(container, index)) & 0x00000000FFFFFFFFL;
case Twain.TWTY_BOOL:
return (TwainUtils.getINT16(container, index) != 0);
case Twain.TWTY_FIX32:
return TwainUtils.getFIX32(container, index);
case Twain.TWTY_FRAME:
double x = TwainUtils.getFIX32(container, index); // left
double y = TwainUtils.getFIX32(container, index + 4); // top
double w = TwainUtils.getFIX32(container, index + 8) - x; // right
double h = TwainUtils.getFIX32(container, index + 12) - y; // bottom
return new Rectangle2D.Double(x, y, w, h);
case Twain.TWTY_STR32:
case Twain.TWTY_STR64:
case Twain.TWTY_STR128:
case Twain.TWTY_STR255:
String s = "";
for (int i = 0; (container[index + i] != 0) && (i < TYPE_SIZES[type]); i++) {
s += (char) container[index + i];
}
return s;
default:
}
return null;
}
private void set16BitObjectAt(byte[] container, int index, Object item) {
if (item instanceof Number) {
int v = (((Number) item).intValue());
TwainUtils.setINT16(container, index, v);
} else if (item instanceof Boolean) {
int v = (((Boolean) item)) ? 1 : 0;
TwainUtils.setINT16(container, index, v);
}
}
protected void setObjectAt(byte[] container, int index, Object item) {
switch (type) {
case Twain.TWTY_INT16:
case Twain.TWTY_UINT16:
set16BitObjectAt(container, index, item);
break;
case Twain.TWTY_FIX32:
case Twain.TWTY_INT32:
case Twain.TWTY_UINT32:
set32BitObjectAt(container, index, item);
break;
default:
}
}
}

View File

@ -0,0 +1,92 @@
package org.aohe.variable;
import org.aohe.core.twain.Twain;
import org.aohe.exceptions.TwainException;
import org.aohe.utils.TwainUtils;
import java.util.ArrayList;
import java.util.List;
public class TwainEnumeration extends TwainContainer {
int count;
int currentIndex;
int defaultIndex;
List<Object> items = new ArrayList<>();
public TwainEnumeration(int cap, byte[] container) {
super(cap, container);
count = TwainUtils.getINT32(container, 2);
currentIndex = TwainUtils.getINT32(container, 6);
defaultIndex = TwainUtils.getINT32(container, 10);
for (int i = 0, off = 14; i < count; i++) {
items.add(getObjectAt(container, off));
off += TYPE_SIZES[type];
}
}
@Override
public int getType() {
return Twain.TWON_ENUMERATION;
}
@Override
public <T> T[] getItems() {
return (T[]) items.toArray();
}
@Override
public byte[] getBytes() {
int count = items.size();
int len = 14 + count * TYPE_SIZES[type];
byte[] container = new byte[len];
TwainUtils.setINT16(container, 0, type);
TwainUtils.setINT32(container, 2, count);
TwainUtils.setINT32(container, 6, currentIndex);
TwainUtils.setINT32(container, 10, defaultIndex);
for (int i = 0, off = 14; i < count; i++) {
setObjectAt(container, off, items.get(i));
off += TYPE_SIZES[type];
}
return container;
}
@Override
public Object getCurrentValue() throws TwainException {
return items.get(currentIndex);
}
@Override
public void setCurrentValue(Object obj) throws TwainException {
int count = items.size();
for (int i = 0; i < count; i++) {
Object item = items.get(i);
if (obj.equals(item)) {
currentIndex = i;
return;
}
}
throw new TwainException(getClass().getName() + ".setCurrentValue:\n\tCould not find " + obj.toString());
}
@Override
public Object getDefaultValue() throws TwainException {
return items.get(defaultIndex);
}
@Override
public void setDefaultValue(Object obj) throws TwainException {
int count = items.size();
for (int i = 0; i < count; i++) {
Object item = items.get(i);
if (obj.equals(item)) {
defaultIndex = i;
return;
}
}
throw new TwainException(getClass().getName() + ".setDefaultValue:\n\tCould not find " + obj.toString());
}
}

View File

@ -0,0 +1,55 @@
package org.aohe.variable;
import org.aohe.core.twain.Twain;
import org.aohe.exceptions.TwainException;
import org.aohe.utils.TwainUtils;
public class TwainOneValue extends TwainContainer {
Object item;
public TwainOneValue(int cap, byte[] container) {
super(cap, container);
item = get32BitObjectAt(container, 2);
}
@Override
public int getType() {
return Twain.TWON_ONEVALUE;
}
@Override
public byte[] getBytes() {
byte[] container = new byte[6];
TwainUtils.setINT16(container, 0, type);
set32BitObjectAt(container, 2, item);
return container;
}
@Override
public Object getCurrentValue() throws TwainException {
return item;
}
@Override
public void setCurrentValue(Object obj) throws TwainException {
item = obj;
}
@Override
public Object getDefaultValue() throws TwainException {
return item;
}
@Override
public void setDefaultValue(Object obj) throws TwainException {
item = obj;
}
@Override
public <T> T[] getItems() {
Object[] items = new Object[1];
items[0] = item;
return (T[]) items;
}
}

View File

@ -0,0 +1,70 @@
package org.aohe.variable;
import org.aohe.core.twain.Twain;
import org.aohe.exceptions.TwainException;
import org.aohe.utils.TwainUtils;
public class TwainRange extends TwainContainer {
private final Object minValue;
private final Object maxValue;
private final Object stepSize;
private Object defaultValue;
private Object currentValue;
public TwainRange(int cap, byte[] container) {
super(cap, container);
minValue = get32BitObjectAt(container, 2);
maxValue = get32BitObjectAt(container, 6);
stepSize = get32BitObjectAt(container, 10);
defaultValue = get32BitObjectAt(container, 14);
currentValue = get32BitObjectAt(container, 18);
}
@Override
public int getType() {
return Twain.TWON_RANGE;
}
@Override
public byte[] getBytes() {
byte[] container = new byte[22];
TwainUtils.setINT16(container, 0, type);
set32BitObjectAt(container, 2, minValue);
set32BitObjectAt(container, 6, maxValue);
set32BitObjectAt(container, 10, stepSize);
set32BitObjectAt(container, 14, defaultValue);
set32BitObjectAt(container, 18, currentValue);
return container;
}
@Override
public Object getCurrentValue() throws TwainException {
return currentValue;
}
@Override
public void setCurrentValue(Object obj) throws TwainException {
currentValue = obj;
}
@Override
public Object getDefaultValue() throws TwainException {
return defaultValue;
}
@Override
public void setDefaultValue(Object obj) throws TwainException {
defaultValue = obj;
}
@Override
public Object[] getItems() {
Object[] items = new Object[1];
items[0] = currentValue;
return items;
}
}

View File

@ -0,0 +1,70 @@
//package org.aohe.web;
//
//
//import cn.hutool.log.Log;
//import cn.hutool.log.LogFactory;
//import cn.hutool.log.StaticLog;
//import org.aohe.result.R;
//import org.java_websocket.WebSocket;
//import org.java_websocket.handshake.ClientHandshake;
//import org.java_websocket.server.WebSocketServer;
//
//import java.net.InetSocketAddress;
//import java.net.UnknownHostException;
//
//import static org.aohe.control.Operational.selectOperational;
//
//public class SocketServer extends WebSocketServer {
//
// private static final Log log = LogFactory.get();
//
// public SocketServer(int port) throws UnknownHostException {
// super(new InetSocketAddress(port));
// }
//
// public SocketServer(InetSocketAddress address) {
// super(address);
// }
//
// @Override
// public void onOpen(WebSocket conn, ClientHandshake handshake) {
// //conn.send("Welcome to the server!"); // This method sends a message to the new client
// //broadcast("new connection: " + handshake.getResourceDescriptor()); // This method sends a message to all clients connected
// //System.out.println(conn.getRemoteSocketAddress().getAddress().getHostAddress() + " entered the room!");
// StaticLog.info("ws用户已连接");
// }
//
// @Override
// public void onClose(WebSocket conn, int code, String reason, boolean remote) {
// StaticLog.info("ws用户关闭连接");
// //这里执行关闭扫描仪连接
// }
//
// @Override
// public void onMessage(WebSocket conn, String message) {
// StaticLog.info("用户发送了数据:\n"+message);
// conn.send(selectOperational(message));
// }
//
// @Override
// public void onError(WebSocket conn, Exception ex) {
// ex.printStackTrace();
// if (conn != null) {
// conn.send(R.fail("error").toJsonStr());
// //绑定不到就退出
// //System.exit(0);
// // some errors like port binding failed may not be assignable to a specific
// // websocket
// }
//
// }
//
// @Override
// public void onStart() {
// System.out.println("Server started!");
// setConnectionLostTimeout(0);
// setConnectionLostTimeout(100);
//
// }
//
//}

View File

@ -0,0 +1,3 @@
Manifest-Version: 1.0
Main-Class: org.aohe.Main

View File

@ -0,0 +1,175 @@
[
{
"name":"[Ljava.lang.Object;"
},
{
"name":"com.sun.jna.Callback"
},
{
"name":"com.sun.jna.CallbackProxy",
"methods":[{"name":"callback","parameterTypes":["java.lang.Object[]"] }]
},
{
"name":"com.sun.jna.CallbackReference",
"methods":[{"name":"getCallback","parameterTypes":["java.lang.Class","com.sun.jna.Pointer","boolean"] }, {"name":"getFunctionPointer","parameterTypes":["com.sun.jna.Callback","boolean"] }, {"name":"getNativeString","parameterTypes":["java.lang.Object","boolean"] }, {"name":"initializeThread","parameterTypes":["com.sun.jna.Callback","com.sun.jna.CallbackReference$AttachOptions"] }]
},
{
"name":"com.sun.jna.CallbackReference$AttachOptions"
},
{
"name":"com.sun.jna.IntegerType",
"fields":[{"name":"value"}]
},
{
"name":"com.sun.jna.JNIEnv"
},
{
"name":"com.sun.jna.Native",
"methods":[{"name":"dispose","parameterTypes":[] }, {"name":"fromNative","parameterTypes":["com.sun.jna.FromNativeConverter","java.lang.Object","java.lang.reflect.Method"] }, {"name":"fromNative","parameterTypes":["java.lang.Class","java.lang.Object"] }, {"name":"fromNative","parameterTypes":["java.lang.reflect.Method","java.lang.Object"] }, {"name":"nativeType","parameterTypes":["java.lang.Class"] }, {"name":"toNative","parameterTypes":["com.sun.jna.ToNativeConverter","java.lang.Object"] }]
},
{
"name":"com.sun.jna.Native$ffi_callback",
"methods":[{"name":"invoke","parameterTypes":["long","long","long"] }]
},
{
"name":"com.sun.jna.NativeMapped",
"methods":[{"name":"toNative","parameterTypes":[] }]
},
{
"name":"com.sun.jna.Pointer",
"fields":[{"name":"peer"}],
"methods":[{"name":"<init>","parameterTypes":["long"] }]
},
{
"name":"com.sun.jna.PointerType",
"fields":[{"name":"pointer"}]
},
{
"name":"com.sun.jna.Structure",
"fields":[{"name":"memory"}, {"name":"typeInfo"}],
"methods":[{"name":"autoRead","parameterTypes":[] }, {"name":"autoWrite","parameterTypes":[] }, {"name":"getTypeInfo","parameterTypes":[] }, {"name":"newInstance","parameterTypes":["java.lang.Class","long"] }]
},
{
"name":"com.sun.jna.Structure$ByValue"
},
{
"name":"com.sun.jna.Structure$FFIType$FFITypes",
"fields":[{"name":"ffi_type_double"}, {"name":"ffi_type_float"}, {"name":"ffi_type_longdouble"}, {"name":"ffi_type_pointer"}, {"name":"ffi_type_sint16"}, {"name":"ffi_type_sint32"}, {"name":"ffi_type_sint64"}, {"name":"ffi_type_sint8"}, {"name":"ffi_type_uint16"}, {"name":"ffi_type_uint32"}, {"name":"ffi_type_uint64"}, {"name":"ffi_type_uint8"}, {"name":"ffi_type_void"}]
},
{
"name":"com.sun.jna.WString",
"methods":[{"name":"<init>","parameterTypes":["java.lang.String"] }]
},
{
"name":"java.lang.Boolean",
"fields":[{"name":"TYPE"}, {"name":"value"}],
"methods":[{"name":"<init>","parameterTypes":["boolean"] }, {"name":"getBoolean","parameterTypes":["java.lang.String"] }]
},
{
"name":"java.lang.Byte",
"fields":[{"name":"TYPE"}, {"name":"value"}],
"methods":[{"name":"<init>","parameterTypes":["byte"] }]
},
{
"name":"java.lang.Character",
"fields":[{"name":"TYPE"}, {"name":"value"}],
"methods":[{"name":"<init>","parameterTypes":["char"] }]
},
{
"name":"java.lang.Class",
"methods":[{"name":"getComponentType","parameterTypes":[] }]
},
{
"name":"java.lang.Double",
"fields":[{"name":"TYPE"}, {"name":"value"}],
"methods":[{"name":"<init>","parameterTypes":["double"] }]
},
{
"name":"java.lang.Error",
"methods":[{"name":"<init>","parameterTypes":["java.lang.String"] }]
},
{
"name":"java.lang.Float",
"fields":[{"name":"TYPE"}, {"name":"value"}],
"methods":[{"name":"<init>","parameterTypes":["float"] }]
},
{
"name":"java.lang.Integer",
"fields":[{"name":"TYPE"}, {"name":"value"}],
"methods":[{"name":"<init>","parameterTypes":["int"] }]
},
{
"name":"java.lang.Long",
"fields":[{"name":"TYPE"}, {"name":"value"}],
"methods":[{"name":"<init>","parameterTypes":["long"] }]
},
{
"name":"java.lang.Object",
"methods":[{"name":"toString","parameterTypes":[] }]
},
{
"name":"java.lang.SecurityManager",
"fields":[{"name":"initialized"}]
},
{
"name":"java.lang.Short",
"fields":[{"name":"TYPE"}, {"name":"value"}],
"methods":[{"name":"<init>","parameterTypes":["short"] }]
},
{
"name":"java.lang.String",
"methods":[{"name":"<init>","parameterTypes":["byte[]"] }, {"name":"<init>","parameterTypes":["byte[]","java.lang.String"] }, {"name":"getBytes","parameterTypes":[] }, {"name":"getBytes","parameterTypes":["java.lang.String"] }, {"name":"toCharArray","parameterTypes":[] }]
},
{
"name":"java.lang.System",
"methods":[{"name":"getProperty","parameterTypes":["java.lang.String"] }]
},
{
"name":"java.lang.UnsatisfiedLinkError",
"methods":[{"name":"<init>","parameterTypes":["java.lang.String"] }]
},
{
"name":"java.lang.Void",
"fields":[{"name":"TYPE"}]
},
{
"name":"java.lang.reflect.Method",
"methods":[{"name":"getParameterTypes","parameterTypes":[] }, {"name":"getReturnType","parameterTypes":[] }]
},
{
"name":"java.nio.Buffer",
"methods":[{"name":"position","parameterTypes":[] }]
},
{
"name":"java.nio.ByteBuffer",
"methods":[{"name":"array","parameterTypes":[] }, {"name":"arrayOffset","parameterTypes":[] }]
},
{
"name":"java.nio.CharBuffer",
"methods":[{"name":"array","parameterTypes":[] }, {"name":"arrayOffset","parameterTypes":[] }]
},
{
"name":"java.nio.DoubleBuffer",
"methods":[{"name":"array","parameterTypes":[] }, {"name":"arrayOffset","parameterTypes":[] }]
},
{
"name":"java.nio.FloatBuffer",
"methods":[{"name":"array","parameterTypes":[] }, {"name":"arrayOffset","parameterTypes":[] }]
},
{
"name":"java.nio.IntBuffer",
"methods":[{"name":"array","parameterTypes":[] }, {"name":"arrayOffset","parameterTypes":[] }]
},
{
"name":"java.nio.LongBuffer",
"methods":[{"name":"array","parameterTypes":[] }, {"name":"arrayOffset","parameterTypes":[] }]
},
{
"name":"java.nio.ShortBuffer",
"methods":[{"name":"array","parameterTypes":[] }, {"name":"arrayOffset","parameterTypes":[] }]
},
{
"name":"sun.management.VMManagementImpl",
"fields":[{"name":"compTimeMonitoringSupport"}, {"name":"currentThreadCpuTimeSupport"}, {"name":"objectMonitorUsageSupport"}, {"name":"otherThreadCpuTimeSupport"}, {"name":"remoteDiagnosticCommandsSupport"}, {"name":"synchronizerUsageSupport"}, {"name":"threadAllocatedMemorySupport"}, {"name":"threadContentionMonitoringSupport"}]
}
]

View File

@ -0,0 +1,8 @@
[
{
"type":"agent-extracted",
"classes":[
]
}
]

View File

@ -0,0 +1,11 @@
[
{
"interfaces":["com.sun.jna.platform.win32.User32"]
},
{
"interfaces":["org.aohe.libs.Kernel32"]
},
{
"interfaces":["org.aohe.libs.Win32Twain"]
}
]

View File

@ -0,0 +1,225 @@
[
{
"name":"[B",
"fields":[{"name":"OPTIONS"}, {"name":"STRING_ENCODING"}, {"name":"STRUCTURE_ALIGNMENT"}, {"name":"TYPE_MAPPER"}]
},
{
"name":"[Ljava.lang.reflect.Method;"
},
{
"name":"byte",
"fields":[{"name":"OPTIONS"}, {"name":"STRING_ENCODING"}, {"name":"STRUCTURE_ALIGNMENT"}, {"name":"TYPE_MAPPER"}]
},
{
"name":"com.alibaba.fastjson.JSONArray"
},
{
"name":"com.alibaba.fastjson.JSONObject"
},
{
"name":"com.alibaba.fastjson2.JSONFactory$CacheItem",
"fields":[{"name":"bytes"}, {"name":"chars"}]
},
{
"name":"com.alibaba.fastjson2.JSONObject",
"queryAllDeclaredConstructors":true
},
{
"name":"com.alibaba.fastjson2.util.TypeUtils$Cache",
"fields":[{"name":"chars"}]
},
{
"name":"com.sun.jna.CallbackProxy",
"methods":[{"name":"callback","parameterTypes":["java.lang.Object[]"] }]
},
{
"name":"com.sun.jna.Structure$FFIType",
"allDeclaredFields":true,
"fields":[{"name":"OPTIONS"}, {"name":"STRING_ENCODING"}, {"name":"STRUCTURE_ALIGNMENT"}, {"name":"TYPE_MAPPER"}]
},
{
"name":"com.sun.jna.Structure$FFIType$size_t",
"methods":[{"name":"<init>","parameterTypes":[] }]
},
{
"name":"com.sun.jna.platform.win32.WinDef$ATOM",
"methods":[{"name":"<init>","parameterTypes":[] }]
},
{
"name":"com.sun.jna.platform.win32.WinDef$HBRUSH",
"methods":[{"name":"<init>","parameterTypes":[] }]
},
{
"name":"com.sun.jna.platform.win32.WinDef$HCURSOR",
"methods":[{"name":"<init>","parameterTypes":[] }]
},
{
"name":"com.sun.jna.platform.win32.WinDef$HICON",
"methods":[{"name":"<init>","parameterTypes":[] }]
},
{
"name":"com.sun.jna.platform.win32.WinDef$HINSTANCE",
"methods":[{"name":"<init>","parameterTypes":[] }]
},
{
"name":"com.sun.jna.platform.win32.WinDef$HWND",
"methods":[{"name":"<init>","parameterTypes":[] }]
},
{
"name":"com.sun.jna.platform.win32.WinDef$LPARAM",
"methods":[{"name":"<init>","parameterTypes":[] }]
},
{
"name":"com.sun.jna.platform.win32.WinDef$LRESULT",
"methods":[{"name":"<init>","parameterTypes":[] }]
},
{
"name":"com.sun.jna.platform.win32.WinDef$POINT",
"allDeclaredFields":true,
"fields":[{"name":"OPTIONS"}, {"name":"STRING_ENCODING"}, {"name":"STRUCTURE_ALIGNMENT"}, {"name":"TYPE_MAPPER"}],
"methods":[{"name":"<init>","parameterTypes":["com.sun.jna.Pointer"] }]
},
{
"name":"com.sun.jna.platform.win32.WinDef$WPARAM",
"methods":[{"name":"<init>","parameterTypes":[] }]
},
{
"name":"com.sun.jna.platform.win32.WinNT$HANDLEByReference",
"methods":[{"name":"<init>","parameterTypes":[] }]
},
{
"name":"com.sun.jna.platform.win32.WinUser$MSG",
"allDeclaredFields":true,
"fields":[{"name":"OPTIONS"}, {"name":"STRING_ENCODING"}, {"name":"STRUCTURE_ALIGNMENT"}, {"name":"TYPE_MAPPER"}]
},
{
"name":"com.sun.jna.platform.win32.WinUser$WNDCLASSEX",
"allDeclaredFields":true,
"fields":[{"name":"OPTIONS"}, {"name":"STRING_ENCODING"}, {"name":"STRUCTURE_ALIGNMENT"}, {"name":"TYPE_MAPPER"}]
},
{
"name":"com.sun.jna.platform.win32.WinUser$WindowProc",
"queryAllDeclaredMethods":true,
"queryAllPublicMethods":true,
"methods":[{"name":"callback","parameterTypes":["com.sun.jna.platform.win32.WinDef$HWND","int","com.sun.jna.platform.win32.WinDef$WPARAM","com.sun.jna.platform.win32.WinDef$LPARAM"] }]
},
{
"name":"java.beans.Transient"
},
{
"name":"java.lang.Object",
"allDeclaredFields":true,
"queryAllDeclaredMethods":true,
"methods":[{"name":"equals","parameterTypes":["java.lang.Object"] }, {"name":"hashCode","parameterTypes":[] }, {"name":"toString","parameterTypes":[] }]
},
{
"name":"java.lang.String",
"fields":[{"name":"COMPACT_STRINGS"}, {"name":"coder"}, {"name":"value"}],
"methods":[{"name":"<init>","parameterTypes":["byte[]","byte"] }, {"name":"coder","parameterTypes":[] }, {"name":"isASCII","parameterTypes":["byte[]"] }, {"name":"value","parameterTypes":[] }]
},
{
"name":"java.lang.StringCoding",
"methods":[{"name":"hasNegatives","parameterTypes":["byte[]","int","int"] }]
},
{
"name":"java.lang.invoke.MethodHandles$Lookup",
"fields":[{"name":"IMPL_LOOKUP"}],
"methods":[{"name":"<init>","parameterTypes":["java.lang.Class","java.lang.Class","int"] }]
},
{
"name":"java.lang.management.ManagementFactory",
"methods":[{"name":"getRuntimeMXBean","parameterTypes":[] }]
},
{
"name":"java.lang.management.RuntimeMXBean",
"methods":[{"name":"getInputArguments","parameterTypes":[] }]
},
{
"name":"java.lang.reflect.Method",
"methods":[{"name":"isVarArgs","parameterTypes":[] }]
},
{
"name":"java.math.BigDecimal",
"fields":[{"name":"intCompact"}]
},
{
"name":"java.math.BigInteger",
"fields":[{"name":"mag"}]
},
{
"name":"java.nio.Buffer"
},
{
"name":"java.security.SecureRandomParameters"
},
{
"name":"java.sql.Date"
},
{
"name":"java.sql.Timestamp"
},
{
"name":"java.util.Collections$UnmodifiableCollection"
},
{
"name":"java.util.Collections$UnmodifiableMap"
},
{
"name":"java.util.concurrent.atomic.AtomicBoolean",
"fields":[{"name":"value"}]
},
{
"name":"java.util.concurrent.atomic.AtomicReference",
"fields":[{"name":"value"}]
},
{
"name":"javax.sql.DataSource"
},
{
"name":"javax.sql.RowSet"
},
{
"name":"org.aohe.core.twain.TwainWndProc",
"fields":[{"name":"OPTIONS"}, {"name":"STRING_ENCODING"}, {"name":"STRUCTURE_ALIGNMENT"}, {"name":"TYPE_MAPPER"}]
},
{
"name":"org.aohe.libs.Win32Twain$TW_CAPABILITY",
"allDeclaredFields":true
},
{
"name":"org.aohe.libs.Win32Twain$TW_IDENTITY",
"allDeclaredFields":true
},
{
"name":"org.aohe.libs.Win32Twain$TW_VERSION",
"allDeclaredFields":true,
"methods":[{"name":"<init>","parameterTypes":[] }, {"name":"<init>","parameterTypes":["com.sun.jna.Pointer"] }]
},
{
"name":"org.aohe.result.R",
"allDeclaredFields":true,
"queryAllDeclaredMethods":true,
"queryAllPublicMethods":true,
"methods":[{"name":"getCode","parameterTypes":[] }, {"name":"getData","parameterTypes":[] }, {"name":"getMsg","parameterTypes":[] }, {"name":"isSuccess","parameterTypes":[] }]
},
{
"name":"short",
"fields":[{"name":"OPTIONS"}, {"name":"STRING_ENCODING"}, {"name":"STRUCTURE_ALIGNMENT"}, {"name":"TYPE_MAPPER"}]
},
{
"name":"sun.misc.Unsafe",
"fields":[{"name":"theUnsafe"}]
},
{
"name":"sun.security.provider.DRBG",
"methods":[{"name":"<init>","parameterTypes":["java.security.SecureRandomParameters"] }]
},
{
"name":"sun.security.provider.SHA",
"methods":[{"name":"<init>","parameterTypes":[] }]
},
{
"name":"sun.security.provider.SHA2$SHA256",
"methods":[{"name":"<init>","parameterTypes":[] }]
}
]

View File

@ -0,0 +1,9 @@
{
"resources":{
"includes":[{
"pattern":"\\QMETA-INF/services/cn.hutool.log.LogFactory\\E"
}, {
"pattern":"\\Qcom/sun/jna/win32-x86-64/jnidispatch.dll\\E"
}]},
"bundles":[]
}

View File

@ -0,0 +1,8 @@
{
"types":[
],
"lambdaCapturingTypes":[
],
"proxies":[
]
}

View File

@ -0,0 +1,81 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<property name="LOG_CONTEXT_NAME" value="AoHe-Scan"/>
<!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径-->
<property name="LOG_HOME" value="logs/${LOG_CONTEXT_NAME}"/>
<!-- 定义日志上下文的名称 -->
<contextName>${LOG_CONTEXT_NAME}</contextName>
<!-- 控制台输出 -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化输出:%d 表示日期,%thread 表示线程名,%-5level级别从左显示 5 个字符宽度%msg日志消息%n 是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{56}.%method:%L - %msg%n</pattern>
<charset>utf-8</charset>
</encoder>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
</appender>
<!--info 日志统一输出-->
<appender name="file.info" class="ch.qos.logback.core.rolling.RollingFileAppender">
<Prudent>true</Prudent>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--日志文件输出的文件名,按小时生成-->
<FileNamePattern>${LOG_HOME}/%d{yyyy-MM-dd}/info/aohe.scan.info.%d{yyyy-MM-dd-HH}.%i.log</FileNamePattern>
<!--日志文件输出的文件名,按天生成-->
<!--<FileNamePattern>${LOG_HOME}/%d{yyyy-MM-dd}/error/error.%d{yyyy-MM-dd}.%i.log</FileNamePattern>-->
<!--日志文件保留天数-->
<MaxHistory>30</MaxHistory>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<!-- 除按日志记录之外,还配置了日志文件不能超过 10M(默认),若超过 10M日志文件会以索引 0 开始 -->
<maxFileSize>10MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化输出:%d 表示日期,%thread 表示线程名,%-5level级别从左显示 5 个字符宽度 %method 方法名 %L 行数 %msg日志消息%n 是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{56}.%method:%L - %msg%n</pattern>
<charset>utf-8</charset>
</encoder>
<!-- 此日志文件只记录 info 级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!--错误日志统一输出-->
<appender name="file.error" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!--省略,参考 file.info appender-->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!--warn 日志统一输出-->
<appender name="file.warn" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!--省略,参考 file.info appender-->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>WARN</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 日志输出级别 -->
<root level="debug">
<appender-ref ref="console"/>
<appender-ref ref="file.error"/>
<appender-ref ref="file.info"/>
<appender-ref ref="file.warn"/>
</root>
</configuration>