]> de.git.xonotic.org Git - xonotic/netradiant.git/blobdiff - radiant/file.cpp
error check and bail if permission denied during gamepack install
[xonotic/netradiant.git] / radiant / file.cpp
index 0f3c8555ef3fc81ab1a249465812a0b12965ee56..4e655c0f4d939b2199a63b6a862dfc821d65c334 100644 (file)
-/*\r
-Copyright (c) 2001, Loki software, inc.\r
-All rights reserved.\r
-\r
-Redistribution and use in source and binary forms, with or without modification, \r
-are permitted provided that the following conditions are met:\r
-\r
-Redistributions of source code must retain the above copyright notice, this list \r
-of conditions and the following disclaimer.\r
-\r
-Redistributions in binary form must reproduce the above copyright notice, this\r
-list of conditions and the following disclaimer in the documentation and/or\r
-other materials provided with the distribution.\r
-\r
-Neither the name of Loki software nor the names of its contributors may be used \r
-to endorse or promote products derived from this software without specific prior \r
-written permission. \r
-\r
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' \r
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE \r
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE \r
-DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY \r
-DIRECT,INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES \r
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; \r
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON \r
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS \r
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \r
-*/\r
-\r
-//\r
-// File class, can be a memory file or a regular disk file.\r
-// Originally from LeoCAD, used with permission from the author. :)\r
-//\r
-// Leonardo Zide (leo@lokigames.com)\r
-//\r
-\r
-#include "stdafx.h"\r
-\r
-#include <stdio.h>\r
-#include <memory.h>\r
-#include <stdlib.h>\r
-#include <string.h>\r
-\r
-\r
-IDataStream::IDataStream()\r
-{ }\r
-  \r
-IDataStream::~IDataStream()\r
-{ }\r
-\r
-/////////////////////////////////////////////////////////////////////////////\r
-// File construction/destruction\r
-\r
-MemStream::MemStream()\r
-{\r
-  m_nGrowBytes = 1024;\r
-  m_nPosition = 0;\r
-  m_nBufferSize = 0;\r
-  m_nFileSize = 0;\r
-  m_pBuffer = NULL;\r
-  m_bAutoDelete = true;\r
-}\r
-\r
-MemStream::MemStream(unsigned long nLen)\r
-{\r
-  m_nGrowBytes = 1024;\r
-  m_nPosition = 0;\r
-  m_nBufferSize = 0;\r
-  m_nFileSize = 0;\r
-  m_pBuffer = NULL;\r
-  m_bAutoDelete = true;\r
-\r
-  GrowFile (nLen);\r
-}\r
-\r
-FileStream::FileStream()\r
-{\r
-  m_hFile = NULL;\r
-  m_bCloseOnDelete = false;\r
-}\r
-\r
-MemStream::~MemStream()\r
-{\r
-  if (m_pBuffer)\r
-    Close();\r
-\r
-  m_nGrowBytes = 0;\r
-  m_nPosition = 0;\r
-  m_nBufferSize = 0;\r
-  m_nFileSize = 0;\r
-}\r
-\r
-FileStream::~FileStream()\r
-{\r
-  if (m_hFile != NULL && m_bCloseOnDelete)\r
-    Close();\r
-}\r
-\r
-/////////////////////////////////////////////////////////////////////////////\r
-// File operations\r
-\r
-char* MemStream::ReadString(char* pBuf, unsigned long nMax)\r
-{\r
-  int nRead = 0;\r
-  unsigned char ch;\r
-\r
-  if (nMax <= 0)\r
-    return NULL;\r
-  if (m_nPosition >= m_nFileSize)\r
-    return NULL;\r
-\r
-  while ((--nMax))\r
-  {\r
-    if (m_nPosition == m_nFileSize)\r
-      break;\r
-\r
-    ch = m_pBuffer[m_nPosition];\r
-    m_nPosition++;\r
-    pBuf[nRead++] = ch;\r
-\r
-    if (ch == '\n')\r
-      break;\r
-  }\r
-\r
-  pBuf[nRead] = '\0';\r
-  return pBuf;\r
-}\r
-\r
-char* FileStream::ReadString(char* pBuf, unsigned long nMax)\r
-{\r
-  return fgets(pBuf, nMax, m_hFile);\r
-}\r
-\r
-unsigned long MemStream::Read(void* pBuf, unsigned long nCount)\r
-{\r
-  if (nCount == 0)\r
-    return 0;\r
-\r
-  if (m_nPosition > m_nFileSize)\r
-    return 0;\r
-\r
-  unsigned long nRead;\r
-  if (m_nPosition + nCount > m_nFileSize)\r
-    nRead = (unsigned long)(m_nFileSize - m_nPosition);\r
-  else\r
-    nRead = nCount;\r
-\r
-  memcpy((unsigned char*)pBuf, (unsigned char*)m_pBuffer + m_nPosition, nRead);\r
-  m_nPosition += nRead;\r
-\r
-  return nRead;\r
-}\r
-\r
-unsigned long FileStream::Read(void* pBuf, unsigned long nCount)\r
-{\r
-  return fread(pBuf, 1, nCount, m_hFile);\r
-}\r
-\r
-int MemStream::GetChar()\r
-{\r
-  if (m_nPosition > m_nFileSize)\r
-    return 0;\r
-\r
-  unsigned char* ret = (unsigned char*)m_pBuffer + m_nPosition;\r
-  m_nPosition++;\r
-\r
-  return *ret;\r
-}\r
-\r
-int FileStream::GetChar()\r
-{\r
-  return fgetc(m_hFile);\r
-}\r
-\r
-unsigned long MemStream::Write(const void* pBuf, unsigned long nCount)\r
-{\r
-  if (nCount == 0)\r
-    return 0;\r
-\r
-  if (m_nPosition + nCount > m_nBufferSize)\r
-    GrowFile(m_nPosition + nCount);\r
-\r
-  memcpy((unsigned char*)m_pBuffer + m_nPosition, (unsigned char*)pBuf, nCount);\r
-\r
-  m_nPosition += nCount;\r
-\r
-  if (m_nPosition > m_nFileSize)\r
-    m_nFileSize = m_nPosition;\r
-\r
-  return nCount;\r
-}\r
-\r
-unsigned long FileStream::Write(const void* pBuf, unsigned long nCount)\r
-{\r
-  return fwrite(pBuf, 1, nCount, m_hFile);\r
-}\r
-\r
-int MemStream::PutChar(int c)\r
-{\r
-  if (m_nPosition + 1 > m_nBufferSize)\r
-    GrowFile(m_nPosition + 1);\r
-\r
-  unsigned char* bt = (unsigned char*)m_pBuffer + m_nPosition;\r
-  *bt = c;\r
-\r
-  m_nPosition++;\r
-\r
-  if (m_nPosition > m_nFileSize)\r
-    m_nFileSize = m_nPosition;\r
-\r
-  return 1;\r
-}\r
-\r
-/*!\todo SPoG suggestion: replace printf with operator >> using c++ iostream and strstream */\r
-void FileStream::printf(const char* s, ...)\r
-{\r
-  va_list args;\r
-\r
-  va_start (args, s);\r
-  vfprintf(m_hFile, s, args);\r
-  va_end (args);\r
-}\r
-\r
-/*!\todo SPoG suggestion: replace printf with operator >> using c++ iostream and strstream */\r
-void MemStream::printf(const char* s, ...)\r
-{\r
-  va_list args;\r
-\r
-  char buffer[4096];\r
-  va_start (args, s);\r
-  vsprintf(buffer, s, args);\r
-  va_end (args);\r
-  Write(buffer, strlen(buffer));\r
-}\r
-\r
-int FileStream::PutChar(int c)\r
-{\r
-  return fputc(c, m_hFile);\r
-}\r
-\r
-bool FileStream::Open(const char *filename, const char *mode)\r
-{\r
-  m_hFile = fopen(filename, mode);\r
-  m_bCloseOnDelete = true;\r
-\r
-  return (m_hFile != NULL);\r
-}\r
-\r
-void MemStream::Close()\r
-{\r
-  m_nGrowBytes = 0;\r
-  m_nPosition = 0;\r
-  m_nBufferSize = 0;\r
-  m_nFileSize = 0;\r
-  if (m_pBuffer && m_bAutoDelete)\r
-    free(m_pBuffer);\r
-  m_pBuffer = NULL;\r
-}\r
-\r
-void FileStream::Close()\r
-{\r
-  if (m_hFile != NULL)\r
-    fclose(m_hFile);\r
-\r
-  m_hFile = NULL;\r
-  m_bCloseOnDelete = false;\r
-}\r
-\r
-unsigned long MemStream::Seek(long lOff, int nFrom)\r
-{\r
-  unsigned long lNewPos = m_nPosition;\r
-\r
-  if (nFrom == SEEK_SET)\r
-    lNewPos = lOff;\r
-  else if (nFrom == SEEK_CUR)\r
-    lNewPos += lOff;\r
-  else if (nFrom == SEEK_END)\r
-    lNewPos = m_nFileSize + lOff;\r
-  else\r
-    return (unsigned long)-1;\r
-\r
-  m_nPosition = lNewPos;\r
-\r
-  return m_nPosition;\r
-}\r
-\r
-unsigned long FileStream::Seek(long lOff, int nFrom)\r
-{\r
-  fseek (m_hFile, lOff, nFrom);\r
-\r
-  return ftell(m_hFile);\r
-}\r
-\r
-unsigned long MemStream::GetPosition() const\r
-{\r
-    return m_nPosition;\r
-}\r
-\r
-unsigned long FileStream::GetPosition() const\r
-{\r
-  return ftell(m_hFile);\r
-}\r
-\r
-void MemStream::GrowFile(unsigned long nNewLen)\r
-{\r
-  if (nNewLen > m_nBufferSize)\r
-  {\r
-    // grow the buffer\r
-    unsigned long nNewBufferSize = m_nBufferSize;\r
-\r
-    // determine new buffer size\r
-    while (nNewBufferSize < nNewLen)\r
-      nNewBufferSize += m_nGrowBytes;\r
-\r
-    // allocate new buffer\r
-    unsigned char* lpNew;\r
-    if (m_pBuffer == NULL)\r
-      lpNew = static_cast<unsigned char*>(malloc(nNewBufferSize));\r
-    else\r
-      lpNew = static_cast<unsigned char*>(realloc(m_pBuffer, nNewBufferSize));\r
-\r
-    m_pBuffer = lpNew;\r
-    m_nBufferSize = nNewBufferSize;\r
-  }\r
-}\r
-\r
-void MemStream::Flush()\r
-{\r
-  // Nothing to be done\r
-}\r
-\r
-void FileStream::Flush()\r
-{\r
-  if (m_hFile == NULL)\r
-    return;\r
-\r
-  fflush(m_hFile);\r
-}\r
-\r
-void MemStream::Abort()\r
-{\r
-  Close();\r
-}\r
-\r
-void FileStream::Abort()\r
-{\r
-  if (m_hFile != NULL)\r
-  {\r
-    // close but ignore errors\r
-    if (m_bCloseOnDelete)\r
-      fclose(m_hFile);\r
-    m_hFile = NULL;\r
-    m_bCloseOnDelete = false;\r
-  }\r
-}\r
-\r
-void MemStream::SetLength(unsigned long nNewLen)\r
-{\r
-  if (nNewLen > m_nBufferSize)\r
-    GrowFile(nNewLen);\r
-\r
-  if (nNewLen < m_nPosition)\r
-    m_nPosition = nNewLen;\r
-\r
-  m_nFileSize = nNewLen;\r
-}\r
-\r
-void FileStream::SetLength(unsigned long nNewLen)\r
-{\r
-  fseek(m_hFile, nNewLen, SEEK_SET);\r
-}\r
-\r
-unsigned long MemStream::GetLength() const\r
-{\r
-  return m_nFileSize;\r
-}\r
-\r
-unsigned long FileStream::GetLength() const\r
-{\r
-  unsigned long nLen, nCur;\r
-\r
-  // Seek is a non const operation\r
-  nCur = ftell(m_hFile);\r
-  fseek(m_hFile, 0, SEEK_END);\r
-  nLen = ftell(m_hFile);\r
-  fseek(m_hFile, nCur, SEEK_SET);\r
-\r
-  return nLen;\r
-}\r
+/*
+   Copyright (c) 2001, Loki software, inc.
+   All rights reserved.
+
+   Redistribution and use in source and binary forms, with or without modification,
+   are permitted provided that the following conditions are met:
+
+   Redistributions of source code must retain the above copyright notice, this list
+   of conditions and the following disclaimer.
+
+   Redistributions in binary form must reproduce the above copyright notice, this
+   list of conditions and the following disclaimer in the documentation and/or
+   other materials provided with the distribution.
+
+   Neither the name of Loki software nor the names of its contributors may be used
+   to endorse or promote products derived from this software without specific prior
+   written permission.
+
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+   DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+   DIRECT,INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+   ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+//
+// File class, can be a memory file or a regular disk file.
+// Originally from LeoCAD, used with permission from the author. :)
+//
+// Leonardo Zide (leo@lokigames.com)
+//
+
+#include "stdafx.h"
+
+#include <stdio.h>
+#include <memory.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+IDataStream::IDataStream()
+{ }
+
+IDataStream::~IDataStream()
+{ }
+
+/////////////////////////////////////////////////////////////////////////////
+// File construction/destruction
+
+MemStream::MemStream(){
+       m_nGrowBytes = 1024;
+       m_nPosition = 0;
+       m_nBufferSize = 0;
+       m_nFileSize = 0;
+       m_pBuffer = NULL;
+       m_bAutoDelete = true;
+}
+
+MemStream::MemStream( unsigned long nLen ){
+       m_nGrowBytes = 1024;
+       m_nPosition = 0;
+       m_nBufferSize = 0;
+       m_nFileSize = 0;
+       m_pBuffer = NULL;
+       m_bAutoDelete = true;
+
+       GrowFile( nLen );
+}
+
+FileStream::FileStream(){
+       m_hFile = NULL;
+       m_bCloseOnDelete = false;
+}
+
+MemStream::~MemStream(){
+       if ( m_pBuffer ) {
+               Close();
+       }
+
+       m_nGrowBytes = 0;
+       m_nPosition = 0;
+       m_nBufferSize = 0;
+       m_nFileSize = 0;
+}
+
+FileStream::~FileStream(){
+       if ( m_hFile != NULL && m_bCloseOnDelete ) {
+               Close();
+       }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// File operations
+
+char* MemStream::ReadString( char* pBuf, unsigned long nMax ){
+       int nRead = 0;
+       unsigned char ch;
+
+       if ( nMax <= 0 ) {
+               return NULL;
+       }
+       if ( m_nPosition >= m_nFileSize ) {
+               return NULL;
+       }
+
+       while ( ( --nMax ) )
+       {
+               if ( m_nPosition == m_nFileSize ) {
+                       break;
+               }
+
+               ch = m_pBuffer[m_nPosition];
+               m_nPosition++;
+               pBuf[nRead++] = ch;
+
+               if ( ch == '\n' ) {
+                       break;
+               }
+       }
+
+       pBuf[nRead] = '\0';
+       return pBuf;
+}
+
+char* FileStream::ReadString( char* pBuf, unsigned long nMax ){
+       return fgets( pBuf, nMax, m_hFile );
+}
+
+unsigned long MemStream::Read( void* pBuf, unsigned long nCount ){
+       if ( nCount == 0 ) {
+               return 0;
+       }
+
+       if ( m_nPosition > m_nFileSize ) {
+               return 0;
+       }
+
+       unsigned long nRead;
+       if ( m_nPosition + nCount > m_nFileSize ) {
+               nRead = (unsigned long)( m_nFileSize - m_nPosition );
+       }
+       else{
+               nRead = nCount;
+       }
+
+       memcpy( (unsigned char*)pBuf, (unsigned char*)m_pBuffer + m_nPosition, nRead );
+       m_nPosition += nRead;
+
+       return nRead;
+}
+
+unsigned long FileStream::Read( void* pBuf, unsigned long nCount ){
+       return fread( pBuf, 1, nCount, m_hFile );
+}
+
+int MemStream::GetChar(){
+       if ( m_nPosition > m_nFileSize ) {
+               return 0;
+       }
+
+       unsigned char* ret = (unsigned char*)m_pBuffer + m_nPosition;
+       m_nPosition++;
+
+       return *ret;
+}
+
+int FileStream::GetChar(){
+       return fgetc( m_hFile );
+}
+
+unsigned long MemStream::Write( const void* pBuf, unsigned long nCount ){
+       if ( nCount == 0 ) {
+               return 0;
+       }
+
+       if ( m_nPosition + nCount > m_nBufferSize ) {
+               GrowFile( m_nPosition + nCount );
+       }
+
+       memcpy( (unsigned char*)m_pBuffer + m_nPosition, (unsigned char*)pBuf, nCount );
+
+       m_nPosition += nCount;
+
+       if ( m_nPosition > m_nFileSize ) {
+               m_nFileSize = m_nPosition;
+       }
+
+       return nCount;
+}
+
+unsigned long FileStream::Write( const void* pBuf, unsigned long nCount ){
+       return fwrite( pBuf, 1, nCount, m_hFile );
+}
+
+int MemStream::PutChar( int c ){
+       if ( m_nPosition + 1 > m_nBufferSize ) {
+               GrowFile( m_nPosition + 1 );
+       }
+
+       unsigned char* bt = (unsigned char*)m_pBuffer + m_nPosition;
+       *bt = c;
+
+       m_nPosition++;
+
+       if ( m_nPosition > m_nFileSize ) {
+               m_nFileSize = m_nPosition;
+       }
+
+       return 1;
+}
+
+/*!\todo SPoG suggestion: replace printf with operator >> using c++ iostream and strstream */
+void FileStream::printf( const char* s, ... ){
+       va_list args;
+
+       va_start( args, s );
+       vfprintf( m_hFile, s, args );
+       va_end( args );
+}
+
+/*!\todo SPoG suggestion: replace printf with operator >> using c++ iostream and strstream */
+void MemStream::printf( const char* s, ... ){
+       va_list args;
+
+       char buffer[4096];
+       va_start( args, s );
+       vsprintf( buffer, s, args );
+       va_end( args );
+       Write( buffer, strlen( buffer ) );
+}
+
+int FileStream::PutChar( int c ){
+       return fputc( c, m_hFile );
+}
+
+bool FileStream::Open( const char *filename, const char *mode ){
+       m_hFile = fopen( filename, mode );
+       m_bCloseOnDelete = true;
+
+       return m_hFile != NULL;
+}
+
+void MemStream::Close(){
+       m_nGrowBytes = 0;
+       m_nPosition = 0;
+       m_nBufferSize = 0;
+       m_nFileSize = 0;
+       if ( m_pBuffer && m_bAutoDelete ) {
+               free( m_pBuffer );
+       }
+       m_pBuffer = NULL;
+}
+
+void FileStream::Close(){
+       if ( m_hFile != NULL ) {
+               fclose( m_hFile );
+       }
+
+       m_hFile = NULL;
+       m_bCloseOnDelete = false;
+}
+
+unsigned long MemStream::Seek( long lOff, int nFrom ){
+       unsigned long lNewPos = m_nPosition;
+
+       if ( nFrom == SEEK_SET ) {
+               lNewPos = lOff;
+       }
+       else if ( nFrom == SEEK_CUR ) {
+               lNewPos += lOff;
+       }
+       else if ( nFrom == SEEK_END ) {
+               lNewPos = m_nFileSize + lOff;
+       }
+       else{
+               return (unsigned long)-1;
+       }
+
+       m_nPosition = lNewPos;
+
+       return m_nPosition;
+}
+
+unsigned long FileStream::Seek( long lOff, int nFrom ){
+       fseek( m_hFile, lOff, nFrom );
+
+       return ftell( m_hFile );
+}
+
+unsigned long MemStream::GetPosition() const {
+       return m_nPosition;
+}
+
+unsigned long FileStream::GetPosition() const {
+       return ftell( m_hFile );
+}
+
+void MemStream::GrowFile( unsigned long nNewLen ){
+       if ( nNewLen > m_nBufferSize ) {
+               // grow the buffer
+               unsigned long nNewBufferSize = m_nBufferSize;
+
+               // determine new buffer size
+               while ( nNewBufferSize < nNewLen )
+                       nNewBufferSize += m_nGrowBytes;
+
+               // allocate new buffer
+               unsigned char* lpNew;
+               if ( m_pBuffer == NULL ) {
+                       lpNew = static_cast<unsigned char*>( malloc( nNewBufferSize ) );
+               }
+               else{
+                       lpNew = static_cast<unsigned char*>( realloc( m_pBuffer, nNewBufferSize ) );
+               }
+
+               m_pBuffer = lpNew;
+               m_nBufferSize = nNewBufferSize;
+       }
+}
+
+void MemStream::Flush(){
+       // Nothing to be done
+}
+
+void FileStream::Flush(){
+       if ( m_hFile == NULL ) {
+               return;
+       }
+
+       fflush( m_hFile );
+}
+
+void MemStream::Abort(){
+       Close();
+}
+
+void FileStream::Abort(){
+       if ( m_hFile != NULL ) {
+               // close but ignore errors
+               if ( m_bCloseOnDelete ) {
+                       fclose( m_hFile );
+               }
+               m_hFile = NULL;
+               m_bCloseOnDelete = false;
+       }
+}
+
+void MemStream::SetLength( unsigned long nNewLen ){
+       if ( nNewLen > m_nBufferSize ) {
+               GrowFile( nNewLen );
+       }
+
+       if ( nNewLen < m_nPosition ) {
+               m_nPosition = nNewLen;
+       }
+
+       m_nFileSize = nNewLen;
+}
+
+void FileStream::SetLength( unsigned long nNewLen ){
+       fseek( m_hFile, nNewLen, SEEK_SET );
+}
+
+unsigned long MemStream::GetLength() const {
+       return m_nFileSize;
+}
+
+unsigned long FileStream::GetLength() const {
+       unsigned long nLen, nCur;
+
+       // Seek is a non const operation
+       nCur = ftell( m_hFile );
+       fseek( m_hFile, 0, SEEK_END );
+       nLen = ftell( m_hFile );
+       fseek( m_hFile, nCur, SEEK_SET );
+
+       return nLen;
+}