1
0
mirror of https://github.com/e621ng/dtext_rb.git synced 2025-03-04 03:03:03 -05:00
dtext_rb/ext/dtext/rb_dtext.cpp
2023-04-03 12:51:59 +02:00

55 lines
1.5 KiB
C++

#include "dtext.h"
#include <ruby.h>
#include <ruby/encoding.h>
static VALUE cDText = Qnil;
static VALUE cDTextError = Qnil;
static VALUE c_parse(VALUE self, VALUE input, VALUE f_inline, VALUE f_allow_color, VALUE f_max_thumbs, VALUE base_url) {
if (NIL_P(input)) {
return Qnil;
}
StringValue(input);
DTextOptions options = {};
options.f_inline = RTEST(f_inline);
options.allow_color = RTEST(f_allow_color);
options.max_thumbs = FIX2LONG(f_max_thumbs);
if (!NIL_P(base_url)) {
options.base_url = StringValueCStr(base_url); // base_url.to_str # raises ArgumentError if base_url contains null bytes.
}
if (memchr(RSTRING_PTR(input), 0, RSTRING_LEN(input))) {
rb_raise(cDTextError, "invalid byte sequence in UTF-8");
}
try {
std::string_view dtext(RSTRING_PTR(input), RSTRING_LEN(input));
auto result = StateMachine::parse_dtext(dtext, options);
VALUE retStr = rb_utf8_str_new(result.dtext.c_str(), result.dtext.size());
VALUE retPostIds = rb_ary_new_capa(result.posts.size());
for (long post_id : result.posts) {
rb_ary_push(retPostIds, LONG2FIX(post_id));
}
VALUE ret = rb_ary_new_capa(2);
rb_ary_push(ret, retStr);
rb_ary_push(ret, retPostIds);
return ret;
} catch (std::exception& e) {
rb_raise(cDTextError, "%s", e.what());
}
}
extern "C" void Init_dtext() {
cDText = rb_define_class("DText", rb_cObject);
cDTextError = rb_define_class_under(cDText, "Error", rb_eStandardError);
rb_define_singleton_method(cDText, "c_parse", c_parse, 5);
}