diff --git a/.gitignore b/.gitignore index f7e5fcc..585dd46 100644 --- a/.gitignore +++ b/.gitignore @@ -25,6 +25,16 @@ *.la *.a *.lib +*.pdb +*.ilk +*.exp +*.tlog +*.tli +*.tlh +*.log +*.sbr +*.idb +*.txt # Executables *.exe @@ -34,3 +44,7 @@ !MSADO15.DLL !libcurl.lib !zip.lib +!create_dumpD.lib +!create_dump.lib + +.vs \ No newline at end of file diff --git a/俱乐部/Platform.sln b/俱乐部/Platform.sln index 1f37ba3..f0c5d31 100644 --- a/俱乐部/Platform.sln +++ b/俱乐部/Platform.sln @@ -31,1676 +31,80 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "create_dump", "Source\Share EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution - Consumer_Release_Indie|ARM = Consumer_Release_Indie|ARM - Consumer_Release_Indie|Mixed Platforms = Consumer_Release_Indie|Mixed Platforms - Consumer_Release_Indie|Win32 = Consumer_Release_Indie|Win32 - Consumer_Release_Indie|x64 = Consumer_Release_Indie|x64 - Consumer_Release|ARM = Consumer_Release|ARM - Consumer_Release|Mixed Platforms = Consumer_Release|Mixed Platforms - Consumer_Release|Win32 = Consumer_Release|Win32 - Consumer_Release|x64 = Consumer_Release|x64 - Debug_Unicode|ARM = Debug_Unicode|ARM - Debug_Unicode|Mixed Platforms = Debug_Unicode|Mixed Platforms Debug_Unicode|Win32 = Debug_Unicode|Win32 Debug_Unicode|x64 = Debug_Unicode|x64 - Debug|ARM = Debug|ARM - Debug|Mixed Platforms = Debug|Mixed Platforms - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - DebugVD|ARM = DebugVD|ARM - DebugVD|Mixed Platforms = DebugVD|Mixed Platforms - DebugVD|Win32 = DebugVD|Win32 - DebugVD|x64 = DebugVD|x64 - Editor_Debug|ARM = Editor_Debug|ARM - Editor_Debug|Mixed Platforms = Editor_Debug|Mixed Platforms - Editor_Debug|Win32 = Editor_Debug|Win32 - Editor_Debug|x64 = Editor_Debug|x64 - Editor_Hybrid_Indie|ARM = Editor_Hybrid_Indie|ARM - Editor_Hybrid_Indie|Mixed Platforms = Editor_Hybrid_Indie|Mixed Platforms - Editor_Hybrid_Indie|Win32 = Editor_Hybrid_Indie|Win32 - Editor_Hybrid_Indie|x64 = Editor_Hybrid_Indie|x64 - Editor_Hybrid|ARM = Editor_Hybrid|ARM - Editor_Hybrid|Mixed Platforms = Editor_Hybrid|Mixed Platforms - Editor_Hybrid|Win32 = Editor_Hybrid|Win32 - Editor_Hybrid|x64 = Editor_Hybrid|x64 - Evaluation|ARM = Evaluation|ARM - Evaluation|Mixed Platforms = Evaluation|Mixed Platforms - Evaluation|Win32 = Evaluation|Win32 - Evaluation|x64 = Evaluation|x64 - Exporter_Debug|ARM = Exporter_Debug|ARM - Exporter_Debug|Mixed Platforms = Exporter_Debug|Mixed Platforms - Exporter_Debug|Win32 = Exporter_Debug|Win32 - Exporter_Debug|x64 = Exporter_Debug|x64 - Exporter_Release|ARM = Exporter_Release|ARM - Exporter_Release|Mixed Platforms = Exporter_Release|Mixed Platforms - Exporter_Release|Win32 = Exporter_Release|Win32 - Exporter_Release|x64 = Exporter_Release|x64 - Hybrid|ARM = Hybrid|ARM - Hybrid|Mixed Platforms = Hybrid|Mixed Platforms - Hybrid|Win32 = Hybrid|Win32 - Hybrid|x64 = Hybrid|x64 - PyModule_Hybrid|ARM = PyModule_Hybrid|ARM - PyModule_Hybrid|Mixed Platforms = PyModule_Hybrid|Mixed Platforms - PyModule_Hybrid|Win32 = PyModule_Hybrid|Win32 - PyModule_Hybrid|x64 = PyModule_Hybrid|x64 - Release_Indie|ARM = Release_Indie|ARM - Release_Indie|Mixed Platforms = Release_Indie|Mixed Platforms - Release_Indie|Win32 = Release_Indie|Win32 - Release_Indie|x64 = Release_Indie|x64 - Release_Manager|ARM = Release_Manager|ARM - Release_Manager|Mixed Platforms = Release_Manager|Mixed Platforms - Release_Manager|Win32 = Release_Manager|Win32 - Release_Manager|x64 = Release_Manager|x64 - Release_Unicode|ARM = Release_Unicode|ARM - Release_Unicode|Mixed Platforms = Release_Unicode|Mixed Platforms Release_Unicode|Win32 = Release_Unicode|Win32 Release_Unicode|x64 = Release_Unicode|x64 - Release|ARM = Release|ARM - Release|Mixed Platforms = Release|Mixed Platforms - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - ReleaseVD|ARM = ReleaseVD|ARM - ReleaseVD|Mixed Platforms = ReleaseVD|Mixed Platforms - ReleaseVD|Win32 = ReleaseVD|Win32 - ReleaseVD|x64 = ReleaseVD|x64 - Static_Release|ARM = Static_Release|ARM - Static_Release|Mixed Platforms = Static_Release|Mixed Platforms - Static_Release|Win32 = Static_Release|Win32 - Static_Release|x64 = Static_Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Consumer_Release_Indie|ARM.ActiveCfg = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Consumer_Release_Indie|ARM.Build.0 = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Consumer_Release_Indie|Mixed Platforms.ActiveCfg = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Consumer_Release_Indie|Mixed Platforms.Build.0 = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Consumer_Release_Indie|Win32.ActiveCfg = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Consumer_Release_Indie|Win32.Build.0 = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Consumer_Release_Indie|x64.ActiveCfg = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Consumer_Release_Indie|x64.Build.0 = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Consumer_Release|ARM.ActiveCfg = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Consumer_Release|ARM.Build.0 = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Consumer_Release|Mixed Platforms.ActiveCfg = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Consumer_Release|Mixed Platforms.Build.0 = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Consumer_Release|Win32.ActiveCfg = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Consumer_Release|Win32.Build.0 = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Consumer_Release|x64.ActiveCfg = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Consumer_Release|x64.Build.0 = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Debug_Unicode|ARM.ActiveCfg = Debug_Unicode|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Debug_Unicode|Mixed Platforms.ActiveCfg = Debug_Unicode|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Debug_Unicode|Mixed Platforms.Build.0 = Debug_Unicode|Win32 {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Debug_Unicode|Win32.ActiveCfg = Debug_Unicode|Win32 {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Debug_Unicode|Win32.Build.0 = Debug_Unicode|Win32 {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Debug_Unicode|x64.ActiveCfg = Debug_Unicode|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Debug|ARM.ActiveCfg = Debug|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Debug|Mixed Platforms.Build.0 = Debug|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Debug|Win32.ActiveCfg = Debug|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Debug|Win32.Build.0 = Debug|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Debug|x64.ActiveCfg = Debug|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.DebugVD|ARM.ActiveCfg = Debug|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.DebugVD|Mixed Platforms.ActiveCfg = Debug|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.DebugVD|Mixed Platforms.Build.0 = Debug|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.DebugVD|Win32.ActiveCfg = Debug|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.DebugVD|Win32.Build.0 = Debug|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.DebugVD|x64.ActiveCfg = Debug|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Editor_Debug|ARM.ActiveCfg = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Editor_Debug|ARM.Build.0 = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Editor_Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Editor_Debug|Mixed Platforms.Build.0 = Debug|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Editor_Debug|Win32.ActiveCfg = Debug|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Editor_Debug|Win32.Build.0 = Debug|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Editor_Debug|x64.ActiveCfg = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Editor_Debug|x64.Build.0 = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Editor_Hybrid_Indie|ARM.ActiveCfg = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Editor_Hybrid_Indie|ARM.Build.0 = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Editor_Hybrid_Indie|Mixed Platforms.ActiveCfg = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Editor_Hybrid_Indie|Mixed Platforms.Build.0 = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Editor_Hybrid_Indie|Win32.ActiveCfg = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Editor_Hybrid_Indie|Win32.Build.0 = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Editor_Hybrid_Indie|x64.ActiveCfg = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Editor_Hybrid_Indie|x64.Build.0 = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Editor_Hybrid|ARM.ActiveCfg = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Editor_Hybrid|ARM.Build.0 = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Editor_Hybrid|Mixed Platforms.ActiveCfg = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Editor_Hybrid|Mixed Platforms.Build.0 = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Editor_Hybrid|Win32.ActiveCfg = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Editor_Hybrid|Win32.Build.0 = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Editor_Hybrid|x64.ActiveCfg = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Editor_Hybrid|x64.Build.0 = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Evaluation|ARM.ActiveCfg = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Evaluation|ARM.Build.0 = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Evaluation|Mixed Platforms.ActiveCfg = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Evaluation|Mixed Platforms.Build.0 = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Evaluation|Win32.ActiveCfg = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Evaluation|Win32.Build.0 = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Evaluation|x64.ActiveCfg = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Evaluation|x64.Build.0 = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Exporter_Debug|ARM.ActiveCfg = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Exporter_Debug|ARM.Build.0 = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Exporter_Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Exporter_Debug|Mixed Platforms.Build.0 = Debug|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Exporter_Debug|Win32.ActiveCfg = Debug|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Exporter_Debug|Win32.Build.0 = Debug|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Exporter_Debug|x64.ActiveCfg = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Exporter_Debug|x64.Build.0 = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Exporter_Release|ARM.ActiveCfg = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Exporter_Release|ARM.Build.0 = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Exporter_Release|Mixed Platforms.ActiveCfg = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Exporter_Release|Mixed Platforms.Build.0 = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Exporter_Release|Win32.ActiveCfg = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Exporter_Release|Win32.Build.0 = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Exporter_Release|x64.ActiveCfg = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Exporter_Release|x64.Build.0 = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Hybrid|ARM.ActiveCfg = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Hybrid|ARM.Build.0 = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Hybrid|Mixed Platforms.ActiveCfg = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Hybrid|Mixed Platforms.Build.0 = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Hybrid|Win32.ActiveCfg = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Hybrid|Win32.Build.0 = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Hybrid|x64.ActiveCfg = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Hybrid|x64.Build.0 = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.PyModule_Hybrid|ARM.ActiveCfg = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.PyModule_Hybrid|ARM.Build.0 = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.PyModule_Hybrid|Mixed Platforms.ActiveCfg = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.PyModule_Hybrid|Mixed Platforms.Build.0 = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.PyModule_Hybrid|Win32.ActiveCfg = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.PyModule_Hybrid|Win32.Build.0 = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.PyModule_Hybrid|x64.ActiveCfg = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.PyModule_Hybrid|x64.Build.0 = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Release_Indie|ARM.ActiveCfg = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Release_Indie|ARM.Build.0 = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Release_Indie|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Release_Indie|Mixed Platforms.Build.0 = Release_Unicode|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Release_Indie|Win32.ActiveCfg = Release_Unicode|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Release_Indie|Win32.Build.0 = Release_Unicode|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Release_Indie|x64.ActiveCfg = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Release_Indie|x64.Build.0 = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Release_Manager|ARM.ActiveCfg = Release_Unicode|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Release_Manager|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Release_Manager|Mixed Platforms.Build.0 = Release_Unicode|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Release_Manager|Win32.ActiveCfg = Release_Unicode|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Release_Manager|Win32.Build.0 = Release_Unicode|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Release_Manager|x64.ActiveCfg = Release_Unicode|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Release_Unicode|ARM.ActiveCfg = Release_Unicode|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Release_Unicode|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Release_Unicode|Mixed Platforms.Build.0 = Release_Unicode|Win32 {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Release_Unicode|Win32.ActiveCfg = Release_Unicode|Win32 {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Release_Unicode|Win32.Build.0 = Release_Unicode|Win32 {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Release_Unicode|x64.ActiveCfg = Release_Unicode|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Release|ARM.ActiveCfg = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Release|Mixed Platforms.Build.0 = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Release|Win32.ActiveCfg = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Release|Win32.Build.0 = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Release|x64.ActiveCfg = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.ReleaseVD|ARM.ActiveCfg = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.ReleaseVD|Mixed Platforms.ActiveCfg = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.ReleaseVD|Mixed Platforms.Build.0 = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.ReleaseVD|Win32.ActiveCfg = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.ReleaseVD|Win32.Build.0 = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.ReleaseVD|x64.ActiveCfg = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Static_Release|ARM.ActiveCfg = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Static_Release|ARM.Build.0 = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Static_Release|Mixed Platforms.ActiveCfg = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Static_Release|Mixed Platforms.Build.0 = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Static_Release|Win32.ActiveCfg = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Static_Release|Win32.Build.0 = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Static_Release|x64.ActiveCfg = Release|Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B}.Static_Release|x64.Build.0 = Release|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Consumer_Release_Indie|ARM.ActiveCfg = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Consumer_Release_Indie|ARM.Build.0 = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Consumer_Release_Indie|Mixed Platforms.ActiveCfg = Release|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Consumer_Release_Indie|Mixed Platforms.Build.0 = Release|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Consumer_Release_Indie|Win32.ActiveCfg = Release|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Consumer_Release_Indie|Win32.Build.0 = Release|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Consumer_Release_Indie|x64.ActiveCfg = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Consumer_Release_Indie|x64.Build.0 = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Consumer_Release|ARM.ActiveCfg = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Consumer_Release|ARM.Build.0 = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Consumer_Release|Mixed Platforms.ActiveCfg = Release|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Consumer_Release|Mixed Platforms.Build.0 = Release|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Consumer_Release|Win32.ActiveCfg = Release|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Consumer_Release|Win32.Build.0 = Release|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Consumer_Release|x64.ActiveCfg = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Consumer_Release|x64.Build.0 = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Debug_Unicode|ARM.ActiveCfg = Debug_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Debug_Unicode|Mixed Platforms.ActiveCfg = Debug_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Debug_Unicode|Mixed Platforms.Build.0 = Debug_Unicode|Win32 {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Debug_Unicode|Win32.ActiveCfg = Debug_Unicode|Win32 {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Debug_Unicode|Win32.Build.0 = Debug_Unicode|Win32 {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Debug_Unicode|x64.ActiveCfg = Debug_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Debug|ARM.ActiveCfg = Debug|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Debug|Mixed Platforms.Build.0 = Debug|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Debug|Win32.ActiveCfg = Debug|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Debug|Win32.Build.0 = Debug|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Debug|x64.ActiveCfg = Debug|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.DebugVD|ARM.ActiveCfg = Release|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.DebugVD|ARM.Build.0 = Release|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.DebugVD|Mixed Platforms.ActiveCfg = Debug_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.DebugVD|Mixed Platforms.Build.0 = Debug_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.DebugVD|Win32.ActiveCfg = Debug_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.DebugVD|Win32.Build.0 = Debug_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.DebugVD|x64.ActiveCfg = Release|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.DebugVD|x64.Build.0 = Release|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Editor_Debug|ARM.ActiveCfg = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Editor_Debug|ARM.Build.0 = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Editor_Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Editor_Debug|Mixed Platforms.Build.0 = Debug|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Editor_Debug|Win32.ActiveCfg = Debug|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Editor_Debug|Win32.Build.0 = Debug|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Editor_Debug|x64.ActiveCfg = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Editor_Debug|x64.Build.0 = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Editor_Hybrid_Indie|ARM.ActiveCfg = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Editor_Hybrid_Indie|ARM.Build.0 = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Editor_Hybrid_Indie|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Editor_Hybrid_Indie|Mixed Platforms.Build.0 = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Editor_Hybrid_Indie|Win32.ActiveCfg = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Editor_Hybrid_Indie|Win32.Build.0 = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Editor_Hybrid_Indie|x64.ActiveCfg = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Editor_Hybrid_Indie|x64.Build.0 = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Editor_Hybrid|ARM.ActiveCfg = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Editor_Hybrid|ARM.Build.0 = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Editor_Hybrid|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Editor_Hybrid|Mixed Platforms.Build.0 = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Editor_Hybrid|Win32.ActiveCfg = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Editor_Hybrid|Win32.Build.0 = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Editor_Hybrid|x64.ActiveCfg = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Editor_Hybrid|x64.Build.0 = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Evaluation|ARM.ActiveCfg = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Evaluation|ARM.Build.0 = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Evaluation|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Evaluation|Mixed Platforms.Build.0 = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Evaluation|Win32.ActiveCfg = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Evaluation|Win32.Build.0 = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Evaluation|x64.ActiveCfg = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Evaluation|x64.Build.0 = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Exporter_Debug|ARM.ActiveCfg = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Exporter_Debug|ARM.Build.0 = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Exporter_Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Exporter_Debug|Mixed Platforms.Build.0 = Debug|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Exporter_Debug|Win32.ActiveCfg = Debug|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Exporter_Debug|Win32.Build.0 = Debug|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Exporter_Debug|x64.ActiveCfg = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Exporter_Debug|x64.Build.0 = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Exporter_Release|ARM.ActiveCfg = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Exporter_Release|ARM.Build.0 = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Exporter_Release|Mixed Platforms.ActiveCfg = Release|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Exporter_Release|Mixed Platforms.Build.0 = Release|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Exporter_Release|Win32.ActiveCfg = Release|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Exporter_Release|Win32.Build.0 = Release|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Exporter_Release|x64.ActiveCfg = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Exporter_Release|x64.Build.0 = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Hybrid|ARM.ActiveCfg = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Hybrid|ARM.Build.0 = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Hybrid|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Hybrid|Mixed Platforms.Build.0 = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Hybrid|Win32.ActiveCfg = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Hybrid|Win32.Build.0 = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Hybrid|x64.ActiveCfg = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Hybrid|x64.Build.0 = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.PyModule_Hybrid|ARM.ActiveCfg = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.PyModule_Hybrid|ARM.Build.0 = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.PyModule_Hybrid|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.PyModule_Hybrid|Mixed Platforms.Build.0 = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.PyModule_Hybrid|Win32.ActiveCfg = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.PyModule_Hybrid|Win32.Build.0 = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.PyModule_Hybrid|x64.ActiveCfg = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.PyModule_Hybrid|x64.Build.0 = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Release_Indie|ARM.ActiveCfg = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Release_Indie|ARM.Build.0 = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Release_Indie|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Release_Indie|Mixed Platforms.Build.0 = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Release_Indie|Win32.ActiveCfg = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Release_Indie|Win32.Build.0 = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Release_Indie|x64.ActiveCfg = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Release_Indie|x64.Build.0 = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Release_Manager|ARM.ActiveCfg = Release|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Release_Manager|ARM.Build.0 = Release|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Release_Manager|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Release_Manager|Mixed Platforms.Build.0 = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Release_Manager|Win32.ActiveCfg = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Release_Manager|Win32.Build.0 = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Release_Manager|x64.ActiveCfg = Release|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Release_Manager|x64.Build.0 = Release|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Release_Unicode|ARM.ActiveCfg = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Release_Unicode|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Release_Unicode|Mixed Platforms.Build.0 = Release_Unicode|Win32 {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Release_Unicode|Win32.ActiveCfg = Release_Unicode|Win32 {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Release_Unicode|Win32.Build.0 = Release_Unicode|Win32 {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Release_Unicode|x64.ActiveCfg = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Release|ARM.ActiveCfg = Release|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Release|Mixed Platforms.Build.0 = Release|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Release|Win32.ActiveCfg = Release|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Release|Win32.Build.0 = Release|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Release|x64.ActiveCfg = Release|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.ReleaseVD|ARM.ActiveCfg = Release|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.ReleaseVD|ARM.Build.0 = Release|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.ReleaseVD|Mixed Platforms.ActiveCfg = Release|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.ReleaseVD|Mixed Platforms.Build.0 = Release|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.ReleaseVD|Win32.ActiveCfg = Release|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.ReleaseVD|Win32.Build.0 = Release|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.ReleaseVD|x64.ActiveCfg = Release|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.ReleaseVD|x64.Build.0 = Release|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Static_Release|ARM.ActiveCfg = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Static_Release|ARM.Build.0 = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Static_Release|Mixed Platforms.ActiveCfg = Release|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Static_Release|Mixed Platforms.Build.0 = Release|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Static_Release|Win32.ActiveCfg = Release|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Static_Release|Win32.Build.0 = Release|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Static_Release|x64.ActiveCfg = Release_Unicode|Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7}.Static_Release|x64.Build.0 = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Consumer_Release_Indie|ARM.ActiveCfg = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Consumer_Release_Indie|ARM.Build.0 = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Consumer_Release_Indie|Mixed Platforms.ActiveCfg = Release|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Consumer_Release_Indie|Mixed Platforms.Build.0 = Release|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Consumer_Release_Indie|Win32.ActiveCfg = Release|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Consumer_Release_Indie|Win32.Build.0 = Release|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Consumer_Release_Indie|x64.ActiveCfg = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Consumer_Release_Indie|x64.Build.0 = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Consumer_Release|ARM.ActiveCfg = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Consumer_Release|ARM.Build.0 = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Consumer_Release|Mixed Platforms.ActiveCfg = Release|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Consumer_Release|Mixed Platforms.Build.0 = Release|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Consumer_Release|Win32.ActiveCfg = Release|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Consumer_Release|Win32.Build.0 = Release|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Consumer_Release|x64.ActiveCfg = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Consumer_Release|x64.Build.0 = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Debug_Unicode|ARM.ActiveCfg = Debug_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Debug_Unicode|Mixed Platforms.ActiveCfg = Debug_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Debug_Unicode|Mixed Platforms.Build.0 = Debug_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Debug_Unicode|Win32.ActiveCfg = Debug_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Debug_Unicode|Win32.Build.0 = Debug_Unicode|Win32 + {51FD2060-F4F9-4982-8474-473541D4FCF8}.Debug_Unicode|Win32.ActiveCfg = Release_Unicode|Win32 + {51FD2060-F4F9-4982-8474-473541D4FCF8}.Debug_Unicode|Win32.Build.0 = Release_Unicode|Win32 {51FD2060-F4F9-4982-8474-473541D4FCF8}.Debug_Unicode|x64.ActiveCfg = Debug_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Debug|ARM.ActiveCfg = Debug|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Debug|Mixed Platforms.Build.0 = Debug|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Debug|Win32.ActiveCfg = Debug|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Debug|Win32.Build.0 = Debug|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Debug|x64.ActiveCfg = Debug|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.DebugVD|ARM.ActiveCfg = Release|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.DebugVD|ARM.Build.0 = Release|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.DebugVD|Mixed Platforms.ActiveCfg = Debug_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.DebugVD|Mixed Platforms.Build.0 = Debug_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.DebugVD|Win32.ActiveCfg = Debug_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.DebugVD|Win32.Build.0 = Debug_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.DebugVD|x64.ActiveCfg = Release|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.DebugVD|x64.Build.0 = Release|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Editor_Debug|ARM.ActiveCfg = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Editor_Debug|ARM.Build.0 = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Editor_Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Editor_Debug|Mixed Platforms.Build.0 = Debug|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Editor_Debug|Win32.ActiveCfg = Debug|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Editor_Debug|Win32.Build.0 = Debug|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Editor_Debug|x64.ActiveCfg = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Editor_Debug|x64.Build.0 = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Editor_Hybrid_Indie|ARM.ActiveCfg = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Editor_Hybrid_Indie|ARM.Build.0 = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Editor_Hybrid_Indie|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Editor_Hybrid_Indie|Mixed Platforms.Build.0 = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Editor_Hybrid_Indie|Win32.ActiveCfg = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Editor_Hybrid_Indie|Win32.Build.0 = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Editor_Hybrid_Indie|x64.ActiveCfg = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Editor_Hybrid_Indie|x64.Build.0 = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Editor_Hybrid|ARM.ActiveCfg = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Editor_Hybrid|ARM.Build.0 = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Editor_Hybrid|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Editor_Hybrid|Mixed Platforms.Build.0 = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Editor_Hybrid|Win32.ActiveCfg = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Editor_Hybrid|Win32.Build.0 = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Editor_Hybrid|x64.ActiveCfg = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Editor_Hybrid|x64.Build.0 = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Evaluation|ARM.ActiveCfg = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Evaluation|ARM.Build.0 = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Evaluation|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Evaluation|Mixed Platforms.Build.0 = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Evaluation|Win32.ActiveCfg = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Evaluation|Win32.Build.0 = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Evaluation|x64.ActiveCfg = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Evaluation|x64.Build.0 = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Exporter_Debug|ARM.ActiveCfg = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Exporter_Debug|ARM.Build.0 = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Exporter_Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Exporter_Debug|Mixed Platforms.Build.0 = Debug|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Exporter_Debug|Win32.ActiveCfg = Debug|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Exporter_Debug|Win32.Build.0 = Debug|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Exporter_Debug|x64.ActiveCfg = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Exporter_Debug|x64.Build.0 = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Exporter_Release|ARM.ActiveCfg = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Exporter_Release|ARM.Build.0 = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Exporter_Release|Mixed Platforms.ActiveCfg = Release|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Exporter_Release|Mixed Platforms.Build.0 = Release|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Exporter_Release|Win32.ActiveCfg = Release|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Exporter_Release|Win32.Build.0 = Release|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Exporter_Release|x64.ActiveCfg = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Exporter_Release|x64.Build.0 = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Hybrid|ARM.ActiveCfg = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Hybrid|ARM.Build.0 = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Hybrid|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Hybrid|Mixed Platforms.Build.0 = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Hybrid|Win32.ActiveCfg = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Hybrid|Win32.Build.0 = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Hybrid|x64.ActiveCfg = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Hybrid|x64.Build.0 = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.PyModule_Hybrid|ARM.ActiveCfg = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.PyModule_Hybrid|ARM.Build.0 = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.PyModule_Hybrid|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.PyModule_Hybrid|Mixed Platforms.Build.0 = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.PyModule_Hybrid|Win32.ActiveCfg = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.PyModule_Hybrid|Win32.Build.0 = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.PyModule_Hybrid|x64.ActiveCfg = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.PyModule_Hybrid|x64.Build.0 = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Release_Indie|ARM.ActiveCfg = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Release_Indie|ARM.Build.0 = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Release_Indie|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Release_Indie|Mixed Platforms.Build.0 = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Release_Indie|Win32.ActiveCfg = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Release_Indie|Win32.Build.0 = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Release_Indie|x64.ActiveCfg = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Release_Indie|x64.Build.0 = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Release_Manager|ARM.ActiveCfg = Release|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Release_Manager|ARM.Build.0 = Release|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Release_Manager|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Release_Manager|Mixed Platforms.Build.0 = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Release_Manager|Win32.ActiveCfg = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Release_Manager|Win32.Build.0 = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Release_Manager|x64.ActiveCfg = Release|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Release_Manager|x64.Build.0 = Release|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Release_Unicode|ARM.ActiveCfg = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Release_Unicode|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Release_Unicode|Mixed Platforms.Build.0 = Release_Unicode|Win32 {51FD2060-F4F9-4982-8474-473541D4FCF8}.Release_Unicode|Win32.ActiveCfg = Release_Unicode|Win32 {51FD2060-F4F9-4982-8474-473541D4FCF8}.Release_Unicode|Win32.Build.0 = Release_Unicode|Win32 {51FD2060-F4F9-4982-8474-473541D4FCF8}.Release_Unicode|x64.ActiveCfg = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Release|ARM.ActiveCfg = Release|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Release|Mixed Platforms.Build.0 = Release|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Release|Win32.ActiveCfg = Release|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Release|Win32.Build.0 = Release|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Release|x64.ActiveCfg = Release|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.ReleaseVD|ARM.ActiveCfg = Release|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.ReleaseVD|ARM.Build.0 = Release|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.ReleaseVD|Mixed Platforms.ActiveCfg = Release|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.ReleaseVD|Mixed Platforms.Build.0 = Release|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.ReleaseVD|Win32.ActiveCfg = Release|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.ReleaseVD|Win32.Build.0 = Release|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.ReleaseVD|x64.ActiveCfg = Release|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.ReleaseVD|x64.Build.0 = Release|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Static_Release|ARM.ActiveCfg = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Static_Release|ARM.Build.0 = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Static_Release|Mixed Platforms.ActiveCfg = Release|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Static_Release|Mixed Platforms.Build.0 = Release|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Static_Release|Win32.ActiveCfg = Release|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Static_Release|Win32.Build.0 = Release|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Static_Release|x64.ActiveCfg = Release_Unicode|Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8}.Static_Release|x64.Build.0 = Release_Unicode|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Consumer_Release_Indie|ARM.ActiveCfg = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Consumer_Release_Indie|ARM.Build.0 = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Consumer_Release_Indie|Mixed Platforms.ActiveCfg = Release|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Consumer_Release_Indie|Mixed Platforms.Build.0 = Release|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Consumer_Release_Indie|Win32.ActiveCfg = Release|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Consumer_Release_Indie|Win32.Build.0 = Release|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Consumer_Release_Indie|x64.ActiveCfg = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Consumer_Release_Indie|x64.Build.0 = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Consumer_Release|ARM.ActiveCfg = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Consumer_Release|ARM.Build.0 = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Consumer_Release|Mixed Platforms.ActiveCfg = Release|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Consumer_Release|Mixed Platforms.Build.0 = Release|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Consumer_Release|Win32.ActiveCfg = Release|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Consumer_Release|Win32.Build.0 = Release|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Consumer_Release|x64.ActiveCfg = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Consumer_Release|x64.Build.0 = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Debug_Unicode|ARM.ActiveCfg = Release|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Debug_Unicode|ARM.Build.0 = Release|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Debug_Unicode|Mixed Platforms.ActiveCfg = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Debug_Unicode|Mixed Platforms.Build.0 = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Debug_Unicode|Win32.ActiveCfg = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Debug_Unicode|Win32.Build.0 = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Debug_Unicode|x64.ActiveCfg = Release|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Debug_Unicode|x64.Build.0 = Release|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Debug|ARM.ActiveCfg = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Debug|Mixed Platforms.Build.0 = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Debug|Win32.ActiveCfg = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Debug|Win32.Build.0 = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Debug|x64.ActiveCfg = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.DebugVD|ARM.ActiveCfg = Release|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.DebugVD|ARM.Build.0 = Release|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.DebugVD|Mixed Platforms.ActiveCfg = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.DebugVD|Mixed Platforms.Build.0 = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.DebugVD|Win32.ActiveCfg = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.DebugVD|Win32.Build.0 = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.DebugVD|x64.ActiveCfg = Release|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.DebugVD|x64.Build.0 = Release|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Editor_Debug|ARM.ActiveCfg = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Editor_Debug|ARM.Build.0 = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Editor_Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Editor_Debug|Mixed Platforms.Build.0 = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Editor_Debug|Win32.ActiveCfg = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Editor_Debug|Win32.Build.0 = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Editor_Debug|x64.ActiveCfg = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Editor_Debug|x64.Build.0 = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Editor_Hybrid_Indie|ARM.ActiveCfg = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Editor_Hybrid_Indie|ARM.Build.0 = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Editor_Hybrid_Indie|Mixed Platforms.ActiveCfg = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Editor_Hybrid_Indie|Mixed Platforms.Build.0 = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Editor_Hybrid_Indie|Win32.ActiveCfg = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Editor_Hybrid_Indie|Win32.Build.0 = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Editor_Hybrid_Indie|x64.ActiveCfg = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Editor_Hybrid_Indie|x64.Build.0 = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Editor_Hybrid|ARM.ActiveCfg = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Editor_Hybrid|ARM.Build.0 = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Editor_Hybrid|Mixed Platforms.ActiveCfg = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Editor_Hybrid|Mixed Platforms.Build.0 = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Editor_Hybrid|Win32.ActiveCfg = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Editor_Hybrid|Win32.Build.0 = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Editor_Hybrid|x64.ActiveCfg = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Editor_Hybrid|x64.Build.0 = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Evaluation|ARM.ActiveCfg = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Evaluation|ARM.Build.0 = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Evaluation|Mixed Platforms.ActiveCfg = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Evaluation|Mixed Platforms.Build.0 = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Evaluation|Win32.ActiveCfg = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Evaluation|Win32.Build.0 = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Evaluation|x64.ActiveCfg = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Evaluation|x64.Build.0 = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Exporter_Debug|ARM.ActiveCfg = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Exporter_Debug|ARM.Build.0 = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Exporter_Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Exporter_Debug|Mixed Platforms.Build.0 = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Exporter_Debug|Win32.ActiveCfg = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Exporter_Debug|Win32.Build.0 = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Exporter_Debug|x64.ActiveCfg = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Exporter_Debug|x64.Build.0 = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Exporter_Release|ARM.ActiveCfg = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Exporter_Release|ARM.Build.0 = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Exporter_Release|Mixed Platforms.ActiveCfg = Release|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Exporter_Release|Mixed Platforms.Build.0 = Release|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Exporter_Release|Win32.ActiveCfg = Release|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Exporter_Release|Win32.Build.0 = Release|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Exporter_Release|x64.ActiveCfg = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Exporter_Release|x64.Build.0 = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Hybrid|ARM.ActiveCfg = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Hybrid|ARM.Build.0 = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Hybrid|Mixed Platforms.ActiveCfg = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Hybrid|Mixed Platforms.Build.0 = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Hybrid|Win32.ActiveCfg = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Hybrid|Win32.Build.0 = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Hybrid|x64.ActiveCfg = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Hybrid|x64.Build.0 = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.PyModule_Hybrid|ARM.ActiveCfg = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.PyModule_Hybrid|ARM.Build.0 = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.PyModule_Hybrid|Mixed Platforms.ActiveCfg = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.PyModule_Hybrid|Mixed Platforms.Build.0 = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.PyModule_Hybrid|Win32.ActiveCfg = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.PyModule_Hybrid|Win32.Build.0 = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.PyModule_Hybrid|x64.ActiveCfg = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.PyModule_Hybrid|x64.Build.0 = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Release_Indie|ARM.ActiveCfg = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Release_Indie|ARM.Build.0 = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Release_Indie|Mixed Platforms.ActiveCfg = Release|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Release_Indie|Mixed Platforms.Build.0 = Release|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Release_Indie|Win32.ActiveCfg = Release|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Release_Indie|Win32.Build.0 = Release|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Release_Indie|x64.ActiveCfg = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Release_Indie|x64.Build.0 = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Release_Manager|ARM.ActiveCfg = Release|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Release_Manager|ARM.Build.0 = Release|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Release_Manager|Mixed Platforms.ActiveCfg = Release|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Release_Manager|Mixed Platforms.Build.0 = Release|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Release_Manager|Win32.ActiveCfg = Release|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Release_Manager|Win32.Build.0 = Release|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Release_Manager|x64.ActiveCfg = Release|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Release_Manager|x64.Build.0 = Release|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Release_Unicode|ARM.ActiveCfg = Release|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Release_Unicode|ARM.Build.0 = Release|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Release_Unicode|Mixed Platforms.ActiveCfg = Release|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Release_Unicode|Mixed Platforms.Build.0 = Release|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Release_Unicode|Win32.ActiveCfg = Release|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Release_Unicode|Win32.Build.0 = Release|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Release_Unicode|x64.ActiveCfg = Release|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Release_Unicode|x64.Build.0 = Release|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Release|ARM.ActiveCfg = Release|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Release|Mixed Platforms.Build.0 = Release|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Release|Win32.ActiveCfg = Release|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Release|Win32.Build.0 = Release|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Release|x64.ActiveCfg = Release|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.ReleaseVD|ARM.ActiveCfg = Release|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.ReleaseVD|ARM.Build.0 = Release|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.ReleaseVD|Mixed Platforms.ActiveCfg = Release|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.ReleaseVD|Mixed Platforms.Build.0 = Release|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.ReleaseVD|Win32.ActiveCfg = Release|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.ReleaseVD|Win32.Build.0 = Release|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.ReleaseVD|x64.ActiveCfg = Release|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.ReleaseVD|x64.Build.0 = Release|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Static_Release|ARM.ActiveCfg = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Static_Release|ARM.Build.0 = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Static_Release|Mixed Platforms.ActiveCfg = Release|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Static_Release|Mixed Platforms.Build.0 = Release|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Static_Release|Win32.ActiveCfg = Release|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Static_Release|Win32.Build.0 = Release|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Static_Release|x64.ActiveCfg = Debug|Win32 - {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Static_Release|x64.Build.0 = Debug|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Consumer_Release_Indie|ARM.ActiveCfg = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Consumer_Release_Indie|ARM.Build.0 = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Consumer_Release_Indie|Mixed Platforms.ActiveCfg = Release|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Consumer_Release_Indie|Mixed Platforms.Build.0 = Release|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Consumer_Release_Indie|Win32.ActiveCfg = Release|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Consumer_Release_Indie|Win32.Build.0 = Release|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Consumer_Release_Indie|x64.ActiveCfg = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Consumer_Release_Indie|x64.Build.0 = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Consumer_Release|ARM.ActiveCfg = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Consumer_Release|ARM.Build.0 = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Consumer_Release|Mixed Platforms.ActiveCfg = Release|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Consumer_Release|Mixed Platforms.Build.0 = Release|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Consumer_Release|Win32.ActiveCfg = Release|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Consumer_Release|Win32.Build.0 = Release|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Consumer_Release|x64.ActiveCfg = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Consumer_Release|x64.Build.0 = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Debug_Unicode|ARM.ActiveCfg = Debug_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Debug_Unicode|Mixed Platforms.ActiveCfg = Debug_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Debug_Unicode|Mixed Platforms.Build.0 = Debug_Unicode|Win32 + {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Debug_Unicode|Win32.ActiveCfg = Release_Unicode|Win32 + {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Debug_Unicode|Win32.Build.0 = Release_Unicode|Win32 + {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Debug_Unicode|x64.ActiveCfg = Debug_Unicode|Win32 + {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Release_Unicode|Win32.ActiveCfg = Release_Unicode|Win32 + {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Release_Unicode|Win32.Build.0 = Release_Unicode|Win32 + {C38EABE4-E7E3-437A-8ECF-97A8626227D0}.Release_Unicode|x64.ActiveCfg = Release_Unicode|Win32 {DA531A23-506A-4643-BA47-B77542C5F41C}.Debug_Unicode|Win32.ActiveCfg = Debug_Unicode|Win32 {DA531A23-506A-4643-BA47-B77542C5F41C}.Debug_Unicode|Win32.Build.0 = Debug_Unicode|Win32 {DA531A23-506A-4643-BA47-B77542C5F41C}.Debug_Unicode|x64.ActiveCfg = Debug_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Debug|ARM.ActiveCfg = Debug|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Debug|Mixed Platforms.Build.0 = Debug|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Debug|Win32.ActiveCfg = Debug|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Debug|Win32.Build.0 = Debug|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Debug|x64.ActiveCfg = Debug|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.DebugVD|ARM.ActiveCfg = Release|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.DebugVD|ARM.Build.0 = Release|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.DebugVD|Mixed Platforms.ActiveCfg = Debug_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.DebugVD|Mixed Platforms.Build.0 = Debug_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.DebugVD|Win32.ActiveCfg = Debug_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.DebugVD|Win32.Build.0 = Debug_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.DebugVD|x64.ActiveCfg = Release|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.DebugVD|x64.Build.0 = Release|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Editor_Debug|ARM.ActiveCfg = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Editor_Debug|ARM.Build.0 = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Editor_Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Editor_Debug|Mixed Platforms.Build.0 = Debug|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Editor_Debug|Win32.ActiveCfg = Debug|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Editor_Debug|Win32.Build.0 = Debug|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Editor_Debug|x64.ActiveCfg = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Editor_Debug|x64.Build.0 = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Editor_Hybrid_Indie|ARM.ActiveCfg = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Editor_Hybrid_Indie|ARM.Build.0 = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Editor_Hybrid_Indie|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Editor_Hybrid_Indie|Mixed Platforms.Build.0 = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Editor_Hybrid_Indie|Win32.ActiveCfg = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Editor_Hybrid_Indie|Win32.Build.0 = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Editor_Hybrid_Indie|x64.ActiveCfg = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Editor_Hybrid_Indie|x64.Build.0 = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Editor_Hybrid|ARM.ActiveCfg = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Editor_Hybrid|ARM.Build.0 = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Editor_Hybrid|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Editor_Hybrid|Mixed Platforms.Build.0 = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Editor_Hybrid|Win32.ActiveCfg = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Editor_Hybrid|Win32.Build.0 = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Editor_Hybrid|x64.ActiveCfg = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Editor_Hybrid|x64.Build.0 = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Evaluation|ARM.ActiveCfg = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Evaluation|ARM.Build.0 = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Evaluation|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Evaluation|Mixed Platforms.Build.0 = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Evaluation|Win32.ActiveCfg = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Evaluation|Win32.Build.0 = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Evaluation|x64.ActiveCfg = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Evaluation|x64.Build.0 = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Exporter_Debug|ARM.ActiveCfg = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Exporter_Debug|ARM.Build.0 = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Exporter_Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Exporter_Debug|Mixed Platforms.Build.0 = Debug|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Exporter_Debug|Win32.ActiveCfg = Debug|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Exporter_Debug|Win32.Build.0 = Debug|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Exporter_Debug|x64.ActiveCfg = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Exporter_Debug|x64.Build.0 = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Exporter_Release|ARM.ActiveCfg = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Exporter_Release|ARM.Build.0 = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Exporter_Release|Mixed Platforms.ActiveCfg = Release|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Exporter_Release|Mixed Platforms.Build.0 = Release|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Exporter_Release|Win32.ActiveCfg = Release|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Exporter_Release|Win32.Build.0 = Release|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Exporter_Release|x64.ActiveCfg = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Exporter_Release|x64.Build.0 = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Hybrid|ARM.ActiveCfg = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Hybrid|ARM.Build.0 = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Hybrid|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Hybrid|Mixed Platforms.Build.0 = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Hybrid|Win32.ActiveCfg = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Hybrid|Win32.Build.0 = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Hybrid|x64.ActiveCfg = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Hybrid|x64.Build.0 = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.PyModule_Hybrid|ARM.ActiveCfg = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.PyModule_Hybrid|ARM.Build.0 = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.PyModule_Hybrid|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.PyModule_Hybrid|Mixed Platforms.Build.0 = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.PyModule_Hybrid|Win32.ActiveCfg = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.PyModule_Hybrid|Win32.Build.0 = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.PyModule_Hybrid|x64.ActiveCfg = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.PyModule_Hybrid|x64.Build.0 = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Release_Indie|ARM.ActiveCfg = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Release_Indie|ARM.Build.0 = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Release_Indie|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Release_Indie|Mixed Platforms.Build.0 = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Release_Indie|Win32.ActiveCfg = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Release_Indie|Win32.Build.0 = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Release_Indie|x64.ActiveCfg = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Release_Indie|x64.Build.0 = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Release_Manager|ARM.ActiveCfg = Release|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Release_Manager|ARM.Build.0 = Release|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Release_Manager|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Release_Manager|Mixed Platforms.Build.0 = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Release_Manager|Win32.ActiveCfg = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Release_Manager|Win32.Build.0 = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Release_Manager|x64.ActiveCfg = Release|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Release_Manager|x64.Build.0 = Release|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Release_Unicode|ARM.ActiveCfg = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Release_Unicode|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Release_Unicode|Mixed Platforms.Build.0 = Release_Unicode|Win32 {DA531A23-506A-4643-BA47-B77542C5F41C}.Release_Unicode|Win32.ActiveCfg = Release_Unicode|Win32 {DA531A23-506A-4643-BA47-B77542C5F41C}.Release_Unicode|Win32.Build.0 = Release_Unicode|Win32 {DA531A23-506A-4643-BA47-B77542C5F41C}.Release_Unicode|x64.ActiveCfg = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Release|ARM.ActiveCfg = Release|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Release|Mixed Platforms.Build.0 = Release|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Release|Win32.ActiveCfg = Release|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Release|Win32.Build.0 = Release|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Release|x64.ActiveCfg = Release|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.ReleaseVD|ARM.ActiveCfg = Release|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.ReleaseVD|ARM.Build.0 = Release|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.ReleaseVD|Mixed Platforms.ActiveCfg = Release|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.ReleaseVD|Mixed Platforms.Build.0 = Release|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.ReleaseVD|Win32.ActiveCfg = Release|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.ReleaseVD|Win32.Build.0 = Release|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.ReleaseVD|x64.ActiveCfg = Release|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.ReleaseVD|x64.Build.0 = Release|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Static_Release|ARM.ActiveCfg = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Static_Release|ARM.Build.0 = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Static_Release|Mixed Platforms.ActiveCfg = Release|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Static_Release|Mixed Platforms.Build.0 = Release|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Static_Release|Win32.ActiveCfg = Release|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Static_Release|Win32.Build.0 = Release|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Static_Release|x64.ActiveCfg = Release_Unicode|Win32 - {DA531A23-506A-4643-BA47-B77542C5F41C}.Static_Release|x64.Build.0 = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Consumer_Release_Indie|ARM.ActiveCfg = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Consumer_Release_Indie|ARM.Build.0 = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Consumer_Release_Indie|Mixed Platforms.ActiveCfg = Release|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Consumer_Release_Indie|Mixed Platforms.Build.0 = Release|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Consumer_Release_Indie|Win32.ActiveCfg = Release|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Consumer_Release_Indie|Win32.Build.0 = Release|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Consumer_Release_Indie|x64.ActiveCfg = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Consumer_Release_Indie|x64.Build.0 = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Consumer_Release|ARM.ActiveCfg = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Consumer_Release|ARM.Build.0 = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Consumer_Release|Mixed Platforms.ActiveCfg = Release|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Consumer_Release|Mixed Platforms.Build.0 = Release|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Consumer_Release|Win32.ActiveCfg = Release|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Consumer_Release|Win32.Build.0 = Release|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Consumer_Release|x64.ActiveCfg = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Consumer_Release|x64.Build.0 = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Debug_Unicode|ARM.ActiveCfg = Debug_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Debug_Unicode|Mixed Platforms.ActiveCfg = Debug_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Debug_Unicode|Mixed Platforms.Build.0 = Debug_Unicode|Win32 {74DE8924-75DC-4444-AB26-B687F71BD778}.Debug_Unicode|Win32.ActiveCfg = Debug_Unicode|Win32 {74DE8924-75DC-4444-AB26-B687F71BD778}.Debug_Unicode|Win32.Build.0 = Debug_Unicode|Win32 {74DE8924-75DC-4444-AB26-B687F71BD778}.Debug_Unicode|x64.ActiveCfg = Debug_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Debug|ARM.ActiveCfg = Debug|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Debug|Mixed Platforms.Build.0 = Debug|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Debug|Win32.ActiveCfg = Debug|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Debug|Win32.Build.0 = Debug|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Debug|x64.ActiveCfg = Debug|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.DebugVD|ARM.ActiveCfg = Release|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.DebugVD|ARM.Build.0 = Release|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.DebugVD|Mixed Platforms.ActiveCfg = Debug_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.DebugVD|Mixed Platforms.Build.0 = Debug_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.DebugVD|Win32.ActiveCfg = Debug_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.DebugVD|Win32.Build.0 = Debug_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.DebugVD|x64.ActiveCfg = Release|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.DebugVD|x64.Build.0 = Release|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Editor_Debug|ARM.ActiveCfg = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Editor_Debug|ARM.Build.0 = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Editor_Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Editor_Debug|Mixed Platforms.Build.0 = Debug|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Editor_Debug|Win32.ActiveCfg = Debug|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Editor_Debug|Win32.Build.0 = Debug|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Editor_Debug|x64.ActiveCfg = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Editor_Debug|x64.Build.0 = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Editor_Hybrid_Indie|ARM.ActiveCfg = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Editor_Hybrid_Indie|ARM.Build.0 = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Editor_Hybrid_Indie|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Editor_Hybrid_Indie|Mixed Platforms.Build.0 = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Editor_Hybrid_Indie|Win32.ActiveCfg = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Editor_Hybrid_Indie|Win32.Build.0 = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Editor_Hybrid_Indie|x64.ActiveCfg = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Editor_Hybrid_Indie|x64.Build.0 = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Editor_Hybrid|ARM.ActiveCfg = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Editor_Hybrid|ARM.Build.0 = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Editor_Hybrid|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Editor_Hybrid|Mixed Platforms.Build.0 = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Editor_Hybrid|Win32.ActiveCfg = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Editor_Hybrid|Win32.Build.0 = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Editor_Hybrid|x64.ActiveCfg = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Editor_Hybrid|x64.Build.0 = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Evaluation|ARM.ActiveCfg = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Evaluation|ARM.Build.0 = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Evaluation|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Evaluation|Mixed Platforms.Build.0 = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Evaluation|Win32.ActiveCfg = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Evaluation|Win32.Build.0 = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Evaluation|x64.ActiveCfg = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Evaluation|x64.Build.0 = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Exporter_Debug|ARM.ActiveCfg = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Exporter_Debug|ARM.Build.0 = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Exporter_Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Exporter_Debug|Mixed Platforms.Build.0 = Debug|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Exporter_Debug|Win32.ActiveCfg = Debug|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Exporter_Debug|Win32.Build.0 = Debug|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Exporter_Debug|x64.ActiveCfg = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Exporter_Debug|x64.Build.0 = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Exporter_Release|ARM.ActiveCfg = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Exporter_Release|ARM.Build.0 = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Exporter_Release|Mixed Platforms.ActiveCfg = Release|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Exporter_Release|Mixed Platforms.Build.0 = Release|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Exporter_Release|Win32.ActiveCfg = Release|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Exporter_Release|Win32.Build.0 = Release|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Exporter_Release|x64.ActiveCfg = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Exporter_Release|x64.Build.0 = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Hybrid|ARM.ActiveCfg = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Hybrid|ARM.Build.0 = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Hybrid|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Hybrid|Mixed Platforms.Build.0 = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Hybrid|Win32.ActiveCfg = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Hybrid|Win32.Build.0 = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Hybrid|x64.ActiveCfg = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Hybrid|x64.Build.0 = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.PyModule_Hybrid|ARM.ActiveCfg = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.PyModule_Hybrid|ARM.Build.0 = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.PyModule_Hybrid|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.PyModule_Hybrid|Mixed Platforms.Build.0 = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.PyModule_Hybrid|Win32.ActiveCfg = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.PyModule_Hybrid|Win32.Build.0 = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.PyModule_Hybrid|x64.ActiveCfg = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.PyModule_Hybrid|x64.Build.0 = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Release_Indie|ARM.ActiveCfg = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Release_Indie|ARM.Build.0 = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Release_Indie|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Release_Indie|Mixed Platforms.Build.0 = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Release_Indie|Win32.ActiveCfg = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Release_Indie|Win32.Build.0 = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Release_Indie|x64.ActiveCfg = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Release_Indie|x64.Build.0 = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Release_Manager|ARM.ActiveCfg = Release|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Release_Manager|ARM.Build.0 = Release|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Release_Manager|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Release_Manager|Mixed Platforms.Build.0 = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Release_Manager|Win32.ActiveCfg = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Release_Manager|Win32.Build.0 = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Release_Manager|x64.ActiveCfg = Release|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Release_Manager|x64.Build.0 = Release|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Release_Unicode|ARM.ActiveCfg = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Release_Unicode|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Release_Unicode|Mixed Platforms.Build.0 = Release_Unicode|Win32 {74DE8924-75DC-4444-AB26-B687F71BD778}.Release_Unicode|Win32.ActiveCfg = Release_Unicode|Win32 {74DE8924-75DC-4444-AB26-B687F71BD778}.Release_Unicode|Win32.Build.0 = Release_Unicode|Win32 {74DE8924-75DC-4444-AB26-B687F71BD778}.Release_Unicode|x64.ActiveCfg = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Release|ARM.ActiveCfg = Release|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Release|Mixed Platforms.Build.0 = Release|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Release|Win32.ActiveCfg = Release|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Release|Win32.Build.0 = Release|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Release|x64.ActiveCfg = Release|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.ReleaseVD|ARM.ActiveCfg = Release|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.ReleaseVD|ARM.Build.0 = Release|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.ReleaseVD|Mixed Platforms.ActiveCfg = Release|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.ReleaseVD|Mixed Platforms.Build.0 = Release|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.ReleaseVD|Win32.ActiveCfg = Release|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.ReleaseVD|Win32.Build.0 = Release|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.ReleaseVD|x64.ActiveCfg = Release|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.ReleaseVD|x64.Build.0 = Release|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Static_Release|ARM.ActiveCfg = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Static_Release|ARM.Build.0 = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Static_Release|Mixed Platforms.ActiveCfg = Release|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Static_Release|Mixed Platforms.Build.0 = Release|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Static_Release|Win32.ActiveCfg = Release|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Static_Release|Win32.Build.0 = Release|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Static_Release|x64.ActiveCfg = Release_Unicode|Win32 - {74DE8924-75DC-4444-AB26-B687F71BD778}.Static_Release|x64.Build.0 = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Consumer_Release_Indie|ARM.ActiveCfg = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Consumer_Release_Indie|ARM.Build.0 = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Consumer_Release_Indie|Mixed Platforms.ActiveCfg = Release|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Consumer_Release_Indie|Mixed Platforms.Build.0 = Release|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Consumer_Release_Indie|Win32.ActiveCfg = Release|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Consumer_Release_Indie|Win32.Build.0 = Release|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Consumer_Release_Indie|x64.ActiveCfg = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Consumer_Release_Indie|x64.Build.0 = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Consumer_Release|ARM.ActiveCfg = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Consumer_Release|ARM.Build.0 = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Consumer_Release|Mixed Platforms.ActiveCfg = Release|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Consumer_Release|Mixed Platforms.Build.0 = Release|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Consumer_Release|Win32.ActiveCfg = Release|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Consumer_Release|Win32.Build.0 = Release|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Consumer_Release|x64.ActiveCfg = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Consumer_Release|x64.Build.0 = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Debug_Unicode|ARM.ActiveCfg = Debug_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Debug_Unicode|Mixed Platforms.ActiveCfg = Debug_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Debug_Unicode|Mixed Platforms.Build.0 = Debug_Unicode|Win32 {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Debug_Unicode|Win32.ActiveCfg = Debug_Unicode|Win32 {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Debug_Unicode|Win32.Build.0 = Debug_Unicode|Win32 {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Debug_Unicode|x64.ActiveCfg = Debug_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Debug|ARM.ActiveCfg = Debug|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Debug|Mixed Platforms.Build.0 = Debug|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Debug|Win32.ActiveCfg = Debug|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Debug|Win32.Build.0 = Debug|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Debug|x64.ActiveCfg = Debug|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.DebugVD|ARM.ActiveCfg = Release|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.DebugVD|ARM.Build.0 = Release|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.DebugVD|Mixed Platforms.ActiveCfg = Debug_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.DebugVD|Mixed Platforms.Build.0 = Debug_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.DebugVD|Win32.ActiveCfg = Debug_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.DebugVD|Win32.Build.0 = Debug_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.DebugVD|x64.ActiveCfg = Release|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.DebugVD|x64.Build.0 = Release|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Editor_Debug|ARM.ActiveCfg = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Editor_Debug|ARM.Build.0 = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Editor_Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Editor_Debug|Mixed Platforms.Build.0 = Debug|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Editor_Debug|Win32.ActiveCfg = Debug|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Editor_Debug|Win32.Build.0 = Debug|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Editor_Debug|x64.ActiveCfg = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Editor_Debug|x64.Build.0 = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Editor_Hybrid_Indie|ARM.ActiveCfg = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Editor_Hybrid_Indie|ARM.Build.0 = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Editor_Hybrid_Indie|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Editor_Hybrid_Indie|Mixed Platforms.Build.0 = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Editor_Hybrid_Indie|Win32.ActiveCfg = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Editor_Hybrid_Indie|Win32.Build.0 = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Editor_Hybrid_Indie|x64.ActiveCfg = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Editor_Hybrid_Indie|x64.Build.0 = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Editor_Hybrid|ARM.ActiveCfg = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Editor_Hybrid|ARM.Build.0 = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Editor_Hybrid|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Editor_Hybrid|Mixed Platforms.Build.0 = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Editor_Hybrid|Win32.ActiveCfg = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Editor_Hybrid|Win32.Build.0 = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Editor_Hybrid|x64.ActiveCfg = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Editor_Hybrid|x64.Build.0 = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Evaluation|ARM.ActiveCfg = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Evaluation|ARM.Build.0 = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Evaluation|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Evaluation|Mixed Platforms.Build.0 = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Evaluation|Win32.ActiveCfg = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Evaluation|Win32.Build.0 = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Evaluation|x64.ActiveCfg = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Evaluation|x64.Build.0 = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Exporter_Debug|ARM.ActiveCfg = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Exporter_Debug|ARM.Build.0 = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Exporter_Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Exporter_Debug|Mixed Platforms.Build.0 = Debug|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Exporter_Debug|Win32.ActiveCfg = Debug|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Exporter_Debug|Win32.Build.0 = Debug|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Exporter_Debug|x64.ActiveCfg = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Exporter_Debug|x64.Build.0 = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Exporter_Release|ARM.ActiveCfg = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Exporter_Release|ARM.Build.0 = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Exporter_Release|Mixed Platforms.ActiveCfg = Release|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Exporter_Release|Mixed Platforms.Build.0 = Release|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Exporter_Release|Win32.ActiveCfg = Release|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Exporter_Release|Win32.Build.0 = Release|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Exporter_Release|x64.ActiveCfg = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Exporter_Release|x64.Build.0 = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Hybrid|ARM.ActiveCfg = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Hybrid|ARM.Build.0 = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Hybrid|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Hybrid|Mixed Platforms.Build.0 = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Hybrid|Win32.ActiveCfg = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Hybrid|Win32.Build.0 = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Hybrid|x64.ActiveCfg = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Hybrid|x64.Build.0 = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.PyModule_Hybrid|ARM.ActiveCfg = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.PyModule_Hybrid|ARM.Build.0 = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.PyModule_Hybrid|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.PyModule_Hybrid|Mixed Platforms.Build.0 = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.PyModule_Hybrid|Win32.ActiveCfg = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.PyModule_Hybrid|Win32.Build.0 = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.PyModule_Hybrid|x64.ActiveCfg = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.PyModule_Hybrid|x64.Build.0 = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Release_Indie|ARM.ActiveCfg = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Release_Indie|ARM.Build.0 = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Release_Indie|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Release_Indie|Mixed Platforms.Build.0 = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Release_Indie|Win32.ActiveCfg = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Release_Indie|Win32.Build.0 = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Release_Indie|x64.ActiveCfg = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Release_Indie|x64.Build.0 = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Release_Manager|ARM.ActiveCfg = Release|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Release_Manager|ARM.Build.0 = Release|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Release_Manager|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Release_Manager|Mixed Platforms.Build.0 = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Release_Manager|Win32.ActiveCfg = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Release_Manager|Win32.Build.0 = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Release_Manager|x64.ActiveCfg = Release|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Release_Manager|x64.Build.0 = Release|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Release_Unicode|ARM.ActiveCfg = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Release_Unicode|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Release_Unicode|Mixed Platforms.Build.0 = Release_Unicode|Win32 {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Release_Unicode|Win32.ActiveCfg = Release_Unicode|Win32 {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Release_Unicode|Win32.Build.0 = Release_Unicode|Win32 {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Release_Unicode|x64.ActiveCfg = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Release|ARM.ActiveCfg = Release|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Release|Mixed Platforms.Build.0 = Release|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Release|Win32.ActiveCfg = Release|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Release|Win32.Build.0 = Release|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Release|x64.ActiveCfg = Release|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.ReleaseVD|ARM.ActiveCfg = Release|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.ReleaseVD|ARM.Build.0 = Release|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.ReleaseVD|Mixed Platforms.ActiveCfg = Release|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.ReleaseVD|Mixed Platforms.Build.0 = Release|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.ReleaseVD|Win32.ActiveCfg = Release|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.ReleaseVD|Win32.Build.0 = Release|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.ReleaseVD|x64.ActiveCfg = Release|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.ReleaseVD|x64.Build.0 = Release|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Static_Release|ARM.ActiveCfg = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Static_Release|ARM.Build.0 = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Static_Release|Mixed Platforms.ActiveCfg = Release|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Static_Release|Mixed Platforms.Build.0 = Release|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Static_Release|Win32.ActiveCfg = Release|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Static_Release|Win32.Build.0 = Release|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Static_Release|x64.ActiveCfg = Release_Unicode|Win32 - {C323A106-B50D-48CB-A353-CFBE5308F2A5}.Static_Release|x64.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Consumer_Release_Indie|ARM.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Consumer_Release_Indie|ARM.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Consumer_Release_Indie|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Consumer_Release_Indie|Mixed Platforms.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Consumer_Release_Indie|Win32.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Consumer_Release_Indie|Win32.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Consumer_Release_Indie|x64.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Consumer_Release_Indie|x64.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Consumer_Release|ARM.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Consumer_Release|ARM.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Consumer_Release|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Consumer_Release|Mixed Platforms.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Consumer_Release|Win32.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Consumer_Release|Win32.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Consumer_Release|x64.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Consumer_Release|x64.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Debug_Unicode|ARM.ActiveCfg = Debug_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Debug_Unicode|Mixed Platforms.ActiveCfg = Debug_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Debug_Unicode|Mixed Platforms.Build.0 = Debug_Unicode|Win32 {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Debug_Unicode|Win32.ActiveCfg = Debug_Unicode|Win32 {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Debug_Unicode|Win32.Build.0 = Debug_Unicode|Win32 {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Debug_Unicode|x64.ActiveCfg = Debug_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Debug|ARM.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Debug|ARM.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Debug|Mixed Platforms.ActiveCfg = Debug_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Debug|Mixed Platforms.Build.0 = Debug_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Debug|Win32.ActiveCfg = Debug_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Debug|Win32.Build.0 = Debug_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Debug|x64.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Debug|x64.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.DebugVD|ARM.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.DebugVD|ARM.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.DebugVD|Mixed Platforms.ActiveCfg = Debug_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.DebugVD|Mixed Platforms.Build.0 = Debug_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.DebugVD|Win32.ActiveCfg = Debug_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.DebugVD|Win32.Build.0 = Debug_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.DebugVD|x64.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.DebugVD|x64.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Editor_Debug|ARM.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Editor_Debug|ARM.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Editor_Debug|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Editor_Debug|Mixed Platforms.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Editor_Debug|Win32.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Editor_Debug|Win32.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Editor_Debug|x64.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Editor_Debug|x64.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Editor_Hybrid_Indie|ARM.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Editor_Hybrid_Indie|ARM.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Editor_Hybrid_Indie|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Editor_Hybrid_Indie|Mixed Platforms.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Editor_Hybrid_Indie|Win32.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Editor_Hybrid_Indie|Win32.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Editor_Hybrid_Indie|x64.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Editor_Hybrid_Indie|x64.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Editor_Hybrid|ARM.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Editor_Hybrid|ARM.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Editor_Hybrid|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Editor_Hybrid|Mixed Platforms.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Editor_Hybrid|Win32.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Editor_Hybrid|Win32.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Editor_Hybrid|x64.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Editor_Hybrid|x64.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Evaluation|ARM.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Evaluation|ARM.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Evaluation|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Evaluation|Mixed Platforms.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Evaluation|Win32.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Evaluation|Win32.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Evaluation|x64.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Evaluation|x64.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Exporter_Debug|ARM.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Exporter_Debug|ARM.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Exporter_Debug|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Exporter_Debug|Mixed Platforms.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Exporter_Debug|Win32.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Exporter_Debug|Win32.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Exporter_Debug|x64.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Exporter_Debug|x64.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Exporter_Release|ARM.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Exporter_Release|ARM.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Exporter_Release|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Exporter_Release|Mixed Platforms.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Exporter_Release|Win32.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Exporter_Release|Win32.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Exporter_Release|x64.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Exporter_Release|x64.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Hybrid|ARM.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Hybrid|ARM.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Hybrid|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Hybrid|Mixed Platforms.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Hybrid|Win32.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Hybrid|Win32.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Hybrid|x64.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Hybrid|x64.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.PyModule_Hybrid|ARM.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.PyModule_Hybrid|ARM.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.PyModule_Hybrid|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.PyModule_Hybrid|Mixed Platforms.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.PyModule_Hybrid|Win32.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.PyModule_Hybrid|Win32.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.PyModule_Hybrid|x64.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.PyModule_Hybrid|x64.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Release_Indie|ARM.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Release_Indie|ARM.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Release_Indie|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Release_Indie|Mixed Platforms.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Release_Indie|Win32.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Release_Indie|Win32.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Release_Indie|x64.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Release_Indie|x64.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Release_Manager|ARM.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Release_Manager|ARM.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Release_Manager|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Release_Manager|Mixed Platforms.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Release_Manager|Win32.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Release_Manager|Win32.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Release_Manager|x64.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Release_Manager|x64.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Release_Unicode|ARM.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Release_Unicode|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Release_Unicode|Mixed Platforms.Build.0 = Release_Unicode|Win32 {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Release_Unicode|Win32.ActiveCfg = Release_Unicode|Win32 {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Release_Unicode|Win32.Build.0 = Release_Unicode|Win32 {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Release_Unicode|x64.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Release|ARM.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Release|ARM.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Release|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Release|Mixed Platforms.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Release|Win32.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Release|Win32.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Release|x64.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Release|x64.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.ReleaseVD|ARM.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.ReleaseVD|ARM.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.ReleaseVD|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.ReleaseVD|Mixed Platforms.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.ReleaseVD|Win32.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.ReleaseVD|Win32.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.ReleaseVD|x64.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.ReleaseVD|x64.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Static_Release|ARM.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Static_Release|ARM.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Static_Release|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Static_Release|Mixed Platforms.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Static_Release|Win32.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Static_Release|Win32.Build.0 = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Static_Release|x64.ActiveCfg = Release_Unicode|Win32 - {660F9BCF-23A3-425A-9BDC-40D7AFBC8DFB}.Static_Release|x64.Build.0 = Release_Unicode|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Consumer_Release_Indie|ARM.ActiveCfg = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Consumer_Release_Indie|ARM.Build.0 = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Consumer_Release_Indie|Mixed Platforms.ActiveCfg = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Consumer_Release_Indie|Mixed Platforms.Build.0 = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Consumer_Release_Indie|Win32.ActiveCfg = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Consumer_Release_Indie|Win32.Build.0 = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Consumer_Release_Indie|x64.ActiveCfg = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Consumer_Release_Indie|x64.Build.0 = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Consumer_Release|ARM.ActiveCfg = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Consumer_Release|ARM.Build.0 = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Consumer_Release|Mixed Platforms.ActiveCfg = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Consumer_Release|Mixed Platforms.Build.0 = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Consumer_Release|Win32.ActiveCfg = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Consumer_Release|Win32.Build.0 = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Consumer_Release|x64.ActiveCfg = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Consumer_Release|x64.Build.0 = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Debug_Unicode|ARM.ActiveCfg = Debug_Unicode|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Debug_Unicode|Mixed Platforms.ActiveCfg = Debug_Unicode|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Debug_Unicode|Mixed Platforms.Build.0 = Debug_Unicode|Win32 {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Debug_Unicode|Win32.ActiveCfg = Debug_Unicode|Win32 {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Debug_Unicode|Win32.Build.0 = Debug_Unicode|Win32 {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Debug_Unicode|x64.ActiveCfg = Debug_Unicode|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Debug|ARM.ActiveCfg = Debug|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Debug|Mixed Platforms.Build.0 = Debug|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Debug|Win32.ActiveCfg = Debug|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Debug|Win32.Build.0 = Debug|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Debug|x64.ActiveCfg = Debug|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.DebugVD|ARM.ActiveCfg = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.DebugVD|ARM.Build.0 = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.DebugVD|Mixed Platforms.ActiveCfg = Debug|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.DebugVD|Mixed Platforms.Build.0 = Debug|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.DebugVD|Win32.ActiveCfg = Debug|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.DebugVD|Win32.Build.0 = Debug|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.DebugVD|x64.ActiveCfg = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.DebugVD|x64.Build.0 = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Editor_Debug|ARM.ActiveCfg = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Editor_Debug|ARM.Build.0 = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Editor_Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Editor_Debug|Mixed Platforms.Build.0 = Debug|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Editor_Debug|Win32.ActiveCfg = Debug|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Editor_Debug|Win32.Build.0 = Debug|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Editor_Debug|x64.ActiveCfg = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Editor_Debug|x64.Build.0 = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Editor_Hybrid_Indie|ARM.ActiveCfg = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Editor_Hybrid_Indie|ARM.Build.0 = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Editor_Hybrid_Indie|Mixed Platforms.ActiveCfg = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Editor_Hybrid_Indie|Mixed Platforms.Build.0 = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Editor_Hybrid_Indie|Win32.ActiveCfg = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Editor_Hybrid_Indie|Win32.Build.0 = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Editor_Hybrid_Indie|x64.ActiveCfg = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Editor_Hybrid_Indie|x64.Build.0 = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Editor_Hybrid|ARM.ActiveCfg = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Editor_Hybrid|ARM.Build.0 = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Editor_Hybrid|Mixed Platforms.ActiveCfg = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Editor_Hybrid|Mixed Platforms.Build.0 = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Editor_Hybrid|Win32.ActiveCfg = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Editor_Hybrid|Win32.Build.0 = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Editor_Hybrid|x64.ActiveCfg = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Editor_Hybrid|x64.Build.0 = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Evaluation|ARM.ActiveCfg = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Evaluation|ARM.Build.0 = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Evaluation|Mixed Platforms.ActiveCfg = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Evaluation|Mixed Platforms.Build.0 = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Evaluation|Win32.ActiveCfg = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Evaluation|Win32.Build.0 = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Evaluation|x64.ActiveCfg = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Evaluation|x64.Build.0 = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Exporter_Debug|ARM.ActiveCfg = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Exporter_Debug|ARM.Build.0 = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Exporter_Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Exporter_Debug|Mixed Platforms.Build.0 = Debug|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Exporter_Debug|Win32.ActiveCfg = Debug|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Exporter_Debug|Win32.Build.0 = Debug|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Exporter_Debug|x64.ActiveCfg = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Exporter_Debug|x64.Build.0 = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Exporter_Release|ARM.ActiveCfg = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Exporter_Release|ARM.Build.0 = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Exporter_Release|Mixed Platforms.ActiveCfg = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Exporter_Release|Mixed Platforms.Build.0 = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Exporter_Release|Win32.ActiveCfg = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Exporter_Release|Win32.Build.0 = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Exporter_Release|x64.ActiveCfg = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Exporter_Release|x64.Build.0 = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Hybrid|ARM.ActiveCfg = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Hybrid|ARM.Build.0 = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Hybrid|Mixed Platforms.ActiveCfg = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Hybrid|Mixed Platforms.Build.0 = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Hybrid|Win32.ActiveCfg = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Hybrid|Win32.Build.0 = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Hybrid|x64.ActiveCfg = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Hybrid|x64.Build.0 = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.PyModule_Hybrid|ARM.ActiveCfg = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.PyModule_Hybrid|ARM.Build.0 = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.PyModule_Hybrid|Mixed Platforms.ActiveCfg = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.PyModule_Hybrid|Mixed Platforms.Build.0 = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.PyModule_Hybrid|Win32.ActiveCfg = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.PyModule_Hybrid|Win32.Build.0 = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.PyModule_Hybrid|x64.ActiveCfg = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.PyModule_Hybrid|x64.Build.0 = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Release_Indie|ARM.ActiveCfg = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Release_Indie|ARM.Build.0 = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Release_Indie|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Release_Indie|Mixed Platforms.Build.0 = Release_Unicode|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Release_Indie|Win32.ActiveCfg = Release_Unicode|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Release_Indie|Win32.Build.0 = Release_Unicode|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Release_Indie|x64.ActiveCfg = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Release_Indie|x64.Build.0 = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Release_Manager|ARM.ActiveCfg = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Release_Manager|ARM.Build.0 = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Release_Manager|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Release_Manager|Mixed Platforms.Build.0 = Release_Unicode|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Release_Manager|Win32.ActiveCfg = Release_Unicode|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Release_Manager|Win32.Build.0 = Release_Unicode|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Release_Manager|x64.ActiveCfg = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Release_Manager|x64.Build.0 = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Release_Unicode|ARM.ActiveCfg = Release_Unicode|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Release_Unicode|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Release_Unicode|Mixed Platforms.Build.0 = Release_Unicode|Win32 {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Release_Unicode|Win32.ActiveCfg = Release_Unicode|Win32 {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Release_Unicode|Win32.Build.0 = Release_Unicode|Win32 {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Release_Unicode|x64.ActiveCfg = Release_Unicode|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Release|ARM.ActiveCfg = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Release|Mixed Platforms.Build.0 = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Release|Win32.ActiveCfg = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Release|Win32.Build.0 = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Release|x64.ActiveCfg = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.ReleaseVD|ARM.ActiveCfg = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.ReleaseVD|ARM.Build.0 = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.ReleaseVD|Mixed Platforms.ActiveCfg = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.ReleaseVD|Mixed Platforms.Build.0 = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.ReleaseVD|Win32.ActiveCfg = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.ReleaseVD|Win32.Build.0 = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.ReleaseVD|x64.ActiveCfg = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.ReleaseVD|x64.Build.0 = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Static_Release|ARM.ActiveCfg = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Static_Release|ARM.Build.0 = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Static_Release|Mixed Platforms.ActiveCfg = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Static_Release|Mixed Platforms.Build.0 = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Static_Release|Win32.ActiveCfg = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Static_Release|Win32.Build.0 = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Static_Release|x64.ActiveCfg = Release|Win32 - {60710DEB-8538-4CB6-8ABA-3A143E451C21}.Static_Release|x64.Build.0 = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Consumer_Release_Indie|ARM.ActiveCfg = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Consumer_Release_Indie|ARM.Build.0 = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Consumer_Release_Indie|Mixed Platforms.ActiveCfg = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Consumer_Release_Indie|Mixed Platforms.Build.0 = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Consumer_Release_Indie|Win32.ActiveCfg = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Consumer_Release_Indie|Win32.Build.0 = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Consumer_Release_Indie|x64.ActiveCfg = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Consumer_Release_Indie|x64.Build.0 = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Consumer_Release|ARM.ActiveCfg = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Consumer_Release|ARM.Build.0 = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Consumer_Release|Mixed Platforms.ActiveCfg = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Consumer_Release|Mixed Platforms.Build.0 = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Consumer_Release|Win32.ActiveCfg = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Consumer_Release|Win32.Build.0 = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Consumer_Release|x64.ActiveCfg = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Consumer_Release|x64.Build.0 = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Debug_Unicode|ARM.ActiveCfg = Debug_Unicode|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Debug_Unicode|Mixed Platforms.ActiveCfg = Debug_Unicode|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Debug_Unicode|Mixed Platforms.Build.0 = Debug_Unicode|Win32 {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Debug_Unicode|Win32.ActiveCfg = Debug_Unicode|Win32 {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Debug_Unicode|Win32.Build.0 = Debug_Unicode|Win32 {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Debug_Unicode|x64.ActiveCfg = Debug_Unicode|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Debug|ARM.ActiveCfg = Debug|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Debug|Mixed Platforms.Build.0 = Debug|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Debug|Win32.ActiveCfg = Debug|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Debug|Win32.Build.0 = Debug|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Debug|x64.ActiveCfg = Debug|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.DebugVD|ARM.ActiveCfg = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.DebugVD|ARM.Build.0 = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.DebugVD|Mixed Platforms.ActiveCfg = Debug_Unicode|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.DebugVD|Mixed Platforms.Build.0 = Debug_Unicode|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.DebugVD|Win32.ActiveCfg = Debug_Unicode|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.DebugVD|Win32.Build.0 = Debug_Unicode|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.DebugVD|x64.ActiveCfg = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.DebugVD|x64.Build.0 = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Editor_Debug|ARM.ActiveCfg = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Editor_Debug|ARM.Build.0 = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Editor_Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Editor_Debug|Mixed Platforms.Build.0 = Debug|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Editor_Debug|Win32.ActiveCfg = Debug|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Editor_Debug|Win32.Build.0 = Debug|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Editor_Debug|x64.ActiveCfg = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Editor_Debug|x64.Build.0 = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Editor_Hybrid_Indie|ARM.ActiveCfg = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Editor_Hybrid_Indie|ARM.Build.0 = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Editor_Hybrid_Indie|Mixed Platforms.ActiveCfg = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Editor_Hybrid_Indie|Mixed Platforms.Build.0 = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Editor_Hybrid_Indie|Win32.ActiveCfg = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Editor_Hybrid_Indie|Win32.Build.0 = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Editor_Hybrid_Indie|x64.ActiveCfg = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Editor_Hybrid_Indie|x64.Build.0 = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Editor_Hybrid|ARM.ActiveCfg = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Editor_Hybrid|ARM.Build.0 = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Editor_Hybrid|Mixed Platforms.ActiveCfg = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Editor_Hybrid|Mixed Platforms.Build.0 = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Editor_Hybrid|Win32.ActiveCfg = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Editor_Hybrid|Win32.Build.0 = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Editor_Hybrid|x64.ActiveCfg = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Editor_Hybrid|x64.Build.0 = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Evaluation|ARM.ActiveCfg = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Evaluation|ARM.Build.0 = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Evaluation|Mixed Platforms.ActiveCfg = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Evaluation|Mixed Platforms.Build.0 = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Evaluation|Win32.ActiveCfg = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Evaluation|Win32.Build.0 = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Evaluation|x64.ActiveCfg = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Evaluation|x64.Build.0 = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Exporter_Debug|ARM.ActiveCfg = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Exporter_Debug|ARM.Build.0 = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Exporter_Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Exporter_Debug|Mixed Platforms.Build.0 = Debug|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Exporter_Debug|Win32.ActiveCfg = Debug|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Exporter_Debug|Win32.Build.0 = Debug|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Exporter_Debug|x64.ActiveCfg = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Exporter_Debug|x64.Build.0 = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Exporter_Release|ARM.ActiveCfg = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Exporter_Release|ARM.Build.0 = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Exporter_Release|Mixed Platforms.ActiveCfg = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Exporter_Release|Mixed Platforms.Build.0 = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Exporter_Release|Win32.ActiveCfg = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Exporter_Release|Win32.Build.0 = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Exporter_Release|x64.ActiveCfg = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Exporter_Release|x64.Build.0 = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Hybrid|ARM.ActiveCfg = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Hybrid|ARM.Build.0 = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Hybrid|Mixed Platforms.ActiveCfg = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Hybrid|Mixed Platforms.Build.0 = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Hybrid|Win32.ActiveCfg = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Hybrid|Win32.Build.0 = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Hybrid|x64.ActiveCfg = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Hybrid|x64.Build.0 = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.PyModule_Hybrid|ARM.ActiveCfg = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.PyModule_Hybrid|ARM.Build.0 = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.PyModule_Hybrid|Mixed Platforms.ActiveCfg = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.PyModule_Hybrid|Mixed Platforms.Build.0 = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.PyModule_Hybrid|Win32.ActiveCfg = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.PyModule_Hybrid|Win32.Build.0 = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.PyModule_Hybrid|x64.ActiveCfg = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.PyModule_Hybrid|x64.Build.0 = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Release_Indie|ARM.ActiveCfg = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Release_Indie|ARM.Build.0 = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Release_Indie|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Release_Indie|Mixed Platforms.Build.0 = Release_Unicode|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Release_Indie|Win32.ActiveCfg = Release_Unicode|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Release_Indie|Win32.Build.0 = Release_Unicode|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Release_Indie|x64.ActiveCfg = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Release_Indie|x64.Build.0 = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Release_Manager|ARM.ActiveCfg = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Release_Manager|ARM.Build.0 = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Release_Manager|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Release_Manager|Mixed Platforms.Build.0 = Release_Unicode|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Release_Manager|Win32.ActiveCfg = Release_Unicode|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Release_Manager|Win32.Build.0 = Release_Unicode|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Release_Manager|x64.ActiveCfg = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Release_Manager|x64.Build.0 = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Release_Unicode|ARM.ActiveCfg = Release_Unicode|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Release_Unicode|Mixed Platforms.ActiveCfg = Release_Unicode|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Release_Unicode|Mixed Platforms.Build.0 = Release_Unicode|Win32 {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Release_Unicode|Win32.ActiveCfg = Release_Unicode|Win32 {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Release_Unicode|Win32.Build.0 = Release_Unicode|Win32 {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Release_Unicode|x64.ActiveCfg = Release_Unicode|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Release|ARM.ActiveCfg = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Release|Mixed Platforms.Build.0 = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Release|Win32.ActiveCfg = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Release|Win32.Build.0 = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Release|x64.ActiveCfg = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.ReleaseVD|ARM.ActiveCfg = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.ReleaseVD|ARM.Build.0 = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.ReleaseVD|Mixed Platforms.ActiveCfg = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.ReleaseVD|Mixed Platforms.Build.0 = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.ReleaseVD|Win32.ActiveCfg = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.ReleaseVD|Win32.Build.0 = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.ReleaseVD|x64.ActiveCfg = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.ReleaseVD|x64.Build.0 = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Static_Release|ARM.ActiveCfg = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Static_Release|ARM.Build.0 = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Static_Release|Mixed Platforms.ActiveCfg = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Static_Release|Mixed Platforms.Build.0 = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Static_Release|Win32.ActiveCfg = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Static_Release|Win32.Build.0 = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Static_Release|x64.ActiveCfg = Release|Win32 - {B4766ADF-5AA6-4ADF-9354-4F889FFF028E}.Static_Release|x64.Build.0 = Release|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Consumer_Release_Indie|ARM.ActiveCfg = Release|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Consumer_Release_Indie|ARM.Build.0 = Release|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Consumer_Release_Indie|Mixed Platforms.ActiveCfg = Release|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Consumer_Release_Indie|Mixed Platforms.Build.0 = Release|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Consumer_Release_Indie|Win32.ActiveCfg = Release|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Consumer_Release_Indie|Win32.Build.0 = Release|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Consumer_Release_Indie|x64.ActiveCfg = Release|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Consumer_Release_Indie|x64.Build.0 = Release|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Consumer_Release|ARM.ActiveCfg = Release|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Consumer_Release|ARM.Build.0 = Release|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Consumer_Release|Mixed Platforms.ActiveCfg = Release|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Consumer_Release|Mixed Platforms.Build.0 = Release|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Consumer_Release|Win32.ActiveCfg = Release|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Consumer_Release|Win32.Build.0 = Release|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Consumer_Release|x64.ActiveCfg = Release|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Consumer_Release|x64.Build.0 = Release|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Debug_Unicode|ARM.ActiveCfg = Release|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Debug_Unicode|ARM.Build.0 = Release|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Debug_Unicode|Mixed Platforms.ActiveCfg = Debug|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Debug_Unicode|Mixed Platforms.Build.0 = Debug|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Debug_Unicode|Win32.ActiveCfg = Debug|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Debug_Unicode|Win32.Build.0 = Debug|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Debug_Unicode|x64.ActiveCfg = Debug|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Debug_Unicode|x64.Build.0 = Debug|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Debug|ARM.ActiveCfg = Debug|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Debug|Mixed Platforms.Build.0 = Debug|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Debug|Win32.ActiveCfg = Debug|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Debug|Win32.Build.0 = Debug|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Debug|x64.ActiveCfg = Debug|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Debug|x64.Build.0 = Debug|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.DebugVD|ARM.ActiveCfg = Release|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.DebugVD|ARM.Build.0 = Release|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.DebugVD|Mixed Platforms.ActiveCfg = Debug|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.DebugVD|Mixed Platforms.Build.0 = Debug|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.DebugVD|Win32.ActiveCfg = Debug|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.DebugVD|Win32.Build.0 = Debug|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.DebugVD|x64.ActiveCfg = Debug|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.DebugVD|x64.Build.0 = Debug|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Editor_Debug|ARM.ActiveCfg = Release|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Editor_Debug|ARM.Build.0 = Release|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Editor_Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Editor_Debug|Mixed Platforms.Build.0 = Debug|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Editor_Debug|Win32.ActiveCfg = Debug|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Editor_Debug|Win32.Build.0 = Debug|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Editor_Debug|x64.ActiveCfg = Debug|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Editor_Debug|x64.Build.0 = Debug|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Editor_Hybrid_Indie|ARM.ActiveCfg = Release|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Editor_Hybrid_Indie|ARM.Build.0 = Release|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Editor_Hybrid_Indie|Mixed Platforms.ActiveCfg = Release|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Editor_Hybrid_Indie|Mixed Platforms.Build.0 = Release|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Editor_Hybrid_Indie|Win32.ActiveCfg = Release|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Editor_Hybrid_Indie|Win32.Build.0 = Release|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Editor_Hybrid_Indie|x64.ActiveCfg = Release|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Editor_Hybrid_Indie|x64.Build.0 = Release|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Editor_Hybrid|ARM.ActiveCfg = Release|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Editor_Hybrid|ARM.Build.0 = Release|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Editor_Hybrid|Mixed Platforms.ActiveCfg = Release|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Editor_Hybrid|Mixed Platforms.Build.0 = Release|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Editor_Hybrid|Win32.ActiveCfg = Release|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Editor_Hybrid|Win32.Build.0 = Release|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Editor_Hybrid|x64.ActiveCfg = Release|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Editor_Hybrid|x64.Build.0 = Release|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Evaluation|ARM.ActiveCfg = Release|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Evaluation|ARM.Build.0 = Release|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Evaluation|Mixed Platforms.ActiveCfg = Release|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Evaluation|Mixed Platforms.Build.0 = Release|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Evaluation|Win32.ActiveCfg = Release|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Evaluation|Win32.Build.0 = Release|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Evaluation|x64.ActiveCfg = Release|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Evaluation|x64.Build.0 = Release|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Exporter_Debug|ARM.ActiveCfg = Release|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Exporter_Debug|ARM.Build.0 = Release|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Exporter_Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Exporter_Debug|Mixed Platforms.Build.0 = Debug|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Exporter_Debug|Win32.ActiveCfg = Debug|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Exporter_Debug|Win32.Build.0 = Debug|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Exporter_Debug|x64.ActiveCfg = Debug|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Exporter_Debug|x64.Build.0 = Debug|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Exporter_Release|ARM.ActiveCfg = Release|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Exporter_Release|ARM.Build.0 = Release|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Exporter_Release|Mixed Platforms.ActiveCfg = Release|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Exporter_Release|Mixed Platforms.Build.0 = Release|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Exporter_Release|Win32.ActiveCfg = Release|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Exporter_Release|Win32.Build.0 = Release|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Exporter_Release|x64.ActiveCfg = Release|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Exporter_Release|x64.Build.0 = Release|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Hybrid|ARM.ActiveCfg = Release|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Hybrid|ARM.Build.0 = Release|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Hybrid|Mixed Platforms.ActiveCfg = Release|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Hybrid|Mixed Platforms.Build.0 = Release|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Hybrid|Win32.ActiveCfg = Release|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Hybrid|Win32.Build.0 = Release|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Hybrid|x64.ActiveCfg = Release|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Hybrid|x64.Build.0 = Release|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.PyModule_Hybrid|ARM.ActiveCfg = Release|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.PyModule_Hybrid|ARM.Build.0 = Release|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.PyModule_Hybrid|Mixed Platforms.ActiveCfg = Release|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.PyModule_Hybrid|Mixed Platforms.Build.0 = Release|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.PyModule_Hybrid|Win32.ActiveCfg = Release|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.PyModule_Hybrid|Win32.Build.0 = Release|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.PyModule_Hybrid|x64.ActiveCfg = Release|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.PyModule_Hybrid|x64.Build.0 = Release|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Release_Indie|ARM.ActiveCfg = Release|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Release_Indie|ARM.Build.0 = Release|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Release_Indie|Mixed Platforms.ActiveCfg = Release|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Release_Indie|Mixed Platforms.Build.0 = Release|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Release_Indie|Win32.ActiveCfg = Release|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Release_Indie|Win32.Build.0 = Release|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Release_Indie|x64.ActiveCfg = Release|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Release_Indie|x64.Build.0 = Release|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Release_Manager|ARM.ActiveCfg = Release|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Release_Manager|ARM.Build.0 = Release|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Release_Manager|Mixed Platforms.ActiveCfg = Release|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Release_Manager|Mixed Platforms.Build.0 = Release|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Release_Manager|Win32.ActiveCfg = Release|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Release_Manager|Win32.Build.0 = Release|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Release_Manager|x64.ActiveCfg = Release|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Release_Manager|x64.Build.0 = Release|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Release_Unicode|ARM.ActiveCfg = Release|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Release_Unicode|ARM.Build.0 = Release|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Release_Unicode|Mixed Platforms.ActiveCfg = Release|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Release_Unicode|Mixed Platforms.Build.0 = Release|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Release_Unicode|Win32.ActiveCfg = Release|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Release_Unicode|Win32.Build.0 = Release|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Release_Unicode|x64.ActiveCfg = Release|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Release_Unicode|x64.Build.0 = Release|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Release|ARM.ActiveCfg = Release|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Release|Mixed Platforms.Build.0 = Release|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Release|Win32.ActiveCfg = Release|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Release|Win32.Build.0 = Release|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Release|x64.ActiveCfg = Release|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Release|x64.Build.0 = Release|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.ReleaseVD|ARM.ActiveCfg = Release|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.ReleaseVD|ARM.Build.0 = Release|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.ReleaseVD|Mixed Platforms.ActiveCfg = Release|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.ReleaseVD|Mixed Platforms.Build.0 = Release|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.ReleaseVD|Win32.ActiveCfg = Release|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.ReleaseVD|Win32.Build.0 = Release|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.ReleaseVD|x64.ActiveCfg = Release|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.ReleaseVD|x64.Build.0 = Release|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Static_Release|ARM.ActiveCfg = Release|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Static_Release|ARM.Build.0 = Release|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Static_Release|Mixed Platforms.ActiveCfg = Release|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Static_Release|Mixed Platforms.Build.0 = Release|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Static_Release|Win32.ActiveCfg = Release|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Static_Release|Win32.Build.0 = Release|Win32 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Static_Release|x64.ActiveCfg = Release|x64 - {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Static_Release|x64.Build.0 = Release|x64 + {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Debug_Unicode|Win32.ActiveCfg = Debug_Unicode|Win32 + {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Debug_Unicode|Win32.Build.0 = Debug_Unicode|Win32 + {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Debug_Unicode|x64.ActiveCfg = Debug_Unicode|x64 + {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Debug_Unicode|x64.Build.0 = Debug_Unicode|x64 + {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Release_Unicode|Win32.ActiveCfg = Release_Unicode|Win32 + {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Release_Unicode|Win32.Build.0 = Release_Unicode|Win32 + {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Release_Unicode|x64.ActiveCfg = Release_Unicode|x64 + {A24A269E-D5C3-4D96-B5D3-A254D91F617D}.Release_Unicode|x64.Build.0 = Release_Unicode|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/俱乐部/Source/Libs/Debug_Unicode/Json.pdb b/俱乐部/Source/Libs/Debug_Unicode/Json.pdb index d7f3c15..dc172cc 100644 Binary files a/俱乐部/Source/Libs/Debug_Unicode/Json.pdb and b/俱乐部/Source/Libs/Debug_Unicode/Json.pdb differ diff --git a/俱乐部/Source/Libs/Debug_Unicode/create_dumpD.lib b/俱乐部/Source/Libs/Debug_Unicode/create_dumpD.lib new file mode 100644 index 0000000..aed968f Binary files /dev/null and b/俱乐部/Source/Libs/Debug_Unicode/create_dumpD.lib differ diff --git a/俱乐部/Source/MessageDef/Pb_ClubInformation.pb.cc b/俱乐部/Source/MessageDef/Pb_ClubInformation.pb.cc index bb8ff16..a314ed9 100644 --- a/俱乐部/Source/MessageDef/Pb_ClubInformation.pb.cc +++ b/俱乐部/Source/MessageDef/Pb_ClubInformation.pb.cc @@ -14,42 +14,18 @@ #include // @@protoc_insertion_point(includes) #include -<<<<<<< .mine extern PROTOBUF_INTERNAL_EXPORT_Pb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_PB_CS_C_ClubAutoAddInfo_Pb_5fClubInformation_2eproto; extern PROTOBUF_INTERNAL_EXPORT_Pb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_PB_CS_C_ClubInfo_Pb_5fClubInformation_2eproto; extern PROTOBUF_INTERNAL_EXPORT_Pb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_PB_CS_S_MemberInfo_Pb_5fClubInformation_2eproto; extern PROTOBUF_INTERNAL_EXPORT_Pb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_PB_CS_S_RecordInfo_Pb_5fClubInformation_2eproto; extern PROTOBUF_INTERNAL_EXPORT_Pb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_PB_CS_S_RecordInfoEX_Pb_5fClubInformation_2eproto; +extern PROTOBUF_INTERNAL_EXPORT_Pb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_PB_CS_tagClubIntegral_Pb_5fClubInformation_2eproto; +extern PROTOBUF_INTERNAL_EXPORT_Pb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_PB_CS_tagClubPlaygames_Pb_5fClubInformation_2eproto; extern PROTOBUF_INTERNAL_EXPORT_Pb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_pb_MessageInfo_Pb_5fClubInformation_2eproto; extern PROTOBUF_INTERNAL_EXPORT_Pb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_pb_PlayerInfo_Pb_5fClubInformation_2eproto; extern PROTOBUF_INTERNAL_EXPORT_Pb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_pb_PlayerName_Pb_5fClubInformation_2eproto; extern PROTOBUF_INTERNAL_EXPORT_Pb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_pb_RoomListInfo_Pb_5fClubInformation_2eproto; extern PROTOBUF_INTERNAL_EXPORT_Pb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_pb_tagTableConfig_Pb_5fClubInformation_2eproto; -||||||| .r248 -extern PROTOBUF_INTERNAL_EXPORT_Source_2fMessageDef_2fPb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_PB_CS_C_ClubAutoAddInfo_Source_2fMessageDef_2fPb_5fClubInformation_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_Source_2fMessageDef_2fPb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_PB_CS_C_ClubInfo_Source_2fMessageDef_2fPb_5fClubInformation_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_Source_2fMessageDef_2fPb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_PB_CS_S_MemberInfo_Source_2fMessageDef_2fPb_5fClubInformation_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_Source_2fMessageDef_2fPb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_PB_CS_S_RecordInfo_Source_2fMessageDef_2fPb_5fClubInformation_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_Source_2fMessageDef_2fPb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_PB_CS_S_RecordInfoEX_Source_2fMessageDef_2fPb_5fClubInformation_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_Source_2fMessageDef_2fPb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_pb_MessageInfo_Source_2fMessageDef_2fPb_5fClubInformation_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_Source_2fMessageDef_2fPb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_pb_PlayerInfo_Source_2fMessageDef_2fPb_5fClubInformation_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_Source_2fMessageDef_2fPb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_pb_PlayerName_Source_2fMessageDef_2fPb_5fClubInformation_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_Source_2fMessageDef_2fPb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_pb_RoomListInfo_Source_2fMessageDef_2fPb_5fClubInformation_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_Source_2fMessageDef_2fPb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_pb_tagTableConfig_Source_2fMessageDef_2fPb_5fClubInformation_2eproto; -======= -extern PROTOBUF_INTERNAL_EXPORT_Source_2fMessageDef_2fPb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_PB_CS_C_ClubAutoAddInfo_Source_2fMessageDef_2fPb_5fClubInformation_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_Source_2fMessageDef_2fPb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_PB_CS_C_ClubInfo_Source_2fMessageDef_2fPb_5fClubInformation_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_Source_2fMessageDef_2fPb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_PB_CS_S_MemberInfo_Source_2fMessageDef_2fPb_5fClubInformation_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_Source_2fMessageDef_2fPb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_PB_CS_S_RecordInfo_Source_2fMessageDef_2fPb_5fClubInformation_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_Source_2fMessageDef_2fPb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_PB_CS_S_RecordInfoEX_Source_2fMessageDef_2fPb_5fClubInformation_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_Source_2fMessageDef_2fPb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_PB_CS_tagClubIntegral_Source_2fMessageDef_2fPb_5fClubInformation_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_Source_2fMessageDef_2fPb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_PB_CS_tagClubPlaygames_Source_2fMessageDef_2fPb_5fClubInformation_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_Source_2fMessageDef_2fPb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_pb_MessageInfo_Source_2fMessageDef_2fPb_5fClubInformation_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_Source_2fMessageDef_2fPb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_pb_PlayerInfo_Source_2fMessageDef_2fPb_5fClubInformation_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_Source_2fMessageDef_2fPb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_pb_PlayerName_Source_2fMessageDef_2fPb_5fClubInformation_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_Source_2fMessageDef_2fPb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_pb_RoomListInfo_Source_2fMessageDef_2fPb_5fClubInformation_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_Source_2fMessageDef_2fPb_5fClubInformation_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_pb_tagTableConfig_Source_2fMessageDef_2fPb_5fClubInformation_2eproto; ->>>>>>> .r273 namespace Club { class PB_CS_C_ClubListDefaultTypeInternal { public: @@ -814,17 +790,9 @@ static void InitDefaultsscc_info_PB_CS_S_tagClubIntegral_Pb_5fClubInformation_2e ::Club::PB_CS_S_tagClubIntegral::InitAsDefaultInstance(); } -<<<<<<< .mine -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_PB_CS_S_tagClubIntegral_Pb_5fClubInformation_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, 0, InitDefaultsscc_info_PB_CS_S_tagClubIntegral_Pb_5fClubInformation_2eproto}, {}}; -||||||| .r248 -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_PB_CS_S_tagClubIntegral_Source_2fMessageDef_2fPb_5fClubInformation_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, 0, InitDefaultsscc_info_PB_CS_S_tagClubIntegral_Source_2fMessageDef_2fPb_5fClubInformation_2eproto}, {}}; -======= -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_PB_CS_S_tagClubIntegral_Source_2fMessageDef_2fPb_5fClubInformation_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 1, 0, InitDefaultsscc_info_PB_CS_S_tagClubIntegral_Source_2fMessageDef_2fPb_5fClubInformation_2eproto}, { - &scc_info_PB_CS_tagClubIntegral_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base,}}; ->>>>>>> .r273 +::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_PB_CS_S_tagClubIntegral_Pb_5fClubInformation_2eproto = + {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 1, 0, InitDefaultsscc_info_PB_CS_S_tagClubIntegral_Pb_5fClubInformation_2eproto}, { + &scc_info_PB_CS_tagClubIntegral_Pb_5fClubInformation_2eproto.base,}}; static void InitDefaultsscc_info_PB_CS_S_tagClubPlaygames_Pb_5fClubInformation_2eproto() { GOOGLE_PROTOBUF_VERIFY_VERSION; @@ -837,24 +805,11 @@ static void InitDefaultsscc_info_PB_CS_S_tagClubPlaygames_Pb_5fClubInformation_2 ::Club::PB_CS_S_tagClubPlaygames::InitAsDefaultInstance(); } -<<<<<<< .mine -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_PB_CS_S_tagClubPlaygames_Pb_5fClubInformation_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, 0, InitDefaultsscc_info_PB_CS_S_tagClubPlaygames_Pb_5fClubInformation_2eproto}, {}}; -||||||| .r248 -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_PB_CS_S_tagClubPlaygames_Source_2fMessageDef_2fPb_5fClubInformation_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, 0, InitDefaultsscc_info_PB_CS_S_tagClubPlaygames_Source_2fMessageDef_2fPb_5fClubInformation_2eproto}, {}}; -======= -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_PB_CS_S_tagClubPlaygames_Source_2fMessageDef_2fPb_5fClubInformation_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 1, 0, InitDefaultsscc_info_PB_CS_S_tagClubPlaygames_Source_2fMessageDef_2fPb_5fClubInformation_2eproto}, { - &scc_info_PB_CS_tagClubPlaygames_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base,}}; ->>>>>>> .r273 +::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_PB_CS_S_tagClubPlaygames_Pb_5fClubInformation_2eproto = + {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 1, 0, InitDefaultsscc_info_PB_CS_S_tagClubPlaygames_Pb_5fClubInformation_2eproto}, { + &scc_info_PB_CS_tagClubPlaygames_Pb_5fClubInformation_2eproto.base,}}; -<<<<<<< .mine -static void InitDefaultsscc_info_pb_MessageInfo_Pb_5fClubInformation_2eproto() { -||||||| .r248 -static void InitDefaultsscc_info_pb_MessageInfo_Source_2fMessageDef_2fPb_5fClubInformation_2eproto() { -======= -static void InitDefaultsscc_info_PB_CS_tagClubIntegral_Source_2fMessageDef_2fPb_5fClubInformation_2eproto() { +static void InitDefaultsscc_info_PB_CS_tagClubIntegral_Pb_5fClubInformation_2eproto() { GOOGLE_PROTOBUF_VERIFY_VERSION; { @@ -865,10 +820,10 @@ static void InitDefaultsscc_info_PB_CS_tagClubIntegral_Source_2fMessageDef_2fPb_ ::Club::PB_CS_tagClubIntegral::InitAsDefaultInstance(); } -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_PB_CS_tagClubIntegral_Source_2fMessageDef_2fPb_5fClubInformation_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, 0, InitDefaultsscc_info_PB_CS_tagClubIntegral_Source_2fMessageDef_2fPb_5fClubInformation_2eproto}, {}}; +::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_PB_CS_tagClubIntegral_Pb_5fClubInformation_2eproto = + {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, 0, InitDefaultsscc_info_PB_CS_tagClubIntegral_Pb_5fClubInformation_2eproto}, {}}; -static void InitDefaultsscc_info_PB_CS_tagClubPlaygames_Source_2fMessageDef_2fPb_5fClubInformation_2eproto() { +static void InitDefaultsscc_info_PB_CS_tagClubPlaygames_Pb_5fClubInformation_2eproto() { GOOGLE_PROTOBUF_VERIFY_VERSION; { @@ -879,11 +834,10 @@ static void InitDefaultsscc_info_PB_CS_tagClubPlaygames_Source_2fMessageDef_2fPb ::Club::PB_CS_tagClubPlaygames::InitAsDefaultInstance(); } -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_PB_CS_tagClubPlaygames_Source_2fMessageDef_2fPb_5fClubInformation_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, 0, InitDefaultsscc_info_PB_CS_tagClubPlaygames_Source_2fMessageDef_2fPb_5fClubInformation_2eproto}, {}}; +::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_PB_CS_tagClubPlaygames_Pb_5fClubInformation_2eproto = + {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, 0, InitDefaultsscc_info_PB_CS_tagClubPlaygames_Pb_5fClubInformation_2eproto}, {}}; -static void InitDefaultsscc_info_pb_MessageInfo_Source_2fMessageDef_2fPb_5fClubInformation_2eproto() { ->>>>>>> .r273 +static void InitDefaultsscc_info_pb_MessageInfo_Pb_5fClubInformation_2eproto() { GOOGLE_PROTOBUF_VERIFY_VERSION; { @@ -953,19 +907,9 @@ static void InitDefaultsscc_info_pb_tagTableConfig_Pb_5fClubInformation_2eproto( ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_pb_tagTableConfig_Pb_5fClubInformation_2eproto = {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, 0, InitDefaultsscc_info_pb_tagTableConfig_Pb_5fClubInformation_2eproto}, {}}; -<<<<<<< .mine -static ::PROTOBUF_NAMESPACE_ID::Metadata file_level_metadata_Pb_5fClubInformation_2eproto[46]; +static ::PROTOBUF_NAMESPACE_ID::Metadata file_level_metadata_Pb_5fClubInformation_2eproto[48]; static constexpr ::PROTOBUF_NAMESPACE_ID::EnumDescriptor const** file_level_enum_descriptors_Pb_5fClubInformation_2eproto = nullptr; static constexpr ::PROTOBUF_NAMESPACE_ID::ServiceDescriptor const** file_level_service_descriptors_Pb_5fClubInformation_2eproto = nullptr; -||||||| .r248 -static ::PROTOBUF_NAMESPACE_ID::Metadata file_level_metadata_Source_2fMessageDef_2fPb_5fClubInformation_2eproto[46]; -static constexpr ::PROTOBUF_NAMESPACE_ID::EnumDescriptor const** file_level_enum_descriptors_Source_2fMessageDef_2fPb_5fClubInformation_2eproto = nullptr; -static constexpr ::PROTOBUF_NAMESPACE_ID::ServiceDescriptor const** file_level_service_descriptors_Source_2fMessageDef_2fPb_5fClubInformation_2eproto = nullptr; -======= -static ::PROTOBUF_NAMESPACE_ID::Metadata file_level_metadata_Source_2fMessageDef_2fPb_5fClubInformation_2eproto[48]; -static constexpr ::PROTOBUF_NAMESPACE_ID::EnumDescriptor const** file_level_enum_descriptors_Source_2fMessageDef_2fPb_5fClubInformation_2eproto = nullptr; -static constexpr ::PROTOBUF_NAMESPACE_ID::ServiceDescriptor const** file_level_service_descriptors_Source_2fMessageDef_2fPb_5fClubInformation_2eproto = nullptr; ->>>>>>> .r273 const ::PROTOBUF_NAMESPACE_ID::uint32 TableStruct_Pb_5fClubInformation_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { ~0u, // no _has_bits_ @@ -1524,7 +1468,6 @@ static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = reinterpret_cast(&::Club::_PB_CS_Club_Make_A_Sample_default_instance_), }; -<<<<<<< .mine const char descriptor_table_protodef_Pb_5fClubInformation_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = "\n\030Pb_ClubInformation.proto\022\004Club\"7\n\020PB_C" "S_C_ClubList\022\023\n\013wStartIndex\030\001 \001(\r\022\016\n\006wCo" @@ -1648,300 +1591,25 @@ const char descriptor_table_protodef_Pb_5fClubInformation_2eproto[] PROTOBUF_SEC "teTableID\030\002 \001(\r\"p\n\025PB_CS_C_ClubPlaygames" "\022\020\n\010dwClubID\030\001 \001(\r\022\r\n\005wType\030\002 \001(\r\022\022\n\nSta" "rtIndex\030\003 \001(\r\022\016\n\006mCount\030\004 \001(\r\022\022\n\nwDateCo" - "unt\030\005 \001(\r\"\205\001\n\030PB_CS_S_tagClubPlaygames\022\020" - "\n\010dwUserID\030\001 \001(\r\022\016\n\006mCount\030\002 \001(\r\022\022\n\nszUs" - "erName\030\003 \001(\t\022\021\n\tszHeadImg\030\004 \001(\t\022\022\n\nwDate" - "Count\030\005 \001(\r\022\014\n\004temp\030\006 \001(\r\"K\n\024PB_CS_C_Clu" - "bIntegral\022\020\n\010dwClubID\030\001 \001(\r\022\r\n\005wType\030\002 \001" - "(\r\022\022\n\nwDateCount\030\003 \001(\r\"\224\001\n\027PB_CS_S_tagCl" - "ubIntegral\022\020\n\010dwUserID\030\001 \001(\r\022\016\n\006mCount\030\002" - " \001(\r\022\016\n\006mJiFen\030\003 \001(\022\022\022\n\nszUserName\030\004 \001(\t" - "\022\021\n\tszHeadImg\030\005 \001(\t\022\022\n\nwDateCount\030\006 \001(\r\022" - "\014\n\004temp\030\007 \001(\r\">\n\030PB_CS_Club_Make_A_Sampl" - "e\022\020\n\010dwClubID\030\001 \001(\r\022\020\n\010IsSample\030\002 \001(\rb\006p" - "roto3" -||||||| .r248 -const char descriptor_table_protodef_Source_2fMessageDef_2fPb_5fClubInformation_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = - "\n*Source/MessageDef/Pb_ClubInformation.p" - "roto\022\004Club\"7\n\020PB_CS_C_ClubList\022\023\n\013wStart" - "Index\030\001 \001(\r\022\016\n\006wCount\030\002 \001(\r\"\272\002\n\021pb_tagTa" - "bleConfig\022\022\n\nwSubGameID\030\001 \001(\r\022\021\n\twPlayRu" - "le\030\002 \001(\r\022\023\n\013wMaxFanRule\030\003 \001(\r\022\021\n\twMaxSco" - "re\030\004 \001(\r\022\026\n\016wPlayCountRule\030\005 \001(\r\022\025\n\rwHad" - "PlayCount\030\006 \001(\r\022\023\n\013zmExtraRule\030\007 \001(\r\022\017\n\007" - "dghRule\030\010 \001(\r\022\027\n\017sPrivateTableID\030\t \001(\t\022\017" - "\n\007bDuoLai\030\n \001(\r\022\021\n\twFengDing\030\013 \001(\r\022\014\n\004tm" - "p1\030\014 \001(\r\022\014\n\004tmp2\030\r \001(\r\022\014\n\004tmp3\030\016 \001(\r\022\014\n\004" - "tmp4\030\017 \001(\r\022\014\n\004tmp5\030\020 \001(\r\"n\n\024PB_CS_S_Club" - "List_Ack\022\022\n\nwNewsCount\030\001 \001(\r\022\022\n\nwClubCou" - "nt\030\002 \001(\r\022.\n\016csGameClubInfo\030\003 \003(\0132\026.Club." - "PB_CS_C_ClubInfo\":\n\023PB_CS_C_ClubMessage\022" - "\023\n\013wStartIndex\030\001 \001(\r\022\016\n\006wCount\030\002 \001(\r\"H\n\016" - "pb_MessageInfo\022\r\n\005dType\030\001 \001(\r\022\021\n\tszConte" - "nt\030\002 \001(\t\022\024\n\014dtActionTime\030\003 \001(\r\"T\n\027PB_CS_" - "S_ClubMessage_Ack\022\016\n\006wCount\030\001 \001(\r\022)\n\013Mes" - "sageInfo\030\002 \003(\0132\024.Club.pb_MessageInfo\"x\n\022" - "PB_CS_C_ClubRecord\022\020\n\010dwClubID\030\001 \001(\r\022\023\n\013" - "wStartIndex\030\002 \001(\r\022\016\n\006wCount\030\003 \001(\r\022\023\n\013dtS" - "tartTime\030\004 \001(\r\022\026\n\016dwPrivatetable\030\005 \001(\r\"$" - "\n\rpb_PlayerName\022\023\n\013PlayerName2\030\001 \001(\t\"\264\001\n" - "\022PB_CS_S_RecordInfo\022\021\n\tdwTableID\030\001 \001(\r\022\017" - "\n\007cbJuShu\030\002 \001(\r\022\020\n\010cbPayWay\030\003 \001(\r\022\026\n\016dwT" - "ableOwnerID\030\004 \001(\r\022\024\n\014dtCreateTime\030\005 \001(\r\022" - "\020\n\010PlayerID\030\006 \003(\r\022(\n\013PlayerName1\030\007 \003(\0132\023" - ".Club.pb_PlayerName\"\\\n\024PB_CS_S_RecordInf" - "oEX\022(\n\006Record\030\001 \001(\0132\030.Club.PB_CS_S_Recor" - "dInfo\022\r\n\005Score\030\002 \003(\022\022\013\n\003Tmp\030\003 \003(\r\"\227\001\n\031PB" - "_CS_S_ClubRecord_Ack_EX\022\016\n\006wCount\030\001 \001(\r\022" - "\024\n\014dwTableCount\030\002 \001(\r\022\020\n\010dwZunShi\030\003 \001(\r\022" - "\020\n\010dwClubID\030\004 \001(\r\0220\n\014csRecordInfo\030\005 \003(\0132" - "\032.Club.PB_CS_S_RecordInfoEX\"\304\002\n\020PB_CS_C_" - "ClubInfo\022\020\n\010dwClubID\030\001 \001(\r\022\022\n\nszClubName" - "\030\002 \001(\t\022\021\n\tcbIsOwner\030\003 \001(\r\022\021\n\twTotalNum\030\004" - " \001(\r\022\025\n\rwWaitTableNum\030\005 \001(\r\022\022\n\nwOnLineNu" - "m\030\006 \001(\r\022\024\n\014wWaitUserNum\030\007 \001(\r\022\021\n\tdwOwner" - "ID\030\010 \001(\r\022\022\n\nszHostName\030\t \001(\t\022\021\n\tszHeadUr" - "l\030\n \001(\t\022\r\n\005temp1\030\013 \001(\r\022\r\n\005temp2\030\014 \001(\r\022\r\n" - "\005temp3\030\r \001(\r\022\r\n\005temp4\030\016 \001(\r\022-\n\014csGameCon" - "fig\030\017 \001(\0132\027.Club.pb_tagTableConfig\"(\n\024PB" - "_CS_C_Club_Action1\022\020\n\010dwClubID\030\001 \001(\r\";\n\030" - "PB_CS_S_Club_Action_Ack1\022\016\n\006Result\030\001 \001(\r" - "\022\017\n\007Message\030\002 \001(\t\"e\n\030PB_CS_S_Club_Action" - "_Ack2\022\016\n\006Result\030\001 \001(\r\022(\n\010ClubInfo\030\002 \001(\0132" - "\026.Club.PB_CS_C_ClubInfo\022\017\n\007Message\030\003 \001(\t" - "\"M\n\024PB_CS_C_Club_Action2\022\020\n\010dwClubID\030\001 \001" - "(\r\022\020\n\010dwUserID\030\002 \001(\r\022\021\n\tcbIsAgree\030\003 \001(\r\"" - "]\n\030PB_CS_S_Club_Action_Ack3\022\017\n\007wClubID\030\001" - " \001(\r\022\016\n\006Result\030\002 \001(\r\022\017\n\007Message\030\003 \001(\t\022\017\n" - "\007cbAgree\030\004 \001(\r\"]\n\024PB_CS_C_ClubOnLineEx\022\020" - "\n\010dwClubID\030\001 \001(\r\022\023\n\013wStartIndex\030\002 \001(\r\022\016\n" - "\006wCount\030\003 \001(\r\022\016\n\006cbType\030\004 \001(\r\"\247\001\n\030PB_CS_" - "S_ClubOnLine_AckEx\022\020\n\010dwClubID\030\001 \001(\r\022\024\n\014" - "wQueTableNum\030\002 \001(\r\022\025\n\rwWaitTableNum\030\003 \001(" - "\r\022\025\n\rwPlayTableNmu\030\004 \001(\r\022\014\n\004temp\030\005 \001(\r\022\026" - "\n\016wtotalTableNum\030\006 \001(\r\022\017\n\007tableID\030\007 \003(\r\"" - "s\n\031PB_CS_S_Club_Notify_ACKEX\022\020\n\010newsFalg" - "\030\001 \001(\r\022\014\n\004Temp\030\002 \001(\r\022\017\n\007Message\030\003 \001(\t\022\020\n" - "\010dwClubID\030\004 \001(\r\022\023\n\013dwUserCount\030\005 \001(\r\"j\n\021" - "PB_CS_C_ClubUser2\022\020\n\010dwClubID\030\001 \001(\r\022\023\n\013w" - "StartIndex\030\002 \001(\r\022\016\n\006wCount\030\003 \001(\r\022\016\n\006cbKi" - "nd\030\004 \001(\r\022\016\n\006dwTemp\030\005 \001(\r\"\216\001\n\022PB_CS_S_Mem" - "berInfo\022\020\n\010BangMaID\030\001 \001(\r\022\017\n\007cbStaus\030\002 \001" - "(\r\022\016\n\006isHost\030\003 \001(\r\022\020\n\010isOnline\030\004 \001(\r\022\020\n\010" - "dwUserID\030\005 \001(\r\022\016\n\006szName\030\006 \001(\t\022\021\n\tszHead" - "Url\030\007 \001(\t\"\226\001\n\025PB_CS_S_ClubUser2_Ack\022\016\n\006c" - "bKind\030\001 \001(\r\022\013\n\003tmp\030\002 \001(\r\022\016\n\006cbHost\030\003 \001(\r" - "\022\020\n\010dwClubID\030\004 \001(\r\022\016\n\006wCount\030\005 \001(\r\022.\n\014cs" - "MemberInfo\030\006 \003(\0132\030.Club.PB_CS_S_MemberIn" - "fo\"8\n\024PB_CS_C_ClubProtocol\022\020\n\010dwClubID\030\001" - " \001(\r\022\016\n\006dwTemp\030\002 \001(\r\"N\n\031PB_CS_S_ClubProt" - "ocolAgree\022\020\n\010dwClubID\030\001 \001(\r\022\017\n\007cbAgree\030\002" - " \001(\r\022\016\n\006dwTemp\030\003 \001(\r\"K\n\026PB_CS_S_ClubActi" - "onAck1\022\020\n\010dwClubID\030\001 \001(\r\022\016\n\006Result\030\002 \001(\r" - "\022\017\n\007Message\030\003 \001(\t\"W\n\022PB_CS_C_ClubNotice\022" - "\020\n\010dwClubID\030\001 \001(\r\022\016\n\006cbType\030\002 \001(\r\022\016\n\006dwT" - "emp\030\003 \001(\r\022\017\n\007Message\030\004 \001(\t\"l\n\025PB_CS_S_Cl" - "ubNoticeACK\022\020\n\010dwClubID\030\001 \001(\r\022\016\n\006cbType\030" - "\002 \001(\r\022\016\n\006dwTemp\030\003 \001(\r\022\020\n\010cbResult\030\004 \001(\r\022" - "\017\n\007Message\030\005 \001(\t\"I\n\020PB_CS_C_ClubUser\022\020\n\010" - "dwClubID\030\001 \001(\r\022\023\n\013wStartIndex\030\002 \001(\r\022\016\n\006w" - "Count\030\003 \001(\r\"x\n\024PB_CS_S_ClubUser_Ack\022\016\n\006c" - "bHost\030\001 \001(\r\022\020\n\010dwClubID\030\002 \001(\r\022\016\n\006wCount\030" - "\003 \001(\r\022.\n\014csMemberInfo\030\004 \003(\0132\030.Club.PB_CS" - "_S_MemberInfo\"N\n\027PB_CS_C_ClubOnLineTable" - "\022\016\n\006cbType\030\001 \001(\r\022\020\n\010dwClubID\030\002 \001(\r\022\021\n\tdw" - "TableID\030\003 \001(\r\"\273\002\n\017pb_RoomListInfo\022\016\n\006szN" - "ame\030\001 \001(\t\022\022\n\ndwServerID\030\002 \001(\r\022\014\n\004szIp\030\003 " - "\001(\t\022\017\n\007bDuoLai\030\004 \001(\r\022\021\n\twFengDing\030\005 \001(\r\022" - "\014\n\004tmp1\030\006 \001(\r\022\014\n\004tmp2\030\007 \001(\r\022\014\n\004tmp6\030\010 \003(" - "\022\022\r\n\005wPort\030\t \001(\r\022\024\n\014dwRoomNumber\030\n \001(\r\022\017" - "\n\007dwDiFen\030\013 \001(\r\022\017\n\007dwJuShu\030\014 \001(\r\022\026\n\016bRoo" - "mCreatePay\030\r \001(\r\022\017\n\007bFanGua\030\016 \001(\r\022\016\n\006bWa" - "nFa\030\017 \001(\r\022\014\n\004tmp3\030\020 \001(\r\022\014\n\004tmp4\030\021 \001(\r\022\014\n" - "\004tmp5\030\022 \001(\r\"V\n\034PB_CS_S_ClubOnLineTableCf" - "Ack\022\021\n\tdwTableID\030\001 \001(\r\022#\n\004Room\030\002 \001(\0132\025.C" - "lub.pb_RoomListInfo\"D\n\rpb_PlayerInfo\022\020\n\010" - "dwUserID\030\001 \001(\r\022\016\n\006szName\030\002 \001(\t\022\021\n\tszHead" - "Url\030\003 \001(\t\"{\n\032PB_CS_S_ClubOnLineTableAck\022" - "\021\n\tdwTableID\030\001 \001(\r\022\016\n\006wJushu\030\002 \001(\r\022\023\n\013wT" - "ableState\030\003 \001(\r\022%\n\010Userinfo\030\004 \003(\0132\023.Club" - ".pb_PlayerInfo\"E\n\024PB_CS_S_Table_Notify\022\014" - "\n\004type\030\001 \001(\r\022\017\n\007tableID\030\002 \001(\r\022\016\n\006clubID\030" - "\003 \001(\r\"\324\001\n\035PB_CS_S_TableOtherInfo_Notify\022" - "\016\n\006ClubID\030\001 \001(\r\022\014\n\004Type\030\002 \001(\r\022\024\n\014totalUs" - "erNum\030\003 \001(\004\022\025\n\ronlineUserNum\030\004 \001(\004\022\025\n\rto" - "talTableNum\030\005 \001(\004\022\021\n\tnewMsgNum\030\006 \001(\r\022\022\n\n" - "newUserNum\030\007 \001(\r\022\024\n\014waitTableNum\030\010 \001(\r\022\024" - "\n\014playTableNum\030\t \001(\r\">\n\030PB_CS_C_ClubDiss" - "olveRoom\022\020\n\010dwClubID\030\001 \001(\r\022\020\n\010dwRoomID\030\002" - " \001(\r\"}\n\027PB_CS_C_ClubAutoAddInfo\022\020\n\010dwClu" - "bID\030\001 \001(\r\022\021\n\tcbWanfaId\030\002 \001(\r\022\020\n\010cbStatus" - "\030\003 \001(\r\022+\n\ngameconfig\030\004 \001(\0132\027.Club.pb_tag" - "TableConfig\"r\n\033PB_CS_S_Club_Action_Ack1A" - "dd\022\016\n\006Result\030\001 \001(\r\0222\n\013AutoAddInfo\030\002 \001(\0132" - "\035.Club.PB_CS_C_ClubAutoAddInfo\022\017\n\007Messag" - "e\030\003 \001(\t\"@\n\024PB_CS_C_ClubExploits\022\020\n\010dwClu" - "bID\030\001 \001(\r\022\026\n\016PrivateTableID\030\002 \001(\r\"p\n\025PB_" - "CS_C_ClubPlaygames\022\020\n\010dwClubID\030\001 \001(\r\022\r\n\005" - "wType\030\002 \001(\r\022\022\n\nStartIndex\030\003 \001(\r\022\016\n\006mCoun" - "t\030\004 \001(\r\022\022\n\nwDateCount\030\005 \001(\r\"\205\001\n\030PB_CS_S_" - "tagClubPlaygames\022\020\n\010dwUserID\030\001 \001(\r\022\016\n\006mC" - "ount\030\002 \001(\r\022\022\n\nszUserName\030\003 \001(\t\022\021\n\tszHead" - "Img\030\004 \001(\t\022\022\n\nwDateCount\030\005 \001(\r\022\014\n\004temp\030\006 " - "\001(\r\"K\n\024PB_CS_C_ClubIntegral\022\020\n\010dwClubID\030" - "\001 \001(\r\022\r\n\005wType\030\002 \001(\r\022\022\n\nwDateCount\030\003 \001(\r" - "\"\224\001\n\027PB_CS_S_tagClubIntegral\022\020\n\010dwUserID" - "\030\001 \001(\r\022\016\n\006mCount\030\002 \001(\r\022\016\n\006mJiFen\030\003 \001(\022\022\022" - "\n\nszUserName\030\004 \001(\t\022\021\n\tszHeadImg\030\005 \001(\t\022\022\n" - "\nwDateCount\030\006 \001(\r\022\014\n\004temp\030\007 \001(\r\">\n\030PB_CS" - "_Club_Make_A_Sample\022\020\n\010dwClubID\030\001 \001(\r\022\020\n" - "\010IsSample\030\002 \001(\rb\006proto3" -======= -const char descriptor_table_protodef_Source_2fMessageDef_2fPb_5fClubInformation_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = - "\n*Source/MessageDef/Pb_ClubInformation.p" - "roto\022\004Club\"7\n\020PB_CS_C_ClubList\022\023\n\013wStart" - "Index\030\001 \001(\r\022\016\n\006wCount\030\002 \001(\r\"\272\002\n\021pb_tagTa" - "bleConfig\022\022\n\nwSubGameID\030\001 \001(\r\022\021\n\twPlayRu" - "le\030\002 \001(\r\022\023\n\013wMaxFanRule\030\003 \001(\r\022\021\n\twMaxSco" - "re\030\004 \001(\r\022\026\n\016wPlayCountRule\030\005 \001(\r\022\025\n\rwHad" - "PlayCount\030\006 \001(\r\022\023\n\013zmExtraRule\030\007 \001(\r\022\017\n\007" - "dghRule\030\010 \001(\r\022\027\n\017sPrivateTableID\030\t \001(\t\022\017" - "\n\007bDuoLai\030\n \001(\r\022\021\n\twFengDing\030\013 \001(\r\022\014\n\004tm" - "p1\030\014 \001(\r\022\014\n\004tmp2\030\r \001(\r\022\014\n\004tmp3\030\016 \001(\r\022\014\n\004" - "tmp4\030\017 \001(\r\022\014\n\004tmp5\030\020 \001(\r\"n\n\024PB_CS_S_Club" - "List_Ack\022\022\n\nwNewsCount\030\001 \001(\r\022\022\n\nwClubCou" - "nt\030\002 \001(\r\022.\n\016csGameClubInfo\030\003 \003(\0132\026.Club." - "PB_CS_C_ClubInfo\":\n\023PB_CS_C_ClubMessage\022" - "\023\n\013wStartIndex\030\001 \001(\r\022\016\n\006wCount\030\002 \001(\r\"H\n\016" - "pb_MessageInfo\022\r\n\005dType\030\001 \001(\r\022\021\n\tszConte" - "nt\030\002 \001(\t\022\024\n\014dtActionTime\030\003 \001(\r\"T\n\027PB_CS_" - "S_ClubMessage_Ack\022\016\n\006wCount\030\001 \001(\r\022)\n\013Mes" - "sageInfo\030\002 \003(\0132\024.Club.pb_MessageInfo\"x\n\022" - "PB_CS_C_ClubRecord\022\020\n\010dwClubID\030\001 \001(\r\022\023\n\013" - "wStartIndex\030\002 \001(\r\022\016\n\006wCount\030\003 \001(\r\022\023\n\013dtS" - "tartTime\030\004 \001(\r\022\026\n\016dwPrivatetable\030\005 \001(\r\"$" - "\n\rpb_PlayerName\022\023\n\013PlayerName2\030\001 \001(\t\"\264\001\n" - "\022PB_CS_S_RecordInfo\022\021\n\tdwTableID\030\001 \001(\r\022\017" - "\n\007cbJuShu\030\002 \001(\r\022\020\n\010cbPayWay\030\003 \001(\r\022\026\n\016dwT" - "ableOwnerID\030\004 \001(\r\022\024\n\014dtCreateTime\030\005 \001(\r\022" - "\020\n\010PlayerID\030\006 \003(\r\022(\n\013PlayerName1\030\007 \003(\0132\023" - ".Club.pb_PlayerName\"\\\n\024PB_CS_S_RecordInf" - "oEX\022(\n\006Record\030\001 \001(\0132\030.Club.PB_CS_S_Recor" - "dInfo\022\r\n\005Score\030\002 \003(\022\022\013\n\003Tmp\030\003 \003(\r\"\227\001\n\031PB" - "_CS_S_ClubRecord_Ack_EX\022\016\n\006wCount\030\001 \001(\r\022" - "\024\n\014dwTableCount\030\002 \001(\r\022\020\n\010dwZunShi\030\003 \001(\r\022" - "\020\n\010dwClubID\030\004 \001(\r\0220\n\014csRecordInfo\030\005 \003(\0132" - "\032.Club.PB_CS_S_RecordInfoEX\"\304\002\n\020PB_CS_C_" - "ClubInfo\022\020\n\010dwClubID\030\001 \001(\r\022\022\n\nszClubName" - "\030\002 \001(\t\022\021\n\tcbIsOwner\030\003 \001(\r\022\021\n\twTotalNum\030\004" - " \001(\r\022\025\n\rwWaitTableNum\030\005 \001(\r\022\022\n\nwOnLineNu" - "m\030\006 \001(\r\022\024\n\014wWaitUserNum\030\007 \001(\r\022\021\n\tdwOwner" - "ID\030\010 \001(\r\022\022\n\nszHostName\030\t \001(\t\022\021\n\tszHeadUr" - "l\030\n \001(\t\022\r\n\005temp1\030\013 \001(\r\022\r\n\005temp2\030\014 \001(\r\022\r\n" - "\005temp3\030\r \001(\r\022\r\n\005temp4\030\016 \001(\r\022-\n\014csGameCon" - "fig\030\017 \001(\0132\027.Club.pb_tagTableConfig\"(\n\024PB" - "_CS_C_Club_Action1\022\020\n\010dwClubID\030\001 \001(\r\";\n\030" - "PB_CS_S_Club_Action_Ack1\022\016\n\006Result\030\001 \001(\r" - "\022\017\n\007Message\030\002 \001(\t\"e\n\030PB_CS_S_Club_Action" - "_Ack2\022\016\n\006Result\030\001 \001(\r\022(\n\010ClubInfo\030\002 \001(\0132" - "\026.Club.PB_CS_C_ClubInfo\022\017\n\007Message\030\003 \001(\t" - "\"M\n\024PB_CS_C_Club_Action2\022\020\n\010dwClubID\030\001 \001" - "(\r\022\020\n\010dwUserID\030\002 \001(\r\022\021\n\tcbIsAgree\030\003 \001(\r\"" - "]\n\030PB_CS_S_Club_Action_Ack3\022\017\n\007wClubID\030\001" - " \001(\r\022\016\n\006Result\030\002 \001(\r\022\017\n\007Message\030\003 \001(\t\022\017\n" - "\007cbAgree\030\004 \001(\r\"]\n\024PB_CS_C_ClubOnLineEx\022\020" - "\n\010dwClubID\030\001 \001(\r\022\023\n\013wStartIndex\030\002 \001(\r\022\016\n" - "\006wCount\030\003 \001(\r\022\016\n\006cbType\030\004 \001(\r\"\247\001\n\030PB_CS_" - "S_ClubOnLine_AckEx\022\020\n\010dwClubID\030\001 \001(\r\022\024\n\014" - "wQueTableNum\030\002 \001(\r\022\025\n\rwWaitTableNum\030\003 \001(" - "\r\022\025\n\rwPlayTableNmu\030\004 \001(\r\022\014\n\004temp\030\005 \001(\r\022\026" - "\n\016wtotalTableNum\030\006 \001(\r\022\017\n\007tableID\030\007 \003(\r\"" - "s\n\031PB_CS_S_Club_Notify_ACKEX\022\020\n\010newsFalg" - "\030\001 \001(\r\022\014\n\004Temp\030\002 \001(\r\022\017\n\007Message\030\003 \001(\t\022\020\n" - "\010dwClubID\030\004 \001(\r\022\023\n\013dwUserCount\030\005 \001(\r\"j\n\021" - "PB_CS_C_ClubUser2\022\020\n\010dwClubID\030\001 \001(\r\022\023\n\013w" - "StartIndex\030\002 \001(\r\022\016\n\006wCount\030\003 \001(\r\022\016\n\006cbKi" - "nd\030\004 \001(\r\022\016\n\006dwTemp\030\005 \001(\r\"\216\001\n\022PB_CS_S_Mem" - "berInfo\022\020\n\010BangMaID\030\001 \001(\r\022\017\n\007cbStaus\030\002 \001" - "(\r\022\016\n\006isHost\030\003 \001(\r\022\020\n\010isOnline\030\004 \001(\r\022\020\n\010" - "dwUserID\030\005 \001(\r\022\016\n\006szName\030\006 \001(\t\022\021\n\tszHead" - "Url\030\007 \001(\t\"\226\001\n\025PB_CS_S_ClubUser2_Ack\022\016\n\006c" - "bKind\030\001 \001(\r\022\013\n\003tmp\030\002 \001(\r\022\016\n\006cbHost\030\003 \001(\r" - "\022\020\n\010dwClubID\030\004 \001(\r\022\016\n\006wCount\030\005 \001(\r\022.\n\014cs" - "MemberInfo\030\006 \003(\0132\030.Club.PB_CS_S_MemberIn" - "fo\"8\n\024PB_CS_C_ClubProtocol\022\020\n\010dwClubID\030\001" - " \001(\r\022\016\n\006dwTemp\030\002 \001(\r\"N\n\031PB_CS_S_ClubProt" - "ocolAgree\022\020\n\010dwClubID\030\001 \001(\r\022\017\n\007cbAgree\030\002" - " \001(\r\022\016\n\006dwTemp\030\003 \001(\r\"K\n\026PB_CS_S_ClubActi" - "onAck1\022\020\n\010dwClubID\030\001 \001(\r\022\016\n\006Result\030\002 \001(\r" - "\022\017\n\007Message\030\003 \001(\t\"W\n\022PB_CS_C_ClubNotice\022" - "\020\n\010dwClubID\030\001 \001(\r\022\016\n\006cbType\030\002 \001(\r\022\016\n\006dwT" - "emp\030\003 \001(\r\022\017\n\007Message\030\004 \001(\t\"l\n\025PB_CS_S_Cl" - "ubNoticeACK\022\020\n\010dwClubID\030\001 \001(\r\022\016\n\006cbType\030" - "\002 \001(\r\022\016\n\006dwTemp\030\003 \001(\r\022\020\n\010cbResult\030\004 \001(\r\022" - "\017\n\007Message\030\005 \001(\t\"I\n\020PB_CS_C_ClubUser\022\020\n\010" - "dwClubID\030\001 \001(\r\022\023\n\013wStartIndex\030\002 \001(\r\022\016\n\006w" - "Count\030\003 \001(\r\"x\n\024PB_CS_S_ClubUser_Ack\022\016\n\006c" - "bHost\030\001 \001(\r\022\020\n\010dwClubID\030\002 \001(\r\022\016\n\006wCount\030" - "\003 \001(\r\022.\n\014csMemberInfo\030\004 \003(\0132\030.Club.PB_CS" - "_S_MemberInfo\"N\n\027PB_CS_C_ClubOnLineTable" - "\022\016\n\006cbType\030\001 \001(\r\022\020\n\010dwClubID\030\002 \001(\r\022\021\n\tdw" - "TableID\030\003 \001(\r\"\273\002\n\017pb_RoomListInfo\022\016\n\006szN" - "ame\030\001 \001(\t\022\022\n\ndwServerID\030\002 \001(\r\022\014\n\004szIp\030\003 " - "\001(\t\022\017\n\007bDuoLai\030\004 \001(\r\022\021\n\twFengDing\030\005 \001(\r\022" - "\014\n\004tmp1\030\006 \001(\r\022\014\n\004tmp2\030\007 \001(\r\022\014\n\004tmp6\030\010 \003(" - "\022\022\r\n\005wPort\030\t \001(\r\022\024\n\014dwRoomNumber\030\n \001(\r\022\017" - "\n\007dwDiFen\030\013 \001(\r\022\017\n\007dwJuShu\030\014 \001(\r\022\026\n\016bRoo" - "mCreatePay\030\r \001(\r\022\017\n\007bFanGua\030\016 \001(\r\022\016\n\006bWa" - "nFa\030\017 \001(\r\022\014\n\004tmp3\030\020 \001(\r\022\014\n\004tmp4\030\021 \001(\r\022\014\n" - "\004tmp5\030\022 \001(\r\"V\n\034PB_CS_S_ClubOnLineTableCf" - "Ack\022\021\n\tdwTableID\030\001 \001(\r\022#\n\004Room\030\002 \001(\0132\025.C" - "lub.pb_RoomListInfo\"D\n\rpb_PlayerInfo\022\020\n\010" - "dwUserID\030\001 \001(\r\022\016\n\006szName\030\002 \001(\t\022\021\n\tszHead" - "Url\030\003 \001(\t\"{\n\032PB_CS_S_ClubOnLineTableAck\022" - "\021\n\tdwTableID\030\001 \001(\r\022\016\n\006wJushu\030\002 \001(\r\022\023\n\013wT" - "ableState\030\003 \001(\r\022%\n\010Userinfo\030\004 \003(\0132\023.Club" - ".pb_PlayerInfo\"E\n\024PB_CS_S_Table_Notify\022\014" - "\n\004type\030\001 \001(\r\022\017\n\007tableID\030\002 \001(\r\022\016\n\006clubID\030" - "\003 \001(\r\"\324\001\n\035PB_CS_S_TableOtherInfo_Notify\022" - "\016\n\006ClubID\030\001 \001(\r\022\014\n\004Type\030\002 \001(\r\022\024\n\014totalUs" - "erNum\030\003 \001(\004\022\025\n\ronlineUserNum\030\004 \001(\004\022\025\n\rto" - "talTableNum\030\005 \001(\004\022\021\n\tnewMsgNum\030\006 \001(\r\022\022\n\n" - "newUserNum\030\007 \001(\r\022\024\n\014waitTableNum\030\010 \001(\r\022\024" - "\n\014playTableNum\030\t \001(\r\">\n\030PB_CS_C_ClubDiss" - "olveRoom\022\020\n\010dwClubID\030\001 \001(\r\022\020\n\010dwRoomID\030\002" - " \001(\r\"}\n\027PB_CS_C_ClubAutoAddInfo\022\020\n\010dwClu" - "bID\030\001 \001(\r\022\021\n\tcbWanfaId\030\002 \001(\r\022\020\n\010cbStatus" - "\030\003 \001(\r\022+\n\ngameconfig\030\004 \001(\0132\027.Club.pb_tag" - "TableConfig\"r\n\033PB_CS_S_Club_Action_Ack1A" - "dd\022\016\n\006Result\030\001 \001(\r\0222\n\013AutoAddInfo\030\002 \001(\0132" - "\035.Club.PB_CS_C_ClubAutoAddInfo\022\017\n\007Messag" - "e\030\003 \001(\t\"@\n\024PB_CS_C_ClubExploits\022\020\n\010dwClu" - "bID\030\001 \001(\r\022\026\n\016PrivateTableID\030\002 \001(\r\"p\n\025PB_" - "CS_C_ClubPlaygames\022\020\n\010dwClubID\030\001 \001(\r\022\r\n\005" - "wType\030\002 \001(\r\022\022\n\nStartIndex\030\003 \001(\r\022\016\n\006mCoun" - "t\030\004 \001(\r\022\022\n\nwDateCount\030\005 \001(\r\"a\n\026PB_CS_tag" - "ClubPlaygames\022\020\n\010dwUserID\030\001 \001(\r\022\016\n\006mCoun" - "t\030\002 \001(\r\022\022\n\nszUserName\030\003 \001(\t\022\021\n\tszHeadImg" - "\030\004 \001(\t\"m\n\030PB_CS_S_tagClubPlaygames\022\022\n\nwD" - "ateCount\030\001 \001(\r\022\014\n\004temp\030\002 \001(\r\022/\n\tPlaygame" - "s\030\003 \003(\0132\034.Club.PB_CS_tagClubPlaygames\"K\n" - "\024PB_CS_C_ClubIntegral\022\020\n\010dwClubID\030\001 \001(\r\022" - "\r\n\005wType\030\002 \001(\r\022\022\n\nwDateCount\030\003 \001(\r\"p\n\025PB" - "_CS_tagClubIntegral\022\020\n\010dwUserID\030\001 \001(\r\022\016\n" - "\006mCount\030\002 \001(\r\022\016\n\006mJiFen\030\003 \001(\022\022\022\n\nszUserN" - "ame\030\004 \001(\t\022\021\n\tszHeadImg\030\005 \001(\t\"j\n\027PB_CS_S_" - "tagClubIntegral\022\022\n\nwDateCount\030\001 \001(\r\022\014\n\004t" - "emp\030\002 \001(\r\022-\n\010Integral\030\003 \003(\0132\033.Club.PB_CS" - "_tagClubIntegral\">\n\030PB_CS_Club_Make_A_Sa" - "mple\022\020\n\010dwClubID\030\001 \001(\r\022\020\n\010IsSample\030\002 \001(\r" - "b\006proto3" ->>>>>>> .r273 + "unt\030\005 \001(\r\"a\n\026PB_CS_tagClubPlaygames\022\020\n\010d" + "wUserID\030\001 \001(\r\022\016\n\006mCount\030\002 \001(\r\022\022\n\nszUserN" + "ame\030\003 \001(\t\022\021\n\tszHeadImg\030\004 \001(\t\"m\n\030PB_CS_S_" + "tagClubPlaygames\022\022\n\nwDateCount\030\001 \001(\r\022\014\n\004" + "temp\030\002 \001(\r\022/\n\tPlaygames\030\003 \003(\0132\034.Club.PB_" + "CS_tagClubPlaygames\"K\n\024PB_CS_C_ClubInteg" + "ral\022\020\n\010dwClubID\030\001 \001(\r\022\r\n\005wType\030\002 \001(\r\022\022\n\n" + "wDateCount\030\003 \001(\r\"p\n\025PB_CS_tagClubIntegra" + "l\022\020\n\010dwUserID\030\001 \001(\r\022\016\n\006mCount\030\002 \001(\r\022\016\n\006m" + "JiFen\030\003 \001(\022\022\022\n\nszUserName\030\004 \001(\t\022\021\n\tszHea" + "dImg\030\005 \001(\t\"j\n\027PB_CS_S_tagClubIntegral\022\022\n" + "\nwDateCount\030\001 \001(\r\022\014\n\004temp\030\002 \001(\r\022-\n\010Integ" + "ral\030\003 \003(\0132\033.Club.PB_CS_tagClubIntegral\">" + "\n\030PB_CS_Club_Make_A_Sample\022\020\n\010dwClubID\030\001" + " \001(\r\022\020\n\010IsSample\030\002 \001(\rb\006proto3" ; static const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable*const descriptor_table_Pb_5fClubInformation_2eproto_deps[1] = { }; -<<<<<<< .mine -static ::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase*const descriptor_table_Pb_5fClubInformation_2eproto_sccs[46] = { +static ::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase*const descriptor_table_Pb_5fClubInformation_2eproto_sccs[48] = { &scc_info_PB_CS_C_ClubAutoAddInfo_Pb_5fClubInformation_2eproto.base, &scc_info_PB_CS_C_ClubDissolveRoom_Pb_5fClubInformation_2eproto.base, &scc_info_PB_CS_C_ClubExploits_Pb_5fClubInformation_2eproto.base, @@ -1983,136 +1651,21 @@ static ::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase*const descriptor_table_Pb_ &scc_info_PB_CS_S_Table_Notify_Pb_5fClubInformation_2eproto.base, &scc_info_PB_CS_S_tagClubIntegral_Pb_5fClubInformation_2eproto.base, &scc_info_PB_CS_S_tagClubPlaygames_Pb_5fClubInformation_2eproto.base, + &scc_info_PB_CS_tagClubIntegral_Pb_5fClubInformation_2eproto.base, + &scc_info_PB_CS_tagClubPlaygames_Pb_5fClubInformation_2eproto.base, &scc_info_pb_MessageInfo_Pb_5fClubInformation_2eproto.base, &scc_info_pb_PlayerInfo_Pb_5fClubInformation_2eproto.base, &scc_info_pb_PlayerName_Pb_5fClubInformation_2eproto.base, &scc_info_pb_RoomListInfo_Pb_5fClubInformation_2eproto.base, &scc_info_pb_tagTableConfig_Pb_5fClubInformation_2eproto.base, -||||||| .r248 -static ::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase*const descriptor_table_Source_2fMessageDef_2fPb_5fClubInformation_2eproto_sccs[46] = { - &scc_info_PB_CS_C_ClubAutoAddInfo_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_C_ClubDissolveRoom_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_C_ClubExploits_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_C_ClubInfo_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_C_ClubIntegral_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_C_ClubList_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_C_ClubMessage_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_C_ClubNotice_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_C_ClubOnLineEx_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_C_ClubOnLineTable_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_C_ClubPlaygames_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_C_ClubProtocol_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_C_ClubRecord_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_C_ClubUser_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_C_ClubUser2_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_C_Club_Action1_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_C_Club_Action2_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_Club_Make_A_Sample_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_S_ClubActionAck1_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_S_ClubList_Ack_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_S_ClubMessage_Ack_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_S_ClubNoticeACK_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_S_ClubOnLineTableAck_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_S_ClubOnLineTableCfAck_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_S_ClubOnLine_AckEx_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_S_ClubProtocolAgree_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_S_ClubRecord_Ack_EX_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_S_ClubUser2_Ack_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_S_ClubUser_Ack_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_S_Club_Action_Ack1_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_S_Club_Action_Ack1Add_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_S_Club_Action_Ack2_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_S_Club_Action_Ack3_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_S_Club_Notify_ACKEX_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_S_MemberInfo_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_S_RecordInfo_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_S_RecordInfoEX_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_S_TableOtherInfo_Notify_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_S_Table_Notify_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_S_tagClubIntegral_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_S_tagClubPlaygames_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_pb_MessageInfo_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_pb_PlayerInfo_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_pb_PlayerName_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_pb_RoomListInfo_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_pb_tagTableConfig_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, -======= -static ::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase*const descriptor_table_Source_2fMessageDef_2fPb_5fClubInformation_2eproto_sccs[48] = { - &scc_info_PB_CS_C_ClubAutoAddInfo_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_C_ClubDissolveRoom_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_C_ClubExploits_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_C_ClubInfo_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_C_ClubIntegral_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_C_ClubList_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_C_ClubMessage_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_C_ClubNotice_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_C_ClubOnLineEx_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_C_ClubOnLineTable_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_C_ClubPlaygames_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_C_ClubProtocol_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_C_ClubRecord_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_C_ClubUser_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_C_ClubUser2_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_C_Club_Action1_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_C_Club_Action2_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_Club_Make_A_Sample_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_S_ClubActionAck1_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_S_ClubList_Ack_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_S_ClubMessage_Ack_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_S_ClubNoticeACK_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_S_ClubOnLineTableAck_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_S_ClubOnLineTableCfAck_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_S_ClubOnLine_AckEx_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_S_ClubProtocolAgree_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_S_ClubRecord_Ack_EX_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_S_ClubUser2_Ack_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_S_ClubUser_Ack_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_S_Club_Action_Ack1_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_S_Club_Action_Ack1Add_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_S_Club_Action_Ack2_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_S_Club_Action_Ack3_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_S_Club_Notify_ACKEX_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_S_MemberInfo_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_S_RecordInfo_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_S_RecordInfoEX_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_S_TableOtherInfo_Notify_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_S_Table_Notify_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_S_tagClubIntegral_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_S_tagClubPlaygames_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_tagClubIntegral_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_PB_CS_tagClubPlaygames_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_pb_MessageInfo_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_pb_PlayerInfo_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_pb_PlayerName_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_pb_RoomListInfo_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, - &scc_info_pb_tagTableConfig_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base, ->>>>>>> .r273 }; -<<<<<<< .mine static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_Pb_5fClubInformation_2eproto_once; static bool descriptor_table_Pb_5fClubInformation_2eproto_initialized = false; const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_Pb_5fClubInformation_2eproto = { - &descriptor_table_Pb_5fClubInformation_2eproto_initialized, descriptor_table_protodef_Pb_5fClubInformation_2eproto, "Pb_ClubInformation.proto", 5325, - &descriptor_table_Pb_5fClubInformation_2eproto_once, descriptor_table_Pb_5fClubInformation_2eproto_sccs, descriptor_table_Pb_5fClubInformation_2eproto_deps, 46, 0, + &descriptor_table_Pb_5fClubInformation_2eproto_initialized, descriptor_table_protodef_Pb_5fClubInformation_2eproto, "Pb_ClubInformation.proto", 5470, + &descriptor_table_Pb_5fClubInformation_2eproto_once, descriptor_table_Pb_5fClubInformation_2eproto_sccs, descriptor_table_Pb_5fClubInformation_2eproto_deps, 48, 0, schemas, file_default_instances, TableStruct_Pb_5fClubInformation_2eproto::offsets, - file_level_metadata_Pb_5fClubInformation_2eproto, 46, file_level_enum_descriptors_Pb_5fClubInformation_2eproto, file_level_service_descriptors_Pb_5fClubInformation_2eproto, -||||||| .r248 -static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_Source_2fMessageDef_2fPb_5fClubInformation_2eproto_once; -static bool descriptor_table_Source_2fMessageDef_2fPb_5fClubInformation_2eproto_initialized = false; -const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_Source_2fMessageDef_2fPb_5fClubInformation_2eproto = { - &descriptor_table_Source_2fMessageDef_2fPb_5fClubInformation_2eproto_initialized, descriptor_table_protodef_Source_2fMessageDef_2fPb_5fClubInformation_2eproto, "Source/MessageDef/Pb_ClubInformation.proto", 5343, - &descriptor_table_Source_2fMessageDef_2fPb_5fClubInformation_2eproto_once, descriptor_table_Source_2fMessageDef_2fPb_5fClubInformation_2eproto_sccs, descriptor_table_Source_2fMessageDef_2fPb_5fClubInformation_2eproto_deps, 46, 0, - schemas, file_default_instances, TableStruct_Source_2fMessageDef_2fPb_5fClubInformation_2eproto::offsets, - file_level_metadata_Source_2fMessageDef_2fPb_5fClubInformation_2eproto, 46, file_level_enum_descriptors_Source_2fMessageDef_2fPb_5fClubInformation_2eproto, file_level_service_descriptors_Source_2fMessageDef_2fPb_5fClubInformation_2eproto, -======= -static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_Source_2fMessageDef_2fPb_5fClubInformation_2eproto_once; -static bool descriptor_table_Source_2fMessageDef_2fPb_5fClubInformation_2eproto_initialized = false; -const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_Source_2fMessageDef_2fPb_5fClubInformation_2eproto = { - &descriptor_table_Source_2fMessageDef_2fPb_5fClubInformation_2eproto_initialized, descriptor_table_protodef_Source_2fMessageDef_2fPb_5fClubInformation_2eproto, "Source/MessageDef/Pb_ClubInformation.proto", 5488, - &descriptor_table_Source_2fMessageDef_2fPb_5fClubInformation_2eproto_once, descriptor_table_Source_2fMessageDef_2fPb_5fClubInformation_2eproto_sccs, descriptor_table_Source_2fMessageDef_2fPb_5fClubInformation_2eproto_deps, 48, 0, - schemas, file_default_instances, TableStruct_Source_2fMessageDef_2fPb_5fClubInformation_2eproto::offsets, - file_level_metadata_Source_2fMessageDef_2fPb_5fClubInformation_2eproto, 48, file_level_enum_descriptors_Source_2fMessageDef_2fPb_5fClubInformation_2eproto, file_level_service_descriptors_Source_2fMessageDef_2fPb_5fClubInformation_2eproto, ->>>>>>> .r273 + file_level_metadata_Pb_5fClubInformation_2eproto, 48, file_level_enum_descriptors_Pb_5fClubInformation_2eproto, file_level_service_descriptors_Pb_5fClubInformation_2eproto, }; // Force running AddDescriptors() at dynamic initialization time. @@ -14303,16 +13856,8 @@ PB_CS_tagClubPlaygames::PB_CS_tagClubPlaygames(const PB_CS_tagClubPlaygames& fro // @@protoc_insertion_point(copy_constructor:Club.PB_CS_tagClubPlaygames) } -<<<<<<< .mine -void PB_CS_S_tagClubPlaygames::SharedCtor() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_PB_CS_S_tagClubPlaygames_Pb_5fClubInformation_2eproto.base); -||||||| .r248 -void PB_CS_S_tagClubPlaygames::SharedCtor() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_PB_CS_S_tagClubPlaygames_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base); -======= void PB_CS_tagClubPlaygames::SharedCtor() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_PB_CS_tagClubPlaygames_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base); ->>>>>>> .r273 + ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_PB_CS_tagClubPlaygames_Pb_5fClubInformation_2eproto.base); szusername_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); szheadimg_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); ::memset(&dwuserid_, 0, static_cast( @@ -14333,16 +13878,8 @@ void PB_CS_tagClubPlaygames::SharedDtor() { void PB_CS_tagClubPlaygames::SetCachedSize(int size) const { _cached_size_.Set(size); } -<<<<<<< .mine -const PB_CS_S_tagClubPlaygames& PB_CS_S_tagClubPlaygames::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_PB_CS_S_tagClubPlaygames_Pb_5fClubInformation_2eproto.base); -||||||| .r248 -const PB_CS_S_tagClubPlaygames& PB_CS_S_tagClubPlaygames::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_PB_CS_S_tagClubPlaygames_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base); -======= const PB_CS_tagClubPlaygames& PB_CS_tagClubPlaygames::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_PB_CS_tagClubPlaygames_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base); ->>>>>>> .r273 + ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_PB_CS_tagClubPlaygames_Pb_5fClubInformation_2eproto.base); return *internal_default_instance(); } @@ -14604,7 +14141,7 @@ PB_CS_S_tagClubPlaygames::PB_CS_S_tagClubPlaygames(const PB_CS_S_tagClubPlaygame } void PB_CS_S_tagClubPlaygames::SharedCtor() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_PB_CS_S_tagClubPlaygames_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base); + ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_PB_CS_S_tagClubPlaygames_Pb_5fClubInformation_2eproto.base); ::memset(&wdatecount_, 0, static_cast( reinterpret_cast(&temp_) - reinterpret_cast(&wdatecount_)) + sizeof(temp_)); @@ -14622,7 +14159,7 @@ void PB_CS_S_tagClubPlaygames::SetCachedSize(int size) const { _cached_size_.Set(size); } const PB_CS_S_tagClubPlaygames& PB_CS_S_tagClubPlaygames::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_PB_CS_S_tagClubPlaygames_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base); + ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_PB_CS_S_tagClubPlaygames_Pb_5fClubInformation_2eproto.base); return *internal_default_instance(); } @@ -15098,16 +14635,8 @@ PB_CS_tagClubIntegral::PB_CS_tagClubIntegral(const PB_CS_tagClubIntegral& from) // @@protoc_insertion_point(copy_constructor:Club.PB_CS_tagClubIntegral) } -<<<<<<< .mine -void PB_CS_S_tagClubIntegral::SharedCtor() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_PB_CS_S_tagClubIntegral_Pb_5fClubInformation_2eproto.base); -||||||| .r248 -void PB_CS_S_tagClubIntegral::SharedCtor() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_PB_CS_S_tagClubIntegral_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base); -======= void PB_CS_tagClubIntegral::SharedCtor() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_PB_CS_tagClubIntegral_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base); ->>>>>>> .r273 + ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_PB_CS_tagClubIntegral_Pb_5fClubInformation_2eproto.base); szusername_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); szheadimg_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); ::memset(&dwuserid_, 0, static_cast( @@ -15128,16 +14657,8 @@ void PB_CS_tagClubIntegral::SharedDtor() { void PB_CS_tagClubIntegral::SetCachedSize(int size) const { _cached_size_.Set(size); } -<<<<<<< .mine -const PB_CS_S_tagClubIntegral& PB_CS_S_tagClubIntegral::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_PB_CS_S_tagClubIntegral_Pb_5fClubInformation_2eproto.base); -||||||| .r248 -const PB_CS_S_tagClubIntegral& PB_CS_S_tagClubIntegral::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_PB_CS_S_tagClubIntegral_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base); -======= const PB_CS_tagClubIntegral& PB_CS_tagClubIntegral::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_PB_CS_tagClubIntegral_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base); ->>>>>>> .r273 + ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_PB_CS_tagClubIntegral_Pb_5fClubInformation_2eproto.base); return *internal_default_instance(); } @@ -15423,7 +14944,7 @@ PB_CS_S_tagClubIntegral::PB_CS_S_tagClubIntegral(const PB_CS_S_tagClubIntegral& } void PB_CS_S_tagClubIntegral::SharedCtor() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_PB_CS_S_tagClubIntegral_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base); + ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_PB_CS_S_tagClubIntegral_Pb_5fClubInformation_2eproto.base); ::memset(&wdatecount_, 0, static_cast( reinterpret_cast(&temp_) - reinterpret_cast(&wdatecount_)) + sizeof(temp_)); @@ -15441,7 +14962,7 @@ void PB_CS_S_tagClubIntegral::SetCachedSize(int size) const { _cached_size_.Set(size); } const PB_CS_S_tagClubIntegral& PB_CS_S_tagClubIntegral::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_PB_CS_S_tagClubIntegral_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.base); + ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_PB_CS_S_tagClubIntegral_Pb_5fClubInformation_2eproto.base); return *internal_default_instance(); } diff --git a/俱乐部/Source/MessageDef/Pb_ClubInformation.pb.h b/俱乐部/Source/MessageDef/Pb_ClubInformation.pb.h index 4ca9970..24b3742 100644 --- a/俱乐部/Source/MessageDef/Pb_ClubInformation.pb.h +++ b/俱乐部/Source/MessageDef/Pb_ClubInformation.pb.h @@ -7771,7 +7771,7 @@ class PB_CS_tagClubPlaygames : ::PROTOBUF_NAMESPACE_ID::uint32 dwuserid_; ::PROTOBUF_NAMESPACE_ID::uint32 mcount_; mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - friend struct ::TableStruct_Source_2fMessageDef_2fPb_5fClubInformation_2eproto; + friend struct ::TableStruct_Pb_5fClubInformation_2eproto; }; // ------------------------------------------------------------------- @@ -7870,8 +7870,8 @@ class PB_CS_S_tagClubPlaygames : ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; private: static ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadataStatic() { - ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&::descriptor_table_Source_2fMessageDef_2fPb_5fClubInformation_2eproto); - return ::descriptor_table_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.file_level_metadata[kIndexInFileMessages]; + ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&::descriptor_table_Pb_5fClubInformation_2eproto); + return ::descriptor_table_Pb_5fClubInformation_2eproto.file_level_metadata[kIndexInFileMessages]; } public: @@ -8266,7 +8266,7 @@ class PB_CS_tagClubIntegral : ::PROTOBUF_NAMESPACE_ID::uint32 mcount_; ::PROTOBUF_NAMESPACE_ID::int64 mjifen_; mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - friend struct ::TableStruct_Source_2fMessageDef_2fPb_5fClubInformation_2eproto; + friend struct ::TableStruct_Pb_5fClubInformation_2eproto; }; // ------------------------------------------------------------------- @@ -8365,8 +8365,8 @@ class PB_CS_S_tagClubIntegral : ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; private: static ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadataStatic() { - ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&::descriptor_table_Source_2fMessageDef_2fPb_5fClubInformation_2eproto); - return ::descriptor_table_Source_2fMessageDef_2fPb_5fClubInformation_2eproto.file_level_metadata[kIndexInFileMessages]; + ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&::descriptor_table_Pb_5fClubInformation_2eproto); + return ::descriptor_table_Pb_5fClubInformation_2eproto.file_level_metadata[kIndexInFileMessages]; } public: diff --git a/俱乐部/Source/MessageDef/Pb_LogonServer.pb.cc b/俱乐部/Source/MessageDef/Pb_LogonServer.pb.cc index 5225bcc..364d3e0 100644 --- a/俱乐部/Source/MessageDef/Pb_LogonServer.pb.cc +++ b/俱乐部/Source/MessageDef/Pb_LogonServer.pb.cc @@ -108,12 +108,7 @@ static void InitDefaultsscc_info_PB_CS_C_RegisterAccounts_Pb_5fLogonServer_2epro ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_PB_CS_C_RegisterAccounts_Pb_5fLogonServer_2eproto = {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, 0, InitDefaultsscc_info_PB_CS_C_RegisterAccounts_Pb_5fLogonServer_2eproto}, {}}; -<<<<<<< .mine -static void InitDefaultsscc_info_PB_CS_S_LogonFailure_Pb_5fLogonServer_2eproto() { -||||||| .r248 -static void InitDefaultsscc_info_PB_CS_S_LogonFailure_Source_2fMessageDef_2fPb_5fLogonServer_2eproto() { -======= -static void InitDefaultsscc_info_PB_CS_S_LogonCheckVerifCode_Source_2fMessageDef_2fPb_5fLogonServer_2eproto() { +static void InitDefaultsscc_info_PB_CS_S_LogonCheckVerifCode_Pb_5fLogonServer_2eproto() { GOOGLE_PROTOBUF_VERIFY_VERSION; { @@ -124,11 +119,10 @@ static void InitDefaultsscc_info_PB_CS_S_LogonCheckVerifCode_Source_2fMessageDef ::LogonServer::PB_CS_S_LogonCheckVerifCode::InitAsDefaultInstance(); } -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_PB_CS_S_LogonCheckVerifCode_Source_2fMessageDef_2fPb_5fLogonServer_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, 0, InitDefaultsscc_info_PB_CS_S_LogonCheckVerifCode_Source_2fMessageDef_2fPb_5fLogonServer_2eproto}, {}}; +::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_PB_CS_S_LogonCheckVerifCode_Pb_5fLogonServer_2eproto = + {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, 0, InitDefaultsscc_info_PB_CS_S_LogonCheckVerifCode_Pb_5fLogonServer_2eproto}, {}}; -static void InitDefaultsscc_info_PB_CS_S_LogonFailure_Source_2fMessageDef_2fPb_5fLogonServer_2eproto() { ->>>>>>> .r273 +static void InitDefaultsscc_info_PB_CS_S_LogonFailure_Pb_5fLogonServer_2eproto() { GOOGLE_PROTOBUF_VERIFY_VERSION; { @@ -184,19 +178,9 @@ static void InitDefaultsscc_info_PB_CS_S_tagGameServer_Pb_5fLogonServer_2eproto( ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_PB_CS_S_tagGameServer_Pb_5fLogonServer_2eproto = {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, 0, InitDefaultsscc_info_PB_CS_S_tagGameServer_Pb_5fLogonServer_2eproto}, {}}; -<<<<<<< .mine -static ::PROTOBUF_NAMESPACE_ID::Metadata file_level_metadata_Pb_5fLogonServer_2eproto[8]; +static ::PROTOBUF_NAMESPACE_ID::Metadata file_level_metadata_Pb_5fLogonServer_2eproto[9]; static constexpr ::PROTOBUF_NAMESPACE_ID::EnumDescriptor const** file_level_enum_descriptors_Pb_5fLogonServer_2eproto = nullptr; static constexpr ::PROTOBUF_NAMESPACE_ID::ServiceDescriptor const** file_level_service_descriptors_Pb_5fLogonServer_2eproto = nullptr; -||||||| .r248 -static ::PROTOBUF_NAMESPACE_ID::Metadata file_level_metadata_Source_2fMessageDef_2fPb_5fLogonServer_2eproto[8]; -static constexpr ::PROTOBUF_NAMESPACE_ID::EnumDescriptor const** file_level_enum_descriptors_Source_2fMessageDef_2fPb_5fLogonServer_2eproto = nullptr; -static constexpr ::PROTOBUF_NAMESPACE_ID::ServiceDescriptor const** file_level_service_descriptors_Source_2fMessageDef_2fPb_5fLogonServer_2eproto = nullptr; -======= -static ::PROTOBUF_NAMESPACE_ID::Metadata file_level_metadata_Source_2fMessageDef_2fPb_5fLogonServer_2eproto[9]; -static constexpr ::PROTOBUF_NAMESPACE_ID::EnumDescriptor const** file_level_enum_descriptors_Source_2fMessageDef_2fPb_5fLogonServer_2eproto = nullptr; -static constexpr ::PROTOBUF_NAMESPACE_ID::ServiceDescriptor const** file_level_service_descriptors_Source_2fMessageDef_2fPb_5fLogonServer_2eproto = nullptr; ->>>>>>> .r273 const ::PROTOBUF_NAMESPACE_ID::uint32 TableStruct_Pb_5fLogonServer_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { ~0u, // no _has_bits_ @@ -344,207 +328,74 @@ static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = reinterpret_cast(&::LogonServer::_PB_CS_S_tagGameServer_default_instance_), }; -<<<<<<< .mine const char descriptor_table_protodef_Pb_5fLogonServer_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = - "\n\024Pb_LogonServer.proto\022\013LogonServer\"\251\001\n\025" + "\n\024Pb_LogonServer.proto\022\013LogonServer\"\274\001\n\025" "PB_CS_C_LogonAccounts\022\021\n\twModuleID\030\001 \001(\r" "\022\026\n\016dwPlazaVersion\030\002 \001(\r\022\024\n\014cbDeviceType" "\030\003 \001(\r\022\022\n\nbLogonType\030\004 \001(\r\022\022\n\nszAccounts" "\030\005 \001(\t\022\022\n\nszPassword\030\006 \001(\t\022\023\n\013szMachineI" - "D\030\007 \001(\t\"\304\002\n\024PB_CS_S_LogonSuccess\022\022\n\ndwCu" - "stomID\030\001 \001(\r\022\020\n\010dwUserID\030\002 \001(\r\022\020\n\010dwGame" - "ID\030\003 \001(\r\022\024\n\014dwExperience\030\004 \001(\r\022\024\n\014dwLove" - "Liness\030\005 \001(\r\022\022\n\nlUserScore\030\006 \001(\021\022\022\n\nlUse" - "rIngot\030\007 \001(\021\022\023\n\013lUserInsure\030\010 \001(\021\022\022\n\ndUs" - "erBeans\030\t \001(\021\022\017\n\007wFaceID\030\n \001(\r\022\020\n\010cbGend" - "er\030\013 \001(\r\022\027\n\017cbInsureEnabled\030\014 \001(\r\022\022\n\nszN" - "ickName\030\r \001(\t\022\025\n\rszDynamicPass\030\016 \001(\t\022\020\n\010" - "BingDing\030\017 \001(\r\"E\n\024PB_CS_S_LogonFailure\022\023" - "\n\013lResultCode\030\001 \001(\022\022\030\n\020szDescribeString\030" - "\002 \001(\t\"@\n\033PB_CS_C_LogonCheckVerifCode\022\017\n\007" - "bResult\030\001 \001(\r\022\020\n\010PhoneNum\030\002 \001(\t\"\347\001\n\030PB_C" - "S_C_RegisterAccounts\022\021\n\twModuleID\030\001 \001(\r\022" - "\026\n\016dwPlazaVersion\030\002 \001(\r\022\024\n\014cbDeviceType\030" - "\003 \001(\r\022\023\n\013szLogonPass\030\004 \001(\t\022\017\n\007wFaceID\030\005 " - "\001(\r\022\020\n\010cbGender\030\006 \001(\r\022\022\n\nszAccounts\030\007 \001(" - "\t\022\022\n\nszNickName\030\010 \001(\t\022\023\n\013szMachineID\030\t \001" - "(\t\022\025\n\rszMobilePhone\030\n \001(\t\"\330\002\n\034PB_CS_C_Lo" - "gonOtherPlatformEx\022\021\n\twModuleID\030\001 \001(\r\022\026\n" - "\016dwPlazaVersion\030\002 \001(\r\022\024\n\014cbDeviceType\030\003 " - "\001(\r\022\020\n\010cbGender\030\004 \001(\r\022\024\n\014cbPlatformID\030\005 " - "\001(\r\022\021\n\tszUserUin\030\006 \001(\t\022\022\n\nszNickName\030\007 \001" - "(\t\022\026\n\016szCompellation\030\010 \001(\t\022\023\n\013szMachineI" - "D\030\t \001(\t\022\025\n\rszMobilePhone\030\n \001(\t\022\021\n\tszHead" - "Url\030\013 \001(\t\022\t\n\001x\030\014 \001(\022\022\t\n\001y\030\r \001(\022\022\023\n\013isSim" - "ulator\030\016 \001(\r\022\023\n\013networkType\030\017 \001(\r\022\021\n\tdia" - "nliang\030\020 \001(\r\")\n\024PB_CS_S_UserServerID\022\021\n\t" - "wServerID\030\001 \001(\r\"\221\003\n\025PB_CS_S_tagGameServe" - "r\022\017\n\007wKindID\030\001 \001(\r\022\017\n\007wNodeID\030\002 \001(\r\022\017\n\007w" - "SortID\030\003 \001(\r\022\021\n\twServerID\030\004 \001(\r\022\023\n\013wServ" - "erKind\030\005 \001(\r\022\023\n\013wServerType\030\006 \001(\r\022\023\n\013wSe" - "rverPort\030\007 \001(\r\022\022\n\nlCellScore\030\010 \001(\022\022\023\n\013lE" - "nterScore\030\t \001(\022\022\024\n\014dwServerRule\030\n \001(\022\022\025\n" - "\rdwOnLineCount\030\013 \001(\r\022\027\n\017wTableFullCount\030" - "\014 \001(\r\022\031\n\021wTableOnlineCount\030\r \001(\r\022\023\n\013dwFu" - "llCount\030\016 \001(\r\022\024\n\014szServerAddr\030\017 \001(\t\022\024\n\014s" - "zServerName\030\020 \001(\t\022\022\n\ndwLiveTime\030\021 \001(\022\022\024\n" - "\014wServerLevel\030\022 \001(\rb\006proto3" -||||||| .r248 -const char descriptor_table_protodef_Source_2fMessageDef_2fPb_5fLogonServer_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = - "\n&Source/MessageDef/Pb_LogonServer.proto" - "\022\013LogonServer\"\251\001\n\025PB_CS_C_LogonAccounts\022" - "\021\n\twModuleID\030\001 \001(\r\022\026\n\016dwPlazaVersion\030\002 \001" - "(\r\022\024\n\014cbDeviceType\030\003 \001(\r\022\022\n\nbLogonType\030\004" - " \001(\r\022\022\n\nszAccounts\030\005 \001(\t\022\022\n\nszPassword\030\006" - " \001(\t\022\023\n\013szMachineID\030\007 \001(\t\"\304\002\n\024PB_CS_S_Lo" - "gonSuccess\022\022\n\ndwCustomID\030\001 \001(\r\022\020\n\010dwUser" - "ID\030\002 \001(\r\022\020\n\010dwGameID\030\003 \001(\r\022\024\n\014dwExperien" - "ce\030\004 \001(\r\022\024\n\014dwLoveLiness\030\005 \001(\r\022\022\n\nlUserS" - "core\030\006 \001(\021\022\022\n\nlUserIngot\030\007 \001(\021\022\023\n\013lUserI" - "nsure\030\010 \001(\021\022\022\n\ndUserBeans\030\t \001(\021\022\017\n\007wFace" - "ID\030\n \001(\r\022\020\n\010cbGender\030\013 \001(\r\022\027\n\017cbInsureEn" - "abled\030\014 \001(\r\022\022\n\nszNickName\030\r \001(\t\022\025\n\rszDyn" - "amicPass\030\016 \001(\t\022\020\n\010BingDing\030\017 \001(\r\"E\n\024PB_C" - "S_S_LogonFailure\022\023\n\013lResultCode\030\001 \001(\022\022\030\n" - "\020szDescribeString\030\002 \001(\t\"@\n\033PB_CS_C_Logon" - "CheckVerifCode\022\017\n\007bResult\030\001 \001(\r\022\020\n\010Phone" - "Num\030\002 \001(\t\"\347\001\n\030PB_CS_C_RegisterAccounts\022\021" - "\n\twModuleID\030\001 \001(\r\022\026\n\016dwPlazaVersion\030\002 \001(" - "\r\022\024\n\014cbDeviceType\030\003 \001(\r\022\023\n\013szLogonPass\030\004" - " \001(\t\022\017\n\007wFaceID\030\005 \001(\r\022\020\n\010cbGender\030\006 \001(\r\022" - "\022\n\nszAccounts\030\007 \001(\t\022\022\n\nszNickName\030\010 \001(\t\022" - "\023\n\013szMachineID\030\t \001(\t\022\025\n\rszMobilePhone\030\n " - "\001(\t\"\330\002\n\034PB_CS_C_LogonOtherPlatformEx\022\021\n\t" - "wModuleID\030\001 \001(\r\022\026\n\016dwPlazaVersion\030\002 \001(\r\022" - "\024\n\014cbDeviceType\030\003 \001(\r\022\020\n\010cbGender\030\004 \001(\r\022" - "\024\n\014cbPlatformID\030\005 \001(\r\022\021\n\tszUserUin\030\006 \001(\t" - "\022\022\n\nszNickName\030\007 \001(\t\022\026\n\016szCompellation\030\010" - " \001(\t\022\023\n\013szMachineID\030\t \001(\t\022\025\n\rszMobilePho" - "ne\030\n \001(\t\022\021\n\tszHeadUrl\030\013 \001(\t\022\t\n\001x\030\014 \001(\022\022\t" - "\n\001y\030\r \001(\022\022\023\n\013isSimulator\030\016 \001(\r\022\023\n\013networ" - "kType\030\017 \001(\r\022\021\n\tdianliang\030\020 \001(\r\")\n\024PB_CS_" - "S_UserServerID\022\021\n\twServerID\030\001 \001(\r\"\221\003\n\025PB" - "_CS_S_tagGameServer\022\017\n\007wKindID\030\001 \001(\r\022\017\n\007" - "wNodeID\030\002 \001(\r\022\017\n\007wSortID\030\003 \001(\r\022\021\n\twServe" - "rID\030\004 \001(\r\022\023\n\013wServerKind\030\005 \001(\r\022\023\n\013wServe" - "rType\030\006 \001(\r\022\023\n\013wServerPort\030\007 \001(\r\022\022\n\nlCel" - "lScore\030\010 \001(\022\022\023\n\013lEnterScore\030\t \001(\022\022\024\n\014dwS" - "erverRule\030\n \001(\022\022\025\n\rdwOnLineCount\030\013 \001(\r\022\027" - "\n\017wTableFullCount\030\014 \001(\r\022\031\n\021wTableOnlineC" - "ount\030\r \001(\r\022\023\n\013dwFullCount\030\016 \001(\r\022\024\n\014szSer" - "verAddr\030\017 \001(\t\022\024\n\014szServerName\030\020 \001(\t\022\022\n\nd" - "wLiveTime\030\021 \001(\022\022\024\n\014wServerLevel\030\022 \001(\rb\006p" - "roto3" -======= -const char descriptor_table_protodef_Source_2fMessageDef_2fPb_5fLogonServer_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = - "\n&Source/MessageDef/Pb_LogonServer.proto" - "\022\013LogonServer\"\274\001\n\025PB_CS_C_LogonAccounts\022" - "\021\n\twModuleID\030\001 \001(\r\022\026\n\016dwPlazaVersion\030\002 \001" - "(\r\022\024\n\014cbDeviceType\030\003 \001(\r\022\022\n\nbLogonType\030\004" - " \001(\r\022\022\n\nszAccounts\030\005 \001(\t\022\022\n\nszPassword\030\006" - " \001(\t\022\023\n\013szMachineID\030\007 \001(\t\022\021\n\tszUserUin\030\010" - " \001(\t\"\304\002\n\024PB_CS_S_LogonSuccess\022\022\n\ndwCusto" - "mID\030\001 \001(\r\022\020\n\010dwUserID\030\002 \001(\r\022\020\n\010dwGameID\030" - "\003 \001(\r\022\024\n\014dwExperience\030\004 \001(\r\022\024\n\014dwLoveLin" - "ess\030\005 \001(\r\022\022\n\nlUserScore\030\006 \001(\021\022\022\n\nlUserIn" - "got\030\007 \001(\021\022\023\n\013lUserInsure\030\010 \001(\021\022\022\n\ndUserB" - "eans\030\t \001(\021\022\017\n\007wFaceID\030\n \001(\r\022\020\n\010cbGender\030" - "\013 \001(\r\022\027\n\017cbInsureEnabled\030\014 \001(\r\022\022\n\nszNick" - "Name\030\r \001(\t\022\025\n\rszDynamicPass\030\016 \001(\t\022\020\n\010Bin" - "gDing\030\017 \001(\r\"E\n\024PB_CS_S_LogonFailure\022\023\n\013l" - "ResultCode\030\001 \001(\022\022\030\n\020szDescribeString\030\002 \001" - "(\t\"@\n\033PB_CS_C_LogonCheckVerifCode\022\017\n\007bRe" - "sult\030\001 \001(\r\022\020\n\010PhoneNum\030\002 \001(\t\"Z\n\033PB_CS_S_" - "LogonCheckVerifCode\022\017\n\007bResult\030\001 \001(\r\022\020\n\010" - "PhoneNum\030\002 \001(\t\022\030\n\020strErrorDescribe\030\003 \001(\t" - "\"\347\001\n\030PB_CS_C_RegisterAccounts\022\021\n\twModule" - "ID\030\001 \001(\r\022\026\n\016dwPlazaVersion\030\002 \001(\r\022\024\n\014cbDe" - "viceType\030\003 \001(\r\022\023\n\013szLogonPass\030\004 \001(\t\022\017\n\007w" - "FaceID\030\005 \001(\r\022\020\n\010cbGender\030\006 \001(\r\022\022\n\nszAcco" - "unts\030\007 \001(\t\022\022\n\nszNickName\030\010 \001(\t\022\023\n\013szMach" - "ineID\030\t \001(\t\022\025\n\rszMobilePhone\030\n \001(\t\"\330\002\n\034P" - "B_CS_C_LogonOtherPlatformEx\022\021\n\twModuleID" - "\030\001 \001(\r\022\026\n\016dwPlazaVersion\030\002 \001(\r\022\024\n\014cbDevi" - "ceType\030\003 \001(\r\022\020\n\010cbGender\030\004 \001(\r\022\024\n\014cbPlat" - "formID\030\005 \001(\r\022\021\n\tszUserUin\030\006 \001(\t\022\022\n\nszNic" - "kName\030\007 \001(\t\022\026\n\016szCompellation\030\010 \001(\t\022\023\n\013s" - "zMachineID\030\t \001(\t\022\025\n\rszMobilePhone\030\n \001(\t\022" - "\021\n\tszHeadUrl\030\013 \001(\t\022\t\n\001x\030\014 \001(\022\022\t\n\001y\030\r \001(\022" - "\022\023\n\013isSimulator\030\016 \001(\r\022\023\n\013networkType\030\017 \001" - "(\r\022\021\n\tdianliang\030\020 \001(\r\")\n\024PB_CS_S_UserSer" - "verID\022\021\n\twServerID\030\001 \001(\r\"\221\003\n\025PB_CS_S_tag" - "GameServer\022\017\n\007wKindID\030\001 \001(\r\022\017\n\007wNodeID\030\002" - " \001(\r\022\017\n\007wSortID\030\003 \001(\r\022\021\n\twServerID\030\004 \001(\r" - "\022\023\n\013wServerKind\030\005 \001(\r\022\023\n\013wServerType\030\006 \001" - "(\r\022\023\n\013wServerPort\030\007 \001(\r\022\022\n\nlCellScore\030\010 " - "\001(\022\022\023\n\013lEnterScore\030\t \001(\022\022\024\n\014dwServerRule" - "\030\n \001(\022\022\025\n\rdwOnLineCount\030\013 \001(\r\022\027\n\017wTableF" - "ullCount\030\014 \001(\r\022\031\n\021wTableOnlineCount\030\r \001(" - "\r\022\023\n\013dwFullCount\030\016 \001(\r\022\024\n\014szServerAddr\030\017" - " \001(\t\022\024\n\014szServerName\030\020 \001(\t\022\022\n\ndwLiveTime" - "\030\021 \001(\022\022\024\n\014wServerLevel\030\022 \001(\rb\006proto3" ->>>>>>> .r273 + "D\030\007 \001(\t\022\021\n\tszUserUin\030\010 \001(\t\"\304\002\n\024PB_CS_S_L" + "ogonSuccess\022\022\n\ndwCustomID\030\001 \001(\r\022\020\n\010dwUse" + "rID\030\002 \001(\r\022\020\n\010dwGameID\030\003 \001(\r\022\024\n\014dwExperie" + "nce\030\004 \001(\r\022\024\n\014dwLoveLiness\030\005 \001(\r\022\022\n\nlUser" + "Score\030\006 \001(\021\022\022\n\nlUserIngot\030\007 \001(\021\022\023\n\013lUser" + "Insure\030\010 \001(\021\022\022\n\ndUserBeans\030\t \001(\021\022\017\n\007wFac" + "eID\030\n \001(\r\022\020\n\010cbGender\030\013 \001(\r\022\027\n\017cbInsureE" + "nabled\030\014 \001(\r\022\022\n\nszNickName\030\r \001(\t\022\025\n\rszDy" + "namicPass\030\016 \001(\t\022\020\n\010BingDing\030\017 \001(\r\"E\n\024PB_" + "CS_S_LogonFailure\022\023\n\013lResultCode\030\001 \001(\022\022\030" + "\n\020szDescribeString\030\002 \001(\t\"@\n\033PB_CS_C_Logo" + "nCheckVerifCode\022\017\n\007bResult\030\001 \001(\r\022\020\n\010Phon" + "eNum\030\002 \001(\t\"Z\n\033PB_CS_S_LogonCheckVerifCod" + "e\022\017\n\007bResult\030\001 \001(\r\022\020\n\010PhoneNum\030\002 \001(\t\022\030\n\020" + "strErrorDescribe\030\003 \001(\t\"\347\001\n\030PB_CS_C_Regis" + "terAccounts\022\021\n\twModuleID\030\001 \001(\r\022\026\n\016dwPlaz" + "aVersion\030\002 \001(\r\022\024\n\014cbDeviceType\030\003 \001(\r\022\023\n\013" + "szLogonPass\030\004 \001(\t\022\017\n\007wFaceID\030\005 \001(\r\022\020\n\010cb" + "Gender\030\006 \001(\r\022\022\n\nszAccounts\030\007 \001(\t\022\022\n\nszNi" + "ckName\030\010 \001(\t\022\023\n\013szMachineID\030\t \001(\t\022\025\n\rszM" + "obilePhone\030\n \001(\t\"\330\002\n\034PB_CS_C_LogonOtherP" + "latformEx\022\021\n\twModuleID\030\001 \001(\r\022\026\n\016dwPlazaV" + "ersion\030\002 \001(\r\022\024\n\014cbDeviceType\030\003 \001(\r\022\020\n\010cb" + "Gender\030\004 \001(\r\022\024\n\014cbPlatformID\030\005 \001(\r\022\021\n\tsz" + "UserUin\030\006 \001(\t\022\022\n\nszNickName\030\007 \001(\t\022\026\n\016szC" + "ompellation\030\010 \001(\t\022\023\n\013szMachineID\030\t \001(\t\022\025" + "\n\rszMobilePhone\030\n \001(\t\022\021\n\tszHeadUrl\030\013 \001(\t" + "\022\t\n\001x\030\014 \001(\022\022\t\n\001y\030\r \001(\022\022\023\n\013isSimulator\030\016 " + "\001(\r\022\023\n\013networkType\030\017 \001(\r\022\021\n\tdianliang\030\020 " + "\001(\r\")\n\024PB_CS_S_UserServerID\022\021\n\twServerID" + "\030\001 \001(\r\"\221\003\n\025PB_CS_S_tagGameServer\022\017\n\007wKin" + "dID\030\001 \001(\r\022\017\n\007wNodeID\030\002 \001(\r\022\017\n\007wSortID\030\003 " + "\001(\r\022\021\n\twServerID\030\004 \001(\r\022\023\n\013wServerKind\030\005 " + "\001(\r\022\023\n\013wServerType\030\006 \001(\r\022\023\n\013wServerPort\030" + "\007 \001(\r\022\022\n\nlCellScore\030\010 \001(\022\022\023\n\013lEnterScore" + "\030\t \001(\022\022\024\n\014dwServerRule\030\n \001(\022\022\025\n\rdwOnLine" + "Count\030\013 \001(\r\022\027\n\017wTableFullCount\030\014 \001(\r\022\031\n\021" + "wTableOnlineCount\030\r \001(\r\022\023\n\013dwFullCount\030\016" + " \001(\r\022\024\n\014szServerAddr\030\017 \001(\t\022\024\n\014szServerNa" + "me\030\020 \001(\t\022\022\n\ndwLiveTime\030\021 \001(\022\022\024\n\014wServerL" + "evel\030\022 \001(\rb\006proto3" ; static const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable*const descriptor_table_Pb_5fLogonServer_2eproto_deps[1] = { }; -<<<<<<< .mine -static ::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase*const descriptor_table_Pb_5fLogonServer_2eproto_sccs[8] = { +static ::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase*const descriptor_table_Pb_5fLogonServer_2eproto_sccs[9] = { &scc_info_PB_CS_C_LogonAccounts_Pb_5fLogonServer_2eproto.base, &scc_info_PB_CS_C_LogonCheckVerifCode_Pb_5fLogonServer_2eproto.base, &scc_info_PB_CS_C_LogonOtherPlatformEx_Pb_5fLogonServer_2eproto.base, &scc_info_PB_CS_C_RegisterAccounts_Pb_5fLogonServer_2eproto.base, + &scc_info_PB_CS_S_LogonCheckVerifCode_Pb_5fLogonServer_2eproto.base, &scc_info_PB_CS_S_LogonFailure_Pb_5fLogonServer_2eproto.base, &scc_info_PB_CS_S_LogonSuccess_Pb_5fLogonServer_2eproto.base, &scc_info_PB_CS_S_UserServerID_Pb_5fLogonServer_2eproto.base, &scc_info_PB_CS_S_tagGameServer_Pb_5fLogonServer_2eproto.base, -||||||| .r248 -static ::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase*const descriptor_table_Source_2fMessageDef_2fPb_5fLogonServer_2eproto_sccs[8] = { - &scc_info_PB_CS_C_LogonAccounts_Source_2fMessageDef_2fPb_5fLogonServer_2eproto.base, - &scc_info_PB_CS_C_LogonCheckVerifCode_Source_2fMessageDef_2fPb_5fLogonServer_2eproto.base, - &scc_info_PB_CS_C_LogonOtherPlatformEx_Source_2fMessageDef_2fPb_5fLogonServer_2eproto.base, - &scc_info_PB_CS_C_RegisterAccounts_Source_2fMessageDef_2fPb_5fLogonServer_2eproto.base, - &scc_info_PB_CS_S_LogonFailure_Source_2fMessageDef_2fPb_5fLogonServer_2eproto.base, - &scc_info_PB_CS_S_LogonSuccess_Source_2fMessageDef_2fPb_5fLogonServer_2eproto.base, - &scc_info_PB_CS_S_UserServerID_Source_2fMessageDef_2fPb_5fLogonServer_2eproto.base, - &scc_info_PB_CS_S_tagGameServer_Source_2fMessageDef_2fPb_5fLogonServer_2eproto.base, -======= -static ::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase*const descriptor_table_Source_2fMessageDef_2fPb_5fLogonServer_2eproto_sccs[9] = { - &scc_info_PB_CS_C_LogonAccounts_Source_2fMessageDef_2fPb_5fLogonServer_2eproto.base, - &scc_info_PB_CS_C_LogonCheckVerifCode_Source_2fMessageDef_2fPb_5fLogonServer_2eproto.base, - &scc_info_PB_CS_C_LogonOtherPlatformEx_Source_2fMessageDef_2fPb_5fLogonServer_2eproto.base, - &scc_info_PB_CS_C_RegisterAccounts_Source_2fMessageDef_2fPb_5fLogonServer_2eproto.base, - &scc_info_PB_CS_S_LogonCheckVerifCode_Source_2fMessageDef_2fPb_5fLogonServer_2eproto.base, - &scc_info_PB_CS_S_LogonFailure_Source_2fMessageDef_2fPb_5fLogonServer_2eproto.base, - &scc_info_PB_CS_S_LogonSuccess_Source_2fMessageDef_2fPb_5fLogonServer_2eproto.base, - &scc_info_PB_CS_S_UserServerID_Source_2fMessageDef_2fPb_5fLogonServer_2eproto.base, - &scc_info_PB_CS_S_tagGameServer_Source_2fMessageDef_2fPb_5fLogonServer_2eproto.base, ->>>>>>> .r273 }; -<<<<<<< .mine static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_Pb_5fLogonServer_2eproto_once; static bool descriptor_table_Pb_5fLogonServer_2eproto_initialized = false; const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_Pb_5fLogonServer_2eproto = { - &descriptor_table_Pb_5fLogonServer_2eproto_initialized, descriptor_table_protodef_Pb_5fLogonServer_2eproto, "Pb_LogonServer.proto", 1707, - &descriptor_table_Pb_5fLogonServer_2eproto_once, descriptor_table_Pb_5fLogonServer_2eproto_sccs, descriptor_table_Pb_5fLogonServer_2eproto_deps, 8, 0, + &descriptor_table_Pb_5fLogonServer_2eproto_initialized, descriptor_table_protodef_Pb_5fLogonServer_2eproto, "Pb_LogonServer.proto", 1818, + &descriptor_table_Pb_5fLogonServer_2eproto_once, descriptor_table_Pb_5fLogonServer_2eproto_sccs, descriptor_table_Pb_5fLogonServer_2eproto_deps, 9, 0, schemas, file_default_instances, TableStruct_Pb_5fLogonServer_2eproto::offsets, - file_level_metadata_Pb_5fLogonServer_2eproto, 8, file_level_enum_descriptors_Pb_5fLogonServer_2eproto, file_level_service_descriptors_Pb_5fLogonServer_2eproto, -||||||| .r248 -static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_Source_2fMessageDef_2fPb_5fLogonServer_2eproto_once; -static bool descriptor_table_Source_2fMessageDef_2fPb_5fLogonServer_2eproto_initialized = false; -const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_Source_2fMessageDef_2fPb_5fLogonServer_2eproto = { - &descriptor_table_Source_2fMessageDef_2fPb_5fLogonServer_2eproto_initialized, descriptor_table_protodef_Source_2fMessageDef_2fPb_5fLogonServer_2eproto, "Source/MessageDef/Pb_LogonServer.proto", 1725, - &descriptor_table_Source_2fMessageDef_2fPb_5fLogonServer_2eproto_once, descriptor_table_Source_2fMessageDef_2fPb_5fLogonServer_2eproto_sccs, descriptor_table_Source_2fMessageDef_2fPb_5fLogonServer_2eproto_deps, 8, 0, - schemas, file_default_instances, TableStruct_Source_2fMessageDef_2fPb_5fLogonServer_2eproto::offsets, - file_level_metadata_Source_2fMessageDef_2fPb_5fLogonServer_2eproto, 8, file_level_enum_descriptors_Source_2fMessageDef_2fPb_5fLogonServer_2eproto, file_level_service_descriptors_Source_2fMessageDef_2fPb_5fLogonServer_2eproto, -======= -static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_Source_2fMessageDef_2fPb_5fLogonServer_2eproto_once; -static bool descriptor_table_Source_2fMessageDef_2fPb_5fLogonServer_2eproto_initialized = false; -const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_Source_2fMessageDef_2fPb_5fLogonServer_2eproto = { - &descriptor_table_Source_2fMessageDef_2fPb_5fLogonServer_2eproto_initialized, descriptor_table_protodef_Source_2fMessageDef_2fPb_5fLogonServer_2eproto, "Source/MessageDef/Pb_LogonServer.proto", 1836, - &descriptor_table_Source_2fMessageDef_2fPb_5fLogonServer_2eproto_once, descriptor_table_Source_2fMessageDef_2fPb_5fLogonServer_2eproto_sccs, descriptor_table_Source_2fMessageDef_2fPb_5fLogonServer_2eproto_deps, 9, 0, - schemas, file_default_instances, TableStruct_Source_2fMessageDef_2fPb_5fLogonServer_2eproto::offsets, - file_level_metadata_Source_2fMessageDef_2fPb_5fLogonServer_2eproto, 9, file_level_enum_descriptors_Source_2fMessageDef_2fPb_5fLogonServer_2eproto, file_level_service_descriptors_Source_2fMessageDef_2fPb_5fLogonServer_2eproto, ->>>>>>> .r273 + file_level_metadata_Pb_5fLogonServer_2eproto, 9, file_level_enum_descriptors_Pb_5fLogonServer_2eproto, file_level_service_descriptors_Pb_5fLogonServer_2eproto, }; // Force running AddDescriptors() at dynamic initialization time. @@ -1997,7 +1848,7 @@ PB_CS_S_LogonCheckVerifCode::PB_CS_S_LogonCheckVerifCode(const PB_CS_S_LogonChec } void PB_CS_S_LogonCheckVerifCode::SharedCtor() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_PB_CS_S_LogonCheckVerifCode_Source_2fMessageDef_2fPb_5fLogonServer_2eproto.base); + ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_PB_CS_S_LogonCheckVerifCode_Pb_5fLogonServer_2eproto.base); phonenum_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); strerrordescribe_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); bresult_ = 0u; @@ -2017,7 +1868,7 @@ void PB_CS_S_LogonCheckVerifCode::SetCachedSize(int size) const { _cached_size_.Set(size); } const PB_CS_S_LogonCheckVerifCode& PB_CS_S_LogonCheckVerifCode::default_instance() { - ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_PB_CS_S_LogonCheckVerifCode_Source_2fMessageDef_2fPb_5fLogonServer_2eproto.base); + ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_PB_CS_S_LogonCheckVerifCode_Pb_5fLogonServer_2eproto.base); return *internal_default_instance(); } diff --git a/俱乐部/Source/MessageDef/Pb_LogonServer.pb.h b/俱乐部/Source/MessageDef/Pb_LogonServer.pb.h index ad265e3..6f0ce10 100644 --- a/俱乐部/Source/MessageDef/Pb_LogonServer.pb.h +++ b/俱乐部/Source/MessageDef/Pb_LogonServer.pb.h @@ -1014,8 +1014,8 @@ class PB_CS_S_LogonCheckVerifCode : ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; private: static ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadataStatic() { - ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&::descriptor_table_Source_2fMessageDef_2fPb_5fLogonServer_2eproto); - return ::descriptor_table_Source_2fMessageDef_2fPb_5fLogonServer_2eproto.file_level_metadata[kIndexInFileMessages]; + ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&::descriptor_table_Pb_5fLogonServer_2eproto); + return ::descriptor_table_Pb_5fLogonServer_2eproto.file_level_metadata[kIndexInFileMessages]; } public: @@ -1079,7 +1079,7 @@ class PB_CS_S_LogonCheckVerifCode : ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr strerrordescribe_; ::PROTOBUF_NAMESPACE_ID::uint32 bresult_; mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; - friend struct ::TableStruct_Source_2fMessageDef_2fPb_5fLogonServer_2eproto; + friend struct ::TableStruct_Pb_5fLogonServer_2eproto; }; // ------------------------------------------------------------------- diff --git a/俱乐部/Source/MessageDef/Pb_RecordPacket.pb.cc b/俱乐部/Source/MessageDef/Pb_RecordPacket.pb.cc index 0035579..92f64d8 100644 --- a/俱乐部/Source/MessageDef/Pb_RecordPacket.pb.cc +++ b/俱乐部/Source/MessageDef/Pb_RecordPacket.pb.cc @@ -162,7 +162,6 @@ static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = reinterpret_cast(&::RecordPacket::_PB_CS_S_ReplayRecordResp_default_instance_), }; -<<<<<<< .mine const char descriptor_table_protodef_Pb_5fRecordPacket_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = "\n\025Pb_RecordPacket.proto\022\014RecordPacket\"]\n" "\023pb_GameRecordPacket\022\020\n\010wChairID\030\001 \001(\r\022\022" @@ -183,51 +182,6 @@ const char descriptor_table_protodef_Pb_5fRecordPacket_2eproto[] PROTOBUF_SECTIO "_chairList\030\007 \003(\0132\034.RecordPacket.pb_Chair" "Record\0228\n\rpRecordPacket\030\010 \003(\0132!.RecordPa" "cket.pb_GameRecordPacketb\006proto3" -||||||| .r248 -const char descriptor_table_protodef_Source_2fMessageDef_2fPb_5fRecordPacket_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = - "\n\'Source/MessageDef/Pb_RecordPacket.prot" - "o\022\014RecordPacket\"]\n\023pb_GameRecordPacket\022\020" - "\n\010wChairID\030\001 \001(\r\022\022\n\nwMainCmdID\030\002 \001(\r\022\021\n\t" - "wSubCmdID\030\003 \001(\r\022\r\n\005pData\030\004 \001(\t\"\201\002\n\rpb_Ga" - "meConfig\022\022\n\nwSubGameID\030\001 \001(\r\022\020\n\010wDiScore" - "\030\002 \001(\r\022\017\n\007wFanFei\030\003 \001(\r\022\020\n\010wIpLimit\030\004 \001(" - "\r\022\026\n\016wPlayCountRule\030\005 \001(\r\022\016\n\006RoomId\030\006 \001(" - "\r\022\017\n\007IsOwner\030\007 \001(\r\022\025\n\rwHadPlayCount\030\010 \001(" - "\r\022\027\n\017sPrivateTableID\030\t \001(\t\022\017\n\007bDuoLai\030\n " - "\001(\r\022\021\n\twFengDing\030\013 \001(\r\022\014\n\004tmp1\030\014 \001(\r\022\014\n\004" - "tmp2\030\r \001(\r\"W\n\016pb_ChairRecord\022\020\n\010wChairId" - "\030\001 \001(\r\022\020\n\010dwUserId\030\002 \001(\r\022\020\n\010userName\030\003 \001" - "(\t\022\017\n\007headUrl\030\004 \001(\t\"\204\002\n\030PB_CS_S_ReplayRe" - "cordResp\022\016\n\006m_UUID\030\001 \001(\r\022\023\n\013m_startTime\030" - "\003 \001(\r\022\021\n\tm_endTime\030\004 \001(\r\022\020\n\010m_UserId\030\005 \001" - "(\r\0221\n\014m_gameconfig\030\006 \001(\0132\033.RecordPacket." - "pb_GameConfig\0221\n\013m_chairList\030\007 \003(\0132\034.Rec" - "ordPacket.pb_ChairRecord\0228\n\rpRecordPacke" - "t\030\010 \003(\0132!.RecordPacket.pb_GameRecordPack" - "etb\006proto3" -======= -const char descriptor_table_protodef_Source_2fMessageDef_2fPb_5fRecordPacket_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = - "\n\'Source/MessageDef/Pb_RecordPacket.prot" - "o\022\014RecordPacket\"]\n\023pb_GameRecordPacket\022\020" - "\n\010wChairID\030\001 \001(\r\022\022\n\nwMainCmdID\030\002 \001(\r\022\021\n\t" - "wSubCmdID\030\003 \001(\r\022\r\n\005pData\030\004 \001(\014\"\201\002\n\rpb_Ga" - "meConfig\022\022\n\nwSubGameID\030\001 \001(\r\022\020\n\010wDiScore" - "\030\002 \001(\r\022\017\n\007wFanFei\030\003 \001(\r\022\020\n\010wIpLimit\030\004 \001(" - "\r\022\026\n\016wPlayCountRule\030\005 \001(\r\022\016\n\006RoomId\030\006 \001(" - "\r\022\017\n\007IsOwner\030\007 \001(\r\022\025\n\rwHadPlayCount\030\010 \001(" - "\r\022\027\n\017sPrivateTableID\030\t \001(\t\022\017\n\007bDuoLai\030\n " - "\001(\r\022\021\n\twFengDing\030\013 \001(\r\022\014\n\004tmp1\030\014 \001(\r\022\014\n\004" - "tmp2\030\r \001(\r\"W\n\016pb_ChairRecord\022\020\n\010wChairId" - "\030\001 \001(\r\022\020\n\010dwUserId\030\002 \001(\r\022\020\n\010userName\030\003 \001" - "(\t\022\017\n\007headUrl\030\004 \001(\t\"\204\002\n\030PB_CS_S_ReplayRe" - "cordResp\022\016\n\006m_UUID\030\001 \001(\r\022\023\n\013m_startTime\030" - "\003 \001(\r\022\021\n\tm_endTime\030\004 \001(\r\022\020\n\010m_UserId\030\005 \001" - "(\r\0221\n\014m_gameconfig\030\006 \001(\0132\033.RecordPacket." - "pb_GameConfig\0221\n\013m_chairList\030\007 \003(\0132\034.Rec" - "ordPacket.pb_ChairRecord\0228\n\rpRecordPacke" - "t\030\010 \003(\0132!.RecordPacket.pb_GameRecordPack" - "etb\006proto3" ->>>>>>> .r273 ; static const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable*const descriptor_table_Pb_5fRecordPacket_2eproto_deps[1] = { }; diff --git a/俱乐部/Source/MessageDef/Pb_Socket.pb.cc b/俱乐部/Source/MessageDef/Pb_Socket.pb.cc index 728e695..706e269 100644 --- a/俱乐部/Source/MessageDef/Pb_Socket.pb.cc +++ b/俱乐部/Source/MessageDef/Pb_Socket.pb.cc @@ -1,6 +1,6 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: Pb_Socket.proto - +#include "stdafx.h" #include "Pb_Socket.pb.h" #include diff --git a/俱乐部/Source/ServerControl/CorrespondServer/CorrespondServer.vcxproj b/俱乐部/Source/ServerControl/CorrespondServer/CorrespondServer.vcxproj index 7ae9bcd..2fc7383 100644 --- a/俱乐部/Source/ServerControl/CorrespondServer/CorrespondServer.vcxproj +++ b/俱乐部/Source/ServerControl/CorrespondServer/CorrespondServer.vcxproj @@ -5,18 +5,10 @@ Debug_Unicode Win32 - - Debug - Win32 - Release_Unicode Win32 - - Release - Win32 - {CCD2D328-1912-4FC4-91B5-2333A7EF6EB7} @@ -25,13 +17,6 @@ 10.0 - - Application - true - v142 - Unicode - Dynamic - Application true @@ -39,14 +24,6 @@ Unicode Dynamic - - Application - false - v142 - true - Unicode - Dynamic - Application false @@ -58,58 +35,23 @@ - - - - - - - - true - true $(SolutionDir)Bin\$(Configuration)\ ../../../\Source\SharedControl\create_dump;$(IncludePath) - - false - false $(SolutionDir)Bin\$(Configuration)\ ../../../\Source\SharedControl\create_dump;$(IncludePath) - - - Use - Level3 - Disabled - _USING_V110_SDK71_;WIN32;_WINDOWS;_DEBUG;%(PreprocessorDefinitions) - true - - - Windows - true - - - false - true - _DEBUG;%(PreprocessorDefinitions) - - - 0x0804 - _DEBUG;%(PreprocessorDefinitions) - $(IntDir);%(AdditionalIncludeDirectories) - - Use @@ -139,33 +81,6 @@ - - - Level3 - Use - MaxSpeed - true - true - WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions) - true - - - Windows - true - true - true - - - false - true - NDEBUG;%(PreprocessorDefinitions) - - - 0x0804 - NDEBUG;%(PreprocessorDefinitions) - $(IntDir);%(AdditionalIncludeDirectories) - - Level3 @@ -232,9 +147,7 @@ copy /y $(OutDir)$(TargetFileName) ..\..\..\Publish\Server\$(Configuration)\$(Ta - Create Create - Create Create diff --git a/俱乐部/Source/ServerControl/CorrespondServer/Debug_Unicode/CorrespondServer.res b/俱乐部/Source/ServerControl/CorrespondServer/Debug_Unicode/CorrespondServer.res new file mode 100644 index 0000000..af6af94 Binary files /dev/null and b/俱乐部/Source/ServerControl/CorrespondServer/Debug_Unicode/CorrespondServer.res differ diff --git a/俱乐部/Source/ServerControl/GameServer/Debug_Unicode/GameServer.res b/俱乐部/Source/ServerControl/GameServer/Debug_Unicode/GameServer.res new file mode 100644 index 0000000..3bec288 Binary files /dev/null and b/俱乐部/Source/ServerControl/GameServer/Debug_Unicode/GameServer.res differ diff --git a/俱乐部/Source/ServerControl/GameServer/GameServer.vcxproj b/俱乐部/Source/ServerControl/GameServer/GameServer.vcxproj index 21e198b..54dc575 100644 --- a/俱乐部/Source/ServerControl/GameServer/GameServer.vcxproj +++ b/俱乐部/Source/ServerControl/GameServer/GameServer.vcxproj @@ -5,18 +5,10 @@ Debug_Unicode Win32 - - Debug - Win32 - Release_Unicode Win32 - - Release - Win32 - {5266973A-47AE-481C-BD4B-06E5DB08A99B} @@ -25,13 +17,6 @@ 10.0 - - Application - true - v142 - Unicode - Dynamic - Application true @@ -39,14 +24,6 @@ Unicode Dynamic - - Application - false - v142 - true - MultiByte - Dynamic - Application false @@ -58,61 +35,24 @@ - - - - - - - - true - D:\MJ_CODE\后台代码\松滋市一脚癞油\Source\ServerControl\curl-7.32.0\include;$(IncludePath) - D:\MJ_CODE\后台代码\松滋市一脚癞油\Source\Libs\Debug_Unicode;$(LibraryPath) - true $(SolutionDir)Bin\$(Configuration)\ ../../../\Source\SharedControl\create_dump;../../../\Source\ServerControl\curl-7.32.0\include;$(IncludePath);../Json; - - false - false $(SolutionDir)Bin\$(Configuration)\ $(Configuration)\ ../../../\Source\SharedControl\create_dump;../../../\Source\ServerControl\curl-7.32.0\include;$(IncludePath);../Json - - - Use - Level3 - Disabled - _USING_V110_SDK71_;WIN32;_WINDOWS;_DEBUG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - - - Windows - true - - - false - true - _DEBUG;%(PreprocessorDefinitions) - - - 0x0804 - _DEBUG;%(PreprocessorDefinitions) - $(IntDir);%(AdditionalIncludeDirectories) - - NotUsing @@ -145,33 +85,6 @@ - - - Level3 - Use - MaxSpeed - true - true - WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions) - true - - - Windows - true - true - true - - - false - true - NDEBUG;%(PreprocessorDefinitions) - - - 0x0804 - NDEBUG;%(PreprocessorDefinitions) - $(IntDir);%(AdditionalIncludeDirectories) - - Level3 @@ -276,9 +189,7 @@ copy /y $(OutDir)$(TargetFileName) ..\..\..\Publish\Server\$(Configuration)\$(Ta - Create Create - Create Create diff --git a/俱乐部/Source/ServerControl/GameService/Debug_Unicode/GameService.res b/俱乐部/Source/ServerControl/GameService/Debug_Unicode/GameService.res new file mode 100644 index 0000000..6e7fbc2 Binary files /dev/null and b/俱乐部/Source/ServerControl/GameService/Debug_Unicode/GameService.res differ diff --git a/俱乐部/Source/ServerControl/GameService/GameService.vcxproj b/俱乐部/Source/ServerControl/GameService/GameService.vcxproj index 877a41b..be930d5 100644 --- a/俱乐部/Source/ServerControl/GameService/GameService.vcxproj +++ b/俱乐部/Source/ServerControl/GameService/GameService.vcxproj @@ -5,18 +5,10 @@ Debug_Unicode Win32 - - Debug - Win32 - Release_Unicode Win32 - - Release - Win32 - {51FD2060-F4F9-4982-8474-473541D4FCF8} @@ -25,13 +17,6 @@ 10.0 - - DynamicLibrary - true - v142 - Unicode - Dynamic - DynamicLibrary true @@ -39,14 +24,6 @@ Unicode Dynamic - - DynamicLibrary - false - v142 - true - Unicode - Dynamic - DynamicLibrary false @@ -58,57 +35,22 @@ - - - - - - - - true - true $(SolutionDir)Bin\$(Configuration)\ $(ProjectName)D - - false - false $(SolutionDir)Bin\$(Configuration)\ - - - Use - Level3 - Disabled - _USING_V110_SDK71_;WIN32;_WINDOWS;_DEBUG;_AFXEXT;GAME_SERVICE_DLL;%(PreprocessorDefinitions) - true - - - Windows - true - .\GameService.def - - - false - _DEBUG;%(PreprocessorDefinitions) - - - 0x0804 - _DEBUG;%(PreprocessorDefinitions) - $(IntDir);%(AdditionalIncludeDirectories) - - NotUsing @@ -139,33 +81,6 @@ - - - Level3 - Use - MaxSpeed - true - true - WIN32;_WINDOWS;NDEBUG;_AFXEXT;GAME_SERVICE_DLL;%(PreprocessorDefinitions) - true - - - Windows - true - true - true - .\GameService.def - - - false - NDEBUG;%(PreprocessorDefinitions) - - - 0x0804 - NDEBUG;%(PreprocessorDefinitions) - $(IntDir);%(AdditionalIncludeDirectories) - - Level3 @@ -216,9 +131,7 @@ copy /y $(OutDir)$(TargetFileName) ..\..\..\Publish\Server\$(Configuration)\$(Ta - Create Create - Create Create diff --git a/俱乐部/Source/ServerControl/GameService/Release_Unicode/GameService.res b/俱乐部/Source/ServerControl/GameService/Release_Unicode/GameService.res new file mode 100644 index 0000000..88f1fc5 Binary files /dev/null and b/俱乐部/Source/ServerControl/GameService/Release_Unicode/GameService.res differ diff --git a/俱乐部/Source/ServerControl/Json/Debug/Json.pdb b/俱乐部/Source/ServerControl/Json/Debug/Json.pdb index d7f3c15..dc172cc 100644 Binary files a/俱乐部/Source/ServerControl/Json/Debug/Json.pdb and b/俱乐部/Source/ServerControl/Json/Debug/Json.pdb differ diff --git a/俱乐部/Source/ServerControl/Json/Json.vcxproj b/俱乐部/Source/ServerControl/Json/Json.vcxproj index 665198b..0ea4e33 100644 --- a/俱乐部/Source/ServerControl/Json/Json.vcxproj +++ b/俱乐部/Source/ServerControl/Json/Json.vcxproj @@ -1,12 +1,12 @@  - - Debug + + Debug_Unicode Win32 - - Release + + Release_Unicode Win32 @@ -17,13 +17,13 @@ 10.0 - + StaticLibrary true v142 Unicode - + StaticLibrary false v142 @@ -33,21 +33,21 @@ - + - + - + true ../../../\Source\Libs\Debug_Unicode - + false - + Use Level3 @@ -60,7 +60,7 @@ true - + Level3 Use @@ -95,11 +95,11 @@ - false - + false + - false - + false + @@ -107,8 +107,8 @@ - Create - Create + Create + Create diff --git a/俱乐部/Source/ServerControl/KernelEngine/Debug_Unicode/vc120.pdb b/俱乐部/Source/ServerControl/KernelEngine/Debug_Unicode/vc120.pdb deleted file mode 100644 index c26a174..0000000 Binary files a/俱乐部/Source/ServerControl/KernelEngine/Debug_Unicode/vc120.pdb and /dev/null differ diff --git a/俱乐部/Source/ServerControl/KernelEngine/Debug_Unicode/vc142.pdb b/俱乐部/Source/ServerControl/KernelEngine/Debug_Unicode/vc142.pdb index 1788d94..732c56c 100644 Binary files a/俱乐部/Source/ServerControl/KernelEngine/Debug_Unicode/vc142.pdb and b/俱乐部/Source/ServerControl/KernelEngine/Debug_Unicode/vc142.pdb differ diff --git a/俱乐部/Source/ServerControl/KernelEngine/QueueService.cpp b/俱乐部/Source/ServerControl/KernelEngine/QueueService.cpp index 5272b6f..7e86659 100644 --- a/俱乐部/Source/ServerControl/KernelEngine/QueueService.cpp +++ b/俱乐部/Source/ServerControl/KernelEngine/QueueService.cpp @@ -1,4 +1,4 @@ -#include "StdAfx.h" +#include "stdafx.h" #include "QueueService.h" ////////////////////////////////////////////////////////////////////////// diff --git a/俱乐部/Source/ServerControl/KernelEngine/Release_Unicode/KernelEngine.res b/俱乐部/Source/ServerControl/KernelEngine/Release_Unicode/KernelEngine.res deleted file mode 100644 index 7e19584..0000000 Binary files a/俱乐部/Source/ServerControl/KernelEngine/Release_Unicode/KernelEngine.res and /dev/null differ diff --git a/俱乐部/Source/ServerControl/LogonServer/Debug_Unicode/LogonServer.res b/俱乐部/Source/ServerControl/LogonServer/Debug_Unicode/LogonServer.res new file mode 100644 index 0000000..f53df5f Binary files /dev/null and b/俱乐部/Source/ServerControl/LogonServer/Debug_Unicode/LogonServer.res differ diff --git a/俱乐部/Source/ServerControl/ModuleManager/Debug_Unicode/ModuleManager.res b/俱乐部/Source/ServerControl/ModuleManager/Debug_Unicode/ModuleManager.res new file mode 100644 index 0000000..c20d132 Binary files /dev/null and b/俱乐部/Source/ServerControl/ModuleManager/Debug_Unicode/ModuleManager.res differ diff --git a/俱乐部/Source/SharedControl/ProcessControl/Debug_Unicode/ProcessControl.res b/俱乐部/Source/SharedControl/ProcessControl/Debug_Unicode/ProcessControl.res new file mode 100644 index 0000000..7e2d91c Binary files /dev/null and b/俱乐部/Source/SharedControl/ProcessControl/Debug_Unicode/ProcessControl.res differ diff --git a/俱乐部/Source/SharedControl/ServiceCore/Debug_Unicode/ServiceCore.res b/俱乐部/Source/SharedControl/ServiceCore/Debug_Unicode/ServiceCore.res new file mode 100644 index 0000000..3b2ec74 Binary files /dev/null and b/俱乐部/Source/SharedControl/ServiceCore/Debug_Unicode/ServiceCore.res differ diff --git a/俱乐部/Source/SharedControl/create_dump/create_dump.vcxproj b/俱乐部/Source/SharedControl/create_dump/create_dump.vcxproj index 6fd53a2..e4efeae 100644 --- a/俱乐部/Source/SharedControl/create_dump/create_dump.vcxproj +++ b/俱乐部/Source/SharedControl/create_dump/create_dump.vcxproj @@ -1,20 +1,20 @@  - - Debug + + Debug_Unicode Win32 - - Debug + + Debug_Unicode x64 - - Release + + Release_Unicode Win32 - - Release + + Release_Unicode x64 @@ -22,27 +22,28 @@ {A24A269E-D5C3-4D96-B5D3-A254D91F617D} Win32Proj create_dump + 10.0 - + DynamicLibrary true v120 Unicode - + DynamicLibrary false v120 true Unicode - + v142 Unicode DynamicLibrary - + v142 DynamicLibrary Unicode @@ -50,28 +51,29 @@ - + - + - + true ..\BIN\Client\X64\Debug\ ..\Obj\Client\X64\Dump\Debug\ $(ProjectName) - + false ..\BIN\Client\X64\Release\ ..\obj\Client\X64\dump\Release\ - + .dll + $(ProjectName)D - + Use Level3 @@ -92,7 +94,7 @@ del "..\LIB\Server\X64\Debug\create_dump.lib" xcopy "..\LIB\Client\X64\Debug\create_dump.lib" "..\LIB\Server\X64\Debug\" - + Level3 Use @@ -116,12 +118,12 @@ del "..\LIB\Server\X64\Release\create_dump.lib" xcopy "..\LIB\Client\X64\Release\create_dump.lib" "..\LIB\Server\X64\Release\" - + CREATE_DUMP_EXPORTS;%(PreprocessorDefinitions) - + CREATE_DUMP_EXPORTS;%(PreprocessorDefinitions) @@ -137,16 +139,16 @@ xcopy "..\LIB\Client\X64\Release\create_dump.lib" "..\LIB\Server\X64\Release\" - false - + false + - false - + false + - Create - Create + Create + Create diff --git a/俱乐部/Source/hiredis/.gitignore b/俱乐部/Source/hiredis/.gitignore new file mode 100644 index 0000000..8e50b54 --- /dev/null +++ b/俱乐部/Source/hiredis/.gitignore @@ -0,0 +1,8 @@ +/hiredis-test +/examples/hiredis-example* +/*.o +/*.so +/*.dylib +/*.a +/*.pc +*.dSYM diff --git a/俱乐部/Source/hiredis/.travis.yml b/俱乐部/Source/hiredis/.travis.yml new file mode 100644 index 0000000..dd8e0e7 --- /dev/null +++ b/俱乐部/Source/hiredis/.travis.yml @@ -0,0 +1,97 @@ +language: c +sudo: false +compiler: + - gcc + - clang + +os: + - linux + - osx + +branches: + only: + - staging + - trying + - master + +before_script: + - if [ "$TRAVIS_OS_NAME" == "osx" ] ; then brew update; brew install redis; fi + +addons: + apt: + packages: + - libc6-dbg + - libc6-dev + - libc6:i386 + - libc6-dev-i386 + - libc6-dbg:i386 + - gcc-multilib + - g++-multilib + - valgrind + +env: + - BITS="32" + - BITS="64" + +script: + - EXTRA_CMAKE_OPTS="-DENABLE_EXAMPLES:BOOL=ON -DHIREDIS_SSL:BOOL=ON"; + if [ "$TRAVIS_OS_NAME" == "osx" ]; then + if [ "$BITS" == "32" ]; then + CFLAGS="-m32 -Werror"; + CXXFLAGS="-m32 -Werror"; + LDFLAGS="-m32"; + EXTRA_CMAKE_OPTS=; + else + CFLAGS="-Werror"; + CXXFLAGS="-Werror"; + fi; + else + TEST_PREFIX="valgrind --track-origins=yes --leak-check=full"; + if [ "$BITS" == "32" ]; then + CFLAGS="-m32 -Werror"; + CXXFLAGS="-m32 -Werror"; + LDFLAGS="-m32"; + EXTRA_CMAKE_OPTS=; + else + CFLAGS="-Werror"; + CXXFLAGS="-Werror"; + fi; + fi; + export CFLAGS CXXFLAGS LDFLAGS TEST_PREFIX EXTRA_CMAKE_OPTS + - mkdir build/ && cd build/ + - cmake .. ${EXTRA_CMAKE_OPTS} + - make VERBOSE=1 + - ctest -V + +matrix: + include: + # Windows MinGW cross compile on Linux + - os: linux + dist: xenial + compiler: mingw + addons: + apt: + packages: + - ninja-build + - gcc-mingw-w64-x86-64 + - g++-mingw-w64-x86-64 + script: + - mkdir build && cd build + - CC=x86_64-w64-mingw32-gcc CXX=x86_64-w64-mingw32-g++ cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_BUILD_WITH_INSTALL_RPATH=on + - ninja -v + + # Windows MSVC 2017 + - os: windows + compiler: msvc + env: + - MATRIX_EVAL="CC=cl.exe && CXX=cl.exe" + before_install: + - eval "${MATRIX_EVAL}" + install: + - choco install ninja + script: + - mkdir build && cd build + - cmd.exe /C '"C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build\vcvarsall.bat" amd64 && + cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Release && + ninja -v' + - ctest -V diff --git a/俱乐部/Source/hiredis/CHANGELOG.md b/俱乐部/Source/hiredis/CHANGELOG.md new file mode 100644 index 0000000..d1d37e5 --- /dev/null +++ b/俱乐部/Source/hiredis/CHANGELOG.md @@ -0,0 +1,199 @@ +### 1.0.0 (unreleased) + +**BREAKING CHANGES**: + +* Bulk and multi-bulk lengths less than -1 or greater than `LLONG_MAX` are now + protocol errors. This is consistent with the RESP specification. On 32-bit + platforms, the upper bound is lowered to `SIZE_MAX`. + +* Change `redisReply.len` to `size_t`, as it denotes the the size of a string + + User code should compare this to `size_t` values as well. If it was used to + compare to other values, casting might be necessary or can be removed, if + casting was applied before. + +### 0.x.x (unreleased) +**BREAKING CHANGES**: + +* Change `redisReply.len` to `size_t`, as it denotes the the size of a string + +User code should compare this to `size_t` values as well. +If it was used to compare to other values, casting might be necessary or can be removed, if casting was applied before. + +* `redisReplyObjectFunctions.createArray` now takes `size_t` for its length parameter. + +### 0.14.0 (2018-09-25) + +* Make string2ll static to fix conflict with Redis (Tom Lee [c3188b]) +* Use -dynamiclib instead of -shared for OSX (Ryan Schmidt [a65537]) +* Use string2ll from Redis w/added tests (Michael Grunder [7bef04, 60f622]) +* Makefile - OSX compilation fixes (Ryan Schmidt [881fcb, 0e9af8]) +* Remove redundant NULL checks (Justin Brewer [54acc8, 58e6b8]) +* Fix bulk and multi-bulk length truncation (Justin Brewer [109197]) +* Fix SIGSEGV in OpenBSD by checking for NULL before calling freeaddrinfo (Justin Brewer [546d94]) +* Several POSIX compatibility fixes (Justin Brewer [bbeab8, 49bbaa, d1c1b6]) +* Makefile - Compatibility fixes (Dimitri Vorobiev [3238cf, 12a9d1]) +* Makefile - Fix make install on FreeBSD (Zach Shipko [a2ef2b]) +* Makefile - don't assume $(INSTALL) is cp (Igor Gnatenko [725a96]) +* Separate side-effect causing function from assert and small cleanup (amallia [b46413, 3c3234]) +* Don't send negative values to `__redisAsyncCommand` (Frederik Deweerdt [706129]) +* Fix leak if setsockopt fails (Frederik Deweerdt [e21c9c]) +* Fix libevent leak (zfz [515228]) +* Clean up GCC warning (Ichito Nagata [2ec774]) +* Keep track of errno in `__redisSetErrorFromErrno()` as snprintf may use it (Jin Qing [25cd88]) +* Solaris compilation fix (Donald Whyte [41b07d]) +* Reorder linker arguments when building examples (Tustfarm-heart [06eedd]) +* Keep track of subscriptions in case of rapid subscribe/unsubscribe (Hyungjin Kim [073dc8, be76c5, d46999]) +* libuv use after free fix (Paul Scott [cbb956]) +* Properly close socket fd on reconnect attempt (WSL [64d1ec]) +* Skip valgrind in OSX tests (Jan-Erik Rediger [9deb78]) +* Various updates for Travis testing OSX (Ted Nyman [fa3774, 16a459, bc0ea5]) +* Update libevent (Chris Xin [386802]) +* Change sds.h for building in C++ projects (Ali Volkan ATLI [f5b32e]) +* Use proper format specifier in redisFormatSdsCommandArgv (Paulino Huerta, Jan-Erik Rediger [360a06, 8655a6]) +* Better handling of NULL reply in example code (Jan-Erik Rediger [1b8ed3]) +* Prevent overflow when formatting an error (Jan-Erik Rediger [0335cb]) +* Compatibility fix for strerror_r (Tom Lee [bb1747]) +* Properly detect integer parse/overflow errors (Justin Brewer [93421f]) +* Adds CI for Windows and cygwin fixes (owent, [6c53d6, 6c3e40]) +* Catch a buffer overflow when formatting the error message +* Import latest upstream sds. This breaks applications that are linked against the old hiredis v0.13 +* Fix warnings, when compiled with -Wshadow +* Make hiredis compile in Cygwin on Windows, now CI-tested +* Bulk and multi-bulk lengths less than -1 or greater than `LLONG_MAX` are now + protocol errors. This is consistent with the RESP specification. On 32-bit + platforms, the upper bound is lowered to `SIZE_MAX`. + +* Remove backwards compatibility macro's + +This removes the following old function aliases, use the new name now: + +| Old | New | +| --------------------------- | ---------------------- | +| redisReplyReaderCreate | redisReaderCreate | +| redisReplyReaderCreate | redisReaderCreate | +| redisReplyReaderFree | redisReaderFree | +| redisReplyReaderFeed | redisReaderFeed | +| redisReplyReaderGetReply | redisReaderGetReply | +| redisReplyReaderSetPrivdata | redisReaderSetPrivdata | +| redisReplyReaderGetObject | redisReaderGetObject | +| redisReplyReaderGetError | redisReaderGetError | + +* The `DEBUG` variable in the Makefile was renamed to `DEBUG_FLAGS` + +Previously it broke some builds for people that had `DEBUG` set to some arbitrary value, +due to debugging other software. +By renaming we avoid unintentional name clashes. + +Simply rename `DEBUG` to `DEBUG_FLAGS` in your environment to make it working again. + +### 0.13.3 (2015-09-16) + +* Revert "Clear `REDIS_CONNECTED` flag when connection is closed". +* Make tests pass on FreeBSD (Thanks, Giacomo Olgeni) + + +If the `REDIS_CONNECTED` flag is cleared, +the async onDisconnect callback function will never be called. +This causes problems as the disconnect is never reported back to the user. + +### 0.13.2 (2015-08-25) + +* Prevent crash on pending replies in async code (Thanks, @switch-st) +* Clear `REDIS_CONNECTED` flag when connection is closed (Thanks, Jerry Jacobs) +* Add MacOS X addapter (Thanks, @dizzus) +* Add Qt adapter (Thanks, Pietro Cerutti) +* Add Ivykis adapter (Thanks, Gergely Nagy) + +All adapters are provided as is and are only tested where possible. + +### 0.13.1 (2015-05-03) + +This is a bug fix release. +The new `reconnect` method introduced new struct members, which clashed with pre-defined names in pre-C99 code. +Another commit forced C99 compilation just to make it work, but of course this is not desirable for outside projects. +Other non-C99 code can now use hiredis as usual again. +Sorry for the inconvenience. + +* Fix memory leak in async reply handling (Salvatore Sanfilippo) +* Rename struct member to avoid name clash with pre-c99 code (Alex Balashov, ncopa) + +### 0.13.0 (2015-04-16) + +This release adds a minimal Windows compatibility layer. +The parser, standalone since v0.12.0, can now be compiled on Windows +(and thus used in other client libraries as well) + +* Windows compatibility layer for parser code (tzickel) +* Properly escape data printed to PKGCONF file (Dan Skorupski) +* Fix tests when assert() undefined (Keith Bennett, Matt Stancliff) +* Implement a reconnect method for the client context, this changes the structure of `redisContext` (Aaron Bedra) + +### 0.12.1 (2015-01-26) + +* Fix `make install`: DESTDIR support, install all required files, install PKGCONF in proper location +* Fix `make test` as 32 bit build on 64 bit platform + +### 0.12.0 (2015-01-22) + +* Add optional KeepAlive support + +* Try again on EINTR errors + +* Add libuv adapter + +* Add IPv6 support + +* Remove possibility of multiple close on same fd + +* Add ability to bind source address on connect + +* Add redisConnectFd() and redisFreeKeepFd() + +* Fix getaddrinfo() memory leak + +* Free string if it is unused (fixes memory leak) + +* Improve redisAppendCommandArgv performance 2.5x + +* Add support for SO_REUSEADDR + +* Fix redisvFormatCommand format parsing + +* Add GLib 2.0 adapter + +* Refactor reading code into read.c + +* Fix errno error buffers to not clobber errors + +* Generate pkgconf during build + +* Silence _BSD_SOURCE warnings + +* Improve digit counting for multibulk creation + + +### 0.11.0 + +* Increase the maximum multi-bulk reply depth to 7. + +* Increase the read buffer size from 2k to 16k. + +* Use poll(2) instead of select(2) to support large fds (>= 1024). + +### 0.10.1 + +* Makefile overhaul. Important to check out if you override one or more + variables using environment variables or via arguments to the "make" tool. + +* Issue #45: Fix potential memory leak for a multi bulk reply with 0 elements + being created by the default reply object functions. + +* Issue #43: Don't crash in an asynchronous context when Redis returns an error + reply after the connection has been made (this happens when the maximum + number of connections is reached). + +### 0.10.0 + +* See commit log. + diff --git a/俱乐部/Source/hiredis/COPYING b/俱乐部/Source/hiredis/COPYING new file mode 100644 index 0000000..a5fc973 --- /dev/null +++ b/俱乐部/Source/hiredis/COPYING @@ -0,0 +1,29 @@ +Copyright (c) 2009-2011, Salvatore Sanfilippo +Copyright (c) 2010-2011, Pieter Noordhuis + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + +* 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. + +* Neither the name of Redis nor the names of its contributors may 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. diff --git a/俱乐部/Source/hiredis/Makefile b/俱乐部/Source/hiredis/Makefile new file mode 100644 index 0000000..2e9f445 --- /dev/null +++ b/俱乐部/Source/hiredis/Makefile @@ -0,0 +1,274 @@ +# Hiredis Makefile +# Copyright (C) 2010-2011 Salvatore Sanfilippo +# Copyright (C) 2010-2011 Pieter Noordhuis +# This file is released under the BSD license, see the COPYING file + +OBJ=net.o hiredis.o sds.o async.o read.o sockcompat.o alloc.o +SSL_OBJ=ssl.o +EXAMPLES=hiredis-example hiredis-example-libevent hiredis-example-libev hiredis-example-glib +ifeq ($(USE_SSL),1) +EXAMPLES+=hiredis-example-ssl hiredis-example-libevent-ssl +endif +TESTS=hiredis-test +LIBNAME=libhiredis +SSL_LIBNAME=libhiredis_ssl +PKGCONFNAME=hiredis.pc +SSL_PKGCONFNAME=hiredis_ssl.pc + +HIREDIS_MAJOR=$(shell grep HIREDIS_MAJOR hiredis.h | awk '{print $$3}') +HIREDIS_MINOR=$(shell grep HIREDIS_MINOR hiredis.h | awk '{print $$3}') +HIREDIS_PATCH=$(shell grep HIREDIS_PATCH hiredis.h | awk '{print $$3}') +HIREDIS_SONAME=$(shell grep HIREDIS_SONAME hiredis.h | awk '{print $$3}') + +# Installation related variables and target +PREFIX?=/usr/local +INCLUDE_PATH?=include/hiredis +LIBRARY_PATH?=lib +PKGCONF_PATH?=pkgconfig +INSTALL_INCLUDE_PATH= $(DESTDIR)$(PREFIX)/$(INCLUDE_PATH) +INSTALL_LIBRARY_PATH= $(DESTDIR)$(PREFIX)/$(LIBRARY_PATH) +INSTALL_PKGCONF_PATH= $(INSTALL_LIBRARY_PATH)/$(PKGCONF_PATH) + +# redis-server configuration used for testing +REDIS_PORT=56379 +REDIS_SERVER=redis-server +define REDIS_TEST_CONFIG + daemonize yes + pidfile /tmp/hiredis-test-redis.pid + port $(REDIS_PORT) + bind 127.0.0.1 + unixsocket /tmp/hiredis-test-redis.sock +endef +export REDIS_TEST_CONFIG + +# Fallback to gcc when $CC is not in $PATH. +CC:=$(shell sh -c 'type $${CC%% *} >/dev/null 2>/dev/null && echo $(CC) || echo gcc') +CXX:=$(shell sh -c 'type $${CXX%% *} >/dev/null 2>/dev/null && echo $(CXX) || echo g++') +OPTIMIZATION?=-O3 +WARNINGS=-Wall -W -Wstrict-prototypes -Wwrite-strings -Wno-missing-field-initializers +DEBUG_FLAGS?= -g -ggdb +REAL_CFLAGS=$(OPTIMIZATION) -fPIC $(CPPFLAGS) $(CFLAGS) $(WARNINGS) $(DEBUG_FLAGS) +REAL_LDFLAGS=$(LDFLAGS) + +DYLIBSUFFIX=so +STLIBSUFFIX=a +DYLIB_MINOR_NAME=$(LIBNAME).$(DYLIBSUFFIX).$(HIREDIS_SONAME) +DYLIB_MAJOR_NAME=$(LIBNAME).$(DYLIBSUFFIX).$(HIREDIS_MAJOR) +DYLIBNAME=$(LIBNAME).$(DYLIBSUFFIX) +SSL_DYLIBNAME=$(SSL_LIBNAME).$(DYLIBSUFFIX) +DYLIB_MAKE_CMD=$(CC) -shared -Wl,-soname,$(DYLIB_MINOR_NAME) +STLIBNAME=$(LIBNAME).$(STLIBSUFFIX) +SSL_STLIBNAME=$(SSL_LIBNAME).$(STLIBSUFFIX) +STLIB_MAKE_CMD=$(AR) rcs + +# Platform-specific overrides +uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not') + +USE_SSL?=0 + +# This is required for test.c only +ifeq ($(USE_SSL),1) + CFLAGS+=-DHIREDIS_TEST_SSL +endif + +ifeq ($(uname_S),Linux) + SSL_LDFLAGS=-lssl -lcrypto +else + OPENSSL_PREFIX?=/usr/local/opt/openssl + CFLAGS+=-I$(OPENSSL_PREFIX)/include + SSL_LDFLAGS+=-L$(OPENSSL_PREFIX)/lib -lssl -lcrypto +endif + +ifeq ($(uname_S),SunOS) + REAL_LDFLAGS+= -ldl -lnsl -lsocket + DYLIB_MAKE_CMD=$(CC) -G -o $(DYLIBNAME) -h $(DYLIB_MINOR_NAME) $(LDFLAGS) +endif +ifeq ($(uname_S),Darwin) + DYLIBSUFFIX=dylib + DYLIB_MINOR_NAME=$(LIBNAME).$(HIREDIS_SONAME).$(DYLIBSUFFIX) + DYLIB_MAKE_CMD=$(CC) -dynamiclib -Wl,-install_name,$(PREFIX)/$(LIBRARY_PATH)/$(DYLIB_MINOR_NAME) -o $(DYLIBNAME) $(LDFLAGS) +endif + +all: $(DYLIBNAME) $(STLIBNAME) hiredis-test $(PKGCONFNAME) +ifeq ($(USE_SSL),1) +all: $(SSL_DYLIBNAME) $(SSL_STLIBNAME) $(SSL_PKGCONFNAME) +endif + +# Deps (use make dep to generate this) +async.o: async.c fmacros.h alloc.h async.h hiredis.h read.h sds.h net.h dict.c dict.h win32.h async_private.h +dict.o: dict.c fmacros.h alloc.h dict.h +hiredis.o: hiredis.c fmacros.h hiredis.h read.h sds.h alloc.h net.h async.h win32.h +alloc.o: alloc.c alloc.h +net.o: net.c fmacros.h net.h hiredis.h read.h sds.h alloc.h sockcompat.h win32.h +read.o: read.c fmacros.h read.h sds.h win32.h +sds.o: sds.c sds.h sdsalloc.h +sockcompat.o: sockcompat.c sockcompat.h +ssl.o: ssl.c hiredis.h read.h sds.h alloc.h async.h async_private.h +test.o: test.c fmacros.h hiredis.h read.h sds.h alloc.h net.h + +$(DYLIBNAME): $(OBJ) + $(DYLIB_MAKE_CMD) -o $(DYLIBNAME) $(OBJ) $(REAL_LDFLAGS) + +$(STLIBNAME): $(OBJ) + $(STLIB_MAKE_CMD) $(STLIBNAME) $(OBJ) + +$(SSL_DYLIBNAME): $(SSL_OBJ) + $(DYLIB_MAKE_CMD) -o $(SSL_DYLIBNAME) $(SSL_OBJ) $(REAL_LDFLAGS) $(SSL_LDFLAGS) + +$(SSL_STLIBNAME): $(SSL_OBJ) + $(STLIB_MAKE_CMD) $(SSL_STLIBNAME) $(SSL_OBJ) + +dynamic: $(DYLIBNAME) +static: $(STLIBNAME) +ifeq ($(USE_SSL),1) +dynamic: $(SSL_DYLIBNAME) +static: $(SSL_STLIBNAME) +endif + +# Binaries: +hiredis-example-libevent: examples/example-libevent.c adapters/libevent.h $(STLIBNAME) + $(CC) -o examples/$@ $(REAL_CFLAGS) -I. $< -levent $(STLIBNAME) $(REAL_LDFLAGS) + +hiredis-example-libevent-ssl: examples/example-libevent-ssl.c adapters/libevent.h $(STLIBNAME) $(SSL_STLIBNAME) + $(CC) -o examples/$@ $(REAL_CFLAGS) -I. $< -levent $(STLIBNAME) $(SSL_STLIBNAME) $(REAL_LDFLAGS) $(SSL_LDFLAGS) + +hiredis-example-libev: examples/example-libev.c adapters/libev.h $(STLIBNAME) + $(CC) -o examples/$@ $(REAL_CFLAGS) -I. $< -lev $(STLIBNAME) $(REAL_LDFLAGS) + +hiredis-example-glib: examples/example-glib.c adapters/glib.h $(STLIBNAME) + $(CC) -o examples/$@ $(REAL_CFLAGS) -I. $< $(shell pkg-config --cflags --libs glib-2.0) $(STLIBNAME) $(REAL_LDFLAGS) + +hiredis-example-ivykis: examples/example-ivykis.c adapters/ivykis.h $(STLIBNAME) + $(CC) -o examples/$@ $(REAL_CFLAGS) -I. $< -livykis $(STLIBNAME) $(REAL_LDFLAGS) + +hiredis-example-macosx: examples/example-macosx.c adapters/macosx.h $(STLIBNAME) + $(CC) -o examples/$@ $(REAL_CFLAGS) -I. $< -framework CoreFoundation $(STLIBNAME) $(REAL_LDFLAGS) + +hiredis-example-ssl: examples/example-ssl.c $(STLIBNAME) $(SSL_STLIBNAME) + $(CC) -o examples/$@ $(REAL_CFLAGS) -I. $< $(STLIBNAME) $(SSL_STLIBNAME) $(REAL_LDFLAGS) $(SSL_LDFLAGS) + +ifndef AE_DIR +hiredis-example-ae: + @echo "Please specify AE_DIR (e.g. /src)" + @false +else +hiredis-example-ae: examples/example-ae.c adapters/ae.h $(STLIBNAME) + $(CC) -o examples/$@ $(REAL_CFLAGS) $(REAL_LDFLAGS) -I. -I$(AE_DIR) $< $(AE_DIR)/ae.o $(AE_DIR)/zmalloc.o $(AE_DIR)/../deps/jemalloc/lib/libjemalloc.a -pthread $(STLIBNAME) +endif + +ifndef LIBUV_DIR +hiredis-example-libuv: + @echo "Please specify LIBUV_DIR (e.g. ../libuv/)" + @false +else +hiredis-example-libuv: examples/example-libuv.c adapters/libuv.h $(STLIBNAME) + $(CC) -o examples/$@ $(REAL_CFLAGS) -I. -I$(LIBUV_DIR)/include $< $(LIBUV_DIR)/.libs/libuv.a -lpthread -lrt $(STLIBNAME) $(REAL_LDFLAGS) +endif + +ifeq ($(and $(QT_MOC),$(QT_INCLUDE_DIR),$(QT_LIBRARY_DIR)),) +hiredis-example-qt: + @echo "Please specify QT_MOC, QT_INCLUDE_DIR AND QT_LIBRARY_DIR" + @false +else +hiredis-example-qt: examples/example-qt.cpp adapters/qt.h $(STLIBNAME) + $(QT_MOC) adapters/qt.h -I. -I$(QT_INCLUDE_DIR) -I$(QT_INCLUDE_DIR)/QtCore | \ + $(CXX) -x c++ -o qt-adapter-moc.o -c - $(REAL_CFLAGS) -I. -I$(QT_INCLUDE_DIR) -I$(QT_INCLUDE_DIR)/QtCore + $(QT_MOC) examples/example-qt.h -I. -I$(QT_INCLUDE_DIR) -I$(QT_INCLUDE_DIR)/QtCore | \ + $(CXX) -x c++ -o qt-example-moc.o -c - $(REAL_CFLAGS) -I. -I$(QT_INCLUDE_DIR) -I$(QT_INCLUDE_DIR)/QtCore + $(CXX) -o examples/$@ $(REAL_CFLAGS) $(REAL_LDFLAGS) -I. -I$(QT_INCLUDE_DIR) -I$(QT_INCLUDE_DIR)/QtCore -L$(QT_LIBRARY_DIR) qt-adapter-moc.o qt-example-moc.o $< -pthread $(STLIBNAME) -lQtCore +endif + +hiredis-example: examples/example.c $(STLIBNAME) + $(CC) -o examples/$@ $(REAL_CFLAGS) -I. $< $(STLIBNAME) $(REAL_LDFLAGS) + +examples: $(EXAMPLES) + +TEST_LIBS = $(STLIBNAME) +ifeq ($(USE_SSL),1) + TEST_LIBS += $(SSL_STLIBNAME) -lssl -lcrypto -lpthread +endif +hiredis-test: test.o $(TEST_LIBS) + +hiredis-%: %.o $(STLIBNAME) + $(CC) $(REAL_CFLAGS) -o $@ $< $(TEST_LIBS) $(REAL_LDFLAGS) + +test: hiredis-test + ./hiredis-test + +check: hiredis-test + TEST_SSL=$(USE_SSL) ./test.sh + +.c.o: + $(CC) -std=c99 -pedantic -c $(REAL_CFLAGS) $< + +clean: + rm -rf $(DYLIBNAME) $(STLIBNAME) $(SSL_DYLIBNAME) $(SSL_STLIBNAME) $(TESTS) $(PKGCONFNAME) examples/hiredis-example* *.o *.gcda *.gcno *.gcov + +dep: + $(CC) $(CPPFLAGS) $(CFLAGS) -MM *.c + +INSTALL?= cp -pPR + +$(PKGCONFNAME): hiredis.h + @echo "Generating $@ for pkgconfig..." + @echo prefix=$(PREFIX) > $@ + @echo exec_prefix=\$${prefix} >> $@ + @echo libdir=$(PREFIX)/$(LIBRARY_PATH) >> $@ + @echo includedir=$(PREFIX)/$(INCLUDE_PATH) >> $@ + @echo >> $@ + @echo Name: hiredis >> $@ + @echo Description: Minimalistic C client library for Redis. >> $@ + @echo Version: $(HIREDIS_MAJOR).$(HIREDIS_MINOR).$(HIREDIS_PATCH) >> $@ + @echo Libs: -L\$${libdir} -lhiredis >> $@ + @echo Cflags: -I\$${includedir} -D_FILE_OFFSET_BITS=64 >> $@ + +$(SSL_PKGCONFNAME): hiredis.h + @echo "Generating $@ for pkgconfig..." + @echo prefix=$(PREFIX) > $@ + @echo exec_prefix=\$${prefix} >> $@ + @echo libdir=$(PREFIX)/$(LIBRARY_PATH) >> $@ + @echo includedir=$(PREFIX)/$(INCLUDE_PATH) >> $@ + @echo >> $@ + @echo Name: hiredis_ssl >> $@ + @echo Description: SSL Support for hiredis. >> $@ + @echo Version: $(HIREDIS_MAJOR).$(HIREDIS_MINOR).$(HIREDIS_PATCH) >> $@ + @echo Requires: hiredis >> $@ + @echo Libs: -L\$${libdir} -lhiredis_ssl >> $@ + @echo Libs.private: -lssl -lcrypto >> $@ + +install: $(DYLIBNAME) $(STLIBNAME) $(PKGCONFNAME) + mkdir -p $(INSTALL_INCLUDE_PATH) $(INSTALL_INCLUDE_PATH)/adapters $(INSTALL_LIBRARY_PATH) + $(INSTALL) hiredis.h async.h read.h sds.h alloc.h $(INSTALL_INCLUDE_PATH) + $(INSTALL) adapters/*.h $(INSTALL_INCLUDE_PATH)/adapters + $(INSTALL) $(DYLIBNAME) $(INSTALL_LIBRARY_PATH)/$(DYLIB_MINOR_NAME) + cd $(INSTALL_LIBRARY_PATH) && ln -sf $(DYLIB_MINOR_NAME) $(DYLIBNAME) + $(INSTALL) $(STLIBNAME) $(INSTALL_LIBRARY_PATH) + mkdir -p $(INSTALL_PKGCONF_PATH) + $(INSTALL) $(PKGCONFNAME) $(INSTALL_PKGCONF_PATH) + +32bit: + @echo "" + @echo "WARNING: if this fails under Linux you probably need to install libc6-dev-i386" + @echo "" + $(MAKE) CFLAGS="-m32" LDFLAGS="-m32" + +32bit-vars: + $(eval CFLAGS=-m32) + $(eval LDFLAGS=-m32) + +gprof: + $(MAKE) CFLAGS="-pg" LDFLAGS="-pg" + +gcov: + $(MAKE) CFLAGS="-fprofile-arcs -ftest-coverage" LDFLAGS="-fprofile-arcs" + +coverage: gcov + make check + mkdir -p tmp/lcov + lcov -d . -c -o tmp/lcov/hiredis.info + genhtml --legend -o tmp/lcov/report tmp/lcov/hiredis.info + +noopt: + $(MAKE) OPTIMIZATION="" + +.PHONY: all test check clean dep install 32bit 32bit-vars gprof gcov noopt diff --git a/俱乐部/Source/hiredis/README.md b/俱乐部/Source/hiredis/README.md new file mode 100644 index 0000000..6095cec --- /dev/null +++ b/俱乐部/Source/hiredis/README.md @@ -0,0 +1,470 @@ +[![Build Status](https://travis-ci.org/redis/hiredis.png)](https://travis-ci.org/redis/hiredis) + +**This Readme reflects the latest changed in the master branch. See [v0.13.3](https://github.com/redis/hiredis/tree/v0.13.3) for the Readme and documentation for the latest release.** + +# HIREDIS + +Hiredis is a minimalistic C client library for the [Redis](http://redis.io/) database. + +It is minimalistic because it just adds minimal support for the protocol, but +at the same time it uses a high level printf-alike API in order to make it +much higher level than otherwise suggested by its minimal code base and the +lack of explicit bindings for every Redis command. + +Apart from supporting sending commands and receiving replies, it comes with +a reply parser that is decoupled from the I/O layer. It +is a stream parser designed for easy reusability, which can for instance be used +in higher level language bindings for efficient reply parsing. + +Hiredis only supports the binary-safe Redis protocol, so you can use it with any +Redis version >= 1.2.0. + +The library comes with multiple APIs. There is the +*synchronous API*, the *asynchronous API* and the *reply parsing API*. + +## Upgrading to `1.0.0` + +Version 1.0.0 marks a stable release of hiredis. +It includes some minor breaking changes, mostly to make the exposed API more uniform and self-explanatory. +It also bundles the updated `sds` library, to sync up with upstream and Redis. +For most applications a recompile against the new hiredis should be enough. +For code changes see the [Changelog](CHANGELOG.md). + +## Upgrading from `<0.9.0` + +Version 0.9.0 is a major overhaul of hiredis in every aspect. However, upgrading existing +code using hiredis should not be a big pain. The key thing to keep in mind when +upgrading is that hiredis >= 0.9.0 uses a `redisContext*` to keep state, in contrast to +the stateless 0.0.1 that only has a file descriptor to work with. + +## Synchronous API + +To consume the synchronous API, there are only a few function calls that need to be introduced: + +```c +redisContext *redisConnect(const char *ip, int port); +void *redisCommand(redisContext *c, const char *format, ...); +void freeReplyObject(void *reply); +``` + +### Connecting + +The function `redisConnect` is used to create a so-called `redisContext`. The +context is where Hiredis holds state for a connection. The `redisContext` +struct has an integer `err` field that is non-zero when the connection is in +an error state. The field `errstr` will contain a string with a description of +the error. More information on errors can be found in the **Errors** section. +After trying to connect to Redis using `redisConnect` you should +check the `err` field to see if establishing the connection was successful: +```c +redisContext *c = redisConnect("127.0.0.1", 6379); +if (c == NULL || c->err) { + if (c) { + printf("Error: %s\n", c->errstr); + // handle error + } else { + printf("Can't allocate redis context\n"); + } +} +``` + +*Note: A `redisContext` is not thread-safe.* + +### Sending commands + +There are several ways to issue commands to Redis. The first that will be introduced is +`redisCommand`. This function takes a format similar to printf. In the simplest form, +it is used like this: +```c +reply = redisCommand(context, "SET foo bar"); +``` + +The specifier `%s` interpolates a string in the command, and uses `strlen` to +determine the length of the string: +```c +reply = redisCommand(context, "SET foo %s", value); +``` +When you need to pass binary safe strings in a command, the `%b` specifier can be +used. Together with a pointer to the string, it requires a `size_t` length argument +of the string: +```c +reply = redisCommand(context, "SET foo %b", value, (size_t) valuelen); +``` +Internally, Hiredis splits the command in different arguments and will +convert it to the protocol used to communicate with Redis. +One or more spaces separates arguments, so you can use the specifiers +anywhere in an argument: +```c +reply = redisCommand(context, "SET key:%s %s", myid, value); +``` + +### Using replies + +The return value of `redisCommand` holds a reply when the command was +successfully executed. When an error occurs, the return value is `NULL` and +the `err` field in the context will be set (see section on **Errors**). +Once an error is returned the context cannot be reused and you should set up +a new connection. + +The standard replies that `redisCommand` are of the type `redisReply`. The +`type` field in the `redisReply` should be used to test what kind of reply +was received: + +* **`REDIS_REPLY_STATUS`**: + * The command replied with a status reply. The status string can be accessed using `reply->str`. + The length of this string can be accessed using `reply->len`. + +* **`REDIS_REPLY_ERROR`**: + * The command replied with an error. The error string can be accessed identical to `REDIS_REPLY_STATUS`. + +* **`REDIS_REPLY_INTEGER`**: + * The command replied with an integer. The integer value can be accessed using the + `reply->integer` field of type `long long`. + +* **`REDIS_REPLY_NIL`**: + * The command replied with a **nil** object. There is no data to access. + +* **`REDIS_REPLY_STRING`**: + * A bulk (string) reply. The value of the reply can be accessed using `reply->str`. + The length of this string can be accessed using `reply->len`. + +* **`REDIS_REPLY_ARRAY`**: + * A multi bulk reply. The number of elements in the multi bulk reply is stored in + `reply->elements`. Every element in the multi bulk reply is a `redisReply` object as well + and can be accessed via `reply->element[..index..]`. + Redis may reply with nested arrays but this is fully supported. + +Replies should be freed using the `freeReplyObject()` function. +Note that this function will take care of freeing sub-reply objects +contained in arrays and nested arrays, so there is no need for the user to +free the sub replies (it is actually harmful and will corrupt the memory). + +**Important:** the current version of hiredis (0.10.0) frees replies when the +asynchronous API is used. This means you should not call `freeReplyObject` when +you use this API. The reply is cleaned up by hiredis _after_ the callback +returns. This behavior will probably change in future releases, so make sure to +keep an eye on the changelog when upgrading (see issue #39). + +### Cleaning up + +To disconnect and free the context the following function can be used: +```c +void redisFree(redisContext *c); +``` +This function immediately closes the socket and then frees the allocations done in +creating the context. + +### Sending commands (cont'd) + +Together with `redisCommand`, the function `redisCommandArgv` can be used to issue commands. +It has the following prototype: +```c +void *redisCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen); +``` +It takes the number of arguments `argc`, an array of strings `argv` and the lengths of the +arguments `argvlen`. For convenience, `argvlen` may be set to `NULL` and the function will +use `strlen(3)` on every argument to determine its length. Obviously, when any of the arguments +need to be binary safe, the entire array of lengths `argvlen` should be provided. + +The return value has the same semantic as `redisCommand`. + +### Pipelining + +To explain how Hiredis supports pipelining in a blocking connection, there needs to be +understanding of the internal execution flow. + +When any of the functions in the `redisCommand` family is called, Hiredis first formats the +command according to the Redis protocol. The formatted command is then put in the output buffer +of the context. This output buffer is dynamic, so it can hold any number of commands. +After the command is put in the output buffer, `redisGetReply` is called. This function has the +following two execution paths: + +1. The input buffer is non-empty: + * Try to parse a single reply from the input buffer and return it + * If no reply could be parsed, continue at *2* +2. The input buffer is empty: + * Write the **entire** output buffer to the socket + * Read from the socket until a single reply could be parsed + +The function `redisGetReply` is exported as part of the Hiredis API and can be used when a reply +is expected on the socket. To pipeline commands, the only things that needs to be done is +filling up the output buffer. For this cause, two commands can be used that are identical +to the `redisCommand` family, apart from not returning a reply: +```c +void redisAppendCommand(redisContext *c, const char *format, ...); +void redisAppendCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen); +``` +After calling either function one or more times, `redisGetReply` can be used to receive the +subsequent replies. The return value for this function is either `REDIS_OK` or `REDIS_ERR`, where +the latter means an error occurred while reading a reply. Just as with the other commands, +the `err` field in the context can be used to find out what the cause of this error is. + +The following examples shows a simple pipeline (resulting in only a single call to `write(2)` and +a single call to `read(2)`): +```c +redisReply *reply; +redisAppendCommand(context,"SET foo bar"); +redisAppendCommand(context,"GET foo"); +redisGetReply(context,&reply); // reply for SET +freeReplyObject(reply); +redisGetReply(context,&reply); // reply for GET +freeReplyObject(reply); +``` +This API can also be used to implement a blocking subscriber: +```c +reply = redisCommand(context,"SUBSCRIBE foo"); +freeReplyObject(reply); +while(redisGetReply(context,&reply) == REDIS_OK) { + // consume message + freeReplyObject(reply); +} +``` +### Errors + +When a function call is not successful, depending on the function either `NULL` or `REDIS_ERR` is +returned. The `err` field inside the context will be non-zero and set to one of the +following constants: + +* **`REDIS_ERR_IO`**: + There was an I/O error while creating the connection, trying to write + to the socket or read from the socket. If you included `errno.h` in your + application, you can use the global `errno` variable to find out what is + wrong. + +* **`REDIS_ERR_EOF`**: + The server closed the connection which resulted in an empty read. + +* **`REDIS_ERR_PROTOCOL`**: + There was an error while parsing the protocol. + +* **`REDIS_ERR_OTHER`**: + Any other error. Currently, it is only used when a specified hostname to connect + to cannot be resolved. + +In every case, the `errstr` field in the context will be set to hold a string representation +of the error. + +## Asynchronous API + +Hiredis comes with an asynchronous API that works easily with any event library. +Examples are bundled that show using Hiredis with [libev](http://software.schmorp.de/pkg/libev.html) +and [libevent](http://monkey.org/~provos/libevent/). + +### Connecting + +The function `redisAsyncConnect` can be used to establish a non-blocking connection to +Redis. It returns a pointer to the newly created `redisAsyncContext` struct. The `err` field +should be checked after creation to see if there were errors creating the connection. +Because the connection that will be created is non-blocking, the kernel is not able to +instantly return if the specified host and port is able to accept a connection. + +*Note: A `redisAsyncContext` is not thread-safe.* + +```c +redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379); +if (c->err) { + printf("Error: %s\n", c->errstr); + // handle error +} +``` + +The asynchronous context can hold a disconnect callback function that is called when the +connection is disconnected (either because of an error or per user request). This function should +have the following prototype: +```c +void(const redisAsyncContext *c, int status); +``` +On a disconnect, the `status` argument is set to `REDIS_OK` when disconnection was initiated by the +user, or `REDIS_ERR` when the disconnection was caused by an error. When it is `REDIS_ERR`, the `err` +field in the context can be accessed to find out the cause of the error. + +The context object is always freed after the disconnect callback fired. When a reconnect is needed, +the disconnect callback is a good point to do so. + +Setting the disconnect callback can only be done once per context. For subsequent calls it will +return `REDIS_ERR`. The function to set the disconnect callback has the following prototype: +```c +int redisAsyncSetDisconnectCallback(redisAsyncContext *ac, redisDisconnectCallback *fn); +``` +`ac->data` may be used to pass user data to this callback, the same can be done for redisConnectCallback. +### Sending commands and their callbacks + +In an asynchronous context, commands are automatically pipelined due to the nature of an event loop. +Therefore, unlike the synchronous API, there is only a single way to send commands. +Because commands are sent to Redis asynchronously, issuing a command requires a callback function +that is called when the reply is received. Reply callbacks should have the following prototype: +```c +void(redisAsyncContext *c, void *reply, void *privdata); +``` +The `privdata` argument can be used to curry arbitrary data to the callback from the point where +the command is initially queued for execution. + +The functions that can be used to issue commands in an asynchronous context are: +```c +int redisAsyncCommand( + redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, + const char *format, ...); +int redisAsyncCommandArgv( + redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, + int argc, const char **argv, const size_t *argvlen); +``` +Both functions work like their blocking counterparts. The return value is `REDIS_OK` when the command +was successfully added to the output buffer and `REDIS_ERR` otherwise. Example: when the connection +is being disconnected per user-request, no new commands may be added to the output buffer and `REDIS_ERR` is +returned on calls to the `redisAsyncCommand` family. + +If the reply for a command with a `NULL` callback is read, it is immediately freed. When the callback +for a command is non-`NULL`, the memory is freed immediately following the callback: the reply is only +valid for the duration of the callback. + +All pending callbacks are called with a `NULL` reply when the context encountered an error. + +### Disconnecting + +An asynchronous connection can be terminated using: +```c +void redisAsyncDisconnect(redisAsyncContext *ac); +``` +When this function is called, the connection is **not** immediately terminated. Instead, new +commands are no longer accepted and the connection is only terminated when all pending commands +have been written to the socket, their respective replies have been read and their respective +callbacks have been executed. After this, the disconnection callback is executed with the +`REDIS_OK` status and the context object is freed. + +### Hooking it up to event library *X* + +There are a few hooks that need to be set on the context object after it is created. +See the `adapters/` directory for bindings to *libev* and *libevent*. + +## Reply parsing API + +Hiredis comes with a reply parsing API that makes it easy for writing higher +level language bindings. + +The reply parsing API consists of the following functions: +```c +redisReader *redisReaderCreate(void); +void redisReaderFree(redisReader *reader); +int redisReaderFeed(redisReader *reader, const char *buf, size_t len); +int redisReaderGetReply(redisReader *reader, void **reply); +``` +The same set of functions are used internally by hiredis when creating a +normal Redis context, the above API just exposes it to the user for a direct +usage. + +### Usage + +The function `redisReaderCreate` creates a `redisReader` structure that holds a +buffer with unparsed data and state for the protocol parser. + +Incoming data -- most likely from a socket -- can be placed in the internal +buffer of the `redisReader` using `redisReaderFeed`. This function will make a +copy of the buffer pointed to by `buf` for `len` bytes. This data is parsed +when `redisReaderGetReply` is called. This function returns an integer status +and a reply object (as described above) via `void **reply`. The returned status +can be either `REDIS_OK` or `REDIS_ERR`, where the latter means something went +wrong (either a protocol error, or an out of memory error). + +The parser limits the level of nesting for multi bulk payloads to 7. If the +multi bulk nesting level is higher than this, the parser returns an error. + +### Customizing replies + +The function `redisReaderGetReply` creates `redisReply` and makes the function +argument `reply` point to the created `redisReply` variable. For instance, if +the response of type `REDIS_REPLY_STATUS` then the `str` field of `redisReply` +will hold the status as a vanilla C string. However, the functions that are +responsible for creating instances of the `redisReply` can be customized by +setting the `fn` field on the `redisReader` struct. This should be done +immediately after creating the `redisReader`. + +For example, [hiredis-rb](https://github.com/pietern/hiredis-rb/blob/master/ext/hiredis_ext/reader.c) +uses customized reply object functions to create Ruby objects. + +### Reader max buffer + +Both when using the Reader API directly or when using it indirectly via a +normal Redis context, the redisReader structure uses a buffer in order to +accumulate data from the server. +Usually this buffer is destroyed when it is empty and is larger than 16 +KiB in order to avoid wasting memory in unused buffers + +However when working with very big payloads destroying the buffer may slow +down performances considerably, so it is possible to modify the max size of +an idle buffer changing the value of the `maxbuf` field of the reader structure +to the desired value. The special value of 0 means that there is no maximum +value for an idle buffer, so the buffer will never get freed. + +For instance if you have a normal Redis context you can set the maximum idle +buffer to zero (unlimited) just with: +```c +context->reader->maxbuf = 0; +``` +This should be done only in order to maximize performances when working with +large payloads. The context should be set back to `REDIS_READER_MAX_BUF` again +as soon as possible in order to prevent allocation of useless memory. + +## SSL/TLS Support + +### Building + +SSL/TLS support is not built by default and requires an explicit flag: + + make USE_SSL=1 + +This requires OpenSSL development package (e.g. including header files to be +available. + +When enabled, SSL/TLS support is built into extra `libhiredis_ssl.a` and +`libhiredis_ssl.so` static/dynamic libraries. This leaves the original libraries +unaffected so no additional dependencies are introduced. + +### Using it + +First, you'll need to make sure you include the SSL header file: + +```c +#include "hiredis.h" +#include "hiredis_ssl.h" +``` + +SSL can only be enabled on a `redisContext` connection after the connection has +been established and before any command has been processed. For example: + +```c +c = redisConnect('localhost', 6443); +if (c == NULL || c->err) { + /* Handle error and abort... */ +} + +if (redisSecureConnection(c, + "cacertbundle.crt", /* File name of trusted CA/ca bundle file */ + "client_cert.pem", /* File name of client certificate file */ + "client_key.pem", /* File name of client privat ekey */ + "redis.mydomain.com" /* Server name to request (SNI) */ + ) != REDIS_OK) { + printf("SSL error: %s\n", c->errstr); + /* Abort... */ +} +``` + +You will also need to link against `libhiredis_ssl`, **in addition** to +`libhiredis` and add `-lssl -lcrypto` to satisfy its dependencies. + +### OpenSSL Global State Initialization + +OpenSSL needs to have certain global state initialized before it can be used. +Using `redisSecureConnection()` will handle this automatically on the first +call. + +**If the calling application itself also initializes and uses OpenSSL directly, +`redisSecureConnection()` must not be used.** + +Instead, use `redisInitiateSSL()` which also provides greater control over the +configuration of the SSL connection, as the caller is responsible to create a +connection context using `SSL_new()` and configure it as required. + +## AUTHORS + +Hiredis was written by Salvatore Sanfilippo (antirez at gmail) and +Pieter Noordhuis (pcnoordhuis at gmail) and is released under the BSD license. diff --git a/俱乐部/Source/hiredis/adapters/ae.h b/俱乐部/Source/hiredis/adapters/ae.h new file mode 100644 index 0000000..0393992 --- /dev/null +++ b/俱乐部/Source/hiredis/adapters/ae.h @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2010-2011, Pieter Noordhuis + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Redis nor the names of its contributors may 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. + */ + +#ifndef __HIREDIS_AE_H__ +#define __HIREDIS_AE_H__ +#include +#include +#include "../hiredis.h" +#include "../async.h" + +typedef struct redisAeEvents { + redisAsyncContext *context; + aeEventLoop *loop; + int fd; + int reading, writing; +} redisAeEvents; + +static void redisAeReadEvent(aeEventLoop *el, int fd, void *privdata, int mask) { + ((void)el); ((void)fd); ((void)mask); + + redisAeEvents *e = (redisAeEvents*)privdata; + redisAsyncHandleRead(e->context); +} + +static void redisAeWriteEvent(aeEventLoop *el, int fd, void *privdata, int mask) { + ((void)el); ((void)fd); ((void)mask); + + redisAeEvents *e = (redisAeEvents*)privdata; + redisAsyncHandleWrite(e->context); +} + +static void redisAeAddRead(void *privdata) { + redisAeEvents *e = (redisAeEvents*)privdata; + aeEventLoop *loop = e->loop; + if (!e->reading) { + e->reading = 1; + aeCreateFileEvent(loop,e->fd,AE_READABLE,redisAeReadEvent,e); + } +} + +static void redisAeDelRead(void *privdata) { + redisAeEvents *e = (redisAeEvents*)privdata; + aeEventLoop *loop = e->loop; + if (e->reading) { + e->reading = 0; + aeDeleteFileEvent(loop,e->fd,AE_READABLE); + } +} + +static void redisAeAddWrite(void *privdata) { + redisAeEvents *e = (redisAeEvents*)privdata; + aeEventLoop *loop = e->loop; + if (!e->writing) { + e->writing = 1; + aeCreateFileEvent(loop,e->fd,AE_WRITABLE,redisAeWriteEvent,e); + } +} + +static void redisAeDelWrite(void *privdata) { + redisAeEvents *e = (redisAeEvents*)privdata; + aeEventLoop *loop = e->loop; + if (e->writing) { + e->writing = 0; + aeDeleteFileEvent(loop,e->fd,AE_WRITABLE); + } +} + +static void redisAeCleanup(void *privdata) { + redisAeEvents *e = (redisAeEvents*)privdata; + redisAeDelRead(privdata); + redisAeDelWrite(privdata); + free(e); +} + +static int redisAeAttach(aeEventLoop *loop, redisAsyncContext *ac) { + redisContext *c = &(ac->c); + redisAeEvents *e; + + /* Nothing should be attached when something is already attached */ + if (ac->ev.data != NULL) + return REDIS_ERR; + + /* Create container for context and r/w events */ + e = (redisAeEvents*)hi_malloc(sizeof(*e)); + e->context = ac; + e->loop = loop; + e->fd = c->fd; + e->reading = e->writing = 0; + + /* Register functions to start/stop listening for events */ + ac->ev.addRead = redisAeAddRead; + ac->ev.delRead = redisAeDelRead; + ac->ev.addWrite = redisAeAddWrite; + ac->ev.delWrite = redisAeDelWrite; + ac->ev.cleanup = redisAeCleanup; + ac->ev.data = e; + + return REDIS_OK; +} +#endif diff --git a/俱乐部/Source/hiredis/adapters/glib.h b/俱乐部/Source/hiredis/adapters/glib.h new file mode 100644 index 0000000..e0a6411 --- /dev/null +++ b/俱乐部/Source/hiredis/adapters/glib.h @@ -0,0 +1,153 @@ +#ifndef __HIREDIS_GLIB_H__ +#define __HIREDIS_GLIB_H__ + +#include + +#include "../hiredis.h" +#include "../async.h" + +typedef struct +{ + GSource source; + redisAsyncContext *ac; + GPollFD poll_fd; +} RedisSource; + +static void +redis_source_add_read (gpointer data) +{ + RedisSource *source = (RedisSource *)data; + g_return_if_fail(source); + source->poll_fd.events |= G_IO_IN; + g_main_context_wakeup(g_source_get_context((GSource *)data)); +} + +static void +redis_source_del_read (gpointer data) +{ + RedisSource *source = (RedisSource *)data; + g_return_if_fail(source); + source->poll_fd.events &= ~G_IO_IN; + g_main_context_wakeup(g_source_get_context((GSource *)data)); +} + +static void +redis_source_add_write (gpointer data) +{ + RedisSource *source = (RedisSource *)data; + g_return_if_fail(source); + source->poll_fd.events |= G_IO_OUT; + g_main_context_wakeup(g_source_get_context((GSource *)data)); +} + +static void +redis_source_del_write (gpointer data) +{ + RedisSource *source = (RedisSource *)data; + g_return_if_fail(source); + source->poll_fd.events &= ~G_IO_OUT; + g_main_context_wakeup(g_source_get_context((GSource *)data)); +} + +static void +redis_source_cleanup (gpointer data) +{ + RedisSource *source = (RedisSource *)data; + + g_return_if_fail(source); + + redis_source_del_read(source); + redis_source_del_write(source); + /* + * It is not our responsibility to remove ourself from the + * current main loop. However, we will remove the GPollFD. + */ + if (source->poll_fd.fd >= 0) { + g_source_remove_poll((GSource *)data, &source->poll_fd); + source->poll_fd.fd = -1; + } +} + +static gboolean +redis_source_prepare (GSource *source, + gint *timeout_) +{ + RedisSource *redis = (RedisSource *)source; + *timeout_ = -1; + return !!(redis->poll_fd.events & redis->poll_fd.revents); +} + +static gboolean +redis_source_check (GSource *source) +{ + RedisSource *redis = (RedisSource *)source; + return !!(redis->poll_fd.events & redis->poll_fd.revents); +} + +static gboolean +redis_source_dispatch (GSource *source, + GSourceFunc callback, + gpointer user_data) +{ + RedisSource *redis = (RedisSource *)source; + + if ((redis->poll_fd.revents & G_IO_OUT)) { + redisAsyncHandleWrite(redis->ac); + redis->poll_fd.revents &= ~G_IO_OUT; + } + + if ((redis->poll_fd.revents & G_IO_IN)) { + redisAsyncHandleRead(redis->ac); + redis->poll_fd.revents &= ~G_IO_IN; + } + + if (callback) { + return callback(user_data); + } + + return TRUE; +} + +static void +redis_source_finalize (GSource *source) +{ + RedisSource *redis = (RedisSource *)source; + + if (redis->poll_fd.fd >= 0) { + g_source_remove_poll(source, &redis->poll_fd); + redis->poll_fd.fd = -1; + } +} + +static GSource * +redis_source_new (redisAsyncContext *ac) +{ + static GSourceFuncs source_funcs = { + .prepare = redis_source_prepare, + .check = redis_source_check, + .dispatch = redis_source_dispatch, + .finalize = redis_source_finalize, + }; + redisContext *c = &ac->c; + RedisSource *source; + + g_return_val_if_fail(ac != NULL, NULL); + + source = (RedisSource *)g_source_new(&source_funcs, sizeof *source); + source->ac = ac; + source->poll_fd.fd = c->fd; + source->poll_fd.events = 0; + source->poll_fd.revents = 0; + g_source_add_poll((GSource *)source, &source->poll_fd); + + ac->ev.addRead = redis_source_add_read; + ac->ev.delRead = redis_source_del_read; + ac->ev.addWrite = redis_source_add_write; + ac->ev.delWrite = redis_source_del_write; + ac->ev.cleanup = redis_source_cleanup; + ac->ev.data = source; + + return (GSource *)source; +} + +#endif /* __HIREDIS_GLIB_H__ */ diff --git a/俱乐部/Source/hiredis/adapters/ivykis.h b/俱乐部/Source/hiredis/adapters/ivykis.h new file mode 100644 index 0000000..75616ee --- /dev/null +++ b/俱乐部/Source/hiredis/adapters/ivykis.h @@ -0,0 +1,81 @@ +#ifndef __HIREDIS_IVYKIS_H__ +#define __HIREDIS_IVYKIS_H__ +#include +#include "../hiredis.h" +#include "../async.h" + +typedef struct redisIvykisEvents { + redisAsyncContext *context; + struct iv_fd fd; +} redisIvykisEvents; + +static void redisIvykisReadEvent(void *arg) { + redisAsyncContext *context = (redisAsyncContext *)arg; + redisAsyncHandleRead(context); +} + +static void redisIvykisWriteEvent(void *arg) { + redisAsyncContext *context = (redisAsyncContext *)arg; + redisAsyncHandleWrite(context); +} + +static void redisIvykisAddRead(void *privdata) { + redisIvykisEvents *e = (redisIvykisEvents*)privdata; + iv_fd_set_handler_in(&e->fd, redisIvykisReadEvent); +} + +static void redisIvykisDelRead(void *privdata) { + redisIvykisEvents *e = (redisIvykisEvents*)privdata; + iv_fd_set_handler_in(&e->fd, NULL); +} + +static void redisIvykisAddWrite(void *privdata) { + redisIvykisEvents *e = (redisIvykisEvents*)privdata; + iv_fd_set_handler_out(&e->fd, redisIvykisWriteEvent); +} + +static void redisIvykisDelWrite(void *privdata) { + redisIvykisEvents *e = (redisIvykisEvents*)privdata; + iv_fd_set_handler_out(&e->fd, NULL); +} + +static void redisIvykisCleanup(void *privdata) { + redisIvykisEvents *e = (redisIvykisEvents*)privdata; + + iv_fd_unregister(&e->fd); + free(e); +} + +static int redisIvykisAttach(redisAsyncContext *ac) { + redisContext *c = &(ac->c); + redisIvykisEvents *e; + + /* Nothing should be attached when something is already attached */ + if (ac->ev.data != NULL) + return REDIS_ERR; + + /* Create container for context and r/w events */ + e = (redisIvykisEvents*)hi_malloc(sizeof(*e)); + e->context = ac; + + /* Register functions to start/stop listening for events */ + ac->ev.addRead = redisIvykisAddRead; + ac->ev.delRead = redisIvykisDelRead; + ac->ev.addWrite = redisIvykisAddWrite; + ac->ev.delWrite = redisIvykisDelWrite; + ac->ev.cleanup = redisIvykisCleanup; + ac->ev.data = e; + + /* Initialize and install read/write events */ + IV_FD_INIT(&e->fd); + e->fd.fd = c->fd; + e->fd.handler_in = redisIvykisReadEvent; + e->fd.handler_out = redisIvykisWriteEvent; + e->fd.handler_err = NULL; + e->fd.cookie = e->context; + + iv_fd_register(&e->fd); + + return REDIS_OK; +} +#endif diff --git a/俱乐部/Source/hiredis/adapters/libev.h b/俱乐部/Source/hiredis/adapters/libev.h new file mode 100644 index 0000000..abad436 --- /dev/null +++ b/俱乐部/Source/hiredis/adapters/libev.h @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2010-2011, Pieter Noordhuis + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Redis nor the names of its contributors may 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. + */ + +#ifndef __HIREDIS_LIBEV_H__ +#define __HIREDIS_LIBEV_H__ +#include +#include +#include +#include "../hiredis.h" +#include "../async.h" + +typedef struct redisLibevEvents { + redisAsyncContext *context; + struct ev_loop *loop; + int reading, writing; + ev_io rev, wev; +} redisLibevEvents; + +static void redisLibevReadEvent(EV_P_ ev_io *watcher, int revents) { +#if EV_MULTIPLICITY + ((void)loop); +#endif + ((void)revents); + + redisLibevEvents *e = (redisLibevEvents*)watcher->data; + redisAsyncHandleRead(e->context); +} + +static void redisLibevWriteEvent(EV_P_ ev_io *watcher, int revents) { +#if EV_MULTIPLICITY + ((void)loop); +#endif + ((void)revents); + + redisLibevEvents *e = (redisLibevEvents*)watcher->data; + redisAsyncHandleWrite(e->context); +} + +static void redisLibevAddRead(void *privdata) { + redisLibevEvents *e = (redisLibevEvents*)privdata; + struct ev_loop *loop = e->loop; + ((void)loop); + if (!e->reading) { + e->reading = 1; + ev_io_start(EV_A_ &e->rev); + } +} + +static void redisLibevDelRead(void *privdata) { + redisLibevEvents *e = (redisLibevEvents*)privdata; + struct ev_loop *loop = e->loop; + ((void)loop); + if (e->reading) { + e->reading = 0; + ev_io_stop(EV_A_ &e->rev); + } +} + +static void redisLibevAddWrite(void *privdata) { + redisLibevEvents *e = (redisLibevEvents*)privdata; + struct ev_loop *loop = e->loop; + ((void)loop); + if (!e->writing) { + e->writing = 1; + ev_io_start(EV_A_ &e->wev); + } +} + +static void redisLibevDelWrite(void *privdata) { + redisLibevEvents *e = (redisLibevEvents*)privdata; + struct ev_loop *loop = e->loop; + ((void)loop); + if (e->writing) { + e->writing = 0; + ev_io_stop(EV_A_ &e->wev); + } +} + +static void redisLibevCleanup(void *privdata) { + redisLibevEvents *e = (redisLibevEvents*)privdata; + redisLibevDelRead(privdata); + redisLibevDelWrite(privdata); + free(e); +} + +static int redisLibevAttach(EV_P_ redisAsyncContext *ac) { + redisContext *c = &(ac->c); + redisLibevEvents *e; + + /* Nothing should be attached when something is already attached */ + if (ac->ev.data != NULL) + return REDIS_ERR; + + /* Create container for context and r/w events */ + e = (redisLibevEvents*)hi_malloc(sizeof(*e)); + e->context = ac; +#if EV_MULTIPLICITY + e->loop = loop; +#else + e->loop = NULL; +#endif + e->reading = e->writing = 0; + e->rev.data = e; + e->wev.data = e; + + /* Register functions to start/stop listening for events */ + ac->ev.addRead = redisLibevAddRead; + ac->ev.delRead = redisLibevDelRead; + ac->ev.addWrite = redisLibevAddWrite; + ac->ev.delWrite = redisLibevDelWrite; + ac->ev.cleanup = redisLibevCleanup; + ac->ev.data = e; + + /* Initialize read/write events */ + ev_io_init(&e->rev,redisLibevReadEvent,c->fd,EV_READ); + ev_io_init(&e->wev,redisLibevWriteEvent,c->fd,EV_WRITE); + return REDIS_OK; +} + +#endif diff --git a/俱乐部/Source/hiredis/adapters/libevent.h b/俱乐部/Source/hiredis/adapters/libevent.h new file mode 100644 index 0000000..0674ca6 --- /dev/null +++ b/俱乐部/Source/hiredis/adapters/libevent.h @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2010-2011, Pieter Noordhuis + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Redis nor the names of its contributors may 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. + */ + +#ifndef __HIREDIS_LIBEVENT_H__ +#define __HIREDIS_LIBEVENT_H__ +#include +#include "../hiredis.h" +#include "../async.h" + +#define REDIS_LIBEVENT_DELETED 0x01 +#define REDIS_LIBEVENT_ENTERED 0x02 + +typedef struct redisLibeventEvents { + redisAsyncContext *context; + struct event *ev; + struct event_base *base; + struct timeval tv; + short flags; + short state; +} redisLibeventEvents; + +static void redisLibeventDestroy(redisLibeventEvents *e) { + free(e); +} + +static void redisLibeventHandler(int fd, short event, void *arg) { + ((void)fd); + redisLibeventEvents *e = (redisLibeventEvents*)arg; + e->state |= REDIS_LIBEVENT_ENTERED; + + #define CHECK_DELETED() if (e->state & REDIS_LIBEVENT_DELETED) {\ + redisLibeventDestroy(e);\ + return; \ + } + + if ((event & EV_TIMEOUT) && (e->state & REDIS_LIBEVENT_DELETED) == 0) { + redisAsyncHandleTimeout(e->context); + CHECK_DELETED(); + } + + if ((event & EV_READ) && e->context && (e->state & REDIS_LIBEVENT_DELETED) == 0) { + redisAsyncHandleRead(e->context); + CHECK_DELETED(); + } + + if ((event & EV_WRITE) && e->context && (e->state & REDIS_LIBEVENT_DELETED) == 0) { + redisAsyncHandleWrite(e->context); + CHECK_DELETED(); + } + + e->state &= ~REDIS_LIBEVENT_ENTERED; + #undef CHECK_DELETED +} + +static void redisLibeventUpdate(void *privdata, short flag, int isRemove) { + redisLibeventEvents *e = (redisLibeventEvents *)privdata; + const struct timeval *tv = e->tv.tv_sec || e->tv.tv_usec ? &e->tv : NULL; + + if (isRemove) { + if ((e->flags & flag) == 0) { + return; + } else { + e->flags &= ~flag; + } + } else { + if (e->flags & flag) { + return; + } else { + e->flags |= flag; + } + } + + event_del(e->ev); + event_assign(e->ev, e->base, e->context->c.fd, e->flags | EV_PERSIST, + redisLibeventHandler, privdata); + event_add(e->ev, tv); +} + +static void redisLibeventAddRead(void *privdata) { + redisLibeventUpdate(privdata, EV_READ, 0); +} + +static void redisLibeventDelRead(void *privdata) { + redisLibeventUpdate(privdata, EV_READ, 1); +} + +static void redisLibeventAddWrite(void *privdata) { + redisLibeventUpdate(privdata, EV_WRITE, 0); +} + +static void redisLibeventDelWrite(void *privdata) { + redisLibeventUpdate(privdata, EV_WRITE, 1); +} + +static void redisLibeventCleanup(void *privdata) { + redisLibeventEvents *e = (redisLibeventEvents*)privdata; + if (!e) { + return; + } + event_del(e->ev); + event_free(e->ev); + e->ev = NULL; + + if (e->state & REDIS_LIBEVENT_ENTERED) { + e->state |= REDIS_LIBEVENT_DELETED; + } else { + redisLibeventDestroy(e); + } +} + +static void redisLibeventSetTimeout(void *privdata, struct timeval tv) { + redisLibeventEvents *e = (redisLibeventEvents *)privdata; + short flags = e->flags; + e->flags = 0; + e->tv = tv; + redisLibeventUpdate(e, flags, 0); +} + +static int redisLibeventAttach(redisAsyncContext *ac, struct event_base *base) { + redisContext *c = &(ac->c); + redisLibeventEvents *e; + + /* Nothing should be attached when something is already attached */ + if (ac->ev.data != NULL) + return REDIS_ERR; + + /* Create container for context and r/w events */ + e = (redisLibeventEvents*)hi_calloc(1, sizeof(*e)); + e->context = ac; + + /* Register functions to start/stop listening for events */ + ac->ev.addRead = redisLibeventAddRead; + ac->ev.delRead = redisLibeventDelRead; + ac->ev.addWrite = redisLibeventAddWrite; + ac->ev.delWrite = redisLibeventDelWrite; + ac->ev.cleanup = redisLibeventCleanup; + ac->ev.scheduleTimer = redisLibeventSetTimeout; + ac->ev.data = e; + + /* Initialize and install read/write events */ + e->ev = event_new(base, c->fd, EV_READ | EV_WRITE, redisLibeventHandler, e); + e->base = base; + return REDIS_OK; +} +#endif diff --git a/俱乐部/Source/hiredis/adapters/libuv.h b/俱乐部/Source/hiredis/adapters/libuv.h new file mode 100644 index 0000000..39ef7cf --- /dev/null +++ b/俱乐部/Source/hiredis/adapters/libuv.h @@ -0,0 +1,119 @@ +#ifndef __HIREDIS_LIBUV_H__ +#define __HIREDIS_LIBUV_H__ +#include +#include +#include "../hiredis.h" +#include "../async.h" +#include + +typedef struct redisLibuvEvents { + redisAsyncContext* context; + uv_poll_t handle; + int events; +} redisLibuvEvents; + + +static void redisLibuvPoll(uv_poll_t* handle, int status, int events) { + redisLibuvEvents* p = (redisLibuvEvents*)handle->data; + int ev = (status ? p->events : events); + + if (p->context != NULL && (ev & UV_READABLE)) { + redisAsyncHandleRead(p->context); + } + if (p->context != NULL && (ev & UV_WRITABLE)) { + redisAsyncHandleWrite(p->context); + } +} + + +static void redisLibuvAddRead(void *privdata) { + redisLibuvEvents* p = (redisLibuvEvents*)privdata; + + p->events |= UV_READABLE; + + uv_poll_start(&p->handle, p->events, redisLibuvPoll); +} + + +static void redisLibuvDelRead(void *privdata) { + redisLibuvEvents* p = (redisLibuvEvents*)privdata; + + p->events &= ~UV_READABLE; + + if (p->events) { + uv_poll_start(&p->handle, p->events, redisLibuvPoll); + } else { + uv_poll_stop(&p->handle); + } +} + + +static void redisLibuvAddWrite(void *privdata) { + redisLibuvEvents* p = (redisLibuvEvents*)privdata; + + p->events |= UV_WRITABLE; + + uv_poll_start(&p->handle, p->events, redisLibuvPoll); +} + + +static void redisLibuvDelWrite(void *privdata) { + redisLibuvEvents* p = (redisLibuvEvents*)privdata; + + p->events &= ~UV_WRITABLE; + + if (p->events) { + uv_poll_start(&p->handle, p->events, redisLibuvPoll); + } else { + uv_poll_stop(&p->handle); + } +} + + +static void on_close(uv_handle_t* handle) { + redisLibuvEvents* p = (redisLibuvEvents*)handle->data; + + free(p); +} + + +static void redisLibuvCleanup(void *privdata) { + redisLibuvEvents* p = (redisLibuvEvents*)privdata; + + p->context = NULL; // indicate that context might no longer exist + uv_close((uv_handle_t*)&p->handle, on_close); +} + + +static int redisLibuvAttach(redisAsyncContext* ac, uv_loop_t* loop) { + redisContext *c = &(ac->c); + + if (ac->ev.data != NULL) { + return REDIS_ERR; + } + + ac->ev.addRead = redisLibuvAddRead; + ac->ev.delRead = redisLibuvDelRead; + ac->ev.addWrite = redisLibuvAddWrite; + ac->ev.delWrite = redisLibuvDelWrite; + ac->ev.cleanup = redisLibuvCleanup; + + redisLibuvEvents* p = (redisLibuvEvents*)malloc(sizeof(*p)); + + if (!p) { + return REDIS_ERR; + } + + memset(p, 0, sizeof(*p)); + + if (uv_poll_init(loop, &p->handle, c->fd) != 0) { + return REDIS_ERR; + } + + ac->ev.data = p; + p->handle.data = p; + p->context = ac; + + return REDIS_OK; +} +#endif diff --git a/俱乐部/Source/hiredis/adapters/macosx.h b/俱乐部/Source/hiredis/adapters/macosx.h new file mode 100644 index 0000000..72121f6 --- /dev/null +++ b/俱乐部/Source/hiredis/adapters/macosx.h @@ -0,0 +1,114 @@ +// +// Created by Дмитрий Бахвалов on 13.07.15. +// Copyright (c) 2015 Dmitry Bakhvalov. All rights reserved. +// + +#ifndef __HIREDIS_MACOSX_H__ +#define __HIREDIS_MACOSX_H__ + +#include + +#include "../hiredis.h" +#include "../async.h" + +typedef struct { + redisAsyncContext *context; + CFSocketRef socketRef; + CFRunLoopSourceRef sourceRef; +} RedisRunLoop; + +static int freeRedisRunLoop(RedisRunLoop* redisRunLoop) { + if( redisRunLoop != NULL ) { + if( redisRunLoop->sourceRef != NULL ) { + CFRunLoopSourceInvalidate(redisRunLoop->sourceRef); + CFRelease(redisRunLoop->sourceRef); + } + if( redisRunLoop->socketRef != NULL ) { + CFSocketInvalidate(redisRunLoop->socketRef); + CFRelease(redisRunLoop->socketRef); + } + free(redisRunLoop); + } + return REDIS_ERR; +} + +static void redisMacOSAddRead(void *privdata) { + RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata; + CFSocketEnableCallBacks(redisRunLoop->socketRef, kCFSocketReadCallBack); +} + +static void redisMacOSDelRead(void *privdata) { + RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata; + CFSocketDisableCallBacks(redisRunLoop->socketRef, kCFSocketReadCallBack); +} + +static void redisMacOSAddWrite(void *privdata) { + RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata; + CFSocketEnableCallBacks(redisRunLoop->socketRef, kCFSocketWriteCallBack); +} + +static void redisMacOSDelWrite(void *privdata) { + RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata; + CFSocketDisableCallBacks(redisRunLoop->socketRef, kCFSocketWriteCallBack); +} + +static void redisMacOSCleanup(void *privdata) { + RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata; + freeRedisRunLoop(redisRunLoop); +} + +static void redisMacOSAsyncCallback(CFSocketRef __unused s, CFSocketCallBackType callbackType, CFDataRef __unused address, const void __unused *data, void *info) { + redisAsyncContext* context = (redisAsyncContext*) info; + + switch (callbackType) { + case kCFSocketReadCallBack: + redisAsyncHandleRead(context); + break; + + case kCFSocketWriteCallBack: + redisAsyncHandleWrite(context); + break; + + default: + break; + } +} + +static int redisMacOSAttach(redisAsyncContext *redisAsyncCtx, CFRunLoopRef runLoop) { + redisContext *redisCtx = &(redisAsyncCtx->c); + + /* Nothing should be attached when something is already attached */ + if( redisAsyncCtx->ev.data != NULL ) return REDIS_ERR; + + RedisRunLoop* redisRunLoop = (RedisRunLoop*) calloc(1, sizeof(RedisRunLoop)); + if( !redisRunLoop ) return REDIS_ERR; + + /* Setup redis stuff */ + redisRunLoop->context = redisAsyncCtx; + + redisAsyncCtx->ev.addRead = redisMacOSAddRead; + redisAsyncCtx->ev.delRead = redisMacOSDelRead; + redisAsyncCtx->ev.addWrite = redisMacOSAddWrite; + redisAsyncCtx->ev.delWrite = redisMacOSDelWrite; + redisAsyncCtx->ev.cleanup = redisMacOSCleanup; + redisAsyncCtx->ev.data = redisRunLoop; + + /* Initialize and install read/write events */ + CFSocketContext socketCtx = { 0, redisAsyncCtx, NULL, NULL, NULL }; + + redisRunLoop->socketRef = CFSocketCreateWithNative(NULL, redisCtx->fd, + kCFSocketReadCallBack | kCFSocketWriteCallBack, + redisMacOSAsyncCallback, + &socketCtx); + if( !redisRunLoop->socketRef ) return freeRedisRunLoop(redisRunLoop); + + redisRunLoop->sourceRef = CFSocketCreateRunLoopSource(NULL, redisRunLoop->socketRef, 0); + if( !redisRunLoop->sourceRef ) return freeRedisRunLoop(redisRunLoop); + + CFRunLoopAddSource(runLoop, redisRunLoop->sourceRef, kCFRunLoopDefaultMode); + + return REDIS_OK; +} + +#endif + diff --git a/俱乐部/Source/hiredis/adapters/qt.h b/俱乐部/Source/hiredis/adapters/qt.h new file mode 100644 index 0000000..5cc02e6 --- /dev/null +++ b/俱乐部/Source/hiredis/adapters/qt.h @@ -0,0 +1,135 @@ +/*- + * Copyright (C) 2014 Pietro Cerutti + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY AUTHOR 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 AUTHOR 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. + */ + +#ifndef __HIREDIS_QT_H__ +#define __HIREDIS_QT_H__ +#include +#include "../async.h" + +static void RedisQtAddRead(void *); +static void RedisQtDelRead(void *); +static void RedisQtAddWrite(void *); +static void RedisQtDelWrite(void *); +static void RedisQtCleanup(void *); + +class RedisQtAdapter : public QObject { + + Q_OBJECT + + friend + void RedisQtAddRead(void * adapter) { + RedisQtAdapter * a = static_cast(adapter); + a->addRead(); + } + + friend + void RedisQtDelRead(void * adapter) { + RedisQtAdapter * a = static_cast(adapter); + a->delRead(); + } + + friend + void RedisQtAddWrite(void * adapter) { + RedisQtAdapter * a = static_cast(adapter); + a->addWrite(); + } + + friend + void RedisQtDelWrite(void * adapter) { + RedisQtAdapter * a = static_cast(adapter); + a->delWrite(); + } + + friend + void RedisQtCleanup(void * adapter) { + RedisQtAdapter * a = static_cast(adapter); + a->cleanup(); + } + + public: + RedisQtAdapter(QObject * parent = 0) + : QObject(parent), m_ctx(0), m_read(0), m_write(0) { } + + ~RedisQtAdapter() { + if (m_ctx != 0) { + m_ctx->ev.data = NULL; + } + } + + int setContext(redisAsyncContext * ac) { + if (ac->ev.data != NULL) { + return REDIS_ERR; + } + m_ctx = ac; + m_ctx->ev.data = this; + m_ctx->ev.addRead = RedisQtAddRead; + m_ctx->ev.delRead = RedisQtDelRead; + m_ctx->ev.addWrite = RedisQtAddWrite; + m_ctx->ev.delWrite = RedisQtDelWrite; + m_ctx->ev.cleanup = RedisQtCleanup; + return REDIS_OK; + } + + private: + void addRead() { + if (m_read) return; + m_read = new QSocketNotifier(m_ctx->c.fd, QSocketNotifier::Read, 0); + connect(m_read, SIGNAL(activated(int)), this, SLOT(read())); + } + + void delRead() { + if (!m_read) return; + delete m_read; + m_read = 0; + } + + void addWrite() { + if (m_write) return; + m_write = new QSocketNotifier(m_ctx->c.fd, QSocketNotifier::Write, 0); + connect(m_write, SIGNAL(activated(int)), this, SLOT(write())); + } + + void delWrite() { + if (!m_write) return; + delete m_write; + m_write = 0; + } + + void cleanup() { + delRead(); + delWrite(); + } + + private slots: + void read() { redisAsyncHandleRead(m_ctx); } + void write() { redisAsyncHandleWrite(m_ctx); } + + private: + redisAsyncContext * m_ctx; + QSocketNotifier * m_read; + QSocketNotifier * m_write; +}; + +#endif /* !__HIREDIS_QT_H__ */ diff --git a/俱乐部/Source/hiredis/alloc.c b/俱乐部/Source/hiredis/alloc.c new file mode 100644 index 0000000..55c3020 --- /dev/null +++ b/俱乐部/Source/hiredis/alloc.c @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2020, Michael Grunder + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Redis nor the names of its contributors may 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. + */ + +#include "fmacros.h" +#include "alloc.h" +#include + +void *hi_malloc(size_t size) { + void *ptr = malloc(size); + if (ptr == NULL) + HIREDIS_OOM_HANDLER; + + return ptr; +} + +void *hi_calloc(size_t nmemb, size_t size) { + void *ptr = calloc(nmemb, size); + if (ptr == NULL) + HIREDIS_OOM_HANDLER; + + return ptr; +} + +void *hi_realloc(void *ptr, size_t size) { + void *newptr = realloc(ptr, size); + if (newptr == NULL) + HIREDIS_OOM_HANDLER; + + return newptr; +} + +char *hi_strdup(const char *str) { + char *newstr = strdup(str); + if (newstr == NULL) + HIREDIS_OOM_HANDLER; + + return newstr; +} diff --git a/俱乐部/Source/hiredis/alloc.h b/俱乐部/Source/hiredis/alloc.h new file mode 100644 index 0000000..803129c --- /dev/null +++ b/俱乐部/Source/hiredis/alloc.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2020, Michael Grunder + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Redis nor the names of its contributors may 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. + */ + +#ifndef HIREDIS_ALLOC_H + +#include /* for size_t */ + +#ifndef HIREDIS_OOM_HANDLER +#define HIREDIS_OOM_HANDLER abort() +#endif + +void *hi_malloc(size_t size); +void *hi_calloc(size_t nmemb, size_t size); +void *hi_realloc(void *ptr, size_t size); +char *hi_strdup(const char *str); + +#endif /* HIREDIS_ALLOC_H */ diff --git a/俱乐部/Source/hiredis/appveyor.yml b/俱乐部/Source/hiredis/appveyor.yml new file mode 100644 index 0000000..5b43fdb --- /dev/null +++ b/俱乐部/Source/hiredis/appveyor.yml @@ -0,0 +1,24 @@ +# Appveyor configuration file for CI build of hiredis on Windows (under Cygwin) +environment: + matrix: + - CYG_BASH: C:\cygwin64\bin\bash + CC: gcc + - CYG_BASH: C:\cygwin\bin\bash + CC: gcc + CFLAGS: -m32 + CXXFLAGS: -m32 + LDFLAGS: -m32 + +clone_depth: 1 + +# Attempt to ensure we don't try to convert line endings to Win32 CRLF as this will cause build to fail +init: + - git config --global core.autocrlf input + +# Install needed build dependencies +install: + - '%CYG_BASH% -lc "cygcheck -dc cygwin"' + +build_script: + - 'echo building...' + - '%CYG_BASH% -lc "cd $APPVEYOR_BUILD_FOLDER; exec 0 + * Copyright (c) 2010-2011, Pieter Noordhuis + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Redis nor the names of its contributors may 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. + */ + +#include "fmacros.h" +#include "alloc.h" +#include +#include +#ifndef _MSC_VER +#include +#endif +#include +#include +#include +#include "async.h" +#include "net.h" +#include "dict.c" +#include "sds.h" +#include "win32.h" + +#include "async_private.h" + +/* Forward declaration of function in hiredis.c */ +int __redisAppendCommand(redisContext *c, const char *cmd, size_t len); + +/* Functions managing dictionary of callbacks for pub/sub. */ +static unsigned int callbackHash(const void *key) { + return dictGenHashFunction((const unsigned char *)key, + sdslen((const sds)key)); +} + +static void *callbackValDup(void *privdata, const void *src) { + ((void) privdata); + redisCallback *dup = hi_malloc(sizeof(*dup)); + memcpy(dup,src,sizeof(*dup)); + return dup; +} + +static int callbackKeyCompare(void *privdata, const void *key1, const void *key2) { + int l1, l2; + ((void) privdata); + + l1 = sdslen((const sds)key1); + l2 = sdslen((const sds)key2); + if (l1 != l2) return 0; + return memcmp(key1,key2,l1) == 0; +} + +static void callbackKeyDestructor(void *privdata, void *key) { + ((void) privdata); + sdsfree((sds)key); +} + +static void callbackValDestructor(void *privdata, void *val) { + ((void) privdata); + free(val); +} + +static dictType callbackDict = { + callbackHash, + NULL, + callbackValDup, + callbackKeyCompare, + callbackKeyDestructor, + callbackValDestructor +}; + +static redisAsyncContext *redisAsyncInitialize(redisContext *c) { + redisAsyncContext *ac; + + ac = realloc(c,sizeof(redisAsyncContext)); + if (ac == NULL) + return NULL; + + c = &(ac->c); + + /* The regular connect functions will always set the flag REDIS_CONNECTED. + * For the async API, we want to wait until the first write event is + * received up before setting this flag, so reset it here. */ + c->flags &= ~REDIS_CONNECTED; + + ac->err = 0; + ac->errstr = NULL; + ac->data = NULL; + + ac->ev.data = NULL; + ac->ev.addRead = NULL; + ac->ev.delRead = NULL; + ac->ev.addWrite = NULL; + ac->ev.delWrite = NULL; + ac->ev.cleanup = NULL; + ac->ev.scheduleTimer = NULL; + + ac->onConnect = NULL; + ac->onDisconnect = NULL; + + ac->replies.head = NULL; + ac->replies.tail = NULL; + ac->sub.invalid.head = NULL; + ac->sub.invalid.tail = NULL; + ac->sub.channels = dictCreate(&callbackDict,NULL); + ac->sub.patterns = dictCreate(&callbackDict,NULL); + return ac; +} + +/* We want the error field to be accessible directly instead of requiring + * an indirection to the redisContext struct. */ +static void __redisAsyncCopyError(redisAsyncContext *ac) { + if (!ac) + return; + + redisContext *c = &(ac->c); + ac->err = c->err; + ac->errstr = c->errstr; +} + +redisAsyncContext *redisAsyncConnectWithOptions(const redisOptions *options) { + redisOptions myOptions = *options; + redisContext *c; + redisAsyncContext *ac; + + myOptions.options |= REDIS_OPT_NONBLOCK; + c = redisConnectWithOptions(&myOptions); + if (c == NULL) { + return NULL; + } + ac = redisAsyncInitialize(c); + if (ac == NULL) { + redisFree(c); + return NULL; + } + __redisAsyncCopyError(ac); + return ac; +} + +redisAsyncContext *redisAsyncConnect(const char *ip, int port) { + redisOptions options = {0}; + REDIS_OPTIONS_SET_TCP(&options, ip, port); + return redisAsyncConnectWithOptions(&options); +} + +redisAsyncContext *redisAsyncConnectBind(const char *ip, int port, + const char *source_addr) { + redisOptions options = {0}; + REDIS_OPTIONS_SET_TCP(&options, ip, port); + options.endpoint.tcp.source_addr = source_addr; + return redisAsyncConnectWithOptions(&options); +} + +redisAsyncContext *redisAsyncConnectBindWithReuse(const char *ip, int port, + const char *source_addr) { + redisOptions options = {0}; + REDIS_OPTIONS_SET_TCP(&options, ip, port); + options.options |= REDIS_OPT_REUSEADDR; + options.endpoint.tcp.source_addr = source_addr; + return redisAsyncConnectWithOptions(&options); +} + +redisAsyncContext *redisAsyncConnectUnix(const char *path) { + redisOptions options = {0}; + REDIS_OPTIONS_SET_UNIX(&options, path); + return redisAsyncConnectWithOptions(&options); +} + +int redisAsyncSetConnectCallback(redisAsyncContext *ac, redisConnectCallback *fn) { + if (ac->onConnect == NULL) { + ac->onConnect = fn; + + /* The common way to detect an established connection is to wait for + * the first write event to be fired. This assumes the related event + * library functions are already set. */ + _EL_ADD_WRITE(ac); + return REDIS_OK; + } + return REDIS_ERR; +} + +int redisAsyncSetDisconnectCallback(redisAsyncContext *ac, redisDisconnectCallback *fn) { + if (ac->onDisconnect == NULL) { + ac->onDisconnect = fn; + return REDIS_OK; + } + return REDIS_ERR; +} + +/* Helper functions to push/shift callbacks */ +static int __redisPushCallback(redisCallbackList *list, redisCallback *source) { + redisCallback *cb; + + /* Copy callback from stack to heap */ + cb = malloc(sizeof(*cb)); + if (cb == NULL) + return REDIS_ERR_OOM; + + if (source != NULL) { + memcpy(cb,source,sizeof(*cb)); + cb->next = NULL; + } + + /* Store callback in list */ + if (list->head == NULL) + list->head = cb; + if (list->tail != NULL) + list->tail->next = cb; + list->tail = cb; + return REDIS_OK; +} + +static int __redisShiftCallback(redisCallbackList *list, redisCallback *target) { + redisCallback *cb = list->head; + if (cb != NULL) { + list->head = cb->next; + if (cb == list->tail) + list->tail = NULL; + + /* Copy callback from heap to stack */ + if (target != NULL) + memcpy(target,cb,sizeof(*cb)); + free(cb); + return REDIS_OK; + } + return REDIS_ERR; +} + +static void __redisRunCallback(redisAsyncContext *ac, redisCallback *cb, redisReply *reply) { + redisContext *c = &(ac->c); + if (cb->fn != NULL) { + c->flags |= REDIS_IN_CALLBACK; + cb->fn(ac,reply,cb->privdata); + c->flags &= ~REDIS_IN_CALLBACK; + } +} + +/* Helper function to free the context. */ +static void __redisAsyncFree(redisAsyncContext *ac) { + redisContext *c = &(ac->c); + redisCallback cb; + dictIterator *it; + dictEntry *de; + + /* Execute pending callbacks with NULL reply. */ + while (__redisShiftCallback(&ac->replies,&cb) == REDIS_OK) + __redisRunCallback(ac,&cb,NULL); + + /* Execute callbacks for invalid commands */ + while (__redisShiftCallback(&ac->sub.invalid,&cb) == REDIS_OK) + __redisRunCallback(ac,&cb,NULL); + + /* Run subscription callbacks callbacks with NULL reply */ + it = dictGetIterator(ac->sub.channels); + while ((de = dictNext(it)) != NULL) + __redisRunCallback(ac,dictGetEntryVal(de),NULL); + dictReleaseIterator(it); + dictRelease(ac->sub.channels); + + it = dictGetIterator(ac->sub.patterns); + while ((de = dictNext(it)) != NULL) + __redisRunCallback(ac,dictGetEntryVal(de),NULL); + dictReleaseIterator(it); + dictRelease(ac->sub.patterns); + + /* Signal event lib to clean up */ + _EL_CLEANUP(ac); + + /* Execute disconnect callback. When redisAsyncFree() initiated destroying + * this context, the status will always be REDIS_OK. */ + if (ac->onDisconnect && (c->flags & REDIS_CONNECTED)) { + if (c->flags & REDIS_FREEING) { + ac->onDisconnect(ac,REDIS_OK); + } else { + ac->onDisconnect(ac,(ac->err == 0) ? REDIS_OK : REDIS_ERR); + } + } + + /* Cleanup self */ + redisFree(c); +} + +/* Free the async context. When this function is called from a callback, + * control needs to be returned to redisProcessCallbacks() before actual + * free'ing. To do so, a flag is set on the context which is picked up by + * redisProcessCallbacks(). Otherwise, the context is immediately free'd. */ +void redisAsyncFree(redisAsyncContext *ac) { + redisContext *c = &(ac->c); + c->flags |= REDIS_FREEING; + if (!(c->flags & REDIS_IN_CALLBACK)) + __redisAsyncFree(ac); +} + +/* Helper function to make the disconnect happen and clean up. */ +void __redisAsyncDisconnect(redisAsyncContext *ac) { + redisContext *c = &(ac->c); + + /* Make sure error is accessible if there is any */ + __redisAsyncCopyError(ac); + + if (ac->err == 0) { + /* For clean disconnects, there should be no pending callbacks. */ + int ret = __redisShiftCallback(&ac->replies,NULL); + assert(ret == REDIS_ERR); + } else { + /* Disconnection is caused by an error, make sure that pending + * callbacks cannot call new commands. */ + c->flags |= REDIS_DISCONNECTING; + } + + /* cleanup event library on disconnect. + * this is safe to call multiple times */ + _EL_CLEANUP(ac); + + /* For non-clean disconnects, __redisAsyncFree() will execute pending + * callbacks with a NULL-reply. */ + if (!(c->flags & REDIS_NO_AUTO_FREE)) { + __redisAsyncFree(ac); + } +} + +/* Tries to do a clean disconnect from Redis, meaning it stops new commands + * from being issued, but tries to flush the output buffer and execute + * callbacks for all remaining replies. When this function is called from a + * callback, there might be more replies and we can safely defer disconnecting + * to redisProcessCallbacks(). Otherwise, we can only disconnect immediately + * when there are no pending callbacks. */ +void redisAsyncDisconnect(redisAsyncContext *ac) { + redisContext *c = &(ac->c); + c->flags |= REDIS_DISCONNECTING; + + /** unset the auto-free flag here, because disconnect undoes this */ + c->flags &= ~REDIS_NO_AUTO_FREE; + if (!(c->flags & REDIS_IN_CALLBACK) && ac->replies.head == NULL) + __redisAsyncDisconnect(ac); +} + +static int __redisGetSubscribeCallback(redisAsyncContext *ac, redisReply *reply, redisCallback *dstcb) { + redisContext *c = &(ac->c); + dict *callbacks; + redisCallback *cb; + dictEntry *de; + int pvariant; + char *stype; + sds sname; + + /* Custom reply functions are not supported for pub/sub. This will fail + * very hard when they are used... */ + if (reply->type == REDIS_REPLY_ARRAY) { + assert(reply->elements >= 2); + assert(reply->element[0]->type == REDIS_REPLY_STRING); + stype = reply->element[0]->str; + pvariant = (tolower(stype[0]) == 'p') ? 1 : 0; + + if (pvariant) + callbacks = ac->sub.patterns; + else + callbacks = ac->sub.channels; + + /* Locate the right callback */ + assert(reply->element[1]->type == REDIS_REPLY_STRING); + sname = sdsnewlen(reply->element[1]->str,reply->element[1]->len); + de = dictFind(callbacks,sname); + if (de != NULL) { + cb = dictGetEntryVal(de); + + /* If this is an subscribe reply decrease pending counter. */ + if (strcasecmp(stype+pvariant,"subscribe") == 0) { + cb->pending_subs -= 1; + } + + memcpy(dstcb,cb,sizeof(*dstcb)); + + /* If this is an unsubscribe message, remove it. */ + if (strcasecmp(stype+pvariant,"unsubscribe") == 0) { + if (cb->pending_subs == 0) + dictDelete(callbacks,sname); + + /* If this was the last unsubscribe message, revert to + * non-subscribe mode. */ + assert(reply->element[2]->type == REDIS_REPLY_INTEGER); + + /* Unset subscribed flag only when no pipelined pending subscribe. */ + if (reply->element[2]->integer == 0 + && dictSize(ac->sub.channels) == 0 + && dictSize(ac->sub.patterns) == 0) + c->flags &= ~REDIS_SUBSCRIBED; + } + } + sdsfree(sname); + } else { + /* Shift callback for invalid commands. */ + __redisShiftCallback(&ac->sub.invalid,dstcb); + } + return REDIS_OK; +} + +void redisProcessCallbacks(redisAsyncContext *ac) { + redisContext *c = &(ac->c); + redisCallback cb = {NULL, NULL, 0, NULL}; + void *reply = NULL; + int status; + + while((status = redisGetReply(c,&reply)) == REDIS_OK) { + if (reply == NULL) { + /* When the connection is being disconnected and there are + * no more replies, this is the cue to really disconnect. */ + if (c->flags & REDIS_DISCONNECTING && sdslen(c->obuf) == 0 + && ac->replies.head == NULL) { + __redisAsyncDisconnect(ac); + return; + } + + /* If monitor mode, repush callback */ + if(c->flags & REDIS_MONITORING) { + __redisPushCallback(&ac->replies,&cb); + } + + /* When the connection is not being disconnected, simply stop + * trying to get replies and wait for the next loop tick. */ + break; + } + + /* Even if the context is subscribed, pending regular callbacks will + * get a reply before pub/sub messages arrive. */ + if (__redisShiftCallback(&ac->replies,&cb) != REDIS_OK) { + /* + * A spontaneous reply in a not-subscribed context can be the error + * reply that is sent when a new connection exceeds the maximum + * number of allowed connections on the server side. + * + * This is seen as an error instead of a regular reply because the + * server closes the connection after sending it. + * + * To prevent the error from being overwritten by an EOF error the + * connection is closed here. See issue #43. + * + * Another possibility is that the server is loading its dataset. + * In this case we also want to close the connection, and have the + * user wait until the server is ready to take our request. + */ + if (((redisReply*)reply)->type == REDIS_REPLY_ERROR) { + c->err = REDIS_ERR_OTHER; + snprintf(c->errstr,sizeof(c->errstr),"%s",((redisReply*)reply)->str); + c->reader->fn->freeObject(reply); + __redisAsyncDisconnect(ac); + return; + } + /* No more regular callbacks and no errors, the context *must* be subscribed or monitoring. */ + assert((c->flags & REDIS_SUBSCRIBED || c->flags & REDIS_MONITORING)); + if(c->flags & REDIS_SUBSCRIBED) + __redisGetSubscribeCallback(ac,reply,&cb); + } + + if (cb.fn != NULL) { + __redisRunCallback(ac,&cb,reply); + c->reader->fn->freeObject(reply); + + /* Proceed with free'ing when redisAsyncFree() was called. */ + if (c->flags & REDIS_FREEING) { + __redisAsyncFree(ac); + return; + } + } else { + /* No callback for this reply. This can either be a NULL callback, + * or there were no callbacks to begin with. Either way, don't + * abort with an error, but simply ignore it because the client + * doesn't know what the server will spit out over the wire. */ + c->reader->fn->freeObject(reply); + } + } + + /* Disconnect when there was an error reading the reply */ + if (status != REDIS_OK) + __redisAsyncDisconnect(ac); +} + +/* Internal helper function to detect socket status the first time a read or + * write event fires. When connecting was not successful, the connect callback + * is called with a REDIS_ERR status and the context is free'd. */ +static int __redisAsyncHandleConnect(redisAsyncContext *ac) { + int completed = 0; + redisContext *c = &(ac->c); + if (redisCheckConnectDone(c, &completed) == REDIS_ERR) { + /* Error! */ + redisCheckSocketError(c); + if (ac->onConnect) ac->onConnect(ac, REDIS_ERR); + __redisAsyncDisconnect(ac); + return REDIS_ERR; + } else if (completed == 1) { + /* connected! */ + if (ac->onConnect) ac->onConnect(ac, REDIS_OK); + c->flags |= REDIS_CONNECTED; + return REDIS_OK; + } else { + return REDIS_OK; + } +} + +void redisAsyncRead(redisAsyncContext *ac) { + redisContext *c = &(ac->c); + + if (redisBufferRead(c) == REDIS_ERR) { + __redisAsyncDisconnect(ac); + } else { + /* Always re-schedule reads */ + _EL_ADD_READ(ac); + redisProcessCallbacks(ac); + } +} + +/* This function should be called when the socket is readable. + * It processes all replies that can be read and executes their callbacks. + */ +void redisAsyncHandleRead(redisAsyncContext *ac) { + redisContext *c = &(ac->c); + + if (!(c->flags & REDIS_CONNECTED)) { + /* Abort connect was not successful. */ + if (__redisAsyncHandleConnect(ac) != REDIS_OK) + return; + /* Try again later when the context is still not connected. */ + if (!(c->flags & REDIS_CONNECTED)) + return; + } + + c->funcs->async_read(ac); +} + +void redisAsyncWrite(redisAsyncContext *ac) { + redisContext *c = &(ac->c); + int done = 0; + + if (redisBufferWrite(c,&done) == REDIS_ERR) { + __redisAsyncDisconnect(ac); + } else { + /* Continue writing when not done, stop writing otherwise */ + if (!done) + _EL_ADD_WRITE(ac); + else + _EL_DEL_WRITE(ac); + + /* Always schedule reads after writes */ + _EL_ADD_READ(ac); + } +} + +void redisAsyncHandleWrite(redisAsyncContext *ac) { + redisContext *c = &(ac->c); + + if (!(c->flags & REDIS_CONNECTED)) { + /* Abort connect was not successful. */ + if (__redisAsyncHandleConnect(ac) != REDIS_OK) + return; + /* Try again later when the context is still not connected. */ + if (!(c->flags & REDIS_CONNECTED)) + return; + } + + c->funcs->async_write(ac); +} + +void __redisSetError(redisContext *c, int type, const char *str); + +void redisAsyncHandleTimeout(redisAsyncContext *ac) { + redisContext *c = &(ac->c); + redisCallback cb; + + if ((c->flags & REDIS_CONNECTED) && ac->replies.head == NULL) { + /* Nothing to do - just an idle timeout */ + return; + } + + if (!c->err) { + __redisSetError(c, REDIS_ERR_TIMEOUT, "Timeout"); + } + + if (!(c->flags & REDIS_CONNECTED) && ac->onConnect) { + ac->onConnect(ac, REDIS_ERR); + } + + while (__redisShiftCallback(&ac->replies, &cb) == REDIS_OK) { + __redisRunCallback(ac, &cb, NULL); + } + + /** + * TODO: Don't automatically sever the connection, + * rather, allow to ignore responses before the queue is clear + */ + __redisAsyncDisconnect(ac); +} + +/* Sets a pointer to the first argument and its length starting at p. Returns + * the number of bytes to skip to get to the following argument. */ +static const char *nextArgument(const char *start, const char **str, size_t *len) { + const char *p = start; + if (p[0] != '$') { + p = strchr(p,'$'); + if (p == NULL) return NULL; + } + + *len = (int)strtol(p+1,NULL,10); + p = strchr(p,'\r'); + assert(p); + *str = p+2; + return p+2+(*len)+2; +} + +/* Helper function for the redisAsyncCommand* family of functions. Writes a + * formatted command to the output buffer and registers the provided callback + * function with the context. */ +static int __redisAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *cmd, size_t len) { + redisContext *c = &(ac->c); + redisCallback cb; + struct dict *cbdict; + dictEntry *de; + redisCallback *existcb; + int pvariant, hasnext; + const char *cstr, *astr; + size_t clen, alen; + const char *p; + sds sname; + int ret; + + /* Don't accept new commands when the connection is about to be closed. */ + if (c->flags & (REDIS_DISCONNECTING | REDIS_FREEING)) return REDIS_ERR; + + /* Setup callback */ + cb.fn = fn; + cb.privdata = privdata; + cb.pending_subs = 1; + + /* Find out which command will be appended. */ + p = nextArgument(cmd,&cstr,&clen); + assert(p != NULL); + hasnext = (p[0] == '$'); + pvariant = (tolower(cstr[0]) == 'p') ? 1 : 0; + cstr += pvariant; + clen -= pvariant; + + if (hasnext && strncasecmp(cstr,"subscribe\r\n",11) == 0) { + c->flags |= REDIS_SUBSCRIBED; + + /* Add every channel/pattern to the list of subscription callbacks. */ + while ((p = nextArgument(p,&astr,&alen)) != NULL) { + sname = sdsnewlen(astr,alen); + if (pvariant) + cbdict = ac->sub.patterns; + else + cbdict = ac->sub.channels; + + de = dictFind(cbdict,sname); + + if (de != NULL) { + existcb = dictGetEntryVal(de); + cb.pending_subs = existcb->pending_subs + 1; + } + + ret = dictReplace(cbdict,sname,&cb); + + if (ret == 0) sdsfree(sname); + } + } else if (strncasecmp(cstr,"unsubscribe\r\n",13) == 0) { + /* It is only useful to call (P)UNSUBSCRIBE when the context is + * subscribed to one or more channels or patterns. */ + if (!(c->flags & REDIS_SUBSCRIBED)) return REDIS_ERR; + + /* (P)UNSUBSCRIBE does not have its own response: every channel or + * pattern that is unsubscribed will receive a message. This means we + * should not append a callback function for this command. */ + } else if(strncasecmp(cstr,"monitor\r\n",9) == 0) { + /* Set monitor flag and push callback */ + c->flags |= REDIS_MONITORING; + __redisPushCallback(&ac->replies,&cb); + } else { + if (c->flags & REDIS_SUBSCRIBED) + /* This will likely result in an error reply, but it needs to be + * received and passed to the callback. */ + __redisPushCallback(&ac->sub.invalid,&cb); + else + __redisPushCallback(&ac->replies,&cb); + } + + __redisAppendCommand(c,cmd,len); + + /* Always schedule a write when the write buffer is non-empty */ + _EL_ADD_WRITE(ac); + + return REDIS_OK; +} + +int redisvAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *format, va_list ap) { + char *cmd; + int len; + int status; + len = redisvFormatCommand(&cmd,format,ap); + + /* We don't want to pass -1 or -2 to future functions as a length. */ + if (len < 0) + return REDIS_ERR; + + status = __redisAsyncCommand(ac,fn,privdata,cmd,len); + free(cmd); + return status; +} + +int redisAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *format, ...) { + va_list ap; + int status; + va_start(ap,format); + status = redisvAsyncCommand(ac,fn,privdata,format,ap); + va_end(ap); + return status; +} + +int redisAsyncCommandArgv(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, int argc, const char **argv, const size_t *argvlen) { + sds cmd; + int len; + int status; + len = redisFormatSdsCommandArgv(&cmd,argc,argv,argvlen); + if (len < 0) + return REDIS_ERR; + status = __redisAsyncCommand(ac,fn,privdata,cmd,len); + sdsfree(cmd); + return status; +} + +int redisAsyncFormattedCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *cmd, size_t len) { + int status = __redisAsyncCommand(ac,fn,privdata,cmd,len); + return status; +} + +void redisAsyncSetTimeout(redisAsyncContext *ac, struct timeval tv) { + if (!ac->c.timeout) { + ac->c.timeout = hi_calloc(1, sizeof(tv)); + } + + if (tv.tv_sec == ac->c.timeout->tv_sec && + tv.tv_usec == ac->c.timeout->tv_usec) { + return; + } + + *ac->c.timeout = tv; +} diff --git a/俱乐部/Source/hiredis/async.h b/俱乐部/Source/hiredis/async.h new file mode 100644 index 0000000..4f6b3b7 --- /dev/null +++ b/俱乐部/Source/hiredis/async.h @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2009-2011, Salvatore Sanfilippo + * Copyright (c) 2010-2011, Pieter Noordhuis + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Redis nor the names of its contributors may 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. + */ + +#ifndef __HIREDIS_ASYNC_H +#define __HIREDIS_ASYNC_H +#include "hiredis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct redisAsyncContext; /* need forward declaration of redisAsyncContext */ +struct dict; /* dictionary header is included in async.c */ + +/* Reply callback prototype and container */ +typedef void (redisCallbackFn)(struct redisAsyncContext*, void*, void*); +typedef struct redisCallback { + struct redisCallback *next; /* simple singly linked list */ + redisCallbackFn *fn; + int pending_subs; + void *privdata; +} redisCallback; + +/* List of callbacks for either regular replies or pub/sub */ +typedef struct redisCallbackList { + redisCallback *head, *tail; +} redisCallbackList; + +/* Connection callback prototypes */ +typedef void (redisDisconnectCallback)(const struct redisAsyncContext*, int status); +typedef void (redisConnectCallback)(const struct redisAsyncContext*, int status); +typedef void(redisTimerCallback)(void *timer, void *privdata); + +/* Context for an async connection to Redis */ +typedef struct redisAsyncContext { + /* Hold the regular context, so it can be realloc'ed. */ + redisContext c; + + /* Setup error flags so they can be used directly. */ + int err; + char *errstr; + + /* Not used by hiredis */ + void *data; + + /* Event library data and hooks */ + struct { + void *data; + + /* Hooks that are called when the library expects to start + * reading/writing. These functions should be idempotent. */ + void (*addRead)(void *privdata); + void (*delRead)(void *privdata); + void (*addWrite)(void *privdata); + void (*delWrite)(void *privdata); + void (*cleanup)(void *privdata); + void (*scheduleTimer)(void *privdata, struct timeval tv); + } ev; + + /* Called when either the connection is terminated due to an error or per + * user request. The status is set accordingly (REDIS_OK, REDIS_ERR). */ + redisDisconnectCallback *onDisconnect; + + /* Called when the first write event was received. */ + redisConnectCallback *onConnect; + + /* Regular command callbacks */ + redisCallbackList replies; + + /* Address used for connect() */ + struct sockaddr *saddr; + size_t addrlen; + + /* Subscription callbacks */ + struct { + redisCallbackList invalid; + struct dict *channels; + struct dict *patterns; + } sub; +} redisAsyncContext; + +/* Functions that proxy to hiredis */ +redisAsyncContext *redisAsyncConnectWithOptions(const redisOptions *options); +redisAsyncContext *redisAsyncConnect(const char *ip, int port); +redisAsyncContext *redisAsyncConnectBind(const char *ip, int port, const char *source_addr); +redisAsyncContext *redisAsyncConnectBindWithReuse(const char *ip, int port, + const char *source_addr); +redisAsyncContext *redisAsyncConnectUnix(const char *path); +int redisAsyncSetConnectCallback(redisAsyncContext *ac, redisConnectCallback *fn); +int redisAsyncSetDisconnectCallback(redisAsyncContext *ac, redisDisconnectCallback *fn); + +void redisAsyncSetTimeout(redisAsyncContext *ac, struct timeval tv); +void redisAsyncDisconnect(redisAsyncContext *ac); +void redisAsyncFree(redisAsyncContext *ac); + +/* Handle read/write events */ +void redisAsyncHandleRead(redisAsyncContext *ac); +void redisAsyncHandleWrite(redisAsyncContext *ac); +void redisAsyncHandleTimeout(redisAsyncContext *ac); +void redisAsyncRead(redisAsyncContext *ac); +void redisAsyncWrite(redisAsyncContext *ac); + +/* Command functions for an async context. Write the command to the + * output buffer and register the provided callback. */ +int redisvAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *format, va_list ap); +int redisAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *format, ...); +int redisAsyncCommandArgv(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, int argc, const char **argv, const size_t *argvlen); +int redisAsyncFormattedCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *cmd, size_t len); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/俱乐部/Source/hiredis/async_private.h b/俱乐部/Source/hiredis/async_private.h new file mode 100644 index 0000000..d0133ae --- /dev/null +++ b/俱乐部/Source/hiredis/async_private.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2009-2011, Salvatore Sanfilippo + * Copyright (c) 2010-2011, Pieter Noordhuis + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Redis nor the names of its contributors may 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. + */ + +#ifndef __HIREDIS_ASYNC_PRIVATE_H +#define __HIREDIS_ASYNC_PRIVATE_H + +#define _EL_ADD_READ(ctx) \ + do { \ + refreshTimeout(ctx); \ + if ((ctx)->ev.addRead) (ctx)->ev.addRead((ctx)->ev.data); \ + } while (0) +#define _EL_DEL_READ(ctx) do { \ + if ((ctx)->ev.delRead) (ctx)->ev.delRead((ctx)->ev.data); \ + } while(0) +#define _EL_ADD_WRITE(ctx) \ + do { \ + refreshTimeout(ctx); \ + if ((ctx)->ev.addWrite) (ctx)->ev.addWrite((ctx)->ev.data); \ + } while (0) +#define _EL_DEL_WRITE(ctx) do { \ + if ((ctx)->ev.delWrite) (ctx)->ev.delWrite((ctx)->ev.data); \ + } while(0) +#define _EL_CLEANUP(ctx) do { \ + if ((ctx)->ev.cleanup) (ctx)->ev.cleanup((ctx)->ev.data); \ + ctx->ev.cleanup = NULL; \ + } while(0); + +static inline void refreshTimeout(redisAsyncContext *ctx) { + if (ctx->c.timeout && ctx->ev.scheduleTimer && + (ctx->c.timeout->tv_sec || ctx->c.timeout->tv_usec)) { + ctx->ev.scheduleTimer(ctx->ev.data, *ctx->c.timeout); + // } else { + // printf("Not scheduling timer.. (tmo=%p)\n", ctx->c.timeout); + // if (ctx->c.timeout){ + // printf("tv_sec: %u. tv_usec: %u\n", ctx->c.timeout->tv_sec, + // ctx->c.timeout->tv_usec); + // } + } +} + +void __redisAsyncDisconnect(redisAsyncContext *ac); +void redisProcessCallbacks(redisAsyncContext *ac); + +#endif /* __HIREDIS_ASYNC_PRIVATE_H */ diff --git a/俱乐部/Source/hiredis/dict.c b/俱乐部/Source/hiredis/dict.c new file mode 100644 index 0000000..eaf4e4d --- /dev/null +++ b/俱乐部/Source/hiredis/dict.c @@ -0,0 +1,339 @@ +/* Hash table implementation. + * + * This file implements in memory hash tables with insert/del/replace/find/ + * get-random-element operations. Hash tables will auto resize if needed + * tables of power of two in size are used, collisions are handled by + * chaining. See the source code for more information... :) + * + * Copyright (c) 2006-2010, Salvatore Sanfilippo + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Redis nor the names of its contributors may 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. + */ + +#include "fmacros.h" +#include "alloc.h" +#include +#include +#include +#include "dict.h" + +/* -------------------------- private prototypes ---------------------------- */ + +static int _dictExpandIfNeeded(dict *ht); +static unsigned long _dictNextPower(unsigned long size); +static int _dictKeyIndex(dict *ht, const void *key); +static int _dictInit(dict *ht, dictType *type, void *privDataPtr); + +/* -------------------------- hash functions -------------------------------- */ + +/* Generic hash function (a popular one from Bernstein). + * I tested a few and this was the best. */ +static unsigned int dictGenHashFunction(const unsigned char *buf, int len) { + unsigned int hash = 5381; + + while (len--) + hash = ((hash << 5) + hash) + (*buf++); /* hash * 33 + c */ + return hash; +} + +/* ----------------------------- API implementation ------------------------- */ + +/* Reset an hashtable already initialized with ht_init(). + * NOTE: This function should only called by ht_destroy(). */ +static void _dictReset(dict *ht) { + ht->table = NULL; + ht->size = 0; + ht->sizemask = 0; + ht->used = 0; +} + +/* Create a new hash table */ +static dict *dictCreate(dictType *type, void *privDataPtr) { + dict *ht = hi_malloc(sizeof(*ht)); + _dictInit(ht,type,privDataPtr); + return ht; +} + +/* Initialize the hash table */ +static int _dictInit(dict *ht, dictType *type, void *privDataPtr) { + _dictReset(ht); + ht->type = type; + ht->privdata = privDataPtr; + return DICT_OK; +} + +/* Expand or create the hashtable */ +static int dictExpand(dict *ht, unsigned long size) { + dict n; /* the new hashtable */ + unsigned long realsize = _dictNextPower(size), i; + + /* the size is invalid if it is smaller than the number of + * elements already inside the hashtable */ + if (ht->used > size) + return DICT_ERR; + + _dictInit(&n, ht->type, ht->privdata); + n.size = realsize; + n.sizemask = realsize-1; + n.table = calloc(realsize,sizeof(dictEntry*)); + + /* Copy all the elements from the old to the new table: + * note that if the old hash table is empty ht->size is zero, + * so dictExpand just creates an hash table. */ + n.used = ht->used; + for (i = 0; i < ht->size && ht->used > 0; i++) { + dictEntry *he, *nextHe; + + if (ht->table[i] == NULL) continue; + + /* For each hash entry on this slot... */ + he = ht->table[i]; + while(he) { + unsigned int h; + + nextHe = he->next; + /* Get the new element index */ + h = dictHashKey(ht, he->key) & n.sizemask; + he->next = n.table[h]; + n.table[h] = he; + ht->used--; + /* Pass to the next element */ + he = nextHe; + } + } + assert(ht->used == 0); + free(ht->table); + + /* Remap the new hashtable in the old */ + *ht = n; + return DICT_OK; +} + +/* Add an element to the target hash table */ +static int dictAdd(dict *ht, void *key, void *val) { + int index; + dictEntry *entry; + + /* Get the index of the new element, or -1 if + * the element already exists. */ + if ((index = _dictKeyIndex(ht, key)) == -1) + return DICT_ERR; + + /* Allocates the memory and stores key */ + entry = hi_malloc(sizeof(*entry)); + entry->next = ht->table[index]; + ht->table[index] = entry; + + /* Set the hash entry fields. */ + dictSetHashKey(ht, entry, key); + dictSetHashVal(ht, entry, val); + ht->used++; + return DICT_OK; +} + +/* Add an element, discarding the old if the key already exists. + * Return 1 if the key was added from scratch, 0 if there was already an + * element with such key and dictReplace() just performed a value update + * operation. */ +static int dictReplace(dict *ht, void *key, void *val) { + dictEntry *entry, auxentry; + + /* Try to add the element. If the key + * does not exists dictAdd will succeed. */ + if (dictAdd(ht, key, val) == DICT_OK) + return 1; + /* It already exists, get the entry */ + entry = dictFind(ht, key); + /* Free the old value and set the new one */ + /* Set the new value and free the old one. Note that it is important + * to do that in this order, as the value may just be exactly the same + * as the previous one. In this context, think to reference counting, + * you want to increment (set), and then decrement (free), and not the + * reverse. */ + auxentry = *entry; + dictSetHashVal(ht, entry, val); + dictFreeEntryVal(ht, &auxentry); + return 0; +} + +/* Search and remove an element */ +static int dictDelete(dict *ht, const void *key) { + unsigned int h; + dictEntry *de, *prevde; + + if (ht->size == 0) + return DICT_ERR; + h = dictHashKey(ht, key) & ht->sizemask; + de = ht->table[h]; + + prevde = NULL; + while(de) { + if (dictCompareHashKeys(ht,key,de->key)) { + /* Unlink the element from the list */ + if (prevde) + prevde->next = de->next; + else + ht->table[h] = de->next; + + dictFreeEntryKey(ht,de); + dictFreeEntryVal(ht,de); + free(de); + ht->used--; + return DICT_OK; + } + prevde = de; + de = de->next; + } + return DICT_ERR; /* not found */ +} + +/* Destroy an entire hash table */ +static int _dictClear(dict *ht) { + unsigned long i; + + /* Free all the elements */ + for (i = 0; i < ht->size && ht->used > 0; i++) { + dictEntry *he, *nextHe; + + if ((he = ht->table[i]) == NULL) continue; + while(he) { + nextHe = he->next; + dictFreeEntryKey(ht, he); + dictFreeEntryVal(ht, he); + free(he); + ht->used--; + he = nextHe; + } + } + /* Free the table and the allocated cache structure */ + free(ht->table); + /* Re-initialize the table */ + _dictReset(ht); + return DICT_OK; /* never fails */ +} + +/* Clear & Release the hash table */ +static void dictRelease(dict *ht) { + _dictClear(ht); + free(ht); +} + +static dictEntry *dictFind(dict *ht, const void *key) { + dictEntry *he; + unsigned int h; + + if (ht->size == 0) return NULL; + h = dictHashKey(ht, key) & ht->sizemask; + he = ht->table[h]; + while(he) { + if (dictCompareHashKeys(ht, key, he->key)) + return he; + he = he->next; + } + return NULL; +} + +static dictIterator *dictGetIterator(dict *ht) { + dictIterator *iter = hi_malloc(sizeof(*iter)); + + iter->ht = ht; + iter->index = -1; + iter->entry = NULL; + iter->nextEntry = NULL; + return iter; +} + +static dictEntry *dictNext(dictIterator *iter) { + while (1) { + if (iter->entry == NULL) { + iter->index++; + if (iter->index >= + (signed)iter->ht->size) break; + iter->entry = iter->ht->table[iter->index]; + } else { + iter->entry = iter->nextEntry; + } + if (iter->entry) { + /* We need to save the 'next' here, the iterator user + * may delete the entry we are returning. */ + iter->nextEntry = iter->entry->next; + return iter->entry; + } + } + return NULL; +} + +static void dictReleaseIterator(dictIterator *iter) { + free(iter); +} + +/* ------------------------- private functions ------------------------------ */ + +/* Expand the hash table if needed */ +static int _dictExpandIfNeeded(dict *ht) { + /* If the hash table is empty expand it to the initial size, + * if the table is "full" double its size. */ + if (ht->size == 0) + return dictExpand(ht, DICT_HT_INITIAL_SIZE); + if (ht->used == ht->size) + return dictExpand(ht, ht->size*2); + return DICT_OK; +} + +/* Our hash table capability is a power of two */ +static unsigned long _dictNextPower(unsigned long size) { + unsigned long i = DICT_HT_INITIAL_SIZE; + + if (size >= LONG_MAX) return LONG_MAX; + while(1) { + if (i >= size) + return i; + i *= 2; + } +} + +/* Returns the index of a free slot that can be populated with + * an hash entry for the given 'key'. + * If the key already exists, -1 is returned. */ +static int _dictKeyIndex(dict *ht, const void *key) { + unsigned int h; + dictEntry *he; + + /* Expand the hashtable if needed */ + if (_dictExpandIfNeeded(ht) == DICT_ERR) + return -1; + /* Compute the key hash value */ + h = dictHashKey(ht, key) & ht->sizemask; + /* Search if this slot does not already contain the given key */ + he = ht->table[h]; + while(he) { + if (dictCompareHashKeys(ht, key, he->key)) + return -1; + he = he->next; + } + return h; +} + diff --git a/俱乐部/Source/hiredis/dict.h b/俱乐部/Source/hiredis/dict.h new file mode 100644 index 0000000..95fcd28 --- /dev/null +++ b/俱乐部/Source/hiredis/dict.h @@ -0,0 +1,126 @@ +/* Hash table implementation. + * + * This file implements in memory hash tables with insert/del/replace/find/ + * get-random-element operations. Hash tables will auto resize if needed + * tables of power of two in size are used, collisions are handled by + * chaining. See the source code for more information... :) + * + * Copyright (c) 2006-2010, Salvatore Sanfilippo + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Redis nor the names of its contributors may 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. + */ + +#ifndef __DICT_H +#define __DICT_H + +#define DICT_OK 0 +#define DICT_ERR 1 + +/* Unused arguments generate annoying warnings... */ +#define DICT_NOTUSED(V) ((void) V) + +typedef struct dictEntry { + void *key; + void *val; + struct dictEntry *next; +} dictEntry; + +typedef struct dictType { + unsigned int (*hashFunction)(const void *key); + void *(*keyDup)(void *privdata, const void *key); + void *(*valDup)(void *privdata, const void *obj); + int (*keyCompare)(void *privdata, const void *key1, const void *key2); + void (*keyDestructor)(void *privdata, void *key); + void (*valDestructor)(void *privdata, void *obj); +} dictType; + +typedef struct dict { + dictEntry **table; + dictType *type; + unsigned long size; + unsigned long sizemask; + unsigned long used; + void *privdata; +} dict; + +typedef struct dictIterator { + dict *ht; + int index; + dictEntry *entry, *nextEntry; +} dictIterator; + +/* This is the initial size of every hash table */ +#define DICT_HT_INITIAL_SIZE 4 + +/* ------------------------------- Macros ------------------------------------*/ +#define dictFreeEntryVal(ht, entry) \ + if ((ht)->type->valDestructor) \ + (ht)->type->valDestructor((ht)->privdata, (entry)->val) + +#define dictSetHashVal(ht, entry, _val_) do { \ + if ((ht)->type->valDup) \ + entry->val = (ht)->type->valDup((ht)->privdata, _val_); \ + else \ + entry->val = (_val_); \ +} while(0) + +#define dictFreeEntryKey(ht, entry) \ + if ((ht)->type->keyDestructor) \ + (ht)->type->keyDestructor((ht)->privdata, (entry)->key) + +#define dictSetHashKey(ht, entry, _key_) do { \ + if ((ht)->type->keyDup) \ + entry->key = (ht)->type->keyDup((ht)->privdata, _key_); \ + else \ + entry->key = (_key_); \ +} while(0) + +#define dictCompareHashKeys(ht, key1, key2) \ + (((ht)->type->keyCompare) ? \ + (ht)->type->keyCompare((ht)->privdata, key1, key2) : \ + (key1) == (key2)) + +#define dictHashKey(ht, key) (ht)->type->hashFunction(key) + +#define dictGetEntryKey(he) ((he)->key) +#define dictGetEntryVal(he) ((he)->val) +#define dictSlots(ht) ((ht)->size) +#define dictSize(ht) ((ht)->used) + +/* API */ +static unsigned int dictGenHashFunction(const unsigned char *buf, int len); +static dict *dictCreate(dictType *type, void *privDataPtr); +static int dictExpand(dict *ht, unsigned long size); +static int dictAdd(dict *ht, void *key, void *val); +static int dictReplace(dict *ht, void *key, void *val); +static int dictDelete(dict *ht, const void *key); +static void dictRelease(dict *ht); +static dictEntry * dictFind(dict *ht, const void *key); +static dictIterator *dictGetIterator(dict *ht); +static dictEntry *dictNext(dictIterator *iter); +static void dictReleaseIterator(dictIterator *iter); + +#endif /* __DICT_H */ diff --git a/俱乐部/Source/hiredis/examples/example-ae.c b/俱乐部/Source/hiredis/examples/example-ae.c new file mode 100644 index 0000000..8efa730 --- /dev/null +++ b/俱乐部/Source/hiredis/examples/example-ae.c @@ -0,0 +1,62 @@ +#include +#include +#include +#include + +#include +#include +#include + +/* Put event loop in the global scope, so it can be explicitly stopped */ +static aeEventLoop *loop; + +void getCallback(redisAsyncContext *c, void *r, void *privdata) { + redisReply *reply = r; + if (reply == NULL) return; + printf("argv[%s]: %s\n", (char*)privdata, reply->str); + + /* Disconnect after receiving the reply to GET */ + redisAsyncDisconnect(c); +} + +void connectCallback(const redisAsyncContext *c, int status) { + if (status != REDIS_OK) { + printf("Error: %s\n", c->errstr); + aeStop(loop); + return; + } + + printf("Connected...\n"); +} + +void disconnectCallback(const redisAsyncContext *c, int status) { + if (status != REDIS_OK) { + printf("Error: %s\n", c->errstr); + aeStop(loop); + return; + } + + printf("Disconnected...\n"); + aeStop(loop); +} + +int main (int argc, char **argv) { + signal(SIGPIPE, SIG_IGN); + + redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379); + if (c->err) { + /* Let *c leak for now... */ + printf("Error: %s\n", c->errstr); + return 1; + } + + loop = aeCreateEventLoop(64); + redisAeAttach(loop, c); + redisAsyncSetConnectCallback(c,connectCallback); + redisAsyncSetDisconnectCallback(c,disconnectCallback); + redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1])); + redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); + aeMain(loop); + return 0; +} + diff --git a/俱乐部/Source/hiredis/examples/example-glib.c b/俱乐部/Source/hiredis/examples/example-glib.c new file mode 100644 index 0000000..d6e10f8 --- /dev/null +++ b/俱乐部/Source/hiredis/examples/example-glib.c @@ -0,0 +1,73 @@ +#include + +#include +#include +#include + +static GMainLoop *mainloop; + +static void +connect_cb (const redisAsyncContext *ac G_GNUC_UNUSED, + int status) +{ + if (status != REDIS_OK) { + g_printerr("Failed to connect: %s\n", ac->errstr); + g_main_loop_quit(mainloop); + } else { + g_printerr("Connected...\n"); + } +} + +static void +disconnect_cb (const redisAsyncContext *ac G_GNUC_UNUSED, + int status) +{ + if (status != REDIS_OK) { + g_error("Failed to disconnect: %s", ac->errstr); + } else { + g_printerr("Disconnected...\n"); + g_main_loop_quit(mainloop); + } +} + +static void +command_cb(redisAsyncContext *ac, + gpointer r, + gpointer user_data G_GNUC_UNUSED) +{ + redisReply *reply = r; + + if (reply) { + g_print("REPLY: %s\n", reply->str); + } + + redisAsyncDisconnect(ac); +} + +gint +main (gint argc G_GNUC_UNUSED, + gchar *argv[] G_GNUC_UNUSED) +{ + redisAsyncContext *ac; + GMainContext *context = NULL; + GSource *source; + + ac = redisAsyncConnect("127.0.0.1", 6379); + if (ac->err) { + g_printerr("%s\n", ac->errstr); + exit(EXIT_FAILURE); + } + + source = redis_source_new(ac); + mainloop = g_main_loop_new(context, FALSE); + g_source_attach(source, context); + + redisAsyncSetConnectCallback(ac, connect_cb); + redisAsyncSetDisconnectCallback(ac, disconnect_cb); + redisAsyncCommand(ac, command_cb, NULL, "SET key 1234"); + redisAsyncCommand(ac, command_cb, NULL, "GET key"); + + g_main_loop_run(mainloop); + + return EXIT_SUCCESS; +} diff --git a/俱乐部/Source/hiredis/examples/example-ivykis.c b/俱乐部/Source/hiredis/examples/example-ivykis.c new file mode 100644 index 0000000..67affce --- /dev/null +++ b/俱乐部/Source/hiredis/examples/example-ivykis.c @@ -0,0 +1,58 @@ +#include +#include +#include +#include + +#include +#include +#include + +void getCallback(redisAsyncContext *c, void *r, void *privdata) { + redisReply *reply = r; + if (reply == NULL) return; + printf("argv[%s]: %s\n", (char*)privdata, reply->str); + + /* Disconnect after receiving the reply to GET */ + redisAsyncDisconnect(c); +} + +void connectCallback(const redisAsyncContext *c, int status) { + if (status != REDIS_OK) { + printf("Error: %s\n", c->errstr); + return; + } + printf("Connected...\n"); +} + +void disconnectCallback(const redisAsyncContext *c, int status) { + if (status != REDIS_OK) { + printf("Error: %s\n", c->errstr); + return; + } + printf("Disconnected...\n"); +} + +int main (int argc, char **argv) { + signal(SIGPIPE, SIG_IGN); + + iv_init(); + + redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379); + if (c->err) { + /* Let *c leak for now... */ + printf("Error: %s\n", c->errstr); + return 1; + } + + redisIvykisAttach(c); + redisAsyncSetConnectCallback(c,connectCallback); + redisAsyncSetDisconnectCallback(c,disconnectCallback); + redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1])); + redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); + + iv_main(); + + iv_deinit(); + + return 0; +} diff --git a/俱乐部/Source/hiredis/examples/example-libev.c b/俱乐部/Source/hiredis/examples/example-libev.c new file mode 100644 index 0000000..cc8b166 --- /dev/null +++ b/俱乐部/Source/hiredis/examples/example-libev.c @@ -0,0 +1,52 @@ +#include +#include +#include +#include + +#include +#include +#include + +void getCallback(redisAsyncContext *c, void *r, void *privdata) { + redisReply *reply = r; + if (reply == NULL) return; + printf("argv[%s]: %s\n", (char*)privdata, reply->str); + + /* Disconnect after receiving the reply to GET */ + redisAsyncDisconnect(c); +} + +void connectCallback(const redisAsyncContext *c, int status) { + if (status != REDIS_OK) { + printf("Error: %s\n", c->errstr); + return; + } + printf("Connected...\n"); +} + +void disconnectCallback(const redisAsyncContext *c, int status) { + if (status != REDIS_OK) { + printf("Error: %s\n", c->errstr); + return; + } + printf("Disconnected...\n"); +} + +int main (int argc, char **argv) { + signal(SIGPIPE, SIG_IGN); + + redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379); + if (c->err) { + /* Let *c leak for now... */ + printf("Error: %s\n", c->errstr); + return 1; + } + + redisLibevAttach(EV_DEFAULT_ c); + redisAsyncSetConnectCallback(c,connectCallback); + redisAsyncSetDisconnectCallback(c,disconnectCallback); + redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1])); + redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); + ev_loop(EV_DEFAULT_ 0); + return 0; +} diff --git a/俱乐部/Source/hiredis/examples/example-libevent-ssl.c b/俱乐部/Source/hiredis/examples/example-libevent-ssl.c new file mode 100644 index 0000000..1021113 --- /dev/null +++ b/俱乐部/Source/hiredis/examples/example-libevent-ssl.c @@ -0,0 +1,73 @@ +#include +#include +#include +#include + +#include +#include +#include +#include + +void getCallback(redisAsyncContext *c, void *r, void *privdata) { + redisReply *reply = r; + if (reply == NULL) return; + printf("argv[%s]: %s\n", (char*)privdata, reply->str); + + /* Disconnect after receiving the reply to GET */ + redisAsyncDisconnect(c); +} + +void connectCallback(const redisAsyncContext *c, int status) { + if (status != REDIS_OK) { + printf("Error: %s\n", c->errstr); + return; + } + printf("Connected...\n"); +} + +void disconnectCallback(const redisAsyncContext *c, int status) { + if (status != REDIS_OK) { + printf("Error: %s\n", c->errstr); + return; + } + printf("Disconnected...\n"); +} + +int main (int argc, char **argv) { + signal(SIGPIPE, SIG_IGN); + struct event_base *base = event_base_new(); + if (argc < 5) { + fprintf(stderr, + "Usage: %s [ca]\n", argv[0]); + exit(1); + } + + const char *value = argv[1]; + size_t nvalue = strlen(value); + + const char *hostname = argv[2]; + int port = atoi(argv[3]); + + const char *cert = argv[4]; + const char *certKey = argv[5]; + const char *caCert = argc > 5 ? argv[6] : NULL; + + redisAsyncContext *c = redisAsyncConnect(hostname, port); + if (c->err) { + /* Let *c leak for now... */ + printf("Error: %s\n", c->errstr); + return 1; + } + if (redisSecureConnection(&c->c, caCert, cert, certKey, "sni") != REDIS_OK) { + printf("SSL Error!\n"); + exit(1); + } + + redisLibeventAttach(c,base); + redisAsyncSetConnectCallback(c,connectCallback); + redisAsyncSetDisconnectCallback(c,disconnectCallback); + redisAsyncCommand(c, NULL, NULL, "SET key %b", value, nvalue); + redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); + event_base_dispatch(base); + return 0; +} diff --git a/俱乐部/Source/hiredis/examples/example-libevent.c b/俱乐部/Source/hiredis/examples/example-libevent.c new file mode 100644 index 0000000..1fe71ae --- /dev/null +++ b/俱乐部/Source/hiredis/examples/example-libevent.c @@ -0,0 +1,64 @@ +#include +#include +#include +#include + +#include +#include +#include + +void getCallback(redisAsyncContext *c, void *r, void *privdata) { + redisReply *reply = r; + if (reply == NULL) { + if (c->errstr) { + printf("errstr: %s\n", c->errstr); + } + return; + } + printf("argv[%s]: %s\n", (char*)privdata, reply->str); + + /* Disconnect after receiving the reply to GET */ + redisAsyncDisconnect(c); +} + +void connectCallback(const redisAsyncContext *c, int status) { + if (status != REDIS_OK) { + printf("Error: %s\n", c->errstr); + return; + } + printf("Connected...\n"); +} + +void disconnectCallback(const redisAsyncContext *c, int status) { + if (status != REDIS_OK) { + printf("Error: %s\n", c->errstr); + return; + } + printf("Disconnected...\n"); +} + +int main (int argc, char **argv) { + signal(SIGPIPE, SIG_IGN); + struct event_base *base = event_base_new(); + redisOptions options = {0}; + REDIS_OPTIONS_SET_TCP(&options, "127.0.0.1", 6379); + struct timeval tv = {0}; + tv.tv_sec = 1; + options.timeout = &tv; + + + redisAsyncContext *c = redisAsyncConnectWithOptions(&options); + if (c->err) { + /* Let *c leak for now... */ + printf("Error: %s\n", c->errstr); + return 1; + } + + redisLibeventAttach(c,base); + redisAsyncSetConnectCallback(c,connectCallback); + redisAsyncSetDisconnectCallback(c,disconnectCallback); + redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1])); + redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); + event_base_dispatch(base); + return 0; +} diff --git a/俱乐部/Source/hiredis/examples/example-libuv.c b/俱乐部/Source/hiredis/examples/example-libuv.c new file mode 100644 index 0000000..a5462d4 --- /dev/null +++ b/俱乐部/Source/hiredis/examples/example-libuv.c @@ -0,0 +1,53 @@ +#include +#include +#include +#include + +#include +#include +#include + +void getCallback(redisAsyncContext *c, void *r, void *privdata) { + redisReply *reply = r; + if (reply == NULL) return; + printf("argv[%s]: %s\n", (char*)privdata, reply->str); + + /* Disconnect after receiving the reply to GET */ + redisAsyncDisconnect(c); +} + +void connectCallback(const redisAsyncContext *c, int status) { + if (status != REDIS_OK) { + printf("Error: %s\n", c->errstr); + return; + } + printf("Connected...\n"); +} + +void disconnectCallback(const redisAsyncContext *c, int status) { + if (status != REDIS_OK) { + printf("Error: %s\n", c->errstr); + return; + } + printf("Disconnected...\n"); +} + +int main (int argc, char **argv) { + signal(SIGPIPE, SIG_IGN); + uv_loop_t* loop = uv_default_loop(); + + redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379); + if (c->err) { + /* Let *c leak for now... */ + printf("Error: %s\n", c->errstr); + return 1; + } + + redisLibuvAttach(c,loop); + redisAsyncSetConnectCallback(c,connectCallback); + redisAsyncSetDisconnectCallback(c,disconnectCallback); + redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1])); + redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); + uv_run(loop, UV_RUN_DEFAULT); + return 0; +} diff --git a/俱乐部/Source/hiredis/examples/example-macosx.c b/俱乐部/Source/hiredis/examples/example-macosx.c new file mode 100644 index 0000000..bc84ed5 --- /dev/null +++ b/俱乐部/Source/hiredis/examples/example-macosx.c @@ -0,0 +1,66 @@ +// +// Created by Дмитрий Бахвалов on 13.07.15. +// Copyright (c) 2015 Dmitry Bakhvalov. All rights reserved. +// + +#include + +#include +#include +#include + +void getCallback(redisAsyncContext *c, void *r, void *privdata) { + redisReply *reply = r; + if (reply == NULL) return; + printf("argv[%s]: %s\n", (char*)privdata, reply->str); + + /* Disconnect after receiving the reply to GET */ + redisAsyncDisconnect(c); +} + +void connectCallback(const redisAsyncContext *c, int status) { + if (status != REDIS_OK) { + printf("Error: %s\n", c->errstr); + return; + } + printf("Connected...\n"); +} + +void disconnectCallback(const redisAsyncContext *c, int status) { + if (status != REDIS_OK) { + printf("Error: %s\n", c->errstr); + return; + } + CFRunLoopStop(CFRunLoopGetCurrent()); + printf("Disconnected...\n"); +} + +int main (int argc, char **argv) { + signal(SIGPIPE, SIG_IGN); + + CFRunLoopRef loop = CFRunLoopGetCurrent(); + if( !loop ) { + printf("Error: Cannot get current run loop\n"); + return 1; + } + + redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379); + if (c->err) { + /* Let *c leak for now... */ + printf("Error: %s\n", c->errstr); + return 1; + } + + redisMacOSAttach(c, loop); + + redisAsyncSetConnectCallback(c,connectCallback); + redisAsyncSetDisconnectCallback(c,disconnectCallback); + + redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1])); + redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); + + CFRunLoopRun(); + + return 0; +} + diff --git a/俱乐部/Source/hiredis/examples/example-qt.cpp b/俱乐部/Source/hiredis/examples/example-qt.cpp new file mode 100644 index 0000000..f524c3f --- /dev/null +++ b/俱乐部/Source/hiredis/examples/example-qt.cpp @@ -0,0 +1,46 @@ +#include +using namespace std; + +#include +#include + +#include "example-qt.h" + +void getCallback(redisAsyncContext *, void * r, void * privdata) { + + redisReply * reply = static_cast(r); + ExampleQt * ex = static_cast(privdata); + if (reply == nullptr || ex == nullptr) return; + + cout << "key: " << reply->str << endl; + + ex->finish(); +} + +void ExampleQt::run() { + + m_ctx = redisAsyncConnect("localhost", 6379); + + if (m_ctx->err) { + cerr << "Error: " << m_ctx->errstr << endl; + redisAsyncFree(m_ctx); + emit finished(); + } + + m_adapter.setContext(m_ctx); + + redisAsyncCommand(m_ctx, NULL, NULL, "SET key %s", m_value); + redisAsyncCommand(m_ctx, getCallback, this, "GET key"); +} + +int main (int argc, char **argv) { + + QCoreApplication app(argc, argv); + + ExampleQt example(argv[argc-1]); + + QObject::connect(&example, SIGNAL(finished()), &app, SLOT(quit())); + QTimer::singleShot(0, &example, SLOT(run())); + + return app.exec(); +} diff --git a/俱乐部/Source/hiredis/examples/example-qt.h b/俱乐部/Source/hiredis/examples/example-qt.h new file mode 100644 index 0000000..374f476 --- /dev/null +++ b/俱乐部/Source/hiredis/examples/example-qt.h @@ -0,0 +1,32 @@ +#ifndef __HIREDIS_EXAMPLE_QT_H +#define __HIREDIS_EXAMPLE_QT_H + +#include + +class ExampleQt : public QObject { + + Q_OBJECT + + public: + ExampleQt(const char * value, QObject * parent = 0) + : QObject(parent), m_value(value) {} + + signals: + void finished(); + + public slots: + void run(); + + private: + void finish() { emit finished(); } + + private: + const char * m_value; + redisAsyncContext * m_ctx; + RedisQtAdapter m_adapter; + + friend + void getCallback(redisAsyncContext *, void *, void *); +}; + +#endif /* !__HIREDIS_EXAMPLE_QT_H */ diff --git a/俱乐部/Source/hiredis/examples/example-ssl.c b/俱乐部/Source/hiredis/examples/example-ssl.c new file mode 100644 index 0000000..81f4648 --- /dev/null +++ b/俱乐部/Source/hiredis/examples/example-ssl.c @@ -0,0 +1,97 @@ +#include +#include +#include + +#include +#include + +int main(int argc, char **argv) { + unsigned int j; + redisContext *c; + redisReply *reply; + if (argc < 4) { + printf("Usage: %s [ca]\n", argv[0]); + exit(1); + } + const char *hostname = (argc > 1) ? argv[1] : "127.0.0.1"; + int port = atoi(argv[2]); + const char *cert = argv[3]; + const char *key = argv[4]; + const char *ca = argc > 4 ? argv[5] : NULL; + + struct timeval tv = { 1, 500000 }; // 1.5 seconds + redisOptions options = {0}; + REDIS_OPTIONS_SET_TCP(&options, hostname, port); + options.timeout = &tv; + c = redisConnectWithOptions(&options); + + if (c == NULL || c->err) { + if (c) { + printf("Connection error: %s\n", c->errstr); + redisFree(c); + } else { + printf("Connection error: can't allocate redis context\n"); + } + exit(1); + } + + if (redisSecureConnection(c, ca, cert, key, "sni") != REDIS_OK) { + printf("Couldn't initialize SSL!\n"); + printf("Error: %s\n", c->errstr); + redisFree(c); + exit(1); + } + + /* PING server */ + reply = redisCommand(c,"PING"); + printf("PING: %s\n", reply->str); + freeReplyObject(reply); + + /* Set a key */ + reply = redisCommand(c,"SET %s %s", "foo", "hello world"); + printf("SET: %s\n", reply->str); + freeReplyObject(reply); + + /* Set a key using binary safe API */ + reply = redisCommand(c,"SET %b %b", "bar", (size_t) 3, "hello", (size_t) 5); + printf("SET (binary API): %s\n", reply->str); + freeReplyObject(reply); + + /* Try a GET and two INCR */ + reply = redisCommand(c,"GET foo"); + printf("GET foo: %s\n", reply->str); + freeReplyObject(reply); + + reply = redisCommand(c,"INCR counter"); + printf("INCR counter: %lld\n", reply->integer); + freeReplyObject(reply); + /* again ... */ + reply = redisCommand(c,"INCR counter"); + printf("INCR counter: %lld\n", reply->integer); + freeReplyObject(reply); + + /* Create a list of numbers, from 0 to 9 */ + reply = redisCommand(c,"DEL mylist"); + freeReplyObject(reply); + for (j = 0; j < 10; j++) { + char buf[64]; + + snprintf(buf,64,"%u",j); + reply = redisCommand(c,"LPUSH mylist element-%s", buf); + freeReplyObject(reply); + } + + /* Let's check what we have inside the list */ + reply = redisCommand(c,"LRANGE mylist 0 -1"); + if (reply->type == REDIS_REPLY_ARRAY) { + for (j = 0; j < reply->elements; j++) { + printf("%u) %s\n", j, reply->element[j]->str); + } + } + freeReplyObject(reply); + + /* Disconnects and frees the context */ + redisFree(c); + + return 0; +} diff --git a/俱乐部/Source/hiredis/examples/example.c b/俱乐部/Source/hiredis/examples/example.c new file mode 100644 index 0000000..0e93fc8 --- /dev/null +++ b/俱乐部/Source/hiredis/examples/example.c @@ -0,0 +1,91 @@ +#include +#include +#include + +#include + +int main(int argc, char **argv) { + unsigned int j, isunix = 0; + redisContext *c; + redisReply *reply; + const char *hostname = (argc > 1) ? argv[1] : "127.0.0.1"; + + if (argc > 2) { + if (*argv[2] == 'u' || *argv[2] == 'U') { + isunix = 1; + /* in this case, host is the path to the unix socket */ + printf("Will connect to unix socket @%s\n", hostname); + } + } + + int port = (argc > 2) ? atoi(argv[2]) : 6379; + + struct timeval timeout = { 1, 500000 }; // 1.5 seconds + if (isunix) { + c = redisConnectUnixWithTimeout(hostname, timeout); + } else { + c = redisConnectWithTimeout(hostname, port, timeout); + } + if (c == NULL || c->err) { + if (c) { + printf("Connection error: %s\n", c->errstr); + redisFree(c); + } else { + printf("Connection error: can't allocate redis context\n"); + } + exit(1); + } + + /* PING server */ + reply = redisCommand(c,"PING"); + printf("PING: %s\n", reply->str); + freeReplyObject(reply); + + /* Set a key */ + reply = redisCommand(c,"SET %s %s", "foo", "hello world"); + printf("SET: %s\n", reply->str); + freeReplyObject(reply); + + /* Set a key using binary safe API */ + reply = redisCommand(c,"SET %b %b", "bar", (size_t) 3, "hello", (size_t) 5); + printf("SET (binary API): %s\n", reply->str); + freeReplyObject(reply); + + /* Try a GET and two INCR */ + reply = redisCommand(c,"GET foo"); + printf("GET foo: %s\n", reply->str); + freeReplyObject(reply); + + reply = redisCommand(c,"INCR counter"); + printf("INCR counter: %lld\n", reply->integer); + freeReplyObject(reply); + /* again ... */ + reply = redisCommand(c,"INCR counter"); + printf("INCR counter: %lld\n", reply->integer); + freeReplyObject(reply); + + /* Create a list of numbers, from 0 to 9 */ + reply = redisCommand(c,"DEL mylist"); + freeReplyObject(reply); + for (j = 0; j < 10; j++) { + char buf[64]; + + snprintf(buf,64,"%u",j); + reply = redisCommand(c,"LPUSH mylist element-%s", buf); + freeReplyObject(reply); + } + + /* Let's check what we have inside the list */ + reply = redisCommand(c,"LRANGE mylist 0 -1"); + if (reply->type == REDIS_REPLY_ARRAY) { + for (j = 0; j < reply->elements; j++) { + printf("%u) %s\n", j, reply->element[j]->str); + } + } + freeReplyObject(reply); + + /* Disconnects and frees the context */ + redisFree(c); + + return 0; +} diff --git a/俱乐部/Source/hiredis/fmacros.h b/俱乐部/Source/hiredis/fmacros.h new file mode 100644 index 0000000..3227faa --- /dev/null +++ b/俱乐部/Source/hiredis/fmacros.h @@ -0,0 +1,12 @@ +#ifndef __HIREDIS_FMACRO_H +#define __HIREDIS_FMACRO_H + +#define _XOPEN_SOURCE 600 +#define _POSIX_C_SOURCE 200112L + +#if defined(__APPLE__) && defined(__MACH__) +/* Enable TCP_KEEPALIVE */ +#define _DARWIN_C_SOURCE +#endif + +#endif diff --git a/俱乐部/Source/hiredis/hiredis.c b/俱乐部/Source/hiredis/hiredis.c new file mode 100644 index 0000000..8e438f2 --- /dev/null +++ b/俱乐部/Source/hiredis/hiredis.c @@ -0,0 +1,1078 @@ +/* + * Copyright (c) 2009-2011, Salvatore Sanfilippo + * Copyright (c) 2010-2014, Pieter Noordhuis + * Copyright (c) 2015, Matt Stancliff , + * Jan-Erik Rediger + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Redis nor the names of its contributors may 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. + */ + +#include "fmacros.h" +#include +#include +#include +#include +#include + +#include "hiredis.h" +#include "net.h" +#include "sds.h" +#include "async.h" +#include "win32.h" + +static redisContextFuncs redisContextDefaultFuncs = { + .free_privdata = NULL, + .async_read = redisAsyncRead, + .async_write = redisAsyncWrite, + .read = redisNetRead, + .write = redisNetWrite +}; + +static redisReply *createReplyObject(int type); +static void *createStringObject(const redisReadTask *task, char *str, size_t len); +static void *createArrayObject(const redisReadTask *task, size_t elements); +static void *createIntegerObject(const redisReadTask *task, long long value); +static void *createDoubleObject(const redisReadTask *task, double value, char *str, size_t len); +static void *createNilObject(const redisReadTask *task); +static void *createBoolObject(const redisReadTask *task, int bval); + +/* Default set of functions to build the reply. Keep in mind that such a + * function returning NULL is interpreted as OOM. */ +static redisReplyObjectFunctions defaultFunctions = { + createStringObject, + createArrayObject, + createIntegerObject, + createDoubleObject, + createNilObject, + createBoolObject, + freeReplyObject +}; + +/* Create a reply object */ +static redisReply *createReplyObject(int type) { + redisReply *r = calloc(1,sizeof(*r)); + + if (r == NULL) + return NULL; + + r->type = type; + return r; +} + +/* Free a reply object */ +void freeReplyObject(void *reply) { + redisReply *r = reply; + size_t j; + + if (r == NULL) + return; + + switch(r->type) { + case REDIS_REPLY_INTEGER: + break; /* Nothing to free */ + case REDIS_REPLY_ARRAY: + case REDIS_REPLY_MAP: + case REDIS_REPLY_SET: + if (r->element != NULL) { + for (j = 0; j < r->elements; j++) + freeReplyObject(r->element[j]); + free(r->element); + } + break; + case REDIS_REPLY_ERROR: + case REDIS_REPLY_STATUS: + case REDIS_REPLY_STRING: + case REDIS_REPLY_DOUBLE: + free(r->str); + break; + } + free(r); +} + +static void *createStringObject(const redisReadTask *task, char *str, size_t len) { + redisReply *r, *parent; + char *buf; + + r = createReplyObject(task->type); + if (r == NULL) + return NULL; + + buf = malloc(len+1); + if (buf == NULL) { + freeReplyObject(r); + return NULL; + } + + assert(task->type == REDIS_REPLY_ERROR || + task->type == REDIS_REPLY_STATUS || + task->type == REDIS_REPLY_STRING); + + /* Copy string value */ + memcpy(buf,str,len); + buf[len] = '\0'; + r->str = buf; + r->len = len; + + if (task->parent) { + parent = task->parent->obj; + assert(parent->type == REDIS_REPLY_ARRAY || + parent->type == REDIS_REPLY_MAP || + parent->type == REDIS_REPLY_SET); + parent->element[task->idx] = r; + } + return r; +} + +static void *createArrayObject(const redisReadTask *task, size_t elements) { + redisReply *r, *parent; + + r = createReplyObject(task->type); + if (r == NULL) + return NULL; + + if (elements > 0) { + r->element = calloc(elements,sizeof(redisReply*)); + if (r->element == NULL) { + freeReplyObject(r); + return NULL; + } + } + + r->elements = elements; + + if (task->parent) { + parent = task->parent->obj; + assert(parent->type == REDIS_REPLY_ARRAY || + parent->type == REDIS_REPLY_MAP || + parent->type == REDIS_REPLY_SET); + parent->element[task->idx] = r; + } + return r; +} + +static void *createIntegerObject(const redisReadTask *task, long long value) { + redisReply *r, *parent; + + r = createReplyObject(REDIS_REPLY_INTEGER); + if (r == NULL) + return NULL; + + r->integer = value; + + if (task->parent) { + parent = task->parent->obj; + assert(parent->type == REDIS_REPLY_ARRAY || + parent->type == REDIS_REPLY_MAP || + parent->type == REDIS_REPLY_SET); + parent->element[task->idx] = r; + } + return r; +} + +static void *createDoubleObject(const redisReadTask *task, double value, char *str, size_t len) { + redisReply *r, *parent; + + r = createReplyObject(REDIS_REPLY_DOUBLE); + if (r == NULL) + return NULL; + + r->dval = value; + r->str = malloc(len+1); + if (r->str == NULL) { + freeReplyObject(r); + return NULL; + } + + /* The double reply also has the original protocol string representing a + * double as a null terminated string. This way the caller does not need + * to format back for string conversion, especially since Redis does efforts + * to make the string more human readable avoiding the calssical double + * decimal string conversion artifacts. */ + memcpy(r->str, str, len); + r->str[len] = '\0'; + + if (task->parent) { + parent = task->parent->obj; + assert(parent->type == REDIS_REPLY_ARRAY || + parent->type == REDIS_REPLY_MAP || + parent->type == REDIS_REPLY_SET); + parent->element[task->idx] = r; + } + return r; +} + +static void *createNilObject(const redisReadTask *task) { + redisReply *r, *parent; + + r = createReplyObject(REDIS_REPLY_NIL); + if (r == NULL) + return NULL; + + if (task->parent) { + parent = task->parent->obj; + assert(parent->type == REDIS_REPLY_ARRAY || + parent->type == REDIS_REPLY_MAP || + parent->type == REDIS_REPLY_SET); + parent->element[task->idx] = r; + } + return r; +} + +static void *createBoolObject(const redisReadTask *task, int bval) { + redisReply *r, *parent; + + r = createReplyObject(REDIS_REPLY_BOOL); + if (r == NULL) + return NULL; + + r->integer = bval != 0; + + if (task->parent) { + parent = task->parent->obj; + assert(parent->type == REDIS_REPLY_ARRAY || + parent->type == REDIS_REPLY_MAP || + parent->type == REDIS_REPLY_SET); + parent->element[task->idx] = r; + } + return r; +} + +/* Return the number of digits of 'v' when converted to string in radix 10. + * Implementation borrowed from link in redis/src/util.c:string2ll(). */ +static uint32_t countDigits(uint64_t v) { + uint32_t result = 1; + for (;;) { + if (v < 10) return result; + if (v < 100) return result + 1; + if (v < 1000) return result + 2; + if (v < 10000) return result + 3; + v /= 10000U; + result += 4; + } +} + +/* Helper that calculates the bulk length given a certain string length. */ +static size_t bulklen(size_t len) { + return 1+countDigits(len)+2+len+2; +} + +int redisvFormatCommand(char **target, const char *format, va_list ap) { + const char *c = format; + char *cmd = NULL; /* final command */ + int pos; /* position in final command */ + sds curarg, newarg; /* current argument */ + int touched = 0; /* was the current argument touched? */ + char **curargv = NULL, **newargv = NULL; + int argc = 0; + int totlen = 0; + int error_type = 0; /* 0 = no error; -1 = memory error; -2 = format error */ + int j; + + /* Abort if there is not target to set */ + if (target == NULL) + return -1; + + /* Build the command string accordingly to protocol */ + curarg = sdsempty(); + if (curarg == NULL) + return -1; + + while(*c != '\0') { + if (*c != '%' || c[1] == '\0') { + if (*c == ' ') { + if (touched) { + newargv = realloc(curargv,sizeof(char*)*(argc+1)); + if (newargv == NULL) goto memory_err; + curargv = newargv; + curargv[argc++] = curarg; + totlen += bulklen(sdslen(curarg)); + + /* curarg is put in argv so it can be overwritten. */ + curarg = sdsempty(); + if (curarg == NULL) goto memory_err; + touched = 0; + } + } else { + newarg = sdscatlen(curarg,c,1); + if (newarg == NULL) goto memory_err; + curarg = newarg; + touched = 1; + } + } else { + char *arg; + size_t size; + + /* Set newarg so it can be checked even if it is not touched. */ + newarg = curarg; + + switch(c[1]) { + case 's': + arg = va_arg(ap,char*); + size = strlen(arg); + if (size > 0) + newarg = sdscatlen(curarg,arg,size); + break; + case 'b': + arg = va_arg(ap,char*); + size = va_arg(ap,size_t); + if (size > 0) + newarg = sdscatlen(curarg,arg,size); + break; + case '%': + newarg = sdscat(curarg,"%"); + break; + default: + /* Try to detect printf format */ + { + static const char intfmts[] = "diouxX"; + static const char flags[] = "#0-+ "; + char _format[16]; + const char *_p = c+1; + size_t _l = 0; + va_list _cpy; + + /* Flags */ + while (*_p != '\0' && strchr(flags,*_p) != NULL) _p++; + + /* Field width */ + while (*_p != '\0' && isdigit(*_p)) _p++; + + /* Precision */ + if (*_p == '.') { + _p++; + while (*_p != '\0' && isdigit(*_p)) _p++; + } + + /* Copy va_list before consuming with va_arg */ + va_copy(_cpy,ap); + + /* Integer conversion (without modifiers) */ + if (strchr(intfmts,*_p) != NULL) { + va_arg(ap,int); + goto fmt_valid; + } + + /* Double conversion (without modifiers) */ + if (strchr("eEfFgGaA",*_p) != NULL) { + va_arg(ap,double); + goto fmt_valid; + } + + /* Size: char */ + if (_p[0] == 'h' && _p[1] == 'h') { + _p += 2; + if (*_p != '\0' && strchr(intfmts,*_p) != NULL) { + va_arg(ap,int); /* char gets promoted to int */ + goto fmt_valid; + } + goto fmt_invalid; + } + + /* Size: short */ + if (_p[0] == 'h') { + _p += 1; + if (*_p != '\0' && strchr(intfmts,*_p) != NULL) { + va_arg(ap,int); /* short gets promoted to int */ + goto fmt_valid; + } + goto fmt_invalid; + } + + /* Size: long long */ + if (_p[0] == 'l' && _p[1] == 'l') { + _p += 2; + if (*_p != '\0' && strchr(intfmts,*_p) != NULL) { + va_arg(ap,long long); + goto fmt_valid; + } + goto fmt_invalid; + } + + /* Size: long */ + if (_p[0] == 'l') { + _p += 1; + if (*_p != '\0' && strchr(intfmts,*_p) != NULL) { + va_arg(ap,long); + goto fmt_valid; + } + goto fmt_invalid; + } + + fmt_invalid: + va_end(_cpy); + goto format_err; + + fmt_valid: + _l = (_p+1)-c; + if (_l < sizeof(_format)-2) { + memcpy(_format,c,_l); + _format[_l] = '\0'; + newarg = sdscatvprintf(curarg,_format,_cpy); + + /* Update current position (note: outer blocks + * increment c twice so compensate here) */ + c = _p-1; + } + + va_end(_cpy); + break; + } + } + + if (newarg == NULL) goto memory_err; + curarg = newarg; + + touched = 1; + c++; + } + c++; + } + + /* Add the last argument if needed */ + if (touched) { + newargv = realloc(curargv,sizeof(char*)*(argc+1)); + if (newargv == NULL) goto memory_err; + curargv = newargv; + curargv[argc++] = curarg; + totlen += bulklen(sdslen(curarg)); + } else { + sdsfree(curarg); + } + + /* Clear curarg because it was put in curargv or was free'd. */ + curarg = NULL; + + /* Add bytes needed to hold multi bulk count */ + totlen += 1+countDigits(argc)+2; + + /* Build the command at protocol level */ + cmd = malloc(totlen+1); + if (cmd == NULL) goto memory_err; + + pos = sprintf(cmd,"*%d\r\n",argc); + for (j = 0; j < argc; j++) { + pos += sprintf(cmd+pos,"$%zu\r\n",sdslen(curargv[j])); + memcpy(cmd+pos,curargv[j],sdslen(curargv[j])); + pos += sdslen(curargv[j]); + sdsfree(curargv[j]); + cmd[pos++] = '\r'; + cmd[pos++] = '\n'; + } + assert(pos == totlen); + cmd[pos] = '\0'; + + free(curargv); + *target = cmd; + return totlen; + +format_err: + error_type = -2; + goto cleanup; + +memory_err: + error_type = -1; + goto cleanup; + +cleanup: + if (curargv) { + while(argc--) + sdsfree(curargv[argc]); + free(curargv); + } + + sdsfree(curarg); + free(cmd); + + return error_type; +} + +/* Format a command according to the Redis protocol. This function + * takes a format similar to printf: + * + * %s represents a C null terminated string you want to interpolate + * %b represents a binary safe string + * + * When using %b you need to provide both the pointer to the string + * and the length in bytes as a size_t. Examples: + * + * len = redisFormatCommand(target, "GET %s", mykey); + * len = redisFormatCommand(target, "SET %s %b", mykey, myval, myvallen); + */ +int redisFormatCommand(char **target, const char *format, ...) { + va_list ap; + int len; + va_start(ap,format); + len = redisvFormatCommand(target,format,ap); + va_end(ap); + + /* The API says "-1" means bad result, but we now also return "-2" in some + * cases. Force the return value to always be -1. */ + if (len < 0) + len = -1; + + return len; +} + +/* Format a command according to the Redis protocol using an sds string and + * sdscatfmt for the processing of arguments. This function takes the + * number of arguments, an array with arguments and an array with their + * lengths. If the latter is set to NULL, strlen will be used to compute the + * argument lengths. + */ +int redisFormatSdsCommandArgv(sds *target, int argc, const char **argv, + const size_t *argvlen) +{ + sds cmd; + unsigned long long totlen; + int j; + size_t len; + + /* Abort on a NULL target */ + if (target == NULL) + return -1; + + /* Calculate our total size */ + totlen = 1+countDigits(argc)+2; + for (j = 0; j < argc; j++) { + len = argvlen ? argvlen[j] : strlen(argv[j]); + totlen += bulklen(len); + } + + /* Use an SDS string for command construction */ + cmd = sdsempty(); + if (cmd == NULL) + return -1; + + /* We already know how much storage we need */ + cmd = sdsMakeRoomFor(cmd, totlen); + if (cmd == NULL) + return -1; + + /* Construct command */ + cmd = sdscatfmt(cmd, "*%i\r\n", argc); + for (j=0; j < argc; j++) { + len = argvlen ? argvlen[j] : strlen(argv[j]); + cmd = sdscatfmt(cmd, "$%u\r\n", len); + cmd = sdscatlen(cmd, argv[j], len); + cmd = sdscatlen(cmd, "\r\n", sizeof("\r\n")-1); + } + + assert(sdslen(cmd)==totlen); + + *target = cmd; + return totlen; +} + +void redisFreeSdsCommand(sds cmd) { + sdsfree(cmd); +} + +/* Format a command according to the Redis protocol. This function takes the + * number of arguments, an array with arguments and an array with their + * lengths. If the latter is set to NULL, strlen will be used to compute the + * argument lengths. + */ +int redisFormatCommandArgv(char **target, int argc, const char **argv, const size_t *argvlen) { + char *cmd = NULL; /* final command */ + int pos; /* position in final command */ + size_t len; + int totlen, j; + + /* Abort on a NULL target */ + if (target == NULL) + return -1; + + /* Calculate number of bytes needed for the command */ + totlen = 1+countDigits(argc)+2; + for (j = 0; j < argc; j++) { + len = argvlen ? argvlen[j] : strlen(argv[j]); + totlen += bulklen(len); + } + + /* Build the command at protocol level */ + cmd = malloc(totlen+1); + if (cmd == NULL) + return -1; + + pos = sprintf(cmd,"*%d\r\n",argc); + for (j = 0; j < argc; j++) { + len = argvlen ? argvlen[j] : strlen(argv[j]); + pos += sprintf(cmd+pos,"$%zu\r\n",len); + memcpy(cmd+pos,argv[j],len); + pos += len; + cmd[pos++] = '\r'; + cmd[pos++] = '\n'; + } + assert(pos == totlen); + cmd[pos] = '\0'; + + *target = cmd; + return totlen; +} + +void redisFreeCommand(char *cmd) { + free(cmd); +} + +void __redisSetError(redisContext *c, int type, const char *str) { + size_t len; + + c->err = type; + if (str != NULL) { + len = strlen(str); + len = len < (sizeof(c->errstr)-1) ? len : (sizeof(c->errstr)-1); + memcpy(c->errstr,str,len); + c->errstr[len] = '\0'; + } else { + /* Only REDIS_ERR_IO may lack a description! */ + assert(type == REDIS_ERR_IO); + strerror_r(errno, c->errstr, sizeof(c->errstr)); + } +} + +redisReader *redisReaderCreate(void) { + return redisReaderCreateWithFunctions(&defaultFunctions); +} + +static redisContext *redisContextInit(const redisOptions *options) { + redisContext *c; + + c = calloc(1, sizeof(*c)); + if (c == NULL) + return NULL; + + c->funcs = &redisContextDefaultFuncs; + c->obuf = sdsempty(); + c->reader = redisReaderCreate(); + c->fd = REDIS_INVALID_FD; + + if (c->obuf == NULL || c->reader == NULL) { + redisFree(c); + return NULL; + } + (void)options; /* options are used in other functions */ + return c; +} + +void redisFree(redisContext *c) { + if (c == NULL) + return; + redisNetClose(c); + + sdsfree(c->obuf); + redisReaderFree(c->reader); + free(c->tcp.host); + free(c->tcp.source_addr); + free(c->unix_sock.path); + free(c->timeout); + free(c->saddr); + if (c->funcs->free_privdata) { + c->funcs->free_privdata(c->privdata); + } + memset(c, 0xff, sizeof(*c)); + free(c); +} + +redisFD redisFreeKeepFd(redisContext *c) { + redisFD fd = c->fd; + c->fd = REDIS_INVALID_FD; + redisFree(c); + return fd; +} + +int redisReconnect(redisContext *c) { + c->err = 0; + memset(c->errstr, '\0', strlen(c->errstr)); + + if (c->privdata && c->funcs->free_privdata) { + c->funcs->free_privdata(c->privdata); + c->privdata = NULL; + } + + redisNetClose(c); + + sdsfree(c->obuf); + redisReaderFree(c->reader); + + c->obuf = sdsempty(); + c->reader = redisReaderCreate(); + + if (c->connection_type == REDIS_CONN_TCP) { + return redisContextConnectBindTcp(c, c->tcp.host, c->tcp.port, + c->timeout, c->tcp.source_addr); + } else if (c->connection_type == REDIS_CONN_UNIX) { + return redisContextConnectUnix(c, c->unix_sock.path, c->timeout); + } else { + /* Something bad happened here and shouldn't have. There isn't + enough information in the context to reconnect. */ + __redisSetError(c,REDIS_ERR_OTHER,"Not enough information to reconnect"); + } + + return REDIS_ERR; +} + +redisContext *redisConnectWithOptions(const redisOptions *options) { + redisContext *c = redisContextInit(options); + if (c == NULL) { + return NULL; + } + if (!(options->options & REDIS_OPT_NONBLOCK)) { + c->flags |= REDIS_BLOCK; + } + if (options->options & REDIS_OPT_REUSEADDR) { + c->flags |= REDIS_REUSEADDR; + } + if (options->options & REDIS_OPT_NOAUTOFREE) { + c->flags |= REDIS_NO_AUTO_FREE; + } + + if (options->type == REDIS_CONN_TCP) { + redisContextConnectBindTcp(c, options->endpoint.tcp.ip, + options->endpoint.tcp.port, options->timeout, + options->endpoint.tcp.source_addr); + } else if (options->type == REDIS_CONN_UNIX) { + redisContextConnectUnix(c, options->endpoint.unix_socket, + options->timeout); + } else if (options->type == REDIS_CONN_USERFD) { + c->fd = options->endpoint.fd; + c->flags |= REDIS_CONNECTED; + } else { + // Unknown type - FIXME - FREE + return NULL; + } + if (options->timeout != NULL && (c->flags & REDIS_BLOCK) && c->fd != REDIS_INVALID_FD) { + redisContextSetTimeout(c, *options->timeout); + } + return c; +} + +/* Connect to a Redis instance. On error the field error in the returned + * context will be set to the return value of the error function. + * When no set of reply functions is given, the default set will be used. */ +redisContext *redisConnect(const char *ip, int port) { + redisOptions options = {0}; + REDIS_OPTIONS_SET_TCP(&options, ip, port); + return redisConnectWithOptions(&options); +} + +redisContext *redisConnectWithTimeout(const char *ip, int port, const struct timeval tv) { + redisOptions options = {0}; + REDIS_OPTIONS_SET_TCP(&options, ip, port); + options.timeout = &tv; + return redisConnectWithOptions(&options); +} + +redisContext *redisConnectNonBlock(const char *ip, int port) { + redisOptions options = {0}; + REDIS_OPTIONS_SET_TCP(&options, ip, port); + options.options |= REDIS_OPT_NONBLOCK; + return redisConnectWithOptions(&options); +} + +redisContext *redisConnectBindNonBlock(const char *ip, int port, + const char *source_addr) { + redisOptions options = {0}; + REDIS_OPTIONS_SET_TCP(&options, ip, port); + options.endpoint.tcp.source_addr = source_addr; + options.options |= REDIS_OPT_NONBLOCK; + return redisConnectWithOptions(&options); +} + +redisContext *redisConnectBindNonBlockWithReuse(const char *ip, int port, + const char *source_addr) { + redisOptions options = {0}; + REDIS_OPTIONS_SET_TCP(&options, ip, port); + options.endpoint.tcp.source_addr = source_addr; + options.options |= REDIS_OPT_NONBLOCK|REDIS_OPT_REUSEADDR; + return redisConnectWithOptions(&options); +} + +redisContext *redisConnectUnix(const char *path) { + redisOptions options = {0}; + REDIS_OPTIONS_SET_UNIX(&options, path); + return redisConnectWithOptions(&options); +} + +redisContext *redisConnectUnixWithTimeout(const char *path, const struct timeval tv) { + redisOptions options = {0}; + REDIS_OPTIONS_SET_UNIX(&options, path); + options.timeout = &tv; + return redisConnectWithOptions(&options); +} + +redisContext *redisConnectUnixNonBlock(const char *path) { + redisOptions options = {0}; + REDIS_OPTIONS_SET_UNIX(&options, path); + options.options |= REDIS_OPT_NONBLOCK; + return redisConnectWithOptions(&options); +} + +redisContext *redisConnectFd(redisFD fd) { + redisOptions options = {0}; + options.type = REDIS_CONN_USERFD; + options.endpoint.fd = fd; + return redisConnectWithOptions(&options); +} + +/* Set read/write timeout on a blocking socket. */ +int redisSetTimeout(redisContext *c, const struct timeval tv) { + if (c->flags & REDIS_BLOCK) + return redisContextSetTimeout(c,tv); + return REDIS_ERR; +} + +/* Enable connection KeepAlive. */ +int redisEnableKeepAlive(redisContext *c) { + if (redisKeepAlive(c, REDIS_KEEPALIVE_INTERVAL) != REDIS_OK) + return REDIS_ERR; + return REDIS_OK; +} + +/* Use this function to handle a read event on the descriptor. It will try + * and read some bytes from the socket and feed them to the reply parser. + * + * After this function is called, you may use redisGetReplyFromReader to + * see if there is a reply available. */ +int redisBufferRead(redisContext *c) { + char buf[1024*16]; + int nread; + + /* Return early when the context has seen an error. */ + if (c->err) + return REDIS_ERR; + + nread = c->funcs->read(c, buf, sizeof(buf)); + if (nread > 0) { + if (redisReaderFeed(c->reader, buf, nread) != REDIS_OK) { + __redisSetError(c, c->reader->err, c->reader->errstr); + return REDIS_ERR; + } else { + } + } else if (nread < 0) { + return REDIS_ERR; + } + return REDIS_OK; +} + +/* Write the output buffer to the socket. + * + * Returns REDIS_OK when the buffer is empty, or (a part of) the buffer was + * successfully written to the socket. When the buffer is empty after the + * write operation, "done" is set to 1 (if given). + * + * Returns REDIS_ERR if an error occurred trying to write and sets + * c->errstr to hold the appropriate error string. + */ +int redisBufferWrite(redisContext *c, int *done) { + + /* Return early when the context has seen an error. */ + if (c->err) + return REDIS_ERR; + + if (sdslen(c->obuf) > 0) { + int nwritten = c->funcs->write(c); + if (nwritten < 0) { + return REDIS_ERR; + } else if (nwritten > 0) { + if (nwritten == (signed)sdslen(c->obuf)) { + sdsfree(c->obuf); + c->obuf = sdsempty(); + } else { + sdsrange(c->obuf,nwritten,-1); + } + } + } + if (done != NULL) *done = (sdslen(c->obuf) == 0); + return REDIS_OK; +} + +/* Internal helper function to try and get a reply from the reader, + * or set an error in the context otherwise. */ +int redisGetReplyFromReader(redisContext *c, void **reply) { + if (redisReaderGetReply(c->reader,reply) == REDIS_ERR) { + __redisSetError(c,c->reader->err,c->reader->errstr); + return REDIS_ERR; + } + return REDIS_OK; +} + +int redisGetReply(redisContext *c, void **reply) { + int wdone = 0; + void *aux = NULL; + + /* Try to read pending replies */ + if (redisGetReplyFromReader(c,&aux) == REDIS_ERR) + return REDIS_ERR; + + /* For the blocking context, flush output buffer and read reply */ + if (aux == NULL && c->flags & REDIS_BLOCK) { + /* Write until done */ + do { + if (redisBufferWrite(c,&wdone) == REDIS_ERR) + return REDIS_ERR; + } while (!wdone); + + /* Read until there is a reply */ + do { + if (redisBufferRead(c) == REDIS_ERR) + return REDIS_ERR; + if (redisGetReplyFromReader(c,&aux) == REDIS_ERR) + return REDIS_ERR; + } while (aux == NULL); + } + + /* Set reply or free it if we were passed NULL */ + if (reply != NULL) { + *reply = aux; + } else { + freeReplyObject(aux); + } + + return REDIS_OK; +} + + +/* Helper function for the redisAppendCommand* family of functions. + * + * Write a formatted command to the output buffer. When this family + * is used, you need to call redisGetReply yourself to retrieve + * the reply (or replies in pub/sub). + */ +int __redisAppendCommand(redisContext *c, const char *cmd, size_t len) { + sds newbuf; + + newbuf = sdscatlen(c->obuf,cmd,len); + if (newbuf == NULL) { + __redisSetError(c,REDIS_ERR_OOM,"Out of memory"); + return REDIS_ERR; + } + + c->obuf = newbuf; + return REDIS_OK; +} + +int redisAppendFormattedCommand(redisContext *c, const char *cmd, size_t len) { + + if (__redisAppendCommand(c, cmd, len) != REDIS_OK) { + return REDIS_ERR; + } + + return REDIS_OK; +} + +int redisvAppendCommand(redisContext *c, const char *format, va_list ap) { + char *cmd; + int len; + + len = redisvFormatCommand(&cmd,format,ap); + if (len == -1) { + __redisSetError(c,REDIS_ERR_OOM,"Out of memory"); + return REDIS_ERR; + } else if (len == -2) { + __redisSetError(c,REDIS_ERR_OTHER,"Invalid format string"); + return REDIS_ERR; + } + + if (__redisAppendCommand(c,cmd,len) != REDIS_OK) { + free(cmd); + return REDIS_ERR; + } + + free(cmd); + return REDIS_OK; +} + +int redisAppendCommand(redisContext *c, const char *format, ...) { + va_list ap; + int ret; + + va_start(ap,format); + ret = redisvAppendCommand(c,format,ap); + va_end(ap); + return ret; +} + +int redisAppendCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen) { + sds cmd; + int len; + + len = redisFormatSdsCommandArgv(&cmd,argc,argv,argvlen); + if (len == -1) { + __redisSetError(c,REDIS_ERR_OOM,"Out of memory"); + return REDIS_ERR; + } + + if (__redisAppendCommand(c,cmd,len) != REDIS_OK) { + sdsfree(cmd); + return REDIS_ERR; + } + + sdsfree(cmd); + return REDIS_OK; +} + +/* Helper function for the redisCommand* family of functions. + * + * Write a formatted command to the output buffer. If the given context is + * blocking, immediately read the reply into the "reply" pointer. When the + * context is non-blocking, the "reply" pointer will not be used and the + * command is simply appended to the write buffer. + * + * Returns the reply when a reply was successfully retrieved. Returns NULL + * otherwise. When NULL is returned in a blocking context, the error field + * in the context will be set. + */ +static void *__redisBlockForReply(redisContext *c) { + void *reply; + + if (c->flags & REDIS_BLOCK) { + if (redisGetReply(c,&reply) != REDIS_OK) + return NULL; + return reply; + } + return NULL; +} + +void *redisvCommand(redisContext *c, const char *format, va_list ap) { + if (redisvAppendCommand(c,format,ap) != REDIS_OK) + return NULL; + return __redisBlockForReply(c); +} + +void *redisCommand(redisContext *c, const char *format, ...) { + va_list ap; + va_start(ap,format); + void *reply = redisvCommand(c,format,ap); + va_end(ap); + return reply; +} + +void *redisCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen) { + if (redisAppendCommandArgv(c,argc,argv,argvlen) != REDIS_OK) + return NULL; + return __redisBlockForReply(c); +} diff --git a/俱乐部/Source/hiredis/hiredis.h b/俱乐部/Source/hiredis/hiredis.h new file mode 100644 index 0000000..9921e61 --- /dev/null +++ b/俱乐部/Source/hiredis/hiredis.h @@ -0,0 +1,298 @@ +/* + * Copyright (c) 2009-2011, Salvatore Sanfilippo + * Copyright (c) 2010-2014, Pieter Noordhuis + * Copyright (c) 2015, Matt Stancliff , + * Jan-Erik Rediger + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Redis nor the names of its contributors may 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. + */ + +#ifndef __HIREDIS_H +#define __HIREDIS_H +#include "read.h" +#include /* for va_list */ +#ifndef _MSC_VER +#include /* for struct timeval */ +#else +struct timeval; /* forward declaration */ +#endif +#include /* uintXX_t, etc */ +#include "sds.h" /* for sds */ +#include "alloc.h" /* for allocation wrappers */ + +#define HIREDIS_MAJOR 0 +#define HIREDIS_MINOR 14 +#define HIREDIS_PATCH 0 +#define HIREDIS_SONAME 0.14 + +/* Connection type can be blocking or non-blocking and is set in the + * least significant bit of the flags field in redisContext. */ +#define REDIS_BLOCK 0x1 + +/* Connection may be disconnected before being free'd. The second bit + * in the flags field is set when the context is connected. */ +#define REDIS_CONNECTED 0x2 + +/* The async API might try to disconnect cleanly and flush the output + * buffer and read all subsequent replies before disconnecting. + * This flag means no new commands can come in and the connection + * should be terminated once all replies have been read. */ +#define REDIS_DISCONNECTING 0x4 + +/* Flag specific to the async API which means that the context should be clean + * up as soon as possible. */ +#define REDIS_FREEING 0x8 + +/* Flag that is set when an async callback is executed. */ +#define REDIS_IN_CALLBACK 0x10 + +/* Flag that is set when the async context has one or more subscriptions. */ +#define REDIS_SUBSCRIBED 0x20 + +/* Flag that is set when monitor mode is active */ +#define REDIS_MONITORING 0x40 + +/* Flag that is set when we should set SO_REUSEADDR before calling bind() */ +#define REDIS_REUSEADDR 0x80 + +/** + * Flag that indicates the user does not want the context to + * be automatically freed upon error + */ +#define REDIS_NO_AUTO_FREE 0x200 + +#define REDIS_KEEPALIVE_INTERVAL 15 /* seconds */ + +/* number of times we retry to connect in the case of EADDRNOTAVAIL and + * SO_REUSEADDR is being used. */ +#define REDIS_CONNECT_RETRIES 10 + +#ifdef __cplusplus +extern "C" { +#endif + +/* This is the reply object returned by redisCommand() */ +typedef struct redisReply { + int type; /* REDIS_REPLY_* */ + long long integer; /* The integer when type is REDIS_REPLY_INTEGER */ + double dval; /* The double when type is REDIS_REPLY_DOUBLE */ + size_t len; /* Length of string */ + char *str; /* Used for REDIS_REPLY_ERROR, REDIS_REPLY_STRING + and REDIS_REPLY_DOUBLE (in additional to dval). */ + size_t elements; /* number of elements, for REDIS_REPLY_ARRAY */ + struct redisReply **element; /* elements vector for REDIS_REPLY_ARRAY */ +} redisReply; + +redisReader *redisReaderCreate(void); + +/* Function to free the reply objects hiredis returns by default. */ +void freeReplyObject(void *reply); + +/* Functions to format a command according to the protocol. */ +int redisvFormatCommand(char **target, const char *format, va_list ap); +int redisFormatCommand(char **target, const char *format, ...); +int redisFormatCommandArgv(char **target, int argc, const char **argv, const size_t *argvlen); +int redisFormatSdsCommandArgv(sds *target, int argc, const char ** argv, const size_t *argvlen); +void redisFreeCommand(char *cmd); +void redisFreeSdsCommand(sds cmd); + +enum redisConnectionType { + REDIS_CONN_TCP, + REDIS_CONN_UNIX, + REDIS_CONN_USERFD +}; + +struct redisSsl; + +#define REDIS_OPT_NONBLOCK 0x01 +#define REDIS_OPT_REUSEADDR 0x02 + +/** + * Don't automatically free the async object on a connection failure, + * or other implicit conditions. Only free on an explicit call to disconnect() or free() + */ +#define REDIS_OPT_NOAUTOFREE 0x04 + +/* In Unix systems a file descriptor is a regular signed int, with -1 + * representing an invalid descriptor. In Windows it is a SOCKET + * (32- or 64-bit unsigned integer depending on the architecture), where + * all bits set (~0) is INVALID_SOCKET. */ +#ifndef _WIN32 +typedef int redisFD; +#define REDIS_INVALID_FD -1 +#else +#ifdef _WIN64 +typedef unsigned long long redisFD; /* SOCKET = 64-bit UINT_PTR */ +#else +typedef unsigned long redisFD; /* SOCKET = 32-bit UINT_PTR */ +#endif +#define REDIS_INVALID_FD ((redisFD)(~0)) /* INVALID_SOCKET */ +#endif + +typedef struct { + /* + * the type of connection to use. This also indicates which + * `endpoint` member field to use + */ + int type; + /* bit field of REDIS_OPT_xxx */ + int options; + /* timeout value. if NULL, no timeout is used */ + const struct timeval *timeout; + union { + /** use this field for tcp/ip connections */ + struct { + const char *source_addr; + const char *ip; + int port; + } tcp; + /** use this field for unix domain sockets */ + const char *unix_socket; + /** + * use this field to have hiredis operate an already-open + * file descriptor */ + redisFD fd; + } endpoint; +} redisOptions; + +/** + * Helper macros to initialize options to their specified fields. + */ +#define REDIS_OPTIONS_SET_TCP(opts, ip_, port_) \ + (opts)->type = REDIS_CONN_TCP; \ + (opts)->endpoint.tcp.ip = ip_; \ + (opts)->endpoint.tcp.port = port_; + +#define REDIS_OPTIONS_SET_UNIX(opts, path) \ + (opts)->type = REDIS_CONN_UNIX; \ + (opts)->endpoint.unix_socket = path; + +struct redisAsyncContext; +struct redisContext; + +typedef struct redisContextFuncs { + void (*free_privdata)(void *); + void (*async_read)(struct redisAsyncContext *); + void (*async_write)(struct redisAsyncContext *); + int (*read)(struct redisContext *, char *, size_t); + int (*write)(struct redisContext *); +} redisContextFuncs; + +/* Context for a connection to Redis */ +typedef struct redisContext { + const redisContextFuncs *funcs; /* Function table */ + + int err; /* Error flags, 0 when there is no error */ + char errstr[128]; /* String representation of error when applicable */ + redisFD fd; + int flags; + char *obuf; /* Write buffer */ + redisReader *reader; /* Protocol reader */ + + enum redisConnectionType connection_type; + struct timeval *timeout; + + struct { + char *host; + char *source_addr; + int port; + } tcp; + + struct { + char *path; + } unix_sock; + + /* For non-blocking connect */ + struct sockadr *saddr; + size_t addrlen; + + /* Additional private data for hiredis addons such as SSL */ + void *privdata; +} redisContext; + +redisContext *redisConnectWithOptions(const redisOptions *options); +redisContext *redisConnect(const char *ip, int port); +redisContext *redisConnectWithTimeout(const char *ip, int port, const struct timeval tv); +redisContext *redisConnectNonBlock(const char *ip, int port); +redisContext *redisConnectBindNonBlock(const char *ip, int port, + const char *source_addr); +redisContext *redisConnectBindNonBlockWithReuse(const char *ip, int port, + const char *source_addr); +redisContext *redisConnectUnix(const char *path); +redisContext *redisConnectUnixWithTimeout(const char *path, const struct timeval tv); +redisContext *redisConnectUnixNonBlock(const char *path); +redisContext *redisConnectFd(redisFD fd); + +/** + * Reconnect the given context using the saved information. + * + * This re-uses the exact same connect options as in the initial connection. + * host, ip (or path), timeout and bind address are reused, + * flags are used unmodified from the existing context. + * + * Returns REDIS_OK on successful connect or REDIS_ERR otherwise. + */ +int redisReconnect(redisContext *c); + +int redisSetTimeout(redisContext *c, const struct timeval tv); +int redisEnableKeepAlive(redisContext *c); +void redisFree(redisContext *c); +redisFD redisFreeKeepFd(redisContext *c); +int redisBufferRead(redisContext *c); +int redisBufferWrite(redisContext *c, int *done); + +/* In a blocking context, this function first checks if there are unconsumed + * replies to return and returns one if so. Otherwise, it flushes the output + * buffer to the socket and reads until it has a reply. In a non-blocking + * context, it will return unconsumed replies until there are no more. */ +int redisGetReply(redisContext *c, void **reply); +int redisGetReplyFromReader(redisContext *c, void **reply); + +/* Write a formatted command to the output buffer. Use these functions in blocking mode + * to get a pipeline of commands. */ +int redisAppendFormattedCommand(redisContext *c, const char *cmd, size_t len); + +/* Write a command to the output buffer. Use these functions in blocking mode + * to get a pipeline of commands. */ +int redisvAppendCommand(redisContext *c, const char *format, va_list ap); +int redisAppendCommand(redisContext *c, const char *format, ...); +int redisAppendCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen); + +/* Issue a command to Redis. In a blocking context, it is identical to calling + * redisAppendCommand, followed by redisGetReply. The function will return + * NULL if there was an error in performing the request, otherwise it will + * return the reply. In a non-blocking context, it is identical to calling + * only redisAppendCommand and will always return NULL. */ +void *redisvCommand(redisContext *c, const char *format, va_list ap); +void *redisCommand(redisContext *c, const char *format, ...); +void *redisCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/俱乐部/Source/hiredis/hiredis.pc.in b/俱乐部/Source/hiredis/hiredis.pc.in new file mode 100644 index 0000000..140b040 --- /dev/null +++ b/俱乐部/Source/hiredis/hiredis.pc.in @@ -0,0 +1,11 @@ +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=${prefix} +libdir=${exec_prefix}/lib +includedir=${prefix}/include +pkgincludedir=${includedir}/hiredis + +Name: hiredis +Description: Minimalistic C client library for Redis. +Version: @PROJECT_VERSION@ +Libs: -L${libdir} -lhiredis +Cflags: -I${pkgincludedir} -D_FILE_OFFSET_BITS=64 diff --git a/俱乐部/Source/hiredis/hiredis_ssl.h b/俱乐部/Source/hiredis/hiredis_ssl.h new file mode 100644 index 0000000..f844f95 --- /dev/null +++ b/俱乐部/Source/hiredis/hiredis_ssl.h @@ -0,0 +1,53 @@ + +/* + * Copyright (c) 2019, Redis Labs + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Redis nor the names of its contributors may 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. + */ + +#ifndef __HIREDIS_SSL_H +#define __HIREDIS_SSL_H + +/* This is the underlying struct for SSL in ssl.h, which is not included to + * keep build dependencies short here. + */ +struct ssl_st; + +/** + * Secure the connection using SSL. This should be done before any command is + * executed on the connection. + */ +int redisSecureConnection(redisContext *c, const char *capath, const char *certpath, + const char *keypath, const char *servername); + +/** + * Initiate SSL/TLS negotiation on a provided context. + */ + +int redisInitiateSSL(redisContext *c, struct ssl_st *ssl); + +#endif /* __HIREDIS_SSL_H */ diff --git a/俱乐部/Source/hiredis/hiredis_ssl.pc.in b/俱乐部/Source/hiredis/hiredis_ssl.pc.in new file mode 100644 index 0000000..588a978 --- /dev/null +++ b/俱乐部/Source/hiredis/hiredis_ssl.pc.in @@ -0,0 +1,12 @@ +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=${prefix} +libdir=${exec_prefix}/lib +includedir=${prefix}/include +pkgincludedir=${includedir}/hiredis + +Name: hiredis_ssl +Description: SSL Support for hiredis. +Version: @PROJECT_VERSION@ +Requires: hiredis +Libs: -L${libdir} -lhiredis_ssl +Libs.private: -lssl -lcrypto diff --git a/俱乐部/Source/hiredis/net.c b/俱乐部/Source/hiredis/net.c new file mode 100644 index 0000000..c928b33 --- /dev/null +++ b/俱乐部/Source/hiredis/net.c @@ -0,0 +1,571 @@ +/* Extracted from anet.c to work properly with Hiredis error reporting. + * + * Copyright (c) 2009-2011, Salvatore Sanfilippo + * Copyright (c) 2010-2014, Pieter Noordhuis + * Copyright (c) 2015, Matt Stancliff , + * Jan-Erik Rediger + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Redis nor the names of its contributors may 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. + */ + +#include "fmacros.h" +#include +#include +#include +#include +#include +#include +#include +#include + +#include "net.h" +#include "sds.h" +#include "sockcompat.h" +#include "win32.h" + +/* Defined in hiredis.c */ +void __redisSetError(redisContext *c, int type, const char *str); + +void redisNetClose(redisContext *c) { + if (c && c->fd != REDIS_INVALID_FD) { + close(c->fd); + c->fd = REDIS_INVALID_FD; + } +} + +int redisNetRead(redisContext *c, char *buf, size_t bufcap) { + int nread = recv(c->fd, buf, bufcap, 0); + if (nread == -1) { + if ((errno == EWOULDBLOCK && !(c->flags & REDIS_BLOCK)) || (errno == EINTR)) { + /* Try again later */ + return 0; + } else if(errno == ETIMEDOUT && (c->flags & REDIS_BLOCK)) { + /* especially in windows */ + __redisSetError(c, REDIS_ERR_TIMEOUT, "recv timeout"); + return -1; + } else { + __redisSetError(c, REDIS_ERR_IO, NULL); + return -1; + } + } else if (nread == 0) { + __redisSetError(c, REDIS_ERR_EOF, "Server closed the connection"); + return -1; + } else { + return nread; + } +} + +int redisNetWrite(redisContext *c) { + int nwritten = send(c->fd, c->obuf, sdslen(c->obuf), 0); + if (nwritten < 0) { + if ((errno == EWOULDBLOCK && !(c->flags & REDIS_BLOCK)) || (errno == EINTR)) { + /* Try again later */ + } else { + __redisSetError(c, REDIS_ERR_IO, NULL); + return -1; + } + } + return nwritten; +} + +static void __redisSetErrorFromErrno(redisContext *c, int type, const char *prefix) { + int errorno = errno; /* snprintf() may change errno */ + char buf[128] = { 0 }; + size_t len = 0; + + if (prefix != NULL) + len = snprintf(buf,sizeof(buf),"%s: ",prefix); + strerror_r(errorno, (char *)(buf + len), sizeof(buf) - len); + __redisSetError(c,type,buf); +} + +static int redisSetReuseAddr(redisContext *c) { + int on = 1; + if (setsockopt(c->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) { + __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL); + redisNetClose(c); + return REDIS_ERR; + } + return REDIS_OK; +} + +static int redisCreateSocket(redisContext *c, int type) { + redisFD s; + if ((s = socket(type, SOCK_STREAM, 0)) == REDIS_INVALID_FD) { + __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL); + return REDIS_ERR; + } + c->fd = s; + if (type == AF_INET) { + if (redisSetReuseAddr(c) == REDIS_ERR) { + return REDIS_ERR; + } + } + return REDIS_OK; +} + +static int redisSetBlocking(redisContext *c, int blocking) { +#ifndef _WIN32 + int flags; + + /* Set the socket nonblocking. + * Note that fcntl(2) for F_GETFL and F_SETFL can't be + * interrupted by a signal. */ + if ((flags = fcntl(c->fd, F_GETFL)) == -1) { + __redisSetErrorFromErrno(c,REDIS_ERR_IO,"fcntl(F_GETFL)"); + redisNetClose(c); + return REDIS_ERR; + } + + if (blocking) + flags &= ~O_NONBLOCK; + else + flags |= O_NONBLOCK; + + if (fcntl(c->fd, F_SETFL, flags) == -1) { + __redisSetErrorFromErrno(c,REDIS_ERR_IO,"fcntl(F_SETFL)"); + redisNetClose(c); + return REDIS_ERR; + } +#else + u_long mode = blocking ? 0 : 1; + if (ioctl(c->fd, FIONBIO, &mode) == -1) { + __redisSetErrorFromErrno(c, REDIS_ERR_IO, "ioctl(FIONBIO)"); + redisNetClose(c); + return REDIS_ERR; + } +#endif /* _WIN32 */ + return REDIS_OK; +} + +int redisKeepAlive(redisContext *c, int interval) { + int val = 1; + redisFD fd = c->fd; + + if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val)) == -1){ + __redisSetError(c,REDIS_ERR_OTHER,strerror(errno)); + return REDIS_ERR; + } + + val = interval; + +#if defined(__APPLE__) && defined(__MACH__) + if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPALIVE, &val, sizeof(val)) < 0) { + __redisSetError(c,REDIS_ERR_OTHER,strerror(errno)); + return REDIS_ERR; + } +#else +#if defined(__GLIBC__) && !defined(__FreeBSD_kernel__) + if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &val, sizeof(val)) < 0) { + __redisSetError(c,REDIS_ERR_OTHER,strerror(errno)); + return REDIS_ERR; + } + + val = interval/3; + if (val == 0) val = 1; + if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &val, sizeof(val)) < 0) { + __redisSetError(c,REDIS_ERR_OTHER,strerror(errno)); + return REDIS_ERR; + } + + val = 3; + if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &val, sizeof(val)) < 0) { + __redisSetError(c,REDIS_ERR_OTHER,strerror(errno)); + return REDIS_ERR; + } +#endif +#endif + + return REDIS_OK; +} + +static int redisSetTcpNoDelay(redisContext *c) { + int yes = 1; + if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY, &yes, sizeof(yes)) == -1) { + __redisSetErrorFromErrno(c,REDIS_ERR_IO,"setsockopt(TCP_NODELAY)"); + redisNetClose(c); + return REDIS_ERR; + } + return REDIS_OK; +} + +#define __MAX_MSEC (((LONG_MAX) - 999) / 1000) + +static int redisContextTimeoutMsec(redisContext *c, long *result) +{ + const struct timeval *timeout = c->timeout; + long msec = -1; + + /* Only use timeout when not NULL. */ + if (timeout != NULL) { + if (timeout->tv_usec > 1000000 || timeout->tv_sec > __MAX_MSEC) { + *result = msec; + return REDIS_ERR; + } + + msec = (timeout->tv_sec * 1000) + ((timeout->tv_usec + 999) / 1000); + + if (msec < 0 || msec > INT_MAX) { + msec = INT_MAX; + } + } + + *result = msec; + return REDIS_OK; +} + +static int redisContextWaitReady(redisContext *c, long msec) { + struct pollfd wfd[1]; + + wfd[0].fd = c->fd; + wfd[0].events = POLLOUT; + + if (errno == EINPROGRESS) { + int res; + + if ((res = poll(wfd, 1, msec)) == -1) { + __redisSetErrorFromErrno(c, REDIS_ERR_IO, "poll(2)"); + redisNetClose(c); + return REDIS_ERR; + } else if (res == 0) { + errno = ETIMEDOUT; + __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL); + redisNetClose(c); + return REDIS_ERR; + } + + if (redisCheckConnectDone(c, &res) != REDIS_OK || res == 0) { + redisCheckSocketError(c); + return REDIS_ERR; + } + + return REDIS_OK; + } + + __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL); + redisNetClose(c); + return REDIS_ERR; +} + +int redisCheckConnectDone(redisContext *c, int *completed) { + int rc = connect(c->fd, (const struct sockaddr *)c->saddr, c->addrlen); + if (rc == 0) { + *completed = 1; + return REDIS_OK; + } + switch (errno) { + case EISCONN: + *completed = 1; + return REDIS_OK; + case EALREADY: + case EINPROGRESS: + case EWOULDBLOCK: + *completed = 0; + return REDIS_OK; + default: + return REDIS_ERR; + } +} + +int redisCheckSocketError(redisContext *c) { + int err = 0, errno_saved = errno; + socklen_t errlen = sizeof(err); + + if (getsockopt(c->fd, SOL_SOCKET, SO_ERROR, &err, &errlen) == -1) { + __redisSetErrorFromErrno(c,REDIS_ERR_IO,"getsockopt(SO_ERROR)"); + return REDIS_ERR; + } + + if (err == 0) { + err = errno_saved; + } + + if (err) { + errno = err; + __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL); + return REDIS_ERR; + } + + return REDIS_OK; +} + +int redisContextSetTimeout(redisContext *c, const struct timeval tv) { + const void *to_ptr = &tv; + size_t to_sz = sizeof(tv); +#ifdef _WIN32 + DWORD timeout_msec = tv.tv_sec * 1000 + tv.tv_usec / 1000; + to_ptr = &timeout_msec; + to_sz = sizeof(timeout_msec); +#endif + if (setsockopt(c->fd,SOL_SOCKET,SO_RCVTIMEO,to_ptr,to_sz) == -1) { + __redisSetErrorFromErrno(c,REDIS_ERR_IO,"setsockopt(SO_RCVTIMEO)"); + return REDIS_ERR; + } + if (setsockopt(c->fd,SOL_SOCKET,SO_SNDTIMEO,to_ptr,to_sz) == -1) { + __redisSetErrorFromErrno(c,REDIS_ERR_IO,"setsockopt(SO_SNDTIMEO)"); + return REDIS_ERR; + } + return REDIS_OK; +} + +static int _redisContextConnectTcp(redisContext *c, const char *addr, int port, + const struct timeval *timeout, + const char *source_addr) { + redisFD s; + int rv, n; + char _port[6]; /* strlen("65535"); */ + struct addrinfo hints, *servinfo, *bservinfo, *p, *b; + int blocking = (c->flags & REDIS_BLOCK); + int reuseaddr = (c->flags & REDIS_REUSEADDR); + int reuses = 0; + long timeout_msec = -1; + + servinfo = NULL; + c->connection_type = REDIS_CONN_TCP; + c->tcp.port = port; + + /* We need to take possession of the passed parameters + * to make them reusable for a reconnect. + * We also carefully check we don't free data we already own, + * as in the case of the reconnect method. + * + * This is a bit ugly, but atleast it works and doesn't leak memory. + **/ + if (c->tcp.host != addr) { + free(c->tcp.host); + + c->tcp.host = hi_strdup(addr); + } + + if (timeout) { + if (c->timeout != timeout) { + if (c->timeout == NULL) + c->timeout = hi_malloc(sizeof(struct timeval)); + + memcpy(c->timeout, timeout, sizeof(struct timeval)); + } + } else { + free(c->timeout); + c->timeout = NULL; + } + + if (redisContextTimeoutMsec(c, &timeout_msec) != REDIS_OK) { + __redisSetError(c, REDIS_ERR_IO, "Invalid timeout specified"); + goto error; + } + + if (source_addr == NULL) { + free(c->tcp.source_addr); + c->tcp.source_addr = NULL; + } else if (c->tcp.source_addr != source_addr) { + free(c->tcp.source_addr); + c->tcp.source_addr = hi_strdup(source_addr); + } + + snprintf(_port, 6, "%d", port); + memset(&hints,0,sizeof(hints)); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + + /* Try with IPv6 if no IPv4 address was found. We do it in this order since + * in a Redis client you can't afford to test if you have IPv6 connectivity + * as this would add latency to every connect. Otherwise a more sensible + * route could be: Use IPv6 if both addresses are available and there is IPv6 + * connectivity. */ + if ((rv = getaddrinfo(c->tcp.host,_port,&hints,&servinfo)) != 0) { + hints.ai_family = AF_INET6; + if ((rv = getaddrinfo(addr,_port,&hints,&servinfo)) != 0) { + __redisSetError(c,REDIS_ERR_OTHER,gai_strerror(rv)); + return REDIS_ERR; + } + } + for (p = servinfo; p != NULL; p = p->ai_next) { +addrretry: + if ((s = socket(p->ai_family,p->ai_socktype,p->ai_protocol)) == REDIS_INVALID_FD) + continue; + + c->fd = s; + if (redisSetBlocking(c,0) != REDIS_OK) + goto error; + if (c->tcp.source_addr) { + int bound = 0; + /* Using getaddrinfo saves us from self-determining IPv4 vs IPv6 */ + if ((rv = getaddrinfo(c->tcp.source_addr, NULL, &hints, &bservinfo)) != 0) { + char buf[128]; + snprintf(buf,sizeof(buf),"Can't get addr: %s",gai_strerror(rv)); + __redisSetError(c,REDIS_ERR_OTHER,buf); + goto error; + } + + if (reuseaddr) { + n = 1; + if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*) &n, + sizeof(n)) < 0) { + freeaddrinfo(bservinfo); + goto error; + } + } + + for (b = bservinfo; b != NULL; b = b->ai_next) { + if (bind(s,b->ai_addr,b->ai_addrlen) != -1) { + bound = 1; + break; + } + } + freeaddrinfo(bservinfo); + if (!bound) { + char buf[128]; + snprintf(buf,sizeof(buf),"Can't bind socket: %s",strerror(errno)); + __redisSetError(c,REDIS_ERR_OTHER,buf); + goto error; + } + } + + /* For repeat connection */ + free(c->saddr); + c->saddr = hi_malloc(p->ai_addrlen); + memcpy(c->saddr, p->ai_addr, p->ai_addrlen); + c->addrlen = p->ai_addrlen; + + if (connect(s,p->ai_addr,p->ai_addrlen) == -1) { + if (errno == EHOSTUNREACH) { + redisNetClose(c); + continue; + } else if (errno == EINPROGRESS) { + if (blocking) { + goto wait_for_ready; + } + /* This is ok. + * Note that even when it's in blocking mode, we unset blocking + * for `connect()` + */ + } else if (errno == EADDRNOTAVAIL && reuseaddr) { + if (++reuses >= REDIS_CONNECT_RETRIES) { + goto error; + } else { + redisNetClose(c); + goto addrretry; + } + } else { + wait_for_ready: + if (redisContextWaitReady(c,timeout_msec) != REDIS_OK) + goto error; + } + } + if (blocking && redisSetBlocking(c,1) != REDIS_OK) + goto error; + if (redisSetTcpNoDelay(c) != REDIS_OK) + goto error; + + c->flags |= REDIS_CONNECTED; + rv = REDIS_OK; + goto end; + } + if (p == NULL) { + char buf[128]; + snprintf(buf,sizeof(buf),"Can't create socket: %s",strerror(errno)); + __redisSetError(c,REDIS_ERR_OTHER,buf); + goto error; + } + +error: + rv = REDIS_ERR; +end: + if(servinfo) { + freeaddrinfo(servinfo); + } + + return rv; // Need to return REDIS_OK if alright +} + +int redisContextConnectTcp(redisContext *c, const char *addr, int port, + const struct timeval *timeout) { + return _redisContextConnectTcp(c, addr, port, timeout, NULL); +} + +int redisContextConnectBindTcp(redisContext *c, const char *addr, int port, + const struct timeval *timeout, + const char *source_addr) { + return _redisContextConnectTcp(c, addr, port, timeout, source_addr); +} + +int redisContextConnectUnix(redisContext *c, const char *path, const struct timeval *timeout) { +#ifndef _WIN32 + int blocking = (c->flags & REDIS_BLOCK); + struct sockaddr_un *sa; + long timeout_msec = -1; + + if (redisCreateSocket(c,AF_UNIX) < 0) + return REDIS_ERR; + if (redisSetBlocking(c,0) != REDIS_OK) + return REDIS_ERR; + + c->connection_type = REDIS_CONN_UNIX; + if (c->unix_sock.path != path) + c->unix_sock.path = hi_strdup(path); + + if (timeout) { + if (c->timeout != timeout) { + if (c->timeout == NULL) + c->timeout = hi_malloc(sizeof(struct timeval)); + + memcpy(c->timeout, timeout, sizeof(struct timeval)); + } + } else { + free(c->timeout); + c->timeout = NULL; + } + + if (redisContextTimeoutMsec(c,&timeout_msec) != REDIS_OK) + return REDIS_ERR; + + sa = (struct sockaddr_un*)(c->saddr = hi_malloc(sizeof(struct sockaddr_un))); + c->addrlen = sizeof(struct sockaddr_un); + sa->sun_family = AF_UNIX; + strncpy(sa->sun_path, path, sizeof(sa->sun_path) - 1); + if (connect(c->fd, (struct sockaddr*)sa, sizeof(*sa)) == -1) { + if (errno == EINPROGRESS && !blocking) { + /* This is ok. */ + } else { + if (redisContextWaitReady(c,timeout_msec) != REDIS_OK) + return REDIS_ERR; + } + } + + /* Reset socket to be blocking after connect(2). */ + if (blocking && redisSetBlocking(c,1) != REDIS_OK) + return REDIS_ERR; + + c->flags |= REDIS_CONNECTED; + return REDIS_OK; +#else + /* We currently do not support Unix sockets for Windows. */ + /* TODO(m): https://devblogs.microsoft.com/commandline/af_unix-comes-to-windows/ */ + errno = EPROTONOSUPPORT; + return REDIS_ERR; +#endif /* _WIN32 */ +} diff --git a/俱乐部/Source/hiredis/net.h b/俱乐部/Source/hiredis/net.h new file mode 100644 index 0000000..a4393c0 --- /dev/null +++ b/俱乐部/Source/hiredis/net.h @@ -0,0 +1,54 @@ +/* Extracted from anet.c to work properly with Hiredis error reporting. + * + * Copyright (c) 2009-2011, Salvatore Sanfilippo + * Copyright (c) 2010-2014, Pieter Noordhuis + * Copyright (c) 2015, Matt Stancliff , + * Jan-Erik Rediger + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Redis nor the names of its contributors may 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. + */ + +#ifndef __NET_H +#define __NET_H + +#include "hiredis.h" + +void redisNetClose(redisContext *c); +int redisNetRead(redisContext *c, char *buf, size_t bufcap); +int redisNetWrite(redisContext *c); + +int redisCheckSocketError(redisContext *c); +int redisContextSetTimeout(redisContext *c, const struct timeval tv); +int redisContextConnectTcp(redisContext *c, const char *addr, int port, const struct timeval *timeout); +int redisContextConnectBindTcp(redisContext *c, const char *addr, int port, + const struct timeval *timeout, + const char *source_addr); +int redisContextConnectUnix(redisContext *c, const char *path, const struct timeval *timeout); +int redisKeepAlive(redisContext *c, int interval); +int redisCheckConnectDone(redisContext *c, int *completed); + +#endif diff --git a/俱乐部/Source/hiredis/read.c b/俱乐部/Source/hiredis/read.c new file mode 100644 index 0000000..a264c37 --- /dev/null +++ b/俱乐部/Source/hiredis/read.c @@ -0,0 +1,669 @@ +/* + * Copyright (c) 2009-2011, Salvatore Sanfilippo + * Copyright (c) 2010-2011, Pieter Noordhuis + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Redis nor the names of its contributors may 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. + */ + +#include "fmacros.h" +#include +#include +#ifndef _MSC_VER +#include +#include +#endif +#include +#include +#include +#include +#include + +#include "read.h" +#include "sds.h" +#include "win32.h" + +static void __redisReaderSetError(redisReader *r, int type, const char *str) { + size_t len; + + if (r->reply != NULL && r->fn && r->fn->freeObject) { + r->fn->freeObject(r->reply); + r->reply = NULL; + } + + /* Clear input buffer on errors. */ + sdsfree(r->buf); + r->buf = NULL; + r->pos = r->len = 0; + + /* Reset task stack. */ + r->ridx = -1; + + /* Set error. */ + r->err = type; + len = strlen(str); + len = len < (sizeof(r->errstr)-1) ? len : (sizeof(r->errstr)-1); + memcpy(r->errstr,str,len); + r->errstr[len] = '\0'; +} + +static size_t chrtos(char *buf, size_t size, char byte) { + size_t len = 0; + + switch(byte) { + case '\\': + case '"': + len = snprintf(buf,size,"\"\\%c\"",byte); + break; + case '\n': len = snprintf(buf,size,"\"\\n\""); break; + case '\r': len = snprintf(buf,size,"\"\\r\""); break; + case '\t': len = snprintf(buf,size,"\"\\t\""); break; + case '\a': len = snprintf(buf,size,"\"\\a\""); break; + case '\b': len = snprintf(buf,size,"\"\\b\""); break; + default: + if (isprint(byte)) + len = snprintf(buf,size,"\"%c\"",byte); + else + len = snprintf(buf,size,"\"\\x%02x\"",(unsigned char)byte); + break; + } + + return len; +} + +static void __redisReaderSetErrorProtocolByte(redisReader *r, char byte) { + char cbuf[8], sbuf[128]; + + chrtos(cbuf,sizeof(cbuf),byte); + snprintf(sbuf,sizeof(sbuf), + "Protocol error, got %s as reply type byte", cbuf); + __redisReaderSetError(r,REDIS_ERR_PROTOCOL,sbuf); +} + +static void __redisReaderSetErrorOOM(redisReader *r) { + __redisReaderSetError(r,REDIS_ERR_OOM,"Out of memory"); +} + +static char *readBytes(redisReader *r, unsigned int bytes) { + char *p; + if (r->len-r->pos >= bytes) { + p = r->buf+r->pos; + r->pos += bytes; + return p; + } + return NULL; +} + +/* Find pointer to \r\n. */ +static char *seekNewline(char *s, size_t len) { + int pos = 0; + int _len = len-1; + + /* Position should be < len-1 because the character at "pos" should be + * followed by a \n. Note that strchr cannot be used because it doesn't + * allow to search a limited length and the buffer that is being searched + * might not have a trailing NULL character. */ + while (pos < _len) { + while(pos < _len && s[pos] != '\r') pos++; + if (pos==_len) { + /* Not found. */ + return NULL; + } else { + if (s[pos+1] == '\n') { + /* Found. */ + return s+pos; + } else { + /* Continue searching. */ + pos++; + } + } + } + return NULL; +} + +/* Convert a string into a long long. Returns REDIS_OK if the string could be + * parsed into a (non-overflowing) long long, REDIS_ERR otherwise. The value + * will be set to the parsed value when appropriate. + * + * Note that this function demands that the string strictly represents + * a long long: no spaces or other characters before or after the string + * representing the number are accepted, nor zeroes at the start if not + * for the string "0" representing the zero number. + * + * Because of its strictness, it is safe to use this function to check if + * you can convert a string into a long long, and obtain back the string + * from the number without any loss in the string representation. */ +static int string2ll(const char *s, size_t slen, long long *value) { + const char *p = s; + size_t plen = 0; + int negative = 0; + unsigned long long v; + + if (plen == slen) + return REDIS_ERR; + + /* Special case: first and only digit is 0. */ + if (slen == 1 && p[0] == '0') { + if (value != NULL) *value = 0; + return REDIS_OK; + } + + if (p[0] == '-') { + negative = 1; + p++; plen++; + + /* Abort on only a negative sign. */ + if (plen == slen) + return REDIS_ERR; + } + + /* First digit should be 1-9, otherwise the string should just be 0. */ + if (p[0] >= '1' && p[0] <= '9') { + v = p[0]-'0'; + p++; plen++; + } else if (p[0] == '0' && slen == 1) { + *value = 0; + return REDIS_OK; + } else { + return REDIS_ERR; + } + + while (plen < slen && p[0] >= '0' && p[0] <= '9') { + if (v > (ULLONG_MAX / 10)) /* Overflow. */ + return REDIS_ERR; + v *= 10; + + if (v > (ULLONG_MAX - (p[0]-'0'))) /* Overflow. */ + return REDIS_ERR; + v += p[0]-'0'; + + p++; plen++; + } + + /* Return if not all bytes were used. */ + if (plen < slen) + return REDIS_ERR; + + if (negative) { + if (v > ((unsigned long long)(-(LLONG_MIN+1))+1)) /* Overflow. */ + return REDIS_ERR; + if (value != NULL) *value = -v; + } else { + if (v > LLONG_MAX) /* Overflow. */ + return REDIS_ERR; + if (value != NULL) *value = v; + } + return REDIS_OK; +} + +static char *readLine(redisReader *r, int *_len) { + char *p, *s; + int len; + + p = r->buf+r->pos; + s = seekNewline(p,(r->len-r->pos)); + if (s != NULL) { + len = s-(r->buf+r->pos); + r->pos += len+2; /* skip \r\n */ + if (_len) *_len = len; + return p; + } + return NULL; +} + +static void moveToNextTask(redisReader *r) { + redisReadTask *cur, *prv; + while (r->ridx >= 0) { + /* Return a.s.a.p. when the stack is now empty. */ + if (r->ridx == 0) { + r->ridx--; + return; + } + + cur = &(r->rstack[r->ridx]); + prv = &(r->rstack[r->ridx-1]); + assert(prv->type == REDIS_REPLY_ARRAY || + prv->type == REDIS_REPLY_MAP || + prv->type == REDIS_REPLY_SET); + if (cur->idx == prv->elements-1) { + r->ridx--; + } else { + /* Reset the type because the next item can be anything */ + assert(cur->idx < prv->elements); + cur->type = -1; + cur->elements = -1; + cur->idx++; + return; + } + } +} + +static int processLineItem(redisReader *r) { + redisReadTask *cur = &(r->rstack[r->ridx]); + void *obj; + char *p; + int len; + + if ((p = readLine(r,&len)) != NULL) { + if (cur->type == REDIS_REPLY_INTEGER) { + if (r->fn && r->fn->createInteger) { + long long v; + if (string2ll(p, len, &v) == REDIS_ERR) { + __redisReaderSetError(r,REDIS_ERR_PROTOCOL, + "Bad integer value"); + return REDIS_ERR; + } + obj = r->fn->createInteger(cur,v); + } else { + obj = (void*)REDIS_REPLY_INTEGER; + } + } else if (cur->type == REDIS_REPLY_DOUBLE) { + if (r->fn && r->fn->createDouble) { + char buf[326], *eptr; + double d; + + if ((size_t)len >= sizeof(buf)) { + __redisReaderSetError(r,REDIS_ERR_PROTOCOL, + "Double value is too large"); + return REDIS_ERR; + } + + memcpy(buf,p,len); + buf[len] = '\0'; + + if (strcasecmp(buf,",inf") == 0) { + d = INFINITY; /* Positive infinite. */ + } else if (strcasecmp(buf,",-inf") == 0) { + d = -INFINITY; /* Negative infinite. */ + } else { + d = strtod((char*)buf,&eptr); + if (buf[0] == '\0' || eptr[0] != '\0' || isnan(d)) { + __redisReaderSetError(r,REDIS_ERR_PROTOCOL, + "Bad double value"); + return REDIS_ERR; + } + } + obj = r->fn->createDouble(cur,d,buf,len); + } else { + obj = (void*)REDIS_REPLY_DOUBLE; + } + } else if (cur->type == REDIS_REPLY_NIL) { + if (r->fn && r->fn->createNil) + obj = r->fn->createNil(cur); + else + obj = (void*)REDIS_REPLY_NIL; + } else if (cur->type == REDIS_REPLY_BOOL) { + int bval = p[0] == 't' || p[0] == 'T'; + if (r->fn && r->fn->createBool) + obj = r->fn->createBool(cur,bval); + else + obj = (void*)REDIS_REPLY_BOOL; + } else { + /* Type will be error or status. */ + if (r->fn && r->fn->createString) + obj = r->fn->createString(cur,p,len); + else + obj = (void*)(size_t)(cur->type); + } + + if (obj == NULL) { + __redisReaderSetErrorOOM(r); + return REDIS_ERR; + } + + /* Set reply if this is the root object. */ + if (r->ridx == 0) r->reply = obj; + moveToNextTask(r); + return REDIS_OK; + } + + return REDIS_ERR; +} + +static int processBulkItem(redisReader *r) { + redisReadTask *cur = &(r->rstack[r->ridx]); + void *obj = NULL; + char *p, *s; + long long len; + unsigned long bytelen; + int success = 0; + + p = r->buf+r->pos; + s = seekNewline(p,r->len-r->pos); + if (s != NULL) { + p = r->buf+r->pos; + bytelen = s-(r->buf+r->pos)+2; /* include \r\n */ + + if (string2ll(p, bytelen - 2, &len) == REDIS_ERR) { + __redisReaderSetError(r,REDIS_ERR_PROTOCOL, + "Bad bulk string length"); + return REDIS_ERR; + } + + if (len < -1 || (LLONG_MAX > SIZE_MAX && len > (long long)SIZE_MAX)) { + __redisReaderSetError(r,REDIS_ERR_PROTOCOL, + "Bulk string length out of range"); + return REDIS_ERR; + } + + if (len == -1) { + /* The nil object can always be created. */ + if (r->fn && r->fn->createNil) + obj = r->fn->createNil(cur); + else + obj = (void*)REDIS_REPLY_NIL; + success = 1; + } else { + /* Only continue when the buffer contains the entire bulk item. */ + bytelen += len+2; /* include \r\n */ + if (r->pos+bytelen <= r->len) { + if (r->fn && r->fn->createString) + obj = r->fn->createString(cur,s+2,len); + else + obj = (void*)REDIS_REPLY_STRING; + success = 1; + } + } + + /* Proceed when obj was created. */ + if (success) { + if (obj == NULL) { + __redisReaderSetErrorOOM(r); + return REDIS_ERR; + } + + r->pos += bytelen; + + /* Set reply if this is the root object. */ + if (r->ridx == 0) r->reply = obj; + moveToNextTask(r); + return REDIS_OK; + } + } + + return REDIS_ERR; +} + +/* Process the array, map and set types. */ +static int processAggregateItem(redisReader *r) { + redisReadTask *cur = &(r->rstack[r->ridx]); + void *obj; + char *p; + long long elements; + int root = 0, len; + + /* Set error for nested multi bulks with depth > 7 */ + if (r->ridx == 8) { + __redisReaderSetError(r,REDIS_ERR_PROTOCOL, + "No support for nested multi bulk replies with depth > 7"); + return REDIS_ERR; + } + + if ((p = readLine(r,&len)) != NULL) { + if (string2ll(p, len, &elements) == REDIS_ERR) { + __redisReaderSetError(r,REDIS_ERR_PROTOCOL, + "Bad multi-bulk length"); + return REDIS_ERR; + } + + root = (r->ridx == 0); + + if (elements < -1 || (LLONG_MAX > SIZE_MAX && elements > SIZE_MAX)) { + __redisReaderSetError(r,REDIS_ERR_PROTOCOL, + "Multi-bulk length out of range"); + return REDIS_ERR; + } + + if (elements == -1) { + if (r->fn && r->fn->createNil) + obj = r->fn->createNil(cur); + else + obj = (void*)REDIS_REPLY_NIL; + + if (obj == NULL) { + __redisReaderSetErrorOOM(r); + return REDIS_ERR; + } + + moveToNextTask(r); + } else { + if (cur->type == REDIS_REPLY_MAP) elements *= 2; + + if (r->fn && r->fn->createArray) + obj = r->fn->createArray(cur,elements); + else + obj = (void*)(long)cur->type; + + if (obj == NULL) { + __redisReaderSetErrorOOM(r); + return REDIS_ERR; + } + + /* Modify task stack when there are more than 0 elements. */ + if (elements > 0) { + cur->elements = elements; + cur->obj = obj; + r->ridx++; + r->rstack[r->ridx].type = -1; + r->rstack[r->ridx].elements = -1; + r->rstack[r->ridx].idx = 0; + r->rstack[r->ridx].obj = NULL; + r->rstack[r->ridx].parent = cur; + r->rstack[r->ridx].privdata = r->privdata; + } else { + moveToNextTask(r); + } + } + + /* Set reply if this is the root object. */ + if (root) r->reply = obj; + return REDIS_OK; + } + + return REDIS_ERR; +} + +static int processItem(redisReader *r) { + redisReadTask *cur = &(r->rstack[r->ridx]); + char *p; + + /* check if we need to read type */ + if (cur->type < 0) { + if ((p = readBytes(r,1)) != NULL) { + switch (p[0]) { + case '-': + cur->type = REDIS_REPLY_ERROR; + break; + case '+': + cur->type = REDIS_REPLY_STATUS; + break; + case ':': + cur->type = REDIS_REPLY_INTEGER; + break; + case ',': + cur->type = REDIS_REPLY_DOUBLE; + break; + case '_': + cur->type = REDIS_REPLY_NIL; + break; + case '$': + cur->type = REDIS_REPLY_STRING; + break; + case '*': + cur->type = REDIS_REPLY_ARRAY; + break; + case '%': + cur->type = REDIS_REPLY_MAP; + break; + case '~': + cur->type = REDIS_REPLY_SET; + break; + case '#': + cur->type = REDIS_REPLY_BOOL; + break; + default: + __redisReaderSetErrorProtocolByte(r,*p); + return REDIS_ERR; + } + } else { + /* could not consume 1 byte */ + return REDIS_ERR; + } + } + + /* process typed item */ + switch(cur->type) { + case REDIS_REPLY_ERROR: + case REDIS_REPLY_STATUS: + case REDIS_REPLY_INTEGER: + case REDIS_REPLY_DOUBLE: + case REDIS_REPLY_NIL: + case REDIS_REPLY_BOOL: + return processLineItem(r); + case REDIS_REPLY_STRING: + return processBulkItem(r); + case REDIS_REPLY_ARRAY: + case REDIS_REPLY_MAP: + case REDIS_REPLY_SET: + return processAggregateItem(r); + default: + assert(NULL); + return REDIS_ERR; /* Avoid warning. */ + } +} + +redisReader *redisReaderCreateWithFunctions(redisReplyObjectFunctions *fn) { + redisReader *r; + + r = calloc(1,sizeof(redisReader)); + if (r == NULL) + return NULL; + + r->fn = fn; + r->buf = sdsempty(); + r->maxbuf = REDIS_READER_MAX_BUF; + if (r->buf == NULL) { + free(r); + return NULL; + } + + r->ridx = -1; + return r; +} + +void redisReaderFree(redisReader *r) { + if (r == NULL) + return; + if (r->reply != NULL && r->fn && r->fn->freeObject) + r->fn->freeObject(r->reply); + sdsfree(r->buf); + free(r); +} + +int redisReaderFeed(redisReader *r, const char *buf, size_t len) { + sds newbuf; + + /* Return early when this reader is in an erroneous state. */ + if (r->err) + return REDIS_ERR; + + /* Copy the provided buffer. */ + if (buf != NULL && len >= 1) { + /* Destroy internal buffer when it is empty and is quite large. */ + if (r->len == 0 && r->maxbuf != 0 && sdsavail(r->buf) > r->maxbuf) { + sdsfree(r->buf); + r->buf = sdsempty(); + r->pos = 0; + + /* r->buf should not be NULL since we just free'd a larger one. */ + assert(r->buf != NULL); + } + + newbuf = sdscatlen(r->buf,buf,len); + if (newbuf == NULL) { + __redisReaderSetErrorOOM(r); + return REDIS_ERR; + } + + r->buf = newbuf; + r->len = sdslen(r->buf); + } + + return REDIS_OK; +} + +int redisReaderGetReply(redisReader *r, void **reply) { + /* Default target pointer to NULL. */ + if (reply != NULL) + *reply = NULL; + + /* Return early when this reader is in an erroneous state. */ + if (r->err) + return REDIS_ERR; + + /* When the buffer is empty, there will never be a reply. */ + if (r->len == 0) + return REDIS_OK; + + /* Set first item to process when the stack is empty. */ + if (r->ridx == -1) { + r->rstack[0].type = -1; + r->rstack[0].elements = -1; + r->rstack[0].idx = -1; + r->rstack[0].obj = NULL; + r->rstack[0].parent = NULL; + r->rstack[0].privdata = r->privdata; + r->ridx = 0; + } + + /* Process items in reply. */ + while (r->ridx >= 0) + if (processItem(r) != REDIS_OK) + break; + + /* Return ASAP when an error occurred. */ + if (r->err) + return REDIS_ERR; + + /* Discard part of the buffer when we've consumed at least 1k, to avoid + * doing unnecessary calls to memmove() in sds.c. */ + if (r->pos >= 1024) { + sdsrange(r->buf,r->pos,-1); + r->pos = 0; + r->len = sdslen(r->buf); + } + + /* Emit a reply when there is one. */ + if (r->ridx == -1) { + if (reply != NULL) { + *reply = r->reply; + } else if (r->reply != NULL && r->fn && r->fn->freeObject) { + r->fn->freeObject(r->reply); + } + r->reply = NULL; + } + return REDIS_OK; +} diff --git a/俱乐部/Source/hiredis/read.h b/俱乐部/Source/hiredis/read.h new file mode 100644 index 0000000..af02aaf --- /dev/null +++ b/俱乐部/Source/hiredis/read.h @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2009-2011, Salvatore Sanfilippo + * Copyright (c) 2010-2011, Pieter Noordhuis + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Redis nor the names of its contributors may 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. + */ + + +#ifndef __HIREDIS_READ_H +#define __HIREDIS_READ_H +#include /* for size_t */ + +#define REDIS_ERR -1 +#define REDIS_OK 0 + +/* When an error occurs, the err flag in a context is set to hold the type of + * error that occurred. REDIS_ERR_IO means there was an I/O error and you + * should use the "errno" variable to find out what is wrong. + * For other values, the "errstr" field will hold a description. */ +#define REDIS_ERR_IO 1 /* Error in read or write */ +#define REDIS_ERR_EOF 3 /* End of file */ +#define REDIS_ERR_PROTOCOL 4 /* Protocol error */ +#define REDIS_ERR_OOM 5 /* Out of memory */ +#define REDIS_ERR_TIMEOUT 6 /* Timed out */ +#define REDIS_ERR_OTHER 2 /* Everything else... */ + +#define REDIS_REPLY_STRING 1 +#define REDIS_REPLY_ARRAY 2 +#define REDIS_REPLY_INTEGER 3 +#define REDIS_REPLY_NIL 4 +#define REDIS_REPLY_STATUS 5 +#define REDIS_REPLY_ERROR 6 +#define REDIS_REPLY_DOUBLE 7 +#define REDIS_REPLY_BOOL 8 +#define REDIS_REPLY_VERB 9 +#define REDIS_REPLY_MAP 9 +#define REDIS_REPLY_SET 10 +#define REDIS_REPLY_ATTR 11 +#define REDIS_REPLY_PUSH 12 +#define REDIS_REPLY_BIGNUM 13 + +#define REDIS_READER_MAX_BUF (1024*16) /* Default max unused reader buffer. */ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct redisReadTask { + int type; + int elements; /* number of elements in multibulk container */ + int idx; /* index in parent (array) object */ + void *obj; /* holds user-generated value for a read task */ + struct redisReadTask *parent; /* parent task */ + void *privdata; /* user-settable arbitrary field */ +} redisReadTask; + +typedef struct redisReplyObjectFunctions { + void *(*createString)(const redisReadTask*, char*, size_t); + void *(*createArray)(const redisReadTask*, size_t); + void *(*createInteger)(const redisReadTask*, long long); + void *(*createDouble)(const redisReadTask*, double, char*, size_t); + void *(*createNil)(const redisReadTask*); + void *(*createBool)(const redisReadTask*, int); + void (*freeObject)(void*); +} redisReplyObjectFunctions; + +typedef struct redisReader { + int err; /* Error flags, 0 when there is no error */ + char errstr[128]; /* String representation of error when applicable */ + + char *buf; /* Read buffer */ + size_t pos; /* Buffer cursor */ + size_t len; /* Buffer length */ + size_t maxbuf; /* Max length of unused buffer */ + + redisReadTask rstack[9]; + int ridx; /* Index of current read task */ + void *reply; /* Temporary reply pointer */ + + redisReplyObjectFunctions *fn; + void *privdata; +} redisReader; + +/* Public API for the protocol parser. */ +redisReader *redisReaderCreateWithFunctions(redisReplyObjectFunctions *fn); +void redisReaderFree(redisReader *r); +int redisReaderFeed(redisReader *r, const char *buf, size_t len); +int redisReaderGetReply(redisReader *r, void **reply); + +#define redisReaderSetPrivdata(_r, _p) (int)(((redisReader*)(_r))->privdata = (_p)) +#define redisReaderGetObject(_r) (((redisReader*)(_r))->reply) +#define redisReaderGetError(_r) (((redisReader*)(_r))->errstr) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/俱乐部/Source/hiredis/sds.c b/俱乐部/Source/hiredis/sds.c new file mode 100644 index 0000000..6cf7584 --- /dev/null +++ b/俱乐部/Source/hiredis/sds.c @@ -0,0 +1,1291 @@ +/* SDSLib 2.0 -- A C dynamic strings library + * + * Copyright (c) 2006-2015, Salvatore Sanfilippo + * Copyright (c) 2015, Oran Agra + * Copyright (c) 2015, Redis Labs, Inc + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Redis nor the names of its contributors may 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. + */ + +#include +#include +#include +#include +#include +#include "sds.h" +#include "sdsalloc.h" + +static inline int sdsHdrSize(char type) { + switch(type&SDS_TYPE_MASK) { + case SDS_TYPE_5: + return sizeof(struct sdshdr5); + case SDS_TYPE_8: + return sizeof(struct sdshdr8); + case SDS_TYPE_16: + return sizeof(struct sdshdr16); + case SDS_TYPE_32: + return sizeof(struct sdshdr32); + case SDS_TYPE_64: + return sizeof(struct sdshdr64); + } + return 0; +} + +static inline char sdsReqType(size_t string_size) { + if (string_size < 32) + return SDS_TYPE_5; + if (string_size < 0xff) + return SDS_TYPE_8; + if (string_size < 0xffff) + return SDS_TYPE_16; + if (string_size < 0xffffffff) + return SDS_TYPE_32; + return SDS_TYPE_64; +} + +/* Create a new sds string with the content specified by the 'init' pointer + * and 'initlen'. + * If NULL is used for 'init' the string is initialized with zero bytes. + * + * The string is always null-termined (all the sds strings are, always) so + * even if you create an sds string with: + * + * mystring = sdsnewlen("abc",3); + * + * You can print the string with printf() as there is an implicit \0 at the + * end of the string. However the string is binary safe and can contain + * \0 characters in the middle, as the length is stored in the sds header. */ +sds sdsnewlen(const void *init, size_t initlen) { + void *sh; + sds s; + char type = sdsReqType(initlen); + /* Empty strings are usually created in order to append. Use type 8 + * since type 5 is not good at this. */ + if (type == SDS_TYPE_5 && initlen == 0) type = SDS_TYPE_8; + int hdrlen = sdsHdrSize(type); + unsigned char *fp; /* flags pointer. */ + + sh = s_malloc(hdrlen+initlen+1); + if (sh == NULL) return NULL; + if (!init) + memset(sh, 0, hdrlen+initlen+1); + s = (char*)sh+hdrlen; + fp = ((unsigned char*)s)-1; + switch(type) { + case SDS_TYPE_5: { + *fp = type | (initlen << SDS_TYPE_BITS); + break; + } + case SDS_TYPE_8: { + SDS_HDR_VAR(8,s); + sh->len = initlen; + sh->alloc = initlen; + *fp = type; + break; + } + case SDS_TYPE_16: { + SDS_HDR_VAR(16,s); + sh->len = initlen; + sh->alloc = initlen; + *fp = type; + break; + } + case SDS_TYPE_32: { + SDS_HDR_VAR(32,s); + sh->len = initlen; + sh->alloc = initlen; + *fp = type; + break; + } + case SDS_TYPE_64: { + SDS_HDR_VAR(64,s); + sh->len = initlen; + sh->alloc = initlen; + *fp = type; + break; + } + } + if (initlen && init) + memcpy(s, init, initlen); + s[initlen] = '\0'; + return s; +} + +/* Create an empty (zero length) sds string. Even in this case the string + * always has an implicit null term. */ +sds sdsempty(void) { + return sdsnewlen("",0); +} + +/* Create a new sds string starting from a null terminated C string. */ +sds sdsnew(const char *init) { + size_t initlen = (init == NULL) ? 0 : strlen(init); + return sdsnewlen(init, initlen); +} + +/* Duplicate an sds string. */ +sds sdsdup(const sds s) { + return sdsnewlen(s, sdslen(s)); +} + +/* Free an sds string. No operation is performed if 's' is NULL. */ +void sdsfree(sds s) { + if (s == NULL) return; + s_free((char*)s-sdsHdrSize(s[-1])); +} + +/* Set the sds string length to the length as obtained with strlen(), so + * considering as content only up to the first null term character. + * + * This function is useful when the sds string is hacked manually in some + * way, like in the following example: + * + * s = sdsnew("foobar"); + * s[2] = '\0'; + * sdsupdatelen(s); + * printf("%d\n", sdslen(s)); + * + * The output will be "2", but if we comment out the call to sdsupdatelen() + * the output will be "6" as the string was modified but the logical length + * remains 6 bytes. */ +void sdsupdatelen(sds s) { + int reallen = strlen(s); + sdssetlen(s, reallen); +} + +/* Modify an sds string in-place to make it empty (zero length). + * However all the existing buffer is not discarded but set as free space + * so that next append operations will not require allocations up to the + * number of bytes previously available. */ +void sdsclear(sds s) { + sdssetlen(s, 0); + s[0] = '\0'; +} + +/* Enlarge the free space at the end of the sds string so that the caller + * is sure that after calling this function can overwrite up to addlen + * bytes after the end of the string, plus one more byte for nul term. + * + * Note: this does not change the *length* of the sds string as returned + * by sdslen(), but only the free buffer space we have. */ +sds sdsMakeRoomFor(sds s, size_t addlen) { + void *sh, *newsh; + size_t avail = sdsavail(s); + size_t len, newlen; + char type, oldtype = s[-1] & SDS_TYPE_MASK; + int hdrlen; + + /* Return ASAP if there is enough space left. */ + if (avail >= addlen) return s; + + len = sdslen(s); + sh = (char*)s-sdsHdrSize(oldtype); + newlen = (len+addlen); + if (newlen < SDS_MAX_PREALLOC) + newlen *= 2; + else + newlen += SDS_MAX_PREALLOC; + + type = sdsReqType(newlen); + + /* Don't use type 5: the user is appending to the string and type 5 is + * not able to remember empty space, so sdsMakeRoomFor() must be called + * at every appending operation. */ + if (type == SDS_TYPE_5) type = SDS_TYPE_8; + + hdrlen = sdsHdrSize(type); + if (oldtype==type) { + newsh = s_realloc(sh, hdrlen+newlen+1); + if (newsh == NULL) { + s_free(sh); + return NULL; + } + s = (char*)newsh+hdrlen; + } else { + /* Since the header size changes, need to move the string forward, + * and can't use realloc */ + newsh = s_malloc(hdrlen+newlen+1); + if (newsh == NULL) return NULL; + memcpy((char*)newsh+hdrlen, s, len+1); + s_free(sh); + s = (char*)newsh+hdrlen; + s[-1] = type; + sdssetlen(s, len); + } + sdssetalloc(s, newlen); + return s; +} + +/* Reallocate the sds string so that it has no free space at the end. The + * contained string remains not altered, but next concatenation operations + * will require a reallocation. + * + * After the call, the passed sds string is no longer valid and all the + * references must be substituted with the new pointer returned by the call. */ +sds sdsRemoveFreeSpace(sds s) { + void *sh, *newsh; + char type, oldtype = s[-1] & SDS_TYPE_MASK; + int hdrlen; + size_t len = sdslen(s); + sh = (char*)s-sdsHdrSize(oldtype); + + type = sdsReqType(len); + hdrlen = sdsHdrSize(type); + if (oldtype==type) { + newsh = s_realloc(sh, hdrlen+len+1); + if (newsh == NULL) return NULL; + s = (char*)newsh+hdrlen; + } else { + newsh = s_malloc(hdrlen+len+1); + if (newsh == NULL) return NULL; + memcpy((char*)newsh+hdrlen, s, len+1); + s_free(sh); + s = (char*)newsh+hdrlen; + s[-1] = type; + sdssetlen(s, len); + } + sdssetalloc(s, len); + return s; +} + +/* Return the total size of the allocation of the specifed sds string, + * including: + * 1) The sds header before the pointer. + * 2) The string. + * 3) The free buffer at the end if any. + * 4) The implicit null term. + */ +size_t sdsAllocSize(sds s) { + size_t alloc = sdsalloc(s); + return sdsHdrSize(s[-1])+alloc+1; +} + +/* Return the pointer of the actual SDS allocation (normally SDS strings + * are referenced by the start of the string buffer). */ +void *sdsAllocPtr(sds s) { + return (void*) (s-sdsHdrSize(s[-1])); +} + +/* Increment the sds length and decrements the left free space at the + * end of the string according to 'incr'. Also set the null term + * in the new end of the string. + * + * This function is used in order to fix the string length after the + * user calls sdsMakeRoomFor(), writes something after the end of + * the current string, and finally needs to set the new length. + * + * Note: it is possible to use a negative increment in order to + * right-trim the string. + * + * Usage example: + * + * Using sdsIncrLen() and sdsMakeRoomFor() it is possible to mount the + * following schema, to cat bytes coming from the kernel to the end of an + * sds string without copying into an intermediate buffer: + * + * oldlen = sdslen(s); + * s = sdsMakeRoomFor(s, BUFFER_SIZE); + * nread = read(fd, s+oldlen, BUFFER_SIZE); + * ... check for nread <= 0 and handle it ... + * sdsIncrLen(s, nread); + */ +void sdsIncrLen(sds s, int incr) { + unsigned char flags = s[-1]; + size_t len; + switch(flags&SDS_TYPE_MASK) { + case SDS_TYPE_5: { + unsigned char *fp = ((unsigned char*)s)-1; + unsigned char oldlen = SDS_TYPE_5_LEN(flags); + assert((incr > 0 && oldlen+incr < 32) || (incr < 0 && oldlen >= (unsigned int)(-incr))); + *fp = SDS_TYPE_5 | ((oldlen+incr) << SDS_TYPE_BITS); + len = oldlen+incr; + break; + } + case SDS_TYPE_8: { + SDS_HDR_VAR(8,s); + assert((incr >= 0 && sh->alloc-sh->len >= incr) || (incr < 0 && sh->len >= (unsigned int)(-incr))); + len = (sh->len += incr); + break; + } + case SDS_TYPE_16: { + SDS_HDR_VAR(16,s); + assert((incr >= 0 && sh->alloc-sh->len >= incr) || (incr < 0 && sh->len >= (unsigned int)(-incr))); + len = (sh->len += incr); + break; + } + case SDS_TYPE_32: { + SDS_HDR_VAR(32,s); + assert((incr >= 0 && sh->alloc-sh->len >= (unsigned int)incr) || (incr < 0 && sh->len >= (unsigned int)(-incr))); + len = (sh->len += incr); + break; + } + case SDS_TYPE_64: { + SDS_HDR_VAR(64,s); + assert((incr >= 0 && sh->alloc-sh->len >= (uint64_t)incr) || (incr < 0 && sh->len >= (uint64_t)(-incr))); + len = (sh->len += incr); + break; + } + default: len = 0; /* Just to avoid compilation warnings. */ + } + s[len] = '\0'; +} + +/* Grow the sds to have the specified length. Bytes that were not part of + * the original length of the sds will be set to zero. + * + * if the specified length is smaller than the current length, no operation + * is performed. */ +sds sdsgrowzero(sds s, size_t len) { + size_t curlen = sdslen(s); + + if (len <= curlen) return s; + s = sdsMakeRoomFor(s,len-curlen); + if (s == NULL) return NULL; + + /* Make sure added region doesn't contain garbage */ + memset(s+curlen,0,(len-curlen+1)); /* also set trailing \0 byte */ + sdssetlen(s, len); + return s; +} + +/* Append the specified binary-safe string pointed by 't' of 'len' bytes to the + * end of the specified sds string 's'. + * + * After the call, the passed sds string is no longer valid and all the + * references must be substituted with the new pointer returned by the call. */ +sds sdscatlen(sds s, const void *t, size_t len) { + size_t curlen = sdslen(s); + + s = sdsMakeRoomFor(s,len); + if (s == NULL) return NULL; + memcpy(s+curlen, t, len); + sdssetlen(s, curlen+len); + s[curlen+len] = '\0'; + return s; +} + +/* Append the specified null termianted C string to the sds string 's'. + * + * After the call, the passed sds string is no longer valid and all the + * references must be substituted with the new pointer returned by the call. */ +sds sdscat(sds s, const char *t) { + return sdscatlen(s, t, strlen(t)); +} + +/* Append the specified sds 't' to the existing sds 's'. + * + * After the call, the modified sds string is no longer valid and all the + * references must be substituted with the new pointer returned by the call. */ +sds sdscatsds(sds s, const sds t) { + return sdscatlen(s, t, sdslen(t)); +} + +/* Destructively modify the sds string 's' to hold the specified binary + * safe string pointed by 't' of length 'len' bytes. */ +sds sdscpylen(sds s, const char *t, size_t len) { + if (sdsalloc(s) < len) { + s = sdsMakeRoomFor(s,len-sdslen(s)); + if (s == NULL) return NULL; + } + memcpy(s, t, len); + s[len] = '\0'; + sdssetlen(s, len); + return s; +} + +/* Like sdscpylen() but 't' must be a null-termined string so that the length + * of the string is obtained with strlen(). */ +sds sdscpy(sds s, const char *t) { + return sdscpylen(s, t, strlen(t)); +} + +/* Helper for sdscatlonglong() doing the actual number -> string + * conversion. 's' must point to a string with room for at least + * SDS_LLSTR_SIZE bytes. + * + * The function returns the length of the null-terminated string + * representation stored at 's'. */ +#define SDS_LLSTR_SIZE 21 +int sdsll2str(char *s, long long value) { + char *p, aux; + unsigned long long v; + size_t l; + + /* Generate the string representation, this method produces + * an reversed string. */ + v = (value < 0) ? -value : value; + p = s; + do { + *p++ = '0'+(v%10); + v /= 10; + } while(v); + if (value < 0) *p++ = '-'; + + /* Compute length and add null term. */ + l = p-s; + *p = '\0'; + + /* Reverse the string. */ + p--; + while(s < p) { + aux = *s; + *s = *p; + *p = aux; + s++; + p--; + } + return l; +} + +/* Identical sdsll2str(), but for unsigned long long type. */ +int sdsull2str(char *s, unsigned long long v) { + char *p, aux; + size_t l; + + /* Generate the string representation, this method produces + * an reversed string. */ + p = s; + do { + *p++ = '0'+(v%10); + v /= 10; + } while(v); + + /* Compute length and add null term. */ + l = p-s; + *p = '\0'; + + /* Reverse the string. */ + p--; + while(s < p) { + aux = *s; + *s = *p; + *p = aux; + s++; + p--; + } + return l; +} + +/* Create an sds string from a long long value. It is much faster than: + * + * sdscatprintf(sdsempty(),"%lld\n", value); + */ +sds sdsfromlonglong(long long value) { + char buf[SDS_LLSTR_SIZE]; + int len = sdsll2str(buf,value); + + return sdsnewlen(buf,len); +} + +/* Like sdscatprintf() but gets va_list instead of being variadic. */ +sds sdscatvprintf(sds s, const char *fmt, va_list ap) { + va_list cpy; + char staticbuf[1024], *buf = staticbuf, *t; + size_t buflen = strlen(fmt)*2; + + /* We try to start using a static buffer for speed. + * If not possible we revert to heap allocation. */ + if (buflen > sizeof(staticbuf)) { + buf = s_malloc(buflen); + if (buf == NULL) return NULL; + } else { + buflen = sizeof(staticbuf); + } + + /* Try with buffers two times bigger every time we fail to + * fit the string in the current buffer size. */ + while(1) { + buf[buflen-2] = '\0'; + va_copy(cpy,ap); + vsnprintf(buf, buflen, fmt, cpy); + va_end(cpy); + if (buf[buflen-2] != '\0') { + if (buf != staticbuf) s_free(buf); + buflen *= 2; + buf = s_malloc(buflen); + if (buf == NULL) return NULL; + continue; + } + break; + } + + /* Finally concat the obtained string to the SDS string and return it. */ + t = sdscat(s, buf); + if (buf != staticbuf) s_free(buf); + return t; +} + +/* Append to the sds string 's' a string obtained using printf-alike format + * specifier. + * + * After the call, the modified sds string is no longer valid and all the + * references must be substituted with the new pointer returned by the call. + * + * Example: + * + * s = sdsnew("Sum is: "); + * s = sdscatprintf(s,"%d+%d = %d",a,b,a+b). + * + * Often you need to create a string from scratch with the printf-alike + * format. When this is the need, just use sdsempty() as the target string: + * + * s = sdscatprintf(sdsempty(), "... your format ...", args); + */ +sds sdscatprintf(sds s, const char *fmt, ...) { + va_list ap; + char *t; + va_start(ap, fmt); + t = sdscatvprintf(s,fmt,ap); + va_end(ap); + return t; +} + +/* This function is similar to sdscatprintf, but much faster as it does + * not rely on sprintf() family functions implemented by the libc that + * are often very slow. Moreover directly handling the sds string as + * new data is concatenated provides a performance improvement. + * + * However this function only handles an incompatible subset of printf-alike + * format specifiers: + * + * %s - C String + * %S - SDS string + * %i - signed int + * %I - 64 bit signed integer (long long, int64_t) + * %u - unsigned int + * %U - 64 bit unsigned integer (unsigned long long, uint64_t) + * %% - Verbatim "%" character. + */ +sds sdscatfmt(sds s, char const *fmt, ...) { + const char *f = fmt; + int i; + va_list ap; + + va_start(ap,fmt); + i = sdslen(s); /* Position of the next byte to write to dest str. */ + while(*f) { + char next, *str; + size_t l; + long long num; + unsigned long long unum; + + /* Make sure there is always space for at least 1 char. */ + if (sdsavail(s)==0) { + s = sdsMakeRoomFor(s,1); + if (s == NULL) goto fmt_error; + } + + switch(*f) { + case '%': + next = *(f+1); + f++; + switch(next) { + case 's': + case 'S': + str = va_arg(ap,char*); + l = (next == 's') ? strlen(str) : sdslen(str); + if (sdsavail(s) < l) { + s = sdsMakeRoomFor(s,l); + if (s == NULL) goto fmt_error; + } + memcpy(s+i,str,l); + sdsinclen(s,l); + i += l; + break; + case 'i': + case 'I': + if (next == 'i') + num = va_arg(ap,int); + else + num = va_arg(ap,long long); + { + char buf[SDS_LLSTR_SIZE]; + l = sdsll2str(buf,num); + if (sdsavail(s) < l) { + s = sdsMakeRoomFor(s,l); + if (s == NULL) goto fmt_error; + } + memcpy(s+i,buf,l); + sdsinclen(s,l); + i += l; + } + break; + case 'u': + case 'U': + if (next == 'u') + unum = va_arg(ap,unsigned int); + else + unum = va_arg(ap,unsigned long long); + { + char buf[SDS_LLSTR_SIZE]; + l = sdsull2str(buf,unum); + if (sdsavail(s) < l) { + s = sdsMakeRoomFor(s,l); + if (s == NULL) goto fmt_error; + } + memcpy(s+i,buf,l); + sdsinclen(s,l); + i += l; + } + break; + default: /* Handle %% and generally %. */ + s[i++] = next; + sdsinclen(s,1); + break; + } + break; + default: + s[i++] = *f; + sdsinclen(s,1); + break; + } + f++; + } + va_end(ap); + + /* Add null-term */ + s[i] = '\0'; + return s; + +fmt_error: + va_end(ap); + return NULL; +} + +/* Remove the part of the string from left and from right composed just of + * contiguous characters found in 'cset', that is a null terminted C string. + * + * After the call, the modified sds string is no longer valid and all the + * references must be substituted with the new pointer returned by the call. + * + * Example: + * + * s = sdsnew("AA...AA.a.aa.aHelloWorld :::"); + * s = sdstrim(s,"Aa. :"); + * printf("%s\n", s); + * + * Output will be just "Hello World". + */ +sds sdstrim(sds s, const char *cset) { + char *start, *end, *sp, *ep; + size_t len; + + sp = start = s; + ep = end = s+sdslen(s)-1; + while(sp <= end && strchr(cset, *sp)) sp++; + while(ep > sp && strchr(cset, *ep)) ep--; + len = (sp > ep) ? 0 : ((ep-sp)+1); + if (s != sp) memmove(s, sp, len); + s[len] = '\0'; + sdssetlen(s,len); + return s; +} + +/* Turn the string into a smaller (or equal) string containing only the + * substring specified by the 'start' and 'end' indexes. + * + * start and end can be negative, where -1 means the last character of the + * string, -2 the penultimate character, and so forth. + * + * The interval is inclusive, so the start and end characters will be part + * of the resulting string. + * + * The string is modified in-place. + * + * Example: + * + * s = sdsnew("Hello World"); + * sdsrange(s,1,-1); => "ello World" + */ +void sdsrange(sds s, int start, int end) { + size_t newlen, len = sdslen(s); + + if (len == 0) return; + if (start < 0) { + start = len+start; + if (start < 0) start = 0; + } + if (end < 0) { + end = len+end; + if (end < 0) end = 0; + } + newlen = (start > end) ? 0 : (end-start)+1; + if (newlen != 0) { + if (start >= (signed)len) { + newlen = 0; + } else if (end >= (signed)len) { + end = len-1; + newlen = (start > end) ? 0 : (end-start)+1; + } + } else { + start = 0; + } + if (start && newlen) memmove(s, s+start, newlen); + s[newlen] = 0; + sdssetlen(s,newlen); +} + +/* Apply tolower() to every character of the sds string 's'. */ +void sdstolower(sds s) { + int len = sdslen(s), j; + + for (j = 0; j < len; j++) s[j] = tolower(s[j]); +} + +/* Apply toupper() to every character of the sds string 's'. */ +void sdstoupper(sds s) { + int len = sdslen(s), j; + + for (j = 0; j < len; j++) s[j] = toupper(s[j]); +} + +/* Compare two sds strings s1 and s2 with memcmp(). + * + * Return value: + * + * positive if s1 > s2. + * negative if s1 < s2. + * 0 if s1 and s2 are exactly the same binary string. + * + * If two strings share exactly the same prefix, but one of the two has + * additional characters, the longer string is considered to be greater than + * the smaller one. */ +int sdscmp(const sds s1, const sds s2) { + size_t l1, l2, minlen; + int cmp; + + l1 = sdslen(s1); + l2 = sdslen(s2); + minlen = (l1 < l2) ? l1 : l2; + cmp = memcmp(s1,s2,minlen); + if (cmp == 0) return l1-l2; + return cmp; +} + +/* Split 's' with separator in 'sep'. An array + * of sds strings is returned. *count will be set + * by reference to the number of tokens returned. + * + * On out of memory, zero length string, zero length + * separator, NULL is returned. + * + * Note that 'sep' is able to split a string using + * a multi-character separator. For example + * sdssplit("foo_-_bar","_-_"); will return two + * elements "foo" and "bar". + * + * This version of the function is binary-safe but + * requires length arguments. sdssplit() is just the + * same function but for zero-terminated strings. + */ +sds *sdssplitlen(const char *s, int len, const char *sep, int seplen, int *count) { + int elements = 0, slots = 5, start = 0, j; + sds *tokens; + + if (seplen < 1 || len < 0) return NULL; + + tokens = s_malloc(sizeof(sds)*slots); + if (tokens == NULL) return NULL; + + if (len == 0) { + *count = 0; + return tokens; + } + for (j = 0; j < (len-(seplen-1)); j++) { + /* make sure there is room for the next element and the final one */ + if (slots < elements+2) { + sds *newtokens; + + slots *= 2; + newtokens = s_realloc(tokens,sizeof(sds)*slots); + if (newtokens == NULL) goto cleanup; + tokens = newtokens; + } + /* search the separator */ + if ((seplen == 1 && *(s+j) == sep[0]) || (memcmp(s+j,sep,seplen) == 0)) { + tokens[elements] = sdsnewlen(s+start,j-start); + if (tokens[elements] == NULL) goto cleanup; + elements++; + start = j+seplen; + j = j+seplen-1; /* skip the separator */ + } + } + /* Add the final element. We are sure there is room in the tokens array. */ + tokens[elements] = sdsnewlen(s+start,len-start); + if (tokens[elements] == NULL) goto cleanup; + elements++; + *count = elements; + return tokens; + +cleanup: + { + int i; + for (i = 0; i < elements; i++) sdsfree(tokens[i]); + s_free(tokens); + *count = 0; + return NULL; + } +} + +/* Free the result returned by sdssplitlen(), or do nothing if 'tokens' is NULL. */ +void sdsfreesplitres(sds *tokens, int count) { + if (!tokens) return; + while(count--) + sdsfree(tokens[count]); + s_free(tokens); +} + +/* Append to the sds string "s" an escaped string representation where + * all the non-printable characters (tested with isprint()) are turned into + * escapes in the form "\n\r\a...." or "\x". + * + * After the call, the modified sds string is no longer valid and all the + * references must be substituted with the new pointer returned by the call. */ +sds sdscatrepr(sds s, const char *p, size_t len) { + s = sdscatlen(s,"\"",1); + while(len--) { + switch(*p) { + case '\\': + case '"': + s = sdscatprintf(s,"\\%c",*p); + break; + case '\n': s = sdscatlen(s,"\\n",2); break; + case '\r': s = sdscatlen(s,"\\r",2); break; + case '\t': s = sdscatlen(s,"\\t",2); break; + case '\a': s = sdscatlen(s,"\\a",2); break; + case '\b': s = sdscatlen(s,"\\b",2); break; + default: + if (isprint(*p)) + s = sdscatprintf(s,"%c",*p); + else + s = sdscatprintf(s,"\\x%02x",(unsigned char)*p); + break; + } + p++; + } + return sdscatlen(s,"\"",1); +} + +/* Helper function for sdssplitargs() that returns non zero if 'c' + * is a valid hex digit. */ +int is_hex_digit(char c) { + return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || + (c >= 'A' && c <= 'F'); +} + +/* Helper function for sdssplitargs() that converts a hex digit into an + * integer from 0 to 15 */ +int hex_digit_to_int(char c) { + switch(c) { + case '0': return 0; + case '1': return 1; + case '2': return 2; + case '3': return 3; + case '4': return 4; + case '5': return 5; + case '6': return 6; + case '7': return 7; + case '8': return 8; + case '9': return 9; + case 'a': case 'A': return 10; + case 'b': case 'B': return 11; + case 'c': case 'C': return 12; + case 'd': case 'D': return 13; + case 'e': case 'E': return 14; + case 'f': case 'F': return 15; + default: return 0; + } +} + +/* Split a line into arguments, where every argument can be in the + * following programming-language REPL-alike form: + * + * foo bar "newline are supported\n" and "\xff\x00otherstuff" + * + * The number of arguments is stored into *argc, and an array + * of sds is returned. + * + * The caller should free the resulting array of sds strings with + * sdsfreesplitres(). + * + * Note that sdscatrepr() is able to convert back a string into + * a quoted string in the same format sdssplitargs() is able to parse. + * + * The function returns the allocated tokens on success, even when the + * input string is empty, or NULL if the input contains unbalanced + * quotes or closed quotes followed by non space characters + * as in: "foo"bar or "foo' + */ +sds *sdssplitargs(const char *line, int *argc) { + const char *p = line; + char *current = NULL; + char **vector = NULL; + + *argc = 0; + while(1) { + /* skip blanks */ + while(*p && isspace(*p)) p++; + if (*p) { + /* get a token */ + int inq=0; /* set to 1 if we are in "quotes" */ + int insq=0; /* set to 1 if we are in 'single quotes' */ + int done=0; + + if (current == NULL) current = sdsempty(); + while(!done) { + if (inq) { + if (*p == '\\' && *(p+1) == 'x' && + is_hex_digit(*(p+2)) && + is_hex_digit(*(p+3))) + { + unsigned char byte; + + byte = (hex_digit_to_int(*(p+2))*16)+ + hex_digit_to_int(*(p+3)); + current = sdscatlen(current,(char*)&byte,1); + p += 3; + } else if (*p == '\\' && *(p+1)) { + char c; + + p++; + switch(*p) { + case 'n': c = '\n'; break; + case 'r': c = '\r'; break; + case 't': c = '\t'; break; + case 'b': c = '\b'; break; + case 'a': c = '\a'; break; + default: c = *p; break; + } + current = sdscatlen(current,&c,1); + } else if (*p == '"') { + /* closing quote must be followed by a space or + * nothing at all. */ + if (*(p+1) && !isspace(*(p+1))) goto err; + done=1; + } else if (!*p) { + /* unterminated quotes */ + goto err; + } else { + current = sdscatlen(current,p,1); + } + } else if (insq) { + if (*p == '\\' && *(p+1) == '\'') { + p++; + current = sdscatlen(current,"'",1); + } else if (*p == '\'') { + /* closing quote must be followed by a space or + * nothing at all. */ + if (*(p+1) && !isspace(*(p+1))) goto err; + done=1; + } else if (!*p) { + /* unterminated quotes */ + goto err; + } else { + current = sdscatlen(current,p,1); + } + } else { + switch(*p) { + case ' ': + case '\n': + case '\r': + case '\t': + case '\0': + done=1; + break; + case '"': + inq=1; + break; + case '\'': + insq=1; + break; + default: + current = sdscatlen(current,p,1); + break; + } + } + if (*p) p++; + } + /* add the token to the vector */ + { + char **new_vector = s_realloc(vector,((*argc)+1)*sizeof(char*)); + if (new_vector == NULL) { + s_free(vector); + return NULL; + } + + vector = new_vector; + vector[*argc] = current; + (*argc)++; + current = NULL; + } + } else { + /* Even on empty input string return something not NULL. */ + if (vector == NULL) vector = s_malloc(sizeof(void*)); + return vector; + } + } + +err: + while((*argc)--) + sdsfree(vector[*argc]); + s_free(vector); + if (current) sdsfree(current); + *argc = 0; + return NULL; +} + +/* Modify the string substituting all the occurrences of the set of + * characters specified in the 'from' string to the corresponding character + * in the 'to' array. + * + * For instance: sdsmapchars(mystring, "ho", "01", 2) + * will have the effect of turning the string "hello" into "0ell1". + * + * The function returns the sds string pointer, that is always the same + * as the input pointer since no resize is needed. */ +sds sdsmapchars(sds s, const char *from, const char *to, size_t setlen) { + size_t j, i, l = sdslen(s); + + for (j = 0; j < l; j++) { + for (i = 0; i < setlen; i++) { + if (s[j] == from[i]) { + s[j] = to[i]; + break; + } + } + } + return s; +} + +/* Join an array of C strings using the specified separator (also a C string). + * Returns the result as an sds string. */ +sds sdsjoin(char **argv, int argc, char *sep) { + sds join = sdsempty(); + int j; + + for (j = 0; j < argc; j++) { + join = sdscat(join, argv[j]); + if (j != argc-1) join = sdscat(join,sep); + } + return join; +} + +/* Like sdsjoin, but joins an array of SDS strings. */ +sds sdsjoinsds(sds *argv, int argc, const char *sep, size_t seplen) { + sds join = sdsempty(); + int j; + + for (j = 0; j < argc; j++) { + join = sdscatsds(join, argv[j]); + if (j != argc-1) join = sdscatlen(join,sep,seplen); + } + return join; +} + +/* Wrappers to the allocators used by SDS. Note that SDS will actually + * just use the macros defined into sdsalloc.h in order to avoid to pay + * the overhead of function calls. Here we define these wrappers only for + * the programs SDS is linked to, if they want to touch the SDS internals + * even if they use a different allocator. */ +void *sds_malloc(size_t size) { return s_malloc(size); } +void *sds_realloc(void *ptr, size_t size) { return s_realloc(ptr,size); } +void sds_free(void *ptr) { s_free(ptr); } + +#if defined(SDS_TEST_MAIN) +#include +#include "testhelp.h" +#include "limits.h" + +#define UNUSED(x) (void)(x) +int sdsTest(void) { + { + sds x = sdsnew("foo"), y; + + test_cond("Create a string and obtain the length", + sdslen(x) == 3 && memcmp(x,"foo\0",4) == 0) + + sdsfree(x); + x = sdsnewlen("foo",2); + test_cond("Create a string with specified length", + sdslen(x) == 2 && memcmp(x,"fo\0",3) == 0) + + x = sdscat(x,"bar"); + test_cond("Strings concatenation", + sdslen(x) == 5 && memcmp(x,"fobar\0",6) == 0); + + x = sdscpy(x,"a"); + test_cond("sdscpy() against an originally longer string", + sdslen(x) == 1 && memcmp(x,"a\0",2) == 0) + + x = sdscpy(x,"xyzxxxxxxxxxxyyyyyyyyyykkkkkkkkkk"); + test_cond("sdscpy() against an originally shorter string", + sdslen(x) == 33 && + memcmp(x,"xyzxxxxxxxxxxyyyyyyyyyykkkkkkkkkk\0",33) == 0) + + sdsfree(x); + x = sdscatprintf(sdsempty(),"%d",123); + test_cond("sdscatprintf() seems working in the base case", + sdslen(x) == 3 && memcmp(x,"123\0",4) == 0) + + sdsfree(x); + x = sdsnew("--"); + x = sdscatfmt(x, "Hello %s World %I,%I--", "Hi!", LLONG_MIN,LLONG_MAX); + test_cond("sdscatfmt() seems working in the base case", + sdslen(x) == 60 && + memcmp(x,"--Hello Hi! World -9223372036854775808," + "9223372036854775807--",60) == 0) + printf("[%s]\n",x); + + sdsfree(x); + x = sdsnew("--"); + x = sdscatfmt(x, "%u,%U--", UINT_MAX, ULLONG_MAX); + test_cond("sdscatfmt() seems working with unsigned numbers", + sdslen(x) == 35 && + memcmp(x,"--4294967295,18446744073709551615--",35) == 0) + + sdsfree(x); + x = sdsnew(" x "); + sdstrim(x," x"); + test_cond("sdstrim() works when all chars match", + sdslen(x) == 0) + + sdsfree(x); + x = sdsnew(" x "); + sdstrim(x," "); + test_cond("sdstrim() works when a single char remains", + sdslen(x) == 1 && x[0] == 'x') + + sdsfree(x); + x = sdsnew("xxciaoyyy"); + sdstrim(x,"xy"); + test_cond("sdstrim() correctly trims characters", + sdslen(x) == 4 && memcmp(x,"ciao\0",5) == 0) + + y = sdsdup(x); + sdsrange(y,1,1); + test_cond("sdsrange(...,1,1)", + sdslen(y) == 1 && memcmp(y,"i\0",2) == 0) + + sdsfree(y); + y = sdsdup(x); + sdsrange(y,1,-1); + test_cond("sdsrange(...,1,-1)", + sdslen(y) == 3 && memcmp(y,"iao\0",4) == 0) + + sdsfree(y); + y = sdsdup(x); + sdsrange(y,-2,-1); + test_cond("sdsrange(...,-2,-1)", + sdslen(y) == 2 && memcmp(y,"ao\0",3) == 0) + + sdsfree(y); + y = sdsdup(x); + sdsrange(y,2,1); + test_cond("sdsrange(...,2,1)", + sdslen(y) == 0 && memcmp(y,"\0",1) == 0) + + sdsfree(y); + y = sdsdup(x); + sdsrange(y,1,100); + test_cond("sdsrange(...,1,100)", + sdslen(y) == 3 && memcmp(y,"iao\0",4) == 0) + + sdsfree(y); + y = sdsdup(x); + sdsrange(y,100,100); + test_cond("sdsrange(...,100,100)", + sdslen(y) == 0 && memcmp(y,"\0",1) == 0) + + sdsfree(y); + sdsfree(x); + x = sdsnew("foo"); + y = sdsnew("foa"); + test_cond("sdscmp(foo,foa)", sdscmp(x,y) > 0) + + sdsfree(y); + sdsfree(x); + x = sdsnew("bar"); + y = sdsnew("bar"); + test_cond("sdscmp(bar,bar)", sdscmp(x,y) == 0) + + sdsfree(y); + sdsfree(x); + x = sdsnew("aar"); + y = sdsnew("bar"); + test_cond("sdscmp(bar,bar)", sdscmp(x,y) < 0) + + sdsfree(y); + sdsfree(x); + x = sdsnewlen("\a\n\0foo\r",7); + y = sdscatrepr(sdsempty(),x,sdslen(x)); + test_cond("sdscatrepr(...data...)", + memcmp(y,"\"\\a\\n\\x00foo\\r\"",15) == 0) + + { + unsigned int oldfree; + char *p; + int step = 10, j, i; + + sdsfree(x); + sdsfree(y); + x = sdsnew("0"); + test_cond("sdsnew() free/len buffers", sdslen(x) == 1 && sdsavail(x) == 0); + + /* Run the test a few times in order to hit the first two + * SDS header types. */ + for (i = 0; i < 10; i++) { + int oldlen = sdslen(x); + x = sdsMakeRoomFor(x,step); + int type = x[-1]&SDS_TYPE_MASK; + + test_cond("sdsMakeRoomFor() len", sdslen(x) == oldlen); + if (type != SDS_TYPE_5) { + test_cond("sdsMakeRoomFor() free", sdsavail(x) >= step); + oldfree = sdsavail(x); + } + p = x+oldlen; + for (j = 0; j < step; j++) { + p[j] = 'A'+j; + } + sdsIncrLen(x,step); + } + test_cond("sdsMakeRoomFor() content", + memcmp("0ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ",x,101) == 0); + test_cond("sdsMakeRoomFor() final length",sdslen(x)==101); + + sdsfree(x); + } + } + test_report() + return 0; +} +#endif + +#ifdef SDS_TEST_MAIN +int main(void) { + return sdsTest(); +} +#endif diff --git a/俱乐部/Source/hiredis/sds.h b/俱乐部/Source/hiredis/sds.h new file mode 100644 index 0000000..3f9a964 --- /dev/null +++ b/俱乐部/Source/hiredis/sds.h @@ -0,0 +1,276 @@ +/* SDSLib 2.0 -- A C dynamic strings library + * + * Copyright (c) 2006-2015, Salvatore Sanfilippo + * Copyright (c) 2015, Oran Agra + * Copyright (c) 2015, Redis Labs, Inc + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Redis nor the names of its contributors may 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. + */ + +#ifndef __SDS_H +#define __SDS_H + +#define SDS_MAX_PREALLOC (1024*1024) +#ifdef _MSC_VER +#define __attribute__(x) +#endif + +#include +#include +#include + +typedef char *sds; + +/* Note: sdshdr5 is never used, we just access the flags byte directly. + * However is here to document the layout of type 5 SDS strings. */ +struct __attribute__ ((__packed__)) sdshdr5 { + unsigned char flags; /* 3 lsb of type, and 5 msb of string length */ + char buf[]; +}; +struct __attribute__ ((__packed__)) sdshdr8 { + uint8_t len; /* used */ + uint8_t alloc; /* excluding the header and null terminator */ + unsigned char flags; /* 3 lsb of type, 5 unused bits */ + char buf[]; +}; +struct __attribute__ ((__packed__)) sdshdr16 { + uint16_t len; /* used */ + uint16_t alloc; /* excluding the header and null terminator */ + unsigned char flags; /* 3 lsb of type, 5 unused bits */ + char buf[]; +}; +struct __attribute__ ((__packed__)) sdshdr32 { + uint32_t len; /* used */ + uint32_t alloc; /* excluding the header and null terminator */ + unsigned char flags; /* 3 lsb of type, 5 unused bits */ + char buf[]; +}; +struct __attribute__ ((__packed__)) sdshdr64 { + uint64_t len; /* used */ + uint64_t alloc; /* excluding the header and null terminator */ + unsigned char flags; /* 3 lsb of type, 5 unused bits */ + char buf[]; +}; + +#define SDS_TYPE_5 0 +#define SDS_TYPE_8 1 +#define SDS_TYPE_16 2 +#define SDS_TYPE_32 3 +#define SDS_TYPE_64 4 +#define SDS_TYPE_MASK 7 +#define SDS_TYPE_BITS 3 +#define SDS_HDR_VAR(T,s) struct sdshdr##T *sh = (struct sdshdr##T *)((s)-(sizeof(struct sdshdr##T))); +#define SDS_HDR(T,s) ((struct sdshdr##T *)((s)-(sizeof(struct sdshdr##T)))) +#define SDS_TYPE_5_LEN(f) ((f)>>SDS_TYPE_BITS) + +static inline size_t sdslen(const sds s) { + unsigned char flags = s[-1]; + switch(flags&SDS_TYPE_MASK) { + case SDS_TYPE_5: + return SDS_TYPE_5_LEN(flags); + case SDS_TYPE_8: + return SDS_HDR(8,s)->len; + case SDS_TYPE_16: + return SDS_HDR(16,s)->len; + case SDS_TYPE_32: + return SDS_HDR(32,s)->len; + case SDS_TYPE_64: + return SDS_HDR(64,s)->len; + } + return 0; +} + +static inline size_t sdsavail(const sds s) { + unsigned char flags = s[-1]; + switch(flags&SDS_TYPE_MASK) { + case SDS_TYPE_5: { + return 0; + } + case SDS_TYPE_8: { + SDS_HDR_VAR(8,s); + return sh->alloc - sh->len; + } + case SDS_TYPE_16: { + SDS_HDR_VAR(16,s); + return sh->alloc - sh->len; + } + case SDS_TYPE_32: { + SDS_HDR_VAR(32,s); + return sh->alloc - sh->len; + } + case SDS_TYPE_64: { + SDS_HDR_VAR(64,s); + return sh->alloc - sh->len; + } + } + return 0; +} + +static inline void sdssetlen(sds s, size_t newlen) { + unsigned char flags = s[-1]; + switch(flags&SDS_TYPE_MASK) { + case SDS_TYPE_5: + { + unsigned char *fp = ((unsigned char*)s)-1; + *fp = (unsigned char)(SDS_TYPE_5 | (newlen << SDS_TYPE_BITS)); + } + break; + case SDS_TYPE_8: + SDS_HDR(8,s)->len = (uint8_t)newlen; + break; + case SDS_TYPE_16: + SDS_HDR(16,s)->len = (uint16_t)newlen; + break; + case SDS_TYPE_32: + SDS_HDR(32,s)->len = (uint32_t)newlen; + break; + case SDS_TYPE_64: + SDS_HDR(64,s)->len = (uint64_t)newlen; + break; + } +} + +static inline void sdsinclen(sds s, size_t inc) { + unsigned char flags = s[-1]; + switch(flags&SDS_TYPE_MASK) { + case SDS_TYPE_5: + { + unsigned char *fp = ((unsigned char*)s)-1; + unsigned char newlen = SDS_TYPE_5_LEN(flags)+(unsigned char)inc; + *fp = SDS_TYPE_5 | (newlen << SDS_TYPE_BITS); + } + break; + case SDS_TYPE_8: + SDS_HDR(8,s)->len += (uint8_t)inc; + break; + case SDS_TYPE_16: + SDS_HDR(16,s)->len += (uint16_t)inc; + break; + case SDS_TYPE_32: + SDS_HDR(32,s)->len += (uint32_t)inc; + break; + case SDS_TYPE_64: + SDS_HDR(64,s)->len += (uint64_t)inc; + break; + } +} + +/* sdsalloc() = sdsavail() + sdslen() */ +static inline size_t sdsalloc(const sds s) { + unsigned char flags = s[-1]; + switch(flags&SDS_TYPE_MASK) { + case SDS_TYPE_5: + return SDS_TYPE_5_LEN(flags); + case SDS_TYPE_8: + return SDS_HDR(8,s)->alloc; + case SDS_TYPE_16: + return SDS_HDR(16,s)->alloc; + case SDS_TYPE_32: + return SDS_HDR(32,s)->alloc; + case SDS_TYPE_64: + return SDS_HDR(64,s)->alloc; + } + return 0; +} + +static inline void sdssetalloc(sds s, size_t newlen) { + unsigned char flags = s[-1]; + switch(flags&SDS_TYPE_MASK) { + case SDS_TYPE_5: + /* Nothing to do, this type has no total allocation info. */ + break; + case SDS_TYPE_8: + SDS_HDR(8,s)->alloc = (uint8_t)newlen; + break; + case SDS_TYPE_16: + SDS_HDR(16,s)->alloc = (uint16_t)newlen; + break; + case SDS_TYPE_32: + SDS_HDR(32,s)->alloc = (uint32_t)newlen; + break; + case SDS_TYPE_64: + SDS_HDR(64,s)->alloc = (uint64_t)newlen; + break; + } +} + +sds sdsnewlen(const void *init, size_t initlen); +sds sdsnew(const char *init); +sds sdsempty(void); +sds sdsdup(const sds s); +void sdsfree(sds s); +sds sdsgrowzero(sds s, size_t len); +sds sdscatlen(sds s, const void *t, size_t len); +sds sdscat(sds s, const char *t); +sds sdscatsds(sds s, const sds t); +sds sdscpylen(sds s, const char *t, size_t len); +sds sdscpy(sds s, const char *t); + +sds sdscatvprintf(sds s, const char *fmt, va_list ap); +#ifdef __GNUC__ +sds sdscatprintf(sds s, const char *fmt, ...) + __attribute__((format(printf, 2, 3))); +#else +sds sdscatprintf(sds s, const char *fmt, ...); +#endif + +sds sdscatfmt(sds s, char const *fmt, ...); +sds sdstrim(sds s, const char *cset); +void sdsrange(sds s, int start, int end); +void sdsupdatelen(sds s); +void sdsclear(sds s); +int sdscmp(const sds s1, const sds s2); +sds *sdssplitlen(const char *s, int len, const char *sep, int seplen, int *count); +void sdsfreesplitres(sds *tokens, int count); +void sdstolower(sds s); +void sdstoupper(sds s); +sds sdsfromlonglong(long long value); +sds sdscatrepr(sds s, const char *p, size_t len); +sds *sdssplitargs(const char *line, int *argc); +sds sdsmapchars(sds s, const char *from, const char *to, size_t setlen); +sds sdsjoin(char **argv, int argc, char *sep); +sds sdsjoinsds(sds *argv, int argc, const char *sep, size_t seplen); + +/* Low level functions exposed to the user API */ +sds sdsMakeRoomFor(sds s, size_t addlen); +void sdsIncrLen(sds s, int incr); +sds sdsRemoveFreeSpace(sds s); +size_t sdsAllocSize(sds s); +void *sdsAllocPtr(sds s); + +/* Export the allocator used by SDS to the program using SDS. + * Sometimes the program SDS is linked to, may use a different set of + * allocators, but may want to allocate or free things that SDS will + * respectively free or allocate. */ +void *sds_malloc(size_t size); +void *sds_realloc(void *ptr, size_t size); +void sds_free(void *ptr); + +#ifdef REDIS_TEST +int sdsTest(int argc, char *argv[]); +#endif + +#endif diff --git a/俱乐部/Source/hiredis/sdsalloc.h b/俱乐部/Source/hiredis/sdsalloc.h new file mode 100644 index 0000000..f43023c --- /dev/null +++ b/俱乐部/Source/hiredis/sdsalloc.h @@ -0,0 +1,42 @@ +/* SDSLib 2.0 -- A C dynamic strings library + * + * Copyright (c) 2006-2015, Salvatore Sanfilippo + * Copyright (c) 2015, Oran Agra + * Copyright (c) 2015, Redis Labs, Inc + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Redis nor the names of its contributors may 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. + */ + +/* SDS allocator selection. + * + * This file is used in order to change the SDS allocator at compile time. + * Just define the following defines to what you want to use. Also add + * the include of your alternate allocator if needed (not needed in order + * to use the default libc allocator). */ + +#define s_malloc malloc +#define s_realloc realloc +#define s_free free diff --git a/俱乐部/Source/hiredis/sockcompat.c b/俱乐部/Source/hiredis/sockcompat.c new file mode 100644 index 0000000..4cc2f41 --- /dev/null +++ b/俱乐部/Source/hiredis/sockcompat.c @@ -0,0 +1,248 @@ +/* + * Copyright (c) 2019, Marcus Geelnard + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Redis nor the names of its contributors may 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. + */ + +#define REDIS_SOCKCOMPAT_IMPLEMENTATION +#include "sockcompat.h" + +#ifdef _WIN32 +static int _wsaErrorToErrno(int err) { + switch (err) { + case WSAEWOULDBLOCK: + return EWOULDBLOCK; + case WSAEINPROGRESS: + return EINPROGRESS; + case WSAEALREADY: + return EALREADY; + case WSAENOTSOCK: + return ENOTSOCK; + case WSAEDESTADDRREQ: + return EDESTADDRREQ; + case WSAEMSGSIZE: + return EMSGSIZE; + case WSAEPROTOTYPE: + return EPROTOTYPE; + case WSAENOPROTOOPT: + return ENOPROTOOPT; + case WSAEPROTONOSUPPORT: + return EPROTONOSUPPORT; + case WSAEOPNOTSUPP: + return EOPNOTSUPP; + case WSAEAFNOSUPPORT: + return EAFNOSUPPORT; + case WSAEADDRINUSE: + return EADDRINUSE; + case WSAEADDRNOTAVAIL: + return EADDRNOTAVAIL; + case WSAENETDOWN: + return ENETDOWN; + case WSAENETUNREACH: + return ENETUNREACH; + case WSAENETRESET: + return ENETRESET; + case WSAECONNABORTED: + return ECONNABORTED; + case WSAECONNRESET: + return ECONNRESET; + case WSAENOBUFS: + return ENOBUFS; + case WSAEISCONN: + return EISCONN; + case WSAENOTCONN: + return ENOTCONN; + case WSAETIMEDOUT: + return ETIMEDOUT; + case WSAECONNREFUSED: + return ECONNREFUSED; + case WSAELOOP: + return ELOOP; + case WSAENAMETOOLONG: + return ENAMETOOLONG; + case WSAEHOSTUNREACH: + return EHOSTUNREACH; + case WSAENOTEMPTY: + return ENOTEMPTY; + default: + /* We just return a generic I/O error if we could not find a relevant error. */ + return EIO; + } +} + +static void _updateErrno(int success) { + errno = success ? 0 : _wsaErrorToErrno(WSAGetLastError()); +} + +static int _initWinsock() { + static int s_initialized = 0; + if (!s_initialized) { + static WSADATA wsadata; + int err = WSAStartup(MAKEWORD(2,2), &wsadata); + if (err != 0) { + errno = _wsaErrorToErrno(err); + return 0; + } + s_initialized = 1; + } + return 1; +} + +int win32_getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res) { + /* Note: This function is likely to be called before other functions, so run init here. */ + if (!_initWinsock()) { + return EAI_FAIL; + } + + switch (getaddrinfo(node, service, hints, res)) { + case 0: return 0; + case WSATRY_AGAIN: return EAI_AGAIN; + case WSAEINVAL: return EAI_BADFLAGS; + case WSAEAFNOSUPPORT: return EAI_FAMILY; + case WSA_NOT_ENOUGH_MEMORY: return EAI_MEMORY; + case WSAHOST_NOT_FOUND: return EAI_NONAME; + case WSATYPE_NOT_FOUND: return EAI_SERVICE; + case WSAESOCKTNOSUPPORT: return EAI_SOCKTYPE; + default: return EAI_FAIL; /* Including WSANO_RECOVERY */ + } +} + +const char *win32_gai_strerror(int errcode) { + switch (errcode) { + case 0: errcode = 0; break; + case EAI_AGAIN: errcode = WSATRY_AGAIN; break; + case EAI_BADFLAGS: errcode = WSAEINVAL; break; + case EAI_FAMILY: errcode = WSAEAFNOSUPPORT; break; + case EAI_MEMORY: errcode = WSA_NOT_ENOUGH_MEMORY; break; + case EAI_NONAME: errcode = WSAHOST_NOT_FOUND; break; + case EAI_SERVICE: errcode = WSATYPE_NOT_FOUND; break; + case EAI_SOCKTYPE: errcode = WSAESOCKTNOSUPPORT; break; + default: errcode = WSANO_RECOVERY; break; /* Including EAI_FAIL */ + } + return gai_strerror(errcode); +} + +void win32_freeaddrinfo(struct addrinfo *res) { + freeaddrinfo(res); +} + +SOCKET win32_socket(int domain, int type, int protocol) { + SOCKET s; + + /* Note: This function is likely to be called before other functions, so run init here. */ + if (!_initWinsock()) { + return INVALID_SOCKET; + } + + _updateErrno((s = socket(domain, type, protocol)) != INVALID_SOCKET); + return s; +} + +int win32_ioctl(SOCKET fd, unsigned long request, unsigned long *argp) { + int ret = ioctlsocket(fd, (long)request, argp); + _updateErrno(ret != SOCKET_ERROR); + return ret != SOCKET_ERROR ? ret : -1; +} + +int win32_bind(SOCKET sockfd, const struct sockaddr *addr, socklen_t addrlen) { + int ret = bind(sockfd, addr, addrlen); + _updateErrno(ret != SOCKET_ERROR); + return ret != SOCKET_ERROR ? ret : -1; +} + +int win32_connect(SOCKET sockfd, const struct sockaddr *addr, socklen_t addrlen) { + int ret = connect(sockfd, addr, addrlen); + _updateErrno(ret != SOCKET_ERROR); + + /* For Winsock connect(), the WSAEWOULDBLOCK error means the same thing as + * EINPROGRESS for POSIX connect(), so we do that translation to keep POSIX + * logic consistent. */ + if (errno == EWOULDBLOCK) { + errno = EINPROGRESS; + } + + return ret != SOCKET_ERROR ? ret : -1; +} + +int win32_getsockopt(SOCKET sockfd, int level, int optname, void *optval, socklen_t *optlen) { + int ret = 0; + if ((level == SOL_SOCKET) && ((optname == SO_RCVTIMEO) || (optname == SO_SNDTIMEO))) { + if (*optlen >= sizeof (struct timeval)) { + struct timeval *tv = optval; + DWORD timeout = 0; + socklen_t dwlen = 0; + ret = getsockopt(sockfd, level, optname, (char *)&timeout, &dwlen); + tv->tv_sec = timeout / 1000; + tv->tv_usec = (timeout * 1000) % 1000000; + } else { + ret = WSAEFAULT; + } + *optlen = sizeof (struct timeval); + } else { + ret = getsockopt(sockfd, level, optname, (char*)optval, optlen); + } + _updateErrno(ret != SOCKET_ERROR); + return ret != SOCKET_ERROR ? ret : -1; +} + +int win32_setsockopt(SOCKET sockfd, int level, int optname, const void *optval, socklen_t optlen) { + int ret = 0; + if ((level == SOL_SOCKET) && ((optname == SO_RCVTIMEO) || (optname == SO_SNDTIMEO))) { + struct timeval *tv = optval; + DWORD timeout = tv->tv_sec * 1000 + tv->tv_usec / 1000; + ret = setsockopt(sockfd, level, optname, (const char*)&timeout, sizeof(DWORD)); + } else { + ret = setsockopt(sockfd, level, optname, (const char*)optval, optlen); + } + _updateErrno(ret != SOCKET_ERROR); + return ret != SOCKET_ERROR ? ret : -1; +} + +int win32_close(SOCKET fd) { + int ret = closesocket(fd); + _updateErrno(ret != SOCKET_ERROR); + return ret != SOCKET_ERROR ? ret : -1; +} + +ssize_t win32_recv(SOCKET sockfd, void *buf, size_t len, int flags) { + int ret = recv(sockfd, (char*)buf, (int)len, flags); + _updateErrno(ret != SOCKET_ERROR); + return ret != SOCKET_ERROR ? ret : -1; +} + +ssize_t win32_send(SOCKET sockfd, const void *buf, size_t len, int flags) { + int ret = send(sockfd, (const char*)buf, (int)len, flags); + _updateErrno(ret != SOCKET_ERROR); + return ret != SOCKET_ERROR ? ret : -1; +} + +int win32_poll(struct pollfd *fds, nfds_t nfds, int timeout) { + int ret = WSAPoll(fds, nfds, timeout); + _updateErrno(ret != SOCKET_ERROR); + return ret != SOCKET_ERROR ? ret : -1; +} +#endif /* _WIN32 */ diff --git a/俱乐部/Source/hiredis/sockcompat.h b/俱乐部/Source/hiredis/sockcompat.h new file mode 100644 index 0000000..56006c1 --- /dev/null +++ b/俱乐部/Source/hiredis/sockcompat.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2019, Marcus Geelnard + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Redis nor the names of its contributors may 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. + */ + +#ifndef __SOCKCOMPAT_H +#define __SOCKCOMPAT_H + +#ifndef _WIN32 +/* For POSIX systems we use the standard BSD socket API. */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#else +/* For Windows we use winsock. */ +#undef _WIN32_WINNT +#define _WIN32_WINNT 0x0600 /* To get WSAPoll etc. */ +#include +#include +#include + +#ifdef _MSC_VER +typedef signed long ssize_t; +#endif + +/* Emulate the parts of the BSD socket API that we need (override the winsock signatures). */ +int win32_getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res); +const char *win32_gai_strerror(int errcode); +void win32_freeaddrinfo(struct addrinfo *res); +SOCKET win32_socket(int domain, int type, int protocol); +int win32_ioctl(SOCKET fd, unsigned long request, unsigned long *argp); +int win32_bind(SOCKET sockfd, const struct sockaddr *addr, socklen_t addrlen); +int win32_connect(SOCKET sockfd, const struct sockaddr *addr, socklen_t addrlen); +int win32_getsockopt(SOCKET sockfd, int level, int optname, void *optval, socklen_t *optlen); +int win32_setsockopt(SOCKET sockfd, int level, int optname, const void *optval, socklen_t optlen); +int win32_close(SOCKET fd); +ssize_t win32_recv(SOCKET sockfd, void *buf, size_t len, int flags); +ssize_t win32_send(SOCKET sockfd, const void *buf, size_t len, int flags); +typedef ULONG nfds_t; +int win32_poll(struct pollfd *fds, nfds_t nfds, int timeout); + +#ifndef REDIS_SOCKCOMPAT_IMPLEMENTATION +#define getaddrinfo(node, service, hints, res) win32_getaddrinfo(node, service, hints, res) +#undef gai_strerror +#define gai_strerror(errcode) win32_gai_strerror(errcode) +#define freeaddrinfo(res) win32_freeaddrinfo(res) +#define socket(domain, type, protocol) win32_socket(domain, type, protocol) +#define ioctl(fd, request, argp) win32_ioctl(fd, request, argp) +#define bind(sockfd, addr, addrlen) win32_bind(sockfd, addr, addrlen) +#define connect(sockfd, addr, addrlen) win32_connect(sockfd, addr, addrlen) +#define getsockopt(sockfd, level, optname, optval, optlen) win32_getsockopt(sockfd, level, optname, optval, optlen) +#define setsockopt(sockfd, level, optname, optval, optlen) win32_setsockopt(sockfd, level, optname, optval, optlen) +#define close(fd) win32_close(fd) +#define recv(sockfd, buf, len, flags) win32_recv(sockfd, buf, len, flags) +#define send(sockfd, buf, len, flags) win32_send(sockfd, buf, len, flags) +#define poll(fds, nfds, timeout) win32_poll(fds, nfds, timeout) +#endif /* REDIS_SOCKCOMPAT_IMPLEMENTATION */ +#endif /* _WIN32 */ + +#endif /* __SOCKCOMPAT_H */ diff --git a/俱乐部/Source/hiredis/ssl.c b/俱乐部/Source/hiredis/ssl.c new file mode 100644 index 0000000..e1e4aba --- /dev/null +++ b/俱乐部/Source/hiredis/ssl.c @@ -0,0 +1,448 @@ +/* + * Copyright (c) 2009-2011, Salvatore Sanfilippo + * Copyright (c) 2010-2011, Pieter Noordhuis + * Copyright (c) 2019, Redis Labs + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Redis nor the names of its contributors may 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. + */ + +#include "hiredis.h" +#include "async.h" + +#include +#include +#include +#include + +#include +#include + +#include "async_private.h" + +void __redisSetError(redisContext *c, int type, const char *str); + +/* The SSL context is attached to SSL/TLS connections as a privdata. */ +typedef struct redisSSLContext { + /** + * OpenSSL SSL_CTX; It is optional and will not be set when using + * user-supplied SSL. + */ + SSL_CTX *ssl_ctx; + + /** + * OpenSSL SSL object. + */ + SSL *ssl; + + /** + * SSL_write() requires to be called again with the same arguments it was + * previously called with in the event of an SSL_read/SSL_write situation + */ + size_t lastLen; + + /** Whether the SSL layer requires read (possibly before a write) */ + int wantRead; + + /** + * Whether a write was requested prior to a read. If set, the write() + * should resume whenever a read takes place, if possible + */ + int pendingWrite; +} redisSSLContext; + +/* Forward declaration */ +redisContextFuncs redisContextSSLFuncs; + +#ifdef HIREDIS_SSL_TRACE +/** + * Callback used for debugging + */ +static void sslLogCallback(const SSL *ssl, int where, int ret) { + const char *retstr; + int should_log = 0; + /* Ignore low-level SSL stuff */ + + if (where & SSL_CB_ALERT) { + should_log = 1; + } + if (where == SSL_CB_HANDSHAKE_START || where == SSL_CB_HANDSHAKE_DONE) { + should_log = 1; + } + if ((where & SSL_CB_EXIT) && ret == 0) { + should_log = 1; + } + + if (!should_log) { + return; + } + + retstr = SSL_alert_type_string(ret); + printf("ST(0x%x). %s. R(0x%x)%s\n", where, SSL_state_string_long(ssl), ret, retstr); + + if (where == SSL_CB_HANDSHAKE_DONE) { + printf("Using SSL version %s. Cipher=%s\n", SSL_get_version(ssl), SSL_get_cipher_name(ssl)); + } +} +#endif + +/** + * OpenSSL global initialization and locking handling callbacks. + * Note that this is only required for OpenSSL < 1.1.0. + */ + +#if OPENSSL_VERSION_NUMBER < 0x10100000L +#define HIREDIS_USE_CRYPTO_LOCKS +#endif + +#ifdef HIREDIS_USE_CRYPTO_LOCKS +typedef pthread_mutex_t sslLockType; +static void sslLockInit(sslLockType *l) { + pthread_mutex_init(l, NULL); +} +static void sslLockAcquire(sslLockType *l) { + pthread_mutex_lock(l); +} +static void sslLockRelease(sslLockType *l) { + pthread_mutex_unlock(l); +} +static pthread_mutex_t *ossl_locks; + +static void opensslDoLock(int mode, int lkid, const char *f, int line) { + sslLockType *l = ossl_locks + lkid; + + if (mode & CRYPTO_LOCK) { + sslLockAcquire(l); + } else { + sslLockRelease(l); + } + + (void)f; + (void)line; +} + +static void initOpensslLocks(void) { + unsigned ii, nlocks; + if (CRYPTO_get_locking_callback() != NULL) { + /* Someone already set the callback before us. Don't destroy it! */ + return; + } + nlocks = CRYPTO_num_locks(); + ossl_locks = hi_malloc(sizeof(*ossl_locks) * nlocks); + for (ii = 0; ii < nlocks; ii++) { + sslLockInit(ossl_locks + ii); + } + CRYPTO_set_locking_callback(opensslDoLock); +} +#endif /* HIREDIS_USE_CRYPTO_LOCKS */ + +/** + * SSL Connection initialization. + */ + +static int redisSSLConnect(redisContext *c, SSL_CTX *ssl_ctx, SSL *ssl) { + if (c->privdata) { + __redisSetError(c, REDIS_ERR_OTHER, "redisContext was already associated"); + return REDIS_ERR; + } + c->privdata = calloc(1, sizeof(redisSSLContext)); + + c->funcs = &redisContextSSLFuncs; + redisSSLContext *rssl = c->privdata; + + rssl->ssl_ctx = ssl_ctx; + rssl->ssl = ssl; + + SSL_set_mode(rssl->ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); + SSL_set_fd(rssl->ssl, c->fd); + SSL_set_connect_state(rssl->ssl); + + ERR_clear_error(); + int rv = SSL_connect(rssl->ssl); + if (rv == 1) { + return REDIS_OK; + } + + rv = SSL_get_error(rssl->ssl, rv); + if (((c->flags & REDIS_BLOCK) == 0) && + (rv == SSL_ERROR_WANT_READ || rv == SSL_ERROR_WANT_WRITE)) { + return REDIS_OK; + } + + if (c->err == 0) { + char err[512]; + if (rv == SSL_ERROR_SYSCALL) + snprintf(err,sizeof(err)-1,"SSL_connect failed: %s",strerror(errno)); + else { + unsigned long e = ERR_peek_last_error(); + snprintf(err,sizeof(err)-1,"SSL_connect failed: %s", + ERR_reason_error_string(e)); + } + __redisSetError(c, REDIS_ERR_IO, err); + } + return REDIS_ERR; +} + +int redisInitiateSSL(redisContext *c, SSL *ssl) { + return redisSSLConnect(c, NULL, ssl); +} + +int redisSecureConnection(redisContext *c, const char *capath, + const char *certpath, const char *keypath, const char *servername) { + + SSL_CTX *ssl_ctx = NULL; + SSL *ssl = NULL; + + /* Initialize global OpenSSL stuff */ + static int isInit = 0; + if (!isInit) { + isInit = 1; + SSL_library_init(); +#ifdef HIREDIS_USE_CRYPTO_LOCKS + initOpensslLocks(); +#endif + } + + ssl_ctx = SSL_CTX_new(SSLv23_client_method()); + if (!ssl_ctx) { + __redisSetError(c, REDIS_ERR_OTHER, "Failed to create SSL_CTX"); + goto error; + } + +#ifdef HIREDIS_SSL_TRACE + SSL_CTX_set_info_callback(ssl_ctx, sslLogCallback); +#endif + SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); + SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, NULL); + if ((certpath != NULL && keypath == NULL) || (keypath != NULL && certpath == NULL)) { + __redisSetError(c, REDIS_ERR_OTHER, "certpath and keypath must be specified together"); + goto error; + } + + if (capath) { + if (!SSL_CTX_load_verify_locations(ssl_ctx, capath, NULL)) { + __redisSetError(c, REDIS_ERR_OTHER, "Invalid CA certificate"); + goto error; + } + } + if (certpath) { + if (!SSL_CTX_use_certificate_chain_file(ssl_ctx, certpath)) { + __redisSetError(c, REDIS_ERR_OTHER, "Invalid client certificate"); + goto error; + } + if (!SSL_CTX_use_PrivateKey_file(ssl_ctx, keypath, SSL_FILETYPE_PEM)) { + __redisSetError(c, REDIS_ERR_OTHER, "Invalid client key"); + goto error; + } + } + + ssl = SSL_new(ssl_ctx); + if (!ssl) { + __redisSetError(c, REDIS_ERR_OTHER, "Couldn't create new SSL instance"); + goto error; + } + if (servername) { + if (!SSL_set_tlsext_host_name(ssl, servername)) { + __redisSetError(c, REDIS_ERR_OTHER, "Couldn't set server name indication"); + goto error; + } + } + + return redisSSLConnect(c, ssl_ctx, ssl); + +error: + if (ssl) SSL_free(ssl); + if (ssl_ctx) SSL_CTX_free(ssl_ctx); + return REDIS_ERR; +} + +static int maybeCheckWant(redisSSLContext *rssl, int rv) { + /** + * If the error is WANT_READ or WANT_WRITE, the appropriate flags are set + * and true is returned. False is returned otherwise + */ + if (rv == SSL_ERROR_WANT_READ) { + rssl->wantRead = 1; + return 1; + } else if (rv == SSL_ERROR_WANT_WRITE) { + rssl->pendingWrite = 1; + return 1; + } else { + return 0; + } +} + +/** + * Implementation of redisContextFuncs for SSL connections. + */ + +static void redisSSLFreeContext(void *privdata){ + redisSSLContext *rsc = privdata; + + if (!rsc) return; + if (rsc->ssl) { + SSL_free(rsc->ssl); + rsc->ssl = NULL; + } + if (rsc->ssl_ctx) { + SSL_CTX_free(rsc->ssl_ctx); + rsc->ssl_ctx = NULL; + } + free(rsc); +} + +static int redisSSLRead(redisContext *c, char *buf, size_t bufcap) { + redisSSLContext *rssl = c->privdata; + + int nread = SSL_read(rssl->ssl, buf, bufcap); + if (nread > 0) { + return nread; + } else if (nread == 0) { + __redisSetError(c, REDIS_ERR_EOF, "Server closed the connection"); + return -1; + } else { + int err = SSL_get_error(rssl->ssl, nread); + if (c->flags & REDIS_BLOCK) { + /** + * In blocking mode, we should never end up in a situation where + * we get an error without it being an actual error, except + * in the case of EINTR, which can be spuriously received from + * debuggers or whatever. + */ + if (errno == EINTR) { + return 0; + } else { + const char *msg = NULL; + if (errno == EAGAIN) { + msg = "Resource temporarily unavailable"; + } + __redisSetError(c, REDIS_ERR_IO, msg); + return -1; + } + } + + /** + * We can very well get an EWOULDBLOCK/EAGAIN, however + */ + if (maybeCheckWant(rssl, err)) { + return 0; + } else { + __redisSetError(c, REDIS_ERR_IO, NULL); + return -1; + } + } +} + +static int redisSSLWrite(redisContext *c) { + redisSSLContext *rssl = c->privdata; + + size_t len = rssl->lastLen ? rssl->lastLen : sdslen(c->obuf); + int rv = SSL_write(rssl->ssl, c->obuf, len); + + if (rv > 0) { + rssl->lastLen = 0; + } else if (rv < 0) { + rssl->lastLen = len; + + int err = SSL_get_error(rssl->ssl, rv); + if ((c->flags & REDIS_BLOCK) == 0 && maybeCheckWant(rssl, err)) { + return 0; + } else { + __redisSetError(c, REDIS_ERR_IO, NULL); + return -1; + } + } + return rv; +} + +static void redisSSLAsyncRead(redisAsyncContext *ac) { + int rv; + redisSSLContext *rssl = ac->c.privdata; + redisContext *c = &ac->c; + + rssl->wantRead = 0; + + if (rssl->pendingWrite) { + int done; + + /* This is probably just a write event */ + rssl->pendingWrite = 0; + rv = redisBufferWrite(c, &done); + if (rv == REDIS_ERR) { + __redisAsyncDisconnect(ac); + return; + } else if (!done) { + _EL_ADD_WRITE(ac); + } + } + + rv = redisBufferRead(c); + if (rv == REDIS_ERR) { + __redisAsyncDisconnect(ac); + } else { + _EL_ADD_READ(ac); + redisProcessCallbacks(ac); + } +} + +static void redisSSLAsyncWrite(redisAsyncContext *ac) { + int rv, done = 0; + redisSSLContext *rssl = ac->c.privdata; + redisContext *c = &ac->c; + + rssl->pendingWrite = 0; + rv = redisBufferWrite(c, &done); + if (rv == REDIS_ERR) { + __redisAsyncDisconnect(ac); + return; + } + + if (!done) { + if (rssl->wantRead) { + /* Need to read-before-write */ + rssl->pendingWrite = 1; + _EL_DEL_WRITE(ac); + } else { + /* No extra reads needed, just need to write more */ + _EL_ADD_WRITE(ac); + } + } else { + /* Already done! */ + _EL_DEL_WRITE(ac); + } + + /* Always reschedule a read */ + _EL_ADD_READ(ac); +} + +redisContextFuncs redisContextSSLFuncs = { + .free_privdata = redisSSLFreeContext, + .async_read = redisSSLAsyncRead, + .async_write = redisSSLAsyncWrite, + .read = redisSSLRead, + .write = redisSSLWrite +}; + diff --git a/俱乐部/Source/hiredis/test.c b/俱乐部/Source/hiredis/test.c new file mode 100644 index 0000000..9c0de6d --- /dev/null +++ b/俱乐部/Source/hiredis/test.c @@ -0,0 +1,1017 @@ +#include "fmacros.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "hiredis.h" +#ifdef HIREDIS_TEST_SSL +#include "hiredis_ssl.h" +#endif +#include "net.h" + +enum connection_type { + CONN_TCP, + CONN_UNIX, + CONN_FD, + CONN_SSL +}; + +struct config { + enum connection_type type; + + struct { + const char *host; + int port; + struct timeval timeout; + } tcp; + + struct { + const char *path; + } unix_sock; + + struct { + const char *host; + int port; + const char *ca_cert; + const char *cert; + const char *key; + } ssl; +}; + +/* The following lines make up our testing "framework" :) */ +static int tests = 0, fails = 0; +#define test(_s) { printf("#%02d ", ++tests); printf(_s); } +#define test_cond(_c) if(_c) printf("\033[0;32mPASSED\033[0;0m\n"); else {printf("\033[0;31mFAILED\033[0;0m\n"); fails++;} + +static long long usec(void) { + struct timeval tv; + gettimeofday(&tv,NULL); + return (((long long)tv.tv_sec)*1000000)+tv.tv_usec; +} + +/* The assert() calls below have side effects, so we need assert() + * even if we are compiling without asserts (-DNDEBUG). */ +#ifdef NDEBUG +#undef assert +#define assert(e) (void)(e) +#endif + +static redisContext *select_database(redisContext *c) { + redisReply *reply; + + /* Switch to DB 9 for testing, now that we know we can chat. */ + reply = redisCommand(c,"SELECT 9"); + assert(reply != NULL); + freeReplyObject(reply); + + /* Make sure the DB is emtpy */ + reply = redisCommand(c,"DBSIZE"); + assert(reply != NULL); + if (reply->type == REDIS_REPLY_INTEGER && reply->integer == 0) { + /* Awesome, DB 9 is empty and we can continue. */ + freeReplyObject(reply); + } else { + printf("Database #9 is not empty, test can not continue\n"); + exit(1); + } + + return c; +} + +static int disconnect(redisContext *c, int keep_fd) { + redisReply *reply; + + /* Make sure we're on DB 9. */ + reply = redisCommand(c,"SELECT 9"); + assert(reply != NULL); + freeReplyObject(reply); + reply = redisCommand(c,"FLUSHDB"); + assert(reply != NULL); + freeReplyObject(reply); + + /* Free the context as well, but keep the fd if requested. */ + if (keep_fd) + return redisFreeKeepFd(c); + redisFree(c); + return -1; +} + +static void do_ssl_handshake(redisContext *c, struct config config) { +#ifdef HIREDIS_TEST_SSL + redisSecureConnection(c, config.ssl.ca_cert, config.ssl.cert, config.ssl.key, NULL); + if (c->err) { + printf("SSL error: %s\n", c->errstr); + redisFree(c); + exit(1); + } +#else + (void) c; + (void) config; +#endif +} + +static redisContext *do_connect(struct config config) { + redisContext *c = NULL; + + if (config.type == CONN_TCP) { + c = redisConnect(config.tcp.host, config.tcp.port); + } else if (config.type == CONN_SSL) { + c = redisConnect(config.ssl.host, config.ssl.port); + } else if (config.type == CONN_UNIX) { + c = redisConnectUnix(config.unix_sock.path); + } else if (config.type == CONN_FD) { + /* Create a dummy connection just to get an fd to inherit */ + redisContext *dummy_ctx = redisConnectUnix(config.unix_sock.path); + if (dummy_ctx) { + int fd = disconnect(dummy_ctx, 1); + printf("Connecting to inherited fd %d\n", fd); + c = redisConnectFd(fd); + } + } else { + assert(NULL); + } + + if (c == NULL) { + printf("Connection error: can't allocate redis context\n"); + exit(1); + } else if (c->err) { + printf("Connection error: %s\n", c->errstr); + redisFree(c); + exit(1); + } + + if (config.type == CONN_SSL) { + do_ssl_handshake(c, config); + } + + return select_database(c); +} + +static void do_reconnect(redisContext *c, struct config config) { + redisReconnect(c); + + if (config.type == CONN_SSL) { + do_ssl_handshake(c, config); + } +} + +static void test_format_commands(void) { + char *cmd; + int len; + + test("Format command without interpolation: "); + len = redisFormatCommand(&cmd,"SET foo bar"); + test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$3\r\nbar\r\n",len) == 0 && + len == 4+4+(3+2)+4+(3+2)+4+(3+2)); + free(cmd); + + test("Format command with %%s string interpolation: "); + len = redisFormatCommand(&cmd,"SET %s %s","foo","bar"); + test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$3\r\nbar\r\n",len) == 0 && + len == 4+4+(3+2)+4+(3+2)+4+(3+2)); + free(cmd); + + test("Format command with %%s and an empty string: "); + len = redisFormatCommand(&cmd,"SET %s %s","foo",""); + test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$0\r\n\r\n",len) == 0 && + len == 4+4+(3+2)+4+(3+2)+4+(0+2)); + free(cmd); + + test("Format command with an empty string in between proper interpolations: "); + len = redisFormatCommand(&cmd,"SET %s %s","","foo"); + test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$0\r\n\r\n$3\r\nfoo\r\n",len) == 0 && + len == 4+4+(3+2)+4+(0+2)+4+(3+2)); + free(cmd); + + test("Format command with %%b string interpolation: "); + len = redisFormatCommand(&cmd,"SET %b %b","foo",(size_t)3,"b\0r",(size_t)3); + test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$3\r\nb\0r\r\n",len) == 0 && + len == 4+4+(3+2)+4+(3+2)+4+(3+2)); + free(cmd); + + test("Format command with %%b and an empty string: "); + len = redisFormatCommand(&cmd,"SET %b %b","foo",(size_t)3,"",(size_t)0); + test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$0\r\n\r\n",len) == 0 && + len == 4+4+(3+2)+4+(3+2)+4+(0+2)); + free(cmd); + + test("Format command with literal %%: "); + len = redisFormatCommand(&cmd,"SET %% %%"); + test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$1\r\n%\r\n$1\r\n%\r\n",len) == 0 && + len == 4+4+(3+2)+4+(1+2)+4+(1+2)); + free(cmd); + + /* Vararg width depends on the type. These tests make sure that the + * width is correctly determined using the format and subsequent varargs + * can correctly be interpolated. */ +#define INTEGER_WIDTH_TEST(fmt, type) do { \ + type value = 123; \ + test("Format command with printf-delegation (" #type "): "); \ + len = redisFormatCommand(&cmd,"key:%08" fmt " str:%s", value, "hello"); \ + test_cond(strncmp(cmd,"*2\r\n$12\r\nkey:00000123\r\n$9\r\nstr:hello\r\n",len) == 0 && \ + len == 4+5+(12+2)+4+(9+2)); \ + free(cmd); \ +} while(0) + +#define FLOAT_WIDTH_TEST(type) do { \ + type value = 123.0; \ + test("Format command with printf-delegation (" #type "): "); \ + len = redisFormatCommand(&cmd,"key:%08.3f str:%s", value, "hello"); \ + test_cond(strncmp(cmd,"*2\r\n$12\r\nkey:0123.000\r\n$9\r\nstr:hello\r\n",len) == 0 && \ + len == 4+5+(12+2)+4+(9+2)); \ + free(cmd); \ +} while(0) + + INTEGER_WIDTH_TEST("d", int); + INTEGER_WIDTH_TEST("hhd", char); + INTEGER_WIDTH_TEST("hd", short); + INTEGER_WIDTH_TEST("ld", long); + INTEGER_WIDTH_TEST("lld", long long); + INTEGER_WIDTH_TEST("u", unsigned int); + INTEGER_WIDTH_TEST("hhu", unsigned char); + INTEGER_WIDTH_TEST("hu", unsigned short); + INTEGER_WIDTH_TEST("lu", unsigned long); + INTEGER_WIDTH_TEST("llu", unsigned long long); + FLOAT_WIDTH_TEST(float); + FLOAT_WIDTH_TEST(double); + + test("Format command with invalid printf format: "); + len = redisFormatCommand(&cmd,"key:%08p %b",(void*)1234,"foo",(size_t)3); + test_cond(len == -1); + + const char *argv[3]; + argv[0] = "SET"; + argv[1] = "foo\0xxx"; + argv[2] = "bar"; + size_t lens[3] = { 3, 7, 3 }; + int argc = 3; + + test("Format command by passing argc/argv without lengths: "); + len = redisFormatCommandArgv(&cmd,argc,argv,NULL); + test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$3\r\nbar\r\n",len) == 0 && + len == 4+4+(3+2)+4+(3+2)+4+(3+2)); + free(cmd); + + test("Format command by passing argc/argv with lengths: "); + len = redisFormatCommandArgv(&cmd,argc,argv,lens); + test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$7\r\nfoo\0xxx\r\n$3\r\nbar\r\n",len) == 0 && + len == 4+4+(3+2)+4+(7+2)+4+(3+2)); + free(cmd); + + sds sds_cmd; + + sds_cmd = NULL; + test("Format command into sds by passing argc/argv without lengths: "); + len = redisFormatSdsCommandArgv(&sds_cmd,argc,argv,NULL); + test_cond(strncmp(sds_cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$3\r\nbar\r\n",len) == 0 && + len == 4+4+(3+2)+4+(3+2)+4+(3+2)); + sdsfree(sds_cmd); + + sds_cmd = NULL; + test("Format command into sds by passing argc/argv with lengths: "); + len = redisFormatSdsCommandArgv(&sds_cmd,argc,argv,lens); + test_cond(strncmp(sds_cmd,"*3\r\n$3\r\nSET\r\n$7\r\nfoo\0xxx\r\n$3\r\nbar\r\n",len) == 0 && + len == 4+4+(3+2)+4+(7+2)+4+(3+2)); + sdsfree(sds_cmd); +} + +static void test_append_formatted_commands(struct config config) { + redisContext *c; + redisReply *reply; + char *cmd; + int len; + + c = do_connect(config); + + test("Append format command: "); + + len = redisFormatCommand(&cmd, "SET foo bar"); + + test_cond(redisAppendFormattedCommand(c, cmd, len) == REDIS_OK); + + assert(redisGetReply(c, (void*)&reply) == REDIS_OK); + + free(cmd); + freeReplyObject(reply); + + disconnect(c, 0); +} + +static void test_reply_reader(void) { + redisReader *reader; + void *reply; + int ret; + int i; + + test("Error handling in reply parser: "); + reader = redisReaderCreate(); + redisReaderFeed(reader,(char*)"@foo\r\n",6); + ret = redisReaderGetReply(reader,NULL); + test_cond(ret == REDIS_ERR && + strcasecmp(reader->errstr,"Protocol error, got \"@\" as reply type byte") == 0); + redisReaderFree(reader); + + /* when the reply already contains multiple items, they must be free'd + * on an error. valgrind will bark when this doesn't happen. */ + test("Memory cleanup in reply parser: "); + reader = redisReaderCreate(); + redisReaderFeed(reader,(char*)"*2\r\n",4); + redisReaderFeed(reader,(char*)"$5\r\nhello\r\n",11); + redisReaderFeed(reader,(char*)"@foo\r\n",6); + ret = redisReaderGetReply(reader,NULL); + test_cond(ret == REDIS_ERR && + strcasecmp(reader->errstr,"Protocol error, got \"@\" as reply type byte") == 0); + redisReaderFree(reader); + + test("Set error on nested multi bulks with depth > 7: "); + reader = redisReaderCreate(); + + for (i = 0; i < 9; i++) { + redisReaderFeed(reader,(char*)"*1\r\n",4); + } + + ret = redisReaderGetReply(reader,NULL); + test_cond(ret == REDIS_ERR && + strncasecmp(reader->errstr,"No support for",14) == 0); + redisReaderFree(reader); + + test("Correctly parses LLONG_MAX: "); + reader = redisReaderCreate(); + redisReaderFeed(reader, ":9223372036854775807\r\n",22); + ret = redisReaderGetReply(reader,&reply); + test_cond(ret == REDIS_OK && + ((redisReply*)reply)->type == REDIS_REPLY_INTEGER && + ((redisReply*)reply)->integer == LLONG_MAX); + freeReplyObject(reply); + redisReaderFree(reader); + + test("Set error when > LLONG_MAX: "); + reader = redisReaderCreate(); + redisReaderFeed(reader, ":9223372036854775808\r\n",22); + ret = redisReaderGetReply(reader,&reply); + test_cond(ret == REDIS_ERR && + strcasecmp(reader->errstr,"Bad integer value") == 0); + freeReplyObject(reply); + redisReaderFree(reader); + + test("Correctly parses LLONG_MIN: "); + reader = redisReaderCreate(); + redisReaderFeed(reader, ":-9223372036854775808\r\n",23); + ret = redisReaderGetReply(reader,&reply); + test_cond(ret == REDIS_OK && + ((redisReply*)reply)->type == REDIS_REPLY_INTEGER && + ((redisReply*)reply)->integer == LLONG_MIN); + freeReplyObject(reply); + redisReaderFree(reader); + + test("Set error when < LLONG_MIN: "); + reader = redisReaderCreate(); + redisReaderFeed(reader, ":-9223372036854775809\r\n",23); + ret = redisReaderGetReply(reader,&reply); + test_cond(ret == REDIS_ERR && + strcasecmp(reader->errstr,"Bad integer value") == 0); + freeReplyObject(reply); + redisReaderFree(reader); + + test("Set error when array < -1: "); + reader = redisReaderCreate(); + redisReaderFeed(reader, "*-2\r\n+asdf\r\n",12); + ret = redisReaderGetReply(reader,&reply); + test_cond(ret == REDIS_ERR && + strcasecmp(reader->errstr,"Multi-bulk length out of range") == 0); + freeReplyObject(reply); + redisReaderFree(reader); + + test("Set error when bulk < -1: "); + reader = redisReaderCreate(); + redisReaderFeed(reader, "$-2\r\nasdf\r\n",11); + ret = redisReaderGetReply(reader,&reply); + test_cond(ret == REDIS_ERR && + strcasecmp(reader->errstr,"Bulk string length out of range") == 0); + freeReplyObject(reply); + redisReaderFree(reader); + +#if LLONG_MAX > SIZE_MAX + test("Set error when array > SIZE_MAX: "); + reader = redisReaderCreate(); + redisReaderFeed(reader, "*9223372036854775807\r\n+asdf\r\n",29); + ret = redisReaderGetReply(reader,&reply); + test_cond(ret == REDIS_ERR && + strcasecmp(reader->errstr,"Multi-bulk length out of range") == 0); + freeReplyObject(reply); + redisReaderFree(reader); + + test("Set error when bulk > SIZE_MAX: "); + reader = redisReaderCreate(); + redisReaderFeed(reader, "$9223372036854775807\r\nasdf\r\n",28); + ret = redisReaderGetReply(reader,&reply); + test_cond(ret == REDIS_ERR && + strcasecmp(reader->errstr,"Bulk string length out of range") == 0); + freeReplyObject(reply); + redisReaderFree(reader); +#endif + + test("Works with NULL functions for reply: "); + reader = redisReaderCreate(); + reader->fn = NULL; + redisReaderFeed(reader,(char*)"+OK\r\n",5); + ret = redisReaderGetReply(reader,&reply); + test_cond(ret == REDIS_OK && reply == (void*)REDIS_REPLY_STATUS); + redisReaderFree(reader); + + test("Works when a single newline (\\r\\n) covers two calls to feed: "); + reader = redisReaderCreate(); + reader->fn = NULL; + redisReaderFeed(reader,(char*)"+OK\r",4); + ret = redisReaderGetReply(reader,&reply); + assert(ret == REDIS_OK && reply == NULL); + redisReaderFeed(reader,(char*)"\n",1); + ret = redisReaderGetReply(reader,&reply); + test_cond(ret == REDIS_OK && reply == (void*)REDIS_REPLY_STATUS); + redisReaderFree(reader); + + test("Don't reset state after protocol error: "); + reader = redisReaderCreate(); + reader->fn = NULL; + redisReaderFeed(reader,(char*)"x",1); + ret = redisReaderGetReply(reader,&reply); + assert(ret == REDIS_ERR); + ret = redisReaderGetReply(reader,&reply); + test_cond(ret == REDIS_ERR && reply == NULL); + redisReaderFree(reader); + + /* Regression test for issue #45 on GitHub. */ + test("Don't do empty allocation for empty multi bulk: "); + reader = redisReaderCreate(); + redisReaderFeed(reader,(char*)"*0\r\n",4); + ret = redisReaderGetReply(reader,&reply); + test_cond(ret == REDIS_OK && + ((redisReply*)reply)->type == REDIS_REPLY_ARRAY && + ((redisReply*)reply)->elements == 0); + freeReplyObject(reply); + redisReaderFree(reader); +} + +static void test_free_null(void) { + void *redisCtx = NULL; + void *reply = NULL; + + test("Don't fail when redisFree is passed a NULL value: "); + redisFree(redisCtx); + test_cond(redisCtx == NULL); + + test("Don't fail when freeReplyObject is passed a NULL value: "); + freeReplyObject(reply); + test_cond(reply == NULL); +} + +#define HIREDIS_BAD_DOMAIN "idontexist-noreally.com" +static void test_blocking_connection_errors(void) { + redisContext *c; + struct addrinfo hints = {.ai_family = AF_INET}; + struct addrinfo *ai_tmp = NULL; + + int rv = getaddrinfo(HIREDIS_BAD_DOMAIN, "6379", &hints, &ai_tmp); + if (rv != 0) { + // Address does *not* exist + test("Returns error when host cannot be resolved: "); + // First see if this domain name *actually* resolves to NXDOMAIN + c = redisConnect(HIREDIS_BAD_DOMAIN, 6379); + test_cond( + c->err == REDIS_ERR_OTHER && + (strcmp(c->errstr, "Name or service not known") == 0 || + strcmp(c->errstr, "Can't resolve: " HIREDIS_BAD_DOMAIN) == 0 || + strcmp(c->errstr, "Name does not resolve") == 0 || + strcmp(c->errstr, + "nodename nor servname provided, or not known") == 0 || + strcmp(c->errstr, "No address associated with hostname") == 0 || + strcmp(c->errstr, "Temporary failure in name resolution") == 0 || + strcmp(c->errstr, + "hostname nor servname provided, or not known") == 0 || + strcmp(c->errstr, "no address associated with name") == 0)); + redisFree(c); + } else { + printf("Skipping NXDOMAIN test. Found evil ISP!\n"); + freeaddrinfo(ai_tmp); + } + + test("Returns error when the port is not open: "); + c = redisConnect((char*)"localhost", 1); + test_cond(c->err == REDIS_ERR_IO && + strcmp(c->errstr,"Connection refused") == 0); + redisFree(c); + + test("Returns error when the unix_sock socket path doesn't accept connections: "); + c = redisConnectUnix((char*)"/tmp/idontexist.sock"); + test_cond(c->err == REDIS_ERR_IO); /* Don't care about the message... */ + redisFree(c); +} + +static void test_blocking_connection(struct config config) { + redisContext *c; + redisReply *reply; + + c = do_connect(config); + + test("Is able to deliver commands: "); + reply = redisCommand(c,"PING"); + test_cond(reply->type == REDIS_REPLY_STATUS && + strcasecmp(reply->str,"pong") == 0) + freeReplyObject(reply); + + test("Is a able to send commands verbatim: "); + reply = redisCommand(c,"SET foo bar"); + test_cond (reply->type == REDIS_REPLY_STATUS && + strcasecmp(reply->str,"ok") == 0) + freeReplyObject(reply); + + test("%%s String interpolation works: "); + reply = redisCommand(c,"SET %s %s","foo","hello world"); + freeReplyObject(reply); + reply = redisCommand(c,"GET foo"); + test_cond(reply->type == REDIS_REPLY_STRING && + strcmp(reply->str,"hello world") == 0); + freeReplyObject(reply); + + test("%%b String interpolation works: "); + reply = redisCommand(c,"SET %b %b","foo",(size_t)3,"hello\x00world",(size_t)11); + freeReplyObject(reply); + reply = redisCommand(c,"GET foo"); + test_cond(reply->type == REDIS_REPLY_STRING && + memcmp(reply->str,"hello\x00world",11) == 0) + + test("Binary reply length is correct: "); + test_cond(reply->len == 11) + freeReplyObject(reply); + + test("Can parse nil replies: "); + reply = redisCommand(c,"GET nokey"); + test_cond(reply->type == REDIS_REPLY_NIL) + freeReplyObject(reply); + + /* test 7 */ + test("Can parse integer replies: "); + reply = redisCommand(c,"INCR mycounter"); + test_cond(reply->type == REDIS_REPLY_INTEGER && reply->integer == 1) + freeReplyObject(reply); + + test("Can parse multi bulk replies: "); + freeReplyObject(redisCommand(c,"LPUSH mylist foo")); + freeReplyObject(redisCommand(c,"LPUSH mylist bar")); + reply = redisCommand(c,"LRANGE mylist 0 -1"); + test_cond(reply->type == REDIS_REPLY_ARRAY && + reply->elements == 2 && + !memcmp(reply->element[0]->str,"bar",3) && + !memcmp(reply->element[1]->str,"foo",3)) + freeReplyObject(reply); + + /* m/e with multi bulk reply *before* other reply. + * specifically test ordering of reply items to parse. */ + test("Can handle nested multi bulk replies: "); + freeReplyObject(redisCommand(c,"MULTI")); + freeReplyObject(redisCommand(c,"LRANGE mylist 0 -1")); + freeReplyObject(redisCommand(c,"PING")); + reply = (redisCommand(c,"EXEC")); + test_cond(reply->type == REDIS_REPLY_ARRAY && + reply->elements == 2 && + reply->element[0]->type == REDIS_REPLY_ARRAY && + reply->element[0]->elements == 2 && + !memcmp(reply->element[0]->element[0]->str,"bar",3) && + !memcmp(reply->element[0]->element[1]->str,"foo",3) && + reply->element[1]->type == REDIS_REPLY_STATUS && + strcasecmp(reply->element[1]->str,"pong") == 0); + freeReplyObject(reply); + + /* Make sure passing NULL to redisGetReply is safe */ + test("Can pass NULL to redisGetReply: "); + assert(redisAppendCommand(c, "PING") == REDIS_OK); + test_cond(redisGetReply(c, NULL) == REDIS_OK); + + disconnect(c, 0); +} + +static void test_blocking_connection_timeouts(struct config config) { + redisContext *c; + redisReply *reply; + ssize_t s; + const char *cmd = "DEBUG SLEEP 3\r\n"; + struct timeval tv; + + c = do_connect(config); + test("Successfully completes a command when the timeout is not exceeded: "); + reply = redisCommand(c,"SET foo fast"); + freeReplyObject(reply); + tv.tv_sec = 0; + tv.tv_usec = 10000; + redisSetTimeout(c, tv); + reply = redisCommand(c, "GET foo"); + test_cond(reply != NULL && reply->type == REDIS_REPLY_STRING && memcmp(reply->str, "fast", 4) == 0); + freeReplyObject(reply); + disconnect(c, 0); + + c = do_connect(config); + test("Does not return a reply when the command times out: "); + redisAppendFormattedCommand(c, cmd, strlen(cmd)); + s = c->funcs->write(c); + tv.tv_sec = 0; + tv.tv_usec = 10000; + redisSetTimeout(c, tv); + reply = redisCommand(c, "GET foo"); + test_cond(s > 0 && reply == NULL && c->err == REDIS_ERR_IO && strcmp(c->errstr, "Resource temporarily unavailable") == 0); + freeReplyObject(reply); + + test("Reconnect properly reconnects after a timeout: "); + do_reconnect(c, config); + reply = redisCommand(c, "PING"); + test_cond(reply != NULL && reply->type == REDIS_REPLY_STATUS && strcmp(reply->str, "PONG") == 0); + freeReplyObject(reply); + + test("Reconnect properly uses owned parameters: "); + config.tcp.host = "foo"; + config.unix_sock.path = "foo"; + do_reconnect(c, config); + reply = redisCommand(c, "PING"); + test_cond(reply != NULL && reply->type == REDIS_REPLY_STATUS && strcmp(reply->str, "PONG") == 0); + freeReplyObject(reply); + + disconnect(c, 0); +} + +static void test_blocking_io_errors(struct config config) { + redisContext *c; + redisReply *reply; + void *_reply; + int major, minor; + + /* Connect to target given by config. */ + c = do_connect(config); + { + /* Find out Redis version to determine the path for the next test */ + const char *field = "redis_version:"; + char *p, *eptr; + + reply = redisCommand(c,"INFO"); + p = strstr(reply->str,field); + major = strtol(p+strlen(field),&eptr,10); + p = eptr+1; /* char next to the first "." */ + minor = strtol(p,&eptr,10); + freeReplyObject(reply); + } + + test("Returns I/O error when the connection is lost: "); + reply = redisCommand(c,"QUIT"); + if (major > 2 || (major == 2 && minor > 0)) { + /* > 2.0 returns OK on QUIT and read() should be issued once more + * to know the descriptor is at EOF. */ + test_cond(strcasecmp(reply->str,"OK") == 0 && + redisGetReply(c,&_reply) == REDIS_ERR); + freeReplyObject(reply); + } else { + test_cond(reply == NULL); + } + + /* On 2.0, QUIT will cause the connection to be closed immediately and + * the read(2) for the reply on QUIT will set the error to EOF. + * On >2.0, QUIT will return with OK and another read(2) needed to be + * issued to find out the socket was closed by the server. In both + * conditions, the error will be set to EOF. */ + assert(c->err == REDIS_ERR_EOF && + strcmp(c->errstr,"Server closed the connection") == 0); + redisFree(c); + + c = do_connect(config); + test("Returns I/O error on socket timeout: "); + struct timeval tv = { 0, 1000 }; + assert(redisSetTimeout(c,tv) == REDIS_OK); + test_cond(redisGetReply(c,&_reply) == REDIS_ERR && + c->err == REDIS_ERR_IO && errno == EAGAIN); + redisFree(c); +} + +static void test_invalid_timeout_errors(struct config config) { + redisContext *c; + + test("Set error when an invalid timeout usec value is given to redisConnectWithTimeout: "); + + config.tcp.timeout.tv_sec = 0; + config.tcp.timeout.tv_usec = 10000001; + + c = redisConnectWithTimeout(config.tcp.host, config.tcp.port, config.tcp.timeout); + + test_cond(c->err == REDIS_ERR_IO && strcmp(c->errstr, "Invalid timeout specified") == 0); + redisFree(c); + + test("Set error when an invalid timeout sec value is given to redisConnectWithTimeout: "); + + config.tcp.timeout.tv_sec = (((LONG_MAX) - 999) / 1000) + 1; + config.tcp.timeout.tv_usec = 0; + + c = redisConnectWithTimeout(config.tcp.host, config.tcp.port, config.tcp.timeout); + + test_cond(c->err == REDIS_ERR_IO && strcmp(c->errstr, "Invalid timeout specified") == 0); + redisFree(c); +} + +static void test_throughput(struct config config) { + redisContext *c = do_connect(config); + redisReply **replies; + int i, num; + long long t1, t2; + + test("Throughput:\n"); + for (i = 0; i < 500; i++) + freeReplyObject(redisCommand(c,"LPUSH mylist foo")); + + num = 1000; + replies = malloc(sizeof(redisReply*)*num); + t1 = usec(); + for (i = 0; i < num; i++) { + replies[i] = redisCommand(c,"PING"); + assert(replies[i] != NULL && replies[i]->type == REDIS_REPLY_STATUS); + } + t2 = usec(); + for (i = 0; i < num; i++) freeReplyObject(replies[i]); + free(replies); + printf("\t(%dx PING: %.3fs)\n", num, (t2-t1)/1000000.0); + + replies = malloc(sizeof(redisReply*)*num); + t1 = usec(); + for (i = 0; i < num; i++) { + replies[i] = redisCommand(c,"LRANGE mylist 0 499"); + assert(replies[i] != NULL && replies[i]->type == REDIS_REPLY_ARRAY); + assert(replies[i] != NULL && replies[i]->elements == 500); + } + t2 = usec(); + for (i = 0; i < num; i++) freeReplyObject(replies[i]); + free(replies); + printf("\t(%dx LRANGE with 500 elements: %.3fs)\n", num, (t2-t1)/1000000.0); + + replies = malloc(sizeof(redisReply*)*num); + t1 = usec(); + for (i = 0; i < num; i++) { + replies[i] = redisCommand(c, "INCRBY incrkey %d", 1000000); + assert(replies[i] != NULL && replies[i]->type == REDIS_REPLY_INTEGER); + } + t2 = usec(); + for (i = 0; i < num; i++) freeReplyObject(replies[i]); + free(replies); + printf("\t(%dx INCRBY: %.3fs)\n", num, (t2-t1)/1000000.0); + + num = 10000; + replies = malloc(sizeof(redisReply*)*num); + for (i = 0; i < num; i++) + redisAppendCommand(c,"PING"); + t1 = usec(); + for (i = 0; i < num; i++) { + assert(redisGetReply(c, (void*)&replies[i]) == REDIS_OK); + assert(replies[i] != NULL && replies[i]->type == REDIS_REPLY_STATUS); + } + t2 = usec(); + for (i = 0; i < num; i++) freeReplyObject(replies[i]); + free(replies); + printf("\t(%dx PING (pipelined): %.3fs)\n", num, (t2-t1)/1000000.0); + + replies = malloc(sizeof(redisReply*)*num); + for (i = 0; i < num; i++) + redisAppendCommand(c,"LRANGE mylist 0 499"); + t1 = usec(); + for (i = 0; i < num; i++) { + assert(redisGetReply(c, (void*)&replies[i]) == REDIS_OK); + assert(replies[i] != NULL && replies[i]->type == REDIS_REPLY_ARRAY); + assert(replies[i] != NULL && replies[i]->elements == 500); + } + t2 = usec(); + for (i = 0; i < num; i++) freeReplyObject(replies[i]); + free(replies); + printf("\t(%dx LRANGE with 500 elements (pipelined): %.3fs)\n", num, (t2-t1)/1000000.0); + + replies = malloc(sizeof(redisReply*)*num); + for (i = 0; i < num; i++) + redisAppendCommand(c,"INCRBY incrkey %d", 1000000); + t1 = usec(); + for (i = 0; i < num; i++) { + assert(redisGetReply(c, (void*)&replies[i]) == REDIS_OK); + assert(replies[i] != NULL && replies[i]->type == REDIS_REPLY_INTEGER); + } + t2 = usec(); + for (i = 0; i < num; i++) freeReplyObject(replies[i]); + free(replies); + printf("\t(%dx INCRBY (pipelined): %.3fs)\n", num, (t2-t1)/1000000.0); + + disconnect(c, 0); +} + +// static long __test_callback_flags = 0; +// static void __test_callback(redisContext *c, void *privdata) { +// ((void)c); +// /* Shift to detect execution order */ +// __test_callback_flags <<= 8; +// __test_callback_flags |= (long)privdata; +// } +// +// static void __test_reply_callback(redisContext *c, redisReply *reply, void *privdata) { +// ((void)c); +// /* Shift to detect execution order */ +// __test_callback_flags <<= 8; +// __test_callback_flags |= (long)privdata; +// if (reply) freeReplyObject(reply); +// } +// +// static redisContext *__connect_nonblock() { +// /* Reset callback flags */ +// __test_callback_flags = 0; +// return redisConnectNonBlock("127.0.0.1", port, NULL); +// } +// +// static void test_nonblocking_connection() { +// redisContext *c; +// int wdone = 0; +// +// test("Calls command callback when command is issued: "); +// c = __connect_nonblock(); +// redisSetCommandCallback(c,__test_callback,(void*)1); +// redisCommand(c,"PING"); +// test_cond(__test_callback_flags == 1); +// redisFree(c); +// +// test("Calls disconnect callback on redisDisconnect: "); +// c = __connect_nonblock(); +// redisSetDisconnectCallback(c,__test_callback,(void*)2); +// redisDisconnect(c); +// test_cond(__test_callback_flags == 2); +// redisFree(c); +// +// test("Calls disconnect callback and free callback on redisFree: "); +// c = __connect_nonblock(); +// redisSetDisconnectCallback(c,__test_callback,(void*)2); +// redisSetFreeCallback(c,__test_callback,(void*)4); +// redisFree(c); +// test_cond(__test_callback_flags == ((2 << 8) | 4)); +// +// test("redisBufferWrite against empty write buffer: "); +// c = __connect_nonblock(); +// test_cond(redisBufferWrite(c,&wdone) == REDIS_OK && wdone == 1); +// redisFree(c); +// +// test("redisBufferWrite against not yet connected fd: "); +// c = __connect_nonblock(); +// redisCommand(c,"PING"); +// test_cond(redisBufferWrite(c,NULL) == REDIS_ERR && +// strncmp(c->error,"write:",6) == 0); +// redisFree(c); +// +// test("redisBufferWrite against closed fd: "); +// c = __connect_nonblock(); +// redisCommand(c,"PING"); +// redisDisconnect(c); +// test_cond(redisBufferWrite(c,NULL) == REDIS_ERR && +// strncmp(c->error,"write:",6) == 0); +// redisFree(c); +// +// test("Process callbacks in the right sequence: "); +// c = __connect_nonblock(); +// redisCommandWithCallback(c,__test_reply_callback,(void*)1,"PING"); +// redisCommandWithCallback(c,__test_reply_callback,(void*)2,"PING"); +// redisCommandWithCallback(c,__test_reply_callback,(void*)3,"PING"); +// +// /* Write output buffer */ +// wdone = 0; +// while(!wdone) { +// usleep(500); +// redisBufferWrite(c,&wdone); +// } +// +// /* Read until at least one callback is executed (the 3 replies will +// * arrive in a single packet, causing all callbacks to be executed in +// * a single pass). */ +// while(__test_callback_flags == 0) { +// assert(redisBufferRead(c) == REDIS_OK); +// redisProcessCallbacks(c); +// } +// test_cond(__test_callback_flags == 0x010203); +// redisFree(c); +// +// test("redisDisconnect executes pending callbacks with NULL reply: "); +// c = __connect_nonblock(); +// redisSetDisconnectCallback(c,__test_callback,(void*)1); +// redisCommandWithCallback(c,__test_reply_callback,(void*)2,"PING"); +// redisDisconnect(c); +// test_cond(__test_callback_flags == 0x0201); +// redisFree(c); +// } + +int main(int argc, char **argv) { + struct config cfg = { + .tcp = { + .host = "127.0.0.1", + .port = 6379 + }, + .unix_sock = { + .path = "/tmp/redis.sock" + } + }; + int throughput = 1; + int test_inherit_fd = 1; + + /* Ignore broken pipe signal (for I/O error tests). */ + signal(SIGPIPE, SIG_IGN); + + /* Parse command line options. */ + argv++; argc--; + while (argc) { + if (argc >= 2 && !strcmp(argv[0],"-h")) { + argv++; argc--; + cfg.tcp.host = argv[0]; + } else if (argc >= 2 && !strcmp(argv[0],"-p")) { + argv++; argc--; + cfg.tcp.port = atoi(argv[0]); + } else if (argc >= 2 && !strcmp(argv[0],"-s")) { + argv++; argc--; + cfg.unix_sock.path = argv[0]; + } else if (argc >= 1 && !strcmp(argv[0],"--skip-throughput")) { + throughput = 0; + } else if (argc >= 1 && !strcmp(argv[0],"--skip-inherit-fd")) { + test_inherit_fd = 0; +#ifdef HIREDIS_TEST_SSL + } else if (argc >= 2 && !strcmp(argv[0],"--ssl-port")) { + argv++; argc--; + cfg.ssl.port = atoi(argv[0]); + } else if (argc >= 2 && !strcmp(argv[0],"--ssl-host")) { + argv++; argc--; + cfg.ssl.host = argv[0]; + } else if (argc >= 2 && !strcmp(argv[0],"--ssl-ca-cert")) { + argv++; argc--; + cfg.ssl.ca_cert = argv[0]; + } else if (argc >= 2 && !strcmp(argv[0],"--ssl-cert")) { + argv++; argc--; + cfg.ssl.cert = argv[0]; + } else if (argc >= 2 && !strcmp(argv[0],"--ssl-key")) { + argv++; argc--; + cfg.ssl.key = argv[0]; +#endif + } else { + fprintf(stderr, "Invalid argument: %s\n", argv[0]); + exit(1); + } + argv++; argc--; + } + + test_format_commands(); + test_reply_reader(); + test_blocking_connection_errors(); + test_free_null(); + + printf("\nTesting against TCP connection (%s:%d):\n", cfg.tcp.host, cfg.tcp.port); + cfg.type = CONN_TCP; + test_blocking_connection(cfg); + test_blocking_connection_timeouts(cfg); + test_blocking_io_errors(cfg); + test_invalid_timeout_errors(cfg); + test_append_formatted_commands(cfg); + if (throughput) test_throughput(cfg); + + printf("\nTesting against Unix socket connection (%s):\n", cfg.unix_sock.path); + cfg.type = CONN_UNIX; + test_blocking_connection(cfg); + test_blocking_connection_timeouts(cfg); + test_blocking_io_errors(cfg); + if (throughput) test_throughput(cfg); + +#ifdef HIREDIS_TEST_SSL + if (cfg.ssl.port && cfg.ssl.host) { + printf("\nTesting against SSL connection (%s:%d):\n", cfg.ssl.host, cfg.ssl.port); + cfg.type = CONN_SSL; + + test_blocking_connection(cfg); + test_blocking_connection_timeouts(cfg); + test_blocking_io_errors(cfg); + test_invalid_timeout_errors(cfg); + test_append_formatted_commands(cfg); + if (throughput) test_throughput(cfg); + } +#endif + + if (test_inherit_fd) { + printf("\nTesting against inherited fd (%s):\n", cfg.unix_sock.path); + cfg.type = CONN_FD; + test_blocking_connection(cfg); + } + + + if (fails) { + printf("*** %d TESTS FAILED ***\n", fails); + return 1; + } + + printf("ALL TESTS PASSED\n"); + return 0; +} diff --git a/俱乐部/Source/hiredis/test.sh b/俱乐部/Source/hiredis/test.sh new file mode 100644 index 0000000..2cab9e6 --- /dev/null +++ b/俱乐部/Source/hiredis/test.sh @@ -0,0 +1,70 @@ +#!/bin/sh -ue + +REDIS_SERVER=${REDIS_SERVER:-redis-server} +REDIS_PORT=${REDIS_PORT:-56379} +REDIS_SSL_PORT=${REDIS_SSL_PORT:-56443} +TEST_SSL=${TEST_SSL:-0} +SSL_TEST_ARGS= + +tmpdir=$(mktemp -d) +PID_FILE=${tmpdir}/hiredis-test-redis.pid +SOCK_FILE=${tmpdir}/hiredis-test-redis.sock + +if [ "$TEST_SSL" = "1" ]; then + SSL_CA_CERT=${tmpdir}/ca.crt + SSL_CA_KEY=${tmpdir}/ca.key + SSL_CERT=${tmpdir}/redis.crt + SSL_KEY=${tmpdir}/redis.key + + openssl genrsa -out ${tmpdir}/ca.key 4096 + openssl req \ + -x509 -new -nodes -sha256 \ + -key ${SSL_CA_KEY} \ + -days 3650 \ + -subj '/CN=Hiredis Test CA' \ + -out ${SSL_CA_CERT} + openssl genrsa -out ${SSL_KEY} 2048 + openssl req \ + -new -sha256 \ + -key ${SSL_KEY} \ + -subj '/CN=Hiredis Test Cert' | \ + openssl x509 \ + -req -sha256 \ + -CA ${SSL_CA_CERT} \ + -CAkey ${SSL_CA_KEY} \ + -CAserial ${tmpdir}/ca.txt \ + -CAcreateserial \ + -days 365 \ + -out ${SSL_CERT} + + SSL_TEST_ARGS="--ssl-host 127.0.0.1 --ssl-port ${REDIS_SSL_PORT} --ssl-ca-cert ${SSL_CA_CERT} --ssl-cert ${SSL_CERT} --ssl-key ${SSL_KEY}" +fi + +cleanup() { + set +e + kill $(cat ${PID_FILE}) + rm -rf ${tmpdir} +} +trap cleanup INT TERM EXIT + +cat > ${tmpdir}/redis.conf <> ${tmpdir}/redis.conf < /* for struct timeval */ + +#ifndef inline +#define inline __inline +#endif + +#ifndef strcasecmp +#define strcasecmp stricmp +#endif + +#ifndef strncasecmp +#define strncasecmp strnicmp +#endif + +#ifndef va_copy +#define va_copy(d,s) ((d) = (s)) +#endif + +#ifndef snprintf +#define snprintf c99_snprintf + +__inline int c99_vsnprintf(char* str, size_t size, const char* format, va_list ap) +{ + int count = -1; + + if (size != 0) + count = _vsnprintf_s(str, size, _TRUNCATE, format, ap); + if (count == -1) + count = _vscprintf(format, ap); + + return count; +} + +__inline int c99_snprintf(char* str, size_t size, const char* format, ...) +{ + int count; + va_list ap; + + va_start(ap, format); + count = c99_vsnprintf(str, size, format, ap); + va_end(ap); + + return count; +} +#endif +#endif /* _MSC_VER */ + +#ifdef _WIN32 +#define strerror_r(errno,buf,len) strerror_s(buf,len,errno) +#endif /* _WIN32 */ + +#endif /* _WIN32_HELPER_INCLUDE */