/*
 * call-seq: StringIO.new(string=""[, mode])
 *
 * Creates new StringIO instance from with _string_ and _mode_.
 */
static VALUE
strio_initialize(argc, argv, self)
    int argc;
    VALUE *argv;
    VALUE self;
{
    struct StringIO *ptr = check_strio(self);
    VALUE string, mode;
    int trunc = Qfalse;

    if (!ptr) {
        DATA_PTR(self) = ptr = strio_alloc();
    }
    rb_call_super(0, 0);
    switch (rb_scan_args(argc, argv, "02", &string, &mode)) {
      case 2:
        if (FIXNUM_P(mode)) {
            int flags = FIX2INT(mode);
            ptr->flags = rb_io_modenum_flags(flags);
            trunc = flags & O_TRUNC;
        }
        else {
            const char *m = StringValueCStr(mode);
            ptr->flags = rb_io_mode_flags(m);
            trunc = *m == 'w';
        }
        StringValue(string);
        if ((ptr->flags & FMODE_WRITABLE) && OBJ_FROZEN(string)) {
            errno = EACCES;
            rb_sys_fail(0);
        }
        if (trunc) {
            rb_str_resize(string, 0);
        }
        break;
      case 1:
        StringValue(string);
        ptr->flags = OBJ_FROZEN(string) ? FMODE_READABLE : FMODE_READWRITE;
        break;
      case 0:
        string = rb_str_new("", 0);
        ptr->flags = FMODE_READWRITE;
        break;
    }
    ptr->string = string;
    return self;
}