Update change log and spec for wrt-plugins-tizen_0.4.38
[framework/web/wrt-plugins-tizen.git] / src / Filesystem / FilesystemUtils.cpp
1 //
2 // Tizen Web Device API
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
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
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
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.
16 //
17
18 #include <map>
19 #include <string>
20 #include <Commons/Exception.h>
21 #include "Enums.h"
22 #include "IManager.h"
23 #include <Commons/WrtAccess/WrtAccess.h>
24 #include <WidgetDB/WidgetDBMgr.h>
25 #include <iconv.h>
26 #include "FilesystemUtils.h"
27 #include <Export.h>
28 #include <Logger.h>
29
30 using namespace WrtDeviceApis;
31 using namespace WrtDeviceApis::Commons;
32
33 namespace {
34 const std::string PATH_INVALID_COMPONENT_PARENT_DIR("..");
35 const std::string PATH_INVALID_COMPONENT_CURRENT_DIR(".");
36
37 typedef std::map<std::string, std::string> RootToPathMap;
38 typedef RootToPathMap::const_iterator RootToPathMapIterator;
39 typedef std::map<std::string, std::string> PathToRootMap;
40 typedef PathToRootMap::const_iterator PathToRootMapIterator;
41 }
42
43 namespace DeviceAPI {
44 namespace Filesystem {
45 namespace Utils{
46 const RootToPathMap DLL_EXPORT & getRootToPathMap()
47 {
48         static RootToPathMap result;
49         if (result.empty()) {
50         IManager& manager = IManager::getInstance();
51                 std::map<std::string, IPathPtr> locations = manager.getStorageList();
52
53                 std::map<std::string, IPathPtr>::const_iterator it;
54
55                 for (it = locations.begin(); it != locations.end(); ++it) {
56                         result[it->first] = it->second->getFullPath();
57                 }
58         }
59         return result;
60 }
61
62 const PathToRootMap DLL_EXPORT & getPathToRootMap()
63 {
64         static PathToRootMap result;
65         if (result.empty()) {
66                 IManager& manager = IManager::getInstance();
67                 std::map<std::string, IPathPtr> locations = manager.getStorageList();
68
69                 std::map<std::string, IPathPtr>::const_iterator it;
70
71                 for (it = locations.begin(); it != locations.end(); ++it) {
72                         result[it->second->getFullPath()] = it->first;
73                 }
74         }
75         return result;
76 }
77
78 IPathPtr DLL_EXPORT fromVirtualPath(JSContextRef context,
79                          const std::string& arg)
80 {
81         LoggerD("arg:[" << arg << "]");
82
83         // uri path, strip file://
84         if (isUriPath(arg)) {
85                 std::string stripPath = arg.substr(strlen("file://"));
86                 LoggerD("uri absolute path" << stripPath);
87                 IPathPtr result = IPath::create(stripPath);
88                 
89                 return result;
90         }
91         
92         if (!isPathValid(arg)) {
93                 LoggerD("virtual path is invalid:[" << arg << "]");
94                 ThrowMsg(Commons::ConversionException, "Not found path component.");
95         }
96
97         std::string root;
98         std::string tail;
99         std::string::size_type separatorPosition = arg.find(IPath::getSeparator());
100         if (separatorPosition != std::string::npos) {
101                 root = arg.substr(0, separatorPosition);
102                 tail = arg.substr(separatorPosition + 1, arg.size() - 1);
103         } else {
104                 root = arg;
105         }
106
107         int widgetId = WrtAccessSingleton::Instance().getWidgetId();
108         WidgetDB::Api::IWidgetDBPtr widgetDB = WidgetDB::Api::getWidgetDB(widgetId);
109
110         RootToPathMap rootToPath = getRootToPathMap();
111         rootToPath["wgt-package"] = widgetDB->getWidgetInstallationPath();
112         rootToPath["wgt-private"] = widgetDB->getWidgetPersistentStoragePath();
113         rootToPath["wgt-private-tmp"] = widgetDB->getWidgetTemporaryStoragePath();
114         RootToPathMapIterator it = rootToPath.find(root);
115
116         if (it == rootToPath.end()) {
117                 //ThrowMsg(Commons::NotFoundException, "Location not found.");
118                 LoggerD("Allow non virtual root path " << arg);
119                 return IPath::create(arg);
120         }
121         
122         IPathPtr result = IPath::create(it->second);
123
124         if (!tail.empty()) {
125                 result->append(tail);
126         }
127
128         return result;
129 }
130
131 std::string DLL_EXPORT toVirtualPath(JSContextRef context, const std::string& arg) {
132
133     int widgetId = WrtAccessSingleton::Instance().getWidgetId();
134     WidgetDB::Api::IWidgetDBPtr widgetDB =
135         WidgetDB::Api::getWidgetDB(widgetId);
136
137         PathToRootMap pathToRoot = getPathToRootMap();
138         pathToRoot[widgetDB->getWidgetInstallationPath()] = "wgt-package";
139         pathToRoot[widgetDB->getWidgetPersistentStoragePath()] = "wgt-private";
140         pathToRoot[widgetDB->getWidgetTemporaryStoragePath()] = "wgt-private-tmp";
141
142         std::string path = arg;
143         
144         std::string::size_type pos = path.size();
145         while (std::string::npos != (pos = path.rfind(IPath::getSeparator(), pos))) {
146                 PathToRootMapIterator it = pathToRoot.find(path);
147                 if (pathToRoot.end() != it) {
148                         return it->second + arg.substr(path.size());
149                 }
150                 path.erase(pos, path.size());
151         }
152         LoggerD("Allow non virtual root path");
153         
154         return arg;
155 //      ThrowMsg(Commons::ConversionException, "Path doesn't contain a valid location type.");
156 }
157
158 bool DLL_EXPORT isUriPath(const std::string& path) {
159                 const char* uriPrefix = "file://";
160                 const char* stringFromPath = path.c_str();
161
162                 if (!strncmp(uriPrefix, stringFromPath, strlen(uriPrefix)) && path[strlen(uriPrefix)] == '/') {
163                         return true;
164                 }
165                 
166                 return false;
167 }
168
169 bool DLL_EXPORT isPathValid(const std::string& path) {
170         static const std::string currentDirBegin(PATH_INVALID_COMPONENT_CURRENT_DIR + IPath::getSeparator());
171         static const std::string parentDirBegin(PATH_INVALID_COMPONENT_PARENT_DIR +
172                 IPath::getSeparator());
173         static const std::string currentDirMiddle(IPath::getSeparator() +
174                 PATH_INVALID_COMPONENT_CURRENT_DIR +IPath::getSeparator());
175         static const std::string parentDirMiddle(IPath::getSeparator() +
176                 PATH_INVALID_COMPONENT_PARENT_DIR +IPath::getSeparator());
177
178         if (path.find(parentDirBegin) == 0 ||
179                         path.find(currentDirBegin) == 0 ||
180                 path.find(parentDirMiddle) != std::string::npos ||
181                 path.find(currentDirMiddle) != std::string::npos) {
182                 return false;
183         }
184
185         return true;
186 }
187
188 void DLL_EXPORT toUTF8String(std::string fromEncoding, const char* from, const size_t fromLength, std::string &outputString)
189 {
190         const char *fromEncodingSet = fromEncoding.c_str();
191         char *outputBuf = NULL;
192         char *buf = NULL;
193         int ret = 0;
194         iconv_t cd;
195         size_t outputLength= 0;
196                 
197         try {
198 //              LoggerD("from " << fromEncodingSet << " to UTF8 conversion " << fromLength);
199                 
200                 cd = iconv_open("UTF-8", fromEncodingSet);
201
202                 if (cd == (iconv_t) -1) 
203                 {
204                         LoggerD("charset conversion exception iconv -1");
205                         ThrowMsg(Commons::PlatformException, "charset conversion exception");
206                 }
207
208                 if (fromLength == 0) 
209                 {
210                         LoggerD("from length 0");
211                         ThrowMsg(Commons::PlatformException, "Couldn't allocate output buffer.");
212                 }
213                 
214                 outputBuf = new char[fromLength * 4 + 1];
215                 outputLength = fromLength * 4;
216                 memset(outputBuf, 0, outputLength + 1);
217                 buf = outputBuf;
218                 
219                 
220                 ret = iconv(cd, (char**)&from, (size_t*)&fromLength, &buf, &outputLength);
221
222                 LoggerD(fromLength << " " << outputLength);
223                 
224                 if (ret < 0) 
225                 {
226                         iconv_close(cd);
227                         LoggerD("charset conversion exception ret " << ret);
228                         ThrowMsg(Commons::PlatformException, "charset conversion exception");
229                 }
230
231                 iconv_close(cd);
232                 outputString = outputBuf;
233                 
234                 if (outputBuf) 
235                         delete[] outputBuf;
236                 
237         }
238         Catch(std::bad_alloc) {
239                 LoggerD("Couldn't allocate output buffer.");
240                 ThrowMsg(Commons::PlatformException, "Couldn't allocate output buffer.");
241         }
242 }
243 }
244 }
245 }