package com.plusonelabs.calendar.prefs;
import android.content.Context;
import android.support.annotation.NonNull;
import android.text.TextUtils;
import android.util.Log;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.nio.charset.Charset;
import java.util.Arrays;
/**
* @author yvolk@yurivolkov.com
*/
public class SettingsStorage {
private static final int BUFFER_LENGTH = 4 * 1024;
private SettingsStorage() {
// Not instantiable
}
public static void saveJson(Context context, String key, JSONObject json) throws IOException {
writeStringToFile(json.toString(), jsonFile(context, key));
}
@NonNull
public static JSONObject loadJson(Context context, String key) throws IOException {
return getJSONObject(jsonFile(context, key));
}
public static void delete(Context context, String key) {
File file = jsonFile(context, key);
if (file.exists()) {
file.delete();
}
}
private static File jsonFile(Context context, String key) {
return new File(getExistingPreferencesDirectory(context), key + ".json");
}
private static File getExistingPreferencesDirectory(Context context) {
File dir = new File(context.getApplicationInfo().dataDir, "shared_prefs");
if (!dir.exists()) {
dir.mkdirs();
}
return dir;
}
private static void writeStringToFile(String string, File file) throws IOException {
FileOutputStream fileOutputStream = null;
Writer out = null;
try {
fileOutputStream = new FileOutputStream(file.getAbsolutePath(), false);
out = new BufferedWriter(new OutputStreamWriter(fileOutputStream, "UTF-8"));
out.write(string);
} finally {
closeSilently(out);
closeSilently(fileOutputStream);
}
}
@NonNull
private static JSONObject getJSONObject(File file) throws IOException {
String fileString = utf8File2String(file);
if (!TextUtils.isEmpty(fileString)) {
try {
return new JSONObject(fileString);
} catch (JSONException e) {
Log.v("getJSONObject", file.getAbsolutePath(), e);
}
}
return new JSONObject();
}
private static String utf8File2String(File file) throws IOException {
return new String(getBytes(file), Charset.forName("UTF-8"));
}
/**
* Reads the whole file
*/
private static byte[] getBytes(File file) throws IOException {
if (file != null) {
return getBytes(new FileInputStream(file));
}
return new byte[0];
}
/**
* Read the stream into an array and close the stream
**/
private static byte[] getBytes(InputStream is) throws IOException {
ByteArrayOutputStream bout = new ByteArrayOutputStream();
if (is != null) {
byte[] readBuffer = new byte[BUFFER_LENGTH];
try {
int read;
do {
read = is.read(readBuffer, 0, readBuffer.length);
if (read == -1) {
break;
}
bout.write(readBuffer, 0, read);
} while (true);
return bout.toByteArray();
} finally {
closeSilently(is);
}
}
return new byte[0];
}
/**
* Reads up to 'size' bytes, starting from 'offset'
*/
private static byte[] getBytes(File file, int offset, int size) throws IOException {
if (file != null) {
InputStream is = new FileInputStream(file);
byte[] readBuffer = new byte[size];
try {
long bytesSkipped = is.skip(offset);
if (bytesSkipped < offset) {
throw new FileNotFoundException("Skipped only " + bytesSkipped
+ " of " + offset + " bytes in file='" + file.getAbsolutePath() + "'");
}
int bytesRead = is.read(readBuffer, 0, size);
if (bytesRead == readBuffer.length) {
return readBuffer;
} else if (bytesRead > 0) {
return Arrays.copyOf(readBuffer, bytesRead);
}
} finally {
closeSilently(is);
}
}
return new byte[0];
}
private static void closeSilently(Closeable closeable) {
if (closeable != null) {
try {
closeable.close();
} catch (IOException e) {
// Ignored
}
}
}
}