rustlol 0.1.1

A wad files lib
Documentation
use std::{fs::File, sync::{atomic::{AtomicPtr, AtomicUsize, Ordering}, Arc, Mutex, OnceLock}};
use crate::lol::io::sys_type::Error;
use memmap2::Mmap;
//use winapi::um::{fileapi::{CreateFileW, GetFileSizeEx, SetFileInformationByHandle, FILE_END_OF_FILE_INFO, OPEN_ALWAYS, OPEN_EXISTING}, handleapi::CloseHandle, memoryapi::{CreateFileMappingW, MapViewOfFile, UnmapViewOfFile, FILE_MAP_READ, FILE_MAP_WRITE}, winnt::{FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, GENERIC_READ, GENERIC_WRITE, HANDLE, LARGE_INTEGER, PAGE_READONLY, PAGE_READWRITE} };
use super::sys_type::{Result, Lolfileresult};


/// 内部句柄:Arc<Mutex<Option<Mmap>>> 实现了 Sync
type Handle = Arc<Mutex<Option<Vec<Mmap>>>>;

/// 全局句柄
static HANDLE: OnceLock<Handle> = OnceLock::new();

/// 全局可见的指针与长度(原子指针也行,这里用普通指针即可)
static PTR: AtomicPtr<u8> = AtomicPtr::new(std::ptr::null_mut());
static LEN: AtomicUsize = AtomicUsize::new(0);

fn get_handle() -> &'static Handle {
    HANDLE.get_or_init(|| {
        Arc::new(Mutex::new(Some(Vec::<Mmap>::new())))
    })
}

fn push_mmap(mmap: Mmap) -> std::io::Result<()> {

    let handle = get_handle();
    let mut map = handle.lock().unwrap();
    map.as_mut().unwrap().push(mmap);
    Ok(())
}

pub struct LOLfile<T>(pub T);


impl Lolfileresult<LOLfile<Handle>, Error> for LOLfile<Handle> {
    type Output = Result<LOLfile<Handle>, Error>;
    fn file_open(path: &std::path::Path, write: bool) -> Result<LOLfile<Handle>, Error> {

        if write {
            if path.extension().and_then(|s| s.to_str()) == Some("client") {
                let newpath = path.with_extension("");
                if newpath .is_dir() {
                    let _= path.to_path_buf();
                } else {
                    std::fs::create_dir(newpath).unwrap();
                }
                
                    
            } else {
                let _ = path.to_path_buf();
            }
            
        }


        let fileopne = File::open(path).unwrap();
        let mmap = unsafe { Mmap::map(&fileopne) }.unwrap();
        let ptr = mmap.as_ptr() as *mut u8;
        let len = mmap.len();

        // 先放句柄,再放原子变量
        push_mmap(mmap).unwrap();// 覆盖旧值
        PTR.store(ptr as *mut u8, Ordering::Release);
        LEN.store(len, Ordering::Release);

            // let mut options = OpenOptions::new();
            // options.read(true);
            // if write {
            //     options.write(true).create(true);
            // }

            // let file = options.open(path);

            // if file.is_err() {
            //     return Result::Err(Error::OpenError);
            // }
        if HANDLE.get().is_none() {
            return Result::Err(Error::OpenError);
        }

        Self::Output::Ok(LOLfile(HANDLE.get().unwrap().clone()))
        
    }

    fn file_size(&self) -> Result<usize, Error> {
        let len = LEN.load(Ordering::Acquire);
        Result::Ok(len)
        
    }


    fn file_resize(&mut self, count: usize) -> Result<usize, Error> {
        

        LEN.store(count, Ordering::Release);
        // }
        Result::Ok(count)    
    }
        


    

    fn file_mmap(&mut self, count: usize, _write: bool) -> Result<*mut u8, Error> {

        if count == 0 {
            return Result::Err(Error::MmapError);
        }

        let data = PTR.load(Ordering::Acquire);


        Result::Ok(data as _)
    }

    fn file_munmap( _count: usize) -> Result<(), Error> {
        PTR.store(std::ptr::null_mut(), Ordering::Release);
        LEN.store(0, Ordering::Release);
        // 只要 Arc 计数归零,Mmap 自动 drop,操作系统立刻 unmap
        let handle = get_handle();
        let mut map =handle.lock().unwrap();
  
        let maps = map.as_mut().unwrap();

        for map in maps {
            drop(map.to_owned());
        }
        Result::Ok(())
    }


}