78 lines
2.4 KiB
Go
78 lines
2.4 KiB
Go
package protocol
|
|
|
|
// MatchPattern checks if the byte slice matches the magic string pattern.
|
|
//
|
|
// '?' matches any single character
|
|
// '*' matches zero or more characters
|
|
// '\' escapes special characters ('?', '*', '\')
|
|
// All other characters must match exactly
|
|
//
|
|
// Returns true if all magic bytes are matched, even if input has extra bytes.
|
|
func Match(magic string, input []byte) bool {
|
|
return match(magic, input, 0, 0)
|
|
}
|
|
|
|
// match is a recursive helper function that implements the matching logic
|
|
func match(magic string, input []byte, magicIndex, inputIndex int) bool {
|
|
// If we've reached the end of magic string, we've successfully matched all magic bytes
|
|
// It doesn't matter if there are extra bytes in the input
|
|
if magicIndex == len(magic) {
|
|
return true
|
|
}
|
|
|
|
// Handle escape character
|
|
if magic[magicIndex] == '\\' {
|
|
// Check if there's a next character in magic
|
|
if magicIndex+1 >= len(magic) {
|
|
// Backslash at end of magic string - treat as literal backslash
|
|
if inputIndex >= len(input) || input[inputIndex] != '\\' {
|
|
return false
|
|
}
|
|
return match(magic, input, magicIndex+1, inputIndex+1)
|
|
}
|
|
|
|
// Escape the next character - we need to match it literally
|
|
escapedChar := magic[magicIndex+1]
|
|
if inputIndex >= len(input) || input[inputIndex] != escapedChar {
|
|
return false
|
|
}
|
|
// Skip both the backslash and the escaped character in magic, move one in input
|
|
return match(magic, input, magicIndex+2, inputIndex+1)
|
|
}
|
|
|
|
// If we've reached the end of input but not magic string
|
|
if inputIndex == len(input) {
|
|
// If we have '*' at the current position, it can match zero characters
|
|
if magic[magicIndex] == '*' {
|
|
return match(magic, input, magicIndex+1, inputIndex)
|
|
}
|
|
return false
|
|
}
|
|
|
|
// Handle '*' character - matches zero or more characters
|
|
if magic[magicIndex] == '*' {
|
|
// Try matching zero characters
|
|
if match(magic, input, magicIndex+1, inputIndex) {
|
|
return true
|
|
}
|
|
// Try matching one or more characters
|
|
if inputIndex < len(input) && match(magic, input, magicIndex, inputIndex+1) {
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
// Handle '?' character - matches any single character
|
|
if magic[magicIndex] == '?' {
|
|
return match(magic, input, magicIndex+1, inputIndex+1)
|
|
}
|
|
|
|
// Handle exact character match
|
|
if magic[magicIndex] == input[inputIndex] {
|
|
return match(magic, input, magicIndex+1, inputIndex+1)
|
|
}
|
|
|
|
// No match found
|
|
return false
|
|
}
|