strings.cc
Go to the documentation of this file.
00001 #include "typelib.hh"
00002 #include <string>
00003 
00004 using namespace Typelib;
00005 using std::string;
00006 using namespace typelib_ruby;
00007 
00008 static bool is_string_handler(Registry const& registry, Type const& type, bool known_size = false)
00009 {
00010     if (type.getCategory() != Type::Array && type.getCategory() != Type::Pointer)
00011         return false;
00012 
00013     Type const* char_type(registry.get("/char"));
00014     if (!char_type)
00015         return false;
00016 
00017     Type const& data_type(static_cast<Indirect const&>(type).getIndirection());
00018     if (data_type.getName() != char_type->getName())
00019         return false;
00020 
00021     if (known_size && type.getCategory() == Type::Pointer)
00022         return false;
00023 
00024     return true;
00025 
00026 }
00027 static void string_buffer_get(Value const& value, char*& buffer, string::size_type& size)
00028 {
00029     Type const& type(value.getType());
00030     if (type.getCategory() == Type::Array)
00031     {
00032         buffer = reinterpret_cast<char*>(value.getData());
00033         size = static_cast<Array const&>(type).getDimension();
00034     }
00035     else
00036     {
00037         buffer = *reinterpret_cast<char**>(value.getData());
00038         size   = string::npos;
00039     }
00040 }
00041 
00042 static VALUE value_string_handler_p(VALUE self)
00043 {
00044     Value const& value(rb2cxx::object<Value>(self));
00045     Type  const& type(value.getType());
00046     Registry const& registry = rb2cxx::object<Registry>(value_get_registry(self));
00047     return is_string_handler(registry, type) ? Qtrue : Qfalse;
00048 }
00049 
00050 /*
00051  * Handle convertion between Ruby's String and C 'char*' types
00052  * It is a module function used to define #to_str on the relevant types
00053  * NEVER call it directly
00054  */
00055 static VALUE value_from_string(VALUE mod, VALUE self, VALUE from, VALUE known_good_type)
00056 {
00057     Value const& value(rb2cxx::object<Value>(self));
00058     Type  const& type(value.getType());
00059     Registry const& registry = rb2cxx::object<Registry>(value_get_registry(self));
00060 
00061     if (!RTEST(known_good_type) && !is_string_handler(registry, type, true))
00062         rb_raise(rb_eTypeError, "Ruby strings can only be converted to char arrays");
00063 
00064     char * buffer;
00065     string::size_type buffer_size;
00066     string_buffer_get(value, buffer, buffer_size);
00067 
00068     string::size_type from_length = RSTRING_LEN(StringValue(from));
00069     if ((buffer_size - 1) < from_length)
00070         rb_raise(rb_eArgError, "array to small: %lu, while %lu was needed", buffer_size, from_length + 1);
00071 
00072     strncpy(buffer, StringValueCStr(from), buffer_size);
00073     buffer[buffer_size - 1] = 0;
00074     return self;
00075 }
00076 
00081 static VALUE value_to_string(VALUE mod, VALUE self, VALUE known_good_type)
00082 {
00083     Value const& value(rb2cxx::object<Value>(self));
00084     Type  const& type(value.getType());
00085     Registry const& registry = rb2cxx::object<Registry>(value_get_registry(self));
00086 
00087     if (!RTEST(known_good_type) && !is_string_handler(registry, type))
00088         rb_raise(rb_eRuntimeError, "invalid conversion to string");
00089 
00090     char* buffer;
00091     string::size_type buffer_size;
00092     string_buffer_get(value, buffer, buffer_size);
00093 
00094     if (buffer_size == string::npos)
00095         return rb_str_new2(buffer);
00096     else
00097     {
00098         // Search the real end of the string inside the buffer
00099         string::size_type real_size;
00100         for (real_size = 0; real_size < buffer_size; ++real_size)
00101         {
00102             if (!buffer[real_size])
00103                 break;
00104         }
00105         return rb_str_new(buffer, real_size);
00106     }
00107 }
00108 
00109 void typelib_ruby::Typelib_init_strings()
00110 {
00111     rb_define_singleton_method(cType, "to_string",    RUBY_METHOD_FUNC(&value_to_string), 2);
00112     rb_define_singleton_method(cType, "from_string",  RUBY_METHOD_FUNC(&value_from_string), 3);
00113     rb_define_method(cType, "string_handler?", RUBY_METHOD_FUNC(&value_string_handler_p), 0);
00114 }
00115 


typelib
Author(s): Sylvain Joyeux/sylvain.joyeux@m4x.org
autogenerated on Sat Jun 8 2019 18:49:22