Update change log and spec for wrt-plugins-tizen_0.2.84
[framework/web/wrt-plugins-tizen.git] / src / standards / Tizen / Calendar / JSStringArray.cpp
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17
18 #include <algorithm>
19 #include <dpl/log/log.h>
20 #include <CommonsJavaScript/Converter.h>
21 #include <CommonsJavaScript/ScopedJSStringRef.h>
22 #include <Tizen/Common/JSTizenExceptionFactory.h>
23 #include <Tizen/Common/JSTizenException.h>
24 #include "CalendarConverter.h"
25 #include "JSStringArray.h"
26
27 #define FUNCTION_CONCAT "concat"
28 #define FUNCTION_JOIN "join"
29 #define FUNCTION_POP "pop"
30 #define FUNCTION_PUSH "push"
31 #define FUNCTION_REVERSE "reverse"
32 #define FUNCTION_SHIFT "shift"
33 #define FUNCTION_SLICE "slice"
34 #define FUNCTION_SORT "sort"
35 #define FUNCTION_SPLICE "splice"
36 #define FUNCTION_TOSTRING "toString"
37 #define FUNCTION_UNSHIFT "unshift"
38 #define FUNCTION_VALUEOF "valueOf"
39 #define ARRAY "Array"
40 #define ATTRIBUTE_LENGTH "length"
41
42 namespace TizenApis {
43 namespace Tizen1_0 {
44 namespace Calendar {
45
46 using namespace TizenApis::Api::Calendar;
47 using namespace TizenApis::Commons;
48 using namespace WrtDeviceApis::CommonsJavaScript;
49
50 JSClassDefinition JSStringArray::m_classInfo = {
51         0,
52         kJSClassAttributeNone,
53         ARRAY,
54         0,
55         m_property,
56         m_function,
57         initialize,
58         finalize,
59         hasProperty,
60         getProperty,
61         setProperty,
62         NULL, //deleteProperty,
63         getPropertyNames,
64         NULL, //callAsFunction,
65         NULL, //callAsConstructor,
66         NULL, //hasInstance,
67         NULL, //convertToType,
68 };
69
70 JSStaticValue JSStringArray::m_property[] = {
71         { ATTRIBUTE_LENGTH, getLength, NULL, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete },
72         { 0, 0, 0, 0 }
73 };
74
75 JSStaticFunction JSStringArray::m_function[] = {
76         { FUNCTION_CONCAT, concat, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete },
77         { FUNCTION_JOIN, join, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete },
78         { FUNCTION_POP, pop, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete },
79         { FUNCTION_PUSH, push, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete },
80         { FUNCTION_REVERSE, reverse, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete },
81         { FUNCTION_SHIFT, shift, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete },
82         { FUNCTION_SLICE, slice, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete },
83         { FUNCTION_SORT, sort, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete },
84         { FUNCTION_SPLICE, splice, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete },
85         { FUNCTION_TOSTRING, toString, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete },
86         { FUNCTION_UNSHIFT, unshift, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete },
87         { FUNCTION_VALUEOF, valueOf, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete },
88         { 0, 0, 0 }
89 };
90
91 JSClassRef JSStringArray::m_jsClassRef = JSClassCreate(
92                 JSStringArray::getClassInfo());
93
94 JSValueRef JSStringArray::getLength(JSContextRef context,
95                 JSObjectRef object,
96                 JSStringRef propertyName,
97                 JSValueRef* exception)
98 {
99         Try
100         {
101                 JSStringArrayPriv* priv =
102                         static_cast<JSStringArrayPriv*>(JSObjectGetPrivate(object));
103                 if (!priv) {
104                         Throw(WrtDeviceApis::Commons::NullPointerException);
105                 }
106                 StringArrayPtr strs = priv->getObject();
107                 if (strs) {
108                         WrtDeviceApis::CommonsJavaScript::BasicConverter converter =
109                                         WrtDeviceApis::CommonsJavaScript::BasicConverterFactory::getConverter(context);
110                         return converter->toJSValueRef(strs->size());
111                 }
112         }
113         Catch(WrtDeviceApis::Commons::Exception)
114         {
115                 LogError("invalid conversion");
116         }
117         return JSValueMakeUndefined(context);
118 }
119
120 JSObjectRef JSStringArray::createArray(JSContextRef context,
121                 const StringArrayPtr &strs)
122 {
123         JSStringArrayPriv *priv = new JSStringArrayPriv(context, strs);
124         return JSObjectMake(context, getClassRef(), priv);
125 }
126
127 const JSClassDefinition* JSStringArray::getClassInfo()
128 {
129         return &(m_classInfo);
130 }
131
132 JSClassRef JSStringArray::getClassRef()
133 {
134         if (!m_jsClassRef) {
135                 m_jsClassRef = JSClassCreate(&m_classInfo);
136         }
137         return m_jsClassRef;
138 }
139
140 bool JSStringArray::isObjectOfClass(JSContextRef context, JSValueRef value)
141 {
142         return JSValueIsObjectOfClass(context, value, getClassRef());
143 }
144
145 StringArrayPtr JSStringArray::getStringArray(JSContextRef context, JSValueRef value)
146 {
147         if (!isObjectOfClass(context, value)) {
148                 Throw(WrtDeviceApis::Commons::InvalidArgumentException);
149         }
150         JSObjectRef object = JSValueToObject(context, value, NULL);
151         if (!object) {
152                 Throw(WrtDeviceApis::Commons::InvalidArgumentException);
153         }
154         JSStringArrayPriv* priv = static_cast<JSStringArrayPriv*>(JSObjectGetPrivate(object));
155         if (!priv) {
156                 Throw(WrtDeviceApis::Commons::NullPointerException);
157         }
158         return priv->getObject();
159 }
160
161 void JSStringArray::initialize(JSContextRef context,
162                 JSObjectRef object)
163 {
164 }
165
166 void JSStringArray::finalize(JSObjectRef object)
167 {
168         JSStringArrayPriv* priv =
169                 static_cast<JSStringArrayPriv*>(JSObjectGetPrivate(object));
170         delete priv;
171         JSObjectSetPrivate(object, NULL);
172 }
173
174 bool JSStringArray::hasProperty(JSContextRef context,
175                 JSObjectRef object,
176                 JSStringRef propertyName)
177 {
178         WrtDeviceApis::CommonsJavaScript::BasicConverter converter =
179                         WrtDeviceApis::CommonsJavaScript::BasicConverterFactory::getConverter(context);
180         Try
181         {
182                 size_t index = converter->toSizeT(propertyName);
183                 JSStringArrayPriv* priv =
184                         static_cast<JSStringArrayPriv*>(JSObjectGetPrivate(object));
185                 if (!priv) {
186                         Throw(WrtDeviceApis::Commons::NullPointerException);
187                 }
188                 StringArrayPtr strs = priv->getObject();
189                 if (index < strs->size()) {
190                         return true;
191                 }
192         }
193         Catch(WrtDeviceApis::Commons::Exception)
194         {
195                 //not reporting error is intended
196         }
197         return false;
198 }
199
200 JSValueRef JSStringArray::getProperty(JSContextRef context,
201                 JSObjectRef object,
202                 JSStringRef propertyName,
203                 JSValueRef* exception)
204 {
205         WrtDeviceApis::CommonsJavaScript::BasicConverter converter =
206                         WrtDeviceApis::CommonsJavaScript::BasicConverterFactory::getConverter(context);
207         Try
208         {
209                 size_t index = converter->toSizeT(propertyName);
210                 JSStringArrayPriv* priv =
211                         static_cast<JSStringArrayPriv*>(JSObjectGetPrivate(object));
212                 if (!priv) {
213                         Throw(WrtDeviceApis::Commons::NullPointerException);
214                 }
215                 StringArrayPtr strs = priv->getObject();
216                 if (index < strs->size()) {
217                         std::string result = strs->at(index);
218                         if (!result.empty()) {
219                                 return converter->toJSValueRef(result);
220                         }
221                 }
222         }
223         Catch(WrtDeviceApis::Commons::Exception)
224         {
225                 LogError("invalid property");
226         }
227         return JSValueMakeUndefined(context);
228 }
229
230 bool JSStringArray::setProperty(JSContextRef context,
231                 JSObjectRef object,
232                 JSStringRef propertyName,
233                 JSValueRef value,
234                 JSValueRef* exception)
235 {
236         WrtDeviceApis::CommonsJavaScript::BasicConverter converter =
237                         WrtDeviceApis::CommonsJavaScript::BasicConverterFactory::getConverter(context);
238         Try
239         {
240                 size_t index = converter->toSizeT(propertyName);
241                 std::string str;
242                 if (!JSValueIsUndefined(context, value)) {
243                         str = converter->toString(value);
244                 }
245                 JSStringArrayPriv* priv =
246                         static_cast<JSStringArrayPriv*>(JSObjectGetPrivate(object));
247                 if (!priv) {
248                         Throw(WrtDeviceApis::Commons::NullPointerException);
249                 }
250                 StringArrayPtr strs = priv->getObject();
251                 if (!strs) {
252                         Throw(WrtDeviceApis::Commons::NullPointerException);
253                 }
254                 if (strs->size() <= index) {
255                         strs->resize(index + 1);
256                 }
257                 (*strs)[index] = str;
258                 return true;
259         }
260         Catch(WrtDeviceApis::Commons::Exception)
261         {
262                 LogError("error occured");
263                 JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type mismatch");
264         }
265         return false;
266 }
267
268 void JSStringArray::getPropertyNames(JSContextRef context,
269                 JSObjectRef object,
270                 JSPropertyNameAccumulatorRef propertyNames)
271 {
272     CalendarConverter converter(context);
273
274         Try
275         {
276                 JSStringArrayPriv* priv =
277                         static_cast<JSStringArrayPriv*>(JSObjectGetPrivate(object));
278                 if (!priv) {
279                         Throw(WrtDeviceApis::Commons::NullPointerException);
280                 }
281                 StringArrayPtr strings = priv->getObject();
282
283                 int count = strings->size();
284
285                 for(int i=0; i < count; i++)
286                 {
287                         ScopedJSStringRef name(converter.toJSStringRef(converter.toString(i)));
288                         JSPropertyNameAccumulatorAddName(propertyNames, name.get());
289                 }
290         }
291         Catch(WrtDeviceApis::Commons::Exception)
292         {
293                 LogError("invalid property");
294         }
295 }
296
297 JSValueRef JSStringArray::concat(JSContextRef context,
298                 JSObjectRef function,
299                 JSObjectRef thisObject,
300                 size_t argumentCount,
301                 const JSValueRef arguments[],
302                 JSValueRef* exception)
303 {
304         Try
305         {
306                 StringArrayPtr strs = StringArrayPtr(new StringArray());
307                 JSStringArrayPriv *newPrivateObject = new JSStringArrayPriv(
308                                 context,
309                                 strs);
310                 JSValueRef result = JSObjectMake(context,
311                                                                                  getClassRef(), newPrivateObject);
312
313                 //copy current strs
314                 JSStringArrayPriv* priv =
315                         static_cast<JSStringArrayPriv*>(JSObjectGetPrivate(thisObject));
316                 StringArrayPtr currentStrings = priv->getObject();
317                 for (size_t i = 0; i < currentStrings->size(); ++i) {
318                         strs->push_back(currentStrings->at(i));
319                 }
320
321                 //copy submitted arrays
322                 WrtDeviceApis::CommonsJavaScript::BasicConverter converter =
323                                 WrtDeviceApis::CommonsJavaScript::BasicConverterFactory::getConverter(context);
324                 for (size_t i = 0; i < argumentCount; ++i) {
325                         if (!JSIsArrayValue(context, arguments[i])) {
326                                 Throw(WrtDeviceApis::Commons::ConversionException);
327                         }
328                         // process array of strings
329                         JSObjectRef arrayObj = converter->toJSObjectRef(arguments[i]);
330                         unsigned int len = JSGetArrayLength(context, arrayObj);
331                         for (unsigned int e = 0; e < len; ++e) {
332                                 JSValueRef att = JSGetArrayElement(context, arrayObj, e);
333                                 strs->push_back(converter->toString(att));
334                         }
335                 }
336                 return result;
337         }
338         Catch(WrtDeviceApis::Commons::Exception)
339         {
340                 LogError("error occured");
341         }
342         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type mismatch");
343 }
344
345 JSValueRef JSStringArray::join(JSContextRef context,
346                 JSObjectRef function,
347                 JSObjectRef thisObject,
348                 size_t argumentCount,
349                 const JSValueRef arguments[],
350                 JSValueRef* exception)
351 {
352         Try
353         {
354                 std::string result;
355                 std::string separator(",");
356                 WrtDeviceApis::CommonsJavaScript::BasicConverter converter =
357                                 WrtDeviceApis::CommonsJavaScript::BasicConverterFactory::getConverter(context);
358                 JSStringArrayPriv* priv =
359                         static_cast<JSStringArrayPriv*>(JSObjectGetPrivate(thisObject));
360                 StringArrayPtr currentStrings = priv->getObject();
361                 if (argumentCount > 0 && JSValueIsString(context, arguments[0])) {
362                         separator = converter->toString(arguments[0]);
363                 }
364                 for (size_t i = 0; i < currentStrings->size(); ++i) {
365                         if (i != 0) {
366                                 result += separator;
367                         }
368                         result += currentStrings->at(i);
369                 }
370                 return converter->toJSValueRef(result);
371         }
372         Catch(WrtDeviceApis::Commons::Exception)
373         {
374                 LogError("error occured");
375         }
376         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type mismatch");
377 }
378
379 JSValueRef JSStringArray::pop(JSContextRef context,
380                 JSObjectRef function,
381                 JSObjectRef thisObject,
382                 size_t argumentCount,
383                 const JSValueRef arguments[],
384                 JSValueRef* exception)
385 {
386         Try
387         {
388                 WrtDeviceApis::CommonsJavaScript::BasicConverter converter =
389                                 WrtDeviceApis::CommonsJavaScript::BasicConverterFactory::getConverter(context);
390                 JSStringArrayPriv* priv =
391                         static_cast<JSStringArrayPriv*>(JSObjectGetPrivate(thisObject));
392                 StringArrayPtr currentStrings = priv->getObject();
393                 if (currentStrings->size() > 0) {
394                         std::string result = currentStrings->at(
395                                         currentStrings->size() - 1);
396                         currentStrings->pop_back();
397                         return converter->toJSValueRef(result);
398                 }
399         }
400         Catch(WrtDeviceApis::Commons::Exception)
401         {
402                 LogError("error occured");
403         }
404         return JSValueMakeUndefined(context);
405 }
406
407 JSValueRef JSStringArray::push(JSContextRef context,
408                 JSObjectRef function,
409                 JSObjectRef thisObject,
410                 size_t argumentCount,
411                 const JSValueRef arguments[],
412                 JSValueRef* exception)
413 {
414         Try
415         {
416                 WrtDeviceApis::CommonsJavaScript::BasicConverter converter =
417                                 WrtDeviceApis::CommonsJavaScript::BasicConverterFactory::getConverter(context);
418                 JSStringArrayPriv* priv =
419                         static_cast<JSStringArrayPriv*>(JSObjectGetPrivate(thisObject));
420                 StringArrayPtr currentStrings = priv->getObject();
421                 for (size_t i = 0; i < argumentCount; ++i) {
422                         currentStrings->push_back(converter->toString(arguments[i]));
423                 }
424                 return converter->toJSValueRef(currentStrings->size());
425         }
426         Catch(WrtDeviceApis::Commons::Exception)
427         {
428                 LogError("error occured");
429         }
430         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type mismatch");
431 }
432
433 JSValueRef JSStringArray::reverse(JSContextRef context,
434                 JSObjectRef function,
435                 JSObjectRef thisObject,
436                 size_t argumentCount,
437                 const JSValueRef arguments[],
438                 JSValueRef* exception)
439 {
440         Try
441         {
442                 WrtDeviceApis::CommonsJavaScript::BasicConverter converter =
443                                 WrtDeviceApis::CommonsJavaScript::BasicConverterFactory::getConverter(context);
444                 JSStringArrayPriv* priv =
445                         static_cast<JSStringArrayPriv*>(JSObjectGetPrivate(thisObject));
446                 StringArrayPtr currentStrings = priv->getObject();
447                 std::reverse(currentStrings->begin(), currentStrings->end());
448                 return thisObject;
449         }
450         Catch(WrtDeviceApis::Commons::Exception)
451         {
452                 LogError("error occured");
453         }
454         return JSValueMakeUndefined(context);
455 }
456
457 JSValueRef JSStringArray::shift(JSContextRef context,
458                 JSObjectRef function,
459                 JSObjectRef thisObject,
460                 size_t argumentCount,
461                 const JSValueRef arguments[],
462                 JSValueRef* exception)
463 {
464         Try
465         {
466                 WrtDeviceApis::CommonsJavaScript::BasicConverter converter =
467                                 WrtDeviceApis::CommonsJavaScript::BasicConverterFactory::getConverter(context);
468                 JSStringArrayPriv* priv =
469                         static_cast<JSStringArrayPriv*>(JSObjectGetPrivate(thisObject));
470                 StringArrayPtr currentStrings = priv->getObject();
471                 if (currentStrings->size() > 0) {
472                         std::string result = currentStrings->at(0);
473                         currentStrings->erase(currentStrings->begin());
474                         return converter->toJSValueRef(result);
475                 }
476         }
477         Catch(WrtDeviceApis::Commons::Exception)
478         {
479                 LogError("error occured");
480         }
481         return JSValueMakeUndefined(context);
482 }
483
484 JSValueRef JSStringArray::slice(JSContextRef context,
485                 JSObjectRef function,
486                 JSObjectRef thisObject,
487                 size_t argumentCount,
488                 const JSValueRef arguments[],
489                 JSValueRef* exception)
490 {
491         Try
492         {
493                 if (argumentCount < 1) {
494                         return JSValueMakeUndefined(context);
495                 }
496                 WrtDeviceApis::CommonsJavaScript::BasicConverter converter =
497                                 WrtDeviceApis::CommonsJavaScript::BasicConverterFactory::getConverter(context);
498                 StringArrayPtr strs = StringArrayPtr(new StringArray());
499                 JSStringArrayPriv *newPrivateObject = new JSStringArrayPriv(
500                                 context,
501                                 strs);
502                 JSValueRef result = JSObjectMake(context,
503                                                                                  getClassRef(), newPrivateObject);
504
505                 //copy current strs
506                 JSStringArrayPriv* priv =
507                         static_cast<JSStringArrayPriv*>(JSObjectGetPrivate(thisObject));
508                 StringArrayPtr currentStrings = priv->getObject();
509                 std::size_t first = converter->toSizeT(arguments[0]);
510                 std::size_t last = currentStrings->size() - 1;
511                 if (argumentCount > 1) {
512                         last = converter->toSizeT(arguments[1]);
513                         if (last >= currentStrings->size()) {
514                                 last = currentStrings->size() - 1;
515                         }
516                 }
517                 if (first < 0) {
518                         first = 0;
519                 }
520                 for (size_t i = first; i <= last; ++i) {
521                         strs->push_back(currentStrings->at(i));
522                 }
523
524                 return result;
525         }
526         Catch(WrtDeviceApis::Commons::Exception)
527         {
528                 LogError("error occured");
529         }
530         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type mismatch");
531 }
532
533 JSValueRef JSStringArray::sort(JSContextRef context,
534                 JSObjectRef function,
535                 JSObjectRef thisObject,
536                 size_t argumentCount,
537                 const JSValueRef arguments[],
538                 JSValueRef* exception)
539 {
540         Try
541         {
542                 WrtDeviceApis::CommonsJavaScript::BasicConverter converter =
543                                 WrtDeviceApis::CommonsJavaScript::BasicConverterFactory::getConverter(context);
544                 JSStringArrayPriv* priv =
545                         static_cast<JSStringArrayPriv*>(JSObjectGetPrivate(thisObject));
546                 StringArrayPtr currentStrings = priv->getObject();
547                 std::sort(currentStrings->begin(), currentStrings->end());
548                 return thisObject;
549         }
550         Catch(WrtDeviceApis::Commons::Exception)
551         {
552                 LogError("error occured");
553         }
554         return JSValueMakeUndefined(context);
555 }
556
557 JSValueRef JSStringArray::splice(JSContextRef context,
558                 JSObjectRef function,
559                 JSObjectRef thisObject,
560                 size_t argumentCount,
561                 const JSValueRef arguments[],
562                 JSValueRef* exception)
563 {
564         return JSValueMakeUndefined(context);
565 }
566
567 JSValueRef JSStringArray::toString(JSContextRef context,
568                 JSObjectRef function,
569                 JSObjectRef thisObject,
570                 size_t argumentCount,
571                 const JSValueRef arguments[],
572                 JSValueRef* exception)
573 {
574         return join(context, function, thisObject, 0, arguments, exception);
575 }
576
577 JSValueRef JSStringArray::unshift(JSContextRef context,
578                 JSObjectRef function,
579                 JSObjectRef thisObject,
580                 size_t argumentCount,
581                 const JSValueRef arguments[],
582                 JSValueRef* exception)
583 {
584         return JSValueMakeUndefined(context);
585 }
586
587 JSValueRef JSStringArray::valueOf(JSContextRef context,
588                 JSObjectRef function,
589                 JSObjectRef thisObject,
590                 size_t argumentCount,
591                 const JSValueRef arguments[],
592                 JSValueRef* exception)
593 {
594         return JSValueMakeUndefined(context);
595 }
596
597 } // Calendar
598 } // Tizen1_0
599 } // TizenApis