1/*
2 * Copyright (C) 2010 Google 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 are
6 * met:
7 *
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#include "config.h"
32#include "FileStream.h"
33
34#include <wtf/text/WTFString.h>
35
36namespace WebCore {
37
38FileStream::FileStream()
39 : m_handle(FileSystem::invalidPlatformFileHandle)
40 , m_bytesProcessed(0)
41 , m_totalBytesToRead(0)
42{
43}
44
45FileStream::~FileStream()
46{
47 close();
48}
49
50long long FileStream::getSize(const String& path, Optional<WallTime> expectedModificationTime)
51{
52 // Check the modification time for the possible file change.
53 auto modificationTime = FileSystem::getFileModificationTime(path);
54 if (!modificationTime)
55 return -1;
56 if (expectedModificationTime) {
57 if (expectedModificationTime->secondsSinceEpoch().secondsAs<time_t>() != modificationTime->secondsSinceEpoch().secondsAs<time_t>())
58 return -1;
59 }
60
61 // Now get the file size.
62 long long length;
63 if (!FileSystem::getFileSize(path, length))
64 return -1;
65
66 return length;
67}
68
69bool FileStream::openForRead(const String& path, long long offset, long long length)
70{
71 if (FileSystem::isHandleValid(m_handle))
72 return true;
73
74 // Open the file.
75 m_handle = FileSystem::openFile(path, FileSystem::FileOpenMode::Read);
76 if (!FileSystem::isHandleValid(m_handle))
77 return false;
78
79 // Jump to the beginning position if the file has been sliced.
80 if (offset > 0) {
81 if (FileSystem::seekFile(m_handle, offset, FileSystem::FileSeekOrigin::Beginning) < 0)
82 return false;
83 }
84
85 m_totalBytesToRead = length;
86 m_bytesProcessed = 0;
87
88 return true;
89}
90
91void FileStream::close()
92{
93 if (FileSystem::isHandleValid(m_handle)) {
94 FileSystem::closeFile(m_handle);
95 m_handle = FileSystem::invalidPlatformFileHandle;
96 }
97}
98
99int FileStream::read(char* buffer, int bufferSize)
100{
101 if (!FileSystem::isHandleValid(m_handle))
102 return -1;
103
104 long long remaining = m_totalBytesToRead - m_bytesProcessed;
105 int bytesToRead = (remaining < bufferSize) ? static_cast<int>(remaining) : bufferSize;
106 int bytesRead = 0;
107 if (bytesToRead > 0)
108 bytesRead = FileSystem::readFromFile(m_handle, buffer, bytesToRead);
109 if (bytesRead < 0)
110 return -1;
111 if (bytesRead > 0)
112 m_bytesProcessed += bytesRead;
113
114 return bytesRead;
115}
116
117} // namespace WebCore
118