Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/third_party/rust/headers/src/common/   (Firefox Browser Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 6 kB image not shown  

Quelle  content_range.rs

  Sprache: Rust
 

use std::fmt;
use std::ops::{Bound, RangeBounds};

use {util, HeaderValue};

/// Content-Range, described in [RFC7233](https://tools.ietf.org/html/rfc7233#section-4.2)
///
/// # ABNF
///
/// ```text
/// Content-Range       = byte-content-range
///                     / other-content-range
///
/// byte-content-range  = bytes-unit SP
///                       ( byte-range-resp / unsatisfied-range )
///
/// byte-range-resp     = byte-range "/" ( complete-length / "*" )
/// byte-range          = first-byte-pos "-" last-byte-pos
/// unsatisfied-range   = "*/" complete-length
///
/// complete-length     = 1*DIGIT
///
/// other-content-range = other-range-unit SP other-range-resp
/// other-range-resp    = *CHAR
/// ```
///
/// # Example
///
/// ```
/// # extern crate headers;
/// use headers::ContentRange;
///
/// // 100 bytes (included byte 199), with a full length of 3,400
/// let cr = ContentRange::bytes(100..200, 3400).unwrap();
/// ```
//NOTE: only supporting bytes-content-range, YAGNI the extension
#[derive(Clone, Debug, PartialEq)]
pub struct ContentRange {
    /// First and last bytes of the range, omitted if request could not be
    /// satisfied
    range: Option<(u64, u64)>,

    /// Total length of the instance, can be omitted if unknown
    complete_length: Option<u64>,
}

error_type!(InvalidContentRange);

impl ContentRange {
    /// Construct a new `Content-Range: bytes ..` header.
    pub fn bytes(
        range: impl RangeBounds<u64>,
        complete_length: impl Into<Option<u64>>,
    ) -> Result<ContentRange, InvalidContentRange> {
        let complete_length = complete_length.into();

        let start = match range.start_bound() {
            Bound::Included(&s) => s,
            Bound::Excluded(&s) => s + 1,
            Bound::Unbounded => 0,
        };

        let end = match range.end_bound() {
            Bound::Included(&e) => e,
            Bound::Excluded(&e) => e - 1,
            Bound::Unbounded => match complete_length {
                Some(max) => max - 1,
                None => return Err(InvalidContentRange { _inner: () }),
            },
        };

        Ok(ContentRange {
            range: Some((start, end)),
            complete_length,
        })
    }

    /// Create a new `ContentRange` stating the range could not be satisfied.
    ///
    /// The passed argument is the complete length of the entity.
    pub fn unsatisfied_bytes(complete_length: u64) -> Self {
        ContentRange {
            range: None,
            complete_length: Some(complete_length),
        }
    }

    /// Get the byte range if satisified.
    ///
    /// Note that these byte ranges are inclusive on both ends.
    pub fn bytes_range(&self) -> Option<(u64, u64)> {
        self.range
    }

    /// Get the bytes complete length if available.
    pub fn bytes_len(&self) -> Option<u64> {
        self.complete_length
    }
}

impl ::Header for ContentRange {
    fn name() -> &'static ::HeaderName {
        &::http::header::CONTENT_RANGE
    }

    fn decode<'i, I: Iterator<Item = &'i HeaderValue>>(values: &mut I) -> Result<Self, ::Error> {
        values
            .next()
            .and_then(|v| v.to_str().ok())
            .and_then(|s| split_in_two(s, ' '))
            .and_then(|(unit, spec)| {
                if unit != "bytes" {
                    // For now, this only supports bytes-content-range. nani?
                    return None;
                }

                let (range, complete_length) = split_in_two(spec, '/')?;

                let complete_length = if complete_length == "*" {
                    None
                } else {
                    Some(complete_length.parse().ok()?)
                };

                let range = if range == "*" {
                    None
                } else {
                    let (first_byte, last_byte) = split_in_two(range, '-')?;
                    let first_byte = first_byte.parse().ok()?;
                    let last_byte = last_byte.parse().ok()?;
                    if last_byte < first_byte {
                        return None;
                    }
                    Some((first_byte, last_byte))
                };

                Some(ContentRange {
                    range,
                    complete_length,
                })
            })
            .ok_or_else(::Error::invalid)
    }

    fn encode<E: Extend<::HeaderValue>>(&self, values: &mut E) {
        struct Adapter<'a>(&'a ContentRange);

        impl<'a> fmt::Display for Adapter<'a> {
            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                f.write_str("bytes ")?;

                if let Some((first_byte, last_byte)) = self.0.range {
                    write!(f, "{}-{}", first_byte, last_byte)?;
                } else {
                    f.write_str("*")?;
                }

                f.write_str("/")?;

                if let Some(v) = self.0.complete_length {
                    write!(f, "{}", v)
                } else {
                    f.write_str("*")
                }
            }
        }

        values.extend(::std::iter::once(util::fmt(Adapter(self))));
    }
}

fn split_in_two(s: &str, separator: char) -> Option<(&str, &str)> {
    let mut iter = s.splitn(2, separator);
    match (iter.next(), iter.next()) {
        (Some(a), Some(b)) => Some((a, b)),
        _ => None,
    }
}

/*
test_header!(test_bytes,
    vec![b"bytes 0-499/500"],
    Some(ContentRange(ContentRangeSpec::Bytes {
        range: Some((0, 499)),
        complete_length: Some(500)
    })));

test_header!(test_bytes_unknown_len,
    vec![b"bytes 0-499/*"],
    Some(ContentRange(ContentRangeSpec::Bytes {
        range: Some((0, 499)),
        complete_length: None
    })));

test_header!(test_bytes_unknown_range,
    vec![b"bytes */

500"],
            Some(ContentRange(ContentRangeSpec::Bytes {
                range: None,
                complete_length: Some(500)
            })));

        test_header!(test_unregistered,
            vec![b"seconds 1-2"],
            Some(ContentRange(ContentRangeSpec::Unregistered {
                unit: "seconds".to_owned(),
                resp: "1-2".to_owned()
            })));

        test_header!(test_no_len,
            vec![b"bytes 0-499"],
            None::<ContentRange>);

        test_header!(test_only_unit,
            vec![b"bytes"],
            None::<ContentRange>);

        test_header!(test_end_less_than_start,
            vec![b"bytes 499-0/500"],
            None::<ContentRange>);

        test_header!(test_blank,
            vec![b""],
            None::<ContentRange>);

        test_header!(test_bytes_many_spaces,
            vec![b"bytes 1-2/500 3"],
            None::<ContentRange>);

        test_header!(test_bytes_many_slashes,
            vec![b"bytes 1-2/500/600"],
            None::<ContentRange>);

        test_header!(test_bytes_many_dashes,
            vec![b"bytes 1-2-3/500"],
            None::<ContentRange>);
*/

Messung V0.5 in Prozent
C=82 H=100 G=91

¤ Dauer der Verarbeitung: 0.16 Sekunden  (vorverarbeitet am  2026-06-22) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.