WebCore/platform/gtk/FileSystemGtk.cpp
changeset 0 4f2f89ce4247
equal deleted inserted replaced
-1:000000000000 0:4f2f89ce4247
       
     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 
       
    28 #include <errno.h>
       
    29 #include <fcntl.h>
       
    30 #include <glib.h>
       
    31 #include <glib/gstdio.h>
       
    32 #include <unistd.h>
       
    33 #include <wtf/text/CString.h>
       
    34 
       
    35 namespace WebCore {
       
    36 
       
    37 /* On linux file names are just raw bytes, so also strings that cannot be encoded in any way
       
    38  * are valid file names. This mean that we cannot just store a file name as-is in a String
       
    39  * but we have to escape it.
       
    40  * On Windows the GLib file name encoding is always UTF-8 so we can optimize this case. */
       
    41 String filenameToString(const char* filename)
       
    42 {
       
    43     if (!filename)
       
    44         return String();
       
    45 
       
    46 #if OS(WINDOWS)
       
    47     return String::fromUTF8(filename);
       
    48 #else
       
    49     gchar* escapedString = g_uri_escape_string(filename, "/:", false);
       
    50     String string(escapedString);
       
    51     g_free(escapedString);
       
    52     return string;
       
    53 #endif
       
    54 }
       
    55 
       
    56 CString fileSystemRepresentation(const String& path)
       
    57 {
       
    58 #if OS(WINDOWS)
       
    59     return path.utf8();
       
    60 #else
       
    61     char* filename = g_uri_unescape_string(path.utf8().data(), 0);
       
    62     CString cfilename(filename);
       
    63     g_free(filename);
       
    64     return cfilename;
       
    65 #endif
       
    66 }
       
    67 
       
    68 // Converts a string to something suitable to be displayed to the user.
       
    69 String filenameForDisplay(const String& string)
       
    70 {
       
    71 #if OS(WINDOWS)
       
    72     return string;
       
    73 #else
       
    74     CString filename = fileSystemRepresentation(string);
       
    75     gchar* display = g_filename_to_utf8(filename.data(), 0, 0, 0, 0);
       
    76     if (!display)
       
    77         return string;
       
    78 
       
    79     String displayString = String::fromUTF8(display);
       
    80     g_free(display);
       
    81 
       
    82     return displayString;
       
    83 #endif
       
    84 }
       
    85 
       
    86 bool fileExists(const String& path)
       
    87 {
       
    88     bool result = false;
       
    89     CString filename = fileSystemRepresentation(path);
       
    90 
       
    91     if (!filename.isNull())
       
    92         result = g_file_test(filename.data(), G_FILE_TEST_EXISTS);
       
    93 
       
    94     return result;
       
    95 }
       
    96 
       
    97 bool deleteFile(const String& path)
       
    98 {
       
    99     bool result = false;
       
   100     CString filename = fileSystemRepresentation(path);
       
   101 
       
   102     if (!filename.isNull())
       
   103         result = g_remove(filename.data()) == 0;
       
   104 
       
   105     return result;
       
   106 }
       
   107 
       
   108 bool deleteEmptyDirectory(const String& path)
       
   109 {
       
   110     bool result = false;
       
   111     CString filename = fileSystemRepresentation(path);
       
   112 
       
   113     if (!filename.isNull())
       
   114         result = g_rmdir(filename.data()) == 0;
       
   115 
       
   116     return result;
       
   117 }
       
   118 
       
   119 bool getFileSize(const String& path, long long& resultSize)
       
   120 {
       
   121     CString filename = fileSystemRepresentation(path);
       
   122     if (filename.isNull())
       
   123         return false;
       
   124 
       
   125     struct stat statResult;
       
   126     gint result = g_stat(filename.data(), &statResult);
       
   127     if (result != 0)
       
   128         return false;
       
   129 
       
   130     resultSize = statResult.st_size;
       
   131     return true;
       
   132 }
       
   133 
       
   134 bool getFileModificationTime(const String& path, time_t& modifiedTime)
       
   135 {
       
   136     CString filename = fileSystemRepresentation(path);
       
   137     if (filename.isNull())
       
   138         return false;
       
   139 
       
   140     struct stat statResult;
       
   141     gint result = g_stat(filename.data(), &statResult);
       
   142     if (result != 0)
       
   143         return false;
       
   144 
       
   145     modifiedTime = statResult.st_mtime;
       
   146     return true;
       
   147 
       
   148 }
       
   149 
       
   150 String pathByAppendingComponent(const String& path, const String& component)
       
   151 {
       
   152     if (path.endsWith(G_DIR_SEPARATOR_S))
       
   153         return path + component;
       
   154     else
       
   155         return path + G_DIR_SEPARATOR_S + component;
       
   156 }
       
   157 
       
   158 bool makeAllDirectories(const String& path)
       
   159 {
       
   160     CString filename = fileSystemRepresentation(path);
       
   161     if (filename.isNull())
       
   162         return false;
       
   163 
       
   164     gint result = g_mkdir_with_parents(filename.data(), S_IRWXU);
       
   165 
       
   166     return result == 0;
       
   167 }
       
   168 
       
   169 String homeDirectoryPath()
       
   170 {
       
   171     return filenameToString(g_get_home_dir());
       
   172 }
       
   173 
       
   174 String pathGetFileName(const String& pathName)
       
   175 {
       
   176     if (pathName.isEmpty())
       
   177         return pathName;
       
   178 
       
   179     CString tmpFilename = fileSystemRepresentation(pathName);
       
   180     char* baseName = g_path_get_basename(tmpFilename.data());
       
   181     String fileName = String::fromUTF8(baseName);
       
   182     g_free(baseName);
       
   183 
       
   184     return fileName;
       
   185 }
       
   186 
       
   187 String directoryName(const String& path)
       
   188 {
       
   189     /* No null checking needed */
       
   190     GOwnPtr<char> tmpFilename(const_cast<char*>(fileSystemRepresentation(path).data()));
       
   191     GOwnPtr<char> dirname(g_path_get_dirname(tmpFilename.get()));
       
   192     return String::fromUTF8(dirname.get());
       
   193 }
       
   194 
       
   195 Vector<String> listDirectory(const String& path, const String& filter)
       
   196 {
       
   197     Vector<String> entries;
       
   198 
       
   199     CString filename = fileSystemRepresentation(path);
       
   200     GDir* dir = g_dir_open(filename.data(), 0, 0);
       
   201     if (!dir)
       
   202         return entries;
       
   203 
       
   204     GPatternSpec *pspec = g_pattern_spec_new((filter.utf8()).data());
       
   205     while (const char* name = g_dir_read_name(dir)) {
       
   206         if (!g_pattern_match_string(pspec, name))
       
   207             continue;
       
   208 
       
   209         GOwnPtr<gchar> entry(g_build_filename(filename.data(), name, NULL));
       
   210         entries.append(filenameToString(entry.get()));
       
   211     }
       
   212     g_pattern_spec_free(pspec);
       
   213     g_dir_close(dir);
       
   214 
       
   215     return entries;
       
   216 }
       
   217 
       
   218 CString openTemporaryFile(const char* prefix, PlatformFileHandle& handle)
       
   219 {
       
   220     gchar* filename = g_strdup_printf("%sXXXXXX", prefix);
       
   221     gchar* tempPath = g_build_filename(g_get_tmp_dir(), filename, NULL);
       
   222     g_free(filename);
       
   223 
       
   224     int fileDescriptor = g_mkstemp(tempPath);
       
   225     if (!isHandleValid(fileDescriptor)) {
       
   226         LOG_ERROR("Can't create a temporary file.");
       
   227         g_free(tempPath);
       
   228         return CString();
       
   229     }
       
   230     CString tempFilePath = tempPath;
       
   231     g_free(tempPath);
       
   232 
       
   233     handle = fileDescriptor;
       
   234     return tempFilePath;
       
   235 }
       
   236 
       
   237 PlatformFileHandle openFile(const String& path, FileOpenMode mode)
       
   238 {
       
   239     CString fsRep = fileSystemRepresentation(path);
       
   240 
       
   241     if (fsRep.isNull())
       
   242         return invalidPlatformFileHandle;
       
   243 
       
   244     int platformFlag = 0;
       
   245     if (mode == OpenForRead)
       
   246         platformFlag |= O_RDONLY;
       
   247     else if (mode == OpenForWrite)
       
   248         platformFlag |= (O_WRONLY | O_CREAT | O_TRUNC);
       
   249 
       
   250     return g_open(fsRep.data(), platformFlag, 0666);
       
   251 }
       
   252 
       
   253 void closeFile(PlatformFileHandle& handle)
       
   254 {
       
   255     if (isHandleValid(handle)) {
       
   256         close(handle);
       
   257         handle = invalidPlatformFileHandle;
       
   258     }
       
   259 }
       
   260 
       
   261 int writeToFile(PlatformFileHandle handle, const char* data, int length)
       
   262 {
       
   263     int totalBytesWritten = 0;
       
   264     while (totalBytesWritten < length) {
       
   265         int bytesWritten = write(handle, data, length - totalBytesWritten);
       
   266         if (bytesWritten < 0)
       
   267             return -1;
       
   268         totalBytesWritten += bytesWritten;
       
   269         data += bytesWritten;
       
   270     }
       
   271 
       
   272     return totalBytesWritten;
       
   273 }
       
   274 
       
   275 int readFromFile(PlatformFileHandle handle, char* data, int length)
       
   276 {
       
   277     do {
       
   278         int bytesRead = read(handle, data, static_cast<size_t>(length));
       
   279         if (bytesRead >= 0)
       
   280             return bytesRead;
       
   281     } while (errno == EINTR);
       
   282 
       
   283     return -1;
       
   284 }
       
   285 
       
   286 bool unloadModule(PlatformModule module)
       
   287 {
       
   288     return g_module_close(module);
       
   289 }
       
   290 }