Unreviewed, rolling out r178039.
[WebKit-https.git] / Source / JavaScriptCore / inspector / InspectorProtocolTypes.h
1 /*
2  * Copyright (C) 2013 Apple Inc. All Rights Reserved.
3  * Copyright (C) 2011 The Chromium Authors. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26
27 #ifndef InspectorProtocolTypes_h
28 #define InspectorProtocolTypes_h
29
30 #if ENABLE(INSPECTOR)
31
32 #include "InspectorValues.h"
33 #include <wtf/Assertions.h>
34 #include <wtf/PassRefPtr.h>
35
36 namespace Inspector {
37
38 namespace Protocol {
39
40 template<typename T>
41 class OptOutput {
42 public:
43     OptOutput() : m_assigned(false) { }
44
45     void operator=(T value)
46     {
47         m_value = value;
48         m_assigned = true;
49     }
50
51     bool isAssigned() const { return m_assigned; }
52
53     T getValue()
54     {
55         ASSERT(isAssigned());
56         return m_value;
57     }
58
59 private:
60     T m_value;
61     bool m_assigned;
62
63     WTF_MAKE_NONCOPYABLE(OptOutput);
64 };
65
66 // This class provides "Traits" type for the input type T. It is programmed using C++ template specialization
67 // technique. By default it simply takes "ItemTraits" type from T, but it doesn't work with the base types.
68 template<typename T>
69 struct ArrayItemHelper {
70     typedef typename T::ItemTraits Traits;
71 };
72
73 template<typename T>
74 class Array : public InspectorArrayBase {
75 private:
76     Array() { }
77
78     InspectorArray* openAccessors()
79     {
80         COMPILE_ASSERT(sizeof(InspectorArray) == sizeof(Array<T>), cannot_cast);
81         return static_cast<InspectorArray*>(static_cast<InspectorArrayBase*>(this));
82     }
83
84 public:
85     void addItem(PassRefPtr<T> value)
86     {
87         ArrayItemHelper<T>::Traits::pushRefPtr(this->openAccessors(), value);
88     }
89
90     void addItem(T value)
91     {
92         ArrayItemHelper<T>::Traits::pushRaw(this->openAccessors(), value);
93     }
94
95     static PassRefPtr<Array<T>> create()
96     {
97         return adoptRef(new Array<T>());
98     }
99 };
100
101 struct StructItemTraits {
102     static void pushRefPtr(InspectorArray* array, PassRefPtr<InspectorValue> value)
103     {
104         array->pushValue(value);
105     }
106 };
107
108 template<>
109 struct ArrayItemHelper<String> {
110     struct Traits {
111         static void pushRaw(InspectorArray* array, const String& value)
112         {
113             array->pushString(value);
114         }
115     };
116 };
117
118 template<>
119 struct ArrayItemHelper<int> {
120     struct Traits {
121         static void pushRaw(InspectorArray* array, int value)
122         {
123             array->pushInteger(value);
124         }
125     };
126 };
127
128 template<>
129 struct ArrayItemHelper<double> {
130     struct Traits {
131         static void pushRaw(InspectorArray* array, double value)
132         {
133             array->pushDouble(value);
134         }
135     };
136 };
137
138 template<>
139 struct ArrayItemHelper<bool> {
140     struct Traits {
141         static void pushRaw(InspectorArray* array, bool value)
142         {
143             array->pushBoolean(value);
144         }
145     };
146 };
147
148 template<>
149 struct ArrayItemHelper<InspectorValue> {
150     struct Traits {
151         static void pushRefPtr(InspectorArray* array, PassRefPtr<InspectorValue> value)
152         {
153             array->pushValue(value);
154         }
155     };
156 };
157
158 template<>
159 struct ArrayItemHelper<InspectorObject> {
160     struct Traits {
161         static void pushRefPtr(InspectorArray* array, PassRefPtr<InspectorValue> value)
162         {
163             array->pushValue(value);
164         }
165     };
166 };
167
168 template<>
169 struct ArrayItemHelper<InspectorArray> {
170     struct Traits {
171         static void pushRefPtr(InspectorArray* array, PassRefPtr<InspectorArray> value)
172         {
173             array->pushArray(value);
174         }
175     };
176 };
177
178 template<typename T>
179 struct ArrayItemHelper<Protocol::Array<T>> {
180     struct Traits {
181         static void pushRefPtr(InspectorArray* array, PassRefPtr<Protocol::Array<T>> value)
182         {
183             array->pushValue(value);
184         }
185     };
186 };
187
188 // Helper methods for Protocol and other Inspector types are provided by
189 // specializations of BindingTraits<T>. Some are generated for protocol types.
190
191 template<typename T>
192 struct BindingTraits {
193     typedef T BindingType;
194
195     static InspectorValue::Type typeTag();
196     static PassRefPtr<T> runtimeCast(PassRefPtr<InspectorObject>);
197 #if !ASSERT_DISABLED
198     static void assertValueHasExpectedType(InspectorValue*);
199 #endif // !ASSERT_DISABLED
200 };
201
202 template<InspectorValue::Type TYPE>
203 struct PrimitiveBindingTraits {
204 #if !ASSERT_DISABLED
205     static void assertValueHasExpectedType(InspectorValue* value)
206     {
207         ASSERT(value->type() == TYPE);
208     }
209 #endif // !ASSERT_DISABLED
210 };
211
212 template<typename T>
213 struct BindingTraits<Protocol::Array<T>> {
214     static PassRefPtr<Array<T>> runtimeCast(PassRefPtr<InspectorValue> value)
215     {
216         RefPtr<InspectorArray> array;
217         bool castSucceeded = value->asArray(array);
218         ASSERT_UNUSED(castSucceeded, castSucceeded);
219 #if !ASSERT_DISABLED
220         assertValueHasExpectedType(array.get());
221 #endif // !ASSERT_DISABLED
222         COMPILE_ASSERT(sizeof(Array<T>) == sizeof(InspectorArray), type_cast_problem);
223         return static_cast<Array<T>*>(static_cast<InspectorArrayBase*>(array.get()));
224     }
225
226 #if !ASSERT_DISABLED
227     static void assertValueHasExpectedType(InspectorValue* value)
228     {
229         RefPtr<InspectorArray> array;
230         bool castSucceeded = value->asArray(array);
231         ASSERT_UNUSED(castSucceeded, castSucceeded);
232         for (unsigned i = 0; i < array->length(); i++)
233             BindingTraits<T>::assertValueHasExpectedType(array->get(i).get());
234     }
235 #endif // !ASSERT_DISABLED
236 };
237
238 template<>
239 struct BindingTraits<InspectorValue> {
240 #if !ASSERT_DISABLED
241     static void assertValueHasExpectedType(InspectorValue*)
242     {
243     }
244 #endif // !ASSERT_DISABLED
245 };
246
247 template<> struct BindingTraits<InspectorArray> : public PrimitiveBindingTraits<InspectorValue::Type::Array> { };
248 template<> struct BindingTraits<InspectorObject> : public PrimitiveBindingTraits<InspectorValue::Type::Object> { };
249 template<> struct BindingTraits<String> : public PrimitiveBindingTraits<InspectorValue::Type::String> { };
250 template<> struct BindingTraits<bool> : public PrimitiveBindingTraits<InspectorValue::Type::Boolean> { };
251 template<> struct BindingTraits<double> : public PrimitiveBindingTraits<InspectorValue::Type::Double> { };
252 template<> struct BindingTraits<int> : public PrimitiveBindingTraits<InspectorValue::Type::Integer> { };
253
254 } // namespace Protocol
255
256 using Protocol::BindingTraits;
257
258 } // namespace Inspector
259
260 #endif // ENABLE(INSPECTOR)
261
262 #endif // !defined(InspectorProtocolTypes_h)