/[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 2922 by schoenebeck, Wed May 18 18:04:49 2016 UTC revision 3481 by schoenebeck, Fri Feb 22 12:12:50 2019 UTC
# Line 2  Line 2 
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-2019 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 64  namespace RIFF { Line 64  namespace RIFF {
64          __range_max = 1.0f;          __range_max = 1.0f;
65      }      }
66    
67        /**
68         * Divides this progress task into the requested amount of equal weighted
69         * sub-progress tasks and returns a vector with those subprogress tasks.
70         *
71         * @param iSubtasks - total amount sub tasks this task should be subdivided
72         * @returns subtasks
73         */
74        std::vector<progress_t> progress_t::subdivide(int iSubtasks) {
75            std::vector<progress_t> v;
76            for (int i = 0; i < iSubtasks; ++i) {
77                progress_t p;
78                __divide_progress(this, &p, iSubtasks, i);
79                v.push_back(p);
80            }
81            return v;
82        }
83    
84        /**
85         * Divides this progress task into the requested amount of sub-progress
86         * tasks, where each one of those new sub-progress tasks is created with its
87         * requested individual weight / portion, and finally returns a vector
88         * with those new subprogress tasks.
89         *
90         * The amount of subprogresses to be created is determined by this method
91         * by calling @c vSubTaskPortions.size() .
92         *
93         * Example: consider you wanted to create 3 subprogresses where the 1st
94         * subtask should be assigned 10% of the new 3 subprogresses' overall
95         * progress, the 2nd subtask should be assigned 50% of the new 3
96         * subprogresses' overall progress, and the 3rd subtask should be assigned
97         * 40%, then you might call this method like this:
98         * @code
99         * std::vector<progress_t> subprogresses = progress.subdivide({0.1, 0.5, 0.4});
100         * @endcode
101         *
102         * @param vSubTaskPortions - amount and individual weight of subtasks to be
103         *                           created
104         * @returns subtasks
105         */
106        std::vector<progress_t> progress_t::subdivide(std::vector<float> vSubTaskPortions) {
107            float fTotal = 0.f; // usually 1.0, but we sum the portions up below to be sure
108            for (int i = 0; i < vSubTaskPortions.size(); ++i)
109                fTotal += vSubTaskPortions[i];
110    
111            float fLow = 0.f, fHigh = 0.f;
112            std::vector<progress_t> v;
113            for (int i = 0; i < vSubTaskPortions.size(); ++i) {
114                fLow  = fHigh;
115                fHigh = vSubTaskPortions[i];
116                progress_t p;
117                __divide_progress(this, &p, fTotal, fLow, fHigh);
118                v.push_back(p);
119            }
120            return v;
121        }
122    
123    
124    
125  // *************** Chunk **************  // *************** Chunk **************
126  // *  // *
127    
128      Chunk::Chunk(File* pFile) {      Chunk::Chunk(File* pFile) {
129          #if DEBUG          #if DEBUG_RIFF
130          std::cout << "Chunk::Chunk(File* pFile)" << std::endl;          std::cout << "Chunk::Chunk(File* pFile)" << std::endl;
131          #endif // DEBUG          #endif // DEBUG_RIFF
132          ullPos     = 0;          ullPos     = 0;
133          pParent    = NULL;          pParent    = NULL;
134          pChunkData = NULL;          pChunkData = NULL;
# Line 84  namespace RIFF { Line 140  namespace RIFF {
140      }      }
141    
142      Chunk::Chunk(File* pFile, file_offset_t StartPos, List* Parent) {      Chunk::Chunk(File* pFile, file_offset_t StartPos, List* Parent) {
143          #if DEBUG          #if DEBUG_RIFF
144          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;
145          #endif // DEBUG          #endif // DEBUG_RIFF
146          this->pFile   = pFile;          this->pFile   = pFile;
147          ullStartPos   = StartPos + CHUNK_HEADER_SIZE(pFile->FileOffsetSize);          ullStartPos   = StartPos + CHUNK_HEADER_SIZE(pFile->FileOffsetSize);
148          pParent       = Parent;          pParent       = Parent;
# Line 115  namespace RIFF { Line 171  namespace RIFF {
171      }      }
172    
173      void Chunk::ReadHeader(file_offset_t filePos) {      void Chunk::ReadHeader(file_offset_t filePos) {
174          #if DEBUG          #if DEBUG_RIFF
175          std::cout << "Chunk::Readheader(" << filePos << ") ";          std::cout << "Chunk::Readheader(" << filePos << ") ";
176          #endif // DEBUG          #endif // DEBUG_RIFF
177          ChunkID = 0;          ChunkID = 0;
178          ullNewChunkSize = ullCurrentChunkSize = 0;          ullNewChunkSize = ullCurrentChunkSize = 0;
179          #if POSIX          #if POSIX
# Line 153  namespace RIFF { Line 209  namespace RIFF {
209                  else                  else
210                      swapBytes_64(&ullCurrentChunkSize);                      swapBytes_64(&ullCurrentChunkSize);
211              }              }
212              #if DEBUG              #if DEBUG_RIFF
213              std::cout << "ckID=" << convertToString(ChunkID) << " ";              std::cout << "ckID=" << convertToString(ChunkID) << " ";
214              std::cout << "ckSize=" << ullCurrentChunkSize << " ";              std::cout << "ckSize=" << ullCurrentChunkSize << " ";
215              std::cout << "bEndianNative=" << pFile->bEndianNative << std::endl;              std::cout << "bEndianNative=" << pFile->bEndianNative << std::endl;
216              #endif // DEBUG              #endif // DEBUG_RIFF
217              ullNewChunkSize = ullCurrentChunkSize;              ullNewChunkSize = ullCurrentChunkSize;
218          }          }
219      }      }
# Line 222  namespace RIFF { Line 278  namespace RIFF {
278       *                  data       *                  data
279       */       */
280      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) {
281          #if DEBUG          #if DEBUG_RIFF
282          std::cout << "Chunk::SetPos(file_offset_t,stream_whence_t)" << std::endl;          std::cout << "Chunk::SetPos(file_offset_t,stream_whence_t)" << std::endl;
283          #endif // DEBUG          #endif // DEBUG_RIFF
284          switch (Whence) {          switch (Whence) {
285              case stream_curpos:              case stream_curpos:
286                  ullPos += Where;                  ullPos += Where;
# Line 254  namespace RIFF { Line 310  namespace RIFF {
310       *  @returns  number of bytes left to read       *  @returns  number of bytes left to read
311       */       */
312      file_offset_t Chunk::RemainingBytes() const {      file_offset_t Chunk::RemainingBytes() const {
313          #if DEBUG          #if DEBUG_RIFF
314          std::cout << "Chunk::Remainingbytes()=" << ullCurrentChunkSize - ullPos << std::endl;          std::cout << "Chunk::Remainingbytes()=" << ullCurrentChunkSize - ullPos << std::endl;
315          #endif // DEBUG          #endif // DEBUG_RIFF
316          return (ullCurrentChunkSize > ullPos) ? ullCurrentChunkSize - ullPos : 0;          return (ullCurrentChunkSize > ullPos) ? ullCurrentChunkSize - ullPos : 0;
317      }      }
318    
# Line 285  namespace RIFF { Line 341  namespace RIFF {
341       *    possible without SetPos()       *    possible without SetPos()
342       */       */
343      stream_state_t Chunk::GetState() const {      stream_state_t Chunk::GetState() const {
344          #if DEBUG          #if DEBUG_RIFF
345          std::cout << "Chunk::GetState()" << std::endl;          std::cout << "Chunk::GetState()" << std::endl;
346          #endif // DEBUG          #endif // DEBUG_RIFF
347          #if POSIX          #if POSIX
348          if (pFile->hFileRead == 0) return stream_closed;          if (pFile->hFileRead == 0) return stream_closed;
349          #elif defined (WIN32)          #elif defined (WIN32)
# Line 313  namespace RIFF { Line 369  namespace RIFF {
369       *  @param WordCount  number of data words to read       *  @param WordCount  number of data words to read
370       *  @param WordSize   size of each data word to read       *  @param WordSize   size of each data word to read
371       *  @returns          number of successfully read data words or 0 if end       *  @returns          number of successfully read data words or 0 if end
372       *                    of file reached or error occured       *                    of file reached or error occurred
373       */       */
374      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) {
375          #if DEBUG          #if DEBUG_RIFF
376          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;
377          #endif // DEBUG          #endif // DEBUG_RIFF
378          //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)
379          if (ullPos >= ullCurrentChunkSize) return 0;          if (ullPos >= ullCurrentChunkSize) return 0;
380          if (ullPos + WordCount * WordSize >= ullCurrentChunkSize) WordCount = (ullCurrentChunkSize - ullPos) / WordSize;          if (ullPos + WordCount * WordSize >= ullCurrentChunkSize) WordCount = (ullCurrentChunkSize - ullPos) / WordSize;
# Line 326  namespace RIFF { Line 382  namespace RIFF {
382          if (lseek(pFile->hFileRead, ullStartPos + ullPos, SEEK_SET) < 0) return 0;          if (lseek(pFile->hFileRead, ullStartPos + ullPos, SEEK_SET) < 0) return 0;
383          ssize_t readWords = read(pFile->hFileRead, pData, WordCount * WordSize);          ssize_t readWords = read(pFile->hFileRead, pData, WordCount * WordSize);
384          if (readWords < 1) {          if (readWords < 1) {
385              #if DEBUG              #if DEBUG_RIFF
386              std::cerr << "POSIX read() failed: " << strerror(errno) << std::endl << std::flush;              std::cerr << "POSIX read() failed: " << strerror(errno) << std::endl << std::flush;
387              #endif // DEBUG              #endif // DEBUG_RIFF
388              return 0;              return 0;
389          }          }
390          readWords /= WordSize;          readWords /= WordSize;
# Line 382  namespace RIFF { Line 438  namespace RIFF {
438       *  @param WordSize   size of each data word to write       *  @param WordSize   size of each data word to write
439       *  @returns          number of successfully written data words       *  @returns          number of successfully written data words
440       *  @throws RIFF::Exception  if write operation would exceed current       *  @throws RIFF::Exception  if write operation would exceed current
441       *                           chunk size or any IO error occured       *                           chunk size or any IO error occurred
442       *  @see Resize()       *  @see Resize()
443       */       */
444      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) {
# Line 455  namespace RIFF { Line 511  namespace RIFF {
511       * @param pData             destination buffer       * @param pData             destination buffer
512       * @param WordCount         number of 8 Bit signed integers to read       * @param WordCount         number of 8 Bit signed integers to read
513       * @returns                 number of read integers       * @returns                 number of read integers
514       * @throws RIFF::Exception  if an error occured or less than       * @throws RIFF::Exception  if an error occurred or less than
515       *                          \a WordCount integers could be read!       *                          \a WordCount integers could be read!
516       */       */
517      file_offset_t Chunk::ReadInt8(int8_t* pData, file_offset_t WordCount) {      file_offset_t Chunk::ReadInt8(int8_t* pData, file_offset_t WordCount) {
518          #if DEBUG          #if DEBUG_RIFF
519          std::cout << "Chunk::ReadInt8(int8_t*,file_offset_t)" << std::endl;          std::cout << "Chunk::ReadInt8(int8_t*,file_offset_t)" << std::endl;
520          #endif // DEBUG          #endif // DEBUG_RIFF
521          return ReadSceptical(pData, WordCount, 1);          return ReadSceptical(pData, WordCount, 1);
522      }      }
523    
# Line 476  namespace RIFF { Line 532  namespace RIFF {
532       * @param pData             source buffer (containing the data)       * @param pData             source buffer (containing the data)
533       * @param WordCount         number of 8 Bit signed integers to write       * @param WordCount         number of 8 Bit signed integers to write
534       * @returns                 number of written integers       * @returns                 number of written integers
535       * @throws RIFF::Exception  if an IO error occured       * @throws RIFF::Exception  if an IO error occurred
536       * @see Resize()       * @see Resize()
537       */       */
538      file_offset_t Chunk::WriteInt8(int8_t* pData, file_offset_t WordCount) {      file_offset_t Chunk::WriteInt8(int8_t* pData, file_offset_t WordCount) {
# Line 492  namespace RIFF { Line 548  namespace RIFF {
548       * @param pData             destination buffer       * @param pData             destination buffer
549       * @param WordCount         number of 8 Bit unsigned integers to read       * @param WordCount         number of 8 Bit unsigned integers to read
550       * @returns                 number of read integers       * @returns                 number of read integers
551       * @throws RIFF::Exception  if an error occured or less than       * @throws RIFF::Exception  if an error occurred or less than
552       *                          \a WordCount integers could be read!       *                          \a WordCount integers could be read!
553       */       */
554      file_offset_t Chunk::ReadUint8(uint8_t* pData, file_offset_t WordCount) {      file_offset_t Chunk::ReadUint8(uint8_t* pData, file_offset_t WordCount) {
555          #if DEBUG          #if DEBUG_RIFF
556          std::cout << "Chunk::ReadUint8(uint8_t*,file_offset_t)" << std::endl;          std::cout << "Chunk::ReadUint8(uint8_t*,file_offset_t)" << std::endl;
557          #endif // DEBUG          #endif // DEBUG_RIFF
558          return ReadSceptical(pData, WordCount, 1);          return ReadSceptical(pData, WordCount, 1);
559      }      }
560    
# Line 513  namespace RIFF { Line 569  namespace RIFF {
569       * @param pData             source buffer (containing the data)       * @param pData             source buffer (containing the data)
570       * @param WordCount         number of 8 Bit unsigned integers to write       * @param WordCount         number of 8 Bit unsigned integers to write
571       * @returns                 number of written integers       * @returns                 number of written integers
572       * @throws RIFF::Exception  if an IO error occured       * @throws RIFF::Exception  if an IO error occurred
573       * @see Resize()       * @see Resize()
574       */       */
575      file_offset_t Chunk::WriteUint8(uint8_t* pData, file_offset_t WordCount) {      file_offset_t Chunk::WriteUint8(uint8_t* pData, file_offset_t WordCount) {
# Line 529  namespace RIFF { Line 585  namespace RIFF {
585       * @param pData             destination buffer       * @param pData             destination buffer
586       * @param WordCount         number of 16 Bit signed integers to read       * @param WordCount         number of 16 Bit signed integers to read
587       * @returns                 number of read integers       * @returns                 number of read integers
588       * @throws RIFF::Exception  if an error occured or less than       * @throws RIFF::Exception  if an error occurred or less than
589       *                          \a WordCount integers could be read!       *                          \a WordCount integers could be read!
590       */       */
591      file_offset_t Chunk::ReadInt16(int16_t* pData, file_offset_t WordCount) {      file_offset_t Chunk::ReadInt16(int16_t* pData, file_offset_t WordCount) {
592          #if DEBUG          #if DEBUG_RIFF
593          std::cout << "Chunk::ReadInt16(int16_t*,file_offset_t)" << std::endl;          std::cout << "Chunk::ReadInt16(int16_t*,file_offset_t)" << std::endl;
594          #endif // DEBUG          #endif // DEBUG_RIFF
595          return ReadSceptical(pData, WordCount, 2);          return ReadSceptical(pData, WordCount, 2);
596      }      }
597    
# Line 550  namespace RIFF { Line 606  namespace RIFF {
606       * @param pData             source buffer (containing the data)       * @param pData             source buffer (containing the data)
607       * @param WordCount         number of 16 Bit signed integers to write       * @param WordCount         number of 16 Bit signed integers to write
608       * @returns                 number of written integers       * @returns                 number of written integers
609       * @throws RIFF::Exception  if an IO error occured       * @throws RIFF::Exception  if an IO error occurred
610       * @see Resize()       * @see Resize()
611       */       */
612      file_offset_t Chunk::WriteInt16(int16_t* pData, file_offset_t WordCount) {      file_offset_t Chunk::WriteInt16(int16_t* pData, file_offset_t WordCount) {
# Line 566  namespace RIFF { Line 622  namespace RIFF {
622       * @param pData             destination buffer       * @param pData             destination buffer
623       * @param WordCount         number of 8 Bit unsigned integers to read       * @param WordCount         number of 8 Bit unsigned integers to read
624       * @returns                 number of read integers       * @returns                 number of read integers
625       * @throws RIFF::Exception  if an error occured or less than       * @throws RIFF::Exception  if an error occurred or less than
626       *                          \a WordCount integers could be read!       *                          \a WordCount integers could be read!
627       */       */
628      file_offset_t Chunk::ReadUint16(uint16_t* pData, file_offset_t WordCount) {      file_offset_t Chunk::ReadUint16(uint16_t* pData, file_offset_t WordCount) {
629          #if DEBUG          #if DEBUG_RIFF
630          std::cout << "Chunk::ReadUint16(uint16_t*,file_offset_t)" << std::endl;          std::cout << "Chunk::ReadUint16(uint16_t*,file_offset_t)" << std::endl;
631          #endif // DEBUG          #endif // DEBUG_RIFF
632          return ReadSceptical(pData, WordCount, 2);          return ReadSceptical(pData, WordCount, 2);
633      }      }
634    
# Line 587  namespace RIFF { Line 643  namespace RIFF {
643       * @param pData             source buffer (containing the data)       * @param pData             source buffer (containing the data)
644       * @param WordCount         number of 16 Bit unsigned integers to write       * @param WordCount         number of 16 Bit unsigned integers to write
645       * @returns                 number of written integers       * @returns                 number of written integers
646       * @throws RIFF::Exception  if an IO error occured       * @throws RIFF::Exception  if an IO error occurred
647       * @see Resize()       * @see Resize()
648       */       */
649      file_offset_t Chunk::WriteUint16(uint16_t* pData, file_offset_t WordCount) {      file_offset_t Chunk::WriteUint16(uint16_t* pData, file_offset_t WordCount) {
# Line 603  namespace RIFF { Line 659  namespace RIFF {
659       * @param pData             destination buffer       * @param pData             destination buffer
660       * @param WordCount         number of 32 Bit signed integers to read       * @param WordCount         number of 32 Bit signed integers to read
661       * @returns                 number of read integers       * @returns                 number of read integers
662       * @throws RIFF::Exception  if an error occured or less than       * @throws RIFF::Exception  if an error occurred or less than
663       *                          \a WordCount integers could be read!       *                          \a WordCount integers could be read!
664       */       */
665      file_offset_t Chunk::ReadInt32(int32_t* pData, file_offset_t WordCount) {      file_offset_t Chunk::ReadInt32(int32_t* pData, file_offset_t WordCount) {
666          #if DEBUG          #if DEBUG_RIFF
667          std::cout << "Chunk::ReadInt32(int32_t*,file_offset_t)" << std::endl;          std::cout << "Chunk::ReadInt32(int32_t*,file_offset_t)" << std::endl;
668          #endif // DEBUG          #endif // DEBUG_RIFF
669          return ReadSceptical(pData, WordCount, 4);          return ReadSceptical(pData, WordCount, 4);
670      }      }
671    
# Line 624  namespace RIFF { Line 680  namespace RIFF {
680       * @param pData             source buffer (containing the data)       * @param pData             source buffer (containing the data)
681       * @param WordCount         number of 32 Bit signed integers to write       * @param WordCount         number of 32 Bit signed integers to write
682       * @returns                 number of written integers       * @returns                 number of written integers
683       * @throws RIFF::Exception  if an IO error occured       * @throws RIFF::Exception  if an IO error occurred
684       * @see Resize()       * @see Resize()
685       */       */
686      file_offset_t Chunk::WriteInt32(int32_t* pData, file_offset_t WordCount) {      file_offset_t Chunk::WriteInt32(int32_t* pData, file_offset_t WordCount) {
# Line 640  namespace RIFF { Line 696  namespace RIFF {
696       * @param pData             destination buffer       * @param pData             destination buffer
697       * @param WordCount         number of 32 Bit unsigned integers to read       * @param WordCount         number of 32 Bit unsigned integers to read
698       * @returns                 number of read integers       * @returns                 number of read integers
699       * @throws RIFF::Exception  if an error occured or less than       * @throws RIFF::Exception  if an error occurred or less than
700       *                          \a WordCount integers could be read!       *                          \a WordCount integers could be read!
701       */       */
702      file_offset_t Chunk::ReadUint32(uint32_t* pData, file_offset_t WordCount) {      file_offset_t Chunk::ReadUint32(uint32_t* pData, file_offset_t WordCount) {
703          #if DEBUG          #if DEBUG_RIFF
704          std::cout << "Chunk::ReadUint32(uint32_t*,file_offset_t)" << std::endl;          std::cout << "Chunk::ReadUint32(uint32_t*,file_offset_t)" << std::endl;
705          #endif // DEBUG          #endif // DEBUG_RIFF
706          return ReadSceptical(pData, WordCount, 4);          return ReadSceptical(pData, WordCount, 4);
707      }      }
708    
# Line 657  namespace RIFF { Line 713  namespace RIFF {
713       *       *
714       * @param s                 destination string       * @param s                 destination string
715       * @param size              number of characters to read       * @param size              number of characters to read
716       * @throws RIFF::Exception  if an error occured or less than       * @throws RIFF::Exception  if an error occurred or less than
717       *                          \a size characters could be read!       *                          \a size characters could be read!
718       */       */
719      void Chunk::ReadString(String& s, int size) {      void Chunk::ReadString(String& s, int size) {
# Line 678  namespace RIFF { Line 734  namespace RIFF {
734       * @param pData             source buffer (containing the data)       * @param pData             source buffer (containing the data)
735       * @param WordCount         number of 32 Bit unsigned integers to write       * @param WordCount         number of 32 Bit unsigned integers to write
736       * @returns                 number of written integers       * @returns                 number of written integers
737       * @throws RIFF::Exception  if an IO error occured       * @throws RIFF::Exception  if an IO error occurred
738       * @see Resize()       * @see Resize()
739       */       */
740      file_offset_t Chunk::WriteUint32(uint32_t* pData, file_offset_t WordCount) {      file_offset_t Chunk::WriteUint32(uint32_t* pData, file_offset_t WordCount) {
# Line 690  namespace RIFF { Line 746  namespace RIFF {
746       * the chunk.       * the chunk.
747       *       *
748       * @returns                 read integer word       * @returns                 read integer word
749       * @throws RIFF::Exception  if an error occured       * @throws RIFF::Exception  if an error occurred
750       */       */
751      int8_t Chunk::ReadInt8() {      int8_t Chunk::ReadInt8() {
752          #if DEBUG          #if DEBUG_RIFF
753          std::cout << "Chunk::ReadInt8()" << std::endl;          std::cout << "Chunk::ReadInt8()" << std::endl;
754          #endif // DEBUG          #endif // DEBUG_RIFF
755          int8_t word;          int8_t word;
756          ReadSceptical(&word,1,1);          ReadSceptical(&word,1,1);
757          return word;          return word;
# Line 706  namespace RIFF { Line 762  namespace RIFF {
762       * within the chunk.       * within the chunk.
763       *       *
764       * @returns                 read integer word       * @returns                 read integer word
765       * @throws RIFF::Exception  if an error occured       * @throws RIFF::Exception  if an error occurred
766       */       */
767      uint8_t Chunk::ReadUint8() {      uint8_t Chunk::ReadUint8() {
768          #if DEBUG          #if DEBUG_RIFF
769          std::cout << "Chunk::ReadUint8()" << std::endl;          std::cout << "Chunk::ReadUint8()" << std::endl;
770          #endif // DEBUG          #endif // DEBUG_RIFF
771          uint8_t word;          uint8_t word;
772          ReadSceptical(&word,1,1);          ReadSceptical(&word,1,1);
773          return word;          return word;
# Line 723  namespace RIFF { Line 779  namespace RIFF {
779       * needed.       * needed.
780       *       *
781       * @returns                 read integer word       * @returns                 read integer word
782       * @throws RIFF::Exception  if an error occured       * @throws RIFF::Exception  if an error occurred
783       */       */
784      int16_t Chunk::ReadInt16() {      int16_t Chunk::ReadInt16() {
785          #if DEBUG          #if DEBUG_RIFF
786          std::cout << "Chunk::ReadInt16()" << std::endl;          std::cout << "Chunk::ReadInt16()" << std::endl;
787          #endif // DEBUG          #endif // DEBUG_RIFF
788          int16_t word;          int16_t word;
789          ReadSceptical(&word,1,2);          ReadSceptical(&word,1,2);
790          return word;          return word;
# Line 740  namespace RIFF { Line 796  namespace RIFF {
796       * needed.       * needed.
797       *       *
798       * @returns                 read integer word       * @returns                 read integer word
799       * @throws RIFF::Exception  if an error occured       * @throws RIFF::Exception  if an error occurred
800       */       */
801      uint16_t Chunk::ReadUint16() {      uint16_t Chunk::ReadUint16() {
802          #if DEBUG          #if DEBUG_RIFF
803          std::cout << "Chunk::ReadUint16()" << std::endl;          std::cout << "Chunk::ReadUint16()" << std::endl;
804          #endif // DEBUG          #endif // DEBUG_RIFF
805          uint16_t word;          uint16_t word;
806          ReadSceptical(&word,1,2);          ReadSceptical(&word,1,2);
807          return word;          return word;
# Line 757  namespace RIFF { Line 813  namespace RIFF {
813       * needed.       * needed.
814       *       *
815       * @returns                 read integer word       * @returns                 read integer word
816       * @throws RIFF::Exception  if an error occured       * @throws RIFF::Exception  if an error occurred
817       */       */
818      int32_t Chunk::ReadInt32() {      int32_t Chunk::ReadInt32() {
819          #if DEBUG          #if DEBUG_RIFF
820          std::cout << "Chunk::ReadInt32()" << std::endl;          std::cout << "Chunk::ReadInt32()" << std::endl;
821          #endif // DEBUG          #endif // DEBUG_RIFF
822          int32_t word;          int32_t word;
823          ReadSceptical(&word,1,4);          ReadSceptical(&word,1,4);
824          return word;          return word;
# Line 774  namespace RIFF { Line 830  namespace RIFF {
830       * needed.       * needed.
831       *       *
832       * @returns                 read integer word       * @returns                 read integer word
833       * @throws RIFF::Exception  if an error occured       * @throws RIFF::Exception  if an error occurred
834       */       */
835      uint32_t Chunk::ReadUint32() {      uint32_t Chunk::ReadUint32() {
836          #if DEBUG          #if DEBUG_RIFF
837          std::cout << "Chunk::ReadUint32()" << std::endl;          std::cout << "Chunk::ReadUint32()" << std::endl;
838          #endif // DEBUG          #endif // DEBUG_RIFF
839          uint32_t word;          uint32_t word;
840          ReadSceptical(&word,1,4);          ReadSceptical(&word,1,4);
841          return word;          return word;
# Line 941  namespace RIFF { Line 997  namespace RIFF {
997              int iBytesMoved = 1;              int iBytesMoved = 1;
998              #endif              #endif
999              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) {
1000                  iBytesMoved = (ullToMove < 4096) ? ullToMove : 4096;                  iBytesMoved = (ullToMove < 4096) ? int(ullToMove) : 4096;
1001                  #if POSIX                  #if POSIX
1002                  lseek(pFile->hFileRead, ullStartPos + ullCurrentDataOffset + ullOffset, SEEK_SET);                  lseek(pFile->hFileRead, ullStartPos + ullCurrentDataOffset + ullOffset, SEEK_SET);
1003                  iBytesMoved = read(pFile->hFileRead, pCopyBuffer, iBytesMoved);                  iBytesMoved = (int) read(pFile->hFileRead, pCopyBuffer, (size_t) iBytesMoved);
1004                  lseek(pFile->hFileWrite, ullWritePos + ullOffset, SEEK_SET);                  lseek(pFile->hFileWrite, ullWritePos + ullOffset, SEEK_SET);
1005                  iBytesMoved = write(pFile->hFileWrite, pCopyBuffer, iBytesMoved);                  iBytesMoved = (int) write(pFile->hFileWrite, pCopyBuffer, (size_t) iBytesMoved);
1006                  #elif defined(WIN32)                  #elif defined(WIN32)
1007                  LARGE_INTEGER liFilePos;                  LARGE_INTEGER liFilePos;
1008                  liFilePos.QuadPart = ullStartPos + ullCurrentDataOffset + ullOffset;                  liFilePos.QuadPart = ullStartPos + ullCurrentDataOffset + ullOffset;
# Line 1008  namespace RIFF { Line 1064  namespace RIFF {
1064  // *  // *
1065    
1066      List::List(File* pFile) : Chunk(pFile) {      List::List(File* pFile) : Chunk(pFile) {
1067          #if DEBUG          #if DEBUG_RIFF
1068          std::cout << "List::List(File* pFile)" << std::endl;          std::cout << "List::List(File* pFile)" << std::endl;
1069          #endif // DEBUG          #endif // DEBUG_RIFF
1070          pSubChunks    = NULL;          pSubChunks    = NULL;
1071          pSubChunksMap = NULL;          pSubChunksMap = NULL;
1072      }      }
1073    
1074      List::List(File* pFile, file_offset_t StartPos, List* Parent)      List::List(File* pFile, file_offset_t StartPos, List* Parent)
1075        : Chunk(pFile, StartPos, Parent) {        : Chunk(pFile, StartPos, Parent) {
1076          #if DEBUG          #if DEBUG_RIFF
1077          std::cout << "List::List(File*,file_offset_t,List*)" << std::endl;          std::cout << "List::List(File*,file_offset_t,List*)" << std::endl;
1078          #endif // DEBUG          #endif // DEBUG_RIFF
1079          pSubChunks    = NULL;          pSubChunks    = NULL;
1080          pSubChunksMap = NULL;          pSubChunksMap = NULL;
1081          ReadHeader(StartPos);          ReadHeader(StartPos);
# Line 1034  namespace RIFF { Line 1090  namespace RIFF {
1090      }      }
1091    
1092      List::~List() {      List::~List() {
1093          #if DEBUG          #if DEBUG_RIFF
1094          std::cout << "List::~List()" << std::endl;          std::cout << "List::~List()" << std::endl;
1095          #endif // DEBUG          #endif // DEBUG_RIFF
1096          DeleteChunkList();          DeleteChunkList();
1097      }      }
1098    
# Line 1069  namespace RIFF { Line 1125  namespace RIFF {
1125       *                   that ID       *                   that ID
1126       */       */
1127      Chunk* List::GetSubChunk(uint32_t ChunkID) {      Chunk* List::GetSubChunk(uint32_t ChunkID) {
1128          #if DEBUG          #if DEBUG_RIFF
1129          std::cout << "List::GetSubChunk(uint32_t)" << std::endl;          std::cout << "List::GetSubChunk(uint32_t)" << std::endl;
1130          #endif // DEBUG          #endif // DEBUG_RIFF
1131          if (!pSubChunksMap) LoadSubChunks();          if (!pSubChunksMap) LoadSubChunks();
1132          return (*pSubChunksMap)[ChunkID];          return (*pSubChunksMap)[ChunkID];
1133      }      }
# Line 1088  namespace RIFF { Line 1144  namespace RIFF {
1144       *                    that type       *                    that type
1145       */       */
1146      List* List::GetSubList(uint32_t ListType) {      List* List::GetSubList(uint32_t ListType) {
1147          #if DEBUG          #if DEBUG_RIFF
1148          std::cout << "List::GetSubList(uint32_t)" << std::endl;          std::cout << "List::GetSubList(uint32_t)" << std::endl;
1149          #endif // DEBUG          #endif // DEBUG_RIFF
1150          if (!pSubChunks) LoadSubChunks();          if (!pSubChunks) LoadSubChunks();
1151          ChunkList::iterator iter = pSubChunks->begin();          ChunkList::iterator iter = pSubChunks->begin();
1152          ChunkList::iterator end  = pSubChunks->end();          ChunkList::iterator end  = pSubChunks->end();
# Line 1114  namespace RIFF { Line 1170  namespace RIFF {
1170       *            otherwise       *            otherwise
1171       */       */
1172      Chunk* List::GetFirstSubChunk() {      Chunk* List::GetFirstSubChunk() {
1173          #if DEBUG          #if DEBUG_RIFF
1174          std::cout << "List::GetFirstSubChunk()" << std::endl;          std::cout << "List::GetFirstSubChunk()" << std::endl;
1175          #endif // DEBUG          #endif // DEBUG_RIFF
1176          if (!pSubChunks) LoadSubChunks();          if (!pSubChunks) LoadSubChunks();
1177          ChunksIterator = pSubChunks->begin();          ChunksIterator = pSubChunks->begin();
1178          return (ChunksIterator != pSubChunks->end()) ? *ChunksIterator : NULL;          return (ChunksIterator != pSubChunks->end()) ? *ChunksIterator : NULL;
# Line 1131  namespace RIFF { Line 1187  namespace RIFF {
1187       *            end of list is reached       *            end of list is reached
1188       */       */
1189      Chunk* List::GetNextSubChunk() {      Chunk* List::GetNextSubChunk() {
1190          #if DEBUG          #if DEBUG_RIFF
1191          std::cout << "List::GetNextSubChunk()" << std::endl;          std::cout << "List::GetNextSubChunk()" << std::endl;
1192          #endif // DEBUG          #endif // DEBUG_RIFF
1193          if (!pSubChunks) return NULL;          if (!pSubChunks) return NULL;
1194          ChunksIterator++;          ChunksIterator++;
1195          return (ChunksIterator != pSubChunks->end()) ? *ChunksIterator : NULL;          return (ChunksIterator != pSubChunks->end()) ? *ChunksIterator : NULL;
# Line 1149  namespace RIFF { Line 1205  namespace RIFF {
1205       *            otherwise       *            otherwise
1206       */       */
1207      List* List::GetFirstSubList() {      List* List::GetFirstSubList() {
1208          #if DEBUG          #if DEBUG_RIFF
1209          std::cout << "List::GetFirstSubList()" << std::endl;          std::cout << "List::GetFirstSubList()" << std::endl;
1210          #endif // DEBUG          #endif // DEBUG_RIFF
1211          if (!pSubChunks) LoadSubChunks();          if (!pSubChunks) LoadSubChunks();
1212          ListIterator            = pSubChunks->begin();          ListIterator            = pSubChunks->begin();
1213          ChunkList::iterator end = pSubChunks->end();          ChunkList::iterator end = pSubChunks->end();
# Line 1171  namespace RIFF { Line 1227  namespace RIFF {
1227       *            end of list is reached       *            end of list is reached
1228       */       */
1229      List* List::GetNextSubList() {      List* List::GetNextSubList() {
1230          #if DEBUG          #if DEBUG_RIFF
1231          std::cout << "List::GetNextSubList()" << std::endl;          std::cout << "List::GetNextSubList()" << std::endl;
1232          #endif // DEBUG          #endif // DEBUG_RIFF
1233          if (!pSubChunks) return NULL;          if (!pSubChunks) return NULL;
1234          if (ListIterator == pSubChunks->end()) return NULL;          if (ListIterator == pSubChunks->end()) return NULL;
1235          ListIterator++;          ListIterator++;
# Line 1375  namespace RIFF { Line 1431  namespace RIFF {
1431      }      }
1432    
1433      void List::ReadHeader(file_offset_t filePos) {      void List::ReadHeader(file_offset_t filePos) {
1434          #if DEBUG          #if DEBUG_RIFF
1435          std::cout << "List::Readheader(file_offset_t) ";          std::cout << "List::Readheader(file_offset_t) ";
1436          #endif // DEBUG          #endif // DEBUG_RIFF
1437          Chunk::ReadHeader(filePos);          Chunk::ReadHeader(filePos);
1438          if (ullCurrentChunkSize < 4) return;          if (ullCurrentChunkSize < 4) return;
1439          ullNewChunkSize = ullCurrentChunkSize -= 4;          ullNewChunkSize = ullCurrentChunkSize -= 4;
# Line 1394  namespace RIFF { Line 1450  namespace RIFF {
1450          fseeko(pFile->hFileRead, filePos + CHUNK_HEADER_SIZE(pFile->FileOffsetSize), SEEK_SET);          fseeko(pFile->hFileRead, filePos + CHUNK_HEADER_SIZE(pFile->FileOffsetSize), SEEK_SET);
1451          fread(&ListType, 4, 1, pFile->hFileRead);          fread(&ListType, 4, 1, pFile->hFileRead);
1452          #endif // POSIX          #endif // POSIX
1453          #if DEBUG          #if DEBUG_RIFF
1454          std::cout << "listType=" << convertToString(ListType) << std::endl;          std::cout << "listType=" << convertToString(ListType) << std::endl;
1455          #endif // DEBUG          #endif // DEBUG_RIFF
1456          if (!pFile->bEndianNative) {          if (!pFile->bEndianNative) {
1457              //swapBytes_32(&ListType);              //swapBytes_32(&ListType);
1458          }          }
# Line 1423  namespace RIFF { Line 1479  namespace RIFF {
1479      }      }
1480    
1481      void List::LoadSubChunks(progress_t* pProgress) {      void List::LoadSubChunks(progress_t* pProgress) {
1482          #if DEBUG          #if DEBUG_RIFF
1483          std::cout << "List::LoadSubChunks()";          std::cout << "List::LoadSubChunks()";
1484          #endif // DEBUG          #endif // DEBUG_RIFF
1485          if (!pSubChunks) {          if (!pSubChunks) {
1486              pSubChunks    = new ChunkList();              pSubChunks    = new ChunkList();
1487              pSubChunksMap = new ChunkMap();              pSubChunksMap = new ChunkMap();
# Line 1440  namespace RIFF { Line 1496  namespace RIFF {
1496                  Chunk* ck;                  Chunk* ck;
1497                  uint32_t ckid;                  uint32_t ckid;
1498                  Read(&ckid, 4, 1);                  Read(&ckid, 4, 1);
1499                  #if DEBUG                  #if DEBUG_RIFF
1500                  std::cout << " ckid=" << convertToString(ckid) << std::endl;                  std::cout << " ckid=" << convertToString(ckid) << std::endl;
1501                  #endif // DEBUG                  #endif // DEBUG_RIFF
1502                  if (ckid == CHUNK_ID_LIST) {                  if (ckid == CHUNK_ID_LIST) {
1503                      ck = new RIFF::List(pFile, ullStartPos + ullPos - 4, this);                      ck = new RIFF::List(pFile, ullStartPos + ullPos - 4, this);
1504                      SetPos(ck->GetSize() + LIST_HEADER_SIZE(pFile->FileOffsetSize) - 4, RIFF::stream_curpos);                      SetPos(ck->GetSize() + LIST_HEADER_SIZE(pFile->FileOffsetSize) - 4, RIFF::stream_curpos);
# Line 1461  namespace RIFF { Line 1517  namespace RIFF {
1517      }      }
1518    
1519      void List::LoadSubChunksRecursively(progress_t* pProgress) {      void List::LoadSubChunksRecursively(progress_t* pProgress) {
1520          const int n = CountSubLists();          const int n = (int) CountSubLists();
1521          int i = 0;          int i = 0;
1522          for (List* pList = GetFirstSubList(); pList; pList = GetNextSubList(), ++i) {          for (List* pList = GetFirstSubList(); pList; pList = GetNextSubList(), ++i) {
1523              // divide local progress into subprogress              // divide local progress into subprogress
# Line 1576  namespace RIFF { Line 1632  namespace RIFF {
1632       * Loads an existing RIFF file with all its chunks.       * Loads an existing RIFF file with all its chunks.
1633       *       *
1634       * @param path - path and file name of the RIFF file to open       * @param path - path and file name of the RIFF file to open
1635       * @throws RIFF::Exception if error occured while trying to load the       * @throws RIFF::Exception if error occurred while trying to load the
1636       *                         given RIFF file       *                         given RIFF file
1637       */       */
1638      File::File(const String& path)      File::File(const String& path)
1639          : List(this), Filename(path), bIsNewFile(false), Layout(layout_standard),          : List(this), Filename(path), bIsNewFile(false), Layout(layout_standard),
1640            FileOffsetPreference(offset_size_auto)            FileOffsetPreference(offset_size_auto)
1641      {      {
1642          #if DEBUG          #if DEBUG_RIFF
1643          std::cout << "File::File("<<path<<")" << std::endl;          std::cout << "File::File("<<path<<")" << std::endl;
1644          #endif // DEBUG          #endif // DEBUG_RIFF
1645          bEndianNative = true;          bEndianNative = true;
1646          FileOffsetSize = 4;          FileOffsetSize = 4;
1647          try {          try {
# Line 1623  namespace RIFF { Line 1679  namespace RIFF {
1679       * @param Endian - whether the file uses little endian or big endian layout       * @param Endian - whether the file uses little endian or big endian layout
1680       * @param layout - general file structure type       * @param layout - general file structure type
1681       * @param fileOffsetSize - (optional) preference how to deal with large files       * @param fileOffsetSize - (optional) preference how to deal with large files
1682       * @throws RIFF::Exception if error occured while trying to load the       * @throws RIFF::Exception if error occurred while trying to load the
1683       *                         given RIFF-alike file       *                         given RIFF-alike file
1684       */       */
1685      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)
# Line 1650  namespace RIFF { Line 1706  namespace RIFF {
1706       * @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
1707       *               be opened       *               be opened
1708       * @param FileType - (optional) expected chunk ID of first chunk in file       * @param FileType - (optional) expected chunk ID of first chunk in file
1709       * @throws RIFF::Exception if error occured while trying to load the       * @throws RIFF::Exception if error occurred while trying to load the
1710       *                         given RIFF file or RIFF-alike file       *                         given RIFF file or RIFF-alike file
1711       */       */
1712      void File::__openExistingFile(const String& path, uint32_t* FileType) {      void File::__openExistingFile(const String& path, uint32_t* FileType) {
# Line 1812  namespace RIFF { Line 1868  namespace RIFF {
1868                      #if POSIX                      #if POSIX
1869                      if (hFileRead)  close(hFileRead);                      if (hFileRead)  close(hFileRead);
1870                      if (hFileWrite) close(hFileWrite);                      if (hFileWrite) close(hFileWrite);
1871                        hFileRead = hFileWrite = 0;
1872                      #elif defined(WIN32)                      #elif defined(WIN32)
1873                      if (hFileRead  != INVALID_HANDLE_VALUE) CloseHandle(hFileRead);                      if (hFileRead  != INVALID_HANDLE_VALUE) CloseHandle(hFileRead);
1874                      if (hFileWrite != INVALID_HANDLE_VALUE) CloseHandle(hFileWrite);                      if (hFileWrite != INVALID_HANDLE_VALUE) CloseHandle(hFileWrite);
1875                        hFileRead = hFileWrite = INVALID_HANDLE_VALUE;
1876                      #else                      #else
1877                      if (hFileRead)  fclose(hFileRead);                      if (hFileRead)  fclose(hFileRead);
1878                      if (hFileWrite) fclose(hFileWrite);                      if (hFileWrite) fclose(hFileWrite);
1879                        hFileRead = hFileWrite = NULL;
1880                      #endif                      #endif
                     hFileRead = hFileWrite = 0;  
1881                      break;                      break;
1882                  default:                  default:
1883                      throw Exception("Unknown file access mode");                      throw Exception("Unknown file access mode");
# Line 1854  namespace RIFF { Line 1912  namespace RIFF {
1912       *       *
1913       * @param pProgress - optional: callback function for progress notification       * @param pProgress - optional: callback function for progress notification
1914       * @throws RIFF::Exception if there is an empty chunk or empty list       * @throws RIFF::Exception if there is an empty chunk or empty list
1915       *                         chunk or any kind of IO error occured       *                         chunk or any kind of IO error occurred
1916       */       */
1917      void File::Save(progress_t* pProgress) {      void File::Save(progress_t* pProgress) {
1918          //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)
# Line 2079  namespace RIFF { Line 2137  namespace RIFF {
2137      }      }
2138    
2139      File::~File() {      File::~File() {
2140          #if DEBUG          #if DEBUG_RIFF
2141          std::cout << "File::~File()" << std::endl;          std::cout << "File::~File()" << std::endl;
2142          #endif // DEBUG          #endif // DEBUG_RIFF
2143          Cleanup();          Cleanup();
2144      }      }
2145    
# Line 2251  namespace RIFF { Line 2309  namespace RIFF {
2309  // *************** Exception ***************  // *************** Exception ***************
2310  // *  // *
2311    
2312        Exception::Exception() {
2313        }
2314    
2315        Exception::Exception(String format, ...) {
2316            va_list arg;
2317            va_start(arg, format);
2318            Message = assemble(format, arg);
2319            va_end(arg);
2320        }
2321    
2322        Exception::Exception(String format, va_list arg) {
2323            Message = assemble(format, arg);
2324        }
2325    
2326      void Exception::PrintMessage() {      void Exception::PrintMessage() {
2327          std::cout << "RIFF::Exception: " << Message << std::endl;          std::cout << "RIFF::Exception: " << Message << std::endl;
2328      }      }
2329    
2330        String Exception::assemble(String format, va_list arg) {
2331            char* buf = NULL;
2332            vasprintf(&buf, format.c_str(), arg);
2333            String s = buf;
2334            free(buf);
2335            return s;
2336        }
2337    
2338    
2339  // *************** functions ***************  // *************** functions ***************
2340  // *  // *

Legend:
Removed from v.2922  
changed lines
  Added in v.3481

  ViewVC Help
Powered by ViewVC