Class: CStruct

Inherits:
Object
  • Object
show all
Defined in:
lib/cstruct/cstruct.rb,
lib/cstruct/field.rb,
lib/cstruct/utils.rb

Overview

Direct Known Subclasses

Win32Struct, Win64Struct

Defined Under Namespace

Modules: Utils Classes: Field

Constant Summary collapse

VERSION =

version

"1.0.1"

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize {|_self| ... } ⇒ CStruct

:nodoc:

Yields:

  • (_self)

Yield Parameters:

  • _self (CStruct)

    the object that the method was called on



204
205
206
207
208
209
# File 'lib/cstruct/cstruct.rb', line 204

def initialize  #:nodoc:
  @data  = "\0"*self.class.size
  @data.encode!("BINARY") if RUBY_VERSION >= '1.9'
  @owner = []
  yield self if block_given?
end

Instance Attribute Details

#ownerObject

Returns the value of attribute owner.



202
203
204
# File 'lib/cstruct/cstruct.rb', line 202

def owner
  @owner
end

Class Method Details

.alignObject

Return the align of a struct;the default is 1.



31
32
33
# File 'lib/cstruct/cstruct.rb', line 31

def align
  @options[:align]
end

.double(*args) ⇒ Object

:nodoc:



181
182
183
# File 'lib/cstruct/cstruct.rb', line 181

def double(*args) #:nodoc:
  field args[0],8,:double,args[1]
end

.endianObject

Return the endian of a struct;the default is :little.



26
27
28
# File 'lib/cstruct/cstruct.rb', line 26

def endian
  @options[:endian] 
end

.fieldsObject

Return the fields of a struct.



36
37
38
# File 'lib/cstruct/cstruct.rb', line 36

def fields
  @fields
end

.float(*args) ⇒ Object

:nodoc:



177
178
179
# File 'lib/cstruct/cstruct.rb', line 177

def float(*args) #:nodoc: 
  field args[0],4,:float,args[1]  
end

.options(opts) ⇒ Object

set the options of a struct.



21
22
23
# File 'lib/cstruct/cstruct.rb', line 21

def options opts
   @options.merge! opts
end

.sizeObject Also known as: __size__

Return the size of a struct;size similar to sizeof in C language.

Example:

class Point < CStruct
  int32:x
  int32:y
end

puts Point.size # or Point.__size__


50
51
52
# File 'lib/cstruct/cstruct.rb', line 50

def size
  @options[:layout_size]
end

.struct(symbol, &block) ⇒ Object

Define a anonymous struct field.

Example:

in C:

struct Window
{
   int style;
   struct{
     int x;
     int y;
   }position;
};

use CStruct in Ruby:

class Window < CStruct
  int32:style
  struct :position do
    int32:x
    int32:y 
  end
end


451
452
453
454
455
456
# File 'lib/cstruct/cstruct.rb', line 451

def CStruct.struct symbol,&block
  struct_super  = self.ancestors[1]
  struct_class = Class.new(struct_super) 
  struct_class.instance_eval(&block)
  structfield symbol,struct_class,struct_class.__size__
end

.union(symbol, &block) ⇒ Object

Define a anonymous union field.

Example: in C:

struct U
{
   union{
     int x;
     int y;
   }value; /* values is anonymous union's instance */

};

use CStruct in Ruby:

class U < CStruct
  union:value do
    int32:x
    int32:y
  end
end


405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
# File 'lib/cstruct/cstruct.rb', line 405

def CStruct.union symbol,&block
	union_super  = self.ancestors[1]
	union_class = Class.new(union_super) do
	def self.change_to_union #:nodoc:
	    @fields.each_key  { |symbol| @fields[symbol].offset = 0 }

	    max_field_size = @fields.values.inject(0)do |max,field| 
	      dimension = field.dimension
	      dimension_product = 1
        if dimension.is_a? Array
	        dimension_product = dimension.inject(1){|m,d| m *= d }
        end       
	      field_size = field.size* dimension_product
	      max = (field_size> max ? field_size : max)
	    end
	    @options[:layout_size] = max_field_size
	  end
	end	
    union_class.instance_eval(&block) 
    union_class.instance_eval{change_to_union}
    structfield symbol,union_class,union_class.size
end

Instance Method Details

#<<(bindata) ⇒ Object

Assign to CStruct’s instance.



229
230
231
232
233
234
# File 'lib/cstruct/cstruct.rb', line 229

def << bindata
  count = @data.size < bindata.size ? @data.size : bindata.size
  (0...count).each do |i|
    Utils.string_setbyte @data,i,Utils.string_getbyte(bindata,i)
  end
end

#dataObject Also known as: __data__

Return the data buffer of a CStruct’s instance.



212
213
214
# File 'lib/cstruct/cstruct.rb', line 212

def data
  @data
end

#data=(bindata) ⇒ Object Also known as: __data__=

Assign to CStruct’s instance.



223
224
225
226
# File 'lib/cstruct/cstruct.rb', line 223

def data= bindata
  raise 'Data Type Error!' unless bindata.is_a? String
  self << bindata
end

#resetObject Also known as: __reset__

Fill the date buffer of a CStruct’s instance with zero.



217
218
219
220
# File 'lib/cstruct/cstruct.rb', line 217

def reset
  (0...self.class.size).each { |i| Utils.string_setbyte @data,i, 0 }
  sync_to_owner
end

#sync_to_ownerObject

:nodoc:



236
237
238
239
240
241
242
243
244
# File 'lib/cstruct/cstruct.rb', line 236

def sync_to_owner #:nodoc:
  return if @owner.empty?
  final_offset = @owner.inject(0) do |sum,owner_value| 
    _,foffset,_ = owner_value
    sum+= foffset
  end
  onwerdata,_,_ = @owner.last
  Utils.buffer_setbytes onwerdata,@data,final_offset
end