Skip to content

Commit

Permalink
Convert Range instances to NS/CFRange structures when passed as argum…
Browse files Browse the repository at this point in the history
…ent.

Closes #35.
  • Loading branch information
alloy committed Aug 20, 2011
1 parent f0633b3 commit 7b1f361
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 2 deletions.
21 changes: 21 additions & 0 deletions bridgesupport.cpp
Expand Up @@ -797,6 +797,27 @@ rb_vm_get_struct_fields(VALUE rval, VALUE *buf, rb_vm_bs_boxed_t *bs_boxed)
buf[i] = RARRAY_AT(rval, i); buf[i] = RARRAY_AT(rval, i);
} }
} }
else if (CLASS_OF(rval) == rb_cRange &&
(strcmp(bs_boxed->as.s->name, "NSRange") == 0 ||
strcmp(bs_boxed->as.s->name, "CFRange") == 0)) {
VALUE b, e;
int exclusive;
rb_range_values(rval, &b, &e, &exclusive);
int begin = NUM2INT(b);
int end = NUM2INT(e);
if (begin < 0 || end < 0) {
// We don't know what the max length of the range will be, so we
// can't count backwards.
rb_raise(rb_eArgError,
"negative values are not allowed in ranges " \
"that are converted to %s structures `%s'",
bs_boxed->as.s->name,
RSTRING_PTR(rb_inspect(rval)));
}
int length = exclusive ? end-1-begin : end-begin;
buf[0] = INT2NUM(begin);
buf[1] = INT2NUM(length);
}
else { else {
if (!rb_obj_is_kind_of(rval, bs_boxed->klass)) { if (!rb_obj_is_kind_of(rval, bs_boxed->klass)) {
rb_raise(rb_eTypeError, rb_raise(rb_eTypeError,
Expand Down
4 changes: 2 additions & 2 deletions range.c
Expand Up @@ -691,10 +691,10 @@ rb_range_values(VALUE range, VALUE *begp, VALUE *endp, int *exclp)
} }
else { else {
if (!rb_vm_respond_to(range, selBeg, false)) { if (!rb_vm_respond_to(range, selBeg, false)) {
return Qfalse; return 0;
} }
if (!rb_vm_respond_to(range, selEnd, false)) { if (!rb_vm_respond_to(range, selEnd, false)) {
return Qfalse; return 0;
} }
b = rb_vm_call(range, selBeg, 0, NULL); b = rb_vm_call(range, selBeg, 0, NULL);
e = rb_vm_call(range, selEnd, 0, NULL); e = rb_vm_call(range, selEnd, 0, NULL);
Expand Down
16 changes: 16 additions & 0 deletions spec/macruby/language/objc_method_spec.rb
Expand Up @@ -367,6 +367,22 @@ def o2.to_str; 'foo' end
lambda { @o.methodAcceptingNSRect([[1, 2], [3, 4, 5]]) }.should raise_error(ArgumentError) lambda { @o.methodAcceptingNSRect([[1, 2], [3, 4, 5]]) }.should raise_error(ArgumentError)
end end


it "accepting a Range as a structure type should receive a NSRange C structure" do
@o.methodAcceptingNSRange(0..41).should == 0
@o.methodAcceptingNSRange(1..42).should == 0
@o.methodAcceptingNSRange(0..42).should == 1
@o.methodAcceptingNSRange(0...42).should == 0
@o.methodAcceptingNSRange(1...42).should == 0
@o.methodAcceptingNSRange(0...43).should == 1

lambda { @o.methodAcceptingNSRange(-1..1) }.should raise_error(ArgumentError)
lambda { @o.methodAcceptingNSRange(1..-1) }.should raise_error(ArgumentError)
lambda { @o.methodAcceptingNSRange(-1..-1) }.should raise_error(ArgumentError)
lambda { @o.methodAcceptingNSRange(-1...1) }.should raise_error(ArgumentError)
lambda { @o.methodAcceptingNSRange(1...-1) }.should raise_error(ArgumentError)
lambda { @o.methodAcceptingNSRange(-1...-1) }.should raise_error(ArgumentError)
end

it "accepting various C types should receive these types as expected" do it "accepting various C types should receive these types as expected" do
@o.methodAcceptingInt(42, float:42, double:42, short:42, NSPoint:[42, 42], @o.methodAcceptingInt(42, float:42, double:42, short:42, NSPoint:[42, 42],
NSRect:[42, 42, 42, 42], char:42).should == 1 NSRect:[42, 42, 42, 42], char:42).should == 1
Expand Down

0 comments on commit 7b1f361

Please sign in to comment.