diff --git a/app/src/main/java/com/hippo/ehviewer/client/EhTagDatabase.kt b/app/src/main/java/com/hippo/ehviewer/client/EhTagDatabase.kt index e931a5add..d85e9d60a 100644 --- a/app/src/main/java/com/hippo/ehviewer/client/EhTagDatabase.kt +++ b/app/src/main/java/com/hippo/ehviewer/client/EhTagDatabase.kt @@ -20,7 +20,6 @@ import com.hippo.ehviewer.AppConfig import com.hippo.ehviewer.EhApplication import com.hippo.ehviewer.EhApplication.Companion.nonCacheOkHttpClient import com.hippo.ehviewer.R -import com.hippo.util.HashCodeUtils import com.hippo.yorozuya.FileUtils import com.hippo.yorozuya.copyToFile import eu.kanade.tachiyomi.util.lang.launchIO @@ -30,16 +29,15 @@ import kotlinx.coroutines.flow.flow import okhttp3.OkHttpClient import okhttp3.Request import okio.BufferedSource +import okio.HashingSink.Companion.sha1 +import okio.blackholeSink import okio.buffer import okio.source import org.json.JSONException import org.json.JSONObject import java.io.File -import java.io.FileInputStream import java.io.IOException import java.nio.charset.StandardCharsets -import java.security.MessageDigest -import java.security.NoSuchAlgorithmException private typealias TagGroup = Map private typealias TagGroups = Map @@ -161,35 +159,24 @@ object EhTagDatabase { } private fun getFileContent(file: File): String? { - try { - file.source().buffer().use { return it.readString(StandardCharsets.UTF_8) } - } catch (e: IOException) { - return null - } + return runCatching { + file.source().buffer().use { it.readString(StandardCharsets.UTF_8) } + }.getOrNull() } private fun getFileSha1(file: File): String? { - try { - FileInputStream(file).use { stream -> - val digest = MessageDigest.getInstance("SHA-1") - var n: Int - val buffer = ByteArray(4 * 1024) - while (stream.read(buffer).also { n = it } != -1) { - digest.update(buffer, 0, n) + return runCatching { + file.source().buffer().use { source -> + sha1(blackholeSink()).use { + source.readAll(it) + it.hash.hex() } - return HashCodeUtils.bytesToHexString(digest.digest()) } - } catch (e: IOException) { - return null - } catch (e: NoSuchAlgorithmException) { - return null - } + }.getOrNull() } - private fun checkData(sha1File: File, dataFile: File): Boolean { - val s1 = getFileContent(sha1File) ?: return false - val s2 = getFileSha1(dataFile) ?: return false - return s1 == s2 + private fun checkData(sha1: String?, data: File): Boolean { + return sha1 != null && sha1 == getFileSha1(data) } private fun save(client: OkHttpClient, url: String, file: File): Boolean { @@ -229,38 +216,31 @@ object EhTagDatabase { val dataName = urls[2] val dataUrl = urls[3] - try { - val dir = AppConfig.getFilesDir("tag-translations") - checkNotNull(dir) + val dir = AppConfig.getFilesDir("tag-translations") + checkNotNull(dir) + val sha1File = File(dir, sha1Name) + val dataFile = File(dir, dataName) + runCatching { // Check current sha1 and current data - val sha1File = File(dir, sha1Name) - val dataFile = File(dir, dataName) - if (!checkData(sha1File, dataFile)) { + val sha1 = getFileContent(sha1File) + if (!checkData(sha1, dataFile)) { FileUtils.delete(sha1File) FileUtils.delete(dataFile) } - // Read current EhTagDatabase - if (!isInitialized() && dataFile.exists()) { - try { - dataFile.source().buffer().use { updateData(it) } - } catch (e: IOException) { - FileUtils.delete(sha1File) - FileUtils.delete(dataFile) - } - } val client = nonCacheOkHttpClient // Save new sha1 val tempSha1File = File(dir, "$sha1Name.tmp") check(save(client, sha1Url, tempSha1File)) + val tempSha1 = getFileContent(tempSha1File) - // Check new sha1 and current data - if (checkData(tempSha1File, dataFile)) { + // Check new sha1 and current sha1 + if (tempSha1 == sha1) { // The data is the same FileUtils.delete(tempSha1File) - return + return@runCatching } // Save new data @@ -268,10 +248,10 @@ object EhTagDatabase { check(save(client, dataUrl, tempDataFile)) // Check new sha1 and new data - if (!checkData(tempSha1File, tempDataFile)) { + if (!checkData(tempSha1, tempDataFile)) { FileUtils.delete(tempSha1File) FileUtils.delete(tempDataFile) - return + return@runCatching } // Replace current sha1 and current data with new sha1 and new data @@ -285,8 +265,18 @@ object EhTagDatabase { dataFile.source().buffer().use { updateData(it) } } catch (_: IOException) { } - } catch (e: Throwable) { - e.printStackTrace() + }.onFailure { + it.printStackTrace() + } + + // Read current EhTagDatabase + if (!isInitialized() && dataFile.exists()) { + try { + dataFile.source().buffer().use { updateData(it) } + } catch (e: IOException) { + FileUtils.delete(sha1File) + FileUtils.delete(dataFile) + } } } } diff --git a/app/src/main/java/com/hippo/util/HashCodeUtils.java b/app/src/main/java/com/hippo/util/HashCodeUtils.java deleted file mode 100644 index dee884947..000000000 --- a/app/src/main/java/com/hippo/util/HashCodeUtils.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2017 Hippo Seven - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hippo.util; -/* - * Created by Hippo on 2017/9/4. - */ - -public class HashCodeUtils { - - private static final int X = 31; - - /** - *
{@code
-     * args[0].hashCode()*31^(n-1) + args[1].hashCode()*31^(n-2) + ... + args[n-1].hashCode()
-     * }
- * Returns 0 if {@code args == null}. - */ - public static int hashCode(Object... args) { - if (args == null) { - return 0; - } - int hash = 0; - for (Object o : args) { - hash = X * hash + (o != null ? o.hashCode() : 0); - } - return hash; - } - - /** - * http://stackoverflow.com/questions/332079 - * - * @param bytes The bytes to convert. - * @return A {@link String} converted from the bytes of a hashable key used - * to store a filename on the disk, to hex digits. - */ - public static String bytesToHexString(final byte[] bytes) { - final StringBuilder builder = new StringBuilder(); - for (final byte b : bytes) { - final String hex = Integer.toHexString(0xFF & b); - if (hex.length() == 1) { - builder.append('0'); - } - builder.append(hex); - } - return builder.toString(); - } -}