#[cfg(not(feature = "std"))]
use alloc::vec::Vec;
use core::ops::Range;
use super::*;
pub fn decode_event_notification_tolerant(data: &[u8]) -> Result<EventNotificationRequest, Error> {
let strict_error = match decode_event_notification(data) {
Ok(notification) => return Ok(notification),
Err(error) => error,
};
let Some(text) = unreadable_message_text(data) else {
return Err(strict_error);
};
let mut without_text = Vec::with_capacity(data.len() - text.len());
without_text.extend_from_slice(&data[..text.start]);
without_text.extend_from_slice(&data[text.end..]);
decode_event_notification(&without_text)
}
fn unreadable_message_text(data: &[u8]) -> Option<Range<usize>> {
let mut offset = 0;
for number in 0..7 {
let (tag, content) = tags::decode_tag(data, offset).ok()?;
if number == 3 {
if !tag.is_opening_tag(number) {
return None;
}
offset = tags::extract_context_value(data, content, number).ok()?.1;
} else {
if !tag.is_context(number) {
return None;
}
offset = content.checked_add(tag.length as usize)?;
data.get(content..offset)?;
}
}
let (tag, content) = tags::decode_tag(data, offset).ok()?;
if !tag.is_context(7) || tag.length == 0 {
return None;
}
let end = content.checked_add(tag.length as usize)?;
let text = data.get(content..end)?;
if end < data.len() && !tags::decode_tag(data, end).ok()?.0.is_context(8) {
return None;
}
primitives::decode_character_string(text)
.is_err()
.then_some(offset..end)
}