doc: add documentation
- add documentation for CKDefines, CKGlobals and VxMemoryMappedFile. - fix build issue in VxMemoryMappedFile. - add file size limitation in VxMemoryMappedFile. File whose size exceed the maximum value can not be opened.
This commit is contained in:
		| @ -5,9 +5,9 @@ | |||||||
|  |  | ||||||
| namespace LibCmo::CK2 { | namespace LibCmo::CK2 { | ||||||
|  |  | ||||||
| #pragma region Preregistred Managers | #pragma region Preregistred Manager GUIDs | ||||||
|  |  | ||||||
| 	// Virtools Managers GUID second data is 0 | 	// Virtools Managers GUID second DWORD must be 0 | ||||||
|  |  | ||||||
| 	constexpr const CKDWORD OBJECT_MANAGER_GUID1 = 0x7cbb3b91; | 	constexpr const CKDWORD OBJECT_MANAGER_GUID1 = 0x7cbb3b91; | ||||||
| 	constexpr const CKDWORD ATTRIBUTE_MANAGER_GUID1 = 0x3d242466; | 	constexpr const CKDWORD ATTRIBUTE_MANAGER_GUID1 = 0x3d242466; | ||||||
| @ -45,7 +45,7 @@ namespace LibCmo::CK2 { | |||||||
|  |  | ||||||
| #pragma endregion | #pragma endregion | ||||||
|  |  | ||||||
| #pragma region Misc Constant | #pragma region Misc Constant Variables | ||||||
|  |  | ||||||
| 	/** | 	/** | ||||||
| 	 * @brief The identifier of Virtools file. | 	 * @brief The identifier of Virtools file. | ||||||
| @ -66,7 +66,6 @@ namespace LibCmo::CK2 { | |||||||
|  |  | ||||||
| #pragma region Common Used Struct | #pragma region Common Used Struct | ||||||
|  |  | ||||||
| 	// a stupid forward decl to remove something |  | ||||||
| 	/** | 	/** | ||||||
| 	 * @brief Storage class for filename extensions | 	 * @brief Storage class for filename extensions | ||||||
| 	*/ | 	*/ | ||||||
| @ -97,10 +96,10 @@ namespace LibCmo::CK2 { | |||||||
|  |  | ||||||
| 		void SetExt(CKSTRING s) { | 		void SetExt(CKSTRING s) { | ||||||
| 			if (s == nullptr) { | 			if (s == nullptr) { | ||||||
| 				m_Data[0] = '\0'; | 				m_Data[0] = u8'\0'; | ||||||
| 			} else { | 			} else { | ||||||
| 				if (s[0] == '.') ++s;	// skip dot | 				if (s[0] == u8'.') ++s;	// skip dot | ||||||
| 				size_t len = std::strlen(s); | 				CKDWORD len = CKStrLen(s); | ||||||
| 				if (len > (c_DataLen - 1)) len = c_DataLen - 1; | 				if (len > (c_DataLen - 1)) len = c_DataLen - 1; | ||||||
| 				std::memcpy(m_Data, s, len); | 				std::memcpy(m_Data, s, len); | ||||||
| 			} | 			} | ||||||
| @ -124,11 +123,11 @@ namespace LibCmo::CK2 { | |||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	/** | 	/** | ||||||
| 	 * The struct describe the bitmap handler's infomation, | 	 * @brief Bitmap readers image description | ||||||
| 	 * including its GUID and supported file extension. | 	 * @details | ||||||
| 	 * This struct also will store some parameters related to bitmap handler, | 	 * The struct describe the bitmap handler's infomation, including its GUID and supported file extension. | ||||||
| 	 * such as jpeg compress level and etc. But currently there are no | 	 * This struct also will store some parameters related to bitmap handler, such as jpeg compress level and etc.  | ||||||
| 	 * such parameters. | 	 * But currently there are no such parameters. | ||||||
| 	*/ | 	*/ | ||||||
| 	class CKBitmapProperties { | 	class CKBitmapProperties { | ||||||
| 	public: | 	public: | ||||||
|  | |||||||
| @ -122,6 +122,14 @@ namespace LibCmo::CK2 { | |||||||
| 		return strl[0] == u8'\0'; | 		return strl[0] == u8'\0'; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	CKDWORD CKStrLen(CKSTRING strl) { | ||||||
|  | 		if (strl == nullptr) return 0u; | ||||||
|  | 		size_t len = std::strlen(YYCC::EncodingHelper::ToOrdinary(strl)); | ||||||
|  | 		if (len > static_cast<size_t>(std::numeric_limits<CKDWORD>::max())) | ||||||
|  | 			throw RuntimeException("Exceed maximum value when cast size_t to CKDWORD."); | ||||||
|  | 		return static_cast<CKDWORD>(len); | ||||||
|  | 	} | ||||||
|  |  | ||||||
| #pragma endregion | #pragma endregion | ||||||
|  |  | ||||||
| #pragma region CKClass Registration | #pragma region CKClass Registration | ||||||
|  | |||||||
| @ -82,6 +82,14 @@ namespace LibCmo::CK2 { | |||||||
| 	 * @remarks nullptr string is seen as empty string. | 	 * @remarks nullptr string is seen as empty string. | ||||||
| 	*/ | 	*/ | ||||||
| 	bool CKStrEmpty(CKSTRING strl); | 	bool CKStrEmpty(CKSTRING strl); | ||||||
|  | 	/** | ||||||
|  | 	 * @brief Get the length of given string. | ||||||
|  | 	 * @param[in] strl String for getting length. nullptr is allowed but not suggested. | ||||||
|  | 	 * @return String length in UTF8 code unit. | ||||||
|  | 	 * @remarks nullptr string will return 0 instead. | ||||||
|  | 	 * @exception RuntimeException Raised if the length of string exceed the maximum value of CKDWORD. | ||||||
|  | 	*/ | ||||||
|  | 	CKDWORD CKStrLen(CKSTRING strl); | ||||||
|  |  | ||||||
| 	// ========== Class registration utilities ========== | 	// ========== Class registration utilities ========== | ||||||
|  |  | ||||||
|  | |||||||
| @ -98,14 +98,50 @@ namespace LibCmo::VxMath { | |||||||
|  |  | ||||||
| 	// ========== Patch Section ========== | 	// ========== Patch Section ========== | ||||||
| 	 | 	 | ||||||
|  | 	/** | ||||||
|  | 	 * @brief The patch namespace for VxVector-like classes | ||||||
|  | 	 * @details This namespace provides VxVector-like classes member functions which presented in original Virtools SDK. | ||||||
|  | 	 * These functions are put in public namespace in original Virtools SDK. | ||||||
|  | 	 * We just organise them into an unique namespace. | ||||||
|  | 	*/ | ||||||
| 	namespace NSVxVector { | 	namespace NSVxVector { | ||||||
|  |  | ||||||
|  | 		/** | ||||||
|  | 		 * @brief Dot product 2 2d vectors. | ||||||
|  | 		 * @param[in] lhs The left side vector of dot product symbol. | ||||||
|  | 		 * @param[in] rhs The right side vector of dot product symbol. | ||||||
|  | 		 * @return The float pointing result of dot product. | ||||||
|  | 		*/ | ||||||
| 		CKFLOAT DotProduct(const VxVector2& lhs, const VxVector2& rhs); | 		CKFLOAT DotProduct(const VxVector2& lhs, const VxVector2& rhs); | ||||||
|  | 		/** | ||||||
|  | 		 * @brief Dot product 2 3d vectors. | ||||||
|  | 		 * @param[in] lhs The left side vector of dot product symbol. | ||||||
|  | 		 * @param[in] rhs The right side vector of dot product symbol. | ||||||
|  | 		 * @return The float pointing result of dot product. | ||||||
|  | 		*/ | ||||||
| 		CKFLOAT DotProduct(const VxVector3& lhs, const VxVector3& rhs); | 		CKFLOAT DotProduct(const VxVector3& lhs, const VxVector3& rhs); | ||||||
|  | 		/** | ||||||
|  | 		 * @brief Dot product 2 4d vectors. | ||||||
|  | 		 * @param[in] lhs The left side vector of dot product symbol. | ||||||
|  | 		 * @param[in] rhs The right side vector of dot product symbol. | ||||||
|  | 		 * @return The float pointing result of dot product. | ||||||
|  | 		*/ | ||||||
| 		CKFLOAT DotProduct(const VxVector4& lhs, const VxVector4& rhs); | 		CKFLOAT DotProduct(const VxVector4& lhs, const VxVector4& rhs); | ||||||
|  |  | ||||||
|  | 		/** | ||||||
|  | 		 * @brief Cross product 2 3d vectors. | ||||||
|  | 		 * @param[in] lhs The left side vector of cross product symbol. | ||||||
|  | 		 * @param[in] rhs The right side vector of cross product symbol. | ||||||
|  | 		 * @return The 3d vector result of cross product. | ||||||
|  | 		*/ | ||||||
| 		VxVector3 CrossProduct(const VxVector3& lhs, const VxVector3& rhs); | 		VxVector3 CrossProduct(const VxVector3& lhs, const VxVector3& rhs); | ||||||
| 		 | 		 | ||||||
|  | 		/** | ||||||
|  | 		 * @brief Set all factor in vector to its absolute value. | ||||||
|  | 		 * @param[in,out] lhs The vector for processing. | ||||||
|  | 		 * @remarks This function is rarely used. | ||||||
|  | 		 * Please note this function is not calculate the absolute value of vector. | ||||||
|  | 		*/ | ||||||
| 		void Abs(VxVector3& lhs); | 		void Abs(VxVector3& lhs); | ||||||
|  |  | ||||||
| 	} | 	} | ||||||
|  | |||||||
| @ -4,29 +4,34 @@ | |||||||
| namespace LibCmo::VxMath { | namespace LibCmo::VxMath { | ||||||
|  |  | ||||||
| 	VxMemoryMappedFile::VxMemoryMappedFile(CKSTRING u8_filepath) : | 	VxMemoryMappedFile::VxMemoryMappedFile(CKSTRING u8_filepath) : | ||||||
| 		// init members | 		// Initialize members | ||||||
| #if YYCC_OS == YYCC_OS_WINDOWS | #if YYCC_OS == YYCC_OS_WINDOWS | ||||||
|  | 		// Initialize Windows specific. | ||||||
| 		m_hFile(NULL), m_hFileMapping(NULL), m_hFileMapView(NULL), | 		m_hFile(NULL), m_hFileMapping(NULL), m_hFileMapView(NULL), | ||||||
| 		m_dwFileSizeLow(0), m_dwFileSizeHigh(0), | 		m_dwFileSize(), | ||||||
| #else | #else | ||||||
|  | 		// Initialize Linux specific. | ||||||
| 		m_hFile(-1), m_offFileSize(0), m_pFileAddr((void*)-1), | 		m_hFile(-1), m_offFileSize(0), m_pFileAddr((void*)-1), | ||||||
| #endif | #endif | ||||||
|  | 		// Initialize common members. | ||||||
| 		m_szFilePath(), | 		m_szFilePath(), | ||||||
| 		m_bIsValid(false), m_pMemoryMappedFileBase(nullptr), m_cbFile(0u) { | 		m_bIsValid(false), m_pMemoryMappedFileBase(nullptr), m_cbFile(0u) { | ||||||
|  |  | ||||||
| 		// save file path | 		// Setup file path first | ||||||
| #if YYCC_OS == YYCC_OS_WINDOWS | 		if (u8_filepath == nullptr) return; | ||||||
| 		EncodingHelper::U8PathToStdPath(m_szFilePath, u8_filepath); | 		m_szFilePath = u8_filepath; | ||||||
| #else |  | ||||||
| 		this->m_szFilePath = u8_filepath; |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| 		// real mapping work | 		// Do real mapping work according to different platform. | ||||||
| #if YYCC_OS == YYCC_OS_WINDOWS | #if YYCC_OS == YYCC_OS_WINDOWS | ||||||
|  |  | ||||||
| 		// open file | 		// Parse file name to wchar_t | ||||||
| 		this->m_hFile = CreateFileW( | 		std::wstring w_filename; | ||||||
| 			this->m_szFilePath.wstring().c_str(), | 		if (!YYCC::EncodingHelper::UTF8ToWchar(m_szFilePath, w_filename)) | ||||||
|  | 			return; | ||||||
|  |  | ||||||
|  | 		// Open file | ||||||
|  | 		this->m_hFile = ::CreateFileW( | ||||||
|  | 			w_filename.c_str(), | ||||||
| 			GENERIC_READ, | 			GENERIC_READ, | ||||||
| 			0,	// do not share | 			0,	// do not share | ||||||
| 			NULL,	// no security | 			NULL,	// no security | ||||||
| @ -38,14 +43,18 @@ namespace LibCmo::VxMath { | |||||||
| 			return; | 			return; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		// get size | 		// Get size and check its range. | ||||||
| 		m_dwFileSizeLow = ::GetFileSize(this->m_hFile, &this->m_dwFileSizeHigh); | 		if (!(::GetFileSizeEx(this->m_hFile, &m_dwFileSize))) { | ||||||
| 		if (m_dwFileSizeLow == INVALID_FILE_SIZE) { |  | ||||||
| 			CloseHandle(this->m_hFile); | 			CloseHandle(this->m_hFile); | ||||||
| 			return; | 			return; | ||||||
| 		} | 		} | ||||||
|  | 		if (m_dwFileSize.HighPart != 0) { | ||||||
|  | 			CloseHandle(this->m_hFile); | ||||||
|  | 			return; | ||||||
|  | 		} | ||||||
|  | 		m_cbFile = m_dwFileSize.LowPart; | ||||||
|  |  | ||||||
| 		// open mapping | 		// Open mapping | ||||||
| 		this->m_hFileMapping = CreateFileMappingW( | 		this->m_hFileMapping = CreateFileMappingW( | ||||||
| 			this->m_hFile, | 			this->m_hFile, | ||||||
| 			NULL,	// default security | 			NULL,	// default security | ||||||
| @ -58,7 +67,7 @@ namespace LibCmo::VxMath { | |||||||
| 			return; | 			return; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		// open map view | 		// Open map view | ||||||
| 		this->m_hFileMapView = MapViewOfFile( | 		this->m_hFileMapView = MapViewOfFile( | ||||||
| 			this->m_hFileMapping, | 			this->m_hFileMapping, | ||||||
| 			FILE_MAP_READ, | 			FILE_MAP_READ, | ||||||
| @ -69,16 +78,14 @@ namespace LibCmo::VxMath { | |||||||
| 			CloseHandle(m_hFileMapping); | 			CloseHandle(m_hFileMapping); | ||||||
| 			CloseHandle(m_hFile); | 			CloseHandle(m_hFile); | ||||||
| 		} | 		} | ||||||
|  | 		// Set base address | ||||||
| 		// write member data |  | ||||||
| 		m_pMemoryMappedFileBase = m_hFileMapView; | 		m_pMemoryMappedFileBase = m_hFileMapView; | ||||||
| 		m_cbFile = static_cast<size_t>(static_cast<uint64_t>(m_dwFileSizeLow) | (static_cast<uint64_t>(m_dwFileSizeHigh) << 32)); |  | ||||||
| 		 | 		 | ||||||
| #else | #else | ||||||
| 		// create file | 		// create file | ||||||
| 		// we do not need provide mode_t, because is served for new created file. | 		// we do not need provide mode_t, because is served for new created file. | ||||||
| 		// we are opening a existed file. | 		// we are opening a existed file. | ||||||
| 		this->m_hFile = open(m_szFilePath.string().c_str(), O_RDONLY); | 		this->m_hFile = open(YYCC::EncodingHelper::ToOrdinary(m_szFilePath.c_str()), O_RDONLY); | ||||||
| 		if (m_hFile == -1) { | 		if (m_hFile == -1) { | ||||||
| 			return; | 			return; | ||||||
| 		} | 		} | ||||||
| @ -91,8 +98,13 @@ namespace LibCmo::VxMath { | |||||||
| 			close(m_hFile); | 			close(m_hFile); | ||||||
| 			return; | 			return; | ||||||
| 		} | 		} | ||||||
| 		// setup size | 		// Setup size and check its range | ||||||
| 		this->m_offFileSize = sb.st_size; | 		this->m_offFileSize = sb.st_size; | ||||||
|  | 		if (this->m_offFileSize > static_cast<off_t>(std::numeric_limits<CKDWORD>::max())) { | ||||||
|  | 			close(m_hFile); | ||||||
|  | 			return; | ||||||
|  | 		} | ||||||
|  | 		m_cbFile = static_cast<CKDWORD>(this->m_offFileSize); | ||||||
|  |  | ||||||
| 		// map file | 		// map file | ||||||
| 		this->m_pFileAddr = mmap( | 		this->m_pFileAddr = mmap( | ||||||
| @ -107,10 +119,9 @@ namespace LibCmo::VxMath { | |||||||
| 			close(m_hFile); | 			close(m_hFile); | ||||||
| 			return; | 			return; | ||||||
| 		} | 		} | ||||||
|  | 		// set base address | ||||||
| 		// write member data |  | ||||||
| 		m_pMemoryMappedFileBase = m_pFileAddr; | 		m_pMemoryMappedFileBase = m_pFileAddr; | ||||||
| 		m_cbFile = static_cast<size_t>(this->m_offFileSize); | 		 | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| 		// set valid | 		// set valid | ||||||
| @ -135,5 +146,20 @@ namespace LibCmo::VxMath { | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	const void* VxMemoryMappedFile::GetBase() const { | ||||||
|  | 		if (!this->IsValid()) | ||||||
|  | 			throw RuntimeException("Try to get file base address on an invalid VxMemoryMappedFile"); | ||||||
|  | 		return this->m_pMemoryMappedFileBase; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	CKDWORD VxMemoryMappedFile::GetFileSize() const { | ||||||
|  | 		if (!this->IsValid()) | ||||||
|  | 			throw RuntimeException("Try to get file size on an invalid VxMemoryMappedFile"); | ||||||
|  | 		return this->m_cbFile; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	bool VxMemoryMappedFile::IsValid() const { | ||||||
|  | 		return this->m_bIsValid; | ||||||
|  | 	} | ||||||
|  |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -2,12 +2,9 @@ | |||||||
|  |  | ||||||
| #include "../VTInternal.hpp" | #include "../VTInternal.hpp" | ||||||
| #if YYCC_OS == YYCC_OS_WINDOWS | #if YYCC_OS == YYCC_OS_WINDOWS | ||||||
|  | #include <WinImportPrefix.hpp> | ||||||
| #include <Windows.h> | #include <Windows.h> | ||||||
| // disable annoy macro at the same time | #include <WinImportSuffix.hpp> | ||||||
| #undef GetObject |  | ||||||
| #undef GetClassName |  | ||||||
| #undef LoadImage |  | ||||||
| #undef GetTempPath |  | ||||||
| #else | #else | ||||||
| #include <sys/mman.h> | #include <sys/mman.h> | ||||||
| #include <sys/stat.h> | #include <sys/stat.h> | ||||||
| @ -17,16 +14,19 @@ | |||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #include <string> | #include <string> | ||||||
| #include <filesystem> |  | ||||||
|  |  | ||||||
| namespace LibCmo::VxMath { | namespace LibCmo::VxMath { | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * @brief Utility class for memory mapped file reading. | ||||||
|  | 	 * @details The VxMemoryMappedFile can be used have a mapping of a file into a memory buffer for reading purposes. | ||||||
|  | 	 * @remarks Due to Virtools limitation, we disallow opening any file whose size exceed the maximum value of CKDWORD. | ||||||
|  | 	*/ | ||||||
| 	class VxMemoryMappedFile { | 	class VxMemoryMappedFile { | ||||||
| 	private: | 	private: | ||||||
|  |  | ||||||
| #if YYCC_OS == YYCC_OS_WINDOWS | #if YYCC_OS == YYCC_OS_WINDOWS | ||||||
| 		HANDLE m_hFile; | 		HANDLE m_hFile; | ||||||
| 		DWORD m_dwFileSizeLow, m_dwFileSizeHigh; | 		LARGE_INTEGER m_dwFileSize; | ||||||
| 		HANDLE m_hFileMapping; | 		HANDLE m_hFileMapping; | ||||||
| 		LPVOID m_hFileMapView; | 		LPVOID m_hFileMapView; | ||||||
| #else | #else | ||||||
| @ -35,19 +35,41 @@ namespace LibCmo::VxMath { | |||||||
| 		void* m_pFileAddr; | 		void* m_pFileAddr; | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| 		std::filesystem::path m_szFilePath; | 		std::u8string m_szFilePath; | ||||||
| 		void* m_pMemoryMappedFileBase; | 		void* m_pMemoryMappedFileBase; | ||||||
| 		size_t m_cbFile; | 		CKDWORD m_cbFile; | ||||||
| 		bool m_bIsValid; | 		bool m_bIsValid; | ||||||
| 	public: |  | ||||||
| 		VxMemoryMappedFile(CKSTRING u8_filepath); |  | ||||||
| 		VxMemoryMappedFile(const VxMemoryMappedFile&) = delete; |  | ||||||
| 		VxMemoryMappedFile& operator=(const VxMemoryMappedFile&) = delete; |  | ||||||
| 		~VxMemoryMappedFile(void); |  | ||||||
|  |  | ||||||
| 		void* GetBase(void) { return this->m_pMemoryMappedFileBase; } | 	public: | ||||||
| 		CKDWORD GetFileSize(void) { return static_cast<CKDWORD>(this->m_cbFile); } | 		/** | ||||||
| 		bool IsValid(void) { return this->m_bIsValid; } | 		 * @brief Create a new VxMemoryMappedFile | ||||||
|  | 		 * @param[in] u8_filepath The path to file to be opened. nullptr is allowed but not suggested. | ||||||
|  | 		 * Because it must create an invalid VxMemoryMappedFile. | ||||||
|  | 		*/ | ||||||
|  | 		VxMemoryMappedFile(CKSTRING u8_filepath); | ||||||
|  | 		~VxMemoryMappedFile(); | ||||||
|  | 		YYCC_DEL_CLS_COPY_MOVE(VxMemoryMappedFile); | ||||||
|  |  | ||||||
|  | 		/** | ||||||
|  | 		 * @brief Returns a pointer to the mapped memory buffer. | ||||||
|  | 		 * @return The pointer to the mapped memory buffer for reading. | ||||||
|  | 		 * @remarks | ||||||
|  | 		 * The returned pointer should not be deleted nor should it be used for writing purpose. | ||||||
|  | 		 * If you did, it will cause undefined behavior. | ||||||
|  | 		 * @exception RuntimeException Raised when calling this on an invalid file mapping. | ||||||
|  | 		*/ | ||||||
|  | 		const void* GetBase() const; | ||||||
|  | 		/** | ||||||
|  | 		 * @brief Returns the file size in bytes. | ||||||
|  | 		 * @return The file size in bytes. | ||||||
|  | 		 * @exception RuntimeException Raised when calling this on an invalid file mapping. | ||||||
|  | 		*/ | ||||||
|  | 		CKDWORD GetFileSize() const; | ||||||
|  | 		/** | ||||||
|  | 		 * @brief Check whether this file mapping is valid to use. | ||||||
|  | 		 * @return True if it is, otherwise false. | ||||||
|  | 		*/ | ||||||
|  | 		bool IsValid() const; | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| } | } | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user