|  | #[cfg(test)] | 
|  | mod tests { | 
|  | #[test] | 
|  | fn it_works() { | 
|  | assert_eq!(2 + 2, 4); | 
|  | } | 
|  | } | 
|  |  | 
|  | // use std::ffi::{CStr, CString}; | 
|  | // use std::os::raw::{c_char, c_uchar, c_ulong}; | 
|  |  | 
|  | // #[no_mangle] | 
|  | // pub extern "C" fn dlsmk_decode( | 
|  | //     key: *const c_uchar, | 
|  | //     qrcode: *const c_uchar, | 
|  | //     qrlen: c_ulong, | 
|  | // ) -> *mut c_char { | 
|  | //     CString::new("Hello ".to_owned()).unwrap().into_raw() | 
|  | // } | 
|  |  | 
|  | // #[cfg(target_os = "android")] | 
|  | #[cfg(any(target_family = "unix", target_os = "android"))] | 
|  | // #[cfg(target_family = "unix")] | 
|  | #[allow(non_snake_case)] | 
|  | pub mod android { | 
|  | extern crate jni; | 
|  |  | 
|  | use self::jni::objects::{JClass, JMap, JObject, JString}; | 
|  | use self::jni::sys::{jboolean, jlong, JNI_FALSE, JNI_TRUE}; | 
|  | use self::jni::JNIEnv; | 
|  | // use super::*; | 
|  | use libc; | 
|  | use std::slice; | 
|  |  | 
|  | use dlqrcode::DaliQrCode; | 
|  |  | 
|  | fn put_data(env: &JNIEnv, map: &JMap, key: &str, value: &str) { | 
|  | map.put( | 
|  | *env.new_string(key).unwrap(), | 
|  | *env.new_string(value).unwrap(), | 
|  | ) | 
|  | .unwrap(); | 
|  | } | 
|  |  | 
|  | #[no_mangle] | 
|  | pub unsafe extern "C" fn Java_com_supwisdom_dlsmk_DLSMKQrCode_decode( | 
|  | env: JNIEnv, | 
|  | _: JClass, | 
|  | key_hex: JString, | 
|  | qrcode: JString, | 
|  | offset: jlong, | 
|  | result: JObject, | 
|  | ) -> jboolean { | 
|  | let key = { | 
|  | let s = env | 
|  | .get_string(key_hex) | 
|  | .expect("invalid key string") | 
|  | .as_ptr(); | 
|  | let keylen = libc::strlen(s); | 
|  | let mut k = Vec::new(); | 
|  | k.extend_from_slice(slice::from_raw_parts(s as *const u8, keylen)); | 
|  | k | 
|  | }; | 
|  |  | 
|  | let qrcode = { | 
|  | let s = env | 
|  | .get_string(qrcode) | 
|  | .expect("invalid qrcode string") | 
|  | .as_ptr(); | 
|  | let qrlen = libc::strlen(s); | 
|  | let mut q = Vec::new(); | 
|  | q.extend_from_slice(slice::from_raw_parts(s as *const u8, qrlen)); | 
|  | q | 
|  | }; | 
|  |  | 
|  | let qrdata = env.get_map(result).expect("invalid qrdata map"); | 
|  |  | 
|  | let key = { | 
|  | let mut k = [0u8; 32]; | 
|  | if let Ok(v) = hex::decode(key.as_slice()) { | 
|  | k.clone_from_slice(v.as_slice()); | 
|  | k | 
|  | } else { | 
|  | put_data( | 
|  | &env, | 
|  | &qrdata, | 
|  | "error", | 
|  | "key must be hex format and 64 characters", | 
|  | ); | 
|  | return JNI_FALSE; | 
|  | } | 
|  | }; | 
|  |  | 
|  | let decode = match DaliQrCode::new(key, None, None, None, None) { | 
|  | Ok(d) => d, | 
|  | Err(e) => { | 
|  | let s = format!("invalid input parameter {:?}", e); | 
|  | put_data(&env, &qrdata, "error", &s); | 
|  | return JNI_FALSE; | 
|  | } | 
|  | }; | 
|  |  | 
|  | match decode.decode(qrcode.as_ptr(), qrcode.len(), offset as i32) { | 
|  | Ok(d) => { | 
|  | qrdata | 
|  | .put( | 
|  | *env.new_string("cardno").unwrap(), | 
|  | *env.new_string(d.cardno).unwrap(), | 
|  | ) | 
|  | .unwrap(); | 
|  | qrdata | 
|  | .put( | 
|  | *env.new_string("cardtype").unwrap(), | 
|  | *env.new_string(d.cardtype).unwrap(), | 
|  | ) | 
|  | .unwrap(); | 
|  | qrdata | 
|  | .put( | 
|  | *env.new_string("uid").unwrap(), | 
|  | *env.new_string(d.uid).unwrap(), | 
|  | ) | 
|  | .unwrap(); | 
|  | return JNI_TRUE; | 
|  | } | 
|  | Err(e) => { | 
|  | let s = format!("{:?}", e); | 
|  | put_data(&env, &qrdata, "error", &s); | 
|  | return JNI_FALSE; | 
|  | } | 
|  | }; | 
|  | } | 
|  | } |