2 Copyright (c) 2001, Loki software, inc.
\r
5 Redistribution and use in source and binary forms, with or without modification,
\r
6 are permitted provided that the following conditions are met:
\r
8 Redistributions of source code must retain the above copyright notice, this list
\r
9 of conditions and the following disclaimer.
\r
11 Redistributions in binary form must reproduce the above copyright notice, this
\r
12 list of conditions and the following disclaimer in the documentation and/or
\r
13 other materials provided with the distribution.
\r
15 Neither the name of Loki software nor the names of its contributors may be used
\r
16 to endorse or promote products derived from this software without specific prior
\r
17 written permission.
\r
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
\r
20 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
\r
21 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
\r
22 DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
\r
23 DIRECT,INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
\r
24 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
\r
25 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
\r
26 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
\r
27 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
\r
28 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\r
32 // File class, can be a memory file or a regular disk file.
\r
33 // Originally from LeoCAD, used with permission from the author. :)
\r
35 // Leonardo Zide (leo@lokigames.com)
\r
46 IDataStream::IDataStream()
\r
49 IDataStream::~IDataStream()
\r
52 /////////////////////////////////////////////////////////////////////////////
\r
53 // File construction/destruction
\r
55 MemStream::MemStream()
\r
57 m_nGrowBytes = 1024;
\r
62 m_bAutoDelete = true;
\r
65 MemStream::MemStream(unsigned long nLen)
\r
67 m_nGrowBytes = 1024;
\r
72 m_bAutoDelete = true;
\r
77 FileStream::FileStream()
\r
80 m_bCloseOnDelete = false;
\r
83 MemStream::~MemStream()
\r
94 FileStream::~FileStream()
\r
96 if (m_hFile != NULL && m_bCloseOnDelete)
\r
100 /////////////////////////////////////////////////////////////////////////////
\r
103 char* MemStream::ReadString(char* pBuf, unsigned long nMax)
\r
110 if (m_nPosition >= m_nFileSize)
\r
115 if (m_nPosition == m_nFileSize)
\r
118 ch = m_pBuffer[m_nPosition];
\r
120 pBuf[nRead++] = ch;
\r
126 pBuf[nRead] = '\0';
\r
130 char* FileStream::ReadString(char* pBuf, unsigned long nMax)
\r
132 return fgets(pBuf, nMax, m_hFile);
\r
135 unsigned long MemStream::Read(void* pBuf, unsigned long nCount)
\r
140 if (m_nPosition > m_nFileSize)
\r
143 unsigned long nRead;
\r
144 if (m_nPosition + nCount > m_nFileSize)
\r
145 nRead = (unsigned long)(m_nFileSize - m_nPosition);
\r
149 memcpy((unsigned char*)pBuf, (unsigned char*)m_pBuffer + m_nPosition, nRead);
\r
150 m_nPosition += nRead;
\r
155 unsigned long FileStream::Read(void* pBuf, unsigned long nCount)
\r
157 return fread(pBuf, 1, nCount, m_hFile);
\r
160 int MemStream::GetChar()
\r
162 if (m_nPosition > m_nFileSize)
\r
165 unsigned char* ret = (unsigned char*)m_pBuffer + m_nPosition;
\r
171 int FileStream::GetChar()
\r
173 return fgetc(m_hFile);
\r
176 unsigned long MemStream::Write(const void* pBuf, unsigned long nCount)
\r
181 if (m_nPosition + nCount > m_nBufferSize)
\r
182 GrowFile(m_nPosition + nCount);
\r
184 memcpy((unsigned char*)m_pBuffer + m_nPosition, (unsigned char*)pBuf, nCount);
\r
186 m_nPosition += nCount;
\r
188 if (m_nPosition > m_nFileSize)
\r
189 m_nFileSize = m_nPosition;
\r
194 unsigned long FileStream::Write(const void* pBuf, unsigned long nCount)
\r
196 return fwrite(pBuf, 1, nCount, m_hFile);
\r
199 int MemStream::PutChar(int c)
\r
201 if (m_nPosition + 1 > m_nBufferSize)
\r
202 GrowFile(m_nPosition + 1);
\r
204 unsigned char* bt = (unsigned char*)m_pBuffer + m_nPosition;
\r
209 if (m_nPosition > m_nFileSize)
\r
210 m_nFileSize = m_nPosition;
\r
215 /*!\todo SPoG suggestion: replace printf with operator >> using c++ iostream and strstream */
\r
216 void FileStream::printf(const char* s, ...)
\r
220 va_start (args, s);
\r
221 vfprintf(m_hFile, s, args);
\r
225 /*!\todo SPoG suggestion: replace printf with operator >> using c++ iostream and strstream */
\r
226 void MemStream::printf(const char* s, ...)
\r
231 va_start (args, s);
\r
232 vsprintf(buffer, s, args);
\r
234 Write(buffer, strlen(buffer));
\r
237 int FileStream::PutChar(int c)
\r
239 return fputc(c, m_hFile);
\r
242 bool FileStream::Open(const char *filename, const char *mode)
\r
244 m_hFile = fopen(filename, mode);
\r
245 m_bCloseOnDelete = true;
\r
247 return (m_hFile != NULL);
\r
250 void MemStream::Close()
\r
256 if (m_pBuffer && m_bAutoDelete)
\r
261 void FileStream::Close()
\r
263 if (m_hFile != NULL)
\r
267 m_bCloseOnDelete = false;
\r
270 unsigned long MemStream::Seek(long lOff, int nFrom)
\r
272 unsigned long lNewPos = m_nPosition;
\r
274 if (nFrom == SEEK_SET)
\r
276 else if (nFrom == SEEK_CUR)
\r
278 else if (nFrom == SEEK_END)
\r
279 lNewPos = m_nFileSize + lOff;
\r
281 return (unsigned long)-1;
\r
283 m_nPosition = lNewPos;
\r
285 return m_nPosition;
\r
288 unsigned long FileStream::Seek(long lOff, int nFrom)
\r
290 fseek (m_hFile, lOff, nFrom);
\r
292 return ftell(m_hFile);
\r
295 unsigned long MemStream::GetPosition() const
\r
297 return m_nPosition;
\r
300 unsigned long FileStream::GetPosition() const
\r
302 return ftell(m_hFile);
\r
305 void MemStream::GrowFile(unsigned long nNewLen)
\r
307 if (nNewLen > m_nBufferSize)
\r
310 unsigned long nNewBufferSize = m_nBufferSize;
\r
312 // determine new buffer size
\r
313 while (nNewBufferSize < nNewLen)
\r
314 nNewBufferSize += m_nGrowBytes;
\r
316 // allocate new buffer
\r
317 unsigned char* lpNew;
\r
318 if (m_pBuffer == NULL)
\r
319 lpNew = static_cast<unsigned char*>(malloc(nNewBufferSize));
\r
321 lpNew = static_cast<unsigned char*>(realloc(m_pBuffer, nNewBufferSize));
\r
324 m_nBufferSize = nNewBufferSize;
\r
328 void MemStream::Flush()
\r
330 // Nothing to be done
\r
333 void FileStream::Flush()
\r
335 if (m_hFile == NULL)
\r
341 void MemStream::Abort()
\r
346 void FileStream::Abort()
\r
348 if (m_hFile != NULL)
\r
350 // close but ignore errors
\r
351 if (m_bCloseOnDelete)
\r
354 m_bCloseOnDelete = false;
\r
358 void MemStream::SetLength(unsigned long nNewLen)
\r
360 if (nNewLen > m_nBufferSize)
\r
363 if (nNewLen < m_nPosition)
\r
364 m_nPosition = nNewLen;
\r
366 m_nFileSize = nNewLen;
\r
369 void FileStream::SetLength(unsigned long nNewLen)
\r
371 fseek(m_hFile, nNewLen, SEEK_SET);
\r
374 unsigned long MemStream::GetLength() const
\r
376 return m_nFileSize;
\r
379 unsigned long FileStream::GetLength() const
\r
381 unsigned long nLen, nCur;
\r
383 // Seek is a non const operation
\r
384 nCur = ftell(m_hFile);
\r
385 fseek(m_hFile, 0, SEEK_END);
\r
386 nLen = ftell(m_hFile);
\r
387 fseek(m_hFile, nCur, SEEK_SET);
\r