Home | History | Annotate | Download | only in brew
      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 
     45 namespace WebCore {
     46 
     47 bool 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 
     60 bool 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 
     67 bool 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 
     74 bool 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 
     81 bool 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 
     88 String 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 
    105 CString fileSystemRepresentation(const String& path)
    106 {
    107     return path.utf8();
    108 }
    109 
    110 static 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 
    133 static 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 
    163 bool makeAllDirectories(const String& path)
    164 {
    165     RefPtr<IFileMgr> fileMgr = createRefPtrInstance<IFileMgr>(AEECLSID_FILEMGR);
    166 
    167     return makeAllDirectories(fileMgr.get(), canonicalPath(path));
    168 }
    169 
    170 String homeDirectoryPath()
    171 {
    172     const int webViewClassId = 0x010aa04c;
    173     return String::format("fs:/~0X%08X/", webViewClassId);
    174 }
    175 
    176 String pathGetFileName(const String& path)
    177 {
    178     return path.substring(path.reverseFind('/') + 1);
    179 }
    180 
    181 String 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 
    189 String 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 
    222 void closeFile(PlatformFileHandle& handle)
    223 {
    224     if (isHandleValid(handle)) {
    225         IFILE_Release(handle);
    226         handle = invalidPlatformFileHandle;
    227     }
    228 }
    229 
    230 int 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 
    241 bool unloadModule(PlatformModule module)
    242 {
    243     notImplemented();
    244 
    245     return false;
    246 }
    247 
    248 Vector<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