1/*
2 * Copyright (C) 2007 Kevin Ollivier
3 * Copyright (C) 2008 Collabora, Ltd.
4 * Copyright (C) 2009 Peter Laufenberg @ Inhance Digital Corp
5 *
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
21 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
25 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#include "config.h"
31#include "FileSystem.h"
32
33#include "NotImplemented.h"
34#include "PlatformString.h"
35#include <wtf/text/CString.h>
36
37#include <wx/wx.h>
38#include <wx/datetime.h>
39#include <wx/dir.h>
40#include <wx/dynlib.h>
41#include <wx/file.h>
42#include <wx/filefn.h>
43#include <wx/filename.h>
44
45#if OS(DARWIN)
46#include <CoreFoundation/CoreFoundation.h>
47#endif
48
49namespace WebCore {
50
51bool fileExists(const String& path)
52{
53    // NOTE: This is called for directory paths too so we need to check both.
54    return wxFileName::FileExists(path) || wxFileName::DirExists(path);
55}
56
57bool deleteFile(const String& path)
58{
59    return wxRemoveFile(path);
60}
61
62bool deleteEmptyDirectory(const String& path)
63{
64    return wxFileName::Rmdir(path);
65}
66
67bool getFileSize(const String& path, long long& resultSize)
68{
69    wxULongLong size = wxFileName::GetSize(path);
70    if (wxInvalidSize != size) {
71        // TODO: why is FileSystem::getFileSize signed?
72        resultSize = (long long)size.GetValue();
73        return true;
74    }
75
76    return false;
77}
78
79bool getFileModificationTime(const String& path, time_t& t)
80{
81    if (wxFileExists(path)) {
82        t = wxFileName(path).GetModificationTime().GetTicks();
83        return true;
84    }
85    return false;
86}
87
88bool makeAllDirectories(const String& path)
89{
90    return wxFileName::Mkdir(path, 0777, wxPATH_MKDIR_FULL);
91}
92
93String pathByAppendingComponent(const String& path, const String& component)
94{
95    return wxFileName(path, component).GetFullPath();
96}
97
98String homeDirectoryPath()
99{
100    return wxFileName::GetHomeDir();
101}
102
103String pathGetFileName(const String& path)
104{
105    return wxFileName(path).GetFullName();
106}
107
108String directoryName(const String& path)
109{
110    return wxFileName(path).GetPath();
111}
112
113String openTemporaryFile(const String& prefix, PlatformFileHandle& handle)
114{
115    wxString sFilename = wxFileName::CreateTempFileName(prefix);
116    wxFile* temp = new wxFile();
117    temp->Open(sFilename.c_str(), wxFile::read_write);
118    handle = temp;
119    return String(sFilename);
120}
121
122void closeFile(PlatformFileHandle& handle)
123{
124    if (handle)
125        delete handle;
126}
127
128int writeToFile(PlatformFileHandle handle, const char* data, int length)
129{
130    if (handle)
131        return static_cast<wxFile*>(handle)->Write(data, length);
132    return -1;
133}
134
135bool unloadModule(PlatformModule mod)
136{
137#if OS(WINDOWS)
138    return ::FreeLibrary(mod);
139#elif OS(DARWIN)
140    CFRelease(mod);
141    return true;
142#else
143    wxASSERT(mod);
144    delete mod;
145    return true;
146#endif
147}
148
149
150class wxDirTraverserNonRecursive : public wxDirTraverser {
151public:
152    wxDirTraverserNonRecursive(wxString basePath, wxArrayString& files) : m_basePath(basePath), m_files(files) { }
153
154    virtual wxDirTraverseResult OnFile(const wxString& filename)
155    {
156        wxFileName afile(filename);
157        afile.MakeRelativeTo(m_basePath);
158        if (afile.GetFullPath().Find(afile.GetPathSeparator()) == wxNOT_FOUND)
159            m_files.push_back(filename);
160
161        return wxDIR_CONTINUE;
162    }
163
164    virtual wxDirTraverseResult OnDir(const wxString& dirname)
165    {
166        wxFileName dirfile(dirname);
167        dirfile.MakeRelativeTo(m_basePath);
168        if (dirfile.GetFullPath().Find(dirfile.GetPathSeparator()) == wxNOT_FOUND)
169            m_files.push_back(dirname);
170
171        return wxDIR_CONTINUE;
172    }
173
174private:
175    wxString m_basePath;
176    wxArrayString& m_files;
177
178    DECLARE_NO_COPY_CLASS(wxDirTraverserNonRecursive)
179};
180
181Vector<String> listDirectory(const String& path, const String& filter)
182{
183    wxArrayString   file_paths;
184    // wxDir::GetAllFiles recurses and for platforms like Mac where
185    // a .plugin or .bundle can be a dir wx will recurse into the bundle
186    // and list the files rather than just returning the plugin name, so
187    // we write a special traverser that works around that issue.
188    wxDirTraverserNonRecursive traverser(path, file_paths);
189
190    wxDir dir(path);
191    dir.Traverse(traverser, _T(""), wxDIR_FILES | wxDIR_DIRS);
192
193    Vector<String> entries;
194
195    for (int i = 0; i < file_paths.GetCount(); i++)
196    {
197        entries.append(file_paths[i]);
198    }
199
200    return entries;
201}
202
203}
204