package co.paralleluniverse.fuse;
import java.nio.ByteBuffer;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import jnr.ffi.Pointer;
import jnr.ffi.annotations.Delegate;
import jnr.ffi.types.off_t;
/**
* A class which provides functionality to pass filenames back to FUSE as part of a readdir() call.
*/
final class DirectoryFillerImpl implements DirectoryFiller {
private static final String currentDirectory = ".";
private static final String parentDirectory = "..";
private final Pointer buf;
private final fuse_fill_dir_t nativeFunction;
private final Set<String> addedFiles = new HashSet<String>();
DirectoryFillerImpl(Pointer buf, fuse_fill_dir_t nativeFunction) {
this.buf = buf;
this.nativeFunction = nativeFunction;
add(Arrays.asList(currentDirectory, parentDirectory));
}
public static interface fuse_fill_dir_t {
@Delegate
int invoke(Pointer buf, ByteBuffer name, Pointer stat, @off_t long off);
}
@Override
public final boolean add(Iterable<String> files) {
int result;
for (String file : files) {
if (file == null)
continue;
file = Paths.get(file).getFileName().toString(); // Keep only the name component
if (addedFiles.add(file)) {
result = nativeFunction.invoke(buf, ByteBuffer.wrap(file.getBytes()), null, 0);
if (result != 0)
return false;
}
}
return true;
}
@Override
public String toString() {
final StringBuilder output = new StringBuilder();
int count = 0;
for (final String file : addedFiles) {
output.append(file);
if (count < addedFiles.size() - 1)
output.append(", ");
count++;
}
return output.toString();
}
}