package com.wouterbreukink.onedrive.filesystem;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.Date;
import java.util.concurrent.TimeUnit;
import java.util.zip.CRC32;
import java.util.zip.CheckedInputStream;
import static com.wouterbreukink.onedrive.CommandLineOpts.getCommandLineOpts;
class ROFileSystemProvider implements FileSystemProvider {
public void delete(File file) throws IOException {
// Do nothing
}
public File createFolder(File file, String name) throws IOException {
return new File(file, name) {
@Override
public boolean isDirectory() {
return true;
}
};
}
public File createFile(File file, String name) throws IOException {
return new File(file, name);
}
public void replaceFile(File original, File replacement) throws IOException {
// Do nothing
}
public void setAttributes(File downloadFile, Date created, Date lastModified) throws IOException {
// Do nothing
}
public boolean verifyCrc(File file, long crc) throws IOException {
return true;
}
public FileMatch verifyMatch(File file, long crc, long fileSize, Date created, Date lastModified) throws IOException {
// Round to nearest second
created = new Date((created.getTime() / 1000) * 1000);
lastModified = new Date((lastModified.getTime() / 1000) * 1000);
BasicFileAttributes attr = Files.readAttributes(file.toPath(), BasicFileAttributes.class);
// Timestamp rounded to the nearest second
Date localCreatedDate = new Date(attr.creationTime().to(TimeUnit.SECONDS) * 1000);
Date localModifiedDate = new Date(attr.lastModifiedTime().to(TimeUnit.SECONDS) * 1000);
boolean sizeMatches = fileSize == file.length();
boolean createdMatches = created.equals(localCreatedDate);
boolean modifiedMatches = lastModified.equals(localModifiedDate);
if (!getCommandLineOpts().useHash() && sizeMatches && createdMatches && modifiedMatches) {
// Close enough!
return FileMatch.YES;
}
long localCrc = getChecksum(file);
boolean crcMatches = crc == localCrc;
// If the crc matches but the timestamps do not we won't upload the content again
if (crcMatches && !(modifiedMatches && createdMatches)) {
return FileMatch.CRC;
} else if (crcMatches) {
return FileMatch.YES;
} else {
return FileMatch.NO;
}
}
public FileMatch verifyMatch(File file, Date created, Date lastModified) throws IOException {
// Round to nearest second
created = new Date((created.getTime() / 1000) * 1000);
lastModified = new Date((lastModified.getTime() / 1000) * 1000);
BasicFileAttributes attr = Files.readAttributes(file.toPath(), BasicFileAttributes.class);
// Timestamp rounded to the nearest second
Date localCreatedDate = new Date(attr.creationTime().to(TimeUnit.SECONDS) * 1000);
Date localModifiedDate = new Date(attr.lastModifiedTime().to(TimeUnit.SECONDS) * 1000);
boolean createdMatches = created.equals(localCreatedDate);
boolean modifiedMatches = lastModified.equals(localModifiedDate);
if (createdMatches && modifiedMatches) {
return FileMatch.YES;
} else {
return FileMatch.NO;
}
}
public long getChecksum(File file) throws IOException {
// Compute CRC32 checksum
CheckedInputStream cis = null;
try {
cis = new CheckedInputStream(new FileInputStream(file), new CRC32());
byte[] buf = new byte[1024];
//noinspection StatementWithEmptyBody
while (cis.read(buf) >= 0) {
}
return cis.getChecksum().getValue();
} finally {
if (cis != null) {
cis.close();
}
}
}
}