Home | History | Annotate | Download | only in gtk
      1 /*
      2  * Copyright (C) 2007, 2009 Holger Hans Peter Freyther
      3  * Copyright (C) 2008 Collabora, Ltd.
      4  * Copyright (C) 2008 Apple Inc. All rights reserved.
      5  *
      6  * This library is free software; you can redistribute it and/or
      7  * modify it under the terms of the GNU Library General Public
      8  * License as published by the Free Software Foundation; either
      9  * version 2 of the License, or (at your option) any later version.
     10  *
     11  * This library is distributed in the hope that it will be useful,
     12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     14  * Library General Public License for more details.
     15  *
     16  * You should have received a copy of the GNU Library General Public License
     17  * along with this library; see the file COPYING.LIB.  If not, write to
     18  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     19  * Boston, MA 02110-1301, USA.
     20  */
     21 
     22 #include "config.h"
     23 #include "FileSystem.h"
     24 
     25 #include "GOwnPtr.h"
     26 #include "PlatformString.h"
     27 #include "CString.h"
     28 
     29 #include <glib.h>
     30 #include <glib/gstdio.h>
     31 
     32 #include <unistd.h>
     33 
     34 namespace WebCore {
     35 
     36 /* On linux file names are just raw bytes, so also strings that cannot be encoded in any way
     37  * are valid file names. This mean that we cannot just store a file name as-is in a String
     38  * but we have to escape it.
     39  * On Windows the GLib file name encoding is always UTF-8 so we can optimize this case. */
     40 String filenameToString(const char* filename)
     41 {
     42     if (!filename)
     43         return String();
     44 
     45 #if OS(WINDOWS)
     46     return String::fromUTF8(filename);
     47 #else
     48     gchar* escapedString = g_uri_escape_string(filename, "/:", false);
     49     String string(escapedString);
     50     g_free(escapedString);
     51     return string;
     52 #endif
     53 }
     54 
     55 char* filenameFromString(const String& string)
     56 {
     57 #if OS(WINDOWS)
     58     return g_strdup(string.utf8().data());
     59 #else
     60     return g_uri_unescape_string(string.utf8().data(), 0);
     61 #endif
     62 }
     63 
     64 // Converts a string to something suitable to be displayed to the user.
     65 String filenameForDisplay(const String& string)
     66 {
     67 #if OS(WINDOWS)
     68     return string;
     69 #else
     70     gchar* filename = filenameFromString(string);
     71     gchar* display = g_filename_to_utf8(filename, 0, 0, 0, 0);
     72     g_free(filename);
     73     if (!display)
     74         return string;
     75 
     76     String displayString = String::fromUTF8(display);
     77     g_free(display);
     78 
     79     return displayString;
     80 #endif
     81 }
     82 
     83 bool fileExists(const String& path)
     84 {
     85     bool result = false;
     86     gchar* filename = filenameFromString(path);
     87 
     88     if (filename) {
     89         result = g_file_test(filename, G_FILE_TEST_EXISTS);
     90         g_free(filename);
     91     }
     92 
     93     return result;
     94 }
     95 
     96 bool deleteFile(const String& path)
     97 {
     98     bool result = false;
     99     gchar* filename = filenameFromString(path);
    100 
    101     if (filename) {
    102         result = g_remove(filename) == 0;
    103         g_free(filename);
    104     }
    105 
    106     return result;
    107 }
    108 
    109 bool deleteEmptyDirectory(const String& path)
    110 {
    111     bool result = false;
    112     gchar* filename = filenameFromString(path);
    113 
    114     if (filename) {
    115         result = g_rmdir(filename) == 0;
    116         g_free(filename);
    117     }
    118 
    119     return result;
    120 }
    121 
    122 bool getFileSize(const String& path, long long& resultSize)
    123 {
    124     gchar* filename = filenameFromString(path);
    125     if (!filename)
    126         return false;
    127 
    128     struct stat statResult;
    129     gint result = g_stat(filename, &statResult);
    130     g_free(filename);
    131     if (result != 0)
    132         return false;
    133 
    134     resultSize = statResult.st_size;
    135     return true;
    136 }
    137 
    138 bool getFileModificationTime(const String& path, time_t& modifiedTime)
    139 {
    140     gchar* filename = filenameFromString(path);
    141     if (!filename)
    142         return false;
    143 
    144     struct stat statResult;
    145     gint result = g_stat(filename, &statResult);
    146     g_free(filename);
    147     if (result != 0)
    148         return false;
    149 
    150     modifiedTime = statResult.st_mtime;
    151     return true;
    152 
    153 }
    154 
    155 String pathByAppendingComponent(const String& path, const String& component)
    156 {
    157     if (path.endsWith(G_DIR_SEPARATOR_S))
    158         return path + component;
    159     else
    160         return path + G_DIR_SEPARATOR_S + component;
    161 }
    162 
    163 bool makeAllDirectories(const String& path)
    164 {
    165     gchar* filename = filenameFromString(path);
    166     if (!filename)
    167         return false;
    168 
    169     gint result = g_mkdir_with_parents(filename, S_IRWXU);
    170     g_free(filename);
    171 
    172     return result == 0;
    173 }
    174 
    175 String homeDirectoryPath()
    176 {
    177     return filenameToString(g_get_home_dir());
    178 }
    179 
    180 String pathGetFileName(const String& pathName)
    181 {
    182     if (pathName.isEmpty())
    183         return pathName;
    184 
    185     char* tmpFilename = filenameFromString(pathName);
    186     char* baseName = g_path_get_basename(tmpFilename);
    187     String fileName = String::fromUTF8(baseName);
    188     g_free(baseName);
    189     g_free(tmpFilename);
    190 
    191     return fileName;
    192 }
    193 
    194 String directoryName(const String& path)
    195 {
    196     /* No null checking needed */
    197     GOwnPtr<char> tmpFilename(filenameFromString(path));
    198     GOwnPtr<char> dirname(g_path_get_dirname(tmpFilename.get()));
    199     return String::fromUTF8(dirname.get());
    200 }
    201 
    202 Vector<String> listDirectory(const String& path, const String& filter)
    203 {
    204     Vector<String> entries;
    205 
    206     gchar* filename = filenameFromString(path);
    207     GDir* dir = g_dir_open(filename, 0, 0);
    208     if (!dir)
    209         return entries;
    210 
    211     GPatternSpec *pspec = g_pattern_spec_new((filter.utf8()).data());
    212     while (const char* name = g_dir_read_name(dir)) {
    213         if (!g_pattern_match_string(pspec, name))
    214             continue;
    215 
    216         gchar* entry = g_build_filename(filename, name, NULL);
    217         entries.append(filenameToString(entry));
    218         g_free(entry);
    219     }
    220     g_dir_close(dir);
    221     g_free(filename);
    222 
    223     return entries;
    224 }
    225 
    226 CString openTemporaryFile(const char* prefix, PlatformFileHandle& handle)
    227 {
    228     gchar* filename = g_strdup_printf("%sXXXXXX", prefix);
    229     gchar* tempPath = g_build_filename(g_get_tmp_dir(), filename, NULL);
    230     g_free(filename);
    231 
    232     int fileDescriptor = g_mkstemp(tempPath);
    233     if (!isHandleValid(fileDescriptor)) {
    234         LOG_ERROR("Can't create a temporary file.");
    235         g_free(tempPath);
    236         return CString();
    237     }
    238     CString tempFilePath = tempPath;
    239     g_free(tempPath);
    240 
    241     handle = fileDescriptor;
    242     return tempFilePath;
    243 }
    244 
    245 void closeFile(PlatformFileHandle& handle)
    246 {
    247     if (isHandleValid(handle)) {
    248         close(handle);
    249         handle = invalidPlatformFileHandle;
    250     }
    251 }
    252 
    253 int writeToFile(PlatformFileHandle handle, const char* data, int length)
    254 {
    255     int totalBytesWritten = 0;
    256     while (totalBytesWritten < length) {
    257         int bytesWritten = write(handle, data, length - totalBytesWritten);
    258         if (bytesWritten < 0)
    259             return -1;
    260         totalBytesWritten += bytesWritten;
    261     }
    262 
    263     return totalBytesWritten;
    264 }
    265 
    266 bool unloadModule(PlatformModule module)
    267 {
    268     return g_module_close(module);
    269 }
    270 }
    271