testnumbat_wasm_node/api/
storage_api_node.rs

1use crate::AndesApiImpl;
2use alloc::vec::Vec;
3use testnumbat_wasm::{
4    api::{Handle, StorageReadApi, StorageWriteApi},
5    types::BoxedBytes,
6};
7
8#[rustfmt::skip]
9extern "C" {
10	// general
11	fn storageStore(keyOffset: *const u8, keyLength: i32, dataOffset: *const u8, dataLength: i32) -> i32;
12	fn storageLoadLength(keyOffset: *const u8, keyLength: i32) -> i32;
13	fn storageLoad(keyOffset: *const u8, keyLength: i32, dataOffset: *mut u8) -> i32;
14
15	// big int API
16	fn bigIntNew(value: i64) -> i32;
17	fn bigIntStorageStoreUnsigned(keyOffset: *const u8, keyLength: i32, source: i32) -> i32;
18	fn bigIntStorageLoadUnsigned(keyOffset: *const u8, keyLength: i32, destination: i32) -> i32;
19
20	// small int API
21	fn smallIntStorageStoreUnsigned(keyOffset: *const u8, keyLength: i32, value: i64) -> i32;
22	fn smallIntStorageStoreSigned(keyOffset: *const u8, keyLength: i32, value: i64) -> i32;
23	fn smallIntStorageLoadUnsigned(keyOffset: *const u8, keyLength: i32) -> i64;
24	fn smallIntStorageLoadSigned(keyOffset: *const u8, keyLength: i32) -> i64;
25
26    // managed buffer API
27    fn mBufferNew() -> i32;
28    fn mBufferStorageStore(keyHandle: i32, mBufferHandle: i32) -> i32;
29    fn mBufferStorageLoad(keyHandle: i32, mBufferHandle: i32) -> i32;
30    fn mBufferGetLength(mBufferHandle: i32) -> i32;
31}
32
33impl StorageReadApi for AndesApiImpl {
34    #[inline]
35    fn storage_load_len(&self, key: &[u8]) -> usize {
36        unsafe { storageLoadLength(key.as_ref().as_ptr(), key.len() as i32) as usize }
37    }
38
39    fn storage_load_vec_u8(&self, key: &[u8]) -> Vec<u8> {
40        unsafe {
41            let value_len = self.storage_load_len(key);
42            let mut res = Vec::with_capacity(value_len);
43            storageLoad(key.as_ref().as_ptr(), key.len() as i32, res.as_mut_ptr());
44            res.set_len(value_len);
45            res
46        }
47    }
48
49    fn storage_load_boxed_bytes(&self, key: &[u8]) -> BoxedBytes {
50        let len = self.storage_load_len(key);
51        unsafe {
52            let mut res = BoxedBytes::allocate(len);
53            if len > 0 {
54                storageLoad(key.as_ref().as_ptr(), key.len() as i32, res.as_mut_ptr());
55            }
56            res
57        }
58    }
59
60    #[inline]
61    fn storage_load_big_uint_raw(&self, key: &[u8]) -> i32 {
62        unsafe {
63            let handle = bigIntNew(0);
64            bigIntStorageLoadUnsigned(key.as_ref().as_ptr(), key.len() as i32, handle);
65            handle
66        }
67    }
68
69    #[inline]
70    fn storage_load_managed_buffer_raw(&self, key_handle: Handle) -> Handle {
71        unsafe {
72            let value_handle = mBufferNew();
73            mBufferStorageLoad(key_handle, value_handle);
74            value_handle
75        }
76    }
77
78    #[inline]
79    fn storage_load_managed_buffer_len(&self, key_handle: Handle) -> usize {
80        unsafe {
81            // TODO: use a temp handle
82            let value_handle = mBufferNew();
83            mBufferStorageLoad(key_handle, value_handle);
84            mBufferGetLength(value_handle) as usize
85        }
86    }
87
88    #[inline]
89    fn storage_load_u64(&self, key: &[u8]) -> u64 {
90        unsafe { smallIntStorageLoadUnsigned(key.as_ref().as_ptr(), key.len() as i32) as u64 }
91    }
92
93    #[inline]
94    fn storage_load_i64(&self, key: &[u8]) -> i64 {
95        unsafe { smallIntStorageLoadSigned(key.as_ref().as_ptr(), key.len() as i32) }
96    }
97}
98
99impl StorageWriteApi for AndesApiImpl {
100    fn storage_store_slice_u8(&self, key: &[u8], value: &[u8]) {
101        unsafe {
102            storageStore(
103                key.as_ref().as_ptr(),
104                key.len() as i32,
105                value.as_ptr(),
106                value.len() as i32,
107            );
108        }
109    }
110
111    #[inline]
112    fn storage_store_big_uint_raw(&self, key: &[u8], handle: i32) {
113        unsafe {
114            bigIntStorageStoreUnsigned(key.as_ref().as_ptr(), key.len() as i32, handle);
115        }
116    }
117
118    fn storage_store_managed_buffer_raw(&self, key_handle: Handle, value_handle: Handle) {
119        unsafe {
120            mBufferStorageStore(key_handle, value_handle);
121        }
122    }
123
124    fn storage_store_managed_buffer_clear(&self, key_handle: Handle) {
125        unsafe {
126            let value_handle = mBufferNew();
127            mBufferStorageStore(key_handle, value_handle);
128        }
129    }
130
131    #[inline]
132    fn storage_store_u64(&self, key: &[u8], value: u64) {
133        unsafe {
134            smallIntStorageStoreUnsigned(key.as_ref().as_ptr(), key.len() as i32, value as i64);
135        }
136    }
137
138    #[inline]
139    fn storage_store_i64(&self, key: &[u8], value: i64) {
140        unsafe {
141            smallIntStorageStoreSigned(key.as_ref().as_ptr(), key.len() as i32, value);
142        }
143    }
144}