rust_rcs_core/internet/headers/
byte_range.rs

1// Copyright 2023 宋昊文
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15// slice_representation sr1 = {s->internal + s->start, i1};
16// slice_representation sr2 = {s->internal + s->start + i1 + 1, i2};
17// slice_representation sr3 = {s->internal + s->start + i2 + 1, s->end - s->start - i2 - 1};
18
19// slice *s1 = slice_copy_representation(sr1);
20// slice *s2 = slice_copy_representation(sr2);
21// slice *s3 = slice_copy_representation(sr3);
22
23// struct byte_range_header_value *byte_range = calloc(1, sizeof(struct byte_range_header_value));
24
25// byte_range->from = slice_to_integer(s1);
26// if (slice_equals_static_str(s2, "*", true))
27// {
28//     byte_range->to = SIZE_MAX;
29// }
30// else
31// {
32//     byte_range->to = slice_to_integer(s2);
33// }
34// byte_range->total = slice_to_integer(s3);
35
36// return byte_range;
37use crate::util::raw_string::ToInt;
38
39pub struct ByteRange {
40    pub from: usize,
41    pub to: Option<usize>,
42    pub total: usize,
43}
44
45pub fn parse(s: &[u8]) -> Option<ByteRange> {
46    let mut iter = s.iter();
47    if let Some(i1) = iter.position(|c| *c == b'-') {
48        if let Some(i2) = iter.position(|c| *c == b'/') {
49            let s1 = &s[..i1];
50            let s2 = &s[i1 + 1..i1 + 1 + i2];
51            let s3 = &s[i1 + 1 + i2 + 1..];
52
53            if let Ok(from) = s1.to_int() {
54                if let Ok(total) = s3.to_int() {
55                    if total >= from || (from == 1 && total == 0) {
56                        if s2 == b"*" {
57                            return Some(ByteRange {
58                                from,
59                                to: None,
60                                total,
61                            });
62                        } else if let Ok(to) = s2.to_int() {
63                            if total >= to && (to >= from || (from == 1 && to == 0)) {
64                                return Some(ByteRange {
65                                    from,
66                                    to: Some(to),
67                                    total,
68                                });
69                            }
70                        }
71                    }
72                }
73            }
74        }
75    }
76
77    None
78}