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.
19 #include "JSFilestream.h"
21 #include <dpl/scoped_array.h>
23 #include <Commons/Base64.h>
24 #include <CommonsJavaScript/JSUtils.h>
25 #include <JSTizenExceptionFactory.h>
26 #include <JSTizenException.h>
27 #include <SecurityExceptions.h>
28 #include <TimeTracer.h>
30 #include "Converter.h"
31 #include "Encodings.h"
32 #include "plugin_config.h"
33 #include "FilesystemUtils.h"
37 const char* PLUGIN_NAME = "FileStream";
38 const char* PROPERTY_EOF = "eof";
39 const char* PROPERTY_POSITION = "position";
40 const char* PROPERTY_BYTES_AVAILABLE = "bytesAvailable";
43 using namespace WrtDeviceApis::Commons;
44 using namespace WrtDeviceApis::CommonsJavaScript;
45 using namespace DeviceAPI::Common;
48 namespace Filesystem {
49 JSClassRef JSFilestream::m_classRef = 0;
51 JSClassDefinition JSFilestream::m_classInfo = {
53 kJSClassAttributeNone,
71 JSStaticValue JSFilestream::m_properties[] = {
72 { PROPERTY_EOF, getProperty, NULL, kJSPropertyAttributeReadOnly },
73 { PROPERTY_POSITION, getProperty, setProperty, kJSPropertyAttributeNone },
74 { PROPERTY_BYTES_AVAILABLE, getProperty, NULL, kJSPropertyAttributeReadOnly },
78 JSStaticFunction JSFilestream::m_functions[] = {
79 { "close", close, kJSPropertyAttributeNone },
80 { "read", read, kJSPropertyAttributeNone },
81 { "readBytes", readBytes, kJSPropertyAttributeNone },
82 { "readBase64", readBase64, kJSPropertyAttributeNone },
83 { "write", write, kJSPropertyAttributeNone },
84 { "writeBytes", writeBytes, kJSPropertyAttributeNone },
85 { "writeBase64", writeBase64, kJSPropertyAttributeNone },
89 void JSFilestream::initialize(JSContextRef context,
94 void JSFilestream::finalize(JSObjectRef object)
96 PrivateObject* privateObject = static_cast<PrivateObject*>(JSObjectGetPrivate(object));
100 const JSClassRef JSFilestream::getClassRef()
103 m_classRef = JSClassCreate(&m_classInfo);
108 const JSClassDefinition* JSFilestream::getClassInfo()
113 JSValueRef JSFilestream::getProperty(JSContextRef context,
115 JSStringRef propertyName,
116 JSValueRef* exception)
118 PrivateObject* privateObject = static_cast<PrivateObject*>(JSObjectGetPrivate(object));
119 if (!privateObject) {
120 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type mismatch error");
124 PrivateObject::ObjectType stream = privateObject->getObject();
125 Converter converter(context);
127 if (JSStringIsEqualToUTF8CString(propertyName, PROPERTY_EOF)) {
128 return converter.toJSValueRef(stream->isEof());
129 } else if (JSStringIsEqualToUTF8CString(propertyName, PROPERTY_POSITION)) {
130 long pos = stream->getPosition();
132 return JSValueMakeUndefined(context);
134 return converter.toJSValueRef(static_cast<unsigned long>(pos));
135 } else if (JSStringIsEqualToUTF8CString(propertyName, PROPERTY_BYTES_AVAILABLE)) {
136 unsigned long long bytes = stream->getSize() - stream->getPosition();
137 return converter.toJSValueRef(static_cast<unsigned long long>(bytes));
139 } catch (const WrtDeviceApis::Commons::ConversionException& ex) {
140 LoggerW("trying to get incorrect value");
143 return JSValueMakeUndefined(context);
146 bool JSFilestream::setProperty(JSContextRef context,
148 JSStringRef propertyName,
150 JSValueRef* exception)
152 PrivateObject* privateObject = static_cast<PrivateObject*>(JSObjectGetPrivate(object));
153 if (!privateObject) {
157 Converter converter(context);
159 if (JSStringIsEqualToUTF8CString(propertyName, PROPERTY_POSITION)) {
160 privateObject->getObject()->setPosition(converter.toLong(value));
163 } catch (const WrtDeviceApis::Commons::Exception& ex) {
164 LoggerW("trying to set incorrect value");
170 void JSFilestream::getPropertyNames(JSContextRef context,
172 JSPropertyNameAccumulatorRef propertyNames)
176 bool JSFilestream::hasInstance(JSContextRef context,
177 JSObjectRef constructor,
179 JSValueRef* exception)
181 return JSValueIsObjectOfClass(context, instance, JSFilestream::getClassRef());
184 JSValueRef JSFilestream::close(JSContextRef context,
186 JSObjectRef thisObject,
188 const JSValueRef argv[],
189 JSValueRef* exception)
191 TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
192 PrivateObject* privateObject = static_cast<PrivateObject*>(JSObjectGetPrivate(thisObject));
193 if (!privateObject) {
194 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type mismatch error");
198 AceSecurityStatus status = FILESYSTEM_CHECK_ACCESS(FILESYSTEM_FUNCTION_API_CLOSE);
199 TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
203 privateObject->getObject()->close();
204 } Catch (WrtDeviceApis::Commons::PlatformException) {
205 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Unknown error");
208 TIME_TRACER_ITEM_END(__FUNCTION__, 0);
209 return JSValueMakeUndefined(context);
212 JSValueRef JSFilestream::read(JSContextRef context,
214 JSObjectRef thisObject,
216 const JSValueRef argv[],
217 JSValueRef* exception)
219 TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
220 TIME_TRACER_ITEM_BEGIN("read(UTF8)", 0);
221 PrivateObject* privateObject = static_cast<PrivateObject*>(JSObjectGetPrivate(thisObject));
222 if (!privateObject) {
223 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type mismatch error");
226 Converter converter(context);
228 AceSecurityStatus status = FILESYSTEM_CHECK_ACCESS(FILESYSTEM_FUNCTION_API_READ);
229 TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
232 JSValueRef undefinedValue = JSValueMakeUndefined(context);
233 unsigned long count = 0;
236 count = converter.toULong(argv[0]);
238 count = converter.toULong(undefinedValue);
241 ThrowMsg(InvalidArgumentException, "Invalid argument");
243 std::string outStr = "";
244 std::string currentCharSet = privateObject->getObject()->getCharSet();
246 DPL::ScopedArray<char> text(privateObject->getObject()->getChars(count));
248 // utf8, iso8859-1, skip
249 if (!strcmp(currentCharSet.c_str(), Encodings::UTF8) || !strcmp(currentCharSet.c_str(), Encodings::ISO88591))
251 TIME_TRACER_ITEM_END(__FUNCTION__, 0);
252 return converter.toJSValueRef(std::string(text.Get()));
256 Utils::toUTF8String(currentCharSet, text.Get(), count, outStr);
257 TIME_TRACER_ITEM_END("read(UTF8)", 0);
258 return converter.toJSValueRef(outStr);
260 } catch(const WrtDeviceApis::Commons::ConversionException& ex) {
261 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, ex.GetMessage());
262 } catch (const WrtDeviceApis::Commons::UnsupportedException& ex) {
263 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::NOT_SUPPORTED_ERROR, ex.GetMessage());
264 } catch(const WrtDeviceApis::Commons::InvalidArgumentException& ex) {
265 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::INVALID_VALUES_ERROR, ex.GetMessage());
266 } catch(const WrtDeviceApis::Commons::PlatformException& ex) {
267 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::IO_ERROR, ex.GetMessage());
272 JSValueRef JSFilestream::readBytes(JSContextRef context,
274 JSObjectRef thisObject,
276 const JSValueRef argv[],
277 JSValueRef* exception)
279 TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
280 PrivateObject* privateObject = static_cast<PrivateObject*>(JSObjectGetPrivate(thisObject));
281 if (!privateObject) {
282 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type mismatch error");
285 AceSecurityStatus status = FILESYSTEM_CHECK_ACCESS(FILESYSTEM_FUNCTION_API_READ_BYTES);
286 TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
289 Converter converter(context);
291 JSValueRef undefinedValue = JSValueMakeUndefined(context);
292 unsigned long count = 0;
295 count = converter.toULong(argv[0]);
297 count = converter.toULong(undefinedValue);
300 ThrowMsg(InvalidArgumentException, "Invalid argument");
303 DPL::ScopedArray<unsigned char> data(privateObject->getObject()->getBytes(count));
304 TIME_TRACER_ITEM_END(__FUNCTION__, 0);
305 return converter.toJSValueRef(data.Get(), privateObject->getObject()->getCount());
306 } catch(const WrtDeviceApis::Commons::ConversionException& ex) {
307 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, ex.GetMessage());
308 } catch (const WrtDeviceApis::Commons::UnsupportedException& ex) {
309 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::NOT_SUPPORTED_ERROR, ex.GetMessage());
310 } catch(const WrtDeviceApis::Commons::InvalidArgumentException& ex) {
311 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::INVALID_VALUES_ERROR, ex.GetMessage());
312 } catch(const WrtDeviceApis::Commons::PlatformException& ex) {
313 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::IO_ERROR, ex.GetMessage());
318 JSValueRef JSFilestream::readBase64(JSContextRef context,
320 JSObjectRef thisObject,
322 const JSValueRef argv[],
323 JSValueRef* exception)
325 TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
326 PrivateObject* privateObject = static_cast<PrivateObject*>(JSObjectGetPrivate(thisObject));
327 if (!privateObject) {
328 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type mismatch error");
331 AceSecurityStatus status = FILESYSTEM_CHECK_ACCESS(FILESYSTEM_FUNCTION_API_READ_BASE64);
332 TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
334 Converter converter(context);
336 JSValueRef undefinedValue = JSValueMakeUndefined(context);
337 unsigned long count = 0;
340 count = converter.toULong(argv[0]);
342 count = converter.toULong(undefinedValue);
345 ThrowMsg(InvalidArgumentException, "Invalid argument");
348 DPL::ScopedArray<unsigned char> data(privateObject->getObject()->getBytes(count));
349 std::string base64 = WrtDeviceApis::Commons::Base64::encode(data.Get(), privateObject->getObject()->getCount());
350 TIME_TRACER_ITEM_END(__FUNCTION__, 0);
351 return converter.toJSValueRef(base64);
352 } catch(const WrtDeviceApis::Commons::ConversionException& ex) {
353 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, ex.GetMessage());
354 } catch (const WrtDeviceApis::Commons::UnsupportedException& ex) {
355 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::NOT_SUPPORTED_ERROR, ex.GetMessage());
356 } catch(const WrtDeviceApis::Commons::InvalidArgumentException& ex) {
357 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::INVALID_VALUES_ERROR, ex.GetMessage());
358 } catch(const WrtDeviceApis::Commons::PlatformException& ex) {
359 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::IO_ERROR, ex.GetMessage());
364 JSValueRef JSFilestream::write(JSContextRef context,
366 JSObjectRef thisObject,
368 const JSValueRef argv[],
369 JSValueRef* exception)
371 TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
372 PrivateObject* privateObject = static_cast<PrivateObject*>(JSObjectGetPrivate(thisObject));
373 if (!privateObject) {
374 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type mismatch error");
377 AceSecurityStatus status = FILESYSTEM_CHECK_ACCESS(FILESYSTEM_FUNCTION_API_WRITE);
378 TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
381 Converter converter(context);
383 JSValueRef undefinedValue = JSValueMakeUndefined(context);
386 privateObject->getObject()->write(converter.toString(argv[0]));
388 privateObject->getObject()->write(converter.toString(undefinedValue));
391 } catch(const WrtDeviceApis::Commons::ConversionException& ex) {
392 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, ex.GetMessage());
393 } catch (const WrtDeviceApis::Commons::UnsupportedException& ex) {
394 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::NOT_SUPPORTED_ERROR, ex.GetMessage());
395 } catch(const WrtDeviceApis::Commons::InvalidArgumentException& ex) {
396 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::INVALID_VALUES_ERROR, ex.GetMessage());
397 } catch(const WrtDeviceApis::Commons::PlatformException& ex) {
398 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::IO_ERROR, ex.GetMessage());
401 TIME_TRACER_ITEM_END(__FUNCTION__, 0);
402 return JSValueMakeUndefined(context);
405 JSValueRef JSFilestream::writeBytes(JSContextRef context,
407 JSObjectRef thisObject,
409 const JSValueRef argv[],
410 JSValueRef* exception)
412 TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
413 PrivateObject* privateObject = static_cast<PrivateObject*>(JSObjectGetPrivate(thisObject));
414 if (!privateObject) {
415 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type mismatch error");
418 AceSecurityStatus status = FILESYSTEM_CHECK_ACCESS(FILESYSTEM_FUNCTION_API_WRITE_BYTES);
419 TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
422 Converter converter(context);
424 if (argc < 1 || !JSIsArrayValue(context, argv[0]))
425 ThrowMsg(ConversionException, "Type mismatch error");
427 PrivateObject::ObjectType stream = privateObject->getObject();
428 std::vector<unsigned char> data = converter.toVectorOfUChars(argv[0]);
429 std::vector<unsigned char>::const_iterator it = data.begin();
430 for (; it != data.end(); ++it) {
433 } catch(const WrtDeviceApis::Commons::ConversionException& ex) {
434 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, ex.GetMessage());
435 } catch (const WrtDeviceApis::Commons::UnsupportedException& ex) {
436 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::NOT_SUPPORTED_ERROR, ex.GetMessage());
437 } catch(const WrtDeviceApis::Commons::InvalidArgumentException& ex) {
438 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::INVALID_VALUES_ERROR, ex.GetMessage());
439 } catch(const WrtDeviceApis::Commons::PlatformException& ex) {
440 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::IO_ERROR, ex.GetMessage());
443 TIME_TRACER_ITEM_END(__FUNCTION__, 0);
444 return JSValueMakeUndefined(context);
447 JSValueRef JSFilestream::writeBase64(JSContextRef context,
449 JSObjectRef thisObject,
451 const JSValueRef argv[],
452 JSValueRef* exception)
454 TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
455 PrivateObject* privateObject = static_cast<PrivateObject*>(JSObjectGetPrivate(thisObject));
456 if (!privateObject) {
457 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type mismatch error");
460 AceSecurityStatus status = FILESYSTEM_CHECK_ACCESS(FILESYSTEM_FUNCTION_API_WRITE_BASE64);
461 TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
463 Converter converter(context);
467 JSValueRef undefinedValue = JSValueMakeUndefined(context);
470 base64 = WrtDeviceApis::Commons::Base64::decode(converter.toString(argv[0]));
472 base64 = WrtDeviceApis::Commons::Base64::decode(converter.toString(undefinedValue));
474 privateObject->getObject()->write(base64);
475 } catch(const WrtDeviceApis::Commons::ConversionException& ex) {
476 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, ex.GetMessage());
477 } catch (const WrtDeviceApis::Commons::UnsupportedException& ex) {
478 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::NOT_SUPPORTED_ERROR, ex.GetMessage());
479 } catch(const WrtDeviceApis::Commons::InvalidArgumentException& ex) {
480 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::INVALID_VALUES_ERROR, ex.GetMessage());
481 } catch(const WrtDeviceApis::Commons::PlatformException& ex) {
482 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::IO_ERROR, ex.GetMessage());
485 TIME_TRACER_ITEM_END(__FUNCTION__, 0);
486 return JSValueMakeUndefined(context);