]> git.tdb.fi Git - libs/core.git/blob - source/console.cpp
Convert C-style casts to C++-style
[libs/core.git] / source / console.cpp
1 /* $Id$
2
3 This file is part of libmspio
4 Copyright © 2008  Mikko Rasa, Mikkosoft Productions
5 Distributed under the LGPL
6 */
7
8 #ifndef WIN32
9 #include <errno.h>
10 #include <fcntl.h>
11 #include <termios.h>
12 #endif
13 #include <msp/core/except.h>
14 #include "console.h"
15
16 namespace {
17
18 #ifndef WIN32
19 termios orig_attr;
20 #endif
21
22 } // namespace
23
24 namespace Msp {
25 namespace IO {
26
27 Console::Console(unsigned n)
28 {
29         if(n>2)
30                 throw InvalidParameterValue("Invalid parameter for Console::Console");
31
32         mode=(n==0 ? M_READ : M_WRITE);
33
34 #ifdef WIN32
35         switch(n)
36         {
37         case 0: handle=GetStdHandle(STD_INPUT_HANDLE); break;
38         case 1: handle=GetStdHandle(STD_OUTPUT_HANDLE); break;
39         case 2: handle=GetStdHandle(STD_ERROR_HANDLE); break;
40         }
41 #else
42         handle=n;
43
44         if(handle==0)
45                 tcgetattr(handle, &orig_attr);
46 #endif
47
48         if(n==0)
49                 set_events(P_INPUT);
50 }
51
52 Console::~Console()
53 {
54 #ifndef WIN32
55         if(handle==0)
56                 tcsetattr(handle, TCSADRAIN, &orig_attr);
57 #endif
58 }
59
60 void Console::set_block(bool b)
61 {
62 #ifdef WIN32
63         // XXX Dunno how to do this in win32
64         (void)b;
65 #else
66         int flags=fcntl(0, F_GETFL);
67         flags=(flags&~O_NONBLOCK) | (b?0:O_NONBLOCK);
68         fcntl(0, F_SETFL, flags);
69 #endif
70 }
71
72 void Console::set_local_echo(bool e)
73 {
74         if(!(mode&M_READ))
75                 throw InvalidState("Local echo can only be set on input console");
76
77 #ifdef WIN32
78         DWORD m;
79         GetConsoleMode(handle, &m);
80         SetConsoleMode(handle, (m&~ENABLE_ECHO_INPUT) | (e?ENABLE_ECHO_INPUT:0));
81 #else
82         termios t;
83         tcgetattr(0, &t);
84         t.c_lflag=(t.c_lflag&~ECHO) | (e?ECHO:0);
85         tcsetattr(0, TCSADRAIN, &t);
86 #endif
87 }
88
89 void Console::set_line_buffer(bool l)
90 {
91         if(!(mode&M_READ))
92                 throw InvalidState("Line buffering can only be set on input console");
93
94 #ifdef WIN32
95         DWORD m;
96         GetConsoleMode(handle, &m);
97         SetConsoleMode(handle, (m&~ENABLE_LINE_INPUT) | (l?ENABLE_LINE_INPUT:0));
98 #else
99         // XXX ICANON does more than just set line buffering, may need a bit more thought
100         termios t;
101         tcgetattr(0, &t);
102         t.c_lflag=(t.c_lflag&~ICANON) | (l?ICANON:0);
103         tcsetattr(0, TCSADRAIN, &t);
104 #endif
105 }
106
107 Handle Console::get_event_handle()
108 {
109         return 0;
110 }
111
112 unsigned Console::do_write(const char *buf, unsigned len)
113 {
114         if(!(mode&M_WRITE))
115                 throw InvalidState("Console is not writable");
116
117 #ifdef WIN32
118         DWORD ret;
119         if(!WriteFile(handle, buf, len, &ret, 0))
120                 throw SystemError("Writing to console failed", GetLastError());
121 #else
122         int ret=::write(1, buf, len);
123         if(ret==-1)
124                 throw SystemError("Writing to console failed", errno);
125 #endif
126
127         return ret;
128 }
129
130 unsigned Console::do_read(char *buf, unsigned len)
131 {
132         if(!(mode&M_READ))
133                 throw InvalidState("Console is not readable");
134
135 #ifdef WIN32
136         DWORD ret;
137         if(!ReadFile(handle, buf, len, &ret, 0))
138                 throw SystemError("Reading from console failed", GetLastError());
139 #else
140         int ret=::read(0, buf, len);
141         if(ret==-1)
142         {
143                 if(errno==EAGAIN)
144                         return 0;
145                 else
146                         throw SystemError("Reading from console failed", errno);
147         }
148         else if(ret==0)
149                 eof_flag=true;
150 #endif
151
152         return ret;
153 }
154
155 Console &Console::instance(unsigned n)
156 {
157         static Console in(0);
158         static Console out(1);
159         static Console err(2);
160
161         switch(n)
162         {
163         case 0: return in;
164         case 1: return out;
165         case 2: return err;
166         }
167
168         throw InvalidParameterValue("Unknown Console instance requested");
169 }
170
171 Console &cin=Console::instance(0);
172 Console &cout=Console::instance(1);
173 Console &cerr=Console::instance(2);
174
175 } // namespace IO
176 } // namespace Msp