dvcompute 2.0.0

Discrete event simulation library (sequential simulation)
Documentation
// Copyright (c) 2020-2022  David Sorokin <davsor@mail.ru>, based in Yoshkar-Ola, Russia
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

use std::mem;
use std::slice;

use libc::*;

use serde::ser::Serialize;
use serde::ser::Serializer;

use serde::de::Deserialize;
use serde::de::Deserializer;

/// The byte vector representation that can be shared between libraries.
#[repr(C)]
#[derive(Copy, Clone)]
struct ByteVecObject {

    vec: *mut c_void,
    data: *const u8,
    len: usize,
}

/// A C-friendly representaton of the byte vector.
#[repr(C)]
pub struct ByteVecRepr {

    /// Delete the object.
    delete: unsafe extern "C" fn(obj: *mut ByteVecObject),

    /// The vector object.
    vec_object: ByteVecObject
}

impl Drop for ByteVecRepr {

    fn drop(&mut self) {
        unsafe {
            (self.delete)(&mut self.vec_object);
        }
    }
}

impl ByteVecRepr {

    /// Convert to a C-friendly representation.
    #[inline]
    pub fn into_repr(vec: Box<Vec<u8>>) -> ByteVecRepr {
        unsafe {
            let data = vec.as_ptr();
            let len  = vec.len();
            let vec_object = ByteVecObject {
                vec: mem::transmute(vec),
                data: data,
                len: len
            };
            ByteVecRepr {
                delete: delete_byte_vec_repr,
                vec_object: vec_object
            }
        }
    }

    /// Get the corresponding byte slice.
    #[inline]
    pub fn slice(&self) -> &[u8] {
        unsafe {
            slice::from_raw_parts(self.vec_object.data, self.vec_object.len)
        }
    }
}

/// Delete the byte vector representation.
unsafe extern "C" fn delete_byte_vec_repr(vec_object: *mut ByteVecObject) {
    let _: Box<Vec<u8>> = mem::transmute((*vec_object).vec);
}

unsafe impl Send for ByteVecRepr {}
unsafe impl Sync for ByteVecRepr {}

impl Serialize for ByteVecRepr {

    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where
        S: Serializer
    {
        let x: Box<Vec<u8>> = unsafe {
            mem::transmute(self.vec_object.vec)
        };
        let y = (*x).serialize(serializer);
        mem::forget(x);
        y
    }
}

impl<'de> Deserialize<'de> for ByteVecRepr {

    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where
        D: Deserializer<'de>
    {
        match Deserialize::deserialize(deserializer) {
            Result::Ok(x) => {
                let x = Box::new(x);
                let x = ByteVecRepr::into_repr(x);
                Result::Ok(x)
            },
            Result::Err(e) => {
                Result::Err(e)
            }
        }
    }
}