Скачиваний:
35
Добавлен:
15.09.2014
Размер:
5.43 Кб
Скачать
// COM.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "COM.h"
#include "Exception.h"
using namespace Kingas;
using namespace Kingas::Communication;

#define defBufferSize 512
CRITICAL_SECTION g_OutputCriticalSection;
int g_CurrentY = 0;
#define defCommandLineY 23
#define defNotifyY (defCommandLineY - 1)
#define defConsoleWidth 80
TCHAR g_SpaceBuffer[defConsoleWidth];

void SyncClear()
{
	COORD coord = {0};
	EnterCriticalSection(&g_OutputCriticalSection);
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
	for (int i = 0; i < defNotifyY; i++)
		Cout << g_SpaceBuffer << endl;
	LeaveCriticalSection(&g_OutputCriticalSection);
}

void SyncOutput(String message)
{
	EnterCriticalSection(&g_OutputCriticalSection);
	if (g_CurrentY + message.length() / defConsoleWidth + 1 >= defNotifyY)
	{
		g_CurrentY = 0;
		SyncClear();
	}
	COORD coord = {0};
	coord.Y = g_CurrentY;
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
	Cout << message;
	Cout.flush();
	g_CurrentY += message.length() / defConsoleWidth + 1;
	LeaveCriticalSection(&g_OutputCriticalSection);
}

void SyncOutputWithNewLine(String message)
{
	EnterCriticalSection(&g_OutputCriticalSection);
	if (g_CurrentY + message.length() / defConsoleWidth + 1 >= defNotifyY)
	{
		g_CurrentY = 0;
		SyncClear();
	}
	COORD coord = {0};
	coord.Y = g_CurrentY;
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
	Cout << message << endl;
	Cout.flush();
	g_CurrentY += message.length() / defConsoleWidth + 1;
	LeaveCriticalSection(&g_OutputCriticalSection);
}

void SyncNotify(String notify)
{
	COORD coord = {0};
	coord.Y = defNotifyY;
	EnterCriticalSection(&g_OutputCriticalSection);
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
	Cout << notify;
	LeaveCriticalSection(&g_OutputCriticalSection);
}

String SyncEnterCommand()
{
	String command;
	TCHAR key;
	COORD coord = {0};
	coord.Y = defCommandLineY;
	int lastLenght = 0;
	bool isBackspace = false;
	do
	{
		key = getch();
		if (key == 13) // Enter
			break;
		else if (key == 8) { // Backspace
			if (command.length() > 0)
				command.pop_back();
			isBackspace = true;
		}
		else
			command += key;
		lastLenght = command.length();
		EnterCriticalSection(&g_OutputCriticalSection);
		SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
		Cout << command;
		if (isBackspace) Cout << ' ';
		LeaveCriticalSection(&g_OutputCriticalSection);
		isBackspace = false;
	} while (true);
	EnterCriticalSection(&g_OutputCriticalSection);
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
	Cout << g_SpaceBuffer;
	LeaveCriticalSection(&g_OutputCriticalSection);
	coord.Y -= 1;
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
	Cout << g_SpaceBuffer;
	return command;
}

void WriteComplete(COM::CompleteStatus status)
{
	if (status == COM::CompleteStatus::Success)
		SyncOutputWithNewLine(_T("Write is complete."));
	else if (status == COM::CompleteStatus::Error)
	{
		SyncOutputWithNewLine(_T("Error write."));
		SyncOutputWithNewLine(Exception::ErrorString());
	}
#ifdef _DEBUG
	else
		SyncOutputWithNewLine(_T("Time-out write."));
#endif
}

void ReadComplete(TCHAR * message, COM::CompleteStatus status)
{
	if (status == COM::CompleteStatus::Success)
	{
		SyncOutputWithNewLine(_T("Read is complete."));
		SyncOutputWithNewLine(message);
	}
	else if (status == COM::CompleteStatus::Error)
	{
		SyncOutputWithNewLine(_T("Error read."));
		SyncOutputWithNewLine(Exception::ErrorString());
	}
#ifdef _DEBUG
	else
		SyncOutputWithNewLine(_T("Time-out read."));
#endif
	delete[] message;
}

int _tmain(int argc, TCHAR* argv[])
{
	for (int i = 0; i < defConsoleWidth - 1; i++)
		g_SpaceBuffer[i] = ' ';
	g_SpaceBuffer[defConsoleWidth - 1] = 0;
	Cout.imbue(locale(".866"));
	Cin.imbue(locale(".866"));
	COM comm;
	TCHAR buffer[defBufferSize + 1];
	String command;
	InitializeCriticalSection(&g_OutputCriticalSection);
	unsigned int port;
	do
	{
		try 
		{
			SyncNotify(_T("Enter command 'exit', 'open', 'close', 'send', 'receive', 'abort'(receive):"));
			command = SyncEnterCommand();
			if (command == _T("exit"))
				break;
			else if (command == _T("open"))
			{
				SyncNotify(_T("Enter port number:"));
				Stream stream;
				stream << SyncEnterCommand();
				stream >> port;
				if (port > 255)
					SyncOutputWithNewLine(_T("Port number must be < 256."));
				else {
					comm.Open(port);
					SyncOutputWithNewLine(_T("Port is opened."));
				}
			}
			else if (command == _T("close")) {
				if (comm.Close())
					SyncOutputWithNewLine(_T("Port is closed."));
			}
			else if (command == _T("send")) {
				SyncNotify(_T("Enter line to send:"));
				command = SyncEnterCommand();
				comm.AsyncWrite(command.c_str(), WriteComplete);
			}
			else if (command == _T("abort"))
				comm.AbortReading();
			else if (command == _T("receive"))
				comm.AsyncRead(ReadComplete, defBufferSize);
			else
				SyncOutputWithNewLine(_T("Unknown command."));
		}
		catch (Exception ex) {
			SyncOutputWithNewLine(ex.What());
			if (ex.Error()) SyncOutputWithNewLine(ex.ErrorMessage());
		}
	} while (true);
	Sleep(500);
	DeleteCriticalSection(&g_OutputCriticalSection);
	return 0;
}
Соседние файлы в папке Source