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-2006 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 #define POSIX 1
00028 #define DEBUG 0
00029 
00030 #include <string>
00031 #include <list>
00032 #include <map>
00033 #include <iostream>
00034 
00035 #ifdef HAVE_CONFIG_H
00036 # include <config.h>
00037 #endif
00038 
00039 #if POSIX
00040 # include <sys/types.h>
00041 # include <sys/stat.h>
00042 # include <fcntl.h>
00043 # include <unistd.h>
00044 #endif // POSIX
00045 
00046 #include <stdint.h>
00047 
00048 //typedef unsigned char  uint8_t;
00049 //typedef unsigned short uint16_t;
00050 //typedef unsigned int   uint32_t;
00051 
00052 #include <stdio.h>
00053 
00054 #if WORDS_BIGENDIAN
00055 # define CHUNK_ID_RIFF  0x52494646
00056 # define CHUNK_ID_RIFX  0x52494658
00057 # define CHUNK_ID_LIST  0x4C495354
00058 #else  // little endian
00059 # define CHUNK_ID_RIFF  0x46464952
00060 # define CHUNK_ID_RIFX  0x58464952
00061 # define CHUNK_ID_LIST  0x5453494C
00062 #endif // WORDS_BIGENDIAN
00063 
00064 #define CHUNK_HEADER_SIZE       8
00065 #define LIST_HEADER_SIZE        12
00066 #define RIFF_HEADER_SIZE        12
00067 
00068 
00070 namespace RIFF {
00071 
00072     /* just symbol prototyping */
00073     class Chunk;
00074     class List;
00075     class File;
00076 
00077     typedef std::string String;
00078 
00080     typedef enum {
00081         stream_mode_read       = 0,
00082         stream_mode_read_write = 1,
00083         stream_mode_closed     = 2
00084     } stream_mode_t;
00085 
00087     typedef enum {
00088         stream_ready       = 0,
00089         stream_end_reached = 1,
00090         stream_closed      = 2
00091     } stream_state_t;
00092 
00094     typedef enum {
00095         stream_start    = 0,
00096         stream_curpos   = 1,
00097         stream_backward = 2,
00098         stream_end      = 3
00099     } stream_whence_t;
00100 
00102     class Chunk {
00103         public:
00104             Chunk(File* pFile, unsigned long StartPos, List* Parent);
00105             String         GetChunkIDString();
00106             uint32_t       GetChunkID() { return ChunkID; };            
00107             List*          GetParent()  { return pParent; };            
00108             unsigned long  GetSize()    { return CurrentChunkSize; };   
00109             unsigned long  GetNewSize() { return NewChunkSize;     };   
00110             unsigned long  GetPos()     { return ulPos; };              
00111             unsigned long  GetFilePos() { return ulStartPos + ulPos; }; 
00112             unsigned long  SetPos(unsigned long Where, stream_whence_t Whence = stream_start);
00113             unsigned long  RemainingBytes();
00114             stream_state_t GetState();
00115             unsigned long  Read(void* pData, unsigned long WordCount, unsigned long WordSize);
00116             unsigned long  ReadInt8(int8_t* pData,     unsigned long WordCount = 1);
00117             unsigned long  ReadUint8(uint8_t* pData,   unsigned long WordCount = 1);
00118             unsigned long  ReadInt16(int16_t* pData,   unsigned long WordCount = 1);
00119             unsigned long  ReadUint16(uint16_t* pData, unsigned long WordCount = 1);
00120             unsigned long  ReadInt32(int32_t* pData,   unsigned long WordCount = 1);
00121             unsigned long  ReadUint32(uint32_t* pData, unsigned long WordCount = 1);
00122             int8_t         ReadInt8();
00123             uint8_t        ReadUint8();
00124             int16_t        ReadInt16();
00125             uint16_t       ReadUint16();
00126             int32_t        ReadInt32();
00127             uint32_t       ReadUint32();
00128             unsigned long  Write(void* pData, unsigned long WordCount, unsigned long WordSize);
00129             unsigned long  WriteInt8(int8_t* pData,     unsigned long WordCount = 1);
00130             unsigned long  WriteUint8(uint8_t* pData,   unsigned long WordCount = 1);
00131             unsigned long  WriteInt16(int16_t* pData,   unsigned long WordCount = 1);
00132             unsigned long  WriteUint16(uint16_t* pData, unsigned long WordCount = 1);
00133             unsigned long  WriteInt32(int32_t* pData,   unsigned long WordCount = 1);
00134             unsigned long  WriteUint32(uint32_t* pData, unsigned long WordCount = 1);
00135             void*          LoadChunkData();
00136             void           ReleaseChunkData();
00137             void           Resize(int iNewSize);
00138             virtual ~Chunk();
00139         protected:
00140             uint32_t      ChunkID;
00141             uint32_t      CurrentChunkSize;             /* in bytes */
00142             uint32_t      NewChunkSize;                 /* in bytes (if chunk was scheduled to be resized) */
00143             List*         pParent;
00144             File*         pFile;
00145             unsigned long ulStartPos;           /* actual position in file where chunk (without header) starts */
00146             unsigned long ulPos;                /* # of bytes from ulStartPos */
00147             uint8_t*      pChunkData;
00148             unsigned long ulChunkDataSize;
00149 
00150             Chunk(File* pFile);
00151             Chunk(File* pFile, List* pParent, uint32_t uiChunkID, uint uiBodySize);
00152             void          ReadHeader(unsigned long fPos);
00153             void          WriteHeader(unsigned long fPos);
00154             unsigned long ReadSceptical(void* pData, unsigned long WordCount, unsigned long WordSize);
00155             inline void   swapBytes_16(void* Word) {
00156                 uint8_t byteCache = *((uint8_t*) Word);
00157                 *((uint8_t*) Word)     = *((uint8_t*) Word + 1);
00158                 *((uint8_t*) Word + 1) = byteCache;
00159             }
00160             inline void   swapBytes_32(void* Word) {
00161                 uint8_t byteCache = *((uint8_t*) Word);
00162                 *((uint8_t*) Word)     = *((uint8_t*) Word + 3);
00163                 *((uint8_t*) Word + 3) = byteCache;
00164                 byteCache = *((uint8_t*) Word + 1);
00165                 *((uint8_t*) Word + 1) = *((uint8_t*) Word + 2);
00166                 *((uint8_t*) Word + 2) = byteCache;
00167             }
00168             inline void   swapBytes(void* Word, unsigned long WordSize) {
00169                 uint8_t byteCache;
00170                 unsigned long lo = 0, hi = WordSize - 1;
00171                 for (; lo < hi; hi--, lo++) {
00172                     byteCache = *((uint8_t*) Word + lo);
00173                     *((uint8_t*) Word + lo) = *((uint8_t*) Word + hi);
00174                     *((uint8_t*) Word + hi) = byteCache;
00175                 }
00176             }
00177             inline String convertToString(uint32_t word) {
00178                 String result;
00179                 for (int i = 0; i < 4; i++) {
00180                     uint8_t byte = *((uint8_t*)(&word) + i);
00181                     char c = byte;
00182                     result += c;
00183                 }
00184                 return result;
00185             }
00186             virtual unsigned long WriteChunk(unsigned long ulWritePos, unsigned long ulCurrentDataOffset);
00187             virtual void __resetPos(); 
00188 
00189             friend class List;
00190     };
00191 
00193     class List : public Chunk {
00194         public:
00195             List(File* pFile, unsigned long StartPos, List* Parent);
00196             String       GetListTypeString();
00197             uint32_t     GetListType() { return ListType; }   
00198             Chunk*       GetSubChunk(uint32_t ChunkID);
00199             List*        GetSubList(uint32_t ListType);
00200             Chunk*       GetFirstSubChunk();
00201             Chunk*       GetNextSubChunk();
00202             List*        GetFirstSubList();
00203             List*        GetNextSubList();
00204             unsigned int CountSubChunks();
00205             unsigned int CountSubChunks(uint32_t ChunkID);
00206             unsigned int CountSubLists();
00207             unsigned int CountSubLists(uint32_t ListType);
00208             Chunk*       AddSubChunk(uint32_t uiChunkID, uint uiBodySize);
00209             List*        AddSubList(uint32_t uiListType);
00210             void         DeleteSubChunk(Chunk* pSubChunk);
00211             virtual ~List();
00212         protected:
00213             typedef std::map<uint32_t, RIFF::Chunk*>  ChunkMap;
00214             typedef std::list<Chunk*>                 ChunkList;
00215 
00216             uint32_t   ListType;
00217             ChunkList* pSubChunks;
00218             ChunkMap*  pSubChunksMap;
00219             ChunkList::iterator ChunksIterator;
00220             ChunkList::iterator ListIterator;
00221 
00222             List(File* pFile);
00223             List(File* pFile, List* pParent, uint32_t uiListID);
00224             void ReadHeader(unsigned long fPos);
00225             void WriteHeader(unsigned long fPos);
00226             void LoadSubChunks();
00227             void LoadSubChunksRecursively();
00228             virtual unsigned long WriteChunk(unsigned long ulWritePos, unsigned long ulCurrentDataOffset);
00229             virtual void __resetPos(); 
00230     };
00231 
00233     class File : public List {
00234         public:
00235             File(uint32_t FileType);
00236             File(const String& path);
00237             stream_mode_t GetMode();
00238             bool          SetMode(stream_mode_t NewMode);
00239             String GetFileName();
00240             virtual void Save();
00241             virtual void Save(const String& path);
00242             virtual ~File();
00243         protected:
00244             #if POSIX
00245             int    hFileRead;  
00246             int    hFileWrite; 
00247             #else
00248             FILE*  hFileRead;  
00249             FILE*  hFileWrite; 
00250             #endif // POSIX
00251             String Filename;
00252             bool   bEndianNative;
00253 
00254             void LogAsResized(Chunk* pResizedChunk);
00255             friend class Chunk;
00256             friend class List;
00257         private:
00258             stream_mode_t  Mode;
00259             ChunkList      ResizedChunks; 
00260 
00261             unsigned long GetFileSize();
00262             void ResizeFile(unsigned long ulNewSize);
00263             #if POSIX
00264             unsigned long __GetFileSize(int hFile);
00265             #else
00266             unsigned long __GetFileSize(FILE* hFile);
00267             #endif
00268     };
00269 
00271     class Exception {
00272         public:
00273             String Message;
00274 
00275             Exception(String Message) { Exception::Message = Message; };
00276             void PrintMessage();
00277             virtual ~Exception() {};
00278     };
00279 
00280     String libraryName();
00281     String libraryVersion();
00282 
00283 } // namespace RIFF
00284 #endif // __RIFF_H__

Generated on Wed Dec 6 19:25:57 2006 for libgig by  doxygen 1.5.1