GDTCOREvent.m 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. /*
  2. * Copyright 2018 Google
  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 "GDTCORLibrary/Public/GDTCOREvent.h"
  17. #import <GoogleDataTransport/GDTCORAssert.h>
  18. #import <GoogleDataTransport/GDTCORClock.h>
  19. #import <GoogleDataTransport/GDTCORConsoleLogger.h>
  20. #import "GDTCORLibrary/Private/GDTCORDataFuture.h"
  21. #import "GDTCORLibrary/Private/GDTCOREvent_Private.h"
  22. @implementation GDTCOREvent
  23. - (nullable instancetype)initWithMappingID:(NSString *)mappingID target:(NSInteger)target {
  24. GDTCORAssert(mappingID.length > 0, @"Please give a valid mapping ID");
  25. GDTCORAssert(target > 0, @"A target cannot be negative or 0");
  26. if (mappingID == nil || mappingID.length == 0 || target <= 0) {
  27. return nil;
  28. }
  29. self = [super init];
  30. if (self) {
  31. _mappingID = mappingID;
  32. _target = target;
  33. _qosTier = GDTCOREventQosDefault;
  34. }
  35. GDTCORLogDebug("Event %@ created. mappingID: %@ target:%ld qos:%ld", self, _mappingID,
  36. (long)_target, (long)_qosTier);
  37. return self;
  38. }
  39. - (instancetype)copy {
  40. GDTCOREvent *copy = [[GDTCOREvent alloc] initWithMappingID:_mappingID target:_target];
  41. copy.dataObject = _dataObject;
  42. copy.qosTier = _qosTier;
  43. copy.clockSnapshot = _clockSnapshot;
  44. copy.customPrioritizationParams = _customPrioritizationParams;
  45. copy->_fileURL = _fileURL;
  46. GDTCORLogDebug("Copying event %@ to event %@", self, copy);
  47. return copy;
  48. }
  49. - (NSUInteger)hash {
  50. // This loses some precision, but it's probably fine.
  51. NSUInteger mappingIDHash = [_mappingID hash];
  52. NSUInteger timeHash = [_clockSnapshot hash];
  53. NSInteger dataObjectHash = [_dataObject hash];
  54. NSUInteger fileURL = [_fileURL hash];
  55. return mappingIDHash ^ _target ^ _qosTier ^ timeHash ^ dataObjectHash ^ fileURL;
  56. }
  57. - (BOOL)isEqual:(id)object {
  58. return [self hash] == [object hash];
  59. }
  60. - (void)setDataObject:(id<GDTCOREventDataObject>)dataObject {
  61. // If you're looking here because of a performance issue in -transportBytes slowing the assignment
  62. // of -dataObject, one way to address this is to add a queue to this class,
  63. // dispatch_(barrier_ if concurrent)async here, and implement the getter with a dispatch_sync.
  64. if (dataObject != _dataObject) {
  65. _dataObject = dataObject;
  66. }
  67. }
  68. - (BOOL)writeToURL:(NSURL *)fileURL error:(NSError **)error {
  69. NSData *dataTransportBytes = [_dataObject transportBytes];
  70. if (dataTransportBytes == nil) {
  71. _fileURL = nil;
  72. _dataObject = nil;
  73. return NO;
  74. }
  75. BOOL writingSuccess = [dataTransportBytes writeToURL:fileURL
  76. options:NSDataWritingAtomic
  77. error:error];
  78. if (!writingSuccess) {
  79. GDTCORLogError(GDTCORMCEFileWriteError, @"An event file could not be written: %@", fileURL);
  80. _fileURL = nil;
  81. return NO;
  82. }
  83. _fileURL = fileURL;
  84. _dataObject = nil;
  85. return YES;
  86. }
  87. #pragma mark - NSSecureCoding and NSCoding Protocols
  88. /** NSCoding key for mappingID property. */
  89. static NSString *mappingIDKey = @"_mappingID";
  90. /** NSCoding key for target property. */
  91. static NSString *targetKey = @"_target";
  92. /** NSCoding key for qosTier property. */
  93. static NSString *qosTierKey = @"_qosTier";
  94. /** NSCoding key for clockSnapshot property. */
  95. static NSString *clockSnapshotKey = @"_clockSnapshot";
  96. /** NSCoding key for fileURL property. */
  97. static NSString *fileURLKey = @"_fileURL";
  98. /** NSCoding key for customPrioritizationParams property. */
  99. static NSString *customPrioritizationParams = @"_customPrioritizationParams";
  100. /** NSCoding key for backwards compatibility of GDTCORStoredEvent mappingID property.*/
  101. static NSString *kStoredEventMappingIDKey = @"GDTCORStoredEventMappingIDKey";
  102. /** NSCoding key for backwards compatibility of GDTCORStoredEvent target property.*/
  103. static NSString *kStoredEventTargetKey = @"GDTCORStoredEventTargetKey";
  104. /** NSCoding key for backwards compatibility of GDTCORStoredEvent qosTier property.*/
  105. static NSString *kStoredEventQosTierKey = @"GDTCORStoredEventQosTierKey";
  106. /** NSCoding key for backwards compatibility of GDTCORStoredEvent clockSnapshot property.*/
  107. static NSString *kStoredEventClockSnapshotKey = @"GDTCORStoredEventClockSnapshotKey";
  108. /** NSCoding key for backwards compatibility of GDTCORStoredEvent dataFuture property.*/
  109. static NSString *kStoredEventDataFutureKey = @"GDTCORStoredEventDataFutureKey";
  110. /** NSCoding key for backwards compatibility of GDTCORStoredEvent customPrioritizationParams
  111. * property.*/
  112. static NSString *kStoredEventCustomPrioritizationParamsKey =
  113. @"GDTCORStoredEventcustomPrioritizationParamsKey";
  114. + (BOOL)supportsSecureCoding {
  115. return YES;
  116. }
  117. - (id)initWithCoder:(NSCoder *)aDecoder {
  118. GDTCORDataFuture *dataFuture = [aDecoder decodeObjectOfClass:[GDTCORDataFuture class]
  119. forKey:kStoredEventDataFutureKey];
  120. if (dataFuture) {
  121. return [self initWithCoderForStoredEventBackwardCompatibility:aDecoder
  122. fileURL:dataFuture.fileURL];
  123. }
  124. NSString *mappingID = [aDecoder decodeObjectOfClass:[NSString class] forKey:mappingIDKey];
  125. NSInteger target = [aDecoder decodeIntegerForKey:targetKey];
  126. self = [self initWithMappingID:mappingID target:target];
  127. if (self) {
  128. _qosTier = [aDecoder decodeIntegerForKey:qosTierKey];
  129. _clockSnapshot = [aDecoder decodeObjectOfClass:[GDTCORClock class] forKey:clockSnapshotKey];
  130. _fileURL = [aDecoder decodeObjectOfClass:[NSURL class] forKey:fileURLKey];
  131. _customPrioritizationParams = [aDecoder decodeObjectOfClass:[NSDictionary class]
  132. forKey:customPrioritizationParams];
  133. }
  134. return self;
  135. }
  136. - (id)initWithCoderForStoredEventBackwardCompatibility:(NSCoder *)aDecoder
  137. fileURL:(NSURL *)fileURL {
  138. NSString *mappingID = [aDecoder decodeObjectOfClass:[NSString class]
  139. forKey:kStoredEventMappingIDKey];
  140. NSInteger target = [[aDecoder decodeObjectOfClass:[NSNumber class]
  141. forKey:kStoredEventTargetKey] integerValue];
  142. self = [self initWithMappingID:mappingID target:target];
  143. if (self) {
  144. _qosTier = [[aDecoder decodeObjectOfClass:[NSNumber class]
  145. forKey:kStoredEventQosTierKey] integerValue];
  146. _clockSnapshot = [aDecoder decodeObjectOfClass:[GDTCORClock class]
  147. forKey:kStoredEventClockSnapshotKey];
  148. _fileURL = fileURL;
  149. _customPrioritizationParams =
  150. [aDecoder decodeObjectOfClass:[NSDictionary class]
  151. forKey:kStoredEventCustomPrioritizationParamsKey];
  152. }
  153. return self;
  154. }
  155. - (void)encodeWithCoder:(NSCoder *)aCoder {
  156. [aCoder encodeObject:_mappingID forKey:mappingIDKey];
  157. [aCoder encodeInteger:_target forKey:targetKey];
  158. [aCoder encodeInteger:_qosTier forKey:qosTierKey];
  159. [aCoder encodeObject:_clockSnapshot forKey:clockSnapshotKey];
  160. [aCoder encodeObject:_fileURL forKey:fileURLKey];
  161. }
  162. @end