1 /**************************************************************************
3 * Copyright 2013-2014 RAD Game Tools and Valve Software
4 * Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 **************************************************************************/
27 // File: vogl_cfile_stream.h
30 #include "vogl_core.h"
31 #include "vogl_data_stream.h"
35 class cfile_stream : public data_stream
39 : data_stream(), m_pFile(NULL), m_size(0), m_ofs(0), m_has_ownership(false)
43 cfile_stream(FILE *pFile, const char *pFilename, uint attribs, bool has_ownership)
44 : data_stream(), m_pFile(NULL), m_size(0), m_ofs(0), m_has_ownership(false)
46 open(pFile, pFilename, attribs, has_ownership);
49 cfile_stream(const char *pFilename, uint attribs = cDataStreamReadable | cDataStreamSeekable, bool open_existing = false)
50 : data_stream(), m_pFile(NULL), m_size(0), m_ofs(0), m_has_ownership(false)
52 open(pFilename, attribs, open_existing);
55 virtual ~cfile_stream()
69 if (EOF == vogl_fclose(m_pFile))
77 m_has_ownership = false;
85 bool open(FILE *pFile, const char *pFilename, uint attribs, bool has_ownership)
88 VOGL_ASSERT(pFilename);
94 m_has_ownership = has_ownership;
95 m_attribs = static_cast<uint16>(attribs);
97 m_ofs = vogl_ftell(m_pFile);
98 vogl_fseek(m_pFile, 0, SEEK_END);
99 m_size = vogl_ftell(m_pFile);
100 vogl_fseek(m_pFile, m_ofs, SEEK_SET);
107 bool open(const char *pFilename, uint attribs = cDataStreamReadable | cDataStreamSeekable, bool open_existing = false)
109 VOGL_ASSERT(pFilename);
113 m_attribs = static_cast<uint16>(attribs);
116 if ((is_readable()) && (is_writable()))
117 pMode = open_existing ? "r+b" : "w+b";
118 else if (is_writable())
119 pMode = open_existing ? "ab" : "wb";
120 else if (is_readable())
128 FILE *pFile = vogl_fopen(pFilename, pMode);
129 m_has_ownership = true;
137 // TODO: Change stream class to support UCS2 filenames.
139 return open(pFile, pFilename, attribs, true);
142 FILE *get_file() const
147 virtual uint read(void *pBuf, uint len)
149 VOGL_ASSERT(len <= 0x7FFFFFFF);
151 if (!m_opened || (!is_readable()) || (!len))
154 len = static_cast<uint>(math::minimum<uint64_t>(len, get_remaining()));
156 if (vogl_fread(pBuf, 1, len, m_pFile) != len)
166 virtual uint write(const void *pBuf, uint len)
168 VOGL_ASSERT(len <= 0x7FFFFFFF);
170 if (!m_opened || (!is_writable()) || (!len))
173 if (vogl_fwrite(pBuf, 1, len, m_pFile) != len)
180 m_size = math::maximum(m_size, m_ofs);
187 if ((!m_opened) || (!is_writable()))
190 if (EOF == vogl_fflush(m_pFile))
199 virtual uint64_t get_size() const
207 virtual uint64_t get_remaining() const
212 VOGL_ASSERT(m_ofs <= m_size);
213 return m_size - m_ofs;
216 virtual uint64_t get_ofs() const
224 virtual bool seek(int64_t ofs, bool relative)
226 if ((!m_opened) || (!is_seekable()))
229 int64_t new_ofs = relative ? (m_ofs + ofs) : ofs;
232 else if (static_cast<uint64_t>(new_ofs) > m_size)
235 if (static_cast<uint64_t>(new_ofs) != m_ofs)
237 if (vogl_fseek(m_pFile, new_ofs, SEEK_SET) != 0)
249 static bool read_file_into_array(const char *pFilename, vector<uint8> &buf)
251 cfile_stream in_stream(pFilename);
252 if (!in_stream.is_opened())
254 return in_stream.read_array(buf);
257 static bool write_array_to_file(const char *pFilename, const vector<uint8> &buf)
259 cfile_stream out_stream(pFilename, cDataStreamWritable | cDataStreamSeekable);
260 if (!out_stream.is_opened())
262 return out_stream.write_array(buf);
267 uint64_t m_size, m_ofs;
268 bool m_has_ownership;