structured_asic/
session.rs1use crate::error::{Error, Limit};
4use core::cell::Cell;
5use structured_asn1::{
6 Encoding, Parser, Span,
7 memory::{Execution, Memory, Work},
8};
9
10#[derive(Debug, Clone, Copy)]
12pub struct Limits {
13 pub processing: structured_asn1::Limits,
15 pub max_entries: u64,
17 pub max_decoded: u64,
19}
20impl Default for Limits {
21 fn default() -> Self {
22 Self {
23 processing: structured_asn1::Limits::default(),
24 max_entries: 1_000_000,
25 max_decoded: 64 * 1024 * 1024,
26 }
27 }
28}
29
30pub struct Session {
33 parser: Parser,
34 limits: Limits,
35 entries: Cell<u64>,
36 decoded: Cell<u64>,
37}
38impl Session {
39 #[must_use]
41 pub fn new(limits: Limits, memory: Memory) -> Self {
42 Self {
43 parser: Parser::new(Encoding::Der, limits.processing, memory),
44 limits,
45 entries: Cell::new(0),
46 decoded: Cell::new(0),
47 }
48 }
49 #[must_use]
51 pub fn limits(&self) -> Limits {
52 self.limits
53 }
54 #[must_use]
56 pub fn execution(&self) -> Execution<'_> {
57 self.parser.execution_in(self.parser.memory())
58 }
59 #[must_use]
61 pub fn query<'q, W: Work>(&'q self, work: &'q W) -> Execution<'q> {
62 work.execution_for(&self.parser)
63 }
64 pub(crate) fn carried<'q, W: Work + 'q>(
65 &'q self,
66 bytes: &'q [u8],
67 work: &W,
68 ) -> structured_asn1::Result<structured_asn1::Reader<'q>> {
69 work.read_source(&self.parser, bytes, 0, Encoding::Ber, 0)
70 }
71 pub(crate) fn owns(&self, reader: &structured_asn1::Reader<'_>) -> bool {
72 core::ptr::eq(core::ptr::from_ref(&self.parser), reader.parser())
73 }
74 pub(crate) fn entries<E>(&self, count: u64, range: Span) -> Result<(), Error<E>> {
75 Self::admit(
76 &self.entries,
77 count,
78 self.limits.max_entries,
79 range,
80 Limit::Entries,
81 )
82 }
83 pub(crate) fn remaining(&self) -> u64 {
84 self.limits.max_decoded - self.decoded.get()
85 }
86 pub(crate) fn decode<E>(&self, count: u64, range: Span) -> Result<(), Error<E>> {
87 Self::admit(
88 &self.decoded,
89 count,
90 self.limits.max_decoded,
91 range,
92 Limit::Decoded,
93 )
94 }
95 fn admit<E>(
96 counter: &Cell<u64>,
97 count: u64,
98 maximum: u64,
99 range: Span,
100 kind: Limit,
101 ) -> Result<(), Error<E>> {
102 let used = counter.get();
103 debug_assert!(used <= maximum);
104 if count > maximum - used {
105 return Err(Error::Limit { range, kind });
106 }
107 counter.set(used + count);
108 Ok(())
109 }
110}