numext_constructor/fixed_hash/core/internal/public_basic.rs
1// Copyright 2018-2019 Cryptape Technologies LLC.
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9//! Define public methods about bits and bytes.
10
11use crate::fixed_hash::HashConstructor;
12use crate::utils;
13use quote::quote;
14
15impl HashConstructor {
16 pub fn defun_pub_basic(&self) {
17 self.defun_pub_bits_ops();
18 self.defun_pub_bytes_ops();
19 self.defun_pub_ptr_ops();
20 self.defun_pub_mem_ops();
21 }
22
23 fn defun_pub_bits_ops(&self) {
24 let bits_size = &self.ts.bits_size;
25 let loop_unit_amount = &utils::pure_uint_list_to_ts(0..self.info.unit_amount);
26 let loop_unit_amount_rev = &utils::pure_uint_list_to_ts((0..self.info.unit_amount).rev());
27 let part = quote!(
28 /// Return the count of bits.
29 #[inline]
30 pub const fn count_bits() -> u64 {
31 #bits_size
32 }
33 /// Return a specific bit, or return None when overlows.
34 ///
35 /// Order from low to high.
36 #[inline]
37 pub fn bit(&self, index: usize) -> Option<bool> {
38 if index >= #bits_size {
39 None
40 } else {
41 let inner = self.inner();
42 let unit_idx = index / 8;
43 let bit_idx = index % 8;
44 Some(inner[unit_idx] & (1 << bit_idx) != 0)
45 }
46 }
47 /// Set a specific bit.
48 /// Return false when overflows.
49 ///
50 /// Order from low to high.
51 #[inline]
52 pub fn set_bit(&mut self, index: usize, value: bool) -> bool {
53 if index >= #bits_size {
54 false
55 } else {
56 let inner = self.mut_inner();
57 let unit_idx = index / 8;
58 let bit_idx = index % 8;
59 if value {
60 inner[unit_idx] |= 1 << bit_idx;
61 } else {
62 inner[unit_idx] &= !(1 << bit_idx);
63 }
64 true
65 }
66 }
67 /// Return the highest bit which is one.
68 ///
69 /// Order from low to high.
70 #[inline]
71 pub fn highest_one(&self) -> Option<usize> {
72 let inner = self.inner();
73 #({
74 let idx = #loop_unit_amount_rev;
75 let v = inner[idx];
76 if v != 0 {
77 let x = 8 * (idx + 1) - 1;
78 let y = v.leading_zeros() as usize;
79 return Some(x - y);
80 }
81 })*
82 None
83 }
84 /// Return the lowest bit which is one.
85 ///
86 /// Order from low to high.
87 #[inline]
88 pub fn lowest_one(&self) -> Option<usize> {
89 let inner = self.inner();
90 #({
91 let idx = #loop_unit_amount;
92 let v = inner[idx];
93 if v != 0 {
94 let x = 8 * idx;
95 let y = v.trailing_zeros() as usize;
96 return Some(x + y);
97 }
98 })*
99 None
100 }
101 );
102 self.defun(part);
103 }
104
105 fn defun_pub_bytes_ops(&self) {
106 let bytes_size = &self.ts.unit_amount;
107 let loop_unit_amount = &utils::pure_uint_list_to_ts(0..self.info.unit_amount);
108 let loop_unit_amount_rev = &utils::pure_uint_list_to_ts((0..self.info.unit_amount).rev());
109 let part = quote!(
110 /// Return the count of bytes.
111 #[inline]
112 pub const fn count_bytes() -> u64 {
113 #bytes_size
114 }
115 /// Return a specific byte, or return None when overlows.
116 #[inline]
117 pub fn byte(&self, index: usize) -> Option<u8> {
118 if index >= #bytes_size {
119 None
120 } else {
121 let inner = self.inner();
122 Some(inner[index])
123 }
124 }
125 /// Set a specific byte.
126 /// Return false when overflows;
127 #[inline]
128 pub fn set_byte(&mut self, index: usize, byte: u8) -> bool {
129 if index >= #bytes_size {
130 false
131 } else {
132 let inner = self.mut_inner();
133 inner[index] = byte;
134 true
135 }
136 }
137 /// Return the highest byte which is nonzero.
138 #[inline]
139 pub fn highest_nonzero_byte(&self) -> Option<usize> {
140 let inner = self.inner();
141 #({
142 let idx: usize = #loop_unit_amount_rev;
143 let v = inner[idx];
144 if v != 0 {
145 return Some(idx);
146 }
147 })*
148 None
149 }
150 /// Return the lowest byte which is nonzero.
151 #[inline]
152 pub fn lowest_nonzero_byte(&self) -> Option<usize> {
153 let inner = self.inner();
154 #({
155 let idx: usize = #loop_unit_amount;
156 let v = inner[idx];
157 if v != 0 {
158 return Some(idx);
159 }
160 })*
161 None
162 }
163 );
164 self.defun(part);
165 }
166
167 fn defun_pub_ptr_ops(&self) {
168 let inner_type = &self.ts.inner_type;
169 let part = quote!(
170 /// Get the inner bytes slice of a fixed hash.
171 #[inline]
172 pub fn as_bytes(&self) -> &[u8] {
173 &self.inner()[..]
174 }
175 /// Get the mutable inner bytes slice of a fixed hash.
176 #[inline]
177 pub fn as_bytes_mut(&mut self) -> &mut [u8] {
178 &mut self.mut_inner()[..]
179 }
180 /// Get the inner bytes of a fixed hash.
181 #[inline]
182 pub fn as_fixed_bytes(&self) -> &#inner_type {
183 self.inner()
184 }
185 /// Get the mutable inner bytes of a fixed hash.
186 #[inline]
187 pub fn as_fixed_bytes_mut(&mut self) -> &mut #inner_type {
188 self.mut_inner()
189 }
190 /// Get the inner bytes array of a fixed hash.
191 #[inline]
192 pub fn into_fixed_bytes(self) -> #inner_type {
193 self.into_inner()
194 }
195 /// Get a vec of a fixed hash.
196 #[inline]
197 pub fn to_vec(&self) -> Vec<u8> {
198 self.inner().to_vec()
199 }
200 /// Get a constant raw pointer to the inner bytes array of a fixed hash.
201 #[inline]
202 pub fn as_ptr(&self) -> *const u8 {
203 self.inner().as_ptr()
204 }
205 /// Get a mutable raw pointer to the inner bytes array of a fixed hash.
206 #[inline]
207 pub fn as_mut_ptr(&mut self) -> *mut u8 {
208 self.mut_inner().as_mut_ptr()
209 }
210 );
211 self.defun(part);
212 }
213
214 fn defun_pub_mem_ops(&self) {
215 let bytes_size = &self.ts.unit_amount;
216 let part = quote!(
217 /// Return the size used by this type in bytes, actually.
218 ///
219 /// This size is greater than or equal to the bytes of this fixed type.
220 #[inline]
221 pub const fn size_of() -> usize {
222 #bytes_size
223 }
224 );
225 self.defun(part);
226 }
227}