GDTCORDirectorySizeTracker.m 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. /*
  2. * Copyright 2020 Google LLC
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #import "GoogleDataTransport/GDTCORLibrary/Internal/GDTCORDirectorySizeTracker.h"
  17. @interface GDTCORDirectorySizeTracker ()
  18. /** The observed directory path. */
  19. @property(nonatomic, readonly) NSString *directoryPath;
  20. /** The cached content size of the observed directory. */
  21. @property(nonatomic, nullable) NSNumber *cachedSizeBytes;
  22. @end
  23. @implementation GDTCORDirectorySizeTracker
  24. - (instancetype)initWithDirectoryPath:(NSString *)path {
  25. self = [super init];
  26. if (self) {
  27. _directoryPath = path;
  28. }
  29. return self;
  30. }
  31. - (GDTCORStorageSizeBytes)directoryContentSize {
  32. if (self.cachedSizeBytes == nil) {
  33. self.cachedSizeBytes = @([self calculateDirectoryContentSize]);
  34. }
  35. return self.cachedSizeBytes.unsignedLongLongValue;
  36. }
  37. - (void)fileWasAddedAtPath:(NSString *)path withSize:(GDTCORStorageSizeBytes)fileSize {
  38. if (![path hasPrefix:self.directoryPath]) {
  39. // Ignore because the file is not inside the directory.
  40. return;
  41. }
  42. self.cachedSizeBytes = @([self directoryContentSize] + fileSize);
  43. }
  44. - (void)fileWasRemovedAtPath:(NSString *)path withSize:(GDTCORStorageSizeBytes)fileSize {
  45. if (![path hasPrefix:self.directoryPath]) {
  46. // Ignore because the file is not inside the directory.
  47. return;
  48. }
  49. self.cachedSizeBytes = @([self directoryContentSize] - fileSize);
  50. }
  51. - (void)resetCachedSize {
  52. self.cachedSizeBytes = nil;
  53. }
  54. - (GDTCORStorageSizeBytes)calculateDirectoryContentSize {
  55. NSArray *prefetchedProperties = @[ NSURLIsRegularFileKey, NSURLFileSizeKey ];
  56. uint64_t totalBytes = 0;
  57. NSURL *directoryURL = [NSURL fileURLWithPath:self.directoryPath];
  58. NSDirectoryEnumerator *enumerator = [[NSFileManager defaultManager]
  59. enumeratorAtURL:directoryURL
  60. includingPropertiesForKeys:prefetchedProperties
  61. options:NSDirectoryEnumerationSkipsHiddenFiles
  62. errorHandler:^BOOL(NSURL *_Nonnull url, NSError *_Nonnull error) {
  63. return YES;
  64. }];
  65. for (NSURL *fileURL in enumerator) {
  66. @autoreleasepool {
  67. NSNumber *isRegularFile;
  68. [fileURL getResourceValue:&isRegularFile forKey:NSURLIsRegularFileKey error:nil];
  69. if (isRegularFile.boolValue) {
  70. totalBytes += [self fileSizeAtURL:fileURL];
  71. }
  72. }
  73. }
  74. return totalBytes;
  75. }
  76. - (GDTCORStorageSizeBytes)fileSizeAtURL:(NSURL *)fileURL {
  77. NSNumber *fileSize;
  78. [fileURL getResourceValue:&fileSize forKey:NSURLFileSizeKey error:nil];
  79. return fileSize.unsignedLongLongValue;
  80. }
  81. @end