pull/2431/head
			
			
		
		
							parent
							
								
									3068eb2138
								
							
						
					
					
						commit
						b95856ff84
					
				| @ -1,35 +1,64 @@ | ||||
| package io.legado.app.utils | ||||
| 
 | ||||
| import android.util.Log | ||||
| import androidx.core.os.postDelayed | ||||
| import com.script.SimpleBindings | ||||
| import io.legado.app.constant.AppConst | ||||
| import io.legado.app.exception.RegexTimeoutException | ||||
| import io.legado.app.help.CrashHandler | ||||
| import io.legado.app.help.coroutine.Coroutine | ||||
| import kotlinx.coroutines.suspendCancellableCoroutine | ||||
| import splitties.init.appCtx | ||||
| import kotlin.coroutines.resume | ||||
| import kotlin.coroutines.resumeWithException | ||||
| 
 | ||||
| private val handler by lazy { buildMainHandler() } | ||||
| 
 | ||||
| /** | ||||
|  * 带有超时检测的正则替换 | ||||
|  */ | ||||
| fun CharSequence.replace(regex: Regex, replacement: String, timeout: Long): String { | ||||
|     val startTime = System.currentTimeMillis() | ||||
|     val charSequence = this | ||||
| suspend fun CharSequence.replace(regex: Regex, replacement: String, timeout: Long): String { | ||||
|     val charSequence = this@replace | ||||
|     val isJs = replacement.startsWith("@js:") | ||||
|     val replacement1 = if (isJs) replacement.substring(4) else replacement | ||||
|     val pattern = regex.toPattern() | ||||
|     val matcher = pattern.matcher(charSequence) | ||||
|     val stringBuffer = StringBuffer() | ||||
|     while (matcher.find()) { | ||||
|         if (System.currentTimeMillis() - startTime > timeout) { | ||||
|             val timeoutMsg = "替换超时,将禁用替换规则" | ||||
|             throw RegexTimeoutException(timeoutMsg) | ||||
|     return suspendCancellableCoroutine { block -> | ||||
|         val coroutine = Coroutine.async { | ||||
|             try { | ||||
|                 val pattern = regex.toPattern() | ||||
|                 val matcher = pattern.matcher(charSequence) | ||||
|                 val stringBuffer = StringBuffer() | ||||
|                 while (matcher.find()) { | ||||
|                     if (isJs) { | ||||
|                         val bindings = SimpleBindings() | ||||
|                         bindings["result"] = matcher.group() | ||||
|                         val jsResult = | ||||
|                             AppConst.SCRIPT_ENGINE.eval(replacement1, bindings).toString() | ||||
|                         matcher.appendReplacement(stringBuffer, jsResult) | ||||
|                     } else { | ||||
|                         matcher.appendReplacement(stringBuffer, replacement1) | ||||
|                     } | ||||
|                 } | ||||
|                 matcher.appendTail(stringBuffer) | ||||
|                 Log.e("regex", "end") | ||||
|                 block.resume(stringBuffer.toString()) | ||||
|             } catch (e: Exception) { | ||||
|                 block.resumeWithException(e) | ||||
|             } | ||||
|         } | ||||
|         if (isJs) { | ||||
|             val bindings = SimpleBindings() | ||||
|             bindings["result"] = matcher.group() | ||||
|             val jsResult = AppConst.SCRIPT_ENGINE.eval(replacement1, bindings).toString() | ||||
|             matcher.appendReplacement(stringBuffer, jsResult) | ||||
|         } else { | ||||
|             matcher.appendReplacement(stringBuffer, replacement1) | ||||
|         handler.postDelayed(timeout) { | ||||
|             if (coroutine.isActive) { | ||||
|                 val timeoutMsg = "替换超时,3秒后还未结束将重启应用\n替换规则$regex\n替换内容:${this}" | ||||
|                 val exception = RegexTimeoutException(timeoutMsg) | ||||
|                 block.cancel(exception) | ||||
|                 appCtx.longToastOnUi(timeoutMsg) | ||||
|                 CrashHandler.saveCrashInfo2File(exception) | ||||
|                 handler.postDelayed(3000) { | ||||
|                     if (coroutine.isActive) { | ||||
|                         appCtx.restart() | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     matcher.appendTail(stringBuffer) | ||||
|     return stringBuffer.toString() | ||||
| } | ||||
| 
 | ||||
|  | ||||
					Loading…
					
					
				
		Reference in new issue