1 /* 2 * Copyright (C) 2020 Linux Studio Plugins Project <https://lsp-plug.in/> 3 * (C) 2020 Vladimir Sadovnikov <sadko4u@gmail.com> 4 * 5 * This file is part of lsp-plugins 6 * Created on: 13 мар. 2019 г. 7 * 8 * lsp-plugins is free software: you can redistribute it and/or modify 9 * it under the terms of the GNU Lesser General Public License as published by 10 * the Free Software Foundation, either version 3 of the License, or 11 * any later version. 12 * 13 * lsp-plugins is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public License 19 * along with lsp-plugins. If not, see <https://www.gnu.org/licenses/>. 20 */ 21 22 #include <core/io/StdioFile.h> 23 #include <core/io/NativeFile.h> 24 #include <core/io/OutFileStream.h> 25 26 namespace lsp 27 { 28 namespace io 29 { 30 OutFileStream()31 OutFileStream::OutFileStream() 32 { 33 pFD = NULL; 34 nWrapFlags = 0; 35 } 36 ~OutFileStream()37 OutFileStream::~OutFileStream() 38 { 39 // Close file descriptor 40 if (pFD != NULL) 41 { 42 if (nWrapFlags & WRAP_CLOSE) 43 pFD->close(); 44 if (nWrapFlags & WRAP_DELETE) 45 delete pFD; 46 pFD = NULL; 47 } 48 nWrapFlags = 0; 49 } 50 close()51 status_t OutFileStream::close() 52 { 53 status_t res = STATUS_OK; 54 55 if (pFD != NULL) 56 { 57 // Perform close 58 if (nWrapFlags & WRAP_CLOSE) 59 res = pFD->close(); 60 if (nWrapFlags & WRAP_DELETE) 61 delete pFD; 62 pFD = NULL; 63 } 64 nWrapFlags = 0; 65 66 return set_error(res); 67 } 68 wrap(FILE * fd,bool close)69 status_t OutFileStream::wrap(FILE *fd, bool close) 70 { 71 if (pFD != NULL) 72 return set_error(STATUS_BAD_STATE); 73 else if (fd == NULL) 74 return set_error(STATUS_BAD_ARGUMENTS); 75 76 StdioFile *f = new StdioFile(); 77 if (f == NULL) 78 return set_error(STATUS_NO_MEM); 79 status_t res = f->wrap(fd, File::FM_WRITE, close); 80 if (res != STATUS_OK) 81 { 82 f->close(); 83 delete f; 84 return set_error(res); 85 } 86 87 res = wrap(f, WRAP_DELETE); 88 if (res != STATUS_OK) 89 { 90 f->close(); 91 delete f; 92 } 93 return set_error(res); 94 } 95 wrap_native(lsp_fhandle_t fd,bool close)96 status_t OutFileStream::wrap_native(lsp_fhandle_t fd, bool close) 97 { 98 if (pFD != NULL) 99 return set_error(STATUS_BAD_STATE); 100 101 NativeFile *f = new NativeFile(); 102 if (f == NULL) 103 return set_error(STATUS_NO_MEM); 104 status_t res = f->wrap(fd, File::FM_WRITE, close); 105 if (res != STATUS_OK) 106 { 107 f->close(); 108 delete f; 109 return set_error(res); 110 } 111 112 res = wrap(f, WRAP_DELETE); 113 if (res != STATUS_OK) 114 { 115 f->close(); 116 delete f; 117 } 118 return set_error(res); 119 } 120 wrap(File * fd,size_t flags)121 status_t OutFileStream::wrap(File *fd, size_t flags) 122 { 123 if (pFD != NULL) 124 return set_error(STATUS_BAD_STATE); 125 else if (fd == NULL) 126 return set_error(STATUS_BAD_ARGUMENTS); 127 128 // Store pointers 129 pFD = fd; 130 nWrapFlags = flags; 131 132 return STATUS_OK; 133 } 134 open(const char * path,size_t mode)135 status_t OutFileStream::open(const char *path, size_t mode) 136 { 137 if (pFD != NULL) 138 return set_error(STATUS_BAD_STATE); 139 else if (path == NULL) 140 return set_error(STATUS_BAD_ARGUMENTS); 141 142 LSPString tmp; 143 if (!tmp.set_utf8(path)) 144 return set_error(STATUS_NO_MEM); 145 return open(&tmp, mode); 146 } 147 open(const LSPString * path,size_t mode)148 status_t OutFileStream::open(const LSPString *path, size_t mode) 149 { 150 if (pFD != NULL) 151 return set_error(STATUS_BAD_STATE); 152 else if (path == NULL) 153 return set_error(STATUS_BAD_ARGUMENTS); 154 155 NativeFile *f = new NativeFile(); 156 if (f == NULL) 157 return set_error(STATUS_NO_MEM); 158 159 status_t res = f->open(path, mode | File::FM_WRITE); 160 if (res != STATUS_OK) 161 { 162 f->close(); 163 delete f; 164 return set_error(res); 165 } 166 167 return wrap(f, WRAP_CLOSE | WRAP_DELETE); 168 } 169 open(const Path * path,size_t mode)170 status_t OutFileStream::open(const Path *path, size_t mode) 171 { 172 return open(path->as_string(), mode); 173 } 174 position()175 wssize_t OutFileStream::position() 176 { 177 if (pFD == NULL) 178 return set_error(STATUS_CLOSED); 179 wssize_t pos = pFD->position(); 180 set_error((pos < 0) ? status_t(-pos) : STATUS_OK); 181 return pos; 182 } 183 write(const void * buf,size_t count)184 ssize_t OutFileStream::write(const void *buf, size_t count) 185 { 186 if (pFD == NULL) 187 return set_error(STATUS_CLOSED); 188 ssize_t res = pFD->write(buf, count); 189 set_error((res < 0) ? status_t(-res) : STATUS_OK); 190 return res; 191 } 192 seek(wsize_t position)193 wssize_t OutFileStream::seek(wsize_t position) 194 { 195 if (pFD == NULL) 196 return set_error(STATUS_CLOSED); 197 status_t res = pFD->seek(position, File::FSK_SET); 198 if (res != STATUS_OK) 199 return -set_error(res); 200 wssize_t pos = pFD->position(); 201 set_error((pos < 0) ? status_t(-pos) : STATUS_OK); 202 return pos; 203 } 204 flush()205 status_t OutFileStream::flush() 206 { 207 if (pFD == NULL) 208 return set_error(STATUS_CLOSED); 209 return set_error(pFD->flush()); 210 } 211 212 } /* namespace io */ 213 } /* namespace lsp */ 214