use crate::{CustomSection, Encode, Section, SectionId, encoding_size};
use alloc::borrow::Cow;
use alloc::vec;
use alloc::vec::Vec;
#[derive(Clone, Debug, Default)]
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,
Field = 10,
Tag = 11,
}
impl NameSection {
pub fn new() -> Self {
Self::default()
}
pub fn module(&mut self, name: &str) {
let len = encoding_size(u32::try_from(name.len()).unwrap());
self.subsection_header(Subsection::Module, len + name.len());
name.encode(&mut self.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);
}
pub fn tag(&mut self, names: &NameMap) {
self.subsection_header(Subsection::Tag, names.size());
names.encode(&mut self.bytes);
}
pub fn fields(&mut self, names: &IndirectNameMap) {
self.subsection_header(Subsection::Field, names.size());
names.encode(&mut self.bytes);
}
pub fn tags(&mut self, names: &NameMap) {
self.subsection_header(Subsection::Tag, names.size());
names.encode(&mut self.bytes);
}
pub fn raw(&mut self, id: u8, data: &[u8]) {
self.bytes.push(id);
data.encode(&mut self.bytes);
}
fn subsection_header(&mut self, id: Subsection, len: usize) {
self.bytes.push(id as u8);
len.encode(&mut self.bytes);
}
pub fn as_custom<'a>(&'a self) -> CustomSection<'a> {
CustomSection {
name: "name".into(),
data: Cow::Borrowed(&self.bytes),
}
}
}
impl Encode for NameSection {
fn encode(&self, sink: &mut Vec<u8>) {
self.as_custom().encode(sink);
}
}
impl Section for NameSection {
fn id(&self) -> u8 {
SectionId::Custom.into()
}
}
#[derive(Clone, Debug, Default)]
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) {
idx.encode(&mut self.bytes);
name.encode(&mut self.bytes);
self.count += 1;
}
pub(crate) fn size(&self) -> usize {
encoding_size(self.count) + self.bytes.len()
}
pub fn is_empty(&self) -> bool {
self.count == 0
}
}
impl Encode for NameMap {
fn encode(&self, sink: &mut Vec<u8>) {
self.count.encode(sink);
sink.extend(&self.bytes);
}
}
#[derive(Clone, Debug, Default)]
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) {
idx.encode(&mut self.bytes);
names.encode(&mut self.bytes);
self.count += 1;
}
fn size(&self) -> usize {
encoding_size(self.count) + self.bytes.len()
}
}
impl Encode for IndirectNameMap {
fn encode(&self, sink: &mut Vec<u8>) {
self.count.encode(sink);
sink.extend(&self.bytes);
}
}