Guest User

Untitled

a guest
Aug 25th, 2016
57
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.42 KB | None | 0 0
  1. static NSData *PSPDFCalculateSHA256FromFileURL(NSURL *fileURL, CC_LONG dataLength, NSError **error) {
  2. NSCParameterAssert(fileURL);
  3.  
  4. dispatch_queue_t shaQueue = dispatch_queue_create("com.pspdfkit.sha256-queue", DISPATCH_QUEUE_SERIAL);
  5. __block dispatch_io_t readChannel;
  6.  
  7. void (^processIntError)(int intError) = ^(int intError) {
  8. if (intError != 0) {
  9. PSPDFLogWarning(@"Stream error: %d", intError);
  10. if (error) *error = [NSError errorWithDomain:@"SHA256Error" code:100 userInfo:@{NSLocalizedDescriptionKey: @"failed to open file for calculating SHA256."}];
  11. }
  12. dispatch_async(shaQueue, ^{
  13. dispatch_io_close(readChannel, DISPATCH_IO_STOP);
  14. });
  15. };
  16.  
  17. // Open the IO channel
  18. readChannel = dispatch_io_create_with_path(DISPATCH_IO_STREAM, fileURL.path.UTF8String, O_RDONLY, 0, shaQueue, processIntError);
  19. if (!readChannel) {
  20. if (error) *error = [NSError errorWithDomain:@"SHA256Error" code:100 userInfo:@{NSLocalizedDescriptionKey: @"failed to open file for calculating SHA256."}];
  21. return nil;
  22. }
  23.  
  24. // Prepare SHA hash
  25. __block CC_SHA256_CTX ctx;
  26. CC_SHA256_Init(&ctx);
  27.  
  28. // Start read and block until we are done.
  29. dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
  30. __block int lastIntError = 0;
  31. dispatch_io_set_high_water(readChannel, 512*1024);
  32. dispatch_io_read(readChannel, 0, SIZE_MAX, shaQueue, ^(bool done, dispatch_data_t data, int intError) {
  33. if (intError != 0) {
  34. lastIntError = intError;
  35. processIntError(intError);
  36. dispatch_semaphore_signal(semaphore);
  37. return;
  38. }
  39.  
  40. dispatch_data_apply(data, ^bool(dispatch_data_t region, size_t offset, const void *buffer, size_t size) {
  41. CC_SHA256_Update(&ctx, (const void *)buffer, (CC_LONG)size);
  42. return true;
  43. });
  44.  
  45. if (done) {
  46. dispatch_semaphore_signal(semaphore);
  47. }
  48. });
  49.  
  50. // Wait for the signal, then wake up.
  51. dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
  52. dispatch_io_close(readChannel, DISPATCH_IO_STOP);
  53.  
  54. // Finalize SHA256 calculation unless there's an error.
  55. if (lastIntError == 0) {
  56. unsigned char sha256[CC_SHA256_DIGEST_LENGTH];
  57. CC_SHA256_Final(sha256, &ctx);
  58. NSData *shaData = [NSData dataWithBytes:sha256 length:CC_SHA256_DIGEST_LENGTH];
  59. return shaData;
  60. }
  61. return nil;
  62. }
Add Comment
Please, Sign In to add comment