From 29512c169e7a483c79be3cf6e87a299a6b222db6 Mon Sep 17 00:00:00 2001 From: "kexuan.yang" Date: Fri, 24 Nov 2023 18:02:14 +0800 Subject: [PATCH] Refacotr test code Change-Id: Ibd72cedd16a1a8415b9a6f6a98cc4f013b54628a --- Cargo.toml | 2 +- .../buildSrc/src/main/java/Configuration.kt | 5 +- .../src/debug/jniLibs/arm64-v8a/libmmkv.so | 4 +- .../src/debug/jniLibs/armeabi-v7a/libmmkv.so | 4 +- .../src/debug/jniLibs/x86_64/libmmkv.so | 2 +- .../src/main/jniLibs/arm64-v8a/libmmkv.so | 4 +- .../src/main/jniLibs/armeabi-v7a/libmmkv.so | 4 +- .../src/main/jniLibs/x86_64/libmmkv.so | 4 +- .../src/debug/jniLibs/arm64-v8a/libmmkv.so | 4 +- .../src/debug/jniLibs/armeabi-v7a/libmmkv.so | 4 +- .../src/debug/jniLibs/x86_64/libmmkv.so | 2 +- .../src/main/jniLibs/arm64-v8a/libmmkv.so | 4 +- .../src/main/jniLibs/armeabi-v7a/libmmkv.so | 4 +- .../src/main/jniLibs/x86_64/libmmkv.so | 4 +- .../Sources/RustMMKV.xcframework/Info.plist | 16 +-- .../RustMMKV.xcframework/ios-arm64/libmmkv.a | 4 +- .../ios-arm64_x86_64-simulator/libmmkv.a | 4 +- .../macos-arm64_x86_64/libmmkv.a | 4 +- src/core/encrypt.rs | 40 +++--- src/core/memory_map.rs | 7 +- src/core/mmkv_impl.rs | 85 ++++++------ src/ffi/ffi_buffer.rs | 121 ++++++------------ src/ffi/mod.rs | 76 ++++++----- src/lib.rs | 6 +- src/log/logger.rs | 2 +- tests/integration_test.rs | 63 +-------- 26 files changed, 197 insertions(+), 282 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index db76cb2..31ca32b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mmkv" -version = "0.2.7" +version = "0.2.8" edition = "2021" authors = ["Kexuan Yang "] description = "Rust version of MMKV" diff --git a/android/buildSrc/src/main/java/Configuration.kt b/android/buildSrc/src/main/java/Configuration.kt index 132e20e..52bb68a 100644 --- a/android/buildSrc/src/main/java/Configuration.kt +++ b/android/buildSrc/src/main/java/Configuration.kt @@ -1,6 +1,7 @@ object Configuration { -// const val libVersion = "0.2.7.1-SNAPSHOT" - const val libVersion = "0.2.7.1" + const val versionStr = "0.2.8" +// const val libVersion = versionStr + "-SNAPSHOT" + const val libVersion = versionStr const val groupId = "net.yangkx" const val description = "Library uses file-based mmap to store key-values" private const val releasesRepoUrl = "https://s01.oss.sonatype.org/content/repositories/releases/" diff --git a/android/library-encrypt/src/debug/jniLibs/arm64-v8a/libmmkv.so b/android/library-encrypt/src/debug/jniLibs/arm64-v8a/libmmkv.so index 7a2f297..d97bee6 100755 --- a/android/library-encrypt/src/debug/jniLibs/arm64-v8a/libmmkv.so +++ b/android/library-encrypt/src/debug/jniLibs/arm64-v8a/libmmkv.so @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6171a0976b7df2a4c8b0202048506c331442e117602364b55acd4bd5c97ab940 -size 37658472 +oid sha256:6ce819baf801cf8d033b359105f11b3d808b34a9f398db5d47af2265b7cb4e83 +size 37658488 diff --git a/android/library-encrypt/src/debug/jniLibs/armeabi-v7a/libmmkv.so b/android/library-encrypt/src/debug/jniLibs/armeabi-v7a/libmmkv.so index 7ffa039..56a54a8 100755 --- a/android/library-encrypt/src/debug/jniLibs/armeabi-v7a/libmmkv.so +++ b/android/library-encrypt/src/debug/jniLibs/armeabi-v7a/libmmkv.so @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3907af71788302188ecf31392c8a73061b022c9d289b93c3013994214b0b399c -size 34539996 +oid sha256:c100dac42bb0f21b60b6a20351aa39c08142386e2b4168b8fb963a06baf3defa +size 34539912 diff --git a/android/library-encrypt/src/debug/jniLibs/x86_64/libmmkv.so b/android/library-encrypt/src/debug/jniLibs/x86_64/libmmkv.so index 01b3810..ef67a3f 100755 --- a/android/library-encrypt/src/debug/jniLibs/x86_64/libmmkv.so +++ b/android/library-encrypt/src/debug/jniLibs/x86_64/libmmkv.so @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3ab9f817440da43340e59e3f9198c7166635ede9bc0b600c6d329e35342a8241 +oid sha256:e82f9c4c92926ea384dae1e68fc27921ae4fbfd8c1d84238140715f209bc33fb size 38050960 diff --git a/android/library-encrypt/src/main/jniLibs/arm64-v8a/libmmkv.so b/android/library-encrypt/src/main/jniLibs/arm64-v8a/libmmkv.so index 6c2d9d7..c61d9d8 100755 --- a/android/library-encrypt/src/main/jniLibs/arm64-v8a/libmmkv.so +++ b/android/library-encrypt/src/main/jniLibs/arm64-v8a/libmmkv.so @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:327ce2e322e3f7468f09dd74b882e9628207267e2ba2c7e5c9e008319696ce46 -size 5584080 +oid sha256:da09c1c5751ba1f1e20688b519bbfc1fe2371c9391be6c54916ba80b13b3643f +size 5584112 diff --git a/android/library-encrypt/src/main/jniLibs/armeabi-v7a/libmmkv.so b/android/library-encrypt/src/main/jniLibs/armeabi-v7a/libmmkv.so index a0cd36f..c0741bb 100755 --- a/android/library-encrypt/src/main/jniLibs/armeabi-v7a/libmmkv.so +++ b/android/library-encrypt/src/main/jniLibs/armeabi-v7a/libmmkv.so @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8a408a5204989a13aef7c989abb52e544bd4d20ffab1a59a5cff43d33e67318a -size 4485072 +oid sha256:ee67b728bfd3c9f889a7e81ae105ca94e464876657fa9933044673340b6f2433 +size 4485080 diff --git a/android/library-encrypt/src/main/jniLibs/x86_64/libmmkv.so b/android/library-encrypt/src/main/jniLibs/x86_64/libmmkv.so index 12829f2..88f5228 100755 --- a/android/library-encrypt/src/main/jniLibs/x86_64/libmmkv.so +++ b/android/library-encrypt/src/main/jniLibs/x86_64/libmmkv.so @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4b33f2c272afbb3c0f51de74032f6a1ad06d07135587afd483344064d2118ab3 -size 5439128 +oid sha256:b5110b03258f03f2ec38d0f264a672c5acbabe1e448df927fde5c16f91011e17 +size 5439120 diff --git a/android/library/src/debug/jniLibs/arm64-v8a/libmmkv.so b/android/library/src/debug/jniLibs/arm64-v8a/libmmkv.so index b687d56..824d003 100755 --- a/android/library/src/debug/jniLibs/arm64-v8a/libmmkv.so +++ b/android/library/src/debug/jniLibs/arm64-v8a/libmmkv.so @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d5b6d6c70b281518d01d281a5ac998faa5ecee127c295c22ff5825af2a7e4559 -size 35865456 +oid sha256:80060bfaee89d82b1cf079fdc37f3ac84e012989da9d6e4cf53541524982935f +size 35865416 diff --git a/android/library/src/debug/jniLibs/armeabi-v7a/libmmkv.so b/android/library/src/debug/jniLibs/armeabi-v7a/libmmkv.so index f640786..29a4000 100755 --- a/android/library/src/debug/jniLibs/armeabi-v7a/libmmkv.so +++ b/android/library/src/debug/jniLibs/armeabi-v7a/libmmkv.so @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:312c5193f45dffb4d87f06a7e0567545d4f9476a959c82b99d31df28e429d1d6 -size 32956416 +oid sha256:7669a42fc1ca62e7f3371d557898083c53056809d29d551108959d8023ff75f3 +size 32956396 diff --git a/android/library/src/debug/jniLibs/x86_64/libmmkv.so b/android/library/src/debug/jniLibs/x86_64/libmmkv.so index 5da74c1..f58917f 100755 --- a/android/library/src/debug/jniLibs/x86_64/libmmkv.so +++ b/android/library/src/debug/jniLibs/x86_64/libmmkv.so @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:41b31799c4a46cf42a3a9046d0c610a3b361a681c98fd90a833d7a8e1e1e21bd +oid sha256:b047aa519cd1c05379ac27b93d588b83a41ade29cd851ddd908d2f0d16903225 size 35891512 diff --git a/android/library/src/main/jniLibs/arm64-v8a/libmmkv.so b/android/library/src/main/jniLibs/arm64-v8a/libmmkv.so index 46c9013..9f5c74f 100755 --- a/android/library/src/main/jniLibs/arm64-v8a/libmmkv.so +++ b/android/library/src/main/jniLibs/arm64-v8a/libmmkv.so @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dbf60e41113b625a8aab0b91775b47d5bd5f4176d1b0c7969fd4997ee7764663 -size 5543152 +oid sha256:e54773e1b2269dc2503aa89b34078cb6e5250e56f6eed01259925005bc4f9a2f +size 5543248 diff --git a/android/library/src/main/jniLibs/armeabi-v7a/libmmkv.so b/android/library/src/main/jniLibs/armeabi-v7a/libmmkv.so index 8fdaa9d..745c657 100755 --- a/android/library/src/main/jniLibs/armeabi-v7a/libmmkv.so +++ b/android/library/src/main/jniLibs/armeabi-v7a/libmmkv.so @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d0b775f04c26c4dbf30aa840ff21aab935696961298b0c0c5dcd5fed81224b17 -size 4459564 +oid sha256:47a5edbb3cdd4ac32e3077e0b5a62d460e9f4d6d62085c7fa0294e51c736f67d +size 4459492 diff --git a/android/library/src/main/jniLibs/x86_64/libmmkv.so b/android/library/src/main/jniLibs/x86_64/libmmkv.so index 3f278e8..639521f 100755 --- a/android/library/src/main/jniLibs/x86_64/libmmkv.so +++ b/android/library/src/main/jniLibs/x86_64/libmmkv.so @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:37b33fdc26bc6102fa15efa914858f5a9cdf1d0021f6b8456b2dac25db1a9656 -size 5390696 +oid sha256:3a66be0b2dc30996828523a48b5d86735e2ebb8fae168fb6cf2d784553282f36 +size 5390688 diff --git a/ios/MMKV/Sources/RustMMKV.xcframework/Info.plist b/ios/MMKV/Sources/RustMMKV.xcframework/Info.plist index fea8fda..6c86166 100644 --- a/ios/MMKV/Sources/RustMMKV.xcframework/Info.plist +++ b/ios/MMKV/Sources/RustMMKV.xcframework/Info.plist @@ -10,7 +10,7 @@ HeadersPath Headers LibraryIdentifier - macos-arm64_x86_64 + ios-arm64_x86_64-simulator LibraryPath libmmkv.a SupportedArchitectures @@ -19,7 +19,9 @@ x86_64 SupportedPlatform - macos + ios + SupportedPlatformVariant + simulator BinaryPath @@ -27,18 +29,15 @@ HeadersPath Headers LibraryIdentifier - ios-arm64_x86_64-simulator + ios-arm64 LibraryPath libmmkv.a SupportedArchitectures arm64 - x86_64 SupportedPlatform ios - SupportedPlatformVariant - simulator BinaryPath @@ -46,15 +45,16 @@ HeadersPath Headers LibraryIdentifier - ios-arm64 + macos-arm64_x86_64 LibraryPath libmmkv.a SupportedArchitectures arm64 + x86_64 SupportedPlatform - ios + macos CFBundlePackageType diff --git a/ios/MMKV/Sources/RustMMKV.xcframework/ios-arm64/libmmkv.a b/ios/MMKV/Sources/RustMMKV.xcframework/ios-arm64/libmmkv.a index 1b0de36..c94fe0f 100644 --- a/ios/MMKV/Sources/RustMMKV.xcframework/ios-arm64/libmmkv.a +++ b/ios/MMKV/Sources/RustMMKV.xcframework/ios-arm64/libmmkv.a @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b812858432a47a550a8d261b13ba9a4600f2ec637a02356137ed654b1d81faa7 -size 37582216 +oid sha256:9b440b7ced9d7074b91a93ae2b3be6b446614eb1eeb51d2a33cb8eabe1d3633e +size 37581920 diff --git a/ios/MMKV/Sources/RustMMKV.xcframework/ios-arm64_x86_64-simulator/libmmkv.a b/ios/MMKV/Sources/RustMMKV.xcframework/ios-arm64_x86_64-simulator/libmmkv.a index 410e9ba..123d7c8 100644 --- a/ios/MMKV/Sources/RustMMKV.xcframework/ios-arm64_x86_64-simulator/libmmkv.a +++ b/ios/MMKV/Sources/RustMMKV.xcframework/ios-arm64_x86_64-simulator/libmmkv.a @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a9dd1cbd8bb101ac0ba8709b24568382c4ded36c9a6481c9a39c41183aa05c55 -size 62360672 +oid sha256:6cb026602d76267d7c5ce4c9fe0b7c486d422ee7fc57349aef973a351eb217f7 +size 62359776 diff --git a/ios/MMKV/Sources/RustMMKV.xcframework/macos-arm64_x86_64/libmmkv.a b/ios/MMKV/Sources/RustMMKV.xcframework/macos-arm64_x86_64/libmmkv.a index 2cb276d..0eb9ac3 100644 --- a/ios/MMKV/Sources/RustMMKV.xcframework/macos-arm64_x86_64/libmmkv.a +++ b/ios/MMKV/Sources/RustMMKV.xcframework/macos-arm64_x86_64/libmmkv.a @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:39d2d6dda8d824edaa1e3df10879cab8787864f761fbf15af581e8f2bb9790ad -size 50320936 +oid sha256:43f3ba2afe7017f511f3ae05791f634527f7b13e5e36fae5a2b3ba3afe521042 +size 50320768 diff --git a/src/core/encrypt.rs b/src/core/encrypt.rs index 7228bc7..668fd21 100644 --- a/src/core/encrypt.rs +++ b/src/core/encrypt.rs @@ -4,10 +4,10 @@ use std::ops::Deref; use std::rc::Rc; use aes::Aes128; -use eax::aead::{generic_array::GenericArray, KeyInit, OsRng, Payload}; use eax::aead::consts::U8; use eax::aead::rand_core::RngCore; use eax::aead::stream::{NewStream, StreamBE32, StreamPrimitive}; +use eax::aead::{generic_array::GenericArray, KeyInit, OsRng, Payload}; use eax::Eax; use crate::core::buffer::{Buffer, Decoder, Encoder, Take}; @@ -67,9 +67,10 @@ impl Encrypt { return Err(EncryptFailed(String::from("counter overflow"))); } - let result = self.stream.encrypt( - self.position, false, Payload::from(bytes.as_slice()), - ).map_err(|e| EncryptFailed(e.to_string()))?; + let result = self + .stream + .encrypt(self.position, false, Payload::from(bytes.as_slice())) + .map_err(|e| EncryptFailed(e.to_string()))?; self.position += Stream::COUNTER_INCR; Ok(result) @@ -80,9 +81,10 @@ impl Encrypt { return Err(DecryptFailed(String::from("counter overflow"))); } - let result = self.stream.decrypt( - self.position, false, Payload::from(bytes.as_slice()), - ).map_err(|e| DecryptFailed(e.to_string()))?; + let result = self + .stream + .decrypt(self.position, false, Payload::from(bytes.as_slice())) + .map_err(|e| DecryptFailed(e.to_string()))?; self.position += Stream::COUNTER_INCR; Ok(result) @@ -147,7 +149,9 @@ impl Debug for EncryptBuffer { impl Debug for Encrypt { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - f.debug_struct("Encrypt").field("nonce", &hex::encode(self.nonce.to_vec())).finish() + f.debug_struct("Encrypt") + .field("nonce", &hex::encode(self.nonce.to_vec())) + .finish() } } @@ -163,20 +167,14 @@ mod tests { #[test] fn test_crypt_buffer() { - let encryptor = Rc::new( - RefCell::new( - Encrypt::new(hex::decode(TEST_KEY).unwrap().try_into().unwrap()) - ) - ); + let encryptor = Rc::new(RefCell::new(Encrypt::new( + hex::decode(TEST_KEY).unwrap().try_into().unwrap(), + ))); let nonce = encryptor.borrow_mut().nonce; - let decryptor = Rc::new( - RefCell::new( - Encrypt::new_with_nonce( - hex::decode(TEST_KEY).unwrap().try_into().unwrap(), - &nonce, - ) - ) - ); + let decryptor = Rc::new(RefCell::new(Encrypt::new_with_nonce( + hex::decode(TEST_KEY).unwrap().try_into().unwrap(), + &nonce, + ))); let buffer = Buffer::from_i32("key1", 1); let buffer = EncryptBuffer::new_with_buffer(buffer, encryptor.clone()); let bytes = buffer.encode_to_bytes().unwrap(); diff --git a/src/core/memory_map.rs b/src/core/memory_map.rs index 78a5074..5057947 100644 --- a/src/core/memory_map.rs +++ b/src/core/memory_map.rs @@ -51,7 +51,12 @@ mod tests { #[test] fn test_mmap() { let _ = fs::remove_file("test_mmap"); - let file = OpenOptions::new().create(true).write(true).read(true).open("test_mmap").unwrap(); + let file = OpenOptions::new() + .create(true) + .write(true) + .read(true) + .open("test_mmap") + .unwrap(); file.set_len(1024).unwrap(); let mut mm = MemoryMap::new(&file); assert_eq!(mm.len(), 8); diff --git a/src/core/mmkv_impl.rs b/src/core/mmkv_impl.rs index 04c54a7..5b60425 100644 --- a/src/core/mmkv_impl.rs +++ b/src/core/mmkv_impl.rs @@ -170,7 +170,12 @@ impl MmkvImpl { let bytes = transform(buffer.clone()).encode_to_bytes()?; mm.append(bytes).map_err(|e| EncodeFailed(e.to_string()))?; } - info!(LOG_TAG, "trimmed, len from {} to {}", original_len, mm.len()); + info!( + LOG_TAG, + "trimmed, len from {} to {}", + original_len, + mm.len() + ); // the encrypt has been reset, need encode it with new encrypt if cfg!(feature = "encryption") { data = buffer.encode_to_bytes()?; @@ -228,13 +233,10 @@ impl Display for MmkvImpl { #[cfg(test)] mod tests { use std::path::Path; - use std::sync::OnceLock; + use std::sync::atomic::{AtomicPtr, Ordering}; use std::{fs, thread}; use crate::core::buffer::Buffer; - use crate::core::crc::CrcBuffer; - #[cfg(feature = "encryption")] - use crate::core::encrypt::EncryptBuffer; use crate::core::mmkv_impl::MmkvImpl; use crate::Error::{InstanceClosed, KeyNotFound, TypeMissMatch}; @@ -349,56 +351,41 @@ mod tests { fn test_multi_thread_mmkv() { let _ = fs::remove_file("test_multi_thread_mmkv"); let _ = fs::remove_file("test_multi_thread_mmkv.meta"); - static mut MMKV: OnceLock = OnceLock::new(); - let mmkv = MmkvImpl::new( + let mmkv_impl = MmkvImpl::new( Path::new("test_multi_thread_mmkv"), 4096, #[cfg(feature = "encryption")] "88C51C536176AD8A8EE4A06F62EE897E", ); + let mmkv_ptr = Box::into_raw(Box::new(mmkv_impl)); + let mmkv = AtomicPtr::new(std::ptr::null_mut()); + mmkv.store(mmkv_ptr, Ordering::Release); + let action = |thread_id: &str| { + for i in 0..1000 { + let key = &format!("{thread_id}_key_{i}"); + let mmkv = unsafe { mmkv.load(Ordering::Acquire).as_mut().unwrap() }; + mmkv.put(key, Buffer::from_i32(key, i)).unwrap(); + } + }; + thread::scope(|s| { + for i in 0..4 { + s.spawn(move || action(format!("thread_{i}").as_ref())); + } + }); unsafe { - MMKV.set(mmkv).unwrap(); - let action = || { - let current_thread = thread::current(); - let thread_id = current_thread.id(); - for i in 0..500 { - let key = &format!("{:?}_key_{i}", thread_id); - MMKV.get_mut() - .unwrap() - .put(key, Buffer::from_i32(key, i)) - .unwrap(); - } - }; - thread::scope(|s| { - for _ in 0..4 { - s.spawn(action); - } - }); - if cfg!(feature = "encryption") { - #[cfg(feature = "encryption")] - { - let encrypt = MMKV.get().unwrap().encrypt.clone(); - let count = MMKV - .get() - .unwrap() - .mm - .read() - .unwrap() - .iter(|| EncryptBuffer::new(encrypt.clone())) - .count(); - assert_eq!(count, 2000); - } - } else { - let count = MMKV - .get() - .unwrap() - .mm - .read() - .unwrap() - .iter(|| CrcBuffer::new()) - .count(); - assert_eq!(count, 2000); - }; + let _ = Box::from_raw(mmkv.swap(std::ptr::null_mut(), Ordering::Release)); + } + let mmkv = MmkvImpl::new( + Path::new("test_multi_thread_mmkv"), + 4096, + #[cfg(feature = "encryption")] + "88C51C536176AD8A8EE4A06F62EE897E", + ); + for i in 0..4 { + for j in 0..1000 { + let key = &format!("thread_{i}_key_{j}"); + assert_eq!(mmkv.get(key).unwrap().decode_i32().unwrap(), j) + } } let _ = fs::remove_file("test_multi_thread_mmkv"); let _ = fs::remove_file("test_multi_thread_mmkv.meta"); diff --git a/src/ffi/ffi_buffer.rs b/src/ffi/ffi_buffer.rs index 5c9aa27..b530c5d 100644 --- a/src/ffi/ffi_buffer.rs +++ b/src/ffi/ffi_buffer.rs @@ -1,8 +1,8 @@ use std::any::Any; use std::fmt::Debug; -use crate::Error; use crate::ffi::ffi::*; +use crate::Error; pub(super) trait Releasable { unsafe fn release(&mut self); @@ -14,19 +14,14 @@ impl ByteSlice { let ptr = boxed.as_ptr(); let len = boxed.len(); std::mem::forget(boxed); - ByteSlice { - bytes: ptr, - len, - } + ByteSlice { bytes: ptr, len } } } impl Releasable for ByteSlice { unsafe fn release(&mut self) { unsafe { - let _ = String::from_raw_parts( - self.bytes as *mut u8, self.len, self.len, - ); + let _ = String::from_raw_parts(self.bytes as *mut u8, self.len, self.len); }; } } @@ -51,42 +46,24 @@ impl Releasable for RawTypedArray { verbose!(LOG_TAG, "release {:?}", self); verbose!(LOG_TAG, "release array {:?}", self.array); let _: Box = match self.type_token { - Types::ByteArray => { - Box::from_raw( - std::slice::from_raw_parts_mut( - self.array as *mut u8, self.len, - ).as_mut_ptr() - ) - } - Types::I32Array => { - Box::from_raw( - std::slice::from_raw_parts_mut( - self.array as *mut i32, self.len, - ).as_mut_ptr() - ) + Types::ByteArray => Box::from_raw( + std::slice::from_raw_parts_mut(self.array as *mut u8, self.len).as_mut_ptr(), + ), + Types::I32Array => Box::from_raw( + std::slice::from_raw_parts_mut(self.array as *mut i32, self.len).as_mut_ptr(), + ), + Types::I64Array => Box::from_raw( + std::slice::from_raw_parts_mut(self.array as *mut i64, self.len).as_mut_ptr(), + ), + Types::F32Array => Box::from_raw( + std::slice::from_raw_parts_mut(self.array as *mut f32, self.len).as_mut_ptr(), + ), + Types::F64Array => Box::from_raw( + std::slice::from_raw_parts_mut(self.array as *mut f64, self.len).as_mut_ptr(), + ), + _ => { + panic!("can't match type of array") } - Types::I64Array => { - Box::from_raw( - std::slice::from_raw_parts_mut( - self.array as *mut i64, self.len, - ).as_mut_ptr() - ) - } - Types::F32Array => { - Box::from_raw( - std::slice::from_raw_parts_mut( - self.array as *mut f32, self.len, - ).as_mut_ptr() - ) - } - Types::F64Array => { - Box::from_raw( - std::slice::from_raw_parts_mut( - self.array as *mut f64, self.len, - ).as_mut_ptr() - ) - } - _ => { panic!("can't match type of array") } }; } } @@ -100,7 +77,10 @@ impl RawBuffer { } } - pub(super) fn set_data(&mut self, data: T) where T: Sized + Debug { + pub(super) fn set_data(&mut self, data: T) + where + T: Sized + Debug, + { let log = format!("{:?}", data); let ptr = Box::into_raw(Box::new(data)) as *const _; verbose!(LOG_TAG, "leak data {log} {:?}", ptr); @@ -113,27 +93,17 @@ impl RawBuffer { } verbose!(LOG_TAG, "release data {:?}", self.rawData); let _: Box = match self.typeToken { - Types::I32 => { - Box::from_raw(self.rawData as *mut i32) - } - Types::Str => { - Box::from_raw(self.rawData as *mut ByteSlice) - } - Types::Bool => { - Box::from_raw(self.rawData as *mut bool) - } - Types::I64 => { - Box::from_raw(self.rawData as *mut i64) - } - Types::F32 => { - Box::from_raw(self.rawData as *mut f32) - } - Types::F64 => { - Box::from_raw(self.rawData as *mut f64) - } - Types::ByteArray | Types::I32Array | Types::I64Array | Types::F32Array | Types::F64Array => { - Box::from_raw(self.rawData as *mut RawTypedArray) - } + Types::I32 => Box::from_raw(self.rawData as *mut i32), + Types::Str => Box::from_raw(self.rawData as *mut ByteSlice), + Types::Bool => Box::from_raw(self.rawData as *mut bool), + Types::I64 => Box::from_raw(self.rawData as *mut i64), + Types::F32 => Box::from_raw(self.rawData as *mut f32), + Types::F64 => Box::from_raw(self.rawData as *mut f64), + Types::ByteArray + | Types::I32Array + | Types::I64Array + | Types::F32Array + | Types::F64Array => Box::from_raw(self.rawData as *mut RawTypedArray), }; } @@ -158,9 +128,7 @@ impl RawBuffer { } pub(super) fn from_raw(ptr: *mut RawBuffer) -> Self { - *unsafe { - Box::from_raw(ptr) - } + *unsafe { Box::from_raw(ptr) } } } @@ -175,21 +143,16 @@ impl Releasable for RawBuffer { impl InternalError { pub(super) fn new(code: i32, reason: Option) -> Self { match reason { - None => { - InternalError { - code, - reason: std::ptr::null(), - } - } + None => InternalError { + code, + reason: std::ptr::null(), + }, Some(str) => { let byte_slice = ByteSlice::new(str); let log = format!("{:?}", byte_slice); let reason = Box::into_raw(Box::new(byte_slice)); verbose!(LOG_TAG, "leak {log} {:?}", reason); - InternalError { - code, - reason, - } + InternalError { code, reason } } } } @@ -207,7 +170,7 @@ impl TryFrom for InternalError { Error::DataInvalid => Ok(InternalError::new(3, None)), Error::InstanceClosed => Ok(InternalError::new(4, None)), Error::EncodeFailed(descr) => Ok(InternalError::new(5, Some(descr))), - _ => Err(()) + _ => Err(()), } } } diff --git a/src/ffi/mod.rs b/src/ffi/mod.rs index bb38d1f..934e8a9 100644 --- a/src/ffi/mod.rs +++ b/src/ffi/mod.rs @@ -6,12 +6,12 @@ mod ffi_buffer; #[cfg(not(feature = "encryption"))] #[allow(non_snake_case)] pub mod ffi { + use mmkv_proc_macro_lib::AutoRelease; use std::ffi::{c_void, CStr}; use std::fmt::Debug; use std::os::raw::c_char; - use mmkv_proc_macro_lib::AutoRelease; - use crate::{Error, Logger, LogLevel, MMKV}; + use crate::{Error, LogLevel, Logger, MMKV}; pub(super) const LOG_TAG: &str = "MMKV:FFI"; @@ -54,7 +54,7 @@ pub mod ffi { } #[no_mangle] - pub extern fn __use_typed_array(typed_array: RawTypedArray) { + pub extern "C" fn __use_typed_array(typed_array: RawTypedArray) { error!(LOG_TAG, "{:?}", typed_array) } @@ -62,8 +62,8 @@ pub mod ffi { #[derive(Debug)] pub struct NativeLogger { obj: *mut c_void, - callback: extern fn(obj: *mut c_void, level: i32, content: *const ByteSlice), - destroy: extern fn(obj: *mut c_void), + callback: extern "C" fn(obj: *mut c_void, level: i32, content: *const ByteSlice), + destroy: extern "C" fn(obj: *mut c_void), } unsafe impl Send for NativeLogger {} @@ -80,9 +80,7 @@ pub mod ffi { impl NativeLogger { fn call_target(&self, log_level: LogLevel, log_str: String) { let ptr = Box::into_raw(Box::new(ByteSlice::new(log_str))); - (self.callback)( - self.obj, log_level as i32, ptr, - ); + (self.callback)(self.obj, log_level as i32, ptr); unsafe { let _ = Box::from_raw(ptr); } @@ -202,58 +200,60 @@ pub mod ffi { } fn map_error(key: &str, e: Error, log: &str) -> InternalError { - error!(LOG_TAG, "{}", format!("failed to {} for key {}, reason {:?}", log, key, e)); + error!( + LOG_TAG, + "{}", + format!("failed to {} for key {}, reason {:?}", log, key, e) + ); return e.try_into().unwrap(); } macro_rules! impl_put { ($name:ident, $value_type:tt, $type_token:expr, $log:literal) => { #[no_mangle] - pub extern fn $name(key: RawCStr, value: $value_type) -> *const RawBuffer { + pub extern "C" fn $name(key: RawCStr, value: $value_type) -> *const RawBuffer { let key_str = unsafe { CStr::from_ptr(key) }.to_str().unwrap(); let mut result = RawBuffer::new($type_token); match mmkv_put!(key_str, value, $value_type) { - Err(e) => { - result.set_error(map_error(key_str, e, $log)) - } + Err(e) => result.set_error(map_error(key_str, e, $log)), Ok(()) => { verbose!(LOG_TAG, "{} for key '{}' success", $log, key_str); } } return result.leak(); } - } + }; } macro_rules! impl_put_typed_array { ($name:ident, $value_type:tt, $type_token:expr, $log:literal) => { #[no_mangle] - pub extern fn $name(key: RawCStr, value: $value_type, len: usize) -> *const RawBuffer { + pub extern "C" fn $name( + key: RawCStr, + value: $value_type, + len: usize, + ) -> *const RawBuffer { let key_str = unsafe { CStr::from_ptr(key) }.to_str().unwrap(); let mut result = Box::new(RawBuffer::new($type_token)); match mmkv_put!(key_str, value, len, $value_type) { - Err(e) => { - result.set_error(map_error(key_str, e, $log)) - } + Err(e) => result.set_error(map_error(key_str, e, $log)), Ok(()) => { verbose!(LOG_TAG, "{} for key '{}' success", $log, key_str); } } return result.leak(); } - } + }; } macro_rules! impl_get { ($name:ident, $value_type:tt, $type_token:expr, $log:literal) => { #[no_mangle] - pub extern fn $name(key: RawCStr) -> *const RawBuffer { + pub extern "C" fn $name(key: RawCStr) -> *const RawBuffer { let key_str = unsafe { CStr::from_ptr(key) }.to_str().unwrap(); let mut result = RawBuffer::new($type_token); match mmkv_get!(key_str, $value_type) { - Err(e) => { - result.set_error(map_error(key_str, e, $log)) - } + Err(e) => result.set_error(map_error(key_str, e, $log)), Ok(value) => { verbose!(LOG_TAG, "{} for key '{}' success", $log, key_str); result.set_data(value); @@ -261,37 +261,37 @@ pub mod ffi { } return result.leak(); } - } + }; } #[no_mangle] - pub extern fn initialize(dir: *const c_char) { + pub extern "C" fn initialize(dir: *const c_char) { let dir_str = unsafe { CStr::from_ptr(dir) }.to_str().unwrap(); MMKV::initialize(dir_str) } #[no_mangle] - pub extern fn set_logger(logger: NativeLogger) { + pub extern "C" fn set_logger(logger: NativeLogger) { MMKV::set_logger(Box::new(logger)); } #[no_mangle] - pub extern fn set_log_level(log_level: i32) { + pub extern "C" fn set_log_level(log_level: i32) { MMKV::set_log_level(log_level.try_into().unwrap()) } #[no_mangle] - pub unsafe extern fn free_buffer(ptr: *const c_void) { + pub unsafe extern "C" fn free_buffer(ptr: *const c_void) { let _ = RawBuffer::from_raw(ptr as *mut RawBuffer); } #[no_mangle] - pub extern fn close_instance() { + pub extern "C" fn close_instance() { MMKV::close() } #[no_mangle] - pub extern fn clear_data() { + pub extern "C" fn clear_data() { MMKV::clear_data() } @@ -319,9 +319,19 @@ pub mod ffi { impl_get!(get_f64, f64, Types::F64, "get f64"); - impl_put_typed_array!(put_byte_array, CByteArray, Types::ByteArray, "put byte array"); + impl_put_typed_array!( + put_byte_array, + CByteArray, + Types::ByteArray, + "put byte array" + ); - impl_get!(get_byte_array, CByteArray, Types::ByteArray, "get byte array"); + impl_get!( + get_byte_array, + CByteArray, + Types::ByteArray, + "get byte array" + ); impl_put_typed_array!(put_i32_array, CI32Array, Types::I32Array, "put i32 array"); @@ -338,4 +348,4 @@ pub mod ffi { impl_put_typed_array!(put_f64_array, CF64Array, Types::F64Array, "put f64 array"); impl_get!(get_f64_array, CF64Array, Types::F64Array, "get f64 array"); -} \ No newline at end of file +} diff --git a/src/lib.rs b/src/lib.rs index cf678a5..0ae8149 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -11,8 +11,8 @@ //! MMKV::clear_data(); //! ``` //! For detailed API doc, see [MMKV] -pub use crate::log::Logger; pub use crate::log::LogLevel; +pub use crate::log::Logger; pub use crate::mmkv::MMKV; #[derive(Debug, PartialEq)] @@ -79,9 +79,9 @@ macro_rules! verbose { } mod core; -#[cfg(target_os = "android")] -mod jni; #[cfg(any(target_os = "ios", target_os = "macos"))] mod ffi; +#[cfg(target_os = "android")] +mod jni; mod log; mod mmkv; diff --git a/src/log/logger.rs b/src/log/logger.rs index 2b01ec7..767d935 100644 --- a/src/log/logger.rs +++ b/src/log/logger.rs @@ -2,7 +2,7 @@ use std::fmt::{Arguments, Debug}; use std::sync::atomic::{AtomicI32, AtomicPtr, Ordering}; use std::sync::OnceLock; -use crate::log::{Logger, LogLevel}; +use crate::log::{LogLevel, Logger}; const LOG_TAG: &str = "MMKV:LOG"; diff --git a/tests/integration_test.rs b/tests/integration_test.rs index 1dd9e25..92d2926 100644 --- a/tests/integration_test.rs +++ b/tests/integration_test.rs @@ -1,74 +1,25 @@ -use std::thread; -#[cfg(feature = "encryption")] use mmkv::Error::KeyNotFound; - use mmkv::MMKV; - -fn test_api() { - MMKV::put_i32("first", 1).unwrap(); - MMKV::put_i32("second", 2).unwrap(); - assert_eq!(MMKV::get_i32("first"), Ok(1)); - assert_eq!(MMKV::get_str("first").is_err(), true); - assert_eq!(MMKV::get_bool("first").is_err(), true); - assert_eq!(MMKV::get_i32("second"), Ok(2)); - assert_eq!(MMKV::get_i32("third").is_err(), true); - MMKV::put_i32("third", 3).unwrap(); - assert_eq!(MMKV::get_i32("third"), Ok(3)); - MMKV::put_str("fourth", "four").unwrap(); - assert_eq!(MMKV::get_str("fourth"), Ok("four".to_string())); - MMKV::put_str("first", "one").unwrap(); - assert_eq!(MMKV::get_i32("first").is_err(), true); - assert_eq!(MMKV::get_str("first"), Ok("one".to_string())); - MMKV::put_bool("second", false).unwrap(); - assert_eq!(MMKV::get_str("second").is_err(), true); - assert_eq!(MMKV::get_bool("second"), Ok(false)); -} +use std::fs; #[test] fn integration_test() { - #[cfg(feature = "encryption")] - test_encrypt_decrypt(); - MMKV::initialize( - ".", - #[cfg(feature = "encryption")] - "88C51C536176AD8A8EE4A06F62EE897E", - ); - thread::scope(|s| { - s.spawn(|| { - test_api(); - }); - for i in 0..4 { - s.spawn(move || { - for j in (i * 1000)..(i + 1) * 1000 { - let key = format!("key_{j}"); - MMKV::put_str(&key, &key).unwrap(); - } - }); - } - }); - for i in 0..4000 { - let key = format!("key_{i}"); - assert_eq!(MMKV::get_str(&key).unwrap(), key) - } - MMKV::clear_data(); -} - -#[cfg(feature = "encryption")] -fn test_encrypt_decrypt() { + let _ = fs::remove_file("mini_mmkv"); + let _ = fs::remove_file("mini_mmkv.meta"); for i in 0..10 { println!("repeat {}", i); MMKV::initialize( ".", #[cfg(feature = "encryption")] - "88C51C536176AD8A8EE4A06F62EE897E", + "88C51C536176AD8A8EE4A06F62EE897E", ); - let result = MMKV::get_str("test_encrypt_decrypt"); + let result = MMKV::get_str("integration_test"); if i == 0 { assert_eq!(result, Err(KeyNotFound)); } else { assert_eq!(result, Ok((i - 1).to_string())) } - MMKV::put_str("test_encrypt_decrypt", &i.to_string()).unwrap(); + MMKV::put_str("integration_test", &i.to_string()).unwrap(); } MMKV::clear_data(); -} \ No newline at end of file +}