Horis 1 год назад
Родитель
Сommit
fce757e99b

+ 0 - 3
app/src/main/java/io/legado/app/model/localBook/LocalBook.kt

@@ -109,14 +109,11 @@ object LocalBook {
             throw TocEmptyException(appCtx.getString(R.string.chapter_list_empty))
         }
         val list = ArrayList(LinkedHashSet(chapters))
-        var wordCount = 0
         list.forEachIndexed { index, bookChapter ->
             bookChapter.index = index
-            wordCount += bookChapter.tag?.toInt() ?: 0
         }
         book.latestChapterTitle = list.last().title
         book.totalChapterNum = list.size
-        book.wordCount = wordCount.toString() + "字"
         book.save()
         return list
     }

+ 37 - 13
app/src/main/java/io/legado/app/model/localBook/TextFile.kt

@@ -90,7 +90,8 @@ class TextFile(private var book: Book) {
                 }
             }
         }
-        val toc = analyze(book.tocUrl.toPattern(Pattern.MULTILINE))
+        val (toc, wordCount) = analyze(book.tocUrl.toPattern(Pattern.MULTILINE))
+        book.wordCount = StringUtils.wordCountFormat(wordCount)
         toc.forEachIndexed { index, bookChapter ->
             bookChapter.index = index
             bookChapter.bookUrl = book.bookUrl
@@ -140,18 +141,19 @@ class TextFile(private var book: Book) {
     /**
      * 按规则解析目录
      */
-    private fun analyze(pattern: Pattern?): ArrayList<BookChapter> {
+    private fun analyze(pattern: Pattern?): Pair<ArrayList<BookChapter>, Int> {
         if (pattern?.pattern().isNullOrEmpty()) {
             return analyze()
         }
-        pattern ?: return analyze()
         val toc = arrayListOf<BookChapter>()
+        var bookWordCount = 0
         LocalBook.getBookInputStream(book).use { bis ->
             var blockContent: String
             //加载章节
             var curOffset: Long = 0
             //读取的长度
             var length: Int
+            var lastChapterWordCount = 0
             val buffer = ByteArray(bufferSize)
             var bufferStart = 3
             bis.read(buffer, 0, 3)
@@ -192,11 +194,12 @@ class TextFile(private var book: Book) {
                     if (book.getSplitLongChapter() && curOffset + chapterLength - lastStart > maxLengthWithToc) {
                         toc.lastOrNull()?.let {
                             it.end = it.start
+                            it.tag = null
                         }
                         //章节字数太多进行拆分
                         val lastTitle = toc.lastOrNull()?.title
                         val lastTitleLength = lastTitle?.toByteArray(charset)?.size ?: 0
-                        val chapters = analyze(
+                        val (chapters, wordCount) = analyze(
                             lastStart + lastTitleLength, curOffset + chapterLength
                         )
                         lastTitle?.let {
@@ -205,6 +208,7 @@ class TextFile(private var book: Book) {
                             }
                         }
                         toc.addAll(chapters)
+                        bookWordCount += wordCount
                         //创建当前章节
                         val curChapter = BookChapter()
                         curChapter.title = matcher.group()
@@ -222,7 +226,7 @@ class TextFile(private var book: Book) {
                                 qyChapter.title = "前言"
                                 qyChapter.start = curOffset
                                 qyChapter.end = curOffset + chapterLength
-                                qyChapter.tag = chapterContent.length.toString()
+                                qyChapter.tag = StringUtils.wordCountFormat(chapterContent.length)
                                 toc.add(qyChapter)
                                 book.intro = if (chapterContent.length <= 500) {
                                     chapterContent
@@ -242,13 +246,16 @@ class TextFile(private var book: Book) {
                                 chapterContent.substringAfter(lastChapter.title).isBlank()
                             //将当前段落添加上一章去
                             lastChapter.end = lastChapter.end!! + chapterLength
-                            lastChapter.tag = ((lastChapter.tag?.toInt() ?: 0) + chapterContent.length).toString()
+                            lastChapterWordCount += chapterContent.length
+                            lastChapter.tag = StringUtils.wordCountFormat(lastChapterWordCount)
                             //创建当前章节
                             val curChapter = BookChapter()
                             curChapter.title = matcher.group()
                             curChapter.start = lastChapter.end
                             toc.add(curChapter)
                         }
+                        bookWordCount += chapterContent.length
+                        lastChapterWordCount = 0
                     } else {
                         if (toc.isNotEmpty()) { //获取章节内容
                             //获取上一章节
@@ -257,7 +264,7 @@ class TextFile(private var book: Book) {
                                 chapterContent.substringAfter(lastChapter.title).isBlank()
                             lastChapter.end =
                                 lastChapter.start!! + chapterLength
-                            lastChapter.tag = chapterContent.length.toString()
+                            lastChapter.tag = StringUtils.wordCountFormat(chapterContent.length)
                             //创建当前章节
                             val curChapter = BookChapter()
                             curChapter.title = matcher.group()
@@ -268,19 +275,24 @@ class TextFile(private var book: Book) {
                             curChapter.title = matcher.group()
                             curChapter.start = curOffset
                             curChapter.end = curOffset
-                            curChapter.tag = chapterContent.length.toString()
+                            curChapter.tag = StringUtils.wordCountFormat(chapterContent.length)
                             toc.add(curChapter)
                         }
+                        bookWordCount += chapterContent.length
+                        lastChapterWordCount = 0
                     }
                     //设置指针偏移
                     seekPos += chapterContent.length
                 }
+                val wordCount = blockContent.length - seekPos
+                bookWordCount += wordCount
+                lastChapterWordCount += wordCount
                 //block的偏移点
                 curOffset += length.toLong()
                 //设置上一章的结尾
                 toc.lastOrNull()?.let {
                     it.end = curOffset
-                    it.tag = blockContent.substring(seekPos).length.toString()
+                    it.tag = StringUtils.wordCountFormat(lastChapterWordCount)
                 }
             }
             toc.lastOrNull()?.let { chapter ->
@@ -288,9 +300,10 @@ class TextFile(private var book: Book) {
                 if (book.getSplitLongChapter() && chapter.end!! - chapter.start!! > maxLengthWithToc) {
                     val end = chapter.end!!
                     chapter.end = chapter.start
+                    chapter.tag = null
                     val lastTitle = chapter.title
                     val lastTitleLength = lastTitle.toByteArray(charset).size
-                    val chapters = analyze(
+                    val (chapters, _) = analyze(
                         chapter.start!! + lastTitleLength, end
                     )
                     chapters.forEachIndexed { index, bookChapter ->
@@ -302,7 +315,7 @@ class TextFile(private var book: Book) {
         }
         System.gc()
         System.runFinalization()
-        return toc
+        return toc to bookWordCount
     }
 
     /**
@@ -310,8 +323,9 @@ class TextFile(private var book: Book) {
      */
     private fun analyze(
         fileStart: Long = 0L, fileEnd: Long = Long.MAX_VALUE
-    ): ArrayList<BookChapter> {
+    ): Pair<ArrayList<BookChapter>, Int> {
         val toc = arrayListOf<BookChapter>()
+        var bookWordCount = 0
         LocalBook.getBookInputStream(book).use { bis ->
             //block的个数
             var blockPos = 0
@@ -320,6 +334,7 @@ class TextFile(private var book: Book) {
             var chapterPos = 0
             //读取的长度
             var length = 0
+            var lastChapterWordCount = 0
             val buffer = ByteArray(bufferSize)
             var bufferStart = 3
             if (fileStart == 0L) {
@@ -360,10 +375,14 @@ class TextFile(private var book: Book) {
                                 break
                             }
                         }
+                        val content = String(buffer, chapterOffset, end - chapterOffset, charset)
+                        bookWordCount += content.length
+                        lastChapterWordCount = content.length
                         val chapter = BookChapter()
                         chapter.title = "第${blockPos}章($chapterPos)"
                         chapter.start = toc.lastOrNull()?.end ?: curOffset
                         chapter.end = chapter.start!! + end - chapterOffset
+                        chapter.tag = StringUtils.wordCountFormat(content.length)
                         toc.add(chapter)
                         //减去已经被分配的长度
                         strLength -= (end - chapterOffset)
@@ -380,19 +399,24 @@ class TextFile(private var book: Book) {
                 curOffset += length.toLong()
             }
             //设置结尾章节
+            val content = String(buffer, 0, bufferStart, charset)
+            bookWordCount += content.length
             if (bufferStart > 100 || toc.isEmpty()) {
                 val chapter = BookChapter()
                 chapter.title = "第${blockPos}章(${chapterPos})"
                 chapter.start = toc.lastOrNull()?.end ?: curOffset
                 chapter.end = chapter.start!! + bufferStart
+                chapter.tag = StringUtils.wordCountFormat(content.length)
                 toc.add(chapter)
             } else {
+                val wordCount = lastChapterWordCount + content.length
                 toc.lastOrNull()?.let {
                     it.end = it.end!! + bufferStart
+                    it.tag = StringUtils.wordCountFormat(wordCount)
                 }
             }
         }
-        return toc
+        return toc to bookWordCount
     }
 
     /**

+ 21 - 3
app/src/main/java/io/legado/app/utils/StringUtils.kt

@@ -8,7 +8,8 @@ import java.io.ByteArrayOutputStream
 import java.io.IOException
 import java.text.DecimalFormat
 import java.text.SimpleDateFormat
-import java.util.*
+import java.util.Calendar
+import java.util.Locale
 import java.util.regex.Matcher
 import java.util.regex.Pattern
 import java.util.zip.GZIPInputStream
@@ -22,6 +23,9 @@ object StringUtils {
     private const val DAY_OF_YESTERDAY = 2
     private const val TIME_UNIT = 60
     private val ChnMap = chnMap
+    private val wordCountFormatter by lazy {
+        DecimalFormat("#.#")
+    }
 
     private val chnMap: HashMap<Char, Int>
         get() {
@@ -232,16 +236,30 @@ object StringUtils {
         return isNum.matches()
     }
 
+    fun wordCountFormat(words: Int): String {
+        var wordsS = ""
+        if (words > 0) {
+            if (words > 10000) {
+                val df = wordCountFormatter
+                wordsS = df.format(words * 1.0f / 10000f.toDouble()) + "万字"
+            } else {
+                wordsS = words.toString() + "字"
+            }
+        }
+        return wordsS
+    }
+
     fun wordCountFormat(wc: String?): String {
         if (wc == null) return ""
         var wordsS = ""
         if (isNumeric(wc)) {
             val words: Int = wc.toInt()
             if (words > 0) {
-                wordsS = words.toString() + "字"
                 if (words > 10000) {
-                    val df = DecimalFormat("#.#")
+                    val df = wordCountFormatter
                     wordsS = df.format(words * 1.0f / 10000f.toDouble()) + "万字"
+                } else {
+                    wordsS = words.toString() + "字"
                 }
             }
         } else {