Class: BinaryBlocker::GroupEncoder

Inherits:
Encoder
  • Object
show all
Defined in:
lib/blocker.rb

Overview

All Encoders that store multiple items subclass from here.

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Encoder

#key_value?, #me

Constructor Details

#initialize(*opts) ⇒ GroupEncoder

Returns a new instance of GroupEncoder.



328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
# File 'lib/blocker.rb', line 328

def initialize(*opts)
  @lookup = self.class.lookup.clone
  @value = self.class.attributes.map { |a| a.call }
  super

  opts.each do |o|
    if o.respond_to? :to_hash
      o.keys.each do |key|
        if pos = @lookup[key.to_sym]
          unless @value[pos].respond_to?(:key_value?) && @value[pos].key_value?
            @value[pos].value = o[key]
          end
        end
      end
    end
  end                
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(sym, *args) ⇒ Object



381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
# File 'lib/blocker.rb', line 381

def method_missing(sym, *args)
  super unless @lookup
  if pos = @lookup[sym]
    return @value[pos].value
  else
    sym = sym.to_s
    if sym[-1] == ?=
      if pos = @lookup[sym[0..-2].to_sym]
        raise NoMethodError.new("undefined method `#{sym}''") if @value[pos].key_value?
        return @value[pos].value = args.first
      end
    end
  end
  puts "method missing #{sym.inspect} #{bt}"
  super
end

Class Method Details

.attributesObject



234
235
236
# File 'lib/blocker.rb', line 234

def attributes
  @attributes
end

.attributes=(a) ⇒ Object



238
239
240
# File 'lib/blocker.rb', line 238

def attributes=(a)
  @attributes=a
end

.clear_registered_klassesObject



323
324
325
# File 'lib/blocker.rb', line 323

def clear_registered_klasses
  @klasses = {}
end

.has_bit_field(sym, type, bit_info, *opts) ⇒ Object



307
308
309
310
# File 'lib/blocker.rb', line 307

def has_bit_field(sym, type, bit_info, *opts)
  self.lookup[sym] = self.attributes.size
  self.attributes << lambda { BitFieldEncoder.new(type, bit_info, *opts) }
end

.has_counted_array(sym, count_type, klasses, *opts) ⇒ Object



295
296
297
298
299
# File 'lib/blocker.rb', line 295

def has_counted_array(sym, count_type, klasses, *opts)
  klasses = include_klasses(klasses, *opts)
  self.lookup[sym] = self.attributes.size 
  self.attributes << lambda { CountedArrayEncoder.new(count_type, klasses, *opts) }
end

.has_fixed_array(sym, count, klasses, *opts) ⇒ Object



301
302
303
304
305
# File 'lib/blocker.rb', line 301

def has_fixed_array(sym, count, klasses, *opts)
  klasses = include_klasses(klasses, *opts)
  self.lookup[sym] = self.attributes.size 
  self.attributes << lambda { FixedArrayEncoder.new(count, klasses, *opts) }
end

.has_list_of(sym, klasses, *opts) ⇒ Object



312
313
314
315
316
# File 'lib/blocker.rb', line 312

def has_list_of(sym, klasses, *opts)
  klasses = include_klasses(klasses, *opts)
  self.lookup[sym] = self.attributes.size 
  self.attributes << lambda { ListOfEncoder.new(klasses, *opts) }
end

.has_one(sym, klass, *opts) ⇒ Object

One and only one (this is the easiest :-)



272
273
274
275
276
# File 'lib/blocker.rb', line 272

def has_one(sym, klass, *opts) 
  klass = self.klasses[klass] if self.klasses[klass]
  self.lookup[sym] = self.attributes.size
  self.attributes << lambda { klass.new(*opts) }
end

.has_one_of(sym, klasses, *opts) ⇒ Object



289
290
291
292
293
# File 'lib/blocker.rb', line 289

def has_one_of(sym, klasses, *opts)
  klasses = include_klasses(klasses, *opts) 
  self.lookup[sym] = self.attributes.size 
  self.attributes << lambda { OneOfEncoder.new(klasses, *opts) }
end

.include_klasses(klasses, *opts) ⇒ Object



278
279
280
281
282
283
284
285
286
287
# File 'lib/blocker.rb', line 278

def include_klasses(klasses, *opts)
  klasses = klasses.map do |k| 
    case
    when @klasses[k]          ; lambda { @klasses[k].new(*opts) }
    when k.respond_to?(:call) ; k
    when k.respond_to?(:new)  ; lambda { k.new(*opts) }
    else raise "Unable to process class: #{k}"
    end
  end
end

.inherited(obj) ⇒ Object



262
263
264
265
266
267
268
269
# File 'lib/blocker.rb', line 262

def inherited(obj)
  obj.instance_eval do
    self.klasses = self.klasses || BinaryBlocker.klasses.clone
    self.attributes = self.attributes || []
    self.lookup = self.lookup || {}
  end
  super
end

.keysObject



246
247
248
# File 'lib/blocker.rb', line 246

def keys
  @lookup.keys.sort_by { |k| @lookup[k] }
end

.klassesObject



254
255
256
# File 'lib/blocker.rb', line 254

def klasses
  @klasses
end

.klasses=(k) ⇒ Object



258
259
260
# File 'lib/blocker.rb', line 258

def klasses=(k)
  @klasses = k
end

.lookupObject



242
243
244
# File 'lib/blocker.rb', line 242

def lookup
  @lookup
end

.lookup=(l) ⇒ Object



250
251
252
# File 'lib/blocker.rb', line 250

def lookup=(l)
  @lookup=l
end

.register_klass(sym, klass) ⇒ Object



318
319
320
321
# File 'lib/blocker.rb', line 318

def register_klass(sym, klass)
  @klasses ||= {}
  @klasses[sym] = klass
end

Instance Method Details

#blockObject



359
360
361
362
363
# File 'lib/blocker.rb', line 359

def block
  @value.inject("") do |a,b|
    a + b.block 
  end
end

#cloneObject



347
348
349
350
351
352
353
354
355
356
357
# File 'lib/blocker.rb', line 347

def clone
  new_me = orig_clone
  new_val = self.class.attributes.map { |a| a.call }
  new_val.each_with_index do |v,i|
    v.value = @value[i].value
  end
  new_me.instance_eval do
    @value = new_val
  end
  new_me
end

#deblock(io) ⇒ Object



365
366
367
368
369
# File 'lib/blocker.rb', line 365

def deblock(io)
  BinaryBlocker.with_guarded_io_pos(io) do
    @value.all? { |o| o.deblock(io) }
  end
end

#orig_cloneObject



346
# File 'lib/blocker.rb', line 346

alias :orig_clone :clone

#to_hObject



371
372
373
374
375
376
377
378
379
# File 'lib/blocker.rb', line 371

def to_h
  result = {}
  @lookup.each_pair do |key, index|
    value = @value[index].value
    value = value.to_h if value.respond_to? :to_h
    result[key] = value
  end    
  result
end

#valid?Boolean

Returns:

  • (Boolean)


408
409
410
# File 'lib/blocker.rb', line 408

def valid?
  @value.all? { |a| a.valid? }
end

#valueObject



398
399
400
# File 'lib/blocker.rb', line 398

def value
  self
end

#value=(val) ⇒ Object



402
403
404
405
406
# File 'lib/blocker.rb', line 402

def value=(val)
  @lookup.keys.each do |key|
    @value[@lookup[key]].value = val.send(key)
  end
end