diff src/if_ruby.c @ 15454:1d2b5c016f17 v8.1.0735

patch 8.1.0735: cannot handle binary data commit https://github.com/vim/vim/commit/6e5ea8d2a995b32bbc5972edc4f827b959f2702f Author: Bram Moolenaar <Bram@vim.org> Date: Sat Jan 12 22:47:31 2019 +0100 patch 8.1.0735: cannot handle binary data Problem: Cannot handle binary data. Solution: Add the Blob type. (Yasuhiro Matsumoto, closes https://github.com/vim/vim/issues/3638)
author Bram Moolenaar <Bram@vim.org>
date Sat, 12 Jan 2019 23:00:06 +0100
parents 0807e2dbbab6
children 55ccc2d353bd
line wrap: on
line diff
--- a/src/if_ruby.c
+++ b/src/if_ruby.c
@@ -51,6 +51,7 @@
 #  define rb_cFloat		(*dll_rb_cFloat)
 # endif
 # define rb_cNilClass		(*dll_rb_cNilClass)
+# define rb_cString		(*dll_rb_cString)
 # define rb_cSymbol		(*dll_rb_cSymbol)
 # define rb_cTrueClass		(*dll_rb_cTrueClass)
 # if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 18
@@ -219,6 +220,7 @@ static void ruby_vim_init(void);
  */
 # define rb_assoc_new			dll_rb_assoc_new
 # define rb_cObject			(*dll_rb_cObject)
+# define rb_class_new_instance		dll_rb_class_new_instance
 # define rb_check_type			dll_rb_check_type
 # ifdef USE_TYPEDDATA
 #  define rb_check_typeddata		dll_rb_check_typeddata
@@ -365,8 +367,10 @@ VALUE *dll_rb_cFloat;
 # endif
 VALUE *dll_rb_cNilClass;
 static VALUE *dll_rb_cObject;
+VALUE *dll_rb_cString;
 VALUE *dll_rb_cSymbol;
 VALUE *dll_rb_cTrueClass;
+static VALUE (*dll_rb_class_new_instance) (int,VALUE*,VALUE);
 static void (*dll_rb_check_type) (VALUE,int);
 # ifdef USE_TYPEDDATA
 static void *(*dll_rb_check_typeddata) (VALUE,const rb_data_type_t *);
@@ -579,8 +583,10 @@ static struct
 # endif
     {"rb_cNilClass", (RUBY_PROC*)&dll_rb_cNilClass},
     {"rb_cObject", (RUBY_PROC*)&dll_rb_cObject},
+    {"rb_cString", (RUBY_PROC*)&dll_rb_cString},
     {"rb_cSymbol", (RUBY_PROC*)&dll_rb_cSymbol},
     {"rb_cTrueClass", (RUBY_PROC*)&dll_rb_cTrueClass},
+    {"rb_class_new_instance", (RUBY_PROC*)&dll_rb_class_new_instance},
     {"rb_check_type", (RUBY_PROC*)&dll_rb_check_type},
 # ifdef USE_TYPEDDATA
     {"rb_check_typeddata", (RUBY_PROC*)&dll_rb_check_typeddata},
@@ -1164,7 +1170,13 @@ static VALUE vim_to_ruby(typval_T *tv)
 	    result = Qtrue;
 	else if (tv->vval.v_number == VVAL_FALSE)
 	    result = Qfalse;
-    } /* else return Qnil; */
+    }
+    else if (tv->v_type == VAR_BLOB)
+    {
+	result = rb_str_new(tv->vval.v_blob->bv_ga.ga_data,
+		tv->vval.v_blob->bv_ga.ga_len);
+    }
+    /* else return Qnil; */
 
     return result;
 }
@@ -1242,6 +1254,19 @@ static buf_T *get_buf(VALUE obj)
     return buf;
 }
 
+static VALUE vim_blob(VALUE self UNUSED, VALUE str)
+{
+    VALUE result = rb_str_new("0z", 2);
+    char    buf[4];
+    int	i;
+    for (i = 0; i < RSTRING_LEN(str); i++)
+    {
+	sprintf(buf, "%02X", RSTRING_PTR(str)[i]);
+	rb_str_concat(result, rb_str_new_cstr(buf));
+    }
+    return result;
+}
+
 static VALUE buffer_s_current(void)
 {
     return buffer_new(curbuf);
@@ -1662,6 +1687,7 @@ static void ruby_vim_init(void)
     rb_define_module_function(mVIM, "set_option", vim_set_option, 1);
     rb_define_module_function(mVIM, "command", vim_command, 1);
     rb_define_module_function(mVIM, "evaluate", vim_evaluate, 1);
+    rb_define_module_function(mVIM, "blob", vim_blob, 1);
 
     eDeletedBufferError = rb_define_class_under(mVIM, "DeletedBufferError",
 						rb_eStandardError);