Restructure repository to include all source folders

Move git root from Client/ to src/ to track all source code:
- Client: Game client source (moved to Client/Client/)
- Server: Game server source
- GameTools: Development tools
- CryptoSource: Encryption utilities
- database: Database scripts
- Script: Game scripts
- rylCoder_16.02.2008_src: Legacy coder tools
- GMFont, Game: Additional resources

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-29 20:17:20 +09:00
parent 5d3cd64a25
commit dd97ddec92
11602 changed files with 1446576 additions and 0 deletions

View File

@@ -0,0 +1,612 @@
<?xml version="1.0" encoding="ks_c_5601-1987"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="BaseLibrary"
ProjectGUID="{585CFC82-602A-466B-8E86-1A4FD1D442CA}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../Library/$(ConfigurationName)"
IntermediateDirectory="../../Intermediate/$(ProjectName)/$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="./;../;../MemoryManager"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
AdditionalDependencies="ws2_32.lib"
OutputFile="$(OutDir)/BaseLibrary.lib"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="../../Library/$(ConfigurationName)"
IntermediateDirectory="../../Intermediate/$(ProjectName)/$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="./;../;../MemoryManager"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
RuntimeLibrary="0"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
AdditionalDependencies="ws2_32.lib"
OutputFile="$(OutDir)/BaseLibrary.lib"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release_NoGD|Win32"
OutputDirectory="../../Library/$(ConfigurationName)"
IntermediateDirectory="../../Intermediate/$(ProjectName)/$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="./;../;../MemoryManager"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
RuntimeLibrary="0"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
AdditionalDependencies="ws2_32.lib"
OutputFile="$(OutDir)/BaseLibrary.lib"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Debug_NoGD|Win32"
OutputDirectory="../../Library/$(ConfigurationName)"
IntermediateDirectory="../../Intermediate/$(ProjectName)/$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="./;../;../MemoryManager"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
AdditionalDependencies="ws2_32.lib"
OutputFile="$(OutDir)/BaseLibrary.lib"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release_MY|Win32"
OutputDirectory="../../Library/$(ConfigurationName)"
IntermediateDirectory="../../Intermediate/$(ProjectName)/$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="./;../;../MemoryManager"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
RuntimeLibrary="0"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
AdditionalDependencies="ws2_32.lib"
OutputFile="$(OutDir)/BaseLibrary.lib"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Debug_MY|Win32"
OutputDirectory="../../Library/$(ConfigurationName)"
IntermediateDirectory="../../Intermediate/$(ProjectName)/$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="./;../;../MemoryManager"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
AdditionalDependencies="ws2_32.lib"
OutputFile="$(OutDir)/BaseLibrary.lib"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Network"
Filter="">
<Filter
Name="Dispatch"
Filter="">
<File
RelativePath=".\Network\Dispatch\Dispatch.cpp">
</File>
<File
RelativePath=".\Network\Dispatch\Dispatch.h">
</File>
<File
RelativePath=".\Network\Dispatch\PoolDispatchFactory.h">
</File>
<File
RelativePath=".\Network\Dispatch\ServerRequest.cpp">
</File>
<File
RelativePath=".\Network\Dispatch\ServerRequest.h">
</File>
</Filter>
<Filter
Name="IOCP"
Filter="">
<File
RelativePath=".\Network\Iocp\CompletionHandler.cpp">
</File>
<File
RelativePath=".\Network\Iocp\CompletionHandler.h">
</File>
<File
RelativePath=".\Network\Iocp\IOCPNet.cpp">
</File>
<File
RelativePath=".\Network\Iocp\IOCPNet.h">
</File>
<File
RelativePath=".\Network\Iocp\IOWorker.cpp">
</File>
<File
RelativePath=".\Network\Iocp\IOWorker.h">
</File>
<File
RelativePath=".\Network\Iocp\Overlapped.cpp">
</File>
<File
RelativePath=".\Network\Iocp\Overlapped.h">
</File>
</Filter>
<Filter
Name="Listener"
Filter="">
<File
RelativePath=".\Network\Listener\Listener.cpp">
</File>
<File
RelativePath=".\Network\Listener\Listener.h">
</File>
</Filter>
<Filter
Name="Session"
Filter="">
<File
RelativePath=".\Network\Session\Session.cpp">
</File>
<File
RelativePath=".\Network\Session\Session.h">
</File>
<File
RelativePath=".\Network\Session\SessionMgr.cpp">
</File>
<File
RelativePath=".\Network\Session\SessionMgr.h">
</File>
<File
RelativePath=".\Network\Session\SessionPolicy.cpp">
</File>
<File
RelativePath=".\Network\Session\SessionPolicy.h">
</File>
</Filter>
<Filter
Name="Winsock"
Filter="">
<File
RelativePath=".\Network\Winsock\SocketFactory.cpp">
</File>
<File
RelativePath=".\Network\Winsock\SocketFactory.h">
</File>
</Filter>
<Filter
Name="Address"
Filter="">
<File
RelativePath=".\Network\Address\INET_Addr.cpp">
</File>
<File
RelativePath=".\Network\Address\INET_Addr.h">
</File>
</Filter>
</Filter>
<Filter
Name="Stream"
Filter="">
<Filter
Name="Buffer"
Filter="">
<File
RelativePath=".\Stream\Buffer\Buffer.cpp">
</File>
<File
RelativePath=".\Stream\Buffer\Buffer.h">
</File>
<File
RelativePath=".\Stream\Buffer\BufferFactory.cpp">
</File>
<File
RelativePath=".\Stream\Buffer\BufferFactory.h">
</File>
<File
RelativePath=".\Stream\Buffer\BufferQueue.cpp">
</File>
<File
RelativePath=".\Stream\Buffer\BufferQueue.h">
</File>
</Filter>
</Filter>
<Filter
Name="Thread"
Filter="">
<File
RelativePath=".\Thread\Lock.h">
</File>
<File
RelativePath=".\Thread\Thread.h">
</File>
<File
RelativePath=".\Thread\ThreadMgr.cpp">
</File>
<File
RelativePath=".\Thread\ThreadMgr.h">
</File>
</Filter>
<Filter
Name="Log"
Filter="">
<File
RelativePath=".\Log\ServerLog.cpp">
</File>
<File
RelativePath=".\Log\ServerLog.h">
</File>
<File
RelativePath=".\Log\ServerLogDefine.h">
</File>
</Filter>
<Filter
Name="Utility"
Filter="">
<Filter
Name="Debug"
Filter="">
<File
RelativePath=".\Utility\Debug\DebugMacros.h">
</File>
<File
RelativePath=".\Utility\Debug\DebugUtils.cpp">
</File>
<File
RelativePath=".\Utility\Debug\DebugUtils.h">
</File>
<File
RelativePath=".\Utility\Debug\DLLModule.h">
</File>
<File
RelativePath=".\Utility\Debug\ExceptionReport.cpp">
</File>
<File
RelativePath=".\Utility\Debug\ExceptionReport.h">
</File>
<File
RelativePath=".\Utility\Debug\PerformanceCheck.cpp">
</File>
<File
RelativePath=".\Utility\Debug\PerformanceCheck.h">
</File>
</Filter>
<Filter
Name="Math"
Filter="">
<File
RelativePath=".\Utility\Math\Convert.inl">
</File>
<File
RelativePath=".\Utility\Math\Math.cpp">
</File>
<File
RelativePath=".\Utility\Math\Math.h">
</File>
<File
RelativePath=".\Utility\Math\PseudoRandom.cpp">
</File>
<File
RelativePath=".\Utility\Math\PseudoRandom.h">
</File>
<File
RelativePath=".\Utility\Math\Random.cpp">
</File>
<File
RelativePath=".\Utility\Math\Random.h">
</File>
</Filter>
<Filter
Name="Compress"
Filter="">
<Filter
Name="MiniLZO"
Filter="">
<File
RelativePath=".\Utility\Compress\MiniLZO\lzoconf.h">
</File>
<File
RelativePath=".\Utility\Compress\MiniLZO\minilzo.cpp">
</File>
<File
RelativePath=".\Utility\Compress\MiniLZO\minilzo.h">
</File>
<File
RelativePath=".\Utility\Compress\MiniLZO\miniLZOWrapper.cpp">
</File>
<File
RelativePath=".\Utility\Compress\MiniLZO\miniLZOWrapper.h">
</File>
</Filter>
</Filter>
<Filter
Name="Registry"
Filter="">
<File
RelativePath=".\Utility\Registry\RegFunctions.cpp">
</File>
<File
RelativePath=".\Utility\Registry\RegFunctions.h">
</File>
</Filter>
<Filter
Name="Resource"
Filter="">
<File
RelativePath=".\Utility\Resource\EnsureCleanup.h">
</File>
</Filter>
<Filter
Name="Time"
Filter="">
<Filter
Name="Pulse"
Filter="">
<File
RelativePath=".\Utility\Time\Pulse\Pulse.cpp">
</File>
<File
RelativePath=".\Utility\Time\Pulse\Pulse.h">
</File>
</Filter>
</Filter>
<Filter
Name="CheckSum"
Filter="">
<File
RelativePath=".\Utility\checksum\Common.h">
</File>
<File
RelativePath=".\Utility\checksum\Crc32Static.cpp">
</File>
<File
RelativePath=".\Utility\checksum\Crc32Static.h">
</File>
<File
RelativePath=".\Utility\checksum\Crc8Static.cpp">
</File>
<File
RelativePath=".\Utility\checksum\Crc8Static.h">
</File>
</Filter>
<Filter
Name="File"
Filter="">
<File
RelativePath=".\Utility\File\MappedFile.cpp">
</File>
<File
RelativePath=".\Utility\File\MappedFile.h">
</File>
</Filter>
</Filter>
<Filter
Name="Pattern"
Filter="">
<File
RelativePath=".\Pattern\Command.cpp">
</File>
<File
RelativePath=".\Pattern\Command.h">
</File>
<File
RelativePath=".\Pattern\CommandQueue.cpp">
</File>
<File
RelativePath=".\Pattern\CommandQueue.h">
</File>
<File
RelativePath=".\Pattern\Singleton.h">
</File>
</Filter>
<Filter
Name="DB"
Filter="">
<File
RelativePath=".\Db\OLEDB.cpp">
</File>
<File
RelativePath=".\Db\OLEDB.h">
</File>
</Filter>
<Filter
Name="Memory"
Filter="">
<File
RelativePath=".\Memory\MemoryPool.cpp">
</File>
<File
RelativePath=".\Memory\MemoryPool.h">
</File>
</Filter>
<File
RelativePath=".\stdafx.cpp">
</File>
<File
RelativePath=".\stdafx.h">
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -0,0 +1,319 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug_MY|Win32">
<Configuration>Debug_MY</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug_NoGD|Win32">
<Configuration>Debug_NoGD</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release_MY|Win32">
<Configuration>Release_MY</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release_NoGD|Win32">
<Configuration>Release_NoGD</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{585CFC82-602A-466B-8E86-1A4FD1D442CA}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_MY|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_MY|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoGD|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_NoGD|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_MY|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release_MY|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoGD|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release_NoGD|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../../Library/$(Configuration)/</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../../Intermediate/$(ProjectName)/$(Configuration)\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../../Library/$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../../Intermediate/$(ProjectName)/$(Configuration)\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release_NoGD|Win32'">../../Library/$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release_NoGD|Win32'">../../Intermediate/$(ProjectName)/$(Configuration)\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoGD|Win32'">../../Library/$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoGD|Win32'">../../Intermediate/$(ProjectName)/$(Configuration)\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release_MY|Win32'">../../Library/$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release_MY|Win32'">../../Intermediate/$(ProjectName)/$(Configuration)\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_MY|Win32'">../../Library/$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_MY|Win32'">../../Intermediate/$(ProjectName)/$(Configuration)\</IntDir>
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug_MY|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug_MY|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug_MY|Win32'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug_NoGD|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug_NoGD|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug_NoGD|Win32'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release_MY|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release_MY|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release_MY|Win32'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release_NoGD|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release_NoGD|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release_NoGD|Win32'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IncludePath);C:\project\trunk\Client\Library\dxx8\include</IncludePath>
<LibraryPath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">C:\project\trunk\Client\Library\dxx8\lib;$(LibraryPath)</LibraryPath>
<IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IncludePath);C:\project\trunk\Client\Library\dxx8\include</IncludePath>
<LibraryPath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">C:\project\trunk\Client\Library\dxx8\lib;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>./;../;../MemoryManager;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<OpenMPSupport>
</OpenMPSupport>
</ClCompile>
<Lib>
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)BaseLibrary.lib</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>./;../;../MemoryManager;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;NO_GAMEGUARD;_LIB;_USE_32BIT_TIME_T;</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
<OpenMPSupport>true</OpenMPSupport>
</ClCompile>
<Lib>
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)BaseLibrary.lib</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release_NoGD|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>./;../;../MemoryManager;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Lib>
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)BaseLibrary.lib</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoGD|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>./;../;../MemoryManager;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
</ClCompile>
<Lib>
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)BaseLibrary.lib</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release_MY|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>./;../;../MemoryManager;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Lib>
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)BaseLibrary.lib</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_MY|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>./;../;../MemoryManager;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
</ClCompile>
<Lib>
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)BaseLibrary.lib</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="Network\Dispatch\Dispatch.cpp" />
<ClCompile Include="Network\Dispatch\ServerRequest.cpp" />
<ClCompile Include="Network\Iocp\CompletionHandler.cpp" />
<ClCompile Include="Network\Iocp\IOCPNet.cpp" />
<ClCompile Include="Network\Iocp\IOWorker.cpp" />
<ClCompile Include="Network\Iocp\Overlapped.cpp" />
<ClCompile Include="Network\Listener\Listener.cpp" />
<ClCompile Include="Network\Session\Session.cpp" />
<ClCompile Include="Network\Session\SessionMgr.cpp" />
<ClCompile Include="Network\Session\SessionPolicy.cpp" />
<ClCompile Include="Network\Winsock\SocketFactory.cpp" />
<ClCompile Include="Network\Address\INET_Addr.cpp" />
<ClCompile Include="Stream\Buffer\Buffer.cpp" />
<ClCompile Include="Stream\Buffer\BufferFactory.cpp" />
<ClCompile Include="Stream\Buffer\BufferQueue.cpp" />
<ClCompile Include="Thread\ThreadMgr.cpp" />
<ClCompile Include="Log\ServerLog.cpp" />
<ClCompile Include="Utility\Debug\DebugUtils.cpp" />
<ClCompile Include="Utility\Debug\ExceptionReport.cpp" />
<ClCompile Include="Utility\Debug\PerformanceCheck.cpp" />
<ClCompile Include="Utility\Math\Math.cpp" />
<ClCompile Include="Utility\Math\PseudoRandom.cpp" />
<ClCompile Include="Utility\Math\Random.cpp" />
<ClCompile Include="Utility\Compress\MiniLZO\minilzo.cpp" />
<ClCompile Include="Utility\Compress\MiniLZO\miniLZOWrapper.cpp" />
<ClCompile Include="Utility\Registry\RegFunctions.cpp" />
<ClCompile Include="Utility\Time\Pulse\Pulse.cpp" />
<ClCompile Include="Utility\checksum\Crc32Static.cpp" />
<ClCompile Include="Utility\checksum\Crc8Static.cpp" />
<ClCompile Include="Utility\File\MappedFile.cpp" />
<ClCompile Include="Pattern\Command.cpp" />
<ClCompile Include="Pattern\CommandQueue.cpp" />
<ClCompile Include="Db\OLEDB.cpp" />
<ClCompile Include="Memory\MemoryPool.cpp" />
<ClCompile Include="stdafx.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="Network\Dispatch\Dispatch.h" />
<ClInclude Include="Network\Dispatch\PoolDispatchFactory.h" />
<ClInclude Include="Network\Dispatch\ServerRequest.h" />
<ClInclude Include="Network\Iocp\CompletionHandler.h" />
<ClInclude Include="Network\Iocp\IOCPNet.h" />
<ClInclude Include="Network\Iocp\IOWorker.h" />
<ClInclude Include="Network\Iocp\Overlapped.h" />
<ClInclude Include="Network\Listener\Listener.h" />
<ClInclude Include="Network\Session\Session.h" />
<ClInclude Include="Network\Session\SessionMgr.h" />
<ClInclude Include="Network\Session\SessionPolicy.h" />
<ClInclude Include="Network\Winsock\SocketFactory.h" />
<ClInclude Include="Network\Address\INET_Addr.h" />
<ClInclude Include="Stream\Buffer\Buffer.h" />
<ClInclude Include="Stream\Buffer\BufferFactory.h" />
<ClInclude Include="Stream\Buffer\BufferQueue.h" />
<ClInclude Include="Thread\Lock.h" />
<ClInclude Include="Thread\Thread.h" />
<ClInclude Include="Thread\ThreadMgr.h" />
<ClInclude Include="Log\ServerLog.h" />
<ClInclude Include="Log\ServerLogDefine.h" />
<ClInclude Include="Utility\Debug\DebugMacros.h" />
<ClInclude Include="Utility\Debug\DebugUtils.h" />
<ClInclude Include="Utility\Debug\DLLModule.h" />
<ClInclude Include="Utility\Debug\ExceptionReport.h" />
<ClInclude Include="Utility\Debug\PerformanceCheck.h" />
<ClInclude Include="Utility\Math\Math.h" />
<ClInclude Include="Utility\Math\PseudoRandom.h" />
<ClInclude Include="Utility\Math\Random.h" />
<ClInclude Include="Utility\Compress\MiniLZO\lzoconf.h" />
<ClInclude Include="Utility\Compress\MiniLZO\minilzo.h" />
<ClInclude Include="Utility\Compress\MiniLZO\miniLZOWrapper.h" />
<ClInclude Include="Utility\Registry\RegFunctions.h" />
<ClInclude Include="Utility\Resource\EnsureCleanup.h" />
<ClInclude Include="Utility\Time\Pulse\Pulse.h" />
<ClInclude Include="Utility\checksum\Common.h" />
<ClInclude Include="Utility\checksum\Crc32Static.h" />
<ClInclude Include="Utility\checksum\Crc8Static.h" />
<ClInclude Include="Utility\File\MappedFile.h" />
<ClInclude Include="Pattern\Command.h" />
<ClInclude Include="Pattern\CommandQueue.h" />
<ClInclude Include="Pattern\Singleton.h" />
<ClInclude Include="Db\OLEDB.h" />
<ClInclude Include="Memory\MemoryPool.h" />
<ClInclude Include="stdafx.h" />
</ItemGroup>
<ItemGroup>
<None Include="Utility\Math\Convert.inl" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MemoryManager\MemoryManager.vcxproj">
<Project>{7b602b2e-c629-4311-b7f6-c9177660ada1}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
<Private>true</Private>
<CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
<LinkLibraryDependencies>false</LinkLibraryDependencies>
<UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@@ -0,0 +1,325 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Network">
<UniqueIdentifier>{4b1a09a3-1e99-452e-9796-2f1990cfae8a}</UniqueIdentifier>
</Filter>
<Filter Include="Network\Dispatch">
<UniqueIdentifier>{92583b4f-c634-437e-a1c5-60a7fb83ad3e}</UniqueIdentifier>
</Filter>
<Filter Include="Network\IOCP">
<UniqueIdentifier>{ceec481d-2c53-49a5-adf5-9381a40ca9ed}</UniqueIdentifier>
</Filter>
<Filter Include="Network\Listener">
<UniqueIdentifier>{6040c95d-b9c6-4852-bcf5-8a4b80ec440b}</UniqueIdentifier>
</Filter>
<Filter Include="Network\Session">
<UniqueIdentifier>{0ec4f43b-9467-4f71-b384-3df914b781f5}</UniqueIdentifier>
</Filter>
<Filter Include="Network\Winsock">
<UniqueIdentifier>{635d719b-ef1c-4545-aa71-feaea2fd9dd7}</UniqueIdentifier>
</Filter>
<Filter Include="Network\Address">
<UniqueIdentifier>{a7fee7f0-052d-4044-a089-06ccfa50cc69}</UniqueIdentifier>
</Filter>
<Filter Include="Stream">
<UniqueIdentifier>{a8868297-dff5-49e2-9741-5514b75dc9a4}</UniqueIdentifier>
</Filter>
<Filter Include="Stream\Buffer">
<UniqueIdentifier>{59389242-22c1-4d2b-b64e-cc0aa3ffe9e0}</UniqueIdentifier>
</Filter>
<Filter Include="Thread">
<UniqueIdentifier>{1dff0a3f-c96e-42e8-ad30-d62e89c4812d}</UniqueIdentifier>
</Filter>
<Filter Include="Log">
<UniqueIdentifier>{4e41ff95-3981-4566-bb5b-e88f5d8d8267}</UniqueIdentifier>
</Filter>
<Filter Include="Utility">
<UniqueIdentifier>{eb0c7751-6367-43cf-b36d-c5c30038f897}</UniqueIdentifier>
</Filter>
<Filter Include="Utility\Debug">
<UniqueIdentifier>{b80e801a-74d4-4a06-92e7-98bfe70490c3}</UniqueIdentifier>
</Filter>
<Filter Include="Utility\Math">
<UniqueIdentifier>{5655b875-dd2a-4e20-a548-1e38f09c1e4b}</UniqueIdentifier>
</Filter>
<Filter Include="Utility\Compress">
<UniqueIdentifier>{bd6c277a-d618-494a-bf74-c278d3d5418f}</UniqueIdentifier>
</Filter>
<Filter Include="Utility\Compress\MiniLZO">
<UniqueIdentifier>{0eca824f-8264-4209-abeb-b38101484318}</UniqueIdentifier>
</Filter>
<Filter Include="Utility\Registry">
<UniqueIdentifier>{69a8ffd2-a35b-49b0-a6fe-692d6a021f08}</UniqueIdentifier>
</Filter>
<Filter Include="Utility\Resource">
<UniqueIdentifier>{2e90ba7b-cd14-4058-83bb-561c20913830}</UniqueIdentifier>
</Filter>
<Filter Include="Utility\Time">
<UniqueIdentifier>{a97a9399-4d40-4603-a291-ec917db5af90}</UniqueIdentifier>
</Filter>
<Filter Include="Utility\Time\Pulse">
<UniqueIdentifier>{ac0388ba-df42-4775-b85c-d8d8f1480d13}</UniqueIdentifier>
</Filter>
<Filter Include="Utility\CheckSum">
<UniqueIdentifier>{2e9a5f73-1d53-465f-aa87-2bd6eb76b7cc}</UniqueIdentifier>
</Filter>
<Filter Include="Utility\File">
<UniqueIdentifier>{0ea5c524-5276-4e79-aef4-3948bac7ef99}</UniqueIdentifier>
</Filter>
<Filter Include="Pattern">
<UniqueIdentifier>{6546cd1e-b0b0-49fe-9ef3-190fb5712e25}</UniqueIdentifier>
</Filter>
<Filter Include="DB">
<UniqueIdentifier>{7bf6fb91-729a-40c7-bad8-4d49122ab956}</UniqueIdentifier>
</Filter>
<Filter Include="Memory">
<UniqueIdentifier>{f790cb13-1f18-4a6d-abca-8eaba5ccfe5b}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Network\Dispatch\Dispatch.cpp">
<Filter>Network\Dispatch</Filter>
</ClCompile>
<ClCompile Include="Network\Dispatch\ServerRequest.cpp">
<Filter>Network\Dispatch</Filter>
</ClCompile>
<ClCompile Include="Network\Iocp\CompletionHandler.cpp">
<Filter>Network\IOCP</Filter>
</ClCompile>
<ClCompile Include="Network\Iocp\IOCPNet.cpp">
<Filter>Network\IOCP</Filter>
</ClCompile>
<ClCompile Include="Network\Iocp\IOWorker.cpp">
<Filter>Network\IOCP</Filter>
</ClCompile>
<ClCompile Include="Network\Iocp\Overlapped.cpp">
<Filter>Network\IOCP</Filter>
</ClCompile>
<ClCompile Include="Network\Listener\Listener.cpp">
<Filter>Network\Listener</Filter>
</ClCompile>
<ClCompile Include="Network\Session\Session.cpp">
<Filter>Network\Session</Filter>
</ClCompile>
<ClCompile Include="Network\Session\SessionMgr.cpp">
<Filter>Network\Session</Filter>
</ClCompile>
<ClCompile Include="Network\Session\SessionPolicy.cpp">
<Filter>Network\Session</Filter>
</ClCompile>
<ClCompile Include="Network\Winsock\SocketFactory.cpp">
<Filter>Network\Winsock</Filter>
</ClCompile>
<ClCompile Include="Network\Address\INET_Addr.cpp">
<Filter>Network\Address</Filter>
</ClCompile>
<ClCompile Include="Stream\Buffer\Buffer.cpp">
<Filter>Stream\Buffer</Filter>
</ClCompile>
<ClCompile Include="Stream\Buffer\BufferFactory.cpp">
<Filter>Stream\Buffer</Filter>
</ClCompile>
<ClCompile Include="Stream\Buffer\BufferQueue.cpp">
<Filter>Stream\Buffer</Filter>
</ClCompile>
<ClCompile Include="Thread\ThreadMgr.cpp">
<Filter>Thread</Filter>
</ClCompile>
<ClCompile Include="Log\ServerLog.cpp">
<Filter>Log</Filter>
</ClCompile>
<ClCompile Include="Utility\Debug\DebugUtils.cpp">
<Filter>Utility\Debug</Filter>
</ClCompile>
<ClCompile Include="Utility\Debug\ExceptionReport.cpp">
<Filter>Utility\Debug</Filter>
</ClCompile>
<ClCompile Include="Utility\Debug\PerformanceCheck.cpp">
<Filter>Utility\Debug</Filter>
</ClCompile>
<ClCompile Include="Utility\Math\Math.cpp">
<Filter>Utility\Math</Filter>
</ClCompile>
<ClCompile Include="Utility\Math\PseudoRandom.cpp">
<Filter>Utility\Math</Filter>
</ClCompile>
<ClCompile Include="Utility\Math\Random.cpp">
<Filter>Utility\Math</Filter>
</ClCompile>
<ClCompile Include="Utility\Compress\MiniLZO\minilzo.cpp">
<Filter>Utility\Compress\MiniLZO</Filter>
</ClCompile>
<ClCompile Include="Utility\Compress\MiniLZO\miniLZOWrapper.cpp">
<Filter>Utility\Compress\MiniLZO</Filter>
</ClCompile>
<ClCompile Include="Utility\Registry\RegFunctions.cpp">
<Filter>Utility\Registry</Filter>
</ClCompile>
<ClCompile Include="Utility\Time\Pulse\Pulse.cpp">
<Filter>Utility\Time\Pulse</Filter>
</ClCompile>
<ClCompile Include="Utility\checksum\Crc32Static.cpp">
<Filter>Utility\CheckSum</Filter>
</ClCompile>
<ClCompile Include="Utility\checksum\Crc8Static.cpp">
<Filter>Utility\CheckSum</Filter>
</ClCompile>
<ClCompile Include="Utility\File\MappedFile.cpp">
<Filter>Utility\File</Filter>
</ClCompile>
<ClCompile Include="Pattern\Command.cpp">
<Filter>Pattern</Filter>
</ClCompile>
<ClCompile Include="Pattern\CommandQueue.cpp">
<Filter>Pattern</Filter>
</ClCompile>
<ClCompile Include="Db\OLEDB.cpp">
<Filter>DB</Filter>
</ClCompile>
<ClCompile Include="Memory\MemoryPool.cpp">
<Filter>Memory</Filter>
</ClCompile>
<ClCompile Include="stdafx.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="Network\Dispatch\Dispatch.h">
<Filter>Network\Dispatch</Filter>
</ClInclude>
<ClInclude Include="Network\Dispatch\PoolDispatchFactory.h">
<Filter>Network\Dispatch</Filter>
</ClInclude>
<ClInclude Include="Network\Dispatch\ServerRequest.h">
<Filter>Network\Dispatch</Filter>
</ClInclude>
<ClInclude Include="Network\Iocp\CompletionHandler.h">
<Filter>Network\IOCP</Filter>
</ClInclude>
<ClInclude Include="Network\Iocp\IOCPNet.h">
<Filter>Network\IOCP</Filter>
</ClInclude>
<ClInclude Include="Network\Iocp\IOWorker.h">
<Filter>Network\IOCP</Filter>
</ClInclude>
<ClInclude Include="Network\Iocp\Overlapped.h">
<Filter>Network\IOCP</Filter>
</ClInclude>
<ClInclude Include="Network\Listener\Listener.h">
<Filter>Network\Listener</Filter>
</ClInclude>
<ClInclude Include="Network\Session\Session.h">
<Filter>Network\Session</Filter>
</ClInclude>
<ClInclude Include="Network\Session\SessionMgr.h">
<Filter>Network\Session</Filter>
</ClInclude>
<ClInclude Include="Network\Session\SessionPolicy.h">
<Filter>Network\Session</Filter>
</ClInclude>
<ClInclude Include="Network\Winsock\SocketFactory.h">
<Filter>Network\Winsock</Filter>
</ClInclude>
<ClInclude Include="Network\Address\INET_Addr.h">
<Filter>Network\Address</Filter>
</ClInclude>
<ClInclude Include="Stream\Buffer\Buffer.h">
<Filter>Stream\Buffer</Filter>
</ClInclude>
<ClInclude Include="Stream\Buffer\BufferFactory.h">
<Filter>Stream\Buffer</Filter>
</ClInclude>
<ClInclude Include="Stream\Buffer\BufferQueue.h">
<Filter>Stream\Buffer</Filter>
</ClInclude>
<ClInclude Include="Thread\Lock.h">
<Filter>Thread</Filter>
</ClInclude>
<ClInclude Include="Thread\Thread.h">
<Filter>Thread</Filter>
</ClInclude>
<ClInclude Include="Thread\ThreadMgr.h">
<Filter>Thread</Filter>
</ClInclude>
<ClInclude Include="Log\ServerLog.h">
<Filter>Log</Filter>
</ClInclude>
<ClInclude Include="Log\ServerLogDefine.h">
<Filter>Log</Filter>
</ClInclude>
<ClInclude Include="Utility\Debug\DebugMacros.h">
<Filter>Utility\Debug</Filter>
</ClInclude>
<ClInclude Include="Utility\Debug\DebugUtils.h">
<Filter>Utility\Debug</Filter>
</ClInclude>
<ClInclude Include="Utility\Debug\DLLModule.h">
<Filter>Utility\Debug</Filter>
</ClInclude>
<ClInclude Include="Utility\Debug\ExceptionReport.h">
<Filter>Utility\Debug</Filter>
</ClInclude>
<ClInclude Include="Utility\Debug\PerformanceCheck.h">
<Filter>Utility\Debug</Filter>
</ClInclude>
<ClInclude Include="Utility\Math\Math.h">
<Filter>Utility\Math</Filter>
</ClInclude>
<ClInclude Include="Utility\Math\PseudoRandom.h">
<Filter>Utility\Math</Filter>
</ClInclude>
<ClInclude Include="Utility\Math\Random.h">
<Filter>Utility\Math</Filter>
</ClInclude>
<ClInclude Include="Utility\Compress\MiniLZO\lzoconf.h">
<Filter>Utility\Compress\MiniLZO</Filter>
</ClInclude>
<ClInclude Include="Utility\Compress\MiniLZO\minilzo.h">
<Filter>Utility\Compress\MiniLZO</Filter>
</ClInclude>
<ClInclude Include="Utility\Compress\MiniLZO\miniLZOWrapper.h">
<Filter>Utility\Compress\MiniLZO</Filter>
</ClInclude>
<ClInclude Include="Utility\Registry\RegFunctions.h">
<Filter>Utility\Registry</Filter>
</ClInclude>
<ClInclude Include="Utility\Resource\EnsureCleanup.h">
<Filter>Utility\Resource</Filter>
</ClInclude>
<ClInclude Include="Utility\Time\Pulse\Pulse.h">
<Filter>Utility\Time\Pulse</Filter>
</ClInclude>
<ClInclude Include="Utility\checksum\Common.h">
<Filter>Utility\CheckSum</Filter>
</ClInclude>
<ClInclude Include="Utility\checksum\Crc32Static.h">
<Filter>Utility\CheckSum</Filter>
</ClInclude>
<ClInclude Include="Utility\checksum\Crc8Static.h">
<Filter>Utility\CheckSum</Filter>
</ClInclude>
<ClInclude Include="Utility\File\MappedFile.h">
<Filter>Utility\File</Filter>
</ClInclude>
<ClInclude Include="Pattern\Command.h">
<Filter>Pattern</Filter>
</ClInclude>
<ClInclude Include="Pattern\CommandQueue.h">
<Filter>Pattern</Filter>
</ClInclude>
<ClInclude Include="Pattern\Singleton.h">
<Filter>Pattern</Filter>
</ClInclude>
<ClInclude Include="Db\OLEDB.h">
<Filter>DB</Filter>
</ClInclude>
<ClInclude Include="Memory\MemoryPool.h">
<Filter>Memory</Filter>
</ClInclude>
<ClInclude Include="stdafx.h" />
</ItemGroup>
<ItemGroup>
<None Include="Utility\Math\Convert.inl">
<Filter>Utility\Math</Filter>
</None>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
</Project>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,135 @@
///////////////////////////////////////////////////////////////////////////////////////////////
//
// OleDB
//
//////////////////////////////////////////////////////////////////////////////////////////////
#ifndef _RYL_BASE_OleDB
#define _RYL_BASE_OleDB
#include <oledb.h>
#include <oledberr.h>
//#define _CHECK_OLEDB_PERFORMANCE // DB <20><><EFBFBD><EFBFBD><EFBFBD>ս<EFBFBD> üũ
#ifdef _CHECK_OLEDB_PERFORMANCE
#define DB_PERFORMANCE_CHECK(x) x
#else
#define DB_PERFORMANCE_CHECK(x) (void*)0;
#endif
//////////////////////////////////////////////////////////////////////////////////////////////
//
// Ŭ<><C5AC><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
//
///////////////////////////////////////////////////////////////////////////////////////////////
class OleDB
{
public:
const static unsigned long MaxRowNum = 2000; // <20>ִ<EFBFBD> <20><> <20><><EFBFBD><EFBFBD>
const static unsigned long MaxErrorLen = 512; // <20>ִ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
const static unsigned long MaxQueryTextLen = 8192; // <20>ִ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ڿ<EFBFBD> <20><><EFBFBD><EFBFBD>
protected:
typedef struct _COL_INFO
{
const static unsigned short MaxColNameLen = 100; // <20>ִ<EFBFBD> <20>÷<EFBFBD> <20≯<EFBFBD> <20><><EFBFBD><EFBFBD>
char ColName[MaxColNameLen]; // <20>÷<EFBFBD> <20≯<EFBFBD>
unsigned long ColSize; // <20>÷<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
}COL_INFO, *LPCOL_INFO;
typedef struct _RESULT_COLS
{
unsigned long ColNum;
DBCOLUMNINFO* lpDBColumnInfo;
WCHAR* lpStringsBuffer;
}RESULT_COLS, *LPRESULT_COLS;
WCHAR m_QueryText[MaxQueryTextLen]; // <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ڿ<EFBFBD>
COL_INFO m_ColInfo;
public:
enum ConnType { ConnType_ODBC = 0, ConnType_MSSQL = 1, ConnType_ORACLE };
enum Rowset { Rowset_Get = 0, Rowset_Update = 1 }; // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ο<EFBFBD><CEBF><EFBFBD>
typedef struct _PARAM_INFO
{
const static unsigned short MaxColNum = 30; // <20>ִ<EFBFBD> <20>÷<EFBFBD> <20≯<EFBFBD> <20><><EFBFBD><EFBFBD>
unsigned long ColNum; // <20>÷<EFBFBD> <20><><EFBFBD><EFBFBD>
DBPARAMIO eParamIO[MaxColNum]; // <20>÷<EFBFBD> <20>Ķ<EFBFBD><C4B6><EFBFBD><EFBFBD><EFBFBD> Ÿ<><C5B8>
unsigned long ColSize[MaxColNum]; // <20>÷<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
unsigned short ColType[MaxColNum]; // <20>÷<EFBFBD> Ÿ<><C5B8>
}
PARAM_INFO, *LPPARAM_INFO;
/*typedef struct _DB_SP_INFO
{
char szCatalog[0xff]; // <20><><EFBFBD><EFBFBD> DB
char szType[0xff]; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
char szSPName[0xff]; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ν<EFBFBD><CEBD><EFBFBD> <20≯<EFBFBD>.
}DB_SP_INFO, *LP_DB_SP_INFO;*/
typedef struct _SET_BINARY
{
unsigned long Size;
}SET_BINARY, *LPSET_BINARY;
protected:
IDBInitialize* m_pIDBInit;
IDBCreateSession* m_pIDBCreateSession;
IDBCreateCommand* m_pIDBCreateCommand;
IRowset* m_pIRowset;
IRowsetChange* m_pIRowsetChange;
HRESULT m_dwLastError;
char m_ErrorString[MaxErrorLen];
unsigned int m_dwQueryErrorCount;
public:
OleDB(void);
virtual ~OleDB(void);
inline const char* GetErrorString(void) const { return m_ErrorString; }
inline HRESULT GetLastError(void) const { return m_dwLastError; }
inline const unsigned int GetQueryErrorCount() const { return m_dwQueryErrorCount; }
bool ConnectDataSourcePrompt(HWND hWnd_In);
bool ConnectSQLServer(LPCTSTR ServerName_In, LPCTSTR DataBaseName_In, LPCTSTR UserID_In, LPCTSTR UserPass_In, ConnType ConnType_In);
bool DisconnectDataSource(void);
bool ExecuteQuery(LPCTSTR Query_In, Rowset Rowset_In = Rowset_Get);
bool ExecuteQueryWithParams(LPCTSTR Query_In, char *Data_In, const PARAM_INFO& ColInfo_In);
bool ExecuteQueryGetData(LPCTSTR Query_In, void *Buffer_Out);
bool GetData(void *Buffer_Out);
bool GetData(void **Buffer_Out, int RowSize_In, int Row_In, int *pGetRow_Out);
bool SetBinaryData(int ColNum_In, LPSET_BINARY lpSetBinary);
COL_INFO& GetColInfo(void) { return m_ColInfo; }
//bool GetUserStoredProcedureInfo(DB_SP_INFO* pSpInfo, DWORD dwMaxSPCnt);
private:
bool HandleError(int ErrorLine_In, HRESULT hResult_In, char *Buffer_In);
bool CreateSession(void);
bool DBCreateCommand(void);
bool AllocResultCols(IUnknown* lpIUnknown_In, RESULT_COLS &Rsult_Cols);
bool ReleaseResultCols(IUnknown* lpIUnknown_In, RESULT_COLS &Rsult_Cols);
bool SetConnectionProperties(LPCTSTR ServerName_In, LPCTSTR DataBaseName_In, LPCTSTR UserID_In, LPCTSTR UserPass_In);
DBBINDING* AllocBindGetData(int ColsNum_In, DBCOLUMNINFO* pDBColumnInfo_In);
DBBINDING* AllocBindParamInputData(const PARAM_INFO &ColInfo_In);
};
#endif

View File

@@ -0,0 +1,374 @@
#include "stdafx.h"
#include "ServerLog.h"
#include "../Utility/Debug/DebugUtils.h"
CServerLog g_Log;
CServerLog g_PacketLog("Packet", 0);
CServerLog g_SessionLog("SessionLog", 0);
CServerLog g_SkillLog("SkillLog", 0);
enum LOG_CONSTANT
{
MAX_LOG_PER_SIZE = 16384,
MAX_LOG_FILE_SIZE = 50 * 1024 * 1024, // 100Mega
MAX_LOG_BUFFER = 256 * 1024,
MAX_LOG_BUFFER_BOUND = 248 * 1024
};
static const char* s_LogType[MAX_LOG_TYPE] =
{
"NOR", // Normal
"RUL", // Game manager things
"INF", // Informations about current status
"DET", // Detail
"SER", // System call error
"ERR", // Fatal error (must be fixed!)
"DBG", // Debug related informations
"WRN", // Warning (must be fixed!)
};
CServerLog::CServerLog(const char* szLogName, const char* szPathName)
: m_hFile(INVALID_HANDLE_VALUE),
m_dwTotalFileWriteSize(0LL),
m_dwTotalLoggedSize(0LL),
m_dwCurrentFileWriteSize(0), m_dwBufferUsed(0),
m_dwLogEnabled(0xFFFFFFFF)
{
if(0 != szLogName)
{
_snprintf(m_szProgramName, MAX_PATH - 1, "%s", szLogName);
m_szProgramName[MAX_PATH - 1] = 0;
}
else
{
DbgUtils::SetProgramName(m_szProgramName, MAX_PATH);
}
if(0 != szPathName)
{
_snprintf(m_szLogPath, MAX_PATH - 1, "%s", szPathName);
m_szLogPath[MAX_PATH - 1] = 0;
}
else
{
DbgUtils::SetProgramName(m_szLogPath, MAX_PATH);
}
m_lpBuffer = new (std::nothrow) char[MAX_LOG_BUFFER];
}
CServerLog::~CServerLog()
{
ServerLogLock::Syncronize sync(m_ServerLogLock);
SimpleLog(LOG_NORMAL, "<EFBFBD>α׸<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD>.");
if(0 != m_dwBufferUsed)
{
InternalFlush();
}
if(INVALID_HANDLE_VALUE != m_hFile)
{
CloseHandle(m_hFile);
}
delete [] m_lpBuffer;
m_lpBuffer = 0;
}
void _cdecl CServerLog::Log(const char* pFormat, ...)
{
// Lock and Push
ServerLogLock::Syncronize sync(m_ServerLogLock);
va_list arguments;
va_start_ext(arguments, pFormat);
int nLength = _vsntprintf(m_lpBuffer + m_dwBufferUsed,
MAX_LOG_BUFFER - m_dwBufferUsed, pFormat, arguments);
va_end(arguments);
if(0 < nLength)
{
m_dwBufferUsed += nLength;
m_dwTotalLoggedSize += nLength;
}
if(MAX_LOG_BUFFER_BOUND <= m_dwBufferUsed)
{
InternalFlush();
}
}
void _cdecl CServerLog::SimpleLog(LOG_TYPE eLogType, const char* pFormat, ...)
{
/*
LOG_NORMAL, // <20>Ϲ<EFBFBD> <20>α<EFBFBD><><C5AC><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD>)
LOG_RULE, // <20><20><><EFBFBD><EFBFBD> <20>α<EFBFBD>
LOG_INFO, // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>α<EFBFBD>
*/
if(!(m_dwLogEnabled & (1 << eLogType)))
{
// Enabled<65><64> <20>αװ<CEB1> <20>ƴϴ<C6B4>. <20><><EFBFBD><EFBFBD> <20>ʴ´<CAB4>.
return;
}
if(0 != m_lpBuffer)
{
int nLogSize = 0;
char szBuffer[MAX_LOG_PER_SIZE];
switch(eLogType)
{
case LOG_NORMAL:
nLogSize = _snprintf(szBuffer, MAX_LOG_PER_SIZE, "[Ty-%s][", s_LogType[eLogType]);
break;
case LOG_RULE:
case LOG_INFO:
{
SYSTEMTIME sysTime;
GetLocalTime(&sysTime);
nLogSize = _snprintf(szBuffer, MAX_LOG_PER_SIZE,
"[Ty-%s][Tm-%04d-%02d-%02d %02d:%02d:%02d][Ex-",
s_LogType[eLogType], sysTime.wYear, sysTime.wMonth, sysTime.wDay,
sysTime.wHour, sysTime.wMinute, sysTime.wSecond);
}
break;
};
va_list arguments;
va_start_ext(arguments, pFormat);
nLogSize += _vsntprintf(szBuffer + nLogSize,
MAX_LOG_PER_SIZE - nLogSize, pFormat, arguments);
va_end(arguments);
// Lock and Push
ServerLogLock::Syncronize sync(m_ServerLogLock);
int nLength = _snprintf(m_lpBuffer + m_dwBufferUsed,
MAX_LOG_BUFFER - m_dwBufferUsed, "%s]\r\n", szBuffer);
if(0 < nLength)
{
m_dwBufferUsed += nLength;
m_dwTotalLoggedSize += nLength;
}
if(MAX_LOG_BUFFER_BOUND <= m_dwBufferUsed)
{
InternalFlush();
}
}
}
void _cdecl CServerLog::DetailLog(LOG_TYPE eLogType, const char* pRtn, const char* pFileName,
int nLine, const char* pFormat, ...)
{
/*
LOG_DETAIL, // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>α<EFBFBD>
LOG_SYSERR, // <20>ý<EFBFBD><C3BD><EFBFBD> <20>Լ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>α<EFBFBD>
LOG_ERROR, // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>α<EFBFBD>
LOG_DEBUG, // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>α<EFBFBD>
LOG_WARN, // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>α<EFBFBD>
*/
if(!(m_dwLogEnabled & (1 << eLogType)))
{
// Enabled<65><64> <20>αװ<CEB1> <20>ƴϴ<C6B4>. <20><><EFBFBD><EFBFBD> <20>ʴ´<CAB4>.
return;
}
if(0 != m_lpBuffer)
{
SYSTEMTIME sysTime;
GetLocalTime(&sysTime);
int nLogSize = 0;
char szBuffer[MAX_LOG_PER_SIZE];
nLogSize = _snprintf(szBuffer, MAX_LOG_PER_SIZE,
"[Ty-%s][Tm-%04d-%02d-%02d %02d:%02d:%02d][Ex-", s_LogType[eLogType],
sysTime.wYear, sysTime.wMonth, sysTime.wDay,
sysTime.wHour, sysTime.wMinute, sysTime.wSecond);
va_list arguments;
va_start_ext(arguments, pFormat);
nLogSize += _vsntprintf(szBuffer + nLogSize, MAX_LOG_PER_SIZE - nLogSize,
pFormat, arguments);
va_end(arguments);
ServerLogLock::Syncronize sync(m_ServerLogLock);
int nLength = _snprintf(m_lpBuffer + m_dwBufferUsed,
MAX_LOG_BUFFER - m_dwBufferUsed,
"%s][Rt-%s][FN-%s][LN-%d]\r\n",
szBuffer, pRtn, pFileName, nLine);
if(0 < nLength)
{
m_dwBufferUsed += nLength;
m_dwTotalLoggedSize += nLength;
}
if(m_dwBufferUsed >= MAX_LOG_BUFFER_BOUND || eLogType == LOG_SYSERR)
{
InternalFlush();
}
}
}
void CServerLog::SetLogFileName(const char* szLogName, const char* szPathName)
{
ServerLogLock::Syncronize sync(m_ServerLogLock);
if(0 < m_dwBufferUsed)
{
InternalFlush();
}
if(INVALID_HANDLE_VALUE != m_hFile)
{
CloseHandle(m_hFile);
m_hFile = INVALID_HANDLE_VALUE;
}
if(0 != szLogName)
{
_snprintf(m_szProgramName, MAX_PATH - 1, "%s", szLogName);
m_szProgramName[MAX_PATH - 1] = 0;
}
else
{
DbgUtils::SetProgramName(m_szProgramName, MAX_PATH);
}
if(0 != szPathName)
{
_snprintf(m_szLogPath, MAX_PATH - 1, "%s", szPathName);
m_szLogPath[MAX_PATH - 1] = 0;
}
else
{
DbgUtils::SetProgramName(m_szLogPath, MAX_PATH);
}
}
HANDLE CServerLog::CreateLogFile()
{
// 1. <20>α<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E4B8AE> <20><><EFBFBD><EFBFBD>.
// 2. <20>α<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
// 3. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><20>ڵ<EFBFBD> <20><><EFBFBD><EFBFBD>.
char szTime[MAX_PATH];
char szFileName[MAX_PATH];
if (INVALID_FILE_ATTRIBUTES == GetFileAttributes(m_szLogPath))
{
if (!CreateDirectory(m_szLogPath, 0))
{
return INVALID_HANDLE_VALUE;
}
}
SYSTEMTIME sysTime;
GetLocalTime(&sysTime);
_snprintf(szTime, MAX_PATH, TEXT("%s%04d-%02d-%02d %02d,%02d,%02d-"),
m_szProgramName, sysTime.wYear, sysTime.wMonth, sysTime.wDay,
sysTime.wHour, sysTime.wMinute, sysTime.wSecond);
// create log file name in good order
for(unsigned long dwSpinCount = 0; TRUE; ++dwSpinCount)
{
int nLength = _snprintf(szFileName, MAX_PATH, "%s/%s%04d.log",
m_szLogPath, szTime, dwSpinCount);
if(nLength < 0)
{
return INVALID_HANDLE_VALUE;
}
if (INVALID_FILE_ATTRIBUTES == GetFileAttributes(szFileName))
{
break;
}
}
m_dwCurrentFileWriteSize = 0;
return CreateFile(szFileName, GENERIC_WRITE,
FILE_SHARE_READ, 0, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0);
}
void CServerLog::InternalFlush()
{
unsigned long dwWritten = 0;
if(INVALID_HANDLE_VALUE == m_hFile)
{
m_hFile = CreateLogFile();
}
WriteFile(m_hFile, m_lpBuffer, m_dwBufferUsed, &dwWritten, 0);
m_dwCurrentFileWriteSize += dwWritten;
m_dwBufferUsed = 0;
if(MAX_LOG_FILE_SIZE < m_dwCurrentFileWriteSize)
{
CloseHandle(m_hFile);
m_hFile = CreateLogFile();
};
}
void CServerLog::Dump(const char* szSignature, char* lpDumpPos, size_t nLength)
{
FILE* fFile = fopen("DumpMemory.txt", "ab");
if(0 != fFile)
{
SYSTEMTIME sysTime;
GetLocalTime(&sysTime);
__try
{
fprintf(fFile, "\n %s : Dump Memory [%04d-%02d-%02d %02d,%02d,%02d]: %s \r\n<",
m_szProgramName, sysTime.wYear, sysTime.wMonth, sysTime.wDay,
sysTime.wHour, sysTime.wMinute, sysTime.wSecond, szSignature);
fwrite(lpDumpPos, nLength, 1, fFile);
}
__finally
{
fprintf(fFile, ">\r\n");
fclose(fFile);
}
}
}
bool CServerLog::NewLog()
{
if(INVALID_HANDLE_VALUE != m_hFile)
CloseHandle(m_hFile);
m_hFile = CreateLogFile();
if(INVALID_HANDLE_VALUE == m_hFile)
return false;
else
return true;
}

View File

@@ -0,0 +1,86 @@
#ifndef _SERVER_LOG_H_
#define _SERVER_LOG_H_
#include "ServerLogDefine.h"
#include "../Thread/Lock.h"
class CNullLog
{
public:
// constructor and destructor
CNullLog(const char* szLogName = 0, const char* szPathName = 0) { }
virtual ~CNullLog() { }
void Enable(unsigned long dwEnableLogType) { }
void Disable(unsigned long dwDisableLogType) { }
void _cdecl Log(const char* pFormat, ...) { }
void _cdecl SimpleLog(LOG_TYPE eLogType, const char* pFormat, ...) { }
void _cdecl DetailLog(LOG_TYPE eLogType, const char* pRtn, const char* pFileName, int nLine, const char* pFormat, ...) { }
void Dump(const char* szSignature, char* lpDumpPos, size_t nLength) { }
void Flush() { }
void SetLogFileName(const char* szLogName, const char* szPathName) { }
};
class CServerLog
{
public:
// constructor and destructor
CServerLog(const char* szLogName = 0, const char* szPathName = 0);
virtual ~CServerLog();
void Enable(unsigned long dwEnableLogType) { m_dwLogEnabled |= dwEnableLogType; }
void Disable(unsigned long dwDisableLogType) { m_dwLogEnabled &= ~dwDisableLogType; }
void _cdecl Log(const char* pFormat, ...);
void _cdecl SimpleLog(LOG_TYPE eLogType, const char* pFormat, ...);
void _cdecl DetailLog(LOG_TYPE eLogType, const char* pRtn,
const char* pFileName, int nLine, const char* pFormat, ...);
void Dump(const char* szSignature, char* lpDumpPos, size_t nLength);
void Flush() { ServerLogLock::Syncronize sync(m_ServerLogLock); InternalFlush(); }
void SetLogFileName(const char* szLogName, const char* szPathName);
unsigned __int64 GetTotalLoggedSize() const { return m_dwTotalLoggedSize; }
unsigned __int64 GetTotalWriteSize() const { return m_dwTotalFileWriteSize; }
unsigned long GetCurrentFileWriteSize() const { return m_dwCurrentFileWriteSize; }
bool NewLog();
protected:
typedef CCSLock ServerLogLock;
ServerLogLock m_ServerLogLock;
HANDLE CreateLogFile();
void InternalFlush();
unsigned __int64 m_dwTotalFileWriteSize;
unsigned __int64 m_dwTotalLoggedSize;
unsigned long m_dwCurrentFileWriteSize;
HANDLE m_hFile;
unsigned long m_dwBufferUsed;
unsigned long m_dwLogEnabled;
char m_szProgramName[MAX_PATH];
char m_szLogPath[MAX_PATH];
char* m_lpBuffer;
};
extern CServerLog g_Log;
extern CServerLog g_PacketLog;
extern CServerLog g_SessionLog;
extern CServerLog g_SkillLog;
#endif

View File

@@ -0,0 +1,329 @@
#ifndef _SERVER_LOG_DEFINE_H_
#define _SERVER_LOG_DEFINE_H_
#pragma once
// ---------------------------------------------------------------------------------------
// <20>ҽ<EFBFBD> <20><><EFBFBD><EFBFBD>
#define _SOURCE_LEVEL_MINIMUM 0 // Only output errors
#define _SOURCE_LEVEL_RELEASE 1 // Normal release mode
#define _SOURCE_LEVEL_BETA 2 // Normal beta season mode
#define _SOURCE_LEVEL_DEBUG 3 // Output mostly
#define _SOURCE_LEVEL_FULL 4 // Output fully
#ifndef _SRCFILE_LEVEL // <20>α<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ǿ<EFBFBD> <20>ִ<EFBFBD><D6B4><EFBFBD> Ȯ<><C8AE>
#ifdef _DEBUG
#define _SRCFILE_LEVEL _SOURCE_LEVEL_FULL
#else
#define _SRCFILE_LEVEL _SOURCE_LEVEL_FULL
#endif
#endif
// Function, File, Line<6E><65> <20><><EFBFBD>ڷ<EFBFBD> <20>ѱ<EFBFBD><D1B1><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>ũ<EFBFBD><C5A9>.
#define LOG_FFL __FUNCTION__, __FILE__, __LINE__
#if (_SRCFILE_LEVEL == _SOURCE_LEVEL_MINIMUM)
#define USE_LOG_SYSERR
#define USE_LOG_ERROR
#define USE_LOG_RULE
#define USE_LOG_INFO
#elif (_SRCFILE_LEVEL == _SOURCE_LEVEL_RELEASE)
#define USE_LOG_SYSERR
#define USE_LOG_ERROR
#define USE_LOG_WARN
#define USE_LOG_INFO
#define USE_LOG_RULE
#elif (_SRCFILE_LEVEL == _SOURCE_LEVEL_BETA)
#define USE_LOG_SYSERR
#define USE_LOG_ERROR
#define USE_LOG_DEBUG
#define USE_LOG_WARN
#define USE_LOG_DUMP
#define USE_LOG_INFO
#define USE_LOG_RULE
#define USE_LOG_STAT
#elif (_SRCFILE_LEVEL == _SOURCE_LEVEL_DEBUG)
#define USE_LOG_SYSERR
#define USE_LOG_ERROR
#define USE_LOG_DEBUG
#define USE_LOG_WARN
#define USE_LOG_DUMP
#define USE_LOG_INFO
#define USE_LOG_RULE
#define USE_LOG_STAT
#elif (_SRCFILE_LEVEL == _SOURCE_LEVEL_FULL)
#define USE_LOG_NORMAL
#define USE_LOG_DETAIL
#define USE_LOG_SYSERR
#define USE_LOG_ERROR
#define USE_LOG_DEBUG
#define USE_LOG_WARN
#define USE_LOG_DUMP
#define USE_LOG_INFO
#define USE_LOG_RULE
#define USE_LOG_STAT
#endif
enum LOG_TYPE
{
LOG_NORMAL, // <20>Ϲ<EFBFBD> <20>α<EFBFBD><><C5AC><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD>)
LOG_RULE, // <20><20><><EFBFBD><EFBFBD> <20>α<EFBFBD>
LOG_INFO, // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>α<EFBFBD>
LOG_DETAIL, // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>α<EFBFBD>
LOG_SYSERR, // <20>ý<EFBFBD><C3BD><EFBFBD> <20>Լ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>α<EFBFBD>
LOG_ERROR, // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>α<EFBFBD>
LOG_DEBUG, // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>α<EFBFBD>
LOG_WARN, // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>α<EFBFBD>
MAX_LOG_TYPE
};
// -------------------------------------------------------------------------------------
// Simple Log Type
#ifdef USE_LOG_NORMAL
#define NORLOG(x) x
#define NORLOG0(LogInstance, szString) LogInstance.SimpleLog(LOG_NORMAL, szString)
#define NORLOG1(LogInstance, szFormat, arg1) LogInstance.SimpleLog(LOG_NORMAL, szFormat, arg1)
#define NORLOG2(LogInstance, szFormat, arg1, arg2) LogInstance.SimpleLog(LOG_NORMAL, szFormat, arg1, arg2)
#define NORLOG3(LogInstance, szFormat, arg1, arg2, arg3) LogInstance.SimpleLog(LOG_NORMAL, szFormat, arg1, arg2, arg3)
#define NORLOG4(LogInstance, szFormat, arg1, arg2, arg3, arg4) LogInstance.SimpleLog(LOG_NORMAL, szFormat, arg1, arg2, arg3, arg4)
#define NORLOG5(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5) LogInstance.SimpleLog(LOG_NORMAL, szFormat, arg1, arg2, arg3, arg4, arg5)
#define NORLOG6(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6) LogInstance.SimpleLog(LOG_NORMAL, szFormat, arg1, arg2, arg3, arg4, arg5, arg6)
#define NORLOG7(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7) LogInstance.SimpleLog(LOG_NORMAL, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
#define NORLOG8(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) LogInstance.SimpleLog(LOG_NORMAL, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
#define NORLOG9(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) LogInstance.SimpleLog(LOG_NORMAL, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
#else
#define NORLOG(x) (void*)0
#define NORLOG0(LogInstance, szString) (void*)0
#define NORLOG1(LogInstance, szFormat, arg1) (void*)0
#define NORLOG2(LogInstance, szFormat, arg1, arg2) (void*)0
#define NORLOG3(LogInstance, szFormat, arg1, arg2, arg3) (void*)0
#define NORLOG4(LogInstance, szFormat, arg1, arg2, arg3, arg4) (void*)0
#define NORLOG5(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5) (void*)0
#define NORLOG6(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6) (void*)0
#define NORLOG7(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7) (void*)0
#define NORLOG8(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) (void*)0
#define NORLOG9(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) (void*)0
#endif
#ifdef USE_LOG_INFO
#define INFLOG(x) x
#define INFLOG0(LogInstance, szString) LogInstance.SimpleLog(LOG_INFO, szString)
#define INFLOG1(LogInstance, szFormat, arg1) LogInstance.SimpleLog(LOG_INFO, szFormat, arg1)
#define INFLOG2(LogInstance, szFormat, arg1, arg2) LogInstance.SimpleLog(LOG_INFO, szFormat, arg1, arg2)
#define INFLOG3(LogInstance, szFormat, arg1, arg2, arg3) LogInstance.SimpleLog(LOG_INFO, szFormat, arg1, arg2, arg3)
#define INFLOG4(LogInstance, szFormat, arg1, arg2, arg3, arg4) LogInstance.SimpleLog(LOG_INFO, szFormat, arg1, arg2, arg3, arg4)
#define INFLOG5(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5) LogInstance.SimpleLog(LOG_INFO, szFormat, arg1, arg2, arg3, arg4, arg5)
#define INFLOG6(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6) LogInstance.SimpleLog(LOG_INFO, szFormat, arg1, arg2, arg3, arg4, arg5, arg6)
#define INFLOG7(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7) LogInstance.SimpleLog(LOG_INFO, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
#define INFLOG8(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) LogInstance.SimpleLog(LOG_INFO, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
#define INFLOG9(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) LogInstance.SimpleLog(LOG_INFO, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
#define INFLOG10(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10) LogInstance.SimpleLog(LOG_INFO, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10)
#define INFLOG11(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11) LogInstance.SimpleLog(LOG_INFO, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11)
#else
#define INFLOG(x) (void*)0
#define INFLOG0(LogInstance, szString) (void*)0
#define INFLOG1(LogInstance, szFormat, arg1) (void*)0
#define INFLOG2(LogInstance, szFormat, arg1, arg2) (void*)0
#define INFLOG3(LogInstance, szFormat, arg1, arg2, arg3) (void*)0
#define INFLOG4(LogInstance, szFormat, arg1, arg2, arg3, arg4) (void*)0
#define INFLOG5(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5) (void*)0
#define INFLOG6(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6) (void*)0
#define INFLOG7(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7) (void*)0
#define INFLOG8(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) (void*)0
#define INFLOG9(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) (void*)0
#endif
#ifdef USE_LOG_RULE
#define RULLOG(x) x
#define RULLOG0(LogInstance, szString) LogInstance.SimpleLog(LOG_RULE, szString)
#define RULLOG1(LogInstance, szFormat, arg1) LogInstance.SimpleLog(LOG_RULE, szFormat, arg1)
#define RULLOG2(LogInstance, szFormat, arg1, arg2) LogInstance.SimpleLog(LOG_RULE, szFormat, arg1, arg2)
#define RULLOG3(LogInstance, szFormat, arg1, arg2, arg3) LogInstance.SimpleLog(LOG_RULE, szFormat, arg1, arg2, arg3)
#define RULLOG4(LogInstance, szFormat, arg1, arg2, arg3, arg4) LogInstance.SimpleLog(LOG_RULE, szFormat, arg1, arg2, arg3, arg4)
#define RULLOG5(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5) LogInstance.SimpleLog(LOG_RULE, szFormat, arg1, arg2, arg3, arg4, arg5)
#define RULLOG6(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6) LogInstance.SimpleLog(LOG_RULE, szFormat, arg1, arg2, arg3, arg4, arg5, arg6)
#define RULLOG7(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7) LogInstance.SimpleLog(LOG_RULE, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
#define RULLOG8(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) LogInstance.SimpleLog(LOG_RULE, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
#define RULLOG9(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) LogInstance.SimpleLog(LOG_RULE, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
#else
#define RULLOG(x) (void*)0
#define RULLOG0(LogInstance, szString) (void*)0
#define RULLOG1(LogInstance, szFormat, arg1) (void*)0
#define RULLOG2(LogInstance, szFormat, arg1, arg2) (void*)0
#define RULLOG3(LogInstance, szFormat, arg1, arg2, arg3) (void*)0
#define RULLOG4(LogInstance, szFormat, arg1, arg2, arg3, arg4) (void*)0
#define RULLOG5(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5) (void*)0
#define RULLOG6(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6) (void*)0
#define RULLOG7(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7) (void*)0
#define RULLOG8(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) (void*)0
#define RULLOG9(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) (void*)0
#endif
// -------------------------------------------------------------------------------------
// Detail Log Type
#ifdef USE_LOG_DETAIL
#define DETLOG(x) x
#define DETLOG0(LogInstance, szString) LogInstance.DetailLog(LOG_DETAIL, LOG_FFL, szString)
#define DETLOG1(LogInstance, szFormat, arg1) LogInstance.DetailLog(LOG_DETAIL, LOG_FFL, szFormat, arg1)
#define DETLOG2(LogInstance, szFormat, arg1, arg2) LogInstance.DetailLog(LOG_DETAIL, LOG_FFL, szFormat, arg1, arg2)
#define DETLOG3(LogInstance, szFormat, arg1, arg2, arg3) LogInstance.DetailLog(LOG_DETAIL, LOG_FFL, szFormat, arg1, arg2, arg3)
#define DETLOG4(LogInstance, szFormat, arg1, arg2, arg3, arg4) LogInstance.DetailLog(LOG_DETAIL, LOG_FFL, szFormat, arg1, arg2, arg3, arg4)
#define DETLOG5(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5) LogInstance.DetailLog(LOG_DETAIL, LOG_FFL, szFormat, arg1, arg2, arg3, arg4, arg5)
#define DETLOG6(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6) LogInstance.DetailLog(LOG_DETAIL, LOG_FFL, szFormat, arg1, arg2, arg3, arg4, arg5, arg6)
#define DETLOG7(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7) LogInstance.DetailLog(LOG_DETAIL, LOG_FFL, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
#define DETLOG8(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) LogInstance.DetailLog(LOG_DETAIL, LOG_FFL, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
#define DETLOG9(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) LogInstance.DetailLog(LOG_DETAIL, LOG_FFL, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
#define DETLOG10(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10) LogInstance.DetailLog(LOG_DETAIL, LOG_FFL, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10)
#else
#define DETLOG(x) (void*)0
#define DETLOG0(LogInstance, szString) (void*)0
#define DETLOG1(LogInstance, szFormat, arg1) (void*)0
#define DETLOG2(LogInstance, szFormat, arg1, arg2) (void*)0
#define DETLOG3(LogInstance, szFormat, arg1, arg2, arg3) (void*)0
#define DETLOG4(LogInstance, szFormat, arg1, arg2, arg3, arg4) (void*)0
#define DETLOG5(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5) (void*)0
#define DETLOG6(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6) (void*)0
#define DETLOG7(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7) (void*)0
#define DETLOG8(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) (void*)0
#define DETLOG9(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) (void*)0
#define DETLOG10(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10) (void*)0
#endif
#ifdef USE_LOG_SYSERR
#define SERLOG(x) x
#define SERLOG0(LogInstance, szString) LogInstance.DetailLog(LOG_SYSERR, LOG_FFL, szString)
#define SERLOG1(LogInstance, szFormat, arg1) LogInstance.DetailLog(LOG_SYSERR, LOG_FFL, szFormat, arg1)
#define SERLOG2(LogInstance, szFormat, arg1, arg2) LogInstance.DetailLog(LOG_SYSERR, LOG_FFL, szFormat, arg1, arg2)
#define SERLOG3(LogInstance, szFormat, arg1, arg2, arg3) LogInstance.DetailLog(LOG_SYSERR, LOG_FFL, szFormat, arg1, arg2, arg3)
#define SERLOG4(LogInstance, szFormat, arg1, arg2, arg3, arg4) LogInstance.DetailLog(LOG_SYSERR, LOG_FFL, szFormat, arg1, arg2, arg3, arg4)
#define SERLOG5(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5) LogInstance.DetailLog(LOG_SYSERR, LOG_FFL, szFormat, arg1, arg2, arg3, arg4, arg5)
#define SERLOG6(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6) LogInstance.DetailLog(LOG_SYSERR, LOG_FFL, szFormat, arg1, arg2, arg3, arg4, arg5, arg6)
#define SERLOG7(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7) LogInstance.DetailLog(LOG_SYSERR, LOG_FFL, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
#define SERLOG8(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) LogInstance.DetailLog(LOG_SYSERR, LOG_FFL, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
#define SERLOG9(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) LogInstance.DetailLog(LOG_SYSERR, LOG_FFL, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
#define SERLOG10(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10) LogInstance.DetailLog(LOG_SYSERR, LOG_FFL, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10)
#else
#define SERLOG(x) (void*)0
#define SERLOG0(LogInstance, szString) (void*)0
#define SERLOG1(LogInstance, szFormat, arg1) (void*)0
#define SERLOG2(LogInstance, szFormat, arg1, arg2) (void*)0
#define SERLOG3(LogInstance, szFormat, arg1, arg2, arg3) (void*)0
#define SERLOG4(LogInstance, szFormat, arg1, arg2, arg3, arg4) (void*)0
#define SERLOG5(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5) (void*)0
#define SERLOG6(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6) (void*)0
#define SERLOG7(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7) (void*)0
#define SERLOG8(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) (void*)0
#define SERLOG9(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) (void*)0
#define SERLOG10(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10) (void*)0
#endif
#ifdef USE_LOG_ERROR
#define ERRLOG(x) x
#define ERRLOG0(LogInstance, szString) LogInstance.DetailLog(LOG_ERROR, LOG_FFL, szString)
#define ERRLOG1(LogInstance, szFormat, arg1) LogInstance.DetailLog(LOG_ERROR, LOG_FFL, szFormat, arg1)
#define ERRLOG2(LogInstance, szFormat, arg1, arg2) LogInstance.DetailLog(LOG_ERROR, LOG_FFL, szFormat, arg1, arg2)
#define ERRLOG3(LogInstance, szFormat, arg1, arg2, arg3) LogInstance.DetailLog(LOG_ERROR, LOG_FFL, szFormat, arg1, arg2, arg3)
#define ERRLOG4(LogInstance, szFormat, arg1, arg2, arg3, arg4) LogInstance.DetailLog(LOG_ERROR, LOG_FFL, szFormat, arg1, arg2, arg3, arg4)
#define ERRLOG5(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5) LogInstance.DetailLog(LOG_ERROR, LOG_FFL, szFormat, arg1, arg2, arg3, arg4, arg5)
#define ERRLOG6(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6) LogInstance.DetailLog(LOG_ERROR, LOG_FFL, szFormat, arg1, arg2, arg3, arg4, arg5, arg6)
#define ERRLOG7(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7) LogInstance.DetailLog(LOG_ERROR, LOG_FFL, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
#define ERRLOG8(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) LogInstance.DetailLog(LOG_ERROR, LOG_FFL, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
#define ERRLOG9(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) LogInstance.DetailLog(LOG_ERROR, LOG_FFL, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
#define ERRLOG10(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10) LogInstance.DetailLog(LOG_ERROR, LOG_FFL, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10)
#else
#define ERRLOG(x) (void*)0
#define ERRLOG0(LogInstance, szString) (void*)0
#define ERRLOG1(LogInstance, szFormat, arg1) (void*)0
#define ERRLOG2(LogInstance, szFormat, arg1, arg2) (void*)0
#define ERRLOG3(LogInstance, szFormat, arg1, arg2, arg3) (void*)0
#define ERRLOG4(LogInstance, szFormat, arg1, arg2, arg3, arg4) (void*)0
#define ERRLOG5(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5) (void*)0
#define ERRLOG6(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6) (void*)0
#define ERRLOG7(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7) (void*)0
#define ERRLOG8(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) (void*)0
#define ERRLOG9(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) (void*)0
#define ERRLOG10(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10) void(*)0
#endif
#ifdef USE_LOG_DEBUG
#define DBGLOG(x) x
#define DBGLOG0(LogInstance, szString) LogInstance.DetailLog(LOG_DEBUG, LOG_FFL, szString)
#define DBGLOG1(LogInstance, szFormat, arg1) LogInstance.DetailLog(LOG_DEBUG, LOG_FFL, szFormat, arg1)
#define DBGLOG2(LogInstance, szFormat, arg1, arg2) LogInstance.DetailLog(LOG_DEBUG, LOG_FFL, szFormat, arg1, arg2)
#define DBGLOG3(LogInstance, szFormat, arg1, arg2, arg3) LogInstance.DetailLog(LOG_DEBUG, LOG_FFL, szFormat, arg1, arg2, arg3)
#define DBGLOG4(LogInstance, szFormat, arg1, arg2, arg3, arg4) LogInstance.DetailLog(LOG_DEBUG, LOG_FFL, szFormat, arg1, arg2, arg3, arg4)
#define DBGLOG5(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5) LogInstance.DetailLog(LOG_DEBUG, LOG_FFL, szFormat, arg1, arg2, arg3, arg4, arg5)
#define DBGLOG6(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6) LogInstance.DetailLog(LOG_DEBUG, LOG_FFL, szFormat, arg1, arg2, arg3, arg4, arg5, arg6)
#define DBGLOG7(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7) LogInstance.DetailLog(LOG_DEBUG, LOG_FFL, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
#define DBGLOG8(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) LogInstance.DetailLog(LOG_DEBUG, LOG_FFL, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
#define DBGLOG9(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) LogInstance.DetailLog(LOG_DEBUG, LOG_FFL, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
#else
#define DBGLOG(x) (void*)0
#define DBGLOG0(LogInstance, szString) (void*)0
#define DBGLOG1(LogInstance, szFormat, arg1) (void*)0
#define DBGLOG2(LogInstance, szFormat, arg1, arg2) (void*)0
#define DBGLOG3(LogInstance, szFormat, arg1, arg2, arg3) (void*)0
#define DBGLOG4(LogInstance, szFormat, arg1, arg2, arg3, arg4) (void*)0
#define DBGLOG5(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5) (void*)0
#define DBGLOG6(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6) (void*)0
#define DBGLOG7(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7) (void*)0
#define DBGLOG8(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) (void*)0
#define DBGLOG9(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) (void*)0
#endif
#ifdef USE_LOG_WARN
#define WRNLOG(x) x
#define WRNLOG0(LogInstance, szString) LogInstance.DetailLog(LOG_WARN, LOG_FFL, szString)
#define WRNLOG1(LogInstance, szFormat, arg1) LogInstance.DetailLog(LOG_WARN, LOG_FFL, szFormat, arg1)
#define WRNLOG2(LogInstance, szFormat, arg1, arg2) LogInstance.DetailLog(LOG_WARN, LOG_FFL, szFormat, arg1, arg2)
#define WRNLOG3(LogInstance, szFormat, arg1, arg2, arg3) LogInstance.DetailLog(LOG_WARN, LOG_FFL, szFormat, arg1, arg2, arg3)
#define WRNLOG4(LogInstance, szFormat, arg1, arg2, arg3, arg4) LogInstance.DetailLog(LOG_WARN, LOG_FFL, szFormat, arg1, arg2, arg3, arg4)
#define WRNLOG5(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5) LogInstance.DetailLog(LOG_WARN, LOG_FFL, szFormat, arg1, arg2, arg3, arg4, arg5)
#define WRNLOG6(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6) LogInstance.DetailLog(LOG_WARN, LOG_FFL, szFormat, arg1, arg2, arg3, arg4, arg5, arg6)
#define WRNLOG7(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7) LogInstance.DetailLog(LOG_WARN, LOG_FFL, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
#define WRNLOG8(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) LogInstance.DetailLog(LOG_WARN, LOG_FFL, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
#define WRNLOG9(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) LogInstance.DetailLog(LOG_WARN, LOG_FFL, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
#else
#define WRNLOG(x) (void*)0
#define WRNLOG0(LogInstance, szString) (void*)0
#define WRNLOG1(LogInstance, szFormat, arg1) (void*)0
#define WRNLOG2(LogInstance, szFormat, arg1, arg2) (void*)0
#define WRNLOG3(LogInstance, szFormat, arg1, arg2, arg3) (void*)0
#define WRNLOG4(LogInstance, szFormat, arg1, arg2, arg3, arg4) (void*)0
#define WRNLOG5(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5) (void*)0
#define WRNLOG6(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6) (void*)0
#define WRNLOG7(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7) (void*)0
#define WRNLOG8(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) (void*)0
#define WRNLOG9(LogInstance, szFormat, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) (void*)0
#endif
#if defined(__linux__) || defined(i386) || defined(_WIN32)
#define va_start_ext(Argument, pFormat) va_start(Argument, pFormat)
#else
#define va_start_ext(Argument, pFormat) va_start(Argument)
#endif
#endif

View File

@@ -0,0 +1,326 @@
#include "stdafx.h"
#include "MemoryPool.h"
#include <winsock2.h>
#include <windows.h>
#include <new>
#include <iostream>
#include <fstream>
const char* const CFixedPool::ms_strErrLogFileName = "FixedMemoryPool_ErrLog.txt";
struct CFixedPool::ChunkNode
{
ChunkNode* m_pNext;
};
struct CFixedPool::AllocateInfo
{
AllocateInfo* m_pNext;
static const int ms_nPaddingSize;
static const char* ms_strAllocatedPadding;
static const char* ms_strDeallocatedPadding;
static const char* ms_strNotUsedPadding;
};
const char* CFixedPool::AllocateInfo::ms_strAllocatedPadding = "Aloc";
const char* CFixedPool::AllocateInfo::ms_strDeallocatedPadding = "Free";
const char* CFixedPool::AllocateInfo::ms_strNotUsedPadding = "Nuse";
#ifdef MEMPOOL_DBGMODE
const int CFixedPool::AllocateInfo::ms_nPaddingSize = 4;
#else
const int CFixedPool::AllocateInfo::ms_nPaddingSize = 0;
#endif
DEFINE_ALLOCATOR(CFixedPool)
{
if(nSize != m_nOriginalSize)
{
return operator new(nSize);
}
m_PoolLock.Lock();
if(NULL == m_pNodeHead)
{
if(!AllocateChunks())
{
return NULL;
}
}
AllocateInfo* pNode = m_pNodeHead;
m_pNodeHead = m_pNodeHead->m_pNext;
++m_nTotalInUse;
m_PoolLock.Unlock();
char* pResult = reinterpret_cast<char*>(pNode);
#ifdef MEMPOOL_DBGMODE
memcpy(pResult + m_nPerAllocateSize - AllocateInfo::ms_nPaddingSize,
AllocateInfo::ms_strAllocatedPadding, AllocateInfo::ms_nPaddingSize);
#endif
return pResult + sizeof(AllocateInfo);
}
DEFINE_DEALLOCATOR(CFixedPool)
{
if(NULL == pDelete)
{
return;
}
if(nSize != m_nOriginalSize)
{
operator delete(pDelete);
return;
}
char* pszDelete = reinterpret_cast<char*>(pDelete) - sizeof(AllocateInfo);
AllocateInfo* pNode = reinterpret_cast<AllocateInfo*>(pszDelete);
#ifdef MEMPOOL_DBGMODE
// <09><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>÷ο<C3B7> Ȥ<><C8A4> <20>޸𸮸<DEB8> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
const char* pszPadding = pszDelete + m_nPerAllocateSize - AllocateInfo::ms_nPaddingSize;
if(0 != memcmp(pszPadding, AllocateInfo::ms_strAllocatedPadding, AllocateInfo::ms_nPaddingSize))
{
LogBufferOverflow(pszDelete);
}
#endif
m_PoolLock.Lock();
pNode->m_pNext = m_pNodeHead;
m_pNodeHead = pNode;
--m_nTotalInUse;
m_PoolLock.Unlock();
}
bool CFixedPool::AllocateChunks()
{
// Allocation and make list
ChunkNode* pChunkNode = reinterpret_cast<ChunkNode*>(
::operator new(sizeof(ChunkNode) + m_nPerAllocateSize * m_nPerAllocateNum));
if(0 == pChunkNode)
{
// Chunk <20>޸<EFBFBD><DEB8><EFBFBD> <20>Ҵ<EFBFBD> <20><><EFBFBD><EFBFBD>.
return false;
}
pChunkNode->m_pNext = m_pChunkHead;
m_pChunkHead = pChunkNode;
m_pNodeHead = reinterpret_cast<AllocateInfo*>(m_pChunkHead + 1);
m_nTotalAllocated += m_nPerAllocateNum; // <20><>ü <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
char* pMakeList = reinterpret_cast<char*>(m_pNodeHead);
size_t nAllocated = m_nPerAllocateNum - 1;
while(0 < nAllocated--)
{
reinterpret_cast<AllocateInfo*>(pMakeList)->m_pNext =
reinterpret_cast<AllocateInfo*>(pMakeList + m_nPerAllocateSize);
pMakeList += m_nPerAllocateSize;
#ifdef MEMPOOL_DBGMODE
// <09>޸𸮰<DEB8> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD> <20><>Ÿ<EFBFBD><C5B8><EFBFBD><EFBFBD> <20>е<EFBFBD><D0B5><EFBFBD> <20><><EFBFBD><EFBFBD>.
memcpy(pMakeList - AllocateInfo::ms_nPaddingSize,
AllocateInfo::ms_strNotUsedPadding, AllocateInfo::ms_nPaddingSize);
#endif
}
reinterpret_cast<AllocateInfo*>(pMakeList)->m_pNext = 0;
return true;
}
CFixedPool::CFixedPool()
: m_pChunkHead(NULL), m_pNodeHead(NULL),
m_nOriginalSize(0), m_nPerAllocateNum(0), m_nPerAllocateSize(0),
m_nTotalAllocated(0), m_nTotalInUse(0)
{
}
CFixedPool::CFixedPool(size_t nPerAllocateSize, size_t nPerAllocateNum,
const char* strMaxPoolName, size_t nNameLen)
: m_pChunkHead(NULL), m_pNodeHead(NULL),
m_nOriginalSize(0), m_nPerAllocateNum(0), m_nPerAllocateSize(0),
m_nTotalAllocated(0), m_nTotalInUse(0)
{
Initialize(nPerAllocateSize, nPerAllocateNum, strMaxPoolName, nNameLen);
}
CFixedPool::~CFixedPool()
{
Destroy();
}
bool CFixedPool::Initialize(size_t nPerAllocateSize, size_t nPerAllocateNum,
const char* strMaxPoolName, size_t nNameLen)
{
Destroy();
m_nOriginalSize = nPerAllocateSize;
m_nPerAllocateNum = nPerAllocateNum;
m_nPerAllocateSize = nPerAllocateSize + GetLeastAllocateSize();
const size_t nLastPos = min(nNameLen, MAX_POOL_NAME - 1);
strncpy(m_pszPoolName, strMaxPoolName, nLastPos);
m_pszPoolName[nLastPos] = 0;
return true;
}
void CFixedPool::LogBufferOverflow(const char* lpBuffer)
{
FILE* pLogFile = fopen(ms_strErrLogFileName, "ab");
if(NULL != pLogFile)
{
SYSTEMTIME sysTime;
GetLocalTime(&sysTime);
__try
{
fprintf(pLogFile, "\n[%04d-%02d-%02d %02d:%02d:%02d] %s <20>޸<EFBFBD><DEB8><EFBFBD> Ǯ<><C7AE><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>÷ο<C3B7> <20>Ǵ<EFBFBD>, "
"<EFBFBD>޸<EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20>־<EFBFBD><D6BE><EFBFBD><EFBFBD>ϴ<EFBFBD>. PerAllocateSize = %d(0x%08x)\n<",
sysTime.wYear, sysTime.wMonth, sysTime.wDay, sysTime.wHour, sysTime.wMinute, sysTime.wSecond, m_pszPoolName,
m_nPerAllocateSize, m_nPerAllocateSize);
fwrite(lpBuffer, m_nPerAllocateSize * 2, 1, pLogFile);
}
__finally
{
fprintf(pLogFile, ">");
fclose(pLogFile);
}
}
}
void CFixedPool::Destroy()
{
PoolLock::Syncronize sync(m_PoolLock);
if(0 != m_nTotalInUse)
{
// <09>޸<EFBFBD><DEB8><EFBFBD> <20><><EFBFBD><EFBFBD> <20>α׸<CEB1> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>. (Chunk<6E><6B> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>޸𸮸<DEB8> ã<>Ƴ<EFBFBD><C6B3><EFBFBD>.)
FILE* pLogFile = fopen(ms_strErrLogFileName, "ab");
if(NULL != pLogFile)
{
SYSTEMTIME sysTime;
GetLocalTime(&sysTime);
fprintf(pLogFile, "[%d-%d-%d %d:%d:%d] %s <20>޸<EFBFBD><DEB8><EFBFBD> Ǯ<><C7AE><EFBFBD><EFBFBD> %d<><64><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʾҽ<CABE><D2BD>ϴ<EFBFBD>. <20>α׷<CEB1> <20><><EFBFBD><EFBFBD><EFBFBD>մϴ<D5B4>.\r\n",
sysTime.wYear, sysTime.wMonth, sysTime.wDay, sysTime.wHour, sysTime.wMinute, sysTime.wSecond,
m_pszPoolName, m_nTotalInUse);
fclose(pLogFile);
}
}
for(ChunkNode* pChunkNode = m_pChunkHead; NULL != pChunkNode;)
{
ChunkNode* pDelNode = pChunkNode;
pChunkNode = pChunkNode->m_pNext;
delete pDelNode;
}
m_nTotalAllocated = m_nTotalInUse = 0;
m_pChunkHead = NULL;
m_pNodeHead = NULL;
}
size_t CFixedPool::GetLeastAllocateSize()
{
return sizeof(AllocateInfo) + AllocateInfo::ms_nPaddingSize;
}
const char* CFixedPool::GetErrFileName()
{
return ms_strErrLogFileName;
}
void CFixedPoolTest::DoTest()
{
const char* const strErrLogFileName = CFixedPool::GetErrFileName();
printf("%s Test Started.\n", __FUNCTION__);
remove(strErrLogFileName);
CFixedPool pool;
const char* pName = "<EFBFBD>׽<EFBFBD>ƮǮ";
const int nSize = 10;
const int nPerAllocate = 100;
const int MAX_ALLOC = nPerAllocate * 10;
void* pAlloc[MAX_ALLOC];
pool.Initialize(nSize, nPerAllocate, pName, strlen(pName));
for(int i = 0; i < MAX_ALLOC; ++i)
{
pAlloc[i] = pool.ALLOC(nSize);
}
for(int i = 0; i < MAX_ALLOC; ++i)
{
pool.FREE(pAlloc[i], nSize);
}
pool.Destroy();
FILE* pFile = fopen(strErrLogFileName, "rb");
if(NULL == pFile)
{
printf("\tTest Successed!\n");
}
else
{
fclose(pFile);
#ifdef WIN32
char szPath[MAX_PATH];
char szFileNameWithPath[MAX_PATH];
UINT nResult = GetWindowsDirectory(szPath, MAX_PATH);
if(0 != nResult && nResult <= MAX_PATH)
{
_snprintf(szFileNameWithPath, MAX_PATH, "%s\\NotePad.exe %s", szPath, strErrLogFileName);
WinExec(szFileNameWithPath, SW_SHOW);
}
#endif
printf("\tMemory Leak or Curruption Detected!\n\tPlease See %s File\n", strErrLogFileName);
}
printf("%s Test Completed.\n\n", __FUNCTION__);
}

View File

@@ -0,0 +1,76 @@
#ifndef _MEMORYPOOL_H_
#define _MEMORYPOOL_H_
#include <cstdlib>
#include "../Thread/Lock.h"
#define MEMPOOL_DBGMODE
#define ALLOC(nSize) Allocate((nSize))
#define FREE(pDelete, nSize) Deallocate((pDelete), (nSize))
#define DECLARE_ALLOCATOR void* Allocate(size_t nSize)
#define DECLARE_DEALLOCATOR void Deallocate(void* pDelete, size_t nSize)
#define DEFINE_ALLOCATOR(className) void* className::Allocate(size_t nSize)
#define DEFINE_DEALLOCATOR(className) void className::Deallocate(void* pDelete, size_t nSize)
class CFixedPool
{
public:
enum { MAX_POOL_NAME = 32 };
CFixedPool();
CFixedPool(size_t nPerAllocateSize, size_t nPerAllocateNum,
const char* strMaxPoolName, size_t nNameLen);
~CFixedPool();
bool Initialize(size_t nPerAllocateSize, size_t nPerAllocateNum,
const char* strMaxPoolName, size_t nNameLen);
void Destroy();
unsigned long GetTotalUse() const { return static_cast<unsigned long>(m_nTotalInUse); }
static size_t GetLeastAllocateSize();
static const char* GetErrFileName();
DECLARE_ALLOCATOR;
DECLARE_DEALLOCATOR;
private:
bool AllocateChunks();
void LogBufferOverflow(const char* lpBuffer);
typedef CCSLock PoolLock;
struct ChunkNode;
struct AllocateInfo;
PoolLock m_PoolLock;
ChunkNode* m_pChunkHead;
AllocateInfo* m_pNodeHead;
size_t m_nOriginalSize;
size_t m_nPerAllocateSize;
size_t m_nPerAllocateNum;
size_t m_nTotalAllocated;
size_t m_nTotalInUse;
char m_pszPoolName[MAX_POOL_NAME];
static const char* const ms_strErrLogFileName;
};
class CFixedPoolTest
{
public:
void DoTest();
};
#endif

View File

@@ -0,0 +1,36 @@
#include "stdafx.h"
#include "INET_Addr.h"
#include "GMMemory.h"
void INET_Addr::set_addr(const char* addr, const unsigned short port)
{
memset(&m_SockAddr, 0, sizeof(sockaddr));
sockaddr_in& addr_in = *reinterpret_cast<sockaddr_in*>(&m_SockAddr);
addr_in.sin_family = AF_INET;
addr_in.sin_addr.s_addr = (NULL == addr) ? htonl(INADDR_ANY) : inet_addr(addr);
addr_in.sin_port = (0 == port) ? 0 : htons(port);
m_iAddrLen = sizeof(sockaddr_in);
}
void INET_Addr::set_addr(const sockaddr& addr, const int size)
{
m_SockAddr = addr;
m_iAddrLen = size;
}
void INET_Addr::set_addr(const IN_ADDR addr, const unsigned short port)
{
memset(&m_SockAddr, 0, sizeof(sockaddr));
sockaddr_in& addr_in = *reinterpret_cast<sockaddr_in*>(&m_SockAddr);
addr_in.sin_family = AF_INET;
addr_in.sin_addr = addr;
addr_in.sin_port = (0 == port) ? 0 : htons(port);
m_iAddrLen = sizeof(sockaddr_in);
}

View File

@@ -0,0 +1,48 @@
#ifndef _GAMA_INET_ADDR_
#define _GAMA_INET_ADDR_
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <winsock2.h>
#include <windows.h>
class INET_Addr
{
public:
INET_Addr() : m_iAddrLen(0) { memset(&m_SockAddr, 0, sizeof(SOCKADDR)); }
INET_Addr(const char* addr, unsigned short port) { set_addr(addr, port); }
INET_Addr(IN_ADDR addr, unsigned short port) { set_addr(addr, port); }
INET_Addr(sockaddr& addr, int size) { set_addr(addr, size); }
~INET_Addr() { }
void clear() { m_iAddrLen = 0; memset(&m_SockAddr, 0, sizeof(SOCKADDR)); }
void set_addr(const char* addr, const unsigned short port);
void set_addr(const IN_ADDR addr, const unsigned short port);
void set_addr(const sockaddr& addr, const int size);
// Winsock<63>Լ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ؼ<EFBFBD> const<73><74> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʾ<EFBFBD><CABE><EFBFBD>.
sockaddr& get_addr() { return m_SockAddr; }
const sockaddr_in& get_addr_in() const { return reinterpret_cast<const sockaddr_in&>(m_SockAddr); }
unsigned short get_port_in() const { return ntohs(reinterpret_cast<const sockaddr_in&>(m_SockAddr).sin_port); }
const char* get_addr_string() const { return inet_ntoa(reinterpret_cast<const sockaddr_in&>(m_SockAddr).sin_addr); }
int get_size() const { return m_iAddrLen; }
int* get_size_ptr() { return &m_iAddrLen; }
void set_size(int n) { m_iAddrLen = n; }
static int get_addr_buffer_size() { return sizeof(sockaddr); }
private:
sockaddr m_SockAddr;
int m_iAddrLen;
};
#endif

View File

@@ -0,0 +1,31 @@
#include "stdafx.h"
#include "Dispatch.h"
#include "../Session/Session.h"
#include "../../Stream/Buffer/Buffer.h"
#include "../../Stream/Buffer/BufferFactory.h"
#include "PoolDispatchFactory.h"
#include "../../Log/ServerLog.h"
void CEchoDispatch::Connected()
{
DETLOG1(g_Log, "this:0x%p Connected", this);
}
void CEchoDispatch::Disconnected()
{
DETLOG1(g_Log, "this:0x%p Disconnected", this);
}
bool CEchoDispatch::ParsePacket (char* const lpStream_In, unsigned long* dwStreamSIze_InOut)
{
unsigned long dwReceived = *dwStreamSIze_InOut;
CBuffer* lpEchoBuffer = CREATE_BUFFER(m_Session.GetPolicy().GetBufferFactory(), dwReceived);
memcpy(lpEchoBuffer->wr_ptr(), lpStream_In, dwReceived);
lpEchoBuffer->wr_ptr(dwReceived);
return m_Session.SendPending(lpEchoBuffer);
}

View File

@@ -0,0 +1,91 @@
#ifndef _GAMA_SERVER_NETWORK_DISPATCH_H_
#define _GAMA_SERVER_NETWORK_DISPATCH_H_
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
class CSession;
// Session<6F><6E><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> DispatchŬ<68><C5AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̽<EFBFBD>.
class CPacketDispatch
{
public:
CPacketDispatch(CSession& Session) : m_Session(Session) { }
virtual ~CPacketDispatch() { }
// In : char* const lpStream_In <20><><EFBFBD><EFBFBD> <20><>Ʈ<EFBFBD><C6AE>
// unsigned long* dwStreamSize_InOut <20><><EFBFBD><EFBFBD> <20><>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD>
// out : Return <20><>Ŷ <20>Ľ<EFBFBD> <20><><EFBFBD><EFBFBD> / <20><><EFBFBD><EFBFBD>(<28><><EFBFBD>н<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>)
// unsigned long* dwStreamSize_InOut <20>Ľ<EFBFBD><C4BD><EFBFBD> <20><><EFBFBD><EFBFBD>
virtual bool ParsePacket(char* const lpStream_In, unsigned long* dwStreamSize_InOut) = 0;
virtual bool Dispatch() = 0;
virtual void Connected() { }
virtual void Disconnected() { }
CSession& GetSession() { return m_Session; }
protected:
CSession& m_Session;
};
class CDispatchFactory
{
public:
virtual ~CDispatchFactory() = 0;
virtual CPacketDispatch* CreateDispatch(CSession& Session) = 0;
virtual void DeleteDispatch(CPacketDispatch* lpDispatch) = 0;
};
inline CDispatchFactory::~CDispatchFactory() { }
template<typename DispatchType>
class CDefaultDispatchFactory : public CDispatchFactory
{
public:
virtual ~CDefaultDispatchFactory() { }
virtual CPacketDispatch* CreateDispatch(CSession& Session) { return new DispatchType(Session); }
virtual void DeleteDispatch(CPacketDispatch* lpDispatch) { delete lpDispatch; }
};
// -----------------------------------------------------------------------
// <20>׽<EFBFBD>Ʈ<EFBFBD><C6AE> Sample Dispatchers....
// <20><><EFBFBD><EFBFBD> <20><>Ŷ<EFBFBD><C5B6> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>. ó<><C3B3><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ʴ´<CAB4>.
class CNullDispatch : public CPacketDispatch
{
public:
CNullDispatch(CSession& Session) : CPacketDispatch(Session) { }
virtual ~CNullDispatch() { }
virtual bool ParsePacket (char* const lpStream_In, unsigned long* dwStreamSIze_InOut) { return true; }
virtual bool Dispatch() { return true; }
};
// <20><><EFBFBD><EFBFBD> <20><>Ŷ<EFBFBD><C5B6> <20>״<EFBFBD><D7B4><EFBFBD> <20>ٽ<EFBFBD> <20><><EFBFBD><EFBFBD> <20>ش<EFBFBD>.
class CEchoDispatch : public CPacketDispatch
{
public:
CEchoDispatch(CSession& Session) : CPacketDispatch(Session) { }
virtual ~CEchoDispatch() { }
virtual void Connected();
virtual void Disconnected();
virtual bool ParsePacket (char* const lpStream_In, unsigned long* dwStreamSIze_InOut);
virtual bool Dispatch() { return true; }
};
#endif

View File

@@ -0,0 +1,34 @@
#ifndef _GAMA_SERVER_NETWORK_POOL_DISPATCH_FACTORY_H_
#define _GAMA_SERVER_NETWORK_POOL_DISPATCH_FACTORY_H_
#include "Dispatch.h"
#include <boost/pool/pool.hpp>
template<typename DispatchType>
class CPoolDispatchFactory : public CDispatchFactory
{
public:
CPoolDispatchFactory() : m_DispatchPool(sizeof(DispatchType)) { }
virtual ~CPoolDispatchFactory() { }
virtual CPacketDispatch* CreateDispatch(CSession& Session)
{
void* ptr = m_DispatchPool.malloc();
return new (ptr) DispatchType(Session);
}
virtual void DeleteDispatch(CPacketDispatch* lpDispatch)
{
lpDispatch->~CPacketDispatch();
m_DispatchPool.free(lpDispatch);
}
protected:
typedef boost::pool<> DispatchPool;
DispatchPool m_DispatchPool;
};
#endif

View File

@@ -0,0 +1,272 @@
#include "stdafx.h"
#include "ServerRequest.h"
#include <Network/Session/Session.h>
#include <Network/Dispatch/Dispatch.h>
#include <Log/ServerLog.h>
#define REQUEST_LOG(x) x
enum RequestConst
{
CANNOT_ADD_REQUEST = (1 << 0)
};
CServerRequest& CServerRequest::GetInstance()
{
static CServerRequest serverRequest;
return serverRequest;
}
CServerRequest::Result::Result(unsigned long dwRequestKey, bool bRemove)
: m_bRemove(bRemove)
{
m_lpSrcDispatch = bRemove
// Request<73><74> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
? CServerRequest::GetInstance().PopRequest(dwRequestKey)
// Request<73><74> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʴ´<CAB4>.
: CServerRequest::GetInstance().GetRequest(dwRequestKey);
}
CServerRequest::Result::~Result()
{
if(0 != m_lpSrcDispatch && m_bRemove)
{
m_lpSrcDispatch->GetSession().Release();
}
}
CSession* CServerRequest::Result::GetSession()
{
return (0 != m_lpSrcDispatch) ? &m_lpSrcDispatch->GetSession() : 0;
}
void CServerRequest::RequestInfo::ProcessRemove()
{
if(m_lpSrcDispatch)
{
if(m_lpTimeoutRequest)
{
m_lpTimeoutRequest(m_lpSrcDispatch);
}
m_lpSrcDispatch->GetSession().Release();
}
if(m_lpDstDispatch)
{
m_lpDstDispatch->GetSession().Release();
}
}
// return value : RequestKey
unsigned long CServerRequest::AddRequest(CPacketDispatch* lpSrcDispatch,
CPacketDispatch* lpDstDispatch,
unsigned long dwDurationSec,
TimeoutRequest lpTimeoutRequest)
{
if( 0 != lpSrcDispatch &&
0 != lpDstDispatch &&
0 != dwDurationSec)
{
LockType::Syncronize sync(m_RequestLock);
if(!(m_dwRequestFlags & CANNOT_ADD_REQUEST))
{
CSession& SrcSession = lpSrcDispatch->GetSession();
CSession& DstSession = lpDstDispatch->GetSession();
if(0 == m_dwRequestCounter)
{
++m_dwRequestCounter;
}
unsigned long dwRequestCounter = m_dwRequestCounter++;
if(m_RequestMap.insert(std::make_pair(dwRequestCounter,
RequestInfo(lpSrcDispatch, lpDstDispatch, dwDurationSec, lpTimeoutRequest))).second)
{
SrcSession.AddRef();
DstSession.AddRef();
REQUEST_LOG(DETLOG5(g_Log, "SS:0x%p/DP:0x%p/IP:%15s/Request:%d/DstDP:0x%p/Request Added",
&lpSrcDispatch->GetSession(), lpSrcDispatch,
lpSrcDispatch->GetSession().GetRemoteAddr().get_addr_string(),
dwRequestCounter, lpDstDispatch));
return dwRequestCounter;
}
}
}
return 0;
}
void CServerRequest::RemoveRequest(unsigned long dwRequestKey)
{
m_RequestLock.Lock();
RequestMap::iterator pos = m_RequestMap.find(dwRequestKey);
RequestMap::iterator end = m_RequestMap.end();
RequestInfo info;
if(pos != end)
{
info = pos->second;
REQUEST_LOG(DETLOG5(g_Log, "SS:0x%p/DP:0x%p/IP:%15s/Request:%d/DstDP:0x%p/Request Removed(By RequestKey)",
&info.m_lpSrcDispatch->GetSession(), info.m_lpSrcDispatch,
info.m_lpSrcDispatch->GetSession().GetRemoteAddr().get_addr_string(),
pos->first, info.m_lpDstDispatch));
pos = m_RequestMap.erase(pos);
}
m_RequestLock.Unlock();
info.ProcessRemove();
}
void CServerRequest::RemoveRequest(CPacketDispatch* lpDispatch)
{
LockType::Syncronize sync(m_RequestLock);
RequestMap::iterator pos = m_RequestMap.begin();
RequestMap::iterator end = m_RequestMap.end();
for(; pos != end;)
{
RequestInfo& info = pos->second;
if(lpDispatch == info.m_lpSrcDispatch ||
lpDispatch == info.m_lpDstDispatch)
{
REQUEST_LOG(DETLOG5(g_Log, "SS:0x%p/DP:0x%p/IP:%15s/Request:%d/DstDP:0x%p/Request Removed(By TargetPtr)",
&info.m_lpSrcDispatch->GetSession(), info.m_lpSrcDispatch,
info.m_lpSrcDispatch->GetSession().GetRemoteAddr().get_addr_string(),
pos->first, info.m_lpDstDispatch));
info.ProcessRemove();
pos = m_RequestMap.erase(pos);
}
else
{
++pos;
}
}
}
void CServerRequest::RemoveTimeoutRequest()
{
LockType::Syncronize sync(m_RequestLock);
RequestMap::iterator pos = m_RequestMap.begin();
RequestMap::iterator end = m_RequestMap.end();
for(; pos != end;)
{
RequestInfo& info = pos->second;
if(0 == --(info.m_dwDurationSec))
{
REQUEST_LOG(DETLOG5(g_Log, "SS:0x%p/DP:0x%p/IP:%15s/Request:%d/DstDP:0x%p/Request Removed(By Timeout)",
&info.m_lpSrcDispatch->GetSession(), info.m_lpSrcDispatch,
info.m_lpSrcDispatch->GetSession().GetRemoteAddr().get_addr_string(),
pos->first, info.m_lpDstDispatch));
info.ProcessRemove();
pos = m_RequestMap.erase(pos);
}
else
{
++pos;
}
}
}
void CServerRequest::RemoveAllRequest()
{
LockType::Syncronize sync(m_RequestLock);
RequestMap::iterator pos = m_RequestMap.begin();
RequestMap::iterator end = m_RequestMap.end();
for(; pos != end; ++pos)
{
pos->second.ProcessRemove();
}
m_RequestMap.clear();
}
void CServerRequest::RequestOn()
{
LockType::Syncronize sync(m_RequestLock);
m_dwRequestFlags &= ~CANNOT_ADD_REQUEST;
}
void CServerRequest::RequestOff()
{
LockType::Syncronize sync(m_RequestLock);
m_dwRequestFlags |= CANNOT_ADD_REQUEST;
}
CServerRequest::CServerRequest()
{
}
CServerRequest::~CServerRequest()
{
RequestOff();
RemoveAllRequest();
}
CPacketDispatch* CServerRequest::GetRequest(unsigned long dwRequestKey)
{
LockType::Syncronize sync(m_RequestLock);
RequestMap::iterator pos = m_RequestMap.find(dwRequestKey);
return (pos != m_RequestMap.end()) ? pos->second.m_lpSrcDispatch : 0;
}
CPacketDispatch* CServerRequest::PopRequest(unsigned long dwRequestKey)
{
LockType::Syncronize sync(m_RequestLock);
RequestMap::iterator pos = m_RequestMap.find(dwRequestKey);
if(pos != m_RequestMap.end())
{
RequestInfo info = pos->second;
REQUEST_LOG(DETLOG5(g_Log, "SS:0x%p/DP:0x%p/IP:%15s/Request:%d/DstDP:0x%p/Request Removed(By Pop Request)",
&info.m_lpSrcDispatch->GetSession(), info.m_lpSrcDispatch,
info.m_lpSrcDispatch->GetSession().GetRemoteAddr().get_addr_string(),
pos->first, info.m_lpDstDispatch));
m_RequestMap.erase(pos);
return info.m_lpSrcDispatch;
}
return 0;
}

View File

@@ -0,0 +1,103 @@
#ifndef _SERVER_REQUEST_H_
#define _SERVER_REQUEST_H_
#include <map>
#include <vector>
#include <utility>
#include <Thread/Lock.h>
class CSession;
class CPacketDispatch;
class CServerRequest
{
public:
typedef void (*TimeoutRequest)(CPacketDispatch* lpSrcDispatch);
static CServerRequest& GetInstance();
// return value : RequestKey
unsigned long AddRequest(CPacketDispatch* lpSrcDispatch, CPacketDispatch* lpDstDispatch,
unsigned long dwDurationSec, TimeoutRequest lpTimeoutRequest = 0);
void RemoveRequest(unsigned long dwRequestKey);
void RemoveRequest(CPacketDispatch* lpDispatch);
void RemoveTimeoutRequest();
void RemoveAllRequest();
void RequestOn();
void RequestOff();
class Result
{
public:
explicit Result(unsigned long dwRequestKey, bool bRemove = true);
~Result();
CPacketDispatch* GetDispatch() { return m_lpSrcDispatch; }
CSession* GetSession();
private:
// new <20><> delete<74><65> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><>.
void* operator new (size_t size);
void operator delete (void* ptr);
CPacketDispatch* m_lpSrcDispatch;
bool m_bRemove;
};
private:
CServerRequest();
~CServerRequest();
// return value : SrcRequest
CPacketDispatch* GetRequest(unsigned long dwRequestKey);
CPacketDispatch* PopRequest(unsigned long dwRequestKey);
struct RequestInfo
{
CPacketDispatch* m_lpSrcDispatch;
CPacketDispatch* m_lpDstDispatch;
unsigned long m_dwDurationSec;
TimeoutRequest m_lpTimeoutRequest;
RequestInfo()
: m_lpSrcDispatch(0),
m_lpDstDispatch(0),
m_dwDurationSec(0),
m_lpTimeoutRequest(0)
{
}
RequestInfo(CPacketDispatch* lpSrcDispatch, CPacketDispatch* lpDstDispatch,
unsigned long dwDurationSec, TimeoutRequest lpTimeoutRequest)
: m_lpSrcDispatch(lpSrcDispatch),
m_lpDstDispatch(lpDstDispatch),
m_dwDurationSec(dwDurationSec),
m_lpTimeoutRequest(lpTimeoutRequest)
{
}
void ProcessRemove();
};
typedef CCSLock LockType;
typedef std::map<unsigned long, RequestInfo> RequestMap;
LockType m_RequestLock;
CACHE_PAD(RequestLock, sizeof(LockType));
RequestMap m_RequestMap;
unsigned long m_dwRequestCounter;
unsigned long m_dwRequestFlags;
};
#endif

View File

@@ -0,0 +1,48 @@
#include "stdafx.h"
#include "CompletionHandler.h"
CCompletionHandler::CCompletionHandler()
: m_hIOCP(INVALID_HANDLE_VALUE), m_nThread(0), m_nTimeOutMS(0)
{
}
CCompletionHandler::~CCompletionHandler()
{
Destroy();
}
bool CCompletionHandler::Initialize(unsigned long nThread, unsigned long nTimeOutMS)
{
if(INVALID_HANDLE_VALUE != m_hIOCP)
{
return false;
}
m_hIOCP = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, NULL, nThread);
if(0 == m_hIOCP)
{
return false;
}
m_nThread = nThread;
m_nTimeOutMS = nTimeOutMS;
return true;
}
bool CCompletionHandler::Destroy()
{
if(INVALID_HANDLE_VALUE != m_hIOCP)
{
if(!CloseHandle(m_hIOCP))
{
return false;
}
}
m_hIOCP = INVALID_HANDLE_VALUE;
return true;
}

View File

@@ -0,0 +1,59 @@
#ifndef _CCOMPLETIONHANDLER_H_
#define _CCOMPLETIONHANDLER_H_
#include <winsock2.h>
#include <windows.h>
//-----------------------------------------------------------------------------
// CCompletionHandler Class
//-----------------------------------------------------------------------------
class CCompletionHandler
{
private:
HANDLE m_hIOCP;
unsigned long m_nThread;
unsigned long m_nTimeOutMS;
public:
CCompletionHandler();
virtual ~CCompletionHandler();
bool Initialize(unsigned long nThread = 0, unsigned long nTimeOutMS = INFINITE); // Completion Handler<65><72> <20>ʱ<EFBFBD>ȭ<EFBFBD>Ѵ<EFBFBD>.
bool Destroy(); // Completion Hander<65><72> <20>Ҹ<EFBFBD><D2B8><EFBFBD>Ų<EFBFBD><C5B2>.
bool AttachToHander(HANDLE hAttach, ULONG_PTR pCompletionKey); // Completion Handler<65><72> <20><> <20>ڵ<EFBFBD><DAB5><EFBFBD> <20>߰<EFBFBD><DFB0>Ѵ<EFBFBD>.
BOOL GetHanderStatus(LPDWORD lpNumOfBytes,
PULONG_PTR lpCompletionKey, LPOVERLAPPED *lpOverlapped); // <20>۾<EFBFBD><DBBE><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ڵ<EFBFBD><DAB5><EFBFBD> <20><><EFBFBD><EFBFBD> <20>´<EFBFBD>. <20>׵<EFBFBD><D7B5><EFBFBD><EFBFBD><EFBFBD> block<63>ȴ<EFBFBD>.
BOOL PostToHandler(unsigned long dwNumOfBytesTransfered,
ULONG_PTR dwCompletionKey, LPOVERLAPPED lpOverlapped); // Handler<65><72> <20>۾<EFBFBD><DBBE><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>߰<EFBFBD><DFB0>Ѵ<EFBFBD>.
};
//-----------------------------------------------------------------------------
// Inline Implementation ------------------------------------------------------
inline bool CCompletionHandler::AttachToHander(HANDLE hAttach, ULONG_PTR pCompletionKey)
{
return (0 != CreateIoCompletionPort(hAttach, m_hIOCP, pCompletionKey, m_nThread));
}
inline BOOL CCompletionHandler::GetHanderStatus(LPDWORD lpNumOfBytes,
PULONG_PTR lpCompletionKey, LPOVERLAPPED *lpOverlapped)
{
return GetQueuedCompletionStatus(m_hIOCP, lpNumOfBytes, lpCompletionKey, lpOverlapped, m_nTimeOutMS);
}
inline BOOL CCompletionHandler::PostToHandler(unsigned long dwNumOfBytesTransfered,
ULONG_PTR dwCompletionKey, LPOVERLAPPED lpOverlapped)
{
return PostQueuedCompletionStatus(m_hIOCP, dwNumOfBytesTransfered, dwCompletionKey, lpOverlapped);
}
#endif

View File

@@ -0,0 +1,354 @@
#include "stdafx.h"
#include "IOCPNet.h"
#include "IOWorker.h"
#include "CompletionHandler.h"
#include "../../Thread/ThreadMgr.h"
#include "../../Stream/Buffer/BufferFactory.h"
#include "../Session/Session.h"
#include "../Session/SessionMgr.h"
#include "../Listener/Listener.h"
#include "../Dispatch/Dispatch.h"
#include "../Winsock/SocketFactory.h"
#include "../../Utility/Resource/EnsureCleanup.h"
#include "../../Utility/Debug/DebugUtils.h"
#include "../../Log/ServerLog.h"
#include <mmsystem.h>
enum IOCPInternalFlag
{
INITIALIZED_IOCP = (1 << 0),
DESTROYED_IOCP = (1 << 1)
};
unsigned long GetOptimalThreadNum()
{
unsigned long dwThreadCount;
SYSTEM_INFO systemInfo;
GetSystemInfo(&systemInfo);
dwThreadCount = systemInfo.dwNumberOfProcessors * 2;
return dwThreadCount;
}
CIOCPNet::CIOCPNet()
: m_dwFlags(0),
m_lpSocketHandler(new (std::nothrow) CCompletionHandler),
m_lpThreadMgr(new (std::nothrow) CThreadMgr),
m_lpSessionMgr(new (std::nothrow) CSessionMgr)
{
WSADATA wsaData;
WSAStartup(0x0202, &wsaData);
}
CIOCPNet::~CIOCPNet()
{
Destroy();
WSACleanup();
}
// Desc : <20>ʱ<EFBFBD>ȭ <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
bool CIOCPNet::Initialize()
{
{
SessionLock::Syncronize sync(m_IOCPLock);
// <20>ʱ<EFBFBD>ȭ<EFBFBD><C8AD> <20>ѹ<EFBFBD><D1B9><EFBFBD> <20><> <20><> <20><><EFBFBD><EFBFBD>.
if(INITIALIZED_IOCP & m_dwFlags)
{
return false;
}
m_dwFlags |= INITIALIZED_IOCP;
}
if(0 == m_lpSocketHandler ||
0 == m_lpThreadMgr ||
0 == m_lpSessionMgr ||
!m_lpSocketHandler->Initialize())
{
return false;
}
// IOCP <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
unsigned long dwThreadNum = GetOptimalThreadNum();
while(0 != dwThreadNum--)
{
if(!m_lpThreadMgr->RegisterAndRun(
new (std::nothrow) CIOWorker(*m_lpSocketHandler)))
{
return false;
}
}
return true;
}
// Desc : Listener<65><72> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
bool CIOCPNet::AddListener(CSessionPolicy* lpSessionPolicy,
const char* lpListenAddress, unsigned short usPort,
unsigned long dwMaxListenPeding,
CValidateConnection* lpValidateConnection)
{
if(0 == lpSessionPolicy || !lpSessionPolicy->IsValid() ||
0 == m_lpSocketHandler || 0 == m_lpSessionMgr)
{
return false;
}
CListener* lpListener = new (std::nothrow) CListener(*m_lpSocketHandler,
*lpSessionPolicy, *m_lpSessionMgr, lpValidateConnection);
if(0 == lpListener)
{
return false;
}
if(!lpListener->Initialize(lpListenAddress, usPort, dwMaxListenPeding))
{
delete lpListener;
return false;
}
lpSessionPolicy->AddRef();
SessionLock::Syncronize sync(m_IOCPLock);
m_ListenerList.push_back(lpListener);
++m_SessionPolicyMap[lpSessionPolicy];
return true;
}
// Desc : <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
bool CIOCPNet::Connect(CSessionPolicy* lpSessionPolicy,
const char* lpConnectAddress, unsigned short usPort)
{
if(0 == lpSessionPolicy || !lpSessionPolicy->IsValid() ||
0 == m_lpSocketHandler || 0 == m_lpSessionMgr)
{
return false;
}
SOCKET hConnectedSocket = lpSessionPolicy->GetSocketFactory().CreateConnectedSocket(lpConnectAddress, usPort);
if(INVALID_SOCKET == hConnectedSocket)
{
ERRLOG3(g_Log, "Connected socket creation error : %d, destination : %s:%d",
WSAGetLastError(), lpConnectAddress, usPort);
}
else
{
CSession* lpSession = m_lpSessionMgr->CreateSession(*lpSessionPolicy);
if(0 != lpSession)
{
if(m_lpSocketHandler->AttachToHander(
reinterpret_cast<HANDLE>(hConnectedSocket),
reinterpret_cast<ULONG_PTR>(lpSession)))
{
lpSession->Socket(hConnectedSocket);
lpSession->SetAddress(INET_Addr(lpConnectAddress, usPort), INET_Addr());
DETLOG3(g_SessionLog, "SP:0x%p/DP:0x%p/IP:%15s/ Connect Success.",
lpSession, lpSession->GetDispatch(), lpConnectAddress);
lpSession->InternalRecv();
m_lpSessionMgr->Add(lpSession);
lpSessionPolicy->AddRef();
SessionLock::Syncronize sync(m_IOCPLock);
++m_SessionPolicyMap[lpSessionPolicy];
return true;
}
m_lpSessionMgr->DeleteSession(lpSession);
}
closesocket(hConnectedSocket);
}
return false;
}
// Desc : Listener<65><72> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ǵ<EFBFBD><C7B5><EFBFBD>, ConnectedSession<6F><6E> ó<><C3B3><EFBFBD><EFBFBD> <20>Ѵ<EFBFBD>.
void CIOCPNet::Process()
{
if(0 != m_lpSessionMgr)
{
m_lpSessionMgr->Process();
}
}
// Desc : <20><><EFBFBD><EFBFBD> Listener<65><72> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
bool CIOCPNet::Destroy()
{
m_IOCPLock.Lock();
if(!(m_dwFlags & DESTROYED_IOCP))
{
CThreadMgr* lpThreadMgr = 0;
CCompletionHandler* lpSocketHandler = 0;
CSessionMgr* lpSessionMgr = 0;
SessionPolicyMap tempMap(m_SessionPolicyMap);
m_SessionPolicyMap.clear();
std::swap(m_lpThreadMgr, lpThreadMgr);
std::swap(m_lpSocketHandler, lpSocketHandler);
std::swap(m_lpSessionMgr, lpSessionMgr);
m_dwFlags |= DESTROYED_IOCP;
m_IOCPLock.Unlock();
DestroyListener();
delete lpSessionMgr;
delete lpThreadMgr;
delete lpSocketHandler;
SessionPolicyMap::iterator pos = tempMap.begin();
SessionPolicyMap::iterator end = tempMap.end();
for(; pos != end; ++pos)
{
for(unsigned int nReleaseCount = pos->second;
0 != nReleaseCount; --nReleaseCount)
{
pos->first->Release();
}
}
return true;
}
m_IOCPLock.Unlock();
return false;
}
void CIOCPNet::DestroyListener()
{
ListenerList deleteList;
{
SessionLock::Syncronize sync(m_IOCPLock);
deleteList.splice(deleteList.end(), m_ListenerList);
}
ListenerList::iterator pos = deleteList.begin();
ListenerList::iterator end = deleteList.end();
for(; pos != end; ++pos)
{
delete (*pos);
}
}
// Desc : <20><><EFBFBD><EFBFBD> Accept<70><74> pending<6E>ϰ<EFBFBD> <20>ִ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
unsigned long CIOCPNet::GetAcceptPendingNum()
{
unsigned long dwPendingNum = 0;
SessionLock::Syncronize sync(m_IOCPLock);
for(ListenerList::iterator itr = m_ListenerList.begin();
itr != m_ListenerList.end(); ++itr)
{
dwPendingNum += (*itr)->GetPendingAcceptNum();
}
return dwPendingNum;
}
unsigned long CIOCPNet::GetSessionNum()
{
if(0 != m_lpSessionMgr)
{
return m_lpSessionMgr->GetSessionNum();
}
return 0;
}
/*
void CIOCPNet::LogListeners()
{
SessionLock::Syncronize sync(m_IOCPLock);
std::for_each(m_ListenerList.begin(), m_ListenerList.end(),
std::mem_fun(CListener::LogListenerStatus));
}
void CIOCPNet::LogConnected()
{
using namespace std;
unsigned int nStateNum[CSession::MAX_SESSION_STATE];
std::fill_n(nStateNum, unsigned int(CSession::MAX_SESSION_STATE), 0);
const char* szDelimiter = "// ------------------------------------------------------------------------------- ";
char szProgramName[MAX_PATH];
char szFileName[MAX_PATH];
char szTime[MAX_PATH];
SYSTEMTIME systemTime;
GetLocalTime(&systemTime);
DbgUtils::SetProgramName(szProgramName, MAX_PATH);
_snprintf(szTime, MAX_PATH, "%04d%02d%02d-%02d%02d%02d",
systemTime.wYear, systemTime.wMonth, systemTime.wDay,
systemTime.wHour, systemTime.wMinute, systemTime.wSecond);
_snprintf(szFileName, MAX_PATH, "%s/ConnectedLog-%s.txt", szProgramName, szTime);
fstream logfile(szFileName, ios::out | ios::app);
fstream::char_type endline = logfile.widen('\n');
logfile << szDelimiter << endline;
m_IOCPLock.Lock();
unsigned int nConnectedNum = 0;
ConnectedArray::iterator first = m_ConnectedArray.begin();
ConnectedArray::iterator last = m_ConnectedArray.end();
for(; first != last; ++first)
{
logfile << **first << endline;
++nStateNum[(*first)->m_cCurrentStatus];
++nConnectedNum;
}
m_IOCPLock.Unlock();
logfile << endline << szDelimiter << endline
<< "Time : " << szTime << endline << endline
<< "nUNINITIALIZED : " << nStateNum[CSession::UNINITIALIZED] << endline
<< "ACCEPT_PENDING : " << nStateNum[CSession::ACCEPT_PENDING] << endline
<< "CONNECTED : " << nStateNum[CSession::CONNECTED] << endline
<< "DISCONNECTED : " << nStateNum[CSession::DISCONNECTED] << endline
<< "Total : " << nConnectedNum << endl;
}
*/

View File

@@ -0,0 +1,61 @@
#ifndef _CIOCPMGR_H_
#define _CIOCPMGR_H_
#include <map>
#include <list>
#include "../../Thread/Lock.h"
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
class CListener;
class CSession;
class CSessionPolicy;
class CCompletionHandler;
class CThreadMgr;
class CSessionMgr;
class CValidateConnection;
class CIOCPNet
{
public:
CIOCPNet();
~CIOCPNet();
bool Initialize();
bool Destroy();
bool AddListener(CSessionPolicy* lpSessionPolicy,
const char* lpListenAddress, unsigned short usPort,
unsigned long dwMaxListenPeding = 10,
CValidateConnection* lpValidateConnection = 0);
bool Connect(CSessionPolicy* lpSessionPolicy,
const char* lpConnectAddress, unsigned short usPort);
void Process();
unsigned long GetAcceptPendingNum();
unsigned long GetSessionNum();
private:
void DestroyListener();
typedef std::list<CListener*> ListenerList;
typedef std::map<CSessionPolicy*, unsigned int> SessionPolicyMap;
typedef CCSLock SessionLock;
SessionLock m_IOCPLock;
CACHE_PAD(SessionLockPad, sizeof(SessionLock));
CCompletionHandler* m_lpSocketHandler;
CThreadMgr* m_lpThreadMgr;
CSessionMgr* m_lpSessionMgr;
ListenerList m_ListenerList;
SessionPolicyMap m_SessionPolicyMap;
unsigned long m_dwFlags;
};
#endif

View File

@@ -0,0 +1,64 @@
#include "stdafx.h"
#include "IOWorker.h"
#include "Overlapped.h"
#include "../IOCP/CompletionHandler.h"
#include "../Session/Session.h"
#include "../Listener/Listener.h"
#include <Log/ServerLog.h>
CIOWorker::CIOWorker(CCompletionHandler& SocketHandler)
: m_SocketHandler(SocketHandler)
{
}
CIOWorker::~CIOWorker()
{
}
unsigned int CIOWorker::Run()
{
COverlapped* lpOverlapped = 0;
while(true)
{
unsigned long dwProcessedBytes = 0;
ULONG_PTR lpSessionKey = 0;
OVERLAPPED* lpOverlappedStruct = 0;
BOOL bResult = m_SocketHandler.GetHanderStatus(&dwProcessedBytes,
&lpSessionKey, &lpOverlappedStruct);
if(0 == lpSessionKey)
{
DETLOG4(g_SessionLog, "SP:0x%p/lpOverlapped:0x%p/bResult:%s/Thread 0x%p Completed",
lpSessionKey, lpOverlappedStruct, bResult ? "T" : "F", GetCurrentThreadId());
break;
}
if(!bResult && 0 == lpOverlappedStruct)
{
// <20><> <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>, Ȥ<><C8A4> Ÿ<>Ӿƿ<D3BE>.
DETLOG4(g_SessionLog, "SP:0x%p/lpOverlapped:0x%p/bResult:%s/GetQueuedCompletionStatus error : %u",
lpSessionKey, lpOverlappedStruct, bResult ? "T" : "F", WSAGetLastError());
}
else
{
// Recv, Send, Accept<70><74> <20><>.
lpOverlapped = static_cast<COverlapped*>(lpOverlappedStruct);
lpOverlapped->Dispatch(bResult, lpSessionKey, dwProcessedBytes);
}
}
return 0;
}
BOOL CIOWorker::End()
{
m_SocketHandler.PostToHandler(0, 0, 0);
return true;
}

View File

@@ -0,0 +1,27 @@
#ifndef _IO_WORKER_H_
#define _IO_WORKER_H_
#include "../../Thread/Thread.h"
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
class CCompletionHandler;
class CIOWorker : public CThread
{
public:
CIOWorker(CCompletionHandler& SocketHandler);
virtual ~CIOWorker();
private:
virtual unsigned int Run();
virtual BOOL End();
CCompletionHandler& m_SocketHandler;
};
#endif

View File

@@ -0,0 +1,284 @@
#include "stdafx.h"
#ifndef NOMINMAX
#define NOMINMAX
#endif
#include "Overlapped.h"
#include "../Session/Session.h"
#include "../Listener/Listener.h"
#include "../../Stream/Buffer/Buffer.h"
#include "../../Stream/Buffer/BufferFactory.h"
#include <boost/pool/pool.hpp>
COverlapped::COverlapped(COverlappedFactory& ovlFactory, CBuffer* lpBuffer)
: m_lpBuffer(lpBuffer), m_ovlFactory(ovlFactory)
{
Internal = InternalHigh = Offset = OffsetHigh = 0;
hEvent = 0;
}
COverlapped::~COverlapped()
{
SAFE_RELEASE_BUFFER(m_lpBuffer);
}
void COverlapped::Release()
{
m_ovlFactory.DeleteOverlapped(this);
}
class CSendOverlapped : public COverlapped
{
public:
CSendOverlapped(COverlappedFactory& ovlFactory, CBuffer* lpSendBuffer)
: COverlapped(ovlFactory, lpSendBuffer) { }
virtual ~CSendOverlapped() { }
virtual void Dispatch(BOOL bResult, ULONG_PTR lpSessionKey, unsigned long dwProcessedBytes)
{
CSession& Session = *reinterpret_cast<CSession*>(lpSessionKey);
Session.SendCompleted(bResult, dwProcessedBytes);
m_ovlFactory.DeleteOverlapped(this);
}
};
class CStreamRecvOverlapped : public COverlapped
{
public:
CStreamRecvOverlapped(COverlappedFactory& ovlFactory) : COverlapped(ovlFactory, 0) { }
virtual ~CStreamRecvOverlapped() { }
virtual void Dispatch(BOOL bResult, ULONG_PTR lpSessionKey, unsigned long dwProcessedBytes)
{
CSession& Session = *reinterpret_cast<CSession*>(lpSessionKey);
if(Session.Dispatch(dwProcessedBytes))
{
Session.Recv();
}
m_ovlFactory.DeleteOverlapped(this);
}
};
class CDatagramRecvOverlapped : public COverlapped
{
public:
CDatagramRecvOverlapped(COverlappedFactory& ovlFactory) : COverlapped(ovlFactory, 0) { }
virtual ~CDatagramRecvOverlapped() { }
virtual void Dispatch(BOOL bResult, ULONG_PTR lpSessionKey, unsigned long dwProcessedBytes)
{
CSession& Session = *reinterpret_cast<CSession*>(lpSessionKey);
if(Session.Dispatch(dwProcessedBytes))
{
Session.RecvFrom();
}
m_ovlFactory.DeleteOverlapped(this);
}
};
class CAcceptOverlapped : public COverlapped
{
public:
CAcceptOverlapped(COverlappedFactory& ovlFactory, CListener& Listener, SOCKET hSocket, CBuffer* lpAddrBuffer)
: COverlapped(ovlFactory, lpAddrBuffer), m_Listener(Listener), m_hSocket(hSocket)
{
}
virtual ~CAcceptOverlapped() { }
virtual void Dispatch(BOOL bResult, ULONG_PTR lpSessionKey, unsigned long dwProcessedBytes)
{
CListener& Listener = *reinterpret_cast<CListener*>(lpSessionKey);
Listener.ProcessAccept(bResult, m_hSocket, m_lpBuffer, dwProcessedBytes);
m_ovlFactory.DeleteOverlapped(this);
}
private:
CListener& m_Listener;
SOCKET m_hSocket;
};
// ----------------------------------------------------------------------
// StreamOverlapped
CStreamOverlappedFactory::CStreamOverlappedFactory()
{
FactoryLock::Syncronize sync(m_Lock);
size_t nMaxPoolSize = std::max(sizeof(CAcceptOverlapped),
std::max(sizeof(CSendOverlapped), sizeof(CStreamRecvOverlapped)));
m_lpOverlappedPool = new (std::nothrow) boost::pool<>(nMaxPoolSize);
}
CStreamOverlappedFactory::~CStreamOverlappedFactory()
{
FactoryLock::Syncronize sync(m_Lock);
delete m_lpOverlappedPool;
m_lpOverlappedPool = 0;
}
COverlapped* CStreamOverlappedFactory::CreateSend(CSession* lpSession, CBuffer* lpMsgBlock)
{
COverlapped* lpOverlapped = 0;
FactoryLock::Syncronize sync(m_Lock);
if(0 != lpSession && 0 != lpMsgBlock && 0 != m_lpOverlappedPool)
{
void* lpBuffer = m_lpOverlappedPool->malloc();
if(0 != lpBuffer)
{
lpOverlapped = new (lpBuffer) CSendOverlapped(*this, lpMsgBlock);
}
}
return lpOverlapped;
}
COverlapped* CStreamOverlappedFactory::CreateRecv(CSession* lpSession, CBuffer* lpMsgBlock)
{
COverlapped* lpOverlapped = 0;
FactoryLock::Syncronize sync(m_Lock);
if(0 != lpSession && 0 != lpMsgBlock && 0 != m_lpOverlappedPool)
{
void* lpBuffer = m_lpOverlappedPool->malloc();
if(0 != lpBuffer)
{
lpOverlapped = new (lpBuffer) CStreamRecvOverlapped(*this);
}
}
return lpOverlapped;
}
COverlapped* CStreamOverlappedFactory::CreateAccept(CListener* lpListener, SOCKET hSocket, CBuffer* lpMsgBlock)
{
COverlapped* lpOverlapped = 0;
FactoryLock::Syncronize sync(m_Lock);
if(0 != lpListener && 0 != lpMsgBlock && 0 != m_lpOverlappedPool)
{
void* lpBuffer = m_lpOverlappedPool->malloc();
if(0 != lpBuffer)
{
lpOverlapped = new (lpBuffer) CAcceptOverlapped(*this, *lpListener, hSocket, lpMsgBlock);
}
}
return lpOverlapped;
}
void CStreamOverlappedFactory::DeleteOverlapped(COverlapped* lpOverlapped)
{
FactoryLock::Syncronize sync(m_Lock);
if(0 != lpOverlapped && 0 != m_lpOverlappedPool)
{
lpOverlapped->~COverlapped();
m_lpOverlappedPool->free(lpOverlapped);
}
}
// ----------------------------------------------------------------------
// DatagramOverlapped
CDatagramOverlappedFactory::CDatagramOverlappedFactory()
{
FactoryLock::Syncronize sync(m_Lock);
size_t nMaxPoolSize = std::max(sizeof(CAcceptOverlapped),
std::max(sizeof(CSendOverlapped), sizeof(CDatagramRecvOverlapped)));
m_lpOverlappedPool = new (std::nothrow) boost::pool<>(nMaxPoolSize);
}
CDatagramOverlappedFactory::~CDatagramOverlappedFactory()
{
FactoryLock::Syncronize sync(m_Lock);
delete m_lpOverlappedPool;
m_lpOverlappedPool = 0;
}
COverlapped* CDatagramOverlappedFactory::CreateSend(CSession* lpSession, CBuffer* lpMsgBlock)
{
COverlapped* lpOverlapped = 0;
FactoryLock::Syncronize sync(m_Lock);
if(0 != lpSession && 0 != lpMsgBlock && 0 != m_lpOverlappedPool)
{
void* lpBuffer = m_lpOverlappedPool->malloc();
if(0 != lpBuffer)
{
lpOverlapped = new (lpBuffer) CSendOverlapped(*this, lpMsgBlock);
}
}
return lpOverlapped;
}
COverlapped* CDatagramOverlappedFactory::CreateRecv(CSession* lpSession, CBuffer* lpMsgBlock)
{
COverlapped* lpOverlapped = 0;
FactoryLock::Syncronize sync(m_Lock);
if(0 != lpSession && 0 != lpMsgBlock && 0 != m_lpOverlappedPool)
{
void* lpBuffer = m_lpOverlappedPool->malloc();
if(0 != lpBuffer)
{
lpOverlapped = new (lpBuffer) CDatagramRecvOverlapped(*this);
}
}
return lpOverlapped;
}
void CDatagramOverlappedFactory::DeleteOverlapped(COverlapped* lpOverlapped)
{
FactoryLock::Syncronize sync(m_Lock);
if(0 != lpOverlapped && 0 != m_lpOverlappedPool)
{
lpOverlapped->~COverlapped();
m_lpOverlappedPool->free(lpOverlapped);
}
}

View File

@@ -0,0 +1,112 @@
#ifndef _COVERLAPPED_H_
#define _COVERLAPPED_H_
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include "../../Thread/Lock.h"
#include <winsock2.h>
#include <windows.h>
#include <boost/pool/poolfwd.hpp>
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
class CBuffer;
class CBufferFactory;
class CSession;
class CListener;
class COverlappedFactory;
class COverlapped : public OVERLAPPED
{
public:
COverlapped(COverlappedFactory& ovlFactory, CBuffer* lpBuffer);
virtual ~COverlapped();
virtual void Dispatch(BOOL bResult, ULONG_PTR lpSessionKey,
unsigned long dwProcessedBytes) = 0;
void SetBuffer(CBuffer* lpBuffer) { m_lpBuffer = lpBuffer; }
void Release();
protected:
COverlappedFactory& m_ovlFactory;
CBuffer* m_lpBuffer;
};
// ---------------------------------------------------------------------------
// COverlappedFactory : <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̽<EFBFBD> <20><><EFBFBD>
class COverlappedFactory
{
public:
virtual ~COverlappedFactory() { }
virtual COverlapped* CreateSend(CSession* lpSession, CBuffer* lpMsgBlock) = 0;
virtual COverlapped* CreateRecv(CSession* lpSession, CBuffer* lpMsgBlock) = 0;
virtual COverlapped* CreateAccept(CListener* lpListener, SOCKET hSocket, CBuffer* lpMsgBlock) = 0;
virtual void DeleteOverlapped(COverlapped* lpOverlapped) = 0;
};
// ---------------------------------------------------------------------------
// CStreamOverlappedFactory : TCP, SPX<50><58><EFBFBD>ſ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
class CStreamOverlappedFactory : public COverlappedFactory
{
public:
CStreamOverlappedFactory();
virtual ~CStreamOverlappedFactory();
virtual COverlapped* CreateSend(CSession* lpSession, CBuffer* lpMsgBlock);
virtual COverlapped* CreateRecv(CSession* lpSession, CBuffer* lpMsgBlock);
virtual COverlapped* CreateAccept(CListener* lpListener, SOCKET hSocket, CBuffer* lpMsgBlock);
virtual void DeleteOverlapped(COverlapped* lpOverlapped);
private:
typedef CCSLock FactoryLock;
FactoryLock m_Lock;
CACHE_PAD(FactoryLockPad, sizeof(FactoryLock));
boost::pool<>* m_lpOverlappedPool;
};
// ---------------------------------------------------------------------------
// CDatagramOverlappedFactory : UDP, IPX<50><58><EFBFBD>ſ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
class CDatagramOverlappedFactory : public COverlappedFactory
{
public:
CDatagramOverlappedFactory();
virtual ~CDatagramOverlappedFactory();
virtual COverlapped* CreateSend(CSession* lpSession, CBuffer* lpMsgBlock);
virtual COverlapped* CreateRecv(CSession* lpSession, CBuffer* lpMsgBlock);
virtual COverlapped* CreateAccept(CListener* lpListener, SOCKET hSocket, CBuffer* lpMsgBlock) { return 0; }
virtual void DeleteOverlapped(COverlapped* lpOverlapped);
private:
typedef CCSLock FactoryLock;
FactoryLock m_Lock;
CACHE_PAD(FactoryLockPad, sizeof(FactoryLock));
boost::pool<>* m_lpOverlappedPool;
};
#endif

View File

@@ -0,0 +1,395 @@
#include "stdafx.h"
#include "Listener.h"
#include "../Session/Session.h"
#include "../Session/SessionMgr.h"
#include "../Dispatch/Dispatch.h"
#include "../Winsock/SocketFactory.h"
#include "../IOCP/CompletionHandler.h"
#include "../IOCP/Overlapped.h"
#include "../../Stream/Buffer/Buffer.h"
#include "../../Stream/Buffer/BufferFactory.h"
#include "../../Utility/Debug/DebugUtils.h"
#include "../../Utility/Resource/EnsureCleanup.h"
#include "../../Log/ServerLog.h"
#include <mmsystem.h>
#include <iostream>
enum LISTENER_CONSTANT
{
DEFAULT_PENDING_NUM = 10
};
CListener::CListener(CCompletionHandler& SocketHandler,
CSessionPolicy& SessionPolicy,
CSessionMgr& SessionMgr,
CValidateConnection* lpValidateConnection)
: m_hListen(INVALID_SOCKET),
m_dwMaxPending(DEFAULT_PENDING_NUM),
m_dwCurrentPending(0),
m_dwTotalPendingCount(0),
m_dwTotalAcceptCompleteCount(0),
m_SocketHandler(SocketHandler),
m_SessionPolicy(SessionPolicy),
m_SessionMgr(SessionMgr),
m_lpValidateConnection(lpValidateConnection)
{
m_SessionPolicy.AddRef();
if(0 != m_lpValidateConnection)
{
m_lpValidateConnection->AddRef();
}
}
CListener::~CListener()
{
{
SessionLock::Syncronize sync(m_ListenerLock);
InternalCloseListen();
}
WaitForPendingComplete(5000);
m_SessionPolicy.Release();
if(0 != m_lpValidateConnection)
{
m_lpValidateConnection->Release();
}
}
bool CListener::Initialize(INET_Addr& addrListen, unsigned long dwMaxPending)
{
if(!m_SessionPolicy.IsValid())
{
ERRLOG0(g_SessionLog, "CListener initialized failed : Invalid SessionPolicy");
return false;
}
else
{
SessionLock::Syncronize sync(m_ListenerLock);
InternalCloseListen();
const sockaddr_in& addr_in = addrListen.get_addr_in();
m_hListen = m_SessionPolicy.GetSocketFactory().CreateListenSocket(
(0 != addr_in.sin_addr.S_un.S_addr) ? inet_ntoa(addr_in.sin_addr) : 0,
addrListen.get_port_in());
if(SOCKET_ERROR == m_hListen)
{
ERRLOG1(g_SessionLog, "CListener initialized failed : Create listen socket failed : %d",
WSAGetLastError());
return false;
}
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Handler<65><72> Attach<63>Ѵ<EFBFBD>.
if(!m_SocketHandler.AttachToHander(
reinterpret_cast<HANDLE>(m_hListen), reinterpret_cast<ULONG_PTR>(this)))
{
ERRLOG1(g_SessionLog, "CListener initialized failed : Attach to Handler failed : %d",
WSAGetLastError());
return false;
}
// Pending<6E><67> <20><20><> <20><><EFBFBD>´<EFBFBD>.
if(m_dwMaxPending < dwMaxPending)
{
m_dwMaxPending = dwMaxPending;
}
dwMaxPending = m_dwMaxPending;
}
for(unsigned long dwCount = 0; dwCount < dwMaxPending; ++dwCount)
{
PendingAccept();
}
return true;
}
void CListener::InternalCloseListen()
{
if(INVALID_SOCKET != m_hListen)
{
if(SOCKET_ERROR == closesocket(m_hListen))
{
ERRLOG1(g_SessionLog, "closesocket failed : %d", WSAGetLastError());
}
m_hListen = INVALID_SOCKET;
}
}
void CListener::WaitForPendingComplete(unsigned long dwTime)
{
unsigned long dwStartTime = timeGetTime();
for(;;)
{
long diffTime = timeGetTime() - dwStartTime;
if(dwTime < static_cast<unsigned long>(std::abs(diffTime)))
{
break;
}
{
SessionLock::Syncronize sync(m_ListenerLock);
if(0 == m_dwCurrentPending)
{
break;
}
}
Sleep(10);
}
}
bool CListener::PendingAccept()
{
SessionLock::Syncronize sync(m_ListenerLock);
if(INVALID_SOCKET == m_hListen)
{
return false;
}
unsigned long dwAddressLen = sizeof(SOCKADDR_IN) + 16;
unsigned long dwBytesReceived = 0;
SOCKET hSocket = m_SessionPolicy.GetSocketFactory().CreateSocket();
CBuffer* lpAddrBuffer = CREATE_BUFFER(m_SessionPolicy.GetBufferFactory(), dwAddressLen * 2);
COverlapped* lpOverlapped = m_SessionPolicy.GetOverlappedFactory().CreateAccept(this, hSocket, lpAddrBuffer);
if(SOCKET_ERROR == AcceptEx(m_hListen, hSocket, lpAddrBuffer->wr_ptr(),
0, dwAddressLen, dwAddressLen, &dwBytesReceived, lpOverlapped))
{
if(WSA_IO_PENDING != WSAGetLastError())
{
// <20><><EFBFBD>۴<EFBFBD> <20><><EFBFBD>ο<EFBFBD><CEBF><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
m_SessionPolicy.GetOverlappedFactory().DeleteOverlapped(lpOverlapped);
closesocket(hSocket);
return false;
}
}
++m_dwCurrentPending;
++m_dwTotalPendingCount;
return true;
}
void CListener::ProcessAccept(BOOL bResult, SOCKET hSocket,
CBuffer* lpBuffer, unsigned long dwProcessedBytes)
{
INET_Addr localAddr;
INET_Addr remoteAddr;
if(bResult)
{
// <20><><EFBFBD><EFBFBD> <20>ɼ<EFBFBD> <20><><EFBFBD><EFBFBD>.
if(SOCKET_ERROR == setsockopt(hSocket, SOL_SOCKET,
SO_UPDATE_ACCEPT_CONTEXT, (char*)&m_hListen, sizeof(m_hListen)))
{
bResult = FALSE;
}
else
{
SOCKADDR* lpLocalAddr = 0;
SOCKADDR* lpRemoteAddr = 0;
int nLocalSockAddrLen = 0;
int nRemoteSockAddrLen = 0;
unsigned long dwAddressLen = sizeof(SOCKADDR_IN) + 16;
// <20>ּ<EFBFBD> <20>м<EFBFBD> <20><> <20>ּ<EFBFBD> <20><>ü <20><><EFBFBD><EFBFBD>.
GetAcceptExSockaddrs(lpBuffer->rd_ptr(), 0, dwAddressLen, dwAddressLen,
&lpLocalAddr, &nLocalSockAddrLen, &lpRemoteAddr, &nRemoteSockAddrLen);
if(0 != lpLocalAddr)
{
localAddr.set_addr(*lpLocalAddr, nLocalSockAddrLen);
}
if(0 != lpRemoteAddr)
{
remoteAddr.set_addr(*lpRemoteAddr, nRemoteSockAddrLen);
}
}
}
if(bResult && 0 != m_lpValidateConnection
&& !(*m_lpValidateConnection)(localAddr, remoteAddr))
{
bResult = FALSE;
}
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
CSession* lpSession = 0;
if(bResult)
{
lpSession = m_SessionMgr.CreateSession(m_SessionPolicy);
if(0 == lpSession || !lpSession->isValid())
{
bResult = FALSE;
}
}
if(bResult && !m_SocketHandler.AttachToHander(
reinterpret_cast<HANDLE>(hSocket),
reinterpret_cast<ULONG_PTR>(lpSession)))
{
bResult = FALSE;
}
if(bResult)
{
lpSession->Socket(hSocket);
lpSession->SetAddress(remoteAddr, localAddr);
DETLOG3(g_SessionLog, "SP:0x%p/DP:0x%p/IP:%15s/ Accept Session Complete.",
lpSession, lpSession->GetDispatch(), remoteAddr.get_addr_string());
lpSession->InternalRecv();
m_SessionMgr.Add(lpSession);
}
else
{
m_SessionMgr.DeleteSession(lpSession);
lpSession = 0;
// pending failed
closesocket(hSocket);
}
{
SessionLock::Syncronize sync(m_ListenerLock);
--m_dwCurrentPending;
++m_dwTotalAcceptCompleteCount;
}
PendingAccept();
}
unsigned long CListener::GetPendingAcceptNum()
{
SessionLock::Syncronize sync(m_ListenerLock);
return m_dwCurrentPending;
}
std::ostream& CListener::PrintStatistics(std::ostream& strm)
{
SessionLock::Syncronize sync(m_ListenerLock);
const int MAX_BUFFER = 1024;
char szBuffer[MAX_BUFFER];
int nLen = InternalPrintStatistics(szBuffer, MAX_BUFFER);
if(0 < nLen)
{
strm << szBuffer;
}
return strm;
}
int CListener::InternalPrintStatistics(char* szBuffer, int nBufferLen)
{
return _snprintf(szBuffer, nBufferLen,
"[ListenSocket:0x%08x][MaxPending:%d][CurrentPending:%d]"
"[TotalPendingCount:%d][TotalAcceptCompleteCount:%d]",
m_hListen, m_dwMaxPending, m_dwCurrentPending,
m_dwTotalPendingCount, m_dwTotalAcceptCompleteCount);
}
/*
bool CListener::LogListenerStatus()
{
using namespace std;
unsigned int nStateNum[CSession::MAX_SESSION_STATE];
std::fill_n(nStateNum, unsigned int(CSession::MAX_SESSION_STATE), 0);
const char* szDelimiter = "// ------------------------------------------------------------------------------- ";
char szProgramName[MAX_PATH];
char szFileName[MAX_PATH];
char szTime[MAX_PATH];
SYSTEMTIME systemTime;
GetLocalTime(&systemTime);
DbgUtils::SetProgramName(szProgramName, MAX_PATH);
_snprintf(szTime, MAX_PATH, "%04d%02d%02d-%02d%02d%02d",
systemTime.wYear, systemTime.wMonth, systemTime.wDay,
systemTime.wHour, systemTime.wMinute, systemTime.wSecond);
_snprintf(szFileName, MAX_PATH, "%s/ListenerLog-%s.txt", szProgramName, szTime);
fstream logfile(szFileName, ios::out | ios::app);
fstream::char_type endline = logfile.widen('\n');
logfile << szDelimiter << endline;
SessionSet::iterator pos = m_SessionSet.begin();
SessionSet::iterator end = m_SessionSet.end();
for(; pos != end; ++pos)
{
CSession* lpSession = *pos;
logfile << lpSession << endline;
++nStateNum[lpSession->m_cCurrentStatus];
}
logfile << endline << szDelimiter << endline
<< "Time : " << szTime << endline << endline
<< "UNINITIALIZED : " << nStateNum[CSession::UNINITIALIZED] << endline
<< "ACCEPT_PENDING : " << nStateNum[CSession::ACCEPT_PENDING] << endline
<< "CONNECTED : " << nStateNum[CSession::CONNECTED] << endline
<< "DISCONNECTED : " << nStateNum[CSession::DISCONNECTED] << endline
<< "Total : " << m_dwMaxConnections << endl;
return true;
}
*/
LONG CValidateConnection::AddRef()
{
return InterlockedIncrement(&m_nRefCount);
}
LONG CValidateConnection::Release()
{
LONG nRefCount = InterlockedDecrement(&m_nRefCount);
if(0 == nRefCount)
{
delete this;
}
return nRefCount;
}

View File

@@ -0,0 +1,114 @@
#ifndef _CLISTENER_H_
#define _CLISTENER_H_
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <winsock2.h>
#include <windows.h>
#include <list>
#include <boost/pool/object_pool.hpp>
#include "../../Thread/Lock.h"
#include "../Address/INET_Addr.h"
#pragma comment(lib, "winmm")
#pragma comment(lib, "mswsock")
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
class CBuffer;
class CSession;
class CSessionMgr;
class CSessionPolicy;
class CSocketFactory;
class CCompletionHandler;
// IP<49><50>, <20><>Ÿ <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> <20><>ħ<EFBFBD><C4A7> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
class CValidateConnection
{
public:
LONG AddRef();
LONG Release();
virtual bool operator () (INET_Addr& localAddr, INET_Addr& remoteAddr) = 0;
protected:
CValidateConnection() : m_nRefCount(1) { }
virtual ~CValidateConnection() { }
private:
LONG m_nRefCount;
};
class CListener
{
public:
CListener(CCompletionHandler& SocketHandler,
CSessionPolicy& SessionPolicy,
CSessionMgr& SessionMgr,
CValidateConnection* lpValidateConnection);
virtual ~CListener();
bool Initialize(const char* lpListenAddress, unsigned short usPort,
unsigned long dwMaxPending = 0)
{
return Initialize(INET_Addr(lpListenAddress, usPort), dwMaxPending);
}
bool Initialize(INET_Addr& addrListen, unsigned long dwMaxPending = 0);
bool PendingAccept();
void ProcessAccept(BOOL bResult, SOCKET hSocket,
CBuffer* lpBuffer, unsigned long dwProcessedBytes);
unsigned long GetPendingAcceptNum();
CSessionPolicy& GetPolicy() { return m_SessionPolicy; }
friend std::ostream& Log(std::ostream& strm, CListener* lpListener) { return (0 != lpListener) ? lpListener->PrintStatistics(strm) : strm; }
friend std::ostream& Log(std::ostream& strm, CListener& Listener) { return Listener.PrintStatistics(strm); }
private:
void InternalProcess();
void InternalPending();
void InternalDestroy();
void InternalCloseListen();
void WaitForPendingComplete(unsigned long dwTime);
std::ostream& PrintStatistics(std::ostream& strm);
int InternalPrintStatistics(char* szBuffer, int nBufferLen);
//---------------------------------------------------
typedef CCSLock SessionLock;
SessionLock m_ListenerLock; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ü <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ǵ帱 <20><> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> <20><>.
CACHE_PAD(ListenerLockPad, sizeof(SessionLock));
SOCKET m_hListen;
INET_Addr m_ListenAddr;
CCompletionHandler& m_SocketHandler;
CSessionPolicy& m_SessionPolicy;
CSessionMgr& m_SessionMgr;
unsigned long m_dwMaxPending;
unsigned long m_dwCurrentPending;
unsigned long m_dwTotalPendingCount;
unsigned long m_dwTotalAcceptCompleteCount;
CValidateConnection* m_lpValidateConnection;
};
#endif

View File

@@ -0,0 +1,729 @@
#include "stdafx.h"
#include "Session.h"
#include "../IOCP/Overlapped.h"
#include "../IOCP/CompletionHandler.h"
#include "../Winsock/SocketFactory.h"
#include "../Address/INET_Addr.h"
#include "../Dispatch/Dispatch.h"
#include "../Dispatch/ServerRequest.h"
#include "../../Stream/Buffer/Buffer.h"
#include "../../Stream/Buffer/BufferFactory.h"
#include "../../Log/ServerLog.h"
#include <iostream>
// SP : SessionPointer
// DP : DispatchPointer
namespace SessionState
{
enum Type
{
CONNECTED, // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
DISCONNECTED, // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ǿ<EFBFBD><C7BE><EFBFBD>.
MAX_SESSION_STATE
};
};
namespace SessionFlag
{
// 8bit SessionFlag
enum Type
{
CONNECT_CALLED = ( 1 << 0 ), // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> ó<><C3B3><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
DISCONNECT_PROCESSED = ( 1 << 1 ), // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> ó<><C3B3><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
SHUTDOWN_CALLED = ( 1 << 2 ), // Shutdown<77><6E> ȣ<><C8A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
SHUTDOWN_PROCESSED = ( 1 << 3 ), // Shutdown ó<><C3B3><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
SUSPEND_RECV = ( 1 << 4 ) // <20>÷<EFBFBD><C3B7>װ<EFBFBD> <20><><EFBFBD>õǾ<C3B5> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Recv<63><76> <20><><EFBFBD><EFBFBD>
};
};
namespace SessionConst
{
enum Data
{
MAX_RECV_BUFFER = 32768
};
}
CSession::CSession(CSessionPolicy& SessionPolicy)
: m_hSocket(INVALID_SOCKET),
m_nRefCount(0),
m_SessionPolicy(SessionPolicy),
m_dwRecvPending(0),
m_dwSendPending(0),
m_cCurrentStatus(SessionState::CONNECTED),
m_cFlags(0),
m_usPadding(0x4343)
{
m_SessionPolicy.AddRef();
m_lpRecvBuffer = CREATE_BUFFER(SessionPolicy.GetBufferFactory(), SessionConst::MAX_RECV_BUFFER);
m_lpDispatch = SessionPolicy.GetDispatchFactory().CreateDispatch(*this);
}
CSession::~CSession()
{
{
SessionLock::Syncronize sync(m_SessionLock);
InternalCloseSocket();
SAFE_RELEASE_BUFFER(m_lpRecvBuffer);
m_SessionPolicy.GetDispatchFactory().DeleteDispatch(m_lpDispatch);
m_usPadding = 0x4444;
}
m_SessionPolicy.Release();
}
// false <20><><EFBFBD>Ͻ<EFBFBD> Accept Pending<6E><67> <20><>.
bool CSession::Process()
{
if(!m_lpDispatch)
{
ERRLOG4(g_SessionLog, "SP:0x%p/DP:0x%p/IP:%15s/SOCKET:0x%p/CloseSocket - Failed Dispatch Pointer",
this, m_lpDispatch, m_RemoteAddr.get_addr_string(), m_hSocket);
return false;
}
SessionState::Type eState = SessionState::MAX_SESSION_STATE;
unsigned char cFlags = 0;
bool bCloseSocket = false;
bool bCallConnected = false;
bool bCallDisconnected = false;
{
SessionLock::Syncronize sync(m_SessionLock);
eState = static_cast<SessionState::Type>(m_cCurrentStatus);
switch(m_cCurrentStatus)
{
case SessionState::CONNECTED:
if(SessionFlag::CONNECT_CALLED != (m_cFlags & SessionFlag::CONNECT_CALLED))
{
bCallConnected = true;
m_cFlags |= SessionFlag::CONNECT_CALLED;
}
if (!(m_cFlags & SessionFlag::SUSPEND_RECV) && 0 == m_dwRecvPending)
{
// <20><><EFBFBD><EFBFBD><EFBFBD>͸<EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>͸<EFBFBD> <20>޴´<DEB4>.
InternalRecv();
}
break;
case SessionState::DISCONNECTED:
if(SessionFlag::DISCONNECT_PROCESSED != (m_cFlags & SessionFlag::DISCONNECT_PROCESSED))
{
bCallDisconnected = true;
m_Statistics.m_DisconnectedTime = time(0);
m_cFlags |= SessionFlag::DISCONNECT_PROCESSED;
}
else if(INVALID_SOCKET == m_hSocket &&
0 == m_dwRecvPending &&
0 == m_dwSendPending &&
0 == m_nRefCount)
{
InternalCloseSocket();
DETLOG4(g_SessionLog, "SP:0x%p/DP:0x%p/IP:%15s/SOCKET:0x%p/Eliminate Session",
this, m_lpDispatch, m_RemoteAddr.get_addr_string(), m_hSocket);
return false;
}
break;
}
cFlags = m_cFlags;
++m_nRefCount;
}
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> ó<><C3B3><EFBFBD><EFBFBD> <20><>.
if(bCallConnected)
{
DETLOG4(g_SessionLog, "SP:0x%p/DP:0x%p/IP:%15s/SOCKET:0x%p/Connection Open - Process connected",
this, m_lpDispatch, m_RemoteAddr.get_addr_string(), m_hSocket);
m_lpDispatch->Connected();
m_Statistics.m_ConnectedTime = time(0);
}
// <20><><EFBFBD><EFBFBD> <20><>Ŷ<EFBFBD><C5B6> Dispatch<63><68>.
if(SessionState::CONNECTED == eState && !m_lpDispatch->Dispatch())
{
DETLOG4(g_SessionLog, "SP:0x%p/DP:0x%p/IP:%15s/SOCKET:0x%p/CloseSocket - Failed Dispatch",
this, m_lpDispatch, m_RemoteAddr.get_addr_string(), m_hSocket);
bCloseSocket = true;
}
// <20><><EFBFBD><EFBFBD> <20>ݱ<EFBFBD> ó<><C3B3><EFBFBD><EFBFBD> <20><>.
if(bCallDisconnected)
{
DETLOG4(g_SessionLog, "SP:0x%p/DP:0x%p/IP:%15s/SOCKET:0x%p/ Connection Closed - Process disconnect",
this, m_lpDispatch, m_RemoteAddr.get_addr_string(), m_hSocket);
m_lpDispatch->Disconnected();
}
{
SessionLock::Syncronize sync(m_SessionLock);
// <20><><EFBFBD><EFBFBD> ó<><C3B3><EFBFBD><EFBFBD> <20>Ѵ<EFBFBD>.
InternalSend();
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Shutdown<77><6E> ȣ<><C8A3><EFBFBD>߾<EFBFBD><DFBE><EFBFBD><EFBFBD><EFBFBD> Shutdown ó<><C3B3><EFBFBD><EFBFBD> <20><>.
if((m_cFlags & SessionFlag::SHUTDOWN_CALLED) &&
m_SendQueue.empty() && INVALID_SOCKET != m_hSocket)
{
if(shutdown(m_hSocket, SD_SEND))
{
m_cFlags |= SessionFlag::SHUTDOWN_PROCESSED;
}
}
--m_nRefCount;
if(bCloseSocket)
{
InternalCloseSocket();
}
}
return true;
}
bool CSession::Dispatch(unsigned long dwReceivedBytes)
{
// <20><>Ŷ ó<><C3B3><EFBFBD><EFBFBD> <20>ϰ<EFBFBD>, ó<><C3B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>δ<EFBFBD>.
m_lpRecvBuffer->wr_ptr(dwReceivedBytes);
unsigned long dwDispatchSize = static_cast<unsigned long>(m_lpRecvBuffer->length());
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>Ʈ <20><><EFBFBD><EFBFBD> 0(<28><><EFBFBD><EFBFBD> <20>Ϸ<EFBFBD>) <20>̰ų<CCB0>, <20><>Ŷ ó<><C3B3><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϸ<EFBFBD> Socket<65><74> Close<73>Ѵ<EFBFBD>.
bool bResult = (0 != dwReceivedBytes &&
m_lpDispatch->ParsePacket(m_lpRecvBuffer->rd_ptr(), &dwDispatchSize));
m_lpRecvBuffer->rd_ptr(dwDispatchSize);
m_lpRecvBuffer->pop_read_data();
SessionLock::Syncronize sync(m_SessionLock);
m_Statistics.m_dwTotalReceived += dwReceivedBytes;
--m_dwRecvPending;
if (!bResult)
{
DETLOG7(g_SessionLog, "SP:0x%p/DP:0x%p/IP:%15s/SOCKET:0x%p/shutdown - %s : dwReceivedBytes:%d, ErrorCode:%d",
this, m_lpDispatch, m_RemoteAddr.get_addr_string(), m_hSocket,
(0 == dwReceivedBytes) ? "Disconnected" : "Failed To Dispatch Packet",
dwReceivedBytes, WSAGetLastError());
InternalCloseSocket();
}
return bResult;
}
void CSession::InternalCloseSocket()
{
if(INVALID_SOCKET != m_hSocket)
{
const char* szRemoteAddr = m_RemoteAddr.get_addr_string();
if(SOCKET_ERROR == shutdown(m_hSocket, SD_SEND))
{
DETLOG5(g_SessionLog, "SP:0x%p/DP:0x%p/IP:%15s/SOCKET:0x%p/ Shutdown failed - ErrorCode:%d",
this, m_lpDispatch, szRemoteAddr, m_hSocket, WSAGetLastError());
}
if(SOCKET_ERROR == closesocket(m_hSocket))
{
DETLOG5(g_SessionLog, "SP:0x%p/DP:0x%p/IP:%15s/SOCKET:0x%p/ InternalCloseSocket failed - ErrorCode:%d",
this, m_lpDispatch, szRemoteAddr, m_hSocket, WSAGetLastError());
}
const int MAX_BUFFER = 1024;
char szBuffer[MAX_BUFFER];
if(0 < InternalPrintStatistics(szBuffer, MAX_BUFFER))
{
DETLOG4(g_SessionLog, "SP:0x%p/DP:0x%p/IP:%15s/ InternalCloseSocket - Statistics : %s",
this, m_lpDispatch, szRemoteAddr, szBuffer);
}
m_cFlags |= SessionFlag::SHUTDOWN_PROCESSED;
m_hSocket = INVALID_SOCKET;
}
m_cCurrentStatus = SessionState::DISCONNECTED;
}
bool CSession::Shutdown()
{
SessionLock::Syncronize sync(m_SessionLock);
m_cFlags |= SessionFlag::SHUTDOWN_CALLED;
return false;
}
LONG CSession::AddRef()
{
SessionLock::Syncronize sync(m_SessionLock);
return ++m_nRefCount;
}
LONG CSession::Release()
{
SessionLock::Syncronize sync(m_SessionLock);
return --m_nRefCount;
}
void CSession::CloseSession()
{
SessionLock::Syncronize sync(m_SessionLock);
DETLOG4(g_SessionLog, "SP:0x%p/DP:0x%p/IP:%15s/ InternalCloseSocket - SessionClose Called : %d",
this, m_lpDispatch, m_RemoteAddr.get_addr_string(), WSAGetLastError());
InternalCloseSocket();
}
bool CSession::IsConnected()
{
SessionLock::Syncronize sync(m_SessionLock);
return (SessionState::CONNECTED == m_cCurrentStatus && m_hSocket != INVALID_SOCKET);
}
bool CSession::CalledConnected()
{
SessionLock::Syncronize sync(m_SessionLock);
return SessionFlag::CONNECT_CALLED == (m_cFlags & SessionFlag::CONNECT_CALLED);
}
bool CSession::CalledDisconnected()
{
SessionLock::Syncronize sync(m_SessionLock);
return SessionFlag::DISCONNECT_PROCESSED == (m_cFlags & SessionFlag::DISCONNECT_PROCESSED);
}
void CSession::SendCompleted(BOOL bResult, unsigned long dwSendedBytes)
{
SessionLock::Syncronize sync(m_SessionLock);
--m_dwSendPending;
m_Statistics.m_dwTotalSendCompleted += dwSendedBytes;
if(!bResult)
{
DETLOG4(g_SessionLog, "SP:0x%p/DP:0x%p/IP:%15s/ InternalCloseSocket - Send Completion Error : %d",
this, m_lpDispatch, m_RemoteAddr.get_addr_string(), WSAGetLastError());
InternalCloseSocket();
}
else
{
InternalSend();
}
}
void CSession::SetAddress(INET_Addr& remoteAddr, INET_Addr& localAddr)
{
m_RemoteAddr = remoteAddr;
m_LocalAddr = localAddr;
}
std::ostream& CSession::PrintStatistics(std::ostream& strm)
{
SessionLock::Syncronize sync(m_SessionLock);
const int MAX_BUFFER = 1024;
char szBuffer[MAX_BUFFER];
int nLen = InternalPrintStatistics(szBuffer, MAX_BUFFER);
if(0 < nLen)
{
strm << szBuffer;
}
return strm;
}
int CSession::InternalPrintStatistics(char* szBuffer, int nBufferLen)
{
const char* szMode = 0;
switch(m_cCurrentStatus)
{
case SessionState::CONNECTED: szMode = "CONNECTED"; break;
case SessionState::DISCONNECTED: szMode = "DISCONNECTED"; break;
default: szMode = "Unknown Mode"; break;
}
int nLen = _snprintf(szBuffer, nBufferLen - 1,
"[m_hSocket:0x%08x][%15s][DiffTime(Sec):%8f]"
"[m_dwTotalReceived:%5d][m_dwTotalSendPending:%5d][m_dwTotalSendCompleted:%5d]"
"[m_dwSendPending:%d][m_dwRecvPending:%d][m_nRefCount:%2d][flags:0x%02x]",
m_hSocket, szMode, difftime(time(0), m_Statistics.m_ConnectedTime),
m_Statistics.m_dwTotalReceived, m_Statistics.m_dwTotalSendPending,
m_Statistics.m_dwTotalSendCompleted,
m_dwSendPending, m_dwRecvPending,
m_nRefCount, m_cFlags);
szBuffer[nBufferLen - 1] = 0;
return nLen;
}
bool CSession::InternalRecv()
{
if (m_cFlags & SessionFlag::SUSPEND_RECV)
{
DETLOG4(g_SessionLog, "SP:0x%p/DP:0x%p/IP:%15s/SOCKET:0x%p/ Recv suspending now",
this, m_lpDispatch, m_RemoteAddr.get_addr_string(), m_hSocket);
return true;
}
else if (0 != m_dwRecvPending)
{
DETLOG4(g_SessionLog, "SP:0x%p/DP:0x%p/IP:%15s/SOCKET:0x%p/ Recv pending now",
this, m_lpDispatch, m_RemoteAddr.get_addr_string(), m_hSocket);
return true;
}
unsigned long dwReceived = 0;
unsigned long dwFlags = 0;
WSABUF wsaBuf;
wsaBuf.buf = m_lpRecvBuffer->wr_ptr();
wsaBuf.len = static_cast<u_long>(m_lpRecvBuffer->remain());
COverlapped* lpOverlapped = m_SessionPolicy.GetOverlappedFactory().CreateRecv(this, m_lpRecvBuffer);
const char* lpErrorFmtString = 0;
if(0 != lpOverlapped)
{
if(SOCKET_ERROR == WSARecv(m_hSocket, &wsaBuf, 1,
&dwReceived, &dwFlags, lpOverlapped, 0))
{
if(WSA_IO_PENDING != WSAGetLastError())
{
lpErrorFmtString = "SP:0x%p/DP:0x%p/IP:%15s/SOCKET:0x%p/InternalCloseSocket"
" - WSARecv Error - ErrorCode:%d";
}
}
}
else
{
lpErrorFmtString = "SP:0x%p/DP:0x%p/IP:%15s/SOCKET:0x%p/InternalCloseSocket"
" - WSARecv Error - Create RecvOverlapped Failed - ErrorCode:%d";
}
if(0 != lpErrorFmtString)
{
DETLOG5(g_SessionLog, lpErrorFmtString, this, m_lpDispatch,
m_RemoteAddr.get_addr_string(), m_hSocket, WSAGetLastError());
InternalCloseSocket();
m_SessionPolicy.GetOverlappedFactory().DeleteOverlapped(lpOverlapped);
return false;
}
++m_dwRecvPending;
return true;
}
bool CSession::InternalRecvFrom()
{
if(0 != m_dwRecvPending)
{
//DETLOG4(g_SessionLog, "SP:0x%p/DP:0x%p/IP:%15s/SOCKET:0x%p/ RecvFrom pending now",
// this, m_lpDispatch, m_RemoteAddr.get_addr_string(), m_hSocket);
return true;
}
if(INVALID_SOCKET == m_hSocket)
{
return false;
}
unsigned long dwReceived = 0;
unsigned long dwFlags = 0;
WSABUF wsaBuf;
wsaBuf.buf = m_lpRecvBuffer->wr_ptr();
wsaBuf.len = static_cast<u_long>(m_lpRecvBuffer->remain());
COverlapped* lpOverlapped =
m_SessionPolicy.GetOverlappedFactory().CreateRecv(this, m_lpRecvBuffer);
const char* lpErrorFmtString = 0;
if(0 != lpOverlapped)
{
INET_Addr& addr = m_lpRecvBuffer->get_addr();
if(SOCKET_ERROR == WSARecvFrom(m_hSocket, &wsaBuf, 1, &dwReceived, &dwFlags,
&addr.get_addr(), addr.get_size_ptr(), lpOverlapped, 0))
{
if(WSA_IO_PENDING != WSAGetLastError())
{
lpErrorFmtString = "SP:0x%p/DP:0x%p/IP:%15s/SOCKET:0x%p/ InternalCloseSocket"
" - WSARecvFrom Error - ErrorCode:%d";
}
}
}
else
{
lpErrorFmtString = "SP:0x%p/DP:0x%p/IP:%15s/SOCKET:0x%p/InternalCloseSocket"
" - WSARecvFrom Error - Create RecvOverlapped Failed - ErrorCode:%d";
}
if(0 != lpErrorFmtString)
{
DETLOG5(g_SessionLog, lpErrorFmtString, this, m_lpDispatch,
m_RemoteAddr.get_addr_string(), m_hSocket, WSAGetLastError());
InternalCloseSocket();
if(0 != lpOverlapped)
{
m_SessionPolicy.GetOverlappedFactory().DeleteOverlapped(lpOverlapped);
}
return false;
}
++m_dwRecvPending;
return true;
}
CSession::SendResult CSession::InternalSend(CBuffer* lpBuffer)
{
if(0 != m_dwSendPending)
{
return SEND_NEXT_TURN;
}
if(INVALID_SOCKET == m_hSocket)
{
return SEND_FAILED;
}
const char* lpErrorFmtString = 0;
COverlapped* lpOverlapped = 0;
if(0 != lpBuffer)
{
lpOverlapped = m_SessionPolicy.GetOverlappedFactory().CreateSend(this, lpBuffer);
if(0 != lpOverlapped)
{
unsigned long dwSentBytes = 0;
WSABUF wsaBuf;
wsaBuf.buf = lpBuffer->rd_ptr();
wsaBuf.len = static_cast<u_long>(lpBuffer->length());
m_Statistics.m_dwTotalSendPending += wsaBuf.len;
if(SOCKET_ERROR == WSASend(m_hSocket, &wsaBuf, 1,
&dwSentBytes, 0, lpOverlapped, 0))
{
if(WSA_IO_PENDING != WSAGetLastError())
{
lpErrorFmtString = "SP:0x%p/DP:0x%p/IP:%15s/SOCKET:0x%p/ "
"InternalCloseSocket - WSASend Error - ErrorCode:%d";
}
}
}
else
{
lpErrorFmtString = "SP:0x%p/DP:0x%p/IP:%15s/SOCKET:0x%p/ InternalCloseSocket"
" - WSASend Error - Cannot Create SendOverlapped - ErrorCode:%d";
}
}
else
{
lpErrorFmtString = "SP:0x%p/DP:0x%p/IP:%15s/SOCKET:0x%p/ InternalCloseSocket"
" - WSASend Error - lpBuffer is 0 - ErrorCode:%d";
}
if(0 != lpErrorFmtString)
{
DETLOG5(g_SessionLog, lpErrorFmtString, this, m_lpDispatch,
m_RemoteAddr.get_addr_string(), m_hSocket, WSAGetLastError());
InternalCloseSocket();
if(0 != lpOverlapped)
{
lpOverlapped->SetBuffer(0);
m_SessionPolicy.GetOverlappedFactory().DeleteOverlapped(lpOverlapped);
}
return SEND_FAILED;
}
++m_dwSendPending;
return SEND_SUCCEEDED;
}
CSession::SendResult CSession::InternalSendTo(CBuffer* lpBuffer)
{
if(0 != m_dwSendPending)
{
return SEND_NEXT_TURN;
}
if(INVALID_SOCKET == m_hSocket)
{
return SEND_FAILED;
}
const char* lpErrorFmtString = 0;
COverlapped* lpOverlapped = 0;
if(0 != lpBuffer)
{
lpOverlapped = m_SessionPolicy.GetOverlappedFactory().CreateSend(this, lpBuffer);
if(0 != lpOverlapped)
{
unsigned long dwSentBytes = 0;
WSABUF wsaBuf;
wsaBuf.buf = lpBuffer->rd_ptr();
wsaBuf.len = static_cast<u_long>(lpBuffer->length());
m_Statistics.m_dwTotalSendPending += wsaBuf.len;
INET_Addr& addr = lpBuffer->get_addr();
if(SOCKET_ERROR == WSASendTo(m_hSocket, &wsaBuf, 1,
&dwSentBytes, 0, &addr.get_addr(), addr.get_size(), lpOverlapped, 0))
{
if(WSA_IO_PENDING != WSAGetLastError())
{
lpErrorFmtString = "SP:0x%p/DP:0x%p/IP:%15s/SOCKET:0x%p/ "
"InternalCloseSocket - WSASendTo Error - ErrorCode:%d";
}
}
}
else
{
lpErrorFmtString = "SP:0x%p/DP:0x%p/IP:%15s/SOCKET:0x%p/ InternalCloseSocket"
" - WSASendTo Error - Cannot Create SendOverlapped - ErrorCode:%d";
}
}
else
{
lpErrorFmtString = "SP:0x%p/DP:0x%p/IP:%15s/SOCKET:0x%p/ InternalCloseSocket"
" - WSASendTo Error - lpBuffer is 0 - ErrorCode:%d";
}
if(0 != lpErrorFmtString)
{
DETLOG5(g_SessionLog, lpErrorFmtString, this, m_lpDispatch,
m_RemoteAddr.get_addr_string(), m_hSocket, WSAGetLastError());
InternalCloseSocket();
if(0 != lpOverlapped)
{
lpOverlapped->SetBuffer(0);
m_SessionPolicy.GetOverlappedFactory().DeleteOverlapped(lpOverlapped);
}
return SEND_FAILED;
}
++m_dwSendPending;
return SEND_SUCCEEDED;
}
bool CSession::SendPending(CBuffer* lpBuffer)
{
SessionLock::Syncronize sync(m_SessionLock);
if(!(SessionFlag::SHUTDOWN_CALLED & m_cFlags) && INVALID_SOCKET != m_hSocket)
{
m_SendQueue.enqueue(lpBuffer);
return true;
}
return false;
}
bool CSession::InternalSend()
{
SendResult eSendResult = SEND_SUCCEEDED;
if(0 == m_dwSendPending)
{
CBuffer* lpBuffer = m_SendQueue.dequeue();
if(0 != lpBuffer)
{
eSendResult = (0 == lpBuffer->get_addr().get_size()) ?
InternalSend(lpBuffer) : InternalSendTo(lpBuffer);
if(SEND_SUCCEEDED != eSendResult)
{
m_SendQueue.enqueue(lpBuffer, true);
}
}
}
return (SEND_FAILED != eSendResult);
}
void CSession::SuspendRecv()
{
SessionLock::Syncronize sync(m_SessionLock);
m_cFlags |= SessionFlag::SUSPEND_RECV;
}
void CSession::ResumeRecv()
{
SessionLock::Syncronize sync(m_SessionLock);
m_cFlags &= ~SessionFlag::SUSPEND_RECV;
}

View File

@@ -0,0 +1,159 @@
#ifndef _CSESSION_H_
#define _CSESSION_H_
#include <winsock2.h>
#include <windows.h>
#include <mswsock.h>
#include <iosfwd>
#include "SessionPolicy.h"
#include "../Address/INET_Addr.h"
#include "../IOCP/Overlapped.h"
#include "../../Thread/Lock.h"
#include "../../Stream/Buffer/BufferQueue.h"
#pragma comment(lib, "ws2_32")
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
class CBuffer;
class CBufferFactory;
class CPacketDispatch;
class CDispatchFactory;
class CCompletionHandler;
class CSocketBaseFactory;
struct SessionStatistics
{
unsigned long m_dwTotalReceived; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>.
unsigned long m_dwTotalSendPending; // <20><><EFBFBD>ǿ<EFBFBD><C7BF><EFBFBD> pending<6E><67> <20><>.
unsigned long m_dwTotalSendCompleted; // Send<6E>Ϸ<EFBFBD><CFB7><EFBFBD> <20><>.
time_t m_ConnectedTime; // Connect<63><74> <20>ð<EFBFBD>.
time_t m_DisconnectedTime; // Disconnected<65><64> <20>ð<EFBFBD>.
SessionStatistics::SessionStatistics()
: m_dwTotalReceived(0), m_dwTotalSendPending(0), m_dwTotalSendCompleted(0),
m_ConnectedTime(0), m_DisconnectedTime(0)
{
}
void Initialize()
{
m_dwTotalReceived = m_dwTotalSendPending = m_dwTotalSendCompleted = 0;
m_ConnectedTime = m_DisconnectedTime = 0;
}
};
class CSession
{
public:
CSession(CSessionPolicy& SessionPolicy);
~CSession();
enum SendResult
{
SEND_SUCCEEDED,
SEND_FAILED,
SEND_NEXT_TURN,
};
LONG AddRef();
LONG Release();
bool IsConnected();
void CloseSession();
bool CalledConnected();
bool CalledDisconnected();
void SetAddress(INET_Addr& remoteAddr, INET_Addr& localAddr);
INET_Addr& GetRemoteAddr() { return m_RemoteAddr; }
INET_Addr& GetLocalAddr() { return m_LocalAddr; }
CPacketDispatch* GetDispatch() { return m_lpDispatch; }
CSessionPolicy& GetPolicy() { return m_SessionPolicy; }
const SessionStatistics& GetStatistics() { return m_Statistics; }
bool SendPending(CBuffer* lpBuffer);
void SendCompleted(BOOL bResult, unsigned long dwSendedBytes);
bool Process();
bool Dispatch(unsigned long dwReceivedBytes);
bool Recv() { SessionLock::Syncronize sync(m_SessionLock); return InternalRecv(); }
bool RecvFrom() { SessionLock::Syncronize sync(m_SessionLock); return InternalRecvFrom(); }
bool Send() { SessionLock::Syncronize sync(m_SessionLock); return InternalSend(); }
bool Connect(CCompletionHandler& Handler, LPSTR lpConnectAddress, unsigned short usPort);
bool Shutdown();
void SuspendRecv();
void ResumeRecv();
friend std::ostream& Log(std::ostream& strm, CSession* lpSession) { return (0 != lpSession) ? lpSession->PrintStatistics(strm) : strm; }
friend std::ostream& Log(std::ostream& strm, CSession& Session) { return Session.PrintStatistics(strm); }
private:
bool isValid() const { return (0 != m_lpRecvBuffer && 0 != m_lpDispatch); }
void Socket(SOCKET hSocket) { m_hSocket = hSocket; }
SOCKET Socket() { return m_hSocket; }
bool InternalRecv();
bool InternalRecvFrom();
bool InternalSend();
SendResult InternalSend(CBuffer* lpBuffer);
SendResult InternalSendTo(CBuffer* lpBuffer);
void InternalCloseSocket();
// Desc : <20>α<EFBFBD> <20><><EFBFBD><EFBFBD>
std::ostream& PrintStatistics(std::ostream& strm);
int InternalPrintStatistics(char* szBuffer, int nBufferLen);
// -------------------------------------------------------------------------
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
typedef CCSLock SessionLock; // Critical Section Lock (24byte)
SessionLock m_SessionLock; // Multithreadȯ<64><C8AF><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> Lock
CACHE_PAD(LockPadding, sizeof(SessionLock));// Cache-align<67><6E> <20><><EFBFBD><EFBFBD> Padding
// Shared class
CSessionPolicy& m_SessionPolicy; // Session Policy
// Per-session data
CPacketDispatch* m_lpDispatch; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> PacketDispatchŬ<68><C5AC><EFBFBD><EFBFBD>
SOCKET m_hSocket; // Socket Descriptor
INET_Addr m_RemoteAddr; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ּ<EFBFBD>
INET_Addr m_LocalAddr; // <20><><EFBFBD><EFBFBD> <20>ּ<EFBFBD>
CBuffer* m_lpRecvBuffer; // Recv Buffer
CBufferQueue m_SendQueue; // SendQueue
unsigned long m_dwRecvPending; // Recv PendingCount
unsigned long m_dwSendPending; // Send PendingCount
LONG m_nRefCount; // <20><><EFBFBD><EFBFBD> <20><><EFBFBD>۷<EFBFBD><DBB7><EFBFBD> ī<><C4AB>Ʈ
SessionStatistics m_Statistics; // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
unsigned char m_cCurrentStatus; // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
unsigned char m_cFlags; // <20><><EFBFBD><EFBFBD> flag
unsigned short m_usPadding; // <20>е<EFBFBD><D0B5><EFBFBD>
friend class CListener;
friend class CIOCPNet;
};
#endif

View File

@@ -0,0 +1,114 @@
#include "SessionMgr.h"
#include "Session.h"
#include <boost/pool/object_pool.hpp>
CSessionMgr::CSessionMgr()
: m_lpSessionPool(new boost::pool<>(sizeof(CSession)))
{
}
CSessionMgr::~CSessionMgr()
{
// <20><>Ÿ <20><><EFBFBD><EFBFBD><EFBFBD>۾<EFBFBD>.
Destroy(5000);
delete m_lpSessionPool;
}
void CSessionMgr::Add(CSession* lpSession)
{
if(0 != lpSession)
{
SessionLock::Syncronize sync(m_AddLock);
m_to_be_added.push_back(lpSession);
}
}
void CSessionMgr::InternalProcess()
{
{
SessionLock::Syncronize sync(m_AddLock);
m_current.splice(m_current.end(), m_to_be_added);
}
SessionSet::iterator pos = m_current.begin();
SessionSet::iterator end = m_current.end();
CSession* lpSession = 0;
for(;pos != end;)
{
lpSession = *pos;
if(!lpSession->Process())
{
pos = m_current.erase(pos);
DeleteSession(lpSession);
}
else
{
++pos;
}
}
}
void CSessionMgr::Destroy(unsigned long dwWaitTime)
{
SessionLock::Syncronize process_sync(m_ProcessLock);
{
SessionLock::Syncronize sync(m_AddLock);
m_current.splice(m_current.end(), m_to_be_added);
}
SessionSet::iterator pos = m_current.begin();
SessionSet::iterator end = m_current.end();
CSession* lpSession = 0;
for(;pos != end; ++pos)
{
lpSession = *pos;
lpSession->CloseSession();
}
pos = m_current.begin();
end = m_current.end();
unsigned long dwTime = timeGetTime();
while(!m_current.empty()
&& timeGetTime() < dwTime + dwWaitTime)
{
InternalProcess();
Sleep(10);
}
}
CSession* CSessionMgr::CreateSession(CSessionPolicy& SessionPolicy)
{
SessionLock::Syncronize sync(m_CreationLock);
void* ptr = m_lpSessionPool->malloc();
return ptr ? new (ptr) CSession(SessionPolicy) : 0;
}
void CSessionMgr::DeleteSession(CSession* lpSession)
{
SessionLock::Syncronize sync(m_CreationLock);
if(0 != m_lpSessionPool && 0 != lpSession)
{
lpSession->~CSession();
m_lpSessionPool->free(lpSession);
}
}

View File

@@ -0,0 +1,51 @@
#ifndef _NETWORK_SESSION_MGR_H_
#define _NETWORK_SESSION_MGR_H_
#include "../../Thread/Lock.h"
#include <list>
#include <boost/pool/poolfwd.hpp>
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
class CSession;
class CSessionPolicy;
class CSessionMgr
{
public:
CSessionMgr();
~CSessionMgr();
void Add(CSession* lpSession);
void Process() { SessionLock::Syncronize process_sync(m_ProcessLock); InternalProcess(); }
void Destroy(unsigned long dwWaitTime = INFINITE);
size_t GetSessionNum() { SessionLock::Syncronize process_sync(m_ProcessLock); return m_current.size(); }
CSession* CreateSession(CSessionPolicy& SessionPolicy);
void DeleteSession(CSession* lpSession);
private:
void InternalProcess();
typedef CCSLock SessionLock;
typedef std::list<CSession*> SessionSet;
SessionLock m_AddLock;
SessionSet m_to_be_added;
CACHE_PAD(AddLockPad, sizeof(SessionSet));
SessionLock m_ProcessLock;
SessionSet m_current;
CACHE_PAD(ProcessLockPad, sizeof(SessionSet));
SessionLock m_CreationLock;
boost::pool<>* m_lpSessionPool;
};
#endif

View File

@@ -0,0 +1,45 @@
#include "stdafx.h"
#include "SessionPolicy.h"
#include "../IOCP/Overlapped.h"
#include "../Dispatch/Dispatch.h"
#include "../Winsock/SocketFactory.h"
#include "../../Stream/Buffer/BufferFactory.h"
CSessionPolicy::CSessionPolicy(CSocketFactory* lpSocketFactory,
CBufferFactory* lpBufferFactory,
CDispatchFactory* lpDispatchFactory,
COverlappedFactory* lpOverlappedFactory)
: m_lpSocketFactory(lpSocketFactory),
m_lpBufferFactory(lpBufferFactory),
m_lpDispatchFactory(lpDispatchFactory),
m_lpOverlappedFactory(lpOverlappedFactory),
m_nRefCount(1)
{
}
CSessionPolicy::~CSessionPolicy()
{
delete m_lpSocketFactory;
delete m_lpBufferFactory;
delete m_lpDispatchFactory;
delete m_lpOverlappedFactory;
}
LONG CSessionPolicy::AddRef()
{
return InterlockedIncrement(&m_nRefCount);
}
LONG CSessionPolicy::Release()
{
LONG nRefCount = InterlockedDecrement(&m_nRefCount);
if(0 == nRefCount)
{
delete this;
}
return nRefCount;
}

View File

@@ -0,0 +1,66 @@
#ifndef _GAMA_NETWORK_LIBRARY_SESSION_POLICY_H_
#define _GAMA_NETWORK_LIBRARY_SESSION_POLICY_H_
// forward decl.
class CSocketFactory;
class CBufferFactory;
class CDispatchFactory;
class COverlappedFactory;
class CSessionPolicy
{
public:
LONG AddRef();
LONG Release();
bool IsValid()
{
return 0 != m_lpBufferFactory && 0 != m_lpSocketFactory &&
0 != m_lpDispatchFactory && 0 != m_lpOverlappedFactory;
}
CSocketFactory& GetSocketFactory() { return *m_lpSocketFactory; }
CBufferFactory& GetBufferFactory() { return *m_lpBufferFactory; }
CDispatchFactory& GetDispatchFactory() { return *m_lpDispatchFactory; }
COverlappedFactory& GetOverlappedFactory() { return *m_lpOverlappedFactory; }
// Creation Factory
template <class SocketFactory, class BufferFactory, class DispatchFactory, class OverlappedFactory>
static CSessionPolicy* Create()
{
CSessionPolicy* lpSessionPolicy = new (std::nothrow) CSessionPolicy(
new SocketFactory,
new BufferFactory,
new DispatchFactory,
new OverlappedFactory);
if(0 == lpSessionPolicy || !lpSessionPolicy->IsValid())
{
delete lpSessionPolicy;
lpSessionPolicy = 0;
}
return lpSessionPolicy;
}
// edith 2009.08.14 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>޸<EFBFBD><DEB8><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> Private Ÿ<>Կ<EFBFBD><D4BF><EFBFBD> Public Ÿ<><C5B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
~CSessionPolicy();
private:
CSessionPolicy(
CSocketFactory* lpSocketFactory,
CBufferFactory* lpBufferFactory,
CDispatchFactory* lpDispatchFactory,
COverlappedFactory* lpOverlappedFactory);
CSocketFactory* m_lpSocketFactory;
CBufferFactory* m_lpBufferFactory;
CDispatchFactory* m_lpDispatchFactory;
COverlappedFactory* m_lpOverlappedFactory;
LONG m_nRefCount;
};
#endif

View File

@@ -0,0 +1,280 @@
#include "stdafx.h"
#include <winsock2.h>
#include <windows.h>
#include <wsipx.h>
#include <cassert>
#include "SocketFactory.h"
//#include "../../Utility/Math/Math.h"
CSocketFactory::CSocketFactory(int nSocketFamily, int nSocketType, int nSocketProtocol, int nAddressLen)
: m_nSockFamily(nSocketFamily), m_nSockType(nSocketType), m_nSockProtocol(nSocketProtocol),
m_nAddressLen(nAddressLen)
{
}
CINETFamilyFactory::CINETFamilyFactory(int nSocketType, int nSocketProtocol)
: CSocketFactory(AF_INET, nSocketType, nSocketProtocol, sizeof(SOCKADDR_IN))
{
}
CTCPFactory::CTCPFactory()
: CINETFamilyFactory(SOCK_STREAM, IPPROTO_TCP)
{
}
CUDPFactory::CUDPFactory()
: CINETFamilyFactory(SOCK_DGRAM, IPPROTO_UDP)
{
}
/*
CIPXFamilyFactory::CIPXFamilyFactory(int nSocketType, int nSocketProtocol)
: CSocketFactory(AF_IPX, nSocketType, nSocketProtocol, sizeof(SOCKADDR_IPX))
{
}
CSPXFactory::CSPXFactory()
: CIPXFamilyFactory(SOCK_STREAM, NSPROTO_SPX)
{
}
CIPXFactory::CIPXFactory()
: CIPXFamilyFactory(SOCK_DGRAM, NSPROTO_IPX)
{
}
*/
SOCKET CSocketFactory::CreateSocket()
{
SOCKET hSocket = WSASocket(m_nSockFamily, m_nSockType, m_nSockProtocol,
NULL, 0, WSA_FLAG_OVERLAPPED);
return hSocket;
}
SOCKET CSocketFactory::CreateConnectedSocket(const char* lpConnAddr, unsigned short usPort)
{
SOCKADDR sockAddr;
if (!SetAddr(&sockAddr, lpConnAddr, usPort))
{
return INVALID_SOCKET;
}
SOCKET connectedSocket = CreateSocket();
if (INVALID_SOCKET != connectedSocket)
{
if (SOCKET_ERROR == connect(connectedSocket, &sockAddr, m_nAddressLen))
{
closesocket(connectedSocket);
connectedSocket = INVALID_SOCKET;
}
}
return connectedSocket;
}
SOCKET CSocketFactory::CreateBindedSocket(const char* lpBindAddr, unsigned short usPort)
{
SOCKADDR sockAddr;
if (!SetAddr(&sockAddr, lpBindAddr, usPort))
{
return INVALID_SOCKET;
}
SOCKET bindedSocket = CreateSocket();
if(INVALID_SOCKET != bindedSocket)
{
BOOL bReuseAddr = TRUE;
if (SOCKET_ERROR == setsockopt(bindedSocket, SOL_SOCKET, SO_REUSEADDR,
(char *)&bReuseAddr, sizeof(bReuseAddr)))
{
closesocket(bindedSocket);
bindedSocket = INVALID_SOCKET;
}
else
{
if(SOCKET_ERROR == bind(bindedSocket, &sockAddr, m_nAddressLen))
{
closesocket(bindedSocket);
bindedSocket = INVALID_SOCKET;
}
}
}
return bindedSocket;
}
SOCKET CSocketFactory::CreateListenSocket(const char* lpListenAddr, unsigned short usPort, int nBackLog)
{
nBackLog = min(nBackLog, MAX_BACKLOG);
// bind server to Server address
SOCKET sdListen = CreateBindedSocket(lpListenAddr, usPort);
if (INVALID_SOCKET != sdListen)
{
// start listening
if (SOCKET_ERROR == listen(sdListen, nBackLog))
{
closesocket(sdListen);
sdListen = INVALID_SOCKET;
}
}
return sdListen;
}
bool CINETFamilyFactory::SetAddr(LPSOCKADDR lpSA, const char* szAddr, unsigned short usPort)
{
int nAddrLen = sizeof(SOCKADDR_IN);
memset(lpSA, 0, nAddrLen);
LPSOCKADDR_IN lpSA_in = reinterpret_cast<LPSOCKADDR_IN>(lpSA);
if (0 != szAddr)
{
lpSA_in->sin_family = m_nSockFamily;
lpSA_in->sin_addr.S_un.S_addr = inet_addr(szAddr);
lpSA_in->sin_port = htons(usPort);
if(0 == lpSA_in->sin_addr.S_un.S_addr)
{
return false;
}
}
else
{
lpSA_in->sin_addr.S_un.S_addr = htonl(INADDR_ANY);
}
lpSA_in->sin_family = m_nSockFamily;
lpSA_in->sin_port = htons(usPort);
return true;
}
bool CINETFamilyFactory::GetNetworkInfo(char *Address_Out, int nMaxBufferSize)
{
const int MAX_HOSTNAME_BUFFER = 256;
char szHostName[MAX_HOSTNAME_BUFFER];
if(!gethostname(szHostName, MAX_HOSTNAME_BUFFER - 1))
{
szHostName[MAX_HOSTNAME_BUFFER - 1] = '\0';
PHOSTENT pHost = gethostbyname(szHostName);
if(NULL == pHost)
{
return false;
}
IN_ADDR Addr = {0,};
int Count = 0;
for(Count = 0;pHost->h_addr_list[Count]; ++Count)
{
memcpy(&Addr, pHost->h_addr_list[Count], sizeof(IN_ADDR));
strncpy(Address_Out, inet_ntoa(Addr), nMaxBufferSize - 1);
Address_Out[nMaxBufferSize - 1] = '\0';
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ȯ<><C8AE>
// 10.0.0.0 ~ 10.255.255.255
// 172.16.0.0 ~ 172.31.255.255
// 192.168.0.0 ~ 192.168.255.255
if((unsigned char)10 == Addr.S_un.S_un_b.s_b1)
{
continue;
}
else if((unsigned char)172 == Addr.S_un.S_un_b.s_b1)
{
if(Addr.S_un.S_un_b.s_b2 >= (unsigned char)16 && Addr.S_un.S_un_b.s_b2 <= (unsigned char)31)
{
continue;
}
}
else if((unsigned char)192 == Addr.S_un.S_un_b.s_b1)
{
if((unsigned char)168 == Addr.S_un.S_un_b.s_b2)
{
continue;
}
}
return true;
}
if(0 != Count)
{
return true;
}
}
return false;
}
bool CTCPFactory::SetLinger(SOCKET hSocket, bool bOn, unsigned short usTimeOut)
{
linger socketLinger;
socketLinger.l_onoff = bOn ? 1 : 0;
socketLinger.l_linger = usTimeOut;
if(SOCKET_ERROR == setsockopt(hSocket, SOL_SOCKET, SO_LINGER,
(char *)&socketLinger, sizeof(linger)))
{
return false;
}
return true;
}
/*
bool CIPXFamilyFactory::SetAddr(LPSOCKADDR lpSA, char *szAddr, unsigned short usPort)
{
if(0 == szAddr) { return false; }
// get the offset for node number / network number separator
LPSTR lpszNodeNum = strchr(szAddr, '.');
if (0 == lpszNodeNum)
{
return false;
}
++lpszNodeNum;
LPSOCKADDR_IPX lpSA_ipx = reinterpret_cast<LPSOCKADDR_IPX>(lpSA);
lpSA_ipx->sa_family = m_nSockFamily;
Math::Convert::AcToHe(szAddr,(char*)&lpSA_ipx->sa_netnum, 4);
Math::Convert::AcToHe(lpszNodeNum,(char*)&lpSA_ipx->sa_nodenum, 6);
lpSA_ipx->sa_socket = htons(usPort);
return true;
}
bool CIPXFamilyFactory::GetNetworkInfo(char *Address_Out, int nMaxBufferSize)
{
return true;
}
*/

View File

@@ -0,0 +1,105 @@
#ifndef _SOCKET_FAMILY_H_
#define _SOCKET_FAMILY_H_
class CSocketFactory
{
public:
virtual ~CSocketFactory() { }
SOCKET CreateConnectedSocket(const char* lpConnAddr, unsigned short usPort);
SOCKET CreateBindedSocket(const char* lpBindAddr, unsigned short usPort);
SOCKET CreateListenSocket(const char* lpListenAddr, unsigned short usPort, int nBackLog = MAX_BACKLOG);
virtual SOCKET CreateSocket();
virtual bool GetNetworkInfo(char* Address_Out, int nMaxBufferSize) = 0;
virtual bool SetAddr(LPSOCKADDR lpSA, const char* szAddr, unsigned short usPort) = 0;
inline int GetAddressLen() const { return m_nAddressLen; }
protected:
CSocketFactory(int nSocketFamily, int nSocketType,
int nSocketProtocol, int nAddressLen);
enum { MAX_BACKLOG = 63 };
int m_nSockFamily;
int m_nSockType;
int m_nSockProtocol;
int m_nAddressLen;
};
class CINETFamilyFactory : public CSocketFactory
{
public:
virtual bool GetNetworkInfo(char* Address_Out, int nMaxBufferSize);
virtual bool SetAddr(LPSOCKADDR lpSA, const char* szAddr, unsigned short usPort);
protected:
CINETFamilyFactory(int nSocketType, int nSocketProtocol);
virtual ~CINETFamilyFactory() { }
};
class CTCPFactory : public CINETFamilyFactory
{
public:
CTCPFactory();
virtual ~CTCPFactory() { }
static bool SetLinger(SOCKET hSocket, bool bOn, unsigned short usTimeOut);
};
class CUDPFactory : public CINETFamilyFactory
{
public:
CUDPFactory();
virtual ~CUDPFactory() { }
};
/*
//-----------------------------------------------------------------------------------------
class CIPXFamilyFactory : public CSocketFactory
{
public:
virtual bool GetNetworkInfo(char* Address_Out, int nMaxBufferSize);
virtual bool SetAddr(LPSOCKADDR lpSA, char* szAddr, unsigned short usPort);
protected:
CIPXFamilyFactory(int nSocketType, int nSocketProtocol);
virtual ~CIPXFamilyFactory() { }
};
class CSPXFactory : public CIPXFamilyFactory
{
public:
CSPXFactory();
virtual ~CSPXFactory() { }
};
class CIPXFactory : public CIPXFamilyFactory
{
public:
CIPXFactory();
virtual ~CIPXFactory() { }
};
//-----------------------------------------------------------------------------------------
*/
#endif

View File

@@ -0,0 +1,40 @@
#include "stdafx.h"
#include "Command.h"
CCommandProcess::CCommandProcess()
{
}
CCommandProcess::~CCommandProcess()
{
ClearAll();
}
void CCommandProcess::ProcessAll()
{
CMDList ProcessList;
m_CMDLock.Lock();
ProcessList.splice(ProcessList.end(), m_CMDList);
m_CMDLock.Unlock();
std::for_each(ProcessList.begin(), ProcessList.end(), std::mem_fun(&CCommand::DoProcess));
std::for_each(ProcessList.begin(), ProcessList.end(), std::mem_fun(&CCommand::Destroy));
}
void CCommandProcess::ClearAll()
{
CMDLock::Syncronize sync(m_CMDLock);
if(m_CMDList.empty())
{
return;
}
std::for_each(m_CMDList.begin(), m_CMDList.end(), std::mem_fun(&CCommand::Destroy));
m_CMDList.clear();
}

View File

@@ -0,0 +1,53 @@
#ifndef _PATTERN_COMMAND_H_
#define _PATTERN_COMMAND_H_
#include <list>
#include <algorithm>
#include <functional>
#include "../Thread/Lock.h"
class CCommand
{
public:
virtual bool DoProcess() = 0;
virtual bool Destroy() = 0; // <20><>ü<EFBFBD><C3BC> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
// stack<63><6B><EFBFBD><EFBFBD> <20><>ü<EFBFBD><C3BC> <20>ƹ<EFBFBD> <20>ϵ<EFBFBD> <20><><EFBFBD><EFBFBD> <20>ʰ<EFBFBD>, Heap<61><70><EFBFBD><EFBFBD> <20><>ü<EFBFBD><C3BC> delete this<69><73> <20><> <20><> <20><>.
};
class CCommandProcess
{
public:
typedef CCSLock CMDLock;
typedef std::list<CCommand*> CMDList;
CCommandProcess();
~CCommandProcess();
inline void Add(CCommand* lpNewCMD);
void ProcessAll();
protected:
void ClearAll();
CMDLock m_CMDLock;
CMDList m_CMDList;
};
inline void CCommandProcess::Add(CCommand* lpNewCMD)
{
if(NULL != lpNewCMD)
{
CMDLock::Syncronize sync(m_CMDLock);
m_CMDList.push_back(lpNewCMD);
}
}
#endif

View File

@@ -0,0 +1,106 @@
#include "stdafx.h"
#include "CommandQueue.h"
#include "Command.h"
#include <Thread/ThreadMgr.h>
#include <Log/ServerLog.h>
CCommandQueueThread::CCommandQueueThread(long nMaxQueueSize)
{
MsgQueueLock::Syncronize sync(m_Lock);
m_hHandles[StopperIndex] = CreateEvent(0, TRUE, FALSE, 0);
m_hHandles[SemaphoreIndex] = CreateSemaphore(0, 0, nMaxQueueSize, 0);
}
CCommandQueueThread::~CCommandQueueThread()
{
CThreadMgr::Stop(this);
MsgQueueLock::Syncronize sync(m_Lock);
CommandList::iterator pos = m_CommandList.begin();
CommandList::iterator end = m_CommandList.end();
for(;pos != end; ++pos)
{
(*pos)->Destroy();
}
m_CommandList.clear();
CloseHandle(m_hHandles[StopperIndex]);
CloseHandle(m_hHandles[SemaphoreIndex]);
}
bool CCommandQueueThread::IsValid()
{
MsgQueueLock::Syncronize sync(m_Lock);
return INVALID_HANDLE_VALUE != m_hHandles[StopperIndex] &&
INVALID_HANDLE_VALUE != m_hHandles[SemaphoreIndex];
}
bool CCommandQueueThread::Add(CCommand* lpCommand)
{
MsgQueueLock::Syncronize sync(m_Lock);
m_CommandList.push_back(lpCommand);
BOOL bResult = ReleaseSemaphore(m_hHandles[SemaphoreIndex], 1, 0);
if(!bResult)
{
m_CommandList.pop_back();
}
return 0 != bResult;
}
unsigned int CCommandQueueThread::Run()
{
bool bExit = false;
while(!bExit)
{
CCommand* lpCommand = 0;
switch(WaitForMultipleObjects(MaxIndex, m_hHandles, FALSE, INFINITE))
{
case StopperIndex:
bExit = true;
break;
case SemaphoreIndex:
{
MsgQueueLock::Syncronize sync(m_Lock);
if(!m_CommandList.empty())
{
lpCommand = m_CommandList.front();
m_CommandList.pop_front();
}
}
if(0 != lpCommand)
{
lpCommand->DoProcess();
lpCommand->Destroy();
lpCommand = 0;
}
break;
case WAIT_FAILED:
ERRLOG1(g_Log, "Err:%d/Error from WaitForMultipleObject", GetLastError());
bExit = true;
break;
}
}
return 0;
}
BOOL CCommandQueueThread::End()
{
return SetEvent(m_hHandles[StopperIndex]);
}

View File

@@ -0,0 +1,50 @@
#ifndef _SYNCRONIZED_COMMAND_QUEUE_
#define _SYNCRONIZED_COMMAND_QUEUE_
#include <winsock2.h>
#include <windows.h>
#include <Thread/Lock.h>
#include <Thread/Thread.h>
#include <list>
// forward decl.
class CCommand;
// <20>޽<EFBFBD><DEBD><EFBFBD> ť <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
class CCommandQueueThread : public CThread
{
public:
CCommandQueueThread(long nMaxQueueSize = LONG_MAX);
virtual ~CCommandQueueThread();
bool Add(CCommand* lpCommand);
bool IsValid();
protected:
enum Const
{
StopperIndex,
SemaphoreIndex,
MaxIndex
};
private:
virtual unsigned int Run();
virtual BOOL End();
typedef CCSLock MsgQueueLock;
typedef std::list<CCommand*> CommandList;
HANDLE m_hHandles[MaxIndex];
MsgQueueLock m_Lock;
CACHE_PAD(MsgQueueLockPad, sizeof(CCSLock));
CommandList m_CommandList;
};
#endif

View File

@@ -0,0 +1,124 @@
#ifndef _CSINGLETON_H_
#define _CSINGLETON_H_
#include <cassert>
template<typename Derived>
class CSingleton
{
private:
static Derived* ms_pSingleton;
protected:
CSingleton();
~CSingleton();
public:
static Derived& GetInstance();
static Derived* GetInstancePtr();
};
template<typename Derived>
CSingleton<Derived>::CSingleton()
{
assert(!ms_pSingleton && "Singleton Ŭ<><C5AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>̹<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ǿ<EFBFBD> <20>ֽ<EFBFBD><D6BD>ϴ<EFBFBD>.");
size_t nOffset = (size_t)(Derived*) 1 - (size_t)(CSingleton<Derived>*)(Derived*) 1;
ms_pSingleton = (Derived*)((size_t)this + nOffset);
}
template<typename Derived>
CSingleton<Derived>::~CSingleton()
{
assert(ms_pSingleton && "Singleton Ŭ<><C5AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʾҽ<CABE><D2BD>ϴ<EFBFBD>");
ms_pSingleton = 0;
}
template<typename Derived>
inline Derived& CSingleton<Derived>::GetInstance()
{
assert(ms_pSingleton && "Singleton Ŭ<><C5AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʾҽ<CABE><D2BD>ϴ<EFBFBD>");
return (*ms_pSingleton);
}
template<typename Derived>
inline Derived* CSingleton<Derived>::GetInstancePtr()
{
assert(ms_pSingleton && "Singleton Ŭ<><C5AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʾҽ<CABE><D2BD>ϴ<EFBFBD>");
return (ms_pSingleton);
}
template<typename Derived>
Derived* CSingleton<Derived>::ms_pSingleton = 0;
// Scotte Meyer's Implementation
template<typename Derived>
class CStaticSingleton
{
public:
inline static Derived& GetInstance()
{
static Derived Instance;
return Instance;
}
};
template<typename Derived>
class CLeakStaticSingleton
{
public:
inline static Derived& GetInstance()
{
static Derived* lpInstance = new Derived;
return *lpInstance;
}
};
// C++ FAQ's Implementation
template<typename T>
class CNiftyCounterSingleton
{
public:
CNiftyCounterSingleton() { ++nifty_count_; }
~CNiftyCounterSingleton() { if ( 0 == --nifty_count_ && pInstance_ ) { delete pInstance_; } }
static T& GetInstance()
{
if (NULL == pInstance_) { pInstance_ = new T; }
return *pInstance_;
}
private:
static int nifty_count_;
static T* pInstance_;
};
template<typename T>
int CNiftyCounterSingleton<T>::nifty_count_ = 0;
template<typename T>
T* CNiftyCounterSingleton<T>::pInstance_ = 0;
/*
Ŭ<><C5AC><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>.
Ŭ<><C5AC><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>, <20>Ҹ<EFBFBD><D2B8>ڴ<EFBFBD> private<74>̰<EFBFBD>, CNiftyCounterSingleton<6F><6E> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>.
namespace
{
CNiftyCounterSingleton<T> TNiftyCounter;
}
*/
#endif

View File

@@ -0,0 +1,21 @@
========================================================================
<20><><EFBFBD><EFBFBD> <20><><EFBFBD>̺귯<CCBA><EAB7AF> : BaseLibrary <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ <20><><EFBFBD><EFBFBD>
========================================================================
<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>α׷<CEB1> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E7BFA1> <20><> BaseLibrary <20><><EFBFBD>̺귯<CCBA><EAB7AF> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD>.
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ<EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ҽ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʾҽ<CABE><D2BD>ϴ<EFBFBD>.
BaseLibrary.vcproj
<20><><EFBFBD><EFBFBD> <20><><EFBFBD>α׷<CEB1> <20><><EFBFBD><EFBFBD><EFBFBD><20><><EFBFBD><EFBFBD><EFBFBD>Ͽ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> VC++ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> <20><20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ <20><><EFBFBD><EFBFBD><EFBFBD>Դϴ<D4B4>.
<20>ش<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Visual C++<2B><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ͽ<EFBFBD>
<20><><EFBFBD><EFBFBD> <20><><EFBFBD>α׷<CEB1> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E7BFA1> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>÷<EFBFBD><C3B7><EFBFBD>, <20><><EFBFBD><EFBFBD> <20><>
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ <20><><EFBFBD>ɿ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ֽ<EFBFBD><D6BD>ϴ<EFBFBD>.
/////////////////////////////////////////////////////////////////////////////
<EFBFBD><EFBFBD>Ÿ <20><><EFBFBD><EFBFBD>:
<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>α׷<CEB1> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E7BFA1> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> "TODO:" <20>ּ<EFBFBD><D6BC><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ڰ<EFBFBD> <20>߰<EFBFBD><DFB0>ϰų<CFB0> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ؾ<EFBFBD> <20>ϴ<EFBFBD>
<EFBFBD>ҽ<EFBFBD> <20>ڵ<EFBFBD> <20>κ<EFBFBD><CEBA><EFBFBD> <20><>Ÿ<EFBFBD><C5B8><EFBFBD>ϴ<EFBFBD>.
/////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,51 @@
#include "stdafx.h"
#include "Buffer.h"
#include "BufferFactory.h"
CBuffer::CBuffer(CBufferFactory& bufferfactory)
: internal_buffer_(0), rd_ptr_(0), wr_ptr_(0), buffer_size_(0),
bufferfactory_(bufferfactory), next_(0), prev_(0)
{
}
CBuffer::~CBuffer()
{
}
void CBuffer::init(char* internal_buffer, unsigned long buffer_size)
{
rd_ptr_ = wr_ptr_ = internal_buffer_ = internal_buffer;
buffer_size_ = buffer_size;
next_ = 0;
prev_ = 0;
address_.clear();
}
bool CBuffer::push(const void* ptr, size_t n)
{
if(NULL != wr_ptr_ && n <= capacity() - length())
{
memcpy(wr_ptr_, ptr, n);
wr_ptr_ += n;
return true;
}
return false;
}
void CBuffer::pop_read_data()
{
if(NULL != internal_buffer_)
{
size_t n = length();
memmove(internal_buffer_, rd_ptr_, n);
wr_ptr_ = internal_buffer_ + n;
rd_ptr_ = internal_buffer_;
}
}

View File

@@ -0,0 +1,78 @@
#ifndef _CBUFFER_H_
#define _CBUFFER_H_
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <winsock2.h>
#include <windows.h>
#include "../../Network/Address/INET_Addr.h"
class CBufferFactory;
class CBuffer
{
public:
CBuffer(CBufferFactory& bufferfactory);
~CBuffer();
void init(char* internal_buffer, unsigned long buffer_size);
bool is_valid() { return 0 != internal_buffer_; }
// <20>б<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
char* rd_ptr() const { return rd_ptr_; }
void rd_ptr(size_t n) { rd_ptr_ += n; }
void rd_ptr(char* ptr) { rd_ptr_ = ptr; }
// <20>б<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
char* wr_ptr() const { return wr_ptr_; }
void wr_ptr(size_t n) { wr_ptr_ += n; }
void wr_ptr(char* ptr) { wr_ptr_ = ptr; }
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(past-end) <20><> <20><><EFBFBD><EFBFBD>.
char* begin() const { return internal_buffer_; }
char* end() const { return internal_buffer_ + buffer_size_; }
// <20><><EFBFBD><EFBFBD><EFBFBD>͸<EFBFBD> <20><><EFBFBD>۷<EFBFBD> <20><><EFBFBD><EFBFBD>.
bool push(const void* ptr, size_t n);
// <20>̹<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>͵<EFBFBD><CDB5><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>. <20><> <20><><EFBFBD><EFBFBD><EFBFBD>͵<EFBFBD><CDB5><EFBFBD> <20><>ȿȭ<C8BF><C8AD>.
void pop_read_data();
size_t length() const { return wr_ptr_ - rd_ptr_; } // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
size_t capacity() const { return buffer_size_; } // <20><><EFBFBD><EFBFBD> ũ<><C5A9>
size_t remain() const { return internal_buffer_ + buffer_size_ - wr_ptr_; } // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
CBuffer* next() { return next_; }
void next(CBuffer* next) { next_ = next; }
CBuffer* prev() { return prev_; }
void prev(CBuffer* prev) { prev_ = prev; }
INET_Addr& get_addr() { return address_; }
CBufferFactory& GetBufferFactory() { return bufferfactory_; }
private:
// -----------------------------------------------------------
// variable
char* internal_buffer_;
char* rd_ptr_;
char* wr_ptr_;
size_t buffer_size_;
CBuffer* next_;
CBuffer* prev_;
INET_Addr address_;
CBufferFactory& bufferfactory_;
};
#endif

View File

@@ -0,0 +1,307 @@
#include "stdafx.h"
#include "Buffer.h"
#include "BufferFactory.h"
#include <boost/pool/pool.hpp>
#include <boost/pool/object_pool.hpp>
#include <Log/ServerLog.h>
CBuffer* CBufferFactory::CreateTracking(const char* szRoutine, const char* szFileName, const int nLine, size_t size)
{
CBuffer* lpBuffer = Create(size);
g_Log.DetailLog(LOG_DETAIL, szRoutine, szFileName, nLine,
"this:%p/BufferAllocate : (0x%p/%d)", this, lpBuffer, size);
return lpBuffer;
};
void CBufferFactory::ReleaseTracking(const char* szRoutine, const char* szFileName, const int nLine, CBuffer* lpBuffer)
{
if(0 != lpBuffer)
{
g_Log.DetailLog(LOG_DETAIL, szRoutine, szFileName, nLine,
"this:%p/BufferDeallocate : (0x%p/%d)", this, lpBuffer, lpBuffer->capacity());
Release(lpBuffer);
}
}
CBuffer* CDefaultBufferFactory::Create(size_t size)
{
char* szBuffer = new (std::nothrow) char[size];
CBuffer* lpBuffer = new (std::nothrow) CBuffer(*this);
if(0 != szBuffer && 0 != lpBuffer)
{
lpBuffer->init(szBuffer, size);
return lpBuffer;
}
delete lpBuffer;
delete [] szBuffer;
return 0;
}
void CDefaultBufferFactory::Release(CBuffer* lpBuffer)
{
if(0 != lpBuffer)
{
if(0 != lpBuffer->begin())
{
delete [] lpBuffer->begin();
}
delete lpBuffer;
}
}
// ----------------------------------------------------------------------------------------
// PoolBufferFactory
CPoolBufferFactory::CPoolBufferFactory()
: m_lpBufferPool(0)
{
Initialize();
}
CPoolBufferFactory::~CPoolBufferFactory()
{
Destroy();
}
bool CPoolBufferFactory::Initialize()
{
Destroy();
BufferLock::Syncronize sync(m_BufferLock);
m_lpBufferPool = new MemoryPool(sizeof(CBuffer));
if(0 == m_lpBufferPool)
{
return false;
}
const unsigned long MAX_SIZE_ARRAY = 7;
unsigned long dwSizeArray[MAX_SIZE_ARRAY] =
{
1024, 2048, 4096, 8192, 16384, 32768, 65535
};
for(unsigned long dwCount = 0; dwCount < MAX_SIZE_ARRAY; ++dwCount)
{
MemoryPool* lpMemoryPool = new MemoryPool(dwSizeArray[dwCount]);
if(0 == lpMemoryPool)
{
return false;
}
m_PoolArray.push_back(lpMemoryPool);
}
return true;
}
CBuffer* CPoolBufferFactory::Create(size_t size)
{
BufferLock::Syncronize sync(m_BufferLock);
if(m_lpBufferPool == 0)
return NULL;
void* ptr = m_lpBufferPool->malloc();
CBuffer* lpBuffer = 0;
if(0 != ptr)
{
lpBuffer = new (ptr) CBuffer(*this);
PoolArray::iterator pos = m_PoolArray.begin();
PoolArray::iterator end = m_PoolArray.end();
MemoryPool* lpMemoryPool = 0;
char* szBuffer = 0;
for(; pos != end; ++pos)
{
lpMemoryPool = (*pos);
size_t requested_size = lpMemoryPool->get_requested_size();
if(size <= requested_size)
{
szBuffer = reinterpret_cast<char*>(lpMemoryPool->malloc());
break;
}
}
if(0 == szBuffer)
{
szBuffer = new char[size];
}
if(0 != szBuffer)
{
lpBuffer->init(szBuffer, static_cast<unsigned long>(size));
}
else
{
m_lpBufferPool->free(lpBuffer);
lpBuffer = 0;
}
}
return lpBuffer;
}
void CPoolBufferFactory::Release(CBuffer* buffer)
{
if(0 != buffer)
{
BufferLock::Syncronize sync(m_BufferLock);
PoolArray::iterator pos = m_PoolArray.begin();
PoolArray::iterator end = m_PoolArray.end();
MemoryPool* lpMemoryPool = 0;
size_t buffer_size = buffer->capacity();
for(; pos != end; ++pos)
{
lpMemoryPool = (*pos);
size_t requested_size = lpMemoryPool->get_requested_size();
if(buffer_size <= requested_size)
{
lpMemoryPool->free(buffer->begin());
break;
}
}
if(pos == end)
{
delete [] buffer->begin();
}
buffer->~CBuffer();
m_lpBufferPool->free(buffer);
}
}
void CPoolBufferFactory::Destroy()
{
BufferLock::Syncronize sync(m_BufferLock);
delete m_lpBufferPool;
m_lpBufferPool = 0;
PoolArray::iterator pos = m_PoolArray.begin();
PoolArray::iterator end = m_PoolArray.end();
for(; pos != end; ++pos)
{
delete *pos;
}
m_PoolArray.clear();
}
//----------------------------------------------------------------------------------------
void CBufferFactoryTest::DoTest()
{
#define RealClock(Large_Integer_In) \
{ __asm rdtsc __asm mov Large_Integer_In.HighPart, edx __asm mov Large_Integer_In.LowPart, eax }
const char* const strErrLogFileName = "./PoolErrorLog.txt";
FILE* lpFile = freopen(strErrLogFileName, "wt", stderr);
if(0 == lpFile)
{
return;
}
fprintf(stderr, "%s Test Started.\n", __FUNCTION__);
LARGE_INTEGER start, stop;
double fTime = 0;
CDefaultBufferFactory bufferFactory;
const int MAX_LOOP = 10000;
for(int nBytes = 36; nBytes < 60000; nBytes *= 2)
{
char* pcBuffer = new char[nBytes];
for(int i = 0; i < nBytes; ++i)
{
pcBuffer[i] = (char)i;
}
CBuffer* pTemp = CREATE_BUFFER(bufferFactory, nBytes);
fTime = 0;
for(int i = 0; i < MAX_LOOP; ++i)
{
RealClock(start);
CBuffer* pBuffer = CREATE_BUFFER(bufferFactory, nBytes);
memcpy(pBuffer->wr_ptr(), pcBuffer, nBytes);
pBuffer->wr_ptr(nBytes);
SAFE_RELEASE_BUFFER(pBuffer);
RealClock(stop);
fTime += (double)(stop.QuadPart - start.QuadPart);
}
fprintf(stderr, "Buffer<EFBFBD>ӵ<EFBFBD> <20>׽<EFBFBD>Ʈ. %dBytes : %f\n", nBytes, fTime/MAX_LOOP);
fTime = 0;
for(int i = 0; i < MAX_LOOP; ++i)
{
RealClock(start);
char* pChar = new char[nBytes];
memcpy(pChar, pcBuffer, nBytes);
delete [] pChar;
RealClock(stop);
fTime += (double)(stop.QuadPart - start.QuadPart);
}
fprintf(stderr, "NewAndDelete %dBytes : %f\n\n", nBytes, fTime/MAX_LOOP);
SAFE_RELEASE_BUFFER(pTemp);
delete [] pcBuffer;
}
fprintf(stderr, "%s Test Completed.\n\n", __FUNCTION__);
fclose(lpFile);
#ifdef WIN32
char szPath[MAX_PATH];
char szFileNameWithPath[MAX_PATH];
UINT nResult = GetWindowsDirectory(szPath, MAX_PATH);
if(0 != nResult && nResult <= MAX_PATH)
{
_snprintf(szFileNameWithPath, MAX_PATH, "%s\\NotePad.exe %s", szPath, strErrLogFileName);
WinExec(szFileNameWithPath, SW_SHOW);
}
#endif
}

View File

@@ -0,0 +1,84 @@
#ifndef _CBUFFER_FACTORY_H_
#define _CBUFFER_FACTORY_H_
#include <vector>
#include <boost/pool/poolfwd.hpp>
#include "../../Thread/Lock.h"
//#define DEBUG_BUFFERFACTORY
#ifdef DEBUG_BUFFERFACTORY
#define BUFFER_ARGUMENT __FUNCTION__, __FILE__, __LINE__,
#define CREATE_METHOD CreateTracking
#define RELEASE_METHOD ReleaseTracking
#else
#define BUFFER_ARGUMENT
#define CREATE_METHOD Create
#define RELEASE_METHOD Release
#endif
#define CREATE_BUFFER(instance, size) (instance).CREATE_METHOD(BUFFER_ARGUMENT size)
#define SAFE_RELEASE_BUFFER(ptr) if(ptr) { (ptr)->GetBufferFactory().RELEASE_METHOD(BUFFER_ARGUMENT (ptr)); (ptr) = 0; }
// <09><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
class CBuffer;
class CBufferFactory
{
public:
virtual ~CBufferFactory() { }
virtual CBuffer* Create(size_t size) = 0;
virtual void Release(CBuffer* lpBuffer) = 0;
CBuffer* CreateTracking(const char* szRoutine, const char* szFileName, const int nLine, size_t size);
void ReleaseTracking(const char* szRoutine, const char* szFileName, const int nLine, CBuffer* lpBuffer);
};
class CDefaultBufferFactory : public CBufferFactory
{
public:
virtual CBuffer* Create(size_t size);
virtual void Release(CBuffer* lpBuffer);
};
class CPoolBufferFactory : public CBufferFactory
{
public:
CPoolBufferFactory();
virtual ~CPoolBufferFactory();
virtual CBuffer* Create(size_t size);
virtual void Release(CBuffer* lpBuffer);
void Destroy();
protected:
bool Initialize();
typedef boost::pool<> MemoryPool;
typedef std::vector<MemoryPool*> PoolArray;
typedef CCSLock BufferLock;
BufferLock m_BufferLock;
MemoryPool* m_lpBufferPool;
PoolArray m_PoolArray;
};
class CBufferFactoryTest
{
public:
void DoTest();
};
#endif

View File

@@ -0,0 +1,194 @@
#include "stdafx.h"
#include "Buffer.h"
#include "BufferQueue.h"
#include "BufferFactory.h"
CBufferQueue::CBufferQueue()
: m_lpHead(0),
m_lpTail(0),
m_bufferNum(0),
m_queueSize(0),
m_maxQueueSize(0xFFFFFFFF)
{
}
CBufferQueue::~CBufferQueue()
{
clear();
}
bool CBufferQueue::enqueue(CBuffer* lpBuffer, bool bPendHead)
{
if(0 != lpBuffer)
{
size_t bufferUsage = lpBuffer->length();
if(m_queueSize + bufferUsage < m_maxQueueSize)
{
if(0 == m_lpHead)
{
m_lpHead = m_lpTail = lpBuffer;
}
else if(!bPendHead)
{
m_lpTail->next(lpBuffer);
lpBuffer->prev(m_lpTail);
m_lpTail = lpBuffer;
}
else
{
lpBuffer->next(m_lpHead);
m_lpHead->prev(lpBuffer);
m_lpHead = lpBuffer;
}
++m_bufferNum;
m_queueSize += bufferUsage;
return true;
}
}
return false;
}
CBuffer* CBufferQueue::dequeue()
{
CBuffer* lpBuffer = 0;
if(0 != m_lpHead)
{
lpBuffer = m_lpHead;
m_lpHead = m_lpHead->next();
lpBuffer->prev(0);
lpBuffer->next(0);
if(m_lpTail == lpBuffer)
{
m_lpTail = 0;
}
--m_bufferNum;
m_queueSize -= lpBuffer->length();
}
return lpBuffer;
}
void CBufferQueue::clear()
{
CBuffer* lpDelete = 0;
while(0 != m_lpHead)
{
lpDelete = m_lpHead;
m_lpHead = m_lpHead->next();
SAFE_RELEASE_BUFFER(lpDelete);
}
m_lpTail = 0;
m_bufferNum = 0;
m_queueSize = 0;
}
void CBufferQueue::splice(CBufferQueue& Buffer_In, bool bPendHead)
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> BufferQueue<75><65> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> BufferQueue<75><65> <20><><EFBFBD>δ<EFBFBD>.
if(0 != Buffer_In.m_lpHead)
{
if(0 == m_lpHead)
{
m_lpHead = Buffer_In.m_lpHead;
m_lpTail = Buffer_In.m_lpTail;
}
else if(!bPendHead)
{
m_lpTail->next(Buffer_In.m_lpHead);
Buffer_In.m_lpHead->prev(m_lpTail);
m_lpTail = Buffer_In.m_lpTail;
}
else
{
Buffer_In.m_lpTail->next(m_lpHead);
m_lpHead->prev(Buffer_In.m_lpTail);
m_lpHead = Buffer_In.m_lpHead;
}
m_bufferNum += Buffer_In.getBufferNum();
m_queueSize += Buffer_In.getQueueSize();
Buffer_In.m_lpHead = 0;
Buffer_In.m_lpTail = 0;
Buffer_In.m_bufferNum = 0;
Buffer_In.m_queueSize = 0;
}
}
void CBufferQueue::splice_n(CBufferQueue& Buffer_In, unsigned long dwSpliceNum, bool bPendHead)
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> BufferQueue<75><65> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20>ִ<EFBFBD> dwSpliceNum<75><6D> <20><>ŭ<EFBFBD><C5AD> <20><> BufferQueue<75><65> <20><><EFBFBD>δ<EFBFBD>.
if (Buffer_In.getBufferNum() <= dwSpliceNum)
{
// <20>ִ밳<D6B4><EBB0B3> <20≯<EFBFBD><CCB8≯<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>δ<EFBFBD>.
splice(Buffer_In, bPendHead);
}
else if(0 != Buffer_In.m_lpHead)
{
// <20>ִ밳<D6B4><EBB0B3> <20>̻<EFBFBD><CCBB><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD>, <20>ϴ<EFBFBD> Ž<><C5BD> <20><><EFBFBD><EFBFBD><EEB0A1> <20>߶󳽴<DFB6>.
unsigned long dwBufferNum = 0; // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
unsigned long dwQueueSize = 0; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>(byte)
CBuffer* lpNewBufferHead = Buffer_In.m_lpHead;
for(; dwBufferNum < dwSpliceNum; ++dwBufferNum)
{
dwQueueSize += lpNewBufferHead->length();
lpNewBufferHead = lpNewBufferHead->next();
}
// <20>յڸ<D5B5> <20>߶󳽴<DFB6>.
CBuffer* lpSplicedHead = Buffer_In.m_lpHead;
CBuffer* lpSplicedTail = lpNewBufferHead;
Buffer_In.m_lpHead = lpSplicedTail->next();
Buffer_In.m_lpHead->prev(0);
lpSplicedTail->next(0);
Buffer_In.m_bufferNum -= dwBufferNum;
Buffer_In.m_queueSize -= dwQueueSize;
if(0 == m_lpHead)
{
m_lpHead = lpSplicedHead;
m_lpTail = lpSplicedTail;
}
else if(!bPendHead)
{
m_lpTail->next(lpSplicedHead);
lpSplicedHead->prev(m_lpTail);
m_lpTail = lpSplicedTail;
}
else
{
lpSplicedTail->next(m_lpHead);
m_lpHead->prev(lpSplicedTail);
m_lpHead = lpSplicedHead;
}
m_bufferNum += dwBufferNum;
m_queueSize += dwQueueSize;
}
}

View File

@@ -0,0 +1,42 @@
#ifndef _GAMA_SERVER_LIB_BUFFER_QUEUE_H_
#define _GAMA_SERVER_LIB_BUFFER_QUEUE_H_
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
#include <list>
class CBuffer;
class CBufferQueue
{
public:
CBufferQueue();
virtual ~CBufferQueue();
void setMaxQueueSize(unsigned long dwMaxQueueSize) { m_maxQueueSize = dwMaxQueueSize; }
bool enqueue(CBuffer* lpBuffer, bool bPendHead = false);
CBuffer* dequeue();
void splice(CBufferQueue& Buffer_In, bool bPendHead = false);
void splice_n(CBufferQueue& Buffer_In, unsigned long dwSpliceNum, bool bPendHead = false);
void clear();
CBuffer* getHead() { return m_lpHead; }
bool empty() const { return 0 == m_bufferNum; }
size_t getQueueSize() const { return m_queueSize; }
size_t getBufferNum() const { return m_bufferNum; }
private:
CBuffer* m_lpHead;
CBuffer* m_lpTail;
size_t m_bufferNum;
size_t m_queueSize;
size_t m_maxQueueSize;
};
#endif

View File

@@ -0,0 +1,191 @@
#ifndef _CLOCK_H_
#define _CLOCK_H_
#include <winsock2.h>
#include <windows.h>
// <20><><EFBFBD><EFBFBD> CPUȯ<55><EFBFBD><E6BFA1><EFBFBD><EFBFBD> Cache-Line<6E><65> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ؾ߸<D8BE> <20><> <20><>.
#define CACHE_ALIGN 32
#define CACHE_PAD(Name, BytesSoFar) \
BYTE Name[CACHE_ALIGN - ((BytesSoFar) % CACHE_ALIGN)]
template<class DerivedLockClass>
class CLock
{
public:
class Syncronize
{
public:
Syncronize(DerivedLockClass* pLockClass) : m_Lock(*pLockClass) { m_Lock.Lock(); }
Syncronize(DerivedLockClass& LockClass) : m_Lock(LockClass) { m_Lock.Lock(); }
~Syncronize() { m_Lock.Unlock();}
protected:
DerivedLockClass& m_Lock;
};
};
// <20><> LockŬ<6B><C5AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>̻<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>޾Ƽ<DEBE><C6BC><EFBFBD> <20><> <20>ȴ<EFBFBD>.
// ----------------------------------------------------------------------------
// DummyLock ------------------------------------------------------------------
class CDummyLock : public CLock<CDummyLock>
{
public:
void Lock() { }
void Unlock() { }
bool IsVaildLock() { return true; }
};
// ----------------------------------------------------------------------------
// SpinLock -------------------------------------------------------------------
class CSpinLock : public CLock<CSpinLock>
{
public:
CSpinLock() : m_bLocked(FALSE) { }
~CSpinLock() { }
void Lock() { while(TRUE == InterlockedExchange(&m_bLocked, TRUE)) { Sleep(0); } }
void Unlock() { InterlockedExchange(&m_bLocked, FALSE); }
bool IsVaildLock() { return true; }
private:
volatile LONG m_bLocked;
};
// ----------------------------------------------------------------------------
// Critical Section -----------------------------------------------------------
class CCSLock : public CLock<CCSLock>
{
public:
CCSLock() { InitializeCriticalSection(&m_CSLock); }
~CCSLock() { DeleteCriticalSection(&m_CSLock); }
void Lock() { EnterCriticalSection(&m_CSLock); }
void Unlock() { LeaveCriticalSection(&m_CSLock); }
bool IsVaildLock() { return true; }
private:
CRITICAL_SECTION m_CSLock;
};
// ----------------------------------------------------------------------------
// Mutex Lock -----------------------------------------------------------------
class CMutex : public CLock<CMutex>
{
public:
CMutex() : m_hMutex(CreateMutex(NULL, FALSE, NULL)) { }
~CMutex() { if(0 != m_hMutex) { CloseHandle(m_hMutex); } }
unsigned long Lock() { return WaitForSingleObject(m_hMutex, INFINITE); }
unsigned long Unlock() { return ReleaseMutex(m_hMutex); }
bool IsVaildLock() { return (NULL != m_hMutex); }
private:
HANDLE m_hMutex;
};
class CNamedMutex : public CLock<CNamedMutex>
{
public:
CNamedMutex(const TCHAR* szMutexName, BOOL bInitialOwner)
: m_hMutex(CreateMutex(NULL, bInitialOwner, szMutexName)) { }
~CNamedMutex() { if(0 != m_hMutex) { CloseHandle(m_hMutex); } }
unsigned long Lock() { return WaitForSingleObject(m_hMutex, INFINITE); }
unsigned long Unlock() { return ReleaseMutex(m_hMutex); }
bool IsVaildLock() { return (NULL != m_hMutex); }
private:
HANDLE m_hMutex;
};
/*
class CFairRWLock : private CCSLock
{
private:
Semaphore access_lock; // used as a one-at-a-time release valve
CCSLock read_barrier; // used to block/wakeup readers
unsigned int is_write_lock; // nonzero if locked for writing
unsigned int writer_count; // # of writers waiting for or holding the lock
unsigned int reader_count; // # of readers holding the lock
unsigned int readers_waiting; // # of readers waiting for the lock
public:
ReadLock()
: access_lock(1), is_write_lock(0),
writers_waiting(0), reader_count(0), readers_waiting(0)
{
}
void ReadLock()
{
Mutex::Lock();
// if there is at least one writer using the lock or waiting for it,
// we need to wait for access
if (writer_count > 0))
{
if (readers_waiting++ == 0) // if we're the first reader in line
Mutex::Unlock();
access_lock.Wait(); // get the access lock
Mutex::Lock();
if (readers_waiting > 1) // then if there are other readers
read_barrier.Open(); // let them go
}
else
{
Mutex::Unlock();
read_barrier.Wait(); // otherwise wait until someone lets us go
Mutex::Lock();
}
readers_waiting--;
}
reader_count++;
Mutex::Unlock();
}
void WriteLock()
{
Mutex::Lock();
writer_count++; // one more writer
Mutex::Unlock();
access_lock.Wait(); // wait until the access lock is available
Mutex::Lock();
is_write_lock = 1; // lock is a write lock
read_barrier.Close(); // give readers something to wait for
Mutex::Unlock();
}
void Unlock()
{
Mutex::Lock();
if (is_write_lock)
{ // if this is a write lock
is_write_lock = 0; // let it go
writer_count--; // one less writer
access_lock.Post(); // now let someone else have a chance
}
else if (--reader_count == 0)
{
// if we're the last reader
access_lock.Post(); // release the access lock
}
Mutex::Unlock();
}
};
*/
#endif

View File

@@ -0,0 +1,35 @@
#ifndef _CTHREAD_H_
#define _CTHREAD_H_
#include <winsock2.h>
#include <windows.h>
class CThread
{
public:
CThread() : m_hThreadHandle(INVALID_HANDLE_VALUE) { }
virtual ~CThread() { }
protected:
virtual unsigned int Run() = 0; // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>Ǵ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ִ´<D6B4>.
virtual BOOL End() = 0; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20>ִ<EFBFBD> <20><>ƾ<EFBFBD><C6BE> <20>ִ´<D6B4>.
typedef unsigned int(__stdcall *LPThreadFunc)(void*);
static inline unsigned int __stdcall ThreadFunc(void* pArg);
inline void SetHandle(HANDLE hHandle) { m_hThreadHandle = hHandle; }
inline HANDLE GetHandle() { return m_hThreadHandle; }
HANDLE m_hThreadHandle;
friend class CThreadMgr;
};
inline unsigned int __stdcall CThread::ThreadFunc(void* pArg)
{
return static_cast<CThread*>(pArg)->Run();
}
#endif

View File

@@ -0,0 +1,126 @@
#include "stdafx.h"
#include "Thread.h"
#include "ThreadMgr.h"
#include <algorithm>
#include <functional>
#include "GMMemory.h"
// constructor and destructor
CThreadMgr::CThreadMgr()
: m_nThreadNum(0), m_bJoinStarted(FALSE)
{
std::fill_n(m_lpThreads, size_t(MAX_THREAD_NUM), reinterpret_cast<CThread*>(0));
std::fill_n(m_hThreads, size_t(MAX_THREAD_NUM), INVALID_HANDLE_VALUE);
}
CThreadMgr::~CThreadMgr()
{
JoinThread();
}
bool CThreadMgr::RegisterAndRun(CThread* llpThread)
{
unsigned int nThreadID = 0;
unsigned int nThreadIndex = 0;
if(0 == llpThread)
{
return false;
}
// Lock
{
ThreadLock::Syncronize sync(m_ThreadLock);
if(63 <= m_nThreadNum || TRUE == m_bJoinStarted)
{
return false;
}
nThreadIndex = m_nThreadNum;
++m_nThreadNum;
}
m_lpThreads[nThreadIndex] = llpThread;
m_hThreads[nThreadIndex] = reinterpret_cast<HANDLE>(_beginthreadex(0, 0,
CThread::ThreadFunc, llpThread, 0, &nThreadID));
return (0 != m_hThreads[nThreadIndex]);
}
bool CThreadMgr::JoinThread()
{
{
ThreadLock::Syncronize sync(m_ThreadLock);
if(0 == m_nThreadNum)
{
return true;
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>۵Ǹ<DBB5>, <20><><EFBFBD>̻<EFBFBD><CCBB><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
m_bJoinStarted = TRUE;
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> & <20><><EFBFBD><EFBFBD>.
std::for_each(&m_lpThreads[0], &m_lpThreads[m_nThreadNum], std::mem_fun(&CThread::End));
WaitForMultipleObjects(m_nThreadNum, m_hThreads, TRUE, INFINITE);
CThread** lppPastEndThread = m_lpThreads + MAX_THREAD_NUM;
HANDLE* lppPastEndHandle = m_hThreads + MAX_THREAD_NUM;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ҹ<EFBFBD>.
for(CThread** lplpThread = m_lpThreads;
lplpThread != lppPastEndThread; ++lplpThread)
{
delete *lplpThread;
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ڵ<EFBFBD> <20>Ҹ<EFBFBD>.
for(HANDLE* lppHandle = m_hThreads;
lppHandle != lppPastEndHandle; ++lppHandle)
{
CloseHandle(*lppHandle);
}
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
ThreadLock::Syncronize sync(m_ThreadLock);
m_nThreadNum = 0;
m_bJoinStarted = FALSE;
}
return true;
}
HANDLE CThreadMgr::Run(CThread* lpThread)
{
unsigned int nThreadID = 0;
HANDLE hThread = reinterpret_cast<HANDLE>(_beginthreadex(0,
0, CThread::ThreadFunc, lpThread, 0, &nThreadID));
lpThread->SetHandle(hThread);
return hThread;
}
bool CThreadMgr::Stop(CThread* lpThread, unsigned long dwTimeout)
{
if(0 == lpThread)
{
return false;
}
HANDLE hThread = lpThread->GetHandle();
if(INVALID_HANDLE_VALUE == hThread)
{
return false;
}
lpThread->SetHandle(INVALID_HANDLE_VALUE);
lpThread->End();
WaitForSingleObject(hThread, dwTimeout);
return (TRUE == CloseHandle(hThread));
}

View File

@@ -0,0 +1,61 @@
#ifndef _CTHREADMGR_H_
#define _CTHREADMGR_H_
#ifndef WINDOWS_LEAN_AND_MEAN
#define WINDOWS_LEAN_AND_MEAN
#endif
#include <winsock2.h>
#include <windows.h>
#include <process.h>
#include "Lock.h"
// forward decl
class CThread;
class CThreadMgr
{
public:
enum { MAX_THREAD_NUM = 63 };
CThreadMgr();
virtual ~CThreadMgr();
bool RegisterAndRun(CThread* lpThread); // <20><><EFBFBD><EFBFBD><EFBFBD><20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>. <20>ִ<EFBFBD> 63<36><33><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20>ִ<EFBFBD>.
bool JoinThread(); // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ų<EFBFBD><C5B2>.
inline int GetNum()
{
return m_nThreadNum;
}
inline int GetMaxNum()
{
return MAX_THREAD_NUM;
}
CThread* GetThread(int iPos)
{
return m_lpThreads[iPos];
}
// <20>Ŵ<EFBFBD><C5B4><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʰ<EFBFBD>, <20>׳<EFBFBD> <20><><EFBFBD><EFBFBD> <20><>Ų<EFBFBD><C5B2>.
static HANDLE Run(CThread* lpThread);
static bool Stop(CThread* lpThread, unsigned long dwTimeout = INFINITE);
private:
typedef CCSLock ThreadLock;
CThread* m_lpThreads[MAX_THREAD_NUM];
HANDLE m_hThreads[MAX_THREAD_NUM];
ThreadLock m_ThreadLock;
unsigned int m_nThreadNum;
unsigned int m_bJoinStarted;
};
#endif

View File

@@ -0,0 +1,451 @@
/* lzoconf.h -- configuration for the LZO real-time data compression library
This file is part of the LZO real-time data compression library.
Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer
All Rights Reserved.
The LZO library is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
The LZO library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the LZO library; see the file COPYING.
If not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Markus F.X.J. Oberhumer
<markus@oberhumer.com>
http://www.oberhumer.com/opensource/lzo/
*/
#ifndef __LZOCONF_H
#define __LZOCONF_H
#define LZO_VERSION 0x1080
#define LZO_VERSION_STRING "1.08"
#define LZO_VERSION_DATE "Jul 12 2002"
/* internal Autoconf configuration file - only used when building LZO */
#if defined(LZO_HAVE_CONFIG_H)
# include <config.h>
#endif
#include <limits.h>
#ifdef __cplusplus
extern "C" {
#endif
/***********************************************************************
// LZO requires a conforming <limits.h>
************************************************************************/
#if !defined(CHAR_BIT) || (CHAR_BIT != 8)
# error "invalid CHAR_BIT"
#endif
#if !defined(UCHAR_MAX) || !defined(UINT_MAX) || !defined(ULONG_MAX)
# error "check your compiler installation"
#endif
#if (USHRT_MAX < 1) || (UINT_MAX < 1) || (ULONG_MAX < 1)
# error "your limits.h macros are broken"
#endif
/* workaround a cpp bug under hpux 10.20 */
#define LZO_0xffffffffL 4294967295ul
#if !defined(LZO_UINT32_C)
# if (UINT_MAX < LZO_0xffffffffL)
# define LZO_UINT32_C(c) c ## UL
# else
# define LZO_UINT32_C(c) c ## U
# endif
#endif
/***********************************************************************
// architecture defines
************************************************************************/
#if !defined(__LZO_WIN) && !defined(__LZO_DOS) && !defined(__LZO_OS2)
# if defined(__WINDOWS__) || defined(_WINDOWS) || defined(_Windows)
# define __LZO_WIN
# elif defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
# define __LZO_WIN
# elif defined(__NT__) || defined(__NT_DLL__) || defined(__WINDOWS_386__)
# define __LZO_WIN
# elif defined(__DOS__) || defined(__MSDOS__) || defined(MSDOS)
# define __LZO_DOS
# elif defined(__OS2__) || defined(__OS2V2__) || defined(OS2)
# define __LZO_OS2
# elif defined(__palmos__)
# define __LZO_PALMOS
# elif defined(__TOS__) || defined(__atarist__)
# define __LZO_TOS
# endif
#endif
#if (UINT_MAX < LZO_0xffffffffL)
# if defined(__LZO_WIN)
# define __LZO_WIN16
# elif defined(__LZO_DOS)
# define __LZO_DOS16
# elif defined(__LZO_PALMOS)
# define __LZO_PALMOS16
# elif defined(__LZO_TOS)
# define __LZO_TOS16
# elif defined(__C166__)
# else
/* porting hint: for pure 16-bit architectures try compiling
* everything with -D__LZO_STRICT_16BIT */
# error "16-bit target not supported - contact me for porting hints"
# endif
#endif
#if !defined(__LZO_i386)
# if defined(__LZO_DOS) || defined(__LZO_WIN16)
# define __LZO_i386
# elif defined(__i386__) || defined(__386__) || defined(_M_IX86)
# define __LZO_i386
# endif
#endif
#if defined(__LZO_STRICT_16BIT)
# if (UINT_MAX < LZO_0xffffffffL)
# include <lzo16bit.h>
# endif
#endif
/* memory checkers */
#if !defined(__LZO_CHECKER)
# if defined(__BOUNDS_CHECKING_ON)
# define __LZO_CHECKER
# elif defined(__CHECKER__)
# define __LZO_CHECKER
# elif defined(__INSURE__)
# define __LZO_CHECKER
# elif defined(__PURIFY__)
# define __LZO_CHECKER
# endif
#endif
/***********************************************************************
// integral and pointer types
************************************************************************/
/* Integral types with 32 bits or more */
#if !defined(LZO_UINT32_MAX)
# if (UINT_MAX >= LZO_0xffffffffL)
typedef unsigned int lzo_uint32;
typedef int lzo_int32;
# define LZO_UINT32_MAX UINT_MAX
# define LZO_INT32_MAX INT_MAX
# define LZO_INT32_MIN INT_MIN
# elif (ULONG_MAX >= LZO_0xffffffffL)
typedef unsigned long lzo_uint32;
typedef long lzo_int32;
# define LZO_UINT32_MAX ULONG_MAX
# define LZO_INT32_MAX LONG_MAX
# define LZO_INT32_MIN LONG_MIN
# else
# error "lzo_uint32"
# endif
#endif
/* lzo_uint is used like size_t */
#if !defined(LZO_UINT_MAX)
# if (UINT_MAX >= LZO_0xffffffffL)
typedef unsigned int lzo_uint;
typedef int lzo_int;
# define LZO_UINT_MAX UINT_MAX
# define LZO_INT_MAX INT_MAX
# define LZO_INT_MIN INT_MIN
# elif (ULONG_MAX >= LZO_0xffffffffL)
typedef unsigned long lzo_uint;
typedef long lzo_int;
# define LZO_UINT_MAX ULONG_MAX
# define LZO_INT_MAX LONG_MAX
# define LZO_INT_MIN LONG_MIN
# else
# error "lzo_uint"
# endif
#endif
typedef int lzo_bool;
/***********************************************************************
// memory models
************************************************************************/
/* Memory model for the public code segment. */
#if !defined(__LZO_CMODEL)
# if defined(__LZO_DOS16) || defined(__LZO_WIN16)
# define __LZO_CMODEL __far
# elif defined(__LZO_i386) && defined(__WATCOMC__)
# define __LZO_CMODEL __near
# else
# define __LZO_CMODEL
# endif
#endif
/* Memory model for the public data segment. */
#if !defined(__LZO_DMODEL)
# if defined(__LZO_DOS16) || defined(__LZO_WIN16)
# define __LZO_DMODEL __far
# elif defined(__LZO_i386) && defined(__WATCOMC__)
# define __LZO_DMODEL __near
# else
# define __LZO_DMODEL
# endif
#endif
/* Memory model that allows to access memory at offsets of lzo_uint. */
#if !defined(__LZO_MMODEL)
# if (LZO_UINT_MAX <= UINT_MAX)
# define __LZO_MMODEL
# elif defined(__LZO_DOS16) || defined(__LZO_WIN16)
# define __LZO_MMODEL __huge
# define LZO_999_UNSUPPORTED
# elif defined(__LZO_PALMOS16) || defined(__LZO_TOS16)
# define __LZO_MMODEL
# else
# error "__LZO_MMODEL"
# endif
#endif
/* no typedef here because of const-pointer issues */
#define lzo_byte unsigned char __LZO_MMODEL
#define lzo_bytep unsigned char __LZO_MMODEL *
#define lzo_charp char __LZO_MMODEL *
#define lzo_voidp void __LZO_MMODEL *
#define lzo_shortp short __LZO_MMODEL *
#define lzo_ushortp unsigned short __LZO_MMODEL *
#define lzo_uint32p lzo_uint32 __LZO_MMODEL *
#define lzo_int32p lzo_int32 __LZO_MMODEL *
#define lzo_uintp lzo_uint __LZO_MMODEL *
#define lzo_intp lzo_int __LZO_MMODEL *
#define lzo_voidpp lzo_voidp __LZO_MMODEL *
#define lzo_bytepp lzo_bytep __LZO_MMODEL *
#ifndef lzo_sizeof_dict_t
# define lzo_sizeof_dict_t sizeof(lzo_bytep)
#endif
/***********************************************************************
// calling conventions and function types
************************************************************************/
/* linkage */
#if !defined(__LZO_EXTERN_C)
# ifdef __cplusplus
# define __LZO_EXTERN_C extern "C"
# else
# define __LZO_EXTERN_C extern
# endif
#endif
/* calling convention */
#if !defined(__LZO_CDECL)
# if defined(__LZO_DOS16) || defined(__LZO_WIN16)
# define __LZO_CDECL __LZO_CMODEL __cdecl
# elif defined(__LZO_i386) && defined(_MSC_VER)
# define __LZO_CDECL __LZO_CMODEL __cdecl
# elif defined(__LZO_i386) && defined(__WATCOMC__)
# define __LZO_CDECL __LZO_CMODEL __cdecl
# else
# define __LZO_CDECL __LZO_CMODEL
# endif
#endif
#if !defined(__LZO_ENTRY)
# define __LZO_ENTRY __LZO_CDECL
#endif
/* C++ exception specification for extern "C" function types */
#if !defined(__cplusplus)
# undef LZO_NOTHROW
# define LZO_NOTHROW
#elif !defined(LZO_NOTHROW)
# define LZO_NOTHROW
#endif
typedef int
(__LZO_ENTRY *lzo_compress_t) ( const lzo_byte *src, lzo_uint src_len,
lzo_byte *dst, lzo_uintp dst_len,
lzo_voidp wrkmem );
typedef int
(__LZO_ENTRY *lzo_decompress_t) ( const lzo_byte *src, lzo_uint src_len,
lzo_byte *dst, lzo_uintp dst_len,
lzo_voidp wrkmem );
typedef int
(__LZO_ENTRY *lzo_optimize_t) ( lzo_byte *src, lzo_uint src_len,
lzo_byte *dst, lzo_uintp dst_len,
lzo_voidp wrkmem );
typedef int
(__LZO_ENTRY *lzo_compress_dict_t)(const lzo_byte *src, lzo_uint src_len,
lzo_byte *dst, lzo_uintp dst_len,
lzo_voidp wrkmem,
const lzo_byte *dict, lzo_uint dict_len );
typedef int
(__LZO_ENTRY *lzo_decompress_dict_t)(const lzo_byte *src, lzo_uint src_len,
lzo_byte *dst, lzo_uintp dst_len,
lzo_voidp wrkmem,
const lzo_byte *dict, lzo_uint dict_len );
/* assembler versions always use __cdecl */
typedef int
(__LZO_CDECL *lzo_compress_asm_t)( const lzo_byte *src, lzo_uint src_len,
lzo_byte *dst, lzo_uintp dst_len,
lzo_voidp wrkmem );
typedef int
(__LZO_CDECL *lzo_decompress_asm_t)( const lzo_byte *src, lzo_uint src_len,
lzo_byte *dst, lzo_uintp dst_len,
lzo_voidp wrkmem );
/* a progress indicator callback function */
typedef void (__LZO_ENTRY *lzo_progress_callback_t) (lzo_uint, lzo_uint);
/***********************************************************************
// export information
************************************************************************/
/* DLL export information */
#if !defined(__LZO_EXPORT1)
# define __LZO_EXPORT1
#endif
#if !defined(__LZO_EXPORT2)
# define __LZO_EXPORT2
#endif
/* exported calling convention for C functions */
#if !defined(LZO_PUBLIC)
# define LZO_PUBLIC(_rettype) \
__LZO_EXPORT1 _rettype __LZO_EXPORT2 __LZO_ENTRY
#endif
#if !defined(LZO_EXTERN)
# define LZO_EXTERN(_rettype) __LZO_EXTERN_C LZO_PUBLIC(_rettype)
#endif
#if !defined(LZO_PRIVATE)
# define LZO_PRIVATE(_rettype) static _rettype __LZO_ENTRY
#endif
/* exported __cdecl calling convention for assembler functions */
#if !defined(LZO_PUBLIC_CDECL)
# define LZO_PUBLIC_CDECL(_rettype) \
__LZO_EXPORT1 _rettype __LZO_EXPORT2 __LZO_CDECL
#endif
#if !defined(LZO_EXTERN_CDECL)
# define LZO_EXTERN_CDECL(_rettype) __LZO_EXTERN_C LZO_PUBLIC_CDECL(_rettype)
#endif
/* exported global variables (LZO currently uses no static variables and
* is fully thread safe) */
#if !defined(LZO_PUBLIC_VAR)
# define LZO_PUBLIC_VAR(_type) \
__LZO_EXPORT1 _type __LZO_EXPORT2 __LZO_DMODEL
#endif
#if !defined(LZO_EXTERN_VAR)
# define LZO_EXTERN_VAR(_type) extern LZO_PUBLIC_VAR(_type)
#endif
/***********************************************************************
// error codes and prototypes
************************************************************************/
/* Error codes for the compression/decompression functions. Negative
* values are errors, positive values will be used for special but
* normal events.
*/
#define LZO_E_OK 0
#define LZO_E_ERROR (-1)
#define LZO_E_OUT_OF_MEMORY (-2) /* not used right now */
#define LZO_E_NOT_COMPRESSIBLE (-3) /* not used right now */
#define LZO_E_INPUT_OVERRUN (-4)
#define LZO_E_OUTPUT_OVERRUN (-5)
#define LZO_E_LOOKBEHIND_OVERRUN (-6)
#define LZO_E_EOF_NOT_FOUND (-7)
#define LZO_E_INPUT_NOT_CONSUMED (-8)
/* lzo_init() should be the first function you call.
* Check the return code !
*
* lzo_init() is a macro to allow checking that the library and the
* compiler's view of various types are consistent.
*/
#define lzo_init() __lzo_init2(LZO_VERSION,(int)sizeof(short),(int)sizeof(int),\
(int)sizeof(long),(int)sizeof(lzo_uint32),(int)sizeof(lzo_uint),\
(int)lzo_sizeof_dict_t,(int)sizeof(char *),(int)sizeof(lzo_voidp),\
(int)sizeof(lzo_compress_t))
LZO_EXTERN(int) __lzo_init2(unsigned,int,int,int,int,int,int,int,int,int);
/* version functions (useful for shared libraries) */
LZO_EXTERN(unsigned) lzo_version(void);
LZO_EXTERN(const char *) lzo_version_string(void);
LZO_EXTERN(const char *) lzo_version_date(void);
LZO_EXTERN(const lzo_charp) _lzo_version_string(void);
LZO_EXTERN(const lzo_charp) _lzo_version_date(void);
/* string functions */
LZO_EXTERN(int)
lzo_memcmp(const lzo_voidp _s1, const lzo_voidp _s2, lzo_uint _len);
LZO_EXTERN(lzo_voidp)
lzo_memcpy(lzo_voidp _dest, const lzo_voidp _src, lzo_uint _len);
LZO_EXTERN(lzo_voidp)
lzo_memmove(lzo_voidp _dest, const lzo_voidp _src, lzo_uint _len);
LZO_EXTERN(lzo_voidp)
lzo_memset(lzo_voidp _s, int _c, lzo_uint _len);
/* checksum functions */
LZO_EXTERN(lzo_uint32)
lzo_adler32(lzo_uint32 _adler, const lzo_byte *_buf, lzo_uint _len);
LZO_EXTERN(lzo_uint32)
lzo_crc32(lzo_uint32 _c, const lzo_byte *_buf, lzo_uint _len);
/* misc. */
LZO_EXTERN(lzo_bool) lzo_assert(int _expr);
LZO_EXTERN(int) _lzo_config_check(void);
typedef union { lzo_bytep p; lzo_uint u; } __lzo_pu_u;
typedef union { lzo_bytep p; lzo_uint32 u32; } __lzo_pu32_u;
typedef union { void *vp; lzo_bytep bp; lzo_uint32 u32; long l; } lzo_align_t;
/* align a char pointer on a boundary that is a multiple of `size' */
LZO_EXTERN(unsigned) __lzo_align_gap(const lzo_voidp _ptr, lzo_uint _size);
#define LZO_PTR_ALIGN_UP(_ptr,_size) \
((_ptr) + (lzo_uint) __lzo_align_gap((const lzo_voidp)(_ptr),(lzo_uint)(_size)))
/* deprecated - only for backward compatibility */
#define LZO_ALIGN(_ptr,_size) LZO_PTR_ALIGN_UP(_ptr,_size)
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* already included */

View File

@@ -0,0 +1,30 @@
#include "stdafx.h"
#include "minilzo.h"
#include "miniLZOWrapper.h"
#if _MSC_VER >= 1300
#define THREAD_LOCAL_STORAGE __declspec(thread) static
#else
#define THREAD_LOCAL_STORAGE
#endif
bool CMiniLZO::CheckLZOUsable()
{
return LZO_E_OK == lzo_init();
}
bool CMiniLZO::Compress(const char* in, unsigned long in_len,
char* out, unsigned long* lp_out_len)
{
THREAD_LOCAL_STORAGE lzo_voidp wrkmem[LZO1X_1_MEM_COMPRESS];
return (LZO_E_OK == lzo1x_1_compress(reinterpret_cast<const lzo_byte*>(in), in_len,
reinterpret_cast<lzo_byte*>(out), reinterpret_cast<lzo_uintp>(lp_out_len), wrkmem));
}
bool CMiniLZO::Decompress(const char* in, unsigned long in_len,
char* out, unsigned long* buffersize_in_out_len)
{
return (LZO_E_OK == lzo1x_decompress_safe(reinterpret_cast<const lzo_byte*>(in), in_len,
reinterpret_cast<lzo_byte*>(out), reinterpret_cast<lzo_uintp>(buffersize_in_out_len), 0));
}

View File

@@ -0,0 +1,20 @@
#ifndef _MINI_LZO_WRAPPER_H_
#define _MINI_LZO_WRAPPER_H_
namespace CMiniLZO
{
bool CheckLZOUsable();
bool Compress(const char* in, unsigned long in_len,
char* out, unsigned long* lp_out_len);
bool Decompress(const char* in, unsigned long in_len,
char* out, unsigned long* buffersize_in_out_len);
inline unsigned long GetLeastCompressBuffer(unsigned long dwInputBlockSize)
{
return dwInputBlockSize + (dwInputBlockSize / 64) + 16 + 3;
}
};
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,100 @@
/* minilzo.h -- mini subset of the LZO real-time data compression library
This file is part of the LZO real-time data compression library.
Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer
All Rights Reserved.
The LZO library is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
The LZO library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the LZO library; see the file COPYING.
If not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Markus F.X.J. Oberhumer
<markus@oberhumer.com>
http://www.oberhumer.com/opensource/lzo/
*/
/*
* NOTE:
* the full LZO package can be found at
* http://www.oberhumer.com/opensource/lzo/
*/
#ifndef __MINILZO_H
#define __MINILZO_H
#define MINILZO_VERSION 0x1080
#ifdef __LZOCONF_H
# error "you cannot use both LZO and miniLZO"
#endif
#undef LZO_HAVE_CONFIG_H
#include "lzoconf.h"
#if !defined(LZO_VERSION) || (LZO_VERSION != MINILZO_VERSION)
# error "version mismatch in header files"
#endif
#ifdef __cplusplus
extern "C" {
#endif
/***********************************************************************
//
************************************************************************/
/* Memory required for the wrkmem parameter.
* When the required size is 0, you can also pass a NULL pointer.
*/
#define LZO1X_MEM_COMPRESS LZO1X_1_MEM_COMPRESS
#define LZO1X_1_MEM_COMPRESS ((lzo_uint32) (16384L * lzo_sizeof_dict_t))
#define LZO1X_MEM_DECOMPRESS (0)
/* compression */
LZO_EXTERN(int)
lzo1x_1_compress ( const lzo_byte *src, lzo_uint src_len,
lzo_byte *dst, lzo_uintp dst_len,
lzo_voidp wrkmem );
/* decompression */
LZO_EXTERN(int)
lzo1x_decompress ( const lzo_byte *src, lzo_uint src_len,
lzo_byte *dst, lzo_uintp dst_len,
lzo_voidp wrkmem /* NOT USED */ );
/* safe decompression with overrun testing */
LZO_EXTERN(int)
lzo1x_decompress_safe ( const lzo_byte *src, lzo_uint src_len,
lzo_byte *dst, lzo_uintp dst_len,
lzo_voidp wrkmem /* NOT USED */ );
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* already included */

View File

@@ -0,0 +1,70 @@
#pragma once
class CDLLModule
{
public:
CDLLModule() : m_hDLL(NULL)
{
}
virtual ~CDLLModule() //destructor, free the library
{
Release();
}
//////////////////////////////////////////////////////////////////
// See if dll been loaded, returning true dose not mean that all
// functions of the dll is valid.
BOOL IsLoaded(void)
{
return m_hDLL != NULL;
}
VOID Release()
{
if( m_hDLL )
::FreeLibrary( m_hDLL );
m_hDLL = NULL;
}
/////////////////////////////////////////////////////////
// pure virtual, must implemented in derived class
// used macros to generate the implementation
virtual BOOL Init( LPCTSTR szDll ) = 0;
protected:
HMODULE m_hDLL;
};
//////////////////////////////////////////////////////////////////////
// macros to implement the Init function
#define DECLARE_DLL_FUNCTION(ret, cc, func, params) \
ret (cc *func)params;
#define BEGIN_DLL_INIT() \
BOOL Init( LPCTSTR szDll ) \
{ \
if( m_hDLL ) \
::FreeLibrary( m_hDLL ); \
m_hDLL = ::LoadLibrary( szDll ); \
BOOL bOk = FALSE;
#define INIT_DLL_TWIN_FUNCTION(ret, cc, func, params, origin) \
if( m_hDLL ) { \
func = (ret (cc* )params) GetProcAddress( m_hDLL, origin ); \
} else \
func = NULL; \
if( func ) \
bOk = TRUE;
#define END_DLL_INIT() \
return bOk; \
}
#define INIT_DLL_FUNCTION(ret, cc, func, params) \
if( m_hDLL ) { \
func = (ret (cc* )params)GetProcAddress( m_hDLL, #func ); \
} else \
func = NULL; \
if( func ) \
bOk = TRUE;

View File

@@ -0,0 +1,21 @@
#ifndef _CUSTOM_DEBUG_MACROS_
#define _CUSTOM_DEBUG_MACROS_
#define _QUOTE(x) # x
#define QUOTE(x) _QUOTE(x)
#define __FILE__LINE__ __FILE__ "(" QUOTE(__LINE__) ") : "
#define NOTE(x) message(x)
#define FILE_LINE message(__FILE__LINE__)
#define TODO(x) message(__FILE__LINE__"\n"\
" -------------------------------------------------\n"\
"| TODO : " x "\n"\
" -------------------------------------------------\n")
#define FIXME(x) message(__FILE__LINE__"\n"\
" -------------------------------------------------\n"\
"| FIXME : " x "\n"\
" -------------------------------------------------\n")
#define todo(x) message(__FILE__LINE__" TODO : " x "\n")
#define fixme(x) message(__FILE__LINE__" FIXME : " x "\n")
#define note(x) message(__FILE__LINE__" NOTE : " x "\n")
#endif

View File

@@ -0,0 +1,82 @@
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <lmerr.h>
#include <stdlib.h>
#include <winsock2.h>
#include <windows.h>
#include "DebugUtils.h"
//
// Set application-name for prefix of log filename
//
void DbgUtils::SetProgramName(TCHAR* pszOutBuffer, int nBufferSize, TCHAR* pszProgramName)
{
if(0 == pszProgramName)
{
TCHAR szDrive[MAX_PATH], szDir[MAX_PATH], szFilename[MAX_PATH], szExt[MAX_PATH];
// Figure out what the report file will be named, and store it away
GetModuleFileName(0, pszOutBuffer, nBufferSize);
PTSTR pszDot = pszOutBuffer;
// Look for the '.' before the "EXE" extension. Replace '.' to '\0'
if((pszDot = _tcsrchr( pszDot, _T('.'))))
{
*pszDot = 0;
}
_tsplitpath(pszOutBuffer, szDrive, szDir, szFilename, szExt);
_tcsncpy(pszOutBuffer, szFilename, nBufferSize);
}
else
{
_tcsncpy(pszOutBuffer, pszProgramName, nBufferSize);
}
}
DbgUtils::CConvertErrorToText& DbgUtils::CConvertErrorToText::GetInstance()
{
static CConvertErrorToText convertErrorToText;
return convertErrorToText;
}
DbgUtils::CConvertErrorToText::CConvertErrorToText()
: m_hNetMsg(LoadLibraryEx(TEXT("netmsg.dll"), NULL, LOAD_LIBRARY_AS_DATAFILE))
{
}
DbgUtils::CConvertErrorToText::~CConvertErrorToText()
{
if(0 != m_hNetMsg)
{
FreeLibrary(m_hNetMsg);
}
}
unsigned long DbgUtils::CConvertErrorToText::GetErrorTextBuffer(TCHAR* lpMessage,
unsigned long dwBufferLen,
unsigned long dwLastError)
{
unsigned long dwFormatFlags = FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM;
LPCVOID lpModule = 0;
if (dwLastError >= NERR_BASE && dwLastError <= MAX_NERR && 0 != m_hNetMsg)
{
lpModule = m_hNetMsg;
dwFormatFlags |= FORMAT_MESSAGE_FROM_HMODULE;
}
return FormatMessage(dwFormatFlags, lpModule, dwLastError,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), lpMessage, dwBufferLen, 0);
}

View File

@@ -0,0 +1,29 @@
#ifndef _DEBUG_UTILS_H_
#define _DEBUG_UTILS_H_
#include <tchar.h>
namespace DbgUtils
{
class CConvertErrorToText;
void SetProgramName(TCHAR* pszOutBuffer, int nBufferSize, TCHAR* pszProgamName = 0);
};
class DbgUtils::CConvertErrorToText
{
public:
unsigned long GetErrorTextBuffer(TCHAR* lpMessage,
unsigned long dwBufferLen, unsigned long dwLastError);
static CConvertErrorToText& GetInstance();
private:
CConvertErrorToText();
~CConvertErrorToText();
HMODULE m_hNetMsg;
};
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,174 @@
#pragma once
#include <dbghelp.h>
#include <cstdio>
#include "DLLModule.h"
#pragma comment(lib, "dbghelp.lib")
class CDBGFuncClass : public CDLLModule
{
public :
DECLARE_DLL_FUNCTION( BOOL, WINAPI, MiniDumpWriteDump, ( HANDLE, unsigned long, HANDLE, MINIDUMP_TYPE, CONST PMINIDUMP_EXCEPTION_INFORMATION, CONST PMINIDUMP_USER_STREAM_INFORMATION, CONST PMINIDUMP_CALLBACK_INFORMATION ) )
DECLARE_DLL_FUNCTION( BOOL, WINAPI, SymEnumSymbols, ( HANDLE, ULONG64, PCSTR, PSYM_ENUMERATESYMBOLS_CALLBACK, PVOID ) )
DECLARE_DLL_FUNCTION( ULONG, WINAPI, SymSetContext, ( HANDLE, PIMAGEHLP_STACK_FRAME, PIMAGEHLP_CONTEXT ) )
DECLARE_DLL_FUNCTION( BOOL, WINAPI, SymFromAddr, ( HANDLE, DWORD64, PDWORD64, PSYMBOL_INFO ) )
DECLARE_DLL_FUNCTION( BOOL, WINAPI, StackWalk, ( unsigned long, HANDLE, HANDLE, LPSTACKFRAME, PVOID, PREAD_PROCESS_MEMORY_ROUTINE, PFUNCTION_TABLE_ACCESS_ROUTINE, PGET_MODULE_BASE_ROUTINE, PTRANSLATE_ADDRESS_ROUTINE ) )
// DECLARE_DLL_FUNCTION( BOOL, WINAPI, StackWalk64, ( unsigned long, HANDLE, HANDLE, LPSTACKFRAME64, PVOID, PREAD_PROCESS_MEMORY_ROUTINE64, PFUNCTION_TABLE_ACCESS_ROUTINE64, PGET_MODULE_BASE_ROUTINE64, PTRANSLATE_ADDRESS_ROUTINE64 ) )
DECLARE_DLL_FUNCTION( BOOL, WINAPI, SymGetLineFromAddr, ( HANDLE, unsigned long, PDWORD, PIMAGEHLP_LINE ) ) // ImageHlp
DECLARE_DLL_FUNCTION( BOOL, WINAPI, SymGetLineFromAddr64, ( HANDLE, DWORD64, PDWORD, PIMAGEHLP_LINE64 ) )
DECLARE_DLL_FUNCTION( PVOID, WINAPI, SymFunctionTableAccess, ( HANDLE, unsigned long ) ) // ImageHlp
// DECLARE_DLL_FUNCTION( PVOID, WINAPI, SymFunctionTableAccess64, ( HANDLE, DWORD64 ) )
DECLARE_DLL_FUNCTION( DWORD64,WINAPI, SymGetModuleBase64, ( HANDLE, DWORD64 ) )
DECLARE_DLL_FUNCTION( BOOL, WINAPI, SymInitialize, ( HANDLE, PSTR, BOOL ) )
DECLARE_DLL_FUNCTION( unsigned long, WINAPI, SymSetOptions, ( unsigned long ) )
DECLARE_DLL_FUNCTION( BOOL, WINAPI, SymCleanup, ( HANDLE ) )
DECLARE_DLL_FUNCTION( unsigned long, WINAPI, SymGetModuleBase, ( HANDLE, unsigned long ) )
// DECLARE_DLL_FUNCTION( DWORD64,WINAPI, SymGetModuleBase64, ( HANDLE, DWORD64 ) )
DECLARE_DLL_FUNCTION( BOOL, WINAPI, SymGetTypeInfo, ( HANDLE, DWORD64, ULONG, IMAGEHLP_SYMBOL_TYPE_INFO, PVOID ) )
public:
BEGIN_DLL_INIT()
INIT_DLL_FUNCTION( BOOL, WINAPI, MiniDumpWriteDump, ( HANDLE, unsigned long, HANDLE, MINIDUMP_TYPE, CONST PMINIDUMP_EXCEPTION_INFORMATION, CONST PMINIDUMP_USER_STREAM_INFORMATION, CONST PMINIDUMP_CALLBACK_INFORMATION ) )
INIT_DLL_FUNCTION( BOOL, WINAPI, SymEnumSymbols, ( HANDLE, ULONG64, PCSTR, PSYM_ENUMERATESYMBOLS_CALLBACK, PVOID ) )
INIT_DLL_FUNCTION( ULONG, WINAPI, SymSetContext, ( HANDLE, PIMAGEHLP_STACK_FRAME, PIMAGEHLP_CONTEXT ) )
INIT_DLL_FUNCTION( BOOL, WINAPI, SymFromAddr, ( HANDLE, DWORD64, PDWORD64, PSYMBOL_INFO ) )
INIT_DLL_FUNCTION( BOOL, WINAPI, StackWalk, ( unsigned long, HANDLE, HANDLE, LPSTACKFRAME, PVOID, PREAD_PROCESS_MEMORY_ROUTINE, PFUNCTION_TABLE_ACCESS_ROUTINE, PGET_MODULE_BASE_ROUTINE, PTRANSLATE_ADDRESS_ROUTINE ) )
// INIT_DLL_FUNCTION( BOOL, WINAPI, StackWalk64, ( unsigned long, HANDLE, HANDLE, LPSTACKFRAME64, PVOID, PREAD_PROCESS_MEMORY_ROUTINE64, PFUNCTION_TABLE_ACCESS_ROUTINE64, PGET_MODULE_BASE_ROUTINE64, PTRANSLATE_ADDRESS_ROUTINE64 ) )
INIT_DLL_FUNCTION( BOOL, WINAPI, SymGetLineFromAddr, ( HANDLE, unsigned long, PDWORD, PIMAGEHLP_LINE ) ) // ImageHlp
INIT_DLL_FUNCTION( BOOL, WINAPI, SymGetLineFromAddr64, ( HANDLE, DWORD64, PDWORD, PIMAGEHLP_LINE64 ) )
INIT_DLL_FUNCTION( PVOID, WINAPI, SymFunctionTableAccess, ( HANDLE, unsigned long ) )
// INIT_DLL_FUNCTION( PVOID, WINAPI, SymFunctionTableAccess64, ( HANDLE, DWORD64 ) )
INIT_DLL_FUNCTION( DWORD64,WINAPI, SymGetModuleBase64, ( HANDLE, DWORD64 ) )
INIT_DLL_FUNCTION( BOOL, WINAPI, SymInitialize, ( HANDLE, PSTR, BOOL ) )
INIT_DLL_FUNCTION( unsigned long, WINAPI, SymSetOptions, ( unsigned long ) )
INIT_DLL_FUNCTION( BOOL, WINAPI, SymCleanup, ( HANDLE ) )
INIT_DLL_FUNCTION( unsigned long, WINAPI, SymGetModuleBase, ( HANDLE, unsigned long ) )
// INIT_DLL_FUNCTION( DWORD64,WINAPI, SymGetModuleBase64, ( HANDLE, DWORD64 ) )
INIT_DLL_FUNCTION( BOOL, WINAPI, SymGetTypeInfo, ( HANDLE, DWORD64, ULONG, IMAGEHLP_SYMBOL_TYPE_INFO, PVOID ) )
END_DLL_INIT()
};
enum BasicType // Stolen from CVCONST.H in the DIA 2.0 SDK
{
btNoType = 0,
btVoid = 1,
btChar = 2,
btWChar = 3,
btInt = 6,
btUInt = 7,
btFloat = 8,
btBCD = 9,
btBool = 10,
btLong = 13,
btULong = 14,
btCurrency = 25,
btDate = 26,
btVariant = 27,
btComplex = 28,
btBit = 29,
btBSTR = 30,
btHresult = 31
};
class CExceptionReport
{
public:
static CExceptionReport& GetInstance();
typedef int (WINAPI *UserFunc)(TCHAR* szBuffer, const int nBufferSize);
enum Features
{
CATCH_EXCEPTION = (1 << 0),
USE_MINIDUMP = (1 << 1),
USE_REPORT = (1 << 2)
};
void Enable(unsigned long dwEnableFeature);
void Disable(unsigned long dwDisableFeature);
void SetDumpLevel(MINIDUMP_TYPE eMiniDumpType) { m_eMiniDumpType = eMiniDumpType; }
void SetUserFunc(UserFunc lpUserFunc) { m_lpUserFunc = lpUserFunc; }
void WriteExceptionReport(PEXCEPTION_POINTERS pExceptionInfo);
static void SetProgramName(TCHAR* pszOutBuffer, int nBufferSize, TCHAR* pszProgramName);
static int WriteBasicInfo(TCHAR* szBuffer_Out, const int nBufferSize, PEXCEPTION_RECORD pExceptionRecord);
static int WriteRegistersInfo(TCHAR* szBuffer_Out, const int nBufferSize, PCONTEXT pContext);
static int WriteMemoryDump(TCHAR* szBuffer_Out, const int nBufferSize, PCONTEXT pContext,
unsigned int nMaxIPDump = 16, unsigned int nMaxStackDump = 1024);
static int WriteStackDetails(TCHAR* szBuffer_Out, const int nBufferSize,
PCONTEXT pContext, BOOL bWriteVariables, BOOL& bHasSymbol_Out, const int nStackDepth = 256);
static int Dump(TCHAR* szBuffer_Out, const int nBufferSize,
DWORD64 pData, unsigned long dwSize, BOOL bAlign);
CDBGFuncClass& GetDBGFuncClass() { return m_DBGHELP; }
private:
CExceptionReport();
~CExceptionReport();
void CloseLogFile();
LONG ProcessException(PEXCEPTION_POINTERS lpExceptionInfo);
LONG ProcessSecondException(PEXCEPTION_POINTERS lpExceptionInfo);
static LONG WINAPI UnhandledExceptionFilter(PEXCEPTION_POINTERS lpExceptionInfo) { return CExceptionReport::GetInstance().ProcessException(lpExceptionInfo); }
static LONG WINAPI UnhandledSecondExceptionFilter(PEXCEPTION_POINTERS lpExceptionInfo) { return CExceptionReport::GetInstance().ProcessSecondException(lpExceptionInfo); }
static void StoreCoreDump(void);
static LPTSTR GetExceptionString( unsigned long dwCode );
static BOOL GetLogicalAddress(PVOID addr, PTSTR szModule, unsigned long len, unsigned long& section, unsigned long& offset );
static BOOL CALLBACK EnumerateSymbolsCallback(PSYMBOL_INFO,ULONG, PVOID);
static BOOL FormatSymbolValue(PSYMBOL_INFO, STACKFRAME *, TCHAR * pszBuffer, unsigned nBufferSize);
static int DumpTypeIndex(TCHAR* szBuffer_Out,
const int nBufferSize, DWORD64 modBase, unsigned long dwTypeIndex,
unsigned int nestingLevel, DWORD_PTR offset, BOOL & bHandled);
static int FormatOutputValue(TCHAR* pszCurrBuffer,
const int nBufferSize, BasicType basicType, DWORD64 length, PVOID pAddress);
static BasicType GetBasicType(unsigned long typeIndex, DWORD64 modBase);
// ---------------------------------------------------------------------
// Data
enum
{
SHIFT_NUM = 4,
BYTES_PER_LINE = 16,
MAX_TEMP_VALUE = 5,
MAX_LOG_BUFFER = 65535 // 64-kb log buffer
};
CDBGFuncClass m_DBGHELP;
UserFunc m_lpUserFunc;
LPTOP_LEVEL_EXCEPTION_FILTER m_OldFilter;
TCHAR m_szLogPrefixName[MAX_PATH];
TCHAR m_szModuleName[MAX_PATH];
TCHAR m_szTempBuffer[MAX_PATH];
TCHAR m_szLogBuffer[MAX_LOG_BUFFER];
CONTEXT m_tempContext;
SYSTEMTIME m_tempSystemTime;
MINIDUMP_EXCEPTION_INFORMATION m_miniDumpInfo;
FILE* m_logFile;
BOOL m_bHasSymbol;
unsigned long m_dwFeaturesFlag;
MINIDUMP_TYPE m_eMiniDumpType;
};

View File

@@ -0,0 +1,194 @@
#include "stdafx.h"
#include <utility>
#include <algorithm>
#include <functional>
#include "DebugUtils.h"
#include "PerformanceCheck.h"
CPerformanceCheck& CPerformanceCheck::GetInstance()
{
static CPerformanceCheck performanceCheck;
return performanceCheck;
}
CPerformanceCheck::CPerformanceCheck()
: m_fnPreFix(0), m_fnPostFix(0)
{
ClockPerSec(m_Frequency, Frequency);
m_fFrequency = static_cast<double>(m_Frequency.QuadPart);
}
CPerformanceCheck::~CPerformanceCheck()
{
PerformanceCheckLock::Syncronize sync(m_TableLock);
m_InstrumentTable.clear();
}
void CPerformanceCheck::SetUserMessageFunc(FnPrintUserMessage fnPreFix, FnPrintUserMessage fnPostFix)
{
m_fnPreFix = fnPreFix;
m_fnPostFix = fnPostFix;
}
inline unsigned long perf_sdbmHash(const unsigned char *str)
{
unsigned long hash = 0;
int c;
while (c = *str++) { hash = c + (hash << 6) + (hash << 16) - hash; }
return hash;
}
void CPerformanceCheck::AddTime(const char* szfunctionName, double fEstimateTime)
{
unsigned long dwHashedKey = perf_sdbmHash(reinterpret_cast<const unsigned char*>(szfunctionName));
PerformanceCheckLock::Syncronize sync(m_TableLock);
fEstimateTime /= m_fFrequency;
std::pair<PerformanceTable::iterator, PerformanceTable::iterator> itrPair =
m_InstrumentTable.equal_range(dwHashedKey);
for(;itrPair.first != itrPair.second; ++itrPair.first)
{
Instrument& instrument = itrPair.first->second;
if(0 == strcmp(szfunctionName, instrument.m_szFunctionName))
{
// <20><><EFBFBD>̺<EFBFBD><CCBA><EFBFBD><EFBFBD><EFBFBD> ã<><C3A3> <20><><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD> <20><><EFBFBD>Ѵ<EFBFBD>.
instrument.m_fProcessTime += fEstimateTime;
if(instrument.m_fMinTime > fEstimateTime) { instrument.m_fMinTime = fEstimateTime; }
if(instrument.m_fMaxTime < fEstimateTime) { instrument.m_fMaxTime = fEstimateTime; }
++instrument.m_dwCalled;
return;
}
}
// <20><><EFBFBD>̺<EFBFBD><CCBA><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʴ<EFBFBD> <20><><EFBFBD><EFBFBD>, <20>о<EFBFBD> <20>ִ´<D6B4>.
m_InstrumentTable.insert(std::make_pair(dwHashedKey, Instrument(dwHashedKey, fEstimateTime, szfunctionName)));
}
bool CPerformanceCheck::PrintAllTime(const char* fileName, bool bReset)
{
if(m_InstrumentTable.empty())
{
return false;
}
char strLogPath[MAX_PATH];
char strLogFileName[MAX_PATH];
DbgUtils::SetProgramName(strLogPath, MAX_PATH, 0);
// create the directory if it doesn't exist
if (INVALID_FILE_ATTRIBUTES == GetFileAttributes(strLogPath))
{
if (!CreateDirectory(strLogPath, 0))
{
return false;
}
}
// create log file name in good order
unsigned long dwSpinCount = 0;
unsigned long dwMaxFileSize = 50 * 1024 * 1024;
while(true)
{
_sntprintf(strLogFileName, MAX_PATH, "%s/PerformanceLog-%s-%05d.log",
strLogPath, fileName, dwSpinCount);
HANDLE hLogFile = CreateFile(strLogFileName, GENERIC_WRITE,
FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 );
if(INVALID_HANDLE_VALUE == hLogFile)
{
break;
}
else
{
unsigned long dwHighValue = 0;
unsigned long dwFileSize = GetFileSize(hLogFile, &dwHighValue);
CloseHandle(hLogFile);
if(dwHighValue == 0 && dwFileSize < dwMaxFileSize)
{
break;
}
}
++dwSpinCount;
}
// create log file
PerformanceCheckLock::Syncronize sync(m_TableLock);
FILE* logFile = fopen(strLogFileName, "at");
if(0 == logFile)
{
return false;
}
if(0 != m_fnPreFix)
{
m_fnPreFix(logFile);
}
fprintf(logFile,
" Average : Minimum : Maximum : Total : # : Profile Name\n"
"------------------------------------------------------------------------------------------------\n" );
double fTotalAvgTime = 0;
PerformanceTable::iterator pos;
PerformanceTable::iterator end;
for(pos = m_InstrumentTable.begin(),
end = m_InstrumentTable.end();
pos != end; ++pos)
{
const Instrument& instrument = pos->second;
if(0 == instrument.m_szFunctionName)
{
continue;
}
const double fAvgTime = (0.0f == instrument.m_fProcessTime) ?
0.0f : (instrument.m_fProcessTime / instrument.m_dwCalled); // Average
fTotalAvgTime += fAvgTime;
fprintf(logFile, " %3.6f %3.6f %3.6f %8.1f %10d %s\n",
fAvgTime, instrument.m_fMinTime, instrument.m_fMaxTime,
instrument.m_fProcessTime, instrument.m_dwCalled, instrument.m_szFunctionName);
}
fprintf(logFile, "\n\n Total AvgTime : %3.6f\n\n\n", fTotalAvgTime);
if(0 != m_fnPostFix)
{
m_fnPostFix(logFile);
}
fclose(logFile);
if(bReset)
{
for(pos = m_InstrumentTable.begin(),
end = m_InstrumentTable.end();
pos != end; ++pos)
{
pos->second.Initialize();
}
}
return true;
}

View File

@@ -0,0 +1,196 @@
#ifndef _FUNCTION_PERFORMANCE_CHECK_H_
#define _FUNCTION_PERFORMANCE_CHECK_H_
#include <winsock2.h>
#include <windows.h>
#include <map>
#include "../../Thread/Lock.h"
#include "../../Pattern/Singleton.h"
#define _USING_REALCLOCK
#if defined(_USING_REALCLOCK) && _M_IX86 >= 500
#define RealClock(Large_Integer_In) \
{ __asm rdtsc __asm mov Large_Integer_In.HighPart, edx __asm mov Large_Integer_In.LowPart, eax }
#define ClockSnapShot(Large_Integer_Out, UniqueVariableName) \
LARGE_INTEGER SnapShot##UniqueVariableName; \
RealClock(SnapShot##UniqueVariableName); \
Large_Integer_Out = SnapShot##UniqueVariableName
#define ClockPerSec(Large_Integer_Frequency_Out, UniqueVariableName) \
LARGE_INTEGER Start##UniqueVariableName, Stop##UniqueVariableName; \
RealClock(Start##UniqueVariableName) \
Sleep(1000); \
RealClock(Stop##UniqueVariableName) \
Large_Integer_Frequency_Out.QuadPart = \
Stop##UniqueVariableName.QuadPart - Start##UniqueVariableName.QuadPart - 57UL
#else
#define ClockSnapShot(Large_Integer_Out, UniqueVariableName) \
QueryPerformanceCounter(&Large_Integer_Out)
#define ClockPerSec(Large_Integer_Frequency_Out, UniqueVariableName) \
QueryPerformanceFrequency(&Large_Integer_Frequency_Out)
#endif
// ------------------------------------------------------------------------------------------------
// <20><> <20>Լ<EFBFBD><D4BC><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD>.
// identifiler<65><72> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ԵǹǷ<C7B9>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>Ģ<EFBFBD><C4A2> <20><><EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD> <20><> <20><>.
// blockName<6D><65> <20>ݵ<EFBFBD><DDB5><EFBFBD> <20><><EFBFBD>ڿ<EFBFBD> <20><><EFBFBD>ͷ<EFBFBD><CDB7><EFBFBD> <20><> <20><>.
#define DeclareBlockTimingCheck(blockName, identifiler) \
CPerformanceInstrument blockInstrument##identifiler(blockName);
#define BlockTimingCheckStart(identifiler) \
blockInstrument##identifiler.Start();
#define BlockTimingCheckStop(identifiler) \
blockInstrument##identifiler.Stop();
// ------------------------------------------------------------------------------------------------
// <20><> <20>Լ<EFBFBD><D4BC><EFBFBD><EFBFBD><EFBFBD> <20>Ѱ<EFBFBD><D1B0><EFBFBD> <20><> <20><> <20><><EFBFBD><EFBFBD>.
#define FunctionTimingCheck \
CPerformanceInstrument functionInstrument(__FUNCTION__); \
CAutoInstrument autofunctionInstrument(functionInstrument);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>Ϸ<EFBFBD> <20><><EFBFBD><EFBFBD>. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ʱ<EFBFBD>ȭ<EFBFBD>Ѵ<EFBFBD>.
#define GetFunctionTimingResult(fileName) \
CPerformanceCheck::GetInstance().PrintAllTime(fileName);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>Ϸ<EFBFBD> <20><><EFBFBD><EFBFBD>. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʱ<EFBFBD>ȭ<EFBFBD><C8AD><EFBFBD><EFBFBD> <20>ʴ´<CAB4>.
#define GetFunctionTimingResultNoReset(fileName) \
CPerformanceCheck::GetInstance().PrintAllTime(fileName, false);
class CPerformanceCheck
{
public:
static CPerformanceCheck& GetInstance();
typedef void (*FnPrintUserMessage) (FILE* fDescriptor);
void SetUserMessageFunc(FnPrintUserMessage fnPreFix = 0, FnPrintUserMessage fnPostFix = 0);
void AddTime(const char* szfunctionName, double fEstimateTime);
bool PrintAllTime(const char* fileName, bool bReset = true);
private:
CPerformanceCheck();
~CPerformanceCheck();
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
struct Instrument
{
double m_fProcessTime;
double m_fMinTime;
double m_fMaxTime;
unsigned long m_dwHashKey;
unsigned long m_dwCalled;
const char* m_szFunctionName;
Instrument(unsigned long dwHashKey, double fProcessTime, const char* szFunctionName)
: m_dwHashKey(dwHashKey), m_fProcessTime(fProcessTime), m_dwCalled(1),
m_fMinTime(fProcessTime), m_fMaxTime(fProcessTime),
m_szFunctionName(szFunctionName) { }
Instrument()
: m_fProcessTime(0.0f), m_fMinTime(0.0f), m_fMaxTime(0.0f),
m_dwCalled(1), m_dwHashKey(0),
m_szFunctionName(NULL) { }
void Initialize()
{
m_fProcessTime = m_fMinTime = m_fMaxTime = 0.0f;
m_dwCalled = 0;
}
};
typedef CCSLock PerformanceCheckLock;
typedef std::multimap<unsigned long, Instrument> PerformanceTable;
PerformanceCheckLock m_TableLock;
CACHE_PAD(PerformanceCheckLockPad, sizeof(PerformanceCheckLock));
LARGE_INTEGER m_Frequency;
double m_fFrequency;
PerformanceTable m_InstrumentTable;
FnPrintUserMessage m_fnPreFix;
FnPrintUserMessage m_fnPostFix;
};
class CPerformanceInstrument
{
public:
CPerformanceInstrument(char* szfunctionName)
: m_szfunctionName(szfunctionName)
{
m_startTime.QuadPart = 0;
CPerformanceCheck::GetInstance().AddTime(m_szfunctionName, 0);
}
CPerformanceInstrument()
: m_szfunctionName(0)
{
m_startTime.QuadPart = 0;
}
void SetName(char* szfunctionName) { m_szfunctionName = szfunctionName; }
~CPerformanceInstrument() { }
inline void Start();
inline void Stop();
private:
LARGE_INTEGER m_startTime;
LARGE_INTEGER m_stopTime;
char* m_szfunctionName;
};
inline void CPerformanceInstrument::Start()
{
m_stopTime.QuadPart = 0;
ClockSnapShot(m_startTime, startTime);
}
inline void CPerformanceInstrument::Stop()
{
ClockSnapShot(m_stopTime, stopTime);
if(0 == m_stopTime.QuadPart) { ++m_stopTime.QuadPart; }
CPerformanceCheck::GetInstance().AddTime(m_szfunctionName,
static_cast<double>(m_stopTime.QuadPart - m_startTime.QuadPart));
}
class CAutoInstrument
{
public:
CAutoInstrument(CPerformanceInstrument& PerformanceInstrument)
: m_PerformanceInstrument(PerformanceInstrument) { m_PerformanceInstrument.Start(); }
~CAutoInstrument() { m_PerformanceInstrument.Stop(); }
private:
CPerformanceInstrument& m_PerformanceInstrument;
};
#endif

View File

@@ -0,0 +1,192 @@
#include "stdafx.h"
#include "MappedFile.h"
CMemoryMappedFile::CMemoryMappedFile()
: m_hFile(INVALID_HANDLE_VALUE), m_hMap(0)
{
}
CMemoryMappedFile::~CMemoryMappedFile()
{
Close();
}
bool CMemoryMappedFile::OpenFile(const char* szFileName, OpenMode eOpenMode)
{
DWORD dwOpenMode = 0;
DWORD dwShareMode = 0;
DWORD dwProtect = 0;
switch(eOpenMode)
{
case READ:
dwOpenMode = GENERIC_READ;
dwShareMode = FILE_SHARE_READ;
dwProtect = PAGE_READONLY;
m_dwFileViewMode = FILE_MAP_READ;
break;
case READ_WRITE:
dwOpenMode = GENERIC_READ | GENERIC_WRITE;
dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
dwProtect = PAGE_READWRITE;
m_dwFileViewMode = FILE_MAP_WRITE;
break;
};
Close();
m_hFile = CreateFile(szFileName, dwOpenMode,
dwShareMode, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
if(INVALID_HANDLE_VALUE != m_hFile)
{
m_hMap = CreateFileMapping(m_hFile, 0, dwProtect, 0, 0, 0);
if(NULL != m_hMap)
{
return true;
}
else
{
CloseHandle(m_hFile);
m_hFile = INVALID_HANDLE_VALUE;
}
}
return false;
}
// <20>޸𸮿<DEB8> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϰų<CFB0> <20><><EFBFBD><EFBFBD>.
bool CMemoryMappedFile::CreateSharedMemory(DWORD dwLowSize, DWORD dwHighSize, const char* szFileName)
{
Close();
m_hMap = CreateFileMapping(INVALID_HANDLE_VALUE, 0,
PAGE_READWRITE, dwHighSize, dwLowSize, szFileName);
return (0 != m_hMap);
}
bool CMemoryMappedFile::OpenSharedMemory(const char* szFileName, OpenMode eOpenMode)
{
Close();
switch(eOpenMode)
{
case READ:
m_dwFileViewMode = FILE_MAP_READ;
break;
case READ_WRITE:
m_dwFileViewMode = FILE_MAP_WRITE;
break;
};
m_hMap = OpenFileMapping(m_dwFileViewMode, FALSE, szFileName);
return (0 != m_hMap);
}
void CMemoryMappedFile::Close()
{
if(0 != m_hMap)
{
CloseHandle(m_hMap);
m_hMap = 0;
}
if(INVALID_HANDLE_VALUE != m_hFile)
{
CloseHandle(m_hFile);
m_hFile = INVALID_HANDLE_VALUE;
}
}
bool CMemoryMappedFile::IsOpen()
{
return (0 != m_hMap);
}
void* CMemoryMappedFile::GetFileView(DWORD dwLowPosition,
DWORD dwHighPosition,
DWORD dwMappingSize)
{
return MapViewOfFileEx(m_hMap, m_dwFileViewMode,
dwHighPosition, dwLowPosition, dwMappingSize, 0);
}
inline bool CMemoryMappedFile::CloseFileView(void* lpView)
{
if(0 != lpView)
{
return (TRUE == UnmapViewOfFile(lpView));
}
return false;
}
inline bool CMemoryMappedFile::FlushFileView(void* lpView, DWORD dwBytesToFlush)
{
return (TRUE == FlushViewOfFile(lpView, dwBytesToFlush));
}
bool CMemoryMappedFile::GetFileSize(unsigned long& dwLowSize, unsigned long& dwHighSize)
{
if(INVALID_HANDLE_VALUE != m_hFile)
{
dwLowSize = ::GetFileSize(m_hFile, &dwHighSize);
return true;
}
return false;
}
CFileMappedView::CFileMappedView(CMemoryMappedFile& mappedFile)
: m_MappedFile(mappedFile), m_FilePointer(0)
{
}
CFileMappedView::~CFileMappedView()
{
Close();
}
void* CFileMappedView::GetPointer(DWORD dwLowPosition,
DWORD dwHighPosition,
DWORD dwMappingSize)
{
Close();
m_FilePointer = m_MappedFile.GetFileView(
dwLowPosition, dwHighPosition, dwMappingSize);
return m_FilePointer;
}
void CFileMappedView::Flush(DWORD dwBytesToFlush)
{
m_MappedFile.FlushFileView(m_FilePointer, dwBytesToFlush);
}
void CFileMappedView::Close()
{
m_MappedFile.CloseFileView(m_FilePointer);
m_FilePointer = 0;
}

View File

@@ -0,0 +1,74 @@
#ifndef _GAMA_NETWORKLIB_MEMORY_MAPPED_FILE_
#define _GAMA_NETWORKLIB_MEMORY_MAPPED_FILE_
#include <winsock2.h>
#include <windows.h>
// forward decl
class CMemoryMappedFile;
class CFileMappedView
{
public:
CFileMappedView(CMemoryMappedFile& mappedFile);
~CFileMappedView();
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ؼ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>͸<EFBFBD> <20><><EFBFBD><EFBFBD> <20>´<EFBFBD>.
void* GetPointer(DWORD dwLowPosition = 0,
DWORD dwHighPosition = 0, DWORD dwMappingSize = 0);
void Flush(DWORD dwBytesToFlush = 0); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> Flush<73>Ѵ<EFBFBD>. (IPC<50><43><EFBFBD><EFBFBD> <20>ʿ<EFBFBD>)
void Close(); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ݴ´<DDB4>.
private:
CMemoryMappedFile& m_MappedFile;
void* m_FilePointer;
};
class CMemoryMappedFile
{
public:
enum OpenMode
{
READ,
READ_WRITE
};
CMemoryMappedFile();
~CMemoryMappedFile();
// <20>̹<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
bool OpenFile(const char* szFileName, OpenMode eOpenMode);
// <20>޸𸮿<DEB8> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϰų<CFB0> <20><><EFBFBD><EFBFBD>.
bool CreateSharedMemory(DWORD dwLowSize, DWORD dwHighSize = 0, const char* szFileName = 0);
bool OpenSharedMemory(const char* szFileName, OpenMode eOpenMode);
bool IsOpen(); // <20>̹<EFBFBD> <20><><EFBFBD><EFBFBD> <20>ִ<EFBFBD><D6B4><EFBFBD> <20><><EFBFBD>ɴ<EFBFBD>.
void Close(); // <20><><EFBFBD><EFBFBD> <20>ִ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ݴ´<DDB4>.
// <20><><EFBFBD><EFBFBD> <20>ִ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD≯<EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ũ<><20>ش<EFBFBD>.
bool GetFileSize(unsigned long& dwLowSize, unsigned long& dwHighSize);
private:
// <20><><EFBFBD><EFBFBD> <20><20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
void* GetFileView(DWORD dwLowPosition,
DWORD dwHighPosition = 0, DWORD dwMappingSize = 0);
static bool FlushFileView(void* lpView, DWORD dwBytesToFlush); // <20><><EFBFBD><EFBFBD> <20>並 Flush<73>Ѵ<EFBFBD>.
static bool CloseFileView(void* lpView); // <20><><EFBFBD><EFBFBD> <20><20>ݴ´<DDB4>.
HANDLE m_hFile;
HANDLE m_hMap;
DWORD m_dwFileViewMode;
friend class CFileMappedView;
};
#endif

View File

@@ -0,0 +1,220 @@
#ifndef _MATH_CONVERT_INLINE_H_
#define _MATH_CONVERT_INLINE_H_
#include <cstdlib>
#include <tchar.h>
inline void Math::Convert::Hex08ToStr( TCHAR *szDest, BYTE hex )
{
*((WORD *) szDest) = m_FastHeToBi[ hex ]; szDest += 2;
*(szDest) = '\0';
}
inline void Math::Convert::Hex16ToStr( TCHAR *szDest, WORD hex )
{
LPBYTE pSrc = (LPBYTE) &hex;
#ifdef BIG_ENDIAN
*((WORD *) (szDest + 0)) = m_FastHeToBi[ *(pSrc++) ];
*((WORD *) (szDest + 2)) = m_FastHeToBi[ *(pSrc++) ];
#else
*((WORD *) (szDest + 2)) = m_FastHeToBi[ *(pSrc++) ];
*((WORD *) (szDest + 0)) = m_FastHeToBi[ *(pSrc++) ];
#endif
*(szDest + 4) = '\0';
}
inline void Math::Convert::Hex32ToStr( TCHAR *szDest, unsigned long hex )
{
LPBYTE pSrc = (LPBYTE) &hex;
#ifdef BIG_ENDIAN
*((WORD *) (szDest + 0)) = m_FastHeToBi[ *(pSrc++) ];
*((WORD *) (szDest + 2)) = m_FastHeToBi[ *(pSrc++) ];
*((WORD *) (szDest + 4)) = m_FastHeToBi[ *(pSrc++) ];
*((WORD *) (szDest + 6)) = m_FastHeToBi[ *(pSrc++) ];
#else
*((WORD *) (szDest + 6)) = m_FastHeToBi[ *(pSrc++) ];
*((WORD *) (szDest + 4)) = m_FastHeToBi[ *(pSrc++) ];
*((WORD *) (szDest + 2)) = m_FastHeToBi[ *(pSrc++) ];
*((WORD *) (szDest + 0)) = m_FastHeToBi[ *(pSrc++) ];
#endif
*(szDest + 8) = '\0';
}
inline void Math::Convert::Hex64ToStr( TCHAR *szDest, DWORD64 hex )
{
LPBYTE pSrc = (LPBYTE) &hex;
#ifdef BIG_ENDIAN
*((WORD *) (szDest + 0)) = m_FastHeToBi[ *(pSrc++) ];
*((WORD *) (szDest + 2)) = m_FastHeToBi[ *(pSrc++) ];
*((WORD *) (szDest + 4)) = m_FastHeToBi[ *(pSrc++) ];
*((WORD *) (szDest + 6)) = m_FastHeToBi[ *(pSrc++) ];
*((WORD *) (szDest + 8)) = m_FastHeToBi[ *(pSrc++) ];
*((WORD *) (szDest + 10)) = m_FastHeToBi[ *(pSrc++) ];
*((WORD *) (szDest + 12)) = m_FastHeToBi[ *(pSrc++) ];
*((WORD *) (szDest + 14)) = m_FastHeToBi[ *(pSrc++) ];
#else
*((WORD *) (szDest + 14)) = m_FastHeToBi[ *(pSrc++) ];
*((WORD *) (szDest + 12)) = m_FastHeToBi[ *(pSrc++) ];
*((WORD *) (szDest + 10)) = m_FastHeToBi[ *(pSrc++) ];
*((WORD *) (szDest + 8)) = m_FastHeToBi[ *(pSrc++) ];
*((WORD *) (szDest + 6)) = m_FastHeToBi[ *(pSrc++) ];
*((WORD *) (szDest + 4)) = m_FastHeToBi[ *(pSrc++) ];
*((WORD *) (szDest + 2)) = m_FastHeToBi[ *(pSrc++) ];
*((WORD *) (szDest + 0)) = m_FastHeToBi[ *(pSrc++) ];
#endif
*(szDest + 16) = '\0';
}
//
// this function returns the equivalent binary value for an individual character specified in the ascii format
inline TCHAR Math::Convert::BiToHe(TCHAR cBin)
{
if((cBin >= '0') && (cBin <= '9'))
{
return (cBin - '0');
}
else if((cBin >= 'A') && (cBin <= 'F'))
{
return (cBin - 'A' + 0xA);
}
if((cBin >= 'a') && (cBin <= 'f'))
{
return (cBin -'a' + 0xA);
}
return cBin;
}
inline void Math::Convert::AcToHe(char *szDst, char *szSrc, int iCount)
{
while(iCount--)
{
*szDst = BiToHe(*szSrc) << 4;
*szSrc++;
*szDst += BiToHe(*szSrc);
*szSrc++;
*szDst++;
}
}
inline BYTE Math::Convert::StrToHex08(const TCHAR *szSrc)
{
const TCHAR* pStart = szSrc + 2;
BYTE cHex = 0;
TCHAR c1, c2;
for (int i=0; i<1; ++i)
{
c1 = BiToHe(*pStart++);
c1 <<= (8*(7-i)+4);
c2 = BiToHe(*pStart++);
c2 <<= (8*(7-i));
cHex += (c1 + c2);
}
return cHex;
}
inline WORD Math::Convert::StrToHex16(const TCHAR *szSrc)
{
const TCHAR* pStart = szSrc + 2;
WORD sHex = 0;
for (int i=0; i<2; i++)
{
WORD s1 = BiToHe(*pStart++);
s1 <<= (8*(1-i)+4);
WORD s2 = BiToHe(*pStart++);
s2 <<= (8*(1-i));
WORD sRet = s1 + s2;
sHex += sRet;
}
return sHex;
}
// convert string to hexadecimal value
inline unsigned long Math::Convert::StrToHex32(const TCHAR *szSrc)
{
const TCHAR* pStart = szSrc + 2;
unsigned long nHex = 0;
for (int i=0; i<4; i++)
{
unsigned long n1 = BiToHe(*pStart++);
n1 <<= (8*(3-i)+4);
unsigned long n2 = BiToHe(*pStart++);
n2 <<= (8*(3-i));
unsigned long nRet = n1 + n2;
nHex += nRet;
}
return nHex;
}
// convert string to hexadecimal value
inline DWORD64 Math::Convert::StrToHex64(const TCHAR *szSrc)
{
const TCHAR* pStart = szSrc + 2;
DWORD64 dlHex = 0;
for (int i=0; i<8; i++)
{
DWORD64 dl1 = BiToHe(*pStart++);
dl1 <<= (8*(7-i)+4);
DWORD64 dl2 = BiToHe(*pStart++);
dl2 <<= (8*(7-i));
DWORD64 dlRet = dl1 + dl2;
dlHex += dlRet;
}
return dlHex;
}
inline BYTE Math::Convert::Atoc(const TCHAR *szSrc)
{
return (0 == _tcsncmp(szSrc, _T("0x"), 2)) ? StrToHex08(szSrc) : (BYTE) _ttol(szSrc);
}
//
// TCHAR *<2A><> <20><>Ĩ<EFBFBD>ô<EFBFBD>! (By Standil)
//
inline WORD Math::Convert::Atos(const TCHAR *szSrc)
{
return (0 == _tcsncmp(szSrc, _T("0x"), 2)) ? StrToHex16(szSrc) : _ttoi(szSrc);
}
//
// TCHAR *<2A><> <20><>Ĩ<EFBFBD>ô<EFBFBD>! (By Standil)
//
inline unsigned long Math::Convert::Atoi(const TCHAR *szSrc)
{
return (0 == _tcsncmp(szSrc, _T("0x"), 2)) ? StrToHex32(szSrc) : _ttol(szSrc);
}
//
// TCHAR *<2A><> <20><>Ĩ<EFBFBD>ô<EFBFBD>! (By Standil)
//
inline DWORD64 Math::Convert::Atol64(const TCHAR *szSrc)
{
return (0 == _tcsncmp(szSrc, _T("0x"), 2)) ? StrToHex64(szSrc) : _ttoi64(szSrc);
}
#endif

View File

@@ -0,0 +1,100 @@
// FastMath.cpp: implementation of the CFastMath class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Math.h"
#include "Random.h"
Math::RandomInt st_random;
///////////////////////////////////////////////////////////////////////////////////////////////
// utility functions
// 0 -0x7FFFFFFF.
unsigned long Math::Random::ComplexRandom(int nEndExtent, int nBeginExtent)
{
// <20><><EFBFBD><EFBFBD> <20>ҽ<EFBFBD><D2BD><EFBFBD> 100<30><30> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 0~99<39><39><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>µ<EFBFBD>
// <20><><EFBFBD><EFBFBD> <20>ۼ<EFBFBD><DBBC><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 100<30><30> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 0~100<30><30><EFBFBD><EFBFBD> <20><><EFBFBD>´<EFBFBD>.
// <20>׷<EFBFBD><D7B7><EFBFBD> -1<><31> <20>ϰ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
if(nBeginExtent == 0)
return st_random.Next(nEndExtent);
return st_random.Next(nBeginExtent, nEndExtent);
/*
if (nEndExtent < 1 || nEndExtent <= nBeginExtent)
{
return nBeginExtent;
}
static unsigned long x = 1;
static unsigned long c = 0;
static unsigned long a = 2083801278UL;
#define addto(rh,rl,ah,al) (rl) = ((rl) + (al)) & 0xFFFFFFFFUL; \
(rh) = ((rh) + (ah) + (((rl) < (al)) ? 1 : 0)) & 0xFFFFFFFFUL
unsigned long xl = (x & 0xFFFFUL);
unsigned long xh = (x >> 16) & 0xFFFFUL;
unsigned long al = (a & 0xFFFFUL);
unsigned long ah = (a >> 16) & 0xFFFFUL;
unsigned long tmp;
x = c;
c = 0;
tmp = xl * al;
addto(c, x, 0, tmp);
tmp = xl * ah;
addto(c, x, (tmp >> 16), (tmp & 0xFFFFUL) << 16);
tmp = xh * ah;
addto(c, x, tmp, 1);
tmp = xh * al;
addto(c, x, (tmp >> 16), (tmp & 0xFFFFUL) << 16);
return (x % (nEndExtent - nBeginExtent)) + nBeginExtent; // return x & 0x7FFFFFFFUL;
*/
}
int Math::Random::SimpleRandom(unsigned long dwSeed, int nEndExtent, int nBeginExtent)
{
return( nBeginExtent + ((((dwSeed * 214013L + 2531011L) >> 16) & 0x7FFF) % (nEndExtent - nBeginExtent)) );
}
// This table only works on Little Endian(Byte Order) machine.
const unsigned short Math::Convert::m_FastHeToBi[0x100] =
{
0x3030, 0x3130, 0x3230, 0x3330, 0x3430, 0x3530, 0x3630, 0x3730,
0x3830, 0x3930, 0x4130, 0x4230, 0x4330, 0x4430, 0x4530, 0x4630,
0x3031, 0x3131, 0x3231, 0x3331, 0x3431, 0x3531, 0x3631, 0x3731,
0x3831, 0x3931, 0x4131, 0x4231, 0x4331, 0x4431, 0x4531, 0x4631,
0x3032, 0x3132, 0x3232, 0x3332, 0x3432, 0x3532, 0x3632, 0x3732,
0x3832, 0x3932, 0x4132, 0x4232, 0x4332, 0x4432, 0x4532, 0x4632,
0x3033, 0x3133, 0x3233, 0x3333, 0x3433, 0x3533, 0x3633, 0x3733,
0x3833, 0x3933, 0x4133, 0x4233, 0x4333, 0x4433, 0x4533, 0x4633,
0x3034, 0x3134, 0x3234, 0x3334, 0x3434, 0x3534, 0x3634, 0x3734,
0x3834, 0x3934, 0x4134, 0x4234, 0x4334, 0x4434, 0x4534, 0x4634,
0x3035, 0x3135, 0x3235, 0x3335, 0x3435, 0x3535, 0x3635, 0x3735,
0x3835, 0x3935, 0x4135, 0x4235, 0x4335, 0x4435, 0x4535, 0x4635,
0x3036, 0x3136, 0x3236, 0x3336, 0x3436, 0x3536, 0x3636, 0x3736,
0x3836, 0x3936, 0x4136, 0x4236, 0x4336, 0x4436, 0x4536, 0x4636,
0x3037, 0x3137, 0x3237, 0x3337, 0x3437, 0x3537, 0x3637, 0x3737,
0x3837, 0x3937, 0x4137, 0x4237, 0x4337, 0x4437, 0x4537, 0x4637,
0x3038, 0x3138, 0x3238, 0x3338, 0x3438, 0x3538, 0x3638, 0x3738,
0x3838, 0x3938, 0x4138, 0x4238, 0x4338, 0x4438, 0x4538, 0x4638,
0x3039, 0x3139, 0x3239, 0x3339, 0x3439, 0x3539, 0x3639, 0x3739,
0x3839, 0x3939, 0x4139, 0x4239, 0x4339, 0x4439, 0x4539, 0x4639,
0x3041, 0x3141, 0x3241, 0x3341, 0x3441, 0x3541, 0x3641, 0x3741,
0x3841, 0x3941, 0x4141, 0x4241, 0x4341, 0x4441, 0x4541, 0x4641,
0x3042, 0x3142, 0x3242, 0x3342, 0x3442, 0x3542, 0x3642, 0x3742,
0x3842, 0x3942, 0x4142, 0x4242, 0x4342, 0x4442, 0x4542, 0x4642,
0x3043, 0x3143, 0x3243, 0x3343, 0x3443, 0x3543, 0x3643, 0x3743,
0x3843, 0x3943, 0x4143, 0x4243, 0x4343, 0x4443, 0x4543, 0x4643,
0x3044, 0x3144, 0x3244, 0x3344, 0x3444, 0x3544, 0x3644, 0x3744,
0x3844, 0x3944, 0x4144, 0x4244, 0x4344, 0x4444, 0x4544, 0x4644,
0x3045, 0x3145, 0x3245, 0x3345, 0x3445, 0x3545, 0x3645, 0x3745,
0x3845, 0x3945, 0x4145, 0x4245, 0x4345, 0x4445, 0x4545, 0x4645,
0x3046, 0x3146, 0x3246, 0x3346, 0x3446, 0x3546, 0x3646, 0x3746,
0x3846, 0x3946, 0x4146, 0x4246, 0x4346, 0x4446, 0x4546, 0x4646,
};

View File

@@ -0,0 +1,99 @@
// FastMath.h: interface for the CFastMath class.
//
//////////////////////////////////////////////////////////////////////
#ifndef _CUSTOM_MATH_FUNCTIONS_H_
#define _CUSTOM_MATH_FUNCTIONS_H_
#include <winsock2.h>
#include <windows.h>
#include <cmath>
namespace Math
{
namespace Convert
{
extern const unsigned short m_FastHeToBi[0x100];
// SPX, IPX <20>ּ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> <20>Լ<EFBFBD>
inline TCHAR BiToHe(TCHAR cBin);
inline void AcToHe(char *szDst, char *szSrc, int iCount);
// String<6E><67> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ٲ<EFBFBD>(String<6E><67> 0x<30><78> <20><><EFBFBD><EFBFBD> Hex string<6E>̴<EFBFBD>.)
inline BYTE StrToHex08(const TCHAR *szSrc);
inline WORD StrToHex16(const TCHAR *szSrc);
inline unsigned long StrToHex32(const TCHAR *szSrc);
inline DWORD64 StrToHex64(const TCHAR *szSrc);
// String<6E><67> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ٲ<EFBFBD>(0x<30><78> <20>ٴ<EFBFBD><D9B4><EFBFBD>, <20><><EFBFBD><EFBFBD> <20>ʴ<EFBFBD><CAB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ٲ<EFBFBD> <20><> <20>ִ<EFBFBD>)
inline BYTE Atoc(const TCHAR *szSrc);
inline WORD Atos(const TCHAR *szSrc);
inline unsigned long Atoi(const TCHAR *szSrc);
inline DWORD64 Atol64(const TCHAR *szSrc);
// <20><><EFBFBD><EFBFBD> Hex String<6E><67><EFBFBD><EFBFBD> <20>ٲ<EFBFBD>
inline void Hex08ToStr(TCHAR *szDest, BYTE hex);
inline void Hex16ToStr(TCHAR *szDest, WORD hex);
inline void Hex32ToStr(TCHAR *szDest, unsigned long hex);
inline void Hex64ToStr(TCHAR *szDest, DWORD64 hex);
};
namespace Random
{
// <20><><EFBFBD>ϰ<EFBFBD><CFB0><EFBFBD> nBeginExtent ~ nEndExtent - 1<><31> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>´<EFBFBD>.
unsigned long ComplexRandom(int nEndExtent, int nBeginExtent = 0); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
int SimpleRandom(unsigned long dwSeed, int nEndExtent, int nBeginExtent = 0);
};
namespace HashFunc
{
// -------------------------------------------------------------------------------------------------
// String-to-Hash <20>Լ<EFBFBD><D4BC><EFBFBD> : http://www.cs.yorku.ca/~oz/hash.html <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
inline unsigned long djb2Hash(const unsigned char *str); // first reported by dan bernstein
inline unsigned long sdbmHash(const unsigned char *str); // this is one of the algorithms used in berkeley db
inline unsigned long looseHash(const unsigned char *str); // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ؽ<EFBFBD>. <20>׳<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
};
namespace Const
{
static float PI = 3.14159f;
}
};
#include "Convert.inl"
inline unsigned long Math::HashFunc::djb2Hash(const unsigned char *str)
{
unsigned long hash = 5381;
int c;
while (c = *str++) { hash = ((hash << 5) + hash) + c; /* hash * 33 + c */ }
return hash;
}
inline unsigned long Math::HashFunc::sdbmHash(const unsigned char *str)
{
unsigned long hash = 0;
int c;
while (c = *str++) { hash = c + (hash << 6) + (hash << 16) - hash; }
return hash;
}
inline unsigned long Math::HashFunc::looseHash(const unsigned char *str)
{
unsigned int hash = 0;
int c;
while (c = *str++) { hash += c; }
return hash;
}
#endif // !defined(AFX_FASTMATH_H__ED69578B_18C1_42EA_9C5E_888DC38101C2__INCLUDED_)

View File

@@ -0,0 +1,65 @@
// mtrand.cpp, see include file mtrand.h for information
#include "stdafx.h"
#include "PseudoRandom.h"
#include <time.h>
// non-inline function definitions and static member definitions cannot
// reside in header file because of the risk of multiple declarations
// initialization of static private members
/*unsigned long MersenneTwister::state[Constant1] = {0x0UL};
int MersenneTwister::position = 0;*/
namespace Math
{
MersenneTwister::MersenneTwister(BOOL useCurrentTime) {
if ( useCurrentTime) {
time_t t; time(&t);
SetSeed(unsigned long(t));
} else {
SetSeed(5489UL);
}
}
void MersenneTwister::GenerateState() { // generate new state vector
for (int i = 0; i < (Constant1 - Constant2); ++i)
state[i] = state[i + Constant2] ^ Twiddle(state[i], state[i + 1]);
for (int i = Constant1 - Constant2; i < (Constant1 - 1); ++i)
state[i] = state[i + Constant2 - Constant1] ^ Twiddle(state[i], state[i + 1]);
state[Constant1 - 1] = state[Constant2 - 1] ^ Twiddle(state[Constant1 - 1], state[0]);
position = 0; // reset position
}
void MersenneTwister::SetSeed(unsigned long s) { // initialized by 32 bit seed
for ( int i=0; i<Constant1; ++i) { state[i]= 0x0UL; }
//state[Constant1] = {0x0UL};
state[0] = s & 0xFFFFFFFFUL; // for > 32 bit machines
for (int i = 1; i < Constant1; ++i) {
state[i] = 1812433253UL * (state[i - 1] ^ (state[i - 1] >> 30)) + i;
// see Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier
// in the previous versions, MSBs of the seed affect only MSBs of the array state
// 2002/01/09 modified by Makoto Matsumoto
state[i] &= 0xFFFFFFFFUL; // for > 32 bit machines
}
position = Constant1; // force GenerateState() to be called for next random number
}
void MersenneTwister::SetSeed(const unsigned long* array, int size) { // initialized by array
SetSeed(19650218UL);
int i = 1, j = 0;
for (int k = ((Constant1 > size) ? Constant1 : size); k; --k) {
state[i] = (state[i] ^ ((state[i - 1] ^ (state[i - 1] >> 30)) * 1664525UL))
+ array[j] + j; // non linear
state[i] &= 0xFFFFFFFFUL; // for > 32 bit machines
++j; j %= size;
if ((++i) == Constant1) { state[0] = state[Constant1 - 1]; i = 1; }
}
for (int k = Constant1 - 1; k; --k) {
state[i] = (state[i] ^ ((state[i - 1] ^ (state[i - 1] >> 30)) * 1566083941UL)) - i;
state[i] &= 0xFFFFFFFFUL; // for > 32 bit machines
if ((++i) == Constant1) { state[0] = state[Constant1 - 1]; i = 1; }
}
state[0] = 0x80000000UL; // MSB is 1; assuring non-zero initial array
position = Constant1; // force GenerateState() to be called for next random number
}
}

View File

@@ -0,0 +1,224 @@
#pragma once
namespace Math
{
/**
The Mersenne Twister random number generator
usage:
PseudoRandomInt foo; //initializes random sequence by the current time
PseudoRandomInt foo(false); // the default seed 5489UL is used
foo.SetSeed(230194019);
foo.Next()
foo.Next(10,4300); //returns unsigned long between 10 and 4300
PseudoRandomFloat foo;
foo.Next(); // return double between [0..1)
foo.Next(245); // return double between [0..245)
PseudoRandomFloatClosed foo;
foo.Next(); // return double between [0..1]
PseudoRandomFloatOpen foo;
foo.Next(); // return double between (0..1)
details:
The Mersenne twister is a pseudorandom number generator that was developed in 1997 by Makoto Matsumoto
(<28><><EFBFBD><EFBFBD> <20><>) and Takuji Nishimura (<28><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>). It provides for fast generation of very high quality random
numbers - having been designed specifically to rectify many of the flaws found in older algorithms.
It has the following desirable properties:
It was designed to have a colossal period of 219937-1 (the creators of the algorithm proved this property).
It has a very high order of dimensional equidistribution (see linear congruential generator). Note that this means, by default, that there is negligible serial correlation between successive values in the output sequence.
It is faster than all but the most statistically unsound generators.
It is statistically random in all the bits of its output.
This implementation is based C++ code by Takuji Nishimura and Makoto Matsumoto, Jasper Bedaux, Isaku Wada
*/
class MersenneTwister {
public:
// default constructor: uses default seed only if this is the first instance
MersenneTwister(BOOL useCurrentTime=TRUE);
// constructor with 32 bit int as seed
MersenneTwister(unsigned long s) { SetSeed(s); }
// constructor with array of size 32 bit ints as seed
MersenneTwister(const unsigned long* array, int size) { SetSeed(array, size); }
// the two seed functions
void SetSeed(unsigned long); // seed with 32 bit integer
void SetSeed(const unsigned long*, int size); // seed with array
// overload operator() to make this a generator (functor)
//unsigned long operator()() { return GenerateRandom(); }
//unsigned long Next() { return (*this)(); }
~MersenneTwister() {} // destructor
protected: // used by derived classes, otherwise not accessible; use the ()-operator
unsigned long GenerateRandom() { // generate 32 bit random integer
if (position == Constant1) GenerateState(); // new state vector needed
// GenerateState() is split off to be non-inline, because it is only called once
// in every 624 calls and otherwise irand() would become too big to get inlined
unsigned long x = state[position++];
x ^= (x >> 11);
x ^= (x << 7) & 0x9D2C5680UL;
x ^= (x << 15) & 0xEFC60000UL;
return x ^ (x >> 18);
}
private:
enum { Constant1 = 624, Constant2 = 397 };
unsigned long state[Constant1]; // state vector array
int position; // position in state array
// private functions used to generate the pseudo random numbers
unsigned long Twiddle(unsigned long u, unsigned long v) {
return (((u & 0x80000000UL) | (v & 0x7FFFFFFFUL)) >> 1) ^ ((v & 1UL) ? 0x9908B0DFUL : 0x0UL);
} // used by GenerateState()
void GenerateState(); // generate new state
// make copy constructor and assignment operator unavailable, they don't make sense
MersenneTwister(const MersenneTwister&); // copy constructor not defined
void operator=(const MersenneTwister&); // assignment operator not defined
};
class PseudoRandomInt : public MersenneTwister {
public:
PseudoRandomInt(BOOL useCurrentTime=TRUE): MersenneTwister(useCurrentTime) {}
PseudoRandomInt(unsigned long seed) : MersenneTwister(seed) {}
PseudoRandomInt(const unsigned long* seed, int size) : MersenneTwister(seed, size) {}
unsigned long operator()() { return GenerateRandom(); }
unsigned long Next() { return (*this)(); }
unsigned long Next(unsigned long minval, unsigned long maxval) {
return minval+(Next()%(maxval-minval));
}
};
// generates double floating point numbers in the half-open interval [0, 1)
class PseudoRandomFloat : public MersenneTwister {
public:
PseudoRandomFloat(BOOL useCurrentTime=TRUE) : MersenneTwister(useCurrentTime) {}
PseudoRandomFloat(unsigned long seed) : MersenneTwister(seed) {}
PseudoRandomFloat(const unsigned long* seed, int size) : MersenneTwister(seed, size) {}
~PseudoRandomFloat() {}
double operator()() {
return static_cast<double>(GenerateRandom()) * (1. / 4294967296.); } // divided by 2^32
double Next() { return (*this)(); }
double Next(double mul) { return Next()*mul; }
private:
PseudoRandomFloat(const PseudoRandomFloat&); // copy constructor not defined
void operator=(const PseudoRandomFloat&); // assignment operator not defined
};
// generates double floating point numbers in the closed interval [0, 1]
class PseudoRandomFloatClosed : public MersenneTwister {
public:
PseudoRandomFloatClosed(BOOL useCurrentTime=TRUE) : MersenneTwister(useCurrentTime) {}
PseudoRandomFloatClosed(unsigned long seed) : MersenneTwister(seed) {}
PseudoRandomFloatClosed(const unsigned long* seed, int size) : MersenneTwister(seed, size) {}
~PseudoRandomFloatClosed() {}
double operator()() {
return static_cast<double>(GenerateRandom()) * (1. / 4294967295.); } // divided by 2^32 - 1
double Next() { return (*this)(); }
double Next(double mul) { return Next()*mul; }
private:
PseudoRandomFloatClosed(const PseudoRandomFloatClosed&); // copy constructor not defined
void operator=(const PseudoRandomFloatClosed&); // assignment operator not defined
};
// generates double floating point numbers in the open interval (0, 1)
class PseudoRandomFloatOpen : public MersenneTwister {
public:
PseudoRandomFloatOpen(BOOL useCurrentTime=TRUE) : MersenneTwister(useCurrentTime) {}
PseudoRandomFloatOpen(unsigned long seed) : MersenneTwister(seed) {}
PseudoRandomFloatOpen(const unsigned long* seed, int size) : MersenneTwister(seed, size) {}
~PseudoRandomFloatOpen() {}
double operator()() {
return (static_cast<double>(GenerateRandom()) + .5) * (1. / 4294967296.); } // divided by 2^32
double Next() { return (*this)(); }
double Next(double mul) { return Next()*mul; }
private:
PseudoRandomFloatOpen(const PseudoRandomFloatOpen&); // copy constructor not defined
void operator=(const PseudoRandomFloatOpen&); // assignment operator not defined
};
// generates 53 bit resolution doubles in the half-open interval [0, 1)
class PseudoRandomFloat53Bit : public MersenneTwister {
public:
PseudoRandomFloat53Bit(BOOL useCurrentTime=TRUE) : MersenneTwister(useCurrentTime) {}
PseudoRandomFloat53Bit(unsigned long seed) : MersenneTwister(seed) {}
PseudoRandomFloat53Bit(const unsigned long* seed, int size) : MersenneTwister(seed, size) {}
~PseudoRandomFloat53Bit() {}
double operator()() {
return (static_cast<double>(GenerateRandom() >> 5) * 67108864. +
static_cast<double>(GenerateRandom() >> 6)) * (1. / 9007199254740992.); }
double Next() { return (*this)(); }
double Next(double mul) { return Next()*mul; }
private:
PseudoRandomFloat53Bit(const PseudoRandomFloat53Bit&); // copy constructor not defined
void operator=(const PseudoRandomFloat53Bit&); // assignment operator not defined
};
// typedef MersenneTwister PseudoRandom;
// Pseudorandom series(21301391);
// mtrand.h
// C++ include file for MT19937, with initialization improved 2002/1/26.
// Coded by Takuji Nishimura and Makoto Matsumoto.
// Ported to C++ by Jasper Bedaux 2003/1/1 (see http://www.bedaux.net/mtrand/).
// The generators returning floating point numbers are based on
// a version by Isaku Wada, 2002/01/09
//
// Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. The names of its contributors may not be used to endorse or promote
// products derived from this software without specific prior written
// permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Any feedback is very welcome.
// http://www.math.keio.ac.jp/matumoto/emt.html
// email: matumoto@math.keio.ac.jp
//
// Feedback about the C++ port should be sent to Jasper Bedaux,
// see http://www.bedaux.net/mtrand/ for e-mail address and info.
}

View File

@@ -0,0 +1,63 @@
#include "stdafx.h"
#include "Random.h"
namespace Math
{
RandomInt::RandomInt()
{
SetSeed(GetTickCount());
}
RandomInt::RandomInt(unsigned long seed) : random(seed)
{
}
void RandomInt::SetSeed(unsigned long seed)
{
random.SetSeed(seed);
}
unsigned int RandomInt::Next()
{
return random.Next();
}
unsigned int RandomInt::Next(unsigned int excludedMax)
{
if(excludedMax == 0)
return excludedMax;
return Next(0, excludedMax);
}
unsigned int RandomInt::Next(unsigned int includedMin, unsigned int excludedMax)
{
if(includedMin == excludedMax)
return includedMin;
return random.Next(includedMin, excludedMax);
}
RandomDouble::RandomDouble()
{
SetSeed(GetTickCount());
}
RandomDouble::RandomDouble(unsigned long seed) : random(seed)
{
}
void RandomDouble::SetSeed(unsigned long seed)
{
random.SetSeed(seed);
}
double RandomDouble::Next()
{
return random.Next();
}
}

View File

@@ -0,0 +1,45 @@
#pragma once
#include "PseudoRandom.h"
namespace Math
{
class RandomInt
{
private:
PseudoRandomInt random;
// unable to copy
RandomInt(const RandomInt& );
void operator =(const RandomInt&);
public:
RandomInt();
RandomInt(unsigned long seed);
void SetSeed(unsigned long seed);
virtual unsigned int Next();
virtual unsigned int Next(unsigned int excludedMax);
virtual unsigned int Next(unsigned int includedMin, unsigned int excludedMax);
};
class RandomDouble
{
private:
PseudoRandomFloatClosed random;
// unable to copy
RandomDouble(const RandomDouble& );
void operator =(const RandomDouble&);
public:
RandomDouble();
RandomDouble(unsigned long seed);
void SetSeed(unsigned long seed);
virtual double Next(); // generates a float number [0, 1]
};
}

View File

@@ -0,0 +1,187 @@
#include "stdafx.h"
#include <winsock2.h>
#include <windows.h>
#include "RegFunctions.h"
#include <fstream>
bool Registry::WriteString(const char *FileName_In, const char *Section_In,
const char *KeyName_In, const char *Value_In)
{
return 0 != WritePrivateProfileString(Section_In, KeyName_In, Value_In, FileName_In);
}
unsigned long Registry::ReadInt(const char *FileName_In, const char *Section_In, const char *KeyName_In)
{
return static_cast<unsigned long>(GetPrivateProfileInt(Section_In, KeyName_In, 0, FileName_In));
}
bool Registry::ReadString(const char *FileName_In, const char *Section_In,
const char *KeyName_In, char *Buffer_Out, int nBufferSize)
{
return 0 != GetPrivateProfileString(Section_In, KeyName_In,
NULL, Buffer_Out, nBufferSize, FileName_In);
}
bool Registry::WriteStruct(const char *FileName_In, const char *Section_In,
const char *KeyName_In, void *Value_In, const int Size_in)
{
return 0 != WritePrivateProfileStruct(Section_In, KeyName_In, Value_In, Size_in, FileName_In);
}
bool Registry::ReadStruct(const char *FileName_In, const char *Section_In,
const char *KeyName_In, void *Value_Out, const int Size_in)
{
return 0 != GetPrivateProfileStruct(Section_In, KeyName_In, Value_Out, Size_in, FileName_In);
}
Registry::CSetupFile::CSetupFile()
{
}
Registry::CSetupFile::CSetupFile(const char* szFileName)
{
Open(szFileName);
}
Registry::CSetupFile::~CSetupFile()
{
}
inline unsigned long sdbmHash(const unsigned char *str)
{
unsigned long hash = 0;
int c;
while (c = *str++) { hash = c + (hash << 6) + (hash << 16) - hash; }
return hash;
}
bool Registry::CSetupFile::Open(const char* szFileName)
{
std::string fileLine;
std::string szSection;
std::string szKey;
std::string szValue;
fileLine.reserve(4096);
szSection.reserve(1024);
szKey.reserve(1024);
szValue.reserve(4096);
std::fstream file(szFileName, std::ios_base::in);
std::string::size_type nPosition = std::string::npos;
std::string::size_type nEndPosition = std::string::npos;
std::string::size_type nDataPosition = std::string::npos;
std::string::size_type nDataEndPosition = std::string::npos;
unsigned long dwSectionValue = 0;
if(file.is_open())
{
while(std::getline(file, fileLine))
{
nPosition = fileLine.find_first_not_of(" \r\n\t");
if(std::string::npos != nPosition)
{
if('[' == fileLine[nPosition])
{
// <20><><EFBFBD>Ǹ<EFBFBD><C7B8><EFBFBD>
nEndPosition = fileLine.find_first_of(']', nPosition);
if(std::string::npos != nEndPosition)
{
szSection.assign(fileLine.begin() + nPosition + 1,
fileLine.begin() + nEndPosition);
dwSectionValue = sdbmHash(reinterpret_cast<const unsigned char*>(szSection.c_str()));
}
}
else if(0 != fileLine.compare(nPosition, sizeof(char) * 2, "//"))
{
// <20>ּ<EFBFBD> <20>ƴ<EFBFBD>
nEndPosition = fileLine.find_first_of('=', nPosition);
if(std::string::npos != nEndPosition)
{
// nEndPosition <20>¿<EFBFBD><C2BF><EFBFBD> Key - Value Pair<69><72>.
nDataEndPosition = fileLine.find_last_not_of("= \t", nEndPosition);
if(std::string::npos != nDataEndPosition)
{
// Ű <20>о<EFBFBD><D0BE><EFBFBD>.
szKey.assign(fileLine.begin() + nPosition,
fileLine.begin() + nDataEndPosition + 1);
nDataPosition = fileLine.find_first_not_of("= \t", nEndPosition);
if(std::string::npos != nDataPosition)
{
nDataEndPosition = fileLine.find_last_not_of(" \r\n\t");
if(std::string::npos != nDataEndPosition)
{
// <20><> <20>о<EFBFBD><D0BE><EFBFBD>
m_SetupMap.insert(SetupMap::value_type(
sdbmHash(reinterpret_cast<const unsigned char*>(szKey.c_str())) + dwSectionValue,
Data(szSection, szKey,
std::string(fileLine.begin() + nDataPosition, fileLine.begin() + nDataEndPosition + 1))));
}
}
}
}
}
}
}
}
return false;
}
void Registry::CSetupFile::Clear()
{
m_SetupMap.clear();
}
const char* Registry::CSetupFile::GetString(const char* szSection, const char* szKey,
const char* szDefaultValue)
{
DWORD dwHashValue = sdbmHash(reinterpret_cast<const unsigned char*>(szSection))
+ sdbmHash(reinterpret_cast<const unsigned char*>(szKey));
std::pair<SetupMap::iterator, SetupMap::iterator> pos_pair = m_SetupMap.equal_range(dwHashValue);
for(; pos_pair.first != pos_pair.second; ++pos_pair.first)
{
Data& data = pos_pair.first->second;
if(0 == data.m_szSection.compare(szSection) &&
0 == data.m_szKey.compare(szKey))
{
return data.m_szValue.c_str();
}
}
return szDefaultValue;
}
unsigned int Registry::CSetupFile::GetInt(const char* szSection, const char* szKey,
unsigned int nDefaultValue)
{
const char* szStr = GetString(szSection, szKey);
if(0 != szStr)
{
return atoi(szStr);
}
return nDefaultValue;
}

View File

@@ -0,0 +1,59 @@
#ifndef _REGISTRY_FUNCTIONS_H_
#define _REGISTRY_FUNCTIONS_H_
#include <map>
#include <string>
namespace Registry
{
bool WriteString(const char *FileName_In, const char *Section_In,
const char *KeyName_In, const char *Value_In);
unsigned long ReadInt(const char *FileName_In,
const char *Section_In, const char *KeyName_In);
bool ReadString(const char *FileName_In, const char *Section_In,
const char *KeyName_In, char *Buffer_Out, int nBufferSize);
bool WriteStruct(const char *FileName_In, const char *Section_In,
const char *KeyName_In, void *Value_In, const int Size_in);
bool ReadStruct(const char *FileName_In, const char *Section_In,
const char *KeyName_In, void *Value_Out, const int Size_in);
class CSetupFile
{
public:
CSetupFile();
CSetupFile(const char* szFileName);
~CSetupFile();
bool Open(const char* szFileName);
void Clear();
const char* GetString(const char* szSection, const char* szKey, const char* szDefaultValue = 0);
unsigned int GetInt(const char* szSection, const char* szKey, unsigned int nDefaultValue = 0);
private:
struct Data
{
std::string m_szSection;
std::string m_szKey;
std::string m_szValue;
Data(const std::string& szSection, const std::string& szKey, const std::string& szValue)
: m_szSection(szSection), m_szKey(szKey), m_szValue(szValue)
{
}
};
typedef std::multimap<unsigned long, Data> SetupMap;
SetupMap m_SetupMap;
};
};
#endif

View File

@@ -0,0 +1,225 @@
/******************************************************************************
Module: EnsureCleanup.h
Notices: Copyright (c) 2000 Jeffrey Richter
Purpose: These classes ensure object cleanup when an object goes out of scope.
See Appendix B.
******************************************************************************/
#ifndef _ENSURE_CLEAN_UP_BY_JEFFERY_RICHTER
#define _ENSURE_CLEAN_UP_BY_JEFFERY_RICHTER
#pragma once // Include this header file once per compilation unit
#include <winsock2.h>
#include <windows.h>
// Data type representing the address of the object's cleanup function.
// I used UINT_PTR so that this class works properly in 64-bit Windows.
typedef VOID (WINAPI* PFNENSURECLEANUP)(UINT_PTR);
// Each template instantiation requires a data type, address of cleanup
// function, and a value that indicates an invalid value.
template<class TYPE, PFNENSURECLEANUP pfn, UINT_PTR tInvalid = NULL>
class CEnsureCleanup
{
public:
// Default constructor assumes an invalid value (nothing to cleanup)
CEnsureCleanup() { m_t = tInvalid; }
// This constructor sets the value to the specified value
CEnsureCleanup(TYPE t) : m_t((UINT_PTR) t) { }
// The destructor performs the cleanup.
~CEnsureCleanup() { Cleanup(); }
// Helper methods to tell if the value represents a valid object or not..
BOOL IsValid() { return(m_t != tInvalid); }
BOOL IsInvalid() { return(!IsValid()); }
// Re-assigning the object forces the current object to be cleaned-up.
TYPE operator=(TYPE t)
{
Cleanup();
m_t = (UINT_PTR) t;
return(*this);
}
// Returns the value (supports both 32-bit and 64-bit Windows).
operator TYPE()
{
// If TYPE is a 32-bit value, cast m_t to 32-bit TYPE
// If TYPE is a 64-bit value, case m_t to 64-bit TYPE
return((sizeof(TYPE) == 4) ? (TYPE) PtrToUint(m_t) : (TYPE) m_t);
}
// Cleanup the object if the value represents a valid object
void Cleanup()
{
if (IsValid())
{
// In 64-bit Windows, all parameters are 64-bits,
// so no casting is required
pfn(m_t); // Close the object.
m_t = tInvalid; // We no longer represent a valid object.
}
}
private:
UINT_PTR m_t; // The member representing the object
};
///////////////////////////////////////////////////////////////////////////////
// Macros to make it easier to declare instances of the template
// class for specific data types.
#define MakeCleanupClass(className, tData, pfnCleanup) \
typedef CEnsureCleanup<tData, (PFNENSURECLEANUP) pfnCleanup> className;
#define MakeCleanupClassX(className, tData, pfnCleanup, tInvalid) \
typedef CEnsureCleanup<tData, (PFNENSURECLEANUP) pfnCleanup, \
(INT_PTR) tInvalid> className;
///////////////////////////////////////////////////////////////////////////////
// Instances of the template C++ class for common data types.
MakeCleanupClass(CEnsureCloseHandle, HANDLE, CloseHandle);
MakeCleanupClassX(CEnsureCloseFile, HANDLE, CloseHandle, INVALID_HANDLE_VALUE);
MakeCleanupClass(CEnsureLocalFree, HLOCAL, LocalFree);
MakeCleanupClass(CEnsureGlobalFree, HGLOBAL, GlobalFree);
MakeCleanupClass(CEnsureRegCloseKey, HKEY, RegCloseKey);
MakeCleanupClass(CEnsureCloseServiceHandle, SC_HANDLE, CloseServiceHandle);
MakeCleanupClass(CEnsureCloseWindowStation, HWINSTA, CloseWindowStation);
MakeCleanupClass(CEnsureCloseDesktop, HDESK, CloseDesktop);
MakeCleanupClass(CEnsureUnmapViewOfFile, PVOID, UnmapViewOfFile);
MakeCleanupClass(CEnsureFreeLibrary, HMODULE, FreeLibrary);
///////////////////////////////////////////////////////////////////////////////
// Special class for releasing a reserved region.
// Special class is required because VirtualFree requires 3 parameters
class CEnsureReleaseRegion
{
public:
CEnsureReleaseRegion(PVOID pv = NULL) : m_pv(pv) { }
~CEnsureReleaseRegion() { Cleanup(); }
PVOID operator=(PVOID pv)
{
Cleanup();
m_pv = pv;
return(m_pv);
}
operator PVOID() { return(m_pv); }
void Cleanup()
{
if (m_pv != NULL)
{
VirtualFree(m_pv, 0, MEM_RELEASE);
m_pv = NULL;
}
}
private:
PVOID m_pv;
};
///////////////////////////////////////////////////////////////////////////////
// Special class for freeing a block from a heap
// Special class is required because HeapFree requires 3 parameters
class CEnsureHeapFree
{
public:
CEnsureHeapFree(PVOID pv = NULL, HANDLE hHeap = GetProcessHeap())
: m_pv(pv), m_hHeap(hHeap) { }
~CEnsureHeapFree() { Cleanup(); }
PVOID operator=(PVOID pv)
{
Cleanup();
m_pv = pv;
return(m_pv);
}
operator PVOID() { return(m_pv); }
void Cleanup()
{
if (m_pv != NULL)
{
HeapFree(m_hHeap, 0, m_pv);
m_pv = NULL;
}
}
private:
HANDLE m_hHeap;
PVOID m_pv;
};
template<typename T>
class CEnsureDelete
{
public:
CEnsureDelete(T* ptr) : m_ptr(ptr) { }
~CEnsureDelete() { if(NULL != m_ptr) { delete m_ptr; } }
private:
// <20><><EFBFBD><20><> <20><> <20><><EFBFBD><EFBFBD> <20><>.
CEnsureDelete& operator =(const CEnsureDelete& ensureDelete);
CEnsureDelete(const CEnsureDelete& ensureDelete);
T* m_ptr;
};
template<typename T>
class CEnsureDeleteArray
{
public:
CEnsureDeleteArray(T* ptrArray) : m_ptrArray(ptrArray) { }
~CEnsureDeleteArray() { if(NULL != m_ptrArray) { delete [] m_ptrArray; } }
private:
// <20><><EFBFBD><20><> <20><> <20><><EFBFBD><EFBFBD> <20><>.
CEnsureDeleteArray& operator =(const CEnsureDeleteArray& ensureDeleteArray);
CEnsureDeleteArray(const CEnsureDeleteArray& ensureDeleteArray);
T* m_ptrArray;
};
template<typename T>
class CEnsureRelease
{
public:
CEnsureRelease(T& t) : m_t(&t) { }
CEnsureRelease(T* t) : m_t(t) { }
~CEnsureRelease() { if(NULL != m_t) { m_t->Release(); } }
private:
// <20><><EFBFBD><20><> <20><> <20><><EFBFBD><EFBFBD> <20><>.
CEnsureRelease& operator =(const CEnsureRelease& ensureRelease);
CEnsureRelease(const CEnsureRelease& ensureRelease);
T* m_t;
};
#endif

View File

@@ -0,0 +1,264 @@
#include "stdafx.h"
#include "Pulse.h"
#include <mmsystem.h>
#include <BaseLibrary/Log/ServerLog.h>
CPulse& CPulse::GetInstance()
{
static CPulse Pulse;
return Pulse;
}
CPulse::CPulse()
: m_dwPulse(0),
m_dwLastTick(timeGetTime()),
m_dwHeavyTrafficCount(0),
m_bTPPOverTwoTime(FALSE),
m_nTicksPerPulse(0),
m_nTicksPerSec(0)
{
SetTicksPerPulse(DEFAULT_TICKS_PER_PULSE);
}
CPulse::~CPulse()
{
}
void CPulse::SetTicksPerPulse(long nTicksPerPulse)
{
if(nTicksPerPulse <= 0)
{
nTicksPerPulse = DEFAULT_TICKS_PER_PULSE;
}
m_nTicksPerPulse = nTicksPerPulse;
m_nTicksPerSec = 1000 / nTicksPerPulse;
}
unsigned long CPulse::GetRemainTime() const
{
long nElapsed = timeGetTime() - m_dwLastTick;
if (nElapsed < m_nTicksPerPulse)
{
return (m_nTicksPerPulse - nElapsed);
}
return 0;
}
unsigned long CPulse::CheckSleep()
{
long nElapsed = timeGetTime() - m_dwLastTick;
if (nElapsed < m_nTicksPerPulse)
{
// <20><EFBFBD>ð<EFBFBD><C3B0><EFBFBD> TPP<50><50><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> Sleep
unsigned long dwSleep = (m_nTicksPerPulse - nElapsed) - 1;
unsigned long dwTicksPerPulse = m_nTicksPerPulse;
if(m_nTicksPerPulse < 0)
{
dwTicksPerPulse = 0;
}
if(dwTicksPerPulse < dwSleep)
{
dwSleep = 0;
}
Sleep(dwSleep);
m_dwHeavyTrafficCount = 0;
m_bTPPOverTwoTime = FALSE;
}
else if(((++m_dwHeavyTrafficCount) > 5) || (nElapsed > (m_nTicksPerPulse * 2)))
{
// <20><20>ð<EFBFBD><C3B0><EFBFBD> TPP<50><50> <20>ι<CEB9><E8BAB8> ū <20><><EFBFBD><EFBFBD> <20>Ǵ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ʈ<><C6AE><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʹ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
DETLOG3(g_Log, "Time Overflow : Elapsed time is %u, (TPP is %d), HeavyTrafficCount is %u"
, nElapsed, m_nTicksPerPulse, m_dwHeavyTrafficCount);
m_bTPPOverTwoTime = TRUE;
}
else
{
DETLOG1(g_Log, "Traffic is %u", m_dwHeavyTrafficCount);
m_bTPPOverTwoTime = FALSE;
}
m_dwLastTick = timeGetTime();
++m_dwPulse;
if(0 == m_dwPulse)
{
// <20><><EFBFBD><EFBFBD> <20>޽<EFBFBD><DEBD><EFBFBD> <20>ѹ<EFBFBD><D1B9><EFBFBD> <20><><EFBFBD>Ƽ<EFBFBD> <20>ٽ<EFBFBD> 0<><30><EFBFBD><EFBFBD> <20><><EFBFBD>ƿԴٸ<D4B4>,
// <20>ѹ<EFBFBD> <20><> <20><><EFBFBD>ؼ<EFBFBD> 0<><30> <20><> <20><> <20><><EFBFBD><EFBFBD> <20>Ѵ<EFBFBD>.
++m_dwPulse;
}
return m_dwPulse;
}
/*
#include "../stdafx.h"
#include "Pulse.h"
#define DEFAULT_TPP 100
CPulse g_Pulse;
// constructor and destructor
CPulse::CPulse() : m_dwPulse(0), m_dwExtraTick(GetTickCount()), m_dwLastTick(GetTickCount()), m_dwHeavyTrafficCount(0), m_TPPOverTwoTime(false)
//, m_SleepOperation(NULL)
{
SetTicksPerPulse(DEFAULT_TPP);
for (int i=0; i<PULSETABLE_NUM; ++i)
::ZeroMemory(&m_PulseTable[i], sizeof(PULSE_TIMER));
DETLOG1(g_Log, "this:0x%08x.", this);
}
CPulse::~CPulse()
{
DETLOG1(g_Log, "this:0x%08x.", this);
}
void CPulse::SetTicksPerPulse(unsigned long dwTicksPerPulse)
{
m_nTicksPerPulse = dwTicksPerPulse;
}
//void CPulse::SetSleepOperation(Operation pOperation)
//{
// m_SleepOperation = pOperation;
//}
unsigned long CPulse::CheckSleep(void)
{
m_dwExtraTick = GetTickCount();
unsigned long nElapsed = m_dwExtraTick - m_dwLastTick;
if (nElapsed <= m_nTicksPerPulse) {
// <20><EFBFBD>ð<EFBFBD><C3B0><EFBFBD> TPP<50><50><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> Sleep
if (nElapsed < m_nTicksPerPulse) {
//if (m_SleepOperation) {
// // <20><><EFBFBD><EFBFBD> <20><><EFBFBD>۷<EFBFBD><DBB7>̼<EFBFBD><CCBC><EFBFBD> <20><><EFBFBD><EFBFBD>
// m_SleepOperation();
// // <20><><EFBFBD>ν<EFBFBD><CEBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>Ŀ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ð<EFBFBD><C3B0><EFBFBD> Ȯ<><C8AE><EFBFBD>ؼ<EFBFBD> TPP<50><50><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><ECBFA1> Sleep
// m_dwExtraTick = GetTickCount();
// nElapsed = m_dwExtraTick - m_dwLastTick;
// if (nElapsed < m_nTicksPerPulse) {
// Sleep((m_nTicksPerPulse - nElapsed) - 1);
// }
//} else {
Sleep((m_nTicksPerPulse - nElapsed) - 1);
//}
}
m_dwLastTick = GetTickCount();
m_dwHeavyTrafficCount = 0;
m_TPPOverTwoTime = false;
} else if(((++m_dwHeavyTrafficCount) > 5) || (nElapsed > (m_nTicksPerPulse * 2))) {
// <20><20>ð<EFBFBD><C3B0><EFBFBD> TPP<50><50> <20>ι<CEB9><E8BAB8> ū <20><><EFBFBD><EFBFBD> <20>Ǵ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ʈ<><C6AE><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʹ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
DETLOG2(g_Log, "Time Overflow : <20><20>ð<EFBFBD><C3B0><EFBFBD> %d <20><> TPP <20><> <20>ι<CEB9><E8BAB8> ũ<>ų<EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ʈ<><C6AE><EFBFBD><EFBFBD><EFBFBD><EFBFBD> %d <20>Դϴ<D4B4>.", nElapsed, m_dwHeavyTrafficCount);
m_dwLastTick = GetTickCount();
m_TPPOverTwoTime = true;
} else {
DETLOG1(g_Log, "Ʈ<><C6AE><EFBFBD><EFBFBD><EFBFBD><EFBFBD> %d <20>Դϴ<D4B4>.", m_dwHeavyTrafficCount);
// m_nTicksPerPulse < nElapsed <= m_nTicksPerPulse * 2
m_dwLastTick = GetTickCount() - (nElapsed - m_nTicksPerPulse);
m_TPPOverTwoTime = false;
}
return ++m_dwPulse;
}
bool CPulse::InstallTimer(int nOperation, unsigned long dwPulse, Operation pOperation)
{
if (nOperation <= 0 || nOperation >= PULSETABLE_NUM) {
return false;
}
for (int i=0; i < PULSETABLE_NUM; ++i) {
if (0 == m_PulseTable[i].m_nOperation) {
m_PulseTable[i].m_nOperation = nOperation;
m_PulseTable[i].m_dwPulse = dwPulse;
m_PulseTable[i].m_pOperation = pOperation;
return true;
}
}
// TODO : <20><><EFBFBD><EFBFBD><EFBFBD>α<EFBFBD>
return false;
}
bool CPulse::UninstallTimer(int nOperation)
{
if(nOperation <= 0 || nOperation >= PULSETABLE_NUM)
{
return false;
}
for (int i=0; i<PULSETABLE_NUM; ++i) {
if (nOperation == m_PulseTable[i].m_nOperation) {
m_PulseTable[i].m_nOperation = 0;
m_PulseTable[i].m_dwPulse = 0;
m_PulseTable[i].m_pOperation = NULL;
// TODO : <20><><EFBFBD>̺<EFBFBD><CCBA><EFBFBD> shift up
ShiftupTable(i + 1);
return true;
}
}
// TODO : <20><><EFBFBD><EFBFBD><EFBFBD>α<EFBFBD>
return false;
}
void CPulse::Operate(void)
{
int i = 0;
while (m_PulseTable[i].m_nOperation) {
if (0 == (GetCurrentPulse() % m_PulseTable[i].m_dwPulse)) {
if (m_PulseTable[i].m_nOperation) {
m_PulseTable[i].m_pOperation();
}
}
++i;
}
}
void CPulse::ShiftupTable(int nStartIndex)
{
for (int i=nStartIndex; i<(PULSETABLE_NUM - 1); ++i) {
// TODO : <20><><EFBFBD>̺<EFBFBD><CCBA><EFBFBD> shift up
m_PulseTable[i].m_nOperation = m_PulseTable[i+1].m_nOperation;
m_PulseTable[i].m_dwPulse = m_PulseTable[i+1].m_dwPulse;
m_PulseTable[i].m_pOperation = m_PulseTable[i+1].m_pOperation;
}
m_PulseTable[PULSETABLE_NUM].m_nOperation = 0;
m_PulseTable[PULSETABLE_NUM].m_dwPulse = 0;
m_PulseTable[PULSETABLE_NUM].m_pOperation = NULL;
}
*/

View File

@@ -0,0 +1,53 @@
#ifndef _RYL_BASE_LIBRARY_PULSE_H_
#define _RYL_BASE_LIBRARY_PULSE_H_
#include <winsock2.h>
#include <windows.h>
#pragma comment(lib, "winmm.lib")
// Single Thread<61><64><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
class CPulse
{
public:
enum PulseConst
{
DEFAULT_TICKS_PER_PULSE = 100
};
static CPulse& GetInstance();
unsigned long CheckSleep();
void SetTicksPerPulse(long nTicksPerPulse);
long GetTicksPerPulse() const { return m_nTicksPerPulse; }
long GetTicksPerSec() const { return m_nTicksPerSec; }
unsigned long GetRemainTime() const;
BOOL GetTPPOverTwoTime() const { return m_bTPPOverTwoTime; }
unsigned long GetCurrentPulse() const { return m_dwPulse; }
unsigned long GetLastTick() const { return m_dwLastTick; }
inline bool ProcessBySecond(unsigned long dwCycleSec) const { return (0 == (m_dwPulse % (dwCycleSec * m_nTicksPerSec))); }
inline bool ProcessByMinute(unsigned long dwCycleMin) const { return ProcessBySecond(dwCycleMin * 60); }
inline bool ProcessByHour(unsigned long dwCycleHour) const { return ProcessBySecond(dwCycleHour * 3600); }
private:
CPulse();
~CPulse();
unsigned long m_dwPulse;
unsigned long m_dwLastTick;
unsigned long m_dwHeavyTrafficCount;
long m_nTicksPerPulse;
long m_nTicksPerSec;
BOOL m_bTPPOverTwoTime;
};
#endif

View File

@@ -0,0 +1,23 @@
#ifndef _COMMON_H_
#define _COMMON_H_
#ifndef _QWORD_DEFINED
#define _QWORD_DEFINED
typedef __int64 QWORD, *LPQWORD;
#endif
#define MAKEQWORD(a, b) \
((QWORD)( ((QWORD) ((unsigned long) (a))) << 32 | ((unsigned long) (b))))
#define LODWORD(l) \
((unsigned long)(l))
#define HIDWORD(l) \
((unsigned long)(((QWORD)(l) >> 32) & 0xFFFFFFFF))
// Read 4K of data at a time (used in the C++ streams, Win32 I/O, and assembly functions)
#define MAX_BUFFER_SIZE 4096
// Map a "view" size of 10MB (used in the filemap function)
#define MAX_VIEW_SIZE 10485760
#endif

View File

@@ -0,0 +1,371 @@
#include "stdafx.h"
#include <crtdbg.h>
#include "Common.h"
#include "Crc32Static.h"
using namespace std;
// Static CRC table
unsigned long CCrc32Static::s_arrdwCrc32Table[256] =
{
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940,
0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116,
0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A,
0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818,
0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C,
0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086,
0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4,
0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE,
0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252,
0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60,
0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04,
0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E,
0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0,
0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6,
0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D,
};
//***********************************************
CCrc32Static::CCrc32Static()
{
}
//***********************************************
CCrc32Static::~CCrc32Static()
{
}
//***********************************************
inline void CCrc32Static::CalcCrc32(const BYTE byte, unsigned long &dwCrc32)
{
dwCrc32 = ((dwCrc32) >> 8) ^ s_arrdwCrc32Table[(byte) ^ ((dwCrc32) & 0x000000FF)];
}
//***********************************************
bool CCrc32Static::GetFileSizeQW(const HANDLE hFile, QWORD &qwSize)
{
_ASSERTE(hFile != INVALID_HANDLE_VALUE);
bool bSuccess = true;
try
{
unsigned long dwLo = 0, dwHi = 0;
dwLo = GetFileSize(hFile, &dwHi);
if(dwLo == INVALID_FILE_SIZE && GetLastError() != NO_ERROR)
{
bSuccess = false;
qwSize = 0;
}
else
{
qwSize = MAKEQWORD(dwHi, dwLo);
}
}
catch (...)
{
bSuccess = false;
}
return bSuccess;
}
//***********************************************
unsigned long CCrc32Static::StringCrc32(LPCTSTR szString, unsigned long &dwCrc32)
{
_ASSERTE(szString);
unsigned long dwErrorCode = NO_ERROR;
dwCrc32 = 0xFFFFFFFF;
try
{
while (*szString != _T('\0'))
{
CalcCrc32((BYTE)*szString, dwCrc32);
szString++;
}
}
catch (...)
{
// An unknown exception happened
dwErrorCode = ERROR_CRC;
}
dwCrc32 = ~dwCrc32;
return dwErrorCode;
}
//***********************************************
unsigned long CCrc32Static::BufferCrc32(const char *szBuffer, size_t size, unsigned long &dwCrc32)
{
_ASSERTE(szBuffer);
unsigned long dwErrorCode = NO_ERROR;
dwCrc32 = 0xFFFFFFFF;
try
{
for (size_t nIndex = 0; nIndex < size; ++nIndex)
{
CalcCrc32((BYTE)*szBuffer, dwCrc32);
++szBuffer;
}
}
catch (...)
{
// An unknown exception happened
dwErrorCode = ERROR_CRC;
}
dwCrc32 = ~dwCrc32;
return dwErrorCode;
}
//***********************************************
unsigned long CCrc32Static::FileCrc32Filemap(LPCTSTR szFilename, unsigned long &dwCrc32)
{
_ASSERTE(szFilename);
_ASSERTE(lstrlen(szFilename));
unsigned long dwErrorCode = NO_ERROR;
HANDLE hFile = NULL, hFilemap = NULL;
dwCrc32 = 0xFFFFFFFF;
try
{
// Open the file
hFile = CreateFile(szFilename,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_SEQUENTIAL_SCAN,
NULL);
if(hFile == INVALID_HANDLE_VALUE)
dwErrorCode = GetLastError();
else
{
QWORD qwFileSize = 0, qwFileOffset = 0;
unsigned long dwByteCount, dwViewSize;
unsigned long dwBaseAddress;
// Get the file size
if(!GetFileSizeQW(hFile, qwFileSize))
dwErrorCode = ERROR_BAD_LENGTH;
else if(qwFileSize != 0) // We cannot CRC zero byte files
{
// Create the file mapping
hFilemap = CreateFileMapping(hFile,
NULL,
PAGE_READONLY,
0,
0,
NULL);
if(hFilemap == NULL)
dwErrorCode = GetLastError();
else
{
LPBYTE pByte;
// Loop while we map a section of the file and CRC it
while (qwFileSize > 0)
{
if(qwFileSize < MAX_VIEW_SIZE)
dwViewSize = LODWORD(qwFileSize);
else
dwViewSize = MAX_VIEW_SIZE;
dwBaseAddress = (unsigned long)MapViewOfFile(hFilemap,
FILE_MAP_READ,
HIDWORD(qwFileOffset),
LODWORD(qwFileOffset),
dwViewSize);
dwByteCount = dwViewSize;
pByte = (LPBYTE)dwBaseAddress;
while (dwByteCount-- > 0)
{
CalcCrc32(*pByte, dwCrc32);
pByte++;
}
UnmapViewOfFile((LPVOID)dwBaseAddress);
qwFileOffset += dwViewSize;
qwFileSize -= dwViewSize;
}
}
}
}
}
catch (...)
{
// An unknown exception happened
dwErrorCode = ERROR_CRC;
}
if(hFile != NULL) CloseHandle(hFile);
if(hFilemap != NULL) CloseHandle(hFilemap);
dwCrc32 = ~dwCrc32;
return dwErrorCode;
}
//***********************************************
unsigned long CCrc32Static::FileCrc32Assembly(LPCTSTR szFilename, unsigned long &dwCrc32)
{
_ASSERTE(szFilename);
_ASSERTE(lstrlen(szFilename));
unsigned long dwErrorCode = NO_ERROR;
HANDLE hFile = NULL;
dwCrc32 = 0xFFFFFFFF;
try
{
// Open the file
hFile = CreateFile(szFilename,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_SEQUENTIAL_SCAN,
NULL);
if(hFile == INVALID_HANDLE_VALUE)
dwErrorCode = GetLastError();
else
{
// There is a bug in the Microsoft compilers where inline assembly
// code cannot access static member variables. This is a work around
// for that bug. For more info see Knowledgebase article Q88092
LPVOID ptrCrc32Table = &s_arrdwCrc32Table;
BYTE buffer[MAX_BUFFER_SIZE];
unsigned long dwBytesRead;
BOOL bSuccess = ReadFile(hFile, buffer, sizeof(buffer), &dwBytesRead, NULL);
while (bSuccess && dwBytesRead)
{
// Register use:
// eax - CRC32 value
// ebx - a lot of things
// ecx - CRC32 value
// edx - address of end of buffer
// esi - address of start of buffer
// edi - CRC32 table
__asm
{
// Save the esi and edi registers
push esi
push edi
mov eax, dwCrc32 // Load the pointer to dwCrc32
mov ecx, [eax] // Dereference the pointer to load dwCrc32
mov edi, ptrCrc32Table // Load the CRC32 table
lea esi, buffer // Load buffer
mov ebx, dwBytesRead // Load dwBytesRead
lea edx, [esi + ebx] // Calculate the end of the buffer
crc32loop:
xor eax, eax // Clear the eax register
mov bl, byte ptr [esi] // Load the current source byte
mov al, cl // Copy crc value into eax
inc esi // Advance the source pointer
xor al, bl // Create the index into the CRC32 table
shr ecx, 8
mov ebx, [edi + eax * 4] // Get the value out of the table
xor ecx, ebx // xor with the current byte
cmp edx, esi // Have we reached the end of the buffer?
jne crc32loop
// Restore the edi and esi registers
pop edi
pop esi
mov eax, dwCrc32 // Load the pointer to dwCrc32
mov [eax], ecx // Write the result
}
bSuccess = ReadFile(hFile, buffer, sizeof(buffer), &dwBytesRead, NULL);
}
}
}
catch (...)
{
// An unknown exception happened
dwErrorCode = ERROR_CRC;
}
if(hFile != NULL) CloseHandle(hFile);
dwCrc32 = ~dwCrc32;
return dwErrorCode;
}

View File

@@ -0,0 +1,27 @@
#ifndef _CRC32STATIC_H_
#define _CRC32STATIC_H_
#include <windows.h>
class CCrc32Static
{
public:
CCrc32Static();
virtual ~CCrc32Static();
static unsigned long StringCrc32(const char *szString, unsigned long &dwCrc32);
static unsigned long BufferCrc32(const char *szBuffer, size_t size, unsigned long &dwCrc32);
static unsigned long FileCrc32Win32(const char *szFilename, unsigned long &dwCrc32);
static unsigned long FileCrc32Filemap(const char *szFilename, unsigned long &dwCrc32);
static unsigned long FileCrc32Assembly(const char *szFilename, unsigned long &dwCrc32);
protected:
static bool GetFileSizeQW(const HANDLE hFile, __int64 &qwSize);
static inline void CalcCrc32(const unsigned char byte, unsigned long &dwCrc32);
static unsigned long s_arrdwCrc32Table[256];
};
#endif

View File

@@ -0,0 +1,72 @@
#include "stdafx.h"
#include "Crc8Static.h"
unsigned char CCrc8Static::s_arrcCrc8Table[] = {
0x00, 0x5e, 0xbc, 0xe2, 0x61, 0x3f, 0xdd, 0x83,
0xc2, 0x9c, 0x7e, 0x20, 0xa3, 0xfd, 0x1f, 0x41,
0x9d, 0xc3, 0x21, 0x7f, 0xfc, 0xa2, 0x40, 0x1e,
0x5f, 0x01, 0xe3, 0xbd, 0x3e, 0x60, 0x82, 0xdc,
0x23, 0x7d, 0x9f, 0xc1, 0x42, 0x1c, 0xfe, 0xa0,
0xe1, 0xbf, 0x5d, 0x03, 0x80, 0xde, 0x3c, 0x62,
0xbe, 0xe0, 0x02, 0x5c, 0xdf, 0x81, 0x63, 0x3d,
0x7c, 0x22, 0xc0, 0x9e, 0x1d, 0x43, 0xa1, 0xff,
0x46, 0x18, 0xfa, 0xa4, 0x27, 0x79, 0x9b, 0xc5,
0x84, 0xda, 0x38, 0x66, 0xe5, 0xbb, 0x59, 0x07,
0xdb, 0x85, 0x67, 0x39, 0xba, 0xe4, 0x06, 0x58,
0x19, 0x47, 0xa5, 0xfb, 0x78, 0x26, 0xc4, 0x9a,
0x65, 0x3b, 0xd9, 0x87, 0x04, 0x5a, 0xb8, 0xe6,
0xa7, 0xf9, 0x1b, 0x45, 0xc6, 0x98, 0x7a, 0x24,
0xf8, 0xa6, 0x44, 0x1a, 0x99, 0xc7, 0x25, 0x7b,
0x3a, 0x64, 0x86, 0xd8, 0x5b, 0x05, 0xe7, 0xb9,
0x8c, 0xd2, 0x30, 0x6e, 0xed, 0xb3, 0x51, 0x0f,
0x4e, 0x10, 0xf2, 0xac, 0x2f, 0x71, 0x93, 0xcd,
0x11, 0x4f, 0xad, 0xf3, 0x70, 0x2e, 0xcc, 0x92,
0xd3, 0x8d, 0x6f, 0x31, 0xb2, 0xec, 0x0e, 0x50,
0xaf, 0xf1, 0x13, 0x4d, 0xce, 0x90, 0x72, 0x2c,
0x6d, 0x33, 0xd1, 0x8f, 0x0c, 0x52, 0xb0, 0xee,
0x32, 0x6c, 0x8e, 0xd0, 0x53, 0x0d, 0xef, 0xb1,
0xf0, 0xae, 0x4c, 0x12, 0x91, 0xcf, 0x2d, 0x73,
0xca, 0x94, 0x76, 0x28, 0xab, 0xf5, 0x17, 0x49,
0x08, 0x56, 0xb4, 0xea, 0x69, 0x37, 0xd5, 0x8b,
0x57, 0x09, 0xeb, 0xb5, 0x36, 0x68, 0x8a, 0xd4,
0x95, 0xcb, 0x29, 0x77, 0xf4, 0xaa, 0x48, 0x16,
0xe9, 0xb7, 0x55, 0x0b, 0x88, 0xd6, 0x34, 0x6a,
0x2b, 0x75, 0x97, 0xc9, 0x4a, 0x14, 0xf6, 0xa8,
0x74, 0x2a, 0xc8, 0x96, 0x15, 0x4b, 0xa9, 0xf7,
0xb6, 0xe8, 0x0a, 0x54, 0xd7, 0x89, 0x6b, 0x35,
};
/********************************************************************\
Routine: crc8
Purpose: Calculate 8-bit cyclic redundancy checksum for a full
buffer
Input:
unsigned char *data data buffer
int len data length in bytes
Function value:
unsighend char CRC-8 code
\********************************************************************/
unsigned char CCrc8Static::BufferCrc8(const char *szBuffer, size_t size)
{
const char* szBufferPos = szBuffer;
const char* szBufferEnd = szBuffer + size;
unsigned char crc8_code = 0;
unsigned char nIndex = 0;
for (; szBufferPos != szBufferEnd; ++szBufferPos)
{
nIndex = (*szBufferPos) ^ crc8_code;
crc8_code = s_arrcCrc8Table[nIndex];
}
return crc8_code;
}

View File

@@ -0,0 +1,18 @@
#ifndef _CRC8STATIC_H_
#define _CRC8STATIC_H_
#include "Common.h"
class CCrc8Static
{
public:
static unsigned char StringCrc8(const char *szString) { return BufferCrc8(szString, strlen(szString)); }
static unsigned char BufferCrc8(const char *szBuffer, size_t size);
protected:
static unsigned char s_arrcCrc8Table[256];
};
#endif

View File

@@ -0,0 +1,69 @@
// Boost config.hpp configuration header file ------------------------------//
// (C) Copyright Boost.org 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.
// See http://www.boost.org for most recent version.
// Boost config.hpp policy and rationale documentation has been moved to
// http://www.boost.org/libs/config
//
// CAUTION: This file is intended to be completely stable -
// DO NOT MODIFY THIS FILE!
//
#ifndef BOOST_CONFIG_HPP
#define BOOST_CONFIG_HPP
// if we don't have a user config, then use the default location:
#if !defined(BOOST_USER_CONFIG) && !defined(BOOST_NO_USER_CONFIG)
# define BOOST_USER_CONFIG <boost/config/user.hpp>
#endif
// include it first:
#ifdef BOOST_USER_CONFIG
# include BOOST_USER_CONFIG
#endif
// if we don't have a compiler config set, try and find one:
#if !defined(BOOST_COMPILER_CONFIG) && !defined(BOOST_NO_COMPILER_CONFIG) && !defined(BOOST_NO_CONFIG)
# include <boost/config/select_compiler_config.hpp>
#endif
// if we have a compiler config, include it now:
#ifdef BOOST_COMPILER_CONFIG
# include BOOST_COMPILER_CONFIG
#endif
// if we don't have a std library config set, try and find one:
#if !defined(BOOST_STDLIB_CONFIG) && !defined(BOOST_NO_STDLIB_CONFIG) && !defined(BOOST_NO_CONFIG)
# include <boost/config/select_stdlib_config.hpp>
#endif
// if we have a std library config, include it now:
#ifdef BOOST_STDLIB_CONFIG
# include BOOST_STDLIB_CONFIG
#endif
// if we don't have a platform config set, try and find one:
#if !defined(BOOST_PLATFORM_CONFIG) && !defined(BOOST_NO_PLATFORM_CONFIG) && !defined(BOOST_NO_CONFIG)
# include <boost/config/select_platform_config.hpp>
#endif
// if we have a platform config, include it now:
#ifdef BOOST_PLATFORM_CONFIG
# include BOOST_PLATFORM_CONFIG
#endif
// get config suffix code:
#include <boost/config/suffix.hpp>
#endif // BOOST_CONFIG_HPP

View File

@@ -0,0 +1,114 @@
// (C) Copyright Boost.org 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.
// See http://www.boost.org for most recent version.
// Microsoft Visual C++ compiler setup:
#define BOOST_MSVC _MSC_VER
// turn off the warnings before we #include anything
#pragma warning( disable : 4503 ) // warning: decorated name length exceeded
#if _MSC_VER <= 1200 // 1200 == VC++ 6.0
#pragma warning( disable : 4786 ) // ident trunc to '255' chars in debug info
# define BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS
# define BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS
# define BOOST_NO_VOID_RETURNS
# define BOOST_NO_EXCEPTION_STD_NAMESPACE
# define BOOST_NO_DEDUCED_TYPENAME
// disable min/max macro defines on vc6:
//
#endif
#if (_MSC_VER <= 1300) // 1200 == VC++ 7.0
#if !defined(_MSC_EXTENSIONS) && !defined(BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS) // VC7 bug with /Za
# define BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS
#endif
# define BOOST_NO_INCLASS_MEMBER_INITIALIZATION
# define BOOST_NO_PRIVATE_IN_AGGREGATE
# define BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
# define BOOST_NO_INTEGRAL_INT64_T
// VC++ 6/7 has member templates but they have numerous problems including
// cases of silent failure, so for safety we define:
# define BOOST_NO_MEMBER_TEMPLATES
// For VC++ experts wishing to attempt workarounds, we define:
# define BOOST_MSVC6_MEMBER_TEMPLATES
# define BOOST_NO_MEMBER_TEMPLATE_FRIENDS
# define BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
# define BOOST_NO_CV_VOID_SPECIALIZATIONS
# define BOOST_NO_FUNCTION_TEMPLATE_ORDERING
# define BOOST_NO_USING_TEMPLATE
# define BOOST_NO_SWPRINTF
# define BOOST_NO_TEMPLATE_TEMPLATES
# if (_MSC_VER > 1200)
# define BOOST_NO_MEMBER_FUNCTION_SPECIALIZATIONS
# endif
#endif
#if _MSC_VER < 1310 // 1310 == VC++ 7.1
# define BOOST_NO_SWPRINTF
#endif
#if _MSC_VER <= 1310
# define BOOST_NO_MEMBER_TEMPLATE_FRIENDS
#endif
#ifndef _NATIVE_WCHAR_T_DEFINED
# define BOOST_NO_INTRINSIC_WCHAR_T
#endif
//
// check for exception handling support:
#ifndef _CPPUNWIND
# define BOOST_NO_EXCEPTIONS
#endif
//
// __int64 support:
//
#if (_MSC_VER >= 1200) && defined(_MSC_EXTENSIONS)
# define BOOST_HAS_MS_INT64
#endif
#if (_MSC_VER >= 1310) && defined(_MSC_EXTENSIONS)
# define BOOST_HAS_LONG_LONG
#endif
//
// disable Win32 API's if compiler extentions are
// turned off:
//
#ifndef _MSC_EXTENSIONS
# define BOOST_DISABLE_WIN32
#endif
# if _MSC_VER == 1200
# define BOOST_COMPILER_VERSION 6.0
# elif _MSC_VER == 1300
# define BOOST_COMPILER_VERSION 7.0
# elif _MSC_VER == 1310
# define BOOST_COMPILER_VERSION 7.1
# else
# define BOOST_COMPILER_VERSION _MSC_VER
# endif
#define BOOST_COMPILER "Microsoft Visual C++ version " BOOST_STRINGIZE(BOOST_COMPILER_VERSION)
//
// versions check:
// we don't support Visual C++ prior to version 6:
#if _MSC_VER < 1200
#error "Compiler not supported or configured - please reconfigure"
#endif
//

View File

@@ -0,0 +1,28 @@
// (C) Copyright John Maddock 2005.
// Use, modification and distribution are subject to the
// Boost Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// The aim of this header is just to include <utility> but to do
// so in a way that does not result in recursive inclusion of
// the Boost TR1 components if boost/tr1/tr1/utility is in the
// include search path. We have to do this to avoid circular
// dependencies:
//
#ifndef BOOST_CONFIG_UTILITY
# define BOOST_CONFIG_UTILITY
# ifndef BOOST_TR1_NO_RECURSION
# define BOOST_TR1_NO_RECURSION
# define BOOST_CONFIG_NO_UTILITY_RECURSION
# endif
# include <utility>
# ifdef BOOST_CONFIG_NO_UTILITY_RECURSION
# undef BOOST_TR1_NO_RECURSION
# undef BOOST_CONFIG_NO_UTILITY_RECURSION
# endif
#endif

View File

@@ -0,0 +1,72 @@
// (C) Copyright Boost.org 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.
// See http://www.boost.org for most recent version.
// Win32 specific config options:
#define BOOST_PLATFORM "Win32"
#if defined(__GNUC__) && !defined(BOOST_NO_SWPRINTF)
# define BOOST_NO_SWPRINTF
#endif
//
// Win32 will normally be using native Win32 threads,
// but there is a pthread library avaliable as an option,
// we used to disable this when BOOST_DISABLE_WIN32 was
// defined but no longer - this should allow some
// files to be compiled in strict mode - while maintaining
// a consistent setting of BOOST_HAS_THREADS across
// all translation units (needed for shared_ptr etc).
//
#ifndef BOOST_HAS_PTHREADS
# define BOOST_HAS_WINTHREADS
#endif
#ifndef BOOST_DISABLE_WIN32
// WEK: Added
#define BOOST_HAS_FTIME
#endif
//
// disable min/max macros:
//
#ifdef min
# undef min
#endif
#ifdef max
# undef max
#endif
#ifndef NOMINMAX
# define NOMINMAX
#endif
#ifdef BOOST_MSVC
namespace std{
// Apparently, something in the Microsoft libraries requires the "long"
// overload, because it calls the min/max functions with arguments of
// slightly different type. (If this proves to be incorrect, this
// whole "BOOST_MSVC" section can be removed.)
inline long min(long __a, long __b) {
return __b < __a ? __b : __a;
}
inline long max(long __a, long __b) {
return __a < __b ? __b : __a;
}
// The "long double" overload is required, otherwise user code calling
// min/max for floating-point numbers will use the "long" overload.
// (SourceForge bug #495495)
inline long double min(long double __a, long double __b) {
return __b < __a ? __b : __a;
}
inline long double max(long double __a, long double __b) {
return __a < __b ? __b : __a;
}
}
using std::min;
using std::max;
# endif

View File

@@ -0,0 +1,78 @@
// Boost compiler configuration selection header file
// (C) Copyright Boost.org 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.
// See http://www.boost.org for most recent version.
// locate which compiler we are using and define
// BOOST_COMPILER_CONFIG as needed:
# if defined __COMO__
// Comeau C++
# define BOOST_COMPILER_CONFIG "boost/config/compiler/comeau.hpp"
#elif defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC) || defined(__ECC)
// Intel
# define BOOST_COMPILER_CONFIG "boost/config/compiler/intel.hpp"
# elif defined __GNUC__
// GNU C++:
# define BOOST_COMPILER_CONFIG "boost/config/compiler/gcc.hpp"
#elif defined __KCC
// Kai C++
# define BOOST_COMPILER_CONFIG "boost/config/compiler/kai.hpp"
#elif defined __sgi
// SGI MIPSpro C++
# define BOOST_COMPILER_CONFIG "boost/config/compiler/sgi_mipspro.hpp"
#elif defined __DECCXX
// Compaq Tru64 Unix cxx
# define BOOST_COMPILER_CONFIG "boost/config/compiler/compaq_cxx.hpp"
#elif defined __ghs
// Greenhills C++
# define BOOST_COMPILER_CONFIG "boost/config/compiler/greenhills.hpp"
#elif defined __BORLANDC__
// Borland
# define BOOST_COMPILER_CONFIG "boost/config/compiler/borland.hpp"
#elif defined __MWERKS__
// Metrowerks CodeWarrior
# define BOOST_COMPILER_CONFIG "boost/config/compiler/metrowerks.hpp"
#elif defined __SUNPRO_CC
// Sun Workshop Compiler C++
# define BOOST_COMPILER_CONFIG "boost/config/compiler/sunpro_cc.hpp"
#elif defined __HP_aCC
// HP aCC
# define BOOST_COMPILER_CONFIG "boost/config/compiler/hp_acc.hpp"
#elif defined(__MRC__) || defined(__SC__)
// MPW MrCpp or SCpp
# define BOOST_COMPILER_CONFIG "boost/config/compiler/mpw.hpp"
#elif defined(__IBMCPP__)
// IBM Visual Age
# define BOOST_COMPILER_CONFIG "boost/config/compiler/vacpp.hpp"
#elif defined _MSC_VER
// Microsoft Visual C++
//
// Must remain the last #elif since some other vendors (Metrowerks, for
// example) also #define _MSC_VER
# define BOOST_COMPILER_CONFIG "boost/config/compiler/visualc.hpp"
#elif defined (BOOST_ASSERT_CONFIG)
// this must come last - generate an error if we don't
// recognise the compiler:
# error "Unknown compiler - please configure and report the results to boost.org"
#endif

View File

@@ -0,0 +1,84 @@
// Boost compiler configuration selection header file
// (C) Copyright Boost.org 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.
// See http://www.boost.org for most recent version.
// locate which platform we are on and define BOOST_PLATFORM_CONFIG as needed.
// Note that we define the headers to include using "header_name" not
// <header_name> in order to prevent macro expansion within the header
// name (for example "linux" is a macro on linux systems).
#if defined(linux) || defined(__linux) || defined(__linux__)
// linux:
# define BOOST_PLATFORM_CONFIG "boost/config/platform/linux.hpp"
#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
// BSD:
# define BOOST_PLATFORM_CONFIG "boost/config/platform/bsd.hpp"
#elif defined(sun) || defined(__sun)
// solaris:
# define BOOST_PLATFORM_CONFIG "boost/config/platform/solaris.hpp"
#elif defined(__sgi)
// SGI Irix:
# define BOOST_PLATFORM_CONFIG "boost/config/platform/irix.hpp"
#elif defined(__hpux)
// hp unix:
# define BOOST_PLATFORM_CONFIG "boost/config/platform/hpux.hpp"
#elif defined(__CYGWIN__)
// cygwin is not win32:
# define BOOST_PLATFORM_CONFIG "boost/config/platform/cygwin.hpp"
#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
// win32:
# define BOOST_PLATFORM_CONFIG "boost/config/platform/win32.hpp"
#elif defined(__BEOS__)
// BeOS
# define BOOST_PLATFORM_CONFIG "boost/config/platform/beos.hpp"
#elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)
// MacOS
# define BOOST_PLATFORM_CONFIG "boost/config/platform/macos.hpp"
#elif defined(__IBMCPP__)
// IBM
# define BOOST_PLATFORM_CONFIG "boost/config/platform/aix.hpp"
#elif defined(__amigaos__)
// AmigaOS
# define BOOST_PLATFORM_CONFIG "boost/config/platform/amigaos.hpp"
#else
# if defined(unix) \
|| defined(__unix) \
|| defined(_XOPEN_SOURCE) \
|| defined(_POSIX_SOURCE)
// generic unix platform:
# ifndef BOOST_HAS_UNISTD_H
# define BOOST_HAS_UNISTD_H
# endif
# include <boost/config/posix_features.hpp>
# endif
# if defined (BOOST_ASSERT_CONFIG)
// this must come last - generate an error if we don't
// recognise the platform:
# error "Unknown platform - please configure and report the results to boost.org"
# endif
#endif

View File

@@ -0,0 +1,65 @@
// Boost compiler configuration selection header file
// (C) Copyright Boost.org 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.
// See http://www.boost.org for most recent version.
// locate which std lib we are using and define BOOST_STDLIB_CONFIG as needed:
// we need to include a std lib header here in order to detect which
// library is in use, use <utility> as it's about the smallest
// of the std lib headers - do not rely on this header being included -
// users can short-circuit this header if they know whose std lib
// they are using.
#include <utility>
#if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)
// STLPort library; this _must_ come first, otherwise since
// STLport typically sits on top of some other library, we
// can end up detecting that first rather than STLport:
# define BOOST_STDLIB_CONFIG "boost/config/stdlib/stlport.hpp"
#elif defined(__LIBCOMO__)
// Comeau STL:
#define BOOST_STDLIB_CONFIG "boost/config/stdlib/libcomo.hpp"
#elif defined(__STD_RWCOMPILER_H__) || defined(_RWSTD_VER)
// Rogue Wave library:
# define BOOST_STDLIB_CONFIG "boost/config/stdlib/roguewave.hpp"
#elif defined(__GLIBCPP__)
// GNU libstdc++ 3
# define BOOST_STDLIB_CONFIG "boost/config/stdlib/libstdcpp3.hpp"
#elif defined(__STL_CONFIG_H)
// generic SGI STL
# define BOOST_STDLIB_CONFIG "boost/config/stdlib/sgi.hpp"
#elif defined(__MSL_CPP__)
// MSL standard lib:
# define BOOST_STDLIB_CONFIG "boost/config/stdlib/msl.hpp"
#elif defined(__IBMCPP__)
// take the default VACPP std lib
# define BOOST_STDLIB_CONFIG "boost/config/stdlib/vacpp.hpp"
#elif defined(MSIPL_COMPILE_H)
// Modena C++ standard library
# define BOOST_STDLIB_CONFIG "boost/config/stdlib/modena.hpp"
#elif (defined(_YVALS) && !defined(__IBMCPP__)) || defined(_CPPLIB_VER)
// Dinkumware Library (this has to appear after any possible replacement libraries):
# define BOOST_STDLIB_CONFIG "boost/config/stdlib/dinkumware.hpp"
#elif defined (BOOST_ASSERT_CONFIG)
// this must come last - generate an error if we don't
// recognise the library:
# error "Unknown standard library - please configure and report the results to boost.org"
#endif

View File

@@ -0,0 +1,82 @@
// (C) Copyright Boost.org 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.
// See http://www.boost.org for most recent version.
// Dinkumware standard library config:
#if !defined(_YVALS) && !defined(_CPPLIB_VER)
#include <utility>
#if !defined(_YVALS) && !defined(_CPPLIB_VER)
#error This is not the Dinkumware lib!
#endif
#endif
#if defined(_CPPLIB_VER) && (_CPPLIB_VER >= 306)
// full dinkumware 3.06 and above
// fully conforming provided the compiler supports it:
# if !(defined(_GLOBAL_USING) && (_GLOBAL_USING+0 > 0)) && !defined(_STD) // can be defined in yvals.h
# define BOOST_NO_STDC_NAMESPACE
# endif
# if !(defined(_HAS_MEMBER_TEMPLATES_REBIND) && (_HAS_MEMBER_TEMPLATES_REBIND+0 > 0)) && !(defined(_MSC_VER) && (_MSC_VER > 1300))
# define BOOST_NO_STD_ALLOCATOR
# endif
# if defined(_MSC_VER) && (_MSC_VER < 1300)
// if this lib version is set up for vc6 then there is no std::use_facet:
# define BOOST_NO_STD_USE_FACET
# define BOOST_HAS_TWO_ARG_USE_FACET
// C lib functions aren't in namespace std either:
# define BOOST_NO_STDC_NAMESPACE
// and nor is <exception>
# define BOOST_NO_EXCEPTION_STD_NAMESPACE
# endif
// There's no numeric_limits<long long> support unless _LONGLONG is defined:
# if !defined(_LONGLONG) && (_CPPLIB_VER <= 310)
# define BOOST_NO_MS_INT64_NUMERIC_LIMITS
# endif
// 3.06 appears to have (non-sgi versions of) <hash_set> & <hash_map>,
// and no <slist> at all
#else
# define BOOST_MSVC_STD_ITERATOR 1
# define BOOST_NO_STD_ITERATOR
# define BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS
# define BOOST_NO_STD_ALLOCATOR
# define BOOST_NO_STDC_NAMESPACE
# define BOOST_NO_STD_USE_FACET
# define BOOST_NO_STD_OUTPUT_ITERATOR_ASSIGN
# define BOOST_HAS_MACRO_USE_FACET
# ifndef _CPPLIB_VER
// Updated Dinkum library defines this, and provides
// its own min and max definitions.
# define BOOST_NO_STD_MIN_MAX
# define BOOST_NO_MS_INT64_NUMERIC_LIMITS
# endif
#endif
#if (defined(_MSC_VER) && (_MSC_VER <= 1300)) || !defined(_CPPLIB_VER) || (_CPPLIB_VER < 306)
// if we're using a dinkum lib that's
// been configured for VC6/7 then there is
// no iterator traits (true even for icl)
# define BOOST_NO_STD_ITERATOR_TRAITS
#endif
#if defined(__ICL) && defined(_CPPLIB_VER) && (_CPPLIB_VER <= 310)
// Intel C++ chokes over any non-trivial use of <locale>
// this may be an overly restrictive define, but regex fails without it:
# define BOOST_NO_STD_LOCALE
#endif
#ifdef _CPPLIB_VER
# define BOOST_STDLIB "Dinkumware standard library version " BOOST_STRINGIZE(_CPPLIB_VER)
#else
# define BOOST_STDLIB "Dinkumware standard library version 1.x"
#endif

View File

@@ -0,0 +1,383 @@
// Boost config.hpp configuration header file ------------------------------//
// (C) Copyright Boost.org 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.
// See http://www.boost.org for most recent version.
// Boost config.hpp policy and rationale documentation has been moved to
// http://www.boost.org/libs/config
//
// This file is intended to be stable, and relatively unchanging.
// It should contain boilerplate code only - no compiler specific
// code unless it is unavoidable - no changes unless unavoidable.
#ifndef BOOST_CONFIG_SUFFIX_HPP
#define BOOST_CONFIG_SUFFIX_HPP
//
// look for long long by looking for the appropriate macros in <limits.h>.
// Note that we use limits.h rather than climits for maximal portability,
// remember that since these just declare a bunch of macros, there should be
// no namespace issues from this.
//
#include <limits.h>
# if !defined(BOOST_HAS_LONG_LONG) \
&& !(defined(BOOST_MSVC) && BOOST_MSVC <=1300) && !defined(__BORLANDC__) \
&& (defined(ULLONG_MAX) || defined(ULONG_LONG_MAX) || defined(ULONGLONG_MAX))
# define BOOST_HAS_LONG_LONG
#endif
#if !defined(BOOST_HAS_LONG_LONG) && !defined(BOOST_NO_INTEGRAL_INT64_T)
# define BOOST_NO_INTEGRAL_INT64_T
#endif
// GCC 3.x will clean up all of those nasty macro definitions that
// BOOST_NO_CTYPE_FUNCTIONS is intended to help work around, so undefine
// it under GCC 3.x.
#if defined(__GNUC__) && (__GNUC__ >= 3) && defined(BOOST_NO_CTYPE_FUNCTIONS)
# undef BOOST_NO_CTYPE_FUNCTIONS
#endif
//
// Assume any extensions are in namespace std:: unless stated otherwise:
//
# ifndef BOOST_STD_EXTENSION_NAMESPACE
# define BOOST_STD_EXTENSION_NAMESPACE std
# endif
//
// If cv-qualified specializations are not allowed, then neither are cv-void ones:
//
# if defined(BOOST_NO_CV_SPECIALIZATIONS) \
&& !defined(BOOST_NO_CV_VOID_SPECIALIZATIONS)
# define BOOST_NO_CV_VOID_SPECIALIZATIONS
# endif
//
// If there is no numeric_limits template, then it can't have any compile time
// constants either!
//
# if defined(BOOST_NO_LIMITS) \
&& !defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS)
# define BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
# define BOOST_NO_MS_INT64_NUMERIC_LIMITS
# define BOOST_NO_LONG_LONG_NUMERIC_LIMITS
# endif
//
// if there is no long long then there is no specialisation
// for numeric_limits<long long> either:
//
#if !defined(BOOST_HAS_LONG_LONG) && !defined(BOOST_NO_LONG_LONG_NUMERIC_LIMITS)
# define BOOST_NO_LONG_LONG_NUMERIC_LIMITS
#endif
//
// if there is no __int64 then there is no specialisation
// for numeric_limits<__int64> either:
//
#if !defined(BOOST_HAS_MS_INT64) && !defined(BOOST_NO_MS_INT64_NUMERIC_LIMITS)
# define BOOST_NO_MS_INT64_NUMERIC_LIMITS
#endif
//
// if member templates are supported then so is the
// VC6 subset of member templates:
//
# if !defined(BOOST_NO_MEMBER_TEMPLATES) \
&& !defined(BOOST_MSVC6_MEMBER_TEMPLATES)
# define BOOST_MSVC6_MEMBER_TEMPLATES
# endif
//
// Without partial specialization, can't test for partial specialisation bugs:
//
# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
&& !defined(BOOST_BCB_PARTIAL_SPECIALIZATION_BUG)
# define BOOST_BCB_PARTIAL_SPECIALIZATION_BUG
# endif
//
// Without partial specialization, std::iterator_traits can't work:
//
# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
&& !defined(BOOST_NO_STD_ITERATOR_TRAITS)
# define BOOST_NO_STD_ITERATOR_TRAITS
# endif
//
// Without member template support, we can't have template constructors
// in the standard library either:
//
# if defined(BOOST_NO_MEMBER_TEMPLATES) \
&& !defined(BOOST_MSVC6_MEMBER_TEMPLATES) \
&& !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)
# define BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS
# endif
//
// Without member template support, we can't have a conforming
// std::allocator template either:
//
# if defined(BOOST_NO_MEMBER_TEMPLATES) \
&& !defined(BOOST_MSVC6_MEMBER_TEMPLATES) \
&& !defined(BOOST_NO_STD_ALLOCATOR)
# define BOOST_NO_STD_ALLOCATOR
# endif
//
// If we have a standard allocator, then we have a partial one as well:
//
#if !defined(BOOST_NO_STD_ALLOCATOR)
# define BOOST_HAS_PARTIAL_STD_ALLOCATOR
#endif
//
// We can't have a working std::use_facet if there is no std::locale:
//
# if defined(BOOST_NO_STD_LOCALE) && !defined(BOOST_NO_STD_USE_FACET)
# define BOOST_NO_STD_USE_FACET
# endif
//
// We can't have a std::messages facet if there is no std::locale:
//
# if defined(BOOST_NO_STD_LOCALE) && !defined(BOOST_NO_STD_MESSAGES)
# define BOOST_NO_STD_MESSAGES
# endif
//
// We can't have a working std::wstreambuf if there is no std::locale:
//
# if defined(BOOST_NO_STD_LOCALE) && !defined(BOOST_NO_STD_WSTREAMBUF)
# define BOOST_NO_STD_WSTREAMBUF
# endif
//
// We can't have a <cwctype> if there is no <cwchar>:
//
# if defined(BOOST_NO_CWCHAR) && !defined(BOOST_NO_CWCTYPE)
# define BOOST_NO_CWCTYPE
# endif
//
// We can't have a swprintf if there is no <cwchar>:
//
# if defined(BOOST_NO_CWCHAR) && !defined(BOOST_NO_SWPRINTF)
# define BOOST_NO_SWPRINTF
# endif
//
// If Win32 support is turned off, then we must turn off
// threading support also, unless there is some other
// thread API enabled:
//
#if defined(BOOST_DISABLE_WIN32) && defined(_WIN32) \
&& !defined(BOOST_DISABLE_THREADS) && !defined(BOOST_HAS_PTHREADS)
# define BOOST_DISABLE_THREADS
#endif
//
// Turn on threading support if the compiler thinks that it's in
// multithreaded mode. We put this here because there are only a
// limited number of macros that identify this (if there's any missing
// from here then add to the appropriate compiler section):
//
#if (defined(__MT__) || defined(_MT) || defined(_REENTRANT) \
|| defined(_PTHREADS)) && !defined(BOOST_HAS_THREADS)
# define BOOST_HAS_THREADS
#endif
//
// Turn threading support off if BOOST_DISABLE_THREADS is defined:
//
#if defined(BOOST_DISABLE_THREADS) && defined(BOOST_HAS_THREADS)
# undef BOOST_HAS_THREADS
#endif
//
// Turn threading support off if we don't recognise the threading API:
//
#if defined(BOOST_HAS_THREADS) && !defined(BOOST_HAS_PTHREADS)\
&& !defined(BOOST_HAS_WINTHREADS) && !defined(BOOST_HAS_BETHREADS)\
&& !defined(BOOST_HAS_MPTASKS)
# undef BOOST_HAS_THREADS
#endif
//
// If the compiler claims to be C99 conformant, then it had better
// have a <stdint.h>:
//
# if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901)
# define BOOST_HAS_STDINT_H
# endif
//
// Define BOOST_NO_SLIST and BOOST_NO_HASH if required.
// Note that this is for backwards compatibility only.
//
# ifndef BOOST_HAS_SLIST
# define BOOST_NO_SLIST
# endif
# ifndef BOOST_HAS_HASH
# define BOOST_NO_HASH
# endif
// BOOST_NO_STDC_NAMESPACE workaround --------------------------------------//
// Because std::size_t usage is so common, even in boost headers which do not
// otherwise use the C library, the <cstddef> workaround is included here so
// that ugly workaround code need not appear in many other boost headers.
// NOTE WELL: This is a workaround for non-conforming compilers; <cstddef>
// must still be #included in the usual places so that <cstddef> inclusion
// works as expected with standard conforming compilers. The resulting
// double inclusion of <cstddef> is harmless.
# ifdef BOOST_NO_STDC_NAMESPACE
# include <cstddef>
namespace std { using ::ptrdiff_t; using ::size_t; }
# endif
// BOOST_NO_STD_MIN_MAX workaround -----------------------------------------//
# ifdef BOOST_NO_STD_MIN_MAX
namespace std {
template <class _Tp>
inline const _Tp& min(const _Tp& __a, const _Tp& __b) {
return __b < __a ? __b : __a;
}
template <class _Tp>
inline const _Tp& max(const _Tp& __a, const _Tp& __b) {
return __a < __b ? __b : __a;
}
}
# endif
// BOOST_STATIC_CONSTANT workaround --------------------------------------- //
// On compilers which don't allow in-class initialization of static integral
// constant members, we must use enums as a workaround if we want the constants
// to be available at compile-time. This macro gives us a convenient way to
// declare such constants.
# ifdef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
# define BOOST_STATIC_CONSTANT(type, assignment) enum { assignment }
# else
# define BOOST_STATIC_CONSTANT(type, assignment) static const type assignment
# endif
// BOOST_USE_FACET workaround ----------------------------------------------//
// When the standard library does not have a conforming std::use_facet there
// are various workarounds available, but they differ from library to library.
// This macro provides a consistent way to access a locale's facets.
// Usage:
// replace
// std::use_facet<Type>(loc);
// with
// BOOST_USE_FACET(Type, loc);
// Note do not add a std:: prefix to the front of BOOST_USE_FACET!
#if defined(BOOST_NO_STD_USE_FACET)
# ifdef BOOST_HAS_TWO_ARG_USE_FACET
# define BOOST_USE_FACET(Type, loc) std::use_facet(loc, static_cast<Type*>(0))
# elif defined(BOOST_HAS_MACRO_USE_FACET)
# define BOOST_USE_FACET(Type, loc) std::_USE(loc, Type)
# elif defined(BOOST_HAS_STLP_USE_FACET)
# define BOOST_USE_FACET(Type, loc) (*std::_Use_facet<Type >(loc))
# endif
#else
# define BOOST_USE_FACET(Type, loc) std::use_facet< Type >(loc)
#endif
// BOOST_NESTED_TEMPLATE workaround ------------------------------------------//
// Member templates are supported by some compilers even though they can't use
// the A::template member<U> syntax, as a workaround replace:
//
// typedef typename A::template rebind<U> binder;
//
// with:
//
// typedef typename A::BOOST_NESTED_TEMPLATE rebind<U> binder;
#ifndef BOOST_NO_MEMBER_TEMPLATE_KEYWORD
# define BOOST_NESTED_TEMPLATE template
#else
# define BOOST_NESTED_TEMPLATE
#endif
// BOOST_UNREACHABLE_RETURN(x) workaround -------------------------------------//
// Normally evaluates to nothing, unless BOOST_NO_UNREACHABLE_RETURN_DETECTION
// is defined, in which case it evaluates to return x; Use when you have a return
// statement that can never be reached.
#ifdef BOOST_NO_UNREACHABLE_RETURN_DETECTION
# define BOOST_UNREACHABLE_RETURN(x) return x;
#else
# define BOOST_UNREACHABLE_RETURN(x)
#endif
// BOOST_DEDUCED_TYPENAME workaround ------------------------------------------//
//
// Some compilers don't support the use of `typename' for dependent
// types in deduced contexts, e.g.
//
// template <class T> void f(T, typename T::type);
// ^^^^^^^^
// Replace these declarations with:
//
// template <class T> void f(T, BOOST_DEDUCED_TYPENAME T::type);
#ifndef BOOST_NO_DEDUCED_TYPENAME
# define BOOST_DEDUCED_TYPENAME typename
#else
# define BOOST_DEDUCED_TYPENAME
#endif
// ---------------------------------------------------------------------------//
//
// Helper macro BOOST_STRINGIZE:
// Converts the parameter X to a string after macro replacement
// on X has been performed.
//
#define BOOST_STRINGIZE(X) BOOST_DO_STRINGIZE(X)
#define BOOST_DO_STRINGIZE(X) #X
//
// Helper macro BOOST_JOIN:
// The following piece of macro magic joins the two
// arguments together, even when one of the arguments is
// itself a macro (see 16.3.1 in C++ standard). The key
// is that macro expansion of macro arguments does not
// occur in BOOST_DO_JOIN2 but does in BOOST_DO_JOIN.
//
#define BOOST_JOIN( X, Y ) BOOST_DO_JOIN( X, Y )
#define BOOST_DO_JOIN( X, Y ) BOOST_DO_JOIN2(X,Y)
#define BOOST_DO_JOIN2( X, Y ) X##Y
//
// Set some default values for compiler/library/platform names.
// These are for debugging config setup only:
//
# ifndef BOOST_COMPILER
# define BOOST_COMPILER "Unknown ISO C++ Compiler"
# endif
# ifndef BOOST_STDLIB
# define BOOST_STDLIB "Unknown ISO standard library"
# endif
# ifndef BOOST_PLATFORM
# if defined(unix) || defined(__unix) || defined(_XOPEN_SOURCE) \
|| defined(_POSIX_SOURCE)
# define BOOST_PLATFORM "Generic Unix"
# else
# define BOOST_PLATFORM "Unknown"
# endif
# endif
#endif

View File

@@ -0,0 +1,68 @@
// boost/config/user.hpp ---------------------------------------------------//
// (C) Copyright Boost.org 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.
// Do not check in modified versions of this file,
// This file may be customized by the end user, but not by boost.
//
// Use this file to define a site and compiler specific
// configuration policy:
//
// define this to locate a compiler config file:
// #define BOOST_COMPILER_CONFIG <myheader>
// define this to locate a stdlib config file:
// #define BOOST_STDLIB_CONFIG <myheader>
// define this to locate a platform config file:
// #define BOOST_PLATFORM_CONFIG <myheader>
// define this to disable compiler config,
// use if your compiler config has nothing to set:
// #define BOOST_NO_COMPILER_CONFIG
// define this to disable stdlib config,
// use if your stdlib config has nothing to set:
// #define BOOST_NO_STDLIB_CONFIG
// define this to disable platform config,
// use if your platform config has nothing to set:
// #define BOOST_NO_PLATFORM_CONFIG
// define this to disable all config options,
// excluding the user config. Use if your
// setup is fully ISO compliant, and has no
// useful extensions, or for autoconf generated
// setups:
// #define BOOST_NO_CONFIG
// define this to make the config "optimistic"
// about unknown compiler versions. Normally
// unknown compiler versions are assumed to have
// all the defects of the last known version, however
// setting this flag, causes the config to assume
// that unknown compiler versions are fully conformant
// with the standard:
// #define BOOST_STRICT_CONFIG
// define this to cause the config to halt compilation
// with an #error if it encounters anything unknown --
// either an unknown compiler version or an unknown
// compiler/platform/library:
// #define BOOST_ASSERT_CONFIG
// define if you want to disable threading support, even
// when available:
// #define BOOST_DISABLE_THREADS
// define when you want to disable Win32 specific features
// even when available:
// #define BOOST_DISABLE_WIN32

View File

@@ -0,0 +1,463 @@
/*
* Copyright (c) 1997
* Silicon Graphics Computer Systems, Inc.
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Silicon Graphics makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*/
/* NOTE: This is not portable code. Parts of numeric_limits<> are
* inherently machine-dependent, and this file is written for the MIPS
* architecture and the SGI MIPSpro C++ compiler. Parts of it (in
* particular, some of the characteristics of floating-point types)
* are almost certainly incorrect for any other platform.
*/
/* The above comment is almost certainly out of date. This file works
* on systems other than SGI MIPSpro C++ now.
*/
/*
* Revision history:
* 21 Sep 2001:
* Only include <cwchar> if BOOST_NO_CWCHAR is defined. (Darin Adler)
* 10 Aug 2001:
* Added MIPS (big endian) to the big endian family. (Jens Maurer)
* 13 Apr 2001:
* Added powerpc to the big endian family. (Jeremy Siek)
* 5 Apr 2001:
* Added sparc (big endian) processor support (John Maddock).
* Initial sub:
* Modified by Jens Maurer for gcc 2.95 on x86.
*/
#ifndef BOOST_SGI_CPP_LIMITS
#define BOOST_SGI_CPP_LIMITS
#include <climits>
#include <cfloat>
#include <boost/config.hpp>
#ifndef BOOST_NO_CWCHAR
#include <cwchar> // for WCHAR_MIN and WCHAR_MAX
#endif
// The macros are not named appropriately. We don't care about integer
// bit layout, but about floating-point NaN (etc.) bit patterns.
#if defined(__sparc) || defined(__sparc__) || defined(__powerpc__) || defined(__ppc__) || defined(__hppa) || defined(_MIPSEB) || defined(_POWER)
#define BOOST_BIG_ENDIAN
#elif defined(__i386__) || defined(__alpha__)
#define BOOST_LITTLE_ENDIAN
#else
#error The file boost/detail/limits.hpp needs to be set up for your CPU type.
#endif
namespace std {
enum float_round_style {
round_indeterminate = -1,
round_toward_zero = 0,
round_to_nearest = 1,
round_toward_infinity = 2,
round_toward_neg_infinity = 3
};
enum float_denorm_style {
denorm_indeterminate = -1,
denorm_absent = 0,
denorm_present = 1
};
// The C++ standard (section 18.2.1) requires that some of the members of
// numeric_limits be static const data members that are given constant-
// initializers within the class declaration. On compilers where the
// BOOST_NO_INCLASS_MEMBER_INITIALIZATION macro is defined, it is impossible to write
// a standard-conforming numeric_limits class.
//
// There are two possible workarounds: either initialize the data
// members outside the class, or change them from data members to
// enums. Neither workaround is satisfactory: the former makes it
// impossible to use the data members in constant-expressions, and the
// latter means they have the wrong type and that it is impossible to
// take their addresses. We choose the former workaround.
#ifdef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
# define BOOST_STL_DECLARE_LIMITS_MEMBER(__mem_type, __mem_name, __mem_value) \
enum { __mem_name = __mem_value }
#else /* BOOST_NO_INCLASS_MEMBER_INITIALIZATION */
# define BOOST_STL_DECLARE_LIMITS_MEMBER(__mem_type, __mem_name, __mem_value) \
static const __mem_type __mem_name = __mem_value
#endif /* BOOST_NO_INCLASS_MEMBER_INITIALIZATION */
// Deal with min/max for MinGW
#ifdef min
# undef min
#endif
#ifdef max
# undef max
#endif
// Base class for all specializations of numeric_limits.
template <class __number>
class _Numeric_limits_base {
public:
BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_specialized, false);
static __number min() throw() { return __number(); }
static __number max() throw() { return __number(); }
BOOST_STL_DECLARE_LIMITS_MEMBER(int, digits, 0);
BOOST_STL_DECLARE_LIMITS_MEMBER(int, digits10, 0);
BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_signed, false);
BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_integer, false);
BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_exact, false);
BOOST_STL_DECLARE_LIMITS_MEMBER(int, radix, 0);
static __number epsilon() throw() { return __number(); }
static __number round_error() throw() { return __number(); }
BOOST_STL_DECLARE_LIMITS_MEMBER(int, min_exponent, 0);
BOOST_STL_DECLARE_LIMITS_MEMBER(int, min_exponent10, 0);
BOOST_STL_DECLARE_LIMITS_MEMBER(int, max_exponent, 0);
BOOST_STL_DECLARE_LIMITS_MEMBER(int, max_exponent10, 0);
BOOST_STL_DECLARE_LIMITS_MEMBER(bool, has_infinity, false);
BOOST_STL_DECLARE_LIMITS_MEMBER(bool, has_quiet_NaN, false);
BOOST_STL_DECLARE_LIMITS_MEMBER(bool, has_signaling_NaN, false);
BOOST_STL_DECLARE_LIMITS_MEMBER(float_denorm_style,
has_denorm,
denorm_absent);
BOOST_STL_DECLARE_LIMITS_MEMBER(bool, has_denorm_loss, false);
static __number infinity() throw() { return __number(); }
static __number quiet_NaN() throw() { return __number(); }
static __number signaling_NaN() throw() { return __number(); }
static __number denorm_min() throw() { return __number(); }
BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_iec559, false);
BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_bounded, false);
BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_modulo, false);
BOOST_STL_DECLARE_LIMITS_MEMBER(bool, traps, false);
BOOST_STL_DECLARE_LIMITS_MEMBER(bool, tinyness_before, false);
BOOST_STL_DECLARE_LIMITS_MEMBER(float_round_style,
round_style,
round_toward_zero);
};
// Base class for integers.
template <class _Int,
_Int __imin,
_Int __imax,
int __idigits = -1>
class _Integer_limits : public _Numeric_limits_base<_Int>
{
public:
BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_specialized, true);
static _Int min() throw() { return __imin; }
static _Int max() throw() { return __imax; }
BOOST_STL_DECLARE_LIMITS_MEMBER(int,
digits,
(__idigits < 0) ? (int)(sizeof(_Int) * CHAR_BIT)
- (__imin == 0 ? 0 : 1)
: __idigits);
BOOST_STL_DECLARE_LIMITS_MEMBER(int, digits10, (digits * 301) / 1000);
// log 2 = 0.301029995664...
BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_signed, __imin != 0);
BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_integer, true);
BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_exact, true);
BOOST_STL_DECLARE_LIMITS_MEMBER(int, radix, 2);
BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_bounded, true);
BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_modulo, true);
};
#if defined(BOOST_BIG_ENDIAN)
template<class Number, unsigned int Word>
struct float_helper{
static Number get_word() throw() {
// sizeof(long double) == 16
const unsigned int _S_word[4] = { Word, 0, 0, 0 };
return *reinterpret_cast<const Number*>(&_S_word);
}
};
#else
template<class Number, unsigned int Word>
struct float_helper{
static Number get_word() throw() {
// sizeof(long double) == 12, but only 10 bytes significant
const unsigned int _S_word[4] = { 0, 0, 0, Word };
return *reinterpret_cast<const Number*>(
reinterpret_cast<const char *>(&_S_word)+16-
(sizeof(Number) == 12 ? 10 : sizeof(Number)));
}
};
#endif
// Base class for floating-point numbers.
template <class __number,
int __Digits, int __Digits10,
int __MinExp, int __MaxExp,
int __MinExp10, int __MaxExp10,
unsigned int __InfinityWord,
unsigned int __QNaNWord, unsigned int __SNaNWord,
bool __IsIEC559,
float_round_style __RoundStyle>
class _Floating_limits : public _Numeric_limits_base<__number>
{
public:
BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_specialized, true);
BOOST_STL_DECLARE_LIMITS_MEMBER(int, digits, __Digits);
BOOST_STL_DECLARE_LIMITS_MEMBER(int, digits10, __Digits10);
BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_signed, true);
BOOST_STL_DECLARE_LIMITS_MEMBER(int, radix, 2);
BOOST_STL_DECLARE_LIMITS_MEMBER(int, min_exponent, __MinExp);
BOOST_STL_DECLARE_LIMITS_MEMBER(int, max_exponent, __MaxExp);
BOOST_STL_DECLARE_LIMITS_MEMBER(int, min_exponent10, __MinExp10);
BOOST_STL_DECLARE_LIMITS_MEMBER(int, max_exponent10, __MaxExp10);
BOOST_STL_DECLARE_LIMITS_MEMBER(bool, has_infinity, true);
BOOST_STL_DECLARE_LIMITS_MEMBER(bool, has_quiet_NaN, true);
BOOST_STL_DECLARE_LIMITS_MEMBER(bool, has_signaling_NaN, true);
BOOST_STL_DECLARE_LIMITS_MEMBER(float_denorm_style,
has_denorm,
denorm_indeterminate);
BOOST_STL_DECLARE_LIMITS_MEMBER(bool, has_denorm_loss, false);
static __number infinity() throw() {
return float_helper<__number, __InfinityWord>::get_word();
}
static __number quiet_NaN() throw() {
return float_helper<__number,__QNaNWord>::get_word();
}
static __number signaling_NaN() throw() {
return float_helper<__number,__SNaNWord>::get_word();
}
BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_iec559, __IsIEC559);
BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_bounded, true);
BOOST_STL_DECLARE_LIMITS_MEMBER(bool, traps, false /* was: true */ );
BOOST_STL_DECLARE_LIMITS_MEMBER(bool, tinyness_before, false);
BOOST_STL_DECLARE_LIMITS_MEMBER(float_round_style, round_style, __RoundStyle);
};
// Class numeric_limits
// The unspecialized class.
template<class T>
class numeric_limits : public _Numeric_limits_base<T> {};
// Specializations for all built-in integral types.
template<>
class numeric_limits<bool>
: public _Integer_limits<bool, false, true, 0>
{};
template<>
class numeric_limits<char>
: public _Integer_limits<char, CHAR_MIN, CHAR_MAX>
{};
template<>
class numeric_limits<signed char>
: public _Integer_limits<signed char, SCHAR_MIN, SCHAR_MAX>
{};
template<>
class numeric_limits<unsigned char>
: public _Integer_limits<unsigned char, 0, UCHAR_MAX>
{};
#ifndef BOOST_NO_INTRINSIC_WCHAR_T
template<>
class numeric_limits<wchar_t>
#if !defined(WCHAR_MAX) || !defined(WCHAR_MIN)
#if defined(_WIN32) || defined(__CYGWIN__)
: public _Integer_limits<wchar_t, 0, USHRT_MAX>
#elif defined(__hppa)
// wchar_t has "unsigned int" as the underlying type
: public _Integer_limits<wchar_t, 0, UINT_MAX>
#else
// assume that wchar_t has "int" as the underlying type
: public _Integer_limits<wchar_t, INT_MIN, INT_MAX>
#endif
#else
// we have WCHAR_MIN and WCHAR_MAX defined, so use it
: public _Integer_limits<wchar_t, WCHAR_MIN, WCHAR_MAX>
#endif
{};
#endif
template<>
class numeric_limits<short>
: public _Integer_limits<short, SHRT_MIN, SHRT_MAX>
{};
template<>
class numeric_limits<unsigned short>
: public _Integer_limits<unsigned short, 0, USHRT_MAX>
{};
template<>
class numeric_limits<int>
: public _Integer_limits<int, INT_MIN, INT_MAX>
{};
template<>
class numeric_limits<unsigned int>
: public _Integer_limits<unsigned int, 0, UINT_MAX>
{};
template<>
class numeric_limits<long>
: public _Integer_limits<long, LONG_MIN, LONG_MAX>
{};
template<>
class numeric_limits<unsigned long>
: public _Integer_limits<unsigned long, 0, ULONG_MAX>
{};
#ifdef __GNUC__
// Some compilers have long long, but don't define the
// LONGLONG_MIN and LONGLONG_MAX macros in limits.h. This
// assumes that long long is 64 bits.
#if !defined(LONGLONG_MAX) && !defined(ULONGLONG_MAX)
# define ULONGLONG_MAX 0xffffffffffffffffLLU
# define LONGLONG_MAX 0x7fffffffffffffffLL
#endif
#if !defined(LONGLONG_MIN)
# define LONGLONG_MIN (-LONGLONG_MAX - 1)
#endif
#if !defined(ULONGLONG_MIN)
# define ULONGLONG_MIN 0
#endif
#endif /* __GNUC__ */
// Specializations for all built-in floating-point type.
template<> class numeric_limits<float>
: public _Floating_limits<float,
FLT_MANT_DIG, // Binary digits of precision
FLT_DIG, // Decimal digits of precision
FLT_MIN_EXP, // Minimum exponent
FLT_MAX_EXP, // Maximum exponent
FLT_MIN_10_EXP, // Minimum base 10 exponent
FLT_MAX_10_EXP, // Maximum base 10 exponent
#if defined(BOOST_BIG_ENDIAN)
0x7f80 << (sizeof(int)*CHAR_BIT-16), // Last word of +infinity
0x7f81 << (sizeof(int)*CHAR_BIT-16), // Last word of quiet NaN
0x7fc1 << (sizeof(int)*CHAR_BIT-16), // Last word of signaling NaN
#else
0x7f800000u, // Last word of +infinity
0x7f810000u, // Last word of quiet NaN
0x7fc10000u, // Last word of signaling NaN
#endif
true, // conforms to iec559
round_to_nearest>
{
public:
static float min() throw() { return FLT_MIN; }
static float denorm_min() throw() { return FLT_MIN; }
static float max() throw() { return FLT_MAX; }
static float epsilon() throw() { return FLT_EPSILON; }
static float round_error() throw() { return 0.5f; } // Units: ulps.
};
template<> class numeric_limits<double>
: public _Floating_limits<double,
DBL_MANT_DIG, // Binary digits of precision
DBL_DIG, // Decimal digits of precision
DBL_MIN_EXP, // Minimum exponent
DBL_MAX_EXP, // Maximum exponent
DBL_MIN_10_EXP, // Minimum base 10 exponent
DBL_MAX_10_EXP, // Maximum base 10 exponent
#if defined(BOOST_BIG_ENDIAN)
0x7ff0 << (sizeof(int)*CHAR_BIT-16), // Last word of +infinity
0x7ff1 << (sizeof(int)*CHAR_BIT-16), // Last word of quiet NaN
0x7ff9 << (sizeof(int)*CHAR_BIT-16), // Last word of signaling NaN
#else
0x7ff00000u, // Last word of +infinity
0x7ff10000u, // Last word of quiet NaN
0x7ff90000u, // Last word of signaling NaN
#endif
true, // conforms to iec559
round_to_nearest>
{
public:
static double min() throw() { return DBL_MIN; }
static double denorm_min() throw() { return DBL_MIN; }
static double max() throw() { return DBL_MAX; }
static double epsilon() throw() { return DBL_EPSILON; }
static double round_error() throw() { return 0.5; } // Units: ulps.
};
template<> class numeric_limits<long double>
: public _Floating_limits<long double,
LDBL_MANT_DIG, // Binary digits of precision
LDBL_DIG, // Decimal digits of precision
LDBL_MIN_EXP, // Minimum exponent
LDBL_MAX_EXP, // Maximum exponent
LDBL_MIN_10_EXP,// Minimum base 10 exponent
LDBL_MAX_10_EXP,// Maximum base 10 exponent
#if defined(BOOST_BIG_ENDIAN)
0x7ff0 << (sizeof(int)*CHAR_BIT-16), // Last word of +infinity
0x7ff1 << (sizeof(int)*CHAR_BIT-16), // Last word of quiet NaN
0x7ff9 << (sizeof(int)*CHAR_BIT-16), // Last word of signaling NaN
#else
0x7fff8000u, // Last word of +infinity
0x7fffc000u, // Last word of quiet NaN
0x7fff9000u, // Last word of signaling NaN
#endif
false, // Doesn't conform to iec559
round_to_nearest>
{
public:
static long double min() throw() { return LDBL_MIN; }
static long double denorm_min() throw() { return LDBL_MIN; }
static long double max() throw() { return LDBL_MAX; }
static long double epsilon() throw() { return LDBL_EPSILON; }
static long double round_error() throw() { return 4; } // Units: ulps.
};
} // namespace std
#endif /* BOOST_SGI_CPP_LIMITS */
// Local Variables:
// mode:C++
// End:

View File

@@ -0,0 +1,74 @@
// Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef WORKAROUND_DWA2002126_HPP
# define WORKAROUND_DWA2002126_HPP
// Compiler/library version workaround macro
//
// Usage:
//
// #if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
// // workaround for eVC4 and VC6
// ... // workaround code here
// #endif
//
// When BOOST_STRICT_CONFIG is defined, expands to 0. Otherwise, the
// first argument must be undefined or expand to a numeric
// value. The above expands to:
//
// (BOOST_MSVC) != 0 && (BOOST_MSVC) < 1300
//
// When used for workarounds that apply to the latest known version
// and all earlier versions of a compiler, the following convention
// should be observed:
//
// #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1301))
//
// The version number in this case corresponds to the last version in
// which the workaround was known to have been required. When
// BOOST_DETECT_OUTDATED_WORKAROUNDS is not the defined, the macro
// BOOST_TESTED_AT(x) expands to "!= 0", which effectively activates
// the workaround for any version of the compiler. When
// BOOST_DETECT_OUTDATED_WORKAROUNDS is defined, a compiler warning or
// error will be issued if the compiler version exceeds the argument
// to BOOST_TESTED_AT(). This can be used to locate workarounds which
// may be obsoleted by newer versions.
# ifndef BOOST_STRICT_CONFIG
# define BOOST_WORKAROUND(symbol, test) \
((symbol != 0) && (1 % (( (symbol test) ) + 1)))
// ^ ^ ^ ^
// The extra level of parenthesis nesting above, along with the
// BOOST_OPEN_PAREN indirection below, is required to satisfy the
// broken preprocessor in MWCW 8.3 and earlier.
//
// The basic mechanism works as follows:
// (symbol test) + 1 => if (symbol test) then 2 else 1
// 1 % ((symbol test) + 1) => if (symbol test) then 1 else 0
//
// The complication with % is for cooperation with BOOST_TESTED_AT().
// When "test" is BOOST_TESTED_AT(x) and
// BOOST_DETECT_OUTDATED_WORKAROUNDS is #defined,
//
// symbol test => if (symbol <= x) then 1 else -1
// (symbol test) + 1 => if (symbol <= x) then 2 else 0
// 1 % ((symbol test) + 1) => if (symbol <= x) then 1 else divide-by-zero
//
# ifdef BOOST_DETECT_OUTDATED_WORKAROUNDS
# define BOOST_OPEN_PAREN (
# define BOOST_TESTED_AT(value) > value) ?(-1): BOOST_OPEN_PAREN 1
# else
# define BOOST_TESTED_AT(value) != ((value)-(value))
# endif
# else
# define BOOST_WORKAROUND(symbol, test) 0
# endif
#endif // WORKAROUND_DWA2002126_HPP

View File

@@ -0,0 +1,139 @@
// (C) Copyright Boost.org 1999. 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.
//
// use this header as a workaround for missing <limits>
#ifndef BOOST_LIMITS
#define BOOST_LIMITS
#include <boost/config.hpp>
#ifdef BOOST_NO_LIMITS
# include <boost/detail/limits.hpp>
#else
# include <limits>
#endif
#if (defined(BOOST_HAS_LONG_LONG) && defined(BOOST_NO_LONG_LONG_NUMERIC_LIMITS)) \
|| (defined(BOOST_HAS_MS_INT64) && defined(BOOST_NO_MS_INT64_NUMERIC_LIMITS))
// Add missing specializations for numeric_limits:
#ifdef BOOST_HAS_MS_INT64
# define BOOST_LLT __int64
#else
# define BOOST_LLT long long
#endif
namespace std
{
template<>
class numeric_limits<BOOST_LLT>
{
public:
BOOST_STATIC_CONSTANT(bool, is_specialized = true);
#ifdef BOOST_HAS_MS_INT64
static BOOST_LLT min(){ return 0x8000000000000000i64; }
static BOOST_LLT max(){ return 0x7FFFFFFFFFFFFFFFi64; }
#elif defined(LLONG_MAX)
static BOOST_LLT min(){ return LLONG_MIN; }
static BOOST_LLT max(){ return LLONG_MAX; }
#elif defined(LONGLONG_MAX)
static BOOST_LLT min(){ return LONGLONG_MIN; }
static BOOST_LLT max(){ return LONGLONG_MAX; }
#else
static BOOST_LLT min(){ return 1LL << (sizeof(BOOST_LLT) * CHAR_BIT - 1); }
static BOOST_LLT max(){ return ~min(); }
#endif
BOOST_STATIC_CONSTANT(int, digits = sizeof(BOOST_LLT) * CHAR_BIT -1);
BOOST_STATIC_CONSTANT(int, digits10 = (CHAR_BIT * sizeof (BOOST_LLT) - 1) * 301L / 1000);
BOOST_STATIC_CONSTANT(bool, is_signed = true);
BOOST_STATIC_CONSTANT(bool, is_integer = true);
BOOST_STATIC_CONSTANT(bool, is_exact = true);
BOOST_STATIC_CONSTANT(int, radix = 2);
static BOOST_LLT epsilon() throw() { return 0; };
static BOOST_LLT round_error() throw() { return 0; };
BOOST_STATIC_CONSTANT(int, min_exponent = 0);
BOOST_STATIC_CONSTANT(int, min_exponent10 = 0);
BOOST_STATIC_CONSTANT(int, max_exponent = 0);
BOOST_STATIC_CONSTANT(int, max_exponent10 = 0);
BOOST_STATIC_CONSTANT(bool, has_infinity = false);
BOOST_STATIC_CONSTANT(bool, has_quiet_NaN = false);
BOOST_STATIC_CONSTANT(bool, has_signaling_NaN = false);
BOOST_STATIC_CONSTANT(bool, has_denorm = false);
BOOST_STATIC_CONSTANT(bool, has_denorm_loss = false);
static BOOST_LLT infinity() throw() { return 0; };
static BOOST_LLT quiet_NaN() throw() { return 0; };
static BOOST_LLT signaling_NaN() throw() { return 0; };
static BOOST_LLT denorm_min() throw() { return 0; };
BOOST_STATIC_CONSTANT(bool, is_iec559 = false);
BOOST_STATIC_CONSTANT(bool, is_bounded = false);
BOOST_STATIC_CONSTANT(bool, is_modulo = false);
BOOST_STATIC_CONSTANT(bool, traps = false);
BOOST_STATIC_CONSTANT(bool, tinyness_before = false);
BOOST_STATIC_CONSTANT(float_round_style, round_style = round_toward_zero);
};
template<>
class numeric_limits<unsigned BOOST_LLT>
{
public:
BOOST_STATIC_CONSTANT(bool, is_specialized = true);
#ifdef BOOST_HAS_MS_INT64
static unsigned BOOST_LLT min(){ return 0ui64; }
static unsigned BOOST_LLT max(){ return 0xFFFFFFFFFFFFFFFFui64; }
#elif defined(ULLONG_MAX) && defined(ULLONG_MIN)
static unsigned BOOST_LLT min(){ return ULLONG_MIN; }
static unsigned BOOST_LLT max(){ return ULLONG_MAX; }
#elif defined(ULONGLONG_MAX) && defined(ULONGLONG_MIN)
static unsigned BOOST_LLT min(){ return ULONGLONG_MIN; }
static unsigned BOOST_LLT max(){ return ULONGLONG_MAX; }
#else
static unsigned BOOST_LLT min(){ return 0uLL; }
static unsigned BOOST_LLT max(){ return ~0uLL; }
#endif
BOOST_STATIC_CONSTANT(int, digits = sizeof(BOOST_LLT) * CHAR_BIT);
BOOST_STATIC_CONSTANT(int, digits10 = (CHAR_BIT * sizeof (BOOST_LLT)) * 301L / 1000);
BOOST_STATIC_CONSTANT(bool, is_signed = false);
BOOST_STATIC_CONSTANT(bool, is_integer = true);
BOOST_STATIC_CONSTANT(bool, is_exact = true);
BOOST_STATIC_CONSTANT(int, radix = 2);
static unsigned BOOST_LLT epsilon() throw() { return 0; };
static unsigned BOOST_LLT round_error() throw() { return 0; };
BOOST_STATIC_CONSTANT(int, min_exponent = 0);
BOOST_STATIC_CONSTANT(int, min_exponent10 = 0);
BOOST_STATIC_CONSTANT(int, max_exponent = 0);
BOOST_STATIC_CONSTANT(int, max_exponent10 = 0);
BOOST_STATIC_CONSTANT(bool, has_infinity = false);
BOOST_STATIC_CONSTANT(bool, has_quiet_NaN = false);
BOOST_STATIC_CONSTANT(bool, has_signaling_NaN = false);
BOOST_STATIC_CONSTANT(bool, has_denorm = false);
BOOST_STATIC_CONSTANT(bool, has_denorm_loss = false);
static unsigned BOOST_LLT infinity() throw() { return 0; };
static unsigned BOOST_LLT quiet_NaN() throw() { return 0; };
static unsigned BOOST_LLT signaling_NaN() throw() { return 0; };
static unsigned BOOST_LLT denorm_min() throw() { return 0; };
BOOST_STATIC_CONSTANT(bool, is_iec559 = false);
BOOST_STATIC_CONSTANT(bool, is_bounded = false);
BOOST_STATIC_CONSTANT(bool, is_modulo = false);
BOOST_STATIC_CONSTANT(bool, traps = false);
BOOST_STATIC_CONSTANT(bool, tinyness_before = false);
BOOST_STATIC_CONSTANT(float_round_style, round_style = round_toward_zero);
};
}
#endif
#endif

View File

@@ -0,0 +1,105 @@
// Copyright (C) 2000 Stephen Cleary (shammah@voyager.net)
//
// This file can be redistributed and/or modified under the terms found
// in "copyright.html"
// This software and its documentation 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 updates, documentation, and revision history.
#ifndef BOOST_POOL_CT_GCD_LCM_HPP
#define BOOST_POOL_CT_GCD_LCM_HPP
#include <boost/static_assert.hpp>
#include <boost/type_traits/ice.hpp>
namespace boost {
namespace details {
namespace pool {
// Compile-time calculation of greatest common divisor and least common multiple
//
// ct_gcd is a compile-time algorithm that calculates the greatest common
// divisor of two unsigned integers, using Euclid's algorithm.
//
// assumes: A != 0 && B != 0
//
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
namespace details {
template <unsigned A, unsigned B, bool Bis0>
struct ct_gcd_helper;
template <unsigned A, unsigned B>
struct ct_gcd_helper<A, B, false>
{
BOOST_STATIC_CONSTANT(unsigned, A_mod_B_ = A % B);
BOOST_STATIC_CONSTANT(unsigned, value =
(::boost::details::pool::details::ct_gcd_helper<
B, static_cast<unsigned>(A_mod_B_),
::boost::type_traits::ice_eq<A_mod_B_, 0>::value
>::value) );
};
template <unsigned A, unsigned B>
struct ct_gcd_helper<A, B, true>
{
BOOST_STATIC_CONSTANT(unsigned, value = A);
};
} // namespace details
template <unsigned A, unsigned B>
struct ct_gcd
{
BOOST_STATIC_ASSERT(A != 0 && B != 0);
BOOST_STATIC_CONSTANT(unsigned, value =
(::boost::details::pool::details::ct_gcd_helper<A, B, false>::value) );
};
#else
// Thanks to Peter Dimov for providing this workaround!
namespace details {
template<unsigned A> struct ct_gcd2
{
template<unsigned B>
struct helper
{
BOOST_STATIC_CONSTANT(unsigned, value = ct_gcd2<B>::helper<A % B>::value);
};
template<>
struct helper<0>
{
BOOST_STATIC_CONSTANT(unsigned, value = A);
};
};
} // namespace details
template<unsigned A, unsigned B> struct ct_gcd
{
BOOST_STATIC_ASSERT(A != 0 && B != 0);
enum { value = details::ct_gcd2<A>::helper<B>::value };
};
#endif
//
// ct_lcm is a compile-time algorithm that calculates the least common
// multiple of two unsigned integers.
//
// assumes: A != 0 && B != 0
//
template <unsigned A, unsigned B>
struct ct_lcm
{
BOOST_STATIC_CONSTANT(unsigned, value =
(A / ::boost::details::pool::ct_gcd<A, B>::value * B) );
};
} // namespace pool
} // namespace details
} // namespace boost
#endif

View File

@@ -0,0 +1,59 @@
// Copyright (C) 2000 Stephen Cleary (shammah@voyager.net)
//
// This file can be redistributed and/or modified under the terms found
// in "copyright.html"
// This software and its documentation 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 updates, documentation, and revision history.
#ifndef BOOST_POOL_GCD_LCM_HPP
#define BOOST_POOL_GCD_LCM_HPP
namespace boost {
namespace details {
namespace pool {
// Greatest common divisor and least common multiple
//
// gcd is an algorithm that calculates the greatest common divisor of two
// integers, using Euclid's algorithm.
//
// Pre: A > 0 && B > 0
// Recommended: A > B
template <typename Integer>
Integer gcd(Integer A, Integer B)
{
do
{
const Integer tmp(B);
B = A % B;
A = tmp;
} while (B != 0);
return A;
}
//
// lcm is an algorithm that calculates the least common multiple of two
// integers.
//
// Pre: A > 0 && B > 0
// Recommended: A > B
template <typename Integer>
Integer lcm(const Integer & A, const Integer & B)
{
Integer ret = A;
ret /= gcd(A, B);
ret *= B;
return ret;
}
} // namespace pool
} // namespace details
} // namespace boost
#endif

View File

@@ -0,0 +1,41 @@
// Copyright (C) 2000 Stephen Cleary (shammah@voyager.net)
//
// This file can be redistributed and/or modified under the terms found
// in "copyright.html"
// This software and its documentation 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 updates, documentation, and revision history.
#ifndef BOOST_POOL_GUARD_HPP
#define BOOST_POOL_GUARD_HPP
// Extremely Light-Weight guard glass
namespace boost {
namespace details {
namespace pool {
template <typename Mutex>
class guard
{
private:
Mutex & mtx;
guard(const guard &);
void operator=(const guard &);
public:
explicit guard(Mutex & nmtx)
:mtx(nmtx) { mtx.lock(); }
~guard() { mtx.unlock(); }
};
} // namespace pool
} // namespace details
} // namespace boost
#endif

Some files were not shown because too many files have changed in this diff Show More