upload tizen1.0 source
[profile/ivi/wrt-plugins-tizen.git] / src / standards / Tizen / Filesystem / JSFilestream.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 "JSFilestream.h"
19
20 #include <dpl/scoped_array.h>
21 #include <dpl/log/log.h>
22
23 #include <Commons/Base64.h>
24 #include <CommonsJavaScript/JSUtils.h>
25 #include <Tizen/Common/JSTizenExceptionFactory.h>
26 #include <Tizen/Common/JSTizenException.h>
27 #include "Converter.h"
28 #include "plugin_config.h"
29
30 namespace {
31 const char* PLUGIN_NAME = "FileStream";
32 const char* PROPERTY_EOF = "eof";
33 const char* PROPERTY_POSITION = "position";
34 const char* PROPERTY_BYTES_AVAILABLE = "bytesAvailable";
35 }
36
37 using namespace WrtDeviceApis::Commons;
38 using namespace WrtDeviceApis::CommonsJavaScript;
39 using namespace TizenApis::Commons;
40
41 namespace TizenApis {
42 namespace Tizen1_0 {
43 JSClassRef JSFilestream::m_classRef = 0;
44
45 JSClassDefinition JSFilestream::m_classInfo = {
46         0,
47         kJSClassAttributeNone,
48         PLUGIN_NAME,
49         0,
50         m_properties,
51         m_functions,
52         initialize,
53         finalize,
54         NULL,
55         NULL,
56         NULL,
57         NULL,
58         getPropertyNames,
59         NULL,
60         NULL,
61         hasInstance,
62         NULL
63 };
64
65 JSStaticValue JSFilestream::m_properties[] = {
66         { PROPERTY_EOF, getProperty, NULL, kJSPropertyAttributeReadOnly },
67         { PROPERTY_POSITION, getProperty, setProperty, kJSPropertyAttributeNone },
68         { PROPERTY_BYTES_AVAILABLE, getProperty, NULL, kJSPropertyAttributeReadOnly },
69         { 0, 0, 0, 0 }
70 };
71
72 JSStaticFunction JSFilestream::m_functions[] = {
73         { "close", close, kJSPropertyAttributeNone },
74         { "read", read, kJSPropertyAttributeNone },
75         { "readBytes", readBytes, kJSPropertyAttributeNone },
76         { "readBase64", readBase64, kJSPropertyAttributeNone },
77         { "write", write, kJSPropertyAttributeNone },
78         { "writeBytes", writeBytes, kJSPropertyAttributeNone },
79         { "writeBase64", writeBase64, kJSPropertyAttributeNone },
80         { 0, 0, 0 }
81 };
82
83 void JSFilestream::initialize(JSContextRef context,
84         JSObjectRef object)
85 {
86 }
87
88 void JSFilestream::finalize(JSObjectRef object)
89 {
90         PrivateObject* privateObject = static_cast<PrivateObject*>(JSObjectGetPrivate(object));
91         delete privateObject;
92 }
93
94 const JSClassRef JSFilestream::getClassRef()
95 {
96         if (!m_classRef) {
97                 m_classRef = JSClassCreate(&m_classInfo);
98         }
99         return m_classRef;
100 }
101
102 const JSClassDefinition* JSFilestream::getClassInfo()
103 {
104         return &m_classInfo;
105 }
106
107 JSValueRef JSFilestream::getProperty(JSContextRef context,
108                 JSObjectRef object,
109                 JSStringRef propertyName,
110                 JSValueRef* exception)
111 {
112         PrivateObject* privateObject = static_cast<PrivateObject*>(JSObjectGetPrivate(object));
113         if (!privateObject) {
114                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type mismatch error");
115                 
116         }
117
118         PrivateObject::ObjectType stream = privateObject->getObject();
119         Converter converter(context);
120         try {
121                 if (JSStringIsEqualToUTF8CString(propertyName, PROPERTY_EOF)) {
122                         return converter.toJSValueRef(stream->isEof());
123                 } else if (JSStringIsEqualToUTF8CString(propertyName, PROPERTY_POSITION)) {
124                         long pos = stream->getPosition();
125                         if (pos < 0) {
126                                 return JSValueMakeUndefined(context);
127                         }
128                         return converter.toJSValueRef(static_cast<unsigned long>(pos));
129                 } else if (JSStringIsEqualToUTF8CString(propertyName, PROPERTY_BYTES_AVAILABLE)) {
130                         long bytes = stream->getSize() - stream->getPosition();
131                         return converter.toJSValueRef(static_cast<unsigned long>(bytes));
132                 }
133         } catch (const WrtDeviceApis::Commons::ConversionException& ex) {
134                 LogWarning("trying to get incorrect value");
135         }
136
137         return JSValueMakeUndefined(context);
138 }
139
140 bool JSFilestream::setProperty(JSContextRef context,
141                 JSObjectRef object,
142                 JSStringRef propertyName,
143                 JSValueRef value,
144                 JSValueRef* exception)
145 {
146         PrivateObject* privateObject =  static_cast<PrivateObject*>(JSObjectGetPrivate(object));
147         if (!privateObject) {
148                 return false;
149         }
150
151         Converter converter(context);
152         try {
153                 if (JSStringIsEqualToUTF8CString(propertyName, PROPERTY_POSITION)) {
154                         privateObject->getObject()->setPosition(converter.toLong(value));
155                         return true;
156                 }
157         } catch (const WrtDeviceApis::Commons::Exception& ex) {
158                 LogWarning("trying to set incorrect value");
159         }
160
161         return false;
162 }
163
164 void JSFilestream::getPropertyNames(JSContextRef context,
165                 JSObjectRef object,
166                 JSPropertyNameAccumulatorRef propertyNames)
167 {
168 }
169
170 bool JSFilestream::hasInstance(JSContextRef context,
171                 JSObjectRef constructor,
172                 JSValueRef instance,
173                 JSValueRef* exception)
174 {
175     return JSValueIsObjectOfClass(context, instance, JSFilestream::getClassRef());
176 }
177
178 JSValueRef JSFilestream::close(JSContextRef context,
179                 JSObjectRef object,
180                 JSObjectRef thisObject,
181                 size_t argc,
182                 const JSValueRef argv[],
183                 JSValueRef* exception)
184 {
185         PrivateObject* privateObject =  static_cast<PrivateObject*>(JSObjectGetPrivate(thisObject));
186         if (!privateObject) {
187                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type mismatch error");
188                 
189         }
190
191         Try {
192                 privateObject->getObject()->close();
193         } Catch (WrtDeviceApis::Commons::PlatformException) {
194                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Unknown error");
195         }
196
197         return JSValueMakeUndefined(context);
198 }
199
200 JSValueRef JSFilestream::read(JSContextRef context,
201                 JSObjectRef object,
202                 JSObjectRef thisObject,
203                 size_t argc,
204                 const JSValueRef argv[],
205                 JSValueRef* exception)
206 {
207         PrivateObject* privateObject = static_cast<PrivateObject*>(JSObjectGetPrivate(thisObject));
208         if (!privateObject) {
209                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type mismatch error");
210         }
211
212         Converter converter(context);
213         try {
214                 JSValueRef undefinedValue = JSValueMakeUndefined(context);
215                 unsigned long count = 0;
216
217                 if (argc > 0) 
218                         count = converter.toULong(argv[0]);
219                 else 
220                         count = converter.toULong(undefinedValue);
221
222                 if (count <= 0) {
223                         ThrowMsg(InvalidArgumentException, "Invalid argument");
224                 }
225                 
226                 DPL::ScopedArray<char> text(privateObject->getObject()->getChars(count));
227                 return converter.toJSValueRef(std::string(text.Get()));
228         } catch(const WrtDeviceApis::Commons::ConversionException& ex) {
229                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, ex.GetMessage());
230         } catch (const WrtDeviceApis::Commons::UnsupportedException& ex) {
231                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::NOT_SUPPORTED_ERROR, ex.GetMessage());
232         } catch(const WrtDeviceApis::Commons::InvalidArgumentException& ex) {
233                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::INVALID_VALUES_ERROR, ex.GetMessage());
234         } catch(const WrtDeviceApis::Commons::PlatformException& ex) {
235                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::IO_ERROR, ex.GetMessage());
236         }
237         
238         return JSValueMakeUndefined(context);
239 }
240
241 JSValueRef JSFilestream::readBytes(JSContextRef context,
242                 JSObjectRef object,
243                 JSObjectRef thisObject,
244                 size_t argc,
245                 const JSValueRef argv[],
246                 JSValueRef* exception)
247 {
248         PrivateObject* privateObject = static_cast<PrivateObject*>(JSObjectGetPrivate(thisObject));
249         if (!privateObject) {
250                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type mismatch error");
251         }
252
253         Converter converter(context);
254         Try {
255                 JSValueRef undefinedValue = JSValueMakeUndefined(context);
256                 unsigned long count = 0;
257
258                 if (argc > 0) 
259                         count = converter.toULong(argv[0]);
260                 else 
261                         count = converter.toULong(undefinedValue);
262
263                 if (count <= 0) {
264                         ThrowMsg(InvalidArgumentException, "Invalid argument");
265                 }               
266
267
268                 DPL::ScopedArray<unsigned char> data(privateObject->getObject()->getBytes(count));
269                 return converter.toJSValueRef(data.Get(), privateObject->getObject()->getCount());
270         } catch(const WrtDeviceApis::Commons::ConversionException& ex) {
271                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, ex.GetMessage());
272         } catch (const WrtDeviceApis::Commons::UnsupportedException& ex) {
273                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::NOT_SUPPORTED_ERROR, ex.GetMessage());
274         } catch(const WrtDeviceApis::Commons::InvalidArgumentException& ex) {
275                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::INVALID_VALUES_ERROR, ex.GetMessage());
276         } catch(const WrtDeviceApis::Commons::PlatformException& ex) {
277                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::IO_ERROR, ex.GetMessage());
278         }
279
280         return JSValueMakeUndefined(context);
281 }
282
283 JSValueRef JSFilestream::readBase64(JSContextRef context,
284                 JSObjectRef object,
285                 JSObjectRef thisObject,
286                 size_t argc,
287                 const JSValueRef argv[],
288                 JSValueRef* exception)
289 {
290         PrivateObject* privateObject = static_cast<PrivateObject*>(JSObjectGetPrivate(thisObject));
291         if (!privateObject) {
292                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type mismatch error");
293         }
294
295         Converter converter(context);
296         try {
297                 JSValueRef undefinedValue = JSValueMakeUndefined(context);
298                 unsigned long count = 0;
299
300                 if (argc > 0) 
301                         count = converter.toULong(argv[0]);
302                 else 
303                         count = converter.toULong(undefinedValue);
304
305                 if (count <= 0) {
306                         ThrowMsg(InvalidArgumentException, "Invalid argument");
307                 }
308
309                 DPL::ScopedArray<unsigned char> data(privateObject->getObject()->getBytes(count));
310                 std::string base64 = WrtDeviceApis::Commons::Base64::encode(data.Get(), privateObject->getObject()->getCount());
311                 return converter.toJSValueRef(base64);
312         } catch(const WrtDeviceApis::Commons::ConversionException& ex) {
313                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, ex.GetMessage());
314         } catch (const WrtDeviceApis::Commons::UnsupportedException& ex) {
315                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::NOT_SUPPORTED_ERROR, ex.GetMessage());
316         } catch(const WrtDeviceApis::Commons::InvalidArgumentException& ex) {
317                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::INVALID_VALUES_ERROR, ex.GetMessage());
318         } catch(const WrtDeviceApis::Commons::PlatformException& ex) {
319                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::IO_ERROR, ex.GetMessage());
320         }
321
322         return JSValueMakeUndefined(context);
323 }
324
325 JSValueRef JSFilestream::write(JSContextRef context,
326         JSObjectRef object,
327         JSObjectRef thisObject,
328         size_t argc,
329         const JSValueRef argv[],
330         JSValueRef* exception)
331 {
332         PrivateObject* privateObject = static_cast<PrivateObject*>(JSObjectGetPrivate(thisObject));
333         if (!privateObject) {
334                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type mismatch error");
335         }
336
337         Converter converter(context);
338         try {
339                 JSValueRef undefinedValue = JSValueMakeUndefined(context);
340
341                 if (argc > 0) 
342                         privateObject->getObject()->write(converter.toString(argv[0]));
343                 else 
344                         privateObject->getObject()->write(converter.toString(undefinedValue));
345
346
347         } catch(const WrtDeviceApis::Commons::ConversionException& ex) {
348                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, ex.GetMessage());
349         } catch (const WrtDeviceApis::Commons::UnsupportedException& ex) {
350                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::NOT_SUPPORTED_ERROR, ex.GetMessage());
351         } catch(const WrtDeviceApis::Commons::InvalidArgumentException& ex) {
352                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::INVALID_VALUES_ERROR, ex.GetMessage());
353         } catch(const WrtDeviceApis::Commons::PlatformException& ex) {
354                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::IO_ERROR, ex.GetMessage());
355         }
356
357         return JSValueMakeUndefined(context);
358 }
359
360 JSValueRef JSFilestream::writeBytes(JSContextRef context,
361                 JSObjectRef object,
362                 JSObjectRef thisObject,
363                 size_t argc,
364                 const JSValueRef argv[],
365                 JSValueRef* exception)
366 {
367         PrivateObject* privateObject = static_cast<PrivateObject*>(JSObjectGetPrivate(thisObject));
368         if (!privateObject) {
369                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type mismatch error");
370         }
371
372
373         Converter converter(context);
374         Try {
375                 if (argc < 1 || !JSIsArrayValue(context, argv[0]))
376                         ThrowMsg(ConversionException,  "Type mismatch error");
377
378                 PrivateObject::ObjectType stream = privateObject->getObject();
379                 std::vector<unsigned char> data = converter.toVectorOfUChars(argv[0]);
380                 std::vector<unsigned char>::const_iterator it = data.begin();
381                 for (; it != data.end(); ++it) {
382                         stream->write(*it);
383                 }
384         } catch(const WrtDeviceApis::Commons::ConversionException& ex) {
385                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, ex.GetMessage());
386         } catch (const WrtDeviceApis::Commons::UnsupportedException& ex) {
387                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::NOT_SUPPORTED_ERROR, ex.GetMessage());
388         } catch(const WrtDeviceApis::Commons::InvalidArgumentException& ex) {
389                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::INVALID_VALUES_ERROR, ex.GetMessage());
390         } catch(const WrtDeviceApis::Commons::PlatformException& ex) {
391                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::IO_ERROR, ex.GetMessage());
392         }
393
394         return JSValueMakeUndefined(context);
395 }
396
397 JSValueRef JSFilestream::writeBase64(JSContextRef context,
398                 JSObjectRef object,
399                 JSObjectRef thisObject,
400                 size_t argc,
401                 const JSValueRef argv[],
402                 JSValueRef* exception)
403 {
404         PrivateObject* privateObject = static_cast<PrivateObject*>(JSObjectGetPrivate(thisObject));
405         if (!privateObject) {
406                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type mismatch error");
407         }
408
409         Converter converter(context);
410         try {
411                 LogDebug("OK");
412                 
413                 JSValueRef undefinedValue = JSValueMakeUndefined(context);
414                 std::string base64;
415                 if (argc > 0) 
416                         base64 = WrtDeviceApis::Commons::Base64::decode(converter.toString(argv[0]));
417                 else 
418                         base64 = WrtDeviceApis::Commons::Base64::decode(converter.toString(undefinedValue));
419
420                 privateObject->getObject()->write(base64);
421         } catch(const WrtDeviceApis::Commons::ConversionException& ex) {
422                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, ex.GetMessage());
423         } catch (const WrtDeviceApis::Commons::UnsupportedException& ex) {
424                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::NOT_SUPPORTED_ERROR, ex.GetMessage());
425         } catch(const WrtDeviceApis::Commons::InvalidArgumentException& ex) {
426                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::INVALID_VALUES_ERROR, ex.GetMessage());
427         } catch(const WrtDeviceApis::Commons::PlatformException& ex) {
428                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::IO_ERROR, ex.GetMessage());
429         }
430
431         return JSValueMakeUndefined(context);
432 }
433 } // Tizen1_0
434 } // TizenApis
435