1/*
2 * Copyright (C) 2016 Apple 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 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 "FileHandle.h"
31
32namespace WebCore {
33
34FileHandle::FileHandle(const String& path, FileSystem::FileOpenMode mode)
35 : m_path { path }
36 , m_mode { mode }
37{
38}
39
40FileHandle::FileHandle(FileHandle&& other)
41 : m_path { WTFMove(other.m_path) }
42 , m_mode { WTFMove(other.m_mode) }
43 , m_fileHandle { std::exchange(other.m_fileHandle, FileSystem::invalidPlatformFileHandle) }
44{
45}
46
47FileHandle::FileHandle(const String& path, FileSystem::FileOpenMode mode, OptionSet<FileSystem::FileLockMode> lockMode)
48 : m_path { path }
49 , m_mode { mode }
50 , m_lockMode { lockMode }
51 , m_shouldLock { true }
52{
53}
54
55FileHandle::~FileHandle()
56{
57 close();
58}
59
60FileHandle& FileHandle::operator=(FileHandle&& other)
61{
62 close();
63 m_path = WTFMove(other.m_path);
64 m_mode = WTFMove(other.m_mode);
65 m_fileHandle = std::exchange(other.m_fileHandle, FileSystem::invalidPlatformFileHandle);
66 return *this;
67}
68
69FileHandle::operator bool() const
70{
71 return FileSystem::isHandleValid(m_fileHandle);
72}
73
74bool FileHandle::open(const String& path, FileSystem::FileOpenMode mode)
75{
76 if (*this && path == m_path && mode == m_mode)
77 return true;
78
79 close();
80 m_path = path;
81 m_mode = mode;
82 return open();
83}
84
85bool FileHandle::open()
86{
87 if (!*this)
88 m_fileHandle = m_shouldLock ? FileSystem::openAndLockFile(m_path, m_mode, m_lockMode) : FileSystem::openFile(m_path, m_mode);
89 return static_cast<bool>(*this);
90}
91
92int FileHandle::read(void* data, int length)
93{
94 if (!open())
95 return -1;
96 return FileSystem::readFromFile(m_fileHandle, static_cast<char*>(data), length);
97}
98
99int FileHandle::write(const void* data, int length)
100{
101 if (!open())
102 return -1;
103 return FileSystem::writeToFile(m_fileHandle, static_cast<const char*>(data), length);
104}
105
106bool FileHandle::printf(const char* format, ...)
107{
108 va_list args;
109 va_start(args, format);
110
111 va_list preflightArgs;
112 va_copy(preflightArgs, args);
113 size_t stringLength = vsnprintf(nullptr, 0, format, preflightArgs);
114 va_end(preflightArgs);
115
116 Vector<char, 1024> buffer(stringLength + 1);
117 vsnprintf(buffer.data(), stringLength + 1, format, args);
118
119 va_end(args);
120
121 return write(buffer.data(), stringLength) >= 0;
122}
123
124void FileHandle::close()
125{
126 if (m_shouldLock && *this) {
127 // FileSystem::unlockAndCloseFile requires the file handle to be valid while closeFile does not
128 FileSystem::unlockAndCloseFile(m_fileHandle);
129 } else
130 FileSystem::closeFile(m_fileHandle);
131}
132
133} // namespace WebCore
134