├── .editorconfig ├── .gitattributes ├── .github └── workflows │ └── cmake-multi-platform.yml ├── .gitignore ├── CMakeLists.txt ├── CMakePresets.json ├── LICENCE ├── README.md ├── advstr ├── CMakeLists.txt ├── advstr.cpp ├── advstr.h ├── alstr.cpp └── alstr.h ├── bis ├── CMakeLists.txt ├── Container │ ├── BasicContainer.cpp │ ├── BasicContainer.h │ ├── IsoContainer.cpp │ └── IsoContainer.h ├── Data │ ├── Basic │ │ ├── Double.cpp │ │ ├── Double.h │ │ ├── Dummy.cpp │ │ ├── Dummy.h │ │ ├── Enum.cpp │ │ ├── Enum.h │ │ ├── Float.cpp │ │ ├── Float.h │ │ ├── Integer.cpp │ │ ├── Integer.h │ │ ├── String.cpp │ │ ├── String.h │ │ └── UString.h │ ├── BasicTypeCreator.cpp │ ├── BasicTypeCreator.h │ ├── Storage │ │ ├── BinaryBlock.cpp │ │ └── BinaryBlock.h │ ├── VarChar.cpp │ └── VarChar.h └── Stream │ ├── ElfStream.cpp │ └── ElfStream.h ├── docs ├── bis │ └── Container.md ├── mulert │ └── mulert.md └── overview.md ├── lib ├── CMakeLists.txt ├── include │ └── lua │ │ ├── lauxlib.h │ │ ├── lua.h │ │ ├── lua.hpp │ │ ├── luaconf.h │ │ └── lualib.h ├── lua │ ├── Makefile │ ├── lapi.c │ ├── lapi.h │ ├── lauxlib.c │ ├── lauxlib.h │ ├── lbaselib.c │ ├── lcode.c │ ├── lcode.h │ ├── lcorolib.c │ ├── lctype.c │ ├── lctype.h │ ├── ldblib.c │ ├── ldebug.c │ ├── ldebug.h │ ├── ldo.c │ ├── ldo.h │ ├── ldump.c │ ├── lfunc.c │ ├── lfunc.h │ ├── lgc.c │ ├── lgc.h │ ├── linit.c │ ├── liolib.c │ ├── ljumptab.h │ ├── llex.c │ ├── llex.h │ ├── llimits.h │ ├── lmathlib.c │ ├── lmem.c │ ├── lmem.h │ ├── loadlib.c │ ├── lobject.c │ ├── lobject.h │ ├── lopcodes.c │ ├── lopcodes.h │ ├── lopnames.h │ ├── loslib.c │ ├── lparser.c │ ├── lparser.h │ ├── lprefix.h │ ├── lstate.c │ ├── lstate.h │ ├── lstring.c │ ├── lstring.h │ ├── lstrlib.c │ ├── ltable.c │ ├── ltable.h │ ├── ltablib.c │ ├── ltm.c │ ├── ltm.h │ ├── lua.c │ ├── lua.h │ ├── lua.hpp │ ├── luac.c │ ├── luaconf.h │ ├── lualib.h │ ├── lundump.c │ ├── lundump.h │ ├── lutf8lib.c │ ├── lvm.c │ ├── lvm.h │ ├── lzio.c │ └── lzio.h └── xybase │ ├── BinaryStream.cpp │ ├── BinaryStream.h │ ├── CMakeLists.txt │ ├── Event.h │ ├── Exception │ ├── Exception.cpp │ ├── Exception.h │ ├── IOException.cpp │ ├── IOException.h │ ├── InvalidOperationException.cpp │ ├── InvalidOperationException.h │ ├── InvalidParameterException.cpp │ ├── InvalidParameterException.h │ ├── NotImplementedException.cpp │ ├── NotImplementedException.h │ ├── OutOfRangeException.cpp │ ├── OutOfRangeException.h │ ├── RuntimeException.cpp │ └── RuntimeException.h │ ├── FileContainer.cpp │ ├── FileContainer.h │ ├── FileContainerBasic.cpp │ ├── FileContainerBasic.h │ ├── Fragment │ ├── Fragment.cpp │ ├── Fragment.h │ ├── FragmentManager.cpp │ └── FragmentManager.h │ ├── HostFsMapper.cpp │ ├── HostFsMapper.h │ ├── MemoryStream.cpp │ ├── MemoryStream.h │ ├── Singleton.h │ ├── Stream.cpp │ ├── Stream.h │ ├── StreamBasic.cpp │ ├── StreamBasic.h │ ├── StringBuilder.h │ ├── TextStream.cpp │ ├── TextStream.h │ ├── Xml │ ├── XmlNode.cpp │ ├── XmlNode.h │ └── XmlParser.h │ ├── xyapi.h │ ├── xystring.cpp │ ├── xystring.h │ ├── xyutils.cpp │ └── xyutils.h ├── mule ├── CMakeLists.txt ├── codepage.cpp ├── codepage.h ├── crc32.cpp ├── crc32.h ├── luaenv.cpp ├── luaenv.h ├── mule.cpp ├── mule.h └── version.h.in ├── mulert ├── CMakeLists.txt ├── Configuration.cpp ├── Configuration.h ├── Data │ ├── Array.cpp │ ├── Array.h │ ├── Basic │ │ ├── BasicType.cpp │ │ ├── BasicType.h │ │ ├── ContextManager.cpp │ │ ├── ContextManager.h │ │ ├── MultiValue.cpp │ │ ├── MultiValue.h │ │ ├── Type.cpp │ │ └── Type.h │ ├── Reference.cpp │ ├── Reference.h │ ├── Sheet.cpp │ ├── Sheet.h │ ├── SmartReference.cpp │ ├── SmartReference.h │ ├── Structure.cpp │ ├── Structure.h │ ├── TypeCreator.cpp │ ├── TypeCreator.h │ ├── TypeManager.cpp │ └── TypeManager.h ├── Logger.cpp ├── Logger.h ├── Mule.cpp ├── Mule.h ├── MuleRtVersion.h.in ├── SheetManager.cpp ├── SheetManager.h ├── SheetReference.cpp ├── SheetReference.h ├── Storage │ ├── BinaryData.cpp │ ├── BinaryData.h │ ├── DataManager.cpp │ ├── DataManager.h │ ├── ResourceManager.cpp │ └── ResourceManager.h ├── TranscripterManager.cpp ├── TranscripterManager.h ├── VirtualFileSystem.cpp ├── VirtualFileSystem.h └── mulert_api.h └── sis ├── CMakeLists.txt ├── Cpp ├── BisEnv.cpp ├── BisEnv.h ├── CStyleInitHandler.cpp ├── CStyleInitHandler.h ├── Mappifier.cpp └── Mappifier.h ├── Csv ├── CsvFileHandler.cpp ├── CsvFileHandler.h ├── CsvHandler.cpp └── CsvHandler.h ├── Json ├── JsonFileHandler.cpp ├── JsonFileHandler.h ├── JsonOutHandler.cpp └── JsonOutHandler.h ├── Lua ├── Api │ ├── ContainerOperation.cpp │ ├── ContainerOperation.h │ ├── StreamOperation.cpp │ ├── StreamOperation.h │ ├── SystemOperation.cpp │ ├── SystemOperation.h │ └── readme.txt ├── CMakeLists.txt ├── LuaDataHandler.cpp ├── LuaDataHandler.h ├── LuaEnvironment.cpp ├── LuaEnvironment.h ├── LuaHost.cpp └── LuaHost.h ├── Ruby ├── CMakeLists.txt ├── RubyHost.cpp └── RubyHost.h └── Xml ├── MvXmlNode.cpp ├── MvXmlNode.h ├── XmlDefinition.cpp ├── XmlDefinition.h ├── XmlGenerator.h ├── XmlHandler.cpp └── XmlHandler.h /.editorconfig: -------------------------------------------------------------------------------- 1 | # Visual Studio 生成了具有 C++ 设置的 .editorconfig 文件。 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | 7 | [*.{c++,cc,cpp,cppm,cxx,h,h++,hh,hpp,hxx,inl,ipp,ixx,tlh,tli}] 8 | 9 | # Visual C++ 代码样式设置 10 | 11 | cpp_generate_documentation_comments = doxygen_slash_star 12 | 13 | # Visual C++ 格式设置 14 | 15 | cpp_indent_braces = false 16 | cpp_indent_multi_line_relative_to = innermost_parenthesis 17 | cpp_indent_within_parentheses = indent 18 | cpp_indent_preserve_within_parentheses = true 19 | cpp_indent_case_contents = true 20 | cpp_indent_case_labels = false 21 | cpp_indent_case_contents_when_block = false 22 | cpp_indent_lambda_braces_when_parameter = true 23 | cpp_indent_goto_labels = one_left 24 | cpp_indent_preprocessor = leftmost_column 25 | cpp_indent_access_specifiers = false 26 | cpp_indent_namespace_contents = true 27 | cpp_indent_preserve_comments = false 28 | cpp_new_line_before_open_brace_namespace = ignore 29 | cpp_new_line_before_open_brace_type = ignore 30 | cpp_new_line_before_open_brace_function = ignore 31 | cpp_new_line_before_open_brace_block = ignore 32 | cpp_new_line_before_open_brace_lambda = ignore 33 | cpp_new_line_scope_braces_on_separate_lines = false 34 | cpp_new_line_close_brace_same_line_empty_type = false 35 | cpp_new_line_close_brace_same_line_empty_function = false 36 | cpp_new_line_before_catch = true 37 | cpp_new_line_before_else = true 38 | cpp_new_line_before_while_in_do_while = false 39 | cpp_space_before_function_open_parenthesis = remove 40 | cpp_space_within_parameter_list_parentheses = false 41 | cpp_space_between_empty_parameter_list_parentheses = false 42 | cpp_space_after_keywords_in_control_flow_statements = true 43 | cpp_space_within_control_flow_statement_parentheses = false 44 | cpp_space_before_lambda_open_parenthesis = false 45 | cpp_space_within_cast_parentheses = false 46 | cpp_space_after_cast_close_parenthesis = false 47 | cpp_space_within_expression_parentheses = false 48 | cpp_space_before_block_open_brace = true 49 | cpp_space_between_empty_braces = false 50 | cpp_space_before_initializer_list_open_brace = false 51 | cpp_space_within_initializer_list_braces = true 52 | cpp_space_preserve_in_initializer_list = true 53 | cpp_space_before_open_square_bracket = false 54 | cpp_space_within_square_brackets = false 55 | cpp_space_before_empty_square_brackets = false 56 | cpp_space_between_empty_square_brackets = false 57 | cpp_space_group_square_brackets = true 58 | cpp_space_within_lambda_brackets = false 59 | cpp_space_between_empty_lambda_brackets = false 60 | cpp_space_before_comma = false 61 | cpp_space_after_comma = true 62 | cpp_space_remove_around_member_operators = true 63 | cpp_space_before_inheritance_colon = true 64 | cpp_space_before_constructor_colon = true 65 | cpp_space_remove_before_semicolon = true 66 | cpp_space_after_semicolon = true 67 | cpp_space_remove_around_unary_operator = true 68 | cpp_space_around_binary_operator = insert 69 | cpp_space_around_assignment_operator = insert 70 | cpp_space_pointer_reference_alignment = right 71 | cpp_space_around_ternary_operator = insert 72 | cpp_wrap_preserve_blocks = one_liners 73 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # CMakeList.txt: 顶层 CMake 项目文件,在此处执行全局配置 2 | # 并包含子项目。 3 | # 4 | cmake_minimum_required (VERSION 3.8) 5 | 6 | project ("mule" VERSION 1.6.0) 7 | 8 | set (USING_LUA ON) 9 | 10 | set (CXX_STANDARD_REQUIRED ON) 11 | 12 | set (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) 13 | 14 | if (MSVC) 15 | add_definitions(-D_CRT_SECURE_NO_WARNINGS) 16 | # 使用 ZI 支持热重载 17 | set (CMAKE_CXX_FLAGS_DEBUG "/MDd /ZI /Ob0 /Od /RTC1") 18 | endif() 19 | 20 | if (CMAKE_COMPILER_IS_GNUCXX) 21 | if (${CMAKE_BUILD_TYPE} STREQUAL "Debug") 22 | add_compile_options("-Wall") 23 | endif() 24 | endif() 25 | 26 | set (CMAKE_DEBUG_POSTFIX "d") 27 | 28 | # 包含子项目。 29 | add_subdirectory ("lib") 30 | add_subdirectory ("mulert") 31 | add_subdirectory ("bis") 32 | add_subdirectory ("sis") 33 | add_subdirectory ("mule") 34 | add_subdirectory ("advstr") 35 | 36 | # 37 | include (GNUInstallDirs) 38 | install(TARGETS advstr DESTINATION ${CMAKE_INSTALL_BINDIR}) 39 | install(TARGETS mule DESTINATION ${CMAKE_INSTALL_BINDIR}) 40 | install(TARGETS mulert DESTINATION ${CMAKE_INSTALL_BINDIR}) 41 | install(TARGETS xybase_dyn DESTINATION ${CMAKE_INSTALL_BINDIR}) 42 | 43 | if(MSVC) 44 | target_compile_options(sislua PUBLIC "/utf-8") 45 | target_compile_options(bis PUBLIC "/utf-8") 46 | target_compile_options(sis PUBLIC "/utf-8") 47 | target_compile_options(mule PUBLIC "/utf-8") 48 | if(${CMAKE_BUILD_TYPE} STREQUAL "Debug") 49 | target_link_options(bis PUBLIC "/INCREMENTAL") 50 | target_link_options(sis PUBLIC "/INCREMENTAL") 51 | target_link_options(mule PUBLIC "/INCREMENTAL") 52 | endif() 53 | endif() 54 | -------------------------------------------------------------------------------- /CMakePresets.json: -------------------------------------------------------------------------------- 1 | { 2 | "configurePresets": [ 3 | { 4 | "name": "windows-base", 5 | "hidden": true, 6 | "generator": "Ninja", 7 | "binaryDir": "${sourceDir}/out/build/${presetName}", 8 | "installDir": "${sourceDir}/out/install/${presetName}", 9 | "cacheVariables": { 10 | "CMAKE_C_COMPILER": "cl.exe", 11 | "CMAKE_CXX_COMPILER": "cl.exe" 12 | }, 13 | "condition": { 14 | "type": "equals", 15 | "lhs": "${hostSystemName}", 16 | "rhs": "Windows" 17 | } 18 | }, 19 | { 20 | "name": "x64-debug", 21 | "displayName": "x64 Debug", 22 | "inherits": "windows-base", 23 | "architecture": { 24 | "value": "x64", 25 | "strategy": "external" 26 | }, 27 | "cacheVariables": { 28 | "CMAKE_BUILD_TYPE": "Debug" 29 | } 30 | }, 31 | { 32 | "name": "x64-release", 33 | "displayName": "x64 Release", 34 | "inherits": "x64-debug", 35 | "cacheVariables": { 36 | "CMAKE_BUILD_TYPE": "Release" 37 | } 38 | }, 39 | { 40 | "name": "x86-debug", 41 | "displayName": "x86 Debug", 42 | "inherits": "windows-base", 43 | "architecture": { 44 | "value": "x86", 45 | "strategy": "external" 46 | }, 47 | "cacheVariables": { 48 | "CMAKE_BUILD_TYPE": "Debug" 49 | } 50 | }, 51 | { 52 | "name": "x86-release", 53 | "displayName": "x86 Release", 54 | "inherits": "x86-debug", 55 | "cacheVariables": { 56 | "CMAKE_BUILD_TYPE": "Release" 57 | } 58 | }, 59 | { 60 | "name": "linux-debug", 61 | "displayName": "Linux Debug", 62 | "generator": "Ninja", 63 | "binaryDir": "${sourceDir}/out/build/${presetName}", 64 | "installDir": "${sourceDir}/out/install/${presetName}", 65 | "cacheVariables": { 66 | "CMAKE_BUILD_TYPE": "Debug", 67 | "CMAKE_CXX_COMPILER": "/usr/bin/g++-13", 68 | "CMAKE_C_COMPILER": "/usr/bin/gcc-13" 69 | }, 70 | "condition": { 71 | "type": "equals", 72 | "lhs": "${hostSystemName}", 73 | "rhs": "Linux" 74 | }, 75 | "vendor": { 76 | "microsoft.com/VisualStudioRemoteSettings/CMake/1.0": { 77 | "sourceDir": "$env{HOME}/.vs/$ms{projectDirName}" 78 | } 79 | } 80 | }, 81 | { 82 | "name": "macos-debug", 83 | "displayName": "macOS Debug", 84 | "generator": "Ninja", 85 | "binaryDir": "${sourceDir}/out/build/${presetName}", 86 | "installDir": "${sourceDir}/out/install/${presetName}", 87 | "cacheVariables": { 88 | "CMAKE_BUILD_TYPE": "Debug" 89 | }, 90 | "condition": { 91 | "type": "equals", 92 | "lhs": "${hostSystemName}", 93 | "rhs": "Darwin" 94 | }, 95 | "vendor": { 96 | "microsoft.com/VisualStudioRemoteSettings/CMake/1.0": { 97 | "sourceDir": "$env{HOME}/.vs/$ms{projectDirName}" 98 | } 99 | } 100 | } 101 | ], 102 | "version": 3 103 | } 104 | -------------------------------------------------------------------------------- /LICENCE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (C) 2023 XiyanFlowC. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | 11 | Libs 12 | ================= 13 | 14 | LUA 15 | ----------------- 16 | 17 | Copyright © 1994–2022 Lua.org, PUC-Rio. 18 | 19 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 20 | 21 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /advstr/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library (advstr SHARED "advstr.cpp" "advstr.h" "alstr.h" "alstr.cpp") 2 | 3 | target_link_libraries (advstr PRIVATE mulert xybase_dyn) 4 | 5 | if (MSVC) 6 | target_compile_options (advstr PRIVATE "/utf-8") 7 | endif() 8 | 9 | if (LINUX) 10 | add_custom_command(TARGET advstr POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different 11 | $ 12 | ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) 13 | endif () 14 | 15 | set_property(TARGET advstr PROPERTY CXX_STANDARD 20) -------------------------------------------------------------------------------- /advstr/advstr.cpp: -------------------------------------------------------------------------------- 1 | #include "advstr.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include "alstr.h" 7 | 8 | int b2t(const char16_t *converter, xybase::Stream *input, xybase::TextStream *output, const char16_t *param) 9 | { 10 | if (0 == memcmp(u"addrtxt", converter, sizeof(u"addrtxt"))) 11 | { 12 | std::u16string para(param); 13 | std::u16string sta = para.substr(0, para.find(':')), 14 | end = para.substr(para.find(':') + 1); 15 | return str_ex(input, output, (int)xybase::string::stoi(sta, 16), (int)xybase::string::stoi(end, 16)); 16 | } 17 | return -1; 18 | } 19 | 20 | int t2b(const char16_t *converter, xybase::TextStream *input, xybase::Stream *output, const char16_t *param) 21 | { 22 | if (0 == memcmp(u"addrtxt", converter, sizeof(u"addrtxt"))) 23 | { 24 | return str_im(input, output); 25 | } 26 | return -1; 27 | } 28 | 29 | mule::PluginDescription desc{ 30 | .name = L"Advanced String Operations", 31 | .author = L"xiyan", 32 | .licence = L"MIT", 33 | .majorVer = 1, 34 | .minorVer = 4, 35 | .description = L"Provides advanced string operation feature", 36 | .muleRtMajorVersion = MULERT_MAJOR_VERSION, 37 | .muleRtMinorVersion = MULERT_MINOR_VERSION, 38 | .ConvertToText = b2t, 39 | .ConvertToBinary = t2b 40 | }; 41 | -------------------------------------------------------------------------------- /advstr/advstr.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifdef WIN32 4 | #define ADVSTR_API __declspec(dllexport) 5 | #else 6 | #define ADVSTR_API 7 | #endif 8 | 9 | extern mule::PluginDescription desc; 10 | 11 | extern "C" 12 | { 13 | mule::PluginDescription ADVSTR_API *GetDescription() 14 | { 15 | return &desc; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /advstr/alstr.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Addressed, lengthed string 3 | * Sniffer and importer 4 | */ 5 | #pragma once 6 | 7 | #include 8 | #include 9 | 10 | int str_ex(xybase::Stream *input, xybase::TextStream *output, int begin, int end); 11 | 12 | int str_im(xybase::TextStream *input, xybase::Stream *output); 13 | -------------------------------------------------------------------------------- /bis/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library (bis "Data/Basic/Integer.cpp" "Data/Basic/String.cpp" "Data/Basic/String.h" "Data/Basic/Float.cpp" "Data/Basic/Float.h" "Data/Basic/Double.cpp" "Data/Basic/Double.h" "Container/BasicContainer.cpp" "Container/BasicContainer.h" "Data/VarChar.cpp" "Data/VarChar.h" "Stream/ElfStream.h" "Stream/ElfStream.cpp" "Container/IsoContainer.cpp" "Container/IsoContainer.h" "Data/Storage/BinaryBlock.h" "Data/Storage/BinaryBlock.cpp" "Data/BasicTypeCreator.h" "Data/BasicTypeCreator.cpp" "Data/Basic/Enum.cpp" "Data/Basic/Enum.h" "Data/Basic/Dummy.h" "Data/Basic/Dummy.cpp" "Data/Basic/UString.h") 2 | 3 | target_include_directories (bis INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) 4 | 5 | target_link_libraries (bis PUBLIC mulert) 6 | 7 | if (CMAKE_VERSION VERSION_GREATER 3.12) 8 | set_property(TARGET bis PROPERTY CXX_STANDARD 20) 9 | endif() 10 | -------------------------------------------------------------------------------- /bis/Container/BasicContainer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef BASIC_CONTAINER_H__ 4 | #define BASIC_CONTAINER_H__ 5 | 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | namespace mule 15 | { 16 | class BasicContainer : public xybase::FileContainer 17 | { 18 | std::stack dir; 19 | 20 | std::map locs; 21 | 22 | int curId = 0; 23 | 24 | std::u16string name; 25 | 26 | enum { 27 | BC_IDLE, 28 | BC_READ, 29 | BC_WRITE 30 | } state; 31 | protected: 32 | 33 | xybase::Stream *file; 34 | 35 | void ReadBytes(int id, char *buffer, size_t size); 36 | 37 | void Write(int id, const char *buffer, size_t size); 38 | 39 | void Close(int id); 40 | 41 | public: 42 | class InnerFile : public xybase::StreamBasic 43 | { 44 | BasicContainer *host; 45 | 46 | int handle; 47 | 48 | size_t size, offset; 49 | 50 | std::u16string name; 51 | public: 52 | 53 | bool isBigEndian = false; 54 | 55 | ~InnerFile(); 56 | 57 | InnerFile(int handle, size_t size, size_t offset, BasicContainer *host, const std::u16string &name); 58 | 59 | virtual void ReadBytes(char *buffer, size_t limit) override; 60 | virtual void Write(const char *buffer, size_t size) override; 61 | virtual size_t Tell() const override; 62 | virtual void Seek(long long offset, SeekMode mode) override; 63 | virtual void Close() override; 64 | virtual std::u16string GetName() const override; 65 | virtual void Flush() override; 66 | 67 | virtual bool IsEof() const noexcept override; 68 | }; 69 | 70 | struct FileDesc 71 | { 72 | size_t offset; 73 | size_t size; 74 | size_t curSize; 75 | bool occupied; 76 | }; 77 | 78 | std::map fileIndices; 79 | 80 | BasicContainer(xybase::Stream *stream); 81 | 82 | virtual xybase::Stream *Open(std::u16string name, xybase::FileOpenMode mode) override; 83 | 84 | virtual std::list List() override; 85 | 86 | virtual void MakeDir(std::u16string path) override; 87 | 88 | virtual void Remove(std::u16string target, bool recursive = false) override; 89 | 90 | void Close(); 91 | 92 | private: 93 | std::map fdMap; 94 | 95 | // 通过 FileContainer 继承 96 | virtual std::u16string GetName() override; 97 | 98 | // 通过 FileContainer 继承 99 | virtual void Flush() override; 100 | }; 101 | } 102 | 103 | #endif // !ISO_CONTAINER_H__ 104 | -------------------------------------------------------------------------------- /bis/Data/Basic/Double.cpp: -------------------------------------------------------------------------------- 1 | #include "Double.h" 2 | 3 | using namespace mule::Data::Basic; 4 | 5 | mule::Data::Basic::Double::Double() { } 6 | 7 | size_t mule::Data::Basic::Double::Size() const 8 | { 9 | return sizeof(double); 10 | } 11 | 12 | std::u16string mule::Data::Basic::Double::GetDataType() const 13 | { 14 | return std::u16string(u"real-number/double"); 15 | } 16 | 17 | MultiValue mule::Data::Basic::Double::DoRead(xybase::Stream *stream) 18 | { 19 | return stream->ReadDouble(); 20 | } 21 | 22 | void mule::Data::Basic::Double::DoWrite(xybase::Stream *stream, const MultiValue &value) 23 | { 24 | if (!value.IsType(MultiValue::MVT_REAL)) throw xybase::InvalidParameterException(L"value", L"Type mismatch!", 19001); 25 | stream->Write((double)value.value.realValue); 26 | } 27 | -------------------------------------------------------------------------------- /bis/Data/Basic/Double.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef DOUBLE_FIELD_H__ 4 | #define DOUBLE_FILED_H__ 5 | 6 | #include 7 | 8 | namespace mule 9 | { 10 | namespace Data 11 | { 12 | namespace Basic 13 | { 14 | class Double : public BasicType 15 | { 16 | public: 17 | Double(); 18 | 19 | virtual size_t Size() const override; 20 | virtual std::u16string GetDataType() const override; 21 | protected: 22 | virtual MultiValue DoRead(xybase::Stream *stream) override; 23 | virtual void DoWrite(xybase::Stream *stream, const MultiValue &value) override; 24 | }; 25 | } 26 | } 27 | } 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /bis/Data/Basic/Dummy.cpp: -------------------------------------------------------------------------------- 1 | #include "Dummy.h" 2 | #include 3 | 4 | using namespace mule::Data::Basic; 5 | 6 | mule::Data::Basic::Dummy::Dummy(int size) 7 | { 8 | this->size = size; 9 | } 10 | 11 | size_t Dummy::Size() const 12 | { 13 | return size >> 3; 14 | } 15 | 16 | std::u16string mule::Data::Basic::Dummy::GetDataType() const 17 | { 18 | return std::u16string(u"dummy/") + u"bit" + xybase::string::to_utf16(std::to_string(size)); 19 | } 20 | 21 | MultiValue mule::Data::Basic::Dummy::DoRead(xybase::Stream *stream) 22 | { 23 | stream->Seek(size >> 3, xybase::Stream::SM_CURRENT); 24 | 25 | return { u"" }; 26 | } 27 | 28 | void mule::Data::Basic::Dummy::DoWrite(xybase::Stream *stream, const MultiValue &value) 29 | { 30 | stream->Seek(size >> 3, xybase::Stream::SM_CURRENT); 31 | } 32 | -------------------------------------------------------------------------------- /bis/Data/Basic/Dummy.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef DUMMY_FIELD_H__ 4 | #define DUMMY_FIELD_H__ 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | namespace mule 11 | { 12 | namespace Data 13 | { 14 | namespace Basic 15 | { 16 | 17 | class Dummy : public BasicType 18 | { 19 | int size; 20 | public: 21 | Dummy(int size); 22 | 23 | virtual size_t Size() const override; 24 | 25 | virtual std::u16string GetDataType() const override; 26 | protected: 27 | virtual MultiValue DoRead(xybase::Stream *stream) override; 28 | 29 | virtual void DoWrite(xybase::Stream *stream, const MultiValue &value) override; 30 | 31 | }; 32 | } 33 | } 34 | } 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /bis/Data/Basic/Enum.cpp: -------------------------------------------------------------------------------- 1 | #include "Enum.h" 2 | #include 3 | #include 4 | 5 | using namespace mule::Data::Basic; 6 | 7 | mule::Data::Basic::Enum::Enum(const std::u16string &name, const std::u16string &baseType) 8 | : name(name) 9 | { 10 | this->baseType = dynamic_cast(mule::Data::TypeManager::GetInstance().GetOrCreateType(baseType)); 11 | if (this->baseType == nullptr) 12 | throw xybase::InvalidParameterException(L"baseType", L"Invalid base type!", 499548); 13 | } 14 | 15 | void mule::Data::Basic::Enum::AddEnum(std::u16string name, MultiValue value) 16 | { 17 | mapS2V[name] = value; 18 | mapV2S[value] = name; 19 | } 20 | 21 | size_t mule::Data::Basic::Enum::Size() const 22 | { 23 | return baseType->Size(); 24 | } 25 | 26 | std::u16string mule::Data::Basic::Enum::GetDataType() const 27 | { 28 | return u"enum/" + name; 29 | } 30 | 31 | MultiValue mule::Data::Basic::Enum::DoRead(xybase::Stream *stream) 32 | { 33 | auto val = baseType->DoRead(stream); 34 | return mapV2S.contains(val) ? mapV2S[val] : val; 35 | } 36 | 37 | void mule::Data::Basic::Enum::DoWrite(xybase::Stream *stream, const MultiValue &value) 38 | { 39 | if (value.IsType(MultiValue::MVT_STRING)) 40 | { 41 | if (!mapS2V.contains(*value.value.stringValue)) 42 | throw xybase::InvalidOperationException( 43 | std::format(L"Unknown enum value {} for {}.", 44 | value.ToString(), xybase::string::to_wstring(name)), 499549); 45 | 46 | baseType->DoWrite(stream, mapS2V[*value.value.stringValue]); 47 | } 48 | else baseType->DoWrite(stream, value); 49 | } 50 | -------------------------------------------------------------------------------- /bis/Data/Basic/Enum.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | namespace mule 5 | { 6 | namespace Data 7 | { 8 | namespace Basic 9 | { 10 | class Enum : public BasicType 11 | { 12 | BasicType *baseType; 13 | std::u16string name; 14 | std::map mapS2V; 15 | std::map mapV2S; 16 | public: 17 | Enum(const std::u16string &name, const std::u16string &baseType = u"int32"); 18 | 19 | void AddEnum(std::u16string name, MultiValue value); 20 | 21 | size_t Size() const override; 22 | std::u16string GetDataType() const override; 23 | protected: 24 | MultiValue DoRead(xybase::Stream *stream) override; 25 | void DoWrite(xybase::Stream *stream, const MultiValue &value) override; 26 | }; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /bis/Data/Basic/Float.cpp: -------------------------------------------------------------------------------- 1 | #include "Float.h" 2 | 3 | using namespace mule::Data::Basic; 4 | 5 | mule::Data::Basic::Float::Float() { } 6 | 7 | 8 | std::u16string mule::Data::Basic::Float::GetDataType() const 9 | { 10 | return std::u16string(u"real-number/float"); 11 | } 12 | 13 | size_t mule::Data::Basic::Float::Size() const 14 | { 15 | return size_t(sizeof(float)); 16 | } 17 | 18 | MultiValue mule::Data::Basic::Float::DoRead(xybase::Stream *stream) 19 | { 20 | return stream->ReadFloat(); 21 | } 22 | 23 | void mule::Data::Basic::Float::DoWrite(xybase::Stream *stream, const MultiValue &value) 24 | { 25 | if (!value.IsType(MultiValue::MVT_REAL)) throw xybase::InvalidParameterException(L"value", L"Type mismatch!", 19002); 26 | stream->Write((float)(value.value.realValue)); 27 | } 28 | -------------------------------------------------------------------------------- /bis/Data/Basic/Float.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef FLOAT_FIELD_H__ 4 | #define FLOAT_FIELD_H__ 5 | 6 | #include 7 | 8 | namespace mule 9 | { 10 | namespace Data 11 | { 12 | namespace Basic 13 | { 14 | class Float : public BasicType 15 | { 16 | public: 17 | Float(); 18 | 19 | virtual size_t Size() const override; 20 | 21 | virtual std::u16string GetDataType() const override; 22 | 23 | 24 | protected: 25 | virtual MultiValue DoRead(xybase::Stream *stream) override; 26 | virtual void DoWrite(xybase::Stream *stream, const MultiValue &value) override; 27 | 28 | }; 29 | } 30 | } 31 | } 32 | 33 | #endif -------------------------------------------------------------------------------- /bis/Data/Basic/Integer.cpp: -------------------------------------------------------------------------------- 1 | #include "Integer.h" 2 | #include 3 | 4 | using namespace mule::Data::Basic; 5 | 6 | mule::Data::Basic::Integer::Integer(int size, bool isUnsigned) 7 | { 8 | this->size = size; 9 | this->isUnsigned = isUnsigned; 10 | } 11 | 12 | size_t Integer::Size() const 13 | { 14 | return size >> 3; 15 | } 16 | 17 | std::u16string mule::Data::Basic::Integer::GetDataType() const 18 | { 19 | return std::u16string(u"integer/") + (isUnsigned ? u"uint" : u"int") + xybase::string::to_utf16(std::to_string(size)); 20 | } 21 | 22 | MultiValue mule::Data::Basic::Integer::DoRead(xybase::Stream *stream) 23 | { 24 | MultiValue value{ }; 25 | switch (size >> 3) 26 | { 27 | case 1: 28 | value.value.unsignedValue = stream->ReadUInt8(); 29 | break; 30 | case 2: 31 | value.value.unsignedValue = stream->ReadUInt16(); 32 | break; 33 | case 4: 34 | value.value.unsignedValue = stream->ReadUInt32(); 35 | break; 36 | case 8: 37 | value.value.unsignedValue = stream->ReadUInt64(); 38 | break; 39 | } 40 | 41 | if (!isUnsigned && value.value.unsignedValue & (1ULL << (size - 1))) 42 | { 43 | uint64_t leading = 0xFFFFFFFFFFFFFFFFULL; 44 | leading <<= size; 45 | value.value.unsignedValue |= leading; 46 | } 47 | 48 | value.type = isUnsigned ? MultiValue::MVT_UINT : MultiValue::MVT_INT; 49 | 50 | return value; 51 | } 52 | 53 | void mule::Data::Basic::Integer::DoWrite(xybase::Stream *stream, const MultiValue &value) 54 | { 55 | if (!value.IsType(MultiValue::MVT_INT) && !value.IsType(MultiValue::MVT_UINT)) throw xybase::InvalidParameterException(L"value", L"Type mismatch!", 19003); 56 | switch (size >> 3) 57 | { 58 | case 1: 59 | stream->Write((uint8_t)(value.value.unsignedValue & 0xFF)); 60 | break; 61 | case 2: 62 | stream->Write((uint16_t)(value.value.unsignedValue & 0xFFFF)); 63 | break; 64 | case 4: 65 | stream->Write((uint32_t)(value.value.unsignedValue & 0xFFFFFFFF)); 66 | break; 67 | case 8: 68 | stream->Write((uint64_t)(value.value.unsignedValue)); 69 | break; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /bis/Data/Basic/Integer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef INTEGER_FIELD_H__ 4 | #define INTEGER_FIELD_H__ 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | namespace mule 11 | { 12 | namespace Data 13 | { 14 | namespace Basic 15 | { 16 | 17 | class Integer : public BasicType 18 | { 19 | int size; 20 | bool isUnsigned; 21 | public: 22 | Integer(int size, bool isUnsigned); 23 | 24 | virtual size_t Size() const override; 25 | 26 | virtual std::u16string GetDataType() const override; 27 | protected: 28 | virtual MultiValue DoRead(xybase::Stream *stream) override; 29 | 30 | virtual void DoWrite(xybase::Stream *stream, const MultiValue &value) override; 31 | 32 | }; 33 | } 34 | } 35 | } 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /bis/Data/Basic/String.cpp: -------------------------------------------------------------------------------- 1 | #include "String.h" 2 | 3 | #include 4 | #include 5 | 6 | using namespace mule::Data::Basic; 7 | 8 | size_t String::Size() const 9 | { 10 | return size_t(-1); 11 | } 12 | 13 | std::u16string mule::Data::Basic::String::GetDataType() const 14 | { 15 | return u"string/text"; 16 | } 17 | 18 | size_t mule::Data::Basic::String::GetLastSize() const 19 | { 20 | return lastSize + 1; 21 | } 22 | 23 | size_t mule::Data::Basic::String::EvalSize(const MultiValue &obj) const 24 | { 25 | if (obj.type != MultiValue::MVT_STRING) 26 | return 0; 27 | auto data = xybase::string::to_string(*(obj.value.stringValue)); 28 | return data.size() + 1; 29 | } 30 | 31 | MultiValue mule::Data::Basic::String::DoRead(xybase::Stream *stream) 32 | { 33 | auto rawString = stream->ReadString(); 34 | MultiValue tmp(xybase::string::to_utf16(rawString)); 35 | lastSize = rawString.size(); 36 | tmp.metadata[u"size"] = lastSize; 37 | return tmp; 38 | } 39 | 40 | void mule::Data::Basic::String::DoWrite(xybase::Stream *stream, const MultiValue &value) 41 | { 42 | if (!value.IsType(MultiValue::MVT_STRING)) throw xybase::InvalidParameterException(L"value", L"Type mismatch!", 19004); 43 | 44 | auto data = xybase::string::to_string(*(value.value.stringValue)); 45 | 46 | auto &&itr = value.metadata.find(u"size"); 47 | if (itr != value.metadata.end()) 48 | { 49 | if (data.size() > itr->second.value.unsignedValue) 50 | throw xybase::InvalidParameterException( 51 | L"value", 52 | std::format( 53 | L"Too large (size {} exceeded {}), string={}", 54 | data.size(), 55 | itr->second.value.unsignedValue, 56 | xybase::string::to_wstring(*value.value.stringValue)), 57 | 19010); 58 | } 59 | 60 | if (value.value.stringValue->size() && data.size() == 0) 61 | { 62 | logger.Warn(L"Failed to encode string."); 63 | logger.Note(L"String={}", xybase::string::to_wstring(*value.value.stringValue)); 64 | } 65 | 66 | stream->Write(data); 67 | lastSize = data.size(); 68 | } 69 | -------------------------------------------------------------------------------- /bis/Data/Basic/String.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef STRING_OBJECT_H__ 4 | #define STRING_OBJECT_H__ 5 | 6 | #include 7 | #include 8 | 9 | namespace mule 10 | { 11 | namespace Data 12 | { 13 | namespace Basic 14 | { 15 | 16 | /** 17 | * @brief String is not a typical object cause it holds a variable length. 18 | */ 19 | class String : public BasicType 20 | { 21 | Logger logger = Logger::GetLogger(); 22 | protected: 23 | size_t lastSize = -1; 24 | public: 25 | virtual size_t Size() const override; 26 | virtual std::u16string GetDataType() const override; 27 | 28 | virtual size_t GetLastSize() const override; 29 | virtual size_t EvalSize(const MultiValue &obj) const override; 30 | protected: 31 | virtual MultiValue DoRead(xybase::Stream *stream) override; 32 | virtual void DoWrite(xybase::Stream *stream, const MultiValue &value) override; 33 | }; 34 | } 35 | } 36 | } 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /bis/Data/BasicTypeCreator.cpp: -------------------------------------------------------------------------------- 1 | #include "BasicTypeCreator.h" 2 | #include "Basic/Integer.h" 3 | #include "Basic/Dummy.h" 4 | #include "Basic/Double.h" 5 | #include "Basic/Float.h" 6 | #include "Basic/String.h" 7 | #include "Basic/UString.h" 8 | 9 | #include 10 | 11 | using namespace mule::Data::Basic; 12 | 13 | Type *mule::Data::BasicTypeCreator::DoCreateObject(const std::u16string &info) 14 | { 15 | return DoCreateObject(info, {}); 16 | } 17 | 18 | Type *mule::Data::BasicTypeCreator::DoCreateObject(const std::u16string &info, const std::map &metainfo) 19 | { 20 | BasicType *ret = nullptr; 21 | if (info.starts_with(u"int")) 22 | { 23 | int size = (int)xybase::string::stoi(info.substr(3)); 24 | if (size != 8 && size != 16 && size != 32 && size != 64) 25 | { 26 | return nullptr; 27 | } 28 | 29 | ret = new Integer(size, false); 30 | } 31 | else if (info.starts_with(u"dum")) 32 | { 33 | int size = (int)xybase::string::stoi(info.substr(3)); 34 | if (size != 8 && size != 16 && size != 32 && size != 64) 35 | { 36 | return nullptr; 37 | } 38 | 39 | ret = new Dummy(size); 40 | } 41 | else if (info.starts_with(u"uint")) 42 | { 43 | int size = (int)xybase::string::stoi(info.substr(4)); 44 | if (size != 8 && size != 16 && size != 32 && size != 64) 45 | { 46 | return nullptr; 47 | } 48 | 49 | ret = new Integer(size, true); 50 | } 51 | else if (info == u"float") 52 | { 53 | ret = new Float(); 54 | } 55 | else if (info == u"double") 56 | { 57 | ret = new Double(); 58 | } 59 | else if (info == u"string") 60 | { 61 | ret = new String(); 62 | } 63 | else if (info == u"u8string") 64 | { 65 | ret = new UString(); 66 | } 67 | else if (info == u"u16string") 68 | { 69 | ret = new UString(); 70 | } 71 | else if (info == u"u32string") 72 | { 73 | ret = new UString(); 74 | } 75 | else 76 | return ret; 77 | 78 | auto &&itr = metainfo.find(u"cache"); 79 | if (itr != metainfo.end()) 80 | { 81 | ret->cacheVariableName = itr->second; 82 | } 83 | 84 | itr = metainfo.find(u"constraint"); 85 | if (itr != metainfo.end()) 86 | { 87 | auto &&cons = itr->second; 88 | auto condition = cons.substr(0, cons.find(':')); 89 | ret->comparator = MultiValue::Parse(cons.substr(cons.find(':') + 1)); 90 | if (condition == u"lt") ret->constraintType = BasicType::BTCT_LT; 91 | if (condition == u"nlt") ret->constraintType = BasicType::BTCT_NLT; 92 | if (condition == u"gt") ret->constraintType = BasicType::BTCT_GT; 93 | if (condition == u"ngt") ret->constraintType = BasicType::BTCT_NGT; 94 | if (condition == u"eq") ret->constraintType = BasicType::BTCT_EQ; 95 | if (condition == u"neq") ret->constraintType = BasicType::BTCT_NEQ; 96 | } 97 | 98 | return ret; 99 | } 100 | -------------------------------------------------------------------------------- /bis/Data/BasicTypeCreator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include 6 | 7 | namespace mule 8 | { 9 | namespace Data 10 | { 11 | 12 | /** 13 | * @brief 基本字段创建器,用于创建整形、浮点型等基础读写器。 14 | */ 15 | class BasicTypeCreator : public TypeCreator 16 | { 17 | virtual Basic::Type *DoCreateObject(const std::u16string &info) override; 18 | 19 | virtual Basic::Type *DoCreateObject(const std::u16string &info, const std::map &metainfo); 20 | }; 21 | } 22 | } -------------------------------------------------------------------------------- /bis/Data/Storage/BinaryBlock.cpp: -------------------------------------------------------------------------------- 1 | #include "BinaryBlock.h" 2 | 3 | #include 4 | #include 5 | 6 | using namespace mule::Data::Basic; 7 | using namespace mule::Data::Storage; 8 | using namespace mule::Storage; 9 | 10 | mule::Data::Storage::BinaryBlock::BinaryBlock(size_t size) 11 | : size(size) 12 | { 13 | } 14 | 15 | void BinaryBlock::Read(xybase::Stream *stream, DataHandler *dataHandler) 16 | { 17 | char *buffer = new char[size]; 18 | stream->ReadBytes(buffer, size); 19 | 20 | // 生成 link 21 | MultiValue mv = DataManager::GetInstance().SaveData(BinaryData{buffer, size, false}); 22 | dataHandler->OnDataRead(mv); 23 | } 24 | 25 | void BinaryBlock::Write(xybase::Stream *stream, FileHandler * fileHandler) 26 | { 27 | MultiValue mv = fileHandler->OnDataWrite(); 28 | if (!mv.IsType(MultiValue::MVT_UINT)) 29 | { 30 | stream->Seek(size, xybase::Stream::SM_CURRENT); 31 | return; 32 | } 33 | 34 | // 获取 link 的数据 35 | stream->Write(DataManager::GetInstance().LoadData((unsigned int)mv.value.unsignedValue).GetData(), size); 36 | } 37 | 38 | size_t BinaryBlock::Size() const 39 | { 40 | return size; 41 | } 42 | 43 | std::u16string BinaryBlock::GetDataType() const 44 | { 45 | return u"bin{" + xybase::string::itos(size) + u"}"; 46 | } 47 | 48 | mule::Data::Basic::Type *BinaryBlock::BinaryBlockCreator::DoCreateObject(const std::u16string &info) 49 | { 50 | if (!info.starts_with(u"bin{")) 51 | { 52 | return nullptr; 53 | } 54 | 55 | size_t loc = info.find_first_of(u"}"); 56 | 57 | if (loc == std::u16string::npos) return nullptr; 58 | 59 | size_t size = xybase::string::stoi(info.substr(4, loc - 4)); 60 | if (size == 0) return nullptr; 61 | 62 | auto ret = new BinaryBlock{size}; 63 | return ret; 64 | } 65 | -------------------------------------------------------------------------------- /bis/Data/Storage/BinaryBlock.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef BINARY_BLOCK_H__ 4 | #define BINARY_BLOCK_H__ 5 | 6 | #include 7 | #include 8 | 9 | namespace mule 10 | { 11 | namespace Data 12 | { 13 | namespace Storage 14 | { 15 | class BinaryBlock : public mule::Data::Basic::Type 16 | { 17 | BinaryBlock(size_t size); 18 | public: 19 | class BinaryBlockCreator : public mule::Data::TypeCreator 20 | { 21 | public: 22 | 23 | virtual mule::Data::Basic::Type *DoCreateObject(const std::u16string &info) override; 24 | }; 25 | virtual void Read(xybase::Stream *stream, DataHandler *dataHandler) override; 26 | virtual void Write(xybase::Stream *stream, FileHandler *fileHandler) override; 27 | virtual size_t Size() const override; 28 | virtual std::u16string GetDataType() const override; 29 | protected: 30 | size_t size; 31 | }; 32 | } 33 | } 34 | } 35 | 36 | #endif // !BINARY_BLOCK_H__ 37 | -------------------------------------------------------------------------------- /bis/Data/VarChar.cpp: -------------------------------------------------------------------------------- 1 | #include "VarChar.h" 2 | 3 | #include "../xybase/xystring.h" 4 | 5 | using namespace mule::Data::Basic; 6 | 7 | mule::Data::VarChar::VarChar(size_t length) 8 | : length(length) 9 | { 10 | buffer = new char[length]; 11 | } 12 | 13 | mule::Data::VarChar::~VarChar() 14 | { 15 | delete[] buffer; 16 | } 17 | 18 | size_t mule::Data::VarChar::Size() const 19 | { 20 | return length; 21 | } 22 | 23 | std::u16string mule::Data::VarChar::GetDataType() const 24 | { 25 | return u"string/text"; 26 | } 27 | 28 | MultiValue mule::Data::VarChar::DoRead(xybase::Stream *stream) 29 | { 30 | stream->ReadBytes(buffer, length); 31 | return xybase::string::to_utf16(buffer); 32 | } 33 | 34 | void mule::Data::VarChar::DoWrite(xybase::Stream *stream, const MultiValue &value) 35 | { 36 | if (value.GetType() != Basic::MultiValue::MVT_STRING) 37 | { 38 | stream->Seek(Size(), xybase::Stream::SM_CURRENT); 39 | return; 40 | } 41 | auto &&str = *value.value.stringValue; 42 | if (str.size() < length - 1) 43 | { 44 | memset(buffer, 0, length); 45 | strcpy(buffer, xybase::string::to_string(str).c_str()); 46 | stream->Write(buffer, length); 47 | } 48 | else 49 | { 50 | stream->Write(xybase::string::to_string(str.substr(0, length - 1))); 51 | } 52 | } 53 | 54 | mule::Data::Basic::Type *mule::Data::VarChar::VarCharCreator::DoCreateObject(const std::u16string &info) 55 | { 56 | if (!info.starts_with(u"varchar(") || !info.ends_with(u')')) 57 | { 58 | return nullptr; 59 | } 60 | size_t endIndex = info.find_first_of(u")"); 61 | if (endIndex == std::string::npos) 62 | { 63 | return nullptr; 64 | } 65 | unsigned long long length = xybase::string::stoi(info.substr(8, endIndex - 8)); 66 | VarChar *ret = new VarChar(length); 67 | 68 | return ret; 69 | } 70 | -------------------------------------------------------------------------------- /bis/Data/VarChar.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #ifndef VAR_CHAR_H__ 3 | #define VAR_CHAR_H__ 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | namespace mule 10 | { 11 | namespace Data 12 | { 13 | class VarChar : Basic::BasicType 14 | { 15 | protected: 16 | size_t length; 17 | 18 | VarChar(size_t length); 19 | 20 | char *buffer; 21 | public: 22 | ~VarChar(); 23 | 24 | class VarCharCreator : public TypeCreator 25 | { 26 | public: 27 | 28 | virtual Basic::Type *DoCreateObject(const std::u16string &info) override; 29 | }; 30 | 31 | virtual size_t Size() const override; 32 | virtual std::u16string GetDataType() const override; 33 | 34 | virtual mule::Data::Basic::MultiValue DoRead(xybase::Stream *stream) override; 35 | virtual void DoWrite(xybase::Stream *stream, const mule::Data::Basic::MultiValue &value) override; 36 | }; 37 | } 38 | } 39 | 40 | #endif // !VAR_CHAR_H__ 41 | -------------------------------------------------------------------------------- /docs/bis/Container.md: -------------------------------------------------------------------------------- 1 | # Container 2 | Container 中存放文件容器。是提供Stream*的容器。虚拟文件系统。 3 | 4 | 其对输入的流进行解释,从而将输入的流作为文件系统来操作。 5 | BasicContainer简单实现了保存不同的打开流的位置,并在读写时,将其转换为对其解释的流的操作。如果其保持的流的位置和需要的位置不同,则会对被翻译的流进行寻址。 6 | ~~注意由于懒寻址的存在,不能同时将其用于读写(这是严重问题,将在未来修复)。~~ 现在已经增加读写判断,现在同时读写理应正常处理。 7 | 8 | ## IsoContainer 9 | 处理ISO流的文件容器。首次附加到流时,将流视作ISO9660的文件镜像,并解析其目录结构。不实现ChangeDir、Remove和MakeDir。只能打开已经存在的文件。尝试打开新文件将出错。 10 | 11 | 在关闭时,不将对文件系统的改动回写,这意味着若文件大小变动则导致不可预料的后果,请注意。(未来将修复这个问题,并正确地实现Open)。 12 | -------------------------------------------------------------------------------- /docs/mulert/mulert.md: -------------------------------------------------------------------------------- 1 | # MULE 运行时 2 | 3 | ## Mule.cpp/.h 4 | 5 | 是mule的主要文件。插件管理等功能通过此文件支持。未确定功能的部分也实现在这里。 6 | 7 | ## SheetManager.cpp/.h 8 | 9 | 表格管理器。通过在此处注册表(mule::Data::Sheet),可以对特定流(xybase::Stream)下所属的表进行管理。 10 | -------------------------------------------------------------------------------- /lib/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | set(LUA_VERSION 5.4.4) 3 | 4 | add_library(lua "lua/lapi.c" "lua/lcode.c" "lua/lctype.c" "lua/ldebug.c" "lua/ldo.c" "lua/ldump.c" "lua/lfunc.c" "lua/lgc.c" "lua/llex.c" "lua/lmem.c" "lua/lobject.c" "lua/lopcodes.c" "lua/lparser.c" "lua/lstate.c" "lua/lstring.c" "lua/ltable.c" "lua/ltm.c" "lua/lundump.c" "lua/lvm.c" "lua/lzio.c" "lua/lauxlib.c" "lua/lbaselib.c" "lua/lcorolib.c" "lua/ldblib.c" "lua/liolib.c" "lua/lmathlib.c" "lua/loadlib.c" "lua/loslib.c" "lua/lstrlib.c" "lua/ltablib.c" "lua/lutf8lib.c" "lua/linit.c") 5 | target_include_directories (lua INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/include/lua") 6 | 7 | add_subdirectory("xybase") 8 | 9 | if (CMAKE_VERSION VERSION_GREATER 3.12) 10 | set_property(TARGET lua PROPERTY CXX_STANDARD 20) 11 | endif() -------------------------------------------------------------------------------- /lib/include/lua/lua.hpp: -------------------------------------------------------------------------------- 1 | // lua.hpp 2 | // Lua header files for C++ 3 | // <> not supplied automatically because Lua also compiles as C++ 4 | 5 | extern "C" { 6 | #include "lua.h" 7 | #include "lualib.h" 8 | #include "lauxlib.h" 9 | } 10 | -------------------------------------------------------------------------------- /lib/include/lua/lualib.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lualib.h $ 3 | ** Lua standard libraries 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #ifndef lualib_h 9 | #define lualib_h 10 | 11 | #include "lua.h" 12 | 13 | 14 | /* version suffix for environment variable names */ 15 | #define LUA_VERSUFFIX "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR 16 | 17 | 18 | LUAMOD_API int (luaopen_base) (lua_State *L); 19 | 20 | #define LUA_COLIBNAME "coroutine" 21 | LUAMOD_API int (luaopen_coroutine) (lua_State *L); 22 | 23 | #define LUA_TABLIBNAME "table" 24 | LUAMOD_API int (luaopen_table) (lua_State *L); 25 | 26 | #define LUA_IOLIBNAME "io" 27 | LUAMOD_API int (luaopen_io) (lua_State *L); 28 | 29 | #define LUA_OSLIBNAME "os" 30 | LUAMOD_API int (luaopen_os) (lua_State *L); 31 | 32 | #define LUA_STRLIBNAME "string" 33 | LUAMOD_API int (luaopen_string) (lua_State *L); 34 | 35 | #define LUA_UTF8LIBNAME "utf8" 36 | LUAMOD_API int (luaopen_utf8) (lua_State *L); 37 | 38 | #define LUA_MATHLIBNAME "math" 39 | LUAMOD_API int (luaopen_math) (lua_State *L); 40 | 41 | #define LUA_DBLIBNAME "debug" 42 | LUAMOD_API int (luaopen_debug) (lua_State *L); 43 | 44 | #define LUA_LOADLIBNAME "package" 45 | LUAMOD_API int (luaopen_package) (lua_State *L); 46 | 47 | 48 | /* open all previous libraries */ 49 | LUALIB_API void (luaL_openlibs) (lua_State *L); 50 | 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /lib/lua/lapi.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lapi.h $ 3 | ** Auxiliary functions from Lua API 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lapi_h 8 | #define lapi_h 9 | 10 | 11 | #include "llimits.h" 12 | #include "lstate.h" 13 | 14 | 15 | /* Increments 'L->top', checking for stack overflows */ 16 | #define api_incr_top(L) {L->top++; api_check(L, L->top <= L->ci->top, \ 17 | "stack overflow");} 18 | 19 | 20 | /* 21 | ** If a call returns too many multiple returns, the callee may not have 22 | ** stack space to accommodate all results. In this case, this macro 23 | ** increases its stack space ('L->ci->top'). 24 | */ 25 | #define adjustresults(L,nres) \ 26 | { if ((nres) <= LUA_MULTRET && L->ci->top < L->top) L->ci->top = L->top; } 27 | 28 | 29 | /* Ensure the stack has at least 'n' elements */ 30 | #define api_checknelems(L,n) api_check(L, (n) < (L->top - L->ci->func), \ 31 | "not enough elements in the stack") 32 | 33 | 34 | /* 35 | ** To reduce the overhead of returning from C functions, the presence of 36 | ** to-be-closed variables in these functions is coded in the CallInfo's 37 | ** field 'nresults', in a way that functions with no to-be-closed variables 38 | ** with zero, one, or "all" wanted results have no overhead. Functions 39 | ** with other number of wanted results, as well as functions with 40 | ** variables to be closed, have an extra check. 41 | */ 42 | 43 | #define hastocloseCfunc(n) ((n) < LUA_MULTRET) 44 | 45 | /* Map [-1, inf) (range of 'nresults') into (-inf, -2] */ 46 | #define codeNresults(n) (-(n) - 3) 47 | #define decodeNresults(n) (-(n) - 3) 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /lib/lua/lctype.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lctype.c $ 3 | ** 'ctype' functions for Lua 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lctype_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include "lctype.h" 14 | 15 | #if !LUA_USE_CTYPE /* { */ 16 | 17 | #include 18 | 19 | 20 | #if defined (LUA_UCID) /* accept UniCode IDentifiers? */ 21 | /* consider all non-ascii codepoints to be alphabetic */ 22 | #define NONA 0x01 23 | #else 24 | #define NONA 0x00 /* default */ 25 | #endif 26 | 27 | 28 | LUAI_DDEF const lu_byte luai_ctype_[UCHAR_MAX + 2] = { 29 | 0x00, /* EOZ */ 30 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0. */ 31 | 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 32 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 1. */ 33 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 34 | 0x0c, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* 2. */ 35 | 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 36 | 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, /* 3. */ 37 | 0x16, 0x16, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 38 | 0x04, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x05, /* 4. */ 39 | 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 40 | 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* 5. */ 41 | 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x05, 42 | 0x04, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x05, /* 6. */ 43 | 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 44 | 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* 7. */ 45 | 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x00, 46 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, /* 8. */ 47 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, 48 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, /* 9. */ 49 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, 50 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, /* a. */ 51 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, 52 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, /* b. */ 53 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, 54 | 0x00, 0x00, NONA, NONA, NONA, NONA, NONA, NONA, /* c. */ 55 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, 56 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, /* d. */ 57 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, 58 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, /* e. */ 59 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, 60 | NONA, NONA, NONA, NONA, NONA, 0x00, 0x00, 0x00, /* f. */ 61 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 62 | }; 63 | 64 | #endif /* } */ 65 | -------------------------------------------------------------------------------- /lib/lua/lctype.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lctype.h $ 3 | ** 'ctype' functions for Lua 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lctype_h 8 | #define lctype_h 9 | 10 | #include "lua.h" 11 | 12 | 13 | /* 14 | ** WARNING: the functions defined here do not necessarily correspond 15 | ** to the similar functions in the standard C ctype.h. They are 16 | ** optimized for the specific needs of Lua. 17 | */ 18 | 19 | #if !defined(LUA_USE_CTYPE) 20 | 21 | #if 'A' == 65 && '0' == 48 22 | /* ASCII case: can use its own tables; faster and fixed */ 23 | #define LUA_USE_CTYPE 0 24 | #else 25 | /* must use standard C ctype */ 26 | #define LUA_USE_CTYPE 1 27 | #endif 28 | 29 | #endif 30 | 31 | 32 | #if !LUA_USE_CTYPE /* { */ 33 | 34 | #include 35 | 36 | #include "llimits.h" 37 | 38 | 39 | #define ALPHABIT 0 40 | #define DIGITBIT 1 41 | #define PRINTBIT 2 42 | #define SPACEBIT 3 43 | #define XDIGITBIT 4 44 | 45 | 46 | #define MASK(B) (1 << (B)) 47 | 48 | 49 | /* 50 | ** add 1 to char to allow index -1 (EOZ) 51 | */ 52 | #define testprop(c,p) (luai_ctype_[(c)+1] & (p)) 53 | 54 | /* 55 | ** 'lalpha' (Lua alphabetic) and 'lalnum' (Lua alphanumeric) both include '_' 56 | */ 57 | #define lislalpha(c) testprop(c, MASK(ALPHABIT)) 58 | #define lislalnum(c) testprop(c, (MASK(ALPHABIT) | MASK(DIGITBIT))) 59 | #define lisdigit(c) testprop(c, MASK(DIGITBIT)) 60 | #define lisspace(c) testprop(c, MASK(SPACEBIT)) 61 | #define lisprint(c) testprop(c, MASK(PRINTBIT)) 62 | #define lisxdigit(c) testprop(c, MASK(XDIGITBIT)) 63 | 64 | 65 | /* 66 | ** In ASCII, this 'ltolower' is correct for alphabetic characters and 67 | ** for '.'. That is enough for Lua needs. ('check_exp' ensures that 68 | ** the character either is an upper-case letter or is unchanged by 69 | ** the transformation, which holds for lower-case letters and '.'.) 70 | */ 71 | #define ltolower(c) \ 72 | check_exp(('A' <= (c) && (c) <= 'Z') || (c) == ((c) | ('A' ^ 'a')), \ 73 | (c) | ('A' ^ 'a')) 74 | 75 | 76 | /* one entry for each character and for -1 (EOZ) */ 77 | LUAI_DDEC(const lu_byte luai_ctype_[UCHAR_MAX + 2];) 78 | 79 | 80 | #else /* }{ */ 81 | 82 | /* 83 | ** use standard C ctypes 84 | */ 85 | 86 | #include 87 | 88 | 89 | #define lislalpha(c) (isalpha(c) || (c) == '_') 90 | #define lislalnum(c) (isalnum(c) || (c) == '_') 91 | #define lisdigit(c) (isdigit(c)) 92 | #define lisspace(c) (isspace(c)) 93 | #define lisprint(c) (isprint(c)) 94 | #define lisxdigit(c) (isxdigit(c)) 95 | 96 | #define ltolower(c) (tolower(c)) 97 | 98 | #endif /* } */ 99 | 100 | #endif 101 | 102 | -------------------------------------------------------------------------------- /lib/lua/ldebug.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ldebug.h $ 3 | ** Auxiliary functions from Debug Interface module 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef ldebug_h 8 | #define ldebug_h 9 | 10 | 11 | #include "lstate.h" 12 | 13 | 14 | #define pcRel(pc, p) (cast_int((pc) - (p)->code) - 1) 15 | 16 | 17 | /* Active Lua function (given call info) */ 18 | #define ci_func(ci) (clLvalue(s2v((ci)->func))) 19 | 20 | 21 | #define resethookcount(L) (L->hookcount = L->basehookcount) 22 | 23 | /* 24 | ** mark for entries in 'lineinfo' array that has absolute information in 25 | ** 'abslineinfo' array 26 | */ 27 | #define ABSLINEINFO (-0x80) 28 | 29 | 30 | /* 31 | ** MAXimum number of successive Instructions WiTHout ABSolute line 32 | ** information. (A power of two allows fast divisions.) 33 | */ 34 | #if !defined(MAXIWTHABS) 35 | #define MAXIWTHABS 128 36 | #endif 37 | 38 | 39 | LUAI_FUNC int luaG_getfuncline (const Proto *f, int pc); 40 | LUAI_FUNC const char *luaG_findlocal (lua_State *L, CallInfo *ci, int n, 41 | StkId *pos); 42 | LUAI_FUNC l_noret luaG_typeerror (lua_State *L, const TValue *o, 43 | const char *opname); 44 | LUAI_FUNC l_noret luaG_callerror (lua_State *L, const TValue *o); 45 | LUAI_FUNC l_noret luaG_forerror (lua_State *L, const TValue *o, 46 | const char *what); 47 | LUAI_FUNC l_noret luaG_concaterror (lua_State *L, const TValue *p1, 48 | const TValue *p2); 49 | LUAI_FUNC l_noret luaG_opinterror (lua_State *L, const TValue *p1, 50 | const TValue *p2, 51 | const char *msg); 52 | LUAI_FUNC l_noret luaG_tointerror (lua_State *L, const TValue *p1, 53 | const TValue *p2); 54 | LUAI_FUNC l_noret luaG_ordererror (lua_State *L, const TValue *p1, 55 | const TValue *p2); 56 | LUAI_FUNC l_noret luaG_runerror (lua_State *L, const char *fmt, ...); 57 | LUAI_FUNC const char *luaG_addinfo (lua_State *L, const char *msg, 58 | TString *src, int line); 59 | LUAI_FUNC l_noret luaG_errormsg (lua_State *L); 60 | LUAI_FUNC int luaG_traceexec (lua_State *L, const Instruction *pc); 61 | 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /lib/lua/ldo.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ldo.h $ 3 | ** Stack and Call structure of Lua 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef ldo_h 8 | #define ldo_h 9 | 10 | 11 | #include "lobject.h" 12 | #include "lstate.h" 13 | #include "lzio.h" 14 | 15 | 16 | /* 17 | ** Macro to check stack size and grow stack if needed. Parameters 18 | ** 'pre'/'pos' allow the macro to preserve a pointer into the 19 | ** stack across reallocations, doing the work only when needed. 20 | ** It also allows the running of one GC step when the stack is 21 | ** reallocated. 22 | ** 'condmovestack' is used in heavy tests to force a stack reallocation 23 | ** at every check. 24 | */ 25 | #define luaD_checkstackaux(L,n,pre,pos) \ 26 | if (l_unlikely(L->stack_last - L->top <= (n))) \ 27 | { pre; luaD_growstack(L, n, 1); pos; } \ 28 | else { condmovestack(L,pre,pos); } 29 | 30 | /* In general, 'pre'/'pos' are empty (nothing to save) */ 31 | #define luaD_checkstack(L,n) luaD_checkstackaux(L,n,(void)0,(void)0) 32 | 33 | 34 | 35 | #define savestack(L,p) ((char *)(p) - (char *)L->stack) 36 | #define restorestack(L,n) ((StkId)((char *)L->stack + (n))) 37 | 38 | 39 | /* macro to check stack size, preserving 'p' */ 40 | #define checkstackGCp(L,n,p) \ 41 | luaD_checkstackaux(L, n, \ 42 | ptrdiff_t t__ = savestack(L, p); /* save 'p' */ \ 43 | luaC_checkGC(L), /* stack grow uses memory */ \ 44 | p = restorestack(L, t__)) /* 'pos' part: restore 'p' */ 45 | 46 | 47 | /* macro to check stack size and GC */ 48 | #define checkstackGC(L,fsize) \ 49 | luaD_checkstackaux(L, (fsize), luaC_checkGC(L), (void)0) 50 | 51 | 52 | /* type of protected functions, to be ran by 'runprotected' */ 53 | typedef void (*Pfunc) (lua_State *L, void *ud); 54 | 55 | LUAI_FUNC void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop); 56 | LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name, 57 | const char *mode); 58 | LUAI_FUNC void luaD_hook (lua_State *L, int event, int line, 59 | int fTransfer, int nTransfer); 60 | LUAI_FUNC void luaD_hookcall (lua_State *L, CallInfo *ci); 61 | LUAI_FUNC int luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, int narg1, int delta); 62 | LUAI_FUNC CallInfo *luaD_precall (lua_State *L, StkId func, int nResults); 63 | LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults); 64 | LUAI_FUNC void luaD_callnoyield (lua_State *L, StkId func, int nResults); 65 | LUAI_FUNC StkId luaD_tryfuncTM (lua_State *L, StkId func); 66 | LUAI_FUNC int luaD_closeprotected (lua_State *L, ptrdiff_t level, int status); 67 | LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u, 68 | ptrdiff_t oldtop, ptrdiff_t ef); 69 | LUAI_FUNC void luaD_poscall (lua_State *L, CallInfo *ci, int nres); 70 | LUAI_FUNC int luaD_reallocstack (lua_State *L, int newsize, int raiseerror); 71 | LUAI_FUNC int luaD_growstack (lua_State *L, int n, int raiseerror); 72 | LUAI_FUNC void luaD_shrinkstack (lua_State *L); 73 | LUAI_FUNC void luaD_inctop (lua_State *L); 74 | 75 | LUAI_FUNC l_noret luaD_throw (lua_State *L, int errcode); 76 | LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud); 77 | 78 | #endif 79 | 80 | -------------------------------------------------------------------------------- /lib/lua/lfunc.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lfunc.h $ 3 | ** Auxiliary functions to manipulate prototypes and closures 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lfunc_h 8 | #define lfunc_h 9 | 10 | 11 | #include "lobject.h" 12 | 13 | 14 | #define sizeCclosure(n) (cast_int(offsetof(CClosure, upvalue)) + \ 15 | cast_int(sizeof(TValue)) * (n)) 16 | 17 | #define sizeLclosure(n) (cast_int(offsetof(LClosure, upvals)) + \ 18 | cast_int(sizeof(TValue *)) * (n)) 19 | 20 | 21 | /* test whether thread is in 'twups' list */ 22 | #define isintwups(L) (L->twups != L) 23 | 24 | 25 | /* 26 | ** maximum number of upvalues in a closure (both C and Lua). (Value 27 | ** must fit in a VM register.) 28 | */ 29 | #define MAXUPVAL 255 30 | 31 | 32 | #define upisopen(up) ((up)->v != &(up)->u.value) 33 | 34 | 35 | #define uplevel(up) check_exp(upisopen(up), cast(StkId, (up)->v)) 36 | 37 | 38 | /* 39 | ** maximum number of misses before giving up the cache of closures 40 | ** in prototypes 41 | */ 42 | #define MAXMISS 10 43 | 44 | 45 | 46 | /* special status to close upvalues preserving the top of the stack */ 47 | #define CLOSEKTOP (-1) 48 | 49 | 50 | LUAI_FUNC Proto *luaF_newproto (lua_State *L); 51 | LUAI_FUNC CClosure *luaF_newCclosure (lua_State *L, int nupvals); 52 | LUAI_FUNC LClosure *luaF_newLclosure (lua_State *L, int nupvals); 53 | LUAI_FUNC void luaF_initupvals (lua_State *L, LClosure *cl); 54 | LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level); 55 | LUAI_FUNC void luaF_newtbcupval (lua_State *L, StkId level); 56 | LUAI_FUNC void luaF_closeupval (lua_State *L, StkId level); 57 | LUAI_FUNC void luaF_close (lua_State *L, StkId level, int status, int yy); 58 | LUAI_FUNC void luaF_unlinkupval (UpVal *uv); 59 | LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f); 60 | LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number, 61 | int pc); 62 | 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /lib/lua/linit.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: linit.c $ 3 | ** Initialization of libraries for lua.c and other clients 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #define linit_c 9 | #define LUA_LIB 10 | 11 | /* 12 | ** If you embed Lua in your program and need to open the standard 13 | ** libraries, call luaL_openlibs in your program. If you need a 14 | ** different set of libraries, copy this file to your project and edit 15 | ** it to suit your needs. 16 | ** 17 | ** You can also *preload* libraries, so that a later 'require' can 18 | ** open the library, which is already linked to the application. 19 | ** For that, do the following code: 20 | ** 21 | ** luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE); 22 | ** lua_pushcfunction(L, luaopen_modname); 23 | ** lua_setfield(L, -2, modname); 24 | ** lua_pop(L, 1); // remove PRELOAD table 25 | */ 26 | 27 | #include "lprefix.h" 28 | 29 | 30 | #include 31 | 32 | #include "lua.h" 33 | 34 | #include "lualib.h" 35 | #include "lauxlib.h" 36 | 37 | 38 | /* 39 | ** these libs are loaded by lua.c and are readily available to any Lua 40 | ** program 41 | */ 42 | static const luaL_Reg loadedlibs[] = { 43 | {LUA_GNAME, luaopen_base}, 44 | {LUA_LOADLIBNAME, luaopen_package}, 45 | {LUA_COLIBNAME, luaopen_coroutine}, 46 | {LUA_TABLIBNAME, luaopen_table}, 47 | {LUA_IOLIBNAME, luaopen_io}, 48 | {LUA_OSLIBNAME, luaopen_os}, 49 | {LUA_STRLIBNAME, luaopen_string}, 50 | {LUA_MATHLIBNAME, luaopen_math}, 51 | {LUA_UTF8LIBNAME, luaopen_utf8}, 52 | {LUA_DBLIBNAME, luaopen_debug}, 53 | {NULL, NULL} 54 | }; 55 | 56 | 57 | LUALIB_API void luaL_openlibs (lua_State *L) { 58 | const luaL_Reg *lib; 59 | /* "require" functions from 'loadedlibs' and set results to global table */ 60 | for (lib = loadedlibs; lib->func; lib++) { 61 | luaL_requiref(L, lib->name, lib->func, 1); 62 | lua_pop(L, 1); /* remove lib */ 63 | } 64 | } 65 | 66 | -------------------------------------------------------------------------------- /lib/lua/ljumptab.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ljumptab.h $ 3 | ** Jump Table for the Lua interpreter 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #undef vmdispatch 9 | #undef vmcase 10 | #undef vmbreak 11 | 12 | #define vmdispatch(x) goto *disptab[x]; 13 | 14 | #define vmcase(l) L_##l: 15 | 16 | #define vmbreak vmfetch(); vmdispatch(GET_OPCODE(i)); 17 | 18 | 19 | static const void *const disptab[NUM_OPCODES] = { 20 | 21 | #if 0 22 | ** you can update the following list with this command: 23 | ** 24 | ** sed -n '/^OP_/\!d; s/OP_/\&\&L_OP_/ ; s/,.*/,/ ; s/\/.*// ; p' lopcodes.h 25 | ** 26 | #endif 27 | 28 | &&L_OP_MOVE, 29 | &&L_OP_LOADI, 30 | &&L_OP_LOADF, 31 | &&L_OP_LOADK, 32 | &&L_OP_LOADKX, 33 | &&L_OP_LOADFALSE, 34 | &&L_OP_LFALSESKIP, 35 | &&L_OP_LOADTRUE, 36 | &&L_OP_LOADNIL, 37 | &&L_OP_GETUPVAL, 38 | &&L_OP_SETUPVAL, 39 | &&L_OP_GETTABUP, 40 | &&L_OP_GETTABLE, 41 | &&L_OP_GETI, 42 | &&L_OP_GETFIELD, 43 | &&L_OP_SETTABUP, 44 | &&L_OP_SETTABLE, 45 | &&L_OP_SETI, 46 | &&L_OP_SETFIELD, 47 | &&L_OP_NEWTABLE, 48 | &&L_OP_SELF, 49 | &&L_OP_ADDI, 50 | &&L_OP_ADDK, 51 | &&L_OP_SUBK, 52 | &&L_OP_MULK, 53 | &&L_OP_MODK, 54 | &&L_OP_POWK, 55 | &&L_OP_DIVK, 56 | &&L_OP_IDIVK, 57 | &&L_OP_BANDK, 58 | &&L_OP_BORK, 59 | &&L_OP_BXORK, 60 | &&L_OP_SHRI, 61 | &&L_OP_SHLI, 62 | &&L_OP_ADD, 63 | &&L_OP_SUB, 64 | &&L_OP_MUL, 65 | &&L_OP_MOD, 66 | &&L_OP_POW, 67 | &&L_OP_DIV, 68 | &&L_OP_IDIV, 69 | &&L_OP_BAND, 70 | &&L_OP_BOR, 71 | &&L_OP_BXOR, 72 | &&L_OP_SHL, 73 | &&L_OP_SHR, 74 | &&L_OP_MMBIN, 75 | &&L_OP_MMBINI, 76 | &&L_OP_MMBINK, 77 | &&L_OP_UNM, 78 | &&L_OP_BNOT, 79 | &&L_OP_NOT, 80 | &&L_OP_LEN, 81 | &&L_OP_CONCAT, 82 | &&L_OP_CLOSE, 83 | &&L_OP_TBC, 84 | &&L_OP_JMP, 85 | &&L_OP_EQ, 86 | &&L_OP_LT, 87 | &&L_OP_LE, 88 | &&L_OP_EQK, 89 | &&L_OP_EQI, 90 | &&L_OP_LTI, 91 | &&L_OP_LEI, 92 | &&L_OP_GTI, 93 | &&L_OP_GEI, 94 | &&L_OP_TEST, 95 | &&L_OP_TESTSET, 96 | &&L_OP_CALL, 97 | &&L_OP_TAILCALL, 98 | &&L_OP_RETURN, 99 | &&L_OP_RETURN0, 100 | &&L_OP_RETURN1, 101 | &&L_OP_FORLOOP, 102 | &&L_OP_FORPREP, 103 | &&L_OP_TFORPREP, 104 | &&L_OP_TFORCALL, 105 | &&L_OP_TFORLOOP, 106 | &&L_OP_SETLIST, 107 | &&L_OP_CLOSURE, 108 | &&L_OP_VARARG, 109 | &&L_OP_VARARGPREP, 110 | &&L_OP_EXTRAARG 111 | 112 | }; 113 | -------------------------------------------------------------------------------- /lib/lua/llex.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: llex.h $ 3 | ** Lexical Analyzer 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef llex_h 8 | #define llex_h 9 | 10 | #include 11 | 12 | #include "lobject.h" 13 | #include "lzio.h" 14 | 15 | 16 | /* 17 | ** Single-char tokens (terminal symbols) are represented by their own 18 | ** numeric code. Other tokens start at the following value. 19 | */ 20 | #define FIRST_RESERVED (UCHAR_MAX + 1) 21 | 22 | 23 | #if !defined(LUA_ENV) 24 | #define LUA_ENV "_ENV" 25 | #endif 26 | 27 | 28 | /* 29 | * WARNING: if you change the order of this enumeration, 30 | * grep "ORDER RESERVED" 31 | */ 32 | enum RESERVED { 33 | /* terminal symbols denoted by reserved words */ 34 | TK_AND = FIRST_RESERVED, TK_BREAK, 35 | TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION, 36 | TK_GOTO, TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT, 37 | TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE, 38 | /* other terminal symbols */ 39 | TK_IDIV, TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, 40 | TK_SHL, TK_SHR, 41 | TK_DBCOLON, TK_EOS, 42 | TK_FLT, TK_INT, TK_NAME, TK_STRING 43 | }; 44 | 45 | /* number of reserved words */ 46 | #define NUM_RESERVED (cast_int(TK_WHILE-FIRST_RESERVED + 1)) 47 | 48 | 49 | typedef union { 50 | lua_Number r; 51 | lua_Integer i; 52 | TString *ts; 53 | } SemInfo; /* semantics information */ 54 | 55 | 56 | typedef struct Token { 57 | int token; 58 | SemInfo seminfo; 59 | } Token; 60 | 61 | 62 | /* state of the lexer plus state of the parser when shared by all 63 | functions */ 64 | typedef struct LexState { 65 | int current; /* current character (charint) */ 66 | int linenumber; /* input line counter */ 67 | int lastline; /* line of last token 'consumed' */ 68 | Token t; /* current token */ 69 | Token lookahead; /* look ahead token */ 70 | struct FuncState *fs; /* current function (parser) */ 71 | struct lua_State *L; 72 | ZIO *z; /* input stream */ 73 | Mbuffer *buff; /* buffer for tokens */ 74 | Table *h; /* to avoid collection/reuse strings */ 75 | struct Dyndata *dyd; /* dynamic structures used by the parser */ 76 | TString *source; /* current source name */ 77 | TString *envn; /* environment variable name */ 78 | } LexState; 79 | 80 | 81 | LUAI_FUNC void luaX_init (lua_State *L); 82 | LUAI_FUNC void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, 83 | TString *source, int firstchar); 84 | LUAI_FUNC TString *luaX_newstring (LexState *ls, const char *str, size_t l); 85 | LUAI_FUNC void luaX_next (LexState *ls); 86 | LUAI_FUNC int luaX_lookahead (LexState *ls); 87 | LUAI_FUNC l_noret luaX_syntaxerror (LexState *ls, const char *s); 88 | LUAI_FUNC const char *luaX_token2str (LexState *ls, int token); 89 | 90 | 91 | #endif 92 | -------------------------------------------------------------------------------- /lib/lua/lopnames.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lopnames.h $ 3 | ** Opcode names 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #if !defined(lopnames_h) 8 | #define lopnames_h 9 | 10 | #include 11 | 12 | 13 | /* ORDER OP */ 14 | 15 | static const char *const opnames[] = { 16 | "MOVE", 17 | "LOADI", 18 | "LOADF", 19 | "LOADK", 20 | "LOADKX", 21 | "LOADFALSE", 22 | "LFALSESKIP", 23 | "LOADTRUE", 24 | "LOADNIL", 25 | "GETUPVAL", 26 | "SETUPVAL", 27 | "GETTABUP", 28 | "GETTABLE", 29 | "GETI", 30 | "GETFIELD", 31 | "SETTABUP", 32 | "SETTABLE", 33 | "SETI", 34 | "SETFIELD", 35 | "NEWTABLE", 36 | "SELF", 37 | "ADDI", 38 | "ADDK", 39 | "SUBK", 40 | "MULK", 41 | "MODK", 42 | "POWK", 43 | "DIVK", 44 | "IDIVK", 45 | "BANDK", 46 | "BORK", 47 | "BXORK", 48 | "SHRI", 49 | "SHLI", 50 | "ADD", 51 | "SUB", 52 | "MUL", 53 | "MOD", 54 | "POW", 55 | "DIV", 56 | "IDIV", 57 | "BAND", 58 | "BOR", 59 | "BXOR", 60 | "SHL", 61 | "SHR", 62 | "MMBIN", 63 | "MMBINI", 64 | "MMBINK", 65 | "UNM", 66 | "BNOT", 67 | "NOT", 68 | "LEN", 69 | "CONCAT", 70 | "CLOSE", 71 | "TBC", 72 | "JMP", 73 | "EQ", 74 | "LT", 75 | "LE", 76 | "EQK", 77 | "EQI", 78 | "LTI", 79 | "LEI", 80 | "GTI", 81 | "GEI", 82 | "TEST", 83 | "TESTSET", 84 | "CALL", 85 | "TAILCALL", 86 | "RETURN", 87 | "RETURN0", 88 | "RETURN1", 89 | "FORLOOP", 90 | "FORPREP", 91 | "TFORPREP", 92 | "TFORCALL", 93 | "TFORLOOP", 94 | "SETLIST", 95 | "CLOSURE", 96 | "VARARG", 97 | "VARARGPREP", 98 | "EXTRAARG", 99 | NULL 100 | }; 101 | 102 | #endif 103 | 104 | -------------------------------------------------------------------------------- /lib/lua/lprefix.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lprefix.h $ 3 | ** Definitions for Lua code that must come before any other header file 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lprefix_h 8 | #define lprefix_h 9 | 10 | 11 | /* 12 | ** Allows POSIX/XSI stuff 13 | */ 14 | #if !defined(LUA_USE_C89) /* { */ 15 | 16 | #if !defined(_XOPEN_SOURCE) 17 | #define _XOPEN_SOURCE 600 18 | #elif _XOPEN_SOURCE == 0 19 | #undef _XOPEN_SOURCE /* use -D_XOPEN_SOURCE=0 to undefine it */ 20 | #endif 21 | 22 | /* 23 | ** Allows manipulation of large files in gcc and some other compilers 24 | */ 25 | #if !defined(LUA_32BITS) && !defined(_FILE_OFFSET_BITS) 26 | #define _LARGEFILE_SOURCE 1 27 | #define _FILE_OFFSET_BITS 64 28 | #endif 29 | 30 | #endif /* } */ 31 | 32 | 33 | /* 34 | ** Windows stuff 35 | */ 36 | #if defined(_WIN32) /* { */ 37 | 38 | #if !defined(_CRT_SECURE_NO_WARNINGS) 39 | #define _CRT_SECURE_NO_WARNINGS /* avoid warnings about ISO C functions */ 40 | #endif 41 | 42 | #endif /* } */ 43 | 44 | #endif 45 | 46 | -------------------------------------------------------------------------------- /lib/lua/lstring.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lstring.h $ 3 | ** String table (keep all strings handled by Lua) 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lstring_h 8 | #define lstring_h 9 | 10 | #include "lgc.h" 11 | #include "lobject.h" 12 | #include "lstate.h" 13 | 14 | 15 | /* 16 | ** Memory-allocation error message must be preallocated (it cannot 17 | ** be created after memory is exhausted) 18 | */ 19 | #define MEMERRMSG "not enough memory" 20 | 21 | 22 | /* 23 | ** Size of a TString: Size of the header plus space for the string 24 | ** itself (including final '\0'). 25 | */ 26 | #define sizelstring(l) (offsetof(TString, contents) + ((l) + 1) * sizeof(char)) 27 | 28 | #define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \ 29 | (sizeof(s)/sizeof(char))-1)) 30 | 31 | 32 | /* 33 | ** test whether a string is a reserved word 34 | */ 35 | #define isreserved(s) ((s)->tt == LUA_VSHRSTR && (s)->extra > 0) 36 | 37 | 38 | /* 39 | ** equality for short strings, which are always internalized 40 | */ 41 | #define eqshrstr(a,b) check_exp((a)->tt == LUA_VSHRSTR, (a) == (b)) 42 | 43 | 44 | LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, unsigned int seed); 45 | LUAI_FUNC unsigned int luaS_hashlongstr (TString *ts); 46 | LUAI_FUNC int luaS_eqlngstr (TString *a, TString *b); 47 | LUAI_FUNC void luaS_resize (lua_State *L, int newsize); 48 | LUAI_FUNC void luaS_clearcache (global_State *g); 49 | LUAI_FUNC void luaS_init (lua_State *L); 50 | LUAI_FUNC void luaS_remove (lua_State *L, TString *ts); 51 | LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, int nuvalue); 52 | LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l); 53 | LUAI_FUNC TString *luaS_new (lua_State *L, const char *str); 54 | LUAI_FUNC TString *luaS_createlngstrobj (lua_State *L, size_t l); 55 | 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /lib/lua/ltable.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ltable.h $ 3 | ** Lua tables (hash) 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef ltable_h 8 | #define ltable_h 9 | 10 | #include "lobject.h" 11 | 12 | 13 | #define gnode(t,i) (&(t)->node[i]) 14 | #define gval(n) (&(n)->i_val) 15 | #define gnext(n) ((n)->u.next) 16 | 17 | 18 | /* 19 | ** Clear all bits of fast-access metamethods, which means that the table 20 | ** may have any of these metamethods. (First access that fails after the 21 | ** clearing will set the bit again.) 22 | */ 23 | #define invalidateTMcache(t) ((t)->flags &= ~maskflags) 24 | 25 | 26 | /* true when 't' is using 'dummynode' as its hash part */ 27 | #define isdummy(t) ((t)->lastfree == NULL) 28 | 29 | 30 | /* allocated size for hash nodes */ 31 | #define allocsizenode(t) (isdummy(t) ? 0 : sizenode(t)) 32 | 33 | 34 | /* returns the Node, given the value of a table entry */ 35 | #define nodefromval(v) cast(Node *, (v)) 36 | 37 | 38 | LUAI_FUNC const TValue *luaH_getint (Table *t, lua_Integer key); 39 | LUAI_FUNC void luaH_setint (lua_State *L, Table *t, lua_Integer key, 40 | TValue *value); 41 | LUAI_FUNC const TValue *luaH_getshortstr (Table *t, TString *key); 42 | LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key); 43 | LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key); 44 | LUAI_FUNC void luaH_newkey (lua_State *L, Table *t, const TValue *key, 45 | TValue *value); 46 | LUAI_FUNC void luaH_set (lua_State *L, Table *t, const TValue *key, 47 | TValue *value); 48 | LUAI_FUNC void luaH_finishset (lua_State *L, Table *t, const TValue *key, 49 | const TValue *slot, TValue *value); 50 | LUAI_FUNC Table *luaH_new (lua_State *L); 51 | LUAI_FUNC void luaH_resize (lua_State *L, Table *t, unsigned int nasize, 52 | unsigned int nhsize); 53 | LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, unsigned int nasize); 54 | LUAI_FUNC void luaH_free (lua_State *L, Table *t); 55 | LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key); 56 | LUAI_FUNC lua_Unsigned luaH_getn (Table *t); 57 | LUAI_FUNC unsigned int luaH_realasize (const Table *t); 58 | 59 | 60 | #if defined(LUA_DEBUG) 61 | LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key); 62 | LUAI_FUNC int luaH_isdummy (const Table *t); 63 | #endif 64 | 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /lib/lua/lua.hpp: -------------------------------------------------------------------------------- 1 | // lua.hpp 2 | // Lua header files for C++ 3 | // <> not supplied automatically because Lua also compiles as C++ 4 | 5 | extern "C" { 6 | #include "lua.h" 7 | #include "lualib.h" 8 | #include "lauxlib.h" 9 | } 10 | -------------------------------------------------------------------------------- /lib/lua/lualib.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lualib.h $ 3 | ** Lua standard libraries 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #ifndef lualib_h 9 | #define lualib_h 10 | 11 | #include "lua.h" 12 | 13 | 14 | /* version suffix for environment variable names */ 15 | #define LUA_VERSUFFIX "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR 16 | 17 | 18 | LUAMOD_API int (luaopen_base) (lua_State *L); 19 | 20 | #define LUA_COLIBNAME "coroutine" 21 | LUAMOD_API int (luaopen_coroutine) (lua_State *L); 22 | 23 | #define LUA_TABLIBNAME "table" 24 | LUAMOD_API int (luaopen_table) (lua_State *L); 25 | 26 | #define LUA_IOLIBNAME "io" 27 | LUAMOD_API int (luaopen_io) (lua_State *L); 28 | 29 | #define LUA_OSLIBNAME "os" 30 | LUAMOD_API int (luaopen_os) (lua_State *L); 31 | 32 | #define LUA_STRLIBNAME "string" 33 | LUAMOD_API int (luaopen_string) (lua_State *L); 34 | 35 | #define LUA_UTF8LIBNAME "utf8" 36 | LUAMOD_API int (luaopen_utf8) (lua_State *L); 37 | 38 | #define LUA_MATHLIBNAME "math" 39 | LUAMOD_API int (luaopen_math) (lua_State *L); 40 | 41 | #define LUA_DBLIBNAME "debug" 42 | LUAMOD_API int (luaopen_debug) (lua_State *L); 43 | 44 | #define LUA_LOADLIBNAME "package" 45 | LUAMOD_API int (luaopen_package) (lua_State *L); 46 | 47 | 48 | /* open all previous libraries */ 49 | LUALIB_API void (luaL_openlibs) (lua_State *L); 50 | 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /lib/lua/lundump.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lundump.h $ 3 | ** load precompiled Lua chunks 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lundump_h 8 | #define lundump_h 9 | 10 | #include "llimits.h" 11 | #include "lobject.h" 12 | #include "lzio.h" 13 | 14 | 15 | /* data to catch conversion errors */ 16 | #define LUAC_DATA "\x19\x93\r\n\x1a\n" 17 | 18 | #define LUAC_INT 0x5678 19 | #define LUAC_NUM cast_num(370.5) 20 | 21 | /* 22 | ** Encode major-minor version in one byte, one nibble for each 23 | */ 24 | #define MYINT(s) (s[0]-'0') /* assume one-digit numerals */ 25 | #define LUAC_VERSION (MYINT(LUA_VERSION_MAJOR)*16+MYINT(LUA_VERSION_MINOR)) 26 | 27 | #define LUAC_FORMAT 0 /* this is the official format */ 28 | 29 | /* load one chunk; from lundump.c */ 30 | LUAI_FUNC LClosure* luaU_undump (lua_State* L, ZIO* Z, const char* name); 31 | 32 | /* dump one chunk; from ldump.c */ 33 | LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, 34 | void* data, int strip); 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /lib/lua/lzio.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lzio.c $ 3 | ** Buffered streams 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lzio_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | 15 | #include "lua.h" 16 | 17 | #include "llimits.h" 18 | #include "lmem.h" 19 | #include "lstate.h" 20 | #include "lzio.h" 21 | 22 | 23 | int luaZ_fill (ZIO *z) { 24 | size_t size; 25 | lua_State *L = z->L; 26 | const char *buff; 27 | lua_unlock(L); 28 | buff = z->reader(L, z->data, &size); 29 | lua_lock(L); 30 | if (buff == NULL || size == 0) 31 | return EOZ; 32 | z->n = size - 1; /* discount char being returned */ 33 | z->p = buff; 34 | return cast_uchar(*(z->p++)); 35 | } 36 | 37 | 38 | void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) { 39 | z->L = L; 40 | z->reader = reader; 41 | z->data = data; 42 | z->n = 0; 43 | z->p = NULL; 44 | } 45 | 46 | 47 | /* --------------------------------------------------------------- read --- */ 48 | size_t luaZ_read (ZIO *z, void *b, size_t n) { 49 | while (n) { 50 | size_t m; 51 | if (z->n == 0) { /* no bytes in buffer? */ 52 | if (luaZ_fill(z) == EOZ) /* try to read more */ 53 | return n; /* no more input; return number of missing bytes */ 54 | else { 55 | z->n++; /* luaZ_fill consumed first byte; put it back */ 56 | z->p--; 57 | } 58 | } 59 | m = (n <= z->n) ? n : z->n; /* min. between n and z->n */ 60 | memcpy(b, z->p, m); 61 | z->n -= m; 62 | z->p += m; 63 | b = (char *)b + m; 64 | n -= m; 65 | } 66 | return 0; 67 | } 68 | 69 | -------------------------------------------------------------------------------- /lib/lua/lzio.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lzio.h $ 3 | ** Buffered streams 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #ifndef lzio_h 9 | #define lzio_h 10 | 11 | #include "lua.h" 12 | 13 | #include "lmem.h" 14 | 15 | 16 | #define EOZ (-1) /* end of stream */ 17 | 18 | typedef struct Zio ZIO; 19 | 20 | #define zgetc(z) (((z)->n--)>0 ? cast_uchar(*(z)->p++) : luaZ_fill(z)) 21 | 22 | 23 | typedef struct Mbuffer { 24 | char *buffer; 25 | size_t n; 26 | size_t buffsize; 27 | } Mbuffer; 28 | 29 | #define luaZ_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->buffsize = 0) 30 | 31 | #define luaZ_buffer(buff) ((buff)->buffer) 32 | #define luaZ_sizebuffer(buff) ((buff)->buffsize) 33 | #define luaZ_bufflen(buff) ((buff)->n) 34 | 35 | #define luaZ_buffremove(buff,i) ((buff)->n -= (i)) 36 | #define luaZ_resetbuffer(buff) ((buff)->n = 0) 37 | 38 | 39 | #define luaZ_resizebuffer(L, buff, size) \ 40 | ((buff)->buffer = luaM_reallocvchar(L, (buff)->buffer, \ 41 | (buff)->buffsize, size), \ 42 | (buff)->buffsize = size) 43 | 44 | #define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0) 45 | 46 | 47 | LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, 48 | void *data); 49 | LUAI_FUNC size_t luaZ_read (ZIO* z, void *b, size_t n); /* read next n bytes */ 50 | 51 | 52 | 53 | /* --------- Private Part ------------------ */ 54 | 55 | struct Zio { 56 | size_t n; /* bytes still unread */ 57 | const char *p; /* current position in buffer */ 58 | lua_Reader reader; /* reader function */ 59 | void *data; /* additional data */ 60 | lua_State *L; /* Lua state (for reader) */ 61 | }; 62 | 63 | 64 | LUAI_FUNC int luaZ_fill (ZIO *z); 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /lib/xybase/BinaryStream.cpp: -------------------------------------------------------------------------------- 1 | #include "BinaryStream.h" 2 | 3 | #include "xystring.h" 4 | #include "xyutils.h" 5 | 6 | using namespace xybase; 7 | 8 | #ifdef WIN32 9 | #define fseek _fseeki64 10 | #define ftell _ftelli64 11 | #else 12 | #define fseek fseeko64 13 | #define ftell ftello64 14 | #endif // WIN32 15 | 16 | BinaryStream::BinaryStream(std::wstring path, const wchar_t *mode, bool isBigEndian) 17 | : name(path) 18 | { 19 | #ifdef WIN32 20 | stream = _wfopen(path.c_str(), mode); 21 | #else 22 | stream = fopen(xybase::string::to_string(path).c_str(), xybase::string::to_string(mode).c_str()); 23 | #endif 24 | if (stream == nullptr) 25 | { 26 | throw IOException(path, L"Failed to open specified file."); 27 | } 28 | isOpen = true; 29 | this->isBigEndian = isBigEndian; 30 | } 31 | 32 | BinaryStream::~BinaryStream() 33 | { 34 | if (isOpen) Close(); 35 | } 36 | 37 | void xybase::BinaryStream::Flush() 38 | { 39 | fflush(stream); 40 | } 41 | 42 | std::u16string xybase::BinaryStream::GetName() const 43 | { 44 | return xybase::string::to_utf16(name); 45 | } 46 | 47 | void BinaryStream::ReadBytes(char* buffer, size_t limit) 48 | { 49 | if (1 != fread(buffer, limit, 1, stream)) throw IOException(name, L"Read error."); 50 | } 51 | 52 | void BinaryStream::Write(const char* buffer, size_t size) 53 | { 54 | if (1 != fwrite(buffer, size, 1, stream)) throw IOException(name, L"Write error."); 55 | } 56 | 57 | size_t BinaryStream::Tell() const 58 | { 59 | return ftell(stream); 60 | } 61 | 62 | void BinaryStream::Seek(long long offset, SeekMode mode) 63 | { 64 | int seekMode; 65 | switch (mode) 66 | { 67 | case xybase::Stream::SM_BEGIN: 68 | seekMode = SEEK_SET; 69 | break; 70 | case xybase::Stream::SM_CURRENT: 71 | seekMode = SEEK_CUR; 72 | break; 73 | case xybase::Stream::SM_END: 74 | seekMode = SEEK_END; 75 | break; 76 | default: 77 | throw xybase::InvalidParameterException(L"mode", L"Invalid seek mode detected.", 15563); 78 | break; 79 | } 80 | fseek(stream, offset, seekMode); 81 | OnSeek(this); 82 | } 83 | 84 | void BinaryStream::Close() 85 | { 86 | OnClose(this); 87 | if (!isOpen) throw InvalidOperationException(L"Already closed.", __LINE__); 88 | isOpen = false; 89 | fclose(stream); 90 | } 91 | 92 | bool xybase::BinaryStream::IsEof() const noexcept 93 | { 94 | return feof(stream); 95 | } 96 | -------------------------------------------------------------------------------- /lib/xybase/BinaryStream.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef XY_BINARY_STREAM_H__ 4 | #define XY_BINARY_STREAM_H__ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "StreamBasic.h" 11 | #include "Exception/IOException.h" 12 | #include "Exception/InvalidOperationException.h" 13 | #include "StringBuilder.h" 14 | 15 | #include "xyapi.h" 16 | 17 | namespace xybase 18 | { 19 | class BinaryStream : public xybase::StreamBasic 20 | { 21 | protected: 22 | FILE *stream; 23 | bool isOpen; 24 | std::wstring name; 25 | 26 | public: 27 | /** 28 | * @brief 创建二进制流用于读写 29 | * @param path 目标文件路径 30 | * @param mode 打开模式 31 | * @param isBigEndian 是否为大端序文件 32 | */ 33 | XY_API BinaryStream(std::wstring path, const wchar_t *mode = L"rb+", bool isBigEndian = false); 34 | XY_API virtual ~BinaryStream(); 35 | 36 | XY_API virtual void Flush() override; 37 | XY_API virtual std::u16string GetName() const override; 38 | XY_API virtual void ReadBytes(char *buffer, size_t limit) override; 39 | XY_API virtual void Write(const char *buffer, size_t size) override; 40 | XY_API virtual size_t Tell() const override; 41 | XY_API virtual void Seek(long long offset, SeekMode mode = SM_BEGIN) override; 42 | XY_API virtual void Close() override; 43 | XY_API virtual bool IsEof() const noexcept override; 44 | }; 45 | } 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /lib/xybase/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set (XY_BASE_SOURCES "BinaryStream.cpp" "Stream.cpp" "Stream.h" "StreamBasic.cpp" "xystring.cpp" "xyutils.cpp" "Exception/InvalidOperationException.cpp" "Exception/InvalidParameterException.cpp" "Exception/IOException.cpp" "Exception/NotImplementedException.cpp" "Exception/OutOfRangeException.cpp" "Exception/RuntimeException.cpp" "Exception/Exception.cpp" "TextStream.cpp" "FileContainer.cpp" "Xml/XmlNode.cpp" "FileContainerBasic.cpp" "HostFsMapper.cpp" "Fragment/Fragment.cpp" "Fragment/FragmentManager.cpp" "MemoryStream.cpp") 2 | set (XY_BASE_HEADERS "BinaryStream.h" "FileContainer.h" "Singleton.h" "StreamBasic.h" "StringBuilder.h" "xystring.h" "xyutils.h" "Exception/InvalidOperationException.h" "Exception/InvalidParameterException.h" "Exception/IOException.h" "Exception/NotImplementedException.h" "Exception/OutOfRangeException.h" "Exception/RuntimeException.h" "Exception/Exception.h" "TextStream.h" "Xml/XmlParser.h" "Xml/XmlNode.h" "FileContainerBasic.h" "HostFsMapper.h" "Fragment/Fragment.h" "Fragment/FragmentManager.h" "Event.h" "MemoryStream.h") 3 | add_library (xybase ${XY_BASE_SOURCES} ${XY_BASE_HEADERS}) 4 | add_library (xybase_dyn SHARED ${XY_BASE_SOURCES} ${XY_BASE_HEADERS}) 5 | 6 | target_compile_definitions (xybase_dyn PUBLIC XY_DYNAMIC_LIBRARY) 7 | target_compile_definitions (xybase_dyn PRIVATE XY_EXPORT_DLL) 8 | 9 | target_include_directories (xybase INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) 10 | target_include_directories (xybase_dyn INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) 11 | 12 | include (GNUInstallDirs) 13 | install (TARGETS xybase DESTINATION ${CMAKE_INSTALL_LIBDIR}/xybase) 14 | install (TARGETS xybase_dyn DESTINATION ${CMAKE_INSTALL_LIBDIR}/xybase) 15 | install (DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/xybase FILES_MATCHING PATTERN "*.h") 16 | 17 | if (MSVC) 18 | target_compile_options(xybase PRIVATE "/utf-8") 19 | target_compile_options(xybase_dyn PRIVATE "/utf-8") 20 | endif() 21 | 22 | if (CMAKE_VERSION VERSION_GREATER 3.12) 23 | set_property(TARGET xybase PROPERTY CXX_STANDARD 20) 24 | set_property(TARGET xybase_dyn PROPERTY CXX_STANDARD 20) 25 | endif() 26 | -------------------------------------------------------------------------------- /lib/xybase/Event.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "xyapi.h" 4 | #include 5 | #include 6 | 7 | namespace xybase 8 | { 9 | template 10 | class Event 11 | { 12 | std::list registeredCallbacks; 13 | 14 | public: 15 | void RegisterCallback(void(*callback)(Args...)); 16 | 17 | void operator+= (void(*callback)(Args...)); 18 | 19 | void UnregisterCallback(void(*callback)(Args...)); 20 | 21 | void operator-= (void(*callback)(Args...)); 22 | 23 | void Invoke(Args... args) const; 24 | 25 | void operator() (Args... args) const; 26 | }; 27 | 28 | template 29 | inline void Event::RegisterCallback(void(*callback)(Args...)) 30 | { 31 | registeredCallbacks.push_back(callback); 32 | } 33 | 34 | template 35 | inline void Event::operator+=(void(*callback)(Args...)) 36 | { 37 | registeredCallbacks.push_back(callback); 38 | } 39 | 40 | template 41 | inline void Event::UnregisterCallback(void(*callback)(Args...)) 42 | { 43 | for (auto itr = registeredCallbacks.begin(); itr != registeredCallbacks.end(); ++itr) 44 | { 45 | if (*itr == callback) 46 | { 47 | registeredCallbacks.erase(itr); 48 | return; 49 | } 50 | } 51 | } 52 | 53 | template 54 | inline void Event::operator-=(void(*callback)(Args...)) 55 | { 56 | for (auto itr = registeredCallbacks.begin(); itr != registeredCallbacks.end(); ++itr) 57 | { 58 | if (*itr == callback) 59 | { 60 | registeredCallbacks.erase(itr); 61 | return; 62 | } 63 | } 64 | } 65 | 66 | template 67 | inline void Event::Invoke(Args ...args) const 68 | { 69 | auto itr = registeredCallbacks.begin(); 70 | while (itr != registeredCallbacks.end()) 71 | { 72 | auto cur = itr++; 73 | (*cur)(args...); 74 | } 75 | } 76 | 77 | template 78 | inline void Event::operator()(Args ...args) const 79 | { 80 | auto itr = registeredCallbacks.begin(); 81 | while (itr != registeredCallbacks.end()) 82 | { 83 | auto cur = itr++; 84 | (*cur)(args...); 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /lib/xybase/Exception/Exception.cpp: -------------------------------------------------------------------------------- 1 | #include "Exception.h" 2 | #include 3 | #include "../xyutils.h" 4 | #include "../xystring.h" 5 | 6 | xybase::Exception::Exception(const std::wstring &message, int err) 7 | : message(message), err(err) 8 | { 9 | auto ret = xybase::string::to_string(message); 10 | buf = new char[ret.size() + 1]; 11 | memcpy(buf, ret.c_str(), ret.size() + 1); 12 | } 13 | 14 | xybase::Exception::~Exception() 15 | { 16 | delete[] buf; 17 | } 18 | 19 | const char *xybase::Exception::what() const noexcept 20 | { 21 | return buf; 22 | } 23 | 24 | const std::wstring &xybase::Exception::GetMessage() const 25 | { 26 | return message; 27 | } 28 | 29 | int xybase::Exception::GetErrorCode() const 30 | { 31 | return err; 32 | } 33 | -------------------------------------------------------------------------------- /lib/xybase/Exception/Exception.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef XY_EXCEPTION_H__ 4 | #define XY_EXCEPTION_H__ 5 | 6 | #include 7 | #include 8 | 9 | #include "../xyapi.h" 10 | 11 | namespace xybase 12 | { 13 | class Exception : public std::exception 14 | { 15 | public: 16 | XY_API Exception(const std::wstring &message, int err); 17 | 18 | XY_API virtual ~Exception(); 19 | 20 | XY_API virtual const char *what() const noexcept override; 21 | 22 | XY_API virtual const std::wstring &GetMessage() const; 23 | 24 | XY_API virtual int GetErrorCode() const; 25 | 26 | protected: 27 | std::wstring message; 28 | int err; 29 | char *buf; 30 | }; 31 | } 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /lib/xybase/Exception/IOException.cpp: -------------------------------------------------------------------------------- 1 | #include "IOException.h" 2 | #include "../xyutils.h" 3 | 4 | xybase::IOException::IOException(const std::wstring &filename, const std::wstring &message, int err) 5 | : RuntimeException(message + L" (When operate file [" + filename + L"])", err), filename(filename) 6 | { 7 | } 8 | 9 | const std::wstring &xybase::IOException::GetFileName() const 10 | { 11 | return filename; 12 | } 13 | 14 | xybase::IOException::~IOException() 15 | { 16 | } 17 | -------------------------------------------------------------------------------- /lib/xybase/Exception/IOException.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef XY_IO_EXCEPTION_H__ 4 | #define XY_IO_EXCEPTION_H__ 5 | 6 | #include "RuntimeException.h" 7 | #include 8 | 9 | #include "../xyapi.h" 10 | 11 | namespace xybase 12 | { 13 | class IOException : public RuntimeException 14 | { 15 | public: 16 | XY_API IOException(const std::wstring &filename, const std::wstring &message, int err = errno); 17 | 18 | XY_API virtual const std::wstring &GetFileName() const; 19 | 20 | XY_API virtual ~IOException(); 21 | 22 | protected: 23 | std::wstring filename; 24 | }; 25 | } 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /lib/xybase/Exception/InvalidOperationException.cpp: -------------------------------------------------------------------------------- 1 | #include "InvalidOperationException.h" 2 | 3 | #include "../xystring.h" 4 | 5 | xybase::InvalidOperationException::InvalidOperationException(const std::wstring &message, int err) 6 | : RuntimeException(message, INVALID_OPERATION_EXCEPTION_LEAD | err) 7 | { 8 | } 9 | 10 | xybase::InvalidOperationException::~InvalidOperationException() {} 11 | -------------------------------------------------------------------------------- /lib/xybase/Exception/InvalidOperationException.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef XY_INVALID_OPERATION_EXCEPTION_H__ 4 | #define XY_INVALID_OPERATION_EXCEPTION_H__ 5 | 6 | #include "RuntimeException.h" 7 | #include 8 | 9 | #include "../xyapi.h" 10 | 11 | namespace xybase 12 | { 13 | const int INVALID_OPERATION_EXCEPTION_LEAD = 0x1000'0000; 14 | 15 | class InvalidOperationException : public RuntimeException 16 | { 17 | public: 18 | XY_API InvalidOperationException(const std::wstring &message, int err); 19 | 20 | XY_API virtual ~InvalidOperationException(); 21 | }; 22 | } 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /lib/xybase/Exception/InvalidParameterException.cpp: -------------------------------------------------------------------------------- 1 | #include "InvalidParameterException.h" 2 | 3 | #include "../xystring.h" 4 | 5 | xybase::InvalidParameterException::InvalidParameterException(const std::wstring ¶m, const std::wstring &message, int err) 6 | : param(param), Exception(L"Parameter: [" + param + L"] is invalid: " + message, INVALID_PARAMETER_EXCPETION_LEAD | err) 7 | { 8 | } 9 | 10 | 11 | const std::wstring &xybase::InvalidParameterException::GetParam() const 12 | { 13 | return param; 14 | } 15 | 16 | xybase::InvalidParameterException::~InvalidParameterException() 17 | { 18 | } 19 | -------------------------------------------------------------------------------- /lib/xybase/Exception/InvalidParameterException.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef XY_INVALID_PARAMETER_EXCEPTION_H__ 4 | #define XY_INVALID_PARAMETER_EXCEPTION_H__ 5 | 6 | #include "Exception.h" 7 | #include 8 | 9 | #include "../xyapi.h" 10 | 11 | namespace xybase 12 | { 13 | const int INVALID_PARAMETER_EXCPETION_LEAD = 0x2000'0000; 14 | 15 | class InvalidParameterException : public Exception 16 | { 17 | public: 18 | XY_API InvalidParameterException(const std::wstring & param, const std::wstring &message, int err); 19 | 20 | XY_API virtual const std::wstring &GetParam() const; 21 | 22 | XY_API virtual ~InvalidParameterException(); 23 | 24 | protected: 25 | std::wstring param; 26 | }; 27 | } 28 | #endif 29 | -------------------------------------------------------------------------------- /lib/xybase/Exception/NotImplementedException.cpp: -------------------------------------------------------------------------------- 1 | #include "NotImplementedException.h" 2 | 3 | xybase::NotImplementedException::NotImplementedException() 4 | : Exception(L"Not implemented yet.", 90002) {} 5 | 6 | xybase::NotImplementedException::~NotImplementedException() 7 | { 8 | } 9 | -------------------------------------------------------------------------------- /lib/xybase/Exception/NotImplementedException.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef XY_NOT_IMPLEMENTED_EXCEPTION_H__ 4 | #define XY_NOT_IMPLEMENTED_EXCEPTION_H__ 5 | 6 | #include "Exception.h" 7 | 8 | #include "../xyapi.h" 9 | 10 | namespace xybase 11 | { 12 | class NotImplementedException : public Exception 13 | { 14 | public: 15 | XY_API NotImplementedException(); 16 | 17 | XY_API virtual ~NotImplementedException(); 18 | }; 19 | } 20 | 21 | #endif // !XY_NOT_IMPLEMENTED_EXCEPTION_H__ 22 | -------------------------------------------------------------------------------- /lib/xybase/Exception/OutOfRangeException.cpp: -------------------------------------------------------------------------------- 1 | #include "OutOfRangeException.h" 2 | 3 | xybase::OutOfRangeException::OutOfRangeException(const std::wstring &message, int err) 4 | : RuntimeException(message, OUT_OF_RANGE_EXCEPTION_LEAD | err) 5 | { 6 | } 7 | 8 | xybase::OutOfRangeException::~OutOfRangeException() 9 | { 10 | } 11 | -------------------------------------------------------------------------------- /lib/xybase/Exception/OutOfRangeException.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef XY_OUT_OF_RANGE_H__ 4 | #define XY_OUT_OF_RANGE_H__ 5 | 6 | #include "RuntimeException.h" 7 | 8 | #include "../xyapi.h" 9 | 10 | namespace xybase 11 | { 12 | const int OUT_OF_RANGE_EXCEPTION_LEAD = 0x3000'0000; 13 | 14 | class OutOfRangeException : public RuntimeException 15 | { 16 | public: 17 | XY_API OutOfRangeException(const std::wstring & message, int err); 18 | 19 | XY_API virtual ~OutOfRangeException(); 20 | }; 21 | } 22 | 23 | #endif // !XY_OUT_OF_RANGE_H__ 24 | -------------------------------------------------------------------------------- /lib/xybase/Exception/RuntimeException.cpp: -------------------------------------------------------------------------------- 1 | #include "RuntimeException.h" 2 | #include 3 | #include "../xyutils.h" 4 | #include "../xystring.h" 5 | 6 | xybase::RuntimeException::RuntimeException(const std::wstring &message, int err) 7 | : message(message), err(RUNTIME_EXCEPTION_LEAD | err) 8 | { 9 | auto ret = xybase::string::to_utf8(message); 10 | buf = new char[ret.size() + 1]; 11 | memcpy(buf, ret.c_str(), ret.size() + 1); 12 | } 13 | 14 | xybase::RuntimeException::~RuntimeException() 15 | { 16 | delete[] buf; 17 | } 18 | 19 | const char *xybase::RuntimeException::what() const noexcept 20 | { 21 | return buf; 22 | } 23 | 24 | const std::wstring &xybase::RuntimeException::GetMessage() const 25 | { 26 | return message; 27 | } 28 | 29 | int xybase::RuntimeException::GetErrorCode() const 30 | { 31 | return err & 0xFF'FFFF; 32 | } 33 | -------------------------------------------------------------------------------- /lib/xybase/Exception/RuntimeException.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef XY_RUNTIME_EXCEPTION_H__ 4 | #define XY_RUNTIME_EXCEPTION_H__ 5 | 6 | #include 7 | #include 8 | 9 | #include "../xyapi.h" 10 | 11 | namespace xybase 12 | { 13 | const int RUNTIME_EXCEPTION_LEAD = 0x8000'0000; 14 | 15 | class RuntimeException : public std::exception 16 | { 17 | public: 18 | XY_API RuntimeException(const std::wstring &message, int err); 19 | 20 | XY_API virtual ~RuntimeException(); 21 | 22 | XY_API virtual const char *what() const noexcept override; 23 | 24 | XY_API virtual const std::wstring &GetMessage() const; 25 | 26 | XY_API virtual int GetErrorCode() const; 27 | 28 | protected: 29 | std::wstring message; 30 | int err; 31 | char *buf; 32 | }; 33 | } 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /lib/xybase/FileContainer.cpp: -------------------------------------------------------------------------------- 1 | #include "FileContainer.h" 2 | 3 | xybase::FileContainer::~FileContainer() 4 | { 5 | } 6 | -------------------------------------------------------------------------------- /lib/xybase/FileContainer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef XY_FILE_CONTAINER_H__ 4 | #define XY_FILE_CONTAINER_H__ 5 | 6 | #include 7 | 8 | #include "Stream.h" 9 | 10 | namespace xybase 11 | { 12 | using FileOpenMode = int; 13 | 14 | const FileOpenMode 15 | FOM_READ = 0x1, 16 | FOM_WRITE = 0x2, 17 | FOM_TRUNCATE = 0x10, 18 | FOM_APPEND = 0x20, 19 | FOM_EXCLUSIVE = 0x40, 20 | FOM_BIG_ENDIAN = 0x80; 21 | 22 | /** 23 | * @brief 文件容器。抽象类,用于表示虚拟文件系统/文件包。 24 | */ 25 | class XY_API FileContainer 26 | { 27 | public: 28 | virtual ~FileContainer(); 29 | 30 | /** 31 | * @brief 获取容器名称,该名称应唯一地标识此实例。 32 | * @return 容器名称。 33 | */ 34 | virtual std::u16string GetName() = 0; 35 | 36 | /** 37 | * @brief 刷新容器缓冲区(文件包用,其他类型保持空操作)。 38 | */ 39 | virtual void Flush() = 0; 40 | 41 | /** 42 | * @brief 以指定模式打开一个文件用于读写。 43 | * @param name 文件名。 44 | * @param mode 打开模式。 45 | * @return 打开的文件流。 46 | */ 47 | virtual xybase::Stream *Open(std::u16string name, FileOpenMode mode = FOM_READ | FOM_WRITE) = 0; 48 | 49 | /** 50 | * @brief 列出所有文件。 51 | * @return 文件列表。 52 | */ 53 | virtual std::list List() = 0; 54 | 55 | /** 56 | * @brief 创建目录。 57 | * @param path 指定路径。 58 | */ 59 | virtual void MakeDir(std::u16string path) = 0; 60 | 61 | /** 62 | * @brief 移除一个文件或目录。 63 | * @param path 文件或目录的路径。 64 | * @param recursive 是否递归删除子项(目录有效,文件忽略此参数)。 65 | */ 66 | virtual void Remove(std::u16string path, bool recursive = false) = 0; 67 | 68 | /** 69 | * @brief 检查一个文件或目录是否存在。 70 | * @param path 文件或目录的路径。 71 | * @return 存在则为真,否则为假。 72 | */ 73 | virtual bool Exists(std::u16string path) = 0; 74 | }; 75 | } 76 | 77 | #endif 78 | -------------------------------------------------------------------------------- /lib/xybase/Fragment/Fragment.cpp: -------------------------------------------------------------------------------- 1 | #include "Fragment.h" 2 | 3 | using namespace xybase::Fragment; 4 | 5 | void Fragment::EliminateBeginning(size_t size) 6 | { 7 | if (size > this->size) throw InvalidParameterException(L"size", L"Cannot larger than this->size.", __LINE__); 8 | 9 | begin += size; 10 | this->size -= size; 11 | } 12 | 13 | void Fragment::EliminateEnding(size_t size) 14 | { 15 | if (size > this->size) throw InvalidParameterException(L"size", L"Cannot be larger than this->size.", __LINE__); 16 | 17 | this->size -= size; 18 | } 19 | 20 | bool Fragment::IsOverlapsWith(const Fragment &frag) const 21 | { 22 | return !(GetEnding() < frag.begin || begin > frag.GetEnding()); 23 | } 24 | 25 | bool Fragment::IsContains(const Fragment &frag) const 26 | { 27 | return begin <= frag.begin && GetEnding() >= frag.GetEnding(); 28 | } 29 | 30 | bool Fragment::IsContains(size_t position) const 31 | { 32 | return position >= begin && position < GetEnding(); 33 | } 34 | 35 | Fragment *Fragment::MergeToNew(const Fragment &target) const 36 | { 37 | if (IsContains(target)) return new Fragment(*this); 38 | if (IsOverlapsWith(target)) 39 | { 40 | size_t nb = begin < target.begin ? begin : target.begin; 41 | size_t ne = GetEnding() < target.GetEnding() ? target.GetEnding() : GetEnding(); 42 | 43 | return new Fragment(nb, ne - nb); 44 | } 45 | 46 | return nullptr; 47 | } 48 | 49 | void Fragment::Merge(const Fragment &target) 50 | { 51 | if (IsContains(target)) return; 52 | if (!IsOverlapsWith(target)) throw InvalidParameterException(L"target", L"Have no insertion with this fragment.", __LINE__); 53 | 54 | begin = begin < target.begin ? begin : target.begin; 55 | SetEnding(GetEnding() < target.GetEnding() ? target.GetEnding() : GetEnding()); 56 | } 57 | 58 | bool Fragment::operator==(const Fragment &right) const 59 | { 60 | return begin == right.begin && size == right.size; 61 | } 62 | 63 | bool Fragment::operator!=(const Fragment &right) const 64 | { 65 | return !(*this == right); 66 | } 67 | 68 | Fragment::Fragment(size_t begin, size_t size) 69 | { 70 | this->begin = begin; 71 | this->size = size; 72 | } 73 | 74 | Fragment::Fragment(const Fragment &pattern) 75 | { 76 | size = pattern.size; 77 | begin = pattern.begin; 78 | } 79 | 80 | size_t Fragment::GetBeginning() const 81 | { 82 | return begin; 83 | } 84 | 85 | size_t Fragment::GetEnding() const 86 | { 87 | return begin + size; 88 | } 89 | 90 | size_t Fragment::GetSize() const 91 | { 92 | return size; 93 | } 94 | 95 | void Fragment::SetFragment(size_t beginning, size_t size) 96 | { 97 | begin = beginning; 98 | this->size = size; 99 | } 100 | 101 | void Fragment::SetBeginning(size_t beginning) 102 | { 103 | if (beginning >= GetEnding()) throw InvalidParameterException(L"beginning", L"Cannot be set to the pos after the ending.", __LINE__); 104 | size_t newSize = GetEnding() - beginning; 105 | 106 | begin = beginning; 107 | size = newSize; 108 | } 109 | 110 | void Fragment::SetSize(size_t size) 111 | { 112 | this->size = size; 113 | } 114 | 115 | void Fragment::SetEnding(size_t ending) 116 | { 117 | if (ending < begin) throw InvalidParameterException(L"ending", L"Cannot be set to the pos before the begining.", __LINE__); 118 | 119 | this->size = ending - begin; 120 | } 121 | -------------------------------------------------------------------------------- /lib/xybase/Fragment/Fragment.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef XY_FRAGMENT_H__ 4 | #define XY_FRAGMENT_H__ 5 | 6 | #include "../Exception/InvalidParameterException.h" 7 | 8 | #include "../xyapi.h" 9 | 10 | namespace xybase 11 | { 12 | namespace Fragment 13 | { 14 | /** 15 | * @brief 存储片段,用于标记一段左闭右开区间 16 | */ 17 | class XY_API Fragment 18 | { 19 | size_t begin, size; 20 | 21 | public: 22 | /** 23 | * @brief 创建新存储片段,指定其起始地址和长度 24 | * @param begin 起始地址 25 | * @param size 长度 26 | */ 27 | Fragment(size_t begin, size_t size); 28 | 29 | /** 30 | * @brief 创建新存储片段 31 | * @param pattern 旧存储片段 32 | */ 33 | Fragment(const Fragment &pattern); 34 | 35 | /** 36 | * @brief 获取片段开始地址 37 | * @return 片段开始地址 38 | */ 39 | size_t GetBeginning() const; 40 | 41 | /** 42 | * @brief 获取片段结束地址(该地址不在片段中) 43 | * @return 片段结束地址 44 | */ 45 | size_t GetEnding() const; 46 | 47 | /** 48 | * @brief 获取片段大小 49 | * @return 片段大小 50 | */ 51 | size_t GetSize() const; 52 | 53 | /** 54 | * @brief 设置片段区间 55 | * @param beginning 起始地址 56 | * @param size 大小 57 | */ 58 | void SetFragment(size_t beginning, size_t size); 59 | 60 | /** 61 | * @brief 重设起始地址 62 | * @param beginning 重新设置起始地址 63 | */ 64 | void SetBeginning(size_t beginning); 65 | 66 | /** 67 | * @brief 重设大小 68 | * @param size 大小 69 | */ 70 | void SetSize(size_t size); 71 | 72 | /** 73 | * @brief 重设结束地址 74 | * @param ending 结束地址 75 | */ 76 | void SetEnding(size_t ending); 77 | 78 | /** 79 | * @brief 消除头部,将头部后移指定大小 80 | * @param size 要消除的大小 81 | */ 82 | void EliminateBeginning(size_t size); 83 | 84 | /** 85 | * @brief 消除尾部,将尾部前移指定大小 86 | * @param size 要消除的大小 87 | */ 88 | void EliminateEnding(size_t size); 89 | 90 | /** 91 | * @brief 检查是否和所给区段重叠 92 | * @param frag 要比对的区段 93 | * @return 真则有重叠,假则没有 94 | */ 95 | bool IsOverlapsWith(const Fragment &frag) const; 96 | 97 | /** 98 | * @brief 检查是否包括指定区段 99 | * @param frag 要比对的片段 100 | * @return 真则包含,假则没有 101 | */ 102 | bool IsContains(const Fragment &frag) const; 103 | 104 | /** 105 | * @brief 检查是否包括指定地址 106 | * @param position 要检查的地址 107 | * @return 真则包含,假则没有 108 | */ 109 | bool IsContains(size_t position) const; 110 | 111 | /** 112 | * @brief 和指定片段合并为新的片段(创建新片段) 113 | * @param target 要合并的片段 114 | * @return 新创建的合并后片段,失败返回 nullptr 115 | */ 116 | Fragment *MergeToNew(const Fragment &target) const; 117 | 118 | /** 119 | * @brief 将所给片段合并到此片段中 120 | * @param target 要合并的片段 121 | */ 122 | void Merge(const Fragment &target); 123 | 124 | /** 125 | * @brief 比对片段是否相等 126 | * @param right 要比对的片段 127 | * @return 真则相等,假则不等 128 | */ 129 | bool operator== (const Fragment &right) const; 130 | 131 | /** 132 | * @brief 比对片段是否不等 133 | * @param right 要比对的片段 134 | * @return 真则不等,假则相等 135 | */ 136 | bool operator!= (const Fragment &right) const; 137 | }; 138 | } 139 | } 140 | 141 | #endif 142 | -------------------------------------------------------------------------------- /lib/xybase/Fragment/FragmentManager.cpp: -------------------------------------------------------------------------------- 1 | #include "FragmentManager.h" 2 | 3 | #include "../xyutils.h" 4 | #include "../Exception/InvalidOperationException.h" 5 | 6 | using namespace xybase::Fragment; 7 | 8 | FragmentManager::~FragmentManager() 9 | { 10 | for (auto ptr : frags) 11 | { 12 | delete ptr; 13 | } 14 | } 15 | 16 | FragmentManager::FragmentManager() 17 | { 18 | } 19 | 20 | const std::list &FragmentManager::GetFragments() const 21 | { 22 | return frags; 23 | } 24 | 25 | void FragmentManager::RegisterFragment(const Fragment &frag) 26 | { 27 | for (auto f : frags) 28 | { 29 | if (f->IsContains(frag)) 30 | { 31 | return; 32 | } 33 | if (f->IsOverlapsWith(frag)) 34 | { 35 | f->Merge(frag); 36 | return; 37 | } 38 | } 39 | frags.push_back(new Fragment(frag)); 40 | } 41 | 42 | void FragmentManager::RegisterFragment(size_t position, size_t size) 43 | { 44 | RegisterFragment(Fragment(position, size)); 45 | } 46 | 47 | void FragmentManager::Defragment() 48 | { 49 | for (auto itr = frags.begin(); itr != frags.end(); ++itr) 50 | { 51 | std::list::iterator jtr = itr; 52 | ++jtr; 53 | while (jtr != frags.end()) 54 | { 55 | if ((*itr)->IsContains(**jtr)) 56 | { 57 | delete *jtr; 58 | frags.erase(jtr++); 59 | } 60 | else if ((*itr)->IsOverlapsWith(**jtr)) 61 | { 62 | (**itr).Merge(**jtr); 63 | delete *jtr; 64 | frags.erase(jtr++); 65 | } 66 | else jtr++; 67 | } 68 | } 69 | } 70 | 71 | bool FragmentManager::IsFree(size_t position) 72 | { 73 | for (auto frag : frags) 74 | { 75 | if (frag->IsContains(position)) return false; 76 | } 77 | return true; 78 | } 79 | 80 | bool FragmentManager::IsFree(Fragment *frag) 81 | { 82 | for (auto frag : frags) 83 | { 84 | if (frag->IsContains(*frag)) return false; 85 | } 86 | return true; 87 | } 88 | 89 | size_t FragmentManager::Alloc(size_t size, int align) 90 | { 91 | size = (size + (static_cast(align) - 1)) & ~(static_cast(align) - 1); 92 | // 尝试分配已经对齐的空间 93 | for (auto frag : frags) 94 | { 95 | if (frag->GetSize() >= size && !(frag->GetBeginning() & (align - 1))) 96 | { 97 | size_t ret = frag->GetBeginning(); 98 | frag->EliminateBeginning((size_t)size); 99 | return ret; 100 | } 101 | } 102 | // 若都不对齐 103 | for (auto frag : frags) 104 | { 105 | // 若可能具有空位 106 | if (frag->GetSize() >= size) 107 | { 108 | // 计算对齐后的大小 109 | auto bgn = frag->GetBeginning(); 110 | bgn = XY_ALIGN(bgn, align); 111 | size_t add = bgn - frag->GetBeginning(); 112 | if (frag->GetSize() >= size + add) 113 | { 114 | // 返回对齐的空间 115 | frag->EliminateBeginning((size_t)size + add); 116 | return bgn; 117 | } 118 | } 119 | } 120 | throw xybase::InvalidOperationException(L"Cannot alloc anymore.", 32751); 121 | } 122 | 123 | Fragment xybase::Fragment::FragmentManager::AllocMaximumFragment() 124 | { 125 | size_t max = 0; 126 | for (auto &&frag : frags) 127 | { 128 | if (frag->GetSize() > max) 129 | { 130 | max = frag->GetSize(); 131 | } 132 | } 133 | return Fragment(Alloc(max, 1), max); 134 | } 135 | -------------------------------------------------------------------------------- /lib/xybase/Fragment/FragmentManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef XY_FRAGMENT_MANAGER_H__ 4 | #define XY_FRAGMENT_MANAGER_H__ 5 | 6 | #include 7 | 8 | #include "Fragment.h" 9 | 10 | #include "../xyapi.h" 11 | 12 | namespace xybase 13 | { 14 | namespace Fragment 15 | { 16 | 17 | #ifndef cal_align 18 | #define cal_align(loc, align) (((loc) < 0) ? ((loc) & ~(align - 1)) : ((loc + (align - 1)) & ~(align - 1))) 19 | #endif 20 | 21 | class FragmentManager 22 | { 23 | std::list frags; 24 | 25 | public: 26 | /** 27 | * @brief 创建新的空碎片管理器。 28 | */ 29 | XY_API FragmentManager(); 30 | 31 | XY_API virtual ~FragmentManager(); 32 | 33 | XY_API const std::list &GetFragments() const; 34 | 35 | /** 36 | * @brief 注册一个碎片。 37 | * @param frag 要注册的碎片。 38 | */ 39 | XY_API void RegisterFragment(const Fragment &frag); 40 | 41 | /** 42 | * @brief 初始化一个碎片并注册。 43 | * @param position 碎片处在的位置。 44 | * @param size 碎片的大小。 45 | */ 46 | XY_API void RegisterFragment(size_t position, size_t size); 47 | 48 | /** 49 | * @brief 碎片整理。 50 | */ 51 | XY_API void Defragment(); 52 | 53 | /** 54 | * @brief 检查指定的位置是否是空闲。 55 | * @param position 要检查的位置。 56 | * @return bool 若空闲则为真,否则为假。 57 | */ 58 | XY_API bool IsFree(size_t position); 59 | 60 | /** 61 | * @brief 检查指定的区段是否空闲。 62 | * @param frag 要检查的区段。 63 | * @return bool 若空闲则为真,否则为假。 64 | */ 65 | XY_API bool IsFree(Fragment *frag); 66 | 67 | /** 68 | * @brief 尝试分配一段空间。 69 | * @param size 要分配的大小。 70 | * @param align 要求的对齐参数。 71 | * @return 分配成功的空间起始地址。 72 | */ 73 | XY_API size_t Alloc(size_t size, int align); 74 | 75 | /** 76 | * @brief 将最大的碎片分配掉。(不定大小分配用) 77 | * @return 最大的碎片。 78 | */ 79 | XY_API Fragment AllocMaximumFragment(); 80 | }; 81 | } 82 | } 83 | 84 | #endif 85 | -------------------------------------------------------------------------------- /lib/xybase/HostFsMapper.cpp: -------------------------------------------------------------------------------- 1 | #include "HostFsMapper.h" 2 | #include "BinaryStream.h" 3 | 4 | #include 5 | #include 6 | #include 7 | #include "Exception/InvalidParameterException.h" 8 | #include "xystring.h" 9 | 10 | xybase::HostFsMapper::HostFsMapper(std::u16string rootPath) 11 | { 12 | if (!rootPath.ends_with('/') && !rootPath.ends_with('\\')) rootPath += u'/'; 13 | if (!std::filesystem::exists(rootPath)) 14 | throw InvalidParameterException(L"rootPath", L"Path " + xybase::string::to_wstring(rootPath) + L" does not exist.", 0xAF10); 15 | 16 | this->rootPath = rootPath; 17 | } 18 | 19 | xybase::HostFsMapper::~HostFsMapper() 20 | { 21 | } 22 | 23 | std::u16string xybase::HostFsMapper::GetName() 24 | { 25 | return rootPath + u"{mapper}:"; 26 | } 27 | 28 | void xybase::HostFsMapper::Flush() 29 | { 30 | // intend to be blank 31 | } 32 | 33 | xybase::Stream *xybase::HostFsMapper::Open(std::u16string name, FileOpenMode mode) 34 | { 35 | if (name.find(u"..") != std::u16string::npos) throw InvalidParameterException(L"name", L"Invalid path: no .. permitted.", 95964); 36 | wchar_t modebuf[8]; 37 | memset(modebuf, 0, sizeof(modebuf)); 38 | wchar_t *ptr = modebuf; 39 | 40 | if (mode & FOM_READ && mode & FOM_WRITE) 41 | { 42 | if (mode & FOM_APPEND) 43 | { 44 | *ptr++ = 'r'; 45 | *ptr++ = 'b'; 46 | *ptr++ = '+'; 47 | } 48 | if (mode & FOM_TRUNCATE) 49 | { 50 | *ptr++ = 'w'; 51 | *ptr++ = 'b'; 52 | *ptr++ = '+'; 53 | } 54 | } 55 | else 56 | { 57 | if (mode & FOM_READ) *ptr++ = 'r'; 58 | if (mode & FOM_WRITE) *ptr++ = 'w'; 59 | *ptr++ = 'b'; 60 | if (mode & FOM_APPEND) *ptr++ = 'a'; 61 | else if (mode & FOM_TRUNCATE); 62 | else *ptr++ = '+'; 63 | } 64 | 65 | if (mode & FOM_EXCLUSIVE); 66 | 67 | return new BinaryStream(xybase::string::to_wstring(rootPath + name), modebuf, mode & FOM_BIG_ENDIAN); 68 | } 69 | 70 | std::list xybase::HostFsMapper::List() 71 | { 72 | std::list ret; 73 | 74 | std::filesystem::path root(rootPath); 75 | std::filesystem::directory_entry rootDir(root); 76 | 77 | for (auto const &itr : std::filesystem::recursive_directory_iterator(root)) 78 | { 79 | ret.push_back(xybase::string::to_utf16(itr.path())); 80 | } 81 | 82 | return ret; 83 | } 84 | 85 | void xybase::HostFsMapper::MakeDir(std::u16string path) 86 | { 87 | if (path.find(u"..") != std::u16string::npos) throw InvalidParameterException(L"path", L"Invalid path: no .. permitted.", 95964); 88 | std::filesystem::path root(rootPath); 89 | std::filesystem::create_directory(root/path); 90 | } 91 | 92 | void xybase::HostFsMapper::Remove(std::u16string path, bool recursive) 93 | { 94 | if (path.find(u"..") != std::u16string::npos) throw InvalidParameterException(L"path", L"Invalid path: no .. permitted.", 95964); 95 | std::filesystem::path root(rootPath); 96 | if (recursive) 97 | std::filesystem::remove_all(root/path); 98 | else 99 | std::filesystem::remove(root/path); 100 | } 101 | 102 | bool xybase::HostFsMapper::Exists(std::u16string path) 103 | { 104 | return std::filesystem::exists(std::filesystem::path(rootPath) / path); 105 | } 106 | -------------------------------------------------------------------------------- /lib/xybase/HostFsMapper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #ifndef XY_HOST_FS_MAPPER_H__ 3 | #define XY_HOST_FS_MAPPER_H__ 4 | 5 | #include "FileContainer.h" 6 | #include "xyapi.h" 7 | 8 | namespace xybase 9 | { 10 | /** 11 | * @brief A mapper to the host file system. As a file container. 12 | */ 13 | class HostFsMapper : public FileContainer 14 | { 15 | std::u16string rootPath; 16 | 17 | public: 18 | XY_API HostFsMapper(std::u16string rootPath); 19 | 20 | XY_API ~HostFsMapper(); 21 | 22 | XY_API std::u16string GetName() override; 23 | XY_API void Flush() override; 24 | XY_API xybase::Stream *Open(std::u16string name, FileOpenMode mode) override; 25 | XY_API std::list List() override; 26 | XY_API void MakeDir(std::u16string path) override; 27 | XY_API void Remove(std::u16string path, bool recursive) override; 28 | XY_API bool Exists(std::u16string path) override; 29 | }; 30 | } 31 | 32 | 33 | #endif // !XY_HOST_FS_MAPPER_H__ 34 | -------------------------------------------------------------------------------- /lib/xybase/MemoryStream.cpp: -------------------------------------------------------------------------------- 1 | #include "MemoryStream.h" 2 | #include 3 | 4 | xybase::MemoryStream::~MemoryStream() 5 | { 6 | } 7 | 8 | xybase::MemoryStream::MemoryStream(void *memoryBasePointer, size_t size, const std::u16string &name) 9 | { 10 | memoryPivot = memoryBasePointer; 11 | this->size = size; 12 | cursor = 0; 13 | this->name = name; 14 | } 15 | 16 | void xybase::MemoryStream::Flush() 17 | { 18 | // Do nothing. 19 | } 20 | 21 | std::u16string xybase::MemoryStream::GetName() const 22 | { 23 | return name; 24 | } 25 | 26 | void xybase::MemoryStream::ReadBytes(char *buffer, size_t limit) 27 | { 28 | if (cursor + limit > size) throw xybase::InvalidParameterException(L"limit", L"Too large.", 440100); 29 | 30 | memcpy(buffer, ((char *)memoryPivot) + cursor, limit); 31 | cursor += limit; 32 | } 33 | 34 | size_t xybase::MemoryStream::Tell() const 35 | { 36 | return cursor; 37 | } 38 | 39 | bool xybase::MemoryStream::IsEof() const noexcept 40 | { 41 | return cursor == size; 42 | } 43 | 44 | void xybase::MemoryStream::Seek(long long offset, SeekMode mode) 45 | { 46 | switch (mode) 47 | { 48 | case xybase::Stream::SM_BEGIN: 49 | if ((unsigned long long)offset > size) throw xybase::InvalidParameterException(L"offset", L"Exceeds stream size.", 440110); 50 | cursor = offset; 51 | break; 52 | case xybase::Stream::SM_CURRENT: 53 | if (offset + cursor > size) throw xybase::InvalidParameterException(L"offset", L"Exceeds stream size.", 440111); 54 | cursor += offset; 55 | break; 56 | case xybase::Stream::SM_END: 57 | if ((unsigned long long)offset > size) throw xybase::InvalidParameterException(L"offset", L"Exceeds stream size.", 440112); 58 | cursor = size + offset; 59 | break; 60 | default: 61 | throw xybase::InvalidParameterException(L"mode", L"Invalid seek mode.", 440199); 62 | break; 63 | } 64 | } 65 | 66 | void xybase::MemoryStream::Close() 67 | { 68 | // do nothing. 69 | } 70 | 71 | void xybase::MemoryStream::Write(const char *buffer, size_t limit) 72 | { 73 | if (cursor + limit > size) throw xybase::InvalidParameterException(L"limit", L"Too large.", 440120); 74 | 75 | memcpy(((char *)memoryPivot) + cursor, buffer, limit); 76 | cursor += limit; 77 | } 78 | -------------------------------------------------------------------------------- /lib/xybase/MemoryStream.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef XY_MEMORY_STREAM_H__ 4 | #define XY_MEMORY_STREAM_H__ 5 | #include "xyapi.h" 6 | #include "StreamBasic.h" 7 | namespace xybase 8 | { 9 | class MemoryStream : public StreamBasic 10 | { 11 | protected: 12 | void *memoryPivot; 13 | size_t size; 14 | size_t cursor; 15 | std::u16string name; 16 | 17 | public: 18 | XY_API virtual ~MemoryStream(); 19 | XY_API MemoryStream(void *memoryBasePointer, size_t size, const std::u16string &name); 20 | 21 | XY_API void Flush() override; 22 | XY_API std::u16string GetName() const override; 23 | XY_API void ReadBytes(char *buffer, size_t limit) override; 24 | XY_API size_t Tell() const override; 25 | XY_API bool IsEof() const noexcept override; 26 | XY_API void Seek(long long offset, SeekMode mode) override; 27 | XY_API void Close() override; 28 | XY_API void Write(const char *buffer, size_t limit) override; 29 | }; 30 | } 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /lib/xybase/Singleton.h: -------------------------------------------------------------------------------- 1 | #ifndef XY_SINGLETON_H__ 2 | #define XY_SINGLETON_H__ 3 | 4 | namespace xybase 5 | { 6 | template 7 | class Singleton 8 | { 9 | T inst; 10 | Singleton() {} 11 | public: 12 | static T& GetInstance() 13 | { 14 | static T inst; 15 | return inst; 16 | } 17 | }; 18 | } 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /lib/xybase/Stream.cpp: -------------------------------------------------------------------------------- 1 | #include "Stream.h" 2 | 3 | bool xybase::bigEndianSystem = (*((const uint16_t *)endianTester) == 0xFF00); 4 | 5 | xybase::Stream::~Stream() 6 | { 7 | } 8 | -------------------------------------------------------------------------------- /lib/xybase/Stream.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef XY_STREAM_H__ 4 | #define XY_STREAM_H__ 5 | 6 | #include 7 | #include 8 | 9 | #include "Event.h" 10 | #include "xyapi.h" 11 | 12 | namespace xybase 13 | { 14 | const char endianTester[] = { '\xFF', 0}; 15 | 16 | extern XY_API bool bigEndianSystem; 17 | 18 | /* 19 | * 处理文件I/O的抽象类。用于平台隔离。 20 | * 避免使用C/C++默认的流式I/O来正确处理BE/LE 21 | * 确保上层不需要处理BE/LE、寻址差异等。 22 | */ 23 | class XY_API Stream 24 | { 25 | protected: 26 | 27 | bool isBigEndian = false; 28 | 29 | public: 30 | #pragma warning(push) 31 | // 正常编译总会相同,别叫了 32 | #pragma warning(disable : 4251) 33 | Event OnClose, OnSeek; 34 | #pragma warning(pop) 35 | virtual void Flush() = 0; 36 | 37 | virtual std::u16string GetName() const = 0; 38 | 39 | virtual ~Stream(); 40 | 41 | virtual uint8_t ReadUInt8() = 0; 42 | 43 | virtual int8_t ReadInt8() = 0; 44 | 45 | virtual uint16_t ReadUInt16() = 0; 46 | 47 | virtual int16_t ReadInt16() = 0; 48 | 49 | virtual uint32_t ReadUInt32() = 0; 50 | 51 | virtual int32_t ReadInt32() = 0; 52 | 53 | virtual uint64_t ReadUInt64() = 0; 54 | 55 | virtual int64_t ReadInt64() = 0; 56 | 57 | virtual float ReadFloat() = 0; 58 | 59 | virtual double ReadDouble() = 0; 60 | 61 | [[deprecated]] 62 | virtual std::string ReadString() = 0; 63 | 64 | virtual void ReadBytes(char* buffer, size_t limit) = 0; 65 | 66 | virtual void Write(uint8_t value) = 0; 67 | 68 | virtual void Write(int8_t value) = 0; 69 | 70 | virtual void Write(uint16_t value) = 0; 71 | 72 | virtual void Write(int16_t value) = 0; 73 | 74 | virtual void Write(uint32_t value) = 0; 75 | 76 | virtual void Write(int32_t value) = 0; 77 | 78 | virtual void Write(uint64_t value) = 0; 79 | 80 | virtual void Write(int64_t value) = 0; 81 | 82 | virtual void Write(float value) = 0; 83 | 84 | virtual void Write(double value) = 0; 85 | 86 | [[deprecated]] 87 | virtual void Write(const std::string& value) = 0; 88 | 89 | virtual void Write(const char* buffer, size_t size) = 0; 90 | 91 | virtual size_t Tell() const = 0; 92 | 93 | virtual bool IsEof() const noexcept = 0; 94 | 95 | /** 96 | * @brief 寻址方式(基准) 97 | */ 98 | enum SeekMode 99 | { 100 | SM_BEGIN, 101 | SM_CURRENT, 102 | SM_END 103 | }; 104 | 105 | /** 106 | * @brief 寻址 107 | * @param offset 偏移 108 | * @param mode 寻址模式 109 | */ 110 | virtual void Seek(long long offset, SeekMode mode = SM_BEGIN) = 0; 111 | 112 | virtual void Close() = 0; 113 | }; 114 | } 115 | 116 | #endif -------------------------------------------------------------------------------- /lib/xybase/StreamBasic.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef XY_STREAM_BASIC_H__ 4 | #define XY_STREAM_BASIC_H__ 5 | 6 | #include "StringBuilder.h" 7 | #include "Stream.h" 8 | 9 | #include "xyapi.h" 10 | 11 | namespace xybase 12 | { 13 | /** 14 | * @brief 提供基于ReadBytes和Write的其他函数实现,简化Stream实现类需编写的方法。 15 | */ 16 | class XY_API StreamBasic : public Stream 17 | { 18 | public: 19 | virtual ~StreamBasic(); 20 | virtual uint8_t ReadUInt8() override; 21 | virtual int8_t ReadInt8() override; 22 | virtual uint16_t ReadUInt16() override; 23 | virtual int16_t ReadInt16() override; 24 | virtual uint32_t ReadUInt32() override; 25 | virtual int32_t ReadInt32() override; 26 | virtual uint64_t ReadUInt64() override; 27 | virtual int64_t ReadInt64() override; 28 | virtual float ReadFloat() override; 29 | virtual double ReadDouble() override; 30 | [[deprecated]] 31 | virtual std::string ReadString() override; 32 | virtual void Write(uint8_t value) override; 33 | virtual void Write(int8_t value) override; 34 | virtual void Write(uint16_t value) override; 35 | virtual void Write(int16_t value) override; 36 | virtual void Write(uint32_t value) override; 37 | virtual void Write(int32_t value) override; 38 | virtual void Write(uint64_t value) override; 39 | virtual void Write(int64_t value) override; 40 | virtual void Write(float value) override; 41 | virtual void Write(double value) override; 42 | [[deprecated]] 43 | virtual void Write(const std::string &value) override; 44 | virtual void Write(const char *buffer, size_t limit) override = 0; 45 | }; 46 | } 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /lib/xybase/TextStream.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef XY_TEXT_STREAM 4 | #define XY_TEXT_STREAM 5 | 6 | #include 7 | #include 8 | 9 | #include "Stream.h" 10 | 11 | #include "xyapi.h" 12 | 13 | namespace xybase 14 | { 15 | class TextStream : public Stream 16 | { 17 | std::wstring name; 18 | std::fstream stream; 19 | public: 20 | 21 | XY_API TextStream(std::string path, std::ios::openmode mode, std::string localeStr = {}); 22 | 23 | XY_API virtual ~TextStream(); 24 | 25 | XY_API virtual void Flush() override; 26 | 27 | XY_API void Close() override; 28 | 29 | XY_API virtual std::u16string GetName() const override; 30 | 31 | XY_API virtual bool ReadLine(std::string &out); 32 | 33 | XY_API virtual char ReadChar(); 34 | XY_API virtual uint8_t ReadUInt8() override; 35 | XY_API virtual int8_t ReadInt8() override; 36 | XY_API virtual uint16_t ReadUInt16() override; 37 | XY_API virtual int16_t ReadInt16() override; 38 | XY_API virtual uint32_t ReadUInt32() override; 39 | XY_API virtual int32_t ReadInt32() override; 40 | XY_API virtual uint64_t ReadUInt64() override; 41 | XY_API virtual int64_t ReadInt64() override; 42 | XY_API virtual float ReadFloat() override; 43 | XY_API virtual double ReadDouble() override; 44 | XY_API virtual void Write(char value); 45 | XY_API virtual void Write(uint8_t value) override; 46 | XY_API virtual void Write(int8_t value) override; 47 | XY_API virtual void Write(uint16_t value) override; 48 | XY_API virtual void Write(int16_t value) override; 49 | XY_API virtual void Write(uint32_t value) override; 50 | XY_API virtual void Write(int32_t value) override; 51 | XY_API virtual void Write(uint64_t value) override; 52 | XY_API virtual void Write(int64_t value) override; 53 | XY_API virtual void Write(float value) override; 54 | XY_API virtual void Write(double value) override; 55 | XY_API virtual void Write(const std::string &value) override; 56 | XY_API virtual void Write(const char *value); 57 | XY_API virtual size_t Tell() const override; 58 | XY_API virtual void Seek(long long offset, SeekMode mode) override; 59 | 60 | XY_API virtual bool IsEof() const noexcept override; 61 | private: 62 | XY_API virtual std::string ReadString() override; 63 | 64 | XY_API virtual void ReadBytes(char *buffer, size_t limit) override; 65 | 66 | XY_API virtual void Write(const char *buffer, size_t size) override; 67 | }; 68 | } 69 | 70 | #endif 71 | -------------------------------------------------------------------------------- /lib/xybase/Xml/XmlNode.cpp: -------------------------------------------------------------------------------- 1 | #include "XmlNode.h" 2 | 3 | using namespace xybase::xml; 4 | 5 | const XmlNode XmlNode::ERROR = XmlNode(); 6 | 7 | bool xybase::xml::XmlNode::IsTextNode() const 8 | { 9 | return text.size(); 10 | } 11 | 12 | void xybase::xml::XmlNode::AddChild(XmlNode node) 13 | { 14 | children.push_back(node); 15 | } 16 | 17 | std::list xybase::xml::XmlNode::GetChildren() const 18 | { 19 | return children; 20 | } 21 | 22 | void xybase::xml::XmlNode::AddText(std::u16string str) 23 | { 24 | XmlNode tmp; 25 | tmp.text = str; 26 | AddChild(tmp); 27 | } 28 | 29 | std::u16string xybase::xml::XmlNode::GetText() const 30 | { 31 | return text; 32 | } 33 | 34 | void xybase::xml::XmlNode::SetName(std::u16string name) 35 | { 36 | this->name = name; 37 | } 38 | 39 | std::u16string xybase::xml::XmlNode::GetName() const 40 | { 41 | return name; 42 | } 43 | 44 | void xybase::xml::XmlNode::AddAttribute(std::u16string name, std::u16string data) 45 | { 46 | attributes[name] = data; 47 | } 48 | 49 | std::map xybase::xml::XmlNode::GetAttributes() const 50 | { 51 | return attributes; 52 | } 53 | 54 | std::u16string xybase::xml::XmlNode::GetAttribute(std::u16string name) const 55 | { 56 | auto &&itr = attributes.find(name); 57 | if (itr == attributes.end()) return u""; 58 | else return itr->second; 59 | } 60 | 61 | bool xybase::xml::XmlNode::operator==(const XmlNode &rvalue) const 62 | { 63 | return name == rvalue.name && attributes == rvalue.attributes; 64 | } 65 | 66 | XmlNode &xybase::xml::XmlNode::operator[](std::u16string name) 67 | { 68 | for (auto &&child : children) 69 | { 70 | if (child.name == name) 71 | { 72 | return child; 73 | } 74 | } 75 | 76 | XmlNode tmp; 77 | tmp.name = name; 78 | children.push_back(tmp); 79 | auto &&itr = children.end(); 80 | --itr; 81 | return *itr; 82 | } 83 | -------------------------------------------------------------------------------- /lib/xybase/Xml/XmlNode.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef XY_XML_NODE_H__ 4 | #define XY_XML_NODE_H__ 5 | 6 | #include 7 | #include 8 | #include 9 | #include "../xyapi.h" 10 | 11 | namespace xybase 12 | { 13 | namespace xml 14 | { 15 | /** 16 | * @brief Xml节点 17 | */ 18 | class XY_API XmlNode 19 | { 20 | #pragma warning(push) 21 | #pragma warning(disable: 4251) 22 | public: 23 | bool IsTextNode() const; 24 | 25 | std::list children; 26 | 27 | std::u16string text; 28 | 29 | std::u16string name; 30 | 31 | std::map attributes; 32 | 33 | void AddChild(XmlNode node); 34 | 35 | std::list GetChildren() const; 36 | 37 | void AddText(std::u16string str); 38 | 39 | std::u16string GetText() const; 40 | 41 | void SetName(std::u16string name); 42 | 43 | std::u16string GetName() const; 44 | 45 | void AddAttribute(std::u16string name, std::u16string data); 46 | 47 | std::map GetAttributes() const; 48 | 49 | std::u16string GetAttribute(std::u16string name) const; 50 | 51 | const static XmlNode ERROR; 52 | 53 | bool operator== (const XmlNode &rvalue) const; 54 | 55 | XmlNode &operator[] (std::u16string name); 56 | #pragma warning(pop) 57 | }; 58 | } 59 | } 60 | 61 | #endif // !XY_XML_NODE_H__ 62 | -------------------------------------------------------------------------------- /lib/xybase/xyapi.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef XY_API_H__ 4 | #define XY_API_H__ 5 | 6 | #ifndef XY_DYNAMIC_LIBRARY 7 | 8 | #define XY_API 9 | 10 | #else 11 | 12 | #ifdef WIN32 13 | 14 | #ifdef _MSC_VER 15 | 16 | #ifdef XY_EXPORT_DLL 17 | #define XY_API __declspec(dllexport) 18 | #else 19 | #define XY_API __declspec(dllimport) 20 | #endif 21 | 22 | #elif defined(__GNUC__) 23 | 24 | #ifdef XY_EXPORT_DLL 25 | #define XY_API __attribute__(dllexport) 26 | #else 27 | #define XY_API __attribute__(dllimport) 28 | #endif /*Windows, GCC*/ 29 | 30 | #endif 31 | 32 | #elif defined(linux) 33 | 34 | #if defined(__GNUC__) 35 | #ifdef XY_EXPORT_DLL 36 | #define XY_API __attribute__((visibility ("default"))) 37 | #else 38 | #define XY_API 39 | #endif 40 | #endif /*Linux, GCC*/ 41 | 42 | #endif 43 | 44 | #endif /*XY_STATIC*/ 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /lib/xybase/xyutils.cpp: -------------------------------------------------------------------------------- 1 | #include "xyutils.h" 2 | #include 3 | 4 | #ifdef _WIN32 5 | #include 6 | #include 7 | #else 8 | #include 9 | #include 10 | #endif 11 | 12 | int xybase::io::access(const char *path, AccessMode mode) 13 | { 14 | #ifdef _WIN32 15 | int mode_ = 0; 16 | if (mode & PM_READ) mode_ |= 0x2; 17 | if (mode & PM_WRITE) mode_ |= 0x4; 18 | return ::_access(path, mode_); 19 | #else 20 | int mode_ = 0; 21 | if (mode & PM_EXECUTE) mode_ |= X_OK; 22 | if (mode & PM_READ) mode_ |= R_OK; 23 | if (mode & PM_WRITE) mode_ |= W_OK; 24 | return ::access(path, mode_); 25 | #endif 26 | } 27 | 28 | int xybase::io::mkdir(const char *path) 29 | { 30 | #ifdef _WIN32 31 | return ::_mkdir(path); 32 | #else 33 | return ::mkdir(path, 0755); 34 | #endif 35 | } 36 | 37 | int xybase::io::CreateDirectoryRecursively(const std::string &path, size_t index) 38 | { 39 | size_t endIndex = path.find_first_of('/', index); 40 | 41 | if (endIndex == std::string::npos) 42 | { 43 | if (xybase::io::access(path.c_str(), xybase::io::PM_READ | xybase::io::PM_WRITE)) 44 | { 45 | return xybase::io::mkdir(path.c_str()); 46 | } 47 | } 48 | 49 | std::string curPath = path.substr(0, endIndex); 50 | if (xybase::io::access(curPath.c_str(), xybase::io::PM_READ | xybase::io::PM_WRITE)) 51 | { 52 | xybase::io::mkdir(curPath.c_str()); 53 | } 54 | return CreateDirectoryRecursively(path, endIndex + 1); 55 | } 56 | 57 | int xybase::io::CreateDirectoryRecursively(const char *path) 58 | { 59 | return CreateDirectoryRecursively(path, 0); 60 | } 61 | -------------------------------------------------------------------------------- /lib/xybase/xyutils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef XYUTILS_H__ 4 | #define XYUTILS_H__ 5 | 6 | #define XY_ALIGN(n, b) ((n) < 0 ? (n) & ~((b) - 1) : ((n + (b) - 1) & ~((b) - 1))) 7 | #define XY_MAX(a, b) ((a) > (b) ? (a) : (b)) 8 | #define XY_MIN(a, b) ((a) > (b) ? (b) : (a)) 9 | 10 | #include "xyapi.h" 11 | #include 12 | 13 | namespace xybase 14 | { 15 | namespace io 16 | { 17 | using AccessMode = int; 18 | 19 | const AccessMode PM_READ = 0x1; 20 | const AccessMode PM_WRITE = 0x2; 21 | const AccessMode PM_EXECUTE = 0x4; 22 | 23 | /** 24 | * @brief 获得是否能以指定权限访问指定路径 25 | * @param path 指定路径 26 | * @param mode 要测试的访问权限 27 | * @return 28 | */ 29 | int XY_API access(const char *path, AccessMode mode); 30 | 31 | int XY_API mkdir(const char *path); 32 | 33 | int XY_API CreateDirectoryRecursively(const std::string &path, size_t index = 0); 34 | 35 | int XY_API CreateDirectoryRecursively(const char *path); 36 | } 37 | } 38 | 39 | #endif // !XYUTILS_H__ 40 | -------------------------------------------------------------------------------- /mule/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable (mule "mule.cpp" "mule.h" "crc32.h" "crc32.cpp" "luaenv.cpp" "luaenv.h" "codepage.h" "codepage.cpp" "version.h.in") 2 | 3 | string (TIMESTAMP COMPILE_TIME %Y/%m/%d-%H:%M:%S) 4 | set (BUILD_TIME ${COMPILE_TIME}) 5 | configure_file("${CMAKE_CURRENT_SOURCE_DIR}/version.h.in" "${CMAKE_CURRENT_SOURCE_DIR}/version.h") 6 | 7 | target_link_libraries (mule PRIVATE sis sislua) 8 | 9 | if (CMAKE_VERSION VERSION_GREATER 3.12) 10 | set_property(TARGET mule PROPERTY CXX_STANDARD 20) 11 | endif() 12 | -------------------------------------------------------------------------------- /mule/codepage.cpp: -------------------------------------------------------------------------------- 1 | #include "codepage.h" 2 | #include 3 | #include 4 | 5 | std::string cvt_to_string(const std::wstring &str) 6 | { 7 | return CodeCvt::GetInstance().CvtToString(str); 8 | } 9 | 10 | std::wstring cvt_to_wstring(const std::string &str) 11 | { 12 | return CodeCvt::GetInstance().CvtToWString(str); 13 | } 14 | 15 | #pragma pack(push,1) 16 | struct CodePageEntry 17 | { 18 | uint32_t dbc; 19 | uint32_t wc; 20 | }; 21 | #pragma pack(pop) 22 | 23 | CodeCvt::~CodeCvt() 24 | { 25 | xybase::string::set_string_cvt(nullptr, nullptr); 26 | } 27 | 28 | CodeCvt &CodeCvt::GetInstance() 29 | { 30 | static CodeCvt _inst; 31 | return _inst; 32 | } 33 | 34 | std::string CodeCvt::CvtToString(const std::wstring &str) 35 | { 36 | auto codes = xybase::string::to_utf32(str); 37 | 38 | xybase::StringBuilder sb; 39 | for (char32_t code : str) 40 | { 41 | auto dbc = uc2cp[code]; 42 | if (dbc == 0) 43 | { 44 | dbc = uc2cp[U'〓']; 45 | if (dbc == 0) 46 | { 47 | dbc = uc2cp[U'?']; 48 | } 49 | } 50 | if (dbc > 0xFF) 51 | { 52 | sb.Append((dbc & 0xFF00) >> 8); 53 | sb.Append(dbc & 0xFF); 54 | } 55 | else 56 | { 57 | sb.Append(dbc); 58 | } 59 | } 60 | 61 | return sb.ToString(); 62 | } 63 | 64 | std::wstring CodeCvt::CvtToWString(const std::string &str) 65 | { 66 | xybase::StringBuilder sb; 67 | int current = 0; 68 | for (char ch : str) 69 | { 70 | if (current) 71 | { 72 | auto wc = cp2uc[(current | (ch & 0xFF)) & 0xFFFF]; 73 | if (wc == 0) 74 | { 75 | wc = U'�'; 76 | } 77 | 78 | sb.Append(wc); 79 | current = 0; 80 | } 81 | else 82 | { 83 | if (ch & 0x80) 84 | { 85 | current = ch << 8; 86 | } 87 | else 88 | { 89 | auto wc = cp2uc[ch]; 90 | if (wc == 0) 91 | { 92 | wc = U'�'; 93 | } 94 | 95 | sb.Append(wc); 96 | } 97 | } 98 | } 99 | return xybase::string::to_wstring(sb.ToString()); 100 | } 101 | 102 | void CodeCvt::Init(const char *cp) 103 | { 104 | uc2cp.clear(); 105 | cp2uc.clear(); 106 | uint64_t count = *((uint64_t *)cp); 107 | if (count & 3) abort(); 108 | count >>= 3; 109 | CodePageEntry *cpe = (CodePageEntry *)(cp + sizeof(uint64_t)); 110 | for (uint64_t i = 0; i < count; ++i) 111 | { 112 | if (!uc2cp.contains(cpe[i].wc)) 113 | uc2cp[cpe[i].wc] = cpe[i].dbc; 114 | cp2uc[cpe[i].dbc] = cpe[i].wc; 115 | } 116 | 117 | xybase::string::set_string_cvt(cvt_to_wstring, cvt_to_string); 118 | } 119 | -------------------------------------------------------------------------------- /mule/codepage.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | class CodeCvt 8 | { 9 | std::map uc2cp; 10 | std::map cp2uc; 11 | public: 12 | ~CodeCvt(); 13 | 14 | static CodeCvt &GetInstance(); 15 | 16 | std::string CvtToString(const std::wstring &str); 17 | 18 | std::wstring CvtToWString(const std::string &str); 19 | 20 | void Init(const char *cp); 21 | }; 22 | 23 | std::string cvt_to_string(const std::wstring &str); 24 | 25 | std::wstring cvt_to_wstring(const std::string &str); 26 | -------------------------------------------------------------------------------- /mule/crc32.cpp: -------------------------------------------------------------------------------- 1 | #include "crc32.h" 2 | 3 | uint32_t crctbl[256]; 4 | 5 | uint32_t crc32_eval(const uint8_t *data, size_t size) 6 | { 7 | uint32_t crc = 0xffffffff; 8 | for (size_t i = 0; i < size; ++i) 9 | { 10 | crc = crctbl[(crc ^ data[i]) & 0xff] ^ (crc >> 8); 11 | } 12 | return crc ^ 0xffffffff; 13 | } 14 | 15 | void crc32_init() 16 | { 17 | for (int i = 0; i < 256; ++i) 18 | { 19 | uint32_t crc = (uint32_t)i; 20 | for (int j = 0; j < 8; ++j) 21 | { 22 | crc = crc & 1 ? 0xedb88320 ^ (crc >> 1) : crc >> 1; 23 | } 24 | crctbl[i] = crc; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /mule/crc32.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef CRC32_H 4 | #define CRC32_H 5 | 6 | #include 7 | #include 8 | 9 | uint32_t crc32_eval(const uint8_t *data, size_t size); 10 | 11 | void crc32_init(); 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /mule/luaenv.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "mule.h" 4 | -------------------------------------------------------------------------------- /mule/mule.h: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | #include "crc32.h" 35 | -------------------------------------------------------------------------------- /mule/version.h.in: -------------------------------------------------------------------------------- 1 | #ifndef VERSION_H__ 2 | #define VERSION_H__ 3 | 4 | #define MULE_BUILD_TIME "@BUILD_TIME@" 5 | #define MULE_MAJOR_VERSION @mule_VERSION_MAJOR@ 6 | #define MULE_MINOR_VERSION @mule_VERSION_MINOR@ 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /mulert/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project (mulert VERSION 1.10) 2 | 3 | string (TIMESTAMP COMPILE_TIME %Y/%m/%d-%H:%M:%S) 4 | set (BUILD_TIME ${COMPILE_TIME}) 5 | configure_file(${CMAKE_CURRENT_SOURCE_DIR}/MuleRtVersion.h.in ${CMAKE_CURRENT_SOURCE_DIR}/MuleRtVersion.h) 6 | 7 | set (MULERT_SOURCES "Data/Basic/Type.cpp" "Data/Basic/MultiValue.cpp" "Storage/BinaryData.cpp" "Storage/DataManager.cpp" "Data/TypeCreator.cpp" "Data/TypeManager.cpp" "VirtualFileSystem.cpp" "Mule.cpp" "TranscripterManager.cpp" "Logger.cpp" "Configuration.cpp" "Storage/ResourceManager.cpp" "Data/Array.cpp" "Data/Reference.cpp" "Data/Structure.cpp" "Data/Basic/BasicType.cpp" "Data/Basic/ContextManager.cpp" "Data/Sheet.cpp" "SheetManager.cpp" "SheetReference.cpp" "Data/SmartReference.cpp") 8 | set (MULERT_HEADERS "Data/Basic/Type.h" "Data/Basic/MultiValue.h" "Storage/BinaryData.h" "Storage/DataManager.h" "Data/TypeCreator.h" "Data/TypeManager.h" "mulert_api.h" "VirtualFileSystem.h" "Mule.h" "TranscripterManager.h" "Logger.h" "Configuration.h" "Storage/ResourceManager.h" "Data/Array.h" "Data/Reference.h" "Data/Structure.h" "Data/Basic/BasicType.h" "Data/Basic/ContextManager.h" "Data/Sheet.h" "SheetManager.h" "SheetReference.h" "Data/SmartReference.h" "MuleRtVersion.h") 9 | 10 | add_library (mulert SHARED ${MULERT_SOURCES} ${MULERT_HEADERS}) 11 | add_library (mulert_sta ${MULERT_SOURCES} ${MULERT_HEADERS}) 12 | 13 | target_compile_definitions (mulert PRIVATE MULERT_EXPORTS_DLL) 14 | target_compile_definitions (mulert_sta PUBLIC MULERT_STATIC) 15 | 16 | target_include_directories (mulert INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) 17 | target_include_directories (mulert_sta INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) 18 | 19 | target_link_libraries (mulert PUBLIC xybase_dyn ${CMAKE_DL_LIBS}) 20 | target_link_libraries (mulert_sta PUBLIC xybase ${CMAKE_DL_LIBS}) 21 | 22 | include (GNUInstallDirs) 23 | install (TARGETS mulert DESTINATION ${CMAKE_INSTALL_LIBDIR}/mule) 24 | install (TARGETS mulert_sta DESTINATION ${CMAKE_INSTALL_LIBDIR}/mule) 25 | install (DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/mule FILES_MATCHING PATTERN "*.h") 26 | 27 | if (MSVC) 28 | target_compile_options(mulert PRIVATE "/utf-8") 29 | target_compile_options(mulert_sta PRIVATE "/utf-8") 30 | endif() 31 | 32 | if (CMAKE_VERSION VERSION_GREATER 3.12) 33 | set_property(TARGET mulert PROPERTY CXX_STANDARD 20) 34 | set_property(TARGET mulert_sta PROPERTY CXX_STANDARD 20) 35 | else() 36 | message (FATAL "CMake 3.12 is required!") 37 | endif() 38 | -------------------------------------------------------------------------------- /mulert/Configuration.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "mulert_api.h" 4 | #include "Data/Basic/MultiValue.h" 5 | #include 6 | #include 7 | 8 | namespace mule 9 | { 10 | /** 11 | * @brief 配置提供类 12 | */ 13 | class Configuration 14 | { 15 | std::map variables; 16 | public: 17 | 18 | /** 19 | * @brief 指定的配置项不存在 20 | */ 21 | class ConfigurationNotFoundException : public xybase::RuntimeException 22 | { 23 | public: 24 | MULERT_API ConfigurationNotFoundException(std::wstring name); 25 | 26 | MULERT_API ~ConfigurationNotFoundException(); 27 | }; 28 | 29 | /** 30 | * @brief 指定的配置项中存在不符合的类型数据 31 | */ 32 | class ConfigurationTypeMismatch : public xybase::RuntimeException 33 | { 34 | public: 35 | MULERT_API ConfigurationTypeMismatch(std::wstring name); 36 | 37 | MULERT_API ~ConfigurationTypeMismatch(); 38 | }; 39 | 40 | MULERT_API static Configuration &GetInstance(); 41 | 42 | MULERT_API std::u16string ResolveVariable(const std::u16string &str); 43 | 44 | MULERT_API void ResetVariable(const char16_t *name); 45 | 46 | MULERT_API void SetVariable(const char16_t *name, mule::Data::Basic::MultiValue value); 47 | 48 | MULERT_API void SetVariable(const char16_t *name, unsigned long long uval); 49 | 50 | MULERT_API void SetVariable(const char16_t *name, long long val); 51 | 52 | MULERT_API void SetVariable(const char16_t *name, double rval); 53 | 54 | MULERT_API void SetVariable(const char16_t *name, const char16_t *sval); 55 | 56 | MULERT_API Data::Basic::MultiValue GetVariable(const char16_t *name); 57 | 58 | MULERT_API const std::u16string GetString(const char16_t *name); 59 | 60 | MULERT_API double GetReal(const char16_t *name, double def = 0.0); 61 | 62 | MULERT_API long long GetSigned(const char16_t *name, long long def = 0); 63 | 64 | MULERT_API unsigned long long GetUnsigned(const char16_t *name, unsigned long long def = 0); 65 | 66 | MULERT_API bool IsExist(const char16_t *name); 67 | }; 68 | } 69 | -------------------------------------------------------------------------------- /mulert/Data/Array.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef ARRAY_H__ 4 | #define ARRAY_H__ 5 | 6 | #include "../mulert_api.h" 7 | #include 8 | #include "Basic/Type.h" 9 | #include "TypeCreator.h" 10 | #include "TypeManager.h" 11 | 12 | namespace mule 13 | { 14 | namespace Data 15 | { 16 | class Array : public Basic::Type 17 | { 18 | protected: 19 | std::u16string sizeCache; 20 | 21 | size_t length; 22 | 23 | Basic::Type *innerObject; 24 | 25 | Array(); 26 | 27 | public: 28 | class MULERT_API ArrayCreator : public TypeCreator 29 | { 30 | public: 31 | virtual Basic::Type *DoCreateObject(const std::u16string &info) override; 32 | }; 33 | 34 | MULERT_API virtual void Read(xybase::Stream *stream, DataHandler *dataHandler) override; 35 | MULERT_API virtual void Write(xybase::Stream *stream, FileHandler *fileHandler) override; 36 | MULERT_API virtual size_t Size() const override; 37 | MULERT_API virtual std::u16string GetDataType() const override; 38 | 39 | MULERT_API virtual bool IsComposite() const override; 40 | }; 41 | } 42 | } 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /mulert/Data/Basic/BasicType.cpp: -------------------------------------------------------------------------------- 1 | #include "BasicType.h" 2 | 3 | mule::Data::Basic::BasicType::ConstraintViolationException::ConstraintViolationException(const std::wstring &msg) 4 | : xybase::RuntimeException(msg, 0xFC0E) 5 | {} 6 | 7 | mule::Data::Basic::BasicType::ConstraintViolationException::~ConstraintViolationException() 8 | { 9 | } 10 | 11 | void mule::Data::Basic::BasicType::Read(xybase::Stream *stream, DataHandler *dataHandler) 12 | { 13 | auto val = DoRead(stream); 14 | if (!cacheVariableName.empty()) 15 | { 16 | ContextManager::GetInstance().SetVariable(cacheVariableName, val); 17 | } 18 | dataHandler->OnDataRead(val); 19 | DoConstraintCheck(val); 20 | } 21 | 22 | void mule::Data::Basic::BasicType::Write(xybase::Stream *stream, FileHandler * fileHandler) 23 | { 24 | MultiValue value = fileHandler->OnDataWrite(); 25 | if (!cacheVariableName.empty()) 26 | { 27 | ContextManager::GetInstance().SetVariable(cacheVariableName, value); 28 | } 29 | DoWrite(stream, value); 30 | DoConstraintCheck(value); 31 | } 32 | 33 | void mule::Data::Basic::BasicType::DoConstraintCheck(const MultiValue &value) 34 | { 35 | switch (constraintType) 36 | { 37 | case mule::Data::Basic::BasicType::BTCT_NONE: 38 | return; 39 | break; 40 | case mule::Data::Basic::BasicType::BTCT_EQ: 41 | if (value != comparator) throw ConstraintViolationException(L"Not equal"); 42 | break; 43 | case mule::Data::Basic::BasicType::BTCT_LT: 44 | if (value >= comparator) throw ConstraintViolationException(L"Not less than"); 45 | break; 46 | case mule::Data::Basic::BasicType::BTCT_GT: 47 | if (value <= comparator) throw ConstraintViolationException(L"Not grater than"); 48 | break; 49 | case mule::Data::Basic::BasicType::BTCT_NEQ: 50 | if (value == comparator) throw ConstraintViolationException(L"Equal"); 51 | break; 52 | case mule::Data::Basic::BasicType::BTCT_NLT: 53 | if (value < comparator) throw ConstraintViolationException(L"Less than"); 54 | break; 55 | case mule::Data::Basic::BasicType::BTCT_NGT: 56 | if (value > comparator) throw ConstraintViolationException(L"Grater than"); 57 | break; 58 | default: 59 | throw xybase::InvalidOperationException(L"Invalid constraint type.", 0x8F52); 60 | break; 61 | } 62 | } 63 | 64 | mule::Data::Basic::BasicType::~BasicType() 65 | { 66 | } 67 | -------------------------------------------------------------------------------- /mulert/Data/Basic/BasicType.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef BASIC_TYPE_H__ 4 | #define BASIC_TYPE_H__ 5 | 6 | #include 7 | 8 | #include "../../mulert_api.h" 9 | #include "Type.h" 10 | #include "ContextManager.h" 11 | 12 | namespace mule 13 | { 14 | namespace Data 15 | { 16 | namespace Basic 17 | { 18 | class BasicType : public Type 19 | { 20 | 21 | protected: 22 | MULERT_API void DoConstraintCheck(const MultiValue &value); 23 | 24 | public: 25 | 26 | MULERT_API virtual MultiValue DoRead(xybase::Stream *stream) = 0; 27 | 28 | MULERT_API virtual void DoWrite(xybase::Stream *stream, const MultiValue &value) = 0; 29 | 30 | 31 | MULERT_API virtual ~BasicType(); 32 | 33 | enum ConstraintType 34 | { 35 | BTCT_NONE, 36 | BTCT_EQ, 37 | BTCT_LT, 38 | BTCT_GT, 39 | BTCT_NEQ, 40 | BTCT_NLT, 41 | BTCT_NGT 42 | } constraintType = BTCT_NONE; 43 | 44 | MultiValue comparator = MultiValue::MV_NULL; 45 | 46 | class ConstraintViolationException : public xybase::RuntimeException 47 | { 48 | public: 49 | MULERT_API ConstraintViolationException(const std::wstring &msg); 50 | 51 | MULERT_API ~ConstraintViolationException(); 52 | }; 53 | 54 | std::u16string cacheVariableName; 55 | 56 | MULERT_API virtual void Read(xybase::Stream *stream, DataHandler *dataHandler) override; 57 | 58 | MULERT_API virtual void Write(xybase::Stream *stream, FileHandler *fileHandler) override; 59 | }; 60 | } 61 | } 62 | } 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /mulert/Data/Basic/ContextManager.cpp: -------------------------------------------------------------------------------- 1 | #include "ContextManager.h" 2 | 3 | using namespace mule::Data::Basic; 4 | 5 | ContextManager &ContextManager::GetInstance() 6 | { 7 | static ContextManager _inst; 8 | return _inst; 9 | } 10 | 11 | void ContextManager::SetVariable(const std::u16string &name, const mule::Data::Basic::MultiValue &value) 12 | { 13 | variables[name] = value; 14 | } 15 | 16 | const mule::Data::Basic::MultiValue &ContextManager::GetVariable(const std::u16string &name) 17 | { 18 | return variables[name]; 19 | } 20 | -------------------------------------------------------------------------------- /mulert/Data/Basic/ContextManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef CONTEXT_MANAGER_H__ 4 | #define CONTEXT_MANAGER_H__ 5 | 6 | #include 7 | #include 8 | 9 | #include "../../mulert_api.h" 10 | #include "MultiValue.h" 11 | 12 | namespace mule 13 | { 14 | namespace Data 15 | { 16 | namespace Basic 17 | { 18 | /** 19 | * @brief 为各个类型提供上下文保存能力:各类型自行决定是否保存该信息,或是否能够保存该信息。 20 | * Provides context for types. Each type decides if context information should be saved. 21 | */ 22 | class ContextManager 23 | { 24 | protected: 25 | std::map variables; 26 | public: 27 | MULERT_API static ContextManager &GetInstance(); 28 | 29 | MULERT_API void SetVariable(const std::u16string &name, const mule::Data::Basic::MultiValue &value); 30 | 31 | MULERT_API const mule::Data::Basic::MultiValue &GetVariable(const std::u16string &name); 32 | }; 33 | } 34 | } 35 | } 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /mulert/Data/Basic/Type.cpp: -------------------------------------------------------------------------------- 1 | #include "Type.h" 2 | 3 | mule::Data::Basic::Type::~Type() 4 | { 5 | } 6 | 7 | size_t mule::Data::Basic::Type::GetLastSize() const 8 | { 9 | return Size(); 10 | } 11 | 12 | size_t mule::Data::Basic::Type::EvalSize(const MultiValue &obj) const 13 | { 14 | return Size(); 15 | } 16 | 17 | bool mule::Data::Basic::Type::IsComposite() const 18 | { 19 | return false; 20 | } 21 | 22 | mule::Data::Basic::Type::DataHandler::~DataHandler() 23 | { 24 | } 25 | 26 | void mule::Data::Basic::Type::DataHandler::AppendMetadata(std::map metadata) 27 | { 28 | for (auto &datum : metadata) 29 | { 30 | AppendMetadatum(datum.first, datum.second); 31 | } 32 | } 33 | 34 | void mule::Data::Basic::Type::DataHandler::AppendMetadatum(std::u16string name, const MultiValue &value) 35 | { 36 | } 37 | 38 | void mule::Data::Basic::Type::DataHandler::SetOutStream(xybase::TextStream *stream) 39 | { 40 | outstream = stream; 41 | } 42 | 43 | mule::Data::Basic::Type::Handler::~Handler() 44 | { 45 | } 46 | 47 | mule::Data::Basic::Type::FileHandler::~FileHandler() 48 | { 49 | } 50 | 51 | void mule::Data::Basic::Type::FileHandler::SetInStream(xybase::TextStream *stream) 52 | { 53 | instream = stream; 54 | } 55 | -------------------------------------------------------------------------------- /mulert/Data/Reference.h: -------------------------------------------------------------------------------- 1 | #ifndef REFERRENCE_FIELD_H__ 2 | #define REFERRENCE_FIELD_H__ 3 | 4 | #pragma once 5 | 6 | #include 7 | #include 8 | #include "../mulert_api.h" 9 | #include "Basic/Type.h" 10 | #include "TypeCreator.h" 11 | #include "TypeManager.h" 12 | #include "../Logger.h" 13 | 14 | namespace mule 15 | { 16 | namespace Data 17 | { 18 | /** 19 | * @brief 指向其他位置的32位引用类型。 20 | */ 21 | class Reference : public Basic::Type 22 | { 23 | /** 24 | * @brief 内部的类型。 25 | */ 26 | Basic::Type *referent = nullptr; 27 | 28 | Logger logger = Logger::GetLogger(); 29 | 30 | Reference(Type *referent); 31 | 32 | long long ptrRejectValue = -1; 33 | bool ptrReject = false; 34 | 35 | class ReferenceRegistry 36 | { 37 | ReferenceRegistry(); 38 | 39 | std::map> records; 40 | 41 | public: 42 | static ReferenceRegistry &GetInstance(); 43 | 44 | void RemoveStream(xybase::Stream *sender); 45 | 46 | bool IsRegistered(xybase::Stream *stream, size_t loc); 47 | 48 | void Register(xybase::Stream *stream, size_t loc); 49 | }; 50 | public: 51 | class MULERT_API ReferenceCreator : public TypeCreator 52 | { 53 | virtual Basic::Type *DoCreateObject(const std::u16string &info) override; 54 | virtual Basic::Type *DoCreateObject(const std::u16string &info, const std::map &metainfo) override; 55 | }; 56 | 57 | MULERT_API virtual void Read(xybase::Stream *stream, Basic::Type::DataHandler *dataHandler) override; 58 | MULERT_API virtual void Write(xybase::Stream *stream, Basic::Type::FileHandler *fileHandler) override; 59 | MULERT_API virtual size_t Size() const override; 60 | MULERT_API virtual std::u16string GetDataType() const override; 61 | MULERT_API virtual bool IsComposite() const override; 62 | }; 63 | } 64 | } 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /mulert/Data/Sheet.cpp: -------------------------------------------------------------------------------- 1 | #include "Sheet.h" 2 | #include "Basic/BasicType.h" 3 | #include "../Configuration.h" 4 | 5 | using namespace mule::Data::Basic; 6 | 7 | mule::Data::Sheet::Sheet(Basic::Type *infraType, size_t offset, size_t length, std::u16string name) 8 | : infraType(infraType), offset(offset), length(length), name(name) 9 | { 10 | if (infraType == nullptr) throw xybase::InvalidParameterException(L"sheet", L"Given type is nullptr", 35002); 11 | structureSimplifySuppression = (int)Configuration::GetInstance().GetSigned(u"mule.data.sheet.structure-simplify-suppression", 0); 12 | } 13 | 14 | const std::u16string &mule::Data::Sheet::GetName() const 15 | { 16 | return name; 17 | } 18 | 19 | size_t mule::Data::Sheet::Size() const 20 | { 21 | if (infraType->Size() == (size_t)-1) return (size_t)-1; 22 | return infraType->Size() * length; 23 | } 24 | 25 | std::u16string mule::Data::Sheet::GetDataType() const 26 | { 27 | return std::u16string(u"sheet/" + name); 28 | } 29 | 30 | bool mule::Data::Sheet::IsComposite() const 31 | { 32 | if (length == 1) return infraType->IsComposite(); 33 | return true; 34 | } 35 | 36 | void mule::Data::Sheet::Read(xybase::Stream *stream, mule::Data::Basic::Type::DataHandler *dataHandler) 37 | { 38 | Configuration::GetInstance().SetVariable(u"mule.data.sheet.name", name); 39 | dataHandler->OnRealmEnter(this, name); 40 | stream->Seek(offset, xybase::Stream::SeekMode::SM_BEGIN); 41 | if (length == 1 && !structureSimplifySuppression) 42 | infraType->Read(stream, dataHandler); 43 | else for (size_t i = 0; i < length; ++i) { 44 | Configuration::GetInstance().SetVariable(u"mule.data.sheet.index", (long long)i); 45 | dataHandler->OnRealmEnter(infraType, (int)i); 46 | try 47 | { 48 | infraType->Read(stream, dataHandler); 49 | } 50 | catch (mule::Data::Basic::BasicType::ConstraintViolationException) 51 | { 52 | dataHandler->OnRealmExit(infraType, (int)i); 53 | break; 54 | } 55 | dataHandler->OnRealmExit(infraType, (int)i); 56 | } 57 | dataHandler->OnRealmExit(this, name); 58 | Configuration::GetInstance().ResetVariable(u"mule.data.sheet.index"); 59 | Configuration::GetInstance().ResetVariable(u"mule.data.sheet.name"); 60 | } 61 | 62 | void mule::Data::Sheet::Write(xybase::Stream *stream, mule::Data::Basic::Type::FileHandler *fileHandler) 63 | { 64 | Configuration::GetInstance().SetVariable(u"mule.data.sheet.name", name); 65 | fileHandler->OnRealmEnter(this, name); 66 | stream->Seek(offset, xybase::Stream::SeekMode::SM_BEGIN); 67 | if (length == 1 && !structureSimplifySuppression) 68 | infraType->Write(stream, fileHandler); 69 | else for (size_t i = 0; i < length; ++i) { 70 | Configuration::GetInstance().SetVariable(u"mule.data.sheet.index", (long long)i); 71 | fileHandler->OnRealmEnter(infraType, (int)i); 72 | try 73 | { 74 | infraType->Write(stream, fileHandler); 75 | } 76 | catch (mule::Data::Basic::BasicType::ConstraintViolationException) 77 | { 78 | fileHandler->OnRealmExit(infraType, (int)i); 79 | break; 80 | } 81 | fileHandler->OnRealmExit(infraType, (int)i); 82 | } 83 | fileHandler->OnRealmExit(this, name); 84 | Configuration::GetInstance().ResetVariable(u"mule.data.sheet.index"); 85 | Configuration::GetInstance().ResetVariable(u"mule.data.sheet.name"); 86 | } 87 | -------------------------------------------------------------------------------- /mulert/Data/Sheet.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Basic/Type.h" 4 | 5 | namespace mule 6 | { 7 | namespace Data 8 | { 9 | /** 10 | * @brief 表示一个数据表。 11 | */ 12 | class Sheet : public Basic::Type 13 | { 14 | Basic::Type *infraType; 15 | size_t length; 16 | size_t offset; 17 | std::u16string name; 18 | int structureSimplifySuppression; 19 | public: 20 | MULERT_API Sheet(Basic::Type *infraType, size_t offset, size_t length, std::u16string name); 21 | 22 | MULERT_API const std::u16string &GetName() const; 23 | MULERT_API size_t Size() const override; 24 | MULERT_API std::u16string GetDataType() const override; 25 | MULERT_API bool IsComposite() const override; 26 | MULERT_API void Read(xybase::Stream *stream, mule::Data::Basic::Type::DataHandler *dataHandler) override; 27 | MULERT_API void Write(xybase::Stream *stream, mule::Data::Basic::Type::FileHandler *fileHandler) override; 28 | }; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /mulert/Data/SmartReference.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../mulert_api.h" 4 | #include "Basic/BasicType.h" 5 | #include "TypeCreator.h" 6 | #include "../Logger.h" 7 | #include 8 | 9 | namespace mule 10 | { 11 | namespace Data 12 | { 13 | class SmartReference : public Basic::BasicType 14 | { 15 | protected: 16 | /** 17 | * @brief 内部的类型。 18 | */ 19 | Basic::BasicType *referent = nullptr; 20 | 21 | int GetAlign() const; 22 | public: 23 | class MemoryManager 24 | { 25 | mule::Logger logger = mule::Logger::GetLogger(); 26 | 27 | std::map memories; 28 | 29 | std::map>> assignedAddresses; 30 | 31 | MemoryManager(); 32 | public: 33 | 34 | MULERT_API void DisposeStreamRecords(xybase::Stream *stream); 35 | 36 | MULERT_API static MemoryManager &GetInstance(); 37 | 38 | MULERT_API xybase::Fragment::FragmentManager &GetMemory(xybase::Stream *stream); 39 | 40 | MULERT_API size_t AssignFor(xybase::Stream *stream, const mule::Data::Basic::MultiValue &value, mule::Data::Basic::BasicType *type, size_t size, int align); 41 | 42 | MULERT_API bool IsAssigned(xybase::Stream *stream, const mule::Data::Basic::MultiValue &value, mule::Data::Basic::BasicType *type); 43 | 44 | MULERT_API void SaveFreeSpace(); 45 | }; 46 | 47 | MULERT_API SmartReference(Basic::BasicType *referent); 48 | 49 | MULERT_API size_t Size() const override; 50 | 51 | MULERT_API std::u16string GetDataType() const override; 52 | 53 | MULERT_API Basic::MultiValue DoRead(xybase::Stream *stream) override; 54 | 55 | MULERT_API void DoWrite(xybase::Stream *stream, const Basic::MultiValue &value) override; 56 | 57 | MULERT_API bool IsComposite() const override; 58 | 59 | class MULERT_API SmartReferenceCreator : public TypeCreator 60 | { 61 | public: 62 | 63 | mule::Data::Basic::Type *DoCreateObject(const std::u16string &info) override; 64 | mule::Data::Basic::Type *DoCreateObject(const std::u16string &info, const std::map &metainfo) override; 65 | }; 66 | 67 | }; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /mulert/Data/Structure.cpp: -------------------------------------------------------------------------------- 1 | #include "Structure.h" 2 | 3 | #include "Basic/BasicType.h" 4 | 5 | using namespace mule::Data; 6 | using namespace mule::Data::Basic; 7 | 8 | Structure::Structure(std::u16string name) : name(name) 9 | { 10 | } 11 | 12 | mule::Data::Structure::~Structure() 13 | { 14 | for (Field *field : fields) 15 | { 16 | delete field; 17 | } 18 | } 19 | 20 | void Structure::AppendField(const std::u16string &name, Type * field) 21 | { 22 | fields.push_back(new Field(name, field)); 23 | } 24 | 25 | void Structure::Read(xybase::Stream *stream, DataHandler *dataHandler) 26 | { 27 | for (Field *field : fields) 28 | { 29 | field->Read(stream, dataHandler); 30 | } 31 | } 32 | 33 | void Structure::Write(xybase::Stream *stream, FileHandler * fileHandler) 34 | { 35 | for (Field *field : fields) 36 | { 37 | field->Write(stream, fileHandler); 38 | } 39 | } 40 | 41 | size_t Structure::Size() const 42 | { 43 | size_t size = 0; 44 | for (Type *obj : fields) 45 | { 46 | if (obj->Size() == -1) 47 | return -1; 48 | size += obj->Size(); 49 | } 50 | return size; 51 | } 52 | 53 | std::u16string mule::Data::Structure::GetName() const 54 | { 55 | return name; 56 | } 57 | 58 | std::u16string mule::Data::Structure::GetDataType() const 59 | { 60 | return name; 61 | } 62 | 63 | bool mule::Data::Structure::IsComposite() const 64 | { 65 | return true; 66 | } 67 | 68 | void mule::Data::Structure::Field::Read(xybase::Stream *stream, DataHandler *dataHandler) 69 | { 70 | dataHandler->OnRealmEnter(object, name); 71 | try 72 | { 73 | object->Read(stream, dataHandler); 74 | } 75 | catch (BasicType::ConstraintViolationException &ex) 76 | { 77 | dataHandler->OnRealmExit(object, name); 78 | throw BasicType::ConstraintViolationException(ex.GetMessage()); 79 | } 80 | dataHandler->OnRealmExit(object, name); 81 | } 82 | 83 | void mule::Data::Structure::Field::Write(xybase::Stream *stream, FileHandler * fileHandler) 84 | { 85 | fileHandler->OnRealmEnter(object, name); 86 | try 87 | { 88 | object->Write(stream, fileHandler); 89 | } 90 | catch (BasicType::ConstraintViolationException &ex) 91 | { 92 | fileHandler->OnRealmExit(object, name); 93 | throw BasicType::ConstraintViolationException(ex.GetMessage()); 94 | } 95 | fileHandler->OnRealmExit(object, name); 96 | } 97 | 98 | size_t mule::Data::Structure::Field::Size() const 99 | { 100 | return object->Size(); 101 | } 102 | 103 | const std::u16string &mule::Data::Structure::Field::GetName() const 104 | { 105 | return name; 106 | } 107 | 108 | const Type *const mule::Data::Structure::Field::GetObject() const 109 | { 110 | return object; 111 | } 112 | 113 | mule::Data::Structure::Field::Field(std::u16string name, Type *obj) 114 | : name(name), object(obj) 115 | { 116 | } 117 | 118 | mule::Data::Structure::Field::~Field() 119 | { 120 | } 121 | 122 | std::u16string mule::Data::Structure::Field::GetDataType() const 123 | { 124 | return u"field/" + object->GetDataType(); 125 | } 126 | -------------------------------------------------------------------------------- /mulert/Data/Structure.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef STRUCTURE_H__ 4 | #define STRUCTURE_H__ 5 | 6 | #include "Basic/Type.h" 7 | #include "../mulert_api.h" 8 | #include 9 | 10 | namespace mule 11 | { 12 | namespace Data 13 | { 14 | /** 15 | * @brief 结构体类。包含多个字段的集合,按顺序依次触发字段区域的进出,并触发字段对应类型的读写。 16 | * 任何新建的结构体理应被注册到ObjectManager以提供Reference可见性。 17 | */ 18 | class Structure : public Basic::Type 19 | { 20 | public: 21 | /** 22 | * @brief 字段。结构体内部类。用于触发字段的进出事件和读写事件。 23 | * 一个结构体持有多个字段类,并有结构体负责生命周期。 24 | */ 25 | class Field : public Basic::Type 26 | { 27 | public: 28 | MULERT_API virtual void Read(xybase::Stream *stream, DataHandler *dataHandler) override; 29 | MULERT_API virtual void Write(xybase::Stream *stream, FileHandler *fileHandler) override; 30 | MULERT_API virtual size_t Size() const override; 31 | 32 | MULERT_API const std::u16string &GetName() const; 33 | MULERT_API const Type *const GetObject() const; 34 | 35 | MULERT_API Field(std::u16string name, Type *obj); 36 | MULERT_API ~Field(); 37 | protected: 38 | /** 39 | * @brief 字段的名字 40 | */ 41 | std::u16string name; 42 | 43 | /** 44 | * @brief 字段读写事件触发时,处理事件的类型实例 45 | */ 46 | Type *object; 47 | 48 | virtual std::u16string GetDataType() const override; 49 | }; 50 | 51 | /** 52 | * @brief 初始化一个新的结构 53 | * @param name 名字 54 | */ 55 | MULERT_API Structure(std::u16string name); 56 | 57 | MULERT_API virtual ~Structure(); 58 | 59 | /** 60 | * @brief 在结构体尾部附加一个字段 61 | * @param name 字段的名字 62 | * @param field 字段处理器的实例 63 | */ 64 | MULERT_API void AppendField(const std::u16string &name, mule::Data::Basic::Type *field); 65 | 66 | /** 67 | * @brief 对指定的流进行读取 68 | * @param stream 要进行读取的流 69 | * @param dataHandler 数据处理器 70 | */ 71 | MULERT_API virtual void Read(xybase::Stream *stream, Basic::Type::DataHandler *dataHandler) override; 72 | 73 | /** 74 | * @brief 对指定的流进行写入 75 | * @param stream 要进行写入的流 76 | * @param dataHandler 数据处理器 77 | */ 78 | MULERT_API virtual void Write(xybase::Stream *stream, Basic::Type::FileHandler *fileHandler) override; 79 | 80 | /** 81 | * @brief 获取结构体整体大小 82 | * @return 结构体整体的大小 83 | */ 84 | MULERT_API virtual size_t Size() const override; 85 | 86 | MULERT_API virtual std::u16string GetName() const; 87 | 88 | MULERT_API virtual std::u16string GetDataType() const override; 89 | 90 | MULERT_API virtual bool IsComposite() const override; 91 | protected: 92 | 93 | /** 94 | * @brief 结构体中的字段 95 | */ 96 | std::list fields; 97 | 98 | /** 99 | * @brief 结构体自身的名字(类型名) 100 | */ 101 | std::u16string name; 102 | }; 103 | } 104 | } 105 | 106 | #endif -------------------------------------------------------------------------------- /mulert/Data/TypeCreator.cpp: -------------------------------------------------------------------------------- 1 | #include "TypeCreator.h" 2 | 3 | #include 4 | 5 | using namespace mule::Data; 6 | using namespace mule::Data::Basic; 7 | 8 | mule::Data::TypeCreator::~TypeCreator() 9 | { 10 | } 11 | 12 | TypeCreator::TypeCreator() 13 | { 14 | nextCreator = nullptr; 15 | } 16 | 17 | TypeCreator::TypeCreator(TypeCreator* next) 18 | { 19 | nextCreator = next; 20 | } 21 | 22 | TypeCreator::TypeCreator(TypeCreator& pattern) 23 | { 24 | this->nextCreator = pattern.nextCreator; 25 | } 26 | 27 | void mule::Data::TypeCreator::AppendCreator(mule::Data::TypeCreator *nextCreator) 28 | { 29 | if (this->nextCreator != nullptr) this->nextCreator->AppendCreator(nextCreator); 30 | else this->nextCreator = nextCreator; 31 | } 32 | 33 | Type* TypeCreator::CreateType(const std::u16string & info) 34 | { 35 | Type* result = DoCreateObject(info); 36 | if (result != nullptr) return result; 37 | 38 | if (nextCreator != nullptr) return nextCreator->CreateType(info); 39 | return nullptr; 40 | } 41 | 42 | Type *TypeCreator::CreateType(const std::u16string & info, const std::map & metainfo) 43 | { 44 | Type *result = DoCreateObject(info, metainfo); 45 | if (result != nullptr) return result; 46 | 47 | if (nextCreator != nullptr) return nextCreator->CreateType(info, metainfo); 48 | return nullptr; 49 | } 50 | 51 | Basic::Type *mule::Data::TypeCreator::DoCreateObject(const std::u16string &info, const std::map & metainfo) 52 | { 53 | return DoCreateObject(info); 54 | } 55 | -------------------------------------------------------------------------------- /mulert/Data/TypeCreator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef TYPE_CREATOR_H__ 4 | #define TYPE_CREATOR_H__ 5 | 6 | #include 7 | 8 | #include "Basic/Type.h" 9 | 10 | #include "../mulert_api.h" 11 | 12 | namespace mule 13 | { 14 | namespace Data 15 | { 16 | 17 | /** 18 | * @brief 字段创建器,ObjectManager用 19 | */ 20 | class MULERT_API TypeCreator 21 | { 22 | public: 23 | virtual ~TypeCreator(); 24 | 25 | TypeCreator(); 26 | 27 | TypeCreator(TypeCreator *next); 28 | 29 | TypeCreator(TypeCreator &pattern); 30 | 31 | mule::Data::TypeCreator *nextCreator; 32 | 33 | /** 34 | * @brief Append a creator to the end of the chain. 35 | * @param nextCreator The creator needs to be appended. 36 | */ 37 | void AppendCreator(mule::Data::TypeCreator *nextCreator); 38 | 39 | /** 40 | * @brief Try to create a field handler by given information. 41 | * @param info 42 | * @return The created Type, nullptr if failed to create. 43 | */ 44 | mule::Data::Basic::Type *CreateType(const std::u16string & info); 45 | 46 | /** 47 | * @brief Try to create a type handler by given information. 48 | * @param name The name of the type 49 | * @param extraInfo The extra creation information 50 | * @return The created Type, nullptr if failed to create. 51 | */ 52 | mule::Data::Basic::Type *CreateType(const std::u16string & info, const std::map & metainfo); 53 | 54 | protected: 55 | // Return nullptr so that flow can move to the next ring of chain-of-responsibility 56 | virtual mule::Data::Basic::Type *DoCreateObject(const std::u16string &info) = 0; 57 | 58 | // Return nullptr so that flow can move to the next ring of chain-of-responsibility 59 | virtual mule::Data::Basic::Type *DoCreateObject(const std::u16string &info, const std::map & metainfo); 60 | }; 61 | } 62 | } 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /mulert/Data/TypeManager.cpp: -------------------------------------------------------------------------------- 1 | #include "TypeManager.h" 2 | #include "xystring.h" 3 | using namespace mule::Data; 4 | 5 | TypeManager::TypeManager() 6 | { 7 | first = last = nullptr; 8 | } 9 | 10 | TypeManager::~TypeManager() 11 | { 12 | for (auto &object : objects) 13 | { 14 | delete object.second; 15 | } 16 | objects.clear(); 17 | } 18 | 19 | TypeManager &TypeManager::GetInstance() 20 | { 21 | static TypeManager _inst; 22 | return _inst; 23 | } 24 | 25 | void TypeManager::RegisterObject(Basic::Type *object, std::u16string name) 26 | { 27 | logger.Info(L"External object {}({}) registered.", xybase::string::to_wstring(name), xybase::string::to_wstring(object->GetDataType())); 28 | objects[name] = object; 29 | } 30 | 31 | void TypeManager::UnregisterObject(std::u16string name) 32 | { 33 | objects.erase(name); 34 | } 35 | 36 | void TypeManager::ReleaseObject(std::u16string name) 37 | { 38 | if (objects.contains(name)) { 39 | delete objects[name]; 40 | objects.erase(name); 41 | } 42 | } 43 | 44 | void TypeManager::RegisterObjectCreator(TypeCreator *creator) 45 | { 46 | if (last == nullptr) 47 | { 48 | first = last = creator; 49 | while (creator->nextCreator != nullptr) 50 | { 51 | creator = last = creator->nextCreator; 52 | } 53 | return; 54 | } 55 | 56 | last->nextCreator = creator; 57 | while (last->nextCreator != nullptr) 58 | { 59 | last = last->nextCreator; 60 | } 61 | } 62 | 63 | Basic::Type *TypeManager::GetOrCreateType(std::u16string info) 64 | { 65 | // 若已经存在则直接返回 66 | if (objects.contains(info)) return objects[info]; 67 | 68 | // 若没有创建器则直接返回 69 | if (first == nullptr) return nullptr; 70 | 71 | auto ret = first->CreateType(info); 72 | if (ret == nullptr) 73 | { 74 | logger.Error(L"Failed to create type {}", xybase::string::to_wstring(info)); 75 | } 76 | 77 | logger.Info(L"New type {} is registered.", xybase::string::to_wstring(info)); 78 | 79 | // 保存创建结果并返回 80 | return objects[info] = ret; 81 | } 82 | 83 | Basic::Type *mule::Data::TypeManager::GetOrCreateType(std::u16string name, const std::map &metainfo) 84 | { 85 | // 若元参数为空则直接返回 86 | if (metainfo.empty()) return GetOrCreateType(name); 87 | 88 | // 若没有创建器则直接返回 89 | if (first == nullptr) return nullptr; 90 | 91 | auto mangledName = name + u"%$%"; 92 | for (auto &&pair : metainfo) 93 | { 94 | mangledName += pair.first + u"%:%" + pair.second + u"%;%"; 95 | } 96 | 97 | if (objects.contains(mangledName)) return objects[mangledName]; 98 | 99 | logger.Info(L"New type {}[mangled] registered.", xybase::string::to_wstring(mangledName)); 100 | // 返回创建结果 101 | return objects[mangledName] = first->CreateType(name, metainfo); 102 | } 103 | 104 | Basic::Type *TypeManager::GetType(std::u16string name) 105 | { 106 | if (objects.contains(name)) return objects[name]; 107 | 108 | logger.Error(L"Requested type {} has not registered yet.", xybase::string::to_wstring(name)); 109 | return nullptr; 110 | } 111 | 112 | -------------------------------------------------------------------------------- /mulert/Data/TypeManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef TYPE_MANAGER_H__ 4 | #define TYPE_MANAGER_H__ 5 | 6 | #include "Basic/Type.h" 7 | #include "TypeCreator.h" 8 | #include 9 | #include 10 | 11 | #include "../Logger.h" 12 | #include "../mulert_api.h" 13 | 14 | namespace mule 15 | { 16 | namespace Data 17 | { 18 | /** 19 | * @brief Singleton Type Manager. Used to manage all of the objects in the environment. 20 | * The other components should get registered objects from this class. 21 | */ 22 | class TypeManager 23 | { 24 | Logger logger = Logger::GetLogger(); 25 | 26 | TypeManager(); 27 | ~TypeManager(); 28 | public: 29 | /** 30 | * @brief Get the instance of this class. 31 | * @return The instance of this class. 32 | */ 33 | MULERT_API static TypeManager &GetInstance(); 34 | 35 | /** 36 | * @brief Register given object to manager with name specified. You can drop the pointer 37 | * if you want to use ReleaseObject() to remove it from the manager. 38 | * @param object The pointer to the object need to be register. 39 | * @param name The name of this object. 40 | */ 41 | MULERT_API void RegisterObject(Basic::Type *object, std::u16string name); 42 | 43 | /** 44 | * @brief Unregister the object specified by its name. 45 | * @param name The name of the object need to be unregistered. 46 | */ 47 | MULERT_API void UnregisterObject(std::u16string name); 48 | 49 | /** 50 | * @brief Release the object by its name. This method will also delete the pointer. 51 | * @param name The name of the object need to be released. 52 | */ 53 | MULERT_API void ReleaseObject(std::u16string name); 54 | 55 | /** 56 | * @brief Register type creator to the manager. This class 57 | * is able to manage an automatic process of Type creation by using the creators registered. 58 | * @param creator The creator(s) need to be registered to the manager. 59 | */ 60 | MULERT_API void RegisterObjectCreator(TypeCreator *creator); 61 | 62 | /** 63 | * @brief Try to create a Field by given information. Using the creators registered to the 64 | * manager. If failed, this method will return nullptr. 65 | * @param name The name of the type. 66 | * @return Created Field instance. nullptr if failed. 67 | */ 68 | MULERT_API Basic::Type *GetOrCreateType(std::u16string name); 69 | 70 | /** 71 | * @brief 尝试获取一个已经创建的 Type 或者创建一个一个新的。注意若 meta-info 不为空,则总是创建新的。 72 | * @param name Type 的名字。 73 | * @param metainfo 修饰 Type 的元信息。 74 | * @return 创建的 Type,若失败则为 nullptr。 75 | */ 76 | MULERT_API Basic::Type *GetOrCreateType(std::u16string name, const std::map &metainfo); 77 | 78 | /** 79 | * @brief Try to get a object that already registered to the manager. 80 | * @param name The name of the object given when registered. 81 | * @return 82 | */ 83 | MULERT_API Basic::Type *GetType(std::u16string name); 84 | protected: 85 | std::map objects; 86 | TypeCreator *first, *last; 87 | }; 88 | } 89 | } 90 | 91 | #endif 92 | -------------------------------------------------------------------------------- /mulert/MuleRtVersion.h.in: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define MULERT_BUILD_TIME "@BUILD_TIME@" 4 | #define MULERT_MAJOR_VERSION (@mulert_VERSION_MAJOR@) 5 | #define MULERT_MINOR_VERSION (@mulert_VERSION_MINOR@) 6 | -------------------------------------------------------------------------------- /mulert/SheetManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Data/Sheet.h" 4 | #include "mulert_api.h" 5 | #include "Logger.h" 6 | #include 7 | #include 8 | 9 | namespace mule 10 | { 11 | class SheetManager 12 | { 13 | std::map> streamSheets; 14 | 15 | xybase::Stream *streamOnProcessing; 16 | std::list suspendedSheets; 17 | 18 | static void StreamCloseHandler(xybase::Stream *stream); 19 | 20 | Logger logger = Logger::GetLogger(); 21 | 22 | SheetManager(); 23 | MULERT_API virtual ~SheetManager(); 24 | public: 25 | MULERT_API void Shutdown(); 26 | 27 | MULERT_API static SheetManager &GetInstance(); 28 | 29 | MULERT_API void WriteSheets(xybase::Stream *target, const std::u16string &handlerName); 30 | 31 | MULERT_API void ReadSheets(xybase::Stream *target, const std::u16string &handlerName); 32 | 33 | /** 34 | * @brief Register a sheet to a stream. If the stream has not been registered yet, register it first. 35 | * @param target Target stream. 36 | * @param sheet The sheet needs to append. 37 | */ 38 | MULERT_API void RegisterSheet(xybase::Stream *target, mule::Data::Sheet *sheet); 39 | 40 | MULERT_API void RemoveSheet(xybase::Stream *target, const std::u16string &name); 41 | 42 | MULERT_API void ClearSheets(xybase::Stream *target); 43 | }; 44 | } 45 | -------------------------------------------------------------------------------- /mulert/SheetReference.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "mulert_api.h" 4 | #include "SheetManager.h" 5 | #include "Data/TypeCreator.h" 6 | #include "Logger.h" 7 | 8 | namespace mule 9 | { 10 | class SheetReference : public Data::Basic::Type 11 | { 12 | Logger logger = Logger::GetLogger(); 13 | protected: 14 | std::u16string locCacheName, sizeCacheName; 15 | size_t sizeDefined = -1; 16 | 17 | Data::Basic::Type *infraType = nullptr; 18 | 19 | std::u16string namePattern; 20 | 21 | std::u16string GenerateName(size_t offset, std::u16string streamName); 22 | public: 23 | MULERT_API virtual ~SheetReference(); 24 | MULERT_API size_t Size() const override; 25 | MULERT_API std::u16string GetDataType() const override; 26 | MULERT_API void Read(xybase::Stream *stream, mule::Data::Basic::Type::DataHandler *dataHandler) override; 27 | MULERT_API void Write(xybase::Stream *stream, mule::Data::Basic::Type::FileHandler *fileHandler) override; 28 | 29 | class MULERT_API SheetReferenceCreator : public mule::Data::TypeCreator 30 | { 31 | public: 32 | mule::Data::Basic::Type *DoCreateObject(const std::u16string &info) override; 33 | 34 | // Return nullptr so that flow can move to the next ring of chain-of-responsibility 35 | virtual mule::Data::Basic::Type *DoCreateObject(const std::u16string &info, const std::map &metainfo); 36 | }; 37 | }; 38 | } 39 | -------------------------------------------------------------------------------- /mulert/Storage/BinaryData.cpp: -------------------------------------------------------------------------------- 1 | #include "BinaryData.h" 2 | #include 3 | using namespace mule::Storage; 4 | 5 | BinaryData::BinaryData(char *data, size_t length, bool duplicate) 6 | { 7 | SetData(data, length, duplicate); 8 | } 9 | 10 | mule::Storage::BinaryData::~BinaryData() 11 | { 12 | } 13 | 14 | const char *BinaryData::GetData() const noexcept 15 | { 16 | return data.get(); 17 | } 18 | 19 | size_t BinaryData::GetLength() const noexcept 20 | { 21 | return length; 22 | } 23 | 24 | void BinaryData::SetData(char *data, size_t length, bool duplicate) 25 | { 26 | if (duplicate) 27 | { 28 | this->data = std::shared_ptr(new char[length]); 29 | memcpy(this->data.get(), data, length); 30 | } 31 | else 32 | { 33 | this->data = std::shared_ptr(data); 34 | } 35 | this->length = length; 36 | } 37 | 38 | void BinaryData::SetData(const char *data, size_t length) 39 | { 40 | SetData((char *)data, length, true); 41 | } 42 | -------------------------------------------------------------------------------- /mulert/Storage/BinaryData.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef BINARY_DATA_H__ 4 | #define BINARY_DATA_H__ 5 | 6 | #include 7 | 8 | #include "../mulert_api.h" 9 | 10 | namespace mule 11 | { 12 | namespace Storage 13 | { 14 | class BinaryData 15 | { 16 | std::shared_ptr data; 17 | size_t length; 18 | 19 | public: 20 | 21 | /** 22 | * @brief 初始化二进制数据。 23 | * @param data 数据所在缓冲区。 24 | * @param length 数据长度。 25 | * @param duplicate 是否复制,若为否,则将传入的data直接托管(shared_ptr)。 26 | */ 27 | MULERT_API BinaryData(char *data, size_t length, bool duplicate = true); 28 | 29 | MULERT_API ~BinaryData(); 30 | 31 | MULERT_API const char *GetData() const noexcept; 32 | 33 | MULERT_API size_t GetLength() const noexcept; 34 | 35 | /** 36 | * @brief 管理对应数据 37 | * @param data 数据 38 | * @param length 数据长度 39 | * @param duplicate 是否复制(不对源操作) 40 | */ 41 | MULERT_API void SetData(char *data, size_t length, bool duplicate = true); 42 | 43 | /** 44 | * @brief 管理对应数据 45 | * @param data 数据 46 | * @param length 数据长度 47 | */ 48 | MULERT_API void SetData(const char *data, size_t length); 49 | }; 50 | } 51 | } 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /mulert/Storage/DataManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef DATA_MANAGER_H__ 4 | #define DATA_MANAGER_H__ 5 | 6 | #include 7 | #include 8 | 9 | #include "BinaryData.h" 10 | 11 | #include "../mulert_api.h" 12 | 13 | namespace mule 14 | { 15 | namespace Storage 16 | { 17 | /** 18 | * @brief Binary internal data manager. Used to store/load binary data to/from disc. 19 | * Internal persistence system should use this class to access data file. 20 | */ 21 | class DataManager 22 | { 23 | 24 | int CreateDirectoryRecursively(std::string path, size_t index = 0); 25 | protected: 26 | 27 | struct FileInfo 28 | { 29 | unsigned int id; 30 | unsigned int crc32; 31 | }; 32 | 33 | std::map fileInfos; 34 | 35 | std::u16string dataPath; 36 | 37 | uint32_t currentId = 0x0100'0000; 38 | 39 | DataManager(); 40 | public: 41 | /** 42 | * @brief Is data file of specified id exists? 43 | * @param id Specified id 44 | * @return true if exist, otherwise false. 45 | */ 46 | MULERT_API bool IsExist(unsigned int id) const; 47 | 48 | /** 49 | * @brief Get the instance. 50 | * @return 51 | */ 52 | MULERT_API static DataManager &GetInstance(); 53 | 54 | MULERT_API virtual ~DataManager(); 55 | 56 | /** 57 | * @brief Set data root directory. 58 | * @param datadir The root directory. 59 | */ 60 | MULERT_API void SetDataDir(const std::u16string &datadir); 61 | 62 | /** 63 | * @brief Load a data into memory. 64 | * @param name File name. 65 | * @return Loaded data. 66 | * @deprecated 67 | */ 68 | MULERT_API mule::Storage::BinaryData LoadData(std::string name); 69 | 70 | /** 71 | * @brief Load a data file into memory. 72 | * @param id File id. 73 | * @return Loaded data. 74 | */ 75 | MULERT_API mule::Storage::BinaryData LoadData(unsigned int id) const; 76 | 77 | /** 78 | * @brief Open a C-style I/O stream. 79 | * @param id File id. 80 | * @param create Create file if it is not exist? 81 | * @return A FILE* handle. 82 | */ 83 | MULERT_API FILE *OpenRaw(unsigned int id, bool create = false); 84 | 85 | /** 86 | * @brief Save a data into specified file. 87 | * @param data Binary data. 88 | * @param id File id. 89 | * @return File id. 90 | */ 91 | MULERT_API unsigned int SaveData(const mule::Storage::BinaryData &data, unsigned int id); 92 | 93 | /** 94 | * @brief Save a data into a file, whose file will be automatic assigned. 95 | * @param data Binary data. 96 | * @return Assigned id. 97 | */ 98 | MULERT_API unsigned int SaveData(const mule::Storage::BinaryData &data); 99 | }; 100 | } 101 | } 102 | 103 | #endif // !DATA_MANAGER_H__ 104 | 105 | -------------------------------------------------------------------------------- /mulert/Storage/ResourceManager.cpp: -------------------------------------------------------------------------------- 1 | #include "ResourceManager.h" 2 | 3 | #include "../Configuration.h" 4 | #include 5 | #include 6 | 7 | using namespace xybase::xml; 8 | using namespace mule::Storage; 9 | 10 | ResourceManager &ResourceManager::GetInstance() 11 | { 12 | static ResourceManager _inst; 13 | return _inst; 14 | } 15 | 16 | BinaryData ResourceManager::LoadResource(std::string path) 17 | { 18 | FILE *f = fopen((xybase::string::to_string(Configuration::GetInstance().GetString(u"mule.resource.basedir")) + path).c_str(), "rb"); 19 | if (f == NULL) 20 | { 21 | if (f == NULL) throw xybase::IOException(xybase::string::to_wstring(path), L"Unable to open resource file."); 22 | } 23 | 24 | logger.Info(L"Opened resource file {}", xybase::string::to_wstring(path)); 25 | 26 | fseek(f, 0, SEEK_END); 27 | size_t length = ftell(f); 28 | fseek(f, 0, SEEK_SET); 29 | 30 | char *buffer = new char[length]; 31 | fread(buffer, length, 1, f); 32 | fclose(f); 33 | 34 | return BinaryData(buffer, length, false); 35 | } 36 | 37 | MULERT_API void mule::Storage::ResourceManager::SaveResource(std::u16string path, const mule::Storage::BinaryData &data) 38 | { 39 | FILE *f = fopen((xybase::string::to_string(Configuration::GetInstance().GetString(u"mule.resource.basedir") + path)).c_str(), "wb"); 40 | if (f == NULL) 41 | { 42 | if (f == NULL) throw xybase::IOException(xybase::string::to_wstring(path), L"Unable to open resource file."); 43 | } 44 | 45 | logger.Info(L"Opened resource file {}", xybase::string::to_wstring(path)); 46 | 47 | fwrite(data.GetData(), data.GetLength(), 1, f); 48 | 49 | fclose(f); 50 | } 51 | -------------------------------------------------------------------------------- /mulert/Storage/ResourceManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "../mulert_api.h" 7 | #include "../Logger.h" 8 | #include "BinaryData.h" 9 | 10 | namespace mule 11 | { 12 | namespace Storage 13 | { 14 | class ResourceManager 15 | { 16 | xybase::xml::XmlParser xmlParser; 17 | 18 | mule::Logger logger = mule::Logger::GetLogger(); 19 | 20 | public: 21 | 22 | MULERT_API static ResourceManager &GetInstance(); 23 | 24 | MULERT_API mule::Storage::BinaryData LoadResource(std::string path); 25 | 26 | MULERT_API void SaveResource(std::u16string path, const mule::Storage::BinaryData &data); 27 | }; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /mulert/TranscripterManager.cpp: -------------------------------------------------------------------------------- 1 | #include "TranscripterManager.h" 2 | 3 | using namespace mule; 4 | 5 | TranscripterManager &mule::TranscripterManager::GetInstance() 6 | { 7 | static TranscripterManager _inst; 8 | return _inst; 9 | } 10 | 11 | xybase::Stream *mule::TranscripterManager::Transcript(const char16_t *name, xybase::Stream *infraStream) 12 | { 13 | for (auto &&transcripter : streamCreators) 14 | { 15 | auto ret = transcripter(name, infraStream); 16 | if (ret == nullptr) continue; 17 | return ret; 18 | } 19 | return nullptr; 20 | } 21 | 22 | xybase::Stream *mule::TranscripterManager::Transcript(int count, const char16_t **parameter) 23 | { 24 | for (auto &&transcripter : advancedStreamCreators) 25 | { 26 | auto ret = transcripter(count, parameter); 27 | if (ret == nullptr) continue; 28 | return ret; 29 | } 30 | return nullptr; 31 | } 32 | 33 | void mule::TranscripterManager::RegisterCreator(xybase::Stream *(*creator)(const char16_t *name, xybase::Stream *infraStream)) 34 | { 35 | streamCreators.push_back(creator); 36 | } 37 | 38 | void mule::TranscripterManager::RegisterCreator(xybase::Stream *(*creator)(int count, const char16_t **parameter)) 39 | { 40 | advancedStreamCreators.push_back(creator); 41 | } 42 | -------------------------------------------------------------------------------- /mulert/TranscripterManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "mulert_api.h" 4 | #include 5 | #include 6 | 7 | namespace mule 8 | { 9 | /** 10 | * @brief 管理Stream转写类的管理器。该类转写类模拟为一个Stream,对下层Stream行为进行转换。 11 | */ 12 | class TranscripterManager 13 | { 14 | std::list streamCreators; 15 | 16 | std::list advancedStreamCreators; 17 | 18 | public: 19 | 20 | MULERT_API static TranscripterManager &GetInstance(); 21 | 22 | /** 23 | * @brief 将一个现有的流以指定的转译器转译 24 | * @param name 转译器标识符 25 | * @param infraStream 要被转译的流 26 | * @return 转译后的流(转译器对象) 27 | */ 28 | MULERT_API xybase::Stream *Transcript(const char16_t *name, xybase::Stream *infraStream); 29 | 30 | /** 31 | * @brief 以指定的参数打开一个流 32 | * @param count 参数个数 33 | * @param parameter 参数 34 | * @return 打开的流 35 | */ 36 | MULERT_API xybase::Stream *Transcript(int count, const char16_t **parameter); 37 | 38 | /** 39 | * @brief 注册转译器创建函数 40 | * @param creator 创建函数 41 | */ 42 | MULERT_API void RegisterCreator(xybase::Stream *(*creator)(const char16_t *name, xybase::Stream *infraStream)); 43 | 44 | /** 45 | * @brief 注册流创建函数 46 | * @param creator 创建函数 47 | */ 48 | MULERT_API void RegisterCreator(xybase::Stream *(*creator)(int count, const char16_t **parameter)); 49 | }; 50 | } 51 | -------------------------------------------------------------------------------- /mulert/VirtualFileSystem.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "mulert_api.h" 11 | #include "Logger.h" 12 | 13 | namespace mule 14 | { 15 | /** 16 | * @brief 管理文件容器类的管理器。文件容器用于将Stream解释为虚拟文件系统。 17 | */ 18 | class VirtualFileSystem 19 | { 20 | Logger logger = Logger::GetLogger(); 21 | 22 | std::map containers; 23 | 24 | std::list containerApplyers; 25 | 26 | VirtualFileSystem(); 27 | MULERT_API virtual ~VirtualFileSystem(); 28 | public: 29 | MULERT_API void Shutdown(); 30 | 31 | MULERT_API static VirtualFileSystem &GetInstance(); 32 | 33 | MULERT_API const std::list List(const char16_t *container); 34 | 35 | /** 36 | * @brief 打开指定路径的流 37 | * @param path 指定路径的流 38 | * @param openMode 打开方式 39 | * @return 打开的流 40 | */ 41 | MULERT_API xybase::Stream *Open(const char16_t *path, xybase::FileOpenMode openMode); 42 | 43 | /** 44 | * @brief 从文件系统中移除一个文件 45 | * @param path 指定的文件路径 46 | * @param recursive 递归移除子目录 47 | */ 48 | MULERT_API void Remove(const char16_t *path, bool recursive = false); 49 | 50 | /** 51 | * @brief 级联打开文件,调用闭包后关闭 52 | * @param targetFile 文件全限定路径 53 | * @param openMode 打开方式 54 | * @param lambda 回调闭包 55 | */ 56 | MULERT_API void CascadeProcess(const char16_t *targetFile, std::function lambda, xybase::FileOpenMode openMode); 57 | 58 | /** 59 | * @brief 挂载一个容器到指定根【此后此容器生命期需由本类管理,丢弃本来指针】 60 | * @param rootName 挂载的根名 61 | * @param container 要挂载的容器 62 | */ 63 | MULERT_API void Mount(const char16_t *rootName, xybase::FileContainer *container); 64 | 65 | /** 66 | * @brief 以指定的type创建文件容器,并挂载到指定根 67 | * @param rootName 要挂载的根 68 | * @param containerType 解释流的容器类型 69 | * @param infraStream 要被解释的下层流 70 | */ 71 | MULERT_API void Mount(const char16_t *rootName, const char16_t *containerType, xybase::Stream *infraStream); 72 | 73 | /** 74 | * @brief 解除挂载 75 | * @param name 指定的根名。 76 | */ 77 | MULERT_API void Unmount(const char16_t *name); 78 | 79 | /** 80 | * @brief 列出当前所有根名。 81 | * @return 所有根名组成的列表 82 | */ 83 | MULERT_API const std::list ListRoots() const; 84 | 85 | /** 86 | * @brief 注册一个创建器到虚拟文件系统。 87 | * @param creator 指向创建函数的指针 88 | */ 89 | MULERT_API void RegisterContainerCreator(xybase::FileContainer *(*creator)(const char16_t *type, xybase::Stream *infra)); 90 | 91 | /** 92 | * @brief 根据根名字获取对应的根文件系统。 93 | * @param rootName 根名字 94 | * @return 由名字确定的根,若失败则为 nullptr 95 | */ 96 | MULERT_API xybase::FileContainer *GetRoot(const char16_t* rootName); 97 | }; 98 | } 99 | -------------------------------------------------------------------------------- /mulert/mulert_api.h: -------------------------------------------------------------------------------- 1 | #ifndef MULERT_API_H__ 2 | #define MULERT_API_H__ 3 | 4 | #ifdef MULERT_STATIC 5 | 6 | #define MULERT_API 7 | 8 | #else 9 | 10 | #ifdef WIN32 11 | 12 | #ifdef _MSC_VER 13 | 14 | #ifdef MULERT_EXPORTS_DLL 15 | #define MULERT_API __declspec(dllexport) 16 | #else 17 | #define MULERT_API __declspec(dllimport) 18 | #endif 19 | 20 | #elif defined(__GNUC__) 21 | 22 | #ifdef MULERT_EXPORT_DLL 23 | #define MULERT_API __attribute__(dllexport) 24 | #else 25 | #define MULERT_API __attribute__(dllimport) 26 | #endif /*Windows, GCC*/ 27 | 28 | #endif 29 | 30 | #elif defined(linux) 31 | 32 | #if defined(__GNUC__) 33 | #ifdef MULERT_EXPORTS_DLL 34 | #define MULERT_API __attribute__((visibility ("default"))) 35 | #else 36 | #define MULERT_API 37 | #endif 38 | #endif /*Linux, GCC*/ 39 | 40 | #endif 41 | 42 | #endif /*MULERT_STATIC*/ 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /sis/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | add_library (sis "Xml/XmlHandler.h" "Xml/XmlHandler.cpp" "Xml/XmlGenerator.h" "Xml/MvXmlNode.h" "Xml/MvXmlNode.cpp" "Cpp/BisEnv.h" "Cpp/BisEnv.cpp" "Cpp/CStyleInitHandler.cpp" "Cpp/CStyleInitHandler.h" "Csv/CsvHandler.h" "Csv/CsvHandler.cpp" "Xml/XmlDefinition.h" "Xml/XmlDefinition.cpp" "Cpp/Mappifier.cpp" "Cpp/Mappifier.h" "Csv/CsvFileHandler.h" "Csv/CsvFileHandler.cpp" "Json/JsonFileHandler.h" "Json/JsonFileHandler.cpp" "Json/JsonOutHandler.h" "Json/JsonOutHandler.cpp") 3 | 4 | target_include_directories (sis INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) 5 | 6 | if (USING_LUA) 7 | target_link_libraries(sis PUBLIC lua) 8 | add_subdirectory(Lua) 9 | endif() 10 | 11 | if (USING_RUBY) 12 | add_subdirectory(Ruby) 13 | endif() 14 | 15 | target_link_libraries(sis PUBLIC bis) 16 | 17 | if (CMAKE_VERSION VERSION_GREATER 3.12) 18 | set_property(TARGET sis PROPERTY CXX_STANDARD 20) 19 | endif() 20 | -------------------------------------------------------------------------------- /sis/Cpp/BisEnv.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 此文件展示了如何将符合 mule 要求的函数注册到 mule 系统中。 3 | */ 4 | #pragma once 5 | 6 | #include 7 | 8 | namespace mule 9 | { 10 | namespace Cpp 11 | { 12 | extern PluginDescription bisDesc; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /sis/Cpp/CStyleInitHandler.cpp: -------------------------------------------------------------------------------- 1 | #include "CStyleInitHandler.h" 2 | 3 | #include 4 | #include 5 | 6 | using namespace mule::Data::Basic; 7 | 8 | int mule::Cpp::CStyleInitHandler::ident = 1, mule::Cpp::CStyleInitHandler::type = 0; 9 | 10 | mule::Cpp::CStyleInitHandler::CStyleInitHandler() 11 | : stream {nullptr}, state{ CSIHS_IDLE } 12 | { 13 | } 14 | 15 | void mule::Cpp::CStyleInitHandler::OnRealmEnter(Type *realm, const std::u16string &name) 16 | { 17 | if (realm->IsComposite()) 18 | { 19 | for (int i = 0; i < layer; ++i) 20 | for (int j = 0; j < ident; ++j) 21 | { 22 | outstream->Write(type ? " " : "\t"); 23 | } 24 | ++layer; 25 | outstream->Write("{\n"); 26 | } 27 | } 28 | 29 | void mule::Cpp::CStyleInitHandler::OnRealmExit(Type *realm, const std::u16string &name) 30 | { 31 | if (realm->IsComposite()) 32 | { 33 | --layer; 34 | for (int i = 0; i < layer; ++i) 35 | for (int j = 0; j < ident; ++j) 36 | { 37 | outstream->Write(type ? " " : "\t"); 38 | } 39 | outstream->Write("},\n"); 40 | } 41 | } 42 | 43 | void mule::Cpp::CStyleInitHandler::OnRealmEnter(Type *realm, int idx) 44 | { 45 | if (realm->IsComposite()) 46 | { 47 | for (int i = 0; i < layer; ++i) 48 | for (int j = 0; j < ident; ++j) 49 | { 50 | outstream->Write(type ? " " : "\t"); 51 | } 52 | ++layer; 53 | outstream->Write("{\n"); 54 | } 55 | } 56 | 57 | void mule::Cpp::CStyleInitHandler::OnRealmExit(Type *realm, int idx) 58 | { 59 | if (realm->IsComposite()) 60 | { 61 | --layer; 62 | for (int i = 0; i < layer; ++i) 63 | for (int j = 0; j < ident; ++j) 64 | { 65 | outstream->Write(type ? " " : "\t"); 66 | } 67 | outstream->Write("},\n"); 68 | } 69 | } 70 | 71 | void mule::Cpp::CStyleInitHandler::OnDataRead(const MultiValue &value) 72 | { 73 | for (int i = 0; i < layer; ++i) 74 | for (int j = 0; j < ident; ++j) 75 | { 76 | outstream->Write(type ? " " : "\t"); 77 | } 78 | outstream->Write(reinterpret_cast(xybase::string::to_utf8(value.Stringfy()).c_str())); 79 | outstream->Write(",\n"); 80 | } 81 | 82 | void mule::Cpp::CStyleInitHandler::OnSheetReadStart() 83 | { 84 | if (state != CSIHS_IDLE) 85 | throw xybase::InvalidOperationException(L"This handler is not idle for read.", 10000); 86 | state = CSIHS_READ; 87 | } 88 | 89 | void mule::Cpp::CStyleInitHandler::OnSheetReadEnd() 90 | { 91 | if (state != CSIHS_READ) 92 | throw xybase::InvalidOperationException(L"This handler is not reading.", 10000); 93 | state = CSIHS_IDLE; 94 | } 95 | -------------------------------------------------------------------------------- /sis/Cpp/CStyleInitHandler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef CSTYLE_INIT_HANDLER_H__ 4 | #define CSTYLE_INIT_HANDLER_H__ 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | namespace mule 11 | { 12 | namespace Cpp 13 | { 14 | class CStyleInitHandler : public mule::Data::Basic::Type::DataHandler 15 | { 16 | public: 17 | CStyleInitHandler(); 18 | 19 | /** 20 | * @brief 缩进符号个数 21 | */ 22 | static int ident; 23 | /** 24 | * @brief 缩进风格,0 为 tab,1 为空格 25 | */ 26 | static int type; 27 | 28 | virtual void OnSheetReadStart() override; 29 | 30 | virtual void OnSheetReadEnd() override; 31 | 32 | virtual void OnRealmEnter(mule::Data::Basic::Type *realm, const std::u16string &name) override; 33 | virtual void OnRealmExit(mule::Data::Basic::Type *realm, const std::u16string &name) override; 34 | virtual void OnRealmEnter(mule::Data::Basic::Type *realm, int idx) override; 35 | virtual void OnRealmExit(mule::Data::Basic::Type *realm, int idx) override; 36 | virtual void OnDataRead(const mule::Data::Basic::MultiValue &value) override; 37 | private: 38 | xybase::Stream *stream; 39 | 40 | enum { 41 | CSIHS_IDLE, 42 | CSIHS_READ, 43 | CSIHS_WRITE, 44 | } state; 45 | 46 | int layer = 0; 47 | }; 48 | } 49 | } 50 | 51 | #endif // !CSTYLE_INIT_HANDLER_H__ 52 | 53 | -------------------------------------------------------------------------------- /sis/Cpp/Mappifier.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef MAPPIFIER_H__ 4 | #define MAPPIFIER_H__ 5 | 6 | #include 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | namespace mule 13 | { 14 | namespace Cpp 15 | { 16 | class Mappifier : public mule::Data::Basic::Type::DataHandler, public mule::Data::Basic::Type::FileHandler 17 | { 18 | public: 19 | virtual void OnSheetReadStart() override; 20 | virtual void OnSheetWriteStart() override; 21 | 22 | virtual void OnSheetReadEnd() override; 23 | virtual void OnSheetWriteEnd() override; 24 | 25 | virtual void OnRealmEnter(mule::Data::Basic::Type *realm, const std::u16string &name) override; 26 | virtual void OnRealmExit(mule::Data::Basic::Type *realm, const std::u16string &name) override; 27 | virtual void OnRealmEnter(mule::Data::Basic::Type *realm, int idx) override; 28 | virtual void OnRealmExit(mule::Data::Basic::Type *realm, int idx) override; 29 | 30 | virtual void OnDataRead(const mule::Data::Basic::MultiValue &value) override; 31 | virtual const mule::Data::Basic::MultiValue OnDataWrite() override; 32 | 33 | virtual void AppendMetadatum(std::u16string name, const mule::Data::Basic::MultiValue &datum) override; 34 | 35 | mule::Data::Basic::MultiValue GetMap() const; 36 | void SetMap(mule::Data::Basic::MultiValue &value); 37 | protected: 38 | std::stack values; 39 | mule::Data::Basic::MultiValue result; 40 | mule::Data::Basic::MultiValue key; 41 | 42 | enum { 43 | DHMS_IDLE, 44 | DHMS_READ, 45 | DHMS_WRITE 46 | } status = DHMS_IDLE; 47 | }; 48 | } 49 | } 50 | 51 | #endif // End of MAPPIFIER_H__ 52 | -------------------------------------------------------------------------------- /sis/Csv/CsvFileHandler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | namespace mule 8 | { 9 | namespace Csv 10 | { 11 | class CsvFileHandler : public mule::Data::Basic::Type::FileHandler 12 | { 13 | mule::Data::Basic::MultiValue readElement; 14 | 15 | enum UCharMode { 16 | UCM_UTF8, 17 | UCM_UTF16LE, 18 | UCM_UTF16BE, 19 | UCM_UTF32LE, /* reserved, not implemented */ 20 | UCM_UTF32BE, /* reserved, not implemented */ 21 | } charMode = UCM_UTF8; 22 | 23 | /** 24 | * @brief Flag: End of line read. 25 | */ 26 | bool flg_eol; 27 | // 换行检查 28 | int wrapLayer = 1; 29 | /** 30 | * @brief 抑制换行:1-抑制基本类型,2-抑制组合类型,0-不抑制 31 | */ 32 | int wrapSuppression = 0; 33 | int layer = 0; 34 | 35 | Logger logger = Logger::GetLogger(); 36 | protected: 37 | int ReadChar(); 38 | 39 | std::u16string ReadCell(); 40 | public: 41 | void OnRealmEnter(mule::Data::Basic::Type *realm, const std::u16string &name) override; 42 | void OnRealmExit(mule::Data::Basic::Type *realm, const std::u16string &name) override; 43 | void HandleReamExit(mule::Data::Basic::Type *realm); 44 | void OnRealmEnter(mule::Data::Basic::Type *realm, int idx) override; 45 | void HandleRealmEnter(mule::Data::Basic::Type *realm); 46 | void OnRealmExit(mule::Data::Basic::Type *realm, int idx) override; 47 | void OnSheetWriteStart() override; 48 | void OnSheetWriteEnd() override; 49 | const mule::Data::Basic::MultiValue OnDataWrite() override; 50 | }; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /sis/Csv/CsvHandler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef CSV_HANDLER_H__ 4 | #define CSV_HANDLER_H__ 5 | 6 | #include 7 | 8 | namespace mule 9 | { 10 | namespace Csv 11 | { 12 | class CsvOutHandler : public mule::Data::Basic::Type::DataHandler 13 | { 14 | public: 15 | /** 16 | * @brief 缩进符号个数 17 | */ 18 | static int ident; 19 | /** 20 | * @brief 缩进风格,0 为 tab,1 为空格 21 | */ 22 | static int type; 23 | 24 | virtual void OnSheetReadStart() override; 25 | 26 | virtual void OnSheetReadEnd() override; 27 | 28 | virtual void OnRealmEnter(mule::Data::Basic::Type *realm, const std::u16string &name) override; 29 | virtual void OnRealmExit(mule::Data::Basic::Type *realm, const std::u16string &name) override; 30 | virtual void OnRealmEnter(mule::Data::Basic::Type *realm, int idx) override; 31 | virtual void OnRealmExit(mule::Data::Basic::Type *realm, int idx) override; 32 | virtual void OnDataRead(const mule::Data::Basic::MultiValue &value) override; 33 | private: 34 | enum { 35 | CHS_IDLE, 36 | CHS_READ, 37 | CHS_READ_TRAILCELL, 38 | CHS_WRITE, 39 | CHS_WRITE_TRAILCELL, 40 | } status = CHS_IDLE; 41 | 42 | bool disarmed = false; 43 | bool isString = false, isText = false, isNumber = false; 44 | int layer = 0; 45 | int wrapLayer = 1; 46 | /** 47 | * @brief 抑制换行:1-抑制基本类型,2-抑制组合类型,0-不抑制 48 | */ 49 | int wrapSuppression = 0; 50 | }; 51 | } 52 | } 53 | 54 | #endif /* End of Csv_HANDLER_H__*/ 55 | -------------------------------------------------------------------------------- /sis/Json/JsonFileHandler.cpp: -------------------------------------------------------------------------------- 1 | #include "JsonFileHandler.h" 2 | 3 | -------------------------------------------------------------------------------- /sis/Json/JsonFileHandler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | -------------------------------------------------------------------------------- /sis/Json/JsonOutHandler.cpp: -------------------------------------------------------------------------------- 1 | #include "JsonOutHandler.h" 2 | 3 | #include 4 | 5 | using namespace mule::Data::Basic; 6 | 7 | void mule::Json::JsonOutHandler::OnRealmEnter(Type *realm, const std::u16string &name) 8 | { 9 | outstream->Write('"'); 10 | outstream->Write((char *)xybase::string::to_utf8(name).c_str()); 11 | outstream->Write("\": "); 12 | if (realm->IsComposite()) 13 | { 14 | if (realm->GetDataType().starts_with(u"array/")) 15 | { 16 | outstream->Write("["); 17 | } 18 | else 19 | { 20 | outstream->Write("{"); 21 | } 22 | } 23 | } 24 | 25 | void mule::Json::JsonOutHandler::OnRealmExit(Type *realm, const std::u16string &name) 26 | { 27 | if (realm->IsComposite()) 28 | { 29 | if (realm->GetDataType().starts_with(u"array/")) 30 | { 31 | outstream->Write("]"); 32 | } 33 | else 34 | { 35 | outstream->Write("}"); 36 | } 37 | } 38 | outstream->Write(", "); 39 | } 40 | 41 | void mule::Json::JsonOutHandler::OnRealmEnter(Type *realm, int idx) 42 | { 43 | if (realm->IsComposite()) 44 | { 45 | if (realm->GetDataType().starts_with(u"array/")) 46 | { 47 | outstream->Write("["); 48 | } 49 | else 50 | { 51 | outstream->Write("{"); 52 | } 53 | } 54 | } 55 | 56 | void mule::Json::JsonOutHandler::OnRealmExit(Type *realm, int idx) 57 | { 58 | if (realm->IsComposite()) 59 | { 60 | if (realm->GetDataType().starts_with(u"array/")) 61 | { 62 | outstream->Write("]"); 63 | } 64 | else 65 | { 66 | outstream->Write("}"); 67 | } 68 | } 69 | outstream->Write(", "); 70 | } 71 | 72 | void mule::Json::JsonOutHandler::OnSheetReadStart() 73 | { 74 | } 75 | 76 | void mule::Json::JsonOutHandler::OnSheetReadEnd() 77 | { 78 | } 79 | 80 | void mule::Json::JsonOutHandler::OnDataRead(const mule::Data::Basic::MultiValue &value) 81 | { 82 | } 83 | -------------------------------------------------------------------------------- /sis/Json/JsonOutHandler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace mule 6 | { 7 | namespace Json 8 | { 9 | class JsonOutHandler : public mule::Data::Basic::Type::DataHandler 10 | { 11 | std::u16string type; 12 | int layer; 13 | public: 14 | // 通过 DataHandler 继承 15 | void OnRealmEnter(mule::Data::Basic::Type *realm, const std::u16string &name) override; 16 | void OnRealmExit(mule::Data::Basic::Type *realm, const std::u16string &name) override; 17 | void OnRealmEnter(mule::Data::Basic::Type *realm, int idx) override; 18 | void OnRealmExit(mule::Data::Basic::Type *realm, int idx) override; 19 | void OnSheetReadStart() override; 20 | void OnSheetReadEnd() override; 21 | void OnDataRead(const mule::Data::Basic::MultiValue &value) override; 22 | }; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /sis/Lua/Api/ContainerOperation.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | namespace mule 8 | { 9 | namespace Lua 10 | { 11 | namespace Api 12 | { 13 | int MountStream(int streamId, std::u8string type, std::u8string root); 14 | 15 | int Unmount(std::u8string root); 16 | 17 | mule::Data::Basic::MultiValue List(std::u8string root); 18 | 19 | mule::Data::Basic::MultiValue ListRoots(); 20 | 21 | mule::Data::Basic::MultiValue Metadata(std::u8string path, mule::Data::Basic::MultiValue data); 22 | 23 | int OpenAndMount(std::u8string root, std::u8string param); 24 | 25 | int Remove(std::u8string name); 26 | 27 | void RegisterContainerOperationFunctions(); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /sis/Lua/Api/StreamOperation.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace mule 6 | { 7 | namespace Lua 8 | { 9 | namespace Api 10 | { 11 | int OpenStream(std::u8string path, std::u8string openMode); 12 | 13 | int CloseStream(int id); 14 | 15 | int ExportStream(std::u8string path, int id); 16 | 17 | int ExportStreamToResource(std::u8string src, std::u8string out); 18 | 19 | int ExtractStream(std::u8string path, int offset, int length, int id); 20 | 21 | int ImportStream(std::u8string path, int id); 22 | 23 | int ImportStreamFromResource(std::u8string dst, std::u8string in); 24 | 25 | int PatchStream(std::u8string path, int offset, int length, int id); 26 | 27 | int StreamOverStream(int streamId, std::u8string applier); 28 | 29 | std::string ReadStream(int streamId, int size); 30 | 31 | int WriteStream(int streamId, std::string data); 32 | 33 | int TellStream(int streamId); 34 | 35 | int SeekStream(int streamId, int offset, int seekType); 36 | 37 | void RegisterStreamOperationFunctions(); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /sis/Lua/Api/SystemOperation.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | namespace mule 8 | { 9 | namespace Lua 10 | { 11 | namespace Api 12 | { 13 | extern Logger logger; 14 | 15 | int Confirm(std::u8string word); 16 | 17 | int PrintPlugins(); 18 | 19 | int Log(std::u8string msg); 20 | 21 | int LoadPlugin(std::u8string path); 22 | 23 | mule::Data::Basic::MultiValue Configuration(std::u8string name, mule::Data::Basic::MultiValue mv); 24 | 25 | int EraseConfiguration(std::u8string name); 26 | 27 | void RegisterSystemOperations(); 28 | 29 | int DefineStructure(std::u8string name, mule::Data::Basic::MultiValue def); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /sis/Lua/Api/readme.txt: -------------------------------------------------------------------------------- 1 | In this folder, these files implemented some api for lua. 2 | To enable the lua-side can manipulate the stream, etc. In the future, with the developing, some of the Apis might be removed. 3 | 4 | 此文件夹中实现了LUA侧操作MULE的接口。 5 | -------------------------------------------------------------------------------- /sis/Lua/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library (sislua "LuaHost.h" "LuaHost.cpp" "LuaDataHandler.h" "LuaDataHandler.cpp" "LuaEnvironment.h" "LuaEnvironment.cpp" "Api/ContainerOperation.cpp" "Api/ContainerOperation.h" "Api/StreamOperation.cpp" "Api/StreamOperation.h" "Api/SystemOperation.cpp" "Api/SystemOperation.h") 2 | 3 | target_link_libraries(sislua PUBLIC bis) 4 | target_link_libraries(sislua PUBLIC lua) 5 | 6 | if (CMAKE_VERSION VERSION_GREATER 3.12) 7 | set_property(TARGET sislua PROPERTY CXX_STANDARD 20) 8 | endif() 9 | -------------------------------------------------------------------------------- /sis/Lua/LuaDataHandler.cpp: -------------------------------------------------------------------------------- 1 | #include "LuaDataHandler.h" 2 | 3 | using namespace mule::Lua; 4 | using namespace mule::Data::Basic; 5 | 6 | void mule::Lua::LuaDataHandler::OnRealmEnter(Type *realm, const std::u16string& name) 7 | { 8 | } 9 | 10 | void mule::Lua::LuaDataHandler::OnRealmExit(Type *realm, const std::u16string& name) 11 | { 12 | } 13 | 14 | void mule::Lua::LuaDataHandler::OnDataRead(const MultiValue &value) 15 | { 16 | } 17 | 18 | void mule::Lua::LuaDataHandler::OnRealmEnter(Type *realm, int idx) 19 | { 20 | } 21 | 22 | void mule::Lua::LuaDataHandler::OnRealmExit(Type *realm, int idx) 23 | { 24 | } 25 | -------------------------------------------------------------------------------- /sis/Lua/LuaDataHandler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #ifndef LUA_DATA_HANDLER__ 3 | #define LUA_DATA_HANDLER__ 4 | 5 | #include 6 | #include "LuaHost.h" 7 | 8 | namespace mule 9 | { 10 | namespace Lua 11 | { 12 | class LuaDataHandler : public mule::Data::Basic::Type::DataHandler 13 | { 14 | public: 15 | virtual void OnRealmEnter(mule::Data::Basic::Type *realm, const std::u16string &name) override; 16 | virtual void OnRealmExit(mule::Data::Basic::Type *realm, const std::u16string &name) override; 17 | virtual void OnDataRead(const mule::Data::Basic::MultiValue &value) override; 18 | virtual void OnRealmEnter(mule::Data::Basic::Type *realm, int idx) override; 19 | virtual void OnRealmExit(mule::Data::Basic::Type *realm, int idx) override; 20 | protected: 21 | }; 22 | } 23 | } 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /sis/Lua/LuaEnvironment.cpp: -------------------------------------------------------------------------------- 1 | #include "LuaEnvironment.h" 2 | 3 | #include 4 | #include 5 | 6 | #include "Api/ContainerOperation.h" 7 | #include "Api/StreamOperation.h" 8 | #include "Api/SystemOperation.h" 9 | 10 | using namespace mule::Lua; 11 | 12 | int regLuaHandler_c(lua_State *L) 13 | { 14 | return 0; 15 | } 16 | 17 | mule::Lua::LuaEnvironment::LuaEnvironment() 18 | { 19 | Init(); 20 | } 21 | 22 | mule::Lua::LuaEnvironment::~LuaEnvironment() 23 | { 24 | //mule::VirtualFileSystem::GetInstance().Shutdown(); 25 | 26 | for (auto ritr = streams.rbegin(); ritr != streams.rend(); ++ritr) 27 | { 28 | ritr->second->Close(); 29 | delete ritr->second; 30 | } 31 | } 32 | 33 | xybase::Stream *mule::Lua::LuaEnvironment::GetStream(int idx) 34 | { 35 | logger.Debug(L"请求流{}", idx); 36 | if (streams.contains(idx)) 37 | { 38 | logger.Debug(L"有效流->{}", xybase::string::to_wstring(streams[idx]->GetName())); 39 | return streams[idx]; 40 | } 41 | else 42 | return nullptr; 43 | } 44 | 45 | int mule::Lua::LuaEnvironment::SetStream(xybase::Stream *stream) 46 | { 47 | if (stream == nullptr) 48 | throw xybase::InvalidParameterException(L"stream", L"Null Pointer!!!", 95585); 49 | int sd = streamd++; 50 | streams[sd] = stream; 51 | #ifndef NDEBUG 52 | logger.Debug(L"登录流{}->{}", xybase::string::to_wstring(stream->GetName()), sd); 53 | stream->OnClose += [](xybase::Stream *sender) -> void 54 | { 55 | LoggerBase::GetInstance().Debug(L"LUA 宿主环境:关闭流监听事件触发"); 56 | LoggerBase::GetInstance().Debug(xybase::string::to_wstring(sender->GetName())); 57 | }; 58 | #endif // !NDEBUG 59 | 60 | return sd; 61 | } 62 | 63 | void mule::Lua::LuaEnvironment::CloseStream(int idx) 64 | { 65 | if (!streams.contains(idx)) throw xybase::InvalidParameterException(L"idx", L"Specified fd not found.", 95594); 66 | auto &&stream = streams[idx]; 67 | logger.Debug(L"注销流{}->{}", idx, xybase::string::to_wstring(stream->GetName())); 68 | stream->Close(); 69 | delete stream; 70 | streams.erase(idx); 71 | } 72 | 73 | LuaEnvironment &mule::Lua::LuaEnvironment::GetInstance() 74 | { 75 | static LuaEnvironment _inst; 76 | return _inst; 77 | } 78 | 79 | void mule::Lua::LuaEnvironment::Init() 80 | { 81 | Api::RegisterContainerOperationFunctions(); 82 | Api::RegisterStreamOperationFunctions(); 83 | Api::RegisterSystemOperations(); 84 | } 85 | 86 | -------------------------------------------------------------------------------- /sis/Lua/LuaEnvironment.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef LUA_API_H__ 4 | #define LUA_API_H__ 5 | 6 | #include "LuaHost.h" 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | namespace mule { 15 | namespace Lua { 16 | /** 17 | * @brief Designed to provide the ability to operate the C++ environment for Lua scripts. 18 | * This class will register lots of functions at the LuaHost. 19 | */ 20 | class LuaEnvironment 21 | { 22 | LuaEnvironment(); 23 | 24 | std::map streams; 25 | std::atomic_int streamd; 26 | 27 | mule::Logger logger = Logger::GetLogger(); 28 | 29 | public: 30 | ~LuaEnvironment(); 31 | 32 | xybase::Stream *GetStream(int idx); 33 | 34 | int SetStream(xybase::Stream *stream); 35 | 36 | void CloseStream(int idx); 37 | 38 | /** 39 | * @brief 获取Lua宿主环境 40 | * @return 本环境 41 | */ 42 | static LuaEnvironment &GetInstance(); 43 | 44 | /** 45 | * @brief Register all functions to the vm / init the vm. 46 | */ 47 | static void Init(); 48 | }; 49 | } 50 | } 51 | 52 | #endif // end of LUA_API_H__ 53 | -------------------------------------------------------------------------------- /sis/Ruby/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library (sisruby "RubyHost.cpp" "RubyHost.h") 2 | 3 | target_link_libraries(sisruby PUBLIC bis) 4 | target_include_directories(sisruby PUBLIC "${PROJECT_SOURCE_DIR}/bis") 5 | target_link_libraries(sisruby PUBLIC liblua) 6 | target_include_directories(sisruby PUBLIC "${PROJECT_SOURCE_DIR}/lib/include/ruby") 7 | 8 | if (CMAKE_VERSION VERSION_GREATER 3.12) 9 | set_property(TARGET sisruby PROPERTY CXX_STANDARD 20) 10 | endif() 11 | -------------------------------------------------------------------------------- /sis/Ruby/RubyHost.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XiyanFlowC/mule/05403633a6fcdee09b27e07fed26c4c37fda2f66/sis/Ruby/RubyHost.cpp -------------------------------------------------------------------------------- /sis/Ruby/RubyHost.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef RUBY_HOST_H__ 4 | #define RUBY_HOST_H__ 5 | 6 | class RubyHost 7 | { 8 | 9 | }; 10 | 11 | #endif // !RUBY_HOST_H__ 12 | -------------------------------------------------------------------------------- /sis/Xml/MvXmlNode.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef MV_XML_NODE_H__ 4 | #define MV_XML_NODE_H__ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | namespace mule 12 | { 13 | namespace Xml 14 | { 15 | /** 16 | * @brief 提供MultiValue和Xml节点的对应关系 17 | */ 18 | class MvXmlNode 19 | { 20 | int counter = 0; 21 | public: 22 | mule::Data::Basic::MultiValue mv; 23 | 24 | std::u16string name; 25 | 26 | MvXmlNode(); 27 | 28 | MvXmlNode(std::u16string name, const mule::Data::Basic::MultiValue &val); 29 | 30 | MvXmlNode(const MvXmlNode &rvalue); 31 | 32 | MvXmlNode(const MvXmlNode &&movee) noexcept; 33 | 34 | void AddChild(MvXmlNode node); 35 | 36 | std::list GetChildren() const; 37 | 38 | void AddText(std::u16string str); 39 | 40 | std::u16string GetText() const; 41 | 42 | void SetName(std::u16string name); 43 | 44 | std::u16string GetName() const; 45 | 46 | void AddAttribute(std::u16string name, std::u16string data); 47 | 48 | std::map GetAttributes() const; 49 | 50 | const static MvXmlNode ERROR; 51 | 52 | bool operator== (const MvXmlNode &rvalue) const; 53 | 54 | MvXmlNode operator[] (std::u16string name); 55 | 56 | /** 57 | * @brief 从MultiValue值转换为Xml需要的Text 58 | */ 59 | static std::function text_to_xml; 60 | /** 61 | * @brief 将Xml转换为需要的MultiValue 62 | */ 63 | static std::function xml_to_text; 64 | }; 65 | } 66 | } 67 | 68 | #endif // !MV_XML_NODE_H__ 69 | -------------------------------------------------------------------------------- /sis/Xml/XmlDefinition.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace mule 7 | { 8 | namespace Xml 9 | { 10 | class XmlDefinition 11 | { 12 | mule::Logger logger = mule::Logger{ "" }; 13 | public: 14 | void Parse(std::u16string name); 15 | 16 | void ParseVersion1(const xybase::xml::XmlNode &node, int subversion = 0); 17 | }; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /sis/Xml/XmlHandler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef XML_HANDLER_H__ 4 | #define XML_HANDLER_H__ 5 | 6 | #include 7 | #include 8 | 9 | #include 10 | 11 | namespace mule 12 | { 13 | namespace Xml 14 | { 15 | class XmlHandler : public mule::Data::Basic::Type::DataHandler, public mule::Data::Basic::Type::FileHandler 16 | { 17 | public: 18 | XmlHandler(); 19 | 20 | /** 21 | * @brief 缩进符号个数 22 | */ 23 | static int ident; 24 | /** 25 | * @brief 缩进风格,0 为 tab,1 为空格 26 | */ 27 | static int type; 28 | 29 | virtual void OnSheetReadStart() override; 30 | 31 | virtual void OnSheetReadEnd() override; 32 | 33 | virtual void OnSheetWriteStart() override; 34 | 35 | virtual void OnSheetWriteEnd() override; 36 | 37 | virtual void OnRealmEnter(mule::Data::Basic::Type *realm, const std::u16string &name) override; 38 | virtual void OnRealmExit(mule::Data::Basic::Type *realm, const std::u16string &name) override; 39 | virtual void OnRealmEnter(mule::Data::Basic::Type *realm, int idx) override; 40 | virtual void OnRealmExit(mule::Data::Basic::Type *realm, int idx) override; 41 | virtual void OnDataRead(const mule::Data::Basic::MultiValue &value) override; 42 | virtual const mule::Data::Basic::MultiValue OnDataWrite() override; 43 | 44 | virtual void AppendMetadatum(std::u16string name, const mule::Data::Basic::MultiValue &mv) override; 45 | protected: 46 | xybase::xml::XmlParser xmlParser; 47 | 48 | private: 49 | void ReadTagAndParse(const std::u8string &tagName, xybase::StringBuilder &sb, bool isString, bool isText); 50 | enum { 51 | XHS_IDLE, 52 | XHS_READ, 53 | XHS_READ_METADATA_WAITING, 54 | XHS_WRITE, 55 | } status; 56 | 57 | mule::Data::Basic::MultiValue element; 58 | 59 | std::u16string nodeName; 60 | 61 | int layer = 0; 62 | }; 63 | } 64 | } 65 | 66 | #endif /* End of XML_HANDLER_H__*/ 67 | --------------------------------------------------------------------------------