Skip to content

Commit abbfb54

Browse files
committed
Avoid allocation in StructRole2::to_name_bytes
1 parent d45610d commit abbfb54

1 file changed

Lines changed: 59 additions & 44 deletions

File tree

src/structure.rs

Lines changed: 59 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
use std::{borrow::Cow, num::NonZeroU16};
1+
use std::io::{Cursor, Write};
2+
use std::num::NonZeroU16;
23

34
use super::*;
45
use crate::color::SeparationInfo;
@@ -444,7 +445,7 @@ impl StructElement<'_> {
444445
/// dictionary. You can create this dictionary by using [`Chunk::namespace`]
445446
/// and then calling [`Namespace::pdf_2_ns`] on the returned writer.
446447
pub fn kind_2(&mut self, role: StructRole2, pdf_2_ns: Ref) -> &mut Self {
447-
self.dict.pair(Name(b"S"), Name(&role.to_name_bytes()));
448+
self.dict.pair(Name(b"S"), Name(role.to_name_bytes(&mut [0; 6])));
448449
self.namespace(pdf_2_ns)
449450
}
450451

@@ -1163,51 +1164,53 @@ pub enum StructRole2 {
11631164
}
11641165

11651166
impl StructRole2 {
1166-
pub(crate) fn to_name_bytes(self) -> Cow<'static, [u8]> {
1167+
pub(crate) fn to_name_bytes(self, buf: &mut [u8; 6]) -> &[u8] {
11671168
match self {
1168-
Self::Document => Cow::Borrowed(b"Document"),
1169-
Self::DocumentFragment => Cow::Borrowed(b"DocumentFragment"),
1170-
Self::Part => Cow::Borrowed(b"Part"),
1171-
Self::Sect => Cow::Borrowed(b"Sect"),
1172-
Self::Div => Cow::Borrowed(b"Div"),
1173-
Self::Aside => Cow::Borrowed(b"Aside"),
1174-
Self::NonStruct => Cow::Borrowed(b"NonStruct"),
1175-
Self::P => Cow::Borrowed(b"P"),
1169+
Self::Document => b"Document",
1170+
Self::DocumentFragment => b"DocumentFragment",
1171+
Self::Part => b"Part",
1172+
Self::Sect => b"Sect",
1173+
Self::Div => b"Div",
1174+
Self::Aside => b"Aside",
1175+
Self::NonStruct => b"NonStruct",
1176+
Self::P => b"P",
11761177
Self::Heading(level) => {
1177-
let name = format!("H{}", level.get());
1178-
Cow::Owned(name.into_bytes())
1178+
let mut cursor = Cursor::new(buf.as_mut_slice());
1179+
write!(&mut cursor, "H{}", level.get()).unwrap();
1180+
let pos = cursor.position() as usize;
1181+
&buf[..pos]
11791182
}
1180-
Self::StructuredHeading => Cow::Borrowed(b"H"),
1181-
Self::Title => Cow::Borrowed(b"Title"),
1182-
Self::FENote => Cow::Borrowed(b"FENote"),
1183-
Self::Sub => Cow::Borrowed(b"Sub"),
1184-
Self::Lbl => Cow::Borrowed(b"Lbl"),
1185-
Self::Span => Cow::Borrowed(b"Span"),
1186-
Self::Em => Cow::Borrowed(b"Em"),
1187-
Self::Strong => Cow::Borrowed(b"Strong"),
1188-
Self::Link => Cow::Borrowed(b"Link"),
1189-
Self::Annot => Cow::Borrowed(b"Annot"),
1190-
Self::Form => Cow::Borrowed(b"Form"),
1191-
Self::Ruby => Cow::Borrowed(b"Ruby"),
1192-
Self::RB => Cow::Borrowed(b"RB"),
1193-
Self::RT => Cow::Borrowed(b"RT"),
1194-
Self::Warichu => Cow::Borrowed(b"Warichu"),
1195-
Self::WT => Cow::Borrowed(b"WT"),
1196-
Self::WP => Cow::Borrowed(b"WP"),
1197-
Self::L => Cow::Borrowed(b"L"),
1198-
Self::LI => Cow::Borrowed(b"LI"),
1199-
Self::LBody => Cow::Borrowed(b"LBody"),
1200-
Self::Table => Cow::Borrowed(b"Table"),
1201-
Self::TR => Cow::Borrowed(b"TR"),
1202-
Self::TH => Cow::Borrowed(b"TH"),
1203-
Self::TD => Cow::Borrowed(b"TD"),
1204-
Self::THead => Cow::Borrowed(b"THead"),
1205-
Self::TBody => Cow::Borrowed(b"TBody"),
1206-
Self::TFoot => Cow::Borrowed(b"TFoot"),
1207-
Self::Caption => Cow::Borrowed(b"Caption"),
1208-
Self::Figure => Cow::Borrowed(b"Figure"),
1209-
Self::Formula => Cow::Borrowed(b"Formula"),
1210-
Self::Artifact => Cow::Borrowed(b"Artifact"),
1183+
Self::StructuredHeading => b"H",
1184+
Self::Title => b"Title",
1185+
Self::FENote => b"FENote",
1186+
Self::Sub => b"Sub",
1187+
Self::Lbl => b"Lbl",
1188+
Self::Span => b"Span",
1189+
Self::Em => b"Em",
1190+
Self::Strong => b"Strong",
1191+
Self::Link => b"Link",
1192+
Self::Annot => b"Annot",
1193+
Self::Form => b"Form",
1194+
Self::Ruby => b"Ruby",
1195+
Self::RB => b"RB",
1196+
Self::RT => b"RT",
1197+
Self::Warichu => b"Warichu",
1198+
Self::WT => b"WT",
1199+
Self::WP => b"WP",
1200+
Self::L => b"L",
1201+
Self::LI => b"LI",
1202+
Self::LBody => b"LBody",
1203+
Self::Table => b"Table",
1204+
Self::TR => b"TR",
1205+
Self::TH => b"TH",
1206+
Self::TD => b"TD",
1207+
Self::THead => b"THead",
1208+
Self::TBody => b"TBody",
1209+
Self::TFoot => b"TFoot",
1210+
Self::Caption => b"Caption",
1211+
Self::Figure => b"Figure",
1212+
Self::Formula => b"Formula",
1213+
Self::Artifact => b"Artifact",
12111214
}
12121215
}
12131216

@@ -2309,3 +2312,15 @@ impl<'a> Metadata<'a> {
23092312
}
23102313

23112314
deref!('a, Metadata<'a> => Stream<'a>, stream);
2315+
2316+
#[cfg(test)]
2317+
mod tests {
2318+
use super::*;
2319+
2320+
#[test]
2321+
fn test_max_heading_name() {
2322+
let mut buf = [0; 6];
2323+
let name = Name(StructRole2::Heading(NonZeroU16::MAX).to_name_bytes(&mut buf));
2324+
assert_eq!(Name(b"H65535"), name);
2325+
}
2326+
}

0 commit comments

Comments
 (0)