├── .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 | 
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