[Cocoa] Make it easier to encode NSObjects
[WebKit-https.git] / Source / WebKit / Shared / Cocoa / WebCoreArgumentCodersCocoa.mm
1 /*
2  * Copyright (C) 2016-2018 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #import "config.h"
27 #import "WebCoreArgumentCoders.h"
28
29 #if ENABLE(APPLE_PAY)
30
31 #import "ArgumentCodersCocoa.h"
32 #import "DataReference.h"
33 #import <WebCore/PaymentAuthorizationStatus.h>
34 #import <pal/cocoa/PassKitSoftLink.h>
35 #import <pal/spi/cocoa/NSKeyedArchiverSPI.h>
36
37 namespace IPC {
38 using namespace WebCore;
39
40 void ArgumentCoder<WebCore::Payment>::encode(Encoder& encoder, const WebCore::Payment& payment)
41 {
42     encoder << payment.pkPayment();
43 }
44
45 std::optional<WebCore::Payment> ArgumentCoder<WebCore::Payment>::decode(Decoder& decoder)
46 {
47     auto payment = IPC::decode<PKPayment>(decoder, PAL::getPKPaymentClass());
48     if (!payment)
49         return std::nullopt;
50
51     return Payment { WTFMove(*payment) };
52 }
53
54 void ArgumentCoder<WebCore::PaymentAuthorizationResult>::encode(Encoder& encoder, const WebCore::PaymentAuthorizationResult& result)
55 {
56     encoder << result.status;
57     encoder << result.errors;
58 }
59
60 std::optional<WebCore::PaymentAuthorizationResult> ArgumentCoder<WebCore::PaymentAuthorizationResult>::decode(Decoder& decoder)
61 {
62     std::optional<PaymentAuthorizationStatus> status;
63     decoder >> status;
64     if (!status)
65         return std::nullopt;
66
67     std::optional<Vector<PaymentError>> errors;
68     decoder >> errors;
69     if (!errors)
70         return std::nullopt;
71
72     return {{ WTFMove(*status), WTFMove(*errors) }};
73 }
74
75 void ArgumentCoder<WebCore::PaymentContact>::encode(Encoder& encoder, const WebCore::PaymentContact& paymentContact)
76 {
77     encoder << paymentContact.pkContact();
78 }
79
80 std::optional<WebCore::PaymentContact> ArgumentCoder<WebCore::PaymentContact>::decode(Decoder& decoder)
81 {
82     auto contact = IPC::decode<PKContact>(decoder, PAL::getPKContactClass());
83     if (!contact)
84         return std::nullopt;
85
86     return WebCore::PaymentContact { WTFMove(*contact) };
87 }
88
89 void ArgumentCoder<WebCore::PaymentError>::encode(Encoder& encoder, const WebCore::PaymentError& error)
90 {
91     encoder << error.code;
92     encoder << error.message;
93     encoder << error.contactField;
94 }
95
96 std::optional<WebCore::PaymentError> ArgumentCoder<WebCore::PaymentError>::decode(Decoder& decoder)
97 {
98     std::optional<WebCore::PaymentError::Code> code;
99     decoder >> code;
100     if (!code)
101         return std::nullopt;
102     
103     std::optional<String> message;
104     decoder >> message;
105     if (!message)
106         return std::nullopt;
107     
108     std::optional<std::optional<WebCore::PaymentError::ContactField>> contactField;
109     decoder >> contactField;
110     if (!contactField)
111         return std::nullopt;
112
113     return {{ WTFMove(*code), WTFMove(*message), WTFMove(*contactField) }};
114 }
115
116 void ArgumentCoder<WebCore::PaymentMerchantSession>::encode(Encoder& encoder, const WebCore::PaymentMerchantSession& paymentMerchantSession)
117 {
118     encoder << paymentMerchantSession.pkPaymentMerchantSession();
119 }
120
121 std::optional<WebCore::PaymentMerchantSession> ArgumentCoder<WebCore::PaymentMerchantSession>::decode(Decoder& decoder)
122 {
123     auto paymentMerchantSession = IPC::decode<PKPaymentMerchantSession>(decoder, PAL::getPKPaymentMerchantSessionClass());
124     if (!paymentMerchantSession)
125         return std::nullopt;
126
127     return WebCore::PaymentMerchantSession { WTFMove(*paymentMerchantSession) };
128 }
129
130 void ArgumentCoder<WebCore::PaymentMethod>::encode(Encoder& encoder, const WebCore::PaymentMethod& paymentMethod)
131 {
132     encoder << paymentMethod.pkPaymentMethod();
133 }
134
135 std::optional<WebCore::PaymentMethod> ArgumentCoder<WebCore::PaymentMethod>::decode(Decoder& decoder)
136 {
137     auto paymentMethod = IPC::decode<PKPaymentMethod>(decoder, PAL::getPKPaymentMethodClass());
138     if (!paymentMethod)
139         return std::nullopt;
140
141     return PaymentMethod { WTFMove(*paymentMethod) };
142 }
143
144 void ArgumentCoder<WebCore::PaymentMethodUpdate>::encode(Encoder& encoder, const WebCore::PaymentMethodUpdate& update)
145 {
146     encoder << update.newTotalAndLineItems;
147 }
148
149 std::optional<WebCore::PaymentMethodUpdate> ArgumentCoder<WebCore::PaymentMethodUpdate>::decode(Decoder& decoder)
150 {
151     std::optional<ApplePaySessionPaymentRequest::TotalAndLineItems> newTotalAndLineItems;
152     decoder >> newTotalAndLineItems;
153     if (!newTotalAndLineItems)
154         return std::nullopt;
155     return {{ WTFMove(*newTotalAndLineItems) }};
156 }
157
158 void ArgumentCoder<ApplePaySessionPaymentRequest>::encode(Encoder& encoder, const ApplePaySessionPaymentRequest& request)
159 {
160     encoder << request.countryCode();
161     encoder << request.currencyCode();
162     encoder << request.requiredBillingContactFields();
163     encoder << request.billingContact();
164     encoder << request.requiredShippingContactFields();
165     encoder << request.shippingContact();
166     encoder << request.merchantCapabilities();
167     encoder << request.supportedNetworks();
168     encoder.encodeEnum(request.shippingType());
169     encoder << request.shippingMethods();
170     encoder << request.lineItems();
171     encoder << request.total();
172     encoder << request.applicationData();
173     encoder << request.supportedCountries();
174     encoder.encodeEnum(request.requester());
175 }
176
177 bool ArgumentCoder<ApplePaySessionPaymentRequest>::decode(Decoder& decoder, ApplePaySessionPaymentRequest& request)
178 {
179     String countryCode;
180     if (!decoder.decode(countryCode))
181         return false;
182     request.setCountryCode(countryCode);
183
184     String currencyCode;
185     if (!decoder.decode(currencyCode))
186         return false;
187     request.setCurrencyCode(currencyCode);
188
189     ApplePaySessionPaymentRequest::ContactFields requiredBillingContactFields;
190     if (!decoder.decode((requiredBillingContactFields)))
191         return false;
192     request.setRequiredBillingContactFields(requiredBillingContactFields);
193
194     std::optional<PaymentContact> billingContact;
195     decoder >> billingContact;
196     if (!billingContact)
197         return false;
198     request.setBillingContact(*billingContact);
199
200     ApplePaySessionPaymentRequest::ContactFields requiredShippingContactFields;
201     if (!decoder.decode((requiredShippingContactFields)))
202         return false;
203     request.setRequiredShippingContactFields(requiredShippingContactFields);
204
205     std::optional<PaymentContact> shippingContact;
206     decoder >> shippingContact;
207     if (!shippingContact)
208         return false;
209     request.setShippingContact(*shippingContact);
210
211     ApplePaySessionPaymentRequest::MerchantCapabilities merchantCapabilities;
212     if (!decoder.decode(merchantCapabilities))
213         return false;
214     request.setMerchantCapabilities(merchantCapabilities);
215
216     Vector<String> supportedNetworks;
217     if (!decoder.decode(supportedNetworks))
218         return false;
219     request.setSupportedNetworks(supportedNetworks);
220
221     ApplePaySessionPaymentRequest::ShippingType shippingType;
222     if (!decoder.decodeEnum(shippingType))
223         return false;
224     request.setShippingType(shippingType);
225
226     Vector<ApplePaySessionPaymentRequest::ShippingMethod> shippingMethods;
227     if (!decoder.decode(shippingMethods))
228         return false;
229     request.setShippingMethods(shippingMethods);
230
231     Vector<ApplePaySessionPaymentRequest::LineItem> lineItems;
232     if (!decoder.decode(lineItems))
233         return false;
234     request.setLineItems(lineItems);
235
236     std::optional<ApplePaySessionPaymentRequest::LineItem> total;
237     decoder >> total;
238     if (!total)
239         return false;
240     request.setTotal(*total);
241
242     String applicationData;
243     if (!decoder.decode(applicationData))
244         return false;
245     request.setApplicationData(applicationData);
246
247     Vector<String> supportedCountries;
248     if (!decoder.decode(supportedCountries))
249         return false;
250     request.setSupportedCountries(WTFMove(supportedCountries));
251
252     ApplePaySessionPaymentRequest::Requester requester;
253     if (!decoder.decodeEnum(requester))
254         return false;
255     request.setRequester(requester);
256
257     return true;
258 }
259
260 void ArgumentCoder<ApplePaySessionPaymentRequest::ContactFields>::encode(Encoder& encoder, const ApplePaySessionPaymentRequest::ContactFields& contactFields)
261 {
262     encoder << contactFields.postalAddress;
263     encoder << contactFields.phone;
264     encoder << contactFields.email;
265     encoder << contactFields.name;
266     encoder << contactFields.phoneticName;
267 }
268
269 bool ArgumentCoder<ApplePaySessionPaymentRequest::ContactFields>::decode(Decoder& decoder, ApplePaySessionPaymentRequest::ContactFields& contactFields)
270 {
271     if (!decoder.decode(contactFields.postalAddress))
272         return false;
273     if (!decoder.decode(contactFields.phone))
274         return false;
275     if (!decoder.decode(contactFields.email))
276         return false;
277     if (!decoder.decode(contactFields.name))
278         return false;
279     if (!decoder.decode(contactFields.phoneticName))
280         return false;
281
282     return true;
283 }
284
285 void ArgumentCoder<ApplePaySessionPaymentRequest::LineItem>::encode(Encoder& encoder, const ApplePaySessionPaymentRequest::LineItem& lineItem)
286 {
287     encoder.encodeEnum(lineItem.type);
288     encoder << lineItem.label;
289     encoder << lineItem.amount;
290 }
291
292 std::optional<ApplePaySessionPaymentRequest::LineItem> ArgumentCoder<ApplePaySessionPaymentRequest::LineItem>::decode(Decoder& decoder)
293 {
294     WebCore::ApplePaySessionPaymentRequest::LineItem lineItem;
295     if (!decoder.decodeEnum(lineItem.type))
296         return std::nullopt;
297     if (!decoder.decode(lineItem.label))
298         return std::nullopt;
299     if (!decoder.decode(lineItem.amount))
300         return std::nullopt;
301
302     return WTFMove(lineItem);
303 }
304
305 void ArgumentCoder<ApplePaySessionPaymentRequest::MerchantCapabilities>::encode(Encoder& encoder, const ApplePaySessionPaymentRequest::MerchantCapabilities& merchantCapabilities)
306 {
307     encoder << merchantCapabilities.supports3DS;
308     encoder << merchantCapabilities.supportsEMV;
309     encoder << merchantCapabilities.supportsCredit;
310     encoder << merchantCapabilities.supportsDebit;
311 }
312
313 bool ArgumentCoder<ApplePaySessionPaymentRequest::MerchantCapabilities>::decode(Decoder& decoder, ApplePaySessionPaymentRequest::MerchantCapabilities& merchantCapabilities)
314 {
315     if (!decoder.decode(merchantCapabilities.supports3DS))
316         return false;
317     if (!decoder.decode(merchantCapabilities.supportsEMV))
318         return false;
319     if (!decoder.decode(merchantCapabilities.supportsCredit))
320         return false;
321     if (!decoder.decode(merchantCapabilities.supportsDebit))
322         return false;
323
324     return true;
325 }
326
327 void ArgumentCoder<ApplePaySessionPaymentRequest::ShippingMethod>::encode(Encoder& encoder, const ApplePaySessionPaymentRequest::ShippingMethod& shippingMethod)
328 {
329     encoder << shippingMethod.label;
330     encoder << shippingMethod.detail;
331     encoder << shippingMethod.amount;
332     encoder << shippingMethod.identifier;
333 }
334
335 std::optional<ApplePaySessionPaymentRequest::ShippingMethod> ArgumentCoder<ApplePaySessionPaymentRequest::ShippingMethod>::decode(Decoder& decoder)
336 {
337     ApplePaySessionPaymentRequest::ShippingMethod shippingMethod;
338     if (!decoder.decode(shippingMethod.label))
339         return std::nullopt;
340     if (!decoder.decode(shippingMethod.detail))
341         return std::nullopt;
342     if (!decoder.decode(shippingMethod.amount))
343         return std::nullopt;
344     if (!decoder.decode(shippingMethod.identifier))
345         return std::nullopt;
346     return WTFMove(shippingMethod);
347 }
348
349 void ArgumentCoder<ApplePaySessionPaymentRequest::TotalAndLineItems>::encode(Encoder& encoder, const ApplePaySessionPaymentRequest::TotalAndLineItems& totalAndLineItems)
350 {
351     encoder << totalAndLineItems.total;
352     encoder << totalAndLineItems.lineItems;
353 }
354
355 std::optional<ApplePaySessionPaymentRequest::TotalAndLineItems> ArgumentCoder<ApplePaySessionPaymentRequest::TotalAndLineItems>::decode(Decoder& decoder)
356 {
357     std::optional<ApplePaySessionPaymentRequest::LineItem> total;
358     decoder >> total;
359     if (!total)
360         return std::nullopt;
361     
362     std::optional<Vector<ApplePaySessionPaymentRequest::LineItem>> lineItems;
363     decoder >> lineItems;
364     if (!lineItems)
365         return std::nullopt;
366     
367     return {{ WTFMove(*total), WTFMove(*lineItems) }};
368 }
369
370 void ArgumentCoder<WebCore::ShippingContactUpdate>::encode(Encoder& encoder, const WebCore::ShippingContactUpdate& update)
371 {
372     encoder << update.errors;
373     encoder << update.newShippingMethods;
374     encoder << update.newTotalAndLineItems;
375 }
376
377 std::optional<WebCore::ShippingContactUpdate> ArgumentCoder<WebCore::ShippingContactUpdate>::decode(Decoder& decoder)
378 {
379     std::optional<Vector<PaymentError>> errors;
380     decoder >> errors;
381     if (!errors)
382         return std::nullopt;
383     
384     std::optional<Vector<ApplePaySessionPaymentRequest::ShippingMethod>> newShippingMethods;
385     decoder >> newShippingMethods;
386     if (!newShippingMethods)
387         return std::nullopt;
388     
389     std::optional<ApplePaySessionPaymentRequest::TotalAndLineItems> newTotalAndLineItems;
390     decoder >> newTotalAndLineItems;
391     if (!newTotalAndLineItems)
392         return std::nullopt;
393     
394     return {{ WTFMove(*errors), WTFMove(*newShippingMethods), WTFMove(*newTotalAndLineItems) }};
395 }
396
397 void ArgumentCoder<WebCore::ShippingMethodUpdate>::encode(Encoder& encoder, const WebCore::ShippingMethodUpdate& update)
398 {
399     encoder << update.newTotalAndLineItems;
400 }
401
402 std::optional<WebCore::ShippingMethodUpdate> ArgumentCoder<WebCore::ShippingMethodUpdate>::decode(Decoder& decoder)
403 {
404     std::optional<ApplePaySessionPaymentRequest::TotalAndLineItems> newTotalAndLineItems;
405     decoder >> newTotalAndLineItems;
406     if (!newTotalAndLineItems)
407         return std::nullopt;
408     return {{ WTFMove(*newTotalAndLineItems) }};
409 }
410
411 }
412 #endif