Skip to content

Commit 168529d

Browse files
authored
ndk/asset: Add missing is_allocated() and open_file_descriptor() (#409)
These two functions are not exactly critical but may be useful to some developers. `is_allocated()` tells us whether a backing buffer is created in RAM, or if the data is directly `mmap()`'ed from the APK (e.g. because no decompression was needed and alignment requirements are upheld). Note that it only returns `true` after the asset is "mapped" (or read in some way) via e.g `get_buffer()`; solely opening the asset is not enough to trigger the allocation and decompression. `open_file_descriptor()` gives the user a file descriptor, which simply seems to be a `dup()` of that from the opened APK, together with an offset and size of the given `AAsset` within that APK. It also requires the asset to be stored uncompressed within the APK.
1 parent 9b94b63 commit 168529d

File tree

2 files changed

+40
-1
lines changed

2 files changed

+40
-1
lines changed

ndk/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
- native_window: Add `lock()` to blit raw pixel data. (#404)
1919
- hardware_buffer_format: Add `YCbCr_P010` and `R8_UNORM` variants. (#405)
2020
- **Breaking:** hardware_buffer_format: Add catch-all variant. (#407)
21+
- ndk/asset: Add missing `is_allocated()` and `open_file_descriptor()` methods. (#409)
2122
- **Breaking:** media_codec: Add support for asynchronous notification callbacks. (#410)
2223
- Add panic guards to callbacks. (#412)
2324
- looper: Add `remove_fd()` to unregister events/callbacks for a file descriptor. (#416)

ndk/src/asset.rs

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
77
use std::ffi::{CStr, CString};
88
use std::io;
9+
// TODO: Import from std::os::fd::{} since Rust 1.66
10+
use std::os::unix::io::{FromRawFd, OwnedFd};
911
use std::ptr::NonNull;
1012

1113
/// A native [`AAssetManager *`]
@@ -224,7 +226,34 @@ impl Asset {
224226
}
225227
}
226228

227-
//pub fn open_file_descriptor(&self) -> TODO
229+
/// Returns whether this asset's internal buffer is allocated in ordinary RAM (i.e. not `mmap`ped).
230+
#[doc(alias = "AAsset_isAllocated")]
231+
pub fn is_allocated(&self) -> bool {
232+
unsafe { ffi::AAsset_isAllocated(self.ptr.as_ptr()) != 0 }
233+
}
234+
235+
/// Open a new file descriptor that can be used to read the asset data.
236+
///
237+
/// Returns an error if direct fd access is not possible (for example, if the asset is compressed).
238+
#[doc(alias = "AAsset_openFileDescriptor64")]
239+
pub fn open_file_descriptor(&self) -> io::Result<OpenedFileDescriptor> {
240+
let mut offset = 0;
241+
let mut size = 0;
242+
let res =
243+
unsafe { ffi::AAsset_openFileDescriptor64(self.ptr.as_ptr(), &mut offset, &mut size) };
244+
if res >= 0 {
245+
Ok(OpenedFileDescriptor {
246+
fd: unsafe { OwnedFd::from_raw_fd(res) },
247+
offset: offset as usize,
248+
size: size as usize,
249+
})
250+
} else {
251+
Err(io::Error::new(
252+
io::ErrorKind::Other,
253+
"Android Asset openFileDescriptor error",
254+
))
255+
}
256+
}
228257
}
229258

230259
impl io::Read for Asset {
@@ -268,3 +297,12 @@ impl io::Seek for Asset {
268297
}
269298
}
270299
}
300+
301+
/// Contains the opened file descriptor returned by [`Asset::open_file_descriptor()`], together
302+
/// with the offset and size of the given asset within that file descriptor.
303+
#[derive(Debug)]
304+
pub struct OpenedFileDescriptor {
305+
pub fd: OwnedFd,
306+
pub offset: usize,
307+
pub size: usize,
308+
}

0 commit comments

Comments
 (0)