rust_rcs_core/internet/
header.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
15use std::fmt;
16use std::io::Read;
17use std::slice::Iter;
18
19use crate::io::Serializable;
20
21pub struct Header {
22    name: Box<dyn AsRef<[u8]> + Send + Sync>,
23    value: Box<dyn AsRef<[u8]> + Send + Sync>,
24}
25
26impl Header {
27    pub fn new<N, V>(name: N, value: V) -> Header
28    where
29        N: AsRef<[u8]> + Send + Sync + 'static,
30        V: AsRef<[u8]> + Send + Sync + 'static,
31    {
32        Header {
33            name: Box::new(name),
34            value: Box::new(value),
35        }
36    }
37
38    pub fn get_name(&self) -> &[u8] {
39        self.name.as_ref().as_ref()
40    }
41
42    pub fn get_value(&self) -> &[u8] {
43        self.value.as_ref().as_ref()
44    }
45
46    pub fn reader(&self) -> HeaderReader {
47        HeaderReader {
48            header: self,
49            pos: 0,
50        }
51    }
52}
53
54impl Clone for Header {
55    fn clone(&self) -> Self {
56        Header {
57            name: Box::new(self.name.as_ref().as_ref().to_vec()),
58            value: Box::new(self.value.as_ref().as_ref().to_vec()),
59        }
60    }
61}
62
63impl fmt::Debug for Header {
64    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
65        f.debug_struct("Header")
66            .field(
67                &String::from_utf8_lossy(self.name.as_ref().as_ref()),
68                &String::from_utf8_lossy(self.value.as_ref().as_ref()),
69            )
70            .finish()
71    }
72}
73
74pub struct HeaderReader<'a> {
75    header: &'a Header,
76    pos: usize,
77}
78
79impl<'a> Read for HeaderReader<'a> {
80    fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
81        let name = self.header.name.as_ref().as_ref();
82        let value = self.header.value.as_ref().as_ref();
83        let mut i = 0;
84        while self.pos + i < name.len() && i < buf.len() {
85            buf[i] = name[self.pos + i];
86            i += 1;
87        }
88        while self.pos + i >= name.len() && self.pos + i < name.len() + 2 && i < buf.len() {
89            if self.pos + i == name.len() {
90                buf[i] = b':';
91            } else {
92                buf[i] = b' ';
93            }
94            i += 1;
95        }
96        while self.pos + i >= name.len() + 2
97            && self.pos + i < name.len() + 2 + value.len()
98            && i < buf.len()
99        {
100            buf[i] = value[self.pos + i - name.len() - 2];
101            i += 1;
102        }
103        while self.pos + i >= name.len() + 2 + value.len()
104            && self.pos + i < name.len() + 2 + value.len() + 2
105            && i < buf.len()
106        {
107            if self.pos + i == name.len() + 2 + value.len() {
108                buf[i] = b'\r';
109            } else {
110                buf[i] = b'\n';
111            }
112            i += 1;
113        }
114        self.pos += i;
115        Ok(i)
116    }
117}
118
119pub struct HeaderSearch<'a, 'b> {
120    iter: Iter<'a, Header>,
121    name: &'b [u8],
122    ignore_case: bool,
123}
124
125impl<'a, 'b> HeaderSearch<'a, 'b> {
126    pub fn new(headers: &'a [Header], name: &'b [u8], ignore_case: bool) -> HeaderSearch<'a, 'b> {
127        HeaderSearch {
128            iter: headers.iter(),
129            name,
130            ignore_case,
131        }
132    }
133}
134
135impl<'a, 'b> Iterator for HeaderSearch<'a, '_> {
136    type Item = &'a Header;
137    fn next(&mut self) -> Option<&'a Header> {
138        while let Some(h) = self.iter.next() {
139            if self.ignore_case {
140                if h.name.as_ref().as_ref().eq_ignore_ascii_case(self.name) {
141                    return Some(h);
142                }
143            } else {
144                if h.name.as_ref().as_ref().eq(self.name) {
145                    return Some(h);
146                }
147            }
148        }
149
150        None
151    }
152}
153
154pub fn search<'a>(headers: &'a [Header], name: &[u8], ignore_case: bool) -> Option<&'a Header> {
155    HeaderSearch::new(headers, name, ignore_case).next()
156}
157
158impl Serializable for [Header] {
159    // fn serialize(&self) -> Vec<u8> {
160    //     let mut data = Vec::new();
161    //     for header in self {
162    //         data.extend_from_slice(header.name.as_ref().as_ref());
163    //         data.extend(b": ");
164    //         data.extend_from_slice(header.value.as_ref().as_ref());
165    //         data.extend(b"\r\n");
166    //     }
167    //     data
168    // }
169
170    fn estimated_size(&self) -> usize {
171        let mut size = 0;
172        for header in self {
173            size += header.name.as_ref().as_ref().len();
174            size += 2;
175            size += header.value.as_ref().as_ref().len();
176            size += 2;
177        }
178        size
179    }
180}
181
182pub fn headers_get_readers<'a>(
183    headers: &'a [Header],
184    readers: &mut Vec<Box<dyn Read + Send + 'a>>,
185) {
186    for header in headers {
187        readers.push(Box::new(header.reader()));
188    }
189}