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 "JSTZDateArray.h"
28 #include <TimeUtilConverter.h>
30 #define FUNCTION_CONCAT "concat"
31 #define FUNCTION_JOIN "join"
32 #define FUNCTION_POP "pop"
33 #define FUNCTION_PUSH "push"
34 #define FUNCTION_REVERSE "reverse"
35 #define FUNCTION_SHIFT "shift"
36 #define FUNCTION_SLICE "slice"
37 #define FUNCTION_SORT "sort"
38 #define FUNCTION_SPLICE "splice"
39 #define FUNCTION_TOSTRING "toString"
40 #define FUNCTION_UNSHIFT "unshift"
41 #define FUNCTION_VALUEOF "valueOf"
43 #define ATTRIBUTE_LENGTH "length"
49 using namespace DeviceAPI::Common;
50 using namespace DeviceAPI::Time;
51 using namespace WrtDeviceApis::CommonsJavaScript;
53 JSClassDefinition JSTZDateArray::m_classInfo = {
55 kJSClassAttributeNone,
65 NULL, //deleteProperty,
67 NULL, //callAsFunction,
68 NULL, //callAsConstructor,
70 NULL, //convertToType,
73 JSStaticValue JSTZDateArray::m_property[] = {
74 { ATTRIBUTE_LENGTH, getLength, NULL, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete },
78 JSStaticFunction JSTZDateArray::m_function[] = {
79 { FUNCTION_CONCAT, concat, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete },
80 { FUNCTION_JOIN, join, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete },
81 { FUNCTION_POP, pop, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete },
82 { FUNCTION_PUSH, push, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete },
83 { FUNCTION_REVERSE, reverse, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete },
84 { FUNCTION_SHIFT, shift, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete },
85 { FUNCTION_SLICE, slice, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete },
86 { FUNCTION_SORT, sort, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete },
87 { FUNCTION_SPLICE, splice, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete },
88 { FUNCTION_TOSTRING, toString, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete },
89 { FUNCTION_UNSHIFT, unshift, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete },
90 { FUNCTION_VALUEOF, valueOf, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete },
94 JSClassRef JSTZDateArray::m_jsClassRef = JSClassCreate(
95 JSTZDateArray::getClassInfo());
97 JSValueRef JSTZDateArray::getLength(JSContextRef context,
99 JSStringRef propertyName,
100 JSValueRef* exception)
104 JSTZDateArrayPriv* priv =
105 static_cast<JSTZDateArrayPriv*>(JSObjectGetPrivate(object));
107 Throw(WrtDeviceApis::Commons::NullPointerException);
109 NumberArrayPtr numbers = priv->getObject();
111 WrtDeviceApis::CommonsJavaScript::BasicConverter converter =
112 WrtDeviceApis::CommonsJavaScript::BasicConverterFactory::getConverter(context);
113 return converter->toJSValueRef(numbers->size());
116 Catch(WrtDeviceApis::Commons::Exception)
118 LogError("invalid conversion");
120 return JSValueMakeUndefined(context);
123 JSObjectRef JSTZDateArray::createArray(JSContextRef context,
124 const NumberArrayPtr &numbers)
126 JSTZDateArrayPriv *priv = new JSTZDateArrayPriv(context, numbers);
127 return JSObjectMake(context, getClassRef(), priv);
130 const JSClassDefinition* JSTZDateArray::getClassInfo()
132 return &(m_classInfo);
135 JSClassRef JSTZDateArray::getClassRef()
138 m_jsClassRef = JSClassCreate(&m_classInfo);
143 bool JSTZDateArray::isObjectOfClass(JSContextRef context, JSValueRef value)
145 return JSValueIsObjectOfClass(context, value, getClassRef());
148 NumberArrayPtr JSTZDateArray::getTZDateArray(JSContextRef context, JSValueRef value)
150 if (!isObjectOfClass(context, value)) {
151 Throw(WrtDeviceApis::Commons::InvalidArgumentException);
153 JSObjectRef object = JSValueToObject(context, value, NULL);
155 Throw(WrtDeviceApis::Commons::InvalidArgumentException);
157 JSTZDateArrayPriv* priv = static_cast<JSTZDateArrayPriv*>(JSObjectGetPrivate(object));
159 Throw(WrtDeviceApis::Commons::NullPointerException);
161 return priv->getObject();
164 void JSTZDateArray::initialize(JSContextRef context,
169 void JSTZDateArray::finalize(JSObjectRef object)
171 JSTZDateArrayPriv* priv =
172 static_cast<JSTZDateArrayPriv*>(JSObjectGetPrivate(object));
174 JSObjectSetPrivate(object, NULL);
177 bool JSTZDateArray::hasProperty(JSContextRef context,
179 JSStringRef propertyName)
181 WrtDeviceApis::CommonsJavaScript::BasicConverter converter =
182 WrtDeviceApis::CommonsJavaScript::BasicConverterFactory::getConverter(context);
185 size_t index = converter->toSizeT(propertyName);
186 JSTZDateArrayPriv* priv =
187 static_cast<JSTZDateArrayPriv*>(JSObjectGetPrivate(object));
189 Throw(WrtDeviceApis::Commons::NullPointerException);
191 NumberArrayPtr numbers = priv->getObject();
192 if (index < numbers->size()) {
196 Catch(WrtDeviceApis::Commons::Exception)
198 //not reporting error is intended
203 JSValueRef JSTZDateArray::getProperty(JSContextRef context,
205 JSStringRef propertyName,
206 JSValueRef* exception)
208 WrtDeviceApis::CommonsJavaScript::BasicConverter converter =
209 WrtDeviceApis::CommonsJavaScript::BasicConverterFactory::getConverter(context);
210 TimeUtilConverter timeConverter(context);
214 size_t index = converter->toSizeT(propertyName);
215 JSTZDateArrayPriv* priv =
216 static_cast<JSTZDateArrayPriv*>(JSObjectGetPrivate(object));
218 Throw(WrtDeviceApis::Commons::NullPointerException);
220 NumberArrayPtr numbers = priv->getObject();
221 if (index < numbers->size()) {
222 long long int result = numbers->at(index);
223 LogInfo("index: "<<index<<", result: "<<result);
224 return timeConverter.toJSValueRefTZDate((double)(result*1000.0), "");
227 Catch(WrtDeviceApis::Commons::Exception)
229 LogError("invalid property");
231 return JSValueMakeUndefined(context);
234 bool JSTZDateArray::setProperty(JSContextRef context,
236 JSStringRef propertyName,
238 JSValueRef* exception)
240 WrtDeviceApis::CommonsJavaScript::BasicConverter converter =
241 WrtDeviceApis::CommonsJavaScript::BasicConverterFactory::getConverter(context);
242 TimeUtilConverter timeConverter(context);
246 size_t index = converter->toSizeT(propertyName);
247 long long int number = 0;
248 if (!JSValueIsUndefined(context, value)) {
249 number = timeConverter.getTimeInMilliseconds(value)/1000;
251 JSTZDateArrayPriv* priv =
252 static_cast<JSTZDateArrayPriv*>(JSObjectGetPrivate(object));
254 Throw(WrtDeviceApis::Commons::NullPointerException);
256 NumberArrayPtr numbers = priv->getObject();
258 Throw(WrtDeviceApis::Commons::NullPointerException);
260 if (numbers->size() <= index) {
261 numbers->resize(index + 1);
263 (*numbers)[index] = number;
266 Catch(WrtDeviceApis::Commons::Exception)
268 LogError("error occured");
269 JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type mismatch");
274 void JSTZDateArray::getPropertyNames(JSContextRef context,
276 JSPropertyNameAccumulatorRef propertyNames)
278 Converter converter(context);
282 JSTZDateArrayPriv* priv =
283 static_cast<JSTZDateArrayPriv*>(JSObjectGetPrivate(object));
285 Throw(WrtDeviceApis::Commons::NullPointerException);
287 NumberArrayPtr numbers = priv->getObject();
289 int count = numbers->size();
291 for(int i=0; i < count; i++)
293 ScopedJSStringRef name(converter.toJSStringRef(converter.toString(i)));
294 JSPropertyNameAccumulatorAddName(propertyNames, name.get());
297 Catch(WrtDeviceApis::Commons::Exception)
299 LogError("invalid property");
303 JSValueRef JSTZDateArray::concat(JSContextRef context,
304 JSObjectRef function,
305 JSObjectRef thisObject,
306 size_t argumentCount,
307 const JSValueRef arguments[],
308 JSValueRef* exception)
312 NumberArrayPtr numbers = NumberArrayPtr(new NumberArray());
313 JSTZDateArrayPriv *newPrivateObject = new JSTZDateArrayPriv(
316 JSValueRef result = JSObjectMake(context, getClassRef(), newPrivateObject);
318 //copy current numbers
319 JSTZDateArrayPriv* priv =
320 static_cast<JSTZDateArrayPriv*>(JSObjectGetPrivate(thisObject));
321 NumberArrayPtr currentNumbers = priv->getObject();
322 for (size_t i = 0; i < currentNumbers->size(); ++i) {
323 numbers->push_back(currentNumbers->at(i));
326 //copy submitted arrays
327 WrtDeviceApis::CommonsJavaScript::BasicConverter converter =
328 WrtDeviceApis::CommonsJavaScript::BasicConverterFactory::getConverter(context);
329 TimeUtilConverter timeConverter(context);
330 for (size_t i = 0; i < argumentCount; ++i) {
331 if (!JSIsArrayValue(context, arguments[i])) {
332 Throw(WrtDeviceApis::Commons::ConversionException);
334 // process array of numbers
335 JSObjectRef arrayObj = converter->toJSObjectRef(arguments[i]);
336 unsigned int len = JSGetArrayLength(context, arrayObj);
337 for (unsigned int e = 0; e < len; ++e) {
338 JSValueRef att = JSGetArrayElement(context, arrayObj, e);
340 long long int number = 0;
341 if (!JSValueIsUndefined(context, att)) {
342 number = timeConverter.getTimeInMilliseconds(att)/1000;
344 LogDebug("Concatenating a number: "<<number);
345 numbers->push_back(number);
350 Catch(WrtDeviceApis::Commons::Exception)
352 LogError("error occured");
354 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type mismatch");
357 JSValueRef JSTZDateArray::join(JSContextRef context,
358 JSObjectRef function,
359 JSObjectRef thisObject,
360 size_t argumentCount,
361 const JSValueRef arguments[],
362 JSValueRef* exception)
367 std::string separator(",");
368 WrtDeviceApis::CommonsJavaScript::BasicConverter converter =
369 WrtDeviceApis::CommonsJavaScript::BasicConverterFactory::getConverter(context);
370 JSTZDateArrayPriv* priv = static_cast<JSTZDateArrayPriv*>(JSObjectGetPrivate(thisObject));
371 TimeUtilConverter timeConverter(context);
373 NumberArrayPtr currentNumbers = priv->getObject();
374 if (argumentCount > 0 && JSValueIsString(context, arguments[0])) {
375 separator = converter->toString(arguments[0]);
376 LogDebug("Separator: "<<separator);
378 for (size_t i = 0; i < currentNumbers->size(); ++i) {
382 std::stringstream ss;
383 ss<<currentNumbers->at(i);
386 LogDebug("Resulting string: "<<result);
387 return converter->toJSValueRef(result);
389 Catch(WrtDeviceApis::Commons::Exception)
391 LogError("error occured");
393 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type mismatch");
396 JSValueRef JSTZDateArray::pop(JSContextRef context,
397 JSObjectRef function,
398 JSObjectRef thisObject,
399 size_t argumentCount,
400 const JSValueRef arguments[],
401 JSValueRef* exception)
405 TimeUtilConverter timeConverter(context);
407 JSTZDateArrayPriv* priv = static_cast<JSTZDateArrayPriv*>(JSObjectGetPrivate(thisObject));
408 NumberArrayPtr currentNumbers = priv->getObject();
409 if (currentNumbers->size() > 0) {
410 long long int result = currentNumbers->at(currentNumbers->size() - 1);
411 currentNumbers->pop_back();
412 return timeConverter.toJSValueRefTZDate((double)(result*1000.0), "");
415 Catch(WrtDeviceApis::Commons::Exception)
417 LogError("error occured");
419 return JSValueMakeUndefined(context);
422 JSValueRef JSTZDateArray::push(JSContextRef context,
423 JSObjectRef function,
424 JSObjectRef thisObject,
425 size_t argumentCount,
426 const JSValueRef arguments[],
427 JSValueRef* exception)
431 TimeUtilConverter timeConverter(context);
433 JSTZDateArrayPriv* priv = static_cast<JSTZDateArrayPriv*>(JSObjectGetPrivate(thisObject));
434 NumberArrayPtr currentNumbers = priv->getObject();
435 for (size_t i = 0; i < argumentCount; ++i) {
436 long long int number = 0;
437 if (!JSValueIsUndefined(context, arguments[i])) {
438 number = timeConverter.getTimeInMilliseconds(arguments[i])/1000;
440 LogDebug("Pushing a TZDate number: "<<number<<" for index: "<<i);
441 currentNumbers->push_back(number);
443 return timeConverter.toJSValueRef(currentNumbers->size());
445 Catch(WrtDeviceApis::Commons::Exception)
447 LogError("error occured");
449 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type mismatch");
452 JSValueRef JSTZDateArray::reverse(JSContextRef context,
453 JSObjectRef function,
454 JSObjectRef thisObject,
455 size_t argumentCount,
456 const JSValueRef arguments[],
457 JSValueRef* exception)
461 WrtDeviceApis::CommonsJavaScript::BasicConverter converter =
462 WrtDeviceApis::CommonsJavaScript::BasicConverterFactory::getConverter(context);
463 JSTZDateArrayPriv* priv =
464 static_cast<JSTZDateArrayPriv*>(JSObjectGetPrivate(thisObject));
465 NumberArrayPtr currentNumbers = priv->getObject();
466 std::reverse(currentNumbers->begin(), currentNumbers->end());
469 Catch(WrtDeviceApis::Commons::Exception)
471 LogError("error occured");
473 return JSValueMakeUndefined(context);
476 JSValueRef JSTZDateArray::shift(JSContextRef context,
477 JSObjectRef function,
478 JSObjectRef thisObject,
479 size_t argumentCount,
480 const JSValueRef arguments[],
481 JSValueRef* exception)
485 WrtDeviceApis::CommonsJavaScript::BasicConverter converter =
486 WrtDeviceApis::CommonsJavaScript::BasicConverterFactory::getConverter(context);
487 JSTZDateArrayPriv* priv =
488 static_cast<JSTZDateArrayPriv*>(JSObjectGetPrivate(thisObject));
489 NumberArrayPtr currentNumbers = priv->getObject();
490 if (currentNumbers->size() > 0) {
491 long long int result = currentNumbers->at(0);
492 currentNumbers->erase(currentNumbers->begin());
493 return converter->toJSValueRef(result);
496 Catch(WrtDeviceApis::Commons::Exception)
498 LogError("error occured");
500 return JSValueMakeUndefined(context);
503 JSValueRef JSTZDateArray::slice(JSContextRef context,
504 JSObjectRef function,
505 JSObjectRef thisObject,
506 size_t argumentCount,
507 const JSValueRef arguments[],
508 JSValueRef* exception)
512 if (argumentCount < 1) {
513 return JSValueMakeUndefined(context);
515 WrtDeviceApis::CommonsJavaScript::BasicConverter converter =
516 WrtDeviceApis::CommonsJavaScript::BasicConverterFactory::getConverter(context);
517 NumberArrayPtr numbers = NumberArrayPtr(new NumberArray());
518 JSTZDateArrayPriv *newPrivateObject = new JSTZDateArrayPriv(context, numbers);
519 JSValueRef result = JSObjectMake(context, getClassRef(), newPrivateObject);
521 //copy current numbers
522 JSTZDateArrayPriv* priv = static_cast<JSTZDateArrayPriv*>(JSObjectGetPrivate(thisObject));
523 NumberArrayPtr currentNumbers = priv->getObject();
524 std::size_t first = converter->toSizeT(arguments[0]);
525 std::size_t last = currentNumbers->size() - 1;
526 if (argumentCount > 1) {
527 last = converter->toSizeT(arguments[1]);
528 if (last >= currentNumbers->size()) {
529 last = currentNumbers->size() - 1;
533 for (size_t i = first; i <= last; ++i) {
534 numbers->push_back(currentNumbers->at(i));
539 Catch(WrtDeviceApis::Commons::Exception)
541 LogError("error occured");
543 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type mismatch");
546 JSValueRef JSTZDateArray::sort(JSContextRef context,
547 JSObjectRef function,
548 JSObjectRef thisObject,
549 size_t argumentCount,
550 const JSValueRef arguments[],
551 JSValueRef* exception)
555 WrtDeviceApis::CommonsJavaScript::BasicConverter converter =
556 WrtDeviceApis::CommonsJavaScript::BasicConverterFactory::getConverter(context);
557 JSTZDateArrayPriv* priv =
558 static_cast<JSTZDateArrayPriv*>(JSObjectGetPrivate(thisObject));
559 NumberArrayPtr currentNumbers = priv->getObject();
560 std::sort(currentNumbers->begin(), currentNumbers->end());
563 Catch(WrtDeviceApis::Commons::Exception)
565 LogError("error occured");
567 return JSValueMakeUndefined(context);
570 JSValueRef JSTZDateArray::splice(JSContextRef context,
571 JSObjectRef function,
572 JSObjectRef thisObject,
573 size_t argumentCount,
574 const JSValueRef arguments[],
575 JSValueRef* exception)
577 return JSValueMakeUndefined(context);
580 JSValueRef JSTZDateArray::toString(JSContextRef context,
581 JSObjectRef function,
582 JSObjectRef thisObject,
583 size_t argumentCount,
584 const JSValueRef arguments[],
585 JSValueRef* exception)
587 return join(context, function, thisObject, 0, arguments, exception);
590 JSValueRef JSTZDateArray::unshift(JSContextRef context,
591 JSObjectRef function,
592 JSObjectRef thisObject,
593 size_t argumentCount,
594 const JSValueRef arguments[],
595 JSValueRef* exception)
597 return JSValueMakeUndefined(context);
600 JSValueRef JSTZDateArray::valueOf(JSContextRef context,
601 JSObjectRef function,
602 JSObjectRef thisObject,
603 size_t argumentCount,
604 const JSValueRef arguments[],
605 JSValueRef* exception)
607 return JSValueMakeUndefined(context);