mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-03-31 10:21:37 +08:00
Compare commits
11 Commits
v9.0.3.26
...
feature/xm
| Author | SHA1 | Date | |
|---|---|---|---|
| 39b17d3edf | |||
| 719c0d21be | |||
| 08ced34aec | |||
| 5fe55ab81a | |||
| 7f245c4f0a | |||
| 7d1fa1c04e | |||
| 7fc5ae2ea8 | |||
| dc41250a5f | |||
| c6cfb03c1d | |||
| 1eb34c3141 | |||
| b224660d70 |
150
OdfFile/Common/xml/TestBuffer/GoogleTest/GoogleTest.vcxproj
Normal file
150
OdfFile/Common/xml/TestBuffer/GoogleTest/GoogleTest.vcxproj
Normal file
@ -0,0 +1,150 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectGuid>{40bb3bec-636b-4b69-b525-8cfde870abab}</ProjectGuid>
|
||||
<RootNamespace>GoogleTest</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>C:\Users\mrkir\googletest-main\googletest;C:\Users\mrkir\googletest-main\googletest\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>C:\Users\mrkir\googletest-main\googletest\include;C:\Users\mrkir\googletest-main\googletest;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\..\..\..\..\googletest-main\googletest\src\gtest-all.cc" />
|
||||
<ClCompile Include="..\..\..\..\..\..\googletest-main\googletest\src\gtest_main.cc" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Исходные файлы">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Файлы заголовков">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Файлы ресурсов">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\..\..\..\..\googletest-main\googletest\src\gtest_main.cc">
|
||||
<Filter>Файлы ресурсов</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\..\..\googletest-main\googletest\src\gtest-all.cc">
|
||||
<Filter>Файлы ресурсов</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@ -5,6 +5,10 @@ VisualStudioVersion = 16.0.33801.447
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestBuffer", "TestBuffer\TestBuffer.vcxproj", "{B16BF38E-B08B-47DF-99E6-2677B43AAC01}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GoogleTest", "GoogleTest\GoogleTest.vcxproj", "{40BB3BEC-636B-4B69-B525-8CFDE870ABAB}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UniteTest", "UniteTest\UniteTest.vcxproj", "{4C0D1C2B-EC5B-4DC1-85D3-7E05E93BF5AB}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
@ -21,6 +25,22 @@ Global
|
||||
{B16BF38E-B08B-47DF-99E6-2677B43AAC01}.Release|x64.Build.0 = Release|x64
|
||||
{B16BF38E-B08B-47DF-99E6-2677B43AAC01}.Release|x86.ActiveCfg = Release|Win32
|
||||
{B16BF38E-B08B-47DF-99E6-2677B43AAC01}.Release|x86.Build.0 = Release|Win32
|
||||
{40BB3BEC-636B-4B69-B525-8CFDE870ABAB}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{40BB3BEC-636B-4B69-B525-8CFDE870ABAB}.Debug|x64.Build.0 = Debug|x64
|
||||
{40BB3BEC-636B-4B69-B525-8CFDE870ABAB}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{40BB3BEC-636B-4B69-B525-8CFDE870ABAB}.Debug|x86.Build.0 = Debug|Win32
|
||||
{40BB3BEC-636B-4B69-B525-8CFDE870ABAB}.Release|x64.ActiveCfg = Release|x64
|
||||
{40BB3BEC-636B-4B69-B525-8CFDE870ABAB}.Release|x64.Build.0 = Release|x64
|
||||
{40BB3BEC-636B-4B69-B525-8CFDE870ABAB}.Release|x86.ActiveCfg = Release|Win32
|
||||
{40BB3BEC-636B-4B69-B525-8CFDE870ABAB}.Release|x86.Build.0 = Release|Win32
|
||||
{4C0D1C2B-EC5B-4DC1-85D3-7E05E93BF5AB}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{4C0D1C2B-EC5B-4DC1-85D3-7E05E93BF5AB}.Debug|x64.Build.0 = Debug|x64
|
||||
{4C0D1C2B-EC5B-4DC1-85D3-7E05E93BF5AB}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{4C0D1C2B-EC5B-4DC1-85D3-7E05E93BF5AB}.Debug|x86.Build.0 = Debug|Win32
|
||||
{4C0D1C2B-EC5B-4DC1-85D3-7E05E93BF5AB}.Release|x64.ActiveCfg = Release|x64
|
||||
{4C0D1C2B-EC5B-4DC1-85D3-7E05E93BF5AB}.Release|x64.Build.0 = Release|x64
|
||||
{4C0D1C2B-EC5B-4DC1-85D3-7E05E93BF5AB}.Release|x86.ActiveCfg = Release|Win32
|
||||
{4C0D1C2B-EC5B-4DC1-85D3-7E05E93BF5AB}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
@ -88,6 +88,7 @@
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>C:\Users\mrkir\googletest-main\googletest\include;C:\Users\mrkir\googletest-main\googletest;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@ -116,6 +117,7 @@
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>C:\Users\mrkir\googletest-main\googletest;C:\Users\mrkir\googletest-main\googletest\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@ -139,6 +141,7 @@
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\simple_xml_writer.h" />
|
||||
<ClInclude Include="simple_xml_writer2.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
|
||||
@ -18,5 +18,8 @@
|
||||
<ClInclude Include="simple_xml_writer2.h">
|
||||
<Filter>Файлы заголовков</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\simple_xml_writer.h">
|
||||
<Filter>Файлы заголовков</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
140
OdfFile/Common/xml/TestBuffer/UniteTest/UniteTest.vcxproj
Normal file
140
OdfFile/Common/xml/TestBuffer/UniteTest/UniteTest.vcxproj
Normal file
@ -0,0 +1,140 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{4c0d1c2b-ec5b-4dc1-85d3-7e05e93bf5ab}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<WindowsTargetPlatformVersion>10.0.22000.0</WindowsTargetPlatformVersion>
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings" />
|
||||
<ImportGroup Label="Shared" />
|
||||
<ImportGroup Label="PropertySheets" />
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\simple_xml_writer.h" />
|
||||
<ClInclude Include="..\..\simple_xml_writer2.h" />
|
||||
<ClInclude Include="..\..\simple_xml_writer3.h" />
|
||||
<ClInclude Include="..\..\simple_xml_writer4.h" />
|
||||
<ClInclude Include="pch.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="test.cpp" />
|
||||
<ClCompile Include="pch.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\GoogleTest\GoogleTest.vcxproj">
|
||||
<Project>{40bb3bec-636b-4b69-b525-8cfde870abab}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\TestBuffer\TestBuffer.vcxproj">
|
||||
<Project>{b16bf38e-b08b-47df-99e6-2677b43aac01}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemDefinitionGroup />
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="..\packages\Microsoft.googletest.v140.windesktop.msvcstl.static.rt-dyn.1.8.1.4\build\native\Microsoft.googletest.v140.windesktop.msvcstl.static.rt-dyn.targets" Condition="Exists('..\packages\Microsoft.googletest.v140.windesktop.msvcstl.static.rt-dyn.1.8.1.4\build\native\Microsoft.googletest.v140.windesktop.msvcstl.static.rt-dyn.targets')" />
|
||||
</ImportGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<AdditionalIncludeDirectories>C:\Users\mrkir\googletest-main\googletest;C:\Users\mrkir\googletest-main\googletest\include;C:\Users\mrkir\core\OdfFile\Common\xml\TestBuffer\TestBuffer;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<ForcedIncludeFiles>pch.h</ForcedIncludeFiles>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<AdditionalDependencies>C:\Users\mrkir\core\build\lib\win_64\debug\kernel.lib;C:\Users\mrkir\core\build\lib\win_64\debug\UnicodeConverter.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>X64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<AdditionalIncludeDirectories>C:\Users\mrkir\googletest-main\googletest;C:\Users\mrkir\googletest-main\googletest\include;C:\Users\mrkir\core\OdfFile\Common\xml\TestBuffer;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<ForcedIncludeFiles>pch.h</ForcedIncludeFiles>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<PreprocessorDefinitions>X64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>Данный проект ссылается на пакеты NuGet, отсутствующие на этом компьютере. Используйте восстановление пакетов NuGet, чтобы скачать их. Дополнительную информацию см. по адресу: http://go.microsoft.com/fwlink/?LinkID=322105. Отсутствует следующий файл: {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\packages\Microsoft.googletest.v140.windesktop.msvcstl.static.rt-dyn.1.8.1.4\build\native\Microsoft.googletest.v140.windesktop.msvcstl.static.rt-dyn.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.googletest.v140.windesktop.msvcstl.static.rt-dyn.1.8.1.4\build\native\Microsoft.googletest.v140.windesktop.msvcstl.static.rt-dyn.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
||||
4
OdfFile/Common/xml/TestBuffer/UniteTest/packages.config
Normal file
4
OdfFile/Common/xml/TestBuffer/UniteTest/packages.config
Normal file
@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.googletest.v140.windesktop.msvcstl.static.rt-dyn" version="1.8.1.4" targetFramework="native" />
|
||||
</packages>
|
||||
5
OdfFile/Common/xml/TestBuffer/UniteTest/pch.cpp
Normal file
5
OdfFile/Common/xml/TestBuffer/UniteTest/pch.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
//
|
||||
// pch.cpp
|
||||
//
|
||||
|
||||
#include "pch.h"
|
||||
7
OdfFile/Common/xml/TestBuffer/UniteTest/pch.h
Normal file
7
OdfFile/Common/xml/TestBuffer/UniteTest/pch.h
Normal file
@ -0,0 +1,7 @@
|
||||
//
|
||||
// pch.h
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
860
OdfFile/Common/xml/TestBuffer/UniteTest/test.cpp
Normal file
860
OdfFile/Common/xml/TestBuffer/UniteTest/test.cpp
Normal file
@ -0,0 +1,860 @@
|
||||
#pragma comment(lib, "../../../../../build/lib/win_64/debug/kernel.lib")
|
||||
#pragma comment(lib, "../../../../../build/lib/win_64/debug/UnicodeConverter.lib")
|
||||
#include <iostream>
|
||||
#include <random>
|
||||
#include <sstream>
|
||||
#include <chrono>
|
||||
#include <codecvt>
|
||||
#include <fstream>
|
||||
#include "../../../utf8cpp/utf8.h"
|
||||
#include "../../../../DesktopEditor/common/File.h"
|
||||
#include "../../../../../DesktopEditor/xml/include/xmlutils.h"
|
||||
#include "../../simple_xml_writer.h"
|
||||
#include "../../simple_xml_writer4.h"
|
||||
|
||||
using namespace cpdoccore;
|
||||
|
||||
class BufferTest : public testing::Test
|
||||
{
|
||||
public:
|
||||
std::wstring data;
|
||||
std::wstring data1;
|
||||
std::wstring data2;
|
||||
public:
|
||||
virtual void SetUp() override
|
||||
{
|
||||
std::random_device rd;
|
||||
std::mt19937 gen(rd());
|
||||
std::uniform_int_distribution<> dis(0x0020, 0x007E);
|
||||
|
||||
data.reserve(250);
|
||||
data1.reserve(100);
|
||||
data2.reserve(50);
|
||||
|
||||
for (size_t i = 0; i < 250; ++i) data.push_back(static_cast<wchar_t>(dis(gen)));
|
||||
for (size_t i = 0; i < 100; ++i) data1.push_back(static_cast<wchar_t>(dis(gen)));
|
||||
for (size_t i = 0; i < 50; ++i) data2.push_back(static_cast<wchar_t>(dis(gen)));
|
||||
}
|
||||
virtual void TearDown() override
|
||||
{
|
||||
data.clear();
|
||||
data1.clear();
|
||||
data2.clear();
|
||||
}
|
||||
};
|
||||
|
||||
class ReadAndWrite
|
||||
{
|
||||
public:
|
||||
ReadAndWrite(xml_writer& _xml_wr_, XmlUtils::CXmlLiteReader& oReader) : _xml_wr_(_xml_wr_), oReader(oReader) {};
|
||||
~ReadAndWrite() {};
|
||||
void AddNode(int depth)
|
||||
{
|
||||
while (oReader.ReadNextSiblingNode(depth))
|
||||
{
|
||||
int tmp = oReader.GetDepth();
|
||||
std::wstring sName = oReader.GetName();
|
||||
CP_XML_NODE(sName)
|
||||
{
|
||||
int na = oReader.GetAttributesCount();
|
||||
if (na > 0)
|
||||
{
|
||||
if (oReader.MoveToFirstAttribute())
|
||||
{
|
||||
std::wstring sNameAttr = oReader.GetName();
|
||||
std::wstring sAttr = oReader.GetText();
|
||||
CP_XML_ATTR2(sNameAttr, sAttr);
|
||||
for (int i = 1; i < na; i++)
|
||||
{
|
||||
if (oReader.MoveToNextAttribute())
|
||||
{
|
||||
sNameAttr = oReader.GetName();
|
||||
sAttr = oReader.GetText();
|
||||
CP_XML_ATTR2(sNameAttr, sAttr);
|
||||
}
|
||||
}
|
||||
oReader.MoveToElement();
|
||||
}
|
||||
}
|
||||
if ((sName == L"w:t" || sName == L"w:instrText" || sName == L"m:t" || sName == L"wp:posOffset" || sName == L"w14:pctHeight" || sName == L"w14:pctWidth" || sName == L"wp:align") && !oReader.IsEmptyNode())
|
||||
{
|
||||
std::wstring sVal = oReader.GetText2();
|
||||
CP_XML_CONTENT(sVal);
|
||||
}
|
||||
else if (!oReader.IsEmptyNode()) this->AddNode(tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
xml_writer& _xml_wr_;
|
||||
XmlUtils::CXmlLiteReader& oReader;
|
||||
};
|
||||
|
||||
class ReadAndWrite4
|
||||
{
|
||||
public:
|
||||
ReadAndWrite4(xml_writer4& _xml_wr_4, XmlUtils::CXmlLiteReader& oReader) : _xml_wr_4(_xml_wr_4), oReader(oReader) {};
|
||||
~ReadAndWrite4() {};
|
||||
void AddNode(int depth)
|
||||
{
|
||||
while (oReader.ReadNextSiblingNode(depth))
|
||||
{
|
||||
int tmp = oReader.GetDepth();
|
||||
std::wstring sName = oReader.GetName();
|
||||
CP_XML_NODE_4(sName)
|
||||
{
|
||||
int na = oReader.GetAttributesCount();
|
||||
if (na > 0)
|
||||
{
|
||||
if (oReader.MoveToFirstAttribute())
|
||||
{
|
||||
std::wstring sNameAttr = oReader.GetName();
|
||||
std::wstring sAttr = oReader.GetText();
|
||||
CP_XML_ATTR2_4(sNameAttr, sAttr);
|
||||
for (int i = 1; i < na; i++)
|
||||
{
|
||||
if (oReader.MoveToNextAttribute())
|
||||
{
|
||||
sNameAttr = oReader.GetName();
|
||||
sAttr = oReader.GetText();
|
||||
CP_XML_ATTR2_4(sNameAttr, sAttr);
|
||||
}
|
||||
}
|
||||
oReader.MoveToElement();
|
||||
}
|
||||
}
|
||||
if ((sName == L"w:t" || sName == L"w:instrText" || sName == L"m:t" || sName == L"wp:posOffset" || sName == L"w14:pctHeight" || sName == L"w14:pctWidth" || sName == L"wp:align") && !oReader.IsEmptyNode())
|
||||
{
|
||||
std::wstring sVal = oReader.GetText2();
|
||||
CP_XML_CONTENT_4(sVal);
|
||||
}
|
||||
else if (!oReader.IsEmptyNode()) this->AddNode(tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
public:
|
||||
xml_writer4& _xml_wr_4;
|
||||
XmlUtils::CXmlLiteReader& oReader;
|
||||
};
|
||||
|
||||
class ReadAndStringBuild
|
||||
{
|
||||
public:
|
||||
ReadAndStringBuild(XmlUtils::CXmlLiteReader& R, NSStringUtils::CStringBuilder& B) : oReader(R), oBuilder(B) {};
|
||||
~ReadAndStringBuild() {};
|
||||
void AddNode(int depth)
|
||||
{
|
||||
while (oReader.ReadNextSiblingNode(depth))
|
||||
{
|
||||
int tmp = oReader.GetDepth();
|
||||
std::wstring sName = oReader.GetName();
|
||||
oBuilder.WriteString(L"<");
|
||||
oBuilder.WriteEncodeXmlString(sName);
|
||||
int na = oReader.GetAttributesCount();
|
||||
if (na > 0)
|
||||
{
|
||||
if (oReader.MoveToFirstAttribute())
|
||||
{
|
||||
std::wstring sNameAttr = oReader.GetName();
|
||||
std::wstring sAttr = oReader.GetText();
|
||||
oBuilder.WriteString(L" ");
|
||||
oBuilder.WriteEncodeXmlString(sNameAttr);
|
||||
oBuilder.WriteString(L"=\"");
|
||||
oBuilder.WriteEncodeXmlString(sAttr);
|
||||
oBuilder.WriteString(L"\"");
|
||||
for (int i = 1; i < na; i++)
|
||||
{
|
||||
if (oReader.MoveToNextAttribute())
|
||||
{
|
||||
sNameAttr = oReader.GetName();
|
||||
sAttr = oReader.GetText();
|
||||
oBuilder.WriteString(L" ");
|
||||
oBuilder.WriteEncodeXmlString(sNameAttr);
|
||||
oBuilder.WriteString(L"=\"");
|
||||
oBuilder.WriteEncodeXmlString(sAttr);
|
||||
oBuilder.WriteString(L"\"");
|
||||
}
|
||||
}
|
||||
oReader.MoveToElement();
|
||||
}
|
||||
}
|
||||
if (oReader.IsEmptyNode()) oBuilder.WriteString(L"/>");
|
||||
else oBuilder.WriteString(L">");
|
||||
if ((sName == L"w:t" || sName == L"w:instrText" || sName == L"m:t" || sName == L"wp:posOffset" || sName == L"w14:pctHeight" || sName == L"w14:pctWidth" || sName == L"wp:align") && !oReader.IsEmptyNode())
|
||||
{
|
||||
std::wstring sVal = oReader.GetText2();
|
||||
oBuilder.WriteEncodeXmlString(sVal);
|
||||
oBuilder.WriteString(L"</");
|
||||
oBuilder.WriteEncodeXmlString(sName);
|
||||
oBuilder.WriteString(L">");
|
||||
}
|
||||
else if (!oReader.IsEmptyNode())
|
||||
{
|
||||
this->AddNode(tmp);
|
||||
oBuilder.WriteString(L"</");
|
||||
oBuilder.WriteEncodeXmlString(sName);
|
||||
oBuilder.WriteString(L">");
|
||||
}
|
||||
}
|
||||
}
|
||||
public:
|
||||
XmlUtils::CXmlLiteReader& oReader;
|
||||
NSStringUtils::CStringBuilder& oBuilder;
|
||||
};
|
||||
|
||||
TEST_F(BufferTest, main_test_read_and_write_xml_with_buffer_and_sstream)
|
||||
{
|
||||
std::wstring filename(__argv[1], __argv[1] + strlen(__argv[1]));
|
||||
XmlUtils::CXmlLiteReader oReader;
|
||||
if (!oReader.FromFile(filename))
|
||||
return;
|
||||
if (!oReader.ReadNextNode())
|
||||
return;
|
||||
|
||||
int n = oReader.GetDepth();
|
||||
std::wstring sName = oReader.GetName();
|
||||
|
||||
//Reading and writing an XML doc via buffer
|
||||
auto begin1 = std::chrono::steady_clock::now();
|
||||
xml::CBufferXml3 outputbuffer;
|
||||
CP_XML_WRITER_4(outputbuffer)
|
||||
{
|
||||
CP_XML_NODE_4(sName)
|
||||
{
|
||||
int na = oReader.GetAttributesCount();
|
||||
if (na > 0)
|
||||
{
|
||||
if (oReader.MoveToFirstAttribute())
|
||||
{
|
||||
CP_XML_ATTR2_4(oReader.GetName(), oReader.GetText());
|
||||
for (int i = 1; i < na; i++)
|
||||
if (oReader.MoveToNextAttribute())
|
||||
CP_XML_ATTR2_4(oReader.GetName(), oReader.GetText());
|
||||
oReader.MoveToElement();
|
||||
}
|
||||
}
|
||||
ReadAndWrite4 rnw(_xml_wr_4, oReader);
|
||||
rnw.AddNode(n);
|
||||
}
|
||||
}
|
||||
auto end1 = std::chrono::steady_clock::now();
|
||||
auto elapsed_ms1 = std::chrono::duration_cast<std::chrono::milliseconds>(end1 - begin1);
|
||||
|
||||
if (!oReader.MoveToStart())
|
||||
return;
|
||||
if (!oReader.ReadNextNode())
|
||||
return;
|
||||
|
||||
sName = oReader.GetName();
|
||||
n = oReader.GetDepth();
|
||||
|
||||
//Reading and writing an XML doc via sstream
|
||||
auto begin2 = std::chrono::steady_clock::now();
|
||||
std::wstringstream outputstream;
|
||||
CP_XML_WRITER(outputstream)
|
||||
{
|
||||
CP_XML_NODE(sName)
|
||||
{
|
||||
int na = oReader.GetAttributesCount();
|
||||
if (na > 0)
|
||||
{
|
||||
if (oReader.MoveToFirstAttribute())
|
||||
{
|
||||
CP_XML_ATTR2(oReader.GetName(), oReader.GetText());
|
||||
for (int i = 1; i < na; i++)
|
||||
if (oReader.MoveToNextAttribute())
|
||||
CP_XML_ATTR2(oReader.GetName(), oReader.GetText());
|
||||
oReader.MoveToElement();
|
||||
}
|
||||
}
|
||||
ReadAndWrite rnw(_xml_wr_, oReader);
|
||||
rnw.AddNode(n);
|
||||
}
|
||||
}
|
||||
auto end2 = std::chrono::steady_clock::now();
|
||||
auto elapsed_ms2 = std::chrono::duration_cast<std::chrono::milliseconds>(end2 - begin2);
|
||||
EXPECT_EQ(outputstream.str(), outputbuffer.str());
|
||||
std::string res;
|
||||
std::wstring out = outputstream.str();
|
||||
utf8::utf16to8(out.begin(), out.end(), std::back_inserter(res));
|
||||
NSFile::CFileBinary file;
|
||||
if (file.CreateFileW(std::wstring_convert<std::codecvt_utf8<wchar_t>>().from_bytes(__argv[3])) == true)
|
||||
{
|
||||
std::string root = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>";
|
||||
file.WriteFile((BYTE*)root.c_str(), root.length());
|
||||
file.WriteFile((BYTE*)res.c_str(), res.length());
|
||||
file.CloseFile();
|
||||
}
|
||||
|
||||
std::cout << '\n' << "Reading and writing an XML doc via buffer time - " << elapsed_ms1.count() / 1000 / 60 << "(min)" << elapsed_ms1.count() / 1000 % 60 << "(s)" << elapsed_ms1.count() % 1000 << "(ms)" << '\n' << "Reading and writing an XML doc via sstream time - " << elapsed_ms2.count() / 1000 / 60 << "(min)" << elapsed_ms2.count() / 1000 % 60 << "(s)" << elapsed_ms2.count() % 1000 << "(ms)" << '\n';
|
||||
}
|
||||
|
||||
TEST_F(BufferTest, test_stringstream_operator)
|
||||
{
|
||||
std::wstring filename(__argv[1], __argv[1] + strlen(__argv[1]));
|
||||
XmlUtils::CXmlLiteReader oReader;
|
||||
if (!oReader.FromFile(filename))
|
||||
return;
|
||||
if (!oReader.ReadNextNode())
|
||||
return;
|
||||
|
||||
int n = oReader.GetDepth();
|
||||
std::wstring sName = oReader.GetName();
|
||||
|
||||
//Reading and writing an XML doc via sstream
|
||||
std::wstringstream outputstream;
|
||||
CP_XML_WRITER(outputstream)
|
||||
{
|
||||
CP_XML_NODE(sName)
|
||||
{
|
||||
int na = oReader.GetAttributesCount();
|
||||
if (na > 0)
|
||||
{
|
||||
if (oReader.MoveToFirstAttribute())
|
||||
{
|
||||
CP_XML_ATTR2(oReader.GetName(), oReader.GetText());
|
||||
for (int i = 1; i < na; i++)
|
||||
if (oReader.MoveToNextAttribute())
|
||||
CP_XML_ATTR2(oReader.GetName(), oReader.GetText());
|
||||
oReader.MoveToElement();
|
||||
}
|
||||
}
|
||||
ReadAndWrite rnw(_xml_wr_, oReader);
|
||||
rnw.AddNode(n);
|
||||
}
|
||||
}
|
||||
|
||||
auto begin1 = std::chrono::steady_clock::now();
|
||||
std::wstringstream outputstream1;
|
||||
for (size_t i = 0; i < 10; i++)
|
||||
{
|
||||
outputstream1 << outputstream.str();
|
||||
}
|
||||
auto end1 = std::chrono::steady_clock::now();
|
||||
auto elapsed_mcs1 = std::chrono::duration_cast<std::chrono::microseconds>(end1 - begin1);
|
||||
|
||||
std::cout << "Time of adding two streams into one " << elapsed_mcs1.count() << "(mcs)" << '\n';
|
||||
}
|
||||
|
||||
TEST_F(BufferTest, test_buffer_operators_sum_and_eq)
|
||||
{
|
||||
std::wstring filename(__argv[2], __argv[2] + strlen(__argv[2]));
|
||||
XmlUtils::CXmlLiteReader oReader;
|
||||
if (!oReader.FromFile(filename))
|
||||
return;
|
||||
if (!oReader.ReadNextNode())
|
||||
return;
|
||||
|
||||
int n = oReader.GetDepth();
|
||||
std::wstring sName = oReader.GetName();
|
||||
|
||||
//Reading and writing an XML doc via buffer
|
||||
xml::CBufferXml3 outputbuffer1;
|
||||
CP_XML_WRITER_4(outputbuffer1)
|
||||
{
|
||||
CP_XML_NODE_4(sName)
|
||||
{
|
||||
int na = oReader.GetAttributesCount();
|
||||
if (na > 0)
|
||||
{
|
||||
if (oReader.MoveToFirstAttribute())
|
||||
{
|
||||
CP_XML_ATTR2_4(oReader.GetName(), oReader.GetText());
|
||||
for (int i = 1; i < na; i++)
|
||||
if (oReader.MoveToNextAttribute())
|
||||
CP_XML_ATTR2_4(oReader.GetName(), oReader.GetText());
|
||||
oReader.MoveToElement();
|
||||
}
|
||||
}
|
||||
ReadAndWrite4 rnw(_xml_wr_4, oReader);
|
||||
rnw.AddNode(n);
|
||||
}
|
||||
}
|
||||
|
||||
std::wstring filename1(__argv[1], __argv[1] + strlen(__argv[1]));
|
||||
if (!oReader.FromFile(filename1))
|
||||
return;
|
||||
if (!oReader.ReadNextNode())
|
||||
return;
|
||||
|
||||
n = oReader.GetDepth();
|
||||
sName = oReader.GetName();
|
||||
|
||||
//Reading and writing an XML doc via buffer
|
||||
xml::CBufferXml3 outputbuffer2;
|
||||
CP_XML_WRITER_4(outputbuffer2)
|
||||
{
|
||||
CP_XML_NODE_4(sName)
|
||||
{
|
||||
int na = oReader.GetAttributesCount();
|
||||
if (na > 0)
|
||||
{
|
||||
if (oReader.MoveToFirstAttribute())
|
||||
{
|
||||
CP_XML_ATTR2_4(oReader.GetName(), oReader.GetText());
|
||||
for (int i = 1; i < na; i++)
|
||||
if (oReader.MoveToNextAttribute())
|
||||
CP_XML_ATTR2_4(oReader.GetName(), oReader.GetText());
|
||||
oReader.MoveToElement();
|
||||
}
|
||||
}
|
||||
ReadAndWrite4 rnw(_xml_wr_4, oReader);
|
||||
rnw.AddNode(n);
|
||||
}
|
||||
}
|
||||
|
||||
auto begin1 = std::chrono::steady_clock::now();
|
||||
for (size_t i = 0; i < 10; i++)
|
||||
{
|
||||
outputbuffer1 = outputbuffer1 + outputbuffer2;
|
||||
}
|
||||
auto end1 = std::chrono::steady_clock::now();
|
||||
auto elapsed_mcs1 = std::chrono::duration_cast<std::chrono::microseconds>(end1 - begin1);
|
||||
|
||||
std::string res = outputbuffer1.utf8();
|
||||
NSFile::CFileBinary file;
|
||||
if (file.CreateFileW(std::wstring_convert<std::codecvt_utf8<wchar_t>>().from_bytes(__argv[4])) == true)
|
||||
{
|
||||
std::string root = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>";
|
||||
file.WriteFile((BYTE*)root.c_str(), root.length());
|
||||
file.WriteFile((BYTE*)res.c_str(), res.length());
|
||||
file.CloseFile();
|
||||
}
|
||||
|
||||
std::cout << "Time of adding two buffers into one " << elapsed_mcs1.count() << "(mcs)" << '\n';
|
||||
}
|
||||
|
||||
TEST_F(BufferTest, test_buffer_operator_add)
|
||||
{
|
||||
std::wstring filename(__argv[2], __argv[2] + strlen(__argv[2]));
|
||||
XmlUtils::CXmlLiteReader oReader;
|
||||
if (!oReader.FromFile(filename))
|
||||
return;
|
||||
if (!oReader.ReadNextNode())
|
||||
return;
|
||||
|
||||
int n = oReader.GetDepth();
|
||||
std::wstring sName = oReader.GetName();
|
||||
|
||||
//Reading and writing an XML doc via buffer
|
||||
xml::CBufferXml3 outputbuffer1;
|
||||
CP_XML_WRITER_4(outputbuffer1)
|
||||
{
|
||||
CP_XML_NODE_4(sName)
|
||||
{
|
||||
int na = oReader.GetAttributesCount();
|
||||
if (na > 0)
|
||||
{
|
||||
if (oReader.MoveToFirstAttribute())
|
||||
{
|
||||
CP_XML_ATTR2_4(oReader.GetName(), oReader.GetText());
|
||||
for (int i = 1; i < na; i++)
|
||||
if (oReader.MoveToNextAttribute())
|
||||
CP_XML_ATTR2_4(oReader.GetName(), oReader.GetText());
|
||||
oReader.MoveToElement();
|
||||
}
|
||||
}
|
||||
ReadAndWrite4 rnw(_xml_wr_4, oReader);
|
||||
rnw.AddNode(n);
|
||||
}
|
||||
}
|
||||
|
||||
std::wstring filename1(__argv[1], __argv[1] + strlen(__argv[1]));
|
||||
if (!oReader.FromFile(filename1))
|
||||
return;
|
||||
if (!oReader.ReadNextNode())
|
||||
return;
|
||||
|
||||
n = oReader.GetDepth();
|
||||
sName = oReader.GetName();
|
||||
|
||||
//Reading and writing an XML doc via buffer
|
||||
xml::CBufferXml3 outputbuffer2;
|
||||
CP_XML_WRITER_4(outputbuffer2)
|
||||
{
|
||||
CP_XML_NODE_4(sName)
|
||||
{
|
||||
int na = oReader.GetAttributesCount();
|
||||
if (na > 0)
|
||||
{
|
||||
if (oReader.MoveToFirstAttribute())
|
||||
{
|
||||
CP_XML_ATTR2_4(oReader.GetName(), oReader.GetText());
|
||||
for (int i = 1; i < na; i++)
|
||||
if (oReader.MoveToNextAttribute())
|
||||
CP_XML_ATTR2_4(oReader.GetName(), oReader.GetText());
|
||||
oReader.MoveToElement();
|
||||
}
|
||||
}
|
||||
ReadAndWrite4 rnw(_xml_wr_4, oReader);
|
||||
rnw.AddNode(n);
|
||||
}
|
||||
}
|
||||
|
||||
auto begin2 = std::chrono::steady_clock::now();
|
||||
for (size_t i = 0; i < 10; i++)
|
||||
{
|
||||
outputbuffer1 += outputbuffer2;
|
||||
}
|
||||
auto end2 = std::chrono::steady_clock::now();
|
||||
auto elapsed_mcs2 = std::chrono::duration_cast<std::chrono::microseconds>(end2 - begin2);
|
||||
|
||||
NSFile::CFileBinary file;
|
||||
std::string res = outputbuffer1.utf8();
|
||||
if (file.CreateFileW(std::wstring_convert<std::codecvt_utf8<wchar_t>>().from_bytes(__argv[5])) == true)
|
||||
{
|
||||
std::string root = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>";
|
||||
file.WriteFile((BYTE*)root.c_str(), root.length());
|
||||
file.WriteFile((BYTE*)res.c_str(), res.length());
|
||||
file.CloseFile();
|
||||
}
|
||||
|
||||
std::cout << "Time of adding the second buffer to the first one " << elapsed_mcs2.count() << "(mcs)" << '\n';
|
||||
|
||||
}
|
||||
|
||||
TEST_F(BufferTest, test_StringBuild_time)
|
||||
{
|
||||
//Reading and writing an XML doc via StringBuild
|
||||
std::wstring filename(__argv[1], __argv[1] + strlen(__argv[1]));
|
||||
XmlUtils::CXmlLiteReader oReader;
|
||||
if (!oReader.FromFile(filename))
|
||||
return;
|
||||
if (!oReader.ReadNextNode())
|
||||
return;
|
||||
|
||||
int n = oReader.GetDepth();
|
||||
std::wstring sName = oReader.GetName();
|
||||
auto begin1 = std::chrono::steady_clock::now();
|
||||
NSStringUtils::CStringBuilder oBuilder;
|
||||
oBuilder.WriteString(L"<");
|
||||
oBuilder.WriteEncodeXmlString(sName);
|
||||
int na = oReader.GetAttributesCount();
|
||||
if (na > 0)
|
||||
{
|
||||
if (oReader.MoveToFirstAttribute())
|
||||
{
|
||||
std::wstring sNameAttr = oReader.GetName();
|
||||
std::wstring sAttr = oReader.GetText();
|
||||
oBuilder.WriteString(L" ");
|
||||
oBuilder.WriteEncodeXmlString(sNameAttr);
|
||||
oBuilder.WriteString(L"=\"");
|
||||
oBuilder.WriteEncodeXmlString(sAttr);
|
||||
oBuilder.WriteString(L"\"");
|
||||
for (int i = 1; i < na; i++)
|
||||
{
|
||||
if (oReader.MoveToNextAttribute())
|
||||
{
|
||||
sNameAttr = oReader.GetName();
|
||||
sAttr = oReader.GetText();
|
||||
oBuilder.WriteString(L" ");
|
||||
oBuilder.WriteEncodeXmlString(sNameAttr);
|
||||
oBuilder.WriteString(L"=\"");
|
||||
oBuilder.WriteEncodeXmlString(sAttr);
|
||||
oBuilder.WriteString(L"\"");
|
||||
}
|
||||
}
|
||||
oReader.MoveToElement();
|
||||
}
|
||||
}
|
||||
if (oReader.IsEmptyNode()) oBuilder.WriteString(L"/>");
|
||||
else oBuilder.WriteString(L">");
|
||||
ReadAndStringBuild abc(oReader, oBuilder);
|
||||
abc.AddNode(n);
|
||||
oBuilder.WriteString(L"</");
|
||||
oBuilder.WriteEncodeXmlString(sName);
|
||||
oBuilder.WriteString(L">");
|
||||
auto end1 = std::chrono::steady_clock::now();
|
||||
auto elapsed_ms1 = std::chrono::duration_cast<std::chrono::milliseconds>(end1 - begin1);
|
||||
|
||||
std::string res;
|
||||
std::wstring out = oBuilder.GetData();
|
||||
utf8::utf16to8(out.begin(), out.end(), std::back_inserter(res));
|
||||
NSFile::CFileBinary file;
|
||||
if (file.CreateFileW(std::wstring_convert<std::codecvt_utf8<wchar_t>>().from_bytes(__argv[6])) == true)
|
||||
{
|
||||
std::string root = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>";
|
||||
file.WriteFile((BYTE*)root.c_str(), root.length());
|
||||
file.WriteFile((BYTE*)res.c_str(), res.length());
|
||||
file.CloseFile();
|
||||
}
|
||||
|
||||
std::cout << '\n' << "Reading and writing an XML doc via StringBuild - " << elapsed_ms1.count() / 1000 / 60 << "(min)" << elapsed_ms1.count() / 1000 % 60 << "(s)" << elapsed_ms1.count() % 1000 << "(ms)" << '\n';
|
||||
}
|
||||
|
||||
TEST_F(BufferTest, test_stringbuild_operator)
|
||||
{
|
||||
//Reading and writing an XML doc via StringBuild
|
||||
std::wstring filename(__argv[1], __argv[1] + strlen(__argv[1]));
|
||||
XmlUtils::CXmlLiteReader oReader;
|
||||
if (!oReader.FromFile(filename))
|
||||
return;
|
||||
if (!oReader.ReadNextNode())
|
||||
return;
|
||||
|
||||
int n = oReader.GetDepth();
|
||||
std::wstring sName = oReader.GetName();
|
||||
NSStringUtils::CStringBuilder oBuilder;
|
||||
oBuilder.WriteString(L"<");
|
||||
oBuilder.WriteEncodeXmlString(sName);
|
||||
int na = oReader.GetAttributesCount();
|
||||
if (na > 0)
|
||||
{
|
||||
if (oReader.MoveToFirstAttribute())
|
||||
{
|
||||
std::wstring sNameAttr = oReader.GetName();
|
||||
std::wstring sAttr = oReader.GetText();
|
||||
oBuilder.WriteString(L" ");
|
||||
oBuilder.WriteEncodeXmlString(sNameAttr);
|
||||
oBuilder.WriteString(L"=\"");
|
||||
oBuilder.WriteEncodeXmlString(sAttr);
|
||||
oBuilder.WriteString(L"\"");
|
||||
for (int i = 1; i < na; i++)
|
||||
{
|
||||
if (oReader.MoveToNextAttribute())
|
||||
{
|
||||
sNameAttr = oReader.GetName();
|
||||
sAttr = oReader.GetText();
|
||||
oBuilder.WriteString(L" ");
|
||||
oBuilder.WriteEncodeXmlString(sNameAttr);
|
||||
oBuilder.WriteString(L"=\"");
|
||||
oBuilder.WriteEncodeXmlString(sAttr);
|
||||
oBuilder.WriteString(L"\"");
|
||||
}
|
||||
}
|
||||
oReader.MoveToElement();
|
||||
}
|
||||
}
|
||||
if (oReader.IsEmptyNode()) oBuilder.WriteString(L"/>");
|
||||
else oBuilder.WriteString(L">");
|
||||
ReadAndStringBuild abc(oReader, oBuilder);
|
||||
abc.AddNode(n);
|
||||
oBuilder.WriteString(L"</");
|
||||
oBuilder.WriteEncodeXmlString(sName);
|
||||
oBuilder.WriteString(L">");
|
||||
|
||||
NSStringUtils::CStringBuilder oBuilder1;
|
||||
auto begin1 = std::chrono::steady_clock::now();
|
||||
for (size_t i = 0; i < 10; i++)
|
||||
{
|
||||
oBuilder1.Write(oBuilder);
|
||||
}
|
||||
auto end1 = std::chrono::steady_clock::now();
|
||||
auto elapsed_mcs1 = std::chrono::duration_cast<std::chrono::microseconds>(end1 - begin1);
|
||||
|
||||
std::cout << "Time of adding two StringBuild into one " << elapsed_mcs1.count() << "(mcs)" << '\n';
|
||||
}
|
||||
|
||||
TEST_F(BufferTest, test_buffer_and_sstream_write_node)
|
||||
{
|
||||
//Writing an XML node via buffer
|
||||
auto begin1 = std::chrono::steady_clock::now();
|
||||
xml::CBufferXml3 outputbuffer;
|
||||
CP_XML_WRITER_4(outputbuffer)
|
||||
{
|
||||
CP_XML_NODE_4(L"NameNode")
|
||||
{
|
||||
CP_XML_ATTR_4(L"NameString", data);
|
||||
}
|
||||
}
|
||||
auto end1 = std::chrono::steady_clock::now();
|
||||
auto elapsed_ms1 = std::chrono::duration_cast<std::chrono::microseconds>(end1 - begin1);
|
||||
|
||||
//Writing an XML node via sstream
|
||||
auto begin2 = std::chrono::steady_clock::now();
|
||||
std::wstringstream outputstream;
|
||||
CP_XML_WRITER(outputstream)
|
||||
{
|
||||
CP_XML_NODE(L"NameNode")
|
||||
{
|
||||
CP_XML_ATTR(L"NameString", data);
|
||||
}
|
||||
}
|
||||
auto end2 = std::chrono::steady_clock::now();
|
||||
auto elapsed_ms2 = std::chrono::duration_cast<std::chrono::microseconds>(end2 - begin2);
|
||||
|
||||
EXPECT_EQ(outputstream.str(), outputbuffer.str());
|
||||
|
||||
std::cout << '\n' << "Writing an XML node via buffer time - " << elapsed_ms1.count() << "(ms)" << '\n' << "Writing an XML node via sstream time - " << elapsed_ms2.count() << "(ms)" << '\n';
|
||||
}
|
||||
|
||||
TEST_F(BufferTest, test_buffer_and_sstream_write_two_nodes_whith_content)
|
||||
{
|
||||
//Writing an two XML node whith content via buffer
|
||||
auto begin1 = std::chrono::steady_clock::now();
|
||||
xml::CBufferXml3 outputbuffer;
|
||||
CP_XML_WRITER_4(outputbuffer)
|
||||
{
|
||||
CP_XML_NODE_4(L"NameNode")
|
||||
{
|
||||
CP_XML_ATTR_4(L"NameString", L"data");
|
||||
|
||||
CP_XML_NODE_4(L"NameNodeTwo")
|
||||
{
|
||||
for (size_t i = 0; i < 100; i++)
|
||||
{
|
||||
CP_XML_CONTENT_4(static_cast<wchar_t>(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
auto end1 = std::chrono::steady_clock::now();
|
||||
auto elapsed_ms1 = std::chrono::duration_cast<std::chrono::microseconds>(end1 - begin1);
|
||||
|
||||
//Writing an two XML node whith content via sstream
|
||||
auto begin2 = std::chrono::steady_clock::now();
|
||||
std::wstringstream outputstream;
|
||||
CP_XML_WRITER(outputstream)
|
||||
{
|
||||
CP_XML_NODE(L"NameNode")
|
||||
{
|
||||
CP_XML_ATTR(L"NameString", L"data");
|
||||
|
||||
CP_XML_NODE(L"NameNodeTwo")
|
||||
{
|
||||
for (size_t i = 0; i < 100; i++)
|
||||
{
|
||||
CP_XML_CONTENT(static_cast<wchar_t>(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
auto end2 = std::chrono::steady_clock::now();
|
||||
auto elapsed_ms2 = std::chrono::duration_cast<std::chrono::microseconds>(end2 - begin2);
|
||||
|
||||
EXPECT_EQ(outputstream.str(), outputbuffer.str());
|
||||
std::cout << '\n' << "Writing an XML node via buffer time - " << elapsed_ms1.count() << "(ms)" << '\n' << "Writing an XML node via sstream time - " << elapsed_ms2.count() << "(ms)" << '\n';
|
||||
}
|
||||
|
||||
TEST_F(BufferTest, test_buffer_and_sstream_write_some_node_with_some_content)
|
||||
{
|
||||
//Writing an some XML node whith some content via buffer
|
||||
auto begin1 = std::chrono::steady_clock::now();
|
||||
xml::CBufferXml3 outputbuffer;
|
||||
CP_XML_WRITER_4(outputbuffer)
|
||||
{
|
||||
CP_XML_NODE_4(L"NameNode")
|
||||
{
|
||||
CP_XML_ATTR_4(L"NameString", data);
|
||||
|
||||
CP_XML_NODE_4(L"NameNodeTwo")
|
||||
{
|
||||
for (size_t i = 0; i < 100; i++)
|
||||
{
|
||||
CP_XML_CONTENT_4(static_cast<wchar_t>(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
CP_XML_NODE_4(L"NameNewNode")
|
||||
{
|
||||
CP_XML_ATTR_4(L"NameString1", data1);
|
||||
|
||||
CP_XML_NODE_4(L"NameNextNode")
|
||||
{
|
||||
CP_XML_ATTR_4(L"NameString2", data2);
|
||||
}
|
||||
CP_XML_NODE_4(L"NameTwoNextNode")
|
||||
{
|
||||
CP_XML_CONTENT_4(L"1234567890");
|
||||
}
|
||||
}
|
||||
}
|
||||
auto end1 = std::chrono::steady_clock::now();
|
||||
auto elapsed_ms1 = std::chrono::duration_cast<std::chrono::microseconds>(end1 - begin1);
|
||||
|
||||
//Writing an some XML node whith some content via stream
|
||||
auto begin2 = std::chrono::steady_clock::now();
|
||||
std::wstringstream outputstream;
|
||||
CP_XML_WRITER(outputstream)
|
||||
{
|
||||
CP_XML_NODE(L"NameNode")
|
||||
{
|
||||
CP_XML_ATTR(L"NameString", data);
|
||||
|
||||
CP_XML_NODE(L"NameNodeTwo")
|
||||
{
|
||||
for (size_t i = 0; i < 100; i++)
|
||||
{
|
||||
CP_XML_CONTENT(static_cast<wchar_t>(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
CP_XML_NODE(L"NameNewNode")
|
||||
{
|
||||
CP_XML_ATTR(L"NameString1", data1);
|
||||
|
||||
CP_XML_NODE(L"NameNextNode")
|
||||
{
|
||||
CP_XML_ATTR(L"NameString2", data2);
|
||||
}
|
||||
CP_XML_NODE(L"NameTwoNextNode")
|
||||
{
|
||||
CP_XML_CONTENT(L"1234567890");
|
||||
}
|
||||
}
|
||||
}
|
||||
auto end2 = std::chrono::steady_clock::now();
|
||||
auto elapsed_ms2 = std::chrono::duration_cast<std::chrono::microseconds>(end2 - begin2);
|
||||
|
||||
EXPECT_EQ(outputstream.str(), outputbuffer.str());
|
||||
|
||||
std::cout << '\n' << "Writing an XML node via buffer time - " << elapsed_ms1.count() << "(ms)" << '\n' << "Writing an XML node via sstream time - " << elapsed_ms2.count() << "(ms)" << '\n';
|
||||
}
|
||||
|
||||
TEST_F(BufferTest, test_buffer_and_sstream_write_xml)
|
||||
{
|
||||
//Writing an some XML node whith some content via buffer
|
||||
xml::CBufferXml3 outputbuffer;
|
||||
auto begin1 = std::chrono::steady_clock::now();
|
||||
CP_XML_WRITER_4(outputbuffer)
|
||||
{
|
||||
CP_XML_NODE_4(L"vt:vector")
|
||||
{
|
||||
CP_XML_ATTR_4(L"size", L"200");
|
||||
CP_XML_ATTR_4(L"baseType", L"variant");
|
||||
|
||||
for (size_t i = 0; i < data2.size(); ++i)
|
||||
{
|
||||
CP_XML_NODE_4(L"vt:variant")
|
||||
{
|
||||
CP_XML_NODE_4(L"vt:lpstr")
|
||||
{
|
||||
CP_XML_CONTENT_4(data2[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
auto end1 = std::chrono::steady_clock::now();
|
||||
auto elapsed_ms1 = std::chrono::duration_cast<std::chrono::microseconds>(end1 - begin1);
|
||||
|
||||
//Writing an some XML node whith some content via stream
|
||||
auto begin2 = std::chrono::steady_clock::now();
|
||||
std::wstringstream outputstream;
|
||||
CP_XML_WRITER(outputstream)
|
||||
{
|
||||
CP_XML_NODE(L"vt:vector")
|
||||
{
|
||||
CP_XML_ATTR(L"size", L"200");
|
||||
CP_XML_ATTR(L"baseType", L"variant");
|
||||
|
||||
for (size_t i = 0; i < data2.size(); ++i)
|
||||
{
|
||||
CP_XML_NODE(L"vt:variant")
|
||||
{
|
||||
CP_XML_NODE(L"vt:lpstr")
|
||||
{
|
||||
CP_XML_CONTENT(data2[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
auto end2 = std::chrono::steady_clock::now();
|
||||
auto elapsed_ms2 = std::chrono::duration_cast<std::chrono::microseconds>(end2 - begin2);
|
||||
|
||||
EXPECT_EQ(outputstream.str(), outputbuffer.str());
|
||||
|
||||
std::cout << '\n' << "Writing an XML node via buffer time - " << elapsed_ms1.count() << "(ms)" << '\n' << "Writing an XML node via sstream time - " << elapsed_ms2.count() << "(ms)" << '\n';
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
@ -40,60 +40,118 @@
|
||||
|
||||
#include "../../../OOXML/Base/Unit.h"
|
||||
|
||||
|
||||
|
||||
namespace cpdoccore
|
||||
{
|
||||
|
||||
namespace xml
|
||||
{
|
||||
template<class T>
|
||||
template<class A>
|
||||
class CBufferXml
|
||||
{
|
||||
public:
|
||||
CBufferXml() : currbuf(0), bufcount(10)
|
||||
CBufferXml() : currbuf(0), bufcount(5)
|
||||
{
|
||||
for (int i = 0; i < bufcount; ++i)
|
||||
for (int i = 0; i < bufcount; i++)
|
||||
{
|
||||
std::vector<T> mbuf;
|
||||
std::vector<A> mbuf;
|
||||
buffer.push_back(mbuf);
|
||||
buffer[i].reserve(100);
|
||||
buffer[0].reserve(1000);
|
||||
}
|
||||
}
|
||||
~CBufferXml()
|
||||
{
|
||||
for (int i = 0; i < bufcount; ++i)
|
||||
buffer[i].clear();
|
||||
buffer.clear();
|
||||
}
|
||||
void push(const T& value)
|
||||
~CBufferXml() { buffer.clear(); }
|
||||
size_t Get_currbuf() { return currbuf; }
|
||||
std::vector<std::vector<A>> Get_buffer() { return buffer; }
|
||||
void push(const A& value)
|
||||
{
|
||||
if (buffer.empty() || (buffer[currbuf].size() >= buffer[currbuf].capacity() && currbuf + 1 == bufcount))
|
||||
{
|
||||
std::vector<T> mbuf;
|
||||
std::vector<A> mbuf;
|
||||
mbuf.reserve(100);
|
||||
buffer.push_back(mbuf);
|
||||
bufcount++;
|
||||
currbuf++;
|
||||
}
|
||||
if (buffer[currbuf].size() >= buffer[currbuf].capacity()) { currbuf++; }
|
||||
else if (buffer[currbuf].size() >= buffer[currbuf].capacity()) { currbuf++; }
|
||||
buffer[currbuf].push_back(value);
|
||||
}
|
||||
void clear()
|
||||
{
|
||||
for (std::vector<A> b : buffer) b.clear();
|
||||
currbuf = 0;
|
||||
}
|
||||
CBufferXml& operator=(CBufferXml other)
|
||||
{
|
||||
this->clear();
|
||||
for (std::vector<A> b : other.Get_buffer())
|
||||
{
|
||||
for (A c : b)
|
||||
{
|
||||
this->push(c);
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
CBufferXml operator+(CBufferXml other)
|
||||
{
|
||||
CBufferXml result;
|
||||
for (std::vector<A> b : this->buffer)
|
||||
{
|
||||
for (A c : b)
|
||||
{
|
||||
result.push(c);
|
||||
}
|
||||
}
|
||||
for (std::vector<A> b : other.Get_buffer())
|
||||
{
|
||||
for (A c : b)
|
||||
{
|
||||
result.push(c);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
CBufferXml& operator+=(CBufferXml other)
|
||||
{
|
||||
for (std::vector<A> b : other.Get_buffer())
|
||||
{
|
||||
for (A c : b)
|
||||
{
|
||||
this->push(c);
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
friend std::wostream& operator<<(std::wostream& out, CBufferXml buf)
|
||||
{
|
||||
for (std::vector<A> b : buf.Get_buffer())
|
||||
{
|
||||
for (A c : b)
|
||||
{
|
||||
out << c;
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
std::wstring str()
|
||||
{
|
||||
std::wstring strres;
|
||||
for (std::vector<T> b : buffer)
|
||||
for (std::vector<A> b : buffer)
|
||||
{
|
||||
if (!b.empty())
|
||||
{
|
||||
for (T c : b)
|
||||
for (A c : b)
|
||||
{
|
||||
strres += c;
|
||||
}
|
||||
}
|
||||
}
|
||||
this->clear();
|
||||
return strres;
|
||||
}
|
||||
private:
|
||||
std::vector<std::vector<T>> buffer;
|
||||
std::vector<std::vector<A>> buffer;
|
||||
size_t currbuf;
|
||||
int bufcount;
|
||||
};
|
||||
@ -101,10 +159,10 @@ namespace cpdoccore
|
||||
namespace writer
|
||||
{
|
||||
|
||||
template <class T> struct chars { };
|
||||
template <class T> struct chars2 { };
|
||||
|
||||
template <>
|
||||
struct chars<char>
|
||||
struct chars2<char>
|
||||
{
|
||||
static const char eq = '=';
|
||||
static const char quote = '\"';
|
||||
@ -125,7 +183,7 @@ namespace cpdoccore
|
||||
};
|
||||
|
||||
template <>
|
||||
struct chars<wchar_t>
|
||||
struct chars2<wchar_t>
|
||||
{
|
||||
static const wchar_t eq = L'=';
|
||||
static const wchar_t quote = L'\"';
|
||||
@ -146,28 +204,28 @@ namespace cpdoccore
|
||||
};
|
||||
|
||||
template <class V>
|
||||
class element;
|
||||
class element2;
|
||||
|
||||
//
|
||||
// xml::writer class
|
||||
//
|
||||
template <class T>
|
||||
class writer
|
||||
class writer2
|
||||
{
|
||||
public:
|
||||
// writer must be bound to an ostream
|
||||
writer(CBufferXml<T> os, bool need_header = false) : level_(0), os_(os), need_header_(need_header) {}
|
||||
~writer(void) { assert(elements_.empty()); }
|
||||
writer2(CBufferXml<T>& os, bool need_header = false) : level_(0), os_(os), need_header_(need_header) {}
|
||||
~writer2(void) { assert(elements_.empty()); }
|
||||
|
||||
private:
|
||||
size_t level_;
|
||||
CBufferXml os_; // output buffer
|
||||
CBufferXml<T>& os_; // output buffer
|
||||
bool need_header_; // have we written an XML header yet?
|
||||
std::stack<element<T>*> elements_; // stack of open element tags
|
||||
std::stack<element2<T>*> elements_; // stack of open element tags
|
||||
|
||||
|
||||
// write XML header, if necessary
|
||||
writer& header()
|
||||
writer2& header()
|
||||
{
|
||||
if (need_header_)
|
||||
{
|
||||
@ -179,31 +237,31 @@ namespace cpdoccore
|
||||
}
|
||||
|
||||
// write a single character to the output stream
|
||||
writer& putc(const T& c)
|
||||
writer2& putc(T c)
|
||||
{
|
||||
os_.push(c);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// write a string to the output stream
|
||||
writer& puts(const T* str) {
|
||||
for (T c : str) { os_.push(c); }
|
||||
writer2& puts(const T* str) {
|
||||
for (int i = 0; i < std::wcslen(str); i++) { os_.push(str[i]); }
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class V>
|
||||
friend class element;
|
||||
friend class element2;
|
||||
};
|
||||
|
||||
//
|
||||
// xml::element class
|
||||
//
|
||||
template <class T>
|
||||
class element
|
||||
class element2
|
||||
{
|
||||
public:
|
||||
// create a new element tag, bound to an xml::writer
|
||||
element(writer<T>& wr, std::basic_string<T, std::char_traits<T>, std::allocator<T> > const& name) : wr_(wr), name_(name)
|
||||
element2(writer2<T>& wr, std::basic_string<T, std::char_traits<T>, std::allocator<T> > const& name) : wr_(wr), name_(name)
|
||||
{
|
||||
wr_.level_++;
|
||||
check_parent();
|
||||
@ -213,47 +271,47 @@ namespace cpdoccore
|
||||
}
|
||||
|
||||
// close the current element tag
|
||||
~element()
|
||||
~element2()
|
||||
{
|
||||
if (!wr_.elements_.empty() && wr_.elements_.top() == this)
|
||||
{
|
||||
wr_.elements_.pop();
|
||||
if (tagopen_)
|
||||
wr_.putc(chars<T>::slash)
|
||||
.putc(chars<T>::right_brocket);
|
||||
wr_.putc(chars2<T>::slash)
|
||||
.putc(chars2<T>::right_brocket);
|
||||
else
|
||||
wr_.putc(chars<T>::left_brocket)
|
||||
.putc(chars<T>::slash)
|
||||
wr_.putc(chars2<T>::left_brocket)
|
||||
.putc(chars2<T>::slash)
|
||||
.puts(name_.c_str())
|
||||
.putc(chars<T>::right_brocket);
|
||||
.putc(chars2<T>::right_brocket);
|
||||
}
|
||||
wr_.level_--;
|
||||
}
|
||||
|
||||
// write an attribute for the current element
|
||||
element& attr(const T* name, const T* value)
|
||||
element2& attr(const T* name, const T* value)
|
||||
{
|
||||
assert(name != 0);
|
||||
assert(value != 0);
|
||||
assert(tagopen_);
|
||||
wr_.putc(chars<T>::space)
|
||||
wr_.putc(chars2<T>::space)
|
||||
.puts(name)
|
||||
.putc(chars<T>::eq)
|
||||
.putc(chars<T>::quote);
|
||||
.putc(chars2<T>::eq)
|
||||
.putc(chars2<T>::quote);
|
||||
qputs(value);
|
||||
wr_.putc(chars<T>::quote);
|
||||
wr_.putc(chars2<T>::quote);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// attr() overload for std::string type
|
||||
element& attr(const T* name, const std::basic_string<T, std::char_traits<T>, std::allocator<T> >& value)
|
||||
element2& attr(const T* name, const std::basic_string<T, std::char_traits<T>, std::allocator<T> >& value)
|
||||
{
|
||||
return attr(name, value.c_str());
|
||||
}
|
||||
|
||||
// attr() function template for all streamable types
|
||||
template <class V>
|
||||
element& attr(const T* name, V value)
|
||||
element2& attr(const T* name, V value)
|
||||
{
|
||||
std::basic_stringstream<T, std::char_traits<T>, std::allocator<T> > ss;
|
||||
ss << value;
|
||||
@ -262,7 +320,7 @@ namespace cpdoccore
|
||||
}
|
||||
|
||||
// write text content for the current element
|
||||
element& contents(const T* str)
|
||||
element2& contents(const T* str)
|
||||
{
|
||||
assert(str != 0);
|
||||
check_parent();
|
||||
@ -271,14 +329,14 @@ namespace cpdoccore
|
||||
}
|
||||
|
||||
// contents() overload for std::string type
|
||||
element& contents(const std::basic_string<T, std::char_traits<T>, std::allocator<T> >& str)
|
||||
element2& contents(const std::basic_string<T, std::char_traits<T>, std::allocator<T> >& str)
|
||||
{
|
||||
return contents(str.c_str());
|
||||
}
|
||||
|
||||
// contents() function template for all streamable types
|
||||
template <class V>
|
||||
element& contents(V value)
|
||||
element2& contents(V value)
|
||||
{
|
||||
std::basic_stringstream<T, std::char_traits<T>, std::allocator<T> > ss;
|
||||
ss << value;
|
||||
@ -286,56 +344,56 @@ namespace cpdoccore
|
||||
return *this;
|
||||
}
|
||||
|
||||
CBufferXml buffer()
|
||||
CBufferXml<T> buffer()
|
||||
{
|
||||
check_parent();
|
||||
return wr_.os_;
|
||||
}
|
||||
|
||||
// write CDATA section
|
||||
element& cdata(const T* str)
|
||||
element2& cdata(const T* str)
|
||||
{
|
||||
assert(str != 0);
|
||||
check_parent();
|
||||
wr_.puts(chars<T>::cdata_open());
|
||||
wr_.puts(chars2<T>::cdata_open());
|
||||
wr_.puts(str);
|
||||
wr_.puts(chars<T>::cdata_close());
|
||||
wr_.puts(chars2<T>::cdata_close());
|
||||
return *this;
|
||||
}
|
||||
|
||||
// cdata() overload for std::string type
|
||||
element& cdata(const std::basic_string<T, std::char_traits<T>, std::allocator<T> >& str)
|
||||
element2& cdata(const std::basic_string<T, std::char_traits<T>, std::allocator<T> >& str)
|
||||
{
|
||||
return cdata(str.c_str());
|
||||
}
|
||||
|
||||
private:
|
||||
writer<T>& wr_; // bound XML writer
|
||||
writer2<T>& wr_; // bound XML writer
|
||||
//const T* name_; // name of current element
|
||||
const std::basic_string<T, std::char_traits<T>, std::allocator<T> > name_;
|
||||
bool tagopen_; // is the element tag for this element still open?
|
||||
|
||||
// write a string quoting characters which have meaning in xml
|
||||
element& qputs(const T* str)
|
||||
element2& qputs(const T* str)
|
||||
{
|
||||
for (; *str; ++str)
|
||||
{
|
||||
switch (*str)
|
||||
{
|
||||
case chars<T>::amp:
|
||||
wr_.puts(chars<T>::amp_str()); break;
|
||||
case chars2<T>::amp:
|
||||
wr_.puts(chars2<T>::amp_str()); break;
|
||||
|
||||
case chars<T>::left_brocket:
|
||||
wr_.puts(chars<T>::left_brocket_str()); break;
|
||||
case chars2<T>::left_brocket:
|
||||
wr_.puts(chars2<T>::left_brocket_str()); break;
|
||||
|
||||
case chars<T>::right_brocket:
|
||||
wr_.puts(chars<T>::right_brocket_str()); break;
|
||||
case chars2<T>::right_brocket:
|
||||
wr_.puts(chars2<T>::right_brocket_str()); break;
|
||||
|
||||
case chars<T>::apos:
|
||||
wr_.puts(chars<T>::apos_str()); break;
|
||||
case chars2<T>::apos:
|
||||
wr_.puts(chars2<T>::apos_str()); break;
|
||||
|
||||
case chars<T>::quote:
|
||||
wr_.puts(chars<T>::quote_str()); break;
|
||||
case chars2<T>::quote:
|
||||
wr_.puts(chars2<T>::quote_str()); break;
|
||||
|
||||
default:
|
||||
wr_.putc(*str); break;
|
||||
@ -349,7 +407,7 @@ namespace cpdoccore
|
||||
{
|
||||
if (!wr_.elements_.empty() && wr_.elements_.top()->tagopen_)
|
||||
{
|
||||
wr_.putc(chars<T>::right_brocket);
|
||||
wr_.putc(chars2<T>::right_brocket);
|
||||
wr_.elements_.top()->tagopen_ = false;
|
||||
}
|
||||
}
|
||||
@ -359,28 +417,28 @@ namespace cpdoccore
|
||||
|
||||
}
|
||||
|
||||
typedef xml::writer::writer<wchar_t> xml_writer;
|
||||
typedef xml::writer::element<wchar_t> xml_element;
|
||||
typedef xml::writer::writer2<wchar_t> xml_writer2;
|
||||
typedef xml::writer::element2<wchar_t> xml_element2;
|
||||
|
||||
#define CP_XML_WRITER(BUFF) if (bool _b_ = false) {} else for (xml_writer _xml_wr_((BUFF));!_b_;_b_=true)
|
||||
#define CP_XML_NODE(NAME) if (bool _b_ = false) {} else for (xml_element _xml_node_(_xml_wr_, (NAME));!_b_;_b_=true)
|
||||
#define CP_XML_ATTR(NAME, VAL) _xml_node_.attr((NAME),(VAL))
|
||||
#define CP_XML_ATTR2(NAME, VAL) _xml_node_.attr((std::wstring(NAME).c_str()),(VAL))
|
||||
#define CP_XML_CONTENT(VAL) _xml_node_.contents((VAL))
|
||||
#define CP_XML_BUFFER() _xml_node_.buffer()
|
||||
#define CP_XML_WRITER_2(BUFF) if (bool _b_ = false) {} else for (xml_writer2 _xml_wr_2((BUFF));!_b_;_b_=true)
|
||||
#define CP_XML_NODE_2(NAME) if (bool _b_ = false) {} else for (xml_element2 _xml_node_2(_xml_wr_2, (NAME));!_b_;_b_=true)
|
||||
#define CP_XML_ATTR_2(NAME, VAL) _xml_node_2.attr((NAME),(VAL))
|
||||
#define CP_XML_ATTR2_2(NAME, VAL) _xml_node_2.attr((std::wstring(NAME).c_str()),(VAL))
|
||||
#define CP_XML_CONTENT_2(VAL) _xml_node_2.contents((VAL))
|
||||
#define CP_XML_BUFFER_2() _xml_node_2.buffer()
|
||||
|
||||
#define CP_GET_XML_NODE() _xml_node_
|
||||
#define CP_GET_XML_NODE_2() _xml_node_2
|
||||
|
||||
#define CP_ATTR_NODE xml_element & _xml_node_
|
||||
#define CP_ATTR_NODE_2 xml_element2 & _xml_node_2
|
||||
|
||||
#define CP_XML_ATTR_ENCODE_STRING(NAME, VAL) _xml_node_.attr((NAME), XmlUtils::EncodeXmlString(VAL))
|
||||
#define CP_XML_ATTR_ENCODE_STRING_2(NAME, VAL) _xml_node_2.attr((NAME), XmlUtils::EncodeXmlString(VAL))
|
||||
|
||||
#define CP_XML_ATTR_OPT(NAME, VAL) if (VAL)CP_XML_ATTR(NAME, (*VAL))
|
||||
#define CP_XML_ATTR_OPT_ENCODE_STRING(NAME, STR) if (STR)CP_XML_ATTR(NAME, XmlUtils::EncodeXmlString(*STR))
|
||||
#define CP_XML_ATTR_OPT_2(NAME, VAL) if (VAL)CP_XML_ATTR_2(NAME, (*VAL))
|
||||
#define CP_XML_ATTR_OPT_ENCODE_STRING_2(NAME, STR) if (STR)CP_XML_ATTR_2(NAME, XmlUtils::EncodeXmlString(*STR))
|
||||
|
||||
#define CP_XML_NODE_SIMPLE() std::wstring NS_NAME = std::wstring(ns) + std::wstring(L":") + std::wstring(name); CP_XML_NODE(NS_NAME)
|
||||
#define CP_XML_NODE_SIMPLE_2() std::wstring NS_NAME = std::wstring(ns) + std::wstring(L":") + std::wstring(name); CP_XML_NODE_2(NS_NAME)
|
||||
|
||||
#define CP_XML_NODE_SIMPLE_NONS() CP_XML_NODE(std::wstring(name))
|
||||
#define CP_XML_NODE_SIMPLE_NONS_2() CP_XML_NODE_2(std::wstring(name))
|
||||
|
||||
|
||||
}
|
||||
417
OdfFile/Common/xml/simple_xml_writer3.h
Normal file
417
OdfFile/Common/xml/simple_xml_writer3.h
Normal file
@ -0,0 +1,417 @@
|
||||
/*
|
||||
* (c) Copyright Ascensio System SIA 2010-2023
|
||||
*
|
||||
* This program is a free software product. You can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License (AGPL)
|
||||
* version 3 as published by the Free Software Foundation. In accordance with
|
||||
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
|
||||
* that Ascensio System SIA expressly excludes the warranty of non-infringement
|
||||
* of any third-party rights.
|
||||
*
|
||||
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
|
||||
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||
*
|
||||
* You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish
|
||||
* street, Riga, Latvia, EU, LV-1050.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of the Program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU AGPL version 3.
|
||||
*
|
||||
* Pursuant to Section 7(b) of the License you must retain the original Product
|
||||
* logo when distributing the program. Pursuant to Section 7(e) we decline to
|
||||
* grant you any rights under trademark law for use of our trademarks.
|
||||
*
|
||||
* All the Product's GUI elements, including illustrations and icon sets, as
|
||||
* well as technical writing content are licensed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
|
||||
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <stack>
|
||||
#include <vector>
|
||||
#include <cassert>
|
||||
|
||||
#include "../../../OOXML/Base/Unit.h"
|
||||
|
||||
namespace cpdoccore
|
||||
{
|
||||
|
||||
namespace xml
|
||||
{
|
||||
class CBufferXml2
|
||||
{
|
||||
public:
|
||||
CBufferXml2()
|
||||
{
|
||||
buffer_size = 0;
|
||||
curr_buff = -1;
|
||||
cbs = 0;
|
||||
buf = NULL;
|
||||
}
|
||||
~CBufferXml2()
|
||||
{
|
||||
buffer.clear();
|
||||
buffer_size = 0;
|
||||
curr_buff = -1;
|
||||
cbs = 0;
|
||||
buf = NULL;
|
||||
}
|
||||
void AddBuf(size_t data_size)
|
||||
{
|
||||
size_t size = std::max((int)data_size, 1000);
|
||||
buffer.emplace_back((wchar_t*)malloc(size * sizeof(wchar_t)));
|
||||
curr_buff++;
|
||||
buf = buffer[curr_buff];
|
||||
cbs = size;
|
||||
}
|
||||
void AddData(const wchar_t& El)
|
||||
{
|
||||
if (cbs == 0)
|
||||
{
|
||||
this->AddBuf(1);
|
||||
}
|
||||
if (cbs == 1)
|
||||
{
|
||||
*buf = L'\0';
|
||||
this->AddBuf(1);
|
||||
}
|
||||
*buf++ = El;
|
||||
buffer_size++;
|
||||
cbs--;
|
||||
}
|
||||
void AddData(const wchar_t* str)
|
||||
{
|
||||
if (cbs == 0)
|
||||
{
|
||||
this->AddBuf(wcslen(str));
|
||||
}
|
||||
if (cbs <= wcslen(str))
|
||||
{
|
||||
*buf = L'\0';
|
||||
this->AddBuf(wcslen(str));
|
||||
}
|
||||
wmemcpy(buf, str, wcslen(str));
|
||||
buf += wcslen(str);
|
||||
buffer_size += wcslen(str);
|
||||
cbs -= wcslen(str);
|
||||
}
|
||||
std::wstring str()
|
||||
{
|
||||
*buf = L'\0';
|
||||
wchar_t* str = (wchar_t*)malloc(buffer_size * sizeof(wchar_t));
|
||||
wchar_t* cur = str;
|
||||
for (const auto& a : buffer)
|
||||
{
|
||||
wmemcpy(cur, a, wcslen(a));
|
||||
cur += wcslen(a);
|
||||
}
|
||||
return std::wstring(str, buffer_size);
|
||||
}
|
||||
std::string utf8()
|
||||
{
|
||||
*buf = L'\0';
|
||||
std::string res;
|
||||
for (const auto& a : buffer)
|
||||
{
|
||||
std::wstring tmp(a, wcslen(a));
|
||||
utf8::utf16to8(tmp.begin(), tmp.end(), std::back_inserter(res));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
private:
|
||||
std::vector<wchar_t*> buffer;
|
||||
wchar_t* buf;
|
||||
size_t buffer_size;
|
||||
size_t curr_buff;
|
||||
size_t cbs;
|
||||
};
|
||||
|
||||
namespace writer
|
||||
{
|
||||
|
||||
template <class T> struct chars3 { };
|
||||
|
||||
template <>
|
||||
struct chars3<char>
|
||||
{
|
||||
static const char eq = '=';
|
||||
static const char quote = '\"';
|
||||
static const char space = ' ';
|
||||
static const char left_brocket = '<';
|
||||
static const char right_brocket = '>';
|
||||
static const char slash = '/';
|
||||
static const char colon = ':';
|
||||
static const char amp = '&';
|
||||
static const char apos = '\'';
|
||||
static const char* cdata_open() { return "<![CDATA["; }
|
||||
static const char* cdata_close() { return "]]>"; }
|
||||
static const char* amp_str() { return "&"; }
|
||||
static const char* left_brocket_str() { return "<"; }
|
||||
static const char* right_brocket_str() { return ">"; }
|
||||
static const char* apos_str() { return "'"; }
|
||||
static const char* quote_str() { return """; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct chars3<wchar_t>
|
||||
{
|
||||
static const wchar_t eq = L'=';
|
||||
static const wchar_t quote = L'\"';
|
||||
static const wchar_t space = L' ';
|
||||
static const wchar_t left_brocket = L'<';
|
||||
static const wchar_t right_brocket = L'>';
|
||||
static const wchar_t slash = L'/';
|
||||
static const wchar_t colon = L':';
|
||||
static const wchar_t amp = L'&';
|
||||
static const wchar_t apos = L'\'';
|
||||
static const wchar_t* cdata_open() { return L"<![CDATA["; }
|
||||
static const wchar_t* cdata_close() { return L"]]>"; }
|
||||
static const wchar_t* amp_str() { return L"&"/* L"&"*/; }
|
||||
static const wchar_t* left_brocket_str() { return L"<"; }
|
||||
static const wchar_t* right_brocket_str() { return L">"; }
|
||||
static const wchar_t* apos_str() { return L"'"; }
|
||||
static const wchar_t* quote_str() { return L"""; }
|
||||
};
|
||||
|
||||
template <class V>
|
||||
class element3;
|
||||
|
||||
//
|
||||
// xml::writer class
|
||||
//
|
||||
template <class T>
|
||||
class writer3
|
||||
{
|
||||
public:
|
||||
// writer must be bound to an ostream
|
||||
writer3(CBufferXml2& os, bool need_header = false) : level_(0), os_(os), need_header_(need_header) {}
|
||||
~writer3(void) { assert(elements_.empty()); }
|
||||
|
||||
private:
|
||||
size_t level_;
|
||||
CBufferXml2& os_; // output stream
|
||||
bool need_header_; // have we written an XML header yet?
|
||||
std::stack<element3<T>*> elements_; // stack of open element tags
|
||||
|
||||
|
||||
// write XML header, if necessary
|
||||
writer3& header()
|
||||
{
|
||||
if (need_header_)
|
||||
{
|
||||
// TODO
|
||||
//os_ << "<?xml version=\"1.0\" encoding=\"utf-8\"?>";
|
||||
need_header_ = false;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// write a single character to the output stream
|
||||
writer3& putc(T c)
|
||||
{
|
||||
os_.AddData(c);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// write a string to the output stream
|
||||
writer3& puts(const T* str) {
|
||||
os_.AddData(str);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class V>
|
||||
friend class element3;
|
||||
};
|
||||
|
||||
//
|
||||
// xml::element class
|
||||
//
|
||||
template <class T>
|
||||
class element3
|
||||
{
|
||||
public:
|
||||
// create a new element tag, bound to an xml::writer
|
||||
element3(writer3<T>& wr, std::basic_string<T, std::char_traits<T>, std::allocator<T> > const& name) : wr_(wr), name_(name)
|
||||
{
|
||||
wr_.level_++;
|
||||
check_parent();
|
||||
wr_.header().putc('<').puts(name_.c_str());
|
||||
tagopen_ = true;
|
||||
wr_.elements_.push(this);
|
||||
}
|
||||
|
||||
// close the current element tag
|
||||
~element3()
|
||||
{
|
||||
if (!wr_.elements_.empty() && wr_.elements_.top() == this)
|
||||
{
|
||||
wr_.elements_.pop();
|
||||
if (tagopen_)
|
||||
wr_.putc(chars3<T>::slash)
|
||||
.putc(chars3<T>::right_brocket);
|
||||
else
|
||||
wr_.putc(chars3<T>::left_brocket)
|
||||
.putc(chars3<T>::slash)
|
||||
.puts(name_.c_str())
|
||||
.putc(chars3<T>::right_brocket);
|
||||
}
|
||||
wr_.level_--;
|
||||
}
|
||||
|
||||
// write an attribute for the current element
|
||||
element3& attr(const T* name, const T* value)
|
||||
{
|
||||
assert(name != 0);
|
||||
assert(value != 0);
|
||||
assert(tagopen_);
|
||||
wr_.putc(chars3<T>::space)
|
||||
.puts(name)
|
||||
.putc(chars3<T>::eq)
|
||||
.putc(chars3<T>::quote);
|
||||
qputs(value);
|
||||
wr_.putc(chars3<T>::quote);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// attr() overload for std::string type
|
||||
element3& attr(const T* name, const std::basic_string<T, std::char_traits<T>, std::allocator<T> >& value)
|
||||
{
|
||||
return attr(name, value.c_str());
|
||||
}
|
||||
|
||||
// attr() function template for all streamable types
|
||||
template <class V>
|
||||
element3& attr(const T* name, V value)
|
||||
{
|
||||
std::basic_stringstream<T, std::char_traits<T>, std::allocator<T> > ss;
|
||||
ss << value;
|
||||
attr(name, ss.str());
|
||||
return *this;
|
||||
}
|
||||
|
||||
// write text content for the current element
|
||||
element3& contents(const T* str)
|
||||
{
|
||||
assert(str != 0);
|
||||
check_parent();
|
||||
qputs(str);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// contents() overload for std::string type
|
||||
element3& contents(const std::basic_string<T, std::char_traits<T>, std::allocator<T> >& str)
|
||||
{
|
||||
return contents(str.c_str());
|
||||
}
|
||||
|
||||
// contents() function template for all streamable types
|
||||
template <class V>
|
||||
element3& contents(V value)
|
||||
{
|
||||
std::basic_stringstream<T, std::char_traits<T>, std::allocator<T> > ss;
|
||||
ss << value;
|
||||
contents(ss.str());
|
||||
return *this;
|
||||
}
|
||||
|
||||
// write CDATA section
|
||||
element3& cdata(const T* str)
|
||||
{
|
||||
assert(str != 0);
|
||||
check_parent();
|
||||
|
||||
wr_.puts(chars3<T>::cdata_open());
|
||||
wr_.puts(str);
|
||||
wr_.puts(chars3<T>::cdata_close());
|
||||
return *this;
|
||||
}
|
||||
|
||||
// cdata() overload for std::string type
|
||||
element3& cdata(const std::basic_string<T, std::char_traits<T>, std::allocator<T> >& str)
|
||||
{
|
||||
return cdata(str.c_str());
|
||||
}
|
||||
|
||||
private:
|
||||
writer3<T>& wr_; // bound XML writer
|
||||
|
||||
//const T* name_; // name of current element
|
||||
const std::basic_string<T, std::char_traits<T>, std::allocator<T> > name_;
|
||||
bool tagopen_; // is the element tag for this element still open?
|
||||
|
||||
// write a string quoting characters which have meaning in xml
|
||||
element3& qputs(const T* str)
|
||||
{
|
||||
for (; *str; ++str)
|
||||
{
|
||||
switch (*str)
|
||||
{
|
||||
case chars3<T>::amp:
|
||||
wr_.puts(chars3<T>::amp_str()); break;
|
||||
|
||||
case chars3<T>::left_brocket:
|
||||
wr_.puts(chars3<T>::left_brocket_str()); break;
|
||||
|
||||
case chars3<T>::right_brocket:
|
||||
wr_.puts(chars3<T>::right_brocket_str()); break;
|
||||
|
||||
case chars3<T>::apos:
|
||||
wr_.puts(chars3<T>::apos_str()); break;
|
||||
|
||||
case chars3<T>::quote:
|
||||
wr_.puts(chars3<T>::quote_str()); break;
|
||||
|
||||
default:
|
||||
wr_.putc(*str); break;
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// check to see if we have a parent tag which needs to be closed
|
||||
void check_parent()
|
||||
{
|
||||
if (!wr_.elements_.empty() && wr_.elements_.top()->tagopen_)
|
||||
{
|
||||
wr_.putc(chars3<T>::right_brocket);
|
||||
wr_.elements_.top()->tagopen_ = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
typedef xml::writer::writer3<wchar_t> xml_writer3;
|
||||
typedef xml::writer::element3<wchar_t> xml_element3;
|
||||
|
||||
#define CP_XML_WRITER_3(BUFF) if (bool _b_ = false) {} else for (xml_writer3 _xml_wr_3((BUFF));!_b_;_b_=true)
|
||||
#define CP_XML_NODE_3(NAME) if (bool _b_ = false) {} else for (xml_element3 _xml_node_3(_xml_wr_3, (NAME));!_b_;_b_=true)
|
||||
#define CP_XML_ATTR_3(NAME, VAL) _xml_node_3.attr((NAME),(VAL))
|
||||
#define CP_XML_ATTR2_3(NAME, VAL) _xml_node_3.attr((std::wstring(NAME).c_str()),(VAL))
|
||||
#define CP_XML_CONTENT_3(VAL) _xml_node_3.contents((VAL))
|
||||
|
||||
#define CP_GET_XML_NODE_3() _xml_node_3
|
||||
|
||||
#define CP_ATTR_NODE_3 xml_element3 & _xml_node_3
|
||||
|
||||
#define CP_XML_ATTR_ENCODE_STRING_3(NAME, VAL) _xml_node_3.attr((NAME), XmlUtils::EncodeXmlString(VAL))
|
||||
|
||||
#define CP_XML_ATTR_OPT_3(NAME, VAL) if (VAL)CP_XML_ATTR(NAME, (*VAL))
|
||||
#define CP_XML_ATTR_OPT_ENCODE_STRING_3(NAME, STR) if (STR)CP_XML_ATTR(NAME, XmlUtils::EncodeXmlString(*STR))
|
||||
|
||||
#define CP_XML_NODE_SIMPLE_3() std::wstring NS_NAME = std::wstring(ns) + std::wstring(L":") + std::wstring(name); CP_XML_NODE(NS_NAME)
|
||||
|
||||
#define CP_XML_NODE_SIMPLE_NONS_3() CP_XML_NODE(std::wstring(name))
|
||||
|
||||
|
||||
}
|
||||
|
||||
515
OdfFile/Common/xml/simple_xml_writer4.h
Normal file
515
OdfFile/Common/xml/simple_xml_writer4.h
Normal file
@ -0,0 +1,515 @@
|
||||
/*
|
||||
* (c) Copyright Ascensio System SIA 2010-2023
|
||||
*
|
||||
* This program is a free software product. You can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License (AGPL)
|
||||
* version 3 as published by the Free Software Foundation. In accordance with
|
||||
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
|
||||
* that Ascensio System SIA expressly excludes the warranty of non-infringement
|
||||
* of any third-party rights.
|
||||
*
|
||||
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
|
||||
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||
*
|
||||
* You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish
|
||||
* street, Riga, Latvia, EU, LV-1050.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of the Program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU AGPL version 3.
|
||||
*
|
||||
* Pursuant to Section 7(b) of the License you must retain the original Product
|
||||
* logo when distributing the program. Pursuant to Section 7(e) we decline to
|
||||
* grant you any rights under trademark law for use of our trademarks.
|
||||
*
|
||||
* All the Product's GUI elements, including illustrations and icon sets, as
|
||||
* well as technical writing content are licensed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
|
||||
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <stack>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <cassert>
|
||||
|
||||
#include "../../../OOXML/Base/Unit.h"
|
||||
|
||||
#define BufferMax 104857600
|
||||
|
||||
namespace cpdoccore
|
||||
{
|
||||
namespace xml
|
||||
{
|
||||
class buffer
|
||||
{
|
||||
public:
|
||||
buffer() : bs(BufferMax), cbs(BufferMax)
|
||||
{
|
||||
buf = (wchar_t*)malloc(BufferMax * sizeof(wchar_t));
|
||||
tmp = buf;
|
||||
}
|
||||
buffer(size_t size) : bs(size), cbs(size)
|
||||
{
|
||||
buf = (wchar_t*)malloc(size * sizeof(wchar_t));
|
||||
tmp = buf;
|
||||
}
|
||||
~buffer()
|
||||
{
|
||||
free(buf);
|
||||
}
|
||||
|
||||
void AddData(const wchar_t& El)
|
||||
{
|
||||
*tmp++ = El;
|
||||
cbs--;
|
||||
}
|
||||
void AddData(const wchar_t* str)
|
||||
{
|
||||
wmemcpy(tmp, str, wcslen(str));
|
||||
tmp += wcslen(str);
|
||||
cbs -= wcslen(str);
|
||||
|
||||
}
|
||||
bool If_add(size_t size)
|
||||
{
|
||||
if (cbs >= size + 1) return true;
|
||||
else return false;
|
||||
}
|
||||
const wchar_t* Get_Buffer() { return buf; }
|
||||
size_t Get_Buf_Size() { return bs - cbs; }
|
||||
private:
|
||||
wchar_t* buf;
|
||||
wchar_t* tmp;
|
||||
size_t bs;
|
||||
size_t cbs;
|
||||
};
|
||||
|
||||
class CBufferXml3
|
||||
{
|
||||
public:
|
||||
CBufferXml3() : cur_buf(0), buffer_size(0)
|
||||
{
|
||||
std::shared_ptr<buffer> ptr = std::make_shared<buffer>();
|
||||
All_Buffer.emplace_back(ptr);
|
||||
}
|
||||
CBufferXml3(size_t buf_count) : cur_buf(-1), buffer_size(0)
|
||||
{
|
||||
All_Buffer.reserve(buf_count);
|
||||
}
|
||||
~CBufferXml3() { All_Buffer.clear(); }
|
||||
|
||||
void AddData(const wchar_t& El)
|
||||
{
|
||||
if (All_Buffer[cur_buf]->If_add(1))
|
||||
{
|
||||
|
||||
All_Buffer[cur_buf]->AddData(El);
|
||||
buffer_size++;
|
||||
}
|
||||
else
|
||||
{
|
||||
All_Buffer[cur_buf]->AddData(L'\0');
|
||||
cur_buf++;
|
||||
std::shared_ptr<buffer> ptr = std::make_shared<buffer>();
|
||||
All_Buffer.emplace_back(ptr);
|
||||
All_Buffer[cur_buf]->AddData(El);
|
||||
buffer_size++;
|
||||
}
|
||||
}
|
||||
void AddData(const wchar_t* str)
|
||||
{
|
||||
if (All_Buffer[cur_buf]->If_add(wcslen(str)))
|
||||
{
|
||||
|
||||
All_Buffer[cur_buf]->AddData(str);
|
||||
buffer_size += wcslen(str);
|
||||
}
|
||||
else
|
||||
{
|
||||
All_Buffer[cur_buf]->AddData(L'\0');
|
||||
cur_buf++;
|
||||
std::shared_ptr<buffer> ptr;
|
||||
if (wcslen(str) > BufferMax) ptr = std::make_shared<buffer>(wcslen(str));
|
||||
else ptr = std::make_shared<buffer>();
|
||||
All_Buffer.emplace_back(ptr);
|
||||
All_Buffer[cur_buf]->AddData(str);
|
||||
buffer_size += wcslen(str);
|
||||
}
|
||||
}
|
||||
|
||||
std::wstring str()
|
||||
{
|
||||
All_Buffer[cur_buf]->AddData(L'\0');
|
||||
int cur_pos = 0;
|
||||
std::wstring res;
|
||||
res.reserve(buffer_size);
|
||||
for (const auto& c : All_Buffer)
|
||||
{
|
||||
res.append(c->Get_Buffer());
|
||||
}
|
||||
return res;
|
||||
}
|
||||
std::string utf8()
|
||||
{
|
||||
All_Buffer[cur_buf]->AddData(L'\0');
|
||||
std::string res;
|
||||
for (const auto& c : All_Buffer)
|
||||
{
|
||||
std::wstring tmp(const_cast<const wchar_t*>(c->Get_Buffer()), wcslen(c->Get_Buffer()));
|
||||
utf8::utf16to8(tmp.begin(), tmp.end(), std::back_inserter(res));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
CBufferXml3 operator+(const CBufferXml3& other)
|
||||
{
|
||||
CBufferXml3 result(cur_buf + other.cur_buf + 2);
|
||||
if (All_Buffer[cur_buf]->Get_Buf_Size() > 0)
|
||||
{
|
||||
All_Buffer[cur_buf]->AddData(L'\0');
|
||||
}
|
||||
for (const auto& c : All_Buffer)
|
||||
{
|
||||
result.All_Buffer.emplace_back(c);
|
||||
cur_buf++;
|
||||
}
|
||||
for (const auto& c : other.All_Buffer)
|
||||
{
|
||||
result.All_Buffer.emplace_back(c);
|
||||
cur_buf++;
|
||||
}
|
||||
result.buffer_size = buffer_size + other.buffer_size;
|
||||
return result;
|
||||
}
|
||||
CBufferXml3& operator=(const CBufferXml3& other)
|
||||
{
|
||||
All_Buffer.clear();
|
||||
cur_buf = -1;
|
||||
for (const auto& c : other.All_Buffer)
|
||||
{
|
||||
All_Buffer.emplace_back(c);
|
||||
cur_buf++;
|
||||
}
|
||||
buffer_size = other.buffer_size;
|
||||
return *this;
|
||||
}
|
||||
CBufferXml3& operator+=(const CBufferXml3& other)
|
||||
{
|
||||
if (All_Buffer[cur_buf]->Get_Buf_Size() > 0)
|
||||
{
|
||||
All_Buffer[cur_buf]->AddData(L'\0');
|
||||
}
|
||||
for (const auto& c : other.All_Buffer)
|
||||
{
|
||||
All_Buffer.emplace_back(c);
|
||||
cur_buf++;
|
||||
}
|
||||
buffer_size += other.buffer_size;
|
||||
return *this;
|
||||
}
|
||||
friend std::wostream& operator<<(std::wostream& os, const CBufferXml3& other)
|
||||
{
|
||||
if (other.All_Buffer[other.cur_buf]->Get_Buf_Size() > 0)
|
||||
{
|
||||
other.All_Buffer[other.cur_buf]->AddData(L'\0');
|
||||
}
|
||||
for (const auto& c : other.All_Buffer)
|
||||
{
|
||||
os << c->Get_Buffer();
|
||||
}
|
||||
return os;
|
||||
}
|
||||
public:
|
||||
std::vector<std::shared_ptr<buffer>> All_Buffer;
|
||||
size_t cur_buf;
|
||||
size_t buffer_size;
|
||||
};
|
||||
|
||||
namespace writer
|
||||
{
|
||||
|
||||
template <class T> struct chars4 { };
|
||||
|
||||
template <>
|
||||
struct chars4<char>
|
||||
{
|
||||
static const char eq = '=';
|
||||
static const char quote = '\"';
|
||||
static const char space = ' ';
|
||||
static const char left_brocket = '<';
|
||||
static const char right_brocket = '>';
|
||||
static const char slash = '/';
|
||||
static const char colon = ':';
|
||||
static const char amp = '&';
|
||||
static const char apos = '\'';
|
||||
static const char* cdata_open() { return "<![CDATA["; }
|
||||
static const char* cdata_close() { return "]]>"; }
|
||||
static const char* amp_str() { return "&"; }
|
||||
static const char* left_brocket_str() { return "<"; }
|
||||
static const char* right_brocket_str() { return ">"; }
|
||||
static const char* apos_str() { return "'"; }
|
||||
static const char* quote_str() { return """; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct chars4<wchar_t>
|
||||
{
|
||||
static const wchar_t eq = L'=';
|
||||
static const wchar_t quote = L'\"';
|
||||
static const wchar_t space = L' ';
|
||||
static const wchar_t left_brocket = L'<';
|
||||
static const wchar_t right_brocket = L'>';
|
||||
static const wchar_t slash = L'/';
|
||||
static const wchar_t colon = L':';
|
||||
static const wchar_t amp = L'&';
|
||||
static const wchar_t apos = L'\'';
|
||||
static const wchar_t* cdata_open() { return L"<![CDATA["; }
|
||||
static const wchar_t* cdata_close() { return L"]]>"; }
|
||||
static const wchar_t* amp_str() { return L"&"/* L"&"*/; }
|
||||
static const wchar_t* left_brocket_str() { return L"<"; }
|
||||
static const wchar_t* right_brocket_str() { return L">"; }
|
||||
static const wchar_t* apos_str() { return L"'"; }
|
||||
static const wchar_t* quote_str() { return L"""; }
|
||||
};
|
||||
|
||||
template <class V>
|
||||
class element4;
|
||||
|
||||
//
|
||||
// xml::writer class
|
||||
//
|
||||
template <class T>
|
||||
class writer4
|
||||
{
|
||||
public:
|
||||
// writer must be bound to an ostream
|
||||
writer4(CBufferXml3& os, bool need_header = false) : level_(0), os_(os), need_header_(need_header) {}
|
||||
~writer4(void) { assert(elements_.empty()); }
|
||||
|
||||
private:
|
||||
size_t level_;
|
||||
CBufferXml3& os_; // output stream
|
||||
bool need_header_; // have we written an XML header yet?
|
||||
std::stack<element4<T>*> elements_; // stack of open element tags
|
||||
|
||||
|
||||
// write XML header, if necessary
|
||||
writer4& header()
|
||||
{
|
||||
if (need_header_)
|
||||
{
|
||||
// TODO
|
||||
//os_ << "<?xml version=\"1.0\" encoding=\"utf-8\"?>";
|
||||
need_header_ = false;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// write a single character to the output stream
|
||||
writer4& putc(T c)
|
||||
{
|
||||
os_.AddData(c);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// write a string to the output stream
|
||||
writer4& puts(const T* str) {
|
||||
os_.AddData(str);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class V>
|
||||
friend class element4;
|
||||
};
|
||||
|
||||
//
|
||||
// xml::element class
|
||||
//
|
||||
template <class T>
|
||||
class element4
|
||||
{
|
||||
public:
|
||||
// create a new element tag, bound to an xml::writer
|
||||
element4(writer4<T>& wr, std::basic_string<T, std::char_traits<T>, std::allocator<T> > const& name) : wr_(wr), name_(name)
|
||||
{
|
||||
wr_.level_++;
|
||||
check_parent();
|
||||
wr_.header().putc('<').puts(name_.c_str());
|
||||
tagopen_ = true;
|
||||
wr_.elements_.push(this);
|
||||
}
|
||||
|
||||
// close the current element tag
|
||||
~element4()
|
||||
{
|
||||
if (!wr_.elements_.empty() && wr_.elements_.top() == this)
|
||||
{
|
||||
wr_.elements_.pop();
|
||||
if (tagopen_)
|
||||
wr_.putc(chars4<T>::slash)
|
||||
.putc(chars4<T>::right_brocket);
|
||||
else
|
||||
wr_.putc(chars4<T>::left_brocket)
|
||||
.putc(chars4<T>::slash)
|
||||
.puts(name_.c_str())
|
||||
.putc(chars4<T>::right_brocket);
|
||||
}
|
||||
wr_.level_--;
|
||||
}
|
||||
|
||||
// write an attribute for the current element
|
||||
element4& attr(const T* name, const T* value)
|
||||
{
|
||||
assert(name != 0);
|
||||
assert(value != 0);
|
||||
assert(tagopen_);
|
||||
wr_.putc(chars4<T>::space)
|
||||
.puts(name)
|
||||
.putc(chars4<T>::eq)
|
||||
.putc(chars4<T>::quote);
|
||||
qputs(value);
|
||||
wr_.putc(chars4<T>::quote);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// attr() overload for std::string type
|
||||
element4& attr(const T* name, const std::basic_string<T, std::char_traits<T>, std::allocator<T> >& value)
|
||||
{
|
||||
return attr(name, value.c_str());
|
||||
}
|
||||
|
||||
// attr() function template for all streamable types
|
||||
template <class V>
|
||||
element4& attr(const T* name, V value)
|
||||
{
|
||||
std::basic_stringstream<T, std::char_traits<T>, std::allocator<T> > ss;
|
||||
ss << value;
|
||||
attr(name, ss.str());
|
||||
return *this;
|
||||
}
|
||||
|
||||
// write text content for the current element
|
||||
element4& contents(const T* str)
|
||||
{
|
||||
assert(str != 0);
|
||||
check_parent();
|
||||
qputs(str);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// contents() overload for std::string type
|
||||
element4& contents(const std::basic_string<T, std::char_traits<T>, std::allocator<T> >& str)
|
||||
{
|
||||
return contents(str.c_str());
|
||||
}
|
||||
|
||||
// contents() function template for all streamable types
|
||||
template <class V>
|
||||
element4& contents(V value)
|
||||
{
|
||||
std::basic_stringstream<T, std::char_traits<T>, std::allocator<T> > ss;
|
||||
ss << value;
|
||||
contents(ss.str());
|
||||
return *this;
|
||||
}
|
||||
|
||||
// write CDATA section
|
||||
element4& cdata(const T* str)
|
||||
{
|
||||
assert(str != 0);
|
||||
check_parent();
|
||||
|
||||
wr_.puts(chars4<T>::cdata_open());
|
||||
wr_.puts(str);
|
||||
wr_.puts(chars4<T>::cdata_close());
|
||||
return *this;
|
||||
}
|
||||
|
||||
// cdata() overload for std::string type
|
||||
element4& cdata(const std::basic_string<T, std::char_traits<T>, std::allocator<T> >& str)
|
||||
{
|
||||
return cdata(str.c_str());
|
||||
}
|
||||
|
||||
private:
|
||||
writer4<T>& wr_; // bound XML writer
|
||||
|
||||
//const T* name_; // name of current element
|
||||
const std::basic_string<T, std::char_traits<T>, std::allocator<T> > name_;
|
||||
bool tagopen_; // is the element tag for this element still open?
|
||||
|
||||
// write a string quoting characters which have meaning in xml
|
||||
element4& qputs(const T* str)
|
||||
{
|
||||
for (; *str; ++str)
|
||||
{
|
||||
switch (*str)
|
||||
{
|
||||
case chars4<T>::amp:
|
||||
wr_.puts(chars4<T>::amp_str()); break;
|
||||
|
||||
case chars4<T>::left_brocket:
|
||||
wr_.puts(chars4<T>::left_brocket_str()); break;
|
||||
|
||||
case chars4<T>::right_brocket:
|
||||
wr_.puts(chars4<T>::right_brocket_str()); break;
|
||||
|
||||
case chars4<T>::apos:
|
||||
wr_.puts(chars4<T>::apos_str()); break;
|
||||
|
||||
case chars4<T>::quote:
|
||||
wr_.puts(chars4<T>::quote_str()); break;
|
||||
|
||||
default:
|
||||
wr_.putc(*str); break;
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// check to see if we have a parent tag which needs to be closed
|
||||
void check_parent()
|
||||
{
|
||||
if (!wr_.elements_.empty() && wr_.elements_.top()->tagopen_)
|
||||
{
|
||||
wr_.putc(chars4<T>::right_brocket);
|
||||
wr_.elements_.top()->tagopen_ = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
typedef xml::writer::writer4<wchar_t> xml_writer4;
|
||||
typedef xml::writer::element4<wchar_t> xml_element4;
|
||||
|
||||
#define CP_XML_WRITER_4(BUFF) if (bool _b_ = false) {} else for (xml_writer4 _xml_wr_4((BUFF));!_b_;_b_=true)
|
||||
#define CP_XML_NODE_4(NAME) if (bool _b_ = false) {} else for (xml_element4 _xml_node_4(_xml_wr_4, (NAME));!_b_;_b_=true)
|
||||
#define CP_XML_ATTR_4(NAME, VAL) _xml_node_4.attr((NAME),(VAL))
|
||||
#define CP_XML_ATTR2_4(NAME, VAL) _xml_node_4.attr((std::wstring(NAME).c_str()),(VAL))
|
||||
#define CP_XML_CONTENT_4(VAL) _xml_node_4.contents((VAL))
|
||||
|
||||
#define CP_GET_XML_NODE_4() _xml_node_4
|
||||
|
||||
#define CP_ATTR_NODE_4 xml_element4 & _xml_node_4
|
||||
|
||||
#define CP_XML_ATTR_ENCODE_STRING_4(NAME, VAL) _xml_node_4.attr((NAME), XmlUtils::EncodeXmlString(VAL))
|
||||
|
||||
#define CP_XML_ATTR_OPT_4(NAME, VAL) if (VAL)CP_XML_ATTR(NAME, (*VAL))
|
||||
#define CP_XML_ATTR_OPT_ENCODE_STRING_4(NAME, STR) if (STR)CP_XML_ATTR(NAME, XmlUtils::EncodeXmlString(*STR))
|
||||
|
||||
#define CP_XML_NODE_SIMPLE_4() std::wstring NS_NAME = std::wstring(ns) + std::wstring(L":") + std::wstring(name); CP_XML_NODE(NS_NAME)
|
||||
|
||||
#define CP_XML_NODE_SIMPLE_NONS_4() CP_XML_NODE(std::wstring(name))
|
||||
|
||||
|
||||
}
|
||||
@ -95,6 +95,7 @@
|
||||
<IntDir>$(Platform)\$(Configuration)\Xml\</IntDir>
|
||||
<IncludePath>..\..\..\Common\3dParty\boost\build\win_32\include;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>..\..\..\Common\3dParty\boost\build\win_64\lib;$(LibraryPath)</LibraryPath>
|
||||
<ExecutablePath>C:\Users\mrkir\core\Common\3dParty\boost\boost_1_72_0;$(ExecutablePath)</ExecutablePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<OutDir>$(Configuration)\</OutDir>
|
||||
@ -138,7 +139,7 @@
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<DisableSpecificWarnings>4311;4267;4996;4172;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
<AdditionalIncludeDirectories>../../DesktopEditor/xml/libxml2/include;../../DesktopEditor/xml/build/vs2005;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>../../DesktopEditor/xml/libxml2/include;../../DesktopEditor/xml/build/vs2005;C:\Users\mrkir\core\Common\3dParty\boost\boost_1_72_0;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Lib>
|
||||
<OutputFile>$(OutDir)$(ProjectName).lib</OutputFile>
|
||||
|
||||
Reference in New Issue
Block a user