1. init
This commit is contained in:
commit
9a63237f32
|
@ -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/
|
|
@ -0,0 +1,3 @@
|
|||
#maven.buildNumber.plugin properties file
|
||||
#Wed Feb 21 16:14:03 CST 2024
|
||||
buildNumber=1
|
|
@ -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>-->
|
||||
<!-- <!–如果不想在打包的后缀加上 assembly.xml 中设置的 id,可以加上下面的配置–>-->
|
||||
<!-- <appendAssemblyId>false</appendAssemblyId>-->
|
||||
<!-- <descriptorRefs>-->
|
||||
<!-- <descriptorRef>jar-with-dependencies</descriptorRef>-->
|
||||
<!-- </descriptorRefs>-->
|
||||
<!-- <archive>-->
|
||||
<!-- <manifest>-->
|
||||
<!-- <!– 是否绑定依赖,将外部 jar 包依赖加入到 classPath 中 –>-->
|
||||
<!-- <addClasspath>true</addClasspath>-->
|
||||
<!-- <!– 依赖前缀,与之前设置的文件夹路径要匹配 –>-->
|
||||
<!-- <classpathPrefix>lib/</classpathPrefix>-->
|
||||
<!-- <!– 执行的主程序入口 –>-->
|
||||
<!-- <mainClass>org.aohe.Main</mainClass>-->
|
||||
<!-- </manifest>-->
|
||||
<!-- </archive>-->
|
||||
<!-- </configuration>-->
|
||||
<!-- <executions>-->
|
||||
<!-- <execution>-->
|
||||
<!-- <id>make-assembly</id>-->
|
||||
<!-- <!–绑定的 maven 操作–>-->
|
||||
<!-- <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>-->
|
||||
<!-- --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>
|
|
@ -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;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
|
@ -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
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package org.aohe.core.twain;
|
||||
|
||||
|
||||
public interface TwainListener {
|
||||
|
||||
public void update(TwainIOMetadata.Type type, TwainIOMetadata metadata);
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package org.aohe.exceptions;
|
||||
|
||||
|
||||
public class TwainCancelException extends TwainResultException {
|
||||
|
||||
public TwainCancelException() {
|
||||
super("User cancelled twain operation.");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package org.aohe.exceptions;
|
||||
|
||||
|
||||
public class TwainCheckStatusException extends TwainResultException {
|
||||
|
||||
public TwainCheckStatusException() {
|
||||
super("\"Source could not fulfill request.");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package org.aohe.exceptions;
|
||||
|
||||
public class TwainDSException extends TwainResultException {
|
||||
|
||||
public TwainDSException() {
|
||||
super("Data source event.");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package org.aohe.exceptions;
|
||||
|
||||
public class TwainDataNotAvailableException extends TwainResultException {
|
||||
|
||||
public TwainDataNotAvailableException() {
|
||||
super("TwainDataNotAvailableException");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package org.aohe.exceptions;
|
||||
|
||||
|
||||
public class TwainEndOfListException extends TwainResultException {
|
||||
|
||||
public TwainEndOfListException() {
|
||||
super("End of List.");
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package org.aohe.exceptions;
|
||||
|
||||
|
||||
public class TwainInfNotSupportedException extends TwainResultException {
|
||||
|
||||
public TwainInfNotSupportedException() {
|
||||
super("InfNotSupported.");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package org.aohe.exceptions;
|
||||
|
||||
|
||||
public class TwainNotDSException extends TwainResultException {
|
||||
|
||||
public TwainNotDSException() {
|
||||
super("No data source event.");
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package org.aohe.exceptions;
|
||||
|
||||
|
||||
public class TwainTransferDoneException extends TwainResultException {
|
||||
|
||||
public TwainTransferDoneException() {
|
||||
super("Image transfer done.");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package org.aohe.exceptions;
|
||||
|
||||
public class TwainUserCancelException extends TwainResultException {
|
||||
|
||||
public TwainUserCancelException() {
|
||||
super("User cancelled twain operation.");
|
||||
}
|
||||
|
||||
}
|
|
@ -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"});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -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"});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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 {
|
||||
}
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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:
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
//
|
||||
// }
|
||||
//
|
||||
//}
|
|
@ -0,0 +1,3 @@
|
|||
Manifest-Version: 1.0
|
||||
Main-Class: org.aohe.Main
|
||||
|
|
@ -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"}]
|
||||
}
|
||||
]
|
|
@ -0,0 +1,8 @@
|
|||
[
|
||||
{
|
||||
"type":"agent-extracted",
|
||||
"classes":[
|
||||
]
|
||||
}
|
||||
]
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
[
|
||||
{
|
||||
"interfaces":["com.sun.jna.platform.win32.User32"]
|
||||
},
|
||||
{
|
||||
"interfaces":["org.aohe.libs.Kernel32"]
|
||||
},
|
||||
{
|
||||
"interfaces":["org.aohe.libs.Win32Twain"]
|
||||
}
|
||||
]
|
|
@ -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":[] }]
|
||||
}
|
||||
]
|
|
@ -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":[]
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"types":[
|
||||
],
|
||||
"lambdaCapturingTypes":[
|
||||
],
|
||||
"proxies":[
|
||||
]
|
||||
}
|
|
@ -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>
|
Loading…
Reference in New Issue