File: trace.rb

package info (click to toggle)
ruby-bindata 2.5.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 652 kB
  • sloc: ruby: 8,896; makefile: 4
file content (88 lines) | stat: -rw-r--r-- 1,930 bytes parent folder | download
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
module BinData

  # 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

  # 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

  def trace_message # :nodoc:
    yield @tracer
  end

  module_function :trace_reading, :trace_message

  module TraceHook
    def turn_on_tracing
      if !method_defined? :do_read_without_hook
        alias_method :do_read_without_hook, :do_read
        alias_method :do_read, :do_read_with_hook
      end
    end

    def turn_off_tracing
      if method_defined? :do_read_without_hook
        alias_method :do_read, :do_read_without_hook
        remove_method :do_read_without_hook
      end
    end
  end

  class BasePrimitive < BinData::Base
    extend TraceHook

    def do_read_with_hook(io)
      do_read_without_hook(io)

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

  class Choice < BinData::Base
    extend TraceHook

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

      do_read_without_hook(io)
    end
  end
end