Skip to content

Commit 6e48998

Browse files
Add C API rb_enc_interned_str_cstr function
Co-authored-by: Thomas Marshall <thomas.marshall@shopify.com>
1 parent 90bfaa0 commit 6e48998

File tree

5 files changed

+38
-1
lines changed

5 files changed

+38
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ Compatibility:
4444
* Do not autosplat a proc that accepts a single positional argument and keywords (#3039, @andrykonchin).
4545
* Support passing anonymous * and ** parameters as method call arguments (#3039, @andrykonchin).
4646
* Handle either positional or keywords arguments by default in `Struct.new` (#3039, @rwstauner).
47+
* Add `rb_enc_interned_str_cstr` function (#3408, @goyox86, @thomasmarshall).
4748

4849
Performance:
4950

lib/cext/ABI_check.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
10
1+
11

spec/ruby/optional/capi/ext/string_spec.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -584,6 +584,11 @@ static VALUE string_spec_rb_str_unlocktmp(VALUE self, VALUE str) {
584584
return rb_str_unlocktmp(str);
585585
}
586586

587+
static VALUE string_spec_rb_enc_interned_str_cstr(VALUE self, VALUE str, VALUE enc) {
588+
rb_encoding *e = rb_to_encoding(enc);
589+
return rb_enc_interned_str_cstr(RSTRING_PTR(str), e);
590+
}
591+
587592
void Init_string_spec(void) {
588593
VALUE cls = rb_define_class("CApiStringSpecs", rb_cObject);
589594
rb_define_method(cls, "rb_cstr2inum", string_spec_rb_cstr2inum, 2);
@@ -685,6 +690,7 @@ void Init_string_spec(void) {
685690
rb_define_method(cls, "rb_str_catf", string_spec_rb_str_catf, 1);
686691
rb_define_method(cls, "rb_str_locktmp", string_spec_rb_str_locktmp, 1);
687692
rb_define_method(cls, "rb_str_unlocktmp", string_spec_rb_str_unlocktmp, 1);
693+
rb_define_method(cls, "rb_enc_interned_str_cstr", string_spec_rb_enc_interned_str_cstr, 2);
688694
}
689695

690696
#ifdef __cplusplus

spec/ruby/optional/capi/string_spec.rb

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1227,4 +1227,29 @@ def inspect
12271227
-> { @s.rb_str_unlocktmp("test") }.should raise_error(RuntimeError, 'temporal unlocking already unlocked string')
12281228
end
12291229
end
1230+
1231+
describe "rb_enc_interned_str_cstr" do
1232+
it "returns a frozen string" do
1233+
str = "hello"
1234+
val = @s.rb_enc_interned_str_cstr(str, Encoding::US_ASCII)
1235+
1236+
val.should.is_a?(String)
1237+
val.encoding.should == Encoding::US_ASCII
1238+
val.should.frozen?
1239+
end
1240+
1241+
it "returns the same frozen string" do
1242+
str = "hello"
1243+
result1 = @s.rb_enc_interned_str_cstr(str, Encoding::US_ASCII)
1244+
result2 = @s.rb_enc_interned_str_cstr(str, Encoding::US_ASCII)
1245+
result1.should.equal?(result2)
1246+
end
1247+
1248+
it "returns different frozen strings for different encodings" do
1249+
str = "hello"
1250+
result1 = @s.rb_enc_interned_str_cstr(str, Encoding::US_ASCII)
1251+
result2 = @s.rb_enc_interned_str_cstr(str, Encoding::UTF_8)
1252+
result1.should_not.equal?(result2)
1253+
end
1254+
end
12301255
end

src/main/c/cext/string.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,3 +437,8 @@ long rb_str_coderange_scan_restartable(const char *s, const char *e, rb_encoding
437437
*cr = ENC_CODERANGE_VALID;
438438
return e - s;
439439
}
440+
441+
VALUE rb_enc_interned_str_cstr(const char *ptr, rb_encoding *enc) {
442+
VALUE str = rb_enc_str_new_cstr(ptr, enc);
443+
return rb_fstring(str);
444+
}

0 commit comments

Comments
 (0)