Class: FFI::StructLayout
- Defined in:
- lib/ffi/struct.rb,
ext/ffi_c/StructLayout.c
Defined Under Namespace
Classes: Array, Field, Function, StructByValue
Constant Summary
Constants inherited from Type
Type::Array, Type::Function, Type::Struct
Instance Method Summary collapse
- #[](field) ⇒ Object
- #fields ⇒ Object
- #initialize(field_names, fields, size, align) ⇒ Object constructor
- #members ⇒ Object
- #offset_of(field_name) ⇒ Object
- #offsets ⇒ Object
- #to_a ⇒ Object
Constructor Details
#initialize(field_names, fields, size, align) ⇒ Object
291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 |
# File 'ext/ffi_c/StructLayout.c', line 291
static VALUE
struct_layout_initialize(VALUE self, VALUE field_names, VALUE fields, VALUE size, VALUE align)
{
StructLayout* layout;
ffi_type* ltype;
int i;
Data_Get_Struct(self, StructLayout, layout);
layout->rbFieldMap = rb_hash_new();
layout->rbFieldNames = rb_ary_dup(field_names);
layout->size = NUM2INT(size);
layout->align = NUM2INT(align);
layout->fieldCount = RARRAY_LEN(field_names);
layout->fields = xcalloc(layout->fieldCount, sizeof(StructField *));
layout->ffiTypes = xcalloc(layout->fieldCount + 1, sizeof(ffi_type *));
layout->rbFields = rb_ary_new2(layout->fieldCount);
layout->base.ffiType->elements = layout->ffiTypes;
layout->base.ffiType->size = 0;
layout->base.ffiType->alignment = 1;
ltype = layout->base.ffiType;
for (i = 0; i < layout->fieldCount; ++i) {
VALUE rbName = rb_ary_entry(field_names, i);
VALUE rbField = rb_hash_aref(fields, rbName);
StructField* field;
ffi_type* ftype;
if (!rb_obj_is_kind_of(rbField, rbffi_StructLayoutFieldClass)) {
rb_raise(rb_eTypeError, "wrong type for field %d.", i);
}
Data_Get_Struct(rbField, StructField, field = layout->fields[i]);
if (field->type == NULL || field->type->ffiType == NULL) {
rb_raise(rb_eRuntimeError, "type of field %d not supported", i);
}
ftype = field->type->ffiType;
if (ftype->size == 0) {
rb_raise(rb_eTypeError, "type of field %d has zero size", i);
}
rb_hash_aset(layout->rbFieldMap, rbName, rbField);
layout->ffiTypes[i] = ftype;
rb_ary_push(layout->rbFields, rbField);
ltype->size = MAX(ltype->size, field->offset + ftype->size);
ltype->alignment = MAX(ltype->alignment, ftype->alignment);
}
if (ltype->size == 0) {
rb_raise(rb_eRuntimeError, "Struct size is zero");
}
// Include tail padding
ltype->size = FFI_ALIGN(ltype->size, ltype->alignment);
return self;
}
|
Instance Method Details
#[](field) ⇒ Object
351 352 353 354 355 356 357 358 359 |
# File 'ext/ffi_c/StructLayout.c', line 351
static VALUE
struct_layout_aref(VALUE self, VALUE field)
{
StructLayout* layout;
Data_Get_Struct(self, StructLayout, layout);
return rb_hash_aref(layout->rbFieldMap, field);
}
|
#fields ⇒ Object
361 362 363 364 365 366 367 368 369 |
# File 'ext/ffi_c/StructLayout.c', line 361
static VALUE
struct_layout_fields(VALUE self)
{
StructLayout* layout;
Data_Get_Struct(self, StructLayout, layout);
return rb_ary_dup(layout->rbFields);
}
|
#members ⇒ Object
371 372 373 374 375 376 377 378 379 |
# File 'ext/ffi_c/StructLayout.c', line 371
static VALUE
struct_layout_members(VALUE self)
{
StructLayout* layout;
Data_Get_Struct(self, StructLayout, layout);
return rb_ary_dup(layout->rbFieldNames);
}
|
#offset_of(field_name) ⇒ Object
10 11 12 |
# File 'lib/ffi/struct.rb', line 10 def offset_of(field_name) self[field_name].offset end |
#offsets ⇒ Object
6 7 8 |
# File 'lib/ffi/struct.rb', line 6 def offsets members.map { |m| [ m, self[m].offset ] } end |
#to_a ⇒ Object
381 382 383 384 385 386 387 388 389 |
# File 'ext/ffi_c/StructLayout.c', line 381
static VALUE
struct_layout_to_a(VALUE self)
{
StructLayout* layout;
Data_Get_Struct(self, StructLayout, layout);
return rb_ary_dup(layout->rbFields);
}
|