| 
				
			 | 
			
			
				@@ -33,6 +33,7 @@ public class RNFetchBlobFileResp extends ResponseBody { 
			 | 
		
	
		
			
			| 
				33
			 | 
			
				33
			 | 
			
			
				     long bytesDownloaded = 0; 
			 | 
		
	
		
			
			| 
				34
			 | 
			
				34
			 | 
			
			
				     ReactApplicationContext rctContext; 
			 | 
		
	
		
			
			| 
				35
			 | 
			
				35
			 | 
			
			
				     FileOutputStream ofStream; 
			 | 
		
	
		
			
			| 
				
			 | 
			
				36
			 | 
			
			
				+    boolean isEndMarkerReceived; 
			 | 
		
	
		
			
			| 
				36
			 | 
			
				37
			 | 
			
			
				  
			 | 
		
	
		
			
			| 
				37
			 | 
			
				38
			 | 
			
			
				     public RNFetchBlobFileResp(ReactApplicationContext ctx, String taskId, ResponseBody body, String path, boolean overwrite) throws IOException { 
			 | 
		
	
		
			
			| 
				38
			 | 
			
				39
			 | 
			
			
				         super(); 
			 | 
		
	
	
		
			
			| 
				
			 | 
			
			
				@@ -41,6 +42,7 @@ public class RNFetchBlobFileResp extends ResponseBody { 
			 | 
		
	
		
			
			| 
				41
			 | 
			
				42
			 | 
			
			
				         this.originalBody = body; 
			 | 
		
	
		
			
			| 
				42
			 | 
			
				43
			 | 
			
			
				         assert path != null; 
			 | 
		
	
		
			
			| 
				43
			 | 
			
				44
			 | 
			
			
				         this.mPath = path; 
			 | 
		
	
		
			
			| 
				
			 | 
			
				45
			 | 
			
			
				+        this.isEndMarkerReceived = false; 
			 | 
		
	
		
			
			| 
				44
			 | 
			
				46
			 | 
			
			
				         if (path != null) { 
			 | 
		
	
		
			
			| 
				45
			 | 
			
				47
			 | 
			
			
				             boolean appendToExistingFile = !overwrite; 
			 | 
		
	
		
			
			| 
				46
			 | 
			
				48
			 | 
			
			
				             path = path.replace("?append=true", ""); 
			 | 
		
	
	
		
			
			| 
				
			 | 
			
			
				@@ -68,6 +70,11 @@ public class RNFetchBlobFileResp extends ResponseBody { 
			 | 
		
	
		
			
			| 
				68
			 | 
			
				70
			 | 
			
			
				         return originalBody.contentLength(); 
			 | 
		
	
		
			
			| 
				69
			 | 
			
				71
			 | 
			
			
				     } 
			 | 
		
	
		
			
			| 
				70
			 | 
			
				72
			 | 
			
			
				  
			 | 
		
	
		
			
			| 
				
			 | 
			
				73
			 | 
			
			
				+    public boolean isDownloadComplete() { 
			 | 
		
	
		
			
			| 
				
			 | 
			
				74
			 | 
			
			
				+        return (bytesDownloaded == contentLength()) // Case of non-chunked downloads 
			 | 
		
	
		
			
			| 
				
			 | 
			
				75
			 | 
			
			
				+                || (contentLength() == -1 && isEndMarkerReceived); // Case of chunked downloads 
			 | 
		
	
		
			
			| 
				
			 | 
			
				76
			 | 
			
			
				+    } 
			 | 
		
	
		
			
			| 
				
			 | 
			
				77
			 | 
			
			
				+ 
			 | 
		
	
		
			
			| 
				71
			 | 
			
				78
			 | 
			
			
				     @Override 
			 | 
		
	
		
			
			| 
				72
			 | 
			
				79
			 | 
			
			
				     public BufferedSource source() { 
			 | 
		
	
		
			
			| 
				73
			 | 
			
				80
			 | 
			
			
				         ProgressReportingSource countable = new ProgressReportingSource(); 
			 | 
		
	
	
		
			
			| 
				
			 | 
			
			
				@@ -83,22 +90,49 @@ public class RNFetchBlobFileResp extends ResponseBody { 
			 | 
		
	
		
			
			| 
				83
			 | 
			
				90
			 | 
			
			
				                 bytesDownloaded += read > 0 ? read : 0; 
			 | 
		
	
		
			
			| 
				84
			 | 
			
				91
			 | 
			
			
				                 if (read > 0) { 
			 | 
		
	
		
			
			| 
				85
			 | 
			
				92
			 | 
			
			
				                     ofStream.write(bytes, 0, (int) read); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				93
			 | 
			
			
				+                } else if (contentLength() == -1 && read == -1) { 
			 | 
		
	
		
			
			| 
				
			 | 
			
				94
			 | 
			
			
				+                    // End marker has been received for chunked download 
			 | 
		
	
		
			
			| 
				
			 | 
			
				95
			 | 
			
			
				+                    isEndMarkerReceived = true; 
			 | 
		
	
		
			
			| 
				86
			 | 
			
				96
			 | 
			
			
				                 } 
			 | 
		
	
		
			
			| 
				87
			 | 
			
				97
			 | 
			
			
				                 RNFetchBlobProgressConfig reportConfig = RNFetchBlobReq.getReportProgress(mTaskId); 
			 | 
		
	
		
			
			| 
				88
			 | 
			
				
			 | 
			
			
				-                if (reportConfig != null && contentLength() != 0 &&reportConfig.shouldReport(bytesDownloaded / contentLength())) { 
			 | 
		
	
		
			
			| 
				89
			 | 
			
				
			 | 
			
			
				-                    WritableMap args = Arguments.createMap(); 
			 | 
		
	
		
			
			| 
				90
			 | 
			
				
			 | 
			
			
				-                    args.putString("taskId", mTaskId); 
			 | 
		
	
		
			
			| 
				91
			 | 
			
				
			 | 
			
			
				-                    args.putString("written", String.valueOf(bytesDownloaded)); 
			 | 
		
	
		
			
			| 
				92
			 | 
			
				
			 | 
			
			
				-                    args.putString("total", String.valueOf(contentLength())); 
			 | 
		
	
		
			
			| 
				93
			 | 
			
				
			 | 
			
			
				-                    rctContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) 
			 | 
		
	
		
			
			| 
				94
			 | 
			
				
			 | 
			
			
				-                            .emit(RNFetchBlobConst.EVENT_PROGRESS, args); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				98
			 | 
			
			
				+ 
			 | 
		
	
		
			
			| 
				
			 | 
			
				99
			 | 
			
			
				+                if (contentLength() != 0) { 
			 | 
		
	
		
			
			| 
				
			 | 
			
				100
			 | 
			
			
				+ 
			 | 
		
	
		
			
			| 
				
			 | 
			
				101
			 | 
			
			
				+                    // For non-chunked download, progress is received / total 
			 | 
		
	
		
			
			| 
				
			 | 
			
				102
			 | 
			
			
				+                    // For chunked download, progress can be either 0 (started) or 1 (ended) 
			 | 
		
	
		
			
			| 
				
			 | 
			
				103
			 | 
			
			
				+                    float progress = (contentLength() != -1) ? bytesDownloaded / contentLength() : ( ( isEndMarkerReceived ) ? 1 : 0 ); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				104
			 | 
			
			
				+ 
			 | 
		
	
		
			
			| 
				
			 | 
			
				105
			 | 
			
			
				+                    if (reportConfig != null && reportConfig.shouldReport(progress /* progress */)) { 
			 | 
		
	
		
			
			| 
				
			 | 
			
				106
			 | 
			
			
				+                        if (contentLength() != -1) { 
			 | 
		
	
		
			
			| 
				
			 | 
			
				107
			 | 
			
			
				+                            // For non-chunked downloads 
			 | 
		
	
		
			
			| 
				
			 | 
			
				108
			 | 
			
			
				+                            reportProgress(mTaskId, bytesDownloaded, contentLength()); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				109
			 | 
			
			
				+                        } else { 
			 | 
		
	
		
			
			| 
				
			 | 
			
				110
			 | 
			
			
				+                            // For chunked downloads 
			 | 
		
	
		
			
			| 
				
			 | 
			
				111
			 | 
			
			
				+                            if (!isEndMarkerReceived) { 
			 | 
		
	
		
			
			| 
				
			 | 
			
				112
			 | 
			
			
				+                                reportProgress(mTaskId, 0, contentLength()); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				113
			 | 
			
			
				+                            } else{ 
			 | 
		
	
		
			
			| 
				
			 | 
			
				114
			 | 
			
			
				+                                reportProgress(mTaskId, bytesDownloaded, bytesDownloaded); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				115
			 | 
			
			
				+                            } 
			 | 
		
	
		
			
			| 
				
			 | 
			
				116
			 | 
			
			
				+                        } 
			 | 
		
	
		
			
			| 
				
			 | 
			
				117
			 | 
			
			
				+                    } 
			 | 
		
	
		
			
			| 
				
			 | 
			
				118
			 | 
			
			
				+ 
			 | 
		
	
		
			
			| 
				95
			 | 
			
				119
			 | 
			
			
				                 } 
			 | 
		
	
		
			
			| 
				
			 | 
			
				120
			 | 
			
			
				+ 
			 | 
		
	
		
			
			| 
				96
			 | 
			
				121
			 | 
			
			
				                 return read; 
			 | 
		
	
		
			
			| 
				97
			 | 
			
				122
			 | 
			
			
				             } catch(Exception ex) { 
			 | 
		
	
		
			
			| 
				98
			 | 
			
				123
			 | 
			
			
				                 return -1; 
			 | 
		
	
		
			
			| 
				99
			 | 
			
				124
			 | 
			
			
				             } 
			 | 
		
	
		
			
			| 
				100
			 | 
			
				125
			 | 
			
			
				         } 
			 | 
		
	
		
			
			| 
				101
			 | 
			
				126
			 | 
			
			
				  
			 | 
		
	
		
			
			| 
				
			 | 
			
				127
			 | 
			
			
				+        private void reportProgress(String taskId, long bytesDownloaded, long contentLength) { 
			 | 
		
	
		
			
			| 
				
			 | 
			
				128
			 | 
			
			
				+            WritableMap args = Arguments.createMap(); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				129
			 | 
			
			
				+            args.putString("taskId", taskId); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				130
			 | 
			
			
				+            args.putString("written", String.valueOf(bytesDownloaded)); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				131
			 | 
			
			
				+            args.putString("total", String.valueOf(contentLength)); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				132
			 | 
			
			
				+            rctContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) 
			 | 
		
	
		
			
			| 
				
			 | 
			
				133
			 | 
			
			
				+                    .emit(RNFetchBlobConst.EVENT_PROGRESS, args); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				134
			 | 
			
			
				+        } 
			 | 
		
	
		
			
			| 
				
			 | 
			
				135
			 | 
			
			
				+ 
			 | 
		
	
		
			
			| 
				102
			 | 
			
				136
			 | 
			
			
				         @Override 
			 | 
		
	
		
			
			| 
				103
			 | 
			
				137
			 | 
			
			
				         public Timeout timeout() { 
			 | 
		
	
		
			
			| 
				104
			 | 
			
				138
			 | 
			
			
				             return null; 
			 |