monistode-emulator 0.1.7

An emulator for the monistode set of ISA's
Documentation
use num_traits::Zero;
use std::ops::{AddAssign, ShlAssign};

use crate::tightly_packed_array::TightlyPackedArray;

use super::segment_meta::ExecutableSegmentMetadata;

#[derive(Debug)]
pub struct ExecutableSegment {
    metadata: ExecutableSegmentMetadata,
    bytes: Vec<u8>,
}

impl ExecutableSegment {
    pub fn metadata(&self) -> &ExecutableSegmentMetadata {
        &self.metadata
    }

    pub fn bytes(&self) -> &[u8] {
        &self.bytes
    }

    pub fn tightly_packed_array<T>(&self) -> TightlyPackedArray<T>
    where
        T: Zero + From<u8> + AddAssign + ShlAssign,
    {
        TightlyPackedArray::new(self.bytes.clone(), self.metadata.byte_size as usize)
    }
}

#[derive(Debug)]
pub struct ExecutableSegments {
    pub segments: Vec<ExecutableSegment>,
}

impl ExecutableSegments {
    pub fn new(bytes: &[u8]) -> ExecutableSegments {
        let mut segments = Vec::new();
        let mut offset = 0;
        while offset < bytes.len() {
            if offset + 16 > bytes.len() {
                break;
            }
            let metadata = ExecutableSegmentMetadata::new(&bytes[offset..]);
            offset += 17;
            let mut segment_bytes = Vec::new();
            for i in 0..metadata.disk_size() {
                if offset + i as usize >= bytes.len() {
                    break;
                }
                segment_bytes.push(bytes[offset + i as usize]);
            }
            offset += metadata.disk_size() as usize;
            segments.push(ExecutableSegment {
                metadata,
                bytes: segment_bytes,
            });
        }
        ExecutableSegments { segments }
    }
}