A big simplification of camera selection.
This commit is contained in:
parent
3b9a75f203
commit
90ccbcb72a
72 changed files with 1 additions and 25876 deletions
13
OpenFace.sln
13
OpenFace.sln
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio 14
|
# Visual Studio 14
|
||||||
VisualStudioVersion = 14.0.25420.1
|
VisualStudioVersion = 14.0.24720.0
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dlib", "lib\3rdParty\dlib\dlib.vcxproj", "{B47A5F12-2567-44E9-AE49-35763EC82149}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dlib", "lib\3rdParty\dlib\dlib.vcxproj", "{B47A5F12-2567-44E9-AE49-35763EC82149}"
|
||||||
EndProject
|
EndProject
|
||||||
|
@ -31,8 +31,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CppInerop", "lib\local\CppI
|
||||||
EndProject
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "UtilLibs", "UtilLibs", "{D5F7B3E2-01FE-4F4A-8CE1-274D74D395D4}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "UtilLibs", "UtilLibs", "{D5F7B3E2-01FE-4F4A-8CE1-274D74D395D4}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CamCom", "lib\local\CamCom\CamCom.vcxproj", "{0CEC6A75-17BA-4DC5-9405-C74154921E60}"
|
|
||||||
EndProject
|
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenFaceOffline", "gui\OpenFaceOffline\OpenFaceOffline.csproj", "{A4760F41-2B1F-4144-B7B2-62785AFFE79B}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenFaceOffline", "gui\OpenFaceOffline\OpenFaceOffline.csproj", "{A4760F41-2B1F-4144-B7B2-62785AFFE79B}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenFaceDemo", "gui\OpenFaceDemo\OpenFaceDemo.csproj", "{E143A2AA-312E-4DFE-B61D-9A87CCBC8E90}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenFaceDemo", "gui\OpenFaceDemo\OpenFaceDemo.csproj", "{E143A2AA-312E-4DFE-B61D-9A87CCBC8E90}"
|
||||||
|
@ -131,14 +129,6 @@ Global
|
||||||
{78196985-EE54-411F-822B-5A23EDF80642}.Release|Win32.Build.0 = Release|Win32
|
{78196985-EE54-411F-822B-5A23EDF80642}.Release|Win32.Build.0 = Release|Win32
|
||||||
{78196985-EE54-411F-822B-5A23EDF80642}.Release|x64.ActiveCfg = Release|x64
|
{78196985-EE54-411F-822B-5A23EDF80642}.Release|x64.ActiveCfg = Release|x64
|
||||||
{78196985-EE54-411F-822B-5A23EDF80642}.Release|x64.Build.0 = Release|x64
|
{78196985-EE54-411F-822B-5A23EDF80642}.Release|x64.Build.0 = Release|x64
|
||||||
{0CEC6A75-17BA-4DC5-9405-C74154921E60}.Debug|Win32.ActiveCfg = Debug|Win32
|
|
||||||
{0CEC6A75-17BA-4DC5-9405-C74154921E60}.Debug|Win32.Build.0 = Debug|Win32
|
|
||||||
{0CEC6A75-17BA-4DC5-9405-C74154921E60}.Debug|x64.ActiveCfg = Debug|x64
|
|
||||||
{0CEC6A75-17BA-4DC5-9405-C74154921E60}.Debug|x64.Build.0 = Debug|x64
|
|
||||||
{0CEC6A75-17BA-4DC5-9405-C74154921E60}.Release|Win32.ActiveCfg = Release|Win32
|
|
||||||
{0CEC6A75-17BA-4DC5-9405-C74154921E60}.Release|Win32.Build.0 = Release|Win32
|
|
||||||
{0CEC6A75-17BA-4DC5-9405-C74154921E60}.Release|x64.ActiveCfg = Release|x64
|
|
||||||
{0CEC6A75-17BA-4DC5-9405-C74154921E60}.Release|x64.Build.0 = Release|x64
|
|
||||||
{A4760F41-2B1F-4144-B7B2-62785AFFE79B}.Debug|Win32.ActiveCfg = Debug|x86
|
{A4760F41-2B1F-4144-B7B2-62785AFFE79B}.Debug|Win32.ActiveCfg = Debug|x86
|
||||||
{A4760F41-2B1F-4144-B7B2-62785AFFE79B}.Debug|Win32.Build.0 = Debug|x86
|
{A4760F41-2B1F-4144-B7B2-62785AFFE79B}.Debug|Win32.Build.0 = Debug|x86
|
||||||
{A4760F41-2B1F-4144-B7B2-62785AFFE79B}.Debug|x64.ActiveCfg = Debug|Any CPU
|
{A4760F41-2B1F-4144-B7B2-62785AFFE79B}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
@ -193,7 +183,6 @@ Global
|
||||||
{34032CF2-1B99-4A25-9050-E9C13DD4CD0A} = {9961DDAC-BE6E-4A6E-8EEF-FFC7D67BD631}
|
{34032CF2-1B99-4A25-9050-E9C13DD4CD0A} = {9961DDAC-BE6E-4A6E-8EEF-FFC7D67BD631}
|
||||||
{DDC3535E-526C-44EC-9DF4-739E2D3A323B} = {9961DDAC-BE6E-4A6E-8EEF-FFC7D67BD631}
|
{DDC3535E-526C-44EC-9DF4-739E2D3A323B} = {9961DDAC-BE6E-4A6E-8EEF-FFC7D67BD631}
|
||||||
{78196985-EE54-411F-822B-5A23EDF80642} = {D5F7B3E2-01FE-4F4A-8CE1-274D74D395D4}
|
{78196985-EE54-411F-822B-5A23EDF80642} = {D5F7B3E2-01FE-4F4A-8CE1-274D74D395D4}
|
||||||
{0CEC6A75-17BA-4DC5-9405-C74154921E60} = {D5F7B3E2-01FE-4F4A-8CE1-274D74D395D4}
|
|
||||||
{A4760F41-2B1F-4144-B7B2-62785AFFE79B} = {C9D8D0B0-11EC-41CB-8524-2DDB5BE94297}
|
{A4760F41-2B1F-4144-B7B2-62785AFFE79B} = {C9D8D0B0-11EC-41CB-8524-2DDB5BE94297}
|
||||||
{E143A2AA-312E-4DFE-B61D-9A87CCBC8E90} = {C9D8D0B0-11EC-41CB-8524-2DDB5BE94297}
|
{E143A2AA-312E-4DFE-B61D-9A87CCBC8E90} = {C9D8D0B0-11EC-41CB-8524-2DDB5BE94297}
|
||||||
{F396362D-821E-4EA6-9BBF-1F6050844118} = {C9D8D0B0-11EC-41CB-8524-2DDB5BE94297}
|
{F396362D-821E-4EA6-9BBF-1F6050844118} = {C9D8D0B0-11EC-41CB-8524-2DDB5BE94297}
|
||||||
|
|
|
@ -46,7 +46,6 @@ using System.Windows.Media.Imaging;
|
||||||
using OpenCVWrappers;
|
using OpenCVWrappers;
|
||||||
using CppInterop;
|
using CppInterop;
|
||||||
using CppInterop.LandmarkDetector;
|
using CppInterop.LandmarkDetector;
|
||||||
using CameraInterop;
|
|
||||||
using System.Windows.Threading;
|
using System.Windows.Threading;
|
||||||
using GazeAnalyser_Interop;
|
using GazeAnalyser_Interop;
|
||||||
|
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<ImportGroup Label="PropertySheets" />
|
|
||||||
<PropertyGroup Label="UserMacros" />
|
|
||||||
<PropertyGroup />
|
|
||||||
<ItemDefinitionGroup>
|
|
||||||
<ClCompile>
|
|
||||||
<AdditionalIncludeDirectories>$(SolutionDir)lib\local\CamCom;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<AdditionalDependencies>dxva2.lib;evr.lib;mf.lib;mfplat.lib;mfplay.lib;mfreadwrite.lib;mfuuid.lib;Strmiids.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemGroup />
|
|
||||||
</Project>
|
|
|
@ -1,167 +0,0 @@
|
||||||
<?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>
|
|
||||||
<PropertyGroup Label="Globals">
|
|
||||||
<ProjectGuid>{0CEC6A75-17BA-4DC5-9405-C74154921E60}</ProjectGuid>
|
|
||||||
<Keyword>Win32Proj</Keyword>
|
|
||||||
<RootNamespace>CamCom</RootNamespace>
|
|
||||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
|
||||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
|
||||||
<PlatformToolset>v140</PlatformToolset>
|
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
|
||||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
|
||||||
<PlatformToolset>v140</PlatformToolset>
|
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
|
||||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
|
||||||
<PlatformToolset>v140</PlatformToolset>
|
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
|
||||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
|
||||||
<PlatformToolset>v140</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" />
|
|
||||||
<Import Project="..\..\3rdParty\OpenCV3.1\openCV3.1.props" />
|
|
||||||
</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" />
|
|
||||||
<Import Project="..\..\3rdParty\OpenCV3.1\openCV3.1.props" />
|
|
||||||
</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" />
|
|
||||||
<Import Project="..\..\3rdParty\OpenCV3.1\openCV3.1.props" />
|
|
||||||
</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" />
|
|
||||||
<Import Project="..\..\3rdParty\OpenCV3.1\openCV3.1.props" />
|
|
||||||
</ImportGroup>
|
|
||||||
<PropertyGroup Label="UserMacros" />
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<LinkIncremental>true</LinkIncremental>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
|
||||||
<LinkIncremental>true</LinkIncremental>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
||||||
<LinkIncremental>false</LinkIncremental>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
|
||||||
<LinkIncremental>false</LinkIncremental>
|
|
||||||
</PropertyGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<ClCompile>
|
|
||||||
<PrecompiledHeader>
|
|
||||||
</PrecompiledHeader>
|
|
||||||
<WarningLevel>Level3</WarningLevel>
|
|
||||||
<Optimization>Disabled</Optimization>
|
|
||||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<AdditionalIncludeDirectories>./;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<SubSystem>Console</SubSystem>
|
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
|
||||||
<ClCompile>
|
|
||||||
<PrecompiledHeader>
|
|
||||||
</PrecompiledHeader>
|
|
||||||
<WarningLevel>Level3</WarningLevel>
|
|
||||||
<Optimization>Disabled</Optimization>
|
|
||||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<AdditionalIncludeDirectories>./;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<SubSystem>Console</SubSystem>
|
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
||||||
<ClCompile>
|
|
||||||
<WarningLevel>Level3</WarningLevel>
|
|
||||||
<PrecompiledHeader>
|
|
||||||
</PrecompiledHeader>
|
|
||||||
<Optimization>MaxSpeed</Optimization>
|
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<AdditionalIncludeDirectories>./;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<SubSystem>Console</SubSystem>
|
|
||||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
|
||||||
<OptimizeReferences>true</OptimizeReferences>
|
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
|
||||||
<ClCompile>
|
|
||||||
<WarningLevel>Level3</WarningLevel>
|
|
||||||
<PrecompiledHeader>
|
|
||||||
</PrecompiledHeader>
|
|
||||||
<Optimization>MaxSpeed</Optimization>
|
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
|
||||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<AdditionalIncludeDirectories>./;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<SubSystem>Console</SubSystem>
|
|
||||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
|
||||||
<OptimizeReferences>true</OptimizeReferences>
|
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClInclude Include="camera_helper.h" />
|
|
||||||
<ClInclude Include="comet_auto_mf.h" />
|
|
||||||
<ClInclude Include="comet_com_ptr_array.h" />
|
|
||||||
<ClInclude Include="comet_task_ptr.h" />
|
|
||||||
<ClInclude Include="stdafx.h" />
|
|
||||||
<ClInclude Include="targetver.h" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClCompile Include="camera_helper.cpp" />
|
|
||||||
<ClCompile Include="stdafx.cpp" />
|
|
||||||
</ItemGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
|
||||||
<ImportGroup Label="ExtensionTargets">
|
|
||||||
</ImportGroup>
|
|
||||||
</Project>
|
|
|
@ -1,45 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<ItemGroup>
|
|
||||||
<Filter Include="Source Files">
|
|
||||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
|
||||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="Header Files">
|
|
||||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
|
||||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="Resource Files">
|
|
||||||
<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>
|
|
||||||
<ClInclude Include="camera_helper.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="comet_auto_mf.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="comet_com_ptr_array.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="comet_task_ptr.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="stdafx.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="targetver.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClCompile Include="camera_helper.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="stdafx.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
|
|
@ -1,192 +0,0 @@
|
||||||
#include "stdafx.h"
|
|
||||||
|
|
||||||
#include "camera_helper.h"
|
|
||||||
|
|
||||||
//#include <format.h>
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
namespace internal {
|
|
||||||
template<camera::Property property> struct property_traits {};
|
|
||||||
|
|
||||||
template<long Id>
|
|
||||||
struct camera_control_property_traits
|
|
||||||
{
|
|
||||||
typedef IAMCameraControl Interface;
|
|
||||||
static long id() { return Id; }
|
|
||||||
};
|
|
||||||
|
|
||||||
template<long Id>
|
|
||||||
struct video_proc_amp_property_traits
|
|
||||||
{
|
|
||||||
typedef IAMVideoProcAmp Interface;
|
|
||||||
static long id() { return Id; }
|
|
||||||
};
|
|
||||||
|
|
||||||
template<> struct property_traits < camera::Exposure > : public camera_control_property_traits<CameraControl_Exposure> {};
|
|
||||||
template<> struct property_traits < camera::Focus > : public camera_control_property_traits<CameraControl_Focus>{};
|
|
||||||
template<> struct property_traits < camera::Zoom > : public camera_control_property_traits<CameraControl_Zoom>{};
|
|
||||||
template<> struct property_traits < camera::Pan > : public camera_control_property_traits<CameraControl_Pan>{};
|
|
||||||
template<> struct property_traits < camera::Tilt > : public camera_control_property_traits<CameraControl_Tilt>{};
|
|
||||||
template<> struct property_traits < camera::Roll > : public camera_control_property_traits<CameraControl_Roll>{};
|
|
||||||
template<> struct property_traits < camera::Iris > : public camera_control_property_traits<CameraControl_Iris>{};
|
|
||||||
|
|
||||||
template<> struct property_traits < camera::Brightness > : public video_proc_amp_property_traits<VideoProcAmp_Brightness>{};
|
|
||||||
template<> struct property_traits < camera::Contrast > : public video_proc_amp_property_traits<VideoProcAmp_Contrast>{};
|
|
||||||
template<> struct property_traits < camera::Hue > : public video_proc_amp_property_traits<VideoProcAmp_Hue>{};
|
|
||||||
template<> struct property_traits < camera::Saturation > : public video_proc_amp_property_traits<VideoProcAmp_Saturation>{};
|
|
||||||
template<> struct property_traits < camera::Sharpness > : public video_proc_amp_property_traits<VideoProcAmp_Sharpness>{};
|
|
||||||
template<> struct property_traits < camera::Gamma > : public video_proc_amp_property_traits<VideoProcAmp_Gamma>{};
|
|
||||||
template<> struct property_traits < camera::ColorEnable > : public video_proc_amp_property_traits<VideoProcAmp_ColorEnable>{};
|
|
||||||
template<> struct property_traits < camera::WhiteBalance > : public video_proc_amp_property_traits<VideoProcAmp_WhiteBalance>{};
|
|
||||||
template<> struct property_traits < camera::BacklightCompensation > : public video_proc_amp_property_traits<VideoProcAmp_BacklightCompensation>{};
|
|
||||||
template<> struct property_traits < camera::Gain > : public video_proc_amp_property_traits < VideoProcAmp_Gain > {};
|
|
||||||
|
|
||||||
template<typename Interface> struct interface_traits {};
|
|
||||||
template<> struct interface_traits < IAMCameraControl >
|
|
||||||
{
|
|
||||||
static long auto_flag() { return CameraControl_Flags_Auto; }
|
|
||||||
static long manual_flag() { return CameraControl_Flags_Manual; }
|
|
||||||
};
|
|
||||||
template<> struct interface_traits<IAMVideoProcAmp>
|
|
||||||
{
|
|
||||||
static long auto_flag() { return VideoProcAmp_Flags_Auto; }
|
|
||||||
static long manual_flag() { return VideoProcAmp_Flags_Manual; }
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Interface, typename SourcePtr>
|
|
||||||
bool has(long id, const SourcePtr& source_ptr) {
|
|
||||||
comet::com_ptr<Interface> pInterface = comet::com_cast(source_ptr);
|
|
||||||
if (!pInterface) return false;
|
|
||||||
long value, flags;
|
|
||||||
HRESULT hr = pInterface->Get(id, &value, &flags);
|
|
||||||
return SUCCEEDED(hr);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Interface, typename SourcePtr>
|
|
||||||
cam_prop_range get_range(long id, const SourcePtr& source_ptr) {
|
|
||||||
comet::com_ptr<Interface> pInterface = comet::try_cast(source_ptr);
|
|
||||||
cam_prop_range range;
|
|
||||||
long flags;
|
|
||||||
pInterface->GetRange(id, &range.min, &range.max, &range.step, &range.defaultValue, &flags) | comet::raise_exception;
|
|
||||||
range.canBeAuto = (flags & interface_traits<Interface>::auto_flag()) != 0;
|
|
||||||
range.canBeManual = (flags & interface_traits<Interface>::manual_flag()) != 0;
|
|
||||||
return range;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Interface, typename SourcePtr>
|
|
||||||
cam_prop_value get(long id, const SourcePtr& source_ptr) {
|
|
||||||
comet::com_ptr<Interface> pInterface = comet::try_cast(source_ptr);
|
|
||||||
cam_prop_value value;
|
|
||||||
long flags;
|
|
||||||
pInterface->Get(id, &value.value, &flags) | comet::raise_exception;
|
|
||||||
value.isAuto = (flags & interface_traits<Interface>::auto_flag()) != 0 || (flags & interface_traits<Interface>::manual_flag()) == 0;
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Interface, typename SourcePtr>
|
|
||||||
void set(long id, const cam_prop_value& value, const SourcePtr& source_ptr) {
|
|
||||||
comet::com_ptr<Interface> pInterface = comet::try_cast(source_ptr);
|
|
||||||
long flags = value.isAuto ? interface_traits<Interface>::auto_flag() : interface_traits<Interface>::manual_flag();
|
|
||||||
pInterface->Set(id, value.value, flags) | comet::raise_exception;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#define MAP_OVER_CAMERA_PROPERTIES(FUNC) \
|
|
||||||
FUNC(::camera::Exposure, Exposure) \
|
|
||||||
FUNC(::camera::Focus, Focus) \
|
|
||||||
FUNC(::camera::Zoom, Zoom) \
|
|
||||||
FUNC(::camera::Pan, Pan) \
|
|
||||||
FUNC(::camera::Tilt, Tilt) \
|
|
||||||
FUNC(::camera::Roll, Roll) \
|
|
||||||
FUNC(::camera::Iris, Iris) \
|
|
||||||
FUNC(::camera::Brightness, Brightness) \
|
|
||||||
FUNC(::camera::Contrast, Contrast) \
|
|
||||||
FUNC(::camera::Hue, Hue) \
|
|
||||||
FUNC(::camera::Saturation, Saturation) \
|
|
||||||
FUNC(::camera::Sharpness, Sharpness) \
|
|
||||||
FUNC(::camera::Gamma, Gamma) \
|
|
||||||
FUNC(::camera::ColorEnable, Color Enable) \
|
|
||||||
FUNC(::camera::WhiteBalance, White Balance) \
|
|
||||||
FUNC(::camera::BacklightCompensation, Backlight Compensation) \
|
|
||||||
FUNC(::camera::Gain, Gain)
|
|
||||||
|
|
||||||
|
|
||||||
bool camera::has(Property property) const
|
|
||||||
{
|
|
||||||
switch (property) {
|
|
||||||
#define CASE(PROP, NAME) case PROP: return ::internal::has<::internal::property_traits<PROP>::Interface>(::internal::property_traits<PROP>::id(), source_ptr);
|
|
||||||
MAP_OVER_CAMERA_PROPERTIES(CASE)
|
|
||||||
#undef CASE
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cam_prop_range camera::get_range(Property property) const
|
|
||||||
{
|
|
||||||
switch (property) {
|
|
||||||
#define CASE(PROP, NAME) case PROP: return ::internal::get_range<::internal::property_traits<PROP>::Interface>(::internal::property_traits<PROP>::id(), source_ptr);
|
|
||||||
MAP_OVER_CAMERA_PROPERTIES(CASE)
|
|
||||||
#undef CASE
|
|
||||||
default:
|
|
||||||
throw std::runtime_error("No such property: " + std::string(camera::property_name(property)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cam_prop_value camera::get(Property property) const
|
|
||||||
{
|
|
||||||
switch (property) {
|
|
||||||
#define CASE(PROP, NAME) case PROP: return ::internal::get<::internal::property_traits<PROP>::Interface>(::internal::property_traits<PROP>::id(), source_ptr);
|
|
||||||
MAP_OVER_CAMERA_PROPERTIES(CASE)
|
|
||||||
#undef CASE
|
|
||||||
default:
|
|
||||||
throw std::runtime_error("No such property: " + std::string(camera::property_name(property)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void camera::set(Property property, const cam_prop_value& value)
|
|
||||||
{
|
|
||||||
switch (property) {
|
|
||||||
#define CASE(PROP, NAME) case PROP: ::internal::set<::internal::property_traits<PROP>::Interface>(::internal::property_traits<PROP>::id(), value, source_ptr); break;
|
|
||||||
MAP_OVER_CAMERA_PROPERTIES(CASE)
|
|
||||||
#undef CASE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<camera::Property> camera::list_properties()
|
|
||||||
{
|
|
||||||
std::vector<camera::Property> properties;
|
|
||||||
properties.push_back(Exposure); // CameraControl
|
|
||||||
properties.push_back(Focus);
|
|
||||||
properties.push_back(Zoom);
|
|
||||||
properties.push_back(Pan);
|
|
||||||
properties.push_back(Tilt);
|
|
||||||
properties.push_back(Roll);
|
|
||||||
properties.push_back(Iris);
|
|
||||||
|
|
||||||
properties.push_back(Brightness);
|
|
||||||
properties.push_back(Contrast);
|
|
||||||
properties.push_back(Hue);
|
|
||||||
properties.push_back(Saturation);
|
|
||||||
properties.push_back(Sharpness);
|
|
||||||
properties.push_back(Gamma);
|
|
||||||
properties.push_back(ColorEnable);
|
|
||||||
properties.push_back(WhiteBalance);
|
|
||||||
properties.push_back(BacklightCompensation);
|
|
||||||
properties.push_back(Gain);
|
|
||||||
|
|
||||||
return properties;
|
|
||||||
//#define PROPENTRY(PROP, NAME) PROP,
|
|
||||||
// MAP_OVER_CAMERA_PROPERTIES(PROPENTRY)
|
|
||||||
//#undef PROPENTRY
|
|
||||||
// };
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* camera::property_name(Property property)
|
|
||||||
{
|
|
||||||
switch (property) {
|
|
||||||
#define CASE(PROP, NAME) case PROP: return #NAME;
|
|
||||||
MAP_OVER_CAMERA_PROPERTIES(CASE)
|
|
||||||
#undef CASE
|
|
||||||
default:
|
|
||||||
return "UNKNOWN";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,720 +0,0 @@
|
||||||
#ifndef camera_helper_h__
|
|
||||||
#define camera_helper_h__
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include <cv.h>
|
|
||||||
#include <highgui.h>
|
|
||||||
#include <opencv2/imgcodecs.hpp>
|
|
||||||
|
|
||||||
#include <mfapi.h>
|
|
||||||
#include <mfidl.h>
|
|
||||||
#include <mfreadwrite.h>
|
|
||||||
#include <mferror.h>
|
|
||||||
|
|
||||||
#include <DShow.h>
|
|
||||||
|
|
||||||
#include <comet/ptr.h>
|
|
||||||
|
|
||||||
#include <comet_task_ptr.h>
|
|
||||||
#include <comet_com_ptr_array.h>
|
|
||||||
|
|
||||||
namespace comet {
|
|
||||||
|
|
||||||
#define MAKE_COMET_COMTYPE(T, BASE) \
|
|
||||||
template<> struct comtype< ::T > \
|
|
||||||
{ \
|
|
||||||
static const IID& uuid() { return IID_ ## T; } \
|
|
||||||
typedef ::BASE base; \
|
|
||||||
}
|
|
||||||
|
|
||||||
MAKE_COMET_COMTYPE(IMF2DBuffer, IUnknown);
|
|
||||||
MAKE_COMET_COMTYPE(IAMVideoProcAmp, IUnknown);
|
|
||||||
MAKE_COMET_COMTYPE(IAMCameraControl, IUnknown);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct cam_prop_range
|
|
||||||
{
|
|
||||||
long min;
|
|
||||||
long max;
|
|
||||||
long step;
|
|
||||||
long defaultValue;
|
|
||||||
bool canBeAuto;
|
|
||||||
bool canBeManual;
|
|
||||||
};
|
|
||||||
|
|
||||||
inline std::ostream& operator<<(std::ostream& os, const cam_prop_range& val)
|
|
||||||
{
|
|
||||||
os << "[" << val.min << ":" << val.step << ":" << val.max << "], " << val.defaultValue;
|
|
||||||
if (val.canBeAuto && val.canBeManual)
|
|
||||||
os << " (auto/manual)";
|
|
||||||
else if (val.canBeAuto)
|
|
||||||
os << " (auto)";
|
|
||||||
else if (val.canBeManual)
|
|
||||||
os << " (manual)";
|
|
||||||
return os;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct cam_prop_value
|
|
||||||
{
|
|
||||||
long value;
|
|
||||||
bool isAuto;
|
|
||||||
|
|
||||||
cam_prop_value() : value(0), isAuto(true)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
cam_prop_value(long value, bool isAuto = false) : value(value), isAuto(isAuto)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
operator long() const
|
|
||||||
{
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cam_prop_value AUTO(long value = 0) {
|
|
||||||
return cam_prop_value(value, true);
|
|
||||||
};
|
|
||||||
static cam_prop_value MANUAL(long value = 0) {
|
|
||||||
return cam_prop_value(value, false);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
inline std::ostream& operator<<(std::ostream& os, const cam_prop_value& val)
|
|
||||||
{
|
|
||||||
os << val.value;
|
|
||||||
os << " (";
|
|
||||||
if (val.isAuto)
|
|
||||||
os << "auto";
|
|
||||||
else
|
|
||||||
os << "manual";
|
|
||||||
os << ")";
|
|
||||||
return os;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace MediaFormat
|
|
||||||
{
|
|
||||||
enum e
|
|
||||||
{
|
|
||||||
Unknown,
|
|
||||||
RGB32, // MFVideoFormat_RGB32
|
|
||||||
ARGB32, // MFVideoFormat_ARGB32
|
|
||||||
RGB24, // MFVideoFormat_RGB24
|
|
||||||
RGB555, // MFVideoFormat_RGB555
|
|
||||||
RGB565, // MFVideoFormat_RGB565
|
|
||||||
RGB8, // MFVideoFormat_RGB8
|
|
||||||
AI44, // MFVideoFormat_AI44
|
|
||||||
AYUV, // MFVideoFormat_AYUV
|
|
||||||
YUY2, // MFVideoFormat_YUY2
|
|
||||||
YVYU, // MFVideoFormat_YVYU
|
|
||||||
YVU9, // MFVideoFormat_YVU9
|
|
||||||
UYVY, // MFVideoFormat_UYVY
|
|
||||||
NV11, // MFVideoFormat_NV11
|
|
||||||
NV12, // MFVideoFormat_NV12
|
|
||||||
YV12, // MFVideoFormat_YV12
|
|
||||||
I420, // MFVideoFormat_I420
|
|
||||||
IYUV, // MFVideoFormat_IYUV
|
|
||||||
Y210, // MFVideoFormat_Y210
|
|
||||||
Y216, // MFVideoFormat_Y216
|
|
||||||
Y410, // MFVideoFormat_Y410
|
|
||||||
Y416, // MFVideoFormat_Y416
|
|
||||||
Y41P, // MFVideoFormat_Y41P
|
|
||||||
Y41T, // MFVideoFormat_Y41T
|
|
||||||
Y42T, // MFVideoFormat_Y42T
|
|
||||||
P210, // MFVideoFormat_P210
|
|
||||||
P216, // MFVideoFormat_P216
|
|
||||||
P010, // MFVideoFormat_P010
|
|
||||||
P016, // MFVideoFormat_P016
|
|
||||||
v210, // MFVideoFormat_v210
|
|
||||||
v216, // MFVideoFormat_v216
|
|
||||||
v410, // MFVideoFormat_v410
|
|
||||||
MP43, // MFVideoFormat_MP43
|
|
||||||
MP4S, // MFVideoFormat_MP4S
|
|
||||||
M4S2, // MFVideoFormat_M4S2
|
|
||||||
MP4V, // MFVideoFormat_MP4V
|
|
||||||
WMV1, // MFVideoFormat_WMV1
|
|
||||||
WMV2, // MFVideoFormat_WMV2
|
|
||||||
WMV3, // MFVideoFormat_WMV3
|
|
||||||
WVC1, // MFVideoFormat_WVC1
|
|
||||||
MSS1, // MFVideoFormat_MSS1
|
|
||||||
MSS2, // MFVideoFormat_MSS2
|
|
||||||
MPG1, // MFVideoFormat_MPG1
|
|
||||||
DVSL, // MFVideoFormat_DVSL
|
|
||||||
DVSD, // MFVideoFormat_DVSD
|
|
||||||
DVHD, // MFVideoFormat_DVHD
|
|
||||||
DV25, // MFVideoFormat_DV25
|
|
||||||
DV50, // MFVideoFormat_DV50
|
|
||||||
DVH1, // MFVideoFormat_DVH1
|
|
||||||
DVC, // MFVideoFormat_DVC
|
|
||||||
H264, // MFVideoFormat_H264
|
|
||||||
MJPG, // MFVideoFormat_MJPG
|
|
||||||
YUV_420O, // MFVideoFormat_420O
|
|
||||||
H263, // MFVideoFormat_H263
|
|
||||||
H264_ES, // MFVideoFormat_H264_ES
|
|
||||||
MPEG2, // MFVideoFormat_MPEG2
|
|
||||||
};
|
|
||||||
|
|
||||||
inline e fromGUID(GUID guid)
|
|
||||||
{
|
|
||||||
if (guid == MFVideoFormat_RGB32) return RGB32;
|
|
||||||
else if (guid == MFVideoFormat_ARGB32) return ARGB32;
|
|
||||||
else if (guid == MFVideoFormat_RGB24) return RGB24;
|
|
||||||
else if (guid == MFVideoFormat_RGB555) return RGB555;
|
|
||||||
else if (guid == MFVideoFormat_RGB565) return RGB565;
|
|
||||||
else if (guid == MFVideoFormat_RGB8) return RGB8;
|
|
||||||
else if (guid == MFVideoFormat_AI44) return AI44;
|
|
||||||
else if (guid == MFVideoFormat_AYUV) return AYUV;
|
|
||||||
else if (guid == MFVideoFormat_YUY2) return YUY2;
|
|
||||||
else if (guid == MFVideoFormat_YVYU) return YVYU;
|
|
||||||
else if (guid == MFVideoFormat_YVU9) return YVU9;
|
|
||||||
else if (guid == MFVideoFormat_UYVY) return UYVY;
|
|
||||||
else if (guid == MFVideoFormat_NV11) return NV11;
|
|
||||||
else if (guid == MFVideoFormat_NV12) return NV12;
|
|
||||||
else if (guid == MFVideoFormat_YV12) return YV12;
|
|
||||||
else if (guid == MFVideoFormat_I420) return I420;
|
|
||||||
else if (guid == MFVideoFormat_IYUV) return IYUV;
|
|
||||||
else if (guid == MFVideoFormat_Y210) return Y210;
|
|
||||||
else if (guid == MFVideoFormat_Y216) return Y216;
|
|
||||||
else if (guid == MFVideoFormat_Y410) return Y410;
|
|
||||||
else if (guid == MFVideoFormat_Y416) return Y416;
|
|
||||||
else if (guid == MFVideoFormat_Y41P) return Y41P;
|
|
||||||
else if (guid == MFVideoFormat_Y41T) return Y41T;
|
|
||||||
else if (guid == MFVideoFormat_Y42T) return Y42T;
|
|
||||||
else if (guid == MFVideoFormat_P210) return P210;
|
|
||||||
else if (guid == MFVideoFormat_P216) return P216;
|
|
||||||
else if (guid == MFVideoFormat_P010) return P010;
|
|
||||||
else if (guid == MFVideoFormat_P016) return P016;
|
|
||||||
else if (guid == MFVideoFormat_v210) return v210;
|
|
||||||
else if (guid == MFVideoFormat_v216) return v216;
|
|
||||||
else if (guid == MFVideoFormat_v410) return v410;
|
|
||||||
else if (guid == MFVideoFormat_MP43) return MP43;
|
|
||||||
else if (guid == MFVideoFormat_MP4S) return MP4S;
|
|
||||||
else if (guid == MFVideoFormat_M4S2) return M4S2;
|
|
||||||
else if (guid == MFVideoFormat_MP4V) return MP4V;
|
|
||||||
else if (guid == MFVideoFormat_WMV1) return WMV1;
|
|
||||||
else if (guid == MFVideoFormat_WMV2) return WMV2;
|
|
||||||
else if (guid == MFVideoFormat_WMV3) return WMV3;
|
|
||||||
else if (guid == MFVideoFormat_WVC1) return WVC1;
|
|
||||||
else if (guid == MFVideoFormat_MSS1) return MSS1;
|
|
||||||
else if (guid == MFVideoFormat_MSS2) return MSS2;
|
|
||||||
else if (guid == MFVideoFormat_MPG1) return MPG1;
|
|
||||||
else if (guid == MFVideoFormat_DVSL) return DVSL;
|
|
||||||
else if (guid == MFVideoFormat_DVSD) return DVSD;
|
|
||||||
else if (guid == MFVideoFormat_DVHD) return DVHD;
|
|
||||||
else if (guid == MFVideoFormat_DV25) return DV25;
|
|
||||||
else if (guid == MFVideoFormat_DV50) return DV50;
|
|
||||||
else if (guid == MFVideoFormat_DVH1) return DVH1;
|
|
||||||
else if (guid == MFVideoFormat_DVC) return DVC;
|
|
||||||
else if (guid == MFVideoFormat_H264) return H264;
|
|
||||||
else if (guid == MFVideoFormat_MJPG) return MJPG;
|
|
||||||
else if (guid == MFVideoFormat_420O) return YUV_420O;
|
|
||||||
else if (guid == MFVideoFormat_H263) return H263;
|
|
||||||
else if (guid == MFVideoFormat_H264_ES) return H264_ES;
|
|
||||||
else if (guid == MFVideoFormat_MPEG2) return MPEG2;
|
|
||||||
else return Unknown;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const char* to_string (const MediaFormat::e& format)
|
|
||||||
{
|
|
||||||
switch (format)
|
|
||||||
{
|
|
||||||
case RGB32: return "RGB32";
|
|
||||||
case ARGB32: return "ARGB32";
|
|
||||||
case RGB24: return "RGB24";
|
|
||||||
case RGB555: return "RGB555";
|
|
||||||
case RGB565: return "RGB565";
|
|
||||||
case RGB8: return "RGB8";
|
|
||||||
case AI44: return "AI44";
|
|
||||||
case AYUV: return "AYUV";
|
|
||||||
case YUY2: return "YUY2";
|
|
||||||
case YVYU: return "YVYU";
|
|
||||||
case YVU9: return "YVU9";
|
|
||||||
case UYVY: return "UYVY";
|
|
||||||
case NV11: return "NV11";
|
|
||||||
case NV12: return "NV12";
|
|
||||||
case YV12: return "YV12";
|
|
||||||
case I420: return "I420";
|
|
||||||
case IYUV: return "IYUV";
|
|
||||||
case Y210: return "Y210";
|
|
||||||
case Y216: return "Y216";
|
|
||||||
case Y410: return "Y410";
|
|
||||||
case Y416: return "Y416";
|
|
||||||
case Y41P: return "Y41P";
|
|
||||||
case Y41T: return "Y41T";
|
|
||||||
case Y42T: return "Y42T";
|
|
||||||
case P210: return "P210";
|
|
||||||
case P216: return "P216";
|
|
||||||
case P010: return "P010";
|
|
||||||
case P016: return "P016";
|
|
||||||
case v210: return "v210";
|
|
||||||
case v216: return "v216";
|
|
||||||
case v410: return "v410";
|
|
||||||
case MP43: return "MP43";
|
|
||||||
case MP4S: return "MP4S";
|
|
||||||
case M4S2: return "M4S2";
|
|
||||||
case MP4V: return "MP4V";
|
|
||||||
case WMV1: return "WMV1";
|
|
||||||
case WMV2: return "WMV2";
|
|
||||||
case WMV3: return "WMV3";
|
|
||||||
case WVC1: return "WVC1";
|
|
||||||
case MSS1: return "MSS1";
|
|
||||||
case MSS2: return "MSS2";
|
|
||||||
case MPG1: return "MPG1";
|
|
||||||
case DVSL: return "DVSL";
|
|
||||||
case DVSD: return "DVSD";
|
|
||||||
case DVHD: return "DVHD";
|
|
||||||
case DV25: return "DV25";
|
|
||||||
case DV50: return "DV50";
|
|
||||||
case DVH1: return "DVH1";
|
|
||||||
case DVC: return "DVC";
|
|
||||||
case H264: return "H264";
|
|
||||||
case MJPG: return "MJPG";
|
|
||||||
case YUV_420O: return "420O";
|
|
||||||
case H263: return "H263";
|
|
||||||
case H264_ES: return "H264_ES";
|
|
||||||
case MPEG2: return "MPEG2";
|
|
||||||
default: return "Unknown";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline std::ostream& operator<< (std::ostream& os, const MediaFormat::e& format)
|
|
||||||
{
|
|
||||||
return os << to_string(format);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class media_type
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
media_type() : _ptr(NULL)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
media_type(IMFMediaType* ptr) : _ptr(ptr)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
media_type(comet::com_ptr<IMFMediaType> ptr) : _ptr(ptr)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
cv::Size resolution() const
|
|
||||||
{
|
|
||||||
UINT32 width, height;
|
|
||||||
MFGetAttributeSize(_ptr.in(), MF_MT_FRAME_SIZE, &width, &height) | comet::raise_exception;
|
|
||||||
return cv::Size(width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
double framerate() const
|
|
||||||
{
|
|
||||||
UINT32 num, denom;
|
|
||||||
MFGetAttributeRatio(_ptr.in(), MF_MT_FRAME_RATE, &num, &denom) | comet::raise_exception;
|
|
||||||
return static_cast<double>(num) / denom;
|
|
||||||
}
|
|
||||||
|
|
||||||
MediaFormat::e format() const
|
|
||||||
{
|
|
||||||
GUID subtype;
|
|
||||||
_ptr->GetGUID(MF_MT_SUBTYPE, &subtype) | comet::raise_exception;
|
|
||||||
return MediaFormat::fromGUID(subtype);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef _TYPEDEF_BOOL_TYPE
|
|
||||||
typedef media_type _Myt;
|
|
||||||
_TYPEDEF_BOOL_TYPE;
|
|
||||||
_OPERATOR_BOOL() const _NOEXCEPT
|
|
||||||
{ // test for non-null pointer
|
|
||||||
return (_ptr != 0 ? _CONVERTIBLE_TO_TRUE : 0);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
explicit operator bool() const
|
|
||||||
{ // test for non-null pointer
|
|
||||||
return _ptr != 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
comet::com_ptr<IMFMediaType> _ptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class camera
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
camera()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
camera(IMFActivate* ptr) : activate_ptr(ptr)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
camera(comet::com_ptr<IMFActivate> ptr) : activate_ptr(ptr)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO actually implement these or make sure they are deleted/created correctly, this might be the reason for weird mapping of stuff
|
|
||||||
camera(const camera& other)
|
|
||||||
{
|
|
||||||
// this->
|
|
||||||
// this = other;
|
|
||||||
}
|
|
||||||
//= delete;
|
|
||||||
|
|
||||||
camera(camera&& other)
|
|
||||||
{
|
|
||||||
*this = std::move(other);
|
|
||||||
}
|
|
||||||
|
|
||||||
//camera& operator=(const camera& other) = delete;
|
|
||||||
|
|
||||||
camera& operator=(camera&& other)
|
|
||||||
{
|
|
||||||
activate_ptr.swap(other.activate_ptr);
|
|
||||||
source_ptr.swap(other.source_ptr);
|
|
||||||
reader_ptr.swap(other.reader_ptr);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
~camera()
|
|
||||||
{
|
|
||||||
shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool is_active() const
|
|
||||||
{
|
|
||||||
return !source_ptr.is_null();
|
|
||||||
}
|
|
||||||
|
|
||||||
void activate()
|
|
||||||
{
|
|
||||||
if (activate_ptr)
|
|
||||||
activate_ptr->ActivateObject(IID_IMFMediaSource, reinterpret_cast<void**>(source_ptr.out())) | comet::raise_exception;
|
|
||||||
reader_ptr = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void shutdown()
|
|
||||||
{
|
|
||||||
if (activate_ptr)
|
|
||||||
activate_ptr->ShutdownObject() | comet::raise_exception;
|
|
||||||
source_ptr = NULL;
|
|
||||||
reader_ptr = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
cv::Mat read_frame(int streamIndex = MF_SOURCE_READER_FIRST_VIDEO_STREAM, int bufferIndex = 0)
|
|
||||||
{
|
|
||||||
if (!activate_ptr)
|
|
||||||
return cv::Mat();
|
|
||||||
|
|
||||||
if (!reader_ptr)
|
|
||||||
{
|
|
||||||
comet::com_ptr<IMFAttributes> pAttributes;
|
|
||||||
MFCreateAttributes(pAttributes.out(), 1) | comet::raise_exception;
|
|
||||||
pAttributes->SetUINT32(MF_SOURCE_READER_ENABLE_VIDEO_PROCESSING, TRUE) | comet::raise_exception;
|
|
||||||
pAttributes->SetUINT32(MF_SOURCE_READER_DISCONNECT_MEDIASOURCE_ON_SHUTDOWN, TRUE) | comet::raise_exception;
|
|
||||||
|
|
||||||
MFCreateSourceReaderFromMediaSource(source_ptr.in(), pAttributes.in(), reader_ptr.out()) | comet::raise_exception;
|
|
||||||
}
|
|
||||||
|
|
||||||
comet::com_ptr<IMFSample> sample;
|
|
||||||
DWORD actualStreamIndex, flags;
|
|
||||||
LONGLONG timestamp;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
do
|
|
||||||
{
|
|
||||||
reader_ptr->ReadSample(
|
|
||||||
streamIndex, // Stream index.
|
|
||||||
0, // Flags.
|
|
||||||
&actualStreamIndex, // Receives the actual stream index.
|
|
||||||
&flags, // Receives status flags.
|
|
||||||
×tamp, // Receives the time stamp.
|
|
||||||
sample.out() // Receives the sample or NULL.
|
|
||||||
) | comet::raise_exception;
|
|
||||||
} while (sample == NULL && (flags & MF_SOURCE_READERF_STREAMTICK));
|
|
||||||
}
|
|
||||||
catch (std::exception& e)
|
|
||||||
{
|
|
||||||
std::cerr << "Error getting frame: " << e.what() << std::endl;
|
|
||||||
std::cerr << " flags: " << flags << std::endl;
|
|
||||||
shutdown();
|
|
||||||
activate();
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
|
|
||||||
media_type cur_media_type;
|
|
||||||
reader_ptr->GetCurrentMediaType(actualStreamIndex, cur_media_type._ptr.out()) | comet::raise_exception;
|
|
||||||
|
|
||||||
//PrintAttributes(cur_media_type._ptr.in());
|
|
||||||
|
|
||||||
auto format = cur_media_type.format();
|
|
||||||
|
|
||||||
cv::Mat ret;
|
|
||||||
|
|
||||||
DWORD bufCount;
|
|
||||||
sample->GetBufferCount(&bufCount) | comet::raise_exception;
|
|
||||||
|
|
||||||
DWORD bufIndex = bufferIndex >= 0 ? bufferIndex : bufCount - bufferIndex;
|
|
||||||
|
|
||||||
if (bufCount > bufIndex)
|
|
||||||
{
|
|
||||||
comet::com_ptr<IMFMediaBuffer> buffer;
|
|
||||||
sample->GetBufferByIndex(bufferIndex, buffer.out()) | comet::raise_exception;
|
|
||||||
|
|
||||||
switch (format)
|
|
||||||
{
|
|
||||||
case MediaFormat::RGB24:
|
|
||||||
case MediaFormat::ARGB32:
|
|
||||||
case MediaFormat::RGB32:
|
|
||||||
{
|
|
||||||
comet::com_ptr<IMF2DBuffer> buf2d = try_cast(buffer);
|
|
||||||
|
|
||||||
//DWORD length;
|
|
||||||
//buf2d->GetContiguousLength(&length) | comet::raise_exception;
|
|
||||||
|
|
||||||
//ret.create();
|
|
||||||
|
|
||||||
//COMET_ASSERT(ret.dataend - ret.datastart == length);
|
|
||||||
|
|
||||||
auto resolution = cur_media_type.resolution();
|
|
||||||
|
|
||||||
struct buf2d_lock
|
|
||||||
{
|
|
||||||
comet::com_ptr<IMF2DBuffer>& buf2d;
|
|
||||||
|
|
||||||
buf2d_lock(comet::com_ptr<IMF2DBuffer>& buf2d, BYTE*& scanline0, LONG& pitch) : buf2d(buf2d)
|
|
||||||
{
|
|
||||||
buf2d->Lock2D(&scanline0, &pitch) | comet::raise_exception;
|
|
||||||
}
|
|
||||||
|
|
||||||
~buf2d_lock()
|
|
||||||
{
|
|
||||||
buf2d->Unlock2D() | comet::raise_exception;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
BYTE *scanline0;
|
|
||||||
LONG pitch;
|
|
||||||
buf2d_lock buf_lock_token(buf2d, scanline0, pitch);
|
|
||||||
if (pitch >= 0)
|
|
||||||
{
|
|
||||||
cv::Mat buf2dmat(resolution,
|
|
||||||
(format == MediaFormat::RGB24) ? CV_8UC3 : CV_8UC4,
|
|
||||||
scanline0,
|
|
||||||
pitch);
|
|
||||||
buf2dmat.copyTo(ret);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cv::Mat buf2dmat(resolution,
|
|
||||||
(format == MediaFormat::RGB24) ? CV_8UC3 : CV_8UC4,
|
|
||||||
scanline0 + pitch*(resolution.height-1),
|
|
||||||
-pitch);
|
|
||||||
cv::flip(buf2dmat, ret, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MediaFormat::MJPG:
|
|
||||||
{
|
|
||||||
struct buf_lock
|
|
||||||
{
|
|
||||||
comet::com_ptr<IMFMediaBuffer>& buffer;
|
|
||||||
|
|
||||||
buf_lock(comet::com_ptr<IMFMediaBuffer>& buffer, BYTE*& data, DWORD& maxLength, DWORD& length) : buffer(buffer)
|
|
||||||
{
|
|
||||||
buffer->Lock(&data, &maxLength, &length) | comet::raise_exception;
|
|
||||||
}
|
|
||||||
|
|
||||||
~buf_lock()
|
|
||||||
{
|
|
||||||
buffer->Unlock() | comet::raise_exception;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
BYTE* data;
|
|
||||||
DWORD length;
|
|
||||||
DWORD maxLength;
|
|
||||||
|
|
||||||
buf_lock buf_lock_token(buffer, data, maxLength, length);
|
|
||||||
|
|
||||||
ret = cv::imdecode(cv::Mat(length, 1, CV_8U, data), cv::IMREAD_COLOR);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
std::stringstream sstream;
|
|
||||||
sstream << "Unknown media format: " << format;
|
|
||||||
throw std::runtime_error(sstream.str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string name() const
|
|
||||||
{
|
|
||||||
return get_attr_str(MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string symlink() const
|
|
||||||
{
|
|
||||||
return get_attr_str(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO change
|
|
||||||
//explicit operator bool() const
|
|
||||||
//{
|
|
||||||
// return !activate_ptr.is_null();
|
|
||||||
//}
|
|
||||||
|
|
||||||
enum Property
|
|
||||||
{
|
|
||||||
// CameraControl
|
|
||||||
Exposure,
|
|
||||||
Focus,
|
|
||||||
Zoom,
|
|
||||||
Pan,
|
|
||||||
Tilt,
|
|
||||||
Roll,
|
|
||||||
Iris,
|
|
||||||
|
|
||||||
// VideoProcAmp
|
|
||||||
Brightness,
|
|
||||||
Contrast,
|
|
||||||
Hue,
|
|
||||||
Saturation,
|
|
||||||
Sharpness,
|
|
||||||
Gamma,
|
|
||||||
ColorEnable,
|
|
||||||
WhiteBalance,
|
|
||||||
BacklightCompensation,
|
|
||||||
Gain
|
|
||||||
};
|
|
||||||
|
|
||||||
bool has(Property property) const;
|
|
||||||
cam_prop_range get_range(Property property) const;
|
|
||||||
cam_prop_value get(Property property) const;
|
|
||||||
void set(Property property, const cam_prop_value& value);
|
|
||||||
|
|
||||||
static std::vector<Property> list_properties();
|
|
||||||
static const char* property_name(Property);
|
|
||||||
|
|
||||||
std::vector<media_type> media_types(int streamIndex = 0) const
|
|
||||||
{
|
|
||||||
auto pHandler = getMediaTypeHandler(streamIndex);
|
|
||||||
|
|
||||||
DWORD cTypes = 0;
|
|
||||||
pHandler->GetMediaTypeCount(&cTypes) | comet::raise_exception;
|
|
||||||
|
|
||||||
std::vector<media_type> ret;
|
|
||||||
for (DWORD i = 0; i < cTypes; i++)
|
|
||||||
{
|
|
||||||
comet::com_ptr<IMFMediaType> pType;
|
|
||||||
pHandler->GetMediaTypeByIndex(i, pType.out()) | comet::raise_exception;
|
|
||||||
ret.emplace_back(pType);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
media_type get_media_type(int streamIndex = 0)
|
|
||||||
{
|
|
||||||
media_type ret;
|
|
||||||
getMediaTypeHandler(streamIndex)->GetCurrentMediaType(ret._ptr.out()) | comet::raise_exception;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_media_type(const media_type& type, int streamIndex = 0)
|
|
||||||
{
|
|
||||||
getMediaTypeHandler(streamIndex)->SetCurrentMediaType(type._ptr.in()) | comet::raise_exception;
|
|
||||||
if (reader_ptr)
|
|
||||||
{
|
|
||||||
reader_ptr->SetCurrentMediaType(streamIndex, nullptr, type._ptr.in()) | comet::raise_exception;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO change
|
|
||||||
//explicit operator bool() {
|
|
||||||
// return !activate_ptr.is_null();
|
|
||||||
//}
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::string get_attr_str(REFGUID guid) const
|
|
||||||
{
|
|
||||||
comet::task_ptr<WCHAR> pStr;
|
|
||||||
UINT32 strLen;
|
|
||||||
activate_ptr->GetAllocatedString(guid, pStr.out(), &strLen) | comet::raise_exception;
|
|
||||||
return comet::bstr_t(pStr.in(), strLen).s_str();
|
|
||||||
}
|
|
||||||
|
|
||||||
comet::com_ptr<IMFMediaTypeHandler> getMediaTypeHandler(int streamIndex = 0) const
|
|
||||||
{
|
|
||||||
comet::com_ptr<IMFPresentationDescriptor> pPD;
|
|
||||||
source_ptr->CreatePresentationDescriptor(pPD.out()) | comet::raise_exception;
|
|
||||||
|
|
||||||
BOOL fSelected;
|
|
||||||
comet::com_ptr<IMFStreamDescriptor> pSD;
|
|
||||||
pPD->GetStreamDescriptorByIndex(streamIndex, &fSelected, pSD.out()) | comet::raise_exception;
|
|
||||||
|
|
||||||
comet::com_ptr<IMFMediaTypeHandler> pHandler;
|
|
||||||
pSD->GetMediaTypeHandler(pHandler.out()) | comet::raise_exception;
|
|
||||||
|
|
||||||
return pHandler;
|
|
||||||
}
|
|
||||||
|
|
||||||
comet::com_ptr<IMFActivate> activate_ptr;
|
|
||||||
comet::com_ptr<IMFMediaSource> source_ptr;
|
|
||||||
comet::com_ptr<IMFSourceReader> reader_ptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
class camera_helper
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
static std::vector<camera> get_all_cameras()
|
|
||||||
{
|
|
||||||
comet::com_ptr<IMFAttributes> config;
|
|
||||||
MFCreateAttributes(config.out(), 1) | comet::raise_exception;
|
|
||||||
|
|
||||||
config->SetGUID(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE, MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID) | comet::raise_exception;
|
|
||||||
|
|
||||||
comet::com_ptr_array<IMFActivate> com_ptr_array;
|
|
||||||
MFEnumDeviceSources(config.in(), com_ptr_array.out(), com_ptr_array.out_count()) | comet::raise_exception;
|
|
||||||
|
|
||||||
std::vector<camera> ret;
|
|
||||||
for (size_t i = 0; i < com_ptr_array.count(); ++i)
|
|
||||||
{
|
|
||||||
ret.emplace_back(com_ptr_array[i]);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static camera get_camera_by_symlink(const std::string& symlink)
|
|
||||||
{
|
|
||||||
// This is how you should do it, but for some reason it gives an activate pointer with no friendly name
|
|
||||||
|
|
||||||
// comet::com_ptr<IMFAttributes> config;
|
|
||||||
// MFCreateAttributes(config.out(), 1) | comet::raise_exception;
|
|
||||||
//
|
|
||||||
// config->SetGUID(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE, MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID) | comet::raise_exception;
|
|
||||||
// comet::bstr_t symlink_bstr(symlink);
|
|
||||||
// config->SetString(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK, symlink_bstr.c_str()) | comet::raise_exception;
|
|
||||||
//
|
|
||||||
// comet::com_ptr<IMFActivate> activate_ptr;
|
|
||||||
// MFCreateDeviceSourceActivate(config.in(), activate_ptr.out()) | comet::raise_exception;
|
|
||||||
//
|
|
||||||
// return camera(activate_ptr);
|
|
||||||
|
|
||||||
for(auto&& camera : get_all_cameras())
|
|
||||||
{
|
|
||||||
if (camera.symlink() == symlink)
|
|
||||||
return std::move(camera);
|
|
||||||
}
|
|
||||||
|
|
||||||
throw std::runtime_error("No camera with symlink: " + std::string(symlink));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // camera_helper_h__
|
|
|
@ -1,150 +0,0 @@
|
||||||
/** \file
|
|
||||||
* Array wrapper.
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* Copyright © 2001 Sofus Mortensen
|
|
||||||
*
|
|
||||||
* This material is provided "as is", with absolutely no warranty
|
|
||||||
* expressed or implied. Any use is at your own risk. Permission to
|
|
||||||
* use or copy this software for any purpose is hereby granted without
|
|
||||||
* fee, provided the above notices are retained on all copies.
|
|
||||||
* Permission to modify the code and to distribute modified code is
|
|
||||||
* granted, provided the above notices are retained, and a notice that
|
|
||||||
* the code was modified is included with the above copyright notice.
|
|
||||||
*
|
|
||||||
* This header is part of Comet version 2.
|
|
||||||
* https://github.com/alamaison/comet
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* comet::array_t is adapted from class array by Nicolai M. Josuttis
|
|
||||||
*
|
|
||||||
* (C) Copyright Nicolai M. Josuttis 2001.
|
|
||||||
* Permission to copy, use, modify, sell and distribute this software
|
|
||||||
* is granted provided this copyright notice appears in all copies.
|
|
||||||
* This software is provided "as is" without express or implied
|
|
||||||
* warranty, and with no claim as to its suitability for any purpose.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef COMET_ARRAY_H
|
|
||||||
#define COMET_ARRAY_H
|
|
||||||
|
|
||||||
#include <cstddef>
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <iterator>
|
|
||||||
#include <algorithm>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace comet {
|
|
||||||
|
|
||||||
#pragma pack(push)
|
|
||||||
#pragma pack(1)
|
|
||||||
|
|
||||||
/*!\addtogroup Misc
|
|
||||||
*/
|
|
||||||
//@{
|
|
||||||
|
|
||||||
template<typename T, size_t SZ> class array_t
|
|
||||||
{
|
|
||||||
T a_[SZ];
|
|
||||||
public:
|
|
||||||
typedef T value_type;
|
|
||||||
typedef typename std::vector<T>::iterator iterator;
|
|
||||||
typedef typename std::vector<T>::const_iterator const_iterator;
|
|
||||||
|
|
||||||
typedef typename std::vector<T>::reverse_iterator reverse_iterator;
|
|
||||||
typedef typename std::vector<T>::const_reverse_iterator const_reverse_iterator;
|
|
||||||
|
|
||||||
typedef typename std::vector<T>::size_type size_type;
|
|
||||||
typedef typename std::vector<T>::difference_type difference_type;
|
|
||||||
|
|
||||||
typedef T& reference;
|
|
||||||
typedef const T& const_reference;
|
|
||||||
|
|
||||||
// reference operator[](size_type i) { return a_[i]; }
|
|
||||||
// const_reference operator[](size_type i) const { return a_[i]; }
|
|
||||||
|
|
||||||
iterator begin() { return iterator(a_); }
|
|
||||||
iterator end() { return iterator(a_ + SZ); }
|
|
||||||
const_iterator begin() const { return const_iterator(a_); }
|
|
||||||
const_iterator end() const { return const_iterator(a_ + SZ); }
|
|
||||||
|
|
||||||
reverse_iterator rbegin() { return reverse_iterator(a_); }
|
|
||||||
reverse_iterator rend() { return reverse_iterator(a_ + SZ); }
|
|
||||||
const_reverse_iterator rbegin() const { return const_reverse_iterator(a_); }
|
|
||||||
const_reverse_iterator rend() const { return const_reverse_iterator(a_ + SZ); }
|
|
||||||
|
|
||||||
operator const T*() const { return a_; }
|
|
||||||
operator T*() { return a_; }
|
|
||||||
|
|
||||||
static size_type size() { return SZ; }
|
|
||||||
static bool empty() { return false; }
|
|
||||||
static size_type max_size() { return SZ; }
|
|
||||||
enum { static_size = SZ };
|
|
||||||
|
|
||||||
reference front() { return a_[0]; }
|
|
||||||
const_reference front() const { return a_[0]; }
|
|
||||||
reference back() { return a_[SZ-1]; };
|
|
||||||
const_reference back() const { return a_[SZ-1]; }
|
|
||||||
|
|
||||||
// swap (note: linear complexity)
|
|
||||||
void swap (array_t<T,SZ>& y) {
|
|
||||||
std::swap_ranges(begin(),end(),y.begin());
|
|
||||||
}
|
|
||||||
|
|
||||||
// assignment with type conversion
|
|
||||||
template <typename T2>
|
|
||||||
array_t<T,SZ>& operator= (const array_t<T2,SZ>& rhs) {
|
|
||||||
std::copy(rhs.begin(),rhs.end(), begin());
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// assign one value to all elements
|
|
||||||
void assign (const T& value)
|
|
||||||
{
|
|
||||||
std::fill_n(begin(),size(),value);
|
|
||||||
}
|
|
||||||
|
|
||||||
reference at(size_type i) { rangecheck(i); return a_[i]; }
|
|
||||||
const_reference at(size_type i) const { rangecheck(i); return a_[i]; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
// check range (may be private because it is static)
|
|
||||||
static void rangecheck (size_type i) {
|
|
||||||
if (i >= size()) { throw std::range_error("array"); }
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
//@}
|
|
||||||
#pragma pack(pop)
|
|
||||||
|
|
||||||
// comparisons
|
|
||||||
template<class T, size_t SZ>
|
|
||||||
bool operator== (const array_t<T,SZ>& x, const array_t<T,SZ>& y) {
|
|
||||||
return std::equal(x.begin(), x.end(), y.begin());
|
|
||||||
}
|
|
||||||
template<class T, size_t SZ>
|
|
||||||
bool operator< (const array_t<T,SZ>& x, const array_t<T,SZ>& y) {
|
|
||||||
return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end());
|
|
||||||
}
|
|
||||||
template<class T, size_t SZ>
|
|
||||||
bool operator!= (const array_t<T,SZ>& x, const array_t<T,SZ>& y) {
|
|
||||||
return !(x==y);
|
|
||||||
}
|
|
||||||
template<class T, size_t SZ>
|
|
||||||
bool operator> (const array_t<T,SZ>& x, const array_t<T,SZ>& y) {
|
|
||||||
return y<x;
|
|
||||||
}
|
|
||||||
template<class T, size_t SZ>
|
|
||||||
bool operator<= (const array_t<T,SZ>& x, const array_t<T,SZ>& y) {
|
|
||||||
return !(y<x);
|
|
||||||
}
|
|
||||||
template<class T, size_t SZ>
|
|
||||||
bool operator>= (const array_t<T,SZ>& x, const array_t<T,SZ>& y) {
|
|
||||||
return !(x<y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,68 +0,0 @@
|
||||||
/** \file
|
|
||||||
Provide run-time asserts.
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* Copyright © 2001 Sofus Mortensen
|
|
||||||
*
|
|
||||||
* This material is provided "as is", with absolutely no warranty
|
|
||||||
* expressed or implied. Any use is at your own risk. Permission to
|
|
||||||
* use or copy this software for any purpose is hereby granted without
|
|
||||||
* fee, provided the above notices are retained on all copies.
|
|
||||||
* Permission to modify the code and to distribute modified code is
|
|
||||||
* granted, provided the above notices are retained, and a notice that
|
|
||||||
* the code was modified is included with the above copyright notice.
|
|
||||||
*
|
|
||||||
* This header is part of Comet version 2.
|
|
||||||
* https://github.com/alamaison/comet
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef COMET_ASSERT_H
|
|
||||||
#define COMET_ASSERT_H
|
|
||||||
|
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
# if defined(COMET_ASSERT_THROWS) || defined(COMET_ASSERT_THROWS_ALWAYS)
|
|
||||||
# if defined(COMET_ASSERT_THROWS_ALWAYS) || !defined(NDEBUG)
|
|
||||||
namespace comet
|
|
||||||
{
|
|
||||||
/*! \defgroup ErrorHandling Error handling.
|
|
||||||
*/
|
|
||||||
//@{
|
|
||||||
//! Indicates a comet assertion failed.
|
|
||||||
/** This is enabled for debug builds if COMET_ASSERT_THROWS is defined and
|
|
||||||
* enabled for both debug and release if COMET_ASSERT_THROWS_ALWAYS is defined.
|
|
||||||
*/
|
|
||||||
struct assert_failed : std::runtime_error
|
|
||||||
{
|
|
||||||
assert_failed( const char *val) : runtime_error(val) {}
|
|
||||||
};
|
|
||||||
//@}
|
|
||||||
}
|
|
||||||
# define COMET_ASSERT(x_) if (x_) ; else throw comet::assert_failed("Assert Failed: " #x_ );
|
|
||||||
# define COMET_THROWS_ASSERT throw( comet::assert_failed)
|
|
||||||
# else
|
|
||||||
# define COMET_ASSERT(x_) ;
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# else
|
|
||||||
# define COMET_THROWS_ASSERT throw()
|
|
||||||
# ifndef __CYGWIN__
|
|
||||||
|
|
||||||
# include <crtdbg.h>
|
|
||||||
# define COMET_ASSERT _ASSERTE
|
|
||||||
|
|
||||||
# else
|
|
||||||
|
|
||||||
# include <assert.h>
|
|
||||||
# define COMET_ASSERT assert
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
/*! \addtogroup ErrorHandling
|
|
||||||
*/
|
|
||||||
//@{
|
|
||||||
/** \def COMET_ASSERT Assertion in commet.
|
|
||||||
* \sa COMET_THROWS_ASSERT COMET_ASSERT_THROWS_ALWAYS
|
|
||||||
*/
|
|
||||||
//@}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,121 +0,0 @@
|
||||||
/** \file
|
|
||||||
* ATL Module Compatability wrapper.
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* Copyright © 2000, 2001 Paul Hollingsworth, Michael Geddes
|
|
||||||
* Copyright © 2013 Alexander Lamaison
|
|
||||||
*
|
|
||||||
* This material is provided "as is", with absolutely no warranty
|
|
||||||
* expressed or implied. Any use is at your own risk. Permission to
|
|
||||||
* use or copy this software for any purpose is hereby granted without
|
|
||||||
* fee, provided the above notices are retained on all copies.
|
|
||||||
* Permission to modify the code and to distribute modified code is
|
|
||||||
* granted, provided the above notices are retained, and a notice that
|
|
||||||
* the code was modified is included with the above copyright notice.
|
|
||||||
*
|
|
||||||
* This header is part of Comet version 2.
|
|
||||||
* https://github.com/alamaison/comet
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef COMET_ATL_MODULE_H
|
|
||||||
#define COMET_ATL_MODULE_H
|
|
||||||
|
|
||||||
#include <comet/server.h>
|
|
||||||
|
|
||||||
#include <atlbase.h>
|
|
||||||
|
|
||||||
namespace comet {
|
|
||||||
/*! \defgroup ATL ATL conversion.
|
|
||||||
*/
|
|
||||||
//@{
|
|
||||||
|
|
||||||
/** \struct declspec_comtype atl_module.h comet/atl_module.h
|
|
||||||
* Helper to create a 'comtype' for a non-comet interface.
|
|
||||||
* \code
|
|
||||||
* namespace comet{
|
|
||||||
* template<> struct comtype<IApplicationOption> :
|
|
||||||
* declspec_comtype<IApplicationOption, ::IDispatch >
|
|
||||||
* { };
|
|
||||||
* };
|
|
||||||
* \endcode
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
template<typename ITF, typename BASE = ::IUnknown> struct declspec_comtype
|
|
||||||
{
|
|
||||||
static const uuid_t& uuid() { return uuid_t::create_const_reference(__uuidof(ITF)); }
|
|
||||||
typedef BASE base;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/// Placeholder for an empty comet typelibrary.
|
|
||||||
struct empty_typelib
|
|
||||||
{
|
|
||||||
typedef nil coclasses;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename COM_SERVER, typename ATL_MODULE = ATL::CComModule>
|
|
||||||
class atl_module_ex : public ATL_MODULE
|
|
||||||
{
|
|
||||||
// ATL will take the responsibility of registering the embedded type library.
|
|
||||||
public:
|
|
||||||
HRESULT Init(_ATL_OBJMAP_ENTRY* p, HINSTANCE h, const GUID* plibid = NULL)
|
|
||||||
{
|
|
||||||
module().instance(h);
|
|
||||||
return ATL_MODULE::Init(p, h, plibid);
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT RegisterServer(BOOL bRegTypeLib = FALSE, const CLSID* pCLSID = NULL)
|
|
||||||
{
|
|
||||||
HRESULT hr = ATL_MODULE::RegisterServer(bRegTypeLib, pCLSID);
|
|
||||||
if(SUCCEEDED(hr))
|
|
||||||
hr = COM_SERVER::DllRegisterServer();
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT UnregisterServer(BOOL bUnRegTypeLib, const CLSID* pCLSID = NULL)
|
|
||||||
{
|
|
||||||
COM_SERVER::DllUnregisterServer();
|
|
||||||
return ATL_MODULE::UnregisterServer(bUnRegTypeLib, pCLSID);
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT GetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
|
|
||||||
{
|
|
||||||
HRESULT hr = COM_SERVER::DllGetClassObject( rclsid, riid, ppv);
|
|
||||||
if( hr == CLASS_E_CLASSNOTAVAILABLE )
|
|
||||||
{
|
|
||||||
hr = ATL_MODULE::GetClassObject(rclsid, riid,ppv);
|
|
||||||
}
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
LONG GetLockCount()
|
|
||||||
{
|
|
||||||
return module().rc() + ATL_MODULE::GetLockCount();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Wraps an ATL::CComModule to provide co-existing ATL/Comet co-classes.
|
|
||||||
* ATL will take responsibility for registering the embedded type-library.
|
|
||||||
*
|
|
||||||
* Here is an example of how to use it:
|
|
||||||
* \code
|
|
||||||
* struct typelib_subset
|
|
||||||
* {
|
|
||||||
* typedef COMET_STRICT_TYPENAME comet::typelist::make_list< CoClass1, CoClass2 > coclasses;
|
|
||||||
* };
|
|
||||||
* comet::atl_module<typelib_subset> _Module;
|
|
||||||
* \endcode
|
|
||||||
* And in std.h:
|
|
||||||
* \code
|
|
||||||
* struct typelib_subset;
|
|
||||||
* extern comet::atl_module<typelib_subset> _Module;
|
|
||||||
* \endcode
|
|
||||||
*/
|
|
||||||
template<typename TYPELIB = empty_typelib, typename ATL_MODULE = ATL::CComModule>
|
|
||||||
class atl_module : public atl_module_ex< com_server<TYPELIB, com_server_traits<NO_EMBEDDED_TLB> >, ATL_MODULE >
|
|
||||||
{
|
|
||||||
};
|
|
||||||
//@}
|
|
||||||
} // namespace comet
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,99 +0,0 @@
|
||||||
/** \file
|
|
||||||
* Simple uncopyable buffer class.
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* Copyright © 2004, Michael Geddes, Lijun Qin.
|
|
||||||
*
|
|
||||||
* This material is provided "as is", with absolutely no warranty
|
|
||||||
* expressed or implied. Any use is at your own risk. Permission to
|
|
||||||
* use or copy this software for any purpose is hereby granted without
|
|
||||||
* fee, provided the above notices are retained on all copies.
|
|
||||||
* Permission to modify the code and to distribute modified code is
|
|
||||||
* granted, provided the above notices are retained, and a notice that
|
|
||||||
* the code was modified is included with the above copyright notice.
|
|
||||||
*
|
|
||||||
* This header is part of Comet version 2.
|
|
||||||
* https://github.com/alamaison/comet
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef INCLUDE_COMET_AUTO_BUFFER_H
|
|
||||||
#define INCLUDE_COMET_AUTO_BUFFER_H
|
|
||||||
|
|
||||||
#ifdef _SHOW_INC
|
|
||||||
#pragma message(" #Include " __FILE__)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace comet
|
|
||||||
{
|
|
||||||
/*!\addtogroup Misc
|
|
||||||
*/
|
|
||||||
//@{
|
|
||||||
|
|
||||||
/** \class auto_buffer_t auto_buffer.h comet/auto_buffer.h
|
|
||||||
* Simle auto-deleting buffer class.
|
|
||||||
* Non-copyable /returnable.
|
|
||||||
*/
|
|
||||||
template <typename T>
|
|
||||||
class auto_buffer_t
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef size_t size_type;
|
|
||||||
/** Create a buffer of the given size.
|
|
||||||
* This is the only valid constructor.
|
|
||||||
*/
|
|
||||||
explicit auto_buffer_t(size_type size)
|
|
||||||
{
|
|
||||||
begin_ = new T[size];
|
|
||||||
}
|
|
||||||
/// Auto-delete the buffer.
|
|
||||||
~auto_buffer_t() throw() { delete[] begin_; }
|
|
||||||
|
|
||||||
/// Clear the buffer.
|
|
||||||
void clear() throw()
|
|
||||||
{
|
|
||||||
delete[] begin_;
|
|
||||||
begin_ = 0;
|
|
||||||
}
|
|
||||||
/// Is the buffer empty.
|
|
||||||
bool empty() const throw()
|
|
||||||
{
|
|
||||||
return begin_ != NULL;
|
|
||||||
}
|
|
||||||
/// Resize the buffer.
|
|
||||||
void resize( size_type newSize) throw()
|
|
||||||
{
|
|
||||||
delete[] begin_;
|
|
||||||
begin_ = new T[newSize];
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return a reference to the specifed element.
|
|
||||||
T & at( size_type t) throw() { return begin_[t]; }
|
|
||||||
T & operator[]( size_type t) throw() { return begin_[t]; }
|
|
||||||
/// Return a const reference to the specifed element.
|
|
||||||
const T & at( size_type t) const throw() { return begin_[t]; }
|
|
||||||
const T & operator[]( size_type t) const throw() { return begin_[t]; }
|
|
||||||
|
|
||||||
/// Detatch the memory.
|
|
||||||
T *detach()
|
|
||||||
{
|
|
||||||
T *val = begin_;
|
|
||||||
begin_ = NULL;
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
/// Return the memory.
|
|
||||||
T *get() { return begin_; }
|
|
||||||
const T *get()const { return begin_; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
/// Can't assign.
|
|
||||||
auto_buffer_t &operator=(const auto_buffer_t &);
|
|
||||||
/// can't copy.
|
|
||||||
auto_buffer_t(const auto_buffer_t&);
|
|
||||||
|
|
||||||
/// Pointer to memory.
|
|
||||||
T *begin_;
|
|
||||||
};
|
|
||||||
//@}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* INCLUDE_COMET_AUTO_BUFFER_H */
|
|
|
@ -1,948 +0,0 @@
|
||||||
/** \file
|
|
||||||
* BSTR wrapper classes.
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* Copyright © 2000-2004 Sofus Mortensen, Michael Geddes
|
|
||||||
* Copyright © 2012 Alexander Lamaison
|
|
||||||
*
|
|
||||||
* This material is provided "as is", with absolutely no warranty
|
|
||||||
* expressed or implied. Any use is at your own risk. Permission to
|
|
||||||
* use or copy this software for any purpose is hereby granted without
|
|
||||||
* fee, provided the above notices are retained on all copies.
|
|
||||||
* Permission to modify the code and to distribute modified code is
|
|
||||||
* granted, provided the above notices are retained, and a notice that
|
|
||||||
* the code was modified is included with the above copyright notice.
|
|
||||||
*
|
|
||||||
* This header is part of Comet version 2.
|
|
||||||
* https://github.com/alamaison/comet
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef COMET_BSTR_H
|
|
||||||
#define COMET_BSTR_H
|
|
||||||
|
|
||||||
#include <comet/config.h>
|
|
||||||
|
|
||||||
#ifdef COMET_BROKEN_WTYPES
|
|
||||||
#include <windows.h>
|
|
||||||
#endif // COMET_BROKEN_WTYPES
|
|
||||||
#include <wtypes.h>
|
|
||||||
#include <malloc.h>
|
|
||||||
#include <stdexcept>
|
|
||||||
#ifndef COMET_GCC_HEADERS
|
|
||||||
#include <oleauto.h>
|
|
||||||
#endif // COMET_GCC_HEADERS
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <functional>
|
|
||||||
#undef max
|
|
||||||
#include <limits>
|
|
||||||
|
|
||||||
#include <comet/assert.h>
|
|
||||||
#include <comet/common.h>
|
|
||||||
#include <comet/static_assert.h>
|
|
||||||
#include <comet/error_fwd.h>
|
|
||||||
#include <comet/uuid_fwd.h>
|
|
||||||
#include <comet/currency.h>
|
|
||||||
#include <comet/type_traits.h>
|
|
||||||
|
|
||||||
#pragma warning(push)
|
|
||||||
#pragma warning(disable : 4522 4521)
|
|
||||||
|
|
||||||
#pragma comment( lib, "oleaut32" )
|
|
||||||
|
|
||||||
namespace comet {
|
|
||||||
|
|
||||||
#ifndef NORM_IGNOREKASHIDA
|
|
||||||
#define NORM_IGNOREKASHIDA 0x00040000
|
|
||||||
#endif // NORM_IGNOREKASHIDA
|
|
||||||
/*! \addtogroup COMType
|
|
||||||
*/
|
|
||||||
//@{
|
|
||||||
//! Comparsion flags.
|
|
||||||
/*! Can be used with \link comet::bstr_t::cmp cmp \endlink or the comparsion functors.
|
|
||||||
\sa cmp
|
|
||||||
less
|
|
||||||
less_equal
|
|
||||||
greater
|
|
||||||
greater_equal
|
|
||||||
equal_to
|
|
||||||
not_equal_to
|
|
||||||
*/
|
|
||||||
|
|
||||||
enum compare_flags_t
|
|
||||||
{
|
|
||||||
cf_ignore_case = NORM_IGNORECASE, //!< Ignore case.
|
|
||||||
cf_ingore_nonspace = NORM_IGNORENONSPACE, //!< Ignore nonspacing chars.
|
|
||||||
cf_ignore_symbols = NORM_IGNORESYMBOLS, //!< Ignore symbols.
|
|
||||||
cf_ignore_width = NORM_IGNOREWIDTH, //!< Ignore string width.
|
|
||||||
cf_ignore_kanatype = NORM_IGNOREKANATYPE, //!< Ignore Kana type.
|
|
||||||
cf_ignore_kashida = NORM_IGNOREKASHIDA //!< Ignore Arabic kashida characters.
|
|
||||||
};
|
|
||||||
//@}
|
|
||||||
|
|
||||||
namespace impl {
|
|
||||||
|
|
||||||
inline const wchar_t* null_to_empty(const wchar_t* s)
|
|
||||||
{ return s ? s : L""; }
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
|
|
||||||
/*! \addtogroup COMType
|
|
||||||
*/
|
|
||||||
//@{
|
|
||||||
|
|
||||||
/*! \class bstr_t bstr.h comet/bstr.h
|
|
||||||
* BSTR Wrapper.
|
|
||||||
* \sa bstr_t
|
|
||||||
*/
|
|
||||||
class bstr_t {
|
|
||||||
public:
|
|
||||||
typedef wchar_t value_type;
|
|
||||||
#if !(defined(_STLP_DEBUG) || (defined(_HAS_ITERATOR_DEBUGGING)) && _MSC_VER >= 1400)
|
|
||||||
typedef std::wstring::iterator iterator;
|
|
||||||
typedef std::wstring::const_iterator const_iterator;
|
|
||||||
|
|
||||||
typedef std::wstring::reverse_iterator reverse_iterator;
|
|
||||||
typedef std::wstring::const_reverse_iterator const_reverse_iterator;
|
|
||||||
#else // _STLP_DEBUG
|
|
||||||
typedef wchar_t *iterator;
|
|
||||||
typedef const wchar_t *const_iterator;
|
|
||||||
#if defined(COMET_STD_ITERATOR)
|
|
||||||
typedef std::reverse_iterator<iterator> reverse_iterator;
|
|
||||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
|
||||||
#else
|
|
||||||
// workaround for broken reverse_iterator implementations due to no partial specialisation
|
|
||||||
typedef std::reverse_iterator<iterator,wchar_t> reverse_iterator;
|
|
||||||
typedef std::reverse_iterator<const_iterator,wchar_t> const_reverse_iterator;
|
|
||||||
#endif
|
|
||||||
#endif // _STLP_DEBUG
|
|
||||||
|
|
||||||
typedef std::wstring::size_type size_type;
|
|
||||||
typedef std::wstring::difference_type difference_type;
|
|
||||||
|
|
||||||
typedef wchar_t& reference;
|
|
||||||
typedef const wchar_t const_reference;
|
|
||||||
|
|
||||||
private:
|
|
||||||
BSTR str_;
|
|
||||||
|
|
||||||
void construct() { str_ = 0; }
|
|
||||||
void construct(BSTR s, bool copy) throw(std::bad_alloc)
|
|
||||||
{ if (copy) str_ = copy_str(s); else str_ = s; }
|
|
||||||
|
|
||||||
void construct(const wchar_t* s) throw(std::bad_alloc)
|
|
||||||
{ str_ = copy_str(s); }
|
|
||||||
|
|
||||||
void construct(const wchar_t* s, size_t len) throw(std::bad_alloc)
|
|
||||||
{ str_ = copy_str(s, len); }
|
|
||||||
|
|
||||||
void construct(const char* s) throw(std::bad_alloc, std::runtime_error) {
|
|
||||||
convert_str(s, -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void construct(const char* s, size_t len)
|
|
||||||
{
|
|
||||||
if (len >= static_cast<size_t>(std::numeric_limits<int>::max()))
|
|
||||||
throw std::length_error(
|
|
||||||
"String exceeded maximum length for conversion");
|
|
||||||
|
|
||||||
convert_str(s, static_cast<int>(len+1));
|
|
||||||
}
|
|
||||||
|
|
||||||
void construct(const uuid_t& u, bool braces)
|
|
||||||
{
|
|
||||||
str_ = impl::bad_alloc_check(::SysAllocStringLen(0, braces?38:36));
|
|
||||||
u.copy_to_str(str_+(braces?1:0));
|
|
||||||
if (braces)
|
|
||||||
{
|
|
||||||
str_[0]=L'{';
|
|
||||||
str_[37]=L'}';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void construct(const wchar_t* s1, size_t l1, const wchar_t* s2, size_t l2) throw(std::bad_alloc)
|
|
||||||
{
|
|
||||||
str_ = impl::bad_alloc_check(::SysAllocStringLen(NULL, UINT(l1+l2)));
|
|
||||||
if (l1) memcpy(str_, s1, sizeof(wchar_t)*(l1));
|
|
||||||
if (l2) memcpy(str_+l1, s2, sizeof(wchar_t)*(1+l2));
|
|
||||||
}
|
|
||||||
|
|
||||||
void destroy() throw()
|
|
||||||
{ if (str_) ::SysFreeString(str_); }
|
|
||||||
|
|
||||||
bool is_regular() const throw()
|
|
||||||
{ return !str_ || length() == wcslen(str_); }
|
|
||||||
|
|
||||||
static BSTR copy_str(const wchar_t* src) throw(std::bad_alloc)
|
|
||||||
{ return src ? impl::bad_alloc_check(::SysAllocString(src)) : 0; }
|
|
||||||
|
|
||||||
static BSTR copy_str(const wchar_t* src, size_t len) throw(std::bad_alloc)
|
|
||||||
{ return src ? impl::bad_alloc_check(::SysAllocStringLen(src, UINT(len))) : 0; }
|
|
||||||
|
|
||||||
static BSTR copy_str(BSTR src) throw(std::bad_alloc)
|
|
||||||
{ return src ? impl::bad_alloc_check(::SysAllocStringLen(src, ::SysStringLen(src))) : 0; }
|
|
||||||
|
|
||||||
void convert_str(const char* s, int l) throw(std::bad_alloc, std::runtime_error)
|
|
||||||
{
|
|
||||||
if (s != 0) {
|
|
||||||
#if defined(_MBCS) || !defined(COMET_NO_MBCS)
|
|
||||||
int wl = ::MultiByteToWideChar(CP_ACP, 0, s, l, NULL,0);
|
|
||||||
#else
|
|
||||||
int wl = ((l>=0)?l: (1+strlen(s)));
|
|
||||||
COMET_ASSERT( wl == ::MultiByteToWideChar( CP_ACP, 0, s, l, NULL,0));
|
|
||||||
#endif
|
|
||||||
str_ = impl::bad_alloc_check(::SysAllocStringLen(0, wl - 1));
|
|
||||||
if (::MultiByteToWideChar(CP_ACP, 0, s, l, str_, wl) == 0)
|
|
||||||
{
|
|
||||||
destroy();
|
|
||||||
throw std::runtime_error("MultiByteToWideChar has failed");
|
|
||||||
}
|
|
||||||
} else str_ = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
/*! Default constructor
|
|
||||||
Constructs a null string.
|
|
||||||
*/
|
|
||||||
bstr_t() throw()
|
|
||||||
{
|
|
||||||
construct();
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Copy constructor
|
|
||||||
/*!
|
|
||||||
\param s
|
|
||||||
String initialise bstr_t from.
|
|
||||||
|
|
||||||
\exception std::bad_alloc
|
|
||||||
On memory exhaustion std::bad_alloc is thrown.
|
|
||||||
*/
|
|
||||||
bstr_t(const bstr_t& s) throw(std::bad_alloc)
|
|
||||||
{
|
|
||||||
construct(s.str_, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Construct string from const wchar_t*
|
|
||||||
/*!
|
|
||||||
\param s
|
|
||||||
String to initialise bstr_t from.
|
|
||||||
|
|
||||||
\exception std::bad_alloc
|
|
||||||
On memory exhaustion std::bad_alloc is thrown.
|
|
||||||
*/
|
|
||||||
bstr_t(const wchar_t* s) throw(std::bad_alloc)
|
|
||||||
{
|
|
||||||
construct(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
bstr_t(const wchar_t* s, size_t len) throw(std::bad_alloc)
|
|
||||||
{
|
|
||||||
construct(s, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Construct string from const char*
|
|
||||||
/*!
|
|
||||||
\param s
|
|
||||||
String to initialise bstr_t from.
|
|
||||||
|
|
||||||
\exception std::bad_alloc
|
|
||||||
On memory exhaustion std::bad_alloc is thrown.
|
|
||||||
\exception std::runtime_error
|
|
||||||
Should string conversion fail, std::runtime_error will be thrown.
|
|
||||||
*/
|
|
||||||
bstr_t(const char* s) throw(std::runtime_error)
|
|
||||||
{
|
|
||||||
construct(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
bstr_t(const char* s, size_t len) throw(std::bad_alloc)
|
|
||||||
{
|
|
||||||
construct(s, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Construct string from const std::string&
|
|
||||||
/*!
|
|
||||||
\param s
|
|
||||||
String to initialise bstr_t from.
|
|
||||||
|
|
||||||
\exception std::bad_alloc
|
|
||||||
On memory exhaustion std::bad_alloc is thrown.
|
|
||||||
\exception std::length_error
|
|
||||||
If this given string is too long to be converted,
|
|
||||||
std::length_error is thrown.
|
|
||||||
\exception std::runtime_error
|
|
||||||
Should string conversion fail, std::runtime_error is thrown.
|
|
||||||
*/
|
|
||||||
bstr_t(const std::string& s)
|
|
||||||
{
|
|
||||||
construct(s.c_str(), s.length());
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Construct string from BSTR
|
|
||||||
/*!
|
|
||||||
Takes ownership of specified BSTR. To prevent misuse the BSTR must be wrapped using auto_attach.
|
|
||||||
|
|
||||||
\code
|
|
||||||
bstr_t bs( auto_attach( myBSTR ) );
|
|
||||||
\endcode
|
|
||||||
|
|
||||||
\param s
|
|
||||||
String to initialise bstr_t from.
|
|
||||||
*/
|
|
||||||
bstr_t(const impl::auto_attach_t<BSTR>& s) throw()
|
|
||||||
{
|
|
||||||
construct(s.get(), false);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//! Construct string from const std::wstring&
|
|
||||||
/*!
|
|
||||||
\param s
|
|
||||||
String to initialise bstr_t from.
|
|
||||||
|
|
||||||
\exception std::bad_alloc
|
|
||||||
On memory exhaustion std::bad_alloc is thrown.
|
|
||||||
*/
|
|
||||||
bstr_t(const std::wstring& s) throw(std::bad_alloc)
|
|
||||||
{
|
|
||||||
construct(s.c_str(), s.length());
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit bstr_t(size_type sz, wchar_t c) throw(std::bad_alloc)
|
|
||||||
{
|
|
||||||
str_ = impl::bad_alloc_check(::SysAllocStringLen(0, UINT(sz)));
|
|
||||||
std::fill(begin(), end(), c);
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit bstr_t(size_type sz) throw(std::bad_alloc)
|
|
||||||
{
|
|
||||||
str_ = impl::bad_alloc_check(::SysAllocStringLen(0, UINT(sz)));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename IT>
|
|
||||||
explicit bstr_t(IT first, IT last)
|
|
||||||
{
|
|
||||||
str_ = 0;
|
|
||||||
assign(first, last);
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit bstr_t(const uuid_t& u, bool braces = false)
|
|
||||||
{
|
|
||||||
construct(u, braces);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
bstr_t(const wchar_t* s1, size_t l1, const wchar_t* s2, size_t l2) throw(std::bad_alloc)
|
|
||||||
{
|
|
||||||
construct(s1, l1, s2, l2);
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
//! Destructor
|
|
||||||
/*!
|
|
||||||
Deletes the wrapped BSTR.
|
|
||||||
*/
|
|
||||||
~bstr_t() throw()
|
|
||||||
{
|
|
||||||
destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Swap
|
|
||||||
void swap(bstr_t& x) throw()
|
|
||||||
{
|
|
||||||
std::swap(str_, x.str_);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Explicit conversion to const wchar_t*
|
|
||||||
const wchar_t* c_str() const throw()
|
|
||||||
{ return impl::null_to_empty(str_); }
|
|
||||||
|
|
||||||
//! Explicit conversion to std::wstring
|
|
||||||
std::wstring w_str() const throw()
|
|
||||||
{ return impl::null_to_empty(str_); }
|
|
||||||
|
|
||||||
#ifdef _MBCS
|
|
||||||
#ifndef COMET_NO_MBCS_WARNING
|
|
||||||
#pragma message( "Warning: _MBCS is defined. bstr_t::s_str may return an std::string containing multibyte characters" )
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//! Explicit conversion to std::string
|
|
||||||
std::string s_str() const
|
|
||||||
{
|
|
||||||
if (is_empty()) return std::string();
|
|
||||||
|
|
||||||
if (length() > static_cast<size_t>(std::numeric_limits<int>::max()))
|
|
||||||
throw std::length_error("String is too large to be converted");
|
|
||||||
|
|
||||||
int ol = static_cast<int>(length());
|
|
||||||
|
|
||||||
#if defined(_MBCS) || !defined(COMET_NO_MBCS)
|
|
||||||
// Calculate the required length of the buffer
|
|
||||||
int l = WideCharToMultiByte(CP_ACP, 0, str_, ol, NULL, 0, NULL, NULL);
|
|
||||||
#else // _MBCS
|
|
||||||
int l = ol;
|
|
||||||
COMET_ASSERT( l == WideCharToMultiByte(CP_ACP, 0, str_, ol, NULL, 0, NULL, NULL));
|
|
||||||
#endif // _MBCS
|
|
||||||
|
|
||||||
// Create the buffer
|
|
||||||
std::string rv(l, std::string::value_type());
|
|
||||||
// Do the conversion.
|
|
||||||
if (0 == WideCharToMultiByte(
|
|
||||||
CP_ACP, 0, str_, ol, &rv[0], l, NULL, NULL))
|
|
||||||
{
|
|
||||||
DWORD err = GetLastError();
|
|
||||||
raise_exception(HRESULT_FROM_WIN32(err));
|
|
||||||
}
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Explicit conversion to "tstring".
|
|
||||||
#ifdef _UNICODE
|
|
||||||
std::wstring t_str() const
|
|
||||||
{
|
|
||||||
return w_str();
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
std::string t_str() const
|
|
||||||
{
|
|
||||||
return s_str();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//! Implicit conversion to std::wstring
|
|
||||||
operator std::wstring() const { return w_str(); }
|
|
||||||
|
|
||||||
//! Implicit conversion to std::string
|
|
||||||
operator std::string() const { return s_str(); }
|
|
||||||
|
|
||||||
//! Returns true if and only if wrapped str is null
|
|
||||||
bool is_null() const throw()
|
|
||||||
{ return str_ == 0; }
|
|
||||||
|
|
||||||
/** Returns true if and only if wrapped str has zero length.
|
|
||||||
*/
|
|
||||||
bool is_empty() const throw() { return length() == 0; }
|
|
||||||
|
|
||||||
//! Returns true if and only if wrapped str has zero length.
|
|
||||||
bool empty() const throw() { return length() == 0; }
|
|
||||||
|
|
||||||
//! Returns length of wrapped string.
|
|
||||||
size_t length() const throw()
|
|
||||||
{ return is_null() ? 0 : ::SysStringLen(str_); }
|
|
||||||
|
|
||||||
size_t size() const throw()
|
|
||||||
{ return length(); }
|
|
||||||
|
|
||||||
/*! \internal */
|
|
||||||
BSTR get_raw() const
|
|
||||||
{ return str_; }
|
|
||||||
|
|
||||||
friend
|
|
||||||
std::basic_ostream<char> &operator<<(std::basic_ostream<char> &os, const bstr_t &val)
|
|
||||||
{ os << val.s_str(); return os; }
|
|
||||||
|
|
||||||
friend
|
|
||||||
std::basic_ostream<wchar_t> &operator<<(std::basic_ostream<wchar_t> &os, const bstr_t &val)
|
|
||||||
{ os << val.w_str(); return os; }
|
|
||||||
|
|
||||||
/// \name Boolean operators
|
|
||||||
//@{
|
|
||||||
|
|
||||||
bool operator==(const wchar_t* s) const
|
|
||||||
{ return 0 == wcscmp(c_str(), impl::null_to_empty(s) ) && is_regular(); }
|
|
||||||
|
|
||||||
bool operator!=(const wchar_t* s) const
|
|
||||||
{ return !operator==(s); }
|
|
||||||
|
|
||||||
bool operator<(const wchar_t* s) const
|
|
||||||
{ return wcscmp(c_str(), impl::null_to_empty(s)) < 0 && is_regular(); }
|
|
||||||
|
|
||||||
bool operator>(const wchar_t* s) const
|
|
||||||
{ return wcscmp(c_str(), impl::null_to_empty(s)) > 0 && !is_regular(); }
|
|
||||||
|
|
||||||
bool operator>=(const wchar_t* s) const
|
|
||||||
{ return !operator<(s); }
|
|
||||||
|
|
||||||
bool operator<=(const wchar_t* s) const
|
|
||||||
{ return !operator>(s); }
|
|
||||||
|
|
||||||
bool operator==(const std::wstring& s) const
|
|
||||||
{
|
|
||||||
size_t l = length();
|
|
||||||
if (l != s.length()) return false;
|
|
||||||
return 0 == memcmp(str_, s.c_str(), sizeof(wchar_t)*l);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator!=(const std::wstring& s) const
|
|
||||||
{ return !operator==(s); }
|
|
||||||
|
|
||||||
bool operator<(const std::wstring& s) const
|
|
||||||
{ return std::lexicographical_compare(str_, str_+length(), s.begin(), s.end()); }
|
|
||||||
|
|
||||||
bool operator>(const std::wstring& s) const
|
|
||||||
{ return std::lexicographical_compare(str_, str_+length(), s.begin(), s.end(), std::greater<wchar_t>()); }
|
|
||||||
|
|
||||||
bool operator>=(const std::wstring& s) const
|
|
||||||
{ return !operator<(s); }
|
|
||||||
|
|
||||||
bool operator<=(const std::wstring& s) const
|
|
||||||
{ return !operator>(s); }
|
|
||||||
|
|
||||||
bool operator==(const bstr_t& s) const
|
|
||||||
{
|
|
||||||
if (str_ == 0 && s.str_ == 0) return true;
|
|
||||||
return ::VarBstrCmp(str_, s.str_, ::GetThreadLocale(), 0) == VARCMP_EQ;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator!=(const bstr_t& s) const
|
|
||||||
{ return !operator==(s); }
|
|
||||||
|
|
||||||
bool operator<(const bstr_t& s) const
|
|
||||||
{
|
|
||||||
if (str_ == 0) {
|
|
||||||
return s.str_ != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s.str_ == 0) return false;
|
|
||||||
|
|
||||||
return ::VarBstrCmp(str_, s.str_, ::GetThreadLocale(), 0) == VARCMP_LT;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator>(const bstr_t& s) const
|
|
||||||
{
|
|
||||||
if (str_ == 0) {
|
|
||||||
return s.str_ != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s.str_ == 0) return false;
|
|
||||||
|
|
||||||
return ::VarBstrCmp(str_, s.str_, ::GetThreadLocale(), 0) == VARCMP_GT;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator>=(const bstr_t& s) const
|
|
||||||
{ return !operator<(s); }
|
|
||||||
|
|
||||||
bool operator<=(const bstr_t& s) const
|
|
||||||
{ return !operator>(s); }
|
|
||||||
//@}
|
|
||||||
|
|
||||||
//! String comparsion function.
|
|
||||||
/*! \param s String to compare
|
|
||||||
\param flags Comparison Flags
|
|
||||||
\retval <0 if less
|
|
||||||
\retval 0 if Equal
|
|
||||||
\retval >0 if greater
|
|
||||||
*/
|
|
||||||
int cmp(const bstr_t& s, compare_flags_t flags = compare_flags_t(0)) const
|
|
||||||
{
|
|
||||||
HRESULT res = ::VarBstrCmp(str_, s.str_, ::GetThreadLocale(), flags);
|
|
||||||
switch(res)
|
|
||||||
{
|
|
||||||
case VARCMP_EQ: return 0;
|
|
||||||
case VARCMP_GT: return 1;
|
|
||||||
case VARCMP_LT: return -1;
|
|
||||||
case VARCMP_NULL:
|
|
||||||
return ((str_==0)?0:1) - ((s.str_==0)?0:1);
|
|
||||||
}
|
|
||||||
if (str_==0 || s.str_ ==0)
|
|
||||||
return ((str_==0)?0:1) - ((s.str_==0)?0:1);
|
|
||||||
raise_exception(res); return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//!\name Comparison Functors
|
|
||||||
//@{
|
|
||||||
//! Less Functor.
|
|
||||||
/*! Useful for STL containers.
|
|
||||||
\code
|
|
||||||
typedef stl::map < comet::bstr_t, long, bstr_t::less<cf_ignore_case> > string_long_map;
|
|
||||||
\endcode
|
|
||||||
\param CF comparison flags.
|
|
||||||
\relates bstr_t
|
|
||||||
*/
|
|
||||||
template<compare_flags_t CF>
|
|
||||||
struct less : std::binary_function< bstr_t,bstr_t,bool>{
|
|
||||||
/// Functor.
|
|
||||||
bool operator()(const bstr_t& l, const bstr_t& r) const
|
|
||||||
{ return l.cmp(r, CF) <0; }
|
|
||||||
};
|
|
||||||
|
|
||||||
//! less or equal functor.
|
|
||||||
/*! \relates bstr_t */
|
|
||||||
template<compare_flags_t CF>
|
|
||||||
struct less_equal : std::binary_function< bstr_t,bstr_t,bool> {
|
|
||||||
/// Functor.
|
|
||||||
bool operator()(const bstr_t& l, const bstr_t& r) const
|
|
||||||
{ return l.cmp(r, CF) <=0; }
|
|
||||||
};
|
|
||||||
|
|
||||||
//! greater functor.
|
|
||||||
/*! \relates bstr_t */
|
|
||||||
template<compare_flags_t CF>
|
|
||||||
struct greater : std::binary_function< bstr_t,bstr_t,bool> {
|
|
||||||
/// Functor.
|
|
||||||
bool operator()(const bstr_t& l, const bstr_t& r) const
|
|
||||||
{ return l.cmp(r, CF) > 0; }
|
|
||||||
};
|
|
||||||
|
|
||||||
//! greater or equal functor.
|
|
||||||
/*! \relates bstr_t */
|
|
||||||
template<compare_flags_t CF>
|
|
||||||
struct greater_equal : std::binary_function< bstr_t,bstr_t,bool> {
|
|
||||||
/// Functor.
|
|
||||||
bool operator()(const bstr_t& l, const bstr_t& r) const
|
|
||||||
{ return l.cmp(r, CF) >=0; }
|
|
||||||
};
|
|
||||||
|
|
||||||
//! equality functor.
|
|
||||||
template<compare_flags_t CF>
|
|
||||||
struct equal_to : std::binary_function< bstr_t,bstr_t,bool> {
|
|
||||||
bool operator()(const bstr_t& l, const bstr_t& r) const
|
|
||||||
{ return l.cmp(r, CF) == 0; }
|
|
||||||
};
|
|
||||||
|
|
||||||
//! Inequality functor.
|
|
||||||
/*! \relates bstr_t */
|
|
||||||
template<compare_flags_t CF>
|
|
||||||
struct not_equal_to : std::binary_function< bstr_t,bstr_t,bool>{
|
|
||||||
/// Functor.
|
|
||||||
bool operator()(const bstr_t& l, const bstr_t& r) const
|
|
||||||
{ return l.cmp(r, CF) != 0; }
|
|
||||||
};
|
|
||||||
//@}
|
|
||||||
|
|
||||||
iterator begin() { return iterator(str_); }
|
|
||||||
iterator end() { return iterator(str_ + length()); }
|
|
||||||
const_iterator begin() const { return const_iterator(str_); }
|
|
||||||
const_iterator end() const { return const_iterator(str_ + length()); }
|
|
||||||
|
|
||||||
reverse_iterator rbegin() { return reverse_iterator(str_); }
|
|
||||||
reverse_iterator rend() { return reverse_iterator(str_ + length()); }
|
|
||||||
const_reverse_iterator rbegin() const { return const_reverse_iterator(str_); }
|
|
||||||
const_reverse_iterator rend() const { return const_reverse_iterator(str_ + length()); }
|
|
||||||
|
|
||||||
reference at(size_type i) { rangecheck(i); return str_[i]; }
|
|
||||||
const_reference at(size_type i) const { rangecheck(i); return str_[i]; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
// check range (may be private because it is static)
|
|
||||||
void rangecheck (size_type i) const {
|
|
||||||
if (i >= length()) { throw std::range_error("bstr_t"); }
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
const_reference operator[](size_type idx) const
|
|
||||||
{ return str_[idx]; }
|
|
||||||
|
|
||||||
reference operator[](size_type idx)
|
|
||||||
{ return str_[idx]; }
|
|
||||||
|
|
||||||
//! Assign string to be \p sz of character \p c .
|
|
||||||
void assign(size_type sz, wchar_t c) throw(std::bad_alloc)
|
|
||||||
{
|
|
||||||
bstr_t t(sz, c);
|
|
||||||
swap(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Assign string from two iterators.
|
|
||||||
template<typename IT>
|
|
||||||
void assign(IT first, IT last)
|
|
||||||
{
|
|
||||||
bstr_t t( std::distance(first, last) );
|
|
||||||
|
|
||||||
#pragma warning(push)
|
|
||||||
#pragma warning(disable:4996)
|
|
||||||
std::copy(first, last, t.begin());
|
|
||||||
#pragma warning(pop)
|
|
||||||
|
|
||||||
swap(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//! Assignment operator from any (non integer) constructable.
|
|
||||||
template<typename T>
|
|
||||||
bstr_t& operator=(const T& x)
|
|
||||||
{
|
|
||||||
COMET_STATIC_ASSERT( type_traits::is_integer<T>::result == false );
|
|
||||||
bstr_t t(x);
|
|
||||||
swap(t);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Default assignment.
|
|
||||||
bstr_t& operator=(const bstr_t& x) throw(std::bad_alloc)
|
|
||||||
{
|
|
||||||
bstr_t t(x);
|
|
||||||
swap(t);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Concat operation
|
|
||||||
bstr_t operator+(const bstr_t& s) const throw(std::bad_alloc)
|
|
||||||
{
|
|
||||||
return bstr_t(str_, length(), s.str_, s.length());
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Concat with const wchar_t*
|
|
||||||
bstr_t operator+(const wchar_t* s) const throw(std::bad_alloc)
|
|
||||||
{
|
|
||||||
return bstr_t(str_, length(), s, wcslen(s));
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Concat with std::wstring
|
|
||||||
bstr_t operator+(const std::wstring& s) const throw(std::bad_alloc)
|
|
||||||
{
|
|
||||||
return bstr_t(str_, length(), s.c_str(), s.length());
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Concat assignment
|
|
||||||
bstr_t& operator+=(const bstr_t& s) throw(std::bad_alloc)
|
|
||||||
{
|
|
||||||
bstr_t t(str_, length(), s.str_, s.length());
|
|
||||||
swap(t);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Concat assignment with const wchar_t*
|
|
||||||
bstr_t& operator+=(const wchar_t* s) throw(std::bad_alloc)
|
|
||||||
{
|
|
||||||
bstr_t t(str_, length(), s, wcslen(s));
|
|
||||||
swap(t);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Concat assignment with std::wstring
|
|
||||||
bstr_t& operator+=(const std::wstring& s) throw(std::bad_alloc)
|
|
||||||
{
|
|
||||||
bstr_t t(str_, length(), s.c_str(), s.length());
|
|
||||||
swap(t);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Detach a raw BSTR from it's wrapper - detach function is dangerous.
|
|
||||||
BSTR detach()
|
|
||||||
{
|
|
||||||
BSTR s(str_);
|
|
||||||
str_ = 0;
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
//!\name Create a reference to a BSTR
|
|
||||||
/*!
|
|
||||||
Creates a bstr_t that is a reference to the BSTR.
|
|
||||||
It will not be reference counted and will not be deleted when the bstr_t goes out of scope.
|
|
||||||
|
|
||||||
This is used by the interface wrappers for [in] BSTR's. Typically clients do not need create_reference.
|
|
||||||
*/
|
|
||||||
//@{
|
|
||||||
static const bstr_t& create_const_reference(const BSTR& s) throw()
|
|
||||||
{ return *reinterpret_cast<const bstr_t*>(&s); }
|
|
||||||
|
|
||||||
static bstr_t& create_reference(BSTR& s) throw()
|
|
||||||
{ return *reinterpret_cast<bstr_t*>(&s); }
|
|
||||||
//@}
|
|
||||||
|
|
||||||
//! Detaches specified bstr
|
|
||||||
static BSTR detach(bstr_t& s)
|
|
||||||
{
|
|
||||||
return s.detach();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! \internal */
|
|
||||||
template<typename T>
|
|
||||||
static BSTR detach(const T& s)
|
|
||||||
{
|
|
||||||
return bstr_t(s).detach();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! \internal */
|
|
||||||
BSTR* get_ptr_to_raw() const
|
|
||||||
{
|
|
||||||
return const_cast<BSTR*>(&str_);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! [in] adapter.
|
|
||||||
/*!
|
|
||||||
Used when calling raw interfaces that require an [in] BSTR argument.
|
|
||||||
|
|
||||||
\code
|
|
||||||
bstr_t bs;
|
|
||||||
HRESULT hr = pRawInterface->raw_Method(bs.in());
|
|
||||||
\endcode
|
|
||||||
|
|
||||||
Only use this wrapper when forced to deal with raw interface.
|
|
||||||
*/
|
|
||||||
BSTR in() const throw()
|
|
||||||
{
|
|
||||||
return str_;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! [in] adapter.
|
|
||||||
/*!
|
|
||||||
Used when calling raw interfaces that require an [in] BSTR* argument.
|
|
||||||
|
|
||||||
\code
|
|
||||||
bstr_t bs;
|
|
||||||
HRESULT hr = pRawInterface->raw_Method(bs.in_ptr());
|
|
||||||
\endcode
|
|
||||||
|
|
||||||
Only use this wrapper when forced to deal with raw interface.
|
|
||||||
*/
|
|
||||||
BSTR* in_ptr() const throw()
|
|
||||||
{
|
|
||||||
return const_cast<BSTR*>(&str_);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! [out] adapter.
|
|
||||||
/*!
|
|
||||||
Used when calling raw interfaces that require an [out] BSTR * argument.
|
|
||||||
|
|
||||||
\code
|
|
||||||
bstr_t bs;
|
|
||||||
HRESULT hr = pRawInterface->raw_MethodThatReturnsBSTR(bs.out());
|
|
||||||
\endcode
|
|
||||||
|
|
||||||
Only use this wrapper when forced to deal with raw interface.
|
|
||||||
*/
|
|
||||||
BSTR* out() throw()
|
|
||||||
{
|
|
||||||
destroy();
|
|
||||||
return &str_;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! [in, out] adapter.
|
|
||||||
/*!
|
|
||||||
Used when calling raw interfaces that require an [in, out] BSTR * argument.
|
|
||||||
|
|
||||||
\code
|
|
||||||
bstr_t bs;
|
|
||||||
HRESULT hr = pRawInterface->raw_MethodThatChangesBSTR(bs.inout());
|
|
||||||
\endcode
|
|
||||||
|
|
||||||
Only use this wrapper when forced to deal with raw interface.
|
|
||||||
|
|
||||||
\note If the wrapped BSTR is shared. The bstr_t is copied so that only this version is modified.
|
|
||||||
|
|
||||||
\exception std::bad_alloc
|
|
||||||
Throws std::bad_alloc if the bstr_t is being copied and memory is exhausted.
|
|
||||||
*/
|
|
||||||
BSTR* inout() throw(std::bad_alloc)
|
|
||||||
{
|
|
||||||
return &str_;
|
|
||||||
}
|
|
||||||
|
|
||||||
friend bstr_t operator+(const std::wstring& s, const bstr_t& t) throw(std::bad_alloc);
|
|
||||||
friend bstr_t operator+(const wchar_t* s, const bstr_t& t) throw(std::bad_alloc);
|
|
||||||
};
|
|
||||||
|
|
||||||
//! Concat operation
|
|
||||||
inline bstr_t operator+(const std::wstring& s, const bstr_t& t) throw(std::bad_alloc)
|
|
||||||
{
|
|
||||||
return bstr_t(s.c_str(), s.length(), t.str_, t.length());
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Concat operation
|
|
||||||
inline bstr_t operator+(const wchar_t* s, const bstr_t& t) throw(std::bad_alloc)
|
|
||||||
{
|
|
||||||
return bstr_t(s, wcslen(s), t.str_, t.length());
|
|
||||||
}
|
|
||||||
//@}
|
|
||||||
|
|
||||||
/*! \name Boolean Operators on String
|
|
||||||
* \relates bstr_t
|
|
||||||
*/
|
|
||||||
//@{
|
|
||||||
inline bool operator==(const wchar_t* s1, const bstr_t& s2) throw()
|
|
||||||
{
|
|
||||||
return s2 == s1;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator!=(const wchar_t* s1, const bstr_t& s2) throw()
|
|
||||||
{
|
|
||||||
return s2 != s1;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator<(const wchar_t* s1, const bstr_t& s2) throw()
|
|
||||||
{
|
|
||||||
return s2 > s1;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator>(const wchar_t* s1, const bstr_t& s2) throw()
|
|
||||||
{
|
|
||||||
return s2 < s1;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator<=(const wchar_t* s1, const bstr_t& s2) throw()
|
|
||||||
{
|
|
||||||
return s2 >= s1;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator>=(const wchar_t* s1, const bstr_t& s2) throw()
|
|
||||||
{
|
|
||||||
return s2 <= s1;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator==(const std::wstring& s1, const bstr_t& s2) throw()
|
|
||||||
{
|
|
||||||
return s2 == s1;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator!=(const std::wstring& s1, const bstr_t& s2) throw()
|
|
||||||
{
|
|
||||||
return s2 != s1;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator<(const std::wstring& s1, const bstr_t& s2) throw()
|
|
||||||
{
|
|
||||||
return s2 > s1;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator>(const std::wstring& s1, const bstr_t& s2) throw()
|
|
||||||
{
|
|
||||||
return s2 < s1;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator<=(const std::wstring& s1, const bstr_t& s2) throw()
|
|
||||||
{
|
|
||||||
return s2 >= s1;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator>=(const std::wstring& s1, const bstr_t& s2) throw()
|
|
||||||
{
|
|
||||||
return s2 <= s1;
|
|
||||||
}
|
|
||||||
//@}
|
|
||||||
|
|
||||||
|
|
||||||
// Implementation of uuid_t construct from bstr.
|
|
||||||
inline uuid_t::uuid_t(const bstr_t& bs)
|
|
||||||
{
|
|
||||||
if (init_from_str(bs.c_str(), bs.length()) == false) throw std::runtime_error(err_msg());
|
|
||||||
}
|
|
||||||
|
|
||||||
inline currency_t& currency_t::parse( const bstr_t &str, LCID locale )
|
|
||||||
{
|
|
||||||
VarCyFromStr( str.in(), locale, 0, &cy_ ) | raise_exception;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
COMET_STATIC_ASSERT( sizeof(comet::bstr_t) == sizeof(BSTR) );
|
|
||||||
COMET_STATIC_ASSERT( sizeof(comet::bstr_t) == sizeof(BSTR) );
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace std {
|
|
||||||
template<> inline void swap( comet::bstr_t& x, comet::bstr_t& y) COMET_STD_SWAP_NOTHROW { x.swap(y); }
|
|
||||||
}
|
|
||||||
|
|
||||||
#include <comet/uuid.h>
|
|
||||||
|
|
||||||
#pragma warning(pop)
|
|
||||||
|
|
||||||
#endif /* COMET_BSTR_H */
|
|
|
@ -1,628 +0,0 @@
|
||||||
/** \file
|
|
||||||
* Provide logging for calls.
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* Copyright © 2003 Michael Geddes
|
|
||||||
*
|
|
||||||
* This material is provided "as is", with absolutely no warranty
|
|
||||||
* expressed or implied. Any use is at your own risk. Permission to
|
|
||||||
* use or copy this software for any purpose is hereby granted without
|
|
||||||
* fee, provided the above notices are retained on all copies.
|
|
||||||
* Permission to modify the code and to distribute modified code is
|
|
||||||
* granted, provided the above notices are retained, and a notice that
|
|
||||||
* the code was modified is included with the above copyright notice.
|
|
||||||
*
|
|
||||||
* This header is part of Comet version 2.
|
|
||||||
* https://github.com/alamaison/comet
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef COMET_CALLLOG_H
|
|
||||||
#define COMET_CALLLOG_H
|
|
||||||
|
|
||||||
#include <comet/config.h>
|
|
||||||
#include <comet/tstring.h>
|
|
||||||
#include <comet/variant.h>
|
|
||||||
#include <comet/currency.h>
|
|
||||||
#include <comet/server.h>
|
|
||||||
#include <iomanip>
|
|
||||||
#include <fstream>
|
|
||||||
#include <sstream>
|
|
||||||
#include <comet/handle_except.h>
|
|
||||||
|
|
||||||
/** \page cometcalllogging Call Logging
|
|
||||||
This is a feature of the comet interfaces that allows the server to log all
|
|
||||||
calls to any of the interface methods. It logs parameter values, and also allows
|
|
||||||
logging of errors (see \ref comethandleexception ).
|
|
||||||
|
|
||||||
Call logging in comet is enabled by using <kbd>tlb2h -L</kbd> (see \ref tlb2husage).
|
|
||||||
|
|
||||||
To enable logging to a specified file, define COMET_LOGFILE and define
|
|
||||||
COMET_LOGFILE_DEFAULT to be the required logfile (see comet::stream_call_logger_t).
|
|
||||||
|
|
||||||
To override logging, specialise comet::call_logger_<true> and implement all the interfaces
|
|
||||||
defined by the default comet::call_logger_.
|
|
||||||
|
|
||||||
How various parameter types are output can be modified by specialising the
|
|
||||||
function comet::comet_log.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** \defgroup CallLog Call-logging
|
|
||||||
*@{
|
|
||||||
*/
|
|
||||||
#ifdef COMET_DOXYGEN // Only for doxygen
|
|
||||||
/** \def COMET_LOGFILE
|
|
||||||
* Define to get simple interface logfiles.
|
|
||||||
* Must use tlb2h -L to enable interface logging. See \ref tlb2husage.
|
|
||||||
* \sa comet_log comet_log_interface comet_log_array stream_call_logger_t tofstream_comet
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define COMET_LOGFILE
|
|
||||||
|
|
||||||
/** \def COMET_LOGFILE_DEFAULT
|
|
||||||
* If COMET_LOGFILE is defined, define to set the default logfile name.
|
|
||||||
* \code
|
|
||||||
#define COMET_LOGFILE_DEFAULT "C:\\log\\comet.log"
|
|
||||||
* \endcode
|
|
||||||
* \relates call_logger_
|
|
||||||
*/
|
|
||||||
#define COMET_LOGFILE_DEFAULT "C:\\log\\comet.log"
|
|
||||||
#endif // COMET_DOXYGEN
|
|
||||||
|
|
||||||
//@}
|
|
||||||
|
|
||||||
namespace comet
|
|
||||||
{
|
|
||||||
/*!\addtogroup CallLog
|
|
||||||
*/
|
|
||||||
//@{
|
|
||||||
/** \struct call_logger_ calllog.h comet/calllog.h
|
|
||||||
* Default NULL logger and description of 'call logger' concept.
|
|
||||||
* Specialise to \b true to override.
|
|
||||||
* \code
|
|
||||||
template<>
|
|
||||||
struct call_logger_<true> : stream_call_logger_t<tofstream_comet>
|
|
||||||
{
|
|
||||||
};
|
|
||||||
* \endcode
|
|
||||||
* \sa stream_call_logger_t tofstream_comet
|
|
||||||
*/
|
|
||||||
template<bool OVERRIDE>
|
|
||||||
struct call_logger_
|
|
||||||
{
|
|
||||||
/** Should the call be logged?
|
|
||||||
* \return Return true to allow call to be logged.
|
|
||||||
*/
|
|
||||||
static inline bool can_log_call() { return false; }
|
|
||||||
/** Should the return values be logged?
|
|
||||||
* \return Return true to allow call return values to be logged.
|
|
||||||
*/
|
|
||||||
static inline bool can_log_return() { return false; }
|
|
||||||
|
|
||||||
/** Called by interfaces to provide call logging.
|
|
||||||
*/
|
|
||||||
static inline void log_call( const tstring &iface, const tstring &funcname, const tstring &log){}
|
|
||||||
|
|
||||||
/// Called by interfaces to provide call return logging.
|
|
||||||
static inline void log_return( const tstring &iface, const tstring &funcname, const tstring &log, const tstring &retval){}
|
|
||||||
|
|
||||||
|
|
||||||
///\name Exception handling redirection.
|
|
||||||
//@{
|
|
||||||
|
|
||||||
/** Should the error be logged?
|
|
||||||
* \return Return true to allow error to be logged.
|
|
||||||
*/
|
|
||||||
static inline bool can_log_exception() { return false; }
|
|
||||||
|
|
||||||
/// Called by exception handlers to provide logging for errors.
|
|
||||||
static inline void log_exception(const tstring &type, const tstring &desc, const source_info_t &errorSource ,const source_info_t &callSource ){}
|
|
||||||
//@}
|
|
||||||
};
|
|
||||||
|
|
||||||
/** \struct stream_call_logger_t calllog.h comet/calllog.h
|
|
||||||
* Log calls to a tostream.
|
|
||||||
* A class/struct that subscribes to and implements the 'call logger' concept for a steam.
|
|
||||||
* Template paramter is expected to be a class that has a method that creates a tostream
|
|
||||||
* instance as follows:
|
|
||||||
* \code
|
|
||||||
* static tostream *create()
|
|
||||||
* \endcode
|
|
||||||
* \param CREATESTREAM Class with a static function \p create() that returns a <b> tostream * </b>
|
|
||||||
* \sa tofstream_comet call_logger_
|
|
||||||
*/
|
|
||||||
template<typename CREATESTREAM>
|
|
||||||
struct stream_call_logger_t
|
|
||||||
#ifdef COMET_DOXYGEN // For documentation
|
|
||||||
: call_logger_
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
static inline bool can_log_call()
|
|
||||||
{
|
|
||||||
tostream *ofs = logger();
|
|
||||||
return ofs != NULL && ofs->good();
|
|
||||||
}
|
|
||||||
static inline bool can_log_return() { return can_log_call(); }
|
|
||||||
static inline bool can_log_exception() { return can_log_call(); }
|
|
||||||
|
|
||||||
static inline void log_call( const tstring &iface, const tstring &funcname, const tstring &log)
|
|
||||||
{
|
|
||||||
log_( false, iface, funcname, log, tstring());
|
|
||||||
}
|
|
||||||
static inline void log_return( const tstring &iface, const tstring &funcname, const tstring &log, const tstring &retval)
|
|
||||||
{
|
|
||||||
log_( true, iface, funcname, log, retval);
|
|
||||||
}
|
|
||||||
static inline void log_exception(const tstring &type, const tstring &desc, const source_info_t &errorSource ,const source_info_t &callSource )
|
|
||||||
{
|
|
||||||
COMET_NOTUSED(errorSource);
|
|
||||||
tostream *ofs= logger();
|
|
||||||
if (ofs==NULL) return; // Should never be NULL, as can_log_call() should have been obeyed before calling.
|
|
||||||
*ofs << _T("Err ") << callSource.source().t_str();
|
|
||||||
if ( !desc.empty() )
|
|
||||||
{
|
|
||||||
*ofs << type << _T(": ") << desc ;
|
|
||||||
}
|
|
||||||
*ofs << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// Log a function call/return.
|
|
||||||
static void log_( bool return_val, const tstring &iface, const tstring &funcname, const tstring &log, const tstring &retval)
|
|
||||||
{
|
|
||||||
tostream *ofs= logger();
|
|
||||||
if (ofs==NULL) return; // Should never be NULL, as can_log_call() should have been obeyed before calling.
|
|
||||||
|
|
||||||
*ofs << (return_val?_T("Out "):_T("In ")) << iface << _T("::") << funcname;
|
|
||||||
if (!return_val || !log.empty())
|
|
||||||
*ofs << _T("(") << log << _T(")");
|
|
||||||
|
|
||||||
if (return_val && !retval.empty())
|
|
||||||
*ofs << _T(" returned ") << retval;
|
|
||||||
*ofs << std::endl;
|
|
||||||
|
|
||||||
}
|
|
||||||
// Access to the static logger instance without needing to initialise a
|
|
||||||
// member.
|
|
||||||
static tostream *logger()
|
|
||||||
{
|
|
||||||
static tostream *ofs_= NULL;
|
|
||||||
if (ofs_ ==NULL)
|
|
||||||
{
|
|
||||||
ofs_ = CREATESTREAM::create();
|
|
||||||
if (ofs_ != NULL)
|
|
||||||
{
|
|
||||||
// Safely clean up static pointer on module destruct
|
|
||||||
module().add_object_to_dispose( create_pointer_deleter( ofs_ ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ofs_;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace impl
|
|
||||||
{
|
|
||||||
/** Redirect default logging to calllog.
|
|
||||||
* \internal
|
|
||||||
*/
|
|
||||||
template<>
|
|
||||||
struct call_logger_redirect_<true>
|
|
||||||
{
|
|
||||||
// This trick allows the user to be able to still override the call logging.
|
|
||||||
// Without this, log_exception has to call
|
|
||||||
// call_logger_<true>::log_exception which causes the template to be
|
|
||||||
// instantiated, and the user is no longer able to specialise
|
|
||||||
// call_logger_
|
|
||||||
template<bool OVERRIDE>
|
|
||||||
struct exe
|
|
||||||
{
|
|
||||||
static inline void log_exception(const tstring &type, const tstring &desc, const source_info_t &errorSource, const source_info_t &callSource )
|
|
||||||
{
|
|
||||||
call_logger_<OVERRIDE>::log_exception(type,desc,errorSource, callSource);
|
|
||||||
}
|
|
||||||
static inline bool can_log_exception()
|
|
||||||
{
|
|
||||||
return call_logger_<OVERRIDE>::can_log_exception();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef COMET_LOGFILE
|
|
||||||
#ifndef COMET_LOGFILE_DEFAULT
|
|
||||||
#define COMET_LOGFILE_DEFAULT NULL
|
|
||||||
#endif
|
|
||||||
#include <fstream>
|
|
||||||
/** \class tofstream_comet calllog.h comet/calllog.h
|
|
||||||
* Provides a filestream creator as well as the implementation of an output filestream logger.
|
|
||||||
* Allows overriding of file name.
|
|
||||||
*/
|
|
||||||
class tofstream_comet : public tofstream
|
|
||||||
{
|
|
||||||
static const char *&filename_()
|
|
||||||
{
|
|
||||||
static const char *default_filename= COMET_LOGFILE_DEFAULT;
|
|
||||||
return default_filename;
|
|
||||||
}
|
|
||||||
public:
|
|
||||||
/// Get the default filename.
|
|
||||||
static const char *get_default_filename() { return filename_(); }
|
|
||||||
/// Set the default filename to a new value.
|
|
||||||
void set_default_filename( const char *filename) { filename_() = filename; }
|
|
||||||
|
|
||||||
tofstream_comet( const char *fname) : tofstream(fname) {}
|
|
||||||
|
|
||||||
/** Create an instance of the logger.
|
|
||||||
* Returns NULL if the file doesn't exist.
|
|
||||||
*/
|
|
||||||
static tostream *create()
|
|
||||||
{
|
|
||||||
const char *fname = filename_();
|
|
||||||
if (fname == NULL)
|
|
||||||
return NULL;
|
|
||||||
return new tofstream_comet(fname);
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
tofstream_comet(const tofstream_comet &);
|
|
||||||
tofstream_comet &operator=(const tofstream_comet &);
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Override specialisation of the call_logger_.
|
|
||||||
* \relates call_logger_
|
|
||||||
*/
|
|
||||||
template<>
|
|
||||||
struct call_logger_<true> : public stream_call_logger_t<tofstream_comet>
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // FILE_LOG
|
|
||||||
|
|
||||||
/** Default interface (com_ptr) logging.
|
|
||||||
* Specialise to provide custom logging for com_ptr.
|
|
||||||
\code
|
|
||||||
template<>
|
|
||||||
void comet_log_interface<IMyInterface>(tostream &os, const com_ptr<IMyInterface> &iface)
|
|
||||||
{
|
|
||||||
os << iface->GetName();
|
|
||||||
}
|
|
||||||
\endcode
|
|
||||||
Specialisations for IUnknown and IDispatch are used by the variant loggers.
|
|
||||||
* \sa comet_log comet_log_array
|
|
||||||
* \relates call_logger_
|
|
||||||
*/
|
|
||||||
template< typename IFACE>
|
|
||||||
void comet_log_interface(tostream &os, const com_ptr<IFACE> &iface)
|
|
||||||
{
|
|
||||||
os << _T("0x") << std::hex << reinterpret_cast<unsigned long>(iface.get()) << std::dec;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Forward declarations.
|
|
||||||
template<typename T> void comet_log(tostream &os, const T &value);
|
|
||||||
|
|
||||||
namespace impl
|
|
||||||
{
|
|
||||||
// Forward declarations.
|
|
||||||
template<typename T> inline void default_comet_log(tostream &os, const T &value);
|
|
||||||
static void comet_log_array_raw(tostream &os, SAFEARRAY *value);
|
|
||||||
|
|
||||||
// The default variant handler.
|
|
||||||
template< bool B>
|
|
||||||
static inline void default_comet_log_variant(tostream &os, const variant_t &value, bool out_type)
|
|
||||||
{
|
|
||||||
VARTYPE vt = value.get_vt();
|
|
||||||
if ((vt & VT_ARRAY) != 0)
|
|
||||||
{
|
|
||||||
comet_log_array_raw(os, value.get().parray);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
VARIANT varcopy=value.in();
|
|
||||||
if (vt == (VT_BYREF | VT_VARIANT)) // Dereference variant by reference
|
|
||||||
varcopy = *V_VARIANTREF(&varcopy);
|
|
||||||
const VARIANT *var=&varcopy;
|
|
||||||
|
|
||||||
#define __VARIANT_LOGPOINTER_TYPE_CAST(vartype,cast) \
|
|
||||||
case VT_##vartype:\
|
|
||||||
if(out_type) os << _T("VT_")_T(#vartype)_T(":");\
|
|
||||||
comet_log_interface(os, cast(V_##vartype(var))); \
|
|
||||||
break
|
|
||||||
|
|
||||||
#define __VARIANT_LOGPOINTER_REFTYPE_CAST(vartype,cast) \
|
|
||||||
case VT_BYREF|VT_##vartype:\
|
|
||||||
if(out_type) os << _T("BYREF VT_")_T(#vartype)_T(":");\
|
|
||||||
comet_log_interface(os, cast(*V_##vartype##REF(var)));\
|
|
||||||
break
|
|
||||||
#define __VARIANT_LOG_TYPE_CAST(vartype,cast) \
|
|
||||||
case VT_##vartype: \
|
|
||||||
if(out_type) os << _T("VT_")_T(#vartype)_T(":"); \
|
|
||||||
comet_log(os, cast(V_##vartype(var))); \
|
|
||||||
break
|
|
||||||
|
|
||||||
#define __VARIANT_LOG_REFTYPE_CAST(vartype,cast)\
|
|
||||||
case VT_BYREF|VT_##vartype:\
|
|
||||||
if(out_type) os << _T("BYREF VT_")_T(#vartype)_T(":");\
|
|
||||||
comet_log(os, cast(*V_##vartype##REF(var)));\
|
|
||||||
break
|
|
||||||
|
|
||||||
#define __VARIANT_LOG_TYPE(vartype) \
|
|
||||||
case VT_##vartype: \
|
|
||||||
if(out_type) os << _T("VT_")_T(#vartype)_T(":");\
|
|
||||||
comet_log(os, V_##vartype(var));\
|
|
||||||
break
|
|
||||||
|
|
||||||
#define __VARIANT_LOG_REFTYPE(vartype)\
|
|
||||||
case VT_BYREF|VT_##vartype: \
|
|
||||||
if(out_type) os << _T("BYREF VT_")_T(#vartype)_T(":"); \
|
|
||||||
comet_log(os, *V_##vartype##REF(var)); \
|
|
||||||
break
|
|
||||||
|
|
||||||
switch (vt)
|
|
||||||
{
|
|
||||||
__VARIANT_LOG_TYPE(UI1);
|
|
||||||
__VARIANT_LOG_TYPE(UI2);
|
|
||||||
__VARIANT_LOG_TYPE(UINT);
|
|
||||||
__VARIANT_LOG_TYPE(UI4);
|
|
||||||
__VARIANT_LOG_TYPE(I1);
|
|
||||||
__VARIANT_LOG_TYPE(I2);
|
|
||||||
__VARIANT_LOG_TYPE(INT);
|
|
||||||
__VARIANT_LOG_TYPE(I4);
|
|
||||||
__VARIANT_LOG_TYPE(R4);
|
|
||||||
__VARIANT_LOG_TYPE(R8);
|
|
||||||
__VARIANT_LOG_REFTYPE(UI1);
|
|
||||||
__VARIANT_LOG_REFTYPE(UI2);
|
|
||||||
__VARIANT_LOG_REFTYPE(UINT);
|
|
||||||
__VARIANT_LOG_REFTYPE(UI4);
|
|
||||||
__VARIANT_LOG_REFTYPE(I1);
|
|
||||||
__VARIANT_LOG_REFTYPE(I2);
|
|
||||||
__VARIANT_LOG_REFTYPE(INT);
|
|
||||||
__VARIANT_LOG_REFTYPE(I4);
|
|
||||||
__VARIANT_LOG_REFTYPE(R4);
|
|
||||||
__VARIANT_LOG_REFTYPE(R8);
|
|
||||||
|
|
||||||
case VT_BOOL:
|
|
||||||
if(out_type) os << _T("VT_BOOL:");
|
|
||||||
os << (V_BOOL(var)==VARIANT_FALSE)?_T("true"):_T("false");
|
|
||||||
break;
|
|
||||||
case VT_BYREF|VT_BOOL:
|
|
||||||
if(out_type) os << _T("BYREF VT_BOOL:");
|
|
||||||
os << (V_BOOL(var)==VARIANT_FALSE)?_T("true"):_T("false");
|
|
||||||
break;
|
|
||||||
__VARIANT_LOG_TYPE_CAST( CY, currency_t::create_const_reference);
|
|
||||||
__VARIANT_LOG_REFTYPE_CAST( CY, currency_t::create_const_reference);
|
|
||||||
__VARIANT_LOG_TYPE_CAST( DATE, datetime_t::create_const_reference);
|
|
||||||
__VARIANT_LOG_REFTYPE_CAST( DATE, datetime_t::create_const_reference);
|
|
||||||
__VARIANT_LOG_TYPE_CAST( BSTR, bstr_t::create_const_reference);
|
|
||||||
__VARIANT_LOG_REFTYPE_CAST( BSTR, bstr_t::create_const_reference);
|
|
||||||
|
|
||||||
__VARIANT_LOGPOINTER_TYPE_CAST( UNKNOWN, com_ptr<IUnknown>::create_const_reference);
|
|
||||||
__VARIANT_LOGPOINTER_TYPE_CAST( DISPATCH, com_ptr<IDispatch>::create_const_reference);
|
|
||||||
__VARIANT_LOGPOINTER_REFTYPE_CAST( UNKNOWN, com_ptr<IUnknown>::create_const_reference);
|
|
||||||
__VARIANT_LOGPOINTER_REFTYPE_CAST( DISPATCH, com_ptr<IDispatch>::create_const_reference);
|
|
||||||
|
|
||||||
case VT_DECIMAL:
|
|
||||||
if(out_type) os << _T("BYREF VT_DECIMAL:");
|
|
||||||
os << _T("?");
|
|
||||||
break;
|
|
||||||
case VT_ERROR:
|
|
||||||
if(out_type) os << _T("VT_ERROR:");
|
|
||||||
os <<_T("0x") << std::hex << V_ERROR(var) << std::dec;
|
|
||||||
break;
|
|
||||||
case VT_BYREF|VT_ERROR:
|
|
||||||
if(out_type) os << _T("BYREF VT_ERROR:");
|
|
||||||
os <<_T("0x") << std::hex << *V_ERRORREF(var) << std::dec;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
os << _T("???");
|
|
||||||
}
|
|
||||||
#undef __VARIANT_LOG_TYPE_CAST
|
|
||||||
#undef __VARIANT_LOG_REFTYPE_CAST
|
|
||||||
#undef __VARIANT_LOG_TYPE
|
|
||||||
#undef __VARIANT_LOG_REFTYPE
|
|
||||||
#undef __VARIANT_LOGPOINTER_TYPE_CAST
|
|
||||||
#undef __VARIANT_LOGPOINTER_REFTYPE_CAST
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Logging for raw safearrays.
|
|
||||||
* For vector arrays of size <= 16, this fakes a variant and then uses the default variant logging to log the elements
|
|
||||||
*/
|
|
||||||
static void comet_log_array_raw(tostream &os, SAFEARRAY *value)
|
|
||||||
{
|
|
||||||
UINT dims = SafeArrayGetDim(value);
|
|
||||||
VARTYPE vt ;
|
|
||||||
if( FAILED(SafeArrayGetVartype(value, &vt ) ) )
|
|
||||||
{
|
|
||||||
os << "???";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
long ubound=-1,lbound=0; // Outside so it can be used for the '1' case below.
|
|
||||||
for (UINT d = 1; d<= dims ; ++d)
|
|
||||||
{
|
|
||||||
if( SUCCEEDED(SafeArrayGetUBound( value, d, &ubound) ) && SUCCEEDED(SafeArrayGetLBound(value, d, &lbound) ))
|
|
||||||
{
|
|
||||||
if( lbound == 0)
|
|
||||||
os << _T("[") << ubound+1 << _T("]");
|
|
||||||
else
|
|
||||||
os << _T("(") << lbound << _T("..") << ubound << _T(")");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
if (dims == 1 )
|
|
||||||
{
|
|
||||||
long size = 1+ubound-lbound;
|
|
||||||
if (size ==0)
|
|
||||||
{
|
|
||||||
os << _T("{}");
|
|
||||||
}
|
|
||||||
else if( size > 0 && size <= 15)
|
|
||||||
{
|
|
||||||
// For small arrays, print out the elements.
|
|
||||||
os << _T("{");
|
|
||||||
VARIANT v;
|
|
||||||
void *var;
|
|
||||||
bool first=true, is_variant= (vt==VT_VARIANT);
|
|
||||||
if ( is_variant)
|
|
||||||
var = (void *)&v;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
V_VT(&v) = vt;
|
|
||||||
var = (void *)&V_UI1(&v);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (long i = lbound; i <= ubound; ++i )
|
|
||||||
{
|
|
||||||
if(first)
|
|
||||||
first = false;
|
|
||||||
else
|
|
||||||
os << _T(",");
|
|
||||||
if( SUCCEEDED( SafeArrayGetElement( value, &i, var ) ))
|
|
||||||
default_comet_log_variant<true>( os, variant_t(auto_attach(v)), first | is_variant);
|
|
||||||
}
|
|
||||||
os << _T("}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Default logging: stream the value.
|
|
||||||
template<typename T>
|
|
||||||
inline void default_comet_log(tostream &os, const T &value)
|
|
||||||
{
|
|
||||||
// ERRORS: If a compiler error occurs here, you may need to
|
|
||||||
// specialise comet_log<> to the type T here.
|
|
||||||
os << value;
|
|
||||||
}
|
|
||||||
// Default logging for bstr_t
|
|
||||||
template<>
|
|
||||||
inline void default_comet_log<bstr_t>(tostream &os, const bstr_t &value)
|
|
||||||
{
|
|
||||||
// Put quotes round the string - simplistic, don't worry about
|
|
||||||
// non-printables or escaping for the moment.
|
|
||||||
os << _T("'") << value << _T("'");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deafult logging for variants.
|
|
||||||
template<>
|
|
||||||
static inline void default_comet_log<variant_t>(tostream &os, const variant_t &value)
|
|
||||||
{
|
|
||||||
default_comet_log_variant<true>( os, value, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Type specific logger.
|
|
||||||
* The default is to use internal logging. This can be specialised to
|
|
||||||
* provide type-specific logging.
|
|
||||||
* \sa comet_log_array comet_log_interface
|
|
||||||
* \relates call_logger_
|
|
||||||
*/
|
|
||||||
template<typename T>
|
|
||||||
void comet_log(tostream &os, const T &value)
|
|
||||||
{
|
|
||||||
impl::default_comet_log(os,value);
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace impl
|
|
||||||
{
|
|
||||||
// trick to work out whether it is a safearray or com_ptr type (required because of no
|
|
||||||
// partial specialisation). Needed to handle the special circumstances
|
|
||||||
template<typename T>
|
|
||||||
struct check_log_type_
|
|
||||||
{
|
|
||||||
static long check(...);
|
|
||||||
|
|
||||||
template<typename S>
|
|
||||||
static char check(const safearray_t<S> &);
|
|
||||||
|
|
||||||
template<typename S>
|
|
||||||
static short check( const com_ptr<S> &);
|
|
||||||
|
|
||||||
static T createT();
|
|
||||||
enum { is = sizeof( check( createT() ) ) };
|
|
||||||
|
|
||||||
};
|
|
||||||
template < int TYPE> struct choose_logger;
|
|
||||||
|
|
||||||
// Default safearray_t logger where we know the type T.
|
|
||||||
//
|
|
||||||
template<typename T>
|
|
||||||
inline void default_comet_log_array(tostream &os, const safearray_t<T> &value)
|
|
||||||
{
|
|
||||||
safearray_t<T>::index_type lbound=value.lower_bound(), size = value.size();
|
|
||||||
if (lbound == 0)
|
|
||||||
os << _T("[") << size << _T("]");
|
|
||||||
else
|
|
||||||
os << _T("(") << lbound << _T("..") << (lbound + size -1) << _T(")");
|
|
||||||
|
|
||||||
if( value.size() <= 15)
|
|
||||||
{
|
|
||||||
os << _T("{");
|
|
||||||
bool first = true;
|
|
||||||
for (safearray_t<T>::const_iterator it = value.begin(); it != value.end(); ++it)
|
|
||||||
{
|
|
||||||
choose_logger<check_log_type_<T>::is >::do_comet_log(os, *it);
|
|
||||||
if (first)
|
|
||||||
first=false;
|
|
||||||
else
|
|
||||||
os << _T(",");
|
|
||||||
}
|
|
||||||
os << _T("}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/** Typed safearray_t logger.
|
|
||||||
* The default is to use internal logging. This can be specialised to
|
|
||||||
* provide type-specific logging.
|
|
||||||
* \sa comet_log comet_log_interface
|
|
||||||
* \relates call_logger_
|
|
||||||
*/
|
|
||||||
template<typename T>
|
|
||||||
void comet_log_array(tostream &os, const safearray_t<T> &value)
|
|
||||||
{
|
|
||||||
impl::default_comet_log_array(os,value);
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace impl
|
|
||||||
{
|
|
||||||
// choose the standard logger
|
|
||||||
template < int TYPE>
|
|
||||||
struct choose_logger
|
|
||||||
{
|
|
||||||
template<typename T>
|
|
||||||
static inline void do_comet_log(tostream &os, const T &value)
|
|
||||||
{
|
|
||||||
comet_log(os,value);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// Choose the array logger
|
|
||||||
template<>
|
|
||||||
struct choose_logger<sizeof(char)>
|
|
||||||
{
|
|
||||||
template <typename T>
|
|
||||||
static inline void do_comet_log(tostream &os, const safearray_t<T> &value)
|
|
||||||
{
|
|
||||||
comet_log_array(os, value);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// Choose the interface logger
|
|
||||||
template<>
|
|
||||||
struct choose_logger<sizeof(short)>
|
|
||||||
{
|
|
||||||
template <typename T>
|
|
||||||
static inline void do_comet_log(tostream &os, const com_ptr<T> &value)
|
|
||||||
{
|
|
||||||
comet_log_interface(os, value);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Choose which of the comet_loggers to use.
|
|
||||||
template<typename T>
|
|
||||||
static inline tostream &do_comet_log(tostream &os, const T &value)
|
|
||||||
{
|
|
||||||
choose_logger<check_log_type_<T>::is >::do_comet_log(os, value);
|
|
||||||
return os;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//@}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* COMET_CALLLOG_H */
|
|
|
@ -1,101 +0,0 @@
|
||||||
/** \file
|
|
||||||
* Command line parser.
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* Copyright © 2002 Mikael Lindgren
|
|
||||||
*
|
|
||||||
* This material is provided "as is", with absolutely no warranty
|
|
||||||
* expressed or implied. Any use is at your own risk. Permission to
|
|
||||||
* use or copy this software for any purpose is hereby granted without
|
|
||||||
* fee, provided the above notices are retained on all copies.
|
|
||||||
* Permission to modify the code and to distribute modified code is
|
|
||||||
* granted, provided the above notices are retained, and a notice that
|
|
||||||
* the code was modified is included with the above copyright notice.
|
|
||||||
*
|
|
||||||
* This header is part of Comet version 2.
|
|
||||||
* https://github.com/alamaison/comet
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef COMET_COMMAND_LINE_PARSER_H
|
|
||||||
#define COMET_COMMAND_LINE_PARSER_H
|
|
||||||
|
|
||||||
#include <comet/tstring.h>
|
|
||||||
|
|
||||||
namespace comet {
|
|
||||||
|
|
||||||
/*! \addtogroup Misc
|
|
||||||
*/
|
|
||||||
//@{
|
|
||||||
class cmd_line_parser
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
enum kind_t {
|
|
||||||
Name, // Name type token, has no leading / or -
|
|
||||||
Option, // Option type token. Leading / or - skipped by token
|
|
||||||
Value, // Value for name or option. Leading : or = skipped by token
|
|
||||||
Done // No more tokens
|
|
||||||
};
|
|
||||||
|
|
||||||
explicit cmd_line_parser(const TCHAR* cmd_line): cmd_line_(cmd_line)
|
|
||||||
{
|
|
||||||
reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
kind_t get_next_token(tstring& result)
|
|
||||||
{
|
|
||||||
static const TCHAR terminators[] = _T("=/- \t");
|
|
||||||
static const TCHAR white_space[] = _T(" \t");
|
|
||||||
|
|
||||||
kind_t kind;
|
|
||||||
|
|
||||||
token_ = next_token_ + _tcsspn(next_token_, white_space); // Skip leading whitespace
|
|
||||||
switch (*token_)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
return Done;
|
|
||||||
case _T('-'):
|
|
||||||
case _T('/'):
|
|
||||||
kind = Option;
|
|
||||||
++token_;
|
|
||||||
break;
|
|
||||||
case _T('='):
|
|
||||||
kind = Value;
|
|
||||||
++token_;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
kind = Name;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (kind == Option || kind == Value)
|
|
||||||
token_ += _tcsspn(token_, white_space); // Skip any more whitespace
|
|
||||||
if (*token_ == _T('"'))
|
|
||||||
{
|
|
||||||
const TCHAR* next = _tcschr(token_+1, _T('"'));
|
|
||||||
if ( next )
|
|
||||||
{
|
|
||||||
result.assign( token_+1, next );
|
|
||||||
next_token_ = next+1;
|
|
||||||
return kind;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
next_token_ = token_ + _tcscspn(token_, terminators);
|
|
||||||
result.assign(token_, next_token_);
|
|
||||||
return kind;
|
|
||||||
}
|
|
||||||
|
|
||||||
void reset()
|
|
||||||
{
|
|
||||||
token_ = 0;
|
|
||||||
next_token_ = cmd_line_;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
const TCHAR* cmd_line_;
|
|
||||||
const TCHAR* token_;
|
|
||||||
const TCHAR* next_token_;
|
|
||||||
};
|
|
||||||
//@}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,776 +0,0 @@
|
||||||
/** \file
|
|
||||||
* Load basic comet libraries.
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* Copyright © 2000, 2001 Sofus Mortensen, Michael Geddes
|
|
||||||
*
|
|
||||||
* This material is provided "as is", with absolutely no warranty
|
|
||||||
* expressed or implied. Any use is at your own risk. Permission to
|
|
||||||
* use or copy this software for any purpose is hereby granted without
|
|
||||||
* fee, provided the above notices are retained on all copies.
|
|
||||||
* Permission to modify the code and to distribute modified code is
|
|
||||||
* granted, provided the above notices are retained, and a notice that
|
|
||||||
* the code was modified is included with the above copyright notice.
|
|
||||||
*
|
|
||||||
* This header is part of Comet version 2.
|
|
||||||
* https://github.com/alamaison/comet
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef COMET_COMET_H
|
|
||||||
#define COMET_COMET_H
|
|
||||||
|
|
||||||
#include <comet/config.h>
|
|
||||||
|
|
||||||
/**
|
|
||||||
@mainpage Comet
|
|
||||||
|
|
||||||
See https://github.com/alamaison/comet
|
|
||||||
|
|
||||||
See \ref comethistory.
|
|
||||||
|
|
||||||
\section cometinfocontents Information Pages
|
|
||||||
<ul>
|
|
||||||
<li>\ref tlb2husage</li>
|
|
||||||
<li>\ref tlb2handidl</li>
|
|
||||||
<li>\ref cometcomptr</li>
|
|
||||||
<li>\ref cometrawcomaccess</li>
|
|
||||||
<li>\ref cometconnectionpoints</li>
|
|
||||||
<ul>
|
|
||||||
<li> \ref cometconnectionpointssource</li>
|
|
||||||
<li> \ref cometconnectionpointsink</li>
|
|
||||||
</ul>
|
|
||||||
<li>\ref comettstring</li>
|
|
||||||
<li>\ref cometdefineconfiguration</li>
|
|
||||||
<li>\ref cometcatchallexception</li>
|
|
||||||
<li>\ref cometclassfactory</li>
|
|
||||||
<li>\link custom_registration Custom Registration\endlink</li>
|
|
||||||
<li>\ref comethandleexception</li>
|
|
||||||
<li>\ref cometcalllogging</li>
|
|
||||||
<li>\ref cometautoexp</li>
|
|
||||||
<ul><li>\ref cometautoexpusage</li></ul>
|
|
||||||
</ul>
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \page cometrawcomaccess Raw COM Acces
|
|
||||||
* The designers of Comet have tried to avoid making the wrappers do too much
|
|
||||||
* implicitly, prefering discrete but explicit ways of triggering functionality.
|
|
||||||
*
|
|
||||||
* In order to provide interaction of Comet classes with their COM counterparts,
|
|
||||||
* a standard set of methods have been used, effectively providing a COM wrapper
|
|
||||||
* <i>concept</i>.
|
|
||||||
*
|
|
||||||
* <ul>
|
|
||||||
* <li><b>in()</b>: Return a pointer suitable for [in] parameters,</li>
|
|
||||||
* <li><b>out()</b>: Return a pointer suitable for [out] parameters, first freeing memory allocated,</li>
|
|
||||||
* <li><b>inout()</b>: Return a pointer suitable for [in,out] parameters.</li>
|
|
||||||
* <li><b>detach()</b>: Detach and return the internal pointer from the object</li>
|
|
||||||
* <li><b>in_ptr()</b>: {optional} Return a pointer suitable for [out] parameter where a pointer is required, first freeing memory allocated</li>
|
|
||||||
* <li><b>get()</b>: {optional} Returns a pointer to the internal pointer (same as STL pointers)</li>
|
|
||||||
* <li><b>auto_attach( RAW_TYPE )</b>: Cause an assignment to attach the object to the specified raw COM type.</li>
|
|
||||||
* <li><b>create_reference( RAW_TYPE )</b>: Static method to create a propper wrapper reference to the specified raw object.</li>
|
|
||||||
* <li><b>create_const_reference( RAW_TYPE )</b>: Static method to create a const wrapper reference to the specified raw object.</li>
|
|
||||||
* </ul>
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** \page cometcatchallexception Exception Catching Policy
|
|
||||||
In an ideal world, Microsoft would have adhered to the C++ standard, and made
|
|
||||||
<kbd>catch(...)</kbd> not catch system exceptions like 'Access Violation',
|
|
||||||
however this is not the case.
|
|
||||||
|
|
||||||
To make it worse, not only do system exceptions get caught by <kbd>catch(...)</kbd>,
|
|
||||||
they also <b>bypass the stack unwinding</b>. This is quite problematic in an
|
|
||||||
environment where this mechanism is relied upon for resource management, commonly
|
|
||||||
'only' memory, but also including multithreading acces control mechanisms.
|
|
||||||
|
|
||||||
One of the big problems with Access Violations is that it is an unplanned
|
|
||||||
exception, and in many situations will leave data structures incomplete,
|
|
||||||
resources locked or other equally vicious artifacts. Essentially, it breaks
|
|
||||||
invariants. One viable take on this is that if you don't know where an
|
|
||||||
exception came from, you shouldn't be catching it.
|
|
||||||
|
|
||||||
A big advantage of letting access violations and it's ilk (or any other
|
|
||||||
unplanned exception) through is that these will then get caught by the JIT (Just
|
|
||||||
In Time) handlers such as Dr. Watson and Compiler environments that allow
|
|
||||||
immediate or post-mortem debugging of the problem. A lot of projects (like
|
|
||||||
Mozilla) have their own bug-reporting which can intercept the bugs at the top
|
|
||||||
level and generate their own crash dumps, and catching these exceptions is
|
|
||||||
actually going to bypass a very useful mechanism.
|
|
||||||
|
|
||||||
All this is to say that we have made a shift away from exception handling
|
|
||||||
policies that cause system expeptions to be caught, however in order to
|
|
||||||
allow as much flexibility as possible, an improved exception handling mechanism
|
|
||||||
has been added to the interface implementations and to the server implementation
|
|
||||||
that uses catch and rethrow to allow logging and custom handling of all exceptions.
|
|
||||||
|
|
||||||
The default action of the mechanisms will be to finally rethrow unknown
|
|
||||||
exceptions. The good thing about this is that the rethrow behaves to a JIT handler
|
|
||||||
as if the expeption had never been caught.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** \page cometautoexp Comet AutoExp.Dat Support
|
|
||||||
There is a largely undocumented feature is Visual Studio 6 and 7 that allows
|
|
||||||
you to create a dll 'ADDIN' that provides custom formatting for variables in the
|
|
||||||
debugger. CometAutoExp.dll allows you to view simple automation types in more
|
|
||||||
detail than currently provided internally by the debugger.
|
|
||||||
|
|
||||||
By enabling this, you will get to see real date/times when you view datetime_t, you
|
|
||||||
get to see SAFEARRAY types (including IIDs), and possibly their contents, you
|
|
||||||
will see full VARIANT types, including SAFEARRAYs.
|
|
||||||
|
|
||||||
The file in comet/src/cometautoexp/AutoExp.dat shows the entries that will
|
|
||||||
be needed to included in your own AutoExp.dat for this to work. (Usually
|
|
||||||
found at "c:\Program Files\Microsoft Visual Studio\Common\MSDev98\Bin\AUTOEXP.DAT")
|
|
||||||
|
|
||||||
See \ref cometautoexpusage for more information on how to use this.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** \page cometdefineconfiguration Comet Configuation
|
|
||||||
While Comet barely uses macros for the import work of creating a COM library,
|
|
||||||
there are a number of preprocessor switches that are used to alter certain
|
|
||||||
behaviours and select code. While most of these refer to the compiler being used,
|
|
||||||
there are a few that are intended to be used as external switches.
|
|
||||||
|
|
||||||
<ul><li><b>COMET_ALLOW_DECLSPEC_PROPERTY</b> : Wrapper headers include declspec
|
|
||||||
properties, allowing interface properties to be assigned-to and read as
|
|
||||||
properties.</li> <li><b>COMET_ASSERT_THROWS</b> : Comet throws
|
|
||||||
comet::assert_failed when internal assertions fail in debug builds.</li>
|
|
||||||
<li><b>COMET_ASSERT_THROWS_ALWAYS</b> : Comet throws comet::assert_failed when
|
|
||||||
internal assertions fail in both debug and release builds.</li>
|
|
||||||
<li><b>COMET_LOGFILE</b> : See \ref cometcalllogging.</li>
|
|
||||||
<li><b>COMET_LOGFILE_DEFAULT</b> : See \ref cometcalllogging. </li>
|
|
||||||
<li><b>COMET_NO_MBCS</b> : Disable comet multi-byte-character-set conversion handling.</li>
|
|
||||||
<li><b>COMET_NO_MBCS_WARNING</b> : Turn off the warning indicating that sdt::string is not compatible with MBCS.</li>
|
|
||||||
<li><b>COMET_USE_RAW_WRAPPERS</b> : Tells com_ptr not to use the comet wrappers but to return raw interface pointers. </li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
There are also a number of macros that are either utitlity macros, reflect compiler differences
|
|
||||||
or Comet version differences that may be convenient to use within your own code.
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li><b>COMET_ASSERT(expression)</b> : Run-time assert.</li>
|
|
||||||
<li><b>COMET_STATIC_ASSERT(static-expression)</b> : Compile-time assert.</li>
|
|
||||||
<li><b>COMET_NOTUSED(info)</b> : Specify unused argument.</li>
|
|
||||||
<li><b>COMET_FORCEINLINE </b> : Use before a method to apply force-inline if available. </li>
|
|
||||||
<li><b>COMET_VARIANT_TRUE,COMET_VARIANT_FALSE</b> : Use in place of VARIANT_TRUE,VARIANT_FALSE to avoid type warnings.</li>
|
|
||||||
<li><b>COMET_MAJOR_VER </b> : Major comet version</li>
|
|
||||||
<li><b>COMET_MINOR_VER </b> : Minor comet version</li>
|
|
||||||
<li><b>COMET_BUILD </b> : Comet version to compare against (yyyymmdd of distribution)</li>
|
|
||||||
<li><b>COMET_STRICT_TYPENAME </b> : Used for when stricter compilers require 'typename' keyword and VC6 has an error.</li>
|
|
||||||
<li><b>COMET_CONST_TYPE(vartype, varname, value)</b> : Define a typed constant for a class/struct (or use enum if not supported) </li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** \page comethistory Comet History
|
|
||||||
\par Version 1 gamma 32 ( )
|
|
||||||
\li Support for VC++2005 (Sofus Mortensen)
|
|
||||||
\li Numerous bug fixes and better support for Intel C++ (Richard Crossley)
|
|
||||||
\li Fixed off-by-one bug regarding array sizes (Yunusov Bulat)
|
|
||||||
|
|
||||||
\par Version 1 beta 31 ( )
|
|
||||||
\li safearray.h - Fix a few omissions/bugs (Lijun Qin)
|
|
||||||
\li comet_lint.lnt - Add pclint options file. (Michael Geddes)
|
|
||||||
\li server.h - Fix singlton_autorelease class (Ralf Jürgensen)
|
|
||||||
\li datetime.h - Fix bug in century non-leap-years. (Michael Geddes)
|
|
||||||
\li datetime.h - Use julian date conversions from boost - to drastically improve split/join efficiency (Michael Geddes)
|
|
||||||
\li datetime.h - Make invalid() rather than valid() the default (Michael Geddes)
|
|
||||||
\li date.h - Make use of above improvements in datetime_t (Michael Geddes)
|
|
||||||
\li datetime.h/date.h - Add ability to construct/assign invalid/null dates from dt_null, dt_invalid (Michael Geddes)
|
|
||||||
\li datetime.h - Fixed bug in to_unixtime (Lijun Qin)
|
|
||||||
\li array.h - Fixed typename problem (Sofus Mortensen)
|
|
||||||
\li safearray.h - Fixed problem with sa_debug_iterator and MSVC 7.1 (Sofus Mortensen)
|
|
||||||
\li uuid_fwd.h - Fixed bug in !operator (Sofus Mortensen)
|
|
||||||
|
|
||||||
\par Version 1 beta 30 (2004-3-5)
|
|
||||||
\li Support for VC7.1 partial specialisation. (Lijun Qin)
|
|
||||||
\li datetime.h - Bugfix in datetime_t conversion (Gordon Donaldson)
|
|
||||||
\li safearray.h - Separate safearray_t::resize into resize and resize_bound to avoid ambiguous conversions. (Michael Geddes)
|
|
||||||
\li safearray.h - Fix bug in safearray_t:resize_bound using an incorrect copy. (Michael Geddes)
|
|
||||||
\li safearray.h - Add safearray_t debug iterator for debug builds. (Michael Geddes)
|
|
||||||
\li safearray.h - Add more comments for safearray_t (Michael Geddes)
|
|
||||||
\li safearray.h - Support more container-type methods (erase,push_front,push_back,pop_front,pop_back) (Michael Geddes)
|
|
||||||
\li server.h - Add auto-release singleton (Michael Geddes)
|
|
||||||
\li uuid.h - uuid_t::operator! no longer reversed (Lijun Qin)
|
|
||||||
\li uuid.h - fix ambiguous ++ operator usage. (Lijun Qin, Bulat Raditch, Michael Geddes)
|
|
||||||
\li handle.h - Extension of handles for GDI objects for cometw (Michael Geddes/Vladimir Voinkov/Lindgren Mikael)
|
|
||||||
\li bstr.h - Throw comparison errors if they occur. (Michael Geddes)
|
|
||||||
\li cp.h - add 'is_connected' method to connection points. (Lijun Qin)
|
|
||||||
\li common.h - Support for pclint (Michael Geddes, Gabriel Barta)
|
|
||||||
\li datetime.h - Support for timezones (Michael Geddes)
|
|
||||||
\li datetime.h - Fix up buffer handling (Michael Geddes, Lijun Qin)
|
|
||||||
\li variant.h - Support for strings with embedded nulls (Michael Geddes)
|
|
||||||
\li tlb2h - Support for bool in structs and in safearrays (Michael Geddes)
|
|
||||||
\li tlb2h - Support for wrapper renaming of specific methods on specific interfaces/struct/unions. (Michael Geddes)
|
|
||||||
\li tlb2h - Dual interfaces inherited from an interface in a different type-library now works when called by dispatch (Michael Geddes)
|
|
||||||
\li tlb2h - Output of HTML now better restricted to only required interfaces. (Michael Geddes)
|
|
||||||
\li tlb2h - Obey COM rules that require [out] pointers to be initialised on failure (Michael Geddes)
|
|
||||||
\li tlb2h - Support implementation of an interface that inherits from an interface from a different typelibrary (Michael Geddes)
|
|
||||||
\li cometautoexp - Support for more types, and better handling of strings. (std::basic_string, COLEDateTime) (Michael Geddes)
|
|
||||||
\li date.h - Added dateonly_t class. (Michael Geddes)
|
|
||||||
\li uuid.h - Make the strings accessors consistant (Michael Geddes, Lijun Qin)
|
|
||||||
|
|
||||||
\par Version 1 beta 29 (2003-12-30)
|
|
||||||
\li Added loads of documentation, reduced doxygen warnings to 1(Michael Geddes)
|
|
||||||
\li Added CometAutoExp.dll extended support for AutoExp.dat
|
|
||||||
\li Remove unnecessary catch(...) - use specific catches (Michael Geddes)
|
|
||||||
\li Support create_const_reference in all wrapper classes. (Michael Geddes)
|
|
||||||
\li tlb2h - Enhance support for error information (interface/coclass name) (Michael Geddes)
|
|
||||||
\li tlb2h - Add support for logging calls & exceptions. (Michael Geddes)
|
|
||||||
\li tlb2h - Support for special characters in help strings. (Michael Geddes)
|
|
||||||
\li tlb2h - Few tweaks to get correct output. (Michael Geddes)
|
|
||||||
\li tlb2h - Option to show version (Michael Geddes)
|
|
||||||
\li bstr.h - Work with _STLP_DEBUG wrappers (Michael Geddes)
|
|
||||||
\li bstr.h - Constructor works with MBCS (Michael Geddes)
|
|
||||||
\li bstr.h - Support for {} round uuid_t (Michael Geddes)
|
|
||||||
\li cp.h - Add convenience methods. (Michael Geddes)
|
|
||||||
\li datetime.h - Constructor to supply date and time (Michael Geddes)
|
|
||||||
\li datetime.h - Support output streams. (Michael Geddes)
|
|
||||||
\li error.h - Support for source, iid and helpfile in errors. (Michael Geddes)
|
|
||||||
\li interface.h - Provide extra comtype definitions. (Michael Geddes)
|
|
||||||
\li interface.h - Provide convenience macro to define extra comtype with IID_ instances. (Michael Geddes)
|
|
||||||
\li ptr.h - Add identity_ptr class that references an identity IUnknown. All other comparisons QI on <b>both</b> pointers. (Michael Geddes)
|
|
||||||
\li server.h - Add support for singelton classes. (Michael Geddes)
|
|
||||||
\li tlbinfo.h - Fix up reference counting on struct wrappers. (Michael Geddes)
|
|
||||||
\li tlbinfo.h - Support ITypeInfo2 (Michael Geddes)
|
|
||||||
\li variant.h - Added explicit converts (as_uchar(), as_uint(), as_double() etc) (Michael Geddes)
|
|
||||||
\li variant.h - Added is_empty(), is_null() and is_nothing() (Michael Geddes)
|
|
||||||
|
|
||||||
\par Version 1 beta 28 (2003-6-18)
|
|
||||||
\li Support for Visual Studio 2003
|
|
||||||
|
|
||||||
\par Version 1 beta 27 (2003-3-5)
|
|
||||||
\li tlb2h - bug fix variant_t members of dispinterfaces (Michael Geddes)
|
|
||||||
\li tlb2h - support for safearrays of interfaces (Michael Geddes)
|
|
||||||
|
|
||||||
\par Version 1 beta 26 (2003-2-1)
|
|
||||||
\li tlb2h - major update. See http://groups.yahoo.com/group/tlb2h/message/706 (Michael Geddes)
|
|
||||||
\li Enum.h - allow copy policies with members (Michael Geddes)
|
|
||||||
\li datetime.h - fixed bug in timeperiod_t::split (Michael Geddes)
|
|
||||||
|
|
||||||
\par Version 1 beta 25 (2002-11-28)
|
|
||||||
\li Connection point implementation is now customisable via traits. See http://groups.yahoo.com/group/tlb2h/message/688 (Michael Geddes)
|
|
||||||
\li Fixed bug in str_formattime in datetime.h (Sofus Mortensen).
|
|
||||||
\li Fixed bug in add_months in datetime.h (Michael Geddes).
|
|
||||||
|
|
||||||
\par Version 1 beta 24 (2002-11-13)
|
|
||||||
\li Major update of tlb2h. See http://groups.yahoo.com/group/tlb2h/message/659 and http://groups.yahoo.com/group/tlb2h/message/661. (Michael Geddes)
|
|
||||||
\li Fixed problem with variant_t::operator==. (Kyle Alons)
|
|
||||||
\li Fixed bug in bstr_t::s_str(), bstr_t::is_empty(), bstr_t::length() (Mikael Lindgren, Michael Geddes)
|
|
||||||
\li safearray_t: 1. Changed the constructor that takes two iterators to not have a default lowerbound (to be consistant with the other constructor)
|
|
||||||
2. Changed resize to allow specifying a lower-bound.
|
|
||||||
3. Changed the default lb to be 0 in the case where none is specified and where the safearray is NULL. (Michael Geddes)
|
|
||||||
|
|
||||||
\par Version 1 beta 23 (2002-9-1)
|
|
||||||
\li Bug fixes to namespace handling. (Michael Geddes)
|
|
||||||
\li Added friendly error message for missing tlbinf32.dll. (Sofus Mortensen)
|
|
||||||
\li Worked around MSVC6 internal compiler error when contructing an enum. (Michael Geddes)
|
|
||||||
\li Bug fixes to currency.h (Michael Geddes)
|
|
||||||
\li Bug fixes to datetime.h (Michael Geddes)
|
|
||||||
|
|
||||||
\par Version 1 beta 22 (2002-8-19)
|
|
||||||
\li Update of tlb2h - better handling of namespace mangling, and support for
|
|
||||||
unwrapping the type of aliases without unwrapping the name of the aliases (Michael Geddes).
|
|
||||||
\li Fixed bug in uuid_fwd. (John Harrison)
|
|
||||||
\li Added oleidl_comtypes.h. (Gabriel Barta)
|
|
||||||
\li Restored old functionality of try_cast - will no longer throw when casting a null pointer. (Sofus Mortensen)
|
|
||||||
\li New auto-locking implementation of safearray_t::create_reference and safearray_t::create_const_reference. (Michael Geddes, Sofus Mortensen)
|
|
||||||
\li Included first drop (pre-alpha version) of cometw. (Vladimir Voinkov)
|
|
||||||
|
|
||||||
\par Version 1 beta 21 (2002-6-21)
|
|
||||||
\li Fixed null pointer bug in com_error::what(). (Kyle Alons)
|
|
||||||
\li Fixed bug to do with the unloading of typelibraries when refcount reaches zero. (Michael Geddes)
|
|
||||||
\li Added support for MBCS to std::string and const char* conversions for bstr_t. Only active when _MBCS is defined. (Michael Geddes)
|
|
||||||
\li Fixed locking/unlocking bug. (Vladimir Voinkov, Sofus Mortensen)
|
|
||||||
\li Fixed bug in safearray_t::create_reference(variant_t&). (Michael Geddes)
|
|
||||||
\li Various fixes to datetime and currency. (Michael Geddes)
|
|
||||||
\li Added constants COMET_VARIANT_TRUE and COMET_VARIANT_FALSE in order to avoid warnings. (Michael Geddes, Sofus Mortensen)
|
|
||||||
\li registry::value has been extended with overload for method str and dword, where a default value can be supplied if the key/value does not exist. (Sofus Mortensen)
|
|
||||||
\li Various patches for BCC. (Michael Geddes)
|
|
||||||
\li Solved problem with vtables gaps when inheriting from those interfaces. (Michael Geddes)
|
|
||||||
\li Removed a few level 4 warnings. (Michael Geddes)
|
|
||||||
\li Added experimental HTML generation to tlb2h. (Sofus Mortensen)
|
|
||||||
|
|
||||||
\par Version 1 beta 20 (2002-4-9)
|
|
||||||
\li tlb2h will fall back to using raw structs for structs with types that cannot be wrapped. (Sofus Mortensen)
|
|
||||||
\li Added application wizard for MSVC.NET. See tlb2h/src/Comet. (Sofus Mortensen)
|
|
||||||
\li Eliminated a few warnings. (Sofus Mortensen)
|
|
||||||
|
|
||||||
\par Version 1 beta 19 (2002-3-26)
|
|
||||||
\li Added caching of IRecordInfo to sa_traits for wrapped structs and ITypeInfo to IDispatch implementations. (Sofus Mortensen)
|
|
||||||
\li Fixed problem with safearray_t iterators on MSVC7. (Sofus Mortensen)
|
|
||||||
\li Fixed bug regarding range checking for safearray_t::at being off by one. (Sofus Mortensen)
|
|
||||||
\li Added range checking assertion (debug only) to safearray_t::operator[]. (Sofus Mortensen)
|
|
||||||
\li Changed safearray_t constructor, so that lower bound of one is no longer assumed. Instead lower bound must be specified. (Sofus Mortensen)
|
|
||||||
|
|
||||||
\par Version 1 beta 18 (2002-3-25)
|
|
||||||
\li Major revision of bstr_t. (Sofus Mortensen)
|
|
||||||
\li Added experimental support for wrapped structs to tlb2h and safearray. (Sofus Mortensen)
|
|
||||||
\li Fixed problem with having a coclass as a connection point sink. (Sofus Mortensen)
|
|
||||||
\li Revised treatment of [in, out] parameters in tlb2h. The old implementation could cause double deletion of [in. out] parameters when an exception was thrown. (Sofus Mortensen)
|
|
||||||
\li Revised all wrapper classes, in order for create_reference to create a mutable reference and create_const_reference an immutable reference. (Sofus Mortensen)
|
|
||||||
\li Revised locking in safearray_t. safearray_t::create_reference and safearray_t::create_const_reference is no longer doing automatic locking. (Sofus Mortensen)
|
|
||||||
\li tlb2h now generates #import alike smart pointer typedef. Ie. interface IFoo will be matched with a typedef com_ptr<IFoo> IFooPtr. (Sofus Mortensen)
|
|
||||||
\li Added support for datetime_t and currency_t to safearray_t. (Sofus Mortensen)
|
|
||||||
\li Added t_str() to bstr_t for converting to tstring. (Sofus Mortensen)
|
|
||||||
|
|
||||||
\par Version 1 beta 17 (2002-2-18)
|
|
||||||
\li Fixed bug in atl_module. (Michael Geddes)
|
|
||||||
\li Documentation update for bstr.h. (Michael Geddes)
|
|
||||||
\li bstr_t now supports strings with embedded nulls. Thanks to Eric Friedman for reporting this. (Sofus Mortensen)
|
|
||||||
\li Removed use of _alloca in bstr.h. (Sofus Mortensen)
|
|
||||||
|
|
||||||
\par Version 1 beta 16 (2002-2-12)
|
|
||||||
\li Fixed bug in functors bstr::less, bstr::less_equal, bstr::greater, bstr::greater_equal, bstr::equal_to and bstr::not_equal_to. (Michael Geddes)
|
|
||||||
\li tlb2h: switched ResolveAliases off per request from Michael Geddes.
|
|
||||||
\li tlb2h: Removed dummy wrapper methods (see http://groups.yahoo.com/group/tlb2h/message/476). (Sofus Mortensen)
|
|
||||||
|
|
||||||
\par Version 1 beta 15 (2002-2-1)
|
|
||||||
\li Added lw_lock class based on Brad Wilson's LightweightLock (see http://www.quality.nu/dotnetguy/archive/fog0000000007.aspx). Many thanks to Brad for making LightweightLock open source. (Sofus Mortensen)
|
|
||||||
\li Comet now works with MSVC7. (Sofus Mortensen)
|
|
||||||
\li Removed functor.h. (Sofus Mortensen)
|
|
||||||
\li Fixed serious bug in bstr_base - causing memory corruption when concat'ing bstr's. (Michael Geddes)
|
|
||||||
\li Fixed obvious typo in locking_ptr. (Vladimir Voinkov)
|
|
||||||
\li Removed unnecessary include dependency from scope_guard.h. (Vladimir Voinkov)
|
|
||||||
\li Fixed compatibility problem with STLport for bstr comparison functors. (Michael Geddes)
|
|
||||||
\li Removed level 4 warnings from currency.h. (Michael Geddes).
|
|
||||||
\li Fixed problem with the -c option in tlb2h. (Michael Geddes).
|
|
||||||
\li Fixed bug in ATL_module.h. (Michael Geddes)
|
|
||||||
\li impl_dispatch is now lazy loading TypeInfo. Better performance for dual interfaces where client is not using IDispatch. (Sofus Mortensen)
|
|
||||||
\li Fixed various bugs in tlb2h. (Sofus Mortensen)
|
|
||||||
|
|
||||||
\par Version 1 beta 14 (2002-1-17)
|
|
||||||
|
|
||||||
\li Fixed problem with dispinterfaces and [in, out] enum parameters. (Sofus Mortensen)
|
|
||||||
\li Added simple system to prevent compiling out-of-date tlb2h generated headers. (Sofus Mortensen)
|
|
||||||
\li Fixed bug in impl_dispatch. (Michael Geddes, Sofus Mortensen)
|
|
||||||
|
|
||||||
\par Version 1 beta 13 take 4 (2002-1-11)
|
|
||||||
|
|
||||||
\li Fixed problem with dispinterfaces and enum parameters reported by Kyle Alons. (Sofus Mortensen)
|
|
||||||
\li Fixed serious bug in iterators for safearray_t reported by Steve Broeffle. The bug was caused by a MSVC compiler bug. (Sofus Mortensen)
|
|
||||||
\li Fixed bug operator in operator[] in iterators for safearray_t. (Sofus Mortensen)
|
|
||||||
|
|
||||||
\par Version 1 beta 13 take 3 (2002-1-9)
|
|
||||||
|
|
||||||
\li Fixed bug in uuid_t introduced in beta 13 take 2. (Sofus Mortensen)
|
|
||||||
|
|
||||||
\par Version 1 beta 13 take 2 (2002-1-7)
|
|
||||||
|
|
||||||
\li Beta 13 couldn't compile with _UNICODE defined. Fixed now. (Sofus Mortensen)
|
|
||||||
|
|
||||||
\par Version 1 beta 13 (2002-1-7)
|
|
||||||
|
|
||||||
\li Added basic support for writing exe servers in Comet. (Mikael Lindgren, Sofus Mortensen)
|
|
||||||
\li Added simple command line parser class to new header comet/cmd_line_parser.h (Mikael Lindgren)
|
|
||||||
\li Added new header comet/tstring.h. Defines tstring, tistream, tostream, etc, etc. (Sofus Mortensen)
|
|
||||||
\li Fixed various bugs in uuid_t. (Sofus Mortensen)
|
|
||||||
|
|
||||||
\par Version 1 beta 12 (2001-12-20)
|
|
||||||
|
|
||||||
\li Revision of embedded_object. embedded_object now takes parent type as first argument, arguments 2, 3, 4, .. denotes interfaces to implement.
|
|
||||||
embedded_object_1 has been removed. embedded_object2 has been added, extends embedded_object with functionality to
|
|
||||||
disconnect a child object from its parent. (Sofus Mortensen with help from Kyle Alons).
|
|
||||||
\li Added new file dispatch.h with specialisation of wrap_t<IDispatch> with similar (but superior) functionality as CComDispatchDriver.
|
|
||||||
\li Added new class dynamic_dispatch to dispatch.h. Use dynamic_dispatch to dynamically implement IDispatch - adding methods and properties at runtime. (Sofus Mortensen)
|
|
||||||
\li Changed interface of sink_impl so that unadvise no longer takes an argument. Additionally the destructor will unadvise if necessary. (Sofus Mortensen)
|
|
||||||
\li Added new file uuid.h with GUID/UUID/CLSID wrapper called uuid_t. (Sofus Mortensen)
|
|
||||||
\li Changed tlb2h to support new wrapper uuid_t. (Sofus Mortensen)
|
|
||||||
\li Fixed potential thread safety problem regarding class factories. (Sofus Mortensen, Paul Hollingsworth)
|
|
||||||
|
|
||||||
\par Version 1 beta 11 (2001-11-16)
|
|
||||||
|
|
||||||
\li Major fix to tlb2h. tlb2h now supports properties in dispinterfaces. (Sofus Mortensen)
|
|
||||||
\li Module constants are now static. (Sofus Mortensen)
|
|
||||||
\li tlb2h now skips non-COM interfaces that do not derive (directly or transitively) from IUnknown. (Sofus Mortensen)
|
|
||||||
\li Fixed problem with error messages ending up as garbage in tlb2h. (Kyle Alons)
|
|
||||||
\li Various fixes regarding safearray_t. (Michael Geddes and Sofus Mortensen)
|
|
||||||
\li Various other minor fixes. (Sofus Mortensen)
|
|
||||||
|
|
||||||
\par Version 1 beta 10 (2001-10-17)
|
|
||||||
|
|
||||||
\li class coclass changed so that the 3, 4, ... template parameters specifify additional interfaces to implement.
|
|
||||||
Example:
|
|
||||||
\code
|
|
||||||
template<> coclass_implementation<Foo> : public coclass<Foo, thread_model::Both, IBar>
|
|
||||||
\endcode
|
|
||||||
(Sofus Mortensen)
|
|
||||||
\li Aggregating another component is now done by adding class aggregates to the type list of interfaces. First template argument of class aggregates is the coclass
|
|
||||||
to aggregating. The 2, 4, ... template arguments specify which interfaces to aggregate. If no interfaces have been specified, all interfaces will be aggregated.
|
|
||||||
Example:
|
|
||||||
\code
|
|
||||||
template<> coclass_implementation<Foo> : public coclass<Foo, thread_model::Both, aggregates<Bar, IBar> >
|
|
||||||
\endcode
|
|
||||||
(Sofus Mortensen)
|
|
||||||
\li Added cmp method to bstr_base which a.o.t. can be configured for case insensitive comparision. (Michael Geddes)
|
|
||||||
\li Added comparison functors based on cmp to bstr_base, less, less_equal, equal_to, etc. Example of usage:
|
|
||||||
\code
|
|
||||||
std::set<bstr_t, bstr_t::less<cf_ignore_case> > mySet;
|
|
||||||
\endcode
|
|
||||||
(Sofus Mortensen)
|
|
||||||
\li Fixed bugs in assignment operators for datetime_t. (Sofus Mortensen, Mikael Lindgren)
|
|
||||||
\li In ptr.h changed COMET_ALLOW_DECLSPEC_PROPERTY to COMET_USE_RAW_WRAPPERS. (Michael Geddes)
|
|
||||||
\li In common.h added workaround for VARIANT_TRUE resulting in a level 4 warning. (Michael Geddes)
|
|
||||||
\li Changed server.h, so that a compiler error will occur if there are unimplemented coclasses. In case you deliberately want
|
|
||||||
unimplemented coclass define COMET_ALLOW_UNIMPLEMENTED_COCLASSES in std.h. (Sofus Mortensen)
|
|
||||||
\li Added various helper functions to util.h. (Sofus Mortensen)
|
|
||||||
\li Added support for aggregating the free threaded marshaler. Example:
|
|
||||||
\code
|
|
||||||
template<> coclass_implementation<Foo> : public coclass<Foo, thread_model::Both, FTM>
|
|
||||||
\endcode
|
|
||||||
(Sofus Mortensen)
|
|
||||||
\li Various bug fixes and changes. (Sofus Mortensen)
|
|
||||||
|
|
||||||
\par Version 1 beta 9 (2001-9-23)
|
|
||||||
|
|
||||||
\li Now wrapper properties and methods are only available through com_ptr::operator->. (Sofus Mortensen)
|
|
||||||
\li Added ostream<> outputting facility to both variant_t and bstr_t. (Sofus Mortensen)
|
|
||||||
\li Added std::string conversions to variant_t. (Sofus Mortensen)
|
|
||||||
\li Fixed various bugs in tlb2h regarding dispinterfaces. (Sofus Mortensen).
|
|
||||||
\li Fixed bug in com_ptr - try_cast'ing from variant_t to com_ptr did not throw an exception on error. (Sofus Mortensen)
|
|
||||||
\li Made com_ptr constructor from variant_t and assignment from variant_t private in com_ptr to prevent misuse. Use com_cast or try_cast. (Sofus Mortensen)
|
|
||||||
|
|
||||||
\par Version 1 beta 8 (2001-9-19)
|
|
||||||
|
|
||||||
\li Fixed bugs in tlb2h regarding datetime_t. (Sofus Mortensen)
|
|
||||||
\li Wrapper properties are now only available when accessing an interface through com_ptr::operator->. (Sofus Mortensen)
|
|
||||||
\li Classes currency_t and datetime_t are now exception safe. (Sofus Mortensen)
|
|
||||||
\li Added conversions for variant_t from/to currency_t and datetime_t. (Sofus Mortensen)
|
|
||||||
\li Added conversions for std::wstring to variant_t, solving various ambiguity problems. (Sofus Mortensen)
|
|
||||||
\li Re-arranged various header files, solving include problems. (Sofus Mortensen)
|
|
||||||
|
|
||||||
\par Version 1 beta 7 (2001-9-7)
|
|
||||||
|
|
||||||
\li Added support for locking to safearray_t. (Michael Geddes)
|
|
||||||
\li Improved support in tlb2h for methods taking arrays as argument. (Sofus Mortensen)
|
|
||||||
\li Fixed bug in tlb2h regarding methods that were the parameters were wrongly given a default value. (Sofus Mortensen)
|
|
||||||
\li Fixed bug in tlb2h regarding type "void *". (Sofus Mortensen)
|
|
||||||
\li Fixed various bugs in datetime.h. (Michael Geddes)
|
|
||||||
\li Added COMET_ASSERT - a replacement for _ASSERTE. (Sofus Mortensen)
|
|
||||||
|
|
||||||
\par Version 1 beta 6 take 2 (2001-8-20)
|
|
||||||
|
|
||||||
\li Fixed dumb, dumb _ASSERTE bug in tlb2h (Sofus Mortensen).
|
|
||||||
|
|
||||||
\par Version 1 beta 6 (2001-8-19)
|
|
||||||
|
|
||||||
\li Changed distribution package - now including scripts for generating docs and the source for both tlb2h and the Comet App. wizard (Sofus Mortensen).
|
|
||||||
\li Wrapped string constant in server.h with _T( ) for UNICODE compatibility (Sofus Mortensen).
|
|
||||||
\li Tlb2h.exe now generates vtable fillers to cater for interfaces with gaps in the vtable. Such are typically produced by VB (Michael Geddes and Sofus Mortensen).
|
|
||||||
\li Bug fixes to date_t (Michael Geddes).
|
|
||||||
\li Elimination of compiler warnings in safearray_t and registry.h (Michael Geddes).
|
|
||||||
|
|
||||||
\par Version 1 beta 5 (2001-8-14)
|
|
||||||
|
|
||||||
\li tlb2h.exe now generates corrects defaults for [optional] VARIANT. variant_t has been updated in order to support this (Sofus Mortensen).
|
|
||||||
\li Fixed problem in tlb2h.exe with using COMET_ALLOW_DECLSPEC_PROPERTY when importing msado20.tlb (Sofus Mortensen).
|
|
||||||
\li Fixed problem in tlb2h.exe with aliases being treated as records (Michael Geddes).
|
|
||||||
\li Several bug fixes to nutshell generation (Michael Geddes).
|
|
||||||
\li Changed tlb2h, so that the generated headers only #include the headers needed (Michael Geddes).
|
|
||||||
|
|
||||||
\par Version 1 beta 4 (2001-7-25)
|
|
||||||
|
|
||||||
\li datetime_t has been updated and support for datetime_t has been added to tlb2h.exe (Michael Geddes).
|
|
||||||
\li typelist::index_of bug fix (Michael Geddes, Sofus Mortensen, thanks to Eric Friedman for reporting this).
|
|
||||||
\li typelist::type_at bug fix (Michael Geddes).
|
|
||||||
\li create_reference added to safearray_t (Michael Geddes).
|
|
||||||
\li Experimental attach_from / attach_to added to safearray_t (Michael Geddes).
|
|
||||||
\li Bug fix in variant.h (Sofus Mortensen).
|
|
||||||
|
|
||||||
\par Version 1 beta 3 (2001-7-14)
|
|
||||||
|
|
||||||
\li MSVC7 beta 2 compatibility fixes (Sofus Mortensen).
|
|
||||||
\li Various bug fixes in tlb2h (Sofus Mortensen).
|
|
||||||
\li Added wizard option to tlb2h for generating skeleton implementation of coclasses (Michael Geddes).
|
|
||||||
\li Various bug fixes to safearray.h (Michael Geddes).
|
|
||||||
\li variant_t now supports converion to/from saferray_t (Michael Geddes, Sofus Mortensen)
|
|
||||||
\li com_ptr can now be used to wrap a pointer to coclass_implementation (Michael Geddes).
|
|
||||||
\li enum.h and cp.h has been updated to support the changes to com_ptr (Michael Geddes).
|
|
||||||
\li Preliminary version of datetime_t has been added (Michael Geddes).
|
|
||||||
|
|
||||||
\par Version 1 beta 2 (2001-7-04)
|
|
||||||
|
|
||||||
\li Major documentation update (Michael Geddes).
|
|
||||||
\li Bug fix in tlb2h.cpp (Michael Geddes).
|
|
||||||
\li Replaced operator bool in com_ptr with a more bullet proof alternative (Sofus Mortensen).
|
|
||||||
\li Updated functor.h to make use of partial specialisation for compilers that support it (Michael Geddes).
|
|
||||||
|
|
||||||
\par Version 1 beta 1 (2001-6-29)
|
|
||||||
|
|
||||||
\li Added currency support to variant_t (Michael Geddes).
|
|
||||||
\li Documentation update for server.h (Michael Geddes).
|
|
||||||
\li Various bug fixes to do with agg-objects (Michael Geddes).
|
|
||||||
\li Added GetClassObject implementation to atl_module (Michael Geddes).
|
|
||||||
|
|
||||||
|
|
||||||
\par Version 1 alpha 10 (2001-6-26):
|
|
||||||
|
|
||||||
\li CURRENCY wrapper updated by Michael Geddes.
|
|
||||||
\li tlb2h has been updated by Michael Geddes (again!). This time with options to specify which namespace to put wrappers in, and an options to emit symbols only for faster compilation.
|
|
||||||
\li atl_module.h documentation updated by Michael Geddes.
|
|
||||||
|
|
||||||
\par Version 1 alpha 9 (2001-6-21):
|
|
||||||
|
|
||||||
\li CURRENCY wrapper added by Michael Geddes.
|
|
||||||
\li Nutshell wrappers didn't work in alpha 8. Now fixed.
|
|
||||||
\li tlb2h has been updated by Michael Geddes for better command line handling. It now supports multiple files including wildcards, and support for specifying an output directory.
|
|
||||||
\li Server implementation updated by Michael Geddes to support loading type libraries that has not yet been registered.
|
|
||||||
\li try_cast no longer throws on null pointers, and comet::com_ptr::operator->() now throws on null pointers. (Michael Geddes)
|
|
||||||
|
|
||||||
\par Version 1 alpha 8 (2001-6-10):
|
|
||||||
|
|
||||||
\li Compatibility patches for GCC/MINGW submitted by Michael Geddes.
|
|
||||||
\li Updated com_error with methods for accessing wrapped HRESULT value and IErrorInfo (source, helpfile, etc).
|
|
||||||
\li Various minor bug fixes.
|
|
||||||
|
|
||||||
\par Version 1 alpha 7 take 3 (2001-3-31):
|
|
||||||
|
|
||||||
\li Added converters for CURRENCY to variant_t..
|
|
||||||
\li Updated functor.h.
|
|
||||||
|
|
||||||
\par Version 1 alpha 7 take 2 (2001-3-28):
|
|
||||||
|
|
||||||
\li Fixed bug concerning using com_cast and try_cast with raw interface pointers.
|
|
||||||
\li Fixed bug in bstr.h
|
|
||||||
\li Fixed dependency on comet/stl.h in comet/enum.h
|
|
||||||
|
|
||||||
|
|
||||||
\par Version 1 alpha 7 take 1 (2001-3-26):
|
|
||||||
|
|
||||||
\li Support for dispinterfaces has been added by Michael Geddes and Mikael Lindgren.
|
|
||||||
\li BCC compatibility patches contributed by Michael Geddes.
|
|
||||||
\li Support for multiple connection points added by Michael Geddes.
|
|
||||||
\li Added generalised functor library that works with MSVC (Not really COM related)
|
|
||||||
\li comet::make_list\<\> has changed behaviour. Instead of writing make_list\<IFoo, IBar\>, you have to write \link comet::make_list make_list\<IFoo,IBar\>::result \endlink. This has been done in order to shorten error messages relating typelists.
|
|
||||||
\li Added several helper classes to comet/typelist.h for manipulation of typelists.
|
|
||||||
\li Fixed various "ambiguous conversion" errors
|
|
||||||
|
|
||||||
|
|
||||||
\par Version 1 alpha 6 (2001-3-7):
|
|
||||||
|
|
||||||
\li Fixed disastrous bug in comet::com_ptr.
|
|
||||||
\li Re-organisation of header files.
|
|
||||||
\li Support for Intel C++ 5.0 added.
|
|
||||||
\li Fixed bug in regkey.
|
|
||||||
\li Various bugs fixes.
|
|
||||||
|
|
||||||
|
|
||||||
\par Version 1 alpha 5 take 2 (2001-1-26):
|
|
||||||
|
|
||||||
\li Fixed bug in ptr.h
|
|
||||||
|
|
||||||
|
|
||||||
\par Version 1 alpha 5 (2001-1-16):
|
|
||||||
|
|
||||||
\li Support for implementing aggregateable components. (Michael Geddes)
|
|
||||||
\li comet::com_ptr is no longer using common base class.
|
|
||||||
\li Various bug fixes.
|
|
||||||
|
|
||||||
|
|
||||||
\par Version 1 alpha 4.2 (2000-12-17):
|
|
||||||
|
|
||||||
\li Fixed bug in critical_section.
|
|
||||||
|
|
||||||
|
|
||||||
\par Version 1 alpha 4.1 (2000-12-14):
|
|
||||||
|
|
||||||
\li Fixed bug in variant.h
|
|
||||||
\li Added support for DATE and CURRENCY to tlb2h. (We might need wrapper classes for those).
|
|
||||||
\li Fixed missing inline in common.h.
|
|
||||||
|
|
||||||
|
|
||||||
\par Version 1 alpha 4 (2000-12-12):
|
|
||||||
|
|
||||||
\li Generated wrappers, interfaces, etc are now placed in namespace corresponding to typelibrary name by tlb2h.
|
|
||||||
\li Fixed bugs in variant.h
|
|
||||||
\li The generated wrappers are no longer using .get_raw() and .get_raw_ptr(). Instead the wrapper methods .in(), .in_ptr(), .inout() and .out() are being used.
|
|
||||||
\li Support for constants placed in type library modules. (See Joav Kohn's posting on ATL discuss).
|
|
||||||
\li Support for version numbering for ProgID's. (Thanks to Mikael Lindgren).
|
|
||||||
\li Updated the wizard.
|
|
||||||
|
|
||||||
|
|
||||||
\par Version 1 alpha 3 (2000-11-29):
|
|
||||||
|
|
||||||
\li Added sanity checking to safearray_t to capture type mismatches.
|
|
||||||
\li Added in() method to all wrapper classes for use when calling raw interfaces.
|
|
||||||
\li The generated header files are now using a normal include guard instead of #pragma once.
|
|
||||||
\li Various minor fixes.
|
|
||||||
|
|
||||||
|
|
||||||
\par Version 1 alpha 2 (2000-11-20):
|
|
||||||
|
|
||||||
\li Nutshell generation added to tlb2h.exe.
|
|
||||||
\li Added STL compatible SAFEARRAY wrapper called comet::safearray_t<T>.
|
|
||||||
\li Updated registry class.
|
|
||||||
\li New BSTR wrapper, comet::bstr<boolean> with optional reference counting.
|
|
||||||
\li comet::bstr_t is now a typedef of comet::bstr<false>.
|
|
||||||
\li ATL support added.
|
|
||||||
|
|
||||||
|
|
||||||
\par Version 1 alpha 1 (2000-10-29):
|
|
||||||
|
|
||||||
\li First alpha release of Comet.
|
|
||||||
|
|
||||||
|
|
||||||
\par Version 0.9.7 (2000-10-19):
|
|
||||||
|
|
||||||
\li typedef bug fix in tlb2h.exe
|
|
||||||
\li Bug fixes in comet::variant_t
|
|
||||||
|
|
||||||
|
|
||||||
\par Version 0.9.6 (2000-10-19):
|
|
||||||
|
|
||||||
\li Documentation updates.
|
|
||||||
\li Misc. bug fixes.
|
|
||||||
|
|
||||||
|
|
||||||
\par Version 0.9.5 (2000-10-5):
|
|
||||||
|
|
||||||
\li Documentation updates.
|
|
||||||
\li Paul Hollingsworth has been busy minimising include dependencies in the header files.
|
|
||||||
\li Added [out] and [in, out] adapters for dealing with raw interfaces.
|
|
||||||
|
|
||||||
|
|
||||||
\par Version 0.9.4 (2000-10-4):
|
|
||||||
|
|
||||||
\li Fixed more bugs in comet::com_ptr.
|
|
||||||
\li Added documentation on comet::com_ptr.
|
|
||||||
|
|
||||||
|
|
||||||
\par Version 0.9.3 (2000-9-26):
|
|
||||||
|
|
||||||
\li Fixed various bugs in comet::com_ptr.
|
|
||||||
|
|
||||||
|
|
||||||
\par Version 0.9.2 (2000-9-25):
|
|
||||||
|
|
||||||
\li Updated tlb2h to use const where appropiate.
|
|
||||||
\li Added support for unions.
|
|
||||||
\li Added support for one-dimensional arrays in structs.
|
|
||||||
|
|
||||||
|
|
||||||
\par Version 0.9.1 (2000-9-21):
|
|
||||||
|
|
||||||
\li Experimental support in tlb2h.exe for optional method arguments (ie. attribue optional or defaultvalue).
|
|
||||||
|
|
||||||
|
|
||||||
\par Version 0.9.0 (2000-9-19):
|
|
||||||
|
|
||||||
\li Paul Hollingsworth has contributed automatic implementation of IProvideClassInfo.
|
|
||||||
\li Better support for [in, out] parameters.
|
|
||||||
\li Fixed bugs in tlb2h's generation of connection point wrapper.
|
|
||||||
\li Removed progid from template parameters, instead override function get_progid().
|
|
||||||
\li Added version metadata to coclass and typelibrary wrappers.
|
|
||||||
\li Fixed bug in variant_t::variant_t(const comet::bstr_t&).
|
|
||||||
|
|
||||||
|
|
||||||
\par Version 0.8.3 (2000-9-12):
|
|
||||||
|
|
||||||
\li Removed DLL dependency for tlb2h.exe.
|
|
||||||
|
|
||||||
|
|
||||||
\par Version 0.8.2 (2000-9-7):
|
|
||||||
|
|
||||||
\li com_error / raise_exception_t has been revised.
|
|
||||||
\li Fixed bug in com_ptr::operator=(int)
|
|
||||||
\li Rearranged header inclusion introducing error_fwd.h.
|
|
||||||
\li Added misc. utility classes not necessarily related to tlb2h to tlb2h/utility.h.
|
|
||||||
\li Updated tlb2h.exe with more types.
|
|
||||||
|
|
||||||
|
|
||||||
\par Version 0.8.1 (2000-9-3):
|
|
||||||
|
|
||||||
\li Type conversions to/from bstr_t has been changed/tweaked.
|
|
||||||
\li bstr_t now supports concatenation through operator+ and operator+=.
|
|
||||||
|
|
||||||
|
|
||||||
\par Version 0.8.0 (2000-8-31):
|
|
||||||
|
|
||||||
\li Fixed several bugs in tlb2h.exe.
|
|
||||||
\li Added misc. utility classes not necessarily related to tlb2h to tlb2h/utility.h.
|
|
||||||
|
|
||||||
|
|
||||||
\par Version 0.7.10 (2000-8-25):
|
|
||||||
|
|
||||||
\li Updated AppWizard to generate uuid for type library.
|
|
||||||
\li Added trait class to com_server for servers with no embedded type library.
|
|
||||||
|
|
||||||
|
|
||||||
\par Version 0.7.9 (2000-8-21):
|
|
||||||
|
|
||||||
\li bstr_t is now capable of converting to std::string as well.
|
|
||||||
\li Rearranged util.h into list.h, common.h and util.h.
|
|
||||||
|
|
||||||
|
|
||||||
\par Version 0.7.8 (2000-8-18):
|
|
||||||
|
|
||||||
\li Added simple AppWizard for creating DLL projects.
|
|
||||||
\li Removed untie. Instead embedded_object now has a release_from_owner method.
|
|
||||||
\li structs defined in type libraries now automatically use CoTaskMem when using new/delete.
|
|
||||||
|
|
||||||
|
|
||||||
\par Version 0.7.7 (2000-8-15):
|
|
||||||
|
|
||||||
\li Changes to lifetime of embedded_object. Introducing tlb2h::untie, breaks tie between owner and embedded_object, so that the embedded_object can be destroyed before the owner.
|
|
||||||
|
|
||||||
|
|
||||||
\par Version 0.7.6 (2000-8-15):
|
|
||||||
|
|
||||||
\li Various changes to comet::bstr_t.
|
|
||||||
|
|
||||||
|
|
||||||
\par Version 0.7.5 (2000-8-13):
|
|
||||||
|
|
||||||
\li Interface inheritance problems solved.
|
|
||||||
\li Problem with [in] VARIANT arguments solved.
|
|
||||||
\li create_enum now works with embedded_objects.
|
|
||||||
\li comet::make_list now handles up to 40 elements.
|
|
||||||
\li Problem with IUnknown interfaces in coclasses solved.
|
|
||||||
\li Workaround for bug in Visual Studio editor causing VS to crash when editing certain template code.
|
|
||||||
|
|
||||||
|
|
||||||
\par Version 0.7.4 (2000-8-8):
|
|
||||||
|
|
||||||
\li Conversion from comet::com_ptr to comet::variant_t improved.
|
|
||||||
\li Updated example to demonstrate now working COM enumeration implementation on STL containers.
|
|
||||||
|
|
||||||
|
|
||||||
\par Version 0.7.3 (2000-8-8):
|
|
||||||
|
|
||||||
\li Nasty connection point bug fixed.
|
|
||||||
\li Added trivial VB client example program demonstrating connection point.
|
|
||||||
\li Added com_cast and try_cast for casting interface pointers. Implicit casting no longer allowed.
|
|
||||||
\li comet::com_error::what() is now working.
|
|
||||||
\li Misc. minor bug fixes/tweaks.
|
|
||||||
|
|
||||||
|
|
||||||
\par Version 0.7.2 (2000-8-3):
|
|
||||||
|
|
||||||
\li Updated the example with registration custom build.
|
|
||||||
\li Misc. bug fixes.
|
|
||||||
|
|
||||||
*/
|
|
||||||
//! Primary namespace for comet. Includes source and libraries.
|
|
||||||
namespace comet {
|
|
||||||
//! Namespace for comet implementation details.
|
|
||||||
/*! \internal
|
|
||||||
*/
|
|
||||||
namespace impl {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/** \defgroup Misc Miscelaneous utility classes.
|
|
||||||
*@{
|
|
||||||
*/
|
|
||||||
//@}
|
|
||||||
/** \defgroup COMType Com type wrappers.
|
|
||||||
*@{
|
|
||||||
*/
|
|
||||||
//@}
|
|
||||||
/*!\defgroup WinUtil Windows utility classes.
|
|
||||||
*@{
|
|
||||||
*/
|
|
||||||
//@}
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,316 +0,0 @@
|
||||||
/** \file
|
|
||||||
* Common utility classes wrappers.
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* Copyright © 2000, 2001 Sofus Mortensen
|
|
||||||
*
|
|
||||||
* This material is provided "as is", with absolutely no warranty
|
|
||||||
* expressed or implied. Any use is at your own risk. Permission to
|
|
||||||
* use or copy this software for any purpose is hereby granted without
|
|
||||||
* fee, provided the above notices are retained on all copies.
|
|
||||||
* Permission to modify the code and to distribute modified code is
|
|
||||||
* granted, provided the above notices are retained, and a notice that
|
|
||||||
* the code was modified is included with the above copyright notice.
|
|
||||||
*
|
|
||||||
* This header is part of Comet version 2.
|
|
||||||
* https://github.com/alamaison/comet
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef COMET_COMMON_H
|
|
||||||
#define COMET_COMMON_H
|
|
||||||
|
|
||||||
#include <comet/config.h>
|
|
||||||
#include <comet/interface.h>
|
|
||||||
#include <wtypes.h>
|
|
||||||
|
|
||||||
namespace comet {
|
|
||||||
|
|
||||||
class uuid_t;
|
|
||||||
template<typename Itf>class com_ptr;
|
|
||||||
namespace impl {
|
|
||||||
template<typename T> T* bad_alloc_check(T* x)
|
|
||||||
{
|
|
||||||
if (!x) throw std::bad_alloc();
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Implementation struct for auto_attach.
|
|
||||||
* \internal
|
|
||||||
*/
|
|
||||||
template<typename T> class auto_attach_t
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit auto_attach_t(const T& v) : val_(v) {};
|
|
||||||
const T& get() const { return val_; }
|
|
||||||
private:
|
|
||||||
const T& val_;
|
|
||||||
auto_attach_t& operator=(const auto_attach_t&);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Forward declare all these - only used if we actually WANT a
|
|
||||||
// safearray.
|
|
||||||
/** Safearray traits for the given type.
|
|
||||||
* \internal
|
|
||||||
*/
|
|
||||||
template<typename T> struct sa_traits;
|
|
||||||
/** Safearray iterator for the given type.
|
|
||||||
* \internal
|
|
||||||
*/
|
|
||||||
template<typename S,typename T> class sa_iterator;
|
|
||||||
/** Safearray const traits for the given type.
|
|
||||||
* \internal
|
|
||||||
*/
|
|
||||||
template<typename T> struct const_traits;
|
|
||||||
/** Safearray non-const traits for the given type.
|
|
||||||
* \internal
|
|
||||||
*/
|
|
||||||
template<typename T> struct nonconst_traits;
|
|
||||||
|
|
||||||
enum sa_traits_check_type { stct_features_ok, stct_vt_ok, stct_iid_ok };
|
|
||||||
enum sa_traits_extras_type { stet_null, stet_record, stet_iid };
|
|
||||||
|
|
||||||
// Interface traits are needed by all interfaces so that we can create
|
|
||||||
// safearrays of the types.
|
|
||||||
template<typename INTERFACE, VARTYPE VT, long FEATURE_FLAG>
|
|
||||||
struct interface_sa_traits
|
|
||||||
{
|
|
||||||
enum { vt = VT };
|
|
||||||
enum { check_type = stct_iid_ok };
|
|
||||||
enum { extras_type = stet_iid };
|
|
||||||
|
|
||||||
typedef INTERFACE* raw;
|
|
||||||
typedef com_ptr<INTERFACE> value_type;
|
|
||||||
typedef com_ptr<INTERFACE> & reference;
|
|
||||||
typedef const com_ptr<INTERFACE> & const_reference;
|
|
||||||
|
|
||||||
static reference create_reference(raw& x) { return *reinterpret_cast<com_ptr< INTERFACE>*>(&x); }
|
|
||||||
static const_reference create_const_reference(raw& x) { return *reinterpret_cast<const com_ptr< INTERFACE >*>(&x); }
|
|
||||||
typedef nonconst_traits<com_ptr<INTERFACE> > nct;
|
|
||||||
typedef sa_iterator<com_ptr<INTERFACE>, nct > iterator;
|
|
||||||
typedef sa_iterator<com_ptr<INTERFACE>, const_traits<com_ptr<INTERFACE> > > const_iterator;
|
|
||||||
|
|
||||||
static bool are_features_ok(unsigned short f) { return (f & FEATURE_FLAG) != 0 && (f & FADF_HAVEIID) != 0; }
|
|
||||||
static const uuid_t& iid() { return uuidof<INTERFACE>(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Basic safearray traits - used by enums.
|
|
||||||
* \internal
|
|
||||||
*/
|
|
||||||
template<typename T, VARTYPE VT> struct basic_sa_traits
|
|
||||||
{
|
|
||||||
enum { vt = VT };
|
|
||||||
enum { check_type = stct_vt_ok };
|
|
||||||
enum { extras_type = stet_null };
|
|
||||||
|
|
||||||
typedef T raw;
|
|
||||||
typedef T value_type;
|
|
||||||
typedef T& reference;
|
|
||||||
typedef const T& const_reference;
|
|
||||||
|
|
||||||
static reference create_reference(T& x) { return x; }
|
|
||||||
static const_reference create_const_reference(T& x) { return x; }
|
|
||||||
|
|
||||||
typedef T* iterator;
|
|
||||||
typedef const T* const_iterator;
|
|
||||||
|
|
||||||
static bool are_features_ok(unsigned short) { return true; }
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! \addtogroup COMType
|
|
||||||
*/
|
|
||||||
//@{
|
|
||||||
/// Used to attach a raw parameter to a wrapper.
|
|
||||||
template<typename T> impl::auto_attach_t<T> auto_attach(const T& t) { return impl::auto_attach_t<T>(t); }
|
|
||||||
|
|
||||||
|
|
||||||
// template<typename T, typename U> inline T up_cast(const U& u, T* = 0) { return u; }
|
|
||||||
|
|
||||||
|
|
||||||
/*! VARIANT_BOOL to bool [in] converter.
|
|
||||||
* This is used by the generated wrappers.
|
|
||||||
*/
|
|
||||||
inline VARIANT_BOOL bool_in(bool x) { return x ? COMET_VARIANT_TRUE : COMET_VARIANT_FALSE; }
|
|
||||||
|
|
||||||
/** \class bool_out common.h comet/common.h
|
|
||||||
* VARIANT_BOOL to bool [out] converter.
|
|
||||||
* This is used by the generated wrappers.
|
|
||||||
*/
|
|
||||||
class bool_out {
|
|
||||||
public:
|
|
||||||
operator VARIANT_BOOL*() { return &vb_; }
|
|
||||||
bool_out(bool& b) : b_(b) {}
|
|
||||||
~bool_out() { b_ = vb_ ? true : false; }
|
|
||||||
private:
|
|
||||||
bool_out &operator=( const bool_out &);
|
|
||||||
VARIANT_BOOL vb_;
|
|
||||||
bool& b_;
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace impl {
|
|
||||||
class bool_adapter_t {
|
|
||||||
public:
|
|
||||||
bool_adapter_t(VARIANT_BOOL* p) : pb_(p) { b_ = *pb_ ? true : false; }
|
|
||||||
~bool_adapter_t() { *pb_ = b_ ? COMET_VARIANT_TRUE : COMET_VARIANT_FALSE; }
|
|
||||||
|
|
||||||
bool& ref() { return b_; }
|
|
||||||
private:
|
|
||||||
bool_adapter_t(const bool_adapter_t&);
|
|
||||||
bool_adapter_t& operator=(const bool_adapter_t&);
|
|
||||||
|
|
||||||
VARIANT_BOOL* pb_;
|
|
||||||
bool b_;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \class bool_inout common.h comet/common.h
|
|
||||||
* VARIANT_BOOL to bool [in,out] converter.
|
|
||||||
* This is used by the generated wrappers.
|
|
||||||
*/
|
|
||||||
class bool_inout {
|
|
||||||
public:
|
|
||||||
operator VARIANT_BOOL*() { return &vb_; }
|
|
||||||
bool_inout(bool& b) : b_(b), vb_(b ? COMET_VARIANT_TRUE : COMET_VARIANT_FALSE) {}
|
|
||||||
~bool_inout() { b_ = vb_ ? true : false; }
|
|
||||||
private:
|
|
||||||
bool_inout &operator=(const bool_inout &);
|
|
||||||
VARIANT_BOOL vb_;
|
|
||||||
bool& b_;
|
|
||||||
};
|
|
||||||
|
|
||||||
/** \class variant_bool_t common.h comet/common.h
|
|
||||||
* VARIANT_BOOL wrapper for structs.
|
|
||||||
* Stands in place of a VARIANT_BOOL in a struct, and behaves like a bool.
|
|
||||||
* This is imporant as sizeof(VARIANT_BOOL) != sizeof(bool).
|
|
||||||
*/
|
|
||||||
class variant_bool_t
|
|
||||||
{
|
|
||||||
VARIANT_BOOL vb_;
|
|
||||||
public:
|
|
||||||
/// \name Constructors.
|
|
||||||
//@{
|
|
||||||
variant_bool_t(): vb_(COMET_VARIANT_FALSE) {}
|
|
||||||
variant_bool_t(const impl::auto_attach_t<VARIANT_BOOL> &b) : vb_(b.get()) {}
|
|
||||||
variant_bool_t(bool b) : vb_(b?COMET_VARIANT_TRUE:COMET_VARIANT_FALSE) {}
|
|
||||||
//@}
|
|
||||||
|
|
||||||
/// \name Assignment operators.
|
|
||||||
//@{
|
|
||||||
variant_bool_t &operator=( bool b) { vb_ = b?COMET_VARIANT_TRUE:COMET_VARIANT_FALSE; return *this;}
|
|
||||||
variant_bool_t &operator=( const impl::auto_attach_t<VARIANT_BOOL> &b) { vb_ = b.get(); return *this; }
|
|
||||||
//@}
|
|
||||||
|
|
||||||
/// \name Boolean operators.
|
|
||||||
//@{
|
|
||||||
operator bool() const{ return vb_!= COMET_VARIANT_FALSE; }
|
|
||||||
bool operator !() const { return vb_== COMET_VARIANT_FALSE; }
|
|
||||||
bool operator==( variant_bool_t vb) const { return vb.vb_ == vb_; }
|
|
||||||
bool operator!=( variant_bool_t vb) const { return vb.vb_ != vb_; }
|
|
||||||
//@}
|
|
||||||
|
|
||||||
/// \name Bitwise operators
|
|
||||||
//@{
|
|
||||||
variant_bool_t operator~() const { variant_bool_t temp(*this); temp.vb_ = (VARIANT_BOOL)~(temp.vb_); return temp; }
|
|
||||||
variant_bool_t &operator&=( const variant_bool_t &b) { vb_ &= b.vb_; return *this; }
|
|
||||||
variant_bool_t &operator|=( const variant_bool_t &b) { vb_ |= b.vb_; return *this; }
|
|
||||||
variant_bool_t &operator^=( const variant_bool_t &b) { vb_ ^= b.vb_; return *this; }
|
|
||||||
variant_bool_t operator&( const variant_bool_t &b)const { variant_bool_t temp(*this); temp.vb_ &= b.vb_; return temp; }
|
|
||||||
variant_bool_t operator|( const variant_bool_t &b)const { variant_bool_t temp(*this); temp.vb_ |= b.vb_; return temp; }
|
|
||||||
variant_bool_t operator^( const variant_bool_t &b)const { variant_bool_t temp(*this); temp.vb_ ^= b.vb_; return temp; }
|
|
||||||
//@}
|
|
||||||
/// \name bool operators
|
|
||||||
//@{
|
|
||||||
bool operator&( bool b)const { return b & operator bool(); }
|
|
||||||
bool operator|( bool b)const { return b | operator bool(); }
|
|
||||||
bool operator^( bool b)const { return b ^ operator bool(); }
|
|
||||||
//@}
|
|
||||||
|
|
||||||
static const variant_bool_t &create_const_reference(const VARIANT_BOOL &vb) { return reinterpret_cast<const variant_bool_t &>(vb); }
|
|
||||||
static variant_bool_t &create_reference(VARIANT_BOOL &vb) { return reinterpret_cast<variant_bool_t &>(vb); }
|
|
||||||
|
|
||||||
///\name Raw accessors
|
|
||||||
//@{
|
|
||||||
VARIANT_BOOL in() { return vb_; }
|
|
||||||
VARIANT_BOOL *out() { return &vb_; }
|
|
||||||
VARIANT_BOOL *inout() { return &vb_; }
|
|
||||||
//@}
|
|
||||||
|
|
||||||
|
|
||||||
/** Allow treating of class as a bool *.
|
|
||||||
* \sa bool_ptr()
|
|
||||||
*/
|
|
||||||
class bool_pointer_t
|
|
||||||
{
|
|
||||||
friend class variant_bool_t;
|
|
||||||
protected:
|
|
||||||
bool_pointer_t( VARIANT_BOOL &vb) : vb_(vb), b_( vb != COMET_VARIANT_FALSE) {}
|
|
||||||
public:
|
|
||||||
~bool_pointer_t() { vb_ = b_ ? COMET_VARIANT_TRUE: COMET_VARIANT_FALSE; }
|
|
||||||
operator bool*(){ return &b_; }
|
|
||||||
operator const bool*()const{ return &b_; }
|
|
||||||
private:
|
|
||||||
bool_pointer_t &operator=(const bool_pointer_t &);
|
|
||||||
bool b_;
|
|
||||||
VARIANT_BOOL &vb_;
|
|
||||||
};
|
|
||||||
/** Return a class that stands in for a bool *.
|
|
||||||
Should be used in place of operator & for passing in to a bool * function.
|
|
||||||
\code
|
|
||||||
variant_bool_t vb;
|
|
||||||
SomeFunc(vb.bool_ptr());
|
|
||||||
\endcode
|
|
||||||
*/
|
|
||||||
bool_pointer_t bool_ptr()
|
|
||||||
{
|
|
||||||
return bool_pointer_t(vb_);
|
|
||||||
}
|
|
||||||
const bool_pointer_t bool_ptr() const
|
|
||||||
{
|
|
||||||
return bool_pointer_t(const_cast<VARIANT_BOOL &>(vb_));
|
|
||||||
}
|
|
||||||
|
|
||||||
friend class bool_reference_t;
|
|
||||||
/** Allow efficient choosing between a bool& and a variant_bool&.
|
|
||||||
*/
|
|
||||||
class bool_reference_chooser_t
|
|
||||||
{
|
|
||||||
friend class variant_bool_t;
|
|
||||||
variant_bool_t &vbt_;
|
|
||||||
protected:
|
|
||||||
bool_reference_chooser_t(variant_bool_t &vbt):vbt_(vbt) {}
|
|
||||||
private:
|
|
||||||
bool_reference_chooser_t &operator=(const bool_reference_chooser_t &);
|
|
||||||
public:
|
|
||||||
inline operator variant_bool_t&() { return vbt_;}
|
|
||||||
inline operator const variant_bool_t&()const { return vbt_;}
|
|
||||||
};
|
|
||||||
/** Allow treating of a class as a bool &.
|
|
||||||
* \sa bool_ref()
|
|
||||||
*/
|
|
||||||
class bool_reference_t : protected bool_pointer_t
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
bool_reference_t( bool_reference_chooser_t &brc )
|
|
||||||
: bool_pointer_t(*static_cast<variant_bool_t&>(brc).inout())
|
|
||||||
{}
|
|
||||||
operator bool &(){ return tmp; /*return * (bool_pointer_t::operator bool*());*/ }
|
|
||||||
operator const bool &()const { return *(bool_pointer_t::operator const bool*()); }
|
|
||||||
bool tmp;
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Return a class that stands in for a bool & or a variant_bool_t &.
|
|
||||||
*/
|
|
||||||
bool_reference_chooser_t bool_ref()
|
|
||||||
{
|
|
||||||
return bool_reference_chooser_t(*this);
|
|
||||||
}
|
|
||||||
const bool_reference_chooser_t bool_ref() const
|
|
||||||
{
|
|
||||||
return bool_reference_chooser_t(const_cast<variant_bool_t &>(*this));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
//@}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,243 +0,0 @@
|
||||||
/** \file
|
|
||||||
* Included by all comet headers to provide compiler-specific
|
|
||||||
* configuration.
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* Copyright © 2000-2002 Sofus Mortensen
|
|
||||||
* Copyright (C) 2013 Alexander Lamaison <alexander.lamaison@gmail.com>
|
|
||||||
*
|
|
||||||
* This material is provided "as is", with absolutely no warranty
|
|
||||||
* expressed or implied. Any use is at your own risk. Permission to
|
|
||||||
* use or copy this software for any purpose is hereby granted without
|
|
||||||
* fee, provided the above notices are retained on all copies.
|
|
||||||
* Permission to modify the code and to distribute modified code is
|
|
||||||
* granted, provided the above notices are retained, and a notice that
|
|
||||||
* the code was modified is included with the above copyright notice.
|
|
||||||
*
|
|
||||||
* This header is part of Comet version 2.
|
|
||||||
* https://github.com/alamaison/comet
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef COMET_CONFIG_H
|
|
||||||
#define COMET_CONFIG_H
|
|
||||||
|
|
||||||
#define COMET_MAJOR_VER 2
|
|
||||||
#define COMET_BUILDTYPE gamma
|
|
||||||
#define COMET_MINOR_VER 1
|
|
||||||
#define COMET_BUILD 20131017
|
|
||||||
|
|
||||||
#ifndef COMET_BUILD_VERSION_ONLY
|
|
||||||
|
|
||||||
#ifndef COMET_NO_DECLSPEC_PROPERTY
|
|
||||||
#define COMET_ALLOW_DECLSPEC_PROPERTY
|
|
||||||
#endif // COMET_NO_DECLSPEC_PROPERTY
|
|
||||||
|
|
||||||
#pragma warning(disable : 4786)
|
|
||||||
#pragma warning(disable : 4042)
|
|
||||||
#pragma warning(disable : 4290)
|
|
||||||
#pragma warning(disable : 4710)
|
|
||||||
|
|
||||||
#ifdef _lint // PC/Lint has a few problems with comet.
|
|
||||||
# if !defined(_MSC_VER) || _MSC_VER >= 1300
|
|
||||||
#define COMET_PARTIAL_SPECIALISATION
|
|
||||||
#else
|
|
||||||
|
|
||||||
#endif
|
|
||||||
#define COMET_NESTED_TEMPLATES
|
|
||||||
#define COMET_GOOD_RECURSIVE_STRUCT
|
|
||||||
#define COMET_CONST_MEMBER_INIT
|
|
||||||
#define COMET_GUID_BASE GUID
|
|
||||||
#define COMET_STD_ITERATOR
|
|
||||||
#define COMET_NO_POINTER_CHECKING
|
|
||||||
#define COMET_STD_SWAP_NOTHROW throw()
|
|
||||||
#define COMET_TL_TRUNC
|
|
||||||
#else
|
|
||||||
//VC 7.1 support partial specialization
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __ICL
|
|
||||||
# define COMET_PARTIAL_SPECIALISATION
|
|
||||||
# define COMET_NESTED_TEMPLATES
|
|
||||||
#else
|
|
||||||
# ifdef _MSC_VER
|
|
||||||
# if _MSC_VER < 1300
|
|
||||||
// Versions less than VC7 can't handle the rethrow & catch exception trick.
|
|
||||||
# define COMET_DISABLE_EXCEPTION_RETHROW_CATCH
|
|
||||||
# else // _MSC_VER >= 1300
|
|
||||||
# define COMET_GOOD_RECURSIVE_STRUCT
|
|
||||||
# define COMET_CONST_MEMBER_INIT
|
|
||||||
# if _MSC_VER >= 1310
|
|
||||||
# define COMET_PARTIAL_SPECIALISATION
|
|
||||||
# define COMET_NESTED_TEMPLATES
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# endif
|
|
||||||
#if defined(_UNICODE) && !defined(UNICODE)
|
|
||||||
#define UNICODE
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __BORLANDC__
|
|
||||||
#pragma warning(disable: 8027)
|
|
||||||
#pragma warning(disable: 8026)
|
|
||||||
#define COMET_PARTIAL_SPECIALISATION
|
|
||||||
#define COMET_NESTED_TEMPLATES
|
|
||||||
#define COMET_BROKEN_WTYPES
|
|
||||||
#define COMET_STD_ITERATOR
|
|
||||||
#define COMET_STD_SWAP_NOTHROW
|
|
||||||
|
|
||||||
#define COMET_GUID_BASE _GUID
|
|
||||||
#else
|
|
||||||
#define COMET_STD_SWAP_NOTHROW throw()
|
|
||||||
#define COMET_GUID_BASE GUID
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __CYGWIN__
|
|
||||||
#define COMET_PARTIAL_SPECIALISATION
|
|
||||||
#define COMET_NESTED_TEMPLATES
|
|
||||||
#define COMET_GCC_HEADERS
|
|
||||||
#define COMET_STD_ITERATOR
|
|
||||||
#define COMET_TL_TRUNC
|
|
||||||
#define _T(x) x
|
|
||||||
|
|
||||||
// This is not a good idea
|
|
||||||
// Routines that use _alloca has to be rewritten for __MINGW32__ targets.
|
|
||||||
// #define _alloca malloc
|
|
||||||
|
|
||||||
// WIN32 defines for GCC
|
|
||||||
#define NONAMELESSUNION
|
|
||||||
#define NOCOMATTRIBUTE
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
// Use COMET_STRICT_TYPENAME only where MSVC barfs on stricter typename usage
|
|
||||||
// required by GCC.
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#if _MSC_VER <= 1300
|
|
||||||
#define COMET_STRICT_TYPENAME
|
|
||||||
#else
|
|
||||||
#define COMET_STRICT_TYPENAME typename
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
#define COMET_STRICT_TYPENAME typename
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// PRH Feb 26 2001
|
|
||||||
// Try and determine which version of std::iterator we have.
|
|
||||||
// The ANSI/ISO compliant one seems to require a compiler
|
|
||||||
// that supports partial specialisation, as well as an
|
|
||||||
// ANSI/ISO compliant implementation of the library.
|
|
||||||
|
|
||||||
// Unfortunately, there is no __ANSI_STL #define.
|
|
||||||
// So we guess:
|
|
||||||
// If we have partial specialisation, and we're using STLPort, then
|
|
||||||
// its the ANSI/ISO std::iterator, otherwise it is the MSVC 6.0
|
|
||||||
// iterator.
|
|
||||||
|
|
||||||
// If you're using some other decent STL other than STLPort,
|
|
||||||
// then you'll need to reflect this by ensuring that COMET_STD_ITERATOR
|
|
||||||
// is defined.
|
|
||||||
|
|
||||||
#if _MSC_VER >= 1300 || defined(_CPPLIB_VER)
|
|
||||||
#define COMET_STD_ITERATOR
|
|
||||||
#else
|
|
||||||
#include <iterator>
|
|
||||||
#ifdef COMET_PARTIAL_SPECIALISATION
|
|
||||||
// this code to "detect" STLport is stolen from <boost/config.hpp>
|
|
||||||
//#if __SGI_STL_PORT >= 0x400 || __SGI_STL_PORT >= 0x321 && defined(__STL_USE_NAMESPACES)
|
|
||||||
#ifdef __SGI_STL
|
|
||||||
#define COMET_STD_ITERATOR
|
|
||||||
#else
|
|
||||||
#ifdef __MINGW32__
|
|
||||||
__STL_BEGIN_NAMESPACE
|
|
||||||
template <class _Tp, class _Distance>struct iterator: bidirectional_iterator<_Tp,_Distance>{};
|
|
||||||
__STL_END_NAMESPACE
|
|
||||||
#endif // __MINGW32__
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
#ifdef _CPPLIB_VER
|
|
||||||
#define COMET_STD_ITERATOR
|
|
||||||
#endif
|
|
||||||
#endif /* COMET_PARTIAL_SPECIALISATION */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef ATL_NO_VTABLE
|
|
||||||
#if _MSC_VER >= 1200
|
|
||||||
#define ATL_NO_VTABLE __declspec(novtable)
|
|
||||||
#else
|
|
||||||
#define ATL_NO_VTABLE
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if _MSC_VER <= 1200
|
|
||||||
//#define COMET_DO_NOT_SPECIALISE_SWAP_IN_STD
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Intel compiler version 500 sets _MSC_VER to 1200,
|
|
||||||
// but doesn't seem to like __forceinline
|
|
||||||
#if _MSC_VER >= 1200 && !defined(__ICL)
|
|
||||||
#define COMET_FORCEINLINE __forceinline
|
|
||||||
#else
|
|
||||||
#define COMET_FORCEINLINE inline
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef _UNICODE
|
|
||||||
#ifndef UNICODE
|
|
||||||
#define UNICODE // UNICODE is used by Windows headers
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef UNICODE
|
|
||||||
#ifndef _UNICODE
|
|
||||||
#define _UNICODE // _UNICODE is used by C-runtime/MFC headers
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Remove Microsoft's C++ macros
|
|
||||||
#undef variant_t
|
|
||||||
#undef bstr_t
|
|
||||||
#undef com_cast
|
|
||||||
|
|
||||||
// Stop subsequent includes of <comutil.h> from #defining variant_t or bstr_t
|
|
||||||
#ifndef _USE_RAW
|
|
||||||
#define _USE_RAW
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef UUID_DEFINED
|
|
||||||
#define UUID_DEFINED
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef UUID
|
|
||||||
#define UUID GUID
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef uuid_t
|
|
||||||
#undef uuid_t
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define COMET_DECLARE_SWAP(TYPE) template<> inline void swap(TYPE &x, TYPE &y)\
|
|
||||||
{\
|
|
||||||
x.swap(y);\
|
|
||||||
}
|
|
||||||
|
|
||||||
const unsigned short COMET_VARIANT_TRUE = (unsigned short)(0xffff);
|
|
||||||
const unsigned short COMET_VARIANT_FALSE = 0;
|
|
||||||
|
|
||||||
#define COMET_NOTUSED(x) x
|
|
||||||
#ifndef COMET_CONST_MEMBER_INIT
|
|
||||||
# define COMET_CONST_TYPE(vartype, varname,value) enum { varname = value };
|
|
||||||
# define COMET_CONST_GROUP enum {
|
|
||||||
# define COMET_CONST_ENTRY(vartype, varname,value) varname = value,
|
|
||||||
# define COMET_CONST_GROUP_END };
|
|
||||||
#else
|
|
||||||
# define COMET_CONST_TYPE(vartype, varname,value) static const vartype varname = value;
|
|
||||||
# define COMET_CONST_ENTRY(vartype, varname,value) COMET_CONST_TYPE(vartype, varname, value);
|
|
||||||
# define COMET_CONST_GROUP
|
|
||||||
# define COMET_CONST_GROUP_END
|
|
||||||
#endif
|
|
||||||
#endif // COMET_BUILD_VERSION_ONLY
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -1,436 +0,0 @@
|
||||||
/** \file
|
|
||||||
* Connection-point implementations.
|
|
||||||
* The thought behind the current implementation was to try and maintain
|
|
||||||
* connections points accessible from the coclass through the member
|
|
||||||
* connection_point.
|
|
||||||
*
|
|
||||||
* Where multiple connection-points are defined, the member is accessed thus:
|
|
||||||
* \code
|
|
||||||
* connection_point_for<IEventInterface>::connection_point
|
|
||||||
* \endcode
|
|
||||||
* The default connection point wrapper implementations have a prefix of
|
|
||||||
* \b Fire_ before the event name.
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* Copyright © 2000 Sofus Mortensen
|
|
||||||
*
|
|
||||||
* This material is provided "as is", with absolutely no warranty
|
|
||||||
* expressed or implied. Any use is at your own risk. Permission to
|
|
||||||
* use or copy this software for any purpose is hereby granted without
|
|
||||||
* fee, provided the above notices are retained on all copies.
|
|
||||||
* Permission to modify the code and to distribute modified code is
|
|
||||||
* granted, provided the above notices are retained, and a notice that
|
|
||||||
* the code was modified is included with the above copyright notice.
|
|
||||||
*
|
|
||||||
* This header is part of Comet version 2.
|
|
||||||
* https://github.com/alamaison/comet
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef COMET_CP_H
|
|
||||||
#define COMET_CP_H
|
|
||||||
|
|
||||||
#include <comet/config.h>
|
|
||||||
|
|
||||||
#include <map>
|
|
||||||
|
|
||||||
#include <comet/server.h>
|
|
||||||
#include <comet/enum.h>
|
|
||||||
|
|
||||||
#pragma warning( push )
|
|
||||||
#pragma warning( disable : 4355 )
|
|
||||||
|
|
||||||
/** \page cometconnectionpoints Connection Points.
|
|
||||||
\section cometconnectionpointssource Connction Point Source
|
|
||||||
Connection points provide events for comet, and rely on tlb2h (see \ref tlb2husage) to generate
|
|
||||||
the implementation for each method on the interface.
|
|
||||||
|
|
||||||
Then comet::implement_cpc is used to provide IConnectionPointContainer
|
|
||||||
(which provides the method for finding a particular connection point.
|
|
||||||
|
|
||||||
The default implementation of a coclass will inherit of this method by
|
|
||||||
default, however they can be explicitly referenced to provide
|
|
||||||
alternate implementations.
|
|
||||||
|
|
||||||
The class comet::implement_cpc is templated to an interface list, which
|
|
||||||
can be constructed with comet::make_list.
|
|
||||||
|
|
||||||
\code
|
|
||||||
class my_class : public simple_object< IFooImpl<my_class>, implement_cpc< make_list<IFooEvent, IBarEvent>::result > >
|
|
||||||
\endcode
|
|
||||||
|
|
||||||
This causes each of the interface in the list of interfaces to be wrapped by a
|
|
||||||
comet::connection_point_for class which provides the access syntax.
|
|
||||||
|
|
||||||
\code
|
|
||||||
connection_point_for<IFooEvent>::connection_point.Fire_FooMethod( args );
|
|
||||||
\endcode
|
|
||||||
|
|
||||||
Note that \b Fire_ is prepended to each method name.
|
|
||||||
|
|
||||||
If there is only one connection point in the list, then the
|
|
||||||
connection_point_for namespace segregator is not required.
|
|
||||||
|
|
||||||
If there is no connection point implementation for the interface, then you should make
|
|
||||||
sure that it is referenced with a [source] tag by a coclass definition
|
|
||||||
in the library you are including, and that you are generating server
|
|
||||||
implementations or forcing it by prepending '*' in a symbol file, see
|
|
||||||
the \ref wrappergensymbolformat.
|
|
||||||
|
|
||||||
\section cometconnectionpointsink Connction Point Sink
|
|
||||||
|
|
||||||
In order to prevent the circular references inherent in connection points, the
|
|
||||||
reference loop must be broken somehow. This is best done by using a contained
|
|
||||||
member that calls back on the parent class.
|
|
||||||
|
|
||||||
The class sink_impl is best used in this circumstance as it contains code for calling
|
|
||||||
Advise and Unadvise. It inherits from static_object which is designed to be embedded in
|
|
||||||
a class, and does reference counting on the module and does not destruct itself.
|
|
||||||
|
|
||||||
This class is templated to the interface implementation desired, which will
|
|
||||||
mostly be the 'Impl' class for the interface, but might be a raw COM interface.
|
|
||||||
|
|
||||||
In this example we have a class 'MyCoclass' that is sinking the event interface IMyEventImpl which
|
|
||||||
has a single 'EventHappened' method.
|
|
||||||
\code
|
|
||||||
class coclass_MyCoclass : public coclass<MyCoclass>
|
|
||||||
{
|
|
||||||
// Private Embedded sink implementation.
|
|
||||||
struct sink_t : sink_impl<IMyEventImpl>
|
|
||||||
{
|
|
||||||
sink_t(coclass_MyCoclass *Parent) :m_parent(Parent) {}
|
|
||||||
inline void EventHappened( long param_Here ) { m_parent->sink_EventHappened(param_Here); }
|
|
||||||
coclass_MyCoclass *m_parent; // Non-addref reference.
|
|
||||||
} m_sink;
|
|
||||||
public:
|
|
||||||
coclass_MyCoclass() : m_sink(this) {}
|
|
||||||
|
|
||||||
// Set the event source.
|
|
||||||
void SetEventSource( const com_ptr<IUnknown> &unknown)
|
|
||||||
{
|
|
||||||
if (m_sink.is_advised())
|
|
||||||
m_sink.unadvise();
|
|
||||||
m_sink.advise( unknown );
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void sink_EventHappened( long param_Here )
|
|
||||||
{
|
|
||||||
// Event code goes here
|
|
||||||
}
|
|
||||||
};
|
|
||||||
\endcode
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace comet {
|
|
||||||
|
|
||||||
template<typename Itf> class connection_point;
|
|
||||||
|
|
||||||
/*! \addtogroup Interfaces
|
|
||||||
*/
|
|
||||||
//@{
|
|
||||||
/** \class simple_cpc cp.h comet/cp.h
|
|
||||||
* Implement a simple connection-point container with a single
|
|
||||||
* connection-point.
|
|
||||||
* \param Itf The single connection-point interface.
|
|
||||||
* \sa implement_cpc
|
|
||||||
*/
|
|
||||||
template<typename Itf> class ATL_NO_VTABLE simple_cpc : public IConnectionPointContainer
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef IConnectionPointContainer interface_is;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
/// \name IConnectionPointContainer interface
|
|
||||||
//@{
|
|
||||||
STDMETHOD(EnumConnectionPoints)(IEnumConnectionPoints**)
|
|
||||||
{
|
|
||||||
return E_NOTIMPL;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHOD(FindConnectionPoint)(REFIID riid, IConnectionPoint** ppCP)
|
|
||||||
{
|
|
||||||
if (!ppCP) return E_POINTER;
|
|
||||||
if (riid == uuidof<Itf>()) {
|
|
||||||
*ppCP = &connection_point;
|
|
||||||
(*ppCP)->AddRef();
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
return CONNECT_E_NOCONNECTION;
|
|
||||||
}
|
|
||||||
//@}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
simple_cpc() : connection_point(this) {}
|
|
||||||
|
|
||||||
connection_point<Itf> connection_point;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/** \class connection_point_for cp.h comet/cp.h
|
|
||||||
* Provide access to implementation for a connection point.
|
|
||||||
* \relates implement_cpc
|
|
||||||
*/
|
|
||||||
template<typename Itf> class connection_point_for
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
connection_point_for(::IUnknown *self) : connection_point(self) {}
|
|
||||||
connection_point<Itf> connection_point;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
namespace impl {
|
|
||||||
|
|
||||||
/** Find a connection point implementation for a given iid.
|
|
||||||
* \internal
|
|
||||||
*/
|
|
||||||
template<typename ITF_LIST> struct connection_point_finder
|
|
||||||
{
|
|
||||||
template<typename T> COMET_FORCEINLINE static ::IConnectionPoint* find_connection_point(T* This, const IID& iid)
|
|
||||||
{
|
|
||||||
typedef find_compatibility< COMET_STRICT_TYPENAME ITF_LIST::head > compatible;
|
|
||||||
if (iid == uuidof<COMET_STRICT_TYPENAME ITF_LIST::head>())
|
|
||||||
return &((static_cast<connection_point_for< COMET_STRICT_TYPENAME ITF_LIST::head > *>(This))->connection_point) ;
|
|
||||||
else return connection_point_finder<COMET_STRICT_TYPENAME ITF_LIST::tail>::find_connection_point(This, iid);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
template<> struct connection_point_finder<nil>
|
|
||||||
{
|
|
||||||
template<typename T> COMET_FORCEINLINE static ::IConnectionPoint* find_connection_point(T*, const IID&)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace impl {
|
|
||||||
|
|
||||||
|
|
||||||
template<typename ITF_LIST> struct ATL_NO_VTABLE inherit_all_ex_unknown;
|
|
||||||
|
|
||||||
#ifdef COMET_GOOD_RECURSIVE_STRUCT
|
|
||||||
// Remove level of indirection. PC-lint cannot handle it, and MSVC7
|
|
||||||
// should be ale to.
|
|
||||||
template<typename ITF_LIST> struct ATL_NO_VTABLE inherit_all_ex_unknown
|
|
||||||
: public ITF_LIST::head, public inherit_all_ex_unknown<typename ITF_LIST::tail >
|
|
||||||
{
|
|
||||||
inherit_all_ex_unknown( ::IUnknown *initParam)
|
|
||||||
: ITF_LIST::head(initParam), inherit_all_ex_unknown< COMET_STRICT_TYPENAME ITF_LIST::tail >(initParam)
|
|
||||||
{}
|
|
||||||
};
|
|
||||||
template<> struct inherit_all_ex_unknown<nil> { inherit_all_ex_unknown(::IUnknown *) {} };
|
|
||||||
|
|
||||||
#else // COMET_GOOD_RECURSIVE_STRUCT
|
|
||||||
template<typename HEAD, typename ITF_TAIL> struct ATL_NO_VTABLE inherit_all_ex_aux_unknown
|
|
||||||
: public HEAD, public inherit_all_ex_unknown<ITF_TAIL>
|
|
||||||
{
|
|
||||||
inherit_all_ex_aux_unknown( ::IUnknown *initParam)
|
|
||||||
: HEAD(initParam), inherit_all_ex_unknown<ITF_TAIL>(initParam)
|
|
||||||
{}
|
|
||||||
};
|
|
||||||
|
|
||||||
// COMET_CONFIG_H is always defined! This is just a trick to get Doxygen to ignore the following declaration that
|
|
||||||
// otherwise seems to be cause an exception in Doxygen 1.2.8
|
|
||||||
#ifdef COMET_CONFIG_H
|
|
||||||
template<typename ITF_LIST> struct ATL_NO_VTABLE inherit_all_ex_unknown
|
|
||||||
: public inherit_all_ex_aux_unknown<typename ITF_LIST::head,typename ITF_LIST::tail >
|
|
||||||
{
|
|
||||||
inherit_all_ex_unknown( ::IUnknown *initParam)
|
|
||||||
:inherit_all_ex_aux_unknown< COMET_STRICT_TYPENAME ITF_LIST::head, COMET_STRICT_TYPENAME ITF_LIST::tail >(initParam)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
|
||||||
template<> struct inherit_all_ex_unknown<nil> { inherit_all_ex_unknown(::IUnknown *) {} };
|
|
||||||
#endif // COMET_CONFIG_H
|
|
||||||
#endif // COMET_GOOD_RECURSIVE_STRUCT
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
COMET_WRAP_EACH_DECLARE( connection_point_for)
|
|
||||||
|
|
||||||
|
|
||||||
/** \struct implement_cpc cp.h comet/cp.h
|
|
||||||
* Implement a connection point container that can handle multiple
|
|
||||||
* connection points.
|
|
||||||
* This should be added to the \link comet::make_list list \endlink of implemented interfaces for a coclass as it
|
|
||||||
* implements IConnectionPointContainer (which will be required for a qi).
|
|
||||||
*
|
|
||||||
* The class is used by the default coclass implementation to provide \ref cometconnectionpoints.
|
|
||||||
*
|
|
||||||
* \param ITF_LST \link comet::make_list List \endlink of connection points interfaces to implement.
|
|
||||||
*/
|
|
||||||
template< typename ITF_LST> struct ATL_NO_VTABLE implement_cpc : public IConnectionPointContainer
|
|
||||||
, public impl::inherit_all_ex_unknown< COMET_WRAP_EACH(connection_point_for, ITF_LST) >
|
|
||||||
{
|
|
||||||
typedef IConnectionPointContainer interface_is;
|
|
||||||
public:
|
|
||||||
implement_cpc()
|
|
||||||
: impl::inherit_all_ex_unknown< COMET_WRAP_EACH(comet::connection_point_for, ITF_LST) >((::IUnknown *)this)
|
|
||||||
{}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
friend struct impl::connection_point_finder<ITF_LST>;
|
|
||||||
/// \name IConnectionPointContainer interface
|
|
||||||
//@{
|
|
||||||
STDMETHOD(EnumConnectionPoints)(IEnumConnectionPoints**)
|
|
||||||
{
|
|
||||||
return E_NOTIMPL;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHOD(FindConnectionPoint)(REFIID riid, IConnectionPoint** ppCP)
|
|
||||||
{
|
|
||||||
if (!ppCP) return E_POINTER;
|
|
||||||
|
|
||||||
const IID& iid = riid;
|
|
||||||
|
|
||||||
*ppCP = impl::connection_point_finder<ITF_LST>::find_connection_point(this, iid);
|
|
||||||
|
|
||||||
if ( *ppCP !=NULL)
|
|
||||||
{
|
|
||||||
(*ppCP)->AddRef();
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
return CONNECT_E_NOCONNECTION;
|
|
||||||
}
|
|
||||||
//@}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/** \class connection_point_impl cp.h comet/cp.h
|
|
||||||
* Implements a connection point.
|
|
||||||
* \param Itf Interface of connection point.
|
|
||||||
*/
|
|
||||||
template<typename Itf> class ATL_NO_VTABLE connection_point_impl : public embedded_object< IUnknown, IConnectionPoint >
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
bool is_connected() const
|
|
||||||
{ return !connections_.empty(); }
|
|
||||||
protected:
|
|
||||||
connection_point_impl(::IUnknown* pUnk) : next_cookie_(1), embedded_object< IUnknown, IConnectionPoint >(pUnk) {}
|
|
||||||
|
|
||||||
/// \name IConnectionPoint interface
|
|
||||||
//@{
|
|
||||||
STDMETHOD(GetConnectionInterface)(IID* pIID)
|
|
||||||
{
|
|
||||||
*pIID = uuidof<Itf>();
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHOD(GetConnectionPointContainer)(IConnectionPointContainer** ppCPC) {
|
|
||||||
com_ptr<IConnectionPointContainer> p;
|
|
||||||
p = try_cast(com_ptr< ::IUnknown >(get_parent()));
|
|
||||||
*ppCPC = com_ptr<IConnectionPointContainer>::detach( p );
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHOD(Advise)(::IUnknown* pUnkSink, DWORD* pdwCookie)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
connections_[next_cookie_] = try_cast( com_ptr< ::IUnknown >(pUnkSink) );
|
|
||||||
}
|
|
||||||
catch (...) {
|
|
||||||
return CONNECT_E_CANNOTCONNECT;
|
|
||||||
}
|
|
||||||
*pdwCookie = next_cookie_++;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
STDMETHOD(Unadvise)(DWORD dwCookie)
|
|
||||||
{
|
|
||||||
CONNECTIONS::iterator it = connections_.find(dwCookie);
|
|
||||||
if (it == connections_.end()) return CONNECT_E_NOCONNECTION;
|
|
||||||
connections_.erase(it);
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHOD(EnumConnections)(IEnumConnections** ppEnum)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
*ppEnum = com_ptr<IEnumConnections>::detach( stl_enumeration<IEnumConnections>::create(connections_, get_unknown()) );
|
|
||||||
} catch (...) {
|
|
||||||
return E_FAIL;
|
|
||||||
}
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
//@}
|
|
||||||
|
|
||||||
typedef std::map<DWORD, com_ptr<Itf> > CONNECTIONS;
|
|
||||||
CONNECTIONS connections_;
|
|
||||||
private:
|
|
||||||
UINT next_cookie_;
|
|
||||||
};
|
|
||||||
|
|
||||||
/** \class sink_impl cp.h comet/cp.h
|
|
||||||
* Implement a sink for a connection pointer.
|
|
||||||
* \param Itf interface to implement.
|
|
||||||
*/
|
|
||||||
template<typename Itf> class ATL_NO_VTABLE sink_impl : public static_object<Itf>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/** Advise this object as sinking connections from \p t.
|
|
||||||
*/
|
|
||||||
void advise(const com_ptr< ::IUnknown>& t)
|
|
||||||
{
|
|
||||||
if (ptr_) throw std::runtime_error("Cannot double advise.");
|
|
||||||
com_ptr<IConnectionPointContainer> cpc( try_cast(t) );
|
|
||||||
IConnectionPoint* cp;
|
|
||||||
cpc->FindConnectionPoint( uuidof<Itf>(), &cp) | raise_exception;
|
|
||||||
|
|
||||||
HRESULT hr = cp->Advise(static_cast< ::IUnknown* >(static_cast<Itf*>(this)), &cookie_);
|
|
||||||
|
|
||||||
cp->Release();
|
|
||||||
|
|
||||||
hr | raise_exception;
|
|
||||||
|
|
||||||
ptr_ = t;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Unadvise this interface from object \p t.
|
|
||||||
*/
|
|
||||||
void unadvise()
|
|
||||||
{
|
|
||||||
if (ptr_) {
|
|
||||||
com_ptr<IConnectionPointContainer> cpc( try_cast(ptr_) );
|
|
||||||
IConnectionPoint* cp;
|
|
||||||
cpc->FindConnectionPoint( uuidof<Itf>(), &cp) | raise_exception;
|
|
||||||
|
|
||||||
HRESULT hr = cp->Unadvise(cookie_);
|
|
||||||
cookie_ = 0;
|
|
||||||
ptr_ = 0;
|
|
||||||
|
|
||||||
cp->Release();
|
|
||||||
|
|
||||||
hr | raise_exception;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Get event object.
|
|
||||||
*/
|
|
||||||
com_ptr< ::IUnknown> object()
|
|
||||||
{
|
|
||||||
return ptr_;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Return true if advised.
|
|
||||||
*/
|
|
||||||
bool is_advised()
|
|
||||||
{
|
|
||||||
return !ptr_.is_null();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
sink_impl() : cookie_(0) {}
|
|
||||||
~sink_impl() { unadvise(); }
|
|
||||||
private:
|
|
||||||
DWORD cookie_;
|
|
||||||
com_ptr< ::IUnknown> ptr_;
|
|
||||||
};
|
|
||||||
//@}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma warning( pop )
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,118 +0,0 @@
|
||||||
/** \file
|
|
||||||
* Connection-point traits.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Copyright © 2002 Michael Geddes
|
|
||||||
* Copyright © 2013 Alexander Lamaison
|
|
||||||
*
|
|
||||||
* This material is provided "as is", with absolutely no warranty
|
|
||||||
* expressed or implied. Any use is at your own risk. Permission to
|
|
||||||
* use or copy this software for any purpose is hereby granted without
|
|
||||||
* fee, provided the above notices are retained on all copies.
|
|
||||||
* Permission to modify the code and to distribute modified code is
|
|
||||||
* granted, provided the above notices are retained, and a notice that
|
|
||||||
* the code was modified is included with the above copyright notice.
|
|
||||||
*
|
|
||||||
* This header is part of Comet version 2.
|
|
||||||
* https://github.com/alamaison/comet
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef INCLUDE_COMET_CPTRAITS_H
|
|
||||||
#define INCLUDE_COMET_CPTRAITS_H
|
|
||||||
|
|
||||||
#ifdef _SHOW_INC
|
|
||||||
#pragma message(" #Include " __FILE__)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <comet/config.h>
|
|
||||||
#include <comet/error_fwd.h> // raise_exception
|
|
||||||
|
|
||||||
#include <Windows.h> // HRESULT
|
|
||||||
|
|
||||||
namespace comet
|
|
||||||
{
|
|
||||||
/*! \struct cp_throw cptraits.h comet/cptraits.h
|
|
||||||
* Default 'throw' traits for connection-points.
|
|
||||||
* \code Usage
|
|
||||||
* connection_point_for<IMySourceInterface>::connection_point.Fire_MyEvent( arg1, comet::cp_throw());
|
|
||||||
* \endcode
|
|
||||||
*/
|
|
||||||
struct cp_throw
|
|
||||||
{
|
|
||||||
|
|
||||||
/// Constructor - called before iterating over the connection-points.
|
|
||||||
cp_throw() : _hr_(S_OK) { }
|
|
||||||
|
|
||||||
/// Destructor - called after iterating over all the connection-points.
|
|
||||||
~cp_throw() { _hr_ | raise_exception ; }
|
|
||||||
|
|
||||||
/*! Called when a connection point fails.
|
|
||||||
* Can also be used to remember the hresult for the destructor.
|
|
||||||
*
|
|
||||||
* \retval true Cause the on_fail method to be called.
|
|
||||||
* \retval false Ignore the failure.
|
|
||||||
*/
|
|
||||||
bool check_fail(HRESULT hr)
|
|
||||||
{
|
|
||||||
if( FAILED(hr) )
|
|
||||||
_hr_ = hr;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! Called when check_fail returns true.
|
|
||||||
* \param par_connects Reference to the STL container containing the connection-points.
|
|
||||||
* \param par_it The iterator of the failed connection-point.
|
|
||||||
*/
|
|
||||||
template<typename CONNECTIONS>
|
|
||||||
static bool on_fail(CONNECTIONS &par_connects, const typename CONNECTIONS::iterator & par_it)
|
|
||||||
{
|
|
||||||
COMET_NOTUSED(par_it);
|
|
||||||
COMET_NOTUSED(par_connects);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
HRESULT _hr_;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/*! \struct cp_nothrow_remove cptraits.h comet/cptraits.h
|
|
||||||
* Traits for connection-points, errors cause the connection-point to auto-remove.
|
|
||||||
* \code
|
|
||||||
* connection_point_for<IMySourceInterface>::connection_point.Fire_MyEvent( arg1, comet::cp_nothrow_remove());
|
|
||||||
* \endcode
|
|
||||||
* \sa cp_throw
|
|
||||||
*/
|
|
||||||
struct cp_nothrow_remove
|
|
||||||
{
|
|
||||||
//! Called when a connection point fails.
|
|
||||||
bool check_fail( HRESULT _hr_) throw() { return FAILED(_hr_); }
|
|
||||||
|
|
||||||
//! Called when check_fail returns true.
|
|
||||||
template<typename CONNECTIONS>
|
|
||||||
static bool on_fail(CONNECTIONS &par_connects, const typename CONNECTIONS::iterator &par_it ) throw()
|
|
||||||
{
|
|
||||||
try{ par_connects.erase(par_it); }catch(...) {}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/*! \struct cp_nothrow cptraits.h comet/cptraits.h
|
|
||||||
* Tratis for connection-points, errors are ignored.
|
|
||||||
* \code
|
|
||||||
* connection_point_for<IMySourceInterface>::connection_point.Fire_MyEvent( arg1, comet::cp_nothrow());
|
|
||||||
* \endcode
|
|
||||||
* \sa cp_throw
|
|
||||||
*/
|
|
||||||
struct cp_nothrow
|
|
||||||
{
|
|
||||||
//! Called when a connection point fails.
|
|
||||||
bool check_fail( HRESULT _hr_) throw() { return FAILED(_hr_); }
|
|
||||||
|
|
||||||
//! Called when check_fail returns true.
|
|
||||||
template<typename CONNECTIONS>
|
|
||||||
static bool on_fail(CONNECTIONS &par_connects, const typename CONNECTIONS::iterator &par_it ) throw() { return false; }
|
|
||||||
};
|
|
||||||
}
|
|
||||||
#endif /* INCLUDE_COMET_CPTRAITS_H */
|
|
|
@ -1,474 +0,0 @@
|
||||||
/** \file
|
|
||||||
* Currency wrapper.
|
|
||||||
*/
|
|
||||||
/* Copyright © 2001 Michael Geddes, Sofus Mortensen
|
|
||||||
*
|
|
||||||
* This material is provided "as is", with absolutely no warranty
|
|
||||||
* expressed or implied. Any use is at your own risk. Permission to
|
|
||||||
* use or copy this software for any purpose is hereby granted without
|
|
||||||
* fee, provided the above notices are retained on all copies.
|
|
||||||
* Permission to modify the code and to distribute modified code is
|
|
||||||
* granted, provided the above notices are retained, and a notice that
|
|
||||||
* the code was modified is included with the above copyright notice.
|
|
||||||
*
|
|
||||||
* This header is part of Comet version 2.
|
|
||||||
* https://github.com/alamaison/comet
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef COMET_CURRENCY_H
|
|
||||||
#define COMET_CURRENCY_H
|
|
||||||
|
|
||||||
#include <comet/config.h>
|
|
||||||
|
|
||||||
#include <comet/error_fwd.h>
|
|
||||||
#include <comet/assert.h>
|
|
||||||
|
|
||||||
#include <wtypes.h>
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
namespace comet
|
|
||||||
{
|
|
||||||
|
|
||||||
class bstr_t;
|
|
||||||
|
|
||||||
// currency_t
|
|
||||||
///////////////
|
|
||||||
|
|
||||||
/*! \addtogroup COMType
|
|
||||||
*/
|
|
||||||
//@{
|
|
||||||
|
|
||||||
/** Wrapper for CURRENCY type.
|
|
||||||
* CURRENCY is a fixed point (to 4 decimal places) 64 bit value.
|
|
||||||
*/
|
|
||||||
|
|
||||||
class currency_t
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/// Default Constructor
|
|
||||||
currency_t() throw() { cy_.int64 = 0; }
|
|
||||||
|
|
||||||
/// CY constructor.
|
|
||||||
currency_t(const CY &cy): cy_(cy) { }
|
|
||||||
|
|
||||||
/// Double Conversion constructor.
|
|
||||||
explicit currency_t(double val)
|
|
||||||
{
|
|
||||||
VarCyFromR8(val,&cy_) | raise_exception;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
// //! Construct currency from CY/CURRENCY.
|
|
||||||
// /*!
|
|
||||||
// Takes ownership of specified CY value. To prevent misuse the CY must be wrapped using auto_attach.
|
|
||||||
//
|
|
||||||
// \code
|
|
||||||
// currency_t cy( auto_attach( myCY ) );
|
|
||||||
// \endcode
|
|
||||||
//
|
|
||||||
// \param cyVal
|
|
||||||
// Value to initialise currency_t from.
|
|
||||||
// */
|
|
||||||
// currency_t( const impl::auto_attach_t<CY> &cyVal) throw() : cy_(cyVal.get())
|
|
||||||
// {}
|
|
||||||
#endif //0
|
|
||||||
|
|
||||||
/// Long Conversion constructor.
|
|
||||||
currency_t( long val )
|
|
||||||
{
|
|
||||||
VarCyFromI4(val,&cy_) | raise_exception;
|
|
||||||
}
|
|
||||||
|
|
||||||
currency_t( int val )
|
|
||||||
{
|
|
||||||
VarCyFromI4(val,&cy_) | raise_exception;
|
|
||||||
}
|
|
||||||
|
|
||||||
void swap(currency_t& c) throw()
|
|
||||||
{
|
|
||||||
std::swap(cy_, c.cy_);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const currency_t& create_const_reference(const CY& s) throw()
|
|
||||||
{ return *reinterpret_cast<const currency_t*>(&s); }
|
|
||||||
|
|
||||||
static currency_t& create_reference(CY& s) throw()
|
|
||||||
{ return *reinterpret_cast<currency_t*>(&s); }
|
|
||||||
|
|
||||||
//! \name Assignment Operators
|
|
||||||
//@{
|
|
||||||
currency_t &operator=(double newVal)
|
|
||||||
{
|
|
||||||
currency_t c( newVal );
|
|
||||||
swap(c);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
currency_t &operator=(long newVal)
|
|
||||||
{
|
|
||||||
currency_t c( newVal );
|
|
||||||
swap(c);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
currency_t &operator=(int newVal)
|
|
||||||
{
|
|
||||||
currency_t c( newVal );
|
|
||||||
swap(c);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
currency_t &operator=(const tagCY &newVal) throw()
|
|
||||||
{
|
|
||||||
cy_ = newVal;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
//@}
|
|
||||||
|
|
||||||
/// \name Mathematical Operators
|
|
||||||
//@{
|
|
||||||
currency_t &operator+=(const currency_t &cy)
|
|
||||||
{
|
|
||||||
currency_t c( *this + cy );
|
|
||||||
swap(c);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
currency_t &operator-=(const currency_t &cy)
|
|
||||||
{
|
|
||||||
currency_t c( *this - cy );
|
|
||||||
swap(c);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
currency_t &operator*=(const currency_t &cy)
|
|
||||||
{
|
|
||||||
currency_t c( *this * cy );
|
|
||||||
swap(c);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
currency_t &operator*=(long cy)
|
|
||||||
{
|
|
||||||
currency_t c( *this * cy );
|
|
||||||
swap(c);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
currency_t &operator*=(int val)
|
|
||||||
{
|
|
||||||
return operator*=((long)val);
|
|
||||||
}
|
|
||||||
currency_t &operator*=(double val)
|
|
||||||
{
|
|
||||||
cy_.int64 = (LONGLONG)(cy_.int64 * val);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
currency_t &operator/=(int val) const
|
|
||||||
{
|
|
||||||
return operator/=((long)val);
|
|
||||||
}
|
|
||||||
currency_t &operator/=(long val)
|
|
||||||
{
|
|
||||||
|
|
||||||
if(!valid())
|
|
||||||
{
|
|
||||||
// Check for invalid number
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for divide by 0
|
|
||||||
if (val == 0)
|
|
||||||
{
|
|
||||||
// Set to maximum negative value
|
|
||||||
cy_.Hi = 0x80000000;
|
|
||||||
cy_.Lo = 0x00000000;
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
cy_.int64/=val;
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
currency_t operator+(const currency_t &cy)const
|
|
||||||
{
|
|
||||||
currency_t rv;
|
|
||||||
VarCyAdd(cy_,cy.cy_,&rv.cy_) | raise_exception ;
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
currency_t operator-(const currency_t &cy)const
|
|
||||||
{
|
|
||||||
currency_t rv;
|
|
||||||
VarCySub(cy_,cy.cy_,&rv.cy_) | raise_exception ;
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
currency_t operator*(const currency_t &cy)const
|
|
||||||
{
|
|
||||||
currency_t rv;
|
|
||||||
VarCyMul(cy_,cy.cy_,&rv.cy_) | raise_exception ;
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
currency_t operator*(long cy)const
|
|
||||||
{
|
|
||||||
currency_t rv;
|
|
||||||
VarCyMulI4(cy_,cy,&rv.cy_) | raise_exception;
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
currency_t operator*(int cy)const
|
|
||||||
{
|
|
||||||
return operator *((long)cy);
|
|
||||||
}
|
|
||||||
|
|
||||||
currency_t operator*(double cy) const
|
|
||||||
{
|
|
||||||
currency_t val(*this);
|
|
||||||
val *=cy;
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// Calculate approximate ratio.
|
|
||||||
double operator/(const currency_t &cy)const
|
|
||||||
{
|
|
||||||
return ((double)cy_.int64 /(double)cy.cy_.int64);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Divide by int.
|
|
||||||
currency_t operator/(int val) const
|
|
||||||
{
|
|
||||||
return operator/((long)val);
|
|
||||||
}
|
|
||||||
/// Divide by long.
|
|
||||||
currency_t operator/(long val) const
|
|
||||||
{
|
|
||||||
currency_t tmp(cy_);
|
|
||||||
tmp/=val;
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Divide by double
|
|
||||||
double operator/(double val) const
|
|
||||||
{
|
|
||||||
if(!valid())
|
|
||||||
{
|
|
||||||
// Check for invalid number
|
|
||||||
throw std::invalid_argument("Invalid divide");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for divide by 0
|
|
||||||
if (val == 0)
|
|
||||||
{
|
|
||||||
throw std::overflow_error("Divide by 0");
|
|
||||||
}
|
|
||||||
return cy_.int64/(val*10000);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Unary negate.
|
|
||||||
currency_t operator-()const
|
|
||||||
{
|
|
||||||
currency_t cy;
|
|
||||||
VarCyNeg(cy_,&(cy.cy_)) | raise_exception;
|
|
||||||
return cy;
|
|
||||||
}
|
|
||||||
|
|
||||||
//@}
|
|
||||||
|
|
||||||
/** Rounds the value to specified number of decimal places.
|
|
||||||
* \param decimals Number of places to round to.
|
|
||||||
*/
|
|
||||||
currency_t &round_to(int decimals)
|
|
||||||
{
|
|
||||||
VarCyRound(cy_,decimals,&cy_) | raise_exception;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// \name Logical Operators
|
|
||||||
//@{
|
|
||||||
|
|
||||||
bool operator!=(const currency_t &cy) const { return cmp(cy)!=0; }
|
|
||||||
bool operator!=(double val) const{ return cmp(val)!=0; }
|
|
||||||
bool operator==(const currency_t &cy) const { return cmp(cy)==0; }
|
|
||||||
bool operator==(double val) const{ return cmp(val)==0; }
|
|
||||||
bool operator<=(const currency_t &cy) const{ return cmp(cy)<=0; }
|
|
||||||
bool operator<=(double val) const{ return cmp(val)<=0; }
|
|
||||||
bool operator>=(const currency_t &cy) const{ return cmp(cy)>=0; }
|
|
||||||
bool operator>=(double val) const{ return cmp(val)>=0; }
|
|
||||||
bool operator<(const currency_t &cy) const{ return cmp(cy)<0; }
|
|
||||||
bool operator<(double val) const{ return cmp(val)<0; }
|
|
||||||
bool operator>(const currency_t &cy) const{ return cmp(cy)>0; }
|
|
||||||
bool operator>(double val) const{ return cmp(val)>0; }
|
|
||||||
|
|
||||||
//@}
|
|
||||||
|
|
||||||
/** Compares the value like strcmp.
|
|
||||||
* \param cy Number to be compared.
|
|
||||||
*/
|
|
||||||
int cmp(const currency_t &cy) const
|
|
||||||
{
|
|
||||||
return _cmpResult(VarCyCmp(cy_,cy.cy_));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Compares the value like strcmp.
|
|
||||||
* \param cy Number to be compared.
|
|
||||||
*/
|
|
||||||
int cmp(double cy) const
|
|
||||||
{
|
|
||||||
return _cmpResult(VarCyCmpR8(cy_,cy));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//! \name Access converters
|
|
||||||
//@{
|
|
||||||
tagCY get() const { return cy_;}
|
|
||||||
tagCY in() const { return cy_;}
|
|
||||||
tagCY *in_ptr() const { return const_cast<CY*>(&cy_);}
|
|
||||||
tagCY *out() { return &cy_;}
|
|
||||||
tagCY *inout() { return &cy_;}
|
|
||||||
//@}
|
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
friend std::ostream &operator <<(std::ostream &str, const currency_t &val)
|
|
||||||
{
|
|
||||||
std::string strval=val.format( 1, str.precision(), str.width() );
|
|
||||||
return str<< strval.c_str();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
friend
|
|
||||||
std::basic_ostream<char> &operator<<(std::basic_ostream<char> &str, const currency_t &val)
|
|
||||||
{
|
|
||||||
std::basic_string<char> strval;
|
|
||||||
val.do_format(strval, 1, str.precision(), str.width() );
|
|
||||||
return str << strval.c_str();
|
|
||||||
}
|
|
||||||
|
|
||||||
friend
|
|
||||||
std::basic_ostream<wchar_t> &operator<<(std::basic_ostream<wchar_t> &str, const currency_t &val)
|
|
||||||
{
|
|
||||||
std::basic_string<wchar_t> strval;
|
|
||||||
val.do_format(strval, 1, str.precision(), str.width() );
|
|
||||||
return str << strval.c_str();
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Format the string with the given digits, precision and width.
|
|
||||||
std::basic_string<TCHAR> format(
|
|
||||||
std::streamsize mindigits=0, std::streamsize minprecision=0,
|
|
||||||
std::streamsize width=0) const
|
|
||||||
{
|
|
||||||
std::basic_string<TCHAR> strval;
|
|
||||||
do_format(strval, mindigits, minprecision, width);
|
|
||||||
return strval;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Parse the string to a currency.
|
|
||||||
currency_t &parse( const bstr_t &str, LCID locale =::GetThreadLocale() );
|
|
||||||
/* {
|
|
||||||
VarCyFromStr( str.in(), locale, 0, &cy_ ) | raise_exception;
|
|
||||||
return *this;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
protected:
|
|
||||||
/** Return a string representation of the value.
|
|
||||||
* \param val output string (return values can't automatically detect template arguments)
|
|
||||||
* \param mindigits Minimum number before decimal point.
|
|
||||||
* \param minprecision Minimum number after decimal point.
|
|
||||||
* \todo Obey ostream formats for: fillchar(), ios_base::left, ios_base::internal, ios_base::showpos
|
|
||||||
*/
|
|
||||||
template <typename CH>
|
|
||||||
void do_format(
|
|
||||||
std::basic_string<CH>& val, std::streamsize mindigits,
|
|
||||||
std::streamsize minprecision, std::streamsize /*width*/) const
|
|
||||||
{
|
|
||||||
COMET_ASSERT(mindigits>=0 && minprecision >=0 );
|
|
||||||
if(minprecision> 4) minprecision =4;
|
|
||||||
|
|
||||||
// Add in the 4 fixed decimal points
|
|
||||||
std::streamsize pr =
|
|
||||||
((0 <= minprecision && minprecision <=4) ?
|
|
||||||
(4-minprecision) : 0);
|
|
||||||
mindigits+=4;
|
|
||||||
|
|
||||||
val.erase();
|
|
||||||
val.reserve(22);
|
|
||||||
LONGLONG value=cy_.int64;
|
|
||||||
bool neg=value<0;
|
|
||||||
if(neg)
|
|
||||||
{
|
|
||||||
value=-value;
|
|
||||||
}
|
|
||||||
// Put in the digits backwards
|
|
||||||
std::streamsize digit=0;
|
|
||||||
bool output=false;
|
|
||||||
while(value !=0 || digit < mindigits)
|
|
||||||
{
|
|
||||||
CH dig=CH(value%10);
|
|
||||||
if(output || true==(output= (dig >0 || digit>=pr))) // Once 'output' is set - output everything.
|
|
||||||
{
|
|
||||||
val+=(CH('0'+dig));
|
|
||||||
}
|
|
||||||
if(++digit == 4)
|
|
||||||
{
|
|
||||||
val+=CH('.');
|
|
||||||
output=true;
|
|
||||||
}
|
|
||||||
value/=10;
|
|
||||||
}
|
|
||||||
if(neg)
|
|
||||||
{
|
|
||||||
val+=CH('-');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now reverse the digits
|
|
||||||
std::reverse(val.begin(), val.end());
|
|
||||||
}
|
|
||||||
public:
|
|
||||||
|
|
||||||
/// Returns true if this is a valid number
|
|
||||||
bool valid() const throw()
|
|
||||||
{ return !(cy_.Hi==(long)0x80000000 && cy_.Lo==0);}
|
|
||||||
|
|
||||||
/// Detaches the CY value. Provided for consistancy.
|
|
||||||
CY detach() throw()
|
|
||||||
{
|
|
||||||
CY val = cy_;
|
|
||||||
cy_.int64 = 0;
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Detaches the CY value. Provided for consistancy.
|
|
||||||
static CY detach(currency_t& cy) throw()
|
|
||||||
{
|
|
||||||
return cy.detach();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
CY cy_;
|
|
||||||
|
|
||||||
static int _cmpResult(HRESULT hr)
|
|
||||||
{
|
|
||||||
if(SUCCEEDED(hr))
|
|
||||||
{
|
|
||||||
switch(hr)
|
|
||||||
{
|
|
||||||
case VARCMP_LT:
|
|
||||||
return -1;
|
|
||||||
case VARCMP_EQ :
|
|
||||||
return 0;
|
|
||||||
case VARCMP_GT:
|
|
||||||
return 1;
|
|
||||||
case VARCMP_NULL:
|
|
||||||
COMET_ASSERT(!"What do we do with this?");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
hr | raise_exception;
|
|
||||||
}
|
|
||||||
return 0; // shut the compiler up
|
|
||||||
}
|
|
||||||
};
|
|
||||||
//@}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // COMET_CURRENCY_H
|
|
|
@ -1,396 +0,0 @@
|
||||||
/** \file
|
|
||||||
* Date wrapper (part of datetime).
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* Copyright © 2004 Michael Geddes
|
|
||||||
*
|
|
||||||
* This material is provided "as is", with absolutely no warranty
|
|
||||||
* expressed or implied. Any use is at your own risk. Permission to
|
|
||||||
* use or copy this software for any purpose is hereby granted without
|
|
||||||
* fee, provided the above notices are retained on all copies.
|
|
||||||
* Permission to modify the code and to distribute modified code is
|
|
||||||
* granted, provided the above notices are retained, and a notice that
|
|
||||||
* the code was modified is included with the above copyright notice.
|
|
||||||
*
|
|
||||||
* This header is part of Comet version 2.
|
|
||||||
* https://github.com/alamaison/comet
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef INCLUDE_COMET_DATE_H
|
|
||||||
#define INCLUDE_COMET_DATE_H
|
|
||||||
|
|
||||||
#ifdef _SHOW_INC
|
|
||||||
#pragma message(" #Include " __FILE__)
|
|
||||||
#endif
|
|
||||||
#include <comet/datetime.h>
|
|
||||||
|
|
||||||
namespace comet
|
|
||||||
{
|
|
||||||
/*! \addtogroup Misc
|
|
||||||
*/
|
|
||||||
//@{
|
|
||||||
|
|
||||||
//! Wrapper for a date only class.
|
|
||||||
/**This is based on an integer version of DATE, except that it is an
|
|
||||||
* absolute offset from 1/1/0.
|
|
||||||
*/
|
|
||||||
struct dateonly_t : protected impl::datetime_base<long>
|
|
||||||
{
|
|
||||||
|
|
||||||
/// constructor
|
|
||||||
dateonly_t() { dt_ = 0; }
|
|
||||||
|
|
||||||
/// Construct from a datetime_t.
|
|
||||||
explicit dateonly_t( const datetime_t &dt)
|
|
||||||
{
|
|
||||||
if (dt == dt_invalid )
|
|
||||||
dt_ = dt_invalid_;
|
|
||||||
else if (dt == dt_null)
|
|
||||||
dt_ = dt_null_;
|
|
||||||
else
|
|
||||||
dt_ = split_oledate_as_absdate_( dt.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Attach from a long.
|
|
||||||
dateonly_t( const impl::auto_attach_t<long> &dateval)
|
|
||||||
{
|
|
||||||
dt_ = dateval.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get the raw 'long' value.
|
|
||||||
long get() const { return dt_; }
|
|
||||||
dateonly_t &operator=(const impl::auto_attach_t<long> & dateval)
|
|
||||||
{
|
|
||||||
dt_ = dateval.get();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Initialise as invalid.
|
|
||||||
dateonly_t( dt_invalid_t ) { dt_ = dt_invalid_; }
|
|
||||||
/// Initialise as null.
|
|
||||||
dateonly_t( dt_null_t ) { dt_ = dt_null_; }
|
|
||||||
/// Initialise as zero.
|
|
||||||
dateonly_t( dt_zero_t) { dt_ = 0; }
|
|
||||||
|
|
||||||
|
|
||||||
/// Construct from year/month/day.
|
|
||||||
dateonly_t( int year, int month, int day )
|
|
||||||
{
|
|
||||||
if (!absdate_from_date_( &dt_, year, month, day))
|
|
||||||
set_invalid_();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get a 'NULL' datetime.
|
|
||||||
static dateonly_t get_null() { return dateonly_t( dt_null_ ); }
|
|
||||||
/// Get a 'zero' datetime.
|
|
||||||
static dateonly_t get_zero() { return dateonly_t( 0 ); }
|
|
||||||
|
|
||||||
/// Return today.
|
|
||||||
static dateonly_t today()
|
|
||||||
{
|
|
||||||
return dateonly_t(datetime_t::now());
|
|
||||||
}
|
|
||||||
/// Return today (UTC).
|
|
||||||
static dateonly_t today_utc()
|
|
||||||
{
|
|
||||||
return dateonly_t(datetime_t::now_utc());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return year/month/day values.
|
|
||||||
void split(int *year, int *month, int *day) const
|
|
||||||
{
|
|
||||||
if(!good() || ! date_from_absdate_( dt_, year, month, day))
|
|
||||||
throw datetime_exception("Invalid Date");
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Set date part as year/month/day.
|
|
||||||
* \param year Year (from year 0 - as in 2000).
|
|
||||||
* \param month Month of year (1-based).
|
|
||||||
* \param day Day of month (1-based).
|
|
||||||
* \retval true Successfully set date.
|
|
||||||
* \retval false Conversion unsuccessful - date not set.
|
|
||||||
*/
|
|
||||||
bool set_date( int year, int month, int day)
|
|
||||||
{
|
|
||||||
return absdate_from_date_( &dt_, year, month, day);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Convert to datetime.
|
|
||||||
operator datetime_t() const
|
|
||||||
{
|
|
||||||
if (!good()) return datetime_t((DATE)dt_);
|
|
||||||
return datetime_t(join_absdate_as_oledate_( dt_, 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// \name Access date parts.
|
|
||||||
//@{
|
|
||||||
/// Year.
|
|
||||||
int year() const
|
|
||||||
{
|
|
||||||
int year;
|
|
||||||
split(&year,NULL,NULL);
|
|
||||||
return year;
|
|
||||||
}
|
|
||||||
/// Month of year (1-based)
|
|
||||||
int month() const
|
|
||||||
{
|
|
||||||
int year,month,day;
|
|
||||||
split(&year,&month,&day);
|
|
||||||
return month;
|
|
||||||
}
|
|
||||||
/// Day of month (1-based)
|
|
||||||
int day() const
|
|
||||||
{
|
|
||||||
int year,month,day;
|
|
||||||
split(&year,&month,&day);
|
|
||||||
return day;
|
|
||||||
}
|
|
||||||
/// The day of week.
|
|
||||||
datetime_t::day_of_week dow() const
|
|
||||||
{
|
|
||||||
int wday;
|
|
||||||
if(!good() || ! dow_from_absdate_( dt_, &wday))
|
|
||||||
throw datetime_exception("Invalid Date");
|
|
||||||
return datetime_t::day_of_week(wday);
|
|
||||||
}
|
|
||||||
/// Day of the year (0 -based)
|
|
||||||
int year_day() const
|
|
||||||
{
|
|
||||||
if (good())
|
|
||||||
{
|
|
||||||
int y,m,d;
|
|
||||||
date_from_absdate_(dt_, &y,&m,&d);
|
|
||||||
long firstday;
|
|
||||||
if ( absdate_from_date_(&firstday, y, 1, 1))
|
|
||||||
return 1 + ( dt_ - firstday);
|
|
||||||
}
|
|
||||||
throw datetime_exception("Invalid Date");
|
|
||||||
}
|
|
||||||
/// Days in the month.
|
|
||||||
int days_in_month() const
|
|
||||||
{
|
|
||||||
int year,month,day;
|
|
||||||
split(&year,&month,&day);
|
|
||||||
return days_in_month(year,month);
|
|
||||||
}
|
|
||||||
|
|
||||||
//@}
|
|
||||||
|
|
||||||
/** Add specified number of months.
|
|
||||||
* If the day is not valid, force to the last day in the month.
|
|
||||||
*/
|
|
||||||
dateonly_t &add_months(int inc_months)
|
|
||||||
{
|
|
||||||
int year,month,day;
|
|
||||||
split(&year,&month,&day);
|
|
||||||
long months = (month-1)+(year*12)+inc_months;
|
|
||||||
|
|
||||||
long quot,rem;
|
|
||||||
quot = months/12;
|
|
||||||
rem = months%12;
|
|
||||||
set_date( quot, rem+1, day);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Add specified number of years.
|
|
||||||
dateonly_t &add_years(int inc_years)
|
|
||||||
{
|
|
||||||
int year,month,day;
|
|
||||||
split(&year,&month,&day);
|
|
||||||
set_date( year+inc_years, month, day);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
///\name Comparison operators
|
|
||||||
//@{
|
|
||||||
bool operator==(const dateonly_t& date) const { return date.dt_ == dt_; }
|
|
||||||
bool operator!=(const dateonly_t& date) const{ return date.dt_ != dt_; }
|
|
||||||
bool operator<(const dateonly_t& date) const
|
|
||||||
{
|
|
||||||
COMET_ASSERT( good() );
|
|
||||||
COMET_ASSERT( date.good() );
|
|
||||||
return dt_ < date.dt_;
|
|
||||||
}
|
|
||||||
bool operator>(const dateonly_t& date) const
|
|
||||||
{
|
|
||||||
COMET_ASSERT( good() );
|
|
||||||
COMET_ASSERT( date.good() );
|
|
||||||
return dt_ > date.dt_;
|
|
||||||
}
|
|
||||||
bool operator<=(const dateonly_t& date) const
|
|
||||||
{
|
|
||||||
COMET_ASSERT( good() );
|
|
||||||
COMET_ASSERT( date.good() );
|
|
||||||
return dt_ <= date.dt_;
|
|
||||||
}
|
|
||||||
bool operator>=(const dateonly_t& date) const
|
|
||||||
{
|
|
||||||
COMET_ASSERT( good() );
|
|
||||||
COMET_ASSERT( date.good() );
|
|
||||||
return dt_ >= date.dt_;
|
|
||||||
}
|
|
||||||
bool operator==(dt_invalid_t) const { return invalid(); }
|
|
||||||
bool operator!=(dt_invalid_t) const { return !invalid(); }
|
|
||||||
bool operator==(dt_zero_t) const { return dt_==0; }
|
|
||||||
bool operator!=(dt_zero_t) const { return dt_!=0; }
|
|
||||||
bool operator==(dt_null_t) const { return null(); }
|
|
||||||
bool operator!=(dt_null_t) const { return !null(); }
|
|
||||||
//@}
|
|
||||||
|
|
||||||
///\name Arithmetic operators
|
|
||||||
//@{
|
|
||||||
dateonly_t operator+(long dateSpan) const
|
|
||||||
{
|
|
||||||
dateonly_t dt(*this);
|
|
||||||
dt+=dateSpan;
|
|
||||||
return dt;
|
|
||||||
}
|
|
||||||
dateonly_t operator-(long dateSpan) const
|
|
||||||
{
|
|
||||||
dateonly_t dt(*this);
|
|
||||||
dt-=dateSpan;
|
|
||||||
return dt;
|
|
||||||
}
|
|
||||||
dateonly_t& operator+=(long dateSpan)
|
|
||||||
{
|
|
||||||
COMET_ASSERT( good() );
|
|
||||||
dt_ += dateSpan;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
dateonly_t& operator-=(long dateSpan)
|
|
||||||
{
|
|
||||||
COMET_ASSERT( good() );
|
|
||||||
dt_ -= dateSpan;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
long operator-(const dateonly_t& date) const
|
|
||||||
{
|
|
||||||
COMET_ASSERT( good() );
|
|
||||||
COMET_ASSERT( date.good() );
|
|
||||||
return dt_ - date.dt_;
|
|
||||||
}
|
|
||||||
dateonly_t &operator++()
|
|
||||||
{
|
|
||||||
COMET_ASSERT( good() );
|
|
||||||
++dt_;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
dateonly_t operator++(int)
|
|
||||||
{
|
|
||||||
COMET_ASSERT( good() );
|
|
||||||
dateonly_t t(*this);
|
|
||||||
++dt_;
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
dateonly_t &operator--()
|
|
||||||
{
|
|
||||||
COMET_ASSERT( good() );
|
|
||||||
--dt_;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
dateonly_t operator--(int)
|
|
||||||
{
|
|
||||||
COMET_ASSERT( good() );
|
|
||||||
dateonly_t t(*this);
|
|
||||||
--dt_;
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
//@}
|
|
||||||
|
|
||||||
/// return true if the date is marked 'invalid'.
|
|
||||||
inline bool invalid() const { return dt_ == ( dt_invalid_); }
|
|
||||||
/// Return true if the date is marked 'null'
|
|
||||||
inline bool null() const { return dt_ == ( dt_null_); }
|
|
||||||
|
|
||||||
/// return true if date is zero
|
|
||||||
inline bool zero() const { return dt_ == 0; }
|
|
||||||
|
|
||||||
/// Return true if the date is usable.
|
|
||||||
inline bool good() const
|
|
||||||
{
|
|
||||||
switch (dt_)
|
|
||||||
{
|
|
||||||
case 0: case dt_invalid_: case dt_null_: return false;
|
|
||||||
default: return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Format as bstr.
|
|
||||||
* \param flags Format (can be or-ed). All format_flags are valid.
|
|
||||||
* \param locale Locale ID (default to User Default.
|
|
||||||
*/
|
|
||||||
bstr_t format( datetime_t::format_flags flags = datetime_t::ff_default , LCID locale = LOCALE_USER_DEFAULT) const
|
|
||||||
{
|
|
||||||
flags = datetime_t::format_flags((flags | datetime_t::ff_date_only) & ~datetime_t::ff_time_only);
|
|
||||||
bstr_t strDate;
|
|
||||||
if (null() || invalid())
|
|
||||||
return strDate;
|
|
||||||
|
|
||||||
DATE dt = join_absdate_as_oledate_( dt_, 0);
|
|
||||||
VarBstrFromDate(dt, locale, flags, strDate.out()) | raise_exception;
|
|
||||||
return strDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Parse bstring to a datetime_t.
|
|
||||||
* \param val String to parse.
|
|
||||||
* \param flags valid format_flags are: ff_default, ff_system_locale, ff_hijri, ff_time_only, ff_date_only
|
|
||||||
* \param locale Locale to use. Default \p locale is the user default.
|
|
||||||
*/
|
|
||||||
dateonly_t &parse( const bstr_t &val, datetime_t::format_flags flags = datetime_t::ff_default, LCID locale = LOCALE_USER_DEFAULT)
|
|
||||||
{
|
|
||||||
flags = datetime_t::format_flags((flags | datetime_t::ff_date_only) & ~datetime_t::ff_time_only);
|
|
||||||
DATE dt;
|
|
||||||
VarDateFromStr( val.in(), locale, flags, &dt) | raise_exception;
|
|
||||||
dt_ = split_oledate_as_absdate_( dt);
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Format as basic_string.
|
|
||||||
* \param fmt See system documentation for strftime for details.
|
|
||||||
*/
|
|
||||||
template<typename CHAR>
|
|
||||||
std::basic_string<CHAR> format( const std::basic_string<CHAR> &fmt ) const
|
|
||||||
{
|
|
||||||
return format(fmt.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Format as basic_string.
|
|
||||||
* \param fmt See system documentation for strftime for details.
|
|
||||||
*/
|
|
||||||
template<typename CHAR>
|
|
||||||
std::basic_string<CHAR> format( const CHAR *fmt ) const
|
|
||||||
{
|
|
||||||
// Just use datetime_t to handle this.
|
|
||||||
datetime_t dt(*this);
|
|
||||||
return dt.format(fmt);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Stream operator.
|
|
||||||
friend
|
|
||||||
std::basic_ostream<char> &operator<<(std::basic_ostream<char> &os, const dateonly_t &val)
|
|
||||||
{
|
|
||||||
os << val.format();
|
|
||||||
return os;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Stream operator.
|
|
||||||
friend
|
|
||||||
std::basic_ostream<wchar_t> &operator<<(std::basic_ostream<wchar_t> &os, const dateonly_t &val)
|
|
||||||
{
|
|
||||||
os << val.format();
|
|
||||||
return os;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int days_in_month(int year, int month)
|
|
||||||
{
|
|
||||||
return impl::datetime_base<long>::days_in_month(year,month);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
explicit dateonly_t(long l) { dt_ = l; }
|
|
||||||
};
|
|
||||||
//@}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* INCLUDE_COMET_DATE_H */
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,675 +0,0 @@
|
||||||
/** \file
|
|
||||||
* Provides dispatch driver via wrap_t< ::IDispatch>
|
|
||||||
* Provides dynamic implementation of IDispatch via dynamic_dispatch.
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* Copyright © 2001 Sofus Mortensen
|
|
||||||
*
|
|
||||||
* This material is provided "as is", with absolutely no warranty
|
|
||||||
* expressed or implied. Any use is at your own risk. Permission to
|
|
||||||
* use or copy this software for any purpose is hereby granted without
|
|
||||||
* fee, provided the above notices are retained on all copies.
|
|
||||||
* Permission to modify the code and to distribute modified code is
|
|
||||||
* granted, provided the above notices are retained, and a notice that
|
|
||||||
* the code was modified is included with the above copyright notice.
|
|
||||||
*
|
|
||||||
* This header is part of Comet version 2.
|
|
||||||
* https://github.com/alamaison/comet
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef COMET_DISPATCH_H
|
|
||||||
#define COMET_DISPATCH_H
|
|
||||||
|
|
||||||
#include <comet/ptr.h>
|
|
||||||
|
|
||||||
#include <map>
|
|
||||||
|
|
||||||
namespace comet {
|
|
||||||
/*! \addtogroup Interfaces
|
|
||||||
*/
|
|
||||||
//@{
|
|
||||||
|
|
||||||
/** Specialisation of wrap_t for IDispatch.
|
|
||||||
* Implements wrappers for the call-by name and call-by dispid for IDispatch methods
|
|
||||||
* and properties. The wrapper supports properties with up to 3 arguments and methods
|
|
||||||
* with up to 4 arguments.
|
|
||||||
* \code
|
|
||||||
com_ptr<IDispatch> disp( my_dual_interface);
|
|
||||||
variant_t val = disp->get(L"Name");
|
|
||||||
* \endcode
|
|
||||||
* See \ref cometcomptrsmartwrapper for details on wrap_t.
|
|
||||||
*/
|
|
||||||
template<> struct wrap_t< ::IDispatch>
|
|
||||||
{
|
|
||||||
/** Get property by dispid.
|
|
||||||
*/
|
|
||||||
variant_t get(DISPID id)
|
|
||||||
{
|
|
||||||
VARIANT result;
|
|
||||||
VARIANT* vars = 0;
|
|
||||||
DISPPARAMS disp = { vars, 0, 0, 0 };
|
|
||||||
HRESULT hr = raw(this)->Invoke(id, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &disp, &result, 0, 0);
|
|
||||||
if (FAILED(hr)) throw_com_error(raw(this), hr);
|
|
||||||
return auto_attach(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Get property by name.
|
|
||||||
*/
|
|
||||||
variant_t get(const wchar_t* name)
|
|
||||||
{
|
|
||||||
DISPID id;
|
|
||||||
HRESULT hr = raw(this)->GetIDsOfNames(IID_NULL, const_cast<OLECHAR**>(&name), 1, LOCALE_USER_DEFAULT, &id);
|
|
||||||
if (FAILED(hr)) throw_com_error(raw(this), hr);
|
|
||||||
return get(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Get property by dispid with 1 argument.
|
|
||||||
*/
|
|
||||||
variant_t get(DISPID id, const variant_t& a0)
|
|
||||||
{
|
|
||||||
VARIANT result;
|
|
||||||
VARIANT vars[1]; vars[0] = a0.in();
|
|
||||||
DISPPARAMS disp = { vars, 0, 1, 0 };
|
|
||||||
HRESULT hr = raw(this)->Invoke(id, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &disp, &result, 0, 0);
|
|
||||||
if (FAILED(hr)) throw_com_error(raw(this), hr);
|
|
||||||
return auto_attach(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Get property by name with 1 argument.
|
|
||||||
*/
|
|
||||||
variant_t get(const wchar_t* name, const variant_t& a0)
|
|
||||||
{
|
|
||||||
DISPID id;
|
|
||||||
HRESULT hr = raw(this)->GetIDsOfNames(IID_NULL, const_cast<OLECHAR**>(&name), 1, LOCALE_USER_DEFAULT, &id);
|
|
||||||
if (FAILED(hr)) throw_com_error(raw(this), hr);
|
|
||||||
return get(id, a0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Get property by dispid with 2 arguments.
|
|
||||||
*/
|
|
||||||
variant_t get(DISPID id, const variant_t& a1, const variant_t& a0)
|
|
||||||
{
|
|
||||||
VARIANT result;
|
|
||||||
VARIANT vars[2]; vars[0] = a0.in(); vars[1] = a1.in();
|
|
||||||
DISPPARAMS disp = { vars, 0, 2, 0 };
|
|
||||||
HRESULT hr = raw(this)->Invoke(id, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &disp, &result, 0, 0);
|
|
||||||
if (FAILED(hr)) throw_com_error(raw(this), hr);
|
|
||||||
return auto_attach(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Get property by name with 2 arguments.
|
|
||||||
*/
|
|
||||||
variant_t get(const wchar_t* name, const variant_t& a1, const variant_t& a0)
|
|
||||||
{
|
|
||||||
DISPID id;
|
|
||||||
HRESULT hr = raw(this)->GetIDsOfNames(IID_NULL, const_cast<OLECHAR**>(&name), 1, LOCALE_USER_DEFAULT, &id);
|
|
||||||
if (FAILED(hr)) throw_com_error(raw(this), hr);
|
|
||||||
return get(id, a1, a0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Get property by dispid with 3 arguments.
|
|
||||||
*/
|
|
||||||
variant_t get(DISPID id, const variant_t& a2, const variant_t& a1, const variant_t& a0)
|
|
||||||
{
|
|
||||||
VARIANT result;
|
|
||||||
VARIANT vars[3]; vars[0] = a0.in(); vars[1] = a1.in(); vars[2] = a2.in();
|
|
||||||
DISPPARAMS disp = { vars, 0, 3, 0 };
|
|
||||||
HRESULT hr = raw(this)->Invoke(id, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &disp, &result, 0, 0);
|
|
||||||
if (FAILED(hr)) throw_com_error(raw(this), hr);
|
|
||||||
return auto_attach(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Get property by name with 3 arguments.
|
|
||||||
*/
|
|
||||||
variant_t get(const wchar_t* name, const variant_t& a2, const variant_t& a1, const variant_t& a0)
|
|
||||||
{
|
|
||||||
DISPID id;
|
|
||||||
HRESULT hr = raw(this)->GetIDsOfNames(IID_NULL, const_cast<OLECHAR**>(&name), 1, LOCALE_USER_DEFAULT, &id);
|
|
||||||
if (FAILED(hr)) throw_com_error(raw(this), hr);
|
|
||||||
return get(id, a2, a1, a0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Put property by dispid.
|
|
||||||
*/
|
|
||||||
void put(DISPID id, const variant_t& val)
|
|
||||||
{
|
|
||||||
VARIANT vars[1]; vars[0] = val.in();
|
|
||||||
DISPID did = DISPID_PROPERTYPUT;
|
|
||||||
DISPPARAMS disp = { vars, &did, 1, 1 };
|
|
||||||
HRESULT hr = raw(this)->Invoke(id, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUT, &disp, 0, 0, 0);
|
|
||||||
if (FAILED(hr)) throw_com_error(raw(this), hr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Put property by name.
|
|
||||||
*/
|
|
||||||
void put(const wchar_t* name, const variant_t& val)
|
|
||||||
{
|
|
||||||
DISPID id;
|
|
||||||
HRESULT hr = raw(this)->GetIDsOfNames(IID_NULL, const_cast<OLECHAR**>(&name), 1, LOCALE_USER_DEFAULT, &id);
|
|
||||||
if (FAILED(hr)) throw_com_error(raw(this), hr);
|
|
||||||
put(id, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Put property with 1 argument by dispid.
|
|
||||||
*/
|
|
||||||
void put(DISPID id, const variant_t& a1, const variant_t& val)
|
|
||||||
{
|
|
||||||
VARIANT vars[2]; vars[0] = val.in(); vars[1] = a1.in();
|
|
||||||
DISPID did = DISPID_PROPERTYPUT;
|
|
||||||
DISPPARAMS disp = { vars, &did, 2, 1 };
|
|
||||||
HRESULT hr = raw(this)->Invoke(id, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUT, &disp, 0, 0, 0);
|
|
||||||
if (FAILED(hr)) throw_com_error(raw(this), hr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Put property with 1 argument by name.
|
|
||||||
*/
|
|
||||||
void put(const wchar_t* name, const variant_t& a1, const variant_t& val)
|
|
||||||
{
|
|
||||||
DISPID id;
|
|
||||||
HRESULT hr = raw(this)->GetIDsOfNames(IID_NULL, const_cast<OLECHAR**>(&name), 1, LOCALE_USER_DEFAULT, &id);
|
|
||||||
if (FAILED(hr)) throw_com_error(raw(this), hr);
|
|
||||||
put(id, a1, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Put property with 2 arguments by dispid.
|
|
||||||
*/
|
|
||||||
void put(DISPID id, const variant_t& a2, const variant_t& a1, const variant_t& val)
|
|
||||||
{
|
|
||||||
VARIANT vars[3]; vars[0] = val.in(); vars[1] = a1.in(); vars[2] = a2.in();
|
|
||||||
DISPID did = DISPID_PROPERTYPUT;
|
|
||||||
DISPPARAMS disp = { vars, &did, 3, 1 };
|
|
||||||
HRESULT hr = raw(this)->Invoke(id, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUT, &disp, 0, 0, 0);
|
|
||||||
if (FAILED(hr)) throw_com_error(raw(this), hr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Put property with 2 arguments by name.
|
|
||||||
*/
|
|
||||||
void put(const wchar_t* name, const variant_t& a2, const variant_t& a1, const variant_t& val)
|
|
||||||
{
|
|
||||||
DISPID id;
|
|
||||||
HRESULT hr = raw(this)->GetIDsOfNames(IID_NULL, const_cast<OLECHAR**>(&name), 1, LOCALE_USER_DEFAULT, &id);
|
|
||||||
if (FAILED(hr)) throw_com_error(raw(this), hr);
|
|
||||||
put(id, a2, a1, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Put property with 3 arguments by dispid.
|
|
||||||
*/
|
|
||||||
void put(DISPID id, const variant_t& a3, const variant_t& a2, const variant_t& a1, const variant_t& val)
|
|
||||||
{
|
|
||||||
VARIANT vars[4]; vars[0] = val.in(); vars[1] = a1.in(); vars[2] = a2.in(); vars[3] = a3.in();
|
|
||||||
DISPID did = DISPID_PROPERTYPUT;
|
|
||||||
DISPPARAMS disp = { vars, &did, 4, 1 };
|
|
||||||
HRESULT hr = raw(this)->Invoke(id, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUT, &disp, 0, 0, 0);
|
|
||||||
if (FAILED(hr)) throw_com_error(raw(this), hr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Put property with 3 arguments by name.
|
|
||||||
*/
|
|
||||||
void put(const wchar_t* name, const variant_t& a3, const variant_t& a2, const variant_t& a1, const variant_t& val)
|
|
||||||
{
|
|
||||||
DISPID id;
|
|
||||||
HRESULT hr = raw(this)->GetIDsOfNames(IID_NULL, const_cast<OLECHAR**>(&name), 1, LOCALE_USER_DEFAULT, &id);
|
|
||||||
if (FAILED(hr)) throw_com_error(raw(this), hr);
|
|
||||||
put(id, a3, a2, a1, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Put property by reference by dispid.
|
|
||||||
*/
|
|
||||||
void putref(DISPID id, const variant_t& val)
|
|
||||||
{
|
|
||||||
VARIANT vars[1]; vars[0] = val.in();
|
|
||||||
DISPID did = DISPID_PROPERTYPUT;
|
|
||||||
DISPPARAMS disp = { vars, &did, 1, 1 };
|
|
||||||
HRESULT hr = raw(this)->Invoke(id, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUTREF, &disp, 0, 0, 0);
|
|
||||||
if (FAILED(hr)) throw_com_error(raw(this), hr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Put property by reference by name.
|
|
||||||
*/
|
|
||||||
void putref(const wchar_t* name, const variant_t& val)
|
|
||||||
{
|
|
||||||
DISPID id;
|
|
||||||
HRESULT hr = raw(this)->GetIDsOfNames(IID_NULL, const_cast<OLECHAR**>(&name), 1, LOCALE_USER_DEFAULT, &id);
|
|
||||||
if (FAILED(hr)) throw_com_error(raw(this), hr);
|
|
||||||
putref(id, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
void putref(DISPID id, const variant_t& a1, const variant_t& val)
|
|
||||||
{
|
|
||||||
VARIANT vars[2]; vars[0] = val.in(); vars[1] = a1.in();
|
|
||||||
DISPID did = DISPID_PROPERTYPUT;
|
|
||||||
DISPPARAMS disp = { vars, &did, 2, 1 };
|
|
||||||
HRESULT hr = raw(this)->Invoke(id, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUTREF, &disp, 0, 0, 0);
|
|
||||||
if (FAILED(hr)) throw_com_error(raw(this), hr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void putref(const wchar_t* name, const variant_t& a1, const variant_t& val)
|
|
||||||
{
|
|
||||||
DISPID id;
|
|
||||||
HRESULT hr = raw(this)->GetIDsOfNames(IID_NULL, const_cast<OLECHAR**>(&name), 1, LOCALE_USER_DEFAULT, &id);
|
|
||||||
if (FAILED(hr)) throw_com_error(raw(this), hr);
|
|
||||||
putref(id, a1, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
void putref(DISPID id, const variant_t& a2, const variant_t& a1, const variant_t& val)
|
|
||||||
{
|
|
||||||
VARIANT vars[3]; vars[0] = val.in(); vars[1] = a1.in(); vars[2] = a2.in();
|
|
||||||
DISPID did = DISPID_PROPERTYPUT;
|
|
||||||
DISPPARAMS disp = { vars, &did, 3, 1 };
|
|
||||||
HRESULT hr = raw(this)->Invoke(id, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUTREF, &disp, 0, 0, 0);
|
|
||||||
if (FAILED(hr)) throw_com_error(raw(this), hr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void putref(const wchar_t* name, const variant_t& a2, const variant_t& a1, const variant_t& val)
|
|
||||||
{
|
|
||||||
DISPID id;
|
|
||||||
HRESULT hr = raw(this)->GetIDsOfNames(IID_NULL, const_cast<OLECHAR**>(&name), 1, LOCALE_USER_DEFAULT, &id);
|
|
||||||
if (FAILED(hr)) throw_com_error(raw(this), hr);
|
|
||||||
putref(id, a2, a1, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
void putref(DISPID id, const variant_t& a3, const variant_t& a2, const variant_t& a1, const variant_t& val)
|
|
||||||
{
|
|
||||||
VARIANT vars[4]; vars[0] = val.in(); vars[1] = a1.in(); vars[2] = a2.in(); vars[3] = a3.in();
|
|
||||||
DISPID did = DISPID_PROPERTYPUT;
|
|
||||||
DISPPARAMS disp = { vars, &did, 4, 1 };
|
|
||||||
HRESULT hr = raw(this)->Invoke(id, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUTREF, &disp, 0, 0, 0);
|
|
||||||
if (FAILED(hr)) throw_com_error(raw(this), hr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void putref(const wchar_t* name, const variant_t& a3, const variant_t& a2, const variant_t& a1, const variant_t& val)
|
|
||||||
{
|
|
||||||
DISPID id;
|
|
||||||
HRESULT hr = raw(this)->GetIDsOfNames(IID_NULL, const_cast<OLECHAR**>(&name), 1, LOCALE_USER_DEFAULT, &id);
|
|
||||||
if (FAILED(hr)) throw_com_error(raw(this), hr);
|
|
||||||
putref(id, a3, a2, a1, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Call method by dispid.
|
|
||||||
*/
|
|
||||||
variant_t call(DISPID id)
|
|
||||||
{
|
|
||||||
VARIANT result;
|
|
||||||
VARIANT* vars = 0;
|
|
||||||
DISPPARAMS disp = { vars, 0, 0, 0 };
|
|
||||||
HRESULT hr = raw(this)->Invoke(id, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, &result, 0, 0);
|
|
||||||
if (FAILED(hr)) throw_com_error(raw(this), hr);
|
|
||||||
return auto_attach(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Call method by name.
|
|
||||||
*/
|
|
||||||
variant_t call(const wchar_t* name)
|
|
||||||
{
|
|
||||||
DISPID id;
|
|
||||||
HRESULT hr = raw(this)->GetIDsOfNames(IID_NULL, const_cast<OLECHAR**>(&name), 1, LOCALE_USER_DEFAULT, &id);
|
|
||||||
if (FAILED(hr)) throw_com_error(raw(this), hr);
|
|
||||||
return call(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
variant_t call(DISPID id, const variant_t& a0)
|
|
||||||
{
|
|
||||||
VARIANT result;
|
|
||||||
VARIANT vars[1]; vars[0] = a0.in();
|
|
||||||
DISPPARAMS disp = { vars, 0, 1, 0 };
|
|
||||||
HRESULT hr = raw(this)->Invoke(id, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, &result, 0, 0);
|
|
||||||
if (FAILED(hr)) throw_com_error(raw(this), hr);
|
|
||||||
return auto_attach(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
variant_t call(const wchar_t* name, const variant_t& a0)
|
|
||||||
{
|
|
||||||
DISPID id;
|
|
||||||
HRESULT hr = raw(this)->GetIDsOfNames(IID_NULL, const_cast<OLECHAR**>(&name), 1, LOCALE_USER_DEFAULT, &id);
|
|
||||||
if (FAILED(hr)) throw_com_error(raw(this), hr);
|
|
||||||
return call(id, a0);
|
|
||||||
}
|
|
||||||
|
|
||||||
variant_t call(DISPID id, const variant_t& a1, const variant_t& a0)
|
|
||||||
{
|
|
||||||
VARIANT result;
|
|
||||||
VARIANT vars[2]; vars[0] = a0.in(); vars[1] = a1.in();
|
|
||||||
DISPPARAMS disp = { vars, 0, 2, 0 };
|
|
||||||
HRESULT hr = raw(this)->Invoke(id, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, &result, 0, 0);
|
|
||||||
if (FAILED(hr)) throw_com_error(raw(this), hr);
|
|
||||||
return auto_attach(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
variant_t call(const wchar_t* name, const variant_t& a1, const variant_t& a0)
|
|
||||||
{
|
|
||||||
DISPID id;
|
|
||||||
HRESULT hr = raw(this)->GetIDsOfNames(IID_NULL, const_cast<OLECHAR**>(&name), 1, LOCALE_USER_DEFAULT, &id);
|
|
||||||
if (FAILED(hr)) throw_com_error(raw(this), hr);
|
|
||||||
return call(id, a1, a0);
|
|
||||||
}
|
|
||||||
|
|
||||||
variant_t call(DISPID id, const variant_t& a2, const variant_t& a1, const variant_t& a0)
|
|
||||||
{
|
|
||||||
VARIANT result;
|
|
||||||
VARIANT vars[3]; vars[0] = a0.in(); vars[1] = a1.in(); vars[2] = a2.in();
|
|
||||||
DISPPARAMS disp = { vars, 0, 3, 0 };
|
|
||||||
HRESULT hr = raw(this)->Invoke(id, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, &result, 0, 0);
|
|
||||||
if (FAILED(hr)) throw_com_error(raw(this), hr);
|
|
||||||
return auto_attach(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
variant_t call(const wchar_t* name, const variant_t& a2, const variant_t& a1, const variant_t& a0)
|
|
||||||
{
|
|
||||||
DISPID id;
|
|
||||||
HRESULT hr = raw(this)->GetIDsOfNames(IID_NULL, const_cast<OLECHAR**>(&name), 1, LOCALE_USER_DEFAULT, &id);
|
|
||||||
if (FAILED(hr)) throw_com_error(raw(this), hr);
|
|
||||||
return call(id, a2, a1, a0);
|
|
||||||
}
|
|
||||||
|
|
||||||
variant_t call(DISPID id, const variant_t& a3, const variant_t& a2, const variant_t& a1, const variant_t& a0)
|
|
||||||
{
|
|
||||||
VARIANT result;
|
|
||||||
VARIANT vars[4]; vars[0] = a0.in(); vars[1] = a1.in(); vars[2] = a2.in(); vars[3] = a3.in();
|
|
||||||
DISPPARAMS disp = { vars, 0, 4, 0 };
|
|
||||||
HRESULT hr = raw(this)->Invoke(id, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, &result, 0, 0);
|
|
||||||
if (FAILED(hr)) throw_com_error(raw(this), hr);
|
|
||||||
return auto_attach(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
variant_t call(const wchar_t* name, const variant_t& a3, const variant_t& a2, const variant_t& a1, const variant_t& a0)
|
|
||||||
{
|
|
||||||
DISPID id;
|
|
||||||
HRESULT hr = raw(this)->GetIDsOfNames(IID_NULL, const_cast<OLECHAR**>(&name), 1, LOCALE_USER_DEFAULT, &id);
|
|
||||||
if (FAILED(hr)) throw_com_error(raw(this), hr);
|
|
||||||
return call(id, a3, a2, a1, a0);
|
|
||||||
}
|
|
||||||
variant_t call(DISPID id, const variant_t& a4, const variant_t& a3, const variant_t& a2, const variant_t& a1, const variant_t& a0)
|
|
||||||
{
|
|
||||||
VARIANT result;
|
|
||||||
VARIANT vars[5]; vars[0] = a0.in(); vars[1] = a1.in(); vars[2] = a2.in(); vars[3] = a3.in(); vars[4] = a4.in();
|
|
||||||
DISPPARAMS disp = { vars, 0, 5, 0 };
|
|
||||||
HRESULT hr = raw(this)->Invoke(id, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, &result, 0, 0);
|
|
||||||
if (FAILED(hr)) throw_com_error(raw(this), hr);
|
|
||||||
return auto_attach(result);
|
|
||||||
}
|
|
||||||
variant_t call(const wchar_t* name, const variant_t& a4, const variant_t& a3, const variant_t& a2, const variant_t& a1, const variant_t& a0)
|
|
||||||
{
|
|
||||||
DISPID id;
|
|
||||||
HRESULT hr = raw(this)->GetIDsOfNames(IID_NULL, const_cast<OLECHAR**>(&name), 1, LOCALE_USER_DEFAULT, &id);
|
|
||||||
if (FAILED(hr)) throw_com_error(raw(this), hr);
|
|
||||||
return call(id, a4, a3, a2, a1, a0);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
/** \class dynamic_dispatch dispatch.h comet/dispatch.h
|
|
||||||
* Implementation of a dynamic IDispatch, allowing methods to be added to
|
|
||||||
* an IDispatch implementation.
|
|
||||||
* The class needs to be inherited from to be able to add methods.
|
|
||||||
* Each method can have up to 4 parameters.
|
|
||||||
*/
|
|
||||||
|
|
||||||
template<typename BASE> class ATL_NO_VTABLE dynamic_dispatch : public ::IDispatch {
|
|
||||||
|
|
||||||
struct method_ptr {
|
|
||||||
bool has_retval;
|
|
||||||
union {
|
|
||||||
void (BASE::*pm00)();
|
|
||||||
void (BASE::*pm01)(const variant_t&);
|
|
||||||
void (BASE::*pm02)(const variant_t&, const variant_t&);
|
|
||||||
void (BASE::*pm03)(const variant_t&, const variant_t&, const variant_t&);
|
|
||||||
void (BASE::*pm04)(const variant_t&, const variant_t&, const variant_t&, const variant_t&);
|
|
||||||
|
|
||||||
variant_t (BASE::*pm10)();
|
|
||||||
variant_t (BASE::*pm11)(const variant_t&);
|
|
||||||
variant_t (BASE::*pm12)(const variant_t&, const variant_t&);
|
|
||||||
variant_t (BASE::*pm13)(const variant_t&, const variant_t&, const variant_t&);
|
|
||||||
variant_t (BASE::*pm14)(const variant_t&, const variant_t&, const variant_t&, const variant_t&);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef std::map<std::wstring, DISPID> NAMEMAP;
|
|
||||||
NAMEMAP name_map_;
|
|
||||||
|
|
||||||
// Workaround VC internal compiler error
|
|
||||||
struct wrap_map_t {
|
|
||||||
std::map<unsigned, method_ptr> m;
|
|
||||||
};
|
|
||||||
typedef std::map<DISPID, wrap_map_t > MAP;
|
|
||||||
MAP map_;
|
|
||||||
|
|
||||||
void add_method(const wchar_t* name, method_ptr p, DISPID id, int type)
|
|
||||||
{
|
|
||||||
if (id == flag_value)
|
|
||||||
{
|
|
||||||
NAMEMAP::const_iterator it = name_map_.find(name);
|
|
||||||
if (it == name_map_.end())
|
|
||||||
{
|
|
||||||
id = 100000 + map_.size();
|
|
||||||
while (map_.find(id) != map_.end()) ++id;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
id = it->second;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
name_map_[name] = id;
|
|
||||||
map_[id].m[type] = p;
|
|
||||||
}
|
|
||||||
enum { flag_value = MINLONG };
|
|
||||||
public:
|
|
||||||
typedef ::IDispatch interface_is;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
void remove(const wchar_t* name)
|
|
||||||
{
|
|
||||||
NAMEMAP::iterator it = name_map_.find(name);
|
|
||||||
if (it != name_map_.end()) {
|
|
||||||
DISPID id = it->second;
|
|
||||||
name_map_.erase(it);
|
|
||||||
|
|
||||||
map_.erase(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void add_method(const wchar_t* name, void (BASE::*pm)(), DISPID id = flag_value)
|
|
||||||
{ method_ptr p; p.has_retval = false; p.pm00 = pm; add_method( name, p, id, 0 << 16 | DISPATCH_METHOD ); }
|
|
||||||
|
|
||||||
void add_method(const wchar_t* name, void (BASE::*pm)(const variant_t&), DISPID id = flag_value)
|
|
||||||
{ method_ptr p; p.has_retval = false; p.pm01 = pm; add_method( name, p, id, 1 << 16 | DISPATCH_METHOD ); }
|
|
||||||
|
|
||||||
void add_method(const wchar_t* name, void (BASE::*pm)(const variant_t&, const variant_t&), DISPID id = flag_value)
|
|
||||||
{ method_ptr p; p.has_retval = false; p.pm02 = pm; add_method( name, p, id, 2 << 16 | DISPATCH_METHOD ); }
|
|
||||||
|
|
||||||
void add_method(const wchar_t* name, void (BASE::*pm)(const variant_t&, const variant_t&, const variant_t&), DISPID id = flag_value)
|
|
||||||
{ method_ptr p; p.has_retval = false; p.pm03 = pm; add_method( name, p, id, 3 << 16 | DISPATCH_METHOD ); }
|
|
||||||
|
|
||||||
void add_method(const wchar_t* name, void (BASE::*pm)(const variant_t&, const variant_t&, const variant_t&, const variant_t&), DISPID id = flag_value)
|
|
||||||
{ method_ptr p; p.has_retval = false; p.pm04 = pm; add_method( name, p, id, 4 << 16 | DISPATCH_METHOD ); }
|
|
||||||
|
|
||||||
void add_method(const wchar_t* name, variant_t (BASE::*pm)(), DISPID id = flag_value)
|
|
||||||
{ method_ptr p; p.has_retval = true; p.pm10 = pm; add_method( name, p, id, 0 << 16 | DISPATCH_METHOD ); }
|
|
||||||
|
|
||||||
void add_method(const wchar_t* name, variant_t (BASE::*pm)(const variant_t&), DISPID id = flag_value)
|
|
||||||
{ method_ptr p; p.has_retval = true; p.pm11 = pm; add_method( name, p, id, 1 << 16 | DISPATCH_METHOD ); }
|
|
||||||
|
|
||||||
void add_method(const wchar_t* name, variant_t (BASE::*pm)(const variant_t&, const variant_t&), DISPID id = flag_value)
|
|
||||||
{ method_ptr p; p.has_retval = true; p.pm12 = pm; add_method( name, p, id, 2 << 16 | DISPATCH_METHOD ); }
|
|
||||||
|
|
||||||
void add_method(const wchar_t* name, variant_t (BASE::*pm)(const variant_t&, const variant_t&, const variant_t&), DISPID id = flag_value)
|
|
||||||
{ method_ptr p; p.has_retval = true; p.pm13 = pm; add_method( name, p, id, 3 << 16 | DISPATCH_METHOD ); }
|
|
||||||
|
|
||||||
void add_method(const wchar_t* name, variant_t (BASE::*pm)(const variant_t&, const variant_t&, const variant_t&, const variant_t&), DISPID id = flag_value)
|
|
||||||
{ method_ptr p; p.has_retval = true; p.pm14 = pm; add_method( name, p, id, 4 << 16 | DISPATCH_METHOD ); }
|
|
||||||
|
|
||||||
void add_put_property(const wchar_t* name, void (BASE::*pm)(const variant_t&), DISPID id = flag_value)
|
|
||||||
{ method_ptr p; p.has_retval = false; p.pm01 = pm; add_method( name, p, id, 1 << 16 | DISPATCH_PROPERTYPUT ); }
|
|
||||||
|
|
||||||
void add_put_property(const wchar_t* name, void (BASE::*pm)(const variant_t&, const variant_t&), DISPID id = flag_value)
|
|
||||||
{ method_ptr p; p.has_retval = false; p.pm02 = pm; add_method( name, p, id, 2 << 16 | DISPATCH_PROPERTYPUT ); }
|
|
||||||
|
|
||||||
void add_put_property(const wchar_t* name, void (BASE::*pm)(const variant_t&, const variant_t&, const variant_t&), DISPID id = flag_value)
|
|
||||||
{ method_ptr p; p.has_retval = false; p.pm03 = pm; add_method( name, p, id, 3 << 16 | DISPATCH_PROPERTYPUT ); }
|
|
||||||
|
|
||||||
void add_put_property(const wchar_t* name, void (BASE::*pm)(const variant_t&, const variant_t&, const variant_t&, const variant_t&), DISPID id = flag_value)
|
|
||||||
{ method_ptr p; p.has_retval = false; p.pm04 = pm; add_method( name, p, id, 4 << 16 | DISPATCH_PROPERTYPUT ); }
|
|
||||||
|
|
||||||
void add_putref_property(const wchar_t* name, void (BASE::*pm)(const variant_t&), DISPID id = flag_value)
|
|
||||||
{ method_ptr p; p.has_retval = false; p.pm01 = pm; add_method( name, p, id, 1 << 16 | DISPATCH_PROPERTYPUTREF ); }
|
|
||||||
|
|
||||||
void add_putref_property(const wchar_t* name, void (BASE::*pm)(const variant_t&, const variant_t&), DISPID id = flag_value)
|
|
||||||
{ method_ptr p; p.has_retval = false; p.pm02 = pm; add_method( name, p, id, 2 << 16 | DISPATCH_PROPERTYPUTREF ); }
|
|
||||||
|
|
||||||
void add_putref_property(const wchar_t* name, void (BASE::*pm)(const variant_t&, const variant_t&, const variant_t&), DISPID id = flag_value)
|
|
||||||
{ method_ptr p; p.has_retval = false; p.pm03 = pm; add_method( name, p, id, 3 << 16 | DISPATCH_PROPERTYPUTREF ); }
|
|
||||||
|
|
||||||
void add_putref_property(const wchar_t* name, void (BASE::*pm)(const variant_t&, const variant_t&, const variant_t&, const variant_t&), DISPID id = flag_value)
|
|
||||||
{ method_ptr p; p.has_retval = false; p.pm04 = pm; add_method( name, p, id, 4 << 16 | DISPATCH_PROPERTYPUTREF ); }
|
|
||||||
|
|
||||||
void add_get_property(const wchar_t* name, variant_t (BASE::*pm)(), DISPID id = flag_value)
|
|
||||||
{ method_ptr p; p.has_retval = true; p.pm10 = pm; add_method( name, p, id, 0 << 16 | DISPATCH_PROPERTYGET ); }
|
|
||||||
|
|
||||||
void add_get_property(const wchar_t* name, variant_t (BASE::*pm)(const variant_t&), DISPID id = flag_value)
|
|
||||||
{ method_ptr p; p.has_retval = true; p.pm11 = pm; add_method( name, p, id, 1 << 16 | DISPATCH_PROPERTYGET ); }
|
|
||||||
|
|
||||||
void add_get_property(const wchar_t* name, variant_t (BASE::*pm)(const variant_t&, const variant_t&), DISPID id = flag_value)
|
|
||||||
{ method_ptr p; p.has_retval = true; p.pm12 = pm; add_method( name, p, id, 2 << 16 | DISPATCH_PROPERTYGET ); }
|
|
||||||
|
|
||||||
void add_get_property(const wchar_t* name, variant_t (BASE::*pm)(const variant_t&, const variant_t&, const variant_t&), DISPID id = flag_value)
|
|
||||||
{ method_ptr p; p.has_retval = true; p.pm13 = pm; add_method( name, p, id, 3 << 16 | DISPATCH_PROPERTYGET ); }
|
|
||||||
|
|
||||||
void add_get_property(const wchar_t* name, variant_t (BASE::*pm)(const variant_t&, const variant_t&, const variant_t&, const variant_t&), DISPID id = flag_value)
|
|
||||||
{ method_ptr p; p.has_retval = true; p.pm14 = pm; add_method( name, p, id, 4 << 16 | DISPATCH_PROPERTYGET ); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
STDMETHOD(Invoke)(DISPID id, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pd, VARIANT* pVarResult, EXCEPINFO* pe, UINT* pu)
|
|
||||||
{
|
|
||||||
unsigned type = pd->cArgs << 16 | (wFlags & 15);
|
|
||||||
typename MAP::const_iterator it2 = map_.find(id);
|
|
||||||
if (it2 == map_.end()) return DISP_E_MEMBERNOTFOUND;
|
|
||||||
|
|
||||||
typename std::map<unsigned, method_ptr>::const_iterator it = it2->second.m.find(type);
|
|
||||||
if (it == it2->second.m.end()) return DISP_E_BADPARAMCOUNT;
|
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
if (pd->cNamedArgs > 1) return DISP_E_NONAMEDARGS;
|
|
||||||
|
|
||||||
if (pd->cNamedArgs == 1) {
|
|
||||||
|
|
||||||
if ((wFlags & 15) != DISPATCH_PROPERTYPUT && (wFlags & 15) != DISPATCH_PROPERTYPUTREF) return DISP_E_NONAMEDARGS;
|
|
||||||
if (pd->rgdispidNamedArgs[0] != DISPID_PROPERTYPUT) return DISP_E_NONAMEDARGS;
|
|
||||||
|
|
||||||
switch (pd->cArgs)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
(static_cast<BASE*>(this)->*it->second.pm01)(variant_t::create_reference(pd->rgvarg[0]));
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
(static_cast<BASE*>(this)->*it->second.pm02)(variant_t::create_reference(pd->rgvarg[1]), variant_t::create_reference(pd->rgvarg[0]));
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
(static_cast<BASE*>(this)->*it->second.pm03)(variant_t::create_reference(pd->rgvarg[2]), variant_t::create_reference(pd->rgvarg[1]), variant_t::create_reference(pd->rgvarg[0]));
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
(static_cast<BASE*>(this)->*it->second.pm04)(variant_t::create_reference(pd->rgvarg[3]), variant_t::create_reference(pd->rgvarg[2]), variant_t::create_reference(pd->rgvarg[1]), variant_t::create_reference(pd->rgvarg[0]));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return DISP_E_MEMBERNOTFOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
variant_t rv;
|
|
||||||
if (it->second.has_retval)
|
|
||||||
{
|
|
||||||
switch (pd->cArgs)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
rv = (static_cast<BASE*>(this)->*it->second.pm10)();
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
rv = (static_cast<BASE*>(this)->*it->second.pm11)(variant_t::create_reference(pd->rgvarg[0]));
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
rv = (static_cast<BASE*>(this)->*it->second.pm12)(variant_t::create_reference(pd->rgvarg[1]), variant_t::create_reference(pd->rgvarg[0]));
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
rv = (static_cast<BASE*>(this)->*it->second.pm13)(variant_t::create_reference(pd->rgvarg[2]), variant_t::create_reference(pd->rgvarg[1]), variant_t::create_reference(pd->rgvarg[1]));
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
rv = (static_cast<BASE*>(this)->*it->second.pm14)(variant_t::create_reference(pd->rgvarg[3]), variant_t::create_reference(pd->rgvarg[1]), variant_t::create_reference(pd->rgvarg[2]), variant_t::create_reference(pd->rgvarg[0]));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return DISP_E_MEMBERNOTFOUND;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch (pd->cArgs)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
(static_cast<BASE*>(this)->*it->second.pm00)();
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
(static_cast<BASE*>(this)->*it->second.pm01)(variant_t::create_reference(pd->rgvarg[0]));
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
(static_cast<BASE*>(this)->*it->second.pm02)(variant_t::create_reference(pd->rgvarg[1]), variant_t::create_reference(pd->rgvarg[0]));
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
(static_cast<BASE*>(this)->*it->second.pm03)(variant_t::create_reference(pd->rgvarg[2]), variant_t::create_reference(pd->rgvarg[1]), variant_t::create_reference(pd->rgvarg[0]));
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
(static_cast<BASE*>(this)->*it->second.pm04)(variant_t::create_reference(pd->rgvarg[3]), variant_t::create_reference(pd->rgvarg[2]), variant_t::create_reference(pd->rgvarg[1]), variant_t::create_reference(pd->rgvarg[0]));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return DISP_E_MEMBERNOTFOUND;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (pVarResult) *pVarResult = rv.detach();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} catch (com_error& err) {
|
|
||||||
return impl::return_com_error(err);
|
|
||||||
} catch (const std::exception& err) {
|
|
||||||
return impl::return_com_error(err);
|
|
||||||
} catch (HRESULT hr) {
|
|
||||||
return hr;
|
|
||||||
} catch (...) {
|
|
||||||
return E_FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return S_OK;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHOD(GetIDsOfNames)(REFIID, WCHAR** names, unsigned int c, LCID, DISPID* dispid)
|
|
||||||
{
|
|
||||||
bool failed = false;
|
|
||||||
for (size_t i=0; i<c; ++i)
|
|
||||||
{
|
|
||||||
NAMEMAP::const_iterator it = name_map_.find(names[i]);
|
|
||||||
if (it == name_map_.end())
|
|
||||||
{
|
|
||||||
failed = true;
|
|
||||||
dispid[i] = DISPID_UNKNOWN;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dispid[i] = it->second;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return failed ? DISP_E_UNKNOWNNAME : S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHOD(GetTypeInfo)(UINT, LCID, ITypeInfo**)
|
|
||||||
{ return E_NOTIMPL; }
|
|
||||||
|
|
||||||
STDMETHOD(GetTypeInfoCount)(UINT *it)
|
|
||||||
{ *it = 0; return S_OK; }
|
|
||||||
|
|
||||||
};
|
|
||||||
//@}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,29 +0,0 @@
|
||||||
/** \file
|
|
||||||
* Legacy header for enum-related implementations and iterators.
|
|
||||||
*
|
|
||||||
* This exists for backward compatibility only. Include specific headers
|
|
||||||
* instead.
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* Copyright © 2000 Sofus Mortensen
|
|
||||||
*
|
|
||||||
* This material is provided "as is", with absolutely no warranty
|
|
||||||
* expressed or implied. Any use is at your own risk. Permission to
|
|
||||||
* use or copy this software for any purpose is hereby granted without
|
|
||||||
* fee, provided the above notices are retained on all copies.
|
|
||||||
* Permission to modify the code and to distribute modified code is
|
|
||||||
* granted, provided the above notices are retained, and a notice that
|
|
||||||
* the code was modified is included with the above copyright notice.
|
|
||||||
*
|
|
||||||
* This header is part of Comet version 2.
|
|
||||||
* https://github.com/alamaison/comet
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef COMET_ENUM_H
|
|
||||||
#define COMET_ENUM_H
|
|
||||||
|
|
||||||
#include <comet/enum_common.h>
|
|
||||||
#include <comet/stl_enum.h>
|
|
||||||
#include <comet/variant_iterator.h>
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,187 +0,0 @@
|
||||||
/** \file
|
|
||||||
* Code common to enumerator implementations.
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* Copyright © 2000 Sofus Mortensen
|
|
||||||
*
|
|
||||||
* This material is provided "as is", with absolutely no warranty
|
|
||||||
* expressed or implied. Any use is at your own risk. Permission to
|
|
||||||
* use or copy this software for any purpose is hereby granted without
|
|
||||||
* fee, provided the above notices are retained on all copies.
|
|
||||||
* Permission to modify the code and to distribute modified code is
|
|
||||||
* granted, provided the above notices are retained, and a notice that
|
|
||||||
* the code was modified is included with the above copyright notice.
|
|
||||||
*
|
|
||||||
* This header is part of Comet version 2.
|
|
||||||
* https://github.com/alamaison/comet
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef COMET_ENUM_IMPL_H
|
|
||||||
#define COMET_ENUM_IMPL_H
|
|
||||||
|
|
||||||
#include <comet/config.h>
|
|
||||||
|
|
||||||
#include <comet/server.h>
|
|
||||||
#include <comet/stl.h>
|
|
||||||
#include <comet/variant.h>
|
|
||||||
|
|
||||||
namespace comet {
|
|
||||||
|
|
||||||
namespace impl {
|
|
||||||
|
|
||||||
template<typename T> struct type_policy;
|
|
||||||
|
|
||||||
template<> struct type_policy<VARIANT>
|
|
||||||
{
|
|
||||||
template<typename S>
|
|
||||||
static void init(VARIANT& t, const S& s)
|
|
||||||
{ ::VariantInit(&t); t = variant_t::detach( variant_t(s) ); }
|
|
||||||
|
|
||||||
static void clear(VARIANT& t) { ::VariantClear(&t); }
|
|
||||||
};
|
|
||||||
|
|
||||||
template<> struct type_policy<CONNECTDATA>
|
|
||||||
{
|
|
||||||
template<typename S>
|
|
||||||
static void init(CONNECTDATA& t, const S& s)
|
|
||||||
{
|
|
||||||
t.dwCookie = s.first;
|
|
||||||
t.pUnk =
|
|
||||||
com_ptr<IUnknown>::detach(com_ptr<IUnknown>(s.second));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void clear(CONNECTDATA& t) { t.pUnk->Release(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
template<
|
|
||||||
typename Itf, typename T, typename CONVERTER, typename Source>
|
|
||||||
class enumeration : public simple_object<Itf>
|
|
||||||
{
|
|
||||||
typedef type_policy<T> policy;
|
|
||||||
public:
|
|
||||||
/// \name Interface \p Itf
|
|
||||||
//@{
|
|
||||||
STDMETHOD(Next)(ULONG celt, T *rgelt, ULONG* pceltFetched)
|
|
||||||
{
|
|
||||||
if (pceltFetched)
|
|
||||||
*pceltFetched = 0;
|
|
||||||
if (!rgelt)
|
|
||||||
return E_POINTER;
|
|
||||||
|
|
||||||
UINT i = 0;
|
|
||||||
typename Source::const_iterator backup_it_ = source_.current();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
while (i < celt && source_.current() != source_.end())
|
|
||||||
{
|
|
||||||
policy::init(rgelt[i], converter_(*source_.current()));
|
|
||||||
++i;
|
|
||||||
++source_.current();
|
|
||||||
}
|
|
||||||
if (pceltFetched)
|
|
||||||
*pceltFetched = i;
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
source_.current() = backup_it_;
|
|
||||||
for (size_t j = 0; j <= i; ++j)
|
|
||||||
policy::clear(rgelt[j]);
|
|
||||||
return E_FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return i == celt ? S_OK : S_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHOD(Reset)()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
source_.current() = source_.begin();
|
|
||||||
}
|
|
||||||
catch (...) { return E_FAIL; }
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHOD(Skip)(ULONG celt)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
while (celt--) source_.current()++;
|
|
||||||
}
|
|
||||||
catch (...) { return E_FAIL; }
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHOD(Clone)(Itf** ppenum)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
enumeration* new_enum =
|
|
||||||
new enumeration(source_, converter_);
|
|
||||||
new_enum->AddRef();
|
|
||||||
*ppenum = new_enum;
|
|
||||||
}
|
|
||||||
catch (...) { return E_FAIL; }
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
//@}
|
|
||||||
|
|
||||||
enumeration(
|
|
||||||
typename Source source, const CONVERTER& converter)
|
|
||||||
: source_(source), converter_(converter) {}
|
|
||||||
|
|
||||||
Source source_;
|
|
||||||
CONVERTER converter_;
|
|
||||||
|
|
||||||
private:
|
|
||||||
enumeration(const enumeration&);
|
|
||||||
enumeration& operator=(const enumeration&);
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \struct enumerated_type_of enum.h comet/enum.h
|
|
||||||
* Traits wrapper mapping COM Enumeration interface to element.
|
|
||||||
*/
|
|
||||||
template<typename EnumItf> struct enumerated_type_of;
|
|
||||||
|
|
||||||
template<> struct enumerated_type_of<IEnumVARIANT>
|
|
||||||
{ typedef VARIANT is; };
|
|
||||||
|
|
||||||
template<> struct enumerated_type_of<IEnumConnectionPoints>
|
|
||||||
{ typedef IConnectionPoint* is; };
|
|
||||||
|
|
||||||
template<> struct enumerated_type_of<IEnumConnections>
|
|
||||||
{ typedef CONNECTDATA is; };
|
|
||||||
|
|
||||||
/** \struct ptr_converter enum.h comet/enum.h
|
|
||||||
* IUnknown Converter for containers containing Comet objects.
|
|
||||||
* \relates stl_enumeration
|
|
||||||
*/
|
|
||||||
template<typename T> struct ptr_converter : std::unary_function< com_ptr<IUnknown>, T>
|
|
||||||
{
|
|
||||||
com_ptr<IUnknown> operator()(const T& x) { return impl::cast_to_unknown(x); }
|
|
||||||
};
|
|
||||||
|
|
||||||
/** \struct ptr_converter_select1st enum.h comet/enum.h
|
|
||||||
* IUnknown Converter for containers containing Comet objects as the first
|
|
||||||
* elment of a pair.
|
|
||||||
* \relates stl_enumeration
|
|
||||||
*/
|
|
||||||
template<typename T> struct ptr_converter_select1st : std::unary_function< com_ptr<IUnknown>, T>
|
|
||||||
{
|
|
||||||
com_ptr<IUnknown> operator()(const T& x) { return impl::cast_to_unknown(x.first); }
|
|
||||||
};
|
|
||||||
|
|
||||||
/** \struct ptr_converter_select2nd enum.h comet/enum.h
|
|
||||||
* IUnknown Converter for containers containing Comet objects as the second
|
|
||||||
* elment of a pair.
|
|
||||||
* \relates stl_enumeration
|
|
||||||
*/
|
|
||||||
template<typename T> struct ptr_converter_select2nd : std::unary_function< com_ptr<IUnknown>, T>
|
|
||||||
{
|
|
||||||
com_ptr<IUnknown> operator()(const T& x) { return impl::cast_to_unknown(x.second); }
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,179 +0,0 @@
|
||||||
/** \file
|
|
||||||
* Standard C++ iterators wrapping any COM enumerator
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* Copyright © 2000 Sofus Mortensen
|
|
||||||
* Copyright © 2011 Alexander Lamaison
|
|
||||||
*
|
|
||||||
* This material is provided "as is", with absolutely no warranty
|
|
||||||
* expressed or implied. Any use is at your own risk. Permission to
|
|
||||||
* use or copy this software for any purpose is hereby granted without
|
|
||||||
* fee, provided the above notices are retained on all copies.
|
|
||||||
* Permission to modify the code and to distribute modified code is
|
|
||||||
* granted, provided the above notices are retained, and a notice that
|
|
||||||
* the code was modified is included with the above copyright notice.
|
|
||||||
*
|
|
||||||
* This header is part of Comet version 2.
|
|
||||||
* https://github.com/alamaison/comet
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef COMET_ENUM_ITERATOR_H
|
|
||||||
#define COMET_ENUM_ITERATOR_H
|
|
||||||
|
|
||||||
#include <comet/config.h>
|
|
||||||
|
|
||||||
#include <comet/enum_common.h>
|
|
||||||
#include <comet/ptr.h>
|
|
||||||
|
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
namespace comet {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* STL style iterator for COM enumerator interfaces
|
|
||||||
*/
|
|
||||||
template<typename E, typename T=enumerated_type_of<E>::is>
|
|
||||||
class enum_iterator : public std::iterator<std::input_iterator_tag, T>
|
|
||||||
{
|
|
||||||
typedef E enumerator_type;
|
|
||||||
typedef typename enumerated_type_of<E>::is element_type;
|
|
||||||
typedef impl::type_policy<element_type> policy;
|
|
||||||
|
|
||||||
com_ptr<enumerator_type> enum_;
|
|
||||||
|
|
||||||
static value_type policy_init(const element_type& element)
|
|
||||||
{
|
|
||||||
value_type out;
|
|
||||||
policy::init(out, element);
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
static value_type copy_value_from_other(const enum_iterator& other)
|
|
||||||
{
|
|
||||||
if (other.is_value_set_)
|
|
||||||
{
|
|
||||||
value_type v;
|
|
||||||
policy::init(v, other.value_);
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return value_type();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
value_type value_;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Flag that ensures the value only gets cleared if it's been set.
|
|
||||||
*
|
|
||||||
* Clearing an uninitialised value could be disastrous as it could
|
|
||||||
* contain any random bits which the clearing code could interpret as
|
|
||||||
* pointers.
|
|
||||||
*
|
|
||||||
* This could happen in the situation where the enumerator has no
|
|
||||||
* items so the value never gets set.
|
|
||||||
*/
|
|
||||||
bool is_value_set_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
enum_iterator(const com_ptr<enumerator_type>& e) :
|
|
||||||
enum_(e), is_value_set_(false)
|
|
||||||
{
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
|
|
||||||
enum_iterator() : is_value_set_(false) {}
|
|
||||||
|
|
||||||
enum_iterator(const enum_iterator& other) :
|
|
||||||
enum_(other.enum_), value_(copy_value_from_other(other)),
|
|
||||||
is_value_set_(other.is_value_set_) {}
|
|
||||||
|
|
||||||
enum_iterator& operator=(const enum_iterator& other)
|
|
||||||
{
|
|
||||||
enum_iterator copy(other);
|
|
||||||
swap(copy);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
void swap(enum_iterator& other)
|
|
||||||
{
|
|
||||||
enum_.swap(other.enum_);
|
|
||||||
std::swap(value_, other.value_);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Move to next element. */
|
|
||||||
enum_iterator& operator++()
|
|
||||||
{
|
|
||||||
next();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Move to next element (post increment). */
|
|
||||||
enum_iterator operator++(int)
|
|
||||||
{
|
|
||||||
enum_iterator t(*this);
|
|
||||||
operator++();
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compare against end.
|
|
||||||
* Comparisons against a non-end iterator throw an exception.
|
|
||||||
* \todo Look into doing element comparisons.
|
|
||||||
*/
|
|
||||||
bool operator!=(const enum_iterator& other)
|
|
||||||
{
|
|
||||||
if (enum_ && other.enum_)
|
|
||||||
throw std::logic_error(
|
|
||||||
"enum_iterator comparison does not work");
|
|
||||||
|
|
||||||
return enum_ || other.enum_;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Current element. */
|
|
||||||
value_type& operator*()
|
|
||||||
{
|
|
||||||
return value_;
|
|
||||||
}
|
|
||||||
|
|
||||||
value_type* operator->()
|
|
||||||
{
|
|
||||||
return &value_;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
void next()
|
|
||||||
{
|
|
||||||
if (enum_)
|
|
||||||
{
|
|
||||||
unsigned long fetched = 0;
|
|
||||||
element_type pod;
|
|
||||||
|
|
||||||
enum_->Next(1, &pod, &fetched) | raise_exception;
|
|
||||||
if (fetched == 0)
|
|
||||||
{
|
|
||||||
enum_ = NULL;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (is_value_set_)
|
|
||||||
policy::clear(value_);
|
|
||||||
value_ = policy_init(pod);
|
|
||||||
is_value_set_ = true;
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
policy::clear(pod);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
policy::clear(pod);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,429 +0,0 @@
|
||||||
/** \file
|
|
||||||
* Provide COM Error support.
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* Copyright © 2000, 2001 Sofus Mortensen
|
|
||||||
*
|
|
||||||
* This material is provided "as is", with absolutely no warranty
|
|
||||||
* expressed or implied. Any use is at your own risk. Permission to
|
|
||||||
* use or copy this software for any purpose is hereby granted without
|
|
||||||
* fee, provided the above notices are retained on all copies.
|
|
||||||
* Permission to modify the code and to distribute modified code is
|
|
||||||
* granted, provided the above notices are retained, and a notice that
|
|
||||||
* the code was modified is included with the above copyright notice.
|
|
||||||
*
|
|
||||||
* This header is part of Comet version 2.
|
|
||||||
* https://github.com/alamaison/comet
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef COMET_ERROR_H
|
|
||||||
#define COMET_ERROR_H
|
|
||||||
|
|
||||||
#include <comet/config.h>
|
|
||||||
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include <comet/error_fwd.h>
|
|
||||||
#include <comet/bstr.h>
|
|
||||||
#include <comet/ptr.h>
|
|
||||||
#include <comet/uuid_fwd.h>
|
|
||||||
|
|
||||||
#pragma warning(push)
|
|
||||||
#pragma warning(disable : 4290)
|
|
||||||
|
|
||||||
namespace comet {
|
|
||||||
|
|
||||||
namespace impl {
|
|
||||||
|
|
||||||
inline com_ptr<IErrorInfo> GetErrorInfo() throw()
|
|
||||||
{
|
|
||||||
IErrorInfo* ei = 0;
|
|
||||||
::GetErrorInfo(0, &ei);
|
|
||||||
return com_ptr<IErrorInfo>(auto_attach(ei));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline com_ptr<ICreateErrorInfo> CreateErrorInfo() throw()
|
|
||||||
{
|
|
||||||
ICreateErrorInfo* cei = 0;
|
|
||||||
::CreateErrorInfo(&cei);
|
|
||||||
return com_ptr<ICreateErrorInfo>(auto_attach(cei));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Itf> inline bool supports_ErrorInfo(Itf* p)
|
|
||||||
{
|
|
||||||
com_ptr<ISupportErrorInfo> q = com_cast(com_ptr<Itf>(p));
|
|
||||||
if (q == 0) return false;
|
|
||||||
return S_OK == q->InterfaceSupportsErrorInfo(uuidof<Itf>());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** \class com_error error.h comet/error.h
|
|
||||||
* COM error.
|
|
||||||
*/
|
|
||||||
class com_error : public std::runtime_error
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
//! Construct com_error from HRESULT.
|
|
||||||
/*!
|
|
||||||
\param hr
|
|
||||||
HRESULT value of error.
|
|
||||||
*/
|
|
||||||
explicit com_error(HRESULT hr) : hr_(hr), std::runtime_error("")
|
|
||||||
{}
|
|
||||||
|
|
||||||
//! Construct com_error from HRESULT and textual description.
|
|
||||||
/*!
|
|
||||||
\param msg
|
|
||||||
Description of error.
|
|
||||||
\param hr
|
|
||||||
HRESULT value of error.
|
|
||||||
*/
|
|
||||||
explicit com_error(const bstr_t& msg, HRESULT hr = E_FAIL) : hr_(hr), std::runtime_error("")
|
|
||||||
{
|
|
||||||
com_ptr<ICreateErrorInfo> cei(impl::CreateErrorInfo());
|
|
||||||
if ( !cei.is_null() ) {
|
|
||||||
try {
|
|
||||||
cei->SetDescription(msg.in());
|
|
||||||
ei_ = com_ptr<IErrorInfo>( com_cast(cei)) ;
|
|
||||||
} catch (std::bad_alloc&)
|
|
||||||
{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//! Construct com_error from HRESULT, textual description, source, iid, help.
|
|
||||||
/*!
|
|
||||||
\param msg Description of error.
|
|
||||||
\param hr HRESULT value of error.
|
|
||||||
\param src Description of source line
|
|
||||||
\param iid Interface the error was on
|
|
||||||
\param helpFile Name of help file
|
|
||||||
\param helpContext Name of help Context
|
|
||||||
*/
|
|
||||||
explicit com_error(const bstr_t &msg, HRESULT hr, const bstr_t &src, const uuid_t &iid = uuid_t(),
|
|
||||||
const bstr_t &helpFile=bstr_t(), DWORD helpContext = -1)
|
|
||||||
: hr_(hr), std::runtime_error("")
|
|
||||||
{
|
|
||||||
com_ptr<ICreateErrorInfo> cei(impl::CreateErrorInfo());
|
|
||||||
if ( ! cei.is_null() )
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
cei->SetDescription(msg.in());
|
|
||||||
if (!src.is_null() )
|
|
||||||
cei->SetSource( src.in() );
|
|
||||||
if (iid != uuid_t())
|
|
||||||
cei->SetGUID( iid );
|
|
||||||
if (!helpFile.is_null())
|
|
||||||
{
|
|
||||||
cei->SetHelpFile( helpFile.in() );
|
|
||||||
cei->SetHelpContext( helpContext );
|
|
||||||
}
|
|
||||||
ei_ = com_ptr<IErrorInfo>( com_cast(cei)) ;
|
|
||||||
} catch (std::bad_alloc&)
|
|
||||||
{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Construct with an error-info and hresult.
|
|
||||||
explicit com_error(HRESULT hr, const com_ptr<IErrorInfo>& ei)
|
|
||||||
: hr_(hr), ei_(ei), std::runtime_error("")
|
|
||||||
{}
|
|
||||||
|
|
||||||
public:
|
|
||||||
//! Return a string with a description of the error
|
|
||||||
/*!
|
|
||||||
what() uses Description from IErrorInfo if such is present, otherwise FormatMessage is used
|
|
||||||
to create a description of the HRESULT error value.
|
|
||||||
|
|
||||||
\retval
|
|
||||||
A const char* string with a textual description of the error.
|
|
||||||
*/
|
|
||||||
const char* what() const throw()
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
if (what_.empty()) {
|
|
||||||
what_ = s_str();
|
|
||||||
}
|
|
||||||
} catch (std::bad_alloc&) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return what_.c_str();
|
|
||||||
}
|
|
||||||
/// Returns a std::string with a description of the error.
|
|
||||||
std::string s_str() const
|
|
||||||
{
|
|
||||||
std::string ret;
|
|
||||||
get_str(ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
/// Returns a std::wstring with a description of the error.
|
|
||||||
std::wstring w_str() const
|
|
||||||
{
|
|
||||||
std::wstring ret;
|
|
||||||
get_str(ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
/// Returns a tstring with a description of the error.
|
|
||||||
tstring t_str() const
|
|
||||||
{
|
|
||||||
tstring ret;
|
|
||||||
get_str(ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
void get_str(std::string& ret) const
|
|
||||||
{
|
|
||||||
if (ei_.is_null() == false)
|
|
||||||
{
|
|
||||||
bstr_t bs;
|
|
||||||
if (SUCCEEDED(ei_->GetDescription(bs.out())) && !bs.is_empty())
|
|
||||||
{
|
|
||||||
ret= bs.s_str();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
char* lpMsgBuf;
|
|
||||||
if (FormatMessageA(
|
|
||||||
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
|
|
||||||
FORMAT_MESSAGE_IGNORE_INSERTS, NULL, hr_,
|
|
||||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
|
|
||||||
reinterpret_cast<char*>(&lpMsgBuf), 0, NULL))
|
|
||||||
{
|
|
||||||
char* lpEnd = lpMsgBuf;
|
|
||||||
while (*lpEnd != '\0')
|
|
||||||
lpEnd++;
|
|
||||||
|
|
||||||
while (lpEnd > lpMsgBuf && // Trim trailing newlines
|
|
||||||
(*(lpEnd - 1) == '\n' || *(lpEnd - 1) == '\r'))
|
|
||||||
lpEnd--;
|
|
||||||
|
|
||||||
ret.assign(lpMsgBuf, lpEnd - lpMsgBuf);
|
|
||||||
LocalFree(lpMsgBuf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void get_str(std::wstring& ret) const
|
|
||||||
{
|
|
||||||
if (ei_.is_null() == false)
|
|
||||||
{
|
|
||||||
bstr_t bs;
|
|
||||||
if (SUCCEEDED(ei_->GetDescription(bs.out())) && !bs.is_empty())
|
|
||||||
{
|
|
||||||
ret = bs.w_str();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
wchar_t* lpMsgBuf;
|
|
||||||
if (FormatMessageW(
|
|
||||||
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
|
|
||||||
FORMAT_MESSAGE_IGNORE_INSERTS, NULL, hr_,
|
|
||||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
|
|
||||||
reinterpret_cast<wchar_t*>(&lpMsgBuf), 0, NULL))
|
|
||||||
{
|
|
||||||
wchar_t* lpEnd = lpMsgBuf;
|
|
||||||
while (*lpEnd != L'\0')
|
|
||||||
lpEnd++;
|
|
||||||
|
|
||||||
while (lpEnd > lpMsgBuf && // Trim trailing newlines
|
|
||||||
(*(lpEnd - 1) == L'\n' || *(lpEnd - 1) == L'\r'))
|
|
||||||
lpEnd--;
|
|
||||||
|
|
||||||
ret.assign(lpMsgBuf, lpEnd - lpMsgBuf);
|
|
||||||
LocalFree(lpMsgBuf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/** Return the HRESULT for the error.
|
|
||||||
*/
|
|
||||||
HRESULT hr() const throw()
|
|
||||||
{
|
|
||||||
return hr_;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// \name wrappers for IErrorInfo
|
|
||||||
//@{
|
|
||||||
|
|
||||||
/// Description of the error.
|
|
||||||
bstr_t description() const
|
|
||||||
{
|
|
||||||
bstr_t rv;
|
|
||||||
if (!ei_.is_null()) ei_->GetDescription( rv.out() ) | raise_exception;
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The error source description.
|
|
||||||
bstr_t source() const
|
|
||||||
{
|
|
||||||
bstr_t rv;
|
|
||||||
if (!ei_.is_null()) ei_->GetSource( rv.out() ) | raise_exception;
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Interface IID.
|
|
||||||
GUID guid() const
|
|
||||||
{
|
|
||||||
GUID rv;
|
|
||||||
if (!ei_.is_null()) ei_->GetGUID( &rv ) | raise_exception;
|
|
||||||
else ZeroMemory(&rv, sizeof(rv));
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Helpfile name.
|
|
||||||
bstr_t help_file() const
|
|
||||||
{
|
|
||||||
bstr_t rv;
|
|
||||||
if (!ei_.is_null()) ei_->GetHelpFile( rv.out() ) | raise_exception;
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// Help conext.
|
|
||||||
DWORD help_context() const
|
|
||||||
{
|
|
||||||
DWORD rv = 0;
|
|
||||||
if (!ei_.is_null()) ei_->GetHelpContext( &rv ) | raise_exception;
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
//@}
|
|
||||||
|
|
||||||
/// Return the error-info object.
|
|
||||||
com_ptr<IErrorInfo> get_ei() const
|
|
||||||
{
|
|
||||||
return ei_;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
mutable std::string what_;
|
|
||||||
com_ptr<IErrorInfo> ei_;
|
|
||||||
HRESULT hr_;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
namespace impl {
|
|
||||||
|
|
||||||
inline HRESULT return_com_error(HRESULT hr, const bstr_t &desc, const bstr_t &src = auto_attach(BSTR(NULL)),
|
|
||||||
const uuid_t &iid=CLSID_NULL, const bstr_t &helpFile=bstr_t(), DWORD helpContext = -1)
|
|
||||||
{
|
|
||||||
com_ptr<ICreateErrorInfo> cei(impl::CreateErrorInfo());
|
|
||||||
if (cei.is_null() == false) {
|
|
||||||
try {
|
|
||||||
cei->SetDescription(desc.in());
|
|
||||||
if (!src.is_null() )
|
|
||||||
cei->SetSource( src.in() );
|
|
||||||
if (iid != uuid_t())
|
|
||||||
cei->SetGUID( iid );
|
|
||||||
if (!helpFile.is_null())
|
|
||||||
{
|
|
||||||
cei->SetHelpFile( helpFile.in() );
|
|
||||||
cei->SetHelpContext( helpContext );
|
|
||||||
}
|
|
||||||
com_ptr<IErrorInfo> ei = com_cast(cei);
|
|
||||||
::SetErrorInfo(0, ei.in());
|
|
||||||
} catch (std::bad_alloc&)
|
|
||||||
{}
|
|
||||||
}
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
inline HRESULT return_com_error(const std::exception& err, const bstr_t &src = auto_attach(BSTR(NULL)),
|
|
||||||
const uuid_t &iid=CLSID_NULL, const bstr_t &helpFile=bstr_t(), DWORD helpContext = -1)
|
|
||||||
{
|
|
||||||
return return_com_error( E_FAIL, bstr_t(err.what()),src,iid,helpFile, helpContext );
|
|
||||||
}
|
|
||||||
inline HRESULT return_com_error(const com_error& err, const bstr_t &src = bstr_t(), const uuid_t &iid = CLSID_NULL) throw()
|
|
||||||
{
|
|
||||||
const bstr_t &cursrc =err.source();
|
|
||||||
const uuid_t &curiid =err.guid();
|
|
||||||
// Return error info with more info.
|
|
||||||
return return_com_error( err.hr(), err.description(), cursrc.is_null()?src:cursrc,
|
|
||||||
curiid.is_null()?iid:curiid, err.help_file(), err.help_context());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void throw_com_error_(HRESULT hr, const com_ptr<IErrorInfo>& ei)
|
|
||||||
{
|
|
||||||
throw_error_handler<true>::throw_error(hr, ei);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Raising an HRESULT with a message
|
|
||||||
inline void raise_exception_t::operator()(const bstr_t& msg, HRESULT hr/* = E_FAIL*/) const
|
|
||||||
{
|
|
||||||
throw com_error(msg, hr);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Raising an HRESULT
|
|
||||||
inline void raise_exception_t::operator()(HRESULT hr) const
|
|
||||||
{
|
|
||||||
throw com_error(hr);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace impl
|
|
||||||
|
|
||||||
/*! \addtogroup ErrorHandling
|
|
||||||
*/
|
|
||||||
//@{
|
|
||||||
|
|
||||||
/** Throw COM error using com_error, using HRESULT and IErrorInfo.
|
|
||||||
*/
|
|
||||||
template<typename Itf> inline void throw_com_error(Itf* p, HRESULT hr)
|
|
||||||
{
|
|
||||||
if (impl::supports_ErrorInfo(p))
|
|
||||||
{
|
|
||||||
com_ptr<IErrorInfo> ei = impl::GetErrorInfo();
|
|
||||||
if (ei.is_null() == false) impl::throw_com_error_(hr, ei);
|
|
||||||
}
|
|
||||||
throw com_error(hr);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<bool OVERRIDE>
|
|
||||||
inline void throw_error_handler<OVERRIDE>::throw_error(HRESULT hr, const com_ptr<IErrorInfo> &ei)
|
|
||||||
{
|
|
||||||
throw com_error(hr, ei);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Construct exception for a method called on a raw COM interface.
|
|
||||||
*
|
|
||||||
* This method aims to imbue the com_error with as much information about
|
|
||||||
* the failure as possible:
|
|
||||||
* - If the interface supports IErrorInfo, the information is taken from
|
|
||||||
* the last ErrorInfo set on the current thread.
|
|
||||||
* - If not, the HRESULT alone determines the message.
|
|
||||||
*
|
|
||||||
* Use this constructor immediately after an interface returns a
|
|
||||||
* failure code before any other code can call SetErrorInfo and
|
|
||||||
* overwrite the error.
|
|
||||||
*
|
|
||||||
* \param failure_source Interface operator method returned a failure code.
|
|
||||||
* \param hr HRESULT value of error.
|
|
||||||
*
|
|
||||||
* \todo Can we add an optional user-defined message to this?
|
|
||||||
*/
|
|
||||||
template<typename Itf>
|
|
||||||
com_error com_error_from_interface(Itf* failure_source, HRESULT hr)
|
|
||||||
{
|
|
||||||
if (impl::supports_ErrorInfo(failure_source))
|
|
||||||
return com_error(hr, impl::GetErrorInfo());
|
|
||||||
else
|
|
||||||
return com_error(hr);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Itf>
|
|
||||||
com_error com_error_from_interface(
|
|
||||||
com_ptr<Itf> failure_source, HRESULT hr)
|
|
||||||
{
|
|
||||||
return com_error_from_interface(failure_source.get(), hr);
|
|
||||||
}
|
|
||||||
|
|
||||||
//@}
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma warning(pop)
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,119 +0,0 @@
|
||||||
/** \file
|
|
||||||
* Error forwarding - using operator|.
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* Copyright © 2000, 2001 Sofus Mortensen
|
|
||||||
*
|
|
||||||
* This material is provided "as is", with absolutely no warranty
|
|
||||||
* expressed or implied. Any use is at your own risk. Permission to
|
|
||||||
* use or copy this software for any purpose is hereby granted without
|
|
||||||
* fee, provided the above notices are retained on all copies.
|
|
||||||
* Permission to modify the code and to distribute modified code is
|
|
||||||
* granted, provided the above notices are retained, and a notice that
|
|
||||||
* the code was modified is included with the above copyright notice.
|
|
||||||
*
|
|
||||||
* This header is part of Comet version 2.
|
|
||||||
* https://github.com/alamaison/comet
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef COMET_ERROR_FWD_H
|
|
||||||
#define COMET_ERROR_FWD_H
|
|
||||||
|
|
||||||
#include <comet/config.h>
|
|
||||||
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <wtypes.h>
|
|
||||||
|
|
||||||
#include <OAIdl.h>
|
|
||||||
|
|
||||||
#pragma warning(push)
|
|
||||||
#pragma warning(disable : 4290)
|
|
||||||
|
|
||||||
namespace comet {
|
|
||||||
template<typename Itf> class com_ptr;
|
|
||||||
class bstr_t;
|
|
||||||
|
|
||||||
class com_error;
|
|
||||||
/*! \addtogroup ErrorHandling
|
|
||||||
*/
|
|
||||||
//@{
|
|
||||||
namespace impl {
|
|
||||||
class raise_exception_t
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
// Raising a std::exception
|
|
||||||
// inline void operator()(const std::exception& err) const;
|
|
||||||
|
|
||||||
// Raising an HRESULT with a message
|
|
||||||
inline void operator()(const bstr_t& msg, HRESULT hr = E_FAIL) const;
|
|
||||||
|
|
||||||
// Raising an HRESULT
|
|
||||||
inline void operator()(HRESULT hr) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Raise exception "function"
|
|
||||||
/*!
|
|
||||||
raise_exception can by used in two different ways:
|
|
||||||
|
|
||||||
First example. The 'do or die' paradigm using overloaded operator|.
|
|
||||||
Here try() is a function that returns an HRESULT. If try fails an exception will be raised.
|
|
||||||
\code
|
|
||||||
try() | raise_exception;
|
|
||||||
\endcode
|
|
||||||
|
|
||||||
Second example. Using raise_exception as an exception throwing function.
|
|
||||||
\code
|
|
||||||
raise_exception(E_POINTER);
|
|
||||||
raise_exception(L"Ran out of toilet paper!", E_FAIL);
|
|
||||||
\endcode
|
|
||||||
|
|
||||||
*/
|
|
||||||
static impl::raise_exception_t raise_exception;
|
|
||||||
|
|
||||||
//! Overload for the 'do or die' useage of raise_exception.
|
|
||||||
/*!
|
|
||||||
\code
|
|
||||||
try() | raise_exception;
|
|
||||||
\endcode
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace impl{
|
|
||||||
inline HRESULT operator|(HRESULT hr, const impl::raise_exception_t&)
|
|
||||||
{if (FAILED(hr)) raise_exception(hr); return hr; }
|
|
||||||
}
|
|
||||||
using impl::operator|;
|
|
||||||
|
|
||||||
/**! \struct throw_error_handler error_fwd.h comet\error_fwd.h
|
|
||||||
* Overridable error info handling.
|
|
||||||
* To override the error handling, use code like this, making sure
|
|
||||||
* that you define the handler before including comet/error.h.
|
|
||||||
\code
|
|
||||||
#include <comet/error_fwd.h>
|
|
||||||
template<> struct throw_error_handler<true>
|
|
||||||
{
|
|
||||||
static inline void throw_error(HRESULT hr, const com_ptr<IErrorInfo> &ei);
|
|
||||||
};
|
|
||||||
#include <comet/error.h>
|
|
||||||
// #include <mycustomerror.h>
|
|
||||||
template<>
|
|
||||||
inline void throw_error_handler<true>::throw_error(HRESULT hr, const com_ptr<IErrorInfo> &ei)
|
|
||||||
{
|
|
||||||
.... Override here ....
|
|
||||||
}
|
|
||||||
\endcode
|
|
||||||
*/
|
|
||||||
|
|
||||||
template<bool OVERRIDE>
|
|
||||||
struct throw_error_handler
|
|
||||||
{
|
|
||||||
/// Called to throw the error.
|
|
||||||
static inline void throw_error(HRESULT hr, const com_ptr<IErrorInfo> &ei);
|
|
||||||
};
|
|
||||||
//@}
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma warning(pop)
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,292 +0,0 @@
|
||||||
/** \file
|
|
||||||
* exe-server classes.
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* Copyright © 2001, 2002 Mikael Lindgren, Sofus Mortensen
|
|
||||||
*
|
|
||||||
* This material is provided "as is", with absolutely no warranty
|
|
||||||
* expressed or implied. Any use is at your own risk. Permission to
|
|
||||||
* use or copy this software for any purpose is hereby granted without
|
|
||||||
* fee, provided the above notices are retained on all copies.
|
|
||||||
* Permission to modify the code and to distribute modified code is
|
|
||||||
* granted, provided the above notices are retained, and a notice that
|
|
||||||
* the code was modified is included with the above copyright notice.
|
|
||||||
*
|
|
||||||
* This header is part of Comet version 2.
|
|
||||||
* https://github.com/alamaison/comet
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef COMET_EXE_SERVER_H
|
|
||||||
#define COMET_EXE_SERVER_H
|
|
||||||
|
|
||||||
#include <comet/server.h>
|
|
||||||
#include <comet/static_assert.h>
|
|
||||||
|
|
||||||
namespace comet {
|
|
||||||
|
|
||||||
namespace impl {
|
|
||||||
template <typename CLS_LIST> struct register_class_entry
|
|
||||||
{
|
|
||||||
typedef COMET_STRICT_TYPENAME CLS_LIST::head CLASS;
|
|
||||||
typedef COMET_STRICT_TYPENAME CLS_LIST::tail NEXT;
|
|
||||||
|
|
||||||
template <typename CLS> struct register_info
|
|
||||||
{
|
|
||||||
DWORD id;
|
|
||||||
};
|
|
||||||
|
|
||||||
static register_info<CLASS>& get_register_info()
|
|
||||||
{
|
|
||||||
static register_info<CLASS> info;
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
COMET_FORCEINLINE static HRESULT register_class_object(DWORD context, DWORD flags)
|
|
||||||
{
|
|
||||||
const IID& clsid = comtype<CLASS>::uuid();
|
|
||||||
::IUnknown* p = impl::coclass_table_entry<CLASS, false>::factory::get(clsid);
|
|
||||||
if (p)
|
|
||||||
{
|
|
||||||
HRESULT hr = ::CoRegisterClassObject(clsid, p, context, flags, &get_register_info().id);
|
|
||||||
p->Release();
|
|
||||||
if (hr != S_OK)
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
return register_class_entry<NEXT>::register_class_object(context, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
COMET_FORCEINLINE static void revoke_class_object()
|
|
||||||
{
|
|
||||||
::CoRevokeClassObject(get_register_info().id);
|
|
||||||
register_class_entry<NEXT>::revoke_class_object();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <> struct register_class_entry<nil>
|
|
||||||
{
|
|
||||||
COMET_FORCEINLINE static HRESULT register_class_object(DWORD context, DWORD flags)
|
|
||||||
{
|
|
||||||
COMET_NOTUSED(context);
|
|
||||||
COMET_NOTUSED(flags);
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
COMET_FORCEINLINE static void revoke_class_object()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
/*! \addtogroup Server
|
|
||||||
*/
|
|
||||||
//@{
|
|
||||||
|
|
||||||
//! Define an EXE server
|
|
||||||
template<typename TYPELIB, bool FREE_THREADED = false, typename TRAITS = com_server_traits<0> > class exe_server : private thread
|
|
||||||
{
|
|
||||||
#if !(_WIN32_WINNT >= 0x0400 ) && !defined(_WIN32_DCOM)
|
|
||||||
// Implementing a free threaded exe server requires NT 4.0 or better.
|
|
||||||
COMET_STATIC_ASSERT(FREE_THREADED == false);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef coclass_table<typename TYPELIB::coclasses, false> COCLASS_TABLE;
|
|
||||||
|
|
||||||
enum { terminate_pause = 1000, idle_shutdown_time = 5000 };
|
|
||||||
|
|
||||||
public:
|
|
||||||
exe_server(HINSTANCE instance);
|
|
||||||
exe_server(HINSTANCE instance, const GUID& appid, const tstring& appid_descr);
|
|
||||||
~exe_server();
|
|
||||||
|
|
||||||
HRESULT run();
|
|
||||||
|
|
||||||
HRESULT register_server();
|
|
||||||
HRESULT unregister_server();
|
|
||||||
HRESULT register_class_objects(DWORD context, DWORD flags);
|
|
||||||
void revoke_class_objects();
|
|
||||||
|
|
||||||
private:
|
|
||||||
event shutdown_event_;
|
|
||||||
DWORD main_thread_id_;
|
|
||||||
const GUID* appid_;
|
|
||||||
tstring appid_descr_;
|
|
||||||
|
|
||||||
virtual DWORD thread_main();
|
|
||||||
};
|
|
||||||
//@}
|
|
||||||
|
|
||||||
template<typename TYPELIB, bool FREE_THREADED, typename TRAITS>
|
|
||||||
exe_server<TYPELIB, FREE_THREADED, TRAITS>::exe_server(HINSTANCE instance):
|
|
||||||
main_thread_id_(::GetCurrentThreadId()),
|
|
||||||
appid_(0)
|
|
||||||
{
|
|
||||||
module_t& m = module();
|
|
||||||
|
|
||||||
m.instance(instance);
|
|
||||||
m.set_shutdown_event(shutdown_event_);
|
|
||||||
|
|
||||||
// initialize static variables in factory::get to avoid potential thread safety problem.
|
|
||||||
::IUnknown* cf = COCLASS_TABLE::find(IID_NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename TYPELIB, bool FREE_THREADED, typename TRAITS>
|
|
||||||
exe_server<TYPELIB, FREE_THREADED, TRAITS>::exe_server(HINSTANCE instance, const GUID& appid, const tstring& appid_descr):
|
|
||||||
main_thread_id_(::GetCurrentThreadId()),
|
|
||||||
appid_(&appid), appid_descr_(appid_descr)
|
|
||||||
{
|
|
||||||
module_t& m = module();
|
|
||||||
|
|
||||||
m.instance(instance);
|
|
||||||
m.set_shutdown_event(shutdown_event_);
|
|
||||||
|
|
||||||
// initialize static variables in factory::get to avoid potential thread safety problem.
|
|
||||||
::IUnknown* cf = COCLASS_TABLE::find(IID_NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename TYPELIB, bool FREE_THREADED, typename TRAITS>
|
|
||||||
exe_server<TYPELIB, FREE_THREADED, TRAITS>::~exe_server()
|
|
||||||
{
|
|
||||||
module().clear_shutdown_event();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename TYPELIB, bool FREE_THREADED, typename TRAITS>
|
|
||||||
HRESULT exe_server<TYPELIB, FREE_THREADED, TRAITS>::run()
|
|
||||||
{
|
|
||||||
thread::start();
|
|
||||||
|
|
||||||
HRESULT hr;
|
|
||||||
#if (_WIN32_WINNT >= 0x0400 ) || defined(_WIN32_DCOM) // DCOM
|
|
||||||
if (FREE_THREADED)
|
|
||||||
{
|
|
||||||
hr = register_class_objects(CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE|REGCLS_SUSPENDED);
|
|
||||||
if (SUCCEEDED(hr))
|
|
||||||
hr = ::CoResumeClassObjects();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
hr = register_class_objects(CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE);
|
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
|
||||||
{
|
|
||||||
MSG msg;
|
|
||||||
while (::GetMessage(&msg, 0, 0, 0))
|
|
||||||
::DispatchMessage(&msg);
|
|
||||||
}
|
|
||||||
else if (thread::running())
|
|
||||||
{
|
|
||||||
shutdown_event_.set();
|
|
||||||
thread::wait(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
revoke_class_objects();
|
|
||||||
Sleep(terminate_pause); //wait for any threads to finish
|
|
||||||
|
|
||||||
module().shutdown();
|
|
||||||
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename TYPELIB, bool FREE_THREADED, typename TRAITS>
|
|
||||||
HRESULT exe_server<TYPELIB, FREE_THREADED, TRAITS>::register_server()
|
|
||||||
{
|
|
||||||
TCHAR filename[MAX_PATH];
|
|
||||||
|
|
||||||
GetModuleFileName(module().instance(), filename, MAX_PATH);
|
|
||||||
|
|
||||||
{
|
|
||||||
HRESULT hr = impl::typelibrary_registration<TRAITS::embedded_tlb>::perform(filename, false);
|
|
||||||
if(FAILED(hr)) return SELFREG_E_TYPELIB;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (appid_)
|
|
||||||
{
|
|
||||||
tstring key(_T("AppID\\{") + uuid_t(*appid_).str() + _T("}"));
|
|
||||||
|
|
||||||
regkey rkey(HKEY_CLASSES_ROOT);
|
|
||||||
rkey.create(key)[_T("")] = appid_descr_;
|
|
||||||
}
|
|
||||||
COCLASS_TABLE::registration(filename, false, false, appid_);
|
|
||||||
}
|
|
||||||
catch (const com_error &e)
|
|
||||||
{
|
|
||||||
unregister_server();
|
|
||||||
return impl::return_com_error(e);
|
|
||||||
}
|
|
||||||
catch (const std::exception &e)
|
|
||||||
{
|
|
||||||
unregister_server();
|
|
||||||
::OutputDebugStringA(e.what());
|
|
||||||
return E_FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename TYPELIB, bool FREE_THREADED, typename TRAITS>
|
|
||||||
HRESULT exe_server<TYPELIB, FREE_THREADED, TRAITS>::unregister_server()
|
|
||||||
{
|
|
||||||
TCHAR filename[MAX_PATH];
|
|
||||||
GetModuleFileName(module().instance(), filename, MAX_PATH);
|
|
||||||
|
|
||||||
impl::typelibrary_registration<TRAITS::embedded_tlb>::perform(filename, true);
|
|
||||||
|
|
||||||
if (appid_)
|
|
||||||
{
|
|
||||||
tstring key(_T("AppID\\{") + uuid_t(*appid_).str() + _T("}"));
|
|
||||||
|
|
||||||
regkey rkey(HKEY_CLASSES_ROOT);
|
|
||||||
rkey.delete_subkey_nothrow(key);
|
|
||||||
}
|
|
||||||
COCLASS_TABLE::registration(filename, true, false, appid_);
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename TYPELIB, bool FREE_THREADED, typename TRAITS>
|
|
||||||
HRESULT exe_server<TYPELIB, FREE_THREADED, TRAITS>::register_class_objects(DWORD context, DWORD flags)
|
|
||||||
{
|
|
||||||
return impl::register_class_entry<TYPELIB::coclasses>::register_class_object(context, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename TYPELIB, bool FREE_THREADED, typename TRAITS>
|
|
||||||
void exe_server<TYPELIB, FREE_THREADED, TRAITS>::revoke_class_objects()
|
|
||||||
{
|
|
||||||
impl::register_class_entry<TYPELIB::coclasses>::revoke_class_object();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename TYPELIB, bool FREE_THREADED, typename TRAITS>
|
|
||||||
DWORD exe_server<TYPELIB, FREE_THREADED, TRAITS>::thread_main()
|
|
||||||
{
|
|
||||||
module_t& m = module();
|
|
||||||
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
shutdown_event_.wait();
|
|
||||||
do
|
|
||||||
{
|
|
||||||
m.reset_activity_flag();
|
|
||||||
} while (shutdown_event_.wait(idle_shutdown_time));
|
|
||||||
// timed out
|
|
||||||
|
|
||||||
if (!m.has_activity()) // if no activity let's really bail
|
|
||||||
{
|
|
||||||
#if (_WIN32_WINNT >= 0x0400 ) || defined(_WIN32_DCOM) // DCOM
|
|
||||||
if (FREE_THREADED)
|
|
||||||
{
|
|
||||||
::CoSuspendClassObjects();
|
|
||||||
if (!m.has_activity())
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
#else
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
::PostThreadMessage(main_thread_id_, WM_QUIT, 0, 0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,95 +0,0 @@
|
||||||
/** \file
|
|
||||||
* Global Interface Table wrapper.
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* Copyright © 2000, 2001 Sofus Mortensen
|
|
||||||
*
|
|
||||||
* This material is provided "as is", with absolutely no warranty
|
|
||||||
* expressed or implied. Any use is at your own risk. Permission to
|
|
||||||
* use or copy this software for any purpose is hereby granted without
|
|
||||||
* fee, provided the above notices are retained on all copies.
|
|
||||||
* Permission to modify the code and to distribute modified code is
|
|
||||||
* granted, provided the above notices are retained, and a notice that
|
|
||||||
* the code was modified is included with the above copyright notice.
|
|
||||||
*
|
|
||||||
* This header is part of Comet version 2.
|
|
||||||
* https://github.com/alamaison/comet
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef COMET_GIT_H
|
|
||||||
#define COMET_GIT_H
|
|
||||||
|
|
||||||
#include <comet/config.h>
|
|
||||||
|
|
||||||
#include <comet/ptr.h>
|
|
||||||
|
|
||||||
namespace comet {
|
|
||||||
/*! \addtogroup COMType
|
|
||||||
*/
|
|
||||||
//@{
|
|
||||||
|
|
||||||
class GIT;
|
|
||||||
|
|
||||||
/// Type-safe GIT Cookie.
|
|
||||||
template<typename Itf> class GIT_cookie
|
|
||||||
{
|
|
||||||
friend class GIT;
|
|
||||||
public:
|
|
||||||
GIT_cookie(const GIT_cookie& c) : cookie_(c.cookie_) {}
|
|
||||||
explicit GIT_cookie(DWORD c) : cookie_(c) {}
|
|
||||||
GIT_cookie() : cookie_(0) {}
|
|
||||||
|
|
||||||
DWORD get_cookie() const { return cookie_; }
|
|
||||||
private:
|
|
||||||
DWORD cookie_;
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Global Interface Table wrapper.
|
|
||||||
class GIT {
|
|
||||||
public:
|
|
||||||
GIT() : git_(CLSID_StdGlobalInterfaceTable)
|
|
||||||
{}
|
|
||||||
|
|
||||||
/** Register Interface in the GIT.
|
|
||||||
* \param ptr Interface to register.
|
|
||||||
* \return Type-safe cookie.
|
|
||||||
*/
|
|
||||||
template<typename Itf>
|
|
||||||
GIT_cookie<Itf> register_interface(com_ptr<Itf> const & ptr)
|
|
||||||
{
|
|
||||||
DWORD cookie;
|
|
||||||
git_->RegisterInterfaceInGlobal(ptr.get(), uuidof<Itf>(), &cookie) | raise_exception;
|
|
||||||
return GIT_cookie<Itf>(cookie);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Retrieve Interface in the GIT.
|
|
||||||
* \param c Cookie
|
|
||||||
* \return Marshalled interface.
|
|
||||||
*/
|
|
||||||
template<typename Itf>
|
|
||||||
com_ptr<Itf> get_interface(GIT_cookie<Itf> const& c)
|
|
||||||
{
|
|
||||||
Itf* itf;
|
|
||||||
git_->GetInterfaceFromGlobal(c.get_cookie(), uuidof<Itf>(), reinterpret_cast<void**>(&itf)) | raise_exception;
|
|
||||||
return auto_attach(itf);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Revoke the cookie from the GIT.
|
|
||||||
* \param c Cookie.
|
|
||||||
*/
|
|
||||||
template<typename Itf>
|
|
||||||
void revoke_interface(GIT_cookie<Itf> const& c)
|
|
||||||
{
|
|
||||||
HRESULT hr = git_->RevokeInterfaceFromGlobal(c.get_cookie());
|
|
||||||
hr;
|
|
||||||
assert(SUCCEEDED(hr));
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
com_ptr< ::IGlobalInterfaceTable> git_;
|
|
||||||
};
|
|
||||||
//@}
|
|
||||||
|
|
||||||
} // namespace comet
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,363 +0,0 @@
|
||||||
/** \file
|
|
||||||
* Wrapper for Win32 API HANDLE.
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* Copyright © 2001,2004 Sofus Mortensen, Michael Geddes
|
|
||||||
*
|
|
||||||
* This material is provided "as is", with absolutely no warranty
|
|
||||||
* expressed or implied. Any use is at your own risk. Permission to
|
|
||||||
* use or copy this software for any purpose is hereby granted without
|
|
||||||
* fee, provided the above notices are retained on all copies.
|
|
||||||
* Permission to modify the code and to distribute modified code is
|
|
||||||
* granted, provided the above notices are retained, and a notice that
|
|
||||||
* the code was modified is included with the above copyright notice.
|
|
||||||
*
|
|
||||||
* This header is part of Comet version 2.
|
|
||||||
* https://github.com/alamaison/comet
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef COMET_HANDLE_H
|
|
||||||
#define COMET_HANDLE_H
|
|
||||||
|
|
||||||
#include <comet/config.h>
|
|
||||||
#include <comet/static_assert.h>
|
|
||||||
#include <comet/error_fwd.h>
|
|
||||||
#include <comet/common.h>
|
|
||||||
#include <comet/assert.h>
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
namespace comet {
|
|
||||||
|
|
||||||
/*! \addtogroup COMType
|
|
||||||
*/
|
|
||||||
//@{
|
|
||||||
|
|
||||||
/** Base and policy class for auto_handle_wrap_t type.
|
|
||||||
* This provides the destroy/detach operations for auto_handle_wrap_t as well as
|
|
||||||
* providing a base class to contain the handle and to add functions to
|
|
||||||
* that are specific to the handle type.
|
|
||||||
* \relates auto_handle_wrap_t
|
|
||||||
* \sa auto_handle_wrap_t
|
|
||||||
*/
|
|
||||||
template< typename H, long INVALID_HANDLE_ >
|
|
||||||
class handle_policy_base_t
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/// Default constructor.
|
|
||||||
handle_policy_base_t() : handle_(reinterpret_cast<H>(INVALID_HANDLE_)) {}
|
|
||||||
|
|
||||||
explicit handle_policy_base_t( H handle) : handle_(handle) {}
|
|
||||||
|
|
||||||
typedef H value_type;
|
|
||||||
|
|
||||||
//! Implicit conversion to HANDLE
|
|
||||||
operator H() const throw()
|
|
||||||
{
|
|
||||||
// This function seemed not to work with returning a namespaced
|
|
||||||
// type.
|
|
||||||
return handle_;
|
|
||||||
}
|
|
||||||
static inline H invalid_handle() { return reinterpret_cast<H>(INVALID_HANDLE_) ;}
|
|
||||||
|
|
||||||
/// Is the handle valid?
|
|
||||||
bool valid() const
|
|
||||||
{
|
|
||||||
return handle_ != invalid_handle();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Detach a raw handle
|
|
||||||
H detach_handle()
|
|
||||||
{
|
|
||||||
return swap_handle(invalid_handle());
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Detaches currently held handle without closing it.
|
|
||||||
static inline value_type detach( handle_policy_base_t &handle )throw()
|
|
||||||
{
|
|
||||||
return handle.detach_handle();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
/// Destructor to prevent one of these from being created by itself.
|
|
||||||
~handle_policy_base_t()
|
|
||||||
{ }
|
|
||||||
|
|
||||||
/// Detach the contained handle to the passed in.
|
|
||||||
void detach_to(handle_policy_base_t &rhs) throw()
|
|
||||||
{
|
|
||||||
value_type handle(handle_);
|
|
||||||
handle_= invalid_handle();
|
|
||||||
rhs.handle_ = handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
H get_handle() const { return handle_; }
|
|
||||||
H *get_handle_ptr() { return &handle_;}
|
|
||||||
|
|
||||||
H swap_handle(H new_handle)
|
|
||||||
{
|
|
||||||
H old = handle_;
|
|
||||||
handle_ = new_handle;
|
|
||||||
return old;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
H handle_;
|
|
||||||
};
|
|
||||||
|
|
||||||
/** \class handle_nothrow_error_policy_t handle.h comet/handle.h
|
|
||||||
* Nothrow Error policy.
|
|
||||||
* \relates auto_handle_wrap_t
|
|
||||||
*/
|
|
||||||
struct handle_nothrow_error_policy_t
|
|
||||||
{
|
|
||||||
static void on_error()
|
|
||||||
{ }
|
|
||||||
};
|
|
||||||
|
|
||||||
/** \class handle_throw_error_policy_t handle.h comet/handle.h
|
|
||||||
* Throwing Error policy.
|
|
||||||
* \relates auto_handle_wrap_t
|
|
||||||
*/
|
|
||||||
struct handle_throw_error_policy_t
|
|
||||||
{
|
|
||||||
static void on_error()
|
|
||||||
{
|
|
||||||
DWORD err = GetLastError();
|
|
||||||
raise_exception(HRESULT_FROM_WIN32(err));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/** \class auto_handle_wrap_t handle.h comet/handle.h
|
|
||||||
* Wrapper for a Win32 API/GDI HANDLE.
|
|
||||||
* Behaves similarly to an auto_ptr in that it implements single-reference,
|
|
||||||
* reference counting, with reference-transferring assignment and
|
|
||||||
* copy-construction.
|
|
||||||
*/
|
|
||||||
|
|
||||||
template<typename C_, typename H, long INVALID_HANDLE_, typename ERROR_POLICY>
|
|
||||||
class auto_handle_wrap_t : public handle_policy_base_t<H, INVALID_HANDLE_>
|
|
||||||
{
|
|
||||||
typedef typename handle_policy_base_t<H, INVALID_HANDLE_>::value_type value_type;
|
|
||||||
protected:
|
|
||||||
|
|
||||||
/// Call destroy_handle
|
|
||||||
static inline bool destroy_( value_type h)
|
|
||||||
{
|
|
||||||
return C_::destroy_handle(h);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Destroy the handle passed in.
|
|
||||||
/** Must be implemented by the parent class.
|
|
||||||
*/
|
|
||||||
static bool destroy_handle(value_type h);
|
|
||||||
|
|
||||||
typedef handle_policy_base_t<H, INVALID_HANDLE_> policy_base ;
|
|
||||||
|
|
||||||
void set_handle( value_type h ) throw()
|
|
||||||
{
|
|
||||||
destroy_(this->swap_handle( h));
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool expect_nonzero( BOOL value)
|
|
||||||
{
|
|
||||||
bool is_ok = (value != FALSE);
|
|
||||||
if (!is_ok)
|
|
||||||
ERROR_POLICY::on_error();
|
|
||||||
return is_ok;
|
|
||||||
}
|
|
||||||
public:
|
|
||||||
|
|
||||||
/// default constructor.
|
|
||||||
auto_handle_wrap_t() throw()
|
|
||||||
{}
|
|
||||||
|
|
||||||
/// A reference to a handle.
|
|
||||||
typedef const C_ &ref;
|
|
||||||
|
|
||||||
/** Assign by auto_attach.
|
|
||||||
*/
|
|
||||||
auto_handle_wrap_t( const impl::auto_attach_t<typename policy_base::value_type> &handle ) throw()
|
|
||||||
: policy_base(handle.get())
|
|
||||||
{}
|
|
||||||
|
|
||||||
/** Non-const copy constructor - takes control of the reference.
|
|
||||||
* \param rhs Handle to detach from.
|
|
||||||
*/
|
|
||||||
auto_handle_wrap_t( auto_handle_wrap_t &rhs) throw()
|
|
||||||
{
|
|
||||||
rhs.detach_to(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Non-const copy constructor - takes control of the reference.
|
|
||||||
* \param rhs Handle to detach from.
|
|
||||||
*/
|
|
||||||
auto_handle_wrap_t( policy_base &rhs) throw()
|
|
||||||
{
|
|
||||||
rhs.detach_to(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Destructor - closes the handle.
|
|
||||||
*/
|
|
||||||
~auto_handle_wrap_t() throw()
|
|
||||||
{
|
|
||||||
destroy_(get());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//! Assignment from similar handles.
|
|
||||||
/** Typically, there might be a different error policy.
|
|
||||||
*/
|
|
||||||
template<typename EP>
|
|
||||||
auto_handle_wrap_t<C_, H, INVALID_HANDLE_, EP> & operator=(auto_handle_wrap_t<C_, H, INVALID_HANDLE_, EP>& rhs) throw()
|
|
||||||
{
|
|
||||||
close_handle();
|
|
||||||
rhs.detach_to(*this);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Assign by auto_attach
|
|
||||||
C_ &operator=(const impl::auto_attach_t<value_type> &handle )
|
|
||||||
{
|
|
||||||
close_handle();
|
|
||||||
set_handle(handle.get());
|
|
||||||
return *static_cast<C_ *>(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Closes the currently held handle (if any).
|
|
||||||
bool close() throw()
|
|
||||||
{
|
|
||||||
return destroy_(policy_base::detach(*this));
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \name Accessor methods
|
|
||||||
//@{
|
|
||||||
|
|
||||||
//! Fitter method.
|
|
||||||
/*!
|
|
||||||
Used when calling a function that take a HANDLE* argument.
|
|
||||||
|
|
||||||
\code
|
|
||||||
auto_handle read_pipe, write_pipe;
|
|
||||||
|
|
||||||
CreatePipe(read_pipe.out(), write_pipe.out(), 0, 0));
|
|
||||||
\endcode
|
|
||||||
*/
|
|
||||||
typename policy_base::value_type* out() throw()
|
|
||||||
{
|
|
||||||
close_handle();
|
|
||||||
return this->get_handle_ptr();
|
|
||||||
}
|
|
||||||
|
|
||||||
typename policy_base::value_type get() const throw()
|
|
||||||
{ return this->get_handle(); }
|
|
||||||
typename policy_base::value_type in() const throw()
|
|
||||||
{ return this->get_handle(); }
|
|
||||||
typename policy_base::value_type *inout() throw()
|
|
||||||
{ return this->get_handle_ptr(); }
|
|
||||||
//@}
|
|
||||||
|
|
||||||
static inline const C_ &create_const_reference(const value_type &val)
|
|
||||||
{ return *reinterpret_cast<const C_ *>(&val); }
|
|
||||||
|
|
||||||
static inline C_ &create_reference(value_type &val)
|
|
||||||
{ return *reinterpret_cast<C_ *>(&val); }
|
|
||||||
|
|
||||||
/// Destroy a reference.
|
|
||||||
static bool destroy_reference(value_type h)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
//! Closes the currently held handle (if any).
|
|
||||||
inline void close_handle()
|
|
||||||
{
|
|
||||||
if (!close())
|
|
||||||
ERROR_POLICY::on_error();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace impl
|
|
||||||
{
|
|
||||||
/** \internal
|
|
||||||
*/
|
|
||||||
class THIS_IS_NOT_ALLOWED
|
|
||||||
{
|
|
||||||
~THIS_IS_NOT_ALLOWED() {}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Disallow closing of a const handle.
|
|
||||||
template< typename H, long INVALID_HANDLE_ >
|
|
||||||
inline impl::THIS_IS_NOT_ALLOWED CloseHandle(const handle_policy_base_t<H,INVALID_HANDLE_>&);
|
|
||||||
|
|
||||||
/// Make sure closing of an auto_handle_wrap_t detaches first.
|
|
||||||
/** \return true if CloseHandle was successful.
|
|
||||||
*/
|
|
||||||
template< typename H, long INVALID_HANDLE_ >
|
|
||||||
bool CloseHandle(handle_policy_base_t<H,INVALID_HANDLE_> &rhs)
|
|
||||||
{
|
|
||||||
return rhs.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Wrapper for HANDLE type
|
|
||||||
template< typename ERROR_POLICY = handle_nothrow_error_policy_t >
|
|
||||||
struct auto_handle_t : auto_handle_wrap_t< auto_handle_t<ERROR_POLICY>, HANDLE, 0, ERROR_POLICY >
|
|
||||||
{
|
|
||||||
typedef auto_handle_wrap_t< auto_handle_t, HANDLE, 0, ERROR_POLICY > handle_base;
|
|
||||||
|
|
||||||
/// Default constructor.
|
|
||||||
auto_handle_t() {}
|
|
||||||
/// Copy constructor.
|
|
||||||
auto_handle_t( auto_handle_t &rhs)
|
|
||||||
: auto_handle_wrap_t< auto_handle_t, HANDLE, 0, ERROR_POLICY >(rhs)
|
|
||||||
{}
|
|
||||||
|
|
||||||
/// Auto_attach constructor.
|
|
||||||
auto_handle_t( const impl::auto_attach_t< HANDLE > &rhs )
|
|
||||||
: auto_handle_wrap_t< auto_handle_t, HANDLE, 0, ERROR_POLICY >(rhs)
|
|
||||||
{ }
|
|
||||||
/// Default assignment.
|
|
||||||
auto_handle_t &operator=(auto_handle_t &rhs)
|
|
||||||
{
|
|
||||||
handle_base::operator=(rhs);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
auto_handle_t &operator=( const impl::auto_attach_t<HANDLE> &rhs)
|
|
||||||
{
|
|
||||||
handle_base::operator=(rhs);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Destroy a handle
|
|
||||||
static bool destroy_handle( HANDLE h)
|
|
||||||
{
|
|
||||||
return ::CloseHandle(h) != FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Auto handle - wrapper for HANLDE.
|
|
||||||
typedef auto_handle_t<> auto_handle;
|
|
||||||
/// Auto handle - throwing wrapper for HANDLE.
|
|
||||||
typedef auto_handle_t< handle_throw_error_policy_t > auto_handle_throw;
|
|
||||||
|
|
||||||
/// Create a reference object to a handle that doesn't destroy it's contents.
|
|
||||||
template <typename T>
|
|
||||||
struct auto_reference_t : T
|
|
||||||
{
|
|
||||||
auto_reference_t( const comet::impl::auto_attach_t<typename T::value_type> &rhs ) : T(rhs)
|
|
||||||
{}
|
|
||||||
~auto_reference_t()
|
|
||||||
{
|
|
||||||
destroy_reference(this->detach_handle());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
//@}
|
|
||||||
}
|
|
||||||
|
|
||||||
using comet::CloseHandle;
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,363 +0,0 @@
|
||||||
/** \file
|
|
||||||
* Handle Comet exceptions.
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* Copyright 2003 Atex Media Command. All rights reserved.
|
|
||||||
* Copyright (C) 2013 Alexander Lamaison <alexander.lamaison@gmail.com>
|
|
||||||
*
|
|
||||||
* This material is provided "as is", with absolutely no warranty
|
|
||||||
* expressed or implied. Any use is at your own risk. Permission to
|
|
||||||
* use or copy this software for any purpose is hereby granted without
|
|
||||||
* fee, provided the above notices are retained on all copies.
|
|
||||||
* Permission to modify the code and to distribute modified code is
|
|
||||||
* granted, provided the above notices are retained, and a notice that
|
|
||||||
* the code was modified is included with the above copyright notice.
|
|
||||||
*
|
|
||||||
* This header is part of Comet version 2.
|
|
||||||
* https://github.com/alamaison/comet
|
|
||||||
*/
|
|
||||||
#ifndef COMET_HANDLE_EXCEPT_H
|
|
||||||
#define COMET_HANDLE_EXCEPT_H
|
|
||||||
|
|
||||||
#ifdef _SHOW_INC
|
|
||||||
#pragma message(" #Include " __FILE__)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <comet/error.h>
|
|
||||||
|
|
||||||
/** \page comethandleexception Custom Exception Handling
|
|
||||||
This allows the user to define how exception handling happens for a particular library.
|
|
||||||
|
|
||||||
Unfortunately due to a compiler bug in MSVC 6 (fixed in 7), some of the
|
|
||||||
functionality won't be available for that compiler (this has also limited
|
|
||||||
the customisability originally designed for).
|
|
||||||
|
|
||||||
To override the default behavior, specialise the struct
|
|
||||||
comet::comet_exception_handler<true> and implement the functions defined
|
|
||||||
in the default implementation comet::comet_exception_handler.
|
|
||||||
\code
|
|
||||||
comet {
|
|
||||||
template<>
|
|
||||||
struct comet_exception_handler<true> : comet_exception_handler<false>
|
|
||||||
{
|
|
||||||
static inline HRESULT catcher_all( const source_info_t &info)
|
|
||||||
{
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
\endcode
|
|
||||||
|
|
||||||
With a suitable compiler, the method comet::comet_exception_handler::rethrow can be
|
|
||||||
overridden to provide support for custom exceptions.
|
|
||||||
|
|
||||||
Don't try putting a try catch round a throw in \p catcher_all as the resulting destruct-twice
|
|
||||||
of the exception when using MSV6 will cause very hard to trace bugs.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef COMET_DISABLE_EXCEPTION_RETHROW_CATCH
|
|
||||||
#define COMET_CATCH_CLASS_EX(funcName,iid) \
|
|
||||||
catch ( const com_error &err) { \
|
|
||||||
return comet_exception_handler<true>::catcher_com_error(err, impl::do_get_source_info_t<_B>::exec( static_cast<_B*>(this), source_info_t(funcName, iid))); \
|
|
||||||
} catch ( const std::exception &err) { \
|
|
||||||
return comet_exception_handler<true>::catcher_exception(err, impl::do_get_source_info_t<_B>::exec( static_cast<_B*>(this), source_info_t(funcName, iid))); \
|
|
||||||
} catch ( HRESULT hr ) { \
|
|
||||||
return comet_exception_handler<true>::catcher_hr(hr, impl::do_get_source_info_t<_B>::exec( static_cast<_B*>(this), source_info_t(funcName, iid))); \
|
|
||||||
} catch (...) { \
|
|
||||||
return comet_exception_handler<true>::catcher_all( impl::do_get_source_info_t<_B>::exec( static_cast<_B*>(this), source_info_t(funcName, iid))); \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define COMET_CATCH_UNKNOWN(funcName, iid, clsname) \
|
|
||||||
catch ( const com_error &err) { \
|
|
||||||
comet_exception_handler<true>::catcher_com_error(err, source_info_t(funcName, iid, clsname)); \
|
|
||||||
} catch ( const std::exception &err) { \
|
|
||||||
comet_exception_handler<true>::catcher_exception(err, source_info_t(funcName, iid, clsname)); \
|
|
||||||
} catch ( HRESULT hr ) { \
|
|
||||||
comet_exception_handler<true>::catcher_hr(hr, source_info_t(funcName, iid, clsname)); \
|
|
||||||
} catch (...) { \
|
|
||||||
comet_exception_handler<true>::catcher_all( source_info_t(funcName, iid, clsname)); \
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#else // COMET_DISABLE_EXCEPTION_RETHROW_CATCH
|
|
||||||
|
|
||||||
#define COMET_CATCH_CLASS_EX( funcName, iid) \
|
|
||||||
catch ( ... ) { \
|
|
||||||
return comet_exception_handler<true>::rethrow( impl::do_get_source_info_t<_B>::exec( static_cast<_B*>(this), source_info_t(funcName, iid))); \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define COMET_CATCH_UNKNOWN(funcName, iid, clsname) \
|
|
||||||
catch ( ... ) { \
|
|
||||||
comet_exception_handler<true>::rethrow( source_info_t(funcName, iid, clsname)); \
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** Macro used in implementation wrappers to hide a bug with catching rethrown
|
|
||||||
* classes.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define COMET_CATCH_CLASS(funcName) COMET_CATCH_CLASS_EX(funcName, comtype<interface_is>::uuid())
|
|
||||||
|
|
||||||
// We define these new catch macros because the ones above don't seem to work.
|
|
||||||
// They use a mystery _B to get the class name. It may have been part of the
|
|
||||||
// old code-generation mechanism which we don't support any more.
|
|
||||||
#define COMET_CATCH_INTERFACE_BOUNDARY(funcName) \
|
|
||||||
catch ( ... ) { \
|
|
||||||
return ::comet::comet_exception_handler<true>::rethrow( \
|
|
||||||
::comet::source_info_t( \
|
|
||||||
funcName, ::comet::comtype<interface_is>::uuid())); \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define COMET_CATCH_CLASS_INTERFACE_BOUNDARY(funcName, clsName) \
|
|
||||||
catch ( ... ) { \
|
|
||||||
return ::comet::comet_exception_handler<true>::rethrow( \
|
|
||||||
::comet::source_info_t( \
|
|
||||||
funcName, ::comet::comtype<interface_is>::uuid(), clsName)); \
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace comet {
|
|
||||||
|
|
||||||
/*! \addtogroup ErrorHandling
|
|
||||||
*/
|
|
||||||
//@{
|
|
||||||
/// Specifies the source of an exception.
|
|
||||||
struct source_info_t
|
|
||||||
{
|
|
||||||
/// Default Constructor
|
|
||||||
source_info_t() {}
|
|
||||||
/// Constructor to fill in a few elements.
|
|
||||||
source_info_t(const bstr_t &par_function, const uuid_t &par_interface_uuid = uuid_t(), const bstr_t &par_coclass_name = bstr_t() )
|
|
||||||
: function_name(par_function), interface_uuid(par_interface_uuid), coclass_name(par_coclass_name) {}
|
|
||||||
|
|
||||||
bstr_t function_name; ///< Name of the function being called.
|
|
||||||
bstr_t coclass_name; ///< Coclass the method belongs to.
|
|
||||||
uuid_t coclass_uuid; ///< CLSID of the coclass.
|
|
||||||
uuid_t interface_uuid; ///< IID of the interface
|
|
||||||
|
|
||||||
bstr_t source_override; ///< Used to override the source description.
|
|
||||||
|
|
||||||
/** Returns the 'source' description, either 'source_overrride' or the
|
|
||||||
* concatenation of the coclass and function_name.
|
|
||||||
*/
|
|
||||||
bstr_t source() const
|
|
||||||
{
|
|
||||||
if ( !source_override.is_empty())
|
|
||||||
{
|
|
||||||
return source_override;
|
|
||||||
}
|
|
||||||
if (coclass_name.is_empty())
|
|
||||||
{
|
|
||||||
return function_name;
|
|
||||||
}
|
|
||||||
if (function_name.is_empty())
|
|
||||||
{
|
|
||||||
return coclass_name;
|
|
||||||
}
|
|
||||||
return coclass_name + L"." + function_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace impl
|
|
||||||
{
|
|
||||||
/** Redirect logging to calllog if enabled.
|
|
||||||
* Used so that if call-logging is loaded, the default action is to
|
|
||||||
* redirect the logging to the call-logger.
|
|
||||||
* \internal
|
|
||||||
*/
|
|
||||||
template<bool>
|
|
||||||
struct call_logger_redirect_
|
|
||||||
{
|
|
||||||
template<bool>
|
|
||||||
struct exe
|
|
||||||
{
|
|
||||||
static inline void log_exception(
|
|
||||||
const tstring& /*type*/, const tstring& /*desc*/,
|
|
||||||
const source_info_t& /*errorSource*/,
|
|
||||||
const source_info_t& /*callSource*/)
|
|
||||||
{ }
|
|
||||||
static inline bool can_log_exception()
|
|
||||||
{ return false; }
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \struct error_logger_ handle_except.h comet/handle_except.h
|
|
||||||
* Default to NULL logger - and description of 'error logger' concept.
|
|
||||||
* Specialise to \b true to override.
|
|
||||||
*/
|
|
||||||
template<bool OVERRIDE>
|
|
||||||
struct error_logger_
|
|
||||||
{
|
|
||||||
/** Should the error be logged?
|
|
||||||
* \return Return true to allow error to be logged.
|
|
||||||
*/
|
|
||||||
static inline bool can_log_exception()
|
|
||||||
{
|
|
||||||
return impl::call_logger_redirect_<OVERRIDE>::template exe<OVERRIDE>::can_log_exception();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Called by exception handlers to provide logging for errors.
|
|
||||||
static inline void log_exception(const tstring &type, const tstring &desc, const source_info_t &errorSource ,const source_info_t &callSource )
|
|
||||||
{
|
|
||||||
impl::call_logger_redirect_<OVERRIDE>::template exe<OVERRIDE>::log_exception(type,desc,errorSource, callSource);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Common exception handler for comet.
|
|
||||||
* Specialize to \c true to overide the behaviour. It is usually convenient
|
|
||||||
* to inherit the comet_exception_handler<true> from
|
|
||||||
* comet_exception_handler<false>.
|
|
||||||
*/
|
|
||||||
template< bool OVERRIDE>
|
|
||||||
struct comet_exception_handler
|
|
||||||
{
|
|
||||||
#ifndef COMET_DISABLE_EXCEPTION_RETHROW_CATCH
|
|
||||||
/** Override to modify which exceptions are caught.
|
|
||||||
* Note that due to a severe bug in MSVC 6, this will not be called in that
|
|
||||||
* case.
|
|
||||||
*/
|
|
||||||
static inline HRESULT rethrow(const source_info_t &info)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
throw;
|
|
||||||
} catch ( const com_error &err)
|
|
||||||
{
|
|
||||||
return catcher_com_error( err, info);
|
|
||||||
}
|
|
||||||
catch ( const std::exception &err)
|
|
||||||
{
|
|
||||||
return catcher_exception( err, info);
|
|
||||||
}
|
|
||||||
catch ( HRESULT hr )
|
|
||||||
{
|
|
||||||
return catcher_hr( hr, info );
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
return catcher_all(info);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif // COMET_DISABLE_EXCEPTION_RETHROW_CATCH
|
|
||||||
|
|
||||||
/// Override to modify handling of com_error
|
|
||||||
static inline HRESULT catcher_com_error( const com_error &err,const source_info_t &info)
|
|
||||||
{
|
|
||||||
if ( error_logger_<OVERRIDE>::can_log_exception() )
|
|
||||||
{
|
|
||||||
source_info_t errorInfo;
|
|
||||||
errorInfo.interface_uuid = err.guid();
|
|
||||||
errorInfo.source_override = err.source();
|
|
||||||
error_logger_<OVERRIDE>::log_exception( _T("comet::com_error"), err.t_str(), errorInfo, info);
|
|
||||||
}
|
|
||||||
return impl::return_com_error(err, info.source(), info.interface_uuid);
|
|
||||||
}
|
|
||||||
/// Override to modify handling of std::exception
|
|
||||||
static inline HRESULT catcher_exception(const std::exception& err,const source_info_t &info)
|
|
||||||
{
|
|
||||||
if ( error_logger_<OVERRIDE>::can_log_exception() )
|
|
||||||
{
|
|
||||||
error_logger_<OVERRIDE>::log_exception( _T("std::exception"),
|
|
||||||
bstr_t(err.what()).t_str(),
|
|
||||||
source_info_t(), info);
|
|
||||||
}
|
|
||||||
return impl::return_com_error(err, info.source(), info.interface_uuid);
|
|
||||||
}
|
|
||||||
/// Override to modify handling of HRESULT
|
|
||||||
static inline HRESULT catcher_hr( HRESULT hr,const source_info_t &info)
|
|
||||||
{
|
|
||||||
return impl::return_com_error(hr, bstr_t(), info.source(), info.interface_uuid);
|
|
||||||
}
|
|
||||||
/// This can be overridden to provide handling of other exceptions.
|
|
||||||
static inline HRESULT catcher_all( const source_info_t &info)
|
|
||||||
{
|
|
||||||
COMET_NOTUSED(info);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
namespace impl
|
|
||||||
{
|
|
||||||
/** Marker for using the coclass information.
|
|
||||||
* \relates handle_exception_default
|
|
||||||
*/
|
|
||||||
struct handle_exception_default_marker {};
|
|
||||||
|
|
||||||
/** Call the coclasses exception handler if it is marked.
|
|
||||||
* \relates handle_exception_default
|
|
||||||
*/
|
|
||||||
template <typename O>
|
|
||||||
struct do_get_source_info_t
|
|
||||||
{
|
|
||||||
/** Call the classes exception handler.
|
|
||||||
* \relates handle_exception_default
|
|
||||||
*/
|
|
||||||
template <bool USETHIS>
|
|
||||||
struct execute_handle
|
|
||||||
{
|
|
||||||
inline static void get_source_info(O * pThis, source_info_t &info)
|
|
||||||
{
|
|
||||||
pThis->get_source_info_( info );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
/** Call the default global exception handler.
|
|
||||||
* \relates handle_exception_default
|
|
||||||
*/
|
|
||||||
template <>
|
|
||||||
struct execute_handle<false>
|
|
||||||
{
|
|
||||||
inline static void get_source_info(O *pThis, const source_info_t &info )
|
|
||||||
{
|
|
||||||
COMET_NOTUSED(pThis);
|
|
||||||
COMET_NOTUSED(info);
|
|
||||||
// return impl::do_handle_exception<nil, IFACE>(src);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Called by the interface wrappers to call the exception handlers.
|
|
||||||
* \relates handle_exception_default
|
|
||||||
*/
|
|
||||||
inline static source_info_t exec( O *pThis, source_info_t info)
|
|
||||||
{
|
|
||||||
// Either call the coclass exception handler, or the project default.
|
|
||||||
execute_handle<type_traits::conversion<O&, handle_exception_default_marker>::exists>::get_source_info( pThis, info);
|
|
||||||
/* ERRORS: If the conversion is ambiguous here, then there are probably two ways of
|
|
||||||
* getting to handle_exception_default_marker, usually via handle_exception_default<COCLASS>,
|
|
||||||
* which is already provided by by IProvideClassInfoImpl<COCLASS>.
|
|
||||||
*/
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \struct handle_exception_default server.h comet/server.h
|
|
||||||
* Used by the exception handler to provide source information for the specified CoClass.
|
|
||||||
* Inherit from this class or IProvideClassInfoImpl to make sure that the
|
|
||||||
* coclass name is known about for custom coclasses.
|
|
||||||
*/
|
|
||||||
template<typename COCLASS>
|
|
||||||
struct handle_exception_default
|
|
||||||
: impl::handle_exception_default_marker // Required to mark the class as being able to handle exceptions with coclass information
|
|
||||||
{
|
|
||||||
void get_source_info_( source_info_t &info)
|
|
||||||
{
|
|
||||||
info.coclass_name = COCLASS::name();
|
|
||||||
info.coclass_uuid = comtype<COCLASS>::uuid();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// Handles the case where there is no coclass, and therefore no coclass name.
|
|
||||||
template<>
|
|
||||||
struct handle_exception_default<nil> : impl::handle_exception_default_marker
|
|
||||||
{
|
|
||||||
void get_source_info_( source_info_t &info)
|
|
||||||
{
|
|
||||||
COMET_NOTUSED(info);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
//@}
|
|
||||||
}
|
|
||||||
#endif /* COMET_HANDLE_EXCEPT_H */
|
|
|
@ -1,546 +0,0 @@
|
||||||
/** \file
|
|
||||||
* Implementation of QueryInterface.
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* Copyright © 2000-2002 Sofus Mortensen, Michael Geddes
|
|
||||||
*
|
|
||||||
* This material is provided "as is", with absolutely no warranty
|
|
||||||
* expressed or implied. Any use is at your own risk. Permission to
|
|
||||||
* use or copy this software for any purpose is hereby granted without
|
|
||||||
* fee, provided the above notices are retained on all copies.
|
|
||||||
* Permission to modify the code and to distribute modified code is
|
|
||||||
* granted, provided the above notices are retained, and a notice that
|
|
||||||
* the code was modified is included with the above copyright notice.
|
|
||||||
*
|
|
||||||
* This header is part of Comet version 2.
|
|
||||||
* https://github.com/alamaison/comet
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef COMET_IMPQI_H
|
|
||||||
#define COMET_IMPQI_H
|
|
||||||
|
|
||||||
#include <wtypes.h>
|
|
||||||
|
|
||||||
#include <comet/config.h>
|
|
||||||
|
|
||||||
#include <comet/ptr.h>
|
|
||||||
#include <comet/typelist.h>
|
|
||||||
#include <comet/common.h>
|
|
||||||
#include <comet/type_traits.h>
|
|
||||||
#include <comet/uuid_fwd.h>
|
|
||||||
#include <comet/threading.h>
|
|
||||||
#include <comet/module.h>
|
|
||||||
|
|
||||||
namespace comet {
|
|
||||||
/*! \addtogroup Interfaces
|
|
||||||
*/
|
|
||||||
//@{
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace impl {
|
|
||||||
|
|
||||||
/** Base class for recognising qi hook.
|
|
||||||
* \internal
|
|
||||||
*/
|
|
||||||
class qi_hook_itf_tag {};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
class qi_hook {};
|
|
||||||
|
|
||||||
template<typename Itf> class qi_hook_itf : public impl::qi_hook_itf_tag{
|
|
||||||
public:
|
|
||||||
typedef Itf exposes;
|
|
||||||
virtual com_ptr<Itf> get_interface_ptr(const com_ptr< ::IUnknown>&) throw() = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace impl {
|
|
||||||
|
|
||||||
template<typename Itf> COMET_FORCEINLINE bool is_interface_compatible(const uuid_t& iid, Itf*)
|
|
||||||
{
|
|
||||||
if (iid == uuidof<Itf>()) return true;
|
|
||||||
else return is_interface_compatible<comtype<Itf>::base>(iid, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<> COMET_FORCEINLINE bool is_interface_compatible< ::IUnknown >(const uuid_t&, ::IUnknown*)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<> COMET_FORCEINLINE bool is_interface_compatible<nil>(const uuid_t&, nil*)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
enum use_cast_t {uc_false=0, uc_static, uc_static_op, uc_qi_hook_itf, uc_qi_hook };
|
|
||||||
|
|
||||||
|
|
||||||
// remove enum for VC2005B2
|
|
||||||
template</*enum*/ use_cast_t>
|
|
||||||
struct find_compatibility_aux
|
|
||||||
{
|
|
||||||
template<typename T>
|
|
||||||
struct with
|
|
||||||
{
|
|
||||||
enum { is = false };
|
|
||||||
|
|
||||||
template<typename P> inline static bool qi(P *, const uuid_t& , com_ptr< ::IUnknown>& )
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct find_compatibility_aux<uc_static>
|
|
||||||
{
|
|
||||||
template<typename Itf> struct with {
|
|
||||||
template<typename T> static bool qi(T *This, const uuid_t& iid, com_ptr< ::IUnknown>& unk)
|
|
||||||
{
|
|
||||||
if (is_interface_compatible<Itf>(iid, 0))
|
|
||||||
{
|
|
||||||
unk = static_cast< ::IUnknown* >(static_cast<Itf*>(This));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct find_compatibility_aux<uc_qi_hook_itf>
|
|
||||||
{
|
|
||||||
template<typename Itf> struct with {
|
|
||||||
template<typename T> static bool qi(T *This, const uuid_t& iid, com_ptr< ::IUnknown>& unk)
|
|
||||||
{
|
|
||||||
if (is_interface_compatible<typename Itf::exposes>(iid,0)) {
|
|
||||||
unk = static_cast<qi_hook_itf<typename Itf::exposes>*>(This)->get_interface_ptr( cast_to_unknown(This) );
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct find_compatibility_aux<uc_qi_hook>
|
|
||||||
{
|
|
||||||
template<typename Itf> struct with {
|
|
||||||
template<typename T> static bool qi(T *This, const uuid_t& iid, com_ptr< ::IUnknown>& unk)
|
|
||||||
{
|
|
||||||
if ( static_cast<Itf*>(This)->qi(This, iid, unk) )
|
|
||||||
return true;
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
/* template<>
|
|
||||||
struct find_compatibility_aux<uc_qi_hook_itf>
|
|
||||||
{
|
|
||||||
template<typename U>
|
|
||||||
struct with
|
|
||||||
{
|
|
||||||
static bool is( const uuid_t &iid){ return is_interface_compatible<U::exposes>(iid,0);}
|
|
||||||
template<class T>
|
|
||||||
static com_ptr< ::IUnknown> cast_from(T *This)
|
|
||||||
{
|
|
||||||
#ifndef NDEBUG
|
|
||||||
try {
|
|
||||||
#endif
|
|
||||||
return static_cast<qi_hook_itf<Itf::exposes>*>(This)->get_interface_ptr( cast_to_unknown(This) );
|
|
||||||
#ifndef NDEBUG
|
|
||||||
} catch (...) {
|
|
||||||
// get_interface_ptr is not allowed to throw. Return null pointer on failure
|
|
||||||
COMET_ASSERT(0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct find_compatibility_aux<uc_qi_hook>
|
|
||||||
{
|
|
||||||
template<typename U>
|
|
||||||
struct with
|
|
||||||
{
|
|
||||||
static bool is( const uuid_t &iid){ return true; }
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
static com_ptr< ::IUnknown> cast_from(T *This)
|
|
||||||
{
|
|
||||||
Itf::
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};*/
|
|
||||||
|
|
||||||
template< typename Itf>
|
|
||||||
struct use_cast_aux
|
|
||||||
{
|
|
||||||
enum { is_static = (type_traits::conversion<Itf*, ::IUnknown*>::exists) };
|
|
||||||
enum { is_static_op =(type_traits::is_cast_operator_compatible<Itf, ::IUnknown>::is)};
|
|
||||||
enum { is_qi_hook_itf = (type_traits::conversion<Itf*, qi_hook_itf_tag*>::exists) };
|
|
||||||
enum { is_qi_hook = (type_traits::conversion<Itf*, qi_hook*>::exists) };
|
|
||||||
// GCC Doesn't handle evaluation of ?: opeators in templates yet.
|
|
||||||
// enum { is = (int)( is_static ? uc_static: ( is_static_op ? uc_static_op : uc_false))
|
|
||||||
enum { is = is_static * uc_static +
|
|
||||||
is_qi_hook_itf * uc_qi_hook_itf +
|
|
||||||
is_qi_hook * uc_qi_hook +
|
|
||||||
is_static_op * uc_static_op };
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Itf>
|
|
||||||
struct find_compatibility
|
|
||||||
{
|
|
||||||
enum { needs_cast_ = use_cast_aux<Itf>::is };
|
|
||||||
typedef find_compatibility_aux< (use_cast_t)needs_cast_ > compatible;
|
|
||||||
|
|
||||||
COMET_FORCEINLINE static bool with(const uuid_t &iid)
|
|
||||||
{ return compatible::template with<Itf>::is(iid); };
|
|
||||||
template<typename T>
|
|
||||||
COMET_FORCEINLINE static com_ptr< ::IUnknown> cast_from( T *This)
|
|
||||||
{ return compatible::template with<Itf>::cast_from(This); }
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename ITF_LIST> struct interface_finder
|
|
||||||
{
|
|
||||||
template<typename T> COMET_FORCEINLINE static bool find_interface(T* This, const uuid_t& iid, com_ptr< ::IUnknown>& rv)
|
|
||||||
{
|
|
||||||
typedef typename find_compatibility_aux< (use_cast_t)use_cast_aux< COMET_STRICT_TYPENAME ITF_LIST::head >::is >::template with<COMET_STRICT_TYPENAME ITF_LIST::head> fc;
|
|
||||||
if ( fc::qi(This, iid, rv) )
|
|
||||||
return true;
|
|
||||||
else
|
|
||||||
return interface_finder< COMET_STRICT_TYPENAME ITF_LIST::tail>::find_interface(This, iid, rv);
|
|
||||||
}
|
|
||||||
|
|
||||||
COMET_FORCEINLINE static bool find_interface_2(const uuid_t& iid)
|
|
||||||
{
|
|
||||||
if (is_interface_compatible<COMET_STRICT_TYPENAME ITF_LIST::head>(iid, 0)) return true;
|
|
||||||
return interface_finder< COMET_STRICT_TYPENAME ITF_LIST::tail>::find_interface_2(iid);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<> struct interface_finder<nil>
|
|
||||||
{
|
|
||||||
template<typename T> COMET_FORCEINLINE static bool find_interface(T*, const uuid_t&, com_ptr< ::IUnknown>&)
|
|
||||||
{ return false; }
|
|
||||||
|
|
||||||
COMET_FORCEINLINE static bool find_interface_2(const uuid_t&)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/* template<> struct interface_finder<make_list<> >
|
|
||||||
{
|
|
||||||
template<typename T> COMET_FORCEINLINE static ::IUnknown* find_interface(T*, const uuid_t&)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
};*/
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \struct typelibrary_loader impqi.h comet/impqi.h
|
|
||||||
* Type Library Loader.
|
|
||||||
* Allow provision for different means of loading a type-library.
|
|
||||||
* \param TL A \e Comet type-library.
|
|
||||||
*/
|
|
||||||
template<typename TL>
|
|
||||||
struct typelibrary_loader
|
|
||||||
{
|
|
||||||
//! Load the type-library.
|
|
||||||
/** Create a different template instantiation of this to load
|
|
||||||
* type-libraries from a different source (example - from a second
|
|
||||||
* resource in the dll).
|
|
||||||
*/
|
|
||||||
static inline HRESULT load( ITypeLib **pTypeLib)
|
|
||||||
{ return LoadRegTypeLib(uuidof<TL>(), TL::major_version, TL::minor_version, LANG_NEUTRAL, pTypeLib); }
|
|
||||||
};
|
|
||||||
|
|
||||||
/** \struct implement_qi impqi.h comet/impqi.h
|
|
||||||
* Implementation of QueryInterface. Inherits from all the types defined
|
|
||||||
* in \p ITF_LIST.
|
|
||||||
* \param ITF_LIST interface implementation list.
|
|
||||||
*/
|
|
||||||
template<typename ITF_LIST> class ATL_NO_VTABLE implement_qi : public typelist::inherit_all<ITF_LIST>
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
// Hide qi
|
|
||||||
void qi();
|
|
||||||
public:
|
|
||||||
/** Get at the unknown for this class. Is here for compatibility when using
|
|
||||||
* implement_internal_qi via aggregateable_coclass for getting at a
|
|
||||||
* pointer from which to QueryInterface from.
|
|
||||||
*/
|
|
||||||
::IUnknown* get_unknown()const
|
|
||||||
{ return static_cast< typename ITF_LIST::head * >(const_cast<implement_qi<ITF_LIST> *>(this)); }
|
|
||||||
|
|
||||||
STDMETHOD(QueryInterface)(REFIID riid, void** ppv)
|
|
||||||
{
|
|
||||||
const uuid_t& iid = uuid_t::create_const_reference(riid);
|
|
||||||
com_ptr< ::IUnknown> p;
|
|
||||||
|
|
||||||
impl::interface_finder<ITF_LIST>::find_interface(this, iid, p);
|
|
||||||
|
|
||||||
if (!p) {
|
|
||||||
if (riid != IID_IUnknown) {
|
|
||||||
*ppv = 0;
|
|
||||||
return E_NOINTERFACE;
|
|
||||||
}
|
|
||||||
p = get_unknown();
|
|
||||||
// p = static_cast< ::IUnknown* >(static_cast< typename ITF_LIST::head * >(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
*ppv = reinterpret_cast<void*>(p.detach());
|
|
||||||
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/** \struct implement_internal_qi impqi.h comet/impqi.h
|
|
||||||
* Implementation of QueryInterfaceInternal. Inherits from all the types defined
|
|
||||||
* in \p ITF_LIST. This implementation is used in aggregation.
|
|
||||||
* \param ITF_LIST interface implementation list.
|
|
||||||
*/
|
|
||||||
template<typename ITF_LIST> class ATL_NO_VTABLE implement_internal_qi : public typelist::inherit_all<ITF_LIST>
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
void qi();
|
|
||||||
public:
|
|
||||||
/** Get at the unknown for this class. Is especially useful using
|
|
||||||
* aggregateable_coclass in getting at a pointer from which to
|
|
||||||
* QueryInterface from.
|
|
||||||
*/
|
|
||||||
::IUnknown* get_unknown()const
|
|
||||||
{ return static_cast< typename ITF_LIST::head * >( const_cast<implement_internal_qi<ITF_LIST> *>(this)); }
|
|
||||||
|
|
||||||
HRESULT QueryInterfaceInternal(REFIID riid, void** ppv)
|
|
||||||
{
|
|
||||||
const IID& iid = riid;
|
|
||||||
com_ptr< ::IUnknown> p;
|
|
||||||
|
|
||||||
impl::interface_finder<ITF_LIST>::find_interface(this, iid, p);
|
|
||||||
|
|
||||||
if (!p) {
|
|
||||||
if (riid != IID_IUnknown) {
|
|
||||||
*ppv = 0;
|
|
||||||
return E_NOINTERFACE;
|
|
||||||
}
|
|
||||||
// p = cast_to_unknown(this);
|
|
||||||
p = static_cast< ::IUnknown* >(static_cast<typename ITF_LIST::head*>(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
*ppv = reinterpret_cast<void*>(p.detach());
|
|
||||||
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace impl {
|
|
||||||
template<typename ITF_LIST> ::IUnknown* cast_to_unknown(implement_qi<ITF_LIST>* iq)
|
|
||||||
{ return static_cast< typename ITF_LIST::head*>(iq); }
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \class impl_dispatch impqi.h comet/impqi.h
|
|
||||||
* Implement IDispatch via type-library.
|
|
||||||
*/
|
|
||||||
template<typename BASE, typename TL> class ATL_NO_VTABLE impl_dispatch : public BASE
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
/// \name IDispatch Interface
|
|
||||||
//@{
|
|
||||||
STDMETHOD(GetTypeInfo)(UINT, LCID, ITypeInfo** ti)
|
|
||||||
{
|
|
||||||
*ti = get_ti();
|
|
||||||
if (*ti)
|
|
||||||
{
|
|
||||||
(*ti)->AddRef();
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
return E_NOTIMPL;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHOD(GetTypeInfoCount)(UINT *it)
|
|
||||||
{ *it = 1; return S_OK; }
|
|
||||||
|
|
||||||
STDMETHOD(GetIDsOfNames)(REFIID, OLECHAR** pNames, UINT cNames, LCID, DISPID* pdispids)
|
|
||||||
{
|
|
||||||
ITypeInfo* ti = get_ti();
|
|
||||||
if (ti)
|
|
||||||
return ti->GetIDsOfNames(pNames, cNames, pdispids);
|
|
||||||
else
|
|
||||||
return E_NOTIMPL;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHOD(Invoke)(DISPID id, REFIID, LCID, WORD wFlags, DISPPARAMS *pd, VARIANT* pVarResult, EXCEPINFO* pe, UINT* pu)
|
|
||||||
{
|
|
||||||
ITypeInfo* ti = get_ti();
|
|
||||||
if (ti)
|
|
||||||
{
|
|
||||||
void* pThis = static_cast<BASE*>(this);
|
|
||||||
return ti->Invoke(pThis, id, wFlags, pd, pVarResult, pe, pu);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return E_NOTIMPL;
|
|
||||||
}
|
|
||||||
//@}
|
|
||||||
private:
|
|
||||||
ITypeInfo* get_ti()
|
|
||||||
{
|
|
||||||
static ITypeInfo* ti_;
|
|
||||||
if (ti_ == 0)
|
|
||||||
{
|
|
||||||
auto_cs lock(module().cs());
|
|
||||||
if (ti_ == 0)
|
|
||||||
{
|
|
||||||
com_ptr<ITypeLib> ptl;
|
|
||||||
|
|
||||||
typelibrary_loader<TL>::load(ptl.out());
|
|
||||||
if (ptl) ptl->GetTypeInfoOfGuid(uuidof<BASE>(), &ti_);
|
|
||||||
|
|
||||||
if (ti_ != 0) module().add_object_to_dispose( impl::create_itf_releaser(ti_) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ti_;
|
|
||||||
}
|
|
||||||
|
|
||||||
// static ITypeInfo* ti_;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Itf> class com_ptr;
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
/** \class aggregates_interface impqi.h comet/impqi.h
|
|
||||||
* Used as an implementation for an interface to Aggregate the required
|
|
||||||
* interface.
|
|
||||||
*/
|
|
||||||
template< typename Itf >
|
|
||||||
class aggregates_interface
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/** Set the inner-unknown returned from the call to CoCreateInstance.
|
|
||||||
*/
|
|
||||||
void set_aggregate(const com_ptr< ::IUnknown>& aggobj) { ag_object_ = com_cast(aggobj); }
|
|
||||||
/** Used by QueryInteface algorithms to work out the interface
|
|
||||||
* exposed by this class.
|
|
||||||
*/
|
|
||||||
typedef Itf exposes;
|
|
||||||
|
|
||||||
operator Itf*() throw()
|
|
||||||
{
|
|
||||||
com_ptr< ::IUnknown> test = ag_object_;
|
|
||||||
return ag_object_.in();
|
|
||||||
// return com_ptr<Itf>( com_cast(ag_object_) );
|
|
||||||
}
|
|
||||||
protected:
|
|
||||||
com_ptr<Itf> ag_object_;
|
|
||||||
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* class FTM : public qi_hook_itf<IMarshal>
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
com_ptr<IMarshal> get_interface_ptr(const com_ptr< ::IUnknown>& This) throw()
|
|
||||||
{
|
|
||||||
::IUnknown* ftm = 0;
|
|
||||||
CoCreateFreeThreadedMarshaler(This.in(), &ftm);
|
|
||||||
return com_cast(ftm);
|
|
||||||
}
|
|
||||||
};*/
|
|
||||||
|
|
||||||
/** \struct FTM impqi.h comet/impqi.h
|
|
||||||
* Aggregate the Free Threaded Marshaller.
|
|
||||||
* \code
|
|
||||||
class coclass_implementation<CoMyClass>
|
|
||||||
: public coclass<CoMyClass, thread_model::Free, FTM>
|
|
||||||
{
|
|
||||||
...
|
|
||||||
};
|
|
||||||
\endcode
|
|
||||||
*/
|
|
||||||
struct FTM : public qi_hook
|
|
||||||
{
|
|
||||||
template<typename T>
|
|
||||||
bool qi(T *This, const uuid_t& iid, com_ptr< ::IUnknown>& unk)
|
|
||||||
{
|
|
||||||
if (iid != uuidof<IMarshal>()) return false;
|
|
||||||
::IUnknown* ftm = 0;
|
|
||||||
CoCreateFreeThreadedMarshaler(impl::cast_to_unknown(This), &ftm);
|
|
||||||
unk = com_ptr< ::IMarshal>( com_cast(ftm) );
|
|
||||||
return unk != 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/** \struct aggregates impqi.h comet/impqi.h
|
|
||||||
* Aggregate an interface.
|
|
||||||
* \code
|
|
||||||
class coclass_implementation<CoMyClass>
|
|
||||||
: public coclass<CoMyClass, thread_model::Free, aggregates<IMyInterface> >
|
|
||||||
{
|
|
||||||
coclass_implementation()
|
|
||||||
{
|
|
||||||
aggregates<IMyInterface>create_aggregate::create_aggregate(this, CLSCTX_ALL);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
\endcode
|
|
||||||
|
|
||||||
\sa coclass
|
|
||||||
*/
|
|
||||||
template<typename COCLASS, COMET_LIST_TEMPLATE> class aggregates : public qi_hook
|
|
||||||
{
|
|
||||||
com_ptr< ::IUnknown> inner_;
|
|
||||||
public:
|
|
||||||
template<typename T> bool qi(T *This, const uuid_t& iid, com_ptr< ::IUnknown>& unk)
|
|
||||||
{
|
|
||||||
typedef typename make_list<COMET_LIST_ARG_1>::result TL;
|
|
||||||
if (typelist::length<TL>::value > 0) {
|
|
||||||
if (impl::interface_finder<TL>::find_interface_2(iid) == false) return false;
|
|
||||||
}
|
|
||||||
if (inner_ == 0) return false;
|
|
||||||
::IUnknown* p;
|
|
||||||
if (SUCCEEDED(inner_.raw()->QueryInterface(iid, reinterpret_cast<void**>(&p))))
|
|
||||||
{
|
|
||||||
unk = auto_attach(p);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
protected:
|
|
||||||
template<typename T> void create_aggregate(T *This, DWORD dwClsContext = CLSCTX_ALL)
|
|
||||||
{ ::IUnknown* unk_this = impl::cast_to_unknown(This); inner_ = com_ptr< ::IUnknown>(uuidof<COCLASS>(), com_ptr< ::IUnknown>::create_reference(unk_this), dwClsContext); }
|
|
||||||
};
|
|
||||||
|
|
||||||
/* template<typename Itf> class aggregates_interface : public qi_hook_itf<Itf>
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
com_ptr< ::IUnknown> inner_;
|
|
||||||
com_ptr<Itf> get_interface_ptr(const com_ptr< ::IUnknown>&)
|
|
||||||
{ return com_cast(inner_); }
|
|
||||||
protected:
|
|
||||||
template<typename ITF_LIST> void create_aggregate(const CLSID& clsid, implement_qi<ITF_LIST>* This, DWORD dwClsContext = CLSCTX_ALL)
|
|
||||||
{
|
|
||||||
::IUnknown* unk_this = static_cast< typename ITF_LIST::head*>(This);
|
|
||||||
inner_ = com_ptr< ::IUnknown>(clsid, com_ptr< ::IUnknown>::create_reference(unk_this), dwClsContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename ITF_LIST> void create_aggregate(const wchar_t* progid, implement_qi<ITF_LIST>* This, DWORD dwClsContext = CLSCTX_ALL)
|
|
||||||
{
|
|
||||||
::IUnknown* unk_this = static_cast< typename ITF_LIST::head*>(This);
|
|
||||||
inner_ = com_ptr< ::IUnknown>(progid, com_ptr< ::IUnknown>::create_reference(unk_this), dwClsContext);
|
|
||||||
}
|
|
||||||
};*/
|
|
||||||
|
|
||||||
//@}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,256 +0,0 @@
|
||||||
/** \file
|
|
||||||
* Provide comtype which supplies information about UUIDs & inheritance,
|
|
||||||
* potentially from Interfaces not defined using a COMET type-library. Also
|
|
||||||
* defines specialisations for some such standard interfaces.
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* Copyright © 2000, 2001 Sofus Mortensen
|
|
||||||
*
|
|
||||||
* This material is provided "as is", with absolutely no warranty
|
|
||||||
* expressed or implied. Any use is at your own risk. Permission to
|
|
||||||
* use or copy this software for any purpose is hereby granted without
|
|
||||||
* fee, provided the above notices are retained on all copies.
|
|
||||||
* Permission to modify the code and to distribute modified code is
|
|
||||||
* granted, provided the above notices are retained, and a notice that
|
|
||||||
* the code was modified is included with the above copyright notice.
|
|
||||||
*
|
|
||||||
* This header is part of Comet version 2.
|
|
||||||
* https://github.com/alamaison/comet
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef COMET_INTERFACE_H
|
|
||||||
#define COMET_INTERFACE_H
|
|
||||||
|
|
||||||
#include <comet/config.h>
|
|
||||||
|
|
||||||
#include <ocidl.h>
|
|
||||||
#include <string>
|
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
#include <comet/typelist.h>
|
|
||||||
#include <comet/static_assert.h>
|
|
||||||
#include <comet/uuid_fwd.h>
|
|
||||||
|
|
||||||
#pragma warning(push, 4)
|
|
||||||
// NB: coclass_implementation _must_ have no data members.
|
|
||||||
// The comet framework uses the test
|
|
||||||
// sizeof coclass_implementation<T> == sizeof coclass_implementation<nil>
|
|
||||||
// in order to determine whether the user has specialized based on T or not.
|
|
||||||
// The logic here is that any real implementation will have a size that is at least
|
|
||||||
// sizeof IUnknown, because any real coclass_implementation must at least derive
|
|
||||||
// off IUnknown and have a "vtable" pointer.
|
|
||||||
/** \class coclass_implementation interface.h comet/interface.h
|
|
||||||
* Utility class to make the implementation of a coclass accessible from the
|
|
||||||
* servers. Implementations of coclasses defined in the type library should
|
|
||||||
* all be specialisations of this class if they are to be exposed by the
|
|
||||||
* comet server.
|
|
||||||
*/
|
|
||||||
template<typename T> class coclass_implementation {};
|
|
||||||
|
|
||||||
#pragma warning(pop)
|
|
||||||
|
|
||||||
namespace comet {
|
|
||||||
|
|
||||||
/** Provide a means for defining new comtype definitions.
|
|
||||||
*/
|
|
||||||
template<typename ITF, const UUID *ItfID, typename BASE = ::IUnknown> struct uuid_comtype
|
|
||||||
{
|
|
||||||
static const uuid_t& uuid() { return uuid_t::create_const_reference(*ItfID); }
|
|
||||||
typedef BASE base;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/** Provide access to uuid and base type of objects.
|
|
||||||
* Specializations allow access to information relevant to non-comet
|
|
||||||
* defined interfaces.
|
|
||||||
*/
|
|
||||||
template<typename T> struct comtype {
|
|
||||||
static const IID& uuid() throw() { return comtype<COMET_STRICT_TYPENAME T::interface_is>::uuid(); }
|
|
||||||
typedef typename comtype<COMET_STRICT_TYPENAME T::interface_is>::base base;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<> struct comtype<nil> {
|
|
||||||
// static const IID& uuid() throw() { throw std::logic_error("interface.h:35"); return IID_NULL; }
|
|
||||||
typedef nil base;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<> struct comtype< ::IUnknown >
|
|
||||||
{
|
|
||||||
static const IID& uuid() { return IID_IUnknown; }
|
|
||||||
typedef nil base;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<> struct comtype<IConnectionPoint>
|
|
||||||
{
|
|
||||||
static const IID& uuid() { return IID_IConnectionPoint; }
|
|
||||||
typedef ::IUnknown base;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<> struct comtype<IConnectionPointContainer>
|
|
||||||
{
|
|
||||||
static const IID& uuid() { return IID_IConnectionPointContainer; }
|
|
||||||
typedef ::IUnknown base;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<> struct comtype<IEnumConnections>
|
|
||||||
{
|
|
||||||
static const IID& uuid() { return IID_IEnumConnections; }
|
|
||||||
typedef ::IUnknown base;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<> struct comtype<IDispatch>
|
|
||||||
{
|
|
||||||
static const IID& uuid() { return IID_IDispatch; }
|
|
||||||
typedef ::IUnknown base;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<> struct comtype<IEnumVARIANT>
|
|
||||||
{
|
|
||||||
static const IID& uuid() { return IID_IEnumVARIANT; }
|
|
||||||
typedef ::IUnknown base;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<> struct comtype<ISupportErrorInfo>
|
|
||||||
{
|
|
||||||
static const IID& uuid() { return IID_ISupportErrorInfo; }
|
|
||||||
typedef ::IUnknown base;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<> struct comtype<IErrorInfo>
|
|
||||||
{
|
|
||||||
static const IID& uuid() { return IID_IErrorInfo; }
|
|
||||||
typedef ::IUnknown base;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<> struct comtype<IProvideClassInfo>
|
|
||||||
{
|
|
||||||
static const IID& uuid() throw() { return IID_IProvideClassInfo; }
|
|
||||||
typedef ::IUnknown base;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<> struct comtype<IPersist>
|
|
||||||
{
|
|
||||||
static const IID& uuid() throw() { return IID_IPersist; }
|
|
||||||
typedef ::IUnknown base;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<> struct comtype<IPersistFile>
|
|
||||||
{
|
|
||||||
static const IID& uuid() throw() { return IID_IPersistFile; }
|
|
||||||
typedef ::IPersist base;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<> struct comtype<IPersistStream>
|
|
||||||
{
|
|
||||||
static const IID& uuid() throw() { return IID_IPersistStream; }
|
|
||||||
typedef ::IPersist base;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<> struct comtype<IPersistStreamInit>
|
|
||||||
{
|
|
||||||
static const IID& uuid() throw() { return IID_IPersistStreamInit; }
|
|
||||||
typedef ::IPersist base;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<> struct comtype<IMessageFilter>
|
|
||||||
{
|
|
||||||
static const IID& uuid() throw() { return IID_IMessageFilter; }
|
|
||||||
typedef ::IUnknown base;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<> struct comtype<IProvideClassInfo2>
|
|
||||||
{
|
|
||||||
static const IID& uuid() throw() { return IID_IProvideClassInfo2; }
|
|
||||||
typedef ::IUnknown base;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<> struct comtype<IMarshal>
|
|
||||||
{
|
|
||||||
static const IID& uuid() throw() { return IID_IMarshal; }
|
|
||||||
typedef ::IUnknown base;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<> struct comtype<IFontDisp>
|
|
||||||
{
|
|
||||||
static const IID& uuid() throw() { return IID_IFontDisp; }
|
|
||||||
typedef ::IDispatch base;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<> struct comtype<IPictureDisp>
|
|
||||||
{
|
|
||||||
static const IID& uuid() throw() { return IID_IPictureDisp; }
|
|
||||||
typedef ::IDispatch base;
|
|
||||||
};
|
|
||||||
template<> struct comtype<IGlobalInterfaceTable>
|
|
||||||
{
|
|
||||||
static const IID& uuid() throw() { return IID_IGlobalInterfaceTable; }
|
|
||||||
typedef ::IUnknown base;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<> struct comtype<IClassFactory>
|
|
||||||
{
|
|
||||||
static const IID& uuid() throw() { return IID_IClassFactory; }
|
|
||||||
typedef ::IUnknown base;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<> struct comtype<IStream>
|
|
||||||
{
|
|
||||||
static const IID& uuid() throw() { return IID_IStream; }
|
|
||||||
typedef ::IUnknown base;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<> struct comtype<ISequentialStream>
|
|
||||||
{
|
|
||||||
static const IID& uuid() throw() { return IID_ISequentialStream; }
|
|
||||||
typedef ::IUnknown base;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//! C++ replacement of VC's __uuidof()
|
|
||||||
/*!
|
|
||||||
Use this function to an IID to an interface or coclass.
|
|
||||||
*/
|
|
||||||
template<typename Itf> inline const uuid_t& uuidof(Itf * = 0) throw()
|
|
||||||
{ return uuid_t::create_const_reference(comtype<Itf>::uuid()); }
|
|
||||||
|
|
||||||
namespace impl {
|
|
||||||
|
|
||||||
template<typename Itf> struct interface_lookup
|
|
||||||
{
|
|
||||||
static bool supports(const uuid_t& iid)
|
|
||||||
{
|
|
||||||
if (iid == uuidof<Itf>())
|
|
||||||
return true;
|
|
||||||
else
|
|
||||||
return interface_lookup< typename comtype<Itf>::base >::supports();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T> static Itf* cast(T* t)
|
|
||||||
{
|
|
||||||
return static_cast<Itf*>(t);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<> struct interface_lookup<nil>
|
|
||||||
{
|
|
||||||
static bool supports(const uuid_t&)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/* template<> struct interface_lookup<make_list<> >
|
|
||||||
{
|
|
||||||
static bool supports(const uuid_t&)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
};*/
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,126 +0,0 @@
|
||||||
/** \file
|
|
||||||
* Implementation of invariant_lock asserts.
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* Copyright © 2000, 2001 Sofus Mortensen, Paul Hollingsworth
|
|
||||||
*
|
|
||||||
* This material is provided "as is", with absolutely no warranty
|
|
||||||
* expressed or implied. Any use is at your own risk. Permission to
|
|
||||||
* use or copy this software for any purpose is hereby granted without
|
|
||||||
* fee, provided the above notices are retained on all copies.
|
|
||||||
* Permission to modify the code and to distribute modified code is
|
|
||||||
* granted, provided the above notices are retained, and a notice that
|
|
||||||
* the code was modified is included with the above copyright notice.
|
|
||||||
*
|
|
||||||
* This header is part of Comet version 2.
|
|
||||||
* https://github.com/alamaison/comet
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef COMET_UTIL_H
|
|
||||||
#define COMET_UTIL_H
|
|
||||||
|
|
||||||
#include <comet/config.h>
|
|
||||||
|
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
#include <comet/error.h>
|
|
||||||
|
|
||||||
namespace comet {
|
|
||||||
/*! \addtogroup Misc
|
|
||||||
*/
|
|
||||||
//@{
|
|
||||||
|
|
||||||
/** Contains implementation of invariant_lock asserts.
|
|
||||||
*/
|
|
||||||
namespace invariant_lock_impl {
|
|
||||||
|
|
||||||
/** Provides base class for invariant_locks.
|
|
||||||
* \sa create_invariant_lock enforcer simple_enforcer
|
|
||||||
*/
|
|
||||||
class invariant_lock
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
invariant_lock() {}
|
|
||||||
invariant_lock(const invariant_lock& /*rhs*/) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
/** A version of invariant_lock able to call any void member of a class.
|
|
||||||
* The member should provide an assertable condition that gets asserted
|
|
||||||
* on creation and destruction of the lock.
|
|
||||||
* \sa create_invariant_lock
|
|
||||||
*/
|
|
||||||
template<typename CLASS> struct enforcer : public invariant_lock
|
|
||||||
{
|
|
||||||
void (CLASS::*m_passert) () const;
|
|
||||||
const CLASS *m_pobj;
|
|
||||||
|
|
||||||
enforcer(const CLASS *pobj, void (CLASS::*passert) () const
|
|
||||||
) : m_pobj(pobj), m_passert(passert)
|
|
||||||
{
|
|
||||||
(m_pobj->*m_passert)();
|
|
||||||
}
|
|
||||||
~enforcer()
|
|
||||||
{
|
|
||||||
(m_pobj->*m_passert)();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/** A version of invariant_lock that calls public method \b assert_valid on
|
|
||||||
* construction and destruction of the lock.
|
|
||||||
* \sa create_invariant_lock
|
|
||||||
*/
|
|
||||||
template<typename CLASS> struct simple_enforcer : public invariant_lock
|
|
||||||
{
|
|
||||||
const CLASS *m_pobj;
|
|
||||||
simple_enforcer(const CLASS *pobj) : m_pobj(pobj)
|
|
||||||
{
|
|
||||||
m_pobj->assert_valid();
|
|
||||||
}
|
|
||||||
|
|
||||||
~simple_enforcer()
|
|
||||||
{
|
|
||||||
m_pobj->assert_valid();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} // namespace invariant_lock_impl
|
|
||||||
|
|
||||||
/*! Create an invariant_lock.
|
|
||||||
* \param pobj The class with the invariant assert
|
|
||||||
* \param assert_member The void member to call on construct & destruct
|
|
||||||
* \author Paul Hollingsworth (Paul@PaulHollingsworth.com)
|
|
||||||
* \relates invariant_lock_impl::invariant_lock
|
|
||||||
* \sa enforcer
|
|
||||||
*/
|
|
||||||
template<typename CLASS>
|
|
||||||
invariant_lock_impl::enforcer<CLASS> create_invariant_lock(const CLASS *pobj, void (CLASS::*assert_member) () const)
|
|
||||||
{
|
|
||||||
return invariant_lock_impl::enforcer<CLASS>(pobj, assert_member);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! Create a simple invariant lock.
|
|
||||||
* This lock will expect assert_valid to be publicly defined on the object
|
|
||||||
* provided.
|
|
||||||
* \param pobj The class with the invariant assert.
|
|
||||||
* \relates invariant_lock_impl::invariant_lock
|
|
||||||
* \sa simple_enforcer
|
|
||||||
* \author Paul Hollingsworth (Paul@PaulHollingsworth.com)
|
|
||||||
*/
|
|
||||||
template<typename CLASS>
|
|
||||||
invariant_lock_impl::simple_enforcer<CLASS> create_invariant_lock(const CLASS *pobj)
|
|
||||||
{
|
|
||||||
return pobj;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! Pointer class to an invariant_lock.
|
|
||||||
* Assigning a temporary to a const reference will cause the object to be
|
|
||||||
* kept for the scope of the const reference.
|
|
||||||
* \relates invariant_lock_impl::invariant_lock
|
|
||||||
* \sa create_invariant_lock
|
|
||||||
* \author Paul Hollingsworth (Paul@PaulHollingsworth.com)
|
|
||||||
*/
|
|
||||||
typedef invariant_lock_impl::invariant_lock &invariant_lock;
|
|
||||||
//@}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,228 +0,0 @@
|
||||||
/** \file
|
|
||||||
* Lightweight Multiple Reader Single Writer lock.
|
|
||||||
*
|
|
||||||
* See \ref cometlwlock.
|
|
||||||
*
|
|
||||||
* The lw_lock class is heavily based on class LightweightLock written by Brad Wilson.
|
|
||||||
* see http://www.quality.nu/dotnetguy/archive/fog0000000007.aspx
|
|
||||||
* \author Brad Wilson
|
|
||||||
* \author Sofus Mortensen
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Copyright (C) 1995-2002 Brad Wilson
|
|
||||||
//
|
|
||||||
// This material is provided "as is", with absolutely no warranty
|
|
||||||
// expressed or implied. Any use is at your own risk. Permission to
|
|
||||||
// use or copy this software for any purpose is hereby granted without
|
|
||||||
// fee, provided the above notices are retained on all copies.
|
|
||||||
// Permission to modify the code and to distribute modified code is
|
|
||||||
// granted, provided the above notices are retained, and a notice that
|
|
||||||
// the code was modified is included with the above copyright notice.
|
|
||||||
//
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
/** \page cometlwlock Lightweight Lock
|
|
||||||
This lightweight lock class was adapted from samples and ideas that
|
|
||||||
were put across the ATL mailing list. It is a non-starving, kernel-
|
|
||||||
free lock that does not order writer requests. It is optimized for
|
|
||||||
use with resources that can take multiple simultaneous reads,
|
|
||||||
particularly when writing is only an occasional task.
|
|
||||||
|
|
||||||
Multiple readers may acquire the lock without any interference with
|
|
||||||
one another. As soon as a writer requests the lock, additional
|
|
||||||
readers will spin. When the pre-writer readers have all given up
|
|
||||||
control of the lock, the writer will obtain it. After the writer
|
|
||||||
has rescinded control, the additional readers will gain access
|
|
||||||
to the locked resource.
|
|
||||||
|
|
||||||
This class is very lightweight. It does not use any kernel objects.
|
|
||||||
It is designed for rapid access to resources without requiring
|
|
||||||
code to undergo process and ring changes. Because the "spin"
|
|
||||||
method for this lock is "Sleep(0)", it is a good idea to keep
|
|
||||||
the lock only long enough for short operations; otherwise, CPU
|
|
||||||
will be wasted spinning for the lock. You can change the spin
|
|
||||||
mechanism by #define'ing COMET_LW_LOCK_SPIN before including this
|
|
||||||
header file.
|
|
||||||
|
|
||||||
VERY VERY IMPORTANT: If you have a lock open with read access and
|
|
||||||
attempt to get write access as well, you will deadlock! Always
|
|
||||||
rescind your read access before requesting write access (and,
|
|
||||||
of course, don't rely on any read information across this).
|
|
||||||
|
|
||||||
This lock works in a single process only. It cannot be used, as is,
|
|
||||||
for cross-process synchronization. To do that, you should convert
|
|
||||||
this lock to using a semaphore and mutex, or use shared memory to
|
|
||||||
avoid kernel objects.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright © 2002 Sofus Mortensen
|
|
||||||
*
|
|
||||||
* This material is provided "as is", with absolutely no warranty
|
|
||||||
* expressed or implied. Any use is at your own risk. Permission to
|
|
||||||
* use or copy this software for any purpose is hereby granted without
|
|
||||||
* fee, provided the above notices are retained on all copies.
|
|
||||||
* Permission to modify the code and to distribute modified code is
|
|
||||||
* granted, provided the above notices are retained, and a notice that
|
|
||||||
* the code was modified is included with the above copyright notice.
|
|
||||||
*
|
|
||||||
* This header is part of Comet version 2.
|
|
||||||
* https://github.com/alamaison/comet
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <comet/config.h>
|
|
||||||
#include <comet/assert.h>
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
namespace comet {
|
|
||||||
|
|
||||||
#ifndef COMET_LW_LOCK_SPIN
|
|
||||||
#define COMET_LW_LOCK_SPIN Sleep(0)
|
|
||||||
#endif
|
|
||||||
/*! \addtogroup Misc
|
|
||||||
*/
|
|
||||||
//@{
|
|
||||||
|
|
||||||
/** Provide a lightweight lock imlementation.
|
|
||||||
* See \ref cometlwlock for more information and warnings.
|
|
||||||
* \sa auto_reader_lock auto_writer_lock
|
|
||||||
*/
|
|
||||||
class lw_lock
|
|
||||||
{
|
|
||||||
// Interface
|
|
||||||
|
|
||||||
public:
|
|
||||||
/// Constructor
|
|
||||||
lw_lock()
|
|
||||||
{
|
|
||||||
reader_count_ = 0;
|
|
||||||
writer_count_ = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Destructor
|
|
||||||
~lw_lock()
|
|
||||||
{
|
|
||||||
COMET_ASSERT( reader_count_ == 0 );
|
|
||||||
COMET_ASSERT( writer_count_ == 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Reader lock acquisition
|
|
||||||
void enter_reader() const
|
|
||||||
{
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
// If there's a writer already, spin without unnecessarily
|
|
||||||
// interlocking the CPUs
|
|
||||||
|
|
||||||
if( writer_count_ != 0 )
|
|
||||||
{
|
|
||||||
COMET_LW_LOCK_SPIN;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add to the readers list
|
|
||||||
|
|
||||||
InterlockedIncrement((long *)&reader_count_ );
|
|
||||||
|
|
||||||
// Check for writers again (we may have been pre-empted). If
|
|
||||||
// there are no writers writing or waiting, then we're done.
|
|
||||||
|
|
||||||
if( writer_count_ == 0 )
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Remove from the readers list, spin, try again
|
|
||||||
|
|
||||||
InterlockedDecrement((long *)&reader_count_ );
|
|
||||||
COMET_LW_LOCK_SPIN;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Reader lock release
|
|
||||||
void leave_reader() const
|
|
||||||
{
|
|
||||||
InterlockedDecrement((long *)&reader_count_ );
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Writer lock acquisition
|
|
||||||
void enter_writer()
|
|
||||||
{
|
|
||||||
// See if we can become the writer (expensive, because it inter-
|
|
||||||
// locks the CPUs, so writing should be an infrequent process)
|
|
||||||
|
|
||||||
while( InterlockedExchange((long *)&writer_count_, 1 ) == 1 )
|
|
||||||
{
|
|
||||||
COMET_LW_LOCK_SPIN;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now we're the writer, but there may be outstanding readers.
|
|
||||||
// Spin until there aren't any more; new readers will wait now
|
|
||||||
// that we're the writer.
|
|
||||||
|
|
||||||
while( reader_count_ != 0 )
|
|
||||||
{
|
|
||||||
COMET_LW_LOCK_SPIN;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Writer lock release
|
|
||||||
void leave_writer()
|
|
||||||
{
|
|
||||||
writer_count_ = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Implementation
|
|
||||||
|
|
||||||
private:
|
|
||||||
mutable long volatile reader_count_;
|
|
||||||
mutable long volatile writer_count_;
|
|
||||||
|
|
||||||
// Declare class non-copyable
|
|
||||||
lw_lock(const lw_lock&);
|
|
||||||
lw_lock& operator=(const lw_lock&);
|
|
||||||
};
|
|
||||||
|
|
||||||
/** \class auto_reader_lock lw_lock.h comet/lw_lock.h
|
|
||||||
* Auto-release locking class for lw_lock Read acces.
|
|
||||||
* \sa lw_lock auto_writer_lock
|
|
||||||
*/
|
|
||||||
class auto_reader_lock {
|
|
||||||
public:
|
|
||||||
explicit auto_reader_lock(const lw_lock& cs) : cs_(cs) {
|
|
||||||
cs_.enter_reader();
|
|
||||||
}
|
|
||||||
|
|
||||||
~auto_reader_lock() {
|
|
||||||
cs_.leave_reader();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
auto_reader_lock& operator=(const auto_reader_lock&);
|
|
||||||
auto_reader_lock(const auto_reader_lock&);
|
|
||||||
|
|
||||||
const lw_lock& cs_;
|
|
||||||
};
|
|
||||||
|
|
||||||
/** \class auto_writer_lock lw_lock.h comet/lw_lock.h
|
|
||||||
* Auto-release locking class for lw_lock write acces.
|
|
||||||
* \sa lw_lock auto_reader_lock
|
|
||||||
*/
|
|
||||||
class auto_writer_lock {
|
|
||||||
public:
|
|
||||||
explicit auto_writer_lock(lw_lock& cs) : cs_(cs) {
|
|
||||||
cs_.enter_writer();
|
|
||||||
}
|
|
||||||
|
|
||||||
~auto_writer_lock() {
|
|
||||||
cs_.leave_writer();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
auto_writer_lock& operator=(const auto_writer_lock&);
|
|
||||||
auto_writer_lock(const auto_writer_lock&);
|
|
||||||
|
|
||||||
lw_lock& cs_;
|
|
||||||
};
|
|
||||||
//@}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,274 +0,0 @@
|
||||||
/** \file
|
|
||||||
* Main functionality for providing a COM module.
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* Copyright © 2000-2002 Sofus Mortensen, Paul Hollingsworth, Michael Geddes, Mikael Lindgren
|
|
||||||
*
|
|
||||||
* This material is provided "as is", with absolutely no warranty
|
|
||||||
* expressed or implied. Any use is at your own risk. Permission to
|
|
||||||
* use or copy this software for any purpose is hereby granted without
|
|
||||||
* fee, provided the above notices are retained on all copies.
|
|
||||||
* Permission to modify the code and to distribute modified code is
|
|
||||||
* granted, provided the above notices are retained, and a notice that
|
|
||||||
* the code was modified is included with the above copyright notice.
|
|
||||||
*
|
|
||||||
* This header is part of Comet version 2.
|
|
||||||
* https://github.com/alamaison/comet
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef COMET_MODULE_H
|
|
||||||
#define COMET_MODULE_H
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <comet/config.h>
|
|
||||||
#include <comet/tstring.h>
|
|
||||||
#include <comet/threading.h>
|
|
||||||
|
|
||||||
namespace comet {
|
|
||||||
|
|
||||||
/*!\addtogroup Server
|
|
||||||
*/
|
|
||||||
//@{
|
|
||||||
namespace impl {
|
|
||||||
/** \internal
|
|
||||||
* 'Command' base class.
|
|
||||||
*/
|
|
||||||
struct cmd_t
|
|
||||||
{
|
|
||||||
virtual void cmd() = 0;
|
|
||||||
cmd_t() {}
|
|
||||||
private:
|
|
||||||
cmd_t(const cmd_t&);
|
|
||||||
cmd_t& operator=(const cmd_t&);
|
|
||||||
};
|
|
||||||
|
|
||||||
/** \internal
|
|
||||||
* 'Command' to delete a pointer.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
template<typename T>
|
|
||||||
struct itf_releaser_t : public cmd_t
|
|
||||||
{
|
|
||||||
void cmd() { IUnknown *p = p_; p_=NULL; p->Release(); }
|
|
||||||
itf_releaser_t(T *&p) :p_(p) { }
|
|
||||||
private:
|
|
||||||
T *&p_;
|
|
||||||
itf_releaser_t(const itf_releaser_t&);
|
|
||||||
itf_releaser_t& operator=(const itf_releaser_t&);
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
cmd_t *create_itf_releaser( T *&p)
|
|
||||||
{
|
|
||||||
return new itf_releaser_t<T>(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 'Command' to Call object_dispose on an object.
|
|
||||||
* \internal
|
|
||||||
*/
|
|
||||||
template<typename T>
|
|
||||||
struct pointer_deleter_t : public cmd_t
|
|
||||||
{
|
|
||||||
void cmd() { T *p = p_; p_=NULL; delete p;}
|
|
||||||
pointer_deleter_t(T *&p) :p_(p) { }
|
|
||||||
private:
|
|
||||||
T *&p_;
|
|
||||||
pointer_deleter_t(const pointer_deleter_t&);
|
|
||||||
pointer_deleter_t& operator=(const pointer_deleter_t&);
|
|
||||||
};
|
|
||||||
|
|
||||||
/** 'Command' to Call object_dispose on an object.
|
|
||||||
* \internal
|
|
||||||
*/
|
|
||||||
template<typename T>
|
|
||||||
struct object_disposer_t : public cmd_t
|
|
||||||
{
|
|
||||||
void cmd() { p_->object_dispose(); }
|
|
||||||
object_disposer_t( T*p) : p_(p) {}
|
|
||||||
private:
|
|
||||||
T *p_;
|
|
||||||
object_disposer_t(const object_disposer_t &);
|
|
||||||
object_disposer_t &operator=(const object_disposer_t &);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
//! Create a pointer deleter command.
|
|
||||||
/** A command to delete pointers, commonly used for shutdown.
|
|
||||||
* \code
|
|
||||||
module().add_object_to_dispose(create_pointer_deleter(new my_class_t()));
|
|
||||||
* \endcode
|
|
||||||
* \sa module_t::add_object_to_dispose
|
|
||||||
*/
|
|
||||||
template<typename T>
|
|
||||||
impl::cmd_t *create_pointer_deleter( T *&p)
|
|
||||||
{
|
|
||||||
return new impl::pointer_deleter_t<T>(p);
|
|
||||||
}
|
|
||||||
//! Create an interface releaser command.
|
|
||||||
/** A command to release COM objects, commonly used for shutdown.
|
|
||||||
* Used for singletons.
|
|
||||||
* \code
|
|
||||||
module().add_object_to_dispose(create_interface_releaser(new my_coclass()));
|
|
||||||
* \endcode
|
|
||||||
* \sa module_t::add_object_to_dispose
|
|
||||||
*/
|
|
||||||
template<typename T>
|
|
||||||
impl::cmd_t *create_interface_releaser( T *&p)
|
|
||||||
{
|
|
||||||
return new impl::itf_releaser_t<T>(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Create a more generic object 'disposer'.
|
|
||||||
/** Creates a Command that calls a static object_dispose(p) method.
|
|
||||||
* \code
|
|
||||||
class my_class_t
|
|
||||||
{
|
|
||||||
object_dispose( my_class_t *val)
|
|
||||||
{
|
|
||||||
val->destroy_myself();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
module().add_object_to_dispose(create_object_disposer(new my_class_t()));
|
|
||||||
* \endcode
|
|
||||||
* \sa module_t::add_object_to_dispose
|
|
||||||
*/
|
|
||||||
template<typename T>
|
|
||||||
impl::cmd_t *create_object_disposer( T *p )
|
|
||||||
{
|
|
||||||
return new impl::object_disposer_t<T>(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// COM module.
|
|
||||||
struct module_t
|
|
||||||
{
|
|
||||||
//! \name Attributes
|
|
||||||
//@{
|
|
||||||
/// Return current reference count.
|
|
||||||
long rc()
|
|
||||||
{
|
|
||||||
return rc_;
|
|
||||||
}
|
|
||||||
/// Retun the HINSTANCE of the module.
|
|
||||||
HINSTANCE instance() const
|
|
||||||
{
|
|
||||||
return instance_;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set the hinstance of the module.
|
|
||||||
void instance(HINSTANCE h)
|
|
||||||
{
|
|
||||||
instance_ = h;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return the module's critical_section.
|
|
||||||
/** \code
|
|
||||||
auto_cs lock( module().cs() );
|
|
||||||
\endcode
|
|
||||||
*/
|
|
||||||
const critical_section& cs() const
|
|
||||||
{
|
|
||||||
return cs_;
|
|
||||||
}
|
|
||||||
|
|
||||||
//@}
|
|
||||||
|
|
||||||
//! \name Operations
|
|
||||||
//@{
|
|
||||||
|
|
||||||
/// Add to the module locks.
|
|
||||||
void lock()
|
|
||||||
{
|
|
||||||
if (InterlockedIncrement(&rc_) == 1 && shutdown_event_ != 0)
|
|
||||||
{
|
|
||||||
auto_cs lock(cs_);
|
|
||||||
if ( shutdown_event_->is_set())
|
|
||||||
shutdown_event_->reset();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Decrement the module lock.
|
|
||||||
void unlock()
|
|
||||||
{
|
|
||||||
if(InterlockedDecrement(&rc_)==0)
|
|
||||||
{
|
|
||||||
activity_ = true;
|
|
||||||
if (shutdown_event_ != 0)
|
|
||||||
{
|
|
||||||
auto_cs lock(cs_);
|
|
||||||
shutdown_event_->set();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Shutdown the server.
|
|
||||||
void shutdown()
|
|
||||||
{
|
|
||||||
for (std::vector<impl::cmd_t*>::iterator it = objects_to_dispose_.begin(); it != objects_to_dispose_.end(); ++it)
|
|
||||||
{
|
|
||||||
(*it)->cmd();
|
|
||||||
delete *it;
|
|
||||||
}
|
|
||||||
objects_to_dispose_.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set an event for shutdown.
|
|
||||||
void set_shutdown_event(event& shutdown_event)
|
|
||||||
{
|
|
||||||
shutdown_event_ = &shutdown_event;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Remove the event for on shutdown.
|
|
||||||
void clear_shutdown_event()
|
|
||||||
{
|
|
||||||
shutdown_event_ = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns if there has been activity on the module since last reset.
|
|
||||||
bool has_activity() const
|
|
||||||
{
|
|
||||||
return rc_ != 0 || activity_;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Reset the activity marker.
|
|
||||||
void reset_activity_flag()
|
|
||||||
{
|
|
||||||
activity_ = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Add an objet to be disposed on shutdown.
|
|
||||||
void add_object_to_dispose(impl::cmd_t* p)
|
|
||||||
{
|
|
||||||
auto_cs lock(cs_);
|
|
||||||
objects_to_dispose_.push_back(p);
|
|
||||||
}
|
|
||||||
//@}
|
|
||||||
|
|
||||||
private:
|
|
||||||
long rc_;
|
|
||||||
bool activity_;
|
|
||||||
event* shutdown_event_;
|
|
||||||
HINSTANCE instance_;
|
|
||||||
critical_section cs_;
|
|
||||||
|
|
||||||
module_t() : rc_(0), activity_(false),
|
|
||||||
shutdown_event_(0), instance_(0)
|
|
||||||
{}
|
|
||||||
|
|
||||||
std::vector<impl::cmd_t*> objects_to_dispose_;
|
|
||||||
|
|
||||||
friend module_t& module();
|
|
||||||
|
|
||||||
// declare non-copyable
|
|
||||||
module_t(const module_t&);
|
|
||||||
module_t& operator=(const module_t&);
|
|
||||||
};
|
|
||||||
|
|
||||||
//! global module object
|
|
||||||
inline module_t& module()
|
|
||||||
{
|
|
||||||
static module_t m;
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
//@}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,72 +0,0 @@
|
||||||
/** \file
|
|
||||||
* comtype<> definitions for interfaces in the COM header file OLEIDL.H.
|
|
||||||
* \author Gabriel Barta
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* Copyright © 2002 Gabriel Barta
|
|
||||||
*
|
|
||||||
* This material is provided "as is", with absolutely no warranty
|
|
||||||
* expressed or implied. Any use is at your own risk. Permission to
|
|
||||||
* use or copy this software for any purpose is hereby granted without
|
|
||||||
* fee, provided the above notices are retained on all copies.
|
|
||||||
* Permission to modify the code and to distribute modified code is
|
|
||||||
* granted, provided the above notices are retained, and a notice that
|
|
||||||
* the code was modified is included with the above copyright notice.
|
|
||||||
*
|
|
||||||
* This header is part of Comet version 2.
|
|
||||||
* https://github.com/alamaison/comet
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef COMET_OLEIDL_COMTYPES_H
|
|
||||||
#define COMET_OLEIDL_COMTYPES_H
|
|
||||||
|
|
||||||
#include <comet/interface.h>
|
|
||||||
|
|
||||||
namespace comet {
|
|
||||||
template<> struct comtype< ::IOleAdviseHolder>
|
|
||||||
: public uuid_comtype< ::IOleAdviseHolder,&IID_IOleAdviseHolder, ::IUnknown> {} ;
|
|
||||||
template<> struct comtype< ::IOleCache>
|
|
||||||
: public uuid_comtype< ::IOleCache,&IID_IOleCache, ::IUnknown> {} ;
|
|
||||||
template<> struct comtype< ::IOleCache2>
|
|
||||||
: public uuid_comtype< ::IOleCache2,&IID_IOleCache2, ::IOleCache> {} ;
|
|
||||||
template<> struct comtype< ::IOleCacheControl>
|
|
||||||
: public uuid_comtype< ::IOleCacheControl,&IID_IOleCacheControl, ::IUnknown> {} ;
|
|
||||||
template<> struct comtype< ::IParseDisplayName>
|
|
||||||
: public uuid_comtype< ::IParseDisplayName,&IID_IParseDisplayName, ::IUnknown> {} ;
|
|
||||||
template<> struct comtype< ::IOleContainer>
|
|
||||||
: public uuid_comtype< ::IOleContainer,&IID_IOleContainer, ::IParseDisplayName> {} ;
|
|
||||||
template<> struct comtype< ::IOleClientSite>
|
|
||||||
: public uuid_comtype< ::IOleClientSite,&IID_IOleClientSite, ::IUnknown> {} ;
|
|
||||||
template<> struct comtype< ::IOleObject>
|
|
||||||
: public uuid_comtype< ::IOleObject,&IID_IOleObject, ::IUnknown> {} ;
|
|
||||||
template<> struct comtype< ::IOleWindow>
|
|
||||||
: public uuid_comtype< ::IOleWindow,&IID_IOleWindow, ::IUnknown> {} ;
|
|
||||||
template<> struct comtype< ::IOleLink>
|
|
||||||
: public uuid_comtype< ::IOleLink,&IID_IOleLink, ::IUnknown> {} ;
|
|
||||||
template<> struct comtype< ::IOleItemContainer>
|
|
||||||
: public uuid_comtype< ::IOleItemContainer,&IID_IOleItemContainer, ::IOleContainer> {} ;
|
|
||||||
template<> struct comtype< ::IOleInPlaceUIWindow>
|
|
||||||
: public uuid_comtype< ::IOleInPlaceUIWindow,&IID_IOleInPlaceUIWindow, ::IOleWindow> {} ;
|
|
||||||
template<> struct comtype< ::IOleInPlaceActiveObject>
|
|
||||||
: public uuid_comtype< ::IOleInPlaceActiveObject,&IID_IOleInPlaceActiveObject, ::IOleWindow> {} ;
|
|
||||||
template<> struct comtype< ::IOleInPlaceFrame>
|
|
||||||
: public uuid_comtype< ::IOleInPlaceFrame,&IID_IOleInPlaceFrame, ::IOleInPlaceUIWindow> {} ;
|
|
||||||
template<> struct comtype< ::IOleInPlaceObject>
|
|
||||||
: public uuid_comtype< ::IOleInPlaceObject,&IID_IOleInPlaceObject, ::IOleWindow> {} ;
|
|
||||||
template<> struct comtype< ::IOleInPlaceSite>
|
|
||||||
: public uuid_comtype< ::IOleInPlaceSite,&IID_IOleInPlaceSite, ::IOleWindow> {} ;
|
|
||||||
template<> struct comtype< ::IContinue>
|
|
||||||
: public uuid_comtype< ::IContinue,&IID_IContinue, ::IUnknown> {} ;
|
|
||||||
template<> struct comtype< ::IViewObject>
|
|
||||||
: public uuid_comtype< ::IViewObject,&IID_IViewObject, ::IUnknown> {} ;
|
|
||||||
template<> struct comtype< ::IViewObject2>
|
|
||||||
: public uuid_comtype< ::IViewObject2,&IID_IViewObject2, ::IViewObject> {} ;
|
|
||||||
template<> struct comtype< ::IDropSource>
|
|
||||||
: public uuid_comtype< ::IDropSource,&IID_IDropSource, ::IUnknown> {} ;
|
|
||||||
template<> struct comtype< ::IDropTarget>
|
|
||||||
: public uuid_comtype< ::IDropTarget,&IID_IDropTarget, ::IUnknown> {} ;
|
|
||||||
template<> struct comtype< ::IEnumOLEVERB>
|
|
||||||
: public uuid_comtype< ::IEnumOLEVERB,&IID_IEnumOLEVERB, ::IUnknown> {} ;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif //COMET_OLEIDL_COMTYPES_H
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,100 +0,0 @@
|
||||||
/** \file
|
|
||||||
* Implements a class that maintains a reference count.
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* Copyright © 2000, 2001 Sofus Mortensen, Paul Hollingsworth
|
|
||||||
*
|
|
||||||
* This material is provided "as is", with absolutely no warranty
|
|
||||||
* expressed or implied. Any use is at your own risk. Permission to
|
|
||||||
* use or copy this software for any purpose is hereby granted without
|
|
||||||
* fee, provided the above notices are retained on all copies.
|
|
||||||
* Permission to modify the code and to distribute modified code is
|
|
||||||
* granted, provided the above notices are retained, and a notice that
|
|
||||||
* the code was modified is included with the above copyright notice.
|
|
||||||
*
|
|
||||||
* This header is part of Comet version 2.
|
|
||||||
* https://github.com/alamaison/comet
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef COMET_REFERENCE_COUNT_H
|
|
||||||
#define COMET_REFERENCE_COUNT_H
|
|
||||||
|
|
||||||
#include <comet/config.h>
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
namespace comet {
|
|
||||||
/*! \addtogroup Misc
|
|
||||||
*/
|
|
||||||
//@{
|
|
||||||
/// Simple reference counter.
|
|
||||||
class reference_count
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
reference_count() : rc_(0) {};
|
|
||||||
explicit reference_count(size_t x) : rc_(reinterpret_cast<size_t*>(x)) {};
|
|
||||||
|
|
||||||
reference_count(const reference_count& x) : rc_(x.rc_) {};
|
|
||||||
|
|
||||||
enum { FLAGVALUE = 1 };
|
|
||||||
bool is_flag() const {
|
|
||||||
return reinterpret_cast<size_t>(rc_) == 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// is_null
|
|
||||||
/** Implies that the there are currently no outstanding references
|
|
||||||
* to this object.
|
|
||||||
*/
|
|
||||||
bool is_null() const {
|
|
||||||
return rc_ == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Increment count.
|
|
||||||
size_t operator++() {
|
|
||||||
if (!rc_) {
|
|
||||||
rc_ = new size_t(1);
|
|
||||||
}
|
|
||||||
return ++*rc_;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Decrement count.
|
|
||||||
size_t operator--() {
|
|
||||||
if (rc_) {
|
|
||||||
if (--*rc_ == 0) {
|
|
||||||
delete rc_;
|
|
||||||
rc_ = 0;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return *rc_;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear() {
|
|
||||||
rc_ = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void swap(reference_count &rhs) throw() {
|
|
||||||
std::swap(rc_, rhs.rc_);
|
|
||||||
}
|
|
||||||
|
|
||||||
reference_count& operator=(reference_count& x)
|
|
||||||
{
|
|
||||||
rc_ = x.rc_;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
size_t* rc_;
|
|
||||||
}; // class reference_count
|
|
||||||
//@}
|
|
||||||
} // namespace comet
|
|
||||||
|
|
||||||
namespace std {
|
|
||||||
//! Specialisation of std::swap for reference_count.
|
|
||||||
template<> inline void swap(comet::reference_count &lhs, comet::reference_count &rhs) COMET_STD_SWAP_NOTHROW
|
|
||||||
{
|
|
||||||
lhs.swap(rhs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,65 +0,0 @@
|
||||||
/** \file
|
|
||||||
* Base regkey type and error-policy definition.
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* Copyright © 2000, 2001 Paul Hollingsworth
|
|
||||||
*
|
|
||||||
* This material is provided "as is", with absolutely no warranty
|
|
||||||
* expressed or implied. Any use is at your own risk. Permission to
|
|
||||||
* use or copy this software for any purpose is hereby granted without
|
|
||||||
* fee, provided the above notices are retained on all copies.
|
|
||||||
* Permission to modify the code and to distribute modified code is
|
|
||||||
* granted, provided the above notices are retained, and a notice that
|
|
||||||
* the code was modified is included with the above copyright notice.
|
|
||||||
*
|
|
||||||
* This header is part of Comet version 2.
|
|
||||||
* https://github.com/alamaison/comet
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef COMET_REGKEY_H
|
|
||||||
#define COMET_REGKEY_H
|
|
||||||
|
|
||||||
#include <comet/config.h>
|
|
||||||
|
|
||||||
#include <comet/registry.h>
|
|
||||||
#include <comet/error.h>
|
|
||||||
|
|
||||||
namespace comet
|
|
||||||
{
|
|
||||||
/** \struct reg_error regkey.h comet/regkey.h
|
|
||||||
* Standard error policy, mainly for use by registry functions.
|
|
||||||
*/
|
|
||||||
struct reg_error
|
|
||||||
{
|
|
||||||
static void on_error(LONG errcode)
|
|
||||||
{
|
|
||||||
throw com_error(HRESULT_FROM_WIN32(errcode));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void on_typemismatch()
|
|
||||||
{
|
|
||||||
throw com_error(HRESULT_FROM_WIN32(ERROR_INVALID_DATATYPE));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Standard type for use when dealing with registry keys.
|
|
||||||
*/
|
|
||||||
typedef registry::key<reg_error> regkey;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace std {
|
|
||||||
|
|
||||||
COMET_DECLARE_SWAP(comet::regkey)
|
|
||||||
COMET_DECLARE_SWAP(comet::regkey::info_type)
|
|
||||||
COMET_DECLARE_SWAP(comet::regkey::mapped_type)
|
|
||||||
COMET_DECLARE_SWAP(comet::regkey::values_type)
|
|
||||||
COMET_DECLARE_SWAP(comet::regkey::subkeys_type)
|
|
||||||
COMET_DECLARE_SWAP(comet::regkey::value_names_type)
|
|
||||||
COMET_DECLARE_SWAP(comet::regkey::values_type::iterator)
|
|
||||||
COMET_DECLARE_SWAP(comet::regkey::values_type::const_iterator)
|
|
||||||
COMET_DECLARE_SWAP(comet::regkey::subkeys_type::iterator)
|
|
||||||
COMET_DECLARE_SWAP(comet::regkey::value_names_type::iterator)
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,363 +0,0 @@
|
||||||
/** \file
|
|
||||||
* Scope-guards can be used to proivde transactional integrity.
|
|
||||||
*
|
|
||||||
* scope_guard and friends are adopted from source by Andrei Alexandrescu and Petru Marginean.
|
|
||||||
*
|
|
||||||
* See the <a href="http://www.cuj.com/experts/1812/alexandr.htm?topic=experts">article</a>.
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* Copyright © 2001 Sofus Mortensen
|
|
||||||
*
|
|
||||||
* This material is provided "as is", with absolutely no warranty
|
|
||||||
* expressed or implied. Any use is at your own risk. Permission to
|
|
||||||
* use or copy this software for any purpose is hereby granted without
|
|
||||||
* fee, provided the above notices are retained on all copies.
|
|
||||||
* Permission to modify the code and to distribute modified code is
|
|
||||||
* granted, provided the above notices are retained, and a notice that
|
|
||||||
* the code was modified is included with the above copyright notice.
|
|
||||||
*
|
|
||||||
* This header is part of Comet version 2.
|
|
||||||
* https://github.com/alamaison/comet
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef COMET_SCOPE_GUARD_H
|
|
||||||
#define COMET_SCOPE_GUARD_H
|
|
||||||
|
|
||||||
#include <comet/config.h>
|
|
||||||
|
|
||||||
namespace comet {
|
|
||||||
|
|
||||||
/*! \addtogroup Misc
|
|
||||||
*/
|
|
||||||
//@{
|
|
||||||
namespace impl {
|
|
||||||
|
|
||||||
/** Base class providing dismission and safe execution primitives.
|
|
||||||
*/
|
|
||||||
class scope_guard_impl_base
|
|
||||||
{
|
|
||||||
scope_guard_impl_base& operator =(const scope_guard_impl_base&);
|
|
||||||
protected:
|
|
||||||
~scope_guard_impl_base()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
scope_guard_impl_base(const scope_guard_impl_base& other) throw()
|
|
||||||
: dismissed_(other.dismissed_)
|
|
||||||
{
|
|
||||||
other.dismiss();
|
|
||||||
}
|
|
||||||
template <typename J> static void safe_execute(J& j) throw()
|
|
||||||
{
|
|
||||||
if (!j.dismissed_)
|
|
||||||
try
|
|
||||||
{
|
|
||||||
j.execute();
|
|
||||||
}
|
|
||||||
catch(...)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mutable bool dismissed_;
|
|
||||||
public:
|
|
||||||
scope_guard_impl_base() throw() : dismissed_(false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
void dismiss() const throw()
|
|
||||||
{
|
|
||||||
dismissed_ = true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/** 0 parameter scope guard.
|
|
||||||
* \internal
|
|
||||||
*/
|
|
||||||
template <typename F> class scope_guard_impl_0 : public scope_guard_impl_base
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
~scope_guard_impl_0() throw()
|
|
||||||
{
|
|
||||||
safe_execute(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void execute()
|
|
||||||
{
|
|
||||||
fun_();
|
|
||||||
}
|
|
||||||
|
|
||||||
scope_guard_impl_0(F fun) : fun_(fun)
|
|
||||||
{}
|
|
||||||
|
|
||||||
private:
|
|
||||||
F fun_;
|
|
||||||
};
|
|
||||||
|
|
||||||
/** 1 parameter scope guard.
|
|
||||||
* \internal
|
|
||||||
*/
|
|
||||||
template <typename F, typename P1> class scope_guard_impl_1 : public scope_guard_impl_base
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
~scope_guard_impl_1() throw()
|
|
||||||
{
|
|
||||||
safe_execute(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void execute()
|
|
||||||
{
|
|
||||||
fun_(p1_);
|
|
||||||
}
|
|
||||||
|
|
||||||
scope_guard_impl_1(F fun, P1 p1) : fun_(fun), p1_(p1)
|
|
||||||
{}
|
|
||||||
|
|
||||||
private:
|
|
||||||
F fun_;
|
|
||||||
const P1 p1_;
|
|
||||||
};
|
|
||||||
|
|
||||||
/** 2 parameter scope guard.
|
|
||||||
* \internal
|
|
||||||
*/
|
|
||||||
template <typename F, typename P1, typename P2> class scope_guard_impl_2: public scope_guard_impl_base
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
~scope_guard_impl_2() throw()
|
|
||||||
{
|
|
||||||
safe_execute(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void execute()
|
|
||||||
{
|
|
||||||
fun_(p1_, p2_);
|
|
||||||
}
|
|
||||||
|
|
||||||
scope_guard_impl_2(F fun, P1 p1, P2 p2) : fun_(fun), p1_(p1), p2_(p2)
|
|
||||||
{}
|
|
||||||
|
|
||||||
private:
|
|
||||||
F fun_;
|
|
||||||
const P1 p1_;
|
|
||||||
const P2 p2_;
|
|
||||||
};
|
|
||||||
|
|
||||||
/** 3 parameter scope guard.
|
|
||||||
* \internal
|
|
||||||
*/
|
|
||||||
template <typename F, typename P1, typename P2, typename P3> class scope_guard_impl_3 : public scope_guard_impl_base
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
~scope_guard_impl_3() throw()
|
|
||||||
{
|
|
||||||
safe_execute(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void execute()
|
|
||||||
{
|
|
||||||
fun_(p1_, p2_, p3_);
|
|
||||||
}
|
|
||||||
|
|
||||||
scope_guard_impl_3(F fun, P1 p1, P2 p2, P3 p3) : fun_(fun), p1_(p1), p2_(p2), p3_(p3)
|
|
||||||
{}
|
|
||||||
|
|
||||||
private:
|
|
||||||
F fun_;
|
|
||||||
const P1 p1_;
|
|
||||||
const P2 p2_;
|
|
||||||
const P3 p3_;
|
|
||||||
};
|
|
||||||
|
|
||||||
/** 0 parameter object scope guard.
|
|
||||||
* \internal
|
|
||||||
*/
|
|
||||||
template <class Obj, typename MemFun> class obj_scope_guard_impl_0 : public scope_guard_impl_base
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
~obj_scope_guard_impl_0() throw()
|
|
||||||
{
|
|
||||||
safe_execute(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void execute()
|
|
||||||
{
|
|
||||||
(obj_.*memFun_)();
|
|
||||||
}
|
|
||||||
|
|
||||||
obj_scope_guard_impl_0(Obj& obj, MemFun memFun)
|
|
||||||
: obj_(obj), memFun_(memFun) {}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Obj& obj_;
|
|
||||||
MemFun memFun_;
|
|
||||||
};
|
|
||||||
|
|
||||||
/** 1 parameter object scope guard.
|
|
||||||
* \internal
|
|
||||||
*/
|
|
||||||
template <class Obj, typename MemFun, typename P1> class obj_scope_guard_impl_1 : public scope_guard_impl_base
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
~obj_scope_guard_impl_1() throw()
|
|
||||||
{
|
|
||||||
safe_execute(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void execute()
|
|
||||||
{
|
|
||||||
(obj_.*memFun_)(p1_);
|
|
||||||
}
|
|
||||||
|
|
||||||
obj_scope_guard_impl_1(Obj& obj, MemFun memFun, P1 p1)
|
|
||||||
: obj_(obj), memFun_(memFun), p1_(p1) {}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Obj& obj_;
|
|
||||||
MemFun memFun_;
|
|
||||||
const P1 p1_;
|
|
||||||
};
|
|
||||||
|
|
||||||
/** 2 parameter object scope guard.
|
|
||||||
* \internal
|
|
||||||
*/
|
|
||||||
template <class Obj, typename MemFun, typename P1, typename P2> class obj_scope_guard_impl_2 : public scope_guard_impl_base
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
~obj_scope_guard_impl_2() throw()
|
|
||||||
{
|
|
||||||
safe_execute(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void execute()
|
|
||||||
{
|
|
||||||
(obj_.*memFun_)(p1_, p2_);
|
|
||||||
}
|
|
||||||
|
|
||||||
obj_scope_guard_impl_2(Obj& obj, MemFun memFun, P1 p1, P2 p2)
|
|
||||||
: obj_(obj), memFun_(memFun), p1_(p1), p2_(p2) {}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Obj& obj_;
|
|
||||||
MemFun memFun_;
|
|
||||||
const P1 p1_;
|
|
||||||
const P2 p2_;
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Implementation to allow argument to be passed by reference.
|
|
||||||
* \internal
|
|
||||||
* \sa make_guard
|
|
||||||
*/
|
|
||||||
template <class T> class ref_holder
|
|
||||||
{
|
|
||||||
T& ref_;
|
|
||||||
public:
|
|
||||||
ref_holder(T& ref) : ref_(ref) {}
|
|
||||||
operator T& () const
|
|
||||||
{
|
|
||||||
return ref_;
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
// Disable assignment - not implemented
|
|
||||||
ref_holder& operator=(const ref_holder&);
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Allow an argument to be passed by reference.
|
|
||||||
* \code
|
|
||||||
* scope_guard guard = make_guard( fun, by_ref(long) );
|
|
||||||
* \endcode
|
|
||||||
* \relates comet::scope_guard
|
|
||||||
* \internal
|
|
||||||
*/
|
|
||||||
template <class T> inline impl::ref_holder<T> by_ref(T& t)
|
|
||||||
{
|
|
||||||
return impl::ref_holder<T>(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Implements a scope guard with 0 parameters.
|
|
||||||
* \param fun Function or \link functor comet::functor \endlink
|
|
||||||
* \relates comet::scope_guard
|
|
||||||
* \internal
|
|
||||||
*/
|
|
||||||
template <typename F> inline impl::scope_guard_impl_0<F> make_guard(F fun)
|
|
||||||
{
|
|
||||||
return impl::scope_guard_impl_0<F>(fun);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Implements a scope guard with 1 parameter.
|
|
||||||
* \param fun Function or \link functor comet::functor \endlink
|
|
||||||
* \relates comet::scope_guard
|
|
||||||
* \sa by_ref
|
|
||||||
* \internal
|
|
||||||
*/
|
|
||||||
template <typename F, typename P1> inline impl::scope_guard_impl_1<F, P1> make_guard(F fun, P1 p1)
|
|
||||||
{
|
|
||||||
return impl::scope_guard_impl_1<F, P1>(fun, p1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Implements a scope guard with 2 parameters.
|
|
||||||
* \param fun Function or \link functor comet::functor \endlink
|
|
||||||
* \relates comet::scope_guard
|
|
||||||
* \sa by_ref
|
|
||||||
* \internal
|
|
||||||
*/
|
|
||||||
template <typename F, typename P1, typename P2> inline impl::scope_guard_impl_2<F, P1, P2> make_guard(F fun, P1 p1, P2 p2)
|
|
||||||
{
|
|
||||||
return impl::scope_guard_impl_2<F, P1, P2>(fun, p1, p2);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Implements a scope guard with 3 parameters.
|
|
||||||
* \param fun Function or \link functor comet::functor \endlink
|
|
||||||
* \relates comet::scope_guard
|
|
||||||
* \sa by_ref
|
|
||||||
* \internal
|
|
||||||
*/
|
|
||||||
template <typename F, typename P1, typename P2, typename P3> inline impl::scope_guard_impl_3<F, P1, P2, P3> make_guard(F fun, P1 p1, P2 p2, P3 p3)
|
|
||||||
{
|
|
||||||
return impl::scope_guard_impl_3<F, P1, P2, P3>(fun, p1, p2, p3);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Implements a scope guard with 0 parameters, calling a memeber function on an object.
|
|
||||||
* \param fun Function or \link functor comet::functor \endlink
|
|
||||||
* \relates comet::scope_guard
|
|
||||||
*/
|
|
||||||
template <class Obj, typename MemFun> inline impl::obj_scope_guard_impl_0<Obj, MemFun> make_obj_guard(Obj& obj, MemFun memFun)
|
|
||||||
{
|
|
||||||
return impl::obj_scope_guard_impl_0<Obj, MemFun>(obj, memFun);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Implements a scope guard with 1 parameter, calling a memeber function on an object.
|
|
||||||
* \param fun Function or \link functor comet::functor \endlink
|
|
||||||
* \relates comet::scope_guard
|
|
||||||
* \sa by_ref
|
|
||||||
* \internal
|
|
||||||
*/
|
|
||||||
template <class Obj, typename MemFun, typename P1> inline impl::obj_scope_guard_impl_1<Obj, MemFun, P1> make_obj_guard(Obj& obj, MemFun memFun, P1 p1)
|
|
||||||
{
|
|
||||||
return impl::obj_scope_guard_impl_1<Obj, MemFun, P1>(obj, memFun, p1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Implements a scope guard with 2 parameters, calling a memeber function on an object.
|
|
||||||
* \param fun Function or \link functor comet::functor \endlink
|
|
||||||
* \relates comet::scope_guard
|
|
||||||
* \sa by_ref
|
|
||||||
* \internal
|
|
||||||
*/
|
|
||||||
template <class Obj, typename MemFun, typename P1, typename P2> inline impl::obj_scope_guard_impl_2<Obj, MemFun, P1, P2> make_obj_guard(Obj& obj, MemFun memFun, P1 p1, P2 p2)
|
|
||||||
{
|
|
||||||
return impl::obj_scope_guard_impl_2<Obj, MemFun, P1, P2>(obj, memFun, p1, p2);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Pointer to a scope guard.
|
|
||||||
* Relies on const references holding on to an assigned stack object for
|
|
||||||
* the scope of the reference.
|
|
||||||
* \sa scope_guard_impl_0 obj_scope_guard_impl_0 scope_guard_impl_1 obj_scope_guard_impl_1 scope_guard_impl_2 obj_scope_guard_impl_2
|
|
||||||
*/
|
|
||||||
typedef const impl::scope_guard_impl_base& scope_guard;
|
|
||||||
|
|
||||||
//@}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
#endif
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,139 +0,0 @@
|
||||||
/** \file
|
|
||||||
* _NewEnum style COM enumerator backed by a smart pointer to items.
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* Copyright © 2010 Alexander Lamaison
|
|
||||||
*
|
|
||||||
* This material is provided "as is", with absolutely no warranty
|
|
||||||
* expressed or implied. Any use is at your own risk. Permission to
|
|
||||||
* use or copy this software for any purpose is hereby granted without
|
|
||||||
* fee, provided the above notices are retained on all copies.
|
|
||||||
* Permission to modify the code and to distribute modified code is
|
|
||||||
* granted, provided the above notices are retained, and a notice that
|
|
||||||
* the code was modified is included with the above copyright notice.
|
|
||||||
*
|
|
||||||
* This header is part of Comet version 2.
|
|
||||||
* https://github.com/alamaison/comet
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef COMET_SMART_ENUM_H
|
|
||||||
#define COMET_SMART_ENUM_H
|
|
||||||
|
|
||||||
#include <comet/config.h>
|
|
||||||
|
|
||||||
#include <comet/enum_common.h>
|
|
||||||
#include <comet/server.h>
|
|
||||||
|
|
||||||
namespace comet {
|
|
||||||
|
|
||||||
namespace impl {
|
|
||||||
|
|
||||||
template<typename SmartPtr>
|
|
||||||
class smart_enum_source
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef typename SmartPtr::element_type::const_iterator
|
|
||||||
const_iterator;
|
|
||||||
|
|
||||||
explicit smart_enum_source(SmartPtr source)
|
|
||||||
: source_(source), it_(begin()) {}
|
|
||||||
|
|
||||||
const_iterator begin()
|
|
||||||
{
|
|
||||||
return source_->begin();
|
|
||||||
}
|
|
||||||
|
|
||||||
const_iterator end()
|
|
||||||
{
|
|
||||||
return source_->end();
|
|
||||||
}
|
|
||||||
|
|
||||||
const_iterator& current()
|
|
||||||
{
|
|
||||||
return it_;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
SmartPtr source_;
|
|
||||||
const_iterator it_;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implements _NewEnum style COM object on top of smart pointer to
|
|
||||||
* a collection.
|
|
||||||
* \param Itf Enumeration Interface.
|
|
||||||
* \param C STL Style container.
|
|
||||||
* \param T Iteration Element type
|
|
||||||
* \param CONVERTER Converts container element to \p T type. (std::identity<C::value_type>)
|
|
||||||
* \sa stl_enumeration create_enum
|
|
||||||
*/
|
|
||||||
template<
|
|
||||||
typename Itf, typename SmartPtr, typename T,
|
|
||||||
typename CONVERTER=std::identity<
|
|
||||||
COMET_STRICT_TYPENAME SmartPtr::element_type::value_type> >
|
|
||||||
class smart_enumeration :
|
|
||||||
public impl::enumeration<
|
|
||||||
Itf, T, CONVERTER, impl::smart_enum_source<SmartPtr> >
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
smart_enumeration(
|
|
||||||
SmartPtr container, const CONVERTER& converter=CONVERTER())
|
|
||||||
: enumeration(
|
|
||||||
impl::smart_enum_source<SmartPtr>(container), converter) {}
|
|
||||||
|
|
||||||
private:
|
|
||||||
smart_enumeration(const smart_enumeration&);
|
|
||||||
smart_enumeration& operator=(const smart_enumeration&);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Smart Enumeration creation helper.
|
|
||||||
*
|
|
||||||
* Creates the enumeration with the element type specified by the
|
|
||||||
* enumerated_type_of policy. To specify the element type explicitly, use
|
|
||||||
* smart_enumeration directly.
|
|
||||||
*
|
|
||||||
* \tparam ET Enumeration Type e.g. IEnumUnknown.
|
|
||||||
* \tparam SmartPtr Smart pointer (inferred from @a container parameter).
|
|
||||||
*
|
|
||||||
* \param container Smart pointer to an STL collection
|
|
||||||
* e.g. auto_ptr<vector>.
|
|
||||||
*/
|
|
||||||
template<typename ET, typename SmartPtr>
|
|
||||||
inline com_ptr<ET> make_smart_enumeration(SmartPtr container)
|
|
||||||
{
|
|
||||||
typedef typename enumerated_type_of<ET>::is T;
|
|
||||||
typedef std::identity<
|
|
||||||
COMET_STRICT_TYPENAME SmartPtr::element_type::value_type>
|
|
||||||
CONVERTER;
|
|
||||||
return new smart_enumeration<ET, SmartPtr, T, CONVERTER>(container);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Smart Enumeration creation helper with custom converter.
|
|
||||||
*
|
|
||||||
* Creates the enumeration with the element type specified by the
|
|
||||||
* enumerated_type_of policy. To specify the element type explicitly, use
|
|
||||||
* smart_enumeration directly.
|
|
||||||
*
|
|
||||||
* \tparam ET Enumeration Type e.g. IEnumUnknown.
|
|
||||||
* \tparam SmartPtr Smart pointer (inferred from @a container parameter).
|
|
||||||
* \tparam CONVERTER Converter type (inferred from @a converter).
|
|
||||||
*
|
|
||||||
* \param container Smart pointer to an STL collection
|
|
||||||
* e.g. auto_ptr<vector>.
|
|
||||||
* \param converter Custom converter.
|
|
||||||
*/
|
|
||||||
template<typename ET, typename SmartPtr, typename CONVERTER>
|
|
||||||
inline com_ptr<ET> make_smart_enumeration(
|
|
||||||
SmartPtr container, const CONVERTER& converter)
|
|
||||||
{
|
|
||||||
typedef typename enumerated_type_of<ET>::is T;
|
|
||||||
return new smart_enumeration<ET, SmartPtr, T, CONVERTER>(
|
|
||||||
container, converter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,54 +0,0 @@
|
||||||
/** \file
|
|
||||||
Provide compile-time asserts.
|
|
||||||
See <a href="http://www.boost.org">www.boost.org</a> for most recent version including documentation.
|
|
||||||
\author John Maddock
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* Copyright © 2000, 2001 Sofus Mortensen
|
|
||||||
*
|
|
||||||
* This material is provided "as is", with absolutely no warranty
|
|
||||||
* expressed or implied. Any use is at your own risk. Permission to
|
|
||||||
* use or copy this software for any purpose is hereby granted without
|
|
||||||
* fee, provided the above notices are retained on all copies.
|
|
||||||
* Permission to modify the code and to distribute modified code is
|
|
||||||
* granted, provided the above notices are retained, and a notice that
|
|
||||||
* the code was modified is included with the above copyright notice.
|
|
||||||
*
|
|
||||||
* This header is part of Comet version 2.
|
|
||||||
* https://github.com/alamaison/comet
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef COMET_STATIC_ASSERT_H
|
|
||||||
#define COMET_STATIC_ASSERT_H
|
|
||||||
|
|
||||||
#include <comet/config.h>
|
|
||||||
|
|
||||||
// (C) Copyright John Maddock 2000.
|
|
||||||
// Permission to copy, use, modify, sell and
|
|
||||||
// distribute this software is granted provided this copyright notice appears
|
|
||||||
// in all copies. This software is provided "as is" without express or implied
|
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
|
||||||
|
|
||||||
// See http://www.boost.org for most recent version including documentation.
|
|
||||||
|
|
||||||
/*
|
|
||||||
Revision history:
|
|
||||||
02 August 2000
|
|
||||||
Initial version.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace comet {
|
|
||||||
namespace impl {
|
|
||||||
|
|
||||||
template <bool> struct COMPILE_TIME_ASSERTION_FAILURE;
|
|
||||||
|
|
||||||
template <> struct COMPILE_TIME_ASSERTION_FAILURE<true>{};
|
|
||||||
|
|
||||||
template<int> struct ct_assert_test{};
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#define COMET_STATIC_ASSERT( B ) typedef ::comet::impl::ct_assert_test<sizeof(::comet::impl::COMPILE_TIME_ASSERTION_FAILURE< ( B ) >)> comet_static_assert_typedef_
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,69 +0,0 @@
|
||||||
/** \file
|
|
||||||
Provide STL extensions.
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* Copyright © 2001 Sofus Mortensen
|
|
||||||
* Copyright © 2013 Alexander Lamaison
|
|
||||||
*
|
|
||||||
* This material is provided "as is", with absolutely no warranty
|
|
||||||
* expressed or implied. Any use is at your own risk. Permission to
|
|
||||||
* use or copy this software for any purpose is hereby granted without
|
|
||||||
* fee, provided the above notices are retained on all copies.
|
|
||||||
* Permission to modify the code and to distribute modified code is
|
|
||||||
* granted, provided the above notices are retained, and a notice that
|
|
||||||
* the code was modified is included with the above copyright notice.
|
|
||||||
*
|
|
||||||
* This header is part of Comet version 2.
|
|
||||||
* https://github.com/alamaison/comet
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef COMET_STL_H
|
|
||||||
#define COMET_STL_H
|
|
||||||
|
|
||||||
#include <comet/config.h>
|
|
||||||
|
|
||||||
#include <functional>
|
|
||||||
|
|
||||||
// add identity, select1st, and select2nd.
|
|
||||||
#if !defined(__SGI_STL_PORT) && !defined(__MINGW32__)
|
|
||||||
namespace std {
|
|
||||||
/** \internal
|
|
||||||
*/
|
|
||||||
template<typename T> struct identity : public unary_function<T, T> {
|
|
||||||
T operator()(const T& t) { return t; }
|
|
||||||
};
|
|
||||||
|
|
||||||
/** \internal
|
|
||||||
*/
|
|
||||||
template<typename T> struct select1st : public unary_function<typename T::first_type, T> {
|
|
||||||
typename T::first_type operator()(const T& t) { return t.first; }
|
|
||||||
};
|
|
||||||
|
|
||||||
/** \internal
|
|
||||||
*/
|
|
||||||
template<typename T> struct select2nd : public unary_function<typename T::second_type, T> {
|
|
||||||
typename T::second_type operator()(const T& t) { return t.second; }
|
|
||||||
};
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#include <functional>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template<typename T> class delete_fun : public std::unary_function<T, void> {
|
|
||||||
public:
|
|
||||||
void operator()(T& x) { delete x; }
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T> class delete2nd_fun : public std::unary_function<T, void> {
|
|
||||||
public:
|
|
||||||
void operator()(T& x) { delete x.second; }
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T> class delete1st_fun : public std::unary_function<T, void> {
|
|
||||||
public:
|
|
||||||
void operator()(T& x) { delete x.first; }
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,188 +0,0 @@
|
||||||
/** \file
|
|
||||||
* Implement _NewEnum style classes and iterators.
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* Copyright © 2000 Sofus Mortensen
|
|
||||||
*
|
|
||||||
* This material is provided "as is", with absolutely no warranty
|
|
||||||
* expressed or implied. Any use is at your own risk. Permission to
|
|
||||||
* use or copy this software for any purpose is hereby granted without
|
|
||||||
* fee, provided the above notices are retained on all copies.
|
|
||||||
* Permission to modify the code and to distribute modified code is
|
|
||||||
* granted, provided the above notices are retained, and a notice that
|
|
||||||
* the code was modified is included with the above copyright notice.
|
|
||||||
*
|
|
||||||
* This header is part of Comet version 2.
|
|
||||||
* https://github.com/alamaison/comet
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef COMET_STL_ENUM_H
|
|
||||||
#define COMET_STL_ENUM_H
|
|
||||||
|
|
||||||
#include <comet/config.h>
|
|
||||||
|
|
||||||
#include <comet/enum_common.h>
|
|
||||||
#include <comet/server.h>
|
|
||||||
#include <comet/stl.h>
|
|
||||||
#include <comet/variant.h>
|
|
||||||
|
|
||||||
namespace comet {
|
|
||||||
|
|
||||||
namespace impl {
|
|
||||||
|
|
||||||
template<typename Collection, typename Outer>
|
|
||||||
class stl_enum_source
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef typename Collection::const_iterator const_iterator;
|
|
||||||
|
|
||||||
explicit stl_enum_source(
|
|
||||||
const Collection& container, com_ptr<Outer> outer)
|
|
||||||
: outer_(outer), container_(container), it_(begin()) {}
|
|
||||||
|
|
||||||
const_iterator begin()
|
|
||||||
{
|
|
||||||
return container_.begin();
|
|
||||||
}
|
|
||||||
|
|
||||||
const_iterator end()
|
|
||||||
{
|
|
||||||
return container_.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
const_iterator& current()
|
|
||||||
{
|
|
||||||
return it_;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
// Not copy-assignable
|
|
||||||
stl_enum_source& operator=(const stl_enum_source&);
|
|
||||||
|
|
||||||
com_ptr<Outer> outer_;
|
|
||||||
const Collection& container_;
|
|
||||||
const_iterator it_;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \class stl_enumeration_t enum.h comet/enum.h
|
|
||||||
* Implements _NewEnum style COM object.
|
|
||||||
* \param Itf Enumeration Interface.
|
|
||||||
* \param C STL Style container.
|
|
||||||
* \param T Iteration Element type (VARIANT)
|
|
||||||
* \param CONVERTER Converts container element to \p T type. (std::identity<C::value_type>)
|
|
||||||
* \sa stl_enumeration create_enum
|
|
||||||
*/
|
|
||||||
template<
|
|
||||||
typename Itf, typename C, typename T=VARIANT,
|
|
||||||
typename CONVERTER=std::identity<COMET_STRICT_TYPENAME C::value_type>,
|
|
||||||
typename TH=::IUnknown>
|
|
||||||
class stl_enumeration_t :
|
|
||||||
public impl::enumeration<
|
|
||||||
Itf, T, CONVERTER, impl::stl_enum_source<C, TH> >
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
stl_enumeration_t(
|
|
||||||
const C& container, TH* outer=0,
|
|
||||||
const CONVERTER& converter=CONVERTER())
|
|
||||||
: enumeration(
|
|
||||||
impl::stl_enum_source<C, TH>(container, outer), converter) {}
|
|
||||||
|
|
||||||
private:
|
|
||||||
stl_enumeration_t(const stl_enumeration_t&);
|
|
||||||
stl_enumeration_t& operator=(const stl_enumeration_t&);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* STL Enumeration creation helper.
|
|
||||||
*
|
|
||||||
* Creates the enumeration with the element type specified by the
|
|
||||||
* enumerated_type_of policy. To specify the element type directly, use
|
|
||||||
* stl_enumeration_t.
|
|
||||||
*
|
|
||||||
* \param ET Enumeration Type e.g. IEnumUnknown.
|
|
||||||
*/
|
|
||||||
template<typename ET>
|
|
||||||
struct stl_enumeration
|
|
||||||
{
|
|
||||||
|
|
||||||
/** Auto-Create a _NewEnum enumerator from an STL container.
|
|
||||||
* No contained object.
|
|
||||||
* \param container STL Container.
|
|
||||||
*/
|
|
||||||
template<typename C>
|
|
||||||
static com_ptr<ET> create(const C& container)
|
|
||||||
{
|
|
||||||
typedef typename enumerated_type_of<ET>::is T;
|
|
||||||
typedef std::identity<COMET_STRICT_TYPENAME C::value_type>
|
|
||||||
CONVERTER;
|
|
||||||
return new stl_enumeration_t<ET, C, T, CONVERTER, IUnknown>(
|
|
||||||
container, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Auto-Create a _NewEnum enumerator from an STL container.
|
|
||||||
* \param container STL Container.
|
|
||||||
* \param th Outer or \e this pointer.
|
|
||||||
*/
|
|
||||||
template<typename C, typename TH>
|
|
||||||
static com_ptr<ET> create(const C& container, TH* th)
|
|
||||||
{
|
|
||||||
typedef typename enumerated_type_of<ET>::is T;
|
|
||||||
typedef std::identity<COMET_STRICT_TYPENAME C::value_type>
|
|
||||||
CONVERTER;
|
|
||||||
return new stl_enumeration_t<ET, C, T, CONVERTER, TH>(
|
|
||||||
container, th);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Auto-Create a _NewEnum enumerator from an STL container, specifying
|
|
||||||
* a converter.
|
|
||||||
* \param container STL Container.
|
|
||||||
* \param th Outer or \e this pointer.
|
|
||||||
* \param converter Converter type (convert Container element to
|
|
||||||
* iterator interface element types).
|
|
||||||
*/
|
|
||||||
template<typename C, typename TH, typename CONVERTER>
|
|
||||||
static com_ptr<ET> create(
|
|
||||||
const C& container, TH* th, const CONVERTER& converter)
|
|
||||||
{
|
|
||||||
typedef typename enumerated_type_of<ET>::is T;
|
|
||||||
return new stl_enumeration_t<ET, C, T, CONVERTER, TH>(
|
|
||||||
container, th, converter);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/*! Creates IEnumVARIANT enumeration of a STL container.
|
|
||||||
* \param container STL Container.
|
|
||||||
* \param th Outer or \e this pointer.
|
|
||||||
\code
|
|
||||||
com_ptr<IEnumVARIANT> get__NewEnum() {
|
|
||||||
return create_enum( collection_, this );
|
|
||||||
}
|
|
||||||
\endcode
|
|
||||||
* \relates stl_enumeration
|
|
||||||
*/
|
|
||||||
template<typename C, typename TH>
|
|
||||||
com_ptr<IEnumVARIANT> create_enum(const C& container, TH* th = 0)
|
|
||||||
{
|
|
||||||
return stl_enumeration<IEnumVARIANT>::create(container, th);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Creates IEnumVARIANT enumeration of a STL container with a converter.
|
|
||||||
/*! \param container STL Container.
|
|
||||||
* \param th Outer or \e this pointer.
|
|
||||||
* \param converter Converter type (convert Container element to VARIANT)
|
|
||||||
* \sa ptr_converter ptr_converter_select1st ptr_converter_select2nd
|
|
||||||
* \relates stl_enumeration
|
|
||||||
*/
|
|
||||||
template<typename C, typename TH, typename CONVERTER>
|
|
||||||
com_ptr<IEnumVARIANT> create_enum(const C& container, TH* th, CONVERTER converter)
|
|
||||||
{
|
|
||||||
return stl_enumeration<IEnumVARIANT>::create(container, th, converter);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,228 +0,0 @@
|
||||||
/** \file
|
|
||||||
* Threading support.
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* Copyright © 2001-2002 Sofus Mortensen, Mikael Lindgren
|
|
||||||
*
|
|
||||||
* This material is provided "as is", with absolutely no warranty
|
|
||||||
* expressed or implied. Any use is at your own risk. Permission to
|
|
||||||
* use or copy this software for any purpose is hereby granted without
|
|
||||||
* fee, provided the above notices are retained on all copies.
|
|
||||||
* Permission to modify the code and to distribute modified code is
|
|
||||||
* granted, provided the above notices are retained, and a notice that
|
|
||||||
* the code was modified is included with the above copyright notice.
|
|
||||||
*
|
|
||||||
* This header is part of Comet version 2.
|
|
||||||
* https://github.com/alamaison/comet
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef COMET_THREADING_H
|
|
||||||
#define COMET_THREADING_H
|
|
||||||
|
|
||||||
#include <comet/config.h>
|
|
||||||
#include <comet/handle.h>
|
|
||||||
|
|
||||||
#include <comet/error.h>
|
|
||||||
|
|
||||||
namespace comet {
|
|
||||||
|
|
||||||
/** \class critical_section threading.h comet/threading.h
|
|
||||||
* wrapper for Win32 CRITICAL_SECTION.
|
|
||||||
*/
|
|
||||||
class critical_section {
|
|
||||||
public:
|
|
||||||
critical_section() {
|
|
||||||
::InitializeCriticalSection(&cs_);
|
|
||||||
}
|
|
||||||
|
|
||||||
~critical_section() {
|
|
||||||
::DeleteCriticalSection(&cs_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void enter() const {
|
|
||||||
::EnterCriticalSection(&cs_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void leave() const {
|
|
||||||
::LeaveCriticalSection(&cs_);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
critical_section(const critical_section&);
|
|
||||||
critical_section& operator=(const critical_section&);
|
|
||||||
|
|
||||||
mutable CRITICAL_SECTION cs_;
|
|
||||||
};
|
|
||||||
|
|
||||||
/** \class auto_cs threading.h comet/threading.h
|
|
||||||
* Stack based critical-section resource obtaining and releasing.
|
|
||||||
*/
|
|
||||||
class auto_cs {
|
|
||||||
public:
|
|
||||||
explicit auto_cs(const critical_section& cs) : cs_(cs) {
|
|
||||||
cs_.enter();
|
|
||||||
}
|
|
||||||
|
|
||||||
~auto_cs() {
|
|
||||||
cs_.leave();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
auto_cs& operator=(const auto_cs&);
|
|
||||||
auto_cs(const auto_cs&);
|
|
||||||
|
|
||||||
const critical_section& cs_;
|
|
||||||
};
|
|
||||||
|
|
||||||
/** \class locking_ptr threading.h comet/threading.h
|
|
||||||
Locking pointer.
|
|
||||||
Based on an article on the volatile keyword by Andrei Alexandrescu
|
|
||||||
See <a href=:http://www.cuj.com/experts/1902/alexandr.htm?topic=experts"> article</a>.
|
|
||||||
*/
|
|
||||||
template <typename T> class locking_ptr {
|
|
||||||
public:
|
|
||||||
locking_ptr(volatile T& obj, critical_section& cs) :
|
|
||||||
pointer_(const_cast<T*>(&obj)),
|
|
||||||
cs_(cs)
|
|
||||||
{
|
|
||||||
cs_.enter();
|
|
||||||
}
|
|
||||||
|
|
||||||
~locking_ptr()
|
|
||||||
{
|
|
||||||
cs_.leave();
|
|
||||||
}
|
|
||||||
|
|
||||||
T& operator*()
|
|
||||||
{
|
|
||||||
return *pointer_;
|
|
||||||
}
|
|
||||||
|
|
||||||
T* operator->()
|
|
||||||
{
|
|
||||||
return pointer_;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
T* pointer_;
|
|
||||||
critical_section& cs_;
|
|
||||||
|
|
||||||
locking_ptr(const locking_ptr&);
|
|
||||||
locking_ptr& operator=(const locking_ptr&);
|
|
||||||
};
|
|
||||||
|
|
||||||
class thread
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
DWORD id_;
|
|
||||||
auto_handle handle_;
|
|
||||||
|
|
||||||
// declare non-copyable
|
|
||||||
thread(thread const& );
|
|
||||||
thread& operator=(thread const& );
|
|
||||||
public:
|
|
||||||
thread() : id_(0)
|
|
||||||
{}
|
|
||||||
|
|
||||||
const auto_handle& start()
|
|
||||||
{
|
|
||||||
handle_ = auto_attach(::CreateThread(0, 0, &thread::start_proc, this, 0, &id_));
|
|
||||||
return handle_;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto_handle& handle() const
|
|
||||||
{
|
|
||||||
return handle_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void exit(DWORD exit_code)
|
|
||||||
{
|
|
||||||
::ExitThread(exit_code);
|
|
||||||
}
|
|
||||||
|
|
||||||
void suspend()
|
|
||||||
{
|
|
||||||
::SuspendThread(handle_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void resume()
|
|
||||||
{
|
|
||||||
::ResumeThread(handle_);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool running()
|
|
||||||
{
|
|
||||||
DWORD code;
|
|
||||||
return handle_ &&
|
|
||||||
::GetExitCodeThread(handle_, &code) &&
|
|
||||||
code == STILL_ACTIVE;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool wait(DWORD timeout = INFINITE)
|
|
||||||
{
|
|
||||||
return ::WaitForSingleObject(handle_, timeout) == WAIT_OBJECT_0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
static DWORD _stdcall start_proc(void* param)
|
|
||||||
{
|
|
||||||
return static_cast<thread*>(param)->thread_main();
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual DWORD thread_main() = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
class event
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
auto_handle handle_;
|
|
||||||
|
|
||||||
// declare non-copyable
|
|
||||||
event(event const& );
|
|
||||||
event& operator=(event const& );
|
|
||||||
public:
|
|
||||||
explicit event(bool initial_state = false)
|
|
||||||
{
|
|
||||||
handle_ = auto_attach(::CreateEvent(0, false, initial_state, 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit event(const TCHAR* name, bool initial_state = false)
|
|
||||||
{
|
|
||||||
handle_ = auto_attach(::CreateEvent(0, false, initial_state, name));
|
|
||||||
}
|
|
||||||
|
|
||||||
void set()
|
|
||||||
{
|
|
||||||
if (0 == ::SetEvent(handle_))
|
|
||||||
{
|
|
||||||
DWORD err = GetLastError();
|
|
||||||
raise_exception(HRESULT_FROM_WIN32(err));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void reset()
|
|
||||||
{
|
|
||||||
if (0==::ResetEvent(handle_) )
|
|
||||||
{
|
|
||||||
DWORD err = GetLastError();
|
|
||||||
raise_exception(HRESULT_FROM_WIN32(err));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool wait(DWORD timeout = INFINITE)
|
|
||||||
{
|
|
||||||
return ::WaitForSingleObject(handle_, timeout) == WAIT_OBJECT_0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool is_set()
|
|
||||||
{
|
|
||||||
return ::WaitForSingleObject(handle_, 0) == WAIT_OBJECT_0;
|
|
||||||
}
|
|
||||||
|
|
||||||
operator HANDLE() const
|
|
||||||
{ return handle_; }
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,451 +0,0 @@
|
||||||
/** \file
|
|
||||||
* Wrappers for ITypeLibInfo.
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* Copyright © 2002 Michael Geddes.
|
|
||||||
*
|
|
||||||
* This material is provided "as is", with absolutely no warranty
|
|
||||||
* expressed or implied. Any use is at your own risk. Permission to
|
|
||||||
* use or copy this software for any purpose is hereby granted without
|
|
||||||
* fee, provided the above notices are retained on all copies.
|
|
||||||
* Permission to modify the code and to distribute modified code is
|
|
||||||
* granted, provided the above notices are retained, and a notice that
|
|
||||||
* the code was modified is included with the above copyright notice.
|
|
||||||
*
|
|
||||||
* This header is part of Comet version 2.
|
|
||||||
* https://github.com/alamaison/comet
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef COMET_TLIBINFO_H
|
|
||||||
#define COMET_TLIBINFO_H
|
|
||||||
|
|
||||||
#ifdef _SHOW_INC
|
|
||||||
#pragma message(" #Include " __FILE__)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <oaidl.h>
|
|
||||||
#include <comet/ptr.h>
|
|
||||||
#include <comet/uuid.h>
|
|
||||||
|
|
||||||
namespace comet
|
|
||||||
{
|
|
||||||
template<> struct comtype<ITypeLib>
|
|
||||||
{
|
|
||||||
static const IID& uuid() throw() { return IID_IPictureDisp; }
|
|
||||||
typedef ::IUnknown base;
|
|
||||||
};
|
|
||||||
template<> struct comtype<ITypeInfo>
|
|
||||||
{
|
|
||||||
static const IID& uuid() throw() { return IID_ITypeInfo; }
|
|
||||||
typedef ::IUnknown base;
|
|
||||||
};
|
|
||||||
template<> struct comtype<ITypeInfo2>
|
|
||||||
{
|
|
||||||
static const IID& uuid() throw() { return IID_ITypeInfo2; }
|
|
||||||
typedef ::ITypeInfo base;
|
|
||||||
};
|
|
||||||
/*! \addtogroup Interfaces
|
|
||||||
*/
|
|
||||||
//@{
|
|
||||||
namespace impl
|
|
||||||
{
|
|
||||||
/// A class to handle the auto-releaseing of structs returned by by the Typeinfo interfaces.
|
|
||||||
template< typename B, typename T>
|
|
||||||
struct tlib_info
|
|
||||||
{
|
|
||||||
typedef void (__stdcall B::*RelFunc)(T*);
|
|
||||||
template< RelFunc RELEASE>
|
|
||||||
struct typeinfo_attr_base
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typeinfo_attr_base() : info_(NULL), attrib_(NULL), rc_(NULL) {}
|
|
||||||
typeinfo_attr_base( const com_ptr<B> &info, T *attrib ) : info_(info),attrib_(attrib),rc_(NULL)
|
|
||||||
{
|
|
||||||
if (attrib != NULL)
|
|
||||||
{
|
|
||||||
rc_ = new long;
|
|
||||||
(*rc_)=1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
typeinfo_attr_base( const typeinfo_attr_base &base)
|
|
||||||
: info_(base.info_), attrib_(base.attrib_), rc_(base.rc_)
|
|
||||||
{
|
|
||||||
++*rc_;
|
|
||||||
}
|
|
||||||
~typeinfo_attr_base()
|
|
||||||
{
|
|
||||||
release();
|
|
||||||
}
|
|
||||||
typeinfo_attr_base &operator =( const typeinfo_attr_base &base)
|
|
||||||
{
|
|
||||||
release();
|
|
||||||
info_= base.info_;
|
|
||||||
attrib_= base.attrib_;
|
|
||||||
rc_ = base.rc_;
|
|
||||||
++*rc_;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
void release()
|
|
||||||
{
|
|
||||||
if(attrib_ != NULL && rc_ != NULL )
|
|
||||||
{
|
|
||||||
if (0 == --*rc_)
|
|
||||||
{
|
|
||||||
(info_.raw()->*RELEASE)( attrib_);
|
|
||||||
delete rc_;
|
|
||||||
}
|
|
||||||
rc_ = NULL;
|
|
||||||
attrib_ = NULL;
|
|
||||||
info_ = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
T *operator->() const
|
|
||||||
{
|
|
||||||
if( attrib_ ==NULL ) throw com_error(E_POINTER);
|
|
||||||
return attrib_;
|
|
||||||
}
|
|
||||||
bool is_null() const { return attrib_ == NULL; }
|
|
||||||
protected:
|
|
||||||
long *rc_;
|
|
||||||
T *attrib_;
|
|
||||||
com_ptr<B> info_;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Auto-release wrapper for TYPEATTR.
|
|
||||||
typedef impl::tlib_info<ITypeInfo, TYPEATTR>::typeinfo_attr_base< &ITypeInfo::ReleaseTypeAttr > type_attr_t;
|
|
||||||
/// Auto-release wrapper for FUNCDESC.
|
|
||||||
typedef impl::tlib_info<ITypeInfo, FUNCDESC>::typeinfo_attr_base< &ITypeInfo::ReleaseFuncDesc > func_desc_t;
|
|
||||||
/// Auto-release wrapper for VARDESC.
|
|
||||||
typedef impl::tlib_info<ITypeInfo, VARDESC>::typeinfo_attr_base< &ITypeInfo::ReleaseVarDesc > var_desc_t;
|
|
||||||
|
|
||||||
/// Auto-release wrapper for TLIBATTR.
|
|
||||||
typedef impl::tlib_info<ITypeLib, TLIBATTR>::typeinfo_attr_base< &ITypeLib::ReleaseTLibAttr > tlibattr_t;
|
|
||||||
|
|
||||||
|
|
||||||
/** Flags for GetImplTypeFlags.
|
|
||||||
* \sa IMPLTYPEFLAGS
|
|
||||||
*/
|
|
||||||
enum impl_type_flag
|
|
||||||
{
|
|
||||||
eft_default=0x1, ///< The interface or dispinterface represents the default for the source or sink.
|
|
||||||
eft_source =0x2, ///< This member of a coclass is called rather than implemented.
|
|
||||||
eft_restricted=0x4, ///< The member should not be displayed or programmable by users.
|
|
||||||
eft_defaultvtable=0x8 ///< Sinks receive events through the VTBL.
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Specialisation wrapper for ITypeInfo.
|
|
||||||
* \struct wrap_t<ITypeInfo> tlbinfo.h comet/tlbinfo.h
|
|
||||||
* Wrapper for ITypeInfo typelib information.
|
|
||||||
* \sa ITypeInfo
|
|
||||||
*/
|
|
||||||
template<>
|
|
||||||
struct wrap_t<ITypeInfo>
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
inline ITypeInfo *raw_(){ return reinterpret_cast<ITypeInfo *>(this); }
|
|
||||||
public:
|
|
||||||
|
|
||||||
/** Returns a wrapped Type Attributes struct.
|
|
||||||
* \sa TYPEATTR
|
|
||||||
*/
|
|
||||||
type_attr_t GetTypeAttr()
|
|
||||||
{
|
|
||||||
TYPEATTR *pTypeAttr;
|
|
||||||
raw_()->GetTypeAttr( &pTypeAttr) | raise_exception ;
|
|
||||||
return type_attr_t( raw_(), pTypeAttr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns an ITypeComp interface.
|
|
||||||
com_ptr<ITypeComp> GetTypeComp()
|
|
||||||
{
|
|
||||||
com_ptr<ITypeComp> ppTComp;
|
|
||||||
raw_()->GetTypeComp( ppTComp.out()) | raise_exception;
|
|
||||||
return ppTComp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Get the function description struct.
|
|
||||||
* \sa FUNCDESC
|
|
||||||
*/
|
|
||||||
func_desc_t GetFuncDesc( unsigned int index)
|
|
||||||
{
|
|
||||||
FUNCDESC *pFuncDesc ;
|
|
||||||
raw_()->GetFuncDesc(index, &pFuncDesc) | raise_exception ;
|
|
||||||
return func_desc_t( raw_(), pFuncDesc);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Get the Variable/Constant/Datamember description.
|
|
||||||
* \sa VARDESC
|
|
||||||
*/
|
|
||||||
var_desc_t GetVarDesc( unsigned int index )
|
|
||||||
{
|
|
||||||
VARDESC *pVarDesc;
|
|
||||||
raw_()->GetVarDesc( index,&pVarDesc) | raise_exception;
|
|
||||||
return var_desc_t(raw_(), pVarDesc);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef NOT_YET
|
|
||||||
std::list<std::string> GetNames( MEMBERID memid )
|
|
||||||
{
|
|
||||||
/* [local] */ HRESULT GetNames( /* [in] */ MEMBERID memid, /* [length_is][size_is][out] */ BSTR *rgBstrNames,
|
|
||||||
/* [in] */ UINT cMaxNames, /* [out] */ UINT *pcNames) ;
|
|
||||||
}
|
|
||||||
#endif //
|
|
||||||
|
|
||||||
/// Retrieves the type description of implemented interface types.
|
|
||||||
HREFTYPE GetRefTypeOfImplType( unsigned int index)
|
|
||||||
{
|
|
||||||
HREFTYPE reftype;
|
|
||||||
raw_()->GetRefTypeOfImplType(index, &reftype) | raise_exception;
|
|
||||||
return reftype;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieves the type description of implemented interface types.
|
|
||||||
long GetImplTypeFlags( int index)
|
|
||||||
{
|
|
||||||
INT implTypeFlags;
|
|
||||||
raw_()->GetImplTypeFlags( index, &implTypeFlags) |raise_exception;
|
|
||||||
return implTypeFlags;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef NOT_YET
|
|
||||||
std::vector<MEMBERID> GetIDsOfNames( const std::vector<bstr_t> &rgsNames);
|
|
||||||
{
|
|
||||||
/* [local] */ HRESULT GetIDsOfNames(
|
|
||||||
/* [size_is][in] */ LPOLESTR *rgszNames,
|
|
||||||
/* [in] */ UINT cNames,
|
|
||||||
/* [size_is][out] */ MEMBERID *pMemId) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* [local] */ HRESULT Invoke(
|
|
||||||
/* [in] */ PVOID pvInstance,
|
|
||||||
/* [in] */ MEMBERID memid,
|
|
||||||
/* [in] */ WORD wFlags,
|
|
||||||
/* [out][in] */ DISPPARAMS *pDispParams,
|
|
||||||
/* [out] */ VARIANT *pVarResult,
|
|
||||||
/* [out] */ EXCEPINFO *pExcepInfo,
|
|
||||||
/* [out] */ UINT *puArgErr) ;
|
|
||||||
#endif // NOT_YET
|
|
||||||
/// Raw wrapper to make sure comet still works/compiles.
|
|
||||||
HRESULT GetIDsOfNames( LPOLESTR *rgszNames, UINT cNames,
|
|
||||||
MEMBERID *pMemId)
|
|
||||||
{
|
|
||||||
return raw_()->GetIDsOfNames( rgszNames, cNames, pMemId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Raw wrapper to make sure comet still works/compiles.
|
|
||||||
HRESULT Invoke( PVOID pvInstance, MEMBERID memid, WORD wFlags,
|
|
||||||
DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo,
|
|
||||||
UINT *puArgErr)
|
|
||||||
{
|
|
||||||
return raw_()->Invoke( pvInstance, memid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GetIDOfName( const wchar_t *name, MEMBERID *id)
|
|
||||||
{
|
|
||||||
wchar_t *ucname = const_cast<wchar_t *>(name);
|
|
||||||
return SUCCEEDED(raw_()->GetIDsOfNames( &ucname, 1, id));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// Get the documentation for the specified MEMBERID.
|
|
||||||
void GetDocumentation(MEMBERID memid, bstr_t *name, bstr_t *docString, DWORD *helpcontext, bstr_t *helpfile)
|
|
||||||
{
|
|
||||||
raw_()->GetDocumentation(memid, name?name->out():NULL, docString?docString->out():NULL,
|
|
||||||
helpcontext, helpfile? helpfile->out():NULL) | raise_exception;
|
|
||||||
}
|
|
||||||
/** Get the member name for the specified MEMBERID.
|
|
||||||
* This is a shortcut for GetDocumentation.
|
|
||||||
*/
|
|
||||||
|
|
||||||
bstr_t GetMemberName(MEMBERID memid)
|
|
||||||
{
|
|
||||||
bstr_t name;
|
|
||||||
raw_()->GetDocumentation(memid, name.out(), NULL, NULL, NULL) | raise_exception;
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
bstr_t GetName()
|
|
||||||
{
|
|
||||||
return GetMemberName(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if NOT_YET
|
|
||||||
/* [local] */ HRESULT GetDllEntry(
|
|
||||||
/* [in] */ MEMBERID memid,
|
|
||||||
/* [in] */ INVOKEKIND invKind,
|
|
||||||
/* [out] */ BSTR *pBstrDllName,
|
|
||||||
/* [out] */ BSTR *pBstrName,
|
|
||||||
/* [out] */ WORD *pwOrdinal) ;
|
|
||||||
#endif // NOT_YET
|
|
||||||
|
|
||||||
/** Get the referenced Type information.
|
|
||||||
*/
|
|
||||||
com_ptr<ITypeInfo> GetRefTypeInfo( HREFTYPE refType)
|
|
||||||
{
|
|
||||||
com_ptr<ITypeInfo> refinfo;
|
|
||||||
raw_()->GetRefTypeInfo( refType, refinfo.out()) | raise_exception;
|
|
||||||
return refinfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if NOT_YET
|
|
||||||
/* [local] */ HRESULT AddressOfMember( /* [in] */ MEMBERID memid, /* [in] */ INVOKEKIND invKind,
|
|
||||||
/* [out] */ PVOID *ppv) ;
|
|
||||||
|
|
||||||
/* [local] */ HRESULT CreateInstance( /* [in] */ IUnknown *pUnkOuter, /* [in] */ REFIID riid,
|
|
||||||
/* [iid_is][out] */ PVOID *ppvObj) ;
|
|
||||||
|
|
||||||
HRESULT GetMops( /* [in] */ MEMBERID memid, /* [out] */ BSTR *pBstrMops) ;
|
|
||||||
#endif // NOT_YET
|
|
||||||
|
|
||||||
/** Get the typelib containing this definition.
|
|
||||||
* \return A pair containing the typelibrary and the index of the type description within the type library.
|
|
||||||
*/
|
|
||||||
std::pair< com_ptr<ITypeLib>, UINT > GetContainingTypeLib()
|
|
||||||
{
|
|
||||||
std::pair< com_ptr<ITypeLib>, UINT> result;
|
|
||||||
raw_()->GetContainingTypeLib( result.first.out(), &(result.second) ) | raise_exception;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
//@}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct wrap_t<ITypeInfo2> : wrap_t<ITypeInfo>
|
|
||||||
{
|
|
||||||
TYPEKIND GetTypeKind()
|
|
||||||
{
|
|
||||||
TYPEKIND tkind;
|
|
||||||
raw_()->GetTypeKind(&tkind) | raise_exception;
|
|
||||||
return tkind;
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
inline ITypeInfo2 *raw_(){ return reinterpret_cast<ITypeInfo2 *>(this); }
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/*! \addtogroup Interfaces
|
|
||||||
*/
|
|
||||||
//@{
|
|
||||||
|
|
||||||
/// Specialisation to handle TypeLibrary API.
|
|
||||||
template<>
|
|
||||||
struct wrap_t<ITypeLib>
|
|
||||||
{
|
|
||||||
inline ITypeLib *raw_(){ return reinterpret_cast<ITypeLib *>(this); }
|
|
||||||
unsigned int GetTypeInfoCount()
|
|
||||||
{
|
|
||||||
return raw_()->GetTypeInfoCount();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get typeinfo at specified index.
|
|
||||||
com_ptr<ITypeInfo> GetTypeInfo( UINT index)
|
|
||||||
{
|
|
||||||
com_ptr<ITypeInfo> tinfo;
|
|
||||||
raw_()->GetTypeInfo( index, tinfo.out()) | raise_exception;
|
|
||||||
return tinfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get type of information at specified index.
|
|
||||||
TYPEKIND GetTypeInfoType( UINT index)
|
|
||||||
{
|
|
||||||
TYPEKIND retval;
|
|
||||||
raw_()->GetTypeInfoType( index, &retval) | raise_exception;
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get typeinfo given GUID.
|
|
||||||
com_ptr<ITypeInfo> GetTypeInfoOfGuid( const uuid_t &guid )
|
|
||||||
{
|
|
||||||
com_ptr<ITypeInfo> tinfo;
|
|
||||||
raw_()->GetTypeInfoOfGuid( guid, tinfo.out()) | raise_exception;
|
|
||||||
return tinfo;
|
|
||||||
}
|
|
||||||
/// Get Raw Typeinfo of guid.
|
|
||||||
HRESULT GetTypeInfoOfGuid( REFGUID guid, ITypeInfo **ppTinfo)
|
|
||||||
{
|
|
||||||
return raw_()->GetTypeInfoOfGuid( guid,ppTinfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get attributes of the typelibrary.
|
|
||||||
tlibattr_t GetLibAttr()
|
|
||||||
{
|
|
||||||
TLIBATTR *attr;
|
|
||||||
raw_()->GetLibAttr( &attr) | raise_exception;
|
|
||||||
return tlibattr_t( raw_(), attr);
|
|
||||||
}
|
|
||||||
|
|
||||||
com_ptr<ITypeComp> GetTypeComp()
|
|
||||||
{
|
|
||||||
com_ptr<ITypeComp> typecomp;
|
|
||||||
raw_()->GetTypeComp( typecomp.out() ) | raise_exception;
|
|
||||||
return typecomp;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GetDocumentation(int index, bstr_t *name, bstr_t *docString, DWORD *helpcontext, bstr_t *helpfile)
|
|
||||||
{
|
|
||||||
raw_()->GetDocumentation(index, name?name->out():NULL, docString?docString->out():NULL,
|
|
||||||
helpcontext, helpfile? helpfile->out():NULL) | raise_exception;
|
|
||||||
}
|
|
||||||
bstr_t GetItemName(int index)
|
|
||||||
{
|
|
||||||
bstr_t name;
|
|
||||||
raw_()->GetDocumentation(index, name.out(), NULL, NULL, NULL) | raise_exception;
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
bstr_t GetName()
|
|
||||||
{
|
|
||||||
return GetItemName(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsName( const bstr_t &name, unsigned long hashval )
|
|
||||||
{
|
|
||||||
BOOL ret;
|
|
||||||
raw_()->IsName( name.in(), hashval, &ret) | raise_exception;
|
|
||||||
return ret!=0;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::pair<com_ptr<ITypeInfo>, MEMBERID> FindName( const bstr_t &name)
|
|
||||||
{
|
|
||||||
std::pair<com_ptr<ITypeInfo>, MEMBERID> result;
|
|
||||||
USHORT tofind = 1;
|
|
||||||
raw_()->FindName(name.in(), 0, result.first.out(), &result.second, &tofind) | raise_exception;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
#ifdef NOT_YET
|
|
||||||
std::list<std::pair<com_ptr<ITypeInfo>, MEMBERID> >FindName( const bstr_t &name, int max)
|
|
||||||
{}
|
|
||||||
[local]
|
|
||||||
HRESULT FindName(
|
|
||||||
[in, out] LPOLESTR szNameBuf,
|
|
||||||
[in] ULONG lHashVal,
|
|
||||||
[out,size_is(*pcFound),length_is(*pcFound)] ITypeInfo **ppTInfo,
|
|
||||||
[out,size_is(*pcFound),length_is(*pcFound)] MEMBERID * rgMemId,
|
|
||||||
[in, out] USHORT * pcFound
|
|
||||||
);
|
|
||||||
#endif // LATER
|
|
||||||
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Load typeinfo from a file.
|
|
||||||
namespace typeinfo
|
|
||||||
{
|
|
||||||
/** Whether to register the typelibrary on load.
|
|
||||||
* \relates typeinfo::LoadTypeLib
|
|
||||||
*/
|
|
||||||
enum regkind_t { reg_default = REGKIND_DEFAULT, reg_register = REGKIND_REGISTER, reg_none = REGKIND_NONE } ;
|
|
||||||
/// Load typeinfo from a file.
|
|
||||||
static inline com_ptr<ITypeLib> LoadTypeLib( const bstr_t &filename, regkind_t regkind= reg_default)
|
|
||||||
{
|
|
||||||
com_ptr<ITypeLib> tlib;
|
|
||||||
LoadTypeLibEx(filename.in(), (REGKIND)(regkind), tlib.out()) | raise_exception;
|
|
||||||
return tlib;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//@}
|
|
||||||
} // namespace comet
|
|
||||||
#endif /* COMET_TLIBINFO_H */
|
|
|
@ -1,125 +0,0 @@
|
||||||
/** \file
|
|
||||||
* C++ Std. lib TCHAR mappings.
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* Copyright © 2002 Sofus Mortensen
|
|
||||||
*
|
|
||||||
* This material is provided "as is", with absolutely no warranty
|
|
||||||
* expressed or implied. Any use is at your own risk. Permission to
|
|
||||||
* use or copy this software for any purpose is hereby granted without
|
|
||||||
* fee, provided the above notices are retained on all copies.
|
|
||||||
* Permission to modify the code and to distribute modified code is
|
|
||||||
* granted, provided the above notices are retained, and a notice that
|
|
||||||
* the code was modified is included with the above copyright notice.
|
|
||||||
*
|
|
||||||
* This header is part of Comet version 2.
|
|
||||||
* https://github.com/alamaison/comet
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef COMET_TSTRING_H
|
|
||||||
#define COMET_TSTRING_H
|
|
||||||
|
|
||||||
#include <tchar.h>
|
|
||||||
#include <strsafe.h>
|
|
||||||
#include <string>
|
|
||||||
#include <iosfwd>
|
|
||||||
|
|
||||||
namespace comet {
|
|
||||||
|
|
||||||
/*! \addtogroup WinUtil
|
|
||||||
*/
|
|
||||||
//@{
|
|
||||||
|
|
||||||
#if defined(_MBCS) && !defined(_UNICODE) && !defined(COMET_NO_MBCS_WARNING)
|
|
||||||
#pragma message( "Warning: _MBCS is defined. Be aware that tstring does not support multi-byte character strings" )
|
|
||||||
#endif
|
|
||||||
/** \page comettstring Comet tstring type.
|
|
||||||
* In order for comet projects to more easily support unicode via the
|
|
||||||
* windows file "tchar.h", many comet classes support the type #comet::tstring which is
|
|
||||||
* a convenience typedef to basic_string. Associated with
|
|
||||||
* \link comet::tstring tstring \endlink are all or most of the other STL
|
|
||||||
* classes that have a \p char argument to the templates.
|
|
||||||
*
|
|
||||||
* In addition to being used by comet, this is a generally useful series
|
|
||||||
* of typedefs to be used when combining STL types with tchar.h compatible
|
|
||||||
* projects.
|
|
||||||
*
|
|
||||||
* There are two area to be particularly wary of with STL and tchar.h.
|
|
||||||
*
|
|
||||||
* The first is that the filename argument for file streams are always
|
|
||||||
* narrow char *. I would suggest using a #comet::bstr_t which will
|
|
||||||
* convert for you, especially in UNICODE (actually UCS2 little-endien) projects.
|
|
||||||
*
|
|
||||||
* The second is that tstring support for multi-byte character strings is
|
|
||||||
* very minimal. Embedded NULLs in the stream are not a problem for
|
|
||||||
* copying around, however none of the parsing/searching/comparison
|
|
||||||
* methods cope with multi-byte character sets.
|
|
||||||
*
|
|
||||||
* I believe that part of the reason for this is the platform specific
|
|
||||||
* nature of multi-byte, and the internal support for a variety of
|
|
||||||
* different MBCS implementations by Microsoft.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** TCHAR version of std::basic_string.
|
|
||||||
* See \ref comettstring
|
|
||||||
*/
|
|
||||||
typedef std::basic_string< TCHAR > tstring;
|
|
||||||
|
|
||||||
/** TCHAR version of std::basic_ios.
|
|
||||||
* \relates tstring
|
|
||||||
*/
|
|
||||||
typedef std::basic_ios<TCHAR, std::char_traits<TCHAR> > tios;
|
|
||||||
/** TCHAR version of std::basic_streambuf.
|
|
||||||
* \relates tstring
|
|
||||||
*/
|
|
||||||
typedef std::basic_streambuf<TCHAR, std::char_traits<TCHAR> > tstreambuf;
|
|
||||||
/** TCHAR version of std::basic_istream.
|
|
||||||
* \relates tstring
|
|
||||||
*/
|
|
||||||
typedef std::basic_istream<TCHAR, std::char_traits<TCHAR> > tistream;
|
|
||||||
/** TCHAR version of std::basic_ostream.
|
|
||||||
* \relates tstring
|
|
||||||
*/
|
|
||||||
typedef std::basic_ostream<TCHAR, std::char_traits<TCHAR> > tostream;
|
|
||||||
/** TCHAR version of std::basic_iostream.
|
|
||||||
* \relates tstring
|
|
||||||
*/
|
|
||||||
typedef std::basic_iostream<TCHAR, std::char_traits<TCHAR> > tiostream;
|
|
||||||
/** TCHAR version of std::basic_stringbuf.
|
|
||||||
* \relates tstring
|
|
||||||
*/
|
|
||||||
typedef std::basic_stringbuf<TCHAR, std::char_traits<TCHAR>, std::allocator<TCHAR> > tstringbuf;
|
|
||||||
/** TCHAR version of std::basic_istringstream.
|
|
||||||
* \relates tstring
|
|
||||||
*/
|
|
||||||
typedef std::basic_istringstream<TCHAR, std::char_traits<TCHAR>, std::allocator<TCHAR> > tistringstream;
|
|
||||||
/** TCHAR version of std::basic_ostringstream.
|
|
||||||
* \relates tstring
|
|
||||||
*/
|
|
||||||
typedef std::basic_ostringstream<TCHAR, std::char_traits<TCHAR>, std::allocator<TCHAR> > tostringstream;
|
|
||||||
/** TCHAR version of std::basic_stringstream.
|
|
||||||
* \relates tstring
|
|
||||||
*/
|
|
||||||
typedef std::basic_stringstream<TCHAR, std::char_traits<TCHAR>, std::allocator<TCHAR> > tstringstream;
|
|
||||||
/** TCHAR version of std::basic_filebuf.
|
|
||||||
* \relates tstring
|
|
||||||
*/
|
|
||||||
typedef std::basic_filebuf<TCHAR, std::char_traits<TCHAR> > tfilebuf;
|
|
||||||
/** TCHAR version of std::basic_ifstream.
|
|
||||||
* \relates tstring
|
|
||||||
*/
|
|
||||||
typedef std::basic_ifstream<TCHAR, std::char_traits<TCHAR> > tifstream;
|
|
||||||
/** TCHAR version of std::basic_ofstream.
|
|
||||||
* \relates tstring
|
|
||||||
*/
|
|
||||||
typedef std::basic_ofstream<TCHAR, std::char_traits<TCHAR> > tofstream;
|
|
||||||
/** TCHAR version of std::basic_fstream.
|
|
||||||
* \relates tstring
|
|
||||||
*/
|
|
||||||
typedef std::basic_fstream<TCHAR, std::char_traits<TCHAR> > tfstream;
|
|
||||||
|
|
||||||
//@}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,262 +0,0 @@
|
||||||
/** \file
|
|
||||||
* Interrogate traits of template types.
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* Copyright © 2000, 2001 Sofus Mortensen, Paul Hollingsworth
|
|
||||||
*
|
|
||||||
* This material is provided "as is", with absolutely no warranty
|
|
||||||
* expressed or implied. Any use is at your own risk. Permission to
|
|
||||||
* use or copy this software for any purpose is hereby granted without
|
|
||||||
* fee, provided the above notices are retained on all copies.
|
|
||||||
* Permission to modify the code and to distribute modified code is
|
|
||||||
* granted, provided the above notices are retained, and a notice that
|
|
||||||
* the code was modified is included with the above copyright notice.
|
|
||||||
*
|
|
||||||
* This header is part of Comet version 2.
|
|
||||||
* https://github.com/alamaison/comet
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Partial copyright for is_const, is_volatile and is_reference.
|
|
||||||
*
|
|
||||||
* (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
|
|
||||||
* Permission to copy, use, modify, sell and
|
|
||||||
* distribute this software is granted provided this copyright notice appears
|
|
||||||
* in all copies. This software is provided "as is" without express or implied
|
|
||||||
* warranty, and with no claim as to its suitability for any purpose.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef COMET_TYPE_TRAITS_H
|
|
||||||
#define COMET_TYPE_TRAITS_H
|
|
||||||
|
|
||||||
namespace comet {
|
|
||||||
|
|
||||||
/** Provides structs to interrogate traits of template types.
|
|
||||||
*/
|
|
||||||
namespace type_traits {
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
// From www.boost.org
|
|
||||||
|
|
||||||
//* is a type T declared const - is_const<T>
|
|
||||||
namespace detail{
|
|
||||||
typedef char yes_result;
|
|
||||||
typedef char (&no_result)[8];
|
|
||||||
yes_result is_const_helper(const volatile void*);
|
|
||||||
no_result is_const_helper(volatile void *);
|
|
||||||
yes_result is_volatile_helper(const volatile void*);
|
|
||||||
no_result is_volatile_helper(const void *);
|
|
||||||
|
|
||||||
template <typename T> struct helper { T t; };
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T> struct is_const
|
|
||||||
{
|
|
||||||
enum{ result = (sizeof(detail::yes_result) == sizeof( detail::is_const_helper(
|
|
||||||
& ((reinterpret_cast<detail::helper<T> *>(0))->t))
|
|
||||||
))
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T> struct is_volatile
|
|
||||||
{
|
|
||||||
enum{ result = (sizeof(detail::yes_result) == sizeof(detail::is_volatile_helper(
|
|
||||||
& ((reinterpret_cast<detail::helper<T> *>(0))->t))
|
|
||||||
))
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# pragma warning(push)
|
|
||||||
# pragma warning(disable: 4181)
|
|
||||||
|
|
||||||
//* is a type T a reference type - is_reference<T>
|
|
||||||
template <typename T> struct is_reference
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
typedef T const volatile cv_t;
|
|
||||||
public:
|
|
||||||
enum // dwa 10/27/00 - VC6.4 seems to choke on short-circuit (&&,||)
|
|
||||||
{ // evaluations in constant expressions
|
|
||||||
value = !is_const<cv_t>::result | !is_volatile<cv_t>::result
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template <> struct is_reference<void>
|
|
||||||
{
|
|
||||||
enum{ value = false };
|
|
||||||
};
|
|
||||||
|
|
||||||
# pragma warning(pop)
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
template<typename T> struct is_integer { enum { result = false }; };
|
|
||||||
template<> struct is_integer<bool> { enum { result = true }; };
|
|
||||||
template<> struct is_integer<char> { enum { result = true }; };
|
|
||||||
template<> struct is_integer<signed char> { enum { result = true }; };
|
|
||||||
template<> struct is_integer<unsigned char> { enum { result = true }; };
|
|
||||||
// template<> struct is_integer<wchar_t> { enum { result = true }; };
|
|
||||||
template<> struct is_integer<short> { enum { result = true }; };
|
|
||||||
template<> struct is_integer<unsigned short> { enum { result = true }; };
|
|
||||||
template<> struct is_integer<int> { enum { result = true }; };
|
|
||||||
template<> struct is_integer<unsigned int> { enum { result = true }; };
|
|
||||||
template<> struct is_integer<long> { enum { result = true }; };
|
|
||||||
template<> struct is_integer<unsigned long> { enum { result = true }; };
|
|
||||||
|
|
||||||
//! @if Internal
|
|
||||||
/** Taken from STLPort.
|
|
||||||
* \internal
|
|
||||||
*/
|
|
||||||
struct _PointerShim {
|
|
||||||
// Since the compiler only allows at most one non-trivial
|
|
||||||
// implicit conversion we can make use of a shim class to
|
|
||||||
// be sure that IsPtr below doesn't accept classes with
|
|
||||||
// implicit pointer conversion operators
|
|
||||||
_PointerShim(const volatile void*); // no implementation
|
|
||||||
};
|
|
||||||
//! @endif
|
|
||||||
|
|
||||||
// These are the discriminating functions
|
|
||||||
static char __cdecl _IsP(bool, _PointerShim); // no implementation is required
|
|
||||||
static char* __cdecl _IsP(bool, ...); // no implementation is required
|
|
||||||
|
|
||||||
template <class _Tp>
|
|
||||||
struct is_pointer {
|
|
||||||
// This template meta function takes a type T
|
|
||||||
// and returns true exactly when T is a pointer.
|
|
||||||
// One can imagine meta-functions discriminating on
|
|
||||||
// other criteria.
|
|
||||||
static _Tp& __null_rep();
|
|
||||||
enum { result = (sizeof(_IsP(false,__null_rep())) == sizeof(char)) };
|
|
||||||
};
|
|
||||||
|
|
||||||
// Work out whether the Type is something we can use operator-> on
|
|
||||||
// (hopefully). If we fail, the worst we get is a level 3 warinng.
|
|
||||||
template <class _Tp>
|
|
||||||
struct is_class_pointer
|
|
||||||
{
|
|
||||||
enum { result = (is_pointer<_Tp>::result && ! is_integer<_Tp>::result) };
|
|
||||||
};
|
|
||||||
|
|
||||||
template<int x> struct int_holder
|
|
||||||
{
|
|
||||||
enum { result = x };
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T> struct type_holder
|
|
||||||
{
|
|
||||||
typedef T result;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* template<typename T, typename U> class is_static_compatible
|
|
||||||
{
|
|
||||||
class yes { };
|
|
||||||
class no {char a[10]; };
|
|
||||||
|
|
||||||
static yes test( U * );
|
|
||||||
static no test( ... );
|
|
||||||
|
|
||||||
public:
|
|
||||||
enum { is = sizeof(test(static_cast<T*>(0))) == sizeof(yes) ? true : false };
|
|
||||||
};*/
|
|
||||||
|
|
||||||
template<typename T, typename U> class is_cast_operator_compatible
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
class yes { };
|
|
||||||
class no {char a[10]; };
|
|
||||||
|
|
||||||
static yes test( U* );
|
|
||||||
static no test( ... );
|
|
||||||
|
|
||||||
public:
|
|
||||||
enum { is = sizeof(test(*static_cast<T*>(0))) == sizeof(yes) /*? 1 : 0 */};
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifndef COMET_PARTIAL_SPECIALISATION
|
|
||||||
template<typename T> struct conversion_aux
|
|
||||||
{
|
|
||||||
template<typename U> class X
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
class yes { };
|
|
||||||
class no {char a[10]; };
|
|
||||||
static T makeT();
|
|
||||||
|
|
||||||
static yes test(U);
|
|
||||||
static no test(...);
|
|
||||||
public:
|
|
||||||
enum { exists = sizeof(test(makeT())) == sizeof(yes) };
|
|
||||||
enum { same_type = false };
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template<> class X<T>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
enum { exists = true };
|
|
||||||
enum { same_type = true };
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
template<typename T, typename U> struct conversion
|
|
||||||
{
|
|
||||||
enum { exists = conversion_aux<T>::X<U>::exists };
|
|
||||||
enum { same_type = conversion_aux<T>::X<U>::same_type };
|
|
||||||
enum { exists_two_way = exists && conversion_aux<U>::X<T>::exists };
|
|
||||||
};
|
|
||||||
#else
|
|
||||||
template<typename T, typename U> struct conversion
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
class yes { };
|
|
||||||
class no {char a[10]; };
|
|
||||||
static T makeT();
|
|
||||||
|
|
||||||
static yes test(U);
|
|
||||||
static no test(...);
|
|
||||||
public:
|
|
||||||
enum { exists = sizeof(test(makeT())) == sizeof(yes) };
|
|
||||||
enum { same_type = false };
|
|
||||||
enum { exists_two_way = conversion<U,T>::exists};
|
|
||||||
|
|
||||||
};
|
|
||||||
template<typename T> struct conversion<T,T>
|
|
||||||
{
|
|
||||||
|
|
||||||
enum { exists = true };
|
|
||||||
enum { same_type = true };
|
|
||||||
enum { exists_two_way = true};
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // COMET_PARTIAL_SPECIALISATION
|
|
||||||
|
|
||||||
template<typename T, typename U> struct super_sub_class
|
|
||||||
{
|
|
||||||
enum { result = conversion<const U*, const T*>::exists && !conversion<const T*, const void*>::same_type };
|
|
||||||
};
|
|
||||||
|
|
||||||
inline bool is_null_vtable_entry(void *p,short n)
|
|
||||||
{
|
|
||||||
return ((n<0)?true:(0==(*reinterpret_cast<long *>(reinterpret_cast<char *>(*(reinterpret_cast<long *>(p)))+n))));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace impl {
|
|
||||||
|
|
||||||
// used by NutshellImpl's
|
|
||||||
struct false_type {};
|
|
||||||
struct true_type {};
|
|
||||||
|
|
||||||
template<int T> struct is_one { typedef false_type val; };
|
|
||||||
template<> struct is_one<1> { typedef true_type val; };
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,450 +0,0 @@
|
||||||
/** \file
|
|
||||||
* Implementation of Lists of types.
|
|
||||||
* Type lists are rather integral to the operation of Comet, and provide us
|
|
||||||
* with many of the mechanisms that allow us to all but remove the need for
|
|
||||||
* \#define macros in code.
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* Copyright © 2000-2002 Sofus Mortensen, Michael Geddes
|
|
||||||
*
|
|
||||||
* This material is provided "as is", with absolutely no warranty
|
|
||||||
* expressed or implied. Any use is at your own risk. Permission to
|
|
||||||
* use or copy this software for any purpose is hereby granted without
|
|
||||||
* fee, provided the above notices are retained on all copies.
|
|
||||||
* Permission to modify the code and to distribute modified code is
|
|
||||||
* granted, provided the above notices are retained, and a notice that
|
|
||||||
* the code was modified is included with the above copyright notice.
|
|
||||||
*
|
|
||||||
* This header is part of Comet version 2.
|
|
||||||
* https://github.com/alamaison/comet
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef COMET_TYPELIST_H
|
|
||||||
#define COMET_TYPELIST_H
|
|
||||||
|
|
||||||
#include <comet/config.h>
|
|
||||||
|
|
||||||
namespace comet {
|
|
||||||
|
|
||||||
/** \struct nil typelist.h comet/typelist.h
|
|
||||||
* End of list type.
|
|
||||||
*/
|
|
||||||
struct nil {};
|
|
||||||
|
|
||||||
template<typename T, typename U>
|
|
||||||
struct tl_t {
|
|
||||||
typedef T head;
|
|
||||||
typedef U tail;
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifndef COMET_TL_TRUNC
|
|
||||||
#ifndef __BORLANDC__
|
|
||||||
#define COMET_TL_LIST( X01,X02,X03,X04,X05,X06,X07,X08,X09, \
|
|
||||||
X10,X11,X12,X13,X14,X15,X16,X17,X18,X19, \
|
|
||||||
X20,X21,X22,X23,X24,X25,X26,X27,X28,X29, \
|
|
||||||
X30,X31,X32,X33,X34,X35,X36,X37,X38,X39) \
|
|
||||||
X01,X02,X03,X04,X05,X06,X07,X08,X09, \
|
|
||||||
X10,X11,X12,X13,X14,X15,X16,X17,X18,X19, \
|
|
||||||
X20,X21,X22,X23,X24,X25,X26,X27,X28,X29, \
|
|
||||||
X30,X31,X32,X33,X34,X35,X36,X37,X38,X39
|
|
||||||
#else
|
|
||||||
#define COMET_TL_LIST( X01,X02,X03,X04,X05,X06,X07,X08,X09, \
|
|
||||||
X10,X11,X12,X13,X14,X15,X16,X17,X18,X19, \
|
|
||||||
X20,X21,X22,X23,X24,X25,X26,X27,X28,X29, \
|
|
||||||
X30,X31,X32,X33,X34,X35,X36,X37,X38,X39) \
|
|
||||||
X01,X02,X03,X04,X05,X06,X07,X08,X09, \
|
|
||||||
X10,X11,X12,X13,X14,X15,X16,X17,X18,X19, \
|
|
||||||
X20,X21,X22,X23,X24,X25,X26,X27,X28,X29
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
#define COMET_TL_LIST( X01,X02,X03,X04,X05,X06,X07,X08,X09, \
|
|
||||||
X10,X11,X12,X13,X14,X15,X16,X17,X18,X19, \
|
|
||||||
X20,X21,X22,X23,X24,X25,X26,X27,X28,X29, \
|
|
||||||
X30,X31,X32,X33,X34,X35,X36,X37,X38,X39) \
|
|
||||||
X01,X02,X03,X04,X05,X06,X07,X08,X09,X10
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define COMET_LIST_TEMPLATE \
|
|
||||||
typename X00=comet::nil, COMET_TL_LIST( typename X01=comet::nil, typename X02=comet::nil, typename X03=comet::nil, typename X04=comet::nil, \
|
|
||||||
typename X05=comet::nil, typename X06=comet::nil, typename X07=comet::nil, typename X08=comet::nil, typename X09=comet::nil, \
|
|
||||||
typename X10=comet::nil, typename X11=comet::nil, typename X12=comet::nil, typename X13=comet::nil, typename X14=comet::nil, \
|
|
||||||
typename X15=comet::nil, typename X16=comet::nil, typename X17=comet::nil, typename X18=comet::nil, typename X19=comet::nil, \
|
|
||||||
typename X20=comet::nil, typename X21=comet::nil, typename X22=comet::nil, typename X23=comet::nil, typename X24=comet::nil, \
|
|
||||||
typename X25=comet::nil, typename X26=comet::nil, typename X27=comet::nil, typename X28=comet::nil, typename X29=comet::nil, \
|
|
||||||
typename X30=comet::nil, typename X31=comet::nil, typename X32=comet::nil, typename X33=comet::nil, typename X34=comet::nil, \
|
|
||||||
typename X35=comet::nil, typename X36=comet::nil, typename X37=comet::nil, typename X38=comet::nil, typename X39=comet::nil)
|
|
||||||
|
|
||||||
#define COMET_LIST_TEMPLATE_0 typename X00, COMET_TL_LIST(\
|
|
||||||
typename X01, typename X02, typename X03, typename X04, \
|
|
||||||
typename X05, typename X06, typename X07, typename X08, typename X09, \
|
|
||||||
typename X10, typename X11, typename X12, typename X13, typename X14, \
|
|
||||||
typename X15, typename X16, typename X17, typename X18, typename X19, \
|
|
||||||
typename X20, typename X21, typename X22, typename X23, typename X24, \
|
|
||||||
typename X25, typename X26, typename X27, typename X28, typename X29, \
|
|
||||||
typename X30, typename X31, typename X32, typename X33, typename X34, \
|
|
||||||
typename X35, typename X36, typename X37, typename X38, typename X39)
|
|
||||||
|
|
||||||
#define COMET_LIST_ARG_1 X00, COMET_TL_LIST(\
|
|
||||||
X01,X02,X03,X04,X05,X06,X07,X08,X09, \
|
|
||||||
X10,X11,X12,X13,X14,X15,X16,X17,X18,X19, \
|
|
||||||
X20,X21,X22,X23,X24,X25,X26,X27,X28,X29, \
|
|
||||||
X30,X31,X32,X33,X34,X35,X36,X37,X38,X39)
|
|
||||||
|
|
||||||
#define COMET_LIST_ARG_0 COMET_TL_LIST(\
|
|
||||||
X01,X02,X03,X04,X05,X06,X07,X08,X09, \
|
|
||||||
X10,X11,X12,X13,X14,X15,X16,X17,X18,X19, \
|
|
||||||
X20,X21,X22,X23,X24,X25,X26,X27,X28,X29, \
|
|
||||||
X30,X31,X32,X33,X34,X35,X36,X37,X38,X39)
|
|
||||||
|
|
||||||
#define COMET_LIST_NIL comet::nil, COMET_TL_LIST(\
|
|
||||||
comet::nil,comet::nil,comet::nil,comet::nil,comet::nil,comet::nil,comet::nil,comet::nil,comet::nil, \
|
|
||||||
comet::nil,comet::nil,comet::nil,comet::nil,comet::nil,comet::nil,comet::nil,comet::nil,comet::nil,comet::nil, \
|
|
||||||
comet::nil,comet::nil,comet::nil,comet::nil,comet::nil,comet::nil,comet::nil,comet::nil,comet::nil,comet::nil, \
|
|
||||||
comet::nil,comet::nil,comet::nil,comet::nil,comet::nil,comet::nil,comet::nil,comet::nil,comet::nil,comet::nil)
|
|
||||||
|
|
||||||
/** \struct make_list typelist.h comet/typelist.h
|
|
||||||
* Construct a 'type list' of up to 40 types.
|
|
||||||
* A list is a 'head-tail' list terminated by a 'nil' tail struct.
|
|
||||||
* It is most easily constructe by using make_list:
|
|
||||||
\code
|
|
||||||
comet::make_list< FooType,BarType>::result
|
|
||||||
\endcode
|
|
||||||
|
|
||||||
* The \e concept of a type-list is that it is either \link comet::nil nil \endlink
|
|
||||||
* or a struct containing a \e typedef of \p head to the first element in the
|
|
||||||
* list and a typedef of \p tail to a type-list that contains the rest of
|
|
||||||
* the list.
|
|
||||||
*
|
|
||||||
* This means that for a type-list \e LST
|
|
||||||
* \code
|
|
||||||
LST::head
|
|
||||||
\endcode
|
|
||||||
* is the first element in the list (assuming it is not
|
|
||||||
* \link comet::nil nil \endlink) and
|
|
||||||
* \code
|
|
||||||
LST::head::tail::head
|
|
||||||
\endcode
|
|
||||||
would be the second element in the list (assuming <kbd>LST::head::tail</KBD> is not
|
|
||||||
\link comet::nil nil \endlink), and so on.
|
|
||||||
|
|
||||||
* Two type lists can be appended together with typelist::append.
|
|
||||||
|
|
||||||
\sa typelist::append
|
|
||||||
*/
|
|
||||||
template<COMET_LIST_TEMPLATE> struct make_list
|
|
||||||
{
|
|
||||||
typedef tl_t<X00, typename make_list<COMET_LIST_ARG_0>::result> result;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<> struct make_list<COMET_LIST_NIL>
|
|
||||||
{
|
|
||||||
typedef nil result;
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace typelist {
|
|
||||||
|
|
||||||
template<typename L> struct length
|
|
||||||
{
|
|
||||||
enum { value = 1 + length< typename L::tail>::value };
|
|
||||||
};
|
|
||||||
|
|
||||||
template<> struct length<nil>
|
|
||||||
{
|
|
||||||
enum { value = 0 };
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef COMET_PARTIAL_SPECIALISATION
|
|
||||||
//! Find the type at the specified index.
|
|
||||||
/** \param L Type List
|
|
||||||
* \param idx Index
|
|
||||||
*/
|
|
||||||
template<typename L, unsigned idx> struct type_at
|
|
||||||
{
|
|
||||||
typedef typename type_at<typename L::tail,idx-1>::result result;
|
|
||||||
};
|
|
||||||
template<typename L> struct type_at<L,0>
|
|
||||||
{
|
|
||||||
typedef typename L::head result;
|
|
||||||
};
|
|
||||||
template< unsigned idx> struct type_at<nil,idx>
|
|
||||||
{
|
|
||||||
typedef nil result;
|
|
||||||
};
|
|
||||||
template<> struct type_at<nil,0>
|
|
||||||
{
|
|
||||||
typedef nil result;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/** \internal
|
|
||||||
*/
|
|
||||||
template<typename L, typename H, typename T> struct index_of_aux
|
|
||||||
{
|
|
||||||
enum { value = 1+(index_of_aux<typename L::tail,typename L::head, T>::value) };
|
|
||||||
};
|
|
||||||
template< typename L, typename T> struct index_of_aux<L,T,T>
|
|
||||||
{
|
|
||||||
enum { value = 0 };
|
|
||||||
};
|
|
||||||
/** Find the index of the type \a T in the type-list \a L.
|
|
||||||
* The result is in index_of::value.
|
|
||||||
*/
|
|
||||||
template<typename L, typename T> struct index_of
|
|
||||||
{
|
|
||||||
enum { value = index_of_aux<typename L::tail,typename L::head, T >::value };
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#else
|
|
||||||
template<typename L, unsigned idx> struct type_at;
|
|
||||||
|
|
||||||
template<typename L> struct type_at_aux
|
|
||||||
{
|
|
||||||
template<unsigned idx> struct X
|
|
||||||
{
|
|
||||||
typedef typename type_at<typename L::tail, idx-1>::result result;
|
|
||||||
// typedef type_at_aux<typename L::tail>::X<idx-1>::result result;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<> struct X<0>
|
|
||||||
{
|
|
||||||
typedef typename L::head result;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template<> struct type_at_aux<nil>
|
|
||||||
{
|
|
||||||
template<unsigned idx> struct X
|
|
||||||
{
|
|
||||||
typedef nil result;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* template<> struct type_at_aux< make_list<> >
|
|
||||||
{
|
|
||||||
template<unsigned idx> struct X
|
|
||||||
{
|
|
||||||
typedef nil result;
|
|
||||||
};
|
|
||||||
};*/
|
|
||||||
|
|
||||||
template<typename L, unsigned idx> struct type_at
|
|
||||||
{
|
|
||||||
typedef typename type_at_aux<L>::X<idx>::result result;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename L, typename T> struct index_of;
|
|
||||||
|
|
||||||
template<typename HEAD> struct index_of_aux
|
|
||||||
{
|
|
||||||
template<typename TAIL> struct X1
|
|
||||||
{
|
|
||||||
template<typename T> struct X2
|
|
||||||
{
|
|
||||||
enum { value = 1 + index_of<TAIL, T>::value };
|
|
||||||
};
|
|
||||||
|
|
||||||
template<> struct X2<HEAD>
|
|
||||||
{
|
|
||||||
enum { value = 0 };
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename L, typename T> struct index_of
|
|
||||||
{
|
|
||||||
enum { value = index_of_aux<typename L::head>::X1<typename L::tail>::X2<T>::value };
|
|
||||||
};
|
|
||||||
#endif // COMET_PARTIAL_SPECIALISATION
|
|
||||||
|
|
||||||
#undef COMET_LIST_ARG
|
|
||||||
|
|
||||||
#ifdef COMET_PARTIAL_SPECIALISATION
|
|
||||||
|
|
||||||
/** \struct append typelist.h comet/typelist.h
|
|
||||||
* Appends two type-lists together.
|
|
||||||
* Example:
|
|
||||||
* \code
|
|
||||||
comet::typelist::append<
|
|
||||||
comet::make_list< Type1, Type2 >::result,
|
|
||||||
comet::make_list< Type3, Type4 >::result
|
|
||||||
>
|
|
||||||
\endcode
|
|
||||||
\sa make_list
|
|
||||||
*/
|
|
||||||
template<typename L1, typename L2> struct append
|
|
||||||
{
|
|
||||||
typedef typename L1::head head;
|
|
||||||
typedef append<typename L1::tail, L2> tail;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename L2> struct append<nil,L2>
|
|
||||||
{
|
|
||||||
typedef typename L2::head head;
|
|
||||||
typedef typename L2::tail tail;
|
|
||||||
};
|
|
||||||
template<typename L2> struct append<make_list<>,L2>
|
|
||||||
{
|
|
||||||
typedef typename L2::head head;
|
|
||||||
typedef typename L2::tail tail;
|
|
||||||
};
|
|
||||||
template<> struct append<nil, nil>
|
|
||||||
{
|
|
||||||
typedef nil head;
|
|
||||||
typedef nil tail;
|
|
||||||
};
|
|
||||||
template<typename L, typename T> struct append_element
|
|
||||||
{
|
|
||||||
typedef typename append<L, typename make_list<T>::result>::head head;
|
|
||||||
typedef typename append<L, typename make_list<T>::result>::tail tail;
|
|
||||||
};
|
|
||||||
#else // COMET_PARTIAL_SPECIALISATION
|
|
||||||
|
|
||||||
template<typename L1, typename L2> struct append;
|
|
||||||
|
|
||||||
namespace impl {
|
|
||||||
|
|
||||||
template<typename L1> struct append_aux
|
|
||||||
{
|
|
||||||
template<typename L2> struct with
|
|
||||||
{
|
|
||||||
typedef typename L1::head head;
|
|
||||||
typedef typename append<typename L1::tail, L2> tail;
|
|
||||||
// typedef typename append_aux<L1::tail>::with<L2> tail;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<> struct with<nil>
|
|
||||||
{
|
|
||||||
typedef typename L1::head head;
|
|
||||||
typedef typename L1::tail tail;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template<> struct append_aux<nil>
|
|
||||||
{
|
|
||||||
template<typename L2> struct with
|
|
||||||
{
|
|
||||||
typedef typename L2::head head;
|
|
||||||
typedef typename L2::tail tail;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
/* template<> struct append_aux<make_list<> >
|
|
||||||
{
|
|
||||||
template<typename L2> struct with
|
|
||||||
{
|
|
||||||
typedef typename L2::head head;
|
|
||||||
typedef typename L2::tail tail;
|
|
||||||
};
|
|
||||||
};*/
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename L1, typename L2> struct append
|
|
||||||
{
|
|
||||||
typedef typename impl::append_aux<L1>::with<L2>::head head;
|
|
||||||
typedef typename impl::append_aux<L1>::with<L2>::tail tail;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename L, typename T> struct append_element
|
|
||||||
{
|
|
||||||
typedef typename impl::append_aux<L>::with< typename make_list<T>::result >::head head;
|
|
||||||
typedef typename impl::append_aux<L>::with< typename make_list<T>::result >::tail tail;
|
|
||||||
};
|
|
||||||
#endif // COMET_PARTIAL_SPECIALISATION
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef COMET_NESTED_TEMPLATES
|
|
||||||
/** \struct wrap_each typelist.h comet/typelist.h
|
|
||||||
* Wrap each of the elements of a list in the specified template class.
|
|
||||||
* Due to lack of support for template parameter to templates by Microsoft,
|
|
||||||
* macros have been defined as a necessary evil to get arround this.
|
|
||||||
* The macros are #COMET_WRAP_EACH_DECLARE and #COMET_WRAP_EACH.
|
|
||||||
* There is a propper implementation for compilers that support nested
|
|
||||||
* interfaces, which will be selected by the macro as appropriate.
|
|
||||||
* \sa COMET_WRAP_EACH_DECLARE COMET_WRAP_EACH
|
|
||||||
*/
|
|
||||||
template< template< typename > class T, typename L1> struct wrap_each;
|
|
||||||
namespace impl
|
|
||||||
{
|
|
||||||
template< template< typename > class T, typename L1> struct wrap_each_aux
|
|
||||||
{
|
|
||||||
typedef wrap_each<T, L1> x;
|
|
||||||
};
|
|
||||||
template< template< typename > class T> struct wrap_each_aux< T, nil>
|
|
||||||
{
|
|
||||||
typedef nil x;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
template< template< typename > class T, typename L1> struct wrap_each
|
|
||||||
{
|
|
||||||
typedef T<typename L1::head> head;
|
|
||||||
typedef typename impl::wrap_each_aux<T, typename L1::tail>::x tail;
|
|
||||||
};
|
|
||||||
|
|
||||||
template< template< typename > class T> struct wrap_each< T, ::comet::nil >
|
|
||||||
{
|
|
||||||
};
|
|
||||||
/** \def COMET_WRAP_EACH_DECLARE(T)
|
|
||||||
* Declare a template for wrapping each element in the specified type.
|
|
||||||
* \relates wrap_each
|
|
||||||
*/
|
|
||||||
#define COMET_WRAP_EACH_DECLARE(T)
|
|
||||||
// MSVC7.1 doesn't like this:
|
|
||||||
// template< template< typename > class T1, typename L1> struct wrap_each;
|
|
||||||
|
|
||||||
/** \def COMET_WRAP_EACH(T, L1)
|
|
||||||
* Produce a list L2 that consists of each member of list L1 wrapped in type T.
|
|
||||||
* This is very much a Lambda calculus concept for those who care.
|
|
||||||
* \relates wrap_each
|
|
||||||
*/
|
|
||||||
#define COMET_WRAP_EACH(T, L1) typelist::wrap_each<T, L1>
|
|
||||||
|
|
||||||
#else // COMET_NESTED_TEMPLATES
|
|
||||||
#define COMET_WRAP_EACH_DECLARE(T) \
|
|
||||||
template< typename L1 > struct wrap_each_aux##T; \
|
|
||||||
namespace impl \
|
|
||||||
{ \
|
|
||||||
template< typename L1> struct p_wrap_each_aux##T \
|
|
||||||
{ \
|
|
||||||
typedef wrap_each_aux##T<L1> x; \
|
|
||||||
}; \
|
|
||||||
template<> struct p_wrap_each_aux##T < ::comet::nil> \
|
|
||||||
{ \
|
|
||||||
typedef ::comet::nil x; \
|
|
||||||
}; \
|
|
||||||
}; \
|
|
||||||
template< typename L1> struct wrap_each_aux##T \
|
|
||||||
{ \
|
|
||||||
typedef T<typename L1::head> head; \
|
|
||||||
typedef typename impl::p_wrap_each_aux##T < typename L1::tail>::x tail;\
|
|
||||||
}; \
|
|
||||||
template<> struct wrap_each_aux##T< ::comet::nil> { };
|
|
||||||
|
|
||||||
#define COMET_WRAP_EACH(T, L1) wrap_each_aux##T<L1>
|
|
||||||
|
|
||||||
#endif // COMET_NESTED_TEMPLATES
|
|
||||||
|
|
||||||
template<typename ITF_LIST> struct ATL_NO_VTABLE inherit_all
|
|
||||||
: public ITF_LIST::head, public inherit_all<typename ITF_LIST::tail>
|
|
||||||
{};
|
|
||||||
|
|
||||||
template<> struct inherit_all<nil> {};
|
|
||||||
// template<> struct inherit_all<make_list<> > {};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* MSVC7 chokes on this one - not actually used anywhere
|
|
||||||
|
|
||||||
template<int idx, COMET_LIST_TEMPLATE> struct select
|
|
||||||
{
|
|
||||||
typedef typelist::type_at< make_list<COMET_LIST_ARG_1>::result, idx>::result result;
|
|
||||||
};*/
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,86 +0,0 @@
|
||||||
/** \file
|
|
||||||
* Unit-test wrapper.
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* Copyright © 2000, 2001 Paul Hollingsworth
|
|
||||||
*
|
|
||||||
* This material is provided "as is", with absolutely no warranty
|
|
||||||
* expressed or implied. Any use is at your own risk. Permission to
|
|
||||||
* use or copy this software for any purpose is hereby granted without
|
|
||||||
* fee, provided the above notices are retained on all copies.
|
|
||||||
* Permission to modify the code and to distribute modified code is
|
|
||||||
* granted, provided the above notices are retained, and a notice that
|
|
||||||
* the code was modified is included with the above copyright notice.
|
|
||||||
*
|
|
||||||
* This header is part of Comet version 2.
|
|
||||||
* https://github.com/alamaison/comet
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef COMET_UNITTEST_H
|
|
||||||
#define COMET_UNITTEST_H
|
|
||||||
|
|
||||||
#include <exception>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
namespace comet {
|
|
||||||
//! Define a unit test \a n.
|
|
||||||
template<int n>
|
|
||||||
struct test
|
|
||||||
{
|
|
||||||
void run() {}
|
|
||||||
};
|
|
||||||
|
|
||||||
int current_test = 0;
|
|
||||||
|
|
||||||
//! Run \a n tests.
|
|
||||||
/** \sa test
|
|
||||||
*/
|
|
||||||
template<int n>
|
|
||||||
struct tester
|
|
||||||
{
|
|
||||||
inline static void runtests()
|
|
||||||
{
|
|
||||||
tester<n-1>::runtests();
|
|
||||||
current_test = n;
|
|
||||||
test<n>().run();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct tester<0>
|
|
||||||
{
|
|
||||||
static void runtests() {}
|
|
||||||
};
|
|
||||||
} // namespace comet
|
|
||||||
|
|
||||||
//! Implement Main function for testing.
|
|
||||||
template<typename T>
|
|
||||||
struct main_t
|
|
||||||
{
|
|
||||||
/// Call to run tests.
|
|
||||||
static int call(int argc, const char * const argv[])
|
|
||||||
{
|
|
||||||
using std::cout;
|
|
||||||
using std::cerr;
|
|
||||||
using std::endl;
|
|
||||||
try {
|
|
||||||
comet::tester<64>::runtests();
|
|
||||||
} catch (const std::exception &e) {
|
|
||||||
std::cerr << "Test #" << comet::current_test << " failed - error message: <" << e.what() << ">" << endl;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
catch(...) {
|
|
||||||
std::cerr << "Test #" << comet::current_test << " failed with an unrecognized exception" << endl;
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
std::cout << "Ran all tests successfully" <<endl;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
#define COMET_TEST_MAIN \
|
|
||||||
int main(int argc, const char * const argv[]) \
|
|
||||||
{\
|
|
||||||
return main_t<void>::call(argc,argv);\
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,125 +0,0 @@
|
||||||
/** \file
|
|
||||||
* Various utilities.
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* Copyright © 2000, 2001 Sofus Mortensen
|
|
||||||
*
|
|
||||||
* This material is provided "as is", with absolutely no warranty
|
|
||||||
* expressed or implied. Any use is at your own risk. Permission to
|
|
||||||
* use or copy this software for any purpose is hereby granted without
|
|
||||||
* fee, provided the above notices are retained on all copies.
|
|
||||||
* Permission to modify the code and to distribute modified code is
|
|
||||||
* granted, provided the above notices are retained, and a notice that
|
|
||||||
* the code was modified is included with the above copyright notice.
|
|
||||||
*
|
|
||||||
* This header is part of Comet version 2.
|
|
||||||
* https://github.com/alamaison/comet
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef COMET_UTIL_H
|
|
||||||
#define COMET_UTIL_H
|
|
||||||
|
|
||||||
#include <comet/config.h>
|
|
||||||
|
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
#include <comet/error.h>
|
|
||||||
#include <comet/server.h>
|
|
||||||
|
|
||||||
namespace comet {
|
|
||||||
|
|
||||||
/*! \addtogroup WinUtil
|
|
||||||
*/
|
|
||||||
//@{
|
|
||||||
//! Automatic handling of CoInitialize / CoUninitialize.
|
|
||||||
class auto_coinit {
|
|
||||||
public:
|
|
||||||
#if (_WIN32_WINNT >= 0x0400 ) || defined(_WIN32_DCOM) // DCOM
|
|
||||||
explicit auto_coinit(COINIT ci) {
|
|
||||||
::CoInitializeEx(0, ci) | raise_exception;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
auto_coinit() { ::CoInitialize(0) | raise_exception; }
|
|
||||||
|
|
||||||
~auto_coinit() { ::CoUninitialize(); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
auto_coinit& operator=(const auto_coinit&);
|
|
||||||
auto_coinit(const auto_coinit&);
|
|
||||||
};
|
|
||||||
|
|
||||||
// For backward compatibility.
|
|
||||||
typedef auto_coinit auto_CoInitialize;
|
|
||||||
|
|
||||||
/// Returns the class id of the free threaded marshaler
|
|
||||||
inline CLSID get_clsid_of_ftm()
|
|
||||||
{
|
|
||||||
CLSID rv;
|
|
||||||
class Dummy : public static_object<> {} dummy;
|
|
||||||
|
|
||||||
IUnknown* pUnk = 0;
|
|
||||||
::CoCreateFreeThreadedMarshaler(&dummy, &pUnk) | raise_exception;
|
|
||||||
|
|
||||||
com_ptr<IMarshal> marshal = try_cast(pUnk);
|
|
||||||
|
|
||||||
marshal.raw()->GetUnmarshalClass(IID_IUnknown, &dummy, MSHCTX_INPROC,0,MSHLFLAGS_NORMAL, &rv) | raise_exception;
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if and only if object is aggregating the free threaded marshaler.
|
|
||||||
*/
|
|
||||||
inline bool is_object_aggregating_ftm(const com_ptr<IUnknown>& p)
|
|
||||||
{
|
|
||||||
com_ptr<IMarshal> marshal = com_cast(p);
|
|
||||||
if (marshal == 0) return false;
|
|
||||||
|
|
||||||
class Dummy : public static_object<> {} dummy;
|
|
||||||
|
|
||||||
CLSID clsid = CLSID_NULL;
|
|
||||||
marshal.raw()->GetUnmarshalClass(IID_IUnknown, &dummy, MSHCTX_INPROC,0,MSHLFLAGS_NORMAL, &clsid);
|
|
||||||
|
|
||||||
CLSID ftm_clsid = get_clsid_of_ftm();
|
|
||||||
return clsid == ftm_clsid ? true : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if (_WIN32_WINNT >= 0x0400 ) || defined(_WIN32_DCOM) // DCOM
|
|
||||||
/**
|
|
||||||
* Returns true if and only if current apartment is the MTA.
|
|
||||||
*/
|
|
||||||
inline bool is_mta()
|
|
||||||
{
|
|
||||||
if (SUCCEEDED(::CoInitializeEx(0, COINIT_MULTITHREADED)))
|
|
||||||
{
|
|
||||||
::CoUninitialize();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
/**
|
|
||||||
* Returns true if and only if current apartment is an STA.
|
|
||||||
*/
|
|
||||||
inline bool is_sta()
|
|
||||||
{
|
|
||||||
if (SUCCEEDED(::CoInitialize(0)))
|
|
||||||
{
|
|
||||||
::CoUninitialize();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if and only if specified ptr is a standard proxy.
|
|
||||||
*/
|
|
||||||
inline bool is_std_proxy(const com_ptr<IUnknown>& unk)
|
|
||||||
{
|
|
||||||
com_ptr<IUnknown> pm;
|
|
||||||
return SUCCEEDED(unk.raw()->QueryInterface(IID_IProxyManager, reinterpret_cast<void**>(pm.out())));
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,88 +0,0 @@
|
||||||
/** \file
|
|
||||||
* uuid wrapper class.
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* Copyright © 2001, 2002 Sofus Mortensen
|
|
||||||
*
|
|
||||||
* This material is provided "as is", with absolutely no warranty
|
|
||||||
* expressed or implied. Any use is at your own risk. Permission to
|
|
||||||
* use or copy this software for any purpose is hereby granted without
|
|
||||||
* fee, provided the above notices are retained on all copies.
|
|
||||||
* Permission to modify the code and to distribute modified code is
|
|
||||||
* granted, provided the above notices are retained, and a notice that
|
|
||||||
* the code was modified is included with the above copyright notice.
|
|
||||||
*
|
|
||||||
* This header is part of Comet version 2.
|
|
||||||
* https://github.com/alamaison/comet
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef COMET_UUID_H
|
|
||||||
#define COMET_UUID_H
|
|
||||||
|
|
||||||
#include <comet/config.h>
|
|
||||||
#include <comet/uuid_fwd.h>
|
|
||||||
#include <comet/bstr.h>
|
|
||||||
|
|
||||||
#pragma comment( lib, "Rpcrt4" )
|
|
||||||
|
|
||||||
namespace comet {
|
|
||||||
|
|
||||||
template<typename C>
|
|
||||||
void uuid_t::copy_to_str(C s[36]) const throw()
|
|
||||||
{
|
|
||||||
const unsigned char *p = reinterpret_cast<const unsigned char*>(this);
|
|
||||||
|
|
||||||
for (int i=0; i<20; ++i)
|
|
||||||
{
|
|
||||||
int j = uuid_table()[i];
|
|
||||||
if (j >= 0)
|
|
||||||
{
|
|
||||||
const unsigned char byt = p[j];
|
|
||||||
*s = hex_table()[byt >> 4];
|
|
||||||
++s;
|
|
||||||
*s = hex_table()[byt & 0xf];
|
|
||||||
}
|
|
||||||
else *s = L'-';
|
|
||||||
++s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename C>
|
|
||||||
bool uuid_t::init_from_str(const C s[], size_t len) throw()
|
|
||||||
{
|
|
||||||
unsigned char *p = reinterpret_cast<unsigned char*>(this);
|
|
||||||
|
|
||||||
bool has_brace;
|
|
||||||
switch (len)
|
|
||||||
{
|
|
||||||
default: return false;
|
|
||||||
case 36: has_brace = false; break;
|
|
||||||
case 38:
|
|
||||||
if (*s != C('{'))
|
|
||||||
return false;
|
|
||||||
has_brace = true;
|
|
||||||
++s;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
int i;
|
|
||||||
for (i=0; i<20; ++i)
|
|
||||||
{
|
|
||||||
int j = uuid_table()[i];
|
|
||||||
if (j >= 0)
|
|
||||||
{
|
|
||||||
int a = parse_nibble(*s);
|
|
||||||
++s;
|
|
||||||
int b = parse_nibble(*s);
|
|
||||||
p[j] = unsigned char(a << 4 | b);
|
|
||||||
}
|
|
||||||
else if (*s != C('-'))
|
|
||||||
return false;
|
|
||||||
++s;
|
|
||||||
}
|
|
||||||
return (! has_brace) || (*s == C('}'));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,441 +0,0 @@
|
||||||
/** \file
|
|
||||||
* uuid wrapper class.
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* Copyright © 2001, 2002 Sofus Mortensen
|
|
||||||
* Copyright © 2013 Alexander Lamaison
|
|
||||||
*
|
|
||||||
* This material is provided "as is", with absolutely no warranty
|
|
||||||
* expressed or implied. Any use is at your own risk. Permission to
|
|
||||||
* use or copy this software for any purpose is hereby granted without
|
|
||||||
* fee, provided the above notices are retained on all copies.
|
|
||||||
* Permission to modify the code and to distribute modified code is
|
|
||||||
* granted, provided the above notices are retained, and a notice that
|
|
||||||
* the code was modified is included with the above copyright notice.
|
|
||||||
*
|
|
||||||
* This header is part of Comet version 2.
|
|
||||||
* https://github.com/alamaison/comet
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef COMET_UUID_FWD_H
|
|
||||||
#define COMET_UUID_FWD_H
|
|
||||||
|
|
||||||
#include <comet/config.h>
|
|
||||||
#include <comet/tstring.h>
|
|
||||||
|
|
||||||
#include <rpc.h>
|
|
||||||
#include <string>
|
|
||||||
#include <algorithm>
|
|
||||||
#include <iostream>
|
|
||||||
#include <ostream>
|
|
||||||
|
|
||||||
namespace comet{
|
|
||||||
|
|
||||||
|
|
||||||
/*! \addtogroup COMType
|
|
||||||
*/
|
|
||||||
//@{
|
|
||||||
|
|
||||||
/// UUID wrapper.
|
|
||||||
class uuid_t : public COMET_GUID_BASE
|
|
||||||
{
|
|
||||||
struct unitialized_t {};
|
|
||||||
uuid_t(unitialized_t) {}
|
|
||||||
|
|
||||||
friend class bstr_t;
|
|
||||||
|
|
||||||
public:
|
|
||||||
/// Default constructor - constructs a nil uuid.
|
|
||||||
uuid_t()
|
|
||||||
{
|
|
||||||
UuidCreateNil(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Copy constructor
|
|
||||||
uuid_t(const COMET_GUID_BASE& u)
|
|
||||||
{
|
|
||||||
memcpy(this, &u, sizeof(COMET_GUID_BASE));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Assignment operator
|
|
||||||
uuid_t& operator=(const COMET_GUID_BASE& u)
|
|
||||||
{
|
|
||||||
memcpy(this, &u, sizeof(COMET_GUID_BASE));
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// \name Construct uuid from string
|
|
||||||
//@{
|
|
||||||
explicit uuid_t(const std::string& s)
|
|
||||||
{
|
|
||||||
if (!init_from_str(s.c_str(), s.length()))
|
|
||||||
throw std::runtime_error(err_msg());
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit uuid_t(const char* s)
|
|
||||||
{
|
|
||||||
if (!init_from_str(s, strlen(s)))
|
|
||||||
throw std::runtime_error(err_msg());
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit uuid_t(const std::wstring& s)
|
|
||||||
{
|
|
||||||
if (!init_from_str(s.c_str(), s.length()))
|
|
||||||
throw std::runtime_error(err_msg());
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit uuid_t(const wchar_t* s)
|
|
||||||
{
|
|
||||||
if (!init_from_str(s, wcslen(s)))
|
|
||||||
throw std::runtime_error(err_msg());
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit uuid_t(const bstr_t& bs);
|
|
||||||
//@}
|
|
||||||
|
|
||||||
//! Generate new guid.
|
|
||||||
static uuid_t create()
|
|
||||||
{
|
|
||||||
unitialized_t x;
|
|
||||||
uuid_t g(x);
|
|
||||||
UuidCreate(&g);
|
|
||||||
return g;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Set to nil uuid.
|
|
||||||
void clear()
|
|
||||||
{
|
|
||||||
UuidCreateNil(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Returns hash of uuid
|
|
||||||
unsigned short hash() const
|
|
||||||
{
|
|
||||||
RPC_STATUS status;
|
|
||||||
unsigned short r = UuidHash(const_cast<uuid_t*>(this), &status);
|
|
||||||
if (status != RPC_S_OK)
|
|
||||||
throw std::runtime_error("uuid_t::hash - UuidHash failed.");
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Convert uuid to string
|
|
||||||
//@{
|
|
||||||
/// Return a std::string version of the uuid.
|
|
||||||
std::string str() const
|
|
||||||
{
|
|
||||||
std::string r;
|
|
||||||
r.resize(36);
|
|
||||||
copy_to_str(&r[0]);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
/// Return a std::string version of the uuid.
|
|
||||||
inline std::string s_str() const
|
|
||||||
{
|
|
||||||
return str();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return a std::wstring version of the uuid.
|
|
||||||
std::wstring w_str() const
|
|
||||||
{
|
|
||||||
std::wstring r;
|
|
||||||
r.resize(36);
|
|
||||||
copy_to_str(&r[0]);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return a tstring (templated to TCHAR) version of the uuid.
|
|
||||||
tstring t_str() const
|
|
||||||
{
|
|
||||||
tstring r;
|
|
||||||
r.resize(36);
|
|
||||||
copy_to_str(&r[0]);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
//@}
|
|
||||||
|
|
||||||
/// Returns true if and only if uuid is nil.
|
|
||||||
bool is_null() const throw()
|
|
||||||
{
|
|
||||||
return ((PLONG) this)[0] == 0 &&
|
|
||||||
((PLONG) this)[1] == 0 &&
|
|
||||||
((PLONG) this)[2] == 0 &&
|
|
||||||
((PLONG) this)[3] == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Returns true if and only if uuid is nil
|
|
||||||
bool operator!() const throw()
|
|
||||||
{
|
|
||||||
return is_null();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Output to an ostream.
|
|
||||||
template<class E, class TR>
|
|
||||||
friend inline std::basic_ostream<E, TR>& operator<<(std::basic_ostream<E, TR>& os, const uuid_t& u);
|
|
||||||
|
|
||||||
/// Input from an ostream
|
|
||||||
template<class E, class TR>
|
|
||||||
friend inline std::basic_istream<E, TR>& operator>>(std::basic_istream<E, TR>& is, uuid_t& u);
|
|
||||||
|
|
||||||
/** \internal
|
|
||||||
*/
|
|
||||||
class bool_tester
|
|
||||||
{ void operator delete(void*); };
|
|
||||||
|
|
||||||
/// Copy the uuid_t to a string/container.
|
|
||||||
template<typename C> void copy_to_str(C s[]) const throw();
|
|
||||||
/// Initialise the uuid_t from a string/container.
|
|
||||||
template<typename C> bool init_from_str(const C s[], size_t len) throw();
|
|
||||||
|
|
||||||
static const int* uuid_table()
|
|
||||||
{
|
|
||||||
static const int table[] = { 3, 2, 1, 0, -1, 5, 4, -1, 7, 6, -1, 8, 9, -1, 10, 11, 12, 13, 14, 15 };
|
|
||||||
return table;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char* hex_table()
|
|
||||||
{
|
|
||||||
static const char hex[] = "0123456789abcdef";
|
|
||||||
return hex;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char* err_msg()
|
|
||||||
{
|
|
||||||
static const char msg[] = "uuid_t: invalid format";
|
|
||||||
return msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int parse_nibble(int c)
|
|
||||||
{
|
|
||||||
return c >= 'A' ? (c|0x20) - 'a' + 10 : c - '0';
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Compare two guids.
|
|
||||||
inline long cmp(const comet::uuid_t &rhs) const
|
|
||||||
{
|
|
||||||
long i; // The code below may be a bit dense, but it is compact and works.
|
|
||||||
if((i = (Data1 - rhs.Data1)) == 0 && (i = (Data2 - rhs.Data2)) == 0 && (i = (Data3 - rhs.Data3)) == 0)
|
|
||||||
(i = ::memcmp(Data4, rhs.Data4, 8));
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Compare two guids for equality.
|
|
||||||
inline bool is_equal( const comet::uuid_t &rhs) const
|
|
||||||
{
|
|
||||||
// From ATL
|
|
||||||
return ((PLONG) this)[0] == ((PLONG) &rhs)[0] &&
|
|
||||||
((PLONG) this)[1] == ((PLONG) &rhs)[1] &&
|
|
||||||
((PLONG) this)[2] == ((PLONG) &rhs)[2] &&
|
|
||||||
((PLONG) this)[3] == ((PLONG) &rhs)[3];
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
/**\internal
|
|
||||||
*/
|
|
||||||
operator bool_tester*() const throw()
|
|
||||||
{ if (is_null()) return 0; static bool_tester test; return &test; }
|
|
||||||
|
|
||||||
/// Construct const reference to uuid from a raw GUID
|
|
||||||
static const uuid_t& create_const_reference(const COMET_GUID_BASE& x)
|
|
||||||
{
|
|
||||||
return *reinterpret_cast<const uuid_t*>(&x);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Construct reference to uuid from a raw GUID
|
|
||||||
static uuid_t& create_reference(COMET_GUID_BASE& x)
|
|
||||||
{
|
|
||||||
return *reinterpret_cast<uuid_t*>(&x);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \name Methods for converting uuid to raw GUID when calling raw COM functions or legacy code.
|
|
||||||
//@{
|
|
||||||
COMET_GUID_BASE* out() { return this; }
|
|
||||||
COMET_GUID_BASE* inout() { return this; }
|
|
||||||
COMET_GUID_BASE in() const { return *this; }
|
|
||||||
COMET_GUID_BASE* in_ptr() const { return const_cast<COMET_GUID_BASE*>(static_cast<const COMET_GUID_BASE*>(this)); }
|
|
||||||
//@}
|
|
||||||
};
|
|
||||||
//@}
|
|
||||||
|
|
||||||
/// \name comparison operators
|
|
||||||
//@{
|
|
||||||
/** Equals operator.
|
|
||||||
* \relates uuid_t
|
|
||||||
*/
|
|
||||||
inline bool operator==(const comet::uuid_t& lhs, const comet::uuid_t& rhs)
|
|
||||||
{
|
|
||||||
return lhs.is_equal(rhs);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Inequality operator.
|
|
||||||
* \relates uuid_t
|
|
||||||
*/
|
|
||||||
inline bool operator!=(const comet::uuid_t& lhs, const comet::uuid_t& rhs)
|
|
||||||
{
|
|
||||||
return !lhs.is_equal(rhs);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Equals operator.
|
|
||||||
* \relates uuid_t
|
|
||||||
*/
|
|
||||||
inline bool operator==(const comet::uuid_t& lhs, const COMET_GUID_BASE& rhs)
|
|
||||||
{
|
|
||||||
return lhs.is_equal( comet::uuid_t::create_const_reference(rhs) );
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Inequality operator.
|
|
||||||
* \relates uuid_t
|
|
||||||
*/
|
|
||||||
inline bool operator!=(const comet::uuid_t& lhs, const COMET_GUID_BASE& rhs)
|
|
||||||
{
|
|
||||||
return !lhs.is_equal( comet::uuid_t::create_const_reference(rhs) );
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Equals operator.
|
|
||||||
* \relates uuid_t
|
|
||||||
*/
|
|
||||||
inline bool operator==(const COMET_GUID_BASE& lhs, const comet::uuid_t& rhs)
|
|
||||||
{
|
|
||||||
return comet::uuid_t::create_const_reference(lhs).is_equal(rhs);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Inequality operator.
|
|
||||||
* \relates uuid_t
|
|
||||||
*/
|
|
||||||
inline bool operator!=(const COMET_GUID_BASE& lhs, const comet::uuid_t& rhs)
|
|
||||||
{
|
|
||||||
return !comet::uuid_t::create_const_reference(lhs).is_equal(rhs);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Less-than operator.
|
|
||||||
* \relates uuid_t
|
|
||||||
*/
|
|
||||||
inline bool operator<(const comet::uuid_t& lhs, const comet::uuid_t& rhs)
|
|
||||||
{
|
|
||||||
return lhs.cmp(rhs)<0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Less-than operator.
|
|
||||||
* \relates uuid_t
|
|
||||||
*/
|
|
||||||
inline bool operator<(const comet::uuid_t& lhs, const COMET_GUID_BASE& rhs)
|
|
||||||
{
|
|
||||||
return lhs.cmp(comet::uuid_t::create_const_reference(rhs))<0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Less-than operator.
|
|
||||||
* \relates uuid_t
|
|
||||||
*/
|
|
||||||
inline bool operator<(const COMET_GUID_BASE& lhs, const comet::uuid_t& rhs)
|
|
||||||
{
|
|
||||||
return comet::uuid_t::create_const_reference(lhs).cmp(rhs)<0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Greater-than-equals operator.
|
|
||||||
* \relates uuid_t
|
|
||||||
*/
|
|
||||||
inline bool operator>=(const comet::uuid_t& lhs, const comet::uuid_t& rhs)
|
|
||||||
{
|
|
||||||
return lhs.cmp(rhs)>=0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Greater-than-equals operator.
|
|
||||||
* \relates uuid_t
|
|
||||||
*/
|
|
||||||
inline bool operator>=(const comet::uuid_t& lhs, const COMET_GUID_BASE& rhs)
|
|
||||||
{
|
|
||||||
return lhs.cmp(comet::uuid_t::create_const_reference(rhs))>=0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Greater-than-equals operator.
|
|
||||||
* \relates uuid_t
|
|
||||||
*/
|
|
||||||
inline bool operator>=(const COMET_GUID_BASE& lhs, const comet::uuid_t& rhs)
|
|
||||||
{
|
|
||||||
return comet::uuid_t::create_const_reference(lhs).cmp(rhs)>=0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Greater-than operator.
|
|
||||||
* \relates uuid_t
|
|
||||||
*/
|
|
||||||
inline bool operator>(const comet::uuid_t& lhs, const comet::uuid_t& rhs)
|
|
||||||
{
|
|
||||||
return lhs.cmp(rhs)>0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Greater-than operator.
|
|
||||||
* \relates uuid_t
|
|
||||||
*/
|
|
||||||
inline bool operator>(const comet::uuid_t& lhs, const COMET_GUID_BASE& rhs)
|
|
||||||
{
|
|
||||||
return lhs.cmp(comet::uuid_t::create_const_reference(rhs))>0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Greater-than operator.
|
|
||||||
* \relates uuid_t
|
|
||||||
*/
|
|
||||||
inline bool operator>(const COMET_GUID_BASE& lhs, const comet::uuid_t& rhs)
|
|
||||||
{
|
|
||||||
return comet::uuid_t::create_const_reference(lhs).cmp(rhs)>0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Less-than-equals operator.
|
|
||||||
* \relates uuid_t
|
|
||||||
*/
|
|
||||||
inline bool operator<=(const comet::uuid_t& lhs, const comet::uuid_t& rhs)
|
|
||||||
{
|
|
||||||
return lhs.cmp(rhs)<=0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Less-than-equals operator.
|
|
||||||
* \relates uuid_t
|
|
||||||
*/
|
|
||||||
inline bool operator<=(const comet::uuid_t& lhs, const COMET_GUID_BASE& rhs)
|
|
||||||
{
|
|
||||||
return lhs.cmp(comet::uuid_t::create_const_reference(rhs))<=0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Less-than-equals operator.
|
|
||||||
* \relates uuid_t
|
|
||||||
*/
|
|
||||||
inline bool operator<=(const COMET_GUID_BASE& lhs, const comet::uuid_t& rhs)
|
|
||||||
{
|
|
||||||
return comet::uuid_t::create_const_reference(lhs).cmp(rhs)<=0;
|
|
||||||
}
|
|
||||||
//@}
|
|
||||||
|
|
||||||
/// \name overloads for output/input to/from streams
|
|
||||||
/// @{
|
|
||||||
|
|
||||||
/** Output to an ostream.
|
|
||||||
* \relates uuid_t
|
|
||||||
*/
|
|
||||||
template<class E, class TR>
|
|
||||||
inline std::basic_ostream<E, TR>& operator<<(std::basic_ostream<E, TR>& os, const comet::uuid_t& u)
|
|
||||||
{
|
|
||||||
E buf[36];
|
|
||||||
u.copy_to_str(buf);
|
|
||||||
os.write(buf, 36);
|
|
||||||
return os;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Input from an istream.
|
|
||||||
* \relates uuid_t
|
|
||||||
*/
|
|
||||||
template<class E, class TR>
|
|
||||||
inline std::basic_istream<E, TR>& operator>>(std::basic_istream<E, TR>& is, comet::uuid_t& u)
|
|
||||||
{
|
|
||||||
typename std::basic_istream<E,TR>::sentry se(is);
|
|
||||||
if (se)
|
|
||||||
{
|
|
||||||
E buf[36];
|
|
||||||
is.read(buf, 36);
|
|
||||||
if (!u.init_from_str(buf, is.gcount()))
|
|
||||||
is.setstate(std::ios::badbit);
|
|
||||||
}
|
|
||||||
return is;
|
|
||||||
}
|
|
||||||
//@}
|
|
||||||
|
|
||||||
} // namespace comet
|
|
||||||
|
|
||||||
#endif
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,149 +0,0 @@
|
||||||
/** \file
|
|
||||||
* Standard C++ iterators wrapping IEnumVARIANT objects.
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* Copyright © 2000 Sofus Mortensen
|
|
||||||
*
|
|
||||||
* This material is provided "as is", with absolutely no warranty
|
|
||||||
* expressed or implied. Any use is at your own risk. Permission to
|
|
||||||
* use or copy this software for any purpose is hereby granted without
|
|
||||||
* fee, provided the above notices are retained on all copies.
|
|
||||||
* Permission to modify the code and to distribute modified code is
|
|
||||||
* granted, provided the above notices are retained, and a notice that
|
|
||||||
* the code was modified is included with the above copyright notice.
|
|
||||||
*
|
|
||||||
* This header is part of Comet version 2.
|
|
||||||
* https://github.com/alamaison/comet
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef COMET_VARIANT_ITERATOR_H
|
|
||||||
#define COMET_VARIANT_ITERATOR_H
|
|
||||||
|
|
||||||
#include <comet/config.h>
|
|
||||||
|
|
||||||
#include <comet/ptr.h>
|
|
||||||
#include <comet/variant.h>
|
|
||||||
|
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
namespace comet {
|
|
||||||
|
|
||||||
/** \class variant_iterator enum.h comet/enum.h
|
|
||||||
* STL style iterator for IEnumVariant interface.
|
|
||||||
*/
|
|
||||||
class variant_iterator
|
|
||||||
{
|
|
||||||
com_ptr<IEnumVARIANT> enum_;
|
|
||||||
variant_t ce_;
|
|
||||||
public:
|
|
||||||
/** Constructor.
|
|
||||||
*/
|
|
||||||
variant_iterator( const com_ptr<IEnumVARIANT>& e ) : enum_(e) {
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
|
|
||||||
variant_iterator() {}
|
|
||||||
|
|
||||||
/** Move to next element.
|
|
||||||
*/
|
|
||||||
variant_iterator& operator++() {
|
|
||||||
next();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator!=(const variant_iterator& v) {
|
|
||||||
if (!v.enum_.is_null())
|
|
||||||
throw std::logic_error(
|
|
||||||
"variant_iterator comparison does not work");
|
|
||||||
|
|
||||||
return !enum_.is_null();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Move to next element (post increment).
|
|
||||||
*/
|
|
||||||
variant_iterator operator++(int) {
|
|
||||||
variant_iterator t(*this);
|
|
||||||
operator++();
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Current element.
|
|
||||||
*/
|
|
||||||
variant_t& operator*() {
|
|
||||||
return ce_;
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
void next() {
|
|
||||||
if (enum_) {
|
|
||||||
unsigned long x = 0;
|
|
||||||
enum_->Next(1, ce_.out(), &x) | raise_exception;
|
|
||||||
if (x == 0) enum_ = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/** \class itf_iterator enum.h comet/enum.h
|
|
||||||
* STL style Iterator for IEnumVARIANT interface returning a contained
|
|
||||||
* interface pointer.
|
|
||||||
*/
|
|
||||||
template<typename Itf> class itf_iterator
|
|
||||||
{
|
|
||||||
com_ptr<IEnumVARIANT> enum_;
|
|
||||||
com_ptr<Itf> p_;
|
|
||||||
public:
|
|
||||||
/** Constructor.
|
|
||||||
*/
|
|
||||||
itf_iterator( const com_ptr<IEnumVARIANT>& e ) : enum_(e) {
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
|
|
||||||
itf_iterator() {}
|
|
||||||
|
|
||||||
/** Move to next element.
|
|
||||||
*/
|
|
||||||
itf_iterator& operator++() {
|
|
||||||
next();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator!=(const itf_iterator& v) {
|
|
||||||
if (v.enum_)
|
|
||||||
throw std::logic_error(
|
|
||||||
"itf_iterator comparison does not work");
|
|
||||||
|
|
||||||
return enum_ != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Move to next element.
|
|
||||||
*/
|
|
||||||
itf_iterator operator++(int) {
|
|
||||||
itf_iterator t(*this);
|
|
||||||
operator++();
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Access element.
|
|
||||||
*/
|
|
||||||
com_ptr<Itf>& operator*() {
|
|
||||||
return p_;
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
void next() {
|
|
||||||
if (enum_) {
|
|
||||||
unsigned long x = 0;
|
|
||||||
variant_t v;
|
|
||||||
enum_->Next(1, v.out(), &x) | raise_exception;
|
|
||||||
if (x == 0) {
|
|
||||||
enum_ = 0;
|
|
||||||
p_ = 0;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
p_ = try_cast(v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,20 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "comet/handle_except.h"
|
|
||||||
#include <mfapi.h>
|
|
||||||
|
|
||||||
namespace comet
|
|
||||||
{
|
|
||||||
struct auto_mf
|
|
||||||
{
|
|
||||||
auto_mf(DWORD dwFlags = MFSTARTUP_FULL)
|
|
||||||
{
|
|
||||||
MFStartup(MF_VERSION) | comet::raise_exception;
|
|
||||||
}
|
|
||||||
~auto_mf()
|
|
||||||
{
|
|
||||||
MFShutdown();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,65 +0,0 @@
|
||||||
#ifndef comet_com_ptr_array_h__
|
|
||||||
#define comet_com_ptr_array_h__
|
|
||||||
|
|
||||||
#include <comet_task_ptr.h>
|
|
||||||
#include <comet/ptr.h>
|
|
||||||
|
|
||||||
namespace comet {
|
|
||||||
template<typename TInf, typename TCount = UINT32>
|
|
||||||
class com_ptr_array {
|
|
||||||
public:
|
|
||||||
com_ptr_array() : _ptr(nullptr), _count(0) {}
|
|
||||||
~com_ptr_array() {
|
|
||||||
clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
TInf** in() {
|
|
||||||
return _ptr.in();
|
|
||||||
}
|
|
||||||
|
|
||||||
TInf*** inout() {
|
|
||||||
return _ptr.inout();
|
|
||||||
}
|
|
||||||
|
|
||||||
TInf*** out() {
|
|
||||||
clear();
|
|
||||||
return _ptr.out();
|
|
||||||
}
|
|
||||||
|
|
||||||
TCount count() {
|
|
||||||
return _count;
|
|
||||||
}
|
|
||||||
|
|
||||||
TCount* inout_count() {
|
|
||||||
return &_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
TCount* out_count() {
|
|
||||||
clear();
|
|
||||||
return &_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
com_ptr<TInf> operator[](size_t i) {
|
|
||||||
return com_ptr<TInf>(_ptr[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
void clear() {
|
|
||||||
if (_ptr) {
|
|
||||||
for (DWORD i = 0; i < _count; i++) {
|
|
||||||
_ptr[i]->Release();
|
|
||||||
}
|
|
||||||
_count = 0;
|
|
||||||
_ptr.free();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
task_ptr<TInf*> _ptr;
|
|
||||||
TCount _count;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // comet_com_ptr_array_h__
|
|
|
@ -1,85 +0,0 @@
|
||||||
#ifndef comet_task_ptr_h__
|
|
||||||
#define comet_task_ptr_h__
|
|
||||||
|
|
||||||
#include <combaseapi.h>
|
|
||||||
|
|
||||||
namespace comet {
|
|
||||||
template<typename T>
|
|
||||||
class task_ptr {
|
|
||||||
public:
|
|
||||||
task_ptr() : _ptr(0) {}
|
|
||||||
task_ptr(T* ptr) : _ptr(ptr) {}
|
|
||||||
|
|
||||||
task_ptr( const task_ptr& other ); // non construction-copyable
|
|
||||||
task_ptr( task_ptr&& other ); // non construction-movable
|
|
||||||
task_ptr& operator=( const task_ptr& ); // non copyable
|
|
||||||
task_ptr& operator=( task_ptr&& ); // non movable
|
|
||||||
|
|
||||||
~task_ptr() {
|
|
||||||
free();
|
|
||||||
}
|
|
||||||
|
|
||||||
void free() {
|
|
||||||
if (_ptr) {
|
|
||||||
CoTaskMemFree(_ptr);
|
|
||||||
}
|
|
||||||
_ptr = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool alloc(size_t size) {
|
|
||||||
free();
|
|
||||||
_ptr = ::CoTaskMemAlloc(size);
|
|
||||||
return _ptr != NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool realloc(size_t size) {
|
|
||||||
_ptr = ::CoTaskMemRealloc(_ptr, size);
|
|
||||||
return _ptr != NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
T* in() {
|
|
||||||
return _ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
T** inout() {
|
|
||||||
return &_ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
T** out() {
|
|
||||||
free();
|
|
||||||
return &_ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef _TYPEDEF_BOOL_TYPE
|
|
||||||
typedef task_ptr<T> _Myt;
|
|
||||||
_TYPEDEF_BOOL_TYPE;
|
|
||||||
_OPERATOR_BOOL() const _NOEXCEPT
|
|
||||||
{ // test for non-null pointer
|
|
||||||
return (_ptr != 0 ? _CONVERTIBLE_TO_TRUE : 0);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
explicit operator bool() const
|
|
||||||
{ // test for non-null pointer
|
|
||||||
return _ptr != 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
T& operator[](size_t i) {
|
|
||||||
return _ptr[i];
|
|
||||||
}
|
|
||||||
const T& operator[](size_t i) const {
|
|
||||||
return _ptr[i];
|
|
||||||
}
|
|
||||||
T* operator->() {
|
|
||||||
return _ptr;
|
|
||||||
}
|
|
||||||
T operator*() {
|
|
||||||
return _ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
T* _ptr;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // comet_task_ptr_h__
|
|
|
@ -1,8 +0,0 @@
|
||||||
// stdafx.cpp : source file that includes just the standard includes
|
|
||||||
// ComCam.pch will be the pre-compiled header
|
|
||||||
// stdafx.obj will contain the pre-compiled type information
|
|
||||||
|
|
||||||
#include "stdafx.h"
|
|
||||||
|
|
||||||
// TODO: reference any additional headers you need in STDAFX.H
|
|
||||||
// and not in this file
|
|
|
@ -1,15 +0,0 @@
|
||||||
// stdafx.h : include file for standard system include files,
|
|
||||||
// or project specific include files that are used frequently, but
|
|
||||||
// are changed infrequently
|
|
||||||
//
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "targetver.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <tchar.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// TODO: reference additional headers your program requires here
|
|
|
@ -1,8 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
// Including SDKDDKVer.h defines the highest available Windows platform.
|
|
||||||
|
|
||||||
// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
|
|
||||||
// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
|
|
||||||
|
|
||||||
#include <SDKDDKVer.h>
|
|
|
@ -1,468 +0,0 @@
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Copyright (C) 2017, Carnegie Mellon University and University of Cambridge,
|
|
||||||
// all rights reserved.
|
|
||||||
//
|
|
||||||
// ACADEMIC OR NON-PROFIT ORGANIZATION NONCOMMERCIAL RESEARCH USE ONLY
|
|
||||||
//
|
|
||||||
// BY USING OR DOWNLOADING THE SOFTWARE, YOU ARE AGREEING TO THE TERMS OF THIS LICENSE AGREEMENT.
|
|
||||||
// IF YOU DO NOT AGREE WITH THESE TERMS, YOU MAY NOT USE OR DOWNLOAD THE SOFTWARE.
|
|
||||||
//
|
|
||||||
// License can be found in OpenFace-license.txt
|
|
||||||
|
|
||||||
// * Any publications arising from the use of this software, including but
|
|
||||||
// not limited to academic journal and conference publications, technical
|
|
||||||
// reports and manuals, must cite at least one of the following works:
|
|
||||||
//
|
|
||||||
// OpenFace: an open source facial behavior analysis toolkit
|
|
||||||
// Tadas Baltrušaitis, Peter Robinson, and Louis-Philippe Morency
|
|
||||||
// in IEEE Winter Conference on Applications of Computer Vision, 2016
|
|
||||||
//
|
|
||||||
// Rendering of Eyes for Eye-Shape Registration and Gaze Estimation
|
|
||||||
// Erroll Wood, Tadas Baltrušaitis, Xucong Zhang, Yusuke Sugano, Peter Robinson, and Andreas Bulling
|
|
||||||
// in IEEE International. Conference on Computer Vision (ICCV), 2015
|
|
||||||
//
|
|
||||||
// Cross-dataset learning and person-speci?c normalisation for automatic Action Unit detection
|
|
||||||
// Tadas Baltrušaitis, Marwa Mahmoud, and Peter Robinson
|
|
||||||
// in Facial Expression Recognition and Analysis Challenge,
|
|
||||||
// IEEE International Conference on Automatic Face and Gesture Recognition, 2015
|
|
||||||
//
|
|
||||||
// Constrained Local Neural Fields for robust facial landmark detection in the wild.
|
|
||||||
// Tadas Baltrušaitis, Peter Robinson, and Louis-Philippe Morency.
|
|
||||||
// in IEEE Int. Conference on Computer Vision Workshops, 300 Faces in-the-Wild Challenge, 2013.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// Camera_Interop.h
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#pragma unmanaged
|
|
||||||
|
|
||||||
// Include all the unmanaged things we need.
|
|
||||||
|
|
||||||
#include <opencv2/core/core.hpp>
|
|
||||||
#include "opencv2/objdetect.hpp"
|
|
||||||
#include "opencv2/calib3d.hpp"
|
|
||||||
#include <opencv2/imgcodecs.hpp>
|
|
||||||
#include <opencv2/imgproc.hpp>
|
|
||||||
#include <opencv2/highgui/highgui.hpp>
|
|
||||||
#include <vector>
|
|
||||||
#include <set>
|
|
||||||
|
|
||||||
#include <OpenCVWrappers.h>
|
|
||||||
|
|
||||||
// For camera listings
|
|
||||||
#include "comet_auto_mf.h"
|
|
||||||
#include "camera_helper.h"
|
|
||||||
|
|
||||||
#pragma managed
|
|
||||||
|
|
||||||
#include <msclr\marshal.h>
|
|
||||||
#include <msclr\marshal_cppstd.h>
|
|
||||||
|
|
||||||
namespace CameraInterop {
|
|
||||||
|
|
||||||
public ref class CaptureFailedException : System::Exception
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
CaptureFailedException(System::String^ message): Exception(message){}
|
|
||||||
};
|
|
||||||
|
|
||||||
public ref class Capture
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
|
|
||||||
// OpenCV based video capture for reading from files
|
|
||||||
cv::VideoCapture* vc;
|
|
||||||
|
|
||||||
OpenCVWrappers::RawImage^ latestFrame;
|
|
||||||
OpenCVWrappers::RawImage^ grayFrame;
|
|
||||||
|
|
||||||
double fps;
|
|
||||||
|
|
||||||
bool is_webcam;
|
|
||||||
bool is_image_seq;
|
|
||||||
|
|
||||||
int frame_num;
|
|
||||||
std::vector<std::string>* image_files;
|
|
||||||
|
|
||||||
int vid_length;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
int width, height;
|
|
||||||
|
|
||||||
Capture(int device, int width, int height)
|
|
||||||
{
|
|
||||||
assert(device >= 0);
|
|
||||||
|
|
||||||
latestFrame = gcnew OpenCVWrappers::RawImage();
|
|
||||||
|
|
||||||
vc = new cv::VideoCapture(device);
|
|
||||||
vc->set(CV_CAP_PROP_FRAME_WIDTH, width);
|
|
||||||
vc->set(CV_CAP_PROP_FRAME_HEIGHT, height);
|
|
||||||
|
|
||||||
is_webcam = true;
|
|
||||||
is_image_seq = false;
|
|
||||||
|
|
||||||
this->width = width;
|
|
||||||
this->height = height;
|
|
||||||
|
|
||||||
vid_length = 0;
|
|
||||||
frame_num = 0;
|
|
||||||
|
|
||||||
int set_width = vc->get(CV_CAP_PROP_FRAME_WIDTH);
|
|
||||||
int set_height = vc->get(CV_CAP_PROP_FRAME_HEIGHT);
|
|
||||||
|
|
||||||
if(!vc->isOpened())
|
|
||||||
{
|
|
||||||
throw gcnew CaptureFailedException("Failed to open the webcam");
|
|
||||||
}
|
|
||||||
if(set_width != width || set_height != height)
|
|
||||||
{
|
|
||||||
throw gcnew CaptureFailedException("Failed to open the webcam with desired resolution");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Capture(System::String^ videoFile)
|
|
||||||
{
|
|
||||||
latestFrame = gcnew OpenCVWrappers::RawImage();
|
|
||||||
|
|
||||||
vc = new cv::VideoCapture(msclr::interop::marshal_as<std::string>(videoFile));
|
|
||||||
fps = vc->get(CV_CAP_PROP_FPS);
|
|
||||||
is_webcam = false;
|
|
||||||
is_image_seq = false;
|
|
||||||
this->width = vc->get(CV_CAP_PROP_FRAME_WIDTH);
|
|
||||||
this->height = vc->get(CV_CAP_PROP_FRAME_HEIGHT);
|
|
||||||
|
|
||||||
vid_length = vc->get(CV_CAP_PROP_FRAME_COUNT);
|
|
||||||
frame_num = 0;
|
|
||||||
|
|
||||||
if(!vc->isOpened())
|
|
||||||
{
|
|
||||||
throw gcnew CaptureFailedException("Failed to open the video file");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// An alternative to using video files is using image sequences
|
|
||||||
Capture(System::Collections::Generic::List<System::String^>^ image_files)
|
|
||||||
{
|
|
||||||
|
|
||||||
latestFrame = gcnew OpenCVWrappers::RawImage();
|
|
||||||
|
|
||||||
is_webcam = false;
|
|
||||||
is_image_seq = true;
|
|
||||||
this->image_files = new std::vector<std::string>();
|
|
||||||
|
|
||||||
for(int i = 0; i < image_files->Count; ++i)
|
|
||||||
{
|
|
||||||
this->image_files->push_back(msclr::interop::marshal_as<std::string>(image_files[i]));
|
|
||||||
}
|
|
||||||
vid_length = image_files->Count;
|
|
||||||
|
|
||||||
// Read the first frame to determine the capture width and height
|
|
||||||
cv::Mat tmp = cv::imread(this->image_files->at(0));
|
|
||||||
|
|
||||||
if (tmp.empty())
|
|
||||||
{
|
|
||||||
throw gcnew CaptureFailedException("Failed to open image sequence");
|
|
||||||
}
|
|
||||||
|
|
||||||
this->width = tmp.size().width;
|
|
||||||
this->height = tmp.size().height;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static void split(const std::string &s, char delim, std::vector<string> &elems) {
|
|
||||||
std::stringstream ss;
|
|
||||||
ss.str(s);
|
|
||||||
std::string item;
|
|
||||||
while (std::getline(ss, item, delim)) {
|
|
||||||
elems.push_back(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static System::Collections::Generic::Dictionary<System::String^, System::Collections::Generic::List<System::Tuple<int,int>^>^>^ GetListingFromFile(std::string filename)
|
|
||||||
{
|
|
||||||
// Check what cameras have been written (using OpenCVs XML packages)
|
|
||||||
cv::FileStorage fs_read(filename, cv::FileStorage::READ);
|
|
||||||
|
|
||||||
auto managed_camera_list_initial = gcnew System::Collections::Generic::Dictionary<System::String^, System::Collections::Generic::List<System::Tuple<int,int>^>^>();
|
|
||||||
|
|
||||||
cv::FileNode camera_node_list = fs_read["cameras"];
|
|
||||||
|
|
||||||
// iterate through a sequence using FileNodeIterator
|
|
||||||
for(size_t idx = 0; idx < camera_node_list.size(); idx++ )
|
|
||||||
{
|
|
||||||
std::string camera_name = (std::string)camera_node_list[idx]["name"];
|
|
||||||
|
|
||||||
cv::FileNode resolution_list = camera_node_list[idx]["resolutions"];
|
|
||||||
auto resolutions = gcnew System::Collections::Generic::List<System::Tuple<int, int>^>();
|
|
||||||
for(size_t r_idx = 0; r_idx < resolution_list.size(); r_idx++ )
|
|
||||||
{
|
|
||||||
string res = resolution_list[r_idx]["res"];
|
|
||||||
|
|
||||||
std::vector<std::string> elems;
|
|
||||||
split(res, 'x', elems);
|
|
||||||
|
|
||||||
int x = stoi(elems[0]);
|
|
||||||
int y = stoi(elems[1]);
|
|
||||||
resolutions->Add(gcnew System::Tuple<int,int>(x, y));
|
|
||||||
}
|
|
||||||
managed_camera_list_initial[gcnew System::String(camera_name.c_str())] = resolutions;
|
|
||||||
}
|
|
||||||
fs_read.release();
|
|
||||||
return managed_camera_list_initial;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void WriteCameraListingToFile(System::Collections::Generic::Dictionary<System::String^, System::Collections::Generic::List<System::Tuple<int,int>^>^>^ camera_list, std::string filename)
|
|
||||||
{
|
|
||||||
cv::FileStorage fs("camera_list.xml", cv::FileStorage::WRITE);
|
|
||||||
|
|
||||||
fs << "cameras" << "[";
|
|
||||||
for each( System::String^ name_m in camera_list->Keys )
|
|
||||||
{
|
|
||||||
|
|
||||||
std::string name = msclr::interop::marshal_as<std::string>(name_m);
|
|
||||||
|
|
||||||
fs << "{:" << "name" << name;
|
|
||||||
fs << "resolutions" << "[";
|
|
||||||
auto resolutions = camera_list[name_m];
|
|
||||||
for(int j = 0; j < resolutions->Count; j++)
|
|
||||||
{
|
|
||||||
stringstream ss;
|
|
||||||
ss << resolutions[j]->Item1 << "x" << resolutions[j]->Item2;
|
|
||||||
|
|
||||||
fs << "{:" << "res" << ss.str();
|
|
||||||
fs<< "}";
|
|
||||||
}
|
|
||||||
fs << "]";
|
|
||||||
fs << "}";
|
|
||||||
}
|
|
||||||
fs << "]";
|
|
||||||
fs.release();
|
|
||||||
}
|
|
||||||
|
|
||||||
static System::Collections::Generic::List<System::Tuple<System::String^, System::Collections::Generic::List<System::Tuple<int,int>^>^, OpenCVWrappers::RawImage^>^>^ GetCameras(System::String^ root_directory_m)
|
|
||||||
{
|
|
||||||
std::string root_directory = msclr::interop::marshal_as<std::string>(root_directory_m);
|
|
||||||
auto managed_camera_list_initial = GetListingFromFile(root_directory + "camera_list.xml");
|
|
||||||
|
|
||||||
auto managed_camera_list = gcnew System::Collections::Generic::List<System::Tuple<System::String^, System::Collections::Generic::List<System::Tuple<int,int>^>^, OpenCVWrappers::RawImage^>^>();
|
|
||||||
|
|
||||||
// Using DirectShow for capturing from webcams (for MJPG as has issues with other formats)
|
|
||||||
comet::auto_mf auto_mf;
|
|
||||||
|
|
||||||
std::vector<camera> cameras = camera_helper::get_all_cameras();
|
|
||||||
|
|
||||||
// A Surface Pro specific hack, it seems to list webcams in a weird way
|
|
||||||
for (size_t i = 0; i < cameras.size(); ++i)
|
|
||||||
{
|
|
||||||
cameras[i].activate();
|
|
||||||
std::string name = cameras[i].name();
|
|
||||||
|
|
||||||
// TODO, something is odd here
|
|
||||||
//if(name.compare("Microsoft LifeCam Front") == 0)
|
|
||||||
//{
|
|
||||||
// cameras.push_back(cameras[i]);
|
|
||||||
// cameras.erase(cameras.begin() + i);
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
for (size_t i = 0; i < cameras.size(); ++i)
|
|
||||||
{
|
|
||||||
cameras[i].activate();
|
|
||||||
std::string name = cameras[i].name();
|
|
||||||
System::String^ name_managed = gcnew System::String(name.c_str());
|
|
||||||
|
|
||||||
// List camera media types
|
|
||||||
auto media_types = cameras[i].media_types();
|
|
||||||
|
|
||||||
System::Collections::Generic::List<System::Tuple<int,int>^>^ resolutions;
|
|
||||||
std::set<std::pair<int, int>> res_set;
|
|
||||||
|
|
||||||
// If we have them just use pre-loaded resolutions
|
|
||||||
if(managed_camera_list_initial->ContainsKey(name_managed))
|
|
||||||
{
|
|
||||||
resolutions = managed_camera_list_initial[name_managed];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
resolutions = gcnew System::Collections::Generic::List<System::Tuple<int,int>^>();
|
|
||||||
for (size_t m = 0; m < media_types.size(); ++m)
|
|
||||||
{
|
|
||||||
auto media_type_curr = media_types[m];
|
|
||||||
res_set.insert(std::pair<int, int>(std::pair<int,int>(media_type_curr.resolution().width, media_type_curr.resolution().height)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Grab some sample images and confirm the resolutions
|
|
||||||
cv::VideoCapture cap1(i);
|
|
||||||
// Go through resolutions if they have not been identified
|
|
||||||
if(resolutions->Count == 0)
|
|
||||||
{
|
|
||||||
for (auto beg = res_set.begin(); beg != res_set.end(); ++beg)
|
|
||||||
{
|
|
||||||
auto resolution = gcnew System::Tuple<int, int>(beg->first, beg->first);
|
|
||||||
|
|
||||||
cap1.set(CV_CAP_PROP_FRAME_WIDTH, resolution->Item1);
|
|
||||||
cap1.set(CV_CAP_PROP_FRAME_HEIGHT, resolution->Item2);
|
|
||||||
|
|
||||||
// Add only valid resolutions as API sometimes provides wrong ones
|
|
||||||
int set_width = cap1.get(CV_CAP_PROP_FRAME_WIDTH);
|
|
||||||
int set_height = cap1.get(CV_CAP_PROP_FRAME_HEIGHT);
|
|
||||||
|
|
||||||
resolution = gcnew System::Tuple<int, int>(set_width, set_height);
|
|
||||||
if(!resolutions->Contains(resolution))
|
|
||||||
{
|
|
||||||
resolutions->Add(resolution);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
managed_camera_list_initial[name_managed] = resolutions;
|
|
||||||
}
|
|
||||||
|
|
||||||
cv::Mat sample_img;
|
|
||||||
OpenCVWrappers::RawImage^ sample_img_managed = gcnew OpenCVWrappers::RawImage();
|
|
||||||
|
|
||||||
// Now that the resolutions have been identified, pick a camera and create a thumbnail
|
|
||||||
if(resolutions->Count > 0)
|
|
||||||
{
|
|
||||||
int resolution_ind = resolutions->Count / 2;
|
|
||||||
|
|
||||||
if(resolution_ind >= resolutions->Count)
|
|
||||||
resolution_ind = resolutions->Count - 1;
|
|
||||||
|
|
||||||
auto resolution = resolutions[resolution_ind];
|
|
||||||
|
|
||||||
cap1.set(CV_CAP_PROP_FRAME_WIDTH, resolution->Item1);
|
|
||||||
cap1.set(CV_CAP_PROP_FRAME_HEIGHT, resolution->Item2);
|
|
||||||
|
|
||||||
for (int k = 0; k < 5; ++k)
|
|
||||||
cap1.read(sample_img);
|
|
||||||
|
|
||||||
// Flip horizontally
|
|
||||||
cv::flip(sample_img, sample_img, 1);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
cap1.~VideoCapture();
|
|
||||||
|
|
||||||
sample_img.copyTo(sample_img_managed->Mat);
|
|
||||||
|
|
||||||
managed_camera_list->Add(gcnew System::Tuple<System::String^, System::Collections::Generic::List<System::Tuple<int,int>^>^, OpenCVWrappers::RawImage^>(gcnew System::String(name.c_str()), resolutions, sample_img_managed));
|
|
||||||
}
|
|
||||||
|
|
||||||
WriteCameraListingToFile(managed_camera_list_initial, root_directory + "camera_list.xml");
|
|
||||||
|
|
||||||
return managed_camera_list;
|
|
||||||
}
|
|
||||||
|
|
||||||
OpenCVWrappers::RawImage^ GetNextFrame(bool mirror)
|
|
||||||
{
|
|
||||||
frame_num++;
|
|
||||||
|
|
||||||
if(vc != nullptr)
|
|
||||||
{
|
|
||||||
|
|
||||||
bool success = vc->read(latestFrame->Mat);
|
|
||||||
|
|
||||||
if (!success)
|
|
||||||
{
|
|
||||||
// Indicate lack of success by returning an empty image
|
|
||||||
cv::Mat empty_mat = cv::Mat();
|
|
||||||
empty_mat.copyTo(latestFrame->Mat);
|
|
||||||
return latestFrame;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(is_image_seq)
|
|
||||||
{
|
|
||||||
if(image_files->empty())
|
|
||||||
{
|
|
||||||
// Indicate lack of success by returning an empty image
|
|
||||||
cv::Mat empty_mat = cv::Mat();
|
|
||||||
empty_mat.copyTo(latestFrame->Mat);
|
|
||||||
return latestFrame;
|
|
||||||
}
|
|
||||||
|
|
||||||
cv::Mat img = cv::imread(image_files->at(0), -1);
|
|
||||||
img.copyTo(latestFrame->Mat);
|
|
||||||
// Remove the first frame
|
|
||||||
image_files->erase(image_files->begin(), image_files->begin() + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (grayFrame == nullptr) {
|
|
||||||
if (latestFrame->Width > 0) {
|
|
||||||
grayFrame = gcnew OpenCVWrappers::RawImage(latestFrame->Width, latestFrame->Height, CV_8UC1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(mirror)
|
|
||||||
{
|
|
||||||
flip(latestFrame->Mat, latestFrame->Mat, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (grayFrame != nullptr) {
|
|
||||||
cvtColor(latestFrame->Mat, grayFrame->Mat, CV_BGR2GRAY);
|
|
||||||
}
|
|
||||||
|
|
||||||
return latestFrame;
|
|
||||||
}
|
|
||||||
|
|
||||||
double GetProgress()
|
|
||||||
{
|
|
||||||
if(vc != nullptr && is_webcam)
|
|
||||||
{
|
|
||||||
return - 1.0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return (double)frame_num / (double)vid_length;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isOpened()
|
|
||||||
{
|
|
||||||
if(vc != nullptr)
|
|
||||||
return vc->isOpened();
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(is_image_seq && image_files->size() > 0)
|
|
||||||
return true;
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
OpenCVWrappers::RawImage^ GetCurrentFrameGray() {
|
|
||||||
return grayFrame;
|
|
||||||
}
|
|
||||||
|
|
||||||
double GetFPS() {
|
|
||||||
return fps;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Finalizer. Definitely called before Garbage Collection,
|
|
||||||
// but not automatically called on explicit Dispose().
|
|
||||||
// May be called multiple times.
|
|
||||||
!Capture()
|
|
||||||
{
|
|
||||||
// Automatically closes capture object before freeing memory.
|
|
||||||
if(vc != nullptr)
|
|
||||||
{
|
|
||||||
vc->~VideoCapture();
|
|
||||||
}
|
|
||||||
if(image_files != nullptr)
|
|
||||||
delete image_files;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Destructor. Called on explicit Dispose() only.
|
|
||||||
~Capture()
|
|
||||||
{
|
|
||||||
this->!Capture();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
|
@ -66,7 +66,6 @@
|
||||||
<Import Project="..\..\3rdParty\dlib\dlib.props" />
|
<Import Project="..\..\3rdParty\dlib\dlib.props" />
|
||||||
<Import Project="..\..\3rdParty\boost\boost_d.props" />
|
<Import Project="..\..\3rdParty\boost\boost_d.props" />
|
||||||
<Import Project="..\..\3rdParty\tbb\tbb_d.props" />
|
<Import Project="..\..\3rdParty\tbb\tbb_d.props" />
|
||||||
<Import Project="..\CamCom\CamCom.props" />
|
|
||||||
<Import Project="..\..\3rdParty\OpenBLAS\OpenBLAS.props" />
|
<Import Project="..\..\3rdParty\OpenBLAS\OpenBLAS.props" />
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
@ -75,7 +74,6 @@
|
||||||
<Import Project="..\..\3rdParty\dlib\dlib.props" />
|
<Import Project="..\..\3rdParty\dlib\dlib.props" />
|
||||||
<Import Project="..\..\3rdParty\boost\boost.props" />
|
<Import Project="..\..\3rdParty\boost\boost.props" />
|
||||||
<Import Project="..\..\3rdParty\tbb\tbb.props" />
|
<Import Project="..\..\3rdParty\tbb\tbb.props" />
|
||||||
<Import Project="..\CamCom\CamCom.props" />
|
|
||||||
<Import Project="..\..\3rdParty\OpenBLAS\OpenBLAS.props" />
|
<Import Project="..\..\3rdParty\OpenBLAS\OpenBLAS.props" />
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
@ -84,7 +82,6 @@
|
||||||
<Import Project="..\..\3rdParty\dlib\dlib.props" />
|
<Import Project="..\..\3rdParty\dlib\dlib.props" />
|
||||||
<Import Project="..\..\3rdParty\boost\boost_d.props" />
|
<Import Project="..\..\3rdParty\boost\boost_d.props" />
|
||||||
<Import Project="..\..\3rdParty\tbb\tbb_d.props" />
|
<Import Project="..\..\3rdParty\tbb\tbb_d.props" />
|
||||||
<Import Project="..\CamCom\CamCom.props" />
|
|
||||||
<Import Project="..\..\3rdParty\OpenBLAS\OpenBLAS.props" />
|
<Import Project="..\..\3rdParty\OpenBLAS\OpenBLAS.props" />
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
@ -93,7 +90,6 @@
|
||||||
<Import Project="..\..\3rdParty\dlib\dlib.props" />
|
<Import Project="..\..\3rdParty\dlib\dlib.props" />
|
||||||
<Import Project="..\..\3rdParty\boost\boost.props" />
|
<Import Project="..\..\3rdParty\boost\boost.props" />
|
||||||
<Import Project="..\..\3rdParty\tbb\tbb.props" />
|
<Import Project="..\..\3rdParty\tbb\tbb.props" />
|
||||||
<Import Project="..\CamCom\CamCom.props" />
|
|
||||||
<Import Project="..\..\3rdParty\OpenBLAS\OpenBLAS.props" />
|
<Import Project="..\..\3rdParty\OpenBLAS\OpenBLAS.props" />
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
<PropertyGroup Label="UserMacros" />
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
@ -178,7 +174,6 @@
|
||||||
<ClCompile Include="CppInterop.cpp" />
|
<ClCompile Include="CppInterop.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="CameraInterop.h" />
|
|
||||||
<ClInclude Include="FaceAnalyserInterop.h" />
|
<ClInclude Include="FaceAnalyserInterop.h" />
|
||||||
<ClInclude Include="GazeAnalyserInterop.h" />
|
<ClInclude Include="GazeAnalyserInterop.h" />
|
||||||
<ClInclude Include="ImageReader.h" />
|
<ClInclude Include="ImageReader.h" />
|
||||||
|
@ -196,9 +191,6 @@
|
||||||
<ProjectReference Include="..\..\3rdParty\dlib\dlib.vcxproj">
|
<ProjectReference Include="..\..\3rdParty\dlib\dlib.vcxproj">
|
||||||
<Project>{b47a5f12-2567-44e9-ae49-35763ec82149}</Project>
|
<Project>{b47a5f12-2567-44e9-ae49-35763ec82149}</Project>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
<ProjectReference Include="..\CamCom\CamCom.vcxproj">
|
|
||||||
<Project>{0cec6a75-17ba-4dc5-9405-c74154921e60}</Project>
|
|
||||||
</ProjectReference>
|
|
||||||
<ProjectReference Include="..\FaceAnalyser\FaceAnalyser.vcxproj">
|
<ProjectReference Include="..\FaceAnalyser\FaceAnalyser.vcxproj">
|
||||||
<Project>{0e7fc556-0e80-45ea-a876-dde4c2fedcd7}</Project>
|
<Project>{0e7fc556-0e80-45ea-a876-dde4c2fedcd7}</Project>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
|
|
|
@ -29,9 +29,6 @@
|
||||||
<ClInclude Include="OpenCVWrappers.h">
|
<ClInclude Include="OpenCVWrappers.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="CameraInterop.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="FaceAnalyserInterop.h">
|
<ClInclude Include="FaceAnalyserInterop.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
|
|
@ -37,7 +37,6 @@
|
||||||
#include "FaceAnalyserInterop.h"
|
#include "FaceAnalyserInterop.h"
|
||||||
#include "GazeAnalyserInterop.h"
|
#include "GazeAnalyserInterop.h"
|
||||||
#include "OpenCVWrappers.h"
|
#include "OpenCVWrappers.h"
|
||||||
#include "CameraInterop.h"
|
|
||||||
#include "ImageReader.h"
|
#include "ImageReader.h"
|
||||||
#include "FaceDetectorInterop.h"
|
#include "FaceDetectorInterop.h"
|
||||||
#include "RecorderInterop.h"
|
#include "RecorderInterop.h"
|
||||||
|
|
Loading…
Reference in a new issue