use std::io::{self, Error};
use std::path::Path;
use std::ptr::null_mut;
use crate::lol::io::sys::LOLfile;
use crate::lol::io::sys_type::Lolfileresult;
use crate::{lol::io::buffer::Buffer, lol_trace_func, lol_throw_if};
#[derive(Debug, Clone)]
pub struct Bytes(pub Buffer);
#[derive(Debug,Clone)]
pub struct Impl {
pub ref_count: usize,
pub vec: Vec<u8>,
pub mmp: MMap,
}
pub type PImpl = *mut Impl;
impl Impl {
fn new() -> Self {
let vec = Vec::<u8>::new();
let mmp = MMap::new();
Self { ref_count: 0, vec, mmp,}
}
}
#[derive(Debug,Clone)]
pub struct MMap{
pub file: *mut u8,
pub data: *mut u8,
pub size: usize
}
impl MMap {
fn new() -> Self {
Self {
file: null_mut(),
data: null_mut(),
size: 0
}
}
}
impl Bytes {
pub fn bytes() ->Self {
Self(Buffer::default())
}
pub fn from_file(path: &Path) ->Bytes {
let trace = lol_trace_func!(from_file,lol_trace_var!(path));
let mut result = Bytes::bytes();
let mut impls = Impl::new();
let mut file = LOLfile::file_open(path, false).unwrap();
let fileopne =file.0.lock().unwrap().as_mut().unwrap().as_ptr();
lol_throw_if!(fileopne.is_null(), trace);
impls.mmp.file = fileopne as _;
let file_size = LOLfile::file_size(&file).unwrap();
lol_throw_if!(file_size.eq(&0), trace);
impls.mmp.size = file_size as usize;
let mmap_data = LOLfile::file_mmap(&mut file, file_size as usize, false);
lol_throw_if!(mmap_data.clone().unwrap().is_null(), trace);
impls.mmp.data = mmap_data.clone().unwrap();
result.0.data_ = mmap_data.unwrap() as *mut u8;
result.0.size_ = file_size as usize;
result.0.impl_ = impls;
return result;
}
pub fn copy(&self, pos: usize, count: usize ) -> Bytes{
let size_ = self.0.size_;
let trace = lol_trace_func!(cpoy, lol_trace_var!("{:#x}", size_), lol_trace_var!("{:#x}", pos), lol_trace_var!("{:#x}", count));
lol_throw_if!(pos + count < pos, trace);
lol_throw_if!(size_ < pos, trace);
lol_throw_if!(size_ - pos < count, trace);
let result = Bytes::bytes();
let bytes= self.impl_copy(pos, count, result);
lol_throw_if!(bytes.is_err(), trace);
return bytes.unwrap();
}
fn impl_copy(&self, pos: usize, count: usize, mut out: Bytes) -> Result<Bytes, Error>{
if count == 0 { return Err(io::Error::last_os_error());};
out.0.data_ = unsafe { self.0.data_.add(pos) };
out.0.size_ = count;
out.0.impl_ = self.0.impl_.clone();
out.0.impl_.ref_count += 1;
return Ok(out);
}
}