RIFF.h

Go to the documentation of this file.
00001 /***************************************************************************
00002  *                                                                         *
00003  *   libgig - C++ cross-platform Gigasampler format file access library    *
00004  *                                                                         *
00005  *   Copyright (C) 2003-2007 by Christian Schoenebeck                      *
00006  *                              <cuse@users.sourceforge.net>               *
00007  *                                                                         *
00008  *   This library is free software; you can redistribute it and/or modify  *
00009  *   it under the terms of the GNU General Public License as published by  *
00010  *   the Free Software Foundation; either version 2 of the License, or     *
00011  *   (at your option) any later version.                                   *
00012  *                                                                         *
00013  *   This library is distributed in the hope that it will be useful,       *
00014  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00015  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00016  *   GNU General Public License for more details.                          *
00017  *                                                                         *
00018  *   You should have received a copy of the GNU General Public License     *
00019  *   along with this library; if not, write to the Free Software           *
00020  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston,                 *
00021  *   MA  02111-1307  USA                                                   *
00022  ***************************************************************************/
00023 
00024 #ifndef __RIFF_H__
00025 #define __RIFF_H__
00026 
00027 #ifdef WIN32
00028 # define POSIX 0
00029 #endif
00030 
00031 #ifndef POSIX
00032 # define POSIX 1
00033 #endif
00034 
00035 #ifndef DEBUG
00036 # define DEBUG 0
00037 #endif
00038 
00039 #include <string>
00040 #include <list>
00041 #include <set>
00042 #include <map>
00043 #include <iostream>
00044 
00045 #ifdef HAVE_CONFIG_H
00046 # include <config.h>
00047 #endif
00048 
00049 #if POSIX
00050 # include <sys/types.h>
00051 # include <sys/stat.h>
00052 # include <fcntl.h>
00053 # include <unistd.h>
00054 #endif // POSIX
00055 
00056 #include <stdint.h>
00057 
00058 #ifdef WIN32
00059 # include <windows.h>
00060   typedef unsigned int   uint;
00061 #endif // WIN32
00062 
00063 #include <stdio.h>
00064 
00065 #if WORDS_BIGENDIAN
00066 # define CHUNK_ID_RIFF  0x52494646
00067 # define CHUNK_ID_RIFX  0x52494658
00068 # define CHUNK_ID_LIST  0x4C495354
00069 #else  // little endian
00070 # define CHUNK_ID_RIFF  0x46464952
00071 # define CHUNK_ID_RIFX  0x58464952
00072 # define CHUNK_ID_LIST  0x5453494C
00073 #endif // WORDS_BIGENDIAN
00074 
00075 #define CHUNK_HEADER_SIZE       8
00076 #define LIST_HEADER_SIZE        12
00077 #define RIFF_HEADER_SIZE        12
00078 
00079 
00099 namespace RIFF {
00100 
00101     /* just symbol prototyping */
00102     class Chunk;
00103     class List;
00104     class File;
00105 
00106     typedef std::string String;
00107 
00109     typedef enum {
00110         stream_mode_read       = 0,
00111         stream_mode_read_write = 1,
00112         stream_mode_closed     = 2
00113     } stream_mode_t;
00114 
00116     typedef enum {
00117         stream_ready       = 0,
00118         stream_end_reached = 1,
00119         stream_closed      = 2
00120     } stream_state_t;
00121 
00123     typedef enum {
00124         stream_start    = 0,
00125         stream_curpos   = 1,
00126         stream_backward = 2,
00127         stream_end      = 3
00128     } stream_whence_t;
00129 
00131     typedef enum {
00132         endian_little = 0,
00133         endian_big    = 1,
00134         endian_native = 2
00135     } endian_t;
00136 
00142     class Chunk {
00143         public:
00144             Chunk(File* pFile, unsigned long StartPos, List* Parent);
00145             String         GetChunkIDString();
00146             uint32_t       GetChunkID() { return ChunkID; }             
00147             List*          GetParent()  { return pParent; }             
00148             unsigned long  GetSize()    { return CurrentChunkSize; }    
00149             unsigned long  GetNewSize() { return NewChunkSize;     }    
00150             unsigned long  GetPos()     { return ulPos; }               
00151             unsigned long  GetFilePos() { return ulStartPos + ulPos; }  
00152             unsigned long  SetPos(unsigned long Where, stream_whence_t Whence = stream_start);
00153             unsigned long  RemainingBytes();
00154             stream_state_t GetState();
00155             unsigned long  Read(void* pData, unsigned long WordCount, unsigned long WordSize);
00156             unsigned long  ReadInt8(int8_t* pData,     unsigned long WordCount = 1);
00157             unsigned long  ReadUint8(uint8_t* pData,   unsigned long WordCount = 1);
00158             unsigned long  ReadInt16(int16_t* pData,   unsigned long WordCount = 1);
00159             unsigned long  ReadUint16(uint16_t* pData, unsigned long WordCount = 1);
00160             unsigned long  ReadInt32(int32_t* pData,   unsigned long WordCount = 1);
00161             unsigned long  ReadUint32(uint32_t* pData, unsigned long WordCount = 1);
00162             int8_t         ReadInt8();
00163             uint8_t        ReadUint8();
00164             int16_t        ReadInt16();
00165             uint16_t       ReadUint16();
00166             int32_t        ReadInt32();
00167             uint32_t       ReadUint32();
00168             unsigned long  Write(void* pData, unsigned long WordCount, unsigned long WordSize);
00169             unsigned long  WriteInt8(int8_t* pData,     unsigned long WordCount = 1);
00170             unsigned long  WriteUint8(uint8_t* pData,   unsigned long WordCount = 1);
00171             unsigned long  WriteInt16(int16_t* pData,   unsigned long WordCount = 1);
00172             unsigned long  WriteUint16(uint16_t* pData, unsigned long WordCount = 1);
00173             unsigned long  WriteInt32(int32_t* pData,   unsigned long WordCount = 1);
00174             unsigned long  WriteUint32(uint32_t* pData, unsigned long WordCount = 1);
00175             void*          LoadChunkData();
00176             void           ReleaseChunkData();
00177             void           Resize(int iNewSize);
00178             virtual ~Chunk();
00179         protected:
00180             uint32_t      ChunkID;
00181             uint32_t      CurrentChunkSize;             /* in bytes */
00182             uint32_t      NewChunkSize;                 /* in bytes (if chunk was scheduled to be resized) */
00183             List*         pParent;
00184             File*         pFile;
00185             unsigned long ulStartPos;           /* actual position in file where chunk (without header) starts */
00186             unsigned long ulPos;                /* # of bytes from ulStartPos */
00187             uint8_t*      pChunkData;
00188             unsigned long ulChunkDataSize;
00189 
00190             Chunk(File* pFile);
00191             Chunk(File* pFile, List* pParent, uint32_t uiChunkID, uint uiBodySize);
00192             void          ReadHeader(unsigned long fPos);
00193             void          WriteHeader(unsigned long fPos);
00194             unsigned long ReadSceptical(void* pData, unsigned long WordCount, unsigned long WordSize);
00195             inline void   swapBytes_16(void* Word) {
00196                 uint8_t byteCache = *((uint8_t*) Word);
00197                 *((uint8_t*) Word)     = *((uint8_t*) Word + 1);
00198                 *((uint8_t*) Word + 1) = byteCache;
00199             }
00200             inline void   swapBytes_32(void* Word) {
00201                 uint8_t byteCache = *((uint8_t*) Word);
00202                 *((uint8_t*) Word)     = *((uint8_t*) Word + 3);
00203                 *((uint8_t*) Word + 3) = byteCache;
00204                 byteCache = *((uint8_t*) Word + 1);
00205                 *((uint8_t*) Word + 1) = *((uint8_t*) Word + 2);
00206                 *((uint8_t*) Word + 2) = byteCache;
00207             }
00208             inline void   swapBytes(void* Word, unsigned long WordSize) {
00209                 uint8_t byteCache;
00210                 unsigned long lo = 0, hi = WordSize - 1;
00211                 for (; lo < hi; hi--, lo++) {
00212                     byteCache = *((uint8_t*) Word + lo);
00213                     *((uint8_t*) Word + lo) = *((uint8_t*) Word + hi);
00214                     *((uint8_t*) Word + hi) = byteCache;
00215                 }
00216             }
00217             inline String convertToString(uint32_t word) {
00218                 String result;
00219                 for (int i = 0; i < 4; i++) {
00220                     uint8_t byte = *((uint8_t*)(&word) + i);
00221                     char c = byte;
00222                     result += c;
00223                 }
00224                 return result;
00225             }
00226             virtual unsigned long WriteChunk(unsigned long ulWritePos, unsigned long ulCurrentDataOffset);
00227             virtual void __resetPos(); 
00228 
00229             friend class List;
00230     };
00231 
00237     class List : public Chunk {
00238         public:
00239             List(File* pFile, unsigned long StartPos, List* Parent);
00240             String       GetListTypeString();
00241             uint32_t     GetListType() { return ListType; }   
00242             Chunk*       GetSubChunk(uint32_t ChunkID);
00243             List*        GetSubList(uint32_t ListType);
00244             Chunk*       GetFirstSubChunk();
00245             Chunk*       GetNextSubChunk();
00246             List*        GetFirstSubList();
00247             List*        GetNextSubList();
00248             unsigned int CountSubChunks();
00249             unsigned int CountSubChunks(uint32_t ChunkID);
00250             unsigned int CountSubLists();
00251             unsigned int CountSubLists(uint32_t ListType);
00252             Chunk*       AddSubChunk(uint32_t uiChunkID, uint uiBodySize);
00253             List*        AddSubList(uint32_t uiListType);
00254             void         DeleteSubChunk(Chunk* pSubChunk);
00255             void         MoveSubChunk(Chunk* pSrc, Chunk* pDst);
00256             virtual ~List();
00257         protected:
00258             typedef std::map<uint32_t, RIFF::Chunk*>  ChunkMap;
00259             typedef std::list<Chunk*>                 ChunkList;
00260 
00261             uint32_t   ListType;
00262             ChunkList* pSubChunks;
00263             ChunkMap*  pSubChunksMap;
00264             ChunkList::iterator ChunksIterator;
00265             ChunkList::iterator ListIterator;
00266 
00267             List(File* pFile);
00268             List(File* pFile, List* pParent, uint32_t uiListID);
00269             void ReadHeader(unsigned long fPos);
00270             void WriteHeader(unsigned long fPos);
00271             void LoadSubChunks();
00272             void LoadSubChunksRecursively();
00273             virtual unsigned long WriteChunk(unsigned long ulWritePos, unsigned long ulCurrentDataOffset);
00274             virtual void __resetPos(); 
00275     };
00276 
00283     class File : public List {
00284         public:
00285             File(uint32_t FileType);
00286             File(const String& path);
00287             stream_mode_t GetMode();
00288             bool          SetMode(stream_mode_t NewMode);
00289             void SetByteOrder(endian_t Endian);
00290             String GetFileName();
00291             virtual void Save();
00292             virtual void Save(const String& path);
00293             virtual ~File();
00294         protected:
00295             #if POSIX
00296             int    hFileRead;  
00297             int    hFileWrite; 
00298             #elif defined(WIN32)
00299             HANDLE hFileRead;  
00300             HANDLE hFileWrite; 
00301             #else
00302             FILE*  hFileRead;  
00303             FILE*  hFileWrite; 
00304             #endif // POSIX
00305             String Filename;
00306             bool   bEndianNative;
00307 
00308             void LogAsResized(Chunk* pResizedChunk);
00309             void UnlogResized(Chunk* pResizedChunk);
00310             friend class Chunk;
00311             friend class List;
00312         private:
00313             stream_mode_t  Mode;
00314             std::set<Chunk*> ResizedChunks; 
00315 
00316             unsigned long GetFileSize();
00317             void ResizeFile(unsigned long ulNewSize);
00318             #if POSIX
00319             unsigned long __GetFileSize(int hFile);
00320             #elif defined(WIN32)
00321             unsigned long __GetFileSize(HANDLE hFile);
00322             #else
00323             unsigned long __GetFileSize(FILE* hFile);
00324             #endif
00325     };
00326 
00330     class Exception {
00331         public:
00332             String Message;
00333 
00334             Exception(String Message) { Exception::Message = Message; }
00335             void PrintMessage();
00336             virtual ~Exception() {}
00337     };
00338 
00339     String libraryName();
00340     String libraryVersion();
00341 
00342 } // namespace RIFF
00343 #endif // __RIFF_H__

Generated on Thu Jan 8 04:09:44 2009 for libgig by  doxygen 1.5.2