diff options
Diffstat (limited to 'wearable_src/Filesystem/JSFilestream.cpp')
-rw-r--r-- | wearable_src/Filesystem/JSFilestream.cpp | 492 |
1 files changed, 492 insertions, 0 deletions
diff --git a/wearable_src/Filesystem/JSFilestream.cpp b/wearable_src/Filesystem/JSFilestream.cpp new file mode 100644 index 0000000..8e36084 --- /dev/null +++ b/wearable_src/Filesystem/JSFilestream.cpp @@ -0,0 +1,492 @@ +// +// Tizen Web Device API +// Copyright (c) 2012 Samsung Electronics Co., Ltd. +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + + +#include "JSFilestream.h" + +#include <dpl/scoped_array.h> + +#include <Commons/Base64.h> +#include <CommonsJavaScript/JSUtils.h> +#include <JSWebAPIErrorFactory.h> +#include <SecurityExceptions.h> +#include <TimeTracer.h> +#include <Export.h> + +#include "Converter.h" +#include "Encodings.h" +#include "plugin_config.h" +#include "FilesystemUtils.h" +#include <Logger.h> + +namespace { +const char* PLUGIN_NAME = "FileStream"; +const char* PROPERTY_EOF = "eof"; +const char* PROPERTY_POSITION = "position"; +const char* PROPERTY_BYTES_AVAILABLE = "bytesAvailable"; +} + +using namespace WrtDeviceApis::Commons; +using namespace WrtDeviceApis::CommonsJavaScript; +using namespace DeviceAPI::Common; + +namespace DeviceAPI { +namespace Filesystem { +JSClassRef JSFilestream::m_classRef = 0; + +JSClassDefinition JSFilestream::m_classInfo = { + 0, + kJSClassAttributeNone, + PLUGIN_NAME, + 0, + m_properties, + m_functions, + initialize, + finalize, + NULL, + NULL, + NULL, + NULL, + getPropertyNames, + NULL, + NULL, + hasInstance, + NULL +}; + +JSStaticValue JSFilestream::m_properties[] = { + { PROPERTY_EOF, getProperty, NULL, kJSPropertyAttributeReadOnly }, + { PROPERTY_POSITION, getProperty, setProperty, kJSPropertyAttributeNone }, + { PROPERTY_BYTES_AVAILABLE, getProperty, NULL, kJSPropertyAttributeReadOnly }, + { 0, 0, 0, 0 } +}; + +JSStaticFunction JSFilestream::m_functions[] = { + { "close", close, kJSPropertyAttributeNone }, + { "read", read, kJSPropertyAttributeNone }, + { "readBytes", readBytes, kJSPropertyAttributeNone }, + { "readBase64", readBase64, kJSPropertyAttributeNone }, + { "write", write, kJSPropertyAttributeNone }, + { "writeBytes", writeBytes, kJSPropertyAttributeNone }, + { "writeBase64", writeBase64, kJSPropertyAttributeNone }, + { 0, 0, 0 } +}; + +void JSFilestream::initialize(JSContextRef context, + JSObjectRef object) +{ +} + +void JSFilestream::finalize(JSObjectRef object) +{ + PrivateObject* privateObject = static_cast<PrivateObject*>(JSObjectGetPrivate(object)); + delete privateObject; +} + +const JSClassRef DLL_EXPORT JSFilestream::getClassRef() +{ + if (!m_classRef) { + m_classRef = JSClassCreate(&m_classInfo); + } + return m_classRef; +} + +const JSClassDefinition* JSFilestream::getClassInfo() +{ + return &m_classInfo; +} + +JSValueRef JSFilestream::getProperty(JSContextRef context, + JSObjectRef object, + JSStringRef propertyName, + JSValueRef* exception) +{ + PrivateObject* privateObject = static_cast<PrivateObject*>(JSObjectGetPrivate(object)); + if (!privateObject) { + return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type mismatch error"); + + } + + PrivateObject::ObjectType stream = privateObject->getObject(); + Converter converter(context); + try { + if (JSStringIsEqualToUTF8CString(propertyName, PROPERTY_EOF)) { + return converter.toJSValueRef(stream->isEof()); + } else if (JSStringIsEqualToUTF8CString(propertyName, PROPERTY_POSITION)) { + long pos = stream->getPosition(); + if (pos < 0) { + return JSValueMakeUndefined(context); + } + return converter.toJSValueRef(static_cast<unsigned long>(pos)); + } else if (JSStringIsEqualToUTF8CString(propertyName, PROPERTY_BYTES_AVAILABLE)) { + long position = stream->getPosition(); + long bytes = stream->getSize() - position; + + return converter.toJSValueRefLong(static_cast<long>(bytes)); + } + } catch (const WrtDeviceApis::Commons::ConversionException& ex) { + LoggerW("trying to get incorrect value"); + } + + return JSValueMakeUndefined(context); +} + +bool JSFilestream::setProperty(JSContextRef context, + JSObjectRef object, + JSStringRef propertyName, + JSValueRef value, + JSValueRef* exception) +{ + PrivateObject* privateObject = static_cast<PrivateObject*>(JSObjectGetPrivate(object)); + if (!privateObject) { + return false; + } + + Converter converter(context); + try { + if (JSStringIsEqualToUTF8CString(propertyName, PROPERTY_POSITION)) { + privateObject->getObject()->setPosition(converter.toLong(value)); + return true; + } + } catch (const WrtDeviceApis::Commons::Exception& ex) { + LoggerW("trying to set incorrect value"); + } + + return false; +} + +void JSFilestream::getPropertyNames(JSContextRef context, + JSObjectRef object, + JSPropertyNameAccumulatorRef propertyNames) +{ +} + +bool JSFilestream::hasInstance(JSContextRef context, + JSObjectRef constructor, + JSValueRef instance, + JSValueRef* exception) +{ + return JSValueIsObjectOfClass(context, instance, JSFilestream::getClassRef()); +} + +JSValueRef JSFilestream::close(JSContextRef context, + JSObjectRef object, + JSObjectRef thisObject, + size_t argc, + const JSValueRef argv[], + JSValueRef* exception) +{ + TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0); + PrivateObject* privateObject = static_cast<PrivateObject*>(JSObjectGetPrivate(thisObject)); + if (!privateObject) { + return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type mismatch error"); + + } + + AceSecurityStatus status = FILESYSTEM_CHECK_ACCESS(FILESYSTEM_FUNCTION_API_CLOSE); + TIZEN_SYNC_ACCESS_HANDLER(status, context, exception); + + + Try { + privateObject->getObject()->close(); + } Catch (WrtDeviceApis::Commons::PlatformException) { + return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::UNKNOWN_ERROR, "Unknown error"); + } + + TIME_TRACER_ITEM_END(__FUNCTION__, 0); + return JSValueMakeUndefined(context); +} + +JSValueRef JSFilestream::read(JSContextRef context, + JSObjectRef object, + JSObjectRef thisObject, + size_t argc, + const JSValueRef argv[], + JSValueRef* exception) +{ + TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0); + TIME_TRACER_ITEM_BEGIN("read(UTF8)", 0); + PrivateObject* privateObject = static_cast<PrivateObject*>(JSObjectGetPrivate(thisObject)); + if (!privateObject) { + return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type mismatch error"); + } + + Converter converter(context); + + AceSecurityStatus status = FILESYSTEM_CHECK_ACCESS(FILESYSTEM_FUNCTION_API_READ); + TIZEN_SYNC_ACCESS_HANDLER(status, context, exception); + + try { + JSValueRef undefinedValue = JSValueMakeUndefined(context); + unsigned long count = 0; + + if (argc > 0) + count = converter.toULong(argv[0]); + else + count = converter.toULong(undefinedValue); + + if (count <= 0) { + ThrowMsg(InvalidArgumentException, "Invalid argument"); + } + std::string outStr = ""; + std::string currentCharSet = privateObject->getObject()->getCharSet(); + + DPL::ScopedArray<char> text(privateObject->getObject()->getChars(count)); + + // utf8, iso8859-1, skip + if (!strcmp(currentCharSet.c_str(), Encodings::UTF8) || !strcmp(currentCharSet.c_str(), Encodings::ISO88591)) + { + TIME_TRACER_ITEM_END(__FUNCTION__, 0); + return converter.toJSValueRef(std::string(text.Get())); + } + else + { + Utils::toUTF8String(currentCharSet, text.Get(), count, outStr); + TIME_TRACER_ITEM_END("read(UTF8)", 0); + return converter.toJSValueRef(outStr); + } + } catch(const WrtDeviceApis::Commons::ConversionException& ex) { + return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, ex.GetMessage()); + } catch (const WrtDeviceApis::Commons::UnsupportedException& ex) { + return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::NOT_SUPPORTED_ERROR, ex.GetMessage()); + } catch(const WrtDeviceApis::Commons::InvalidArgumentException& ex) { + return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::INVALID_VALUES_ERROR, ex.GetMessage()); + } catch(const WrtDeviceApis::Commons::PlatformException& ex) { + return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::IO_ERROR, ex.GetMessage()); + } + +} + +JSValueRef JSFilestream::readBytes(JSContextRef context, + JSObjectRef object, + JSObjectRef thisObject, + size_t argc, + const JSValueRef argv[], + JSValueRef* exception) +{ + TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0); + PrivateObject* privateObject = static_cast<PrivateObject*>(JSObjectGetPrivate(thisObject)); + if (!privateObject) { + return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type mismatch error"); + } + + AceSecurityStatus status = FILESYSTEM_CHECK_ACCESS(FILESYSTEM_FUNCTION_API_READ_BYTES); + TIZEN_SYNC_ACCESS_HANDLER(status, context, exception); + + + Converter converter(context); + Try { + JSValueRef undefinedValue = JSValueMakeUndefined(context); + unsigned long count = 0; + + if (argc > 0) + count = converter.toULong(argv[0]); + else + count = converter.toULong(undefinedValue); + + if (count <= 0) { + ThrowMsg(InvalidArgumentException, "Invalid argument"); + } + + DPL::ScopedArray<unsigned char> data(privateObject->getObject()->getBytes(count)); + TIME_TRACER_ITEM_END(__FUNCTION__, 0); + return converter.toJSValueRef(data.Get(), privateObject->getObject()->getCount()); + } catch(const WrtDeviceApis::Commons::ConversionException& ex) { + return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, ex.GetMessage()); + } catch (const WrtDeviceApis::Commons::UnsupportedException& ex) { + return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::NOT_SUPPORTED_ERROR, ex.GetMessage()); + } catch(const WrtDeviceApis::Commons::InvalidArgumentException& ex) { + return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::INVALID_VALUES_ERROR, ex.GetMessage()); + } catch(const WrtDeviceApis::Commons::PlatformException& ex) { + return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::IO_ERROR, ex.GetMessage()); + } + +} + +JSValueRef JSFilestream::readBase64(JSContextRef context, + JSObjectRef object, + JSObjectRef thisObject, + size_t argc, + const JSValueRef argv[], + JSValueRef* exception) +{ + TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0); + PrivateObject* privateObject = static_cast<PrivateObject*>(JSObjectGetPrivate(thisObject)); + if (!privateObject) { + return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type mismatch error"); + } + + AceSecurityStatus status = FILESYSTEM_CHECK_ACCESS(FILESYSTEM_FUNCTION_API_READ_BASE64); + TIZEN_SYNC_ACCESS_HANDLER(status, context, exception); + + Converter converter(context); + try { + JSValueRef undefinedValue = JSValueMakeUndefined(context); + unsigned long count = 0; + + if (argc > 0) + count = converter.toULong(argv[0]); + else + count = converter.toULong(undefinedValue); + + if (count <= 0) { + ThrowMsg(InvalidArgumentException, "Invalid argument"); + } + + DPL::ScopedArray<unsigned char> data(privateObject->getObject()->getBytes(count)); + std::string base64 = WrtDeviceApis::Commons::Base64::encode(data.Get(), privateObject->getObject()->getCount()); + TIME_TRACER_ITEM_END(__FUNCTION__, 0); + return converter.toJSValueRef(base64); + } catch(const WrtDeviceApis::Commons::ConversionException& ex) { + return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, ex.GetMessage()); + } catch (const WrtDeviceApis::Commons::UnsupportedException& ex) { + return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::NOT_SUPPORTED_ERROR, ex.GetMessage()); + } catch(const WrtDeviceApis::Commons::InvalidArgumentException& ex) { + return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::INVALID_VALUES_ERROR, ex.GetMessage()); + } catch(const WrtDeviceApis::Commons::PlatformException& ex) { + return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::IO_ERROR, ex.GetMessage()); + } + +} + +JSValueRef JSFilestream::write(JSContextRef context, + JSObjectRef object, + JSObjectRef thisObject, + size_t argc, + const JSValueRef argv[], + JSValueRef* exception) +{ + TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0); + PrivateObject* privateObject = static_cast<PrivateObject*>(JSObjectGetPrivate(thisObject)); + if (!privateObject) { + return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type mismatch error"); + } + + AceSecurityStatus status = FILESYSTEM_CHECK_ACCESS(FILESYSTEM_FUNCTION_API_WRITE); + TIZEN_SYNC_ACCESS_HANDLER(status, context, exception); + + + Converter converter(context); + try { + JSValueRef undefinedValue = JSValueMakeUndefined(context); + + if (argc > 0) + privateObject->getObject()->write(converter.toString(argv[0])); + else + privateObject->getObject()->write(converter.toString(undefinedValue)); + + + } catch(const WrtDeviceApis::Commons::ConversionException& ex) { + return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, ex.GetMessage()); + } catch (const WrtDeviceApis::Commons::UnsupportedException& ex) { + return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::NOT_SUPPORTED_ERROR, ex.GetMessage()); + } catch(const WrtDeviceApis::Commons::InvalidArgumentException& ex) { + return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::INVALID_VALUES_ERROR, ex.GetMessage()); + } catch(const WrtDeviceApis::Commons::PlatformException& ex) { + return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::IO_ERROR, ex.GetMessage()); + } + + TIME_TRACER_ITEM_END(__FUNCTION__, 0); + return JSValueMakeUndefined(context); +} + +JSValueRef JSFilestream::writeBytes(JSContextRef context, + JSObjectRef object, + JSObjectRef thisObject, + size_t argc, + const JSValueRef argv[], + JSValueRef* exception) +{ + TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0); + PrivateObject* privateObject = static_cast<PrivateObject*>(JSObjectGetPrivate(thisObject)); + if (!privateObject) { + return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type mismatch error"); + } + + AceSecurityStatus status = FILESYSTEM_CHECK_ACCESS(FILESYSTEM_FUNCTION_API_WRITE_BYTES); + TIZEN_SYNC_ACCESS_HANDLER(status, context, exception); + + + Converter converter(context); + Try { + if (argc < 1 || !JSIsArrayValue(context, argv[0])) + ThrowMsg(ConversionException, "Type mismatch error"); + + PrivateObject::ObjectType stream = privateObject->getObject(); + std::vector<unsigned char> data = converter.toVectorOfUChars(argv[0]); + std::vector<unsigned char>::const_iterator it = data.begin(); + for (; it != data.end(); ++it) { + stream->write(*it); + } + } catch(const WrtDeviceApis::Commons::ConversionException& ex) { + return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, ex.GetMessage()); + } catch (const WrtDeviceApis::Commons::UnsupportedException& ex) { + return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::NOT_SUPPORTED_ERROR, ex.GetMessage()); + } catch(const WrtDeviceApis::Commons::InvalidArgumentException& ex) { + return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::INVALID_VALUES_ERROR, ex.GetMessage()); + } catch(const WrtDeviceApis::Commons::PlatformException& ex) { + return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::IO_ERROR, ex.GetMessage()); + } + + TIME_TRACER_ITEM_END(__FUNCTION__, 0); + return JSValueMakeUndefined(context); +} + +JSValueRef JSFilestream::writeBase64(JSContextRef context, + JSObjectRef object, + JSObjectRef thisObject, + size_t argc, + const JSValueRef argv[], + JSValueRef* exception) +{ + TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0); + PrivateObject* privateObject = static_cast<PrivateObject*>(JSObjectGetPrivate(thisObject)); + if (!privateObject) { + return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type mismatch error"); + } + + AceSecurityStatus status = FILESYSTEM_CHECK_ACCESS(FILESYSTEM_FUNCTION_API_WRITE_BASE64); + TIZEN_SYNC_ACCESS_HANDLER(status, context, exception); + + Converter converter(context); + try { + LoggerD("OK"); + + JSValueRef undefinedValue = JSValueMakeUndefined(context); + std::string base64; + if (argc > 0) + base64 = WrtDeviceApis::Commons::Base64::decode(converter.toString(argv[0])); + else + base64 = WrtDeviceApis::Commons::Base64::decode(converter.toString(undefinedValue)); + + privateObject->getObject()->write(base64); + } catch(const WrtDeviceApis::Commons::ConversionException& ex) { + return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, ex.GetMessage()); + } catch (const WrtDeviceApis::Commons::UnsupportedException& ex) { + return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::NOT_SUPPORTED_ERROR, ex.GetMessage()); + } catch(const WrtDeviceApis::Commons::InvalidArgumentException& ex) { + return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::IO_ERROR, ex.GetMessage()); + } catch(const WrtDeviceApis::Commons::PlatformException& ex) { + return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::IO_ERROR, ex.GetMessage()); + } + + TIME_TRACER_ITEM_END(__FUNCTION__, 0); + return JSValueMakeUndefined(context); +} +} // Tizen1_0 +} // TizenApis + |