GitHub

@@ -1278,6 +1278,86 @@ mrb_str_uminus(mrb_state *mrb, mrb_value str)

12781278

return mrb_obj_freeze(mrb, mrb_str_dup(mrb, str));

12791279

}

128012801281+

static mrb_value

1282+

str_bytesplice(mrb_state *mrb, mrb_value str, mrb_int idx1, mrb_int len1, mrb_value replace, mrb_int idx2, mrb_int len2)

1283+

{

1284+

struct RString *s = RSTRING(str);

1285+

if (RSTR_LEN(s) <= idx1 || RSTRING_LEN(replace) <= idx2) {

1286+

mrb_raise(mrb, E_INDEX_ERROR, "index out of string");

1287+

}

1288+

if (RSTR_LEN(s) <= idx1+len1) {

1289+

len1 = RSTR_LEN(s) - idx1;

1290+

}

1291+

if (RSTRING_LEN(replace) <= idx2+len2) {

1292+

len2 = RSTRING_LEN(replace) - idx2;

1293+

}

1294+

if (len2 == 0) return replace;

1295+

mrb_str_modify(mrb, s);

1296+

if (len1 >= len2) {

1297+

memmove(RSTR_PTR(s)+idx1, RSTRING_PTR(replace)+idx2, len2);

1298+

if (len1 > len2) {

1299+

memmove(RSTR_PTR(s)+idx1+len2, RSTR_PTR(s)+idx1+len1, RSTR_LEN(s)-(idx1+len1));

1300+

RSTR_SET_LEN(s, RSTR_LEN(s)-(len1-len2));

1301+

}

1302+

}

1303+

else { /* len1 < len2 */

1304+

mrb_int slen = RSTR_LEN(s);

1305+

mrb_str_resize(mrb, str, slen+len2-len1);

1306+

memmove(RSTR_PTR(s)+idx1+len2, RSTR_PTR(s)+idx1+len1, slen-(idx1+len1));

1307+

memmove(RSTR_PTR(s)+idx1, RSTRING_PTR(replace)+idx2, len2);

1308+

}

1309+

return replace;

1310+

}

1311+1312+

/*

1313+

* call-seq:

1314+

* bytesplice(index, length, str) -> string

1315+

* bytesplice(index, length, str, str_index, str_length) -> string

1316+

* bytesplice(range, str) -> string

1317+

* bytesplice(range, str, str_range) -> string

1318+

*

1319+

* Replaces some or all of the content of +self+ with +str+, and returns +self+.

1320+

* The portion of the string affected is determined using

1321+

* the same criteria as String#byteslice, except that +length+ cannot be omitted.

1322+

* If the replacement string is not the same length as the text it is replacing,

1323+

* the string will be adjusted accordingly.

1324+

*

1325+

* If +str_index+ and +str_length+, or +str_range+ are given, the content of +self+ is replaced by str.byteslice(str_index, str_length) or str.byteslice(str_range); however the substring of +str+ is not allocated as a new string.

1326+

*

1327+

* The form that take an Integer will raise an IndexError if the value is out

1328+

* of range; the Range form will raise a RangeError.

1329+

* If the beginning or ending offset does not land on character (codepoint)

1330+

* boundary, an IndexError will be raised.

1331+

*/

1332+

static mrb_value

1333+

mrb_str_bytesplice(mrb_state *mrb, mrb_value str)

1334+

{

1335+

mrb_int idx1, len1, idx2, len2;

1336+

mrb_value range1, range2, replace;

1337+

switch (mrb_get_argc(mrb)) {

1338+

case 3:

1339+

mrb_get_args(mrb, "ooo", &range1, &replace, &range2);

1340+

if (mrb_integer_p(range1)) {

1341+

mrb_get_args(mrb, "iiS", &idx1, &len1, &replace);

1342+

return str_bytesplice(mrb, str, idx1, len1, replace, 0, RSTRING_LEN(replace));

1343+

}

1344+

if (mrb_range_beg_len(mrb, range1, &idx1, &len1, RSTRING_LEN(str), FALSE) != MRB_RANGE_OK) break;

1345+

if (mrb_range_beg_len(mrb, range2, &idx2, &len2, RSTRING_LEN(replace), FALSE) != MRB_RANGE_OK) break;

1346+

return str_bytesplice(mrb, str, idx1, len1, replace, idx2, len2);

1347+

case 5:

1348+

mrb_get_args(mrb, "iiSii", &idx1, &len1, &replace, &idx2, &len2);

1349+

return str_bytesplice(mrb, str, idx1, len1, replace, idx2, len2);

1350+

case 2:

1351+

mrb_get_args(mrb, "oS", &range1, &replace);

1352+

if (mrb_range_beg_len(mrb, range1, &idx1, &len1, RSTRING_LEN(str), FALSE) == MRB_RANGE_OK) {

1353+

return str_bytesplice(mrb, str, idx1, len1, replace, 0, RSTRING_LEN(replace));

1354+

}

1355+

default:

1356+

break;

1357+

}

1358+

mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong number of arumgnts");

1359+

}

1360+12811361

void

12821362

mrb_mruby_string_ext_gem_init(mrb_state* mrb)

12831363

{

@@ -1315,6 +1395,7 @@ mrb_mruby_string_ext_gem_init(mrb_state* mrb)

13151395

mrb_define_method(mrb, s, "casecmp?", mrb_str_casecmp_p, MRB_ARGS_REQ(1));

13161396

mrb_define_method(mrb, s, "+@", mrb_str_uplus, MRB_ARGS_REQ(1));

13171397

mrb_define_method(mrb, s, "-@", mrb_str_uminus, MRB_ARGS_REQ(1));

1398+

mrb_define_method(mrb, s, "bytesplice", mrb_str_bytesplice, MRB_ARGS_ANY());

1318139913191400

mrb_define_method(mrb, s, "__lines", mrb_str_lines, MRB_ARGS_NONE());

13201401

Read the original on github.com ↗