FileLoader.java

/*
 * Decompiled with CFR 0_132.
 * 
 * Could not load the following classes:
 *  android.text.TextUtils
 */
package org.xutils.http.loader;

import android.text.TextUtils;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.Arrays;
import java.util.Date;
import org.xutils.cache.DiskCacheEntity;
import org.xutils.cache.DiskCacheFile;
import org.xutils.cache.LruDiskCache;
import org.xutils.common.Callback;
import org.xutils.common.util.IOUtil;
import org.xutils.common.util.LogUtil;
import org.xutils.common.util.ProcessLock;
import org.xutils.ex.FileLockedException;
import org.xutils.ex.HttpException;
import org.xutils.http.ProgressHandler;
import org.xutils.http.RequestParams;
import org.xutils.http.loader.Loader;
import org.xutils.http.request.UriRequest;

public class FileLoader
extends Loader<File> {
    private static final int CHECK_SIZE = 512;
    private String tempSaveFilePath;
    private String saveFilePath;
    private boolean isAutoResume;
    private boolean isAutoRename;
    private long contentLength;
    private String responseFileName;
    private DiskCacheFile diskCacheFile;

    @Override
    public Loader<File> newInstance() {
        return new FileLoader();
    }

    @Override
    public void setParams(RequestParams params) {
        if (params != null) {
            this.params = params;
            this.isAutoResume = params.isAutoResume();
            this.isAutoRename = params.isAutoRename();
        }
    }

    /*
     * WARNING - Removed try catching itself - possible behaviour change.
     */
    @Override
    public File load(InputStream in) throws Throwable {
        File targetFile = null;
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        try {
            File dir;
            int len;
            targetFile = new File(this.tempSaveFilePath);
            if (targetFile.isDirectory()) {
                IOUtil.deleteFileOrDir(targetFile);
            }
            if (!(targetFile.exists() || (dir = targetFile.getParentFile()).exists() || dir.mkdirs())) {
                throw new IOException("can not create dir: " + dir.getAbsolutePath());
            }
            long targetFileLen = targetFile.length();
            if (this.isAutoResume && targetFileLen > 0L) {
                FileInputStream fis;
                block16 : {
                    fis = null;
                    try {
                        long filePos = targetFileLen - 512L;
                        if (filePos > 0L) {
                            fis = new FileInputStream(targetFile);
                            byte[] fileCheckBuffer = IOUtil.readBytes(fis, filePos, 512);
                            byte[] checkBuffer = IOUtil.readBytes(in, 0L, 512);
                            if (!Arrays.equals(checkBuffer, fileCheckBuffer)) {
                                IOUtil.closeQuietly(fis);
                                IOUtil.deleteFileOrDir(targetFile);
                                throw new RuntimeException("need retry");
                            }
                            this.contentLength -= 512L;
                            break block16;
                        }
                        IOUtil.deleteFileOrDir(targetFile);
                        throw new RuntimeException("need retry");
                    }
                    catch (Throwable throwable) {
                        IOUtil.closeQuietly(fis);
                        throw throwable;
                    }
                }
                IOUtil.closeQuietly(fis);
            }
            long current = 0L;
            FileOutputStream fileOutputStream = null;
            if (this.isAutoResume) {
                current = targetFileLen;
                fileOutputStream = new FileOutputStream(targetFile, true);
            } else {
                fileOutputStream = new FileOutputStream(targetFile);
            }
            long total = this.contentLength + current;
            bis = new BufferedInputStream(in);
            bos = new BufferedOutputStream(fileOutputStream);
            if (this.progressHandler != null && !this.progressHandler.updateProgress(total, current, true)) {
                throw new Callback.CancelledException("download stopped!");
            }
            byte[] tmp = new byte[4096];
            while ((len = bis.read(tmp)) != -1) {
                if (!targetFile.getParentFile().exists()) {
                    targetFile.getParentFile().mkdirs();
                    throw new IOException("parent be deleted!");
                }
                bos.write(tmp, 0, len);
                if (this.progressHandler == null || this.progressHandler.updateProgress(total, current += (long)len, false)) continue;
                bos.flush();
                throw new Callback.CancelledException("download stopped!");
            }
            bos.flush();
            if (this.diskCacheFile != null) {
                targetFile = this.diskCacheFile.commit();
            }
            if (this.progressHandler != null) {
                this.progressHandler.updateProgress(total, current, true);
            }
        }
        catch (Throwable throwable) {
            IOUtil.closeQuietly(bis);
            IOUtil.closeQuietly(bos);
            throw throwable;
        }
        IOUtil.closeQuietly(bis);
        IOUtil.closeQuietly(bos);
        return this.autoRename(targetFile);
    }

    /*
     * WARNING - Removed try catching itself - possible behaviour change.
     */
    @Override
    public File load(UriRequest request) throws Throwable {
        File result;
        block21 : {
            ProcessLock processLock = null;
            result = null;
            try {
                this.saveFilePath = this.params.getSaveFilePath();
                this.diskCacheFile = null;
                if (TextUtils.isEmpty((CharSequence)this.saveFilePath)) {
                    if (this.progressHandler != null && !this.progressHandler.updateProgress(0L, 0L, false)) {
                        throw new Callback.CancelledException("download stopped!");
                    }
                    this.initDiskCacheFile(request);
                } else {
                    this.tempSaveFilePath = this.saveFilePath + ".tmp";
                }
                if (this.progressHandler != null && !this.progressHandler.updateProgress(0L, 0L, false)) {
                    throw new Callback.CancelledException("download stopped!");
                }
                processLock = ProcessLock.tryLock(this.saveFilePath + "_lock", true);
                if (processLock == null || !processLock.isValid()) {
                    throw new FileLockedException("download exists: " + this.saveFilePath);
                }
                this.params = request.getParams();
                long range = 0L;
                if (this.isAutoResume) {
                    File tempFile = new File(this.tempSaveFilePath);
                    long fileLen = tempFile.length();
                    if (fileLen <= 512L) {
                        IOUtil.deleteFileOrDir(tempFile);
                        range = 0L;
                    } else {
                        range = fileLen - 512L;
                    }
                }
                this.params.setHeader("RANGE", "bytes=" + range + "-");
                if (this.progressHandler != null && !this.progressHandler.updateProgress(0L, 0L, false)) {
                    throw new Callback.CancelledException("download stopped!");
                }
                request.sendRequest();
                this.contentLength = request.getContentLength();
                if (this.isAutoRename) {
                    this.responseFileName = FileLoader.getResponseFileName(request);
                }
                if (this.isAutoResume) {
                    this.isAutoResume = FileLoader.isSupportRange(request);
                }
                if (this.progressHandler != null && !this.progressHandler.updateProgress(0L, 0L, false)) {
                    throw new Callback.CancelledException("download stopped!");
                }
                if (this.diskCacheFile != null) {
                    DiskCacheEntity entity = this.diskCacheFile.getCacheEntity();
                    entity.setLastAccess(System.currentTimeMillis());
                    entity.setEtag(request.getETag());
                    entity.setExpires(request.getExpiration());
                    entity.setLastModify(new Date(request.getLastModified()));
                }
                result = this.load(request.getInputStream());
                IOUtil.closeQuietly(processLock);
            }
            catch (HttpException httpException) {
                if (httpException.getCode() == 416) {
                    result = this.diskCacheFile != null ? this.diskCacheFile.commit() : new File(this.tempSaveFilePath);
                    if (result != null && result.exists()) {
                        if (this.isAutoRename) {
                            this.responseFileName = FileLoader.getResponseFileName(request);
                        }
                        result = this.autoRename(result);
                        break block21;
                    }
                    IOUtil.deleteFileOrDir(result);
                    throw new IllegalStateException("cache file not found" + request.getCacheKey());
                }
                throw httpException;
            }
            finally {
                IOUtil.closeQuietly(processLock);
                IOUtil.closeQuietly(this.diskCacheFile);
            }
            IOUtil.closeQuietly(this.diskCacheFile);
        }
        return result;
    }

    private void initDiskCacheFile(UriRequest request) throws Throwable {
        DiskCacheEntity entity = new DiskCacheEntity();
        entity.setKey(request.getCacheKey());
        this.diskCacheFile = LruDiskCache.getDiskCache(this.params.getCacheDirName()).createDiskCacheFile(entity);
        if (this.diskCacheFile == null) {
            throw new IOException("create cache file error:" + request.getCacheKey());
        }
        this.tempSaveFilePath = this.saveFilePath = this.diskCacheFile.getAbsolutePath();
        this.isAutoRename = false;
    }

    private File autoRename(File loadedFile) {
        if (this.isAutoRename && loadedFile.exists() && !TextUtils.isEmpty((CharSequence)this.responseFileName)) {
            File newFile = new File(loadedFile.getParent(), this.responseFileName);
            while (newFile.exists()) {
                newFile = new File(loadedFile.getParent(), "" + System.currentTimeMillis() + this.responseFileName);
            }
            return loadedFile.renameTo(newFile) ? newFile : loadedFile;
        }
        if (!this.saveFilePath.equals(this.tempSaveFilePath)) {
            File newFile = new File(this.saveFilePath);
            return loadedFile.renameTo(newFile) ? newFile : loadedFile;
        }
        return loadedFile;
    }

    private static String getResponseFileName(UriRequest request) {
        int startIndex;
        if (request == null) {
            return null;
        }
        String disposition = request.getResponseHeader("Content-Disposition");
        if (!TextUtils.isEmpty((CharSequence)disposition) && (startIndex = disposition.indexOf("filename=")) > 0) {
            int endIndex = disposition.indexOf(";", startIndex += 9);
            if (endIndex < 0) {
                endIndex = disposition.length();
            }
            if (endIndex > startIndex) {
                try {
                    String name = URLDecoder.decode(disposition.substring(startIndex, endIndex), request.getParams().getCharset());
                    if (name.startsWith("\"") && name.endsWith("\"")) {
                        name = name.substring(1, name.length() - 1);
                    }
                    return name;
                }
                catch (UnsupportedEncodingException ex) {
                    LogUtil.e(ex.getMessage(), ex);
                }
            }
        }
        return null;
    }

    private static boolean isSupportRange(UriRequest request) {
        if (request == null) {
            return false;
        }
        String ranges = request.getResponseHeader("Accept-Ranges");
        if (ranges != null) {
            return ranges.contains("bytes");
        }
        ranges = request.getResponseHeader("Content-Range");
        return ranges != null && ranges.contains("bytes");
    }

    @Override
    public File loadFromCache(DiskCacheEntity cacheEntity) throws Throwable {
        return LruDiskCache.getDiskCache(this.params.getCacheDirName()).getDiskCacheFile(cacheEntity.getKey());
    }

    @Override
    public void save2Cache(UriRequest request) {
    }
}