mirror of
https://github.com/reactos/reactos.git
synced 2024-12-26 17:14:41 +00:00
[ATL][ATL_APITEST] Add <atlconv.h> and atlconv testcase (#5449)
- Add <atlconv.h> header file. - Add atlconv testcase to atl_apitest.exe. CORE-16668
This commit is contained in:
parent
d24c991aa7
commit
1191bcaf03
8 changed files with 738 additions and 1 deletions
|
@ -3,6 +3,7 @@ add_definitions(-DINITGUID -DWINETEST_USE_DBGSTR_LONGLONG)
|
|||
|
||||
list(APPEND SOURCE
|
||||
AtlObjMap.cpp
|
||||
atlconv.cpp
|
||||
atltypes.cpp
|
||||
CAtlFileMapping.cpp
|
||||
CAtlArray.cpp
|
||||
|
|
218
modules/rostests/apitests/atl/atlconv.cpp
Normal file
218
modules/rostests/apitests/atl/atlconv.cpp
Normal file
|
@ -0,0 +1,218 @@
|
|||
/*
|
||||
* PROJECT: ReactOS api tests
|
||||
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
|
||||
* PURPOSE: Test for <atlconv.h>
|
||||
* COPYRIGHT: Copyright 2023 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
|
||||
*/
|
||||
|
||||
#ifdef HAVE_APITEST
|
||||
#include <apitest.h>
|
||||
#else
|
||||
#include "atltest.h"
|
||||
#endif
|
||||
#include <atlbase.h>
|
||||
#include <atlconv.h>
|
||||
|
||||
START_TEST(atlconv)
|
||||
{
|
||||
char dataA[MAX_PATH];
|
||||
wchar_t dataW[MAX_PATH];
|
||||
const char *dataAX = "test12345";
|
||||
const wchar_t *dataWX = L"test12345";
|
||||
using namespace ATL;
|
||||
|
||||
//
|
||||
// Initialize long data
|
||||
//
|
||||
FillMemory(dataA, sizeof(dataA), 'A');
|
||||
dataA[_countof(dataA) - 1] = 0;
|
||||
|
||||
for (size_t i = 0; i < _countof(dataW); ++i)
|
||||
dataW[i] = L'A';
|
||||
dataW[_countof(dataW) - 1] = 0;
|
||||
|
||||
//
|
||||
// The NULL strings
|
||||
//
|
||||
{
|
||||
CA2A a2a(NULL);
|
||||
ok_ptr((LPSTR)a2a, NULL);
|
||||
ok_ptr(a2a.m_psz, NULL);
|
||||
ok_int(a2a.m_szBuffer[0], 0);
|
||||
|
||||
CW2A w2a(NULL);
|
||||
ok_ptr((LPSTR)w2a, NULL);
|
||||
ok_ptr(w2a.m_psz, NULL);
|
||||
ok_int(w2a.m_szBuffer[0], 0);
|
||||
|
||||
CA2W a2w(NULL);
|
||||
ok_ptr((LPWSTR)a2w, NULL);
|
||||
ok_ptr(a2w.m_psz, NULL);
|
||||
ok_int(a2w.m_szBuffer[0], 0);
|
||||
|
||||
CW2W w2w(NULL);
|
||||
ok_ptr((LPWSTR)w2w, NULL);
|
||||
ok_ptr(w2w.m_psz, NULL);
|
||||
ok_int(w2w.m_szBuffer[0], 0);
|
||||
}
|
||||
|
||||
//
|
||||
// The zero-length strings
|
||||
//
|
||||
{
|
||||
CA2A a2a("");
|
||||
ok_str((LPSTR)a2a, "");
|
||||
ok_str(a2a.m_psz, "");
|
||||
ok_int(a2a.m_szBuffer[0], 0);
|
||||
ok_ptr(a2a.m_psz, a2a.m_szBuffer);
|
||||
|
||||
CW2A w2a(L"");
|
||||
ok_str((LPSTR)w2a, "");
|
||||
ok_str(w2a.m_psz, "");
|
||||
ok_int(w2a.m_szBuffer[0], 0);
|
||||
ok_ptr(w2a.m_psz, w2a.m_szBuffer);
|
||||
|
||||
CA2W a2w("");
|
||||
ok_wstr((LPWSTR)a2w, L"");
|
||||
ok_wstr(a2w.m_psz, L"");
|
||||
ok_int(a2w.m_szBuffer[0], 0);
|
||||
ok_ptr(a2w.m_psz, a2w.m_szBuffer);
|
||||
|
||||
CW2W w2w(L"");
|
||||
ok_wstr((LPWSTR)w2w, L"");
|
||||
ok_wstr(w2w.m_psz, L"");
|
||||
ok_int(w2w.m_szBuffer[0], 0);
|
||||
ok_ptr(w2w.m_psz, w2w.m_szBuffer);
|
||||
}
|
||||
|
||||
//
|
||||
// The short strings
|
||||
//
|
||||
{
|
||||
CA2A a2a("TEST123");
|
||||
ok_str((LPSTR)a2a, "TEST123");
|
||||
ok_str(a2a.m_psz, "TEST123");
|
||||
ok_ptr(a2a.m_psz, a2a.m_szBuffer);
|
||||
|
||||
CW2A w2a(L"TEST123");
|
||||
ok_str((LPSTR)w2a, "TEST123");
|
||||
ok_str(w2a.m_psz, "TEST123");
|
||||
ok_ptr(w2a.m_psz, w2a.m_szBuffer);
|
||||
|
||||
CA2W a2w("TEST123");
|
||||
ok_wstr((LPWSTR)a2w, L"TEST123");
|
||||
ok_wstr(a2w.m_psz, L"TEST123");
|
||||
ok_ptr(a2w.m_psz, a2w.m_szBuffer);
|
||||
|
||||
CW2W w2w(L"TEST123");
|
||||
ok_wstr((LPWSTR)w2w, L"TEST123");
|
||||
ok_wstr(w2w.m_psz, L"TEST123");
|
||||
ok_ptr(w2w.m_psz, w2w.m_szBuffer);
|
||||
}
|
||||
|
||||
//
|
||||
// The short strings (EX)
|
||||
//
|
||||
{
|
||||
CA2AEX<5> a2ax("123");
|
||||
ok_str((LPSTR)a2ax, "123");
|
||||
ok_str(a2ax.m_psz, "123");
|
||||
ok_ptr(a2ax.m_psz, a2ax.m_szBuffer);
|
||||
|
||||
CW2AEX<5> w2ax(L"123");
|
||||
ok_str((LPSTR)w2ax, "123");
|
||||
ok_str(w2ax.m_psz, "123");
|
||||
ok(w2ax.m_psz != w2ax.m_szBuffer, "w2ax.m_psz == w2ax.m_szBuffer\n"); // corner case
|
||||
|
||||
CA2WEX<5> a2wx("123");
|
||||
ok_wstr((LPWSTR)a2wx, L"123");
|
||||
ok_wstr(a2wx.m_psz, L"123");
|
||||
ok_ptr(a2wx.m_psz, a2wx.m_szBuffer);
|
||||
|
||||
CW2WEX<5> w2wx(L"123");
|
||||
ok_wstr((LPWSTR)w2wx, L"123");
|
||||
ok_wstr(w2wx.m_psz, L"123");
|
||||
ok_ptr(w2wx.m_psz, w2wx.m_szBuffer);
|
||||
}
|
||||
|
||||
//
|
||||
// The long strings
|
||||
//
|
||||
{
|
||||
CA2A a2a2(dataA);
|
||||
ok_str((LPSTR)a2a2, dataA);
|
||||
ok_str(a2a2.m_psz, dataA);
|
||||
ok_str(a2a2.m_szBuffer, "");
|
||||
ok(a2a2.m_psz != dataA, "a2a2.m_psz == dataA\n");
|
||||
ok(a2a2.m_psz != a2a2.m_szBuffer, "a2a2.m_psz == a2a2.m_szBuffer\n");
|
||||
|
||||
CW2A w2a2(dataW);
|
||||
ok_str((LPSTR)w2a2, dataA);
|
||||
ok_str(w2a2.m_psz, dataA);
|
||||
ok_str(w2a2.m_szBuffer, "");
|
||||
ok(w2a2.m_psz != dataA, "w2a2.m_psz == dataA\n");
|
||||
ok(w2a2.m_psz != w2a2.m_szBuffer, "w2a2.m_psz == w2a2.m_szBuffer\n");
|
||||
|
||||
CA2W a2w2(dataA);
|
||||
ok_wstr((LPWSTR)a2w2, dataW);
|
||||
ok_wstr(a2w2.m_psz, dataW);
|
||||
ok_wstr(a2w2.m_szBuffer, L"");
|
||||
ok(a2w2.m_psz != dataW, "a2w2.m_psz == dataW\n");
|
||||
ok(a2w2.m_psz != a2w2.m_szBuffer, "a2w2.m_psz == a2w2.m_szBuffer\n");
|
||||
|
||||
CW2W w2w2(dataW);
|
||||
ok_wstr((LPWSTR)w2w2, dataW);
|
||||
ok_wstr(w2w2.m_psz, dataW);
|
||||
ok_wstr(w2w2.m_szBuffer, L"");
|
||||
ok(w2w2.m_psz != dataW, "w2w2.m_psz == dataW\n");
|
||||
ok(w2w2.m_psz != w2w2.m_szBuffer, "w2w2.m_psz == w2w2.m_szBuffer\n");
|
||||
}
|
||||
|
||||
//
|
||||
// The long strings (EX)
|
||||
//
|
||||
{
|
||||
CA2AEX<5> a2a2x(dataAX);
|
||||
ok_str((LPSTR)a2a2x, dataAX);
|
||||
ok_str(a2a2x.m_psz, dataAX);
|
||||
ok_str(a2a2x.m_szBuffer, "");
|
||||
ok(a2a2x.m_psz != dataAX, "a2a2x.m_psz == dataAX\n");
|
||||
ok(a2a2x.m_psz != a2a2x.m_szBuffer, "a2a2x.m_psz == a2a2x.m_szBuffer\n");
|
||||
|
||||
CW2AEX<5> w2a2x(dataWX);
|
||||
ok_str((LPSTR)w2a2x, dataAX);
|
||||
ok_str(w2a2x.m_psz, dataAX);
|
||||
ok_str(w2a2x.m_szBuffer, "");
|
||||
ok(w2a2x.m_psz != dataAX, "w2a2x.m_psz == dataAX\n");
|
||||
ok(w2a2x.m_psz != w2a2x.m_szBuffer, "w2a2x.m_psz == w2a2x.m_szBuffer\n");
|
||||
|
||||
CA2WEX<5> a2w2x(dataAX);
|
||||
ok_wstr((LPWSTR)a2w2x, dataWX);
|
||||
ok_wstr(a2w2x.m_psz, dataWX);
|
||||
ok_wstr(a2w2x.m_szBuffer, L"");
|
||||
ok(a2w2x.m_psz != dataWX, "a2w2x.m_psz == dataWX\n");
|
||||
ok(a2w2x.m_psz != a2w2x.m_szBuffer, "a2w2x.m_psz == a2w2x.m_szBuffer\n");
|
||||
|
||||
CW2WEX<5> w2w2x(dataWX);
|
||||
ok_wstr((LPWSTR)w2w2x, dataWX);
|
||||
ok_wstr(w2w2x.m_psz, dataWX);
|
||||
ok_wstr(w2w2x.m_szBuffer, L"");
|
||||
ok(w2w2x.m_psz != dataWX, "w2w2x.m_psz == dataWX\n");
|
||||
ok(w2w2x.m_psz != w2w2x.m_szBuffer, "w2w2x.m_psz == w2w2x.m_szBuffer\n");
|
||||
}
|
||||
|
||||
//
|
||||
// The const strings
|
||||
//
|
||||
{
|
||||
CA2CA a2ca(dataA);
|
||||
ok_str((LPCSTR)a2ca, dataA);
|
||||
ok_str(a2ca.m_psz, dataA);
|
||||
ok_ptr(a2ca.m_psz, dataA);
|
||||
|
||||
CW2CW w2cw(dataW);
|
||||
ok_wstr((LPCWSTR)w2cw, dataW);
|
||||
ok_wstr(w2cw.m_psz, dataW);
|
||||
ok_ptr(w2cw.m_psz, dataW);
|
||||
}
|
||||
}
|
|
@ -107,7 +107,7 @@ char *wine_dbgstr_w(const wchar_t *wstr)
|
|||
|
||||
#define ok_ptr(expression, result) \
|
||||
do { \
|
||||
void *_value = (expression); \
|
||||
const void *_value = (expression); \
|
||||
ok(_value == (result), "Wrong value for '%s', expected: " #result " (%p), got: %p\n", \
|
||||
#expression, (void*)(result), _value); \
|
||||
} while (0)
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
*.opendb
|
||||
*.db
|
||||
*.user
|
||||
*.filters
|
||||
x64/
|
||||
.vs/
|
||||
ipch/
|
||||
atlconv/
|
||||
CAtlArray/
|
||||
CAtlFileMapping/
|
||||
CAtlList/
|
||||
|
|
|
@ -31,6 +31,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CPath", "CPath.vcxproj", "{
|
|||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AtlObjMap", "AtlObjMap.vcxproj", "{B628C42A-A38E-488E-8512-2B997B75E95C}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "atlconv", "atlconv.vcxproj", "{85194CA3-A828-4270-962A-333743E2BF83}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
|
@ -151,6 +153,14 @@ Global
|
|||
{B628C42A-A38E-488E-8512-2B997B75E95C}.Release|x64.Build.0 = Release|x64
|
||||
{B628C42A-A38E-488E-8512-2B997B75E95C}.Release|x86.ActiveCfg = Release|Win32
|
||||
{B628C42A-A38E-488E-8512-2B997B75E95C}.Release|x86.Build.0 = Release|Win32
|
||||
{85194CA3-A828-4270-962A-333743E2BF83}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{85194CA3-A828-4270-962A-333743E2BF83}.Debug|x64.Build.0 = Debug|x64
|
||||
{85194CA3-A828-4270-962A-333743E2BF83}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{85194CA3-A828-4270-962A-333743E2BF83}.Debug|x86.Build.0 = Debug|Win32
|
||||
{85194CA3-A828-4270-962A-333743E2BF83}.Release|x64.ActiveCfg = Release|x64
|
||||
{85194CA3-A828-4270-962A-333743E2BF83}.Release|x64.Build.0 = Release|x64
|
||||
{85194CA3-A828-4270-962A-333743E2BF83}.Release|x86.ActiveCfg = Release|Win32
|
||||
{85194CA3-A828-4270-962A-333743E2BF83}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
154
modules/rostests/apitests/atl/devenv/atlconv.vcxproj
Normal file
154
modules/rostests/apitests/atl/devenv/atlconv.vcxproj
Normal file
|
@ -0,0 +1,154 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.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>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\atlconv.cpp" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{85194CA3-A828-4270-962A-333743E2BF83}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>atlconv</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140_xp</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140_xp</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
</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)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IntDir>$(ProjectName)\$(Platform)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<IntDir>$(ProjectName)\$(Platform)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
|
@ -2,6 +2,7 @@
|
|||
#include <apitest.h>
|
||||
|
||||
extern void func_AtlObjMap(void);
|
||||
extern void func_atlconv(void);
|
||||
extern void func_atltypes(void);
|
||||
extern void func_CAtlFileMapping(void);
|
||||
extern void func_CAtlArray(void);
|
||||
|
@ -23,6 +24,7 @@ extern void func_SubclassWindow(void);
|
|||
const struct test winetest_testlist[] =
|
||||
{
|
||||
{ "AtlObjMap", func_AtlObjMap },
|
||||
{ "atlconv", func_atlconv },
|
||||
{ "atltypes", func_atltypes },
|
||||
{ "CAtlFileMapping", func_CAtlFileMapping },
|
||||
{ "CAtlArray", func_CAtlArray },
|
||||
|
|
348
sdk/lib/atl/atlconv.h
Normal file
348
sdk/lib/atl/atlconv.h
Normal file
|
@ -0,0 +1,348 @@
|
|||
/*
|
||||
* PROJECT: ReactOS ATL
|
||||
* LICENSE: LGPL-2.0-or-later (https://spdx.org/licenses/LGPL-2.0-or-later)
|
||||
* PURPOSE: String conversion
|
||||
* COPYRIGHT: Copyright 2023 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef __ATLCONV_H__
|
||||
#define __ATLCONV_H__
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "atlbase.h"
|
||||
|
||||
namespace ATL
|
||||
{
|
||||
|
||||
// This class does not own the string
|
||||
template <int t_nBufferLength = 128>
|
||||
class CA2CAEX
|
||||
{
|
||||
public:
|
||||
LPCSTR m_psz;
|
||||
|
||||
CA2CAEX(_In_z_ LPCSTR psz) : m_psz(psz) { }
|
||||
|
||||
CA2CAEX(_In_z_ LPCSTR psz, _In_ UINT nCodePage) : m_psz(psz)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(nCodePage);
|
||||
}
|
||||
|
||||
~CA2CAEX() throw() { } // There is nothing to free here
|
||||
|
||||
_Ret_z_ operator LPCSTR() const throw() { return m_psz; }
|
||||
|
||||
private:
|
||||
// CA2CAEX is not copyable
|
||||
CA2CAEX(_In_ const CA2CAEX&) throw() = delete;
|
||||
CA2CAEX& operator=(_In_ const CA2CAEX&) throw() = delete;
|
||||
};
|
||||
|
||||
// This class does not own the string
|
||||
template <int t_nBufferLength = 128>
|
||||
class CW2CWEX
|
||||
{
|
||||
public:
|
||||
LPCWSTR m_psz;
|
||||
|
||||
CW2CWEX(_In_z_ LPCWSTR psz) : m_psz(psz) { }
|
||||
|
||||
CW2CWEX(_In_z_ LPCWSTR psz, _In_ UINT nCodePage) : m_psz(psz)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(nCodePage);
|
||||
}
|
||||
|
||||
~CW2CWEX() throw() { } // There is nothing to free here
|
||||
|
||||
_Ret_z_ operator LPCWSTR() const throw() { return m_psz; }
|
||||
|
||||
private:
|
||||
// CW2CWEX is not copyable
|
||||
CW2CWEX(_In_ const CW2CWEX&) throw() = delete;
|
||||
CW2CWEX& operator=(_In_ const CW2CWEX&) throw() = delete;
|
||||
};
|
||||
|
||||
template <int t_nBufferLength = 128>
|
||||
class CA2AEX
|
||||
{
|
||||
public:
|
||||
LPSTR m_psz;
|
||||
char m_szBuffer[t_nBufferLength];
|
||||
|
||||
CA2AEX(_In_z_ LPCSTR psz)
|
||||
{
|
||||
Init(psz);
|
||||
}
|
||||
|
||||
CA2AEX(_In_z_ LPCSTR psz, _In_ UINT nCodePage)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(nCodePage);
|
||||
Init(psz);
|
||||
}
|
||||
|
||||
~CA2AEX() throw()
|
||||
{
|
||||
if (m_psz != m_szBuffer)
|
||||
free(m_psz);
|
||||
}
|
||||
|
||||
_Ret_z_ operator LPSTR() const throw()
|
||||
{
|
||||
return m_psz;
|
||||
}
|
||||
|
||||
private:
|
||||
// CA2AEX is not copyable
|
||||
CA2AEX(_In_ const CA2AEX &) throw() = delete;
|
||||
CA2AEX& operator=(_In_ const CA2AEX &) throw() = delete;
|
||||
|
||||
void Init(_In_z_ LPCSTR psz)
|
||||
{
|
||||
if (!psz)
|
||||
{
|
||||
m_psz = NULL;
|
||||
m_szBuffer[0] = 0;
|
||||
return;
|
||||
}
|
||||
int cchMax = lstrlenA(psz) + 1;
|
||||
if (cchMax <= t_nBufferLength)
|
||||
{
|
||||
#ifdef _STRSAFE_H_INCLUDED_
|
||||
StringCchCopyA(m_szBuffer, _countof(m_szBuffer), psz);
|
||||
#else
|
||||
lstrcpynA(m_szBuffer, psz, _countof(m_szBuffer));
|
||||
#endif
|
||||
m_psz = m_szBuffer;
|
||||
return;
|
||||
}
|
||||
|
||||
m_szBuffer[0] = 0;
|
||||
m_psz = _strdup(psz);
|
||||
if (!m_psz)
|
||||
AtlThrow(E_OUTOFMEMORY);
|
||||
}
|
||||
};
|
||||
|
||||
template <int t_nBufferLength = 128>
|
||||
class CW2WEX
|
||||
{
|
||||
public:
|
||||
LPWSTR m_psz;
|
||||
wchar_t m_szBuffer[t_nBufferLength];
|
||||
|
||||
CW2WEX(_In_z_ LPCWSTR psz)
|
||||
{
|
||||
Init(psz);
|
||||
}
|
||||
|
||||
CW2WEX(_In_z_ LPCWSTR psz, _In_ UINT nCodePage)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(nCodePage);
|
||||
Init(psz);
|
||||
}
|
||||
|
||||
~CW2WEX() throw()
|
||||
{
|
||||
if (m_psz != m_szBuffer)
|
||||
free(m_psz);
|
||||
}
|
||||
|
||||
_Ret_z_ operator LPWSTR() const throw()
|
||||
{
|
||||
return m_psz;
|
||||
}
|
||||
|
||||
private:
|
||||
// CW2WEX is not copyable
|
||||
CW2WEX(_In_ const CW2WEX&) throw() = delete;
|
||||
CW2WEX& operator=(_In_ const CW2WEX&) throw() = delete;
|
||||
|
||||
void Init(_In_z_ LPCWSTR psz)
|
||||
{
|
||||
if (!psz)
|
||||
{
|
||||
m_psz = NULL;
|
||||
m_szBuffer[0] = 0;
|
||||
return;
|
||||
}
|
||||
int cchMax = lstrlenW(psz);
|
||||
if (cchMax <= t_nBufferLength)
|
||||
{
|
||||
#ifdef _STRSAFE_H_INCLUDED_
|
||||
StringCchCopyW(m_szBuffer, _countof(m_szBuffer), psz);
|
||||
#else
|
||||
lstrcpynW(m_szBuffer, psz, _countof(m_szBuffer));
|
||||
#endif
|
||||
m_psz = m_szBuffer;
|
||||
return;
|
||||
}
|
||||
|
||||
m_szBuffer[0] = 0;
|
||||
m_psz = _wcsdup(psz);
|
||||
if (!m_psz)
|
||||
AtlThrow(E_OUTOFMEMORY);
|
||||
}
|
||||
};
|
||||
|
||||
template <int t_nBufferLength = 128>
|
||||
class CA2WEX
|
||||
{
|
||||
public:
|
||||
LPWSTR m_psz;
|
||||
wchar_t m_szBuffer[t_nBufferLength];
|
||||
|
||||
CA2WEX(_In_z_ LPCSTR psz)
|
||||
{
|
||||
Init(psz, CP_ACP);
|
||||
}
|
||||
|
||||
CA2WEX(_In_z_ LPCSTR psz, _In_ UINT nCodePage)
|
||||
{
|
||||
Init(psz, nCodePage);
|
||||
}
|
||||
|
||||
~CA2WEX() throw()
|
||||
{
|
||||
if (m_psz != m_szBuffer)
|
||||
free(m_psz);
|
||||
}
|
||||
|
||||
_Ret_z_ operator LPWSTR() const throw()
|
||||
{
|
||||
return m_psz;
|
||||
}
|
||||
|
||||
private:
|
||||
// CA2WEX is not copyable
|
||||
CA2WEX(_In_ const CA2WEX&) throw() = delete;
|
||||
CA2WEX& operator=(_In_ const CA2WEX&) throw() = delete;
|
||||
|
||||
void Init(_In_z_ LPCSTR psz, _In_ UINT nCodePage)
|
||||
{
|
||||
if (!psz)
|
||||
{
|
||||
m_psz = NULL;
|
||||
m_szBuffer[0] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
#if 1
|
||||
int cchMax = lstrlenA(psz) + 1; // This is 3 times faster
|
||||
#else
|
||||
int cchMax = MultiByteToWideChar(nCodePage, 0, psz, -1, NULL, 0); // It's slow
|
||||
#endif
|
||||
if (cchMax <= (int)_countof(m_szBuffer))
|
||||
{
|
||||
// Use the static buffer
|
||||
m_psz = m_szBuffer;
|
||||
cchMax = _countof(m_szBuffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Allocate a new buffer
|
||||
m_szBuffer[0] = 0;
|
||||
m_psz = (LPWSTR)malloc(cchMax * sizeof(WCHAR));
|
||||
if (!m_psz)
|
||||
AtlThrow(E_OUTOFMEMORY);
|
||||
}
|
||||
|
||||
MultiByteToWideChar(nCodePage, 0, psz, -1, m_psz, cchMax);
|
||||
m_psz[cchMax - 1] = 0;
|
||||
}
|
||||
};
|
||||
|
||||
template <int t_nBufferLength = 128>
|
||||
class CW2AEX
|
||||
{
|
||||
public:
|
||||
LPSTR m_psz;
|
||||
char m_szBuffer[t_nBufferLength];
|
||||
|
||||
CW2AEX(_In_z_ LPCWSTR psz)
|
||||
{
|
||||
Init(psz, CP_ACP);
|
||||
}
|
||||
|
||||
CW2AEX(_In_z_ LPCWSTR psz, _In_ UINT nCodePage)
|
||||
{
|
||||
Init(psz, nCodePage);
|
||||
}
|
||||
|
||||
~CW2AEX() throw()
|
||||
{
|
||||
if (m_psz != m_szBuffer)
|
||||
free(m_psz);
|
||||
}
|
||||
|
||||
_Ret_z_ operator LPSTR() const throw()
|
||||
{
|
||||
return m_psz;
|
||||
}
|
||||
|
||||
private:
|
||||
// CW2AEX is not copyable
|
||||
CW2AEX(_In_ const CW2AEX&) throw() = delete;
|
||||
CW2AEX& operator=(_In_ const CW2AEX&) throw() = delete;
|
||||
|
||||
void Init(_In_z_ LPCWSTR psz, _In_ UINT nConvertCodePage)
|
||||
{
|
||||
if (!psz)
|
||||
{
|
||||
m_psz = NULL;
|
||||
m_szBuffer[0] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// NOTE: This has a failure.
|
||||
int cchMax = WideCharToMultiByte(nConvertCodePage, 0, psz, -1, NULL, 0, NULL, NULL);
|
||||
if (cchMax <= (int)_countof(m_szBuffer))
|
||||
{
|
||||
// Use the static buffer
|
||||
m_psz = m_szBuffer;
|
||||
cchMax = _countof(m_szBuffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Allocate a new buffer
|
||||
m_szBuffer[0] = 0;
|
||||
m_psz = (LPSTR)malloc(cchMax * sizeof(CHAR));
|
||||
if (!m_psz)
|
||||
AtlThrow(E_OUTOFMEMORY);
|
||||
}
|
||||
|
||||
WideCharToMultiByte(nConvertCodePage, 0, psz, -1, m_psz, cchMax, NULL, NULL);
|
||||
m_psz[cchMax - 1] = 0;
|
||||
}
|
||||
};
|
||||
|
||||
typedef CA2AEX<> CA2A;
|
||||
typedef CW2AEX<> CW2A;
|
||||
typedef CA2WEX<> CA2W;
|
||||
typedef CW2WEX<> CW2W;
|
||||
typedef CA2CAEX<> CA2CA;
|
||||
typedef CW2CWEX<> CW2CW;
|
||||
|
||||
#ifdef UNICODE
|
||||
#define CA2CTEX CA2WEX
|
||||
#define CA2TEX CA2WEX
|
||||
#define CT2AEX CW2AEX
|
||||
#define CT2CAEX CW2AEX
|
||||
#define CT2CWEX CW2CWEX
|
||||
#define CT2WEX CW2WEX
|
||||
#define CW2CTEX CW2CWEX
|
||||
#define CW2CTEX CW2CWEX
|
||||
#else
|
||||
#define CA2CTEX CA2CAEX
|
||||
#define CA2TEX CA2AEX
|
||||
#define CT2AEX CA2AEX
|
||||
#define CT2CAEX CA2CAEX
|
||||
#define CT2CWEX CA2WEX
|
||||
#define CT2WEX CA2WEX
|
||||
#define CW2CTEX CW2AEX
|
||||
#define CW2TEX CW2AEX
|
||||
#endif
|
||||
|
||||
} // namespace ATL
|
||||
|
||||
#endif // ndef __ATLCONV_H__
|
Loading…
Reference in a new issue