|  | @@ -69,7 +69,6 @@ NSMutableDictionary *fileStreams = nil;
 | 
	
		
			
			| 69 | 69 |      return [NSSearchPathForDirectoriesInDomains(NSPicturesDirectory, NSUserDomainMask, YES) firstObject];
 | 
	
		
			
			| 70 | 70 |  }
 | 
	
		
			
			| 71 | 71 |  
 | 
	
		
			
			| 72 |  | -
 | 
	
		
			
			| 73 | 72 |  + (NSString *) getTempPath {
 | 
	
		
			
			| 74 | 73 |      
 | 
	
		
			
			| 75 | 74 |      return [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject] stringByAppendingString:@"/RNFetchBlob_tmp"];
 | 
	
	
		
			
			|  | @@ -85,6 +84,103 @@ NSMutableDictionary *fileStreams = nil;
 | 
	
		
			
			| 85 | 84 |      return tempPath;
 | 
	
		
			
			| 86 | 85 |  }
 | 
	
		
			
			| 87 | 86 |  
 | 
	
		
			
			|  | 87 | ++ (void) writeFile:(NSString *)path encoding:(NSString *)encoding data:(NSString *)data resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject {
 | 
	
		
			
			|  | 88 | +    @try {
 | 
	
		
			
			|  | 89 | +        NSFileManager * fm = [NSFileManager defaultManager];
 | 
	
		
			
			|  | 90 | +        NSError * err = nil;
 | 
	
		
			
			|  | 91 | +        NSString * folder = [path stringByDeletingLastPathComponent];
 | 
	
		
			
			|  | 92 | +        if(![fm fileExistsAtPath:folder]) {
 | 
	
		
			
			|  | 93 | +            [fm createDirectoryAtPath:folder withIntermediateDirectories:YES attributes:NULL error:&err];
 | 
	
		
			
			|  | 94 | +        }
 | 
	
		
			
			|  | 95 | +        if(![fm fileExistsAtPath:path]) {
 | 
	
		
			
			|  | 96 | +            if([[encoding lowercaseString] isEqualToString:@"base64"]){
 | 
	
		
			
			|  | 97 | +                NSData * byteData = [[NSData alloc] initWithBase64EncodedString:data options:0];
 | 
	
		
			
			|  | 98 | +                [fm createFileAtPath:path contents:byteData attributes:NULL];
 | 
	
		
			
			|  | 99 | +            }
 | 
	
		
			
			|  | 100 | +            else
 | 
	
		
			
			|  | 101 | +                [fm createFileAtPath:path contents:[data dataUsingEncoding:NSUTF8StringEncoding] attributes:NULL];
 | 
	
		
			
			|  | 102 | +        }
 | 
	
		
			
			|  | 103 | +        else {
 | 
	
		
			
			|  | 104 | +            NSFileHandle *fileHandle = [NSFileHandle fileHandleForWritingAtPath:path];
 | 
	
		
			
			|  | 105 | +            [fileHandle seekToEndOfFile];
 | 
	
		
			
			|  | 106 | +            if([[encoding lowercaseString] isEqualToString:@"base64"]) {
 | 
	
		
			
			|  | 107 | +                NSData * byteData = [[NSData alloc] initWithBase64EncodedString:data options:0];
 | 
	
		
			
			|  | 108 | +                [fileHandle writeData:byteData];
 | 
	
		
			
			|  | 109 | +            }
 | 
	
		
			
			|  | 110 | +            else
 | 
	
		
			
			|  | 111 | +                [fileHandle writeData:[data dataUsingEncoding:NSUTF8StringEncoding]];
 | 
	
		
			
			|  | 112 | +            [fileHandle closeFile];
 | 
	
		
			
			|  | 113 | +        }
 | 
	
		
			
			|  | 114 | +        fm = nil;
 | 
	
		
			
			|  | 115 | +        resolve([NSNull null]);
 | 
	
		
			
			|  | 116 | +    }
 | 
	
		
			
			|  | 117 | +    @catch (NSException * e)
 | 
	
		
			
			|  | 118 | +    {
 | 
	
		
			
			|  | 119 | +        reject(@"RNFetchBlob writeFile Error", @"Error", [e description]);
 | 
	
		
			
			|  | 120 | +    }
 | 
	
		
			
			|  | 121 | +}
 | 
	
		
			
			|  | 122 | +
 | 
	
		
			
			|  | 123 | ++ (void) writeFileArray:(NSString *)path data:(NSArray *)data resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject {
 | 
	
		
			
			|  | 124 | +    @try {
 | 
	
		
			
			|  | 125 | +        NSFileManager * fm = [NSFileManager defaultManager];
 | 
	
		
			
			|  | 126 | +        NSMutableData * fileContent = [NSMutableData alloc];
 | 
	
		
			
			|  | 127 | +        // prevent stack overflow, alloc on heap
 | 
	
		
			
			|  | 128 | +        char * bytes = (char*) malloc([data count]);
 | 
	
		
			
			|  | 129 | +        for(int i = 0; i < data.count; i++) {
 | 
	
		
			
			|  | 130 | +            bytes[i] = [[data objectAtIndex:i] charValue];
 | 
	
		
			
			|  | 131 | +        }
 | 
	
		
			
			|  | 132 | +        // if append == NO
 | 
	
		
			
			|  | 133 | +//        BOOL success = [fm createFileAtPath:path contents:fileContent attributes:NULL];
 | 
	
		
			
			|  | 134 | +        [fileContent appendBytes:bytes length:data.count];
 | 
	
		
			
			|  | 135 | +        NSFileHandle *fileHandle = [NSFileHandle fileHandleForWritingAtPath:path];
 | 
	
		
			
			|  | 136 | +        [fileHandle seekToEndOfFile];
 | 
	
		
			
			|  | 137 | +        [fileHandle writeData:fileContent];
 | 
	
		
			
			|  | 138 | +        [fileHandle closeFile];
 | 
	
		
			
			|  | 139 | +        free(bytes);
 | 
	
		
			
			|  | 140 | +        fm = nil;
 | 
	
		
			
			|  | 141 | +        resolve([NSNull null]);
 | 
	
		
			
			|  | 142 | +    }
 | 
	
		
			
			|  | 143 | +    @catch (NSException * e)
 | 
	
		
			
			|  | 144 | +    {
 | 
	
		
			
			|  | 145 | +        reject(@"RNFetchBlob writeFile Error", @"Error", [e description]);
 | 
	
		
			
			|  | 146 | +    }
 | 
	
		
			
			|  | 147 | +}
 | 
	
		
			
			|  | 148 | +
 | 
	
		
			
			|  | 149 | ++ (void) readFile:(NSString *)path encoding:(NSString *)encoding resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject {
 | 
	
		
			
			|  | 150 | +    @try
 | 
	
		
			
			|  | 151 | +    {
 | 
	
		
			
			|  | 152 | +        NSFileManager * fm = [NSFileManager defaultManager];
 | 
	
		
			
			|  | 153 | +        NSError *err = nil;
 | 
	
		
			
			|  | 154 | +        BOOL exists = [fm fileExistsAtPath:path];
 | 
	
		
			
			|  | 155 | +        if(!exists) {
 | 
	
		
			
			|  | 156 | +            @throw @"RNFetchBlobFS readFile error", @"file not exists", path;
 | 
	
		
			
			|  | 157 | +            return;
 | 
	
		
			
			|  | 158 | +        }
 | 
	
		
			
			|  | 159 | +        if([[encoding lowercaseString] isEqualToString:@"utf8"]) {
 | 
	
		
			
			|  | 160 | +            NSString * utf8Result = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&err];
 | 
	
		
			
			|  | 161 | +            resolve(utf8Result);
 | 
	
		
			
			|  | 162 | +        }
 | 
	
		
			
			|  | 163 | +        else if ([[encoding lowercaseString] isEqualToString:@"base64"]) {
 | 
	
		
			
			|  | 164 | +            NSData * fileData = [NSData dataWithContentsOfFile:path];
 | 
	
		
			
			|  | 165 | +            resolve([fileData base64EncodedStringWithOptions:0]);
 | 
	
		
			
			|  | 166 | +        }
 | 
	
		
			
			|  | 167 | +        else if ([[encoding lowercaseString] isEqualToString:@"ascii"]) {
 | 
	
		
			
			|  | 168 | +            NSData * resultData = [NSData dataWithContentsOfFile:path];
 | 
	
		
			
			|  | 169 | +            NSMutableArray * resultArray = [NSMutableArray array];
 | 
	
		
			
			|  | 170 | +            char * bytes = [resultData bytes];
 | 
	
		
			
			|  | 171 | +            for(int i=0;i<[resultData length];i++) {
 | 
	
		
			
			|  | 172 | +                [resultArray addObject:[NSNumber numberWithChar:bytes[i]]];
 | 
	
		
			
			|  | 173 | +            }
 | 
	
		
			
			|  | 174 | +            resolve(resultArray);
 | 
	
		
			
			|  | 175 | +        }
 | 
	
		
			
			|  | 176 | +        
 | 
	
		
			
			|  | 177 | +    }
 | 
	
		
			
			|  | 178 | +    @catch(NSException * e)
 | 
	
		
			
			|  | 179 | +    {
 | 
	
		
			
			|  | 180 | +        reject(@"RNFetchBlobFS readFile error", @"error", [e description]);
 | 
	
		
			
			|  | 181 | +    }
 | 
	
		
			
			|  | 182 | +}
 | 
	
		
			
			|  | 183 | +
 | 
	
		
			
			| 88 | 184 |  + (BOOL) mkdir:(NSString *) path {
 | 
	
		
			
			| 89 | 185 |      BOOL isDir;
 | 
	
		
			
			| 90 | 186 |      NSError * err = nil;
 | 
	
	
		
			
			|  | @@ -278,31 +374,28 @@ void runOnMainQueueWithoutDeadlocking(void (^block)(void))
 | 
	
		
			
			| 278 | 374 |                  // when encoding is ASCII, send byte array data
 | 
	
		
			
			| 279 | 375 |                  else if ( [[self.encoding lowercaseString] isEqualToString:@"ascii"] ) {
 | 
	
		
			
			| 280 | 376 |                      // RCTBridge only emits string data, so we have to create JSON byte array string
 | 
	
		
			
			| 281 |  | -                    NSString * asciiStr = @"[";
 | 
	
		
			
			|  | 377 | +                    NSMutableArray * asciiArray = [NSMutableArray array];
 | 
	
		
			
			|  | 378 | +                    unsigned char *bytePtr;
 | 
	
		
			
			| 282 | 379 |                      if (chunkData.length > 0)
 | 
	
		
			
			| 283 | 380 |                      {
 | 
	
		
			
			| 284 |  | -                        unsigned char *bytePtr = (unsigned char *)[chunkData bytes];
 | 
	
		
			
			|  | 381 | +                        bytePtr = (unsigned char *)[chunkData bytes];
 | 
	
		
			
			| 285 | 382 |                          NSInteger byteLen = chunkData.length/sizeof(uint8_t);
 | 
	
		
			
			| 286 | 383 |                          for (int i = 0; i < byteLen; i++)
 | 
	
		
			
			| 287 | 384 |                          {
 | 
	
		
			
			| 288 |  | -                            NSInteger val = bytePtr[i];
 | 
	
		
			
			| 289 |  | -                            if(i+1 < byteLen)
 | 
	
		
			
			| 290 |  | -                                asciiStr = [asciiStr stringByAppendingFormat:@"%d,", val];
 | 
	
		
			
			| 291 |  | -                            else
 | 
	
		
			
			| 292 |  | -                                asciiStr = [asciiStr stringByAppendingFormat:@"%d", val];
 | 
	
		
			
			|  | 385 | +                            [asciiArray addObject:[NSNumber numberWithChar:bytePtr[i]]];
 | 
	
		
			
			| 293 | 386 |                          }
 | 
	
		
			
			| 294 |  | -                        free(bytePtr);
 | 
	
		
			
			| 295 | 387 |                      }
 | 
	
		
			
			| 296 |  | -                    asciiStr = [asciiStr stringByAppendingString:@"]"];
 | 
	
		
			
			|  | 388 | +                    
 | 
	
		
			
			| 297 | 389 |                      [self.bridge.eventDispatcher
 | 
	
		
			
			| 298 | 390 |                       sendDeviceEventWithName:streamEventCode
 | 
	
		
			
			| 299 | 391 |                       body: @{
 | 
	
		
			
			| 300 | 392 |                               @"event": FS_EVENT_DATA,
 | 
	
		
			
			| 301 |  | -                             @"detail": asciiStr
 | 
	
		
			
			|  | 393 | +                             @"detail": asciiArray
 | 
	
		
			
			| 302 | 394 |                              }
 | 
	
		
			
			| 303 | 395 |                       ];
 | 
	
		
			
			| 304 | 396 |                      free(buf);
 | 
	
		
			
			| 305 |  | -                    asciiStr = nil;
 | 
	
		
			
			|  | 397 | +                    bytePtr = nil;
 | 
	
		
			
			|  | 398 | +                    asciiArray = nil;
 | 
	
		
			
			| 306 | 399 |                      buf = nil;
 | 
	
		
			
			| 307 | 400 |                      chunkData = nil;
 | 
	
		
			
			| 308 | 401 |                      return;
 |