summaryrefslogtreecommitdiff
path: root/winpipes.h
blob: 3260e196cc41cc431e398ce7b924c94f963ca118 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#ifndef CRYPTOPP_WINPIPES_H
#define CRYPTOPP_WINPIPES_H

#include "config.h"

#ifdef WINDOWS_PIPES_AVAILABLE

#include "network.h"
#include "queue.h"
#include <windows.h>

NAMESPACE_BEGIN(CryptoPP)

//! Windows Handle
class WindowsHandle
{
public:
	WindowsHandle(HANDLE h = INVALID_HANDLE_VALUE, bool own=false);
	WindowsHandle(const WindowsHandle &h) : m_h(h.m_h), m_own(false) {}
	virtual ~WindowsHandle();

	bool GetOwnership() const {return m_own;}
	void SetOwnership(bool own) {m_own = own;}

	operator HANDLE() {return m_h;}
	HANDLE GetHandle() const {return m_h;}
	bool HandleValid() const;
	void AttachHandle(HANDLE h, bool own=false);
	HANDLE DetachHandle();
	void CloseHandle();

protected:
	virtual void HandleChanged() {}

	HANDLE m_h;
	bool m_own;
};

//! Windows Pipe
class WindowsPipe
{
public:
	class Err : public OS_Error
	{
	public:
		Err(HANDLE h, const std::string& operation, int error);
		HANDLE GetHandle() const {return m_h;}

	private:
		HANDLE m_h;
	};

protected:
	virtual HANDLE GetHandle() const =0;
	virtual void HandleError(const char *operation) const;
	void CheckAndHandleError(const char *operation, BOOL result) const
		{assert(result==TRUE || result==FALSE); if (!result) HandleError(operation);}
};

//! .
class WindowsPipeReceiver : public WindowsPipe, public NetworkReceiver
{
public:
	WindowsPipeReceiver();

	bool MustWaitForResult() {return true;}
	void Receive(byte* buf, unsigned int bufLen);
	unsigned int GetReceiveResult();
	bool EofReceived() const {return m_eofReceived;}

	unsigned int GetMaxWaitObjectCount() const {return 1;}
	void GetWaitObjects(WaitObjectContainer &container);

private:
	WindowsHandle m_event;
	OVERLAPPED m_overlapped;
	bool m_resultPending;
	DWORD m_lastResult;
	bool m_eofReceived;
};

//! .
class WindowsPipeSender : public WindowsPipe, public NetworkSender
{
public:
	WindowsPipeSender();

	bool MustWaitForResult() {return true;}
	void Send(const byte* buf, unsigned int bufLen);
	unsigned int GetSendResult();
	void SendEof() {}

	unsigned int GetMaxWaitObjectCount() const {return 1;}
	void GetWaitObjects(WaitObjectContainer &container);

private:
	WindowsHandle m_event;
	OVERLAPPED m_overlapped;
	bool m_resultPending;
	DWORD m_lastResult;
};

//! Windows Pipe Source
class WindowsPipeSource : public WindowsHandle, public NetworkSource, public WindowsPipeReceiver
{
public:
	WindowsPipeSource(HANDLE h=INVALID_HANDLE_VALUE, bool pumpAll=false, BufferedTransformation *attachment=NULL)
		: WindowsHandle(h), NetworkSource(attachment)
	{
		if (pumpAll)
			PumpAll();
	}

	NetworkSource::GetMaxWaitObjectCount;
	NetworkSource::GetWaitObjects;

private:
	HANDLE GetHandle() const {return WindowsHandle::GetHandle();}
	NetworkReceiver & AccessReceiver() {return *this;}
};

//! Windows Pipe Sink
class WindowsPipeSink : public WindowsHandle, public NetworkSink, public WindowsPipeSender
{
public:
	WindowsPipeSink(HANDLE h=INVALID_HANDLE_VALUE, unsigned int maxBufferSize=0, bool autoFlush=false)
		: WindowsHandle(h), NetworkSink(maxBufferSize, autoFlush) {}

	NetworkSink::GetMaxWaitObjectCount;
	NetworkSink::GetWaitObjects;

private:
	HANDLE GetHandle() const {return WindowsHandle::GetHandle();}
	NetworkSender & AccessSender() {return *this;}
};

NAMESPACE_END

#endif

#endif