bit_byte_bit/scheme.rs
1use std::fmt::{Debug};
2use crate::{Bits};
3
4
5/// Defines a region of bits.
6///
7/// Each field has a unit, size, and a flag indicating if the field represents a signed integer.
8/// The unit is the minimum number of bits extracted by the field. The size is the total number
9/// of units extracted by the field.
10///
11/// The flag comes into play when a field extracts more bits than are available. If at least one
12/// bit is still available and the flag is true, the bit string is sign extended to the length of
13/// the field.
14///
15/// ## Constants
16///
17/// Common field types.
18///
19/// | Constant | Unit | Size | Signed |
20/// |:-------------:|:----:|:-------:|:------:|
21/// | `BIT` | 1 | 1 |
22/// | `BYTES` | 8 | UNBOUND |
23/// | `SIGNED` | 1 | UNBOUND | X
24/// | `SIGNED_2` | 1 | 2 | X
25/// | `SIGNED_4` | 1 | 4 | X
26/// | `SIGNED_8` | 1 | 8 | X
27/// | `SIGNED_16` | 1 | 16 | X
28/// | `SIGNED_32` | 1 | 32 | X
29/// | `SIGNED_64` | 1 | 64 | X
30/// | `UNSIGNED` | 1 | UNBOUND |
31/// | `UNSIGNED_2` | 1 | 2 |
32/// | `UNSIGNED_4` | 1 | 4 |
33/// | `UNSIGNED_8` | 1 | 8 |
34/// | `UNSIGNED_16` | 1 | 16 |
35/// | `UNSIGNED_32` | 1 | 32 |
36/// | `UNSIGNED_64` | 1 | 64 |
37///
38#[derive(Debug, Copy, Clone)]
39pub struct Field {
40 size: isize,
41 unit: usize,
42 signed: bool
43}
44
45impl Field {
46 pub const BIT: Field = Field { size: 1, unit: 1, signed: false };
47 pub const BYTES: Field = Field { size: -1, unit: 8, signed: false };
48 pub const SIGNED: Field = Field { size: -1, unit: 1, signed: true };
49 pub const SIGNED_2: Field = Field { size: 2, unit: 1, signed: true };
50 pub const SIGNED_4: Field = Field { size: 4, unit: 1, signed: true };
51 pub const SIGNED_8: Field = Field { size: 8, unit: 1, signed: true };
52 pub const SIGNED_16: Field = Field { size: 16, unit: 1, signed: true };
53 pub const SIGNED_32: Field = Field { size: 32, unit: 1, signed: true };
54 pub const SIGNED_64: Field = Field { size: 64, unit: 1, signed: true };
55 pub const UNSIGNED: Field = Field { size: -1, unit: 1, signed: false };
56 pub const UNSIGNED_2: Field = Field { size: 2, unit: 1, signed: false };
57 pub const UNSIGNED_4: Field = Field { size: 4, unit: 1, signed: false };
58 pub const UNSIGNED_8: Field = Field { size: 8, unit: 1, signed: false };
59 pub const UNSIGNED_16: Field = Field { size: 16, unit: 1, signed: false };
60 pub const UNSIGNED_32: Field = Field { size: 32, unit: 1, signed: false };
61 pub const UNSIGNED_64: Field = Field { size: 64, unit: 1, signed: false };
62
63 /// Bit field aligned to a given unit
64 ///
65 /// When `m` and `n` are negative `Bits::aligned(m, signed) == Bits::aligned(n, signed)`,
66 /// even if `m != n`.
67 ///
68 /// Example
69 /// ```
70 /// # use bit_byte_bit::{Field};
71 /// let field = Field::aligned(7, 48, false);
72 ///
73 /// assert_eq!(field.unit(), 7);
74 /// assert_eq!(field.size(), 48);
75 /// assert_eq!(field.len(), 48 * 7);
76 ///
77 /// let mfield = Field::aligned(7, -1, true);
78 /// let nfield = Field::aligned(7, isize::MIN, true);
79 ///
80 /// assert_eq!(mfield, nfield);
81 /// assert_eq!(mfield.size(), -1);
82 /// assert_eq!(nfield.size(), -1);
83 /// assert!(mfield.is_signed());
84 /// ```
85 pub fn aligned(unit: usize, size: isize, signed: bool) -> Self { Field { size, unit, signed } }
86
87 /// Byte-aligned bit field
88 ///
89 /// When `m` and `n` are negative `Bits::bytes(m, signed) == Bits::bytes(n, signed)`,
90 /// even if `m != n`.
91 ///
92 /// Example
93 /// ```
94 /// # use bit_byte_bit::{Field};
95 /// let field = Field::bytes(48, false);
96 ///
97 /// assert_eq!(field.unit(), 8);
98 /// assert_eq!(field.size(), 48);
99 /// assert_eq!(field.len(), 48 * 8);
100 ///
101 /// let mfield = Field::bytes(-1, true);
102 /// let nfield = Field::bytes(isize::MIN, true);
103 ///
104 /// assert_eq!(mfield, nfield);
105 /// assert_eq!(mfield.size(), -1);
106 /// assert_eq!(nfield.size(), -1);
107 /// assert!(mfield.is_signed());
108 /// ```
109 pub fn bytes(size: isize, signed: bool) -> Self { Field { size, unit: 8, signed } }
110
111 /// Bit field
112 ///
113 /// When `m` and `n` are negative `Bits::bits(m, signed) == Bits::bits(n, signed)`,
114 /// even if `m != n`.
115 ///
116 /// Example
117 /// ```
118 /// # use bit_byte_bit::{Field};
119 /// let field = Field::signed(96);
120 ///
121 /// assert_eq!(field.unit(), 1);
122 /// assert_eq!(field.size(), 96);
123 /// assert_eq!(field.len(), 96);
124 /// assert!(field.is_signed());
125 ///
126 /// let mfield = Field::signed(-1);
127 /// let nfield = Field::signed(isize::MIN);
128 ///
129 /// assert_eq!(mfield, nfield);
130 /// assert_eq!(mfield.size(), -1);
131 /// assert_eq!(nfield.size(), -1);
132 /// assert!(mfield.is_signed());
133 ///
134 /// ```
135 pub fn signed(size: isize) -> Self { Field { size, unit: 1, signed: true } }
136
137 /// Bit field
138 ///
139 /// When `m` and `n` are negative `Bits::bits(m, signed) == Bits::bits(n, signed)`,
140 /// even if `m != n`.
141 ///
142 /// Example
143 /// ```
144 /// # use bit_byte_bit::{Field};
145 /// let field = Field::unsigned(96);
146 ///
147 /// assert_eq!(field.unit(), 1);
148 /// assert_eq!(field.size(), 96);
149 /// assert_eq!(field.len(), 96);
150 /// assert!(!field.is_signed());
151 ///
152 /// let mfield = Field::unsigned(-1);
153 /// let nfield = Field::unsigned(isize::MIN);
154 ///
155 /// assert_eq!(mfield, nfield);
156 /// assert_eq!(mfield.size(), -1);
157 /// assert_eq!(nfield.size(), -1);
158 /// assert!(!mfield.is_signed());
159 ///
160 /// ```
161 pub fn unsigned(size: isize) -> Self { Field { size, unit: 1, signed: false } }
162
163 /// Whether this field represents a signed integer.
164 ///
165 /// Example
166 /// ```
167 /// # use bit_byte_bit::{Field};
168 /// assert!(Field::aligned(7, 48, true).is_signed());
169 /// assert!(!Field::aligned(7, 48, false).is_signed());
170 /// assert!(Field::bytes(-1, true).is_signed());
171 /// assert!(!Field::bytes(-1, false).is_signed());
172 /// assert!(Field::signed(96).is_signed());
173 /// assert!(!Field::unsigned(96).is_signed());
174 /// ```
175 pub fn is_signed(&self) -> bool { self.signed }
176
177 /// Number of bits extracted by the field
178 ///
179 /// `-1` means that the field extracts the maximum number of bits that can be divided by the
180 /// `unit` of the field. Extraction never exceeds the remaining the number of bits.
181 ///
182 /// Example
183 /// ```
184 /// # use bit_byte_bit::{Field};
185 /// assert_eq!(Field::aligned(0, -1, true).len(), 0);
186 /// assert_eq!(Field::aligned(7, 0, false).len(), 0);
187 /// assert_eq!(Field::aligned(7, 48, true).len(), 48 * 7);
188 /// assert_eq!(Field::aligned(7, -1, false).len(), -1);
189 /// assert_eq!(Field::aligned(7, isize::MIN, true).len(), -1);
190 /// assert_eq!(Field::bytes(48, true).len(), 48 * 8);
191 /// assert_eq!(Field::bytes(-1, false).len(), -1);
192 /// assert_eq!(Field::bytes(isize::MIN, true).len(), -1);
193 /// assert_eq!(Field::signed(48).len(), 48);
194 /// assert_eq!(Field::signed(-1).len(), -1);
195 /// assert_eq!(Field::signed(isize::MIN).len(), -1);
196 /// assert_eq!(Field::unsigned(48).len(), 48);
197 /// assert_eq!(Field::unsigned(-1).len(), -1);
198 /// assert_eq!(Field::unsigned(isize::MIN).len(), -1);
199 /// ```
200 pub fn len(&self) -> isize {
201 match (self.size, self.unit) {
202 (0, _) | (_, 0) => 0,
203 (size, _) if size < 0 => -1,
204 (size, unit) => size * (unit as isize)
205 }
206 }
207
208 /// Number of units in the field
209 ///
210 /// Example
211 /// ```
212 /// # use bit_byte_bit::{Field};
213 /// assert_eq!(Field::aligned(7, 48, true).size(), 48);
214 /// assert_eq!(Field::aligned(7, -1, false).size(), -1);
215 /// assert_eq!(Field::aligned(7, isize::MIN, true).size(), -1);
216 /// assert_eq!(Field::bytes(48, true).size(), 48);
217 /// assert_eq!(Field::bytes(-1, false).size(), -1);
218 /// assert_eq!(Field::bytes(isize::MIN, true).size(), -1);
219 /// assert_eq!(Field::signed(48).size(), 48);
220 /// assert_eq!(Field::signed(-1).size(), -1);
221 /// assert_eq!(Field::signed(isize::MIN).size(), -1);
222 /// assert_eq!(Field::unsigned(48).size(), 48);
223 /// assert_eq!(Field::unsigned(-1).size(), -1);
224 /// assert_eq!(Field::unsigned(isize::MIN).size(), -1);
225 /// ```
226 pub fn size(&self) -> isize { if self.size < 0 { -1 } else { self.size } }
227
228 /// Minimum number of bits extracted by the field.
229 ///
230 /// Example
231 /// ```
232 /// # use bit_byte_bit::{Field};
233 /// assert_eq!(Field::aligned(7, 48, true).unit(), 7);
234 /// assert_eq!(Field::aligned(7, -1, false).unit(), 7);
235 /// assert_eq!(Field::aligned(7, isize::MIN, true).unit(), 7);
236 /// assert_eq!(Field::bytes(48, true).unit(), 8);
237 /// assert_eq!(Field::bytes(-1, false).unit(), 8);
238 /// assert_eq!(Field::bytes(isize::MIN, true).unit(), 8);
239 /// assert_eq!(Field::signed(48).unit(), 1);
240 /// assert_eq!(Field::signed(-1).unit(), 1);
241 /// assert_eq!(Field::signed(isize::MIN).unit(), 1);
242 /// assert_eq!(Field::unsigned(48).unit(), 1);
243 /// assert_eq!(Field::unsigned(-1).unit(), 1);
244 /// assert_eq!(Field::unsigned(isize::MIN).unit(), 1);
245 /// ```
246 pub fn unit(&self) -> usize { self.unit }
247
248 fn default(&self) -> Bits {
249 let length = self.len();
250
251 if length <= 0 {
252 Bits::empty()
253 } else {
254 Bits::zeros(length as usize)
255 }
256 }
257
258 fn extract(&self, bits: &Bits, bits_len: usize, start: usize) -> Bits {
259 let length = self.len();
260
261 if length == 0 { return Bits::empty() }
262
263 if length < 0 { return self.extract_var_data(bits, bits_len, start); }
264
265 let length = length as usize;
266 let end = start + length;
267
268 if end > bits_len {
269 let x_len = bits_len - start;
270
271 let mut remaining_bits = Bits::take(bits.bytes(), start, x_len);
272 let signed = self.signed && remaining_bits.i(x_len - 1) == 1;
273
274 remaining_bits.push_left(signed, end - bits_len);
275
276 remaining_bits
277 } else {
278 Bits::take(bits.bytes(), start, length)
279 }
280 }
281
282 fn extract_var_data(&self, bits: &Bits, bits_len: usize, start: usize) -> Bits {
283 let remaining = bits_len - start;
284
285 Bits::take(bits.bytes(), start, remaining - (remaining % self.unit))
286 }
287}
288
289impl Eq for Field {}
290
291impl PartialEq for Field {
292 fn eq(&self, other: &Field) -> bool {
293 self.unit == other.unit
294 && self.signed == other.signed
295 && ((self.size < 0 && other.size < 0) || (self.size == other.size))
296 }
297}
298
299
300/// Defines a pattern giving meaning to different regions of a bit string.
301pub struct Scheme(Vec<Field>);
302
303impl Scheme {
304 /// # Example
305 /// ```
306 /// # use bit_byte_bit::{bits_as, Bits, Field, Scheme};
307 ///
308 /// let unsigned_3 = Field::unsigned(3);
309 ///
310 /// let scheme = Scheme::new([
311 /// Field::signed(5),
312 /// Field::BIT,
313 /// unsigned_3,
314 /// unsigned_3,
315 /// Field::UNSIGNED_4,
316 /// Field::aligned(23, 1, true),
317 /// Field::unsigned(32),
318 /// Field::signed(32),
319 /// Field::bytes(4, false),
320 /// Field::aligned(6, 8, true)
321 /// ]);
322 ///
323 /// let time_since_epoch = Field::UNSIGNED_64;
324 /// let identifier = Field::UNSIGNED_8;
325 /// let datatype = Field::UNSIGNED_4;
326 /// let data = Field::BYTES;
327 ///
328 /// let scheme2 = Scheme::new([time_since_epoch, identifier, datatype, data]);
329 /// ```
330 pub fn new<I: IntoIterator<Item = Field>>(pattern: I) -> Self {
331 Scheme(pattern.into_iter().collect())
332 }
333
334 /// Number of bits extracted
335 ///
336 /// If any field in the scheme has a negative length, this method returns -1, indicating
337 /// the scheme extracts a variable number of bits.
338 ///
339 /// # Example
340 /// ```
341 /// # use bit_byte_bit::{bits_as, Bits, Field, Scheme};
342 ///
343 /// let unsigned_3 = Field::unsigned(3);
344 ///
345 /// let scheme = Scheme::new([
346 /// Field::signed(5), Field::BIT, unsigned_3, unsigned_3, Field::UNSIGNED_4
347 /// ]);
348 ///
349 /// assert_eq!(scheme.len(), 16);
350 ///
351 /// let scheme2 = Scheme::new([
352 /// Field::aligned(23, 1, true),
353 /// Field::unsigned(0),
354 /// Field::unsigned(32),
355 /// Field::bytes(4, false),
356 /// Field::aligned(0, 8, false),
357 /// Field::aligned(7, 8, true)
358 /// ]);
359 ///
360 /// let scheme3 = Scheme::new([
361 /// Field::aligned(23, 1, true),
362 /// Field::unsigned(0),
363 /// Field::unsigned(32),
364 /// Field::signed(-1),
365 /// Field::bytes(4, false),
366 /// Field::aligned(0, 8, false),
367 /// Field::aligned(7, 8, true)
368 /// ]);
369 ///
370 /// assert_eq!(scheme3.len(), -1);
371 /// ```
372 pub fn len(&self) -> isize {
373 let mut acc = 0;
374
375 for field in &self.0 {
376 let n = field.len();
377
378 if n < 0 { return -1; }
379
380 acc += n
381 }
382
383 acc
384 }
385
386 /// Extracts the data associated with the fields of this scheme
387 ///
388 /// # Example
389 /// ```
390 /// # use bit_byte_bit::{bits_as, Bits, Field, Scheme};
391 ///
392 /// let unsigned_3 = Field::unsigned(3);
393 ///
394 /// let scheme = Scheme::new([
395 /// Field::signed(5), Field::BIT, unsigned_3, unsigned_3, Field::UNSIGNED_4
396 /// ]);
397 ///
398 /// let bits = Bits::new([0xBA, 0x1C]);
399 /// let parts = scheme.split_bits(&bits);
400 ///
401 /// assert_eq!(bits_as::int8(&parts[0]), -6);
402 /// assert_eq!(bits_as::uint8(&parts[1]), 1);
403 /// assert_eq!(bits_as::uint8(&parts[2]), 2);
404 /// assert_eq!(bits_as::uint8(&parts[3]), 6);
405 /// assert_eq!(bits_as::uint8(&parts[4]), 1);
406 ///
407 /// let bits2 = Bits::new([0xBA]);
408 /// let parts2 = scheme.split_bits(&bits2);
409 ///
410 /// assert_eq!(bits_as::int8(&parts2[0]), -6);
411 /// assert_eq!(bits_as::uint8(&parts2[1]), 1);
412 /// assert_eq!(bits_as::uint8(&parts2[2]), 2);
413 /// assert_eq!(bits_as::uint8(&parts2[3]), 0);
414 /// assert_eq!(bits_as::uint8(&parts2[4]), 0);
415 ///
416 /// let scheme2 = Scheme::new([
417 /// Field::aligned(23, -1, true),
418 /// Field::aligned(0, -1, false),
419 /// Field::bytes(-1, false),
420 /// Field::signed(-1),
421 /// Field::unsigned(-1),
422 /// Field::unsigned(0),
423 /// Field::unsigned(32),
424 /// Field::bytes(4, false),
425 /// Field::aligned(0, 8, false),
426 /// Field::aligned(7, 8, true),
427 /// Field::signed(-1),
428 /// Field::unsigned(-1)
429 /// ]);
430 ///
431 /// let bytes = [0xBA, 0xDC, 0xFE, 0x10, 0x32];
432 /// let bits3 = Bits::from(bytes.as_slice()); // 38-bits
433 /// let parts = scheme2.split_bits(&bits3);
434 ///
435 /// assert_eq!(bits_as::int32(&parts[0]), 0xFFFEDCBAu32 as i32);
436 /// assert_eq!(parts[1], Bits::empty());
437 /// assert_eq!(bits_as::vec_u8(&parts[2]), vec![0x21]);
438 /// assert_eq!(bits_as::vec_i32(&parts[3]), vec![-28]);
439 /// assert_eq!(parts[4], Bits::empty());
440 /// assert_eq!(parts[5], Bits::empty());
441 /// assert_eq!(parts[6], Bits::zeros(32));
442 /// assert_eq!(parts[7], Bits::zeros(32));
443 /// assert_eq!(parts[8], Bits::empty());
444 /// assert_eq!(parts[9], Bits::zeros(56));
445 /// assert_eq!(parts[10], Bits::empty());
446 /// assert_eq!(parts[11], Bits::empty());
447 /// ```
448 pub fn split_bits(&self, bits: &Bits) -> Vec<Bits> { self.split_bits_at(0, bits) }
449
450 /// Extracts the data associated with the fields of this scheme.
451 ///
452 /// # Example
453 /// ```
454 /// # use bit_byte_bit::{bits_as, Bits, Field, Scheme};
455 ///
456 /// let unsigned_3 = Field::unsigned(3);
457 ///
458 /// let scheme = Scheme::new([
459 /// Field::signed(5), Field::BIT, unsigned_3, unsigned_3, Field::UNSIGNED_4
460 /// ]);
461 ///
462 /// let bits = Bits::new([0xBA, 0x1C]);
463 /// let parts = scheme.split_bits_at(0, &bits);
464 ///
465 /// assert_eq!(bits_as::int8(&parts[0]), -6);
466 /// assert_eq!(bits_as::uint8(&parts[1]), 1);
467 /// assert_eq!(bits_as::uint8(&parts[2]), 2);
468 /// assert_eq!(bits_as::uint8(&parts[3]), 6);
469 /// assert_eq!(bits_as::uint8(&parts[4]), 1);
470 ///
471 /// let parts2 = scheme.split_bits_at(8, &bits);
472 ///
473 /// assert_eq!(bits_as::int8(&parts2[0]), -4);
474 /// assert_eq!(bits_as::uint8(&parts2[1]), 0);
475 /// assert_eq!(bits_as::uint8(&parts2[2]), 0);
476 /// assert_eq!(bits_as::uint8(&parts2[3]), 0);
477 /// assert_eq!(bits_as::uint8(&parts2[4]), 0);
478 ///
479 /// let scheme2 = Scheme::new([
480 /// Field::aligned(23, -1, true),
481 /// Field::aligned(0, -1, false),
482 /// Field::bytes(-1, false),
483 /// Field::signed(-1),
484 /// Field::unsigned(-1),
485 /// Field::unsigned(0),
486 /// Field::unsigned(32),
487 /// Field::bytes(4, false),
488 /// Field::aligned(0, 8, false),
489 /// Field::aligned(7, 8, true),
490 /// Field::signed(-1),
491 /// Field::unsigned(-1)
492 /// ]);
493 ///
494 /// let bytes = [0xBA, 0xDC, 0xFE, 0x10, 0x32];
495 /// let bits3 = Bits::from(bytes.as_slice()); // 38-bits
496 /// let parts = scheme2.split_bits_at(4, &bits3);
497 ///
498 /// assert_eq!(bits_as::int32(&parts[0]), 0x0FEDCB);
499 /// assert_eq!(parts[1], Bits::empty());
500 /// assert_eq!(bits_as::vec_u8(&parts[2]), vec![0x42]);
501 /// assert_eq!(bits_as::vec_i32(&parts[3]), vec![-2]);
502 /// assert_eq!(parts[4], Bits::empty());
503 /// assert_eq!(parts[5], Bits::empty());
504 /// assert_eq!(parts[6], Bits::zeros(32));
505 /// assert_eq!(parts[7], Bits::zeros(32));
506 /// assert_eq!(parts[8], Bits::empty());
507 /// assert_eq!(parts[9], Bits::zeros(56));
508 /// assert_eq!(parts[10], Bits::empty());
509 /// assert_eq!(parts[11], Bits::empty());
510 /// ```
511 pub fn split_bits_at(&self, index: usize, bits: &Bits) -> Vec<Bits> {
512 let length = bits.len();
513 let mut matches = Vec::with_capacity(self.0.len());
514 let mut index = index;
515
516 for field in &self.0 {
517 if index >= length {
518 matches.push(field.default());
519 } else {
520 let data = field.extract(&bits, length, index);
521
522 index += data.len();
523 matches.push(data);
524 }
525 }
526
527 matches
528 }
529
530 /// Extracts the data associated with the fields of this scheme
531 ///
532 /// # Example
533 /// ```
534 /// # use bit_byte_bit::{bits_as, Bits, Field, Scheme};
535 ///
536 /// let unsigned_3 = Field::unsigned(3);
537 ///
538 /// let scheme = Scheme::new([
539 /// Field::signed(5), Field::BIT, unsigned_3, unsigned_3, Field::UNSIGNED_4
540 /// ]);
541 ///
542 /// let parts = scheme.split_bytes([0xBA, 0x1C]);
543 ///
544 /// assert_eq!(bits_as::int8(&parts[0]), -6);
545 /// assert_eq!(bits_as::uint8(&parts[1]), 1);
546 /// assert_eq!(bits_as::uint8(&parts[2]), 2);
547 /// assert_eq!(bits_as::uint8(&parts[3]), 6);
548 /// assert_eq!(bits_as::uint8(&parts[4]), 1);
549 ///
550 /// let parts2 = scheme.split_bytes([0xBA]);
551 ///
552 /// assert_eq!(bits_as::int8(&parts2[0]), -6);
553 /// assert_eq!(bits_as::uint8(&parts2[1]), 1);
554 /// assert_eq!(bits_as::uint8(&parts2[2]), 2);
555 /// assert_eq!(bits_as::uint8(&parts2[3]), 0);
556 /// assert_eq!(bits_as::uint8(&parts2[4]), 0);
557 ///
558 /// let scheme2 = Scheme::new([
559 /// Field::aligned(23, -1, true),
560 /// Field::aligned(0, -1, false),
561 /// Field::bytes(-1, false),
562 /// Field::signed(-1),
563 /// Field::unsigned(-1),
564 /// Field::unsigned(0),
565 /// Field::unsigned(32),
566 /// Field::bytes(4, false),
567 /// Field::aligned(0, 8, false),
568 /// Field::aligned(7, 8, true),
569 /// Field::signed(-1),
570 /// Field::unsigned(-1)
571 /// ]);
572 ///
573 /// let parts = scheme2.split_bytes(vec![0xBA, 0xDC, 0xFE, 0x10, 0x32]);
574 ///
575 /// assert_eq!(bits_as::int32(&parts[0]), 0xFFFEDCBAu32 as i32);
576 /// assert_eq!(parts[1], Bits::empty());
577 /// assert_eq!(bits_as::vec_u8(&parts[2]), vec![0x21, 0x64]);
578 /// assert_eq!(parts[3], Bits::zeros(1));
579 /// assert_eq!(bits_as::int64(&parts[4]), 0);
580 /// assert_eq!(parts[5], Bits::empty());
581 /// assert_eq!(parts[6], Bits::zeros(32));
582 /// assert_eq!(parts[7], Bits::zeros(32));
583 /// assert_eq!(parts[8], Bits::empty());
584 /// assert_eq!(parts[9], Bits::zeros(56));
585 /// assert_eq!(parts[10], Bits::empty());
586 /// assert_eq!(parts[11], Bits::empty());
587 /// ```
588 pub fn split_bytes<I: IntoIterator<Item=u8>>(&self, bytes: I) -> Vec<Bits> {
589 self.split_bits_at(0, &Bits::new(bytes))
590 }
591
592 /// Extracts the data associated with the fields of this scheme.
593 ///
594 /// # Example
595 /// ```
596 /// # use bit_byte_bit::{bits_as, Bits, Field, Scheme};
597 ///
598 /// let unsigned_3 = Field::unsigned(3);
599 ///
600 /// let scheme = Scheme::new([
601 /// Field::signed(5), Field::BIT, unsigned_3, unsigned_3, Field::UNSIGNED_4
602 /// ]);
603 ///
604 /// let parts = scheme.split_bytes_at(0, [0xBA, 0x1C]);
605 ///
606 /// assert_eq!(bits_as::int8(&parts[0]), -6);
607 /// assert_eq!(bits_as::uint8(&parts[1]), 1);
608 /// assert_eq!(bits_as::uint8(&parts[2]), 2);
609 /// assert_eq!(bits_as::uint8(&parts[3]), 6);
610 /// assert_eq!(bits_as::uint8(&parts[4]), 1);
611 ///
612 /// let parts2 = scheme.split_bytes_at(8, [0xBA, 0x1C]);
613 ///
614 /// assert_eq!(bits_as::int8(&parts2[0]), -4);
615 /// assert_eq!(bits_as::uint8(&parts2[1]), 0);
616 /// assert_eq!(bits_as::uint8(&parts2[2]), 0);
617 /// assert_eq!(bits_as::uint8(&parts2[3]), 0);
618 /// assert_eq!(bits_as::uint8(&parts2[4]), 0);
619 ///
620 /// let scheme2 = Scheme::new([
621 /// Field::aligned(23, -1, true),
622 /// Field::aligned(0, -1, false),
623 /// Field::bytes(-1, false),
624 /// Field::signed(-1),
625 /// Field::unsigned(-1),
626 /// Field::unsigned(0),
627 /// Field::unsigned(32),
628 /// Field::bytes(4, false),
629 /// Field::aligned(0, 8, false),
630 /// Field::aligned(7, 8, true),
631 /// Field::signed(-1),
632 /// Field::unsigned(-1)
633 /// ]);
634 ///
635 /// let parts = scheme2.split_bytes_at(4, [0xBA, 0xDC, 0xFE, 0x10, 0x32]);
636 ///
637 /// assert_eq!(bits_as::int32(&parts[0]), 0x0FEDCB);
638 /// assert_eq!(parts[1], Bits::empty());
639 /// assert_eq!(bits_as::vec_u8(&parts[2]), vec![0x42]);
640 /// assert_eq!(bits_as::vec_i32(&parts[3]), vec![6]);
641 /// assert_eq!(parts[4], Bits::empty());
642 /// assert_eq!(parts[5], Bits::empty());
643 /// assert_eq!(parts[6], Bits::zeros(32));
644 /// assert_eq!(parts[7], Bits::zeros(32));
645 /// assert_eq!(parts[8], Bits::empty());
646 /// assert_eq!(parts[9], Bits::zeros(56));
647 /// assert_eq!(parts[10], Bits::empty());
648 /// assert_eq!(parts[11], Bits::empty());
649 /// ```
650 pub fn split_bytes_at<I: IntoIterator<Item=u8>>(&self, index: usize, bytes: I) -> Vec<Bits> {
651 self.split_bits_at(index, &Bits::new(bytes))
652 }
653
654
655}
656