--- libgig/trunk/src/RIFF.cpp 2016/05/17 19:04:56 2914 +++ libgig/trunk/src/RIFF.cpp 2019/02/22 12:12:50 3481 @@ -2,7 +2,7 @@ * * * libgig - C++ cross-platform Gigasampler format file access library * * * - * Copyright (C) 2003-2016 by Christian Schoenebeck * + * Copyright (C) 2003-2019 by Christian Schoenebeck * * * * * * This library is free software; you can redistribute it and/or modify * @@ -64,15 +64,71 @@ __range_max = 1.0f; } + /** + * Divides this progress task into the requested amount of equal weighted + * sub-progress tasks and returns a vector with those subprogress tasks. + * + * @param iSubtasks - total amount sub tasks this task should be subdivided + * @returns subtasks + */ + std::vector progress_t::subdivide(int iSubtasks) { + std::vector v; + for (int i = 0; i < iSubtasks; ++i) { + progress_t p; + __divide_progress(this, &p, iSubtasks, i); + v.push_back(p); + } + return v; + } + + /** + * Divides this progress task into the requested amount of sub-progress + * tasks, where each one of those new sub-progress tasks is created with its + * requested individual weight / portion, and finally returns a vector + * with those new subprogress tasks. + * + * The amount of subprogresses to be created is determined by this method + * by calling @c vSubTaskPortions.size() . + * + * Example: consider you wanted to create 3 subprogresses where the 1st + * subtask should be assigned 10% of the new 3 subprogresses' overall + * progress, the 2nd subtask should be assigned 50% of the new 3 + * subprogresses' overall progress, and the 3rd subtask should be assigned + * 40%, then you might call this method like this: + * @code + * std::vector subprogresses = progress.subdivide({0.1, 0.5, 0.4}); + * @endcode + * + * @param vSubTaskPortions - amount and individual weight of subtasks to be + * created + * @returns subtasks + */ + std::vector progress_t::subdivide(std::vector vSubTaskPortions) { + float fTotal = 0.f; // usually 1.0, but we sum the portions up below to be sure + for (int i = 0; i < vSubTaskPortions.size(); ++i) + fTotal += vSubTaskPortions[i]; + + float fLow = 0.f, fHigh = 0.f; + std::vector v; + for (int i = 0; i < vSubTaskPortions.size(); ++i) { + fLow = fHigh; + fHigh = vSubTaskPortions[i]; + progress_t p; + __divide_progress(this, &p, fTotal, fLow, fHigh); + v.push_back(p); + } + return v; + } + // *************** Chunk ************** // * Chunk::Chunk(File* pFile) { - #if DEBUG + #if DEBUG_RIFF std::cout << "Chunk::Chunk(File* pFile)" << std::endl; - #endif // DEBUG + #endif // DEBUG_RIFF ullPos = 0; pParent = NULL; pChunkData = NULL; @@ -84,9 +140,9 @@ } Chunk::Chunk(File* pFile, file_offset_t StartPos, List* Parent) { - #if DEBUG + #if DEBUG_RIFF std::cout << "Chunk::Chunk(File*,file_offset_t,List*),StartPos=" << StartPos << std::endl; - #endif // DEBUG + #endif // DEBUG_RIFF this->pFile = pFile; ullStartPos = StartPos + CHUNK_HEADER_SIZE(pFile->FileOffsetSize); pParent = Parent; @@ -115,9 +171,9 @@ } void Chunk::ReadHeader(file_offset_t filePos) { - #if DEBUG + #if DEBUG_RIFF std::cout << "Chunk::Readheader(" << filePos << ") "; - #endif // DEBUG + #endif // DEBUG_RIFF ChunkID = 0; ullNewChunkSize = ullCurrentChunkSize = 0; #if POSIX @@ -125,7 +181,8 @@ read(pFile->hFileRead, &ChunkID, 4); read(pFile->hFileRead, &ullCurrentChunkSize, pFile->FileOffsetSize); #elif defined(WIN32) - const LARGE_INTEGER liFilePos = { .QuadPart = filePos }; + LARGE_INTEGER liFilePos; + liFilePos.QuadPart = filePos; if (SetFilePointerEx(pFile->hFileRead, liFilePos, NULL/*new pos pointer*/, FILE_BEGIN)) { DWORD dwBytesRead; ReadFile(pFile->hFileRead, &ChunkID, 4, &dwBytesRead, NULL); @@ -152,11 +209,11 @@ else swapBytes_64(&ullCurrentChunkSize); } - #if DEBUG + #if DEBUG_RIFF std::cout << "ckID=" << convertToString(ChunkID) << " "; std::cout << "ckSize=" << ullCurrentChunkSize << " "; std::cout << "bEndianNative=" << pFile->bEndianNative << std::endl; - #endif // DEBUG + #endif // DEBUG_RIFF ullNewChunkSize = ullCurrentChunkSize; } } @@ -185,7 +242,8 @@ write(pFile->hFileWrite, &ullNewChunkSize, pFile->FileOffsetSize); } #elif defined(WIN32) - const LARGE_INTEGER liFilePos = { .QuadPart = filePos }; + LARGE_INTEGER liFilePos; + liFilePos.QuadPart = filePos; if (SetFilePointerEx(pFile->hFileWrite, liFilePos, NULL/*new pos pointer*/, FILE_BEGIN)) { DWORD dwBytesWritten; WriteFile(pFile->hFileWrite, &uiNewChunkID, 4, &dwBytesWritten, NULL); @@ -220,9 +278,9 @@ * data */ file_offset_t Chunk::SetPos(file_offset_t Where, stream_whence_t Whence) { - #if DEBUG + #if DEBUG_RIFF std::cout << "Chunk::SetPos(file_offset_t,stream_whence_t)" << std::endl; - #endif // DEBUG + #endif // DEBUG_RIFF switch (Whence) { case stream_curpos: ullPos += Where; @@ -252,9 +310,9 @@ * @returns number of bytes left to read */ file_offset_t Chunk::RemainingBytes() const { - #if DEBUG + #if DEBUG_RIFF std::cout << "Chunk::Remainingbytes()=" << ullCurrentChunkSize - ullPos << std::endl; - #endif // DEBUG + #endif // DEBUG_RIFF return (ullCurrentChunkSize > ullPos) ? ullCurrentChunkSize - ullPos : 0; } @@ -283,9 +341,9 @@ * possible without SetPos() */ stream_state_t Chunk::GetState() const { - #if DEBUG + #if DEBUG_RIFF std::cout << "Chunk::GetState()" << std::endl; - #endif // DEBUG + #endif // DEBUG_RIFF #if POSIX if (pFile->hFileRead == 0) return stream_closed; #elif defined (WIN32) @@ -311,12 +369,12 @@ * @param WordCount number of data words to read * @param WordSize size of each data word to read * @returns number of successfully read data words or 0 if end - * of file reached or error occured + * of file reached or error occurred */ file_offset_t Chunk::Read(void* pData, file_offset_t WordCount, file_offset_t WordSize) { - #if DEBUG + #if DEBUG_RIFF std::cout << "Chunk::Read(void*,file_offset_t,file_offset_t)" << std::endl; - #endif // DEBUG + #endif // DEBUG_RIFF //if (ulStartPos == 0) return 0; // is only 0 if this is a new chunk, so nothing to read (yet) if (ullPos >= ullCurrentChunkSize) return 0; if (ullPos + WordCount * WordSize >= ullCurrentChunkSize) WordCount = (ullCurrentChunkSize - ullPos) / WordSize; @@ -324,14 +382,15 @@ if (lseek(pFile->hFileRead, ullStartPos + ullPos, SEEK_SET) < 0) return 0; ssize_t readWords = read(pFile->hFileRead, pData, WordCount * WordSize); if (readWords < 1) { - #if DEBUG + #if DEBUG_RIFF std::cerr << "POSIX read() failed: " << strerror(errno) << std::endl << std::flush; - #endif // DEBUG + #endif // DEBUG_RIFF return 0; } readWords /= WordSize; #elif defined(WIN32) - const LARGE_INTEGER liFilePos = { .QuadPart = ullStartPos + ullPos }; + LARGE_INTEGER liFilePos; + liFilePos.QuadPart = ullStartPos + ullPos; if (!SetFilePointerEx(pFile->hFileRead, liFilePos, NULL/*new pos pointer*/, FILE_BEGIN)) return 0; DWORD readWords; @@ -379,7 +438,7 @@ * @param WordSize size of each data word to write * @returns number of successfully written data words * @throws RIFF::Exception if write operation would exceed current - * chunk size or any IO error occured + * chunk size or any IO error occurred * @see Resize() */ file_offset_t Chunk::Write(void* pData, file_offset_t WordCount, file_offset_t WordSize) { @@ -416,7 +475,8 @@ if (writtenWords < 1) throw Exception("POSIX IO Error while trying to write chunk data"); writtenWords /= WordSize; #elif defined(WIN32) - const LARGE_INTEGER liFilePos = { .QuadPart = ullStartPos + ullPos }; + LARGE_INTEGER liFilePos; + liFilePos.QuadPart = ullStartPos + ullPos; if (!SetFilePointerEx(pFile->hFileWrite, liFilePos, NULL/*new pos pointer*/, FILE_BEGIN)) { throw Exception("Could not seek to position " + ToString(ullPos) + " in chunk (" + ToString(ullStartPos + ullPos) + " in file)"); @@ -451,13 +511,13 @@ * @param pData destination buffer * @param WordCount number of 8 Bit signed integers to read * @returns number of read integers - * @throws RIFF::Exception if an error occured or less than + * @throws RIFF::Exception if an error occurred or less than * \a WordCount integers could be read! */ file_offset_t Chunk::ReadInt8(int8_t* pData, file_offset_t WordCount) { - #if DEBUG + #if DEBUG_RIFF std::cout << "Chunk::ReadInt8(int8_t*,file_offset_t)" << std::endl; - #endif // DEBUG + #endif // DEBUG_RIFF return ReadSceptical(pData, WordCount, 1); } @@ -472,7 +532,7 @@ * @param pData source buffer (containing the data) * @param WordCount number of 8 Bit signed integers to write * @returns number of written integers - * @throws RIFF::Exception if an IO error occured + * @throws RIFF::Exception if an IO error occurred * @see Resize() */ file_offset_t Chunk::WriteInt8(int8_t* pData, file_offset_t WordCount) { @@ -488,13 +548,13 @@ * @param pData destination buffer * @param WordCount number of 8 Bit unsigned integers to read * @returns number of read integers - * @throws RIFF::Exception if an error occured or less than + * @throws RIFF::Exception if an error occurred or less than * \a WordCount integers could be read! */ file_offset_t Chunk::ReadUint8(uint8_t* pData, file_offset_t WordCount) { - #if DEBUG + #if DEBUG_RIFF std::cout << "Chunk::ReadUint8(uint8_t*,file_offset_t)" << std::endl; - #endif // DEBUG + #endif // DEBUG_RIFF return ReadSceptical(pData, WordCount, 1); } @@ -509,7 +569,7 @@ * @param pData source buffer (containing the data) * @param WordCount number of 8 Bit unsigned integers to write * @returns number of written integers - * @throws RIFF::Exception if an IO error occured + * @throws RIFF::Exception if an IO error occurred * @see Resize() */ file_offset_t Chunk::WriteUint8(uint8_t* pData, file_offset_t WordCount) { @@ -525,13 +585,13 @@ * @param pData destination buffer * @param WordCount number of 16 Bit signed integers to read * @returns number of read integers - * @throws RIFF::Exception if an error occured or less than + * @throws RIFF::Exception if an error occurred or less than * \a WordCount integers could be read! */ file_offset_t Chunk::ReadInt16(int16_t* pData, file_offset_t WordCount) { - #if DEBUG + #if DEBUG_RIFF std::cout << "Chunk::ReadInt16(int16_t*,file_offset_t)" << std::endl; - #endif // DEBUG + #endif // DEBUG_RIFF return ReadSceptical(pData, WordCount, 2); } @@ -546,7 +606,7 @@ * @param pData source buffer (containing the data) * @param WordCount number of 16 Bit signed integers to write * @returns number of written integers - * @throws RIFF::Exception if an IO error occured + * @throws RIFF::Exception if an IO error occurred * @see Resize() */ file_offset_t Chunk::WriteInt16(int16_t* pData, file_offset_t WordCount) { @@ -562,13 +622,13 @@ * @param pData destination buffer * @param WordCount number of 8 Bit unsigned integers to read * @returns number of read integers - * @throws RIFF::Exception if an error occured or less than + * @throws RIFF::Exception if an error occurred or less than * \a WordCount integers could be read! */ file_offset_t Chunk::ReadUint16(uint16_t* pData, file_offset_t WordCount) { - #if DEBUG + #if DEBUG_RIFF std::cout << "Chunk::ReadUint16(uint16_t*,file_offset_t)" << std::endl; - #endif // DEBUG + #endif // DEBUG_RIFF return ReadSceptical(pData, WordCount, 2); } @@ -583,7 +643,7 @@ * @param pData source buffer (containing the data) * @param WordCount number of 16 Bit unsigned integers to write * @returns number of written integers - * @throws RIFF::Exception if an IO error occured + * @throws RIFF::Exception if an IO error occurred * @see Resize() */ file_offset_t Chunk::WriteUint16(uint16_t* pData, file_offset_t WordCount) { @@ -599,13 +659,13 @@ * @param pData destination buffer * @param WordCount number of 32 Bit signed integers to read * @returns number of read integers - * @throws RIFF::Exception if an error occured or less than + * @throws RIFF::Exception if an error occurred or less than * \a WordCount integers could be read! */ file_offset_t Chunk::ReadInt32(int32_t* pData, file_offset_t WordCount) { - #if DEBUG + #if DEBUG_RIFF std::cout << "Chunk::ReadInt32(int32_t*,file_offset_t)" << std::endl; - #endif // DEBUG + #endif // DEBUG_RIFF return ReadSceptical(pData, WordCount, 4); } @@ -620,7 +680,7 @@ * @param pData source buffer (containing the data) * @param WordCount number of 32 Bit signed integers to write * @returns number of written integers - * @throws RIFF::Exception if an IO error occured + * @throws RIFF::Exception if an IO error occurred * @see Resize() */ file_offset_t Chunk::WriteInt32(int32_t* pData, file_offset_t WordCount) { @@ -636,13 +696,13 @@ * @param pData destination buffer * @param WordCount number of 32 Bit unsigned integers to read * @returns number of read integers - * @throws RIFF::Exception if an error occured or less than + * @throws RIFF::Exception if an error occurred or less than * \a WordCount integers could be read! */ file_offset_t Chunk::ReadUint32(uint32_t* pData, file_offset_t WordCount) { - #if DEBUG + #if DEBUG_RIFF std::cout << "Chunk::ReadUint32(uint32_t*,file_offset_t)" << std::endl; - #endif // DEBUG + #endif // DEBUG_RIFF return ReadSceptical(pData, WordCount, 4); } @@ -653,7 +713,7 @@ * * @param s destination string * @param size number of characters to read - * @throws RIFF::Exception if an error occured or less than + * @throws RIFF::Exception if an error occurred or less than * \a size characters could be read! */ void Chunk::ReadString(String& s, int size) { @@ -674,7 +734,7 @@ * @param pData source buffer (containing the data) * @param WordCount number of 32 Bit unsigned integers to write * @returns number of written integers - * @throws RIFF::Exception if an IO error occured + * @throws RIFF::Exception if an IO error occurred * @see Resize() */ file_offset_t Chunk::WriteUint32(uint32_t* pData, file_offset_t WordCount) { @@ -686,12 +746,12 @@ * the chunk. * * @returns read integer word - * @throws RIFF::Exception if an error occured + * @throws RIFF::Exception if an error occurred */ int8_t Chunk::ReadInt8() { - #if DEBUG + #if DEBUG_RIFF std::cout << "Chunk::ReadInt8()" << std::endl; - #endif // DEBUG + #endif // DEBUG_RIFF int8_t word; ReadSceptical(&word,1,1); return word; @@ -702,12 +762,12 @@ * within the chunk. * * @returns read integer word - * @throws RIFF::Exception if an error occured + * @throws RIFF::Exception if an error occurred */ uint8_t Chunk::ReadUint8() { - #if DEBUG + #if DEBUG_RIFF std::cout << "Chunk::ReadUint8()" << std::endl; - #endif // DEBUG + #endif // DEBUG_RIFF uint8_t word; ReadSceptical(&word,1,1); return word; @@ -719,12 +779,12 @@ * needed. * * @returns read integer word - * @throws RIFF::Exception if an error occured + * @throws RIFF::Exception if an error occurred */ int16_t Chunk::ReadInt16() { - #if DEBUG + #if DEBUG_RIFF std::cout << "Chunk::ReadInt16()" << std::endl; - #endif // DEBUG + #endif // DEBUG_RIFF int16_t word; ReadSceptical(&word,1,2); return word; @@ -736,12 +796,12 @@ * needed. * * @returns read integer word - * @throws RIFF::Exception if an error occured + * @throws RIFF::Exception if an error occurred */ uint16_t Chunk::ReadUint16() { - #if DEBUG + #if DEBUG_RIFF std::cout << "Chunk::ReadUint16()" << std::endl; - #endif // DEBUG + #endif // DEBUG_RIFF uint16_t word; ReadSceptical(&word,1,2); return word; @@ -753,12 +813,12 @@ * needed. * * @returns read integer word - * @throws RIFF::Exception if an error occured + * @throws RIFF::Exception if an error occurred */ int32_t Chunk::ReadInt32() { - #if DEBUG + #if DEBUG_RIFF std::cout << "Chunk::ReadInt32()" << std::endl; - #endif // DEBUG + #endif // DEBUG_RIFF int32_t word; ReadSceptical(&word,1,4); return word; @@ -770,12 +830,12 @@ * needed. * * @returns read integer word - * @throws RIFF::Exception if an error occured + * @throws RIFF::Exception if an error occurred */ uint32_t Chunk::ReadUint32() { - #if DEBUG + #if DEBUG_RIFF std::cout << "Chunk::ReadUint32()" << std::endl; - #endif // DEBUG + #endif // DEBUG_RIFF uint32_t word; ReadSceptical(&word,1,4); return word; @@ -807,7 +867,8 @@ #if POSIX if (lseek(pFile->hFileRead, ullStartPos, SEEK_SET) == -1) return NULL; #elif defined(WIN32) - const LARGE_INTEGER liFilePos = { .QuadPart = ullStartPos }; + LARGE_INTEGER liFilePos; + liFilePos.QuadPart = ullStartPos; if (!SetFilePointerEx(pFile->hFileRead, liFilePos, NULL/*new pos pointer*/, FILE_BEGIN)) return NULL; #else if (fseeko(pFile->hFileRead, ullStartPos, SEEK_SET)) return NULL; @@ -869,7 +930,7 @@ * boundary! * * @param NewSize - new chunk body size in bytes (must be greater than zero) - * @throws RIFF::Exception if \a NewSize is less than 1 or Unrealistic large + * @throws RIFF::Exception if \a NewSize is less than 1 or unrealistic large * @see File::Save() */ void Chunk::Resize(file_offset_t NewSize) { @@ -912,7 +973,8 @@ throw Exception("Writing Chunk data (from RAM) failed"); } #elif defined(WIN32) - const LARGE_INTEGER liFilePos = { .QuadPart = ullWritePos }; + LARGE_INTEGER liFilePos; + liFilePos.QuadPart = ullWritePos; SetFilePointerEx(pFile->hFileWrite, liFilePos, NULL/*new pos pointer*/, FILE_BEGIN); DWORD dwBytesWritten; WriteFile(pFile->hFileWrite, pChunkData, ullNewChunkSize, &dwBytesWritten, NULL); //FIXME: won't save chunks larger than 2GB ! @@ -935,14 +997,15 @@ int iBytesMoved = 1; #endif for (file_offset_t ullOffset = 0; ullToMove > 0 && iBytesMoved > 0; ullOffset += iBytesMoved, ullToMove -= iBytesMoved) { - iBytesMoved = (ullToMove < 4096) ? ullToMove : 4096; + iBytesMoved = (ullToMove < 4096) ? int(ullToMove) : 4096; #if POSIX lseek(pFile->hFileRead, ullStartPos + ullCurrentDataOffset + ullOffset, SEEK_SET); - iBytesMoved = read(pFile->hFileRead, pCopyBuffer, iBytesMoved); + iBytesMoved = (int) read(pFile->hFileRead, pCopyBuffer, (size_t) iBytesMoved); lseek(pFile->hFileWrite, ullWritePos + ullOffset, SEEK_SET); - iBytesMoved = write(pFile->hFileWrite, pCopyBuffer, iBytesMoved); + iBytesMoved = (int) write(pFile->hFileWrite, pCopyBuffer, (size_t) iBytesMoved); #elif defined(WIN32) - LARGE_INTEGER liFilePos = { .QuadPart = ullStartPos + ullCurrentDataOffset + ullOffset }; + LARGE_INTEGER liFilePos; + liFilePos.QuadPart = ullStartPos + ullCurrentDataOffset + ullOffset; SetFilePointerEx(pFile->hFileRead, liFilePos, NULL/*new pos pointer*/, FILE_BEGIN); ReadFile(pFile->hFileRead, pCopyBuffer, iBytesMoved, &iBytesMoved, NULL); liFilePos.QuadPart = ullWritePos + ullOffset; @@ -976,7 +1039,8 @@ lseek(pFile->hFileWrite, ullStartPos + ullNewChunkSize, SEEK_SET); write(pFile->hFileWrite, &cPadByte, 1); #elif defined(WIN32) - const LARGE_INTEGER liFilePos = { .QuadPart = ullStartPos + ullNewChunkSize }; + LARGE_INTEGER liFilePos; + liFilePos.QuadPart = ullStartPos + ullNewChunkSize; SetFilePointerEx(pFile->hFileWrite, liFilePos, NULL/*new pos pointer*/, FILE_BEGIN); DWORD dwBytesWritten; WriteFile(pFile->hFileWrite, &cPadByte, 1, &dwBytesWritten, NULL); @@ -1000,18 +1064,18 @@ // * List::List(File* pFile) : Chunk(pFile) { - #if DEBUG + #if DEBUG_RIFF std::cout << "List::List(File* pFile)" << std::endl; - #endif // DEBUG + #endif // DEBUG_RIFF pSubChunks = NULL; pSubChunksMap = NULL; } List::List(File* pFile, file_offset_t StartPos, List* Parent) : Chunk(pFile, StartPos, Parent) { - #if DEBUG + #if DEBUG_RIFF std::cout << "List::List(File*,file_offset_t,List*)" << std::endl; - #endif // DEBUG + #endif // DEBUG_RIFF pSubChunks = NULL; pSubChunksMap = NULL; ReadHeader(StartPos); @@ -1026,9 +1090,9 @@ } List::~List() { - #if DEBUG + #if DEBUG_RIFF std::cout << "List::~List()" << std::endl; - #endif // DEBUG + #endif // DEBUG_RIFF DeleteChunkList(); } @@ -1061,9 +1125,9 @@ * that ID */ Chunk* List::GetSubChunk(uint32_t ChunkID) { - #if DEBUG + #if DEBUG_RIFF std::cout << "List::GetSubChunk(uint32_t)" << std::endl; - #endif // DEBUG + #endif // DEBUG_RIFF if (!pSubChunksMap) LoadSubChunks(); return (*pSubChunksMap)[ChunkID]; } @@ -1071,7 +1135,7 @@ /** * Returns sublist chunk with list type \a ListType within this * chunk list. Use this method if you expect only one sublist chunk of - * that type in the list. It there are more than one, it's undetermined + * that type in the list. If there are more than one, it's undetermined * which one of them will be returned! If there are no sublists with * that desired list type, NULL will be returned. * @@ -1080,9 +1144,9 @@ * that type */ List* List::GetSubList(uint32_t ListType) { - #if DEBUG + #if DEBUG_RIFF std::cout << "List::GetSubList(uint32_t)" << std::endl; - #endif // DEBUG + #endif // DEBUG_RIFF if (!pSubChunks) LoadSubChunks(); ChunkList::iterator iter = pSubChunks->begin(); ChunkList::iterator end = pSubChunks->end(); @@ -1097,7 +1161,8 @@ } /** - * Returns the first subchunk within the list. You have to call this + * Returns the first subchunk within the list (which may be an ordinary + * chunk as well as a list chunk). You have to call this * method before you can call GetNextSubChunk(). Recall it when you want * to start from the beginning of the list again. * @@ -1105,25 +1170,26 @@ * otherwise */ Chunk* List::GetFirstSubChunk() { - #if DEBUG + #if DEBUG_RIFF std::cout << "List::GetFirstSubChunk()" << std::endl; - #endif // DEBUG + #endif // DEBUG_RIFF if (!pSubChunks) LoadSubChunks(); ChunksIterator = pSubChunks->begin(); return (ChunksIterator != pSubChunks->end()) ? *ChunksIterator : NULL; } /** - * Returns the next subchunk within the list. You have to call + * Returns the next subchunk within the list (which may be an ordinary + * chunk as well as a list chunk). You have to call * GetFirstSubChunk() before you can use this method! * * @returns pointer to the next subchunk within the list or NULL if * end of list is reached */ Chunk* List::GetNextSubChunk() { - #if DEBUG + #if DEBUG_RIFF std::cout << "List::GetNextSubChunk()" << std::endl; - #endif // DEBUG + #endif // DEBUG_RIFF if (!pSubChunks) return NULL; ChunksIterator++; return (ChunksIterator != pSubChunks->end()) ? *ChunksIterator : NULL; @@ -1139,9 +1205,9 @@ * otherwise */ List* List::GetFirstSubList() { - #if DEBUG + #if DEBUG_RIFF std::cout << "List::GetFirstSubList()" << std::endl; - #endif // DEBUG + #endif // DEBUG_RIFF if (!pSubChunks) LoadSubChunks(); ListIterator = pSubChunks->begin(); ChunkList::iterator end = pSubChunks->end(); @@ -1161,9 +1227,9 @@ * end of list is reached */ List* List::GetNextSubList() { - #if DEBUG + #if DEBUG_RIFF std::cout << "List::GetNextSubList()" << std::endl; - #endif // DEBUG + #endif // DEBUG_RIFF if (!pSubChunks) return NULL; if (ListIterator == pSubChunks->end()) return NULL; ListIterator++; @@ -1176,9 +1242,9 @@ } /** - * Returns number of subchunks within the list. + * Returns number of subchunks within the list (including list chunks). */ - unsigned int List::CountSubChunks() { + size_t List::CountSubChunks() { if (!pSubChunks) LoadSubChunks(); return pSubChunks->size(); } @@ -1187,8 +1253,8 @@ * Returns number of subchunks within the list with chunk ID * \a ChunkId. */ - unsigned int List::CountSubChunks(uint32_t ChunkID) { - unsigned int result = 0; + size_t List::CountSubChunks(uint32_t ChunkID) { + size_t result = 0; if (!pSubChunks) LoadSubChunks(); ChunkList::iterator iter = pSubChunks->begin(); ChunkList::iterator end = pSubChunks->end(); @@ -1204,7 +1270,7 @@ /** * Returns number of sublists within the list. */ - unsigned int List::CountSubLists() { + size_t List::CountSubLists() { return CountSubChunks(CHUNK_ID_LIST); } @@ -1212,8 +1278,8 @@ * Returns number of sublists within the list with list type * \a ListType */ - unsigned int List::CountSubLists(uint32_t ListType) { - unsigned int result = 0; + size_t List::CountSubLists(uint32_t ListType) { + size_t result = 0; if (!pSubChunks) LoadSubChunks(); ChunkList::iterator iter = pSubChunks->begin(); ChunkList::iterator end = pSubChunks->end(); @@ -1365,9 +1431,9 @@ } void List::ReadHeader(file_offset_t filePos) { - #if DEBUG + #if DEBUG_RIFF std::cout << "List::Readheader(file_offset_t) "; - #endif // DEBUG + #endif // DEBUG_RIFF Chunk::ReadHeader(filePos); if (ullCurrentChunkSize < 4) return; ullNewChunkSize = ullCurrentChunkSize -= 4; @@ -1375,7 +1441,8 @@ lseek(pFile->hFileRead, filePos + CHUNK_HEADER_SIZE(pFile->FileOffsetSize), SEEK_SET); read(pFile->hFileRead, &ListType, 4); #elif defined(WIN32) - const LARGE_INTEGER liFilePos = { .QuadPart = filePos + CHUNK_HEADER_SIZE(pFile->FileOffsetSize) }; + LARGE_INTEGER liFilePos; + liFilePos.QuadPart = filePos + CHUNK_HEADER_SIZE(pFile->FileOffsetSize); SetFilePointerEx(pFile->hFileRead, liFilePos, NULL/*new pos pointer*/, FILE_BEGIN); DWORD dwBytesRead; ReadFile(pFile->hFileRead, &ListType, 4, &dwBytesRead, NULL); @@ -1383,9 +1450,9 @@ fseeko(pFile->hFileRead, filePos + CHUNK_HEADER_SIZE(pFile->FileOffsetSize), SEEK_SET); fread(&ListType, 4, 1, pFile->hFileRead); #endif // POSIX - #if DEBUG + #if DEBUG_RIFF std::cout << "listType=" << convertToString(ListType) << std::endl; - #endif // DEBUG + #endif // DEBUG_RIFF if (!pFile->bEndianNative) { //swapBytes_32(&ListType); } @@ -1400,7 +1467,8 @@ lseek(pFile->hFileWrite, filePos + CHUNK_HEADER_SIZE(pFile->FileOffsetSize), SEEK_SET); write(pFile->hFileWrite, &ListType, 4); #elif defined(WIN32) - const LARGE_INTEGER liFilePos = { .QuadPart = filePos + CHUNK_HEADER_SIZE(pFile->FileOffsetSize) }; + LARGE_INTEGER liFilePos; + liFilePos.QuadPart = filePos + CHUNK_HEADER_SIZE(pFile->FileOffsetSize); SetFilePointerEx(pFile->hFileWrite, liFilePos, NULL/*new pos pointer*/, FILE_BEGIN); DWORD dwBytesWritten; WriteFile(pFile->hFileWrite, &ListType, 4, &dwBytesWritten, NULL); @@ -1411,9 +1479,9 @@ } void List::LoadSubChunks(progress_t* pProgress) { - #if DEBUG + #if DEBUG_RIFF std::cout << "List::LoadSubChunks()"; - #endif // DEBUG + #endif // DEBUG_RIFF if (!pSubChunks) { pSubChunks = new ChunkList(); pSubChunksMap = new ChunkMap(); @@ -1428,9 +1496,9 @@ Chunk* ck; uint32_t ckid; Read(&ckid, 4, 1); - #if DEBUG + #if DEBUG_RIFF std::cout << " ckid=" << convertToString(ckid) << std::endl; - #endif // DEBUG + #endif // DEBUG_RIFF if (ckid == CHUNK_ID_LIST) { ck = new RIFF::List(pFile, ullStartPos + ullPos - 4, this); SetPos(ck->GetSize() + LIST_HEADER_SIZE(pFile->FileOffsetSize) - 4, RIFF::stream_curpos); @@ -1449,7 +1517,7 @@ } void List::LoadSubChunksRecursively(progress_t* pProgress) { - const int n = CountSubLists(); + const int n = (int) CountSubLists(); int i = 0; for (List* pList = GetFirstSubList(); pList; pList = GetNextSubList(), ++i) { // divide local progress into subprogress @@ -1485,8 +1553,8 @@ // write all subchunks (including sub list chunks) recursively if (pSubChunks) { - int i = 0; - const int n = pSubChunks->size(); + size_t i = 0; + const size_t n = pSubChunks->size(); for (ChunkList::iterator iter = pSubChunks->begin(), end = pSubChunks->end(); iter != end; ++iter, ++i) { // divide local progress into subprogress for loading current Instrument progress_t subprogress; @@ -1564,16 +1632,16 @@ * Loads an existing RIFF file with all its chunks. * * @param path - path and file name of the RIFF file to open - * @throws RIFF::Exception if error occured while trying to load the + * @throws RIFF::Exception if error occurred while trying to load the * given RIFF file */ File::File(const String& path) : List(this), Filename(path), bIsNewFile(false), Layout(layout_standard), FileOffsetPreference(offset_size_auto) { - #if DEBUG + #if DEBUG_RIFF std::cout << "File::File("< 0; ++iNotif) { iBytesMoved = (ullPos < 4096) ? ullPos : 4096; @@ -1909,7 +1979,8 @@ lseek(hFileWrite, ullPos + positiveSizeDiff, SEEK_SET); iBytesMoved = write(hFileWrite, pCopyBuffer, iBytesMoved); #elif defined(WIN32) - LARGE_INTEGER liFilePos = { .QuadPart = ullPos }; + LARGE_INTEGER liFilePos; + liFilePos.QuadPart = ullPos; SetFilePointerEx(hFileRead, liFilePos, NULL/*new pos pointer*/, FILE_BEGIN); ReadFile(hFileRead, pCopyBuffer, iBytesMoved, &iBytesMoved, NULL); liFilePos.QuadPart = ullPos + positiveSizeDiff; @@ -2053,7 +2124,8 @@ if (ftruncate(hFileWrite, ullNewSize) < 0) throw Exception("Could not resize file \"" + Filename + "\""); #elif defined(WIN32) - const LARGE_INTEGER liFilePos = { .QuadPart = ullNewSize }; + LARGE_INTEGER liFilePos; + liFilePos.QuadPart = ullNewSize; if ( !SetFilePointerEx(hFileWrite, liFilePos, NULL/*new pos pointer*/, FILE_BEGIN) || !SetEndOfFile(hFileWrite) @@ -2065,9 +2137,9 @@ } File::~File() { - #if DEBUG + #if DEBUG_RIFF std::cout << "File::~File()" << std::endl; - #endif // DEBUG + #endif // DEBUG_RIFF Cleanup(); } @@ -2237,10 +2309,32 @@ // *************** Exception *************** // * + Exception::Exception() { + } + + Exception::Exception(String format, ...) { + va_list arg; + va_start(arg, format); + Message = assemble(format, arg); + va_end(arg); + } + + Exception::Exception(String format, va_list arg) { + Message = assemble(format, arg); + } + void Exception::PrintMessage() { std::cout << "RIFF::Exception: " << Message << std::endl; } + String Exception::assemble(String format, va_list arg) { + char* buf = NULL; + vasprintf(&buf, format.c_str(), arg); + String s = buf; + free(buf); + return s; + } + // *************** functions *************** // *