/
VT100ControlParser.m
135 lines (119 loc) · 3.98 KB
/
VT100ControlParser.m
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
//
// VT100ControlParser.m
// iTerm
//
// Created by George Nachman on 3/2/14.
//
//
#import "VT100ControlParser.h"
#import "VT100CSIParser.h"
#import "VT100XtermParser.h"
#import "VT100AnsiParser.h"
#import "VT100DCSParser.h"
#import "VT100OtherParser.h"
@interface VT100ControlParser ()
@property(nonatomic, retain) VT100DCSParser *dcsParser;
@end
@implementation VT100ControlParser
- (id)init {
self = [super init];
if (self) {
_dcsParser = [[VT100DCSParser alloc] init];
}
return self;
}
- (void)dealloc {
[_dcsParser release];
[super dealloc];
}
- (void)unhookDCS {
[_dcsParser reset];
}
- (NSString *)hookDescription {
return _dcsParser.hookDescription;
}
- (void)parseDCSWithData:(unsigned char *)datap
datalen:(int)datalen
rmlen:(int *)rmlen
token:(VT100Token *)token
encoding:(NSStringEncoding)encoding
savedState:(NSMutableDictionary *)savedState {
iTermParserContext context = iTermParserContextMake(datap, datalen);
[_dcsParser decodeFromContext:&context
token:token
encoding:encoding
savedState:savedState];
*rmlen = context.rmlen;
}
- (BOOL)dcsHooked {
return _dcsParser.isHooked;
}
- (void)parseControlWithData:(unsigned char *)datap
datalen:(int)datalen
rmlen:(int *)rmlen
incidentals:(CVector *)incidentals
token:(VT100Token *)token
encoding:(NSStringEncoding)encoding
savedState:(NSMutableDictionary *)savedState
dcsHooked:(BOOL *)dcsHooked {
if (_dcsParser.isHooked || isDCS(datap, datalen)) {
[self parseDCSWithData:datap
datalen:datalen
rmlen:rmlen
token:token
encoding:encoding
savedState:savedState];
*dcsHooked = self.dcsParser.isHooked;
} else if (isCSI(datap, datalen)) {
iTermParserContext context = iTermParserContextMake(datap, datalen);
[VT100CSIParser decodeFromContext:&context
incidentals:incidentals
token:token];
*rmlen = context.rmlen;
} else if (isXTERM(datap, datalen)) {
iTermParserContext context = iTermParserContextMake(datap, datalen);
[VT100XtermParser decodeFromContext:&context
incidentals:incidentals
token:token
encoding:encoding
savedState:savedState];
*rmlen = context.rmlen;
} else if (isANSI(datap, datalen)) {
[VT100AnsiParser decodeBytes:datap
length:datalen
bytesUsed:rmlen
token:token];
} else {
NSCParameterAssert(datalen > 0);
switch (*datap) {
case VT100CC_NULL:
token->type = VT100_SKIP;
*rmlen = 0;
while (datalen > 0 && *datap == '\0') {
++datap;
--datalen;
++*rmlen;
}
break;
case VT100CC_ESC:
if (datalen == 1) {
token->type = VT100_WAIT;
} else {
[VT100OtherParser decodeBytes:datap
length:datalen
bytesUsed:rmlen
token:token
encoding:encoding];
}
break;
default:
token->type = *datap;
*rmlen = 1;
break;
}
}
}
- (void)startTmuxRecoveryMode {
[_dcsParser startTmuxRecoveryMode];
}
@end