1use super::primitive_read::*;
2use smart_default::SmartDefault;
3use std::borrow::Cow;
4
5#[cfg(feature = "serialize")]
6use serde::Serialize;
7
8#[cfg_attr(feature = "serialize", derive(Serialize))]
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11pub enum ByteOrder {
12 LittleEndian,
13 BigEndian,
14}
15
16#[derive(Debug, Clone, Copy, PartialEq, Eq)]
17pub enum CompressType {
18 Uncompressed,
19 #[cfg(feature = "gzip")]
20 GzipCompressed,
21 #[cfg(feature = "bzip")]
22 BzipCompressed,
23 #[cfg(feature = "zipfile")]
24 ZipCompressed,
25}
26
27pub type B1 = [u8; 1];
32pub type C1 = char;
35pub type U1 = u8;
36pub type U2 = u16;
37pub type U4 = u32;
38pub type U8 = u64;
39pub type I1 = i8;
40pub type I2 = i16;
41pub type I4 = i32;
42pub type R4 = f32;
43pub type R8 = f64;
44
45pub type Cn = String;
47
48pub type Cf = String;
50
51pub type Sn = String;
53
54pub type Bn = Vec<u8>;
56
57#[cfg_attr(feature = "serialize", derive(Serialize))]
62#[derive(SmartDefault, Debug, Clone, PartialEq, Eq)]
63pub struct Dn {
64 pub bit_count: u16,
65 pub bit_data: Vec<u8>,
66}
67
68pub type KxCn = Vec<Cn>;
69pub type KxSn = Vec<Sn>;
70pub type KxCf = Vec<Cf>;
71pub type KxU1 = Vec<U1>;
72pub type KxU2 = Vec<U2>;
73pub type KxU4 = Vec<U4>;
74pub type KxU8 = Vec<U8>;
75pub type KxR4 = Vec<R4>;
76pub type KxN1 = Vec<U1>;
77
78#[cfg_attr(feature = "serialize", derive(Serialize))]
84#[derive(SmartDefault, Debug, Clone, PartialEq, Eq)]
85pub enum KxUf {
86 #[default]
87 F1(KxU1),
88 F2(KxU2),
89 F4(KxU4),
90 F8(KxU8),
91}
92
93#[cfg_attr(feature = "serialize", derive(Serialize))]
97#[derive(Debug, Clone, PartialEq)]
98pub enum V1 {
99 B0,
100 U1(U1),
101 U2(U2),
102 U4(U4),
103 I1(I1),
104 I2(I2),
105 I4(I4),
106 R4(R4),
107 R8(R8),
108 Cn(Cn),
109 Bn(Bn),
110 Dn(Dn),
111 N1(U1),
112 Invalid,
113}
114
115pub type Vn = Vec<V1>;
116
117pub(crate) const VIEW_ABSENT_OFT: u16 = u16::MAX;
126
127#[inline]
129pub(crate) fn validate_offset(off: u16) -> Option<usize> {
130 if off == VIEW_ABSENT_OFT {
131 None
132 } else {
133 Some(off as usize)
134 }
135}
136
137#[derive(SmartDefault, Clone, Copy, Debug)]
139pub struct CnRef<'a>(&'a [u8]);
140
141#[derive(SmartDefault, Clone, Copy, Debug)]
144pub struct SnRef<'a>(&'a [u8]);
145
146#[derive(SmartDefault, Clone, Copy, Debug)]
148pub struct BnRef<'a>(&'a [u8]);
149
150#[derive(SmartDefault, Clone, Copy, Debug)]
153pub struct DnRef<'a> {
154 bit_count: u16,
155 bit_data: &'a [u8],
156}
157
158#[derive(Clone, Copy, Default)]
174pub struct KxCnRef<'a> {
175 raw: &'a [u8],
176 start: usize,
177 k: usize,
178}
179
180pub struct KxCnRefIter<'a> {
182 raw: &'a [u8],
183 pos: usize,
184 remaining: usize,
185}
186
187#[derive(SmartDefault, Clone, Copy)]
203pub struct KxSnRef<'a> {
204 raw: &'a [u8],
205 start: usize,
206 k: usize,
207 #[default(ByteOrder::LittleEndian)]
208 order: ByteOrder,
209}
210
211pub struct KxSnRefIter<'a> {
213 raw: &'a [u8],
214 pos: usize,
215 remaining: usize,
216 order: ByteOrder,
217}
218
219#[derive(Clone, Copy, Default)]
235pub struct KxCfRef<'a> {
236 raw: &'a [u8],
237 start: usize,
238 k: usize,
239 f: usize,
240}
241
242pub struct KxCfRefIter<'a> {
244 raw: &'a [u8],
245 pos: usize,
246 remaining: usize,
247 f: usize,
248}
249
250impl<'a> CnRef<'a> {
251 #[inline]
254 pub(crate) fn read_at(raw: &'a [u8], off: u16) -> Option<Self> {
255 let p = validate_offset(off)?;
256 let cnt = *raw.get(p)? as usize;
257 let start = p + 1;
258 let end = std::cmp::min(start + cnt, raw.len()); Some(CnRef(&raw[start..end]))
260 }
261
262 #[inline]
264 pub fn as_bytes(&self) -> &'a [u8] {
265 self.0
266 }
267
268 #[inline]
272 pub fn as_str(&self) -> Cow<'a, str> {
273 bytes_to_cow_str(self.0)
274 }
275
276 pub fn to_owned(&self) -> Cn {
279 bytes_to_string(self.0)
280 }
281}
282
283impl<'a> SnRef<'a> {
284 #[inline]
287 pub(crate) fn read_at(raw: &'a [u8], off: u16, order: &ByteOrder) -> Option<Self> {
288 let p = validate_offset(off)?;
289 let mut cp = p;
290 let cnt = read_u2(raw, &mut cp, order) as usize;
291 let start = cp;
292 let end = std::cmp::min(start + cnt, raw.len());
293 Some(SnRef(raw.get(start..end).unwrap_or(&[])))
294 }
295
296 #[inline]
298 pub fn as_bytes(&self) -> &'a [u8] {
299 self.0
300 }
301
302 #[inline]
306 pub fn as_str(&self) -> Cow<'a, str> {
307 bytes_to_cow_str(self.0)
308 }
309
310 pub fn to_owned(&self) -> Sn {
313 bytes_to_string(self.0)
314 }
315}
316
317impl<'a> BnRef<'a> {
318 #[inline]
321 pub(crate) fn read_at(raw: &'a [u8], off: u16) -> Option<Self> {
322 let p = validate_offset(off)?;
323 let cnt = *raw.get(p)? as usize;
324 let start = p + 1;
325 let end = std::cmp::min(start + cnt, raw.len());
326 Some(BnRef(&raw[start..end]))
327 }
328
329 #[inline]
331 pub fn as_bytes(&self) -> &'a [u8] {
332 self.0
333 }
334
335 #[inline]
336 pub fn is_empty(&self) -> bool {
337 self.0.is_empty()
338 }
339
340 #[inline]
341 pub fn len(&self) -> usize {
342 self.0.len()
343 }
344
345 pub fn to_owned(&self) -> Bn {
348 self.0.to_vec()
349 }
350}
351
352impl<'a> DnRef<'a> {
353 #[inline]
356 pub(crate) fn read_at(raw: &'a [u8], off: u16, order: &ByteOrder) -> Option<Self> {
357 let p = validate_offset(off)?;
358 let mut cp = p;
359 let bitcount = read_u2(raw, &mut cp, order);
360 let bytecount = (bitcount as usize).div_ceil(8);
361 let start = cp;
362 let end = std::cmp::min(start + bytecount, raw.len());
363 Some(DnRef {
364 bit_count: bitcount,
365 bit_data: raw.get(start..end).unwrap_or(&[]),
366 })
367 }
368
369 #[inline]
371 pub fn bit_count(&self) -> u16 {
372 self.bit_count
373 }
374
375 #[inline]
377 pub fn as_bytes(&self) -> &'a [u8] {
378 self.bit_data
379 }
380
381 #[inline]
382 pub fn is_empty(&self) -> bool {
383 self.bit_data.is_empty()
384 }
385
386 #[inline]
387 pub fn len(&self) -> usize {
388 self.bit_data.len()
389 }
390
391 pub fn to_owned(&self) -> Dn {
394 Dn {
395 bit_count: self.bit_count,
396 bit_data: self.bit_data.to_vec(),
397 }
398 }
399}
400
401impl<'a> KxCnRef<'a> {
402 #[inline]
407 pub fn new(raw: &'a [u8], start: usize, k: usize) -> Self {
408 KxCnRef { raw, start, k }
409 }
410
411 #[inline]
413 pub fn len(&self) -> usize {
414 self.k
415 }
416
417 #[inline]
419 pub fn is_empty(&self) -> bool {
420 self.k == 0
421 }
422
423 #[inline]
428 pub fn get_str(&self, i: usize) -> Option<Cow<'a, str>> {
429 self.get_bytes(i).map(bytes_to_cow_str)
430 }
431
432 #[inline]
435 pub fn get_bytes(&self, i: usize) -> Option<&'a [u8]> {
436 if i >= self.k {
437 return None;
438 }
439 let mut pos = self.start;
442 for _ in 0..i {
443 let cnt = *self.raw.get(pos)? as usize;
444 pos = std::cmp::min(pos + 1 + cnt, self.raw.len());
445 }
446 let cnt = *self.raw.get(pos)? as usize;
447 let start = pos + 1;
448 let end = std::cmp::min(start + cnt, self.raw.len());
449 Some(&self.raw[start..end])
450 }
451
452 #[inline]
454 pub fn iter(&self) -> KxCnRefIter<'a> {
455 KxCnRefIter {
456 raw: self.raw,
457 pos: self.start,
458 remaining: self.k,
459 }
460 }
461
462 #[inline]
464 pub fn as_vec(&self) -> Vec<Cow<'a, str>> {
465 self.iter().collect()
466 }
467
468 #[inline]
471 pub fn to_owned(&self) -> KxCn {
472 self.iter().map(Cow::into_owned).collect()
473 }
474}
475
476impl<'a> Iterator for KxCnRefIter<'a> {
477 type Item = Cow<'a, str>;
478
479 fn next(&mut self) -> Option<Self::Item> {
480 if self.remaining == 0 {
481 return None;
482 }
483 self.remaining -= 1;
484 let cnt = *self.raw.get(self.pos)? as usize;
485 self.pos += 1;
486 let end = std::cmp::min(self.pos + cnt, self.raw.len());
487 let slice = &self.raw[self.pos..end];
488 self.pos = end;
489 Some(bytes_to_cow_str(slice))
490 }
491}
492
493impl<'a> IntoIterator for &'a KxCnRef<'a> {
494 type Item = Cow<'a, str>;
495 type IntoIter = KxCnRefIter<'a>;
496
497 fn into_iter(self) -> Self::IntoIter {
498 self.iter()
499 }
500}
501
502impl<'a> KxSnRef<'a> {
503 #[inline]
509 pub fn new(raw: &'a [u8], start: usize, k: usize, order: ByteOrder) -> Self {
510 KxSnRef {
511 raw,
512 start,
513 k,
514 order,
515 }
516 }
517
518 #[inline]
520 pub fn len(&self) -> usize {
521 self.k
522 }
523
524 #[inline]
526 pub fn is_empty(&self) -> bool {
527 self.k == 0
528 }
529
530 #[inline]
535 pub fn get_str(&self, i: usize) -> Option<Cow<'a, str>> {
536 self.get_bytes(i).map(bytes_to_cow_str)
537 }
538
539 #[inline]
542 pub fn get_bytes(&self, i: usize) -> Option<&'a [u8]> {
543 if i >= self.k {
544 return None;
545 }
546 let mut pos = self.start;
549 for _ in 0..i {
550 let mut cp = pos;
551 let cnt = read_u2(self.raw, &mut cp, &self.order) as usize;
552 pos = std::cmp::min(cp + cnt, self.raw.len());
553 }
554 let mut cp = pos;
555 let cnt = read_u2(self.raw, &mut cp, &self.order) as usize;
556 let start = cp;
557 let end = std::cmp::min(start + cnt, self.raw.len());
558 Some(self.raw.get(start..end).unwrap_or(&[]))
559 }
560
561 #[inline]
563 pub fn iter(&self) -> KxSnRefIter<'a> {
564 KxSnRefIter {
565 raw: self.raw,
566 pos: self.start,
567 remaining: self.k,
568 order: self.order,
569 }
570 }
571
572 #[inline]
574 pub fn as_vec(&self) -> Vec<Cow<'a, str>> {
575 self.iter().collect()
576 }
577
578 #[inline]
581 pub fn to_owned(&self) -> KxSn {
582 self.iter().map(Cow::into_owned).collect()
583 }
584}
585
586impl<'a> Iterator for KxSnRefIter<'a> {
587 type Item = Cow<'a, str>;
588
589 fn next(&mut self) -> Option<Self::Item> {
590 if self.remaining == 0 {
591 return None;
592 }
593 self.remaining -= 1;
594 let mut cp = self.pos;
595 let cnt = read_u2(self.raw, &mut cp, &self.order) as usize;
596 self.pos = cp;
597 let end = std::cmp::min(self.pos + cnt, self.raw.len());
598 let slice = self.raw.get(self.pos..end).unwrap_or(&[]);
599 self.pos = end;
600 Some(bytes_to_cow_str(slice))
601 }
602}
603
604impl<'a> IntoIterator for &'a KxSnRef<'a> {
605 type Item = Cow<'a, str>;
606 type IntoIter = KxSnRefIter<'a>;
607
608 fn into_iter(self) -> Self::IntoIter {
609 self.iter()
610 }
611}
612
613impl<'a> KxCfRef<'a> {
614 #[inline]
620 pub fn new(raw: &'a [u8], start: usize, k: usize, f: usize) -> Self {
621 KxCfRef { raw, start, k, f }
622 }
623
624 #[inline]
626 pub fn len(&self) -> usize {
627 self.k
628 }
629
630 #[inline]
632 pub fn is_empty(&self) -> bool {
633 self.k == 0
634 }
635
636 #[inline]
641 pub fn get_str(&self, i: usize) -> Option<Cow<'a, str>> {
642 self.get_bytes(i).map(bytes_to_cow_str)
643 }
644
645 #[inline]
648 pub fn get_bytes(&self, i: usize) -> Option<&'a [u8]> {
649 if i >= self.k {
650 return None;
651 }
652 let start = self.start + i * self.f;
653 let end = std::cmp::min(start + self.f, self.raw.len());
654 self.raw.get(start..end)
655 }
656
657 #[inline]
659 pub fn iter(&self) -> KxCfRefIter<'a> {
660 KxCfRefIter {
661 raw: self.raw,
662 pos: self.start,
663 remaining: self.k,
664 f: self.f,
665 }
666 }
667
668 #[inline]
670 pub fn as_vec(&self) -> Vec<Cow<'a, str>> {
671 self.iter().collect()
672 }
673
674 #[inline]
677 pub fn to_owned(&self) -> KxCf {
678 self.iter().map(Cow::into_owned).collect()
679 }
680}
681
682impl<'a> Iterator for KxCfRefIter<'a> {
683 type Item = Cow<'a, str>;
684
685 fn next(&mut self) -> Option<Self::Item> {
686 if self.remaining == 0 {
687 return None;
688 }
689 self.remaining -= 1;
690 let end = std::cmp::min(self.pos + self.f, self.raw.len());
691 let slice = self.raw.get(self.pos..end).unwrap_or(&[]);
692 self.pos = end;
693 Some(bytes_to_cow_str(slice))
694 }
695}
696
697impl<'a> IntoIterator for &'a KxCfRef<'a> {
698 type Item = Cow<'a, str>;
699 type IntoIter = KxCfRefIter<'a>;
700
701 fn into_iter(self) -> Self::IntoIter {
702 self.iter()
703 }
704}
705
706#[inline(always)]
710pub(crate) fn bytes_to_cow_str(data: &[u8]) -> Cow<'_, str> {
711 match std::str::from_utf8(data) {
712 Ok(s) => Cow::Borrowed(s),
713 Err(_) => Cow::Owned(data.iter().map(|&x| x as char).collect()),
714 }
715}
716
717#[inline(always)]
719pub(crate) fn bytes_to_string(data: &[u8]) -> String {
720 bytes_to_cow_str(data).into_owned()
721}