CKKSRecordHolder.m [plain text]
/*
* Copyright (c) 2017 Apple Inc. All Rights Reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
#if OCTAGON
#include <AssertMacros.h>
#import <Foundation/Foundation.h>
#import "CKKSItem.h"
#import "CKKSSIV.h"
#include <utilities/SecDb.h>
#include <securityd/SecDbItem.h>
#include <securityd/SecItemSchema.h>
#import <CloudKit/CloudKit.h>
@implementation CKKSCKRecordHolder
- (instancetype) initWithCKRecord: (CKRecord*) record {
if(self = [super init]) {
self.zoneID = record.recordID.zoneID;
[self setFromCKRecord:record];
}
return self;
}
- (instancetype)initWithCKRecordType: (NSString*) recordType encodedCKRecord: (NSData*) encodedCKRecord zoneID:(CKRecordZoneID*)zoneID {
if(self = [super init]) {
_zoneID = zoneID;
_ckRecordType = recordType;
_encodedCKRecord = encodedCKRecord;
if(self.encodedCKRecord && ![self.storedCKRecord.recordID.zoneID isEqual: self.zoneID]) {
secerror("ckks: mismatching zone ids in a single record: }
}
return self;
}
- (CKRecord*) storedCKRecord {
if(!_encodedCKRecord) {
return nil;
}
NSKeyedUnarchiver *coder = [[NSKeyedUnarchiver alloc] initForReadingWithData:_encodedCKRecord];
coder.requiresSecureCoding = YES;
CKRecord* ckRecord = [[CKRecord alloc] initWithCoder:coder];
[coder finishDecoding];
return ckRecord;
}
- (void) setStoredCKRecord: (CKRecord*) ckRecord {
if(!ckRecord) {
_encodedCKRecord = nil;
return;
}
self.zoneID = ckRecord.recordID.zoneID;
self.ckRecordType = ckRecord.recordType;
NSMutableData* data = [NSMutableData data];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
[ckRecord encodeWithCoder:archiver];
[archiver finishEncoding];
_encodedCKRecord = data;
}
- (CKRecord*) CKRecordWithZoneID: (CKRecordZoneID*) zoneID {
CKRecordID* recordID = [[CKRecordID alloc] initWithRecordName: [self CKRecordName] zoneID: zoneID];
CKRecord* record = nil;
if(self.encodedCKRecord == nil) {
record = [[CKRecord alloc] initWithRecordType:self.ckRecordType recordID:recordID];
} else {
record = self.storedCKRecord;
}
[self updateCKRecord:record zoneID:zoneID];
self.storedCKRecord = record;
return record;
}
- (NSString*) CKRecordName {
@throw [NSException exceptionWithName:NSInternalInconsistencyException
reason:[NSString stringWithFormat:@" userInfo:nil];
}
- (CKRecord*) updateCKRecord: (CKRecord*) record zoneID: (CKRecordZoneID*) zoneID {
@throw [NSException exceptionWithName:NSInternalInconsistencyException
reason:[NSString stringWithFormat:@" userInfo:nil];
}
- (void) setFromCKRecord: (CKRecord*) record {
@throw [NSException exceptionWithName:NSInternalInconsistencyException
reason:[NSString stringWithFormat:@" userInfo:nil];
}
- (bool) matchesCKRecord: (CKRecord*) record {
@throw [NSException exceptionWithName:NSInternalInconsistencyException
reason:[NSString stringWithFormat:@" userInfo:nil];
}
- (instancetype)copyWithZone:(NSZone *)zone {
CKKSCKRecordHolder *rhCopy = [super copyWithZone:zone];
rhCopy->_zoneID = _zoneID;
rhCopy->_ckRecordType = _ckRecordType;
rhCopy->_encodedCKRecord = _encodedCKRecord;
return rhCopy;
}
@end
#endif