ndarray_npy/npy/elements/
num.rs1use super::{bytes_as_mut_slice, bytes_as_slice, check_for_extra_bytes};
4use crate::{ReadDataError, ReadableElement, ViewDataError, ViewElement, ViewMutElement};
5use byteorder::{BigEndian, LittleEndian, ReadBytesExt};
6use py_literal::Value as PyValue;
7use std::io;
8
9macro_rules! impl_readable_primitive_one_byte {
10 ($elem:ty, [$($desc:expr),*], $zero:expr, $read_into:ident) => {
11 impl ReadableElement for $elem {
12 fn read_to_end_exact_vec<R: io::Read>(
13 mut reader: R,
14 type_desc: &PyValue,
15 len: usize,
16 ) -> Result<Vec<Self>, ReadDataError> {
17 match *type_desc {
18 PyValue::String(ref s) if $(s == $desc)||* => {
19 let mut out = vec![$zero; len];
20 reader.$read_into(&mut out)?;
21 check_for_extra_bytes(&mut reader)?;
22 Ok(out)
23 }
24 ref other => Err(ReadDataError::WrongDescriptor(other.clone())),
25 }
26 }
27 }
28 };
29}
30
31macro_rules! impl_view_and_view_mut_primitive_one_byte {
32 ($elem:ty, [$($desc:expr),*]) => {
33 impl ViewElement for $elem {
34 fn bytes_as_slice<'a>(
35 bytes: &'a [u8],
36 type_desc: &PyValue,
37 len: usize,
38 ) -> Result<&'a [Self], ViewDataError> {
39 match *type_desc {
40 PyValue::String(ref s) if $(s == $desc)||* => unsafe {
41 bytes_as_slice(bytes, len)
42 }
43 ref other => Err(ViewDataError::WrongDescriptor(other.clone())),
44 }
45 }
46 }
47
48 impl ViewMutElement for $elem {
49 fn bytes_as_mut_slice<'a>(
50 bytes: &'a mut [u8],
51 type_desc: &PyValue,
52 len: usize,
53 ) -> Result<&'a mut [Self], ViewDataError> {
54 match *type_desc {
55 PyValue::String(ref s) if $(s == $desc)||* => unsafe {
56 bytes_as_mut_slice(bytes, len)
57 }
58 ref other => Err(ViewDataError::WrongDescriptor(other.clone())),
59 }
60 }
61 }
62 };
63}
64
65macro_rules! impl_primitive_one_byte {
66 ($elem:ty, $write_desc:expr, [$($read_desc:expr),*], $zero:expr, $read_into:ident) => {
67 impl_writable_element_always_valid_cast!($elem, $write_desc, $write_desc);
68 impl_readable_primitive_one_byte!($elem, [$($read_desc),*], $zero, $read_into);
69 impl_view_and_view_mut_primitive_one_byte!($elem, [$($read_desc),*]);
70 };
71}
72
73impl_primitive_one_byte!(i8, "|i1", ["|i1", "i1", "b"], 0, read_i8_into);
74impl_primitive_one_byte!(u8, "|u1", ["|u1", "u1", "B"], 0, read_exact);
75
76macro_rules! impl_readable_primitive_multi_byte {
77 ($elem:ty, $little_desc:expr, $big_desc:expr, $zero:expr, $read_into:ident) => {
78 impl ReadableElement for $elem {
79 fn read_to_end_exact_vec<R: io::Read>(
80 mut reader: R,
81 type_desc: &PyValue,
82 len: usize,
83 ) -> Result<Vec<Self>, ReadDataError> {
84 let mut out = vec![$zero; len];
85 match *type_desc {
86 PyValue::String(ref s) if s == $little_desc => {
87 reader.$read_into::<LittleEndian>(&mut out)?;
88 }
89 PyValue::String(ref s) if s == $big_desc => {
90 reader.$read_into::<BigEndian>(&mut out)?;
91 }
92 ref other => {
93 return Err(ReadDataError::WrongDescriptor(other.clone()));
94 }
95 }
96 check_for_extra_bytes(&mut reader)?;
97 Ok(out)
98 }
99 }
100 };
101}
102
103macro_rules! impl_primitive_multi_byte {
104 ($elem:ty, $little_desc:expr, $big_desc:expr, $zero:expr, $read_into:ident) => {
105 impl_writable_element_always_valid_cast!($elem, $little_desc, $big_desc);
106 impl_readable_primitive_multi_byte!($elem, $little_desc, $big_desc, $zero, $read_into);
107 #[cfg(target_endian = "little")]
108 impl_view_and_view_mut_always_valid_cast_multi_byte!($elem, $little_desc, $big_desc);
109 #[cfg(target_endian = "big")]
110 impl_view_and_view_mut_always_valid_cast_multi_byte!($elem, $big_desc, $little_desc);
111 };
112}
113
114impl_primitive_multi_byte!(i16, "<i2", ">i2", 0, read_i16_into);
115impl_primitive_multi_byte!(i32, "<i4", ">i4", 0, read_i32_into);
116impl_primitive_multi_byte!(i64, "<i8", ">i8", 0, read_i64_into);
117
118impl_primitive_multi_byte!(u16, "<u2", ">u2", 0, read_u16_into);
119impl_primitive_multi_byte!(u32, "<u4", ">u4", 0, read_u32_into);
120impl_primitive_multi_byte!(u64, "<u8", ">u8", 0, read_u64_into);
121
122impl_primitive_multi_byte!(f32, "<f4", ">f4", 0., read_f32_into);
123impl_primitive_multi_byte!(f64, "<f8", ">f8", 0., read_f64_into);