Module: Bytemapper

Defined in:
lib/bytemapper.rb,
lib/bytemapper/type.rb,
lib/bytemapper/chunk.rb,
lib/bytemapper/shape.rb,
lib/bytemapper/table.rb,
lib/bytemapper/nameable.rb,
lib/bytemapper/registry.rb,
lib/bytemapper/typeable.rb,
lib/bytemapper/flattenable.rb

Overview

Bytemapper - Model arbitrary bytestrings as Ruby objects.

Copyright © 2020 Jefferson Hudson

This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License along with this program. If not, see <www.gnu.org/licenses/>.

Defined Under Namespace

Modules: Flattenable, Nameable, NilTimes, Typeable Classes: Chunk, Registry, Shape, Table, Type

Constant Summary collapse

@@registry =
Registry.new

Class Method Summary collapse

Class Method Details

.get(obj) ⇒ Object



98
99
100
# File 'lib/bytemapper.rb', line 98

def get(obj)
  registry.get(obj)
end

.get2(obj) ⇒ Object



102
103
104
105
# File 'lib/bytemapper.rb', line 102

def get2(obj)
  obj.each_pair { |k,v| obj[k] = get(v) if registry.registered_name?(v) }
  registry.get(obj)
end

.is_a_name?(obj) ⇒ Boolean

Returns:

  • (Boolean)


71
72
73
# File 'lib/bytemapper.rb', line 71

def is_a_name?(obj)
  obj.is_a?(String) || obj.is_a?(Symbol)
end

.is_a_shape?(obj) ⇒ Boolean

Returns:

  • (Boolean)


67
68
69
# File 'lib/bytemapper.rb', line 67

def is_a_shape?(obj)
  obj.is_a?(Hash)
end

.is_a_type?(obj) ⇒ Boolean

Returns:

  • (Boolean)


59
60
61
62
63
64
65
# File 'lib/bytemapper.rb', line 59

def is_a_type?(obj)
  obj.is_a?(Type) ||
  obj.is_a?(Array) &&
  obj.size == 2 &&
  obj.first.is_a?(Integer) &&
  obj.last.is_a?(String)
end

.map(bytes, shape, name = nil) ⇒ Object



75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/bytemapper.rb', line 75

def map(bytes, shape, name = nil)
  bytes = StringIO.from(bytes)

  if shape.is_a?(Bytemapper::Table)
    shape.populate(bytes)
  elsif shape.is_a?(Array)
    chunks = []
    shape.each { |s| chunks << Chunk.new(bytes.read(s.size), s, name) }
    chunks
  else
    shape = wrap(shape, name)
    Chunk.new(bytes, shape, name)
  end
end

.names(filter_key = nil) ⇒ Object



111
112
113
# File 'lib/bytemapper.rb', line 111

def names(filter_key = nil)
  registry.names.keys
end


115
116
117
# File 'lib/bytemapper.rb', line 115

def print
  registry.print
end

.put(obj, name) ⇒ Object



107
108
109
# File 'lib/bytemapper.rb', line 107

def put(obj, name)
  registry.put(obj, name)
end

.register(obj, name, fqname = []) ⇒ Object Also known as: wrap



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
# File 'lib/bytemapper.rb', line 32

def register(obj, name, fqname = [])
  return if obj.nil?
  name = name.downcase.to_sym unless name.nil?
  fqname << name unless name.nil?
  if is_a_type?(obj)
    name = fqname.size > 1 ? fqname.join('.') : fqname.first
    obj = Type.new(obj)
    put(obj, name)
  elsif is_a_name?(obj)
    register(get(obj), nil, fqname)
  elsif is_a_shape?(obj)
    if registered?(obj)
      obj = get(obj)
      put(obj, name)
    else
      shape = Shape.new
      obj.each do |k,v|
        shape[k] = register(v, k, [].concat(fqname))
      end
      put(shape, name)
    end
  else
    put(obj, name)
  end
end

.registered?(obj) ⇒ Boolean

Returns:

  • (Boolean)


94
95
96
# File 'lib/bytemapper.rb', line 94

def registered?(obj)
  registry.registered?(obj)
end

.registryObject



119
120
121
# File 'lib/bytemapper.rb', line 119

def registry
  @@registry
end

.repeat(obj, times = nil) ⇒ Object



90
91
92
# File 'lib/bytemapper.rb', line 90

def repeat(obj, times = nil)
  Table.new(obj, times)
end

.reset(with_basic_types = true) ⇒ Object



123
124
125
# File 'lib/bytemapper.rb', line 123

def reset(with_basic_types = true)
  @@registry = Registry.new(with_basic_types)
end

.reverse_lookup(prefix, value = nil) ⇒ Object



127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/bytemapper.rb', line 127

def reverse_lookup(prefix, value = nil)
  @@rl_cache ||= {}
  prefix = "#{prefix.to_s}_"
  lookup = @@rl_cache[prefix]

  if lookup.nil?
    labels = names.filter { |n| n.start_with?(prefix) } 
    values = labels.map { |l| get(l) }
    lookup = Hash[values.zip(labels)]
    @@rl_cache[prefix] = lookup
  end

  value.nil? ? lookup : lookup[value]
end