1/* 2 * Copyright (C) 2010 Company 100, Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 14 * its contributors may be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29#include "config.h" 30#include "FileSystem.h" 31 32#include "NotImplemented.h" 33 34#include <AEEAppGen.h> 35#include <AEEFile.h> 36#include <AEEStdLib.h> 37 38#include <wtf/RandomNumber.h> 39#include <wtf/brew/RefPtrBrew.h> 40#include <wtf/brew/ShellBrew.h> 41#include <wtf/text/CString.h> 42#include <wtf/text/StringBuilder.h> 43#include <wtf/text/WTFString.h> 44 45namespace WebCore { 46 47bool getFileSize(const String& path, long long& result) 48{ 49 RefPtr<IFileMgr> fileMgr = createRefPtrInstance<IFileMgr>(AEECLSID_FILEMGR); 50 FileInfo info; 51 52 if (IFILEMGR_GetInfo(fileMgr.get(), path.utf8().data(), &info) == SUCCESS) { 53 result = info.dwSize; 54 return true; 55 } 56 57 return false; 58} 59 60bool getFileModificationTime(const String& path, time_t& result) 61{ 62 // There is no way to get file modification time in BREW. IFILEMGR_GetInfoEx() returns 63 // only file creation time. 64 return false; 65} 66 67bool fileExists(const String& path) 68{ 69 RefPtr<IFileMgr> fileMgr = createRefPtrInstance<IFileMgr>(AEECLSID_FILEMGR); 70 71 return (IFILEMGR_Test(fileMgr.get(), path.utf8().data()) == SUCCESS); 72} 73 74bool deleteFile(const String& path) 75{ 76 RefPtr<IFileMgr> fileMgr = createRefPtrInstance<IFileMgr>(AEECLSID_FILEMGR); 77 78 return (IFILEMGR_Remove(fileMgr.get(), path.utf8().data()) == SUCCESS); 79} 80 81bool deleteEmptyDirectory(const String& path) 82{ 83 RefPtr<IFileMgr> fileMgr = createRefPtrInstance<IFileMgr>(AEECLSID_FILEMGR); 84 85 return (IFILEMGR_RmDir(fileMgr.get(), path.utf8().data()) == SUCCESS); 86} 87 88String pathByAppendingComponent(const String& path, const String& component) 89{ 90 if (component.isEmpty()) 91 return path; 92 93 Vector<UChar, 1024> buffer; 94 95 buffer.append(path.characters(), path.length()); 96 97 if (buffer.last() != L'/' && component[0] != L'/') 98 buffer.append(L'/'); 99 100 buffer.append(component.characters(), component.length()); 101 102 return String(buffer.data(), buffer.size()); 103} 104 105CString fileSystemRepresentation(const String& path) 106{ 107 return path.utf8(); 108} 109 110static String canonicalPath(const String& path) 111{ 112 RefPtr<IFileMgr> fileMgr = createRefPtrInstance<IFileMgr>(AEECLSID_FILEMGR); 113 114 // Get the buffer size required to resolve the path. 115 int canonPathLen; 116 IFILEMGR_ResolvePath(fileMgr.get(), path.utf8().data(), 0, &canonPathLen); 117 118 // Resolve the path to the canonical path. 119 Vector<char> canonPathBuffer(canonPathLen); 120 IFILEMGR_ResolvePath(fileMgr.get(), path.utf8().data(), canonPathBuffer.data(), &canonPathLen); 121 122 String canonPath(canonPathBuffer.data()); 123 124 // Remove the trailing '/'. 125 int lastDivPos = canonPath.reverseFind('/'); 126 int endPos = canonPath.length(); 127 if (lastDivPos == endPos - 1) 128 canonPath = canonPath.substring(0, canonPath.length() - 1); 129 130 return canonPath; 131} 132 133static bool makeAllDirectories(IFileMgr* fileManager, const String& path) 134{ 135 if (path == canonicalPath(AEEFS_HOME_DIR)) 136 return true; 137 138 int lastDivPos = path.reverseFind('/'); 139 int endPos = path.length(); 140 if (lastDivPos == path.length() - 1) { 141 endPos -= 1; 142 lastDivPos = path.reverseFind('/', lastDivPos); 143 } 144 145 if (lastDivPos > 0) { 146 if (!makeAllDirectories(fileManager, path.substring(0, lastDivPos))) 147 return false; 148 } 149 150 String folder(path.substring(0, endPos)); 151 152 // IFILEMGR_MkDir return SUCCESS when the file is successfully created or if file already exists. 153 // So we need to check fileinfo.attrib. 154 IFILEMGR_MkDir(fileManager, folder.utf8().data()); 155 156 FileInfo fileInfo; 157 if (IFILEMGR_GetInfo(fileManager, folder.utf8().data(), &fileInfo) != SUCCESS) 158 return false; 159 160 return fileInfo.attrib & _FA_DIR; 161} 162 163bool makeAllDirectories(const String& path) 164{ 165 RefPtr<IFileMgr> fileMgr = createRefPtrInstance<IFileMgr>(AEECLSID_FILEMGR); 166 167 return makeAllDirectories(fileMgr.get(), canonicalPath(path)); 168} 169 170String homeDirectoryPath() 171{ 172 const int webViewClassId = 0x010aa04c; 173 return String::format("fs:/~0X%08X/", webViewClassId); 174} 175 176String pathGetFileName(const String& path) 177{ 178 return path.substring(path.reverseFind('/') + 1); 179} 180 181String directoryName(const String& path) 182{ 183 String fileName = pathGetFileName(path); 184 String dirName = String(path); 185 dirName.truncate(dirName.length() - pathGetFileName(path).length()); 186 return dirName; 187} 188 189String openTemporaryFile(const String& prefix, PlatformFileHandle& handle) 190{ 191 // BREW does not have a system-wide temporary directory, 192 // use "fs:/~/tmp" as our temporary directory. 193 String tempPath("fs:/~/tmp"); 194 195 RefPtr<IFileMgr> fileMgr = createRefPtrInstance<IFileMgr>(AEECLSID_FILEMGR); 196 197 // Create the temporary directory if it does not exist. 198 IFILEMGR_MkDir(fileMgr.get(), tempPath.utf8().data()); 199 200 // Loop until we find a temporary filename that does not exist. 201 int number = static_cast<int>(randomNumber() * 10000); 202 String filename; 203 do { 204 StringBuilder builder; 205 builder.append(tempPath); 206 builder.append('/'); 207 builder.append(prefix); 208 builder.append(String::number(number)); 209 filename = builder.toString(); 210 number++; 211 } while (IFILEMGR_Test(fileMgr.get(), filename.utf8().data()) == SUCCESS); 212 213 IFile* tempFile = IFILEMGR_OpenFile(fileMgr.get(), filename.utf8().data(), _OFM_CREATE); 214 if (tempFile) { 215 handle = tempFile; 216 return filename; 217 } 218 219 return String(); 220} 221 222void closeFile(PlatformFileHandle& handle) 223{ 224 if (isHandleValid(handle)) { 225 IFILE_Release(handle); 226 handle = invalidPlatformFileHandle; 227 } 228} 229 230int writeToFile(PlatformFileHandle handle, const char* data, int length) 231{ 232 if (!isHandleValid(handle)) 233 return -1; 234 235 int bytesWritten = IFILE_Write(handle, data, length); 236 if (!bytesWritten) 237 return -1; 238 return bytesWritten; 239} 240 241bool unloadModule(PlatformModule module) 242{ 243 notImplemented(); 244 245 return false; 246} 247 248Vector<String> listDirectory(const String& path, const String& filter) 249{ 250 Vector<String> entries; 251 252 // OK to not implement listDirectory, because it's only used for plug-ins and 253 // Brew MP does not support the plug-in at the moment. 254 notImplemented(); 255 256 return entries; 257} 258 259} 260