@@ -57,198 +57,86 @@ func procWindowChangeEvent(eventPayload string, windowResize func(h int, w int)
57
57
58
58
func inPipe (from io.Reader , to io.Writer , windowResize func (h int , w int ) error ) error {
59
59
inBuf := make ([]byte , DefaultBufferSize )
60
- eventBuf := make ([]byte , DefaultBufferSize )
61
-
62
- evSize := 0
63
60
64
61
for {
65
62
// Receive data
66
63
n , err := from .Read (inBuf )
67
64
if err != nil {
68
65
if errors .Is (err , io .EOF ) {
69
- if evSize > 0 {
70
- // Still contain event cache data, send them all
71
- _ , err = to .Write (eventBuf [:evSize ])
72
- if err != nil {
73
- return fmt .Errorf ("failed to pipe to stdin: %w" , err )
74
- }
75
- }
76
66
break
77
67
} else {
78
68
return fmt .Errorf ("failed to read from stdin: %w" , err )
79
69
}
80
70
}
81
71
82
- // Set start index
83
- start := 0
84
- if evSize > 0 {
85
- // Last loop remains unprocessed data, continue to process
86
- if evSize < EscapeWindowChangePrefixLen {
87
- // Prefix not matched, start to match prefix
88
- for ; start + evSize <= EscapeWindowChangePrefixLen ; start ++ { // Start from the first byte after \x1B
89
- eventBuf [start + evSize ] = inBuf [start ]
90
- if inBuf [start ] != EscapeWindowChangePrefix [start + evSize - 1 ] {
91
- // Mismatch
92
- start = 0
93
- break
94
- }
95
- }
72
+ dataBuf := inBuf [:n ]
96
73
97
- if start == 0 { // Mismatch
98
- // Unable to handle this, send buffered event data to server
99
- _ , err = to .Write (eventBuf [:evSize ])
100
- if err != nil {
101
- return fmt .Errorf ("failed to pipe to stdin: %w" , err )
102
- }
103
- evSize = 0 // reset
104
- }
105
- }
74
+ for { // Process all events in a single input event (latest one overwrites all before)
75
+ // Check if event exists
76
+ dataLen := len (dataBuf )
77
+ eventStartIndex := bytes .Index (dataBuf , EscapeWindowChangePrefix )
106
78
107
- if evSize > 0 {
108
- // Prefix match, start receiving event bytes till match suffix
109
- for ; start < n ; start ++ {
110
- eventBuf [start + evSize ] = inBuf [start ]
111
- if inBuf [start ] == EscapeWindowChangeSuffix {
112
- break
113
- }
114
- }
115
-
116
- if start >= n {
117
- // Message incomplete, save it and wait for next loop
118
- evSize += start
119
- continue
120
- }
121
-
122
- // else: suffix match, message complete
123
- // Maybe contain some incomplete event fragments, so go reversely to find if any prefix match
124
- eventPayloadSliceFrom := EscapeWindowChangePrefixLen // discard prefix
125
- eventPayload := eventBuf [:evSize + start ] // discard suffix
126
- eventPrefixLastIndex := bytes .LastIndex (eventPayload , EscapeWindowChangePrefix )
127
- if eventPrefixLastIndex != 0 {
128
- // Include invalid events
129
-
130
- // Send invalid events as raw content to writer
131
- _ , err = to .Write (eventPayload [:eventPrefixLastIndex ])
132
- if err != nil {
133
- return fmt .Errorf ("failed to pipe to stdin: %w" , err )
134
- }
135
-
136
- // Slice from new location
137
- eventPayloadSliceFrom = eventPrefixLastIndex + EscapeWindowChangePrefixLen
79
+ if eventStartIndex == - 1 {
80
+ // No event, just pipe normally
81
+ _ , err = to .Write (dataBuf [:dataLen ])
82
+ if err != nil {
83
+ return fmt .Errorf ("failed to pipe to stdin: %w" , err )
138
84
}
139
- err = procWindowChangeEvent (string (eventPayload [eventPayloadSliceFrom :]), windowResize )
85
+ break // Proceed to next loop
86
+ } else if eventStartIndex > 0 { // 0 means nothing to send
87
+ // Send bytes before event
88
+ _ , err = to .Write (dataBuf [:eventStartIndex ])
140
89
if err != nil {
141
- // Unable to handle this, send buffered event data to server
142
- _ , err = to .Write (eventBuf [eventPrefixLastIndex :evSize ])
143
- if err != nil {
144
- return fmt .Errorf ("failed to pipe to stdin: %w" , err )
145
- }
146
- start = 0 // reset
147
- } else {
148
- start += 1 // Skip suffix
90
+ return fmt .Errorf ("failed to pipe to stdin: %w" , err )
149
91
}
150
-
151
- evSize = 0 // reset
152
92
}
153
- }
154
-
155
- i := start
156
-
157
- // Check byte by byte
158
- for ; i < n ; i ++ {
159
- if inBuf [i ] == EscapeWindowChangePrefix [0 ] { // ESC for ANSI escape sequences
160
- break
161
- }
162
- }
163
-
164
- if i >= n {
165
- // No event, just pipe normally
166
- _ , err = to .Write (inBuf [start :n ])
167
- if err != nil {
168
- return fmt .Errorf ("failed to pipe to stdin: %w" , err )
169
- }
170
- continue // Proceed to next loop
171
- }
172
-
173
- // Otherwise: event caused early end
174
- _ , err = to .Write (inBuf [start :i ]) // pipe data before event
175
- if err != nil {
176
- return fmt .Errorf ("failed to pipe to stdin: %w" , err )
177
- }
178
93
179
- // Match prefix
180
- for evSize = 0 ; (i + evSize < n ) && (evSize < EscapeWindowChangePrefixLen ); evSize ++ { // Start from the first byte
181
- eventBuf [evSize ] = inBuf [i + evSize ]
182
- if inBuf [i + evSize ] != EscapeWindowChangePrefix [evSize ] {
183
- // Mismatch
184
- evSize = 0
185
- break
186
- }
187
- }
94
+ // Match suffix
95
+ eventEndIndex := eventStartIndex + len (EscapeWindowChangePrefix )
188
96
189
- if evSize == 0 { // Mismatch
190
- // Unable to handle this, send to server
191
- _ , err = to . Write ( inBuf [ i : n ])
192
- if err != nil {
193
- return fmt . Errorf ( "failed to pipe to stdin: %w" , err )
97
+ // else: prefix all match, extract all bytes into event buffer till match suffix
98
+ for ; eventEndIndex < dataLen ; eventEndIndex ++ {
99
+ if dataBuf [ eventEndIndex ] == EscapeWindowChangeSuffix {
100
+ break
101
+ }
194
102
}
195
- continue // Proceed to next loop
196
- }
197
103
198
- if i + evSize >= n {
199
- // Message incomplete, save it and wait for next loop
200
- continue
201
- }
202
-
203
- // else: prefix all match, extract all bytes into event buffer till match suffix
204
- for ; i + evSize < n ; evSize ++ {
205
- eventBuf [evSize ] = inBuf [i + evSize ]
206
- if inBuf [i + evSize ] == EscapeWindowChangeSuffix {
207
- break
104
+ if eventEndIndex >= dataLen {
105
+ // Incomplete event, just pipe normally
106
+ _ , err = to .Write (dataBuf [eventStartIndex :])
107
+ if err != nil {
108
+ return fmt .Errorf ("failed to pipe to stdin: %w" , err )
109
+ }
110
+ break // Proceed to next loop
208
111
}
209
- }
210
112
211
- if i + evSize >= n {
212
- // Message incomplete, save it and wait for next loop
213
- continue
214
- }
113
+ // else: event all extracted! time to analyse
114
+ // Maybe contain some incomplete event fragments, so go reversely to find if any prefix match
115
+ eventPayload := dataBuf [eventStartIndex :eventEndIndex ] // discard suffix
116
+ eventPrefixLastIndex := bytes .LastIndex (eventPayload , EscapeWindowChangePrefix )
117
+ if eventPrefixLastIndex > 0 {
118
+ // Include invalid events
215
119
216
- // else: event all extracted! time to analyse
217
- // Maybe contain some incomplete event fragments, so go reversely to find if any prefix match
218
- eventPayloadSliceFrom := EscapeWindowChangePrefixLen // discard prefix
219
- eventPayload := eventBuf [:evSize ] // discard suffix
220
- eventPrefixLastIndex := bytes .LastIndex (eventPayload , EscapeWindowChangePrefix )
221
- if eventPrefixLastIndex != 0 {
222
- // Include invalid events
223
-
224
- // Send invalid events as raw content to writer
225
- _ , err = to .Write (eventPayload [:eventPrefixLastIndex ])
226
- if err != nil {
227
- return fmt .Errorf ("failed to pipe to stdin: %w" , err )
120
+ // Send invalid events as raw content
121
+ _ , err = to .Write (eventPayload [:eventPrefixLastIndex ])
122
+ if err != nil {
123
+ return fmt .Errorf ("failed to pipe to stdin: %w" , err )
124
+ }
228
125
}
229
126
230
- // Slice from new location
231
- eventPayloadSliceFrom = eventPrefixLastIndex + EscapeWindowChangePrefixLen
232
- }
233
- err = procWindowChangeEvent (string (eventPayload [eventPayloadSliceFrom :]), windowResize )
234
- if err != nil {
235
- // Something is wrong, we can't handle this event, so send without processing
236
- evSize = 0 // reset
237
- _ , err = to .Write (inBuf [i + eventPrefixLastIndex : n ]) // Send everything
238
- if err != nil {
239
- return fmt .Errorf ("failed to proc window change event: %w" , err )
127
+ // Process event
128
+ if err = procWindowChangeEvent (string (eventPayload [eventPrefixLastIndex + len (EscapeWindowChangePrefix ):]), windowResize ); err != nil {
129
+ // Something is wrong, we can't handle this event, so send without processing
130
+ _ , err = to .Write (dataBuf [eventStartIndex + eventPrefixLastIndex :]) // Send everything
131
+ if err != nil {
132
+ return fmt .Errorf ("failed to proc window change event: %w" , err )
133
+ }
134
+ break // Proceed to next loop
240
135
}
241
- continue // Proceed to next loop
242
- }
243
136
244
- // Send remain bytes
245
- _ , err = to .Write (inBuf [i + evSize + 1 : n ])
246
- if err != nil {
247
- return fmt .Errorf ("failed to pipe to stdin: %w" , err )
137
+ // Continue to process remain bytes
138
+ dataBuf = dataBuf [eventEndIndex + 1 :]
248
139
}
249
-
250
- // Reset event size as already processed
251
- evSize = 0
252
140
}
253
141
254
142
return nil
0 commit comments