package skj.thunder;
import com.sun.jna.Native;
import com.sun.jna.NativeLong;
import com.sun.jna.WString;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.ptr.LongByReference;
import com.sun.jna.ptr.NativeLongByReference;
public class ThunderUtil {
static {
// 注冊dll
Native.register("D:\\Workspace\\myresource\\thunderdll\\XLDownload");
}
// --------XLError.h中的狀態--------------
public static final int XL_ERROR_FAIL = 268435456;
public static final int XL_SUCCESS = 0;
public static final int XL_ERROR_FILE_NAME_INVALID = XL_ERROR_FAIL + 12;
public static final int XL_ERROR_ADD_TASK_TRAY_ICON_FAIL = XL_ERROR_FAIL + 4;
public static final int XL_ERROR_FILE_ALREADY_EXIST = XL_ERROR_FAIL + 16;
public static final int XL_ERROR_INVALID_TASK_TYPE = XL_ERROR_FAIL + 15;
public static final int XL_ERROR_BUFFER_TOO_SMALL = XL_ERROR_FAIL + 22;
public static final int XL_ERROR_CANNOT_CONTINUE_TASK = XL_ERROR_FAIL + 20;
public static final int XL_ERROR_INIT_TASK_TRAY_ICON_FAIL = XL_ERROR_FAIL + 3;
public static final int XL_ERROR_INVALID_ARG = XL_ERROR_FAIL + 10;
public static final int XL_ERROR_CREATE_DIRECTORY_FAIL = XL_ERROR_FAIL + 8;
public static final int XL_ERROR_STRING_IS_EMPTY = XL_ERROR_FAIL + 6;
public static final int XL_ERROR_TASK_DONT_EXIST = XL_ERROR_FAIL + 11;
public static final int XL_ERROR_UNINITAILIZE = XL_ERROR_FAIL + 1;
public static final int XL_ERROR_POINTER_IS_NULL = XL_ERROR_FAIL + 5;
public static final int XL_ERROR_CANNOT_PAUSE_TASK = XL_ERROR_FAIL + 21;
public static final int XL_ERROR_PATH_DONT_INCLUDE_FILENAME = XL_ERROR_FAIL + 7;
public static final int XL_ERROR_WRITE_CFG_FILE_FAIL = XL_ERROR_FAIL + 19;
public static final int XL_ERROR_INIT_THREAD_EXIT_TOO_EARLY = XL_ERROR_FAIL + 23;
public static final int XL_ERROR_READ_CFG_FILE_FAIL = XL_ERROR_FAIL + 18;
public static final int XL_ERROR_NOTIMPL = XL_ERROR_FAIL + 13;
public static final int XL_ERROR_MEMORY_ISNT_ENOUGH = XL_ERROR_FAIL + 9;
public static final int XL_ERROR_FILE_DONT_EXIST = XL_ERROR_FAIL + 17;
public static final int XL_ERROR_UNSPORTED_PROTOCOL = XL_ERROR_FAIL + 2;
public static final int XL_ERROR_TASKNUM_EXCEED_MAXNUM = XL_ERROR_FAIL + 14;
// -------XLDownload中Task的狀態------------
/**
* 開始建立連接
*/
public static final int XL_STATUS_CONNECT = 0;
/**
* 開始下載
*/
public static final int XL_STATUS_DOWNLOAD = 2;
/**
* 暫停
*/
public static final int XL_STATUS_PAUSE = 10;
/**
* 下載成功
*/
public static final int XL_STATUS_SUCESS = 11;
/**
* 下載失敗
*/
public static final int XL_STATUS_FAIL = 12;
// ------XLDownload中的方法簽名---------------------
/**
* 初始化引擎
* @return TRUE,表示成功;FALSE,表示失敗。
*/
public static native boolean XLInitDownloadEngine();
/**
* 下載指定的資源,并保存到本地文件,只支持HTTP,不支持動態鏈
* @param pszFileName 下載資源的本地文件名
* @param pszUrl 資源的URL,不能為NULL
* @param pszRefUrl 資源的引用頁,可以為NULL
* @param lTaskId 【傳出參數】唯一標識引擎創建的任務,該參數可以作為XLQueryTaskInfo、XLStopTask的第一個參數。如果該參數值為0,表示引擎創建任務失敗
* @return XL_SUCCESS,表示成功。其他值,表示失敗
*/
public static native int XLURLDownloadToFile(WString pszFileName, WString pszUrl, WString pszRefUrl, NativeLongByReference lTaskId);
/**
* 查詢指定任務的當前狀態
* @param lTaskId 指定將要查詢的任務。通過調用XLURLDownloadToFile可以獲取一個任務ID
* @param plStatus 【傳出參數】返回任務的當前狀態。可能的取值,參見XLDownload.h
* @param pullFileSize 【傳出參數】文件大小,單位是字節
* @param pullRecvSize 【傳出參數】已經下載到的數據,單位是字節
* @return
*/
public static native int XLQueryTaskInfo(NativeLong lTaskId, NativeLongByReference plStatus, LongByReference pullFileSize, LongByReference pullRecvSize);
/**
* 暫停指定任務,并返回新的任務ID
* @param lTaskId 任務ID。通過調用XLURLDownloadToFile可以獲取一個任務ID
* @param lNewTaskId 【傳出參數】當返回值等于XL_SUCCESS時,返回新的任務ID;否則,值未定義
* @return XL_SUCCESS,表示成功;其他值,表示失敗。
*/
public static native int XLPauseTask(NativeLong lTaskId, NativeLongByReference lNewTaskId);
/**
* 恢復已暫停的任務
* @param lTaskId 任務ID
* @return XL_SUCCESS,表示成功;其他值,表示失敗。
*/
public static native int XLContinueTask(NativeLong lTaskId);
/**
* 從指定的TD文件開始新任務
* @param pszTdFileFullPath TD文件的完整路徑及文件名
* @param lTaskId 【傳出參數】調用成功時,返回新建任務的ID
* @return XL_SUCCESS,表示成功;其他,表示失敗。詳見XLError.h
*/
public static native int XLContinueTaskFromTdFile(String pszTdFileFullPath, NativeLongByReference lTaskId);
/**
* 停止指定任務
* 【注意】每個任務,無論下載成功或失敗,最后都必須調用一次XLStopTask。否則,會導致資源泄漏。
* @param lTaskId 要停止的任務ID
*/
public static native void XLStopTask(NativeLong lTaskId);
/**
* 進行一些資源回收操作
* 【注意】當不再使用引擎時,必須調用該函數,否則會導致資源泄漏。
* @return TRUE,表示成功;FALSE,表示失敗。
*/
public static native boolean XLUninitDownloadEngine();
/**
* 將錯誤碼對應的錯誤消息拷貝至指定的緩沖區。
* @param dwErrorId 開放下載引擎定義的錯誤碼,詳見XLError.h
* @param pszBuffer 緩沖區首地址
* @param dwSize 【傳出參數】傳入時,指定緩沖區長度;函數返回時,如果緩沖區長度不足,該參數被設置成所需的緩沖區長度。該參數的單位是字符數,不是字節數。
* @return
*/
public static native int XLGetErrorMsg(int dwErrorId, String pszBuffer, IntByReference dwSize);
//-------------------工具函數----------------
/**
* long轉NativeLongByReference
* @param value
* @return
*/
public static NativeLongByReference makeNativeRefLong(long value) {
NativeLongByReference ullFileSize = new NativeLongByReference();
ullFileSize.setValue(new NativeLong(value));
return ullFileSize;
}
/**
* NativeLongByReference轉long
* @param longRef
* @return
*/
public static long getLongValue(NativeLongByReference longRef) {
return longRef.getValue().longValue();
}
// 測試代碼: http://xldoc.xl7.xunlei.com/0000000026/index.html的C語言的Java翻版
public static void main( String[] args) throws InterruptedException {
int result;
try {
if (!XLInitDownloadEngine()) {
System.out.println("Initialize download engine failed.");
return;
}
NativeLongByReference lTaskId = makeNativeRefLong(0);
result = XLURLDownloadToFile(
new WString("d:\\xxx.flv"),
new WString("http://f6.r.56.com/f6.c95.56.com/flvdownload/5/4/135175960260hd.flv?v=1&t=clnCNmA07nD3NWUGnVwBQQ&r=36978&e=1351849624"),
new WString(""),
lTaskId);
System.out.println("result code: " + result);
System.out.println("task id: " + getLongValue(lTaskId));
if (XL_SUCCESS != result) {
XLUninitDownloadEngine();
System.out.println("Create new task failed, error code: " + ( result - XL_ERROR_FAIL) );
return;
}
System.out.println("Begin download file.");
do {
Thread.sleep(1000);
LongByReference ullFileSize = new LongByReference(0);
LongByReference ullRecvSize = new LongByReference(0);
NativeLongByReference lStatus = makeNativeRefLong(-1);
NativeLong nativeLong = new NativeLong();
nativeLong.setValue(getLongValue(lTaskId));
result = XLQueryTaskInfo(nativeLong, lStatus, ullFileSize, ullRecvSize);
if (XL_SUCCESS == result) {
// 輸出進度信息
if (0 != ullFileSize.getValue()) {
double douProgress = (double) ullRecvSize.getValue() / (double) ullFileSize.getValue();
douProgress *= 100.0;
System.out.println("Download progress:" + douProgress);
} else {
System.out.println("File size is zero.");
}
if (XL_STATUS_SUCESS == getLongValue(lStatus)) {
System.out.println("Download successfully.\n");
break;
}
if (XL_STATUS_FAIL == getLongValue(lStatus)) {
System.out.println("Download failed.");
break;
}
}
} while (XL_SUCCESS == result);
XLStopTask(lTaskId.getValue());
} finally {
XLUninitDownloadEngine();
}
}
}