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.



323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
# File 'lib/blocker.rb', line 323

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



376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
# File 'lib/blocker.rb', line 376

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}"
  super
end

Class Method Details

.attributesObject



229
230
231
# File 'lib/blocker.rb', line 229

def attributes
  @attributes
end

.attributes=(a) ⇒ Object



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

def attributes=(a)
  @attributes=a
end

.clear_registered_klassesObject



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

def clear_registered_klasses
  @klasses = {}
end

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



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

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



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

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



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

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



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

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 :-)



267
268
269
270
271
# File 'lib/blocker.rb', line 267

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



284
285
286
287
288
# File 'lib/blocker.rb', line 284

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



273
274
275
276
277
278
279
280
281
282
# File 'lib/blocker.rb', line 273

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

.inherited(obj) ⇒ Object



257
258
259
260
261
262
263
264
# File 'lib/blocker.rb', line 257

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



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

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

.klassesObject



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

def klasses
  @klasses
end

.klasses=(k) ⇒ Object



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

def klasses=(k)
  @klasses = k
end

.lookupObject



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

def lookup
  @lookup
end

.lookup=(l) ⇒ Object



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

def lookup=(l)
  @lookup=l
end

.register_klass(sym, klass) ⇒ Object



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

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

Instance Method Details

#blockObject



354
355
356
357
358
# File 'lib/blocker.rb', line 354

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

#cloneObject



342
343
344
345
346
347
348
349
350
351
352
# File 'lib/blocker.rb', line 342

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



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

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

#orig_cloneObject



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

alias :orig_clone :clone

#to_hObject



366
367
368
369
370
371
372
373
374
# File 'lib/blocker.rb', line 366

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)


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

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

#valueObject



393
394
395
# File 'lib/blocker.rb', line 393

def value
  self
end

#value=(val) ⇒ Object



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

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