-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathSystem.Console.InternalTypes.pas
More file actions
331 lines (259 loc) · 10.1 KB
/
System.Console.InternalTypes.pas
File metadata and controls
331 lines (259 loc) · 10.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
unit System.Console.InternalTypes;
interface
{$I 'System.Console.inc'}
uses
System.Types,
System.Classes,
System.SysUtils,
System.Console.Types;
type
//don't add interface here, otherwise we will need to make methods virtual;
TConsoleImplementation = class
protected
procedure RaiseUnsupported(const methodName : string);
function PlatformName : string;virtual;abstract;
//protected as only called from this class
procedure WriteString(const value : string);virtual;abstract;
procedure SetTempColors(foreground : TConsoleColor; background : TConsoleColor = TConsoleColor.NotSet);virtual;abstract;
procedure RestoreColors;virtual;abstract;
public
function OpenStandardInput : TStream;virtual;abstract;
function OpenStandardOutput : TStream;virtual;abstract;
function OpenStandardError : TStream;virtual;abstract;
function GetOrCreateReader : TTextReader;virtual;abstract;
function GetBackgroundColor: TConsoleColor; virtual;abstract;
procedure SetBackgroundColor(value: TConsoleColor); virtual;abstract;
function GetForegroundColor: TConsoleColor; virtual;abstract;
procedure SetForegroundColor(value: TConsoleColor); virtual;abstract;
procedure SetColors(foreground : TConsoleColor; background : TConsoleColor);virtual;abstract;
procedure ResetColors;virtual;abstract;
function GetBufferWidth : integer;virtual;abstract;
procedure SetBufferWidth(value : integer);virtual;abstract;
function GetBufferHeight : integer;virtual;abstract;
procedure SetBufferHeight(value : integer);virtual;abstract;
procedure SetBufferSize(width : integer; height : integer);virtual;abstract;
function GetCursorPosition: TPoint;virtual;abstract;
procedure SetCursorPosition(x : integer; y : integer);virtual;abstract;
function GetCursorLeft : integer; virtual;abstract;
procedure SetCursorLeft(value: integer); virtual;abstract;
function GetCursorTop : integer; virtual;abstract;
procedure SetCursorTop(value : integer); virtual;abstract;
function GetCursorSize : integer;virtual;abstract;
procedure SetCursorSize(value : integer); virtual;abstract;
function GetCursorVisible : boolean;virtual;abstract;
procedure SetCursorVisible(value : boolean); virtual;abstract;
function GetTitle : string;virtual;abstract;
procedure SetTitle(const value : string);virtual;abstract;
function GetIsErrorRedirected : boolean;virtual;abstract;
function GetIsInputRedirected : boolean;virtual;abstract;
function GetIsOutputRedirected: boolean;virtual;abstract;
function GetConsoleOutputEncoding : TEncoding;virtual;abstract;
procedure SetConsoleOutputEncoding(const value : TEncoding);virtual;abstract;
function GetConsoleInputEncoding : TEncoding;virtual;abstract;
procedure SetConsoleInputEncoding(const value : TEncoding);virtual;abstract;
function GetWindowSize : TSize;virtual;abstract;
procedure SetWindowSize(const width : integer; height : integer);virtual;abstract;
function GetWindowPosition : TPoint;virtual;abstract;
procedure SetWindowPosition(Left, Top: Integer);virtual;abstract;
function GetLargestWindowHeight : integer;virtual;abstract;
function GetLargestWindowWidth : integer;virtual;abstract;
function GetCancelKeyPress : TConsoleCancelEventHandler;virtual;abstract;
procedure SetCancelKeyPress(value : TConsoleCancelEventHandler);virtual;abstract;
procedure Beep(frequency : Cardinal; duration: Cardinal); overload; virtual;abstract;
procedure Beep; overload; virtual;abstract;
procedure Clear;virtual;abstract;
procedure MoveBufferArea(const sourceLeft, sourceTop, sourceWidth, sourceHeight, targetLeft, targetTop: Integer); overload; virtual;
procedure MoveBufferArea(const sourceLeft, sourceTop, sourceWidth, sourceHeight, targetLeft, targetTop: Integer; sourceChar: Char; sourceForeColor, sourceBackColor: TConsoleColor); overload; virtual;
function GetKeyAvailable : boolean;virtual;abstract;
function ReadKey(intercept: boolean) : TConsoleKeyInfo;virtual;abstract;
function GetCapsLock: boolean; virtual;abstract;
function GetNumLock : boolean; virtual;abstract;
function GetTreatControlCAsInput: boolean;virtual;abstract;
procedure SetTreatControlCAsInput(value : boolean);virtual;abstract;
//these all call into WriteString
procedure Write(value : boolean);overload;
procedure Write(c : Char);overload;virtual;
procedure Write(chars : TArray<Char>);overload;
procedure Write(const s : string);overload;
procedure Write(const obj : TObject);overload;
procedure Write<T>(const value : T);overload;
procedure WriteLine;overload;
procedure WriteLine(value : boolean);overload;
procedure WriteLine(c : Char);overload;
procedure WriteLine(const obj : TObject);overload;
procedure WriteLine(const s : string);overload;
procedure WriteLine<T>(const value : T);overload;
end;
TConsoleImplFactory = class
public
class function CreateConsole : TConsoleImplementation;static;
end;
TFileAccess = (
// Specifies read access to the file. Data can be read from the file and
// the file pointer can be moved. Combine with WRITE for read-write access.
Read = 1,
// Specifies write access to the file. Data can be written to the file and
// the file pointer can be moved. Combine with READ for read-write access.
Write = 2
);
const
// Unlike many other buffer sizes throughout .NET, which often only affect performance, this buffer size has a
// functional impact on interactive console apps, where the size of the buffer passed to ReadFile/Console impacts
// how many characters the cmd window will allow to be typed as part of a single line. It also does affect perf,
// in particular when input is redirected and data may be consumed from a larger source. This 4K default size is the
// same as is currently used by most other environments/languages tried.
ReadBufferSize = 4096;
// There's no visible functional impact to the write buffer size, and as we auto flush on every write,
// there's little benefit to having a large buffer. So we use a smaller buffer size to reduce working set.
const WriteBufferSize = 256;
implementation
uses
System.TypInfo,
System.Rtti,
System.Console,
{$IFDEF MSWINDOWS}
System.Console.Windows;
{$ELSEIF MACOS }
System.Console.Posix;
{$ELSEIF LINUX }
System.Console.Posix;
{$ELSE}
Invalid platform
{$IFEND}
procedure TConsoleImplementation.Write(const s: string);
begin
WriteString(s);
end;
procedure TConsoleImplementation.Write(value: boolean);
begin
WriteString(BoolToStr(value, true));
end;
procedure TConsoleImplementation.MoveBufferArea(const sourceLeft, sourceTop, sourceWidth, sourceHeight, targetLeft, targetTop: Integer; sourceChar: Char; sourceForeColor, sourceBackColor: TConsoleColor);
begin
RaiseUnsupported('MoveBufferArea');
end;
procedure TConsoleImplementation.MoveBufferArea(const sourceLeft, sourceTop, sourceWidth, sourceHeight, targetLeft, targetTop: Integer);
begin
RaiseUnsupported('MoveBufferArea');
end;
procedure TConsoleImplementation.RaiseUnsupported(const methodName : string);
begin
if Console.RaiseUnsupported then
raise EUnsupportedException.Create('Method [' + methodName + '] is not supported on ' + PlatformName );
end;
procedure TConsoleImplementation.Write(const obj: TObject);
begin
if obj <> nil then
WriteString(obj.ToString);
end;
procedure TConsoleImplementation.Write<T>(const value: T);
var
thevalue : Tvalue;
arrayElement : Tvalue;
arrayLength : integer;
i : integer;
begin
//Tvalue.Make<T> only in 10.4 and does this anyway
Tvalue.Make(@value, System.TypeInfo(T), thevalue);
if thevalue.IsArray then
begin
arrayLength := thevalue.GetArrayLength;
if arrayLength = 0 then
exit;
for i := 0 to arrayLength -1 do
begin
arrayElement := thevalue.GetArrayElement(i);
Write(arrayElement.ToString);
end;
exit;
end;
if thevalue.IsObject and (thevalue.TypeInfo.Kind <> tkInterface) then
begin
Write(thevalue.AsObject);
exit;
end;
if thevalue.TypeInfo.Kind = tkRecord then
begin
Write('Write<T> - unsupported type : record');
exit;
end;
Write(thevalue.ToString);
end;
procedure TConsoleImplementation.Write(chars : TArray<Char>);
begin
WriteString(string(chars));
end;
procedure TConsoleImplementation.WriteLine(const s: string);
begin
WriteString(s + sLineBreak);
end;
procedure TConsoleImplementation.WriteLine(const obj: TObject);
begin
WriteString(obj.ToString + sLineBreak);
end;
procedure TConsoleImplementation.WriteLine<T>(const value: T);
var
thevalue : Tvalue;
arrayElement : Tvalue;
arrayLength : integer;
i : integer;
begin
//Tvalue.Make<T> only in 10.4 and does this anyway
Tvalue.Make(@value, System.TypeInfo(T), thevalue);
if thevalue.IsArray then
begin
arrayLength := thevalue.GetArrayLength;
if arrayLength = 0 then
begin
WriteLine;//writeline always writes newline
exit;
end;
for i := 0 to arrayLength -1 do
begin
arrayElement := thevalue.GetArrayElement(i);
Write(arrayElement.ToString + sLineBreak);
end;
exit;
end;
if thevalue.IsObject and (thevalue.TypeInfo.Kind <> tkInterface) then
begin
WriteLine(thevalue.AsObject);
exit;
end;
if thevalue.TypeInfo.Kind = tkRecord then
begin
WriteLine('WriteLine<T> - unsupported type : record');
exit;
end;
Write(thevalue.ToString + sLineBreak);
end;
procedure TConsoleImplementation.WriteLine(c: Char);
begin
WriteString(c + sLineBreak);
end;
procedure TConsoleImplementation.WriteLine(value: boolean);
begin
WriteString(BoolToStr(value, true) + sLineBreak);
end;
procedure TConsoleImplementation.Write(c: Char);
begin
WriteString(string(c));
end;
procedure TConsoleImplementation.WriteLine;
begin
WriteString(sLineBreak);
end;
{ TConsoleImplFactory }
class function TConsoleImplFactory.CreateConsole: TConsoleImplementation;
begin
{$IFDEF MSWINDOWS}
result := TWindowsConsole.Create;
{$ELSEIF MACOS }
result := TPosixConsole.Create;
{$ELSEIF LINUX }
result := TPosixConsole.Create;
{$ELSE}
Invalid platform
{$IFEND}
end;
end.