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}