LMMS
Loading...
Searching...
No Matches
FileOutputStream.cpp
Go to the documentation of this file.
1/*
2 ==============================================================================
3
4 This file is part of the Water library.
5 Copyright (c) 2016 ROLI Ltd.
6 Copyright (C) 2017 Filipe Coelho <falktx@falktx.com>
7
8 Permission is granted to use this software under the terms of the ISC license
9 http://www.isc.org/downloads/software-support-policy/isc-license/
10
11 Permission to use, copy, modify, and/or distribute this software for any
12 purpose with or without fee is hereby granted, provided that the above
13 copyright notice and this permission notice appear in all copies.
14
15 THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH REGARD
16 TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17 FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
18 OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
19 USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
20 TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
21 OF THIS SOFTWARE.
22
23 ==============================================================================
24*/
25
26#include "FileOutputStream.h"
27
28namespace water {
29
30int64 water_fileSetPosition (void* handle, int64 pos);
31
32//==============================================================================
33FileOutputStream::FileOutputStream (const File& f, const size_t bufferSizeToUse)
34 : file (f),
36 status (Result::ok()),
38 bufferSize (bufferSizeToUse),
40{
41 if (buffer.malloc(jmax (bufferSizeToUse, (size_t) 16)))
42 openHandle();
43 else
44 status = Result::fail ("Allocation failure");
45}
46
52
57
59{
60 if (newPosition != currentPosition)
61 {
64 }
65
66 return newPosition == currentPosition;
67}
68
70{
71 bool ok = true;
72
73 if (bytesInBuffer > 0)
74 {
75 ok = (writeInternal (buffer, bytesInBuffer) == (ssize_t) bytesInBuffer);
76 bytesInBuffer = 0;
77 }
78
79 return ok;
80}
81
87
88bool FileOutputStream::write (const void* const src, const size_t numBytes)
89{
90 wassert (src != nullptr && ((ssize_t) numBytes) >= 0);
91
92 if (bytesInBuffer + numBytes < bufferSize)
93 {
94 memcpy (buffer + bytesInBuffer, src, numBytes);
95 bytesInBuffer += numBytes;
96 currentPosition += (int64) numBytes;
97 }
98 else
99 {
100 if (! flushBuffer())
101 return false;
102
103 if (numBytes < bufferSize)
104 {
105 memcpy (buffer + bytesInBuffer, src, numBytes);
106 bytesInBuffer += numBytes;
107 currentPosition += (int64) numBytes;
108 }
109 else
110 {
111 const ssize_t bytesWritten = writeInternal (src, numBytes);
112
113 if (bytesWritten < 0)
114 return false;
115
116 currentPosition += (int64) bytesWritten;
117 return bytesWritten == (ssize_t) numBytes;
118 }
119 }
120
121 return true;
122}
123
124bool FileOutputStream::writeRepeatedByte (uint8 byte, size_t numBytes)
125{
126 wassert (((ssize_t) numBytes) >= 0);
127
128 if (bytesInBuffer + numBytes < bufferSize)
129 {
130 memset (buffer + bytesInBuffer, byte, numBytes);
131 bytesInBuffer += numBytes;
132 currentPosition += (int64) numBytes;
133 return true;
134 }
135
136 return OutputStream::writeRepeatedByte (byte, numBytes);
137}
138
139#ifdef CARLA_OS_WIN
141{
142 HANDLE h = CreateFileA (file.getFullPathName().toUTF8(), GENERIC_WRITE, FILE_SHARE_READ, 0,
143 OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
144
145 if (h != INVALID_HANDLE_VALUE)
146 {
147 LARGE_INTEGER li;
148 li.QuadPart = 0;
149 li.LowPart = SetFilePointer (h, 0, &li.HighPart, FILE_END);
150
151 if (li.LowPart != INVALID_SET_FILE_POINTER)
152 {
153 fileHandle = (void*) h;
154 currentPosition = li.QuadPart;
155 return;
156 }
157 }
158
159 status = getResultForLastError();
160}
161
163{
165}
166
167ssize_t FileOutputStream::writeInternal (const void* bufferToWrite, size_t numBytes)
168{
169 if (fileHandle != nullptr)
170 {
171 DWORD actualNum = 0;
172 if (! WriteFile ((HANDLE) fileHandle, bufferToWrite, (DWORD) numBytes, &actualNum, 0))
173 status = getResultForLastError();
174
175 return (ssize_t) actualNum;
176 }
177
178 return 0;
179}
180
182{
183 if (fileHandle != nullptr)
184 if (! FlushFileBuffers ((HANDLE) fileHandle))
185 status = getResultForLastError();
186}
187#else
189{
190 if (file.exists())
191 {
192 const int f = open (file.getFullPathName().toUTF8(), O_RDWR, 00644);
193
194 if (f != -1)
195 {
197
198 if (currentPosition >= 0)
199 {
200 fileHandle = fdToVoidPointer (f);
201 }
202 else
203 {
204 status = getResultForErrno();
205 close (f);
206 }
207 }
208 else
209 {
210 status = getResultForErrno();
211 }
212 }
213 else
214 {
215 const int f = open (file.getFullPathName().toUTF8(), O_RDWR + O_CREAT, 00644);
216
217 if (f != -1)
218 fileHandle = fdToVoidPointer (f);
219 else
220 status = getResultForErrno();
221 }
222}
223
225{
226 if (fileHandle != 0)
227 {
228 close (getFD (fileHandle));
229 fileHandle = 0;
230 }
231}
232
233ssize_t FileOutputStream::writeInternal (const void* const data, const size_t numBytes)
234{
235 ssize_t result = 0;
236
237 if (fileHandle != 0)
238 {
239 result = ::write (getFD (fileHandle), data, numBytes);
240
241 if (result == -1)
242 status = getResultForErrno();
243 }
244
245 return result;
246}
247
249{
250 if (fileHandle != 0)
251 {
252 if (fsync (getFD (fileHandle)) == -1)
253 status = getResultForErrno();
254 }
255}
256#endif
257
258}
#define nullptr
Definition DistrhoDefines.h:75
Definition File.h:50
size_t bufferSize
Definition FileOutputStream.h:109
void closeHandle()
Definition FileOutputStream.cpp:224
ssize_t writeInternal(const void *, size_t)
Definition FileOutputStream.cpp:233
File file
Definition FileOutputStream.h:105
void flushInternal()
Definition FileOutputStream.cpp:248
HeapBlock< char > buffer
Definition FileOutputStream.h:110
bool setPosition(int64) override
Definition FileOutputStream.cpp:58
bool flushBuffer()
Definition FileOutputStream.cpp:69
void * fileHandle
Definition FileOutputStream.h:106
Result status
Definition FileOutputStream.h:107
void openHandle()
Definition FileOutputStream.cpp:188
FileOutputStream(const File &fileToWriteTo, size_t bufferSizeToUse=16384)
Definition FileOutputStream.cpp:33
bool writeRepeatedByte(uint8 byte, size_t numTimesToRepeat) override
Definition FileOutputStream.cpp:124
int64 getPosition() override
Definition FileOutputStream.cpp:53
bool write(const void *, size_t) override
Definition FileOutputStream.cpp:88
~FileOutputStream()
Definition FileOutputStream.cpp:47
void flush() override
Definition FileOutputStream.cpp:82
int64 currentPosition
Definition FileOutputStream.h:108
size_t bytesInBuffer
Definition FileOutputStream.h:109
virtual bool writeRepeatedByte(uint8 byte, size_t numTimesToRepeat)
Definition OutputStream.cpp:56
Definition Result.h:64
static Result fail(const std::string &errorMessage) noexcept
Definition Result.cpp:58
unsigned f
Definition inflate.c:1572
JSAMPIMAGE data
Definition jpeglib.h:945
#define wassert(expression)
Definition AudioSampleBuffer.h:33
static int64 water_fileSetPosition(void *handle, int64 pos)
long long int64
Definition water.h:100
unsigned char uint8
Definition water.h:90
Type jmax(const Type a, const Type b)
Definition MathsFunctions.h:48
unsigned int DWORD
Definition swell-types.h:164
void * HANDLE
Definition swell-types.h:212
BOOL CloseHandle(HANDLE hand)
Definition swell.cpp:157
memcpy(hh, h, RAND_HEAD_LEN)
uch h[RAND_HEAD_LEN]
Definition crypt.c:459
int result
Definition process.c:1455
Z_OFF_T lseek()
#define SEEK_END
Definition unzpriv.h:1304
struct zdirent * file
Definition win32.c:1500