Class: BitPacker

Inherits:
Object
  • Object
show all
Defined in:
lib/bit-packer.rb

Constant Summary collapse

TYPES =

Holds types index.

Set::new [
    :number,
    :boolean
]
BYTESIZE =

Indicates size of one byte.

8

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(data = nil, &block) ⇒ BitPacker

Constructor.

Parameters:

  • data (Integer) (defaults to: nil)

    raw integer for unpack

  • block (Proc)

    block with declaration

See Also:



67
68
69
70
71
72
73
74
75
# File 'lib/bit-packer.rb', line 67

def initialize(data = nil, &block)
    @stack = [ ]
    @length = 0
    self.declare(&block)
    
    if not data.nil?
        self << data
    end
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args, &block) ⇒ Integer

Handles missing methods as declarations.

Parameters:

  • name (Symbol)

    data type of the entry

  • args (Array)

    first argument is expected to be name

  • block (Proc)

    block which returns length of the entry in bits

Returns:

  • (Integer)

    new length of the packed data

See Also:



107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/bit-packer.rb', line 107

def method_missing(name, *args, &block)
    if not self.class::TYPES.include? name
        raise Exception::new("Invalid type/method specified: '" << name.to_s << "'.")
    end

    if not block.nil?
        length = block.call()
    else
        length = 1
    end
    
    self.add(args.first, name, length)
end

Instance Attribute Details

#lengthInteger (readonly)

Holds total length.

Returns:

  • (Integer)

    total length of the packed data according to declaration



56
57
58
# File 'lib/bit-packer.rb', line 56

def length
  @length
end

#rawInteger (readonly)

Holds raw data.

Returns:

  • (Integer)

    raw (original) integer data



46
47
48
# File 'lib/bit-packer.rb', line 46

def raw
  @raw
end

Instance Method Details

#<<(value) ⇒ Object

Fills by input data.

Parameters:

  • value (Integer)

    raw integer data for unpack



141
142
143
144
145
146
147
148
# File 'lib/bit-packer.rb', line 141

def <<(value)
    if not value.kind_of? Integer
        raise Exception::new("Integer is expected for BitPacker.")
    end
    
    @raw = value
    @data = nil
end

#add(name, type, length = 1) ⇒ Integer

Adds declaration.

Parameters:

  • name (Symbol)

    name of the entry

  • type (Symbol)

    type of the entry

  • length (Integer) (defaults to: 1)

    length of the entry in bits

Returns:

  • (Integer)

    new length of the packed data



130
131
132
133
134
# File 'lib/bit-packer.rb', line 130

def add(name, type, length = 1)
    @stack << [name, type, @length, length]
    @struct = nil
    @length += length
end

#bitsizeInteger

Returns size in bits.

Returns:

  • (Integer)

    size in bits

Since:

  • 0.1.1



215
216
217
# File 'lib/bit-packer.rb', line 215

def bitsize
    @length
end

#bytesizeInteger

Returns size in bytes. It means number of bits rounded to number of bytes according to BYTESIZE.

Returns:

  • (Integer)

    size in bytes

Since:

  • 0.1.1



227
228
229
# File 'lib/bit-packer.rb', line 227

def bytesize
    (@length.to_f / 8).ceil
end

#dataClass

Returns structure analyze.

Returns:

  • (Class)

    struct with the packed data



155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
# File 'lib/bit-packer.rb', line 155

def data
    if @data.nil?
        values = [ ]
        
        @stack.each do |name, type, position, length|
            rel_pos = @length - position - length
            value = @raw & __mask(rel_pos, length)
            
            case type
                when :boolean
                    values << (value > 0)
                when :number
                    values << (value >> rel_pos)
            end
        end
        
        @data = __struct::new(*values)
    end
    
    return @data
end

#declare(&block) ⇒ Object

Receives declaration.

Adds declaration of bit array items. Can be call multiple times. New delcarations are joind to end of the array.

Examples:

packer.declare do
    number (:number) {2}
    boolean :boolean
end

Parameters:

  • block (Proc)

    block with declaration

See Also:



93
94
95
# File 'lib/bit-packer.rb', line 93

def declare(&block)
    self.instance_eval(&block)
end

#to_iInteger Also known as: to_int

Converts to integer.

Returns:

  • (Integer)

    resultant integer according to current data state



182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
# File 'lib/bit-packer.rb', line 182

def to_i
    result = 0
    @stack.each do |name, type, position, length|
        rel_pos = @length - position - length
        value = self.data[name]
        
        case type
            when :boolean
                mask = __mask(rel_pos, length)
                if value === true
                    result |= mask
                else
                    result &= ~mask
                end
            when :number
                value &= __mask(0, length)
                value = value << rel_pos
                result |= value
        end
    end
    
    return result
end