#pragma once #include #include #include #include #include struct lua_State; namespace mosis { struct FileStat { size_t size; int64_t modified; // Unix timestamp bool is_dir; }; struct VirtualFSLimits { size_t max_quota_bytes = 50 * 1024 * 1024; // 50 MB per app size_t max_file_size = 10 * 1024 * 1024; // 10 MB per file int max_path_depth = 10; // Max directory depth size_t max_path_length = 256; // Max path string length }; class VirtualFS { public: VirtualFS(const std::string& app_id, const std::string& app_root, const VirtualFSLimits& limits = VirtualFSLimits{}); ~VirtualFS(); // Path operations bool ValidatePath(const std::string& virtual_path, std::string& error); std::string ResolvePath(const std::string& virtual_path); // File operations std::optional Read(const std::string& path, std::string& error); bool Write(const std::string& path, const std::string& data, std::string& error); bool Append(const std::string& path, const std::string& data, std::string& error); bool Delete(const std::string& path, std::string& error); bool Exists(const std::string& path); std::optional> List(const std::string& path, std::string& error); bool MakeDir(const std::string& path, std::string& error); std::optional Stat(const std::string& path, std::string& error); // Quota management size_t GetUsedBytes() const { return m_used_bytes; } size_t GetQuotaBytes() const { return m_limits.max_quota_bytes; } void RecalculateUsage(); // Cleanup void ClearTemp(); void ClearAll(); // For testing // Permission check callback (set by sandbox) std::function CheckPermission; private: std::string m_app_id; std::string m_app_root; VirtualFSLimits m_limits; size_t m_used_bytes = 0; bool EnsureParentDir(const std::string& path); void UpdateUsage(int64_t delta); bool CheckQuota(size_t additional_bytes, std::string& error); int GetPathDepth(const std::string& path); bool IsValidPathChar(char c); void DeleteDirectoryRecursive(const std::string& path); size_t CalculateDirectorySize(const std::string& path); }; // Register fs.* APIs as globals void RegisterVirtualFS(lua_State* L, VirtualFS* vfs); } // namespace mosis