mirror of
https://github.com/JakeWharton/mosaic.git
synced 2025-11-04 06:32:26 +08:00
Random parser changes (#546)
This commit is contained in:
@ -186,26 +186,22 @@ public class TerminalParser(
|
|||||||
|
|
||||||
private fun parseApc(buffer: ByteArray, start: Int, limit: Int): Event? {
|
private fun parseApc(buffer: ByteArray, start: Int, limit: Int): Event? {
|
||||||
// TODO https://stackoverflow.com/a/71632523/132047
|
// TODO https://stackoverflow.com/a/71632523/132047
|
||||||
return parseUntilStringTerminator(buffer, start, limit) { stIndex, end ->
|
return parseUntilStringTerminator(buffer, start, limit) { b3Index, stIndex, end ->
|
||||||
val b3Index = start + 2
|
|
||||||
if (stIndex > b3Index && buffer[b3Index].toInt() == 'G'.code) {
|
if (stIndex > b3Index && buffer[b3Index].toInt() == 'G'.code) {
|
||||||
val delimiter = buffer.indexOf(';'.code.toByte(), b3Index, stIndex)
|
val delimiter = buffer.indexOf(';'.code.toByte(), b3Index, stIndex)
|
||||||
val b5Index = start + 4
|
val b5Index = start + 4
|
||||||
if (delimiter == -1 ||
|
if (delimiter != -1 &&
|
||||||
delimiter <= b5Index ||
|
delimiter > b5Index &&
|
||||||
buffer[start + 3].toInt() != 'i'.code ||
|
buffer[start + 3].toInt() == 'i'.code &&
|
||||||
buffer[b5Index].toInt() != '='.code
|
buffer[b5Index].toInt() == '='.code
|
||||||
) {
|
) {
|
||||||
UnknownEvent(buffer.copyOfRange(start, end))
|
return@parseUntilStringTerminator KittyGraphicsEvent(
|
||||||
} else {
|
|
||||||
KittyGraphicsEvent(
|
|
||||||
id = buffer.parseIntDigits(b5Index, delimiter),
|
id = buffer.parseIntDigits(b5Index, delimiter),
|
||||||
message = buffer.decodeToString(delimiter + 1, stIndex),
|
message = buffer.decodeToString(delimiter + 1, stIndex),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
UnknownEvent(buffer.copyOfRange(start, end))
|
|
||||||
}
|
}
|
||||||
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -275,6 +271,13 @@ public class TerminalParser(
|
|||||||
'm'.code,
|
'm'.code,
|
||||||
'M'.code,
|
'M'.code,
|
||||||
-> {
|
-> {
|
||||||
|
if (b3Index == finalIndex) {
|
||||||
|
// TODO If we are in UTF-8 mode it is at minimum 3 but could be up to 6.
|
||||||
|
val trailingEnd = end + 3
|
||||||
|
if (trailingEnd > limit) return null
|
||||||
|
offset = trailingEnd
|
||||||
|
break@error
|
||||||
|
}
|
||||||
if (buffer[b3Index].toInt() != '<'.code) {
|
if (buffer[b3Index].toInt() != '<'.code) {
|
||||||
break@error
|
break@error
|
||||||
}
|
}
|
||||||
@ -411,7 +414,9 @@ public class TerminalParser(
|
|||||||
}
|
}
|
||||||
} while (false)
|
} while (false)
|
||||||
|
|
||||||
return UnknownEvent(buffer.copyOfRange(start, end))
|
// Use 'offset' not 'end' because some sequences put data after the "final" index. This allows
|
||||||
|
// parsing of that trailing data to error and still be included in the unknown event.
|
||||||
|
return UnknownEvent(buffer.copyOfRange(start, offset))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun parseCsiLegacy(buffer: ByteArray, start: Int, limit: Int, codepoint: Int): CodepointEvent {
|
private fun parseCsiLegacy(buffer: ByteArray, start: Int, limit: Int, codepoint: Int): CodepointEvent {
|
||||||
@ -421,15 +426,15 @@ public class TerminalParser(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun parseDcs(buffer: ByteArray, start: Int, limit: Int): Event? {
|
private fun parseDcs(buffer: ByteArray, start: Int, limit: Int): Event? {
|
||||||
return parseUntilStringTerminator(buffer, start, limit) { stIndex, end ->
|
return parseUntilStringTerminator(buffer, start, limit) { b3Index, stIndex, end ->
|
||||||
val b4Index = start + 3
|
val b4Index = start + 3
|
||||||
if (stIndex > b4Index &&
|
if (stIndex > b4Index &&
|
||||||
buffer[start + 2].toInt() == '>'.code &&
|
buffer[b3Index].toInt() == '>'.code &&
|
||||||
buffer[b4Index].toInt() == '|'.code
|
buffer[b4Index].toInt() == '|'.code
|
||||||
) {
|
) {
|
||||||
TerminalVersionEvent(buffer.decodeToString(start + 4, stIndex))
|
TerminalVersionEvent(buffer.decodeToString(start + 4, stIndex))
|
||||||
} else {
|
} else {
|
||||||
UnknownEvent(buffer.copyOfRange(start, end))
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -439,14 +444,14 @@ public class TerminalParser(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun parsePm(buffer: ByteArray, start: Int, limit: Int): Event? {
|
private fun parsePm(buffer: ByteArray, start: Int, limit: Int): Event? {
|
||||||
return parseUntilStringTerminator(buffer, start, limit) { _, end ->
|
return parseUntilStringTerminator(buffer, start, limit) { _, _, _ ->
|
||||||
UnknownEvent(buffer.copyOfRange(start, end))
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun parseSos(buffer: ByteArray, start: Int, limit: Int): Event? {
|
private fun parseSos(buffer: ByteArray, start: Int, limit: Int): Event? {
|
||||||
return parseUntilStringTerminator(buffer, start, limit) { _, end ->
|
return parseUntilStringTerminator(buffer, start, limit) { _, _, _ ->
|
||||||
UnknownEvent(buffer.copyOfRange(start, end))
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -457,40 +462,45 @@ public class TerminalParser(
|
|||||||
offset = end
|
offset = end
|
||||||
|
|
||||||
val b3Index = start + 2
|
val b3Index = start + 2
|
||||||
val codepoint = when (buffer[b3Index].toInt()) {
|
error@ do {
|
||||||
'A'.code -> CodepointEvent.Up
|
val codepoint = when (buffer[b3Index].toInt()) {
|
||||||
'B'.code -> CodepointEvent.Down
|
'A'.code -> CodepointEvent.Up
|
||||||
'C'.code -> CodepointEvent.Right
|
'B'.code -> CodepointEvent.Down
|
||||||
'D'.code -> CodepointEvent.Left
|
'C'.code -> CodepointEvent.Right
|
||||||
'F'.code -> CodepointEvent.End
|
'D'.code -> CodepointEvent.Left
|
||||||
'H'.code -> CodepointEvent.Home
|
'F'.code -> CodepointEvent.End
|
||||||
'P'.code -> CodepointEvent.F1
|
'H'.code -> CodepointEvent.Home
|
||||||
'Q'.code -> CodepointEvent.F2
|
'P'.code -> CodepointEvent.F1
|
||||||
'R'.code -> CodepointEvent.F3
|
'Q'.code -> CodepointEvent.F2
|
||||||
'S'.code -> CodepointEvent.F3
|
'R'.code -> CodepointEvent.F3
|
||||||
0x1b -> {
|
'S'.code -> CodepointEvent.F3
|
||||||
// libvaxis added a guard against this case
|
0x1b -> {
|
||||||
// https://github.com/rockorager/libvaxis/commit/b68864c3babf2767c15c52911179e8ee9158e1d2
|
// libvaxis added a guard against this case
|
||||||
offset = b3Index
|
// https://github.com/rockorager/libvaxis/commit/b68864c3babf2767c15c52911179e8ee9158e1d2
|
||||||
return UnknownEvent(buffer.copyOfRange(start, b3Index))
|
offset = b3Index
|
||||||
|
break@error
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> break@error
|
||||||
}
|
}
|
||||||
else -> {
|
return CodepointEvent(codepoint)
|
||||||
return UnknownEvent(buffer.copyOfRange(start, end))
|
} while (false)
|
||||||
}
|
|
||||||
}
|
// Use 'offset' not 'end' because if end is an escape we back up the offset.
|
||||||
return CodepointEvent(codepoint)
|
return UnknownEvent(buffer.copyOfRange(start, offset))
|
||||||
}
|
}
|
||||||
|
|
||||||
private inline fun parseUntilStringTerminator(
|
private inline fun parseUntilStringTerminator(
|
||||||
buffer: ByteArray,
|
buffer: ByteArray,
|
||||||
start: Int,
|
start: Int,
|
||||||
limit: Int,
|
limit: Int,
|
||||||
crossinline handler: (stIndex: Int, end: Int) -> Event,
|
crossinline handler: (b3Index: Int, stIndex: Int, end: Int) -> Event?,
|
||||||
): Event? {
|
): Event? {
|
||||||
// TODO test string with 0x1b inside of it
|
// TODO test string with 0x1b inside of it
|
||||||
|
|
||||||
// Skip leading discriminator.
|
// Skip leading discriminator.
|
||||||
var searchFrom = start + 2
|
val b3Index = start + 2
|
||||||
|
var searchFrom = b3Index
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
val escIndex = buffer.indexOfFirstOrElse(
|
val escIndex = buffer.indexOfFirstOrElse(
|
||||||
@ -506,7 +516,8 @@ public class TerminalParser(
|
|||||||
if (buffer[slashIndex] == '\\'.code.toByte()) {
|
if (buffer[slashIndex] == '\\'.code.toByte()) {
|
||||||
val end = escIndex + 2
|
val end = escIndex + 2
|
||||||
offset = end
|
offset = end
|
||||||
return handler(escIndex, end)
|
return handler(b3Index, escIndex, end)
|
||||||
|
?: UnknownEvent(buffer.copyOfRange(start, end))
|
||||||
}
|
}
|
||||||
searchFrom = slashIndex
|
searchFrom = slashIndex
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,7 +13,7 @@ public class UnknownEvent(
|
|||||||
override fun toString(): String = buildString {
|
override fun toString(): String = buildString {
|
||||||
append("UnknownEvent(")
|
append("UnknownEvent(")
|
||||||
for (byte in bytes) {
|
for (byte in bytes) {
|
||||||
append(byte.toString(16).padStart(2, '0'))
|
append(byte.toUByte().toString(16).padStart(2, '0'))
|
||||||
}
|
}
|
||||||
append(')')
|
append(')')
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user