diff --git a/LibCmo/LibCmo.vcxproj b/LibCmo/LibCmo.vcxproj
index a3cec72..35fff1b 100644
--- a/LibCmo/LibCmo.vcxproj
+++ b/LibCmo/LibCmo.vcxproj
@@ -100,7 +100,7 @@
true
LIBCMO_EXPORTING;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
true
- $(BOOST_MMAP_INCLUDE_PATH);$(ZLIB_PATH);%(AdditionalIncludeDirectories)
+ $(BOOST_INCLUDE_PATH);$(ZLIB_PATH);%(AdditionalIncludeDirectories)
stdcpp20
@@ -118,7 +118,7 @@
true
LIBCMO_EXPORTING;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
true
- $(BOOST_MMAP_INCLUDE_PATH);$(ZLIB_PATH);%(AdditionalIncludeDirectories)
+ $(BOOST_INCLUDE_PATH);$(ZLIB_PATH);%(AdditionalIncludeDirectories)
stdcpp20
@@ -136,7 +136,7 @@
true
LIBCMO_EXPORTING;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
true
- $(BOOST_MMAP_INCLUDE_PATH);$(ZLIB_PATH);%(AdditionalIncludeDirectories)
+ $(BOOST_INCLUDE_PATH);$(ZLIB_PATH);%(AdditionalIncludeDirectories)
stdcpp20
@@ -154,7 +154,7 @@
true
LIBCMO_EXPORTING;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
true
- $(BOOST_MMAP_INCLUDE_PATH);$(ZLIB_PATH);%(AdditionalIncludeDirectories)
+ $(BOOST_INCLUDE_PATH);$(ZLIB_PATH);%(AdditionalIncludeDirectories)
stdcpp20
@@ -168,9 +168,11 @@
+
+
diff --git a/LibCmo/LibCmo.vcxproj.filters b/LibCmo/LibCmo.vcxproj.filters
index c2526e8..e63257d 100644
--- a/LibCmo/LibCmo.vcxproj.filters
+++ b/LibCmo/LibCmo.vcxproj.filters
@@ -18,6 +18,9 @@
Sources
+
+ Sources
+
@@ -32,5 +35,8 @@
Headers
+
+ Headers
+
\ No newline at end of file
diff --git a/LibCmo/VTConstants.hpp b/LibCmo/VTConstants.hpp
index 8bf8842..e9a3e09 100644
--- a/LibCmo/VTConstants.hpp
+++ b/LibCmo/VTConstants.hpp
@@ -4,6 +4,8 @@
#include
#include
#include
+#include
+#include
namespace LibCmo {
@@ -25,6 +27,16 @@ namespace LibCmo {
}
using CK_ID = uint32_t;
+ using CKDWORD = uint32_t;
+ using CKBOOL = int32_t;
+
+ using XString = std::string;
+ using XBitArray = std::vector;
+ template
+ using XArray = std::vector;
+ using XIntArray = std::vector;
+ template
+ using XClassArray = std::vector;
enum class CK_CLASSID : uint32_t {
CKCID_OBJECT = 1,
diff --git a/LibCmo/VTEncoding.hpp b/LibCmo/VTEncoding.hpp
new file mode 100644
index 0000000..b22f372
--- /dev/null
+++ b/LibCmo/VTEncoding.hpp
@@ -0,0 +1,118 @@
+#pragma once
+
+#include
+
+#if defined(_WIN32)
+#define LIBCMO_OS_WIN32
+#endif
+
+#if defined(LIBCMO_OS_WIN32)
+#include
+#else
+#include
+#endif
+
+namespace LibCmo {
+ namespace Encoding {
+
+#pragma region assist functions
+
+#if defined(LIBCMO_OS_WIN32)
+
+#define LIBCMO_STR_EQUAL(a, b) strcmp(reinterpret_cast(a), reinterpret_cast(b)) == 0
+ bool GetWindowsCodePage(const char* u8_encoding_spec, UINT* result) {
+ if (LIBCMO_STR_EQUAL(u8_encoding_spec, u8"CP_ACP")) *result = CP_ACP;
+ else if (LIBCMO_STR_EQUAL(u8_encoding_spec, u8"CP_MACCP")) *result = CP_MACCP;
+ else if (LIBCMO_STR_EQUAL(u8_encoding_spec, u8"CP_OEMCP")) *result = CP_OEMCP;
+ else if (LIBCMO_STR_EQUAL(u8_encoding_spec, u8"CP_THREAD_ACPP")) *result = CP_THREAD_ACP;
+ else if (LIBCMO_STR_EQUAL(u8_encoding_spec, u8"CP_UTF8")) *result = CP_UTF8;
+ else {
+ char* pend = nullptr;
+ errno = 0;
+ uint64_t v = std::strtoull(u8_encoding_spec, &pend, 10);
+
+ if (pend == u8_encoding_spec || errno == ERANGE) return false;
+ *result = static_cast(v);
+ }
+ return true;
+ }
+#undef LIBCMO_STR_EQUAL
+
+ bool WcharToChar(const wchar_t* src, std::string& dest, UINT codepage) {
+ int count, write_result;
+
+ //converter to CHAR
+ count = WideCharToMultiByte(CP_UTF8, 0, src, -1, NULL, 0, NULL, NULL);
+ if (count <= 0) return false;
+
+ dest.resize(count);
+ write_result = WideCharToMultiByte(CP_UTF8, 0, src, -1, dest.data(), count, NULL, NULL);
+ if (write_result <= 0) return false;
+
+ return true;
+ }
+ bool WcharToChar(std::wstring& src, std::string& dest, UINT codepage) {
+ return WcharToChar(src.c_str(), dest, codepage);
+ }
+
+ bool CharToWchar(const char* src, std::wstring& dest, UINT codepage) {
+ int wcount, write_result;
+
+ // convert to WCHAR
+ wcount = MultiByteToWideChar(codepage, 0, src, -1, NULL, 0);
+ if (wcount <= 0) return false;
+
+ dest.resize(wcount);
+ write_result = MultiByteToWideChar(CP_UTF8, 0, src, -1, dest.data(), wcount);
+ if (write_result <= 0) return false;
+
+ return true;
+ }
+ bool CharToWchar(std::string& src, std::wstring& dest, UINT codepage) {
+ return CharToWchar(src.c_str(), dest, codepage);
+ }
+
+#else
+
+ //todo: linux implementation
+
+#endif
+
+#pragma endregion
+
+#pragma region core functions
+
+#if defined(LIBCMO_OS_WIN32)
+
+ void GetUtf8VirtoolsName(std::string& native_name, std::string& u8_name, const char* u8_encoding_spec) {
+ // switch encoding spec
+ UINT codepage = CP_ACP;
+ if (!GetWindowsCodePage(u8_encoding_spec, &codepage)) {
+ u8_name = native_name.c_str();
+ return;
+ }
+
+ // do convert
+ std::wstring intermediary;
+ if (!CharToWchar(native_name, intermediary, codepage)) {
+ u8_name = native_name.c_str();
+ return;
+ }
+ if (!WcharToChar(intermediary, u8_name, CP_UTF8)) {
+ u8_name = native_name.c_str();
+ return;
+ }
+
+ return;
+ }
+
+#else
+ //todo: linux implementation
+#error NO IMPLEMENTATION FOR LINUX ENCODING!
+
+#endif
+
+#pragma endregion
+
+ }
+}
diff --git a/LibCmo/VTStruct.cpp b/LibCmo/VTStruct.cpp
new file mode 100644
index 0000000..abf6204
--- /dev/null
+++ b/LibCmo/VTStruct.cpp
@@ -0,0 +1,56 @@
+#include "VTStruct.hpp"
+
+namespace LibCmo {
+
+ VxMemoryMappedFile::VxMemoryMappedFile(const char* u8_filepath) :
+ m_szFilePath(),
+ m_hFile(nullptr), m_hFileMapping(nullptr),
+ m_bIsValid(false) {
+
+ // save file path and set region option
+ boost::interprocess::map_options_t region_option;
+#if defined(LIBCMO_OS_WIN32)
+ Encoding::CharToWchar(u8_filepath, this->m_szFilePath, CP_UTF8);
+ region_option = FILE_MAP_READ;
+#else
+ this->m_szFilePath = u8_filepath;
+ region_option = boost::interprocess::default_map_options;
+#endif
+
+ // open file
+ this->m_hFile = new boost::interprocess::file_mapping(
+ this->m_szFilePath.c_str(), boost::interprocess::read_only
+ );
+
+ // open region
+ this->m_hFileMapping = new boost::interprocess::mapped_region(
+ this->m_hFile, boost::interprocess::read_only,
+ 0, 0, nullptr,
+ region_option
+ );
+
+ // set valid
+ this->m_bIsValid = true;
+
+ }
+
+ VxMemoryMappedFile::~VxMemoryMappedFile(void) {
+ this->m_bIsValid = false;
+
+ delete this->m_hFileMapping;
+ boost::interprocess::file_mapping::remove(this->m_szFilePath.c_str());
+ delete this->m_hFile;
+ }
+
+ void* VxMemoryMappedFile::GetBase(void) { return this->m_hFileMapping->get_address(); }
+ size_t VxMemoryMappedFile::GetFileSize(void) { return this->m_hFileMapping->get_size(); }
+ bool VxMemoryMappedFile::IsValid(void) { return this->m_bIsValid; }
+
+
+ CKFile::CKFile() {
+ }
+
+ CKFile::~CKFile() {
+ }
+
+}
diff --git a/LibCmo/VTStruct.hpp b/LibCmo/VTStruct.hpp
index 6f70f09..2fc05fe 100644
--- a/LibCmo/VTStruct.hpp
+++ b/LibCmo/VTStruct.hpp
@@ -1 +1,142 @@
#pragma once
+
+#include "VTConstants.hpp"
+#include "VTEncoding.hpp"
+#include
+
+// only expose boost in libcom self. do not let it be seen by any program using libcmo.
+#if defined(LIBCMO_EXPORTING)
+#include
+#include
+#endif
+
+namespace LibCmo {
+
+ struct CKGUID {
+ union {
+ struct {
+ CKDWORD d1, d2;
+ };
+ CKDWORD d[2];
+ };
+ CKGUID(CKDWORD gd1 = 0, CKDWORD gd2 = 0) { d[0] = gd1; d[1] = gd2; }
+ };
+
+ // define some mapped file to make boost is invisible for
+ // any program using this library
+#if defined(LIBCMO_EXPORTING)
+ using P_FILE_MAPPING = boost::interprocess::file_mapping*;
+ using P_MAPPED_REGION = boost::interprocess::mapped_region*;
+#else
+ using P_FILE_MAPPING = void*;
+ using P_MAPPED_REGION = void*;
+#endif
+
+ class VxMemoryMappedFile {
+ public:
+ VxMemoryMappedFile(const char* u8_filepath);
+ ~VxMemoryMappedFile(void);
+
+ void* GetBase(void);
+ size_t GetFileSize(void);
+ bool IsValid(void);
+
+ private:
+
+#if defined(LIBCMO_OS_WIN32)
+ std::wstring m_szFilePath;
+#else
+ std::string m_szFilePath;
+#endif
+
+ P_FILE_MAPPING m_hFile;
+ P_MAPPED_REGION m_hFileMapping;
+ bool m_bIsValid;
+ };
+
+ class CKBufferParser {
+ private:
+ char* m_ReaderBegin;
+ size_t m_ReaderPos;
+ bool m_NeedManualFree;
+ size_t m_ReaderSize;
+
+ public:
+ CKBufferParser(void* ptr, size_t rsize, bool need_manual_free) :
+ m_ReaderBegin(static_cast(ptr)),
+ m_ReaderPos(0u), m_ReaderSize(rsize),
+ m_NeedManualFree(need_manual_free) {
+ ;
+ }
+ ~CKBufferParser() {
+ if (this->m_NeedManualFree) free(this->m_ReaderBegin);
+ }
+
+ inline void* GetPtr(void) { return (this->m_ReaderBegin + m_ReaderPos); }
+ inline size_t GetSize(void) { return this->m_ReaderSize; }
+ inline void MoveCursor(size_t off) { this->m_ReaderPos += off; }
+ inline void SetCursor(size_t off) { this->m_ReaderPos = off; }
+ };
+
+ struct CKFileInfo {
+ CKDWORD ProductVersion; // Virtools Version (Dev/Creation). (CK_VIRTOOLS_VERSION)
+ CKDWORD ProductBuild; // Virtools Build Number.
+ CK_FILE_WRITEMODE FileWriteMode; // Options used to save this file. (CK_FILE_WRITEMODE)
+ CKDWORD FileVersion; // Version of file format when file was saved.
+ CKDWORD CKVersion; // Version of CK when file was saved.
+ CKDWORD FileSize; // Size of file in bytes.
+ CKDWORD ObjectCount; // Number of objects stored in the file.
+ CKDWORD ManagerCount; // Number of managers which saved data in the file.
+ CKDWORD MaxIDSaved; // Maximum Object identifier saved
+ CKDWORD Crc; // Crc of data
+ CKDWORD Hdr1PackSize; // Reserved
+ CKDWORD Hdr1UnPackSize; // Reserved
+ CKDWORD DataPackSize; // Reserved
+ CKDWORD DataUnPackSize; // Reserved
+ };
+
+ struct CKFileObject {
+ CK_ID Object;
+ CK_ID CreatedObject;
+ CK_CLASSID ObjectCid;
+ void* ObjPtr;
+ std::string Name;
+ void* Data;
+ CKDWORD PostPackSize;
+ CKDWORD PrePackSize;
+ CK_FO_OPTIONS Options;
+ CKDWORD FileIndex;
+ CK_FILE_WRITEMODE SaveFlags;
+ };
+
+ struct CKFilePluginDependencies {
+ CKDWORD m_PluginCategory;
+ XArray m_Guids;
+ XBitArray ValidGuids;
+ };
+
+ class CKFile {
+ public:
+ CKFile();
+ ~CKFile();
+
+
+ int32_t m_SaveIDMax;
+ XArray m_FileObject;
+ //XArray m_ManagersData;
+ XClassArray m_PluginDep;
+ //XClassArray m_IndexByClassId;
+ //XClassArray m_IncludedFiles;
+
+ CKFileInfo m_FileInfo;
+
+ CK_LOAD_FLAGS m_Flags;
+ std::string m_FileName;
+ CKBufferParser* m_Parser;
+ VxMemoryMappedFile* m_MappedFile;
+
+ bool m_ReadFileDataDone;
+
+ };
+
+}
diff --git a/LibRef.props b/LibRef.props
index ef3cd11..47c1132 100644
--- a/LibRef.props
+++ b/LibRef.props
@@ -2,7 +2,7 @@
- D:\CppLib\interprocess-boost-1.81.0\include
+ D:\CppLib\boost_1_81_0
D:\CppLib\SQLite\sqlite-amalgamation-3400100
D:\CppLib\SQLite\sqlite-dll-win32-x86-3400100
@@ -13,8 +13,8 @@
-
- $(BOOST_MMAP_INCLUDE_PATH)
+
+ $(BOOST_INCLUDE_PATH)
diff --git a/Unvirt/Unvirt.cpp b/Unvirt/Unvirt.cpp
index 25f4db6..25308c4 100644
--- a/Unvirt/Unvirt.cpp
+++ b/Unvirt/Unvirt.cpp
@@ -10,7 +10,7 @@ int main(int argc, char* argv[]) {
Unvirt::AccessibleValue::GetEnumName(Unvirt::AccessibleValue::EnumDesc::CK_FO_OPTIONS, test, LibCmo::CK_FO_OPTIONS::CK_FO_RENAMEOBJECT);
printf("%s\n", test.c_str());
-
+
Unvirt::AccessibleValue::GetFlagEnumName(Unvirt::AccessibleValue::EnumDesc::CK_LOAD_FLAGS, test, LibCmo::CK_LOAD_FLAGS::CK_LOAD_DEFAULT);
printf("%s\n", test.c_str());
auto v = LibCmo::EnumHelper::FlagEnumAdd(LibCmo::CK_LOAD_FLAGS::CK_LOAD_ANIMATION, LibCmo::CK_LOAD_FLAGS::CK_LOAD_ASCHARACTER);