1/*
2 * Copyright (C) 2016 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#pragma once
27
28#include "IDLTypes.h"
29#include "JSDOMConvertAny.h"
30#include "JSDOMConvertInterface.h"
31#include "JSDOMConvertNumbers.h"
32#include "JSDOMConvertStrings.h"
33
34namespace WebCore {
35
36namespace Detail {
37
38template<typename IDLType>
39struct NullableConversionType;
40
41template<typename IDLType>
42struct NullableConversionType {
43 using Type = typename IDLNullable<IDLType>::ImplementationType;
44};
45
46template<typename T>
47struct NullableConversionType<IDLInterface<T>> {
48 using Type = typename Converter<IDLInterface<T>>::ReturnType;
49};
50
51template<>
52struct NullableConversionType<IDLAny> {
53 using Type = typename Converter<IDLAny>::ReturnType;
54};
55
56}
57
58template<typename T> struct Converter<IDLNullable<T>> : DefaultConverter<IDLNullable<T>> {
59 using ReturnType = typename Detail::NullableConversionType<T>::Type;
60
61 // 1. If Type(V) is not Object, and the conversion to an IDL value is being performed
62 // due to V being assigned to an attribute whose type is a nullable callback function
63 // that is annotated with [TreatNonObjectAsNull], then return the IDL nullable type T?
64 // value null.
65 //
66 // NOTE: Handled elsewhere.
67 //
68 // 2. Otherwise, if V is null or undefined, then return the IDL nullable type T? value null.
69 // 3. Otherwise, return the result of converting V using the rules for the inner IDL type T.
70
71 static ReturnType convert(JSC::ExecState& state, JSC::JSValue value)
72 {
73 if (value.isUndefinedOrNull())
74 return T::nullValue();
75 return Converter<T>::convert(state, value);
76 }
77 static ReturnType convert(JSC::ExecState& state, JSC::JSValue value, JSC::JSObject& thisObject)
78 {
79 if (value.isUndefinedOrNull())
80 return T::nullValue();
81 return Converter<T>::convert(state, value, thisObject);
82 }
83 static ReturnType convert(JSC::ExecState& state, JSC::JSValue value, JSDOMGlobalObject& globalObject)
84 {
85 if (value.isUndefinedOrNull())
86 return T::nullValue();
87 return Converter<T>::convert(state, value, globalObject);
88 }
89 template<typename ExceptionThrower = DefaultExceptionThrower>
90 static ReturnType convert(JSC::ExecState& state, JSC::JSValue value, ExceptionThrower&& exceptionThrower)
91 {
92 if (value.isUndefinedOrNull())
93 return T::nullValue();
94 return Converter<T>::convert(state, value, std::forward<ExceptionThrower>(exceptionThrower));
95 }
96 template<typename ExceptionThrower = DefaultExceptionThrower>
97 static ReturnType convert(JSC::ExecState& state, JSC::JSValue value, JSC::JSObject& thisObject, ExceptionThrower&& exceptionThrower)
98 {
99 if (value.isUndefinedOrNull())
100 return T::nullValue();
101 return Converter<T>::convert(state, value, thisObject, std::forward<ExceptionThrower>(exceptionThrower));
102 }
103 template<typename ExceptionThrower = DefaultExceptionThrower>
104 static ReturnType convert(JSC::ExecState& state, JSC::JSValue value, JSDOMGlobalObject& globalObject, ExceptionThrower&& exceptionThrower)
105 {
106 if (value.isUndefinedOrNull())
107 return T::nullValue();
108 return Converter<T>::convert(state, value, globalObject, std::forward<ExceptionThrower>(exceptionThrower));
109 }
110};
111
112template<typename T> struct JSConverter<IDLNullable<T>> {
113 using ImplementationType = typename IDLNullable<T>::ImplementationType;
114
115 static constexpr bool needsState = JSConverter<T>::needsState;
116 static constexpr bool needsGlobalObject = JSConverter<T>::needsGlobalObject;
117
118 template<typename U>
119 static JSC::JSValue convert(U&& value)
120 {
121 if (T::isNullValue(value))
122 return JSC::jsNull();
123 return JSConverter<T>::convert(T::extractValueFromNullable(value));
124 }
125 template<typename U>
126 static JSC::JSValue convert(JSC::ExecState& state, U&& value)
127 {
128 if (T::isNullValue(value))
129 return JSC::jsNull();
130 return JSConverter<T>::convert(state, T::extractValueFromNullable(value));
131 }
132 template<typename U>
133 static JSC::JSValue convert(JSC::ExecState& state, JSDOMGlobalObject& globalObject, U&& value)
134 {
135 if (T::isNullValue(value))
136 return JSC::jsNull();
137 return JSConverter<T>::convert(state, globalObject, T::extractValueFromNullable(value));
138 }
139
140 template<typename U>
141 static JSC::JSValue convertNewlyCreated(JSC::ExecState& state, JSDOMGlobalObject& globalObject, U&& value)
142 {
143 if (T::isNullValue(value))
144 return JSC::jsNull();
145 return JSConverter<T>::convert(state, globalObject, T::extractValueFromNullable(value));
146 }
147};
148
149
150} // namespace WebCore
151