use super::*;
#[derive(Clone, Debug)]
pub struct NameSection {
bytes: Vec<u8>,
}
enum Subsection {
Module = 0,
Function = 1,
Local = 2,
Label = 3,
Type = 4,
Table = 5,
Memory = 6,
Global = 7,
Element = 8,
Data = 9,
}
impl NameSection {
pub fn new() -> NameSection {
NameSection { bytes: vec![] }
}
pub fn module(&mut self, name: &str) {
let len = encoders::u32(u32::try_from(name.len()).unwrap());
self.subsection_header(Subsection::Module, len.len() + name.len());
self.bytes.extend(len);
self.bytes.extend(name.as_bytes());
}
pub fn functions(&mut self, names: &NameMap) {
self.subsection_header(Subsection::Function, names.size());
names.encode(&mut self.bytes);
}
pub fn locals(&mut self, names: &IndirectNameMap) {
self.subsection_header(Subsection::Local, names.size());
names.encode(&mut self.bytes);
}
pub fn labels(&mut self, names: &IndirectNameMap) {
self.subsection_header(Subsection::Label, names.size());
names.encode(&mut self.bytes);
}
pub fn types(&mut self, names: &NameMap) {
self.subsection_header(Subsection::Type, names.size());
names.encode(&mut self.bytes);
}
pub fn tables(&mut self, names: &NameMap) {
self.subsection_header(Subsection::Table, names.size());
names.encode(&mut self.bytes);
}
pub fn memories(&mut self, names: &NameMap) {
self.subsection_header(Subsection::Memory, names.size());
names.encode(&mut self.bytes);
}
pub fn globals(&mut self, names: &NameMap) {
self.subsection_header(Subsection::Global, names.size());
names.encode(&mut self.bytes);
}
pub fn elements(&mut self, names: &NameMap) {
self.subsection_header(Subsection::Element, names.size());
names.encode(&mut self.bytes);
}
pub fn data(&mut self, names: &NameMap) {
self.subsection_header(Subsection::Data, names.size());
names.encode(&mut self.bytes);
}
fn subsection_header(&mut self, id: Subsection, len: usize) {
self.bytes.push(id as u8);
self.bytes
.extend(encoders::u32(u32::try_from(len).unwrap()));
}
}
impl Section for NameSection {
fn id(&self) -> u8 {
SectionId::Custom.into()
}
fn encode<S>(&self, sink: &mut S)
where
S: Extend<u8>,
{
let name_len = encoders::u32(4);
let n = name_len.len();
sink.extend(
encoders::u32(u32::try_from(n + 4 + self.bytes.len()).unwrap())
.chain(name_len)
.chain(b"name".iter().copied())
.chain(self.bytes.iter().copied()),
);
}
}
#[derive(Clone, Debug)]
pub struct NameMap {
bytes: Vec<u8>,
count: u32,
}
impl NameMap {
pub fn new() -> NameMap {
NameMap {
bytes: vec![],
count: 0,
}
}
pub fn append(&mut self, idx: u32, name: &str) {
self.bytes.extend(encoders::u32(idx));
self.bytes
.extend(encoders::u32(u32::try_from(name.len()).unwrap()));
self.bytes.extend(name.as_bytes());
self.count += 1;
}
fn size(&self) -> usize {
encoders::u32(self.count).len() + self.bytes.len()
}
fn encode(&self, dst: &mut Vec<u8>) {
dst.extend(encoders::u32(self.count));
dst.extend(&self.bytes);
}
}
#[derive(Clone, Debug)]
pub struct IndirectNameMap {
bytes: Vec<u8>,
count: u32,
}
impl IndirectNameMap {
pub fn new() -> IndirectNameMap {
IndirectNameMap {
bytes: vec![],
count: 0,
}
}
pub fn append(&mut self, idx: u32, names: &NameMap) {
self.bytes.extend(encoders::u32(idx));
names.encode(&mut self.bytes);
self.count += 1;
}
fn size(&self) -> usize {
encoders::u32(self.count).len() + self.bytes.len()
}
fn encode(&self, dst: &mut Vec<u8>) {
dst.extend(encoders::u32(self.count));
dst.extend(&self.bytes);
}
}