4399游戏盒 v7.2.1.31版本的 MD5 值为:951717f45e3fda95c8a358caf4ca93e1

以下内容为反编译后的 DbStoragePlainFile.java 源代码,内容仅作参考


package io.paperdb;

import android.content.Context;
import android.util.Log;
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.KryoException;
import com.esotericsoftware.kryo.Serializer;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
import com.esotericsoftware.kryo.serializers.CompatibleFieldSerializer;
import de.javakaffee.kryoserializers.ArraysAsListSerializer;
import de.javakaffee.kryoserializers.SynchronizedCollectionsSerializer;
import de.javakaffee.kryoserializers.UUIDSerializer;
import de.javakaffee.kryoserializers.UnmodifiableCollectionsSerializer;
import io.paperdb.serializer.NoArgCollectionSerializer;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.UUID;
import org.objenesis.b.d;

public class DbStoragePlainFile implements Storage {
    private final Context mContext;
    private final HashMap<Class, Serializer> mCustomSerializers;
    private final String mDbName;
    private String mFilesDir;
    private final ThreadLocal<Kryo> mKryo = new ThreadLocal<Kryo>() {
        @Override
        public Kryo initialValue() {
            return DbStoragePlainFile.this.createKryoInstance();
        }
    };
    private boolean mPaperDirIsCreated;

    private Kryo getKryo() {
        return this.mKryo.get();
    }

    public Kryo createKryoInstance() {
        Kryo kryo = new Kryo();
        kryo.register(PaperTable.class);
        kryo.setDefaultSerializer(CompatibleFieldSerializer.class);
        kryo.setReferences(false);
        kryo.register(Arrays.asList("").getClass(), new ArraysAsListSerializer());
        UnmodifiableCollectionsSerializer.registerSerializers(kryo);
        SynchronizedCollectionsSerializer.registerSerializers(kryo);
        kryo.addDefaultSerializer(new ArrayList().subList(0, 0).getClass(), new NoArgCollectionSerializer());
        kryo.addDefaultSerializer(new LinkedList().subList(0, 0).getClass(), new NoArgCollectionSerializer());
        kryo.register(UUID.class, new UUIDSerializer());
        for (Class cls : this.mCustomSerializers.keySet()) {
            kryo.register(cls, this.mCustomSerializers.get(cls));
        }
        kryo.setInstantiatorStrategy(new Kryo.DefaultInstantiatorStrategy(new d()));
        return kryo;
    }

    public DbStoragePlainFile(Context context, String str, HashMap<Class, Serializer> hashMap) {
        this.mContext = context;
        this.mDbName = str;
        this.mCustomSerializers = hashMap;
    }

    @Override
    public synchronized void destroy() {
        assertInit();
        String dbPath = getDbPath(this.mContext, this.mDbName);
        if (!deleteDirectory(dbPath)) {
            Log.e("paperdb", "Couldn't delete Paper dir " + dbPath);
        }
        this.mPaperDirIsCreated = false;
    }

    @Override
    public synchronized <E> void insert(String str, E e) {
        assertInit();
        PaperTable<E> paperTable = new PaperTable<>(e);
        File originalFile = getOriginalFile(str);
        File makeBackupFile = makeBackupFile(originalFile);
        if (originalFile.exists()) {
            if (!makeBackupFile.exists()) {
                if (!originalFile.renameTo(makeBackupFile)) {
                    throw new PaperDbException("Couldn't rename file " + originalFile + " to backup file " + makeBackupFile);
                }
            } else {
                originalFile.delete();
            }
        }
        writeTableFile(str, paperTable, originalFile, makeBackupFile);
    }

    @Override
    public synchronized <E> E select(String str) {
        assertInit();
        File originalFile = getOriginalFile(str);
        File makeBackupFile = makeBackupFile(originalFile);
        if (makeBackupFile.exists()) {
            originalFile.delete();
            makeBackupFile.renameTo(originalFile);
        }
        if (!exist(str)) {
            return null;
        }
        return (E) readTableFile(str, originalFile);
    }

    @Override
    public synchronized boolean exist(String str) {
        assertInit();
        return getOriginalFile(str).exists();
    }

    @Override
    public List<String> getAllKeys() {
        assertInit();
        String[] list = new File(this.mFilesDir).list();
        if (list != null) {
            for (int i = 0; i < list.length; i++) {
                list[i] = list[i].replace(".pt", "");
            }
            return Arrays.asList(list);
        }
        return new ArrayList();
    }

    @Override
    public synchronized void deleteIfExists(String str) {
        assertInit();
        File originalFile = getOriginalFile(str);
        if (originalFile.exists()) {
            if (originalFile.delete()) {
                return;
            }
            throw new PaperDbException("Couldn't delete file " + originalFile + " for table " + str);
        }
    }

    private File getOriginalFile(String str) {
        return new File(this.mFilesDir + File.separator + str + ".pt");
    }

    private <E> void writeTableFile(String str, PaperTable<E> paperTable, File file, File file2) {
        try {
            FileOutputStream fileOutputStream = new FileOutputStream(file);
            Output output = new Output(fileOutputStream);
            getKryo().writeObject(output, paperTable);
            output.flush();
            fileOutputStream.flush();
            sync(fileOutputStream);
            output.close();
            file2.delete();
        } catch (KryoException | IOException e) {
            if (file.exists() && !file.delete()) {
                throw new PaperDbException("Couldn't clean up partially-written file " + file, e);
            }
            throw new PaperDbException("Couldn't save table: " + str + ". Backed up table will be used on next read attempt", e);
        }
    }

    private <E> E readTableFile(String str, File file) {
        try {
            Input input = new Input(new FileInputStream(file));
            PaperTable paperTable = (PaperTable) getKryo().readObject(input, PaperTable.class);
            input.close();
            return (E) paperTable.mContent;
        } catch (KryoException | FileNotFoundException e) {
            if (file.exists() && !file.delete()) {
                throw new PaperDbException("Couldn't clean up broken/unserializable file " + file, e);
            }
            String str2 = "Couldn't read/deserialize file " + file + " for table " + str;
            if (e.getMessage().startsWith("Class cannot be created (missing no-arg constructor): ")) {
                str2 = "You have to add a public no-arg constructor for the class" + e.getMessage().replace("Class cannot be created (missing no-arg constructor):", "") + "\n Read more: https://github.com/pilgr/Paper#save";
            }
            throw new PaperDbException(str2, e);
        }
    }

    private String getDbPath(Context context, String str) {
        return context.getFilesDir() + File.separator + str;
    }

    private void assertInit() {
        if (this.mPaperDirIsCreated) {
            return;
        }
        createPaperDir();
        this.mPaperDirIsCreated = true;
    }

    private void createPaperDir() {
        this.mFilesDir = getDbPath(this.mContext, this.mDbName);
        if (new File(this.mFilesDir).exists() || new File(this.mFilesDir).mkdirs()) {
            return;
        }
        throw new RuntimeException("Couldn't create Paper dir: " + this.mFilesDir);
    }

    private static boolean deleteDirectory(String str) {
        File[] listFiles;
        File file = new File(str);
        if (file.exists() && (listFiles = file.listFiles()) != null) {
            for (File file2 : listFiles) {
                if (file2.isDirectory()) {
                    deleteDirectory(file2.toString());
                } else {
                    file2.delete();
                }
            }
        }
        return file.delete();
    }

    private File makeBackupFile(File file) {
        return new File(file.getPath() + ".bak");
    }

    private static boolean sync(FileOutputStream fileOutputStream) {
        if (fileOutputStream == null) {
            return true;
        }
        try {
            fileOutputStream.getFD().sync();
            return true;
        } catch (IOException unused) {
            return false;
        }
    }
}