summaryrefslogtreecommitdiffstats
path: root/third_party/rust/deflate/src/lzvalue.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
commit2aa4a82499d4becd2284cdb482213d541b8804dd (patch)
treeb80bf8bf13c3766139fbacc530efd0dd9d54394c /third_party/rust/deflate/src/lzvalue.rs
parentInitial commit. (diff)
downloadfirefox-2aa4a82499d4becd2284cdb482213d541b8804dd.tar.xz
firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.zip
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/deflate/src/lzvalue.rs')
-rw-r--r--third_party/rust/deflate/src/lzvalue.rs121
1 files changed, 121 insertions, 0 deletions
diff --git a/third_party/rust/deflate/src/lzvalue.rs b/third_party/rust/deflate/src/lzvalue.rs
new file mode 100644
index 0000000000..acbbde8b20
--- /dev/null
+++ b/third_party/rust/deflate/src/lzvalue.rs
@@ -0,0 +1,121 @@
+use huffman_table::{MAX_DISTANCE, MIN_MATCH};
+#[cfg(test)]
+use huffman_table::MAX_MATCH;
+
+#[derive(Copy, Clone, Eq, PartialEq, Debug)]
+pub struct StoredLength {
+ length: u8,
+}
+
+impl StoredLength {
+ #[cfg(test)]
+ pub fn from_actual_length(length: u16) -> StoredLength {
+ assert!(length <= MAX_MATCH && length >= MIN_MATCH);
+ StoredLength {
+ length: (length - MIN_MATCH) as u8,
+ }
+ }
+
+ pub fn new(stored_length: u8) -> StoredLength {
+ StoredLength {
+ length: stored_length,
+ }
+ }
+
+ pub fn stored_length(&self) -> u8 {
+ self.length
+ }
+
+ #[cfg(test)]
+ pub fn actual_length(&self) -> u16 {
+ u16::from(self.length) + MIN_MATCH
+ }
+}
+
+#[derive(Copy, Clone, Eq, PartialEq, Debug)]
+pub enum LZType {
+ Literal(u8),
+ StoredLengthDistance(StoredLength, u16),
+}
+
+#[derive(Copy, Clone, Eq, PartialEq, Debug)]
+pub struct LZValue {
+ litlen: u8,
+ distance: u16,
+}
+
+impl LZValue {
+ #[inline]
+ pub fn literal(value: u8) -> LZValue {
+ LZValue {
+ litlen: value,
+ distance: 0,
+ }
+ }
+
+ #[inline]
+ pub fn length_distance(length: u16, distance: u16) -> LZValue {
+ debug_assert!(distance > 0 && distance <= MAX_DISTANCE);
+ let stored_length = (length - MIN_MATCH) as u8;
+ LZValue {
+ litlen: stored_length,
+ distance: distance,
+ }
+ }
+
+ #[inline]
+ pub fn value(&self) -> LZType {
+ if self.distance != 0 {
+ LZType::StoredLengthDistance(StoredLength::new(self.litlen), self.distance)
+ } else {
+ LZType::Literal(self.litlen)
+ }
+ }
+}
+
+#[cfg(test)]
+pub fn lit(l: u8) -> LZValue {
+ LZValue::literal(l)
+}
+
+#[cfg(test)]
+pub fn ld(l: u16, d: u16) -> LZValue {
+ LZValue::length_distance(l, d)
+}
+
+#[cfg(test)]
+mod test {
+ use super::*;
+ use huffman_table::{MIN_MATCH, MIN_DISTANCE, MAX_MATCH, MAX_DISTANCE};
+ #[test]
+ fn lzvalue() {
+ for i in 0..255 as usize + 1 {
+ let v = LZValue::literal(i as u8);
+ if let LZType::Literal(n) = v.value() {
+ assert_eq!(n as usize, i);
+ } else {
+ panic!();
+ }
+ }
+
+ for i in MIN_MATCH..MAX_MATCH + 1 {
+ let v = LZValue::length_distance(i, 5);
+ if let LZType::StoredLengthDistance(l, _) = v.value() {
+ assert_eq!(l.actual_length(), i);
+ } else {
+ panic!();
+ }
+ }
+
+ for i in MIN_DISTANCE..MAX_DISTANCE + 1 {
+ let v = LZValue::length_distance(5, i);
+
+ if let LZType::StoredLengthDistance(_, d) = v.value() {
+ assert_eq!(d, i);
+ } else {
+ panic!("Failed to get distance {}", i);
+ }
+ }
+
+ }
+}