private void strioInit(ThreadContext context, IRubyObject[] args) { Ruby runtime = context.runtime; RubyString string; IRubyObject mode; boolean trunc = false; switch (args.length) { case 2: mode = args[1]; if (mode instanceof RubyFixnum) { int flags = RubyFixnum.fix2int(mode); ptr.flags = ModeFlags.getOpenFileFlagsFor(flags); trunc = (flags & ModeFlags.TRUNC) != 0; } else { String m = args[1].convertToString().toString(); ptr.flags = OpenFile.ioModestrFmode(runtime, m); trunc = m.charAt(0) == 'w'; } string = args[0].convertToString(); if ((ptr.flags & OpenFile.WRITABLE) != 0 && string.isFrozen()) { throw runtime.newErrnoEACCESError("Permission denied"); } if (trunc) { string.resize(0); } break; case 1: string = args[0].convertToString(); ptr.flags = string.isFrozen() ? OpenFile.READABLE : OpenFile.READWRITE; break; case 0: string = RubyString.newEmptyString(runtime, runtime.getDefaultExternalEncoding()); ptr.flags = OpenFile.READWRITE; break; default: throw runtime.newArgumentError(args.length, 2); } ptr.string = string; ptr.pos = 0; ptr.lineno = 0; // funky way of shifting readwrite flags into object flags flags |= (ptr.flags & OpenFile.READWRITE) * (STRIO_READABLE / OpenFile.READABLE); }
@JRubyMethod(name = "read", optional = 2) public IRubyObject read(ThreadContext context, IRubyObject[] args) { checkReadable(); Ruby runtime = context.runtime; IRubyObject str = runtime.getNil(); int len; boolean binary = false; switch (args.length) { case 2: str = args[1]; if (!str.isNil()) { str = str.convertToString(); ((RubyString) str).modify(); } case 1: if (!args[0].isNil()) { len = RubyNumeric.fix2int(args[0]); if (len < 0) { throw getRuntime().newArgumentError("negative length " + len + " given"); } if (len > 0 && isEndOfString()) { if (!str.isNil()) ((RubyString) str).resize(0); return getRuntime().getNil(); } binary = true; break; } case 0: len = ptr.string.size(); if (len <= ptr.pos) { if (str.isNil()) { str = runtime.newString(); } else { ((RubyString) str).resize(0); } return str; } else { len -= ptr.pos; } break; default: throw getRuntime().newArgumentError(args.length, 0); } if (str.isNil()) { str = strioSubstr(runtime, ptr.pos, len); if (binary) ((RubyString) str).setEncoding(ASCIIEncoding.INSTANCE); } else { int rest = ptr.string.size() - ptr.pos; if (len > rest) len = rest; ((RubyString) str).resize(len); ByteList strByteList = ((RubyString) str).getByteList(); byte[] strBytes = strByteList.getUnsafeBytes(); ByteList dataByteList = ptr.string.getByteList(); byte[] dataBytes = dataByteList.getUnsafeBytes(); System.arraycopy( dataBytes, dataByteList.getBegin() + ptr.pos, strBytes, strByteList.getBegin(), len); if (binary) { ((RubyString) str).setEncoding(ASCIIEncoding.INSTANCE); } else { ((RubyString) str).setEncoding(ptr.string.getEncoding()); } } ptr.pos += ((RubyString) str).size(); return str; }