File: trace.rb

package info (click to toggle)
ruby-bindata 2.4.14-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 600 kB
  • sloc: ruby: 8,566; makefile: 4
file content (95 lines) | stat: -rw-r--r-- 2,101 bytes parent folder | download | duplicates (3)
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
module BinData
  # reference to the current tracer
  @tracer ||= nil

  class Tracer #:nodoc:
    def initialize(io)
      @trace_io = io
    end

    def trace(msg)
      @trace_io.puts(msg)
    end

    def trace_obj(obj_name, val)
      if val.length > 30
        val = val.slice(0..30) + "..."
      end

      trace "#{obj_name} => #{val}"
    end
  end

  # Turn on trace information when reading a BinData object.
  # If +block+ is given then the tracing only occurs for that block.
  # This is useful for debugging a BinData declaration.
  def trace_reading(io = STDERR)
    @tracer = Tracer.new(io)
    [BasePrimitive, Choice].each(&:turn_on_tracing)

    if block_given?
      begin
        yield
      ensure
        [BasePrimitive, Choice].each(&:turn_off_tracing)
        @tracer = nil
      end
    end
  end

  def trace_message #:nodoc:
    yield @tracer if @tracer
  end

  module_function :trace_reading, :trace_message

  class BasePrimitive < BinData::Base
    class << self
      def turn_on_tracing
        alias_method :do_read_without_hook, :do_read
        alias_method :do_read, :do_read_with_hook
      end

      def turn_off_tracing
        alias_method :do_read, :do_read_without_hook
      end
    end

    def do_read_with_hook(io)
      do_read_without_hook(io)
      trace_value
    end

    def trace_value
      BinData.trace_message do |tracer|
        value_string = _value.inspect
        tracer.trace_obj(debug_name, value_string)
      end
    end
  end

  class Choice < BinData::Base
    class << self
      def turn_on_tracing
        alias_method :do_read_without_hook, :do_read
        alias_method :do_read, :do_read_with_hook
      end

      def turn_off_tracing
        alias_method :do_read, :do_read_without_hook
      end
    end

    def do_read_with_hook(io)
      trace_selection
      do_read_without_hook(io)
    end

    def trace_selection
      BinData.trace_message do |tracer|
        selection_string = eval_parameter(:selection).inspect
        tracer.trace_obj("#{debug_name}-selection-", selection_string)
      end
    end
  end
end