Skip to content

Commit 9607b17

Browse files
committed
Implement rb_enc_mbcput
1 parent cb774a0 commit 9607b17

File tree

5 files changed

+52
-1
lines changed

5 files changed

+52
-1
lines changed

lib/cext/include/ruby/onigmo.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -373,10 +373,12 @@ int onigenc_mbclen_approximate(const OnigUChar* p,const OnigUChar* e, const stru
373373
#ifdef TRUFFLERUBY
374374
int rb_tr_code_to_mbclen(OnigCodePoint code, OnigEncodingType *encoding);
375375
#define ONIGENC_CODE_TO_MBCLEN(enc,code) rb_tr_code_to_mbclen(code,enc)
376+
int rb_tr_code_to_mbc(OnigCodePoint code, UChar *buf, OnigEncoding enc);
377+
#define ONIGENC_CODE_TO_MBC(enc,code,buf) rb_tr_code_to_mbc(code,buf,enc)
376378
#else
377379
#define ONIGENC_CODE_TO_MBCLEN(enc,code) (enc)->code_to_mbclen(code,enc)
378-
#endif
379380
#define ONIGENC_CODE_TO_MBC(enc,code,buf) (enc)->code_to_mbc(code,buf,enc)
381+
#endif
380382
#define ONIGENC_PROPERTY_NAME_TO_CTYPE(enc,p,end) \
381383
(enc)->property_name_to_ctype(enc,p,end)
382384

spec/ruby/optional/capi/encoding_spec.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,15 @@
139139
end
140140
end
141141

142+
describe "rb_enc_mbcput" do
143+
it "writes the correct bytes to the buffer" do
144+
@s.rb_enc_mbcput(0x24, Encoding::UTF_8).should == "$"
145+
@s.rb_enc_mbcput(0xA2, Encoding::UTF_8).should == "¢"
146+
@s.rb_enc_mbcput(0x20AC, Encoding::UTF_8).should == "€"
147+
@s.rb_enc_mbcput(0x24B62, Encoding::UTF_8).should == "𤭢"
148+
end
149+
end
150+
142151
describe "rb_usascii_encoding" do
143152
it "returns the encoding for Encoding::US_ASCII" do
144153
@s.rb_usascii_encoding.should == "US-ASCII"

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,16 @@ static VALUE encoding_spec_rb_enc_mbc_to_codepoint(VALUE self, VALUE str, VALUE
127127
return INT2FIX(rb_enc_mbc_to_codepoint(p, e, rb_enc_get(str)));
128128
}
129129

130+
static VALUE encoding_spec_rb_enc_mbcput(VALUE self, VALUE code, VALUE encoding) {
131+
unsigned int c = FIX2UINT(code);
132+
rb_encoding *enc = rb_to_encoding(encoding);
133+
char *buf = (char*) malloc(10);
134+
int len = rb_enc_mbcput(c, buf, enc);
135+
VALUE str = rb_enc_str_new(buf, len, enc);
136+
free(buf);
137+
return str;
138+
}
139+
130140
static VALUE encoding_spec_rb_enc_from_encoding(VALUE self, VALUE name) {
131141
return rb_enc_from_encoding(rb_enc_find(RSTRING_PTR(name)));
132142
}
@@ -324,6 +334,7 @@ void Init_encoding_spec(void) {
324334
rb_define_method(cls, "rb_enc_isspace", encoding_spec_rb_enc_isspace, 2);
325335
rb_define_method(cls, "rb_enc_from_index", encoding_spec_rb_enc_from_index, 1);
326336
rb_define_method(cls, "rb_enc_mbc_to_codepoint", encoding_spec_rb_enc_mbc_to_codepoint, 2);
337+
rb_define_method(cls, "rb_enc_mbcput", encoding_spec_rb_enc_mbcput, 2);
327338
rb_define_method(cls, "rb_enc_from_encoding", encoding_spec_rb_enc_from_encoding, 1);
328339
rb_define_method(cls, "rb_enc_get", encoding_spec_rb_enc_get, 1);
329340
rb_define_method(cls, "rb_enc_precise_mbclen", encoding_spec_rb_enc_precise_mbclen, 2);

src/main/c/cext/encoding.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,3 +366,13 @@ int rb_tr_enc_mbc_case_fold(rb_encoding *enc, int flag, const UChar** p, const U
366366
}
367367
return result_len;
368368
}
369+
370+
int rb_tr_code_to_mbc(OnigCodePoint code, UChar *buf, OnigEncoding enc) {
371+
VALUE result_str = rb_tr_wrap(polyglot_invoke(RUBY_CEXT, "rb_tr_code_to_mbc",
372+
rb_tr_unwrap(rb_enc_from_encoding(enc)), code));
373+
int result_len = RSTRING_LEN(result_str);
374+
if (result_len > 0) {
375+
strncpy((char *)buf, RSTRING_PTR(result_str), result_len);
376+
}
377+
return result_len;
378+
}

src/main/java/org/truffleruby/cext/CExtNodes.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1310,6 +1310,25 @@ protected int getCacheLimit() {
13101310

13111311
}
13121312

1313+
@CoreMethod(names = "rb_tr_code_to_mbc", onSingleton = true, required = 2, lowerFixnum = 2)
1314+
public abstract static class RbTrMbcPutNode extends CoreMethodArrayArgumentsNode {
1315+
1316+
@Specialization(guards = "isRubyEncoding(enc)")
1317+
protected Object rbTrEncMbcPut(DynamicObject enc, int code) {
1318+
final Encoding encoding = EncodingOperations.getEncoding(enc);
1319+
final byte buf[] = new byte[org.jcodings.Config.ENC_CODE_TO_MBC_MAXLEN];
1320+
final int resultLength = encoding.codeToMbc(code, buf, 0);
1321+
final byte result[] = new byte[resultLength];
1322+
if (resultLength > 0) {
1323+
System.arraycopy(buf, 0, result, 0, resultLength);
1324+
}
1325+
return StringOperations.createString(
1326+
getContext(),
1327+
RopeOperations.create(result, USASCIIEncoding.INSTANCE, CodeRange.CR_UNKNOWN));
1328+
}
1329+
1330+
}
1331+
13131332
@CoreMethod(names = "rb_enc_mbmaxlen", onSingleton = true, required = 1)
13141333
public abstract static class RbEncMaxLenNode extends CoreMethodArrayArgumentsNode {
13151334

0 commit comments

Comments
 (0)