forked from gnachman/iTerm2
/
VT100LineInfo.m
114 lines (101 loc) · 2.58 KB
/
VT100LineInfo.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
//
// VT100LineInfo.m
// iTerm
//
// Created by George Nachman on 11/17/13.
//
//
#import "VT100LineInfo.h"
@implementation VT100LineInfo {
char *dirty_;
int width_;
BOOL anyCharPossiblyDirty_; // No means nothing is dirty. Yes means MAYBE something is dirty.
NSTimeInterval timestamp_;
}
@synthesize timestamp = timestamp_;
- (id)initWithWidth:(int)width {
self = [super init];
if (self) {
width_ = width;
dirty_ = realloc(dirty_, width);
[self setDirty:NO inRange:VT100GridRangeMake(0, width) updateTimestamp:YES];
[self updateTimestamp];
}
return self;
}
- (void)dealloc {
free(dirty_);
[super dealloc];
}
- (void)setDirty:(BOOL)dirty inRange:(VT100GridRange)range updateTimestamp:(BOOL)updateTimestamp {
#ifdef ITERM_DEBUG
assert(range.location >= 0);
assert(range.length >= 0);
assert(range.location + range.length <= width_);
#endif
if (dirty) {
anyCharPossiblyDirty_ = YES;
if (updateTimestamp) {
[self updateTimestamp];
}
} else if (range.location == 0 && range.length == width_) {
anyCharPossiblyDirty_ = NO;
}
int n = MAX(0, MIN(range.length, width_ - range.location));
memset(dirty_ + range.location, dirty, n);
}
- (VT100GridRange)dirtyRange {
VT100GridRange range = VT100GridRangeMake(-1, 0);
if (!anyCharPossiblyDirty_) {
return range;
}
for (int i = 0; i < width_; i++) {
if (dirty_[i]) {
range.location = i;
break;
}
}
if (range.location >= 0) {
for (int i = width_ - 1; i >= 0; i--) {
if (dirty_[i]) {
range.length = i - range.location + 1;
break;
}
}
}
if (range.location == -1) {
anyCharPossiblyDirty_ = NO;
}
return range;
}
- (void)updateTimestamp {
timestamp_ = [NSDate timeIntervalSinceReferenceDate];
}
- (BOOL)isDirtyAtOffset:(int)x {
#if DEBUG
assert(x >= 0 && x < width_);
#else
x = MIN(width_ - 1, MAX(0, x));
#endif
return dirty_[x];
}
- (BOOL)anyCharIsDirty {
if (!anyCharPossiblyDirty_) {
return NO;
} else {
for (int i = 0; i < width_; i++) {
if (dirty_[i]) {
return YES;
}
}
return NO;
}
}
- (id)copyWithZone:(NSZone *)zone {
VT100LineInfo *theCopy = [[VT100LineInfo alloc] initWithWidth:width_];
memmove(theCopy->dirty_, dirty_, width_);
theCopy->anyCharPossiblyDirty_ = anyCharPossiblyDirty_;
theCopy->timestamp_ = timestamp_;
return theCopy;
}
@end