rust_rcs_core/internet/parameter.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::io::Read;
16
17use crate::internet::syntax;
18
19pub struct Parameter<'a> {
20 pub name: &'a [u8],
21 pub value: Option<&'a [u8]>,
22}
23
24impl<'a> Parameter<'a> {
25 pub fn reader(&self) -> ParameterReader {
26 ParameterReader {
27 n: self.name,
28 v: self.value,
29 d: b';',
30 pos: 0,
31 }
32 }
33}
34
35impl<'a> From<&'a [u8]> for Parameter<'a> {
36 /// Build a Parameter from string bytes
37 ///
38 /// # Examples
39 ///
40 /// ```
41 /// let a = "key=value".as_bytes();
42 /// let p = rust_rcs_core::internet::parameter::Parameter::from(a);
43 /// assert_eq!(p.name, "key".as_bytes());
44 /// if let Some(value) = p.value {
45 /// assert_eq!(value, "value".as_bytes());
46 /// } else {
47 /// panic!("decode not successful\n");
48 /// }
49 /// ```
50 fn from(s: &'a [u8]) -> Parameter {
51 let mut iter = s.iter();
52
53 if let Some(position) = iter.position(|c| *c == b'=') {
54 return Parameter {
55 name: &s[..position],
56 value: Some(&s[position + 1..]),
57 };
58 }
59
60 return Parameter {
61 name: s,
62 value: None,
63 };
64 }
65}
66
67pub struct ParameterParser<'a> {
68 s: &'a [u8],
69 d: u8,
70 p: usize,
71 ows: bool,
72}
73
74impl<'a> ParameterParser<'a> {
75 pub fn new(s: &'a [u8], d: u8, ows: bool) -> ParameterParser<'a> {
76 ParameterParser { s, d, p: 0, ows }
77 }
78}
79
80impl<'a> Iterator for ParameterParser<'a> {
81 type Item = Parameter<'a>;
82 fn next(&mut self) -> Option<Parameter<'a>> {
83 if self.p < self.s.len() {
84 let chunk;
85 let advance;
86 if let Some(idx) = syntax::index_with_token_escaping(&self.s[self.p..], self.d) {
87 chunk = &self.s[self.p..self.p + idx];
88 advance = idx;
89 } else {
90 chunk = &self.s[self.p..];
91 advance = self.s.len() - self.p;
92 }
93
94 let chunk = syntax::trim(chunk);
95
96 if self.p + advance + 1 < self.s.len() {
97 if self.ows {
98 self.p = self.p
99 + advance
100 + syntax::index_skipping_ows_and_obs_fold(&self.s[self.p + advance + 1..])
101 + 1;
102 } else {
103 self.p = self.p + advance + 1;
104 }
105 } else {
106 self.p = self.p + advance + 1;
107 }
108
109 return Some(Parameter::from(chunk));
110 }
111
112 None
113 }
114}
115
116// #[deprecated]
117// pub fn parse_parameters(s: &[u8], delimeter: u8) -> Vec<Parameter> {
118// let mut parameters = Vec::new();
119
120// let mut iter = s.split(|c| *c == delimeter);
121
122// loop {
123// match iter.next() {
124// Some(s) => {
125// let p = Parameter::from(s);
126// parameters.push(p);
127// }
128// None => break,
129// }
130// }
131
132// parameters
133// }
134
135// #[deprecated]
136// pub fn search<'a>(parameters: &'a [Parameter], name: &[u8]) -> Option<&'a Parameter<'a>> {
137// if let Some(position) = parameters.iter().position(|p| p.name == name) {
138// return Some(¶meters[position]);
139// }
140// None
141// }
142
143pub struct ParameterReader<'a> {
144 n: &'a [u8],
145 v: Option<&'a [u8]>,
146 d: u8,
147 pos: usize,
148}
149
150impl<'a> Read for ParameterReader<'a> {
151 fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
152 let mut i = 0;
153 let n_length = self.n.len();
154 while self.pos + i < 1 && i < buf.len() {
155 buf[i] = self.d;
156 i += 1;
157 }
158 while self.pos + i >= 1 && self.pos + i < 1 + n_length && i < buf.len() {
159 buf[i] = self.n[self.pos + i - 1];
160 i += 1;
161 }
162 if let Some(v) = self.v {
163 let v_length = v.len();
164 while self.pos + i >= 1 + n_length && self.pos + i < 1 + n_length + 1 && i < buf.len() {
165 buf[i] = b'=';
166 i += 1;
167 }
168 while self.pos + i >= 1 + n_length + 1
169 && self.pos + i < 1 + n_length + 1 + v_length
170 && i < buf.len()
171 {
172 buf[i] = v[self.pos + i - 1 - n_length - 1];
173 i += 1;
174 }
175 }
176 self.pos += i;
177 Ok(i)
178 }
179}