/*
 * call-seq:
 *   from_memory(string, url = nil, encoding = nil, options = 0)
 *
 * Create a new reader that parses +string+
 */
static VALUE from_memory(int argc, VALUE *argv, VALUE klass)
{
  VALUE rb_buffer, rb_url, encoding, rb_options;

  const char * c_url      = NULL;
  const char * c_encoding = NULL;
  int c_options           = 0; 

  rb_scan_args(argc, argv, "13", &rb_buffer, &rb_url, &encoding, &rb_options);

  rb_buffer = StringValue(rb_buffer) ;
  if (RTEST(rb_url)) c_url = StringValuePtr(rb_url);
  if (RTEST(encoding)) c_encoding = StringValuePtr(encoding);
  if (RTEST(rb_options)) c_options = NUM2INT(rb_options);

  xmlTextReaderPtr reader = xmlReaderForMemory(
      StringValuePtr(rb_buffer),
      RSTRING_LEN(rb_buffer),
      c_url,
      c_encoding,
      c_options
  );

  if(reader == NULL) {
    xmlFreeTextReader(reader);
    rb_raise(rb_eRuntimeError, "couldn't create a parser");
  }

  VALUE rb_reader = Data_Wrap_Struct(klass, NULL, dealloc, reader);
  rb_funcall(rb_reader, rb_intern("initialize"), 2, rb_url, encoding);

  return rb_reader;
}