///|
/// The paged results control OID (RFC 2696).
pub const PAGED_RESULTS_OID : String = "1.2.840.113556.1.4.319"
///|
/// RealSearchControlValue ::= SEQUENCE { size INTEGER, cookie OCTET STRING }
/// for a paged results *request* control value (RFC 2696).
pub fn paged_results_request_value(size : Int, cookie : Bytes) -> Bytes {
encode_sequence([encode_integer(size), encode_octet_string(cookie)])
}
///|
/// The paged results *response* control value: an estimated total size plus
/// the server-issued continuation cookie.
pub fn paged_results_response_value(total_size : Int, cookie : Bytes) -> Bytes {
encode_sequence([encode_integer(total_size), encode_octet_string(cookie)])
}
///|
pub struct PagedResultsResponse {
total_size : Int
cookie : Bytes
} derive(Eq, @debug.Debug)
///|
pub fn PagedResultsResponse::new(total_size : Int, cookie : Bytes) -> Self {
{ total_size, cookie }
}
///|
/// Build the paged results request control with the given page size and
/// cookie (empty cookie starts the enumeration).
pub fn paged_results_control(size : Int, cookie : Bytes) -> Control {
Control::new(
PAGED_RESULTS_OID,
false,
paged_results_request_value(size, cookie),
)
}
///|
fn parse_paged_value(value : Bytes) -> PagedResultsResponse? {
let decoded = match decode_ber(value, None) {
Ok(v) => v
Err(_) => return None
}
if !decoded.is_constructed() {
return None
}
let kids = decoded.children_or_empty()
if kids.length() != 2 {
return None
}
let total_size = match parse_integer(kids[0].content, 8) {
Ok(v) => v
Err(_) => return None
}
Some(PagedResultsResponse::new(total_size, kids[1].content))
}
///|
/// Extract the paged results response control from a response's controls,
/// returning `None` when absent or malformed.
pub fn parse_paged_results_response(
controls : Array[Control]?,
) -> PagedResultsResponse? {
match controls {
Some(list) =>
for ctrl in list {
if ctrl.control_type == PAGED_RESULTS_OID {
return parse_paged_value(ctrl.control_value)
}
}
None => ()
}
None
}