Class: Expect::Pattern

Inherits:
Struct
  • Object
show all
Defined in:
lib/expect/pattern.rb

Overview

一个已编号的文本模式或事件及其回调;匹配结果统一使用字节偏移,便于精确消费 IO 缓冲。

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#callback ⇒ Object

Returns the value of attribute callback

Returns:

  • (Object) —

    the current value of callback



5
6
7
# File 'lib/expect/pattern.rb', line 5

def callback
  @callback
end

#number ⇒ Object

Returns the value of attribute number

Returns:

  • (Object) —

    the current value of number



5
6
7
# File 'lib/expect/pattern.rb', line 5

def number
  @number
end

#value ⇒ Object

Returns the value of attribute value

Returns:

  • (Object) —

    the current value of value



5
6
7
# File 'lib/expect/pattern.rb', line 5

def value
  @value
end

Instance Method Details

#call(subject) ⇒ Object

将匹配会话或超时会话数组交给回调;额外上下文由调用方闭包保存。



7
8
9
# File 'lib/expect/pattern.rb', line 7

def call(subject)
  callback&.call(subject)
end

#eof? ⇒ Boolean

识别 EOF 事件,供引擎在源结束时单独派发。

Returns:

  • (Boolean)


12
# File 'lib/expect/pattern.rb', line 12

def eof? = value == :eof

#locate(buffer, final: false, offset: 0) ⇒ Object

在缓冲中定位字符串或正则,返回 [字节偏移, 字节长度, 捕获组];事件或未匹配返回 nil。 buffer 应为二进制字符串,offset 仅用于字面扫描;正则始终看到完整窗口以保留锚点语义。 final 表示不会再有新输入,此时不完整的编码尾部也必须报错,不能永远当作等待分片。



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
# File 'lib/expect/pattern.rb', line 17

def locate(buffer, final: false, offset: 0)
  case value
  when String
    offset = buffer.index(value, offset)
    return [offset, value.bytesize, []] if offset
  when Regexp
    # 正则只读取输入;只有编码标记不同才复制,避免每个模式额外分配缓冲对象。
    text = if value.fixed_encoding? && value.encoding != buffer.encoding
             buffer.dup.force_encoding(value.encoding)
           else
             buffer
           end
    unless text.valid_encoding?
      # 不完整的尾字符可能改变锚点或前瞻结果,必须等字符收齐后再匹配。
      validate_incomplete_suffix!(text, final: final)
      return nil
    end
    found = value.match(text)
    return unless found

    # 直接使用正则的字节范围,避免为转换字符偏移创建前缀切片;捕获组也返回字节串。
    offset, finish = found.byteoffset(0)
    return [offset, finish - offset, found.captures.map { |capture| capture&.b }]
  end
  nil
end