skia_safe/core/
data_table.rs1use crate::prelude::*;
2use skia_bindings::{self as sb, SkDataTable, SkRefCntBase};
3use std::{
4 ffi::{CStr, c_void},
5 fmt, mem,
6 ops::Index,
7};
8
9pub type DataTable = RCHandle<SkDataTable>;
10unsafe_send_sync!(DataTable);
11require_type_equality!(sb::SkDataTable_INHERITED, sb::SkRefCnt);
12
13impl NativeRefCountedBase for SkDataTable {
14 type Base = SkRefCntBase;
15}
16
17impl Index<usize> for DataTable {
18 type Output = [u8];
19
20 fn index(&self, index: usize) -> &Self::Output {
21 self.at(index)
22 }
23}
24
25impl fmt::Debug for DataTable {
26 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
27 f.debug_struct("DataTable")
28 .field("count", &self.count())
29 .finish()
30 }
31}
32
33impl DataTable {
34 pub fn is_empty(&self) -> bool {
35 self.count() == 0
36 }
37
38 pub fn count(&self) -> usize {
39 unsafe { sb::C_SkDataTable_count(self.native()) }
40 .try_into()
41 .unwrap()
42 }
43
44 pub fn at_size(&self, index: usize) -> usize {
45 assert!(index < self.count());
46 unsafe { self.native().atSize(index.try_into().unwrap()) }
47 }
48
49 pub fn at(&self, index: usize) -> &[u8] {
50 unsafe { self.at_t(index) }
51 }
52
53 #[allow(clippy::missing_safety_doc)]
54 pub unsafe fn at_t<T: Copy>(&self, index: usize) -> &[T] {
55 unsafe {
56 assert!(index < self.count());
57 let mut size = usize::default();
58 let ptr = self.native().at(index.try_into().unwrap(), &mut size);
59 let element_size = mem::size_of::<T>();
60 assert_eq!(size % element_size, 0);
61 let elements = size / element_size;
62 safer::from_raw_parts(ptr as _, elements)
63 }
64 }
65
66 pub fn at_str(&self, index: usize) -> &CStr {
67 let bytes = self.at(index);
68 CStr::from_bytes_with_nul(bytes).unwrap()
69 }
70
71 pub fn new_empty() -> Self {
72 DataTable::from_ptr(unsafe { sb::C_SkDataTable_MakeEmpty() }).unwrap()
73 }
74
75 pub fn from_slices(slices: &[&[u8]]) -> Self {
76 let ptrs: Vec<*const c_void> = slices.iter().map(|s| s.as_ptr() as _).collect();
77 let sizes: Vec<usize> = slices.iter().map(|s| s.len()).collect();
78 unsafe {
79 DataTable::from_ptr(sb::C_SkDataTable_MakeCopyArrays(
80 ptrs.as_ptr(),
81 sizes.as_ptr(),
82 slices.len().try_into().unwrap(),
83 ))
84 .unwrap()
85 }
86 }
87
88 pub fn from_slice<T: Copy>(slice: &[T]) -> Self {
89 unsafe {
90 DataTable::from_ptr(sb::C_SkDataTable_MakeCopyArray(
91 slice.as_ptr() as _,
92 mem::size_of::<T>(),
93 slice.len().try_into().unwrap(),
94 ))
95 .unwrap()
96 }
97 }
98
99 pub fn iter(&self) -> Iter {
102 Iter {
103 table: self,
104 count: self.count(),
105 current: 0,
106 }
107 }
108}
109
110#[derive(Debug)]
111pub struct Iter<'a> {
112 table: &'a DataTable,
113 count: usize,
114 current: usize,
115}
116
117impl<'a> Iterator for Iter<'a> {
118 type Item = &'a [u8];
119
120 fn next(&mut self) -> Option<Self::Item> {
121 if self.current < self.count {
122 let r = Some(self.table.at(self.current));
123 self.current += 1;
124 r
125 } else {
126 None
127 }
128 }
129}