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