2 |
* * |
* * |
3 |
* libgig - C++ cross-platform Gigasampler format file access library * |
* libgig - C++ cross-platform Gigasampler format file access library * |
4 |
* * |
* * |
5 |
* Copyright (C) 2003-2016 by Christian Schoenebeck * |
* Copyright (C) 2003-2017 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 * |
70 |
// * |
// * |
71 |
|
|
72 |
Chunk::Chunk(File* pFile) { |
Chunk::Chunk(File* pFile) { |
73 |
#if DEBUG |
#if DEBUG_RIFF |
74 |
std::cout << "Chunk::Chunk(File* pFile)" << std::endl; |
std::cout << "Chunk::Chunk(File* pFile)" << std::endl; |
75 |
#endif // DEBUG |
#endif // DEBUG_RIFF |
76 |
ullPos = 0; |
ullPos = 0; |
77 |
pParent = NULL; |
pParent = NULL; |
78 |
pChunkData = NULL; |
pChunkData = NULL; |
84 |
} |
} |
85 |
|
|
86 |
Chunk::Chunk(File* pFile, file_offset_t StartPos, List* Parent) { |
Chunk::Chunk(File* pFile, file_offset_t StartPos, List* Parent) { |
87 |
#if DEBUG |
#if DEBUG_RIFF |
88 |
std::cout << "Chunk::Chunk(File*,file_offset_t,List*),StartPos=" << StartPos << std::endl; |
std::cout << "Chunk::Chunk(File*,file_offset_t,List*),StartPos=" << StartPos << std::endl; |
89 |
#endif // DEBUG |
#endif // DEBUG_RIFF |
90 |
this->pFile = pFile; |
this->pFile = pFile; |
91 |
ullStartPos = StartPos + CHUNK_HEADER_SIZE(pFile->FileOffsetSize); |
ullStartPos = StartPos + CHUNK_HEADER_SIZE(pFile->FileOffsetSize); |
92 |
pParent = Parent; |
pParent = Parent; |
115 |
} |
} |
116 |
|
|
117 |
void Chunk::ReadHeader(file_offset_t filePos) { |
void Chunk::ReadHeader(file_offset_t filePos) { |
118 |
#if DEBUG |
#if DEBUG_RIFF |
119 |
std::cout << "Chunk::Readheader(" << filePos << ") "; |
std::cout << "Chunk::Readheader(" << filePos << ") "; |
120 |
#endif // DEBUG |
#endif // DEBUG_RIFF |
121 |
ChunkID = 0; |
ChunkID = 0; |
122 |
ullNewChunkSize = ullCurrentChunkSize = 0; |
ullNewChunkSize = ullCurrentChunkSize = 0; |
123 |
#if POSIX |
#if POSIX |
153 |
else |
else |
154 |
swapBytes_64(&ullCurrentChunkSize); |
swapBytes_64(&ullCurrentChunkSize); |
155 |
} |
} |
156 |
#if DEBUG |
#if DEBUG_RIFF |
157 |
std::cout << "ckID=" << convertToString(ChunkID) << " "; |
std::cout << "ckID=" << convertToString(ChunkID) << " "; |
158 |
std::cout << "ckSize=" << ullCurrentChunkSize << " "; |
std::cout << "ckSize=" << ullCurrentChunkSize << " "; |
159 |
std::cout << "bEndianNative=" << pFile->bEndianNative << std::endl; |
std::cout << "bEndianNative=" << pFile->bEndianNative << std::endl; |
160 |
#endif // DEBUG |
#endif // DEBUG_RIFF |
161 |
ullNewChunkSize = ullCurrentChunkSize; |
ullNewChunkSize = ullCurrentChunkSize; |
162 |
} |
} |
163 |
} |
} |
222 |
* data |
* data |
223 |
*/ |
*/ |
224 |
file_offset_t Chunk::SetPos(file_offset_t Where, stream_whence_t Whence) { |
file_offset_t Chunk::SetPos(file_offset_t Where, stream_whence_t Whence) { |
225 |
#if DEBUG |
#if DEBUG_RIFF |
226 |
std::cout << "Chunk::SetPos(file_offset_t,stream_whence_t)" << std::endl; |
std::cout << "Chunk::SetPos(file_offset_t,stream_whence_t)" << std::endl; |
227 |
#endif // DEBUG |
#endif // DEBUG_RIFF |
228 |
switch (Whence) { |
switch (Whence) { |
229 |
case stream_curpos: |
case stream_curpos: |
230 |
ullPos += Where; |
ullPos += Where; |
254 |
* @returns number of bytes left to read |
* @returns number of bytes left to read |
255 |
*/ |
*/ |
256 |
file_offset_t Chunk::RemainingBytes() const { |
file_offset_t Chunk::RemainingBytes() const { |
257 |
#if DEBUG |
#if DEBUG_RIFF |
258 |
std::cout << "Chunk::Remainingbytes()=" << ullCurrentChunkSize - ullPos << std::endl; |
std::cout << "Chunk::Remainingbytes()=" << ullCurrentChunkSize - ullPos << std::endl; |
259 |
#endif // DEBUG |
#endif // DEBUG_RIFF |
260 |
return (ullCurrentChunkSize > ullPos) ? ullCurrentChunkSize - ullPos : 0; |
return (ullCurrentChunkSize > ullPos) ? ullCurrentChunkSize - ullPos : 0; |
261 |
} |
} |
262 |
|
|
285 |
* possible without SetPos() |
* possible without SetPos() |
286 |
*/ |
*/ |
287 |
stream_state_t Chunk::GetState() const { |
stream_state_t Chunk::GetState() const { |
288 |
#if DEBUG |
#if DEBUG_RIFF |
289 |
std::cout << "Chunk::GetState()" << std::endl; |
std::cout << "Chunk::GetState()" << std::endl; |
290 |
#endif // DEBUG |
#endif // DEBUG_RIFF |
291 |
#if POSIX |
#if POSIX |
292 |
if (pFile->hFileRead == 0) return stream_closed; |
if (pFile->hFileRead == 0) return stream_closed; |
293 |
#elif defined (WIN32) |
#elif defined (WIN32) |
313 |
* @param WordCount number of data words to read |
* @param WordCount number of data words to read |
314 |
* @param WordSize size of each data word to read |
* @param WordSize size of each data word to read |
315 |
* @returns number of successfully read data words or 0 if end |
* @returns number of successfully read data words or 0 if end |
316 |
* of file reached or error occured |
* of file reached or error occurred |
317 |
*/ |
*/ |
318 |
file_offset_t Chunk::Read(void* pData, file_offset_t WordCount, file_offset_t WordSize) { |
file_offset_t Chunk::Read(void* pData, file_offset_t WordCount, file_offset_t WordSize) { |
319 |
#if DEBUG |
#if DEBUG_RIFF |
320 |
std::cout << "Chunk::Read(void*,file_offset_t,file_offset_t)" << std::endl; |
std::cout << "Chunk::Read(void*,file_offset_t,file_offset_t)" << std::endl; |
321 |
#endif // DEBUG |
#endif // DEBUG_RIFF |
322 |
//if (ulStartPos == 0) return 0; // is only 0 if this is a new chunk, so nothing to read (yet) |
//if (ulStartPos == 0) return 0; // is only 0 if this is a new chunk, so nothing to read (yet) |
323 |
if (ullPos >= ullCurrentChunkSize) return 0; |
if (ullPos >= ullCurrentChunkSize) return 0; |
324 |
if (ullPos + WordCount * WordSize >= ullCurrentChunkSize) WordCount = (ullCurrentChunkSize - ullPos) / WordSize; |
if (ullPos + WordCount * WordSize >= ullCurrentChunkSize) WordCount = (ullCurrentChunkSize - ullPos) / WordSize; |
326 |
if (lseek(pFile->hFileRead, ullStartPos + ullPos, SEEK_SET) < 0) return 0; |
if (lseek(pFile->hFileRead, ullStartPos + ullPos, SEEK_SET) < 0) return 0; |
327 |
ssize_t readWords = read(pFile->hFileRead, pData, WordCount * WordSize); |
ssize_t readWords = read(pFile->hFileRead, pData, WordCount * WordSize); |
328 |
if (readWords < 1) { |
if (readWords < 1) { |
329 |
#if DEBUG |
#if DEBUG_RIFF |
330 |
std::cerr << "POSIX read() failed: " << strerror(errno) << std::endl << std::flush; |
std::cerr << "POSIX read() failed: " << strerror(errno) << std::endl << std::flush; |
331 |
#endif // DEBUG |
#endif // DEBUG_RIFF |
332 |
return 0; |
return 0; |
333 |
} |
} |
334 |
readWords /= WordSize; |
readWords /= WordSize; |
382 |
* @param WordSize size of each data word to write |
* @param WordSize size of each data word to write |
383 |
* @returns number of successfully written data words |
* @returns number of successfully written data words |
384 |
* @throws RIFF::Exception if write operation would exceed current |
* @throws RIFF::Exception if write operation would exceed current |
385 |
* chunk size or any IO error occured |
* chunk size or any IO error occurred |
386 |
* @see Resize() |
* @see Resize() |
387 |
*/ |
*/ |
388 |
file_offset_t Chunk::Write(void* pData, file_offset_t WordCount, file_offset_t WordSize) { |
file_offset_t Chunk::Write(void* pData, file_offset_t WordCount, file_offset_t WordSize) { |
455 |
* @param pData destination buffer |
* @param pData destination buffer |
456 |
* @param WordCount number of 8 Bit signed integers to read |
* @param WordCount number of 8 Bit signed integers to read |
457 |
* @returns number of read integers |
* @returns number of read integers |
458 |
* @throws RIFF::Exception if an error occured or less than |
* @throws RIFF::Exception if an error occurred or less than |
459 |
* \a WordCount integers could be read! |
* \a WordCount integers could be read! |
460 |
*/ |
*/ |
461 |
file_offset_t Chunk::ReadInt8(int8_t* pData, file_offset_t WordCount) { |
file_offset_t Chunk::ReadInt8(int8_t* pData, file_offset_t WordCount) { |
462 |
#if DEBUG |
#if DEBUG_RIFF |
463 |
std::cout << "Chunk::ReadInt8(int8_t*,file_offset_t)" << std::endl; |
std::cout << "Chunk::ReadInt8(int8_t*,file_offset_t)" << std::endl; |
464 |
#endif // DEBUG |
#endif // DEBUG_RIFF |
465 |
return ReadSceptical(pData, WordCount, 1); |
return ReadSceptical(pData, WordCount, 1); |
466 |
} |
} |
467 |
|
|
476 |
* @param pData source buffer (containing the data) |
* @param pData source buffer (containing the data) |
477 |
* @param WordCount number of 8 Bit signed integers to write |
* @param WordCount number of 8 Bit signed integers to write |
478 |
* @returns number of written integers |
* @returns number of written integers |
479 |
* @throws RIFF::Exception if an IO error occured |
* @throws RIFF::Exception if an IO error occurred |
480 |
* @see Resize() |
* @see Resize() |
481 |
*/ |
*/ |
482 |
file_offset_t Chunk::WriteInt8(int8_t* pData, file_offset_t WordCount) { |
file_offset_t Chunk::WriteInt8(int8_t* pData, file_offset_t WordCount) { |
492 |
* @param pData destination buffer |
* @param pData destination buffer |
493 |
* @param WordCount number of 8 Bit unsigned integers to read |
* @param WordCount number of 8 Bit unsigned integers to read |
494 |
* @returns number of read integers |
* @returns number of read integers |
495 |
* @throws RIFF::Exception if an error occured or less than |
* @throws RIFF::Exception if an error occurred or less than |
496 |
* \a WordCount integers could be read! |
* \a WordCount integers could be read! |
497 |
*/ |
*/ |
498 |
file_offset_t Chunk::ReadUint8(uint8_t* pData, file_offset_t WordCount) { |
file_offset_t Chunk::ReadUint8(uint8_t* pData, file_offset_t WordCount) { |
499 |
#if DEBUG |
#if DEBUG_RIFF |
500 |
std::cout << "Chunk::ReadUint8(uint8_t*,file_offset_t)" << std::endl; |
std::cout << "Chunk::ReadUint8(uint8_t*,file_offset_t)" << std::endl; |
501 |
#endif // DEBUG |
#endif // DEBUG_RIFF |
502 |
return ReadSceptical(pData, WordCount, 1); |
return ReadSceptical(pData, WordCount, 1); |
503 |
} |
} |
504 |
|
|
513 |
* @param pData source buffer (containing the data) |
* @param pData source buffer (containing the data) |
514 |
* @param WordCount number of 8 Bit unsigned integers to write |
* @param WordCount number of 8 Bit unsigned integers to write |
515 |
* @returns number of written integers |
* @returns number of written integers |
516 |
* @throws RIFF::Exception if an IO error occured |
* @throws RIFF::Exception if an IO error occurred |
517 |
* @see Resize() |
* @see Resize() |
518 |
*/ |
*/ |
519 |
file_offset_t Chunk::WriteUint8(uint8_t* pData, file_offset_t WordCount) { |
file_offset_t Chunk::WriteUint8(uint8_t* pData, file_offset_t WordCount) { |
529 |
* @param pData destination buffer |
* @param pData destination buffer |
530 |
* @param WordCount number of 16 Bit signed integers to read |
* @param WordCount number of 16 Bit signed integers to read |
531 |
* @returns number of read integers |
* @returns number of read integers |
532 |
* @throws RIFF::Exception if an error occured or less than |
* @throws RIFF::Exception if an error occurred or less than |
533 |
* \a WordCount integers could be read! |
* \a WordCount integers could be read! |
534 |
*/ |
*/ |
535 |
file_offset_t Chunk::ReadInt16(int16_t* pData, file_offset_t WordCount) { |
file_offset_t Chunk::ReadInt16(int16_t* pData, file_offset_t WordCount) { |
536 |
#if DEBUG |
#if DEBUG_RIFF |
537 |
std::cout << "Chunk::ReadInt16(int16_t*,file_offset_t)" << std::endl; |
std::cout << "Chunk::ReadInt16(int16_t*,file_offset_t)" << std::endl; |
538 |
#endif // DEBUG |
#endif // DEBUG_RIFF |
539 |
return ReadSceptical(pData, WordCount, 2); |
return ReadSceptical(pData, WordCount, 2); |
540 |
} |
} |
541 |
|
|
550 |
* @param pData source buffer (containing the data) |
* @param pData source buffer (containing the data) |
551 |
* @param WordCount number of 16 Bit signed integers to write |
* @param WordCount number of 16 Bit signed integers to write |
552 |
* @returns number of written integers |
* @returns number of written integers |
553 |
* @throws RIFF::Exception if an IO error occured |
* @throws RIFF::Exception if an IO error occurred |
554 |
* @see Resize() |
* @see Resize() |
555 |
*/ |
*/ |
556 |
file_offset_t Chunk::WriteInt16(int16_t* pData, file_offset_t WordCount) { |
file_offset_t Chunk::WriteInt16(int16_t* pData, file_offset_t WordCount) { |
566 |
* @param pData destination buffer |
* @param pData destination buffer |
567 |
* @param WordCount number of 8 Bit unsigned integers to read |
* @param WordCount number of 8 Bit unsigned integers to read |
568 |
* @returns number of read integers |
* @returns number of read integers |
569 |
* @throws RIFF::Exception if an error occured or less than |
* @throws RIFF::Exception if an error occurred or less than |
570 |
* \a WordCount integers could be read! |
* \a WordCount integers could be read! |
571 |
*/ |
*/ |
572 |
file_offset_t Chunk::ReadUint16(uint16_t* pData, file_offset_t WordCount) { |
file_offset_t Chunk::ReadUint16(uint16_t* pData, file_offset_t WordCount) { |
573 |
#if DEBUG |
#if DEBUG_RIFF |
574 |
std::cout << "Chunk::ReadUint16(uint16_t*,file_offset_t)" << std::endl; |
std::cout << "Chunk::ReadUint16(uint16_t*,file_offset_t)" << std::endl; |
575 |
#endif // DEBUG |
#endif // DEBUG_RIFF |
576 |
return ReadSceptical(pData, WordCount, 2); |
return ReadSceptical(pData, WordCount, 2); |
577 |
} |
} |
578 |
|
|
587 |
* @param pData source buffer (containing the data) |
* @param pData source buffer (containing the data) |
588 |
* @param WordCount number of 16 Bit unsigned integers to write |
* @param WordCount number of 16 Bit unsigned integers to write |
589 |
* @returns number of written integers |
* @returns number of written integers |
590 |
* @throws RIFF::Exception if an IO error occured |
* @throws RIFF::Exception if an IO error occurred |
591 |
* @see Resize() |
* @see Resize() |
592 |
*/ |
*/ |
593 |
file_offset_t Chunk::WriteUint16(uint16_t* pData, file_offset_t WordCount) { |
file_offset_t Chunk::WriteUint16(uint16_t* pData, file_offset_t WordCount) { |
603 |
* @param pData destination buffer |
* @param pData destination buffer |
604 |
* @param WordCount number of 32 Bit signed integers to read |
* @param WordCount number of 32 Bit signed integers to read |
605 |
* @returns number of read integers |
* @returns number of read integers |
606 |
* @throws RIFF::Exception if an error occured or less than |
* @throws RIFF::Exception if an error occurred or less than |
607 |
* \a WordCount integers could be read! |
* \a WordCount integers could be read! |
608 |
*/ |
*/ |
609 |
file_offset_t Chunk::ReadInt32(int32_t* pData, file_offset_t WordCount) { |
file_offset_t Chunk::ReadInt32(int32_t* pData, file_offset_t WordCount) { |
610 |
#if DEBUG |
#if DEBUG_RIFF |
611 |
std::cout << "Chunk::ReadInt32(int32_t*,file_offset_t)" << std::endl; |
std::cout << "Chunk::ReadInt32(int32_t*,file_offset_t)" << std::endl; |
612 |
#endif // DEBUG |
#endif // DEBUG_RIFF |
613 |
return ReadSceptical(pData, WordCount, 4); |
return ReadSceptical(pData, WordCount, 4); |
614 |
} |
} |
615 |
|
|
624 |
* @param pData source buffer (containing the data) |
* @param pData source buffer (containing the data) |
625 |
* @param WordCount number of 32 Bit signed integers to write |
* @param WordCount number of 32 Bit signed integers to write |
626 |
* @returns number of written integers |
* @returns number of written integers |
627 |
* @throws RIFF::Exception if an IO error occured |
* @throws RIFF::Exception if an IO error occurred |
628 |
* @see Resize() |
* @see Resize() |
629 |
*/ |
*/ |
630 |
file_offset_t Chunk::WriteInt32(int32_t* pData, file_offset_t WordCount) { |
file_offset_t Chunk::WriteInt32(int32_t* pData, file_offset_t WordCount) { |
640 |
* @param pData destination buffer |
* @param pData destination buffer |
641 |
* @param WordCount number of 32 Bit unsigned integers to read |
* @param WordCount number of 32 Bit unsigned integers to read |
642 |
* @returns number of read integers |
* @returns number of read integers |
643 |
* @throws RIFF::Exception if an error occured or less than |
* @throws RIFF::Exception if an error occurred or less than |
644 |
* \a WordCount integers could be read! |
* \a WordCount integers could be read! |
645 |
*/ |
*/ |
646 |
file_offset_t Chunk::ReadUint32(uint32_t* pData, file_offset_t WordCount) { |
file_offset_t Chunk::ReadUint32(uint32_t* pData, file_offset_t WordCount) { |
647 |
#if DEBUG |
#if DEBUG_RIFF |
648 |
std::cout << "Chunk::ReadUint32(uint32_t*,file_offset_t)" << std::endl; |
std::cout << "Chunk::ReadUint32(uint32_t*,file_offset_t)" << std::endl; |
649 |
#endif // DEBUG |
#endif // DEBUG_RIFF |
650 |
return ReadSceptical(pData, WordCount, 4); |
return ReadSceptical(pData, WordCount, 4); |
651 |
} |
} |
652 |
|
|
657 |
* |
* |
658 |
* @param s destination string |
* @param s destination string |
659 |
* @param size number of characters to read |
* @param size number of characters to read |
660 |
* @throws RIFF::Exception if an error occured or less than |
* @throws RIFF::Exception if an error occurred or less than |
661 |
* \a size characters could be read! |
* \a size characters could be read! |
662 |
*/ |
*/ |
663 |
void Chunk::ReadString(String& s, int size) { |
void Chunk::ReadString(String& s, int size) { |
678 |
* @param pData source buffer (containing the data) |
* @param pData source buffer (containing the data) |
679 |
* @param WordCount number of 32 Bit unsigned integers to write |
* @param WordCount number of 32 Bit unsigned integers to write |
680 |
* @returns number of written integers |
* @returns number of written integers |
681 |
* @throws RIFF::Exception if an IO error occured |
* @throws RIFF::Exception if an IO error occurred |
682 |
* @see Resize() |
* @see Resize() |
683 |
*/ |
*/ |
684 |
file_offset_t Chunk::WriteUint32(uint32_t* pData, file_offset_t WordCount) { |
file_offset_t Chunk::WriteUint32(uint32_t* pData, file_offset_t WordCount) { |
690 |
* the chunk. |
* the chunk. |
691 |
* |
* |
692 |
* @returns read integer word |
* @returns read integer word |
693 |
* @throws RIFF::Exception if an error occured |
* @throws RIFF::Exception if an error occurred |
694 |
*/ |
*/ |
695 |
int8_t Chunk::ReadInt8() { |
int8_t Chunk::ReadInt8() { |
696 |
#if DEBUG |
#if DEBUG_RIFF |
697 |
std::cout << "Chunk::ReadInt8()" << std::endl; |
std::cout << "Chunk::ReadInt8()" << std::endl; |
698 |
#endif // DEBUG |
#endif // DEBUG_RIFF |
699 |
int8_t word; |
int8_t word; |
700 |
ReadSceptical(&word,1,1); |
ReadSceptical(&word,1,1); |
701 |
return word; |
return word; |
706 |
* within the chunk. |
* within the chunk. |
707 |
* |
* |
708 |
* @returns read integer word |
* @returns read integer word |
709 |
* @throws RIFF::Exception if an error occured |
* @throws RIFF::Exception if an error occurred |
710 |
*/ |
*/ |
711 |
uint8_t Chunk::ReadUint8() { |
uint8_t Chunk::ReadUint8() { |
712 |
#if DEBUG |
#if DEBUG_RIFF |
713 |
std::cout << "Chunk::ReadUint8()" << std::endl; |
std::cout << "Chunk::ReadUint8()" << std::endl; |
714 |
#endif // DEBUG |
#endif // DEBUG_RIFF |
715 |
uint8_t word; |
uint8_t word; |
716 |
ReadSceptical(&word,1,1); |
ReadSceptical(&word,1,1); |
717 |
return word; |
return word; |
723 |
* needed. |
* needed. |
724 |
* |
* |
725 |
* @returns read integer word |
* @returns read integer word |
726 |
* @throws RIFF::Exception if an error occured |
* @throws RIFF::Exception if an error occurred |
727 |
*/ |
*/ |
728 |
int16_t Chunk::ReadInt16() { |
int16_t Chunk::ReadInt16() { |
729 |
#if DEBUG |
#if DEBUG_RIFF |
730 |
std::cout << "Chunk::ReadInt16()" << std::endl; |
std::cout << "Chunk::ReadInt16()" << std::endl; |
731 |
#endif // DEBUG |
#endif // DEBUG_RIFF |
732 |
int16_t word; |
int16_t word; |
733 |
ReadSceptical(&word,1,2); |
ReadSceptical(&word,1,2); |
734 |
return word; |
return word; |
740 |
* needed. |
* needed. |
741 |
* |
* |
742 |
* @returns read integer word |
* @returns read integer word |
743 |
* @throws RIFF::Exception if an error occured |
* @throws RIFF::Exception if an error occurred |
744 |
*/ |
*/ |
745 |
uint16_t Chunk::ReadUint16() { |
uint16_t Chunk::ReadUint16() { |
746 |
#if DEBUG |
#if DEBUG_RIFF |
747 |
std::cout << "Chunk::ReadUint16()" << std::endl; |
std::cout << "Chunk::ReadUint16()" << std::endl; |
748 |
#endif // DEBUG |
#endif // DEBUG_RIFF |
749 |
uint16_t word; |
uint16_t word; |
750 |
ReadSceptical(&word,1,2); |
ReadSceptical(&word,1,2); |
751 |
return word; |
return word; |
757 |
* needed. |
* needed. |
758 |
* |
* |
759 |
* @returns read integer word |
* @returns read integer word |
760 |
* @throws RIFF::Exception if an error occured |
* @throws RIFF::Exception if an error occurred |
761 |
*/ |
*/ |
762 |
int32_t Chunk::ReadInt32() { |
int32_t Chunk::ReadInt32() { |
763 |
#if DEBUG |
#if DEBUG_RIFF |
764 |
std::cout << "Chunk::ReadInt32()" << std::endl; |
std::cout << "Chunk::ReadInt32()" << std::endl; |
765 |
#endif // DEBUG |
#endif // DEBUG_RIFF |
766 |
int32_t word; |
int32_t word; |
767 |
ReadSceptical(&word,1,4); |
ReadSceptical(&word,1,4); |
768 |
return word; |
return word; |
774 |
* needed. |
* needed. |
775 |
* |
* |
776 |
* @returns read integer word |
* @returns read integer word |
777 |
* @throws RIFF::Exception if an error occured |
* @throws RIFF::Exception if an error occurred |
778 |
*/ |
*/ |
779 |
uint32_t Chunk::ReadUint32() { |
uint32_t Chunk::ReadUint32() { |
780 |
#if DEBUG |
#if DEBUG_RIFF |
781 |
std::cout << "Chunk::ReadUint32()" << std::endl; |
std::cout << "Chunk::ReadUint32()" << std::endl; |
782 |
#endif // DEBUG |
#endif // DEBUG_RIFF |
783 |
uint32_t word; |
uint32_t word; |
784 |
ReadSceptical(&word,1,4); |
ReadSceptical(&word,1,4); |
785 |
return word; |
return word; |
874 |
* boundary! |
* boundary! |
875 |
* |
* |
876 |
* @param NewSize - new chunk body size in bytes (must be greater than zero) |
* @param NewSize - new chunk body size in bytes (must be greater than zero) |
877 |
* @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 |
878 |
* @see File::Save() |
* @see File::Save() |
879 |
*/ |
*/ |
880 |
void Chunk::Resize(file_offset_t NewSize) { |
void Chunk::Resize(file_offset_t NewSize) { |
941 |
int iBytesMoved = 1; |
int iBytesMoved = 1; |
942 |
#endif |
#endif |
943 |
for (file_offset_t ullOffset = 0; ullToMove > 0 && iBytesMoved > 0; ullOffset += iBytesMoved, ullToMove -= iBytesMoved) { |
for (file_offset_t ullOffset = 0; ullToMove > 0 && iBytesMoved > 0; ullOffset += iBytesMoved, ullToMove -= iBytesMoved) { |
944 |
iBytesMoved = (ullToMove < 4096) ? ullToMove : 4096; |
iBytesMoved = (ullToMove < 4096) ? int(ullToMove) : 4096; |
945 |
#if POSIX |
#if POSIX |
946 |
lseek(pFile->hFileRead, ullStartPos + ullCurrentDataOffset + ullOffset, SEEK_SET); |
lseek(pFile->hFileRead, ullStartPos + ullCurrentDataOffset + ullOffset, SEEK_SET); |
947 |
iBytesMoved = read(pFile->hFileRead, pCopyBuffer, iBytesMoved); |
iBytesMoved = (int) read(pFile->hFileRead, pCopyBuffer, (size_t) iBytesMoved); |
948 |
lseek(pFile->hFileWrite, ullWritePos + ullOffset, SEEK_SET); |
lseek(pFile->hFileWrite, ullWritePos + ullOffset, SEEK_SET); |
949 |
iBytesMoved = write(pFile->hFileWrite, pCopyBuffer, iBytesMoved); |
iBytesMoved = (int) write(pFile->hFileWrite, pCopyBuffer, (size_t) iBytesMoved); |
950 |
#elif defined(WIN32) |
#elif defined(WIN32) |
951 |
LARGE_INTEGER liFilePos; |
LARGE_INTEGER liFilePos; |
952 |
liFilePos.QuadPart = ullStartPos + ullCurrentDataOffset + ullOffset; |
liFilePos.QuadPart = ullStartPos + ullCurrentDataOffset + ullOffset; |
1008 |
// * |
// * |
1009 |
|
|
1010 |
List::List(File* pFile) : Chunk(pFile) { |
List::List(File* pFile) : Chunk(pFile) { |
1011 |
#if DEBUG |
#if DEBUG_RIFF |
1012 |
std::cout << "List::List(File* pFile)" << std::endl; |
std::cout << "List::List(File* pFile)" << std::endl; |
1013 |
#endif // DEBUG |
#endif // DEBUG_RIFF |
1014 |
pSubChunks = NULL; |
pSubChunks = NULL; |
1015 |
pSubChunksMap = NULL; |
pSubChunksMap = NULL; |
1016 |
} |
} |
1017 |
|
|
1018 |
List::List(File* pFile, file_offset_t StartPos, List* Parent) |
List::List(File* pFile, file_offset_t StartPos, List* Parent) |
1019 |
: Chunk(pFile, StartPos, Parent) { |
: Chunk(pFile, StartPos, Parent) { |
1020 |
#if DEBUG |
#if DEBUG_RIFF |
1021 |
std::cout << "List::List(File*,file_offset_t,List*)" << std::endl; |
std::cout << "List::List(File*,file_offset_t,List*)" << std::endl; |
1022 |
#endif // DEBUG |
#endif // DEBUG_RIFF |
1023 |
pSubChunks = NULL; |
pSubChunks = NULL; |
1024 |
pSubChunksMap = NULL; |
pSubChunksMap = NULL; |
1025 |
ReadHeader(StartPos); |
ReadHeader(StartPos); |
1034 |
} |
} |
1035 |
|
|
1036 |
List::~List() { |
List::~List() { |
1037 |
#if DEBUG |
#if DEBUG_RIFF |
1038 |
std::cout << "List::~List()" << std::endl; |
std::cout << "List::~List()" << std::endl; |
1039 |
#endif // DEBUG |
#endif // DEBUG_RIFF |
1040 |
DeleteChunkList(); |
DeleteChunkList(); |
1041 |
} |
} |
1042 |
|
|
1069 |
* that ID |
* that ID |
1070 |
*/ |
*/ |
1071 |
Chunk* List::GetSubChunk(uint32_t ChunkID) { |
Chunk* List::GetSubChunk(uint32_t ChunkID) { |
1072 |
#if DEBUG |
#if DEBUG_RIFF |
1073 |
std::cout << "List::GetSubChunk(uint32_t)" << std::endl; |
std::cout << "List::GetSubChunk(uint32_t)" << std::endl; |
1074 |
#endif // DEBUG |
#endif // DEBUG_RIFF |
1075 |
if (!pSubChunksMap) LoadSubChunks(); |
if (!pSubChunksMap) LoadSubChunks(); |
1076 |
return (*pSubChunksMap)[ChunkID]; |
return (*pSubChunksMap)[ChunkID]; |
1077 |
} |
} |
1079 |
/** |
/** |
1080 |
* Returns sublist chunk with list type <i>\a ListType</i> within this |
* Returns sublist chunk with list type <i>\a ListType</i> within this |
1081 |
* chunk list. Use this method if you expect only one sublist chunk of |
* chunk list. Use this method if you expect only one sublist chunk of |
1082 |
* 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 |
1083 |
* which one of them will be returned! If there are no sublists with |
* which one of them will be returned! If there are no sublists with |
1084 |
* that desired list type, NULL will be returned. |
* that desired list type, NULL will be returned. |
1085 |
* |
* |
1088 |
* that type |
* that type |
1089 |
*/ |
*/ |
1090 |
List* List::GetSubList(uint32_t ListType) { |
List* List::GetSubList(uint32_t ListType) { |
1091 |
#if DEBUG |
#if DEBUG_RIFF |
1092 |
std::cout << "List::GetSubList(uint32_t)" << std::endl; |
std::cout << "List::GetSubList(uint32_t)" << std::endl; |
1093 |
#endif // DEBUG |
#endif // DEBUG_RIFF |
1094 |
if (!pSubChunks) LoadSubChunks(); |
if (!pSubChunks) LoadSubChunks(); |
1095 |
ChunkList::iterator iter = pSubChunks->begin(); |
ChunkList::iterator iter = pSubChunks->begin(); |
1096 |
ChunkList::iterator end = pSubChunks->end(); |
ChunkList::iterator end = pSubChunks->end(); |
1105 |
} |
} |
1106 |
|
|
1107 |
/** |
/** |
1108 |
* Returns the first subchunk within the list. You have to call this |
* Returns the first subchunk within the list (which may be an ordinary |
1109 |
|
* chunk as well as a list chunk). You have to call this |
1110 |
* method before you can call GetNextSubChunk(). Recall it when you want |
* method before you can call GetNextSubChunk(). Recall it when you want |
1111 |
* to start from the beginning of the list again. |
* to start from the beginning of the list again. |
1112 |
* |
* |
1114 |
* otherwise |
* otherwise |
1115 |
*/ |
*/ |
1116 |
Chunk* List::GetFirstSubChunk() { |
Chunk* List::GetFirstSubChunk() { |
1117 |
#if DEBUG |
#if DEBUG_RIFF |
1118 |
std::cout << "List::GetFirstSubChunk()" << std::endl; |
std::cout << "List::GetFirstSubChunk()" << std::endl; |
1119 |
#endif // DEBUG |
#endif // DEBUG_RIFF |
1120 |
if (!pSubChunks) LoadSubChunks(); |
if (!pSubChunks) LoadSubChunks(); |
1121 |
ChunksIterator = pSubChunks->begin(); |
ChunksIterator = pSubChunks->begin(); |
1122 |
return (ChunksIterator != pSubChunks->end()) ? *ChunksIterator : NULL; |
return (ChunksIterator != pSubChunks->end()) ? *ChunksIterator : NULL; |
1123 |
} |
} |
1124 |
|
|
1125 |
/** |
/** |
1126 |
* Returns the next subchunk within the list. You have to call |
* Returns the next subchunk within the list (which may be an ordinary |
1127 |
|
* chunk as well as a list chunk). You have to call |
1128 |
* GetFirstSubChunk() before you can use this method! |
* GetFirstSubChunk() before you can use this method! |
1129 |
* |
* |
1130 |
* @returns pointer to the next subchunk within the list or NULL if |
* @returns pointer to the next subchunk within the list or NULL if |
1131 |
* end of list is reached |
* end of list is reached |
1132 |
*/ |
*/ |
1133 |
Chunk* List::GetNextSubChunk() { |
Chunk* List::GetNextSubChunk() { |
1134 |
#if DEBUG |
#if DEBUG_RIFF |
1135 |
std::cout << "List::GetNextSubChunk()" << std::endl; |
std::cout << "List::GetNextSubChunk()" << std::endl; |
1136 |
#endif // DEBUG |
#endif // DEBUG_RIFF |
1137 |
if (!pSubChunks) return NULL; |
if (!pSubChunks) return NULL; |
1138 |
ChunksIterator++; |
ChunksIterator++; |
1139 |
return (ChunksIterator != pSubChunks->end()) ? *ChunksIterator : NULL; |
return (ChunksIterator != pSubChunks->end()) ? *ChunksIterator : NULL; |
1149 |
* otherwise |
* otherwise |
1150 |
*/ |
*/ |
1151 |
List* List::GetFirstSubList() { |
List* List::GetFirstSubList() { |
1152 |
#if DEBUG |
#if DEBUG_RIFF |
1153 |
std::cout << "List::GetFirstSubList()" << std::endl; |
std::cout << "List::GetFirstSubList()" << std::endl; |
1154 |
#endif // DEBUG |
#endif // DEBUG_RIFF |
1155 |
if (!pSubChunks) LoadSubChunks(); |
if (!pSubChunks) LoadSubChunks(); |
1156 |
ListIterator = pSubChunks->begin(); |
ListIterator = pSubChunks->begin(); |
1157 |
ChunkList::iterator end = pSubChunks->end(); |
ChunkList::iterator end = pSubChunks->end(); |
1171 |
* end of list is reached |
* end of list is reached |
1172 |
*/ |
*/ |
1173 |
List* List::GetNextSubList() { |
List* List::GetNextSubList() { |
1174 |
#if DEBUG |
#if DEBUG_RIFF |
1175 |
std::cout << "List::GetNextSubList()" << std::endl; |
std::cout << "List::GetNextSubList()" << std::endl; |
1176 |
#endif // DEBUG |
#endif // DEBUG_RIFF |
1177 |
if (!pSubChunks) return NULL; |
if (!pSubChunks) return NULL; |
1178 |
if (ListIterator == pSubChunks->end()) return NULL; |
if (ListIterator == pSubChunks->end()) return NULL; |
1179 |
ListIterator++; |
ListIterator++; |
1186 |
} |
} |
1187 |
|
|
1188 |
/** |
/** |
1189 |
* Returns number of subchunks within the list. |
* Returns number of subchunks within the list (including list chunks). |
1190 |
*/ |
*/ |
1191 |
unsigned int List::CountSubChunks() { |
size_t List::CountSubChunks() { |
1192 |
if (!pSubChunks) LoadSubChunks(); |
if (!pSubChunks) LoadSubChunks(); |
1193 |
return pSubChunks->size(); |
return pSubChunks->size(); |
1194 |
} |
} |
1197 |
* Returns number of subchunks within the list with chunk ID |
* Returns number of subchunks within the list with chunk ID |
1198 |
* <i>\a ChunkId</i>. |
* <i>\a ChunkId</i>. |
1199 |
*/ |
*/ |
1200 |
unsigned int List::CountSubChunks(uint32_t ChunkID) { |
size_t List::CountSubChunks(uint32_t ChunkID) { |
1201 |
unsigned int result = 0; |
size_t result = 0; |
1202 |
if (!pSubChunks) LoadSubChunks(); |
if (!pSubChunks) LoadSubChunks(); |
1203 |
ChunkList::iterator iter = pSubChunks->begin(); |
ChunkList::iterator iter = pSubChunks->begin(); |
1204 |
ChunkList::iterator end = pSubChunks->end(); |
ChunkList::iterator end = pSubChunks->end(); |
1214 |
/** |
/** |
1215 |
* Returns number of sublists within the list. |
* Returns number of sublists within the list. |
1216 |
*/ |
*/ |
1217 |
unsigned int List::CountSubLists() { |
size_t List::CountSubLists() { |
1218 |
return CountSubChunks(CHUNK_ID_LIST); |
return CountSubChunks(CHUNK_ID_LIST); |
1219 |
} |
} |
1220 |
|
|
1222 |
* Returns number of sublists within the list with list type |
* Returns number of sublists within the list with list type |
1223 |
* <i>\a ListType</i> |
* <i>\a ListType</i> |
1224 |
*/ |
*/ |
1225 |
unsigned int List::CountSubLists(uint32_t ListType) { |
size_t List::CountSubLists(uint32_t ListType) { |
1226 |
unsigned int result = 0; |
size_t result = 0; |
1227 |
if (!pSubChunks) LoadSubChunks(); |
if (!pSubChunks) LoadSubChunks(); |
1228 |
ChunkList::iterator iter = pSubChunks->begin(); |
ChunkList::iterator iter = pSubChunks->begin(); |
1229 |
ChunkList::iterator end = pSubChunks->end(); |
ChunkList::iterator end = pSubChunks->end(); |
1375 |
} |
} |
1376 |
|
|
1377 |
void List::ReadHeader(file_offset_t filePos) { |
void List::ReadHeader(file_offset_t filePos) { |
1378 |
#if DEBUG |
#if DEBUG_RIFF |
1379 |
std::cout << "List::Readheader(file_offset_t) "; |
std::cout << "List::Readheader(file_offset_t) "; |
1380 |
#endif // DEBUG |
#endif // DEBUG_RIFF |
1381 |
Chunk::ReadHeader(filePos); |
Chunk::ReadHeader(filePos); |
1382 |
if (ullCurrentChunkSize < 4) return; |
if (ullCurrentChunkSize < 4) return; |
1383 |
ullNewChunkSize = ullCurrentChunkSize -= 4; |
ullNewChunkSize = ullCurrentChunkSize -= 4; |
1394 |
fseeko(pFile->hFileRead, filePos + CHUNK_HEADER_SIZE(pFile->FileOffsetSize), SEEK_SET); |
fseeko(pFile->hFileRead, filePos + CHUNK_HEADER_SIZE(pFile->FileOffsetSize), SEEK_SET); |
1395 |
fread(&ListType, 4, 1, pFile->hFileRead); |
fread(&ListType, 4, 1, pFile->hFileRead); |
1396 |
#endif // POSIX |
#endif // POSIX |
1397 |
#if DEBUG |
#if DEBUG_RIFF |
1398 |
std::cout << "listType=" << convertToString(ListType) << std::endl; |
std::cout << "listType=" << convertToString(ListType) << std::endl; |
1399 |
#endif // DEBUG |
#endif // DEBUG_RIFF |
1400 |
if (!pFile->bEndianNative) { |
if (!pFile->bEndianNative) { |
1401 |
//swapBytes_32(&ListType); |
//swapBytes_32(&ListType); |
1402 |
} |
} |
1423 |
} |
} |
1424 |
|
|
1425 |
void List::LoadSubChunks(progress_t* pProgress) { |
void List::LoadSubChunks(progress_t* pProgress) { |
1426 |
#if DEBUG |
#if DEBUG_RIFF |
1427 |
std::cout << "List::LoadSubChunks()"; |
std::cout << "List::LoadSubChunks()"; |
1428 |
#endif // DEBUG |
#endif // DEBUG_RIFF |
1429 |
if (!pSubChunks) { |
if (!pSubChunks) { |
1430 |
pSubChunks = new ChunkList(); |
pSubChunks = new ChunkList(); |
1431 |
pSubChunksMap = new ChunkMap(); |
pSubChunksMap = new ChunkMap(); |
1440 |
Chunk* ck; |
Chunk* ck; |
1441 |
uint32_t ckid; |
uint32_t ckid; |
1442 |
Read(&ckid, 4, 1); |
Read(&ckid, 4, 1); |
1443 |
#if DEBUG |
#if DEBUG_RIFF |
1444 |
std::cout << " ckid=" << convertToString(ckid) << std::endl; |
std::cout << " ckid=" << convertToString(ckid) << std::endl; |
1445 |
#endif // DEBUG |
#endif // DEBUG_RIFF |
1446 |
if (ckid == CHUNK_ID_LIST) { |
if (ckid == CHUNK_ID_LIST) { |
1447 |
ck = new RIFF::List(pFile, ullStartPos + ullPos - 4, this); |
ck = new RIFF::List(pFile, ullStartPos + ullPos - 4, this); |
1448 |
SetPos(ck->GetSize() + LIST_HEADER_SIZE(pFile->FileOffsetSize) - 4, RIFF::stream_curpos); |
SetPos(ck->GetSize() + LIST_HEADER_SIZE(pFile->FileOffsetSize) - 4, RIFF::stream_curpos); |
1461 |
} |
} |
1462 |
|
|
1463 |
void List::LoadSubChunksRecursively(progress_t* pProgress) { |
void List::LoadSubChunksRecursively(progress_t* pProgress) { |
1464 |
const int n = CountSubLists(); |
const int n = (int) CountSubLists(); |
1465 |
int i = 0; |
int i = 0; |
1466 |
for (List* pList = GetFirstSubList(); pList; pList = GetNextSubList(), ++i) { |
for (List* pList = GetFirstSubList(); pList; pList = GetNextSubList(), ++i) { |
1467 |
// divide local progress into subprogress |
// divide local progress into subprogress |
1497 |
|
|
1498 |
// write all subchunks (including sub list chunks) recursively |
// write all subchunks (including sub list chunks) recursively |
1499 |
if (pSubChunks) { |
if (pSubChunks) { |
1500 |
int i = 0; |
size_t i = 0; |
1501 |
const int n = pSubChunks->size(); |
const size_t n = pSubChunks->size(); |
1502 |
for (ChunkList::iterator iter = pSubChunks->begin(), end = pSubChunks->end(); iter != end; ++iter, ++i) { |
for (ChunkList::iterator iter = pSubChunks->begin(), end = pSubChunks->end(); iter != end; ++iter, ++i) { |
1503 |
// divide local progress into subprogress for loading current Instrument |
// divide local progress into subprogress for loading current Instrument |
1504 |
progress_t subprogress; |
progress_t subprogress; |
1576 |
* Loads an existing RIFF file with all its chunks. |
* Loads an existing RIFF file with all its chunks. |
1577 |
* |
* |
1578 |
* @param path - path and file name of the RIFF file to open |
* @param path - path and file name of the RIFF file to open |
1579 |
* @throws RIFF::Exception if error occured while trying to load the |
* @throws RIFF::Exception if error occurred while trying to load the |
1580 |
* given RIFF file |
* given RIFF file |
1581 |
*/ |
*/ |
1582 |
File::File(const String& path) |
File::File(const String& path) |
1583 |
: List(this), Filename(path), bIsNewFile(false), Layout(layout_standard), |
: List(this), Filename(path), bIsNewFile(false), Layout(layout_standard), |
1584 |
FileOffsetPreference(offset_size_auto) |
FileOffsetPreference(offset_size_auto) |
1585 |
{ |
{ |
1586 |
#if DEBUG |
#if DEBUG_RIFF |
1587 |
std::cout << "File::File("<<path<<")" << std::endl; |
std::cout << "File::File("<<path<<")" << std::endl; |
1588 |
#endif // DEBUG |
#endif // DEBUG_RIFF |
1589 |
bEndianNative = true; |
bEndianNative = true; |
1590 |
FileOffsetSize = 4; |
FileOffsetSize = 4; |
1591 |
try { |
try { |
1623 |
* @param Endian - whether the file uses little endian or big endian layout |
* @param Endian - whether the file uses little endian or big endian layout |
1624 |
* @param layout - general file structure type |
* @param layout - general file structure type |
1625 |
* @param fileOffsetSize - (optional) preference how to deal with large files |
* @param fileOffsetSize - (optional) preference how to deal with large files |
1626 |
* @throws RIFF::Exception if error occured while trying to load the |
* @throws RIFF::Exception if error occurred while trying to load the |
1627 |
* given RIFF-alike file |
* given RIFF-alike file |
1628 |
*/ |
*/ |
1629 |
File::File(const String& path, uint32_t FileType, endian_t Endian, layout_t layout, offset_size_t fileOffsetSize) |
File::File(const String& path, uint32_t FileType, endian_t Endian, layout_t layout, offset_size_t fileOffsetSize) |
1650 |
* @param path - path and file name of the RIFF file or RIFF-alike file to |
* @param path - path and file name of the RIFF file or RIFF-alike file to |
1651 |
* be opened |
* be opened |
1652 |
* @param FileType - (optional) expected chunk ID of first chunk in file |
* @param FileType - (optional) expected chunk ID of first chunk in file |
1653 |
* @throws RIFF::Exception if error occured while trying to load the |
* @throws RIFF::Exception if error occurred while trying to load the |
1654 |
* given RIFF file or RIFF-alike file |
* given RIFF file or RIFF-alike file |
1655 |
*/ |
*/ |
1656 |
void File::__openExistingFile(const String& path, uint32_t* FileType) { |
void File::__openExistingFile(const String& path, uint32_t* FileType) { |
1854 |
* |
* |
1855 |
* @param pProgress - optional: callback function for progress notification |
* @param pProgress - optional: callback function for progress notification |
1856 |
* @throws RIFF::Exception if there is an empty chunk or empty list |
* @throws RIFF::Exception if there is an empty chunk or empty list |
1857 |
* chunk or any kind of IO error occured |
* chunk or any kind of IO error occurred |
1858 |
*/ |
*/ |
1859 |
void File::Save(progress_t* pProgress) { |
void File::Save(progress_t* pProgress) { |
1860 |
//TODO: implementation for the case where first chunk is not a global container (List chunk) is not implemented yet (i.e. Korg files) |
//TODO: implementation for the case where first chunk is not a global container (List chunk) is not implemented yet (i.e. Korg files) |
1910 |
#if defined(WIN32) |
#if defined(WIN32) |
1911 |
DWORD iBytesMoved = 1; // we have to pass it via pointer to the Windows API, thus the correct size must be ensured |
DWORD iBytesMoved = 1; // we have to pass it via pointer to the Windows API, thus the correct size must be ensured |
1912 |
#else |
#else |
1913 |
int iBytesMoved = 1; |
ssize_t iBytesMoved = 1; |
1914 |
#endif |
#endif |
1915 |
for (file_offset_t ullPos = workingFileSize, iNotif = 0; iBytesMoved > 0; ++iNotif) { |
for (file_offset_t ullPos = workingFileSize, iNotif = 0; iBytesMoved > 0; ++iNotif) { |
1916 |
iBytesMoved = (ullPos < 4096) ? ullPos : 4096; |
iBytesMoved = (ullPos < 4096) ? ullPos : 4096; |
2079 |
} |
} |
2080 |
|
|
2081 |
File::~File() { |
File::~File() { |
2082 |
#if DEBUG |
#if DEBUG_RIFF |
2083 |
std::cout << "File::~File()" << std::endl; |
std::cout << "File::~File()" << std::endl; |
2084 |
#endif // DEBUG |
#endif // DEBUG_RIFF |
2085 |
Cleanup(); |
Cleanup(); |
2086 |
} |
} |
2087 |
|
|
2251 |
// *************** Exception *************** |
// *************** Exception *************** |
2252 |
// * |
// * |
2253 |
|
|
2254 |
|
Exception::Exception() { |
2255 |
|
} |
2256 |
|
|
2257 |
|
Exception::Exception(String format, ...) { |
2258 |
|
va_list arg; |
2259 |
|
va_start(arg, format); |
2260 |
|
Message = assemble(format, arg); |
2261 |
|
va_end(arg); |
2262 |
|
} |
2263 |
|
|
2264 |
|
Exception::Exception(String format, va_list arg) { |
2265 |
|
Message = assemble(format, arg); |
2266 |
|
} |
2267 |
|
|
2268 |
void Exception::PrintMessage() { |
void Exception::PrintMessage() { |
2269 |
std::cout << "RIFF::Exception: " << Message << std::endl; |
std::cout << "RIFF::Exception: " << Message << std::endl; |
2270 |
} |
} |
2271 |
|
|
2272 |
|
String Exception::assemble(String format, va_list arg) { |
2273 |
|
char* buf = NULL; |
2274 |
|
vasprintf(&buf, format.c_str(), arg); |
2275 |
|
String s = buf; |
2276 |
|
free(buf); |
2277 |
|
return s; |
2278 |
|
} |
2279 |
|
|
2280 |
|
|
2281 |
// *************** functions *************** |
// *************** functions *************** |
2282 |
// * |
// * |