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