#include <boost/iostreams/categories.hpp>
#include <boost/iostreams/stream.hpp>
#include <boost/coroutine/all.hpp>
#include <functional>
#include <istream>
#include <memory>
#include <cwchar>
using namespace boost;
using namespace std;
#include <windows.h>
typedef function<void(wchar_t)> CharHandler;
CharHandler on_char;
HWND main_hwnd;
template<typename F>
void async_read(F f)
{
on_char = f;
}
typedef coroutines::coroutine<void()> Coro;
typedef std::shared_ptr<Coro> shared_coro;
struct DataSource
{
typedef wchar_t char_type;
typedef iostreams::source_tag category;
Coro::caller_type &ca;
const shared_coro *coro;
std::streamsize read(wchar_t* s, streamsize n)
{
if(n==0) return 0;
auto &&sc = *coro;
async_read([s, sc, this](wchar_t ch)
{
s[0] = ch;
coro = ≻
(*sc)();
});
ca();
return 1;
}
};
typedef iostreams::stream<DataSource> InputStream;
void foo(wistream &client_stream)
{
wstring msg;
do
{
getline(client_stream, msg);
SendMessage(main_hwnd, WM_SETTEXT, 0, reinterpret_cast<LPARAM>(msg.c_str()));
} while(msg != L"exit");
}
void task()
{
auto &&coro = make_shared<Coro>();
*coro = Coro([&coro](Coro::caller_type &ca)
{
DataSource source = {ca, &coro};
InputStream client_stream(source);
foo(client_stream);
});
}
LRESULT CALLBACK window_procedure(HWND hwnd, UINT msg, WPARAM w_param, LPARAM l_param)
{
switch (msg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_SIZE:
if(w_param == SIZE_MAXIMIZED)
{
static auto once = []{ return task(), 1; }();
} break;
case WM_CHAR:
if(on_char)
{
wchar_t ch = w_param;
auto handler = on_char;
on_char = CharHandler();
handler(ch == L'\x0D'? L'\n' : ch);
} break;
}
return DefWindowProc(hwnd, msg, w_param, l_param);
}
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE, LPSTR, int nCmdShow)
{
WNDCLASS wincl = {};
wincl.hInstance = hInstance;
wincl.lpszClassName = TEXT("SFC");
wincl.lpfnWndProc = window_procedure;
RegisterClass(&wincl);
main_hwnd = CreateWindow(wincl.lpszClassName, TEXT(""), WS_OVERLAPPEDWINDOW, 0, 0, 400, 100, 0, 0, hInstance, 0);
ShowWindow(main_hwnd, nCmdShow);
MSG msg;
while(GetMessage(&msg, 0, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
I2luY2x1ZGUgPGJvb3N0L2lvc3RyZWFtcy9jYXRlZ29yaWVzLmhwcD4KI2luY2x1ZGUgPGJvb3N0L2lvc3RyZWFtcy9zdHJlYW0uaHBwPgojaW5jbHVkZSA8Ym9vc3QvY29yb3V0aW5lL2FsbC5ocHA+CgojaW5jbHVkZSA8ZnVuY3Rpb25hbD4KI2luY2x1ZGUgPGlzdHJlYW0+CiNpbmNsdWRlIDxtZW1vcnk+CiNpbmNsdWRlIDxjd2NoYXI+Cgp1c2luZyBuYW1lc3BhY2UgYm9vc3Q7CnVzaW5nIG5hbWVzcGFjZSBzdGQ7CgojaW5jbHVkZSA8d2luZG93cy5oPgoKdHlwZWRlZiBmdW5jdGlvbjx2b2lkKHdjaGFyX3QpPiBDaGFySGFuZGxlcjsKQ2hhckhhbmRsZXIgb25fY2hhcjsKSFdORCBtYWluX2h3bmQ7Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBGPgp2b2lkIGFzeW5jX3JlYWQoRiBmKQp7CiAgICBvbl9jaGFyID0gZjsKfQoKdHlwZWRlZiBjb3JvdXRpbmVzOjpjb3JvdXRpbmU8dm9pZCgpPiBDb3JvOwp0eXBlZGVmIHN0ZDo6c2hhcmVkX3B0cjxDb3JvPiBzaGFyZWRfY29ybzsKCnN0cnVjdCBEYXRhU291cmNlCnsKICAgIHR5cGVkZWYgd2NoYXJfdCBjaGFyX3R5cGU7CiAgICB0eXBlZGVmIGlvc3RyZWFtczo6c291cmNlX3RhZyBjYXRlZ29yeTsKCiAgICBDb3JvOjpjYWxsZXJfdHlwZSAmY2E7CiAgICBjb25zdCBzaGFyZWRfY29ybyAqY29ybzsKCiAgICBzdGQ6OnN0cmVhbXNpemUgcmVhZCh3Y2hhcl90KiBzLCBzdHJlYW1zaXplIG4pIAogICAgewogICAgICAgIGlmKG49PTApIHJldHVybiAwOwogICAgICAgIGF1dG8gJiZzYyA9ICpjb3JvOwogICAgICAgIGFzeW5jX3JlYWQoW3MsIHNjLCB0aGlzXSh3Y2hhcl90IGNoKQogICAgICAgIHsKICAgICAgICAgICAgc1swXSA9IGNoOwogICAgICAgICAgICBjb3JvID0gJnNjOwogICAgICAgICAgICAoKnNjKSgpOwogICAgICAgIH0pOwogICAgICAgIGNhKCk7CiAgICAgICAgcmV0dXJuIDE7CiAgICB9Cn07CnR5cGVkZWYgaW9zdHJlYW1zOjpzdHJlYW08RGF0YVNvdXJjZT4gSW5wdXRTdHJlYW07Cgp2b2lkIGZvbyh3aXN0cmVhbSAmY2xpZW50X3N0cmVhbSkKewogICAgd3N0cmluZyBtc2c7CiAgICBkbwogICAgewogICAgICAgIGdldGxpbmUoY2xpZW50X3N0cmVhbSwgbXNnKTsKICAgICAgICBTZW5kTWVzc2FnZShtYWluX2h3bmQsIFdNX1NFVFRFWFQsIDAsIHJlaW50ZXJwcmV0X2Nhc3Q8TFBBUkFNPihtc2cuY19zdHIoKSkpOwogICAgfSB3aGlsZShtc2cgIT0gTCJleGl0Iik7Cn0KCnZvaWQgdGFzaygpCnsKICAgIGF1dG8gJiZjb3JvID0gbWFrZV9zaGFyZWQ8Q29ybz4oKTsKICAgICpjb3JvID0gQ29ybyhbJmNvcm9dKENvcm86OmNhbGxlcl90eXBlICZjYSkKICAgIHsKICAgICAgICBEYXRhU291cmNlIHNvdXJjZSA9IHtjYSwgJmNvcm99OwogICAgICAgIElucHV0U3RyZWFtIGNsaWVudF9zdHJlYW0oc291cmNlKTsKICAgICAgICBmb28oY2xpZW50X3N0cmVhbSk7CiAgICB9KTsKfQoKTFJFU1VMVCBDQUxMQkFDSyB3aW5kb3dfcHJvY2VkdXJlKEhXTkQgaHduZCwgVUlOVCBtc2csIFdQQVJBTSB3X3BhcmFtLCBMUEFSQU0gbF9wYXJhbSkKewogICAgc3dpdGNoIChtc2cpCiAgICB7CiAgICAgICAgY2FzZSBXTV9ERVNUUk9ZOgogICAgICAgICAgICBQb3N0UXVpdE1lc3NhZ2UoMCk7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgY2FzZSBXTV9TSVpFOgogICAgICAgICAgICBpZih3X3BhcmFtID09IFNJWkVfTUFYSU1JWkVEKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzdGF0aWMgYXV0byBvbmNlID0gW117IHJldHVybiB0YXNrKCksIDE7IH0oKTsKICAgICAgICAgICAgfSBicmVhazsKICAgICAgICBjYXNlIFdNX0NIQVI6CiAgICAgICAgICAgIGlmKG9uX2NoYXIpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHdjaGFyX3QgY2ggPSB3X3BhcmFtOwogICAgICAgICAgICAgICAgYXV0byBoYW5kbGVyID0gb25fY2hhcjsKICAgICAgICAgICAgICAgIG9uX2NoYXIgPSBDaGFySGFuZGxlcigpOwogICAgICAgICAgICAgICAgaGFuZGxlcihjaCA9PSBMJ1x4MEQnPyBMJ1xuJyA6IGNoKTsKICAgICAgICAgICAgfSBicmVhazsKICAgIH0KICAgIHJldHVybiBEZWZXaW5kb3dQcm9jKGh3bmQsIG1zZywgd19wYXJhbSwgbF9wYXJhbSk7Cn0KCmludCBXSU5BUEkgV2luTWFpbiAoSElOU1RBTkNFIGhJbnN0YW5jZSwgSElOU1RBTkNFLCBMUFNUUiwgaW50IG5DbWRTaG93KQp7CiAgICBXTkRDTEFTUyB3aW5jbCA9IHt9OwogICAgd2luY2wuaEluc3RhbmNlID0gaEluc3RhbmNlOwogICAgd2luY2wubHBzekNsYXNzTmFtZSA9IFRFWFQoIlNGQyIpOwogICAgd2luY2wubHBmblduZFByb2MgPSB3aW5kb3dfcHJvY2VkdXJlOwogICAgUmVnaXN0ZXJDbGFzcygmd2luY2wpOwoKICAgIG1haW5faHduZCA9IENyZWF0ZVdpbmRvdyh3aW5jbC5scHN6Q2xhc3NOYW1lLCBURVhUKCIiKSwgV1NfT1ZFUkxBUFBFRFdJTkRPVywgMCwgMCwgNDAwLCAxMDAsIDAsIDAsIGhJbnN0YW5jZSwgMCk7CiAgICBTaG93V2luZG93KG1haW5faHduZCwgbkNtZFNob3cpOwoKICAgIE1TRyBtc2c7CiAgICB3aGlsZShHZXRNZXNzYWdlKCZtc2csIDAsIDAsIDApKQogICAgewogICAgICAgIFRyYW5zbGF0ZU1lc3NhZ2UoJm1zZyk7CiAgICAgICAgRGlzcGF0Y2hNZXNzYWdlKCZtc2cpOwogICAgfQp9Cg==