1/*
2 * Copyright (C) 2012 Research In Motion Limited. All rights reserved.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
17 */
18
19#include "config.h"
20#include "JavaScriptVariant.h"
21
22#include "JavaScriptVariant_p.h"
23#include "WebPage.h"
24#include <JSStringRef.h>
25#include <JSValueRef.h>
26#include <stdlib.h>
27#include <wtf/Vector.h>
28
29namespace BlackBerry {
30namespace WebKit {
31
32JavaScriptVariant JSValueRefToBlackBerryJavaScriptVariant(const JSGlobalContextRef& ctx, const JSValueRef& value)
33{
34    JavaScriptVariant returnValue;
35
36    switch (JSValueGetType(ctx, value)) {
37    case kJSTypeNull:
38        returnValue.setType(JavaScriptVariant::Null);
39        break;
40    case kJSTypeBoolean:
41        returnValue.setBoolean(JSValueToBoolean(ctx, value));
42        break;
43    case kJSTypeNumber:
44        returnValue.setDouble(JSValueToNumber(ctx, value, 0));
45        break;
46    case kJSTypeString: {
47        JSStringRef stringRef = JSValueToStringCopy(ctx, value, 0);
48        if (!stringRef) {
49            returnValue.setString(BlackBerry::Platform::String::emptyString());
50            break;
51        }
52        size_t bufferSize = JSStringGetMaximumUTF8CStringSize(stringRef);
53        WTF::Vector<char> buffer(bufferSize);
54        size_t rc = JSStringGetUTF8CString(stringRef, buffer.data(), bufferSize);
55        returnValue.setString(BlackBerry::Platform::String::fromUtf8(buffer.data(), rc - 1));
56        JSStringRelease(stringRef);
57        break;
58    }
59    case kJSTypeObject:
60        returnValue.setType(JavaScriptVariant::Object);
61        break;
62    case kJSTypeUndefined:
63        returnValue.setType(JavaScriptVariant::Undefined);
64        break;
65    }
66    return returnValue;
67}
68
69JSValueRef BlackBerryJavaScriptVariantToJSValueRef(const JSGlobalContextRef& ctx, const JavaScriptVariant& variant)
70{
71    JSValueRef ref = 0;
72    switch (variant.type()) {
73    case JavaScriptVariant::Undefined:
74        ref = JSValueMakeUndefined(ctx);
75        break;
76    case JavaScriptVariant::Null:
77        ref = JSValueMakeNull(ctx);
78        break;
79    case JavaScriptVariant::Boolean:
80        ref = JSValueMakeBoolean(ctx, variant.booleanValue());
81        break;
82    case JavaScriptVariant::Number:
83        ref = JSValueMakeNumber(ctx, variant.doubleValue());
84        break;
85    case JavaScriptVariant::String: {
86        JSStringRef str = JSStringCreateWithUTF8CString(variant.stringValue().c_str());
87        ref = JSValueMakeString(ctx, str);
88        JSStringRelease(str);
89        break;
90    }
91    case JavaScriptVariant::Exception:
92    case JavaScriptVariant::Object:
93        ASSERT_NOT_REACHED();
94        break;
95    }
96    return ref;
97}
98
99JavaScriptVariant::JavaScriptVariant()
100    : m_type(Undefined)
101{
102}
103
104JavaScriptVariant::JavaScriptVariant(double value)
105    : m_type(Undefined)
106{
107    setDouble(value);
108}
109
110JavaScriptVariant::JavaScriptVariant(int value)
111    : m_type(Undefined)
112{
113    setDouble(value);
114}
115
116JavaScriptVariant::JavaScriptVariant(const BlackBerry::Platform::String& value)
117    : m_type(Undefined)
118{
119    setString(value);
120}
121
122JavaScriptVariant::JavaScriptVariant(bool value)
123    : m_type(Undefined)
124{
125    setBoolean(value);
126}
127
128JavaScriptVariant::JavaScriptVariant(const JavaScriptVariant &v)
129    : m_type(Undefined)
130{
131    this->operator=(v);
132}
133
134JavaScriptVariant::~JavaScriptVariant()
135{
136}
137
138JavaScriptVariant& JavaScriptVariant::operator=(const JavaScriptVariant& v)
139{
140    if (&v == this)
141        return *this;
142
143    switch (v.type()) {
144    case Boolean:
145        setBoolean(v.booleanValue());
146        break;
147    case Number:
148        setDouble(v.doubleValue());
149        break;
150    case String:
151        setString(v.stringValue());
152        break;
153    default:
154        setType(v.type());
155        break;
156    }
157
158    return *this;
159}
160
161void JavaScriptVariant::setType(const DataType& type)
162{
163    if (m_type == String)
164        m_stringValue = BlackBerry::Platform::String::emptyString();
165    m_type = type;
166}
167
168JavaScriptVariant::DataType JavaScriptVariant::type() const
169{
170    return m_type;
171}
172
173void JavaScriptVariant::setDouble(double value)
174{
175    setType(Number);
176    m_doubleValue = value;
177}
178
179double JavaScriptVariant::doubleValue() const
180{
181    return m_doubleValue;
182}
183
184void JavaScriptVariant::setString(const BlackBerry::Platform::String& value)
185{
186    setType(String);
187    m_stringValue = value;
188}
189
190const BlackBerry::Platform::String& JavaScriptVariant::stringValue() const
191{
192    return m_stringValue;
193}
194
195void JavaScriptVariant::setBoolean(bool value)
196{
197    setType(Boolean);
198    m_booleanValue = value;
199}
200
201bool JavaScriptVariant::booleanValue() const
202{
203    return m_booleanValue;
204}
205
206}
207}
208