///|
/// A bounded ordered header collection. Names compare without ASCII case.
pub struct Headers {
priv entries : Array[(String, String)]
}
///|
pub fn Headers::new() -> Headers {
{ entries: [], }
}
///|
pub fn Headers::add(
self : Headers,
name : String,
value : String,
) -> Unit raise RtspError {
require(self.entries.length() < 128, "header count")
require(name.length() > 0 && name.length() <= 128, "header name length")
for c in name {
require(
(c >= 'a' && c <= 'z') ||
(c >= 'A' && c <= 'Z') ||
(c >= '0' && c <= '9') ||
c == '-' ||
c == '_',
"header name",
)
}
require(value.length() <= 8192 && clean(value), "header value")
self.entries.push((name, trim(value)))
}
///|
pub fn Headers::get(self : Headers, name : String) -> String? {
let key = lower(name)
for (k, v) in self.entries {
if lower(k) == key {
return Some(v)
}
}
None
}
///|
pub fn Headers::all(self : Headers, name : String) -> Array[String] {
let values = []
for (k, v) in self.entries {
if lower(k) == lower(name) {
values.push(v)
}
}
values
}
///|
pub fn Headers::set(
self : Headers,
name : String,
value : String,
) -> Unit raise RtspError {
let validated = Headers::new()
validated.add(name, value)
let mut i = self.entries.length() - 1
while i >= 0 {
if lower(self.entries[i].0) == lower(name) {
self.entries.remove(i) |> ignore
}
i -= 1
}
self.add(name, value)
}
///|
pub fn Headers::items(self : Headers) -> Array[(String, String)] {
self.entries.copy()
}
///|
pub fn Headers::copy(self : Headers) -> Headers {
{ entries: self.entries.copy(), }
}
///|
fn Headers::wire(self : Headers) -> String {
let out = StringBuilder()
for (k, v) in self.entries {
out.write_string(k + ": " + v + "\r\n")
}
out.to_string()
}
///|
fn Headers::unique(self : Headers, name : String) -> String? raise RtspError {
let values = self.all(name)
require(values.length() <= 1, "duplicate framing header")
if values.length() == 0 {
None
} else {
Some(values[0])
}
}