Compare commits

...

11 Commits

16 changed files with 2291 additions and 83 deletions

View 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>

View File

@ -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>

View File

@ -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

View File

@ -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" />

View File

@ -18,5 +18,8 @@
<ClInclude Include="simple_xml_writer2.h">
<Filter>Файлы заголовков</Filter>
</ClInclude>
<ClInclude Include="..\..\simple_xml_writer.h">
<Filter>Файлы заголовков</Filter>
</ClInclude>
</ItemGroup>
</Project>

View 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>

View 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>

View File

@ -0,0 +1,5 @@
//
// pch.cpp
//
#include "pch.h"

View File

@ -0,0 +1,7 @@
//
// pch.h
//
#pragma once
#include "gtest/gtest.h"

View 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';
}

View File

@ -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))
}

View 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 "&amp;"; }
static const char* left_brocket_str() { return "&lt;"; }
static const char* right_brocket_str() { return "&gt;"; }
static const char* apos_str() { return "&apos;"; }
static const char* quote_str() { return "&quot;"; }
};
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"&amp;"*/; }
static const wchar_t* left_brocket_str() { return L"&lt;"; }
static const wchar_t* right_brocket_str() { return L"&gt;"; }
static const wchar_t* apos_str() { return L"&apos;"; }
static const wchar_t* quote_str() { return L"&quot;"; }
};
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))
}

View 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 "&amp;"; }
static const char* left_brocket_str() { return "&lt;"; }
static const char* right_brocket_str() { return "&gt;"; }
static const char* apos_str() { return "&apos;"; }
static const char* quote_str() { return "&quot;"; }
};
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"&amp;"*/; }
static const wchar_t* left_brocket_str() { return L"&lt;"; }
static const wchar_t* right_brocket_str() { return L"&gt;"; }
static const wchar_t* apos_str() { return L"&apos;"; }
static const wchar_t* quote_str() { return L"&quot;"; }
};
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))
}

View File

@ -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>