├── .gitignore ├── ChatClient ├── App.config ├── ClientSimpleTcp.cs ├── DevLog.cs ├── Packet.cs ├── PacketBufferManager.cs ├── PacketDefine.cs ├── PacketProcessForm.cs ├── Program.cs ├── Properties │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings ├── csharp_test_client.csproj ├── csharp_test_client.sln ├── mainForm.Designer.cs ├── mainForm.cs └── mainForm.resx ├── LICENSE ├── README.md ├── Tutorial ├── 10 │ ├── ChatServer.h │ ├── ChatServer_03.sln │ ├── ChatServer_03.vcxproj │ ├── ChatServer_03.vcxproj.filters │ ├── ErrorCode.h │ ├── Packet.h │ ├── PacketManager.cpp │ ├── PacketManager.h │ ├── RedisManager.h │ ├── RedisTaskDefine.h │ ├── Room.h │ ├── RoomManager.h │ ├── ServerNetwork │ │ ├── ClientInfo.h │ │ ├── Define.h │ │ └── IOCPServer.h │ ├── User.h │ ├── UserManager.h │ └── main.cpp ├── 01 │ ├── IOCP_01.sln │ ├── IOCP_01.vcxproj │ ├── IOCompletionPort.h │ └── main.cpp ├── 02 │ ├── Define.h │ ├── IOCP_02.sln │ ├── IOCP_02.vcxproj │ ├── IOCompletionPort.h │ └── main.cpp ├── 03 │ ├── Define.h │ ├── EchoServer.h │ ├── IOCPServer.h │ ├── IOCP_03.sln │ ├── IOCP_03.vcxproj │ ├── IOCP_03.vcxproj.filters │ └── main.cpp ├── 04 │ ├── ClientInfo.h │ ├── Define.h │ ├── EchoServer.h │ ├── IOCPServer.h │ ├── IOCP_04.sln │ ├── IOCP_04.vcxproj │ ├── IOCP_04.vcxproj.filters │ ├── Packet.h │ └── main.cpp ├── 05 │ ├── ClientInfo.h │ ├── Define.h │ ├── EchoServer.h │ ├── IOCPServer.h │ ├── IOCP_05.sln │ ├── IOCP_05.vcxproj │ ├── IOCP_05.vcxproj.filters │ ├── Packet.h │ └── main.cpp ├── 06 │ ├── ClientInfo.h │ ├── Define.h │ ├── EchoServer.h │ ├── IOCPServer.h │ ├── IOCP_06.sln │ ├── IOCP_06.vcxproj │ ├── IOCP_06.vcxproj.filters │ ├── Packet.h │ └── main.cpp ├── 07 │ ├── ClientInfo.h │ ├── Define.h │ ├── EchoServer.h │ ├── IOCPServer.h │ ├── IOCP_07.sln │ ├── IOCP_07.vcxproj │ ├── IOCP_07.vcxproj.filters │ ├── Packet.h │ └── main.cpp ├── 08 │ ├── ChatServer.h │ ├── ChatServer_01.sln │ ├── ChatServer_01.vcxproj │ ├── ChatServer_01.vcxproj.filters │ ├── ErrorCode.h │ ├── Packet.h │ ├── PacketManager.cpp │ ├── PacketManager.h │ ├── ServerNetwork │ │ ├── ClientInfo.h │ │ ├── Define.h │ │ └── IOCPServer.h │ ├── User.h │ ├── UserManager.h │ └── main.cpp ├── 09 │ ├── ChatServer.h │ ├── ChatServer_02.sln │ ├── ChatServer_02.vcxproj │ ├── ChatServer_02.vcxproj.filters │ ├── ErrorCode.h │ ├── Packet.h │ ├── PacketManager.cpp │ ├── PacketManager.h │ ├── RedisManager.h │ ├── RedisTaskDefine.h │ ├── ServerNetwork │ │ ├── ClientInfo.h │ │ ├── Define.h │ │ └── IOCPServer.h │ ├── User.h │ ├── UserManager.h │ └── main.cpp ├── AllProjects.sln ├── ChatServerWithLogger │ ├── ChatServer.h │ ├── ChatServer.sln │ ├── ChatServer.vcxproj │ ├── ChatServer.vcxproj.filters │ ├── ErrorCode.h │ ├── Packet.h │ ├── PacketManager.cpp │ ├── PacketManager.h │ ├── RedisManager.h │ ├── RedisTaskDefine.h │ ├── Room.h │ ├── RoomManager.h │ ├── ServerNetwork │ │ ├── ClientInfo.h │ │ ├── Define.h │ │ └── IOCPServer.h │ ├── User.h │ ├── UserManager.h │ └── main.cpp ├── premake5.lua └── thirdparty │ ├── CRedisConn.h │ ├── RedisCpp-hiredis │ ├── CRedisConn_test.cpp │ ├── RedisCpp-hiredis.md │ ├── Samples │ │ ├── Connect │ │ │ ├── Connect.cpp │ │ │ ├── Connect.sln │ │ │ ├── Connect.vcxproj │ │ │ └── Connect.vcxproj.filters │ │ └── List │ │ │ ├── List.sln │ │ │ ├── List.vcxproj │ │ │ ├── main.cpp │ │ │ └── premake5.lua │ ├── images │ │ ├── 001.png │ │ └── 002.png │ └── src │ │ └── CRedisConn.h │ ├── flags.h │ ├── hiredis │ ├── .gitignore │ ├── .travis.yml │ ├── CHANGELOG.md │ ├── CMakeLists.txt │ ├── COPYING │ ├── Makefile │ ├── README.md │ ├── VS-IDE │ │ ├── ALL_BUILD.vcxproj │ │ ├── ALL_BUILD.vcxproj.filters │ │ ├── CMakeCache.txt │ │ ├── Debug │ │ │ ├── hiredis.lib │ │ │ └── hiredis.pdb │ │ ├── INSTALL.vcxproj │ │ ├── INSTALL.vcxproj.filters │ │ ├── Release │ │ │ └── hiredis.lib │ │ ├── ZERO_CHECK.vcxproj │ │ ├── ZERO_CHECK.vcxproj.filters │ │ ├── cmake_install.cmake │ │ ├── hiredis.pc │ │ ├── hiredis.sln │ │ ├── hiredis.vcxproj │ │ └── hiredis.vcxproj.filters │ ├── adapters │ │ ├── ae.h │ │ ├── glib.h │ │ ├── ivykis.h │ │ ├── libev.h │ │ ├── libevent.h │ │ ├── libuv.h │ │ ├── macosx.h │ │ └── qt.h │ ├── appveyor.yml │ ├── async.c │ ├── async.h │ ├── async_private.h │ ├── dict.c │ ├── dict.h │ ├── examples │ │ ├── CMakeLists.txt │ │ ├── example-ae.c │ │ ├── example-glib.c │ │ ├── example-ivykis.c │ │ ├── example-libev.c │ │ ├── example-libevent-ssl.c │ │ ├── example-libevent.c │ │ ├── example-libuv.c │ │ ├── example-macosx.c │ │ ├── example-qt.cpp │ │ ├── example-qt.h │ │ ├── example-ssl.c │ │ └── example.c │ ├── fmacros.h │ ├── hiredis.c │ ├── hiredis.h │ ├── hiredis.pc.in │ ├── hiredis_ssl.h │ ├── hiredis_ssl.pc.in │ ├── net.c │ ├── net.h │ ├── read.c │ ├── read.h │ ├── sds.c │ ├── sds.h │ ├── sdsalloc.h │ ├── sockcompat.c │ ├── sockcompat.h │ ├── ssl.c │ ├── test.c │ ├── test.sh │ └── win32.h │ └── plog │ ├── .appveyor.yml │ ├── .circleci │ └── config.yml │ ├── .cirrus.yml │ ├── .editorconfig │ ├── .gitignore │ ├── .travis.yml │ ├── CMakeLists.txt │ ├── LICENSE │ ├── README.md │ ├── include │ └── plog │ │ ├── Appenders │ │ ├── AndroidAppender.h │ │ ├── ColorConsoleAppender.h │ │ ├── ConsoleAppender.h │ │ ├── DebugOutputAppender.h │ │ ├── EventLogAppender.h │ │ ├── IAppender.h │ │ └── RollingFileAppender.h │ │ ├── Converters │ │ ├── NativeEOLConverter.h │ │ └── UTF8Converter.h │ │ ├── Formatters │ │ ├── CsvFormatter.h │ │ ├── FuncMessageFormatter.h │ │ ├── MessageOnlyFormatter.h │ │ └── TxtFormatter.h │ │ ├── Init.h │ │ ├── Log.h │ │ ├── Logger.h │ │ ├── Record.h │ │ ├── Severity.h │ │ ├── Util.h │ │ └── WinApi.h │ └── samples │ ├── Android │ ├── CMakeLists.txt │ └── jni │ │ ├── Android.mk │ │ ├── Application.mk │ │ └── Sample.cpp │ ├── CMakeLists.txt │ ├── Chained │ ├── CMakeLists.txt │ ├── ChainedApp │ │ └── Main.cpp │ └── ChainedLib │ │ └── Main.cpp │ ├── ColorConsole │ ├── CMakeLists.txt │ └── Main.cpp │ ├── CustomAppender │ ├── CMakeLists.txt │ └── Main.cpp │ ├── CustomConverter │ ├── CMakeLists.txt │ └── Main.cpp │ ├── CustomFormatter │ ├── CMakeLists.txt │ └── Main.cpp │ ├── CustomType │ ├── CMakeLists.txt │ └── Main.cpp │ ├── DebugOutput │ ├── CMakeLists.txt │ └── Main.cpp │ ├── Demo │ ├── CMakeLists.txt │ ├── Customer.h │ ├── Main.cpp │ ├── MyClass.cpp │ └── MyClass.h │ ├── EventLog │ ├── CMakeLists.txt │ └── Main.cpp │ ├── Facilities │ ├── CMakeLists.txt │ └── Main.cpp │ ├── Hello │ ├── CMakeLists.txt │ └── Main.cpp │ ├── Library │ ├── CMakeLists.txt │ ├── LibraryApp │ │ └── Main.cpp │ └── LibraryLib │ │ └── Lib.cpp │ ├── MultiAppender │ ├── CMakeLists.txt │ └── Main.cpp │ ├── MultiInstance │ ├── CMakeLists.txt │ └── Main.cpp │ ├── ObjectiveC │ ├── CMakeLists.txt │ └── Main.mm │ ├── Performance │ ├── CMakeLists.txt │ └── Main.cpp │ ├── SkipNativeEOL │ ├── CMakeLists.txt │ └── Main.cpp │ └── UtcTime │ ├── CMakeLists.txt │ └── Main.cpp ├── iocp_learning_guide.md └── iocp_learning_guide_sub01.md /ChatClient/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /ChatClient/ClientSimpleTcp.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net.Sockets; 3 | using System.Net; 4 | 5 | namespace csharp_test_client 6 | { 7 | public class ClientSimpleTcp 8 | { 9 | public Socket Sock = null; 10 | public string LatestErrorMsg; 11 | 12 | 13 | //소켓연결 14 | public bool Connect(string ip, int port) 15 | { 16 | try 17 | { 18 | IPAddress serverIP = IPAddress.Parse(ip); 19 | int serverPort = port; 20 | 21 | Sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 22 | Sock.Connect(new IPEndPoint(serverIP, serverPort)); 23 | 24 | if (Sock == null || Sock.Connected == false) 25 | { 26 | return false; 27 | } 28 | 29 | return true; 30 | } 31 | catch (Exception ex) 32 | { 33 | LatestErrorMsg = ex.Message; 34 | return false; 35 | } 36 | } 37 | 38 | public Tuple Receive() 39 | { 40 | 41 | try 42 | { 43 | byte[] ReadBuffer = new byte[2048]; 44 | var nRecv = Sock.Receive(ReadBuffer, 0, ReadBuffer.Length, SocketFlags.None); 45 | 46 | if (nRecv == 0) 47 | { 48 | return null; 49 | } 50 | 51 | return Tuple.Create(nRecv,ReadBuffer); 52 | } 53 | catch (SocketException se) 54 | { 55 | LatestErrorMsg = se.Message; 56 | } 57 | 58 | return null; 59 | } 60 | 61 | //스트림에 쓰기 62 | public void Send(byte[] sendData) 63 | { 64 | try 65 | { 66 | if (Sock != null && Sock.Connected) //연결상태 유무 확인 67 | { 68 | Sock.Send(sendData, 0, sendData.Length, SocketFlags.None); 69 | } 70 | else 71 | { 72 | LatestErrorMsg = "먼저 채팅서버에 접속하세요!"; 73 | } 74 | } 75 | catch (SocketException se) 76 | { 77 | LatestErrorMsg = se.Message; 78 | } 79 | } 80 | 81 | //소켓과 스트림 닫기 82 | public void Close() 83 | { 84 | if (Sock != null && Sock.Connected) 85 | { 86 | //Sock.Shutdown(SocketShutdown.Both); 87 | Sock.Close(); 88 | } 89 | } 90 | 91 | public bool IsConnected() { return (Sock != null && Sock.Connected) ? true : false; } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /ChatClient/DevLog.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | using System.Runtime.CompilerServices; 8 | using System.Threading; 9 | 10 | namespace csharp_test_client 11 | { 12 | public class DevLog 13 | { 14 | static System.Collections.Concurrent.ConcurrentQueue logMsgQueue = new System.Collections.Concurrent.ConcurrentQueue(); 15 | 16 | static Int64 출력가능_로그레벨 = (Int64)LOG_LEVEL.TRACE; 17 | 18 | 19 | 20 | static public void Init(LOG_LEVEL logLevel) 21 | { 22 | ChangeLogLevel(logLevel); 23 | } 24 | 25 | static public void ChangeLogLevel(LOG_LEVEL logLevel) 26 | { 27 | Interlocked.Exchange(ref 출력가능_로그레벨, (int)logLevel); 28 | } 29 | 30 | public static LOG_LEVEL CurrentLogLevel() 31 | { 32 | var curLogLevel = (LOG_LEVEL)Interlocked.Read(ref 출력가능_로그레벨); 33 | return curLogLevel; 34 | } 35 | 36 | static public void Write(string msg, LOG_LEVEL logLevel = LOG_LEVEL.TRACE, 37 | [CallerFilePath] string fileName = "", 38 | [CallerMemberName] string methodName = "", 39 | [CallerLineNumber] int lineNumber = 0) 40 | { 41 | if (CurrentLogLevel() <= logLevel) 42 | { 43 | logMsgQueue.Enqueue(string.Format("{0}:{1}| {2}", DateTime.Now, methodName, msg)); 44 | } 45 | } 46 | 47 | static public bool GetLog(out string msg) 48 | { 49 | if (logMsgQueue.TryDequeue(out msg)) 50 | { 51 | return true; 52 | } 53 | 54 | return false; 55 | } 56 | 57 | } 58 | 59 | 60 | public enum LOG_LEVEL 61 | { 62 | TRACE, 63 | DEBUG, 64 | INFO, 65 | WARN, 66 | ERROR, 67 | DISABLE 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /ChatClient/PacketBufferManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace csharp_test_client 8 | { 9 | class PacketBufferManager 10 | { 11 | int BufferSize = 0; 12 | int ReadPos = 0; 13 | int WritePos = 0; 14 | 15 | int HeaderSize = 0; 16 | int MaxPacketSize = 0; 17 | byte[] PacketData; 18 | byte[] PacketDataTemp; 19 | 20 | public bool Init(int size, int headerSize, int maxPacketSize) 21 | { 22 | if (size < (maxPacketSize * 2) || size < 1 || headerSize < 1 || maxPacketSize < 1) 23 | { 24 | return false; 25 | } 26 | 27 | BufferSize = size; 28 | PacketData = new byte[size]; 29 | PacketDataTemp = new byte[size]; 30 | HeaderSize = headerSize; 31 | MaxPacketSize = maxPacketSize; 32 | 33 | return true; 34 | } 35 | 36 | public bool Write(byte[] data, int pos, int size) 37 | { 38 | if (data == null || (data.Length < (pos + size))) 39 | { 40 | return false; 41 | } 42 | 43 | var remainBufferSize = BufferSize - WritePos; 44 | 45 | if (remainBufferSize < size) 46 | { 47 | return false; 48 | } 49 | 50 | Buffer.BlockCopy(data, pos, PacketData, WritePos, size); 51 | WritePos += size; 52 | 53 | if (NextFree() == false) 54 | { 55 | BufferRelocate(); 56 | } 57 | return true; 58 | } 59 | 60 | public ArraySegment Read() 61 | { 62 | var enableReadSize = WritePos - ReadPos; 63 | 64 | if (enableReadSize < HeaderSize) 65 | { 66 | return new ArraySegment(); 67 | } 68 | 69 | var packetDataSize = BitConverter.ToInt16(PacketData, ReadPos); 70 | if (enableReadSize < packetDataSize) 71 | { 72 | return new ArraySegment(); 73 | } 74 | 75 | var completePacketData = new ArraySegment(PacketData, ReadPos, packetDataSize); 76 | ReadPos += packetDataSize; 77 | return completePacketData; 78 | } 79 | 80 | bool NextFree() 81 | { 82 | var enableWriteSize = BufferSize - WritePos; 83 | 84 | if (enableWriteSize < MaxPacketSize) 85 | { 86 | return false; 87 | } 88 | 89 | return true; 90 | } 91 | 92 | void BufferRelocate() 93 | { 94 | var enableReadSize = WritePos - ReadPos; 95 | 96 | Buffer.BlockCopy(PacketData, ReadPos, PacketDataTemp, 0, enableReadSize); 97 | Buffer.BlockCopy(PacketDataTemp, 0, PacketData, 0, enableReadSize); 98 | 99 | ReadPos = 0; 100 | WritePos = enableReadSize; 101 | } 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /ChatClient/PacketDefine.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace csharp_test_client 8 | { 9 | class PacketDef 10 | { 11 | public const Int16 PACKET_HEADER_SIZE = 5; 12 | public const int MAX_USER_ID_BYTE_LENGTH = 33; 13 | public const int MAX_USER_PW_BYTE_LENGTH = 33; 14 | public const int MAX_CHAT_MSG_SIZE = 257; 15 | } 16 | 17 | public enum PACKET_ID : ushort 18 | { 19 | DEV_ECHO = 1, 20 | 21 | // 로그인 22 | LOGIN_REQ = 201, 23 | LOGIN_RES = 202, 24 | 25 | ROOM_ENTER_REQ = 206, 26 | ROOM_ENTER_RES = 207, 27 | ROOM_NEW_USER_NTF = 208, 28 | ROOM_USER_LIST_NTF = 209, 29 | 30 | ROOM_LEAVE_REQ = 215, 31 | ROOM_LEAVE_RES = 216, 32 | ROOM_LEAVE_USER_NTF = 217, 33 | 34 | ROOM_CHAT_REQ = 221, 35 | ROOM_CHAT_RES = 222, 36 | ROOM_CHAT_NOTIFY = 223, 37 | } 38 | 39 | 40 | public enum ERROR_CODE : Int16 41 | { 42 | ERROR_NONE = 0, 43 | 44 | 45 | 46 | ERROR_CODE_USER_MGR_INVALID_USER_UNIQUEID = 112, 47 | 48 | ERROR_CODE_PUBLIC_CHANNEL_IN_USER = 114, 49 | 50 | ERROR_CODE_PUBLIC_CHANNEL_INVALIDE_NUMBER = 115, 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /ChatClient/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Runtime.Versioning; 5 | using System.Threading.Tasks; 6 | using System.Windows.Forms; 7 | 8 | namespace csharp_test_client; 9 | 10 | [SupportedOSPlatform("windows10.0.177630")] 11 | static class Program 12 | { 13 | /// 14 | /// 해당 응용 프로그램의 주 진입점입니다. 15 | /// 16 | [STAThread] 17 | static void Main() 18 | { 19 | Application.EnableVisualStyles(); 20 | Application.SetCompatibleTextRenderingDefault(false); 21 | Application.Run(new mainForm()); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ChatClient/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // 이 코드는 도구를 사용하여 생성되었습니다. 4 | // 런타임 버전:4.0.30319.42000 5 | // 6 | // 파일 내용을 변경하면 잘못된 동작이 발생할 수 있으며, 코드를 다시 생성하면 7 | // 이러한 변경 내용이 손실됩니다. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace csharp_test_client.Properties 12 | { 13 | 14 | 15 | /// 16 | /// 지역화된 문자열 등을 찾기 위한 강력한 형식의 리소스 클래스입니다. 17 | /// 18 | // 이 클래스는 ResGen 또는 Visual Studio와 같은 도구를 통해 StronglyTypedResourceBuilder 19 | // 클래스에서 자동으로 생성되었습니다. 20 | // 멤버를 추가하거나 제거하려면 .ResX 파일을 편집한 다음 /str 옵션을 사용하여 21 | // ResGen을 다시 실행하거나 VS 프로젝트를 다시 빌드하십시오. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources 26 | { 27 | 28 | private static global::System.Resources.ResourceManager resourceMan; 29 | 30 | private static global::System.Globalization.CultureInfo resourceCulture; 31 | 32 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 33 | internal Resources() 34 | { 35 | } 36 | 37 | /// 38 | /// 이 클래스에서 사용하는 캐시된 ResourceManager 인스턴스를 반환합니다. 39 | /// 40 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 41 | internal static global::System.Resources.ResourceManager ResourceManager 42 | { 43 | get 44 | { 45 | if ((resourceMan == null)) 46 | { 47 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("csharp_test_client.Properties.Resources", typeof(Resources).Assembly); 48 | resourceMan = temp; 49 | } 50 | return resourceMan; 51 | } 52 | } 53 | 54 | /// 55 | /// 이 강력한 형식의 리소스 클래스를 사용하여 모든 리소스 조회에 대해 56 | /// 현재 스레드의 CurrentUICulture 속성을 재정의합니다. 57 | /// 58 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 59 | internal static global::System.Globalization.CultureInfo Culture 60 | { 61 | get 62 | { 63 | return resourceCulture; 64 | } 65 | set 66 | { 67 | resourceCulture = value; 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /ChatClient/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace csharp_test_client.Properties 12 | { 13 | 14 | 15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] 17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase 18 | { 19 | 20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 21 | 22 | public static Settings Default 23 | { 24 | get 25 | { 26 | return defaultInstance; 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /ChatClient/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ChatClient/csharp_test_client.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | net8.0-windows 4 | WinExe 5 | false 6 | true 7 | true 8 | 9 | 10 | ..\bin\ 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /ChatClient/csharp_test_client.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "csharp_test_client", "csharp_test_client.csproj", "{9E4B5E72-4E76-4E22-90B0-E53275A99018}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {9E4B5E72-4E76-4E22-90B0-E53275A99018}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {9E4B5E72-4E76-4E22-90B0-E53275A99018}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {9E4B5E72-4E76-4E22-90B0-E53275A99018}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {9E4B5E72-4E76-4E22-90B0-E53275A99018}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Choi HeungBae 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 단계 별로 IOCP 실습 2 | - 코드에 버그가 있을 수 있다.(버그를 잡는 것도 공부!) 3 | - Modern C++을 적극적으로 사용하는 것을 추천한다. 4 | - 'Tutorial/ChatServerWithLogger' 있는 프로젝트는 채팅 서버에 plog 라이브러리를 사용하고 있으며, Windows Event Log에 로그 데이터를 기록할 수 있다. 5 | - Visual Studio 2022를 사용한다(하위 버전으로 변경해도 코드 변경은 없다) 6 | - [YOUTUBE](https://www.youtube.com/watch?v=RMRsvll7hrM&list=PLW_xyUw4fSdbYjgwC-JCCFWznhayrZv77 ) 7 | - [학습 가이드](./iocp_learning_guide.md) 8 | 9 |
10 | 11 | 12 | ## 실습 단계 13 | 실습을 하기 전에 꼭 IOCP에 대해 학습을 한다. 14 | IOCP는 오래된 기술로 서적에서 다루기도 했고, 특히 네이버에서 검색해도 많은 자료를 찾을 수 있다(네이버 검색하면 한글 자료) 15 | - 1 단계. 가장 간단한 IOCP 서버. Echo 서버 코드 만들기 16 | - IOCP API 동작에 대해서 이해할 수 있다. 17 | - 2 단계. OverlappedEx 구조체에 있는 `char m_szBuf[ MAX_SOCKBUF ]`를 stClientInfo 구조체로 이동 및 코드 분리하기 18 | - 앞 단계에는 OverlappedEx 구조체에 `m_szBuf`가 있어서 불 필요한 메모리 낭비가 발생함 19 | - 3 단계. 애플리케이션과 네트워크 코드 분리하기 20 | - IOCP를 네트워크 라이브러리화 하기 위해 네트워크와 서버 로직 코드를 분리한다. 21 | - 연결, 끊어짐, 데이터 받음을 애플리케이션에 전달하기 22 | - 4 단계. 네트워크와 로직(패킷 or 요청) 처리 각각의 스레드로 분리하기 23 | - Send를 Recv와 다른 스레드에서 하기 24 | - send를 연속으로 보낼 수 있는 구조가 되어야 한다. 25 | - 5 단계. 1-Send 구현하기 26 | - 버퍼에 쌓아 놓고, send 스레드에서 보내기. 27 | - 6 단계. 1-Send 구현하기 28 | - queue에 담아 놓고 순차적으로 보내기. 29 | - 7 단계. 비동기 Accept 사용하기 30 | - 6단계까지는 Accept 처리를 동기 I/O로 했다. 이것을 비동기I/O로 바꾼다. 이로써 네트워크 동작이 모두 비동기 I/O가 된다 31 | - 6단계에서 이어서 기능을 구현한다. 32 | - 8 단계. 채팅 서버 만들기 (ChatServer_01) 33 | - 패킷 구조 사용하기, 로그인 34 | - 9 단계. 로그인 때 Redis 사용하기 (ChatServer_02) 35 | - C++에서 Redis를 사용하는 방법은 [examples_cpp_redis](https://github.com/jacking75/examples_cpp_redis )를 참고한다. 36 | - 10 단계. 방 입장, 방 나가기, 방 채팅 구현하기 (ChatServer_03) 37 | 38 | ### 더 진행 한다면... 39 | - 11 단계. 최적화 하기 40 | - GetQueuedCompletionStatusEx 버전 사용하기 41 | - 서버에서 사용하는 설정을 입력 받기 42 | - 동적 할당을 최소화 하기 43 | - 링버퍼 구현 추가(덮어 쓰기 방지) 44 | - Lock 사용 범위를 줄이거나 좀 더 가벼운 Lock 사용하기 45 | - 더미 클라이언트로 테스트 하기 46 | - 12 단계. Network, Content, Host 각 레이어로 프로젝트 나누기 47 | - Network, Content는 각각 정적 라이브러리로 만든다. 48 | - Host는 콘솔 프로젝트. Network, Content 라이브러리를 사용한다. 49 | 50 | 51 | 52 | ## 참고 글 모음 53 | - [IOCP 기본 구조 이해](https://www.slideshare.net/namhyeonuk90/iocp ) 54 | - [IOCP에 대하여](https://www.joinc.co.kr/w/Site/win_network_prog/doc/iocp ) 55 | - [IOCP (I/O CompletionPort)](https://chfhrqnfrhc.tistory.com/entry/IOCP ) 56 | - [IOCP 정리](https://hmjo.tistory.com/159 ) 57 | - [IOCP](https://blog.naver.com/zzangrho/80150515226 ) 58 | - [IOCP 모델](https://blog.naver.com/handodos/140138259592 ) 59 | - [IOCP 모델 - 구조의 이해](https://zxwnstn.blog.me/221513630216 ) 60 | - [서버 모델 - 윈도우 IOCP](https://dev-ahn.tistory.com/114 ) 61 | - [IOCP 내용 정리](https://blog.naver.com/dkdldhekznal/221233789231 ) 62 | - [게임 서버를 제작하기 위한 IOCP 네트워크 클래스 만들기 Ver1](https://blog.naver.com/dkdldhekznal/221235469866 ) 63 | - [게임 서버를 제작하기 위한 IOCP 네트워크 클래스 만들기 Ver2](https://blog.naver.com/dkdldhekznal/221242411793 ) 64 | 65 | -------------------------------------------------------------------------------- /Tutorial/01/IOCP_01.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.4.33103.184 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "IOCP_01", "IOCP_01.vcxproj", "{5975048C-30EF-4D61-A112-6508B13FEB78}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Win64 = Debug|Win64 11 | Release|Win64 = Release|Win64 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {5975048C-30EF-4D61-A112-6508B13FEB78}.Debug|Win64.ActiveCfg = Debug Win64|x64 15 | {5975048C-30EF-4D61-A112-6508B13FEB78}.Debug|Win64.Build.0 = Debug Win64|x64 16 | {5975048C-30EF-4D61-A112-6508B13FEB78}.Release|Win64.ActiveCfg = Release Win64|x64 17 | {5975048C-30EF-4D61-A112-6508B13FEB78}.Release|Win64.Build.0 = Release Win64|x64 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {078B383E-1816-470F-AE48-F478698D22C8} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /Tutorial/01/IOCompletionPort.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/01/IOCompletionPort.h -------------------------------------------------------------------------------- /Tutorial/01/main.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/01/main.cpp -------------------------------------------------------------------------------- /Tutorial/02/Define.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/02/Define.h -------------------------------------------------------------------------------- /Tutorial/02/IOCP_02.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 16 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "IOCP_02", "IOCP_02.vcxproj", "{B05C4CB4-1C3C-CB4F-2554-562691B231B1}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Win64 = Debug|Win64 9 | Release|Win64 = Release|Win64 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {B05C4CB4-1C3C-CB4F-2554-562691B231B1}.Debug|Win64.ActiveCfg = Debug Win64|x64 13 | {B05C4CB4-1C3C-CB4F-2554-562691B231B1}.Debug|Win64.Build.0 = Debug Win64|x64 14 | {B05C4CB4-1C3C-CB4F-2554-562691B231B1}.Release|Win64.ActiveCfg = Release Win64|x64 15 | {B05C4CB4-1C3C-CB4F-2554-562691B231B1}.Release|Win64.Build.0 = Release Win64|x64 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /Tutorial/02/IOCompletionPort.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/02/IOCompletionPort.h -------------------------------------------------------------------------------- /Tutorial/02/main.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/02/main.cpp -------------------------------------------------------------------------------- /Tutorial/03/Define.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/03/Define.h -------------------------------------------------------------------------------- /Tutorial/03/EchoServer.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/03/EchoServer.h -------------------------------------------------------------------------------- /Tutorial/03/IOCPServer.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/03/IOCPServer.h -------------------------------------------------------------------------------- /Tutorial/03/IOCP_03.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 16 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "IOCP_03", "IOCP_03.vcxproj", "{B25C4CB4-1E3C-CB4F-2754-562693B231B1}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Win64 = Debug|Win64 9 | Release|Win64 = Release|Win64 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {B25C4CB4-1E3C-CB4F-2754-562693B231B1}.Debug|Win64.ActiveCfg = Debug Win64|x64 13 | {B25C4CB4-1E3C-CB4F-2754-562693B231B1}.Debug|Win64.Build.0 = Debug Win64|x64 14 | {B25C4CB4-1E3C-CB4F-2754-562693B231B1}.Release|Win64.ActiveCfg = Release Win64|x64 15 | {B25C4CB4-1E3C-CB4F-2754-562693B231B1}.Release|Win64.Build.0 = Release Win64|x64 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /Tutorial/03/IOCP_03.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | ServerNetwork 9 | 10 | 11 | ServerNetwork 12 | 13 | 14 | 15 | 16 | 17 | {1fc0f584-76ea-4096-9ebc-805fceb35389} 18 | 19 | 20 | -------------------------------------------------------------------------------- /Tutorial/03/main.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/03/main.cpp -------------------------------------------------------------------------------- /Tutorial/04/ClientInfo.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/04/ClientInfo.h -------------------------------------------------------------------------------- /Tutorial/04/Define.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/04/Define.h -------------------------------------------------------------------------------- /Tutorial/04/EchoServer.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/04/EchoServer.h -------------------------------------------------------------------------------- /Tutorial/04/IOCPServer.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/04/IOCPServer.h -------------------------------------------------------------------------------- /Tutorial/04/IOCP_04.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.4.33103.184 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "IOCP_04", "IOCP_04.vcxproj", "{65A564D8-C247-4280-A894-0F8EFCA86B9B}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Win64 = Debug|Win64 11 | Release|Win64 = Release|Win64 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {65A564D8-C247-4280-A894-0F8EFCA86B9B}.Debug|Win64.ActiveCfg = Debug Win64|x64 15 | {65A564D8-C247-4280-A894-0F8EFCA86B9B}.Debug|Win64.Build.0 = Debug Win64|x64 16 | {65A564D8-C247-4280-A894-0F8EFCA86B9B}.Release|Win64.ActiveCfg = Release Win64|x64 17 | {65A564D8-C247-4280-A894-0F8EFCA86B9B}.Release|Win64.Build.0 = Release Win64|x64 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {4C7F5233-D82A-4BBE-A6FB-3500E11016AD} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /Tutorial/04/IOCP_04.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | ServerNetwork 9 | 10 | 11 | ServerNetwork 12 | 13 | 14 | 15 | 16 | ServerNetwork 17 | 18 | 19 | 20 | 21 | {1fc0f584-76ea-4096-9ebc-805fceb35389} 22 | 23 | 24 | -------------------------------------------------------------------------------- /Tutorial/04/Packet.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/04/Packet.h -------------------------------------------------------------------------------- /Tutorial/04/main.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/04/main.cpp -------------------------------------------------------------------------------- /Tutorial/05/ClientInfo.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/05/ClientInfo.h -------------------------------------------------------------------------------- /Tutorial/05/Define.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/05/Define.h -------------------------------------------------------------------------------- /Tutorial/05/EchoServer.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/05/EchoServer.h -------------------------------------------------------------------------------- /Tutorial/05/IOCPServer.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/05/IOCPServer.h -------------------------------------------------------------------------------- /Tutorial/05/IOCP_05.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.4.33103.184 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "IOCP_05", "IOCP_05.vcxproj", "{8B046929-2A17-4BA6-B062-315006B7C2CD}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Win64 = Debug|Win64 11 | Release|Win64 = Release|Win64 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {8B046929-2A17-4BA6-B062-315006B7C2CD}.Debug|Win64.ActiveCfg = Debug Win64|x64 15 | {8B046929-2A17-4BA6-B062-315006B7C2CD}.Debug|Win64.Build.0 = Debug Win64|x64 16 | {8B046929-2A17-4BA6-B062-315006B7C2CD}.Release|Win64.ActiveCfg = Release Win64|x64 17 | {8B046929-2A17-4BA6-B062-315006B7C2CD}.Release|Win64.Build.0 = Release Win64|x64 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {9EEDA435-A83C-4836-82F2-BE698882AE26} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /Tutorial/05/IOCP_05.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | ServerNetwork 9 | 10 | 11 | ServerNetwork 12 | 13 | 14 | 15 | 16 | ServerNetwork 17 | 18 | 19 | 20 | 21 | {1fc0f584-76ea-4096-9ebc-805fceb35389} 22 | 23 | 24 | -------------------------------------------------------------------------------- /Tutorial/05/Packet.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define WIN32_LEAN_AND_MEAN 4 | #include 5 | 6 | struct PacketData 7 | { 8 | UINT32 SessionIndex = 0; 9 | UINT32 DataSize = 0; 10 | char* pPacketData = nullptr; 11 | 12 | void Set(PacketData& vlaue) 13 | { 14 | SessionIndex = vlaue.SessionIndex; 15 | DataSize = vlaue.DataSize; 16 | 17 | pPacketData = new char[vlaue.DataSize]; 18 | CopyMemory(pPacketData, vlaue.pPacketData, vlaue.DataSize); 19 | } 20 | 21 | void Set(UINT32 sessionIndex_, UINT32 dataSize_, char* pData) 22 | { 23 | SessionIndex = sessionIndex_; 24 | DataSize = dataSize_; 25 | 26 | pPacketData = new char[dataSize_]; 27 | CopyMemory(pPacketData, pData, dataSize_); 28 | } 29 | 30 | void Release() 31 | { 32 | delete pPacketData; 33 | } 34 | }; -------------------------------------------------------------------------------- /Tutorial/05/main.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/05/main.cpp -------------------------------------------------------------------------------- /Tutorial/06/Define.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/06/Define.h -------------------------------------------------------------------------------- /Tutorial/06/EchoServer.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/06/EchoServer.h -------------------------------------------------------------------------------- /Tutorial/06/IOCPServer.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/06/IOCPServer.h -------------------------------------------------------------------------------- /Tutorial/06/IOCP_06.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.4.33103.184 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "IOCP_06", "IOCP_06.vcxproj", "{CB30F320-4B4B-4065-89A1-3516A2A4E36A}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Win64 = Debug|Win64 11 | Release|Win64 = Release|Win64 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {CB30F320-4B4B-4065-89A1-3516A2A4E36A}.Debug|Win64.ActiveCfg = Debug Win64|x64 15 | {CB30F320-4B4B-4065-89A1-3516A2A4E36A}.Debug|Win64.Build.0 = Debug Win64|x64 16 | {CB30F320-4B4B-4065-89A1-3516A2A4E36A}.Release|Win64.ActiveCfg = Release Win64|x64 17 | {CB30F320-4B4B-4065-89A1-3516A2A4E36A}.Release|Win64.Build.0 = Release Win64|x64 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {5E11D69A-A97E-49A0-AE55-DB25418E7C25} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /Tutorial/06/IOCP_06.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | ServerNetwork 9 | 10 | 11 | ServerNetwork 12 | 13 | 14 | 15 | 16 | ServerNetwork 17 | 18 | 19 | 20 | 21 | {1fc0f584-76ea-4096-9ebc-805fceb35389} 22 | 23 | 24 | -------------------------------------------------------------------------------- /Tutorial/06/Packet.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define WIN32_LEAN_AND_MEAN 4 | #include 5 | 6 | struct PacketData 7 | { 8 | UINT32 SessionIndex = 0; 9 | UINT32 DataSize = 0; 10 | char* pPacketData = nullptr; 11 | 12 | void Set(PacketData& vlaue) 13 | { 14 | SessionIndex = vlaue.SessionIndex; 15 | DataSize = vlaue.DataSize; 16 | 17 | pPacketData = new char[vlaue.DataSize]; 18 | CopyMemory(pPacketData, vlaue.pPacketData, vlaue.DataSize); 19 | } 20 | 21 | void Set(UINT32 sessionIndex_, UINT32 dataSize_, char* pData) 22 | { 23 | SessionIndex = sessionIndex_; 24 | DataSize = dataSize_; 25 | 26 | pPacketData = new char[dataSize_]; 27 | CopyMemory(pPacketData, pData, dataSize_); 28 | } 29 | 30 | void Release() 31 | { 32 | delete pPacketData; 33 | } 34 | }; -------------------------------------------------------------------------------- /Tutorial/06/main.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/06/main.cpp -------------------------------------------------------------------------------- /Tutorial/07/ClientInfo.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/07/ClientInfo.h -------------------------------------------------------------------------------- /Tutorial/07/Define.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/07/Define.h -------------------------------------------------------------------------------- /Tutorial/07/EchoServer.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/07/EchoServer.h -------------------------------------------------------------------------------- /Tutorial/07/IOCPServer.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/07/IOCPServer.h -------------------------------------------------------------------------------- /Tutorial/07/IOCP_07.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.4.33103.184 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "IOCP_07", "IOCP_07.vcxproj", "{3AABBED2-FCBF-4690-82C6-288C21E70052}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Win64 = Debug|Win64 11 | Release|Win64 = Release|Win64 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {3AABBED2-FCBF-4690-82C6-288C21E70052}.Debug|Win64.ActiveCfg = Debug Win64|x64 15 | {3AABBED2-FCBF-4690-82C6-288C21E70052}.Debug|Win64.Build.0 = Debug Win64|x64 16 | {3AABBED2-FCBF-4690-82C6-288C21E70052}.Release|Win64.ActiveCfg = Release Win64|x64 17 | {3AABBED2-FCBF-4690-82C6-288C21E70052}.Release|Win64.Build.0 = Release Win64|x64 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {D5D4BF4A-926C-4A9E-9235-C4990B96DC98} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /Tutorial/07/IOCP_07.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | ServerNetwork 9 | 10 | 11 | ServerNetwork 12 | 13 | 14 | 15 | 16 | ServerNetwork 17 | 18 | 19 | 20 | 21 | {1fc0f584-76ea-4096-9ebc-805fceb35389} 22 | 23 | 24 | -------------------------------------------------------------------------------- /Tutorial/07/Packet.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define WIN32_LEAN_AND_MEAN 4 | #include 5 | 6 | struct PacketData 7 | { 8 | UINT32 SessionIndex = 0; 9 | UINT32 DataSize = 0; 10 | char* pPacketData = nullptr; 11 | 12 | void Set(PacketData& vlaue) 13 | { 14 | SessionIndex = vlaue.SessionIndex; 15 | DataSize = vlaue.DataSize; 16 | 17 | pPacketData = new char[vlaue.DataSize]; 18 | CopyMemory(pPacketData, vlaue.pPacketData, vlaue.DataSize); 19 | } 20 | 21 | void Set(UINT32 sessionIndex_, UINT32 dataSize_, char* pData) 22 | { 23 | SessionIndex = sessionIndex_; 24 | DataSize = dataSize_; 25 | 26 | pPacketData = new char[dataSize_]; 27 | CopyMemory(pPacketData, pData, dataSize_); 28 | } 29 | 30 | void Release() 31 | { 32 | delete pPacketData; 33 | } 34 | }; -------------------------------------------------------------------------------- /Tutorial/07/main.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/07/main.cpp -------------------------------------------------------------------------------- /Tutorial/08/ChatServer.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/08/ChatServer.h -------------------------------------------------------------------------------- /Tutorial/08/ChatServer_01.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 16 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ChatServer_01", "ChatServer_01.vcxproj", "{B25C4CB4-1E3C-CB4F-2754-562693B231B1}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Win64 = Debug|Win64 9 | Release|Win64 = Release|Win64 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {B25C4CB4-1E3C-CB4F-2754-562693B231B1}.Debug|Win64.ActiveCfg = Debug Win64|x64 13 | {B25C4CB4-1E3C-CB4F-2754-562693B231B1}.Debug|Win64.Build.0 = Debug Win64|x64 14 | {B25C4CB4-1E3C-CB4F-2754-562693B231B1}.Release|Win64.ActiveCfg = Release Win64|x64 15 | {B25C4CB4-1E3C-CB4F-2754-562693B231B1}.Release|Win64.Build.0 = Release Win64|x64 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /Tutorial/08/ChatServer_01.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | ServerNetwork 16 | 17 | 18 | ServerNetwork 19 | 20 | 21 | ServerNetwork 22 | 23 | 24 | 25 | 26 | {1fc0f584-76ea-4096-9ebc-805fceb35389} 27 | 28 | 29 | -------------------------------------------------------------------------------- /Tutorial/08/ErrorCode.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/08/ErrorCode.h -------------------------------------------------------------------------------- /Tutorial/08/Packet.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/08/Packet.h -------------------------------------------------------------------------------- /Tutorial/08/PacketManager.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/08/PacketManager.cpp -------------------------------------------------------------------------------- /Tutorial/08/PacketManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Packet.h" 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | 12 | class UserManager; 13 | class RoomManager; 14 | class RedisManager; 15 | 16 | class PacketManager { 17 | public: 18 | PacketManager() = default; 19 | ~PacketManager() = default; 20 | 21 | void Init(const UINT32 maxClient_); 22 | 23 | bool Run(); 24 | 25 | void End(); 26 | 27 | void ReceivePacketData(const UINT32 clientIndex_, const UINT32 size_, char* pData_); 28 | 29 | void PushSystemPacket(PacketInfo packet_); 30 | 31 | std::function SendPacketFunc; 32 | 33 | 34 | private: 35 | void CreateCompent(const UINT32 maxClient_); 36 | 37 | void ClearConnectionInfo(INT32 clientIndex_); 38 | 39 | void EnqueuePacketData(const UINT32 clientIndex_); 40 | PacketInfo DequePacketData(); 41 | 42 | PacketInfo DequeSystemPacketData(); 43 | 44 | 45 | void ProcessPacket(); 46 | 47 | void ProcessRecvPacket(const UINT32 clientIndex_, const UINT16 packetId_, const UINT16 packetSize_, char* pPacket_); 48 | 49 | void ProcessUserConnect(UINT32 clientIndex_, UINT16 packetSize_, char* pPacket_); 50 | void ProcessUserDisConnect(UINT32 clientIndex_, UINT16 packetSize_, char* pPacket_); 51 | 52 | void ProcessLogin(UINT32 clientIndex_, UINT16 packetSize_, char* pPacket_); 53 | 54 | 55 | 56 | 57 | typedef void(PacketManager::* PROCESS_RECV_PACKET_FUNCTION)(UINT32, UINT16, char*); 58 | std::unordered_map mRecvFuntionDictionary; 59 | 60 | UserManager* mUserManager; 61 | 62 | std::function mSendMQDataFunc; 63 | 64 | 65 | bool mIsRunProcessThread = false; 66 | 67 | std::thread mProcessThread; 68 | 69 | std::mutex mLock; 70 | 71 | std::deque mInComingPacketUserIndex; 72 | 73 | std::deque mSystemPacketQueue; 74 | }; 75 | 76 | -------------------------------------------------------------------------------- /Tutorial/08/ServerNetwork/ClientInfo.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/08/ServerNetwork/ClientInfo.h -------------------------------------------------------------------------------- /Tutorial/08/ServerNetwork/Define.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/08/ServerNetwork/Define.h -------------------------------------------------------------------------------- /Tutorial/08/ServerNetwork/IOCPServer.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/08/ServerNetwork/IOCPServer.h -------------------------------------------------------------------------------- /Tutorial/08/User.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include "Packet.h" 5 | 6 | class User 7 | { 8 | const UINT32 PACKET_DATA_BUFFER_SIZE = 8096; 9 | 10 | public: 11 | enum class DOMAIN_STATE 12 | { 13 | NONE = 0, 14 | LOGIN = 1, 15 | ROOM = 2 16 | }; 17 | 18 | 19 | User() = default; 20 | ~User() = default; 21 | 22 | void Init(const INT32 index) 23 | { 24 | mIndex = index; 25 | mPakcetDataBuffer = new char[PACKET_DATA_BUFFER_SIZE]; 26 | } 27 | 28 | void Clear() 29 | { 30 | mRoomIndex = -1; 31 | mUserID = ""; 32 | mIsConfirm = false; 33 | mCurDomainState = DOMAIN_STATE::NONE; 34 | 35 | mPakcetDataBufferWPos = 0; 36 | mPakcetDataBufferRPos = 0; 37 | } 38 | 39 | int SetLogin(char* userID_) 40 | { 41 | mCurDomainState = DOMAIN_STATE::LOGIN; 42 | mUserID = userID_; 43 | 44 | return 0; 45 | } 46 | 47 | void EnterRoom(INT32 roomIndex_) 48 | { 49 | mRoomIndex = roomIndex_; 50 | mCurDomainState = DOMAIN_STATE::ROOM; 51 | } 52 | 53 | void SetDomainState(DOMAIN_STATE value_) { mCurDomainState = value_; } 54 | 55 | INT32 GetCurrentRoom() 56 | { 57 | return mRoomIndex; 58 | } 59 | 60 | INT32 GetNetConnIdx() 61 | { 62 | return mIndex; 63 | } 64 | 65 | std::string GetUserId() const 66 | { 67 | return mUserID; 68 | } 69 | 70 | DOMAIN_STATE GetDomainState() 71 | { 72 | return mCurDomainState; 73 | } 74 | 75 | void SetPacketData(const UINT32 dataSize_, char* pData_) 76 | { 77 | if ((mPakcetDataBufferWPos + dataSize_) >= PACKET_DATA_BUFFER_SIZE) 78 | { 79 | auto remainDataSize = mPakcetDataBufferWPos - mPakcetDataBufferRPos; 80 | 81 | if (remainDataSize > 0) 82 | { 83 | CopyMemory(&mPakcetDataBuffer[0], &mPakcetDataBuffer[mPakcetDataBufferRPos], remainDataSize); 84 | mPakcetDataBufferWPos = remainDataSize; 85 | } 86 | else 87 | { 88 | mPakcetDataBufferWPos = 0; 89 | } 90 | 91 | mPakcetDataBufferRPos = 0; 92 | } 93 | 94 | CopyMemory(&mPakcetDataBuffer[mPakcetDataBufferWPos], pData_, dataSize_); 95 | mPakcetDataBufferWPos += dataSize_; 96 | } 97 | 98 | PacketInfo GetPacket() 99 | { 100 | const int PACKET_SIZE_LENGTH = 2; 101 | const int PACKET_TYPE_LENGTH = 2; 102 | short packetSize = 0; 103 | 104 | UINT32 remainByte = mPakcetDataBufferWPos - mPakcetDataBufferRPos; 105 | 106 | if(remainByte < PACKET_HEADER_LENGTH) 107 | { 108 | return PacketInfo(); 109 | } 110 | 111 | auto pHeader = (PACKET_HEADER*)&mPakcetDataBuffer[mPakcetDataBufferRPos]; 112 | 113 | if (pHeader->PacketLength > remainByte) 114 | { 115 | return PacketInfo(); 116 | } 117 | 118 | PacketInfo packetInfo; 119 | packetInfo.PacketId = pHeader->PacketId; 120 | packetInfo.DataSize = pHeader->PacketLength; 121 | packetInfo.pDataPtr = &mPakcetDataBuffer[mPakcetDataBufferRPos]; 122 | 123 | mPakcetDataBufferRPos += pHeader->PacketLength; 124 | 125 | return packetInfo; 126 | } 127 | 128 | 129 | private: 130 | INT32 mIndex = -1; 131 | 132 | INT32 mRoomIndex = -1; 133 | 134 | std::string mUserID; 135 | bool mIsConfirm = false; 136 | std::string mAuthToken; 137 | 138 | DOMAIN_STATE mCurDomainState = DOMAIN_STATE::NONE; 139 | 140 | UINT32 mPakcetDataBufferWPos = 0; 141 | UINT32 mPakcetDataBufferRPos = 0; 142 | char* mPakcetDataBuffer = nullptr; 143 | }; 144 | 145 | -------------------------------------------------------------------------------- /Tutorial/08/UserManager.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/08/UserManager.h -------------------------------------------------------------------------------- /Tutorial/08/main.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/08/main.cpp -------------------------------------------------------------------------------- /Tutorial/09/ChatServer.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/09/ChatServer.h -------------------------------------------------------------------------------- /Tutorial/09/ChatServer_02.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.4.33103.184 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ChatServer_02", "ChatServer_02.vcxproj", "{3D6EB567-1785-4427-997C-61A937B60709}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Win64 = Debug|Win64 11 | Release|Win64 = Release|Win64 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {3D6EB567-1785-4427-997C-61A937B60709}.Debug|Win64.ActiveCfg = Debug Win64|x64 15 | {3D6EB567-1785-4427-997C-61A937B60709}.Debug|Win64.Build.0 = Debug Win64|x64 16 | {3D6EB567-1785-4427-997C-61A937B60709}.Release|Win64.ActiveCfg = Release Win64|x64 17 | {3D6EB567-1785-4427-997C-61A937B60709}.Release|Win64.Build.0 = Release Win64|x64 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {77285403-16BF-47CC-96B6-5415C277FA22} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /Tutorial/09/ChatServer_02.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | ServerNetwork 16 | 17 | 18 | ServerNetwork 19 | 20 | 21 | ServerNetwork 22 | 23 | 24 | 25 | 26 | 27 | 28 | {1fc0f584-76ea-4096-9ebc-805fceb35389} 29 | 30 | 31 | -------------------------------------------------------------------------------- /Tutorial/09/ErrorCode.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/09/ErrorCode.h -------------------------------------------------------------------------------- /Tutorial/09/Packet.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/09/Packet.h -------------------------------------------------------------------------------- /Tutorial/09/PacketManager.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/09/PacketManager.cpp -------------------------------------------------------------------------------- /Tutorial/09/PacketManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Packet.h" 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | 12 | class UserManager; 13 | class RoomManager; 14 | class RedisManager; 15 | 16 | class PacketManager { 17 | public: 18 | PacketManager() = default; 19 | ~PacketManager() = default; 20 | 21 | void Init(const UINT32 maxClient_); 22 | 23 | bool Run(); 24 | 25 | void End(); 26 | 27 | void ReceivePacketData(const UINT32 clientIndex_, const UINT32 size_, char* pData_); 28 | 29 | void PushSystemPacket(PacketInfo packet_); 30 | 31 | std::function SendPacketFunc; 32 | 33 | 34 | private: 35 | void CreateCompent(const UINT32 maxClient_); 36 | 37 | void ClearConnectionInfo(INT32 clientIndex_); 38 | 39 | void EnqueuePacketData(const UINT32 clientIndex_); 40 | PacketInfo DequePacketData(); 41 | 42 | PacketInfo DequeSystemPacketData(); 43 | 44 | 45 | void ProcessPacket(); 46 | 47 | void ProcessRecvPacket(const UINT32 clientIndex_, const UINT16 packetId_, const UINT16 packetSize_, char* pPacket_); 48 | 49 | void ProcessUserConnect(UINT32 clientIndex_, UINT16 packetSize_, char* pPacket_); 50 | void ProcessUserDisConnect(UINT32 clientIndex_, UINT16 packetSize_, char* pPacket_); 51 | 52 | void ProcessLogin(UINT32 clientIndex_, UINT16 packetSize_, char* pPacket_); 53 | void ProcessLoginDBResult(UINT32 clientIndex_, UINT16 packetSize_, char* pPacket_); 54 | 55 | 56 | 57 | typedef void(PacketManager::* PROCESS_RECV_PACKET_FUNCTION)(UINT32, UINT16, char*); 58 | std::unordered_map mRecvFuntionDictionary; 59 | 60 | UserManager* mUserManager; 61 | RedisManager* mRedisMgr; 62 | 63 | std::function mSendMQDataFunc; 64 | 65 | 66 | bool mIsRunProcessThread = false; 67 | 68 | std::thread mProcessThread; 69 | 70 | std::mutex mLock; 71 | 72 | std::deque mInComingPacketUserIndex; 73 | 74 | std::deque mSystemPacketQueue; 75 | }; 76 | 77 | -------------------------------------------------------------------------------- /Tutorial/09/RedisManager.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/09/RedisManager.h -------------------------------------------------------------------------------- /Tutorial/09/RedisTaskDefine.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/09/RedisTaskDefine.h -------------------------------------------------------------------------------- /Tutorial/09/ServerNetwork/ClientInfo.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/09/ServerNetwork/ClientInfo.h -------------------------------------------------------------------------------- /Tutorial/09/ServerNetwork/Define.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/09/ServerNetwork/Define.h -------------------------------------------------------------------------------- /Tutorial/09/ServerNetwork/IOCPServer.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/09/ServerNetwork/IOCPServer.h -------------------------------------------------------------------------------- /Tutorial/09/User.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include "Packet.h" 5 | 6 | class User 7 | { 8 | const UINT32 PACKET_DATA_BUFFER_SIZE = 8096; 9 | 10 | public: 11 | enum class DOMAIN_STATE 12 | { 13 | NONE = 0, 14 | LOGIN = 1, 15 | ROOM = 2 16 | }; 17 | 18 | 19 | User() = default; 20 | ~User() = default; 21 | 22 | void Init(const INT32 index) 23 | { 24 | mIndex = index; 25 | mPakcetDataBuffer = new char[PACKET_DATA_BUFFER_SIZE]; 26 | } 27 | 28 | void Clear() 29 | { 30 | mRoomIndex = -1; 31 | mUserID = ""; 32 | mIsConfirm = false; 33 | mCurDomainState = DOMAIN_STATE::NONE; 34 | 35 | mPakcetDataBufferWPos = 0; 36 | mPakcetDataBufferRPos = 0; 37 | } 38 | 39 | int SetLogin(char* userID_) 40 | { 41 | mCurDomainState = DOMAIN_STATE::LOGIN; 42 | mUserID = userID_; 43 | 44 | return 0; 45 | } 46 | 47 | void EnterRoom(INT32 roomIndex_) 48 | { 49 | mRoomIndex = roomIndex_; 50 | mCurDomainState = DOMAIN_STATE::ROOM; 51 | } 52 | 53 | void SetDomainState(DOMAIN_STATE value_) { mCurDomainState = value_; } 54 | 55 | INT32 GetCurrentRoom() 56 | { 57 | return mRoomIndex; 58 | } 59 | 60 | INT32 GetNetConnIdx() 61 | { 62 | return mIndex; 63 | } 64 | 65 | std::string GetUserId() const 66 | { 67 | return mUserID; 68 | } 69 | 70 | DOMAIN_STATE GetDomainState() 71 | { 72 | return mCurDomainState; 73 | } 74 | 75 | void SetPacketData(const UINT32 dataSize_, char* pData_) 76 | { 77 | if ((mPakcetDataBufferWPos + dataSize_) >= PACKET_DATA_BUFFER_SIZE) 78 | { 79 | auto remainDataSize = mPakcetDataBufferWPos - mPakcetDataBufferRPos; 80 | 81 | if (remainDataSize > 0) 82 | { 83 | CopyMemory(&mPakcetDataBuffer[0], &mPakcetDataBuffer[mPakcetDataBufferRPos], remainDataSize); 84 | mPakcetDataBufferWPos = remainDataSize; 85 | } 86 | else 87 | { 88 | mPakcetDataBufferWPos = 0; 89 | } 90 | 91 | mPakcetDataBufferRPos = 0; 92 | } 93 | 94 | CopyMemory(&mPakcetDataBuffer[mPakcetDataBufferWPos], pData_, dataSize_); 95 | mPakcetDataBufferWPos += dataSize_; 96 | } 97 | 98 | PacketInfo GetPacket() 99 | { 100 | const int PACKET_SIZE_LENGTH = 2; 101 | const int PACKET_TYPE_LENGTH = 2; 102 | short packetSize = 0; 103 | 104 | UINT32 remainByte = mPakcetDataBufferWPos - mPakcetDataBufferRPos; 105 | 106 | if(remainByte < PACKET_HEADER_LENGTH) 107 | { 108 | return PacketInfo(); 109 | } 110 | 111 | auto pHeader = (PACKET_HEADER*)&mPakcetDataBuffer[mPakcetDataBufferRPos]; 112 | 113 | if (pHeader->PacketLength > remainByte) 114 | { 115 | return PacketInfo(); 116 | } 117 | 118 | PacketInfo packetInfo; 119 | packetInfo.PacketId = pHeader->PacketId; 120 | packetInfo.DataSize = pHeader->PacketLength; 121 | packetInfo.pDataPtr = &mPakcetDataBuffer[mPakcetDataBufferRPos]; 122 | 123 | mPakcetDataBufferRPos += pHeader->PacketLength; 124 | 125 | return packetInfo; 126 | } 127 | 128 | 129 | private: 130 | INT32 mIndex = -1; 131 | 132 | INT32 mRoomIndex = -1; 133 | 134 | std::string mUserID; 135 | bool mIsConfirm = false; 136 | std::string mAuthToken; 137 | 138 | DOMAIN_STATE mCurDomainState = DOMAIN_STATE::NONE; 139 | 140 | UINT32 mPakcetDataBufferWPos = 0; 141 | UINT32 mPakcetDataBufferRPos = 0; 142 | char* mPakcetDataBuffer = nullptr; 143 | }; 144 | 145 | -------------------------------------------------------------------------------- /Tutorial/09/UserManager.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/09/UserManager.h -------------------------------------------------------------------------------- /Tutorial/09/main.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/09/main.cpp -------------------------------------------------------------------------------- /Tutorial/10/ChatServer.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/10/ChatServer.h -------------------------------------------------------------------------------- /Tutorial/10/ChatServer_03.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.4.33103.184 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ChatServer_03", "ChatServer_03.vcxproj", "{51BA089A-13B7-403B-8422-14972E641F59}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Win64 = Debug|Win64 11 | Release|Win64 = Release|Win64 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {51BA089A-13B7-403B-8422-14972E641F59}.Debug|Win64.ActiveCfg = Debug Win64|x64 15 | {51BA089A-13B7-403B-8422-14972E641F59}.Debug|Win64.Build.0 = Debug Win64|x64 16 | {51BA089A-13B7-403B-8422-14972E641F59}.Release|Win64.ActiveCfg = Release Win64|x64 17 | {51BA089A-13B7-403B-8422-14972E641F59}.Release|Win64.Build.0 = Release Win64|x64 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {3C173561-CA80-421C-A442-C08D1E0BD798} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /Tutorial/10/ChatServer_03.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | ServerNetwork 18 | 19 | 20 | ServerNetwork 21 | 22 | 23 | ServerNetwork 24 | 25 | 26 | 27 | 28 | 29 | 30 | {1fc0f584-76ea-4096-9ebc-805fceb35389} 31 | 32 | 33 | -------------------------------------------------------------------------------- /Tutorial/10/ErrorCode.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/10/ErrorCode.h -------------------------------------------------------------------------------- /Tutorial/10/Packet.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/10/Packet.h -------------------------------------------------------------------------------- /Tutorial/10/PacketManager.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/10/PacketManager.cpp -------------------------------------------------------------------------------- /Tutorial/10/PacketManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Packet.h" 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | 12 | class UserManager; 13 | class RoomManager; 14 | class RedisManager; 15 | 16 | class PacketManager { 17 | public: 18 | PacketManager() = default; 19 | ~PacketManager() = default; 20 | 21 | void Init(const UINT32 maxClient_); 22 | 23 | bool Run(); 24 | 25 | void End(); 26 | 27 | void ReceivePacketData(const UINT32 clientIndex_, const UINT32 size_, char* pData_); 28 | 29 | void PushSystemPacket(PacketInfo packet_); 30 | 31 | std::function SendPacketFunc; 32 | 33 | 34 | private: 35 | void CreateCompent(const UINT32 maxClient_); 36 | 37 | void ClearConnectionInfo(INT32 clientIndex_); 38 | 39 | void EnqueuePacketData(const UINT32 clientIndex_); 40 | PacketInfo DequePacketData(); 41 | 42 | PacketInfo DequeSystemPacketData(); 43 | 44 | 45 | void ProcessPacket(); 46 | 47 | void ProcessRecvPacket(const UINT32 clientIndex_, const UINT16 packetId_, const UINT16 packetSize_, char* pPacket_); 48 | 49 | void ProcessUserConnect(UINT32 clientIndex_, UINT16 packetSize_, char* pPacket_); 50 | void ProcessUserDisConnect(UINT32 clientIndex_, UINT16 packetSize_, char* pPacket_); 51 | 52 | void ProcessLogin(UINT32 clientIndex_, UINT16 packetSize_, char* pPacket_); 53 | void ProcessLoginDBResult(UINT32 clientIndex_, UINT16 packetSize_, char* pPacket_); 54 | 55 | void ProcessEnterRoom(UINT32 clientIndex_, UINT16 packetSize_, char* pPacket_); 56 | void ProcessLeaveRoom(UINT32 clientIndex_, UINT16 packetSize_, char* pPacket_); 57 | void ProcessRoomChatMessage(UINT32 clientIndex_, UINT16 packetSize_, char* pPacket_); 58 | 59 | 60 | 61 | 62 | typedef void(PacketManager::* PROCESS_RECV_PACKET_FUNCTION)(UINT32, UINT16, char*); 63 | std::unordered_map mRecvFuntionDictionary; 64 | 65 | UserManager* mUserManager; 66 | RoomManager* mRoomManager; 67 | RedisManager* mRedisMgr; 68 | 69 | std::function mSendMQDataFunc; 70 | 71 | 72 | bool mIsRunProcessThread = false; 73 | 74 | std::thread mProcessThread; 75 | 76 | std::mutex mLock; 77 | 78 | std::deque mInComingPacketUserIndex; 79 | 80 | std::deque mSystemPacketQueue; 81 | }; 82 | 83 | -------------------------------------------------------------------------------- /Tutorial/10/RedisManager.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/10/RedisManager.h -------------------------------------------------------------------------------- /Tutorial/10/RedisTaskDefine.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/10/RedisTaskDefine.h -------------------------------------------------------------------------------- /Tutorial/10/Room.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "UserManager.h" 4 | #include "Packet.h" 5 | 6 | #include 7 | 8 | 9 | class Room 10 | { 11 | public: 12 | Room() = default; 13 | ~Room() = default; 14 | 15 | INT32 GetMaxUserCount() { return mMaxUserCount; } 16 | 17 | INT32 GetCurrentUserCount() { return mCurrentUserCount; } 18 | 19 | INT32 GetRoomNumber() { return mRoomNum; } 20 | 21 | 22 | void Init(const INT32 roomNum_, const INT32 maxUserCount_) 23 | { 24 | mRoomNum = roomNum_; 25 | mMaxUserCount = maxUserCount_; 26 | } 27 | 28 | UINT16 EnterUser(User* user_) 29 | { 30 | if (mCurrentUserCount >= mMaxUserCount) 31 | { 32 | return (UINT16)ERROR_CODE::ENTER_ROOM_FULL_USER; 33 | } 34 | 35 | mUserList.push_back(user_); 36 | ++mCurrentUserCount; 37 | 38 | user_->EnterRoom(mRoomNum); 39 | return (UINT16)ERROR_CODE::NONE; 40 | } 41 | 42 | void LeaveUser(User* leaveUser_) 43 | { 44 | mUserList.remove_if([leaveUserId = leaveUser_->GetUserId()](User* pUser) { 45 | return leaveUserId == pUser->GetUserId(); 46 | }); 47 | } 48 | 49 | void NotifyChat(INT32 clientIndex_, const char* userID_, const char* msg_) 50 | { 51 | ROOM_CHAT_NOTIFY_PACKET roomChatNtfyPkt; 52 | roomChatNtfyPkt.PacketId = (UINT16)PACKET_ID::ROOM_CHAT_NOTIFY; 53 | roomChatNtfyPkt.PacketLength = sizeof(roomChatNtfyPkt); 54 | 55 | CopyMemory(roomChatNtfyPkt.Msg, msg_, sizeof(roomChatNtfyPkt.Msg)); 56 | CopyMemory(roomChatNtfyPkt.UserID, userID_, sizeof(roomChatNtfyPkt.UserID)); 57 | SendToAllUser(sizeof(roomChatNtfyPkt), (char*)&roomChatNtfyPkt, clientIndex_, false); 58 | } 59 | 60 | 61 | std::function SendPacketFunc; 62 | 63 | private: 64 | void SendToAllUser(const UINT16 dataSize_, char* data_, const INT32 passUserIndex_, bool exceptMe) 65 | { 66 | for (auto pUser : mUserList) 67 | { 68 | if (pUser == nullptr) { 69 | continue; 70 | } 71 | 72 | if (exceptMe && pUser->GetNetConnIdx() == passUserIndex_) { 73 | continue; 74 | } 75 | 76 | SendPacketFunc((UINT32)pUser->GetNetConnIdx(), (UINT32)dataSize_, data_); 77 | } 78 | } 79 | 80 | 81 | INT32 mRoomNum = -1; 82 | 83 | std::list mUserList; 84 | 85 | INT32 mMaxUserCount = 0; 86 | 87 | UINT16 mCurrentUserCount = 0; 88 | }; 89 | -------------------------------------------------------------------------------- /Tutorial/10/RoomManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Room.h" 3 | 4 | class RoomManager 5 | { 6 | public: 7 | RoomManager() = default; 8 | ~RoomManager() = default; 9 | 10 | void Init(const INT32 beginRoomNumber_, const INT32 maxRoomCount_, const INT32 maxRoomUserCount_) 11 | { 12 | mBeginRoomNumber = beginRoomNumber_; 13 | mMaxRoomCount = maxRoomCount_; 14 | mEndRoomNumber = beginRoomNumber_ + maxRoomCount_; 15 | 16 | mRoomList = std::vector(maxRoomCount_); 17 | 18 | for (auto i = 0; i < maxRoomCount_; i++) 19 | { 20 | mRoomList[i] = new Room(); 21 | mRoomList[i]->SendPacketFunc = SendPacketFunc; 22 | mRoomList[i]->Init((i+ beginRoomNumber_), maxRoomUserCount_); 23 | } 24 | } 25 | 26 | UINT GetMaxRoomCount() { return mMaxRoomCount; } 27 | 28 | UINT16 EnterUser(INT32 roomNumber_, User* user_) 29 | { 30 | auto pRoom = GetRoomByNumber(roomNumber_); 31 | if (pRoom == nullptr) 32 | { 33 | return (UINT16)ERROR_CODE::ROOM_INVALID_INDEX; 34 | } 35 | 36 | 37 | return pRoom->EnterUser(user_); 38 | } 39 | 40 | INT16 LeaveUser(INT32 roomNumber_, User* user_) 41 | { 42 | auto pRoom = GetRoomByNumber(roomNumber_); 43 | if (pRoom == nullptr) 44 | { 45 | return (INT16)ERROR_CODE::ROOM_INVALID_INDEX; 46 | } 47 | 48 | user_->SetDomainState(User::DOMAIN_STATE::LOGIN); 49 | pRoom->LeaveUser(user_); 50 | return (INT16)ERROR_CODE::NONE; 51 | } 52 | 53 | Room* GetRoomByNumber(INT32 number_) 54 | { 55 | if (number_ < mBeginRoomNumber || number_ >= mEndRoomNumber) 56 | { 57 | return nullptr; 58 | } 59 | 60 | auto index = (number_ - mBeginRoomNumber); 61 | return mRoomList[index]; 62 | } 63 | 64 | 65 | std::function SendPacketFunc; 66 | 67 | 68 | private: 69 | std::vector mRoomList; 70 | INT32 mBeginRoomNumber = 0; 71 | INT32 mEndRoomNumber = 0; 72 | INT32 mMaxRoomCount = 0; 73 | }; 74 | -------------------------------------------------------------------------------- /Tutorial/10/ServerNetwork/ClientInfo.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/10/ServerNetwork/ClientInfo.h -------------------------------------------------------------------------------- /Tutorial/10/ServerNetwork/Define.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/10/ServerNetwork/Define.h -------------------------------------------------------------------------------- /Tutorial/10/ServerNetwork/IOCPServer.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/10/ServerNetwork/IOCPServer.h -------------------------------------------------------------------------------- /Tutorial/10/User.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/10/User.h -------------------------------------------------------------------------------- /Tutorial/10/UserManager.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/10/UserManager.h -------------------------------------------------------------------------------- /Tutorial/10/main.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/10/main.cpp -------------------------------------------------------------------------------- /Tutorial/ChatServerWithLogger/ChatServer.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/ChatServerWithLogger/ChatServer.h -------------------------------------------------------------------------------- /Tutorial/ChatServerWithLogger/ChatServer.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 16 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ChatServer", "ChatServer.vcxproj", "{B25C4CB4-1E3C-CB4F-2754-562693B231B1}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Win64 = Debug|Win64 9 | Release|Win64 = Release|Win64 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {B25C4CB4-1E3C-CB4F-2754-562693B231B1}.Debug|Win64.ActiveCfg = Debug Win64|x64 13 | {B25C4CB4-1E3C-CB4F-2754-562693B231B1}.Debug|Win64.Build.0 = Debug Win64|x64 14 | {B25C4CB4-1E3C-CB4F-2754-562693B231B1}.Release|Win64.ActiveCfg = Release Win64|x64 15 | {B25C4CB4-1E3C-CB4F-2754-562693B231B1}.Release|Win64.Build.0 = Release Win64|x64 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /Tutorial/ChatServerWithLogger/ChatServer.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | ServerNetwork 18 | 19 | 20 | ServerNetwork 21 | 22 | 23 | ServerNetwork 24 | 25 | 26 | 27 | 28 | 29 | 30 | {1fc0f584-76ea-4096-9ebc-805fceb35389} 31 | 32 | 33 | -------------------------------------------------------------------------------- /Tutorial/ChatServerWithLogger/ErrorCode.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/ChatServerWithLogger/ErrorCode.h -------------------------------------------------------------------------------- /Tutorial/ChatServerWithLogger/Packet.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/ChatServerWithLogger/Packet.h -------------------------------------------------------------------------------- /Tutorial/ChatServerWithLogger/PacketManager.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/ChatServerWithLogger/PacketManager.cpp -------------------------------------------------------------------------------- /Tutorial/ChatServerWithLogger/PacketManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Packet.h" 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | 12 | class UserManager; 13 | class RoomManager; 14 | class RedisManager; 15 | 16 | class PacketManager { 17 | public: 18 | PacketManager() = default; 19 | ~PacketManager() = default; 20 | 21 | void Init(const UINT32 maxClient_); 22 | 23 | bool Run(); 24 | 25 | void End(); 26 | 27 | void ReceivePacketData(const UINT32 clientIndex_, const UINT32 size_, char* pData_); 28 | 29 | void PushSystemPacket(PacketInfo packet_); 30 | 31 | std::function SendPacketFunc; 32 | 33 | 34 | private: 35 | void CreateCompent(const UINT32 maxClient_); 36 | 37 | void ClearConnectionInfo(INT32 clientIndex_); 38 | 39 | void EnqueuePacketData(const UINT32 clientIndex_); 40 | PacketInfo DequePacketData(); 41 | 42 | PacketInfo DequeSystemPacketData(); 43 | 44 | 45 | void ProcessPacket(); 46 | 47 | void ProcessRecvPacket(const UINT32 clientIndex_, const UINT16 packetId_, const UINT16 packetSize_, char* pPacket_); 48 | 49 | void ProcessUserConnect(UINT32 clientIndex_, UINT16 packetSize_, char* pPacket_); 50 | void ProcessUserDisConnect(UINT32 clientIndex_, UINT16 packetSize_, char* pPacket_); 51 | 52 | void ProcessLogin(UINT32 clientIndex_, UINT16 packetSize_, char* pPacket_); 53 | void ProcessLoginDBResult(UINT32 clientIndex_, UINT16 packetSize_, char* pPacket_); 54 | 55 | void ProcessEnterRoom(UINT32 clientIndex_, UINT16 packetSize_, char* pPacket_); 56 | void ProcessLeaveRoom(UINT32 clientIndex_, UINT16 packetSize_, char* pPacket_); 57 | void ProcessRoomChatMessage(UINT32 clientIndex_, UINT16 packetSize_, char* pPacket_); 58 | 59 | 60 | 61 | 62 | typedef void(PacketManager::* PROCESS_RECV_PACKET_FUNCTION)(UINT32, UINT16, char*); 63 | std::unordered_map mRecvFuntionDictionary; 64 | 65 | UserManager* mUserManager; 66 | RoomManager* mRoomManager; 67 | RedisManager* mRedisMgr; 68 | 69 | std::function mSendMQDataFunc; 70 | 71 | 72 | bool mIsRunProcessThread = false; 73 | 74 | std::thread mProcessThread; 75 | 76 | std::mutex mLock; 77 | 78 | std::deque mInComingPacketUserIndex; 79 | 80 | std::deque mSystemPacketQueue; 81 | }; 82 | 83 | -------------------------------------------------------------------------------- /Tutorial/ChatServerWithLogger/RedisManager.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/ChatServerWithLogger/RedisManager.h -------------------------------------------------------------------------------- /Tutorial/ChatServerWithLogger/RedisTaskDefine.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/ChatServerWithLogger/RedisTaskDefine.h -------------------------------------------------------------------------------- /Tutorial/ChatServerWithLogger/Room.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "UserManager.h" 4 | #include "Packet.h" 5 | 6 | #include 7 | 8 | 9 | class Room 10 | { 11 | public: 12 | Room() = default; 13 | ~Room() = default; 14 | 15 | INT32 GetMaxUserCount() { return mMaxUserCount; } 16 | 17 | INT32 GetCurrentUserCount() { return mCurrentUserCount; } 18 | 19 | INT32 GetRoomNumber() { return mRoomNum; } 20 | 21 | 22 | void Init(const INT32 roomNum_, const INT32 maxUserCount_) 23 | { 24 | mRoomNum = roomNum_; 25 | mMaxUserCount = maxUserCount_; 26 | } 27 | 28 | UINT16 EnterUser(User* user_) 29 | { 30 | if (mCurrentUserCount >= mMaxUserCount) 31 | { 32 | return (UINT16)ERROR_CODE::ENTER_ROOM_FULL_USER; 33 | } 34 | 35 | mUserList.push_back(user_); 36 | ++mCurrentUserCount; 37 | 38 | user_->EnterRoom(mRoomNum); 39 | return (UINT16)ERROR_CODE::NONE; 40 | } 41 | 42 | void LeaveUser(User* leaveUser_) 43 | { 44 | mUserList.remove_if([leaveUserId = leaveUser_->GetUserId()](User* pUser) { 45 | return leaveUserId == pUser->GetUserId(); 46 | }); 47 | } 48 | 49 | void NotifyChat(INT32 clientIndex_, const char* userID_, const char* msg_) 50 | { 51 | ROOM_CHAT_NOTIFY_PACKET roomChatNtfyPkt; 52 | roomChatNtfyPkt.PacketId = (UINT16)PACKET_ID::ROOM_CHAT_NOTIFY; 53 | roomChatNtfyPkt.PacketLength = sizeof(roomChatNtfyPkt); 54 | 55 | CopyMemory(roomChatNtfyPkt.Msg, msg_, sizeof(roomChatNtfyPkt.Msg)); 56 | CopyMemory(roomChatNtfyPkt.UserID, userID_, sizeof(roomChatNtfyPkt.UserID)); 57 | SendToAllUser(sizeof(roomChatNtfyPkt), (char*)&roomChatNtfyPkt, clientIndex_, false); 58 | } 59 | 60 | 61 | std::function SendPacketFunc; 62 | 63 | private: 64 | void SendToAllUser(const UINT16 dataSize_, char* data_, const INT32 passUserIndex_, bool exceptMe) 65 | { 66 | for (auto pUser : mUserList) 67 | { 68 | if (pUser == nullptr) { 69 | continue; 70 | } 71 | 72 | if (exceptMe && pUser->GetNetConnIdx() == passUserIndex_) { 73 | continue; 74 | } 75 | 76 | SendPacketFunc((UINT32)pUser->GetNetConnIdx(), (UINT32)dataSize_, data_); 77 | } 78 | } 79 | 80 | 81 | INT32 mRoomNum = -1; 82 | 83 | std::list mUserList; 84 | 85 | INT32 mMaxUserCount = 0; 86 | 87 | UINT16 mCurrentUserCount = 0; 88 | }; 89 | -------------------------------------------------------------------------------- /Tutorial/ChatServerWithLogger/RoomManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Room.h" 3 | 4 | class RoomManager 5 | { 6 | public: 7 | RoomManager() = default; 8 | ~RoomManager() = default; 9 | 10 | void Init(const INT32 beginRoomNumber_, const INT32 maxRoomCount_, const INT32 maxRoomUserCount_) 11 | { 12 | mBeginRoomNumber = beginRoomNumber_; 13 | mMaxRoomCount = maxRoomCount_; 14 | mEndRoomNumber = beginRoomNumber_ + maxRoomCount_; 15 | 16 | mRoomList = std::vector(maxRoomCount_); 17 | 18 | for (auto i = 0; i < maxRoomCount_; i++) 19 | { 20 | mRoomList[i] = new Room(); 21 | mRoomList[i]->SendPacketFunc = SendPacketFunc; 22 | mRoomList[i]->Init((i+ beginRoomNumber_), maxRoomUserCount_); 23 | } 24 | } 25 | 26 | UINT GetMaxRoomCount() { return mMaxRoomCount; } 27 | 28 | UINT16 EnterUser(INT32 roomNumber_, User* user_) 29 | { 30 | auto pRoom = GetRoomByNumber(roomNumber_); 31 | if (pRoom == nullptr) 32 | { 33 | return (UINT16)ERROR_CODE::ROOM_INVALID_INDEX; 34 | } 35 | 36 | 37 | return pRoom->EnterUser(user_); 38 | } 39 | 40 | INT16 LeaveUser(INT32 roomNumber_, User* user_) 41 | { 42 | auto pRoom = GetRoomByNumber(roomNumber_); 43 | if (pRoom == nullptr) 44 | { 45 | return (INT16)ERROR_CODE::ROOM_INVALID_INDEX; 46 | } 47 | 48 | user_->SetDomainState(User::DOMAIN_STATE::LOGIN); 49 | pRoom->LeaveUser(user_); 50 | return (INT16)ERROR_CODE::NONE; 51 | } 52 | 53 | Room* GetRoomByNumber(INT32 number_) 54 | { 55 | if (number_ < mBeginRoomNumber || number_ >= mEndRoomNumber) 56 | { 57 | return nullptr; 58 | } 59 | 60 | auto index = (number_ - mBeginRoomNumber); 61 | return mRoomList[index]; 62 | } 63 | 64 | 65 | std::function SendPacketFunc; 66 | 67 | 68 | private: 69 | std::vector mRoomList; 70 | INT32 mBeginRoomNumber = 0; 71 | INT32 mEndRoomNumber = 0; 72 | INT32 mMaxRoomCount = 0; 73 | }; 74 | -------------------------------------------------------------------------------- /Tutorial/ChatServerWithLogger/ServerNetwork/ClientInfo.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/ChatServerWithLogger/ServerNetwork/ClientInfo.h -------------------------------------------------------------------------------- /Tutorial/ChatServerWithLogger/ServerNetwork/Define.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/ChatServerWithLogger/ServerNetwork/Define.h -------------------------------------------------------------------------------- /Tutorial/ChatServerWithLogger/ServerNetwork/IOCPServer.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/ChatServerWithLogger/ServerNetwork/IOCPServer.h -------------------------------------------------------------------------------- /Tutorial/ChatServerWithLogger/User.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include "Packet.h" 5 | 6 | class User 7 | { 8 | const UINT32 PACKET_DATA_BUFFER_SIZE = 8096; 9 | 10 | public: 11 | enum class DOMAIN_STATE 12 | { 13 | NONE = 0, 14 | LOGIN = 1, 15 | ROOM = 2 16 | }; 17 | 18 | 19 | User() = default; 20 | ~User() = default; 21 | 22 | void Init(const INT32 index) 23 | { 24 | mIndex = index; 25 | mPakcetDataBuffer = new char[PACKET_DATA_BUFFER_SIZE]; 26 | } 27 | 28 | void Clear() 29 | { 30 | mRoomIndex = -1; 31 | mUserID = ""; 32 | mIsConfirm = false; 33 | mCurDomainState = DOMAIN_STATE::NONE; 34 | 35 | mPakcetDataBufferWPos = 0; 36 | mPakcetDataBufferRPos = 0; 37 | } 38 | 39 | int SetLogin(char* userID_) 40 | { 41 | mCurDomainState = DOMAIN_STATE::LOGIN; 42 | mUserID = userID_; 43 | 44 | return 0; 45 | } 46 | 47 | void EnterRoom(INT32 roomIndex_) 48 | { 49 | mRoomIndex = roomIndex_; 50 | mCurDomainState = DOMAIN_STATE::ROOM; 51 | } 52 | 53 | void SetDomainState(DOMAIN_STATE value_) { mCurDomainState = value_; } 54 | 55 | INT32 GetCurrentRoom() 56 | { 57 | return mRoomIndex; 58 | } 59 | 60 | INT32 GetNetConnIdx() 61 | { 62 | return mIndex; 63 | } 64 | 65 | std::string GetUserId() const 66 | { 67 | return mUserID; 68 | } 69 | 70 | DOMAIN_STATE GetDomainState() 71 | { 72 | return mCurDomainState; 73 | } 74 | 75 | void SetPacketData(const UINT32 dataSize_, char* pData_) 76 | { 77 | if ((mPakcetDataBufferWPos + dataSize_) >= PACKET_DATA_BUFFER_SIZE) 78 | { 79 | auto remainDataSize = mPakcetDataBufferWPos - mPakcetDataBufferRPos; 80 | 81 | if (remainDataSize > 0) 82 | { 83 | CopyMemory(&mPakcetDataBuffer[0], &mPakcetDataBuffer[mPakcetDataBufferRPos], remainDataSize); 84 | mPakcetDataBufferWPos = remainDataSize; 85 | } 86 | else 87 | { 88 | mPakcetDataBufferWPos = 0; 89 | } 90 | 91 | mPakcetDataBufferRPos = 0; 92 | } 93 | 94 | CopyMemory(&mPakcetDataBuffer[mPakcetDataBufferWPos], pData_, dataSize_); 95 | mPakcetDataBufferWPos += dataSize_; 96 | } 97 | 98 | PacketInfo GetPacket() 99 | { 100 | const int PACKET_SIZE_LENGTH = 2; 101 | const int PACKET_TYPE_LENGTH = 2; 102 | short packetSize = 0; 103 | 104 | UINT32 remainByte = mPakcetDataBufferWPos - mPakcetDataBufferRPos; 105 | 106 | if(remainByte < PACKET_HEADER_LENGTH) 107 | { 108 | return PacketInfo(); 109 | } 110 | 111 | auto pHeader = (PACKET_HEADER*)&mPakcetDataBuffer[mPakcetDataBufferRPos]; 112 | 113 | if (pHeader->PacketLength > remainByte) 114 | { 115 | return PacketInfo(); 116 | } 117 | 118 | PacketInfo packetInfo; 119 | packetInfo.PacketId = pHeader->PacketId; 120 | packetInfo.DataSize = pHeader->PacketLength; 121 | packetInfo.pDataPtr = &mPakcetDataBuffer[mPakcetDataBufferRPos]; 122 | 123 | mPakcetDataBufferRPos += pHeader->PacketLength; 124 | 125 | return packetInfo; 126 | } 127 | 128 | 129 | private: 130 | INT32 mIndex = -1; 131 | 132 | INT32 mRoomIndex = -1; 133 | 134 | std::string mUserID; 135 | bool mIsConfirm = false; 136 | std::string mAuthToken; 137 | 138 | DOMAIN_STATE mCurDomainState = DOMAIN_STATE::NONE; 139 | 140 | UINT32 mPakcetDataBufferWPos = 0; 141 | UINT32 mPakcetDataBufferRPos = 0; 142 | char* mPakcetDataBuffer = nullptr; 143 | }; 144 | 145 | -------------------------------------------------------------------------------- /Tutorial/ChatServerWithLogger/UserManager.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/ChatServerWithLogger/UserManager.h -------------------------------------------------------------------------------- /Tutorial/ChatServerWithLogger/main.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/ChatServerWithLogger/main.cpp -------------------------------------------------------------------------------- /Tutorial/premake5.lua: -------------------------------------------------------------------------------- 1 | solution "IOCP_01" 2 | configurations { "Debug", "Release" } 3 | platforms { "Win64" } 4 | 5 | -- A project defines one build target 6 | project "IOCP_01" 7 | kind "ConsoleApp" 8 | language "C++" 9 | files { "**.h", "**.cpp" } 10 | 11 | configuration "Debug" 12 | defines { "DEBUG" } 13 | flags { "Symbols" } 14 | platforms { "Win64" } 15 | 16 | configuration "Release" 17 | defines { "NDEBUG" } 18 | flags { "Optimize" } 19 | 20 | filter { "platforms:Win64" } 21 | architecture "x64" 22 | targetdir("../bin") -------------------------------------------------------------------------------- /Tutorial/thirdparty/RedisCpp-hiredis/RedisCpp-hiredis.md: -------------------------------------------------------------------------------- 1 | # RedisCpp-hiredis 2 | 3 | ## 개요 4 | - 원본 소스는 [RedisCppTeam/RedisCpp-hiredis](https://github.com/RedisCppTeam/RedisCpp-hiredis ) 5 | - 원본 소스를 조금 수정하여 hiredis와 header-only로 사용 가능하다. 6 | - hiredis는 C 언어용 redis 클라이언트 라이브러리이고, RedisCpp는 이것을 C++용으로 랩핑한 것이다. 7 | - src 디렉토리에 1개의 헤더파일로 되어있다. 8 | 9 | 10 | 11 | ## 사용하기 12 | ### Windows 13 | - hiredis 소스와 lib 디렉토리를 지정한다. 14 | ![hiredis_vc](./images/002.png) 15 | - 'CRedisConn.h' 헤더 파일을 추가한다. 16 | 17 | 18 | ## Sample 19 | `CRedisConn_test.cpp` 파일은 원본 소스의 예제이다. 20 | 21 | ### 연결 22 | - Smaples/Connect 23 | 24 | ### List 사용하기 25 | - Smaples/List -------------------------------------------------------------------------------- /Tutorial/thirdparty/RedisCpp-hiredis/Samples/Connect/Connect.cpp: -------------------------------------------------------------------------------- 1 | // Connect.cpp : 이 파일에는 'main' 함수가 포함됩니다. 거기서 프로그램 실행이 시작되고 종료됩니다. 2 | // 3 | 4 | #include 5 | 6 | #include "../../src/CRedisConn.h" 7 | 8 | int main() 9 | { 10 | //int64_t ret = 0; 11 | //uint64_t ret2 = 0; 12 | 13 | RedisCpp::CRedisConn con; 14 | 15 | std::string value; 16 | 17 | if (!con.connect("127.0.0.1", 6379)) 18 | { 19 | std::cout << "connect error " << con.getErrorStr() << std::endl; 20 | return -1; 21 | } 22 | else 23 | { 24 | std::cout << "connect success !!!" << std::endl; 25 | } 26 | 27 | return 0; 28 | } 29 | 30 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/RedisCpp-hiredis/Samples/Connect/Connect.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.29215.179 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Connect", "Connect.vcxproj", "{1B3844C0-0D1E-4A23-907A-E62175FF60CF}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {1B3844C0-0D1E-4A23-907A-E62175FF60CF}.Debug|x64.ActiveCfg = Debug|x64 17 | {1B3844C0-0D1E-4A23-907A-E62175FF60CF}.Debug|x64.Build.0 = Debug|x64 18 | {1B3844C0-0D1E-4A23-907A-E62175FF60CF}.Debug|x86.ActiveCfg = Debug|Win32 19 | {1B3844C0-0D1E-4A23-907A-E62175FF60CF}.Debug|x86.Build.0 = Debug|Win32 20 | {1B3844C0-0D1E-4A23-907A-E62175FF60CF}.Release|x64.ActiveCfg = Release|x64 21 | {1B3844C0-0D1E-4A23-907A-E62175FF60CF}.Release|x64.Build.0 = Release|x64 22 | {1B3844C0-0D1E-4A23-907A-E62175FF60CF}.Release|x86.ActiveCfg = Release|Win32 23 | {1B3844C0-0D1E-4A23-907A-E62175FF60CF}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {A5758A69-29C7-45C4-BEB1-2A13891BEF49} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/RedisCpp-hiredis/Samples/Connect/Connect.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/RedisCpp-hiredis/Samples/List/List.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 16 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "List", "List.vcxproj", "{418A887C-2DC1-890D-D6AD-6F10C2C3050F}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Win64 = Debug|Win64 9 | Release|Win64 = Release|Win64 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {418A887C-2DC1-890D-D6AD-6F10C2C3050F}.Debug|Win64.ActiveCfg = Debug Win64|x64 13 | {418A887C-2DC1-890D-D6AD-6F10C2C3050F}.Debug|Win64.Build.0 = Debug Win64|x64 14 | {418A887C-2DC1-890D-D6AD-6F10C2C3050F}.Release|Win64.ActiveCfg = Release Win64|x64 15 | {418A887C-2DC1-890D-D6AD-6F10C2C3050F}.Release|Win64.Build.0 = Release Win64|x64 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/RedisCpp-hiredis/Samples/List/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "../../src/CRedisConn.h" 4 | 5 | void TestList( ) 6 | { 7 | int64_t ret = 0; 8 | uint64_t ret2 = 0; 9 | RedisCpp::CRedisConn con; 10 | std::string value; 11 | 12 | if ( !con.connect( "127.0.0.1", 6379 ) ) 13 | { 14 | std::cout << "connect error " << con.getErrorStr( ) << std::endl; 15 | return; 16 | } 17 | 18 | /*if ( !con.auth("111") ) 19 | { 20 | std::cout << "auth error: " << con.getErrorStr() << std::endl; 21 | } 22 | else 23 | { 24 | std::cout << "auth success" << std::endl; 25 | }*/ 26 | 27 | std::cout << "lpush-lpop" << std::endl; 28 | // lpush 29 | if ( !con.lpush( "test", "yuhaiyang", ret2 ) ) 30 | { 31 | std::cout << "lpush error: " << con.getErrorStr( ) << std::endl; 32 | }else 33 | { 34 | std::cout << "lpush len = " << ret2 << std::endl; 35 | } 36 | 37 | //LINDEX https://kwoncharlie.blog.me/220397447626 38 | if (!con.lindex("test", 1, value)) 39 | { 40 | std::cout << "lindex error: " << con.getErrorStr() << std::endl; 41 | } 42 | else 43 | { 44 | std::cout << value.c_str() << std::endl; 45 | } 46 | 47 | //lpop 48 | if( !con.lpop( "test", value ) ) 49 | { 50 | std::cout << "lpop error: " << con.getErrorStr( ) << std::endl; 51 | }else 52 | { 53 | std::cout << "value: " << value << std::endl; 54 | } 55 | std::cout << std::endl; 56 | 57 | 58 | std::cout << "rpush-rpop" << std::endl; 59 | //rpush 60 | if ( !con.rpush( "testM", "yuhaiyang", ret2 ) ) 61 | { 62 | std::cout << "rpush error: " << con.getErrorStr( ) << std::endl; 63 | }else 64 | { 65 | std::cout << "rpush len = " << ret2 << std::endl; 66 | } 67 | 68 | 69 | //rpop 70 | if( !con.rpop( "Atest", value ) ) 71 | { 72 | std::cout << "rpop error: " << con.getErrorStr( ) << std::endl; 73 | }else 74 | { 75 | std::cout << "value: " << value << std::endl; 76 | } 77 | std::cout << std::endl; 78 | 79 | 80 | std::cout << "llen" << std::endl; 81 | if( !con.llen("test",ret2) ) 82 | { 83 | std::cout << "llen error: " << con.getErrorStr( ) << std::endl; 84 | 85 | } 86 | else 87 | { 88 | std::cout << "llen = " << ret2 << std::endl; 89 | } 90 | std::cout << std::endl; 91 | 92 | 93 | std::cout << "linsert" << std::endl; 94 | if( !con.linsert("Ltest", RedisCpp::BEFORE, "value0", "chenjun", ret ) ) 95 | { 96 | std::cout << "linsert error: " << con.getErrorStr( ) << std::endl; 97 | } 98 | else 99 | { 100 | std::cout << "revalue = " << ret << std::endl; 101 | } 102 | std::cout << std::endl; 103 | 104 | 105 | 106 | std::cout << "lrange" << std::endl; 107 | RedisCpp::ValueList valueList; 108 | if( !con.lrange( "test", 0, -1, valueList ) ) 109 | { 110 | std::cout << "lrange error: " << con.getErrorStr() << std::endl; 111 | }else 112 | { 113 | RedisCpp::ValueList::const_iterator it = valueList.begin(); 114 | 115 | for( ; it != valueList.end(); it++ ) 116 | { 117 | std::cout << "value: " << *it << std::endl; 118 | } 119 | } 120 | 121 | } 122 | 123 | int main(int argc, char* argv[]) 124 | { 125 | TestList(); 126 | return 0; 127 | } -------------------------------------------------------------------------------- /Tutorial/thirdparty/RedisCpp-hiredis/Samples/List/premake5.lua: -------------------------------------------------------------------------------- 1 | solution "List" 2 | configurations { "Debug", "Release" } 3 | platforms { "Win64" } 4 | 5 | -- A project defines one build target 6 | project "List" 7 | kind "ConsoleApp" 8 | language "C++" 9 | files { "**.h", "**.hpp", "**.cpp" } 10 | 11 | includedirs { 12 | "D:/Dev/c++/thirdparty/hiredis" 13 | } 14 | 15 | configuration "Debug" 16 | defines { "DEBUG" } 17 | platforms { "Win64" } 18 | libdirs { "D:/Dev/c++/thirdparty/hiredis/vc_soluration/hiredis.dir/Debug" } 19 | 20 | configuration "Release" 21 | defines { "NDEBUG" } 22 | 23 | filter { "platforms:Win64" } 24 | architecture "x64" 25 | targetdir("../bins") -------------------------------------------------------------------------------- /Tutorial/thirdparty/RedisCpp-hiredis/images/001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/thirdparty/RedisCpp-hiredis/images/001.png -------------------------------------------------------------------------------- /Tutorial/thirdparty/RedisCpp-hiredis/images/002.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/thirdparty/RedisCpp-hiredis/images/002.png -------------------------------------------------------------------------------- /Tutorial/thirdparty/hiredis/.gitignore: -------------------------------------------------------------------------------- 1 | /hiredis-test 2 | /examples/hiredis-example* 3 | /*.o 4 | /*.so 5 | /*.dylib 6 | /*.a 7 | /*.pc 8 | *.dSYM 9 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/hiredis/.travis.yml: -------------------------------------------------------------------------------- 1 | language: c 2 | sudo: false 3 | compiler: 4 | - gcc 5 | - clang 6 | 7 | os: 8 | - linux 9 | - osx 10 | 11 | branches: 12 | only: 13 | - staging 14 | - trying 15 | - master 16 | 17 | before_script: 18 | - if [ "$TRAVIS_OS_NAME" == "osx" ] ; then brew update; brew install redis; fi 19 | 20 | addons: 21 | apt: 22 | packages: 23 | - libc6-dbg 24 | - libc6-dev 25 | - libc6:i386 26 | - libc6-dev-i386 27 | - libc6-dbg:i386 28 | - gcc-multilib 29 | - g++-multilib 30 | - valgrind 31 | 32 | env: 33 | - BITS="32" 34 | - BITS="64" 35 | 36 | script: 37 | - EXTRA_CMAKE_OPTS="-DENABLE_EXAMPLES:BOOL=ON -DHIREDIS_SSL:BOOL=ON"; 38 | if [ "$TRAVIS_OS_NAME" == "osx" ]; then 39 | if [ "$BITS" == "32" ]; then 40 | CFLAGS="-m32 -Werror"; 41 | CXXFLAGS="-m32 -Werror"; 42 | LDFLAGS="-m32"; 43 | EXTRA_CMAKE_OPTS=; 44 | else 45 | CFLAGS="-Werror"; 46 | CXXFLAGS="-Werror"; 47 | fi; 48 | else 49 | TEST_PREFIX="valgrind --track-origins=yes --leak-check=full"; 50 | if [ "$BITS" == "32" ]; then 51 | CFLAGS="-m32 -Werror"; 52 | CXXFLAGS="-m32 -Werror"; 53 | LDFLAGS="-m32"; 54 | EXTRA_CMAKE_OPTS=; 55 | else 56 | CFLAGS="-Werror"; 57 | CXXFLAGS="-Werror"; 58 | fi; 59 | fi; 60 | export CFLAGS CXXFLAGS LDFLAGS TEST_PREFIX EXTRA_CMAKE_OPTS 61 | - mkdir build/ && cd build/ 62 | - cmake .. ${EXTRA_CMAKE_OPTS} 63 | - make VERBOSE=1 64 | - ctest -V 65 | 66 | matrix: 67 | include: 68 | # Windows MinGW cross compile on Linux 69 | - os: linux 70 | dist: xenial 71 | compiler: mingw 72 | addons: 73 | apt: 74 | packages: 75 | - ninja-build 76 | - gcc-mingw-w64-x86-64 77 | - g++-mingw-w64-x86-64 78 | script: 79 | - mkdir build && cd build 80 | - 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 81 | - ninja -v 82 | 83 | # Windows MSVC 2017 84 | - os: windows 85 | compiler: msvc 86 | env: 87 | - MATRIX_EVAL="CC=cl.exe && CXX=cl.exe" 88 | before_install: 89 | - eval "${MATRIX_EVAL}" 90 | install: 91 | - choco install ninja 92 | script: 93 | - mkdir build && cd build 94 | - cmd.exe /C '"C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build\vcvarsall.bat" amd64 && 95 | cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Release && 96 | ninja -v' 97 | - ctest -V 98 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/hiredis/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | CMAKE_MINIMUM_REQUIRED(VERSION 3.4.0) 2 | INCLUDE(GNUInstallDirs) 3 | PROJECT(hiredis) 4 | 5 | OPTION(ENABLE_SSL "Build hiredis_ssl for SSL support" OFF) 6 | 7 | MACRO(getVersionBit name) 8 | SET(VERSION_REGEX "^#define ${name} (.+)$") 9 | FILE(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/hiredis.h" 10 | VERSION_BIT REGEX ${VERSION_REGEX}) 11 | STRING(REGEX REPLACE ${VERSION_REGEX} "\\1" ${name} "${VERSION_BIT}") 12 | ENDMACRO(getVersionBit) 13 | 14 | getVersionBit(HIREDIS_MAJOR) 15 | getVersionBit(HIREDIS_MINOR) 16 | getVersionBit(HIREDIS_PATCH) 17 | getVersionBit(HIREDIS_SONAME) 18 | SET(VERSION "${HIREDIS_MAJOR}.${HIREDIS_MINOR}.${HIREDIS_PATCH}") 19 | MESSAGE("Detected version: ${VERSION}") 20 | 21 | PROJECT(hiredis VERSION "${VERSION}") 22 | 23 | SET(ENABLE_EXAMPLES OFF CACHE BOOL "Enable building hiredis examples") 24 | 25 | ADD_LIBRARY(hiredis SHARED 26 | async.c 27 | dict.c 28 | hiredis.c 29 | net.c 30 | read.c 31 | sds.c 32 | sockcompat.c) 33 | 34 | SET_TARGET_PROPERTIES(hiredis 35 | PROPERTIES 36 | VERSION "${HIREDIS_SONAME}") 37 | IF(WIN32 OR MINGW) 38 | TARGET_LINK_LIBRARIES(hiredis PRIVATE ws2_32) 39 | ENDIF() 40 | TARGET_INCLUDE_DIRECTORIES(hiredis PUBLIC .) 41 | 42 | CONFIGURE_FILE(hiredis.pc.in hiredis.pc @ONLY) 43 | 44 | INSTALL(TARGETS hiredis 45 | DESTINATION "${CMAKE_INSTALL_LIBDIR}") 46 | 47 | INSTALL(FILES hiredis.h read.h sds.h async.h 48 | DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/hiredis) 49 | 50 | INSTALL(DIRECTORY adapters 51 | DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/hiredis) 52 | 53 | INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/hiredis.pc 54 | DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) 55 | 56 | IF(ENABLE_SSL) 57 | IF (NOT OPENSSL_ROOT_DIR) 58 | IF (APPLE) 59 | SET(OPENSSL_ROOT_DIR "/usr/local/opt/openssl") 60 | ENDIF() 61 | ENDIF() 62 | FIND_PACKAGE(OpenSSL REQUIRED) 63 | ADD_LIBRARY(hiredis_ssl SHARED 64 | ssl.c) 65 | TARGET_INCLUDE_DIRECTORIES(hiredis_ssl PRIVATE "${OPENSSL_INCLUDE_DIR}") 66 | TARGET_LINK_LIBRARIES(hiredis_ssl PRIVATE ${OPENSSL_LIBRARIES}) 67 | CONFIGURE_FILE(hiredis_ssl.pc.in hiredis_ssl.pc @ONLY) 68 | 69 | INSTALL(TARGETS hiredis_ssl 70 | DESTINATION "${CMAKE_INSTALL_LIBDIR}") 71 | 72 | INSTALL(FILES hiredis_ssl.h 73 | DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/hiredis) 74 | 75 | INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/hiredis_ssl.pc 76 | DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) 77 | ENDIF() 78 | 79 | IF(NOT (WIN32 OR MINGW)) 80 | ENABLE_TESTING() 81 | ADD_EXECUTABLE(hiredis-test test.c) 82 | TARGET_LINK_LIBRARIES(hiredis-test hiredis) 83 | ADD_TEST(NAME hiredis-test 84 | COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/test.sh) 85 | ENDIF() 86 | 87 | # Add examples 88 | IF(ENABLE_EXAMPLES) 89 | ADD_SUBDIRECTORY(examples) 90 | ENDIF(ENABLE_EXAMPLES) 91 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/hiredis/COPYING: -------------------------------------------------------------------------------- 1 | Copyright (c) 2009-2011, Salvatore Sanfilippo 2 | Copyright (c) 2010-2011, Pieter Noordhuis 3 | 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, 10 | this list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of Redis nor the names of its contributors may be used 17 | to endorse or promote products derived from this software without specific 18 | prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 21 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 22 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 24 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 25 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 26 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 27 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/hiredis/VS-IDE/ALL_BUILD.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/hiredis/VS-IDE/Debug/hiredis.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/thirdparty/hiredis/VS-IDE/Debug/hiredis.lib -------------------------------------------------------------------------------- /Tutorial/thirdparty/hiredis/VS-IDE/Debug/hiredis.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/thirdparty/hiredis/VS-IDE/Debug/hiredis.pdb -------------------------------------------------------------------------------- /Tutorial/thirdparty/hiredis/VS-IDE/INSTALL.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | CMake Rules 6 | 7 | 8 | 9 | 10 | {17D7F1E9-9A9E-3EFB-9D2C-43D625A70ACD} 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/hiredis/VS-IDE/Release/hiredis.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacking75/edu_cpp_IOCP/b4044bc980887c5f9c9b4c23a1121cd249784524/Tutorial/thirdparty/hiredis/VS-IDE/Release/hiredis.lib -------------------------------------------------------------------------------- /Tutorial/thirdparty/hiredis/VS-IDE/ZERO_CHECK.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | CMake Rules 6 | 7 | 8 | 9 | 10 | {17D7F1E9-9A9E-3EFB-9D2C-43D625A70ACD} 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/hiredis/VS-IDE/hiredis.pc: -------------------------------------------------------------------------------- 1 | prefix=C:/Program Files (x86)/hiredis 2 | exec_prefix=${prefix} 3 | libdir=${exec_prefix}/lib 4 | includedir=${prefix}/include 5 | pkgincludedir=${includedir}/hiredis 6 | 7 | Name: hiredis 8 | Description: Minimalistic C client library for Redis. 9 | Version: 0.14.0 10 | Libs: -L${libdir} -lhiredis 11 | Cflags: -I${pkgincludedir} -D_FILE_OFFSET_BITS=64 12 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/hiredis/VS-IDE/hiredis.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Source Files 6 | 7 | 8 | Source Files 9 | 10 | 11 | Source Files 12 | 13 | 14 | Source Files 15 | 16 | 17 | Source Files 18 | 19 | 20 | Source Files 21 | 22 | 23 | Source Files 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | {EC0E5508-4303-3509-97AD-66AEC359EA9D} 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/hiredis/adapters/ivykis.h: -------------------------------------------------------------------------------- 1 | #ifndef __HIREDIS_IVYKIS_H__ 2 | #define __HIREDIS_IVYKIS_H__ 3 | #include 4 | #include "../hiredis.h" 5 | #include "../async.h" 6 | 7 | typedef struct redisIvykisEvents { 8 | redisAsyncContext *context; 9 | struct iv_fd fd; 10 | } redisIvykisEvents; 11 | 12 | static void redisIvykisReadEvent(void *arg) { 13 | redisAsyncContext *context = (redisAsyncContext *)arg; 14 | redisAsyncHandleRead(context); 15 | } 16 | 17 | static void redisIvykisWriteEvent(void *arg) { 18 | redisAsyncContext *context = (redisAsyncContext *)arg; 19 | redisAsyncHandleWrite(context); 20 | } 21 | 22 | static void redisIvykisAddRead(void *privdata) { 23 | redisIvykisEvents *e = (redisIvykisEvents*)privdata; 24 | iv_fd_set_handler_in(&e->fd, redisIvykisReadEvent); 25 | } 26 | 27 | static void redisIvykisDelRead(void *privdata) { 28 | redisIvykisEvents *e = (redisIvykisEvents*)privdata; 29 | iv_fd_set_handler_in(&e->fd, NULL); 30 | } 31 | 32 | static void redisIvykisAddWrite(void *privdata) { 33 | redisIvykisEvents *e = (redisIvykisEvents*)privdata; 34 | iv_fd_set_handler_out(&e->fd, redisIvykisWriteEvent); 35 | } 36 | 37 | static void redisIvykisDelWrite(void *privdata) { 38 | redisIvykisEvents *e = (redisIvykisEvents*)privdata; 39 | iv_fd_set_handler_out(&e->fd, NULL); 40 | } 41 | 42 | static void redisIvykisCleanup(void *privdata) { 43 | redisIvykisEvents *e = (redisIvykisEvents*)privdata; 44 | 45 | iv_fd_unregister(&e->fd); 46 | free(e); 47 | } 48 | 49 | static int redisIvykisAttach(redisAsyncContext *ac) { 50 | redisContext *c = &(ac->c); 51 | redisIvykisEvents *e; 52 | 53 | /* Nothing should be attached when something is already attached */ 54 | if (ac->ev.data != NULL) 55 | return REDIS_ERR; 56 | 57 | /* Create container for context and r/w events */ 58 | e = (redisIvykisEvents*)malloc(sizeof(*e)); 59 | e->context = ac; 60 | 61 | /* Register functions to start/stop listening for events */ 62 | ac->ev.addRead = redisIvykisAddRead; 63 | ac->ev.delRead = redisIvykisDelRead; 64 | ac->ev.addWrite = redisIvykisAddWrite; 65 | ac->ev.delWrite = redisIvykisDelWrite; 66 | ac->ev.cleanup = redisIvykisCleanup; 67 | ac->ev.data = e; 68 | 69 | /* Initialize and install read/write events */ 70 | IV_FD_INIT(&e->fd); 71 | e->fd.fd = c->fd; 72 | e->fd.handler_in = redisIvykisReadEvent; 73 | e->fd.handler_out = redisIvykisWriteEvent; 74 | e->fd.handler_err = NULL; 75 | e->fd.cookie = e->context; 76 | 77 | iv_fd_register(&e->fd); 78 | 79 | return REDIS_OK; 80 | } 81 | #endif 82 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/hiredis/adapters/libuv.h: -------------------------------------------------------------------------------- 1 | #ifndef __HIREDIS_LIBUV_H__ 2 | #define __HIREDIS_LIBUV_H__ 3 | #include 4 | #include 5 | #include "../hiredis.h" 6 | #include "../async.h" 7 | #include 8 | 9 | typedef struct redisLibuvEvents { 10 | redisAsyncContext* context; 11 | uv_poll_t handle; 12 | int events; 13 | } redisLibuvEvents; 14 | 15 | 16 | static void redisLibuvPoll(uv_poll_t* handle, int status, int events) { 17 | redisLibuvEvents* p = (redisLibuvEvents*)handle->data; 18 | int ev = (status ? p->events : events); 19 | 20 | if (p->context != NULL && (ev & UV_READABLE)) { 21 | redisAsyncHandleRead(p->context); 22 | } 23 | if (p->context != NULL && (ev & UV_WRITABLE)) { 24 | redisAsyncHandleWrite(p->context); 25 | } 26 | } 27 | 28 | 29 | static void redisLibuvAddRead(void *privdata) { 30 | redisLibuvEvents* p = (redisLibuvEvents*)privdata; 31 | 32 | p->events |= UV_READABLE; 33 | 34 | uv_poll_start(&p->handle, p->events, redisLibuvPoll); 35 | } 36 | 37 | 38 | static void redisLibuvDelRead(void *privdata) { 39 | redisLibuvEvents* p = (redisLibuvEvents*)privdata; 40 | 41 | p->events &= ~UV_READABLE; 42 | 43 | if (p->events) { 44 | uv_poll_start(&p->handle, p->events, redisLibuvPoll); 45 | } else { 46 | uv_poll_stop(&p->handle); 47 | } 48 | } 49 | 50 | 51 | static void redisLibuvAddWrite(void *privdata) { 52 | redisLibuvEvents* p = (redisLibuvEvents*)privdata; 53 | 54 | p->events |= UV_WRITABLE; 55 | 56 | uv_poll_start(&p->handle, p->events, redisLibuvPoll); 57 | } 58 | 59 | 60 | static void redisLibuvDelWrite(void *privdata) { 61 | redisLibuvEvents* p = (redisLibuvEvents*)privdata; 62 | 63 | p->events &= ~UV_WRITABLE; 64 | 65 | if (p->events) { 66 | uv_poll_start(&p->handle, p->events, redisLibuvPoll); 67 | } else { 68 | uv_poll_stop(&p->handle); 69 | } 70 | } 71 | 72 | 73 | static void on_close(uv_handle_t* handle) { 74 | redisLibuvEvents* p = (redisLibuvEvents*)handle->data; 75 | 76 | free(p); 77 | } 78 | 79 | 80 | static void redisLibuvCleanup(void *privdata) { 81 | redisLibuvEvents* p = (redisLibuvEvents*)privdata; 82 | 83 | p->context = NULL; // indicate that context might no longer exist 84 | uv_close((uv_handle_t*)&p->handle, on_close); 85 | } 86 | 87 | 88 | static int redisLibuvAttach(redisAsyncContext* ac, uv_loop_t* loop) { 89 | redisContext *c = &(ac->c); 90 | 91 | if (ac->ev.data != NULL) { 92 | return REDIS_ERR; 93 | } 94 | 95 | ac->ev.addRead = redisLibuvAddRead; 96 | ac->ev.delRead = redisLibuvDelRead; 97 | ac->ev.addWrite = redisLibuvAddWrite; 98 | ac->ev.delWrite = redisLibuvDelWrite; 99 | ac->ev.cleanup = redisLibuvCleanup; 100 | 101 | redisLibuvEvents* p = (redisLibuvEvents*)malloc(sizeof(*p)); 102 | 103 | if (!p) { 104 | return REDIS_ERR; 105 | } 106 | 107 | memset(p, 0, sizeof(*p)); 108 | 109 | if (uv_poll_init(loop, &p->handle, c->fd) != 0) { 110 | return REDIS_ERR; 111 | } 112 | 113 | ac->ev.data = p; 114 | p->handle.data = p; 115 | p->context = ac; 116 | 117 | return REDIS_OK; 118 | } 119 | #endif 120 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/hiredis/appveyor.yml: -------------------------------------------------------------------------------- 1 | # Appveyor configuration file for CI build of hiredis on Windows (under Cygwin) 2 | environment: 3 | matrix: 4 | - CYG_BASH: C:\cygwin64\bin\bash 5 | CC: gcc 6 | - CYG_BASH: C:\cygwin\bin\bash 7 | CC: gcc 8 | CFLAGS: -m32 9 | CXXFLAGS: -m32 10 | LDFLAGS: -m32 11 | 12 | clone_depth: 1 13 | 14 | # Attempt to ensure we don't try to convert line endings to Win32 CRLF as this will cause build to fail 15 | init: 16 | - git config --global core.autocrlf input 17 | 18 | # Install needed build dependencies 19 | install: 20 | - '%CYG_BASH% -lc "cygcheck -dc cygwin"' 21 | 22 | build_script: 23 | - 'echo building...' 24 | - '%CYG_BASH% -lc "cd $APPVEYOR_BUILD_FOLDER; exec 0 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | /* Put event loop in the global scope, so it can be explicitly stopped */ 11 | static aeEventLoop *loop; 12 | 13 | void getCallback(redisAsyncContext *c, void *r, void *privdata) { 14 | redisReply *reply = r; 15 | if (reply == NULL) return; 16 | printf("argv[%s]: %s\n", (char*)privdata, reply->str); 17 | 18 | /* Disconnect after receiving the reply to GET */ 19 | redisAsyncDisconnect(c); 20 | } 21 | 22 | void connectCallback(const redisAsyncContext *c, int status) { 23 | if (status != REDIS_OK) { 24 | printf("Error: %s\n", c->errstr); 25 | aeStop(loop); 26 | return; 27 | } 28 | 29 | printf("Connected...\n"); 30 | } 31 | 32 | void disconnectCallback(const redisAsyncContext *c, int status) { 33 | if (status != REDIS_OK) { 34 | printf("Error: %s\n", c->errstr); 35 | aeStop(loop); 36 | return; 37 | } 38 | 39 | printf("Disconnected...\n"); 40 | aeStop(loop); 41 | } 42 | 43 | int main (int argc, char **argv) { 44 | signal(SIGPIPE, SIG_IGN); 45 | 46 | redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379); 47 | if (c->err) { 48 | /* Let *c leak for now... */ 49 | printf("Error: %s\n", c->errstr); 50 | return 1; 51 | } 52 | 53 | loop = aeCreateEventLoop(64); 54 | redisAeAttach(loop, c); 55 | redisAsyncSetConnectCallback(c,connectCallback); 56 | redisAsyncSetDisconnectCallback(c,disconnectCallback); 57 | redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1])); 58 | redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); 59 | aeMain(loop); 60 | return 0; 61 | } 62 | 63 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/hiredis/examples/example-glib.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | static GMainLoop *mainloop; 8 | 9 | static void 10 | connect_cb (const redisAsyncContext *ac G_GNUC_UNUSED, 11 | int status) 12 | { 13 | if (status != REDIS_OK) { 14 | g_printerr("Failed to connect: %s\n", ac->errstr); 15 | g_main_loop_quit(mainloop); 16 | } else { 17 | g_printerr("Connected...\n"); 18 | } 19 | } 20 | 21 | static void 22 | disconnect_cb (const redisAsyncContext *ac G_GNUC_UNUSED, 23 | int status) 24 | { 25 | if (status != REDIS_OK) { 26 | g_error("Failed to disconnect: %s", ac->errstr); 27 | } else { 28 | g_printerr("Disconnected...\n"); 29 | g_main_loop_quit(mainloop); 30 | } 31 | } 32 | 33 | static void 34 | command_cb(redisAsyncContext *ac, 35 | gpointer r, 36 | gpointer user_data G_GNUC_UNUSED) 37 | { 38 | redisReply *reply = r; 39 | 40 | if (reply) { 41 | g_print("REPLY: %s\n", reply->str); 42 | } 43 | 44 | redisAsyncDisconnect(ac); 45 | } 46 | 47 | gint 48 | main (gint argc G_GNUC_UNUSED, 49 | gchar *argv[] G_GNUC_UNUSED) 50 | { 51 | redisAsyncContext *ac; 52 | GMainContext *context = NULL; 53 | GSource *source; 54 | 55 | ac = redisAsyncConnect("127.0.0.1", 6379); 56 | if (ac->err) { 57 | g_printerr("%s\n", ac->errstr); 58 | exit(EXIT_FAILURE); 59 | } 60 | 61 | source = redis_source_new(ac); 62 | mainloop = g_main_loop_new(context, FALSE); 63 | g_source_attach(source, context); 64 | 65 | redisAsyncSetConnectCallback(ac, connect_cb); 66 | redisAsyncSetDisconnectCallback(ac, disconnect_cb); 67 | redisAsyncCommand(ac, command_cb, NULL, "SET key 1234"); 68 | redisAsyncCommand(ac, command_cb, NULL, "GET key"); 69 | 70 | g_main_loop_run(mainloop); 71 | 72 | return EXIT_SUCCESS; 73 | } 74 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/hiredis/examples/example-ivykis.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | void getCallback(redisAsyncContext *c, void *r, void *privdata) { 11 | redisReply *reply = r; 12 | if (reply == NULL) return; 13 | printf("argv[%s]: %s\n", (char*)privdata, reply->str); 14 | 15 | /* Disconnect after receiving the reply to GET */ 16 | redisAsyncDisconnect(c); 17 | } 18 | 19 | void connectCallback(const redisAsyncContext *c, int status) { 20 | if (status != REDIS_OK) { 21 | printf("Error: %s\n", c->errstr); 22 | return; 23 | } 24 | printf("Connected...\n"); 25 | } 26 | 27 | void disconnectCallback(const redisAsyncContext *c, int status) { 28 | if (status != REDIS_OK) { 29 | printf("Error: %s\n", c->errstr); 30 | return; 31 | } 32 | printf("Disconnected...\n"); 33 | } 34 | 35 | int main (int argc, char **argv) { 36 | signal(SIGPIPE, SIG_IGN); 37 | 38 | iv_init(); 39 | 40 | redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379); 41 | if (c->err) { 42 | /* Let *c leak for now... */ 43 | printf("Error: %s\n", c->errstr); 44 | return 1; 45 | } 46 | 47 | redisIvykisAttach(c); 48 | redisAsyncSetConnectCallback(c,connectCallback); 49 | redisAsyncSetDisconnectCallback(c,disconnectCallback); 50 | redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1])); 51 | redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); 52 | 53 | iv_main(); 54 | 55 | iv_deinit(); 56 | 57 | return 0; 58 | } 59 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/hiredis/examples/example-libev.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | void getCallback(redisAsyncContext *c, void *r, void *privdata) { 11 | redisReply *reply = r; 12 | if (reply == NULL) return; 13 | printf("argv[%s]: %s\n", (char*)privdata, reply->str); 14 | 15 | /* Disconnect after receiving the reply to GET */ 16 | redisAsyncDisconnect(c); 17 | } 18 | 19 | void connectCallback(const redisAsyncContext *c, int status) { 20 | if (status != REDIS_OK) { 21 | printf("Error: %s\n", c->errstr); 22 | return; 23 | } 24 | printf("Connected...\n"); 25 | } 26 | 27 | void disconnectCallback(const redisAsyncContext *c, int status) { 28 | if (status != REDIS_OK) { 29 | printf("Error: %s\n", c->errstr); 30 | return; 31 | } 32 | printf("Disconnected...\n"); 33 | } 34 | 35 | int main (int argc, char **argv) { 36 | signal(SIGPIPE, SIG_IGN); 37 | 38 | redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379); 39 | if (c->err) { 40 | /* Let *c leak for now... */ 41 | printf("Error: %s\n", c->errstr); 42 | return 1; 43 | } 44 | 45 | redisLibevAttach(EV_DEFAULT_ c); 46 | redisAsyncSetConnectCallback(c,connectCallback); 47 | redisAsyncSetDisconnectCallback(c,disconnectCallback); 48 | redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1])); 49 | redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); 50 | ev_loop(EV_DEFAULT_ 0); 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/hiredis/examples/example-libevent-ssl.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | void getCallback(redisAsyncContext *c, void *r, void *privdata) { 12 | redisReply *reply = r; 13 | if (reply == NULL) return; 14 | printf("argv[%s]: %s\n", (char*)privdata, reply->str); 15 | 16 | /* Disconnect after receiving the reply to GET */ 17 | redisAsyncDisconnect(c); 18 | } 19 | 20 | void connectCallback(const redisAsyncContext *c, int status) { 21 | if (status != REDIS_OK) { 22 | printf("Error: %s\n", c->errstr); 23 | return; 24 | } 25 | printf("Connected...\n"); 26 | } 27 | 28 | void disconnectCallback(const redisAsyncContext *c, int status) { 29 | if (status != REDIS_OK) { 30 | printf("Error: %s\n", c->errstr); 31 | return; 32 | } 33 | printf("Disconnected...\n"); 34 | } 35 | 36 | int main (int argc, char **argv) { 37 | signal(SIGPIPE, SIG_IGN); 38 | struct event_base *base = event_base_new(); 39 | if (argc < 5) { 40 | fprintf(stderr, 41 | "Usage: %s [ca]\n", argv[0]); 42 | exit(1); 43 | } 44 | 45 | const char *value = argv[1]; 46 | size_t nvalue = strlen(value); 47 | 48 | const char *hostname = argv[2]; 49 | int port = atoi(argv[3]); 50 | 51 | const char *cert = argv[4]; 52 | const char *certKey = argv[5]; 53 | const char *caCert = argc > 5 ? argv[6] : NULL; 54 | 55 | redisAsyncContext *c = redisAsyncConnect(hostname, port); 56 | if (c->err) { 57 | /* Let *c leak for now... */ 58 | printf("Error: %s\n", c->errstr); 59 | return 1; 60 | } 61 | if (redisSecureConnection(&c->c, caCert, cert, certKey, "sni") != REDIS_OK) { 62 | printf("SSL Error!\n"); 63 | exit(1); 64 | } 65 | 66 | redisLibeventAttach(c,base); 67 | redisAsyncSetConnectCallback(c,connectCallback); 68 | redisAsyncSetDisconnectCallback(c,disconnectCallback); 69 | redisAsyncCommand(c, NULL, NULL, "SET key %b", value, nvalue); 70 | redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); 71 | event_base_dispatch(base); 72 | return 0; 73 | } 74 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/hiredis/examples/example-libevent.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | void getCallback(redisAsyncContext *c, void *r, void *privdata) { 11 | redisReply *reply = r; 12 | if (reply == NULL) { 13 | if (c->errstr) { 14 | printf("errstr: %s\n", c->errstr); 15 | } 16 | return; 17 | } 18 | printf("argv[%s]: %s\n", (char*)privdata, reply->str); 19 | 20 | /* Disconnect after receiving the reply to GET */ 21 | redisAsyncDisconnect(c); 22 | } 23 | 24 | void connectCallback(const redisAsyncContext *c, int status) { 25 | if (status != REDIS_OK) { 26 | printf("Error: %s\n", c->errstr); 27 | return; 28 | } 29 | printf("Connected...\n"); 30 | } 31 | 32 | void disconnectCallback(const redisAsyncContext *c, int status) { 33 | if (status != REDIS_OK) { 34 | printf("Error: %s\n", c->errstr); 35 | return; 36 | } 37 | printf("Disconnected...\n"); 38 | } 39 | 40 | int main (int argc, char **argv) { 41 | signal(SIGPIPE, SIG_IGN); 42 | struct event_base *base = event_base_new(); 43 | redisOptions options = {0}; 44 | REDIS_OPTIONS_SET_TCP(&options, "127.0.0.1", 6379); 45 | struct timeval tv = {0}; 46 | tv.tv_sec = 1; 47 | options.timeout = &tv; 48 | 49 | 50 | redisAsyncContext *c = redisAsyncConnectWithOptions(&options); 51 | if (c->err) { 52 | /* Let *c leak for now... */ 53 | printf("Error: %s\n", c->errstr); 54 | return 1; 55 | } 56 | 57 | redisLibeventAttach(c,base); 58 | redisAsyncSetConnectCallback(c,connectCallback); 59 | redisAsyncSetDisconnectCallback(c,disconnectCallback); 60 | redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1])); 61 | redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); 62 | event_base_dispatch(base); 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/hiredis/examples/example-libuv.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | void getCallback(redisAsyncContext *c, void *r, void *privdata) { 11 | redisReply *reply = r; 12 | if (reply == NULL) return; 13 | printf("argv[%s]: %s\n", (char*)privdata, reply->str); 14 | 15 | /* Disconnect after receiving the reply to GET */ 16 | redisAsyncDisconnect(c); 17 | } 18 | 19 | void connectCallback(const redisAsyncContext *c, int status) { 20 | if (status != REDIS_OK) { 21 | printf("Error: %s\n", c->errstr); 22 | return; 23 | } 24 | printf("Connected...\n"); 25 | } 26 | 27 | void disconnectCallback(const redisAsyncContext *c, int status) { 28 | if (status != REDIS_OK) { 29 | printf("Error: %s\n", c->errstr); 30 | return; 31 | } 32 | printf("Disconnected...\n"); 33 | } 34 | 35 | int main (int argc, char **argv) { 36 | signal(SIGPIPE, SIG_IGN); 37 | uv_loop_t* loop = uv_default_loop(); 38 | 39 | redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379); 40 | if (c->err) { 41 | /* Let *c leak for now... */ 42 | printf("Error: %s\n", c->errstr); 43 | return 1; 44 | } 45 | 46 | redisLibuvAttach(c,loop); 47 | redisAsyncSetConnectCallback(c,connectCallback); 48 | redisAsyncSetDisconnectCallback(c,disconnectCallback); 49 | redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1])); 50 | redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); 51 | uv_run(loop, UV_RUN_DEFAULT); 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/hiredis/examples/example-macosx.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Дмитрий Бахвалов on 13.07.15. 3 | // Copyright (c) 2015 Dmitry Bakhvalov. All rights reserved. 4 | // 5 | 6 | #include 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | void getCallback(redisAsyncContext *c, void *r, void *privdata) { 13 | redisReply *reply = r; 14 | if (reply == NULL) return; 15 | printf("argv[%s]: %s\n", (char*)privdata, reply->str); 16 | 17 | /* Disconnect after receiving the reply to GET */ 18 | redisAsyncDisconnect(c); 19 | } 20 | 21 | void connectCallback(const redisAsyncContext *c, int status) { 22 | if (status != REDIS_OK) { 23 | printf("Error: %s\n", c->errstr); 24 | return; 25 | } 26 | printf("Connected...\n"); 27 | } 28 | 29 | void disconnectCallback(const redisAsyncContext *c, int status) { 30 | if (status != REDIS_OK) { 31 | printf("Error: %s\n", c->errstr); 32 | return; 33 | } 34 | CFRunLoopStop(CFRunLoopGetCurrent()); 35 | printf("Disconnected...\n"); 36 | } 37 | 38 | int main (int argc, char **argv) { 39 | signal(SIGPIPE, SIG_IGN); 40 | 41 | CFRunLoopRef loop = CFRunLoopGetCurrent(); 42 | if( !loop ) { 43 | printf("Error: Cannot get current run loop\n"); 44 | return 1; 45 | } 46 | 47 | redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379); 48 | if (c->err) { 49 | /* Let *c leak for now... */ 50 | printf("Error: %s\n", c->errstr); 51 | return 1; 52 | } 53 | 54 | redisMacOSAttach(c, loop); 55 | 56 | redisAsyncSetConnectCallback(c,connectCallback); 57 | redisAsyncSetDisconnectCallback(c,disconnectCallback); 58 | 59 | redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1])); 60 | redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); 61 | 62 | CFRunLoopRun(); 63 | 64 | return 0; 65 | } 66 | 67 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/hiredis/examples/example-qt.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | #include 5 | #include 6 | 7 | #include "example-qt.h" 8 | 9 | void getCallback(redisAsyncContext *, void * r, void * privdata) { 10 | 11 | redisReply * reply = static_cast(r); 12 | ExampleQt * ex = static_cast(privdata); 13 | if (reply == nullptr || ex == nullptr) return; 14 | 15 | cout << "key: " << reply->str << endl; 16 | 17 | ex->finish(); 18 | } 19 | 20 | void ExampleQt::run() { 21 | 22 | m_ctx = redisAsyncConnect("localhost", 6379); 23 | 24 | if (m_ctx->err) { 25 | cerr << "Error: " << m_ctx->errstr << endl; 26 | redisAsyncFree(m_ctx); 27 | emit finished(); 28 | } 29 | 30 | m_adapter.setContext(m_ctx); 31 | 32 | redisAsyncCommand(m_ctx, NULL, NULL, "SET key %s", m_value); 33 | redisAsyncCommand(m_ctx, getCallback, this, "GET key"); 34 | } 35 | 36 | int main (int argc, char **argv) { 37 | 38 | QCoreApplication app(argc, argv); 39 | 40 | ExampleQt example(argv[argc-1]); 41 | 42 | QObject::connect(&example, SIGNAL(finished()), &app, SLOT(quit())); 43 | QTimer::singleShot(0, &example, SLOT(run())); 44 | 45 | return app.exec(); 46 | } 47 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/hiredis/examples/example-qt.h: -------------------------------------------------------------------------------- 1 | #ifndef __HIREDIS_EXAMPLE_QT_H 2 | #define __HIREDIS_EXAMPLE_QT_H 3 | 4 | #include 5 | 6 | class ExampleQt : public QObject { 7 | 8 | Q_OBJECT 9 | 10 | public: 11 | ExampleQt(const char * value, QObject * parent = 0) 12 | : QObject(parent), m_value(value) {} 13 | 14 | signals: 15 | void finished(); 16 | 17 | public slots: 18 | void run(); 19 | 20 | private: 21 | void finish() { emit finished(); } 22 | 23 | private: 24 | const char * m_value; 25 | redisAsyncContext * m_ctx; 26 | RedisQtAdapter m_adapter; 27 | 28 | friend 29 | void getCallback(redisAsyncContext *, void *, void *); 30 | }; 31 | 32 | #endif /* !__HIREDIS_EXAMPLE_QT_H */ 33 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/hiredis/examples/example-ssl.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | int main(int argc, char **argv) { 9 | unsigned int j; 10 | redisContext *c; 11 | redisReply *reply; 12 | if (argc < 4) { 13 | printf("Usage: %s [ca]\n", argv[0]); 14 | exit(1); 15 | } 16 | const char *hostname = (argc > 1) ? argv[1] : "127.0.0.1"; 17 | int port = atoi(argv[2]); 18 | const char *cert = argv[3]; 19 | const char *key = argv[4]; 20 | const char *ca = argc > 4 ? argv[5] : NULL; 21 | 22 | struct timeval tv = { 1, 500000 }; // 1.5 seconds 23 | redisOptions options = {0}; 24 | REDIS_OPTIONS_SET_TCP(&options, hostname, port); 25 | options.timeout = &tv; 26 | c = redisConnectWithOptions(&options); 27 | 28 | if (c == NULL || c->err) { 29 | if (c) { 30 | printf("Connection error: %s\n", c->errstr); 31 | redisFree(c); 32 | } else { 33 | printf("Connection error: can't allocate redis context\n"); 34 | } 35 | exit(1); 36 | } 37 | 38 | if (redisSecureConnection(c, ca, cert, key, "sni") != REDIS_OK) { 39 | printf("Couldn't initialize SSL!\n"); 40 | printf("Error: %s\n", c->errstr); 41 | redisFree(c); 42 | exit(1); 43 | } 44 | 45 | /* PING server */ 46 | reply = redisCommand(c,"PING"); 47 | printf("PING: %s\n", reply->str); 48 | freeReplyObject(reply); 49 | 50 | /* Set a key */ 51 | reply = redisCommand(c,"SET %s %s", "foo", "hello world"); 52 | printf("SET: %s\n", reply->str); 53 | freeReplyObject(reply); 54 | 55 | /* Set a key using binary safe API */ 56 | reply = redisCommand(c,"SET %b %b", "bar", (size_t) 3, "hello", (size_t) 5); 57 | printf("SET (binary API): %s\n", reply->str); 58 | freeReplyObject(reply); 59 | 60 | /* Try a GET and two INCR */ 61 | reply = redisCommand(c,"GET foo"); 62 | printf("GET foo: %s\n", reply->str); 63 | freeReplyObject(reply); 64 | 65 | reply = redisCommand(c,"INCR counter"); 66 | printf("INCR counter: %lld\n", reply->integer); 67 | freeReplyObject(reply); 68 | /* again ... */ 69 | reply = redisCommand(c,"INCR counter"); 70 | printf("INCR counter: %lld\n", reply->integer); 71 | freeReplyObject(reply); 72 | 73 | /* Create a list of numbers, from 0 to 9 */ 74 | reply = redisCommand(c,"DEL mylist"); 75 | freeReplyObject(reply); 76 | for (j = 0; j < 10; j++) { 77 | char buf[64]; 78 | 79 | snprintf(buf,64,"%u",j); 80 | reply = redisCommand(c,"LPUSH mylist element-%s", buf); 81 | freeReplyObject(reply); 82 | } 83 | 84 | /* Let's check what we have inside the list */ 85 | reply = redisCommand(c,"LRANGE mylist 0 -1"); 86 | if (reply->type == REDIS_REPLY_ARRAY) { 87 | for (j = 0; j < reply->elements; j++) { 88 | printf("%u) %s\n", j, reply->element[j]->str); 89 | } 90 | } 91 | freeReplyObject(reply); 92 | 93 | /* Disconnects and frees the context */ 94 | redisFree(c); 95 | 96 | return 0; 97 | } 98 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/hiredis/examples/example.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | 7 | int main(int argc, char **argv) { 8 | unsigned int j, isunix = 0; 9 | redisContext *c; 10 | redisReply *reply; 11 | const char *hostname = (argc > 1) ? argv[1] : "127.0.0.1"; 12 | 13 | if (argc > 2) { 14 | if (*argv[2] == 'u' || *argv[2] == 'U') { 15 | isunix = 1; 16 | /* in this case, host is the path to the unix socket */ 17 | printf("Will connect to unix socket @%s\n", hostname); 18 | } 19 | } 20 | 21 | int port = (argc > 2) ? atoi(argv[2]) : 6379; 22 | 23 | struct timeval timeout = { 1, 500000 }; // 1.5 seconds 24 | if (isunix) { 25 | c = redisConnectUnixWithTimeout(hostname, timeout); 26 | } else { 27 | c = redisConnectWithTimeout(hostname, port, timeout); 28 | } 29 | if (c == NULL || c->err) { 30 | if (c) { 31 | printf("Connection error: %s\n", c->errstr); 32 | redisFree(c); 33 | } else { 34 | printf("Connection error: can't allocate redis context\n"); 35 | } 36 | exit(1); 37 | } 38 | 39 | /* PING server */ 40 | reply = redisCommand(c,"PING"); 41 | printf("PING: %s\n", reply->str); 42 | freeReplyObject(reply); 43 | 44 | /* Set a key */ 45 | reply = redisCommand(c,"SET %s %s", "foo", "hello world"); 46 | printf("SET: %s\n", reply->str); 47 | freeReplyObject(reply); 48 | 49 | /* Set a key using binary safe API */ 50 | reply = redisCommand(c,"SET %b %b", "bar", (size_t) 3, "hello", (size_t) 5); 51 | printf("SET (binary API): %s\n", reply->str); 52 | freeReplyObject(reply); 53 | 54 | /* Try a GET and two INCR */ 55 | reply = redisCommand(c,"GET foo"); 56 | printf("GET foo: %s\n", reply->str); 57 | freeReplyObject(reply); 58 | 59 | reply = redisCommand(c,"INCR counter"); 60 | printf("INCR counter: %lld\n", reply->integer); 61 | freeReplyObject(reply); 62 | /* again ... */ 63 | reply = redisCommand(c,"INCR counter"); 64 | printf("INCR counter: %lld\n", reply->integer); 65 | freeReplyObject(reply); 66 | 67 | /* Create a list of numbers, from 0 to 9 */ 68 | reply = redisCommand(c,"DEL mylist"); 69 | freeReplyObject(reply); 70 | for (j = 0; j < 10; j++) { 71 | char buf[64]; 72 | 73 | snprintf(buf,64,"%u",j); 74 | reply = redisCommand(c,"LPUSH mylist element-%s", buf); 75 | freeReplyObject(reply); 76 | } 77 | 78 | /* Let's check what we have inside the list */ 79 | reply = redisCommand(c,"LRANGE mylist 0 -1"); 80 | if (reply->type == REDIS_REPLY_ARRAY) { 81 | for (j = 0; j < reply->elements; j++) { 82 | printf("%u) %s\n", j, reply->element[j]->str); 83 | } 84 | } 85 | freeReplyObject(reply); 86 | 87 | /* Disconnects and frees the context */ 88 | redisFree(c); 89 | 90 | return 0; 91 | } 92 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/hiredis/fmacros.h: -------------------------------------------------------------------------------- 1 | #ifndef __HIREDIS_FMACRO_H 2 | #define __HIREDIS_FMACRO_H 3 | 4 | #define _XOPEN_SOURCE 600 5 | #define _POSIX_C_SOURCE 200112L 6 | 7 | #if defined(__APPLE__) && defined(__MACH__) 8 | /* Enable TCP_KEEPALIVE */ 9 | #define _DARWIN_C_SOURCE 10 | #endif 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/hiredis/hiredis.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@CMAKE_INSTALL_PREFIX@ 2 | exec_prefix=${prefix} 3 | libdir=${exec_prefix}/lib 4 | includedir=${prefix}/include 5 | pkgincludedir=${includedir}/hiredis 6 | 7 | Name: hiredis 8 | Description: Minimalistic C client library for Redis. 9 | Version: @PROJECT_VERSION@ 10 | Libs: -L${libdir} -lhiredis 11 | Cflags: -I${pkgincludedir} -D_FILE_OFFSET_BITS=64 12 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/hiredis/hiredis_ssl.h: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Copyright (c) 2019, Redis Labs 4 | * 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the above copyright notice, 11 | * this list of conditions and the following disclaimer. 12 | * * Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * * Neither the name of Redis nor the names of its contributors may be used 16 | * to endorse or promote products derived from this software without 17 | * specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 23 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 | * POSSIBILITY OF SUCH DAMAGE. 30 | */ 31 | 32 | #ifndef __HIREDIS_SSL_H 33 | #define __HIREDIS_SSL_H 34 | 35 | /* This is the underlying struct for SSL in ssl.h, which is not included to 36 | * keep build dependencies short here. 37 | */ 38 | struct ssl_st; 39 | 40 | /** 41 | * Secure the connection using SSL. This should be done before any command is 42 | * executed on the connection. 43 | */ 44 | int redisSecureConnection(redisContext *c, const char *capath, const char *certpath, 45 | const char *keypath, const char *servername); 46 | 47 | /** 48 | * Initiate SSL/TLS negotiation on a provided context. 49 | */ 50 | 51 | int redisInitiateSSL(redisContext *c, struct ssl_st *ssl); 52 | 53 | #endif /* __HIREDIS_SSL_H */ 54 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/hiredis/hiredis_ssl.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@CMAKE_INSTALL_PREFIX@ 2 | exec_prefix=${prefix} 3 | libdir=${exec_prefix}/lib 4 | includedir=${prefix}/include 5 | pkgincludedir=${includedir}/hiredis 6 | 7 | Name: hiredis_ssl 8 | Description: SSL Support for hiredis. 9 | Version: @PROJECT_VERSION@ 10 | Requires: hiredis 11 | Libs: -L${libdir} -lhiredis_ssl 12 | Libs.private: -lssl -lcrypto 13 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/hiredis/net.h: -------------------------------------------------------------------------------- 1 | /* Extracted from anet.c to work properly with Hiredis error reporting. 2 | * 3 | * Copyright (c) 2009-2011, Salvatore Sanfilippo 4 | * Copyright (c) 2010-2014, Pieter Noordhuis 5 | * Copyright (c) 2015, Matt Stancliff , 6 | * Jan-Erik Rediger 7 | * 8 | * All rights reserved. 9 | * 10 | * Redistribution and use in source and binary forms, with or without 11 | * modification, are permitted provided that the following conditions are met: 12 | * 13 | * * Redistributions of source code must retain the above copyright notice, 14 | * this list of conditions and the following disclaimer. 15 | * * Redistributions in binary form must reproduce the above copyright 16 | * notice, this list of conditions and the following disclaimer in the 17 | * documentation and/or other materials provided with the distribution. 18 | * * Neither the name of Redis nor the names of its contributors may be used 19 | * to endorse or promote products derived from this software without 20 | * specific prior written permission. 21 | * 22 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 23 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 26 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 27 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 28 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 29 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 30 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32 | * POSSIBILITY OF SUCH DAMAGE. 33 | */ 34 | 35 | #ifndef __NET_H 36 | #define __NET_H 37 | 38 | #include "hiredis.h" 39 | 40 | void redisNetClose(redisContext *c); 41 | int redisNetRead(redisContext *c, char *buf, size_t bufcap); 42 | int redisNetWrite(redisContext *c); 43 | 44 | int redisCheckSocketError(redisContext *c); 45 | int redisContextSetTimeout(redisContext *c, const struct timeval tv); 46 | int redisContextConnectTcp(redisContext *c, const char *addr, int port, const struct timeval *timeout); 47 | int redisContextConnectBindTcp(redisContext *c, const char *addr, int port, 48 | const struct timeval *timeout, 49 | const char *source_addr); 50 | int redisContextConnectUnix(redisContext *c, const char *path, const struct timeval *timeout); 51 | int redisKeepAlive(redisContext *c, int interval); 52 | int redisCheckConnectDone(redisContext *c, int *completed); 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/hiredis/sdsalloc.h: -------------------------------------------------------------------------------- 1 | /* SDSLib 2.0 -- A C dynamic strings library 2 | * 3 | * Copyright (c) 2006-2015, Salvatore Sanfilippo 4 | * Copyright (c) 2015, Oran Agra 5 | * Copyright (c) 2015, Redis Labs, Inc 6 | * All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions are met: 10 | * 11 | * * Redistributions of source code must retain the above copyright notice, 12 | * this list of conditions and the following disclaimer. 13 | * * Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * * Neither the name of Redis nor the names of its contributors may be used 17 | * to endorse or promote products derived from this software without 18 | * specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 24 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 | * POSSIBILITY OF SUCH DAMAGE. 31 | */ 32 | 33 | /* SDS allocator selection. 34 | * 35 | * This file is used in order to change the SDS allocator at compile time. 36 | * Just define the following defines to what you want to use. Also add 37 | * the include of your alternate allocator if needed (not needed in order 38 | * to use the default libc allocator). */ 39 | 40 | #define s_malloc malloc 41 | #define s_realloc realloc 42 | #define s_free free 43 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/hiredis/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -ue 2 | 3 | REDIS_SERVER=${REDIS_SERVER:-redis-server} 4 | REDIS_PORT=${REDIS_PORT:-56379} 5 | REDIS_SSL_PORT=${REDIS_SSL_PORT:-56443} 6 | TEST_SSL=${TEST_SSL:-0} 7 | SSL_TEST_ARGS= 8 | 9 | tmpdir=$(mktemp -d) 10 | PID_FILE=${tmpdir}/hiredis-test-redis.pid 11 | SOCK_FILE=${tmpdir}/hiredis-test-redis.sock 12 | 13 | if [ "$TEST_SSL" = "1" ]; then 14 | SSL_CA_CERT=${tmpdir}/ca.crt 15 | SSL_CA_KEY=${tmpdir}/ca.key 16 | SSL_CERT=${tmpdir}/redis.crt 17 | SSL_KEY=${tmpdir}/redis.key 18 | 19 | openssl genrsa -out ${tmpdir}/ca.key 4096 20 | openssl req \ 21 | -x509 -new -nodes -sha256 \ 22 | -key ${SSL_CA_KEY} \ 23 | -days 3650 \ 24 | -subj '/CN=Hiredis Test CA' \ 25 | -out ${SSL_CA_CERT} 26 | openssl genrsa -out ${SSL_KEY} 2048 27 | openssl req \ 28 | -new -sha256 \ 29 | -key ${SSL_KEY} \ 30 | -subj '/CN=Hiredis Test Cert' | \ 31 | openssl x509 \ 32 | -req -sha256 \ 33 | -CA ${SSL_CA_CERT} \ 34 | -CAkey ${SSL_CA_KEY} \ 35 | -CAserial ${tmpdir}/ca.txt \ 36 | -CAcreateserial \ 37 | -days 365 \ 38 | -out ${SSL_CERT} 39 | 40 | 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}" 41 | fi 42 | 43 | cleanup() { 44 | set +e 45 | kill $(cat ${PID_FILE}) 46 | rm -rf ${tmpdir} 47 | } 48 | trap cleanup INT TERM EXIT 49 | 50 | cat > ${tmpdir}/redis.conf <> ${tmpdir}/redis.conf < /* for struct timeval */ 6 | 7 | #ifndef inline 8 | #define inline __inline 9 | #endif 10 | 11 | #ifndef strcasecmp 12 | #define strcasecmp stricmp 13 | #endif 14 | 15 | #ifndef strncasecmp 16 | #define strncasecmp strnicmp 17 | #endif 18 | 19 | #ifndef va_copy 20 | #define va_copy(d,s) ((d) = (s)) 21 | #endif 22 | 23 | #ifndef snprintf 24 | #define snprintf c99_snprintf 25 | 26 | __inline int c99_vsnprintf(char* str, size_t size, const char* format, va_list ap) 27 | { 28 | int count = -1; 29 | 30 | if (size != 0) 31 | count = _vsnprintf_s(str, size, _TRUNCATE, format, ap); 32 | if (count == -1) 33 | count = _vscprintf(format, ap); 34 | 35 | return count; 36 | } 37 | 38 | __inline int c99_snprintf(char* str, size_t size, const char* format, ...) 39 | { 40 | int count; 41 | va_list ap; 42 | 43 | va_start(ap, format); 44 | count = c99_vsnprintf(str, size, format, ap); 45 | va_end(ap); 46 | 47 | return count; 48 | } 49 | #endif 50 | #endif /* _MSC_VER */ 51 | 52 | #ifdef _WIN32 53 | #define strerror_r(errno,buf,len) strerror_s(buf,len,errno) 54 | #endif /* _WIN32 */ 55 | 56 | #endif /* _WIN32_HELPER_INCLUDE */ 57 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/.appveyor.yml: -------------------------------------------------------------------------------- 1 | configuration: 2 | - Debug 3 | - Release 4 | 5 | environment: 6 | matrix: 7 | - generator: "Visual Studio 14 2015" 8 | - generator: "Visual Studio 14 2015 Win64" 9 | - generator: "Visual Studio 10 2010" 10 | - generator: "Visual Studio 10 2010 Win64" 11 | - generator: "MinGW Makefiles" 12 | dialect: mingw 13 | - generator: "MinGW Makefiles" 14 | dialect: mingw-w64 15 | 16 | matrix: 17 | fast_finish: true 18 | 19 | shallow_clone: true 20 | 21 | before_build: 22 | # Workaround for CMake not wanting sh.exe on PATH for MinGW 23 | - set PATH=%PATH:C:\Program Files\Git\usr\bin;=% 24 | - if "%dialect%"=="mingw" set PATH=c:\MinGW\bin;%PATH% 25 | - if "%dialect%"=="mingw-w64" set PATH=c:\msys64\mingw64\bin;%PATH% 26 | - cmake -H. -Bbuild -G"%generator%" -DCMAKE_BUILD_TYPE=%configuration% 27 | 28 | build_script: 29 | - if "%generator:~0,6%"=="Visual" set CMAKE_BUILD_FLAGS=--config %configuration% -- /m /v:m 30 | - if "%generator:~0,5%"=="MinGW" set CMAKE_BUILD_FLAGS=-- -j 31 | - cmake --build build %CMAKE_BUILD_FLAGS% -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2.0 2 | jobs: 3 | build: 4 | docker: 5 | - image: sergiusthebest/rtems-arm-rasberrypi-ci:latest 6 | steps: 7 | - checkout 8 | - run: cmake -H. -Bbuild -DCMAKE_TOOLCHAIN_FILE=$CMAKE_TOOLCHAIN_FILE && cd build && make -j -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/.cirrus.yml: -------------------------------------------------------------------------------- 1 | task: 2 | name: FreeBSD 3 | freebsd_instance: 4 | matrix: 5 | image_family: freebsd-12-1 6 | matrix: 7 | env: 8 | BUILD_TYPE: Debug 9 | env: 10 | BUILD_TYPE: Release 11 | install_script: pkg install -y cmake 12 | compile_script: cmake -H. -Bbuild -DCMAKE_BUILD_TYPE=$BUILD_TYPE && cmake --build build -- -j4 13 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # editorconfig.org 4 | 5 | root = true 6 | 7 | [*] 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | indent_style = space 11 | indent_size = 4 12 | 13 | [*.md] 14 | trim_trailing_whitespace = false 15 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | .vscode 3 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/.travis.yml: -------------------------------------------------------------------------------- 1 | language: cpp 2 | 3 | compiler: 4 | - gcc 5 | - clang 6 | 7 | env: 8 | - BUILD_TYPE=Debug 9 | - BUILD_TYPE=Release 10 | 11 | addons: 12 | apt: 13 | packages: 14 | - gobjc++ 15 | 16 | script: 17 | - cmake -H. -Bbuild -DCMAKE_BUILD_TYPE=$BUILD_TYPE 18 | - cd build 19 | - make -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8) 2 | 3 | option(PLOG_BUILD_SAMPLES "Build plog's samples." ON) 4 | 5 | project(plog LANGUAGES CXX) 6 | 7 | # Make sure install paths work on all platforms. 8 | if(NOT CMAKE_INSTALL_INCLUDEDIR) 9 | include(GNUInstallDirs) 10 | endif() 11 | 12 | add_library(plog INTERFACE) 13 | target_include_directories(plog 14 | INTERFACE 15 | $ 16 | $ 17 | ) 18 | 19 | add_library(plog::plog ALIAS plog) 20 | 21 | #making sure we can build standalone under windows 22 | get_filename_component(CURRENT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR} ABSOLUTE) 23 | get_filename_component(SOURCE_DIR ${CMAKE_SOURCE_DIR} ABSOLUTE) 24 | 25 | # check if building as a stand-alone project 26 | if(${CURRENT_SOURCE_DIR} STREQUAL ${SOURCE_DIR} AND PLOG_BUILD_SAMPLES) 27 | # add a pseudo-project to make plog headers visible in IDE 28 | file(GLOB_RECURSE PLOG_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/include/*.h) 29 | add_library(plog-headers STATIC ${PLOG_HEADERS}) 30 | set_target_properties(plog-headers PROPERTIES LINKER_LANGUAGE CXX) 31 | set_target_properties(plog-headers PROPERTIES FOLDER Include) 32 | 33 | # add samples 34 | add_subdirectory(samples) 35 | endif() 36 | 37 | install( 38 | DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/plog 39 | DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} 40 | FILES_MATCHING # headers only 41 | PATTERN "*.h" 42 | ) 43 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/include/plog/Appenders/AndroidAppender.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | namespace plog 6 | { 7 | template 8 | class AndroidAppender : public IAppender 9 | { 10 | public: 11 | AndroidAppender(const char* tag) : m_tag(tag) 12 | { 13 | } 14 | 15 | virtual void write(const Record& record) 16 | { 17 | std::string str = Formatter::format(record); 18 | 19 | __android_log_print(toPriority(record.getSeverity()), m_tag, "%s", str.c_str()); 20 | } 21 | 22 | private: 23 | static android_LogPriority toPriority(Severity severity) 24 | { 25 | switch (severity) 26 | { 27 | case fatal: 28 | return ANDROID_LOG_FATAL; 29 | case error: 30 | return ANDROID_LOG_ERROR; 31 | case warning: 32 | return ANDROID_LOG_WARN; 33 | case info: 34 | return ANDROID_LOG_INFO; 35 | case debug: 36 | return ANDROID_LOG_DEBUG; 37 | case verbose: 38 | return ANDROID_LOG_VERBOSE; 39 | default: 40 | return ANDROID_LOG_UNKNOWN; 41 | } 42 | } 43 | 44 | private: 45 | const char* const m_tag; 46 | }; 47 | } 48 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/include/plog/Appenders/ColorConsoleAppender.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | namespace plog 6 | { 7 | template 8 | class ColorConsoleAppender : public ConsoleAppender 9 | { 10 | public: 11 | #ifdef _WIN32 12 | ColorConsoleAppender() : m_originalAttr() 13 | { 14 | if (this->m_isatty) 15 | { 16 | CONSOLE_SCREEN_BUFFER_INFO csbiInfo; 17 | GetConsoleScreenBufferInfo(this->m_stdoutHandle, &csbiInfo); 18 | 19 | m_originalAttr = csbiInfo.wAttributes; 20 | } 21 | } 22 | #else 23 | ColorConsoleAppender() {} 24 | #endif 25 | 26 | virtual void write(const Record& record) 27 | { 28 | util::nstring str = Formatter::format(record); 29 | util::MutexLock lock(this->m_mutex); 30 | 31 | setColor(record.getSeverity()); 32 | this->writestr(str); 33 | resetColor(); 34 | } 35 | 36 | private: 37 | void setColor(Severity severity) 38 | { 39 | if (this->m_isatty) 40 | { 41 | switch (severity) 42 | { 43 | #ifdef _WIN32 44 | case fatal: 45 | SetConsoleTextAttribute(this->m_stdoutHandle, foreground::kRed | foreground::kGreen | foreground::kBlue | foreground::kIntensity | background::kRed); // white on red background 46 | break; 47 | 48 | case error: 49 | SetConsoleTextAttribute(this->m_stdoutHandle, static_cast(foreground::kRed | foreground::kIntensity | (m_originalAttr & 0xf0))); // red 50 | break; 51 | 52 | case warning: 53 | SetConsoleTextAttribute(this->m_stdoutHandle, static_cast(foreground::kRed | foreground::kGreen | foreground::kIntensity | (m_originalAttr & 0xf0))); // yellow 54 | break; 55 | 56 | case debug: 57 | case verbose: 58 | SetConsoleTextAttribute(this->m_stdoutHandle, static_cast(foreground::kGreen | foreground::kBlue | foreground::kIntensity | (m_originalAttr & 0xf0))); // cyan 59 | break; 60 | #else 61 | case fatal: 62 | std::cout << "\x1B[97m\x1B[41m"; // white on red background 63 | break; 64 | 65 | case error: 66 | std::cout << "\x1B[91m"; // red 67 | break; 68 | 69 | case warning: 70 | std::cout << "\x1B[93m"; // yellow 71 | break; 72 | 73 | case debug: 74 | case verbose: 75 | std::cout << "\x1B[96m"; // cyan 76 | break; 77 | #endif 78 | default: 79 | break; 80 | } 81 | } 82 | } 83 | 84 | void resetColor() 85 | { 86 | if (this->m_isatty) 87 | { 88 | #ifdef _WIN32 89 | SetConsoleTextAttribute(this->m_stdoutHandle, m_originalAttr); 90 | #else 91 | std::cout << "\x1B[0m\x1B[0K"; 92 | #endif 93 | } 94 | } 95 | 96 | private: 97 | #ifdef _WIN32 98 | WORD m_originalAttr; 99 | #endif 100 | }; 101 | } 102 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/include/plog/Appenders/ConsoleAppender.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | namespace plog 8 | { 9 | template 10 | class ConsoleAppender : public IAppender 11 | { 12 | public: 13 | #ifdef _WIN32 14 | ConsoleAppender() : m_isatty(!!_isatty(_fileno(stdout))), m_stdoutHandle() 15 | { 16 | if (m_isatty) 17 | { 18 | m_stdoutHandle = GetStdHandle(stdHandle::kOutput); 19 | } 20 | } 21 | #else 22 | ConsoleAppender() : m_isatty(!!isatty(fileno(stdout))) {} 23 | #endif 24 | 25 | virtual void write(const Record& record) 26 | { 27 | util::nstring str = Formatter::format(record); 28 | util::MutexLock lock(m_mutex); 29 | 30 | writestr(str); 31 | } 32 | 33 | protected: 34 | void writestr(const util::nstring& str) 35 | { 36 | #ifdef _WIN32 37 | if (m_isatty) 38 | { 39 | WriteConsoleW(m_stdoutHandle, str.c_str(), static_cast(str.size()), NULL, NULL); 40 | } 41 | else 42 | { 43 | std::cout << util::toNarrow(str, codePage::kActive) << std::flush; 44 | } 45 | #else 46 | std::cout << str << std::flush; 47 | #endif 48 | } 49 | 50 | private: 51 | #ifdef __BORLANDC__ 52 | static int _isatty(int fd) { return ::isatty(fd); } 53 | #endif 54 | 55 | protected: 56 | util::Mutex m_mutex; 57 | const bool m_isatty; 58 | #ifdef _WIN32 59 | HANDLE m_stdoutHandle; 60 | #endif 61 | }; 62 | } 63 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/include/plog/Appenders/DebugOutputAppender.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | namespace plog 6 | { 7 | template 8 | class DebugOutputAppender : public IAppender 9 | { 10 | public: 11 | virtual void write(const Record& record) 12 | { 13 | OutputDebugStringW(Formatter::format(record).c_str()); 14 | } 15 | }; 16 | } 17 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/include/plog/Appenders/IAppender.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace plog 5 | { 6 | class IAppender 7 | { 8 | public: 9 | virtual ~IAppender() 10 | { 11 | } 12 | 13 | virtual void write(const Record& record) = 0; 14 | }; 15 | } 16 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/include/plog/Converters/NativeEOLConverter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | namespace plog 6 | { 7 | template 8 | class NativeEOLConverter : public NextConverter 9 | { 10 | #ifdef _WIN32 11 | public: 12 | static std::string header(const util::nstring& str) 13 | { 14 | return NextConverter::header(fixLineEndings(str)); 15 | } 16 | 17 | static std::string convert(const util::nstring& str) 18 | { 19 | return NextConverter::convert(fixLineEndings(str)); 20 | } 21 | 22 | private: 23 | static std::wstring fixLineEndings(const std::wstring& str) 24 | { 25 | std::wstring output; 26 | output.reserve(str.length() * 2); 27 | 28 | for (size_t i = 0; i < str.size(); ++i) 29 | { 30 | wchar_t ch = str[i]; 31 | 32 | if (ch == L'\n') 33 | { 34 | output.push_back(L'\r'); 35 | } 36 | 37 | output.push_back(ch); 38 | } 39 | 40 | return output; 41 | } 42 | #endif 43 | }; 44 | } 45 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/include/plog/Converters/UTF8Converter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace plog 5 | { 6 | class UTF8Converter 7 | { 8 | public: 9 | static std::string header(const util::nstring& str) 10 | { 11 | const char kBOM[] = "\xEF\xBB\xBF"; 12 | 13 | return std::string(kBOM) + convert(str); 14 | } 15 | 16 | #ifdef _WIN32 17 | static std::string convert(const util::nstring& str) 18 | { 19 | return util::toNarrow(str, codePage::kUTF8); 20 | } 21 | #else 22 | static const std::string& convert(const util::nstring& str) 23 | { 24 | return str; 25 | } 26 | #endif 27 | }; 28 | } 29 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/include/plog/Formatters/CsvFormatter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | 6 | namespace plog 7 | { 8 | template 9 | class CsvFormatterImpl 10 | { 11 | public: 12 | static util::nstring header() 13 | { 14 | return PLOG_NSTR("Date;Time;Severity;TID;This;Function;Message\n"); 15 | } 16 | 17 | static util::nstring format(const Record& record) 18 | { 19 | tm t; 20 | (useUtcTime ? util::gmtime_s : util::localtime_s)(&t, &record.getTime().time); 21 | 22 | util::nostringstream ss; 23 | ss << t.tm_year + 1900 << PLOG_NSTR("/") << std::setfill(PLOG_NSTR('0')) << std::setw(2) << t.tm_mon + 1 << PLOG_NSTR("/") << std::setfill(PLOG_NSTR('0')) << std::setw(2) << t.tm_mday << PLOG_NSTR(";"); 24 | ss << std::setfill(PLOG_NSTR('0')) << std::setw(2) << t.tm_hour << PLOG_NSTR(":") << std::setfill(PLOG_NSTR('0')) << std::setw(2) << t.tm_min << PLOG_NSTR(":") << std::setfill(PLOG_NSTR('0')) << std::setw(2) << t.tm_sec << PLOG_NSTR(".") << std::setfill(PLOG_NSTR('0')) << std::setw(3) << record.getTime().millitm << PLOG_NSTR(";"); 25 | ss << severityToString(record.getSeverity()) << PLOG_NSTR(";"); 26 | ss << record.getTid() << PLOG_NSTR(";"); 27 | ss << record.getObject() << PLOG_NSTR(";"); 28 | ss << record.getFunc() << PLOG_NSTR("@") << record.getLine() << PLOG_NSTR(";"); 29 | 30 | util::nstring message = record.getMessage(); 31 | 32 | if (message.size() > kMaxMessageSize) 33 | { 34 | message.resize(kMaxMessageSize); 35 | message.append(PLOG_NSTR("...")); 36 | } 37 | 38 | util::nistringstream split(message); 39 | util::nstring token; 40 | 41 | while (!split.eof()) 42 | { 43 | std::getline(split, token, PLOG_NSTR('"')); 44 | ss << PLOG_NSTR("\"") << token << PLOG_NSTR("\""); 45 | } 46 | 47 | ss << PLOG_NSTR("\n"); 48 | 49 | return ss.str(); 50 | } 51 | 52 | static const size_t kMaxMessageSize = 32000; 53 | }; 54 | 55 | class CsvFormatter : public CsvFormatterImpl {}; 56 | class CsvFormatterUtcTime : public CsvFormatterImpl {}; 57 | } 58 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/include/plog/Formatters/FuncMessageFormatter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | namespace plog 6 | { 7 | class FuncMessageFormatter 8 | { 9 | public: 10 | static util::nstring header() 11 | { 12 | return util::nstring(); 13 | } 14 | 15 | static util::nstring format(const Record& record) 16 | { 17 | util::nostringstream ss; 18 | ss << record.getFunc() << PLOG_NSTR("@") << record.getLine() << PLOG_NSTR(": ") << record.getMessage() << PLOG_NSTR("\n"); 19 | 20 | return ss.str(); 21 | } 22 | }; 23 | } 24 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/include/plog/Formatters/MessageOnlyFormatter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | namespace plog 6 | { 7 | class MessageOnlyFormatter 8 | { 9 | public: 10 | static util::nstring header() 11 | { 12 | return util::nstring(); 13 | } 14 | 15 | static util::nstring format(const Record& record) 16 | { 17 | util::nostringstream ss; 18 | ss << record.getMessage() << PLOG_NSTR("\n"); 19 | 20 | return ss.str(); 21 | } 22 | }; 23 | } 24 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/include/plog/Formatters/TxtFormatter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | 6 | namespace plog 7 | { 8 | template 9 | class TxtFormatterImpl 10 | { 11 | public: 12 | static util::nstring header() 13 | { 14 | return util::nstring(); 15 | } 16 | 17 | static util::nstring format(const Record& record) 18 | { 19 | tm t; 20 | (useUtcTime ? util::gmtime_s : util::localtime_s)(&t, &record.getTime().time); 21 | 22 | util::nostringstream ss; 23 | ss << t.tm_year + 1900 << "-" << std::setfill(PLOG_NSTR('0')) << std::setw(2) << t.tm_mon + 1 << PLOG_NSTR("-") << std::setfill(PLOG_NSTR('0')) << std::setw(2) << t.tm_mday << PLOG_NSTR(" "); 24 | ss << std::setfill(PLOG_NSTR('0')) << std::setw(2) << t.tm_hour << PLOG_NSTR(":") << std::setfill(PLOG_NSTR('0')) << std::setw(2) << t.tm_min << PLOG_NSTR(":") << std::setfill(PLOG_NSTR('0')) << std::setw(2) << t.tm_sec << PLOG_NSTR(".") << std::setfill(PLOG_NSTR('0')) << std::setw(3) << record.getTime().millitm << PLOG_NSTR(" "); 25 | ss << std::setfill(PLOG_NSTR(' ')) << std::setw(5) << std::left << severityToString(record.getSeverity()) << PLOG_NSTR(" "); 26 | ss << PLOG_NSTR("[") << record.getTid() << PLOG_NSTR("] "); 27 | ss << PLOG_NSTR("[") << record.getFunc() << PLOG_NSTR("@") << record.getLine() << PLOG_NSTR("] "); 28 | ss << record.getMessage() << PLOG_NSTR("\n"); 29 | 30 | return ss.str(); 31 | } 32 | }; 33 | 34 | class TxtFormatter : public TxtFormatterImpl {}; 35 | class TxtFormatterUtcTime : public TxtFormatterImpl {}; 36 | } 37 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/include/plog/Logger.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | 6 | #ifdef PLOG_DEFAULT_INSTANCE // for backward compatibility 7 | # define PLOG_DEFAULT_INSTANCE_ID PLOG_DEFAULT_INSTANCE 8 | #endif 9 | 10 | #ifndef PLOG_DEFAULT_INSTANCE_ID 11 | # define PLOG_DEFAULT_INSTANCE_ID 0 12 | #endif 13 | 14 | namespace plog 15 | { 16 | template 17 | class Logger : public util::Singleton >, public IAppender 18 | { 19 | public: 20 | Logger(Severity maxSeverity = none) : m_maxSeverity(maxSeverity) 21 | { 22 | } 23 | 24 | Logger& addAppender(IAppender* appender) 25 | { 26 | assert(appender != this); 27 | m_appenders.push_back(appender); 28 | return *this; 29 | } 30 | 31 | Severity getMaxSeverity() const 32 | { 33 | return m_maxSeverity; 34 | } 35 | 36 | void setMaxSeverity(Severity severity) 37 | { 38 | m_maxSeverity = severity; 39 | } 40 | 41 | bool checkSeverity(Severity severity) const 42 | { 43 | return severity <= m_maxSeverity; 44 | } 45 | 46 | virtual void write(const Record& record) 47 | { 48 | if (checkSeverity(record.getSeverity())) 49 | { 50 | *this += record; 51 | } 52 | } 53 | 54 | void operator+=(const Record& record) 55 | { 56 | for (std::vector::iterator it = m_appenders.begin(); it != m_appenders.end(); ++it) 57 | { 58 | (*it)->write(record); 59 | } 60 | } 61 | 62 | private: 63 | Severity m_maxSeverity; 64 | std::vector m_appenders; 65 | }; 66 | 67 | template 68 | inline Logger* get() 69 | { 70 | return Logger::getInstance(); 71 | } 72 | 73 | inline Logger* get() 74 | { 75 | return Logger::getInstance(); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/include/plog/Severity.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace plog 5 | { 6 | enum Severity 7 | { 8 | none = 0, 9 | fatal = 1, 10 | error = 2, 11 | warning = 3, 12 | info = 4, 13 | debug = 5, 14 | verbose = 6 15 | }; 16 | 17 | inline const char* severityToString(Severity severity) 18 | { 19 | switch (severity) 20 | { 21 | case fatal: 22 | return "FATAL"; 23 | case error: 24 | return "ERROR"; 25 | case warning: 26 | return "WARN"; 27 | case info: 28 | return "INFO"; 29 | case debug: 30 | return "DEBUG"; 31 | case verbose: 32 | return "VERB"; 33 | default: 34 | return "NONE"; 35 | } 36 | } 37 | 38 | inline Severity severityFromString(const char* str) 39 | { 40 | switch (std::toupper(str[0])) 41 | { 42 | case 'F': 43 | return fatal; 44 | case 'E': 45 | return error; 46 | case 'W': 47 | return warning; 48 | case 'I': 49 | return info; 50 | case 'D': 51 | return debug; 52 | case 'V': 53 | return verbose; 54 | default: 55 | return none; 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/samples/Android/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_custom_target(Android SOURCES jni/Sample.cpp) 2 | set_target_properties(Android PROPERTIES FOLDER Samples) -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/samples/Android/jni/Android.mk: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2009 The Android Open Source Project 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # 15 | LOCAL_PATH := $(call my-dir) 16 | 17 | include $(CLEAR_VARS) 18 | 19 | LOCAL_MODULE := Sample 20 | LOCAL_SRC_FILES := Sample.cpp 21 | LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../../include 22 | 23 | LOCAL_LDLIBS := -llog 24 | 25 | include $(BUILD_SHARED_LIBRARY) 26 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/samples/Android/jni/Application.mk: -------------------------------------------------------------------------------- 1 | APP_ABI := all 2 | APP_STL := stlport_static -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/samples/Android/jni/Sample.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Android - shows how to use the android-specific appender. 3 | // 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | extern "C" void Java_com_github_sergius_myapp_Sample_foo(JNIEnv* env, jobject obj) 11 | { 12 | // For simplicity the logger is initialized here. But the good place is JNI_OnLoad. 13 | static plog::AndroidAppender appender("MyApp"); // Create an appender and set a log tag. 14 | static plog::Logger<0>& logger = plog::init(plog::debug, &appender); // Initialize the logger with the appender. 15 | 16 | PLOGD << "Hello Android!"; 17 | } 18 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/samples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8) 2 | 3 | if(POLICY CMP0063) #Honor visibility properties for all target types 4 | cmake_policy(SET CMP0063 NEW) 5 | endif() 6 | 7 | set_property(GLOBAL PROPERTY USE_FOLDERS ON) 8 | 9 | macro(checkObjCXX) 10 | file(WRITE "${CMAKE_BINARY_DIR}/CMakeFiles/dummy.mm" "int main(){return 0;}\n") 11 | execute_process( 12 | WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/CMakeFiles 13 | COMMAND ${CMAKE_CXX_COMPILER} dummy.mm 14 | RESULT_VARIABLE result 15 | ERROR_QUIET 16 | OUTPUT_QUIET 17 | ) 18 | file(REMOVE "${CMAKE_BINARY_DIR}/CMakeFiles/dummy.mm") 19 | 20 | if("${result}" STREQUAL "0") 21 | set(CMAKE_OBJCXX_AVAILABLE 1) 22 | message("-- ObjectiveC++ support is detected") 23 | endif() 24 | endmacro() 25 | 26 | project(Samples) 27 | 28 | if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") 29 | set(CMAKE_COMPILER_IS_CLANGXX 1) 30 | endif () 31 | 32 | if(MSVC) 33 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4 /WX") 34 | string(REPLACE "/RTC1" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}") 35 | elseif(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANGXX) 36 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wconversion -Wnon-virtual-dtor -Wundef -pedantic -Werror") 37 | set(CMAKE_CXX_VISIBILITY_PRESET hidden) 38 | set(CMAKE_VISIBILITY_INLINES_HIDDEN 1) 39 | checkObjCXX() 40 | endif() 41 | 42 | add_subdirectory(Android) 43 | add_subdirectory(Chained) 44 | add_subdirectory(ColorConsole) 45 | add_subdirectory(CustomAppender) 46 | add_subdirectory(CustomConverter) 47 | add_subdirectory(CustomFormatter) 48 | add_subdirectory(CustomType) 49 | add_subdirectory(DebugOutput) 50 | add_subdirectory(Demo) 51 | add_subdirectory(EventLog) 52 | add_subdirectory(Facilities) 53 | add_subdirectory(Hello) 54 | add_subdirectory(Library) 55 | add_subdirectory(MultiAppender) 56 | add_subdirectory(MultiInstance) 57 | add_subdirectory(SkipNativeEOL) 58 | add_subdirectory(ObjectiveC) 59 | add_subdirectory(Performance) 60 | add_subdirectory(UtcTime) -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/samples/Chained/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # some systems have no shared libraries support, so check it 2 | if(NOT DEFINED TARGET_SUPPORTS_SHARED_LIBS OR TARGET_SUPPORTS_SHARED_LIBS) 3 | add_executable(ChainedApp ChainedApp/Main.cpp) 4 | target_link_libraries(ChainedApp ChainedLib plog) 5 | set_target_properties(ChainedApp PROPERTIES FOLDER Samples/Chained) 6 | 7 | add_library(ChainedLib SHARED ChainedLib/Main.cpp) 8 | target_link_libraries(ChainedLib plog) 9 | set_target_properties(ChainedLib PROPERTIES FOLDER Samples/Chained) 10 | endif() -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/samples/Chained/ChainedApp/Main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Chained - shows how to chain a logger (route messages) in a shared library with the main logger. 3 | // 4 | 5 | #include 6 | 7 | // Functions imported form the shared library. 8 | extern "C" void initialize(plog::Severity severity, plog::IAppender* appender); 9 | extern "C" void foo(); 10 | 11 | int main() 12 | { 13 | plog::init(plog::debug, "ChainedApp.txt"); // Initialize the main logger. 14 | 15 | PLOGD << "Hello from app!"; // Write a log message. 16 | 17 | initialize(plog::debug, plog::get()); // Initialize the logger in the shared library. Note that it has its own severity. 18 | foo(); // Call a function from the shared library that produces a log message. 19 | 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/samples/Chained/ChainedLib/Main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Chained - shows how to chain a logger (route messages) in a shared library with the main logger. 3 | // 4 | 5 | #include 6 | 7 | // Helper macro to mark functions exported from the library. 8 | #if defined _MSC_VER || defined __CYGWIN__ 9 | # define EXPORT __declspec(dllexport) 10 | #else 11 | # define EXPORT __attribute__ ((visibility ("default"))) 12 | #endif 13 | 14 | // Function that initializes the logger in the shared library. 15 | extern "C" void EXPORT initialize(plog::Severity severity, plog::IAppender* appender) 16 | { 17 | plog::init(severity, appender); // Initialize the shared library logger. 18 | } 19 | 20 | // Function that produces a log message. 21 | extern "C" void EXPORT foo() 22 | { 23 | PLOGI << "Hello from shared lib!"; 24 | } 25 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/samples/ColorConsole/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(ColorConsole Main.cpp) 2 | target_link_libraries(ColorConsole plog) 3 | set_target_properties(ColorConsole PROPERTIES FOLDER Samples) -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/samples/ColorConsole/Main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ColorConsole - shows how to use a color console appender. 3 | // 4 | 5 | #include 6 | #include 7 | 8 | int main() 9 | { 10 | static plog::ColorConsoleAppender consoleAppender; 11 | plog::init(plog::verbose, &consoleAppender); 12 | 13 | // Log severity levels are printed in different colors. 14 | PLOG_VERBOSE << "This is a VERBOSE message"; 15 | PLOG_DEBUG << "This is a DEBUG message"; 16 | PLOG_INFO << "This is an INFO message"; 17 | PLOG_WARNING << "This is a WARNING message"; 18 | PLOG_ERROR << "This is an ERROR message"; 19 | PLOG_FATAL << "This is a FATAL message"; 20 | 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/samples/CustomAppender/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(CustomAppender Main.cpp) 2 | target_link_libraries(CustomAppender plog) 3 | set_target_properties(CustomAppender PROPERTIES FOLDER Samples) -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/samples/CustomAppender/Main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // CustomAppender - shows how to implement a custom appender that stores log messages in memory. 3 | // 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | namespace plog 10 | { 11 | template // Typically a formatter is passed as a template parameter. 12 | class MyAppender : public IAppender // All appenders MUST inherit IAppender interface. 13 | { 14 | public: 15 | virtual void write(const Record& record) // This is a method from IAppender that MUST be implemented. 16 | { 17 | util::nstring str = Formatter::format(record); // Use the formatter to get a string from a record. 18 | 19 | m_messageList.push_back(str); // Store a log message in a list. 20 | } 21 | 22 | std::list& getMessageList() 23 | { 24 | return m_messageList; 25 | } 26 | 27 | private: 28 | std::list m_messageList; 29 | }; 30 | } 31 | 32 | int main() 33 | { 34 | static plog::MyAppender myAppender; // Create our custom appender. 35 | plog::init(plog::debug, &myAppender); // Initialize the logger with our appender. 36 | 37 | PLOGD << "A debug message!"; 38 | 39 | myAppender.getMessageList(); // This returns a list of stored log messages. 40 | 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/samples/CustomConverter/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(CustomConverter Main.cpp) 2 | target_link_libraries(CustomConverter plog) 3 | set_target_properties(CustomConverter PROPERTIES FOLDER Samples) -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/samples/CustomConverter/Main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // CustomConverter - shows how to implement a custom converter that encrypts log messages. 3 | // 4 | 5 | #include 6 | 7 | namespace plog 8 | { 9 | class MyConverter 10 | { 11 | public: 12 | static std::string header(const util::nstring& str) 13 | { 14 | return convert(str); // We have no special header for a file, so just call convert. 15 | } 16 | 17 | static std::string convert(const util::nstring& str) 18 | { 19 | const std::string& in = UTF8Converter::convert(str); // Convert to UTF8 first as it is more compact. 20 | 21 | std::string out; 22 | out.resize(in.size()); 23 | 24 | // This is an encryption key. 25 | const char kKey[] = "\x56\x5a\x43\x4d\x5f\x81\x4c\x4e\x19\x29\x2e\x13\x7c\x31\x14\x17\x5d\x63\x32\x39"; 26 | 27 | // Simple XOR encryption. 28 | for (size_t i = 0; i < out.size(); ++i) 29 | { 30 | out[i] = in[i] ^ kKey[i % (sizeof(kKey) - 1)]; 31 | } 32 | 33 | return out; 34 | } 35 | }; 36 | } 37 | 38 | int main() 39 | { 40 | static plog::RollingFileAppender appender("CustomConverter.txt"); // Create an appender and pass our converter as a template parameter. 41 | plog::init(plog::debug, &appender); // Initialize the logger with the appender. 42 | 43 | PLOGD << "A debug message!"; 44 | PLOGD << "Another one debug message!"; 45 | 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/samples/CustomFormatter/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(CustomFormatter Main.cpp) 2 | target_link_libraries(CustomFormatter plog) 3 | set_target_properties(CustomFormatter PROPERTIES FOLDER Samples) -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/samples/CustomFormatter/Main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // CustomFormatter - shows how to implement a custom formatter. 3 | // 4 | 5 | #include 6 | 7 | namespace plog 8 | { 9 | class MyFormatter 10 | { 11 | public: 12 | static util::nstring header() // This method returns a header for a new file. In our case it is empty. 13 | { 14 | return util::nstring(); 15 | } 16 | 17 | static util::nstring format(const Record& record) // This method returns a string from a record. 18 | { 19 | util::nostringstream ss; 20 | ss << record.getMessage() << "\n"; // Produce a simple string with a log message. 21 | 22 | return ss.str(); 23 | } 24 | }; 25 | } 26 | 27 | int main() 28 | { 29 | plog::init(plog::debug, "CustomFormatter.txt"); // Initialize the logger and pass our formatter as a template parameter to init function. 30 | 31 | PLOGD << "A debug message!"; 32 | 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/samples/CustomType/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(CustomType Main.cpp) 2 | target_link_libraries(CustomType plog) 3 | set_target_properties(CustomType PROPERTIES FOLDER Samples) -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/samples/CustomType/Main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // CustomType - shows how to print a custom type to the log stream. 3 | // 4 | 5 | #include 6 | 7 | struct Point // This is our custom type that we want to print to the log stream. 8 | { 9 | int x; 10 | int y; 11 | }; 12 | 13 | namespace plog 14 | { 15 | Record& operator<<(Record& record, const Point& pt) // Implement a stream operator for our type. 16 | { 17 | return record << "(" << pt.x << ";" << pt.y << ")"; 18 | } 19 | } 20 | 21 | int main() 22 | { 23 | plog::init(plog::debug, "CustomType.txt"); // Initialize the logger. 24 | 25 | Point pt1 = { 0, 0 }; 26 | Point pt2 = { 10, -5 }; 27 | 28 | PLOGI << "We've got a line with coords: " << pt1 << pt2; // Print our type to the log stream. 29 | PLOGI << pt1 << pt2 << " - test for a custom type at begin of the stream"; // Print our type to the log stream. 30 | 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/samples/DebugOutput/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | if(WIN32) 2 | add_executable(DebugOutput Main.cpp) 3 | target_link_libraries(DebugOutput plog) 4 | set_target_properties(DebugOutput PROPERTIES FOLDER Samples) 5 | endif() -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/samples/DebugOutput/Main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // DebugOutput - shows how to use DebugOutputAppender to write to the windows debug output. 3 | // 4 | 5 | #include 6 | #include 7 | 8 | int main() 9 | { 10 | static plog::DebugOutputAppender debugOutputAppender; 11 | plog::init(plog::verbose, &debugOutputAppender); 12 | 13 | PLOGD << "Hello log!"; // short macro 14 | PLOG_DEBUG << "Hello log!"; // long macro 15 | PLOG(plog::debug) << "Hello log!"; // function-style macro 16 | 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/samples/Demo/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(Demo Main.cpp MyClass.h MyClass.cpp Customer.h) 2 | target_link_libraries(Demo plog) 3 | set_target_properties(Demo PROPERTIES FOLDER Samples) 4 | 5 | if(MSVC AND NOT (MSVC_VERSION LESS 1700)) # Visual Studio 2012 and higher 6 | add_executable(DemoManaged Main.cpp MyClass.h MyClass.cpp Customer.h) 7 | target_link_libraries(DemoManaged plog) 8 | set_property(TARGET DemoManaged PROPERTY COMPILE_FLAGS "/clr /EHa") 9 | set_target_properties(DemoManaged PROPERTIES FOLDER Samples) 10 | endif() 11 | 12 | if(NOT WIN32) 13 | add_executable(DemoWchar Main.cpp MyClass.h MyClass.cpp Customer.h) 14 | target_link_libraries(DemoWchar plog) 15 | set_target_properties(DemoWchar PROPERTIES COMPILE_FLAGS "-DPLOG_ENABLE_WCHAR_INPUT=1") 16 | set_target_properties(DemoWchar PROPERTIES FOLDER Samples) 17 | 18 | if(APPLE) 19 | target_link_libraries(DemoWchar -liconv) 20 | endif() 21 | endif() -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/samples/Demo/Customer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | struct Customer 6 | { 7 | int id; 8 | std::string name; 9 | }; 10 | 11 | inline std::ostream& operator<<(std::ostream& os, const Customer& obj) 12 | { 13 | os << "Customer (id: " << obj.id << ", name: " << obj.name << ")"; 14 | return os; 15 | } 16 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/samples/Demo/MyClass.cpp: -------------------------------------------------------------------------------- 1 | #include "MyClass.h" 2 | 3 | MyClass::MyClass() 4 | { 5 | PLOGD; 6 | } 7 | 8 | MyClass::~MyClass() 9 | { 10 | PLOGD; 11 | } 12 | 13 | void MyClass::method() 14 | { 15 | PLOGD; 16 | } 17 | 18 | void MyClass::staticMethod() 19 | { 20 | PLOGD; 21 | } 22 | 23 | MyClass::operator std::string() const 24 | { 25 | return std::string("This is an implicit cast to string."); 26 | } 27 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/samples/Demo/MyClass.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | class MyClass 5 | { 6 | public: 7 | MyClass(); 8 | ~MyClass(); 9 | 10 | void method(); 11 | 12 | void inlineMethod() 13 | { 14 | PLOGD; 15 | } 16 | 17 | static void staticMethod(); 18 | 19 | operator std::string() const; 20 | }; 21 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/samples/EventLog/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | if(WIN32) 2 | add_executable(EventLog Main.cpp) 3 | target_link_libraries(EventLog plog) 4 | set_target_properties(EventLog PROPERTIES FOLDER Samples) 5 | endif() -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/samples/EventLog/Main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // EventLog - shows how to use EventLogAppender to write to the windows event log. 3 | // 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | using namespace std; 11 | 12 | int main(int argc, char* argv[]) 13 | { 14 | const wchar_t kEventSourceName[] = L"EventLogSample"; 15 | 16 | if (argc == 2) 17 | { 18 | // 19 | // Note: register/unregister operations require admin rights. 20 | // 21 | 22 | if (0 == strcmp(argv[1], "--register")) 23 | { 24 | if (!plog::EventLogAppenderRegistry::add(kEventSourceName)) 25 | { 26 | cerr << "Failed to register eventlog source." << endl; 27 | return -1; 28 | } 29 | 30 | cout << "Successfully registered eventlog source." << endl; 31 | } 32 | else if (0 == strcmp(argv[1], "--unregister")) 33 | { 34 | plog::EventLogAppenderRegistry::remove(kEventSourceName); 35 | cout << "Successfully unregistered eventlog source." << endl; 36 | } 37 | else if (0 == strcmp(argv[1], "--query")) 38 | { 39 | cout << "Eventlog source exists: " << plog::EventLogAppenderRegistry::exists(kEventSourceName) << endl; 40 | } 41 | 42 | return 0; 43 | } 44 | 45 | // 46 | // Note: eventlog source must be registered prior to creating its appender. 47 | // 48 | 49 | static plog::EventLogAppender eventLogAppender(kEventSourceName); 50 | plog::init(plog::verbose, &eventLogAppender); 51 | 52 | PLOG_VERBOSE << "This is a VERBOSE message"; 53 | PLOG_DEBUG << "This is a DEBUG message"; 54 | PLOG_INFO << "This is an INFO message"; 55 | PLOG_WARNING << "This is a WARNING message"; 56 | PLOG_ERROR << "This is an ERROR message"; 57 | PLOG_FATAL << "This is a FATAL message"; 58 | 59 | return 0; 60 | } 61 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/samples/Facilities/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(Facilities Main.cpp) 2 | target_link_libraries(Facilities plog) 3 | set_target_properties(Facilities PROPERTIES FOLDER Samples) -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/samples/Facilities/Main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Facilities - shows how to use logging per facilities via multiple logger instances (useful for big projects). 3 | // 4 | 5 | #include 6 | 7 | enum Facility // Define log facilities. 8 | { 9 | Default, // The default is 0. 10 | Auth, 11 | FileIO, 12 | Sink = -1 // This is a log sink. Messages from other facilities go there. 13 | }; 14 | 15 | int main() 16 | { 17 | plog::init(plog::debug, "Facility.csv"); // Initialize the sink logger. 18 | 19 | // Initialize all other loggers and set the sink logger as an appender. Each of the loggers can have their own severity level. 20 | plog::init(plog::debug, plog::get()); 21 | plog::init(plog::warning, plog::get()); 22 | plog::init(plog::info, plog::get()); 23 | 24 | PLOGD_(Default) << "This is a message from the Default facility"; 25 | PLOGD << "This is a message from the Default facility too because Default = 0"; 26 | 27 | PLOGW_(Auth) << "This is a message from the Auth facility"; 28 | PLOGI_(FileIO) << "This is a message from the FileIO facility"; 29 | 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/samples/Hello/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(Hello Main.cpp) 2 | target_link_libraries(Hello plog) 3 | set_target_properties(Hello PROPERTIES FOLDER Samples) -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/samples/Hello/Main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Hello - a minimal introduction sample, shows the basic 3 steps to start using plog. 3 | // 4 | 5 | #include // Step1: include the header. 6 | 7 | int main() 8 | { 9 | plog::init(plog::debug, "Hello.txt"); // Step2: initialize the logger. 10 | 11 | // Step3: write log messages using a special macro. There are several log macros, use the macro you liked the most. 12 | 13 | PLOGD << "Hello log!"; // short macro 14 | PLOG_DEBUG << "Hello log!"; // long macro 15 | PLOG(plog::debug) << "Hello log!"; // function-style macro 16 | 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/samples/Library/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(LibraryApp LibraryApp/Main.cpp) 2 | target_link_libraries(LibraryApp LibraryLib plog) 3 | set_target_properties(LibraryApp PROPERTIES FOLDER Samples/Library) 4 | 5 | add_library(LibraryLib STATIC LibraryLib/Lib.cpp) 6 | target_link_libraries(LibraryLib plog) 7 | set_target_properties(LibraryLib PROPERTIES FOLDER Samples/Library) -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/samples/Library/LibraryApp/Main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Library - shows plog usage in static libraries. 3 | // 4 | 5 | #include 6 | 7 | void foo(); // Function from the static library. 8 | 9 | int main() 10 | { 11 | plog::init(plog::debug, "LibraryApp.txt"); // Initialize the logger. The static library will use it. 12 | // Note that the main app is not required to use plog, the static library will be linked fine in any case. 13 | 14 | foo(); 15 | 16 | PLOGD << "A message from the main application!"; 17 | 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/samples/Library/LibraryLib/Lib.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Library - shows plog usage in static libraries. 3 | // 4 | 5 | #include 6 | 7 | void foo() 8 | { 9 | // The logger is initialized in the main app. It is safe not to do that and even not to use plog at all. The library will be linked fine. 10 | PLOGD << "A message from the static library!"; 11 | } 12 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/samples/MultiAppender/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(MultiAppender Main.cpp) 2 | target_link_libraries(MultiAppender plog) 3 | set_target_properties(MultiAppender PROPERTIES FOLDER Samples) -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/samples/MultiAppender/Main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // MultiAppender - shows how to use multiple appenders with the same logger. 3 | // 4 | 5 | #include 6 | #include 7 | 8 | int main() 9 | { 10 | static plog::RollingFileAppender fileAppender("MultiAppender.csv", 8000, 3); // Create the 1st appender. 11 | static plog::ConsoleAppender consoleAppender; // Create the 2nd appender. 12 | plog::init(plog::debug, &fileAppender).addAppender(&consoleAppender); // Initialize the logger with the both appenders. 13 | 14 | // A bunch of log lines that goes to the both appenders: to the file and to the console. 15 | for (int i = 0; i < 100; ++i) 16 | { 17 | PLOG_INFO << "i: " << i; 18 | } 19 | 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/samples/MultiInstance/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(MultiInstance Main.cpp) 2 | target_link_libraries(MultiInstance plog) 3 | set_target_properties(MultiInstance PROPERTIES FOLDER Samples) -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/samples/MultiInstance/Main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // MultiInstance - shows how to use multiple logger instances, each instance has its own independent configuration. 3 | // 4 | 5 | #include 6 | 7 | enum // Define log instances. Default is 0 and is omitted from this enum. 8 | { 9 | SecondLog = 1 10 | }; 11 | 12 | int main() 13 | { 14 | plog::init(plog::debug, "MultiInstance-default.txt"); // Initialize the default logger instance. 15 | plog::init(plog::debug, "MultiInstance-second.txt"); // Initialize the 2nd logger instance. 16 | 17 | // Write some messages to the default log. 18 | PLOGD << "Hello default log!"; 19 | PLOG_DEBUG << "Hello default log!"; 20 | PLOG(plog::debug) << "Hello default log!"; 21 | 22 | // Write some messages to the 2nd log. 23 | PLOGD_(SecondLog) << "Hello second log!"; 24 | PLOG_DEBUG_(SecondLog) << "Hello second log!"; 25 | PLOG_(SecondLog, plog::debug) << "Hello second log!"; 26 | 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/samples/ObjectiveC/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | if(CMAKE_OBJCXX_AVAILABLE AND NOT CMAKE_COMPILER_IS_CLANGXX) 2 | add_executable(ObjectiveC Main.mm) 3 | target_link_libraries(ObjectiveC objc plog) 4 | else() 5 | add_custom_target(ObjectiveC SOURCES Main.mm) 6 | endif() 7 | set_target_properties(ObjectiveC PROPERTIES FOLDER Samples) -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/samples/ObjectiveC/Main.mm: -------------------------------------------------------------------------------- 1 | // 2 | // ObjectiveC - shows that plog can be used in ObjectiveC++. 3 | // 4 | 5 | #include 6 | #include 7 | 8 | @interface Greeter : Object 9 | { 10 | int dummy; 11 | } 12 | +(void) greet; 13 | @end 14 | 15 | @implementation Greeter 16 | +(void) greet 17 | { 18 | PLOGD << "Hello ObjC++!"; 19 | } 20 | @end 21 | 22 | int main() 23 | { 24 | plog::init(plog::debug, "ObjectiveC.csv"); // Initialize the logger. 25 | PLOGD << "Hello ObjC++!"; 26 | 27 | [Greeter greet]; 28 | 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/samples/Performance/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(Performance Main.cpp) 2 | target_link_libraries(Performance plog) 3 | set_target_properties(Performance PROPERTIES FOLDER Samples) -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/samples/Performance/Main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Performance - measures time per a log call. 3 | // 4 | 5 | #include 6 | #include 7 | 8 | enum 9 | { 10 | Console = 1 11 | }; 12 | 13 | int main() 14 | { 15 | // Initialize the logger that will be measured. 16 | plog::init(plog::debug, "Performance.txt"); 17 | 18 | // Initialize the logger for printing info messages. 19 | static plog::ConsoleAppender consoleAppender; 20 | plog::init(plog::debug, &consoleAppender); 21 | 22 | PLOGI_(Console) << "Test started"; 23 | 24 | plog::util::Time startTime; 25 | plog::util::ftime(&startTime); 26 | 27 | const int kCount = 50000; 28 | 29 | // Performance measure loop. 30 | for (int i = 0; i < kCount; ++i) 31 | { 32 | PLOGD << "Hello log!"; 33 | } 34 | 35 | plog::util::Time finishTime; 36 | plog::util::ftime(&finishTime); 37 | 38 | time_t timeDiff = (finishTime.millitm - startTime.millitm) + (finishTime.time - startTime.time) * 1000; 39 | 40 | PLOGI_(Console) << "Test finished: " << static_cast(timeDiff) * 1000 / kCount << " microsec per call"; 41 | 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/samples/SkipNativeEOL/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(SkipNativeEOL Main.cpp) 2 | target_link_libraries(SkipNativeEOL plog) 3 | set_target_properties(SkipNativeEOL PROPERTIES FOLDER Samples) 4 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/samples/SkipNativeEOL/Main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // SkipNativeEOL - shows how to skip NativeEOLConverter. 3 | // 4 | 5 | #include 6 | #include 7 | 8 | int main() 9 | { 10 | // NativeEOLConverter will use on Windows and on everything else as line endings. 11 | // It's used by default. 12 | // If you want to always use you can skip NativeEOLConverter and specify UTF8Converter directly. 13 | static plog::RollingFileAppender fileAppender("SkipNativeEOL.log", 8000, 3); // Create an appender without NativeEOLConverter. 14 | plog::init(plog::debug, &fileAppender); // Initialize the logger. 15 | 16 | // Write some data. 17 | for (int i = 0; i < 100; ++i) 18 | { 19 | PLOGI << "i: " << i; 20 | } 21 | 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/samples/UtcTime/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(UtcTime Main.cpp) 2 | target_link_libraries(UtcTime plog) 3 | set_target_properties(UtcTime PROPERTIES FOLDER Samples) -------------------------------------------------------------------------------- /Tutorial/thirdparty/plog/samples/UtcTime/Main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // UtcTime - shows how to use UTC time in logs. 3 | // 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | int main() 10 | { 11 | static plog::ColorConsoleAppender consoleAppender; // TxtFormatter in UTC 12 | static plog::RollingFileAppender fileAppender("UtcTime.csv", 10000, 2); // CsvFormatter in UTC 13 | plog::init(plog::verbose, &consoleAppender).addAppender(&fileAppender); 14 | 15 | PLOG_VERBOSE << "This is a VERBOSE message"; 16 | PLOG_DEBUG << "This is a DEBUG message"; 17 | PLOG_INFO << "This is an INFO message"; 18 | PLOG_WARNING << "This is a WARNING message"; 19 | PLOG_ERROR << "This is an ERROR message"; 20 | PLOG_FATAL << "This is a FATAL message"; 21 | 22 | return 0; 23 | } 24 | --------------------------------------------------------------------------------