Skip to content

Commit

Permalink
Merge pull request #722 from josedonizetti/supporting_offset
Browse files Browse the repository at this point in the history
REFACTORING: supporting flag about receiving an offset or not.
  • Loading branch information
headius committed May 10, 2013
2 parents 6480caa + 05de78e commit d9a1e1d
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 10 deletions.
36 changes: 30 additions & 6 deletions src/org/jruby/RubyFile.java
Expand Up @@ -331,7 +331,19 @@ public IRubyObject initialize19(ThreadContext context, IRubyObject[] args, Block
}
}

return openFile19(context, args);
RubyBoolean hasOffset = context.runtime.newBoolean(false);
if (args[args.length - 1] instanceof RubyBoolean) {
hasOffset = (RubyBoolean) args[args.length - 1];
IRubyObject[] newArgs = new IRubyObject[args.length - 1];
System.arraycopy(args, 0, newArgs, 0, newArgs.length);
args = newArgs;
}

if(hasOffset.isTrue()) {
return openFile19(context, args, true);
} else {
return openFile19(context, args, false);
}
}

@JRubyMethod(required = 1)
Expand Down Expand Up @@ -1104,8 +1116,11 @@ public void setEncoding(Encoding encoding) {
// :)
}

// mri: rb_open_file + rb_scan_open_args
private IRubyObject openFile19(ThreadContext context, IRubyObject args[]) {
return openFile19(context, args, false);
}
// mri: rb_open_file + rb_scan_open_args
private IRubyObject openFile19(ThreadContext context, IRubyObject args[], boolean hasOffeset) {
Ruby runtime = context.runtime;
RubyString filename = get_path(context, args[0]);

Expand Down Expand Up @@ -1147,7 +1162,7 @@ private IRubyObject openFile19(ThreadContext context, IRubyObject args[]) {
int perm = (pm[EncodingUtils.PERM] != null && !pm[EncodingUtils.PERM].isNil()) ?
RubyNumeric.num2int(pm[EncodingUtils.PERM]) : 0666;

sysopenInternal(path, ModeFlags.createModeFlags(oflags), perm);
sysopenInternal(path, ModeFlags.createModeFlags(oflags), perm, hasOffeset);

return this;
}
Expand Down Expand Up @@ -1184,8 +1199,12 @@ private int getFilePermissions(IRubyObject[] args) {
return (args.length > 2 && !args[2].isNil()) ? RubyNumeric.num2int(args[2]) : 438;
}

// mri: rb_file_open_generic
protected void sysopenInternal(String path, ModeFlags modes, int perm) {
sysopenInternal(path, modes, perm, false);
}

// mri: rb_file_open_generic
protected void sysopenInternal(String path, ModeFlags modes, int perm, boolean hasOffset) {
if (path.startsWith("jar:")) path = path.substring(4);

openFile = new OpenFile();
Expand All @@ -1196,7 +1215,7 @@ protected void sysopenInternal(String path, ModeFlags modes, int perm) {
int umask = getUmaskSafe( getRuntime() );
perm = perm - (perm & umask);

ChannelDescriptor descriptor = sysopen(path, modes, perm);
ChannelDescriptor descriptor = sysopen(path, modes, perm, hasOffset);
openFile.setMainStream(fdopen(descriptor, modes));
if (hasBom) {
// FIXME: Wonky that we acquire RubyEncoding to pass these encodings through
Expand Down Expand Up @@ -1238,14 +1257,19 @@ protected void openInternal(String path, String modeString) {
}

private ChannelDescriptor sysopen(String path, ModeFlags modes, int perm) {
return sysopen(path,modes,perm,false);
}

private ChannelDescriptor sysopen(String path, ModeFlags modes, int perm, boolean hasOffset) {
try {
ChannelDescriptor descriptor = ChannelDescriptor.open(
getRuntime().getCurrentDirectory(),
path,
modes,
perm,
getRuntime().getPosix(),
getRuntime().getJRubyClassLoader());
getRuntime().getJRubyClassLoader(),
hasOffset);

// TODO: check if too many open files, GC and try again

Expand Down
10 changes: 8 additions & 2 deletions src/org/jruby/RubyIO.java
Expand Up @@ -3605,11 +3605,17 @@ private static IRubyObject read19(ThreadContext context, IRubyObject recv, IRuby
*/
private static IRubyObject write19(ThreadContext context, IRubyObject recv, IRubyObject path, IRubyObject str, IRubyObject offset, RubyHash options) {
// FIXME: process options
Ruby runtime = context.runtime;

IRubyObject hasOffset = runtime.getNil();

if (!offset.isNil()) hasOffset = runtime.newBoolean(true);
else hasOffset = runtime.newBoolean(false);

RubyString pathStr = RubyFile.get_path(context, path);
Ruby runtime = context.runtime;

failIfDirectory(runtime, pathStr);
RubyIO file = newFile(context, recv, pathStr, context.runtime.newString("w"));
RubyIO file = newFile(context, recv, pathStr, context.runtime.newString("w"), hasOffset);

try {
if (!offset.isNil()) file.seek(context, offset);
Expand Down
8 changes: 6 additions & 2 deletions src/org/jruby/util/io/ChannelDescriptor.java
Expand Up @@ -790,6 +790,10 @@ public static ChannelDescriptor open(String cwd, String path, ModeFlags flags, i
* @throws java.io.IOException if there is an exception during IO
*/
public static ChannelDescriptor open(String cwd, String path, ModeFlags flags, int perm, POSIX posix, ClassLoader classLoader) throws FileNotFoundException, DirectoryAsFileException, FileExistsException, IOException {
return open(cwd, path, flags, perm, posix, classLoader, false);
}

public static ChannelDescriptor open(String cwd, String path, ModeFlags flags, int perm, POSIX posix, ClassLoader classLoader, boolean hasOffset) throws FileNotFoundException, DirectoryAsFileException, FileExistsException, IOException {
boolean fileCreated = false;
if (path.equals("/dev/null") || path.equalsIgnoreCase("nul:") || path.equalsIgnoreCase("nul")) {
Channel nullChannel = new NullChannel();
Expand Down Expand Up @@ -865,7 +869,7 @@ public static ChannelDescriptor open(String cwd, String path, ModeFlags flags, i
FileChannel fileChannel;
boolean isInAppendMode;
if (flags.isWritable() && !flags.isReadable()) {
FileOutputStream fos = new FileOutputStream(theFile, flags.isAppendable());
RandomAccessFile fos = new RandomAccessFile(theFile, flags.toJavaModeString());
fileChannel = fos.getChannel();
fileDescriptor = fos.getFD();
isInAppendMode = true;
Expand All @@ -887,7 +891,7 @@ public static ChannelDescriptor open(String cwd, String path, ModeFlags flags, i
}

try {
if (flags.isTruncate()) fileChannel.truncate(0);
if (flags.isTruncate() && !hasOffset) fileChannel.truncate(0);
} catch (IOException ioe) {
if (ioe.getMessage().equals("Illegal seek")) {
// ignore; it's a pipe or fifo that can't be truncated
Expand Down

0 comments on commit d9a1e1d

Please sign in to comment.