(&'a self, bytes: B)
| 3124 | /// the caller's allocation is not retained. |
| 3125 | #[allow(clippy::transmute_ptr_to_ptr)] |
| 3126 | pub fn push_bytes<'a, B: Deref<Target = [u8]>>(&'a self, bytes: B) -> &'a [u8] { |
| 3127 | let bytes: &[u8] = &bytes; |
| 3128 | let need = bytes.len(); |
| 3129 | if need == 0 { |
| 3130 | return &[]; |
| 3131 | } |
| 3132 | let mut inner = self.inner.borrow_mut(); |
| 3133 | |
| 3134 | // Find or create a region with spare capacity for `need` bytes, never growing a region |
| 3135 | // that already holds data (see the type-level comment for why this preserves references). |
| 3136 | let has_room = inner |
| 3137 | .last() |
| 3138 | .map_or(false, |region| region.capacity() - region.len() >= need); |
| 3139 | if !has_room { |
| 3140 | let last_cap = inner.last().map_or(0, |region| region.capacity()); |
| 3141 | let new_cap = std::cmp::max(need, last_cap.saturating_mul(2)); |
| 3142 | inner.push(Vec::with_capacity(new_cap)); |
| 3143 | } |
| 3144 | |
| 3145 | let region = inner.last_mut().expect("region present"); |
| 3146 | let start = region.len(); |
| 3147 | region.extend_from_slice(bytes); |
| 3148 | let copied = ®ion[start..]; |
| 3149 | unsafe { |
| 3150 | // This is safe because: |
| 3151 | // * `copied` references bytes inside `region`'s heap buffer, which we just sized to |
| 3152 | // fit without reallocating; that buffer is never resized again while it holds data |
| 3153 | // (we allocate a new region instead), so the reference stays valid. |
| 3154 | // * The buffer lives as long as the arena: regions are only dropped by `clear`/`drop`, |
| 3155 | // both of which take `&mut`/ownership, so no `&'a self`-tied reference can outlive |
| 3156 | // them. |
| 3157 | // * Pushing further regions may reallocate `self.inner`, but that moves only the |
| 3158 | // `Vec<u8>` headers, not the heap buffers they own. |
| 3159 | transmute::<&[u8], &'a [u8]>(copied) |
| 3160 | } |
| 3161 | } |
| 3162 | |
| 3163 | /// Copies `string` into the arena and returns a reference valid for its lifetime. |
| 3164 | pub fn push_string<'a>(&'a self, string: String) -> &'a str { |
no test coverage detected