@@ -27,6 +27,10 @@ private var isUnzipping = false
2727class  SVGAParser (context :  Context ? ) {
2828    private  var  mContext =  context?.applicationContext
2929
30+     init  {
31+         SVGACache .onCreate(context)
32+     }
33+ 
3034    @Volatile
3135    private  var  mFrameWidth:  Int  =  0 
3236
@@ -118,6 +122,7 @@ class SVGAParser(context: Context?) {
118122
119123    fun  init (context :  Context ) {
120124        mContext =  context.applicationContext
125+         SVGACache .onCreate(mContext)
121126    }
122127
123128    fun  setFrameSize (frameWidth :  Int , frameHeight :  Int ) {
@@ -134,7 +139,7 @@ class SVGAParser(context: Context?) {
134139            LogUtils .info(TAG , " ================ decode from assets ================" 
135140            threadPoolExecutor.execute {
136141                mContext?.assets?.open(name)?.let  {
137-                     this .decodeFromInputStream(it, buildCacheKey(" file:///assets/$name " true )
142+                     this .decodeFromInputStream(it, SVGACache . buildCacheKey(" file:///assets/$name " true )
138143                }
139144            }
140145        } catch  (e:  java.lang.Exception ) {
@@ -148,24 +153,102 @@ class SVGAParser(context: Context?) {
148153            return  null 
149154        }
150155        LogUtils .info(TAG , " ================ decode from url ================" 
151-         return  if  (this .isCached(buildCacheKey(url))) {
156+         val  cacheKey =  SVGACache .buildCacheKey(url);
157+         return  if  (SVGACache .isCached(cacheKey)) {
152158            LogUtils .info(TAG , " this url cached" 
153159            threadPoolExecutor.execute {
154-                 this .decodeFromCacheKey(buildCacheKey(url), callback)
160+                 if  (SVGACache .isDefaultCache()) {
161+                     this .decodeFromCacheKey(cacheKey, callback)
162+                 } else  {
163+                     this ._decodeFromCacheKey (cacheKey, callback)
164+                 }
155165            }
156-             null 
157-         }
158-         else  {
166+             return  null 
167+         } else  {
159168            LogUtils .info(TAG , " no cached, prepare to download" 
160169            fileDownloader.resume(url, {
161-                 this .decodeFromInputStream(it, this .buildCacheKey(url), callback)
170+                 if  (SVGACache .isDefaultCache()) {
171+                     this .decodeFromInputStream(it, cacheKey, callback)
172+                 } else  {
173+                     this ._decodeFromInputStream (it, cacheKey, callback)
174+                 }
162175            }, {
163176                this .invokeErrorCallback(it, callback)
164177            })
165178        }
166179    }
167180
168-     fun  decodeFromInputStream (inputStream :  InputStream , cacheKey :  String , callback :  ParseCompletion ? , closeInputStream :  Boolean  = false) {
181+     fun  _decodeFromCacheKey (cacheKey :  String , callback :  ParseCompletion ? ) {
182+         val  svga =  SVGACache .buildCacheFile(cacheKey)
183+         try  {
184+             LogUtils .info(TAG , " binary change to entity" 
185+             FileInputStream (svga).use {
186+                 LogUtils .info(TAG , " binary change to entity success" 
187+                 this .invokeCompleteCallback(
188+                     SVGAVideoEntity (
189+                         MovieEntity .ADAPTER .decode(it),
190+                         SVGACache .buildCacheDir(cacheKey),
191+                         mFrameWidth,
192+                         mFrameHeight
193+                     ), callback
194+                 )
195+             }
196+         } catch  (e:  Exception ) {
197+             LogUtils .error(TAG , " binary change to entity fail" 
198+             SVGACache .buildCacheDir(cacheKey).delete()
199+             svga.delete()
200+             this .invokeErrorCallback(e, callback)
201+         }
202+     }
203+ 
204+     fun  _decodeFromInputStream (
205+         inputStream :  InputStream ,
206+         cacheKey :  String ,
207+         callback :  ParseCompletion ? 
208+     ) {
209+         threadPoolExecutor.execute {
210+             try  {
211+                 readAsBytes(inputStream)?.let  { bytes -> 
212+                     LogUtils .info(TAG , " decode from input stream, inflate start" 
213+                     inflate(bytes)?.let  { inflateBytes -> 
214+                         threadPoolExecutor.execute {
215+                             SVGACache .buildCacheFile(cacheKey).let  { cacheFile -> 
216+                                 cacheFile.takeIf  { ! it.exists() }?.createNewFile()
217+                                 FileOutputStream (cacheFile).write(inflateBytes)
218+                             }
219+                         }
220+                         val  videoItem =  SVGAVideoEntity (
221+                             MovieEntity .ADAPTER .decode(inflateBytes),
222+                             File (cacheKey),
223+                             mFrameWidth,
224+                             mFrameHeight
225+                         )
226+                         videoItem.prepare {
227+                             LogUtils .info(TAG , " decode from input stream, inflate end" 
228+                             this .invokeCompleteCallback(videoItem, callback)
229+                         }
230+                     } ? :  this .invokeErrorCallback(
231+                         Exception (" inflate(bytes) cause exception" 
232+                         callback
233+                     )
234+                 } ? :  this .invokeErrorCallback(
235+                     Exception (" readAsBytes(inputStream) cause exception" 
236+                     callback
237+                 )
238+             } catch  (e:  Exception ) {
239+                 this .invokeErrorCallback(e, callback)
240+             } finally  {
241+                 inputStream.close()
242+             }
243+         }
244+     }
245+ 
246+     fun  decodeFromInputStream (
247+         inputStream :  InputStream ,
248+         cacheKey :  String ,
249+         callback :  ParseCompletion ? ,
250+         closeInputStream :  Boolean  = false
251+     ) {
169252        if  (mContext ==  null ) {
170253            LogUtils .error(TAG , " 在配置 SVGAParser context 前, 无法解析 SVGA 文件。" 
171254            return 
@@ -176,9 +259,9 @@ class SVGAParser(context: Context?) {
176259                readAsBytes(inputStream)?.let  { bytes -> 
177260                    if  (bytes.size >  4  &&  bytes[0 ].toInt() ==  80  &&  bytes[1 ].toInt() ==  75  &&  bytes[2 ].toInt() ==  3  &&  bytes[3 ].toInt() ==  4 ) {
178261                        LogUtils .info(TAG , " decode from zip file" 
179-                         if  (! buildCacheDir(cacheKey).exists() ||  isUnzipping) {
262+                         if  (! SVGACache . buildCacheDir(cacheKey).exists() ||  isUnzipping) {
180263                            synchronized(fileLock) {
181-                                 if  (! buildCacheDir(cacheKey).exists()) {
264+                                 if  (! SVGACache . buildCacheDir(cacheKey).exists()) {
182265                                    isUnzipping =  true 
183266                                    LogUtils .info(TAG , " no cached, prepare to unzip" 
184267                                    ByteArrayInputStream (bytes).use {
@@ -193,14 +276,26 @@ class SVGAParser(context: Context?) {
193276                    } else  {
194277                        LogUtils .info(TAG , " decode from input stream, inflate start" 
195278                        inflate(bytes)?.let  {
196-                             val  videoItem =  SVGAVideoEntity (MovieEntity .ADAPTER .decode(it), File (cacheKey), mFrameWidth, mFrameHeight)
279+                             val  videoItem =  SVGAVideoEntity (
280+                                 MovieEntity .ADAPTER .decode(it),
281+                                 File (cacheKey),
282+                                 mFrameWidth,
283+                                 mFrameHeight
284+                             )
197285                            videoItem.prepare {
198286                                LogUtils .info(TAG , " decode from input stream, inflate end" 
199287                                this .invokeCompleteCallback(videoItem, callback)
200288                            }
201-                         } ? :  LogUtils .error(TAG , " inflate(bytes) cause exception" 
289+ 
290+                         } ? :  this .invokeErrorCallback(
291+                             Exception (" inflate(bytes) cause exception" 
292+                             callback
293+                         )
202294                    }
203-                 } ? :  LogUtils .error(TAG , " readAsBytes(inputStream) cause exception" 
295+                 } ? :  this .invokeErrorCallback(
296+                     Exception (" readAsBytes(inputStream) cause exception" 
297+                     callback
298+                 )
204299            } catch  (e:  java.lang.Exception ) {
205300                this .invokeErrorCallback(e, callback)
206301            } finally  {
@@ -251,10 +346,6 @@ class SVGAParser(context: Context?) {
251346        }
252347    }
253348
254-     private  fun  isCached (cacheKey :  String ): Boolean  {
255-         return  buildCacheDir(cacheKey).exists()
256-     }
257- 
258349    private  fun  decodeFromCacheKey (cacheKey :  String , callback :  ParseCompletion ? ) {
259350        LogUtils .info(TAG , " ================ decode from cache ================" 
260351        LogUtils .debug(TAG , " decodeFromCacheKey called with cacheKey : $cacheKey " 
@@ -311,30 +402,14 @@ class SVGAParser(context: Context?) {
311402        }
312403    }
313404
314-     private  fun  buildCacheKey (str :  String ): String  {
315-         val  messageDigest =  MessageDigest .getInstance(" MD5" 
316-         messageDigest.update(str.toByteArray(charset(" UTF-8" 
317-         val  digest =  messageDigest.digest()
318-         var  sb =  " " 
319-         for  (b in  digest) {
320-             sb + =  String .format(" %02x" 
321-         }
322-         return  sb
323-     }
324- 
325-     private  fun  buildCacheKey (url :  URL ): String  =  buildCacheKey(url.toString())
326- 
327-     private  fun  buildCacheDir (cacheKey :  String ): File  =  File (mContext?.cacheDir?.absolutePath +  " /" +  cacheKey +  " /" 
328- 
329405    private  fun  readAsBytes (inputStream :  InputStream ): ByteArray?  {
330406        ByteArrayOutputStream ().use { byteArrayOutputStream -> 
331407            val  byteArray =  ByteArray (2048 )
332408            while  (true ) {
333409                val  count =  inputStream.read(byteArray, 0 , 2048 )
334410                if  (count <=  0 ) {
335411                    break 
336-                 }
337-                 else  {
412+                 } else  {
338413                    byteArrayOutputStream.write(byteArray, 0 , count)
339414                }
340415            }
@@ -362,7 +437,7 @@ class SVGAParser(context: Context?) {
362437
363438    private  fun  unzip (inputStream :  InputStream , cacheKey :  String ) {
364439        LogUtils .info(TAG , " ================ unzip prepare ================" 
365-         val  cacheDir =  this .buildCacheDir(cacheKey)
440+         val  cacheDir =  SVGACache .buildCacheDir(cacheKey)
366441        cacheDir.mkdirs()
367442        try  {
368443            BufferedInputStream (inputStream).use {
0 commit comments