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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2 - (hide annotations) (download)
Sat Oct 25 20:15:04 2003 UTC (20 years, 5 months ago) by schoenebeck
File size: 25016 byte(s)
Initial revision

1 schoenebeck 2 /***************************************************************************
2     * *
3     * libgig - C++ cross-platform Gigasampler format file loader library *
4     * *
5     * Copyright (C) 2003 by Christian Schoenebeck *
6     * <cuse@users.sourceforge.net> *
7     * *
8     * This library is free software; you can redistribute it and/or modify *
9     * it under the terms of the GNU General Public License as published by *
10     * the Free Software Foundation; either version 2 of the License, or *
11     * (at your option) any later version. *
12     * *
13     * This library is distributed in the hope that it will be useful, *
14     * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16     * GNU General Public License for more details. *
17     * *
18     * You should have received a copy of the GNU General Public License *
19     * along with this library; if not, write to the Free Software *
20     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
21     * MA 02111-1307 USA *
22     ***************************************************************************/
23     #if 1
24     #include "RIFF.h"
25    
26     namespace RIFF {
27    
28     // *************** Chunk **************
29     // *
30    
31     Chunk::Chunk() {
32     #if DEBUG
33     std::cout << "Chunk::Chunk()" << std::endl;
34     #endif // DEBUG
35     ulPos = 0;
36     pParent = NULL;
37     pChunkData = NULL;
38     }
39    
40     #if POSIX
41     Chunk::Chunk(int hFile, unsigned long StartPos, bool EndianNative, List* Parent) {
42     #else
43     Chunk::Chunk(FILE* hFile, unsigned long StartPos, bool EndianNative, List* Parent) {
44     #endif // POSIX
45     #if DEBUG
46     std::cout << "Chunk::Chunk(FILE,ulong,bool,List*),StartPos=" << StartPos << std::endl;
47     #endif // DEBUG
48     Chunk::hFile = hFile;
49     ulStartPos = StartPos + CHUNK_HEADER_SIZE;
50     bEndianNative = EndianNative;
51     pParent = Parent;
52     ulPos = 0;
53     pChunkData = NULL;
54     ReadHeader(StartPos);
55     }
56    
57     Chunk::~Chunk() {
58     if (pChunkData) delete[] pChunkData;
59     }
60    
61     void Chunk::ReadHeader(unsigned long fPos) {
62     #if DEBUG
63     std::cout << "Chunk::Readheader(" << fPos << ") ";
64     #endif // DEBUG
65     #if POSIX
66     if (lseek(hFile, fPos, SEEK_SET) != -1) {
67     read(hFile, &ChunkID, 4);
68     read(hFile, &ChunkSize, 4);
69     #else
70     if (!fseek(hFile, fPos, SEEK_SET)) {
71     fread(&ChunkID, 4, 1, hFile);
72     fread(&ChunkSize, 4, 1, hFile);
73     #endif // POSIX
74     #if DEBUG
75     std::cout << "ckID=" << convertToString(ChunkID) << " ";
76     std::cout << "ckSize=" << ChunkSize << std::endl;
77     #endif // DEBUG
78     #if WORDS_BIGENDIAN
79     if (ChunkID == CHUNK_ID_RIFF) {
80     bEndianNative = false;
81     }
82     #else // little endian
83     if (ChunkID == CHUNK_ID_RIFX) {
84     bEndianNative = false;
85     ChunkID = CHUNK_ID_RIFF;
86     }
87     #endif // WORDS_BIGENDIAN
88     if (!bEndianNative) {
89     swapBytes_32(&ChunkID);
90     swapBytes_32(&ChunkSize);
91     }
92     }
93     }
94    
95     String Chunk::GetChunkIDString() {
96     return convertToString(ChunkID);
97     }
98    
99     unsigned long Chunk::SetPos(unsigned long Where, stream_whence_t Whence) {
100     #if DEBUG
101     std::cout << "Chunk::SetPos(ulong)" << std::endl;
102     #endif // DEBUG
103     switch (Whence) {
104     case stream_curpos:
105     ulPos += Where;
106     break;
107     case stream_end:
108     ulPos = ChunkSize - 1 - Where;
109     break;
110     case stream_backward:
111     ulPos -= Where;
112     break;
113     case stream_start: default:
114     ulPos = Where;
115     break;
116     }
117     if (ulPos > ChunkSize) ulPos = ChunkSize;
118     return ulPos;
119     }
120    
121     unsigned long Chunk::RemainingBytes() {
122     #if DEBUG
123     std::cout << "Chunk::Remainingbytes()=" << ChunkSize - ulPos << std::endl;
124     #endif // DEBUG
125     return ChunkSize - ulPos;
126     }
127    
128     stream_state_t Chunk::GetState() {
129     #if DEBUG
130     std::cout << "Chunk::GetState()" << std::endl;
131     #endif // DEBUG
132     #if POSIX
133     if (hFile == 0) return stream_closed;
134     #else
135     if (hFile == NULL) return stream_closed;
136     #endif // POSIX
137     if (ulPos < ChunkSize) return stream_ready;
138     else return stream_end_reached;
139     }
140    
141     /**
142     * Reads \a WordCount number of data words with given \a WordSize and
143     * copies it into a buffer pointed by \a pData. The buffer has to be
144     * allocated and be sure to provide the correct \a WordSize, as this
145     * will be important and taken into account for eventual endian
146     * correction (swapping of bytes due to different native byte order of
147     * a system). The position within the chunk will automatically be
148     * incremented.
149     *
150     * @param pData destination buffer
151     * @param WordCount number of data words to read
152     * @param WordSize size of each data word to read
153     * @returns number of successfully read data words or 0 if end
154     * of file reached or error occured
155     */
156     unsigned long Chunk::Read(void* pData, unsigned long WordCount, unsigned long WordSize) {
157     #if DEBUG
158     std::cout << "Chunk::Read(void*,ulong,ulong)" << std::endl;
159     #endif // DEBUG
160     if (ChunkSize - ulPos <= 0) return 0;
161     if (ulPos + WordCount * WordSize >= ChunkSize) WordCount = (ChunkSize - ulPos) / WordSize;
162     #if POSIX
163     if (lseek(hFile, ulStartPos + ulPos, SEEK_SET) < 0) return 0;
164     unsigned long readWords = read(hFile, pData, WordCount * WordSize);
165     if (readWords < 1) return 0;
166     readWords /= WordSize;
167     #else // standard C functions
168     if (fseek(hFile, ulStartPos + ulPos, SEEK_SET)) return 0;
169     unsigned long readWords = fread(pData, WordSize, WordCount, hFile);
170     #endif // POSIX
171     if (!bEndianNative && WordSize != 1) {
172     switch (WordSize) {
173     case 2:
174     for (unsigned long iWord = 0; iWord < readWords; iWord++)
175     swapBytes_16((uint16_t*) pData + iWord);
176     break;
177     case 4:
178     for (unsigned long iWord = 0; iWord < readWords; iWord++)
179     swapBytes_32((uint32_t*) pData + iWord);
180     break;
181     default:
182     for (unsigned long iWord = 0; iWord < readWords; iWord++)
183     swapBytes((uint8_t*) pData + iWord * WordSize, WordSize);
184     break;
185     }
186     }
187     SetPos(readWords * WordSize, stream_curpos);
188     return readWords;
189     }
190    
191     /** Just an internal wrapper for the main <i>Read()</i> method with additional Exception throwing on errors. */
192     unsigned long Chunk::ReadSceptical(void* pData, unsigned long WordCount, unsigned long WordSize) {
193     unsigned long readWords = Read(pData, WordCount, WordSize);
194     if (readWords != WordCount) throw RIFF::Exception("End of chunk data reached.");
195     return readWords;
196     }
197    
198     /**
199     * Reads \a WordCount number of 8 Bit signed integer words and copies it
200     * into the buffer pointed by \a pData. The buffer has to be allocated.
201     * The position within the chunk will automatically be incremented.
202     *
203     * @param pData destination buffer
204     * @param WordCount number of 8 Bit signed integers to read
205     * @returns number of read integers
206     * @throws RIFF::Exception if an error occured or less than
207     * \a WordCount integers could be read!
208     */
209     unsigned long Chunk::ReadInt8(int8_t* pData, unsigned long WordCount) {
210     #if DEBUG
211     std::cout << "Chunk::ReadInt8(int8_t*,ulong)" << std::endl;
212     #endif // DEBUG
213     return ReadSceptical(pData, WordCount, 1);
214     }
215    
216     /**
217     * Reads \a WordCount number of 8 Bit unsigned integer words and copies
218     * it into the buffer pointed by \a pData. The buffer has to be
219     * allocated. The position within the chunk will automatically be
220     * incremented.
221     *
222     * @param pData destination buffer
223     * @param WordCount number of 8 Bit unsigned integers to read
224     * @returns number of read integers
225     * @throws RIFF::Exception if an error occured or less than
226     * \a WordCount integers could be read!
227     */
228     unsigned long Chunk::ReadUint8(uint8_t* pData, unsigned long WordCount) {
229     #if DEBUG
230     std::cout << "Chunk::ReadUint8(uint8_t*,ulong)" << std::endl;
231     #endif // DEBUG
232     return ReadSceptical(pData, WordCount, 1);
233     }
234    
235     /**
236     * Reads \a WordCount number of 16 Bit signed integer words and copies
237     * it into the buffer pointed by \a pData. The buffer has to be
238     * allocated. Endian correction will automatically be done if needed.
239     * The position within the chunk will automatically be incremented.
240     *
241     * @param pData destination buffer
242     * @param WordCount number of 16 Bit signed integers to read
243     * @returns number of read integers
244     * @throws RIFF::Exception if an error occured or less than
245     * \a WordCount integers could be read!
246     */
247     unsigned long Chunk::ReadInt16(int16_t* pData, unsigned long WordCount) {
248     #if DEBUG
249     std::cout << "Chunk::ReadInt16(int16_t*,ulong)" << std::endl;
250     #endif // DEBUG
251     return ReadSceptical(pData, WordCount, 2);
252     }
253    
254     /**
255     * Reads \a WordCount number of 16 Bit unsigned integer words and copies
256     * it into the buffer pointed by \a pData. The buffer has to be
257     * allocated. Endian correction will automatically be done if needed.
258     * The position within the chunk will automatically be incremented.
259     *
260     * @param pData destination buffer
261     * @param WordCount number of 8 Bit unsigned integers to read
262     * @returns number of read integers
263     * @throws RIFF::Exception if an error occured or less than
264     * \a WordCount integers could be read!
265     */
266     unsigned long Chunk::ReadUint16(uint16_t* pData, unsigned long WordCount) {
267     #if DEBUG
268     std::cout << "Chunk::ReadUint16(uint16_t*,ulong)" << std::endl;
269     #endif // DEBUG
270     return ReadSceptical(pData, WordCount, 2);
271     }
272    
273     /**
274     * Reads \a WordCount number of 32 Bit signed integer words and copies
275     * it into the buffer pointed by \a pData. The buffer has to be
276     * allocated. Endian correction will automatically be done if needed.
277     * The position within the chunk will automatically be incremented.
278     *
279     * @param pData destination buffer
280     * @param WordCount number of 32 Bit signed integers to read
281     * @returns number of read integers
282     * @throws RIFF::Exception if an error occured or less than
283     * \a WordCount integers could be read!
284     */
285     unsigned long Chunk::ReadInt32(int32_t* pData, unsigned long WordCount) {
286     #if DEBUG
287     std::cout << "Chunk::ReadInt32(int32_t*,ulong)" << std::endl;
288     #endif // DEBUG
289     return ReadSceptical(pData, WordCount, 4);
290     }
291    
292     /**
293     * Reads \a WordCount number of 32 Bit unsigned integer words and copies
294     * it into the buffer pointed by \a pData. The buffer has to be
295     * allocated. Endian correction will automatically be done if needed.
296     * The position within the chunk will automatically be incremented.
297     *
298     * @param pData destination buffer
299     * @param WordCount number of 32 Bit unsigned integers to read
300     * @returns number of read integers
301     * @throws RIFF::Exception if an error occured or less than
302     * \a WordCount integers could be read!
303     */
304     unsigned long Chunk::ReadUint32(uint32_t* pData, unsigned long WordCount) {
305     #if DEBUG
306     std::cout << "Chunk::ReadUint32(uint32_t*,ulong)" << std::endl;
307     #endif // DEBUG
308     return ReadSceptical(pData, WordCount, 4);
309     }
310    
311     /**
312     * Reads one 8 Bit signed integer word and increments the position within
313     * the chunk.
314     *
315     * @returns read integer word
316     * @throws RIFF::Exception if an error occured
317     */
318     int8_t Chunk::ReadInt8() {
319     #if DEBUG
320     std::cout << "Chunk::ReadInt8()" << std::endl;
321     #endif // DEBUG
322     int8_t word;
323     ReadSceptical(&word,1,1);
324     return word;
325     }
326    
327     /**
328     * Reads one 8 Bit unsigned integer word and increments the position
329     * within the chunk.
330     *
331     * @returns read integer word
332     * @throws RIFF::Exception if an error occured
333     */
334     uint8_t Chunk::ReadUint8() {
335     #if DEBUG
336     std::cout << "Chunk::ReadUint8()" << std::endl;
337     #endif // DEBUG
338     uint8_t word;
339     ReadSceptical(&word,1,1);
340     return word;
341     }
342    
343     /**
344     * Reads one 16 Bit signed integer word and increments the position
345     * within the chunk. Endian correction will automatically be done if
346     * needed.
347     *
348     * @returns read integer word
349     * @throws RIFF::Exception if an error occured
350     */
351     int16_t Chunk::ReadInt16() {
352     #if DEBUG
353     std::cout << "Chunk::ReadInt16()" << std::endl;
354     #endif // DEBUG
355     int16_t word;
356     ReadSceptical(&word,1,2);
357     return word;
358     }
359    
360     /**
361     * Reads one 16 Bit unsigned integer word and increments the position
362     * within the chunk. Endian correction will automatically be done if
363     * needed.
364     *
365     * @returns read integer word
366     * @throws RIFF::Exception if an error occured
367     */
368     uint16_t Chunk::ReadUint16() {
369     #if DEBUG
370     std::cout << "Chunk::ReadUint16()" << std::endl;
371     #endif // DEBUG
372     uint16_t word;
373     ReadSceptical(&word,1,2);
374     return word;
375     }
376    
377     /**
378     * Reads one 32 Bit signed integer word and increments the position
379     * within the chunk. Endian correction will automatically be done if
380     * needed.
381     *
382     * @returns read integer word
383     * @throws RIFF::Exception if an error occured
384     */
385     int32_t Chunk::ReadInt32() {
386     #if DEBUG
387     std::cout << "Chunk::ReadInt32()" << std::endl;
388     #endif // DEBUG
389     int32_t word;
390     ReadSceptical(&word,1,4);
391     return word;
392     }
393    
394     /**
395     * Reads one 32 Bit unsigned integer word and increments the position
396     * within the chunk. Endian correction will automatically be done if
397     * needed.
398     *
399     * @returns read integer word
400     * @throws RIFF::Exception if an error occured
401     */
402     uint32_t Chunk::ReadUint32() {
403     #if DEBUG
404     std::cout << "Chunk::ReadUint32()" << std::endl;
405     #endif // DEBUG
406     uint32_t word;
407     ReadSceptical(&word,1,4);
408     return word;
409     }
410    
411     void* Chunk::LoadChunkData() {
412     if (!pChunkData) {
413     #if POSIX
414     if (lseek(hFile, ulStartPos, SEEK_SET) == -1) return NULL;
415     pChunkData = new uint8_t[GetSize()];
416     if (!pChunkData) return NULL;
417     unsigned long readWords = read(hFile, pChunkData, GetSize());
418     #else
419     if (fseek(hFile, ulStartPos, SEEK_SET)) return NULL;
420     pChunkData = new uint8_t[GetSize()];
421     if (!pChunkData) return NULL;
422     unsigned long readWords = fread(pChunkData, 1, GetSize(), hFile);
423     #endif // POSIX
424     if (readWords != GetSize()) {
425     delete[] pChunkData;
426     return (pChunkData = NULL);
427     }
428     }
429     return pChunkData;
430     }
431    
432     void Chunk::ReleaseChunkData() {
433     if (pChunkData) {
434     delete[] pChunkData;
435     pChunkData = NULL;
436     }
437     }
438    
439    
440    
441     // *************** List ***************
442     // *
443    
444     List::List() : Chunk() {
445     #if DEBUG
446     std::cout << "List::List()" << std::endl;
447     #endif // DEBUG
448     pSubChunks = NULL;
449     pSubChunksMap = NULL;
450     }
451    
452     #if POSIX
453     List::List(int hFile, unsigned long StartPos, bool EndianNative, List* Parent)
454     #else
455     List::List(FILE* hFile, unsigned long StartPos, bool EndianNative, List* Parent)
456     #endif // POSIX
457     : Chunk(hFile, StartPos, EndianNative, Parent) {
458     #if DEBUG
459     std::cout << "List::List(FILE*,ulong,bool,List*)" << std::endl;
460     #endif // DEBUG
461     pSubChunks = NULL;
462     pSubChunksMap = NULL;
463     ReadHeader(StartPos);
464     ulStartPos = StartPos + LIST_HEADER_SIZE;
465     }
466    
467     List::~List() {
468     #if DEBUG
469     std::cout << "List::~List()" << std::endl;
470     #endif // DEBUG
471     if (pSubChunks) {
472     ChunkList::iterator iter = pSubChunks->begin();
473     ChunkList::iterator end = pSubChunks->end();
474     while (iter != end) {
475     delete *iter;
476     iter++;
477     }
478     delete pSubChunks;
479     }
480     if (pSubChunksMap) delete pSubChunksMap;
481     }
482    
483     Chunk* List::GetSubChunk(uint32_t ChunkID) {
484     #if DEBUG
485     std::cout << "List::GetSubChunk(uint32_t)" << std::endl;
486     #endif // DEBUG
487     if (!pSubChunksMap) LoadSubChunks();
488     return (*pSubChunksMap)[ChunkID];
489     }
490    
491     List* List::GetSubList(uint32_t ListType) {
492     #if DEBUG
493     std::cout << "List::GetSubList(uint32_t)" << std::endl;
494     #endif // DEBUG
495     if (!pSubChunks) LoadSubChunks();
496     ChunkList::iterator iter = pSubChunks->begin();
497     ChunkList::iterator end = pSubChunks->end();
498     while (iter != end) {
499     if ((*iter)->GetChunkID() == CHUNK_ID_LIST) {
500     List* l = (List*) *iter;
501     if (l->GetListType() == ListType) return l;
502     }
503     iter++;
504     }
505     return NULL;
506     }
507    
508     Chunk* List::GetFirstSubChunk() {
509     #if DEBUG
510     std::cout << "List::GetFirstSubChunk()" << std::endl;
511     #endif // DEBUG
512     if (!pSubChunks) LoadSubChunks();
513     ChunksIterator = pSubChunks->begin();
514     return (ChunksIterator != pSubChunks->end()) ? *ChunksIterator : NULL;
515     }
516    
517     Chunk* List::GetNextSubChunk() {
518     #if DEBUG
519     std::cout << "List::GetNextSubChunk()" << std::endl;
520     #endif // DEBUG
521     if (!pSubChunks) return NULL;
522     ChunksIterator++;
523     return (ChunksIterator != pSubChunks->end()) ? *ChunksIterator : NULL;
524     }
525    
526     List* List::GetFirstSubList() {
527     #if DEBUG
528     std::cout << "List::GetFirstSubList()" << std::endl;
529     #endif // DEBUG
530     if (!pSubChunks) LoadSubChunks();
531     ListIterator = pSubChunks->begin();
532     ChunkList::iterator end = pSubChunks->end();
533     while (ListIterator != end) {
534     if ((*ListIterator)->GetChunkID() == CHUNK_ID_LIST) return (List*) *ListIterator;
535     ListIterator++;
536     }
537     return NULL;
538     }
539    
540     List* List::GetNextSubList() {
541     #if DEBUG
542     std::cout << "List::GetNextSubList()" << std::endl;
543     #endif // DEBUG
544     if (!pSubChunks) return NULL;
545     if (ListIterator == pSubChunks->end()) return NULL;
546     ListIterator++;
547     ChunkList::iterator end = pSubChunks->end();
548     while (ListIterator != end) {
549     if ((*ListIterator)->GetChunkID() == CHUNK_ID_LIST) return (List*) *ListIterator;
550     ListIterator++;
551     }
552     return NULL;
553     }
554    
555     unsigned int List::CountSubChunks() {
556     if (!pSubChunks) LoadSubChunks();
557     return pSubChunks->size();
558     }
559    
560     unsigned int List::CountSubChunks(uint32_t ChunkID) {
561     unsigned int result = 0;
562     if (!pSubChunks) LoadSubChunks();
563     ChunkList::iterator iter = pSubChunks->begin();
564     ChunkList::iterator end = pSubChunks->end();
565     while (iter != end) {
566     if ((*iter)->GetChunkID() == ChunkID) {
567     result++;
568     }
569     iter++;
570     }
571     return result;
572     }
573    
574     unsigned int List::CountSubLists() {
575     return CountSubChunks(CHUNK_ID_LIST);
576     }
577    
578     unsigned int List::CountSubLists(uint32_t ListType) {
579     unsigned int result = 0;
580     if (!pSubChunks) LoadSubChunks();
581     ChunkList::iterator iter = pSubChunks->begin();
582     ChunkList::iterator end = pSubChunks->end();
583     while (iter != end) {
584     if ((*iter)->GetChunkID() == CHUNK_ID_LIST) {
585     List* l = (List*) *iter;
586     if (l->GetListType() == ListType) result++;
587     }
588     iter++;
589     }
590     return result;
591     }
592    
593     void List::ReadHeader(unsigned long fPos) {
594     #if DEBUG
595     std::cout << "List::Readheader(ulong) ";
596     #endif // DEBUG
597     Chunk::ReadHeader(fPos);
598     ChunkSize -= 4;
599     #if POSIX
600     lseek(hFile, fPos + CHUNK_HEADER_SIZE, SEEK_SET);
601     read(hFile, &ListType, 4);
602     #else
603     fseek(hFile, fPos + CHUNK_HEADER_SIZE, SEEK_SET);
604     fread(&ListType, 4, 1, hFile);
605     #endif // POSIX
606     #if DEBUG
607     std::cout << "listType=" << convertToString(ListType) << std::endl;
608     #endif // DEBUG
609     if (!bEndianNative) {
610     swapBytes_32(&ListType);
611     }
612     }
613    
614     void List::LoadSubChunks() {
615     #if DEBUG
616     std::cout << "List::LoadSubChunks()";
617     #endif // DEBUG
618     if (!pSubChunks) {
619     pSubChunks = new ChunkList();
620     pSubChunksMap = new ChunkMap();
621     while (RemainingBytes() >= CHUNK_HEADER_SIZE) {
622     Chunk* ck;
623     uint32_t ckid = ReadUint32();
624     #if DEBUG
625     std::cout << " ckid=" << convertToString(ckid) << std::endl;
626     #endif // DEBUG
627     if (ckid == CHUNK_ID_LIST) {
628     ck = new RIFF::List(hFile, ulStartPos + ulPos - 4, bEndianNative, this);
629     SetPos(ck->GetSize() + LIST_HEADER_SIZE - 4, RIFF::stream_curpos);
630     }
631     else { // simple chunk
632     ck = new RIFF::Chunk(hFile, ulStartPos + ulPos - 4, bEndianNative, this);
633     SetPos(ck->GetSize() + CHUNK_HEADER_SIZE - 4, RIFF::stream_curpos);
634     }
635     pSubChunks->push_back(ck);
636     (*pSubChunksMap)[ckid] = ck;
637     if (GetPos() % 2 != 0) SetPos(1, RIFF::stream_curpos); // jump over pad byte
638     }
639     }
640     }
641    
642     String List::GetListTypeString() {
643     return convertToString(ListType);
644     }
645    
646    
647    
648     // *************** File ***************
649     // *
650    
651     File::File(const String& path) : List() {
652     #if DEBUG
653     std::cout << "File::File("<<path<<")" << std::endl;
654     #endif // DEBUG
655     bEndianNative = true;
656     #if POSIX
657     hFile = open(path.c_str(), O_RDONLY | O_NONBLOCK);
658     if (hFile <= 0) {
659     hFile = 0;
660     throw RIFF::Exception("Can't open \"" + path + "\"");
661     }
662     #else
663     hFile = fopen(path.c_str(), "rb");
664     if (!hFile) throw RIFF::Exception("Can't open \"" + path + "\"");
665     #endif // POSIX
666     ulStartPos = RIFF_HEADER_SIZE;
667     ReadHeader(0);
668     if (ChunkID != CHUNK_ID_RIFF) {
669     throw RIFF::Exception("Not a RIFF file");
670     }
671     }
672    
673     File::~File() {
674     #if DEBUG
675     std::cout << "File::~File()" << std::endl;
676     #endif // DEBUG
677     #if POSIX
678     if (hFile) close(hFile);
679     #else
680     if (hFile) fclose(hFile);
681     #endif // POSIX
682     }
683    
684     unsigned long File::GetFileSize() {
685     #if POSIX
686     struct stat filestat;
687     fstat(hFile, &filestat);
688     long size = filestat.st_size;
689     #else // standard C functions
690     long curpos = ftell(hFile);
691     fseek(hFile, 0, SEEK_END);
692     long size = ftell(hFile);
693     fseek(hFile, curpos, SEEK_SET);
694     #endif // POSIX
695     return size;
696     }
697    
698    
699    
700     // *************** Exception ***************
701     // *
702    
703     void Exception::PrintMessage() {
704     std::cout << "RIFF::Exception: " << Message << std::endl;
705     }
706    
707     } // namespace RIFF
708     #endif

  ViewVC Help
Powered by ViewVC