package com.circlegate.liban.utils;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import android.content.Context;
import android.os.Environment;
import com.circlegate.liban.base.ApiDataIO.ApiDataAppVersionCodeLegacyResolver;
import com.circlegate.liban.base.ApiDataIO.ApiDataInput;
import com.circlegate.liban.base.ApiDataIO.ApiDataInputOutputBase;
import com.circlegate.liban.base.ApiDataIO.ApiDataInputStreamWrp;
import com.circlegate.liban.base.ApiDataIO.ApiDataOutput;
import com.circlegate.liban.base.ApiDataIO.ApiDataOutputStreamWrp;
import com.circlegate.liban.base.GlobalContextLib;
public class FileUtils {
private static final String TAG = FileUtils.class.getSimpleName();
private static final String TMP_FILE_POSTFIX = "~tmp";
/* Checks if external storage is available for read and write */
public static boolean isExternalStorageWritable() {
String state = Environment.getExternalStorageState();
return Environment.MEDIA_MOUNTED.equals(state);
}
/* Checks if external storage is available to at least read */
public static boolean isExternalStorageReadable() {
String state = Environment.getExternalStorageState();
return Environment.MEDIA_MOUNTED.equals(state) ||
Environment.MEDIA_MOUNTED_READ_ONLY.equals(state);
}
public static boolean readObjsFromFile(Context context, FileObjsStaticInfo info, ReadObjsCallback callback) {
synchronized (info.getLock()) {
String fileName = info.getFileName();
ApiDataInputStreamWrp stream = null;
try {
if (!context.getFileStreamPath(fileName).exists()) {
fileName += TMP_FILE_POSTFIX; // Pokud dany soubor neexistuje, tak se podivame, jestli neexistuje soubor s priponou ~tmp a pripadne jej zkusime nacist
if (!context.getFileStreamPath(fileName).exists()) {
callback.setDefaults();
return false;
}
}
stream = new ApiDataInputStreamWrp(new DataInputStream(new BufferedInputStream(context.openFileInput(fileName))), info.getCustomFlags(), info);
if (!info.canReadFile1(stream.getDataAppVersionCode())) {
callback.setDefaults();
stream.close();
stream = null;
context.deleteFile(fileName);
return false;
}
else {
callback.readObjects(stream);
return true;
}
}
catch (Exception e) {
LogUtils.e(TAG, "Exception while reading " + fileName, e);
callback.setDefaults();
return false;
}
finally {
if (stream != null)
stream.close();
}
}
}
public static boolean writeObjsToFile(Context context, FileObjsStaticInfo info, WriteObjsCallback callback) {
final boolean ret;
synchronized (info.getLock()) {
ApiDataOutputStreamWrp stream = null;
String fileNameTmp = info.getFileName() + TMP_FILE_POSTFIX;
try {
stream = new ApiDataOutputStreamWrp(new DataOutputStream(new BufferedOutputStream(
context.openFileOutput(fileNameTmp, Context.MODE_PRIVATE))));
callback.writeObjects(stream);
}
catch (Exception e) {
LogUtils.e(TAG, "Exception while writing " + info.getFileName(), e);
return false;
}
finally {
if (stream != null)
stream.close();
}
File tmpFile = context.getFileStreamPath(fileNameTmp);
File origFile = context.getFileStreamPath(info.getFileName());
if (origFile.exists())
origFile.delete();
ret = tmpFile.renameTo(origFile);
}
GlobalContextLib.get().requestGoogleBackupIfNeeded(info.getFileName());
return ret;
}
public static void writeObjsToFileAsync(final Context context, final FileObjsStaticInfo info, final WriteObjsCallback callback) {
Thread t = new Thread(new Runnable() {
public void run() {
writeObjsToFile(context, info, callback);
}
});
t.start();
}
public static class FileObjsStaticInfo implements ApiDataAppVersionCodeLegacyResolver {
private final Object lock;
private final String fileName;
private final int minReadAppVersionCode;
private final int customFlags;
public FileObjsStaticInfo(Object lock, String fileName) {
this(lock, fileName, Integer.MIN_VALUE);
}
public FileObjsStaticInfo(Object lock, String fileName, int minReadAppVersionCode) {
this(lock, fileName, minReadAppVersionCode, ApiDataInputOutputBase.FLAG_NONE);
}
public FileObjsStaticInfo(Object lock, String fileName, int minReadAppVersionCode, int customFlags) {
this.lock = lock;
this.fileName = fileName;
this.minReadAppVersionCode = minReadAppVersionCode;
this.customFlags = customFlags;
}
public Object getLock() {
return this.lock;
}
public String getFileName() {
return this.fileName;
}
public int getCustomFlags() {
return customFlags;
}
public boolean canReadFile1(int fileAppVersionCode) {
return fileAppVersionCode >= minReadAppVersionCode;
}
@Override
public int resolveAppVersionCodeLegacy(int legacyDataVersion) {
return 0;
}
public FileObjsStaticInfo createPortableInfoForWriting() {
return new FileObjsStaticInfo(getLock(), getFileName() + ".port", minReadAppVersionCode, customFlags | ApiDataInputOutputBase.FLAG_PORTABLE);
}
}
public interface ReadObjsCallback {
void readObjects(ApiDataInput d);
void setDefaults();
}
public interface WriteObjsCallback {
void writeObjects(ApiDataOutput d);
}
public interface FileObjsCallback extends WriteObjsCallback, ReadObjsCallback {
}
}