installed pty
[VSoRC/.git] / node_modules / node-pty / deps / winpty / src / agent / NamedPipe.h
1 // Copyright (c) 2011-2012 Ryan Prichard
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining a copy
4 // of this software and associated documentation files (the "Software"), to
5 // deal in the Software without restriction, including without limitation the
6 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7 // sell copies of the Software, and to permit persons to whom the Software is
8 // furnished to do so, subject to the following conditions:
9 //
10 // The above copyright notice and this permission notice shall be included in
11 // all copies or substantial portions of the Software.
12 //
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19 // IN THE SOFTWARE.
20
21 #ifndef NAMEDPIPE_H
22 #define NAMEDPIPE_H
23
24 #include <windows.h>
25
26 #include <memory>
27 #include <string>
28 #include <vector>
29
30 #include "../shared/OwnedHandle.h"
31
32 class EventLoop;
33
34 class NamedPipe
35 {
36 private:
37     // The EventLoop uses these private members.
38     friend class EventLoop;
39     NamedPipe() {}
40     ~NamedPipe() { closePipe(); }
41     bool serviceIo(std::vector<HANDLE> *waitHandles);
42     void startPipeWorkers();
43
44     enum class ServiceResult { NoProgress, Error, Progress };
45
46 private:
47     class IoWorker
48     {
49     public:
50         IoWorker(NamedPipe &namedPipe);
51         virtual ~IoWorker() {}
52         ServiceResult service();
53         void waitForCanceledIo();
54         HANDLE getWaitEvent();
55     protected:
56         NamedPipe &m_namedPipe;
57         bool m_pending = false;
58         DWORD m_currentIoSize = 0;
59         OwnedHandle m_event;
60         OVERLAPPED m_over = {};
61         enum { kIoSize = 64 * 1024 };
62         char m_buffer[kIoSize];
63         virtual void completeIo(DWORD size) = 0;
64         virtual bool shouldIssueIo(DWORD *size, bool *isRead) = 0;
65     };
66
67     class InputWorker : public IoWorker
68     {
69     public:
70         InputWorker(NamedPipe &namedPipe) : IoWorker(namedPipe) {}
71     protected:
72         virtual void completeIo(DWORD size) override;
73         virtual bool shouldIssueIo(DWORD *size, bool *isRead) override;
74     };
75
76     class OutputWorker : public IoWorker
77     {
78     public:
79         OutputWorker(NamedPipe &namedPipe) : IoWorker(namedPipe) {}
80         DWORD getPendingIoSize();
81     protected:
82         virtual void completeIo(DWORD size) override;
83         virtual bool shouldIssueIo(DWORD *size, bool *isRead) override;
84     };
85
86 public:
87     struct OpenMode {
88         typedef int t;
89         enum { None = 0, Reading = 1, Writing = 2, Duplex = 3 };
90     };
91
92     std::wstring name() const { return m_name; }
93     void openServerPipe(LPCWSTR pipeName, OpenMode::t openMode,
94                         int outBufferSize, int inBufferSize);
95     void connectToServer(LPCWSTR pipeName, OpenMode::t openMode);
96     size_t bytesToSend();
97     void write(const void *data, size_t size);
98     void write(const char *text);
99     size_t readBufferSize();
100     void setReadBufferSize(size_t size);
101     size_t bytesAvailable();
102     size_t peek(void *data, size_t size);
103     size_t read(void *data, size_t size);
104     std::string readToString(size_t size);
105     std::string readAllToString();
106     void closePipe();
107     bool isClosed() { return m_handle == nullptr; }
108     bool isConnected() { return !isClosed() && !isConnecting(); }
109     bool isConnecting() { return m_connectEvent.get() != nullptr; }
110
111 private:
112     // Input/output buffers
113     std::wstring m_name;
114     OVERLAPPED m_connectOver = {};
115     OwnedHandle m_connectEvent;
116     OpenMode::t m_openMode = OpenMode::None;
117     size_t m_readBufferSize = 64 * 1024;
118     std::string m_inQueue;
119     std::string m_outQueue;
120     HANDLE m_handle = nullptr;
121     std::unique_ptr<InputWorker> m_inputWorker;
122     std::unique_ptr<OutputWorker> m_outputWorker;
123 };
124
125 #endif // NAMEDPIPE_H