tagging release
[dasher.git] / trunk / Src / Win32 / Sockets / SocketInput.cpp
blob40a7f860b97cea6205839ac3b713c4f901033733
1 // SocketInput.cpp
3 // (C) Copyright Seb Wills 2005
5 //
7 // Win32-specific socket input class
11 #include "..\Common\WinCommon.h"
15 #include "./SocketInput.h"
17 #include "../../Win32/resource.h" // Probably shouldn't be including a file outside DasherCore. This is needed purely for the resource strings (IDS_...) used in the error message titles
21 #include <process.h>
23 #include <atlstr.h>
25 #include <stdlib.h>
27 #include <stddef.h>
31 using namespace Dasher;
35 // Track memory leaks on Windows to the line that new'd the memory
37 #ifdef _WIN32
39 #ifdef _DEBUG
41 #define DEBUG_NEW new( _NORMAL_BLOCK, THIS_FILE, __LINE__ )
43 #define new DEBUG_NEW
45 #undef THIS_FILE
47 static char THIS_FILE[] = __FILE__;
49 #endif
51 #endif
55 CSocketInput::CSocketInput(CEventHandler * pEventHandler, CSettingsStore * pSettingsStore)
57 :CSocketInputBase(pEventHandler, pSettingsStore) {
61 allocatedConsole = false;
65 // Although SetDebug is called in the constructore for CSocketInputBase, that invokes CSocketInputBase::SetDebug,
67 // and we need to invoke CSocketInput::SetDebug to bring up the debug messages window if debugging is enabled.
69 SetDebug(GetBoolParameter(BP_SOCKET_DEBUG));
73 // Windows-specific initialisation of Winsock:
75 WORD wVersionRequested;
77 WSADATA wsaData;
79 int err;
81 wVersionRequested = MAKEWORD( 2, 2 );
83 err = WSAStartup( wVersionRequested, &wsaData );
85 if ( err != 0 ) {
87 Tstring ErrTitle;
89 WinLocalisation::GetResourceString(IDS_ERR_SOCKET_TITLE, &ErrTitle);
91 MessageBox(NULL, _TEXT("Failed to initialize Winsock DLL"), ErrTitle.c_str(), MB_OK | MB_ICONEXCLAMATION);
99 CSocketInput::~CSocketInput() {
101 StopListening();
109 bool CSocketInput::LaunchReaderThread() {
113 unsigned threadId;
115 m_readerThreadHandle = (HANDLE) _beginthreadex(NULL, // security attributes
117 0, // stack size (0 = use default)
119 ThreadLauncherStub, // function to invoke
121 this, // argument
123 0, // initflag
125 &threadId); // receives thread ID
127 if(m_readerThreadHandle == 0) {
129 ReportErrnoError("Error creating reader thread");
131 return false;
135 return true;
141 void CSocketInput::CancelReaderThread() {
143 // FIXME: this is ugly; should have a way of cleanly terminating the thread
145 // The thread will need to use select to check the socket input buffer
147 // (rather than just calling recv which blocks indefinitely) and monitor a pleaseStop
149 // variable or something. But this seems to work OK...
151 TerminateThread(m_readerThreadHandle, 1);
157 void CSocketInput::ReportError(std::string s) {
159 CString msg(s.c_str()); //FIXME: check what goes on here with encodings. Is s in UTF-8? Do we need to call mbstowcs or something on it?
161 Tstring ErrTitle;
163 WinLocalisation::GetResourceString(IDS_ERR_SOCKET_TITLE, &ErrTitle);
165 MessageBox(NULL, msg, ErrTitle.c_str(), MB_OK | MB_ICONEXCLAMATION);
171 void CSocketInput::ReportErrnoError(std::string prefix) {
173 CString msg(prefix.c_str());
175 //wchar_t *tmp = new wchar_t[mbstowcs(NULL, (const char *) prefix.c_str(), 1024)];
179 msg += _TEXT(": Errno reports '");
181 msg += _tcserror(errno); // retrieve localised error message for the most recent socket error
183 CString msg2;
185 msg2.Format(_TEXT("'. WSAGetLastError returns %d."), WSAGetLastError());
187 msg += msg2;
191 Tstring ErrTitle;
193 WinLocalisation::GetResourceString(IDS_ERR_SOCKET_TITLE, &ErrTitle);
195 MessageBox(NULL, msg, ErrTitle.c_str(), MB_OK | MB_ICONEXCLAMATION);
201 void CSocketInput::SetDebug(bool _debug) {
202 if(_debug && !allocatedConsole) {
203 AllocConsole();
204 freopen("conout$", "w", stderr); // makes stderr go to the new console window (but not std::cerr, it seems!)
205 allocatedConsole = true;
207 CSocketInputBase::SetDebug(_debug);