2 // Tizen Web Device API
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
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
9 // http://www.apache.org/licenses/LICENSE-2.0
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.
21 #include <dpl/log/log.h>
22 #include <CommonsJavaScript/Converter.h>
23 #include <CommonsJavaScript/ScopedJSStringRef.h>
24 #include <JSTizenExceptionFactory.h>
25 #include <JSTizenException.h>
26 #include <CommonsJavaScript/Converter.h>
27 #include "JSNumberArray.h"
29 #define FUNCTION_CONCAT "concat"
30 #define FUNCTION_JOIN "join"
31 #define FUNCTION_POP "pop"
32 #define FUNCTION_PUSH "push"
33 #define FUNCTION_REVERSE "reverse"
34 #define FUNCTION_SHIFT "shift"
35 #define FUNCTION_SLICE "slice"
36 #define FUNCTION_SORT "sort"
37 #define FUNCTION_SPLICE "splice"
38 #define FUNCTION_TOSTRING "toString"
39 #define FUNCTION_UNSHIFT "unshift"
40 #define FUNCTION_VALUEOF "valueOf"
42 #define ATTRIBUTE_LENGTH "length"
48 using namespace DeviceAPI::Common;
49 using namespace WrtDeviceApis::CommonsJavaScript;
51 JSClassDefinition JSNumberArray::m_classInfo = {
53 kJSClassAttributeNone,
63 NULL, //deleteProperty,
65 NULL, //callAsFunction,
66 NULL, //callAsConstructor,
68 NULL, //convertToType,
71 JSStaticValue JSNumberArray::m_property[] = {
72 { ATTRIBUTE_LENGTH, getLength, NULL, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete },
76 JSStaticFunction JSNumberArray::m_function[] = {
77 { FUNCTION_CONCAT, concat, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete },
78 { FUNCTION_JOIN, join, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete },
79 { FUNCTION_POP, pop, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete },
80 { FUNCTION_PUSH, push, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete },
81 { FUNCTION_REVERSE, reverse, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete },
82 { FUNCTION_SHIFT, shift, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete },
83 { FUNCTION_SLICE, slice, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete },
84 { FUNCTION_SORT, sort, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete },
85 { FUNCTION_SPLICE, splice, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete },
86 { FUNCTION_TOSTRING, toString, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete },
87 { FUNCTION_UNSHIFT, unshift, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete },
88 { FUNCTION_VALUEOF, valueOf, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete },
92 JSClassRef JSNumberArray::m_jsClassRef = JSClassCreate(
93 JSNumberArray::getClassInfo());
95 JSValueRef JSNumberArray::getLength(JSContextRef context,
97 JSStringRef propertyName,
98 JSValueRef* exception)
102 JSNumberArrayPriv* priv =
103 static_cast<JSNumberArrayPriv*>(JSObjectGetPrivate(object));
105 Throw(WrtDeviceApis::Commons::NullPointerException);
107 NumberArrayPtr numbers = priv->getObject();
109 WrtDeviceApis::CommonsJavaScript::BasicConverter converter =
110 WrtDeviceApis::CommonsJavaScript::BasicConverterFactory::getConverter(context);
111 return converter->toJSValueRef(numbers->size());
114 Catch(WrtDeviceApis::Commons::Exception)
116 LogError("invalid conversion");
118 return JSValueMakeUndefined(context);
121 JSObjectRef JSNumberArray::createArray(JSContextRef context,
122 const NumberArrayPtr &numbers)
124 JSNumberArrayPriv *priv = new JSNumberArrayPriv(context, numbers);
125 return JSObjectMake(context, getClassRef(), priv);
128 const JSClassDefinition* JSNumberArray::getClassInfo()
130 return &(m_classInfo);
133 JSClassRef JSNumberArray::getClassRef()
136 m_jsClassRef = JSClassCreate(&m_classInfo);
141 bool JSNumberArray::isObjectOfClass(JSContextRef context, JSValueRef value)
143 return JSValueIsObjectOfClass(context, value, getClassRef());
146 NumberArrayPtr JSNumberArray::getNumberArray(JSContextRef context, JSValueRef value)
148 if (!isObjectOfClass(context, value)) {
149 Throw(WrtDeviceApis::Commons::InvalidArgumentException);
151 JSObjectRef object = JSValueToObject(context, value, NULL);
153 Throw(WrtDeviceApis::Commons::InvalidArgumentException);
155 JSNumberArrayPriv* priv = static_cast<JSNumberArrayPriv*>(JSObjectGetPrivate(object));
157 Throw(WrtDeviceApis::Commons::NullPointerException);
159 return priv->getObject();
162 void JSNumberArray::initialize(JSContextRef context,
167 void JSNumberArray::finalize(JSObjectRef object)
169 JSNumberArrayPriv* priv =
170 static_cast<JSNumberArrayPriv*>(JSObjectGetPrivate(object));
172 JSObjectSetPrivate(object, NULL);
175 bool JSNumberArray::hasProperty(JSContextRef context,
177 JSStringRef propertyName)
179 WrtDeviceApis::CommonsJavaScript::BasicConverter converter =
180 WrtDeviceApis::CommonsJavaScript::BasicConverterFactory::getConverter(context);
183 size_t index = converter->toSizeT(propertyName);
184 JSNumberArrayPriv* priv =
185 static_cast<JSNumberArrayPriv*>(JSObjectGetPrivate(object));
187 Throw(WrtDeviceApis::Commons::NullPointerException);
189 NumberArrayPtr numbers = priv->getObject();
190 if (index < numbers->size()) {
194 Catch(WrtDeviceApis::Commons::Exception)
196 //not reporting error is intended
201 JSValueRef JSNumberArray::getProperty(JSContextRef context,
203 JSStringRef propertyName,
204 JSValueRef* exception)
206 WrtDeviceApis::CommonsJavaScript::BasicConverter converter =
207 WrtDeviceApis::CommonsJavaScript::BasicConverterFactory::getConverter(context);
211 size_t index = converter->toSizeT(propertyName);
212 JSNumberArrayPriv* priv =
213 static_cast<JSNumberArrayPriv*>(JSObjectGetPrivate(object));
215 Throw(WrtDeviceApis::Commons::NullPointerException);
217 NumberArrayPtr numbers = priv->getObject();
218 if (index < numbers->size()) {
219 long long int result = numbers->at(index);
220 LogInfo("index: "<<index<<", result: "<<result);
221 return converter->toJSValueRef(result);
224 Catch(WrtDeviceApis::Commons::Exception)
226 LogError("invalid property");
228 return JSValueMakeUndefined(context);
231 bool JSNumberArray::setProperty(JSContextRef context,
233 JSStringRef propertyName,
235 JSValueRef* exception)
237 WrtDeviceApis::CommonsJavaScript::BasicConverter converter =
238 WrtDeviceApis::CommonsJavaScript::BasicConverterFactory::getConverter(context);
242 size_t index = converter->toSizeT(propertyName);
243 long long int number = 0;
244 if (!JSValueIsUndefined(context, value)) {
245 number = converter->toLongLong(value);
247 JSNumberArrayPriv* priv =
248 static_cast<JSNumberArrayPriv*>(JSObjectGetPrivate(object));
250 Throw(WrtDeviceApis::Commons::NullPointerException);
252 NumberArrayPtr numbers = priv->getObject();
254 Throw(WrtDeviceApis::Commons::NullPointerException);
256 if (numbers->size() <= index) {
257 numbers->resize(index + 1);
259 (*numbers)[index] = number;
262 Catch(WrtDeviceApis::Commons::Exception)
264 LogError("error occured");
265 JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type mismatch");
270 void JSNumberArray::getPropertyNames(JSContextRef context,
272 JSPropertyNameAccumulatorRef propertyNames)
274 Converter converter(context);
278 JSNumberArrayPriv* priv =
279 static_cast<JSNumberArrayPriv*>(JSObjectGetPrivate(object));
281 Throw(WrtDeviceApis::Commons::NullPointerException);
283 NumberArrayPtr numbers = priv->getObject();
285 int count = numbers->size();
287 for(int i=0; i < count; i++)
289 ScopedJSStringRef name(converter.toJSStringRef(converter.toString(i)));
290 JSPropertyNameAccumulatorAddName(propertyNames, name.get());
293 Catch(WrtDeviceApis::Commons::Exception)
295 LogError("invalid property");
299 JSValueRef JSNumberArray::concat(JSContextRef context,
300 JSObjectRef function,
301 JSObjectRef thisObject,
302 size_t argumentCount,
303 const JSValueRef arguments[],
304 JSValueRef* exception)
308 NumberArrayPtr numbers = NumberArrayPtr(new NumberArray());
309 JSNumberArrayPriv *newPrivateObject = new JSNumberArrayPriv(
312 JSValueRef result = JSObjectMake(context,
313 getClassRef(), newPrivateObject);
315 //copy current numbers
316 JSNumberArrayPriv* priv =
317 static_cast<JSNumberArrayPriv*>(JSObjectGetPrivate(thisObject));
318 NumberArrayPtr currentNumbers = priv->getObject();
319 for (size_t i = 0; i < currentNumbers->size(); ++i) {
320 numbers->push_back(currentNumbers->at(i));
323 //copy submitted arrays
324 WrtDeviceApis::CommonsJavaScript::BasicConverter converter =
325 WrtDeviceApis::CommonsJavaScript::BasicConverterFactory::getConverter(context);
326 for (size_t i = 0; i < argumentCount; ++i) {
327 if (!JSIsArrayValue(context, arguments[i])) {
328 Throw(WrtDeviceApis::Commons::ConversionException);
330 // process array of numbers
331 JSObjectRef arrayObj = converter->toJSObjectRef(arguments[i]);
332 unsigned int len = JSGetArrayLength(context, arrayObj);
333 for (unsigned int e = 0; e < len; ++e) {
334 JSValueRef att = JSGetArrayElement(context, arrayObj, e);
335 numbers->push_back(converter->toLong(att));
340 Catch(WrtDeviceApis::Commons::Exception)
342 LogError("error occured");
344 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type mismatch");
347 JSValueRef JSNumberArray::join(JSContextRef context,
348 JSObjectRef function,
349 JSObjectRef thisObject,
350 size_t argumentCount,
351 const JSValueRef arguments[],
352 JSValueRef* exception)
357 std::string separator(",");
358 WrtDeviceApis::CommonsJavaScript::BasicConverter converter =
359 WrtDeviceApis::CommonsJavaScript::BasicConverterFactory::getConverter(context);
360 JSNumberArrayPriv* priv = static_cast<JSNumberArrayPriv*>(JSObjectGetPrivate(thisObject));
361 NumberArrayPtr currentNumbers = priv->getObject();
362 if (argumentCount > 0 && JSValueIsString(context, arguments[0])) {
363 separator = converter->toString(arguments[0]);
364 LogDebug("Separator: "<<separator);
366 for (size_t i = 0; i < currentNumbers->size(); ++i) {
370 std::stringstream ss;
371 ss<<currentNumbers->at(i);
374 LogDebug("Resulting string: "<<result);
375 return converter->toJSValueRef(result);
377 Catch(WrtDeviceApis::Commons::Exception)
379 LogError("error occured");
381 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type mismatch");
384 JSValueRef JSNumberArray::pop(JSContextRef context,
385 JSObjectRef function,
386 JSObjectRef thisObject,
387 size_t argumentCount,
388 const JSValueRef arguments[],
389 JSValueRef* exception)
393 WrtDeviceApis::CommonsJavaScript::BasicConverter converter =
394 WrtDeviceApis::CommonsJavaScript::BasicConverterFactory::getConverter(context);
395 JSNumberArrayPriv* priv =
396 static_cast<JSNumberArrayPriv*>(JSObjectGetPrivate(thisObject));
397 NumberArrayPtr currentNumbers = priv->getObject();
398 if (currentNumbers->size() > 0) {
399 long long int result = currentNumbers->at(
400 currentNumbers->size() - 1);
401 currentNumbers->pop_back();
402 return converter->toJSValueRef(result);
405 Catch(WrtDeviceApis::Commons::Exception)
407 LogError("error occured");
409 return JSValueMakeUndefined(context);
412 JSValueRef JSNumberArray::push(JSContextRef context,
413 JSObjectRef function,
414 JSObjectRef thisObject,
415 size_t argumentCount,
416 const JSValueRef arguments[],
417 JSValueRef* exception)
421 WrtDeviceApis::CommonsJavaScript::BasicConverter converter =
422 WrtDeviceApis::CommonsJavaScript::BasicConverterFactory::getConverter(context);
423 JSNumberArrayPriv* priv =
424 static_cast<JSNumberArrayPriv*>(JSObjectGetPrivate(thisObject));
425 NumberArrayPtr currentNumbers = priv->getObject();
426 for (size_t i = 0; i < argumentCount; ++i) {
427 currentNumbers->push_back(converter->toLong(arguments[i]));
429 return converter->toJSValueRef(currentNumbers->size());
431 Catch(WrtDeviceApis::Commons::Exception)
433 LogError("error occured");
435 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type mismatch");
438 JSValueRef JSNumberArray::reverse(JSContextRef context,
439 JSObjectRef function,
440 JSObjectRef thisObject,
441 size_t argumentCount,
442 const JSValueRef arguments[],
443 JSValueRef* exception)
447 WrtDeviceApis::CommonsJavaScript::BasicConverter converter =
448 WrtDeviceApis::CommonsJavaScript::BasicConverterFactory::getConverter(context);
449 JSNumberArrayPriv* priv =
450 static_cast<JSNumberArrayPriv*>(JSObjectGetPrivate(thisObject));
451 NumberArrayPtr currentNumbers = priv->getObject();
452 std::reverse(currentNumbers->begin(), currentNumbers->end());
455 Catch(WrtDeviceApis::Commons::Exception)
457 LogError("error occured");
459 return JSValueMakeUndefined(context);
462 JSValueRef JSNumberArray::shift(JSContextRef context,
463 JSObjectRef function,
464 JSObjectRef thisObject,
465 size_t argumentCount,
466 const JSValueRef arguments[],
467 JSValueRef* exception)
471 WrtDeviceApis::CommonsJavaScript::BasicConverter converter =
472 WrtDeviceApis::CommonsJavaScript::BasicConverterFactory::getConverter(context);
473 JSNumberArrayPriv* priv =
474 static_cast<JSNumberArrayPriv*>(JSObjectGetPrivate(thisObject));
475 NumberArrayPtr currentNumbers = priv->getObject();
476 if (currentNumbers->size() > 0) {
477 long long int result = currentNumbers->at(0);
478 currentNumbers->erase(currentNumbers->begin());
479 return converter->toJSValueRef(result);
482 Catch(WrtDeviceApis::Commons::Exception)
484 LogError("error occured");
486 return JSValueMakeUndefined(context);
489 JSValueRef JSNumberArray::slice(JSContextRef context,
490 JSObjectRef function,
491 JSObjectRef thisObject,
492 size_t argumentCount,
493 const JSValueRef arguments[],
494 JSValueRef* exception)
498 if (argumentCount < 1) {
499 return JSValueMakeUndefined(context);
501 WrtDeviceApis::CommonsJavaScript::BasicConverter converter =
502 WrtDeviceApis::CommonsJavaScript::BasicConverterFactory::getConverter(context);
503 NumberArrayPtr numbers = NumberArrayPtr(new NumberArray());
504 JSNumberArrayPriv *newPrivateObject = new JSNumberArrayPriv(
507 JSValueRef result = JSObjectMake(context,
508 getClassRef(), newPrivateObject);
510 //copy current numbers
511 JSNumberArrayPriv* priv =
512 static_cast<JSNumberArrayPriv*>(JSObjectGetPrivate(thisObject));
513 NumberArrayPtr currentNumbers = priv->getObject();
514 std::size_t first = converter->toSizeT(arguments[0]);
515 std::size_t last = currentNumbers->size() - 1;
516 if (argumentCount > 1) {
517 last = converter->toSizeT(arguments[1]);
518 if (last >= currentNumbers->size()) {
519 last = currentNumbers->size() - 1;
522 for (size_t i = first; i <= last; ++i) {
523 numbers->push_back(currentNumbers->at(i));
528 Catch(WrtDeviceApis::Commons::Exception)
530 LogError("error occured");
532 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type mismatch");
535 JSValueRef JSNumberArray::sort(JSContextRef context,
536 JSObjectRef function,
537 JSObjectRef thisObject,
538 size_t argumentCount,
539 const JSValueRef arguments[],
540 JSValueRef* exception)
544 WrtDeviceApis::CommonsJavaScript::BasicConverter converter =
545 WrtDeviceApis::CommonsJavaScript::BasicConverterFactory::getConverter(context);
546 JSNumberArrayPriv* priv =
547 static_cast<JSNumberArrayPriv*>(JSObjectGetPrivate(thisObject));
548 NumberArrayPtr currentNumbers = priv->getObject();
549 std::sort(currentNumbers->begin(), currentNumbers->end());
552 Catch(WrtDeviceApis::Commons::Exception)
554 LogError("error occured");
556 return JSValueMakeUndefined(context);
559 JSValueRef JSNumberArray::splice(JSContextRef context,
560 JSObjectRef function,
561 JSObjectRef thisObject,
562 size_t argumentCount,
563 const JSValueRef arguments[],
564 JSValueRef* exception)
566 return JSValueMakeUndefined(context);
569 JSValueRef JSNumberArray::toString(JSContextRef context,
570 JSObjectRef function,
571 JSObjectRef thisObject,
572 size_t argumentCount,
573 const JSValueRef arguments[],
574 JSValueRef* exception)
576 return join(context, function, thisObject, 0, arguments, exception);
579 JSValueRef JSNumberArray::unshift(JSContextRef context,
580 JSObjectRef function,
581 JSObjectRef thisObject,
582 size_t argumentCount,
583 const JSValueRef arguments[],
584 JSValueRef* exception)
586 return JSValueMakeUndefined(context);
589 JSValueRef JSNumberArray::valueOf(JSContextRef context,
590 JSObjectRef function,
591 JSObjectRef thisObject,
592 size_t argumentCount,
593 const JSValueRef arguments[],
594 JSValueRef* exception)
596 return JSValueMakeUndefined(context);