/[svn]/libgig/trunk/src/RIFF.cpp
ViewVC logotype

Diff of /libgig/trunk/src/RIFF.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 780 by schoenebeck, Sun Sep 25 13:40:37 2005 UTC revision 802 by schoenebeck, Thu Nov 10 19:53:34 2005 UTC
# Line 22  Line 22 
22   ***************************************************************************/   ***************************************************************************/
23    
24  #include <string.h>  #include <string.h>
 #include <sstream>  
25    
26  #include "RIFF.h"  #include "RIFF.h"
27    
28  namespace RIFF {  #include "helper.h"
   
 // *************** Helper Functions **************  
 // *  
   
     template<class T> inline String ToString(T o) {  
         std::stringstream ss;  
         ss << o;  
         return ss.str();  
     }  
   
29    
30    namespace RIFF {
31    
32  // *************** Chunk **************  // *************** Chunk **************
33  // *  // *
# Line 49  namespace RIFF { Line 39  namespace RIFF {
39          ulPos      = 0;          ulPos      = 0;
40          pParent    = NULL;          pParent    = NULL;
41          pChunkData = NULL;          pChunkData = NULL;
42            ulChunkDataSize = 0;
43            ChunkID    = CHUNK_ID_RIFF;
44          this->pFile = pFile;          this->pFile = pFile;
45      }      }
46    
# Line 61  namespace RIFF { Line 53  namespace RIFF {
53          pParent       = Parent;          pParent       = Parent;
54          ulPos         = 0;          ulPos         = 0;
55          pChunkData    = NULL;          pChunkData    = NULL;
56            ulChunkDataSize = 0;
57          ReadHeader(StartPos);          ReadHeader(StartPos);
58      }      }
59    
# Line 70  namespace RIFF { Line 63  namespace RIFF {
63          this->pParent    = pParent;          this->pParent    = pParent;
64          ulPos            = 0;          ulPos            = 0;
65          pChunkData       = NULL;          pChunkData       = NULL;
66            ulChunkDataSize  = 0;
67          ChunkID          = uiChunkID;          ChunkID          = uiChunkID;
68          CurrentChunkSize = 0;          CurrentChunkSize = 0;
69          NewChunkSize     = uiBodySize;          NewChunkSize     = uiBodySize;
# Line 293  namespace RIFF { Line 287  namespace RIFF {
287       *  @see Resize()       *  @see Resize()
288       */       */
289      unsigned long Chunk::Write(void* pData, unsigned long WordCount, unsigned long WordSize) {      unsigned long Chunk::Write(void* pData, unsigned long WordCount, unsigned long WordSize) {
290          if (pFile->Mode == stream_mode_read)          if (pFile->Mode != stream_mode_read_write)
291              throw Exception("Writing chunk data in read-only file access mode was attempted");              throw Exception("Cannot write data to chunk, file has to be opened in read+write mode first");
292          if (ulPos >= CurrentChunkSize || ulPos + WordCount * WordSize >= CurrentChunkSize)          if (ulPos >= CurrentChunkSize || ulPos + WordCount * WordSize > CurrentChunkSize)
293              throw Exception("End of chunk reached while trying to write data");              throw Exception("End of chunk reached while trying to write data");
294          if (!pFile->bEndianNative && WordSize != 1) {          if (!pFile->bEndianNative && WordSize != 1) {
295              switch (WordSize) {              switch (WordSize) {
# Line 667  namespace RIFF { Line 661  namespace RIFF {
661       *       *
662       * <b>Caution:</b> the buffer pointer will be invalidated once       * <b>Caution:</b> the buffer pointer will be invalidated once
663       * File::Save() was called. You have to call LoadChunkData() again to       * File::Save() was called. You have to call LoadChunkData() again to
664       * get a new pointer whenever File::Save() was called.       * get a new, valid pointer whenever File::Save() was called.
665         *
666         * You can call LoadChunkData() again if you previously scheduled to
667         * enlarge this chunk with a Resize() call. In that case the buffer will
668         * be enlarged to the new, scheduled chunk size and you can already
669         * place the new chunk data to the buffer and finally call File::Save()
670         * to enlarge the chunk physically and write the new data in one rush.
671         * This approach is definitely recommended if you have to enlarge and
672         * write new data to a lot of chunks.
673       *       *
674       * @returns a pointer to the data in RAM on success, NULL otherwise       * @returns a pointer to the data in RAM on success, NULL otherwise
675         * @throws Exception if data buffer could not be enlarged
676       * @see ReleaseChunkData()       * @see ReleaseChunkData()
677       */       */
678      void* Chunk::LoadChunkData() {      void* Chunk::LoadChunkData() {
679          if (!pChunkData) {          if (!pChunkData && pFile->Filename != "") {
680              #if POSIX              #if POSIX
681              if (lseek(pFile->hFileRead, ulStartPos, SEEK_SET) == -1) return NULL;              if (lseek(pFile->hFileRead, ulStartPos, SEEK_SET) == -1) return NULL;
             pChunkData = new uint8_t[GetSize()];  
             if (!pChunkData) return NULL;  
             unsigned long readWords = read(pFile->hFileRead, pChunkData, GetSize());  
682              #else              #else
683              if (fseek(pFile->hFileRead, ulStartPos, SEEK_SET)) return NULL;              if (fseek(pFile->hFileRead, ulStartPos, SEEK_SET)) return NULL;
684              pChunkData = new uint8_t[GetSize()];              #endif // POSIX
685                unsigned long ulBufferSize = (CurrentChunkSize > NewChunkSize) ? CurrentChunkSize : NewChunkSize;
686                pChunkData = new uint8_t[ulBufferSize];
687              if (!pChunkData) return NULL;              if (!pChunkData) return NULL;
688                memset(pChunkData, 0, ulBufferSize);
689                #if POSIX
690                unsigned long readWords = read(pFile->hFileRead, pChunkData, GetSize());
691                #else
692              unsigned long readWords = fread(pChunkData, 1, GetSize(), pFile->hFileRead);              unsigned long readWords = fread(pChunkData, 1, GetSize(), pFile->hFileRead);
693              #endif // POSIX              #endif // POSIX
694              if (readWords != GetSize()) {              if (readWords != GetSize()) {
695                  delete[] pChunkData;                  delete[] pChunkData;
696                  return (pChunkData = NULL);                  return (pChunkData = NULL);
697              }              }
698                ulChunkDataSize = ulBufferSize;
699            } else if (NewChunkSize > ulChunkDataSize) {
700                uint8_t* pNewBuffer = new uint8_t[NewChunkSize];
701                if (!pNewBuffer) throw Exception("Could not enlarge chunk data buffer to " + ToString(NewChunkSize) + " bytes");
702                memset(pNewBuffer, 0 , NewChunkSize);
703                memcpy(pNewBuffer, pChunkData, ulChunkDataSize);
704                delete[] pChunkData;
705                pChunkData      = pNewBuffer;
706                ulChunkDataSize = NewChunkSize;
707          }          }
708          return pChunkData;          return pChunkData;
709      }      }
# Line 718  namespace RIFF { Line 733  namespace RIFF {
733       *       *
734       * <b>Caution:</b> You cannot directly write to enlarged chunks before       * <b>Caution:</b> You cannot directly write to enlarged chunks before
735       * calling File::Save() as this might exceed the current chunk's body       * calling File::Save() as this might exceed the current chunk's body
736       * boundary.       * boundary!
737       *       *
738       * @param iNewSize - new chunk body size in bytes (must be greater than zero)       * @param iNewSize - new chunk body size in bytes (must be greater than zero)
739       * @throws RIFF::Exception  if \a iNewSize is less than 1       * @throws RIFF::Exception  if \a iNewSize is less than 1
# Line 726  namespace RIFF { Line 741  namespace RIFF {
741       */       */
742      void Chunk::Resize(int iNewSize) {      void Chunk::Resize(int iNewSize) {
743          if (iNewSize <= 0) throw Exception("Chunk size must be at least one byte");          if (iNewSize <= 0) throw Exception("Chunk size must be at least one byte");
744            if (NewChunkSize == iNewSize) return;
745          NewChunkSize = iNewSize;          NewChunkSize = iNewSize;
746          pFile->LogAsResized(this);          pFile->LogAsResized(this);
747      }      }
# Line 743  namespace RIFF { Line 759  namespace RIFF {
759       *          (including its header size of course)       *          (including its header size of course)
760       */       */
761      unsigned long Chunk::WriteChunk(unsigned long ulWritePos, unsigned long ulCurrentDataOffset) {      unsigned long Chunk::WriteChunk(unsigned long ulWritePos, unsigned long ulCurrentDataOffset) {
762          unsigned long ulOriginalPos = ulWritePos;          const unsigned long ulOriginalPos = ulWritePos;
763          ulWritePos += CHUNK_HEADER_SIZE;          ulWritePos += CHUNK_HEADER_SIZE;
764    
765            if (pFile->Mode != stream_mode_read_write)
766                throw Exception("Cannot write list chunk, file has to be opened in read+write mode");
767    
768          // if the whole chunk body was loaded into RAM          // if the whole chunk body was loaded into RAM
769          if (pChunkData) {          if (pChunkData) {
770              // in case the chunk size was changed, reallocate the data in RAM with the chunk's new size              // make sure chunk data buffer in RAM is at least as large as the new chunk size
771              if (NewChunkSize != CurrentChunkSize) {              LoadChunkData();
                 uint8_t* pNewBuffer = new uint8_t[NewChunkSize];  
                 if (NewChunkSize > CurrentChunkSize) {  
                     memcpy(pNewBuffer, pChunkData, CurrentChunkSize);  
                     memset(pNewBuffer + CurrentChunkSize, 0, NewChunkSize - CurrentChunkSize);  
                 } else {  
                     memcpy(pNewBuffer, pChunkData, NewChunkSize);  
                 }  
                 delete[] pChunkData;  
                 pChunkData = pNewBuffer;  
             }  
   
772              // write chunk data from RAM persistently to the file              // write chunk data from RAM persistently to the file
773              #if POSIX              #if POSIX
774              lseek(pFile->hFileWrite, ulWritePos, SEEK_SET);              lseek(pFile->hFileWrite, ulWritePos, SEEK_SET);
# Line 806  namespace RIFF { Line 814  namespace RIFF {
814    
815          // add pad byte if needed          // add pad byte if needed
816          if ((ulStartPos + NewChunkSize) % 2 != 0) {          if ((ulStartPos + NewChunkSize) % 2 != 0) {
817              char cPadByte = 0;              const char cPadByte = 0;
818              #if POSIX              #if POSIX
819                lseek(pFile->hFileWrite, ulStartPos + NewChunkSize, SEEK_SET);
820              write(pFile->hFileWrite, &cPadByte, 1);              write(pFile->hFileWrite, &cPadByte, 1);
821              #else              #else
822                fseek(pFile->hFileWrite, ulStartPos + NewChunkSize, SEEK_SET);
823              fwrite(&cPadByte, 1, 1, pFile->hFileWrite);              fwrite(&cPadByte, 1, 1, pFile->hFileWrite);
824              #endif              #endif
825              return ulStartPos + NewChunkSize + 1;              return ulStartPos + NewChunkSize + 1;
# Line 1063  namespace RIFF { Line 1073  namespace RIFF {
1073      Chunk* List::AddSubChunk(uint32_t uiChunkID, uint uiBodySize) {      Chunk* List::AddSubChunk(uint32_t uiChunkID, uint uiBodySize) {
1074          if (uiBodySize == 0) throw Exception("Chunk body size must be at least 1 byte");          if (uiBodySize == 0) throw Exception("Chunk body size must be at least 1 byte");
1075          if (!pSubChunks) LoadSubChunks();          if (!pSubChunks) LoadSubChunks();
1076          Chunk* pNewChunk = new Chunk(pFile, this, uiChunkID, uiBodySize);          Chunk* pNewChunk = new Chunk(pFile, this, uiChunkID, 0);
1077          pSubChunks->push_back(pNewChunk);          pSubChunks->push_back(pNewChunk);
1078          (*pSubChunksMap)[uiChunkID] = pNewChunk;          (*pSubChunksMap)[uiChunkID] = pNewChunk;
1079          pFile->ResizedChunks.push_back(pNewChunk);          pNewChunk->Resize(uiBodySize);
1080          return pNewChunk;          return pNewChunk;
1081      }      }
1082    
# Line 1197  namespace RIFF { Line 1207  namespace RIFF {
1207       *          (including its header size of course)       *          (including its header size of course)
1208       */       */
1209      unsigned long List::WriteChunk(unsigned long ulWritePos, unsigned long ulCurrentDataOffset) {      unsigned long List::WriteChunk(unsigned long ulWritePos, unsigned long ulCurrentDataOffset) {
1210          unsigned long ulOriginalPos = ulWritePos;          const unsigned long ulOriginalPos = ulWritePos;
1211          ulWritePos += LIST_HEADER_SIZE;          ulWritePos += LIST_HEADER_SIZE;
1212    
1213            if (pFile->Mode != stream_mode_read_write)
1214                throw Exception("Cannot write list chunk, file has to be opened in read+write mode");
1215    
1216          // write all subchunks (including sub list chunks) recursively          // write all subchunks (including sub list chunks) recursively
1217          if (pSubChunks) {          if (pSubChunks) {
1218              for (ChunkList::iterator iter = pSubChunks->begin(), end = pSubChunks->end(); iter != end; ++iter) {              for (ChunkList::iterator iter = pSubChunks->begin(), end = pSubChunks->end(); iter != end; ++iter) {
# Line 1211  namespace RIFF { Line 1224  namespace RIFF {
1224          CurrentChunkSize = NewChunkSize = ulWritePos - ulOriginalPos - LIST_HEADER_SIZE;          CurrentChunkSize = NewChunkSize = ulWritePos - ulOriginalPos - LIST_HEADER_SIZE;
1225          WriteHeader(ulOriginalPos);          WriteHeader(ulOriginalPos);
1226    
1227            // offset of this list chunk in new written file may have changed
1228            ulStartPos = ulOriginalPos + LIST_HEADER_SIZE;
1229    
1230          return ulWritePos;          return ulWritePos;
1231      }      }
1232    
# Line 1241  namespace RIFF { Line 1257  namespace RIFF {
1257       * "from scratch". Note: there must be no empty chunks or empty list       * "from scratch". Note: there must be no empty chunks or empty list
1258       * chunks when trying to make the new RIFF file persistent with Save()!       * chunks when trying to make the new RIFF file persistent with Save()!
1259       *       *
1260         * @param FileType - four-byte identifier of the RIFF file type
1261       * @see AddSubChunk(), AddSubList()       * @see AddSubChunk(), AddSubList()
1262       */       */
1263      File::File() : List(this) {      File::File(uint32_t FileType) : List(this) {
1264          hFileRead = hFileWrite = 0;          hFileRead = hFileWrite = 0;
1265            Mode = stream_mode_closed;
1266          bEndianNative = true;          bEndianNative = true;
1267          ulStartPos = RIFF_HEADER_SIZE;          ulStartPos = RIFF_HEADER_SIZE;
1268            ListType = FileType;
1269      }      }
1270    
1271      /** @brief Load existing RIFF file.      /** @brief Load existing RIFF file.
# Line 1272  namespace RIFF { Line 1291  namespace RIFF {
1291          hFileRead = hFileWrite = fopen(path.c_str(), "rb");          hFileRead = hFileWrite = fopen(path.c_str(), "rb");
1292          if (!hFile) throw RIFF::Exception("Can't open \"" + path + "\"");          if (!hFile) throw RIFF::Exception("Can't open \"" + path + "\"");
1293          #endif // POSIX          #endif // POSIX
1294            Mode = stream_mode_read;
1295          ulStartPos = RIFF_HEADER_SIZE;          ulStartPos = RIFF_HEADER_SIZE;
1296          ReadHeader(0);          ReadHeader(0);
1297          if (ChunkID != CHUNK_ID_RIFF) {          if (ChunkID != CHUNK_ID_RIFF) {
# Line 1314  namespace RIFF { Line 1334  namespace RIFF {
1334                      if (!hFileRead) throw Exception("Could not (re)open file \"" + Filename + "\" in read mode");                      if (!hFileRead) throw Exception("Could not (re)open file \"" + Filename + "\" in read mode");
1335                      #endif                      #endif
1336                      __resetPos(); // reset read/write position of ALL 'Chunk' objects                      __resetPos(); // reset read/write position of ALL 'Chunk' objects
1337                      return true;                      break;
1338                  case stream_mode_read_write:                  case stream_mode_read_write:
1339                      #if POSIX                      #if POSIX
1340                      if (hFileRead) close(hFileRead);                      if (hFileRead) close(hFileRead);
# Line 1332  namespace RIFF { Line 1352  namespace RIFF {
1352                      }                      }
1353                      #endif                      #endif
1354                      __resetPos(); // reset read/write position of ALL 'Chunk' objects                      __resetPos(); // reset read/write position of ALL 'Chunk' objects
1355                      return true;                      break;
1356                    case stream_mode_closed:
1357                        #if POSIX
1358                        if (hFileRead)  close(hFileRead);
1359                        if (hFileWrite) close(hFileWrite);
1360                        #else
1361                        if (hFileRead)  fclose(hFileRead);
1362                        if (hFileWrite) fclose(hFileWrite);
1363                        #endif
1364                        hFileRead = hFileWrite = 0;
1365                        break;
1366                  default:                  default:
1367                      throw Exception("Unknown file access mode");                      throw Exception("Unknown file access mode");
1368              }              }
1369                Mode = NewMode;
1370                return true;
1371          }          }
1372          return false;          return false;
1373      }      }
# Line 1352  namespace RIFF { Line 1384  namespace RIFF {
1384       */       */
1385      void File::Save() {      void File::Save() {
1386          // reopen file in write mode          // reopen file in write mode
1387          bool bModeWasChanged = SetMode(stream_mode_read_write);          SetMode(stream_mode_read_write);
1388    
1389          // to be able to save the whole file without loading everything into          // to be able to save the whole file without loading everything into
1390          // RAM and without having to store the data in a temporary file, we          // RAM and without having to store the data in a temporary file, we
# Line 1365  namespace RIFF { Line 1397  namespace RIFF {
1397          unsigned long ulPositiveSizeDiff = 0;          unsigned long ulPositiveSizeDiff = 0;
1398          for (ChunkList::iterator iter = ResizedChunks.begin(), end = ResizedChunks.end(); iter != end; ++iter) {          for (ChunkList::iterator iter = ResizedChunks.begin(), end = ResizedChunks.end(); iter != end; ++iter) {
1399              if ((*iter)->GetNewSize() == 0) throw Exception("There is at least one empty chunk (zero size)");              if ((*iter)->GetNewSize() == 0) throw Exception("There is at least one empty chunk (zero size)");
1400              unsigned long ulDiff = (*iter)->GetNewSize() - (*iter)->GetSize() + 1L; // +1 in case we have to add a pad byte              if ((*iter)->GetNewSize() + 1L > (*iter)->GetSize()) {
1401              if (ulDiff > 0) ulPositiveSizeDiff += ulDiff;                  unsigned long ulDiff = (*iter)->GetNewSize() - (*iter)->GetSize() + 1L; // +1 in case we have to add a pad byte
1402                    ulPositiveSizeDiff += ulDiff;
1403                }
1404          }          }
1405    
1406          unsigned long ulWorkingFileSize = GetFileSize();          unsigned long ulWorkingFileSize = GetFileSize();
# Line 1400  namespace RIFF { Line 1434  namespace RIFF {
1434          }          }
1435    
1436          // rebuild / rewrite complete RIFF tree          // rebuild / rewrite complete RIFF tree
1437          unsigned long ulTotalSize = WriteChunk(0, ulPositiveSizeDiff);          unsigned long ulTotalSize  = WriteChunk(0, ulPositiveSizeDiff);
1438            unsigned long ulActualSize = __GetFileSize(hFileWrite);
1439    
1440          // resize file to the final size          // resize file to the final size
1441          if (ulTotalSize < ulWorkingFileSize) ResizeFile(ulTotalSize);          if (ulTotalSize < ulActualSize) ResizeFile(ulTotalSize);
1442    
1443          // forget all resized chunks          // forget all resized chunks
1444          ResizedChunks.clear();          ResizedChunks.clear();
   
         // reopen file in read mode  
         if (bModeWasChanged) SetMode(stream_mode_read);  
1445      }      }
1446    
1447      /** @brief Save changes to another file.      /** @brief Save changes to another file.
# Line 1417  namespace RIFF { Line 1449  namespace RIFF {
1449       * Make all changes of all chunks persistent by writing them to another       * Make all changes of all chunks persistent by writing them to another
1450       * file. <b>Caution:</b> this method is optimized for writing to       * file. <b>Caution:</b> this method is optimized for writing to
1451       * <b>another</b> file, do not use it to save the changes to the same       * <b>another</b> file, do not use it to save the changes to the same
1452       * file! Use File::Save() in that case instead!       * file! Use File::Save() in that case instead! Ignoring this might
1453         * result in a corrupted file, especially in case chunks were resized!
1454       *       *
1455       * After calling this method, this File object will be associated with       * After calling this method, this File object will be associated with
1456       * the new file (given by \a path) afterwards.       * the new file (given by \a path) afterwards.
# Line 1425  namespace RIFF { Line 1458  namespace RIFF {
1458       * @param path - path and file name where everything should be written to       * @param path - path and file name where everything should be written to
1459       */       */
1460      void File::Save(const String& path) {      void File::Save(const String& path) {
1461            //TODO: we should make a check here if somebody tries to write to the same file and automatically call the other Save() method in that case
1462    
1463            if (Filename.length() > 0) SetMode(stream_mode_read);
1464          // open the other (new) file for writing and truncate it to zero size          // open the other (new) file for writing and truncate it to zero size
1465          #if POSIX          #if POSIX
1466          hFileWrite = open(path.c_str(), O_RDWR | O_CREAT | O_TRUNC);          hFileWrite = open(path.c_str(), O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP);
1467          if (hFileWrite < 0) {          if (hFileWrite < 0) {
1468              hFileWrite = hFileRead;              hFileWrite = hFileRead;
1469              throw Exception("Could not open file \"" + path + "\" for writing");              throw Exception("Could not open file \"" + path + "\" for writing");
# Line 1439  namespace RIFF { Line 1475  namespace RIFF {
1475              throw Exception("Could not open file \"" + path + "\" for writing");              throw Exception("Could not open file \"" + path + "\" for writing");
1476          }          }
1477          #endif // POSIX          #endif // POSIX
1478            Mode = stream_mode_read_write;
1479    
1480          // write complete RIFF tree to the other (new) file          // write complete RIFF tree to the other (new) file
1481          WriteChunk(0, 0);          unsigned long ulTotalSize  = WriteChunk(0, 0);
1482            unsigned long ulActualSize = __GetFileSize(hFileWrite);
1483    
1484            // resize file to the final size (if the file was originally larger)
1485            if (ulTotalSize < ulActualSize) ResizeFile(ulTotalSize);
1486    
1487          // forget all resized chunks          // forget all resized chunks
1488          ResizedChunks.clear();          ResizedChunks.clear();
1489    
1490            if (Filename.length() > 0) {
1491                #if POSIX
1492                close(hFileWrite);
1493                #else
1494                fclose(hFileWrite);
1495                #endif
1496                hFileWrite = hFileRead;
1497            }
1498    
1499          // associate new file with this File object from now on          // associate new file with this File object from now on
1500          Filename = path;          Filename = path;
1501          stream_mode_t oldMode = Mode;          Mode = (stream_mode_t) -1;       // Just set it to an undefined mode ...
1502          Mode = (stream_mode_t) -1; // Just set it to an undefined mode ...          SetMode(stream_mode_read_write); // ... so SetMode() has to reopen the file handles.
         SetMode(oldMode);          // ... so SetMode() has to reopen the file handles.  
1503      }      }
1504    
1505      void File::ResizeFile(unsigned long ulNewSize) {      void File::ResizeFile(unsigned long ulNewSize) {
# Line 1459  namespace RIFF { Line 1508  namespace RIFF {
1508              throw Exception("Could not resize file \"" + Filename + "\"");              throw Exception("Could not resize file \"" + Filename + "\"");
1509          #else          #else
1510          # error Sorry, this version of libgig only supports POSIX systems yet.          # error Sorry, this version of libgig only supports POSIX systems yet.
1511          # error Reason: portable implementation of RIFF::File::ResizeFile() is missing!          # error Reason: portable implementation of RIFF::File::ResizeFile() is missing (yet)!
1512          #endif          #endif
1513      }      }
1514    
# Line 1479  namespace RIFF { Line 1528  namespace RIFF {
1528      }      }
1529    
1530      unsigned long File::GetFileSize() {      unsigned long File::GetFileSize() {
1531          #if POSIX          return __GetFileSize(hFileRead);
1532        }
1533    
1534        #if POSIX
1535        unsigned long File::__GetFileSize(int hFile) {
1536          struct stat filestat;          struct stat filestat;
1537          fstat(hFileRead, &filestat);          fstat(hFile, &filestat);
1538          long size = filestat.st_size;          long size = filestat.st_size;
         #else // standard C functions  
         long curpos = ftell(hFileRead);  
         fseek(hFileRead, 0, SEEK_END);  
         long size = ftell(hFileRead);  
         fseek(hFileRead, curpos, SEEK_SET);  
         #endif // POSIX  
1539          return size;          return size;
1540      }      }
1541        #else // standard C functions
1542        unsigned long File::__GetFileSize(FILE* hFile) {
1543            long curpos = ftell(hFile);
1544            fseek(hFile, 0, SEEK_END);
1545            long size = ftell(hFile);
1546            fseek(hFile, curpos, SEEK_SET);
1547            return size;
1548        }
1549        #endif
1550    
1551    
1552  // *************** Exception ***************  // *************** Exception ***************

Legend:
Removed from v.780  
changed lines
  Added in v.802

  ViewVC Help
Powered by ViewVC