casc_storage/utils/
shared_memory.rs

1//! Shared memory support for inter-process communication
2
3use crate::error::Result;
4use crate::types::SharedMemoryFlags;
5use std::path::Path;
6use tracing::debug;
7
8/// Shared memory structure for CASC storage
9#[derive(Debug)]
10pub struct SharedMemory {
11    /// Version of the shared memory format
12    pub version: u32,
13    /// Build number of the game
14    pub build_number: u32,
15    /// Game region (e.g., "US", "EU")
16    pub region: [u8; 4],
17    /// Status flags
18    pub flags: SharedMemoryFlags,
19    /// Number of archives
20    pub archive_count: u32,
21    /// Number of indices
22    pub index_count: u32,
23    /// Total storage size in bytes
24    pub total_size: u64,
25    /// Available space in bytes
26    pub free_space: u64,
27    /// Path to data directory
28    pub data_path: String,
29}
30
31impl SharedMemory {
32    /// Create a new shared memory structure
33    pub fn new(data_path: String) -> Self {
34        Self {
35            version: 1,
36            build_number: 0,
37            region: [b'U', b'S', 0, 0],
38            flags: SharedMemoryFlags {
39                is_ready: false,
40                is_updating: false,
41                needs_repair: false,
42            },
43            archive_count: 0,
44            index_count: 0,
45            total_size: 0,
46            free_space: 0,
47            data_path,
48        }
49    }
50
51    /// Write shared memory to a file
52    pub fn write_to_file(&self, path: &Path) -> Result<()> {
53        debug!("Writing shared memory to {:?}", path);
54
55        // For now, we just write a simple JSON representation
56        // In production, this would be a binary format or actual shared memory
57        let json = serde_json::json!({
58            "version": self.version,
59            "build_number": self.build_number,
60            "region": String::from_utf8_lossy(&self.region),
61            "flags": {
62                "is_ready": self.flags.is_ready,
63                "is_updating": self.flags.is_updating,
64                "needs_repair": self.flags.needs_repair,
65            },
66            "archive_count": self.archive_count,
67            "index_count": self.index_count,
68            "total_size": self.total_size,
69            "free_space": self.free_space,
70            "data_path": self.data_path,
71        });
72
73        std::fs::write(path, json.to_string())?;
74        Ok(())
75    }
76
77    /// Read shared memory from a file
78    pub fn read_from_file(path: &Path) -> Result<Self> {
79        debug!("Reading shared memory from {:?}", path);
80
81        let content = std::fs::read_to_string(path)?;
82        let json: serde_json::Value = serde_json::from_str(&content)
83            .map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))?;
84
85        let region_str = json["region"].as_str().unwrap_or("US");
86        let mut region = [0u8; 4];
87        region[..region_str.len().min(4)].copy_from_slice(region_str.as_bytes());
88
89        Ok(Self {
90            version: json["version"].as_u64().unwrap_or(1) as u32,
91            build_number: json["build_number"].as_u64().unwrap_or(0) as u32,
92            region,
93            flags: SharedMemoryFlags {
94                is_ready: json["flags"]["is_ready"].as_bool().unwrap_or(false),
95                is_updating: json["flags"]["is_updating"].as_bool().unwrap_or(false),
96                needs_repair: json["flags"]["needs_repair"].as_bool().unwrap_or(false),
97            },
98            archive_count: json["archive_count"].as_u64().unwrap_or(0) as u32,
99            index_count: json["index_count"].as_u64().unwrap_or(0) as u32,
100            total_size: json["total_size"].as_u64().unwrap_or(0),
101            free_space: json["free_space"].as_u64().unwrap_or(0),
102            data_path: json["data_path"].as_str().unwrap_or("").to_string(),
103        })
104    }
105
106    /// Update statistics
107    pub fn update_stats(&mut self, archive_count: u32, index_count: u32, total_size: u64) {
108        self.archive_count = archive_count;
109        self.index_count = index_count;
110        self.total_size = total_size;
111    }
112
113    /// Mark as ready
114    pub fn set_ready(&mut self, ready: bool) {
115        self.flags.is_ready = ready;
116    }
117
118    /// Mark as updating
119    pub fn set_updating(&mut self, updating: bool) {
120        self.flags.is_updating = updating;
121    }
122
123    /// Mark as needing repair
124    pub fn set_needs_repair(&mut self, needs_repair: bool) {
125        self.flags.needs_repair = needs_repair;
126    }
127}
128
129// Add serde_json to dependencies for this module
130use serde_json;