/[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 833 by schoenebeck, Sun Feb 5 17:30:13 2006 UTC revision 1095 by schoenebeck, Mon Mar 12 18:16:55 2007 UTC
# Line 1  Line 1 
1  /***************************************************************************  /***************************************************************************
2   *                                                                         *   *                                                                         *
3   *   libgig - C++ cross-platform Gigasampler format file loader library    *   *   libgig - C++ cross-platform Gigasampler format file access library    *
4   *                                                                         *   *                                                                         *
5   *   Copyright (C) 2003-2005 by Christian Schoenebeck                      *   *   Copyright (C) 2003-2007 by Christian Schoenebeck                      *
6   *                              <cuse@users.sourceforge.net>               *   *                              <cuse@users.sourceforge.net>               *
7   *                                                                         *   *                                                                         *
8   *   This library is free software; you can redistribute it and/or modify  *   *   This library is free software; you can redistribute it and/or modify  *
# Line 70  namespace RIFF { Line 70  namespace RIFF {
70      }      }
71    
72      Chunk::~Chunk() {      Chunk::~Chunk() {
73            if (CurrentChunkSize != NewChunkSize) pFile->UnlogResized(this);
74          if (pChunkData) delete[] pChunkData;          if (pChunkData) delete[] pChunkData;
75      }      }
76    
# Line 81  namespace RIFF { Line 82  namespace RIFF {
82          if (lseek(pFile->hFileRead, fPos, SEEK_SET) != -1) {          if (lseek(pFile->hFileRead, fPos, SEEK_SET) != -1) {
83              read(pFile->hFileRead, &ChunkID, 4);              read(pFile->hFileRead, &ChunkID, 4);
84              read(pFile->hFileRead, &CurrentChunkSize, 4);              read(pFile->hFileRead, &CurrentChunkSize, 4);
85            #elif defined(WIN32)
86            if (SetFilePointer(pFile->hFileRead, fPos, NULL/*32 bit*/, FILE_BEGIN) != INVALID_SET_FILE_POINTER) {
87                DWORD dwBytesRead;
88                ReadFile(pFile->hFileRead, &ChunkID, 4, &dwBytesRead, NULL);
89                ReadFile(pFile->hFileRead, &CurrentChunkSize, 4, &dwBytesRead, NULL);
90          #else          #else
91          if (!fseek(pFile->hFileRead, fPos, SEEK_SET)) {          if (!fseek(pFile->hFileRead, fPos, SEEK_SET)) {
92              fread(&ChunkID, 4, 1, pFile->hFileRead);              fread(&ChunkID, 4, 1, pFile->hFileRead);
# Line 129  namespace RIFF { Line 135  namespace RIFF {
135              write(pFile->hFileWrite, &uiNewChunkID, 4);              write(pFile->hFileWrite, &uiNewChunkID, 4);
136              write(pFile->hFileWrite, &uiNewChunkSize, 4);              write(pFile->hFileWrite, &uiNewChunkSize, 4);
137          }          }
138            #elif defined(WIN32)
139            if (SetFilePointer(pFile->hFileWrite, fPos, NULL/*32 bit*/, FILE_BEGIN) != INVALID_SET_FILE_POINTER) {
140                DWORD dwBytesWritten;
141                WriteFile(pFile->hFileWrite, &uiNewChunkID, 4, &dwBytesWritten, NULL);
142                WriteFile(pFile->hFileWrite, &uiNewChunkSize, 4, &dwBytesWritten, NULL);
143            }
144          #else          #else
145          if (!fseek(pFile->hFileWrite, fPos, SEEK_SET)) {          if (!fseek(pFile->hFileWrite, fPos, SEEK_SET)) {
146              fwrite(&uiNewChunkID, 4, 1, pFile->hFileWrite);              fwrite(&uiNewChunkID, 4, 1, pFile->hFileWrite);
# Line 212  namespace RIFF { Line 224  namespace RIFF {
224        std::cout << "Chunk::GetState()" << std::endl;        std::cout << "Chunk::GetState()" << std::endl;
225        #endif // DEBUG        #endif // DEBUG
226          #if POSIX          #if POSIX
227          if (pFile->hFileRead == 0)    return stream_closed;          if (pFile->hFileRead == 0) return stream_closed;
228            #elif defined (WIN32)
229            if (pFile->hFileRead == INVALID_HANDLE_VALUE)
230                return stream_closed;
231          #else          #else
232          if (pFile->hFileRead == NULL) return stream_closed;          if (pFile->hFileRead == NULL) return stream_closed;
233          #endif // POSIX          #endif // POSIX
# Line 246  namespace RIFF { Line 261  namespace RIFF {
261          unsigned long readWords = read(pFile->hFileRead, pData, WordCount * WordSize);          unsigned long readWords = read(pFile->hFileRead, pData, WordCount * WordSize);
262          if (readWords < 1) return 0;          if (readWords < 1) return 0;
263          readWords /= WordSize;          readWords /= WordSize;
264            #elif defined(WIN32)
265            if (SetFilePointer(pFile->hFileRead, ulStartPos + ulPos, NULL/*32 bit*/, FILE_BEGIN) == INVALID_SET_FILE_POINTER) return 0;
266            DWORD readWords;
267            ReadFile(pFile->hFileRead, pData, WordCount * WordSize, &readWords, NULL);
268            if (readWords < 1) return 0;
269            readWords /= WordSize;
270          #else // standard C functions          #else // standard C functions
271          if (fseek(pFile->hFileRead, ulStartPos + ulPos, SEEK_SET)) return 0;          if (fseek(pFile->hFileRead, ulStartPos + ulPos, SEEK_SET)) return 0;
272          unsigned long readWords = fread(pData, WordSize, WordCount, pFile->hFileRead);          unsigned long readWords = fread(pData, WordSize, WordCount, pFile->hFileRead);
# Line 315  namespace RIFF { Line 336  namespace RIFF {
336          unsigned long writtenWords = write(pFile->hFileWrite, pData, WordCount * WordSize);          unsigned long writtenWords = write(pFile->hFileWrite, pData, WordCount * WordSize);
337          if (writtenWords < 1) throw Exception("POSIX IO Error while trying to write chunk data");          if (writtenWords < 1) throw Exception("POSIX IO Error while trying to write chunk data");
338          writtenWords /= WordSize;          writtenWords /= WordSize;
339            #elif defined(WIN32)
340            if (SetFilePointer(pFile->hFileWrite, ulStartPos + ulPos, NULL/*32 bit*/, FILE_BEGIN) == INVALID_SET_FILE_POINTER) {
341                throw Exception("Could not seek to position " + ToString(ulPos) +
342                                " in chunk (" + ToString(ulStartPos + ulPos) + " in file)");            
343            }
344            DWORD writtenWords;
345            WriteFile(pFile->hFileWrite, pData, WordCount * WordSize, &writtenWords, NULL);
346            if (writtenWords < 1) throw Exception("Windows IO Error while trying to write chunk data");
347            writtenWords /= WordSize;
348          #else // standard C functions          #else // standard C functions
349          if (fseek(pFile->hFileWrite, ulStartPos + ulPos, SEEK_SET)) {          if (fseek(pFile->hFileWrite, ulStartPos + ulPos, SEEK_SET)) {
350              throw Exception("Could not seek to position " + ToString(ulPos) +              throw Exception("Could not seek to position " + ToString(ulPos) +
# Line 679  namespace RIFF { Line 709  namespace RIFF {
709          if (!pChunkData && pFile->Filename != "") {          if (!pChunkData && pFile->Filename != "") {
710              #if POSIX              #if POSIX
711              if (lseek(pFile->hFileRead, ulStartPos, SEEK_SET) == -1) return NULL;              if (lseek(pFile->hFileRead, ulStartPos, SEEK_SET) == -1) return NULL;
712                #elif defined(WIN32)
713                if (SetFilePointer(pFile->hFileRead, ulStartPos, NULL/*32 bit*/, FILE_BEGIN) == INVALID_SET_FILE_POINTER) return NULL;
714              #else              #else
715              if (fseek(pFile->hFileRead, ulStartPos, SEEK_SET)) return NULL;              if (fseek(pFile->hFileRead, ulStartPos, SEEK_SET)) return NULL;
716              #endif // POSIX              #endif // POSIX
# Line 688  namespace RIFF { Line 720  namespace RIFF {
720              memset(pChunkData, 0, ulBufferSize);              memset(pChunkData, 0, ulBufferSize);
721              #if POSIX              #if POSIX
722              unsigned long readWords = read(pFile->hFileRead, pChunkData, GetSize());              unsigned long readWords = read(pFile->hFileRead, pChunkData, GetSize());
723                #elif defined(WIN32)
724                DWORD readWords;
725                ReadFile(pFile->hFileRead, pChunkData, GetSize(), &readWords, NULL);
726              #else              #else
727              unsigned long readWords = fread(pChunkData, 1, GetSize(), pFile->hFileRead);              unsigned long readWords = fread(pChunkData, 1, GetSize(), pFile->hFileRead);
728              #endif // POSIX              #endif // POSIX
# Line 775  namespace RIFF { Line 810  namespace RIFF {
810              if (write(pFile->hFileWrite, pChunkData, NewChunkSize) != NewChunkSize) {              if (write(pFile->hFileWrite, pChunkData, NewChunkSize) != NewChunkSize) {
811                  throw Exception("Writing Chunk data (from RAM) failed");                  throw Exception("Writing Chunk data (from RAM) failed");
812              }              }
813                #elif defined(WIN32)
814                SetFilePointer(pFile->hFileWrite, ulWritePos, NULL/*32 bit*/, FILE_BEGIN);
815                DWORD dwBytesWritten;
816                WriteFile(pFile->hFileWrite, pChunkData, NewChunkSize, &dwBytesWritten, NULL);
817                if (dwBytesWritten != NewChunkSize) {
818                    throw Exception("Writing Chunk data (from RAM) failed");
819                }
820              #else              #else
821              fseek(pFile->hFileWrite, ulWritePos, SEEK_SET);              fseek(pFile->hFileWrite, ulWritePos, SEEK_SET);
822              if (fwrite(pChunkData, 1, NewChunkSize, pFile->hFileWrite) != NewChunkSize) {              if (fwrite(pChunkData, 1, NewChunkSize, pFile->hFileWrite) != NewChunkSize) {
# Line 785  namespace RIFF { Line 827  namespace RIFF {
827              // move chunk data from the end of the file to the appropriate position              // move chunk data from the end of the file to the appropriate position
828              int8_t* pCopyBuffer = new int8_t[4096];              int8_t* pCopyBuffer = new int8_t[4096];
829              unsigned long ulToMove = (NewChunkSize < CurrentChunkSize) ? NewChunkSize : CurrentChunkSize;              unsigned long ulToMove = (NewChunkSize < CurrentChunkSize) ? NewChunkSize : CurrentChunkSize;
830                #if defined(WIN32)
831                DWORD iBytesMoved = 1; // we have to pass it via pointer to the Windows API, thus the correct size must be ensured
832                #else
833              int iBytesMoved = 1;              int iBytesMoved = 1;
834                #endif
835              for (unsigned long ulOffset = 0; iBytesMoved > 0; ulOffset += iBytesMoved, ulToMove -= iBytesMoved) {              for (unsigned long ulOffset = 0; iBytesMoved > 0; ulOffset += iBytesMoved, ulToMove -= iBytesMoved) {
836                  iBytesMoved = (ulToMove < 4096) ? ulToMove : 4096;                  iBytesMoved = (ulToMove < 4096) ? ulToMove : 4096;
837                  #if POSIX                  #if POSIX
# Line 793  namespace RIFF { Line 839  namespace RIFF {
839                  iBytesMoved = read(pFile->hFileRead, pCopyBuffer, iBytesMoved);                  iBytesMoved = read(pFile->hFileRead, pCopyBuffer, iBytesMoved);
840                  lseek(pFile->hFileWrite, ulWritePos + ulOffset, SEEK_SET);                  lseek(pFile->hFileWrite, ulWritePos + ulOffset, SEEK_SET);
841                  iBytesMoved = write(pFile->hFileWrite, pCopyBuffer, iBytesMoved);                  iBytesMoved = write(pFile->hFileWrite, pCopyBuffer, iBytesMoved);
842                    #elif defined(WIN32)
843                    SetFilePointer(pFile->hFileRead, ulStartPos + ulCurrentDataOffset + ulOffset, NULL/*32 bit*/, FILE_BEGIN);
844                    ReadFile(pFile->hFileRead, pCopyBuffer, iBytesMoved, &iBytesMoved, NULL);
845                    SetFilePointer(pFile->hFileWrite, ulWritePos + ulOffset, NULL/*32 bit*/, FILE_BEGIN);
846                    WriteFile(pFile->hFileWrite, pCopyBuffer, iBytesMoved, &iBytesMoved, NULL);
847                  #else                  #else
848                  fseek(pFile->hFileRead, ulStartPos + ulCurrentDataOffset + ulOffset, SEEK_SET);                  fseek(pFile->hFileRead, ulStartPos + ulCurrentDataOffset + ulOffset, SEEK_SET);
849                  iBytesMoved = fread(pCopyBuffer, 1, iBytesMoved, pFile->hFileRead);                  iBytesMoved = fread(pCopyBuffer, 1, iBytesMoved, pFile->hFileRead);
# Line 818  namespace RIFF { Line 869  namespace RIFF {
869              #if POSIX              #if POSIX
870              lseek(pFile->hFileWrite, ulStartPos + NewChunkSize, SEEK_SET);              lseek(pFile->hFileWrite, ulStartPos + NewChunkSize, SEEK_SET);
871              write(pFile->hFileWrite, &cPadByte, 1);              write(pFile->hFileWrite, &cPadByte, 1);
872                #elif defined(WIN32)
873                SetFilePointer(pFile->hFileWrite, ulStartPos + NewChunkSize, NULL/*32 bit*/, FILE_BEGIN);
874                DWORD dwBytesWritten;
875                WriteFile(pFile->hFileWrite, &cPadByte, 1, &dwBytesWritten, NULL);
876              #else              #else
877              fseek(pFile->hFileWrite, ulStartPos + NewChunkSize, SEEK_SET);              fseek(pFile->hFileWrite, ulStartPos + NewChunkSize, SEEK_SET);
878              fwrite(&cPadByte, 1, 1, pFile->hFileWrite);              fwrite(&cPadByte, 1, 1, pFile->hFileWrite);
# Line 1101  namespace RIFF { Line 1156  namespace RIFF {
1156       *       *
1157       * Removes the sub chunk given by \a pSubChunk from this list and frees       * Removes the sub chunk given by \a pSubChunk from this list and frees
1158       * it completely from RAM. The given chunk can either be a normal sub       * it completely from RAM. The given chunk can either be a normal sub
1159       * chunk or a list sub chunk. You should call File::Save() to make this       * chunk or a list sub chunk. In case the given chunk is a list chunk,
1160       * change persistent at any time.       * all its subchunks (if any) will be removed recursively as well. You
1161         * should call File::Save() to make this change persistent at any time.
1162       *       *
1163       * @param pSubChunk - sub chunk or sub list chunk to be removed       * @param pSubChunk - sub chunk or sub list chunk to be removed
1164       */       */
# Line 1133  namespace RIFF { Line 1189  namespace RIFF {
1189          #if POSIX          #if POSIX
1190          lseek(pFile->hFileRead, fPos + CHUNK_HEADER_SIZE, SEEK_SET);          lseek(pFile->hFileRead, fPos + CHUNK_HEADER_SIZE, SEEK_SET);
1191          read(pFile->hFileRead, &ListType, 4);          read(pFile->hFileRead, &ListType, 4);
1192            #elif defined(WIN32)
1193            SetFilePointer(pFile->hFileRead, fPos + CHUNK_HEADER_SIZE, NULL/*32 bit*/, FILE_BEGIN);
1194            DWORD dwBytesRead;
1195            ReadFile(pFile->hFileRead, &ListType, 4, &dwBytesRead, NULL);
1196          #else          #else
1197          fseek(pFile->hFileRead, fPos + CHUNK_HEADER_SIZE, SEEK_SET);          fseek(pFile->hFileRead, fPos + CHUNK_HEADER_SIZE, SEEK_SET);
1198          fread(&ListType, 4, 1, pFile->hFileRead);          fread(&ListType, 4, 1, pFile->hFileRead);
# Line 1153  namespace RIFF { Line 1213  namespace RIFF {
1213          #if POSIX          #if POSIX
1214          lseek(pFile->hFileWrite, fPos + CHUNK_HEADER_SIZE, SEEK_SET);          lseek(pFile->hFileWrite, fPos + CHUNK_HEADER_SIZE, SEEK_SET);
1215          write(pFile->hFileWrite, &ListType, 4);          write(pFile->hFileWrite, &ListType, 4);
1216            #elif defined(WIN32)
1217            SetFilePointer(pFile->hFileWrite, fPos + CHUNK_HEADER_SIZE, NULL/*32 bit*/, FILE_BEGIN);
1218            DWORD dwBytesWritten;
1219            WriteFile(pFile->hFileWrite, &ListType, 4, &dwBytesWritten, NULL);
1220          #else          #else
1221          fseek(pFile->hFileWrite, fPos + CHUNK_HEADER_SIZE, SEEK_SET);          fseek(pFile->hFileWrite, fPos + CHUNK_HEADER_SIZE, SEEK_SET);
1222          fwrite(&ListType, 4, 1, pFile->hFileWrite);          fwrite(&ListType, 4, 1, pFile->hFileWrite);
# Line 1266  namespace RIFF { Line 1330  namespace RIFF {
1330       * @see AddSubChunk(), AddSubList()       * @see AddSubChunk(), AddSubList()
1331       */       */
1332      File::File(uint32_t FileType) : List(this) {      File::File(uint32_t FileType) : List(this) {
1333            #if defined(WIN32)
1334            hFileRead = hFileWrite = INVALID_HANDLE_VALUE;
1335            #else
1336          hFileRead = hFileWrite = 0;          hFileRead = hFileWrite = 0;
1337            #endif
1338          Mode = stream_mode_closed;          Mode = stream_mode_closed;
1339          bEndianNative = true;          bEndianNative = true;
1340          ulStartPos = RIFF_HEADER_SIZE;          ulStartPos = RIFF_HEADER_SIZE;
# Line 1292  namespace RIFF { Line 1360  namespace RIFF {
1360              hFileRead = hFileWrite = 0;              hFileRead = hFileWrite = 0;
1361              throw RIFF::Exception("Can't open \"" + path + "\"");              throw RIFF::Exception("Can't open \"" + path + "\"");
1362          }          }
1363            #elif defined(WIN32)
1364            hFileRead = hFileWrite = CreateFile(
1365                                         path.c_str(), GENERIC_READ,
1366                                         FILE_SHARE_READ | FILE_SHARE_WRITE,
1367                                         NULL, OPEN_EXISTING,
1368                                         FILE_ATTRIBUTE_NORMAL, NULL
1369                                     );
1370            if (hFileRead == INVALID_HANDLE_VALUE) {
1371                hFileRead = hFileWrite = INVALID_HANDLE_VALUE;
1372                throw RIFF::Exception("Can't open \"" + path + "\"");
1373            }
1374          #else          #else
1375          hFileRead = hFileWrite = fopen(path.c_str(), "rb");          hFileRead = hFileWrite = fopen(path.c_str(), "rb");
1376          if (!hFile) throw RIFF::Exception("Can't open \"" + path + "\"");          if (!hFileRead) throw RIFF::Exception("Can't open \"" + path + "\"");
1377          #endif // POSIX          #endif // POSIX
1378          Mode = stream_mode_read;          Mode = stream_mode_read;
1379          ulStartPos = RIFF_HEADER_SIZE;          ulStartPos = RIFF_HEADER_SIZE;
# Line 1333  namespace RIFF { Line 1412  namespace RIFF {
1412                          hFileRead = hFileWrite = 0;                          hFileRead = hFileWrite = 0;
1413                          throw Exception("Could not (re)open file \"" + Filename + "\" in read mode");                          throw Exception("Could not (re)open file \"" + Filename + "\" in read mode");
1414                      }                      }
1415                        #elif defined(WIN32)
1416                        if (hFileRead != INVALID_HANDLE_VALUE) CloseHandle(hFileRead);
1417                        hFileRead = hFileWrite = CreateFile(
1418                                                     Filename.c_str(), GENERIC_READ,
1419                                                     FILE_SHARE_READ | FILE_SHARE_WRITE,
1420                                                     NULL, OPEN_EXISTING,
1421                                                     FILE_ATTRIBUTE_NORMAL, NULL
1422                                                 );
1423                        if (hFileRead == INVALID_HANDLE_VALUE) {
1424                            hFileRead = hFileWrite = INVALID_HANDLE_VALUE;
1425                            throw Exception("Could not (re)open file \"" + Filename + "\" in read mode");
1426                        }
1427                      #else                      #else
1428                      if (hFileRead) fclose(hFileRead);                      if (hFileRead) fclose(hFileRead);
1429                      hFileRead = hFileWrite = fopen(path.c_str(), "rb");                      hFileRead = hFileWrite = fopen(Filename.c_str(), "rb");
1430                      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");
1431                      #endif                      #endif
1432                      __resetPos(); // reset read/write position of ALL 'Chunk' objects                      __resetPos(); // reset read/write position of ALL 'Chunk' objects
# Line 1348  namespace RIFF { Line 1439  namespace RIFF {
1439                          hFileRead = hFileWrite = open(Filename.c_str(), O_RDONLY | O_NONBLOCK);                          hFileRead = hFileWrite = open(Filename.c_str(), O_RDONLY | O_NONBLOCK);
1440                          throw Exception("Could not open file \"" + Filename + "\" in read+write mode");                          throw Exception("Could not open file \"" + Filename + "\" in read+write mode");
1441                      }                      }
1442                        #elif defined(WIN32)
1443                        if (hFileRead != INVALID_HANDLE_VALUE) CloseHandle(hFileRead);
1444                        hFileRead = hFileWrite = CreateFile(
1445                                                     Filename.c_str(),
1446                                                     GENERIC_READ | GENERIC_WRITE,
1447                                                     FILE_SHARE_READ,
1448                                                     NULL, OPEN_ALWAYS,
1449                                                     FILE_ATTRIBUTE_NORMAL, NULL
1450                                                 );
1451                        if (hFileRead == INVALID_HANDLE_VALUE) {
1452                            hFileRead = hFileWrite = CreateFile(
1453                                                         Filename.c_str(), GENERIC_READ,
1454                                                         FILE_SHARE_READ | FILE_SHARE_WRITE,
1455                                                         NULL, OPEN_EXISTING,
1456                                                         FILE_ATTRIBUTE_NORMAL, NULL
1457                                                     );
1458                            throw Exception("Could not (re)open file \"" + Filename + "\" in read mode");
1459                        }
1460                      #else                      #else
1461                      if (hFileRead) fclose(hFileRead);                      if (hFileRead) fclose(hFileRead);
1462                      hFileRead = hFileWrite = fopen(path.c_str(), "r+b");                      hFileRead = hFileWrite = fopen(Filename.c_str(), "r+b");
1463                      if (!hFileRead) {                      if (!hFileRead) {
1464                          hFileRead = hFileWrite = fopen(path.c_str(), "rb");                          hFileRead = hFileWrite = fopen(Filename.c_str(), "rb");
1465                          throw Exception("Could not open file \"" + Filename + "\" in read+write mode");                          throw Exception("Could not open file \"" + Filename + "\" in read+write mode");
1466                      }                      }
1467                      #endif                      #endif
# Line 1362  namespace RIFF { Line 1471  namespace RIFF {
1471                      #if POSIX                      #if POSIX
1472                      if (hFileRead)  close(hFileRead);                      if (hFileRead)  close(hFileRead);
1473                      if (hFileWrite) close(hFileWrite);                      if (hFileWrite) close(hFileWrite);
1474                        #elif defined(WIN32)
1475                        if (hFileRead  != INVALID_HANDLE_VALUE) CloseHandle(hFileRead);
1476                        if (hFileWrite != INVALID_HANDLE_VALUE) CloseHandle(hFileWrite);
1477                      #else                      #else
1478                      if (hFileRead)  fclose(hFileRead);                      if (hFileRead)  fclose(hFileRead);
1479                      if (hFileWrite) fclose(hFileWrite);                      if (hFileWrite) fclose(hFileWrite);
# Line 1404  namespace RIFF { Line 1516  namespace RIFF {
1516          // first we sum up all positive chunk size changes (and skip all negative ones)          // first we sum up all positive chunk size changes (and skip all negative ones)
1517          unsigned long ulPositiveSizeDiff = 0;          unsigned long ulPositiveSizeDiff = 0;
1518          for (ChunkList::iterator iter = ResizedChunks.begin(), end = ResizedChunks.end(); iter != end; ++iter) {          for (ChunkList::iterator iter = ResizedChunks.begin(), end = ResizedChunks.end(); iter != end; ++iter) {
1519              if ((*iter)->GetNewSize() == 0) throw Exception("There is at least one empty chunk (zero size)");              if ((*iter)->GetNewSize() == 0) {
1520                    // just to make the exception message a bit more verbose: resolve the chunk's path
1521                    String sChunkPath;
1522                    for (Chunk* pChunk = *iter; pChunk; pChunk = pChunk->GetParent()) {
1523                        if (pChunk->GetChunkID() == CHUNK_ID_LIST) {
1524                            List* pList = (List*) pChunk;
1525                            sChunkPath = "->'" + pList->GetListTypeString() + "'" + sChunkPath;
1526                        } else {
1527                            sChunkPath = "->'" + pChunk->GetChunkIDString() + "'" + sChunkPath;
1528                        }
1529                    }
1530                    throw Exception("There is at least one empty chunk (zero size): " + sChunkPath);
1531                }
1532              if ((*iter)->GetNewSize() + 1L > (*iter)->GetSize()) {              if ((*iter)->GetNewSize() + 1L > (*iter)->GetSize()) {
1533                  unsigned long ulDiff = (*iter)->GetNewSize() - (*iter)->GetSize() + 1L; // +1 in case we have to add a pad byte                  unsigned long ulDiff = (*iter)->GetNewSize() - (*iter)->GetSize() + 1L; // +1 in case we have to add a pad byte
1534                  ulPositiveSizeDiff += ulDiff;                  ulPositiveSizeDiff += ulDiff;
# Line 1421  namespace RIFF { Line 1545  namespace RIFF {
1545              // ... and move current data by the same amount towards end of file.              // ... and move current data by the same amount towards end of file.
1546              int8_t* pCopyBuffer = new int8_t[4096];              int8_t* pCopyBuffer = new int8_t[4096];
1547              const unsigned long ulFileSize = GetSize() + RIFF_HEADER_SIZE;              const unsigned long ulFileSize = GetSize() + RIFF_HEADER_SIZE;
1548              int iBytesMoved = 1;              #if defined(WIN32)
1549                DWORD iBytesMoved = 1; // we have to pass it via pointer to the Windows API, thus the correct size must be ensured
1550                #else
1551                int iBytesMoved = 1;
1552                #endif
1553              for (unsigned long ulPos = 0; iBytesMoved > 0; ulPos += iBytesMoved) {              for (unsigned long ulPos = 0; iBytesMoved > 0; ulPos += iBytesMoved) {
1554                  const unsigned long ulToMove = ulFileSize - ulPos;                  const unsigned long ulToMove = ulFileSize - ulPos;
1555                  iBytesMoved = (ulToMove < 4096) ? ulToMove : 4096;                  iBytesMoved = (ulToMove < 4096) ? ulToMove : 4096;
# Line 1430  namespace RIFF { Line 1558  namespace RIFF {
1558                  iBytesMoved = read(hFileRead, pCopyBuffer, iBytesMoved);                  iBytesMoved = read(hFileRead, pCopyBuffer, iBytesMoved);
1559                  lseek(hFileWrite, ulPos + ulPositiveSizeDiff, SEEK_SET);                  lseek(hFileWrite, ulPos + ulPositiveSizeDiff, SEEK_SET);
1560                  iBytesMoved = write(hFileWrite, pCopyBuffer, iBytesMoved);                  iBytesMoved = write(hFileWrite, pCopyBuffer, iBytesMoved);
1561                    #elif defined(WIN32)
1562                    SetFilePointer(hFileRead, ulPos, NULL/*32 bit*/, FILE_BEGIN);
1563                    ReadFile(hFileRead, pCopyBuffer, iBytesMoved, &iBytesMoved, NULL);
1564                    SetFilePointer(hFileWrite, ulPos + ulPositiveSizeDiff, NULL/*32 bit*/, FILE_BEGIN);
1565                    WriteFile(hFileWrite, pCopyBuffer, iBytesMoved, &iBytesMoved, NULL);
1566                  #else                  #else
1567                  fseek(hFileRead, ulPos, SEEK_SET);                  fseek(hFileRead, ulPos, SEEK_SET);
1568                  iBytesMoved = fread(pCopyBuffer, 1, iBytesMoved, hFileRead);                  iBytesMoved = fread(pCopyBuffer, 1, iBytesMoved, hFileRead);
# Line 1479  namespace RIFF { Line 1612  namespace RIFF {
1612              hFileWrite = hFileRead;              hFileWrite = hFileRead;
1613              throw Exception("Could not open file \"" + path + "\" for writing");              throw Exception("Could not open file \"" + path + "\" for writing");
1614          }          }
1615            #elif defined(WIN32)
1616            hFileWrite = CreateFile(
1617                             path.c_str(), GENERIC_WRITE, FILE_SHARE_READ,
1618                             NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL
1619                         );
1620            if (hFileWrite == INVALID_HANDLE_VALUE) {
1621                hFileWrite = hFileRead;
1622                throw Exception("Could not open file \"" + path + "\" for writing");
1623            }
1624          #else          #else
1625          hFileWrite = fopen(path.c_str(), "w+b");          hFileWrite = fopen(path.c_str(), "w+b");
1626          if (!hFileWrite) {          if (!hFileWrite) {
# Line 1501  namespace RIFF { Line 1643  namespace RIFF {
1643          if (Filename.length() > 0) {          if (Filename.length() > 0) {
1644              #if POSIX              #if POSIX
1645              close(hFileWrite);              close(hFileWrite);
1646                #elif defined(WIN32)
1647                CloseHandle(hFileWrite);
1648              #else              #else
1649              fclose(hFileWrite);              fclose(hFileWrite);
1650              #endif              #endif
# Line 1517  namespace RIFF { Line 1661  namespace RIFF {
1661          #if POSIX          #if POSIX
1662          if (ftruncate(hFileWrite, ulNewSize) < 0)          if (ftruncate(hFileWrite, ulNewSize) < 0)
1663              throw Exception("Could not resize file \"" + Filename + "\"");              throw Exception("Could not resize file \"" + Filename + "\"");
1664            #elif defined(WIN32)
1665            if (
1666                SetFilePointer(hFileWrite, ulNewSize, NULL/*32 bit*/, FILE_BEGIN) == INVALID_SET_FILE_POINTER ||
1667                !SetEndOfFile(hFileWrite)
1668            ) throw Exception("Could not resize file \"" + Filename + "\"");
1669          #else          #else
1670          # error Sorry, this version of libgig only supports POSIX systems yet.          # error Sorry, this version of libgig only supports POSIX and Windows systems yet.
1671          # error Reason: portable implementation of RIFF::File::ResizeFile() is missing (yet)!          # error Reason: portable implementation of RIFF::File::ResizeFile() is missing (yet)!
1672          #endif          #endif
1673      }      }
# Line 1529  namespace RIFF { Line 1678  namespace RIFF {
1678         #endif // DEBUG         #endif // DEBUG
1679          #if POSIX          #if POSIX
1680          if (hFileRead) close(hFileRead);          if (hFileRead) close(hFileRead);
1681            #elif defined(WIN32)
1682            if (hFileRead != INVALID_HANDLE_VALUE) CloseHandle(hFileRead);
1683          #else          #else
1684          if (hFileRead) fclose(hFileRead);          if (hFileRead) fclose(hFileRead);
1685          #endif // POSIX          #endif // POSIX
# Line 1538  namespace RIFF { Line 1689  namespace RIFF {
1689          ResizedChunks.push_back(pResizedChunk);          ResizedChunks.push_back(pResizedChunk);
1690      }      }
1691    
1692        void File::UnlogResized(Chunk* pResizedChunk) {
1693            ResizedChunks.remove(pResizedChunk);
1694        }
1695    
1696      unsigned long File::GetFileSize() {      unsigned long File::GetFileSize() {
1697          return __GetFileSize(hFileRead);          return __GetFileSize(hFileRead);
1698      }      }
# Line 1549  namespace RIFF { Line 1704  namespace RIFF {
1704          long size = filestat.st_size;          long size = filestat.st_size;
1705          return size;          return size;
1706      }      }
1707        #elif defined(WIN32)
1708        unsigned long File::__GetFileSize(HANDLE hFile) {
1709            DWORD dwSize = ::GetFileSize(hFile, NULL /*32bit*/);
1710            if (dwSize == INVALID_FILE_SIZE)
1711                throw Exception("Windows FS error: could not determine file size");
1712            return dwSize;
1713        }
1714      #else // standard C functions      #else // standard C functions
1715      unsigned long File::__GetFileSize(FILE* hFile) {      unsigned long File::__GetFileSize(FILE* hFile) {
1716          long curpos = ftell(hFile);          long curpos = ftell(hFile);

Legend:
Removed from v.833  
changed lines
  Added in v.1095

  ViewVC Help
Powered by ViewVC