Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / src / darwin / Framework / CHIP / CHIPPersistentStorageDelegateBridge.mm
1 /**
2  *
3  *    Copyright (c) 2020 Project CHIP Authors
4  *
5  *    Licensed under the Apache License, Version 2.0 (the "License");
6  *    you may not use this file except in compliance with the License.
7  *    You may obtain a copy of the License at
8  *
9  *        http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *    Unless required by applicable law or agreed to in writing, software
12  *    distributed under the License is distributed on an "AS IS" BASIS,
13  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *    See the License for the specific language governing permissions and
15  *    limitations under the License.
16  */
17
18 #import "CHIPPersistentStorageDelegateBridge.h"
19
20 CHIPPersistentStorageDelegateBridge::CHIPPersistentStorageDelegateBridge(void)
21     : mDelegate(nil)
22 {
23     mDefaultPersistentStorage = [[NSUserDefaults alloc] init];
24     mWorkQueue = dispatch_queue_create("com.zigbee.chip.framework.storage.workqueue", DISPATCH_QUEUE_SERIAL);
25 }
26
27 CHIPPersistentStorageDelegateBridge::~CHIPPersistentStorageDelegateBridge(void) {}
28
29 void CHIPPersistentStorageDelegateBridge::setFrameworkDelegate(id<CHIPPersistentStorageDelegate> delegate, dispatch_queue_t queue)
30 {
31     dispatch_async(mWorkQueue, ^{
32         if (delegate && queue) {
33             mDelegate = delegate;
34             mQueue = queue;
35         } else {
36             mDelegate = nil;
37             mQueue = nil;
38         }
39     });
40 }
41
42 void CHIPPersistentStorageDelegateBridge::SetStorageDelegate(chip::PersistentStorageResultDelegate * delegate)
43 {
44     dispatch_async(mWorkQueue, ^{
45         if (delegate) {
46             mCallback = delegate;
47
48             mSetStatusHandler = ^(NSString * key, NSError * status) {
49                 chip::PersistentStorageResultDelegate * callback = mCallback;
50                 if (callback) {
51                     dispatch_async(mWorkQueue, ^{
52                         callback->OnPersistentStorageStatus([key UTF8String],
53                             chip::PersistentStorageResultDelegate::Operation::kSET, [CHIPError errorToCHIPErrorCode:status]);
54                     });
55                 }
56             };
57
58             mDeleteStatusHandler = ^(NSString * key, NSError * status) {
59                 chip::PersistentStorageResultDelegate * callback = mCallback;
60                 if (callback) {
61                     dispatch_async(mWorkQueue, ^{
62                         callback->OnPersistentStorageStatus([key UTF8String],
63                             chip::PersistentStorageResultDelegate::Operation::kDELETE, [CHIPError errorToCHIPErrorCode:status]);
64                     });
65                 }
66             };
67         } else {
68             mCallback = nil;
69             mSetStatusHandler = nil;
70             mDeleteStatusHandler = nil;
71         }
72     });
73 }
74
75 CHIP_ERROR CHIPPersistentStorageDelegateBridge::SyncGetKeyValue(const char * key, char * value, uint16_t & size)
76 {
77     __block CHIP_ERROR error = CHIP_NO_ERROR;
78     NSString * keyString = [NSString stringWithUTF8String:key];
79     dispatch_sync(mWorkQueue, ^{
80         NSLog(@"PersistentStorageDelegate Sync Get Value for Key: %@", keyString);
81
82         NSString * valueString = nil;
83
84         id<CHIPPersistentStorageDelegate> strongDelegate = mDelegate;
85         if (strongDelegate) {
86             valueString = [strongDelegate CHIPGetKeyValue:keyString];
87         } else {
88             valueString = [mDefaultPersistentStorage objectForKey:keyString];
89         }
90
91         if (valueString != nil) {
92             if (([valueString lengthOfBytesUsingEncoding:NSUTF8StringEncoding] + 1) > UINT16_MAX) {
93                 error = CHIP_ERROR_BUFFER_TOO_SMALL;
94             } else {
95                 if (value != nullptr) {
96                     size = (uint16_t) strlcpy(value, [valueString UTF8String], size);
97                     if (size < [valueString lengthOfBytesUsingEncoding:NSUTF8StringEncoding]) {
98                         error = CHIP_ERROR_NO_MEMORY;
99                     }
100                 } else {
101                     size = (uint16_t) [valueString lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
102                     error = CHIP_ERROR_NO_MEMORY;
103                 }
104                 // Increment size to account for null termination
105                 size += 1;
106             }
107         } else {
108             error = CHIP_ERROR_KEY_NOT_FOUND;
109         }
110     });
111     return error;
112 }
113
114 void CHIPPersistentStorageDelegateBridge::AsyncSetKeyValue(const char * key, const char * value)
115 {
116     NSString * keyString = [NSString stringWithUTF8String:key];
117     NSString * valueString = [NSString stringWithUTF8String:value];
118     dispatch_async(mWorkQueue, ^{
119         NSLog(@"PersistentStorageDelegate Set Key %@, Value %@", keyString, valueString);
120
121         id<CHIPPersistentStorageDelegate> strongDelegate = mDelegate;
122         if (strongDelegate && mQueue) {
123             dispatch_async(mQueue, ^{
124                 [strongDelegate CHIPSetKeyValue:keyString value:valueString handler:mSetStatusHandler];
125             });
126         } else {
127             [mDefaultPersistentStorage setObject:valueString forKey:keyString];
128             if (mSetStatusHandler) {
129                 mSetStatusHandler(keyString, [CHIPError errorForCHIPErrorCode:0]);
130             }
131         }
132     });
133 }
134
135 void CHIPPersistentStorageDelegateBridge::AsyncDeleteKeyValue(const char * key)
136 {
137     NSString * keyString = [NSString stringWithUTF8String:key];
138     dispatch_async(mWorkQueue, ^{
139         NSLog(@"PersistentStorageDelegate Delete Key: %@", keyString);
140
141         id<CHIPPersistentStorageDelegate> strongDelegate = mDelegate;
142         if (strongDelegate && mQueue) {
143             dispatch_async(mQueue, ^{
144                 [strongDelegate CHIPDeleteKeyValue:keyString handler:mDeleteStatusHandler];
145             });
146         } else {
147             [mDefaultPersistentStorage removeObjectForKey:keyString];
148             if (mDeleteStatusHandler) {
149                 mDeleteStatusHandler(keyString, [CHIPError errorForCHIPErrorCode:0]);
150             }
151         }
152     });
153 }