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